summaryrefslogtreecommitdiff
path: root/chromium/content
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-01-29 16:35:13 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-02-01 15:33:35 +0000
commitc8c2d1901aec01e934adf561a9fdf0cc776cdef8 (patch)
tree9157c3d9815e5870799e070b113813bec53e0535 /chromium/content
parentabefd5095b41dac94ca451d784ab6e27372e981a (diff)
downloadqtwebengine-chromium-c8c2d1901aec01e934adf561a9fdf0cc776cdef8.tar.gz
BASELINE: Update Chromium to 64.0.3282.139
Change-Id: I1cae68fe9c94ff7608b26b8382fc19862cdb293a Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/content')
-rw-r--r--chromium/content/BUILD.gn6
-rw-r--r--chromium/content/app/android/content_child_process_service_delegate.cc30
-rw-r--r--chromium/content/app/android/content_main.cc5
-rw-r--r--chromium/content/app/android/library_loader_hooks.cc2
-rw-r--r--chromium/content/app/content_main_runner.cc33
-rw-r--r--chromium/content/app/content_service_manager_main_delegate.cc8
-rw-r--r--chromium/content/app/content_service_manager_main_delegate.h3
-rw-r--r--chromium/content/app/strings/content_strings.grd6
-rw-r--r--chromium/content/app/strings/translations/content_strings_am.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_ar.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_bg.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_bn.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_ca.xtb6
-rw-r--r--chromium/content/app/strings/translations/content_strings_cs.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_da.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_de.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_el.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_en-GB.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_es-419.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_es.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_et.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_fa.xtb8
-rw-r--r--chromium/content/app/strings/translations/content_strings_fi.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_fil.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_fr.xtb4
-rw-r--r--chromium/content/app/strings/translations/content_strings_gu.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_hi.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_hr.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_hu.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_id.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_it.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_iw.xtb4
-rw-r--r--chromium/content/app/strings/translations/content_strings_ja.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_kn.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_ko.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_lt.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_lv.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_ml.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_mr.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_ms.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_nl.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_no.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_pl.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_pt-BR.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_pt-PT.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_ro.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_ru.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_sk.xtb4
-rw-r--r--chromium/content/app/strings/translations/content_strings_sl.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_sr.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_sv.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_sw.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_ta.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_te.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_th.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_tr.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_uk.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_vi.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_zh-CN.xtb2
-rw-r--r--chromium/content/app/strings/translations/content_strings_zh-TW.xtb2
-rw-r--r--chromium/content/browser/BUILD.gn173
-rw-r--r--chromium/content/browser/DEPS78
-rw-r--r--chromium/content/browser/accessibility/accessibility_event_recorder_win.cc18
-rw-r--r--chromium/content/browser/accessibility/accessibility_mode_browsertest.cc1
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter.cc47
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter.h33
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_android.cc14
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc36
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc25
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_blink.h4
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_browser.cc16
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_browser.h6
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm12
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_stub.cc9
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc463
-rw-r--r--chromium/content/browser/accessibility/accessibility_ui.cc105
-rw-r--r--chromium/content/browser/accessibility/accessibility_ui.h14
-rw-r--r--chromium/content/browser/accessibility/accessibility_win_browsertest.cc161
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility.cc114
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility.h25
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_android.cc68
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_android.h3
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_auralinux.cc972
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_auralinux.h67
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_cocoa.h3
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_cocoa.mm286
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_com_win.cc138
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_com_win.h13
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_event.cc148
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_event.h85
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_event_win.cc102
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_event_win.h38
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager.cc232
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager.h54
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_android.cc138
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_android.h11
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc19
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h11
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_mac.h34
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm278
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc27
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_win.cc307
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_win.h35
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_position.cc (renamed from chromium/content/browser/accessibility/ax_platform_position.cc)57
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_position.h (renamed from chromium/content/browser/accessibility/ax_platform_position.h)20
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc200
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h5
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc8
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc85
-rw-r--r--chromium/content/browser/accessibility/fullscreen_browsertest.cc108
-rw-r--r--chromium/content/browser/accessibility/hit_testing_browsertest.cc22
-rw-r--r--chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc22
-rw-r--r--chromium/content/browser/accessibility/one_shot_accessibility_tree_search.h4
-rw-r--r--chromium/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc32
-rw-r--r--chromium/content/browser/accessibility/web_contents_accessibility_android.cc27
-rw-r--r--chromium/content/browser/accessibility/web_contents_accessibility_android.h5
-rw-r--r--chromium/content/browser/android/app_web_message_port.cc6
-rw-r--r--chromium/content/browser/android/browser_startup_controller.cc16
-rw-r--r--chromium/content/browser/android/content_feature_list.cc7
-rw-r--r--chromium/content/browser/android/content_startup_flags.cc5
-rw-r--r--chromium/content/browser/android/content_video_view.cc3
-rw-r--r--chromium/content/browser/android/content_view_core.cc233
-rw-r--r--chromium/content/browser/android/content_view_core.h33
-rw-r--r--chromium/content/browser/android/content_view_render_view.cc8
-rw-r--r--chromium/content/browser/android/content_view_statics.cc7
-rw-r--r--chromium/content/browser/android/dialog_overlay_impl.cc22
-rw-r--r--chromium/content/browser/android/gesture_event_type.h40
-rw-r--r--chromium/content/browser/android/gpu_process_callback.cc5
-rw-r--r--chromium/content/browser/android/ime_adapter_android.cc47
-rw-r--r--chromium/content/browser/android/interstitial_page_delegate_android.cc7
-rw-r--r--chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.cc6
-rw-r--r--chromium/content/browser/android/java/gin_java_bridge_message_filter.cc4
-rw-r--r--chromium/content/browser/android/java/gin_java_method_invocation_helper.cc2
-rw-r--r--chromium/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc12
-rw-r--r--chromium/content/browser/android/java/gin_java_script_to_java_types_coercion.cc6
-rw-r--r--chromium/content/browser/android/launcher_thread.h5
-rw-r--r--chromium/content/browser/android/load_url_params.cc6
-rw-r--r--chromium/content/browser/android/overscroll_controller_android.cc22
-rw-r--r--chromium/content/browser/android/overscroll_controller_android.h2
-rw-r--r--chromium/content/browser/android/overscroll_controller_android_unittest.cc38
-rw-r--r--chromium/content/browser/android/popup_zoomer.cc13
-rw-r--r--chromium/content/browser/android/selection_popup_controller.cc16
-rw-r--r--chromium/content/browser/android/smart_selection_client.cc9
-rw-r--r--chromium/content/browser/android/synchronous_compositor_browser_filter.cc2
-rw-r--r--chromium/content/browser/android/synchronous_compositor_host.cc2
-rw-r--r--chromium/content/browser/android/synchronous_compositor_host.h2
-rw-r--r--chromium/content/browser/android/text_suggestion_host_android.cc6
-rw-r--r--chromium/content/browser/android/text_suggestion_host_mojo_impl_android.cc2
-rw-r--r--chromium/content/browser/android/tracing_controller_android.cc7
-rw-r--r--chromium/content/browser/android/web_contents_observer_proxy.cc7
-rw-r--r--chromium/content/browser/appcache/OWNERS4
-rw-r--r--chromium/content/browser/appcache/appcache.cc32
-rw-r--r--chromium/content/browser/appcache/appcache.h19
-rw-r--r--chromium/content/browser/appcache/appcache_backend_impl.cc18
-rw-r--r--chromium/content/browser/appcache/appcache_backend_impl.h2
-rw-r--r--chromium/content/browser/appcache/appcache_browsertest.cc18
-rw-r--r--chromium/content/browser/appcache/appcache_database.cc30
-rw-r--r--chromium/content/browser/appcache/appcache_disk_cache.cc21
-rw-r--r--chromium/content/browser/appcache/appcache_disk_cache_unittest.cc12
-rw-r--r--chromium/content/browser/appcache/appcache_dispatcher_host.cc17
-rw-r--r--chromium/content/browser/appcache/appcache_dispatcher_host.h2
-rw-r--r--chromium/content/browser/appcache/appcache_entry.h2
-rw-r--r--chromium/content/browser/appcache/appcache_executable_handler.h56
-rw-r--r--chromium/content/browser/appcache/appcache_frontend_proxy.cc4
-rw-r--r--chromium/content/browser/appcache/appcache_group.cc14
-rw-r--r--chromium/content/browser/appcache/appcache_group_unittest.cc25
-rw-r--r--chromium/content/browser/appcache/appcache_host.cc87
-rw-r--r--chromium/content/browser/appcache/appcache_host.h2
-rw-r--r--chromium/content/browser/appcache/appcache_host_unittest.cc136
-rw-r--r--chromium/content/browser/appcache/appcache_interceptor.cc16
-rw-r--r--chromium/content/browser/appcache/appcache_job.cc32
-rw-r--r--chromium/content/browser/appcache/appcache_job.h42
-rw-r--r--chromium/content/browser/appcache/appcache_manifest_parser.cc15
-rw-r--r--chromium/content/browser/appcache/appcache_quota_client.cc2
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler.cc263
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler.h110
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler_unittest.cc368
-rw-r--r--chromium/content/browser/appcache/appcache_response.cc12
-rw-r--r--chromium/content/browser/appcache/appcache_response_unittest.cc8
-rw-r--r--chromium/content/browser/appcache/appcache_service_impl.cc2
-rw-r--r--chromium/content/browser/appcache/appcache_service_impl.h14
-rw-r--r--chromium/content/browser/appcache/appcache_service_unittest.cc14
-rw-r--r--chromium/content/browser/appcache/appcache_storage_impl.cc47
-rw-r--r--chromium/content/browser/appcache/appcache_storage_impl.h6
-rw-r--r--chromium/content/browser/appcache/appcache_storage_impl_unittest.cc56
-rw-r--r--chromium/content/browser/appcache/appcache_storage_unittest.cc4
-rw-r--r--chromium/content/browser/appcache/appcache_subresource_url_factory.cc354
-rw-r--r--chromium/content/browser/appcache/appcache_subresource_url_factory.h22
-rw-r--r--chromium/content/browser/appcache/appcache_unittest.cc2
-rw-r--r--chromium/content/browser/appcache/appcache_update_job.cc222
-rw-r--r--chromium/content/browser/appcache/appcache_update_job.h1
-rw-r--r--chromium/content/browser/appcache/appcache_update_job_unittest.cc777
-rw-r--r--chromium/content/browser/appcache/appcache_update_request_base.cc6
-rw-r--r--chromium/content/browser/appcache/appcache_update_request_base.h2
-rw-r--r--chromium/content/browser/appcache/appcache_update_url_fetcher.cc4
-rw-r--r--chromium/content/browser/appcache/appcache_update_url_loader_request.cc6
-rw-r--r--chromium/content/browser/appcache/appcache_update_url_loader_request.h4
-rw-r--r--chromium/content/browser/appcache/appcache_url_loader_job.cc416
-rw-r--r--chromium/content/browser/appcache/appcache_url_loader_job.h163
-rw-r--r--chromium/content/browser/appcache/appcache_url_loader_request.cc19
-rw-r--r--chromium/content/browser/appcache/appcache_url_loader_request.h7
-rw-r--r--chromium/content/browser/appcache/appcache_url_request_job.cc169
-rw-r--r--chromium/content/browser/appcache/appcache_url_request_job.h35
-rw-r--r--chromium/content/browser/appcache/appcache_url_request_job_unittest.cc16
-rw-r--r--chromium/content/browser/appcache/chrome_appcache_service.cc3
-rw-r--r--chromium/content/browser/appcache/chrome_appcache_service_unittest.cc10
-rw-r--r--chromium/content/browser/appcache/mock_appcache_storage_unittest.cc14
-rw-r--r--chromium/content/browser/background_fetch/OWNERS1
-rw-r--r--chromium/content/browser/background_fetch/background_fetch.proto14
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_context.cc254
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_context.h89
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_cross_origin_filter.cc5
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_cross_origin_filter_unittest.cc2
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager.cc693
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager.h148
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager_unittest.cc402
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc194
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h93
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc114
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_job_controller.cc106
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_job_controller.h77
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_job_controller_unittest.cc128
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_registration_notifier.cc19
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_registration_notifier.h17
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc58
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_request_info.cc15
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_request_info.h13
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_request_manager.h53
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_service_impl.cc45
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_service_impl.h6
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_service_unittest.cc109
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_test_base.cc6
-rw-r--r--chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc72
-rw-r--r--chromium/content/browser/background_fetch/mock_background_fetch_delegate.h30
-rw-r--r--chromium/content/browser/background_fetch/storage/README.md50
-rw-r--r--chromium/content/browser/background_fetch/storage/cleanup_task.cc93
-rw-r--r--chromium/content/browser/background_fetch/storage/cleanup_task.h49
-rw-r--r--chromium/content/browser/background_fetch/storage/create_registration_task.cc154
-rw-r--r--chromium/content/browser/background_fetch/storage/create_registration_task.h62
-rw-r--r--chromium/content/browser/background_fetch/storage/database_helpers.cc101
-rw-r--r--chromium/content/browser/background_fetch/storage/database_helpers.h52
-rw-r--r--chromium/content/browser/background_fetch/storage/database_task.cc38
-rw-r--r--chromium/content/browser/background_fetch/storage/database_task.h69
-rw-r--r--chromium/content/browser/background_fetch/storage/delete_registration_task.cc112
-rw-r--r--chromium/content/browser/background_fetch/storage/delete_registration_task.h49
-rw-r--r--chromium/content/browser/background_fetch/storage/get_developer_ids_task.cc63
-rw-r--r--chromium/content/browser/background_fetch/storage/get_developer_ids_task.h55
-rw-r--r--chromium/content/browser/background_fetch/storage/get_registration_task.cc123
-rw-r--r--chromium/content/browser/background_fetch/storage/get_registration_task.h63
-rw-r--r--chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc110
-rw-r--r--chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.h51
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager.cc10
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager.h6
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager_unittest.cc135
-rw-r--r--chromium/content/browser/bad_message.h164
-rw-r--r--chromium/content/browser/battery_monitor_browsertest.cc2
-rw-r--r--chromium/content/browser/blob_storage/DEPS3
-rw-r--r--chromium/content/browser/blob_storage/blob_dispatcher_host.cc36
-rw-r--r--chromium/content/browser/blob_storage/blob_dispatcher_host_unittest.cc6
-rw-r--r--chromium/content/browser/blob_storage/blob_internals_url_loader.cc2
-rw-r--r--chromium/content/browser/blob_storage/blob_registry_wrapper.cc13
-rw-r--r--chromium/content/browser/blob_storage/blob_registry_wrapper.h5
-rw-r--r--chromium/content/browser/blob_storage/blob_transport_host_unittest.cc1
-rw-r--r--chromium/content/browser/blob_storage/blob_url_browsertest.cc6
-rw-r--r--chromium/content/browser/blob_storage/blob_url_loader_factory.cc44
-rw-r--r--chromium/content/browser/blob_storage/blob_url_loader_factory.h11
-rw-r--r--chromium/content/browser/blob_storage/blob_url_unittest.cc38
-rw-r--r--chromium/content/browser/blob_storage/chrome_blob_storage_context.cc12
-rw-r--r--chromium/content/browser/blob_storage/chrome_blob_storage_context.h8
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_allowed_devices_unittest.cc6
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc49
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc16
-rw-r--r--chromium/content/browser/bluetooth/frame_connected_bluetooth_devices.cc2
-rw-r--r--chromium/content/browser/bluetooth/frame_connected_bluetooth_devices_unittest.cc4
-rw-r--r--chromium/content/browser/bluetooth/web_bluetooth_service_impl.cc2
-rw-r--r--chromium/content/browser/broadcast_channel/broadcast_channel_provider.cc10
-rw-r--r--chromium/content/browser/broadcast_channel/broadcast_channel_provider.h2
-rw-r--r--chromium/content/browser/browser_associated_interface_unittest.cc15
-rw-r--r--chromium/content/browser/browser_child_process_host_impl.cc20
-rw-r--r--chromium/content/browser/browser_context.cc63
-rw-r--r--chromium/content/browser/browser_ipc_logging.cc15
-rw-r--r--chromium/content/browser/browser_main.cc2
-rw-r--r--chromium/content/browser/browser_main_loop.cc271
-rw-r--r--chromium/content/browser/browser_main_loop.h32
-rw-r--r--chromium/content/browser/browser_main_runner.cc4
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_embedder.cc42
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_embedder.h13
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest.cc106
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest.h37
-rw-r--r--chromium/content/browser/browser_shutdown_profile_dumper.cc7
-rw-r--r--chromium/content/browser/browser_side_navigation_browsertest.cc7
-rw-r--r--chromium/content/browser/browser_thread_unittest.cc40
-rw-r--r--chromium/content/browser/browser_url_handler_impl.cc3
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_filter_builder_impl.cc6
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc12
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_remover_impl.cc8
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_remover_impl.h1
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc160
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc25
-rw-r--r--chromium/content/browser/browsing_data/clear_site_data_throttle.cc48
-rw-r--r--chromium/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc26
-rw-r--r--chromium/content/browser/browsing_data/clear_site_data_throttle_unittest.cc111
-rw-r--r--chromium/content/browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc4
-rw-r--r--chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.cc10
-rw-r--r--chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.h4
-rw-r--r--chromium/content/browser/byte_stream.cc4
-rw-r--r--chromium/content/browser/cache_storage/cache_storage.cc153
-rw-r--r--chromium/content/browser/cache_storage/cache_storage.h63
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc3
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache.cc315
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache.h71
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache_handle.cc23
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache_handle.h6
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc307
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc156
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_dispatcher_host.h52
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_manager.cc6
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc405
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_operation_unittest.cc2
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_scheduler.cc2
-rw-r--r--chromium/content/browser/child_process_launcher.cc24
-rw-r--r--chromium/content/browser/child_process_launcher.h4
-rw-r--r--chromium/content/browser/child_process_launcher_helper.cc40
-rw-r--r--chromium/content/browser/child_process_launcher_helper.h16
-rw-r--r--chromium/content/browser/child_process_launcher_helper_android.cc6
-rw-r--r--chromium/content/browser/child_process_launcher_helper_fuchsia.cc4
-rw-r--r--chromium/content/browser/child_process_launcher_helper_linux.cc7
-rw-r--r--chromium/content/browser/child_process_launcher_helper_mac.cc14
-rw-r--r--chromium/content/browser/child_process_launcher_helper_win.cc5
-rw-r--r--chromium/content/browser/child_process_security_policy_impl.cc16
-rw-r--r--chromium/content/browser/child_process_security_policy_impl.h22
-rw-r--r--chromium/content/browser/child_process_security_policy_unittest.cc5
-rw-r--r--chromium/content/browser/cocoa/system_hotkey_helper_mac.mm2
-rw-r--r--chromium/content/browser/compositor/OWNERS2
-rw-r--r--chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc35
-rw-r--r--chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h23
-rw-r--r--chromium/content/browser/compositor/gpu_output_surface_mac.h3
-rw-r--r--chromium/content/browser/compositor/gpu_output_surface_mac.mm5
-rw-r--r--chromium/content/browser/compositor/gpu_process_transport_factory.cc481
-rw-r--r--chromium/content/browser/compositor/gpu_process_transport_factory.h47
-rw-r--r--chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc10
-rw-r--r--chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h3
-rw-r--r--chromium/content/browser/compositor/image_transport_factory.cc12
-rw-r--r--chromium/content/browser/compositor/image_transport_factory.h12
-rw-r--r--chromium/content/browser/compositor/image_transport_factory_browsertest.cc27
-rw-r--r--chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc8
-rw-r--r--chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.h4
-rw-r--r--chromium/content/browser/compositor/owned_mailbox.cc6
-rw-r--r--chromium/content/browser/compositor/owned_mailbox.h1
-rw-r--r--chromium/content/browser/compositor/reflector_impl.cc10
-rw-r--r--chromium/content/browser/compositor/reflector_impl_unittest.cc17
-rw-r--r--chromium/content/browser/compositor/software_browser_compositor_output_surface.cc25
-rw-r--r--chromium/content/browser/compositor/software_browser_compositor_output_surface.h6
-rw-r--r--chromium/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc9
-rw-r--r--chromium/content/browser/compositor/software_output_device_mac.h94
-rw-r--r--chromium/content/browser/compositor/software_output_device_mac.mm215
-rw-r--r--chromium/content/browser/compositor/software_output_device_mac_unittest.mm120
-rw-r--r--chromium/content/browser/compositor/software_output_device_ozone.cc71
-rw-r--r--chromium/content/browser/compositor/software_output_device_ozone.h48
-rw-r--r--chromium/content/browser/compositor/software_output_device_ozone_unittest.cc153
-rw-r--r--chromium/content/browser/compositor/software_output_device_win.cc206
-rw-r--r--chromium/content/browser/compositor/software_output_device_win.h76
-rw-r--r--chromium/content/browser/compositor/software_output_device_x11.cc128
-rw-r--r--chromium/content/browser/compositor/software_output_device_x11.h39
-rw-r--r--chromium/content/browser/compositor/surface_utils.cc35
-rw-r--r--chromium/content/browser/compositor/viz_process_transport_factory.cc488
-rw-r--r--chromium/content/browser/compositor/viz_process_transport_factory.h177
-rw-r--r--chromium/content/browser/cross_site_transfer_browsertest.cc2
-rw-r--r--chromium/content/browser/dedicated_worker/OWNERS4
-rw-r--r--chromium/content/browser/dedicated_worker/README.md8
-rw-r--r--chromium/content/browser/dedicated_worker/dedicated_worker_host.cc88
-rw-r--r--chromium/content/browser/dedicated_worker/dedicated_worker_host.h24
-rw-r--r--chromium/content/browser/device_sensors/device_sensor_browsertest.cc76
-rw-r--r--chromium/content/browser/devtools/devtools_agent_host_impl.cc124
-rw-r--r--chromium/content/browser/devtools/devtools_agent_host_impl.h11
-rw-r--r--chromium/content/browser/devtools/devtools_frontend_host_impl.cc59
-rw-r--r--chromium/content/browser/devtools/devtools_frontend_host_impl.h19
-rw-r--r--chromium/content/browser/devtools/devtools_http_handler.cc35
-rw-r--r--chromium/content/browser/devtools/devtools_interceptor_controller.cc137
-rw-r--r--chromium/content/browser/devtools/devtools_interceptor_controller.h98
-rw-r--r--chromium/content/browser/devtools/devtools_io_context.cc17
-rw-r--r--chromium/content/browser/devtools/devtools_manager.cc16
-rw-r--r--chromium/content/browser/devtools/devtools_manager.h4
-rw-r--r--chromium/content/browser/devtools/devtools_manager_unittest.cc11
-rw-r--r--chromium/content/browser/devtools/devtools_network_transaction_factory.cc4
-rw-r--r--chromium/content/browser/devtools/devtools_pipe_handler.cc270
-rw-r--r--chromium/content/browser/devtools/devtools_pipe_handler.h49
-rw-r--r--chromium/content/browser/devtools/devtools_session.cc104
-rw-r--r--chromium/content/browser/devtools/devtools_session.h24
-rw-r--r--chromium/content/browser/devtools/devtools_target_registry.cc211
-rw-r--r--chromium/content/browser/devtools/devtools_target_registry.h77
-rw-r--r--chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc1025
-rw-r--r--chromium/content/browser/devtools/devtools_url_interceptor_request_job.h127
-rw-r--r--chromium/content/browser/devtools/devtools_url_request_interceptor.cc486
-rw-r--r--chromium/content/browser/devtools/devtools_url_request_interceptor.h301
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_download_manager_delegate.cc2
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc89
-rw-r--r--chromium/content/browser/devtools/protocol/emulation_handler.cc67
-rw-r--r--chromium/content/browser/devtools/protocol/input_handler.cc43
-rw-r--r--chromium/content/browser/devtools/protocol/input_handler.h5
-rw-r--r--chromium/content/browser/devtools/protocol/network_handler.cc412
-rw-r--r--chromium/content/browser/devtools/protocol/network_handler.h54
-rw-r--r--chromium/content/browser/devtools/protocol/page_handler.cc116
-rw-r--r--chromium/content/browser/devtools/protocol/page_handler.h12
-rw-r--r--chromium/content/browser/devtools/protocol/service_worker_handler.cc17
-rw-r--r--chromium/content/browser/devtools/protocol/storage_handler.cc17
-rw-r--r--chromium/content/browser/devtools/protocol/target_auto_attacher.cc26
-rw-r--r--chromium/content/browser/devtools/protocol/target_auto_attacher.h4
-rw-r--r--chromium/content/browser/devtools/protocol/target_handler.cc115
-rw-r--r--chromium/content/browser/devtools/protocol/target_handler.h10
-rw-r--r--chromium/content/browser/devtools/protocol/tethering_handler.cc23
-rw-r--r--chromium/content/browser/devtools/protocol/tracing_handler.cc2
-rw-r--r--chromium/content/browser/devtools/protocol_config.json12
-rw-r--r--chromium/content/browser/devtools/protocol_string.cc2
-rw-r--r--chromium/content/browser/devtools/protocol_string.h2
-rw-r--r--chromium/content/browser/devtools/render_frame_devtools_agent_host.cc502
-rw-r--r--chromium/content/browser/devtools/render_frame_devtools_agent_host.h29
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_agent_host.cc7
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_agent_host.h7
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_manager.cc17
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_manager.h8
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc17
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_manager.cc9
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_manager.h3
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_manager_unittest.cc126
-rw-r--r--chromium/content/browser/devtools/site_per_process_devtools_browsertest.cc4
-rw-r--r--chromium/content/browser/devtools/worker_devtools_agent_host.cc15
-rw-r--r--chromium/content/browser/devtools/worker_devtools_agent_host.h4
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_area.cc6
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_area_unittest.cc19
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_browsertest.cc5
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_impl.cc24
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc24
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc39
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_wrapper.h10
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_database.cc2
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_host.cc4
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_message_filter.cc2
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_namespace.cc4
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_session.cc46
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_session.h15
-rw-r--r--chromium/content/browser/dom_storage/local_storage_context_mojo.cc74
-rw-r--r--chromium/content/browser/dom_storage/local_storage_context_mojo.h6
-rw-r--r--chromium/content/browser/dom_storage/local_storage_context_mojo_unittest.cc339
-rw-r--r--chromium/content/browser/dom_storage/session_storage_context_mojo.cc58
-rw-r--r--chromium/content/browser/dom_storage/session_storage_context_mojo.h62
-rw-r--r--chromium/content/browser/dom_storage/session_storage_database.cc47
-rw-r--r--chromium/content/browser/dom_storage/session_storage_namespace_impl.cc19
-rw-r--r--chromium/content/browser/download/base_file.cc98
-rw-r--r--chromium/content/browser/download/base_file.h6
-rw-r--r--chromium/content/browser/download/base_file_unittest.cc15
-rw-r--r--chromium/content/browser/download/base_file_win.cc2
-rw-r--r--chromium/content/browser/download/base_file_win_unittest.cc3
-rw-r--r--chromium/content/browser/download/download_browsertest.cc1092
-rw-r--r--chromium/content/browser/download/download_create_info.cc3
-rw-r--r--chromium/content/browser/download/download_create_info.h6
-rw-r--r--chromium/content/browser/download/download_file.h4
-rw-r--r--chromium/content/browser/download/download_file_factory.cc4
-rw-r--r--chromium/content/browser/download/download_file_factory.h6
-rw-r--r--chromium/content/browser/download/download_file_impl.cc102
-rw-r--r--chromium/content/browser/download/download_file_impl.h59
-rw-r--r--chromium/content/browser/download/download_file_unittest.cc27
-rw-r--r--chromium/content/browser/download/download_item_factory.h13
-rw-r--r--chromium/content/browser/download/download_item_impl.cc252
-rw-r--r--chromium/content/browser/download/download_item_impl.h22
-rw-r--r--chromium/content/browser/download/download_item_impl_delegate.cc7
-rw-r--r--chromium/content/browser/download/download_item_impl_delegate.h4
-rw-r--r--chromium/content/browser/download/download_item_impl_unittest.cc22
-rw-r--r--chromium/content/browser/download/download_job.cc20
-rw-r--r--chromium/content/browser/download/download_job_factory.cc9
-rw-r--r--chromium/content/browser/download/download_job_unittest.cc6
-rw-r--r--chromium/content/browser/download/download_manager_impl.cc289
-rw-r--r--chromium/content/browser/download/download_manager_impl.h34
-rw-r--r--chromium/content/browser/download/download_manager_impl_unittest.cc62
-rw-r--r--chromium/content/browser/download/download_net_log_parameters.cc212
-rw-r--r--chromium/content/browser/download/download_net_log_parameters.h113
-rw-r--r--chromium/content/browser/download/download_request_core.cc29
-rw-r--r--chromium/content/browser/download/download_request_core_unittest.cc2
-rw-r--r--chromium/content/browser/download/download_resource_handler.cc2
-rw-r--r--chromium/content/browser/download/download_response_handler.cc29
-rw-r--r--chromium/content/browser/download/download_response_handler.h12
-rw-r--r--chromium/content/browser/download/download_stats.cc37
-rw-r--r--chromium/content/browser/download/download_stats.h8
-rw-r--r--chromium/content/browser/download/download_utils.cc50
-rw-r--r--chromium/content/browser/download/download_utils.h6
-rw-r--r--chromium/content/browser/download/download_worker.cc13
-rw-r--r--chromium/content/browser/download/drag_download_file.cc12
-rw-r--r--chromium/content/browser/download/drag_download_file_browsertest.cc19
-rw-r--r--chromium/content/browser/download/drag_download_util.cc2
-rw-r--r--chromium/content/browser/download/mhtml_extra_parts_impl.cc11
-rw-r--r--chromium/content/browser/download/mhtml_extra_parts_impl.h5
-rw-r--r--chromium/content/browser/download/mhtml_generation_manager.cc29
-rw-r--r--chromium/content/browser/download/mock_download_file.h3
-rw-r--r--chromium/content/browser/download/mock_download_item_impl.cc3
-rw-r--r--chromium/content/browser/download/parallel_download_job.cc10
-rw-r--r--chromium/content/browser/download/parallel_download_job_unittest.cc30
-rw-r--r--chromium/content/browser/download/resource_downloader.cc198
-rw-r--r--chromium/content/browser/download/resource_downloader.h69
-rw-r--r--chromium/content/browser/download/save_file.cc4
-rw-r--r--chromium/content/browser/download/save_file_manager.cc4
-rw-r--r--chromium/content/browser/download/save_package.cc195
-rw-r--r--chromium/content/browser/download/save_package.h10
-rw-r--r--chromium/content/browser/download/save_package_browsertest.cc2
-rw-r--r--chromium/content/browser/download/slow_download_http_response.cc106
-rw-r--r--chromium/content/browser/download/slow_download_http_response.h49
-rw-r--r--chromium/content/browser/download/url_downloader.cc2
-rw-r--r--chromium/content/browser/field_trial_recorder.cc2
-rw-r--r--chromium/content/browser/file_url_loader_factory.cc589
-rw-r--r--chromium/content/browser/file_url_loader_factory.h49
-rw-r--r--chromium/content/browser/fileapi/DEPS3
-rw-r--r--chromium/content/browser/fileapi/OWNERS2
-rw-r--r--chromium/content/browser/fileapi/browser_file_system_helper.cc4
-rw-r--r--chromium/content/browser/fileapi/file_system_operation_runner_unittest.cc1
-rw-r--r--chromium/content/browser/fileapi/fileapi_message_filter.cc17
-rw-r--r--chromium/content/browser/fileapi/fileapi_message_filter_unittest.cc2
-rw-r--r--chromium/content/browser/fileapi/upload_file_system_file_element_reader.cc118
-rw-r--r--chromium/content/browser/fileapi/upload_file_system_file_element_reader.h71
-rw-r--r--chromium/content/browser/fileapi/upload_file_system_file_element_reader_unittest.cc283
-rw-r--r--chromium/content/browser/find_request_manager.cc2
-rw-r--r--chromium/content/browser/find_request_manager_browsertest.cc11
-rw-r--r--chromium/content/browser/frame_host/ancestor_throttle.cc3
-rw-r--r--chromium/content/browser/frame_host/cross_process_frame_connector.cc148
-rw-r--r--chromium/content/browser/frame_host/cross_process_frame_connector.h41
-rw-r--r--chromium/content/browser/frame_host/data_url_navigation_browsertest.cc20
-rw-r--r--chromium/content/browser/frame_host/data_url_navigation_throttle.cc6
-rw-r--r--chromium/content/browser/frame_host/debug_urls.cc17
-rw-r--r--chromium/content/browser/frame_host/debug_urls.h6
-rw-r--r--chromium/content/browser/frame_host/form_submission_throttle.cc22
-rw-r--r--chromium/content/browser/frame_host/form_submission_throttle.h8
-rw-r--r--chromium/content/browser/frame_host/form_submission_throttle_browsertest.cc21
-rw-r--r--chromium/content/browser/frame_host/frame_navigation_entry.cc13
-rw-r--r--chromium/content/browser/frame_host/frame_navigation_entry.h2
-rw-r--r--chromium/content/browser/frame_host/frame_tree.cc42
-rw-r--r--chromium/content/browser/frame_host/frame_tree.h15
-rw-r--r--chromium/content/browser/frame_host/frame_tree_browsertest.cc181
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node.cc103
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node.h139
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node_blame_context.cc2
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc17
-rw-r--r--chromium/content/browser/frame_host/frame_tree_unittest.cc227
-rw-r--r--chromium/content/browser/frame_host/input/OWNERS1
-rw-r--r--chromium/content/browser/frame_host/input/input_injector_impl.cc2
-rw-r--r--chromium/content/browser/frame_host/input/legacy_ipc_frame_input_handler.cc49
-rw-r--r--chromium/content/browser/frame_host/input/legacy_ipc_frame_input_handler.h3
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_impl.cc23
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_impl.h1
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_impl_browsertest.cc105
-rw-r--r--chromium/content/browser/frame_host/keep_alive_handle_factory.cc17
-rw-r--r--chromium/content/browser/frame_host/keep_alive_handle_factory.h8
-rw-r--r--chromium/content/browser/frame_host/mixed_content_navigation_throttle.cc33
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_android.cc25
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.cc85
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc530
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc135
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl.cc99
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl.h10
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc11
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_screenshot_manager.cc2
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl.cc139
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl.h35
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc362
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc980
-rw-r--r--chromium/content/browser/frame_host/navigation_request.cc146
-rw-r--r--chromium/content/browser/frame_host/navigation_request.h57
-rw-r--r--chromium/content/browser/frame_host/navigation_request_info.cc3
-rw-r--r--chromium/content/browser/frame_host/navigation_request_info.h25
-rw-r--r--chromium/content/browser/frame_host/navigator.cc2
-rw-r--r--chromium/content/browser/frame_host/navigator.h9
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.cc36
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.h1
-rw-r--r--chromium/content/browser/frame_host/navigator_impl_unittest.cc131
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_android.cc25
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_android.h5
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_delegate.cc5
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_delegate.h13
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_factory.cc4
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc37
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl.cc695
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl.h202
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc141
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager.cc184
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager.h14
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc389
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc347
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter.cc93
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter.h8
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc11
-rw-r--r--chromium/content/browser/frame_host/render_frame_proxy_host.cc7
-rw-r--r--chromium/content/browser/frame_host/render_frame_proxy_host.h15
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest.cc164
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest.h35
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc14
-rw-r--r--chromium/content/browser/generic_sensor_browsertest.cc62
-rw-r--r--chromium/content/browser/geolocation/geolocation_service_impl.cc37
-rw-r--r--chromium/content/browser/geolocation/geolocation_service_impl.h17
-rw-r--r--chromium/content/browser/geolocation/geolocation_service_impl_unittest.cc36
-rw-r--r--chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc141
-rw-r--r--chromium/content/browser/gpu/browser_gpu_channel_host_factory.h16
-rw-r--r--chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc4
-rw-r--r--chromium/content/browser/gpu/compositor_util.cc32
-rw-r--r--chromium/content/browser/gpu/gpu_client.cc89
-rw-r--r--chromium/content/browser/gpu/gpu_client.h14
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl.cc17
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl.h4
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private.cc85
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private.h4
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc53
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_testing_arrays_and_structs_autogen.h8
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_testing_autogen.cc2
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_testing_autogen.h1
-rw-r--r--chromium/content/browser/gpu/gpu_feature_checker_impl.cc2
-rw-r--r--chromium/content/browser/gpu/gpu_internals_ui.cc139
-rw-r--r--chromium/content/browser/gpu/gpu_ipc_browsertests.cc134
-rw-r--r--chromium/content/browser/gpu/gpu_main_thread_factory.h7
-rw-r--r--chromium/content/browser/gpu/gpu_process_host.cc173
-rw-r--r--chromium/content/browser/gpu/gpu_process_host.h29
-rw-r--r--chromium/content/browser/histogram_controller.cc6
-rw-r--r--chromium/content/browser/histogram_internals_url_loader.cc2
-rw-r--r--chromium/content/browser/histogram_message_filter.cc54
-rw-r--r--chromium/content/browser/histogram_message_filter.h37
-rw-r--r--chromium/content/browser/histogram_synchronizer.cc4
-rw-r--r--chromium/content/browser/host_zoom_map_impl.cc212
-rw-r--r--chromium/content/browser/host_zoom_map_impl.h25
-rw-r--r--chromium/content/browser/host_zoom_map_impl_unittest.cc18
-rw-r--r--chromium/content/browser/host_zoom_map_observer.cc2
-rw-r--r--chromium/content/browser/hyphenation/hyphenation_impl.cc2
-rw-r--r--chromium/content/browser/image_capture/image_capture_impl.cc2
-rw-r--r--chromium/content/browser/indexed_db/cursor_impl.cc4
-rw-r--r--chromium/content/browser/indexed_db/database_impl.cc14
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc2
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_active_blob_registry_unittest.cc2
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_backing_store.cc58
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc30
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_browsertest.cc8
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_callbacks.cc12
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc18
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_connection.cc2
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_context_impl.cc41
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_context_impl.h6
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_database.cc20
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_database_unittest.cc30
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc2
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc52
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_impl.cc138
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_impl.h27
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc200
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc13
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_index_writer.cc2
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_internals_ui.cc18
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc21
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h5
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_leveldb_operations.cc24
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_leveldb_operations.h8
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_quota_client_unittest.cc2
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper.cc12
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper_unittest.cc4
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_transaction.cc2
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_transaction_unittest.cc18
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_unittest.cc16
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_database.cc42
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_database.h1
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc4
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_unittest.cc7
-rw-r--r--chromium/content/browser/indexed_db/leveldb_coding_scheme.md1
-rw-r--r--chromium/content/browser/indexed_db/list_set_unittest.cc6
-rw-r--r--chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc4
-rw-r--r--chromium/content/browser/installedapp/installed_app_provider_impl_default.cc2
-rw-r--r--chromium/content/browser/interface_provider_filtering.cc57
-rw-r--r--chromium/content/browser/interface_provider_filtering.h29
-rw-r--r--chromium/content/browser/isolated_origin_browsertest.cc83
-rw-r--r--chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.cc4
-rw-r--r--chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.h5
-rw-r--r--chromium/content/browser/leveldb_wrapper_impl.cc624
-rw-r--r--chromium/content/browser/leveldb_wrapper_impl.h163
-rw-r--r--chromium/content/browser/leveldb_wrapper_impl_unittest.cc1236
-rw-r--r--chromium/content/browser/loader/DEPS351
-rw-r--r--chromium/content/browser/loader/async_resource_handler.cc98
-rw-r--r--chromium/content/browser/loader/async_resource_handler.h1
-rw-r--r--chromium/content/browser/loader/async_resource_handler_browsertest.cc17
-rw-r--r--chromium/content/browser/loader/async_resource_handler_unittest.cc77
-rw-r--r--chromium/content/browser/loader/cross_site_document_resource_handler_unittest.cc3
-rw-r--r--chromium/content/browser/loader/cross_site_resource_handler_browsertest.cc2
-rw-r--r--chromium/content/browser/loader/detachable_resource_handler.cc21
-rw-r--r--chromium/content/browser/loader/detachable_resource_handler_unittest.cc23
-rw-r--r--chromium/content/browser/loader/downloaded_temp_file_impl.cc2
-rw-r--r--chromium/content/browser/loader/intercepting_resource_handler.cc20
-rw-r--r--chromium/content/browser/loader/intercepting_resource_handler_unittest.cc21
-rw-r--r--chromium/content/browser/loader/loader_delegate.h5
-rw-r--r--chromium/content/browser/loader/mime_sniffing_resource_handler.cc74
-rw-r--r--chromium/content/browser/loader/mime_sniffing_resource_handler_unittest.cc98
-rw-r--r--chromium/content/browser/loader/mock_resource_loader.cc14
-rw-r--r--chromium/content/browser/loader/mojo_async_resource_handler.cc57
-rw-r--r--chromium/content/browser/loader/mojo_async_resource_handler.h3
-rw-r--r--chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc21
-rw-r--r--chromium/content/browser/loader/navigation_resource_handler.cc21
-rw-r--r--chromium/content/browser/loader/navigation_resource_handler.h8
-rw-r--r--chromium/content/browser/loader/navigation_resource_throttle.cc20
-rw-r--r--chromium/content/browser/loader/navigation_url_loader.cc14
-rw-r--r--chromium/content/browser/loader/navigation_url_loader.h18
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_delegate.h25
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl.cc14
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl.h3
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl_core.cc21
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl_core.h5
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_network_service.cc319
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_network_service.h16
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_network_service_unittest.cc30
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_unittest.cc31
-rw-r--r--chromium/content/browser/loader/redirect_to_file_resource_handler.cc20
-rw-r--r--chromium/content/browser/loader/redirect_to_file_resource_handler_unittest.cc8
-rw-r--r--chromium/content/browser/loader/resource_buffer.cc2
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc32
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_impl.cc314
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_impl.h12
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_unittest.cc93
-rw-r--r--chromium/content/browser/loader/resource_handler.cc9
-rw-r--r--chromium/content/browser/loader/resource_handler.h1
-rw-r--r--chromium/content/browser/loader/resource_hints_impl.cc4
-rw-r--r--chromium/content/browser/loader/resource_loader.cc35
-rw-r--r--chromium/content/browser/loader/resource_loader.h10
-rw-r--r--chromium/content/browser/loader/resource_loader_unittest.cc31
-rw-r--r--chromium/content/browser/loader/resource_message_filter.cc26
-rw-r--r--chromium/content/browser/loader/resource_message_filter.h10
-rw-r--r--chromium/content/browser/loader/resource_request_info_impl.cc99
-rw-r--r--chromium/content/browser/loader/resource_request_info_impl.h14
-rw-r--r--chromium/content/browser/loader/resource_scheduler.cc4
-rw-r--r--chromium/content/browser/loader/resource_scheduler_browsertest.cc37
-rw-r--r--chromium/content/browser/loader/resource_scheduler_unittest.cc16
-rw-r--r--chromium/content/browser/loader/stream_resource_handler.cc5
-rw-r--r--chromium/content/browser/loader/stream_writer.cc10
-rw-r--r--chromium/content/browser/loader/stream_writer.h9
-rw-r--r--chromium/content/browser/loader/temporary_file_stream_unittest.cc4
-rw-r--r--chromium/content/browser/loader/test_resource_handler.cc2
-rw-r--r--chromium/content/browser/loader/throttling_resource_handler_unittest.cc2
-rw-r--r--chromium/content/browser/loader/upload_data_stream_builder.cc25
-rw-r--r--chromium/content/browser/loader/upload_data_stream_builder_unittest.cc6
-rw-r--r--chromium/content/browser/loader/url_loader_factory_impl_unittest.cc2
-rw-r--r--chromium/content/browser/loader/url_loader_request_handler.cc10
-rw-r--r--chromium/content/browser/loader/url_loader_request_handler.h15
-rw-r--r--chromium/content/browser/loader/wake_lock_resource_throttle.cc6
-rw-r--r--chromium/content/browser/loader_delegate_impl.cc20
-rw-r--r--chromium/content/browser/loader_delegate_impl.h3
-rw-r--r--chromium/content/browser/manifest/manifest_browsertest.cc50
-rw-r--r--chromium/content/browser/manifest/manifest_manager_host.cc16
-rw-r--r--chromium/content/browser/manifest/manifest_manager_host.h4
-rw-r--r--chromium/content/browser/media/android/browser_media_player_manager.cc18
-rw-r--r--chromium/content/browser/media/android/media_player_renderer.cc43
-rw-r--r--chromium/content/browser/media/android/media_player_renderer.h16
-rw-r--r--chromium/content/browser/media/android/media_player_renderer_web_contents_observer.cc47
-rw-r--r--chromium/content/browser/media/android/media_player_renderer_web_contents_observer.h45
-rw-r--r--chromium/content/browser/media/audible_metrics.cc8
-rw-r--r--chromium/content/browser/media/audible_metrics.h4
-rw-r--r--chromium/content/browser/media/audible_metrics_unittest.cc14
-rw-r--r--chromium/content/browser/media/audio_stream_monitor.cc2
-rw-r--r--chromium/content/browser/media/audio_stream_monitor.h5
-rw-r--r--chromium/content/browser/media/capture/audio_mirroring_manager.cc19
-rw-r--r--chromium/content/browser/media/capture/aura_window_capture_machine.cc33
-rw-r--r--chromium/content/browser/media/capture/aura_window_capture_machine.h3
-rw-r--r--chromium/content/browser/media/capture/cursor_renderer.cc2
-rw-r--r--chromium/content/browser/media/capture/cursor_renderer.h1
-rw-r--r--chromium/content/browser/media/capture/cursor_renderer_aura.cc2
-rw-r--r--chromium/content/browser/media/capture/cursor_renderer_mac.mm2
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device.cc14
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device_unittest.cc5
-rw-r--r--chromium/content/browser/media/capture/fake_webcontent_capture_machine.cc36
-rw-r--r--chromium/content/browser/media/capture/fake_webcontent_capture_machine.h41
-rw-r--r--chromium/content/browser/media/capture/screen_capture_device_android.cc2
-rw-r--r--chromium/content/browser/media/capture/screen_capture_device_android_unittest.cc4
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_input_stream.cc15
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc12
-rw-r--r--chromium/content/browser/media/capture/web_contents_video_capture_device.cc45
-rw-r--r--chromium/content/browser/media/capture/web_contents_video_capture_device_unittest.cc22
-rw-r--r--chromium/content/browser/media/cdm_file_impl.cc363
-rw-r--r--chromium/content/browser/media/cdm_file_impl.h123
-rw-r--r--chromium/content/browser/media/cdm_storage_impl.cc255
-rw-r--r--chromium/content/browser/media/cdm_storage_impl.h70
-rw-r--r--chromium/content/browser/media/cdm_storage_impl_unittest.cc181
-rw-r--r--chromium/content/browser/media/encrypted_media_browsertest.cc22
-rw-r--r--chromium/content/browser/media/media_browsertest.cc27
-rw-r--r--chromium/content/browser/media/media_browsertest.h6
-rw-r--r--chromium/content/browser/media/media_canplaytype_browsertest.cc39
-rw-r--r--chromium/content/browser/media/media_capabilities_browsertest.cc176
-rw-r--r--chromium/content/browser/media/media_color_browsertest.cc4
-rw-r--r--chromium/content/browser/media/media_devices_permission_checker.cc6
-rw-r--r--chromium/content/browser/media/media_devices_permission_checker_unittest.cc10
-rw-r--r--chromium/content/browser/media/media_devices_util.cc16
-rw-r--r--chromium/content/browser/media/media_devices_util.h16
-rw-r--r--chromium/content/browser/media/media_interface_proxy.cc10
-rw-r--r--chromium/content/browser/media/media_internals.cc8
-rw-r--r--chromium/content/browser/media/media_internals_ui.cc2
-rw-r--r--chromium/content/browser/media/media_internals_unittest.cc2
-rw-r--r--chromium/content/browser/media/media_redirect_browsertest.cc2
-rw-r--r--chromium/content/browser/media/media_source_browsertest.cc30
-rw-r--r--chromium/content/browser/media/media_web_contents_observer.cc16
-rw-r--r--chromium/content/browser/media/midi_host.cc2
-rw-r--r--chromium/content/browser/media/session/OWNERS1
-rw-r--r--chromium/content/browser/media/session/audio_focus_manager_unittest.cc2
-rw-r--r--chromium/content/browser/media/session/media_session_android.cc23
-rw-r--r--chromium/content/browser/media/session/media_session_android.h6
-rw-r--r--chromium/content/browser/media/session/media_session_browsertest.cc6
-rw-r--r--chromium/content/browser/media/session/media_session_controller.cc14
-rw-r--r--chromium/content/browser/media/session/media_session_controller.h2
-rw-r--r--chromium/content/browser/media/session/media_session_controller_unittest.cc39
-rw-r--r--chromium/content/browser/media/session/media_session_impl.cc11
-rw-r--r--chromium/content/browser/media/session/media_session_impl.h6
-rw-r--r--chromium/content/browser/media/session/media_session_impl_browsertest.cc236
-rw-r--r--chromium/content/browser/media/session/media_session_impl_service_routing_unittest.cc8
-rw-r--r--chromium/content/browser/media/session/media_session_impl_uma_unittest.cc2
-rw-r--r--chromium/content/browser/media/session/media_session_impl_visibility_browsertest.cc18
-rw-r--r--chromium/content/browser/media/session/media_session_player_observer.h8
-rw-r--r--chromium/content/browser/media/session/media_session_service_impl_browsertest.cc2
-rw-r--r--chromium/content/browser/media/session/media_session_uma_helper.cc8
-rw-r--r--chromium/content/browser/media/session/media_session_uma_helper.h4
-rw-r--r--chromium/content/browser/media/session/media_session_uma_helper_unittest.cc14
-rw-r--r--chromium/content/browser/media/session/mock_media_session_observer.h5
-rw-r--r--chromium/content/browser/media/session/mock_media_session_player_observer.cc22
-rw-r--r--chromium/content/browser/media/session/mock_media_session_player_observer.h12
-rw-r--r--chromium/content/browser/media/session/pepper_playback_observer.cc14
-rw-r--r--chromium/content/browser/media/session/pepper_player_delegate.cc22
-rw-r--r--chromium/content/browser/media/session/pepper_player_delegate.h2
-rw-r--r--chromium/content/browser/media/url_provision_fetcher.cc2
-rw-r--r--chromium/content/browser/memory/memory_coordinator_impl.cc10
-rw-r--r--chromium/content/browser/memory/memory_coordinator_impl.h4
-rw-r--r--chromium/content/browser/memory/memory_coordinator_impl_unittest.cc20
-rw-r--r--chromium/content/browser/memory/memory_monitor_android.cc11
-rw-r--r--chromium/content/browser/memory/memory_monitor_chromeos.cc2
-rw-r--r--chromium/content/browser/memory/memory_monitor_linux.cc2
-rw-r--r--chromium/content/browser/memory/swap_metrics_driver_impl_linux.cc12
-rw-r--r--chromium/content/browser/mime_registry_impl.cc2
-rw-r--r--chromium/content/browser/mus_util.cc21
-rw-r--r--chromium/content/browser/mus_util.h16
-rw-r--r--chromium/content/browser/net/network_errors_listing_ui.cc13
-rw-r--r--chromium/content/browser/net/network_quality_observer_impl.cc4
-rw-r--r--chromium/content/browser/net/quota_policy_cookie_store.cc3
-rw-r--r--chromium/content/browser/net/reporting_service_proxy.cc41
-rw-r--r--chromium/content/browser/net/view_http_cache_job_factory.cc2
-rw-r--r--chromium/content/browser/net_info_browsertest.cc36
-rw-r--r--chromium/content/browser/network_service_browsertest.cc158
-rw-r--r--chromium/content/browser/network_service_client.cc60
-rw-r--r--chromium/content/browser/network_service_client.h37
-rw-r--r--chromium/content/browser/network_service_restart_browsertest.cc98
-rw-r--r--chromium/content/browser/notification_service_impl.cc4
-rw-r--r--chromium/content/browser/notifications/OWNERS2
-rw-r--r--chromium/content/browser/notifications/blink_notification_service_impl.cc6
-rw-r--r--chromium/content/browser/notifications/blink_notification_service_impl.h8
-rw-r--r--chromium/content/browser/notifications/notification_database.cc25
-rw-r--r--chromium/content/browser/notifications/notification_database_data_unittest.cc6
-rw-r--r--chromium/content/browser/notifications/notification_event_dispatcher_impl.cc32
-rw-r--r--chromium/content/browser/notifications/notification_event_dispatcher_impl.h6
-rw-r--r--chromium/content/browser/notifications/notification_id_generator.cc30
-rw-r--r--chromium/content/browser/notifications/notification_id_generator.h22
-rw-r--r--chromium/content/browser/notifications/notification_id_generator_unittest.cc289
-rw-r--r--chromium/content/browser/notifications/notification_message_filter.cc29
-rw-r--r--chromium/content/browser/notifications/notification_message_filter.h10
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_impl.cc10
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_impl.h6
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_unittest.cc3
-rw-r--r--chromium/content/browser/origin_manifest/origin_manifest_parser.cc105
-rw-r--r--chromium/content/browser/origin_manifest/origin_manifest_parser.h54
-rw-r--r--chromium/content/browser/origin_manifest/origin_manifest_parser_unittest.cc386
-rw-r--r--chromium/content/browser/payments/payment_app.proto2
-rw-r--r--chromium/content/browser/payments/payment_app_content_unittest_base.cc13
-rw-r--r--chromium/content/browser/payments/payment_app_context_impl.cc2
-rw-r--r--chromium/content/browser/payments/payment_app_database.cc19
-rw-r--r--chromium/content/browser/payments/payment_app_info_fetcher.cc130
-rw-r--r--chromium/content/browser/payments/payment_app_info_fetcher.h19
-rw-r--r--chromium/content/browser/payments/payment_app_provider_impl.cc3
-rw-r--r--chromium/content/browser/payments/payment_app_provider_impl_unittest.cc19
-rw-r--r--chromium/content/browser/pepper_flash_settings_helper_impl.cc2
-rw-r--r--chromium/content/browser/permissions/permission_service_context.cc4
-rw-r--r--chromium/content/browser/permissions/permission_service_impl.cc35
-rw-r--r--chromium/content/browser/permissions/permission_service_impl_unittest.cc17
-rw-r--r--chromium/content/browser/plugin_data_remover_impl.cc11
-rw-r--r--chromium/content/browser/plugin_private_storage_helper.cc4
-rw-r--r--chromium/content/browser/plugin_service_impl.cc34
-rw-r--r--chromium/content/browser/plugin_service_impl.h1
-rw-r--r--chromium/content/browser/plugin_service_impl_unittest.cc108
-rw-r--r--chromium/content/browser/pointer_lock_browsertest.cc15
-rw-r--r--chromium/content/browser/ppapi_plugin_process_host.cc50
-rw-r--r--chromium/content/browser/presentation/OWNERS1
-rw-r--r--chromium/content/browser/presentation/presentation_service_impl.h2
-rw-r--r--chromium/content/browser/presentation/presentation_service_impl_unittest.cc10
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_manager.cc4
-rw-r--r--chromium/content/browser/quota_dispatcher_host.cc166
-rw-r--r--chromium/content/browser/quota_dispatcher_host.h36
-rw-r--r--chromium/content/browser/renderer_host/OWNERS3
-rw-r--r--chromium/content/browser/renderer_host/browser_compositor_view_mac.h2
-rw-r--r--chromium/content/browser/renderer_host/browser_compositor_view_mac.mm10
-rw-r--r--chromium/content/browser/renderer_host/clipboard_host_impl.cc303
-rw-r--r--chromium/content/browser/renderer_host/clipboard_host_impl.h98
-rw-r--r--chromium/content/browser/renderer_host/clipboard_host_impl_mac.mm (renamed from chromium/content/browser/renderer_host/clipboard_message_filter_mac.mm)29
-rw-r--r--chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc (renamed from chromium/content/browser/renderer_host/clipboard_message_filter_unittest.cc)89
-rw-r--r--chromium/content/browser/renderer_host/clipboard_message_filter.cc328
-rw-r--r--chromium/content/browser/renderer_host/clipboard_message_filter.h113
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android.cc127
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android.h17
-rw-r--r--chromium/content/browser/renderer_host/compositor_resize_lock.cc10
-rw-r--r--chromium/content/browser/renderer_host/compositor_resize_lock.h1
-rw-r--r--chromium/content/browser/renderer_host/cursor_manager_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_host.cc208
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_host.h56
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_host_client_aura.cc6
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_host_client_aura.h1
-rw-r--r--chromium/content/browser/renderer_host/dip_util.cc3
-rw-r--r--chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc2
-rw-r--r--chromium/content/browser/renderer_host/file_utilities_host_impl.cc2
-rw-r--r--chromium/content/browser/renderer_host/font_utils_linux.cc4
-rw-r--r--chromium/content/browser/renderer_host/frame_connector_delegate.cc44
-rw-r--r--chromium/content/browser/renderer_host/frame_connector_delegate.h54
-rw-r--r--chromium/content/browser/renderer_host/input/OWNERS1
-rw-r--r--chromium/content/browser/renderer_host/input/composited_scrolling_browsertest.cc6
-rw-r--r--chromium/content/browser/renderer_host/input/gesture_event_queue.cc17
-rw-r--r--chromium/content/browser/renderer_host/input/gesture_event_queue.h23
-rw-r--r--chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc13
-rw-r--r--chromium/content/browser/renderer_host/input/input_disposition_handler.h8
-rw-r--r--chromium/content/browser/renderer_host/input/input_router.h5
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_client.h4
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl.cc87
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl.h15
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc1066
-rw-r--r--chromium/content/browser/renderer_host/input/legacy_input_router_impl.cc122
-rw-r--r--chromium/content/browser/renderer_host/input/legacy_input_router_impl.h27
-rw-r--r--chromium/content/browser/renderer_host/input/legacy_input_router_impl_perftest.cc6
-rw-r--r--chromium/content/browser/renderer_host/input/legacy_input_router_impl_unittest.cc152
-rw-r--r--chromium/content/browser/renderer_host/input/legacy_ipc_widget_input_handler.cc16
-rw-r--r--chromium/content/browser/renderer_host/input/legacy_touch_event_queue.cc652
-rw-r--r--chromium/content/browser/renderer_host/input/legacy_touch_event_queue.h210
-rw-r--r--chromium/content/browser/renderer_host/input/legacy_touch_event_queue_unittest.cc2680
-rw-r--r--chromium/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc8
-rw-r--r--chromium/content/browser/renderer_host/input/mock_input_disposition_handler.cc7
-rw-r--r--chromium/content/browser/renderer_host/input/mock_input_disposition_handler.h5
-rw-r--r--chromium/content/browser/renderer_host/input/mock_input_router_client.cc2
-rw-r--r--chromium/content/browser/renderer_host/input/mock_widget_input_handler.cc93
-rw-r--r--chromium/content/browser/renderer_host/input/mock_widget_input_handler.h68
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc107
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc68
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.h17
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc29
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc86
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.h23
-rw-r--r--chromium/content/browser/renderer_host/input/non_blocking_event_browsertest.cc4
-rw-r--r--chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.cc15
-rw-r--r--chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.h11
-rw-r--r--chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc12
-rw-r--r--chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc125
-rw-r--r--chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h36
-rw-r--r--chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc224
-rw-r--r--chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc8
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc7
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target.h5
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc17
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.cc4
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.h2
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer_action_unittest.cc5
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer_driver.cc6
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc34
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_browsertest.cc2
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc4
-rw-r--r--chromium/content/browser/renderer_host/input/touch_emulator.h2
-rw-r--r--chromium/content/browser/renderer_host/input/touch_event_queue.h12
-rw-r--r--chromium/content/browser/renderer_host/input/touch_input_browsertest.cc12
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc8
-rw-r--r--chromium/content/browser/renderer_host/input/touch_timeout_handler.h2
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_android.cc59
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_android.h26
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc27
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm7
-rw-r--r--chromium/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc149
-rw-r--r--chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc4
-rw-r--r--chromium/content/browser/renderer_host/legacy_render_widget_host_win.h4
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_delegate_impl.cc290
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_delegate_impl.h107
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_delegate_impl_unittest.cc345
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_device_manager.cc12
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_device_manager.h12
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_renderer_host.cc474
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_renderer_host.h131
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc59
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_sync_writer.cc10
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_sync_writer.h4
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc6
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc62
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_authorization_handler.h18
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc79
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_delegate_impl.cc20
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_delegate_impl.h2
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_delegate_impl_unittest.cc30
-rw-r--r--chromium/content/browser/renderer_host/media/audio_renderer_host.cc18
-rw-r--r--chromium/content/browser/renderer_host/media/audio_renderer_host.h6
-rw-r--r--chromium/content/browser/renderer_host/media/audio_renderer_host_unittest.cc48
-rw-r--r--chromium/content/browser/renderer_host/media/audio_sync_reader.cc23
-rw-r--r--chromium/content/browser/renderer_host/media/audio_sync_reader.h2
-rw-r--r--chromium/content/browser/renderer_host/media/audio_sync_reader_unittest.cc108
-rw-r--r--chromium/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc92
-rw-r--r--chromium/content/browser/renderer_host/media/fake_video_capture_device_launcher.h34
-rw-r--r--chromium/content/browser/renderer_host/media/fake_video_capture_provider.cc26
-rw-r--r--chromium/content/browser/renderer_host/media/fake_video_capture_provider.h30
-rw-r--r--chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc12
-rw-r--r--chromium/content/browser/renderer_host/media/in_process_video_capture_provider.cc6
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc166
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.h51
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc102
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_manager.cc88
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_manager_unittest.cc16
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc163
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.h72
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc186
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_manager.cc222
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_manager.h67
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc14
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_requester.h49
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc16
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc10
-rw-r--r--chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc18
-rw-r--r--chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc26
-rw-r--r--chromium/content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.cc9
-rw-r--r--chromium/content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.h4
-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.cc18
-rw-r--r--chromium/content/browser/renderer_host/media/service_video_capture_provider.cc6
-rw-r--r--chromium/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc15
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_browsertest.cc20
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc4
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_controller.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc10
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc137
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h31
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_host.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc8
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_provider_switcher.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_unittest.cc84
-rw-r--r--chromium/content/browser/renderer_host/offscreen_canvas_provider_impl.cc2
-rw-r--r--chromium/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc57
-rw-r--r--chromium/content/browser/renderer_host/offscreen_canvas_surface_impl.cc5
-rw-r--r--chromium/content/browser/renderer_host/offscreen_canvas_surface_impl.h1
-rw-r--r--chromium/content/browser/renderer_host/overscroll_configuration.cc50
-rw-r--r--chromium/content/browser/renderer_host/overscroll_controller.cc57
-rw-r--r--chromium/content/browser/renderer_host/overscroll_controller.h11
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc15
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h8
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc24
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_udp.cc14
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc6
-rw-r--r--chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_ref_host.cc4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc6
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc2
-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.cc2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.cc6
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_socket_utils.cc28
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc22
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_host.cc4
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_pango.cc6
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc6
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.cc6
-rw-r--r--chromium/content/browser/renderer_host/render_message_filter.cc107
-rw-r--r--chromium/content/browser/renderer_host/render_message_filter.h57
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_browsertest.cc95
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_impl.cc481
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_impl.h51
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_unittest.cc102
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate.cc8
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate.h3
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate_view.cc12
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate_view.h9
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_factory.cc2
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_impl.cc17
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_unittest.cc8
-rw-r--r--chromium/content/browser/renderer_host/render_widget_helper.cc4
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_delegate.cc4
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_delegate.h8
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_factory.cc42
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_factory.h69
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.cc207
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.h55
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc99
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_input_event_router.h11
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc22
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_unittest.cc428
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_android.cc226
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_android.h30
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura.cc163
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura.h39
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc2282
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_base.cc64
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_base.h43
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc112
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc174
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame.h48
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc68
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc49
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc58
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h9
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac.h22
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac.mm86
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm2
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm2
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm733
-rw-r--r--chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm2
-rw-r--r--chromium/content/browser/renderer_host/ui_events_helper.cc2
-rw-r--r--chromium/content/browser/renderer_host/ui_events_helper.h2
-rw-r--r--chromium/content/browser/renderer_host/web_database_host_impl.cc12
-rw-r--r--chromium/content/browser/renderer_host/web_database_host_impl.h12
-rw-r--r--chromium/content/browser/renderer_interface_binders.cc163
-rw-r--r--chromium/content/browser/renderer_interface_binders.h35
-rw-r--r--chromium/content/browser/resolve_proxy_msg_helper.cc9
-rw-r--r--chromium/content/browser/resolve_proxy_msg_helper_unittest.cc6
-rw-r--r--chromium/content/browser/resource_context_impl.cc7
-rw-r--r--chromium/content/browser/resources/accessibility/accessibility.html5
-rw-r--r--chromium/content/browser/resources/accessibility/accessibility.js26
-rw-r--r--chromium/content/browser/resources/gpu/browser_bridge_tests.js1
-rw-r--r--chromium/content/browser/resources/gpu/info_view.html5
-rw-r--r--chromium/content/browser/resources/gpu/info_view.js24
-rw-r--r--chromium/content/browser/resources/media/dump_creator.js8
-rw-r--r--chromium/content/browser/sandbox_ipc_linux.cc16
-rw-r--r--chromium/content/browser/sandbox_parameters_mac.mm34
-rw-r--r--chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc20
-rw-r--r--chromium/content/browser/security_exploit_browsertest.cc19
-rw-r--r--chromium/content/browser/service_manager/common_browser_interfaces.cc11
-rw-r--r--chromium/content/browser/service_manager/service_manager_context.cc136
-rw-r--r--chromium/content/browser/service_manager/service_manager_context_browsertest.cc78
-rw-r--r--chromium/content/browser/service_worker/OWNERS2
-rw-r--r--chromium/content/browser/service_worker/browser_side_controller_service_worker.cc237
-rw-r--r--chromium/content/browser/service_worker/browser_side_controller_service_worker.h79
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance.cc55
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance.h37
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc244
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_registry.cc7
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_registry.h6
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_test_helper.cc197
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_test_helper.h51
-rw-r--r--chromium/content/browser/service_worker/foreign_fetch_request_handler.cc317
-rw-r--r--chromium/content/browser/service_worker/foreign_fetch_request_handler.h152
-rw-r--r--chromium/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc406
-rw-r--r--chromium/content/browser/service_worker/link_header_support.cc178
-rw-r--r--chromium/content/browser/service_worker/link_header_support.h38
-rw-r--r--chromium/content/browser/service_worker/link_header_support_unittest.cc451
-rw-r--r--chromium/content/browser/service_worker/service_worker_blob_reader.cc5
-rw-r--r--chromium/content/browser/service_worker/service_worker_blob_reader.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_browsertest.cc392
-rw-r--r--chromium/content/browser/service_worker/service_worker_client_utils.cc49
-rw-r--r--chromium/content/browser/service_worker/service_worker_consts.cc52
-rw-r--r--chromium/content/browser/service_worker/service_worker_consts.h29
-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.cc111
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core.h22
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core_observer.h3
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc17
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_unittest.cc42
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_watcher.cc24
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_watcher.h3
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper.cc69
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper.h10
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc20
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler.h17
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc30
-rw-r--r--chromium/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc11
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.cc353
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.h27
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.proto4
-rw-r--r--chromium/content/browser/service_worker/service_worker_database_unittest.cc276
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host.cc670
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host.h91
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc541
-rw-r--r--chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc229
-rw-r--r--chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h55
-rw-r--r--chromium/content/browser/service_worker/service_worker_handle.cc13
-rw-r--r--chromium/content/browser/service_worker/service_worker_handle.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_handle_unittest.cc8
-rw-r--r--chromium/content/browser/service_worker/service_worker_info.cc7
-rw-r--r--chromium/content/browser/service_worker/service_worker_info.h7
-rw-r--r--chromium/content/browser/service_worker/service_worker_installed_scripts_sender.cc161
-rw-r--r--chromium/content/browser/service_worker/service_worker_installed_scripts_sender.h56
-rw-r--r--chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc315
-rw-r--r--chromium/content/browser/service_worker/service_worker_internals_ui.cc53
-rw-r--r--chromium/content/browser/service_worker/service_worker_job_unittest.cc179
-rw-r--r--chromium/content/browser/service_worker/service_worker_lifetime_tracker.cc7
-rw-r--r--chromium/content/browser/service_worker/service_worker_lifetime_tracker.h5
-rw-r--r--chromium/content/browser/service_worker/service_worker_lifetime_tracker_unittest.cc9
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics.cc24
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics.h7
-rw-r--r--chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc2
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host.cc562
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host.h130
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc511
-rw-r--r--chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc6
-rw-r--r--chromium/content/browser/service_worker/service_worker_register_job.cc62
-rw-r--r--chromium/content/browser/service_worker/service_worker_register_job.h5
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration.cc16
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration.h8
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_handle.cc106
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_handle.h91
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_object_host.cc346
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_object_host.h130
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_status.cc63
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_status.h11
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_unittest.cc652
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler.cc49
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler.h10
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc5
-rw-r--r--chromium/content/browser/service_worker/service_worker_response_info.cc15
-rw-r--r--chromium/content/browser/service_worker/service_worker_response_info.h4
-rw-r--r--chromium/content/browser/service_worker/service_worker_response_type.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_cache_map.cc4
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_cache_map.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_url_loader.cc43
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_url_loader.h4
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_url_loader_factory.cc9
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_url_loader_unittest.cc21
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage.cc140
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage.h51
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage_unittest.cc165
-rw-r--r--chromium/content/browser/service_worker/service_worker_test_utils.cc163
-rw-r--r--chromium/content/browser/service_worker/service_worker_test_utils.h62
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_loader_job.cc131
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_loader_job.h23
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_loader_job_unittest.cc136
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job.cc122
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job.h35
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc201
-rw-r--r--chromium/content/browser/service_worker/service_worker_version.cc311
-rw-r--r--chromium/content/browser/service_worker/service_worker_version.h176
-rw-r--r--chromium/content/browser/service_worker/service_worker_version_unittest.cc355
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc17
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc15
-rw-r--r--chromium/content/browser/shareable_file_reference_unittest.cc4
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_connector_impl.cc10
-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.cc33
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_host.h12
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_instance.cc48
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_instance.h29
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_instance_unittest.cc163
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl.cc118
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl.h30
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc402
-rw-r--r--chromium/content/browser/shared_worker/worker_browsertest.cc19
-rw-r--r--chromium/content/browser/site_instance_impl.cc85
-rw-r--r--chromium/content/browser/site_instance_impl.h26
-rw-r--r--chromium/content/browser/site_instance_impl_unittest.cc164
-rw-r--r--chromium/content/browser/site_per_process_browsertest.cc1298
-rw-r--r--chromium/content/browser/site_per_process_mac_browsertest.mm83
-rw-r--r--chromium/content/browser/snapshot_browsertest.cc23
-rw-r--r--chromium/content/browser/speech/audio_encoder.cc5
-rw-r--r--chromium/content/browser/speech/chunked_byte_buffer.cc2
-rw-r--r--chromium/content/browser/speech/chunked_byte_buffer_unittest.cc6
-rw-r--r--chromium/content/browser/speech/endpointer/endpointer.cc13
-rw-r--r--chromium/content/browser/speech/endpointer/endpointer_unittest.cc4
-rw-r--r--chromium/content/browser/speech/speech_recognition_engine.cc4
-rw-r--r--chromium/content/browser/speech/speech_recognition_engine_unittest.cc2
-rw-r--r--chromium/content/browser/speech/speech_recognition_manager_impl.cc12
-rw-r--r--chromium/content/browser/speech/speech_recognition_manager_impl.h1
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl.cc25
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl.h13
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_unittest.cc12
-rw-r--r--chromium/content/browser/ssl/ssl_error_handler.cc26
-rw-r--r--chromium/content/browser/ssl/ssl_error_handler.h13
-rw-r--r--chromium/content/browser/ssl/ssl_manager.cc48
-rw-r--r--chromium/content/browser/ssl/ssl_manager.h10
-rw-r--r--chromium/content/browser/ssl/ssl_manager_unittest.cc107
-rw-r--r--chromium/content/browser/storage_partition_impl.cc65
-rw-r--r--chromium/content/browser/storage_partition_impl.h25
-rw-r--r--chromium/content/browser/storage_partition_impl_map.cc25
-rw-r--r--chromium/content/browser/storage_partition_impl_unittest.cc30
-rw-r--r--chromium/content/browser/streams/stream.cc31
-rw-r--r--chromium/content/browser/streams/stream.h12
-rw-r--r--chromium/content/browser/streams/stream_context.cc2
-rw-r--r--chromium/content/browser/streams/stream_metadata.h41
-rw-r--r--chromium/content/browser/streams/stream_registry.cc2
-rw-r--r--chromium/content/browser/streams/stream_url_request_job.cc96
-rw-r--r--chromium/content/browser/streams/stream_url_request_job.h10
-rw-r--r--chromium/content/browser/streams/stream_url_request_job_unittest.cc24
-rw-r--r--chromium/content/browser/top_document_isolation_browsertest.cc10
-rw-r--r--chromium/content/browser/tracing/background_memory_tracing_observer.cc15
-rw-r--r--chromium/content/browser/tracing/background_memory_tracing_observer_unittest.cc19
-rw-r--r--chromium/content/browser/tracing/background_tracing_config_unittest.cc2
-rw-r--r--chromium/content/browser/tracing/background_tracing_manager_browsertest.cc4
-rw-r--r--chromium/content/browser/tracing/background_tracing_manager_impl.cc4
-rw-r--r--chromium/content/browser/tracing/etw_tracing_agent_win.cc6
-rw-r--r--chromium/content/browser/tracing/memory_instrumentation_browsertest.cc2
-rw-r--r--chromium/content/browser/tracing/memory_tracing_browsertest.cc25
-rw-r--r--chromium/content/browser/tracing/tracing_controller_browsertest.cc6
-rw-r--r--chromium/content/browser/tracing/tracing_controller_impl.cc150
-rw-r--r--chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc14
-rw-r--r--chromium/content/browser/tracing/tracing_ui.cc2
-rw-r--r--chromium/content/browser/url_loader_factory_getter.cc20
-rw-r--r--chromium/content/browser/url_loader_factory_getter.h16
-rw-r--r--chromium/content/browser/utility_process_host_impl.cc77
-rw-r--r--chromium/content/browser/utility_process_host_impl.h6
-rw-r--r--chromium/content/browser/utility_process_host_impl_browsertest.cc3
-rw-r--r--chromium/content/browser/web_contents/aura/OWNERS2
-rw-r--r--chromium/content/browser/web_contents/aura/gesture_nav_simple.cc78
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc34
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc5
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_window_delegate.cc19
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_window_delegate.h10
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_window_delegate_unittest.cc4
-rw-r--r--chromium/content/browser/web_contents/aura/shadow_layer_delegate.cc4
-rw-r--r--chromium/content/browser/web_contents/aura/shadow_layer_delegate.h1
-rw-r--r--chromium/content/browser/web_contents/opened_by_dom_browsertest.cc2
-rw-r--r--chromium/content/browser/web_contents/web_contents_android.cc23
-rw-r--r--chromium/content/browser/web_contents/web_contents_delegate_unittest.cc16
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl.cc348
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl.h44
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl_browsertest.cc81
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl_unittest.cc53
-rw-r--r--chromium/content/browser/web_contents/web_contents_user_data_unittest.cc32
-rw-r--r--chromium/content/browser/web_contents/web_contents_view.h5
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_android.cc81
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_android.h17
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura.cc192
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura.h7
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc23
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_child_frame.cc12
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_child_frame.h1
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_guest.cc19
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_guest.h1
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mac.h6
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mac.mm63
-rw-r--r--chromium/content/browser/web_contents/web_drag_dest_mac.h9
-rw-r--r--chromium/content/browser/web_contents/web_drag_dest_mac.mm26
-rw-r--r--chromium/content/browser/web_contents/web_drag_source_mac.h5
-rw-r--r--chromium/content/browser/web_contents/web_drag_source_mac.mm15
-rw-r--r--chromium/content/browser/web_contents_binding_set_browsertest.cc8
-rw-r--r--chromium/content/browser/webauth/DEPS3
-rw-r--r--chromium/content/browser/webauth/attestation_object.cc40
-rw-r--r--chromium/content/browser/webauth/attestation_object.h43
-rw-r--r--chromium/content/browser/webauth/attestation_statement.cc17
-rw-r--r--chromium/content/browser/webauth/attestation_statement.h44
-rw-r--r--chromium/content/browser/webauth/attested_credential_data.cc61
-rw-r--r--chromium/content/browser/webauth/attested_credential_data.h56
-rw-r--r--chromium/content/browser/webauth/authenticator_data.cc63
-rw-r--r--chromium/content/browser/webauth/authenticator_data.h70
-rw-r--r--chromium/content/browser/webauth/authenticator_impl.cc205
-rw-r--r--chromium/content/browser/webauth/authenticator_impl.h54
-rw-r--r--chromium/content/browser/webauth/authenticator_impl_unittest.cc557
-rw-r--r--chromium/content/browser/webauth/authenticator_utils.cc29
-rw-r--r--chromium/content/browser/webauth/authenticator_utils.h39
-rw-r--r--chromium/content/browser/webauth/cbor/cbor_values.h36
-rw-r--r--chromium/content/browser/webauth/cbor/cbor_writer.cc70
-rw-r--r--chromium/content/browser/webauth/cbor/cbor_writer.h59
-rw-r--r--chromium/content/browser/webauth/cbor/cbor_writer_unittest.cc228
-rw-r--r--chromium/content/browser/webauth/collected_client_data.cc71
-rw-r--r--chromium/content/browser/webauth/collected_client_data.h56
-rw-r--r--chromium/content/browser/webauth/ec_public_key.cc54
-rw-r--r--chromium/content/browser/webauth/ec_public_key.h48
-rw-r--r--chromium/content/browser/webauth/fido_attestation_statement.cc102
-rw-r--r--chromium/content/browser/webauth/fido_attestation_statement.h43
-rw-r--r--chromium/content/browser/webauth/public_key.cc18
-rw-r--r--chromium/content/browser/webauth/public_key.h35
-rw-r--r--chromium/content/browser/webauth/register_response_data.cc89
-rw-r--r--chromium/content/browser/webauth/register_response_data.h52
-rw-r--r--chromium/content/browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc88
-rw-r--r--chromium/content/browser/webrtc/webrtc_browsertest.cc14
-rw-r--r--chromium/content/browser/webrtc/webrtc_capture_from_element_browsertest.cc20
-rw-r--r--chromium/content/browser/webrtc/webrtc_eventlog_host.cc80
-rw-r--r--chromium/content/browser/webrtc/webrtc_eventlog_host.h22
-rw-r--r--chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc161
-rw-r--r--chromium/content/browser/webrtc/webrtc_image_capture_browsertest.cc46
-rw-r--r--chromium/content/browser/webrtc/webrtc_internals.cc83
-rw-r--r--chromium/content/browser/webrtc/webrtc_internals.h5
-rw-r--r--chromium/content/browser/webrtc/webrtc_internals_browsertest.cc12
-rw-r--r--chromium/content/browser/webrtc/webrtc_internals_ui.cc2
-rw-r--r--chromium/content/browser/webrtc/webrtc_internals_unittest.cc18
-rw-r--r--chromium/content/browser/webrtc/webrtc_pause_play_browsertest.cc62
-rw-r--r--chromium/content/browser/webrtc/webrtc_video_capture_browsertest.cc14
-rw-r--r--chromium/content/browser/webui/i18n_source_stream.cc71
-rw-r--r--chromium/content/browser/webui/i18n_source_stream.h61
-rw-r--r--chromium/content/browser/webui/i18n_source_stream_unittest.cc265
-rw-r--r--chromium/content/browser/webui/network_error_url_loader.cc6
-rw-r--r--chromium/content/browser/webui/shared_resources_data_source.cc5
-rw-r--r--chromium/content/browser/webui/url_data_manager.cc4
-rw-r--r--chromium/content/browser/webui/url_data_manager_backend.cc6
-rw-r--r--chromium/content/browser/webui/web_ui_controller_factory_registry.cc37
-rw-r--r--chromium/content/browser/webui/web_ui_data_source_unittest.cc2
-rw-r--r--chromium/content/browser/webui/web_ui_impl.cc6
-rw-r--r--chromium/content/browser/webui/web_ui_mojo_browsertest.cc2
-rw-r--r--chromium/content/browser/webui/web_ui_url_loader_factory.cc89
-rw-r--r--chromium/content/browser/webui/web_ui_url_loader_factory.h11
-rw-r--r--chromium/content/browser/zygote_host/zygote_communication_linux.cc24
-rw-r--r--chromium/content/browser/zygote_host/zygote_host_impl_linux.cc7
-rw-r--r--chromium/content/child/BUILD.gn132
-rw-r--r--chromium/content/child/DEPS1
-rw-r--r--chromium/content/child/OWNERS5
-rw-r--r--chromium/content/child/blink_platform_impl.cc101
-rw-r--r--chromium/content/child/blink_platform_impl.h35
-rw-r--r--chromium/content/child/blink_platform_impl_unittest.cc4
-rw-r--r--chromium/content/child/browser_font_resource_trusted.cc6
-rw-r--r--chromium/content/child/child_histogram_fetcher_impl.cc5
-rw-r--r--chromium/content/child/child_process.cc9
-rw-r--r--chromium/content/child/child_process.h5
-rw-r--r--chromium/content/child/child_process_sandbox_support_impl_linux.cc14
-rw-r--r--chromium/content/child/child_thread_impl.cc176
-rw-r--r--chromium/content/child/child_thread_impl.h95
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc7
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc7
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h20
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc9
-rw-r--r--chromium/content/child/dwrite_font_proxy/font_fallback_win.cc7
-rw-r--r--chromium/content/child/dwrite_font_proxy/font_fallback_win.h10
-rw-r--r--chromium/content/child/dwrite_font_proxy/font_fallback_win_unittest.cc80
-rw-r--r--chromium/content/child/feature_policy/OWNERS1
-rw-r--r--chromium/content/child/feature_policy/feature_policy_platform.cc41
-rw-r--r--chromium/content/child/feature_policy/feature_policy_platform.h22
-rw-r--r--chromium/content/child/loader/cors_url_loader.cc108
-rw-r--r--chromium/content/child/push_messaging/OWNERS4
-rw-r--r--chromium/content/child/quota_message_filter.cc60
-rw-r--r--chromium/content/child/quota_message_filter.h49
-rw-r--r--chromium/content/child/runtime_features.cc41
-rw-r--r--chromium/content/child/service_worker/OWNERS4
-rw-r--r--chromium/content/child/service_worker/service_worker_dispatcher.cc619
-rw-r--r--chromium/content/child/service_worker/service_worker_dispatcher.h256
-rw-r--r--chromium/content/child/service_worker/service_worker_dispatcher_unittest.cc505
-rw-r--r--chromium/content/child/service_worker/service_worker_handle_reference.cc52
-rw-r--r--chromium/content/child/service_worker/service_worker_message_filter.cc97
-rw-r--r--chromium/content/child/service_worker/service_worker_message_filter.h56
-rw-r--r--chromium/content/child/service_worker/service_worker_provider_context.cc274
-rw-r--r--chromium/content/child/service_worker/service_worker_provider_context_unittest.cc155
-rw-r--r--chromium/content/child/service_worker/service_worker_subresource_loader_unittest.cc443
-rw-r--r--chromium/content/child/service_worker/web_service_worker_registration_impl.cc210
-rw-r--r--chromium/content/child/service_worker/web_service_worker_registration_impl.h114
-rw-r--r--chromium/content/child/web_database_impl.cc42
-rw-r--r--chromium/content/child/web_database_impl.h39
-rw-r--r--chromium/content/common/BUILD.gn91
-rw-r--r--chromium/content/common/DEPS13
-rw-r--r--chromium/content/common/OWNERS2
-rw-r--r--chromium/content/common/accessibility_messages.h5
-rw-r--r--chromium/content/common/android/OWNERS1
-rw-r--r--chromium/content/common/android/browser_side_navigation_policy_android.cc5
-rw-r--r--chromium/content/common/android/hash_set.h5
-rw-r--r--chromium/content/common/android/resource_request_body_android.cc11
-rw-r--r--chromium/content/common/android/sync_compositor_messages.h2
-rw-r--r--chromium/content/common/appcache.mojom50
-rw-r--r--chromium/content/common/appcache_interfaces.cc80
-rw-r--r--chromium/content/common/appcache_interfaces.h68
-rw-r--r--chromium/content/common/appcache_messages.h10
-rw-r--r--chromium/content/common/associated_interface_provider_impl.cc2
-rw-r--r--chromium/content/common/associated_interface_provider_impl.h5
-rw-r--r--chromium/content/common/associated_interface_registry_impl.cc8
-rw-r--r--chromium/content/common/associated_interface_registry_impl.h9
-rw-r--r--chromium/content/common/background_fetch/background_fetch_struct_traits.cc4
-rw-r--r--chromium/content/common/background_fetch/background_fetch_struct_traits.h8
-rw-r--r--chromium/content/common/background_fetch/background_fetch_struct_traits_unittest.cc11
-rw-r--r--chromium/content/common/background_fetch/background_fetch_types.h4
-rw-r--r--chromium/content/common/browser_plugin/browser_plugin_messages.h27
-rw-r--r--chromium/content/common/cache_storage/cache_storage_messages.h22
-rw-r--r--chromium/content/common/cache_storage/cache_storage_types.h13
-rw-r--r--chromium/content/common/child_control.mojom13
-rw-r--r--chromium/content/common/child_process_host_impl.cc42
-rw-r--r--chromium/content/common/child_process_host_impl.h5
-rw-r--r--chromium/content/common/child_process_messages.h106
-rw-r--r--chromium/content/common/clipboard.mojom85
-rw-r--r--chromium/content/common/clipboard.typemap11
-rw-r--r--chromium/content/common/clipboard_messages.h117
-rw-r--r--chromium/content/common/clipboard_struct_traits.h54
-rw-r--r--chromium/content/common/common_param_traits_unittest.cc17
-rw-r--r--chromium/content/common/common_sandbox_support_linux.cc11
-rw-r--r--chromium/content/common/content_message_generator.h21
-rw-r--r--chromium/content/common/content_param_traits.cc4
-rw-r--r--chromium/content/common/content_param_traits_macros.h11
-rw-r--r--chromium/content/common/content_security_policy/csp_context_unittest.cc6
-rw-r--r--chromium/content/common/content_security_policy/csp_source_list_unittest.cc19
-rw-r--r--chromium/content/common/content_security_policy/csp_source_unittest.cc17
-rw-r--r--chromium/content/common/content_switches_internal.cc15
-rw-r--r--chromium/content/common/content_switches_internal.h5
-rw-r--r--chromium/content/common/cross_site_document_classifier_unittest.cc12
-rw-r--r--chromium/content/common/cursors/webcursor.cc2
-rw-r--r--chromium/content/common/cursors/webcursor_aurax11.cc4
-rw-r--r--chromium/content/common/devtools.mojom131
-rw-r--r--chromium/content/common/devtools/devtools_network_conditions.cc31
-rw-r--r--chromium/content/common/devtools/devtools_network_controller.h54
-rw-r--r--chromium/content/common/devtools_messages.h32
-rw-r--r--chromium/content/common/drag_messages.h20
-rw-r--r--chromium/content/common/feature_policy/README.md134
-rw-r--r--chromium/content/common/feature_policy/feature_policy.cc244
-rw-r--r--chromium/content/common/feature_policy/feature_policy.h220
-rw-r--r--chromium/content/common/feature_policy/feature_policy_unittest.cc1007
-rw-r--r--chromium/content/common/font_cache_dispatcher_win.cc42
-rw-r--r--chromium/content/common/font_cache_dispatcher_win.h29
-rw-r--r--chromium/content/common/font_cache_win.mojom18
-rw-r--r--chromium/content/common/font_config_ipc_linux.cc6
-rw-r--r--chromium/content/common/font_list_fontconfig.cc2
-rw-r--r--chromium/content/common/font_list_mac.mm2
-rw-r--r--chromium/content/common/font_list_win.cc2
-rw-r--r--chromium/content/common/frame.mojom86
-rw-r--r--chromium/content/common/frame_messages.h158
-rw-r--r--chromium/content/common/frame_owner_properties.h2
-rw-r--r--chromium/content/common/frame_replication_state.cc7
-rw-r--r--chromium/content/common/frame_replication_state.h45
-rw-r--r--chromium/content/common/indexed_db/indexed_db.mojom4
-rw-r--r--chromium/content/common/input/OWNERS1
-rw-r--r--chromium/content/common/input/input_event_ack.h4
-rw-r--r--chromium/content/common/input/input_event_ack_state.cc34
-rw-r--r--chromium/content/common/input/input_event_struct_traits.cc76
-rw-r--r--chromium/content/common/input/input_handler.mojom5
-rw-r--r--chromium/content/common/input/input_param_traits.cc2
-rw-r--r--chromium/content/common/input/input_param_traits_unittest.cc10
-rw-r--r--chromium/content/common/input/synthetic_web_input_event_builders.cc4
-rw-r--r--chromium/content/common/input/synthetic_web_input_event_builders.h4
-rw-r--r--chromium/content/common/input/touch_event_stream_validator.cc2
-rw-r--r--chromium/content/common/input_messages.h15
-rw-r--r--chromium/content/common/leveldb_wrapper.mojom7
-rw-r--r--chromium/content/common/loader_util.cc71
-rw-r--r--chromium/content/common/loader_util.h7
-rw-r--r--chromium/content/common/mac/attributed_string_coder.h13
-rw-r--r--chromium/content/common/mac/attributed_string_coder.mm41
-rw-r--r--chromium/content/common/mac/attributed_string_coder_unittest.mm15
-rw-r--r--chromium/content/common/mac/font_descriptor.h36
-rw-r--r--chromium/content/common/mac/font_descriptor.mm25
-rw-r--r--chromium/content/common/mac/font_descriptor_unittest.mm114
-rw-r--r--chromium/content/common/mac/font_loader.h27
-rw-r--r--chromium/content/common/mac/font_loader.mm75
-rw-r--r--chromium/content/common/media/aec_dump_messages.h9
-rw-r--r--chromium/content/common/media/media_devices.mojom110
-rw-r--r--chromium/content/common/media/media_devices.typemap9
-rw-r--r--chromium/content/common/media/media_player_delegate_messages.h8
-rw-r--r--chromium/content/common/media/media_stream.mojom41
-rw-r--r--chromium/content/common/native_types.mojom3
-rw-r--r--chromium/content/common/native_types.typemap4
-rw-r--r--chromium/content/common/native_types_mac.typemap1
-rw-r--r--chromium/content/common/navigation_params.cc22
-rw-r--r--chromium/content/common/navigation_params.h20
-rw-r--r--chromium/content/common/navigation_params.typemap14
-rw-r--r--chromium/content/common/navigation_subresource_loader_params.cc23
-rw-r--r--chromium/content/common/navigation_subresource_loader_params.h34
-rw-r--r--chromium/content/common/net/url_fetcher.cc2
-rw-r--r--chromium/content/common/origin_trials/trial_policy_impl.cc7
-rw-r--r--chromium/content/common/origin_trials/trial_policy_impl.h6
-rw-r--r--chromium/content/common/origin_util.cc3
-rw-r--r--chromium/content/common/page_messages.h3
-rw-r--r--chromium/content/common/page_state.mojom110
-rw-r--r--chromium/content/common/page_state_serialization.cc463
-rw-r--r--chromium/content/common/page_state_serialization.h12
-rw-r--r--chromium/content/common/page_state_serialization_unittest.cc366
-rw-r--r--chromium/content/common/quarantine/quarantine_linux.cc4
-rw-r--r--chromium/content/common/quarantine/quarantine_linux_unittest.cc2
-rw-r--r--chromium/content/common/quarantine/quarantine_mac.mm6
-rw-r--r--chromium/content/common/quarantine/quarantine_win.cc6
-rw-r--r--chromium/content/common/quota_dispatcher_host.mojom35
-rw-r--r--chromium/content/common/quota_messages.h55
-rw-r--r--chromium/content/common/render_frame_message_filter.mojom9
-rw-r--r--chromium/content/common/render_message_filter.mojom30
-rw-r--r--chromium/content/common/render_process_messages.h74
-rw-r--r--chromium/content/common/renderer.mojom25
-rw-r--r--chromium/content/common/renderer_host.mojom14
-rw-r--r--chromium/content/common/resize_params.cc1
-rw-r--r--chromium/content/common/resize_params.h4
-rw-r--r--chromium/content/common/resource_messages.cc70
-rw-r--r--chromium/content/common/resource_messages.h41
-rw-r--r--chromium/content/common/sandbox_init_linux.cc (renamed from chromium/content/common/sandbox_linux/sandbox_init_linux.cc)8
-rw-r--r--chromium/content/common/sandbox_init_mac.cc31
-rw-r--r--chromium/content/common/sandbox_init_mac.h26
-rw-r--r--chromium/content/common/sandbox_init_win.cc58
-rw-r--r--chromium/content/common/sandbox_linux/OWNERS8
-rw-r--r--chromium/content/common/sandbox_linux/bpf_cdm_policy_linux.cc55
-rw-r--r--chromium/content/common/sandbox_linux/bpf_cdm_policy_linux.h28
-rw-r--r--chromium/content/common/sandbox_linux/bpf_cros_amd_gpu_policy_linux.cc171
-rw-r--r--chromium/content/common/sandbox_linux/bpf_cros_amd_gpu_policy_linux.h29
-rw-r--r--chromium/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc182
-rw-r--r--chromium/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h32
-rw-r--r--chromium/content/common/sandbox_linux/bpf_gpu_policy_linux.cc384
-rw-r--r--chromium/content/common/sandbox_linux/bpf_gpu_policy_linux.h65
-rw-r--r--chromium/content/common/sandbox_linux/bpf_pdf_compositor_policy_linux.cc55
-rw-r--r--chromium/content/common/sandbox_linux/bpf_pdf_compositor_policy_linux.h28
-rw-r--r--chromium/content/common/sandbox_linux/bpf_ppapi_policy_linux.cc50
-rw-r--r--chromium/content/common/sandbox_linux/bpf_ppapi_policy_linux.h28
-rw-r--r--chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.cc111
-rw-r--r--chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.h28
-rw-r--r--chromium/content/common/sandbox_linux/bpf_utility_policy_linux.cc55
-rw-r--r--chromium/content/common/sandbox_linux/bpf_utility_policy_linux.h28
-rw-r--r--chromium/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.cc46
-rw-r--r--chromium/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h51
-rw-r--r--chromium/content/common/sandbox_linux/sandbox_debug_handling_linux.cc80
-rw-r--r--chromium/content/common/sandbox_linux/sandbox_debug_handling_linux.h25
-rw-r--r--chromium/content/common/sandbox_linux/sandbox_linux.cc490
-rw-r--r--chromium/content/common/sandbox_linux/sandbox_linux.h195
-rw-r--r--chromium/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc299
-rw-r--r--chromium/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h61
-rw-r--r--chromium/content/common/sandbox_mac_diraccess_unittest.mm2
-rw-r--r--chromium/content/common/sandbox_mac_fontloading_unittest.mm43
-rw-r--r--chromium/content/common/sandbox_mac_unittest_helper.mm6
-rw-r--r--chromium/content/common/sandbox_policy_fuchsia.cc6
-rw-r--r--chromium/content/common/sandbox_win.cc894
-rw-r--r--chromium/content/common/sandbox_win.h50
-rw-r--r--chromium/content/common/service_manager/service_manager_connection_impl.cc9
-rw-r--r--chromium/content/common/service_manager/service_manager_connection_impl_unittest.cc2
-rw-r--r--chromium/content/common/service_worker/controller_service_worker.mojom20
-rw-r--r--chromium/content/common/service_worker/embedded_worker.mojom60
-rw-r--r--chromium/content/common/service_worker/embedded_worker.typemap6
-rw-r--r--chromium/content/common/service_worker/embedded_worker_messages.h18
-rw-r--r--chromium/content/common/service_worker/embedded_worker_start_params.h2
-rw-r--r--chromium/content/common/service_worker/embedded_worker_start_params_struct_traits.cc33
-rw-r--r--chromium/content/common/service_worker/embedded_worker_start_params_struct_traits.h64
-rw-r--r--chromium/content/common/service_worker/service_worker_client_info.cc14
-rw-r--r--chromium/content/common/service_worker/service_worker_client_info.h25
-rw-r--r--chromium/content/common/service_worker/service_worker_container.mojom60
-rw-r--r--chromium/content/common/service_worker/service_worker_event_dispatcher.mojom35
-rw-r--r--chromium/content/common/service_worker/service_worker_fetch_request.typemap2
-rw-r--r--chromium/content/common/service_worker/service_worker_fetch_request_struct_traits.cc95
-rw-r--r--chromium/content/common/service_worker/service_worker_fetch_request_struct_traits.h34
-rw-r--r--chromium/content/common/service_worker/service_worker_fetch_response_callback.mojom10
-rw-r--r--chromium/content/common/service_worker/service_worker_installed_scripts_manager.mojom9
-rw-r--r--chromium/content/common/service_worker/service_worker_loader_helpers.cc37
-rw-r--r--chromium/content/common/service_worker/service_worker_loader_helpers.h9
-rw-r--r--chromium/content/common/service_worker/service_worker_messages.h178
-rw-r--r--chromium/content/common/service_worker/service_worker_provider.mojom15
-rw-r--r--chromium/content/common/service_worker/service_worker_provider_host_info.cc6
-rw-r--r--chromium/content/common/service_worker/service_worker_provider_host_info.h9
-rw-r--r--chromium/content/common/service_worker/service_worker_provider_struct_traits.cc1
-rw-r--r--chromium/content/common/service_worker/service_worker_provider_struct_traits.h3
-rw-r--r--chromium/content/common/service_worker/service_worker_types.cc81
-rw-r--r--chromium/content/common/service_worker/service_worker_types.h106
-rw-r--r--chromium/content/common/service_worker/service_worker_types.mojom26
-rw-r--r--chromium/content/common/service_worker/service_worker_types.typemap20
-rw-r--r--chromium/content/common/service_worker/service_worker_types_struct_traits.cc58
-rw-r--r--chromium/content/common/service_worker/service_worker_types_struct_traits.h24
-rw-r--r--chromium/content/common/service_worker/service_worker_types_unittest.cc44
-rw-r--r--chromium/content/common/service_worker/service_worker_utils.cc8
-rw-r--r--chromium/content/common/service_worker/service_worker_utils.h5
-rw-r--r--chromium/content/common/shared_worker/shared_worker_factory.mojom24
-rw-r--r--chromium/content/common/shared_worker/shared_worker_info.mojom1
-rw-r--r--chromium/content/common/site_isolation_policy.cc15
-rw-r--r--chromium/content/common/site_isolation_policy.h10
-rw-r--r--chromium/content/common/speech_recognition_messages.h11
-rw-r--r--chromium/content/common/storage_partition_service.mojom3
-rw-r--r--chromium/content/common/throttling_url_loader.cc37
-rw-r--r--chromium/content/common/throttling_url_loader.h12
-rw-r--r--chromium/content/common/throttling_url_loader_unittest.cc66
-rw-r--r--chromium/content/common/typemaps.gni5
-rw-r--r--chromium/content/common/typemaps_mac.gni5
-rw-r--r--chromium/content/common/unique_name_helper.cc48
-rw-r--r--chromium/content/common/unique_name_helper.h42
-rw-r--r--chromium/content/common/unique_name_helper_unittest.cc23
-rw-r--r--chromium/content/common/url_loader_factory_bundle.cc94
-rw-r--r--chromium/content/common/url_loader_factory_bundle.h87
-rw-r--r--chromium/content/common/url_loader_factory_bundle.mojom16
-rw-r--r--chromium/content/common/url_loader_factory_bundle.typemap13
-rw-r--r--chromium/content/common/url_loader_factory_bundle_struct_traits.cc34
-rw-r--r--chromium/content/common/url_loader_factory_bundle_struct_traits.h29
-rw-r--r--chromium/content/common/view_messages.h44
-rw-r--r--chromium/content/common/web_database.mojom66
-rw-r--r--chromium/content/common/web_preferences.typemap7
-rw-r--r--chromium/content/content_resources.grd19
-rw-r--r--chromium/content/gpu/BUILD.gn14
-rw-r--r--chromium/content/gpu/DEPS4
-rw-r--r--chromium/content/gpu/gpu_child_thread.cc47
-rw-r--r--chromium/content/gpu/gpu_child_thread.h15
-rw-r--r--chromium/content/gpu/gpu_main.cc83
-rw-r--r--chromium/content/gpu/gpu_sandbox_hook_linux.cc351
-rw-r--r--chromium/content/gpu/gpu_sandbox_hook_linux.h17
-rw-r--r--chromium/content/gpu/gpu_service_factory.cc8
-rw-r--r--chromium/content/gpu/in_process_gpu_thread.cc14
-rw-r--r--chromium/content/gpu/in_process_gpu_thread.h9
-rw-r--r--chromium/content/network/BUILD.gn34
-rw-r--r--chromium/content/network/DEPS5
-rw-r--r--chromium/content/network/OWNERS4
-rw-r--r--chromium/content/network/PRESUBMIT.py (renamed from chromium/content/browser/frame_host/PRESUBMIT.py)10
-rw-r--r--chromium/content/network/cache_url_loader.cc2
-rw-r--r--chromium/content/network/cookie_manager.cc (renamed from chromium/content/network/cookie_manager_impl.cc)86
-rw-r--r--chromium/content/network/cookie_manager.h (renamed from chromium/content/network/cookie_manager_impl.h)14
-rw-r--r--chromium/content/network/cookie_manager_unittest.cc (renamed from chromium/content/network/cookie_manager_impl_unittest.cc)817
-rw-r--r--chromium/content/network/network_change_manager.cc67
-rw-r--r--chromium/content/network/network_change_manager.h65
-rw-r--r--chromium/content/network/network_change_manager_unittest.cc226
-rw-r--r--chromium/content/network/network_context.cc62
-rw-r--r--chromium/content/network/network_context.h21
-rw-r--r--chromium/content/network/network_context_unittest.cc2
-rw-r--r--chromium/content/network/network_sandbox_hook_linux.cc28
-rw-r--r--chromium/content/network/network_sandbox_hook_linux.h17
-rw-r--r--chromium/content/network/network_service_impl.cc89
-rw-r--r--chromium/content/network/network_service_impl.h34
-rw-r--r--chromium/content/network/network_service_unittest.cc205
-rw-r--r--chromium/content/network/network_service_url_loader_factory.cc (renamed from chromium/content/network/network_service_url_loader_factory_impl.cc)18
-rw-r--r--chromium/content/network/network_service_url_loader_factory.h (renamed from chromium/content/network/network_service_url_loader_factory_impl.h)17
-rw-r--r--chromium/content/network/proxy_resolver_factory_mojo.cc25
-rw-r--r--chromium/content/network/proxy_resolver_factory_mojo.h10
-rw-r--r--chromium/content/network/proxy_resolver_factory_mojo_unittest.cc37
-rw-r--r--chromium/content/network/proxy_service_mojo.cc8
-rw-r--r--chromium/content/network/proxy_service_mojo.h9
-rw-r--r--chromium/content/network/restricted_cookie_manager.cc (renamed from chromium/content/network/restricted_cookie_manager_impl.cc)44
-rw-r--r--chromium/content/network/restricted_cookie_manager.h (renamed from chromium/content/network/restricted_cookie_manager_impl.h)20
-rw-r--r--chromium/content/network/restricted_cookie_manager_unittest.cc (renamed from chromium/content/network/restricted_cookie_manager_impl_unittest.cc)137
-rw-r--r--chromium/content/network/throttling/network_conditions.cc30
-rw-r--r--chromium/content/network/throttling/network_conditions.h (renamed from chromium/content/common/devtools/devtools_network_conditions.h)26
-rw-r--r--chromium/content/network/throttling/throttling_controller.cc (renamed from chromium/content/common/devtools/devtools_network_controller.cc)36
-rw-r--r--chromium/content/network/throttling/throttling_controller.h54
-rw-r--r--chromium/content/network/throttling/throttling_controller_unittest.cc (renamed from chromium/content/common/devtools/devtools_network_controller_unittest.cc)105
-rw-r--r--chromium/content/network/throttling/throttling_network_interceptor.cc (renamed from chromium/content/common/devtools/devtools_network_interceptor.cc)65
-rw-r--r--chromium/content/network/throttling/throttling_network_interceptor.h (renamed from chromium/content/common/devtools/devtools_network_interceptor.h)28
-rw-r--r--chromium/content/network/throttling/throttling_network_transaction.cc (renamed from chromium/content/common/devtools/devtools_network_transaction.cc)104
-rw-r--r--chromium/content/network/throttling/throttling_network_transaction.h (renamed from chromium/content/common/devtools/devtools_network_transaction.h)29
-rw-r--r--chromium/content/network/throttling/throttling_network_transaction_factory.cc (renamed from chromium/content/common/devtools/devtools_network_transaction_factory.cc)19
-rw-r--r--chromium/content/network/throttling/throttling_network_transaction_factory.h (renamed from chromium/content/common/devtools/devtools_network_transaction_factory.h)9
-rw-r--r--chromium/content/network/throttling/throttling_upload_data_stream.cc (renamed from chromium/content/common/devtools/devtools_network_upload_data_stream.cc)34
-rw-r--r--chromium/content/network/throttling/throttling_upload_data_stream.h (renamed from chromium/content/common/devtools/devtools_network_upload_data_stream.h)26
-rw-r--r--chromium/content/network/upload_progress_tracker.cc (renamed from chromium/content/browser/loader/upload_progress_tracker.cc)2
-rw-r--r--chromium/content/network/upload_progress_tracker.h (renamed from chromium/content/browser/loader/upload_progress_tracker.h)6
-rw-r--r--chromium/content/network/upload_progress_tracker_unittest.cc (renamed from chromium/content/browser/loader/upload_progress_tracker_unittest.cc)4
-rw-r--r--chromium/content/network/url_loader.cc (renamed from chromium/content/network/url_loader_impl.cc)408
-rw-r--r--chromium/content/network/url_loader.h (renamed from chromium/content/network/url_loader_impl.h)51
-rw-r--r--chromium/content/network/url_loader_unittest.cc547
-rw-r--r--chromium/content/ppapi_plugin/DEPS1
-rw-r--r--chromium/content/ppapi_plugin/broker_process_dispatcher.cc17
-rw-r--r--chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc18
-rw-r--r--chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h3
-rw-r--r--chromium/content/ppapi_plugin/ppapi_broker_main.cc2
-rw-r--r--chromium/content/ppapi_plugin/ppapi_plugin_main.cc11
-rw-r--r--chromium/content/ppapi_plugin/ppapi_thread.cc25
-rw-r--r--chromium/content/public/android/BUILD.gn9
-rw-r--r--chromium/content/public/android/OWNERS1
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/input/OWNERS1
-rw-r--r--chromium/content/public/app/BUILD.gn8
-rw-r--r--chromium/content/public/app/content_main_delegate.cc11
-rw-r--r--chromium/content/public/app/content_main_delegate.h24
-rw-r--r--chromium/content/public/app/mojo/content_browser_manifest.json80
-rw-r--r--chromium/content/public/app/mojo/content_gpu_manifest.json7
-rw-r--r--chromium/content/public/app/mojo/content_packaged_services_manifest.json2
-rw-r--r--chromium/content/public/app/mojo/content_plugin_manifest.json6
-rw-r--r--chromium/content/public/app/mojo/content_renderer_manifest.json24
-rw-r--r--chromium/content/public/app/mojo/content_utility_manifest.json6
-rw-r--r--chromium/content/public/browser/BUILD.gn9
-rw-r--r--chromium/content/public/browser/DEPS1
-rw-r--r--chromium/content/public/browser/android/OWNERS1
-rw-r--r--chromium/content/public/browser/android/compositor.h6
-rw-r--r--chromium/content/public/browser/background_fetch_delegate.h58
-rw-r--r--chromium/content/public/browser/background_fetch_response.cc10
-rw-r--r--chromium/content/public/browser/background_fetch_response.h26
-rw-r--r--chromium/content/public/browser/browser_context.h20
-rw-r--r--chromium/content/public/browser/browser_plugin_guest_delegate.h5
-rw-r--r--chromium/content/public/browser/browser_thread.h21
-rw-r--r--chromium/content/public/browser/certificate_request_result_type.h3
-rw-r--r--chromium/content/public/browser/child_process_security_policy.h25
-rw-r--r--chromium/content/public/browser/content_browser_client.cc65
-rw-r--r--chromium/content/public/browser/content_browser_client.h102
-rw-r--r--chromium/content/public/browser/desktop_media_id.h2
-rw-r--r--chromium/content/public/browser/devtools_agent_host.h9
-rw-r--r--chromium/content/public/browser/devtools_agent_host_client.h3
-rw-r--r--chromium/content/public/browser/download_item.h8
-rw-r--r--chromium/content/public/browser/download_manager_delegate.cc19
-rw-r--r--chromium/content/public/browser/download_manager_delegate.h23
-rw-r--r--chromium/content/public/browser/download_request_utils.h28
-rw-r--r--chromium/content/public/browser/download_source.h59
-rw-r--r--chromium/content/public/browser/download_url_parameters.cc3
-rw-r--r--chromium/content/public/browser/download_url_parameters.h17
-rw-r--r--chromium/content/public/browser/file_url_loader.h32
-rw-r--r--chromium/content/public/browser/gpu_data_manager.h3
-rw-r--r--chromium/content/public/browser/gpu_utils.cc11
-rw-r--r--chromium/content/public/browser/guest_host.h3
-rw-r--r--chromium/content/public/browser/host_zoom_map.h2
-rw-r--r--chromium/content/public/browser/javascript_dialog_manager.h2
-rw-r--r--chromium/content/public/browser/media_session.h11
-rw-r--r--chromium/content/public/browser/navigation_handle.h20
-rw-r--r--chromium/content/public/browser/navigation_throttle.cc4
-rw-r--r--chromium/content/public/browser/navigation_throttle.h15
-rw-r--r--chromium/content/public/browser/network_service_instance.cc10
-rw-r--r--chromium/content/public/browser/notification_event_dispatcher.h15
-rw-r--r--chromium/content/public/browser/overscroll_configuration.h29
-rw-r--r--chromium/content/public/browser/page_navigator.cc4
-rw-r--r--chromium/content/public/browser/page_navigator.h7
-rw-r--r--chromium/content/public/browser/permission_type.h4
-rw-r--r--chromium/content/public/browser/platform_notification_service.h17
-rw-r--r--chromium/content/public/browser/presentation_service_delegate.h6
-rw-r--r--chromium/content/public/browser/provision_fetcher_impl.cc2
-rw-r--r--chromium/content/public/browser/render_frame_host.h22
-rw-r--r--chromium/content/public/browser/render_process_host.h51
-rw-r--r--chromium/content/public/browser/render_process_host_observer.h4
-rw-r--r--chromium/content/public/browser/render_widget_host.h42
-rw-r--r--chromium/content/public/browser/render_widget_host_view.h22
-rw-r--r--chromium/content/public/browser/render_widget_host_view_mac_delegate.h5
-rw-r--r--chromium/content/public/browser/resource_dispatcher_host_delegate.cc9
-rw-r--r--chromium/content/public/browser/resource_dispatcher_host_delegate.h10
-rw-r--r--chromium/content/public/browser/resource_request_details.cc9
-rw-r--r--chromium/content/public/browser/resource_request_details.h11
-rw-r--r--chromium/content/public/browser/resource_request_info.h35
-rw-r--r--chromium/content/public/browser/shared_worker_service.h40
-rw-r--r--chromium/content/public/browser/site_instance.h4
-rw-r--r--chromium/content/public/browser/ssl_status.h11
-rw-r--r--chromium/content/public/browser/storage_partition.h18
-rw-r--r--chromium/content/public/browser/stored_payment_app.cc6
-rw-r--r--chromium/content/public/browser/stored_payment_app.h19
-rw-r--r--chromium/content/public/browser/utility_process_host.h5
-rw-r--r--chromium/content/public/browser/utility_process_mojo_client.h3
-rw-r--r--chromium/content/public/browser/web_contents.cc4
-rw-r--r--chromium/content/public/browser/web_contents.h33
-rw-r--r--chromium/content/public/browser/web_contents_binding_set.h2
-rw-r--r--chromium/content/public/browser/web_contents_delegate.cc39
-rw-r--r--chromium/content/public/browser/web_contents_delegate.h39
-rw-r--r--chromium/content/public/browser/web_contents_observer.h23
-rw-r--r--chromium/content/public/browser/web_contents_view_delegate.cc8
-rw-r--r--chromium/content/public/browser/web_contents_view_delegate.h20
-rw-r--r--chromium/content/public/browser/web_ui.h3
-rw-r--r--chromium/content/public/browser/webrtc_log.cc26
-rw-r--r--chromium/content/public/browser/webrtc_log.h37
-rw-r--r--chromium/content/public/browser/worker_service.h53
-rw-r--r--chromium/content/public/browser/worker_service_observer.h29
-rw-r--r--chromium/content/public/child/BUILD.gn7
-rw-r--r--chromium/content/public/common/BUILD.gn18
-rw-r--r--chromium/content/public/common/DEPS4
-rw-r--r--chromium/content/public/common/OWNERS4
-rw-r--r--chromium/content/public/common/appcache_info.h37
-rw-r--r--chromium/content/public/common/appcache_info.mojom33
-rw-r--r--chromium/content/public/common/associated_interface_provider.h53
-rw-r--r--chromium/content/public/common/associated_interface_registry.h62
-rw-r--r--chromium/content/public/common/bindings_policy.h18
-rw-r--r--chromium/content/public/common/browser_side_navigation_policy.cc11
-rw-r--r--chromium/content/public/common/browser_side_navigation_policy.h3
-rw-r--r--chromium/content/public/common/common_param_traits_macros.h27
-rw-r--r--chromium/content/public/common/common_sandbox_support_linux.h4
-rw-r--r--chromium/content/public/common/content_client.cc10
-rw-r--r--chromium/content/public/common/content_features.cc142
-rw-r--r--chromium/content/public/common/content_features.h29
-rw-r--r--chromium/content/public/common/content_switches.cc80
-rw-r--r--chromium/content/public/common/content_switches.h19
-rw-r--r--chromium/content/public/common/context_menu_params.cc3
-rw-r--r--chromium/content/public/common/context_menu_params.h11
-rw-r--r--chromium/content/public/common/cors_error_status.typemap13
-rw-r--r--chromium/content/public/common/drop_data.cc4
-rw-r--r--chromium/content/public/common/drop_data.h4
-rw-r--r--chromium/content/public/common/drop_data_unittest.cc77
-rw-r--r--chromium/content/public/common/input_event_ack_source.h (renamed from chromium/content/common/input/input_event_ack_source.h)6
-rw-r--r--chromium/content/public/common/input_event_ack_state.h (renamed from chromium/content/common/input/input_event_ack_state.h)8
-rw-r--r--chromium/content/public/common/manifest.cc3
-rw-r--r--chromium/content/public/common/manifest.h4
-rw-r--r--chromium/content/public/common/manifest.typemap2
-rw-r--r--chromium/content/public/common/manifest_struct_traits.cc3
-rw-r--r--chromium/content/public/common/manifest_struct_traits.h8
-rw-r--r--chromium/content/public/common/menu_item.h3
-rw-r--r--chromium/content/public/common/mutable_network_traffic_annotation_tag.typemap10
-rw-r--r--chromium/content/public/common/mutable_network_traffic_annotation_tag_struct_traits.h31
-rw-r--r--chromium/content/public/common/network_connection_tracker.cc147
-rw-r--r--chromium/content/public/common/network_connection_tracker.h117
-rw-r--r--chromium/content/public/common/network_connection_tracker_unittest.cc317
-rw-r--r--chromium/content/public/common/network_service.mojom51
-rw-r--r--chromium/content/public/common/network_service_test.mojom10
-rw-r--r--chromium/content/public/common/pepper_plugin_info.cc7
-rw-r--r--chromium/content/public/common/referrer_struct_traits.cc1
-rw-r--r--chromium/content/public/common/referrer_struct_traits.h1
-rw-r--r--chromium/content/public/common/renderer_preferences.cc3
-rw-r--r--chromium/content/public/common/renderer_preferences.h9
-rw-r--r--chromium/content/public/common/resource_request.h33
-rw-r--r--chromium/content/public/common/resource_request_body.cc17
-rw-r--r--chromium/content/public/common/resource_request_body.h10
-rw-r--r--chromium/content/public/common/resource_request_completion_status.cc20
-rw-r--r--chromium/content/public/common/resource_request_completion_status.h48
-rw-r--r--chromium/content/public/common/resource_response.cc2
-rw-r--r--chromium/content/public/common/resource_response_info.cc1
-rw-r--r--chromium/content/public/common/resource_response_info.h6
-rw-r--r--chromium/content/public/common/sandbox_init.h15
-rw-r--r--chromium/content/public/common/sandbox_linux.h41
-rw-r--r--chromium/content/public/common/sandboxed_process_launcher_delegate.cc11
-rw-r--r--chromium/content/public/common/sandboxed_process_launcher_delegate.h33
-rw-r--r--chromium/content/public/common/screen_info.h9
-rw-r--r--chromium/content/public/common/service_worker_modes.h40
-rw-r--r--chromium/content/public/common/simple_url_loader.cc760
-rw-r--r--chromium/content/public/common/simple_url_loader.h73
-rw-r--r--chromium/content/public/common/simple_url_loader_unittest.cc1429
-rw-r--r--chromium/content/public/common/storage_quota_params.h8
-rw-r--r--chromium/content/public/common/typemaps.gni5
-rw-r--r--chromium/content/public/common/url_constants.cc11
-rw-r--r--chromium/content/public/common/url_constants.h10
-rw-r--r--chromium/content/public/common/url_loader.mojom14
-rw-r--r--chromium/content/public/common/url_loader_completion_status.typemap (renamed from chromium/content/public/common/url_loader_status.typemap)6
-rw-r--r--chromium/content/public/common/url_loader_factory.mojom18
-rw-r--r--chromium/content/public/common/url_loader_throttle.cc5
-rw-r--r--chromium/content/public/common/url_loader_throttle.h8
-rw-r--r--chromium/content/public/common/url_utils.cc45
-rw-r--r--chromium/content/public/common/url_utils.h17
-rw-r--r--chromium/content/public/common/web_preferences.cc1
-rw-r--r--chromium/content/public/common/web_preferences.h1
-rw-r--r--chromium/content/public/common/webplugininfo.h10
-rw-r--r--chromium/content/public/common/webplugininfo.mojom (renamed from chromium/content/public/common/mutable_network_traffic_annotation_tag.mojom)5
-rw-r--r--chromium/content/public/common/webplugininfo.typemap12
-rw-r--r--chromium/content/public/common/webplugininfo_param_traits.h33
-rw-r--r--chromium/content/public/network/BUILD.gn4
-rw-r--r--chromium/content/public/network/DEPS1
-rw-r--r--chromium/content/public/network/ignore_errors_cert_verifier.cc (renamed from chromium/content/browser/ssl/ignore_errors_cert_verifier.cc)6
-rw-r--r--chromium/content/public/network/ignore_errors_cert_verifier.h (renamed from chromium/content/public/browser/ignore_errors_cert_verifier.h)20
-rw-r--r--chromium/content/public/network/ignore_errors_cert_verifier_unittest.cc (renamed from chromium/content/browser/ssl/ignore_errors_cert_verifier_unittest.cc)4
-rw-r--r--chromium/content/public/network/mojo_proxy_resolver_factory.h37
-rw-r--r--chromium/content/public/network/network_service.h15
-rw-r--r--chromium/content/public/network/url_request_context_builder_mojo.cc17
-rw-r--r--chromium/content/public/network/url_request_context_builder_mojo.h28
-rw-r--r--chromium/content/public/renderer/BUILD.gn7
-rw-r--r--chromium/content/public/renderer/associated_resource_fetcher.h8
-rw-r--r--chromium/content/public/renderer/child_url_loader_factory_getter.h (renamed from chromium/content/public/child/child_url_loader_factory_getter.h)6
-rw-r--r--chromium/content/public/renderer/content_renderer_client.cc12
-rw-r--r--chromium/content/public/renderer/content_renderer_client.h15
-rw-r--r--chromium/content/public/renderer/fixed_received_data.cc (renamed from chromium/content/public/child/fixed_received_data.cc)2
-rw-r--r--chromium/content/public/renderer/fixed_received_data.h (renamed from chromium/content/public/child/fixed_received_data.h)8
-rw-r--r--chromium/content/public/renderer/render_frame.h16
-rw-r--r--chromium/content/public/renderer/render_frame_observer.cc2
-rw-r--r--chromium/content/public/renderer/render_thread.cc2
-rw-r--r--chromium/content/public/renderer/render_thread_observer.h9
-rw-r--r--chromium/content/public/renderer/render_view.h3
-rw-r--r--chromium/content/public/renderer/renderer_ppapi_host.h4
-rw-r--r--chromium/content/public/renderer/request_peer.h (renamed from chromium/content/public/child/request_peer.h)22
-rw-r--r--chromium/content/public/renderer/resource_dispatcher_delegate.h (renamed from chromium/content/public/child/resource_dispatcher_delegate.h)19
-rw-r--r--chromium/content/public/renderer/v8_value_converter.h (renamed from chromium/content/public/child/v8_value_converter.h)6
-rw-r--r--chromium/content/public/renderer/video_encode_accelerator.cc2
-rw-r--r--chromium/content/public/renderer/worker_thread.h (renamed from chromium/content/public/child/worker_thread.h)6
-rw-r--r--chromium/content/public/test/android/BUILD.gn2
-rw-r--r--chromium/content/public/utility/content_utility_client.h9
-rw-r--r--chromium/content/public/utility/utility_thread.cc2
-rw-r--r--chromium/content/renderer/BUILD.gn183
-rw-r--r--chromium/content/renderer/DEPS4
-rw-r--r--chromium/content/renderer/OWNERS8
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc8
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_tree_source.cc20
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl.cc37
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl.h6
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_filter.cc2
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_proxy.h2
-rw-r--r--chromium/content/renderer/android/synchronous_layer_tree_frame_sink.cc21
-rw-r--r--chromium/content/renderer/android/synchronous_layer_tree_frame_sink.h5
-rw-r--r--chromium/content/renderer/appcache/OWNERS (renamed from chromium/content/child/appcache/OWNERS)4
-rw-r--r--chromium/content/renderer/appcache/appcache_backend_proxy.cc (renamed from chromium/content/child/appcache/appcache_backend_proxy.cc)11
-rw-r--r--chromium/content/renderer/appcache/appcache_backend_proxy.h (renamed from chromium/content/child/appcache/appcache_backend_proxy.h)9
-rw-r--r--chromium/content/renderer/appcache/appcache_dispatcher.cc (renamed from chromium/content/child/appcache/appcache_dispatcher.cc)2
-rw-r--r--chromium/content/renderer/appcache/appcache_dispatcher.h (renamed from chromium/content/child/appcache/appcache_dispatcher.h)8
-rw-r--r--chromium/content/renderer/appcache/appcache_frontend_impl.cc (renamed from chromium/content/child/appcache/appcache_frontend_impl.cc)60
-rw-r--r--chromium/content/renderer/appcache/appcache_frontend_impl.h (renamed from chromium/content/child/appcache/appcache_frontend_impl.h)6
-rw-r--r--chromium/content/renderer/appcache/web_application_cache_host_impl.cc (renamed from chromium/content/child/appcache/web_application_cache_host_impl.cc)81
-rw-r--r--chromium/content/renderer/appcache/web_application_cache_host_impl.h (renamed from chromium/content/child/appcache/web_application_cache_host_impl.h)12
-rw-r--r--chromium/content/renderer/background_sync/OWNERS (renamed from chromium/content/child/background_sync/OWNERS)0
-rw-r--r--chromium/content/renderer/background_sync/background_sync_type_converters.cc (renamed from chromium/content/child/background_sync/background_sync_type_converters.cc)2
-rw-r--r--chromium/content/renderer/background_sync/background_sync_type_converters.h (renamed from chromium/content/child/background_sync/background_sync_type_converters.h)6
-rw-r--r--chromium/content/renderer/blob_storage/OWNERS (renamed from chromium/content/child/blob_storage/OWNERS)0
-rw-r--r--chromium/content/renderer/blob_storage/blob_consolidation.cc (renamed from chromium/content/child/blob_storage/blob_consolidation.cc)2
-rw-r--r--chromium/content/renderer/blob_storage/blob_consolidation.h (renamed from chromium/content/child/blob_storage/blob_consolidation.h)6
-rw-r--r--chromium/content/renderer/blob_storage/blob_consolidation_unittest.cc (renamed from chromium/content/child/blob_storage/blob_consolidation_unittest.cc)2
-rw-r--r--chromium/content/renderer/blob_storage/blob_message_filter.cc (renamed from chromium/content/child/blob_storage/blob_message_filter.cc)4
-rw-r--r--chromium/content/renderer/blob_storage/blob_message_filter.h (renamed from chromium/content/child/blob_storage/blob_message_filter.h)6
-rw-r--r--chromium/content/renderer/blob_storage/blob_transport_controller.cc (renamed from chromium/content/child/blob_storage/blob_transport_controller.cc)8
-rw-r--r--chromium/content/renderer/blob_storage/blob_transport_controller.h (renamed from chromium/content/child/blob_storage/blob_transport_controller.h)6
-rw-r--r--chromium/content/renderer/blob_storage/blob_transport_controller_unittest.cc (renamed from chromium/content/child/blob_storage/blob_transport_controller_unittest.cc)4
-rw-r--r--chromium/content/renderer/blob_storage/webblobregistry_impl.cc (renamed from chromium/content/child/blob_storage/webblobregistry_impl.cc)6
-rw-r--r--chromium/content/renderer/blob_storage/webblobregistry_impl.h (renamed from chromium/content/child/blob_storage/webblobregistry_impl.h)6
-rw-r--r--chromium/content/renderer/browser_plugin/browser_plugin.cc215
-rw-r--r--chromium/content/renderer/browser_plugin/browser_plugin.h79
-rw-r--r--chromium/content/renderer/browser_plugin/browser_plugin_manager.cc9
-rw-r--r--chromium/content/renderer/browser_plugin/browser_plugin_manager.h3
-rw-r--r--chromium/content/renderer/browser_render_view_browsertest.cc6
-rw-r--r--chromium/content/renderer/cache_storage/cache_storage_dispatcher.cc54
-rw-r--r--chromium/content/renderer/cache_storage/cache_storage_dispatcher.h20
-rw-r--r--chromium/content/renderer/cache_storage/cache_storage_message_filter.h2
-rw-r--r--chromium/content/renderer/cache_storage/webserviceworkercachestorage_impl.h1
-rw-r--r--chromium/content/renderer/child_frame_compositing_helper.cc67
-rw-r--r--chromium/content/renderer/child_frame_compositing_helper.h17
-rw-r--r--chromium/content/renderer/child_message_filter.cc (renamed from chromium/content/child/child_message_filter.cc)6
-rw-r--r--chromium/content/renderer/child_message_filter.h (renamed from chromium/content/child/child_message_filter.h)6
-rw-r--r--chromium/content/renderer/context_menu_params_builder.cc7
-rw-r--r--chromium/content/renderer/devtools/devtools_agent.cc369
-rw-r--r--chromium/content/renderer/devtools/devtools_agent.h87
-rw-r--r--chromium/content/renderer/devtools/devtools_agent_filter.cc103
-rw-r--r--chromium/content/renderer/devtools/devtools_agent_filter.h68
-rw-r--r--chromium/content/renderer/devtools/devtools_client.cc54
-rw-r--r--chromium/content/renderer/devtools/devtools_client.h57
-rw-r--r--chromium/content/renderer/devtools/devtools_cpu_throttler.cc2
-rw-r--r--chromium/content/renderer/devtools/devtools_frontend_impl.cc67
-rw-r--r--chromium/content/renderer/devtools/devtools_frontend_impl.h65
-rw-r--r--chromium/content/renderer/dom_automation_controller.cc3
-rw-r--r--chromium/content/renderer/dom_serializer_browsertest.cc32
-rw-r--r--chromium/content/renderer/dom_storage/DEPS2
-rw-r--r--chromium/content/renderer/dom_storage/dom_storage_cached_area.cc43
-rw-r--r--chromium/content/renderer/dom_storage/dom_storage_cached_area.h23
-rw-r--r--chromium/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc35
-rw-r--r--chromium/content/renderer/dom_storage/dom_storage_dispatcher.cc15
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_area.cc72
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_area.h36
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_area_unittest.cc173
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_areas.cc102
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_areas.h39
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_areas_unittest.cc59
-rw-r--r--chromium/content/renderer/dom_storage/mock_leveldb_wrapper.cc81
-rw-r--r--chromium/content/renderer/dom_storage/mock_leveldb_wrapper.h117
-rw-r--r--chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.cc41
-rw-r--r--chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.h37
-rw-r--r--chromium/content/renderer/dom_storage/webstoragenamespace_impl.cc2
-rw-r--r--chromium/content/renderer/fetchers/associated_resource_fetcher_impl.cc10
-rw-r--r--chromium/content/renderer/fetchers/associated_resource_fetcher_impl.h7
-rw-r--r--chromium/content/renderer/fetchers/manifest_fetcher.cc6
-rw-r--r--chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc8
-rw-r--r--chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h4
-rw-r--r--chromium/content/renderer/fetchers/resource_fetcher_browsertest.cc4
-rw-r--r--chromium/content/renderer/fetchers/resource_fetcher_impl.cc10
-rw-r--r--chromium/content/renderer/file_info_util.cc (renamed from chromium/content/child/file_info_util.cc)2
-rw-r--r--chromium/content/renderer/file_info_util.h (renamed from chromium/content/child/file_info_util.h)6
-rw-r--r--chromium/content/renderer/fileapi/OWNERS (renamed from chromium/content/child/fileapi/OWNERS)2
-rw-r--r--chromium/content/renderer/fileapi/file_system_dispatcher.cc (renamed from chromium/content/child/fileapi/file_system_dispatcher.cc)2
-rw-r--r--chromium/content/renderer/fileapi/file_system_dispatcher.h (renamed from chromium/content/child/fileapi/file_system_dispatcher.h)6
-rw-r--r--chromium/content/renderer/fileapi/webfilesystem_impl.cc (renamed from chromium/content/child/fileapi/webfilesystem_impl.cc)26
-rw-r--r--chromium/content/renderer/fileapi/webfilesystem_impl.h (renamed from chromium/content/child/fileapi/webfilesystem_impl.h)8
-rw-r--r--chromium/content/renderer/fileapi/webfilewriter_base.cc (renamed from chromium/content/child/fileapi/webfilewriter_base.cc)2
-rw-r--r--chromium/content/renderer/fileapi/webfilewriter_base.h (renamed from chromium/content/child/fileapi/webfilewriter_base.h)6
-rw-r--r--chromium/content/renderer/fileapi/webfilewriter_base_unittest.cc (renamed from chromium/content/child/fileapi/webfilewriter_base_unittest.cc)8
-rw-r--r--chromium/content/renderer/fileapi/webfilewriter_impl.cc (renamed from chromium/content/child/fileapi/webfilewriter_impl.cc)19
-rw-r--r--chromium/content/renderer/fileapi/webfilewriter_impl.h (renamed from chromium/content/child/fileapi/webfilewriter_impl.h)8
-rw-r--r--chromium/content/renderer/frame_owner_properties.cc2
-rw-r--r--chromium/content/renderer/gamepad_shared_memory_reader.cc2
-rw-r--r--chromium/content/renderer/gpu/compositor_dependencies.h3
-rw-r--r--chromium/content/renderer/gpu/compositor_external_begin_frame_source.cc3
-rw-r--r--chromium/content/renderer/gpu/frame_swap_message_queue.cc4
-rw-r--r--chromium/content/renderer/gpu/frame_swap_message_queue_unittest.cc18
-rw-r--r--chromium/content/renderer/gpu/gpu_benchmarking_extension.cc147
-rw-r--r--chromium/content/renderer/gpu/gpu_benchmarking_extension.h4
-rw-r--r--chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc2
-rw-r--r--chromium/content/renderer/gpu/render_widget_compositor.cc78
-rw-r--r--chromium/content/renderer/gpu/render_widget_compositor.h22
-rw-r--r--chromium/content/renderer/gpu/render_widget_compositor_delegate.h1
-rw-r--r--chromium/content/renderer/gpu/render_widget_compositor_unittest.cc218
-rw-r--r--chromium/content/renderer/history_entry.cc2
-rw-r--r--chromium/content/renderer/history_serialization.cc12
-rw-r--r--chromium/content/renderer/idle_user_detector.cc2
-rw-r--r--chromium/content/renderer/image_downloader/image_downloader_base.cc9
-rw-r--r--chromium/content/renderer/image_downloader/image_downloader_impl.cc2
-rw-r--r--chromium/content/renderer/indexed_db/OWNERS (renamed from chromium/content/child/indexed_db/OWNERS)0
-rw-r--r--chromium/content/renderer/indexed_db/indexed_db_callbacks_impl.cc (renamed from chromium/content/child/indexed_db/indexed_db_callbacks_impl.cc)19
-rw-r--r--chromium/content/renderer/indexed_db/indexed_db_callbacks_impl.h (renamed from chromium/content/child/indexed_db/indexed_db_callbacks_impl.h)6
-rw-r--r--chromium/content/renderer/indexed_db/indexed_db_database_callbacks_impl.cc (renamed from chromium/content/child/indexed_db/indexed_db_database_callbacks_impl.cc)8
-rw-r--r--chromium/content/renderer/indexed_db/indexed_db_database_callbacks_impl.h (renamed from chromium/content/child/indexed_db/indexed_db_database_callbacks_impl.h)6
-rw-r--r--chromium/content/renderer/indexed_db/indexed_db_dispatcher.cc (renamed from chromium/content/child/indexed_db/indexed_db_dispatcher.cc)8
-rw-r--r--chromium/content/renderer/indexed_db/indexed_db_dispatcher.h (renamed from chromium/content/child/indexed_db/indexed_db_dispatcher.h)12
-rw-r--r--chromium/content/renderer/indexed_db/indexed_db_key_builders.cc (renamed from chromium/content/child/indexed_db/indexed_db_key_builders.cc)2
-rw-r--r--chromium/content/renderer/indexed_db/indexed_db_key_builders.h (renamed from chromium/content/child/indexed_db/indexed_db_key_builders.h)6
-rw-r--r--chromium/content/renderer/indexed_db/mock_webidbcallbacks.cc (renamed from chromium/content/child/indexed_db/mock_webidbcallbacks.cc)2
-rw-r--r--chromium/content/renderer/indexed_db/mock_webidbcallbacks.h (renamed from chromium/content/child/indexed_db/mock_webidbcallbacks.h)6
-rw-r--r--chromium/content/renderer/indexed_db/webidbcursor_impl.cc (renamed from chromium/content/child/indexed_db/webidbcursor_impl.cc)12
-rw-r--r--chromium/content/renderer/indexed_db/webidbcursor_impl.h (renamed from chromium/content/child/indexed_db/webidbcursor_impl.h)6
-rw-r--r--chromium/content/renderer/indexed_db/webidbcursor_impl_unittest.cc (renamed from chromium/content/child/indexed_db/webidbcursor_impl_unittest.cc)16
-rw-r--r--chromium/content/renderer/indexed_db/webidbdatabase_impl.cc (renamed from chromium/content/child/indexed_db/webidbdatabase_impl.cc)26
-rw-r--r--chromium/content/renderer/indexed_db/webidbdatabase_impl.h (renamed from chromium/content/child/indexed_db/webidbdatabase_impl.h)6
-rw-r--r--chromium/content/renderer/indexed_db/webidbdatabase_impl_unittest.cc (renamed from chromium/content/child/indexed_db/webidbdatabase_impl_unittest.cc)4
-rw-r--r--chromium/content/renderer/indexed_db/webidbfactory_impl.cc (renamed from chromium/content/child/indexed_db/webidbfactory_impl.cc)16
-rw-r--r--chromium/content/renderer/indexed_db/webidbfactory_impl.h (renamed from chromium/content/child/indexed_db/webidbfactory_impl.h)7
-rw-r--r--chromium/content/renderer/input/OWNERS1
-rw-r--r--chromium/content/renderer/input/frame_input_handler_impl.cc31
-rw-r--r--chromium/content/renderer/input/frame_input_handler_impl.h8
-rw-r--r--chromium/content/renderer/input/input_event_filter.cc13
-rw-r--r--chromium/content/renderer/input/input_event_filter.h2
-rw-r--r--chromium/content/renderer/input/input_event_filter_unittest.cc3
-rw-r--r--chromium/content/renderer/input/input_handler_manager.cc4
-rw-r--r--chromium/content/renderer/input/input_handler_manager.h5
-rw-r--r--chromium/content/renderer/input/input_handler_manager_client.h2
-rw-r--r--chromium/content/renderer/input/input_handler_wrapper.cc4
-rw-r--r--chromium/content/renderer/input/input_handler_wrapper.h2
-rw-r--r--chromium/content/renderer/input/main_thread_event_queue.cc42
-rw-r--r--chromium/content/renderer/input/main_thread_event_queue.h14
-rw-r--r--chromium/content/renderer/input/main_thread_event_queue_task.h2
-rw-r--r--chromium/content/renderer/input/main_thread_event_queue_unittest.cc208
-rw-r--r--chromium/content/renderer/input/render_widget_input_handler.cc69
-rw-r--r--chromium/content/renderer/input/render_widget_input_handler.h8
-rw-r--r--chromium/content/renderer/input/render_widget_input_handler_delegate.h5
-rw-r--r--chromium/content/renderer/input/widget_input_handler_impl.cc6
-rw-r--r--chromium/content/renderer/input/widget_input_handler_manager.cc148
-rw-r--r--chromium/content/renderer/input/widget_input_handler_manager.h23
-rw-r--r--chromium/content/renderer/installedapp/related_apps_fetcher.cc12
-rw-r--r--chromium/content/renderer/installedapp/related_apps_fetcher.h14
-rw-r--r--chromium/content/renderer/internal_document_state_data.cc4
-rw-r--r--chromium/content/renderer/internal_document_state_data.h10
-rw-r--r--chromium/content/renderer/java/gin_java_bridge_value_converter.cc2
-rw-r--r--chromium/content/renderer/java/gin_java_bridge_value_converter.h2
-rw-r--r--chromium/content/renderer/java/gin_java_function_invocation_helper.cc4
-rw-r--r--chromium/content/renderer/loader/OWNERS1
-rw-r--r--chromium/content/renderer/loader/child_resource_message_filter.cc (renamed from chromium/content/child/child_resource_message_filter.cc)4
-rw-r--r--chromium/content/renderer/loader/child_resource_message_filter.h (renamed from chromium/content/child/child_resource_message_filter.h)6
-rw-r--r--chromium/content/renderer/loader/child_url_loader_factory_getter_impl.cc (renamed from chromium/content/child/child_url_loader_factory_getter_impl.cc)2
-rw-r--r--chromium/content/renderer/loader/child_url_loader_factory_getter_impl.h (renamed from chromium/content/child/child_url_loader_factory_getter_impl.h)8
-rw-r--r--chromium/content/renderer/loader/cors_url_loader.cc219
-rw-r--r--chromium/content/renderer/loader/cors_url_loader.h (renamed from chromium/content/child/loader/cors_url_loader.h)40
-rw-r--r--chromium/content/renderer/loader/cors_url_loader_factory.cc (renamed from chromium/content/child/loader/cors_url_loader_factory.cc)6
-rw-r--r--chromium/content/renderer/loader/cors_url_loader_factory.h (renamed from chromium/content/child/loader/cors_url_loader_factory.h)6
-rw-r--r--chromium/content/renderer/loader/cors_url_loader_unittest.cc250
-rw-r--r--chromium/content/renderer/loader/ftp_directory_listing_response_delegate.cc (renamed from chromium/content/child/ftp_directory_listing_response_delegate.cc)4
-rw-r--r--chromium/content/renderer/loader/ftp_directory_listing_response_delegate.h (renamed from chromium/content/child/ftp_directory_listing_response_delegate.h)6
-rw-r--r--chromium/content/renderer/loader/request_extra_data.cc (renamed from chromium/content/child/request_extra_data.cc)5
-rw-r--r--chromium/content/renderer/loader/request_extra_data.h (renamed from chromium/content/child/request_extra_data.h)9
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher.cc (renamed from chromium/content/child/resource_dispatcher.cc)96
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher.h (renamed from chromium/content/child/resource_dispatcher.h)33
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher_unittest.cc (renamed from chromium/content/child/resource_dispatcher_unittest.cc)82
-rw-r--r--chromium/content/renderer/loader/resource_scheduling_filter.cc (renamed from chromium/content/child/resource_scheduling_filter.cc)4
-rw-r--r--chromium/content/renderer/loader/resource_scheduling_filter.h (renamed from chromium/content/child/resource_scheduling_filter.h)6
-rw-r--r--chromium/content/renderer/loader/shared_memory_data_consumer_handle.cc (renamed from chromium/content/child/shared_memory_data_consumer_handle.cc)8
-rw-r--r--chromium/content/renderer/loader/shared_memory_data_consumer_handle.h (renamed from chromium/content/child/shared_memory_data_consumer_handle.h)8
-rw-r--r--chromium/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc (renamed from chromium/content/child/shared_memory_data_consumer_handle_unittest.cc)42
-rw-r--r--chromium/content/renderer/loader/shared_memory_received_data_factory.cc (renamed from chromium/content/child/shared_memory_received_data_factory.cc)4
-rw-r--r--chromium/content/renderer/loader/shared_memory_received_data_factory.h (renamed from chromium/content/child/shared_memory_received_data_factory.h)8
-rw-r--r--chromium/content/renderer/loader/shared_memory_received_data_factory_unittest.cc (renamed from chromium/content/child/shared_memory_received_data_factory_unittest.cc)2
-rw-r--r--chromium/content/renderer/loader/site_isolation_stats_gatherer.cc (renamed from chromium/content/child/site_isolation_stats_gatherer.cc)15
-rw-r--r--chromium/content/renderer/loader/site_isolation_stats_gatherer.h (renamed from chromium/content/child/site_isolation_stats_gatherer.h)7
-rw-r--r--chromium/content/renderer/loader/site_isolation_stats_gatherer_browsertest.cc (renamed from chromium/content/child/site_isolation_stats_gatherer_browsertest.cc)0
-rw-r--r--chromium/content/renderer/loader/site_isolation_stats_gatherer_unittest.cc (renamed from chromium/content/child/site_isolation_stats_gatherer_unittest.cc)2
-rw-r--r--chromium/content/renderer/loader/sync_load_context.cc (renamed from chromium/content/child/sync_load_context.cc)22
-rw-r--r--chromium/content/renderer/loader/sync_load_context.h (renamed from chromium/content/child/sync_load_context.h)18
-rw-r--r--chromium/content/renderer/loader/sync_load_response.cc (renamed from chromium/content/child/sync_load_response.cc)2
-rw-r--r--chromium/content/renderer/loader/sync_load_response.h (renamed from chromium/content/child/sync_load_response.h)14
-rw-r--r--chromium/content/renderer/loader/test_request_peer.cc (renamed from chromium/content/child/test_request_peer.cc)12
-rw-r--r--chromium/content/renderer/loader/test_request_peer.h (renamed from chromium/content/child/test_request_peer.h)16
-rw-r--r--chromium/content/renderer/loader/url_loader_client_impl.cc (renamed from chromium/content/child/url_loader_client_impl.cc)8
-rw-r--r--chromium/content/renderer/loader/url_loader_client_impl.h (renamed from chromium/content/child/url_loader_client_impl.h)13
-rw-r--r--chromium/content/renderer/loader/url_loader_client_impl_unittest.cc (renamed from chromium/content/child/url_loader_client_impl_unittest.cc)50
-rw-r--r--chromium/content/renderer/loader/url_response_body_consumer.cc (renamed from chromium/content/child/url_response_body_consumer.cc)20
-rw-r--r--chromium/content/renderer/loader/url_response_body_consumer.h (renamed from chromium/content/child/url_response_body_consumer.h)15
-rw-r--r--chromium/content/renderer/loader/url_response_body_consumer_unittest.cc (renamed from chromium/content/child/url_response_body_consumer_unittest.cc)30
-rw-r--r--chromium/content/renderer/loader/web_data_consumer_handle_impl.cc (renamed from chromium/content/child/web_data_consumer_handle_impl.cc)2
-rw-r--r--chromium/content/renderer/loader/web_data_consumer_handle_impl.h (renamed from chromium/content/child/web_data_consumer_handle_impl.h)6
-rw-r--r--chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc (renamed from chromium/content/child/web_data_consumer_handle_impl_unittest.cc)8
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl.cc (renamed from chromium/content/child/web_url_loader_impl.cc)429
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl.h (renamed from chromium/content/child/web_url_loader_impl.h)36
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl_unittest.cc (renamed from chromium/content/child/web_url_loader_impl_unittest.cc)63
-rw-r--r--chromium/content/renderer/loader/web_url_request_util.cc (renamed from chromium/content/child/web_url_request_util.cc)199
-rw-r--r--chromium/content/renderer/loader/web_url_request_util.h (renamed from chromium/content/child/web_url_request_util.h)10
-rw-r--r--chromium/content/renderer/loader/weburlresponse_extradata_impl.cc (renamed from chromium/content/child/weburlresponse_extradata_impl.cc)2
-rw-r--r--chromium/content/renderer/loader/weburlresponse_extradata_impl.h (renamed from chromium/content/child/weburlresponse_extradata_impl.h)6
-rw-r--r--chromium/content/renderer/manifest/manifest_debug_info.cc13
-rw-r--r--chromium/content/renderer/manifest/manifest_debug_info.h38
-rw-r--r--chromium/content/renderer/manifest/manifest_manager.cc68
-rw-r--r--chromium/content/renderer/manifest/manifest_manager.h36
-rw-r--r--chromium/content/renderer/manifest/manifest_parser.cc92
-rw-r--r--chromium/content/renderer/manifest/manifest_parser.h25
-rw-r--r--chromium/content/renderer/manifest/manifest_parser_unittest.cc106
-rw-r--r--chromium/content/renderer/mash_util.cc10
-rw-r--r--chromium/content/renderer/mash_util.h2
-rw-r--r--chromium/content/renderer/media/OWNERS1
-rw-r--r--chromium/content/renderer/media/aec_dump_message_filter.cc34
-rw-r--r--chromium/content/renderer/media/aec_dump_message_filter.h16
-rw-r--r--chromium/content/renderer/media/android/media_player_renderer_client_factory.cc2
-rw-r--r--chromium/content/renderer/media/android/stream_texture_factory.cc2
-rw-r--r--chromium/content/renderer/media/apply_constraints_processor.cc20
-rw-r--r--chromium/content/renderer/media/apply_constraints_processor.h9
-rw-r--r--chromium/content/renderer/media/audio_device_factory.cc4
-rw-r--r--chromium/content/renderer/media/audio_input_message_filter.cc8
-rw-r--r--chromium/content/renderer/media/audio_ipc_factory.cc2
-rw-r--r--chromium/content/renderer/media/audio_ipc_factory_unittest.cc2
-rw-r--r--chromium/content/renderer/media/audio_message_filter.cc8
-rw-r--r--chromium/content/renderer/media/audio_message_filter_unittest.cc6
-rw-r--r--chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc2
-rw-r--r--chromium/content/renderer/media/audio_repetition_detector.cc2
-rw-r--r--chromium/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc2
-rw-r--r--chromium/content/renderer/media/cdm/ppapi_decryptor.cc7
-rw-r--r--chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc4
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_encoder.cc27
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_encoder_unittest.cc12
-rw-r--r--chromium/content/renderer/media/media_devices_event_dispatcher.cc4
-rw-r--r--chromium/content/renderer/media/media_devices_event_dispatcher.h9
-rw-r--r--chromium/content/renderer/media/media_devices_event_dispatcher_unittest.cc10
-rw-r--r--chromium/content/renderer/media/media_devices_listener_impl.cc4
-rw-r--r--chromium/content/renderer/media/media_devices_listener_impl.h8
-rw-r--r--chromium/content/renderer/media/media_factory.cc54
-rw-r--r--chromium/content/renderer/media/media_factory.h7
-rw-r--r--chromium/content/renderer/media/media_permission_dispatcher.cc13
-rw-r--r--chromium/content/renderer/media/media_permission_dispatcher.h10
-rw-r--r--chromium/content/renderer/media/media_stream_audio_processor.cc39
-rw-r--r--chromium/content/renderer/media/media_stream_audio_processor.h5
-rw-r--r--chromium/content/renderer/media/media_stream_audio_processor_options.h1
-rw-r--r--chromium/content/renderer/media/media_stream_audio_processor_unittest.cc19
-rw-r--r--chromium/content/renderer/media/media_stream_audio_track.cc5
-rw-r--r--chromium/content/renderer/media/media_stream_audio_track.h2
-rw-r--r--chromium/content/renderer/media/media_stream_center.cc27
-rw-r--r--chromium/content/renderer/media/media_stream_center.h5
-rw-r--r--chromium/content/renderer/media/media_stream_constraints_util.h2
-rw-r--r--chromium/content/renderer/media/media_stream_constraints_util_audio.cc27
-rw-r--r--chromium/content/renderer/media/media_stream_constraints_util_audio.h7
-rw-r--r--chromium/content/renderer/media/media_stream_constraints_util_audio_unittest.cc27
-rw-r--r--chromium/content/renderer/media/media_stream_constraints_util_video_content.cc6
-rw-r--r--chromium/content/renderer/media/media_stream_constraints_util_video_device.cc18
-rw-r--r--chromium/content/renderer/media/media_stream_constraints_util_video_device.h5
-rw-r--r--chromium/content/renderer/media/media_stream_constraints_util_video_device_unittest.cc41
-rw-r--r--chromium/content/renderer/media/media_stream_device_observer.cc199
-rw-r--r--chromium/content/renderer/media/media_stream_device_observer.h93
-rw-r--r--chromium/content/renderer/media/media_stream_device_observer_unittest.cc91
-rw-r--r--chromium/content/renderer/media/media_stream_dispatcher.cc370
-rw-r--r--chromium/content/renderer/media/media_stream_dispatcher.h158
-rw-r--r--chromium/content/renderer/media/media_stream_dispatcher_eventhandler.h24
-rw-r--r--chromium/content/renderer/media/media_stream_dispatcher_unittest.cc376
-rw-r--r--chromium/content/renderer/media/media_stream_renderer_factory_impl.cc2
-rw-r--r--chromium/content/renderer/media/media_stream_source.cc4
-rw-r--r--chromium/content/renderer/media/media_stream_source.h9
-rw-r--r--chromium/content/renderer/media/media_stream_track.h6
-rw-r--r--chromium/content/renderer/media/media_stream_video_capturer_source.cc16
-rw-r--r--chromium/content/renderer/media/media_stream_video_capturer_source.h10
-rw-r--r--chromium/content/renderer/media/media_stream_video_capturer_source_unittest.cc42
-rw-r--r--chromium/content/renderer/media/media_stream_video_renderer_sink_unittest.cc21
-rw-r--r--chromium/content/renderer/media/media_stream_video_source.cc76
-rw-r--r--chromium/content/renderer/media/media_stream_video_source.h3
-rw-r--r--chromium/content/renderer/media/media_stream_video_source_unittest.cc56
-rw-r--r--chromium/content/renderer/media/media_stream_video_track.cc14
-rw-r--r--chromium/content/renderer/media/media_stream_video_track.h2
-rw-r--r--chromium/content/renderer/media/media_stream_video_track_unittest.cc15
-rw-r--r--chromium/content/renderer/media/mock_media_stream_dispatcher.cc117
-rw-r--r--chromium/content/renderer/media/mock_media_stream_dispatcher.h71
-rw-r--r--chromium/content/renderer/media/mock_media_stream_video_source.cc4
-rw-r--r--chromium/content/renderer/media/mock_media_stream_video_source.h4
-rw-r--r--chromium/content/renderer/media/mock_mojo_media_stream_dispatcher_host.cc83
-rw-r--r--chromium/content/renderer/media/mock_mojo_media_stream_dispatcher_host.h54
-rw-r--r--chromium/content/renderer/media/mock_peer_connection_impl.cc91
-rw-r--r--chromium/content/renderer/media/mock_peer_connection_impl.h36
-rw-r--r--chromium/content/renderer/media/mock_web_rtc_peer_connection_handler_client.cc34
-rw-r--r--chromium/content/renderer/media/mock_web_rtc_peer_connection_handler_client.h40
-rw-r--r--chromium/content/renderer/media/mojo_audio_input_ipc.cc103
-rw-r--r--chromium/content/renderer/media/mojo_audio_input_ipc.h80
-rw-r--r--chromium/content/renderer/media/mojo_audio_input_ipc_unittest.cc249
-rw-r--r--chromium/content/renderer/media/mojo_audio_output_ipc_unittest.cc52
-rw-r--r--chromium/content/renderer/media/peer_connection_tracker.cc24
-rw-r--r--chromium/content/renderer/media/peer_connection_tracker.h8
-rw-r--r--chromium/content/renderer/media/pepper_to_video_track_adapter_unittest.cc9
-rw-r--r--chromium/content/renderer/media/render_media_log.cc7
-rw-r--r--chromium/content/renderer/media/render_media_log.h4
-rw-r--r--chromium/content/renderer/media/render_media_log_unittest.cc7
-rw-r--r--chromium/content/renderer/media/renderer_webaudiodevice_impl.h1
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc27
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate.h3
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc14
-rw-r--r--chromium/content/renderer/media/rtc_certificate_generator.cc4
-rw-r--r--chromium/content/renderer/media/rtc_data_channel_handler.cc2
-rw-r--r--chromium/content/renderer/media/rtc_dtmf_sender_handler.cc6
-rw-r--r--chromium/content/renderer/media/rtc_peer_connection_handler.cc561
-rw-r--r--chromium/content/renderer/media/rtc_peer_connection_handler.h39
-rw-r--r--chromium/content/renderer/media/rtc_peer_connection_handler_unittest.cc368
-rw-r--r--chromium/content/renderer/media/speech_recognition_audio_sink.cc183
-rw-r--r--chromium/content/renderer/media/speech_recognition_audio_sink.h120
-rw-r--r--chromium/content/renderer/media/speech_recognition_audio_sink_unittest.cc547
-rw-r--r--chromium/content/renderer/media/track_audio_renderer.cc2
-rw-r--r--chromium/content/renderer/media/user_media_client_impl.cc82
-rw-r--r--chromium/content/renderer/media/user_media_client_impl.h28
-rw-r--r--chromium/content/renderer/media/user_media_client_impl_unittest.cc243
-rw-r--r--chromium/content/renderer/media/user_media_processor.cc185
-rw-r--r--chromium/content/renderer/media/user_media_processor.h80
-rw-r--r--chromium/content/renderer/media/video_capture_impl_manager_unittest.cc2
-rw-r--r--chromium/content/renderer/media/video_track_adapter.cc2
-rw-r--r--chromium/content/renderer/media/video_track_to_pepper_adapter.cc7
-rw-r--r--chromium/content/renderer/media/video_track_to_pepper_adapter_unittest.cc14
-rw-r--r--chromium/content/renderer/media/webmediaplayer_ms.cc15
-rw-r--r--chromium/content/renderer/media/webmediaplayer_ms.h10
-rw-r--r--chromium/content/renderer/media/webmediaplayer_ms_compositor.cc6
-rw-r--r--chromium/content/renderer/media/webmediaplayer_ms_unittest.cc2
-rw-r--r--chromium/content/renderer/media/webrtc/audio_codec_factory.cc85
-rw-r--r--chromium/content/renderer/media/webrtc/audio_codec_factory.h22
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc48
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc2
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc2
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc5
-rw-r--r--chromium/content/renderer/media/webrtc/mock_peer_connection_dependency_factory.cc16
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc39
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc2
-rw-r--r--chromium/content/renderer/media/webrtc/processed_local_audio_source.cc19
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc66
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h25
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc2
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc166
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h27
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc38
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h5
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc63
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc108
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h138
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc149
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc29
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc15
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc36
-rw-r--r--chromium/content/renderer/media/webrtc_audio_device_impl.cc99
-rw-r--r--chromium/content/renderer/media/webrtc_audio_device_impl.h17
-rw-r--r--chromium/content/renderer/media/webrtc_audio_device_not_impl.cc32
-rw-r--r--chromium/content/renderer/media/webrtc_audio_device_not_impl.h7
-rw-r--r--chromium/content/renderer/media/webrtc_audio_renderer.cc4
-rw-r--r--chromium/content/renderer/media/webrtc_logging.cc2
-rw-r--r--chromium/content/renderer/media_capture_from_element/canvas_capture_handler.cc355
-rw-r--r--chromium/content/renderer/media_capture_from_element/canvas_capture_handler.h48
-rw-r--r--chromium/content/renderer/media_capture_from_element/canvas_capture_handler_unittest.cc34
-rw-r--r--chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source.cc2
-rw-r--r--chromium/content/renderer/media_recorder/audio_track_encoder.cc20
-rw-r--r--chromium/content/renderer/media_recorder/audio_track_encoder.h62
-rw-r--r--chromium/content/renderer/media_recorder/audio_track_opus_encoder.cc200
-rw-r--r--chromium/content/renderer/media_recorder/audio_track_opus_encoder.h69
-rw-r--r--chromium/content/renderer/media_recorder/audio_track_pcm_encoder.cc56
-rw-r--r--chromium/content/renderer/media_recorder/audio_track_pcm_encoder.h36
-rw-r--r--chromium/content/renderer/media_recorder/audio_track_recorder.cc301
-rw-r--r--chromium/content/renderer/media_recorder/audio_track_recorder.h37
-rw-r--r--chromium/content/renderer/media_recorder/audio_track_recorder_unittest.cc138
-rw-r--r--chromium/content/renderer/media_recorder/media_recorder_handler.cc98
-rw-r--r--chromium/content/renderer/media_recorder/media_recorder_handler.h6
-rw-r--r--chromium/content/renderer/media_recorder/media_recorder_handler_unittest.cc20
-rw-r--r--chromium/content/renderer/media_recorder/video_track_recorder.cc8
-rw-r--r--chromium/content/renderer/media_recorder/video_track_recorder.h4
-rw-r--r--chromium/content/renderer/media_recorder/video_track_recorder_unittest.cc21
-rw-r--r--chromium/content/renderer/media_recorder/vpx_encoder.cc6
-rw-r--r--chromium/content/renderer/mojo/blink_connector_js_wrapper.cc39
-rw-r--r--chromium/content/renderer/mojo/blink_connector_js_wrapper.h4
-rw-r--r--chromium/content/renderer/mojo/blink_interface_registry_impl.cc21
-rw-r--r--chromium/content/renderer/mojo/blink_interface_registry_impl.h18
-rw-r--r--chromium/content/renderer/mojo/interface_provider_js_wrapper.cc54
-rw-r--r--chromium/content/renderer/mojo/interface_provider_js_wrapper.h3
-rw-r--r--chromium/content/renderer/mojo_bindings_controller.cc129
-rw-r--r--chromium/content/renderer/mojo_bindings_controller.h60
-rw-r--r--chromium/content/renderer/mojo_context_state.cc267
-rw-r--r--chromium/content/renderer/mojo_context_state.h86
-rw-r--r--chromium/content/renderer/mojo_main_runner.cc55
-rw-r--r--chromium/content/renderer/mojo_main_runner.h46
-rw-r--r--chromium/content/renderer/mouse_lock_dispatcher.cc16
-rw-r--r--chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc8
-rw-r--r--chromium/content/renderer/mus/BUILD.gn3
-rw-r--r--chromium/content/renderer/mus/mus_embedded_frame.cc121
-rw-r--r--chromium/content/renderer/mus/mus_embedded_frame.h87
-rw-r--r--chromium/content/renderer/mus/mus_embedded_frame_delegate.h31
-rw-r--r--chromium/content/renderer/mus/render_widget_window_tree_client_factory.cc2
-rw-r--r--chromium/content/renderer/mus/renderer_window_tree_client.cc139
-rw-r--r--chromium/content/renderer/mus/renderer_window_tree_client.h64
-rw-r--r--chromium/content/renderer/notifications/OWNERS (renamed from chromium/content/child/notifications/OWNERS)0
-rw-r--r--chromium/content/renderer/notifications/notification_data_conversions.cc (renamed from chromium/content/child/notifications/notification_data_conversions.cc)2
-rw-r--r--chromium/content/renderer/notifications/notification_data_conversions.h (renamed from chromium/content/child/notifications/notification_data_conversions.h)6
-rw-r--r--chromium/content/renderer/notifications/notification_data_conversions_unittest.cc (renamed from chromium/content/child/notifications/notification_data_conversions_unittest.cc)2
-rw-r--r--chromium/content/renderer/notifications/notification_dispatcher.cc (renamed from chromium/content/child/notifications/notification_dispatcher.cc)4
-rw-r--r--chromium/content/renderer/notifications/notification_dispatcher.h (renamed from chromium/content/child/notifications/notification_dispatcher.h)8
-rw-r--r--chromium/content/renderer/notifications/notification_manager.cc (renamed from chromium/content/child/notifications/notification_manager.cc)8
-rw-r--r--chromium/content/renderer/notifications/notification_manager.h (renamed from chromium/content/child/notifications/notification_manager.h)10
-rw-r--r--chromium/content/renderer/p2p/filtering_network_manager_unittest.cc2
-rw-r--r--chromium/content/renderer/p2p/ipc_socket_factory.cc6
-rw-r--r--chromium/content/renderer/p2p/socket_client_impl.cc6
-rw-r--r--chromium/content/renderer/p2p/socket_dispatcher.cc11
-rw-r--r--chromium/content/renderer/pepper/content_decryptor_delegate.cc52
-rw-r--r--chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc31
-rw-r--r--chromium/content/renderer/pepper/event_conversion.cc2
-rw-r--r--chromium/content/renderer/pepper/host_array_buffer_var.cc2
-rw-r--r--chromium/content/renderer/pepper/host_globals.cc16
-rw-r--r--chromium/content/renderer/pepper/host_var_tracker_unittest.cc4
-rw-r--r--chromium/content/renderer/pepper/message_channel.cc2
-rw-r--r--chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc11
-rw-r--r--chromium/content/renderer/pepper/mock_renderer_ppapi_host.h1
-rw-r--r--chromium/content/renderer/pepper/pepper_audio_input_host.cc4
-rw-r--r--chromium/content/renderer/pepper/pepper_audio_output_host.cc4
-rw-r--r--chromium/content/renderer/pepper/pepper_broker.cc4
-rw-r--r--chromium/content/renderer/pepper/pepper_compositor_host.cc39
-rw-r--r--chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.cc4
-rw-r--r--chromium/content/renderer/pepper/pepper_file_chooser_host.cc8
-rw-r--r--chromium/content/renderer/pepper/pepper_file_system_host.cc6
-rw-r--r--chromium/content/renderer/pepper/pepper_graphics_2d_host.cc262
-rw-r--r--chromium/content/renderer/pepper/pepper_graphics_2d_host.h51
-rw-r--r--chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc8
-rw-r--r--chromium/content/renderer/pepper/pepper_in_process_router.cc2
-rw-r--r--chromium/content/renderer/pepper/pepper_media_device_manager.cc93
-rw-r--r--chromium/content/renderer/pepper/pepper_media_device_manager.h39
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_input.cc14
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_output.cc9
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_output_dev.cc8
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_camera_device.cc4
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_video_capture.cc7
-rw-r--r--chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc322
-rw-r--r--chromium/content/renderer/pepper/pepper_plugin_instance_impl.h84
-rw-r--r--chromium/content/renderer/pepper/pepper_plugin_registry.cc6
-rw-r--r--chromium/content/renderer/pepper/pepper_url_loader_host.cc45
-rw-r--r--chromium/content/renderer/pepper/pepper_video_capture_host.cc3
-rw-r--r--chromium/content/renderer/pepper/pepper_video_destination_host.cc8
-rw-r--r--chromium/content/renderer/pepper/pepper_video_encoder_host.cc14
-rw-r--r--chromium/content/renderer/pepper/pepper_video_source_host.cc12
-rw-r--r--chromium/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc3
-rw-r--r--chromium/content/renderer/pepper/plugin_module.cc24
-rw-r--r--chromium/content/renderer/pepper/plugin_object.cc6
-rw-r--r--chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc40
-rw-r--r--chromium/content/renderer/pepper/ppb_audio_impl.cc4
-rw-r--r--chromium/content/renderer/pepper/ppb_broker_impl.cc13
-rw-r--r--chromium/content/renderer/pepper/ppb_buffer_impl.cc2
-rw-r--r--chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc4
-rw-r--r--chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc35
-rw-r--r--chromium/content/renderer/pepper/ppb_image_data_impl.cc10
-rw-r--r--chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc6
-rw-r--r--chromium/content/renderer/pepper/ppb_video_decoder_impl.cc5
-rw-r--r--chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc24
-rw-r--r--chromium/content/renderer/pepper/renderer_ppapi_host_impl.h8
-rw-r--r--chromium/content/renderer/pepper/resource_converter.cc2
-rw-r--r--chromium/content/renderer/pepper/resource_creation_impl.cc3
-rw-r--r--chromium/content/renderer/pepper/url_request_info_util.cc4
-rw-r--r--chromium/content/renderer/pepper/v8_var_converter_unittest.cc2
-rw-r--r--chromium/content/renderer/pepper/v8object_var.cc4
-rw-r--r--chromium/content/renderer/pepper/video_decoder_shim.cc11
-rw-r--r--chromium/content/renderer/peripheral_content_heuristic_unittest.cc61
-rw-r--r--chromium/content/renderer/presentation/presentation_dispatcher_unittest.cc24
-rw-r--r--chromium/content/renderer/push_messaging/push_messaging_client.cc19
-rw-r--r--chromium/content/renderer/push_messaging/push_messaging_client.h5
-rw-r--r--chromium/content/renderer/push_messaging/push_provider.cc (renamed from chromium/content/child/push_messaging/push_provider.cc)4
-rw-r--r--chromium/content/renderer/push_messaging/push_provider.h (renamed from chromium/content/child/push_messaging/push_provider.h)8
-rw-r--r--chromium/content/renderer/quota_dispatcher.cc (renamed from chromium/content/child/quota_dispatcher.cc)106
-rw-r--r--chromium/content/renderer/quota_dispatcher.h (renamed from chromium/content/child/quota_dispatcher.h)49
-rw-r--r--chromium/content/renderer/render_frame_impl.cc1329
-rw-r--r--chromium/content/renderer/render_frame_impl.h213
-rw-r--r--chromium/content/renderer/render_frame_impl_browsertest.cc57
-rw-r--r--chromium/content/renderer/render_frame_proxy.cc227
-rw-r--r--chromium/content/renderer/render_frame_proxy.h75
-rw-r--r--chromium/content/renderer/render_process_impl.cc9
-rw-r--r--chromium/content/renderer/render_thread_impl.cc427
-rw-r--r--chromium/content/renderer/render_thread_impl.h103
-rw-r--r--chromium/content/renderer/render_thread_impl_browsertest.cc26
-rw-r--r--chromium/content/renderer/render_view_browsertest.cc219
-rw-r--r--chromium/content/renderer/render_view_impl.cc339
-rw-r--r--chromium/content/renderer/render_view_impl.h47
-rw-r--r--chromium/content/renderer/render_widget.cc255
-rw-r--r--chromium/content/renderer/render_widget.h61
-rw-r--r--chromium/content/renderer/render_widget_browsertest.cc17
-rw-r--r--chromium/content/renderer/render_widget_fullscreen_pepper.cc6
-rw-r--r--chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc10
-rw-r--r--chromium/content/renderer/render_widget_owner_delegate.h6
-rw-r--r--chromium/content/renderer/render_widget_unittest.cc297
-rw-r--r--chromium/content/renderer/renderer_blink_platform_impl.cc277
-rw-r--r--chromium/content/renderer/renderer_blink_platform_impl.h67
-rw-r--r--chromium/content/renderer/renderer_clipboard_delegate.cc162
-rw-r--r--chromium/content/renderer/renderer_clipboard_delegate.h70
-rw-r--r--chromium/content/renderer/renderer_main.cc8
-rw-r--r--chromium/content/renderer/renderer_main_platform_delegate_android.cc2
-rw-r--r--chromium/content/renderer/renderer_main_platform_delegate_linux.cc22
-rw-r--r--chromium/content/renderer/renderer_main_platform_delegate_mac.mm6
-rw-r--r--chromium/content/renderer/renderer_main_platform_delegate_win.cc1
-rw-r--r--chromium/content/renderer/renderer_webapplicationcachehost_impl.cc8
-rw-r--r--chromium/content/renderer/renderer_webapplicationcachehost_impl.h2
-rw-r--r--chromium/content/renderer/renderer_webcookiejar_impl.cc5
-rw-r--r--chromium/content/renderer/sandbox_mac_v2_unittest.mm32
-rw-r--r--chromium/content/renderer/savable_resources.cc2
-rw-r--r--chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.cc2
-rw-r--r--chromium/content/renderer/screen_orientation/screen_orientation_dispatcher_browsertest.cc16
-rw-r--r--chromium/content/renderer/service_worker/controller_service_worker_connector.cc (renamed from chromium/content/child/service_worker/controller_service_worker_connector.cc)14
-rw-r--r--chromium/content/renderer/service_worker/controller_service_worker_connector.h (renamed from chromium/content/child/service_worker/controller_service_worker_connector.h)18
-rw-r--r--chromium/content/renderer/service_worker/controller_service_worker_impl.cc37
-rw-r--r--chromium/content/renderer/service_worker/controller_service_worker_impl.h59
-rw-r--r--chromium/content/renderer/service_worker/embedded_worker_devtools_agent.cc39
-rw-r--r--chromium/content/renderer/service_worker/embedded_worker_devtools_agent.h10
-rw-r--r--chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.cc28
-rw-r--r--chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.h9
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_client.cc824
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_client.h53
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_message_filter.h2
-rw-r--r--chromium/content/renderer/service_worker/service_worker_dispatcher.cc141
-rw-r--r--chromium/content/renderer/service_worker/service_worker_dispatcher.h104
-rw-r--r--chromium/content/renderer/service_worker/service_worker_dispatcher_unittest.cc199
-rw-r--r--chromium/content/renderer/service_worker/service_worker_fetch_context_impl.cc29
-rw-r--r--chromium/content/renderer/service_worker/service_worker_fetch_context_impl.h10
-rw-r--r--chromium/content/renderer/service_worker/service_worker_handle_reference.cc59
-rw-r--r--chromium/content/renderer/service_worker/service_worker_handle_reference.h (renamed from chromium/content/child/service_worker/service_worker_handle_reference.h)32
-rw-r--r--chromium/content/renderer/service_worker/service_worker_message_filter.cc39
-rw-r--r--chromium/content/renderer/service_worker/service_worker_message_filter.h34
-rw-r--r--chromium/content/renderer/service_worker/service_worker_network_provider.cc (renamed from chromium/content/child/service_worker/service_worker_network_provider.cc)95
-rw-r--r--chromium/content/renderer/service_worker/service_worker_network_provider.h (renamed from chromium/content/child/service_worker/service_worker_network_provider.h)33
-rw-r--r--chromium/content/renderer/service_worker/service_worker_provider_context.cc441
-rw-r--r--chromium/content/renderer/service_worker/service_worker_provider_context.h (renamed from chromium/content/child/service_worker/service_worker_provider_context.h)140
-rw-r--r--chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc551
-rw-r--r--chromium/content/renderer/service_worker/service_worker_subresource_loader.cc (renamed from chromium/content/child/service_worker/service_worker_subresource_loader.cc)178
-rw-r--r--chromium/content/renderer/service_worker/service_worker_subresource_loader.h (renamed from chromium/content/child/service_worker/service_worker_subresource_loader.h)45
-rw-r--r--chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc844
-rw-r--r--chromium/content/renderer/service_worker/service_worker_timeout_timer.cc118
-rw-r--r--chromium/content/renderer/service_worker/service_worker_timeout_timer.h110
-rw-r--r--chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc211
-rw-r--r--chromium/content/renderer/service_worker/service_worker_type_util.cc27
-rw-r--r--chromium/content/renderer/service_worker/thread_safe_script_container.cc21
-rw-r--r--chromium/content/renderer/service_worker/thread_safe_script_container.h21
-rw-r--r--chromium/content/renderer/service_worker/thread_safe_script_container_unittest.cc8
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_impl.cc (renamed from chromium/content/child/service_worker/web_service_worker_impl.cc)14
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_impl.h (renamed from chromium/content/child/service_worker/web_service_worker_impl.h)6
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.cc54
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h6
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl_unittest.cc112
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc (renamed from chromium/content/child/service_worker/web_service_worker_provider_impl.cc)183
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_provider_impl.h (renamed from chromium/content/child/service_worker/web_service_worker_provider_impl.h)46
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc479
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_registration_impl.h293
-rw-r--r--chromium/content/renderer/service_worker/worker_fetch_context_impl.cc166
-rw-r--r--chromium/content/renderer/service_worker/worker_fetch_context_impl.h44
-rw-r--r--chromium/content/renderer/shared_memory_seqlock_reader.cc6
-rw-r--r--chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc73
-rw-r--r--chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h8
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_devtools_agent.cc (renamed from chromium/content/child/shared_worker_devtools_agent.cc)13
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_devtools_agent.h (renamed from chromium/content/child/shared_worker_devtools_agent.h)12
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc11
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_factory_impl.h4
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_repository.cc4
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_repository.h1
-rw-r--r--chromium/content/renderer/skia_benchmarking_extension.cc6
-rw-r--r--chromium/content/renderer/speech_recognition_dispatcher.cc73
-rw-r--r--chromium/content/renderer/speech_recognition_dispatcher.h27
-rw-r--r--chromium/content/renderer/stats_collection_controller.cc36
-rw-r--r--chromium/content/renderer/storage_util.cc (renamed from chromium/content/child/storage_util.cc)2
-rw-r--r--chromium/content/renderer/storage_util.h (renamed from chromium/content/child/storage_util.h)6
-rw-r--r--chromium/content/renderer/v8_value_converter_impl.cc (renamed from chromium/content/child/v8_value_converter_impl.cc)36
-rw-r--r--chromium/content/renderer/v8_value_converter_impl.h (renamed from chromium/content/child/v8_value_converter_impl.h)8
-rw-r--r--chromium/content/renderer/v8_value_converter_impl_unittest.cc (renamed from chromium/content/child/v8_value_converter_impl_unittest.cc)22
-rw-r--r--chromium/content/renderer/web_database_observer_impl.cc (renamed from chromium/content/child/web_database_observer_impl.cc)8
-rw-r--r--chromium/content/renderer/web_database_observer_impl.h (renamed from chromium/content/child/web_database_observer_impl.h)15
-rw-r--r--chromium/content/renderer/web_ui_extension.cc11
-rw-r--r--chromium/content/renderer/webclipboard_impl.cc117
-rw-r--r--chromium/content/renderer/webclipboard_impl.h8
-rw-r--r--chromium/content/renderer/webclipboard_impl_browsertest.cc3
-rw-r--r--chromium/content/renderer/webfileutilities_impl.cc (renamed from chromium/content/child/webfileutilities_impl.cc)4
-rw-r--r--chromium/content/renderer/webfileutilities_impl.h (renamed from chromium/content/child/webfileutilities_impl.h)6
-rw-r--r--chromium/content/renderer/webgraphicscontext3d_provider_impl.cc43
-rw-r--r--chromium/content/renderer/webgraphicscontext3d_provider_impl.h29
-rw-r--r--chromium/content/renderer/worker_thread_message_filter.cc (renamed from chromium/content/child/worker_thread_message_filter.cc)4
-rw-r--r--chromium/content/renderer/worker_thread_message_filter.h (renamed from chromium/content/child/worker_thread_message_filter.h)8
-rw-r--r--chromium/content/renderer/worker_thread_registry.cc (renamed from chromium/content/child/worker_thread_registry.cc)4
-rw-r--r--chromium/content/renderer/worker_thread_registry.h (renamed from chromium/content/child/worker_thread_registry.h)8
-rw-r--r--chromium/content/renderer/worker_thread_registry_unittest.cc (renamed from chromium/content/child/worker_thread_registry_unittest.cc)4
-rw-r--r--chromium/content/shell/BUILD.gn97
-rw-r--r--chromium/content/shell/shell_resources.grd2
-rw-r--r--chromium/content/shell/test_runner/BUILD.gn4
-rw-r--r--chromium/content/test/BUILD.gn149
-rw-r--r--chromium/content/test/fuzzer/BUILD.gn12
-rw-r--r--chromium/content/utility/BUILD.gn1
-rw-r--r--chromium/content/utility/DEPS1
-rw-r--r--chromium/content/utility/utility_main.cc18
-rw-r--r--chromium/content/utility/utility_service_factory.cc29
-rw-r--r--chromium/content/utility/utility_service_factory.h6
-rw-r--r--chromium/content/utility/utility_thread_impl.cc4
-rw-r--r--chromium/content/zygote/DEPS3
-rw-r--r--chromium/content/zygote/OWNERS5
-rw-r--r--chromium/content/zygote/zygote_linux.cc40
-rw-r--r--chromium/content/zygote/zygote_main_linux.cc119
2517 files changed, 77200 insertions, 64625 deletions
diff --git a/chromium/content/BUILD.gn b/chromium/content/BUILD.gn
index aead39a3c41..6123821cd17 100644
--- a/chromium/content/BUILD.gn
+++ b/chromium/content/BUILD.gn
@@ -88,8 +88,8 @@ if (is_component_build) {
source_set("content") {
set_sources_assignment_filter([])
sources = [
- "common/sandbox_linux/sandbox_init_linux.cc",
- "common/sandbox_linux/sandbox_seccomp_bpf_linux.cc",
+ "//services/service_manager/sandbox/linux/sandbox_seccomp_bpf_linux.cc",
+ "common/sandbox_init_linux.cc",
"common/send_zygote_child_ping_linux.cc",
"public/common/content_switches.cc",
"public/common/content_switches.h",
@@ -97,7 +97,6 @@ if (is_component_build) {
"public/common/mojo_channel_switches.h",
]
set_sources_assignment_filter(sources_assignment_filter)
-
deps = [
"//base",
"//media:media_features",
@@ -133,7 +132,6 @@ grit("resources") {
"//content/public/app:plugin_manifest",
"//content/public/app:renderer_manifest",
"//content/public/app:utility_manifest",
- "//mojo/public/js:bindings",
"//services/catalog:manifest",
]
}
diff --git a/chromium/content/app/android/content_child_process_service_delegate.cc b/chromium/content/app/android/content_child_process_service_delegate.cc
index ff4ebaad11a..e248520493e 100644
--- a/chromium/content/app/android/content_child_process_service_delegate.cc
+++ b/chromium/content/app/android/content_child_process_service_delegate.cc
@@ -99,10 +99,11 @@ base::LazyInstance<ChildProcessSurfaceManager>::Leaky
// Chrome actually uses the renderer code path for all of its child
// processes such as renderers, plugins, etc.
-void InternalInitChildProcess(JNIEnv* env,
- const JavaParamRef<jobject>& service_impl,
- jint cpu_count,
- jlong cpu_features) {
+void JNI_ContentChildProcessServiceDelegate_InternalInitChildProcess(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& service_impl,
+ jint cpu_count,
+ jlong cpu_features) {
// Set the CPU properties.
android_setCpu(cpu_count, cpu_features);
@@ -118,19 +119,24 @@ void InternalInitChildProcess(JNIEnv* env,
} // namespace
-void InitChildProcess(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jint cpu_count,
- jlong cpu_features) {
- InternalInitChildProcess(env, obj, cpu_count, cpu_features);
+void JNI_ContentChildProcessServiceDelegate_InitChildProcess(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint cpu_count,
+ jlong cpu_features) {
+ JNI_ContentChildProcessServiceDelegate_InternalInitChildProcess(
+ env, obj, cpu_count, cpu_features);
}
-void ShutdownMainThread(JNIEnv* env, const JavaParamRef<jobject>& obj) {
+void JNI_ContentChildProcessServiceDelegate_ShutdownMainThread(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
ChildThreadImpl::ShutdownThread();
}
-void RetrieveFileDescriptorsIdsToKeys(JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
+void JNI_ContentChildProcessServiceDelegate_RetrieveFileDescriptorsIdsToKeys(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
std::map<int, std::string> ids_to_keys;
std::string file_switch_value =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
diff --git a/chromium/content/app/android/content_main.cc b/chromium/content/app/android/content_main.cc
index bb5c870998f..664f0464833 100644
--- a/chromium/content/app/android/content_main.cc
+++ b/chromium/content/app/android/content_main.cc
@@ -28,12 +28,13 @@ LazyInstance<std::unique_ptr<ContentMainDelegate>>::DestructorAtExit
} // namespace
-static jint Start(JNIEnv* env, const JavaParamRef<jclass>& clazz) {
+static jint JNI_ContentMain_Start(JNIEnv* env,
+ const JavaParamRef<jclass>& clazz) {
TRACE_EVENT0("startup", "content::Start");
DCHECK(!g_service_manager_main_delegate.Get());
g_service_manager_main_delegate.Get() =
- base::MakeUnique<ContentServiceManagerMainDelegate>(
+ std::make_unique<ContentServiceManagerMainDelegate>(
ContentMainParams(g_content_main_delegate.Get().get()));
service_manager::MainParams main_params(
diff --git a/chromium/content/app/android/library_loader_hooks.cc b/chromium/content/app/android/library_loader_hooks.cc
index 8d2a753abd0..9db1995783d 100644
--- a/chromium/content/app/android/library_loader_hooks.cc
+++ b/chromium/content/app/android/library_loader_hooks.cc
@@ -18,7 +18,7 @@ bool LibraryLoaded(JNIEnv* env, jclass clazz) {
// Android's main browser loop is custom so we set the browser
// name here as early as possible.
- base::trace_event::TraceLog::GetInstance()->SetProcessName("Browser");
+ base::trace_event::TraceLog::GetInstance()->set_process_name("Browser");
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventBrowserProcessSortIndex);
diff --git a/chromium/content/app/content_main_runner.cc b/chromium/content/app/content_main_runner.cc
index d2275a49982..d5e46419c0b 100644
--- a/chromium/content/app/content_main_runner.cc
+++ b/chromium/content/app/content_main_runner.cc
@@ -73,7 +73,6 @@
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/power_monitor/power_monitor_device_source.h"
#include "content/browser/mach_broker_mac.h"
-#include "content/common/sandbox_init_mac.h"
#endif // OS_WIN
#if defined(OS_POSIX)
@@ -170,6 +169,7 @@ void InitializeFieldTrialAndFeatureList(
base::FeatureList::SetInstance(std::move(feature_list));
}
+#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
void LoadV8ContextSnapshotFile() {
#if defined(OS_POSIX) && !defined(OS_MACOSX)
base::FileDescriptorStore& file_descriptor_store =
@@ -182,14 +182,13 @@ void LoadV8ContextSnapshotFile() {
region.size);
return;
}
-#endif // OS
+#endif // OS_POSIX && !OS_MACOSX
#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
gin::V8Initializer::LoadV8ContextSnapshot();
-#endif
+#endif // !CHROME_MULTIPLE_DLL_BROWSER
}
void LoadV8SnapshotFile() {
-#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
#if defined(OS_POSIX) && !defined(OS_MACOSX)
base::FileDescriptorStore& file_descriptor_store =
base::FileDescriptorStore::GetInstance();
@@ -204,12 +203,10 @@ void LoadV8SnapshotFile() {
#endif // OS_POSIX && !OS_MACOSX
#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
gin::V8Initializer::LoadV8Snapshot();
-#endif
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
+#endif // !CHROME_MULTIPLE_DLL_BROWSER
}
void LoadV8NativesFile() {
-#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
#if defined(OS_POSIX) && !defined(OS_MACOSX)
base::FileDescriptorStore& file_descriptor_store =
base::FileDescriptorStore::GetInstance();
@@ -224,18 +221,20 @@ void LoadV8NativesFile() {
#endif // OS_POSIX && !OS_MACOSX
#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
gin::V8Initializer::LoadV8Natives();
-#endif
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
+#endif // !CHROME_MULTIPLE_DLL_BROWSER
}
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
void InitializeV8IfNeeded(const base::CommandLine& command_line,
const std::string& process_type) {
if (process_type == switches::kGpuProcess)
return;
+#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
LoadV8SnapshotFile();
LoadV8NativesFile();
LoadV8ContextSnapshotFile();
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
}
} // namespace
@@ -306,8 +305,7 @@ struct MainFunction {
int (*function)(const MainFunctionParams&);
};
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \
- !defined(OS_FUCHSIA)
+#if defined(OS_LINUX)
// On platforms that use the zygote, we have a special subset of
// subprocesses that are launched via the zygote. This function
// fills in some process-launching bits around ZygoteMain().
@@ -364,8 +362,7 @@ int RunZygote(const MainFunctionParams& main_function_params,
NOTREACHED() << "Unknown zygote process type: " << process_type;
return 1;
}
-#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \
-// !defined(OS_FUCHSIA)
+#endif // defined(OS_LINUX)
static void RegisterMainThreadFactories() {
#if !defined(CHROME_MULTIPLE_DLL_BROWSER) && !defined(CHROME_MULTIPLE_DLL_CHILD)
@@ -453,8 +450,8 @@ class ContentMainRunnerImpl : public ContentMainRunner {
: is_initialized_(false),
is_shutdown_(false),
completed_basic_startup_(false),
- delegate_(NULL),
- ui_task_(NULL) {
+ delegate_(nullptr),
+ ui_task_(nullptr) {
#if defined(OS_WIN)
memset(&sandbox_info_, 0, sizeof(sandbox_info_));
#endif
@@ -693,8 +690,6 @@ class ContentMainRunnerImpl : public ContentMainRunner {
if (!process_type.empty() && process_type != switches::kZygoteProcess)
InitializeFieldTrialAndFeatureList(&field_trial_list);
- base::HistogramBase::EnableActivityReportHistogram(process_type);
-
MainFunctionParams main_params(command_line);
main_params.ui_task = ui_task_;
#if defined(OS_WIN)
@@ -729,9 +724,9 @@ class ContentMainRunnerImpl : public ContentMainRunner {
#endif // _CRTDBG_MAP_ALLOC
#endif // OS_WIN
- exit_manager_.reset(NULL);
+ exit_manager_.reset(nullptr);
- delegate_ = NULL;
+ delegate_ = nullptr;
is_shutdown_ = true;
}
diff --git a/chromium/content/app/content_service_manager_main_delegate.cc b/chromium/content/app/content_service_manager_main_delegate.cc
index 104f2bd1f43..62dceb57886 100644
--- a/chromium/content/app/content_service_manager_main_delegate.cc
+++ b/chromium/content/app/content_service_manager_main_delegate.cc
@@ -109,14 +109,6 @@ void ContentServiceManagerMainDelegate::AdjustServiceProcessCommandLine(
command_line->AppendArgNative(arg);
}
-bool ContentServiceManagerMainDelegate::
- ShouldTerminateServiceManagerOnInstanceQuit(
- const service_manager::Identity& identity,
- int* exit_code) {
- return content_main_params_.delegate
- ->ShouldTerminateServiceManagerOnInstanceQuit(identity, exit_code);
-}
-
void ContentServiceManagerMainDelegate::OnServiceManagerInitialized(
const base::Closure& quit_closure,
service_manager::BackgroundServiceManager* service_manager) {
diff --git a/chromium/content/app/content_service_manager_main_delegate.h b/chromium/content/app/content_service_manager_main_delegate.h
index 7563ce48bf5..4393a8fac23 100644
--- a/chromium/content/app/content_service_manager_main_delegate.h
+++ b/chromium/content/app/content_service_manager_main_delegate.h
@@ -34,9 +34,6 @@ class ContentServiceManagerMainDelegate : public service_manager::MainDelegate {
void AdjustServiceProcessCommandLine(
const service_manager::Identity& identity,
base::CommandLine* command_line) override;
- bool ShouldTerminateServiceManagerOnInstanceQuit(
- const service_manager::Identity& identity,
- int* exit_code) override;
void OnServiceManagerInitialized(
const base::Closure& quit_closure,
service_manager::BackgroundServiceManager* service_manager) override;
diff --git a/chromium/content/app/strings/content_strings.grd b/chromium/content/app/strings/content_strings.grd
index 2dedd1ac31a..448e474b794 100644
--- a/chromium/content/app/strings/content_strings.grd
+++ b/chromium/content/app/strings/content_strings.grd
@@ -782,6 +782,9 @@ below:
<message name="IDS_MEDIA_OVERFLOW_MENU_CLOSED_CAPTIONS" desc="Media controls overflow menu item label for a closed captions button. The text for this overflow menu should be short.">
Captions
</message>
+ <message name="IDS_MEDIA_OVERFLOW_MENU_CLOSED_CAPTIONS_SUBMENU_TITLE" desc="Media controls overflow menu title for the closed captions submenu. The text for this overflow menu should be short.">
+ Options
+ </message>
<message name="IDS_MEDIA_OVERFLOW_MENU_CAST" desc="Media controls overflow menu item label for a cast button.">
Cast
</message>
@@ -809,9 +812,6 @@ below:
<message name="IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD" desc="Media controls overflow menu item label for a download button.">
Download
</message>
- <message name="IDS_MEDIA_REMOTING_DISABLE_TEXT" desc="Media remoting disable button label.">
- Play on both screens
- </message>
<message name="IDS_MEDIA_REMOTING_CAST_TEXT" desc="Text message shown to the user when casting a video to a known remote device.">
Now casting to <ph name="DEVICE_FRIENDLY_NAME">$1<ex>Living Room TV</ex></ph>
</message>
diff --git a/chromium/content/app/strings/translations/content_strings_am.xtb b/chromium/content/app/strings/translations/content_strings_am.xtb
index 1cad7854674..181edbb09f4 100644
--- a/chromium/content/app/strings/translations/content_strings_am.xtb
+++ b/chromium/content/app/strings/translations/content_strings_am.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">የወር መምረጫ ፓነል አሳይ</translation>
<translation id="6404546809543547843">የኦዲዮ ሰዓት አንፏቃቂ</translation>
<translation id="648732519525291180">ሰዓት መራጭ</translation>
+<translation id="6550675742724504774">አማራጮች</translation>
<translation id="658823671542763450">ወደ ሙሉ ገጽ ዕይታ ግባ</translation>
<translation id="663493177488814956">ምግብ</translation>
<translation id="6637586476836377253">የምዝግብ ማስታወሻ</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">እባክዎ ፋይል ይምረጡ።</translation>
<translation id="8461852803063341183">የሬዲዮ አዝራር</translation>
<translation id="8511325616783751178">የተቆልቋይ አዝራር</translation>
-<translation id="8519420564908284378">በሁለቱም ማያ ገጾች ላይ ተጫወት</translation>
<translation id="8534579021159131403">ደቂቃዎች</translation>
<translation id="8541249477527128034">የማህደረ መረጃ ቁጥጥር</translation>
<translation id="8583702881314752957">የብየና ዝርዝር</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ar.xtb b/chromium/content/app/strings/translations/content_strings_ar.xtb
index 5eb50b6b70f..b2e31c12817 100644
--- a/chromium/content/app/strings/translations/content_strings_ar.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ar.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">عرض لوحة تحديد الشهر</translation>
<translation id="6404546809543547843">شريط تمرير وقت الصوت</translation>
<translation id="648732519525291180">منتقي الوقت</translation>
+<translation id="6550675742724504774">خيارات</translation>
<translation id="658823671542763450">تشغيل وضع ملء الشاشة</translation>
<translation id="663493177488814956">البطاقات</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">يُرجى تحديد ملف.</translation>
<translation id="8461852803063341183">زر الاختيار</translation>
<translation id="8511325616783751178">زر القائمة المنسدلة</translation>
-<translation id="8519420564908284378">التشغيل على كلتا الشاشتين</translation>
<translation id="8534579021159131403">دقائق</translation>
<translation id="8541249477527128034">التحكم في الوسائط</translation>
<translation id="8583702881314752957">قائمة تعريف</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_bg.xtb b/chromium/content/app/strings/translations/content_strings_bg.xtb
index ae7a0c29d7f..3b4af6a07bf 100644
--- a/chromium/content/app/strings/translations/content_strings_bg.xtb
+++ b/chromium/content/app/strings/translations/content_strings_bg.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Показване на панела за избиране на месец</translation>
<translation id="6404546809543547843">времеви плъзгач за аудиозаписа</translation>
<translation id="648732519525291180">инструмент за избор на час</translation>
+<translation id="6550675742724504774">Опции</translation>
<translation id="658823671542763450">вход за цял екран</translation>
<translation id="663493177488814956">емисия</translation>
<translation id="6637586476836377253">регистрационен файл</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Моля, изберете файл.</translation>
<translation id="8461852803063341183">бутон за избор</translation>
<translation id="8511325616783751178">бутон за падащо меню</translation>
-<translation id="8519420564908284378">Възпроизвеждане и на двата екрана</translation>
<translation id="8534579021159131403">Минути</translation>
<translation id="8541249477527128034">медийна контрола</translation>
<translation id="8583702881314752957">списък с дефиниции</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_bn.xtb b/chromium/content/app/strings/translations/content_strings_bn.xtb
index feacf0c9627..1dac567321a 100644
--- a/chromium/content/app/strings/translations/content_strings_bn.xtb
+++ b/chromium/content/app/strings/translations/content_strings_bn.xtb
@@ -6,7 +6,7 @@
<translation id="10623998915015855">টগল বোতাম</translation>
<translation id="1088086359088493902">সেকেন্ড</translation>
<translation id="1171774979989969504">দয়া করে কোন ইমেল ঠিকানা প্রবেশ করান:</translation>
-<translation id="1178581264944972037">বিরাম</translation>
+<translation id="1178581264944972037">বিরতি</translation>
<translation id="1188858454923323853">পরিপূরক</translation>
<translation id="1206619573307042055">marquee</translation>
<translation id="1206693055195146388">স্লাইডার</translation>
@@ -39,14 +39,14 @@
<translation id="2561842179657104141">আরও মিডিয়া নিয়ন্ত্রণ দেখান</translation>
<translation id="2572483411312390101">চালনা করুন</translation>
<translation id="2613802280814924224">দয়া করে একটি বৈধ মান লিখুন৷ কাছাকাছির বৈধ মান হল <ph name="VALID_VALUE" />৷</translation>
-<translation id="2653659639078652383">জমা</translation>
+<translation id="2653659639078652383">জমা দিন</translation>
<translation id="2674318244760992338">পাদলেখ</translation>
<translation id="2709516037105925701">স্বয়ংপূরণ</translation>
<translation id="2723001399770238859">অডিও</translation>
<translation id="2746543609216772311">মানকে অবশ্যই <ph name="MINIMUM_DATE_OR_TIME" /> বা পরবর্তী হতে হবে৷</translation>
<translation id="2759744352195237655">পপ আপ বোতাম</translation>
<translation id="2761667185364618470">আপনি যদি এগিয়ে যেতে চান তবে দয়া করে এই বাক্সটি পরীক্ষা করুন৷</translation>
-<translation id="2896972712917208084">রেডিও বোতাম গোষ্ঠী</translation>
+<translation id="2896972712917208084">রেডিও বোতাম গ্রুপ</translation>
<translation id="2908441821576996758">দয়া করে ইমেল ঠিকানাগুলির একটি কমা দিয়ে আলাদা করা মান প্রবেশ করান৷</translation>
<translation id="2940813599313844715">অবজেক্ট</translation>
<translation id="2942448076852699108">হাইলাইট করা সামগ্রী</translation>
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">মাস নির্বাচনের প্যানেল দেখান</translation>
<translation id="6404546809543547843">অডিও সময় স্ক্রাবার</translation>
<translation id="648732519525291180">সময় চয়নকারি</translation>
+<translation id="6550675742724504774">বিকল্পসমূহ</translation>
<translation id="658823671542763450">পূর্ণ স্ক্রীনে প্রবেশ করুন</translation>
<translation id="663493177488814956">ফিড</translation>
<translation id="6637586476836377253">লগ</translation>
@@ -163,11 +164,10 @@
<translation id="8451268428117625855">দয়া করে একটি ফাইল নির্বাচন করুন৷</translation>
<translation id="8461852803063341183">রেডিও বোতাম</translation>
<translation id="8511325616783751178">ড্রপ ডাউন বোতাম</translation>
-<translation id="8519420564908284378">দুটি স্ক্রিনেই প্লে করুন</translation>
<translation id="8534579021159131403">মিনিট</translation>
<translation id="8541249477527128034">মিডিয়া নিয়ন্ত্রণ</translation>
<translation id="8583702881314752957">সংজ্ঞার তালিকা</translation>
-<translation id="8597182159515967513">শিরোনামা</translation>
+<translation id="8597182159515967513">শিরোনাম</translation>
<translation id="8613126697340063924">রিমোট প্লেব্যাক নিয়ন্ত্রণ করুন</translation>
<translation id="8750798805984357768">দয়া করে বিকল্পগুলির একটি নির্বাচন করুন৷</translation>
<translation id="8785498733064193001">প্লেব্যাক শুরু করুন</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ca.xtb b/chromium/content/app/strings/translations/content_strings_ca.xtb
index 0110d59dd4c..d49f3f40ecf 100644
--- a/chromium/content/app/strings/translations/content_strings_ca.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ca.xtb
@@ -6,7 +6,7 @@
<translation id="10623998915015855">botó de commutació</translation>
<translation id="1088086359088493902">Segons</translation>
<translation id="1171774979989969504">Introduïu una adreça electrònica.</translation>
-<translation id="1178581264944972037">Pausa</translation>
+<translation id="1178581264944972037">Posa en pausa</translation>
<translation id="1188858454923323853">complementari</translation>
<translation id="1206619573307042055">marquee</translation>
<translation id="1206693055195146388">control lliscant</translation>
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Mostra el tauler de la selecció de mes</translation>
<translation id="6404546809543547843">barra de moment de l'àudio</translation>
<translation id="648732519525291180">selector d'hora</translation>
+<translation id="6550675742724504774">Opcions</translation>
<translation id="658823671542763450">visualitza en pantalla completa</translation>
<translation id="663493177488814956">El meu tauler</translation>
<translation id="6637586476836377253">registre</translation>
@@ -146,7 +147,7 @@
<translation id="7720026100085573005">temps restant</translation>
<translation id="7740016676195725605">deixa de mostrar subtítols ocults</translation>
<translation id="7740050170769002709">Contingut HTML</translation>
-<translation id="7789962463072032349">pausa</translation>
+<translation id="7789962463072032349">posa en pausa</translation>
<translation id="7802800022689234070">triangle desplegable</translation>
<translation id="7888071071722539607">Incloeu el símbol "<ph name="ATSIGN" />" a l'adreça electrònica. Al camp "<ph name="INVALIDADDRESS" />" falta el símbol "<ph name="ATSIGN" />".</translation>
<translation id="7891486169920085145">divisor</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Seleccioneu un fitxer.</translation>
<translation id="8461852803063341183">botó d'opció</translation>
<translation id="8511325616783751178">botó desplegable</translation>
-<translation id="8519420564908284378">Reprodueix a les dues pantalles</translation>
<translation id="8534579021159131403">Minuts</translation>
<translation id="8541249477527128034">control de mitjans</translation>
<translation id="8583702881314752957">llista de definicions</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_cs.xtb b/chromium/content/app/strings/translations/content_strings_cs.xtb
index b082b982fce..b716136b77d 100644
--- a/chromium/content/app/strings/translations/content_strings_cs.xtb
+++ b/chromium/content/app/strings/translations/content_strings_cs.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Zobrazit panel pro výběr měsíců</translation>
<translation id="6404546809543547843">posuvník času zvuku</translation>
<translation id="648732519525291180">výběr času</translation>
+<translation id="6550675742724504774">Možnosti</translation>
<translation id="658823671542763450">přejít do režimu celé obrazovky</translation>
<translation id="663493177488814956">zdroj</translation>
<translation id="6637586476836377253">protokol</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Vyberte prosím soubor.</translation>
<translation id="8461852803063341183">přepínač</translation>
<translation id="8511325616783751178">tlačítko rozbalovací nabídky</translation>
-<translation id="8519420564908284378">Přehrát na obou obrazovkách</translation>
<translation id="8534579021159131403">Minuty</translation>
<translation id="8541249477527128034">ovládání médií</translation>
<translation id="8583702881314752957">seznam definic</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_da.xtb b/chromium/content/app/strings/translations/content_strings_da.xtb
index ea76167a83d..62918b062f4 100644
--- a/chromium/content/app/strings/translations/content_strings_da.xtb
+++ b/chromium/content/app/strings/translations/content_strings_da.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Vis panel til valg af måned</translation>
<translation id="6404546809543547843">afspilningsbjælke for lyd</translation>
<translation id="648732519525291180">tidsvælger</translation>
+<translation id="6550675742724504774">Valgmuligheder</translation>
<translation id="658823671542763450">åbn fuld skærm</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Vælg en fil.</translation>
<translation id="8461852803063341183">alternativknap</translation>
<translation id="8511325616783751178">rullemenuknap</translation>
-<translation id="8519420564908284378">Afspil på begge skærme</translation>
<translation id="8534579021159131403">Minutter</translation>
<translation id="8541249477527128034">mediekontrol</translation>
<translation id="8583702881314752957">liste over definitioner</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_de.xtb b/chromium/content/app/strings/translations/content_strings_de.xtb
index 1bebd5463c9..a9e23be207e 100644
--- a/chromium/content/app/strings/translations/content_strings_de.xtb
+++ b/chromium/content/app/strings/translations/content_strings_de.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Auswahlbereich für Monatsanzeige</translation>
<translation id="6404546809543547843">Audio-Zeitachse</translation>
<translation id="648732519525291180">Uhrzeitauswahl</translation>
+<translation id="6550675742724504774">Optionen</translation>
<translation id="658823671542763450">Vollbildmodus aktivieren</translation>
<translation id="663493177488814956">Feed</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Wählen Sie eine Datei aus.</translation>
<translation id="8461852803063341183">Optionsfeld</translation>
<translation id="8511325616783751178">Drop-down-Schaltfläche</translation>
-<translation id="8519420564908284378">Auf beiden Bildschirmen wiedergeben</translation>
<translation id="8534579021159131403">Minuten</translation>
<translation id="8541249477527128034">Mediensteuerung</translation>
<translation id="8583702881314752957">Definitionsliste</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_el.xtb b/chromium/content/app/strings/translations/content_strings_el.xtb
index aa981ef011a..070ec20b8ae 100644
--- a/chromium/content/app/strings/translations/content_strings_el.xtb
+++ b/chromium/content/app/strings/translations/content_strings_el.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Εμφάνιση παραθύρου επιλογής μήνα</translation>
<translation id="6404546809543547843">δείκτης χρόνου ήχου</translation>
<translation id="648732519525291180">εργαλείο επιλογής ώρας</translation>
+<translation id="6550675742724504774">Επιλογές</translation>
<translation id="658823671542763450">ενεργοποίηση πλήρους οθόνης</translation>
<translation id="663493177488814956">ροή</translation>
<translation id="6637586476836377253">αρχείο καταγραφής</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Επιλέξτε ένα αρχείο.</translation>
<translation id="8461852803063341183">κουμπί επιλογής</translation>
<translation id="8511325616783751178">αναπτυσσόμενο κουμπί</translation>
-<translation id="8519420564908284378">Αναπαραγωγή και στις δύο οθόνες</translation>
<translation id="8534579021159131403">Λεπτά</translation>
<translation id="8541249477527128034">έλεγχος μέσων</translation>
<translation id="8583702881314752957">λίστα ορισμών</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 2070b4e523a..0f92f0526aa 100644
--- a/chromium/content/app/strings/translations/content_strings_en-GB.xtb
+++ b/chromium/content/app/strings/translations/content_strings_en-GB.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Show month selection panel</translation>
<translation id="6404546809543547843">audio time scrubber</translation>
<translation id="648732519525291180">time picker</translation>
+<translation id="6550675742724504774">Options</translation>
<translation id="658823671542763450">enter full screen</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Please select a file.</translation>
<translation id="8461852803063341183">radio button</translation>
<translation id="8511325616783751178">drop-down button</translation>
-<translation id="8519420564908284378">Play on both screens</translation>
<translation id="8534579021159131403">Minutes</translation>
<translation id="8541249477527128034">media control</translation>
<translation id="8583702881314752957">definition list</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 c4ae00aaa7a..bf8315ca41f 100644
--- a/chromium/content/app/strings/translations/content_strings_es-419.xtb
+++ b/chromium/content/app/strings/translations/content_strings_es-419.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Mostrar el panel de selección de meses</translation>
<translation id="6404546809543547843">control deslizante de duración del audio</translation>
<translation id="648732519525291180">selector de hora</translation>
+<translation id="6550675742724504774">Opciones</translation>
<translation id="658823671542763450">ingresar a pantalla completa</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">rgstr</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Selecciona un archivo.</translation>
<translation id="8461852803063341183">botón de selección</translation>
<translation id="8511325616783751178">botón desplegable</translation>
-<translation id="8519420564908284378">Reproducir en ambas pantallas</translation>
<translation id="8534579021159131403">Minutos</translation>
<translation id="8541249477527128034">control de medios</translation>
<translation id="8583702881314752957">lista de definiciones</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_es.xtb b/chromium/content/app/strings/translations/content_strings_es.xtb
index 10077278318..19de99fefe6 100644
--- a/chromium/content/app/strings/translations/content_strings_es.xtb
+++ b/chromium/content/app/strings/translations/content_strings_es.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Mostrar panel para seleccionar el mes</translation>
<translation id="6404546809543547843">control deslizante de duración de audio</translation>
<translation id="648732519525291180">selector de hora</translation>
+<translation id="6550675742724504774">Configuración</translation>
<translation id="658823671542763450">activar pantalla completa</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">registro</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Selecciona un archivo</translation>
<translation id="8461852803063341183">botón de selección</translation>
<translation id="8511325616783751178">botón desplegable</translation>
-<translation id="8519420564908284378">Reproducir en ambas pantallas</translation>
<translation id="8534579021159131403">Minutos</translation>
<translation id="8541249477527128034">control de medios</translation>
<translation id="8583702881314752957">lista de definiciones</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_et.xtb b/chromium/content/app/strings/translations/content_strings_et.xtb
index f747c0be2a1..2fb3286d6eb 100644
--- a/chromium/content/app/strings/translations/content_strings_et.xtb
+++ b/chromium/content/app/strings/translations/content_strings_et.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Kuu valikupaneeli kuvamine</translation>
<translation id="6404546809543547843">heli ajamõõdik</translation>
<translation id="648732519525291180">kellaaja valija</translation>
+<translation id="6550675742724504774">Valikud</translation>
<translation id="658823671542763450">kuvamine täisekraanil</translation>
<translation id="663493177488814956">voog</translation>
<translation id="6637586476836377253">logi</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Valige üks fail.</translation>
<translation id="8461852803063341183">raadionupp</translation>
<translation id="8511325616783751178">rippmenüü nupp</translation>
-<translation id="8519420564908284378">Esita mõlemal ekraanikuval</translation>
<translation id="8534579021159131403">Minutid</translation>
<translation id="8541249477527128034">meedia juhtimine</translation>
<translation id="8583702881314752957">definitsioonide loend</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_fa.xtb b/chromium/content/app/strings/translations/content_strings_fa.xtb
index 535a229207b..53ce1c3ba06 100644
--- a/chromium/content/app/strings/translations/content_strings_fa.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fa.xtb
@@ -5,7 +5,7 @@
<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,7 +16,7 @@
<translation id="1589122976691792535">منطقه</translation>
<translation id="1591562245178063882">این ماه</translation>
<translation id="1637811476055996098">انتخاب فایل‌ها</translation>
-<translation id="1729654308190250600">لطفاً یک آدرس رایانامه غیرخالی وارد کنید.</translation>
+<translation id="1729654308190250600">لطفاً یک نشانی رایانامه غیرخالی وارد کنید.</translation>
<translation id="1758486001363313524">موارد دیگر...</translation>
<translation id="1806710327868736751">alert_dialog</translation>
<translation id="1821985195704844674">شبکه درختی</translation>
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">نمایش پانل انتخاب ماه</translation>
<translation id="6404546809543547843">انتخابگر زمان صدا</translation>
<translation id="648732519525291180">انتخابگر زمان</translation>
+<translation id="6550675742724504774">گزینه‌ها</translation>
<translation id="658823671542763450">رفتن به حالت تمام صفحه</translation>
<translation id="663493177488814956">خبرمایه</translation>
<translation id="6637586476836377253">log</translation>
@@ -148,7 +149,7 @@
<translation id="7740050170769002709">‏محتوای HTML</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>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">لطفاً یک فایل انتخاب کنید.</translation>
<translation id="8461852803063341183">دکمه رادیو</translation>
<translation id="8511325616783751178">دکمه کرکره‌ای</translation>
-<translation id="8519420564908284378">پخش در هر دو صفحه‌نمایش</translation>
<translation id="8534579021159131403">دقیقه</translation>
<translation id="8541249477527128034">کنترل رسانه</translation>
<translation id="8583702881314752957">فهرست معنی‌ها</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_fi.xtb b/chromium/content/app/strings/translations/content_strings_fi.xtb
index a3fbbe239d3..8b928213ff1 100644
--- a/chromium/content/app/strings/translations/content_strings_fi.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fi.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Näytä kuukaudenvalintapaneeli</translation>
<translation id="6404546809543547843">äänen ajan liukusäädin</translation>
<translation id="648732519525291180">ajan valitsin</translation>
+<translation id="6550675742724504774">Asetukset</translation>
<translation id="658823671542763450">siirry koko näytön tilaan</translation>
<translation id="663493177488814956">fiidi</translation>
<translation id="6637586476836377253">loki</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Valitse tiedosto.</translation>
<translation id="8461852803063341183">valintapainike</translation>
<translation id="8511325616783751178">avattavan valikon painike</translation>
-<translation id="8519420564908284378">Toista molemmilla näytöillä</translation>
<translation id="8534579021159131403">Minuuttia</translation>
<translation id="8541249477527128034">median hallinta</translation>
<translation id="8583702881314752957">määritelmäluettelo</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_fil.xtb b/chromium/content/app/strings/translations/content_strings_fil.xtb
index b35173ea342..7557262050e 100644
--- a/chromium/content/app/strings/translations/content_strings_fil.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fil.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Ipakita ang panel ng pagpipilian ng buwan</translation>
<translation id="6404546809543547843">scrubber ng oras ng audio</translation>
<translation id="648732519525291180">picker ng petsa</translation>
+<translation id="6550675742724504774">Mga Pagpipilian</translation>
<translation id="658823671542763450">mag-full screen</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Mangyaring pumili ng file.</translation>
<translation id="8461852803063341183">radio button</translation>
<translation id="8511325616783751178">button ng drop-down</translation>
-<translation id="8519420564908284378">I-play sa parehong screen</translation>
<translation id="8534579021159131403">Minuto</translation>
<translation id="8541249477527128034">kontrol sa media</translation>
<translation id="8583702881314752957">listahan ng kahulugan</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_fr.xtb b/chromium/content/app/strings/translations/content_strings_fr.xtb
index ba0e9c2eda4..c5e602af9a3 100644
--- a/chromium/content/app/strings/translations/content_strings_fr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fr.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Afficher le panneau de sélection du mois</translation>
<translation id="6404546809543547843">curseur durée audio</translation>
<translation id="648732519525291180">outil de sélection de l'heure</translation>
+<translation id="6550675742724504774">Options</translation>
<translation id="658823671542763450">activer le mode plein écran</translation>
<translation id="663493177488814956">flux</translation>
<translation id="6637586476836377253">journal</translation>
@@ -138,7 +139,7 @@
<translation id="7223624360433298498">temps écoulé</translation>
<translation id="7263440858009898357">Sélectionnez un élément dans la liste.</translation>
<translation id="727747134524199931">en-tête de colonne</translation>
-<translation id="7364796246159120393">Choisissez un fichier</translation>
+<translation id="7364796246159120393">Choisir un fichier</translation>
<translation id="739024184232394898">Autre…</translation>
<translation id="7491962110804786152">tabulation</translation>
<translation id="7514365320538308">Télécharger</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Veuillez sélectionner un fichier.</translation>
<translation id="8461852803063341183">case d'option</translation>
<translation id="8511325616783751178">bouton déroulant</translation>
-<translation id="8519420564908284378">Jouer sur les deux écrans</translation>
<translation id="8534579021159131403">Minutes</translation>
<translation id="8541249477527128034">commande multimédia</translation>
<translation id="8583702881314752957">liste de définitions</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_gu.xtb b/chromium/content/app/strings/translations/content_strings_gu.xtb
index 793f878a4ba..21be160da73 100644
--- a/chromium/content/app/strings/translations/content_strings_gu.xtb
+++ b/chromium/content/app/strings/translations/content_strings_gu.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">મહિના પસંદગી પેનલ દર્શાવો</translation>
<translation id="6404546809543547843">ઑડિઓ સમય સ્ક્રબર</translation>
<translation id="648732519525291180">સમય પીકર</translation>
+<translation id="6550675742724504774">વિકલ્પો</translation>
<translation id="658823671542763450">પૂર્ણ સ્ક્રીનમાં દાખલ થાઓ</translation>
<translation id="663493177488814956">ફીડ</translation>
<translation id="6637586476836377253">લૉગ</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">કૃપા કરીને કોઈ ફાઇલ પસંદ કરો.</translation>
<translation id="8461852803063341183">રેડિઓ બટન</translation>
<translation id="8511325616783751178">ડ્રોપ ડાઉન બટન</translation>
-<translation id="8519420564908284378">બન્ને સ્ક્રીન પર ચલાવો</translation>
<translation id="8534579021159131403">મિનિટ</translation>
<translation id="8541249477527128034">મીડિયાનું નિયંત્રણ</translation>
<translation id="8583702881314752957">વિવરણ સૂચિ</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_hi.xtb b/chromium/content/app/strings/translations/content_strings_hi.xtb
index c8dc154c4bb..594b72a42dd 100644
--- a/chromium/content/app/strings/translations/content_strings_hi.xtb
+++ b/chromium/content/app/strings/translations/content_strings_hi.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">माह चयन फलक दिखाएं</translation>
<translation id="6404546809543547843">ऑडियो समय स्क्रबर</translation>
<translation id="648732519525291180">समय पिकर</translation>
+<translation id="6550675742724504774">विकल्प</translation>
<translation id="658823671542763450">पूर्ण स्क्रीन में प्रवेश करें</translation>
<translation id="663493177488814956">फ़ीड</translation>
<translation id="6637586476836377253">लॉग</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">कृपया किसी फ़ाइल को चुनें.</translation>
<translation id="8461852803063341183">रेडियो बटन</translation>
<translation id="8511325616783751178">ड्रॉप डाउन बटन</translation>
-<translation id="8519420564908284378">दोनों स्क्रीन पर चलाएं</translation>
<translation id="8534579021159131403">मिनट</translation>
<translation id="8541249477527128034">मीडिया नियंत्रण</translation>
<translation id="8583702881314752957">परिभाषा सूची</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_hr.xtb b/chromium/content/app/strings/translations/content_strings_hr.xtb
index d21e39be48e..9116c4f9dad 100644
--- a/chromium/content/app/strings/translations/content_strings_hr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_hr.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Prikaži ploču za odabir mjeseca</translation>
<translation id="6404546809543547843">klizač vremena audiozapisa</translation>
<translation id="648732519525291180">alat za odabir vremena</translation>
+<translation id="6550675742724504774">Opcije</translation>
<translation id="658823671542763450">otvaranje na cijelom zaslonu</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">zap</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Odaberite datoteku.</translation>
<translation id="8461852803063341183">izborni gumb</translation>
<translation id="8511325616783751178">gumb padajućeg izbornika</translation>
-<translation id="8519420564908284378">Reproduciraj na oba zaslona</translation>
<translation id="8534579021159131403">Minute</translation>
<translation id="8541249477527128034">kontrola medija</translation>
<translation id="8583702881314752957">popis definicija</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_hu.xtb b/chromium/content/app/strings/translations/content_strings_hu.xtb
index 569cc52462e..fddc1ec9771 100644
--- a/chromium/content/app/strings/translations/content_strings_hu.xtb
+++ b/chromium/content/app/strings/translations/content_strings_hu.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">A hónapválasztási panel megjelenítése</translation>
<translation id="6404546809543547843">hang idővonalának vezérlője</translation>
<translation id="648732519525291180">időválasztó</translation>
+<translation id="6550675742724504774">Beállítások</translation>
<translation id="658823671542763450">teljes képernyős nézet</translation>
<translation id="663493177488814956">hírcsatorna</translation>
<translation id="6637586476836377253">napló</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Válasszon egy fájlt.</translation>
<translation id="8461852803063341183">választógomb</translation>
<translation id="8511325616783751178">legördülő gomb</translation>
-<translation id="8519420564908284378">Lejátszás mindkét képernyőn</translation>
<translation id="8534579021159131403">Perc</translation>
<translation id="8541249477527128034">médiavezérlő</translation>
<translation id="8583702881314752957">definíciós lista</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_id.xtb b/chromium/content/app/strings/translations/content_strings_id.xtb
index 5e62458108f..943474f876b 100644
--- a/chromium/content/app/strings/translations/content_strings_id.xtb
+++ b/chromium/content/app/strings/translations/content_strings_id.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Tampilkan panel pilihan bulan</translation>
<translation id="6404546809543547843">scrubber waktu audio</translation>
<translation id="648732519525291180">pemilih waktu</translation>
+<translation id="6550675742724504774">Opsi</translation>
<translation id="658823671542763450">masuk layar penuh</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Pilih file.</translation>
<translation id="8461852803063341183">tombol radio</translation>
<translation id="8511325616783751178">tombol tarik-turun</translation>
-<translation id="8519420564908284378">Putar di kedua layar</translation>
<translation id="8534579021159131403">Menit</translation>
<translation id="8541249477527128034">kontrol media</translation>
<translation id="8583702881314752957">daftar definisi</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_it.xtb b/chromium/content/app/strings/translations/content_strings_it.xtb
index c56ad34c360..96851b7e6e7 100644
--- a/chromium/content/app/strings/translations/content_strings_it.xtb
+++ b/chromium/content/app/strings/translations/content_strings_it.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Mostra il riquadro di selezione del mese</translation>
<translation id="6404546809543547843">dispositivo di scorrimento durata audio</translation>
<translation id="648732519525291180">selettore di ora</translation>
+<translation id="6550675742724504774">Opzioni</translation>
<translation id="658823671542763450">passa a schermo intero</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Seleziona un file.</translation>
<translation id="8461852803063341183">pulsante di opzione</translation>
<translation id="8511325616783751178">pulsante a discesa</translation>
-<translation id="8519420564908284378">Riproduci su entrambi gli schermi</translation>
<translation id="8534579021159131403">Minuti</translation>
<translation id="8541249477527128034">controllo contenuti multimediali</translation>
<translation id="8583702881314752957">elenco di definizioni</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_iw.xtb b/chromium/content/app/strings/translations/content_strings_iw.xtb
index 212c68ff230..becd8dc30b6 100644
--- a/chromium/content/app/strings/translations/content_strings_iw.xtb
+++ b/chromium/content/app/strings/translations/content_strings_iw.xtb
@@ -85,7 +85,7 @@
<translation id="4757246831282535685">חלונית כרטיסיות</translation>
<translation id="4763480195061959176">סרטוני וידאו</translation>
<translation id="479989351350248267">Search</translation>
-<translation id="4812940957355064477">הזן מספר.</translation>
+<translation id="4812940957355064477">יש להזין מספר.</translation>
<translation id="4975562563186953947"><ph name="SELECTED_COUNT" /> נבחרו</translation>
<translation id="4992066212339426712">בטל השתקה</translation>
<translation id="49969490063480558">הזן חלק ולאחריו '<ph name="ATSIGN" />'‏. השדה '<ph name="INVALIDADDRESS" />' אינו מלא.</translation>
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">הצג חלונית לבחירת חודש</translation>
<translation id="6404546809543547843">מסתיר משך אודיו</translation>
<translation id="648732519525291180">בוחר שעות</translation>
+<translation id="6550675742724504774">אפשרויות</translation>
<translation id="658823671542763450">היכנס למסך מלא</translation>
<translation id="663493177488814956">פיד</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">בחר קובץ.</translation>
<translation id="8461852803063341183">לחצן בחירה</translation>
<translation id="8511325616783751178">לחצן רשימה נפתחת</translation>
-<translation id="8519420564908284378">הפעל בשני המסכים</translation>
<translation id="8534579021159131403">דקות</translation>
<translation id="8541249477527128034">שליטה במדיה</translation>
<translation id="8583702881314752957">רשימת הגדרות</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ja.xtb b/chromium/content/app/strings/translations/content_strings_ja.xtb
index e67a4ff1395..a2f90021db0 100644
--- a/chromium/content/app/strings/translations/content_strings_ja.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ja.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">月選択パネルを表示</translation>
<translation id="6404546809543547843">オーディオ再生バー</translation>
<translation id="648732519525291180">時間選択ツール</translation>
+<translation id="6550675742724504774">オプション</translation>
<translation id="658823671542763450">全画面表示</translation>
<translation id="663493177488814956">フィード</translation>
<translation id="6637586476836377253">ログ</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">ファイルを選択してください。</translation>
<translation id="8461852803063341183">ラジオボタン</translation>
<translation id="8511325616783751178">プルダウン ボタン</translation>
-<translation id="8519420564908284378">両方の画面で再生</translation>
<translation id="8534579021159131403">分</translation>
<translation id="8541249477527128034">メディア管理</translation>
<translation id="8583702881314752957">定義リスト</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_kn.xtb b/chromium/content/app/strings/translations/content_strings_kn.xtb
index a5e572f4704..c46de15cd13 100644
--- a/chromium/content/app/strings/translations/content_strings_kn.xtb
+++ b/chromium/content/app/strings/translations/content_strings_kn.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">ತಿಂಗಳ ಆಯ್ಕೆ ಪ್ಯಾನಲ್ ತೋರಿಸಿ</translation>
<translation id="6404546809543547843">ಆಡಿಯೊ ಸಮಯ ಸ್ಕ್ರಬ್ಬರ್</translation>
<translation id="648732519525291180">ಸಮಯ ಪಿಕರ್</translation>
+<translation id="6550675742724504774">ಆಯ್ಕೆಗಳು</translation>
<translation id="658823671542763450">ಪೂರ್ಣ ಪರದೆ ನಮೂದಿಸು</translation>
<translation id="663493177488814956">ಫೀಡ್‌</translation>
<translation id="6637586476836377253">ಲಾಗ್</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">ದಯವಿಟ್ಟು ಫೈಲ್ ಆಯ್ಕೆಮಾಡಿ.</translation>
<translation id="8461852803063341183">ರೇಡಿಯೋ ಬಟನ್</translation>
<translation id="8511325616783751178">ಡ್ರಾಪ್ ಡೌನ್ ಬಟನ್</translation>
-<translation id="8519420564908284378">ಎರಡೂ ಪರದೆಯ ಮೇಲೆ ಪ್ಲೇ ಮಾಡಿ</translation>
<translation id="8534579021159131403">ನಿಮಿಷಗಳು</translation>
<translation id="8541249477527128034">ಮಾಧ್ಯಮ ನಿಯಂತ್ರಣ</translation>
<translation id="8583702881314752957">ವಿವರಣೆ ಪಟ್ಟಿ</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ko.xtb b/chromium/content/app/strings/translations/content_strings_ko.xtb
index aade7d0173a..9b69237ae36 100644
--- a/chromium/content/app/strings/translations/content_strings_ko.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ko.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">월 선택 패널 표시</translation>
<translation id="6404546809543547843">오디오 시간 스크러버</translation>
<translation id="648732519525291180">시간 선택기</translation>
+<translation id="6550675742724504774">옵션</translation>
<translation id="658823671542763450">전체화면 열기</translation>
<translation id="663493177488814956">피드</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">파일을 선택하세요.</translation>
<translation id="8461852803063341183">라디오 버튼</translation>
<translation id="8511325616783751178">드롭다운 버튼</translation>
-<translation id="8519420564908284378">두 화면에서 재생</translation>
<translation id="8534579021159131403">분</translation>
<translation id="8541249477527128034">미디어 컨트롤</translation>
<translation id="8583702881314752957">정의 목록</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_lt.xtb b/chromium/content/app/strings/translations/content_strings_lt.xtb
index 4173da0e669..f287fa80b75 100644
--- a/chromium/content/app/strings/translations/content_strings_lt.xtb
+++ b/chromium/content/app/strings/translations/content_strings_lt.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Rodyti mėnesio pasirinkimo skydelį</translation>
<translation id="6404546809543547843">garso laiko valdiklis</translation>
<translation id="648732519525291180">laiko rinkiklis</translation>
+<translation id="6550675742724504774">Parinktys</translation>
<translation id="658823671542763450">įjungti viso ekrano režimą</translation>
<translation id="663493177488814956">sklaidos kanalas</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Pasirinkite failą.</translation>
<translation id="8461852803063341183">akutė</translation>
<translation id="8511325616783751178">išskleidžiamasis mygtukas</translation>
-<translation id="8519420564908284378">Leisti abiejuose ekranuose</translation>
<translation id="8534579021159131403">Minutės</translation>
<translation id="8541249477527128034">medijos valdiklis</translation>
<translation id="8583702881314752957">apibrėžimų sąrašas</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_lv.xtb b/chromium/content/app/strings/translations/content_strings_lv.xtb
index 281b26f217b..77f47080434 100644
--- a/chromium/content/app/strings/translations/content_strings_lv.xtb
+++ b/chromium/content/app/strings/translations/content_strings_lv.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Rādīt mēneša atlases paneli</translation>
<translation id="6404546809543547843">audio laika skalas slīdnis</translation>
<translation id="648732519525291180">laika atlasītājs</translation>
+<translation id="6550675742724504774">Opcijas</translation>
<translation id="658823671542763450">atvērt pilnekrāna režīmā</translation>
<translation id="663493177488814956">plūsma</translation>
<translation id="6637586476836377253">žurnāls</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Lūdzu, atlasiet failu.</translation>
<translation id="8461852803063341183">radiopoga</translation>
<translation id="8511325616783751178">nolaižamās izvēlnes poga</translation>
-<translation id="8519420564908284378">Atskaņot abos ekrānos</translation>
<translation id="8534579021159131403">Minūtes</translation>
<translation id="8541249477527128034">multivides vadība</translation>
<translation id="8583702881314752957">definīciju saraksts</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ml.xtb b/chromium/content/app/strings/translations/content_strings_ml.xtb
index 6325973eb42..9dc403e7370 100644
--- a/chromium/content/app/strings/translations/content_strings_ml.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ml.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">മാസം തിരഞ്ഞെടുക്കുന്ന പാനൽ കാണിക്കുക</translation>
<translation id="6404546809543547843">ഓഡിയോ സമയ സ്‌ക്രബർ</translation>
<translation id="648732519525291180">സമയ പിക്കർ</translation>
+<translation id="6550675742724504774">ഓപ്ഷനുകൾ</translation>
<translation id="658823671542763450">പൂർണ്ണ സ്‌ക്രീനിലേക്ക് പോവുക</translation>
<translation id="663493177488814956">ഫീഡ്</translation>
<translation id="6637586476836377253">ലോഗ്</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">ദയവായി ഒരു ഫയല്‍ തരം തിരഞ്ഞെടുക്കുക.</translation>
<translation id="8461852803063341183">റേഡിയോ ബട്ടൺ</translation>
<translation id="8511325616783751178">ഡ്രോപ്പ് ഡൗൺ ബട്ടൺ</translation>
-<translation id="8519420564908284378">രണ്ട് സ്‌ക്രീനുകളിലും പ്ലേ ചെയ്യുക</translation>
<translation id="8534579021159131403">മിനിറ്റ്</translation>
<translation id="8541249477527128034">മീഡിയ നിയന്ത്രണം</translation>
<translation id="8583702881314752957">നിർവചന ലിസ്റ്റ്</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_mr.xtb b/chromium/content/app/strings/translations/content_strings_mr.xtb
index adcefef7875..47e139d0bb4 100644
--- a/chromium/content/app/strings/translations/content_strings_mr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_mr.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">महिना निवड पॅनेल दर्शवा</translation>
<translation id="6404546809543547843">ऑडिओ वेळ स्क्रबर</translation>
<translation id="648732519525291180">वेळ निवडक</translation>
+<translation id="6550675742724504774">पर्याय</translation>
<translation id="658823671542763450">पूर्ण स्क्रीन एंटर करा</translation>
<translation id="663493177488814956">फीड</translation>
<translation id="6637586476836377253">लॉग</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">कृपया एखादी फाइल निवडा.</translation>
<translation id="8461852803063341183">रेडिओ बटण</translation>
<translation id="8511325616783751178">ड्रॉप डाउन बटण</translation>
-<translation id="8519420564908284378">दोन्ही स्क्रीनवर प्ले करा</translation>
<translation id="8534579021159131403">मिनिटे</translation>
<translation id="8541249477527128034">माध्यम नियंत्रण</translation>
<translation id="8583702881314752957">परिभाषा सूची</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ms.xtb b/chromium/content/app/strings/translations/content_strings_ms.xtb
index 0b1a49caf7b..196ce6b0d53 100644
--- a/chromium/content/app/strings/translations/content_strings_ms.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ms.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Tunjukkan panel pilihan bulan</translation>
<translation id="6404546809543547843">pembersih masa audio</translation>
<translation id="648732519525291180">pemilih masa</translation>
+<translation id="6550675742724504774">Pilihan</translation>
<translation id="658823671542763450">memasuki skrin penuh</translation>
<translation id="663493177488814956">suapan</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Sila pilih fail.</translation>
<translation id="8461852803063341183">butang radio</translation>
<translation id="8511325616783751178">butang lungsur</translation>
-<translation id="8519420564908284378">Main pada kedua-dua skrin</translation>
<translation id="8534579021159131403">Minit</translation>
<translation id="8541249477527128034">kawalan media</translation>
<translation id="8583702881314752957">senarai takrif</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_nl.xtb b/chromium/content/app/strings/translations/content_strings_nl.xtb
index 0cc3740025c..80b0f63a5b7 100644
--- a/chromium/content/app/strings/translations/content_strings_nl.xtb
+++ b/chromium/content/app/strings/translations/content_strings_nl.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Deelvenster voor maandselectie weergeven</translation>
<translation id="6404546809543547843">scrollbar met audiotijd</translation>
<translation id="648732519525291180">tijdkiezer</translation>
+<translation id="6550675742724504774">Opties</translation>
<translation id="658823671542763450">volledig scherm openen</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">logboek</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Selecteer een bestand.</translation>
<translation id="8461852803063341183">keuzerondje</translation>
<translation id="8511325616783751178">dropdown-knop</translation>
-<translation id="8519420564908284378">Afspelen op beide schermen</translation>
<translation id="8534579021159131403">Minuten</translation>
<translation id="8541249477527128034">mediacontrole</translation>
<translation id="8583702881314752957">definitielijst</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_no.xtb b/chromium/content/app/strings/translations/content_strings_no.xtb
index 2d2febe514a..08d9ff43f24 100644
--- a/chromium/content/app/strings/translations/content_strings_no.xtb
+++ b/chromium/content/app/strings/translations/content_strings_no.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Se panelet for valg av måned</translation>
<translation id="6404546809543547843">lydtidslinje</translation>
<translation id="648732519525291180">klokkeslettvelger</translation>
+<translation id="6550675742724504774">Alternativer</translation>
<translation id="658823671542763450">gå til fullskjermmodus</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">logg</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Velg en fil.</translation>
<translation id="8461852803063341183">alternativknapp</translation>
<translation id="8511325616783751178">rullegardinknapp</translation>
-<translation id="8519420564908284378">Spill av på begge skjermene</translation>
<translation id="8534579021159131403">Minutter</translation>
<translation id="8541249477527128034">mediekontroll</translation>
<translation id="8583702881314752957">definisjonsliste</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_pl.xtb b/chromium/content/app/strings/translations/content_strings_pl.xtb
index 5a9e2f03d92..8bde320e61a 100644
--- a/chromium/content/app/strings/translations/content_strings_pl.xtb
+++ b/chromium/content/app/strings/translations/content_strings_pl.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Pokaż panel wyboru miesiąca</translation>
<translation id="6404546809543547843">pasek czasu odtwarzania dźwięku</translation>
<translation id="648732519525291180">selektor godziny</translation>
+<translation id="6550675742724504774">Opcje</translation>
<translation id="658823671542763450">przejdź do pełnego ekranu</translation>
<translation id="663493177488814956">kanał</translation>
<translation id="6637586476836377253">dziennik</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Wybierz plik.</translation>
<translation id="8461852803063341183">przycisk opcji</translation>
<translation id="8511325616783751178">przycisk listy</translation>
-<translation id="8519420564908284378">Graj na obu ekranach</translation>
<translation id="8534579021159131403">Minuty</translation>
<translation id="8541249477527128034">sterowanie multimediami</translation>
<translation id="8583702881314752957">lista definicji</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 54ed7d02c11..531555141ba 100644
--- a/chromium/content/app/strings/translations/content_strings_pt-BR.xtb
+++ b/chromium/content/app/strings/translations/content_strings_pt-BR.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Mostrar painel de seleção de mês</translation>
<translation id="6404546809543547843">barra de progressão do áudio</translation>
<translation id="648732519525291180">seletor de hora</translation>
+<translation id="6550675742724504774">Opções</translation>
<translation id="658823671542763450">entrar no modo tela cheia</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Selecione um arquivo.</translation>
<translation id="8461852803063341183">botão de opção</translation>
<translation id="8511325616783751178">botão suspenso</translation>
-<translation id="8519420564908284378">Reproduzir nas duas telas</translation>
<translation id="8534579021159131403">Minutos</translation>
<translation id="8541249477527128034">controle de mídia</translation>
<translation id="8583702881314752957">lista de definições</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 73666eb5121..222cfbf2608 100644
--- a/chromium/content/app/strings/translations/content_strings_pt-PT.xtb
+++ b/chromium/content/app/strings/translations/content_strings_pt-PT.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Mostrar painel de seleção do mês</translation>
<translation id="6404546809543547843">controlo de arrasto do tempo do áudio</translation>
<translation id="648732519525291180">selecionador de hora</translation>
+<translation id="6550675742724504774">Opções</translation>
<translation id="658823671542763450">entrar no modo de ecrã inteiro</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Seleccione um ficheiro.</translation>
<translation id="8461852803063341183">botão de opção</translation>
<translation id="8511325616783751178">botão pendente</translation>
-<translation id="8519420564908284378">Reproduzir em ambos os ecrãs</translation>
<translation id="8534579021159131403">Minutos</translation>
<translation id="8541249477527128034">controlo multimédia</translation>
<translation id="8583702881314752957">lista de definições</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ro.xtb b/chromium/content/app/strings/translations/content_strings_ro.xtb
index e575d215dd5..43057d5fd97 100644
--- a/chromium/content/app/strings/translations/content_strings_ro.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ro.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Afișează panoul de selectare a lunii</translation>
<translation id="6404546809543547843">glisor redare audio</translation>
<translation id="648732519525291180">selector oră</translation>
+<translation id="6550675742724504774">Opțiuni</translation>
<translation id="658823671542763450">deschideți în ecran complet</translation>
<translation id="663493177488814956">feed</translation>
<translation id="6637586476836377253">jurnal</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Selectează un fișier.</translation>
<translation id="8461852803063341183">buton radio</translation>
<translation id="8511325616783751178">buton drop-down</translation>
-<translation id="8519420564908284378">Redă pe ambele ecrane</translation>
<translation id="8534579021159131403">Minute</translation>
<translation id="8541249477527128034">comandă media</translation>
<translation id="8583702881314752957">listă de definiții</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ru.xtb b/chromium/content/app/strings/translations/content_strings_ru.xtb
index 236149ef2eb..0b6634049aa 100644
--- a/chromium/content/app/strings/translations/content_strings_ru.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ru.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Показать панель выбора месяца</translation>
<translation id="6404546809543547843">полоса воспроизведения</translation>
<translation id="648732519525291180">окно выбора даты</translation>
+<translation id="6550675742724504774">Параметры</translation>
<translation id="658823671542763450">полноэкранный режим</translation>
<translation id="663493177488814956">лента</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Выберите файл.</translation>
<translation id="8461852803063341183">переключатель</translation>
<translation id="8511325616783751178">кнопка раскрывающегося меню</translation>
-<translation id="8519420564908284378">Воспроизвести на обоих экранах</translation>
<translation id="8534579021159131403">Минуты</translation>
<translation id="8541249477527128034">управление мультимедиа</translation>
<translation id="8583702881314752957">список описаний</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_sk.xtb b/chromium/content/app/strings/translations/content_strings_sk.xtb
index 58d7b011028..8e718b43b4d 100644
--- a/chromium/content/app/strings/translations/content_strings_sk.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sk.xtb
@@ -74,7 +74,7 @@
<translation id="4151657705144244502">grafika</translation>
<translation id="4201051445878709314">Zobraziť predchádzajúci mesiac</translation>
<translation id="421884353938374759">výber farieb</translation>
-<translation id="4248100235867064564">panel ponuky</translation>
+<translation id="4248100235867064564">panel s ponukami</translation>
<translation id="4254339807215791271">informácie o obsahu</translation>
<translation id="4360991593054037559">Zadajte platnú hodnotu. Najbližšie platné hodnoty sú <ph name="VALID_VALUE_LOW" /> a <ph name="VALID_VALUE_HIGHER" />.</translation>
<translation id="4413860115965805769">tlačidlo ponuky</translation>
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Zobraziť panel na výber mesiaca</translation>
<translation id="6404546809543547843">posúvač časovej osi zvuku</translation>
<translation id="648732519525291180">výber času</translation>
+<translation id="6550675742724504774">Možnosti</translation>
<translation id="658823671542763450">prejsť do režimu celej obrazovky</translation>
<translation id="663493177488814956">informačný kanál</translation>
<translation id="6637586476836377253">denník</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Vyberte súbor.</translation>
<translation id="8461852803063341183">prepínač</translation>
<translation id="8511325616783751178">tlačidlo rozbaľovacej ponuky</translation>
-<translation id="8519420564908284378">Prehrať na oboch obrazovkách</translation>
<translation id="8534579021159131403">Minúty</translation>
<translation id="8541249477527128034">ovládanie médií</translation>
<translation id="8583702881314752957">zoznam definícií</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_sl.xtb b/chromium/content/app/strings/translations/content_strings_sl.xtb
index 9e7dc67b0bf..c95f25b119e 100644
--- a/chromium/content/app/strings/translations/content_strings_sl.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sl.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Prikaz podokna za izbiro meseca</translation>
<translation id="6404546809543547843">časovni krmilnik za predvajanje zvoka</translation>
<translation id="648732519525291180">izbirnik ure</translation>
+<translation id="6550675742724504774">Možnosti</translation>
<translation id="658823671542763450">prehod v celozaslonski način</translation>
<translation id="663493177488814956">vir</translation>
<translation id="6637586476836377253">dnevn</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Izberite datoteko.</translation>
<translation id="8461852803063341183">izbirni gumb</translation>
<translation id="8511325616783751178">spustni gumb</translation>
-<translation id="8519420564908284378">Predvajaj na obeh zaslonih</translation>
<translation id="8534579021159131403">Minute</translation>
<translation id="8541249477527128034">nadziranje predstavnosti</translation>
<translation id="8583702881314752957">seznam opredelitev</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_sr.xtb b/chromium/content/app/strings/translations/content_strings_sr.xtb
index f4af6541568..2824ce6da81 100644
--- a/chromium/content/app/strings/translations/content_strings_sr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sr.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Прикажи таблу за избор месеца</translation>
<translation id="6404546809543547843">клизач за трајање аудио-садржаја</translation>
<translation id="648732519525291180">бирач времена</translation>
+<translation id="6550675742724504774">Опције</translation>
<translation id="658823671542763450">пређите на режим целог екрана</translation>
<translation id="663493177488814956">фид</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Изаберите датотеку.</translation>
<translation id="8461852803063341183">дугме за избор</translation>
<translation id="8511325616783751178">дугме за падајући мени</translation>
-<translation id="8519420564908284378">Пусти на оба екрана</translation>
<translation id="8534579021159131403">Минути</translation>
<translation id="8541249477527128034">контрола за медије</translation>
<translation id="8583702881314752957">листа дефиниција</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_sv.xtb b/chromium/content/app/strings/translations/content_strings_sv.xtb
index 546bfd64718..808c804c251 100644
--- a/chromium/content/app/strings/translations/content_strings_sv.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sv.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Visa panelen för val av månad</translation>
<translation id="6404546809543547843">tidsreglage för ljud</translation>
<translation id="648732519525291180">tidsväljare</translation>
+<translation id="6550675742724504774">Alternativ</translation>
<translation id="658823671542763450">visa i helskärm</translation>
<translation id="663493177488814956">flöde</translation>
<translation id="6637586476836377253">logg</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Välj en fil.</translation>
<translation id="8461852803063341183">alternativknapp</translation>
<translation id="8511325616783751178">rullgardinsknapp</translation>
-<translation id="8519420564908284378">Spela upp på båda skärmarna</translation>
<translation id="8534579021159131403">Minuter</translation>
<translation id="8541249477527128034">mediekontroll</translation>
<translation id="8583702881314752957">definitionslista</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_sw.xtb b/chromium/content/app/strings/translations/content_strings_sw.xtb
index 7d4c44dacba..22debd9c10f 100644
--- a/chromium/content/app/strings/translations/content_strings_sw.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sw.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Onyesha kisanduku cha uchaguzi wa mwezi</translation>
<translation id="6404546809543547843">kitelezi cha muda cha sauti</translation>
<translation id="648732519525291180">Kiteua wakati</translation>
+<translation id="6550675742724504774">Chaguo</translation>
<translation id="658823671542763450">ingia skrini kamili</translation>
<translation id="663493177488814956">mipasho</translation>
<translation id="6637586476836377253">kumbukumbu</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Tafadhali chagua faili.</translation>
<translation id="8461852803063341183">kitufe cha mviringo</translation>
<translation id="8511325616783751178">kitufe kunjuzi</translation>
-<translation id="8519420564908284378">Cheza kwenye skrini zote mbili</translation>
<translation id="8534579021159131403">Dakika</translation>
<translation id="8541249477527128034">udhibiti wa vyombo vya habari</translation>
<translation id="8583702881314752957">orodha ya ufafanuzi</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ta.xtb b/chromium/content/app/strings/translations/content_strings_ta.xtb
index f93c9f3d4a1..6541df9436e 100644
--- a/chromium/content/app/strings/translations/content_strings_ta.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ta.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">மாதம் தேர்ந்தெடுப்புப் பலகத்தைக் காட்டு</translation>
<translation id="6404546809543547843">ஆடியோ நேர ஸ்கிரப்பர்</translation>
<translation id="648732519525291180">நேரம் தேர்ந்தெடுப்பான்</translation>
+<translation id="6550675742724504774">விருப்பத்தேர்வுகள்</translation>
<translation id="658823671542763450">முழுத்திரைக்குச் செல்</translation>
<translation id="663493177488814956">ஊட்டம்</translation>
<translation id="6637586476836377253">பதிவு</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">ஒரு கோப்பை தேர்ந்தெடுக்கவும்.</translation>
<translation id="8461852803063341183">ரேடியோ பொத்தான்</translation>
<translation id="8511325616783751178">கீழ் தோன்றுதல் மெனு</translation>
-<translation id="8519420564908284378">இரண்டு திரைகளிலும் இயக்கு</translation>
<translation id="8534579021159131403">நிமிடங்கள்</translation>
<translation id="8541249477527128034">மீடியா கட்டுப்பாடு</translation>
<translation id="8583702881314752957">விளக்கப் பட்டியல்</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_te.xtb b/chromium/content/app/strings/translations/content_strings_te.xtb
index e3e820b1d21..4f6d48d74ea 100644
--- a/chromium/content/app/strings/translations/content_strings_te.xtb
+++ b/chromium/content/app/strings/translations/content_strings_te.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">నెల ఎంపిక ప్యానెల్‌ను చూపుతుంది</translation>
<translation id="6404546809543547843">ఆడియో సమయ స్క్రబ్బర్</translation>
<translation id="648732519525291180">సమయం ఎంపిక</translation>
+<translation id="6550675742724504774">ఎంపికలు</translation>
<translation id="658823671542763450">పూర్తి స్క్రీన్‌లోకి ప్రవేశించు</translation>
<translation id="663493177488814956">ఫీడ్</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">దయచేసి ఒక ఫైల్‌ని ఎంచుకోండి.</translation>
<translation id="8461852803063341183">రేడియో బటన్</translation>
<translation id="8511325616783751178">డ్రాప్ డౌన్ బటన్</translation>
-<translation id="8519420564908284378">రెండు స్క్రీన్‌లలో ప్లే చేయి</translation>
<translation id="8534579021159131403">నిమిషాలు</translation>
<translation id="8541249477527128034">మీడియా నియంత్రణ</translation>
<translation id="8583702881314752957">నిర్వచన జాబితా</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_th.xtb b/chromium/content/app/strings/translations/content_strings_th.xtb
index 9ab965ca012..b3eaeb486d6 100644
--- a/chromium/content/app/strings/translations/content_strings_th.xtb
+++ b/chromium/content/app/strings/translations/content_strings_th.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">แสดงแผงการเลือกเดือน</translation>
<translation id="6404546809543547843">ตัวควบคุมเวลาของเสียง</translation>
<translation id="648732519525291180">เครื่องมือเลือกเวลา</translation>
+<translation id="6550675742724504774">ตัวเลือก</translation>
<translation id="658823671542763450">เข้าสู่โหมดเต็มหน้าจอ</translation>
<translation id="663493177488814956">ฟีด</translation>
<translation id="6637586476836377253">บันทึก</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">โปรดเลือกไฟล์</translation>
<translation id="8461852803063341183">ปุ่มตัวเลือก</translation>
<translation id="8511325616783751178">ปุ่มแบบเลื่อนลง</translation>
-<translation id="8519420564908284378">เล่นในทั้งสองหน้าจอ</translation>
<translation id="8534579021159131403">นาที</translation>
<translation id="8541249477527128034">การควบคุมสื่อ</translation>
<translation id="8583702881314752957">รายการคำจำกัดความ</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_tr.xtb b/chromium/content/app/strings/translations/content_strings_tr.xtb
index 9040e2047dd..ee316f59c84 100644
--- a/chromium/content/app/strings/translations/content_strings_tr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_tr.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Ay seçim panelini göster</translation>
<translation id="6404546809543547843">ses zaman çizelgesi temizleyici</translation>
<translation id="648732519525291180">zaman seçici</translation>
+<translation id="6550675742724504774">Seçenekler</translation>
<translation id="658823671542763450">tam ekrana geç</translation>
<translation id="663493177488814956">kartlar</translation>
<translation id="6637586476836377253">log</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Lütfen bir dosya seçin.</translation>
<translation id="8461852803063341183">radyo düğmesi</translation>
<translation id="8511325616783751178">açılır liste düğmesi</translation>
-<translation id="8519420564908284378">Her iki ekranda oynat</translation>
<translation id="8534579021159131403">Dakika</translation>
<translation id="8541249477527128034">medya kontrolü</translation>
<translation id="8583702881314752957">tanım listesi</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_uk.xtb b/chromium/content/app/strings/translations/content_strings_uk.xtb
index 64461a4bfed..1b7fe267755 100644
--- a/chromium/content/app/strings/translations/content_strings_uk.xtb
+++ b/chromium/content/app/strings/translations/content_strings_uk.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Показати панель вибору місяців</translation>
<translation id="6404546809543547843">повзунок часу відтворення аудіо</translation>
<translation id="648732519525291180">засіб вибору часу</translation>
+<translation id="6550675742724504774">Параметри</translation>
<translation id="658823671542763450">увійти в повноекранний режим</translation>
<translation id="663493177488814956">стрічка</translation>
<translation id="6637586476836377253">журнал</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Виберіть файл.</translation>
<translation id="8461852803063341183">перемикач</translation>
<translation id="8511325616783751178">кнопка спадного меню</translation>
-<translation id="8519420564908284378">Відтворити на обох екранах</translation>
<translation id="8534579021159131403">Хвилини</translation>
<translation id="8541249477527128034">елемент керування мультимедіа</translation>
<translation id="8583702881314752957">список визначень</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_vi.xtb b/chromium/content/app/strings/translations/content_strings_vi.xtb
index 793e59b6c41..9e06281183b 100644
--- a/chromium/content/app/strings/translations/content_strings_vi.xtb
+++ b/chromium/content/app/strings/translations/content_strings_vi.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">Hiển thị bảng lựa chọn tháng</translation>
<translation id="6404546809543547843">trình kiểm soát thời gian âm thanh</translation>
<translation id="648732519525291180">bộ chọn giờ</translation>
+<translation id="6550675742724504774">Tùy chọn</translation>
<translation id="658823671542763450">vào chế độ toàn màn hình</translation>
<translation id="663493177488814956">nguồn cấp dữ liệu</translation>
<translation id="6637586476836377253">nhật ký</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">Vui lòng chọn một tệp.</translation>
<translation id="8461852803063341183">nút radio</translation>
<translation id="8511325616783751178">nút thả xuống</translation>
-<translation id="8519420564908284378">Phát trên cả hai màn hình</translation>
<translation id="8534579021159131403">Phút</translation>
<translation id="8541249477527128034">kiểm soát phương tiện</translation>
<translation id="8583702881314752957">danh sách định nghĩa</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 b56701ed856..99fd0dd7357 100644
--- a/chromium/content/app/strings/translations/content_strings_zh-CN.xtb
+++ b/chromium/content/app/strings/translations/content_strings_zh-CN.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">显示月份选择面板</translation>
<translation id="6404546809543547843">音频时间进度条</translation>
<translation id="648732519525291180">时间选择器</translation>
+<translation id="6550675742724504774">选项</translation>
<translation id="658823671542763450">进入全屏模式</translation>
<translation id="663493177488814956">Feed</translation>
<translation id="6637586476836377253">日志</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">请选择一个文件。</translation>
<translation id="8461852803063341183">单选按钮</translation>
<translation id="8511325616783751178">下拉式按钮</translation>
-<translation id="8519420564908284378">同时在两个屏幕上播放</translation>
<translation id="8534579021159131403">分钟</translation>
<translation id="8541249477527128034">媒体控件</translation>
<translation id="8583702881314752957">定义列表</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 01ec1d3b048..2a44aa8060d 100644
--- a/chromium/content/app/strings/translations/content_strings_zh-TW.xtb
+++ b/chromium/content/app/strings/translations/content_strings_zh-TW.xtb
@@ -119,6 +119,7 @@
<translation id="6398862346408813489">顯示月份選取面板</translation>
<translation id="6404546809543547843">音訊時間點拖曳工具</translation>
<translation id="648732519525291180">時間選擇器</translation>
+<translation id="6550675742724504774">選項</translation>
<translation id="658823671542763450">進入全螢幕</translation>
<translation id="663493177488814956">資訊提供</translation>
<translation id="6637586476836377253">紀錄</translation>
@@ -163,7 +164,6 @@
<translation id="8451268428117625855">請選取檔案。</translation>
<translation id="8461852803063341183">圓形按鈕</translation>
<translation id="8511325616783751178">下拉式清單按鈕</translation>
-<translation id="8519420564908284378">在兩個螢幕上播放</translation>
<translation id="8534579021159131403">分鐘</translation>
<translation id="8541249477527128034">媒體控制</translation>
<translation id="8583702881314752957">定義清單</translation>
diff --git a/chromium/content/browser/BUILD.gn b/chromium/content/browser/BUILD.gn
index 442baeee39e..7717c05cfb2 100644
--- a/chromium/content/browser/BUILD.gn
+++ b/chromium/content/browser/BUILD.gn
@@ -4,6 +4,7 @@
import("//build/buildflag_header.gni")
import("//build/config/features.gni")
+import("//build/config/jumbo.gni")
import("//build/config/linux/pangocairo/pangocairo.gni")
import("//build/config/ui.gni")
import("//gpu/vulkan/features.gni")
@@ -13,7 +14,7 @@ import("//printing/features/features.gni")
import("//third_party/WebKit/public/public_features.gni")
import("//tools/ipc_fuzzer/ipc_fuzzer.gni")
-source_set("browser") {
+jumbo_source_set("browser") {
# Only the public target should depend on this. All other targets (even
# internal content ones) should depend on the public one.
visibility = [
@@ -40,6 +41,7 @@ source_set("browser") {
"//cc/paint",
"//components/discardable_memory/common",
"//components/discardable_memory/service",
+ "//components/download/downloader/in_progress",
"//components/filesystem:lib",
"//components/leveldb:lib",
"//components/link_header_util",
@@ -79,23 +81,26 @@ source_set("browser") {
"//device/bluetooth",
"//device/gamepad",
"//device/geolocation",
+ "//device/geolocation/public/cpp",
"//device/geolocation/public/interfaces",
"//device/screen_orientation/public/interfaces",
+ "//device/u2f",
"//device/vr:mojo_bindings",
"//google_apis",
"//gpu",
"//gpu/command_buffer/client:gles2_implementation",
"//gpu/command_buffer/client:gles2_interface",
+ "//gpu/ipc/common:gpu_preferences_util",
"//gpu/ipc/host",
"//gpu/vulkan:features",
"//media",
"//media:media_features",
"//media/capture",
"//media/capture/mojo:image_capture",
- "//media/gpu/ipc/client",
"//media/midi",
"//media/midi:mojo",
"//media/mojo:features",
+ "//media/mojo/clients:jpeg_decode_accelerator",
"//media/mojo/interfaces",
"//media/mojo/interfaces:constants",
"//media/mojo/services",
@@ -103,6 +108,7 @@ source_set("browser") {
"//mojo/edk/system",
"//mojo/public/cpp/bindings",
"//mojo/public/js",
+ "//mojo/public/js:resources",
"//net",
"//net:extras",
"//net:http_server",
@@ -133,17 +139,19 @@ source_set("browser") {
"//services/service_manager/runner/host:lib",
"//services/shape_detection:lib",
"//services/shape_detection/public/interfaces",
- "//services/ui/gpu/interfaces",
"//services/ui/public/cpp/gpu",
"//services/video_capture/public/cpp",
"//services/video_capture/public/interfaces:constants",
"//services/video_capture/public/uma",
+ "//services/viz/privileged/interfaces",
+ "//services/viz/public/interfaces",
"//skia",
"//sql",
"//storage/browser",
"//storage/common",
"//third_party/WebKit/common:blink_common",
"//third_party/WebKit/public:blink_headers",
+ "//third_party/WebKit/public:core_mojo_bindings",
"//third_party/WebKit/public:features",
"//third_party/WebKit/public:mojo_bindings",
"//third_party/WebKit/public:resources",
@@ -159,6 +167,7 @@ source_set("browser") {
"//ui/accessibility",
"//ui/accessibility:ax_gen",
"//ui/base",
+ "//ui/base:ui_features",
"//ui/base/ime",
"//ui/display",
"//ui/display/types",
@@ -185,6 +194,7 @@ source_set("browser") {
":accessibility_flags",
"//ipc",
"//media/mojo/interfaces:remoting",
+ "//third_party/WebKit/public:media_devices_mojo_bindings",
"//third_party/WebKit/public:offscreen_canvas_mojo_bindings",
"//third_party/leveldatabase",
]
@@ -248,18 +258,12 @@ source_set("browser") {
"accessibility/accessibility_tree_formatter_win.cc",
"accessibility/accessibility_ui.cc",
"accessibility/accessibility_ui.h",
- "accessibility/ax_platform_position.cc",
- "accessibility/ax_platform_position.h",
"accessibility/browser_accessibility.cc",
"accessibility/browser_accessibility.h",
"accessibility/browser_accessibility_cocoa.h",
"accessibility/browser_accessibility_cocoa.mm",
"accessibility/browser_accessibility_com_win.cc",
"accessibility/browser_accessibility_com_win.h",
- "accessibility/browser_accessibility_event.cc",
- "accessibility/browser_accessibility_event.h",
- "accessibility/browser_accessibility_event_win.cc",
- "accessibility/browser_accessibility_event_win.h",
"accessibility/browser_accessibility_mac.h",
"accessibility/browser_accessibility_mac.mm",
"accessibility/browser_accessibility_manager.cc",
@@ -268,6 +272,8 @@ source_set("browser") {
"accessibility/browser_accessibility_manager_mac.mm",
"accessibility/browser_accessibility_manager_win.cc",
"accessibility/browser_accessibility_manager_win.h",
+ "accessibility/browser_accessibility_position.cc",
+ "accessibility/browser_accessibility_position.h",
"accessibility/browser_accessibility_state_impl.cc",
"accessibility/browser_accessibility_state_impl.h",
"accessibility/browser_accessibility_state_impl_mac.mm",
@@ -324,7 +330,6 @@ source_set("browser") {
"appcache/appcache_dispatcher_host.cc",
"appcache/appcache_dispatcher_host.h",
"appcache/appcache_entry.h",
- "appcache/appcache_executable_handler.h",
"appcache/appcache_frontend_proxy.cc",
"appcache/appcache_frontend_proxy.h",
"appcache/appcache_group.cc",
@@ -402,8 +407,25 @@ source_set("browser") {
"background_fetch/background_fetch_registration_notifier.h",
"background_fetch/background_fetch_request_info.cc",
"background_fetch/background_fetch_request_info.h",
+ "background_fetch/background_fetch_request_manager.h",
"background_fetch/background_fetch_service_impl.cc",
"background_fetch/background_fetch_service_impl.h",
+ "background_fetch/storage/cleanup_task.cc",
+ "background_fetch/storage/cleanup_task.h",
+ "background_fetch/storage/create_registration_task.cc",
+ "background_fetch/storage/create_registration_task.h",
+ "background_fetch/storage/database_helpers.cc",
+ "background_fetch/storage/database_helpers.h",
+ "background_fetch/storage/database_task.cc",
+ "background_fetch/storage/database_task.h",
+ "background_fetch/storage/delete_registration_task.cc",
+ "background_fetch/storage/delete_registration_task.h",
+ "background_fetch/storage/get_developer_ids_task.cc",
+ "background_fetch/storage/get_developer_ids_task.h",
+ "background_fetch/storage/get_registration_task.cc",
+ "background_fetch/storage/get_registration_task.h",
+ "background_fetch/storage/mark_registration_for_deletion_task.cc",
+ "background_fetch/storage/mark_registration_for_deletion_task.h",
"background_sync/background_sync_context.cc",
"background_sync/background_sync_context.h",
"background_sync/background_sync_manager.cc",
@@ -531,6 +553,8 @@ source_set("browser") {
# needed on all platforms.
"compositor/surface_utils.cc",
"compositor/surface_utils.h",
+ "dedicated_worker/dedicated_worker_host.cc",
+ "dedicated_worker/dedicated_worker_host.h",
"devtools/browser_devtools_agent_host.cc",
"devtools/browser_devtools_agent_host.h",
"devtools/devtools_agent_host_impl.cc",
@@ -539,13 +563,19 @@ source_set("browser") {
"devtools/devtools_frame_trace_recorder.h",
"devtools/devtools_http_handler.cc",
"devtools/devtools_http_handler.h",
+ "devtools/devtools_interceptor_controller.cc",
+ "devtools/devtools_interceptor_controller.h",
"devtools/devtools_io_context.cc",
"devtools/devtools_io_context.h",
"devtools/devtools_manager.cc",
"devtools/devtools_manager.h",
"devtools/devtools_network_transaction_factory.cc",
+ "devtools/devtools_pipe_handler.cc",
+ "devtools/devtools_pipe_handler.h",
"devtools/devtools_session.cc",
"devtools/devtools_session.h",
+ "devtools/devtools_target_registry.cc",
+ "devtools/devtools_target_registry.h",
"devtools/devtools_url_interceptor_request_job.cc",
"devtools/devtools_url_interceptor_request_job.h",
"devtools/devtools_url_request_interceptor.cc",
@@ -634,6 +664,8 @@ source_set("browser") {
"dom_storage/local_storage_context_mojo.h",
"dom_storage/local_storage_database_adapter.cc",
"dom_storage/local_storage_database_adapter.h",
+ "dom_storage/session_storage_context_mojo.cc",
+ "dom_storage/session_storage_context_mojo.h",
"dom_storage/session_storage_database.cc",
"dom_storage/session_storage_database.h",
"dom_storage/session_storage_database_adapter.cc",
@@ -667,8 +699,6 @@ source_set("browser") {
"download/download_job_impl.h",
"download/download_manager_impl.cc",
"download/download_manager_impl.h",
- "download/download_net_log_parameters.cc",
- "download/download_net_log_parameters.h",
"download/download_request_core.cc",
"download/download_request_core.h",
"download/download_request_handle.cc",
@@ -720,12 +750,12 @@ source_set("browser") {
"download/url_downloader.h",
"field_trial_recorder.cc",
"field_trial_recorder.h",
+ "file_url_loader_factory.cc",
+ "file_url_loader_factory.h",
"fileapi/browser_file_system_helper.cc",
"fileapi/browser_file_system_helper.h",
"fileapi/fileapi_message_filter.cc",
"fileapi/fileapi_message_filter.h",
- "fileapi/upload_file_system_file_element_reader.cc",
- "fileapi/upload_file_system_file_element_reader.h",
"find_request_manager.cc",
"find_request_manager.h",
"font_list_async.cc",
@@ -828,8 +858,6 @@ source_set("browser") {
"histogram_internals_request_job.h",
"histogram_internals_url_loader.cc",
"histogram_internals_url_loader.h",
- "histogram_message_filter.cc",
- "histogram_message_filter.h",
"histogram_subscriber.h",
"histogram_synchronizer.cc",
"histogram_synchronizer.h",
@@ -917,6 +945,8 @@ source_set("browser") {
"indexed_db/list_set.h",
"installedapp/installed_app_provider_impl_default.cc",
"installedapp/installed_app_provider_impl_default.h",
+ "interface_provider_filtering.cc",
+ "interface_provider_filtering.h",
"isolated_origin_util.cc",
"isolated_origin_util.h",
"keyboard_lock/keyboard_lock_service_impl.cc",
@@ -996,8 +1026,6 @@ source_set("browser") {
"loader/throttling_resource_handler.h",
"loader/upload_data_stream_builder.cc",
"loader/upload_data_stream_builder.h",
- "loader/upload_progress_tracker.cc",
- "loader/upload_progress_tracker.h",
"loader/url_loader_factory_impl.cc",
"loader/url_loader_factory_impl.h",
"loader/url_loader_request_handler.cc",
@@ -1018,6 +1046,8 @@ source_set("browser") {
"media/android/browser_surface_view_manager.h",
"media/android/media_player_renderer.cc",
"media/android/media_player_renderer.h",
+ "media/android/media_player_renderer_web_contents_observer.cc",
+ "media/android/media_player_renderer_web_contents_observer.h",
"media/android/media_resource_getter_impl.cc",
"media/android/media_resource_getter_impl.h",
"media/android/media_web_contents_observer_android.cc",
@@ -1103,6 +1133,8 @@ source_set("browser") {
"message_port_provider.cc",
"mime_registry_impl.cc",
"mime_registry_impl.h",
+ "mus_util.cc",
+ "mus_util.h",
"net/browser_online_state_observer.cc",
"net/browser_online_state_observer.h",
"net/network_errors_listing_ui.cc",
@@ -1117,6 +1149,8 @@ source_set("browser") {
"net/view_blob_internals_job_factory.h",
"net/view_http_cache_job_factory.cc",
"net/view_http_cache_job_factory.h",
+ "network_service_client.cc",
+ "network_service_client.h",
"notification_service_impl.cc",
"notification_service_impl.h",
"notifications/blink_notification_service_impl.cc",
@@ -1135,6 +1169,8 @@ source_set("browser") {
"notifications/platform_notification_context_impl.h",
"notifications/type_converters.cc",
"notifications/type_converters.h",
+ "origin_manifest/origin_manifest_parser.cc",
+ "origin_manifest/origin_manifest_parser.h",
"payments/payment_app_context_impl.cc",
"payments/payment_app_context_impl.h",
"payments/payment_app_database.cc",
@@ -1161,9 +1197,9 @@ source_set("browser") {
"push_messaging/push_messaging_router.h",
"quota_dispatcher_host.cc",
"quota_dispatcher_host.h",
- "renderer_host/clipboard_message_filter.cc",
- "renderer_host/clipboard_message_filter.h",
- "renderer_host/clipboard_message_filter_mac.mm",
+ "renderer_host/clipboard_host_impl.cc",
+ "renderer_host/clipboard_host_impl.h",
+ "renderer_host/clipboard_host_impl_mac.mm",
"renderer_host/cursor_manager.cc",
"renderer_host/cursor_manager.h",
"renderer_host/dip_util.cc",
@@ -1198,8 +1234,6 @@ source_set("browser") {
"renderer_host/input/legacy_input_router_impl.h",
"renderer_host/input/legacy_ipc_widget_input_handler.cc",
"renderer_host/input/legacy_ipc_widget_input_handler.h",
- "renderer_host/input/legacy_touch_event_queue.cc",
- "renderer_host/input/legacy_touch_event_queue.h",
"renderer_host/input/motion_event_web.cc",
"renderer_host/input/motion_event_web.h",
"renderer_host/input/mouse_wheel_event_queue.cc",
@@ -1276,6 +1310,8 @@ source_set("browser") {
"renderer_host/input/web_input_event_builders_mac.mm",
"renderer_host/legacy_render_widget_host_win.cc",
"renderer_host/legacy_render_widget_host_win.h",
+ "renderer_host/media/audio_input_delegate_impl.cc",
+ "renderer_host/media/audio_input_delegate_impl.h",
"renderer_host/media/audio_input_device_manager.cc",
"renderer_host/media/audio_input_device_manager.h",
"renderer_host/media/audio_input_renderer_host.cc",
@@ -1307,7 +1343,6 @@ source_set("browser") {
"renderer_host/media/media_stream_manager.cc",
"renderer_host/media/media_stream_manager.h",
"renderer_host/media/media_stream_provider.h",
- "renderer_host/media/media_stream_requester.h",
"renderer_host/media/media_stream_track_metrics_host.cc",
"renderer_host/media/media_stream_track_metrics_host.h",
"renderer_host/media/media_stream_ui_proxy.cc",
@@ -1364,6 +1399,8 @@ source_set("browser") {
"renderer_host/render_widget_helper.h",
"renderer_host/render_widget_host_delegate.cc",
"renderer_host/render_widget_host_delegate.h",
+ "renderer_host/render_widget_host_factory.cc",
+ "renderer_host/render_widget_host_factory.h",
"renderer_host/render_widget_host_impl.cc",
"renderer_host/render_widget_host_impl.h",
"renderer_host/render_widget_host_input_event_router.cc",
@@ -1396,6 +1433,8 @@ source_set("browser") {
"renderer_host/web_database_host_impl.h",
"renderer_host/webmenurunner_mac.h",
"renderer_host/webmenurunner_mac.mm",
+ "renderer_interface_binders.cc",
+ "renderer_interface_binders.h",
"resolve_proxy_msg_helper.cc",
"resolve_proxy_msg_helper.h",
"resource_context_impl.cc",
@@ -1412,23 +1451,19 @@ source_set("browser") {
"service_manager/common_browser_interfaces.h",
"service_manager/service_manager_context.cc",
"service_manager/service_manager_context.h",
- "service_worker/browser_side_controller_service_worker.cc",
- "service_worker/browser_side_controller_service_worker.h",
"service_worker/embedded_worker_instance.cc",
"service_worker/embedded_worker_instance.h",
"service_worker/embedded_worker_registry.cc",
"service_worker/embedded_worker_registry.h",
"service_worker/embedded_worker_status.h",
- "service_worker/foreign_fetch_request_handler.cc",
- "service_worker/foreign_fetch_request_handler.h",
- "service_worker/link_header_support.cc",
- "service_worker/link_header_support.h",
"service_worker/service_worker_blob_reader.cc",
"service_worker/service_worker_blob_reader.h",
"service_worker/service_worker_cache_writer.cc",
"service_worker/service_worker_cache_writer.h",
"service_worker/service_worker_client_utils.cc",
"service_worker/service_worker_client_utils.h",
+ "service_worker/service_worker_consts.cc",
+ "service_worker/service_worker_consts.h",
"service_worker/service_worker_content_settings_proxy_impl.cc",
"service_worker/service_worker_content_settings_proxy_impl.h",
"service_worker/service_worker_context_core.cc",
@@ -1483,8 +1518,8 @@ source_set("browser") {
"service_worker/service_worker_register_job_base.h",
"service_worker/service_worker_registration.cc",
"service_worker/service_worker_registration.h",
- "service_worker/service_worker_registration_handle.cc",
- "service_worker/service_worker_registration_handle.h",
+ "service_worker/service_worker_registration_object_host.cc",
+ "service_worker/service_worker_registration_object_host.h",
"service_worker/service_worker_registration_status.cc",
"service_worker/service_worker_registration_status.h",
"service_worker/service_worker_request_handler.cc",
@@ -1534,7 +1569,6 @@ source_set("browser") {
"speech/speech_recognizer.h",
"speech/speech_recognizer_impl_android.cc",
"speech/speech_recognizer_impl_android.h",
- "ssl/ignore_errors_cert_verifier.cc",
"ssl/ssl_client_auth_handler.cc",
"ssl/ssl_client_auth_handler.h",
"ssl/ssl_error_handler.cc",
@@ -1616,8 +1650,6 @@ source_set("browser") {
"web_contents/web_drag_source_mac.mm",
"web_contents/web_drag_utils_win.cc",
"web_contents/web_drag_utils_win.h",
- "webauth/authenticator_impl.cc",
- "webauth/authenticator_impl.h",
"webauth/cbor/cbor_values.cc",
"webauth/cbor/cbor_values.h",
"webauth/cbor/cbor_writer.cc",
@@ -1632,8 +1664,6 @@ source_set("browser") {
"webui/content_web_ui_controller_factory.h",
"webui/generic_handler.cc",
"webui/generic_handler.h",
- "webui/i18n_source_stream.cc",
- "webui/i18n_source_stream.h",
"webui/network_error_url_loader.cc",
"webui/network_error_url_loader.h",
"webui/shared_resources_data_source.cc",
@@ -1758,6 +1788,8 @@ source_set("browser") {
sources += [
"media/capture/cursor_renderer.cc",
"media/capture/cursor_renderer.h",
+ "media/capture/fake_webcontent_capture_machine.cc",
+ "media/capture/fake_webcontent_capture_machine.h",
"media/capture/web_contents_video_capture_device.cc",
"media/capture/web_contents_video_capture_device.h",
"media/capture/window_activity_tracker.cc",
@@ -1922,6 +1954,8 @@ source_set("browser") {
if (enable_library_cdms) {
sources += [
+ "media/cdm_file_impl.cc",
+ "media/cdm_file_impl.h",
"media/cdm_storage_impl.cc",
"media/cdm_storage_impl.h",
]
@@ -1978,7 +2012,6 @@ source_set("browser") {
"android/content_view_statics.cc",
"android/date_time_chooser_android.cc",
"android/date_time_chooser_android.h",
- "android/gesture_event_type.h",
"android/ime_adapter_android.cc",
"android/ime_adapter_android.h",
"android/interstitial_page_delegate_android.cc",
@@ -2045,6 +2078,12 @@ source_set("browser") {
"web_contents/web_contents_view_android.h",
]
+ jumbo_excluded_sources = [
+ # Files with kJavaLangClass and similar constants:
+ # Bug https://crbug.com/787557.
+ "android/java/java_method.cc", # and in gin_java_bound_object.cc.
+ ]
+
set_sources_assignment_filter([])
sources += [
"memory/swap_metrics_driver_impl_linux.cc",
@@ -2102,6 +2141,30 @@ source_set("browser") {
"speech/speech_recognition_engine.h",
"speech/speech_recognizer_impl.cc",
"speech/speech_recognizer_impl.h",
+
+ # Most webauth code is non-Android
+ "webauth/attestation_object.cc",
+ "webauth/attestation_object.h",
+ "webauth/attestation_statement.cc",
+ "webauth/attestation_statement.h",
+ "webauth/attested_credential_data.cc",
+ "webauth/attested_credential_data.h",
+ "webauth/authenticator_data.cc",
+ "webauth/authenticator_data.h",
+ "webauth/authenticator_impl.cc",
+ "webauth/authenticator_impl.h",
+ "webauth/authenticator_utils.cc",
+ "webauth/authenticator_utils.h",
+ "webauth/collected_client_data.cc",
+ "webauth/collected_client_data.h",
+ "webauth/ec_public_key.cc",
+ "webauth/ec_public_key.h",
+ "webauth/fido_attestation_statement.cc",
+ "webauth/fido_attestation_statement.h",
+ "webauth/public_key.cc",
+ "webauth/public_key.h",
+ "webauth/register_response_data.cc",
+ "webauth/register_response_data.h",
]
deps += [ "//third_party/flac" ]
}
@@ -2128,6 +2191,7 @@ source_set("browser") {
if (use_aura) {
deps += [
+ "//services/ui:lib",
"//services/ui/public/cpp",
"//services/ui/public/interfaces",
"//ui/aura",
@@ -2192,14 +2256,8 @@ source_set("browser") {
"compositor/reflector_texture.h",
"compositor/software_browser_compositor_output_surface.cc",
"compositor/software_browser_compositor_output_surface.h",
- "compositor/software_output_device_mac.h",
- "compositor/software_output_device_mac.mm",
- "compositor/software_output_device_ozone.cc",
- "compositor/software_output_device_ozone.h",
- "compositor/software_output_device_win.cc",
- "compositor/software_output_device_win.h",
- "compositor/software_output_device_x11.cc",
- "compositor/software_output_device_x11.h",
+ "compositor/viz_process_transport_factory.cc",
+ "compositor/viz_process_transport_factory.h",
"context_factory.cc",
"renderer_host/browser_compositor_view_mac.h",
"renderer_host/browser_compositor_view_mac.mm",
@@ -2208,25 +2266,22 @@ source_set("browser") {
"renderer_host/delegated_frame_host.cc",
"renderer_host/delegated_frame_host.h",
]
+ if (is_mac) {
+ jumbo_excluded_sources = [
+ # Both Mac SDK headers and third_party/khronos/GLES2/gl2ext.h
+ # declare macros GL_LINES_ADJACENCY_EXT, GL_LINE_STRIP_ADJACENCY_EXT,
+ # GL_TRIANGLES_ADJACENCY_EXT and GL_TRIANGLE_STRIP_ADJACENCY_EXT. They
+ # get the same values but with different formatting (0xD vs 0x000D).
+ # https://crbug.com/783666
+ "compositor/gpu_output_surface_mac.mm",
+ ]
+ }
if (enable_vulkan) {
sources += [
"compositor/vulkan_browser_compositor_output_surface.cc",
"compositor/vulkan_browser_compositor_output_surface.h",
]
}
- if (!use_x11) {
- sources -= [
- "compositor/software_output_device_x11.cc",
- "compositor/software_output_device_x11.h",
- ]
- }
-
- if (!use_ozone) {
- sources -= [
- "compositor/software_output_device_ozone.cc",
- "compositor/software_output_device_ozone.h",
- ]
- }
deps += [
"//components/viz/service",
"//ui/compositor",
diff --git a/chromium/content/browser/DEPS b/chromium/content/browser/DEPS
index ab76486097e..94e0ad4db36 100644
--- a/chromium/content/browser/DEPS
+++ b/chromium/content/browser/DEPS
@@ -3,6 +3,7 @@ include_rules = [
# See comment in content/DEPS for which components are allowed.
"+components/discardable_memory/common",
"+components/discardable_memory/service",
+ "+components/download/downloader/in_progress",
"+components/filesystem",
"+components/leveldb",
"+components/link_header_util",
@@ -37,7 +38,6 @@ include_rules = [
"+ui/aura_extra",
"+components/vector_icons",
"+ui/webui",
- "+storage/public/interfaces",
# In general, //content shouldn't depend on //device.
# This is the an exception.
@@ -51,6 +51,7 @@ include_rules = [
"+third_party/iaccessible2",
"+third_party/isimpledom",
"+third_party/khronos", # For enum definitions only
+ "+third_party/libaom/av1_features.h",
"+third_party/re2",
"+third_party/zlib",
@@ -65,13 +66,13 @@ include_rules = [
# No inclusion of WebKit from the browser, other than strictly enum/POD,
# header-only types, and some selected common code.
"-third_party/WebKit",
+ "+third_party/WebKit/common/feature_policy/feature_policy.h",
+ "+third_party/WebKit/common/feature_policy/feature_policy_feature.h",
"+third_party/WebKit/public/platform/WebAddressSpace.h",
"+third_party/WebKit/public/platform/WebContentSecurityPolicy.h",
"+third_party/WebKit/public/platform/WebCursorInfo.h",
"+third_party/WebKit/public/platform/WebDisplayMode.h",
"+third_party/WebKit/public/platform/WebDragOperation.h",
- "+third_party/WebKit/public/platform/WebFeaturePolicy.h",
- "+third_party/WebKit/public/platform/WebFeaturePolicyFeature.h",
"+third_party/WebKit/public/platform/WebFocusType.h",
"+third_party/WebKit/public/platform/WebGestureEvent.h",
"+third_party/WebKit/public/platform/WebInputEvent.h",
@@ -82,48 +83,22 @@ include_rules = [
"+third_party/WebKit/public/platform/WebMouseWheelEvent.h",
"+third_party/WebKit/public/platform/WebPageVisibilityState.h",
"+third_party/WebKit/public/platform/WebReferrerPolicy.h",
+ "+third_party/WebKit/public/platform/WebRemoteFrameProperties.h",
+ "+third_party/WebKit/public/platform/WebRemoteScrollProperties.h",
"+third_party/WebKit/public/platform/WebScreenInfo.h",
"+third_party/WebKit/public/platform/WebSecurityStyle.h",
"+third_party/WebKit/public/platform/WebSuddenTerminationDisablerType.h",
"+third_party/WebKit/public/platform/WebTouchEvent.h",
"+third_party/WebKit/public/platform/WebTextInputType.h",
- "+third_party/WebKit/public/platform/input_host.mojom.h",
- "+third_party/WebKit/public/platform/input_messages.mojom.h",
"+third_party/WebKit/public/platform/mac/WebScrollbarTheme.h",
- "+third_party/WebKit/public/platform/mime_registry.mojom.h",
- "+third_party/WebKit/public/platform/modules/background_sync/background_sync.mojom.h",
- "+third_party/WebKit/public/platform/modules/bluetooth/web_bluetooth.mojom.h",
- "+third_party/WebKit/public/platform/modules/broadcastchannel/broadcast_channel.mojom.h",
"+third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseException.h",
"+third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h",
- "+third_party/WebKit/public/platform/modules/installedapp/installed_app_provider.mojom.h",
- "+third_party/WebKit/public/platform/modules/installedapp/related_application.mojom.h",
- "+third_party/WebKit/public/platform/modules/keyboard_lock/keyboard_lock.mojom.h",
- "+third_party/WebKit/public/platform/modules/manifest/manifest_manager.mojom.h",
- "+third_party/WebKit/public/platform/modules/mediasession/media_session.mojom.h",
"+third_party/WebKit/public/platform/modules/notifications/WebNotificationConstants.h",
- "+third_party/WebKit/public/platform/modules/notifications/notification.mojom.h",
- "+third_party/WebKit/public/platform/modules/notifications/notification_service.mojom.h",
- "+third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom.h",
- "+third_party/WebKit/public/platform/modules/payments/payment_app.mojom.h",
- "+third_party/WebKit/public/platform/modules/permissions/permission.mojom.h",
- "+third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h",
- "+third_party/WebKit/public/platform/modules/presentation/presentation.mojom.h",
"+third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h",
"+third_party/WebKit/public/platform/modules/screen_orientation/WebLockOrientationError.h",
"+third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h",
"+third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationType.h",
- "+third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCacheError.h",
"+third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h",
- "+third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponseError.h",
- "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h",
- "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h",
- "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h",
- "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_state.mojom.h",
- "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_stream_handle.mojom.h",
- "+third_party/WebKit/public/platform/modules/webauth/authenticator.mojom.h",
- "+third_party/WebKit/public/platform/modules/websockets/websocket.mojom.h",
- "+third_party/WebKit/public/platform/reporting.mojom.h",
"+third_party/WebKit/public/public_features.h",
"+third_party/WebKit/public/web/WebAXEnums.h",
"+third_party/WebKit/public/web/WebConsoleMessage.h",
@@ -136,7 +111,7 @@ include_rules = [
"+third_party/WebKit/public/web/WebMediaPlayerAction.h",
"+third_party/WebKit/public/web/WebPluginAction.h",
"+third_party/WebKit/public/web/WebPopupType.h",
- "+third_party/WebKit/public/web/WebSandboxFlags.h",
+ "+third_party/WebKit/common/sandbox_flags.h",
"+third_party/WebKit/public/web/WebSerializedScriptValueVersion.h",
"+third_party/WebKit/public/web/WebSharedWorkerCreationContextType.h",
"+third_party/WebKit/public/web/WebSharedWorkerCreationErrors.h",
@@ -149,6 +124,45 @@ include_rules = [
# does not use Blink types like WTF.
"+third_party/WebKit/common",
+ # Allow mojo generated files in WebKit. These files use STL types and
+ # don't use WTF types.
+ "+third_party/WebKit/public/platform/dedicated_worker_factory.mojom.h",
+ "+third_party/WebKit/public/platform/input_host.mojom.h",
+ "+third_party/WebKit/public/platform/input_messages.mojom.h",
+ "+third_party/WebKit/public/platform/mime_registry.mojom.h",
+ "+third_party/WebKit/public/platform/modules/background_sync/background_sync.mojom.h",
+ "+third_party/WebKit/public/platform/modules/bluetooth/web_bluetooth.mojom.h",
+ "+third_party/WebKit/public/platform/modules/broadcastchannel/broadcast_channel.mojom.h",
+ "+third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h",
+ "+third_party/WebKit/public/platform/modules/geolocation/geolocation_service.mojom.h",
+ "+third_party/WebKit/public/platform/modules/installedapp/installed_app_provider.mojom.h",
+ "+third_party/WebKit/public/platform/modules/installedapp/related_application.mojom.h",
+ "+third_party/WebKit/public/platform/modules/keyboard_lock/keyboard_lock.mojom.h",
+ "+third_party/WebKit/public/platform/modules/manifest/manifest_manager.mojom.h",
+ "+third_party/WebKit/public/platform/modules/mediasession/media_session.mojom.h",
+ "+third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h",
+ "+third_party/WebKit/public/platform/modules/notifications/notification.mojom.h",
+ "+third_party/WebKit/public/platform/modules/notifications/notification_service.mojom.h",
+ "+third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom.h",
+ "+third_party/WebKit/public/platform/modules/payments/payment_app.mojom.h",
+ "+third_party/WebKit/public/platform/modules/permissions/permission.mojom.h",
+ "+third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h",
+ "+third_party/WebKit/public/platform/modules/presentation/presentation.mojom.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/navigation_preload_state.mojom.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/service_worker.mojom.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_state.mojom.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_stream_handle.mojom.h",
+ "+third_party/WebKit/public/platform/modules/webauth/authenticator.mojom.h",
+ "+third_party/WebKit/public/platform/modules/webdatabase/web_database.mojom.h",
+ "+third_party/WebKit/public/platform/modules/websockets/websocket.mojom.h",
+ "+third_party/WebKit/public/platform/oom_intervention.mojom.h",
+ "+third_party/WebKit/public/platform/reporting.mojom.h",
+ "+third_party/WebKit/public/platform/web_feature.mojom.h",
+
# DO NOT ADD ANY CHROME OR COMPONENTS INCLUDES HERE!!!
# See https://sites.google.com/a/chromium.org/dev/developers/content-module
# for more information.
diff --git a/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc b/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
index 79c29e4eff7..3f0e57f76ca 100644
--- a/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
+++ b/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
@@ -6,6 +6,7 @@
#include <oleacc.h>
#include <stdint.h>
+#include <wrl/client.h>
#include <string>
@@ -16,7 +17,6 @@
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_com_initializer.h"
-#include "base/win/scoped_comptr.h"
#include "base/win/scoped_variant.h"
#include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
@@ -39,7 +39,7 @@ std::string RoleVariantToString(const base::win::ScopedVariant& role) {
}
HRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) {
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
return SUCCEEDED(hr) ?
service_provider->QueryService(IID_IAccessible2, accessible2) : hr;
@@ -47,7 +47,7 @@ HRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) {
HRESULT QueryIAccessibleText(IAccessible* accessible,
IAccessibleText** accessible_text) {
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
return SUCCEEDED(hr) ?
service_provider->QueryService(IID_IAccessibleText, accessible_text) : hr;
@@ -109,6 +109,8 @@ class AccessibilityEventRecorderWin : public AccessibilityEventRecorder {
HWINEVENTHOOK win_event_hook_handle_;
static AccessibilityEventRecorderWin* instance_;
+
+ // Initializes COM services when standalone dump events tool is used.
base::win::ScopedCOMInitializer com_initializer;
};
@@ -173,7 +175,7 @@ void AccessibilityEventRecorderWin::OnWinEventHook(
LONG child_id,
DWORD event_thread,
DWORD event_time) {
- base::win::ScopedComPtr<IAccessible> browser_accessible;
+ Microsoft::WRL::ComPtr<IAccessible> browser_accessible;
HRESULT hr = AccessibleObjectFromWindowWrapper(
hwnd, obj_id, IID_IAccessible,
reinterpret_cast<void**>(browser_accessible.GetAddressOf()));
@@ -186,7 +188,7 @@ void AccessibilityEventRecorderWin::OnWinEventHook(
}
base::win::ScopedVariant childid_variant(child_id);
- base::win::ScopedComPtr<IDispatch> dispatch;
+ Microsoft::WRL::ComPtr<IDispatch> dispatch;
hr = browser_accessible->get_accChild(childid_variant,
dispatch.GetAddressOf());
if (!SUCCEEDED(hr) || !dispatch) {
@@ -195,7 +197,7 @@ void AccessibilityEventRecorderWin::OnWinEventHook(
return;
}
- base::win::ScopedComPtr<IAccessible> iaccessible;
+ Microsoft::WRL::ComPtr<IAccessible> iaccessible;
hr = dispatch.CopyTo(iaccessible.GetAddressOf());
if (!SUCCEEDED(hr)) {
VLOG(1) << "Ignoring result " << hr << " from QueryInterface";
@@ -236,7 +238,7 @@ void AccessibilityEventRecorderWin::OnWinEventHook(
ia_state &= ~STATE_SYSTEM_READONLY;
AccessibleStates ia2_state = 0;
- base::win::ScopedComPtr<IAccessible2> iaccessible2;
+ Microsoft::WRL::ComPtr<IAccessible2> iaccessible2;
hr = QueryIAccessible2(iaccessible.Get(), iaccessible2.GetAddressOf());
if (SUCCEEDED(hr))
iaccessible2->get_states(&ia2_state);
@@ -254,7 +256,7 @@ void AccessibilityEventRecorderWin::OnWinEventHook(
// For TEXT_REMOVED and TEXT_INSERTED events, query the text that was
// inserted or removed and include that in the log.
- base::win::ScopedComPtr<IAccessibleText> accessible_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> accessible_text;
hr = QueryIAccessibleText(iaccessible.Get(), accessible_text.GetAddressOf());
if (SUCCEEDED(hr)) {
if (event == IA2_EVENT_TEXT_REMOVED) {
diff --git a/chromium/content/browser/accessibility/accessibility_mode_browsertest.cc b/chromium/content/browser/accessibility/accessibility_mode_browsertest.cc
index e53abd0235c..6bffc59b39f 100644
--- a/chromium/content/browser/accessibility/accessibility_mode_browsertest.cc
+++ b/chromium/content/browser/accessibility/accessibility_mode_browsertest.cc
@@ -2,6 +2,7 @@
// 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 "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter.cc
index 7e80f8d3dda..f7d4159ef4c 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter.cc
@@ -45,11 +45,36 @@ void AccessibilityTreeFormatter::FormatAccessibilityTree(
RecursiveFormatAccessibilityTree(*(dict.get()), contents);
}
+void AccessibilityTreeFormatter::FormatAccessibilityTree(
+ const base::DictionaryValue& dict,
+ base::string16* contents) {
+ RecursiveFormatAccessibilityTree(dict, contents);
+}
+
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatter::FilterAccessibilityTree(
+ const base::DictionaryValue& dict) {
+ auto filtered_dict = std::make_unique<base::DictionaryValue>();
+ ProcessTreeForOutput(dict, filtered_dict.get());
+ const base::ListValue* children;
+ if (dict.GetList(kChildrenDictAttr, &children) && !children->empty()) {
+ const base::DictionaryValue* child_dict;
+ auto filtered_children = std::make_unique<base::ListValue>();
+ for (size_t i = 0; i < children->GetSize(); i++) {
+ children->GetDictionary(i, &child_dict);
+ auto filtered_child = FilterAccessibilityTree(*child_dict);
+ filtered_children->Append(std::move(filtered_child));
+ }
+ filtered_dict->Set(kChildrenDictAttr, std::move(filtered_children));
+ }
+ return filtered_dict;
+}
+
void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree(
const base::DictionaryValue& dict, base::string16* contents, int depth) {
base::string16 indent = base::string16(depth * kIndentSymbolCount,
kIndentSymbol);
- base::string16 line = indent + ToString(dict);
+ base::string16 line = indent + ProcessTreeForOutput(dict);
if (line.find(base::ASCIIToUTF16(kSkipString)) != base::string16::npos)
return;
@@ -64,7 +89,8 @@ void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree(
return;
const base::ListValue* children;
- dict.GetList(kChildrenDictAttr, &children);
+ if (!dict.GetList(kChildrenDictAttr, &children))
+ return;
const base::DictionaryValue* child_dict;
for (size_t i = 0; i < children->GetSize(); i++) {
children->GetDictionary(i, &child_dict);
@@ -113,20 +139,23 @@ base::string16 AccessibilityTreeFormatter::FormatCoordinates(
return base::UTF8ToUTF16(xy_str);
}
-void AccessibilityTreeFormatter::WriteAttribute(
- bool include_by_default, const std::string& attr, base::string16* line) {
- WriteAttribute(include_by_default, base::UTF8ToUTF16(attr), line);
+bool AccessibilityTreeFormatter::WriteAttribute(bool include_by_default,
+ const std::string& attr,
+ base::string16* line) {
+ return WriteAttribute(include_by_default, base::UTF8ToUTF16(attr), line);
}
-void AccessibilityTreeFormatter::WriteAttribute(
- bool include_by_default, const base::string16& attr, base::string16* line) {
+bool AccessibilityTreeFormatter::WriteAttribute(bool include_by_default,
+ const base::string16& attr,
+ base::string16* line) {
if (attr.empty())
- return;
+ return false;
if (!MatchesFilters(attr, include_by_default))
- return;
+ return false;
if (!line->empty())
*line += base::ASCIIToUTF16(" ");
*line += attr;
+ return true;
}
} // namespace content
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter.h b/chromium/content/browser/accessibility/accessibility_tree_formatter.h
index 71a789952f2..536fcb617e7 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter.h
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter.h
@@ -11,11 +11,13 @@
#include "base/files/file_path.h"
#include "base/macros.h"
+#include "base/process/process_handle.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/common/content_export.h"
+#include "ui/gfx/native_widget_types.h"
namespace {
const char kChildrenDictAttr[] = "children";
@@ -75,12 +77,27 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
// "children": [ ]
// } ]
// }
+ // Build an accessibility tree for the current Chrome app.
virtual std::unique_ptr<base::DictionaryValue> BuildAccessibilityTree(
BrowserAccessibility* root) = 0;
+ // Build an accessibility tree for any process with a window.
+ virtual std::unique_ptr<base::DictionaryValue>
+ BuildAccessibilityTreeForProcess(base::ProcessId pid) = 0;
+
+ // Build an accessibility tree for any window.
+ virtual std::unique_ptr<base::DictionaryValue>
+ BuildAccessibilityTreeForWindow(gfx::AcceleratedWidget widget) = 0;
+
+ // Returns a filtered accesibility tree using the current filters.
+ std::unique_ptr<base::DictionaryValue> FilterAccessibilityTree(
+ const base::DictionaryValue& dict);
+
// Dumps a BrowserAccessibility tree into a string.
void FormatAccessibilityTree(
BrowserAccessibility* root, base::string16* contents);
+ void FormatAccessibilityTree(const base::DictionaryValue& tree_node,
+ base::string16* contents);
// Set regular expression filters that apply to each component of every
// line before it's output.
@@ -119,8 +136,15 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
// Overridden by platform subclasses.
//
- // Returns a platform specific representation of a BrowserAccessibility.
- virtual base::string16 ToString(const base::DictionaryValue& node) = 0;
+ // Process accessibility tree with filters for output.
+ // Given a dictionary that contains a platform-specific dictionary
+ // representing an accessibility tree, and utilizing filters_:
+ // - Returns a filtered text view as one large string.
+ // - Provides a filtered version of the dictionary in an out param,
+ // (only if the out param is provided).
+ virtual base::string16 ProcessTreeForOutput(
+ const base::DictionaryValue& node,
+ base::DictionaryValue* filtered_dict_result = nullptr) = 0;
//
// Utility functions to be used by each platform.
@@ -132,10 +156,11 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
const base::DictionaryValue& value);
// Writes the given attribute string out to |line| if it matches the filters.
- void WriteAttribute(bool include_by_default,
+ // Returns false if the attribute was filtered out.
+ bool WriteAttribute(bool include_by_default,
const base::string16& attr,
base::string16* line);
- void WriteAttribute(bool include_by_default,
+ bool WriteAttribute(bool include_by_default,
const std::string& attr,
base::string16* line);
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_android.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_android.cc
index 1d4b55d52bc..0a0487518d3 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_android.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_android.cc
@@ -84,7 +84,9 @@ class AccessibilityTreeFormatterAndroid
const std::string GetDenyString() override;
void AddProperties(const BrowserAccessibility& node,
base::DictionaryValue* dict) override;
- base::string16 ToString(const base::DictionaryValue& node) override;
+ base::string16 ProcessTreeForOutput(
+ const base::DictionaryValue& node,
+ base::DictionaryValue* filtered_dict_result = nullptr) override;
};
// static
@@ -164,10 +166,14 @@ void AccessibilityTreeFormatterAndroid::AddProperties(
dict->SetBoolean("action_scroll_right", android_node->CanScrollRight());
}
-base::string16 AccessibilityTreeFormatterAndroid::ToString(
- const base::DictionaryValue& dict) {
- base::string16 line;
+base::string16 AccessibilityTreeFormatterAndroid::ProcessTreeForOutput(
+ const base::DictionaryValue& dict,
+ base::DictionaryValue* filtered_dict_result) {
+ base::string16 error_value;
+ if (dict.GetString("error", &error_value))
+ return error_value;
+ base::string16 line;
if (show_ids()) {
int id_value;
dict.GetInteger("id", &id_value);
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
index a0507f27362..b8ed49ddcc3 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
@@ -4,8 +4,6 @@
#include "content/browser/accessibility/accessibility_tree_formatter_browser.h"
-#include <atk/atk.h>
-
#include <utility>
#include "base/logging.h"
@@ -16,6 +14,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "content/browser/accessibility/browser_accessibility_auralinux.h"
+#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
namespace content {
@@ -32,7 +31,9 @@ class AccessibilityTreeFormatterAuraLinux
const std::string GetDenyString() override;
void AddProperties(const BrowserAccessibility& node,
base::DictionaryValue* dict) override;
- base::string16 ToString(const base::DictionaryValue& node) override;
+ base::string16 ProcessTreeForOutput(
+ const base::DictionaryValue& node,
+ base::DictionaryValue* filtered_dict_result = nullptr) override;
};
// static
@@ -53,29 +54,16 @@ void AccessibilityTreeFormatterAuraLinux::AddProperties(
BrowserAccessibilityAuraLinux* acc_obj =
ToBrowserAccessibilityAuraLinux(const_cast<BrowserAccessibility*>(&node));
- AtkObject* atk_object = acc_obj->GetAtkObject();
- AtkRole role = acc_obj->atk_role();
- if (role != ATK_ROLE_UNKNOWN)
- dict->SetString("role", std::string(atk_role_get_name(role)));
- const gchar* name = atk_object_get_name(atk_object);
- if (name)
- dict->SetString("name", std::string(name));
- const gchar* description = atk_object_get_description(atk_object);
- if (description)
- dict->SetString("description", std::string(description));
-
- AtkStateSet* state_set = atk_object_ref_state_set(atk_object);
- auto states = base::MakeUnique<base::ListValue>();
- 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))
- states->AppendString(atk_state_type_get_name(state_type));
- }
- dict->Set("states", std::move(states));
+ acc_obj->GetNode()->AddAccessibilityTreeProperties(dict);
}
-base::string16 AccessibilityTreeFormatterAuraLinux::ToString(
- const base::DictionaryValue& node) {
+base::string16 AccessibilityTreeFormatterAuraLinux::ProcessTreeForOutput(
+ const base::DictionaryValue& node,
+ base::DictionaryValue* filtered_dict_result) {
+ base::string16 error_value;
+ if (node.GetString("error", &error_value))
+ return error_value;
+
base::string16 line;
std::string role_value;
node.GetString("role", &role_value);
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc
index 6a87eb36a9b..9d3bca65de9 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -151,6 +151,12 @@ void AccessibilityTreeFormatterBlink::AddProperties(
node.GetData().transform &&
!node.GetData().transform->IsIdentity());
+ gfx::Rect unclipped_bounds = node.GetPageBoundsRect(&offscreen, false);
+ dict->SetInteger("unclippedBoundsX", unclipped_bounds.x());
+ dict->SetInteger("unclippedBoundsY", unclipped_bounds.y());
+ dict->SetInteger("unclippedBoundsWidth", unclipped_bounds.width());
+ dict->SetInteger("unclippedBoundsHeight", unclipped_bounds.height());
+
for (int state_index = ui::AX_STATE_NONE;
state_index <= ui::AX_STATE_LAST;
++state_index) {
@@ -203,7 +209,7 @@ void AccessibilityTreeFormatterBlink::AddProperties(
if (node.HasIntListAttribute(attr)) {
std::vector<int32_t> values;
node.GetIntListAttribute(attr, &values);
- auto value_list = base::MakeUnique<base::ListValue>();
+ auto value_list = std::make_unique<base::ListValue>();
for (size_t i = 0; i < values.size(); ++i) {
if (ui::IsNodeIdIntListAttribute(attr)) {
BrowserAccessibility* target = node.manager()->GetFromID(values[i]);
@@ -242,8 +248,13 @@ void AccessibilityTreeFormatterBlink::AddProperties(
dict->SetString("actions", base::JoinString(actions_strings, ","));
}
-base::string16 AccessibilityTreeFormatterBlink::ToString(
- const base::DictionaryValue& dict) {
+base::string16 AccessibilityTreeFormatterBlink::ProcessTreeForOutput(
+ const base::DictionaryValue& dict,
+ base::DictionaryValue* filtered_dict_result) {
+ base::string16 error_value;
+ if (dict.GetString("error", &error_value))
+ return error_value;
+
base::string16 line;
if (show_ids()) {
@@ -291,6 +302,14 @@ base::string16 AccessibilityTreeFormatterBlink::ToString(
FormatCoordinates("pageSize",
"pageBoundsWidth", "pageBoundsHeight", dict),
&line);
+ WriteAttribute(false,
+ FormatCoordinates("unclippedLocation", "unclippedBoundsX",
+ "unclippedBoundsY", dict),
+ &line);
+ WriteAttribute(false,
+ FormatCoordinates("unclippedSize", "unclippedBoundsWidth",
+ "unclippedBoundsHeight", dict),
+ &line);
bool transform;
if (dict.GetBoolean("transform", &transform) && transform)
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.h b/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.h
index d31190da979..b72cc5863bc 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.h
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.h
@@ -30,7 +30,9 @@ class CONTENT_EXPORT AccessibilityTreeFormatterBlink
std::string IntAttrToString(const BrowserAccessibility& node,
ui::AXIntAttribute attr,
int value) const;
- base::string16 ToString(const base::DictionaryValue& node) override;
+ base::string16 ProcessTreeForOutput(
+ const base::DictionaryValue& node,
+ base::DictionaryValue* filtered_dict_result = nullptr) override;
};
} // namespace content
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.cc
index 17412d3fda4..f62e4d4d4c6 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.cc
@@ -17,12 +17,26 @@ AccessibilityTreeFormatterBrowser::BuildAccessibilityTree(
return dict;
}
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatterBrowser::BuildAccessibilityTreeForProcess(
+ base::ProcessId pid) {
+ NOTREACHED();
+ return nullptr;
+}
+
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatterBrowser::BuildAccessibilityTreeForWindow(
+ gfx::AcceleratedWidget widget) {
+ NOTREACHED();
+ return nullptr;
+}
+
void AccessibilityTreeFormatterBrowser::RecursiveBuildAccessibilityTree(
const BrowserAccessibility& node,
base::DictionaryValue* dict) {
AddProperties(node, dict);
- auto children = base::MakeUnique<base::ListValue>();
+ auto children = std::make_unique<base::ListValue>();
for (size_t i = 0; i < ChildCount(node); ++i) {
BrowserAccessibility* child_node = GetChild(node, i);
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.h b/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.h
index 9e153baaa83..b91c9debdc3 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.h
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.h
@@ -25,6 +25,12 @@ class CONTENT_EXPORT AccessibilityTreeFormatterBrowser
std::unique_ptr<base::DictionaryValue> BuildAccessibilityTree(
BrowserAccessibility* root) override;
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForProcess(
+ base::ProcessId pid) override;
+
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForWindow(
+ gfx::AcceleratedWidget widget) 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 d496aa08eed..1402f8eb016 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -219,7 +219,8 @@ class AccessibilityTreeFormatterMac : public AccessibilityTreeFormatterBrowser {
const std::string GetDenyString() override;
void AddProperties(const BrowserAccessibility& node,
base::DictionaryValue* dict) override;
- base::string16 ToString(const base::DictionaryValue& node) override;
+ base::string16 ProcessTreeForOutput(const base::DictionaryValue& node,
+ base::DictionaryValue* filtered_dict_result = nullptr) override;
};
// static
@@ -267,8 +268,13 @@ void AccessibilityTreeFormatterMac::AddProperties(
dict->Set(kSizeDictAttr, PopulateSize(cocoa_node));
}
-base::string16 AccessibilityTreeFormatterMac::ToString(
- const base::DictionaryValue& dict) {
+base::string16 AccessibilityTreeFormatterMac::ProcessTreeForOutput(
+ const base::DictionaryValue& dict,
+ base::DictionaryValue* filtered_dict_result) {
+ base::string16 error_value;
+ if (dict.GetString("error", &error_value))
+ return error_value;
+
base::string16 line;
if (show_ids()) {
int id_value;
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_stub.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_stub.cc
index 72e9af187d4..26c8d20ca57 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_stub.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_stub.cc
@@ -20,7 +20,9 @@ class AccessibilityTreeFormatterStub
const std::string GetDenyString() override;
void AddProperties(const BrowserAccessibility& node,
base::DictionaryValue* dict) override;
- base::string16 ToString(const base::DictionaryValue& node) override;
+ base::string16 ProcessTreeForOutput(
+ const base::DictionaryValue& node,
+ base::DictionaryValue* filtered_dict_result = nullptr) override;
};
#if !defined(PLATFORM_HAS_NATIVE_ACCESSIBILITY_IMPL)
@@ -42,8 +44,9 @@ void AccessibilityTreeFormatterStub::AddProperties(
dict->SetInteger("id", node.GetId());
}
-base::string16 AccessibilityTreeFormatterStub::ToString(
- const base::DictionaryValue& node) {
+base::string16 AccessibilityTreeFormatterStub::ProcessTreeForOutput(
+ const base::DictionaryValue& node,
+ base::DictionaryValue* filtered_dict_result) {
int id_value;
node.GetInteger("id", &id_value);
return base::IntToString16(id_value);
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc
index 25fc4d490db..d370745cabc 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -7,6 +7,7 @@
#include <oleacc.h>
#include <stddef.h>
#include <stdint.h>
+#include <wrl/client.h>
#include <string>
#include <utility>
@@ -20,14 +21,41 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "base/win/scoped_bstr.h"
-#include "base/win/scoped_comptr.h"
+#include "base/win/scoped_com_initializer.h"
#include "base/win/scoped_variant.h"
#include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_win.h"
#include "third_party/iaccessible2/ia2_api_all.h"
#include "ui/base/win/atl_module.h"
+#include "ui/gfx/win/hwnd_util.h"
+namespace {
+
+struct HwndWithProcId {
+ HwndWithProcId(const base::ProcessId id) : pid(id), hwnd(nullptr) {}
+ const base::ProcessId pid;
+ HWND hwnd;
+};
+
+BOOL CALLBACK EnumWindowsProcPid(HWND hwnd, LPARAM lParam) {
+ DWORD process_id;
+ GetWindowThreadProcessId(hwnd, &process_id);
+ HwndWithProcId* hwnd_with_proc_id = (HwndWithProcId*)lParam;
+ if (process_id == static_cast<DWORD>(hwnd_with_proc_id->pid)) {
+ hwnd_with_proc_id->hwnd = hwnd;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+HWND GetHwndForProcess(base::ProcessId pid) {
+ HwndWithProcId hwnd_with_proc_id(pid);
+ EnumWindows(&EnumWindowsProcPid, (LPARAM)&hwnd_with_proc_id);
+ return hwnd_with_proc_id.hwnd;
+}
+
+} // namespace
namespace content {
@@ -38,14 +66,18 @@ class AccessibilityTreeFormatterWin : public AccessibilityTreeFormatter {
std::unique_ptr<base::DictionaryValue> BuildAccessibilityTree(
BrowserAccessibility* start) override;
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForWindow(
+ gfx::AcceleratedWidget hwnd) override;
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForProcess(
+ base::ProcessId pid) override;
std::unique_ptr<base::DictionaryValue> BuildAccessibilityTree(
- base::win::ScopedComPtr<IAccessible> start,
+ Microsoft::WRL::ComPtr<IAccessible> start,
LONG window_x = 0,
LONG window_y = 0);
private:
void RecursiveBuildAccessibilityTree(
- const base::win::ScopedComPtr<IAccessible> node,
+ const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict,
LONG root_x,
LONG root_y);
@@ -54,29 +86,36 @@ class AccessibilityTreeFormatterWin : public AccessibilityTreeFormatter {
const std::string GetAllowEmptyString() override;
const std::string GetAllowString() override;
const std::string GetDenyString() override;
- void AddProperties(const base::win::ScopedComPtr<IAccessible>,
+ void AddProperties(const Microsoft::WRL::ComPtr<IAccessible>,
base::DictionaryValue* dict,
LONG root_x,
LONG root_y);
- void AddMSAAProperties(const base::win::ScopedComPtr<IAccessible>,
+ void AddMSAAProperties(const Microsoft::WRL::ComPtr<IAccessible>,
base::DictionaryValue* dict,
LONG root_x,
LONG root_y);
- void AddSimpleDOMNodeProperties(const base::win::ScopedComPtr<IAccessible>,
+ void AddSimpleDOMNodeProperties(const Microsoft::WRL::ComPtr<IAccessible>,
base::DictionaryValue* dict);
- bool AddIA2Properties(const base::win::ScopedComPtr<IAccessible>,
+ bool AddIA2Properties(const Microsoft::WRL::ComPtr<IAccessible>,
base::DictionaryValue* dict);
- void AddIA2ActionProperties(const base::win::ScopedComPtr<IAccessible>,
+ void AddIA2ActionProperties(const Microsoft::WRL::ComPtr<IAccessible>,
base::DictionaryValue* dict);
- void AddIA2HypertextProperties(const base::win::ScopedComPtr<IAccessible>,
+ void AddIA2HypertextProperties(const Microsoft::WRL::ComPtr<IAccessible>,
base::DictionaryValue* dict);
- void AddIA2TextProperties(const base::win::ScopedComPtr<IAccessible>,
+ void AddIA2TextProperties(const Microsoft::WRL::ComPtr<IAccessible>,
base::DictionaryValue* dict);
- void AddIA2TableProperties(const base::win::ScopedComPtr<IAccessible>,
+ void AddIA2TableProperties(const Microsoft::WRL::ComPtr<IAccessible>,
base::DictionaryValue* dict);
- void AddIA2ValueProperties(const base::win::ScopedComPtr<IAccessible>,
+ void AddIA2TableCellProperties(const Microsoft::WRL::ComPtr<IAccessible>,
+ base::DictionaryValue* dict);
+ void AddIA2ValueProperties(const Microsoft::WRL::ComPtr<IAccessible>,
base::DictionaryValue* dict);
- base::string16 ToString(const base::DictionaryValue& node) override;
+ base::string16 ProcessTreeForOutput(
+ const base::DictionaryValue& node,
+ base::DictionaryValue* filtered_dict_result = nullptr) override;
+
+ // Initializes COM services when standalone dump events tool is used.
+ base::win::ScopedCOMInitializer com_initializer;
};
// static
@@ -95,7 +134,7 @@ static HRESULT QuerySimpleDOMNode(IAccessible* accessible,
ISimpleDOMNode** simple_dom_node) {
// IA2 Spec dictates that IServiceProvider should be used instead of
// QueryInterface when retrieving IAccessible2.
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -106,7 +145,7 @@ static HRESULT QueryIAccessible2(IAccessible* accessible,
IAccessible2** accessible2) {
// IA2 Spec dictates that IServiceProvider should be used instead of
// QueryInterface when retrieving IAccessible2.
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -117,7 +156,7 @@ static HRESULT QueryIAccessibleAction(IAccessible* accessible,
IAccessibleAction** accessibleAction) {
// IA2 Spec dictates that IServiceProvider should be used instead of
// QueryInterface when retrieving alternate interfaces.
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -131,7 +170,7 @@ static HRESULT QueryIAccessibleHypertext(
IAccessibleHypertext** accessibleHypertext) {
// IA2 Spec dictates that IServiceProvider should be used instead of
// QueryInterface when retrieving alternate interfaces.
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -143,18 +182,31 @@ static HRESULT QueryIAccessibleTable(IAccessible* accessible,
IAccessibleTable** accessibleTable) {
// IA2 Spec dictates that IServiceProvider should be used instead of
// QueryInterface when retrieving alternate interfaces.
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
if (FAILED(hr))
return hr;
return service_provider->QueryService(IID_IAccessibleTable, accessibleTable);
}
+static HRESULT QueryIAccessibleTableCell(
+ IAccessible* accessible,
+ IAccessibleTableCell** accessibleTableCell) {
+ // IA2 Spec dictates that IServiceProvider should be used instead of
+ // QueryInterface when retrieving alternate interfaces.
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
+ HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
+ if (FAILED(hr))
+ return hr;
+ return service_provider->QueryService(IID_IAccessibleTableCell,
+ accessibleTableCell);
+}
+
static HRESULT QueryIAccessibleText(IAccessible* accessible,
IAccessibleText** accessibleText) {
// IA2 Spec dictates that IServiceProvider should be used instead of
// QueryInterface when retrieving alternate interfaces.
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -165,7 +217,7 @@ static HRESULT QueryIAccessibleValue(IAccessible* accessible,
IAccessibleValue** accessibleValue) {
// IA2 Spec dictates that IServiceProvider should be used instead of
// QueryInterface when retrieving alternate interfaces.
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -177,9 +229,7 @@ AccessibilityTreeFormatterWin::BuildAccessibilityTree(
BrowserAccessibility* start_node) {
DCHECK(start_node);
- VARIANT variant_self;
- variant_self.vt = VT_I4;
- variant_self.lVal = CHILDID_SELF;
+ base::win::ScopedVariant variant_self(CHILDID_SELF);
LONG root_x, root_y, root_width, root_height;
BrowserAccessibility* root =
start_node->manager()->GetRootManager()->GetRoot();
@@ -187,7 +237,7 @@ AccessibilityTreeFormatterWin::BuildAccessibilityTree(
&root_x, &root_y, &root_width, &root_height, variant_self);
DCHECK(SUCCEEDED(hr));
- base::win::ScopedComPtr<IAccessible> start_ia =
+ Microsoft::WRL::ComPtr<IAccessible> start_ia =
ToBrowserAccessibilityComWin(start_node);
return BuildAccessibilityTree(start_ia, root_x, root_y);
@@ -195,7 +245,7 @@ AccessibilityTreeFormatterWin::BuildAccessibilityTree(
std::unique_ptr<base::DictionaryValue>
AccessibilityTreeFormatterWin::BuildAccessibilityTree(
- base::win::ScopedComPtr<IAccessible> start,
+ Microsoft::WRL::ComPtr<IAccessible> start,
LONG root_x,
LONG root_y) {
CHECK(start);
@@ -206,38 +256,103 @@ AccessibilityTreeFormatterWin::BuildAccessibilityTree(
return dict;
}
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatterWin::BuildAccessibilityTreeForWindow(
+ gfx::AcceleratedWidget hwnd) {
+ if (!hwnd)
+ return nullptr;
+
+ // Get IAccessible* for window
+ Microsoft::WRL::ComPtr<IAccessible> start;
+ HRESULT hr = ::AccessibleObjectFromWindow(
+ hwnd, static_cast<DWORD>(OBJID_CLIENT), IID_PPV_ARGS(&start));
+ if (FAILED(hr))
+ return nullptr;
+
+ auto dict(std::make_unique<base::DictionaryValue>());
+ RecursiveBuildAccessibilityTree(start, dict.get(), 0, 0);
+
+ return dict;
+}
+
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatterWin::BuildAccessibilityTreeForProcess(
+ base::ProcessId pid) {
+ // Get HWND for process id.
+ HWND hwnd = GetHwndForProcess(pid);
+ return BuildAccessibilityTreeForWindow(hwnd);
+}
+
void AccessibilityTreeFormatterWin::RecursiveBuildAccessibilityTree(
- const base::win::ScopedComPtr<IAccessible> node,
+ const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict,
LONG root_x,
LONG root_y) {
AddProperties(node, dict, root_x, root_y);
- auto children = base::MakeUnique<base::ListValue>();
+ auto children = std::make_unique<base::ListValue>();
LONG child_count;
if (S_OK != node->get_accChildCount(&child_count))
return;
- for (int index = 1; index <= child_count; ++index) {
- base::win::ScopedVariant childid_index(index);
- base::win::ScopedComPtr<IDispatch> child_dispatch;
- base::win::ScopedComPtr<IAccessible> child_accessible;
- if (S_OK ==
- node->get_accChild(childid_index, child_dispatch.GetAddressOf()) &&
- S_OK == child_dispatch.CopyTo(child_accessible.GetAddressOf())) {
- std::unique_ptr<base::DictionaryValue> child_dict(
- new base::DictionaryValue);
- RecursiveBuildAccessibilityTree(child_accessible, child_dict.get(),
- root_x, root_y);
- children->Append(std::move(child_dict));
+ std::unique_ptr<VARIANT[]> children_array(new VARIANT[child_count]);
+ LONG obtained_count = 0;
+ HRESULT hr = AccessibleChildren(node.Get(), 0, child_count,
+ children_array.get(), &obtained_count);
+ if (hr != S_OK)
+ return;
+
+ for (LONG index = 0; index < obtained_count; index++) {
+ base::win::ScopedVariant child_variant;
+ child_variant.Reset(
+ children_array[index]); // Sets without adding another reference.
+ std::unique_ptr<base::DictionaryValue> child_dict(
+ new base::DictionaryValue);
+ Microsoft::WRL::ComPtr<IDispatch> dispatch;
+ if (child_variant.type() == VT_DISPATCH) {
+ dispatch = V_DISPATCH(child_variant.ptr());
+ } else if (child_variant.type() == VT_I4) {
+ HRESULT hr = node->get_accChild(child_variant, dispatch.GetAddressOf());
+ if (FAILED(hr)) {
+ child_dict->SetString("error",
+ base::ASCIIToUTF16("[Error retrieving child]"));
+ } else if (!dispatch) {
+ // Partial child does not have its own object.
+ // Add minimal info -- role and name.
+ base::win::ScopedVariant role_variant;
+ if (SUCCEEDED(
+ node->get_accRole(child_variant, role_variant.Receive()))) {
+ if (role_variant.type() == VT_I4) {
+ child_dict->SetString("role",
+ base::ASCIIToUTF16(" [partial child]"));
+ }
+ }
+ base::win::ScopedBstr temp_bstr;
+ if (S_OK == node->get_accName(child_variant, temp_bstr.Receive())) {
+ base::string16 name = base::string16(temp_bstr, temp_bstr.Length());
+ child_dict->SetString("name", name);
+ }
+ }
+ } else {
+ child_dict->SetString("error",
+ base::ASCIIToUTF16("[Unknown child type]"));
}
+ if (dispatch) {
+ Microsoft::WRL::ComPtr<IAccessible> accessible;
+ if (SUCCEEDED(dispatch.As(&accessible)))
+ RecursiveBuildAccessibilityTree(accessible, child_dict.get(), root_x,
+ root_y);
+ }
+ children->Append(std::move(child_dict));
}
dict->Set(kChildrenDictAttr, std::move(children));
}
const char* const ALL_ATTRIBUTES[] = {
"name",
+ "parent",
+ "window_class",
"value",
"states",
"attributes",
@@ -261,6 +376,8 @@ const char* const ALL_ATTRIBUTES[] = {
"table_columns",
"row_index",
"column_index",
+ "row_headers",
+ "column_headers",
"n_characters",
"caret_offset",
"n_selections",
@@ -271,7 +388,7 @@ const char* const ALL_ATTRIBUTES[] = {
};
void AccessibilityTreeFormatterWin::AddProperties(
- const base::win::ScopedComPtr<IAccessible> node,
+ const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict,
LONG root_x,
LONG root_y) {
@@ -281,31 +398,34 @@ void AccessibilityTreeFormatterWin::AddProperties(
AddIA2ActionProperties(node, dict);
AddIA2HypertextProperties(node, dict);
AddIA2TableProperties(node, dict);
+ AddIA2TableCellProperties(node, dict);
AddIA2TextProperties(node, dict);
AddIA2ValueProperties(node, dict);
}
}
+base::string16 RoleVariantToString(const base::win::ScopedVariant& role) {
+ if (role.type() == VT_I4) {
+ return IAccessible2RoleToString(V_I4(role.ptr()));
+ } else if (role.type() == VT_BSTR) {
+ BSTR bstr_role = V_BSTR(role.ptr());
+ return base::string16(bstr_role, SysStringLen(bstr_role));
+ }
+ return base::string16();
+}
+
void AccessibilityTreeFormatterWin::AddMSAAProperties(
- const base::win::ScopedComPtr<IAccessible> node,
+ const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict,
LONG root_x,
LONG root_y) {
- VARIANT variant_self;
- variant_self.vt = VT_I4;
- variant_self.lVal = CHILDID_SELF;
-
+ base::win::ScopedVariant variant_self(CHILDID_SELF);
base::win::ScopedBstr temp_bstr;
-
+ base::win::ScopedVariant ia_role_variant;
LONG ia_role = 0;
- VARIANT ia_role_variant;
- if (SUCCEEDED(node->get_accRole(variant_self, &ia_role_variant))) {
- if (ia_role_variant.vt == VT_I4) {
- ia_role = ia_role_variant.lVal;
- dict->SetString("role", IAccessible2RoleToString(ia_role));
- } else if (ia_role_variant.vt == VT_BSTR) {
- dict->SetString("role", base::string16(ia_role_variant.bstrVal));
- }
+ if (SUCCEEDED(node->get_accRole(variant_self, ia_role_variant.Receive()))) {
+ dict->SetString("role", RoleVariantToString(ia_role_variant));
+ ia_role = V_I4(ia_role_variant.ptr());
}
// If S_FALSE it means there is no name
@@ -318,27 +438,44 @@ void AccessibilityTreeFormatterWin::AddMSAAProperties(
}
temp_bstr.Reset();
+ Microsoft::WRL::ComPtr<IDispatch> parent_dispatch;
+ if (SUCCEEDED(node->get_accParent(parent_dispatch.GetAddressOf()))) {
+ Microsoft::WRL::ComPtr<IAccessible> parent_accessible;
+ if (!parent_dispatch) {
+ dict->SetString("parent", "[null]");
+ } else if (SUCCEEDED(
+ parent_dispatch.CopyTo(parent_accessible.GetAddressOf()))) {
+ base::win::ScopedVariant parent_ia_role_variant;
+ if (SUCCEEDED(parent_accessible->get_accRole(
+ variant_self, parent_ia_role_variant.Receive())))
+ dict->SetString("parent", RoleVariantToString(parent_ia_role_variant));
+ else
+ dict->SetString("parent", L"[Error retrieving role from parent]");
+ } else {
+ dict->SetString("parent", L"[Error getting IAccessible* for parent]");
+ }
+ } else {
+ dict->SetString("parent", L"[Error retrieving parent]");
+ }
+
+ HWND hwnd;
+ if (SUCCEEDED(::WindowFromAccessibleObject(node.Get(), &hwnd)) && hwnd) {
+ dict->SetString("window_class", gfx::GetClassName(hwnd));
+ } else {
+ // This method is implemented by oleacc.dll and uses get_accParent,
+ // therefore it Will fail if get_accParent from root fails.
+ dict->SetString("window_class", L"[Error]");
+ }
+
if (SUCCEEDED(node->get_accValue(variant_self, temp_bstr.Receive())))
dict->SetString("value", base::string16(temp_bstr, temp_bstr.Length()));
temp_bstr.Reset();
int32_t ia_state = 0;
- VARIANT ia_state_variant;
- if (node->get_accState(variant_self, &ia_state_variant) == S_OK &&
- ia_state_variant.vt == VT_I4) {
- ia_state = ia_state_variant.intVal;
-
- if (true /* reduced_flakiness_mode_ */) { // TODO
- // Avoid flakiness: these states depend on whether the window is focused
- // and the position of the mouse cursor.
- ia_state &= ~STATE_SYSTEM_HOTTRACKED;
- ia_state &= ~STATE_SYSTEM_OFFSCREEN;
-
- // For testing, having the focused state may also cause flakiness if the
- // window isn't in the foreground.
- ia_state &= ~STATE_SYSTEM_FOCUSED;
- }
-
+ base::win::ScopedVariant ia_state_variant;
+ if (node->get_accState(variant_self, ia_state_variant.Receive()) == S_OK &&
+ ia_state_variant.type() == VT_I4) {
+ ia_state = ia_state_variant.ptr()->intVal;
std::vector<base::string16> state_strings;
IAccessibleStateToStringVector(ia_state, &state_strings);
std::unique_ptr<base::ListValue> states(new base::ListValue());
@@ -374,12 +511,12 @@ void AccessibilityTreeFormatterWin::AddMSAAProperties(
LONG x, y, width, height;
if (SUCCEEDED(node->accLocation(&x, &y, &width, &height, variant_self))) {
- auto location = base::MakeUnique<base::DictionaryValue>();
+ auto location = std::make_unique<base::DictionaryValue>();
location->SetInteger("x", x - root_x);
location->SetInteger("y", y - root_y);
dict->Set("location", std::move(location));
- auto size = base::MakeUnique<base::DictionaryValue>();
+ auto size = std::make_unique<base::DictionaryValue>();
size->SetInteger("width", width);
size->SetInteger("height", height);
dict->Set("size", std::move(size));
@@ -387,9 +524,9 @@ void AccessibilityTreeFormatterWin::AddMSAAProperties(
}
void AccessibilityTreeFormatterWin::AddSimpleDOMNodeProperties(
- const base::win::ScopedComPtr<IAccessible> node,
+ const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict) {
- base::win::ScopedComPtr<ISimpleDOMNode> simple_dom_node;
+ Microsoft::WRL::ComPtr<ISimpleDOMNode> simple_dom_node;
if (S_OK != QuerySimpleDOMNode(node.Get(), simple_dom_node.GetAddressOf()))
return; // No IA2Value, we are finished with this node.
@@ -404,15 +541,17 @@ void AccessibilityTreeFormatterWin::AddSimpleDOMNodeProperties(
}
bool AccessibilityTreeFormatterWin::AddIA2Properties(
- const base::win::ScopedComPtr<IAccessible> node,
+ const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict) {
- base::win::ScopedComPtr<IAccessible2> ia2;
+ Microsoft::WRL::ComPtr<IAccessible2> ia2;
if (S_OK != QueryIAccessible2(node.Get(), ia2.GetAddressOf()))
return false; // No IA2, we are finished with this node.
LONG ia2_role = 0;
if (SUCCEEDED(ia2->role(&ia2_role))) {
- dict->SetKey("msaa_legacy_role", dict->Clone());
+ std::string legacy_role;
+ dict->GetString("role", &legacy_role);
+ dict->SetString("msaa_legacy_role", legacy_role);
// Overwrite MSAA role which is more limited.
dict->SetString("role", IAccessible2RoleToString(ia2_role));
}
@@ -470,9 +609,9 @@ bool AccessibilityTreeFormatterWin::AddIA2Properties(
}
void AccessibilityTreeFormatterWin::AddIA2ActionProperties(
- const base::win::ScopedComPtr<IAccessible> node,
+ const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict) {
- base::win::ScopedComPtr<IAccessibleAction> ia2action;
+ Microsoft::WRL::ComPtr<IAccessibleAction> ia2action;
if (S_OK != QueryIAccessibleAction(node.Get(), ia2action.GetAddressOf()))
return; // No IA2Value, we are finished with this node.
@@ -487,9 +626,9 @@ void AccessibilityTreeFormatterWin::AddIA2ActionProperties(
}
void AccessibilityTreeFormatterWin::AddIA2HypertextProperties(
- base::win::ScopedComPtr<IAccessible> node,
+ Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict) {
- base::win::ScopedComPtr<IAccessibleHypertext> ia2hyper;
+ Microsoft::WRL::ComPtr<IAccessibleHypertext> ia2hyper;
if (S_OK != QueryIAccessibleHypertext(node.Get(), ia2hyper.GetAddressOf()))
return; // No IA2, we are finished with this node
@@ -526,11 +665,11 @@ void AccessibilityTreeFormatterWin::AddIA2HypertextProperties(
LONG child_index = -1;
if (hr == S_OK) {
DCHECK_GE(index_of_embed, 0);
- base::win::ScopedComPtr<IAccessibleHyperlink> embedded_object;
+ Microsoft::WRL::ComPtr<IAccessibleHyperlink> embedded_object;
hr = ia2hyper->get_hyperlink(index_of_embed,
embedded_object.GetAddressOf());
DCHECK(SUCCEEDED(hr));
- base::win::ScopedComPtr<IAccessible2> ax_embed;
+ Microsoft::WRL::ComPtr<IAccessible2> ax_embed;
hr = embedded_object.CopyTo(ax_embed.GetAddressOf());
DCHECK(SUCCEEDED(hr));
hr = ax_embed->get_indexInParent(&child_index);
@@ -556,9 +695,9 @@ void AccessibilityTreeFormatterWin::AddIA2HypertextProperties(
}
void AccessibilityTreeFormatterWin::AddIA2TableProperties(
- const base::win::ScopedComPtr<IAccessible> node,
+ const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict) {
- base::win::ScopedComPtr<IAccessibleTable> ia2table;
+ Microsoft::WRL::ComPtr<IAccessibleTable> ia2table;
if (S_OK != QueryIAccessibleTable(node.Get(), ia2table.GetAddressOf()))
return; // No IA2Text, we are finished with this node.
@@ -571,10 +710,64 @@ void AccessibilityTreeFormatterWin::AddIA2TableProperties(
dict->SetInteger("table_columns", table_columns);
}
+static base::string16 ProcessAccessiblesArray(IUnknown** accessibles,
+ LONG num_accessibles) {
+ base::string16 related_accessibles_string;
+ if (num_accessibles <= 0)
+ return related_accessibles_string;
+
+ base::win::ScopedVariant variant_self(CHILDID_SELF);
+
+ for (int index = 0; index < num_accessibles; index++) {
+ related_accessibles_string += index > 0 ? L"," : L"<";
+ Microsoft::WRL::ComPtr<IUnknown> unknown = accessibles[index];
+ Microsoft::WRL::ComPtr<IAccessible> accessible;
+ if (SUCCEEDED(unknown.CopyTo(accessible.GetAddressOf()))) {
+ base::win::ScopedBstr temp_bstr;
+ if (S_OK == accessible->get_accName(variant_self, temp_bstr.Receive()))
+ related_accessibles_string += temp_bstr;
+ else
+ related_accessibles_string += L"no name";
+ }
+ }
+
+ return related_accessibles_string + L">";
+}
+
+void AccessibilityTreeFormatterWin::AddIA2TableCellProperties(
+ const Microsoft::WRL::ComPtr<IAccessible> node,
+ base::DictionaryValue* dict) {
+ Microsoft::WRL::ComPtr<IAccessibleTableCell> ia2cell;
+ if (S_OK != QueryIAccessibleTableCell(node.Get(), ia2cell.GetAddressOf()))
+ return; // No IA2Text, we are finished with this node.
+
+ LONG n_row_header_cells;
+ IUnknown** row_headers;
+ if (SUCCEEDED(
+ ia2cell->get_rowHeaderCells(&row_headers, &n_row_header_cells)) &&
+ n_row_header_cells > 0) {
+ base::string16 accessibles_desc =
+ ProcessAccessiblesArray(row_headers, n_row_header_cells);
+ CoTaskMemFree(row_headers); // Free the array manually.
+ dict->SetString("row_headers", accessibles_desc);
+ }
+
+ LONG n_column_header_cells;
+ IUnknown** column_headers;
+ if (SUCCEEDED(ia2cell->get_columnHeaderCells(&column_headers,
+ &n_column_header_cells)) &&
+ n_column_header_cells > 0) {
+ base::string16 accessibles_desc =
+ ProcessAccessiblesArray(column_headers, n_column_header_cells);
+ CoTaskMemFree(column_headers); // Free the array manually.
+ dict->SetString("column_headers", accessibles_desc);
+ }
+}
+
void AccessibilityTreeFormatterWin::AddIA2TextProperties(
- const base::win::ScopedComPtr<IAccessible> node,
+ const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict) {
- base::win::ScopedComPtr<IAccessibleText> ia2text;
+ Microsoft::WRL::ComPtr<IAccessibleText> ia2text;
if (S_OK != QueryIAccessibleText(node.Get(), ia2text.GetAddressOf()))
return; // No IA2Text, we are finished with this node.
@@ -638,69 +831,80 @@ void AccessibilityTreeFormatterWin::AddIA2TextProperties(
}
void AccessibilityTreeFormatterWin::AddIA2ValueProperties(
- const base::win::ScopedComPtr<IAccessible> node,
+ const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict) {
- base::win::ScopedComPtr<IAccessibleValue> ia2value;
+ Microsoft::WRL::ComPtr<IAccessibleValue> ia2value;
if (S_OK != QueryIAccessibleValue(node.Get(), ia2value.GetAddressOf()))
return; // No IA2Value, we are finished with this node.
- VARIANT currentValue;
- if (ia2value->get_currentValue(&currentValue) == S_OK)
- dict->SetDouble("currentValue", V_R8(&currentValue));
+ base::win::ScopedVariant currentValue;
+ if (ia2value->get_currentValue(currentValue.Receive()) == S_OK)
+ dict->SetDouble("currentValue", V_R8(currentValue.ptr()));
- VARIANT minimumValue;
- if (ia2value->get_minimumValue(&minimumValue) == S_OK)
- dict->SetDouble("minimumValue", V_R8(&minimumValue));
+ base::win::ScopedVariant minimumValue;
+ if (ia2value->get_minimumValue(minimumValue.Receive()) == S_OK)
+ dict->SetDouble("minimumValue", V_R8(minimumValue.ptr()));
- VARIANT maximumValue;
- if (ia2value->get_maximumValue(&maximumValue) == S_OK)
- dict->SetDouble("maximumValue", V_R8(&maximumValue));
+ base::win::ScopedVariant maximumValue;
+ if (ia2value->get_maximumValue(maximumValue.Receive()) == S_OK)
+ dict->SetDouble("maximumValue", V_R8(maximumValue.ptr()));
}
-base::string16 AccessibilityTreeFormatterWin::ToString(
- const base::DictionaryValue& dict) {
+base::string16 AccessibilityTreeFormatterWin::ProcessTreeForOutput(
+ const base::DictionaryValue& dict,
+ base::DictionaryValue* filtered_dict_result) {
base::string16 line;
+ // Always show role, and show it first.
base::string16 role_value;
dict.GetString("role", &role_value);
WriteAttribute(true, base::UTF16ToUTF8(role_value), &line);
+ if (filtered_dict_result)
+ filtered_dict_result->SetString("role", role_value);
for (const char* attribute_name : ALL_ATTRIBUTES) {
const base::Value* value;
if (!dict.Get(attribute_name, &value))
continue;
- switch (value->GetType()) {
+ switch (value->type()) {
case base::Value::Type::STRING: {
base::string16 string_value;
value->GetAsString(&string_value);
- WriteAttribute(false,
- base::StringPrintf(L"%ls='%ls'",
- base::UTF8ToUTF16(attribute_name).c_str(),
- string_value.c_str()),
- &line);
+ bool did_pass_filters = WriteAttribute(
+ false,
+ base::StringPrintf(L"%ls='%ls'",
+ base::UTF8ToUTF16(attribute_name).c_str(),
+ string_value.c_str()),
+ &line);
+ if (filtered_dict_result && did_pass_filters)
+ filtered_dict_result->SetString(attribute_name, string_value);
break;
}
case base::Value::Type::INTEGER: {
int int_value = 0;
value->GetAsInteger(&int_value);
- WriteAttribute(false,
- base::StringPrintf(L"%ls=%d",
- base::UTF8ToUTF16(
- attribute_name).c_str(),
- int_value),
- &line);
+ bool did_pass_filters = WriteAttribute(
+ false,
+ base::StringPrintf(L"%ls=%d",
+ base::UTF8ToUTF16(attribute_name).c_str(),
+ int_value),
+ &line);
+ if (filtered_dict_result && did_pass_filters)
+ filtered_dict_result->SetInteger(attribute_name, int_value);
break;
}
case base::Value::Type::DOUBLE: {
double double_value = 0.0;
value->GetAsDouble(&double_value);
- WriteAttribute(false,
- base::StringPrintf(L"%ls=%.2f",
- base::UTF8ToUTF16(
- attribute_name).c_str(),
- double_value),
- &line);
+ bool did_pass_filters = WriteAttribute(
+ false,
+ base::StringPrintf(L"%ls=%.2f",
+ base::UTF8ToUTF16(attribute_name).c_str(),
+ double_value),
+ &line);
+ if (filtered_dict_result && did_pass_filters)
+ filtered_dict_result->SetDouble(attribute_name, double_value);
break;
}
case base::Value::Type::LIST: {
@@ -708,13 +912,18 @@ base::string16 AccessibilityTreeFormatterWin::ToString(
// attribute names.
const base::ListValue* list_value;
value->GetAsList(&list_value);
+ std::unique_ptr<base::ListValue> filtered_list(new base::ListValue());
+
for (base::ListValue::const_iterator it = list_value->begin();
it != list_value->end();
++it) {
base::string16 string_value;
if (it->GetAsString(&string_value))
- WriteAttribute(false, string_value, &line);
+ if (WriteAttribute(false, string_value, &line))
+ filtered_list->AppendString(string_value);
}
+ if (filtered_dict_result && !filtered_list->empty())
+ filtered_dict_result->Set(attribute_name, std::move(filtered_list));
break;
}
case base::Value::Type::DICTIONARY: {
@@ -722,16 +931,18 @@ base::string16 AccessibilityTreeFormatterWin::ToString(
// Revisit this if that changes.
const base::DictionaryValue* dict_value;
value->GetAsDictionary(&dict_value);
+ bool did_pass_filters = false;
if (strcmp(attribute_name, "size") == 0) {
- WriteAttribute(false,
- FormatCoordinates("size", "width", "height",
- *dict_value),
- &line);
+ did_pass_filters = WriteAttribute(
+ false, FormatCoordinates("size", "width", "height", *dict_value),
+ &line);
} else if (strcmp(attribute_name, "location") == 0) {
- WriteAttribute(false,
- FormatCoordinates("location", "x", "y", *dict_value),
- &line);
+ did_pass_filters = WriteAttribute(
+ false, FormatCoordinates("location", "x", "y", *dict_value),
+ &line);
}
+ if (filtered_dict_result && did_pass_filters)
+ filtered_dict_result->SetKey(attribute_name, dict_value->Clone());
break;
}
default:
diff --git a/chromium/content/browser/accessibility/accessibility_ui.cc b/chromium/content/browser/accessibility/accessibility_ui.cc
index 8dd4a990328..e745f631490 100644
--- a/chromium/content/browser/accessibility/accessibility_ui.cc
+++ b/chromium/content/browser/accessibility/accessibility_ui.cc
@@ -22,6 +22,7 @@
#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/browser/web_contents/web_contents_view.h"
#include "content/browser/webui/web_ui_data_source_impl.h"
#include "content/common/view_message_enums.h"
#include "content/grit/content_resources.h"
@@ -36,8 +37,9 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "net/base/escape.h"
+#include "ui/accessibility/platform/ax_platform_node.h"
-static const char kDataFile[] = "targets-data.json";
+static const char kTargetsDataFile[] = "targets-data.json";
static const char kProcessIdField[] = "processId";
static const char kRouteIdField[] = "routeId";
@@ -102,7 +104,7 @@ std::unique_ptr<base::DictionaryValue> BuildTargetDescriptor(
title = base::UTF16ToUTF8(web_contents->GetTitle());
NavigationController& controller = web_contents->GetController();
NavigationEntry* entry = controller.GetVisibleEntry();
- if (entry != NULL && entry->GetURL().is_valid())
+ if (entry != nullptr && entry->GetURL().is_valid())
favicon_url = entry->GetFavicon().url;
accessibility_mode = web_contents->GetAccessibilityMode();
}
@@ -115,10 +117,11 @@ std::unique_ptr<base::DictionaryValue> BuildTargetDescriptor(
accessibility_mode);
}
-bool HandleRequestCallback(BrowserContext* current_context,
- const std::string& path,
- const WebUIDataSource::GotDataCallback& callback) {
- if (path != kDataFile)
+bool HandleAccessibilityRequestCallback(
+ BrowserContext* current_context,
+ const std::string& path,
+ const WebUIDataSource::GotDataCallback& callback) {
+ if (path != kTargetsDataFile)
return false;
std::unique_ptr<base::ListValue> rvh_list(new base::ListValue());
@@ -175,6 +178,20 @@ bool HandleRequestCallback(BrowserContext* current_context,
return true;
}
+std::string RecursiveDumpAXPlatformNodeAsString(ui::AXPlatformNode* node,
+ int indent) {
+ std::string str(2 * indent, '+');
+ str += node->GetDelegate()->GetData().ToString() + "\n";
+ for (int i = 0; i < node->GetDelegate()->GetChildCount(); i++) {
+ gfx::NativeViewAccessible child = node->GetDelegate()->ChildAtIndex(i);
+ ui::AXPlatformNode* child_node =
+ ui::AXPlatformNode::FromNativeViewAccessible(child);
+ if (child_node)
+ str += RecursiveDumpAXPlatformNodeAsString(child_node, indent + 1);
+ }
+ return str;
+}
+
} // namespace
AccessibilityUI::AccessibilityUI(WebUI* web_ui) : WebUIController(web_ui) {
@@ -182,38 +199,52 @@ AccessibilityUI::AccessibilityUI(WebUI* web_ui) : WebUIController(web_ui) {
WebUIDataSourceImpl* html_source = static_cast<WebUIDataSourceImpl*>(
WebUIDataSource::Create(kChromeUIAccessibilityHost));
- web_ui->RegisterMessageCallback(
- "toggleAccessibility",
- base::Bind(&AccessibilityUI::ToggleAccessibility,
- base::Unretained(this)));
- web_ui->RegisterMessageCallback(
- "setGlobalFlag",
- base::Bind(&AccessibilityUI::SetGlobalFlag,
- base::Unretained(this)));
- web_ui->RegisterMessageCallback(
- "requestAccessibilityTree",
- base::Bind(&AccessibilityUI::RequestAccessibilityTree,
- base::Unretained(this)));
-
// Add required resources.
html_source->SetJsonPath("strings.js");
html_source->AddResourcePath("accessibility.css", IDR_ACCESSIBILITY_CSS);
html_source->AddResourcePath("accessibility.js", IDR_ACCESSIBILITY_JS);
html_source->SetDefaultResource(IDR_ACCESSIBILITY_HTML);
html_source->SetRequestFilter(
- base::Bind(&HandleRequestCallback,
+ base::Bind(&HandleAccessibilityRequestCallback,
web_ui->GetWebContents()->GetBrowserContext()));
- html_source->UseGzip({kDataFile});
+ html_source->UseGzip({kTargetsDataFile});
BrowserContext* browser_context =
web_ui->GetWebContents()->GetBrowserContext();
WebUIDataSource::Add(browser_context, html_source);
+
+ web_ui->AddMessageHandler(base::MakeUnique<AccessibilityUIMessageHandler>());
}
AccessibilityUI::~AccessibilityUI() {}
-void AccessibilityUI::ToggleAccessibility(const base::ListValue* args) {
+AccessibilityUIMessageHandler::AccessibilityUIMessageHandler() {}
+
+AccessibilityUIMessageHandler::~AccessibilityUIMessageHandler() {}
+
+void AccessibilityUIMessageHandler::RegisterMessages() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ web_ui()->RegisterMessageCallback(
+ "toggleAccessibility",
+ base::Bind(&AccessibilityUIMessageHandler::ToggleAccessibility,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "setGlobalFlag", base::Bind(&AccessibilityUIMessageHandler::SetGlobalFlag,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "requestWebContentsTree",
+ base::Bind(&AccessibilityUIMessageHandler::RequestWebContentsTree,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "requestNativeUITree",
+ base::Bind(&AccessibilityUIMessageHandler::RequestNativeUITree,
+ base::Unretained(this)));
+}
+
+void AccessibilityUIMessageHandler::ToggleAccessibility(
+ const base::ListValue* args) {
std::string process_id_str;
std::string route_id_str;
int process_id;
@@ -227,6 +258,7 @@ void AccessibilityUI::ToggleAccessibility(const base::ListValue* args) {
CHECK(base::StringToInt(process_id_str, &process_id));
CHECK(base::StringToInt(route_id_str, &route_id));
+ AllowJavascript();
RenderViewHost* rvh = RenderViewHost::FromID(process_id, route_id);
if (!rvh)
return;
@@ -252,13 +284,14 @@ void AccessibilityUI::ToggleAccessibility(const base::ListValue* args) {
web_contents->SetAccessibilityMode(current_mode);
}
-void AccessibilityUI::SetGlobalFlag(const base::ListValue* args) {
+void AccessibilityUIMessageHandler::SetGlobalFlag(const base::ListValue* args) {
std::string flag_name_str;
bool enabled;
CHECK_EQ(2U, args->GetSize());
CHECK(args->GetString(0, &flag_name_str));
CHECK(args->GetBoolean(1, &enabled));
+ AllowJavascript();
if (flag_name_str == kInternal) {
g_show_internal_accessibility_tree = enabled;
LOG(ERROR) << "INTERNAL: " << g_show_internal_accessibility_tree;
@@ -305,7 +338,8 @@ void AccessibilityUI::SetGlobalFlag(const base::ListValue* args) {
state->RemoveAccessibilityModeFlags(new_mode);
}
-void AccessibilityUI::RequestAccessibilityTree(const base::ListValue* args) {
+void AccessibilityUIMessageHandler::RequestWebContentsTree(
+ const base::ListValue* args) {
std::string process_id_str;
std::string route_id_str;
int process_id;
@@ -316,14 +350,14 @@ void AccessibilityUI::RequestAccessibilityTree(const base::ListValue* args) {
CHECK(base::StringToInt(process_id_str, &process_id));
CHECK(base::StringToInt(route_id_str, &route_id));
+ AllowJavascript();
RenderViewHost* rvh = RenderViewHost::FromID(process_id, route_id);
if (!rvh) {
std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
result->SetInteger(kProcessIdField, process_id);
result->SetInteger(kRouteIdField, route_id);
result->SetString("error", "Renderer no longer exists.");
- web_ui()->CallJavascriptFunctionUnsafe("accessibility.showTree",
- *(result.get()));
+ CallJavascriptFunction("accessibility.showTree", *(result.get()));
return;
}
@@ -351,8 +385,23 @@ void AccessibilityUI::RequestAccessibilityTree(const base::ListValue* args) {
formatter->FormatAccessibilityTree(ax_mgr->GetRoot(),
&accessibility_contents_utf16);
result->SetString("tree", base::UTF16ToUTF8(accessibility_contents_utf16));
- web_ui()->CallJavascriptFunctionUnsafe("accessibility.showTree",
- *(result.get()));
+ CallJavascriptFunction("accessibility.showTree", *(result.get()));
+}
+
+void AccessibilityUIMessageHandler::RequestNativeUITree(
+ const base::ListValue* args) {
+ AllowJavascript();
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(web_ui()->GetWebContents());
+ gfx::NativeWindow native_window =
+ web_contents->GetView()->GetTopLevelNativeWindow();
+ ui::AXPlatformNode* node =
+ ui::AXPlatformNode::FromNativeWindow(native_window);
+ std::string str = RecursiveDumpAXPlatformNodeAsString(node, 0);
+
+ std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
+ result->SetString("tree", str);
+ CallJavascriptFunction("accessibility.showNativeUITree", *(result.get()));
}
} // namespace content
diff --git a/chromium/content/browser/accessibility/accessibility_ui.h b/chromium/content/browser/accessibility/accessibility_ui.h
index 2167b2920f4..a54f23d3502 100644
--- a/chromium/content/browser/accessibility/accessibility_ui.h
+++ b/chromium/content/browser/accessibility/accessibility_ui.h
@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/browser/web_ui_message_handler.h"
namespace base {
class ListValue;
@@ -19,13 +20,22 @@ class AccessibilityUI : public WebUIController {
public:
explicit AccessibilityUI(WebUI* web_ui);
~AccessibilityUI() override;
+};
+
+class AccessibilityUIMessageHandler : public content::WebUIMessageHandler {
+ public:
+ AccessibilityUIMessageHandler();
+ ~AccessibilityUIMessageHandler() override;
+
+ void RegisterMessages() override;
private:
void ToggleAccessibility(const base::ListValue* args);
void SetGlobalFlag(const base::ListValue* args);
- void RequestAccessibilityTree(const base::ListValue* args);
+ void RequestWebContentsTree(const base::ListValue* args);
+ void RequestNativeUITree(const base::ListValue* args);
- DISALLOW_COPY_AND_ASSIGN(AccessibilityUI);
+ DISALLOW_COPY_AND_ASSIGN(AccessibilityUIMessageHandler);
};
} // namespace content
diff --git a/chromium/content/browser/accessibility/accessibility_win_browsertest.cc b/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
index a945abb3444..bbf0fd107a9 100644
--- a/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -5,6 +5,7 @@
#include <objbase.h>
#include <stddef.h>
#include <stdint.h>
+#include <wrl/client.h>
#include <memory>
#include <vector>
@@ -13,7 +14,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include "base/win/scoped_bstr.h"
-#include "base/win/scoped_comptr.h"
#include "base/win/scoped_variant.h"
#include "content/browser/accessibility/accessibility_tree_formatter.h"
#include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
@@ -67,20 +67,19 @@ class AccessibilityWinBrowserTest : public ContentBrowserTest {
ui::AXMode accessibility_mode = ui::kAXModeComplete);
IAccessible* GetRendererAccessible();
void ExecuteScript(const std::wstring& script);
- void SetUpInputField(
- base::win::ScopedComPtr<IAccessibleText>* input_text);
+ void SetUpInputField(Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
void SetUpTextareaField(
- base::win::ScopedComPtr<IAccessibleText>* textarea_text);
+ Microsoft::WRL::ComPtr<IAccessibleText>* textarea_text);
void SetUpSampleParagraph(
- base::win::ScopedComPtr<IAccessibleText>* accessible_text,
+ Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text,
ui::AXMode accessibility_mode = ui::kAXModeComplete);
void SetUpSampleParagraphWithScroll(
- base::win::ScopedComPtr<IAccessibleText>* accessible_text,
+ Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text,
ui::AXMode accessibility_mode = ui::kAXModeComplete);
void SetUpSampleParagraphHelper(
- base::win::ScopedComPtr<IAccessibleText>* accessible_text);
+ Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text);
- static base::win::ScopedComPtr<IAccessible> GetAccessibleFromVariant(
+ static Microsoft::WRL::ComPtr<IAccessible> GetAccessibleFromVariant(
IAccessible* parent,
VARIANT* var);
static HRESULT QueryIAccessible2(IAccessible* accessible,
@@ -90,13 +89,12 @@ class AccessibilityWinBrowserTest : public ContentBrowserTest {
const std::wstring& expected_name,
int32_t depth,
bool* found);
- static void CheckTextAtOffset(
- base::win::ScopedComPtr<IAccessibleText>& object,
- LONG offset,
- IA2TextBoundaryType boundary_type,
- LONG expected_start_offset,
- LONG expected_end_offset,
- const std::wstring& expected_text);
+ static void CheckTextAtOffset(Microsoft::WRL::ComPtr<IAccessibleText>& object,
+ LONG offset,
+ IA2TextBoundaryType boundary_type,
+ LONG expected_start_offset,
+ LONG expected_end_offset,
+ const std::wstring& expected_text);
static std::vector<base::win::ScopedVariant> GetAllAccessibleChildren(
IAccessible* element);
@@ -134,7 +132,7 @@ void AccessibilityWinBrowserTest::ExecuteScript(const std::wstring& script) {
// Loads a page with an input text field and places sample text in it. Also,
// places the caret on the last character.
void AccessibilityWinBrowserTest::SetUpInputField(
- base::win::ScopedComPtr<IAccessibleText>* input_text) {
+ Microsoft::WRL::ComPtr<IAccessibleText>* input_text) {
ASSERT_NE(nullptr, input_text);
LoadInitialAccessibilityTreeFromHtml(std::string("<!DOCTYPE html><html><body>"
"<form><label for='textField'>Browser name:</label>"
@@ -143,12 +141,12 @@ void AccessibilityWinBrowserTest::SetUpInputField(
"'></form></body></html>"));
// Retrieve the IAccessible interface for the web page.
- base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
+ Microsoft::WRL::ComPtr<IAccessible> document(GetRendererAccessible());
std::vector<base::win::ScopedVariant> document_children =
GetAllAccessibleChildren(document.Get());
ASSERT_EQ(1u, document_children.size());
- base::win::ScopedComPtr<IAccessible2> form;
+ Microsoft::WRL::ComPtr<IAccessible2> form;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
.Get(),
@@ -158,7 +156,7 @@ void AccessibilityWinBrowserTest::SetUpInputField(
ASSERT_EQ(2u, form_children.size());
// Find the input text field.
- base::win::ScopedComPtr<IAccessible2> input;
+ Microsoft::WRL::ComPtr<IAccessible2> input;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(form.Get(), form_children[1].AsInput()).Get(),
input.GetAddressOf()));
@@ -186,7 +184,7 @@ void AccessibilityWinBrowserTest::SetUpInputField(
// Loads a page with a textarea text field and places sample text in it. Also,
// places the caret on the last character.
void AccessibilityWinBrowserTest::SetUpTextareaField(
- base::win::ScopedComPtr<IAccessibleText>* textarea_text) {
+ Microsoft::WRL::ComPtr<IAccessibleText>* textarea_text) {
ASSERT_NE(nullptr, textarea_text);
LoadInitialAccessibilityTreeFromHtml(std::string("<!DOCTYPE html><html><body>"
"<textarea id='textField' rows='3' cols='60'>") +
@@ -194,12 +192,12 @@ void AccessibilityWinBrowserTest::SetUpTextareaField(
"</textarea></body></html>"));
// Retrieve the IAccessible interface for the web page.
- base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
+ Microsoft::WRL::ComPtr<IAccessible> document(GetRendererAccessible());
std::vector<base::win::ScopedVariant> document_children =
GetAllAccessibleChildren(document.Get());
ASSERT_EQ(1u, document_children.size());
- base::win::ScopedComPtr<IAccessible2> section;
+ Microsoft::WRL::ComPtr<IAccessible2> section;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
.Get(),
@@ -209,7 +207,7 @@ void AccessibilityWinBrowserTest::SetUpTextareaField(
ASSERT_EQ(1u, section_children.size());
// Find the textarea text field.
- base::win::ScopedComPtr<IAccessible2> textarea;
+ Microsoft::WRL::ComPtr<IAccessible2> textarea;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(section.Get(), section_children[0].AsInput())
.Get(),
@@ -237,7 +235,7 @@ void AccessibilityWinBrowserTest::SetUpTextareaField(
// Loads a page with a paragraph of sample text.
void AccessibilityWinBrowserTest::SetUpSampleParagraph(
- base::win::ScopedComPtr<IAccessibleText>* accessible_text,
+ Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text,
ui::AXMode accessibility_mode) {
LoadInitialAccessibilityTreeFromHtml(
"<!DOCTYPE html><html>"
@@ -254,7 +252,7 @@ void AccessibilityWinBrowserTest::SetUpSampleParagraph(
// Loads a page with a paragraph of sample text which is below the
// bottom of the screen.
void AccessibilityWinBrowserTest::SetUpSampleParagraphWithScroll(
- base::win::ScopedComPtr<IAccessibleText>* accessible_text,
+ Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text,
ui::AXMode accessibility_mode) {
LoadInitialAccessibilityTreeFromHtml(
"<!DOCTYPE html><html>"
@@ -269,16 +267,16 @@ void AccessibilityWinBrowserTest::SetUpSampleParagraphWithScroll(
}
void AccessibilityWinBrowserTest::SetUpSampleParagraphHelper(
- base::win::ScopedComPtr<IAccessibleText>* accessible_text) {
+ Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text) {
ASSERT_NE(nullptr, accessible_text);
// Retrieve the IAccessible interface for the web page.
- base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
+ Microsoft::WRL::ComPtr<IAccessible> document(GetRendererAccessible());
std::vector<base::win::ScopedVariant> document_children =
GetAllAccessibleChildren(document.Get());
ASSERT_EQ(1u, document_children.size());
- base::win::ScopedComPtr<IAccessible2> paragraph;
+ Microsoft::WRL::ComPtr<IAccessible2> paragraph;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
.Get(),
@@ -291,11 +289,10 @@ void AccessibilityWinBrowserTest::SetUpSampleParagraphHelper(
// Static helpers ------------------------------------------------
-base::win::ScopedComPtr<IAccessible>
-AccessibilityWinBrowserTest::GetAccessibleFromVariant(
- IAccessible* parent,
- VARIANT* var) {
- base::win::ScopedComPtr<IAccessible> ptr;
+Microsoft::WRL::ComPtr<IAccessible>
+AccessibilityWinBrowserTest::GetAccessibleFromVariant(IAccessible* parent,
+ VARIANT* var) {
+ Microsoft::WRL::ComPtr<IAccessible> ptr;
switch (V_VT(var)) {
case VT_DISPATCH: {
IDispatch* dispatch = V_DISPATCH(var);
@@ -305,7 +302,7 @@ AccessibilityWinBrowserTest::GetAccessibleFromVariant(
}
case VT_I4: {
- base::win::ScopedComPtr<IDispatch> dispatch;
+ Microsoft::WRL::ComPtr<IDispatch> dispatch;
HRESULT hr = parent->get_accChild(*var, dispatch.GetAddressOf());
EXPECT_TRUE(SUCCEEDED(hr));
if (dispatch.Get())
@@ -321,7 +318,7 @@ HRESULT AccessibilityWinBrowserTest::QueryIAccessible2(
IAccessible2** accessible2) {
// IA2 Spec dictates that IServiceProvider should be used instead of
// QueryInterface when retrieving IAccessible2.
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf());
return SUCCEEDED(hr) ?
service_provider->QueryService(IID_IAccessible2, accessible2) : hr;
@@ -360,7 +357,7 @@ void AccessibilityWinBrowserTest::FindNodeInAccessibilityTree(
std::vector<base::win::ScopedVariant> children = GetAllAccessibleChildren(
node);
for (size_t i = 0; i < children.size(); ++i) {
- base::win::ScopedComPtr<IAccessible> child_accessible(
+ Microsoft::WRL::ComPtr<IAccessible> child_accessible(
GetAccessibleFromVariant(node, children[i].AsInput()));
if (child_accessible) {
FindNodeInAccessibilityTree(
@@ -375,7 +372,7 @@ void AccessibilityWinBrowserTest::FindNodeInAccessibilityTree(
// Ensures that the text and the start and end offsets retrieved using
// get_textAtOffset match the expected values.
void AccessibilityWinBrowserTest::CheckTextAtOffset(
- base::win::ScopedComPtr<IAccessibleText>& object,
+ Microsoft::WRL::ComPtr<IAccessibleText>& object,
LONG offset,
IA2TextBoundaryType boundary_type,
LONG expected_start_offset,
@@ -574,7 +571,7 @@ void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleRole(
void AccessibilityWinBrowserTest::AccessibleChecker::CheckIA2Role(
IAccessible* accessible) {
- base::win::ScopedComPtr<IAccessible2> accessible2;
+ Microsoft::WRL::ComPtr<IAccessible2> accessible2;
HRESULT hr = QueryIAccessible2(accessible, accessible2.GetAddressOf());
ASSERT_EQ(S_OK, hr);
long ia2_role = 0;
@@ -640,7 +637,7 @@ void AccessibilityWinBrowserTest::AccessibleChecker::CheckAccessibleChildren(
child_checker != children_.end()
&& child != obtained_children.end();
++child_checker, ++child) {
- base::win::ScopedComPtr<IAccessible> child_accessible(
+ Microsoft::WRL::ComPtr<IAccessible> child_accessible(
GetAccessibleFromVariant(parent, child->AsInput()));
ASSERT_TRUE(child_accessible.Get());
(*child_checker)->CheckAccessible(child_accessible.Get());
@@ -847,7 +844,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
// Focus the document accessible. This will un-focus the current node.
waiter.reset(new AccessibilityNotificationWaiter(
shell()->web_contents(), ui::kAXModeComplete, ui::AX_EVENT_BLUR));
- base::win::ScopedComPtr<IAccessible> document_accessible(
+ Microsoft::WRL::ComPtr<IAccessible> document_accessible(
GetRendererAccessible());
ASSERT_NE(document_accessible.Get(), reinterpret_cast<IAccessible*>(NULL));
base::win::ScopedVariant childid_self(CHILDID_SELF);
@@ -913,7 +910,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
CHECK(window_tree_host);
HWND hwnd = window_tree_host->GetAcceleratedWidget();
CHECK(hwnd);
- base::win::ScopedComPtr<IAccessible> browser_accessible;
+ Microsoft::WRL::ComPtr<IAccessible> browser_accessible;
HRESULT hr = AccessibleObjectFromWindow(
hwnd, OBJID_WINDOW, IID_IAccessible,
reinterpret_cast<void**>(browser_accessible.GetAddressOf()));
@@ -931,12 +928,12 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
"<body><input type='checkbox'></body>");
// Get the IAccessible object for the document.
- base::win::ScopedComPtr<IAccessible> document_accessible(
+ Microsoft::WRL::ComPtr<IAccessible> document_accessible(
GetRendererAccessible());
ASSERT_NE(document_accessible.Get(), reinterpret_cast<IAccessible*>(NULL));
// Get the ISimpleDOM object for the document.
- base::win::ScopedComPtr<IServiceProvider> service_provider;
+ Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
HRESULT hr = static_cast<IAccessible*>(document_accessible.Get())
->QueryInterface(service_provider.GetAddressOf());
ASSERT_EQ(S_OK, hr);
@@ -944,7 +941,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
0x12e4,
0x11cf,
{0xb6, 0x61, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8}};
- base::win::ScopedComPtr<ISimpleDOMNode> document_isimpledomnode;
+ Microsoft::WRL::ComPtr<ISimpleDOMNode> document_isimpledomnode;
hr = service_provider->QueryService(refguid,
IID_PPV_ARGS(&document_isimpledomnode));
ASSERT_EQ(S_OK, hr);
@@ -964,7 +961,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
node_name.Reset();
node_value.Reset();
- base::win::ScopedComPtr<ISimpleDOMNode> body_isimpledomnode;
+ Microsoft::WRL::ComPtr<ISimpleDOMNode> body_isimpledomnode;
hr = document_isimpledomnode->get_firstChild(
body_isimpledomnode.GetAddressOf());
ASSERT_EQ(S_OK, hr);
@@ -978,7 +975,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
node_name.Reset();
node_value.Reset();
- base::win::ScopedComPtr<ISimpleDOMNode> checkbox_isimpledomnode;
+ Microsoft::WRL::ComPtr<ISimpleDOMNode> checkbox_isimpledomnode;
hr = body_isimpledomnode->get_firstChild(
checkbox_isimpledomnode.GetAddressOf());
ASSERT_EQ(S_OK, hr);
@@ -1009,7 +1006,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestRoleGroup) {
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestCharacterExtentsWithInvalidArguments) {
- base::win::ScopedComPtr<IAccessibleText> paragraph_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> paragraph_text;
SetUpSampleParagraph(&paragraph_text);
LONG invalid_offset = -3;
@@ -1053,7 +1050,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestCharacterExtents) {
- base::win::ScopedComPtr<IAccessibleText> paragraph_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> paragraph_text;
SetUpSampleParagraph(&paragraph_text);
const LONG newline_offset = 46;
@@ -1109,7 +1106,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestCharacterExtents) {
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestCharacterExtentsWithAccessibilityModeChange) {
- base::win::ScopedComPtr<IAccessibleText> paragraph_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> paragraph_text;
SetUpSampleParagraph(&paragraph_text, ui::AXMode::kNativeAPIs |
ui::AXMode::kWebContents |
ui::AXMode::kScreenReader);
@@ -1140,9 +1137,9 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestScrollToPoint) {
- base::win::ScopedComPtr<IAccessibleText> accessible_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> accessible_text;
SetUpSampleParagraphWithScroll(&accessible_text);
- base::win::ScopedComPtr<IAccessible2> paragraph;
+ Microsoft::WRL::ComPtr<IAccessible2> paragraph;
ASSERT_HRESULT_SUCCEEDED(
accessible_text.CopyTo(IID_PPV_ARGS(&paragraph)));
@@ -1174,7 +1171,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestScrollToPoint) {
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestSetCaretOffset) {
- base::win::ScopedComPtr<IAccessibleText> input_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
LONG caret_offset = 0;
@@ -1197,7 +1194,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestSetCaretOffset) {
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestMultiLineSetCaretOffset) {
- base::win::ScopedComPtr<IAccessibleText> textarea_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
SetUpTextareaField(&textarea_text);
LONG caret_offset = 0;
@@ -1219,7 +1216,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestSetSelection) {
- base::win::ScopedComPtr<IAccessibleText> input_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
LONG start_offset, end_offset;
@@ -1258,7 +1255,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestSetSelection) {
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestMultiLineSetSelection) {
- base::win::ScopedComPtr<IAccessibleText> textarea_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
SetUpTextareaField(&textarea_text);
LONG start_offset, end_offset;
@@ -1299,7 +1296,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestMultiLineSetSelection) {
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestStaticTextSetSelection) {
- base::win::ScopedComPtr<IAccessibleText> paragraph_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> paragraph_text;
SetUpSampleParagraph(&paragraph_text);
LONG n_characters;
@@ -1337,7 +1334,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestTextAtOffsetWithInvalidArguments) {
- base::win::ScopedComPtr<IAccessibleText> input_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
HRESULT hr = input_text->get_textAtOffset(
0, IA2_TEXT_BOUNDARY_CHAR, NULL, NULL, NULL);
@@ -1430,7 +1427,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestMultiLineTextAtOffsetWithInvalidArguments) {
- base::win::ScopedComPtr<IAccessibleText> textarea_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
SetUpTextareaField(&textarea_text);
HRESULT hr = textarea_text->get_textAtOffset(
0, IA2_TEXT_BOUNDARY_CHAR, NULL, NULL, NULL);
@@ -1523,7 +1520,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestTextAtOffsetWithBoundaryCharacter) {
- base::win::ScopedComPtr<IAccessibleText> input_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
for (LONG offset = 0; offset < CONTENTS_LENGTH; ++offset) {
std::wstring expected_text(1, INPUT_CONTENTS[offset]);
@@ -1547,7 +1544,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestMultiLineTextAtOffsetWithBoundaryCharacter) {
- base::win::ScopedComPtr<IAccessibleText> textarea_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
SetUpTextareaField(&textarea_text);
for (LONG offset = 0; offset < CONTENTS_LENGTH; ++offset) {
std::wstring expected_text(1, TEXTAREA_CONTENTS[offset]);
@@ -1571,7 +1568,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestTextAtOffsetWithBoundaryWord) {
- base::win::ScopedComPtr<IAccessibleText> input_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
// Trailing punctuation should be included as part of the previous word.
@@ -1643,7 +1640,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestMultiLineTextAtOffsetWithBoundaryWord) {
- base::win::ScopedComPtr<IAccessibleText> textarea_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
SetUpTextareaField(&textarea_text);
// Trailing punctuation should be included as part of the previous word.
@@ -1715,7 +1712,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestStaticTextAtOffsetWithBoundaryWord) {
- base::win::ScopedComPtr<IAccessibleText> paragraph_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> paragraph_text;
SetUpSampleParagraph(&paragraph_text);
base::string16 embedded_character(
1, BrowserAccessibilityComWin::kEmbeddedCharacter);
@@ -1755,7 +1752,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestTextAtOffsetWithBoundarySentence) {
- base::win::ScopedComPtr<IAccessibleText> input_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
// Sentence navigation is not currently implemented.
@@ -1770,7 +1767,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestMultiLineTextAtOffsetWithBoundarySentence) {
- base::win::ScopedComPtr<IAccessibleText> textarea_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
SetUpTextareaField(&textarea_text);
// Sentence navigation is not currently implemented.
@@ -1785,7 +1782,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestTextAtOffsetWithBoundaryLine) {
- base::win::ScopedComPtr<IAccessibleText> input_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
// Single line text fields should return the whole text.
@@ -1801,7 +1798,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestMultiLineTextAtOffsetWithBoundaryLine) {
- base::win::ScopedComPtr<IAccessibleText> textarea_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
SetUpTextareaField(&textarea_text);
CheckTextAtOffset(textarea_text, 0, IA2_TEXT_BOUNDARY_LINE,
@@ -1828,7 +1825,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestParagraphTextAtOffsetWithBoundaryLine) {
- base::win::ScopedComPtr<IAccessibleText> paragraph_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> paragraph_text;
SetUpSampleParagraph(&paragraph_text);
// There should be two lines in this paragraph.
@@ -1856,7 +1853,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestTextAtOffsetWithBoundaryAll) {
- base::win::ScopedComPtr<IAccessibleText> input_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
SetUpInputField(&input_text);
CheckTextAtOffset(input_text, 0, IA2_TEXT_BOUNDARY_ALL,
@@ -1865,7 +1862,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestMultiLineTextAtOffsetWithBoundaryAll) {
- base::win::ScopedComPtr<IAccessibleText> textarea_text;
+ Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
SetUpTextareaField(&textarea_text);
CheckTextAtOffset(textarea_text, CONTENTS_LENGTH - 1, IA2_TEXT_BOUNDARY_ALL,
@@ -1880,12 +1877,12 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestIAccessibleAction) {
"</body></html>");
// Retrieve the IAccessible interface for the web page.
- base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
+ Microsoft::WRL::ComPtr<IAccessible> document(GetRendererAccessible());
std::vector<base::win::ScopedVariant> document_children =
GetAllAccessibleChildren(document.Get());
ASSERT_EQ(1u, document_children.size());
- base::win::ScopedComPtr<IAccessible2> div;
+ Microsoft::WRL::ComPtr<IAccessible2> div;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
.Get(),
@@ -1894,7 +1891,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestIAccessibleAction) {
GetAllAccessibleChildren(div.Get());
ASSERT_EQ(1u, div_children.size());
- base::win::ScopedComPtr<IAccessible2> image;
+ Microsoft::WRL::ComPtr<IAccessible2> image;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(div.Get(), div_children[0].AsInput()).Get(),
image.GetAddressOf()));
@@ -1902,7 +1899,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestIAccessibleAction) {
ASSERT_HRESULT_SUCCEEDED(image->role(&image_role));
ASSERT_EQ(ROLE_SYSTEM_GRAPHIC, image_role);
- base::win::ScopedComPtr<IAccessibleAction> image_action;
+ Microsoft::WRL::ComPtr<IAccessibleAction> image_action;
ASSERT_HRESULT_SUCCEEDED(image.CopyTo(image_action.GetAddressOf()));
LONG n_actions = 0;
@@ -1978,13 +1975,13 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestAccNavigateInTables) {
"/accessibility/html/table-spans.html"));
waiter.WaitForNotification();
- base::win::ScopedComPtr<IAccessible> document(GetRendererAccessible());
+ Microsoft::WRL::ComPtr<IAccessible> document(GetRendererAccessible());
std::vector<base::win::ScopedVariant> document_children =
GetAllAccessibleChildren(document.Get());
// There are two tables in this test file. Use only the first one.
ASSERT_EQ(2u, document_children.size());
- base::win::ScopedComPtr<IAccessible2> table;
+ Microsoft::WRL::ComPtr<IAccessible2> table;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
.Get(),
@@ -1994,16 +1991,16 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestAccNavigateInTables) {
ASSERT_EQ(ROLE_SYSTEM_TABLE, role);
// Retrieve the first cell.
- base::win::ScopedComPtr<IAccessibleTable2> table2;
- base::win::ScopedComPtr<IUnknown> cell;
- base::win::ScopedComPtr<IAccessible2> cell1;
+ Microsoft::WRL::ComPtr<IAccessibleTable2> table2;
+ Microsoft::WRL::ComPtr<IUnknown> cell;
+ Microsoft::WRL::ComPtr<IAccessible2> cell1;
EXPECT_HRESULT_SUCCEEDED(table.CopyTo(table2.GetAddressOf()));
EXPECT_HRESULT_SUCCEEDED(table2->get_cellAt(0, 0, cell.GetAddressOf()));
EXPECT_HRESULT_SUCCEEDED(cell.CopyTo(cell1.GetAddressOf()));
base::win::ScopedBstr name;
base::win::ScopedVariant childid_self(CHILDID_SELF);
- base::win::ScopedComPtr<IAccessibleTableCell> accessible_cell;
+ Microsoft::WRL::ComPtr<IAccessibleTableCell> accessible_cell;
LONG row_index = -1;
LONG column_index = -1;
EXPECT_HRESULT_SUCCEEDED(cell1->role(&role));
@@ -2026,7 +2023,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestAccNavigateInTables) {
ASSERT_EQ(VT_EMPTY, variant.type());
// Try navigating to the cell in the first row, 2nd column.
- base::win::ScopedComPtr<IAccessible2> cell2;
+ Microsoft::WRL::ComPtr<IAccessible2> cell2;
EXPECT_HRESULT_SUCCEEDED(
cell1->accNavigate(NAVDIR_RIGHT, childid_self, variant.Receive()));
ASSERT_NE(nullptr, V_DISPATCH(variant.AsInput()));
@@ -2046,7 +2043,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestAccNavigateInTables) {
accessible_cell.Reset();
// Try navigating to the cell in the second row, 2nd column.
- base::win::ScopedComPtr<IAccessible2> cell3;
+ Microsoft::WRL::ComPtr<IAccessible2> cell3;
EXPECT_HRESULT_SUCCEEDED(
cell2->accNavigate(NAVDIR_DOWN, childid_self, variant.Receive()));
ASSERT_NE(nullptr, V_DISPATCH(variant.AsInput()));
diff --git a/chromium/content/browser/accessibility/browser_accessibility.cc b/chromium/content/browser/accessibility/browser_accessibility.cc
index 94a64408c4d..eb0ea60865b 100644
--- a/chromium/content/browser/accessibility/browser_accessibility.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility.cc
@@ -49,10 +49,7 @@ bool BrowserAccessibility::PlatformIsLeaf() const {
// implementation details, but we want to expose them as leaves to platform
// accessibility APIs because screen readers might be confused if they find
// any children.
- // Note that if a combo box, search box or text field are not native, they
- // might present a menu of choices using aria-owns which should not be hidden
- // from tree.
- if (IsNativeTextControl() || IsTextOnlyObject())
+ if (IsPlainTextField() || IsTextOnlyObject())
return true;
// Roles whose children are only presentational according to the ARIA and
@@ -140,6 +137,7 @@ BrowserAccessibility* BrowserAccessibility::PlatformGetChild(
bool BrowserAccessibility::PlatformIsChildOfLeaf() const {
BrowserAccessibility* ancestor = InternalGetParent();
+
while (ancestor) {
if (ancestor->PlatformIsLeaf())
return true;
@@ -335,8 +333,9 @@ gfx::Rect BrowserAccessibility::GetFrameBoundsRect() const {
return RelativeToAbsoluteBounds(gfx::RectF(), true);
}
-gfx::Rect BrowserAccessibility::GetPageBoundsRect(bool* offscreen) const {
- return RelativeToAbsoluteBounds(gfx::RectF(), false, offscreen);
+gfx::Rect BrowserAccessibility::GetPageBoundsRect(bool* offscreen,
+ bool clip_bounds) const {
+ return RelativeToAbsoluteBounds(gfx::RectF(), false, offscreen, clip_bounds);
}
gfx::Rect BrowserAccessibility::GetPageBoundsForRange(int start, int len)
@@ -347,7 +346,7 @@ gfx::Rect BrowserAccessibility::GetPageBoundsForRange(int start, int len)
// Standard text fields such as textarea have an embedded div inside them that
// holds all the text.
// TODO(nektar): This is fragile! Replace with code that flattens tree.
- if (IsSimpleTextControl() && InternalChildCount() == 1)
+ if (IsPlainTextField() && InternalChildCount() == 1)
return InternalGetChild(0)->GetPageBoundsForRange(start, len);
if (GetRole() != ui::AX_ROLE_STATIC_TEXT) {
@@ -481,22 +480,20 @@ gfx::Rect BrowserAccessibility::GetScreenBoundsForRange(int start, int len)
base::string16 BrowserAccessibility::GetValue() const {
base::string16 value = GetString16Attribute(ui::AX_ATTR_VALUE);
- // Some screen readers like Jaws and older versions of VoiceOver require a
- // value to be set in text fields with rich content, even though the same
- // information is available on the children.
- if (value.empty() &&
- (IsSimpleTextControl() || IsRichTextControl()) &&
- !IsNativeTextControl())
- value = GetInnerText();
+ // Some screen readers like Jaws and VoiceOver require a value to be set in
+ // text fields with rich content, even though the same information is
+ // available on the children.
+ if (value.empty() && IsRichTextField())
+ return GetInnerText();
return value;
}
BrowserAccessibility* BrowserAccessibility::ApproximateHitTest(
const gfx::Point& point) {
// The best result found that's a child of this object.
- BrowserAccessibility* child_result = NULL;
+ BrowserAccessibility* child_result = nullptr;
// The best result that's an indirect descendant like grandchild, etc.
- BrowserAccessibility* descendant_result = NULL;
+ BrowserAccessibility* descendant_result = nullptr;
// Walk the children recursively looking for the BrowserAccessibility that
// most tightly encloses the specified point. Walk backwards so that in
@@ -537,13 +534,8 @@ BrowserAccessibility* BrowserAccessibility::ApproximateHitTest(
}
void BrowserAccessibility::Destroy() {
- // Allow the object to fire a TextRemoved notification.
- manager()->NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::FromTreeChange,
- ui::AX_EVENT_HIDE,
- this);
- node_ = NULL;
- manager_ = NULL;
+ node_ = nullptr;
+ manager_ = nullptr;
NativeReleaseReference();
}
@@ -727,7 +719,7 @@ bool BrowserAccessibility::HasAction(ui::AXAction action_enum) const {
}
bool BrowserAccessibility::HasCaret() const {
- if (IsSimpleTextControl() && HasIntAttribute(ui::AX_ATTR_TEXT_SEL_START) &&
+ if (IsPlainTextField() && HasIntAttribute(ui::AX_ATTR_TEXT_SEL_START) &&
HasIntAttribute(ui::AX_ATTR_TEXT_SEL_END)) {
return true;
}
@@ -758,47 +750,20 @@ bool BrowserAccessibility::IsClickable() const {
return ui::IsRoleClickable(GetRole());
}
-bool BrowserAccessibility::IsNativeTextControl() const {
- const std::string& html_tag = GetStringAttribute(ui::AX_ATTR_HTML_TAG);
- if (html_tag == "input") {
- std::string input_type;
- if (!GetHtmlAttribute("type", &input_type))
- return true;
- return input_type.empty() || input_type == "email" ||
- input_type == "password" || input_type == "search" ||
- input_type == "tel" || input_type == "text" || input_type == "url" ||
- input_type == "number";
- }
- return html_tag == "textarea";
-}
-
-// In general we should use ui::IsEditField() instead if we want to check for
-// something that has a caret and the user can edit.
-// TODO(aleventhal) this name is confusing because it returns true for combobox,
-// and we should take a look at why a combobox is considered a text control. The
-// ARIA spec says a combobox would contain (but not be) a text field. It looks
-// like a mistake may have been made in that comboboxes have been considered a
-// kind of textbox. Find an appropriate name for this function, and consider
-// returning false for comboboxes it doesn't break existing websites.
-bool BrowserAccessibility::IsSimpleTextControl() const {
- // Time fields, color wells and spinner buttons might also use text fields as
- // constituent parts, but they are not considered text fields as a whole.
- switch (GetRole()) {
- case ui::AX_ROLE_COMBO_BOX:
- case ui::AX_ROLE_SEARCH_BOX:
- return true;
- case ui::AX_ROLE_TEXT_FIELD:
- return !HasState(ui::AX_STATE_RICHLY_EDITABLE);
- default:
- return false;
- }
+bool BrowserAccessibility::IsPlainTextField() const {
+ // We need to check both the role and editable state, because some ARIA text
+ // fields may in fact not be editable, whilst some editable fields might not
+ // have the role.
+ return !HasState(ui::AX_STATE_RICHLY_EDITABLE) &&
+ (GetRole() == ui::AX_ROLE_TEXT_FIELD ||
+ GetRole() == ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX ||
+ GetRole() == ui::AX_ROLE_SEARCH_BOX ||
+ GetBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT));
}
-// Indicates if this object is at the root of a rich edit text control.
-bool BrowserAccessibility::IsRichTextControl() const {
- return HasState(ui::AX_STATE_RICHLY_EDITABLE) &&
- (!PlatformGetParent() ||
- !PlatformGetParent()->HasState(ui::AX_STATE_RICHLY_EDITABLE));
+bool BrowserAccessibility::IsRichTextField() const {
+ return GetBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT) &&
+ HasState(ui::AX_STATE_RICHLY_EDITABLE);
}
bool BrowserAccessibility::HasExplicitlyEmptyName() const {
@@ -834,12 +799,12 @@ std::vector<int> BrowserAccessibility::GetLineStartOffsets() const {
return node()->GetOrComputeLineStartOffsets();
}
-BrowserAccessibility::AXPlatformPositionInstance
+BrowserAccessibilityPosition::AXPositionInstance
BrowserAccessibility::CreatePositionAt(int offset,
ui::AXTextAffinity affinity) const {
DCHECK(manager_);
- return AXPlatformPosition::CreateTextPosition(manager_->ax_tree_id(), GetId(),
- offset, affinity);
+ return BrowserAccessibilityPosition::CreateTextPosition(
+ manager_->ax_tree_id(), GetId(), offset, affinity);
}
base::string16 BrowserAccessibility::GetInnerText() const {
@@ -855,11 +820,12 @@ base::string16 BrowserAccessibility::GetInnerText() const {
gfx::Rect BrowserAccessibility::RelativeToAbsoluteBounds(
gfx::RectF bounds,
bool frame_only,
- bool* offscreen) const {
+ bool* offscreen,
+ bool clip_bounds) const {
const BrowserAccessibility* node = this;
while (node) {
bounds = node->manager()->ax_tree()->RelativeToTreeBounds(
- node->node(), bounds, offscreen);
+ node->node(), bounds, offscreen, clip_bounds);
// On some platforms we need to unapply root scroll offsets.
const BrowserAccessibility* root = node->manager()->GetRoot();
@@ -924,10 +890,18 @@ gfx::NativeWindow BrowserAccessibility::GetTopLevelWidget() {
gfx::NativeViewAccessible BrowserAccessibility::GetParent() {
auto* parent = PlatformGetParent();
- if (!parent)
+ if (parent)
+ return parent->GetNativeViewAccessible();
+
+ if (!manager_)
+ return nullptr;
+
+ BrowserAccessibilityDelegate* delegate =
+ manager_->GetDelegateFromRootManager();
+ if (!delegate)
return nullptr;
- return parent->GetNativeViewAccessible();
+ return delegate->AccessibilityGetNativeViewAccessible();
}
int BrowserAccessibility::GetChildCount() {
diff --git a/chromium/content/browser/accessibility/browser_accessibility.h b/chromium/content/browser/accessibility/browser_accessibility.h
index f94f3f9f036..ac32ed42550 100644
--- a/chromium/content/browser/accessibility/browser_accessibility.h
+++ b/chromium/content/browser/accessibility/browser_accessibility.h
@@ -16,7 +16,7 @@
#include "base/strings/string_split.h"
#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_flags.h"
-#include "content/browser/accessibility/ax_platform_position.h"
+#include "content/browser/accessibility/browser_accessibility_position.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/web/WebAXEnums.h"
#include "ui/accessibility/ax_node.h"
@@ -153,8 +153,9 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
// Returns the bounds of this object in coordinates relative to the
// page (specifically, the top-left corner of the topmost web contents).
// Optionally updates |offscreen| to be true if the element is offscreen
- // within its page.
- gfx::Rect GetPageBoundsRect(bool* offscreen = nullptr) const;
+ // within its page. Clips bounds by default unless |clip_bounds| is false.
+ gfx::Rect GetPageBoundsRect(bool* offscreen = nullptr,
+ bool clip_bounds = true) const;
// Returns the bounds of the given range in coordinates relative to the
// top-left corner of the overall web area. Only valid when the
@@ -169,9 +170,11 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
// absolute bounds, either in page coordinates (when |frameOnly| is
// false), or in frame coordinates (when |frameOnly| is true).
// Updates optional |offscreen| to be true if the node is offscreen.
+ // If |clip_bounds| is set to false, will return unclipped bounds.
virtual gfx::Rect RelativeToAbsoluteBounds(gfx::RectF bounds,
bool frame_only,
- bool* offscreen = nullptr) const;
+ bool* offscreen = nullptr,
+ bool clip_bounds = true) const;
// This is to handle the cases such as ARIA textbox, where the value should
// be calculated from the object's inner text.
@@ -308,10 +311,8 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
bool IsWebAreaForPresentationalIframe() const;
virtual bool IsClickable() const;
- bool IsNativeTextControl() const;
- bool IsSimpleTextControl() const;
- // Indicates if this object is at the root of a rich edit text control.
- bool IsRichTextControl() const;
+ bool IsPlainTextField() const;
+ bool IsRichTextField() const;
// Return true if the accessible name was explicitly set to "" by the author
bool HasExplicitlyEmptyName() const;
@@ -321,7 +322,7 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
std::string ComputeAccessibleNameFromDescendants() const;
// Creates a text position rooted at this object.
- AXPlatformPosition::AXPositionInstance CreatePositionAt(
+ BrowserAccessibilityPosition::AXPositionInstance CreatePositionAt(
int offset,
ui::AXTextAffinity affinity = ui::AX_TEXT_AFFINITY_DOWNSTREAM) const;
@@ -348,8 +349,10 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
bool IsOffscreen() const override;
protected:
- using AXPlatformPositionInstance = AXPlatformPosition::AXPositionInstance;
- using AXPlatformRange = ui::AXRange<AXPlatformPositionInstance::element_type>;
+ using BrowserAccessibilityPositionInstance =
+ BrowserAccessibilityPosition::AXPositionInstance;
+ using AXPlatformRange =
+ ui::AXRange<BrowserAccessibilityPositionInstance::element_type>;
BrowserAccessibility();
diff --git a/chromium/content/browser/accessibility/browser_accessibility_android.cc b/chromium/content/browser/accessibility/browser_accessibility_android.cc
index c38af870950..38bbf3ae464 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_android.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_android.cc
@@ -21,11 +21,6 @@
#include "ui/accessibility/platform/ax_platform_unique_id.h"
#include "ui/accessibility/platform/ax_snapshot_node_android_platform.h"
-namespace aria_strings {
-const char kAriaLivePolite[] = "polite";
-const char kAriaLiveAssertive[] = "assertive";
-}
-
namespace {
// These are enums from android.text.InputType in Java:
@@ -84,7 +79,6 @@ BrowserAccessibilityAndroid* BrowserAccessibilityAndroid::GetFromUniqueId(
BrowserAccessibilityAndroid::BrowserAccessibilityAndroid()
: unique_id_(ui::GetNextAXPlatformNodeUniqueId()) {
g_unique_id_map.Get()[unique_id_] = this;
- first_time_ = true;
}
BrowserAccessibilityAndroid::~BrowserAccessibilityAndroid() {
@@ -97,10 +91,9 @@ bool BrowserAccessibilityAndroid::IsNative() const {
}
void BrowserAccessibilityAndroid::OnLocationChanged() {
- manager()->NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::FromTreeChange,
- ui::AX_EVENT_LOCATION_CHANGED,
- this);
+ auto* manager =
+ static_cast<BrowserAccessibilityManagerAndroid*>(this->manager());
+ manager->FireLocationChanged(this);
}
base::string16 BrowserAccessibilityAndroid::GetValue() const {
@@ -224,11 +217,7 @@ bool BrowserAccessibilityAndroid::IsDismissable() const {
}
bool BrowserAccessibilityAndroid::IsEditableText() const {
- // TODO(dmazzoni): Use utility function in ax_role_properties, and
- // handle different types of combo boxes correctly.
- return GetRole() == ui::AX_ROLE_TEXT_FIELD ||
- GetRole() == ui::AX_ROLE_SEARCH_BOX ||
- GetRole() == ui::AX_ROLE_COMBO_BOX;
+ return IsPlainTextField() || IsRichTextField();
}
bool BrowserAccessibilityAndroid::IsEnabled() const {
@@ -310,10 +299,8 @@ bool BrowserAccessibilityAndroid::IsVisibleToUser() const {
}
bool BrowserAccessibilityAndroid::IsInterestingOnAndroid() const {
- // The root is not interesting if it doesn't have a title, even
- // though it's focusable.
if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA && GetText().empty())
- return false;
+ return true;
// Focusable nodes are always interesting. Note that IsFocusable()
// already skips over things like iframes and child frames that are
@@ -532,8 +519,11 @@ base::string16 BrowserAccessibilityAndroid::GetRoleDescription() const {
case ui::AX_ROLE_COLUMN:
// No role description.
break;
- case ui::AX_ROLE_COMBO_BOX:
- message_id = IDS_AX_ROLE_COMBO_BOX;
+ case ui::AX_ROLE_COMBO_BOX_GROUPING:
+ // No role descripotion.
+ break;
+ case ui::AX_ROLE_COMBO_BOX_MENU_BUTTON:
+ // No role descripotion.
break;
case ui::AX_ROLE_COMPLEMENTARY:
message_id = IDS_AX_ROLE_COMPLEMENTARY;
@@ -804,6 +794,9 @@ base::string16 BrowserAccessibilityAndroid::GetRoleDescription() const {
case ui::AX_ROLE_TEXT_FIELD:
// No role description.
break;
+ case ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX:
+ // No role description.
+ break;
case ui::AX_ROLE_TIME:
message_id = IDS_AX_ROLE_TIME;
break;
@@ -1407,9 +1400,9 @@ bool BrowserAccessibilityAndroid::ShouldExposeValueAsName() const {
return true;
switch (GetRole()) {
- case ui::AX_ROLE_COMBO_BOX:
case ui::AX_ROLE_POP_UP_BUTTON:
case ui::AX_ROLE_TEXT_FIELD:
+ case ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX:
return true;
default:
break;
@@ -1428,39 +1421,6 @@ void BrowserAccessibilityAndroid::OnDataChanged() {
new_value_ = value;
}
}
-
- if (GetRole() == ui::AX_ROLE_ALERT && first_time_) {
- manager()->NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::FromTreeChange,
- ui::AX_EVENT_ALERT,
- this);
- }
-
- base::string16 live;
- if (GetString16Attribute(
- ui::AX_ATTR_CONTAINER_LIVE_STATUS, &live)) {
- NotifyLiveRegionUpdate(live);
- }
-
- first_time_ = false;
-}
-
-void BrowserAccessibilityAndroid::NotifyLiveRegionUpdate(
- base::string16& aria_live) {
- if (!base::EqualsASCII(aria_live, aria_strings::kAriaLivePolite) &&
- !base::EqualsASCII(aria_live, aria_strings::kAriaLiveAssertive))
- return;
-
- base::string16 text = GetText();
- if (cached_text_ != text) {
- if (!text.empty()) {
- manager()->NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::FromTreeChange,
- ui::AX_EVENT_SHOW,
- this);
- }
- cached_text_ = text;
- }
}
int BrowserAccessibilityAndroid::CountChildrenWithRole(ui::AXRole role) const {
diff --git a/chromium/content/browser/accessibility/browser_accessibility_android.h b/chromium/content/browser/accessibility/browser_accessibility_android.h
index 12a2c5baf73..e30bb699a4f 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_android.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_android.h
@@ -155,8 +155,6 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility {
bool IsIframe() const;
bool ShouldExposeValueAsName() const;
- void NotifyLiveRegionUpdate(base::string16& aria_live);
-
int CountChildrenWithRole(ui::AXRole role) const;
static size_t CommonPrefixLength(const base::string16 a,
@@ -167,7 +165,6 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility {
const base::string16 b);
base::string16 cached_text_;
- bool first_time_;
base::string16 old_value_;
base::string16 new_value_;
int32_t unique_id_;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_auralinux.cc b/chromium/content/browser/accessibility/browser_accessibility_auralinux.cc
index 11d709daf89..3921dd72764 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_auralinux.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_auralinux.cc
@@ -4,990 +4,50 @@
#include "content/browser/accessibility/browser_accessibility_auralinux.h"
-#include <stdint.h>
-#include <string.h>
-
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "content/browser/accessibility/browser_accessibility_manager_auralinux.h"
-#include "content/common/accessibility_messages.h"
-#include "ui/accessibility/ax_text_utils.h"
+#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
namespace content {
-static gpointer browser_accessibility_parent_class = NULL;
-
-static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
- BrowserAccessibilityAtk* atk_object) {
- if (!atk_object)
- return NULL;
-
- return atk_object->m_object;
-}
-
-const BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
- const BrowserAccessibility* obj) {
- DCHECK(!obj || obj->IsNative());
- return static_cast<const BrowserAccessibilityAuraLinux*>(obj);
-}
-
BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
BrowserAccessibility* obj) {
DCHECK(!obj || obj->IsNative());
return static_cast<BrowserAccessibilityAuraLinux*>(obj);
}
-//
-// AtkAction interface.
-//
-
-static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
- AtkAction* atk_action) {
- if (!IS_BROWSER_ACCESSIBILITY(atk_action))
- return NULL;
-
- return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_action));
-}
-
-static gboolean browser_accessibility_do_action(AtkAction* atk_action,
- gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), FALSE);
- g_return_val_if_fail(!index, FALSE);
-
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_action);
- if (!obj)
- return FALSE;
-
- obj->manager()->DoDefaultAction(*obj);
-
- return TRUE;
-}
-
-static gint browser_accessibility_get_n_actions(AtkAction* atk_action) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), 0);
-
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_action);
- if (!obj)
- return 0;
-
- return 1;
-}
-
-static const gchar* browser_accessibility_get_description(AtkAction* atk_action,
- gint) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), 0);
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_action);
- if (!obj)
- return 0;
-
- return 0;
-}
-
-static const gchar* browser_accessibility_get_name(AtkAction* atk_action,
- gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), 0);
- g_return_val_if_fail(!index, 0);
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_action);
- if (!obj)
- return nullptr;
-
- int action;
- if (!obj->GetIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB, &action))
- return nullptr;
- base::string16 action_verb = ui::ActionVerbToUnlocalizedString(
- static_cast<ui::AXDefaultActionVerb>(action));
- return base::UTF16ToUTF8(action_verb).c_str();
-}
-
-static const gchar* browser_accessibility_get_keybinding(AtkAction* atk_action,
- gint index) {
- g_return_val_if_fail(ATK_IS_ACTION(atk_action), 0);
- g_return_val_if_fail(!index, 0);
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_action);
- if (!obj)
- return 0;
-
- return obj->GetStringAttribute(ui::AX_ATTR_ACCESS_KEY).c_str();
-}
-
-static void ActionInterfaceInit(AtkActionIface* iface) {
- iface->do_action = browser_accessibility_do_action;
- iface->get_n_actions = browser_accessibility_get_n_actions;
- iface->get_description = browser_accessibility_get_description;
- iface->get_name = browser_accessibility_get_name;
- iface->get_keybinding = browser_accessibility_get_keybinding;
-}
-
-static const GInterfaceInfo ActionInfo = {
- reinterpret_cast<GInterfaceInitFunc>(ActionInterfaceInit), 0, 0};
-
-//
-// AtkComponent interface.
-//
-
-static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
- AtkComponent* atk_component) {
- if (!IS_BROWSER_ACCESSIBILITY(atk_component))
- return NULL;
-
- return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_component));
-}
-
-static AtkObject* browser_accessibility_accessible_at_point(
- AtkComponent* atk_component,
- gint x,
- gint y,
- AtkCoordType coord_type) {
- g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), 0);
-
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_component);
- if (!obj)
- return NULL;
-
- gfx::Point point(x, y);
- BrowserAccessibility* result = obj->manager()->CachingAsyncHitTest(point);
- if (!result)
- return NULL;
-
- AtkObject* atk_result =
- ToBrowserAccessibilityAuraLinux(result)->GetAtkObject();
- g_object_ref(atk_result);
- return atk_result;
-}
-
-static void browser_accessibility_get_extents(AtkComponent* atk_component,
- gint* x,
- gint* y,
- gint* width,
- gint* height,
- AtkCoordType coord_type) {
- g_return_if_fail(ATK_IS_COMPONENT(atk_component));
-
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_component);
- if (!obj)
- return;
-
- gfx::Rect bounds = obj->GetScreenBoundsRect();
- if (x)
- *x = bounds.x();
- if (y)
- *y = bounds.y();
- if (width)
- *width = bounds.width();
- if (height)
- *height = bounds.height();
-}
-
-static gboolean browser_accessibility_grab_focus(AtkComponent* atk_component) {
- g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), FALSE);
-
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_component);
- if (!obj)
- return false;
-
- obj->manager()->SetFocus(*obj);
- return true;
-}
-
-static void ComponentInterfaceInit(AtkComponentIface* iface) {
- iface->ref_accessible_at_point = browser_accessibility_accessible_at_point;
- iface->get_extents = browser_accessibility_get_extents;
- iface->grab_focus = browser_accessibility_grab_focus;
-}
-
-static const GInterfaceInfo ComponentInfo = {
- reinterpret_cast<GInterfaceInitFunc>(ComponentInterfaceInit),
- 0,
- 0};
-
-//
-// AtkDocument interface.
-//
-
-static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
- AtkDocument* atk_doc) {
- if (!IS_BROWSER_ACCESSIBILITY(atk_doc))
- return NULL;
-
- return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_doc));
-}
-
-static const gchar* GetDocumentAttributeValue(
- BrowserAccessibilityAuraLinux* obj,
- const gchar* attribute) {
- if (!g_ascii_strcasecmp(attribute, "DocType"))
- return obj->manager()->GetTreeData().doctype.c_str();
- else if (!g_ascii_strcasecmp(attribute, "MimeType"))
- return obj->manager()->GetTreeData().mimetype.c_str();
- else if (!g_ascii_strcasecmp(attribute, "Title"))
- return obj->manager()->GetTreeData().title.c_str();
- else if (!g_ascii_strcasecmp(attribute, "URI"))
- return obj->manager()->GetTreeData().url.c_str();
-
- return 0;
-}
-
-AtkAttributeSet* SetAtkAttributeSet(AtkAttributeSet* attribute_set,
- const char* name,
- const char* value) {
- AtkAttribute* attribute =
- static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
- attribute->name = g_strdup(name);
- attribute->value = g_strdup(value);
- attribute_set = g_slist_prepend(attribute_set, attribute);
- return attribute_set;
-}
-
-static const gchar* browser_accessibility_get_attribute_value(
- AtkDocument* atk_doc,
- const gchar* attribute) {
- g_return_val_if_fail(ATK_IS_DOCUMENT(atk_doc), 0);
- BrowserAccessibilityAuraLinux* obj = ToBrowserAccessibilityAuraLinux(atk_doc);
- if (!obj)
- return 0;
-
- return GetDocumentAttributeValue(obj, attribute);
-}
-
-static AtkAttributeSet* browser_accessibility_get_attributes(
- AtkDocument* atk_doc) {
- g_return_val_if_fail(ATK_IS_DOCUMENT(atk_doc), 0);
- BrowserAccessibilityAuraLinux* obj = ToBrowserAccessibilityAuraLinux(atk_doc);
- if (!obj)
- return 0;
-
- AtkAttributeSet* attribute_set = 0;
- const gchar* doc_attributes[] = {"DocType", "MimeType", "Title", "URI"};
- const gchar* value = 0;
-
- for (unsigned i = 0; i < G_N_ELEMENTS(doc_attributes); i++) {
- value = GetDocumentAttributeValue(obj, doc_attributes[i]);
- if (value)
- attribute_set =
- SetAtkAttributeSet(attribute_set, doc_attributes[i], value);
- }
-
- return attribute_set;
-}
-
-static void DocumentInterfaceInit(AtkDocumentIface* iface) {
- iface->get_document_attribute_value =
- browser_accessibility_get_attribute_value;
- iface->get_document_attributes = browser_accessibility_get_attributes;
-}
-
-static const GInterfaceInfo DocumentInfo = {
- reinterpret_cast<GInterfaceInitFunc>(DocumentInterfaceInit), 0, 0};
-
-//
-// AtkImage interface.
-//
-
-static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
- AtkImage* atk_img) {
- if (!IS_BROWSER_ACCESSIBILITY(atk_img))
- return NULL;
-
- return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_img));
-}
-
-void GetImagePositionSize(BrowserAccessibilityAuraLinux* obj,
- gint* x,
- gint* y,
- gint* width,
- gint* height) {
- gfx::Rect img_pos_size = obj->GetScreenBoundsRect();
-
- if (x)
- *x = img_pos_size.x();
- if (y)
- *y = img_pos_size.y();
- if (width)
- *width = img_pos_size.width();
- if (height)
- *height = img_pos_size.height();
-}
-
-static void browser_accessibility_get_image_position(AtkImage* atk_img,
- gint* x,
- gint* y,
- AtkCoordType coordType) {
- g_return_if_fail(ATK_IMAGE(atk_img));
- BrowserAccessibilityAuraLinux* obj = ToBrowserAccessibilityAuraLinux(atk_img);
- if (!obj)
- return;
-
- GetImagePositionSize(obj, x, y, nullptr, nullptr);
-}
-
-static const gchar* browser_accessibility_get_image_description(
- AtkImage* atk_img) {
- g_return_val_if_fail(ATK_IMAGE(atk_img), 0);
- BrowserAccessibilityAuraLinux* obj = ToBrowserAccessibilityAuraLinux(atk_img);
- if (!obj)
- return 0;
-
- return obj->GetStringAttribute(ui::AX_ATTR_DESCRIPTION).c_str();
-}
-
-static void browser_accessibility_get_image_size(AtkImage* atk_img,
- gint* width,
- gint* height) {
- g_return_if_fail(ATK_IMAGE(atk_img));
- BrowserAccessibilityAuraLinux* obj = ToBrowserAccessibilityAuraLinux(atk_img);
- if (!obj)
- return;
-
- GetImagePositionSize(obj, nullptr, nullptr, width, height);
-}
-
-void ImageInterfaceInit(AtkImageIface* iface) {
- iface->get_image_position = browser_accessibility_get_image_position;
- iface->get_image_description = browser_accessibility_get_image_description;
- iface->get_image_size = browser_accessibility_get_image_size;
-}
-
-static const GInterfaceInfo ImageInfo = {
- reinterpret_cast<GInterfaceInitFunc>(ImageInterfaceInit), 0, 0};
-
-//
-// AtkValue interface.
-//
-
-static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
- AtkValue* atk_object) {
- if (!IS_BROWSER_ACCESSIBILITY(atk_object))
- return NULL;
-
- return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_object));
-}
-
-static float GetStepAttribute(BrowserAccessibilityAuraLinux* obj) {
- // TODO(shreeram.k): Get Correct value of Step attribute.
- return 1.0;
-}
-
-static void browser_accessibility_get_current_value(AtkValue* atk_value,
- GValue* value) {
- g_return_if_fail(ATK_VALUE(atk_value));
-
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_value);
- if (!obj)
- return;
-
- float float_val;
- if (obj->GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, &float_val)) {
- memset(value, 0, sizeof(*value));
- g_value_init(value, G_TYPE_FLOAT);
- g_value_set_float(value, float_val);
- }
-}
-
-static void browser_accessibility_get_minimum_value(AtkValue* atk_value,
- GValue* value) {
- g_return_if_fail(ATK_VALUE(atk_value));
-
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_value);
- if (!obj)
- return;
-
- float float_val;
- if (obj->GetFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE, &float_val)) {
- memset(value, 0, sizeof(*value));
- g_value_init(value, G_TYPE_FLOAT);
- g_value_set_float(value, float_val);
- }
-}
-
-static void browser_accessibility_get_maximum_value(AtkValue* atk_value,
- GValue* value) {
- g_return_if_fail(ATK_VALUE(atk_value));
-
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_value);
- if (!obj)
- return;
-
- float float_val;
- if (obj->GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE, &float_val)) {
- memset(value, 0, sizeof(*value));
- g_value_init(value, G_TYPE_FLOAT);
- g_value_set_float(value, float_val);
- }
-}
-
-static void browser_accessibility_get_minimum_increment(AtkValue* atk_value,
- GValue* gValue) {
- g_return_if_fail(ATK_VALUE(atk_value));
-
- memset(gValue, 0, sizeof(GValue));
- g_value_init(gValue, G_TYPE_FLOAT);
-
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_value);
- if (!obj)
- return;
-
- g_value_set_float(gValue, GetStepAttribute(obj));
-}
-
-static void ValueInterfaceInit(AtkValueIface* iface) {
- iface->get_current_value = browser_accessibility_get_current_value;
- iface->get_minimum_value = browser_accessibility_get_minimum_value;
- iface->get_maximum_value = browser_accessibility_get_maximum_value;
- iface->get_minimum_increment = browser_accessibility_get_minimum_increment;
-}
-
-static const GInterfaceInfo ValueInfo = {
- reinterpret_cast<GInterfaceInitFunc>(ValueInterfaceInit),
- 0,
- 0};
-
-//
-// AtkObject interface
-//
-
-static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
- AtkObject* atk_object) {
- if (!IS_BROWSER_ACCESSIBILITY(atk_object))
- return NULL;
-
- return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_object));
-}
-
-static const gchar* browser_accessibility_get_name(AtkObject* atk_object) {
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_object);
- if (!obj)
- return NULL;
-
- if (obj->GetStringAttribute(ui::AX_ATTR_NAME).empty() &&
- !obj->HasExplicitlyEmptyName())
- return NULL;
-
- return obj->GetStringAttribute(ui::AX_ATTR_NAME).c_str();
-}
-
-static const gchar* browser_accessibility_get_description(
- AtkObject* atk_object) {
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_object);
- if (!obj)
- return NULL;
-
- return obj->GetStringAttribute(ui::AX_ATTR_DESCRIPTION).c_str();
-}
-
-static AtkObject* browser_accessibility_get_parent(AtkObject* atk_object) {
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_object);
- if (!obj)
- return NULL;
- if (obj->PlatformGetParent())
- return ToBrowserAccessibilityAuraLinux(obj->PlatformGetParent())
- ->GetAtkObject();
-
- BrowserAccessibilityManagerAuraLinux* manager =
- static_cast<BrowserAccessibilityManagerAuraLinux*>(obj->manager());
- return manager->parent_object();
-}
-
-static gint browser_accessibility_get_n_children(AtkObject* atk_object) {
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_object);
- if (!obj)
- return 0;
-
- return obj->PlatformChildCount();
-}
-
-static AtkObject* browser_accessibility_ref_child(AtkObject* atk_object,
- gint index) {
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_object);
- if (!obj)
- return NULL;
-
- if (index < 0 || index >= static_cast<gint>(obj->PlatformChildCount()))
- return NULL;
-
- AtkObject* result = ToBrowserAccessibilityAuraLinux(
- obj->InternalGetChild(index))->GetAtkObject();
- g_object_ref(result);
- return result;
-}
-
-static gint browser_accessibility_get_index_in_parent(AtkObject* atk_object) {
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_object);
- if (!obj)
- return 0;
- return obj->GetIndexInParent();
-}
-
-static AtkAttributeSet* browser_accessibility_get_attributes(
- AtkObject* atk_object) {
- return NULL;
-}
-
-static AtkRole browser_accessibility_get_role(AtkObject* atk_object) {
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_object);
- if (!obj)
- return ATK_ROLE_INVALID;
- return obj->atk_role();
-}
-
-static AtkStateSet* browser_accessibility_ref_state_set(AtkObject* atk_object) {
- BrowserAccessibilityAuraLinux* obj =
- ToBrowserAccessibilityAuraLinux(atk_object);
- if (!obj)
- return NULL;
- AtkStateSet* state_set = ATK_OBJECT_CLASS(browser_accessibility_parent_class)
- ->ref_state_set(atk_object);
- int32_t state = obj->GetState();
-
- if (state & (1 << ui::AX_STATE_FOCUSABLE))
- atk_state_set_add_state(state_set, ATK_STATE_FOCUSABLE);
- if (obj->manager()->GetFocus() == obj)
- atk_state_set_add_state(state_set, ATK_STATE_FOCUSED);
-
- switch (obj->GetIntAttribute(ui::AX_ATTR_RESTRICTION)) {
- case ui::AX_RESTRICTION_DISABLED:
- break;
- case ui::AX_RESTRICTION_READ_ONLY:
-// The following would require ATK 2.16 or later, which many
-// systems do not have. Since we aren't officially supporting ATK
-// it's best to leave this out rather than break people's builds:
-#if defined(ATK_CHECK_VERSION)
-#if ATK_CHECK_VERSION(2, 16, 0)
- atk_state_set_add_state(state_set, ATK_STATE_READ_ONLY);
-#endif
-#endif
- break;
- default:
- atk_state_set_add_state(state_set, ATK_STATE_ENABLED);
- break;
- }
-
- return state_set;
-}
-
-static AtkRelationSet* browser_accessibility_ref_relation_set(
- AtkObject* atk_object) {
- AtkRelationSet* relation_set =
- ATK_OBJECT_CLASS(browser_accessibility_parent_class)
- ->ref_relation_set(atk_object);
- return relation_set;
-}
-
-//
-// The rest of the BrowserAccessibilityAuraLinux code, not specific to one
-// of the Atk* interfaces.
-//
-
-static void browser_accessibility_init(AtkObject* atk_object, gpointer data) {
- if (ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize) {
- ATK_OBJECT_CLASS(browser_accessibility_parent_class)
- ->initialize(atk_object, data);
- }
-
- BROWSER_ACCESSIBILITY(atk_object)->m_object =
- reinterpret_cast<BrowserAccessibilityAuraLinux*>(data);
-}
-
-static void browser_accessibility_finalize(GObject* atk_object) {
- G_OBJECT_CLASS(browser_accessibility_parent_class)->finalize(atk_object);
-}
-
-static void browser_accessibility_class_init(AtkObjectClass* klass) {
- GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
- browser_accessibility_parent_class = g_type_class_peek_parent(klass);
-
- gobject_class->finalize = browser_accessibility_finalize;
- klass->initialize = browser_accessibility_init;
- klass->get_name = browser_accessibility_get_name;
- klass->get_description = browser_accessibility_get_description;
- klass->get_parent = browser_accessibility_get_parent;
- klass->get_n_children = browser_accessibility_get_n_children;
- klass->ref_child = browser_accessibility_ref_child;
- klass->get_role = browser_accessibility_get_role;
- klass->ref_state_set = browser_accessibility_ref_state_set;
- klass->get_index_in_parent = browser_accessibility_get_index_in_parent;
- klass->get_attributes = browser_accessibility_get_attributes;
- klass->ref_relation_set = browser_accessibility_ref_relation_set;
-}
-
-GType browser_accessibility_get_type() {
- static volatile gsize type_volatile = 0;
-
-#if !GLIB_CHECK_VERSION(2, 36, 0)
- g_type_init();
-#endif
-
- if (g_once_init_enter(&type_volatile)) {
- static const GTypeInfo tinfo = {
- sizeof(BrowserAccessibilityAtkClass),
- (GBaseInitFunc)0,
- (GBaseFinalizeFunc)0,
- (GClassInitFunc)browser_accessibility_class_init,
- (GClassFinalizeFunc)0,
- 0, /* class data */
- sizeof(BrowserAccessibilityAtk), /* instance size */
- 0, /* nb preallocs */
- (GInstanceInitFunc)0,
- 0 /* value table */
- };
-
- GType type = g_type_register_static(ATK_TYPE_OBJECT, "BrowserAccessibility",
- &tinfo, GTypeFlags(0));
- g_once_init_leave(&type_volatile, type);
- }
-
- return type_volatile;
-}
-
-static const char* GetUniqueAccessibilityTypeName(int interface_mask) {
- // 20 characters is enough for "Chrome%x" with any integer value.
- static char name[20];
- snprintf(name, sizeof(name), "Chrome%x", interface_mask);
- return name;
-}
-
-enum AtkInterfaces {
- ATK_ACTION_INTERFACE,
- ATK_COMPONENT_INTERFACE,
- ATK_DOCUMENT_INTERFACE,
- ATK_EDITABLE_TEXT_INTERFACE,
- ATK_HYPERLINK_INTERFACE,
- ATK_HYPERTEXT_INTERFACE,
- ATK_IMAGE_INTERFACE,
- ATK_SELECTION_INTERFACE,
- ATK_TABLE_INTERFACE,
- ATK_TEXT_INTERFACE,
- ATK_VALUE_INTERFACE,
-};
-
-static int GetInterfaceMaskFromObject(BrowserAccessibilityAuraLinux* obj) {
- int interface_mask = 0;
-
- // Component interface is always supported.
- interface_mask |= 1 << ATK_COMPONENT_INTERFACE;
-
- // Action interface is basic one. It just relays on executing default action
- // for each object.
- interface_mask |= 1 << ATK_ACTION_INTERFACE;
-
- // Value Interface
- int role = obj->GetRole();
- if (role == ui::AX_ROLE_PROGRESS_INDICATOR ||
- role == ui::AX_ROLE_SCROLL_BAR || role == ui::AX_ROLE_SLIDER) {
- interface_mask |= 1 << ATK_VALUE_INTERFACE;
- }
-
- // Document Interface
- if (role == ui::AX_ROLE_DOCUMENT || role == ui::AX_ROLE_ROOT_WEB_AREA ||
- role == ui::AX_ROLE_WEB_AREA)
- interface_mask |= 1 << ATK_DOCUMENT_INTERFACE;
-
- // Image Interface
- if (role == ui::AX_ROLE_IMAGE || role == ui::AX_ROLE_IMAGE_MAP)
- interface_mask |= 1 << ATK_IMAGE_INTERFACE;
-
- return interface_mask;
-}
-
-static GType GetAccessibilityTypeFromObject(
- BrowserAccessibilityAuraLinux* obj) {
- static const GTypeInfo type_info = {
- sizeof(BrowserAccessibilityAtkClass),
- (GBaseInitFunc)0,
- (GBaseFinalizeFunc)0,
- (GClassInitFunc)0,
- (GClassFinalizeFunc)0,
- 0, /* class data */
- sizeof(BrowserAccessibilityAtk), /* instance size */
- 0, /* nb preallocs */
- (GInstanceInitFunc)0,
- 0 /* value table */
- };
-
- int interface_mask = GetInterfaceMaskFromObject(obj);
- const char* atk_type_name = GetUniqueAccessibilityTypeName(interface_mask);
- GType type = g_type_from_name(atk_type_name);
- if (type)
- return type;
-
- type = g_type_register_static(BROWSER_ACCESSIBILITY_TYPE, atk_type_name,
- &type_info, GTypeFlags(0));
- if (interface_mask & (1 << ATK_ACTION_INTERFACE))
- g_type_add_interface_static(type, ATK_TYPE_ACTION, &ActionInfo);
- if (interface_mask & (1 << ATK_COMPONENT_INTERFACE))
- g_type_add_interface_static(type, ATK_TYPE_COMPONENT, &ComponentInfo);
- if (interface_mask & (1 << ATK_DOCUMENT_INTERFACE))
- g_type_add_interface_static(type, ATK_TYPE_DOCUMENT, &DocumentInfo);
- if (interface_mask & (1 << ATK_IMAGE_INTERFACE))
- g_type_add_interface_static(type, ATK_TYPE_IMAGE, &ImageInfo);
- if (interface_mask & (1 << ATK_VALUE_INTERFACE))
- g_type_add_interface_static(type, ATK_TYPE_VALUE, &ValueInfo);
-
- return type;
-}
-
-BrowserAccessibilityAtk* browser_accessibility_new(
- BrowserAccessibilityAuraLinux* obj) {
- #if !GLIB_CHECK_VERSION(2, 36, 0)
- static bool first_time = true;
- if (first_time) {
- g_type_init();
- first_time = false;
- }
- #endif
-
- GType type = GetAccessibilityTypeFromObject(obj);
- AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0));
-
- atk_object_initialize(atk_object, obj);
-
- return BROWSER_ACCESSIBILITY(atk_object);
-}
-
-void browser_accessibility_detach(BrowserAccessibilityAtk* atk_object) {
- atk_object->m_object = NULL;
-}
-
// static
BrowserAccessibility* BrowserAccessibility::Create() {
return new BrowserAccessibilityAuraLinux();
}
-BrowserAccessibilityAuraLinux::BrowserAccessibilityAuraLinux()
- : atk_object_(NULL) {
+BrowserAccessibilityAuraLinux::BrowserAccessibilityAuraLinux() {
+ node_ = static_cast<ui::AXPlatformNodeAuraLinux*>(
+ ui::AXPlatformNode::Create(this));
}
BrowserAccessibilityAuraLinux::~BrowserAccessibilityAuraLinux() {
- browser_accessibility_detach(BROWSER_ACCESSIBILITY(atk_object_));
- if (atk_object_)
- g_object_unref(atk_object_);
+ DCHECK(node_);
+ node_->Destroy();
+}
+
+ui::AXPlatformNodeAuraLinux* BrowserAccessibilityAuraLinux::GetNode() const {
+ return node_;
}
-AtkObject* BrowserAccessibilityAuraLinux::GetAtkObject() const {
- if (!G_IS_OBJECT(atk_object_))
- return NULL;
- return atk_object_;
+gfx::NativeViewAccessible
+BrowserAccessibilityAuraLinux::GetNativeViewAccessible() {
+ DCHECK(node_);
+ return node_->GetNativeViewAccessible();
}
void BrowserAccessibilityAuraLinux::OnDataChanged() {
BrowserAccessibility::OnDataChanged();
- InitRoleAndState();
- if (atk_object_) {
- // If the object's role changes and that causes its
- // interface mask to change, we need to create a new
- // AtkObject for it.
- int interface_mask = GetInterfaceMaskFromObject(this);
- if (interface_mask != interface_mask_) {
- g_object_unref(atk_object_);
- atk_object_ = NULL;
- }
- }
-
- if (!atk_object_) {
- interface_mask_ = GetInterfaceMaskFromObject(this);
- atk_object_ = ATK_OBJECT(browser_accessibility_new(this));
- if (this->PlatformGetParent()) {
- atk_object_set_parent(atk_object_, ToBrowserAccessibilityAuraLinux(
- this->PlatformGetParent())
- ->GetAtkObject());
- }
- }
+ DCHECK(node_);
+ node_->DataChanged();
}
bool BrowserAccessibilityAuraLinux::IsNative() const {
return true;
}
-void BrowserAccessibilityAuraLinux::InitRoleAndState() {
- switch (GetRole()) {
- case ui::AX_ROLE_DOCUMENT:
- case ui::AX_ROLE_ROOT_WEB_AREA:
- case ui::AX_ROLE_WEB_AREA:
- atk_role_ = ATK_ROLE_DOCUMENT_WEB;
- break;
- case ui::AX_ROLE_ALERT:
- case ui::AX_ROLE_ALERT_DIALOG:
- atk_role_ = ATK_ROLE_ALERT;
- break;
- case ui::AX_ROLE_APPLICATION:
- atk_role_ = ATK_ROLE_APPLICATION;
- break;
- case ui::AX_ROLE_BUTTON:
- atk_role_ = ATK_ROLE_PUSH_BUTTON;
- break;
- case ui::AX_ROLE_AUDIO:
-#if defined(ATK_CHECK_VERSION)
-#if ATK_CHECK_VERSION(2, 12, 0)
- atk_role_ = ATK_ROLE_AUDIO;
-#else
- atk_role_ = ATK_ROLE_SECTION;
-#endif
-#else
- atk_role_ = ATK_ROLE_SECTION;
-#endif
- break;
- case ui::AX_ROLE_CANVAS:
- atk_role_ = ATK_ROLE_CANVAS;
- break;
- case ui::AX_ROLE_CAPTION:
- atk_role_ = ATK_ROLE_CAPTION;
- break;
- case ui::AX_ROLE_CHECK_BOX:
- atk_role_ = ATK_ROLE_CHECK_BOX;
- break;
- case ui::AX_ROLE_COLOR_WELL:
- atk_role_ = ATK_ROLE_COLOR_CHOOSER;
- break;
- case ui::AX_ROLE_COLUMN_HEADER:
- atk_role_ = ATK_ROLE_COLUMN_HEADER;
- break;
- case ui::AX_ROLE_COMBO_BOX:
- atk_role_ = ATK_ROLE_COMBO_BOX;
- break;
- case ui::AX_ROLE_DATE:
- case ui::AX_ROLE_DATE_TIME:
- atk_role_ = ATK_ROLE_DATE_EDITOR;
- break;
- case ui::AX_ROLE_DIALOG:
- atk_role_ = ATK_ROLE_DIALOG;
- break;
- case ui::AX_ROLE_GENERIC_CONTAINER:
- case ui::AX_ROLE_GROUP:
- atk_role_ = ATK_ROLE_SECTION;
- break;
- case ui::AX_ROLE_FORM:
- atk_role_ = ATK_ROLE_FORM;
- break;
- case ui::AX_ROLE_IMAGE:
- atk_role_ = ATK_ROLE_IMAGE;
- break;
- case ui::AX_ROLE_IMAGE_MAP:
- atk_role_ = ATK_ROLE_IMAGE_MAP;
- break;
- case ui::AX_ROLE_LABEL_TEXT:
- atk_role_ = ATK_ROLE_LABEL;
- break;
- case ui::AX_ROLE_LINK:
- atk_role_ = ATK_ROLE_LINK;
- break;
- case ui::AX_ROLE_LIST:
- atk_role_ = ATK_ROLE_LIST;
- break;
- case ui::AX_ROLE_LIST_BOX:
- atk_role_ = ATK_ROLE_LIST_BOX;
- break;
- case ui::AX_ROLE_LIST_ITEM:
- atk_role_ = ATK_ROLE_LIST_ITEM;
- break;
- case ui::AX_ROLE_MENU:
- atk_role_ = ATK_ROLE_MENU;
- break;
- case ui::AX_ROLE_MENU_BAR:
- atk_role_ = ATK_ROLE_MENU_BAR;
- break;
- case ui::AX_ROLE_MENU_ITEM:
- atk_role_ = ATK_ROLE_MENU_ITEM;
- break;
- case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
- atk_role_ = ATK_ROLE_CHECK_MENU_ITEM;
- break;
- case ui::AX_ROLE_MENU_ITEM_RADIO:
- atk_role_ = ATK_ROLE_RADIO_MENU_ITEM;
- break;
- case ui::AX_ROLE_METER:
- atk_role_ = ATK_ROLE_PROGRESS_BAR;
- break;
- case ui::AX_ROLE_PARAGRAPH:
- atk_role_ = ATK_ROLE_PARAGRAPH;
- break;
- case ui::AX_ROLE_RADIO_BUTTON:
- atk_role_ = ATK_ROLE_RADIO_BUTTON;
- break;
- case ui::AX_ROLE_ROW_HEADER:
- atk_role_ = ATK_ROLE_ROW_HEADER;
- break;
- case ui::AX_ROLE_SCROLL_BAR:
- atk_role_ = ATK_ROLE_SCROLL_BAR;
- break;
- case ui::AX_ROLE_SLIDER:
- atk_role_ = ATK_ROLE_SLIDER;
- break;
- case ui::AX_ROLE_SPIN_BUTTON:
- atk_role_ = ATK_ROLE_SPIN_BUTTON;
- break;
- case ui::AX_ROLE_SPLITTER:
- atk_role_ = ATK_ROLE_SEPARATOR;
- break;
- case ui::AX_ROLE_STATIC_TEXT:
- atk_role_ = ATK_ROLE_TEXT;
- break;
- case ui::AX_ROLE_STATUS:
- atk_role_ = ATK_ROLE_STATUSBAR;
- break;
- case ui::AX_ROLE_TAB:
- atk_role_ = ATK_ROLE_PAGE_TAB;
- break;
- case ui::AX_ROLE_TABLE:
- atk_role_ = ATK_ROLE_TABLE;
- break;
- case ui::AX_ROLE_TAB_LIST:
- atk_role_ = ATK_ROLE_PAGE_TAB_LIST;
- break;
- case ui::AX_ROLE_TOGGLE_BUTTON:
- atk_role_ = ATK_ROLE_TOGGLE_BUTTON;
- break;
- case ui::AX_ROLE_TOOLBAR:
- atk_role_ = ATK_ROLE_TOOL_BAR;
- break;
- case ui::AX_ROLE_TOOLTIP:
- atk_role_ = ATK_ROLE_TOOL_TIP;
- break;
- case ui::AX_ROLE_TEXT_FIELD:
- atk_role_ = ATK_ROLE_ENTRY;
- break;
- case ui::AX_ROLE_TREE:
- atk_role_ = ATK_ROLE_TREE;
- break;
- case ui::AX_ROLE_TREE_ITEM:
- atk_role_ = ATK_ROLE_TREE_ITEM;
- break;
- case ui::AX_ROLE_TREE_GRID:
- atk_role_ = ATK_ROLE_TREE_TABLE;
- break;
- case ui::AX_ROLE_VIDEO:
-#if defined(ATK_CHECK_VERSION)
-#if ATK_CHECK_VERSION(2, 12, 0)
- atk_role_ = ATK_ROLE_VIDEO;
-#else
- atk_role_ = ATK_ROLE_SECTION;
-#endif
-#else
- atk_role_ = ATK_ROLE_SECTION;
-#endif
- break;
- default:
- atk_role_ = ATK_ROLE_UNKNOWN;
- break;
- }
-}
-
} // namespace content
diff --git a/chromium/content/browser/accessibility/browser_accessibility_auralinux.h b/chromium/content/browser/accessibility/browser_accessibility_auralinux.h
index b17cf0fb56d..6ba7d6f6b31 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_auralinux.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_auralinux.h
@@ -5,60 +5,16 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_AURALINUX_H_
#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_AURALINUX_H_
-#include <atk/atk.h>
-
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/common/content_export.h"
-namespace content {
-
-class BrowserAccessibilityAuraLinux;
-
-G_BEGIN_DECLS
-
-#define BROWSER_ACCESSIBILITY_TYPE (browser_accessibility_get_type())
-#define BROWSER_ACCESSIBILITY(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), BROWSER_ACCESSIBILITY_TYPE, \
- BrowserAccessibilityAtk))
-#define BROWSER_ACCESSIBILITY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), BROWSER_ACCESSIBILITY_TYPE, \
- BrowserAccessibilityAtkClass))
-#define IS_BROWSER_ACCESSIBILITY(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), BROWSER_ACCESSIBILITY_TYPE))
-#define IS_BROWSER_ACCESSIBILITY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), BROWSER_ACCESSIBILITY_TYPE))
-#define BROWSER_ACCESSIBILITY_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), BROWSER_ACCESSIBILITY_TYPE, \
- BrowserAccessibilityAtkClass))
-
-typedef struct _BrowserAccessibilityAtk BrowserAccessibilityAtk;
-typedef struct _BrowserAccessibilityAtkClass BrowserAccessibilityAtkClass;
-
-struct _BrowserAccessibilityAtk {
- AtkObject parent;
- BrowserAccessibilityAuraLinux* m_object;
-};
-
-struct _BrowserAccessibilityAtkClass {
- AtkObjectClass parent_class;
-};
-
-GType browser_accessibility_get_type(void) G_GNUC_CONST;
-
-BrowserAccessibilityAtk* browser_accessibility_new(
- BrowserAccessibilityAuraLinux* object);
-
-BrowserAccessibilityAuraLinux* browser_accessibility_get_object(
- BrowserAccessibilityAtk* atk_object);
-
-void browser_accessibility_detach(BrowserAccessibilityAtk* atk_object);
-
-AtkObject* browser_accessibility_get_focused_element(
- BrowserAccessibilityAtk* atk_object);
+namespace ui {
+class AXPlatformNodeAuraLinux;
+}
-G_END_DECLS
+namespace content {
class BrowserAccessibilityAuraLinux : public BrowserAccessibility {
public:
@@ -66,31 +22,22 @@ class BrowserAccessibilityAuraLinux : public BrowserAccessibility {
~BrowserAccessibilityAuraLinux() override;
- AtkObject* GetAtkObject() const;
-
- AtkRole atk_role() { return atk_role_; }
+ ui::AXPlatformNodeAuraLinux* GetNode() const;
// BrowserAccessibility methods.
void OnDataChanged() override;
bool IsNative() const override;
+ gfx::NativeViewAccessible GetNativeViewAccessible() override;
private:
- virtual void InitRoleAndState();
-
// Give BrowserAccessibility::Create access to our constructor.
friend class BrowserAccessibility;
- AtkObject* atk_object_;
- AtkRole atk_role_;
- int interface_mask_;
+ ui::AXPlatformNodeAuraLinux* node_;
- private:
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityAuraLinux);
};
-CONTENT_EXPORT const BrowserAccessibilityAuraLinux*
-ToBrowserAccessibilityAuraLinux(const BrowserAccessibility* obj);
-
CONTENT_EXPORT BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
BrowserAccessibility* obj);
diff --git a/chromium/content/browser/accessibility/browser_accessibility_cocoa.h b/chromium/content/browser/accessibility/browser_accessibility_cocoa.h
index e7743707caf..599882f1028 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_cocoa.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -83,6 +83,9 @@ struct AXTextEdit {
- (NSString*)valueForRange:(NSRange)range;
- (NSAttributedString*)attributedValueForRange:(NSRange)range;
+- (BOOL)isRowHeaderForCurrentCell:(content::BrowserAccessibility*)header;
+- (BOOL)isColumnHeaderForCurrentCell:(content::BrowserAccessibility*)header;
+
// Internally-used property.
@property(nonatomic, readonly) NSPoint origin;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm b/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
index 2e01e7cdab0..a49c9b7b378 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -20,10 +20,10 @@
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/app/strings/grit/content_strings.h"
-#include "content/browser/accessibility/ax_platform_position.h"
#include "content/browser/accessibility/browser_accessibility_mac.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_manager_mac.h"
+#include "content/browser/accessibility/browser_accessibility_position.h"
#include "content/browser/accessibility/one_shot_accessibility_tree_search.h"
#include "content/public/common/content_client.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -32,13 +32,14 @@
#import "ui/accessibility/platform/ax_platform_node_mac.h"
-using AXPlatformPositionInstance =
- content::AXPlatformPosition::AXPositionInstance;
-using AXPlatformRange = ui::AXRange<AXPlatformPositionInstance::element_type>;
+using BrowserAccessibilityPositionInstance =
+ content::BrowserAccessibilityPosition::AXPositionInstance;
+using AXPlatformRange =
+ ui::AXRange<BrowserAccessibilityPositionInstance::element_type>;
using AXTextMarkerRangeRef = CFTypeRef;
using AXTextMarkerRef = CFTypeRef;
using StringAttribute = ui::AXStringAttribute;
-using content::AXPlatformPosition;
+using content::BrowserAccessibilityPosition;
using content::AccessibilityMatchPredicate;
using content::BrowserAccessibility;
using content::BrowserAccessibilityDelegate;
@@ -148,10 +149,10 @@ AXTextMarkerRef AXTextMarkerRangeCopyEndMarker(
} // extern "C"
// AXTextMarkerCreate copies from data buffer given to it.
-id CreateTextMarker(AXPlatformPositionInstance position) {
+id CreateTextMarker(BrowserAccessibilityPositionInstance position) {
AXTextMarkerRef text_marker = AXTextMarkerCreate(
kCFAllocatorDefault, reinterpret_cast<const UInt8*>(position.get()),
- sizeof(AXPlatformPosition));
+ sizeof(BrowserAccessibilityPosition));
return static_cast<id>(
base::mac::CFTypeRefToNSObjectAutorelease(text_marker));
}
@@ -161,31 +162,34 @@ id CreateTextMarker(AXPlatformPositionInstance position) {
id CreateTextMarkerRange(const AXPlatformRange range) {
base::ScopedCFTypeRef<AXTextMarkerRef> start_marker(AXTextMarkerCreate(
kCFAllocatorDefault, reinterpret_cast<const UInt8*>(range.anchor()),
- sizeof(AXPlatformPosition)));
+ sizeof(BrowserAccessibilityPosition)));
base::ScopedCFTypeRef<AXTextMarkerRef> end_marker(AXTextMarkerCreate(
kCFAllocatorDefault, reinterpret_cast<const UInt8*>(range.focus()),
- sizeof(AXPlatformPosition)));
+ sizeof(BrowserAccessibilityPosition)));
AXTextMarkerRangeRef marker_range =
AXTextMarkerRangeCreate(kCFAllocatorDefault, start_marker, end_marker);
return static_cast<id>(
base::mac::CFTypeRefToNSObjectAutorelease(marker_range));
}
-AXPlatformPositionInstance CreatePositionFromTextMarker(
+BrowserAccessibilityPositionInstance CreatePositionFromTextMarker(
AXTextMarkerRef text_marker) {
DCHECK(text_marker);
- if (AXTextMarkerGetLength(text_marker) != sizeof(AXPlatformPosition))
- return AXPlatformPosition::CreateNullPosition();
+ if (AXTextMarkerGetLength(text_marker) !=
+ sizeof(BrowserAccessibilityPosition))
+ return BrowserAccessibilityPosition::CreateNullPosition();
const UInt8* source_buffer = AXTextMarkerGetBytePtr(text_marker);
if (!source_buffer)
- return AXPlatformPosition::CreateNullPosition();
- UInt8* destination_buffer = new UInt8[sizeof(AXPlatformPosition)];
- std::memcpy(destination_buffer, source_buffer, sizeof(AXPlatformPosition));
- AXPlatformPosition::AXPositionInstance position(
- reinterpret_cast<AXPlatformPosition::AXPositionInstance::pointer>(
+ return BrowserAccessibilityPosition::CreateNullPosition();
+ UInt8* destination_buffer = new UInt8[sizeof(BrowserAccessibilityPosition)];
+ std::memcpy(destination_buffer, source_buffer,
+ sizeof(BrowserAccessibilityPosition));
+ BrowserAccessibilityPosition::AXPositionInstance position(
+ reinterpret_cast<
+ BrowserAccessibilityPosition::AXPositionInstance::pointer>(
destination_buffer));
if (!position)
- return AXPlatformPosition::CreateNullPosition();
+ return BrowserAccessibilityPosition::CreateNullPosition();
return position;
}
@@ -199,24 +203,24 @@ AXPlatformRange CreateRangeFromTextMarkerRange(
if (!start_marker.get() || !end_marker.get())
return AXPlatformRange();
- AXPlatformPositionInstance anchor =
+ BrowserAccessibilityPositionInstance anchor =
CreatePositionFromTextMarker(start_marker.get());
- AXPlatformPositionInstance focus =
+ BrowserAccessibilityPositionInstance focus =
CreatePositionFromTextMarker(end_marker.get());
// |AXPlatformRange| takes ownership of its anchor and focus.
return AXPlatformRange(std::move(anchor), std::move(focus));
}
-AXPlatformPositionInstance CreateTextPosition(
+BrowserAccessibilityPositionInstance CreateTextPosition(
const BrowserAccessibility& object,
int offset,
ui::AXTextAffinity affinity) {
if (!object.instance_active())
- return AXPlatformPosition::CreateNullPosition();
+ return BrowserAccessibilityPosition::CreateNullPosition();
const BrowserAccessibilityManager* manager = object.manager();
DCHECK(manager);
- return AXPlatformPosition::CreateTextPosition(
+ return BrowserAccessibilityPosition::CreateTextPosition(
manager->ax_tree_id(), object.GetId(), offset, affinity);
}
@@ -226,9 +230,9 @@ AXPlatformRange CreateTextRange(const BrowserAccessibility& start_object,
const BrowserAccessibility& end_object,
int end_offset,
ui::AXTextAffinity end_affinity) {
- AXPlatformPositionInstance anchor =
+ BrowserAccessibilityPositionInstance anchor =
CreateTextPosition(start_object, start_offset, start_affinity);
- AXPlatformPositionInstance focus =
+ BrowserAccessibilityPositionInstance focus =
CreateTextPosition(end_object, end_offset, end_affinity);
// |AXPlatformRange| takes ownership of its anchor and focus.
return AXPlatformRange(std::move(anchor), std::move(focus));
@@ -297,7 +301,7 @@ NSAttributedString* GetAttributedTextForTextMarkerRange(
std::swap(start_offset, end_offset);
int trim_length = 0;
- if ((end_object->IsSimpleTextControl() || end_object->IsTextOnlyObject()) &&
+ if ((end_object->IsPlainTextField() || end_object->IsTextOnlyObject()) &&
end_offset < static_cast<int>(end_object->GetText().length())) {
trim_length = static_cast<int>(end_object->GetText().length()) - end_offset;
}
@@ -801,13 +805,55 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
}
+- (BOOL)isColumnHeaderForCurrentCell:(BrowserAccessibility*)header {
+ int cell_first_col = -1;
+ int cell_colspan = -1;
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_ARIA_CELL_COLUMN_INDEX,
+ &cell_first_col);
+ if (cell_first_col < 0) {
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_TABLE_CELL_COLUMN_INDEX,
+ &cell_first_col);
+ }
+ if (cell_first_col < 0)
+ return false;
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_TABLE_CELL_COLUMN_SPAN,
+ &cell_colspan);
+ if (cell_colspan <= 0)
+ cell_colspan = 1;
+ int cell_last_col = cell_first_col + cell_colspan - 1;
+
+ int header_first_col = -1;
+ int header_colspan = -1;
+ header->GetIntAttribute(ui::AX_ATTR_ARIA_CELL_COLUMN_INDEX,
+ &header_first_col);
+ if (header_first_col < 0) {
+ header->GetIntAttribute(ui::AX_ATTR_TABLE_CELL_COLUMN_INDEX,
+ &header_first_col);
+ }
+ if (header_first_col < 0)
+ return false;
+
+ header->GetIntAttribute(ui::AX_ATTR_TABLE_CELL_COLUMN_SPAN, &header_colspan);
+ if (header_colspan <= 0)
+ header_colspan = 1;
+ int header_last_col = header_first_col + header_colspan - 1;
+
+ int topmost_col_of_either = std::max(cell_first_col, header_first_col);
+ int bottommost_col_of_either = std::min(cell_last_col, header_last_col);
+ bool has_col_intersection = topmost_col_of_either <= bottommost_col_of_either;
+
+ return has_col_intersection;
+}
+
- (NSArray*)columnHeaders {
if (![self instanceActive])
return nil;
- if (!ui::IsTableLikeRole(browserAccessibility_->GetRole()) &&
- !ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole())) {
+
+ bool is_cell_or_table_header =
+ ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole());
+ bool is_table_like = ui::IsTableLikeRole(browserAccessibility_->GetRole());
+ if (!is_table_like && !is_cell_or_table_header)
return nil;
- }
BrowserAccessibility* table = [self containingTable];
if (!table)
return nil;
@@ -819,10 +865,14 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
int id = uniqueCellIds[i];
BrowserAccessibility* cell =
browserAccessibility_->manager()->GetFromID(id);
- if (cell && cell->GetRole() == ui::AX_ROLE_COLUMN_HEADER)
- [ret addObject:ToBrowserAccessibilityCocoa(cell)];
+ if (cell && cell->GetRole() == ui::AX_ROLE_COLUMN_HEADER) {
+ // Expose all column headers on table object.
+ // Expose only relevant column headers on cell object.
+ if (is_table_like || [self isColumnHeaderForCurrentCell:cell])
+ [ret addObject:ToBrowserAccessibilityCocoa(cell)];
+ }
}
- return ret;
+ return [ret count] ? ret : nil;
}
- (NSValue*)columnIndexRange {
@@ -1024,7 +1074,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (!root)
return nil;
- AXPlatformPositionInstance position = root->CreatePositionAt(0);
+ BrowserAccessibilityPositionInstance position = root->CreatePositionAt(0);
return CreateTextMarker(position->CreatePositionAtEndOfAnchor());
}
@@ -1470,9 +1520,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return NSAccessibilityGroupRole;
}
- if ((browserAccessibility_->IsSimpleTextControl() &&
+ if ((browserAccessibility_->IsPlainTextField() &&
browserAccessibility_->HasState(ui::AX_STATE_MULTILINE)) ||
- browserAccessibility_->IsRichTextControl()) {
+ browserAccessibility_->IsRichTextField()) {
return NSAccessibilityTextAreaRole;
}
@@ -1613,13 +1663,56 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return NSAccessibilityRoleDescription(role, nil);
}
+- (BOOL)isRowHeaderForCurrentCell:(BrowserAccessibility*)header {
+ int cell_first_row = -1;
+ int cell_rowspan = -1;
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_ARIA_CELL_ROW_INDEX,
+ &cell_first_row);
+ if (cell_first_row < 0) {
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_INDEX,
+ &cell_first_row);
+ }
+ if (cell_first_row < 0)
+ return false;
+
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_SPAN,
+ &cell_rowspan);
+ if (cell_rowspan <= 0)
+ cell_rowspan = 1;
+
+ int cell_last_row = cell_first_row + cell_rowspan - 1;
+
+ int header_first_row = -1;
+ int header_rowspan = -1;
+ header->GetIntAttribute(ui::AX_ATTR_ARIA_CELL_ROW_INDEX, &header_first_row);
+ if (header_first_row < 0) {
+ header->GetIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_INDEX,
+ &header_first_row);
+ }
+ if (header_first_row < 0)
+ return false;
+
+ header->GetIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_SPAN, &header_rowspan);
+ if (header_rowspan <= 0)
+ header_rowspan = 1;
+
+ int header_last_row = header_first_row + header_rowspan - 1;
+
+ int topmost_row_of_either = std::max(cell_first_row, header_first_row);
+ int bottommost_row_of_either = std::min(cell_last_row, header_last_row);
+ bool has_row_intersection = topmost_row_of_either <= bottommost_row_of_either;
+
+ return has_row_intersection;
+}
+
- (NSArray*)rowHeaders {
if (![self instanceActive])
return nil;
- if (!ui::IsTableLikeRole(browserAccessibility_->GetRole()) &&
- !ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole())) {
+ bool is_cell_or_table_header =
+ ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole());
+ bool is_table_like = ui::IsTableLikeRole(browserAccessibility_->GetRole());
+ if (!is_table_like && !is_cell_or_table_header)
return nil;
- }
BrowserAccessibility* table = [self containingTable];
if (!table)
return nil;
@@ -1631,10 +1724,12 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
int id = uniqueCellIds[i];
BrowserAccessibility* cell =
browserAccessibility_->manager()->GetFromID(id);
- if (cell && cell->GetRole() == ui::AX_ROLE_ROW_HEADER)
- [ret addObject:ToBrowserAccessibilityCocoa(cell)];
+ if (cell && cell->GetRole() == ui::AX_ROLE_ROW_HEADER) {
+ if (is_table_like || [self isRowHeaderForCurrentCell:cell])
+ [ret addObject:ToBrowserAccessibilityCocoa(cell)];
+ }
}
- return ret;
+ return [ret count] ? ret : nil;
}
- (NSValue*)rowIndexRange {
@@ -1852,7 +1947,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (!root)
return nil;
- AXPlatformPositionInstance position = root->CreatePositionAt(0);
+ BrowserAccessibilityPositionInstance position = root->CreatePositionAt(0);
return CreateTextMarker(position->CreatePositionAtStartOfAnchor());
}
@@ -1860,19 +1955,19 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSString*) subrole {
if (![self instanceActive])
return nil;
- ui::AXRole browserAccessibilityRole = [self internalRole];
- if (browserAccessibilityRole == ui::AX_ROLE_TEXT_FIELD &&
+
+ if (browserAccessibility_->IsPlainTextField() &&
GetState(browserAccessibility_, ui::AX_STATE_PROTECTED)) {
return NSAccessibilitySecureTextFieldSubrole;
}
- if (browserAccessibilityRole == ui::AX_ROLE_DESCRIPTION_LIST)
+ if ([self internalRole] == ui::AX_ROLE_DESCRIPTION_LIST)
return NSAccessibilityDefinitionListSubrole;
- if (browserAccessibilityRole == ui::AX_ROLE_LIST)
+ if ([self internalRole] == ui::AX_ROLE_LIST)
return NSAccessibilityContentListSubrole;
- return [AXPlatformNodeCocoa nativeSubroleFromAXRole:browserAccessibilityRole];
+ return [AXPlatformNodeCocoa nativeSubroleFromAXRole:[self internalRole]];
}
// Returns all tabs in this subtree.
@@ -1905,11 +2000,18 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if ([self shouldExposeTitleUIElement])
return @"";
+ ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>(
+ browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM));
+
+ // On Mac OS X, cell titles are "" if it it came from content.
+ NSString* role = [self role];
+ if ([role isEqualToString:NSAccessibilityCellRole] &&
+ nameFrom == ui::AX_NAME_FROM_CONTENTS)
+ return @"";
+
// 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.
- ui::AXNameFrom nameFrom = static_cast<ui::AXNameFrom>(
- browserAccessibility_->GetIntAttribute(ui::AX_ATTR_NAME_FROM));
if (nameFrom == ui::AX_NAME_FROM_CONTENTS ||
nameFrom == ui::AX_NAME_FROM_RELATED_ELEMENT ||
nameFrom == ui::AX_NAME_FROM_VALUE) {
@@ -2050,17 +2152,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSArray*)visibleChildren {
if (![self instanceActive])
return nil;
- NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
- uint32_t childCount = browserAccessibility_->PlatformChildCount();
- for (uint32_t index = 0; index < childCount; ++index) {
- BrowserAccessibilityCocoa* child = ToBrowserAccessibilityCocoa(
- browserAccessibility_->PlatformGetChild(index));
- if ([child isIgnored])
- [ret addObjectsFromArray:[child visibleChildren]];
- else
- [ret addObject:child];
- }
- return ret;
+ return [self children];
}
- (NSArray*)visibleColumns {
@@ -2255,7 +2347,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
CreatePositionFromTextMarker(parameter);
if (!position->IsNullPosition())
return ToBrowserAccessibilityCocoa(position->GetAnchor());
@@ -2264,9 +2356,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) {
- AXPlatformPositionInstance startPosition =
+ BrowserAccessibilityPositionInstance startPosition =
browserAccessibility_->CreatePositionAt(0);
- AXPlatformPositionInstance endPosition =
+ BrowserAccessibilityPositionInstance endPosition =
startPosition->CreatePositionAtEndOfAnchor();
AXPlatformRange range =
AXPlatformRange(std::move(startPosition), std::move(endPosition));
@@ -2280,7 +2372,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return GetAttributedTextForTextMarkerRange(parameter);
if ([attribute isEqualToString:@"AXNextTextMarkerForTextMarker"]) {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
CreatePositionFromTextMarker(parameter);
if (position->IsNullPosition())
return nil;
@@ -2289,7 +2381,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
CreatePositionFromTextMarker(parameter);
if (position->IsNullPosition())
return nil;
@@ -2298,18 +2390,18 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"]) {
- AXPlatformPositionInstance endPosition =
+ BrowserAccessibilityPositionInstance endPosition =
CreatePositionFromTextMarker(parameter);
if (endPosition->IsNullPosition())
return nil;
- AXPlatformPositionInstance startWordPosition =
+ BrowserAccessibilityPositionInstance startWordPosition =
endPosition->CreatePreviousWordStartPosition(
ui::AXBoundaryBehavior::StopAtAnchorBoundary);
- AXPlatformPositionInstance endWordPosition =
+ BrowserAccessibilityPositionInstance endWordPosition =
endPosition->CreatePreviousWordEndPosition(
ui::AXBoundaryBehavior::StopAtAnchorBoundary);
- AXPlatformPositionInstance startPosition =
+ BrowserAccessibilityPositionInstance startPosition =
*startWordPosition <= *endWordPosition ? std::move(endWordPosition)
: std::move(startWordPosition);
AXPlatformRange range(std::move(startPosition), std::move(endPosition));
@@ -2317,18 +2409,18 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"]) {
- AXPlatformPositionInstance startPosition =
+ BrowserAccessibilityPositionInstance startPosition =
CreatePositionFromTextMarker(parameter);
if (startPosition->IsNullPosition())
return nil;
- AXPlatformPositionInstance endWordPosition =
+ BrowserAccessibilityPositionInstance endWordPosition =
startPosition->CreateNextWordEndPosition(
ui::AXBoundaryBehavior::StopAtAnchorBoundary);
- AXPlatformPositionInstance startWordPosition =
+ BrowserAccessibilityPositionInstance startWordPosition =
startPosition->CreateNextWordStartPosition(
ui::AXBoundaryBehavior::StopAtAnchorBoundary);
- AXPlatformPositionInstance endPosition =
+ BrowserAccessibilityPositionInstance endPosition =
*startWordPosition <= *endWordPosition ? std::move(startWordPosition)
: std::move(endWordPosition);
AXPlatformRange range(std::move(startPosition), std::move(endPosition));
@@ -2336,7 +2428,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"]) {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
CreatePositionFromTextMarker(parameter);
if (position->IsNullPosition())
return nil;
@@ -2346,7 +2438,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if ([attribute
isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"]) {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
CreatePositionFromTextMarker(parameter);
if (position->IsNullPosition())
return nil;
@@ -2355,15 +2447,15 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXTextMarkerRangeForLine"]) {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
CreatePositionFromTextMarker(parameter);
if (position->IsNullPosition())
return nil;
- AXPlatformPositionInstance startPosition =
+ BrowserAccessibilityPositionInstance startPosition =
position->CreatePreviousLineStartPosition(
ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary);
- AXPlatformPositionInstance endPosition =
+ BrowserAccessibilityPositionInstance endPosition =
position->CreateNextLineEndPosition(
ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary);
AXPlatformRange range(std::move(startPosition), std::move(endPosition));
@@ -2371,18 +2463,18 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"]) {
- AXPlatformPositionInstance endPosition =
+ BrowserAccessibilityPositionInstance endPosition =
CreatePositionFromTextMarker(parameter);
if (endPosition->IsNullPosition())
return nil;
- AXPlatformPositionInstance startLinePosition =
+ BrowserAccessibilityPositionInstance startLinePosition =
endPosition->CreatePreviousLineStartPosition(
ui::AXBoundaryBehavior::CrossBoundary);
- AXPlatformPositionInstance endLinePosition =
+ BrowserAccessibilityPositionInstance endLinePosition =
endPosition->CreatePreviousLineEndPosition(
ui::AXBoundaryBehavior::CrossBoundary);
- AXPlatformPositionInstance startPosition =
+ BrowserAccessibilityPositionInstance startPosition =
*startLinePosition <= *endLinePosition ? std::move(endLinePosition)
: std::move(startLinePosition);
AXPlatformRange range(std::move(startPosition), std::move(endPosition));
@@ -2390,18 +2482,18 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"]) {
- AXPlatformPositionInstance startPosition =
+ BrowserAccessibilityPositionInstance startPosition =
CreatePositionFromTextMarker(parameter);
if (startPosition->IsNullPosition())
return nil;
- AXPlatformPositionInstance startLinePosition =
+ BrowserAccessibilityPositionInstance startLinePosition =
startPosition->CreateNextLineStartPosition(
ui::AXBoundaryBehavior::CrossBoundary);
- AXPlatformPositionInstance endLinePosition =
+ BrowserAccessibilityPositionInstance endLinePosition =
startPosition->CreateNextLineEndPosition(
ui::AXBoundaryBehavior::CrossBoundary);
- AXPlatformPositionInstance endPosition =
+ BrowserAccessibilityPositionInstance endPosition =
*startLinePosition <= *endLinePosition ? std::move(startLinePosition)
: std::move(endLinePosition);
AXPlatformRange range(std::move(startPosition), std::move(endPosition));
@@ -2409,7 +2501,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"]) {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
CreatePositionFromTextMarker(parameter);
if (position->IsNullPosition())
return nil;
@@ -2419,7 +2511,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if ([attribute
isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"]) {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
CreatePositionFromTextMarker(parameter);
if (position->IsNullPosition())
return nil;
@@ -2470,7 +2562,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if ([attribute isEqualToString:
NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute]) {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
CreatePositionFromTextMarker(parameter);
if (position->IsNullPosition())
return nil;
@@ -2518,9 +2610,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if ([text_marker_array count] != 2)
return nil;
- AXPlatformPositionInstance startPosition =
+ BrowserAccessibilityPositionInstance startPosition =
CreatePositionFromTextMarker([text_marker_array objectAtIndex:0]);
- AXPlatformPositionInstance endPosition =
+ BrowserAccessibilityPositionInstance endPosition =
CreatePositionFromTextMarker([text_marker_array objectAtIndex:1]);
if (*startPosition <= *endPosition) {
return CreateTextMarkerRange(
@@ -2749,12 +2841,20 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
[ret addObjectsFromArray:@[
NSAccessibilityColumnIndexRangeAttribute,
NSAccessibilityRowIndexRangeAttribute,
- NSAccessibilityColumnHeaderUIElementsAttribute,
- NSAccessibilityRowHeaderUIElementsAttribute,
NSAccessibilityARIAColumnIndexAttribute,
NSAccessibilityARIARowIndexAttribute,
@"AXSortDirection",
]];
+ if ([self internalRole] != ui::AX_ROLE_COLUMN_HEADER) {
+ [ret addObjectsFromArray:@[
+ NSAccessibilityColumnHeaderUIElementsAttribute,
+ ]];
+ }
+ if ([self internalRole] != ui::AX_ROLE_ROW_HEADER) {
+ [ret addObjectsFromArray:@[
+ NSAccessibilityRowHeaderUIElementsAttribute,
+ ]];
+ }
} else if ([role isEqualToString:@"AXWebArea"]) {
[ret addObjectsFromArray:@[
@"AXLoaded", NSAccessibilityLoadingProgressAttribute
diff --git a/chromium/content/browser/accessibility/browser_accessibility_com_win.cc b/chromium/content/browser/accessibility/browser_accessibility_com_win.cc
index 7f2a57ce63c..7e7c129773d 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -16,9 +16,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/enum_variant.h"
-#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"
-#include "content/browser/accessibility/browser_accessibility_event_win.h"
#include "content/browser/accessibility/browser_accessibility_manager_win.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/accessibility/browser_accessibility_win.h"
@@ -40,8 +38,10 @@ const uint32_t kScreenReaderAndHTMLAccessibilityModes =
namespace content {
-using AXPlatformPositionInstance = AXPlatformPosition::AXPositionInstance;
-using AXPlatformRange = ui::AXRange<AXPlatformPositionInstance::element_type>;
+using BrowserAccessibilityPositionInstance =
+ BrowserAccessibilityPosition::AXPositionInstance;
+using AXPlatformRange =
+ ui::AXRange<BrowserAccessibilityPositionInstance::element_type>;
// These nonstandard GUIDs are taken directly from the Mozilla sources
// (accessible/src/msaa/nsAccessNodeWrap.cpp); some documentation is here:
@@ -1713,32 +1713,12 @@ void BrowserAccessibilityComWin::ComputeStylesIfNeeded() {
return;
std::map<int, std::vector<base::string16>> attributes_map;
- if (owner()->PlatformIsLeaf() || owner()->IsSimpleTextControl()) {
+ if (owner()->PlatformIsLeaf() || owner()->IsPlainTextField()) {
attributes_map[0] = ComputeTextAttributes();
- std::map<int, std::vector<base::string16>> spelling_attributes =
+ const std::map<int, std::vector<base::string16>> spelling_attributes =
GetSpellingAttributes();
- for (auto& spelling_attribute : spelling_attributes) {
- auto attributes_iterator = attributes_map.find(spelling_attribute.first);
- if (attributes_iterator == attributes_map.end()) {
- attributes_map[spelling_attribute.first] =
- std::move(spelling_attribute.second);
- } else {
- std::vector<base::string16>& existing_attributes =
- attributes_iterator->second;
-
- // There might be a spelling attribute already in the list of text
- // attributes, originating from "aria-invalid".
- auto existing_spelling_attribute =
- std::find(existing_attributes.begin(), existing_attributes.end(),
- L"invalid:false");
- if (existing_spelling_attribute != existing_attributes.end())
- existing_attributes.erase(existing_spelling_attribute);
-
- existing_attributes.insert(existing_attributes.end(),
- spelling_attribute.second.begin(),
- spelling_attribute.second.end());
- }
- }
+ MergeSpellingIntoTextAttributes(spelling_attributes, 0 /* start_offset */,
+ &attributes_map);
win_attributes_->offset_to_text_attributes.swap(attributes_map);
return;
}
@@ -1762,10 +1742,15 @@ void BrowserAccessibilityComWin::ComputeStylesIfNeeded() {
}
}
- if (child->owner()->IsTextOnlyObject())
+ if (child->owner()->IsTextOnlyObject()) {
+ const std::map<int, std::vector<base::string16>> spelling_attributes =
+ child->GetSpellingAttributes();
+ MergeSpellingIntoTextAttributes(spelling_attributes, start_offset,
+ &attributes_map);
start_offset += child->GetText().length();
- else
+ } else {
start_offset += 1;
+ }
}
win_attributes_->offset_to_text_attributes.swap(attributes_map);
@@ -1777,9 +1762,9 @@ void BrowserAccessibilityComWin::ComputeStylesIfNeeded() {
// tree positions.
// TODO(nektar): Remove this function once selection fixes in Blink are
// thoroughly tested and convert to tree positions.
-AXPlatformPosition::AXPositionInstance
+BrowserAccessibilityPosition::AXPositionInstance
BrowserAccessibilityComWin::CreatePositionForSelectionAt(int offset) const {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
owner()->CreatePositionAt(offset)->AsLeafTextPosition();
if (position->GetAnchor() &&
position->GetAnchor()->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) {
@@ -1903,12 +1888,13 @@ void BrowserAccessibilityComWin::UpdateStep3FireEvents(
FireNativeEvent(IA2_EVENT_TEXT_INSERTED);
}
- // Changing a static text node can affect the IAccessibleText hypertext
- // of the parent node, so force an update on the parent.
+ // Changing a static text node can affect the IA2 hypertext of its parent
+ // and, if the node is in a simple text control, the hypertext of the text
+ // control itself.
BrowserAccessibilityComWin* parent =
ToBrowserAccessibilityComWin(owner()->PlatformGetParent());
- if (parent && owner()->IsTextOnlyObject() &&
- name() != old_win_attributes_->name) {
+ if (parent && (parent->owner()->HasState(ui::AX_STATE_EDITABLE) ||
+ owner()->IsTextOnlyObject())) {
parent->owner()->UpdatePlatformAttributes();
}
}
@@ -1996,8 +1982,7 @@ std::vector<base::string16> BrowserAccessibilityComWin::ComputeTextAttributes()
// We assume that there are 96 pixels per inch on a standard display.
// TODO(nektar): Figure out the current value of pixels per inch.
float points = font_size * 72.0 / 96.0;
- attributes.push_back(L"font-size:" +
- base::UTF8ToUTF16(base::DoubleToString(points)) +
+ attributes.push_back(L"font-size:" + base::NumberToString16(points) +
L"pt");
}
@@ -2149,7 +2134,7 @@ BrowserAccessibilityComWin::GetSpellingAttributes() {
spelling_attributes[end_offset] = end_attributes;
}
}
- if (owner()->IsSimpleTextControl()) {
+ if (owner()->IsPlainTextField()) {
int start_offset = 0;
for (BrowserAccessibility* static_text =
BrowserAccessibilityManager::NextTextOnlyObject(
@@ -2211,6 +2196,39 @@ HRESULT BrowserAccessibilityComWin::GetStringAttributeAsBstr(
return S_OK;
}
+// static
+void BrowserAccessibilityComWin::MergeSpellingIntoTextAttributes(
+ const std::map<int, std::vector<base::string16>>& spelling_attributes,
+ int start_offset,
+ std::map<int, std::vector<base::string16>>* text_attributes) {
+ if (!text_attributes) {
+ NOTREACHED();
+ return;
+ }
+
+ for (const auto& spelling_attribute : spelling_attributes) {
+ int offset = start_offset + spelling_attribute.first;
+ const auto iterator = text_attributes->find(offset);
+ if (iterator == text_attributes->end()) {
+ text_attributes->emplace(offset, spelling_attribute.second);
+ } else {
+ std::vector<base::string16>& existing_attributes = iterator->second;
+ // There might be a spelling attribute already in the list of text
+ // attributes, originating from "aria-invalid", that is being overwritten
+ // by a spelling marker.
+ auto existing_spelling_attribute =
+ std::find(existing_attributes.begin(), existing_attributes.end(),
+ L"invalid:false");
+ if (existing_spelling_attribute != existing_attributes.end())
+ existing_attributes.erase(existing_spelling_attribute);
+
+ existing_attributes.insert(existing_attributes.end(),
+ spelling_attribute.second.begin(),
+ spelling_attribute.second.end());
+ }
+ }
+}
+
// Static
void BrowserAccessibilityComWin::SanitizeStringAttributeForIA2(
const base::string16& input,
@@ -2230,9 +2248,9 @@ void BrowserAccessibilityComWin::SetIA2HypertextSelection(LONG start_offset,
LONG end_offset) {
HandleSpecialTextOffset(&start_offset);
HandleSpecialTextOffset(&end_offset);
- AXPlatformPositionInstance start_position =
+ BrowserAccessibilityPositionInstance start_position =
CreatePositionForSelectionAt(static_cast<int>(start_offset));
- AXPlatformPositionInstance end_position =
+ BrowserAccessibilityPositionInstance end_position =
CreatePositionForSelectionAt(static_cast<int>(end_offset));
Manager()->SetSelection(
AXPlatformRange(std::move(start_position), std::move(end_position)));
@@ -2242,28 +2260,29 @@ LONG BrowserAccessibilityComWin::FindBoundary(
IA2TextBoundaryType ia2_boundary,
LONG start_offset,
ui::TextBoundaryDirection direction) {
- // If the boundary is relative to the caret, use the selection
- // affinity, otherwise default to downstream affinity.
- ui::AXTextAffinity affinity =
- start_offset == IA2_TEXT_OFFSET_CARET
- ? Manager()->GetTreeData().sel_focus_affinity
- : ui::AX_TEXT_AFFINITY_DOWNSTREAM;
-
HandleSpecialTextOffset(&start_offset);
+ // If the |start_offset| is equal to the location of the caret, then use the
+ // focus affinity, otherwise default to downstream affinity.
+ ui::AXTextAffinity affinity = ui::AX_TEXT_AFFINITY_DOWNSTREAM;
+ int selection_start, selection_end;
+ GetSelectionOffsets(&selection_start, &selection_end);
+ if (selection_end >= 0 && start_offset == selection_end)
+ affinity = Manager()->GetTreeData().sel_focus_affinity;
+
if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) {
switch (direction) {
case ui::FORWARDS_DIRECTION: {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
owner()->CreatePositionAt(static_cast<int>(start_offset), affinity);
- AXPlatformPositionInstance next_word =
+ BrowserAccessibilityPositionInstance next_word =
position->CreateNextWordStartPosition(
ui::AXBoundaryBehavior::StopAtAnchorBoundary);
return next_word->text_offset();
}
case ui::BACKWARDS_DIRECTION: {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
owner()->CreatePositionAt(static_cast<int>(start_offset), affinity);
- AXPlatformPositionInstance previous_word =
+ BrowserAccessibilityPositionInstance previous_word =
position->CreatePreviousWordStartPosition(
ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary);
return previous_word->text_offset();
@@ -2274,17 +2293,17 @@ LONG BrowserAccessibilityComWin::FindBoundary(
if (ia2_boundary == IA2_TEXT_BOUNDARY_LINE) {
switch (direction) {
case ui::FORWARDS_DIRECTION: {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
owner()->CreatePositionAt(static_cast<int>(start_offset), affinity);
- AXPlatformPositionInstance next_line =
+ BrowserAccessibilityPositionInstance next_line =
position->CreateNextLineStartPosition(
ui::AXBoundaryBehavior::StopAtAnchorBoundary);
return next_line->text_offset();
}
case ui::BACKWARDS_DIRECTION: {
- AXPlatformPositionInstance position =
+ BrowserAccessibilityPositionInstance position =
owner()->CreatePositionAt(static_cast<int>(start_offset), affinity);
- AXPlatformPositionInstance previous_line =
+ BrowserAccessibilityPositionInstance previous_line =
position->CreatePreviousLineStartPosition(
ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary);
return previous_line->text_offset();
@@ -2356,9 +2375,10 @@ bool BrowserAccessibilityComWin::IsListBoxOptionOrMenuListOption() {
}
void BrowserAccessibilityComWin::FireNativeEvent(LONG win_event_type) const {
- (new BrowserAccessibilityEventWin(BrowserAccessibilityEvent::FromTreeChange,
- ui::AX_EVENT_NONE, win_event_type, owner()))
- ->Fire();
+ if (owner()->PlatformIsChildOfLeaf())
+ return;
+ Manager()->ToBrowserAccessibilityManagerWin()->FireWinAccessibilityEvent(
+ win_event_type, owner());
}
BrowserAccessibilityComWin* ToBrowserAccessibilityComWin(
diff --git a/chromium/content/browser/accessibility/browser_accessibility_com_win.h b/chromium/content/browser/accessibility/browser_accessibility_com_win.h
index ca4e32003fc..d601a6414e4 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_com_win.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_com_win.h
@@ -413,7 +413,7 @@ class __declspec(uuid("562072fe-3390-43b1-9e2c-dd4118f5ac79"))
// |offset| could either be a text character or a child index in case of
// non-text objects.
- AXPlatformPosition::AXPositionInstance CreatePositionForSelectionAt(
+ BrowserAccessibilityPosition::AXPositionInstance CreatePositionForSelectionAt(
int offset) const;
// Public accessors (these do not have COM accessible accessors)
@@ -470,6 +470,17 @@ class __declspec(uuid("562072fe-3390-43b1-9e2c-dd4118f5ac79"))
HRESULT GetStringAttributeAsBstr(ui::AXStringAttribute attribute,
BSTR* value_bstr);
+ // Merges the given spelling attributes, i.e. document marker information,
+ // into the given text attributes starting at the given character offset. This
+ // is required for two reasons: 1. Document markers that are present on text
+ // leaves need to be propagated to their parent object for compatibility with
+ // Firefox. 2. Spelling markers need to overwrite any aria-invalid="false" in
+ // the text attributes.
+ static void MergeSpellingIntoTextAttributes(
+ const std::map<int, std::vector<base::string16>>& spelling_attributes,
+ int start_offset,
+ std::map<int, std::vector<base::string16>>* text_attributes);
+
// Escapes characters in string attributes as required by the IA2 Spec.
// It's okay for input to be the same as output.
CONTENT_EXPORT static void SanitizeStringAttributeForIA2(
diff --git a/chromium/content/browser/accessibility/browser_accessibility_event.cc b/chromium/content/browser/accessibility/browser_accessibility_event.cc
deleted file mode 100644
index 555688d7ff2..00000000000
--- a/chromium/content/browser/accessibility/browser_accessibility_event.cc
+++ /dev/null
@@ -1,148 +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/accessibility/browser_accessibility_event.h"
-
-#include <string>
-
-#include "base/strings/string_util.h"
-#include "content/browser/accessibility/browser_accessibility.h"
-#include "content/browser/accessibility/browser_accessibility_manager.h"
-
-namespace content {
-
-namespace {
-std::string ReplaceNewlines(std::string str) {
- std::string result;
- base::ReplaceChars(str, "\n", "\\n", &result);
- return result;
-}
-} // namespace
-
-// static
-bool BrowserAccessibilityEvent::FailedToSend(Result result) {
- switch (result) {
- case Sent:
- case NotNeededOnThisPlatform:
- case DiscardedBecauseUserNavigatingAway:
- case DiscardedBecauseLiveRegionBusy:
- return false;
- case FailedBecauseNoWindow:
- case FailedBecauseNoFocus:
- case FailedBecauseFrameIsDetached:
- return true;
- }
-
- NOTREACHED();
- return true;
-}
-
-#if !defined(OS_WIN)
-// static
-BrowserAccessibilityEvent* BrowserAccessibilityEvent::Create(
- Source source,
- ui::AXEvent event_type,
- const BrowserAccessibility* target) {
- return new BrowserAccessibilityEvent(source, event_type, target);
-}
-#endif // !defined(OS_WIN)
-
-BrowserAccessibilityEvent::BrowserAccessibilityEvent(
- Source source,
- ui::AXEvent event_type,
- const BrowserAccessibility* target)
- : source_(source),
- event_type_(event_type),
- target_(target),
- original_target_(target) {
- DCHECK(target_);
-}
-
-BrowserAccessibilityEvent::~BrowserAccessibilityEvent() {
-}
-
-BrowserAccessibilityEvent::Result BrowserAccessibilityEvent::Fire() {
- delete this;
- return NotNeededOnThisPlatform;
-}
-
-std::string BrowserAccessibilityEvent::GetEventNameStr() {
- return ui::ToString(event_type_);
-}
-
-void BrowserAccessibilityEvent::VerboseLog(Result result) {
- std::string event_name = GetEventNameStr();
-
- const char* result_str = nullptr;
- switch (result) {
- case Sent:
- result_str = "Sent";
- break;
- case NotNeededOnThisPlatform:
- result_str = "NotNeededOnThisPlatform";
- break;
- case DiscardedBecauseUserNavigatingAway:
- result_str = "DiscardedBecauseUserNavigatingAway";
- break;
- case DiscardedBecauseLiveRegionBusy:
- result_str = "DiscardedBecauseLiveRegionBusy";
- break;
- case FailedBecauseNoWindow:
- result_str = "FailedBecauseNoWindow";
- break;
- case FailedBecauseNoFocus:
- result_str = "FailedBecauseNoFocus";
- break;
- case FailedBecauseFrameIsDetached:
- result_str = "FailedBecauseFrameIsDetached";
- break;
- }
-
- const char* success_str = (result == Sent ? "+" : "-");
-
- const char* source_str = nullptr;
- switch (source_) {
- case FromBlink:
- source_str = "FromBlink";
- break;
- case FromChildFrameLoading:
- source_str = "FromChildFrameLoading";
- break;
- case FromFindInPageResult:
- source_str = "FromFindInPageResult";
- break;
- case FromRenderFrameHost:
- source_str = "FromRenderFrameHost";
- break;
- case FromScroll:
- source_str = "FromScroll";
- break;
- case FromTreeChange:
- source_str = "FromTreeChange";
- break;
- case FromWindowFocusChange:
- source_str = "FromWindowFocusChange";
- break;
- case FromPendingLoadComplete:
- source_str = "FromPendingLoadComplete";
- break;
- }
-
- std::string original_target_str;
- if (original_target_ != target_) {
- original_target_str = " originalTarget=[["
- + ReplaceNewlines(original_target_->GetData().ToString()) + "]]";
- }
-
- VLOG(1) << "Accessibility event"
- << " " << success_str
- << " " << event_name
- << " result=" << result_str
- << " source=" << source_str
- << " target=[["
- << ReplaceNewlines(target_->GetData().ToString()) << "]]"
- << original_target_str;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/accessibility/browser_accessibility_event.h b/chromium/content/browser/accessibility/browser_accessibility_event.h
deleted file mode 100644
index b985b72497c..00000000000
--- a/chromium/content/browser/accessibility/browser_accessibility_event.h
+++ /dev/null
@@ -1,85 +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_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_H_
-#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_H_
-
-#include <string>
-
-#include "content/browser/accessibility/browser_accessibility.h"
-#include "content/common/content_export.h"
-#include "ui/accessibility/ax_enums.h"
-
-namespace content {
-
-class BrowserAccessibility;
-
-class CONTENT_EXPORT BrowserAccessibilityEvent {
- public:
- enum Source {
- FromBlink,
- FromChildFrameLoading,
- FromFindInPageResult,
- FromRenderFrameHost,
- FromScroll,
- FromTreeChange,
- FromWindowFocusChange,
- FromPendingLoadComplete,
- };
-
- enum Result {
- Sent,
- NotNeededOnThisPlatform,
- DiscardedBecauseUserNavigatingAway,
- DiscardedBecauseLiveRegionBusy,
- FailedBecauseNoWindow,
- FailedBecauseNoFocus,
- FailedBecauseFrameIsDetached,
- };
-
- // Returns true if the given result indicates that sending the event failed.
- // Returns false if the event was sent, or if it was not needed (which is
- // not considered failure).
- static bool FailedToSend(Result result);
-
- static BrowserAccessibilityEvent* Create(Source source,
- ui::AXEvent event_type,
- const BrowserAccessibility* target);
-
- // Construct a new accessibility event that should be sent via a
- // platform-specific notification.
- BrowserAccessibilityEvent(Source source,
- ui::AXEvent event_type,
- const BrowserAccessibility* target);
- virtual ~BrowserAccessibilityEvent();
-
- // Synchronously try to send the native accessibility event notification
- // and return a result indicating the outcome. This deletes the event.
- virtual Result Fire();
-
- Source source() { return source_; }
- ui::AXEvent event_type() { return event_type_; }
- const BrowserAccessibility* target() { return target_; }
- void set_target(const BrowserAccessibility* target) { target_ = target; }
- void set_original_target(BrowserAccessibility* target) {
- original_target_ = target;
- }
-
- protected:
- virtual std::string GetEventNameStr();
- void VerboseLog(Result result);
-
- private:
- Source source_;
- ui::AXEvent event_type_;
- const BrowserAccessibility* target_;
- const BrowserAccessibility* original_target_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityEvent);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_H_
diff --git a/chromium/content/browser/accessibility/browser_accessibility_event_win.cc b/chromium/content/browser/accessibility/browser_accessibility_event_win.cc
deleted file mode 100644
index 540b216da28..00000000000
--- a/chromium/content/browser/accessibility/browser_accessibility_event_win.cc
+++ /dev/null
@@ -1,102 +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/accessibility/browser_accessibility_event_win.h"
-
-#include "base/strings/utf_string_conversions.h"
-#include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
-#include "content/browser/accessibility/browser_accessibility.h"
-#include "content/browser/accessibility/browser_accessibility_manager_win.h"
-
-namespace content {
-
-// static
-BrowserAccessibilityEvent* BrowserAccessibilityEvent::Create(
- Source source,
- ui::AXEvent event_type,
- const BrowserAccessibility* target) {
- LONG win_event_type = EVENT_MIN;
- switch (event_type) {
- case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
- win_event_type = IA2_EVENT_ACTIVE_DESCENDANT_CHANGED;
- break;
- case ui::AX_EVENT_ALERT:
- win_event_type = EVENT_SYSTEM_ALERT;
- break;
- case ui::AX_EVENT_CHILDREN_CHANGED:
- win_event_type = EVENT_OBJECT_REORDER;
- break;
- case ui::AX_EVENT_FOCUS:
- win_event_type = EVENT_OBJECT_FOCUS;
- break;
- case ui::AX_EVENT_LIVE_REGION_CHANGED:
- win_event_type = EVENT_OBJECT_LIVEREGIONCHANGED;
- break;
- case ui::AX_EVENT_LOAD_COMPLETE:
- win_event_type = IA2_EVENT_DOCUMENT_LOAD_COMPLETE;
- break;
- case ui::AX_EVENT_LOCATION_CHANGED:
- win_event_type = IA2_EVENT_VISIBLE_DATA_CHANGED;
- break;
- case ui::AX_EVENT_SCROLL_POSITION_CHANGED:
- win_event_type = EVENT_SYSTEM_SCROLLINGEND;
- break;
- case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
- win_event_type = EVENT_SYSTEM_SCROLLINGSTART;
- break;
- case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED:
- win_event_type = EVENT_OBJECT_SELECTIONWITHIN;
- break;
- default:
- break;
- }
-
- return new BrowserAccessibilityEventWin(
- source,
- event_type,
- win_event_type,
- target);
-}
-
-BrowserAccessibilityEventWin::BrowserAccessibilityEventWin(
- Source source,
- ui::AXEvent event_type,
- LONG win_event_type,
- const BrowserAccessibility* target)
- : BrowserAccessibilityEvent(source, event_type, target),
- win_event_type_(win_event_type) {
-}
-
-BrowserAccessibilityEventWin::~BrowserAccessibilityEventWin() {
-}
-
-BrowserAccessibilityEvent::Result BrowserAccessibilityEventWin::Fire() {
- DCHECK(target()->manager());
-
- if (win_event_type_ == EVENT_MIN) {
- delete this;
- return NotNeededOnThisPlatform;
- }
-
- Result result = target()->manager()->ToBrowserAccessibilityManagerWin()
- ->FireWinAccessibilityEvent(this);
-
- if (VLOG_IS_ON(1))
- VerboseLog(result);
-
- delete this;
- return result;
-}
-
-std::string BrowserAccessibilityEventWin::GetEventNameStr() {
- std::string result = base::UTF16ToUTF8(AccessibilityEventToString(
- win_event_type_));
- if (event_type() != ui::AX_EVENT_NONE) {
- result.push_back('/');
- result.append(ui::ToString(event_type()));
- }
- return result;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/accessibility/browser_accessibility_event_win.h b/chromium/content/browser/accessibility/browser_accessibility_event_win.h
deleted file mode 100644
index 1d1ac4eaf31..00000000000
--- a/chromium/content/browser/accessibility/browser_accessibility_event_win.h
+++ /dev/null
@@ -1,38 +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_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_WIN_H_
-#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_WIN_H_
-
-#include <oleacc.h>
-
-#include "content/browser/accessibility/browser_accessibility_event.h"
-
-namespace content {
-
-class CONTENT_EXPORT BrowserAccessibilityEventWin
- : public BrowserAccessibilityEvent {
- public:
- BrowserAccessibilityEventWin(Source source,
- ui::AXEvent event_type,
- LONG win_event_type,
- const BrowserAccessibility* target);
- ~BrowserAccessibilityEventWin() override;
-
- LONG win_event_type() { return win_event_type_; }
-
- Result Fire() override;
-
- protected:
- std::string GetEventNameStr() override;
-
- LONG win_event_type_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityEventWin);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_EVENT_WIN_H_
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager.cc b/chromium/content/browser/accessibility/browser_accessibility_manager.cc
index 38269319de3..fe1875f94f9 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <utility>
+#include "base/debug/crash_logging.h"
#include "base/logging.h"
#include "build/build_config.h"
#include "content/browser/accessibility/browser_accessibility.h"
@@ -133,7 +134,8 @@ BrowserAccessibilityManager* BrowserAccessibilityManager::FromID(
BrowserAccessibilityManager::BrowserAccessibilityManager(
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory)
- : delegate_(delegate),
+ : AXEventGenerator(),
+ delegate_(delegate),
factory_(factory),
tree_(new ui::AXSerializableTree()),
user_is_navigating_away_(false),
@@ -144,14 +146,15 @@ BrowserAccessibilityManager::BrowserAccessibilityManager(
parent_node_id_from_parent_tree_(0),
device_scale_factor_(1.0f),
use_custom_device_scale_factor_for_testing_(false) {
- tree_->SetDelegate(this);
+ SetTree(tree_.get());
}
BrowserAccessibilityManager::BrowserAccessibilityManager(
const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory)
- : delegate_(delegate),
+ : AXEventGenerator(),
+ delegate_(delegate),
factory_(factory),
tree_(new ui::AXSerializableTree()),
user_is_navigating_away_(false),
@@ -161,24 +164,27 @@ BrowserAccessibilityManager::BrowserAccessibilityManager(
parent_node_id_from_parent_tree_(0),
device_scale_factor_(1.0f),
use_custom_device_scale_factor_for_testing_(false) {
- tree_->SetDelegate(this);
+ SetTree(tree_.get());
Initialize(initial_tree);
}
BrowserAccessibilityManager::~BrowserAccessibilityManager() {
- tree_.reset(NULL);
+ tree_.reset(nullptr);
+ ReleaseTree();
g_ax_tree_id_map.Get().erase(ax_tree_id_);
}
void BrowserAccessibilityManager::Initialize(
const ui::AXTreeUpdate& initial_tree) {
if (!tree_->Unserialize(initial_tree)) {
- if (delegate_) {
- LOG(ERROR) << tree_->error();
- delegate_->AccessibilityFatalError();
- } else {
- LOG(FATAL) << tree_->error();
- }
+ // Temporarily log some additional crash keys so we can try to
+ // figure out why we're getting bad accessibility trees here.
+ // http://crbug.com/765490
+ // Be sure to re-enable BrowserAccessibilityManagerTest.TestFatalError
+ // when done (or delete it if no longer needed).
+ base::debug::SetCrashKeyValue("ax_tree_error", tree_->error());
+ base::debug::SetCrashKeyValue("ax_tree_update", initial_tree.ToString());
+ LOG(FATAL) << tree_->error();
}
}
@@ -198,15 +204,7 @@ BrowserAccessibilityManager::GetEmptyDocument() {
return update;
}
-void BrowserAccessibilityManager::NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::Source source,
- ui::AXEvent event_type,
- BrowserAccessibility* node) {
- BrowserAccessibilityEvent::Create(source, event_type, node)->Fire();
-}
-
-void BrowserAccessibilityManager::FireFocusEventsIfNeeded(
- BrowserAccessibilityEvent::Source source) {
+void BrowserAccessibilityManager::FireFocusEventsIfNeeded() {
BrowserAccessibility* focus = GetFocus();
// Don't fire focus events if the window itself doesn't have focus.
@@ -231,7 +229,7 @@ void BrowserAccessibilityManager::FireFocusEventsIfNeeded(
}
if (focus && focus != last_focused_node_)
- FireFocusEvent(source, focus);
+ FireFocusEvent(focus);
last_focused_node_ = focus;
last_focused_manager_ = focus ? focus->manager() : nullptr;
@@ -241,11 +239,7 @@ bool BrowserAccessibilityManager::CanFireEvents() {
return true;
}
-void BrowserAccessibilityManager::FireFocusEvent(
- BrowserAccessibilityEvent::Source source,
- BrowserAccessibility* node) {
- NotifyAccessibilityEvent(source, ui::AX_EVENT_FOCUS, node);
-
+void BrowserAccessibilityManager::FireFocusEvent(BrowserAccessibility* node) {
if (g_focus_change_callback_for_testing.Get())
g_focus_change_callback_for_testing.Get().Run();
}
@@ -316,7 +310,7 @@ const ui::AXTreeData& BrowserAccessibilityManager::GetTreeData() {
void BrowserAccessibilityManager::OnWindowFocused() {
if (this == GetRootManager())
- FireFocusEventsIfNeeded(BrowserAccessibilityEvent::FromWindowFocusChange);
+ FireFocusEventsIfNeeded();
}
void BrowserAccessibilityManager::OnWindowBlurred() {
@@ -376,88 +370,42 @@ void BrowserAccessibilityManager::OnAccessibilityEvents(
if (!connected_to_parent_tree_node_) {
parent->OnDataChanged();
parent->UpdatePlatformAttributes();
- NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::FromChildFrameLoading,
- ui::AX_EVENT_CHILDREN_CHANGED,
- parent);
+ FireGeneratedEvent(Event::CHILDREN_CHANGED, parent);
connected_to_parent_tree_node_ = true;
}
} else {
connected_to_parent_tree_node_ = false;
}
- // Fire any events related to changes to the tree.
- for (auto& entry : tree_events_) {
- BrowserAccessibility* event_target = GetFromID(entry.first);
- if (!event_target)
- continue;
- std::set<ui::AXEvent>& events = entry.second;
- if (events.find(ui::AX_EVENT_LIVE_REGION_CREATED) != events.end() ||
- events.find(ui::AX_EVENT_ALERT) != events.end()) {
- events.erase(ui::AX_EVENT_LIVE_REGION_CHANGED);
- }
- for (auto event : events) {
- NotifyAccessibilityEvent(BrowserAccessibilityEvent::FromTreeChange, event,
- event_target);
- }
- }
- tree_events_.clear();
-
// Based on the changes to the tree, fire focus events if needed.
// Screen readers might not do the right thing if they're not aware of what
// has focus, so always try that first. Nothing will be fired if the window
// itself isn't focused or if focus hasn't changed.
- GetRootManager()->FireFocusEventsIfNeeded(
- BrowserAccessibilityEvent::FromBlink);
-
- // We are in the process of inferring all native events from tree changes.
- // Mac OS X no longer needs to iterate over the specific events coming from
- // the renderer, all needed events were fired above by iterating over
- // tree_events_.
- //
- // When all platforms have switched to inferring all events, we can delete
- // the following code, which iterates over the non-focus events from the
- // renderer and fires native events based on them.
- //
- // See http://crbug.com/699438 for details.
- for (uint32_t index = 0; index < details.size(); index++) {
- const AXEventNotificationDetails& detail = details[index];
+ GetRootManager()->FireFocusEventsIfNeeded();
- // Find the node corresponding to the id that's the target of the
- // event (which may not be the root of the update tree).
- ui::AXNode* node = tree_->GetFromId(detail.id);
- if (!node)
+ // Fire any events related to changes to the tree.
+ for (auto targeted_event : *this) {
+ BrowserAccessibility* event_target = GetFromAXNode(targeted_event.node);
+ if (!event_target)
continue;
- ui::AXEvent event_type = detail.event_type;
-
-// On Mac and Windows, nearly all events are now fired implicitly,
-// so we should ignore most events from the renderer.
-#if defined(OS_MACOSX) || defined(OS_WIN)
- if (event_type != ui::AX_EVENT_HOVER &&
- event_type != ui::AX_EVENT_LOCATION_CHANGED &&
- event_type != ui::AX_EVENT_SCROLLED_TO_ANCHOR) {
- continue;
- }
-#endif // !defined(OS_MACOSX)
+ FireGeneratedEvent(targeted_event.event, event_target);
+ }
+ ClearEvents();
- if (event_type == ui::AX_EVENT_FOCUS ||
- event_type == ui::AX_EVENT_BLUR) {
- // We already handled all focus events above.
- continue;
- }
+ // Fire events from Blink.
+ for (uint32_t index = 0; index < details.size(); index++) {
+ const AXEventNotificationDetails& detail = details[index];
// Fire the native event.
- BrowserAccessibility* event_target = GetFromAXNode(node);
- if (event_target) {
- if (event_type == ui::AX_EVENT_HOVER)
- GetRootManager()->CacheHitTestResult(event_target);
-
- NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::FromBlink,
- event_type,
- event_target);
- }
+ BrowserAccessibility* event_target = GetFromID(detail.id);
+ if (!event_target)
+ return;
+
+ if (detail.event_type == ui::AX_EVENT_HOVER)
+ GetRootManager()->CacheHitTestResult(event_target);
+
+ FireBlinkEvent(detail.event_type, event_target);
}
}
@@ -498,27 +446,6 @@ void BrowserAccessibilityManager::OnFindInPageResult(
ActivateFindInPageResult(request_id);
}
-void BrowserAccessibilityManager::OnChildFrameHitTestResult(
- const gfx::Point& point,
- int hit_obj_id,
- ui::AXEvent event_to_fire) {
- BrowserAccessibility* obj = GetFromID(hit_obj_id);
- if (!obj || !obj->HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID))
- return;
-
- BrowserAccessibilityManager* child_manager =
- BrowserAccessibilityManager::FromID(
- obj->GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID));
- if (!child_manager || !child_manager->delegate())
- return;
-
- ui::AXActionData action_data;
- action_data.target_point = point;
- action_data.action = ui::AX_ACTION_HIT_TEST;
- action_data.hit_test_event_to_fire = event_to_fire;
- return child_manager->delegate()->AccessibilityPerformAction(action_data);
-}
-
void BrowserAccessibilityManager::ActivateFindInPageResult(
int request_id) {
find_in_page_info_.active_request_id = request_id;
@@ -534,10 +461,7 @@ void BrowserAccessibilityManager::ActivateFindInPageResult(
// The "scrolled to anchor" notification is a great way to get a
// screen reader to jump directly to a specific location in a document.
- NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::FromFindInPageResult,
- ui::AX_EVENT_SCROLLED_TO_ANCHOR,
- node);
+ FireBlinkEvent(ui::AX_EVENT_SCROLLED_TO_ANCHOR, node);
}
BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendant(
@@ -813,10 +737,19 @@ BrowserAccessibility* BrowserAccessibilityManager::NextInTreeOrder(
// static
// Previous object in tree using depth-first pre-order traversal.
BrowserAccessibility* BrowserAccessibilityManager::PreviousInTreeOrder(
- const BrowserAccessibility* object) {
+ const BrowserAccessibility* object,
+ bool can_wrap_to_last_element) {
if (!object)
return nullptr;
+ // For android, this needs to be handled carefully. If not, there is a chance
+ // of getting into infinite loop.
+ if (can_wrap_to_last_element &&
+ object->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA &&
+ object->PlatformChildCount() != 0) {
+ return object->PlatformDeepestLastChild();
+ }
+
BrowserAccessibility* sibling = object->GetPreviousSibling();
if (!sibling)
return object->PlatformGetParent();
@@ -830,9 +763,9 @@ BrowserAccessibility* BrowserAccessibilityManager::PreviousInTreeOrder(
// static
BrowserAccessibility* BrowserAccessibilityManager::PreviousTextOnlyObject(
const BrowserAccessibility* object) {
- BrowserAccessibility* previous_object = PreviousInTreeOrder(object);
+ BrowserAccessibility* previous_object = PreviousInTreeOrder(object, false);
while (previous_object && !previous_object->IsTextOnlyObject())
- previous_object = PreviousInTreeOrder(previous_object);
+ previous_object = PreviousInTreeOrder(previous_object, false);
return previous_object;
}
@@ -932,7 +865,7 @@ BrowserAccessibilityManager::FindTextOnlyObjectsInRange(
const BrowserAccessibility* start_text_object = nullptr;
const BrowserAccessibility* end_text_object = nullptr;
- if (&start_object == &end_object && start_object.IsSimpleTextControl()) {
+ if (&start_object == &end_object && start_object.IsPlainTextField()) {
// We need to get to the shadow DOM that is inside the text control in order
// to find the text-only objects.
if (!start_object.InternalChildCount())
@@ -989,7 +922,7 @@ base::string16 BrowserAccessibilityManager::GetTextForRange(
DCHECK_GE(start_offset, 0);
DCHECK_GE(end_offset, 0);
- if (&start_object == &end_object && start_object.IsSimpleTextControl()) {
+ if (&start_object == &end_object && start_object.IsPlainTextField()) {
if (start_offset > end_offset)
std::swap(start_offset, end_offset);
@@ -1059,7 +992,7 @@ gfx::Rect BrowserAccessibilityManager::GetPageBoundsForRange(
DCHECK_GE(start_offset, 0);
DCHECK_GE(end_offset, 0);
- if (&start_object == &end_object && start_object.IsSimpleTextControl()) {
+ if (&start_object == &end_object && start_object.IsPlainTextField()) {
if (start_offset > end_offset)
std::swap(start_offset, end_offset);
@@ -1113,18 +1046,9 @@ gfx::Rect BrowserAccessibilityManager::GetPageBoundsForRange(
return result;
}
-void BrowserAccessibilityManager::OnNodeDataWillChange(
- ui::AXTree* tree,
- const ui::AXNodeData& old_node_data,
- const ui::AXNodeData& new_node_data) {}
-
-void BrowserAccessibilityManager::OnTreeDataChanged(
- ui::AXTree* tree,
- const ui::AXTreeData& old_tree_data,
- const ui::AXTreeData& new_tree_data) {}
-
void BrowserAccessibilityManager::OnNodeWillBeDeleted(ui::AXTree* tree,
ui::AXNode* node) {
+ AXEventGenerator::OnNodeWillBeDeleted(tree, node);
DCHECK(node);
if (id_wrapper_map_.find(node->id()) == id_wrapper_map_.end())
return;
@@ -1134,6 +1058,7 @@ void BrowserAccessibilityManager::OnNodeWillBeDeleted(ui::AXTree* tree,
void BrowserAccessibilityManager::OnSubtreeWillBeDeleted(ui::AXTree* tree,
ui::AXNode* node) {
+ AXEventGenerator::OnSubtreeWillBeDeleted(tree, node);
DCHECK(node);
BrowserAccessibility* obj = GetFromAXNode(node);
if (obj)
@@ -1142,24 +1067,33 @@ void BrowserAccessibilityManager::OnSubtreeWillBeDeleted(ui::AXTree* tree,
void BrowserAccessibilityManager::OnNodeWillBeReparented(ui::AXTree* tree,
ui::AXNode* node) {
+ AXEventGenerator::OnNodeWillBeReparented(tree, node);
// BrowserAccessibility should probably ask the tree source for the AXNode via
// an id rather than weakly holding a pointer to a AXNode that might have been
// destroyed under the hood and re-created later on. Treat this as a delete to
// make things work.
- OnNodeWillBeDeleted(tree, node);
+ if (id_wrapper_map_.find(node->id()) == id_wrapper_map_.end())
+ return;
+ GetFromAXNode(node)->Destroy();
+ id_wrapper_map_.erase(node->id());
}
void BrowserAccessibilityManager::OnSubtreeWillBeReparented(ui::AXTree* tree,
ui::AXNode* node) {
+ AXEventGenerator::OnSubtreeWillBeReparented(tree, node);
// BrowserAccessibility should probably ask the tree source for the AXNode via
// an id rather than weakly holding a pointer to a AXNode that might have been
// destroyed under the hood and re-created later on. Treat this as a delete to
// make things work.
- OnSubtreeWillBeDeleted(tree, node);
+ DCHECK(node);
+ BrowserAccessibility* obj = GetFromAXNode(node);
+ if (obj)
+ obj->OnSubtreeWillBeDeleted();
}
void BrowserAccessibilityManager::OnNodeCreated(ui::AXTree* tree,
ui::AXNode* node) {
+ AXEventGenerator::OnNodeCreated(tree, node);
BrowserAccessibility* wrapper = factory_->Create();
wrapper->Init(this, node);
id_wrapper_map_[node->id()] = wrapper;
@@ -1168,15 +1102,20 @@ void BrowserAccessibilityManager::OnNodeCreated(ui::AXTree* tree,
void BrowserAccessibilityManager::OnNodeReparented(ui::AXTree* tree,
ui::AXNode* node) {
+ AXEventGenerator::OnNodeReparented(tree, node);
// BrowserAccessibility should probably ask the tree source for the AXNode via
// an id rather than weakly holding a pointer to a AXNode that might have been
// destroyed under the hood and re-created later on. Treat this as a create to
// make things work.
- OnNodeCreated(tree, node);
+ BrowserAccessibility* wrapper = factory_->Create();
+ wrapper->Init(this, node);
+ id_wrapper_map_[node->id()] = wrapper;
+ wrapper->OnDataChanged();
}
void BrowserAccessibilityManager::OnNodeChanged(ui::AXTree* tree,
ui::AXNode* node) {
+ AXEventGenerator::OnNodeChanged(tree, node);
DCHECK(node);
GetFromAXNode(node)->OnDataChanged();
}
@@ -1185,6 +1124,7 @@ void BrowserAccessibilityManager::OnAtomicUpdateFinished(
ui::AXTree* tree,
bool root_changed,
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_) {
g_ax_tree_id_map.Get().erase(ax_tree_id_);
@@ -1205,24 +1145,6 @@ void BrowserAccessibilityManager::OnAtomicUpdateFinished(
last_focused_node_ = nullptr;
last_focused_manager_ = nullptr;
}
-
- // Notify ATs if any live regions have been created.
- for (auto& change : changes) {
- if (change.type != NODE_CREATED && change.type != SUBTREE_CREATED)
- continue;
-
- const ui::AXNode* created_node = change.node;
- DCHECK(created_node);
- BrowserAccessibility* object = GetFromAXNode(created_node);
- if (object && object->HasStringAttribute(ui::AX_ATTR_LIVE_STATUS)) {
- int32_t id = object->GetId();
- if (object->GetRole() == ui::AX_ROLE_ALERT) {
- tree_events_[id].insert(ui::AX_EVENT_ALERT);
- } else {
- tree_events_[id].insert(ui::AX_EVENT_LIVE_REGION_CREATED);
- }
- }
- }
}
BrowserAccessibilityManager* BrowserAccessibilityManager::GetRootManager() {
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager.h b/chromium/content/browser/accessibility/browser_accessibility_manager.h
index 9fdf2e240fe..96deed77686 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager.h
@@ -15,12 +15,12 @@
#include "base/macros.h"
#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_flags.h"
-#include "content/browser/accessibility/ax_platform_position.h"
-#include "content/browser/accessibility/browser_accessibility_event.h"
+#include "content/browser/accessibility/browser_accessibility_position.h"
#include "content/common/content_export.h"
#include "content/public/browser/ax_event_notification_details.h"
#include "third_party/WebKit/public/web/WebAXEnums.h"
#include "ui/accessibility/ax_action_data.h"
+#include "ui/accessibility/ax_event_generator.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_range.h"
#include "ui/accessibility/ax_serializable_tree.h"
@@ -110,7 +110,7 @@ struct BrowserAccessibilityFindInPageInfo {
};
// Manages a tree of BrowserAccessibility objects.
-class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
+class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXEventGenerator {
public:
// Creates the platform-specific BrowserAccessibilityManager, but
// with no parent window pointer. Only useful for unit tests.
@@ -128,24 +128,21 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
static ui::AXTreeUpdate GetEmptyDocument();
- virtual void NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::Source source,
- ui::AXEvent event_type,
- BrowserAccessibility* node);
+ // Subclasses override these methods to send native event notifications.
+ virtual void FireFocusEvent(BrowserAccessibility* node);
+ virtual void FireBlinkEvent(ui::AXEvent event_type,
+ BrowserAccessibility* node) {}
+ virtual void FireGeneratedEvent(AXEventGenerator::Event event_type,
+ BrowserAccessibility* node) {}
// Checks whether focus has changed since the last time it was checked,
// taking into account whether the window has focus and which frame within
// the frame tree has focus. If focus has changed, calls FireFocusEvent.
- void FireFocusEventsIfNeeded(BrowserAccessibilityEvent::Source source);
+ void FireFocusEventsIfNeeded();
// Return whether or not we are currently able to fire events.
virtual bool CanFireEvents();
- // Fire a focus event. Virtual so that some platforms can customize it,
- // like firing a focus event on the root first, on Windows.
- virtual void FireFocusEvent(BrowserAccessibilityEvent::Source source,
- BrowserAccessibility* node);
-
// Return a pointer to the root of the tree, does not make a new reference.
BrowserAccessibility* GetRoot();
@@ -212,7 +209,9 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
void SetValue(
const BrowserAccessibility& node, const base::string16& value);
void SetSelection(
- ui::AXRange<AXPlatformPosition::AXPositionInstance::element_type> range);
+ ui::AXRange<
+ BrowserAccessibilityPosition::AXPositionInstance::element_type>
+ range);
void ShowContextMenu(const BrowserAccessibility& node);
// Retrieve the bounds of the parent View in screen coordinates.
@@ -237,13 +236,6 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
int request_id, int match_index, int start_id, int start_offset,
int end_id, int end_offset);
- // Called in response to a hit test, when the object hit has a child frame
- // (like an iframe element or browser plugin), and we need to do another
- // hit test recursively.
- void OnChildFrameHitTestResult(const gfx::Point& point,
- int hit_obj_id,
- ui::AXEvent event_to_fire);
-
// This is called when the user has committed to a find in page query,
// e.g. by pressing enter or tapping on the next / previous result buttons.
// If a match has already been received for this request id,
@@ -291,7 +283,8 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
static BrowserAccessibility* NextInTreeOrder(
const BrowserAccessibility* object);
static BrowserAccessibility* PreviousInTreeOrder(
- const BrowserAccessibility* object);
+ const BrowserAccessibility* object,
+ bool can_wrap_to_last_element);
static BrowserAccessibility* NextTextOnlyObject(
const BrowserAccessibility* object);
static BrowserAccessibility* PreviousTextOnlyObject(
@@ -342,12 +335,6 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
const ui::AXTree* ax_tree() const { return tree_.get(); }
// AXTreeDelegate implementation.
- void OnNodeDataWillChange(ui::AXTree* tree,
- const ui::AXNodeData& old_node_data,
- const ui::AXNodeData& new_node_data) override;
- void OnTreeDataChanged(ui::AXTree* tree,
- const ui::AXTreeData& old_tree_data,
- const ui::AXTreeData& new_tree_data) override;
void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
void OnSubtreeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
void OnNodeWillBeReparented(ui::AXTree* tree, ui::AXNode* node) override;
@@ -390,8 +377,10 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
void CacheHitTestResult(BrowserAccessibility* hit_test_result);
protected:
- using AXPlatformPositionInstance = AXPlatformPosition::AXPositionInstance;
- using AXPlatformRange = ui::AXRange<AXPlatformPositionInstance::element_type>;
+ using BrowserAccessibilityPositionInstance =
+ BrowserAccessibilityPosition::AXPositionInstance;
+ using AXPlatformRange =
+ ui::AXRange<BrowserAccessibilityPositionInstance::element_type>;
BrowserAccessibilityManager(
BrowserAccessibilityDelegate* delegate,
@@ -421,11 +410,6 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
// A mapping from a node id to its wrapper of type BrowserAccessibility.
base::hash_map<int32_t, BrowserAccessibility*> id_wrapper_map_;
- // A set of accessibility events to fire based on changes to the
- // accessibility tree. It's represented as a map from node id
- // to a set of events, which makes it easy to remove duplicates.
- std::map<int32_t, std::set<ui::AXEvent>> tree_events_;
-
// True if the user has initiated a navigation to another page.
bool user_is_navigating_away_;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc
index 284c4019b1f..aff0ed4623f 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -8,6 +8,7 @@
#include "content/browser/accessibility/browser_accessibility_android.h"
#include "content/browser/accessibility/web_contents_accessibility_android.h"
#include "content/common/accessibility_messages.h"
+#include "ui/accessibility/ax_role_properties.h"
namespace content {
@@ -65,39 +66,71 @@ bool BrowserAccessibilityManagerAndroid::ShouldExposePasswordText() {
BrowserAccessibility* BrowserAccessibilityManagerAndroid::GetFocus() {
BrowserAccessibility* focus = BrowserAccessibilityManager::GetFocus();
- BrowserAccessibilityAndroid* android_focus =
- static_cast<BrowserAccessibilityAndroid*>(focus);
- // This is a temporary workaround because we're not distinguishing
- // between text fields with a role of combobox, and pop-up menu buttons.
- // TODO(dmazzoni): Handle different types of combo boxes correctly.
- if (!android_focus->IsEditableText())
+ if (!focus->IsPlainTextField())
return GetActiveDescendant(focus);
return focus;
}
-void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::Source source,
- ui::AXEvent event_type,
+void BrowserAccessibilityManagerAndroid::FireFocusEvent(
BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireFocusEvent(node);
WebContentsAccessibilityAndroid* wcax = GetWebContentsAXFromRootManager();
if (!wcax)
return;
- if (event_type == ui::AX_EVENT_HIDE)
- return;
+ BrowserAccessibilityAndroid* android_node =
+ static_cast<BrowserAccessibilityAndroid*>(node);
+ wcax->HandleFocusChanged(android_node->unique_id());
+}
- if (event_type == ui::AX_EVENT_TREE_CHANGED)
+void BrowserAccessibilityManagerAndroid::FireLocationChanged(
+ BrowserAccessibility* node) {
+ WebContentsAccessibilityAndroid* wcax = GetWebContentsAXFromRootManager();
+ if (!wcax)
return;
- // Layout changes are handled in OnLocationChanges and
- // SendLocationChangeEvents.
- if (event_type == ui::AX_EVENT_LAYOUT_COMPLETE)
- return;
+ BrowserAccessibilityAndroid* android_node =
+ static_cast<BrowserAccessibilityAndroid*>(node);
+ wcax->HandleContentChanged(android_node->unique_id());
+}
- if (event_type == ui::AX_EVENT_HOVER) {
- HandleHoverEvent(node);
+void BrowserAccessibilityManagerAndroid::FireBlinkEvent(
+ ui::AXEvent event_type,
+ BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireBlinkEvent(event_type, node);
+ WebContentsAccessibilityAndroid* wcax = GetWebContentsAXFromRootManager();
+ if (!wcax)
return;
+
+ // Sometimes we get events on nodes in our internal accessibility tree
+ // that aren't exposed on Android. Update |node| to point to the highest
+ // ancestor that's a leaf node.
+ node = node->GetClosestPlatformObject();
+ BrowserAccessibilityAndroid* android_node =
+ static_cast<BrowserAccessibilityAndroid*>(node);
+
+ switch (event_type) {
+ case ui::AX_EVENT_HOVER:
+ HandleHoverEvent(node);
+ break;
+ case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
+ wcax->HandleScrolledToAnchor(android_node->unique_id());
+ break;
+ case ui::AX_EVENT_CLICKED:
+ wcax->HandleClicked(android_node->unique_id());
+ break;
+ default:
+ break;
}
+}
+
+void BrowserAccessibilityManagerAndroid::FireGeneratedEvent(
+ AXEventGenerator::Event event_type,
+ BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireGeneratedEvent(event_type, node);
+ WebContentsAccessibilityAndroid* wcax = GetWebContentsAXFromRootManager();
+ if (!wcax)
+ return;
// Sometimes we get events on nodes in our internal accessibility tree
// that aren't exposed on Android. Update |node| to point to the highest
@@ -122,55 +155,64 @@ void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent(
// node has changed.
wcax->HandleContentChanged(android_node->unique_id());
- // Ignore load complete events on iframes.
- if (event_type == ui::AX_EVENT_LOAD_COMPLETE &&
- node->manager() != GetRootManager()) {
- return;
- }
-
switch (event_type) {
- case ui::AX_EVENT_LOAD_COMPLETE: {
- auto* android_focused =
- static_cast<BrowserAccessibilityAndroid*>(GetFocus());
- wcax->HandlePageLoaded(android_focused->unique_id());
- } break;
- case ui::AX_EVENT_FOCUS:
- wcax->HandleFocusChanged(android_node->unique_id());
+ case Event::LOAD_COMPLETE:
+ if (node->manager() == GetRootManager()) {
+ auto* android_focused =
+ static_cast<BrowserAccessibilityAndroid*>(GetFocus());
+ wcax->HandlePageLoaded(android_focused->unique_id());
+ }
break;
- case ui::AX_EVENT_CHECKED_STATE_CHANGED:
+ case Event::CHECKED_STATE_CHANGED:
wcax->HandleCheckStateChanged(android_node->unique_id());
break;
- case ui::AX_EVENT_CLICKED:
- wcax->HandleClicked(android_node->unique_id());
- break;
- case ui::AX_EVENT_SCROLL_POSITION_CHANGED:
+ case Event::SCROLL_POSITION_CHANGED:
wcax->HandleScrollPositionChanged(android_node->unique_id());
break;
- case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
- wcax->HandleScrolledToAnchor(android_node->unique_id());
- break;
- case ui::AX_EVENT_ALERT:
- // An alert is a special case of live region. Fall through to the
- // next case to handle it.
- case ui::AX_EVENT_SHOW: {
+ case Event::ALERT:
+ // An alert is a special case of live region. Fall through to the
+ // next case to handle it.
+ case Event::LIVE_REGION_NODE_CHANGED: {
// This event is fired when an object appears in a live region.
// Speak its text.
base::string16 text = android_node->GetText();
wcax->AnnounceLiveRegionText(text);
break;
}
- case ui::AX_EVENT_TEXT_SELECTION_CHANGED:
- wcax->HandleTextSelectionChanged(android_node->unique_id());
+ case Event::DOCUMENT_SELECTION_CHANGED: {
+ int32_t focus_id = GetTreeData().sel_focus_object_id;
+ BrowserAccessibility* focus_object = GetFromID(focus_id);
+ if (focus_object) {
+ BrowserAccessibilityAndroid* android_focus_object =
+ static_cast<BrowserAccessibilityAndroid*>(focus_object);
+ wcax->HandleTextSelectionChanged(android_focus_object->unique_id());
+ }
break;
- case ui::AX_EVENT_TEXT_CHANGED:
- case ui::AX_EVENT_VALUE_CHANGED:
+ }
+ case Event::VALUE_CHANGED:
if (android_node->IsEditableText() && GetFocus() == node) {
wcax->HandleEditableTextChanged(android_node->unique_id());
} else if (android_node->IsSlider()) {
wcax->HandleSliderChanged(android_node->unique_id());
}
break;
- default:
+ case Event::ACTIVE_DESCENDANT_CHANGED:
+ case Event::CHILDREN_CHANGED:
+ case Event::COLLAPSED:
+ case Event::DESCRIPTION_CHANGED:
+ case Event::DOCUMENT_TITLE_CHANGED:
+ case Event::EXPANDED:
+ case Event::INVALID_STATUS_CHANGED:
+ case Event::LIVE_REGION_CHANGED:
+ case Event::LIVE_REGION_CREATED:
+ case Event::MENU_ITEM_SELECTED:
+ case Event::NAME_CHANGED:
+ case Event::OTHER_ATTRIBUTE_CHANGED:
+ case Event::ROLE_CHANGED:
+ case Event::ROW_COUNT_CHANGED:
+ case Event::SELECTED_CHANGED:
+ case Event::SELECTED_CHILDREN_CHANGED:
+ case Event::STATE_CHANGED:
// There are some notifications that aren't meaningful on Android.
// It's okay to skip them.
break;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_android.h b/chromium/content/browser/accessibility/browser_accessibility_manager_android.h
index 13df13f72a2..355792f717a 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_android.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -78,13 +78,16 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAndroid
// BrowserAccessibilityManager overrides.
BrowserAccessibility* GetFocus() override;
- void NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::Source source,
- ui::AXEvent event_type,
- BrowserAccessibility* node) override;
void SendLocationChangeEvents(
const std::vector<AccessibilityHostMsg_LocationChangeParams>& params)
override;
+ void FireFocusEvent(BrowserAccessibility* node) override;
+ void FireBlinkEvent(ui::AXEvent event_type,
+ BrowserAccessibility* node) override;
+ void FireGeneratedEvent(AXEventGenerator::Event event_type,
+ BrowserAccessibility* node) override;
+
+ void FireLocationChanged(BrowserAccessibility* node);
// Helper functions to compute the next start and end index when moving
// forwards or backwards by character, word, or line. This part is
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
index 6646f7b4881..1464e6f4169 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
@@ -48,11 +48,24 @@ ui::AXTreeUpdate
return update;
}
-void BrowserAccessibilityManagerAuraLinux::NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::Source source,
+void BrowserAccessibilityManagerAuraLinux::FireFocusEvent(
+ BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireFocusEvent(node);
+ // Need to implement.
+}
+
+void BrowserAccessibilityManagerAuraLinux::FireBlinkEvent(
ui::AXEvent event_type,
BrowserAccessibility* node) {
- // TODO(shreeram.k) : Implement.
+ BrowserAccessibilityManager::FireBlinkEvent(event_type, node);
+ // Need to implement.
+}
+
+void BrowserAccessibilityManagerAuraLinux::FireGeneratedEvent(
+ AXEventGenerator::Event event_type,
+ BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireGeneratedEvent(event_type, node);
+ // Need to implement.
}
} // namespace content
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h
index 1f69769cc0b..4d47128efa8 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h
@@ -25,11 +25,12 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAuraLinux
static ui::AXTreeUpdate GetEmptyDocument();
- // Implementation BrowserAccessibilityManager methods
- void NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::Source source,
- ui::AXEvent event_type,
- BrowserAccessibility* node) override;
+ // Implementation of BrowserAccessibilityManager methods.
+ void FireFocusEvent(BrowserAccessibility* node) override;
+ void FireBlinkEvent(ui::AXEvent event_type,
+ BrowserAccessibility* node) override;
+ void FireGeneratedEvent(AXEventGenerator::Event event_type,
+ BrowserAccessibility* node) override;
AtkObject* parent_object() { return parent_object_; }
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h
index d5508ba09af..bf5626f049f 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h
@@ -34,10 +34,11 @@ class CONTENT_EXPORT BrowserAccessibilityManagerMac
BrowserAccessibility* GetFocus() override;
// Implementation of BrowserAccessibilityManager.
- void NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::Source source,
- ui::AXEvent event_type,
- BrowserAccessibility* node) override;
+ void FireFocusEvent(BrowserAccessibility* node) override;
+ void FireBlinkEvent(ui::AXEvent event_type,
+ BrowserAccessibility* node) override;
+ void FireGeneratedEvent(AXEventGenerator::Event event_type,
+ BrowserAccessibility* node) override;
void OnAccessibilityEvents(
const std::vector<AXEventNotificationDetails>& details) override;
@@ -45,29 +46,10 @@ class CONTENT_EXPORT BrowserAccessibilityManagerMac
NSView* GetParentView();
private:
+ void FireNativeMacNotification(NSString* mac_notification,
+ BrowserAccessibility* node);
+
// AXTreeDelegate methods.
- void OnTreeDataChanged(ui::AXTree* tree,
- const ui::AXTreeData& old_tree_data,
- const ui::AXTreeData& new_tree_data) override;
- void OnStateChanged(ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXState state,
- bool new_value) override;
- void OnStringAttributeChanged(ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXStringAttribute attr,
- const std::string& old_value,
- const std::string& new_value) override;
- void OnIntAttributeChanged(ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXIntAttribute attr,
- int32_t old_value,
- int32_t new_value) override;
- void OnFloatAttributeChanged(ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXFloatAttribute attr,
- float old_value,
- float new_value) override;
void OnAtomicUpdateFinished(ui::AXTree* tree,
bool root_changed,
const std::vector<Change>& changes) override;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
index f798789bf05..33c5ec07d1d 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -94,8 +94,6 @@ NSString* const NSAccessibilityTextSelectionGranularity =
@"AXTextSelectionGranularity";
NSString* const NSAccessibilityTextSelectionChangedFocus =
@"AXTextSelectionChangedFocus";
-NSString* const NSAccessibilitySelectedTextMarkerRangeAttribute =
- @"AXSelectedTextMarkerRange";
NSString* const NSAccessibilityTextChangeElement = @"AXTextChangeElement";
NSString* const NSAccessibilityTextEditType = @"AXTextEditType";
NSString* const NSAccessibilityTextChangeValue = @"AXTextChangeValue";
@@ -150,8 +148,7 @@ BrowserAccessibility* BrowserAccessibilityManagerMac::GetFocus() {
// For editable combo boxes, focus should stay on the combo box so the user
// will not be taken out of the combo box while typing.
if (focus && (focus->GetRole() == ui::AX_ROLE_LIST_BOX ||
- (focus->GetRole() == ui::AX_ROLE_COMBO_BOX &&
- focus->HasState(ui::AX_STATE_EDITABLE)))) {
+ (focus->GetRole() == ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX))) {
return focus;
}
@@ -159,10 +156,36 @@ BrowserAccessibility* BrowserAccessibilityManagerMac::GetFocus() {
return GetActiveDescendant(focus);
}
-void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::Source source,
+void BrowserAccessibilityManagerMac::FireFocusEvent(
+ BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireFocusEvent(node);
+ FireNativeMacNotification(NSAccessibilityFocusedUIElementChangedNotification,
+ node);
+}
+
+void BrowserAccessibilityManagerMac::FireBlinkEvent(
ui::AXEvent event_type,
BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireBlinkEvent(event_type, node);
+ NSString* mac_notification = nullptr;
+ switch (event_type) {
+ case ui::AX_EVENT_AUTOCORRECTION_OCCURED:
+ mac_notification = NSAccessibilityAutocorrectionOccurredNotification;
+ break;
+ case ui::AX_EVENT_LAYOUT_COMPLETE:
+ mac_notification = NSAccessibilityLayoutCompleteNotification;
+ break;
+ default:
+ return;
+ }
+
+ FireNativeMacNotification(mac_notification, node);
+}
+
+void BrowserAccessibilityManagerMac::FireGeneratedEvent(
+ AXEventGenerator::Event event_type,
+ BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireGeneratedEvent(event_type, node);
if (!node->IsNative())
return;
@@ -170,12 +193,12 @@ void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
DCHECK(native_node);
// Refer to |AXObjectCache::postPlatformNotification| in WebKit source code.
- NSString* mac_notification;
+ NSString* mac_notification = nullptr;
switch (event_type) {
- case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
+ case Event::ACTIVE_DESCENDANT_CHANGED:
if (node->GetRole() == ui::AX_ROLE_TREE) {
mac_notification = NSAccessibilitySelectedRowsChangedNotification;
- } else if (node->GetRole() == ui::AX_ROLE_COMBO_BOX) {
+ } else if (node->GetRole() == ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX) {
// Even though the selected item in the combo box has changed, we don't
// want to post a focus change because this will take the focus out of
// the combo box where the user might be typing.
@@ -187,16 +210,7 @@ void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
return;
}
break;
- case ui::AX_EVENT_AUTOCORRECTION_OCCURED:
- mac_notification = NSAccessibilityAutocorrectionOccurredNotification;
- break;
- case ui::AX_EVENT_FOCUS:
- mac_notification = NSAccessibilityFocusedUIElementChangedNotification;
- break;
- case ui::AX_EVENT_LAYOUT_COMPLETE:
- mac_notification = NSAccessibilityLayoutCompleteNotification;
- break;
- case ui::AX_EVENT_LOAD_COMPLETE:
+ case Event::LOAD_COMPLETE:
// This notification should only be fired on the top document.
// Iframes should use |AX_EVENT_LAYOUT_COMPLETE| to signify that they have
// finished loading.
@@ -206,17 +220,17 @@ void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
mac_notification = NSAccessibilityLayoutCompleteNotification;
}
break;
- case ui::AX_EVENT_INVALID_STATUS_CHANGED:
+ case Event::INVALID_STATUS_CHANGED:
mac_notification = NSAccessibilityInvalidStatusChangedNotification;
break;
- case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED:
+ case Event::SELECTED_CHILDREN_CHANGED:
if (ui::IsTableLikeRole(node->GetRole())) {
mac_notification = NSAccessibilitySelectedRowsChangedNotification;
} else {
mac_notification = NSAccessibilitySelectedChildrenChangedNotification;
}
break;
- case ui::AX_EVENT_DOCUMENT_SELECTION_CHANGED: {
+ case Event::DOCUMENT_SELECTION_CHANGED: {
mac_notification = NSAccessibilitySelectedTextChangedNotification;
// WebKit fires a notification both on the focused object and the page
// root.
@@ -250,10 +264,10 @@ void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
}
break;
}
- case ui::AX_EVENT_CHECKED_STATE_CHANGED:
+ case Event::CHECKED_STATE_CHANGED:
mac_notification = NSAccessibilityValueChangedNotification;
break;
- case ui::AX_EVENT_VALUE_CHANGED:
+ case Event::VALUE_CHANGED:
mac_notification = NSAccessibilityValueChangedNotification;
if (base::mac::IsAtLeastOS10_11() && !text_edits_.empty()) {
base::string16 deleted_text;
@@ -280,18 +294,17 @@ void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
return;
}
break;
- case ui::AX_EVENT_LIVE_REGION_CREATED:
+ case Event::LIVE_REGION_CREATED:
mac_notification = NSAccessibilityLiveRegionCreatedNotification;
break;
- case ui::AX_EVENT_ALERT:
+ case Event::ALERT:
NSAccessibilityPostNotification(
native_node, NSAccessibilityLiveRegionCreatedNotification);
// Voiceover requires a live region changed notification to actually
// announce the live region.
- NotifyAccessibilityEvent(BrowserAccessibilityEvent::FromTreeChange,
- ui::AX_EVENT_LIVE_REGION_CHANGED, node);
+ FireGeneratedEvent(Event::LIVE_REGION_CHANGED, node);
return;
- case ui::AX_EVENT_LIVE_REGION_CHANGED: {
+ case Event::LIVE_REGION_CHANGED: {
// Voiceover seems to drop live region changed notifications if they come
// too soon after a live region created notification.
// TODO(nektar): Limit the number of changed notifications as well.
@@ -315,48 +328,57 @@ void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
},
std::move(retained_node)),
base::TimeDelta::FromMilliseconds(kLiveRegionChangeIntervalMS));
- }
return;
- case ui::AX_EVENT_ROW_COUNT_CHANGED:
+ }
+ case Event::ROW_COUNT_CHANGED:
mac_notification = NSAccessibilityRowCountChangedNotification;
break;
- case ui::AX_EVENT_ROW_EXPANDED:
- mac_notification = NSAccessibilityRowExpandedNotification;
- break;
- case ui::AX_EVENT_ROW_COLLAPSED:
- mac_notification = NSAccessibilityRowCollapsedNotification;
+ case Event::EXPANDED:
+ if (node->GetRole() == ui::AX_ROLE_ROW ||
+ node->GetRole() == ui::AX_ROLE_TREE_ITEM) {
+ mac_notification = NSAccessibilityRowExpandedNotification;
+ } else {
+ mac_notification = NSAccessibilityExpandedChanged;
+ }
break;
- // TODO(nektar): Add events for busy.
- case ui::AX_EVENT_EXPANDED_CHANGED:
- mac_notification = NSAccessibilityExpandedChanged;
+ case Event::COLLAPSED:
+ if (node->GetRole() == ui::AX_ROLE_ROW ||
+ node->GetRole() == ui::AX_ROLE_TREE_ITEM) {
+ mac_notification = NSAccessibilityRowCollapsedNotification;
+ } else {
+ mac_notification = NSAccessibilityExpandedChanged;
+ }
break;
- // TODO(nektar): Support menu open/close notifications.
- case ui::AX_EVENT_MENU_LIST_ITEM_SELECTED:
+ case Event::MENU_ITEM_SELECTED:
mac_notification = NSAccessibilityMenuItemSelectedNotification;
break;
-
- // These events are not used on Mac for now.
- case ui::AX_EVENT_TEXT_CHANGED:
- case ui::AX_EVENT_CHILDREN_CHANGED:
- case ui::AX_EVENT_MENU_LIST_VALUE_CHANGED:
- case ui::AX_EVENT_SCROLL_POSITION_CHANGED:
- case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
- case ui::AX_EVENT_ARIA_ATTRIBUTE_CHANGED:
- case ui::AX_EVENT_LOCATION_CHANGED:
- return;
-
- // Deprecated events.
- case ui::AX_EVENT_BLUR:
- case ui::AX_EVENT_HIDE:
- case ui::AX_EVENT_HOVER:
- case ui::AX_EVENT_TEXT_SELECTION_CHANGED:
- case ui::AX_EVENT_SHOW:
- return;
- default:
- DLOG(WARNING) << "Unknown accessibility event: " << event_type;
+ case Event::CHILDREN_CHANGED:
+ case Event::DESCRIPTION_CHANGED:
+ case Event::DOCUMENT_TITLE_CHANGED:
+ case Event::LIVE_REGION_NODE_CHANGED:
+ case Event::NAME_CHANGED:
+ case Event::OTHER_ATTRIBUTE_CHANGED:
+ case Event::ROLE_CHANGED:
+ case Event::SCROLL_POSITION_CHANGED:
+ case Event::SELECTED_CHANGED:
+ case Event::STATE_CHANGED:
+ // There are some notifications that aren't meaningful on Mac.
+ // It's okay to skip them.
return;
}
+ FireNativeMacNotification(mac_notification, node);
+}
+
+void BrowserAccessibilityManagerMac::FireNativeMacNotification(
+ NSString* mac_notification,
+ BrowserAccessibility* node) {
+ if (!node->IsNative())
+ return;
+
+ DCHECK(mac_notification);
+ auto native_node = ToBrowserAccessibilityCocoa(node);
+ DCHECK(native_node);
NSAccessibilityPostNotification(native_node, mac_notification);
}
@@ -368,116 +390,6 @@ void BrowserAccessibilityManagerMac::OnAccessibilityEvents(
BrowserAccessibilityManager::OnAccessibilityEvents(details);
}
-void BrowserAccessibilityManagerMac::OnTreeDataChanged(
- ui::AXTree* tree,
- const ui::AXTreeData& old_tree_data,
- const ui::AXTreeData& new_tree_data) {
- BrowserAccessibilityManager::OnTreeDataChanged(tree, old_tree_data,
- new_tree_data);
- if (new_tree_data.loaded && !old_tree_data.loaded)
- tree_events_[tree->root()->id()].insert(ui::AX_EVENT_LOAD_COMPLETE);
- if (new_tree_data.sel_anchor_object_id !=
- old_tree_data.sel_anchor_object_id ||
- new_tree_data.sel_anchor_offset != old_tree_data.sel_anchor_offset ||
- new_tree_data.sel_anchor_affinity != old_tree_data.sel_anchor_affinity ||
- new_tree_data.sel_focus_object_id != old_tree_data.sel_focus_object_id ||
- new_tree_data.sel_focus_offset != old_tree_data.sel_focus_offset ||
- new_tree_data.sel_focus_affinity != old_tree_data.sel_focus_affinity) {
- tree_events_[tree->root()->id()].insert(
- ui::AX_EVENT_DOCUMENT_SELECTION_CHANGED);
- }
-}
-
-void BrowserAccessibilityManagerMac::OnStateChanged(ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXState state,
- bool new_value) {
- BrowserAccessibilityManager::OnStateChanged(tree, node, state, new_value);
- if (state == ui::AX_STATE_EXPANDED) {
- if (node->data().role == ui::AX_ROLE_ROW ||
- node->data().role == ui::AX_ROLE_TREE_ITEM) {
- if (new_value)
- tree_events_[node->id()].insert(ui::AX_EVENT_ROW_EXPANDED);
- else
- tree_events_[node->id()].insert(ui::AX_EVENT_ROW_COLLAPSED);
- ui::AXNode* container = node;
- while (container && !ui::IsRowContainer(container->data().role))
- container = container->parent();
- if (container)
- tree_events_[container->id()].insert(ui::AX_EVENT_ROW_COUNT_CHANGED);
- } else {
- tree_events_[node->id()].insert(ui::AX_EVENT_EXPANDED_CHANGED);
- }
- }
- if (state == ui::AX_STATE_SELECTED) {
- ui::AXNode* container = node;
- while (container &&
- !ui::IsContainerWithSelectableChildrenRole(container->data().role))
- container = container->parent();
- if (container)
- tree_events_[container->id()].insert(
- ui::AX_EVENT_SELECTED_CHILDREN_CHANGED);
- }
-}
-
-void BrowserAccessibilityManagerMac::OnStringAttributeChanged(
- ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXStringAttribute attr,
- const std::string& old_value,
- const std::string& new_value) {
- BrowserAccessibilityManager::OnStringAttributeChanged(tree, node, attr,
- old_value, new_value);
- switch (attr) {
- case ui::AX_ATTR_VALUE:
- tree_events_[node->id()].insert(ui::AX_EVENT_VALUE_CHANGED);
- break;
- case ui::AX_ATTR_ARIA_INVALID_VALUE:
- tree_events_[node->id()].insert(ui::AX_EVENT_INVALID_STATUS_CHANGED);
- break;
- case ui::AX_ATTR_LIVE_STATUS:
- tree_events_[node->id()].insert(ui::AX_EVENT_LIVE_REGION_CREATED);
- break;
- default:
- break;
- }
-}
-
-void BrowserAccessibilityManagerMac::OnIntAttributeChanged(
- ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXIntAttribute attr,
- int32_t old_value,
- int32_t new_value) {
- BrowserAccessibilityManager::OnIntAttributeChanged(tree, node, attr,
- old_value, new_value);
- switch (attr) {
- case ui::AX_ATTR_CHECKED_STATE:
- tree_events_[node->id()].insert(ui::AX_EVENT_VALUE_CHANGED);
- break;
- case ui::AX_ATTR_ACTIVEDESCENDANT_ID:
- tree_events_[node->id()].insert(ui::AX_EVENT_ACTIVEDESCENDANTCHANGED);
- break;
- case ui::AX_ATTR_INVALID_STATE:
- tree_events_[node->id()].insert(ui::AX_EVENT_INVALID_STATUS_CHANGED);
- break;
- default:
- break;
- }
-}
-
-void BrowserAccessibilityManagerMac::OnFloatAttributeChanged(
- ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXFloatAttribute attr,
- float old_value,
- float new_value) {
- BrowserAccessibilityManager::OnFloatAttributeChanged(tree, node, attr,
- old_value, new_value);
- if (attr == ui::AX_ATTR_VALUE_FOR_RANGE)
- tree_events_[node->id()].insert(ui::AX_EVENT_VALUE_CHANGED);
-}
-
void BrowserAccessibilityManagerMac::OnAtomicUpdateFinished(
ui::AXTree* tree,
bool root_changed,
@@ -494,25 +406,6 @@ void BrowserAccessibilityManagerMac::OnAtomicUpdateFinished(
if (editable_root && [editable_root instanceActive])
changed_editable_roots.insert(editable_root);
}
-
- if ((change.type == NODE_CREATED || change.type == SUBTREE_CREATED) &&
- change.node->data().HasStringAttribute(ui::AX_ATTR_LIVE_STATUS)) {
- if (change.node->data().role == ui::AX_ROLE_ALERT)
- tree_events_[change.node->id()].insert(ui::AX_EVENT_ALERT);
- else
- tree_events_[change.node->id()].insert(
- ui::AX_EVENT_LIVE_REGION_CREATED);
- continue;
- }
- if (change.node->data().HasStringAttribute(
- ui::AX_ATTR_CONTAINER_LIVE_STATUS)) {
- ui::AXNode* live_root = change.node;
- while (live_root &&
- !live_root->data().HasStringAttribute(ui::AX_ATTR_LIVE_STATUS))
- live_root = live_root->parent();
- if (live_root)
- tree_events_[live_root->id()].insert(ui::AX_EVENT_LIVE_REGION_CHANGED);
- }
}
for (const BrowserAccessibilityCocoa* obj : changed_editable_roots) {
@@ -521,9 +414,6 @@ void BrowserAccessibilityManagerMac::OnAtomicUpdateFinished(
if (!text_edit.IsEmpty())
text_edits_[[obj browserAccessibility]->GetId()] = text_edit;
}
-
- if (root_changed && tree->data().loaded)
- tree_events_[tree->root()->id()].insert(ui::AX_EVENT_LOAD_COMPLETE);
}
NSDictionary* BrowserAccessibilityManagerMac::
@@ -550,6 +440,8 @@ NSDictionary* BrowserAccessibilityManagerMac::
id selected_text = [native_focus_object selectedTextMarkerRange];
if (selected_text) {
+ NSString* const NSAccessibilitySelectedTextMarkerRangeAttribute =
+ @"AXSelectedTextMarkerRange";
[user_info setObject:selected_text
forKey:NSAccessibilitySelectedTextMarkerRangeAttribute];
}
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc
index 6429708562e..8a865088863 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -520,7 +520,8 @@ TEST(BrowserAccessibilityManagerTest, TestMoveChildUp) {
ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
}
-TEST(BrowserAccessibilityManagerTest, TestFatalError) {
+// Temporarily disabled due to bug http://crbug.com/765490
+TEST(BrowserAccessibilityManagerTest, DISABLED_TestFatalError) {
// Test that BrowserAccessibilityManager raises a fatal error
// (which will crash the renderer) if the same id is used in
// two places in the tree.
@@ -1035,11 +1036,25 @@ TEST(BrowserAccessibilityManagerTest, TestNextPreviousInTreeOrder) {
EXPECT_EQ(node5_accessible, manager->NextInTreeOrder(node4_accessible));
EXPECT_EQ(nullptr, manager->NextInTreeOrder(node5_accessible));
- EXPECT_EQ(nullptr, manager->PreviousInTreeOrder(nullptr));
- EXPECT_EQ(node4_accessible, manager->PreviousInTreeOrder(node5_accessible));
- EXPECT_EQ(node3_accessible, manager->PreviousInTreeOrder(node4_accessible));
- EXPECT_EQ(node2_accessible, manager->PreviousInTreeOrder(node3_accessible));
- EXPECT_EQ(root_accessible, manager->PreviousInTreeOrder(node2_accessible));
+ EXPECT_EQ(nullptr, manager->PreviousInTreeOrder(nullptr, false));
+ EXPECT_EQ(node4_accessible,
+ manager->PreviousInTreeOrder(node5_accessible, false));
+ EXPECT_EQ(node3_accessible,
+ manager->PreviousInTreeOrder(node4_accessible, false));
+ EXPECT_EQ(node2_accessible,
+ manager->PreviousInTreeOrder(node3_accessible, false));
+ EXPECT_EQ(root_accessible,
+ manager->PreviousInTreeOrder(node2_accessible, false));
+
+ EXPECT_EQ(nullptr, manager->PreviousInTreeOrder(nullptr, true));
+ EXPECT_EQ(node4_accessible,
+ manager->PreviousInTreeOrder(node5_accessible, true));
+ EXPECT_EQ(node3_accessible,
+ manager->PreviousInTreeOrder(node4_accessible, true));
+ EXPECT_EQ(node2_accessible,
+ manager->PreviousInTreeOrder(node3_accessible, true));
+ EXPECT_EQ(root_accessible,
+ manager->PreviousInTreeOrder(node2_accessible, true));
EXPECT_EQ(ui::AX_TREE_ORDER_EQUAL,
BrowserAccessibilityManager::CompareNodes(
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
index 5e298f3f28e..4cbb1b33625 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -10,9 +10,7 @@
#include <vector>
#include "base/command_line.h"
-#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"
-#include "content/browser/accessibility/browser_accessibility_event_win.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/accessibility/browser_accessibility_win.h"
#include "content/browser/renderer_host/legacy_render_widget_host_win.h"
@@ -21,28 +19,6 @@
namespace content {
-namespace {
-
-bool IsContainerWithSelectableChildrenRole(ui::AXRole role) {
- switch (role) {
- case ui::AX_ROLE_COMBO_BOX:
- case ui::AX_ROLE_GRID:
- case ui::AX_ROLE_LIST_BOX:
- case ui::AX_ROLE_MENU:
- case ui::AX_ROLE_MENU_BAR:
- case ui::AX_ROLE_RADIO_GROUP:
- case ui::AX_ROLE_TAB_LIST:
- case ui::AX_ROLE_TOOLBAR:
- case ui::AX_ROLE_TREE:
- case ui::AX_ROLE_TREE_GRID:
- return true;
- default:
- return false;
- }
-}
-
-} // namespace
-
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
const ui::AXTreeUpdate& initial_tree,
@@ -105,13 +81,8 @@ void BrowserAccessibilityManagerWin::OnIAccessible2Used() {
}
void BrowserAccessibilityManagerWin::UserIsReloading() {
- if (GetRoot()) {
- (new BrowserAccessibilityEventWin(
- BrowserAccessibilityEvent::FromRenderFrameHost,
- ui::AX_EVENT_NONE,
- IA2_EVENT_DOCUMENT_RELOAD,
- GetRoot()))->Fire();
- }
+ if (GetRoot())
+ FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_RELOAD, GetRoot());
}
BrowserAccessibility* BrowserAccessibilityManagerWin::GetFocus() {
@@ -119,104 +90,138 @@ BrowserAccessibility* BrowserAccessibilityManagerWin::GetFocus() {
return GetActiveDescendant(focus);
}
-void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::Source source,
+void BrowserAccessibilityManagerWin::FireFocusEvent(
+ BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireFocusEvent(node);
+ DCHECK(node);
+ // On Windows, we always fire a FOCUS event on the root of a frame before
+ // firing a focus event within that frame.
+ if (node->manager() != last_focused_manager_ &&
+ node != node->manager()->GetRoot()) {
+ FireWinAccessibilityEvent(EVENT_OBJECT_FOCUS, node->manager()->GetRoot());
+ }
+
+ FireWinAccessibilityEvent(EVENT_OBJECT_FOCUS, node);
+}
+
+void BrowserAccessibilityManagerWin::FireBlinkEvent(
ui::AXEvent event_type,
BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireBlinkEvent(event_type, node);
+ switch (event_type) {
+ case ui::AX_EVENT_LOCATION_CHANGED:
+ FireWinAccessibilityEvent(IA2_EVENT_VISIBLE_DATA_CHANGED, node);
+ break;
+ case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
+ FireWinAccessibilityEvent(EVENT_SYSTEM_SCROLLINGSTART, node);
+ break;
+ default:
+ break;
+ }
+}
+
+void BrowserAccessibilityManagerWin::FireGeneratedEvent(
+ AXEventGenerator::Event event_type,
+ BrowserAccessibility* node) {
+ BrowserAccessibilityManager::FireGeneratedEvent(event_type, node);
bool can_fire_events = CanFireEvents();
- // TODO(dmazzoni): A better fix would be to always have a HWND.
- // http://crbug.com/521877
- if (event_type == ui::AX_EVENT_LOAD_COMPLETE && can_fire_events)
+ if (event_type == Event::LOAD_COMPLETE && can_fire_events)
load_complete_pending_ = false;
if (load_complete_pending_ && can_fire_events && GetRoot()) {
load_complete_pending_ = false;
- NotifyAccessibilityEvent(BrowserAccessibilityEvent::FromPendingLoadComplete,
- ui::AX_EVENT_LOAD_COMPLETE,
- GetRoot());
+ FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_LOAD_COMPLETE, GetRoot());
}
if (!can_fire_events && !load_complete_pending_ &&
- event_type == ui::AX_EVENT_LOAD_COMPLETE && GetRoot() &&
+ event_type == Event::LOAD_COMPLETE && GetRoot() &&
!GetRoot()->IsOffscreen() && GetRoot()->PlatformChildCount() > 0) {
load_complete_pending_ = true;
}
- if (event_type == ui::AX_EVENT_BLUR) {
- // Equivalent to focus on the root.
- event_type = ui::AX_EVENT_FOCUS;
- node = GetRoot();
- }
-
- if (event_type == ui::AX_EVENT_DOCUMENT_SELECTION_CHANGED) {
- // Fire the event on the object where the focus of the selection is.
- int32_t focus_id = GetTreeData().sel_focus_object_id;
- BrowserAccessibility* focus_object = GetFromID(focus_id);
- if (focus_object) {
- (new BrowserAccessibilityEventWin(
- source,
- ui::AX_EVENT_NONE,
- IA2_EVENT_TEXT_CARET_MOVED,
- focus_object))->Fire();
- return;
+ switch (event_type) {
+ case Event::ACTIVE_DESCENDANT_CHANGED:
+ FireWinAccessibilityEvent(IA2_EVENT_ACTIVE_DESCENDANT_CHANGED, node);
+ break;
+ case Event::ALERT:
+ FireWinAccessibilityEvent(EVENT_SYSTEM_ALERT, node);
+ break;
+ case Event::CHILDREN_CHANGED:
+ FireWinAccessibilityEvent(EVENT_OBJECT_REORDER, node);
+ break;
+ case Event::LIVE_REGION_CHANGED:
+ FireWinAccessibilityEvent(EVENT_OBJECT_LIVEREGIONCHANGED, node);
+ break;
+ case Event::LOAD_COMPLETE:
+ FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_LOAD_COMPLETE, node);
+ break;
+ case Event::SCROLL_POSITION_CHANGED:
+ FireWinAccessibilityEvent(EVENT_SYSTEM_SCROLLINGEND, node);
+ break;
+ case Event::SELECTED_CHILDREN_CHANGED:
+ FireWinAccessibilityEvent(EVENT_OBJECT_SELECTIONWITHIN, node);
+ break;
+ case Event::DOCUMENT_SELECTION_CHANGED: {
+ // Fire the event on the object where the focus of the selection is.
+ int32_t focus_id = GetTreeData().sel_focus_object_id;
+ BrowserAccessibility* focus_object = GetFromID(focus_id);
+ if (focus_object)
+ FireWinAccessibilityEvent(IA2_EVENT_TEXT_CARET_MOVED, focus_object);
+ break;
}
+ case Event::CHECKED_STATE_CHANGED:
+ case Event::COLLAPSED:
+ case Event::DESCRIPTION_CHANGED:
+ case Event::DOCUMENT_TITLE_CHANGED:
+ case Event::EXPANDED:
+ case Event::INVALID_STATUS_CHANGED:
+ case Event::LIVE_REGION_CREATED:
+ case Event::LIVE_REGION_NODE_CHANGED:
+ case Event::MENU_ITEM_SELECTED:
+ case Event::NAME_CHANGED:
+ case Event::OTHER_ATTRIBUTE_CHANGED:
+ case Event::ROLE_CHANGED:
+ case Event::ROW_COUNT_CHANGED:
+ case Event::SELECTED_CHANGED:
+ case Event::STATE_CHANGED:
+ case Event::VALUE_CHANGED:
+ // There are some notifications that aren't meaningful on Windows.
+ // It's okay to skip them.
+ break;
}
-
- BrowserAccessibilityManager::NotifyAccessibilityEvent(
- source, event_type, node);
}
-BrowserAccessibilityEvent::Result
- BrowserAccessibilityManagerWin::FireWinAccessibilityEvent(
- BrowserAccessibilityEventWin* event) {
- const BrowserAccessibility* target = event->target();
- ui::AXEvent event_type = event->event_type();
- LONG win_event_type = event->win_event_type();
-
+void BrowserAccessibilityManagerWin::FireWinAccessibilityEvent(
+ LONG win_event_type,
+ BrowserAccessibility* node) {
+ // 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.
BrowserAccessibilityDelegate* root_delegate = GetDelegateFromRootManager();
if (!root_delegate)
- return BrowserAccessibilityEvent::FailedBecauseFrameIsDetached;
+ return;
HWND hwnd = root_delegate->AccessibilityGetAcceleratedWidget();
if (!hwnd)
- return BrowserAccessibilityEvent::FailedBecauseNoWindow;
+ return;
// Don't fire events when this document might be stale as the user has
// started navigating to a new document.
if (user_is_navigating_away_)
- return BrowserAccessibilityEvent::DiscardedBecauseUserNavigatingAway;
-
- if (!target)
- return BrowserAccessibilityEvent::FailedBecauseNoFocus;
+ return;
// Inline text boxes are an internal implementation detail, we don't
// expose them to Windows.
- if (target->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
- return BrowserAccessibilityEvent::NotNeededOnThisPlatform;
-
- if ((event_type == ui::AX_EVENT_LIVE_REGION_CREATED ||
- event_type == ui::AX_EVENT_LIVE_REGION_CHANGED) &&
- target->GetBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_BUSY)) {
- return BrowserAccessibilityEvent::DiscardedBecauseLiveRegionBusy;
- }
-
- event->set_target(target);
-
- // It doesn't make sense to fire a REORDER event on a leaf node; that
- // happens when the target has internal children inline text boxes.
- if (win_event_type == EVENT_OBJECT_REORDER &&
- target->PlatformChildCount() == 0) {
- return BrowserAccessibilityEvent::NotNeededOnThisPlatform;
- }
+ if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX)
+ return;
// Pass the negation of this node's unique id in the |child_id|
// argument to NotifyWinEvent; the AT client will then call get_accChild
// on the HWND's accessibility object and pass it that same id, which
// we can use to retrieve the IAccessible for this node.
- LONG child_id = -(ToBrowserAccessibilityWin(target)->GetCOM()->unique_id());
+ LONG child_id = -(ToBrowserAccessibilityWin(node)->GetCOM()->unique_id());
::NotifyWinEvent(win_event_type, hwnd, OBJID_CLIENT, child_id);
- return BrowserAccessibilityEvent::Sent;
}
bool BrowserAccessibilityManagerWin::CanFireEvents() {
@@ -227,22 +232,6 @@ bool BrowserAccessibilityManagerWin::CanFireEvents() {
return hwnd != nullptr;
}
-void BrowserAccessibilityManagerWin::FireFocusEvent(
- BrowserAccessibilityEvent::Source source,
- BrowserAccessibility* node) {
- DCHECK(node);
- // On Windows, we always fire a FOCUS event on the root of a frame before
- // firing a focus event within that frame.
- if (node->manager() != last_focused_manager_ &&
- node != node->manager()->GetRoot()) {
- BrowserAccessibilityEvent::Create(source,
- ui::AX_EVENT_FOCUS,
- node->manager()->GetRoot())->Fire();
- }
-
- BrowserAccessibilityManager::FireFocusEvent(source, node);
-}
-
gfx::Rect BrowserAccessibilityManagerWin::GetViewBounds() {
// We have to take the device scale factor into account on Windows.
BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager();
@@ -255,84 +244,6 @@ gfx::Rect BrowserAccessibilityManagerWin::GetViewBounds() {
return gfx::Rect();
}
-void BrowserAccessibilityManagerWin::OnTreeDataChanged(
- ui::AXTree* tree,
- const ui::AXTreeData& old_tree_data,
- const ui::AXTreeData& new_tree_data) {
- BrowserAccessibilityManager::OnTreeDataChanged(tree, old_tree_data,
- new_tree_data);
- if (new_tree_data.loaded && !old_tree_data.loaded)
- tree_events_[tree->root()->id()].insert(ui::AX_EVENT_LOAD_COMPLETE);
- if (new_tree_data.sel_anchor_object_id !=
- old_tree_data.sel_anchor_object_id ||
- new_tree_data.sel_anchor_offset != old_tree_data.sel_anchor_offset ||
- new_tree_data.sel_anchor_affinity != old_tree_data.sel_anchor_affinity ||
- new_tree_data.sel_focus_object_id != old_tree_data.sel_focus_object_id ||
- new_tree_data.sel_focus_offset != old_tree_data.sel_focus_offset ||
- new_tree_data.sel_focus_affinity != old_tree_data.sel_focus_affinity) {
- tree_events_[tree->root()->id()].insert(
- ui::AX_EVENT_DOCUMENT_SELECTION_CHANGED);
- }
-}
-
-void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXTree* tree,
- ui::AXNode* node) {
- DCHECK(node);
- BrowserAccessibilityManager::OnNodeCreated(tree, node);
- BrowserAccessibility* obj = GetFromAXNode(node);
- if (!obj)
- return;
- if (!obj->IsNative())
- return;
-}
-
-void BrowserAccessibilityManagerWin::OnNodeDataWillChange(
- ui::AXTree* tree,
- const ui::AXNodeData& old_node_data,
- const ui::AXNodeData& new_node_data) {
- if (new_node_data.child_ids != old_node_data.child_ids &&
- new_node_data.role != ui::AX_ROLE_STATIC_TEXT) {
- tree_events_[new_node_data.id].insert(ui::AX_EVENT_CHILDREN_CHANGED);
- }
-}
-
-void BrowserAccessibilityManagerWin::OnStateChanged(ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXState state,
- bool new_value) {
- if (state == ui::AX_STATE_SELECTED) {
- ui::AXNode* container = node;
- while (container &&
- !IsContainerWithSelectableChildrenRole(container->data().role))
- container = container->parent();
- if (container) {
- tree_events_[container->id()].insert(
- ui::AX_EVENT_SELECTED_CHILDREN_CHANGED);
- }
- }
-}
-
-void BrowserAccessibilityManagerWin::OnIntAttributeChanged(
- ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXIntAttribute attr,
- int32_t old_value,
- int32_t new_value) {
- BrowserAccessibilityManager::OnIntAttributeChanged(tree, node, attr,
- old_value, new_value);
- switch (attr) {
- case ui::AX_ATTR_ACTIVEDESCENDANT_ID:
- tree_events_[node->id()].insert(ui::AX_EVENT_ACTIVEDESCENDANTCHANGED);
- break;
- case ui::AX_ATTR_SCROLL_X:
- case ui::AX_ATTR_SCROLL_Y:
- tree_events_[node->id()].insert(ui::AX_EVENT_SCROLL_POSITION_CHANGED);
- break;
- default:
- break;
- }
-}
-
void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
ui::AXTree* tree,
bool root_changed,
@@ -340,24 +251,6 @@ void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
BrowserAccessibilityManager::OnAtomicUpdateFinished(
tree, root_changed, changes);
- if (root_changed && tree->data().loaded)
- tree_events_[tree->root()->id()].insert(ui::AX_EVENT_LOAD_COMPLETE);
-
- // Handle live region changes.
- for (size_t i = 0; i < changes.size(); ++i) {
- const ui::AXNode* node = changes[i].node;
- DCHECK(node);
- if (node->data().HasStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS)) {
- const ui::AXNode* container = node;
- while (container &&
- !container->data().HasStringAttribute(ui::AX_ATTR_LIVE_STATUS)) {
- container = container->parent();
- }
- if (container)
- tree_events_[container->id()].insert(ui::AX_EVENT_LIVE_REGION_CHANGED);
- }
- }
-
// Do a sequence of Windows-specific updates on each node. Each one is
// done in a single pass that must complete before the next step starts.
// The first step moves win_attributes_ to old_win_attributes_ and then
@@ -366,7 +259,7 @@ void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
const ui::AXNode* changed_node = change.node;
DCHECK(changed_node);
BrowserAccessibility* obj = GetFromAXNode(changed_node);
- if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf()) {
+ if (obj && obj->IsNative()) {
ToBrowserAccessibilityWin(obj)
->GetCOM()
->UpdateStep1ComputeWinAttributes();
@@ -380,7 +273,7 @@ void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
const ui::AXNode* changed_node = change.node;
DCHECK(changed_node);
BrowserAccessibility* obj = GetFromAXNode(changed_node);
- if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf())
+ if (obj && obj->IsNative())
ToBrowserAccessibilityWin(obj)->GetCOM()->UpdateStep2ComputeHypertext();
}
@@ -396,7 +289,7 @@ void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished(
const ui::AXNode* changed_node = change.node;
DCHECK(changed_node);
BrowserAccessibility* obj = GetFromAXNode(changed_node);
- if (obj && obj->IsNative() && !obj->PlatformIsChildOfLeaf()) {
+ if (obj && obj->IsNative()) {
ToBrowserAccessibilityWin(obj)->GetCOM()->UpdateStep3FireEvents(
change.type == AXTreeDelegate::SUBTREE_CREATED);
}
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_win.h b/chromium/content/browser/accessibility/browser_accessibility_manager_win.h
index c00cf5d1158..6a4a65a5d8f 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_win.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -10,12 +10,10 @@
#include <memory>
#include "base/macros.h"
-#include "base/win/scoped_comptr.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
namespace content {
-class BrowserAccessibilityEventWin;
class BrowserAccessibilityWin;
// Manages a tree of BrowserAccessibilityWin objects.
@@ -41,18 +39,17 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin
// BrowserAccessibilityManager methods
void UserIsReloading() override;
BrowserAccessibility* GetFocus() override;
- void NotifyAccessibilityEvent(
- BrowserAccessibilityEvent::Source source,
- ui::AXEvent event_type,
- BrowserAccessibility* node) override;
- BrowserAccessibilityEvent::Result
- FireWinAccessibilityEvent(BrowserAccessibilityEventWin* event);
bool CanFireEvents() override;
- void FireFocusEvent(
- BrowserAccessibilityEvent::Source source,
- BrowserAccessibility* node) override;
gfx::Rect GetViewBounds() override;
+ void FireFocusEvent(BrowserAccessibility* node) override;
+ void FireBlinkEvent(ui::AXEvent event_type,
+ BrowserAccessibility* node) override;
+ void FireGeneratedEvent(AXEventGenerator::Event event_type,
+ BrowserAccessibility* node) override;
+
+ void FireWinAccessibilityEvent(LONG win_event, BrowserAccessibility* node);
+
// Track this object and post a VISIBLE_DATA_CHANGED notification when
// its container scrolls.
// TODO(dmazzoni): remove once http://crbug.com/113483 is fixed.
@@ -63,22 +60,6 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin
protected:
// AXTreeDelegate methods.
- void OnTreeDataChanged(ui::AXTree* tree,
- const ui::AXTreeData& old_tree_data,
- const ui::AXTreeData& new_tree_data) override;
- void OnNodeCreated(ui::AXTree* tree, ui::AXNode* node) override;
- void OnNodeDataWillChange(ui::AXTree* tree,
- const ui::AXNodeData& old_node_data,
- const ui::AXNodeData& new_node_data) override;
- void OnStateChanged(ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXState state,
- bool new_value) override;
- void OnIntAttributeChanged(ui::AXTree* tree,
- ui::AXNode* node,
- ui::AXIntAttribute attr,
- int32_t old_value,
- int32_t new_value) override;
void OnAtomicUpdateFinished(
ui::AXTree* tree,
bool root_changed,
diff --git a/chromium/content/browser/accessibility/ax_platform_position.cc b/chromium/content/browser/accessibility/browser_accessibility_position.cc
index 47caacda155..392be197239 100644
--- a/chromium/content/browser/accessibility/ax_platform_position.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_position.cc
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/accessibility/ax_platform_position.h"
+#include "content/browser/accessibility/browser_accessibility_position.h"
+#include "base/strings/string_util.h"
+#include "build/build_config.h"
#include "content/browser/accessibility/accessibility_flags.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
@@ -11,24 +13,25 @@
namespace content {
-AXPlatformPosition::AXPlatformPosition() {}
+BrowserAccessibilityPosition::BrowserAccessibilityPosition() {}
-AXPlatformPosition::~AXPlatformPosition() {}
+BrowserAccessibilityPosition::~BrowserAccessibilityPosition() {}
-AXPlatformPosition::AXPositionInstance AXPlatformPosition::Clone() const {
- return AXPositionInstance(new AXPlatformPosition(*this));
+BrowserAccessibilityPosition::AXPositionInstance
+BrowserAccessibilityPosition::Clone() const {
+ return AXPositionInstance(new BrowserAccessibilityPosition(*this));
}
-base::string16 AXPlatformPosition::GetInnerText() const {
+base::string16 BrowserAccessibilityPosition::GetInnerText() const {
if (IsNullPosition())
return base::string16();
DCHECK(GetAnchor());
return GetAnchor()->GetText();
}
-void AXPlatformPosition::AnchorChild(int child_index,
- AXTreeID* tree_id,
- int32_t* child_id) const {
+void BrowserAccessibilityPosition::AnchorChild(int child_index,
+ AXTreeID* tree_id,
+ int32_t* child_id) const {
DCHECK(tree_id);
DCHECK(child_id);
@@ -49,7 +52,7 @@ void AXPlatformPosition::AnchorChild(int child_index,
*child_id = child->GetId();
}
-int AXPlatformPosition::AnchorChildCount() const {
+int BrowserAccessibilityPosition::AnchorChildCount() const {
if (!GetAnchor())
return 0;
@@ -60,13 +63,13 @@ int AXPlatformPosition::AnchorChildCount() const {
}
}
-int AXPlatformPosition::AnchorIndexInParent() const {
+int BrowserAccessibilityPosition::AnchorIndexInParent() const {
return GetAnchor() ? static_cast<int>(GetAnchor()->GetIndexInParent())
: AXPosition::INVALID_INDEX;
}
-void AXPlatformPosition::AnchorParent(AXTreeID* tree_id,
- int32_t* parent_id) const {
+void BrowserAccessibilityPosition::AnchorParent(AXTreeID* tree_id,
+ int32_t* parent_id) const {
DCHECK(tree_id);
DCHECK(parent_id);
@@ -81,8 +84,9 @@ void AXPlatformPosition::AnchorParent(AXTreeID* tree_id,
*parent_id = parent->GetId();
}
-BrowserAccessibility* AXPlatformPosition::GetNodeInTree(AXTreeID tree_id,
- int32_t node_id) const {
+BrowserAccessibility* BrowserAccessibilityPosition::GetNodeInTree(
+ AXTreeID tree_id,
+ int32_t node_id) const {
if (tree_id == AXPosition::INVALID_TREE_ID ||
node_id == AXPosition::INVALID_ANCHOR_ID) {
return nullptr;
@@ -94,7 +98,7 @@ BrowserAccessibility* AXPlatformPosition::GetNodeInTree(AXTreeID tree_id,
return manager->GetFromID(node_id);
}
-int AXPlatformPosition::MaxTextOffset() const {
+int BrowserAccessibilityPosition::MaxTextOffset() const {
if (IsNullPosition())
return INVALID_OFFSET;
return static_cast<int>(GetInnerText().length());
@@ -103,7 +107,7 @@ int AXPlatformPosition::MaxTextOffset() const {
// On some platforms, most objects are represented in the text of their parents
// with a special (embedded object) character and not with their actual text
// contents.
-int AXPlatformPosition::MaxTextOffsetInParent() const {
+int BrowserAccessibilityPosition::MaxTextOffsetInParent() const {
#if defined(OS_WIN) || BUILDFLAG(USE_ATK)
if (IsNullPosition())
return INVALID_OFFSET;
@@ -119,29 +123,30 @@ int AXPlatformPosition::MaxTextOffsetInParent() const {
#endif
}
-bool AXPlatformPosition::IsInLineBreak() const {
+bool BrowserAccessibilityPosition::IsInWhiteSpace() const {
if (IsNullPosition())
return false;
DCHECK(GetAnchor());
- return GetAnchor()->IsLineBreakObject();
+ return GetAnchor()->IsLineBreakObject() ||
+ base::ContainsOnlyChars(GetInnerText(), base::kWhitespaceUTF16);
}
-std::vector<int32_t> AXPlatformPosition::GetWordStartOffsets() const {
+std::vector<int32_t> BrowserAccessibilityPosition::GetWordStartOffsets() const {
if (IsNullPosition())
return std::vector<int32_t>();
DCHECK(GetAnchor());
return GetAnchor()->GetIntListAttribute(ui::AX_ATTR_WORD_STARTS);
}
-std::vector<int32_t> AXPlatformPosition::GetWordEndOffsets() const {
+std::vector<int32_t> BrowserAccessibilityPosition::GetWordEndOffsets() const {
if (IsNullPosition())
return std::vector<int32_t>();
DCHECK(GetAnchor());
return GetAnchor()->GetIntListAttribute(ui::AX_ATTR_WORD_ENDS);
}
-int32_t AXPlatformPosition::GetNextOnLineID(int32_t node_id) const {
+int32_t BrowserAccessibilityPosition::GetNextOnLineID(int32_t node_id) const {
if (IsNullPosition())
return INVALID_ANCHOR_ID;
BrowserAccessibility* node = GetNodeInTree(tree_id(), node_id);
@@ -153,14 +158,14 @@ int32_t AXPlatformPosition::GetNextOnLineID(int32_t node_id) const {
return static_cast<int32_t>(next_on_line_id);
}
-int32_t AXPlatformPosition::GetPreviousOnLineID(int32_t node_id) const {
+int32_t BrowserAccessibilityPosition::GetPreviousOnLineID(
+ int32_t node_id) const {
if (IsNullPosition())
return INVALID_ANCHOR_ID;
BrowserAccessibility* node = GetNodeInTree(tree_id(), node_id);
int previous_on_line_id;
- if (!node ||
- !node->GetIntAttribute(ui::AX_ATTR_PREVIOUS_ON_LINE_ID,
- &previous_on_line_id)) {
+ if (!node || !node->GetIntAttribute(ui::AX_ATTR_PREVIOUS_ON_LINE_ID,
+ &previous_on_line_id)) {
return INVALID_ANCHOR_ID;
}
return static_cast<int32_t>(previous_on_line_id);
diff --git a/chromium/content/browser/accessibility/ax_platform_position.h b/chromium/content/browser/accessibility/browser_accessibility_position.h
index 186c02b4a66..89ea6d8e407 100644
--- a/chromium/content/browser/accessibility/ax_platform_position.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_position.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_ACCESSIBILITY_AX_PLATFORM_POSITION_H_
-#define CONTENT_BROWSER_ACCESSIBILITY_AX_PLATFORM_POSITION_H_
+#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_POSITION_H_
+#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_POSITION_H_
#include <stdint.h>
@@ -19,18 +19,20 @@ class BrowserAccessibility;
using AXTreeID = ui::AXTreeIDRegistry::AXTreeID;
-class AXPlatformPosition
- : public ui::AXPosition<AXPlatformPosition, BrowserAccessibility> {
+class BrowserAccessibilityPosition
+ : public ui::AXPosition<BrowserAccessibilityPosition,
+ BrowserAccessibility> {
public:
- AXPlatformPosition();
- ~AXPlatformPosition() override;
+ BrowserAccessibilityPosition();
+ ~BrowserAccessibilityPosition() override;
AXPositionInstance Clone() const override;
base::string16 GetInnerText() const override;
protected:
- AXPlatformPosition(const AXPlatformPosition& other) = default;
+ BrowserAccessibilityPosition(const BrowserAccessibilityPosition& other) =
+ default;
void AnchorChild(int child_index,
AXTreeID* tree_id,
int32_t* child_id) const override;
@@ -41,7 +43,7 @@ class AXPlatformPosition
int32_t node_id) const override;
int MaxTextOffset() const override;
int MaxTextOffsetInParent() const override;
- bool IsInLineBreak() const override;
+ bool IsInWhiteSpace() const override;
std::vector<int32_t> GetWordStartOffsets() const override;
std::vector<int32_t> GetWordEndOffsets() const override;
int32_t GetNextOnLineID(int32_t node_id) const override;
@@ -50,4 +52,4 @@ class AXPlatformPosition
} // namespace content
-#endif // CONTENT_BROWSER_ACCESSIBILITY_AX_PLATFORM_POSITION_H_
+#endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_POSITION_H_
diff --git a/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc b/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc
index cac0cf8943b..ab7238f08cd 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -6,6 +6,7 @@
#include <objbase.h>
#include <stdint.h>
+#include <wrl/client.h>
#include <memory>
#include <utility>
@@ -13,7 +14,6 @@
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_bstr.h"
-#include "base/win/scoped_comptr.h"
#include "base/win/scoped_variant.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_manager_win.h"
@@ -141,13 +141,13 @@ TEST_F(BrowserAccessibilityTest, TestChildrenChange) {
// Query for the text IAccessible and verify that it returns "old text" as its
// value.
base::win::ScopedVariant one(1);
- base::win::ScopedComPtr<IDispatch> text_dispatch;
+ Microsoft::WRL::ComPtr<IDispatch> text_dispatch;
HRESULT hr = ToBrowserAccessibilityWin(manager->GetRoot())
->GetCOM()
->get_accChild(one, text_dispatch.GetAddressOf());
ASSERT_EQ(S_OK, hr);
- base::win::ScopedComPtr<IAccessible> text_accessible;
+ Microsoft::WRL::ComPtr<IAccessible> text_accessible;
hr = text_dispatch.CopyTo(text_accessible.GetAddressOf());
ASSERT_EQ(S_OK, hr);
@@ -293,6 +293,9 @@ TEST_F(BrowserAccessibilityTest, TestTextBoundaries) {
line_break.AddState(ui::AX_STATE_EDITABLE);
line_break.SetName("\n");
+ inline_box1.AddIntAttribute(ui::AX_ATTR_NEXT_ON_LINE_ID, line_break.id);
+ line_break.AddIntAttribute(ui::AX_ATTR_PREVIOUS_ON_LINE_ID, inline_box1.id);
+
ui::AXNodeData static_text2;
static_text2.id = 6;
static_text2.role = ui::AX_ROLE_STATIC_TEXT;
@@ -447,7 +450,7 @@ TEST_F(BrowserAccessibilityTest, TestSimpleHypertext) {
EXPECT_EQ(S_OK, root_obj->get_nHyperlinks(&hyperlink_count));
EXPECT_EQ(0, hyperlink_count);
- base::win::ScopedComPtr<IAccessibleHyperlink> hyperlink;
+ Microsoft::WRL::ComPtr<IAccessibleHyperlink> hyperlink;
EXPECT_EQ(E_INVALIDARG,
root_obj->get_hyperlink(-1, hyperlink.GetAddressOf()));
EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlink(0, hyperlink.GetAddressOf()));
@@ -496,7 +499,8 @@ TEST_F(BrowserAccessibilityTest, TestComplexHypertext) {
ui::AXNodeData combo_box;
combo_box.id = 12;
- combo_box.role = ui::AX_ROLE_COMBO_BOX;
+ combo_box.role = ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX;
+ combo_box.AddState(ui::AX_STATE_EDITABLE);
combo_box.SetName(base::UTF16ToUTF8(combo_box_name));
combo_box.SetValue(base::UTF16ToUTF8(combo_box_value));
@@ -561,8 +565,8 @@ TEST_F(BrowserAccessibilityTest, TestComplexHypertext) {
EXPECT_EQ(S_OK, root_obj->get_nHyperlinks(&hyperlink_count));
EXPECT_EQ(4, hyperlink_count);
- base::win::ScopedComPtr<IAccessibleHyperlink> hyperlink;
- base::win::ScopedComPtr<IAccessibleText> hypertext;
+ Microsoft::WRL::ComPtr<IAccessibleHyperlink> hyperlink;
+ Microsoft::WRL::ComPtr<IAccessibleText> hypertext;
EXPECT_EQ(E_INVALIDARG,
root_obj->get_hyperlink(-1, hyperlink.GetAddressOf()));
EXPECT_EQ(E_INVALIDARG, root_obj->get_hyperlink(4, hyperlink.GetAddressOf()));
@@ -808,11 +812,14 @@ TEST_F(BrowserAccessibilityTest, TestValueAttributeInTextControls) {
combo_box_text.id = 3;
combo_box.SetName("Combo box:");
combo_box_text.SetName("Combo box text");
- combo_box.role = ui::AX_ROLE_COMBO_BOX;
+ combo_box.role = ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX;
combo_box_text.role = ui::AX_ROLE_STATIC_TEXT;
+ combo_box.AddBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT, true);
combo_box.AddState(ui::AX_STATE_EDITABLE);
+ combo_box.AddState(ui::AX_STATE_RICHLY_EDITABLE);
combo_box.AddState(ui::AX_STATE_FOCUSABLE);
combo_box_text.AddState(ui::AX_STATE_EDITABLE);
+ combo_box_text.AddState(ui::AX_STATE_RICHLY_EDITABLE);
combo_box.child_ids.push_back(combo_box_text.id);
ui::AXNodeData search_box, search_box_text, new_line;
@@ -825,16 +832,21 @@ TEST_F(BrowserAccessibilityTest, TestValueAttributeInTextControls) {
search_box.role = ui::AX_ROLE_SEARCH_BOX;
search_box_text.role = ui::AX_ROLE_STATIC_TEXT;
new_line.role = ui::AX_ROLE_LINE_BREAK;
+ search_box.AddBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT, true);
search_box.AddState(ui::AX_STATE_EDITABLE);
+ search_box.AddState(ui::AX_STATE_RICHLY_EDITABLE);
search_box.AddState(ui::AX_STATE_FOCUSABLE);
search_box_text.AddState(ui::AX_STATE_EDITABLE);
+ search_box_text.AddState(ui::AX_STATE_RICHLY_EDITABLE);
new_line.AddState(ui::AX_STATE_EDITABLE);
+ new_line.AddState(ui::AX_STATE_RICHLY_EDITABLE);
search_box.child_ids.push_back(search_box_text.id);
search_box.child_ids.push_back(new_line.id);
ui::AXNodeData text_field;
text_field.id = 7;
text_field.role = ui::AX_ROLE_TEXT_FIELD;
+ text_field.AddBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT, true);
text_field.AddState(ui::AX_STATE_EDITABLE);
text_field.AddState(ui::AX_STATE_FOCUSABLE);
text_field.SetValue("Text field text");
@@ -1046,11 +1058,11 @@ TEST_F(BrowserAccessibilityTest, TestWordBoundariesInTextControls) {
ToBrowserAccessibilityWin(root_accessible->PlatformGetChild(1));
ASSERT_NE(nullptr, text_field_accessible);
- base::win::ScopedComPtr<IAccessibleText> textarea_object;
+ Microsoft::WRL::ComPtr<IAccessibleText> textarea_object;
EXPECT_HRESULT_SUCCEEDED(textarea_accessible->GetCOM()->QueryInterface(
IID_IAccessibleText,
reinterpret_cast<void**>(textarea_object.GetAddressOf())));
- base::win::ScopedComPtr<IAccessibleText> text_field_object;
+ Microsoft::WRL::ComPtr<IAccessibleText> text_field_object;
EXPECT_HRESULT_SUCCEEDED(text_field_accessible->GetCOM()->QueryInterface(
IID_IAccessibleText,
reinterpret_cast<void**>(text_field_object.GetAddressOf())));
@@ -1103,7 +1115,7 @@ TEST_F(BrowserAccessibilityTest, TestCaretAndSelectionInSimpleFields) {
ui::AXNodeData combo_box;
combo_box.id = 2;
- combo_box.role = ui::AX_ROLE_COMBO_BOX;
+ combo_box.role = ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX;
combo_box.AddState(ui::AX_STATE_EDITABLE);
combo_box.AddState(ui::AX_STATE_FOCUSABLE);
combo_box.SetValue("Test1");
@@ -1524,7 +1536,7 @@ TEST_F(BrowserAccessibilityTest, TestIAccessibleHyperlink) {
LONG start_index = -1;
LONG end_index = -1;
- base::win::ScopedComPtr<IAccessibleHyperlink> hyperlink;
+ Microsoft::WRL::ComPtr<IAccessibleHyperlink> hyperlink;
base::win::ScopedVariant anchor;
base::win::ScopedVariant anchor_target;
base::win::ScopedBstr bstr;
@@ -1671,12 +1683,10 @@ TEST_F(BrowserAccessibilityTest, TestTextAttributesInContentEditables) {
ui::AX_TEXT_STYLE_UNDERLINE);
// The name "lnk" is misspelled.
- std::vector<int32_t> marker_types;
- marker_types.push_back(static_cast<int32_t>(ui::AX_MARKER_TYPE_SPELLING));
- std::vector<int32_t> marker_starts;
- marker_starts.push_back(0);
- std::vector<int32_t> marker_ends;
- marker_ends.push_back(3);
+ std::vector<int32_t> marker_types{
+ static_cast<int32_t>(ui::AX_MARKER_TYPE_SPELLING)};
+ std::vector<int32_t> marker_starts{0};
+ std::vector<int32_t> marker_ends{3};
link_text.AddIntListAttribute(ui::AX_ATTR_MARKER_TYPES, marker_types);
link_text.AddIntListAttribute(ui::AX_ATTR_MARKER_STARTS, marker_starts);
link_text.AddIntListAttribute(ui::AX_ATTR_MARKER_ENDS, marker_ends);
@@ -1778,6 +1788,10 @@ TEST_F(BrowserAccessibilityTest, TestTextAttributesInContentEditables) {
EXPECT_NE(
base::string16::npos,
base::string16(text_attributes).find(L"text-underline-type:single"));
+ // For compatibility with Firefox, spelling attributes should also be
+ // propagated to the parent of static text leaves.
+ EXPECT_NE(base::string16::npos,
+ base::string16(text_attributes).find(L"invalid:spelling"));
text_attributes.Reset();
hr = ax_link_text->GetCOM()->get_attributes(2, &start_offset, &end_offset,
@@ -1860,7 +1874,7 @@ TEST_F(BrowserAccessibilityTest, TestTextAttributesInContentEditables) {
manager.reset();
}
-TEST_F(BrowserAccessibilityTest, TestMisspellingsInSimpleTextFields) {
+TEST_F(BrowserAccessibilityTest, TestExistingMisspellingsInSimpleTextFields) {
std::string value1("Testing .");
// The word "helo" is misspelled.
std::string value2("Helo there.");
@@ -1876,7 +1890,7 @@ TEST_F(BrowserAccessibilityTest, TestMisspellingsInSimpleTextFields) {
ui::AXNodeData combo_box;
combo_box.id = 2;
- combo_box.role = ui::AX_ROLE_COMBO_BOX;
+ combo_box.role = ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX;
combo_box.AddState(ui::AX_STATE_EDITABLE);
combo_box.AddState(ui::AX_STATE_FOCUSABLE);
combo_box.SetValue(value1 + value2);
@@ -1928,7 +1942,6 @@ TEST_F(BrowserAccessibilityTest, TestMisspellingsInSimpleTextFields) {
BrowserAccessibilityWin* ax_combo_box =
ToBrowserAccessibilityWin(ax_root->PlatformGetChild(0));
ASSERT_NE(nullptr, ax_combo_box);
- ASSERT_EQ(1U, ax_combo_box->PlatformChildCount());
HRESULT hr;
LONG start_offset, end_offset;
@@ -1974,6 +1987,133 @@ TEST_F(BrowserAccessibilityTest, TestMisspellingsInSimpleTextFields) {
manager.reset();
}
+TEST_F(BrowserAccessibilityTest, TestNewMisspellingsInSimpleTextFields) {
+ std::string value1("Testing .");
+ // The word "helo" is misspelled.
+ std::string value2("Helo there.");
+
+ LONG value1_length = static_cast<LONG>(value1.length());
+ LONG value2_length = static_cast<LONG>(value2.length());
+ LONG combo_box_value_length = value1_length + value2_length;
+
+ ui::AXNodeData root;
+ root.id = 1;
+ root.role = ui::AX_ROLE_ROOT_WEB_AREA;
+ root.AddState(ui::AX_STATE_FOCUSABLE);
+
+ ui::AXNodeData combo_box;
+ combo_box.id = 2;
+ combo_box.role = ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX;
+ combo_box.AddState(ui::AX_STATE_EDITABLE);
+ combo_box.AddState(ui::AX_STATE_FOCUSABLE);
+ combo_box.SetValue(value1 + value2);
+
+ ui::AXNodeData combo_box_div;
+ combo_box_div.id = 3;
+ combo_box_div.role = ui::AX_ROLE_GENERIC_CONTAINER;
+ combo_box_div.AddState(ui::AX_STATE_EDITABLE);
+
+ ui::AXNodeData static_text1;
+ static_text1.id = 4;
+ static_text1.role = ui::AX_ROLE_STATIC_TEXT;
+ static_text1.AddState(ui::AX_STATE_EDITABLE);
+ static_text1.SetName(value1);
+
+ ui::AXNodeData static_text2;
+ static_text2.id = 5;
+ static_text2.role = ui::AX_ROLE_STATIC_TEXT;
+ static_text2.AddState(ui::AX_STATE_EDITABLE);
+ static_text2.SetName(value2);
+
+ root.child_ids.push_back(combo_box.id);
+ combo_box.child_ids.push_back(combo_box_div.id);
+ combo_box_div.child_ids.push_back(static_text1.id);
+ combo_box_div.child_ids.push_back(static_text2.id);
+
+ std::unique_ptr<BrowserAccessibilityManager> manager(
+ BrowserAccessibilityManager::Create(
+ MakeAXTreeUpdate(root, combo_box, combo_box_div, static_text1,
+ static_text2),
+ nullptr, new BrowserAccessibilityFactory()));
+
+ ASSERT_NE(nullptr, manager->GetRoot());
+ BrowserAccessibilityWin* ax_root =
+ ToBrowserAccessibilityWin(manager->GetRoot());
+ ASSERT_NE(nullptr, ax_root);
+ ASSERT_EQ(1U, ax_root->PlatformChildCount());
+
+ BrowserAccessibilityWin* ax_combo_box =
+ ToBrowserAccessibilityWin(ax_root->PlatformGetChild(0));
+ ASSERT_NE(nullptr, ax_combo_box);
+
+ HRESULT hr;
+ LONG start_offset, end_offset;
+ base::win::ScopedBstr text_attributes;
+
+ // Ensure that nothing is marked misspelled.
+ for (LONG offset = 0; offset < combo_box_value_length; ++offset) {
+ hr = ax_combo_box->GetCOM()->get_attributes(
+ offset, &start_offset, &end_offset, text_attributes.Receive());
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(0, start_offset);
+ EXPECT_EQ(combo_box_value_length, end_offset);
+ EXPECT_EQ(base::string16::npos,
+ base::string16(text_attributes).find(L"invalid:spelling"));
+ text_attributes.Reset();
+ }
+
+ // Add the spelling markers on "helo".
+ std::vector<int32_t> marker_types{
+ static_cast<int32_t>(ui::AX_MARKER_TYPE_SPELLING)};
+ std::vector<int32_t> marker_starts{0};
+ std::vector<int32_t> marker_ends{4};
+ static_text2.AddIntListAttribute(ui::AX_ATTR_MARKER_TYPES, marker_types);
+ static_text2.AddIntListAttribute(ui::AX_ATTR_MARKER_STARTS, marker_starts);
+ static_text2.AddIntListAttribute(ui::AX_ATTR_MARKER_ENDS, marker_ends);
+ ui::AXTree* tree = const_cast<ui::AXTree*>(manager->ax_tree());
+ ASSERT_NE(nullptr, tree);
+ ASSERT_TRUE(tree->Unserialize(MakeAXTreeUpdate(static_text2)));
+
+ // Ensure that value1 is still not marked misspelled.
+ for (LONG offset = 0; offset < value1_length; ++offset) {
+ hr = ax_combo_box->GetCOM()->get_attributes(
+ offset, &start_offset, &end_offset, text_attributes.Receive());
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(0, start_offset);
+ EXPECT_EQ(value1_length, end_offset);
+ EXPECT_EQ(base::string16::npos,
+ base::string16(text_attributes).find(L"invalid:spelling"));
+ text_attributes.Reset();
+ }
+
+ // Ensure that "helo" is now marked misspelled.
+ for (LONG offset = value1_length; offset < value1_length + 4; ++offset) {
+ hr = ax_combo_box->GetCOM()->get_attributes(
+ offset, &start_offset, &end_offset, text_attributes.Receive());
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(value1_length, start_offset);
+ EXPECT_EQ(value1_length + 4, end_offset);
+ EXPECT_NE(base::string16::npos,
+ base::string16(text_attributes).find(L"invalid:spelling"));
+ text_attributes.Reset();
+ }
+
+ // Ensure that the last part of the value is not marked misspelled.
+ for (LONG offset = value1_length + 4; offset < combo_box_value_length;
+ ++offset) {
+ hr = ax_combo_box->GetCOM()->get_attributes(
+ offset, &start_offset, &end_offset, text_attributes.Receive());
+ EXPECT_EQ(S_OK, hr);
+ EXPECT_EQ(value1_length + 4, start_offset);
+ EXPECT_EQ(combo_box_value_length, end_offset);
+ EXPECT_EQ(base::string16::npos,
+ base::string16(text_attributes).find(L"invalid:spelling"));
+ text_attributes.Reset();
+ }
+
+ manager.reset();
+}
+
TEST_F(BrowserAccessibilityTest, TestDeepestFirstLastChild) {
ui::AXNodeData root;
root.id = 1;
@@ -2209,26 +2349,26 @@ TEST_F(BrowserAccessibilityTest, UniqueIdWinInvalidAfterDeletingTree) {
// Trying to access the unique IDs of the old, deleted objects should fail.
base::win::ScopedVariant old_root_variant(-root_unique_id);
- base::win::ScopedComPtr<IDispatch> old_root_dispatch;
+ Microsoft::WRL::ComPtr<IDispatch> old_root_dispatch;
HRESULT hr = ToBrowserAccessibilityWin(root)->GetCOM()->get_accChild(
old_root_variant, old_root_dispatch.GetAddressOf());
EXPECT_EQ(E_INVALIDARG, hr);
base::win::ScopedVariant old_child_variant(-child_unique_id);
- base::win::ScopedComPtr<IDispatch> old_child_dispatch;
+ Microsoft::WRL::ComPtr<IDispatch> old_child_dispatch;
hr = ToBrowserAccessibilityWin(root)->GetCOM()->get_accChild(
old_child_variant, old_child_dispatch.GetAddressOf());
EXPECT_EQ(E_INVALIDARG, hr);
// Trying to access the unique IDs of the new objects should succeed.
base::win::ScopedVariant new_root_variant(-root_unique_id_2);
- base::win::ScopedComPtr<IDispatch> new_root_dispatch;
+ Microsoft::WRL::ComPtr<IDispatch> new_root_dispatch;
hr = ToBrowserAccessibilityWin(root)->GetCOM()->get_accChild(
new_root_variant, new_root_dispatch.GetAddressOf());
EXPECT_EQ(S_OK, hr);
base::win::ScopedVariant new_child_variant(-child_unique_id_2);
- base::win::ScopedComPtr<IDispatch> new_child_dispatch;
+ Microsoft::WRL::ComPtr<IDispatch> new_child_dispatch;
hr = ToBrowserAccessibilityWin(root)->GetCOM()->get_accChild(
new_child_variant, new_child_dispatch.GetAddressOf());
EXPECT_EQ(S_OK, hr);
@@ -2252,7 +2392,7 @@ TEST_F(BrowserAccessibilityTest, AccChildOnlyReturnsDescendants) {
BrowserAccessibility* child = root->PlatformGetChild(0);
base::win::ScopedVariant root_unique_id_variant(-GetUniqueId(root));
- base::win::ScopedComPtr<IDispatch> result;
+ Microsoft::WRL::ComPtr<IDispatch> result;
EXPECT_EQ(E_INVALIDARG,
ToBrowserAccessibilityWin(child)->GetCOM()->get_accChild(
root_unique_id_variant, result.GetAddressOf()));
@@ -2299,10 +2439,10 @@ TEST_F(BrowserAccessibilityTest, TestIAccessible2Relations) {
LONG n_targets = 0;
LONG unique_id = 0;
base::win::ScopedBstr relation_type;
- base::win::ScopedComPtr<IAccessibleRelation> describedby_relation;
- base::win::ScopedComPtr<IAccessibleRelation> description_for_relation;
- base::win::ScopedComPtr<IUnknown> target;
- base::win::ScopedComPtr<IAccessible2> ax_target;
+ Microsoft::WRL::ComPtr<IAccessibleRelation> describedby_relation;
+ Microsoft::WRL::ComPtr<IAccessibleRelation> description_for_relation;
+ Microsoft::WRL::ComPtr<IUnknown> target;
+ Microsoft::WRL::ComPtr<IAccessible2> ax_target;
EXPECT_HRESULT_SUCCEEDED(ax_root->GetCOM()->get_nRelations(&n_relations));
EXPECT_EQ(1, n_relations);
diff --git a/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h b/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h
index 32762eea89e..5db8c81c084 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h
+++ b/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#ifndef CONTENT_BROWSER_ACCESSIBILITY_DUMP_ACCESSIBILITY_BROWSERTEST_BASE_H_
+#define CONTENT_BROWSER_ACCESSIBILITY_DUMP_ACCESSIBILITY_BROWSERTEST_BASE_H_
+
#include <string>
#include <vector>
@@ -114,3 +117,5 @@ class DumpAccessibilityTestBase : public ContentBrowserTest {
};
} // namespace content
+
+#endif // CONTENT_BROWSER_ACCESSIBILITY_DUMP_ACCESSIBILITY_BROWSERTEST_BASE_H_
diff --git a/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index e1b4b319bb4..5c24a18c40e 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -298,7 +298,13 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
- AccessibilityEventsLiveRegionRemove) {
+ AccessibilityEventsLiveRegionIgnoresClick) {
+ RunEventTest(FILE_PATH_LITERAL("live-region-ignores-click.html"));
+}
+
+// http:/crbug.com/786848
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
+ DISABLED_AccessibilityEventsLiveRegionRemove) {
RunEventTest(FILE_PATH_LITERAL("live-region-remove.html"));
}
diff --git a/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 76c2d6efd49..51e955b4f11 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -116,6 +116,13 @@ class DumpAccessibilityTreeTest : public DumpAccessibilityTestBase {
RunTest(html_file, "accessibility/html");
}
+ void RunRegressionTest(const base::FilePath::CharType* file_path) {
+ base::FilePath test_path = GetTestFilePath("accessibility", "regression");
+ base::FilePath test_file = test_path.Append(base::FilePath(file_path));
+
+ RunTest(test_file, "accessibility/regression");
+ }
+
std::vector<std::string> Dump() override {
std::unique_ptr<AccessibilityTreeFormatter> formatter(
CreateAccessibilityTreeFormatter());
@@ -154,7 +161,7 @@ void DumpAccessibilityTreeTest::AddDefaultFilters(
AddFilter(filters, "DEFAULT");
AddFilter(filters, "EXPANDED");
AddFilter(filters, "FLOATING");
- AddFilter(filters, "FOCUS*");
+ AddFilter(filters, "FOCUSABLE");
AddFilter(filters, "HASPOPUP");
AddFilter(filters, "INVISIBLE");
AddFilter(filters, "MARQUEED");
@@ -181,6 +188,10 @@ void DumpAccessibilityTreeTest::AddDefaultFilters(
AddFilter(filters, "IA2_STATE_REQUIRED");
AddFilter(filters, "IA2_STATE_STALE");
AddFilter(filters, "IA2_STATE_TRANSIENT");
+ // Reduce flakiness.
+ AddFilter(filters, "FOCUSED", Filter::DENY);
+ AddFilter(filters, "HOTTRACKED", Filter::DENY);
+ AddFilter(filters, "OFFSCREEN", Filter::DENY);
//
// Blink
@@ -272,6 +283,11 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAbbr) {
RunHtmlTest(FILE_PATH_LITERAL("abbr.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityAbsoluteOffscreen) {
+ RunHtmlTest(FILE_PATH_LITERAL("absolute-offscreen.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityActionVerbs) {
RunHtmlTest(FILE_PATH_LITERAL("action-verbs.html"));
}
@@ -749,7 +765,7 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaSearchbox) {
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
- AccessibilityAriaSearchboxWithSelection) {
+ DISABLED_AccessibilityAriaSearchboxWithSelection) {
RunAriaTest(FILE_PATH_LITERAL("aria-searchbox-with-selection.html"));
}
@@ -822,7 +838,7 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
- AccessibilityAriaTextboxWithSelection) {
+ DISABLED_AccessibilityAriaTextboxWithSelection) {
RunAriaTest(FILE_PATH_LITERAL("aria-textbox-with-selection.html"));
}
@@ -929,7 +945,15 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityBody) {
RunHtmlTest(FILE_PATH_LITERAL("body.html"));
}
-IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, DISABLED_AccessibilityBR) {
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityBoundsInherits) {
+ RunHtmlTest(FILE_PATH_LITERAL("bounds-inherits.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibiltyBoundsClips) {
+ RunHtmlTest(FILE_PATH_LITERAL("bounds-clips.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityBR) {
RunHtmlTest(FILE_PATH_LITERAL("br.html"));
}
@@ -1150,31 +1174,20 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
RunHtmlTest(FILE_PATH_LITERAL("iframe-cross-process.html"));
}
-// Flaky on Mac and Win
-#if defined(OS_WIN) || defined(OS_MACOSX)
-#define MAYBE_AccessibilityIframeCoordinates \
- DISABLED_AccessibilityIframeCoordinates
-#else
-#define MAYBE_AccessibilityIframeCoordinates AccessibilityIframeCoordinates
-#endif
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
- MAYBE_AccessibilityIframeCoordinates) {
+ AccessibilityIframeCoordinates) {
RunHtmlTest(FILE_PATH_LITERAL("iframe-coordinates.html"));
}
-// Flaky on Mac and Win
-#if defined(OS_WIN) || defined(OS_MACOSX)
-#define MAYBE_AccessibilityIframeCoordinatesCrossProcess \
- DISABLED_AccessibilityIframeCoordinatesCrossProcess
-#else
-#define MAYBE_AccessibilityIframeCoordinatesCrossProcess \
- AccessibilityIframeCoordinatesCrossProcess
-#endif
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
- MAYBE_AccessibilityIframeCoordinatesCrossProcess) {
+ AccessibilityIframeCoordinatesCrossProcess) {
RunHtmlTest(FILE_PATH_LITERAL("iframe-coordinates-cross-process.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityIframePadding) {
+ RunHtmlTest(FILE_PATH_LITERAL("iframe-padding.html"));
+}
+
// Flaky on Win7. http://crbug.com/610744
#ifdef OS_WIN
#define MAYBE_AccessibilityIframePresentational DISABLED_AccessibilityIframePresentational
@@ -1197,18 +1210,17 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
- DISABLED_AccessibilityIframeTransformNested) {
+ AccessibilityIframeTransformNested) {
RunHtmlTest(FILE_PATH_LITERAL("iframe-transform-nested.html"));
}
-IN_PROC_BROWSER_TEST_F(
- DumpAccessibilityTreeTest,
- DISABLED_AccessibilityIframeTransformNestedCrossProcess) {
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityIframeTransformNestedCrossProcess) {
RunHtmlTest(FILE_PATH_LITERAL("iframe-transform-nested-cross-process.html"));
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
- DISABLED_AccessibilityIframeTransformScrolled) {
+ AccessibilityIframeTransformScrolled) {
RunHtmlTest(FILE_PATH_LITERAL("iframe-transform-scrolled.html"));
}
@@ -1293,6 +1305,10 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
RunHtmlTest(FILE_PATH_LITERAL("input-image-button-in-menu.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputList) {
+ RunHtmlTest(FILE_PATH_LITERAL("input-list.html"));
+}
+
// crbug.com/423675 - AX tree is different for Win7 and Win8.
#if defined(OS_WIN)
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
@@ -1510,13 +1526,12 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityObject) {
RunHtmlTest(FILE_PATH_LITERAL("object.html"));
}
-IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
- DISABLED_AccessibilityOffscreen) {
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityOffscreen) {
RunHtmlTest(FILE_PATH_LITERAL("offscreen.html"));
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
- DISABLED_AccessibilityOffscreenScroll) {
+ AccessibilityOffscreenScroll) {
RunHtmlTest(FILE_PATH_LITERAL("offscreen-scroll.html"));
}
@@ -1694,8 +1709,18 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityWbr) {
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
- DISABLED_AccessibilityWindowCropsItems) {
+ AccessibilityWindowCropsItems) {
RunHtmlTest(FILE_PATH_LITERAL("window-crops-items.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
+// in the past.
+//
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, XmlInIframeCrash) {
+ RunRegressionTest(FILE_PATH_LITERAL("xml-in-iframe-crash.html"));
+}
+
} // namespace content
diff --git a/chromium/content/browser/accessibility/fullscreen_browsertest.cc b/chromium/content/browser/accessibility/fullscreen_browsertest.cc
new file mode 100644
index 00000000000..a93f137234f
--- /dev/null
+++ b/chromium/content/browser/accessibility/fullscreen_browsertest.cc
@@ -0,0 +1,108 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/web_contents/web_contents_impl.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 "content/test/accessibility_browser_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class AccessibilityFullscreenBrowserTest : public ContentBrowserTest {
+ public:
+ AccessibilityFullscreenBrowserTest() = default;
+ ~AccessibilityFullscreenBrowserTest() override = default;
+
+ protected:
+ BrowserAccessibility* FindButton(BrowserAccessibility* node) {
+ if (node->GetRole() == ui::AX_ROLE_BUTTON)
+ return node;
+ for (unsigned i = 0; i < node->PlatformChildCount(); i++) {
+ if (BrowserAccessibility* button = FindButton(node->PlatformGetChild(i)))
+ return button;
+ }
+ return nullptr;
+ }
+
+ int CountLinks(BrowserAccessibility* node) {
+ if (node->GetRole() == ui::AX_ROLE_LINK)
+ return 1;
+ int links_in_children = 0;
+ for (unsigned i = 0; i < node->PlatformChildCount(); i++) {
+ links_in_children += CountLinks(node->PlatformGetChild(i));
+ }
+ return links_in_children;
+ }
+};
+
+namespace {
+
+// FakeFullscreenDelegate simply stores the latest requested mod and reports it
+// back, which is all that is required for the renderer to enter fullscreen.
+class FakeFullscreenDelegate : public WebContentsDelegate {
+ public:
+ FakeFullscreenDelegate() = default;
+ ~FakeFullscreenDelegate() override = default;
+
+ void EnterFullscreenModeForTab(WebContents*, const GURL&) override {
+ is_fullscreen_ = true;
+ }
+
+ void ExitFullscreenModeForTab(WebContents*) override {
+ is_fullscreen_ = false;
+ }
+
+ bool IsFullscreenForTabOrPending(const WebContents*) const override {
+ return is_fullscreen_;
+ }
+
+ private:
+ bool is_fullscreen_ = false;
+ DISALLOW_COPY_AND_ASSIGN(FakeFullscreenDelegate);
+};
+
+} // namespace
+
+IN_PROC_BROWSER_TEST_F(AccessibilityFullscreenBrowserTest,
+ IgnoreElementsOutsideFullscreenElement) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ FakeFullscreenDelegate delegate;
+ shell()->web_contents()->SetDelegate(&delegate);
+
+ AccessibilityNotificationWaiter waiter(
+ shell()->web_contents(), ui::kAXModeComplete, ui::AX_EVENT_LOAD_COMPLETE);
+ GURL url(
+ embedded_test_server()->GetURL("/accessibility/fullscreen/links.html"));
+ NavigateToURL(shell(), url);
+ waiter.WaitForNotification();
+
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ BrowserAccessibilityManager* manager =
+ web_contents->GetRootBrowserAccessibilityManager();
+
+ // Initially there are 3 links in the accessiblity tree.
+ EXPECT_EQ(3, CountLinks(manager->GetRoot()));
+
+ // Enter fullscreen by finding the button and performing the default action,
+ // which is to click it.
+ BrowserAccessibility* button = FindButton(manager->GetRoot());
+ ASSERT_NE(nullptr, button);
+ manager->DoDefaultAction(*button);
+
+ // Upon entering fullscreen, the page will change the button text to "Done".
+ WaitForAccessibilityTreeToContainNodeWithName(web_contents, "Done");
+
+ // Now, the two links outside of the fullscreen element are gone.
+ EXPECT_EQ(1, CountLinks(manager->GetRoot()));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/accessibility/hit_testing_browsertest.cc b/chromium/content/browser/accessibility/hit_testing_browsertest.cc
index 11e32bf32f0..1d035edc738 100644
--- a/chromium/content/browser/accessibility/hit_testing_browsertest.cc
+++ b/chromium/content/browser/accessibility/hit_testing_browsertest.cc
@@ -97,7 +97,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityHitTestingBrowserTest,
waiter.WaitForNotification();
BrowserAccessibility* hit_node = HitTestAndWaitForResult(gfx::Point(-1, -1));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_EQ(ui::AX_ROLE_ROOT_WEB_AREA, hit_node->GetRole());
}
@@ -126,30 +126,30 @@ IN_PROC_BROWSER_TEST_F(AccessibilityHitTestingBrowserTest,
// (50, 50) -> "Button"
BrowserAccessibility* hit_node;
hit_node = HitTestAndWaitForResult(gfx::Point(50, 50));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_EQ(ui::AX_ROLE_BUTTON, hit_node->GetRole());
ASSERT_EQ("Button", hit_node->GetStringAttribute(ui::AX_ATTR_NAME));
// (50, 305) -> div in first iframe
hit_node = HitTestAndWaitForResult(gfx::Point(50, 305));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_EQ(ui::AX_ROLE_GENERIC_CONTAINER, hit_node->GetRole());
// (50, 350) -> "Ordinary Button"
hit_node = HitTestAndWaitForResult(gfx::Point(50, 350));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_EQ(ui::AX_ROLE_BUTTON, hit_node->GetRole());
ASSERT_EQ("Ordinary Button", hit_node->GetStringAttribute(ui::AX_ATTR_NAME));
// (50, 455) -> "Scrolled Button"
hit_node = HitTestAndWaitForResult(gfx::Point(50, 455));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_EQ(ui::AX_ROLE_BUTTON, hit_node->GetRole());
ASSERT_EQ("Scrolled Button", hit_node->GetStringAttribute(ui::AX_ATTR_NAME));
// (50, 505) -> div in second iframe
hit_node = HitTestAndWaitForResult(gfx::Point(50, 505));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_EQ(ui::AX_ROLE_GENERIC_CONTAINER, hit_node->GetRole());
// (50, 505) -> div in second iframe
@@ -188,21 +188,21 @@ IN_PROC_BROWSER_TEST_F(AccessibilityHitTestingBrowserTest,
// (50, 50) -> "Button"
BrowserAccessibility* hit_node;
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 50));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_NE(ui::AX_ROLE_BUTTON, hit_node->GetRole());
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 50));
ASSERT_EQ("Button", hit_node->GetStringAttribute(ui::AX_ATTR_NAME));
// (50, 305) -> div in first iframe
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 305));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_NE(ui::AX_ROLE_GENERIC_CONTAINER, hit_node->GetRole());
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 305));
ASSERT_EQ(ui::AX_ROLE_GENERIC_CONTAINER, hit_node->GetRole());
// (50, 350) -> "Ordinary Button"
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 350));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_NE(ui::AX_ROLE_BUTTON, hit_node->GetRole());
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 350));
ASSERT_EQ(ui::AX_ROLE_BUTTON, hit_node->GetRole());
@@ -210,7 +210,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityHitTestingBrowserTest,
// (50, 455) -> "Scrolled Button"
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 455));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_NE(ui::AX_ROLE_BUTTON, hit_node->GetRole());
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 455));
ASSERT_EQ(ui::AX_ROLE_BUTTON, hit_node->GetRole());
@@ -218,7 +218,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityHitTestingBrowserTest,
// (50, 505) -> div in second iframe
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 505));
- ASSERT_TRUE(hit_node != NULL);
+ ASSERT_TRUE(hit_node != nullptr);
ASSERT_NE(ui::AX_ROLE_GENERIC_CONTAINER, hit_node->GetRole());
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 505));
ASSERT_EQ(ui::AX_ROLE_GENERIC_CONTAINER, hit_node->GetRole());
diff --git a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc
index 468d6839e44..97ebec83ed4 100644
--- a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc
+++ b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc
@@ -39,9 +39,9 @@ OneShotAccessibilityTreeSearch::OneShotAccessibilityTreeSearch(
direction_(OneShotAccessibilityTreeSearch::FORWARDS),
result_limit_(UNLIMITED_RESULTS),
immediate_descendants_only_(false),
+ can_wrap_to_last_element_(false),
visible_only_(false),
- did_search_(false) {
-}
+ did_search_(false) {}
OneShotAccessibilityTreeSearch::~OneShotAccessibilityTreeSearch() {
}
@@ -73,6 +73,12 @@ void OneShotAccessibilityTreeSearch::SetImmediateDescendantsOnly(
immediate_descendants_only_ = immediate_descendants_only;
}
+void OneShotAccessibilityTreeSearch::SetCanWrapToLastElement(
+ bool can_wrap_to_last_element) {
+ DCHECK(!did_search_);
+ can_wrap_to_last_element_ = can_wrap_to_last_element;
+}
+
void OneShotAccessibilityTreeSearch::SetVisibleOnly(bool visible_only) {
DCHECK(!did_search_);
visible_only_ = visible_only;
@@ -159,7 +165,7 @@ void OneShotAccessibilityTreeSearch::SearchByWalkingTree() {
if (direction_ == FORWARDS)
node = tree_->NextInTreeOrder(start_node_);
else
- node = tree_->PreviousInTreeOrder(start_node_);
+ node = tree_->PreviousInTreeOrder(start_node_, can_wrap_to_last_element_);
}
BrowserAccessibility* stop_node = scope_node_->PlatformGetParent();
@@ -173,7 +179,7 @@ void OneShotAccessibilityTreeSearch::SearchByWalkingTree() {
if (direction_ == FORWARDS)
node = tree_->NextInTreeOrder(node);
else
- node = tree_->PreviousInTreeOrder(node);
+ node = tree_->PreviousInTreeOrder(node, can_wrap_to_last_element_);
}
}
@@ -247,7 +253,9 @@ bool AccessibilityCheckboxPredicate(
bool AccessibilityComboboxPredicate(
BrowserAccessibility* start, BrowserAccessibility* node) {
- return (node->GetRole() == ui::AX_ROLE_COMBO_BOX ||
+ return (node->GetRole() == ui::AX_ROLE_COMBO_BOX_GROUPING ||
+ node->GetRole() == ui::AX_ROLE_COMBO_BOX_MENU_BUTTON ||
+ node->GetRole() == ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX ||
node->GetRole() == ui::AX_ROLE_POP_UP_BUTTON);
}
@@ -413,7 +421,7 @@ bool AccessibilityTablePredicate(
bool AccessibilityTextfieldPredicate(
BrowserAccessibility* start, BrowserAccessibility* node) {
- return (node->IsSimpleTextControl() || node->IsRichTextControl());
+ return (node->IsPlainTextField() || node->IsRichTextField());
}
bool AccessibilityTextStyleBoldPredicate(
@@ -436,7 +444,7 @@ bool AccessibilityTextStyleUnderlinePredicate(
bool AccessibilityTreePredicate(
BrowserAccessibility* start, BrowserAccessibility* node) {
- return (node->IsSimpleTextControl() || node->IsRichTextControl());
+ return (node->IsPlainTextField() || node->IsRichTextField());
}
bool AccessibilityUnvisitedLinkPredicate(
diff --git a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.h b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.h
index df79eb94e02..3080a5d0ff0 100644
--- a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.h
+++ b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.h
@@ -108,6 +108,9 @@ class CONTENT_EXPORT OneShotAccessibilityTreeSearch {
// recurse.
void SetImmediateDescendantsOnly(bool immediate_descendants_only);
+ // If true, wraps to the last element.
+ void SetCanWrapToLastElement(bool can_wrap_to_last_element);
+
// If true, only considers nodes that aren't invisible or offscreen.
void SetVisibleOnly(bool visible_only);
@@ -138,6 +141,7 @@ class CONTENT_EXPORT OneShotAccessibilityTreeSearch {
Direction direction_;
int result_limit_;
bool immediate_descendants_only_;
+ bool can_wrap_to_last_element_;
bool visible_only_;
std::string search_text_;
diff --git a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc
index 23841fbacb6..13a377496ae 100644
--- a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc
+++ b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc
@@ -10,12 +10,23 @@
#include "base/test/scoped_task_environment.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
+#ifdef OS_ANDROID
+#include "content/browser/accessibility/browser_accessibility_manager_android.h"
+#endif
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
+#ifdef OS_ANDROID
+class TestBrowserAccessibilityManager
+ : public BrowserAccessibilityManagerAndroid {
+ public:
+ TestBrowserAccessibilityManager(const ui::AXTreeUpdate& initial_tree)
+ : BrowserAccessibilityManagerAndroid(initial_tree, nullptr, nullptr) {}
+};
+#else
class TestBrowserAccessibilityManager : public BrowserAccessibilityManager {
public:
TestBrowserAccessibilityManager(
@@ -24,6 +35,7 @@ class TestBrowserAccessibilityManager : public BrowserAccessibilityManager {
nullptr,
new BrowserAccessibilityFactory()) {}
};
+#endif
} // namespace
@@ -55,6 +67,7 @@ void MAYBE_OneShotAccessibilityTreeSearchTest::SetUp() {
root.SetName("Document");
root.role = ui::AX_ROLE_ROOT_WEB_AREA;
root.location = gfx::RectF(0, 0, 800, 600);
+ root.AddBoolAttribute(ui::AX_ATTR_CLIPS_CHILDREN, true);
root.child_ids.push_back(2);
root.child_ids.push_back(3);
root.child_ids.push_back(6);
@@ -63,10 +76,12 @@ void MAYBE_OneShotAccessibilityTreeSearchTest::SetUp() {
heading.id = 2;
heading.SetName("Heading");
heading.role = ui::AX_ROLE_HEADING;
+ heading.location = gfx::RectF(0, 0, 800, 50);
ui::AXNodeData list;
list.id = 3;
list.role = ui::AX_ROLE_LIST;
+ list.location = gfx::RectF(0, 50, 500, 500);
list.child_ids.push_back(4);
list.child_ids.push_back(5);
@@ -74,11 +89,13 @@ void MAYBE_OneShotAccessibilityTreeSearchTest::SetUp() {
list_item_1.id = 4;
list_item_1.SetName("Autobots");
list_item_1.role = ui::AX_ROLE_LIST_ITEM;
+ list_item_1.location = gfx::RectF(10, 10, 200, 30);
ui::AXNodeData list_item_2;
list_item_2.id = 5;
list_item_2.SetName("Decepticons");
list_item_2.role = ui::AX_ROLE_LIST_ITEM;
+ list_item_2.location = gfx::RectF(10, 40, 200, 60);
ui::AXNodeData footer;
footer.id = 6;
@@ -123,6 +140,19 @@ TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, BackwardsWithStartNode) {
}
TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest,
+ BackwardsWithStartNodeForAndroid) {
+ OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+ search.SetStartNode(tree_->GetFromID(4));
+ search.SetDirection(OneShotAccessibilityTreeSearch::BACKWARDS);
+ search.SetResultLimit(3);
+ search.SetCanWrapToLastElement(true);
+ ASSERT_EQ(3U, search.CountMatches());
+ EXPECT_EQ(3, search.GetMatchAtIndex(0)->GetId());
+ EXPECT_EQ(2, search.GetMatchAtIndex(1)->GetId());
+ EXPECT_EQ(1, search.GetMatchAtIndex(2)->GetId());
+}
+
+TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest,
ForwardsWithStartNodeAndScope) {
OneShotAccessibilityTreeSearch search(tree_->GetFromID(4));
search.SetStartNode(tree_->GetFromID(5));
@@ -187,7 +217,7 @@ TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest,
EXPECT_EQ(4, search.GetMatchAtIndex(0)->GetId());
}
-TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, DISABLED_VisibleOnly) {
+TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, VisibleOnly) {
OneShotAccessibilityTreeSearch search(tree_->GetRoot());
search.SetVisibleOnly(true);
ASSERT_EQ(5U, search.CountMatches());
diff --git a/chromium/content/browser/accessibility/web_contents_accessibility_android.cc b/chromium/content/browser/accessibility/web_contents_accessibility_android.cc
index 11d16927674..0c98392e526 100644
--- a/chromium/content/browser/accessibility/web_contents_accessibility_android.cc
+++ b/chromium/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -859,7 +859,8 @@ void WebContentsAccessibilityAndroid::SetSelection(
jint unique_id,
jint start,
jint end) {
- using AXPlatformPositionInstance = AXPlatformPosition::AXPositionInstance;
+ using AXPlatformPositionInstance =
+ BrowserAccessibilityPosition::AXPositionInstance;
using AXPlatformRange = ui::AXRange<AXPlatformPositionInstance::element_type>;
BrowserAccessibilityAndroid* node = GetAXFromUniqueID(unique_id);
@@ -899,8 +900,7 @@ jboolean WebContentsAccessibilityAndroid::AdjustSlider(
value += (increment ? delta : -delta);
value = std::max(std::min(value, max), min);
if (value != original_value) {
- node->manager()->SetValue(*node,
- base::UTF8ToUTF16(base::DoubleToString(value)));
+ node->manager()->SetValue(*node, base::NumberToString16(value));
return true;
}
return false;
@@ -942,6 +942,9 @@ jint WebContentsAccessibilityAndroid::FindElementType(
: OneShotAccessibilityTreeSearch::BACKWARDS);
tree_search.SetResultLimit(1);
tree_search.SetImmediateDescendantsOnly(false);
+ // SetCanWrapToLastElement needs to be set as true after talkback pushes its
+ // corresponding change for b/29103330.
+ tree_search.SetCanWrapToLastElement(false);
tree_search.SetVisibleOnly(false);
tree_search.AddPredicate(predicate);
@@ -995,6 +998,17 @@ jboolean WebContentsAccessibilityAndroid::NextAtGranularity(
return false;
}
+jint WebContentsAccessibilityAndroid::GetTextLength(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jint unique_id) {
+ BrowserAccessibilityAndroid* node = GetAXFromUniqueID(unique_id);
+ if (!node)
+ return -1;
+ base::string16 text = node->GetText();
+ return text.size();
+}
+
jboolean WebContentsAccessibilityAndroid::PreviousAtGranularity(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
@@ -1256,9 +1270,10 @@ void WebContentsAccessibilityAndroid::CollectStats() {
CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_PERFORM_GESTURES);
}
-jlong Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents) {
+jlong JNI_WebContentsAccessibility_Init(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& jweb_contents) {
WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents);
DCHECK(web_contents);
diff --git a/chromium/content/browser/accessibility/web_contents_accessibility_android.h b/chromium/content/browser/accessibility/web_contents_accessibility_android.h
index 1770297b18d..90033fb25a5 100644
--- a/chromium/content/browser/accessibility/web_contents_accessibility_android.h
+++ b/chromium/content/browser/accessibility/web_contents_accessibility_android.h
@@ -191,6 +191,11 @@ class CONTENT_EXPORT WebContentsAccessibilityAndroid
const base::android::JavaParamRef<jobject>& obj,
jint id);
+ // Returns the length of the text node.
+ jint GetTextLength(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint id);
+
// Request loading inline text boxes for a given node.
void LoadInlineTextBoxes(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
diff --git a/chromium/content/browser/android/app_web_message_port.cc b/chromium/content/browser/android/app_web_message_port.cc
index 3c2aaa3382c..9260e0efb93 100644
--- a/chromium/content/browser/android/app_web_message_port.cc
+++ b/chromium/content/browser/android/app_web_message_port.cc
@@ -7,6 +7,7 @@
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/android/string_message_codec.h"
#include "jni/AppWebMessagePort_jni.h"
@@ -121,7 +122,8 @@ void AppWebMessagePort::StartReceivingMessages(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& jcaller) {
channel_.SetCallback(base::Bind(&AppWebMessagePort::OnMessagesAvailable,
- base::Unretained(this)));
+ base::Unretained(this)),
+ base::ThreadTaskRunnerHandle::Get());
}
AppWebMessagePort::AppWebMessagePort(
@@ -142,7 +144,7 @@ void AppWebMessagePort::OnMessagesAvailable() {
Java_AppWebMessagePort_onMessagesAvailable(env, obj);
}
-void InitializeAppWebMessagePortPair(
+void JNI_AppWebMessagePort_InitializeAppWebMessagePortPair(
JNIEnv* env,
const base::android::JavaParamRef<jclass>& jcaller,
const base::android::JavaParamRef<jobjectArray>& ports) {
diff --git a/chromium/content/browser/android/browser_startup_controller.cc b/chromium/content/browser/android/browser_startup_controller.cc
index 37df3a3fe54..7a8bb0b76df 100644
--- a/chromium/content/browser/android/browser_startup_controller.cc
+++ b/chromium/content/browser/android/browser_startup_controller.cc
@@ -27,7 +27,7 @@ bool ShouldStartGpuProcessOnBrowserStartup() {
env);
}
-static void SetCommandLineFlags(
+static void JNI_BrowserStartupController_SetCommandLineFlags(
JNIEnv* env,
const JavaParamRef<jclass>& clazz,
jboolean single_process,
@@ -39,8 +39,9 @@ static void SetCommandLineFlags(
SetContentCommandLineFlags(static_cast<bool>(single_process), plugin_str);
}
-static jboolean IsOfficialBuild(JNIEnv* env,
- const JavaParamRef<jclass>& clazz) {
+static jboolean JNI_BrowserStartupController_IsOfficialBuild(
+ JNIEnv* env,
+ const JavaParamRef<jclass>& clazz) {
#if defined(OFFICIAL_BUILD)
return true;
#else
@@ -48,8 +49,9 @@ static jboolean IsOfficialBuild(JNIEnv* env,
#endif
}
-static jboolean IsPluginEnabled(JNIEnv* env,
- const JavaParamRef<jclass>& clazz) {
+static jboolean JNI_BrowserStartupController_IsPluginEnabled(
+ JNIEnv* env,
+ const JavaParamRef<jclass>& clazz) {
#if BUILDFLAG(ENABLE_PLUGINS)
return true;
#else
@@ -57,7 +59,9 @@ static jboolean IsPluginEnabled(JNIEnv* env,
#endif
}
-static void FlushStartupTasks(JNIEnv* env, const JavaParamRef<jclass>& clazz) {
+static void JNI_BrowserStartupController_FlushStartupTasks(
+ JNIEnv* env,
+ const JavaParamRef<jclass>& clazz) {
BrowserMainLoop::GetInstance()->SynchronouslyFlushStartupTasks();
}
diff --git a/chromium/content/browser/android/content_feature_list.cc b/chromium/content/browser/android/content_feature_list.cc
index 25c40266647..fdfc06d7263 100644
--- a/chromium/content/browser/android/content_feature_list.cc
+++ b/chromium/content/browser/android/content_feature_list.cc
@@ -41,9 +41,10 @@ const base::Feature* FindFeatureExposedToJava(const std::string& feature_name) {
const base::Feature kRequestUnbufferedDispatch{
"RequestUnbufferedDispatch", base::FEATURE_ENABLED_BY_DEFAULT};
-static jboolean IsEnabled(JNIEnv* env,
- const JavaParamRef<jclass>& clazz,
- const JavaParamRef<jstring>& jfeature_name) {
+static jboolean JNI_ContentFeatureList_IsEnabled(
+ JNIEnv* env,
+ const JavaParamRef<jclass>& clazz,
+ const JavaParamRef<jstring>& jfeature_name) {
const base::Feature* feature =
FindFeatureExposedToJava(ConvertJavaStringToUTF8(env, jfeature_name));
return base::FeatureList::IsEnabled(*feature);
diff --git a/chromium/content/browser/android/content_startup_flags.cc b/chromium/content/browser/android/content_startup_flags.cc
index 48c281e9a17..9fbc4f0adb6 100644
--- a/chromium/content/browser/android/content_startup_flags.cc
+++ b/chromium/content/browser/android/content_startup_flags.cc
@@ -46,9 +46,6 @@ void SetContentCommandLineFlags(bool single_process,
switches::kTouchTextSelectionStrategy, "direction");
}
- // There is no software fallback on Android, so don't limit GPU crashes.
- parsed_command_line->AppendSwitch(switches::kDisableGpuProcessCrashLimit);
-
// On legacy low-memory devices the behavior has not been studied with regard
// to having an extra process with similar priority as the foreground renderer
// and given that the system will often be looking for a process to be killed
@@ -63,8 +60,6 @@ void SetContentCommandLineFlags(bool single_process,
parsed_command_line->AppendSwitch(
cc::switches::kDisableCompositedAntialiasing);
- parsed_command_line->AppendSwitch(switches::kUIPrioritizeInGpuProcess);
-
if (!plugin_descriptor.empty()) {
parsed_command_line->AppendSwitchNative(
switches::kRegisterPepperPlugins, plugin_descriptor);
diff --git a/chromium/content/browser/android/content_video_view.cc b/chromium/content/browser/android/content_video_view.cc
index 13940c8b5a6..9df12f90ff6 100644
--- a/chromium/content/browser/android/content_video_view.cc
+++ b/chromium/content/browser/android/content_video_view.cc
@@ -22,7 +22,8 @@ ContentVideoView* g_content_video_view = NULL;
} // namespace
-static ScopedJavaLocalRef<jobject> GetSingletonJavaContentVideoView(
+static ScopedJavaLocalRef<jobject>
+JNI_ContentVideoView_GetSingletonJavaContentVideoView(
JNIEnv* env,
const JavaParamRef<jclass>&) {
if (g_content_video_view)
diff --git a/chromium/content/browser/android/content_view_core.cc b/chromium/content/browser/android/content_view_core.cc
index 575acdf44b0..2892f23959d 100644
--- a/chromium/content/browser/android/content_view_core.cc
+++ b/chromium/content/browser/android/content_view_core.cc
@@ -21,7 +21,6 @@
#include "cc/layers/layer.h"
#include "cc/layers/solid_color_layer.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
-#include "content/browser/android/gesture_event_type.h"
#include "content/browser/android/interstitial_page_delegate_android.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/media/media_web_contents_observer.h"
@@ -30,7 +29,9 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
+#include "content/browser/web_contents/web_contents_android.h"
#include "content/browser/web_contents/web_contents_view_android.h"
+#include "content/common/content_switches_internal.h"
#include "content/common/frame_messages.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
@@ -46,10 +47,11 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/menu_item.h"
#include "content/public/common/user_agent.h"
-#include "jni/ContentViewCore_jni.h"
+#include "jni/ContentViewCoreImpl_jni.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "ui/android/view_android.h"
#include "ui/android/window_android.h"
+#include "ui/events/android/gesture_event_type.h"
#include "ui/events/blink/blink_event_util.h"
#include "ui/events/blink/web_input_event_traits.h"
#include "ui/events/event_utils.h"
@@ -103,37 +105,37 @@ int GetRenderProcessIdFromRenderViewHost(RenderViewHost* host) {
int ToGestureEventType(WebInputEvent::Type type) {
switch (type) {
case WebInputEvent::kGestureScrollBegin:
- return GESTURE_EVENT_TYPE_SCROLL_START;
+ return ui::GESTURE_EVENT_TYPE_SCROLL_START;
case WebInputEvent::kGestureScrollEnd:
- return GESTURE_EVENT_TYPE_SCROLL_END;
+ return ui::GESTURE_EVENT_TYPE_SCROLL_END;
case WebInputEvent::kGestureScrollUpdate:
- return GESTURE_EVENT_TYPE_SCROLL_BY;
+ return ui::GESTURE_EVENT_TYPE_SCROLL_BY;
case WebInputEvent::kGestureFlingStart:
- return GESTURE_EVENT_TYPE_FLING_START;
+ return ui::GESTURE_EVENT_TYPE_FLING_START;
case WebInputEvent::kGestureFlingCancel:
- return GESTURE_EVENT_TYPE_FLING_CANCEL;
+ return ui::GESTURE_EVENT_TYPE_FLING_CANCEL;
case WebInputEvent::kGestureShowPress:
- return GESTURE_EVENT_TYPE_SHOW_PRESS;
+ return ui::GESTURE_EVENT_TYPE_SHOW_PRESS;
case WebInputEvent::kGestureTap:
- return GESTURE_EVENT_TYPE_SINGLE_TAP_CONFIRMED;
+ return ui::GESTURE_EVENT_TYPE_SINGLE_TAP_CONFIRMED;
case WebInputEvent::kGestureTapUnconfirmed:
- return GESTURE_EVENT_TYPE_SINGLE_TAP_UNCONFIRMED;
+ return ui::GESTURE_EVENT_TYPE_SINGLE_TAP_UNCONFIRMED;
case WebInputEvent::kGestureTapDown:
- return GESTURE_EVENT_TYPE_TAP_DOWN;
+ return ui::GESTURE_EVENT_TYPE_TAP_DOWN;
case WebInputEvent::kGestureTapCancel:
- return GESTURE_EVENT_TYPE_TAP_CANCEL;
+ return ui::GESTURE_EVENT_TYPE_TAP_CANCEL;
case WebInputEvent::kGestureDoubleTap:
- return GESTURE_EVENT_TYPE_DOUBLE_TAP;
+ return ui::GESTURE_EVENT_TYPE_DOUBLE_TAP;
case WebInputEvent::kGestureLongPress:
- return GESTURE_EVENT_TYPE_LONG_PRESS;
+ return ui::GESTURE_EVENT_TYPE_LONG_PRESS;
case WebInputEvent::kGestureLongTap:
- return GESTURE_EVENT_TYPE_LONG_TAP;
+ return ui::GESTURE_EVENT_TYPE_LONG_TAP;
case WebInputEvent::kGesturePinchBegin:
- return GESTURE_EVENT_TYPE_PINCH_BEGIN;
+ return ui::GESTURE_EVENT_TYPE_PINCH_BEGIN;
case WebInputEvent::kGesturePinchEnd:
- return GESTURE_EVENT_TYPE_PINCH_END;
+ return ui::GESTURE_EVENT_TYPE_PINCH_END;
case WebInputEvent::kGesturePinchUpdate:
- return GESTURE_EVENT_TYPE_PINCH_BY;
+ return ui::GESTURE_EVENT_TYPE_PINCH_BY;
case WebInputEvent::kGestureTwoFingerTap:
default:
NOTREACHED() << "Invalid source gesture type: "
@@ -211,7 +213,7 @@ ContentViewCore::~ContentViewCore() {
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
java_ref_.reset();
if (!j_obj.is_null()) {
- Java_ContentViewCore_onNativeContentViewCoreDestroyed(
+ Java_ContentViewCoreImpl_onNativeContentViewCoreDestroyed(
env, j_obj, reinterpret_cast<intptr_t>(this));
}
}
@@ -269,14 +271,14 @@ void ContentViewCore::InitWebContents() {
->SetContentViewCore(this);
DCHECK(!web_contents_->GetUserData(kContentViewUserDataKey));
web_contents_->SetUserData(kContentViewUserDataKey,
- base::MakeUnique<ContentViewUserData>(this));
+ std::make_unique<ContentViewUserData>(this));
}
void ContentViewCore::RenderViewReady() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (!obj.is_null())
- Java_ContentViewCore_onRenderProcessChange(env, obj);
+ Java_ContentViewCoreImpl_onRenderProcessChange(env, obj);
if (device_orientation_ != 0)
SendOrientationChangeEventInternal();
@@ -306,7 +308,7 @@ void ContentViewCore::RenderViewHostChanged(RenderViewHost* old_host,
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (!obj.is_null()) {
- Java_ContentViewCore_onRenderProcessChange(env, obj);
+ Java_ContentViewCoreImpl_onRenderProcessChange(env, obj);
}
}
@@ -344,30 +346,36 @@ jint ContentViewCore::GetBackgroundColor(JNIEnv* env, jobject obj) {
// All positions and sizes (except |top_shown_pix|) are in CSS pixels.
// Note that viewport_width/height is a best effort based.
// ContentViewCore has the actual information about the physical viewport size.
-void ContentViewCore::UpdateFrameInfo(
- const gfx::Vector2dF& scroll_offset,
- float page_scale_factor,
- const gfx::Vector2dF& page_scale_factor_limits,
- const gfx::SizeF& content_size,
- const gfx::SizeF& viewport_size,
- const float content_offset,
- const float top_shown_pix,
- bool top_changed,
- bool is_mobile_optimized_hint) {
+void ContentViewCore::UpdateFrameInfo(const gfx::Vector2dF& scroll_offset,
+ float page_scale_factor,
+ const float min_page_scale,
+ const float max_page_scale,
+ const gfx::SizeF& content_size,
+ const gfx::SizeF& viewport_size,
+ const float content_offset,
+ const float top_shown_pix,
+ bool top_changed,
+ bool is_mobile_optimized_hint) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (obj.is_null() || !GetWindowAndroid())
return;
- GetViewAndroid()->UpdateFrameInfo({
- viewport_size, page_scale_factor, content_offset,
- });
+ GetViewAndroid()->UpdateFrameInfo({viewport_size, content_offset});
- Java_ContentViewCore_updateFrameInfo(
+ // Current viewport size in css.
+ gfx::SizeF view_size = gfx::SizeF(gfx::ScaleToCeiledSize(
+ GetViewportSizePix(), 1.0f / (dpi_scale() * page_scale_factor)));
+
+ // Adjust content size to be always at least as big as the actual
+ // viewport (as set by onSizeChanged).
+ float content_width = std::max(content_size.width(), view_size.width());
+ float content_height = std::max(content_size.height(), view_size.height());
+
+ Java_ContentViewCoreImpl_updateFrameInfo(
env, obj, scroll_offset.x(), scroll_offset.y(), page_scale_factor,
- page_scale_factor_limits.x(), page_scale_factor_limits.y(),
- content_size.width(), content_size.height(), viewport_size.width(),
- viewport_size.height(), top_shown_pix, top_changed,
+ min_page_scale, max_page_scale, content_width, content_height,
+ viewport_size.width(), viewport_size.height(), top_shown_pix, top_changed,
is_mobile_optimized_hint);
}
@@ -423,8 +431,13 @@ void ContentViewCore::ShowSelectPopupMenu(RenderFrameHost* frame,
const ScopedJavaLocalRef<jobject> popup_view = select_popup_.view();
if (popup_view.is_null())
return;
- view->SetAnchorRect(popup_view, gfx::RectF(bounds));
- Java_ContentViewCore_showSelectPopup(
+ // |bounds| is in physical pixels if --use-zoom-for-dsf is enabled. Otherwise,
+ // it is in DIP pixels.
+ gfx::RectF bounds_dip = gfx::RectF(bounds);
+ if (IsUseZoomForDSFEnabled())
+ bounds_dip.Scale(1 / dpi_scale_);
+ view->SetAnchorRect(popup_view, bounds_dip);
+ Java_ContentViewCoreImpl_showSelectPopup(
env, j_obj, popup_view, reinterpret_cast<intptr_t>(frame), items_array,
enabled_array, multiple, selected_array, right_aligned);
}
@@ -433,7 +446,7 @@ void ContentViewCore::HideSelectPopupMenu() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
if (!j_obj.is_null())
- Java_ContentViewCore_hideSelectPopup(env, j_obj);
+ Java_ContentViewCoreImpl_hideSelectPopup(env, j_obj);
select_popup_.Reset();
}
@@ -448,40 +461,40 @@ void ContentViewCore::OnGestureEventAck(const blink::WebGestureEvent& event,
case WebInputEvent::kGestureFlingStart:
if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) {
// The view expects the fling velocity in pixels/s.
- Java_ContentViewCore_onFlingStartEventConsumed(env, j_obj);
+ Java_ContentViewCoreImpl_onFlingStartEventConsumed(env, j_obj);
} else {
// If a scroll ends with a fling, a SCROLL_END event is never sent.
// However, if that fling went unconsumed, we still need to let the
// listeners know that scrolling has ended.
- Java_ContentViewCore_onScrollEndEventAck(env, j_obj);
+ Java_ContentViewCoreImpl_onScrollEndEventAck(env, j_obj);
}
break;
case WebInputEvent::kGestureFlingCancel:
- Java_ContentViewCore_onFlingCancelEventAck(env, j_obj);
+ Java_ContentViewCoreImpl_onFlingCancelEventAck(env, j_obj);
break;
case WebInputEvent::kGestureScrollBegin:
- Java_ContentViewCore_onScrollBeginEventAck(env, j_obj);
+ Java_ContentViewCoreImpl_onScrollBeginEventAck(env, j_obj);
break;
case WebInputEvent::kGestureScrollUpdate:
if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
- Java_ContentViewCore_onScrollUpdateGestureConsumed(env, j_obj);
+ Java_ContentViewCoreImpl_onScrollUpdateGestureConsumed(env, j_obj);
break;
case WebInputEvent::kGestureScrollEnd:
- Java_ContentViewCore_onScrollEndEventAck(env, j_obj);
+ Java_ContentViewCoreImpl_onScrollEndEventAck(env, j_obj);
break;
case WebInputEvent::kGesturePinchBegin:
- Java_ContentViewCore_onPinchBeginEventAck(env, j_obj);
+ Java_ContentViewCoreImpl_onPinchBeginEventAck(env, j_obj);
break;
case WebInputEvent::kGesturePinchEnd:
- Java_ContentViewCore_onPinchEndEventAck(env, j_obj);
+ Java_ContentViewCoreImpl_onPinchEndEventAck(env, j_obj);
break;
case WebInputEvent::kGestureTap:
- Java_ContentViewCore_onSingleTapEventAck(
+ Java_ContentViewCoreImpl_onSingleTapEventAck(
env, j_obj, ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
break;
case WebInputEvent::kGestureLongPress:
if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
- Java_ContentViewCore_performLongPressHapticFeedback(env, j_obj);
+ Java_ContentViewCoreImpl_performLongPressHapticFeedback(env, j_obj);
break;
default:
break;
@@ -508,16 +521,16 @@ bool ContentViewCore::FilterInputEvent(const blink::WebInputEvent& event) {
const blink::WebGestureEvent& gesture =
static_cast<const blink::WebGestureEvent&>(event);
int gesture_type = ToGestureEventType(event.GetType());
- return Java_ContentViewCore_filterTapOrPressEvent(env, j_obj, gesture_type,
- gesture.x * dpi_scale(),
- gesture.y * dpi_scale());
+ return Java_ContentViewCoreImpl_filterTapOrPressEvent(
+ env, j_obj, gesture_type, gesture.x * dpi_scale(),
+ gesture.y * dpi_scale());
}
void ContentViewCore::RequestDisallowInterceptTouchEvent() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (!obj.is_null())
- Java_ContentViewCore_requestDisallowInterceptTouchEvent(env, obj);
+ Java_ContentViewCoreImpl_requestDisallowInterceptTouchEvent(env, obj);
}
void ContentViewCore::DidStopFlinging() {
@@ -525,14 +538,7 @@ void ContentViewCore::DidStopFlinging() {
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (!obj.is_null())
- Java_ContentViewCore_onNativeFlingStopped(env, obj);
-}
-
-gfx::Size ContentViewCore::GetViewSize() const {
- gfx::Size size = GetViewportSizeDip();
- if (DoBrowserControlsShrinkBlinkSize())
- size.Enlarge(0, -GetTopControlsHeightDip() - GetBottomControlsHeightDip());
- return size;
+ Java_ContentViewCoreImpl_onNativeFlingStopped(env, obj);
}
gfx::Size ContentViewCore::GetViewportSizePix() const {
@@ -540,44 +546,16 @@ gfx::Size ContentViewCore::GetViewportSizePix() const {
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
if (j_obj.is_null())
return gfx::Size();
- return gfx::Size(Java_ContentViewCore_getViewportWidthPix(env, j_obj),
- Java_ContentViewCore_getViewportHeightPix(env, j_obj));
-}
-
-int ContentViewCore::GetTopControlsHeightPix() const {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
- if (j_obj.is_null())
- return 0;
- return Java_ContentViewCore_getTopControlsHeightPix(env, j_obj);
+ return gfx::Size(Java_ContentViewCoreImpl_getViewportWidthPix(env, j_obj),
+ Java_ContentViewCoreImpl_getViewportHeightPix(env, j_obj));
}
-int ContentViewCore::GetBottomControlsHeightPix() const {
+int ContentViewCore::GetMouseWheelMinimumGranularity() const {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
if (j_obj.is_null())
return 0;
- return Java_ContentViewCore_getBottomControlsHeightPix(env, j_obj);
-}
-
-gfx::Size ContentViewCore::GetViewportSizeDip() const {
- return gfx::ScaleToCeiledSize(GetViewportSizePix(), 1.0f / dpi_scale());
-}
-
-bool ContentViewCore::DoBrowserControlsShrinkBlinkSize() const {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
- if (j_obj.is_null())
- return false;
- return Java_ContentViewCore_doBrowserControlsShrinkBlinkSize(env, j_obj);
-}
-
-float ContentViewCore::GetTopControlsHeightDip() const {
- return GetTopControlsHeightPix() / dpi_scale();
-}
-
-float ContentViewCore::GetBottomControlsHeightDip() const {
- return GetBottomControlsHeightPix() / dpi_scale();
+ return Java_ContentViewCoreImpl_getMouseWheelTickMultiplier(env, j_obj);
}
void ContentViewCore::SendScreenRectsAndResizeWidget() {
@@ -653,6 +631,15 @@ void ContentViewCore::SetFocusInternal(bool focused) {
GetRenderWidgetHostViewAndroid()->LostFocus();
}
+int ContentViewCore::GetTopControlsShrinkBlinkHeightPixForTesting(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
+ RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
+ return !rwhv || !rwhv->DoBrowserControlsShrinkBlinkSize()
+ ? 0
+ : rwhv->GetTopControlsHeight() * dpi_scale_;
+}
+
void ContentViewCore::SendOrientationChangeEvent(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
@@ -773,37 +760,6 @@ void ContentViewCore::DoubleTap(JNIEnv* env,
SendGestureEvent(event);
}
-void ContentViewCore::PinchBegin(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jlong time_ms,
- jfloat x,
- jfloat y) {
- WebGestureEvent event =
- MakeGestureEvent(WebInputEvent::kGesturePinchBegin, time_ms, x, y);
- SendGestureEvent(event);
-}
-
-void ContentViewCore::PinchEnd(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jlong time_ms) {
- WebGestureEvent event =
- MakeGestureEvent(WebInputEvent::kGesturePinchEnd, time_ms, 0, 0);
- SendGestureEvent(event);
-}
-
-void ContentViewCore::PinchBy(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jlong time_ms,
- jfloat anchor_x,
- jfloat anchor_y,
- jfloat delta) {
- WebGestureEvent event = MakeGestureEvent(WebInputEvent::kGesturePinchUpdate,
- time_ms, anchor_x, anchor_y);
- event.data.pinch_update.scale = delta;
-
- SendGestureEvent(event);
-}
-
void ContentViewCore::SetTextHandlesTemporarilyHidden(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
@@ -844,7 +800,7 @@ void ContentViewCore::OnTouchDown(
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (obj.is_null())
return;
- Java_ContentViewCore_onTouchDown(env, obj, event);
+ Java_ContentViewCoreImpl_onTouchDown(env, obj, event);
}
void ContentViewCore::WasResized(JNIEnv* env,
@@ -886,7 +842,8 @@ bool ContentViewCore::IsFullscreenRequiredForOrientationLock() const {
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (obj.is_null())
return true;
- return Java_ContentViewCore_isFullscreenRequiredForOrientationLock(env, obj);
+ return Java_ContentViewCoreImpl_isFullscreenRequiredForOrientationLock(env,
+ obj);
}
void ContentViewCore::SendOrientationChangeEventInternal() {
@@ -927,7 +884,7 @@ void ContentViewCore::HidePopupsAndPreserveSelection() {
if (obj.is_null())
return;
- Java_ContentViewCore_hidePopupsAndPreserveSelection(env, obj);
+ Java_ContentViewCoreImpl_hidePopupsAndPreserveSelection(env, obj);
}
void ContentViewCore::WebContentsDestroyed() {
@@ -938,12 +895,13 @@ void ContentViewCore::WebContentsDestroyed() {
}
// This is called for each ContentView.
-jlong Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents,
- const JavaParamRef<jobject>& jview_android_delegate,
- jlong jwindow_android,
- jfloat dip_scale) {
+jlong JNI_ContentViewCoreImpl_Init(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& jweb_contents,
+ const JavaParamRef<jobject>& jview_android_delegate,
+ jlong jwindow_android,
+ jfloat dip_scale) {
WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
WebContents::FromJavaWebContents(jweb_contents));
CHECK(web_contents)
@@ -961,7 +919,8 @@ jlong Init(JNIEnv* env,
return reinterpret_cast<intptr_t>(view);
}
-static ScopedJavaLocalRef<jobject> FromWebContentsAndroid(
+static ScopedJavaLocalRef<jobject>
+JNI_ContentViewCoreImpl_FromWebContentsAndroid(
JNIEnv* env,
const JavaParamRef<jclass>& clazz,
const JavaParamRef<jobject>& jweb_contents) {
diff --git a/chromium/content/browser/android/content_view_core.h b/chromium/content/browser/android/content_view_core.h
index 7218a518f78..0feda0a8939 100644
--- a/chromium/content/browser/android/content_view_core.h
+++ b/chromium/content/browser/android/content_view_core.h
@@ -75,6 +75,12 @@ class ContentViewCore : public WebContentsObserver {
jlong selectPopupSourceFrame,
const base::android::JavaParamRef<jintArray>& indices);
+ // Returns the amount of the top controls height if controls are in the state
+ // of shrinking Blink's view size, otherwise 0.
+ int GetTopControlsShrinkBlinkHeightPixForTesting(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+
void SendOrientationChangeEvent(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
@@ -125,20 +131,6 @@ class ContentViewCore : public WebContentsObserver {
jfloat x,
jfloat y);
- void PinchBegin(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- jlong time_ms,
- jfloat x,
- jfloat y);
- void PinchEnd(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- jlong time_ms);
- void PinchBy(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- jlong time_ms,
- jfloat x,
- jfloat y,
- jfloat delta);
void SetTextHandlesTemporarilyHidden(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
@@ -213,7 +205,8 @@ class ContentViewCore : public WebContentsObserver {
// as cached by the renderer.
void UpdateFrameInfo(const gfx::Vector2dF& scroll_offset,
float page_scale_factor,
- const gfx::Vector2dF& page_scale_factor_limits,
+ float min_page_scale,
+ float max_page_scale,
const gfx::SizeF& content_size,
const gfx::SizeF& viewport_size,
const float top_content_offset,
@@ -232,19 +225,13 @@ class ContentViewCore : public WebContentsObserver {
// the Activity context.
base::android::ScopedJavaLocalRef<jobject> GetContext() const;
- // Returns the viewport size after accounting for the viewport offset.
- gfx::Size GetViewSize() const;
-
bool IsFullscreenRequiredForOrientationLock() const;
// --------------------------------------------------------------------------
// Methods called from native code
// --------------------------------------------------------------------------
- gfx::Size GetViewportSizeDip() const;
- bool DoBrowserControlsShrinkBlinkSize() const;
- float GetTopControlsHeightDip() const;
- float GetBottomControlsHeightDip() const;
+ int GetMouseWheelMinimumGranularity() const;
void UpdateCursor(const content::CursorInfo& info);
void OnTouchDown(const base::android::ScopedJavaLocalRef<jobject>& event);
@@ -278,8 +265,6 @@ class ContentViewCore : public WebContentsObserver {
float y) const;
gfx::Size GetViewportSizePix() const;
- int GetTopControlsHeightPix() const;
- int GetBottomControlsHeightPix() const;
void SendGestureEvent(const blink::WebGestureEvent& event);
diff --git a/chromium/content/browser/android/content_view_render_view.cc b/chromium/content/browser/android/content_view_render_view.cc
index 595cb42e51d..f6ca2f8e245 100644
--- a/chromium/content/browser/android/content_view_render_view.cc
+++ b/chromium/content/browser/android/content_view_render_view.cc
@@ -40,9 +40,9 @@ ContentViewRenderView::~ContentViewRenderView() {
}
// static
-static jlong Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jlong native_root_window) {
+static jlong JNI_ContentViewRenderView_Init(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong native_root_window) {
gfx::NativeWindow root_window =
reinterpret_cast<gfx::NativeWindow>(native_root_window);
ContentViewRenderView* content_view_render_view =
@@ -108,6 +108,8 @@ void ContentViewRenderView::SetOverlayVideoMode(
const JavaParamRef<jobject>& obj,
bool enabled) {
compositor_->SetRequiresAlphaChannel(enabled);
+ compositor_->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT
+ : SK_ColorWHITE);
compositor_->SetNeedsComposite();
}
diff --git a/chromium/content/browser/android/content_view_statics.cc b/chromium/content/browser/android/content_view_statics.cc
index 222a5b81ba7..abeb57cd933 100644
--- a/chromium/content/browser/android/content_view_statics.cc
+++ b/chromium/content/browser/android/content_view_statics.cc
@@ -90,9 +90,10 @@ base::LazyInstance<SuspendedProcessWatcher>::DestructorAtExit
} // namespace
-static void SetWebKitSharedTimersSuspended(JNIEnv* env,
- const JavaParamRef<jclass>& obj,
- jboolean suspend) {
+static void JNI_ContentViewStatics_SetWebKitSharedTimersSuspended(
+ JNIEnv* env,
+ const JavaParamRef<jclass>& obj,
+ jboolean suspend) {
if (suspend) {
g_suspended_processes_watcher.Pointer()->SuspendWebKitSharedTimers();
} else {
diff --git a/chromium/content/browser/android/dialog_overlay_impl.cc b/chromium/content/browser/android/dialog_overlay_impl.cc
index 46257dbff2f..b58177c08bb 100644
--- a/chromium/content/browser/android/dialog_overlay_impl.cc
+++ b/chromium/content/browser/android/dialog_overlay_impl.cc
@@ -19,11 +19,11 @@ using base::android::ScopedJavaLocalRef;
namespace content {
-static jlong Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jlong high,
- jlong low,
- jboolean power_efficient) {
+static jlong JNI_DialogOverlayImpl_Init(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jlong high,
+ jlong low,
+ jboolean power_efficient) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderFrameHostImpl* rfhi =
@@ -226,16 +226,17 @@ void DialogOverlayImpl::OnDetachedFromWindow() {
Java_DialogOverlayImpl_onWindowToken(env, obj, nullptr);
}
-static jint RegisterSurface(JNIEnv* env,
- const base::android::JavaParamRef<jclass>& jcaller,
- const JavaParamRef<jobject>& surface) {
+static jint JNI_DialogOverlayImpl_RegisterSurface(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jclass>& jcaller,
+ const JavaParamRef<jobject>& surface) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return gpu::GpuSurfaceTracker::Get()->AddSurfaceForNativeWidget(
gpu::GpuSurfaceTracker::SurfaceRecord(gfx::kNullAcceleratedWidget,
surface.obj()));
}
-static void UnregisterSurface(
+static void JNI_DialogOverlayImpl_UnregisterSurface(
JNIEnv* env,
const base::android::JavaParamRef<jclass>& jcaller,
jint surface_id) {
@@ -243,7 +244,8 @@ static void UnregisterSurface(
gpu::GpuSurfaceTracker::Get()->RemoveSurface(surface_id);
}
-static ScopedJavaLocalRef<jobject> LookupSurfaceForTesting(
+static ScopedJavaLocalRef<jobject>
+JNI_DialogOverlayImpl_LookupSurfaceForTesting(
JNIEnv* env,
const base::android::JavaParamRef<jclass>& jcaller,
jint surfaceId) {
diff --git a/chromium/content/browser/android/gesture_event_type.h b/chromium/content/browser/android/gesture_event_type.h
deleted file mode 100644
index 1b4854ceba9..00000000000
--- a/chromium/content/browser/android/gesture_event_type.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_ANDROID_GESTURE_EVENT_TYPE_H_
-#define CONTENT_BROWSER_ANDROID_GESTURE_EVENT_TYPE_H_
-
-namespace content {
-
-// This file contains a list of GestureEventType's usable by ContentViewCore,
-// providing a direct mapping to and from their corresponding
-// blink::WebGestureEvent types.
-//
-// A Java counterpart will be generated for this enum.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.browser
-enum GestureEventType {
- GESTURE_EVENT_TYPE_SHOW_PRESS,
- GESTURE_EVENT_TYPE_DOUBLE_TAP,
- GESTURE_EVENT_TYPE_SINGLE_TAP_UP,
- GESTURE_EVENT_TYPE_SINGLE_TAP_CONFIRMED,
- GESTURE_EVENT_TYPE_SINGLE_TAP_UNCONFIRMED,
- GESTURE_EVENT_TYPE_LONG_PRESS,
- GESTURE_EVENT_TYPE_SCROLL_START,
- GESTURE_EVENT_TYPE_SCROLL_BY,
- GESTURE_EVENT_TYPE_SCROLL_END,
- GESTURE_EVENT_TYPE_FLING_START,
- GESTURE_EVENT_TYPE_FLING_CANCEL,
- GESTURE_EVENT_TYPE_FLING_END,
- GESTURE_EVENT_TYPE_PINCH_BEGIN,
- GESTURE_EVENT_TYPE_PINCH_BY,
- GESTURE_EVENT_TYPE_PINCH_END,
- GESTURE_EVENT_TYPE_TAP_CANCEL,
- GESTURE_EVENT_TYPE_LONG_TAP,
- GESTURE_EVENT_TYPE_TAP_DOWN,
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_GESTURE_EVENT_TYPE_H_
-
diff --git a/chromium/content/browser/android/gpu_process_callback.cc b/chromium/content/browser/android/gpu_process_callback.cc
index 0bcc4247dcd..fc33aa10fd8 100644
--- a/chromium/content/browser/android/gpu_process_callback.cc
+++ b/chromium/content/browser/android/gpu_process_callback.cc
@@ -12,7 +12,7 @@
namespace content {
-void CompleteScopedSurfaceRequest(
+void JNI_GpuProcessCallback_CompleteScopedSurfaceRequest(
JNIEnv* env,
const base::android::JavaParamRef<jclass>& clazz,
const base::android::JavaParamRef<jobject>& token,
@@ -33,7 +33,8 @@ void CompleteScopedSurfaceRequest(
requestToken, gl::ScopedJavaSurface(jsurface));
}
-base::android::ScopedJavaLocalRef<jobject> GetViewSurface(
+base::android::ScopedJavaLocalRef<jobject>
+JNI_GpuProcessCallback_GetViewSurface(
JNIEnv* env,
const base::android::JavaParamRef<jclass>& jcaller,
jint surface_id) {
diff --git a/chromium/content/browser/android/ime_adapter_android.cc b/chromium/content/browser/android/ime_adapter_android.cc
index 38d949bda8a..8e1ed005537 100644
--- a/chromium/content/browser/android/ime_adapter_android.cc
+++ b/chromium/content/browser/android/ime_adapter_android.cc
@@ -62,9 +62,9 @@ NativeWebKeyboardEvent NativeWebKeyboardEventFromKeyEvent(
} // anonymous namespace
-jlong Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents) {
+jlong JNI_ImeAdapter_Init(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& jweb_contents) {
WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents);
DCHECK(web_contents);
auto* ime_adapter = new ImeAdapterAndroid(env, obj, web_contents);
@@ -74,12 +74,12 @@ jlong Init(JNIEnv* env,
// Callback from Java to convert BackgroundColorSpan data to a
// ui::ImeTextSpan instance, and append it to |ime_text_spans_ptr|.
-void AppendBackgroundColorSpan(JNIEnv*,
- const JavaParamRef<jclass>&,
- jlong ime_text_spans_ptr,
- jint start,
- jint end,
- jint background_color) {
+void JNI_ImeAdapter_AppendBackgroundColorSpan(JNIEnv*,
+ const JavaParamRef<jclass>&,
+ jlong ime_text_spans_ptr,
+ jint start,
+ jint end,
+ jint background_color) {
DCHECK_GE(start, 0);
DCHECK_GE(end, 0);
// Do not check |background_color|.
@@ -94,15 +94,16 @@ void AppendBackgroundColorSpan(JNIEnv*,
// Callback from Java to convert SuggestionSpan data to a
// ui::ImeTextSpan instance, and append it to |ime_text_spans_ptr|.
-void AppendSuggestionSpan(JNIEnv* env,
- const JavaParamRef<jclass>&,
- jlong ime_text_spans_ptr,
- jint start,
- jint end,
- jboolean is_misspelling,
- jint underline_color,
- jint suggestion_highlight_color,
- const JavaParamRef<jobjectArray>& suggestions) {
+void JNI_ImeAdapter_AppendSuggestionSpan(
+ JNIEnv* env,
+ const JavaParamRef<jclass>&,
+ jlong ime_text_spans_ptr,
+ jint start,
+ jint end,
+ jboolean is_misspelling,
+ jint underline_color,
+ jint suggestion_highlight_color,
+ const JavaParamRef<jobjectArray>& suggestions) {
DCHECK_GE(start, 0);
DCHECK_GE(end, 0);
@@ -122,11 +123,11 @@ void AppendSuggestionSpan(JNIEnv* env,
// Callback from Java to convert UnderlineSpan data to a
// ui::ImeTextSpan instance, and append it to |ime_text_spans_ptr|.
-void AppendUnderlineSpan(JNIEnv*,
- const JavaParamRef<jclass>&,
- jlong ime_text_spans_ptr,
- jint start,
- jint end) {
+void JNI_ImeAdapter_AppendUnderlineSpan(JNIEnv*,
+ const JavaParamRef<jclass>&,
+ jlong ime_text_spans_ptr,
+ jint start,
+ jint end) {
DCHECK_GE(start, 0);
DCHECK_GE(end, 0);
std::vector<ui::ImeTextSpan>* ime_text_spans =
diff --git a/chromium/content/browser/android/interstitial_page_delegate_android.cc b/chromium/content/browser/android/interstitial_page_delegate_android.cc
index 9da5c8146b4..81b57c0f1ce 100644
--- a/chromium/content/browser/android/interstitial_page_delegate_android.cc
+++ b/chromium/content/browser/android/interstitial_page_delegate_android.cc
@@ -82,9 +82,10 @@ void InterstitialPageDelegateAndroid::CommandReceived(
}
}
-static jlong Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jstring>& html_content) {
+static jlong JNI_InterstitialPageDelegateAndroid_Init(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jstring>& html_content) {
InterstitialPageDelegateAndroid* delegate =
new InterstitialPageDelegateAndroid(
env, obj, base::android::ConvertJavaStringToUTF8(env, html_content));
diff --git a/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.cc b/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
index fd3edd3eae7..466dc018e49 100644
--- a/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
+++ b/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
@@ -325,13 +325,13 @@ void GinJavaBridgeDispatcherHost::OnInvokeMethod(
DCHECK(routing_id != MSG_ROUTING_NONE);
scoped_refptr<GinJavaBoundObject> object = FindObject(object_id);
if (!object.get()) {
- wrapped_result->Append(base::MakeUnique<base::Value>());
+ wrapped_result->Append(std::make_unique<base::Value>());
*error_code = kGinJavaBridgeUnknownObjectId;
return;
}
scoped_refptr<GinJavaMethodInvocationHelper> result =
new GinJavaMethodInvocationHelper(
- base::MakeUnique<GinJavaBoundObjectDelegate>(object), method_name,
+ std::make_unique<GinJavaBoundObjectDelegate>(object), method_name,
arguments);
result->Init(this);
result->Invoke();
@@ -354,7 +354,7 @@ void GinJavaBridgeDispatcherHost::OnInvokeMethod(
wrapped_result->Append(
GinJavaBridgeValue::CreateObjectIDValue(returned_object_id));
} else {
- wrapped_result->Append(base::MakeUnique<base::Value>());
+ wrapped_result->Append(std::make_unique<base::Value>());
}
}
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 9838877bcc8..84eb03266fc 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
@@ -96,7 +96,7 @@ scoped_refptr<GinJavaBridgeMessageFilter> GinJavaBridgeMessageFilter::FromHost(
rph->AddFilter(filter.get());
rph->SetUserData(
kGinJavaBridgeMessageFilterKey,
- base::MakeUnique<base::UserDataAdapter<GinJavaBridgeMessageFilter>>(
+ std::make_unique<base::UserDataAdapter<GinJavaBridgeMessageFilter>>(
filter.get()));
}
return filter;
@@ -157,7 +157,7 @@ void GinJavaBridgeMessageFilter::OnInvokeMethod(
host->OnInvokeMethod(current_routing_id_, object_id, method_name, arguments,
wrapped_result, error_code);
} else {
- wrapped_result->Append(base::MakeUnique<base::Value>());
+ wrapped_result->Append(std::make_unique<base::Value>());
*error_code = kGinJavaBridgeRenderFrameDeleted;
}
}
diff --git a/chromium/content/browser/android/java/gin_java_method_invocation_helper.cc b/chromium/content/browser/android/java/gin_java_method_invocation_helper.cc
index 6c5edab76ce..4c2e33d7d82 100644
--- a/chromium/content/browser/android/java/gin_java_method_invocation_helper.cc
+++ b/chromium/content/browser/android/java/gin_java_method_invocation_helper.cc
@@ -321,7 +321,7 @@ void GinJavaMethodInvocationHelper::InvokeMethod(jobject object,
}
ScopedJavaLocalRef<jobject> scoped_java_object(env, java_object);
if (!scoped_java_object.obj()) {
- result_wrapper.Append(base::MakeUnique<base::Value>());
+ result_wrapper.Append(std::make_unique<base::Value>());
break;
}
SetObjectResult(scoped_java_object, object_->GetSafeAnnotationClass());
diff --git a/chromium/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc b/chromium/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc
index dfc96ff7c47..d6689dc6dd3 100644
--- a/chromium/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc
+++ b/chromium/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc
@@ -129,21 +129,21 @@ TEST_F(GinJavaMethodInvocationHelperTest, RetrievalOfObjectsHaveObjects) {
base::ListValue objects;
objects.AppendInteger(100);
objects.Append(GinJavaBridgeValue::CreateObjectIDValue(1));
- auto sub_list = base::MakeUnique<base::ListValue>();
+ auto sub_list = std::make_unique<base::ListValue>();
sub_list->AppendInteger(200);
sub_list->Append(GinJavaBridgeValue::CreateObjectIDValue(2));
objects.Append(std::move(sub_list));
- auto sub_dict = base::MakeUnique<base::DictionaryValue>();
+ auto sub_dict = std::make_unique<base::DictionaryValue>();
sub_dict->SetInteger("1", 300);
sub_dict->Set("2", GinJavaBridgeValue::CreateObjectIDValue(3));
objects.Append(std::move(sub_dict));
- auto sub_list_with_dict = base::MakeUnique<base::ListValue>();
- auto sub_sub_dict = base::MakeUnique<base::DictionaryValue>();
+ auto sub_list_with_dict = std::make_unique<base::ListValue>();
+ auto sub_sub_dict = std::make_unique<base::DictionaryValue>();
sub_sub_dict->Set("1", GinJavaBridgeValue::CreateObjectIDValue(4));
sub_list_with_dict->Append(std::move(sub_sub_dict));
objects.Append(std::move(sub_list_with_dict));
- auto sub_dict_with_list = base::MakeUnique<base::DictionaryValue>();
- auto sub_sub_list = base::MakeUnique<base::ListValue>();
+ auto sub_dict_with_list = std::make_unique<base::DictionaryValue>();
+ auto sub_sub_list = std::make_unique<base::ListValue>();
sub_sub_list->Append(GinJavaBridgeValue::CreateObjectIDValue(5));
sub_dict_with_list->Set("1", std::move(sub_sub_list));
objects.Append(std::move(sub_dict_with_list));
diff --git a/chromium/content/browser/android/java/gin_java_script_to_java_types_coercion.cc b/chromium/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
index a7fdc628f30..2e0a324c127 100644
--- a/chromium/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
+++ b/chromium/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
@@ -466,7 +466,7 @@ jobject CoerceJavaScriptListToArray(JNIEnv* env,
if (!result) {
return NULL;
}
- auto null_value = base::MakeUnique<base::Value>();
+ auto null_value = std::make_unique<base::Value>();
for (jsize i = 0; i < length; ++i) {
const base::Value* value_element = null_value.get();
list_value->Get(i, &value_element);
@@ -538,7 +538,7 @@ jobject CoerceJavaScriptDictionaryToArray(JNIEnv* env,
if (!result) {
return NULL;
}
- auto null_value = base::MakeUnique<base::Value>();
+ auto null_value = std::make_unique<base::Value>();
for (jsize i = 0; i < length; ++i) {
const std::string key(base::IntToString(i));
const base::Value* value_element = null_value.get();
@@ -698,7 +698,7 @@ jvalue CoerceJavaScriptValueToJavaValue(JNIEnv* env,
// Note that in all these conversions, the relevant field of the jvalue must
// always be explicitly set, as jvalue does not initialize its fields.
- switch (value->GetType()) {
+ switch (value->type()) {
case base::Value::Type::INTEGER:
return CoerceJavaScriptIntegerToJavaValue(
env, value, target_type, coerce_to_string, error);
diff --git a/chromium/content/browser/android/launcher_thread.h b/chromium/content/browser/android/launcher_thread.h
index a64ebd8e81a..02233fc2686 100644
--- a/chromium/content/browser/android/launcher_thread.h
+++ b/chromium/content/browser/android/launcher_thread.h
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#ifndef CONTENT_BROWSER_ANDROID_LAUNCHER_THREAD_H
+#define CONTENT_BROWSER_ANDROID_LAUNCHER_THREAD_H
+
#include "base/android/java_handler_thread.h"
#include "base/lazy_instance.h"
@@ -30,3 +33,5 @@ class LauncherThread {
} // namespace android
} // namespace content
+
+#endif // CONTENT_BROWSER_ANDROID_LAUNCHER_THREAD_H
diff --git a/chromium/content/browser/android/load_url_params.cc b/chromium/content/browser/android/load_url_params.cc
index bd9f814f66b..2a1cf646b14 100644
--- a/chromium/content/browser/android/load_url_params.cc
+++ b/chromium/content/browser/android/load_url_params.cc
@@ -14,9 +14,9 @@ using base::android::JavaParamRef;
namespace content {
-jboolean IsDataScheme(JNIEnv* env,
- const JavaParamRef<jclass>& clazz,
- const JavaParamRef<jstring>& jurl) {
+jboolean JNI_LoadUrlParams_IsDataScheme(JNIEnv* env,
+ const JavaParamRef<jclass>& clazz,
+ const JavaParamRef<jstring>& jurl) {
GURL url(base::android::ConvertJavaStringToUTF8(env, jurl));
return url.SchemeIs(url::kDataScheme);
}
diff --git a/chromium/content/browser/android/overscroll_controller_android.cc b/chromium/content/browser/android/overscroll_controller_android.cc
index 939d5e260ee..e34ff4e244d 100644
--- a/chromium/content/browser/android/overscroll_controller_android.cc
+++ b/chromium/content/browser/android/overscroll_controller_android.cc
@@ -81,7 +81,7 @@ std::unique_ptr<OverscrollGlow> CreateGlowEffect(OverscrollGlowClient* client,
return nullptr;
}
- return base::MakeUnique<OverscrollGlow>(client);
+ return std::make_unique<OverscrollGlow>(client);
}
std::unique_ptr<OverscrollRefresh> CreateRefreshEffect(
@@ -91,7 +91,7 @@ std::unique_ptr<OverscrollRefresh> CreateRefreshEffect(
return nullptr;
}
- return base::MakeUnique<OverscrollRefresh>(overscroll_refresh_handler);
+ return std::make_unique<OverscrollRefresh>(overscroll_refresh_handler);
}
} // namespace
@@ -228,9 +228,9 @@ void OverscrollControllerAndroid::OnOverscrolled(
return;
if (refresh_effect_) {
- if (params.scroll_boundary_behavior.y !=
- cc::ScrollBoundaryBehavior::ScrollBoundaryBehaviorType::
- kScrollBoundaryBehaviorTypeAuto)
+ if (params.overscroll_behavior.y !=
+ cc::OverscrollBehavior::OverscrollBehaviorType::
+ kOverscrollBehaviorTypeAuto)
refresh_effect_->Reset();
else
refresh_effect_->OnOverscrolled();
@@ -255,17 +255,17 @@ void OverscrollControllerAndroid::OnOverscrolled(
gfx::Vector2dF overscroll_location = gfx::ScaleVector2d(
params.causal_event_viewport_point.OffsetFromOrigin(), scale_factor);
- if (params.scroll_boundary_behavior.x ==
- cc::ScrollBoundaryBehavior::ScrollBoundaryBehaviorType::
- kScrollBoundaryBehaviorTypeNone) {
+ if (params.overscroll_behavior.x ==
+ cc::OverscrollBehavior::OverscrollBehaviorType::
+ kOverscrollBehaviorTypeNone) {
accumulated_overscroll.set_x(0);
latest_overscroll_delta.set_x(0);
current_fling_velocity.set_x(0);
}
- if (params.scroll_boundary_behavior.y ==
- cc::ScrollBoundaryBehavior::ScrollBoundaryBehaviorType::
- kScrollBoundaryBehaviorTypeNone) {
+ if (params.overscroll_behavior.y ==
+ cc::OverscrollBehavior::OverscrollBehaviorType::
+ kOverscrollBehaviorTypeNone) {
accumulated_overscroll.set_y(0);
latest_overscroll_delta.set_y(0);
current_fling_velocity.set_y(0);
diff --git a/chromium/content/browser/android/overscroll_controller_android.h b/chromium/content/browser/android/overscroll_controller_android.h
index f620c5fd6d1..d3def7a5443 100644
--- a/chromium/content/browser/android/overscroll_controller_android.h
+++ b/chromium/content/browser/android/overscroll_controller_android.h
@@ -11,7 +11,7 @@
#include "base/macros.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
#include "ui/android/overscroll_glow.h"
#include "ui/android/overscroll_refresh.h"
#include "ui/gfx/geometry/vector2d_f.h"
diff --git a/chromium/content/browser/android/overscroll_controller_android_unittest.cc b/chromium/content/browser/android/overscroll_controller_android_unittest.cc
index 7db012376b3..21b2012a97b 100644
--- a/chromium/content/browser/android/overscroll_controller_android_unittest.cc
+++ b/chromium/content/browser/android/overscroll_controller_android_unittest.cc
@@ -71,9 +71,9 @@ class MockRefresh : public OverscrollRefresh {
class OverscrollControllerAndroidUnitTest : public testing::Test {
public:
OverscrollControllerAndroidUnitTest() {
- std::unique_ptr<MockGlow> glow_ptr = base::MakeUnique<MockGlow>();
- std::unique_ptr<MockRefresh> refresh_ptr = base::MakeUnique<MockRefresh>();
- compositor_ = base::MakeUnique<MockCompositor>();
+ std::unique_ptr<MockGlow> glow_ptr = std::make_unique<MockGlow>();
+ std::unique_ptr<MockRefresh> refresh_ptr = std::make_unique<MockRefresh>();
+ compositor_ = std::make_unique<MockCompositor>();
glow_ = glow_ptr.get();
refresh_ = refresh_ptr.get();
controller_ = OverscrollControllerAndroid::CreateForTests(
@@ -97,10 +97,10 @@ class OverscrollControllerAndroidUnitTest : public testing::Test {
};
TEST_F(OverscrollControllerAndroidUnitTest,
- ScrollBoundaryBehaviorAutoAllowsGlowAndNavigation) {
+ OverscrollBehaviorAutoAllowsGlowAndNavigation) {
ui::DidOverscrollParams params = CreateVerticalOverscrollParams();
- params.scroll_boundary_behavior.y = cc::ScrollBoundaryBehavior::
- ScrollBoundaryBehaviorType::kScrollBoundaryBehaviorTypeAuto;
+ params.overscroll_behavior.y = cc::OverscrollBehavior::
+ OverscrollBehaviorType::kOverscrollBehaviorTypeAuto;
EXPECT_CALL(*refresh_, OnOverscrolled());
EXPECT_CALL(*refresh_, IsActive()).WillOnce(Return(true));
@@ -112,10 +112,10 @@ TEST_F(OverscrollControllerAndroidUnitTest,
}
TEST_F(OverscrollControllerAndroidUnitTest,
- ScrollBoundaryBehaviorContainPreventsNavigation) {
+ OverscrollBehaviorContainPreventsNavigation) {
ui::DidOverscrollParams params = CreateVerticalOverscrollParams();
- params.scroll_boundary_behavior.y = cc::ScrollBoundaryBehavior::
- ScrollBoundaryBehaviorType::kScrollBoundaryBehaviorTypeContain;
+ params.overscroll_behavior.y = cc::OverscrollBehavior::
+ OverscrollBehaviorType::kOverscrollBehaviorTypeContain;
EXPECT_CALL(*refresh_, OnOverscrolled()).Times(0);
EXPECT_CALL(*refresh_, Reset());
@@ -130,10 +130,10 @@ TEST_F(OverscrollControllerAndroidUnitTest,
testing::Mock::VerifyAndClearExpectations(glow_);
// Test that the "contain" set on x-axis would not affect navigation.
- params.scroll_boundary_behavior.y = cc::ScrollBoundaryBehavior::
- ScrollBoundaryBehaviorType::kScrollBoundaryBehaviorTypeAuto;
- params.scroll_boundary_behavior.x = cc::ScrollBoundaryBehavior::
- ScrollBoundaryBehaviorType::kScrollBoundaryBehaviorTypeContain;
+ params.overscroll_behavior.y = cc::OverscrollBehavior::
+ OverscrollBehaviorType::kOverscrollBehaviorTypeAuto;
+ params.overscroll_behavior.x = cc::OverscrollBehavior::
+ OverscrollBehaviorType::kOverscrollBehaviorTypeContain;
EXPECT_CALL(*refresh_, OnOverscrolled());
EXPECT_CALL(*refresh_, Reset()).Times(0);
@@ -147,10 +147,10 @@ TEST_F(OverscrollControllerAndroidUnitTest,
}
TEST_F(OverscrollControllerAndroidUnitTest,
- ScrollBoundaryBehaviorNonePreventsNavigationAndGlow) {
+ OverscrollBehaviorNonePreventsNavigationAndGlow) {
ui::DidOverscrollParams params = CreateVerticalOverscrollParams();
- params.scroll_boundary_behavior.y = cc::ScrollBoundaryBehavior::
- ScrollBoundaryBehaviorType::kScrollBoundaryBehaviorTypeNone;
+ params.overscroll_behavior.y = cc::OverscrollBehavior::
+ OverscrollBehaviorType::kOverscrollBehaviorTypeNone;
EXPECT_CALL(*refresh_, OnOverscrolled()).Times(0);
EXPECT_CALL(*refresh_, Reset());
@@ -184,8 +184,8 @@ TEST_F(OverscrollControllerAndroidUnitTest,
TEST_F(OverscrollControllerAndroidUnitTest,
ConsumedUpdateDoesNotResetEnabledRefresh) {
ui::DidOverscrollParams params = CreateVerticalOverscrollParams();
- params.scroll_boundary_behavior.y = cc::ScrollBoundaryBehavior::
- ScrollBoundaryBehaviorType::kScrollBoundaryBehaviorTypeAuto;
+ params.overscroll_behavior.y = cc::OverscrollBehavior::
+ OverscrollBehaviorType::kOverscrollBehaviorTypeAuto;
EXPECT_CALL(*refresh_, OnOverscrolled());
EXPECT_CALL(*refresh_, IsActive()).WillOnce(Return(true));
@@ -207,4 +207,4 @@ TEST_F(OverscrollControllerAndroidUnitTest,
} // namespace
-} // namespace content \ No newline at end of file
+} // namespace content
diff --git a/chromium/content/browser/android/popup_zoomer.cc b/chromium/content/browser/android/popup_zoomer.cc
index 8f1357e1e93..8d7e2da930c 100644
--- a/chromium/content/browser/android/popup_zoomer.cc
+++ b/chromium/content/browser/android/popup_zoomer.cc
@@ -21,16 +21,18 @@ namespace content {
namespace {
-ScopedJavaLocalRef<jobject> CreateJavaRect(JNIEnv* env, const gfx::Rect& rect) {
+ScopedJavaLocalRef<jobject> JNI_PopupZoomer_CreateJavaRect(
+ JNIEnv* env,
+ const gfx::Rect& rect) {
return ScopedJavaLocalRef<jobject>(Java_PopupZoomer_createRect(
env, rect.x(), rect.y(), rect.right(), rect.bottom()));
}
} // namespace
-jlong Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents) {
+jlong JNI_PopupZoomer_Init(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& jweb_contents) {
WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents);
DCHECK(web_contents);
@@ -71,7 +73,8 @@ void PopupZoomer::ShowPopup(const gfx::Rect& rect_pixels,
if (obj.is_null())
return;
- ScopedJavaLocalRef<jobject> rect_object(CreateJavaRect(env, rect_pixels));
+ ScopedJavaLocalRef<jobject> rect_object(
+ JNI_PopupZoomer_CreateJavaRect(env, rect_pixels));
ScopedJavaLocalRef<jobject> java_bitmap =
gfx::ConvertToJavaBitmap(&zoomed_bitmap);
diff --git a/chromium/content/browser/android/selection_popup_controller.cc b/chromium/content/browser/android/selection_popup_controller.cc
index 983da189b54..8adc372f9c2 100644
--- a/chromium/content/browser/android/selection_popup_controller.cc
+++ b/chromium/content/browser/android/selection_popup_controller.cc
@@ -24,9 +24,10 @@ using blink::WebContextMenuData;
namespace content {
-void Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents) {
+void JNI_SelectionPopupController_Init(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& jweb_contents) {
WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents);
DCHECK(web_contents);
@@ -133,12 +134,11 @@ bool SelectionPopupController::ShowSelectionMenu(
params.source_type == ui::MENU_SOURCE_STYLUS;
const bool from_selection_adjustment =
- params.source_type == ui::MENU_SOURCE_ADJUST_SELECTION;
- const bool from_selection_reset =
+ params.source_type == ui::MENU_SOURCE_ADJUST_SELECTION ||
params.source_type == ui::MENU_SOURCE_ADJUST_SELECTION_RESET;
// If source_type is not in the list then return.
- if (!from_touch && !from_selection_adjustment && !from_selection_reset)
+ if (!from_touch && !from_selection_adjustment)
return false;
// Don't show paste pop-up for non-editable textarea.
@@ -160,8 +160,8 @@ bool SelectionPopupController::ShowSelectionMenu(
env, obj, params.selection_rect.x(), params.selection_rect.y(),
params.selection_rect.right(),
params.selection_rect.bottom() + handle_height, params.is_editable,
- is_password_type, jselected_text, can_select_all, can_edit_richly,
- should_suggest, from_selection_adjustment);
+ is_password_type, jselected_text, params.selection_start_offset,
+ can_select_all, can_edit_richly, should_suggest, params.source_type);
return true;
}
diff --git a/chromium/content/browser/android/smart_selection_client.cc b/chromium/content/browser/android/smart_selection_client.cc
index 95497ef141e..ad96d4155e6 100644
--- a/chromium/content/browser/android/smart_selection_client.cc
+++ b/chromium/content/browser/android/smart_selection_client.cc
@@ -35,9 +35,10 @@ class UserData : public base::SupportsUserData::Data {
};
}
-jlong Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents) {
+jlong JNI_SmartSelectionClient_Init(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& jweb_contents) {
WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents);
CHECK(web_contents)
<< "A SmartSelectionClient should be created with a valid WebContents.";
@@ -55,7 +56,7 @@ SmartSelectionClient::SmartSelectionClient(
weak_ptr_factory_(this) {
DCHECK(!web_contents_->GetUserData(kSmartSelectionClientUDKey));
web_contents_->SetUserData(kSmartSelectionClientUDKey,
- base::MakeUnique<UserData>(this));
+ std::make_unique<UserData>(this));
}
SmartSelectionClient::~SmartSelectionClient() {
diff --git a/chromium/content/browser/android/synchronous_compositor_browser_filter.cc b/chromium/content/browser/android/synchronous_compositor_browser_filter.cc
index 3352a64d9fc..2faac6f628f 100644
--- a/chromium/content/browser/android/synchronous_compositor_browser_filter.cc
+++ b/chromium/content/browser/android/synchronous_compositor_browser_filter.cc
@@ -84,7 +84,7 @@ bool SynchronousCompositorBrowserFilter::ReceiveFrame(
future_map_.erase(itr);
}
- auto frame_ptr = base::MakeUnique<SynchronousCompositor::Frame>();
+ auto frame_ptr = std::make_unique<SynchronousCompositor::Frame>();
frame_ptr->layer_tree_frame_sink_id = std::get<0>(param);
base::Optional<viz::CompositorFrame>& compositor_frame = std::get<1>(param);
if (compositor_frame) {
diff --git a/chromium/content/browser/android/synchronous_compositor_host.cc b/chromium/content/browser/android/synchronous_compositor_host.cc
index e927367760a..974571de854 100644
--- a/chromium/content/browser/android/synchronous_compositor_host.cc
+++ b/chromium/content/browser/android/synchronous_compositor_host.cc
@@ -89,7 +89,7 @@ SynchronousCompositorHost::DemandDrawHwAsync(
scoped_refptr<FrameFuture> frame_future = new FrameFuture();
if (compute_scroll_needs_synchronous_draw_) {
compute_scroll_needs_synchronous_draw_ = false;
- auto frame_ptr = base::MakeUnique<Frame>();
+ auto frame_ptr = std::make_unique<Frame>();
*frame_ptr = DemandDrawHw(viewport_size, viewport_rect_for_tile_priority,
transform_for_tile_priority);
frame_future->SetFrame(std::move(frame_ptr));
diff --git a/chromium/content/browser/android/synchronous_compositor_host.h b/chromium/content/browser/android/synchronous_compositor_host.h
index 45a40711030..0bd21d86690 100644
--- a/chromium/content/browser/android/synchronous_compositor_host.h
+++ b/chromium/content/browser/android/synchronous_compositor_host.h
@@ -15,8 +15,8 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "components/viz/common/quads/compositor_frame.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/public/browser/android/synchronous_compositor.h"
+#include "content/public/common/input_event_ack_state.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/geometry/size_f.h"
diff --git a/chromium/content/browser/android/text_suggestion_host_android.cc b/chromium/content/browser/android/text_suggestion_host_android.cc
index 999aa4e1927..a49d1295d31 100644
--- a/chromium/content/browser/android/text_suggestion_host_android.cc
+++ b/chromium/content/browser/android/text_suggestion_host_android.cc
@@ -34,9 +34,9 @@ const size_t kMaxNumberOfSuggestions = 5;
} // namespace
-jlong Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents) {
+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 =
diff --git a/chromium/content/browser/android/text_suggestion_host_mojo_impl_android.cc b/chromium/content/browser/android/text_suggestion_host_mojo_impl_android.cc
index 9105c2a4753..c16d8c0cc45 100644
--- a/chromium/content/browser/android/text_suggestion_host_mojo_impl_android.cc
+++ b/chromium/content/browser/android/text_suggestion_host_mojo_impl_android.cc
@@ -18,7 +18,7 @@ void TextSuggestionHostMojoImplAndroid::Create(
TextSuggestionHostAndroid* text_suggestion_host,
blink::mojom::TextSuggestionHostRequest request) {
mojo::MakeStrongBinding(
- base::MakeUnique<TextSuggestionHostMojoImplAndroid>(text_suggestion_host),
+ std::make_unique<TextSuggestionHostMojoImplAndroid>(text_suggestion_host),
std::move(request));
}
diff --git a/chromium/content/browser/android/tracing_controller_android.cc b/chromium/content/browser/android/tracing_controller_android.cc
index b2335d52f1e..9a03da8661a 100644
--- a/chromium/content/browser/android/tracing_controller_android.cc
+++ b/chromium/content/browser/android/tracing_controller_android.cc
@@ -19,7 +19,9 @@ using base::android::ScopedJavaLocalRef;
namespace content {
-static jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj) {
+static jlong JNI_TracingControllerAndroid_Init(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
TracingControllerAndroid* profiler = new TracingControllerAndroid(env, obj);
return reinterpret_cast<intptr_t>(profiler);
}
@@ -110,7 +112,8 @@ void TracingControllerAndroid::OnKnownCategoriesReceived(
LOG(WARNING) << "{\"traceCategoriesList\": " << received_category_list << "}";
}
-static ScopedJavaLocalRef<jstring> GetDefaultCategories(
+static ScopedJavaLocalRef<jstring>
+JNI_TracingControllerAndroid_GetDefaultCategories(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
base::trace_event::TraceConfig trace_config;
diff --git a/chromium/content/browser/android/web_contents_observer_proxy.cc b/chromium/content/browser/android/web_contents_observer_proxy.cc
index 5f4191ddba8..a4148564636 100644
--- a/chromium/content/browser/android/web_contents_observer_proxy.cc
+++ b/chromium/content/browser/android/web_contents_observer_proxy.cc
@@ -42,9 +42,10 @@ WebContentsObserverProxy::WebContentsObserverProxy(JNIEnv* env,
WebContentsObserverProxy::~WebContentsObserverProxy() {
}
-jlong Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& java_web_contents) {
+jlong JNI_WebContentsObserverProxy_Init(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& java_web_contents) {
WebContents* web_contents =
WebContents::FromJavaWebContents(java_web_contents);
CHECK(web_contents);
diff --git a/chromium/content/browser/appcache/OWNERS b/chromium/content/browser/appcache/OWNERS
index 92b1943e320..21ddbb8551d 100644
--- a/chromium/content/browser/appcache/OWNERS
+++ b/chromium/content/browser/appcache/OWNERS
@@ -1,3 +1,7 @@
+pwnall@chromium.org
+jsbell@chromium.org
+
+# OOO until this comment is removed.
michaeln@chromium.org
# TEAM: storage-dev@chromium.org
diff --git a/chromium/content/browser/appcache/appcache.cc b/chromium/content/browser/appcache/appcache.cc
index 0bd1f3096fb..061c95de799 100644
--- a/chromium/content/browser/appcache/appcache.cc
+++ b/chromium/content/browser/appcache/appcache.cc
@@ -10,7 +10,6 @@
#include "base/logging.h"
#include "base/stl_util.h"
-#include "content/browser/appcache/appcache_executable_handler.h"
#include "content/browser/appcache/appcache_group.h"
#include "content/browser/appcache/appcache_host.h"
#include "content/browser/appcache/appcache_storage.h"
@@ -86,37 +85,6 @@ const AppCacheEntry* AppCache::GetEntryAndUrlWithResponseId(
return nullptr;
}
-AppCacheExecutableHandler* AppCache::GetExecutableHandler(int64_t response_id) {
- HandlerMap::const_iterator found = executable_handlers_.find(response_id);
- if (found != executable_handlers_.end())
- return found->second.get();
- return nullptr;
-}
-
-AppCacheExecutableHandler* AppCache::GetOrCreateExecutableHandler(
- int64_t response_id,
- net::IOBuffer* handler_source) {
- AppCacheExecutableHandler* handler = GetExecutableHandler(response_id);
- if (handler)
- return handler;
-
- GURL handler_url;
- const AppCacheEntry* entry = GetEntryAndUrlWithResponseId(
- response_id, &handler_url);
- if (!entry || !entry->IsExecutable())
- return nullptr;
-
- DCHECK(storage_->service()->handler_factory());
- std::unique_ptr<AppCacheExecutableHandler> own_ptr =
- storage_->service()->handler_factory()->CreateHandler(handler_url,
- handler_source);
- handler = own_ptr.get();
- if (!handler)
- return nullptr;
- executable_handlers_[response_id] = std::move(own_ptr);
- return handler;
-}
-
GURL AppCache::GetNamespaceEntryUrl(const AppCacheNamespaceVector& namespaces,
const GURL& namespace_url) const {
size_t count = namespaces.size();
diff --git a/chromium/content/browser/appcache/appcache.h b/chromium/content/browser/appcache/appcache.h
index 1deb90b3355..34644e20ecb 100644
--- a/chromium/content/browser/appcache/appcache.h
+++ b/chromium/content/browser/appcache/appcache.h
@@ -22,14 +22,9 @@
#include "content/common/content_export.h"
#include "url/gurl.h"
-namespace net {
-class IOBuffer;
-}
-
namespace content {
FORWARD_DECLARE_TEST(AppCacheTest, InitializeWithManifest);
FORWARD_DECLARE_TEST(AppCacheTest, ToFromDatabaseRecords);
-class AppCacheExecutableHandler;
class AppCacheGroup;
class AppCacheHost;
class AppCacheStorage;
@@ -75,16 +70,6 @@ class CONTENT_EXPORT AppCache
GURL* optional_url);
const EntryMap& entries() const { return entries_; }
- // The AppCache owns the collection of executable handlers that have
- // been started for this instance. The getter looks up an existing
- // handler returning null if not found, the GetOrCreate method will
- // cons one up if not found.
- // Do not store the returned ptrs, they're owned by 'this'.
- AppCacheExecutableHandler* GetExecutableHandler(int64_t response_id);
- AppCacheExecutableHandler* GetOrCreateExecutableHandler(
- int64_t response_id,
- net::IOBuffer* handler_source);
-
// Returns the URL of the resource used as entry for 'namespace_url'.
GURL GetFallbackEntryUrl(const GURL& namespace_url) const {
return GetNamespaceEntryUrl(fallback_namespaces_, namespace_url);
@@ -199,10 +184,6 @@ class CONTENT_EXPORT AppCache
int64_t cache_size_;
- typedef std::map<int64_t, std::unique_ptr<AppCacheExecutableHandler>>
- HandlerMap;
- HandlerMap executable_handlers_;
-
// to notify storage when cache is deleted
AppCacheStorage* storage_;
diff --git a/chromium/content/browser/appcache/appcache_backend_impl.cc b/chromium/content/browser/appcache/appcache_backend_impl.cc
index 0c30e74dbaa..1fe4457a272 100644
--- a/chromium/content/browser/appcache/appcache_backend_impl.cc
+++ b/chromium/content/browser/appcache/appcache_backend_impl.cc
@@ -14,10 +14,7 @@
namespace content {
AppCacheBackendImpl::AppCacheBackendImpl()
- : service_(NULL),
- frontend_(NULL),
- process_id_(0) {
-}
+ : service_(nullptr), frontend_(nullptr), process_id_(0) {}
AppCacheBackendImpl::~AppCacheBackendImpl() {
hosts_.clear();
@@ -39,7 +36,7 @@ bool AppCacheBackendImpl::RegisterHost(int id) {
if (GetHost(id))
return false;
- hosts_[id] = base::MakeUnique<AppCacheHost>(id, frontend_, service_);
+ hosts_[id] = std::make_unique<AppCacheHost>(id, frontend_, service_);
return true;
}
@@ -70,15 +67,6 @@ bool AppCacheBackendImpl::SelectCache(
manifest_url);
}
-bool AppCacheBackendImpl::SelectCacheForWorker(
- int host_id, int parent_process_id, int parent_host_id) {
- AppCacheHost* host = GetHost(host_id);
- if (!host)
- return false;
-
- return host->SelectCacheForWorker(parent_process_id, parent_host_id);
-}
-
bool AppCacheBackendImpl::SelectCacheForSharedWorker(int host_id,
int64_t appcache_id) {
AppCacheHost* host = GetHost(host_id);
@@ -152,7 +140,7 @@ std::unique_ptr<AppCacheHost> AppCacheBackendImpl::TransferHostOut(
std::unique_ptr<AppCacheHost> transferree = std::move(found->second);
// Put a new empty host in its place.
- found->second = base::MakeUnique<AppCacheHost>(host_id, frontend_, service_);
+ found->second = std::make_unique<AppCacheHost>(host_id, frontend_, service_);
// We give up ownership.
transferree->PrepareForTransfer();
diff --git a/chromium/content/browser/appcache/appcache_backend_impl.h b/chromium/content/browser/appcache/appcache_backend_impl.h
index bb89020120e..96ee706acfb 100644
--- a/chromium/content/browser/appcache/appcache_backend_impl.h
+++ b/chromium/content/browser/appcache/appcache_backend_impl.h
@@ -38,8 +38,6 @@ class CONTENT_EXPORT AppCacheBackendImpl {
const GURL& manifest_url);
void GetResourceList(
int host_id, std::vector<AppCacheResourceInfo>* resource_infos);
- bool SelectCacheForWorker(int host_id, int parent_process_id,
- int parent_host_id);
bool SelectCacheForSharedWorker(int host_id, int64_t appcache_id);
bool MarkAsForeignEntry(int host_id,
const GURL& document_url,
diff --git a/chromium/content/browser/appcache/appcache_browsertest.cc b/chromium/content/browser/appcache/appcache_browsertest.cc
index a89478e63ff..676460e5790 100644
--- a/chromium/content/browser/appcache/appcache_browsertest.cc
+++ b/chromium/content/browser/appcache/appcache_browsertest.cc
@@ -3,12 +3,11 @@
// found in the LICENSE file.
#include <stdint.h>
-#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/appcache/appcache_subresource_url_factory.h"
#include "content/public/common/content_features.h"
-#include "content/public/common/content_switches.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"
@@ -25,7 +24,11 @@ namespace content {
// test the AppCache code in that mode.
class AppCacheNetworkServiceBrowserTest : public ContentBrowserTest {
public:
- AppCacheNetworkServiceBrowserTest() {}
+ AppCacheNetworkServiceBrowserTest() {
+ scoped_feature_list_.InitAndEnableFeature(features::kNetworkService);
+ }
+
+ ~AppCacheNetworkServiceBrowserTest() override {}
// Handler to count the number of requests.
std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
@@ -41,15 +44,12 @@ class AppCacheNetworkServiceBrowserTest : public ContentBrowserTest {
int request_count() const { return request_count_; }
- protected:
- void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitchASCII(switches::kEnableFeatures,
- features::kNetworkService.name);
- }
-
private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
// Tracks the number of requests.
int request_count_ = 0;
+
DISALLOW_COPY_AND_ASSIGN(AppCacheNetworkServiceBrowserTest);
};
diff --git a/chromium/content/browser/appcache/appcache_database.cc b/chromium/content/browser/appcache/appcache_database.cc
index d80c5536a14..d0a87ed0707 100644
--- a/chromium/content/browser/appcache/appcache_database.cc
+++ b/chromium/content/browser/appcache/appcache_database.cc
@@ -177,9 +177,6 @@ bool CreateIndex(sql::Connection* db, const IndexInfo& info) {
}
std::string GetActiveExperimentFlags() {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- kEnableExecutableHandlers))
- return std::string("executableHandlersEnabled");
return std::string();
}
@@ -762,19 +759,10 @@ bool AppCacheDatabase::InsertNamespace(
" (cache_id, origin, type, namespace_url, target_url, is_pattern)"
" VALUES (?, ?, ?, ?, ?, ?)";
- // Note: quick and dirty storage for the 'executable' bit w/o changing
- // schemas, we use the high bit of 'type' field.
- int type_with_executable_bit = record->namespace_.type;
- if (record->namespace_.is_executable) {
- type_with_executable_bit |= 0x8000000;
- DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- kEnableExecutableHandlers));
- }
-
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindInt64(0, record->cache_id);
statement.BindString(1, record->origin.spec());
- statement.BindInt(2, type_with_executable_bit);
+ statement.BindInt(2, record->namespace_.type);
statement.BindString(3, record->namespace_.namespace_url.spec());
statement.BindString(4, record->namespace_.target_url.spec());
statement.BindBool(5, record->namespace_.is_pattern);
@@ -1035,20 +1023,14 @@ void AppCacheDatabase::ReadNamespaceRecord(
const sql::Statement* statement, NamespaceRecord* record) {
record->cache_id = statement->ColumnInt64(0);
record->origin = GURL(statement->ColumnString(1));
- int type_with_executable_bit = statement->ColumnInt(2);
+ record->namespace_.type =
+ static_cast<AppCacheNamespaceType>(statement->ColumnInt(2));
record->namespace_.namespace_url = GURL(statement->ColumnString(3));
record->namespace_.target_url = GURL(statement->ColumnString(4));
record->namespace_.is_pattern = statement->ColumnBool(5);
-
- // Note: quick and dirty storage for the 'executable' bit w/o changing
- // schemas, we use the high bit of 'type' field.
- record->namespace_.type = static_cast<AppCacheNamespaceType>
- (type_with_executable_bit & 0x7ffffff);
- record->namespace_.is_executable =
- (type_with_executable_bit & 0x80000000) != 0;
- DCHECK(!record->namespace_.is_executable ||
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- kEnableExecutableHandlers));
+ DCHECK(record->namespace_.type == APPCACHE_FALLBACK_NAMESPACE ||
+ record->namespace_.type == APPCACHE_INTERCEPT_NAMESPACE);
+ // The APPCACHE_NETWORK_NAMESPACE are stored as OnlineWhiteListRecords.
}
void AppCacheDatabase::ReadOnlineWhiteListRecord(
diff --git a/chromium/content/browser/appcache/appcache_disk_cache.cc b/chromium/content/browser/appcache/appcache_disk_cache.cc
index 66dba6fc372..6b390ed2583 100644
--- a/chromium/content/browser/appcache/appcache_disk_cache.cc
+++ b/chromium/content/browser/appcache/appcache_disk_cache.cc
@@ -30,9 +30,7 @@ class AppCacheDiskCache::CreateBackendCallbackShim
: appcache_diskcache_(object) {
}
- void Cancel() {
- appcache_diskcache_ = NULL;
- }
+ void Cancel() { appcache_diskcache_ = nullptr; }
void Callback(int rv) {
if (appcache_diskcache_)
@@ -101,9 +99,9 @@ class AppCacheDiskCache::EntryImpl : public Entry {
}
void Abandon() {
- owner_ = NULL;
+ owner_ = nullptr;
disk_cache_entry_->Close();
- disk_cache_entry_ = NULL;
+ disk_cache_entry_ = nullptr;
}
private:
@@ -240,7 +238,7 @@ void AppCacheDiskCache::Disable() {
if (create_backend_callback_.get()) {
create_backend_callback_->Cancel();
- create_backend_callback_ = NULL;
+ create_backend_callback_ = nullptr;
OnCreateBackendComplete(net::ERR_ABORTED);
}
@@ -302,7 +300,7 @@ int AppCacheDiskCache::DoomEntry(int64_t key,
return net::ERR_ABORTED;
if (is_initializing_or_waiting_to_initialize()) {
- pending_calls_.push_back(PendingCall(DOOM, key, NULL, callback));
+ pending_calls_.push_back(PendingCall(DOOM, key, nullptr, callback));
return net::ERR_IO_PENDING;
}
@@ -320,10 +318,7 @@ AppCacheDiskCache::AppCacheDiskCache(bool use_simple_cache)
weak_factory_(this) {}
AppCacheDiskCache::PendingCall::PendingCall()
- : call_type(CREATE),
- key(0),
- entry(NULL) {
-}
+ : call_type(CREATE), key(0), entry(nullptr) {}
AppCacheDiskCache::PendingCall::PendingCall(
PendingCallType call_type,
@@ -350,7 +345,7 @@ int AppCacheDiskCache::Init(net::CacheType cache_type,
cache_type,
use_simple_cache_ ? net::CACHE_BACKEND_SIMPLE
: net::CACHE_BACKEND_DEFAULT,
- cache_directory, cache_size, force, NULL,
+ cache_directory, cache_size, force, nullptr,
&(create_backend_callback_->backend_ptr_),
std::move(post_cleanup_callback),
base::Bind(&CreateBackendCallbackShim::Callback,
@@ -366,7 +361,7 @@ void AppCacheDiskCache::OnCreateBackendComplete(int rv) {
if (rv == net::OK) {
disk_cache_ = std::move(create_backend_callback_->backend_ptr_);
}
- create_backend_callback_ = NULL;
+ create_backend_callback_ = nullptr;
// Invoke our clients callback function.
if (!init_callback_.is_null()) {
diff --git a/chromium/content/browser/appcache/appcache_disk_cache_unittest.cc b/chromium/content/browser/appcache/appcache_disk_cache_unittest.cc
index f8ef08c912c..61857e2eb9c 100644
--- a/chromium/content/browser/appcache/appcache_disk_cache_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_disk_cache_unittest.cc
@@ -50,7 +50,7 @@ class AppCacheDiskCacheTest : public testing::Test {
};
TEST_F(AppCacheDiskCacheTest, DisablePriorToInitCompletion) {
- AppCacheDiskCache::Entry* entry = NULL;
+ AppCacheDiskCache::Entry* entry = nullptr;
// Create an instance and start it initializing, queue up
// one of each kind of "entry" function.
@@ -69,7 +69,7 @@ TEST_F(AppCacheDiskCacheTest, DisablePriorToInitCompletion) {
FlushCacheTasks();
- EXPECT_EQ(NULL, entry);
+ EXPECT_EQ(nullptr, entry);
EXPECT_EQ(4u, completion_results_.size());
for (std::vector<int>::const_iterator iter = completion_results_.begin();
iter < completion_results_.end(); ++iter) {
@@ -105,7 +105,7 @@ TEST_F(AppCacheDiskCacheTest, DisableAfterInitted) {
// Methods should return immediately when disabled and not invoke
// the callback at all.
- AppCacheDiskCache::Entry* entry = NULL;
+ AppCacheDiskCache::Entry* entry = nullptr;
completion_results_.clear();
EXPECT_EQ(net::ERR_ABORTED,
disk_cache->CreateEntry(1, &entry, completion_callback_));
@@ -137,8 +137,8 @@ TEST_F(AppCacheDiskCacheTest, DISABLED_DisableWithEntriesOpen) {
// and we do have expectations about that.
// Create/open some entries.
- AppCacheDiskCache::Entry* entry1 = NULL;
- AppCacheDiskCache::Entry* entry2 = NULL;
+ AppCacheDiskCache::Entry* entry1 = nullptr;
+ AppCacheDiskCache::Entry* entry2 = nullptr;
disk_cache->CreateEntry(1, &entry1, completion_callback_);
disk_cache->CreateEntry(2, &entry2, completion_callback_);
FlushCacheTasks();
@@ -167,7 +167,7 @@ TEST_F(AppCacheDiskCacheTest, DISABLED_DisableWithEntriesOpen) {
EXPECT_TRUE(base::DeleteFile(directory_.GetPath(), true));
EXPECT_FALSE(base::DirectoryExists(directory_.GetPath()));
- disk_cache.reset(NULL);
+ disk_cache.reset(nullptr);
// Also, new IO operations should fail immediately.
EXPECT_EQ(
diff --git a/chromium/content/browser/appcache/appcache_dispatcher_host.cc b/chromium/content/browser/appcache/appcache_dispatcher_host.cc
index 2aa5137dd2b..86889c5b465 100644
--- a/chromium/content/browser/appcache/appcache_dispatcher_host.cc
+++ b/chromium/content/browser/appcache/appcache_dispatcher_host.cc
@@ -41,8 +41,6 @@ bool AppCacheDispatcherHost::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(AppCacheHostMsg_SetSpawningHostId, OnSetSpawningHostId)
IPC_MESSAGE_HANDLER(AppCacheHostMsg_GetResourceList, OnGetResourceList)
IPC_MESSAGE_HANDLER(AppCacheHostMsg_SelectCache, OnSelectCache)
- IPC_MESSAGE_HANDLER(AppCacheHostMsg_SelectCacheForWorker,
- OnSelectCacheForWorker)
IPC_MESSAGE_HANDLER(AppCacheHostMsg_SelectCacheForSharedWorker,
OnSelectCacheForSharedWorker)
IPC_MESSAGE_HANDLER(AppCacheHostMsg_MarkAsForeignEntry,
@@ -110,19 +108,6 @@ void AppCacheDispatcherHost::OnSelectCache(
}
}
-void AppCacheDispatcherHost::OnSelectCacheForWorker(
- int host_id, int parent_process_id, int parent_host_id) {
- if (appcache_service_.get()) {
- if (!backend_impl_.SelectCacheForWorker(host_id, parent_process_id,
- parent_host_id)) {
- bad_message::ReceivedBadMessage(
- this, bad_message::ACDH_SELECT_CACHE_FOR_WORKER);
- }
- } else {
- frontend_proxy_.OnCacheSelected(host_id, AppCacheInfo());
- }
-}
-
void AppCacheDispatcherHost::OnSelectCacheForSharedWorker(int host_id,
int64_t appcache_id) {
if (appcache_service_.get()) {
@@ -173,7 +158,7 @@ void AppCacheDispatcherHost::OnGetStatus(int host_id, IPC::Message* reply_msg) {
return;
}
- GetStatusCallback(APPCACHE_STATUS_UNCACHED, reply_msg);
+ GetStatusCallback(AppCacheStatus::APPCACHE_STATUS_UNCACHED, reply_msg);
}
void AppCacheDispatcherHost::OnStartUpdate(int host_id,
diff --git a/chromium/content/browser/appcache/appcache_dispatcher_host.h b/chromium/content/browser/appcache/appcache_dispatcher_host.h
index d148276136f..39764ef1ca3 100644
--- a/chromium/content/browser/appcache/appcache_dispatcher_host.h
+++ b/chromium/content/browser/appcache/appcache_dispatcher_host.h
@@ -46,8 +46,6 @@ class AppCacheDispatcherHost : public BrowserMessageFilter {
const GURL& document_url,
int64_t cache_document_was_loaded_from,
const GURL& opt_manifest_url);
- void OnSelectCacheForWorker(int host_id, int parent_process_id,
- int parent_host_id);
void OnSelectCacheForSharedWorker(int host_id, int64_t appcache_id);
void OnMarkAsForeignEntry(int host_id,
const GURL& document_url,
diff --git a/chromium/content/browser/appcache/appcache_entry.h b/chromium/content/browser/appcache/appcache_entry.h
index 3c3b89ea772..51182d0ea32 100644
--- a/chromium/content/browser/appcache/appcache_entry.h
+++ b/chromium/content/browser/appcache/appcache_entry.h
@@ -26,7 +26,6 @@ class AppCacheEntry {
FOREIGN = 1 << 3,
FALLBACK = 1 << 4,
INTERCEPT = 1 << 5,
- EXECUTABLE = 1 << 6,
};
AppCacheEntry()
@@ -51,7 +50,6 @@ class AppCacheEntry {
bool IsForeign() const { return (types_ & FOREIGN) != 0; }
bool IsFallback() const { return (types_ & FALLBACK) != 0; }
bool IsIntercept() const { return (types_ & INTERCEPT) != 0; }
- bool IsExecutable() const { return (types_ & EXECUTABLE) != 0; }
int64_t response_id() const { return response_id_; }
void set_response_id(int64_t id) { response_id_ = id; }
diff --git a/chromium/content/browser/appcache/appcache_executable_handler.h b/chromium/content/browser/appcache/appcache_executable_handler.h
deleted file mode 100644
index e1df619273e..00000000000
--- a/chromium/content/browser/appcache/appcache_executable_handler.h
+++ /dev/null
@@ -1,56 +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_BROWSER_APPCACHE_APPCACHE_EXECUTABLE_HANDLER_H_
-#define CONTENT_BROWSER_APPCACHE_APPCACHE_EXECUTABLE_HANDLER_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "content/common/content_export.h"
-#include "url/gurl.h"
-
-namespace net {
-class IOBuffer;
-class URLRequest;
-}
-
-namespace content {
-
-// An interface that must be provided by the embedder to support this feature.
-class CONTENT_EXPORT AppCacheExecutableHandler {
- public:
- // A handler can respond in one of 4 ways, if each of the GURL fields
- // in 'Response' are empty and use_network is false, an error response is
- // synthesized.
- struct Response {
- GURL cached_resource_url;
- GURL redirect_url;
- bool use_network;
- // TODO: blob + headers would be a good one to provide as well, as it would
- // make templating possible.
- };
- typedef base::OnceCallback<void(const Response&)> ResponseCallback;
-
- // Deletion of the handler cancels all pending callbacks.
- virtual ~AppCacheExecutableHandler() {}
-
- virtual void HandleRequest(net::URLRequest* req,
- ResponseCallback callback) = 0;
-};
-
-// A factory to produce instances.
-class CONTENT_EXPORT AppCacheExecutableHandlerFactory {
- public:
- virtual std::unique_ptr<AppCacheExecutableHandler> CreateHandler(
- const GURL& handler_url,
- net::IOBuffer* handler_source) = 0;
-
- protected:
- virtual ~AppCacheExecutableHandlerFactory() {}
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_APPCACHE_APPCACHE_EXECUTABLE_HANDLER_H_
diff --git a/chromium/content/browser/appcache/appcache_frontend_proxy.cc b/chromium/content/browser/appcache/appcache_frontend_proxy.cc
index 918521638cc..421aece9d87 100644
--- a/chromium/content/browser/appcache/appcache_frontend_proxy.cc
+++ b/chromium/content/browser/appcache/appcache_frontend_proxy.cc
@@ -24,8 +24,8 @@ void AppCacheFrontendProxy::OnStatusChanged(const std::vector<int>& host_ids,
void AppCacheFrontendProxy::OnEventRaised(const std::vector<int>& host_ids,
AppCacheEventID event_id) {
- DCHECK_NE(APPCACHE_PROGRESS_EVENT,
- event_id); // See OnProgressEventRaised.
+ DCHECK_NE(AppCacheEventID::APPCACHE_PROGRESS_EVENT,
+ event_id); // See OnProgressEventRaised.
sender_->Send(new AppCacheMsg_EventRaised(host_ids, event_id));
}
diff --git a/chromium/content/browser/appcache/appcache_group.cc b/chromium/content/browser/appcache/appcache_group.cc
index c5e1e5ad871..06cca4ca884 100644
--- a/chromium/content/browser/appcache/appcache_group.cc
+++ b/chromium/content/browser/appcache/appcache_group.cc
@@ -46,8 +46,8 @@ AppCacheGroup::AppCacheGroup(AppCacheStorage* storage,
update_status_(IDLE),
is_obsolete_(false),
is_being_deleted_(false),
- newest_complete_cache_(NULL),
- update_job_(NULL),
+ newest_complete_cache_(nullptr),
+ update_job_(nullptr),
storage_(storage),
is_in_dtor_(false) {
storage_->working_set()->AddGroup(this);
@@ -116,8 +116,8 @@ void AppCacheGroup::RemoveCache(AppCache* cache) {
if (cache == newest_complete_cache_) {
CancelUpdate();
AppCache* tmp_cache = newest_complete_cache_;
- newest_complete_cache_ = NULL;
- tmp_cache->set_owning_group(NULL); // may cause this group to be deleted
+ newest_complete_cache_ = nullptr;
+ tmp_cache->set_owning_group(nullptr); // may cause this group to be deleted
} else {
scoped_refptr<AppCacheGroup> protect(this);
@@ -126,7 +126,7 @@ void AppCacheGroup::RemoveCache(AppCache* cache) {
if (it != old_caches_.end()) {
AppCache* tmp_cache = *it;
old_caches_.erase(it);
- tmp_cache->set_owning_group(NULL); // may cause group to be released
+ tmp_cache->set_owning_group(nullptr); // may cause group to be released
}
if (!is_obsolete() && old_caches_.empty() &&
@@ -256,12 +256,12 @@ void AppCacheGroup::SetUpdateAppCacheStatus(UpdateAppCacheStatus status) {
if (status != IDLE) {
DCHECK(update_job_);
} else {
- update_job_ = NULL;
+ update_job_ = nullptr;
// Observers may release us in these callbacks, so we protect against
// deletion by adding an extra ref in this scope (but only if we're not
// in our destructor).
- scoped_refptr<AppCacheGroup> protect(is_in_dtor_ ? NULL : this);
+ scoped_refptr<AppCacheGroup> protect(is_in_dtor_ ? nullptr : this);
for (auto& observer : observers_)
observer.OnUpdateComplete(this);
if (!queued_updates_.empty())
diff --git a/chromium/content/browser/appcache/appcache_group_unittest.cc b/chromium/content/browser/appcache/appcache_group_unittest.cc
index 9aace6671a2..323497b834d 100644
--- a/chromium/content/browser/appcache/appcache_group_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_group_unittest.cc
@@ -20,9 +20,9 @@ namespace {
class TestAppCacheFrontend : public content::AppCacheFrontend {
public:
TestAppCacheFrontend()
- : last_host_id_(-1), last_cache_id_(-1),
- last_status_(content::APPCACHE_STATUS_OBSOLETE) {
- }
+ : last_host_id_(-1),
+ last_cache_id_(-1),
+ last_status_(content::AppCacheStatus::APPCACHE_STATUS_OBSOLETE) {}
void OnCacheSelected(int host_id,
const content::AppCacheInfo& info) override {
@@ -192,12 +192,12 @@ TEST_F(AppCacheGroupTest, CleanupUnusedGroup) {
host1.AssociateCompleteCache(cache1);
EXPECT_EQ(frontend.last_host_id_, host1.host_id());
EXPECT_EQ(frontend.last_cache_id_, cache1->cache_id());
- EXPECT_EQ(frontend.last_status_, APPCACHE_STATUS_IDLE);
+ EXPECT_EQ(frontend.last_status_, AppCacheStatus::APPCACHE_STATUS_IDLE);
host2.AssociateCompleteCache(cache1);
EXPECT_EQ(frontend.last_host_id_, host2.host_id());
EXPECT_EQ(frontend.last_cache_id_, cache1->cache_id());
- EXPECT_EQ(frontend.last_status_, APPCACHE_STATUS_IDLE);
+ EXPECT_EQ(frontend.last_status_, AppCacheStatus::APPCACHE_STATUS_IDLE);
AppCache* cache2 = new AppCache(service.storage(), 222);
cache2->set_complete(true);
@@ -210,7 +210,7 @@ TEST_F(AppCacheGroupTest, CleanupUnusedGroup) {
host2.AssociateNoCache(GURL());
EXPECT_EQ(frontend.last_host_id_, host2.host_id());
EXPECT_EQ(frontend.last_cache_id_, kAppCacheNoCacheId);
- EXPECT_EQ(frontend.last_status_, APPCACHE_STATUS_UNCACHED);
+ EXPECT_EQ(frontend.last_status_, AppCacheStatus::APPCACHE_STATUS_UNCACHED);
}
TEST_F(AppCacheGroupTest, StartUpdate) {
@@ -222,15 +222,16 @@ TEST_F(AppCacheGroupTest, StartUpdate) {
group->update_status_ = AppCacheGroup::CHECKING;
group->StartUpdate();
AppCacheUpdateJob* update = group->update_job_;
- EXPECT_TRUE(update != NULL);
+ EXPECT_TRUE(update != nullptr);
// Start another update, check that same update job is in use.
- group->StartUpdateWithHost(NULL);
+ group->StartUpdateWithHost(nullptr);
EXPECT_EQ(update, group->update_job_);
- // Deleting the update should restore the group to APPCACHE_STATUS_IDLE.
+ // Deleting the update should restore the group to
+ // AppCacheStatus::APPCACHE_STATUS_IDLE.
delete update;
- EXPECT_TRUE(group->update_job_ == NULL);
+ EXPECT_TRUE(group->update_job_ == nullptr);
EXPECT_EQ(AppCacheGroup::IDLE, group->update_status());
}
@@ -243,12 +244,12 @@ TEST_F(AppCacheGroupTest, CancelUpdate) {
group->update_status_ = AppCacheGroup::CHECKING;
group->StartUpdate();
AppCacheUpdateJob* update = group->update_job_;
- EXPECT_TRUE(update != NULL);
+ EXPECT_TRUE(update != nullptr);
// Deleting the group should cancel the update.
TestUpdateObserver observer;
group->AddUpdateObserver(&observer);
- group = NULL; // causes group to be deleted
+ group = nullptr; // causes group to be deleted
EXPECT_TRUE(observer.update_completed_);
EXPECT_FALSE(observer.group_has_cache_);
}
diff --git a/chromium/content/browser/appcache/appcache_host.cc b/chromium/content/browser/appcache/appcache_host.cc
index 58a10dc1e7c..13d410199ed 100644
--- a/chromium/content/browser/appcache/appcache_host.cc
+++ b/chromium/content/browser/appcache/appcache_host.cc
@@ -62,7 +62,7 @@ AppCacheHost::AppCacheHost(int host_id,
frontend_(frontend),
service_(service),
storage_(service->storage()),
- pending_callback_param_(NULL),
+ pending_callback_param_(nullptr),
main_resource_was_namespace_entry_(false),
main_resource_blocked_(false),
associated_cache_info_pending_(false),
@@ -104,7 +104,7 @@ bool AppCacheHost::SelectCache(const GURL& document_url,
was_select_cache_called_ = true;
if (!is_cache_selection_enabled_) {
- FinishCacheSelection(NULL, NULL);
+ FinishCacheSelection(nullptr, nullptr);
return true;
}
@@ -134,17 +134,15 @@ bool AppCacheHost::SelectCache(const GURL& document_url,
AppCachePolicy* policy = service()->appcache_policy();
if (policy &&
!policy->CanCreateAppCache(manifest_url, first_party_url_)) {
- FinishCacheSelection(NULL, NULL);
+ FinishCacheSelection(nullptr, nullptr);
std::vector<int> host_ids(1, host_id_);
- frontend_->OnEventRaised(host_ids, APPCACHE_CHECKING_EVENT);
+ frontend_->OnEventRaised(host_ids,
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
frontend_->OnErrorEventRaised(
- host_ids,
- AppCacheErrorDetails(
- "Cache creation was blocked by the content policy",
- APPCACHE_POLICY_ERROR,
- GURL(),
- 0,
- false /*is_cross_origin*/));
+ host_ids, AppCacheErrorDetails(
+ "Cache creation was blocked by the content policy",
+ AppCacheErrorReason::APPCACHE_POLICY_ERROR, GURL(), 0,
+ false /*is_cross_origin*/));
frontend_->OnContentBlocked(host_id_, manifest_url);
return true;
}
@@ -160,24 +158,7 @@ bool AppCacheHost::SelectCache(const GURL& document_url,
// TODO(michaeln): If there was a manifest URL, the user agent may report
// to the user that it was ignored, to aid in application development.
- FinishCacheSelection(NULL, NULL);
- return true;
-}
-
-bool AppCacheHost::SelectCacheForWorker(int parent_process_id,
- int parent_host_id) {
- if (was_select_cache_called_)
- return false;
-
- DCHECK(pending_start_update_callback_.is_null() &&
- pending_swap_cache_callback_.is_null() &&
- pending_get_status_callback_.is_null() &&
- !is_selection_pending());
-
- was_select_cache_called_ = true;
- parent_process_id_ = parent_process_id;
- parent_host_id_ = parent_host_id;
- FinishCacheSelection(NULL, NULL);
+ FinishCacheSelection(nullptr, nullptr);
return true;
}
@@ -195,7 +176,7 @@ bool AppCacheHost::SelectCacheForSharedWorker(int64_t appcache_id) {
LoadSelectedCache(appcache_id);
return true;
}
- FinishCacheSelection(NULL, NULL);
+ FinishCacheSelection(nullptr, nullptr);
return true;
}
@@ -232,7 +213,7 @@ void AppCacheHost::DoPendingGetStatus() {
std::move(pending_get_status_callback_)
.Run(GetStatus(), pending_callback_param_);
- pending_callback_param_ = NULL;
+ pending_callback_param_ = nullptr;
}
void AppCacheHost::StartUpdateWithCallback(StartUpdateCallback callback,
@@ -264,7 +245,7 @@ void AppCacheHost::DoPendingStartUpdate() {
std::move(pending_start_update_callback_)
.Run(success, pending_callback_param_);
- pending_callback_param_ = NULL;
+ pending_callback_param_ = nullptr;
}
void AppCacheHost::SwapCacheWithCallback(SwapCacheCallback callback,
@@ -299,7 +280,7 @@ void AppCacheHost::DoPendingSwapCache() {
}
std::move(pending_swap_cache_callback_).Run(success, pending_callback_param_);
- pending_callback_param_ = NULL;
+ pending_callback_param_ = nullptr;
}
void AppCacheHost::SetSpawningHostId(
@@ -310,13 +291,13 @@ void AppCacheHost::SetSpawningHostId(
const AppCacheHost* AppCacheHost::GetSpawningHost() const {
AppCacheBackendImpl* backend = service_->GetBackend(spawning_process_id_);
- return backend ? backend->GetHost(spawning_host_id_) : NULL;
+ return backend ? backend->GetHost(spawning_host_id_) : nullptr;
}
AppCacheHost* AppCacheHost::GetParentAppCacheHost() const {
DCHECK(is_for_dedicated_worker());
AppCacheBackendImpl* backend = service_->GetBackend(parent_process_id_);
- return backend ? backend->GetHost(parent_host_id_) : NULL;
+ return backend ? backend->GetHost(parent_host_id_) : nullptr;
}
std::unique_ptr<AppCacheRequestHandler> AppCacheHost::CreateRequestHandler(
@@ -328,7 +309,7 @@ std::unique_ptr<AppCacheRequestHandler> AppCacheHost::CreateRequestHandler(
if (parent_host)
return parent_host->CreateRequestHandler(
std::move(request), resource_type, should_reset_appcache);
- return NULL;
+ return nullptr;
}
if (AppCacheRequestHandler::IsMainResourceType(resource_type)) {
@@ -344,7 +325,7 @@ std::unique_ptr<AppCacheRequestHandler> AppCacheHost::CreateRequestHandler(
return base::WrapUnique(new AppCacheRequestHandler(
this, resource_type, should_reset_appcache, std::move(request)));
}
- return NULL;
+ return nullptr;
}
void AppCacheHost::GetResourceList(
@@ -357,22 +338,22 @@ AppCacheStatus AppCacheHost::GetStatus() {
// 6.9.8 Application cache API
AppCache* cache = associated_cache();
if (!cache)
- return APPCACHE_STATUS_UNCACHED;
+ return AppCacheStatus::APPCACHE_STATUS_UNCACHED;
// A cache without an owning group represents the cache being constructed
// during the application cache update process.
if (!cache->owning_group())
- return APPCACHE_STATUS_DOWNLOADING;
+ return AppCacheStatus::APPCACHE_STATUS_DOWNLOADING;
if (cache->owning_group()->is_obsolete())
- return APPCACHE_STATUS_OBSOLETE;
+ return AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
if (cache->owning_group()->update_status() == AppCacheGroup::CHECKING)
- return APPCACHE_STATUS_CHECKING;
+ return AppCacheStatus::APPCACHE_STATUS_CHECKING;
if (cache->owning_group()->update_status() == AppCacheGroup::DOWNLOADING)
- return APPCACHE_STATUS_DOWNLOADING;
+ return AppCacheStatus::APPCACHE_STATUS_DOWNLOADING;
if (swappable_cache_.get())
- return APPCACHE_STATUS_UPDATE_READY;
- return APPCACHE_STATUS_IDLE;
+ return AppCacheStatus::APPCACHE_STATUS_UPDATE_READY;
+ return AppCacheStatus::APPCACHE_STATUS_IDLE;
}
void AppCacheHost::LoadOrCreateGroup(const GURL& manifest_url) {
@@ -385,7 +366,7 @@ void AppCacheHost::OnGroupLoaded(AppCacheGroup* group,
const GURL& manifest_url) {
DCHECK(manifest_url == pending_selected_manifest_url_);
pending_selected_manifest_url_ = GURL();
- FinishCacheSelection(NULL, group);
+ FinishCacheSelection(nullptr, group);
}
void AppCacheHost::LoadSelectedCache(int64_t cache_id) {
@@ -400,7 +381,7 @@ void AppCacheHost::OnCacheLoaded(AppCache* cache, int64_t cache_id) {
main_resource_cache_ = cache;
} else if (cache_id == pending_selected_cache_id_) {
pending_selected_cache_id_ = kAppCacheNoCacheId;
- FinishCacheSelection(cache, NULL);
+ FinishCacheSelection(cache, nullptr);
}
}
@@ -489,8 +470,8 @@ void AppCacheHost::OnUpdateComplete(AppCacheGroup* group) {
// Add a reference to the newest complete cache.
SetSwappableCache(group);
- group_being_updated_ = NULL;
- newest_cache_of_group_being_updated_ = NULL;
+ group_being_updated_ = nullptr;
+ newest_cache_of_group_being_updated_ = nullptr;
if (associated_cache_info_pending_ && associated_cache_.get() &&
associated_cache_->is_complete()) {
@@ -508,13 +489,13 @@ void AppCacheHost::OnUpdateComplete(AppCacheGroup* group) {
void AppCacheHost::SetSwappableCache(AppCacheGroup* group) {
if (!group) {
- swappable_cache_ = NULL;
+ swappable_cache_ = nullptr;
} else {
AppCache* new_cache = group->newest_complete_cache();
if (new_cache != associated_cache_.get())
swappable_cache_ = new_cache;
else
- swappable_cache_ = NULL;
+ swappable_cache_ = nullptr;
}
}
@@ -546,7 +527,7 @@ void AppCacheHost::PrepareForTransfer() {
DCHECK(!is_selection_pending());
DCHECK(!group_being_updated_.get());
host_id_ = kAppCacheNoHostId;
- frontend_ = NULL;
+ frontend_ = nullptr;
}
void AppCacheHost::CompleteTransfer(int host_id, AppCacheFrontend* frontend) {
@@ -583,7 +564,7 @@ void AppCacheHost::SetAppCacheSubresourceFactory(
void AppCacheHost::AssociateNoCache(const GURL& manifest_url) {
// manifest url can be empty.
- AssociateCacheHelper(NULL, manifest_url);
+ AssociateCacheHelper(nullptr, manifest_url);
}
void AppCacheHost::AssociateIncompleteCache(AppCache* cache,
@@ -605,7 +586,7 @@ void AppCacheHost::AssociateCacheHelper(AppCache* cache,
}
associated_cache_ = cache;
- SetSwappableCache(cache ? cache->owning_group() : NULL);
+ SetSwappableCache(cache ? cache->owning_group() : nullptr);
associated_cache_info_pending_ = cache && !cache->is_complete();
AppCacheInfo info;
if (cache)
diff --git a/chromium/content/browser/appcache/appcache_host.h b/chromium/content/browser/appcache/appcache_host.h
index d49fc865112..27f31ab8797 100644
--- a/chromium/content/browser/appcache/appcache_host.h
+++ b/chromium/content/browser/appcache/appcache_host.h
@@ -88,8 +88,6 @@ class CONTENT_EXPORT AppCacheHost
bool SelectCache(const GURL& document_url,
const int64_t cache_document_was_loaded_from,
const GURL& manifest_url);
- bool SelectCacheForWorker(int parent_process_id,
- int parent_host_id);
bool SelectCacheForSharedWorker(int64_t appcache_id);
bool MarkAsForeignEntry(const GURL& document_url,
int64_t cache_document_was_loaded_from);
diff --git a/chromium/content/browser/appcache/appcache_host_unittest.cc b/chromium/content/browser/appcache/appcache_host_unittest.cc
index 46b40aa9b8e..3db34247c43 100644
--- a/chromium/content/browser/appcache/appcache_host_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_host_unittest.cc
@@ -32,12 +32,12 @@ class AppCacheHostTest : public testing::Test {
class MockFrontend : public AppCacheFrontend {
public:
MockFrontend()
- : last_host_id_(-222), last_cache_id_(-222),
- last_status_(APPCACHE_STATUS_OBSOLETE),
- last_status_changed_(APPCACHE_STATUS_OBSOLETE),
- last_event_id_(APPCACHE_OBSOLETE_EVENT),
- content_blocked_(false) {
- }
+ : last_host_id_(-222),
+ last_cache_id_(-222),
+ last_status_(AppCacheStatus::APPCACHE_STATUS_OBSOLETE),
+ last_status_changed_(AppCacheStatus::APPCACHE_STATUS_OBSOLETE),
+ last_event_id_(AppCacheEventID::APPCACHE_OBSOLETE_EVENT),
+ content_blocked_(false) {}
void OnCacheSelected(int host_id, const AppCacheInfo& info) override {
last_host_id_ = host_id;
@@ -57,14 +57,14 @@ class AppCacheHostTest : public testing::Test {
void OnErrorEventRaised(const std::vector<int>& host_ids,
const AppCacheErrorDetails& details) override {
- last_event_id_ = APPCACHE_ERROR_EVENT;
+ last_event_id_ = AppCacheEventID::APPCACHE_ERROR_EVENT;
}
void OnProgressEventRaised(const std::vector<int>& host_ids,
const GURL& url,
int num_total,
int num_complete) override {
- last_event_id_ = APPCACHE_PROGRESS_EVENT;
+ last_event_id_ = AppCacheEventID::APPCACHE_PROGRESS_EVENT;
}
void OnLogMessage(int host_id,
@@ -89,7 +89,7 @@ class AppCacheHostTest : public testing::Test {
class MockQuotaManagerProxy : public storage::QuotaManagerProxy {
public:
- MockQuotaManagerProxy() : QuotaManagerProxy(NULL, NULL) {}
+ MockQuotaManagerProxy() : QuotaManagerProxy(nullptr, nullptr) {}
// Not needed for our tests.
void RegisterClient(storage::QuotaClient* client) override {}
@@ -166,15 +166,15 @@ TEST_F(AppCacheHostTest, Basic) {
EXPECT_EQ(1, host.host_id());
EXPECT_EQ(&service_, host.service());
EXPECT_EQ(&mock_frontend_, host.frontend());
- EXPECT_EQ(NULL, host.associated_cache());
+ EXPECT_EQ(nullptr, host.associated_cache());
EXPECT_FALSE(host.is_selection_pending());
// See that the callbacks are delivered immediately
// and respond as if there is no cache selected.
- last_status_result_ = APPCACHE_STATUS_OBSOLETE;
+ last_status_result_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
host.GetStatusWithCallback(std::move(get_status_callback_),
reinterpret_cast<void*>(1));
- EXPECT_EQ(APPCACHE_STATUS_UNCACHED, last_status_result_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED, last_status_result_);
EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
last_start_result_ = true;
@@ -202,7 +202,7 @@ TEST_F(AppCacheHostTest, SelectNoCache) {
// Reset our mock frontend
mock_frontend_.last_cache_id_ = -333;
mock_frontend_.last_host_id_ = -333;
- mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
+ mock_frontend_.last_status_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin());
{
@@ -213,25 +213,26 @@ TEST_F(AppCacheHostTest, SelectNoCache) {
// We should have received an OnCacheSelected msg
EXPECT_EQ(1, mock_frontend_.last_host_id_);
EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
- EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED,
+ mock_frontend_.last_status_);
// Otherwise, see that it respond as if there is no cache selected.
EXPECT_EQ(1, host.host_id());
EXPECT_EQ(&service_, host.service());
EXPECT_EQ(&mock_frontend_, host.frontend());
- EXPECT_EQ(NULL, host.associated_cache());
+ EXPECT_EQ(nullptr, host.associated_cache());
EXPECT_FALSE(host.is_selection_pending());
EXPECT_TRUE(host.preferred_manifest_url().is_empty());
}
EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
- service_.set_quota_manager_proxy(NULL);
+ service_.set_quota_manager_proxy(nullptr);
}
TEST_F(AppCacheHostTest, ForeignEntry) {
// Reset our mock frontend
mock_frontend_.last_cache_id_ = -333;
mock_frontend_.last_host_id_ = -333;
- mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
+ mock_frontend_.last_status_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
// Precondition, a cache with an entry that is not marked as foreign.
const int kCacheId = 22;
@@ -245,13 +246,14 @@ TEST_F(AppCacheHostTest, ForeignEntry) {
// We should have received an OnCacheSelected msg for kAppCacheNoCacheId.
EXPECT_EQ(1, mock_frontend_.last_host_id_);
EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
- EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED,
+ mock_frontend_.last_status_);
// See that it respond as if there is no cache selected.
EXPECT_EQ(1, host.host_id());
EXPECT_EQ(&service_, host.service());
EXPECT_EQ(&mock_frontend_, host.frontend());
- EXPECT_EQ(NULL, host.associated_cache());
+ EXPECT_EQ(nullptr, host.associated_cache());
EXPECT_FALSE(host.is_selection_pending());
// See that the entry was marked as foreign.
@@ -262,7 +264,7 @@ TEST_F(AppCacheHostTest, ForeignFallbackEntry) {
// Reset our mock frontend
mock_frontend_.last_cache_id_ = -333;
mock_frontend_.last_host_id_ = -333;
- mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
+ mock_frontend_.last_status_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
// Precondition, a cache with a fallback entry that is not marked as foreign.
const int kCacheId = 22;
@@ -277,7 +279,8 @@ TEST_F(AppCacheHostTest, ForeignFallbackEntry) {
// We should have received an OnCacheSelected msg for kAppCacheNoCacheId.
EXPECT_EQ(1, mock_frontend_.last_host_id_);
EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
- EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED,
+ mock_frontend_.last_status_);
// See that the fallback entry was marked as foreign.
EXPECT_TRUE(cache->GetEntry(kFallbackURL)->IsForeign());
@@ -287,7 +290,7 @@ TEST_F(AppCacheHostTest, FailedCacheLoad) {
// Reset our mock frontend
mock_frontend_.last_cache_id_ = -333;
mock_frontend_.last_host_id_ = -333;
- mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
+ mock_frontend_.last_status_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
AppCacheHost host(1, &mock_frontend_, &service_);
EXPECT_FALSE(host.is_selection_pending());
@@ -300,24 +303,25 @@ TEST_F(AppCacheHostTest, FailedCacheLoad) {
EXPECT_TRUE(host.is_selection_pending());
// The callback should not occur until we finish cache selection.
- last_status_result_ = APPCACHE_STATUS_OBSOLETE;
+ last_status_result_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
last_callback_param_ = reinterpret_cast<void*>(-1);
host.GetStatusWithCallback(std::move(get_status_callback_),
reinterpret_cast<void*>(1));
- EXPECT_EQ(APPCACHE_STATUS_OBSOLETE, last_status_result_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_OBSOLETE, last_status_result_);
EXPECT_EQ(reinterpret_cast<void*>(-1), last_callback_param_);
// Satisfy the load with NULL, a failure.
- host.OnCacheLoaded(NULL, kMockCacheId);
+ host.OnCacheLoaded(nullptr, kMockCacheId);
// Cache selection should have finished
EXPECT_FALSE(host.is_selection_pending());
EXPECT_EQ(1, mock_frontend_.last_host_id_);
EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
- EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED,
+ mock_frontend_.last_status_);
// Callback should have fired upon completing the cache load too.
- EXPECT_EQ(APPCACHE_STATUS_UNCACHED, last_status_result_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED, last_status_result_);
EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
}
@@ -332,30 +336,31 @@ TEST_F(AppCacheHostTest, FailedGroupLoad) {
EXPECT_TRUE(host.is_selection_pending());
// The callback should not occur until we finish cache selection.
- last_status_result_ = APPCACHE_STATUS_OBSOLETE;
+ last_status_result_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
last_callback_param_ = reinterpret_cast<void*>(-1);
host.GetStatusWithCallback(std::move(get_status_callback_),
reinterpret_cast<void*>(1));
- EXPECT_EQ(APPCACHE_STATUS_OBSOLETE, last_status_result_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_OBSOLETE, last_status_result_);
EXPECT_EQ(reinterpret_cast<void*>(-1), last_callback_param_);
// Satisfy the load will NULL, a failure.
- host.OnGroupLoaded(NULL, kMockManifestUrl);
+ host.OnGroupLoaded(nullptr, kMockManifestUrl);
// Cache selection should have finished
EXPECT_FALSE(host.is_selection_pending());
EXPECT_EQ(1, mock_frontend_.last_host_id_);
EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
- EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED,
+ mock_frontend_.last_status_);
// Callback should have fired upon completing the group load.
- EXPECT_EQ(APPCACHE_STATUS_UNCACHED, last_status_result_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED, last_status_result_);
EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
}
TEST_F(AppCacheHostTest, SetSwappableCache) {
AppCacheHost host(1, &mock_frontend_, &service_);
- host.SetSwappableCache(NULL);
+ host.SetSwappableCache(nullptr);
EXPECT_FALSE(host.swappable_cache_.get());
scoped_refptr<AppCacheGroup> group1(new AppCacheGroup(
@@ -373,11 +378,11 @@ TEST_F(AppCacheHostTest, SetSwappableCache) {
host.AssociateCompleteCache(cache1);
EXPECT_FALSE(host.swappable_cache_.get()); // was same as associated cache
- EXPECT_EQ(APPCACHE_STATUS_IDLE, host.GetStatus());
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_IDLE, host.GetStatus());
// verify OnCacheSelected was called
EXPECT_EQ(host.host_id(), mock_frontend_.last_host_id_);
EXPECT_EQ(cache1->cache_id(), mock_frontend_.last_cache_id_);
- EXPECT_EQ(APPCACHE_STATUS_IDLE, mock_frontend_.last_status_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_IDLE, mock_frontend_.last_status_);
AppCache* cache2 = new AppCache(service_.storage(), 222);
cache2->set_complete(true);
@@ -421,40 +426,6 @@ TEST_F(AppCacheHostTest, SetSwappableCache) {
EXPECT_FALSE(host.swappable_cache_.get()); // group2 had no newest cache
}
-TEST_F(AppCacheHostTest, ForDedicatedWorker) {
- const int kMockProcessId = 1;
- const int kParentHostId = 1;
- const int kWorkerHostId = 2;
-
- AppCacheBackendImpl backend_impl;
- backend_impl.Initialize(&service_, &mock_frontend_, kMockProcessId);
- backend_impl.RegisterHost(kParentHostId);
- backend_impl.RegisterHost(kWorkerHostId);
-
- AppCacheHost* parent_host = backend_impl.GetHost(kParentHostId);
- EXPECT_FALSE(parent_host->is_for_dedicated_worker());
-
- AppCacheHost* worker_host = backend_impl.GetHost(kWorkerHostId);
- worker_host->SelectCacheForWorker(kParentHostId, kMockProcessId);
- EXPECT_TRUE(worker_host->is_for_dedicated_worker());
- EXPECT_EQ(parent_host, worker_host->GetParentAppCacheHost());
-
- // We should have received an OnCacheSelected msg for the worker_host.
- // The host for workers always indicates 'no cache selected' regardless
- // of its parent's state. This is OK because the worker cannot access
- // the scriptable interface, the only function available is resource
- // loading (see appcache_request_handler_unittests those tests).
- EXPECT_EQ(kWorkerHostId, mock_frontend_.last_host_id_);
- EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
- EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
-
- // Simulate the parent being torn down.
- backend_impl.UnregisterHost(kParentHostId);
- parent_host = NULL;
- EXPECT_EQ(NULL, backend_impl.GetHost(kParentHostId));
- EXPECT_EQ(NULL, worker_host->GetParentAppCacheHost());
-}
-
TEST_F(AppCacheHostTest, SelectCacheAllowed) {
scoped_refptr<MockQuotaManagerProxy> mock_quota_proxy(
new MockQuotaManagerProxy);
@@ -466,8 +437,8 @@ TEST_F(AppCacheHostTest, SelectCacheAllowed) {
// Reset our mock frontend
mock_frontend_.last_cache_id_ = -333;
mock_frontend_.last_host_id_ = -333;
- mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
- mock_frontend_.last_event_id_ = APPCACHE_OBSOLETE_EVENT;
+ mock_frontend_.last_status_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
+ mock_frontend_.last_event_id_ = AppCacheEventID::APPCACHE_OBSOLETE_EVENT;
mock_frontend_.content_blocked_ = false;
const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin());
@@ -482,15 +453,17 @@ TEST_F(AppCacheHostTest, SelectCacheAllowed) {
// have received an OnCacheSelected msg yet.
EXPECT_EQ(-333, mock_frontend_.last_host_id_);
EXPECT_EQ(-333, mock_frontend_.last_cache_id_);
- EXPECT_EQ(APPCACHE_STATUS_OBSOLETE, mock_frontend_.last_status_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_OBSOLETE,
+ mock_frontend_.last_status_);
// No error events either
- EXPECT_EQ(APPCACHE_OBSOLETE_EVENT, mock_frontend_.last_event_id_);
+ EXPECT_EQ(AppCacheEventID::APPCACHE_OBSOLETE_EVENT,
+ mock_frontend_.last_event_id_);
EXPECT_FALSE(mock_frontend_.content_blocked_);
EXPECT_TRUE(host.is_selection_pending());
}
EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
- service_.set_quota_manager_proxy(NULL);
+ service_.set_quota_manager_proxy(nullptr);
}
TEST_F(AppCacheHostTest, SelectCacheBlocked) {
@@ -504,8 +477,8 @@ TEST_F(AppCacheHostTest, SelectCacheBlocked) {
// Reset our mock frontend
mock_frontend_.last_cache_id_ = -333;
mock_frontend_.last_host_id_ = -333;
- mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
- mock_frontend_.last_event_id_ = APPCACHE_OBSOLETE_EVENT;
+ mock_frontend_.last_status_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
+ mock_frontend_.last_event_id_ = AppCacheEventID::APPCACHE_OBSOLETE_EVENT;
mock_frontend_.content_blocked_ = false;
const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin());
@@ -519,22 +492,24 @@ TEST_F(AppCacheHostTest, SelectCacheBlocked) {
// We should have received an OnCacheSelected msg
EXPECT_EQ(1, mock_frontend_.last_host_id_);
EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
- EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
+ EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED,
+ mock_frontend_.last_status_);
// Also, an error event was raised
- EXPECT_EQ(APPCACHE_ERROR_EVENT, mock_frontend_.last_event_id_);
+ EXPECT_EQ(AppCacheEventID::APPCACHE_ERROR_EVENT,
+ mock_frontend_.last_event_id_);
EXPECT_TRUE(mock_frontend_.content_blocked_);
// Otherwise, see that it respond as if there is no cache selected.
EXPECT_EQ(1, host.host_id());
EXPECT_EQ(&service_, host.service());
EXPECT_EQ(&mock_frontend_, host.frontend());
- EXPECT_EQ(NULL, host.associated_cache());
+ EXPECT_EQ(nullptr, host.associated_cache());
EXPECT_FALSE(host.is_selection_pending());
EXPECT_TRUE(host.preferred_manifest_url().is_empty());
}
EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
- service_.set_quota_manager_proxy(NULL);
+ service_.set_quota_manager_proxy(nullptr);
}
TEST_F(AppCacheHostTest, SelectCacheTwice) {
@@ -545,7 +520,6 @@ TEST_F(AppCacheHostTest, SelectCacheTwice) {
// Select methods should bail if cache has already been selected.
EXPECT_FALSE(host.SelectCache(kDocAndOriginUrl, kAppCacheNoCacheId, GURL()));
- EXPECT_FALSE(host.SelectCacheForWorker(0, 0));
EXPECT_FALSE(host.SelectCacheForSharedWorker(kAppCacheNoCacheId));
EXPECT_FALSE(host.MarkAsForeignEntry(kDocAndOriginUrl, kAppCacheNoCacheId));
}
diff --git a/chromium/content/browser/appcache/appcache_interceptor.cc b/chromium/content/browser/appcache/appcache_interceptor.cc
index 95e24b01a87..249851898ec 100644
--- a/chromium/content/browser/appcache/appcache_interceptor.cc
+++ b/chromium/content/browser/appcache/appcache_interceptor.cc
@@ -6,7 +6,6 @@
#include <utility>
-#include "base/debug/crash_logging.h"
#include "content/browser/appcache/appcache_backend_impl.h"
#include "content/browser/appcache/appcache_host.h"
#include "content/browser/appcache/appcache_request_handler.h"
@@ -104,15 +103,6 @@ void AppCacheInterceptor::CompleteCrossSiteTransfer(
if (!handler->SanityCheckIsSameService(requester_info->appcache_service())) {
// This can happen when V2 apps and web pages end up in the same storage
// partition.
- const GURL& first_party_url_for_cookies = request->site_for_cookies();
- if (first_party_url_for_cookies.is_valid()) {
- // TODO(lazyboy): Remove this once we know which extensions run into this
- // issue. See https://crbug.com/612711#c25 for details.
- base::debug::SetCrashKeyValue("aci_wrong_sp_extension_id",
- first_party_url_for_cookies.host());
- // No need to explicitly call DumpWithoutCrashing(), since
- // bad_message::ReceivedBadMessage() below will do that.
- }
bad_message::ReceivedBadMessage(requester_info->filter(),
bad_message::ACI_WRONG_STORAGE_PARTITION);
return;
@@ -140,7 +130,7 @@ net::URLRequestJob* AppCacheInterceptor::MaybeInterceptRequest(
net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
AppCacheRequestHandler* handler = GetHandler(request);
if (!handler)
- return NULL;
+ return nullptr;
AppCacheJob* job = handler->MaybeLoadResource(network_delegate);
return job ? job->AsURLRequestJob() : nullptr;
@@ -152,7 +142,7 @@ net::URLRequestJob* AppCacheInterceptor::MaybeInterceptRedirect(
const GURL& location) const {
AppCacheRequestHandler* handler = GetHandler(request);
if (!handler)
- return NULL;
+ return nullptr;
AppCacheJob* job =
handler->MaybeLoadFallbackForRedirect(network_delegate, location);
@@ -163,7 +153,7 @@ net::URLRequestJob* AppCacheInterceptor::MaybeInterceptResponse(
net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
AppCacheRequestHandler* handler = GetHandler(request);
if (!handler)
- return NULL;
+ return nullptr;
AppCacheJob* job = handler->MaybeLoadFallbackForResponse(network_delegate);
return job ? job->AsURLRequestJob() : nullptr;
diff --git a/chromium/content/browser/appcache/appcache_job.cc b/chromium/content/browser/appcache/appcache_job.cc
index e5258140d19..24312c7de5b 100644
--- a/chromium/content/browser/appcache/appcache_job.cc
+++ b/chromium/content/browser/appcache/appcache_job.cc
@@ -16,28 +16,6 @@
namespace content {
-std::unique_ptr<AppCacheJob> AppCacheJob::Create(
- bool is_main_resource,
- AppCacheHost* host,
- AppCacheStorage* storage,
- AppCacheRequest* request,
- net::NetworkDelegate* network_delegate,
- OnPrepareToRestartCallback restart_callback,
- std::unique_ptr<SubresourceLoadInfo> subresource_load_info,
- URLLoaderFactoryGetter* loader_factory_getter) {
- std::unique_ptr<AppCacheJob> job;
- if (base::FeatureList::IsEnabled(features::kNetworkService)) {
- job.reset(new AppCacheURLLoaderJob(
- *(request->GetResourceRequest()), request->AsURLLoaderRequest(),
- storage, std::move(subresource_load_info), loader_factory_getter));
- } else {
- job.reset(new AppCacheURLRequestJob(
- request->GetURLRequest(), network_delegate, storage, host,
- is_main_resource, std::move(restart_callback)));
- }
- return job;
-}
-
AppCacheJob::~AppCacheJob() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
@@ -62,11 +40,7 @@ bool AppCacheJob::IsCacheEntryNotFound() const {
return cache_entry_not_found_;
}
-base::WeakPtr<AppCacheJob> AppCacheJob::GetWeakPtr() {
- return weak_factory_.GetWeakPtr();
-}
-
-net::URLRequestJob* AppCacheJob::AsURLRequestJob() {
+AppCacheURLRequestJob* AppCacheJob::AsURLRequestJob() {
return nullptr;
}
@@ -75,9 +49,7 @@ AppCacheURLLoaderJob* AppCacheJob::AsURLLoaderJob() {
}
AppCacheJob::AppCacheJob()
- : cache_entry_not_found_(false),
- delivery_type_(AWAITING_DELIVERY_ORDERS),
- weak_factory_(this) {}
+ : cache_entry_not_found_(false), delivery_type_(AWAITING_DELIVERY_ORDERS) {}
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 b5965c5639b..47d80378f29 100644
--- a/chromium/content/browser/appcache/appcache_job.h
+++ b/chromium/content/browser/appcache/appcache_job.h
@@ -18,29 +18,23 @@
namespace net {
class HttpRequestHeaders;
class HttpResponseInfo;
-class NetworkDelegate;
class URLRequestJob;
}
namespace content {
class AppCacheEntry;
-class AppCacheHost;
-class AppCacheRequest;
class AppCacheResponseInfo;
class AppCacheResponseReader;
-class AppCacheStorage;
class AppCacheURLLoaderJob;
-class URLLoaderFactoryGetter;
-class URLRequestJob;
-struct SubresourceLoadInfo;
+class AppCacheURLRequestJob;
// Interface for an AppCache job. This is used to send data stored in the
// AppCache to networking consumers.
// Subclasses implement this interface to wrap custom job objects like
// URLRequestJob, URLLoaderJob, etc to ensure that these dependencies stay out
// of the AppCache code.
-class CONTENT_EXPORT AppCacheJob : public base::SupportsWeakPtr<AppCacheJob> {
+class CONTENT_EXPORT AppCacheJob {
public:
enum DeliveryType {
AWAITING_DELIVERY_ORDERS,
@@ -49,32 +43,8 @@ class CONTENT_EXPORT AppCacheJob : public base::SupportsWeakPtr<AppCacheJob> {
ERROR_DELIVERY
};
- // Callback that will be invoked before the request is restarted. The caller
- // can use this opportunity to grab state from the job to determine how it
- // should behave when the request is restarted.
- // TODO(ananta)
- // This applies only to the URLRequestJob at the moment. Look into taking
- // this knowledge out of this class.
- using OnPrepareToRestartCallback = base::OnceClosure;
-
- // Factory function to create the AppCacheJob instance for the |request|
- // passed in. The |job_type| parameter controls the type of job which is
- // created.
- static std::unique_ptr<AppCacheJob> Create(
- bool is_main_resource,
- AppCacheHost* host,
- AppCacheStorage* storage,
- AppCacheRequest* request,
- net::NetworkDelegate* network_delegate,
- OnPrepareToRestartCallback restart_callback,
- std::unique_ptr<SubresourceLoadInfo> subresource_load_info,
- URLLoaderFactoryGetter* loader_factory_getter);
-
virtual ~AppCacheJob();
- // Kills the job.
- virtual void Kill() = 0;
-
// Returns true if the job was started.
virtual bool IsStarted() const = 0;
@@ -109,11 +79,11 @@ class CONTENT_EXPORT AppCacheJob : public base::SupportsWeakPtr<AppCacheJob> {
virtual void DeliverErrorResponse() = 0;
// Returns a weak pointer reference to the job.
- virtual base::WeakPtr<AppCacheJob> GetWeakPtr();
+ virtual base::WeakPtr<AppCacheJob> GetWeakPtr() = 0;
- // Returns the underlying URLRequestJob if any. This only applies to
+ // Returns the underlying AppCacheURLRequestJob if any. This only applies to
// AppCaches loaded via the URLLoader mechanism.
- virtual net::URLRequestJob* AsURLRequestJob();
+ virtual AppCacheURLRequestJob* AsURLRequestJob();
// Returns the underlying ApppCacheURLLoaderJob if any. This only applies to
// AppCaches loaded via the URLRequest mechanism.
@@ -150,8 +120,6 @@ class CONTENT_EXPORT AppCacheJob : public base::SupportsWeakPtr<AppCacheJob> {
// Used to read the cache.
std::unique_ptr<AppCacheResponseReader> reader_;
- base::WeakPtrFactory<AppCacheJob> weak_factory_;
-
DISALLOW_COPY_AND_ASSIGN(AppCacheJob);
};
diff --git a/chromium/content/browser/appcache/appcache_manifest_parser.cc b/chromium/content/browser/appcache/appcache_manifest_parser.cc
index a8b9321e5d8..88ab907592f 100644
--- a/chromium/content/browser/appcache/appcache_manifest_parser.cc
+++ b/chromium/content/browser/appcache/appcache_manifest_parser.cc
@@ -272,16 +272,8 @@ bool ParseManifest(const GURL& manifest_url, const char* data, int length,
++line_p;
// Look for a type value we understand, otherwise skip the line.
- InterceptVerb verb = UNKNOWN_VERB;
std::wstring type(type_start, line_p - type_start);
- if (type == L"return") {
- verb = RETURN;
- } else if (type == L"execute" &&
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- kEnableExecutableHandlers)) {
- verb = EXECUTE;
- }
- if (verb == UNKNOWN_VERB)
+ if (type != L"return")
continue;
// Skip whitespace separating type from the target_url.
@@ -309,9 +301,8 @@ bool ParseManifest(const GURL& manifest_url, const char* data, int length,
continue;
bool is_pattern = HasPatternMatchingAnnotation(line_p, line_end);
- manifest.intercept_namespaces.push_back(
- AppCacheNamespace(APPCACHE_INTERCEPT_NAMESPACE, namespace_url,
- target_url, is_pattern, verb == EXECUTE));
+ 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();
diff --git a/chromium/content/browser/appcache/appcache_quota_client.cc b/chromium/content/browser/appcache/appcache_quota_client.cc
index c20f8b8a7aa..97b6ef7d07d 100644
--- a/chromium/content/browser/appcache/appcache_quota_client.cc
+++ b/chromium/content/browser/appcache/appcache_quota_client.cc
@@ -231,7 +231,7 @@ void AppCacheQuotaClient::NotifyAppCacheReady() {
}
void AppCacheQuotaClient::NotifyAppCacheDestroyed() {
- service_ = NULL;
+ service_ = nullptr;
while (!pending_batch_requests_.empty())
RunFront(&pending_batch_requests_);
diff --git a/chromium/content/browser/appcache/appcache_request_handler.cc b/chromium/content/browser/appcache/appcache_request_handler.cc
index 44f342d8ada..e5dd7d2878f 100644
--- a/chromium/content/browser/appcache/appcache_request_handler.cc
+++ b/chromium/content/browser/appcache/appcache_request_handler.cc
@@ -19,6 +19,7 @@
#include "content/browser/appcache/appcache_url_loader_request.h"
#include "content/browser/appcache/appcache_url_request_job.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "content/public/common/content_features.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
@@ -50,7 +51,8 @@ AppCacheRequestHandler::AppCacheRequestHandler(
old_host_id_(kAppCacheNoHostId),
cache_id_(kAppCacheNoCacheId),
service_(host_->service()),
- request_(std::move(request)) {
+ request_(std::move(request)),
+ weak_factory_(this) {
DCHECK(host_);
DCHECK(service_);
host_->AddObserver(this);
@@ -64,6 +66,9 @@ AppCacheRequestHandler::~AppCacheRequestHandler() {
}
if (service_)
service_->RemoveObserver(this);
+
+ if (job_ && job_->AsURLLoaderJob())
+ job_->AsURLLoaderJob()->DeleteIfNeeded();
}
AppCacheStorage* AppCacheRequestHandler::storage() const {
@@ -77,7 +82,7 @@ AppCacheJob* AppCacheRequestHandler::MaybeLoadResource(
if (!host_ ||
!AppCacheRequest::IsSchemeAndMethodSupportedForAppCache(request_.get()) ||
cache_entry_not_found_) {
- return NULL;
+ return nullptr;
}
// This method can get called multiple times over the life
@@ -89,7 +94,7 @@ AppCacheJob* AppCacheRequestHandler::MaybeLoadResource(
// This time through, we return NULL so the request hits the wire.
if (is_delivering_network_response_) {
is_delivering_network_response_ = false;
- return NULL;
+ return nullptr;
}
// Clear out our 'found' fields since we're starting a request for a
@@ -109,9 +114,14 @@ AppCacheJob* AppCacheRequestHandler::MaybeLoadResource(
// If its been setup to deliver a network response, we can just delete
// it now and return NULL instead to achieve that since it couldn't
// have been started yet.
- if (job && job->IsDeliveringNetworkResponse() && !job->AsURLLoaderJob()) {
+ if (job && job->IsDeliveringNetworkResponse()) {
DCHECK(!job->IsStarted());
- job.reset();
+ if (job->AsURLLoaderJob()) {
+ job.release(); // AppCacheURLLoaderJob always deletes itself.
+ job_ = nullptr;
+ } else {
+ job.reset();
+ }
}
return job.release();
@@ -123,34 +133,29 @@ AppCacheJob* AppCacheRequestHandler::MaybeLoadFallbackForRedirect(
if (!host_ ||
!AppCacheRequest::IsSchemeAndMethodSupportedForAppCache(request_.get()) ||
cache_entry_not_found_)
- return NULL;
+ return nullptr;
if (is_main_resource())
- return NULL;
+ return nullptr;
// TODO(vabr) This is a temporary fix (see crbug/141114). We should get rid of
// it once a more general solution to crbug/121325 is in place.
if (!maybe_load_resource_executed_)
- return NULL;
+ return nullptr;
if (request_->GetURL().GetOrigin() == location.GetOrigin())
- return NULL;
+ return nullptr;
- // In network service land, the existing job initiates a fallback request.
- if (!base::FeatureList::IsEnabled(features::kNetworkService)) {
- DCHECK(!job_.get()); // our jobs never generate redirects
- } else {
- DCHECK(job_.get());
- }
+ DCHECK(!job_.get()); // our jobs never generate redirects
std::unique_ptr<AppCacheJob> job;
if (found_fallback_entry_.has_response_id()) {
- job = MaybeCreateJobForFallback(network_delegate);
// 6.9.6, step 4: If this results in a redirect to another origin,
// get the resource of the fallback entry.
+ job = CreateJob(network_delegate);
DeliverAppCachedResponse(found_fallback_entry_, found_cache_id_,
found_manifest_url_, true,
found_namespace_entry_url_);
} else if (!found_network_namespace_) {
// 6.9.6, step 6: Fail the resource load.
- job = MaybeCreateJobForFallback(network_delegate);
+ job = CreateJob(network_delegate);
DeliverErrorResponse();
} else {
// 6.9.6 step 3 and 5: Fetch the resource normally.
@@ -164,33 +169,30 @@ AppCacheJob* AppCacheRequestHandler::MaybeLoadFallbackForResponse(
if (!host_ ||
!AppCacheRequest::IsSchemeAndMethodSupportedForAppCache(request_.get()) ||
cache_entry_not_found_)
- return NULL;
+ return nullptr;
if (!found_fallback_entry_.has_response_id())
- return NULL;
+ return nullptr;
if (request_->IsCancelled()) {
// 6.9.6, step 4: But not if the user canceled the download.
- return NULL;
+ return nullptr;
}
// We don't fallback for responses that we delivered.
if (job_.get()) {
- // In the network service world the existing job initiates a fallback
- // response request with the exception being a job which already
- // delivered an AppCached or error response.
if (!base::FeatureList::IsEnabled(features::kNetworkService)) {
DCHECK(!job_->IsDeliveringNetworkResponse());
- return NULL;
+ return nullptr;
} else if (job_->IsDeliveringAppCacheResponse() ||
job_->IsDeliveringErrorResponse()) {
- return NULL;
+ return nullptr;
}
}
if (request_->IsSuccess()) {
int code_major = request_->GetResponseCode() / 100;
if (code_major !=4 && code_major != 5)
- return NULL;
+ return nullptr;
// Servers can override the fallback behavior with a response header.
const std::string kFallbackOverrideHeader(
@@ -200,16 +202,13 @@ AppCacheJob* AppCacheRequestHandler::MaybeLoadFallbackForResponse(
std::string header_value;
header_value = request_->GetResponseHeaderByName(kFallbackOverrideHeader);
if (header_value == kFallbackOverrideValue)
- return NULL;
+ return nullptr;
}
// 6.9.6, step 4: If this results in a 4xx or 5xx status code
// or there were network errors, get the resource of the fallback entry.
- // In network service land, the job initiates a fallback request. We reuse
- // the existing job to deliver the fallback response.
- std::unique_ptr<AppCacheJob> job =
- MaybeCreateJobForFallback(network_delegate);
+ std::unique_ptr<AppCacheJob> job = CreateJob(network_delegate);
DeliverAppCachedResponse(found_fallback_entry_, found_cache_id_,
found_manifest_url_, true,
@@ -254,29 +253,6 @@ void AppCacheRequestHandler::MaybeCompleteCrossSiteTransferInOldProcess(
CompleteCrossSiteTransfer(old_process_id_, old_host_id_);
}
-AppCacheJob* AppCacheRequestHandler::MaybeCreateSubresourceLoader(
- std::unique_ptr<SubresourceLoadInfo> subresource_load_info,
- URLLoaderFactoryGetter* loader_factory_getter,
- AppCacheSubresourceURLFactory* subresource_factory) {
- DCHECK(!is_main_resource());
- DCHECK(base::FeatureList::IsEnabled(features::kNetworkService));
- job_ = nullptr;
-
- subresource_load_info_ = std::move(subresource_load_info);
- network_url_loader_factory_getter_ = loader_factory_getter;
- request_->AsURLLoaderRequest()->set_request(subresource_load_info_->request);
-
- AppCacheJob* job = MaybeLoadResource(nullptr);
- if (!job)
- return nullptr;
-
- AppCacheURLLoaderJob* loader_job = job->AsURLLoaderJob();
- // The job takes ownership of the handler.
- loader_job->SetRequestHandlerAndFactory(
- std::unique_ptr<AppCacheRequestHandler>(this), subresource_factory);
- return job;
-}
-
// static
std::unique_ptr<AppCacheRequestHandler>
AppCacheRequestHandler::InitializeForNavigationNetworkService(
@@ -294,12 +270,13 @@ AppCacheRequestHandler::InitializeForNavigationNetworkService(
void AppCacheRequestHandler::OnDestructionImminent(AppCacheHost* host) {
storage()->CancelDelegateCallbacks(this);
- host_ = NULL; // no need to RemoveObserver, the host is being deleted
+ host_ = nullptr; // no need to RemoveObserver, the host is being deleted
// Since the host is being deleted, we don't have to complete any job
// that is current running. It's destined for the bit bucket anyway.
if (job_.get()) {
- job_->Kill();
+ if (job_->AsURLRequestJob())
+ job_->AsURLRequestJob()->Kill();
job_.reset();
}
}
@@ -334,10 +311,6 @@ void AppCacheRequestHandler::DeliverAppCachedResponse(
host_->NotifyMainResourceIsNamespaceEntry(namespace_entry_url);
job_->DeliverAppCachedResponse(manifest_url, cache_id, entry, is_fallback);
- // In the network service world, we need to release the AppCacheJob instance
- // created for handling navigation requests. These instances will get
- // destroyed when the client disconnects.
- navigation_request_job_.release();
}
void AppCacheRequestHandler::DeliverErrorResponse() {
@@ -345,10 +318,6 @@ void AppCacheRequestHandler::DeliverErrorResponse() {
DCHECK_EQ(kAppCacheNoCacheId, cache_id_);
DCHECK(manifest_url_.is_empty());
job_->DeliverErrorResponse();
- // In the network service world, we need to release the AppCacheJob instance
- // created for handling navigation requests. These instances will get
- // destroyed when the client disconnects.
- navigation_request_job_.release();
}
void AppCacheRequestHandler::DeliverNetworkResponse() {
@@ -356,12 +325,10 @@ void AppCacheRequestHandler::DeliverNetworkResponse() {
DCHECK_EQ(kAppCacheNoCacheId, cache_id_);
DCHECK(manifest_url_.is_empty());
job_->DeliverNetworkResponse();
- // In the network service world, we need to destroy the AppCacheJob instance
- // created for handling navigation requests.
- navigation_request_job_.reset(nullptr);
}
-void AppCacheRequestHandler::OnPrepareToRestart() {
+void AppCacheRequestHandler::OnPrepareToRestartURLRequest() {
+ DCHECK(job_->AsURLRequestJob());
DCHECK(job_->IsDeliveringNetworkResponse() || job_->IsCacheEntryNotFound());
// Any information about the source of the response is no longer relevant.
@@ -378,29 +345,21 @@ void AppCacheRequestHandler::OnPrepareToRestart() {
std::unique_ptr<AppCacheJob> AppCacheRequestHandler::CreateJob(
net::NetworkDelegate* network_delegate) {
- std::unique_ptr<AppCacheJob> job = AppCacheJob::Create(
- is_main_resource(), host_, storage(), request_.get(), network_delegate,
- base::BindOnce(&AppCacheRequestHandler::OnPrepareToRestart,
- base::Unretained(this)),
- std::move(subresource_load_info_),
- network_url_loader_factory_getter_.get());
+ std::unique_ptr<AppCacheJob> job;
+ if (base::FeatureList::IsEnabled(features::kNetworkService)) {
+ job.reset(new AppCacheURLLoaderJob(request_->AsURLLoaderRequest(),
+ storage(), std::move(loader_callback_)));
+ } else {
+ job.reset(new AppCacheURLRequestJob(
+ request_->GetURLRequest(), network_delegate, storage(), host_,
+ is_main_resource(),
+ base::BindOnce(&AppCacheRequestHandler::OnPrepareToRestartURLRequest,
+ base::Unretained(this))));
+ }
job_ = job->GetWeakPtr();
return job;
}
-std::unique_ptr<AppCacheJob> AppCacheRequestHandler::MaybeCreateJobForFallback(
- net::NetworkDelegate* network_delegate) {
- if (!base::FeatureList::IsEnabled(features::kNetworkService) ||
- IsMainResourceType(resource_type_)) {
- return CreateJob(network_delegate);
- }
- // In network service land, the job initiates a fallback request. We reuse
- // the existing job to deliver the fallback response.
- DCHECK(job_.get());
- job_->set_delivery_type(AppCacheJob::AWAITING_DELIVERY_ORDERS);
- return std::unique_ptr<AppCacheJob>(job_.get());
-}
-
// Main-resource handling ----------------------------------------------
std::unique_ptr<AppCacheJob> AppCacheRequestHandler::MaybeLoadMainResource(
@@ -411,7 +370,7 @@ std::unique_ptr<AppCacheJob> AppCacheRequestHandler::MaybeLoadMainResource(
// If a page falls into the scope of a ServiceWorker, any matching AppCaches
// should be ignored. This depends on the ServiceWorker handler being invoked
// prior to the AppCache handler.
- // TODO(ananta)
+ // TODO(ananta/michaeln)
// We need to handle this for AppCache requests initiated for the network
// service
if (request_->GetURLRequest() &&
@@ -512,6 +471,18 @@ void AppCacheRequestHandler::OnMainResponseFound(
}
}
+// NetworkService loading:
+void AppCacheRequestHandler::RunLoaderCallbackForMainResource(
+ LoaderCallback callback,
+ StartLoaderCallback start_loader_callback) {
+ // For now let |this| always also return the subresource loader
+ // if (and only if) this returns a non-null |start_loader_callback|
+ // for handling the main resource.
+ if (start_loader_callback)
+ should_create_subresource_loader_ = true;
+ std::move(callback).Run(std::move(start_loader_callback));
+}
+
// Sub-resource handling ----------------------------------------------
std::unique_ptr<AppCacheJob> AppCacheRequestHandler::MaybeLoadSubResource(
@@ -612,47 +583,107 @@ void AppCacheRequestHandler::MaybeCreateLoader(
const ResourceRequest& resource_request,
ResourceContext* resource_context,
LoaderCallback callback) {
- // MaybeLoadMainResource will invoke navigation_request_job's methods
- // asynchronously via AppCacheStorage::Delegate.
+ loader_callback_ =
+ base::BindOnce(&AppCacheRequestHandler::RunLoaderCallbackForMainResource,
+ weak_factory_.GetWeakPtr(), std::move(callback));
request_->AsURLLoaderRequest()->set_request(resource_request);
- navigation_request_job_.reset(MaybeLoadResource(nullptr));
- if (!navigation_request_job_.get()) {
- std::move(callback).Run(StartLoaderCallback());
- return;
+ MaybeLoadResource(nullptr);
+ // If a job is created, the job assumes ownership of the callback and
+ // the responsibility to call it. If no job is created, we call it with
+ // an empty StartLoaderCallback to let our client we have no loader for
+ // this resource request.
+ if (loader_callback_)
+ std::move(loader_callback_).Run(StartLoaderCallback());
+}
+
+bool AppCacheRequestHandler::MaybeCreateLoaderForResponse(
+ const ResourceResponseHead& response,
+ mojom::URLLoaderPtr* loader,
+ mojom::URLLoaderClientRequest* client_request) {
+ // The sync interface of this method is inherited from the
+ // URLLoaderRequestHandler class. The LoaderCallback created here is invoked
+ // synchronously in fallback cases, and only when there really is a loader
+ // to start.
+ bool was_called = false;
+ loader_callback_ = base::BindOnce(
+ [](mojom::URLLoaderPtr* loader,
+ mojom::URLLoaderClientRequest* client_request, bool* was_called,
+ StartLoaderCallback start_function) {
+ *was_called = true;
+ mojom::URLLoaderClientPtr client;
+ *client_request = mojo::MakeRequest(&client);
+ std::move(start_function)
+ .Run(mojo::MakeRequest(loader), std::move(client));
+ },
+ loader, client_request, &was_called);
+ request_->AsURLLoaderRequest()->set_response(response);
+ if (!MaybeLoadFallbackForResponse(nullptr)) {
+ DCHECK(!was_called);
+ loader_callback_.Reset();
+ return false;
}
- navigation_request_job_->AsURLLoaderJob()->set_main_resource_loader_callback(
- std::move(callback));
+ DCHECK(was_called);
+ return true;
}
-mojom::URLLoaderFactoryPtr
-AppCacheRequestHandler::MaybeCreateSubresourceFactory() {
- mojom::URLLoaderFactoryPtr factory_ptr = nullptr;
+base::Optional<SubresourceLoaderParams>
+AppCacheRequestHandler::MaybeCreateSubresourceLoaderParams() {
+ if (!should_create_subresource_loader_)
+ return base::nullopt;
// The factory is destroyed when the renderer drops the connection.
+ mojom::URLLoaderFactoryPtr factory_ptr;
AppCacheSubresourceURLFactory::CreateURLLoaderFactory(
network_url_loader_factory_getter_.get(), appcache_host_, &factory_ptr);
- return factory_ptr;
+ SubresourceLoaderParams params;
+ params.loader_factory_info = factory_ptr.PassInterface();
+ return params;
}
-bool AppCacheRequestHandler::MaybeCreateLoaderForResponse(
+void AppCacheRequestHandler::MaybeCreateSubresourceLoader(
+ const ResourceRequest& resource_request,
+ LoaderCallback loader_callback) {
+ DCHECK(!job_);
+ DCHECK(!is_main_resource());
+ // Subresource loads start out just like a main resource loads, but they go
+ // down different branches along the way to completion.
+ MaybeCreateLoader(resource_request, nullptr, std::move(loader_callback));
+}
+
+void AppCacheRequestHandler::MaybeFallbackForSubresourceResponse(
const ResourceResponseHead& response,
- mojom::URLLoaderPtr* loader,
- mojom::URLLoaderClientRequest* client_request) {
+ LoaderCallback loader_callback) {
+ DCHECK(!job_);
+ DCHECK(!is_main_resource());
+ loader_callback_ = std::move(loader_callback);
request_->AsURLLoaderRequest()->set_response(response);
- // The AppCacheJob will get destroyed when the client connection is
- // dropped.
- AppCacheJob* job = MaybeLoadFallbackForResponse(nullptr);
- if (job) {
- mojom::URLLoaderClientPtr client;
- *client_request = mojo::MakeRequest(&client);
- mojom::URLLoaderRequest loader_request = mojo::MakeRequest(loader);
-
- job->AsURLLoaderJob()->BindRequest(std::move(client),
- std::move(loader_request));
- return true;
- }
- return false;
+ MaybeLoadFallbackForResponse(nullptr);
+ if (loader_callback_)
+ std::move(loader_callback_).Run(StartLoaderCallback());
+}
+
+void AppCacheRequestHandler::MaybeFallbackForSubresourceRedirect(
+ const net::RedirectInfo& redirect_info,
+ LoaderCallback loader_callback) {
+ DCHECK(!job_);
+ DCHECK(!is_main_resource());
+ loader_callback_ = std::move(loader_callback);
+ MaybeLoadFallbackForRedirect(nullptr, redirect_info.new_url);
+ if (loader_callback_)
+ std::move(loader_callback_).Run(StartLoaderCallback());
+}
+
+void AppCacheRequestHandler::MaybeFollowSubresourceRedirect(
+ const net::RedirectInfo& redirect_info,
+ LoaderCallback loader_callback) {
+ DCHECK(!job_);
+ DCHECK(!is_main_resource());
+ loader_callback_ = std::move(loader_callback);
+ request_->AsURLLoaderRequest()->UpdateWithRedirectInfo(redirect_info);
+ MaybeLoadResource(nullptr);
+ if (loader_callback_)
+ std::move(loader_callback_).Run(StartLoaderCallback());
}
// static
diff --git a/chromium/content/browser/appcache/appcache_request_handler.h b/chromium/content/browser/appcache/appcache_request_handler.h
index 4f457094537..de3e9b9e611 100644
--- a/chromium/content/browser/appcache/appcache_request_handler.h
+++ b/chromium/content/browser/appcache/appcache_request_handler.h
@@ -35,7 +35,6 @@ class AppCacheRequest;
class AppCacheRequestHandlerTest;
class AppCacheURLRequestJob;
class AppCacheHost;
-struct SubresourceLoadInfo;
// An instance is created for each net::URLRequest. The instance survives all
// http transactions involved in the processing of its net::URLRequest, and is
@@ -52,6 +51,9 @@ class CONTENT_EXPORT AppCacheRequestHandler
~AppCacheRequestHandler() override;
// These are called on each request intercept opportunity.
+ // When the NetworkService is not enabled, the AppCacheInterceptor calls these
+ // methods directly. When the NetworkService is enabled, the various
+ // MaybeCreateLoader methods below call call these internally.
AppCacheJob* MaybeLoadResource(net::NetworkDelegate* network_delegate);
AppCacheJob* MaybeLoadFallbackForRedirect(
net::NetworkDelegate* network_delegate,
@@ -72,24 +74,40 @@ class CONTENT_EXPORT AppCacheRequestHandler
return !host_ || (host_->service() == service);
}
- // This method is called in the network service code path for creating a job
- // for handling subresource load requests.
- // The |subresource_load_info| parameter contains the information required to
- // service the load request.
- // The |loader_factory_getter| parameter points to the URLLoaderFactoryGetter
- // instance which provides functionality to return the default network
- // URLLoader interface.
- // The |subresource_factory| parameter points to the AppCache URLLoader
- // factory which serves subresources to the client.
- AppCacheJob* MaybeCreateSubresourceLoader(
- std::unique_ptr<SubresourceLoadInfo> subresource_load_info,
- URLLoaderFactoryGetter* loader_factory_getter,
- AppCacheSubresourceURLFactory* subresource_factory);
+ // NetworkService loading
- static bool IsMainResourceType(ResourceType type) {
- return IsResourceTypeFrame(type) ||
- type == RESOURCE_TYPE_SHARED_WORKER;
- }
+ // URLLoaderRequestHandler overrides - main resource loading.
+ // These methods are used by the NavigationURLLoaderNetworkService.
+ // Internally they use same methods used by the network library based impl,
+ // MaybeLoadResource and MaybeLoadFallbackForResponse.
+ // Eventually one of the Deliver*Response() methods is called and the
+ // LoaderCallback is invoked.
+ void MaybeCreateLoader(const ResourceRequest& resource_request,
+ ResourceContext* resource_context,
+ LoaderCallback callback) override;
+ // MaybeCreateLoaderForResponse always returns synchronously.
+ bool MaybeCreateLoaderForResponse(
+ const ResourceResponseHead& response,
+ mojom::URLLoaderPtr* loader,
+ mojom::URLLoaderClientRequest* client_request) override;
+ base::Optional<SubresourceLoaderParams> MaybeCreateSubresourceLoaderParams()
+ override;
+
+ // These methods are used for subresource loading by the
+ // AppCacheSubresourceURLFactory::SubresourceLoader class.
+ // Internally they use same methods used by the network library based impl,
+ // MaybeLoadResource, MaybeLoadFallbackForResponse, and
+ // MaybeLoadFallbackForRedirect. Eventually one of the Deliver*Response()
+ // methods is called and the LoaderCallback is invoked.
+ void MaybeCreateSubresourceLoader(const ResourceRequest& resource_request,
+ LoaderCallback callback);
+ void MaybeFallbackForSubresourceResponse(const ResourceResponseHead& response,
+ LoaderCallback callback);
+ void MaybeFallbackForSubresourceRedirect(
+ const net::RedirectInfo& redirect_info,
+ LoaderCallback callback);
+ void MaybeFollowSubresourceRedirect(const net::RedirectInfo& redirect_info,
+ LoaderCallback callback);
static std::unique_ptr<AppCacheRequestHandler>
InitializeForNavigationNetworkService(
@@ -97,14 +115,17 @@ class CONTENT_EXPORT AppCacheRequestHandler
AppCacheNavigationHandleCore* appcache_handle_core,
URLLoaderFactoryGetter* url_loader_factory_getter);
+ static bool IsMainResourceType(ResourceType type) {
+ return IsResourceTypeFrame(type) || type == RESOURCE_TYPE_SHARED_WORKER;
+ }
+
// Called by unittests to indicate that we are in test mode.
static void SetRunningInTests(bool in_tests);
-
- // Returns true if we are running in tests.
static bool IsRunningInTests();
private:
friend class AppCacheHost;
+ friend class AppCacheRequestHandlerTest;
// Callers should use AppCacheHost::CreateRequestHandler.
AppCacheRequestHandler(AppCacheHost* host,
@@ -130,17 +151,13 @@ class CONTENT_EXPORT AppCacheRequestHandler
// Called just before the request is restarted. Grabs the reason for
// restarting, so can correctly continue to handle the request.
- void OnPrepareToRestart();
+ void OnPrepareToRestartURLRequest();
// Helper method to create an AppCacheJob and populate job_.
// Caller takes ownership of returned value.
std::unique_ptr<AppCacheJob> CreateJob(
net::NetworkDelegate* network_delegate);
- // Helper method to create an AppCacheJob for fallback responses.
- std::unique_ptr<AppCacheJob> MaybeCreateJobForFallback(
- net::NetworkDelegate* network_delegate);
-
// Helper to retrieve a pointer to the storage object.
AppCacheStorage* storage() const;
@@ -163,6 +180,16 @@ class CONTENT_EXPORT AppCacheRequestHandler
int64_t group_id,
const GURL& mainfest_url) override;
+ // NetworkService loading:
+ // Called when a |callback| that is originally given to
+ // MaybeCreateLoader() runs for the main resource.
+ // This flips should_create_subresource_loader_ if non-null
+ // |start_loader_callback| is given, and then (always) run
+ // |callback| passing in |start_loader_callback|.
+ void RunLoaderCallbackForMainResource(
+ LoaderCallback callback,
+ StartLoaderCallback start_loader_callback);
+
// Sub-resource loading -------------------------------------
// Dedicated worker and all manner of sub-resources are handled here.
@@ -173,20 +200,6 @@ class CONTENT_EXPORT AppCacheRequestHandler
// AppCacheHost::Observer override
void OnCacheSelectionComplete(AppCacheHost* host) override;
- // Network service loading
-
- // URLLoaderRequestHandler overrides
- // These functions are invoked for loading AppCache content for the frame and
- // for subresources.
- void MaybeCreateLoader(const ResourceRequest& resource_request,
- ResourceContext* resource_context,
- LoaderCallback callback) override;
- mojom::URLLoaderFactoryPtr MaybeCreateSubresourceFactory() override;
- bool MaybeCreateLoaderForResponse(
- const ResourceResponseHead& response,
- mojom::URLLoaderPtr* loader,
- mojom::URLLoaderClientRequest* client_request) override;
-
// Data members -----------------------------------------------
// What host we're servicing a request for.
@@ -249,25 +262,22 @@ class CONTENT_EXPORT AppCacheRequestHandler
// Network service related members.
- // In the network service world we are queried via the URLLoaderRequestHandler
- // interface to see if the navigation request can be handled via the
- // AppCache. We hold onto the AppCache job created here until the client
- // binds to it (Serviced via AppCache). If the request cannot be handled via
- // the AppCache, we delete the job.
- std::unique_ptr<AppCacheJob> navigation_request_job_;
+ LoaderCallback loader_callback_;
+
+ // Flipped to true if AppCache wants to handle subresource requests
+ // (i.e. when |loader_callback_| is fired with a non-null callback for
+ // non-error cases.
+ bool should_create_subresource_loader_ = false;
// Points to the getter for the network URL loader.
scoped_refptr<URLLoaderFactoryGetter> network_url_loader_factory_getter_;
- friend class content::AppCacheRequestHandlerTest;
-
- // Subresource load information.
- std::unique_ptr<SubresourceLoadInfo> subresource_load_info_;
-
// The AppCache host instance. We pass this to the
// AppCacheSubresourceURLFactory instance on creation.
base::WeakPtr<AppCacheHost> appcache_host_;
+ base::WeakPtrFactory<AppCacheRequestHandler> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(AppCacheRequestHandler);
};
diff --git a/chromium/content/browser/appcache/appcache_request_handler_unittest.cc b/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
index 8b32e5212e0..4b6191b3a3a 100644
--- a/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
@@ -29,6 +29,7 @@
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_backend_impl.h"
#include "content/browser/appcache/appcache_job.h"
+#include "content/browser/appcache/appcache_url_loader_job.h"
#include "content/browser/appcache/appcache_url_loader_request.h"
#include "content/browser/appcache/appcache_url_request.h"
#include "content/browser/appcache/appcache_url_request_job.h"
@@ -157,18 +158,18 @@ class AppCacheRequestHandlerTest
public:
MockURLRequestJobFactory() {}
- ~MockURLRequestJobFactory() override { DCHECK(!job_); }
+ ~MockURLRequestJobFactory() override { DCHECK(!request_job_); }
void SetJob(std::unique_ptr<net::URLRequestJob> job) {
- job_ = std::move(job);
+ request_job_ = std::move(job);
}
net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
const std::string& scheme,
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
- if (job_)
- return job_.release();
+ if (request_job_)
+ return request_job_.release();
// Some of these tests trigger UpdateJobs which start URLRequests.
// We short circuit those be returning error jobs.
@@ -198,7 +199,7 @@ class AppCacheRequestHandlerTest
}
private:
- mutable std::unique_ptr<net::URLRequestJob> job_;
+ mutable std::unique_ptr<net::URLRequestJob> request_job_;
};
static void SetUpTestCase() {
@@ -216,7 +217,7 @@ class AppCacheRequestHandlerTest
// Test harness --------------------------------------------------
AppCacheRequestHandlerTest()
- : host_(NULL), request_(nullptr), request_handler_type_(GetParam()) {
+ : host_(nullptr), request_(nullptr), request_handler_type_(GetParam()) {
AppCacheRequestHandler::SetRunningInTests(true);
if (request_handler_type_ == URLLOADER)
feature_list_.InitAndEnableFeature(features::kNetworkService);
@@ -259,7 +260,8 @@ class AppCacheRequestHandlerTest
void TearDownTest() {
DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
- job_ = NULL;
+ appcache_url_request_job_.reset();
+ appcache_url_loader_job_.reset();
handler_.reset();
request_ = nullptr;
url_request_.reset();
@@ -269,7 +271,7 @@ class AppCacheRequestHandlerTest
mock_policy_.reset();
job_factory_.reset();
empty_context_.reset();
- host_ = NULL;
+ host_ = nullptr;
}
void TestFinished() {
@@ -302,6 +304,25 @@ class AppCacheRequestHandlerTest
task_stack_.pop();
}
+ void SetAppCacheJob(AppCacheJob* job) {
+ if (!job) {
+ appcache_url_request_job_.reset();
+ appcache_url_loader_job_ = nullptr;
+ return;
+ }
+ if (request_handler_type_ == URLREQUEST)
+ appcache_url_request_job_.reset(job->AsURLRequestJob());
+ else
+ appcache_url_loader_job_ = job->AsURLLoaderJob()->GetDerivedWeakPtr();
+ }
+
+ AppCacheJob* job() {
+ if (request_handler_type_ == URLREQUEST)
+ return appcache_url_request_job_.get();
+ else
+ return appcache_url_loader_job_.get();
+ }
+
// MainResource_Miss --------------------------------------------------
void MainResource_Miss() {
@@ -313,17 +334,17 @@ class AppCacheRequestHandlerTest
RESOURCE_TYPE_MAIN_FRAME));
EXPECT_TRUE(handler_.get());
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsWaiting());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsWaiting());
// We have to wait for completion of storage->FindResponseForMainRequest.
ScheduleNextTask();
}
void Verify_MainResource_Miss() {
- EXPECT_FALSE(job_->IsWaiting());
- EXPECT_TRUE(job_->IsDeliveringNetworkResponse());
+ EXPECT_FALSE(job()->IsWaiting());
+ EXPECT_TRUE(job()->IsDeliveringNetworkResponse());
int64_t cache_id = kAppCacheNoCacheId;
GURL manifest_url;
@@ -332,12 +353,11 @@ class AppCacheRequestHandlerTest
EXPECT_EQ(GURL(), manifest_url);
EXPECT_EQ(0, handler_->found_group_id_);
- std::unique_ptr<AppCacheJob> fallback_job(
- handler_->MaybeLoadFallbackForRedirect(nullptr,
- GURL("http://blah/redirect")));
- EXPECT_FALSE(fallback_job);
- fallback_job.reset(handler_->MaybeLoadFallbackForResponse(nullptr));
- EXPECT_FALSE(fallback_job);
+ SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
+ nullptr, GURL("http://blah/redirect")));
+ EXPECT_FALSE(job());
+ SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
+ EXPECT_FALSE(job());
EXPECT_TRUE(host_->preferred_manifest_url().is_empty());
@@ -360,17 +380,17 @@ class AppCacheRequestHandlerTest
GURL(), AppCacheEntry(),
1, 2, GURL("http://blah/manifest/"));
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsWaiting());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsWaiting());
// We have to wait for completion of storage->FindResponseForMainRequest.
ScheduleNextTask();
}
void Verify_MainResource_Hit() {
- EXPECT_FALSE(job_->IsWaiting());
- EXPECT_TRUE(job_->IsDeliveringAppCacheResponse());
+ EXPECT_FALSE(job()->IsWaiting());
+ EXPECT_TRUE(job()->IsDeliveringAppCacheResponse());
int64_t cache_id = kAppCacheNoCacheId;
GURL manifest_url;
@@ -379,9 +399,8 @@ class AppCacheRequestHandlerTest
EXPECT_EQ(GURL("http://blah/manifest/"), manifest_url);
EXPECT_EQ(2, handler_->found_group_id_);
- std::unique_ptr<AppCacheJob> fallback_job(
- handler_->MaybeLoadFallbackForResponse(nullptr));
- EXPECT_FALSE(fallback_job);
+ SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
+ EXPECT_FALSE(job());
EXPECT_EQ(GURL("http://blah/manifest/"),
host_->preferred_manifest_url());
@@ -406,9 +425,9 @@ class AppCacheRequestHandlerTest
AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
1, 2, GURL("http://blah/manifest/"));
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsWaiting());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsWaiting());
// We have to wait for completion of storage->FindResponseForMainRequest.
ScheduleNextTask();
@@ -422,7 +441,7 @@ class AppCacheRequestHandlerTest
net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.length()));
if (request_handler_type_ == URLREQUEST) {
- job_factory_->SetJob(base::MakeUnique<MockURLRequestJob>(
+ job_factory_->SetJob(std::make_unique<MockURLRequestJob>(
url_request_.get(), nullptr, info));
request_->AsURLRequest()->GetURLRequest()->Start();
// All our simulation needs to satisfy are the DCHECK's for the request
@@ -438,7 +457,7 @@ class AppCacheRequestHandlerTest
void SimulateResponseInfo(const net::HttpResponseInfo& info) {
if (request_handler_type_ == URLREQUEST) {
- job_factory_->SetJob(base::MakeUnique<MockURLRequestJob>(
+ job_factory_->SetJob(std::make_unique<MockURLRequestJob>(
url_request_.get(), nullptr, info));
request_->AsURLRequest()->GetURLRequest()->Start();
} else {
@@ -449,25 +468,27 @@ class AppCacheRequestHandlerTest
}
void Verify_MainResource_Fallback() {
- EXPECT_FALSE(job_->IsWaiting());
- EXPECT_TRUE(job_->IsDeliveringNetworkResponse());
+ EXPECT_FALSE(job()->IsWaiting());
+ EXPECT_TRUE(job()->IsDeliveringNetworkResponse());
// The handler expects to the job to tell it that the request is going to
// be restarted before it sees the next request.
- handler_->OnPrepareToRestart();
+ if (request_handler_type_ == URLREQUEST) {
+ handler_->OnPrepareToRestartURLRequest();
- // When the request is restarted, the existing job is dropped so a
- // real network job gets created. We expect NULL here which will cause
- // the net library to create a real job.
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_FALSE(job_.get());
+ // When the request is restarted, the existing job is dropped so a
+ // real network job gets created. We expect NULL here which will cause
+ // the net library to create a real job.
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_FALSE(job());
+ }
// Simulate an http error of the real network job.
SimulateResponseCode(500);
- job_.reset(handler_->MaybeLoadFallbackForResponse(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsDeliveringAppCacheResponse());
+ SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsDeliveringAppCacheResponse());
int64_t cache_id = kAppCacheNoCacheId;
GURL manifest_url;
@@ -500,27 +521,29 @@ class AppCacheRequestHandlerTest
AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
1, 2, GURL("http://blah/manifest/"));
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsWaiting());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsWaiting());
// We have to wait for completion of storage->FindResponseForMainRequest.
ScheduleNextTask();
}
void Verify_MainResource_FallbackOverride() {
- EXPECT_FALSE(job_->IsWaiting());
- EXPECT_TRUE(job_->IsDeliveringNetworkResponse());
+ EXPECT_FALSE(job()->IsWaiting());
+ EXPECT_TRUE(job()->IsDeliveringNetworkResponse());
// The handler expects to the job to tell it that the request is going to
// be restarted before it sees the next request.
- handler_->OnPrepareToRestart();
+ if (request_handler_type_ == URLREQUEST) {
+ handler_->OnPrepareToRestartURLRequest();
- // When the request is restarted, the existing job is dropped so a
- // real network job gets created. We expect NULL here which will cause
- // the net library to create a real job.
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_FALSE(job_.get());
+ // When the request is restarted, the existing job is dropped so a
+ // real network job gets created. We expect NULL here which will cause
+ // the net library to create a real job.
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_FALSE(job());
+ }
// Simulate an http error of the real network job, but with custom
// headers that override the fallback behavior.
@@ -533,8 +556,8 @@ class AppCacheRequestHandlerTest
std::string(kOverrideHeaders, arraysize(kOverrideHeaders)));
SimulateResponseInfo(info);
- job_.reset(handler_->MaybeLoadFallbackForResponse(nullptr));
- EXPECT_FALSE(job_.get());
+ SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
+ EXPECT_FALSE(job());
// GetExtraResponseInfo should return no information.
int64_t cache_id = kAppCacheNoCacheId;
@@ -569,16 +592,15 @@ class AppCacheRequestHandlerTest
RESOURCE_TYPE_SUB_RESOURCE));
EXPECT_TRUE(handler_.get());
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsDeliveringErrorResponse());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsDeliveringErrorResponse());
- std::unique_ptr<AppCacheJob> fallback_job(
- handler_->MaybeLoadFallbackForRedirect(nullptr,
- GURL("http://blah/redirect")));
- EXPECT_FALSE(fallback_job);
- fallback_job.reset(handler_->MaybeLoadFallbackForResponse(nullptr));
- EXPECT_FALSE(fallback_job);
+ SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
+ nullptr, GURL("http://blah/redirect")));
+ EXPECT_FALSE(job());
+ SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
+ EXPECT_FALSE(job());
TestFinished();
}
@@ -594,20 +616,19 @@ class AppCacheRequestHandlerTest
EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
RESOURCE_TYPE_SUB_RESOURCE));
EXPECT_TRUE(handler_.get());
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsWaiting());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsWaiting());
- host_->FinishCacheSelection(cache.get(), NULL);
- EXPECT_FALSE(job_->IsWaiting());
- EXPECT_TRUE(job_->IsDeliveringErrorResponse());
+ host_->FinishCacheSelection(cache.get(), nullptr);
+ EXPECT_FALSE(job()->IsWaiting());
+ EXPECT_TRUE(job()->IsDeliveringErrorResponse());
- std::unique_ptr<AppCacheJob> fallback_job(
- handler_->MaybeLoadFallbackForRedirect(nullptr,
- GURL("http://blah/redirect")));
- EXPECT_FALSE(fallback_job);
- fallback_job.reset(handler_->MaybeLoadFallbackForResponse(nullptr));
- EXPECT_FALSE(fallback_job);
+ SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
+ nullptr, GURL("http://blah/redirect")));
+ EXPECT_FALSE(job());
+ SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
+ EXPECT_FALSE(job());
TestFinished();
}
@@ -623,16 +644,15 @@ class AppCacheRequestHandlerTest
EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
RESOURCE_TYPE_SUB_RESOURCE));
EXPECT_TRUE(handler_.get());
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsDeliveringAppCacheResponse());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsDeliveringAppCacheResponse());
- std::unique_ptr<AppCacheJob> fallback_job(
- handler_->MaybeLoadFallbackForRedirect(nullptr,
- GURL("http://blah/redirect")));
- EXPECT_FALSE(fallback_job);
- fallback_job.reset(handler_->MaybeLoadFallbackForResponse(nullptr));
- EXPECT_FALSE(fallback_job);
+ SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
+ nullptr, GURL("http://blah/redirect")));
+ EXPECT_FALSE(job());
+ SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
+ EXPECT_FALSE(job());
TestFinished();
}
@@ -650,34 +670,16 @@ class AppCacheRequestHandlerTest
EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
RESOURCE_TYPE_SUB_RESOURCE));
EXPECT_TRUE(handler_.get());
- job_.reset(handler_->MaybeLoadResource(nullptr));
- // If the request goes to the network, the URLRequest job is destroyed. The
- // URLLoader job is destroyed when the URLLoaderClient disconnects.
- if (request_handler_type_ == URLREQUEST) {
- EXPECT_FALSE(job_.get());
- } else {
- // In the URLLoader world, the same job instance is used to provide the
- // fallback.
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsDeliveringNetworkResponse());
- }
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_FALSE(job());
- std::unique_ptr<AppCacheJob> redirect_fallback_job;
- redirect_fallback_job.reset(handler_->MaybeLoadFallbackForRedirect(
+ SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
nullptr, GURL("http://not_blah/redirect")));
- EXPECT_TRUE(redirect_fallback_job.get());
- EXPECT_TRUE(redirect_fallback_job->IsDeliveringAppCacheResponse());
-
- if (request_handler_type_ == URLLOADER) {
- // In the URLLoader world, the same job instance is used to provide the
- // fallback.
- EXPECT_EQ(job_.get(), redirect_fallback_job.get());
- job_.release();
- }
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsDeliveringAppCacheResponse());
- std::unique_ptr<AppCacheJob> fallback_job(
- handler_->MaybeLoadFallbackForResponse(nullptr));
- EXPECT_FALSE(fallback_job);
+ SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
+ EXPECT_FALSE(job());
TestFinished();
}
@@ -695,28 +697,16 @@ class AppCacheRequestHandlerTest
EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
RESOURCE_TYPE_SUB_RESOURCE));
EXPECT_TRUE(handler_.get());
- job_.reset(handler_->MaybeLoadResource(nullptr));
- if (request_handler_type_ == URLREQUEST) {
- EXPECT_FALSE(job_.get());
- } else {
- // In the URLLoader world, the same job instance is used to provide the
- // fallback.
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsDeliveringNetworkResponse());
- }
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_FALSE(job());
- std::unique_ptr<AppCacheJob> fallback_job(
- handler_->MaybeLoadFallbackForRedirect(nullptr,
- GURL("http://blah/redirect")));
- EXPECT_FALSE(fallback_job);
-
- // Fallback responses are provided by a new job instance.
- if (request_handler_type_ == URLLOADER)
- job_.reset(nullptr);
+ SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
+ nullptr, GURL("http://blah/redirect")));
+ EXPECT_FALSE(job());
SimulateResponseCode(200);
- fallback_job.reset(handler_->MaybeLoadFallbackForResponse(nullptr));
- EXPECT_FALSE(fallback_job);
+ SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
+ EXPECT_FALSE(job());
TestFinished();
}
@@ -735,22 +725,14 @@ class AppCacheRequestHandlerTest
EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
RESOURCE_TYPE_SUB_RESOURCE));
EXPECT_TRUE(handler_.get());
- job_.reset(handler_->MaybeLoadResource(nullptr));
- // If the request goes to the network, the URLRequest job is destroyed. The
- // URLLoader job is destroyed when the URLLoaderClient disconnects.
- if (request_handler_type_ == URLREQUEST) {
- EXPECT_FALSE(job_.get());
- } else {
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsDeliveringNetworkResponse());
- }
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_FALSE(job());
- std::unique_ptr<AppCacheJob> fallback_job(
- handler_->MaybeLoadFallbackForRedirect(nullptr,
- GURL("http://blah/redirect")));
- EXPECT_FALSE(fallback_job);
- fallback_job.reset(handler_->MaybeLoadFallbackForResponse(nullptr));
- EXPECT_FALSE(fallback_job);
+ SetAppCacheJob(handler_->MaybeLoadFallbackForRedirect(
+ nullptr, GURL("http://blah/redirect")));
+ EXPECT_FALSE(job());
+ SetAppCacheJob(handler_->MaybeLoadFallbackForResponse(nullptr));
+ EXPECT_FALSE(job());
TestFinished();
}
@@ -768,7 +750,7 @@ class AppCacheRequestHandlerTest
EXPECT_TRUE(handler_.get());
backend_impl_->UnregisterHost(1);
- host_ = NULL;
+ host_ = nullptr;
EXPECT_FALSE(handler_->MaybeLoadResource(nullptr));
EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
@@ -788,16 +770,15 @@ class AppCacheRequestHandlerTest
RESOURCE_TYPE_SUB_RESOURCE));
EXPECT_TRUE(handler_.get());
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsWaiting());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsWaiting());
backend_impl_->UnregisterHost(1);
- host_ = NULL;
+ host_ = nullptr;
if (request_handler_type_ == URLREQUEST) {
- EXPECT_TRUE(
- static_cast<AppCacheURLRequestJob*>(job_.get())->has_been_killed());
+ EXPECT_TRUE(appcache_url_request_job_->has_been_killed());
}
EXPECT_FALSE(handler_->MaybeLoadResource(nullptr));
EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
@@ -818,18 +799,17 @@ class AppCacheRequestHandlerTest
EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), host_,
RESOURCE_TYPE_SUB_RESOURCE));
EXPECT_TRUE(handler_.get());
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
backend_impl_.reset();
mock_frontend_.reset();
mock_service_.reset();
mock_policy_.reset();
- host_ = NULL;
+ host_ = nullptr;
if (request_handler_type_ == URLREQUEST) {
- EXPECT_TRUE(
- static_cast<AppCacheURLRequestJob*>(job_.get())->has_been_killed());
+ EXPECT_TRUE(appcache_url_request_job_->has_been_killed());
}
EXPECT_FALSE(handler_->MaybeLoadResource(nullptr));
EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
@@ -850,7 +830,7 @@ class AppCacheRequestHandlerTest
mock_frontend_.reset();
mock_service_.reset();
mock_policy_.reset();
- host_ = NULL;
+ host_ = nullptr;
EXPECT_FALSE(handler_->host_for_cross_site_transfer_.get());
EXPECT_FALSE(handler_->MaybeLoadResource(nullptr));
@@ -886,19 +866,17 @@ class AppCacheRequestHandlerTest
RESOURCE_TYPE_MAIN_FRAME));
EXPECT_TRUE(handler_.get());
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsWaiting());
- EXPECT_FALSE(job_->IsStarted());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsWaiting());
+ EXPECT_FALSE(job()->IsStarted());
- base::WeakPtr<AppCacheJob> weak_job = job_->GetWeakPtr();
+ base::WeakPtr<AppCacheJob> weak_job = job()->GetWeakPtr();
// TODO(ananta/michaeln)
// Rewrite this test for URLLoader.
if (request_handler_type_ == URLREQUEST) {
- std::unique_ptr<AppCacheURLRequestJob> job(
- static_cast<AppCacheURLRequestJob*>(job_.release()));
- job_factory_->SetJob(std::move(job));
+ job_factory_->SetJob(std::move(appcache_url_request_job_));
request_->AsURLRequest()->GetURLRequest()->Start();
ASSERT_TRUE(weak_job);
@@ -913,47 +891,6 @@ class AppCacheRequestHandlerTest
TestFinished();
}
- // WorkerRequest -----------------------------
-
- void WorkerRequest() {
- EXPECT_TRUE(AppCacheRequestHandler::IsMainResourceType(
- RESOURCE_TYPE_MAIN_FRAME));
- EXPECT_TRUE(AppCacheRequestHandler::IsMainResourceType(
- RESOURCE_TYPE_SUB_FRAME));
- EXPECT_TRUE(AppCacheRequestHandler::IsMainResourceType(
- RESOURCE_TYPE_SHARED_WORKER));
- EXPECT_FALSE(AppCacheRequestHandler::IsMainResourceType(
- RESOURCE_TYPE_WORKER));
-
-
- const int kParentHostId = host_->host_id();
- const int kWorkerHostId = 2;
- const int kAbandonedWorkerHostId = 3;
- const int kNonExsitingHostId = 700;
-
- backend_impl_->RegisterHost(kWorkerHostId);
- AppCacheHost* worker_host = backend_impl_->GetHost(kWorkerHostId);
- worker_host->SelectCacheForWorker(kParentHostId, kMockProcessId);
- EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), worker_host,
- RESOURCE_TYPE_SHARED_WORKER));
- EXPECT_TRUE(handler_.get());
- // Verify that the handler is associated with the parent host.
- EXPECT_EQ(host_, handler_->host_);
-
- // Create a new worker host, but associate it with a parent host that
- // does not exists to simulate the host having been torn down.
- backend_impl_->UnregisterHost(kWorkerHostId);
- backend_impl_->RegisterHost(kAbandonedWorkerHostId);
- worker_host = backend_impl_->GetHost(kAbandonedWorkerHostId);
- EXPECT_EQ(NULL, backend_impl_->GetHost(kNonExsitingHostId));
- worker_host->SelectCacheForWorker(kNonExsitingHostId, kMockProcessId);
- EXPECT_TRUE(CreateRequestAndHandler(GURL("http://blah/"), worker_host,
- RESOURCE_TYPE_SHARED_WORKER));
- EXPECT_FALSE(handler_.get());
-
- TestFinished();
- }
-
// MainResource_Blocked --------------------------------------------------
void MainResource_Blocked() {
@@ -971,17 +908,17 @@ class AppCacheRequestHandlerTest
GURL(), AppCacheEntry(),
1, 2, GURL("http://blah/manifest/"));
- job_.reset(handler_->MaybeLoadResource(nullptr));
- EXPECT_TRUE(job_.get());
- EXPECT_TRUE(job_->IsWaiting());
+ SetAppCacheJob(handler_->MaybeLoadResource(nullptr));
+ EXPECT_TRUE(job());
+ EXPECT_TRUE(job()->IsWaiting());
// We have to wait for completion of storage->FindResponseForMainRequest.
ScheduleNextTask();
}
void Verify_MainResource_Blocked() {
- EXPECT_FALSE(job_->IsWaiting());
- EXPECT_FALSE(job_->IsDeliveringAppCacheResponse());
+ EXPECT_FALSE(job()->IsWaiting());
+ EXPECT_FALSE(job()->IsDeliveringAppCacheResponse());
EXPECT_EQ(0, handler_->found_cache_id_);
EXPECT_EQ(0, handler_->found_group_id_);
@@ -1052,7 +989,8 @@ class AppCacheRequestHandlerTest
AppCacheRequest* request_;
std::unique_ptr<net::URLRequest> url_request_;
std::unique_ptr<AppCacheRequestHandler> handler_;
- std::unique_ptr<AppCacheJob> job_;
+ std::unique_ptr<AppCacheURLRequestJob> appcache_url_request_job_;
+ base::WeakPtr<AppCacheURLLoaderJob> appcache_url_loader_job_;
static std::unique_ptr<base::Thread> io_thread_;
static std::unique_ptr<base::test::ScopedTaskEnvironment>
@@ -1141,10 +1079,6 @@ TEST_P(AppCacheRequestHandlerTest, CanceledRequest) {
RunTestOnIOThread(&AppCacheRequestHandlerTest::CanceledRequest);
}
-TEST_P(AppCacheRequestHandlerTest, WorkerRequest) {
- RunTestOnIOThread(&AppCacheRequestHandlerTest::WorkerRequest);
-}
-
TEST_P(AppCacheRequestHandlerTest, MainResource_Blocked) {
RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Blocked);
}
diff --git a/chromium/content/browser/appcache/appcache_response.cc b/chromium/content/browser/appcache/appcache_response.cc
index 4c7b0744514..dd47432bcb6 100644
--- a/chromium/content/browser/appcache/appcache_response.cc
+++ b/chromium/content/browser/appcache/appcache_response.cc
@@ -98,7 +98,7 @@ AppCacheResponseIO::AppCacheResponseIO(
const base::WeakPtr<AppCacheDiskCacheInterface>& disk_cache)
: response_id_(response_id),
disk_cache_(disk_cache),
- entry_(NULL),
+ entry_(nullptr),
buffer_len_(0),
weak_factory_(this) {}
@@ -116,8 +116,8 @@ void AppCacheResponseIO::ScheduleIOCompletionCallback(int result) {
void AppCacheResponseIO::InvokeUserCompletionCallback(int result) {
// Clear the user callback and buffers prior to invoking the callback
// so the caller can schedule additional operations in the callback.
- buffer_ = NULL;
- info_buffer_ = NULL;
+ buffer_ = nullptr;
+ info_buffer_ = nullptr;
OnceCompletionCallback cb = std::move(callback_);
callback_.Reset();
std::move(cb).Run(result);
@@ -152,7 +152,7 @@ void AppCacheResponseIO::OnRawIOComplete(int result) {
void AppCacheResponseIO::OpenEntryIfNeeded() {
int rv;
- AppCacheDiskCacheInterface::Entry** entry_ptr = NULL;
+ AppCacheDiskCacheInterface::Entry** entry_ptr = nullptr;
if (entry_) {
rv = net::OK;
} else if (!disk_cache_) {
@@ -398,7 +398,7 @@ void AppCacheResponseWriter::OnIOComplete(int result) {
void AppCacheResponseWriter::CreateEntryIfNeededAndContinue() {
int rv;
- AppCacheDiskCacheInterface::Entry** entry_ptr = NULL;
+ AppCacheDiskCacheInterface::Entry** entry_ptr = nullptr;
if (entry_) {
creation_phase_ = NO_ATTEMPT;
rv = net::OK;
@@ -430,7 +430,7 @@ void AppCacheResponseWriter::OnCreateEntryComplete(
creation_phase_ = DOOM_EXISTING;
rv = disk_cache_->DoomEntry(response_id_, create_callback_);
if (rv != net::ERR_IO_PENDING)
- OnCreateEntryComplete(NULL, rv);
+ OnCreateEntryComplete(nullptr, rv);
return;
}
} else if (creation_phase_ == DOOM_EXISTING) {
diff --git a/chromium/content/browser/appcache/appcache_response_unittest.cc b/chromium/content/browser/appcache/appcache_response_unittest.cc
index e6996565a66..524c4a66371 100644
--- a/chromium/content/browser/appcache/appcache_response_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_response_unittest.cc
@@ -116,11 +116,11 @@ class AppCacheResponseTest : public testing::Test {
task_stack_.pop();
reader_.reset();
- read_buffer_ = NULL;
- read_info_buffer_ = NULL;
+ read_buffer_ = nullptr;
+ read_info_buffer_ = nullptr;
writer_.reset();
- write_buffer_ = NULL;
- write_info_buffer_ = NULL;
+ write_buffer_ = nullptr;
+ write_info_buffer_ = nullptr;
storage_delegate_.reset();
service_.reset();
}
diff --git a/chromium/content/browser/appcache/appcache_service_impl.cc b/chromium/content/browser/appcache/appcache_service_impl.cc
index 00b051b2791..06f166fe978 100644
--- a/chromium/content/browser/appcache/appcache_service_impl.cc
+++ b/chromium/content/browser/appcache/appcache_service_impl.cc
@@ -19,7 +19,6 @@
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_backend_impl.h"
#include "content/browser/appcache/appcache_entry.h"
-#include "content/browser/appcache/appcache_executable_handler.h"
#include "content/browser/appcache/appcache_histograms.h"
#include "content/browser/appcache/appcache_policy.h"
#include "content/browser/appcache/appcache_quota_client.h"
@@ -403,7 +402,6 @@ AppCacheServiceImpl::AppCacheServiceImpl(
base::TaskShutdownBehavior::BLOCK_SHUTDOWN})),
appcache_policy_(nullptr),
quota_client_(nullptr),
- handler_factory_(nullptr),
quota_manager_proxy_(quota_manager_proxy),
request_context_(nullptr),
force_keep_session_state_(false),
diff --git a/chromium/content/browser/appcache/appcache_service_impl.h b/chromium/content/browser/appcache/appcache_service_impl.h
index fe49dad17ce..a4856f4dd7f 100644
--- a/chromium/content/browser/appcache/appcache_service_impl.h
+++ b/chromium/content/browser/appcache/appcache_service_impl.h
@@ -39,7 +39,6 @@ class SpecialStoragePolicy;
namespace content {
FORWARD_DECLARE_TEST(AppCacheServiceImplTest, ScheduleReinitialize);
class AppCacheBackendImpl;
-class AppCacheExecutableHandlerFactory;
class AppCacheQuotaClient;
class AppCachePolicy;
class AppCacheServiceImplTest;
@@ -136,18 +135,6 @@ class CONTENT_EXPORT AppCacheServiceImpl
appcache_policy_ = policy;
}
- // The factory may be null, in which case invocations of exe handlers
- // will result in an error response.
- // The service does NOT assume ownership of the factory, it is the callers
- // responsibility to ensure that the pointer remains valid while set.
- AppCacheExecutableHandlerFactory* handler_factory() const {
- return handler_factory_;
- }
- void set_handler_factory(
- AppCacheExecutableHandlerFactory* factory) {
- handler_factory_ = factory;
- }
-
storage::SpecialStoragePolicy* special_storage_policy() const {
return special_storage_policy_.get();
}
@@ -214,7 +201,6 @@ class CONTENT_EXPORT AppCacheServiceImpl
scoped_refptr<base::SequencedTaskRunner> db_task_runner_;
AppCachePolicy* appcache_policy_;
AppCacheQuotaClient* quota_client_;
- AppCacheExecutableHandlerFactory* handler_factory_;
std::unique_ptr<AppCacheStorage> storage_;
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;
diff --git a/chromium/content/browser/appcache/appcache_service_unittest.cc b/chromium/content/browser/appcache/appcache_service_unittest.cc
index 7eb6044bb83..38d0dd12ec7 100644
--- a/chromium/content/browser/appcache/appcache_service_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_service_unittest.cc
@@ -98,8 +98,9 @@ class AppCacheServiceImplTest : public testing::Test {
AppCacheServiceImplTest()
: kOrigin("http://hello/"),
kManifestUrl(kOrigin.Resolve("manifest")),
- service_(new AppCacheServiceImpl(NULL)),
- delete_result_(net::OK), delete_completion_count_(0),
+ service_(new AppCacheServiceImpl(nullptr)),
+ delete_result_(net::OK),
+ delete_completion_count_(0),
deletion_callback_(
base::Bind(&AppCacheServiceImplTest::OnDeleteAppCachesComplete,
base::Unretained(this))) {
@@ -149,9 +150,9 @@ class AppCacheServiceImplTest : public testing::Test {
void SetupMockReader(
bool valid_info, bool valid_data, bool valid_size) {
- net::HttpResponseInfo* info = valid_info ? MakeMockResponseInfo() : NULL;
+ net::HttpResponseInfo* info = valid_info ? MakeMockResponseInfo() : nullptr;
int info_size = info ? GetResponseInfoSize(info) : 0;
- const char* data = valid_data ? kMockBody : NULL;
+ const char* data = valid_data ? kMockBody : nullptr;
int data_size = valid_size ? kMockBodySize : 3;
mock_storage()->SimulateResponseReader(
new MockResponseReader(kMockResponseId, info, info_size,
@@ -336,7 +337,8 @@ TEST_F(AppCacheServiceImplTest, ScheduleReinitialize) {
const base::TimeDelta kOneHour(base::TimeDelta::FromHours(1));
// Do things get initialized as expected?
- std::unique_ptr<AppCacheServiceImpl> service(new AppCacheServiceImpl(NULL));
+ std::unique_ptr<AppCacheServiceImpl> service(
+ new AppCacheServiceImpl(nullptr));
EXPECT_TRUE(service->last_reinit_time_.is_null());
EXPECT_FALSE(service->reinit_timer_.IsRunning());
EXPECT_EQ(kNoDelay, service->next_reinit_delay_);
@@ -380,7 +382,7 @@ TEST_F(AppCacheServiceImplTest, ScheduleReinitialize) {
EXPECT_EQ(kOneHour, service->next_reinit_delay_);
// Fine to delete while pending.
- service.reset(NULL);
+ service.reset(nullptr);
}
diff --git a/chromium/content/browser/appcache/appcache_storage_impl.cc b/chromium/content/browser/appcache/appcache_storage_impl.cc
index 7d1cae4ffd6..7cbf946cf6f 100644
--- a/chromium/content/browser/appcache/appcache_storage_impl.cc
+++ b/chromium/content/browser/appcache/appcache_storage_impl.cc
@@ -37,15 +37,14 @@
#include "storage/browser/quota/quota_client.h"
#include "storage/browser/quota/quota_manager.h"
#include "storage/browser/quota/quota_manager_proxy.h"
-#include "storage/browser/quota/special_storage_policy.h"
namespace content {
// Hard coded default when not using quota management.
static const int kDefaultQuota = 5 * 1024 * 1024;
-static const int kMaxDiskCacheSize = 250 * 1024 * 1024;
-static const int kMaxMemDiskCacheSize = 10 * 1024 * 1024;
+static const int kMaxAppCacheDiskCacheSize = 250 * 1024 * 1024;
+static const int kMaxAppCacheMemDiskCacheSize = 10 * 1024 * 1024;
static const base::FilePath::CharType kDiskCacheDirectoryName[] =
FILE_PATH_LITERAL("Cache");
@@ -75,9 +74,11 @@ bool DeleteGroupAndRelatedRecords(
return success;
}
+} // namespace
+
// Destroys |database|. If there is appcache data to be deleted
// (|force_keep_session_state| is false), deletes session-only appcache data.
-void ClearSessionOnlyOrigins(
+void AppCacheStorageImpl::ClearSessionOnlyOrigins(
AppCacheDatabase* database,
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy,
bool force_keep_session_state) {
@@ -133,8 +134,6 @@ void ClearSessionOnlyOrigins(
} // for each origin
}
-} // namespace
-
// DatabaseTask -----------------------------------------
class AppCacheStorageImpl::DatabaseTask
@@ -205,7 +204,7 @@ void AppCacheStorageImpl::DatabaseTask::Schedule() {
void AppCacheStorageImpl::DatabaseTask::CancelCompletion() {
DCHECK(io_thread_->RunsTasksInCurrentSequence());
delegates_.clear();
- storage_ = NULL;
+ storage_ = nullptr;
}
void AppCacheStorageImpl::DatabaseTask::CallRun(
@@ -645,7 +644,7 @@ AppCacheStorageImpl::StoreGroupAndCacheTask::StoreGroupAndCacheTask(
}
void AppCacheStorageImpl::StoreGroupAndCacheTask::GetQuotaThenSchedule() {
- storage::QuotaManager* quota_manager = NULL;
+ storage::QuotaManager* quota_manager = nullptr;
if (storage_->service()->quota_manager_proxy()) {
quota_manager =
storage_->service()->quota_manager_proxy()->quota_manager();
@@ -810,8 +809,8 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::RunCompleted() {
delegates_,
OnGroupAndNewestCacheStored(
group_.get(), cache_.get(), success_, would_exceed_quota_));
- group_ = NULL;
- cache_ = NULL;
+ group_ = nullptr;
+ cache_ = nullptr;
// TODO(michaeln): if (would_exceed_quota_) what if the current usage
// also exceeds the quota? http://crbug.com/83968
@@ -821,8 +820,8 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::CancelCompletion() {
// Overriden to safely drop our reference to the group and cache
// which are not thread safe refcounted.
DatabaseTask::CancelCompletion();
- group_ = NULL;
- cache_ = NULL;
+ group_ = nullptr;
+ cache_ = nullptr;
}
// FindMainResponseTask -------
@@ -870,7 +869,7 @@ class NetworkNamespaceHelper {
WhiteListMap::value_type(cache_id, AppCacheNamespaceVector()));
if (result.second)
GetOnlineWhiteListForCache(cache_id, &result.first->second);
- return AppCache::FindNamespace(result.first->second, url) != NULL;
+ return AppCache::FindNamespace(result.first->second, url) != nullptr;
}
private:
@@ -1223,14 +1222,14 @@ void AppCacheStorageImpl::MakeGroupObsoleteTask::RunCompleted() {
}
FOR_EACH_DELEGATE(
delegates_, OnGroupMadeObsolete(group_.get(), success_, response_code_));
- group_ = NULL;
+ group_ = nullptr;
}
void AppCacheStorageImpl::MakeGroupObsoleteTask::CancelCompletion() {
// Overriden to safely drop our reference to the group
// which is not thread safe refcounted.
DatabaseTask::CancelCompletion();
- group_ = NULL;
+ group_ = nullptr;
}
// GetDeletableResponseIdsTask -------
@@ -1393,7 +1392,7 @@ AppCacheStorageImpl::AppCacheStorageImpl(AppCacheServiceImpl* service)
is_response_deletion_scheduled_(false),
did_start_deleting_responses_(false),
last_deletable_response_rowid_(0),
- database_(NULL),
+ database_(nullptr),
is_disabled_(false),
delete_and_start_over_pending_(false),
expecting_cleanup_complete_on_disable_(false),
@@ -1413,7 +1412,7 @@ AppCacheStorageImpl::~AppCacheStorageImpl() {
service()->force_keep_session_state()))) {
delete database_;
}
- database_ = NULL; // So no further database tasks can be scheduled.
+ database_ = nullptr; // So no further database tasks can be scheduled.
}
void AppCacheStorageImpl::Initialize(
@@ -1456,7 +1455,7 @@ void AppCacheStorageImpl::GetAllInfo(Delegate* delegate) {
void AppCacheStorageImpl::LoadCache(int64_t id, Delegate* delegate) {
DCHECK(delegate);
if (is_disabled_) {
- delegate->OnCacheLoaded(NULL, id);
+ delegate->OnCacheLoaded(nullptr, id);
return;
}
@@ -1486,7 +1485,7 @@ void AppCacheStorageImpl::LoadOrCreateGroup(
const GURL& manifest_url, Delegate* delegate) {
DCHECK(delegate);
if (is_disabled_) {
- delegate->OnGroupLoaded(NULL, manifest_url);
+ delegate->OnGroupLoaded(nullptr, manifest_url);
return;
}
@@ -1843,7 +1842,7 @@ AppCacheStorageImpl::GetPendingCacheLoadTask(int64_t cache_id) {
PendingCacheLoads::iterator found = pending_cache_loads_.find(cache_id);
if (found != pending_cache_loads_.end())
return found->second;
- return NULL;
+ return nullptr;
}
AppCacheStorageImpl::GroupLoadTask*
@@ -1851,7 +1850,7 @@ AppCacheStorageImpl::GetPendingGroupLoadTask(const GURL& manifest_url) {
PendingGroupLoads::iterator found = pending_group_loads_.find(manifest_url);
if (found != pending_group_loads_.end())
return found->second;
- return NULL;
+ return nullptr;
}
void AppCacheStorageImpl::GetPendingForeignMarkingsForCache(
@@ -1888,14 +1887,14 @@ AppCacheDiskCache* AppCacheStorageImpl::disk_cache() {
disk_cache_.reset(new AppCacheDiskCache);
if (is_incognito_) {
rv = disk_cache_->InitWithMemBackend(
- kMaxMemDiskCacheSize,
+ kMaxAppCacheMemDiskCacheSize,
base::Bind(&AppCacheStorageImpl::OnDiskCacheInitialized,
base::Unretained(this)));
} else {
expecting_cleanup_complete_on_disable_ = true;
rv = disk_cache_->InitWithDiskBackend(
- cache_directory_.Append(kDiskCacheDirectoryName), kMaxDiskCacheSize,
- false,
+ cache_directory_.Append(kDiskCacheDirectoryName),
+ 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 30cf261c83a..022ae2f4563 100644
--- a/chromium/content/browser/appcache/appcache_storage_impl.h
+++ b/chromium/content/browser/appcache/appcache_storage_impl.h
@@ -22,6 +22,7 @@
#include "content/browser/appcache/appcache_disk_cache.h"
#include "content/browser/appcache/appcache_storage.h"
#include "content/common/content_export.h"
+#include "storage/browser/quota/special_storage_policy.h"
namespace base {
class SequencedTaskRunner;
@@ -127,6 +128,11 @@ class AppCacheStorageImpl : public AppCacheStorage {
void LazilyCommitLastAccessTimes();
void OnLazyCommitTimer();
+ static void ClearSessionOnlyOrigins(
+ AppCacheDatabase* database,
+ scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy,
+ bool force_keep_session_state);
+
// Sometimes we can respond without having to query the database.
bool FindResponseForMainRequestInGroup(
AppCacheGroup* group, const GURL& url, Delegate* delegate);
diff --git a/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc b/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
index ed8d7e04dc3..a02afef1f54 100644
--- a/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
@@ -171,8 +171,8 @@ class IOThread : public base::Thread {
std::unique_ptr<net::URLRequestJobFactoryImpl> factory(
new net::URLRequestJobFactoryImpl());
factory->SetProtocolHandler("http",
- base::MakeUnique<MockHttpServerJobFactory>(
- base::MakeUnique<AppCacheInterceptor>()));
+ std::make_unique<MockHttpServerJobFactory>(
+ std::make_unique<AppCacheInterceptor>()));
job_factory_ = std::move(factory);
request_context_.reset(new net::TestURLRequestContext());
request_context_->set_job_factory(job_factory_.get());
@@ -214,8 +214,8 @@ class AppCacheStorageImplTest : public testing::Test {
const GURL& manifest_url) override {
loaded_group_ = group;
loaded_manifest_url_ = manifest_url;
- loaded_groups_newest_cache_ = group ? group->newest_complete_cache()
- : NULL;
+ loaded_groups_newest_cache_ =
+ group ? group->newest_complete_cache() : nullptr;
test_->ScheduleNextTask();
}
@@ -310,7 +310,7 @@ class AppCacheStorageImplTest : public testing::Test {
class MockQuotaManagerProxy : public storage::QuotaManagerProxy {
public:
MockQuotaManagerProxy()
- : QuotaManagerProxy(NULL, NULL),
+ : QuotaManagerProxy(nullptr, nullptr),
notify_storage_accessed_count_(0),
notify_storage_modified_count_(0),
last_delta_(0),
@@ -431,10 +431,10 @@ class AppCacheStorageImplTest : public testing::Test {
scoped_refptr<base::SequencedTaskRunner> db_runner =
storage()->db_task_runner_;
storage()->CancelDelegateCallbacks(delegate());
- group_ = NULL;
- cache_ = NULL;
- cache2_ = NULL;
- mock_quota_manager_proxy_ = NULL;
+ group_ = nullptr;
+ cache_ = nullptr;
+ cache2_ = nullptr;
+ mock_quota_manager_proxy_ = nullptr;
delegate_.reset();
service_.reset();
FlushTasks(db_runner.get());
@@ -588,8 +588,8 @@ class AppCacheStorageImplTest : public testing::Test {
// Setup some preconditions. Create a group and newest cache that
// appear to be "stored" and "not currently in use".
MakeCacheAndGroup(kManifestUrl, 1, 1, true);
- group_ = NULL;
- cache_ = NULL;
+ group_ = nullptr;
+ cache_ = nullptr;
// Conduct the cache load test, completes async
storage()->LoadCache(1, delegate());
@@ -609,7 +609,7 @@ class AppCacheStorageImplTest : public testing::Test {
EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_modified_count_);
// Drop things from the working set.
- delegate()->loaded_cache_ = NULL;
+ delegate()->loaded_cache_ = nullptr;
EXPECT_FALSE(delegate()->loaded_group_.get());
// Conduct the group load test, also complete asynchronously.
@@ -624,7 +624,7 @@ class AppCacheStorageImplTest : public testing::Test {
EXPECT_TRUE(delegate()->loaded_group_.get());
EXPECT_EQ(kManifestUrl, delegate()->loaded_manifest_url_);
EXPECT_TRUE(delegate()->loaded_group_->newest_complete_cache());
- delegate()->loaded_groups_newest_cache_ = NULL;
+ delegate()->loaded_groups_newest_cache_ = nullptr;
EXPECT_TRUE(delegate()->loaded_group_->HasOneRef());
EXPECT_EQ(2, mock_quota_manager_proxy_->notify_storage_accessed_count_);
EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_modified_count_);
@@ -947,8 +947,8 @@ class AppCacheStorageImplTest : public testing::Test {
EXPECT_TRUE(database()->InsertEntry(&entry_record));
EXPECT_FALSE(cache_->GetEntry(kEntryUrl)->IsForeign());
EXPECT_TRUE(cache_->HasOneRef());
- cache_ = NULL;
- group_ = NULL;
+ cache_ = nullptr;
+ group_ = nullptr;
// Conduct the test, start a cache load, and prior to completion
// of that load, mark the entry as foreign.
@@ -1027,9 +1027,9 @@ class AppCacheStorageImplTest : public testing::Test {
// Optionally drop the cache/group pair from the working set.
if (drop_from_working_set) {
EXPECT_TRUE(cache_->HasOneRef());
- cache_ = NULL;
+ cache_ = nullptr;
EXPECT_TRUE(group_->HasOneRef());
- group_ = NULL;
+ group_ = nullptr;
}
// Conduct the test.
@@ -1103,9 +1103,9 @@ class AppCacheStorageImplTest : public testing::Test {
EXPECT_TRUE(database()->InsertOnlineWhiteListRecords(whitelists));
if (drop_from_working_set) {
EXPECT_TRUE(cache_->HasOneRef());
- cache_ = NULL;
+ cache_ = nullptr;
EXPECT_TRUE(group_->HasOneRef());
- group_ = NULL;
+ group_ = nullptr;
}
// Conduct the test. The test url is in both fallback namespace urls,
@@ -1177,9 +1177,9 @@ class AppCacheStorageImplTest : public testing::Test {
EXPECT_TRUE(database()->InsertOnlineWhiteListRecords(whitelists));
if (drop_from_working_set) {
EXPECT_TRUE(cache_->HasOneRef());
- cache_ = NULL;
+ cache_ = nullptr;
EXPECT_TRUE(group_->HasOneRef());
- group_ = NULL;
+ group_ = nullptr;
}
// Conduct the test. The test url is in both intercept namespaces,
@@ -1243,9 +1243,9 @@ class AppCacheStorageImplTest : public testing::Test {
EXPECT_TRUE(database()->InsertNamespaceRecords(intercepts));
if (drop_from_working_set) {
EXPECT_TRUE(cache_->HasOneRef());
- cache_ = NULL;
+ cache_ = nullptr;
EXPECT_TRUE(group_->HasOneRef());
- group_ = NULL;
+ group_ = nullptr;
}
// First test something that does not match the pattern.
@@ -1330,9 +1330,9 @@ class AppCacheStorageImplTest : public testing::Test {
EXPECT_TRUE(database()->InsertNamespaceRecords(fallbacks));
if (drop_from_working_set) {
EXPECT_TRUE(cache_->HasOneRef());
- cache_ = NULL;
+ cache_ = nullptr;
EXPECT_TRUE(group_->HasOneRef());
- group_ = NULL;
+ group_ = nullptr;
}
// First test something that does not match the pattern.
@@ -1581,8 +1581,8 @@ class AppCacheStorageImplTest : public testing::Test {
whitelist_record.namespace_url = kOnlineNamespaceWithinFallback;
EXPECT_TRUE(database()->InsertOnlineWhiteList(&whitelist_record));
if (drop_from_working_set) {
- cache_ = NULL;
- group_ = NULL;
+ cache_ = nullptr;
+ group_ = nullptr;
}
// We should not find anything for the foreign entry.
@@ -1748,7 +1748,7 @@ class AppCacheStorageImplTest : public testing::Test {
}
// Recreate the service to point at the db and corruption on disk.
- service_.reset(new AppCacheServiceImpl(NULL));
+ service_.reset(new AppCacheServiceImpl(nullptr));
service_->set_request_context(io_thread->request_context());
service_->Initialize(temp_directory_.GetPath());
mock_quota_manager_proxy_ = new MockQuotaManagerProxy();
diff --git a/chromium/content/browser/appcache/appcache_storage_unittest.cc b/chromium/content/browser/appcache/appcache_storage_unittest.cc
index ab582aa7368..242c33bd501 100644
--- a/chromium/content/browser/appcache/appcache_storage_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_storage_unittest.cc
@@ -98,7 +98,7 @@ TEST_F(AppCacheStorageTest, DelegateReferences) {
service.storage()->GetDelegateReference(&delegate)->delegate);
EXPECT_EQ(service.storage()->GetDelegateReference(&delegate),
service.storage()->GetOrCreateDelegateReference(&delegate));
- delegate_reference1 = NULL;
+ delegate_reference1 = nullptr;
EXPECT_FALSE(service.storage()->GetDelegateReference(&delegate));
delegate_reference1 =
@@ -123,7 +123,7 @@ TEST_F(AppCacheStorageTest, UsageMap) {
MockAppCacheService service;
scoped_refptr<MockQuotaManagerProxy> mock_proxy(
- new MockQuotaManagerProxy(NULL, NULL));
+ new MockQuotaManagerProxy(nullptr, nullptr));
service.set_quota_manager_proxy(mock_proxy.get());
service.storage()->UpdateUsageMapAndNotify(kOrigin, 0);
diff --git a/chromium/content/browser/appcache/appcache_subresource_url_factory.cc b/chromium/content/browser/appcache/appcache_subresource_url_factory.cc
index 0438c033e16..1213a50b218 100644
--- a/chromium/content/browser/appcache/appcache_subresource_url_factory.cc
+++ b/chromium/content/browser/appcache/appcache_subresource_url_factory.cc
@@ -18,9 +18,291 @@
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "net/url_request/url_request.h"
namespace content {
+namespace {
+
+// URLLoader implementation that utilizes either a network loader
+// or an appcache loader depending on where the resources should
+// be loaded from. This class binds to the remote client in the
+// renderer and internally creates one or the other kind of loader.
+// The URLLoader and URLLoaderClient interfaces are proxied between
+// the remote consumer and the chosen internal loader.
+//
+// This class owns and scopes the lifetime of the AppCacheRequestHandler
+// for the duration of a subresource load.
+class SubresourceLoader : public mojom::URLLoader,
+ public mojom::URLLoaderClient {
+ public:
+ SubresourceLoader(mojom::URLLoaderRequest url_loader_request,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const ResourceRequest& request,
+ mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag& annotation,
+ base::WeakPtr<AppCacheHost> appcache_host,
+ scoped_refptr<URLLoaderFactoryGetter> net_factory_getter)
+ : remote_binding_(this, std::move(url_loader_request)),
+ remote_client_(std::move(client)),
+ request_(request),
+ routing_id_(routing_id),
+ request_id_(request_id),
+ options_(options),
+ traffic_annotation_(annotation),
+ network_loader_factory_(std::move(net_factory_getter)),
+ local_client_binding_(this),
+ host_(appcache_host),
+ weak_factory_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ remote_binding_.set_connection_error_handler(base::Bind(
+ &SubresourceLoader::OnConnectionError, base::Unretained(this)));
+ base::SequencedTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&SubresourceLoader::Start, weak_factory_.GetWeakPtr()));
+ }
+
+ private:
+ ~SubresourceLoader() override {}
+
+ void OnConnectionError() { delete this; }
+
+ void Start() {
+ if (!host_) {
+ remote_client_->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ return;
+ }
+ handler_ = host_->CreateRequestHandler(
+ AppCacheURLLoaderRequest::Create(request_), request_.resource_type,
+ request_.should_reset_appcache);
+ if (!handler_) {
+ CreateAndStartNetworkLoader();
+ return;
+ }
+ handler_->MaybeCreateSubresourceLoader(
+ request_, base::BindOnce(&SubresourceLoader::ContinueStart,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ void ContinueStart(StartLoaderCallback start_function) {
+ if (start_function)
+ CreateAndStartAppCacheLoader(std::move(start_function));
+ else
+ CreateAndStartNetworkLoader();
+ }
+
+ void CreateAndStartAppCacheLoader(StartLoaderCallback start_function) {
+ DCHECK(!appcache_loader_) << "only expected to be called onced";
+ DCHECK(start_function);
+
+ // Disconnect from the network loader first.
+ local_client_binding_.Close();
+ network_loader_ = nullptr;
+
+ mojom::URLLoaderClientPtr client_ptr;
+ local_client_binding_.Bind(mojo::MakeRequest(&client_ptr));
+ std::move(start_function)
+ .Run(mojo::MakeRequest(&appcache_loader_), std::move(client_ptr));
+ }
+
+ void CreateAndStartNetworkLoader() {
+ DCHECK(!appcache_loader_);
+ mojom::URLLoaderClientPtr client_ptr;
+ local_client_binding_.Bind(mojo::MakeRequest(&client_ptr));
+ network_loader_factory_->GetNetworkFactory()->CreateLoaderAndStart(
+ mojo::MakeRequest(&network_loader_), routing_id_, request_id_, options_,
+ request_, std::move(client_ptr), traffic_annotation_);
+ if (has_set_priority_)
+ network_loader_->SetPriority(priority_, intra_priority_value_);
+ if (has_paused_reading_)
+ network_loader_->PauseReadingBodyFromNet();
+ }
+
+ // mojom::URLLoader implementation
+ // Called by the remote client in the renderer.
+ void FollowRedirect() override {
+ if (!handler_) {
+ network_loader_->FollowRedirect();
+ return;
+ }
+ DCHECK(network_loader_);
+ DCHECK(!appcache_loader_);
+ handler_->MaybeFollowSubresourceRedirect(
+ redirect_info_,
+ base::BindOnce(&SubresourceLoader::ContinueFollowRedirect,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ void ContinueFollowRedirect(StartLoaderCallback start_function) {
+ if (start_function)
+ CreateAndStartAppCacheLoader(std::move(start_function));
+ else
+ network_loader_->FollowRedirect();
+ }
+
+ void SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) override {
+ has_set_priority_ = true;
+ priority_ = priority;
+ intra_priority_value_ = intra_priority_value;
+ if (network_loader_)
+ network_loader_->SetPriority(priority, intra_priority_value);
+ }
+
+ void PauseReadingBodyFromNet() override {
+ has_paused_reading_ = true;
+ if (network_loader_)
+ network_loader_->PauseReadingBodyFromNet();
+ }
+
+ void ResumeReadingBodyFromNet() override {
+ has_paused_reading_ = false;
+ if (network_loader_)
+ network_loader_->ResumeReadingBodyFromNet();
+ }
+
+ // mojom::URLLoaderClient implementation
+ // Called by either the appcache or network loader, whichever is in use.
+ void OnReceiveResponse(
+ const ResourceResponseHead& response_head,
+ const base::Optional<net::SSLInfo>& ssl_info,
+ mojom::DownloadedTempFilePtr downloaded_file) override {
+ // Don't MaybeFallback for appcache produced responses.
+ if (appcache_loader_ || !handler_) {
+ remote_client_->OnReceiveResponse(response_head, ssl_info,
+ std::move(downloaded_file));
+ return;
+ }
+
+ did_receive_network_response_ = true;
+ handler_->MaybeFallbackForSubresourceResponse(
+ response_head,
+ base::BindOnce(&SubresourceLoader::ContinueOnReceiveResponse,
+ weak_factory_.GetWeakPtr(), response_head, ssl_info,
+ std::move(downloaded_file)));
+ }
+
+ void ContinueOnReceiveResponse(const ResourceResponseHead& response_head,
+ const base::Optional<net::SSLInfo>& ssl_info,
+ mojom::DownloadedTempFilePtr downloaded_file,
+ StartLoaderCallback start_function) {
+ if (start_function) {
+ CreateAndStartAppCacheLoader(std::move(start_function));
+ } else {
+ remote_client_->OnReceiveResponse(response_head, ssl_info,
+ std::move(downloaded_file));
+ }
+ }
+
+ void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& response_head) override {
+ DCHECK(network_loader_) << "appcache loader does not produce redirects";
+ if (!redirect_limit_--) {
+ OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_TOO_MANY_REDIRECTS));
+ return;
+ }
+ if (!handler_) {
+ remote_client_->OnReceiveRedirect(redirect_info_, response_head);
+ return;
+ }
+ redirect_info_ = redirect_info;
+ handler_->MaybeFallbackForSubresourceRedirect(
+ redirect_info,
+ base::BindOnce(&SubresourceLoader::ContinueOnReceiveRedirect,
+ weak_factory_.GetWeakPtr(), response_head));
+ }
+
+ void ContinueOnReceiveRedirect(const ResourceResponseHead& response_head,
+ StartLoaderCallback start_function) {
+ if (start_function)
+ CreateAndStartAppCacheLoader(std::move(start_function));
+ else
+ remote_client_->OnReceiveRedirect(redirect_info_, response_head);
+ }
+
+ void OnDataDownloaded(int64_t data_len, int64_t encoded_data_len) override {
+ remote_client_->OnDataDownloaded(data_len, encoded_data_len);
+ }
+
+ void OnUploadProgress(int64_t current_position,
+ int64_t total_size,
+ OnUploadProgressCallback ack_callback) override {
+ remote_client_->OnUploadProgress(current_position, total_size,
+ std::move(ack_callback));
+ }
+
+ void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {
+ remote_client_->OnReceiveCachedMetadata(data);
+ }
+
+ void OnTransferSizeUpdated(int32_t transfer_size_diff) override {
+ remote_client_->OnTransferSizeUpdated(transfer_size_diff);
+ }
+
+ void OnStartLoadingResponseBody(
+ mojo::ScopedDataPipeConsumerHandle body) override {
+ remote_client_->OnStartLoadingResponseBody(std::move(body));
+ }
+
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override {
+ if (!network_loader_ || !handler_ || did_receive_network_response_ ||
+ status.error_code == net::OK) {
+ remote_client_->OnComplete(status);
+ return;
+ }
+ handler_->MaybeFallbackForSubresourceResponse(
+ ResourceResponseHead(),
+ base::BindOnce(&SubresourceLoader::ContinueOnComplete,
+ weak_factory_.GetWeakPtr(), status));
+ }
+
+ void ContinueOnComplete(const network::URLLoaderCompletionStatus& status,
+ StartLoaderCallback start_function) {
+ if (start_function)
+ CreateAndStartAppCacheLoader(std::move(start_function));
+ else
+ remote_client_->OnComplete(status);
+ }
+
+ // The binding and client pointer associated with the renderer.
+ mojo::Binding<mojom::URLLoader> remote_binding_;
+ mojom::URLLoaderClientPtr remote_client_;
+
+ ResourceRequest request_;
+ int32_t routing_id_;
+ int32_t request_id_;
+ uint32_t options_;
+ net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
+ scoped_refptr<URLLoaderFactoryGetter> network_loader_factory_;
+ net::RedirectInfo redirect_info_;
+ int redirect_limit_ = net::URLRequest::kMaxRedirects;
+ bool did_receive_network_response_ = false;
+ bool has_paused_reading_ = false;
+ bool has_set_priority_ = false;
+ net::RequestPriority priority_;
+ int32_t intra_priority_value_;
+
+ // Core appcache logic that decides how to handle a request.
+ std::unique_ptr<AppCacheRequestHandler> handler_;
+
+ // The local binding to either our network or appcache loader,
+ // we only use one of them at any given time.
+ mojo::Binding<mojom::URLLoaderClient> local_client_binding_;
+ mojom::URLLoaderPtr network_loader_;
+ mojom::URLLoaderPtr appcache_loader_;
+
+ base::WeakPtr<AppCacheHost> host_;
+
+ base::WeakPtrFactory<SubresourceLoader> weak_factory_;
+ DISALLOW_COPY_AND_ASSIGN(SubresourceLoader);
+};
+
+} // namespace
+
// Implements the URLLoaderFactory mojom for AppCache requests.
AppCacheSubresourceURLFactory::AppCacheSubresourceURLFactory(
URLLoaderFactoryGetter* default_url_loader_factory_getter,
@@ -41,14 +323,12 @@ void AppCacheSubresourceURLFactory::CreateURLLoaderFactory(
base::WeakPtr<AppCacheHost> host,
mojom::URLLoaderFactoryPtr* loader_factory) {
DCHECK(host.get());
- mojom::URLLoaderFactoryRequest request = mojo::MakeRequest(loader_factory);
-
// This instance is effectively reference counted by the number of pipes open
// to it and will get deleted when all clients drop their connections.
// Please see OnConnectionError() for details.
auto* impl = new AppCacheSubresourceURLFactory(
default_url_loader_factory_getter, host);
- impl->Clone(std::move(request));
+ impl->Clone(mojo::MakeRequest(loader_factory));
// Save the factory in the host to ensure that we don't create it again when
// the cache is selected, etc.
@@ -64,39 +344,9 @@ void AppCacheSubresourceURLFactory::CreateLoaderAndStart(
mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DLOG(WARNING) << "Received request for loading : " << request.url.spec();
-
- // If the host is invalid, it means that the renderer has probably died.
- // (Frame has navigated elsewhere?)
- if (!appcache_host_.get()) {
- NotifyError(std::move(client), net::ERR_FAILED);
- return;
- }
-
- std::unique_ptr<AppCacheRequestHandler> handler =
- appcache_host_->CreateRequestHandler(
- AppCacheURLLoaderRequest::Create(request), request.resource_type,
- request.should_reset_appcache);
- if (!handler) {
- NotifyError(std::move(client), net::ERR_FAILED);
- return;
- }
-
- std::unique_ptr<SubresourceLoadInfo> load_info(new SubresourceLoadInfo());
- load_info->url_loader_request = std::move(url_loader_request);
- load_info->routing_id = routing_id;
- load_info->request_id = request_id;
- load_info->options = options;
- load_info->request = request;
- load_info->client = std::move(client);
- load_info->traffic_annotation = traffic_annotation;
-
- if (handler->MaybeCreateSubresourceLoader(
- std::move(load_info), default_url_loader_factory_getter_.get(),
- this)) {
- // The handler is owned by the job and will be destroyed with the job.
- handler.release();
- }
+ new SubresourceLoader(std::move(url_loader_request), routing_id, request_id,
+ options, request, std::move(client), traffic_annotation,
+ appcache_host_, default_url_loader_factory_getter_);
}
void AppCacheSubresourceURLFactory::Clone(
@@ -109,41 +359,9 @@ AppCacheSubresourceURLFactory::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
-void AppCacheSubresourceURLFactory::Restart(
- const net::RedirectInfo& redirect_info,
- std::unique_ptr<AppCacheRequestHandler> subresource_handler,
- std::unique_ptr<SubresourceLoadInfo> subresource_load_info) {
- if (!appcache_host_.get())
- return;
-
- // Should not hit the redirect limit.
- DCHECK(subresource_load_info->redirect_limit > 0);
-
- subresource_load_info->request.url = redirect_info.new_url;
- subresource_load_info->request.method = redirect_info.new_method;
- subresource_load_info->request.referrer = GURL(redirect_info.new_referrer);
- subresource_load_info->request.site_for_cookies =
- redirect_info.new_site_for_cookies;
-
- if (subresource_handler->MaybeCreateSubresourceLoader(
- std::move(subresource_load_info),
- default_url_loader_factory_getter_.get(), this)) {
- // The handler is owned by the job and will be destroyed with the job.
- subresource_handler.release();
- }
-}
-
void AppCacheSubresourceURLFactory::OnConnectionError() {
if (bindings_.empty())
delete this;
}
-void AppCacheSubresourceURLFactory::NotifyError(
- mojom::URLLoaderClientPtr client,
- int error_code) {
- ResourceRequestCompletionStatus request_result;
- request_result.error_code = error_code;
- client->OnComplete(request_result);
-}
-
} // namespace content
diff --git a/chromium/content/browser/appcache/appcache_subresource_url_factory.h b/chromium/content/browser/appcache/appcache_subresource_url_factory.h
index 9b6e504e1a7..d08cea12a0d 100644
--- a/chromium/content/browser/appcache/appcache_subresource_url_factory.h
+++ b/chromium/content/browser/appcache/appcache_subresource_url_factory.h
@@ -20,7 +20,6 @@ class AppCacheJob;
class AppCacheRequestHandler;
class AppCacheServiceImpl;
class URLLoaderFactoryGetter;
-struct SubresourceLoadInfo;
// Implements the URLLoaderFactory mojom for AppCache subresource requests.
class CONTENT_EXPORT AppCacheSubresourceURLFactory
@@ -52,36 +51,19 @@ class CONTENT_EXPORT AppCacheSubresourceURLFactory
base::WeakPtr<AppCacheSubresourceURLFactory> GetWeakPtr();
- // Called bythe AppCacheURLLoaderJob to restart the request during a
- // redirect. We attempt to serve the request out of the AppCache and if
- // that fails we go to the network.
- void Restart(const net::RedirectInfo& redirect_info,
- std::unique_ptr<AppCacheRequestHandler> subresource_handler,
- std::unique_ptr<SubresourceLoadInfo> subresource_load_info);
-
private:
friend class AppCacheNetworkServiceBrowserTest;
+ // TODO(michaeln): Declare SubresourceLoader here and add unittests.
+
AppCacheSubresourceURLFactory(URLLoaderFactoryGetter* factory_getter,
base::WeakPtr<AppCacheHost> host);
-
void OnConnectionError();
- // Notifies the |client| if there is a failure. The |error_code| contains the
- // actual error.
- void NotifyError(mojom::URLLoaderClientPtr client, int error_code);
-
- // Mojo bindings.
mojo::BindingSet<mojom::URLLoaderFactory> bindings_;
-
- // Used to retrieve the network service factory to pass unhandled requests to
- // the network service.
scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_;
-
base::WeakPtr<AppCacheHost> appcache_host_;
-
base::WeakPtrFactory<AppCacheSubresourceURLFactory> weak_factory_;
-
DISALLOW_COPY_AND_ASSIGN(AppCacheSubresourceURLFactory);
};
diff --git a/chromium/content/browser/appcache/appcache_unittest.cc b/chromium/content/browser/appcache/appcache_unittest.cc
index 1806bcad98f..e64b3b0250d 100644
--- a/chromium/content/browser/appcache/appcache_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_unittest.cc
@@ -607,7 +607,7 @@ TEST_F(AppCacheTest, ToFromDatabaseRecords) {
EXPECT_EQ(1u, intercepts.size());
EXPECT_EQ(1u, fallbacks.size());
EXPECT_EQ(1u, whitelists.size());
- cache = NULL;
+ cache = nullptr;
// Create a new AppCache and populate it with those records and verify.
cache = new AppCache(service.storage(), kCacheId);
diff --git a/chromium/content/browser/appcache/appcache_update_job.cc b/chromium/content/browser/appcache/appcache_update_job.cc
index a7b97daf6a1..21c8faa7610 100644
--- a/chromium/content/browser/appcache/appcache_update_job.cc
+++ b/chromium/content/browser/appcache/appcache_update_job.cc
@@ -27,7 +27,7 @@ namespace content {
namespace {
-const int kBufferSize = 32768;
+const int kAppCacheFetchBufferSize = 32768;
const size_t kMaxConcurrentUrlFetches = 2;
std::string FormatUrlErrorMessage(
@@ -57,7 +57,7 @@ bool IsEvictableError(AppCacheUpdateJob::ResultType result,
return true;
case AppCacheUpdateJob::MANIFEST_ERROR:
- return details.reason == APPCACHE_SIGNATURE_ERROR;
+ return details.reason == AppCacheErrorReason::APPCACHE_SIGNATURE_ERROR;
default:
NOTREACHED();
@@ -178,12 +178,12 @@ AppCacheUpdateJob::AppCacheUpdateJob(AppCacheServiceImpl* service,
doing_full_update_check_(false),
master_entries_completed_(0),
url_fetches_completed_(0),
- manifest_fetcher_(NULL),
+ manifest_fetcher_(nullptr),
manifest_has_valid_mime_type_(false),
stored_state_(UNSTORED),
storage_(service->storage()),
weak_factory_(this) {
- service_->AddObserver(this);
+ service_->AddObserver(this);
}
AppCacheUpdateJob::~AppCacheUpdateJob() {
@@ -237,9 +237,9 @@ void AppCacheUpdateJob::StartUpdate(AppCacheHost* host,
if (update_status == AppCacheGroup::CHECKING ||
update_status == AppCacheGroup::DOWNLOADING) {
if (host) {
- NotifySingleHost(host, APPCACHE_CHECKING_EVENT);
+ NotifySingleHost(host, AppCacheEventID::APPCACHE_CHECKING_EVENT);
if (update_status == AppCacheGroup::DOWNLOADING)
- NotifySingleHost(host, APPCACHE_DOWNLOADING_EVENT);
+ NotifySingleHost(host, AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
// Add to fetch list or an existing entry if already fetched.
if (!new_master_resource.is_empty()) {
@@ -259,12 +259,12 @@ void AppCacheUpdateJob::StartUpdate(AppCacheHost* host,
base::TimeDelta time_since_last_check =
base::Time::Now() - group_->last_full_update_check_time();
doing_full_update_check_ = time_since_last_check > kFullUpdateInterval;
- NotifyAllAssociatedHosts(APPCACHE_CHECKING_EVENT);
+ NotifyAllAssociatedHosts(AppCacheEventID::APPCACHE_CHECKING_EVENT);
} else {
update_type_ = CACHE_ATTEMPT;
doing_full_update_check_ = true;
DCHECK(host);
- NotifySingleHost(host, APPCACHE_CHECKING_EVENT);
+ NotifySingleHost(host, AppCacheEventID::APPCACHE_CHECKING_EVENT);
}
if (!new_master_resource.is_empty()) {
@@ -323,7 +323,7 @@ void AppCacheUpdateJob::HandleCacheFailure(
// DeleteAppCacheGroup, otherwise that method would delete |this|
// and we need the stack to unwind prior to deletion.
group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE);
- group_ = NULL;
+ group_ = nullptr;
service_->DeleteAppCacheGroup(manifest_url_,
base::Bind(EmptyCompletionCallback));
}
@@ -337,12 +337,14 @@ void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) {
new URLFetcher(manifest_url_,
is_first_fetch ? URLFetcher::MANIFEST_FETCH
: URLFetcher::MANIFEST_REFETCH,
- this, kBufferSize);
+ this, kAppCacheFetchBufferSize);
if (is_first_fetch) {
// Maybe load the cached headers to make a condiditional request.
- AppCacheEntry* entry = (update_type_ == UPGRADE_ATTEMPT) ?
- group_->newest_complete_cache()->GetEntry(manifest_url_) : NULL;
+ AppCacheEntry* entry =
+ (update_type_ == UPGRADE_ATTEMPT)
+ ? group_->newest_complete_cache()->GetEntry(manifest_url_)
+ : nullptr;
if (entry && !doing_full_update_check_) {
// Asynchronously load response info for manifest from newest cache.
storage_->LoadResponseInfo(manifest_url_, entry->response_id(), this);
@@ -364,7 +366,7 @@ void AppCacheUpdateJob::HandleManifestFetchCompleted(URLFetcher* fetcher,
DCHECK_EQ(internal_state_, FETCH_MANIFEST);
DCHECK_EQ(manifest_fetcher_, fetcher);
- manifest_fetcher_ = NULL;
+ manifest_fetcher_ = nullptr;
UpdateRequestBase* request = fetcher->request();
int response_code = -1;
@@ -394,13 +396,11 @@ void AppCacheUpdateJob::HandleManifestFetchCompleted(URLFetcher* fetcher,
const char kFormatString[] = "Manifest fetch failed (%d) %s";
std::string message = FormatUrlErrorMessage(
kFormatString, manifest_url_, fetcher->result(), response_code);
- HandleCacheFailure(AppCacheErrorDetails(message,
- APPCACHE_MANIFEST_ERROR,
- manifest_url_,
- response_code,
- false /*is_cross_origin*/),
- fetcher->result(),
- GURL());
+ HandleCacheFailure(
+ AppCacheErrorDetails(
+ message, AppCacheErrorReason::APPCACHE_MANIFEST_ERROR,
+ manifest_url_, response_code, false /*is_cross_origin*/),
+ fetcher->result(), GURL());
}
}
@@ -408,26 +408,23 @@ void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group,
bool success,
int response_code) {
DCHECK(master_entry_fetches_.empty());
- CancelAllMasterEntryFetches(AppCacheErrorDetails(
- "The cache has been made obsolete, "
- "the manifest file returned 404 or 410",
- APPCACHE_MANIFEST_ERROR,
- GURL(),
- response_code,
- false /*is_cross_origin*/));
+ CancelAllMasterEntryFetches(
+ AppCacheErrorDetails("The cache has been made obsolete, "
+ "the manifest file returned 404 or 410",
+ AppCacheErrorReason::APPCACHE_MANIFEST_ERROR, GURL(),
+ response_code, false /*is_cross_origin*/));
if (success) {
DCHECK(group->is_obsolete());
- NotifyAllAssociatedHosts(APPCACHE_OBSOLETE_EVENT);
+ NotifyAllAssociatedHosts(AppCacheEventID::APPCACHE_OBSOLETE_EVENT);
internal_state_ = COMPLETED;
MaybeCompleteUpdate();
} else {
// Treat failure to mark group obsolete as a cache failure.
- HandleCacheFailure(AppCacheErrorDetails(
- "Failed to mark the cache as obsolete",
- APPCACHE_UNKNOWN_ERROR, GURL(), 0,
- false /*is_cross_origin*/),
- DB_ERROR,
- GURL());
+ HandleCacheFailure(
+ AppCacheErrorDetails("Failed to mark the cache as obsolete",
+ AppCacheErrorReason::APPCACHE_UNKNOWN_ERROR,
+ GURL(), 0, false /*is_cross_origin*/),
+ DB_ERROR, GURL());
}
}
@@ -455,11 +452,10 @@ void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) {
const std::string message = base::StringPrintf(kFormatString,
manifest_url_.spec().c_str());
HandleCacheFailure(
- AppCacheErrorDetails(
- message, APPCACHE_SIGNATURE_ERROR, GURL(), 0,
- false /*is_cross_origin*/),
- MANIFEST_ERROR,
- GURL());
+ AppCacheErrorDetails(message,
+ AppCacheErrorReason::APPCACHE_SIGNATURE_ERROR,
+ GURL(), 0, false /*is_cross_origin*/),
+ MANIFEST_ERROR, GURL());
VLOG(1) << message;
return;
}
@@ -497,7 +493,7 @@ void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) {
}
group_->SetUpdateAppCacheStatus(AppCacheGroup::DOWNLOADING);
- NotifyAllAssociatedHosts(APPCACHE_DOWNLOADING_EVENT);
+ NotifyAllAssociatedHosts(AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
FetchUrls();
FetchMasterEntries();
MaybeCompleteUpdate(); // if not done, continues when async fetches complete
@@ -555,26 +551,23 @@ void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher,
case DISKCACHE_ERROR:
HandleCacheFailure(
AppCacheErrorDetails(
- message, APPCACHE_UNKNOWN_ERROR, GURL(), 0,
- is_cross_origin),
- result,
- url);
+ message, AppCacheErrorReason::APPCACHE_UNKNOWN_ERROR,
+ GURL(), 0, is_cross_origin),
+ result, url);
break;
case NETWORK_ERROR:
HandleCacheFailure(
- AppCacheErrorDetails(message, APPCACHE_RESOURCE_ERROR, url, 0,
- is_cross_origin),
- result,
- url);
+ AppCacheErrorDetails(
+ message, AppCacheErrorReason::APPCACHE_RESOURCE_ERROR, url,
+ 0, is_cross_origin),
+ result, url);
break;
default:
- HandleCacheFailure(AppCacheErrorDetails(message,
- APPCACHE_RESOURCE_ERROR,
- url,
- response_code,
- is_cross_origin),
- result,
- url);
+ HandleCacheFailure(
+ AppCacheErrorDetails(
+ message, AppCacheErrorReason::APPCACHE_RESOURCE_ERROR, url,
+ response_code, is_cross_origin),
+ result, url);
break;
}
return;
@@ -663,8 +656,8 @@ void AppCacheUpdateJob::HandleMasterEntryFetchCompleted(URLFetcher* fetcher,
std::string message = FormatUrlErrorMessage(
kFormatString, request->GetURL(), fetcher->result(), response_code);
host_notifier.SendErrorNotifications(AppCacheErrorDetails(
- message, APPCACHE_MANIFEST_ERROR, request->GetURL(), response_code,
- false /*is_cross_origin*/));
+ message, AppCacheErrorReason::APPCACHE_MANIFEST_ERROR,
+ request->GetURL(), response_code, false /*is_cross_origin*/));
// In downloading case, update result is different if all master entries
// failed vs. only some failing.
@@ -676,9 +669,9 @@ void AppCacheUpdateJob::HandleMasterEntryFetchCompleted(URLFetcher* fetcher,
// Section 6.9.4, step 22.3.
if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) {
HandleCacheFailure(
- AppCacheErrorDetails(message, APPCACHE_MANIFEST_ERROR,
- request->GetURL(), response_code,
- false /*is_cross_origin*/),
+ AppCacheErrorDetails(
+ message, AppCacheErrorReason::APPCACHE_MANIFEST_ERROR,
+ request->GetURL(), response_code, false /*is_cross_origin*/),
fetcher->result(), GURL());
return;
}
@@ -694,14 +687,16 @@ void AppCacheUpdateJob::HandleManifestRefetchCompleted(URLFetcher* fetcher,
int net_error) {
DCHECK(internal_state_ == REFETCH_MANIFEST);
DCHECK(manifest_fetcher_ == fetcher);
- manifest_fetcher_ = NULL;
+ manifest_fetcher_ = nullptr;
int response_code =
net_error == net::OK ? fetcher->request()->GetResponseCode() : -1;
if (response_code == 304 || manifest_data_ == fetcher->manifest_data()) {
// Only need to store response in storage if manifest is not already
// an entry in the cache.
- AppCacheEntry* entry = inprogress_cache_->GetEntry(manifest_url_);
+ AppCacheEntry* entry = nullptr;
+ if (inprogress_cache_)
+ entry = inprogress_cache_->GetEntry(manifest_url_);
if (entry) {
entry->add_types(AppCacheEntry::MANIFEST);
StoreGroupAndCache();
@@ -719,24 +714,20 @@ void AppCacheUpdateJob::HandleManifestRefetchCompleted(URLFetcher* fetcher,
<< " response code: " << response_code;
ScheduleUpdateRetry(kRerunDelayMs);
if (response_code == 200) {
- HandleCacheFailure(AppCacheErrorDetails("Manifest changed during update",
- APPCACHE_CHANGED_ERROR,
- GURL(),
- 0,
- false /*is_cross_origin*/),
- MANIFEST_ERROR,
- GURL());
+ HandleCacheFailure(
+ AppCacheErrorDetails("Manifest changed during update",
+ AppCacheErrorReason::APPCACHE_CHANGED_ERROR,
+ GURL(), 0, false /*is_cross_origin*/),
+ MANIFEST_ERROR, GURL());
} else {
const char kFormatString[] = "Manifest re-fetch failed (%d) %s";
std::string message = FormatUrlErrorMessage(
kFormatString, manifest_url_, fetcher->result(), response_code);
- HandleCacheFailure(AppCacheErrorDetails(message,
- APPCACHE_MANIFEST_ERROR,
- GURL(),
- response_code,
- false /*is_cross_origin*/),
- fetcher->result(),
- GURL());
+ HandleCacheFailure(
+ AppCacheErrorDetails(
+ message, AppCacheErrorReason::APPCACHE_MANIFEST_ERROR, GURL(),
+ response_code, false /*is_cross_origin*/),
+ fetcher->result(), GURL());
}
}
}
@@ -753,12 +744,9 @@ void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) {
} else {
HandleCacheFailure(
AppCacheErrorDetails("Failed to write the manifest headers to storage",
- APPCACHE_UNKNOWN_ERROR,
- GURL(),
- 0,
- false /*is_cross_origin*/),
- DISKCACHE_ERROR,
- GURL());
+ AppCacheErrorReason::APPCACHE_UNKNOWN_ERROR,
+ GURL(), 0, false /*is_cross_origin*/),
+ DISKCACHE_ERROR, GURL());
}
}
@@ -773,12 +761,9 @@ void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) {
} else {
HandleCacheFailure(
AppCacheErrorDetails("Failed to write the manifest data to storage",
- APPCACHE_UNKNOWN_ERROR,
- GURL(),
- 0,
- false /*is_cross_origin*/),
- DISKCACHE_ERROR,
- GURL());
+ AppCacheErrorReason::APPCACHE_UNKNOWN_ERROR,
+ GURL(), 0, false /*is_cross_origin*/),
+ DISKCACHE_ERROR, GURL());
}
}
@@ -819,12 +804,12 @@ void AppCacheUpdateJob::OnGroupAndNewestCacheStored(AppCacheGroup* group,
inprogress_cache_ = newest_cache;
ResultType result = DB_ERROR;
- AppCacheErrorReason reason = APPCACHE_UNKNOWN_ERROR;
+ AppCacheErrorReason reason = AppCacheErrorReason::APPCACHE_UNKNOWN_ERROR;
std::string message("Failed to commit new cache to storage");
if (would_exceed_quota) {
message.append(", would exceed quota");
result = QUOTA_ERROR;
- reason = APPCACHE_QUOTA_ERROR;
+ reason = AppCacheErrorReason::APPCACHE_QUOTA_ERROR;
}
HandleCacheFailure(
AppCacheErrorDetails(message, reason, GURL(), 0,
@@ -911,7 +896,7 @@ void AppCacheUpdateJob::OnServiceReinitialized(
void AppCacheUpdateJob::CheckIfManifestChanged() {
DCHECK(update_type_ == UPGRADE_ATTEMPT);
- AppCacheEntry* entry = NULL;
+ AppCacheEntry* entry = nullptr;
if (group_->newest_complete_cache())
entry = group_->newest_complete_cache()->GetEntry(manifest_url_);
if (!entry) {
@@ -922,12 +907,9 @@ void AppCacheUpdateJob::CheckIfManifestChanged() {
AppCacheServiceImpl* service = service_;
HandleCacheFailure(
AppCacheErrorDetails("Manifest entry not found in existing cache",
- APPCACHE_UNKNOWN_ERROR,
- GURL(),
- 0,
- false /*is_cross_origin*/),
- DB_ERROR,
- GURL());
+ AppCacheErrorReason::APPCACHE_UNKNOWN_ERROR,
+ GURL(), 0, false /*is_cross_origin*/),
+ DB_ERROR, GURL());
AppCacheHistograms::AddMissingManifestEntrySample();
service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback());
}
@@ -938,10 +920,9 @@ void AppCacheUpdateJob::CheckIfManifestChanged() {
manifest_response_reader_.reset(
storage_->CreateResponseReader(manifest_url_,
entry->response_id()));
- read_manifest_buffer_ = new net::IOBuffer(kBufferSize);
+ read_manifest_buffer_ = new net::IOBuffer(kAppCacheFetchBufferSize);
manifest_response_reader_->ReadData(
- read_manifest_buffer_.get(),
- kBufferSize,
+ read_manifest_buffer_.get(), kAppCacheFetchBufferSize,
base::Bind(&AppCacheUpdateJob::OnManifestDataReadComplete,
base::Unretained(this))); // async read
}
@@ -950,12 +931,11 @@ void AppCacheUpdateJob::OnManifestDataReadComplete(int result) {
if (result > 0) {
loaded_manifest_data_.append(read_manifest_buffer_->data(), result);
manifest_response_reader_->ReadData(
- read_manifest_buffer_.get(),
- kBufferSize,
+ read_manifest_buffer_.get(), kAppCacheFetchBufferSize,
base::Bind(&AppCacheUpdateJob::OnManifestDataReadComplete,
base::Unretained(this))); // read more
} else {
- read_manifest_buffer_ = NULL;
+ read_manifest_buffer_ = nullptr;
manifest_response_reader_.reset();
ContinueHandleManifestFetchCompleted(
result < 0 || manifest_data_ != loaded_manifest_data_);
@@ -973,10 +953,7 @@ void AppCacheUpdateJob::BuildUrlFileList(const AppCacheManifest& manifest) {
manifest.intercept_namespaces;
for (std::vector<AppCacheNamespace>::const_iterator it = intercepts.begin();
it != intercepts.end(); ++it) {
- int flags = AppCacheEntry::INTERCEPT;
- if (it->is_executable)
- flags |= AppCacheEntry::EXECUTABLE;
- AddUrlToFileList(it->target_url, flags);
+ AddUrlToFileList(it->target_url, AppCacheEntry::INTERCEPT);
}
const std::vector<AppCacheNamespace>& fallbacks =
@@ -1004,7 +981,7 @@ void AppCacheUpdateJob::AddUrlToFileList(const GURL& url, int type) {
AppCache::EntryMap::value_type(url, AppCacheEntry(type)));
if (ret.second)
- urls_to_fetch_.push_back(UrlToFetch(url, false, NULL));
+ urls_to_fetch_.push_back(UrlToFetch(url, false, nullptr));
else
ret.first->second.add_types(type); // URL already exists. Merge types.
}
@@ -1033,8 +1010,9 @@ void AppCacheUpdateJob::FetchUrls() {
MaybeLoadFromNewestCache(url_to_fetch.url, entry)) {
// Continues asynchronously after data is loaded from newest cache.
} else {
- URLFetcher* fetcher = new URLFetcher(
- url_to_fetch.url, URLFetcher::URL_FETCH, this, kBufferSize);
+ URLFetcher* fetcher =
+ new URLFetcher(url_to_fetch.url, URLFetcher::URL_FETCH, this,
+ kAppCacheFetchBufferSize);
if (url_to_fetch.existing_response_info.get() &&
group_->newest_complete_cache()) {
AppCacheEntry* existing_entry =
@@ -1157,7 +1135,7 @@ void AppCacheUpdateJob::FetchMasterEntries() {
}
} else {
URLFetcher* fetcher = new URLFetcher(url, URLFetcher::MASTER_ENTRY_FETCH,
- this, kBufferSize);
+ this, kAppCacheFetchBufferSize);
fetcher->Start();
master_entry_fetches_.insert(PendingUrlFetches::value_type(url, fetcher));
}
@@ -1227,8 +1205,8 @@ bool AppCacheUpdateJob::MaybeLoadFromNewestCache(const GURL& url,
void AppCacheUpdateJob::OnResponseInfoLoaded(
AppCacheResponseInfo* response_info,
int64_t response_id) {
- const net::HttpResponseInfo* http_info = response_info ?
- response_info->http_response_info() : NULL;
+ const net::HttpResponseInfo* http_info =
+ response_info ? response_info->http_response_info() : nullptr;
// Needed response info for a manifest fetch request.
if (internal_state_ == FETCH_MANIFEST) {
@@ -1244,7 +1222,7 @@ void AppCacheUpdateJob::OnResponseInfoLoaded(
const GURL& url = found->second;
if (!http_info) {
- LoadFromNewestCacheFailed(url, NULL); // no response found
+ LoadFromNewestCacheFailed(url, nullptr); // no response found
} else if (!CanUseExistingResource(http_info)) {
LoadFromNewestCacheFailed(url, response_info);
} else {
@@ -1314,7 +1292,7 @@ void AppCacheUpdateJob::MaybeCompleteUpdate() {
}
group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE);
// 6.9.4 steps 7.3-7.7.
- NotifyAllAssociatedHosts(APPCACHE_NO_UPDATE_EVENT);
+ NotifyAllAssociatedHosts(AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
DiscardDuplicateResponses();
internal_state_ = COMPLETED;
break;
@@ -1327,9 +1305,9 @@ void AppCacheUpdateJob::MaybeCompleteUpdate() {
NotifyAllFinalProgress();
group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE);
if (update_type_ == CACHE_ATTEMPT)
- NotifyAllAssociatedHosts(APPCACHE_CACHED_EVENT);
+ NotifyAllAssociatedHosts(AppCacheEventID::APPCACHE_CACHED_EVENT);
else
- NotifyAllAssociatedHosts(APPCACHE_UPDATE_READY_EVENT);
+ NotifyAllAssociatedHosts(AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
DiscardDuplicateResponses();
internal_state_ = COMPLETED;
LogHistogramStats(UPDATE_OK, GURL());
@@ -1360,7 +1338,7 @@ void AppCacheUpdateJob::Cancel() {
if (manifest_fetcher_) {
delete manifest_fetcher_;
- manifest_fetcher_ = NULL;
+ manifest_fetcher_ = nullptr;
}
for (PendingUrlFetches::iterator it = pending_url_fetches_.begin();
@@ -1403,7 +1381,7 @@ void AppCacheUpdateJob::DiscardInprogressCache() {
// We can make no assumptions about whether the StoreGroupAndCacheTask
// actually completed or not. This condition should only be reachable
// during shutdown. Free things up and return to do no harm.
- inprogress_cache_ = NULL;
+ inprogress_cache_ = nullptr;
added_master_entries_.clear();
return;
}
@@ -1426,7 +1404,7 @@ void AppCacheUpdateJob::DiscardInprogressCache() {
while (!hosts.empty())
(*hosts.begin())->AssociateNoCache(GURL());
- inprogress_cache_ = NULL;
+ inprogress_cache_ = nullptr;
added_master_entries_.clear();
}
@@ -1470,13 +1448,13 @@ void AppCacheUpdateJob::DeleteSoon() {
manifest_response_writer_.reset();
storage_->CancelDelegateCallbacks(this);
service_->RemoveObserver(this);
- service_ = NULL;
+ service_ = nullptr;
// Break the connection with the group so the group cannot call delete
// on this object after we've posted a task to delete ourselves.
if (group_) {
group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE);
- group_ = NULL;
+ group_ = nullptr;
}
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
diff --git a/chromium/content/browser/appcache/appcache_update_job.h b/chromium/content/browser/appcache/appcache_update_job.h
index c3785e97e15..3ea0b210237 100644
--- a/chromium/content/browser/appcache/appcache_update_job.h
+++ b/chromium/content/browser/appcache/appcache_update_job.h
@@ -36,7 +36,6 @@ FORWARD_DECLARE_TEST(AppCacheGroupTest, QueueUpdate);
class AppCacheGroupTest;
class AppCacheUpdateJobTest;
class HostNotifier;
-class URLFetcher;
// Application cache Update algorithm and state.
class CONTENT_EXPORT AppCacheUpdateJob
diff --git a/chromium/content/browser/appcache/appcache_update_job_unittest.cc b/chromium/content/browser/appcache/appcache_update_job_unittest.cc
index 27387f5cc99..8086c707580 100644
--- a/chromium/content/browser/appcache/appcache_update_job_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_update_job_unittest.cc
@@ -245,10 +245,12 @@ inline bool operator==(const AppCacheNamespace& lhs,
class MockFrontend : public AppCacheFrontend {
public:
MockFrontend()
- : ignore_progress_events_(false), verify_progress_events_(false),
- last_progress_total_(-1), last_progress_complete_(-1),
- start_update_trigger_(APPCACHE_CHECKING_EVENT), update_(NULL) {
- }
+ : ignore_progress_events_(false),
+ verify_progress_events_(false),
+ last_progress_total_(-1),
+ last_progress_complete_(-1),
+ start_update_trigger_(AppCacheEventID::APPCACHE_CHECKING_EVENT),
+ update_(nullptr) {}
void OnCacheSelected(int host_id, const AppCacheInfo& info) override {}
@@ -274,7 +276,7 @@ class MockFrontend : public AppCacheFrontend {
void OnErrorEventRaised(const std::vector<int>& host_ids,
const AppCacheErrorDetails& details) override {
error_message_ = details.message;
- OnEventRaised(host_ids, APPCACHE_ERROR_EVENT);
+ OnEventRaised(host_ids, AppCacheEventID::APPCACHE_ERROR_EVENT);
}
void OnProgressEventRaised(const std::vector<int>& host_ids,
@@ -282,7 +284,7 @@ class MockFrontend : public AppCacheFrontend {
int num_total,
int num_complete) override {
if (!ignore_progress_events_)
- OnEventRaised(host_ids, APPCACHE_PROGRESS_EVENT);
+ OnEventRaised(host_ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
if (verify_progress_events_) {
EXPECT_GE(num_total, num_complete);
@@ -320,7 +322,8 @@ class MockFrontend : public AppCacheFrontend {
void AddExpectedEvent(const std::vector<int>& host_ids,
AppCacheEventID event_id) {
- DCHECK(!ignore_progress_events_ || event_id != APPCACHE_PROGRESS_EVENT);
+ DCHECK(!ignore_progress_events_ ||
+ event_id != AppCacheEventID::APPCACHE_PROGRESS_EVENT);
expected_events_.push_back(RaisedEvent(host_ids, event_id));
}
@@ -590,10 +593,7 @@ class IfModifiedSinceJobFactory
// classes by refactoring the response headers/data into a common class.
class MockURLLoaderFactory : public mojom::URLLoaderFactory {
public:
- static void Create(mojom::URLLoaderFactoryPtr* loader_factory) {
- mojom::URLLoaderFactoryRequest request = mojo::MakeRequest(loader_factory);
- new MockURLLoaderFactory(std::move(request));
- }
+ MockURLLoaderFactory() {}
// mojom::URLLoaderFactory implementation.
void CreateLoaderAndStart(mojom::URLLoaderRequest request,
@@ -606,9 +606,7 @@ class MockURLLoaderFactory : public mojom::URLLoaderFactory {
traffic_annotation) override {
if (url_request.url.host() == "failme" ||
url_request.url.host() == "testme") {
- ResourceRequestCompletionStatus status;
- status.error_code = -100;
- client->OnComplete(status);
+ client->OnComplete(network::URLLoaderCompletionStatus(-100));
return;
}
@@ -643,16 +641,6 @@ class MockURLLoaderFactory : public mojom::URLLoaderFactory {
void Clone(mojom::URLLoaderFactoryRequest factory) override { NOTREACHED(); }
private:
- MockURLLoaderFactory(mojom::URLLoaderFactoryRequest request)
- : binding_(this, std::move(request)) {
- binding_.set_connection_error_handler(base::BindOnce(
- &MockURLLoaderFactory::OnConnectionError, base::Unretained(this)));
- }
-
- void OnConnectionError() { delete this; }
-
- mojo::Binding<mojom::URLLoaderFactory> binding_;
-
DISALLOW_COPY_AND_ASSIGN(MockURLLoaderFactory);
};
@@ -711,11 +699,11 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_is_being_deleted_(false),
expect_evictable_error_(false),
expect_eviction_(false),
- expect_old_cache_(NULL),
- expect_newest_cache_(NULL),
+ expect_old_cache_(nullptr),
+ expect_newest_cache_(nullptr),
expect_non_null_update_time_(false),
tested_manifest_(NONE),
- tested_manifest_path_override_(NULL),
+ tested_manifest_path_override_(nullptr),
request_handler_type_(GetParam()),
thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD) {
BrowserThread::PostTask(
@@ -760,10 +748,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
void InitializeFactory() {
if (!loader_factory_getter_.get())
return;
- mojom::URLLoaderFactoryPtr test_loader_factory;
- MockURLLoaderFactory::Create(&test_loader_factory);
loader_factory_getter_->SetNetworkFactoryForTesting(
- std::move(test_loader_factory));
+ &mock_url_loader_factory_);
}
void StartCacheAttemptTest() {
@@ -794,7 +780,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
EXPECT_EQ(expected, events.size());
EXPECT_EQ(expected, events[0].first.size());
EXPECT_EQ(host.host_id(), events[0].first[0]);
- EXPECT_EQ(APPCACHE_CHECKING_EVENT, events[0].second);
+ EXPECT_EQ(AppCacheEventID::APPCACHE_CHECKING_EVENT, events[0].second);
// Abort as we're not testing actual URL fetches in this test.
delete update;
@@ -851,14 +837,14 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
!= host_ids.end());
EXPECT_TRUE(std::find(host_ids.begin(), host_ids.end(), host3.host_id())
!= host_ids.end());
- EXPECT_EQ(APPCACHE_CHECKING_EVENT, events[0].second);
+ EXPECT_EQ(AppCacheEventID::APPCACHE_CHECKING_EVENT, events[0].second);
events = mock_frontend2.raised_events_;
expected = 1;
EXPECT_EQ(expected, events.size());
EXPECT_EQ(expected, events[0].first.size()); // 1 host using frontend2
EXPECT_EQ(host2.host_id(), events[0].first[0]);
- EXPECT_EQ(APPCACHE_CHECKING_EVENT, events[0].second);
+ EXPECT_EQ(AppCacheEventID::APPCACHE_CHECKING_EVENT, events[0].second);
events = mock_frontend3.raised_events_;
EXPECT_TRUE(events.empty());
@@ -888,7 +874,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false;
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -914,7 +900,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
group_->set_last_full_update_check_time(
base::Time::Now() - kFullUpdateInterval - kOneHour);
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
EXPECT_TRUE(update->doing_full_update_check_);
// Set up checks for when update job finishes.
@@ -925,11 +911,11 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_newest_cache_ = cache; // newest cache unaffected by update
expect_full_update_time_equal_to_ = group_->last_full_update_check_time();
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_ERROR_EVENT);
WaitForUpdateToFinish();
}
@@ -961,7 +947,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false; // redirect is like a failed request
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -985,7 +971,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
frontend->SetVerifyProgressEvents(true);
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
// Set up checks for when update job finishes.
do_checks_after_update_finished_ = true;
@@ -995,10 +981,13 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
tested_manifest_ = EMPTY_MANIFEST;
tested_manifest_path_override_ = "files/missing-mime-manifest";
MockFrontend::HostIds ids(1, host->host_id());
- frontend->AddExpectedEvent(ids, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_DOWNLOADING_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); // final
- frontend->AddExpectedEvent(ids, APPCACHE_UPDATE_READY_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend->AddExpectedEvent(
+ ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend->AddExpectedEvent(ids,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
WaitForUpdateToFinish();
}
@@ -1022,7 +1011,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
host1->AssociateCompleteCache(cache);
host2->AssociateCompleteCache(cache);
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
// Set up checks for when update job finishes.
do_checks_after_update_finished_ = true;
@@ -1030,11 +1019,11 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_has_cache_ = true;
expect_newest_cache_ = cache; // newest cache unaffected by update
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_OBSOLETE_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_OBSOLETE_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_OBSOLETE_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_OBSOLETE_EVENT);
WaitForUpdateToFinish();
}
@@ -1059,7 +1048,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false;
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -1084,7 +1073,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false; // treated like cache failure
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -1111,7 +1100,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
group_->set_last_full_update_check_time(
base::Time::Now() - kFullUpdateInterval - kOneHour);
group_->set_first_evictable_error_time(base::Time::Now());
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
EXPECT_TRUE(update->doing_full_update_check_);
// Set up checks for when update job finishes.
@@ -1122,11 +1111,13 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_evictable_error_ = false; // should be reset
expect_full_update_time_newer_than_ = group_->last_full_update_check_time();
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_NO_UPDATE_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_NO_UPDATE_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
WaitForUpdateToFinish();
}
@@ -1160,11 +1151,13 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_has_cache_ = true;
expect_newest_cache_ = cache; // newest cache unaffected by update
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_NO_UPDATE_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_NO_UPDATE_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
// Seed storage with expected manifest data.
const std::string seed_data(kManifest1Contents);
@@ -1199,7 +1192,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
AppCacheHost* host = MakeHost(1, frontend);
host->AssociateCompleteCache(cache);
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
// Set up checks for when update job finishes.
do_checks_after_update_finished_ = true;
@@ -1207,8 +1200,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_has_cache_ = true;
expect_newest_cache_ = cache; // newest cache unaffected by update
MockFrontend::HostIds id(1, host->host_id());
- frontend->AddExpectedEvent(id, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(id, APPCACHE_ERROR_EVENT);
+ frontend->AddExpectedEvent(id, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(id, AppCacheEventID::APPCACHE_ERROR_EVENT);
frontend->expected_error_message_ =
"Manifest entry not found in existing cache";
WaitForUpdateToFinish();
@@ -1219,7 +1212,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
response_writer_.reset();
AppCacheUpdateJob* update = group_->update_job_;
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
WaitForUpdateToFinish();
}
@@ -1249,7 +1242,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_full_update_time_newer_than_ = base::Time::Now() - kOneHour;
tested_manifest_ = MANIFEST1;
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -1277,7 +1270,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_has_cache_ = true;
tested_manifest_ = MANIFEST_WITH_INTERCEPT;
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -1318,19 +1311,25 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
tested_manifest_ = MANIFEST1;
expect_full_update_time_newer_than_ = group_->last_full_update_check_time();
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final
- frontend2->AddExpectedEvent(ids2, APPCACHE_UPDATE_READY_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
// Seed storage with expected manifest data different from manifest1.
const std::string seed_data("different");
@@ -1378,12 +1377,15 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
response_writer_->response_id()));
tested_manifest_ = MANIFEST1;
MockFrontend::HostIds ids(1, host->host_id());
- frontend->AddExpectedEvent(ids, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_DOWNLOADING_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); // final
- frontend->AddExpectedEvent(ids, APPCACHE_UPDATE_READY_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(
+ ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend->AddExpectedEvent(ids,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
// Seed storage with expected http response info for entry. Allow reuse.
const char data[] =
@@ -1437,12 +1439,15 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_old_cache_ = cache;
tested_manifest_ = MANIFEST1;
MockFrontend::HostIds ids(1, host->host_id());
- frontend->AddExpectedEvent(ids, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_DOWNLOADING_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); // final
- frontend->AddExpectedEvent(ids, APPCACHE_UPDATE_READY_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(
+ ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend->AddExpectedEvent(ids,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
// Seed storage with expected http response info for entry. Do NOT
// allow reuse by setting an expires header in the past.
@@ -1497,12 +1502,15 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_old_cache_ = cache;
tested_manifest_ = MANIFEST1;
MockFrontend::HostIds ids(1, host->host_id());
- frontend->AddExpectedEvent(ids, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_DOWNLOADING_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); // final
- frontend->AddExpectedEvent(ids, APPCACHE_UPDATE_READY_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(
+ ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend->AddExpectedEvent(ids,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
// Seed storage with expected http response info for entry: a vary header.
const char data[] =
@@ -1560,12 +1568,15 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
response_writer_->response_id()));
tested_manifest_ = MANIFEST1;
MockFrontend::HostIds ids(1, host->host_id());
- frontend->AddExpectedEvent(ids, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_DOWNLOADING_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); // final
- frontend->AddExpectedEvent(ids, APPCACHE_UPDATE_READY_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(
+ ids, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend->AddExpectedEvent(ids,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
// Seed storage with expected http response info for an entry
// with a vary header for which we allow reuse.
@@ -1615,7 +1626,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"),
AppCacheEntry(AppCacheEntry::MASTER, 111));
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
// Set up checks for when update job finishes.
do_checks_after_update_finished_ = true;
@@ -1624,19 +1635,27 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_old_cache_ = cache;
tested_manifest_ = MANIFEST_MERGED_TYPES;
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // explicit1
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // manifest
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // explicit1
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // manifest
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final
- frontend2->AddExpectedEvent(ids2, APPCACHE_UPDATE_READY_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
WaitForUpdateToFinish();
}
@@ -1661,7 +1680,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false; // 404 explicit url is cache failure
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -1689,7 +1708,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
host1->AssociateCompleteCache(cache);
host2->AssociateCompleteCache(cache);
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
// Set up checks for when update job finishes.
do_checks_after_update_finished_ = true;
@@ -1698,13 +1717,15 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_newest_cache_ = cache; // newest cache unaffectd by failed update
expect_eviction_ = true;
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_ERROR_EVENT);
WaitForUpdateToFinish();
}
@@ -1757,7 +1778,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
MakeAppCacheResponseInfo(kManifestUrl, 444, kRawHeaders);
MakeAppCacheResponseInfo(kManifestUrl, 555, kRawHeaders);
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
// Set up checks for when update job finishes.
do_checks_after_update_finished_ = true;
@@ -1779,27 +1800,45 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_response_ids_.insert(std::map<GURL, int64_t>::value_type(
MockHttpServer::GetMockUrl("files/notmodified"), 555)); // copied
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // explicit1
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // fallback1a
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // notfound
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // explicit2
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // servererror
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // notmodified
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // explicit1
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // fallback1a
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // notfound
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // explicit2
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // servererror
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // notmodified
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // explicit1
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // fallback1a
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // notfound
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // explicit2
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // servererror
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // notmodified
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final
- frontend2->AddExpectedEvent(ids2, APPCACHE_UPDATE_READY_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // explicit1
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // fallback1a
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // notfound
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // explicit2
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // servererror
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // notmodified
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
WaitForUpdateToFinish();
}
@@ -1825,7 +1864,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
frontend1->SetVerifyProgressEvents(true);
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
// Set up checks for when update job finishes.
do_checks_after_update_finished_ = true;
@@ -1834,15 +1873,21 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_old_cache_ = cache;
tested_manifest_ = EMPTY_MANIFEST;
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final
- frontend2->AddExpectedEvent(ids2, APPCACHE_UPDATE_READY_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
WaitForUpdateToFinish();
}
@@ -1872,11 +1917,14 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_has_cache_ = true;
tested_manifest_ = EMPTY_FILE_MANIFEST;
MockFrontend::HostIds ids1(1, host->host_id());
- frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
WaitForUpdateToFinish();
}
@@ -1913,7 +1961,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false;
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -1950,7 +1998,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false;
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -1988,7 +2036,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false;
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -2025,7 +2073,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = true;
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -2062,7 +2110,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = true;
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -2091,7 +2139,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false; // storage failed
frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()),
- APPCACHE_CHECKING_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -2119,7 +2167,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
host1->AssociateCompleteCache(cache);
host2->AssociateCompleteCache(cache);
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
// Set up checks for when update job finishes.
do_checks_after_update_finished_ = true;
@@ -2127,17 +2175,19 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_has_cache_ = true;
expect_newest_cache_ = cache; // unchanged
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_ERROR_EVENT);
WaitForUpdateToFinish();
}
@@ -2185,7 +2235,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_has_cache_ = true;
expect_newest_cache_ = cache.get(); // unchanged
MockFrontend::HostIds ids1(1, host->host_id());
- frontend->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
frontend->expected_error_message_ =
"Failed to commit new cache to storage";
@@ -2215,7 +2265,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
host1->AssociateCompleteCache(cache);
host2->AssociateCompleteCache(cache);
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
// Set up checks for when update job finishes.
do_checks_after_update_finished_ = true;
@@ -2223,11 +2273,11 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_has_cache_ = true;
expect_newest_cache_ = cache; // newest cache unaffected by update
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_ERROR_EVENT);
WaitForUpdateToFinish();
}
@@ -2251,8 +2301,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false;
MockFrontend::HostIds ids1(1, host->host_id());
- frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
WaitForUpdateToFinish();
}
@@ -2277,8 +2327,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false;
MockFrontend::HostIds ids1(1, host->host_id());
- frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
WaitForUpdateToFinish();
}
@@ -2306,8 +2356,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false;
MockFrontend::HostIds ids1(1, host->host_id());
- frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
WaitForUpdateToFinish();
}
@@ -2335,9 +2385,10 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false; // 404 fallback url is cache failure
MockFrontend::HostIds ids1(1, host->host_id());
- frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
WaitForUpdateToFinish();
}
@@ -2373,13 +2424,15 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_obsolete_ = false;
expect_group_has_cache_ = false; // all pending masters failed
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_ERROR_EVENT);
WaitForUpdateToFinish();
}
@@ -2422,19 +2475,24 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_old_cache_ = cache;
tested_manifest_ = MANIFEST1;
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_ERROR_EVENT);
MockFrontend::HostIds ids3(1, host3->host_id());
- frontend3->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_DOWNLOADING_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_ERROR_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend3->AddExpectedEvent(ids3,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_ERROR_EVENT);
WaitForUpdateToFinish();
}
@@ -2473,16 +2531,19 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
MockHttpServer::GetMockUrl("files/explicit2"),
AppCacheEntry(AppCacheEntry::MASTER)));
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_ERROR_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final
- frontend2->AddExpectedEvent(ids2, APPCACHE_CACHED_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CACHED_EVENT);
WaitForUpdateToFinish();
}
@@ -2527,22 +2588,29 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
MockHttpServer::GetMockUrl("files/explicit2"),
AppCacheEntry(AppCacheEntry::MASTER)));
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_ERROR_EVENT);
MockFrontend::HostIds ids3(1, host3->host_id());
- frontend3->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_DOWNLOADING_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); // final
- frontend3->AddExpectedEvent(ids3, APPCACHE_UPDATE_READY_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend3->AddExpectedEvent(ids3,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend3->AddExpectedEvent(
+ ids3, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend3->AddExpectedEvent(ids3,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
WaitForUpdateToFinish();
}
@@ -2589,14 +2657,16 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_non_null_update_time_ = true;
tested_manifest_ = PENDING_MASTER_NO_UPDATE;
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_NO_UPDATE_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
MockFrontend::HostIds ids3(1, host3->host_id());
- frontend2->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_CHECKING_EVENT);
MockFrontend::HostIds ids2and3;
ids2and3.push_back(host2->host_id());
ids2and3.push_back(host3->host_id());
- frontend2->AddExpectedEvent(ids2and3, APPCACHE_NO_UPDATE_EVENT);
+ frontend2->AddExpectedEvent(ids2and3,
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
WaitForUpdateToFinish();
}
@@ -2638,11 +2708,12 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
MockFrontend* frontend5 = MakeMockFrontend();
AppCacheHost* host5 = MakeHost(5, frontend5); // no master entry url
- frontend1->TriggerAdditionalUpdates(APPCACHE_DOWNLOADING_EVENT, update);
+ frontend1->TriggerAdditionalUpdates(
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT, update);
frontend1->AdditionalUpdateHost(host2); // fetch will fail
frontend1->AdditionalUpdateHost(host3); // same as an explicit entry
frontend1->AdditionalUpdateHost(host4); // same as another master entry
- frontend1->AdditionalUpdateHost(NULL); // no host
+ frontend1->AdditionalUpdateHost(nullptr); // no host
frontend1->AdditionalUpdateHost(host5); // no master entry url
// Set up checks for when update job finishes.
@@ -2654,35 +2725,43 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
MockHttpServer::GetMockUrl("files/explicit2"),
AppCacheEntry(AppCacheEntry::MASTER)));
MockFrontend::HostIds ids1(1, host1->host_id());
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend1->AddExpectedEvent(ids1, APPCACHE_CACHED_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CACHED_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_ERROR_EVENT);
MockFrontend::HostIds ids3(1, host3->host_id());
- frontend3->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_DOWNLOADING_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); // final
- frontend3->AddExpectedEvent(ids3, APPCACHE_CACHED_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend3->AddExpectedEvent(ids3,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend3->AddExpectedEvent(
+ ids3, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_CACHED_EVENT);
MockFrontend::HostIds ids4(1, host4->host_id());
- frontend4->AddExpectedEvent(ids4, APPCACHE_CHECKING_EVENT);
- frontend4->AddExpectedEvent(ids4, APPCACHE_DOWNLOADING_EVENT);
- frontend4->AddExpectedEvent(ids4, APPCACHE_PROGRESS_EVENT);
- frontend4->AddExpectedEvent(ids4, APPCACHE_PROGRESS_EVENT);
- frontend4->AddExpectedEvent(ids4, APPCACHE_PROGRESS_EVENT); // final
- frontend4->AddExpectedEvent(ids4, APPCACHE_CACHED_EVENT);
+ frontend4->AddExpectedEvent(ids4, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend4->AddExpectedEvent(ids4,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend4->AddExpectedEvent(ids4, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend4->AddExpectedEvent(ids4, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend4->AddExpectedEvent(
+ ids4, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend4->AddExpectedEvent(ids4, AppCacheEventID::APPCACHE_CACHED_EVENT);
// Host 5 is not associated with cache so no progress/cached events.
MockFrontend::HostIds ids5(1, host5->host_id());
- frontend5->AddExpectedEvent(ids5, APPCACHE_CHECKING_EVENT);
- frontend5->AddExpectedEvent(ids5, APPCACHE_DOWNLOADING_EVENT);
+ frontend5->AddExpectedEvent(ids5, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend5->AddExpectedEvent(ids5,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
WaitForUpdateToFinish();
}
@@ -2734,9 +2813,10 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
host6->new_master_entry_url_ =
MockHttpServer::GetMockUrl("files/explicit1");
- frontend2->TriggerAdditionalUpdates(APPCACHE_ERROR_EVENT, update);
+ frontend2->TriggerAdditionalUpdates(AppCacheEventID::APPCACHE_ERROR_EVENT,
+ update);
frontend2->AdditionalUpdateHost(host3);
- frontend2->AdditionalUpdateHost(NULL); // no host
+ frontend2->AdditionalUpdateHost(nullptr); // no host
frontend2->AdditionalUpdateHost(host4); // no master entry url
frontend2->AdditionalUpdateHost(host5); // same as existing cache entry
frontend2->AdditionalUpdateHost(host6); // same as another master entry
@@ -2748,21 +2828,25 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_newest_cache_ = cache; // newest cache unaffected by update
tested_manifest_ = PENDING_MASTER_NO_UPDATE;
MockFrontend::HostIds ids1(1, host1->host_id()); // prior associated host
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_NO_UPDATE_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_ERROR_EVENT);
MockFrontend::HostIds ids3(1, host3->host_id());
- frontend3->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_NO_UPDATE_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend3->AddExpectedEvent(ids3,
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
MockFrontend::HostIds ids4(1, host4->host_id()); // unassociated w/cache
- frontend4->AddExpectedEvent(ids4, APPCACHE_CHECKING_EVENT);
+ frontend4->AddExpectedEvent(ids4, AppCacheEventID::APPCACHE_CHECKING_EVENT);
MockFrontend::HostIds ids5(1, host5->host_id());
- frontend5->AddExpectedEvent(ids5, APPCACHE_CHECKING_EVENT);
- frontend5->AddExpectedEvent(ids5, APPCACHE_NO_UPDATE_EVENT);
+ frontend5->AddExpectedEvent(ids5, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend5->AddExpectedEvent(ids5,
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
MockFrontend::HostIds ids6(1, host6->host_id());
- frontend6->AddExpectedEvent(ids6, APPCACHE_CHECKING_EVENT);
- frontend6->AddExpectedEvent(ids6, APPCACHE_NO_UPDATE_EVENT);
+ frontend6->AddExpectedEvent(ids6, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend6->AddExpectedEvent(ids6,
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
WaitForUpdateToFinish();
}
@@ -2784,7 +2868,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
AppCacheHost* host1 = MakeHost(1, frontend1);
host1->AssociateCompleteCache(cache);
- update->StartUpdate(NULL, GURL());
+ update->StartUpdate(nullptr, GURL());
// Set up additional updates to be started while update is in progress.
MockFrontend* frontend2 = MakeMockFrontend();
@@ -2805,9 +2889,10 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
host5->new_master_entry_url_ =
MockHttpServer::GetMockUrl("files/explicit2");
- frontend1->TriggerAdditionalUpdates(APPCACHE_PROGRESS_EVENT, update);
+ frontend1->TriggerAdditionalUpdates(
+ AppCacheEventID::APPCACHE_PROGRESS_EVENT, update);
frontend1->AdditionalUpdateHost(host2); // same as entry in manifest
- frontend1->AdditionalUpdateHost(NULL); // no host
+ frontend1->AdditionalUpdateHost(nullptr); // no host
frontend1->AdditionalUpdateHost(host3); // new master entry
frontend1->AdditionalUpdateHost(host4); // no master entry url
frontend1->AdditionalUpdateHost(host5); // same as another master entry
@@ -2821,33 +2906,46 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
MockHttpServer::GetMockUrl("files/explicit2"),
AppCacheEntry(AppCacheEntry::MASTER)));
MockFrontend::HostIds ids1(1, host1->host_id()); // prior associated host
- frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend1->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend1->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
MockFrontend::HostIds ids2(1, host2->host_id());
- frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT);
- frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final
- frontend2->AddExpectedEvent(ids2, APPCACHE_UPDATE_READY_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend2->AddExpectedEvent(ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend2->AddExpectedEvent(
+ ids2, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend2->AddExpectedEvent(ids2,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
MockFrontend::HostIds ids3(1, host3->host_id());
- frontend3->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_DOWNLOADING_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT);
- frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); // final
- frontend3->AddExpectedEvent(ids3, APPCACHE_UPDATE_READY_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend3->AddExpectedEvent(ids3,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend3->AddExpectedEvent(ids3, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend3->AddExpectedEvent(
+ ids3, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend3->AddExpectedEvent(ids3,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
MockFrontend::HostIds ids4(1, host4->host_id()); // unassociated w/cache
- frontend4->AddExpectedEvent(ids4, APPCACHE_CHECKING_EVENT);
- frontend4->AddExpectedEvent(ids4, APPCACHE_DOWNLOADING_EVENT);
+ frontend4->AddExpectedEvent(ids4, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend4->AddExpectedEvent(ids4,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
MockFrontend::HostIds ids5(1, host5->host_id());
- frontend5->AddExpectedEvent(ids5, APPCACHE_CHECKING_EVENT);
- frontend5->AddExpectedEvent(ids5, APPCACHE_DOWNLOADING_EVENT);
- frontend5->AddExpectedEvent(ids5, APPCACHE_PROGRESS_EVENT);
- frontend5->AddExpectedEvent(ids5, APPCACHE_PROGRESS_EVENT); // final
- frontend5->AddExpectedEvent(ids5, APPCACHE_UPDATE_READY_EVENT);
+ frontend5->AddExpectedEvent(ids5, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend5->AddExpectedEvent(ids5,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend5->AddExpectedEvent(ids5, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend5->AddExpectedEvent(
+ ids5, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend5->AddExpectedEvent(ids5,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
WaitForUpdateToFinish();
}
@@ -2891,14 +2989,16 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_extra_entries_.insert(AppCache::EntryMap::value_type(
host->new_master_entry_url_, AppCacheEntry(AppCacheEntry::MASTER)));
MockFrontend::HostIds ids1(1, host->host_id());
- frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend->AddExpectedEvent(ids1, APPCACHE_CACHED_EVENT);
-
- // Group status will be APPCACHE_STATUS_IDLE so cannot call
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CACHED_EVENT);
+
+ // Group status will be AppCacheStatus::APPCACHE_STATUS_IDLE so cannot call
// WaitForUpdateToFinish.
group_->AddUpdateObserver(this);
}
@@ -3092,12 +3192,15 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_old_cache_ = cache;
tested_manifest_ = MANIFEST1;
MockFrontend::HostIds ids1(1, host->host_id());
- frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
// Seed storage with expected manifest response info that will cause
// an If-Modified-Since header to be put in the manifest fetch request.
@@ -3159,12 +3262,15 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_old_cache_ = cache;
tested_manifest_ = MANIFEST1;
MockFrontend::HostIds ids1(1, host->host_id());
- frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT);
- frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final
- frontend->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT);
+ frontend->AddExpectedEvent(
+ ids1, AppCacheEventID::APPCACHE_PROGRESS_EVENT); // final
+ frontend->AddExpectedEvent(ids1,
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
// Seed storage with expected manifest response info that will cause
// an If-None-Match header to be put in the manifest fetch request.
@@ -3315,7 +3421,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_has_cache_ = true;
tested_manifest_ = NONE;
MockFrontend::HostIds host_ids(1, host->host_id());
- frontend->AddExpectedEvent(host_ids, APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(host_ids,
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -3343,7 +3450,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expect_group_has_cache_ = false;
tested_manifest_ = NONE;
MockFrontend::HostIds host_ids(1, host->host_id());
- frontend->AddExpectedEvent(host_ids, APPCACHE_CHECKING_EVENT);
+ frontend->AddExpectedEvent(host_ids,
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
WaitForUpdateToFinish();
}
@@ -3371,17 +3479,17 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
void UpdateFinishedUnwound() {
EXPECT_EQ(AppCacheGroup::IDLE, group_->update_status());
- EXPECT_TRUE(group_->update_job() == NULL);
+ EXPECT_TRUE(group_->update_job() == nullptr);
if (do_checks_after_update_finished_)
VerifyExpectations();
// Clean up everything that was created on the IO thread.
- protect_newest_cache_ = NULL;
- group_ = NULL;
+ protect_newest_cache_ = nullptr;
+ group_ = nullptr;
hosts_.clear();
frontends_.clear();
response_infos_.clear();
- service_.reset(NULL);
+ service_.reset(nullptr);
event_->Signal();
}
@@ -3420,7 +3528,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
AppCacheHost* MakeHost(int host_id, AppCacheFrontend* frontend) {
hosts_.push_back(
- base::MakeUnique<AppCacheHost>(host_id, frontend, service_.get()));
+ std::make_unique<AppCacheHost>(host_id, frontend, service_.get()));
return hosts_.back().get();
}
@@ -3438,7 +3546,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
MockFrontend* MakeMockFrontend() {
- frontends_.push_back(base::MakeUnique<MockFrontend>());
+ frontends_.push_back(std::make_unique<MockFrontend>());
return frontends_.back().get();
}
@@ -3472,7 +3580,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
if (expect_group_has_cache_) {
- EXPECT_TRUE(group_->newest_complete_cache() != NULL);
+ EXPECT_TRUE(group_->newest_complete_cache() != nullptr);
if (expect_non_null_update_time_)
EXPECT_TRUE(!group_->newest_complete_cache()->update_time().is_null());
@@ -3519,7 +3627,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
}
} else {
- EXPECT_TRUE(group_->newest_complete_cache() == NULL);
+ EXPECT_TRUE(group_->newest_complete_cache() == nullptr);
}
// Check expected events.
@@ -3556,7 +3664,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
// and will abort the test if they fail.
if (tested_manifest_) {
AppCache* cache = group_->newest_complete_cache();
- ASSERT_TRUE(cache != NULL);
+ ASSERT_TRUE(cache != nullptr);
EXPECT_EQ(group_.get(), cache->owning_group());
EXPECT_TRUE(cache->is_complete());
@@ -3789,6 +3897,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
RequestHandlerType request_handler_type_;
base::test::ScopedFeatureList feature_list_;
+ MockURLLoaderFactory mock_url_loader_factory_;
scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter_;
content::TestBrowserThreadBundle thread_bundle_;
};
@@ -3805,7 +3914,7 @@ TEST_P(AppCacheUpdateJobTest, AlreadyChecking) {
group->update_job_ = &update;
group->update_status_ = AppCacheGroup::CHECKING;
- update.StartUpdate(NULL, GURL());
+ update.StartUpdate(nullptr, GURL());
EXPECT_EQ(AppCacheGroup::CHECKING, group->update_status());
MockFrontend mock_frontend;
@@ -3817,7 +3926,7 @@ TEST_P(AppCacheUpdateJobTest, AlreadyChecking) {
EXPECT_EQ(expected, events.size());
EXPECT_EQ(expected, events[0].first.size());
EXPECT_EQ(host.host_id(), events[0].first[0]);
- EXPECT_EQ(APPCACHE_CHECKING_EVENT, events[0].second);
+ EXPECT_EQ(AppCacheEventID::APPCACHE_CHECKING_EVENT, events[0].second);
EXPECT_EQ(AppCacheGroup::CHECKING, group->update_status());
}
@@ -3833,7 +3942,7 @@ TEST_P(AppCacheUpdateJobTest, AlreadyDownloading) {
group->update_job_ = &update;
group->update_status_ = AppCacheGroup::DOWNLOADING;
- update.StartUpdate(NULL, GURL());
+ update.StartUpdate(nullptr, GURL());
EXPECT_EQ(AppCacheGroup::DOWNLOADING, group->update_status());
MockFrontend mock_frontend;
@@ -3846,11 +3955,11 @@ TEST_P(AppCacheUpdateJobTest, AlreadyDownloading) {
expected = 1;
EXPECT_EQ(expected, events[0].first.size());
EXPECT_EQ(host.host_id(), events[0].first[0]);
- EXPECT_EQ(APPCACHE_CHECKING_EVENT, events[0].second);
+ EXPECT_EQ(AppCacheEventID::APPCACHE_CHECKING_EVENT, events[0].second);
EXPECT_EQ(expected, events[1].first.size());
EXPECT_EQ(host.host_id(), events[1].first[0]);
- EXPECT_EQ(APPCACHE_DOWNLOADING_EVENT, events[1].second);
+ EXPECT_EQ(AppCacheEventID::APPCACHE_DOWNLOADING_EVENT, events[1].second);
EXPECT_EQ(AppCacheGroup::DOWNLOADING, group->update_status());
}
diff --git a/chromium/content/browser/appcache/appcache_update_request_base.cc b/chromium/content/browser/appcache/appcache_update_request_base.cc
index 30dcd0d9011..b2f68d21f3d 100644
--- a/chromium/content/browser/appcache/appcache_update_request_base.cc
+++ b/chromium/content/browser/appcache/appcache_update_request_base.cc
@@ -11,7 +11,7 @@
namespace content {
namespace {
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+constexpr net::NetworkTrafficAnnotationTag kAppCacheTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("appcache_update_job", R"(
semantics {
sender: "HTML5 AppCache System"
@@ -64,8 +64,8 @@ AppCacheUpdateJob::UpdateRequestBase::Create(
AppCacheUpdateJob::UpdateRequestBase::UpdateRequestBase() {}
net::NetworkTrafficAnnotationTag
-AppCacheUpdateJob::UpdateRequestBase::GetTrafficAnnotation() const {
- return kTrafficAnnotation;
+AppCacheUpdateJob::UpdateRequestBase::GetTrafficAnnotation() {
+ return kAppCacheTrafficAnnotation;
}
} // namespace content
diff --git a/chromium/content/browser/appcache/appcache_update_request_base.h b/chromium/content/browser/appcache/appcache_update_request_base.h
index 9238d0b5898..b6a26e7b54f 100644
--- a/chromium/content/browser/appcache/appcache_update_request_base.h
+++ b/chromium/content/browser/appcache/appcache_update_request_base.h
@@ -88,7 +88,7 @@ class AppCacheUpdateJob::UpdateRequestBase {
// Returns the traffic annotation information to be used for the outgoing
// request.
- net::NetworkTrafficAnnotationTag GetTrafficAnnotation() const;
+ static net::NetworkTrafficAnnotationTag GetTrafficAnnotation();
};
} // namespace content
diff --git a/chromium/content/browser/appcache/appcache_update_url_fetcher.cc b/chromium/content/browser/appcache/appcache_update_url_fetcher.cc
index d91d8e63a39..527d30d60da 100644
--- a/chromium/content/browser/appcache/appcache_update_url_fetcher.cc
+++ b/chromium/content/browser/appcache/appcache_update_url_fetcher.cc
@@ -41,7 +41,7 @@ AppCacheUpdateJob::URLFetcher::~URLFetcher() {}
void AppCacheUpdateJob::URLFetcher::Start() {
request_->SetSiteForCookies(job_->manifest_url_);
- request_->SetInitiator(url::Origin(job_->manifest_url_));
+ request_->SetInitiator(url::Origin::Create(job_->manifest_url_));
if (fetch_type_ == MANIFEST_FETCH && job_->doing_full_update_check_)
request_->SetLoadFlags(request_->GetLoadFlags() | net::LOAD_BYPASS_CACHE);
else if (existing_response_headers_.get())
@@ -249,4 +249,4 @@ bool AppCacheUpdateJob::URLFetcher::MaybeRetryRequest() {
return true;
}
-} // namespace content. \ No newline at end of file
+} // namespace content.
diff --git a/chromium/content/browser/appcache/appcache_update_url_loader_request.cc b/chromium/content/browser/appcache/appcache_update_url_loader_request.cc
index ae46c3ca297..efe132d5d28 100644
--- a/chromium/content/browser/appcache/appcache_update_url_loader_request.cc
+++ b/chromium/content/browser/appcache/appcache_update_url_loader_request.cc
@@ -21,8 +21,8 @@ void AppCacheUpdateJob::UpdateURLLoaderRequest::Start() {
mojom::URLLoaderClientPtr client;
client_binding_.Bind(mojo::MakeRequest(&client));
- DCHECK(loader_factory_getter_->GetNetworkFactory()->get());
- loader_factory_getter_->GetNetworkFactory()->get()->CreateLoaderAndStart(
+ DCHECK(loader_factory_getter_->GetNetworkFactory());
+ loader_factory_getter_->GetNetworkFactory()->CreateLoaderAndStart(
mojo::MakeRequest(&url_loader_), -1, -1, mojom::kURLLoadOptionNone,
request_, std::move(client),
net::MutableNetworkTrafficAnnotationTag(GetTrafficAnnotation()));
@@ -161,7 +161,7 @@ void AppCacheUpdateJob::UpdateURLLoaderRequest::OnStartLoadingResponseBody(
}
void AppCacheUpdateJob::UpdateURLLoaderRequest::OnComplete(
- const ResourceRequestCompletionStatus& status) {
+ const network::URLLoaderCompletionStatus& status) {
response_status_ = status;
// We inform the URLFetcher about a failure only here. For the success case
// OnResponseCompleted() is invoked by URLFetcher::OnReadCompleted().
diff --git a/chromium/content/browser/appcache/appcache_update_url_loader_request.h b/chromium/content/browser/appcache/appcache_update_url_loader_request.h
index ebe478c7a30..a8aabc415ee 100644
--- a/chromium/content/browser/appcache/appcache_update_url_loader_request.h
+++ b/chromium/content/browser/appcache/appcache_update_url_loader_request.h
@@ -67,7 +67,7 @@ class AppCacheUpdateJob::UpdateURLLoaderRequest
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- void OnComplete(const ResourceRequestCompletionStatus& status) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
private:
UpdateURLLoaderRequest(URLLoaderFactoryGetter* loader_factory_getter,
@@ -92,7 +92,7 @@ class AppCacheUpdateJob::UpdateURLLoaderRequest
ResourceRequest request_;
ResourceResponseHead response_;
- ResourceRequestCompletionStatus response_status_;
+ network::URLLoaderCompletionStatus response_status_;
// Response details.
std::unique_ptr<net::HttpResponseInfo> http_response_info_;
// Binds the URLLoaderClient interface to the channel.
diff --git a/chromium/content/browser/appcache/appcache_url_loader_job.cc b/chromium/content/browser/appcache/appcache_url_loader_job.cc
index 0a45271126f..a7aeb0185c3 100644
--- a/chromium/content/browser/appcache/appcache_url_loader_job.cc
+++ b/chromium/content/browser/appcache/appcache_url_loader_job.cc
@@ -16,39 +16,21 @@
namespace content {
-namespace {
-
-// Max number of http redirects to follow. Same number as gecko.
-// TODO(ananta/michaeln). Avoid duplicating logic from the n/w stack and figure
-// out a way to use FollowRedirect() mechanism in the network URL loader.
-const int kMaxRedirects = 20;
-
-} // namespace
-
-SubresourceLoadInfo::SubresourceLoadInfo()
- : routing_id(-1),
- request_id(-1),
- options(0),
- redirect_limit(kMaxRedirects) {}
-
-SubresourceLoadInfo::~SubresourceLoadInfo() {}
-
AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {
if (storage_.get())
storage_->CancelDelegateCallbacks(this);
}
-void AppCacheURLLoaderJob::Kill() {}
-
bool AppCacheURLLoaderJob::IsStarted() const {
- return delivery_type_ != AWAITING_DELIVERY_ORDERS;
+ return delivery_type_ != AWAITING_DELIVERY_ORDERS &&
+ delivery_type_ != NETWORK_DELIVERY;
}
void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
int64_t cache_id,
const AppCacheEntry& entry,
bool is_fallback) {
- if (!storage_.get()) {
+ if (!storage_.get() || !appcache_request_) {
DeliverErrorResponse();
return;
}
@@ -70,12 +52,10 @@ void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
entry_ = entry;
is_fallback_ = is_fallback;
- // Handle range requests.
- InitializeRangeRequestInfo(request_.headers);
+ if (is_fallback_ && loader_callback_)
+ CallLoaderCallback();
- // TODO(ananta)
- // Implement the AppCacheServiceImpl::Observer interface or add weak pointer
- // support to it.
+ InitializeRangeRequestInfo(appcache_request_->GetResourceRequest()->headers);
storage_->LoadResponseInfo(manifest_url_, entry_.response_id(), this);
}
@@ -89,25 +69,13 @@ void AppCacheURLLoaderJob::DeliverNetworkResponse() {
AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() -
start_time_tick_);
- if (IsResourceTypeFrame(request_.resource_type)) {
- DCHECK(!main_resource_loader_callback_.is_null());
- // In network service land, if we are processing a navigation request, we
- // need to inform the loader callback that we are not going to handle this
- // request. The loader callback is valid only for navigation requests.
- std::move(main_resource_loader_callback_).Run(StartLoaderCallback());
- } else {
- mojom::URLLoaderClientPtr client_ptr;
- network_loader_client_binding_.Bind(mojo::MakeRequest(&client_ptr));
-
- default_url_loader_factory_getter_->GetNetworkFactory()
- ->get()
- ->CreateLoaderAndStart(
- mojo::MakeRequest(&network_loader_),
- subresource_load_info_->routing_id,
- subresource_load_info_->request_id, subresource_load_info_->options,
- subresource_load_info_->request, std::move(client_ptr),
- subresource_load_info_->traffic_annotation);
- }
+ // We signal our caller with an empy callback that it needs to perform
+ // the network load.
+ DCHECK(loader_callback_ && !binding_.is_bound());
+ std::move(loader_callback_).Run(StartLoaderCallback());
+ weak_factory_.InvalidateWeakPtrs();
+ is_deleting_soon_ = true;
+ base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
void AppCacheURLLoaderJob::DeliverErrorResponse() {
@@ -117,18 +85,8 @@ void AppCacheURLLoaderJob::DeliverErrorResponse() {
if (AppCacheRequestHandler::IsRunningInTests())
return;
- // AppCacheURLRequestJob uses ERR_FAILED as the error code here. That seems
- // to map to HTTP_INTERNAL_SERVER_ERROR.
- std::string status("HTTP/1.1 ");
- status.append(base::IntToString(net::HTTP_INTERNAL_SERVER_ERROR));
- status.append(" ");
- status.append(net::GetHttpReasonPhrase(net::HTTP_INTERNAL_SERVER_ERROR));
- status.append("\0\0", 2);
-
- ResourceResponseHead response;
- response.headers = new net::HttpResponseHeaders(status);
- client_->OnReceiveResponse(response, base::nullopt, nullptr);
-
+ if (loader_callback_)
+ CallLoaderCallback();
NotifyCompleted(net::ERR_FAILED);
AppCacheHistograms::AddErrorJobStartDelaySample(base::TimeTicks::Now() -
@@ -139,192 +97,61 @@ AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() {
return this;
}
-void AppCacheURLLoaderJob::FollowRedirect() {
- if (subresource_factory_.get()) {
- if (storage_->usage_map()->find(
- last_subresource_redirect_info_.new_url.GetOrigin()) !=
- storage_->usage_map()->end()) {
- // If we hit the redirect limit then attempt to load a fallback here.
- // If that succeeds we are good. If not notify the client about the
- // failure.
- // TODO(ananta/michaeln)
- // Avoid this logic and figure out a way to reuse the network loader's
- // FollowRedirect mechanism.
- subresource_load_info_->redirect_limit--;
-
- if (subresource_load_info_->redirect_limit <= 0) {
- HandleRedirectLimitHit();
- return;
- }
- subresource_load_info_->client = std::move(client_);
- subresource_load_info_->url_loader_request = binding_.Unbind();
- subresource_factory_->Restart(last_subresource_redirect_info_,
- std::move(sub_resource_handler_),
- std::move(subresource_load_info_));
- base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
- return;
- }
- }
-
- if (network_loader_)
- network_loader_->FollowRedirect();
-}
-
-void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority,
- int32_t intra_priority_value) {
- if (network_loader_)
- network_loader_->SetPriority(priority, intra_priority_value);
+base::WeakPtr<AppCacheJob> AppCacheURLLoaderJob::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
}
-void AppCacheURLLoaderJob::PauseReadingBodyFromNet() {
- if (network_loader_)
- network_loader_->PauseReadingBodyFromNet();
+base::WeakPtr<AppCacheURLLoaderJob> AppCacheURLLoaderJob::GetDerivedWeakPtr() {
+ return weak_factory_.GetWeakPtr();
}
-void AppCacheURLLoaderJob::ResumeReadingBodyFromNet() {
- if (network_loader_)
- network_loader_->ResumeReadingBodyFromNet();
+void AppCacheURLLoaderJob::FollowRedirect() {
+ NOTREACHED() << "appcache never produces redirects";
}
-void AppCacheURLLoaderJob::OnReceiveResponse(
- const ResourceResponseHead& response_head,
- const base::Optional<net::SSLInfo>& ssl_info,
- mojom::DownloadedTempFilePtr downloaded_file) {
- appcache_request_->set_response(response_head);
- // The MaybeLoadFallbackForResponse() call below can pass a fallback
- // response to us. Reset the delivery_type_ to ensure that we can
- // receive it
- delivery_type_ = AWAITING_DELIVERY_ORDERS;
-
- received_response_ = true;
-
- if (!sub_resource_handler_->MaybeLoadFallbackForResponse(nullptr)) {
- client_->OnReceiveResponse(response_head, ssl_info,
- std::move(downloaded_file));
- } else {
- // Disconnect from the network loader as we are delivering a fallback
- // response to the client.
- DisconnectFromNetworkLoader();
- }
-}
+void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) {}
+void AppCacheURLLoaderJob::PauseReadingBodyFromNet() {}
+void AppCacheURLLoaderJob::ResumeReadingBodyFromNet() {}
-void AppCacheURLLoaderJob::OnReceiveRedirect(
- const net::RedirectInfo& redirect_info,
- const ResourceResponseHead& response_head) {
- appcache_request_->set_response(response_head);
-
- // The MaybeLoadFallbackForRedirect() call below can pass a fallback
- // response to us. Reset the delivery_type_ to ensure that we can
- // receive it
- delivery_type_ = AWAITING_DELIVERY_ORDERS;
- if (sub_resource_handler_->MaybeLoadFallbackForRedirect(
- nullptr, redirect_info.new_url)) {
- // Disconnect from the network loader as we are delivering a fallback
- // response to the client.
- DisconnectFromNetworkLoader();
+void AppCacheURLLoaderJob::DeleteIfNeeded() {
+ if (binding_.is_bound() || is_deleting_soon_)
return;
- }
-
- last_subresource_redirect_info_ = redirect_info;
- client_->OnReceiveRedirect(redirect_info, response_head);
+ delete this;
}
-void AppCacheURLLoaderJob::OnDataDownloaded(int64_t data_len,
- int64_t encoded_data_len) {
- client_->OnDataDownloaded(data_len, encoded_data_len);
-}
-
-void AppCacheURLLoaderJob::OnUploadProgress(
- int64_t current_position,
- int64_t total_size,
- OnUploadProgressCallback ack_callback) {
- client_->OnUploadProgress(current_position, total_size,
- std::move(ack_callback));
-}
-
-void AppCacheURLLoaderJob::OnReceiveCachedMetadata(
- const std::vector<uint8_t>& data) {
- client_->OnReceiveCachedMetadata(data);
-}
-
-void AppCacheURLLoaderJob::OnTransferSizeUpdated(int32_t transfer_size_diff) {
- client_->OnTransferSizeUpdated(transfer_size_diff);
-}
-
-void AppCacheURLLoaderJob::OnStartLoadingResponseBody(
- mojo::ScopedDataPipeConsumerHandle body) {
- client_->OnStartLoadingResponseBody(std::move(body));
-}
-
-void AppCacheURLLoaderJob::OnComplete(
- const ResourceRequestCompletionStatus& status) {
- delivery_type_ = AWAITING_DELIVERY_ORDERS;
- if (status.error_code != net::OK && !received_response_) {
- if (sub_resource_handler_->MaybeLoadFallbackForResponse(nullptr)) {
- // Disconnect from the network loader as we are delivering a fallback
- // response to the client.
- DisconnectFromNetworkLoader();
- return;
- }
- }
- client_->OnComplete(status);
-}
-
-void AppCacheURLLoaderJob::SetRequestHandlerAndFactory(
- std::unique_ptr<AppCacheRequestHandler> handler,
- AppCacheSubresourceURLFactory* subresource_factory) {
- sub_resource_handler_ = std::move(handler);
- subresource_factory_ = subresource_factory->GetWeakPtr();
-}
-
-void AppCacheURLLoaderJob::BindRequest(mojom::URLLoaderClientPtr client,
- mojom::URLLoaderRequest request) {
+void AppCacheURLLoaderJob::Start(mojom::URLLoaderRequest request,
+ mojom::URLLoaderClientPtr client) {
DCHECK(!binding_.is_bound());
binding_.Bind(std::move(request));
-
client_ = std::move(client);
-
binding_.set_connection_error_handler(base::BindOnce(
- &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this)));
-}
-
-void AppCacheURLLoaderJob::Start(mojom::URLLoaderRequest request,
- mojom::URLLoaderClientPtr client) {
- BindRequest(std::move(client), std::move(request));
- // Send the cached AppCacheResponse if any.
- if (info_.get())
- SendResponseInfo();
+ &AppCacheURLLoaderJob::OnConnectionError, GetDerivedWeakPtr()));
}
AppCacheURLLoaderJob::AppCacheURLLoaderJob(
- const ResourceRequest& request,
AppCacheURLLoaderRequest* appcache_request,
AppCacheStorage* storage,
- std::unique_ptr<SubresourceLoadInfo> subresource_load_info,
- URLLoaderFactoryGetter* loader_factory_getter)
- : request_(request),
- storage_(storage->GetWeakPtr()),
+ LoaderCallback loader_callback)
+ : storage_(storage->GetWeakPtr()),
start_time_tick_(base::TimeTicks::Now()),
cache_id_(kAppCacheNoCacheId),
is_fallback_(false),
binding_(this),
writable_handle_watcher_(FROM_HERE,
mojo::SimpleWatcher::ArmingPolicy::MANUAL),
- network_loader_client_binding_(this),
- appcache_request_(appcache_request),
- received_response_(false) {
- if (subresource_load_info.get()) {
- DCHECK(loader_factory_getter);
- subresource_load_info_ = std::move(subresource_load_info);
- request_ = subresource_load_info_->request;
-
- binding_.Bind(std::move(subresource_load_info_->url_loader_request));
- binding_.set_connection_error_handler(base::BindOnce(
- &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this)));
-
- client_ = std::move(subresource_load_info_->client);
- default_url_loader_factory_getter_ = loader_factory_getter;
- }
+ loader_callback_(std::move(loader_callback)),
+ appcache_request_(appcache_request->GetWeakPtr()),
+ is_main_resource_load_(IsResourceTypeFrame(
+ appcache_request->GetResourceRequest()->resource_type)),
+ weak_factory_(this) {}
+
+void AppCacheURLLoaderJob::CallLoaderCallback() {
+ DCHECK(loader_callback_);
+ DCHECK(!binding_.is_bound());
+ std::move(loader_callback_)
+ .Run(base::BindOnce(&AppCacheURLLoaderJob::Start, GetDerivedWeakPtr()));
+ DCHECK(binding_.is_bound());
}
void AppCacheURLLoaderJob::OnResponseInfoLoaded(
@@ -338,6 +165,9 @@ void AppCacheURLLoaderJob::OnResponseInfoLoaded(
}
if (response_info) {
+ if (loader_callback_)
+ CallLoaderCallback();
+
info_ = response_info;
reader_.reset(
storage_->CreateResponseReader(manifest_url_, entry_.response_id()));
@@ -345,13 +175,6 @@ void AppCacheURLLoaderJob::OnResponseInfoLoaded(
if (is_range_request())
SetupRangeResponse();
- if (IsResourceTypeFrame(request_.resource_type) &&
- main_resource_loader_callback_) {
- std::move(main_resource_loader_callback_)
- .Run(base::BindOnce(&AppCacheURLLoaderJob::Start,
- StaticAsWeakPtr(this)));
- }
-
response_body_stream_ = std::move(data_pipe_.producer_handle);
// TODO(ananta)
@@ -362,58 +185,64 @@ void AppCacheURLLoaderJob::OnResponseInfoLoaded(
writable_handle_watcher_.Watch(
response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
base::Bind(&AppCacheURLLoaderJob::OnResponseBodyStreamReady,
- StaticAsWeakPtr(this)));
-
- if (client_)
- SendResponseInfo();
+ GetDerivedWeakPtr()));
+ SendResponseInfo();
ReadMore();
- } else {
- // Error case here. We fallback to the network.
- DeliverNetworkResponse();
- AppCacheHistograms::CountResponseRetrieval(
- false, IsResourceTypeFrame(request_.resource_type),
- manifest_url_.GetOrigin());
+ return;
+ }
- cache_entry_not_found_ = true;
+ // We failed to load the response headers from the disk cache.
+ if (storage_->service()->storage() == storage_.get()) {
+ // A resource that is expected to be in the appcache is missing.
+ // If the 'check' fails, the corrupt appcache will be deleted.
+ // See http://code.google.com/p/chromium/issues/detail?id=50657
+ storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_,
+ entry_.response_id());
+ AppCacheHistograms::CountResponseRetrieval(false, is_main_resource_load_,
+ manifest_url_.GetOrigin());
}
+ cache_entry_not_found_ = true;
+
+ // We fallback to the network unless this job was falling back to the
+ // appcache from the network which had already failed in some way.
+ if (!is_fallback_)
+ DeliverNetworkResponse();
+ else
+ DeliverErrorResponse();
}
void AppCacheURLLoaderJob::OnReadComplete(int result) {
- DLOG(WARNING) << "AppCache read completed with result: " << result;
-
- if (result <= 0) {
- writable_handle_watcher_.Cancel();
- pending_write_->Complete(0);
+ if (result > 0) {
+ uint32_t bytes_written = static_cast<uint32_t>(result);
+ response_body_stream_ = pending_write_->Complete(bytes_written);
pending_write_ = nullptr;
+ ReadMore();
+ return;
}
- bool is_main_resource = IsResourceTypeFrame(request_.resource_type);
+ writable_handle_watcher_.Cancel();
+ pending_write_->Complete(0);
+ pending_write_ = nullptr;
+ NotifyCompleted(result);
+}
- if (result == 0) {
- NotifyCompleted(result);
- AppCacheHistograms::CountResponseRetrieval(true, is_main_resource,
- manifest_url_.GetOrigin());
- return;
- } else if (result < 0) {
- // TODO(ananta)
- // Populate the relevant fields of the ResourceRequestCompletionStatus
- // structure.
- NotifyCompleted(result);
- AppCacheHistograms::CountResponseRetrieval(false, is_main_resource,
- manifest_url_.GetOrigin());
+void AppCacheURLLoaderJob::OnResponseBodyStreamReady(MojoResult result) {
+ // TODO(ananta)
+ // Add proper error handling here.
+ if (result != MOJO_RESULT_OK) {
+ DCHECK(false);
+ NotifyCompleted(net::ERR_FAILED);
return;
}
-
- uint32_t bytes_written = static_cast<uint32_t>(result);
- response_body_stream_ = pending_write_->Complete(bytes_written);
- pending_write_ = nullptr;
ReadMore();
}
void AppCacheURLLoaderJob::OnConnectionError() {
if (storage_.get())
storage_->CancelDelegateCallbacks(this);
+ weak_factory_.InvalidateWeakPtrs();
+ is_deleting_soon_ = true;
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
@@ -426,7 +255,6 @@ void AppCacheURLLoaderJob::SendResponseInfo() {
const net::HttpResponseInfo* http_info = is_range_request()
? range_response_info_.get()
: info_->http_response_info();
-
ResourceResponseHead response_head;
response_head.headers = http_info->headers;
response_head.appcache_id = cache_id_;
@@ -442,20 +270,15 @@ void AppCacheURLLoaderJob::SendResponseInfo() {
response_head.content_length =
is_range_request() ? range_response_info_->headers->GetContentLength()
: info_->response_data_size();
-
response_head.connection_info = http_info->connection_info;
response_head.socket_address = http_info->socket_address;
response_head.was_fetched_via_spdy = http_info->was_fetched_via_spdy;
response_head.was_alpn_negotiated = http_info->was_alpn_negotiated;
response_head.alpn_negotiated_protocol = http_info->alpn_negotiated_protocol;
-
response_head.load_timing = load_timing_info_;
- appcache_request_->set_response(response_head);
-
client_->OnReceiveResponse(response_head, http_info->ssl_info,
mojom::DownloadedTempFilePtr());
-
client_->OnStartLoadingResponseBody(std::move(data_pipe_.consumer_handle));
}
@@ -471,9 +294,6 @@ void AppCacheURLLoaderJob::ReadMore() {
writable_handle_watcher_.ArmOrNotify();
return;
} else if (result != MOJO_RESULT_OK) {
- // The response body stream is in a bad state. Bail.
- // TODO(ananta)
- // Add proper error handling here.
NotifyCompleted(net::ERR_FAILED);
writable_handle_watcher_.Cancel();
response_body_stream_.reset();
@@ -489,17 +309,7 @@ void AppCacheURLLoaderJob::ReadMore() {
reader_->ReadData(
buffer.get(), bytes_to_read,
- base::Bind(&AppCacheURLLoaderJob::OnReadComplete, StaticAsWeakPtr(this)));
-}
-
-void AppCacheURLLoaderJob::OnResponseBodyStreamReady(MojoResult result) {
- // TODO(ananta)
- // Add proper error handling here.
- if (result != MOJO_RESULT_OK) {
- DCHECK(false);
- NotifyCompleted(net::ERR_FAILED);
- }
- ReadMore();
+ base::Bind(&AppCacheURLLoaderJob::OnReadComplete, GetDerivedWeakPtr()));
}
void AppCacheURLLoaderJob::NotifyCompleted(int error_code) {
@@ -509,47 +319,23 @@ void AppCacheURLLoaderJob::NotifyCompleted(int error_code) {
if (AppCacheRequestHandler::IsRunningInTests())
return;
- const net::HttpResponseInfo* http_info =
- is_range_request() ? range_response_info_.get()
- : (info_ ? info_->http_response_info() : nullptr);
-
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = error_code;
-
- // TODO(ananta)
- // Fill other details in the ResourceRequestCompletionStatus structure in
- // case of an error.
- if (!request_complete_data.error_code) {
- request_complete_data.exists_in_cache = http_info->was_cached;
- request_complete_data.completion_time = base::TimeTicks::Now();
- request_complete_data.encoded_body_length =
+ network::URLLoaderCompletionStatus status(error_code);
+ if (!error_code) {
+ const net::HttpResponseInfo* http_info =
+ is_range_request() ? range_response_info_.get()
+ : (info_ ? info_->http_response_info() : nullptr);
+ status.exists_in_cache = http_info->was_cached;
+ status.completion_time = base::TimeTicks::Now();
+ status.encoded_body_length =
is_range_request() ? range_response_info_->headers->GetContentLength()
: (info_ ? info_->response_data_size() : 0);
- request_complete_data.decoded_body_length =
- request_complete_data.encoded_body_length;
+ status.decoded_body_length = status.encoded_body_length;
}
- client_->OnComplete(request_complete_data);
-}
-
-void AppCacheURLLoaderJob::DisconnectFromNetworkLoader() {
- // Close the pipe to the network loader as we are delivering a fallback
- // response to the client.
- network_loader_client_binding_.Close();
- network_loader_ = nullptr;
-}
+ client_->OnComplete(status);
-void AppCacheURLLoaderJob::HandleRedirectLimitHit() {
- DCHECK(sub_resource_handler_.get());
- // TODO(ananta/michaeln)
- // Fix the IsSuccess() function in the AppCacheURLLoaderRequest class.
- // Currently presence of headers in the response is treated as success.
- appcache_request_->set_response(ResourceResponseHead());
- if (sub_resource_handler_->MaybeLoadFallbackForResponse(nullptr)) {
- DisconnectFromNetworkLoader();
- } else {
- ResourceRequestCompletionStatus result;
- result.error_code = net::ERR_FAILED;
- client_->OnComplete(result);
+ if (delivery_type_ == APPCACHED_DELIVERY) {
+ AppCacheHistograms::CountResponseRetrieval(
+ error_code == 0, is_main_resource_load_, manifest_url_.GetOrigin());
}
}
diff --git a/chromium/content/browser/appcache/appcache_url_loader_job.h b/chromium/content/browser/appcache/appcache_url_loader_job.h
index d4da7d7f84f..bc8d93f0ee2 100644
--- a/chromium/content/browser/appcache/appcache_url_loader_job.h
+++ b/chromium/content/browser/appcache/appcache_url_loader_job.h
@@ -28,36 +28,14 @@ class NetToMojoPendingBuffer;
namespace content {
-class AppCacheSubresourceURLFactory;
class AppCacheRequest;
class AppCacheURLLoaderRequest;
-class URLLoaderFactoryGetter;
-
-// Holds information about the subresource load request like the routing id,
-// request id, the client pointer, etc.
-struct SubresourceLoadInfo {
- SubresourceLoadInfo();
- ~SubresourceLoadInfo();
-
- mojom::URLLoaderRequest url_loader_request;
- int32_t routing_id;
- int32_t request_id;
- uint32_t options;
- ResourceRequest request;
- mojom::URLLoaderClientPtr client;
- net::MutableNetworkTrafficAnnotationTag traffic_annotation;
- // TODO(ananta/michaeln)
- // Avoid duplicating the redirect limit logic in the n/w stack and figure
- // out a way to use the FollowRedirect() mechanism in the network loader.
- int redirect_limit;
-};
// AppCacheJob wrapper for a mojom::URLLoader implementation which returns
// responses stored in the AppCache.
class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob,
public AppCacheStorage::Delegate,
- public mojom::URLLoader,
- public mojom::URLLoaderClient {
+ public mojom::URLLoader {
public:
~AppCacheURLLoaderJob() override;
@@ -65,7 +43,6 @@ class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob,
void Start(mojom::URLLoaderRequest request, mojom::URLLoaderClientPtr client);
// AppCacheJob overrides.
- void Kill() override;
bool IsStarted() const override;
void DeliverAppCachedResponse(const GURL& manifest_url,
int64_t cache_id,
@@ -74,6 +51,8 @@ class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob,
void DeliverNetworkResponse() override;
void DeliverErrorResponse() override;
AppCacheURLLoaderJob* AsURLLoaderJob() override;
+ base::WeakPtr<AppCacheJob> GetWeakPtr() override;
+ base::WeakPtr<AppCacheURLLoaderJob> GetDerivedWeakPtr();
// mojom::URLLoader implementation:
void FollowRedirect() override;
@@ -82,105 +61,50 @@ class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob,
void PauseReadingBodyFromNet() override;
void ResumeReadingBodyFromNet() override;
- // mojom::URLLoaderClient implementation.
- // These methods are called by the network loader for subresource requests
- // which go to the network. We serve fallback content in these methods
- // if applicable.
- void OnReceiveResponse(const ResourceResponseHead& response_head,
- const base::Optional<net::SSLInfo>& ssl_info,
- mojom::DownloadedTempFilePtr downloaded_file) override;
- void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
- const ResourceResponseHead& response_head) override;
- void OnDataDownloaded(int64_t data_len, int64_t encoded_data_len) 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 body) override;
- void OnComplete(const ResourceRequestCompletionStatus& status) override;
-
- void set_main_resource_loader_callback(LoaderCallback callback) {
- main_resource_loader_callback_ = std::move(callback);
- }
-
- // Ownership of the |handler| is transferred to us via this call. This is
- // only for subresource requests. The subresource_factory is maintained as
- // a weak pointer.
- void SetRequestHandlerAndFactory(
- std::unique_ptr<AppCacheRequestHandler> handler,
- AppCacheSubresourceURLFactory* subresource_factory);
-
- // Binds to the URLLoaderRequest instance passed in the |request| parameter.
- // The URLLoaderClient instance is passed in the |client| parameter. This
- // enables the client to receive notifications/data, etc for the ensuing
- // URL load.
- void BindRequest(mojom::URLLoaderClientPtr client,
- mojom::URLLoaderRequest request);
+ void DeleteIfNeeded();
protected:
- // AppCacheJob::Create() creates this instance.
- friend class AppCacheJob;
+ // AppCacheRequestHandler::CreateJob() creates this instance.
+ friend class AppCacheRequestHandler;
+
+ AppCacheURLLoaderJob(AppCacheURLLoaderRequest* appcache_request,
+ AppCacheStorage* storage,
+ LoaderCallback loader_callback);
- AppCacheURLLoaderJob(
- const ResourceRequest& request,
- AppCacheURLLoaderRequest* appcache_request,
- AppCacheStorage* storage,
- std::unique_ptr<SubresourceLoadInfo> subresource_load_info,
- URLLoaderFactoryGetter* loader_factory_getter);
+ // Invokes the loader callback which is expected to setup the mojo binding.
+ void CallLoaderCallback();
// AppCacheStorage::Delegate methods
void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
int64_t response_id) override;
- // AppCacheResponseReader completion callback
+ // AppCacheResponseReader completion callback.
void OnReadComplete(int result);
+ // Callback invoked when the data pipe can be written to.
+ void OnResponseBodyStreamReady(MojoResult result);
+
+ // Mojo binding error handler.
void OnConnectionError();
- // Helper to send the AppCacheResponseInfo to the URLLoaderClient.
void SendResponseInfo();
-
- // Helper function to read the data from the AppCache.
void ReadMore();
-
- // Callback invoked when the data pipe can be written to.
- void OnResponseBodyStreamReady(MojoResult result);
-
- // Notifies the client about request completion.
void NotifyCompleted(int error_code);
- // Disconnects the mojo pipe to the network loader and releases related
- // resources.
- void DisconnectFromNetworkLoader();
-
- // If we hit the redirect limit for a subresource then we need to try a
- // fallback or return a failure to the client. This function does that.
- void HandleRedirectLimitHit();
-
- // The current request.
- ResourceRequest request_;
-
base::WeakPtr<AppCacheStorage> storage_;
// Time when the request started.
base::TimeTicks start_time_tick_;
- // The AppCache manifest URL.
- GURL manifest_url_;
+ // Timing information for the most recent request. Its start times are
+ // populated in DeliverAppCachedResponse().
+ net::LoadTimingInfo load_timing_info_;
- // The AppCache id.
+ GURL manifest_url_;
int64_t cache_id_;
-
AppCacheEntry entry_;
-
- // Set to true if we are loading fallback content.
bool is_fallback_;
- // The data pipe used to transfer AppCache data to the client.
- mojo::DataPipe data_pipe_;
-
// Binds the URLLoaderClient with us.
mojo::Binding<mojom::URLLoader> binding_;
@@ -188,49 +112,24 @@ class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob,
// about the URL load
mojom::URLLoaderClientPtr client_;
- // mojo data pipe entities.
+ // The data pipe used to transfer AppCache data to the client.
+ mojo::DataPipe data_pipe_;
mojo::ScopedDataPipeProducerHandle response_body_stream_;
-
scoped_refptr<network::NetToMojoPendingBuffer> pending_write_;
-
mojo::SimpleWatcher writable_handle_watcher_;
// The Callback to be invoked in the network service land to indicate if
- // the main resource request can be serviced via the AppCache.
- LoaderCallback main_resource_loader_callback_;
-
- // We own the AppCacheRequestHandler instance for subresource requests.
- std::unique_ptr<AppCacheRequestHandler> sub_resource_handler_;
-
- scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_;
-
- // Holds subresource url loader information.
- std::unique_ptr<SubresourceLoadInfo> subresource_load_info_;
-
- // Timing information for the most recent request. Its start times are
- // populated in DeliverAppCachedResponse().
- net::LoadTimingInfo load_timing_info_;
-
- // Used for subresource requests which go to the network.
- mojom::URLLoaderPtr network_loader_;
-
- // Network URLLoaderClient binding for subresource requests.
- mojo::Binding<mojom::URLLoaderClient> network_loader_client_binding_;
-
- // The AppCacheURLLoaderRequest instance. We use this to set the response
- // info when we receive it.
- AppCacheURLLoaderRequest* appcache_request_;
-
- // Set to true when we receive a response from the network URL loader.
- // Please see OnReceiveResponse()
- bool received_response_;
+ // the resource request can be serviced via the AppCache.
+ LoaderCallback loader_callback_;
- // The last redirect seen for a subresource.
- net::RedirectInfo last_subresource_redirect_info_;
+ // The AppCacheRequest instance, used to inform the loader job about range
+ // request headers. Not owned by this class.
+ base::WeakPtr<AppCacheURLLoaderRequest> appcache_request_;
- // Used to restart the subresource request in case of a redirect.
- base::WeakPtr<AppCacheSubresourceURLFactory> subresource_factory_;
+ bool is_deleting_soon_ = false;
+ bool is_main_resource_load_;
+ base::WeakPtrFactory<AppCacheURLLoaderJob> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoaderJob);
};
diff --git a/chromium/content/browser/appcache/appcache_url_loader_request.cc b/chromium/content/browser/appcache/appcache_url_loader_request.cc
index a0898eb3e92..360d4b9ad35 100644
--- a/chromium/content/browser/appcache/appcache_url_loader_request.cc
+++ b/chromium/content/browser/appcache/appcache_url_loader_request.cc
@@ -4,6 +4,7 @@
#include "content/browser/appcache/appcache_url_loader_request.h"
#include "content/public/common/resource_type.h"
+#include "net/url_request/redirect_util.h"
#include "net/url_request/url_request.h"
namespace content {
@@ -69,8 +70,24 @@ AppCacheURLLoaderRequest* AppCacheURLLoaderRequest::AsURLLoaderRequest() {
return this;
}
+base::WeakPtr<AppCacheURLLoaderRequest> AppCacheURLLoaderRequest::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
+void AppCacheURLLoaderRequest::UpdateWithRedirectInfo(
+ const net::RedirectInfo& redirect_info) {
+ bool not_used_clear_body;
+ net::RedirectUtil::UpdateHttpRequest(request_.url, request_.method,
+ redirect_info, &request_.headers,
+ &not_used_clear_body);
+ request_.url = redirect_info.new_url;
+ request_.method = redirect_info.new_method;
+ request_.referrer = GURL(redirect_info.new_referrer);
+ request_.site_for_cookies = redirect_info.new_site_for_cookies;
+}
+
AppCacheURLLoaderRequest::AppCacheURLLoaderRequest(
const ResourceRequest& request)
- : request_(request) {}
+ : request_(request), weak_factory_(this) {}
} // namespace content
diff --git a/chromium/content/browser/appcache/appcache_url_loader_request.h b/chromium/content/browser/appcache/appcache_url_loader_request.h
index cdd6285b7f8..b75ed55c786 100644
--- a/chromium/content/browser/appcache/appcache_url_loader_request.h
+++ b/chromium/content/browser/appcache/appcache_url_loader_request.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_URL_LOADER_REQUEST_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_URL_LOADER_REQUEST_H_
+#include "base/memory/weak_ptr.h"
#include "content/browser/appcache/appcache_request.h"
#include "content/public/common/resource_request.h"
#include "content/public/common/resource_response.h"
+#include "net/url_request/redirect_info.h"
namespace content {
@@ -37,18 +39,21 @@ class CONTENT_EXPORT AppCacheURLLoaderRequest : public AppCacheRequest {
ResourceRequest* GetResourceRequest() override;
AppCacheURLLoaderRequest* AsURLLoaderRequest() override;
+ void UpdateWithRedirectInfo(const net::RedirectInfo& redirect_info);
void set_request(const ResourceRequest& request) { request_ = request; }
void set_response(const ResourceResponseHead& response) {
response_ = response;
}
+ base::WeakPtr<AppCacheURLLoaderRequest> GetWeakPtr();
+
protected:
explicit AppCacheURLLoaderRequest(const ResourceRequest& request);
private:
ResourceRequest request_;
ResourceResponseHead response_;
-
+ base::WeakPtrFactory<AppCacheURLLoaderRequest> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoaderRequest);
};
diff --git a/chromium/content/browser/appcache/appcache_url_request_job.cc b/chromium/content/browser/appcache/appcache_url_request_job.cc
index 1061c5f5cf9..6460fbfa3ae 100644
--- a/chromium/content/browser/appcache/appcache_url_request_job.cc
+++ b/chromium/content/browser/appcache/appcache_url_request_job.cc
@@ -43,15 +43,15 @@ void AppCacheURLRequestJob::Kill() {
handler_source_reader_.reset();
if (storage_) {
storage_->CancelDelegateCallbacks(this);
- storage_ = NULL;
+ storage_ = nullptr;
}
- host_ = NULL;
- info_ = NULL;
- cache_ = NULL;
- group_ = NULL;
+ host_ = nullptr;
+ info_ = nullptr;
+ cache_ = nullptr;
+ group_ = nullptr;
range_response_info_.reset();
net::URLRequestJob::Kill();
- AppCacheJob::weak_factory_.InvalidateWeakPtrs();
+ weak_factory_.InvalidateWeakPtrs();
}
}
@@ -76,21 +76,30 @@ void AppCacheURLRequestJob::DeliverAppCachedResponse(const GURL& manifest_url,
void AppCacheURLRequestJob::DeliverNetworkResponse() {
DCHECK(!has_delivery_orders());
delivery_type_ = NETWORK_DELIVERY;
- storage_ = NULL; // not needed
+ storage_ = nullptr; // not needed
MaybeBeginDelivery();
}
void AppCacheURLRequestJob::DeliverErrorResponse() {
DCHECK(!has_delivery_orders());
delivery_type_ = ERROR_DELIVERY;
- storage_ = NULL; // not needed
+ storage_ = nullptr; // not needed
MaybeBeginDelivery();
}
-net::URLRequestJob* AppCacheURLRequestJob::AsURLRequestJob() {
+AppCacheURLRequestJob* AppCacheURLRequestJob::AsURLRequestJob() {
return this;
}
+base::WeakPtr<AppCacheJob> AppCacheURLRequestJob::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
+base::WeakPtr<AppCacheURLRequestJob>
+AppCacheURLRequestJob::GetDerivedWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
AppCacheURLRequestJob::AppCacheURLRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
@@ -106,7 +115,8 @@ AppCacheURLRequestJob::AppCacheURLRequestJob(
cache_id_(kAppCacheNoCacheId),
is_fallback_(false),
is_main_resource_(is_main_resource),
- on_prepare_to_restart_callback_(std::move(restart_callback)) {
+ on_prepare_to_restart_callback_(std::move(restart_callback)),
+ weak_factory_(this) {
DCHECK(storage_);
}
@@ -116,7 +126,7 @@ void AppCacheURLRequestJob::MaybeBeginDelivery() {
// callbacks happen as they would for network requests.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&AppCacheURLRequestJob::BeginDelivery,
- StaticAsWeakPtr(this)));
+ GetDerivedWeakPtr()));
}
}
@@ -147,10 +157,6 @@ void AppCacheURLRequestJob::BeginDelivery() {
break;
case APPCACHED_DELIVERY:
- if (entry_.IsExecutable()) {
- BeginExecutableHandlerDelivery();
- return;
- }
AppCacheHistograms::AddAppCacheJobStartDelaySample(
base::TimeTicks::Now() - start_time_tick_);
request()->net_log().AddEvent(
@@ -166,133 +172,12 @@ void AppCacheURLRequestJob::BeginDelivery() {
}
}
-void AppCacheURLRequestJob::BeginExecutableHandlerDelivery() {
- DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
- kEnableExecutableHandlers));
- if (!storage_->service()->handler_factory()) {
- BeginErrorDelivery("missing handler factory");
- return;
- }
-
- request()->net_log().AddEvent(
- net::NetLogEventType::APPCACHE_DELIVERING_EXECUTABLE_RESPONSE);
-
- // We defer job delivery until the executable handler is spun up and
- // provides a response. The sequence goes like this...
- //
- // 1. First we load the cache.
- // 2. Then if the handler is not spun up, we load the script resource which
- // is needed to spin it up.
- // 3. Then we ask then we ask the handler to compute a response.
- // 4. Finally we deilver that response to the caller.
- storage_->LoadCache(cache_id_, this);
-}
-
-void AppCacheURLRequestJob::OnCacheLoaded(AppCache* cache, int64_t cache_id) {
- DCHECK_EQ(cache_id_, cache_id);
- DCHECK(!has_been_killed());
-
- if (!cache) {
- BeginErrorDelivery("cache load failed");
- return;
- }
-
- // Keep references to ensure they don't go out of scope until job completion.
- cache_ = cache;
- group_ = cache->owning_group();
-
- // If the handler is spun up, ask it to compute a response.
- AppCacheExecutableHandler* handler =
- cache->GetExecutableHandler(entry_.response_id());
- if (handler) {
- InvokeExecutableHandler(handler);
- return;
- }
-
- // Handler is not spun up yet, load the script resource to do that.
- // NOTE: This is not ideal since multiple jobs may be doing this,
- // concurrently but close enough for now, the first to load the script
- // will win.
-
- // Read the script data, truncating if its too large.
- // NOTE: we just issue one read and don't bother chaining if the resource
- // is very (very) large, close enough for now.
- const int64_t kLimit = 500 * 1000;
- handler_source_buffer_ = new net::GrowableIOBuffer();
- handler_source_buffer_->SetCapacity(kLimit);
- handler_source_reader_.reset(
- storage_->CreateResponseReader(manifest_url_, entry_.response_id()));
- handler_source_reader_->ReadData(
- handler_source_buffer_.get(),
- kLimit,
- base::Bind(&AppCacheURLRequestJob::OnExecutableSourceLoaded,
- base::Unretained(this)));
-}
-
-void AppCacheURLRequestJob::OnExecutableSourceLoaded(int result) {
- DCHECK(!has_been_killed());
- handler_source_reader_.reset();
- if (result < 0) {
- BeginErrorDelivery("script source load failed");
- return;
- }
-
- handler_source_buffer_->SetCapacity(result); // Free up some memory.
-
- AppCacheExecutableHandler* handler = cache_->GetOrCreateExecutableHandler(
- entry_.response_id(), handler_source_buffer_.get());
- handler_source_buffer_ = NULL; // not needed anymore
- if (handler) {
- InvokeExecutableHandler(handler);
- return;
- }
-
- BeginErrorDelivery("factory failed to produce a handler");
-}
-
-void AppCacheURLRequestJob::InvokeExecutableHandler(
- AppCacheExecutableHandler* handler) {
- handler->HandleRequest(
- request(),
- base::Bind(&AppCacheURLRequestJob::OnExecutableResponseCallback,
- StaticAsWeakPtr(this)));
-}
-
-void AppCacheURLRequestJob::OnExecutableResponseCallback(
- const AppCacheExecutableHandler::Response& response) {
- DCHECK(!has_been_killed());
- if (response.use_network) {
- delivery_type_ = NETWORK_DELIVERY;
- storage_ = NULL;
- BeginDelivery();
- return;
- }
-
- if (!response.cached_resource_url.is_empty()) {
- AppCacheEntry* entry_ptr = cache_->GetEntry(response.cached_resource_url);
- if (entry_ptr && !entry_ptr->IsExecutable()) {
- entry_ = *entry_ptr;
- BeginDelivery();
- return;
- }
- }
-
- if (!response.redirect_url.is_empty()) {
- // TODO(michaeln): playback a redirect
- // response_headers_(new HttpResponseHeaders(response_headers)),
- // fallthru for now to deliver an error
- }
-
- // Otherwise, return an error.
- BeginErrorDelivery("handler returned an invalid response");
-}
-
void AppCacheURLRequestJob::BeginErrorDelivery(const char* message) {
if (host_)
host_->frontend()->OnLogMessage(host_->host_id(), APPCACHE_LOG_ERROR,
message);
delivery_type_ = ERROR_DELIVERY;
- storage_ = NULL;
+ storage_ = nullptr;
BeginDelivery();
}
@@ -322,13 +207,19 @@ void AppCacheURLRequestJob::OnResponseInfoLoaded(
false, is_main_resource_, manifest_url_.GetOrigin());
}
cache_entry_not_found_ = true;
- NotifyRestartRequired();
+
+ // We fallback to the network unless this job was falling back to the
+ // appcache from the network which had already failed in some way.
+ if (!is_fallback_)
+ NotifyRestartRequired();
+ else
+ BeginErrorDelivery("failed to load appcache response info");
}
}
const net::HttpResponseInfo* AppCacheURLRequestJob::http_info() const {
if (!info_.get())
- return NULL;
+ return nullptr;
if (range_response_info_)
return range_response_info_.get();
return info_->http_response_info();
diff --git a/chromium/content/browser/appcache/appcache_url_request_job.h b/chromium/content/browser/appcache/appcache_url_request_job.h
index 1d6ba83160f..a9f47f1b873 100644
--- a/chromium/content/browser/appcache/appcache_url_request_job.h
+++ b/chromium/content/browser/appcache/appcache_url_request_job.h
@@ -11,7 +11,6 @@
#include "base/callback.h"
#include "content/browser/appcache/appcache_entry.h"
-#include "content/browser/appcache/appcache_executable_handler.h"
#include "content/browser/appcache/appcache_job.h"
#include "content/browser/appcache/appcache_storage.h"
#include "content/common/content_export.h"
@@ -28,19 +27,13 @@ class AppCacheURLRequestJobTest;
// A net::URLRequestJob derivative that knows how to return a response stored
// in the appcache.
-class CONTENT_EXPORT AppCacheURLRequestJob : public net::URLRequestJob,
+class CONTENT_EXPORT AppCacheURLRequestJob : public AppCacheJob,
public AppCacheStorage::Delegate,
- public AppCacheJob {
+ public net::URLRequestJob {
public:
- // Callback that will be invoked before the request is restarted. The caller
- // can use this opportunity to grab state from the AppCacheURLRequestJob to
- // determine how it should behave when the request is restarted.
- using OnPrepareToRestartCallback = base::OnceClosure;
-
~AppCacheURLRequestJob() override;
// AppCacheJob overrides.
- void Kill() override;
bool IsStarted() const override;
void DeliverAppCachedResponse(const GURL& manifest_url,
int64_t cache_id,
@@ -48,7 +41,9 @@ class CONTENT_EXPORT AppCacheURLRequestJob : public net::URLRequestJob,
bool is_fallback) override;
void DeliverNetworkResponse() override;
void DeliverErrorResponse() override;
- net::URLRequestJob* AsURLRequestJob() override;
+ AppCacheURLRequestJob* AsURLRequestJob() override;
+ base::WeakPtr<AppCacheJob> GetWeakPtr() override;
+ base::WeakPtr<AppCacheURLRequestJob> GetDerivedWeakPtr();
// Accessors for the info about the appcached response, if any,
// that this job has been instructed to deliver. These are only
@@ -65,8 +60,13 @@ class CONTENT_EXPORT AppCacheURLRequestJob : public net::URLRequestJob,
private:
friend class AppCacheRequestHandlerTest;
friend class AppCacheURLRequestJobTest;
- // AppCacheJob::Create() creates this instance.
- friend class AppCacheJob;
+ // AppCacheRequestHandler::CreateJob() creates this instance.
+ friend class AppCacheRequestHandler;
+
+ // Callback that will be invoked before the request is restarted. The caller
+ // can use this opportunity to grab state from the AppCacheURLRequestJob to
+ // determine how it should behave when the request is restarted.
+ using OnPrepareToRestartCallback = base::OnceClosure;
AppCacheURLRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
@@ -80,19 +80,11 @@ class CONTENT_EXPORT AppCacheURLRequestJob : public net::URLRequestJob,
void MaybeBeginDelivery();
void BeginDelivery();
-
- // For executable response handling.
- void BeginExecutableHandlerDelivery();
- void OnExecutableSourceLoaded(int result);
- void InvokeExecutableHandler(AppCacheExecutableHandler* handler);
- void OnExecutableResponseCallback(
- const AppCacheExecutableHandler::Response& response);
void BeginErrorDelivery(const char* message);
// AppCacheStorage::Delegate methods
void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
int64_t response_id) override;
- void OnCacheLoaded(AppCache* cache, int64_t cache_id) override;
const net::HttpResponseInfo* http_info() const;
@@ -101,6 +93,7 @@ class CONTENT_EXPORT AppCacheURLRequestJob : public net::URLRequestJob,
// net::URLRequestJob methods, see url_request_job.h for doc comments
void Start() override;
+ void Kill() override;
net::LoadState GetLoadState() const override;
bool GetCharset(std::string* charset) override;
void GetResponseInfo(net::HttpResponseInfo* info) override;
@@ -133,6 +126,8 @@ class CONTENT_EXPORT AppCacheURLRequestJob : public net::URLRequestJob,
scoped_refptr<AppCache> cache_;
scoped_refptr<AppCacheGroup> group_;
OnPrepareToRestartCallback on_prepare_to_restart_callback_;
+ base::WeakPtrFactory<AppCacheURLRequestJob> weak_factory_;
+ DISALLOW_COPY_AND_ASSIGN(AppCacheURLRequestJob);
};
} // namespace content
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 7e6d05d7ac0..b2adce0158c 100644
--- a/chromium/content/browser/appcache/appcache_url_request_job_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_url_request_job_unittest.cc
@@ -284,11 +284,11 @@ class AppCacheURLRequestJobTest : public testing::Test {
task_stack_.pop();
reader_.reset();
- read_buffer_ = NULL;
- read_info_buffer_ = NULL;
+ read_buffer_ = nullptr;
+ read_info_buffer_ = nullptr;
writer_.reset();
- write_buffer_ = NULL;
- write_info_buffer_ = NULL;
+ write_buffer_ = nullptr;
+ write_info_buffer_ = nullptr;
storage_delegate_.reset();
service_.reset();
@@ -636,8 +636,8 @@ class AppCacheURLRequestJobTest : public testing::Test {
// Setup to create an AppCacheURLRequestJob with orders to deliver
// a network response.
std::unique_ptr<AppCacheURLRequestJob> job(
- new AppCacheURLRequestJob(request_.get(), NULL, storage, NULL, false,
- base::BindOnce(&ExpectNotRestarted)));
+ new AppCacheURLRequestJob(request_.get(), nullptr, storage, nullptr,
+ false, base::BindOnce(&ExpectNotRestarted)));
if (start_after_delivery_orders) {
job->DeliverAppCachedResponse(
@@ -756,8 +756,8 @@ class AppCacheURLRequestJobTest : public testing::Test {
// Create job with orders to deliver an appcached entry.
std::unique_ptr<AppCacheURLRequestJob> job(
- new AppCacheURLRequestJob(request_.get(), NULL, storage, NULL, false,
- base::BindOnce(&ExpectNotRestarted)));
+ new AppCacheURLRequestJob(request_.get(), nullptr, storage, nullptr,
+ false, base::BindOnce(&ExpectNotRestarted)));
job->DeliverAppCachedResponse(
GURL(), 111,
AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_), false);
diff --git a/chromium/content/browser/appcache/chrome_appcache_service.cc b/chromium/content/browser/appcache/chrome_appcache_service.cc
index e6d557ad035..db7f04b2cc4 100644
--- a/chromium/content/browser/appcache/chrome_appcache_service.cc
+++ b/chromium/content/browser/appcache/chrome_appcache_service.cc
@@ -17,8 +17,7 @@ namespace content {
ChromeAppCacheService::ChromeAppCacheService(
storage::QuotaManagerProxy* quota_manager_proxy)
- : AppCacheServiceImpl(quota_manager_proxy), resource_context_(NULL) {
-}
+ : AppCacheServiceImpl(quota_manager_proxy), resource_context_(nullptr) {}
void ChromeAppCacheService::InitializeOnIOThread(
const base::FilePath& cache_path,
diff --git a/chromium/content/browser/appcache/chrome_appcache_service_unittest.cc b/chromium/content/browser/appcache/chrome_appcache_service_unittest.cc
index 9b98d31d2a2..2db6bb0e092 100644
--- a/chromium/content/browser/appcache/chrome_appcache_service_unittest.cc
+++ b/chromium/content/browser/appcache/chrome_appcache_service_unittest.cc
@@ -94,7 +94,7 @@ ChromeAppCacheServiceTest::CreateAppCacheServiceImpl(
const base::FilePath& appcache_path,
bool init_storage) {
scoped_refptr<ChromeAppCacheService> appcache_service =
- new ChromeAppCacheService(NULL);
+ new ChromeAppCacheService(nullptr);
scoped_refptr<MockSpecialStoragePolicy> mock_policy =
new MockSpecialStoragePolicy;
mock_policy->AddProtected(kProtectedManifestURL.GetOrigin());
@@ -152,7 +152,7 @@ TEST_F(ChromeAppCacheServiceTest, KeepOnDestruction) {
InsertDataIntoAppCache(appcache_service.get());
// Test: delete the ChromeAppCacheService
- appcache_service = NULL;
+ appcache_service = nullptr;
scoped_task_environment_.RunUntilIdle();
// Recreate the appcache (for reading the data back)
@@ -172,7 +172,7 @@ TEST_F(ChromeAppCacheServiceTest, KeepOnDestruction) {
origins.end());
// Delete and let cleanup tasks run prior to returning.
- appcache_service = NULL;
+ appcache_service = nullptr;
scoped_task_environment_.RunUntilIdle();
}
@@ -192,7 +192,7 @@ TEST_F(ChromeAppCacheServiceTest, SaveSessionState) {
appcache_service->set_force_keep_session_state();
// Test: delete the ChromeAppCacheService
- appcache_service = NULL;
+ appcache_service = nullptr;
scoped_task_environment_.RunUntilIdle();
// Recreate the appcache (for reading the data back)
@@ -212,7 +212,7 @@ TEST_F(ChromeAppCacheServiceTest, SaveSessionState) {
origins.end());
// Delete and let cleanup tasks run prior to returning.
- appcache_service = NULL;
+ appcache_service = nullptr;
scoped_task_environment_.RunUntilIdle();
}
diff --git a/chromium/content/browser/appcache/mock_appcache_storage_unittest.cc b/chromium/content/browser/appcache/mock_appcache_storage_unittest.cc
index 55fb914932b..25ad99c83a1 100644
--- a/chromium/content/browser/appcache/mock_appcache_storage_unittest.cc
+++ b/chromium/content/browser/appcache/mock_appcache_storage_unittest.cc
@@ -186,8 +186,8 @@ TEST_F(MockAppCacheStorageTest, LoadGroupAndCache_FarHit) {
// these objects appear as "not currently in use".
AppCache* cache_ptr = cache.get();
AppCacheGroup* group_ptr = group.get();
- cache = NULL;
- group = NULL;
+ cache = nullptr;
+ group = nullptr;
// Setup a delegate to receive completion callbacks.
MockStorageDelegate delegate;
@@ -201,7 +201,7 @@ TEST_F(MockAppCacheStorageTest, LoadGroupAndCache_FarHit) {
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(cache_id, delegate.loaded_cache_id_);
EXPECT_EQ(cache_ptr, delegate.loaded_cache_.get());
- delegate.loaded_cache_ = NULL;
+ delegate.loaded_cache_ = nullptr;
// Conduct the group load test.
EXPECT_NE(manifest_url, delegate.loaded_manifest_url_);
@@ -373,8 +373,8 @@ TEST_F(MockAppCacheStorageTest, MakeGroupObsolete) {
EXPECT_TRUE(storage->stored_groups_.empty());
EXPECT_TRUE(cache->HasOneRef());
EXPECT_FALSE(group->HasOneRef());
- delegate.obsoleted_group_ = NULL;
- cache = NULL;
+ delegate.obsoleted_group_ = nullptr;
+ cache = nullptr;
EXPECT_TRUE(group->HasOneRef());
}
@@ -543,8 +543,8 @@ TEST_F(MockAppCacheStorageTest, FindMainResponseWithMultipleCandidates) {
storage->AddStoredGroup(group.get());
storage->AddStoredCache(cache.get());
// Drop our references to cache1 so it appears as "not in use".
- cache = NULL;
- group = NULL;
+ cache = nullptr;
+ group = nullptr;
// The second cache.
cache = new AppCache(service.storage(), kCacheId2);
diff --git a/chromium/content/browser/background_fetch/OWNERS b/chromium/content/browser/background_fetch/OWNERS
index 33676fa093b..317a5576e9a 100644
--- a/chromium/content/browser/background_fetch/OWNERS
+++ b/chromium/content/browser/background_fetch/OWNERS
@@ -4,6 +4,7 @@
peter@chromium.org
johnme@chromium.org
+delphick@chromium.org
# TEAM: platform-capabilities@chromium.org
# COMPONENT: Blink>BackgroundFetch
diff --git a/chromium/content/browser/background_fetch/background_fetch.proto b/chromium/content/browser/background_fetch/background_fetch.proto
index 0725408eece..01e7c359d22 100644
--- a/chromium/content/browser/background_fetch/background_fetch.proto
+++ b/chromium/content/browser/background_fetch/background_fetch.proto
@@ -10,7 +10,15 @@ package content.proto;
// Stores per-registration (as opposed to per-request) data.
//
-// Next tag: 2
+// Next tag: 5
message BackgroundFetchRegistration {
- optional int64 creation_microseconds_since_unix_epoch = 1;
-} \ No newline at end of file
+ // See definition of |unique_id| in BackgroundFetchRegistrationId.
+ optional string unique_id = 1;
+
+ // See definition of |developer_id| in BackgroundFetchRegistrationId.
+ optional bytes developer_id = 2;
+
+ optional string origin = 3;
+
+ optional int64 creation_microseconds_since_unix_epoch = 4;
+}
diff --git a/chromium/content/browser/background_fetch/background_fetch_context.cc b/chromium/content/browser/background_fetch/background_fetch_context.cc
index d2275571aa3..cc1cb4bc69b 100644
--- a/chromium/content/browser/background_fetch/background_fetch_context.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_context.cc
@@ -6,20 +6,24 @@
#include <utility>
-#include "base/memory/ptr_util.h"
+#include "base/bind_helpers.h"
#include "content/browser/background_fetch/background_fetch_job_controller.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/background_fetch/background_fetch_registration_notifier.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/background_fetch_delegate.h"
-#include "content/public/browser/blob_handle.h"
#include "content/public/browser/browser_context.h"
#include "net/url_request/url_request_context_getter.h"
+#include "storage/browser/blob/blob_data_handle.h"
namespace content {
namespace {
+void IgnoreError(blink::mojom::BackgroundFetchError) {
+ // TODO(johnme): Log errors to UMA.
+}
+
// Records the |error| status issued by the DataManager after it was requested
// to create and store a new Background Fetch registration.
void RecordRegistrationCreatedError(blink::mojom::BackgroundFetchError error) {
@@ -52,6 +56,47 @@ BackgroundFetchContext::~BackgroundFetchContext() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
+void BackgroundFetchContext::GetRegistration(
+ int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ const std::string& developer_id,
+ blink::mojom::BackgroundFetchService::GetRegistrationCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ data_manager_.GetRegistration(
+ service_worker_registration_id, origin, developer_id,
+ base::BindOnce(&BackgroundFetchContext::DidGetRegistration,
+ weak_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void BackgroundFetchContext::GetDeveloperIdsForServiceWorker(
+ int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback) {
+ data_manager_.GetDeveloperIdsForServiceWorker(service_worker_registration_id,
+ origin, std::move(callback));
+}
+
+void BackgroundFetchContext::DidGetRegistration(
+ blink::mojom::BackgroundFetchService::GetRegistrationCallback callback,
+ blink::mojom::BackgroundFetchError error,
+ std::unique_ptr<BackgroundFetchRegistration> registration) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (error != blink::mojom::BackgroundFetchError::NONE) {
+ std::move(callback).Run(error, base::nullopt);
+ return;
+ }
+
+ DCHECK(registration);
+ // The data manager only has the number of bytes from completed downloads, so
+ // augment this with the number of downloaded bytes from in-progress jobs.
+ DCHECK(job_controllers_.count(registration->unique_id));
+ registration->downloaded +=
+ job_controllers_[registration->unique_id]->GetInProgressDownloadedBytes();
+ std::move(callback).Run(error, *registration.get());
+}
+
void BackgroundFetchContext::StartFetch(
const BackgroundFetchRegistrationId& registration_id,
const std::vector<ServiceWorkerFetchRequest>& requests,
@@ -71,40 +116,63 @@ void BackgroundFetchContext::DidCreateRegistration(
const BackgroundFetchOptions& options,
blink::mojom::BackgroundFetchService::FetchCallback callback,
blink::mojom::BackgroundFetchError error,
- const base::Optional<BackgroundFetchRegistration>& registration) {
+ std::unique_ptr<BackgroundFetchRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
RecordRegistrationCreatedError(error);
- if (error == blink::mojom::BackgroundFetchError::NONE) {
- DCHECK(registration);
- // Create the BackgroundFetchJobController to do the actual fetching.
- CreateController(registration_id, options, registration.value());
+ if (error != blink::mojom::BackgroundFetchError::NONE) {
+ std::move(callback).Run(error, base::nullopt);
+ return;
}
- std::move(callback).Run(error, registration);
+ DCHECK(registration);
+ // Create the BackgroundFetchJobController to do the actual fetching.
+ CreateController(registration_id, options, *registration.get());
+ std::move(callback).Run(error, *registration.get());
}
-BackgroundFetchJobController* BackgroundFetchContext::GetActiveFetch(
- const std::string& unique_id) const {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+void BackgroundFetchContext::AddRegistrationObserver(
+ const std::string& unique_id,
+ blink::mojom::BackgroundFetchRegistrationObserverPtr observer) {
+ registration_notifier_->AddObserver(unique_id, std::move(observer));
+}
- auto iter = active_fetches_.find(unique_id);
- if (iter == active_fetches_.end())
- return nullptr;
+void BackgroundFetchContext::UpdateUI(
+ const std::string& unique_id,
+ const std::string& title,
+ blink::mojom::BackgroundFetchService::UpdateUICallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BackgroundFetchJobController* controller = iter->second.get();
- if (controller->state() == BackgroundFetchJobController::State::ABORTED ||
- controller->state() == BackgroundFetchJobController::State::COMPLETED) {
- return nullptr;
+ // The registration must a) still be active, or b) have completed/failed (not
+ // aborted) with the waitUntil promise from that event not yet resolved.
+ if (!job_controllers_.count(unique_id)) {
+ std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_ID);
+ return;
}
- return controller;
+ data_manager_.UpdateRegistrationUI(
+ unique_id, title,
+ base::BindOnce(&BackgroundFetchContext::DidUpdateStoredUI,
+ weak_factory_.GetWeakPtr(), unique_id, title,
+ std::move(callback)));
}
-void BackgroundFetchContext::AddRegistrationObserver(
+void BackgroundFetchContext::DidUpdateStoredUI(
const std::string& unique_id,
- blink::mojom::BackgroundFetchRegistrationObserverPtr observer) {
- registration_notifier_->AddObserver(unique_id, std::move(observer));
+ const std::string& title,
+ blink::mojom::BackgroundFetchService::UpdateUICallback callback,
+ blink::mojom::BackgroundFetchError error) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // TODO(delphick): The controller might not exist if the developer updates the
+ // UI from the event using event.waitUntil. Consider showing a message in the
+ // console.
+ if (error == blink::mojom::BackgroundFetchError::NONE &&
+ job_controllers_.count(unique_id)) {
+ job_controllers_[unique_id]->UpdateUI(title);
+ }
+
+ std::move(callback).Run(error);
}
void BackgroundFetchContext::CreateController(
@@ -118,49 +186,76 @@ void BackgroundFetchContext::CreateController(
// Safe because JobControllers are destroyed before RegistrationNotifier.
base::BindRepeating(&BackgroundFetchRegistrationNotifier::Notify,
base::Unretained(registration_notifier_.get())),
- base::BindOnce(&BackgroundFetchContext::DidCompleteJob,
- weak_factory_.GetWeakPtr()));
+ base::BindOnce(&BackgroundFetchContext::DidFinishJob,
+ weak_factory_.GetWeakPtr(), base::Bind(&IgnoreError)));
+
+ // TODO(delphick): This assumes that fetches are always started afresh in
+ // each browser session. We need to initialize the number of downloads using
+ // information loaded from the database.
+ controller->InitializeRequestStatus(
+ 0, /* completed_downloads*/
+ data_manager_.GetTotalNumberOfRequests(registration_id),
+ std::vector<std::string>() /* outstanding download GUIDs */);
// Start fetching the first few requests immediately. At some point in the
// future we may want a more elaborate scheduling mechanism here.
controller->Start();
- active_fetches_.insert(
+ job_controllers_.insert(
std::make_pair(registration_id.unique_id(), std::move(controller)));
}
-void BackgroundFetchContext::DidCompleteJob(
- BackgroundFetchJobController* controller) {
+void BackgroundFetchContext::Abort(
+ const BackgroundFetchRegistrationId& registration_id,
+ blink::mojom::BackgroundFetchService::AbortCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- const BackgroundFetchRegistrationId& registration_id =
- controller->registration_id();
-
- // Delete observers for the registration, there won't be any future updates.
- registration_notifier_->RemoveObservers(registration_id.unique_id());
-
- DCHECK_GT(active_fetches_.count(registration_id.unique_id()), 0u);
- switch (controller->state()) {
- case BackgroundFetchJobController::State::ABORTED:
- event_dispatcher_.DispatchBackgroundFetchAbortEvent(
- registration_id,
- base::Bind(&BackgroundFetchContext::DeleteRegistration,
- weak_factory_.GetWeakPtr(), registration_id,
- std::vector<std::unique_ptr<BlobHandle>>()));
- return;
- case BackgroundFetchJobController::State::COMPLETED:
- data_manager_.GetSettledFetchesForRegistration(
- registration_id,
- base::BindOnce(&BackgroundFetchContext::DidGetSettledFetches,
- weak_factory_.GetWeakPtr(), registration_id));
- return;
- case BackgroundFetchJobController::State::INITIALIZED:
- case BackgroundFetchJobController::State::FETCHING:
- // These cases should not happen. Fall through to the NOTREACHED() below.
- break;
- }
+ DidFinishJob(std::move(callback), registration_id, true /* aborted */);
+}
- NOTREACHED();
+void BackgroundFetchContext::DidFinishJob(
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback,
+ const BackgroundFetchRegistrationId& registration_id,
+ bool aborted) {
+ 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.
+ data_manager_.MarkRegistrationForDeletion(
+ registration_id,
+ base::BindOnce(&BackgroundFetchContext::DidMarkForDeletion,
+ weak_factory_.GetWeakPtr(), registration_id, aborted,
+ std::move(callback)));
+}
+
+void BackgroundFetchContext::DidMarkForDeletion(
+ const BackgroundFetchRegistrationId& registration_id,
+ bool aborted,
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback,
+ blink::mojom::BackgroundFetchError error) {
+ std::move(callback).Run(error);
+
+ // 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.
+ if (error != blink::mojom::BackgroundFetchError::NONE)
+ return;
+
+ if (aborted) {
+ DCHECK(job_controllers_.count(registration_id.unique_id()));
+ job_controllers_[registration_id.unique_id()]->Abort();
+
+ CleanupRegistration(registration_id, {});
+
+ event_dispatcher_.DispatchBackgroundFetchAbortEvent(
+ registration_id, base::Bind(&base::DoNothing));
+ } else {
+ data_manager_.GetSettledFetchesForRegistration(
+ registration_id,
+ base::BindOnce(&BackgroundFetchContext::DidGetSettledFetches,
+ weak_factory_.GetWeakPtr(), registration_id));
+ }
}
void BackgroundFetchContext::DidGetSettledFetches(
@@ -168,11 +263,11 @@ void BackgroundFetchContext::DidGetSettledFetches(
blink::mojom::BackgroundFetchError error,
bool background_fetch_succeeded,
std::vector<BackgroundFetchSettledFetch> settled_fetches,
- std::vector<std::unique_ptr<BlobHandle>> blob_handles) {
+ std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (error != blink::mojom::BackgroundFetchError::NONE) {
- DeleteRegistration(registration_id, std::move(blob_handles));
+ CleanupRegistration(registration_id, {});
return;
}
@@ -182,30 +277,55 @@ void BackgroundFetchContext::DidGetSettledFetches(
if (background_fetch_succeeded) {
event_dispatcher_.DispatchBackgroundFetchedEvent(
registration_id, std::move(settled_fetches),
- base::Bind(&BackgroundFetchContext::DeleteRegistration,
+ base::Bind(&BackgroundFetchContext::CleanupRegistration,
weak_factory_.GetWeakPtr(), registration_id,
- std::move(blob_handles)));
+ // 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)));
} else {
event_dispatcher_.DispatchBackgroundFetchFailEvent(
registration_id, std::move(settled_fetches),
- base::Bind(&BackgroundFetchContext::DeleteRegistration,
+ base::Bind(&BackgroundFetchContext::CleanupRegistration,
weak_factory_.GetWeakPtr(), registration_id,
- std::move(blob_handles)));
+ // 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)));
}
}
-void BackgroundFetchContext::DeleteRegistration(
+void BackgroundFetchContext::CleanupRegistration(
const BackgroundFetchRegistrationId& registration_id,
- const std::vector<std::unique_ptr<BlobHandle>>& blob_handles) {
+ const std::vector<std::unique_ptr<storage::BlobDataHandle>>& blob_handles) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // 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 backgroundfetched/backgroundfetchfail
+ // event has been resolved.
+ 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::Bind(&BackgroundFetchContext::LastObserverGarbageCollected,
+ weak_factory_.GetWeakPtr(), registration_id));
+}
+
+void BackgroundFetchContext::LastObserverGarbageCollected(
+ const BackgroundFetchRegistrationId& registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_GT(active_fetches_.count(registration_id.unique_id()), 0u);
- // Delete all persistent information associated with the |registration_id|.
data_manager_.DeleteRegistration(
registration_id, base::BindOnce(&RecordRegistrationDeletedError));
-
- // Delete the local state associated with the |registration_id|.
- active_fetches_.erase(registration_id.unique_id());
}
} // namespace content
diff --git a/chromium/content/browser/background_fetch/background_fetch_context.h b/chromium/content/browser/background_fetch/background_fetch_context.h
index f591395a752..8692ef07511 100644
--- a/chromium/content/browser/background_fetch/background_fetch_context.h
+++ b/chromium/content/browser/background_fetch/background_fetch_context.h
@@ -20,13 +20,16 @@
#include "content/public/browser/browser_thread.h"
#include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h"
+namespace storage {
+class BlobDataHandle;
+}
+
namespace content {
class BackgroundFetchJobController;
struct BackgroundFetchOptions;
class BackgroundFetchRegistrationId;
class BackgroundFetchRegistrationNotifier;
-class BlobHandle;
class BrowserContext;
class ServiceWorkerContextWrapper;
struct ServiceWorkerFetchRequest;
@@ -45,18 +48,35 @@ class CONTENT_EXPORT BackgroundFetchContext
BrowserContext* browser_context,
const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context);
+ // Gets the active Background Fetch registration identified by |developer_id|
+ // for the given |service_worker_id| and |origin|. The |callback| will be
+ // invoked with the registration when it has been retrieved.
+ void GetRegistration(
+ int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ const std::string& developer_id,
+ blink::mojom::BackgroundFetchService::GetRegistrationCallback callback);
+
+ // Gets all the Background Fetch registration |developer_id|s for a Service
+ // Worker and invokes |callback| with that list.
+ void GetDeveloperIdsForServiceWorker(
+ int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback);
+
// Starts a Background Fetch for the |registration_id|. The |requests| will be
// asynchronously fetched. The |callback| will be invoked when the fetch has
- // been registered, or an error occurred that avoids it from doing so.
+ // been registered, or an error occurred that prevents it from doing so.
void StartFetch(const BackgroundFetchRegistrationId& registration_id,
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
blink::mojom::BackgroundFetchService::FetchCallback callback);
- // Returns the JobController that is handling the |unique_id|, or a nullptr if
- // it does not exist. Must be immediately used by the caller.
- BackgroundFetchJobController* GetActiveFetch(
- const std::string& unique_id) const;
+ // Aborts the Background Fetch for the |registration_id|. The callback will be
+ // invoked with INVALID_ID if the registration has already completed or
+ // aborted, STORAGE_ERROR if an I/O error occurs, or NONE for success.
+ void Abort(const BackgroundFetchRegistrationId& registration_id,
+ blink::mojom::BackgroundFetchService::AbortCallback callback);
// Registers the |observer| to be notified of progress events for the
// registration identified by |unique_id| whenever they happen. The observer
@@ -65,7 +85,13 @@ class CONTENT_EXPORT BackgroundFetchContext
const std::string& unique_id,
blink::mojom::BackgroundFetchRegistrationObserverPtr observer);
- BackgroundFetchDataManager& data_manager() { return data_manager_; }
+ // Updates the title of the Background Fetch identified by |unique_id|. The
+ // |callback| will be invoked when the title has been updated, or an error
+ // occurred that prevents it from doing so.
+ void UpdateUI(
+ const std::string& unique_id,
+ const std::string& title,
+ blink::mojom::BackgroundFetchService::UpdateUICallback callback);
private:
friend class base::DeleteHelper<BackgroundFetchContext>;
@@ -81,16 +107,41 @@ class CONTENT_EXPORT BackgroundFetchContext
const BackgroundFetchOptions& options,
const BackgroundFetchRegistration& registration);
+ // Called when an existing registration has been retrieved from the data
+ // manager. If the registration does not exist then |registration| is nullptr.
+ void DidGetRegistration(
+ blink::mojom::BackgroundFetchService::GetRegistrationCallback callback,
+ blink::mojom::BackgroundFetchError error,
+ std::unique_ptr<BackgroundFetchRegistration> registration);
+
// Called when a new registration has been created by the data manager.
void DidCreateRegistration(
const BackgroundFetchRegistrationId& registration_id,
const BackgroundFetchOptions& options,
blink::mojom::BackgroundFetchService::FetchCallback callback,
blink::mojom::BackgroundFetchError error,
- const base::Optional<BackgroundFetchRegistration>& registration);
+ std::unique_ptr<BackgroundFetchRegistration> registration);
- // Called when the given |controller| has finished processing its job.
- void DidCompleteJob(BackgroundFetchJobController* controller);
+ // Called when the new title has been updated in the data manager.
+ void DidUpdateStoredUI(
+ const std::string& unique_id,
+ const std::string& title,
+ blink::mojom::BackgroundFetchService::UpdateUICallback callback,
+ blink::mojom::BackgroundFetchError error);
+
+ // Called by a JobController when it finishes processing. Also used to
+ // implement |Abort|.
+ void DidFinishJob(
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback,
+ const BackgroundFetchRegistrationId& registration_id,
+ bool aborted);
+
+ // Called when the data manager finishes marking a registration as deleted.
+ void DidMarkForDeletion(
+ const BackgroundFetchRegistrationId& registration_id,
+ bool aborted,
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback,
+ blink::mojom::BackgroundFetchError error);
// Called when the sequence of settled fetches for |registration_id| have been
// retrieved from storage, and the Service Worker event can be invoked.
@@ -99,13 +150,21 @@ class CONTENT_EXPORT BackgroundFetchContext
blink::mojom::BackgroundFetchError error,
bool background_fetch_succeeded,
std::vector<BackgroundFetchSettledFetch> settled_fetches,
- std::vector<std::unique_ptr<BlobHandle>> blob_handles);
+ std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles);
// Called when all processing for the |registration_id| has been finished and
- // the job, including its associated data, is ready to be deleted.
- void DeleteRegistration(
+ // the job is ready to be deleted. |blob_handles| are unused, but some callers
+ // use it to keep blobs alive for the right duration.
+ void CleanupRegistration(
const BackgroundFetchRegistrationId& registration_id,
- const std::vector<std::unique_ptr<BlobHandle>>& blob_handles);
+ const std::vector<std::unique_ptr<storage::BlobDataHandle>>&
+ blob_data_handles);
+
+ // 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);
// |this| is owned, indirectly, by the BrowserContext.
BrowserContext* browser_context_;
@@ -119,7 +178,7 @@ class CONTENT_EXPORT BackgroundFetchContext
// controllers. Must be destroyed before |data_manager_| and
// |registration_notifier_|.
std::map<std::string, std::unique_ptr<BackgroundFetchJobController>>
- active_fetches_;
+ job_controllers_;
base::WeakPtrFactory<BackgroundFetchContext> weak_factory_; // Must be last.
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 125a4fa270f..120b53c5723 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
@@ -36,7 +36,7 @@ bool ParseOriginListHeader(const std::string& value,
value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
for (const std::string& origin_string : origin_vector) {
- url::Origin origin = url::Origin(GURL(origin_string));
+ url::Origin origin = url::Origin::Create(GURL(origin_string));
if (origin.unique())
return false;
@@ -58,7 +58,8 @@ BackgroundFetchCrossOriginFilter::BackgroundFetchCrossOriginFilter(
const auto& response_header_map = request.GetResponseHeaders();
// True iff |source_origin| is the same origin as the original request URL.
- is_same_origin_ = source_origin.IsSameOriginWith(url::Origin(final_url));
+ is_same_origin_ =
+ source_origin.IsSameOriginWith(url::Origin::Create(final_url));
// Access-Control-Allow-Origin checks. The header's values must be valid for
// it to not be completely discarded.
diff --git a/chromium/content/browser/background_fetch/background_fetch_cross_origin_filter_unittest.cc b/chromium/content/browser/background_fetch/background_fetch_cross_origin_filter_unittest.cc
index 980d28719cb..85949dc7ffe 100644
--- a/chromium/content/browser/background_fetch/background_fetch_cross_origin_filter_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_cross_origin_filter_unittest.cc
@@ -25,7 +25,7 @@ class BackgroundFetchCrossOriginFilterTest : public ::testing::Test {
public:
BackgroundFetchCrossOriginFilterTest()
: thread_bundle_(TestBrowserThreadBundle::REAL_IO_THREAD),
- source_(url::Origin(GURL(kFirstOrigin))) {}
+ source_(url::Origin::Create(GURL(kFirstOrigin))) {}
~BackgroundFetchCrossOriginFilterTest() override = default;
// Creates a BackgroundFetchRequestInfo instance filled with the information
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 86344bc5880..21b9620023d 100644
--- a/chromium/content/browser/background_fetch/background_fetch_data_manager.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_data_manager.cc
@@ -4,163 +4,36 @@
#include "content/browser/background_fetch/background_fetch_data_manager.h"
-#include <algorithm>
+#include <utility>
#include "base/command_line.h"
#include "base/containers/queue.h"
-#include "base/memory/ptr_util.h"
-#include "base/numerics/checked_math.h"
-#include "base/strings/string_number_conversions.h"
+#include "base/guid.h"
#include "base/time/time.h"
-#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/background_fetch_constants.h"
-#include "content/browser/background_fetch/background_fetch_context.h"
#include "content/browser/background_fetch/background_fetch_cross_origin_filter.h"
#include "content/browser/background_fetch/background_fetch_request_info.h"
+#include "content/browser/background_fetch/storage/cleanup_task.h"
+#include "content/browser/background_fetch/storage/create_registration_task.h"
+#include "content/browser/background_fetch/storage/database_task.h"
+#include "content/browser/background_fetch/storage/delete_registration_task.h"
+#include "content/browser/background_fetch/storage/get_developer_ids_task.h"
+#include "content/browser/background_fetch/storage/get_registration_task.h"
+#include "content/browser/background_fetch/storage/mark_registration_for_deletion_task.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/public/browser/blob_handle.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/download_interrupt_reasons.h"
-#include "content/public/browser/download_item.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
-#include "services/network/public/interfaces/fetch_api.mojom.h"
-
-// Service Worker DB UserData schema
-// =================================
-// Design doc:
-// https://docs.google.com/document/d/1-WPPTP909Gb5PnaBOKP58tPVLw2Fq0Ln-u1EBviIBns/edit
-//
-// - Each key will be stored twice by the Service Worker DB, once as a
-// "REG_HAS_USER_DATA:", and once as a "REG_USER_DATA:" - see
-// content/browser/service_worker/service_worker_database.cc for details.
-// - Integer values are serialized as a string by base::Int*ToString().
-//
-// key: "bgfetch_registration_developer_id_to_unique_id_"
-// + <std::string 'developer_id'>
-// value: <std::string 'unique_id'>
-//
-// key: "bgfetch_registration_" + <std::string 'unique_id'>
-// value: <std::string 'serialized content::proto::BackgroundFetchRegistration'>
-//
-// key: "bgfetch_request_" + <std::string 'registration unique_id'>
-// + "_" + <int 'request_index'>
-// value: <TODO: FetchAPIRequest serialized as a string>
-//
-// key: "bgfetch_pending_request_"
-// + <int64_t 'registration_creation_microseconds_since_unix_epoch'>
-// + "_" + <std::string 'registration unique_id'>
-// + "_" + <int 'request_index'>
-// value: ""
+#include "storage/browser/blob/blob_data_builder.h"
+#include "storage/browser/blob/blob_impl.h"
+#include "storage/browser/blob/blob_storage_context.h"
+#include "third_party/WebKit/common/blob/blob.mojom.h"
namespace content {
namespace {
-// Warning: registration |developer_id|s may contain kSeparator characters.
-const char kSeparator[] = "_";
-
-const char kRegistrationDeveloperIdToUniqueIdKeyPrefix[] =
- "bgfetch_registration_developer_id_to_unique_id_";
-const char kRegistrationKeyPrefix[] = "bgfetch_registration_";
-const char kRequestKeyPrefix[] = "bgfetch_request_";
-const char kPendingRequestKeyPrefix[] = "bgfetch_pending_request_";
-
-std::string RegistrationDeveloperIdToUniqueIdKey(
- const std::string& developer_id) {
- // Allows looking up the active registration's |unique_id| by |developer_id|.
- return kRegistrationDeveloperIdToUniqueIdKeyPrefix + developer_id;
-}
-
-std::string RegistrationKey(
- const BackgroundFetchRegistrationId& registration_id) {
- // Allows looking up a registration by |unique_id|.
- return kRegistrationKeyPrefix + registration_id.unique_id();
-}
-
-std::string RequestKeyPrefix(
- const BackgroundFetchRegistrationId& registration_id) {
- // Allows looking up all requests within a registration.
- return kRequestKeyPrefix + registration_id.unique_id() + kSeparator;
-}
-
-std::string RequestKey(const BackgroundFetchRegistrationId& registration_id,
- int request_index) {
- // Allows looking up a request by registration id and index within that.
- return RequestKeyPrefix(registration_id) + base::IntToString(request_index);
-}
-
-std::string PendingRequestKeyPrefix(
- int64_t registration_creation_microseconds_since_unix_epoch,
- const BackgroundFetchRegistrationId& registration_id) {
- // These keys are ordered by the registration's creation time rather than by
- // its |unique_id|, so that the highest priority pending requests in FIFO
- // order can be looked up by fetching the lexicographically smallest keys.
- // https://crbug.com/741609 may introduce more advanced prioritisation.
- //
- // Since the ordering must survive restarts, wall clock time is used, but that
- // is not monotonically increasing, so the ordering is not exact, and the
- // |unique_id| is appended to break ties in case the wall clock returns the
- // same values more than once.
- //
- // On Nov 20 2286 17:46:39 the microseconds will transition from 9999999999999
- // to 10000000000000 and pending requests will briefly sort incorrectly.
- return kPendingRequestKeyPrefix +
- base::Int64ToString(
- registration_creation_microseconds_since_unix_epoch) +
- kSeparator + registration_id.unique_id() + kSeparator;
-}
-
-std::string PendingRequestKey(
- int64_t registration_creation_microseconds_since_unix_epoch,
- const BackgroundFetchRegistrationId& registration_id,
- int request_index) {
- // In addition to the ordering from PendingRequestKeyPrefix, the requests
- // within each registration should be prioritized according to their index.
- return PendingRequestKeyPrefix(
- registration_creation_microseconds_since_unix_epoch,
- registration_id) +
- base::IntToString(request_index);
-}
-
-enum class DatabaseStatus { kOk, kFailed, kNotFound };
-
-DatabaseStatus ToDatabaseStatus(ServiceWorkerStatusCode status) {
- switch (status) {
- case SERVICE_WORKER_OK:
- return DatabaseStatus::kOk;
- case SERVICE_WORKER_ERROR_FAILED:
- case SERVICE_WORKER_ERROR_ABORT:
- // FAILED is for invalid arguments (e.g. empty key) or database errors.
- // ABORT is for unexpected failures, e.g. because shutdown is in progress.
- // BackgroundFetchDataManager handles both of these the same way.
- return DatabaseStatus::kFailed;
- case SERVICE_WORKER_ERROR_NOT_FOUND:
- // This can also happen for writes, if the ServiceWorkerRegistration has
- // been deleted.
- return DatabaseStatus::kNotFound;
- case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
- case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
- case SERVICE_WORKER_ERROR_EXISTS:
- case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
- case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
- case SERVICE_WORKER_ERROR_IPC_FAILED:
- case SERVICE_WORKER_ERROR_NETWORK:
- case SERVICE_WORKER_ERROR_SECURITY:
- case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
- case SERVICE_WORKER_ERROR_STATE:
- case SERVICE_WORKER_ERROR_TIMEOUT:
- case SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED:
- case SERVICE_WORKER_ERROR_DISK_CACHE:
- case SERVICE_WORKER_ERROR_REDUNDANT:
- case SERVICE_WORKER_ERROR_DISALLOWED:
- case SERVICE_WORKER_ERROR_MAX_VALUE:
- break;
- }
- NOTREACHED();
- return DatabaseStatus::kFailed;
-}
-
// Returns whether the response contained in the Background Fetch |request| is
// considered OK. See https://fetch.spec.whatwg.org/#ok-status aka a successful
// 2xx status per https://tools.ietf.org/html/rfc7231#section-6.3.
@@ -171,276 +44,15 @@ bool IsOK(const BackgroundFetchRequestInfo& request) {
} // namespace
-// A DatabaseTask is an asynchronous "transaction" that needs to read/write the
-// Service Worker Database.
-//
-// Only one DatabaseTask can run at once per StoragePartition, and no other code
-// reads/writes Background Fetch keys, so each task effectively has an exclusive
-// lock, except that core Service Worker code may delete all keys for a
-// ServiceWorkerRegistration or the entire database at any time.
-class BackgroundFetchDataManager::DatabaseTask {
- public:
- virtual ~DatabaseTask() = default;
-
- void Run() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(!data_manager_->database_tasks_.empty());
- DCHECK_EQ(data_manager_->database_tasks_.front().get(), this);
- Start();
- }
-
- protected:
- explicit DatabaseTask(BackgroundFetchDataManager* data_manager)
- : data_manager_(data_manager) {}
-
- // The task should begin reading/writing when this is called.
- virtual void Start() = 0;
-
- // Each task MUST call this once finished, even if exceptions occur, to
- // release their lock and allow the next task to execute.
- void Finished() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(!data_manager_->database_tasks_.empty());
- DCHECK_EQ(data_manager_->database_tasks_.front().get(), this);
- // Keep a reference to |this| on the stack, so |this| lives until |self|
- // goes out of scope instead of being destroyed when |pop| is called.
- std::unique_ptr<DatabaseTask> self(
- std::move(data_manager_->database_tasks_.front()));
- data_manager_->database_tasks_.pop();
- if (!data_manager_->database_tasks_.empty())
- data_manager_->database_tasks_.front()->Run();
- }
-
- ServiceWorkerContextWrapper* service_worker_context() {
- DCHECK(data_manager_->service_worker_context_);
- return data_manager_->service_worker_context_.get();
- }
-
- private:
- BackgroundFetchDataManager* data_manager_; // Owns this.
-
- DISALLOW_COPY_AND_ASSIGN(DatabaseTask);
-};
-
-namespace {
-
-class CreateRegistrationTask : public BackgroundFetchDataManager::DatabaseTask {
- public:
- CreateRegistrationTask(
- BackgroundFetchDataManager* data_manager,
- const BackgroundFetchRegistrationId& registration_id,
- const std::vector<ServiceWorkerFetchRequest>& requests,
- const BackgroundFetchOptions& options,
- blink::mojom::BackgroundFetchService::FetchCallback callback)
- : DatabaseTask(data_manager),
- registration_id_(registration_id),
- requests_(requests),
- options_(options),
- callback_(std::move(callback)),
- weak_factory_(this) {}
-
- ~CreateRegistrationTask() override = default;
-
- void Start() override {
- service_worker_context()->GetRegistrationUserData(
- registration_id_.service_worker_registration_id(),
- {RegistrationDeveloperIdToUniqueIdKey(registration_id_.developer_id())},
- base::Bind(&CreateRegistrationTask::DidGetUniqueId,
- weak_factory_.GetWeakPtr()));
- }
-
- private:
- void DidGetUniqueId(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
- switch (ToDatabaseStatus(status)) {
- case DatabaseStatus::kNotFound:
- StoreRegistration();
- return;
- case DatabaseStatus::kOk:
- // Can't create a registration since there is already an active
- // registration with the same |developer_id|. It must be deactivated
- // (completed/failed/aborted) first.
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID,
- base::nullopt /* registration */);
- Finished(); // Destroys |this|.
- return;
- case DatabaseStatus::kFailed:
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- base::nullopt /* registration */);
- Finished(); // Destroys |this|.
- return;
- }
- }
-
- void StoreRegistration() {
- int64_t registration_creation_microseconds_since_unix_epoch =
- (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds();
-
- std::vector<std::pair<std::string, std::string>> entries;
- entries.reserve(requests_.size() * 2 + 1);
-
- // First serialize per-registration (as opposed to per-request) data.
- // TODO(crbug.com/757760): Serialize BackgroundFetchOptions as part of this.
- proto::BackgroundFetchRegistration registration_proto;
- registration_proto.set_creation_microseconds_since_unix_epoch(
- registration_creation_microseconds_since_unix_epoch);
- std::string serialized_registration_proto;
- if (!registration_proto.SerializeToString(&serialized_registration_proto)) {
- // TODO(johnme): Log failures to UMA.
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- base::nullopt /* registration */);
- Finished(); // Destroys |this|.
- return;
- }
- entries.emplace_back(
- RegistrationDeveloperIdToUniqueIdKey(registration_id_.developer_id()),
- registration_id_.unique_id());
- entries.emplace_back(RegistrationKey(registration_id_),
- std::move(serialized_registration_proto));
-
- // Signed integers are used for request indexes to avoid unsigned gotchas.
- for (int i = 0; i < base::checked_cast<int>(requests_.size()); i++) {
- // TODO(crbug.com/757760): Serialize actual values for these entries.
- entries.emplace_back(RequestKey(registration_id_, i),
- "TODO: Serialize FetchAPIRequest as value");
- entries.emplace_back(
- PendingRequestKey(registration_creation_microseconds_since_unix_epoch,
- registration_id_, i),
- std::string());
- }
-
- service_worker_context()->StoreRegistrationUserData(
- registration_id_.service_worker_registration_id(),
- registration_id_.origin().GetURL(), entries,
- base::Bind(&CreateRegistrationTask::DidStoreRegistration,
- weak_factory_.GetWeakPtr()));
- }
-
- void DidStoreRegistration(ServiceWorkerStatusCode status) {
- switch (ToDatabaseStatus(status)) {
- case DatabaseStatus::kOk:
- break;
- case DatabaseStatus::kFailed:
- case DatabaseStatus::kNotFound:
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- base::nullopt /* registration */);
- Finished(); // Destroys |this|.
- return;
- }
-
- BackgroundFetchRegistration registration;
- registration.developer_id = registration_id_.developer_id();
- registration.unique_id = registration_id_.unique_id();
- registration.icons = options_.icons;
- registration.title = options_.title;
- // TODO(crbug.com/774054): Uploads are not yet supported.
- registration.upload_total = 0;
- registration.uploaded = 0;
- registration.download_total = options_.download_total;
- registration.downloaded = 0;
-
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE,
- std::move(registration));
- Finished(); // Destroys |this|.
- }
-
- BackgroundFetchRegistrationId registration_id_;
- std::vector<ServiceWorkerFetchRequest> requests_;
- BackgroundFetchOptions options_;
- blink::mojom::BackgroundFetchService::FetchCallback callback_;
-
- base::WeakPtrFactory<CreateRegistrationTask> weak_factory_; // Keep as last.
-
- DISALLOW_COPY_AND_ASSIGN(CreateRegistrationTask);
-};
-
-class DeleteRegistrationTask : public BackgroundFetchDataManager::DatabaseTask {
- public:
- DeleteRegistrationTask(
- BackgroundFetchDataManager* data_manager,
- const BackgroundFetchRegistrationId& registration_id,
- BackgroundFetchDataManager::DeleteRegistrationCallback callback)
- : DatabaseTask(data_manager),
- registration_id_(registration_id),
- callback_(std::move(callback)),
- weak_factory_(this) {}
-
- ~DeleteRegistrationTask() override = default;
-
- void Start() override {
- // Get the registration creation time so we can delete any pending requests.
- service_worker_context()->GetRegistrationUserData(
- registration_id_.service_worker_registration_id(),
- {RegistrationKey(registration_id_)},
- base::Bind(&DeleteRegistrationTask::DidGetRegistration,
- weak_factory_.GetWeakPtr()));
- }
-
- private:
- void DidGetRegistration(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
- // TODO(crbug.com/757760): In future removing the
- // RegistrationDeveloperIdToUniqueIdKey and RegistrationKey will happen
- // separately, since registration data must persist for as long as
- // JavaScript retains a reference to it, even once completed/failed/aborted.
- std::vector<std::string> prefixes_to_clear = {
- RegistrationDeveloperIdToUniqueIdKey(registration_id_.developer_id()),
- RegistrationKey(registration_id_), RequestKeyPrefix(registration_id_)};
-
- if (status == SERVICE_WORKER_OK) {
- DCHECK_EQ(1u, data.size());
- proto::BackgroundFetchRegistration registration_proto;
- if (registration_proto.ParseFromString(data[0]) &&
- registration_proto.has_creation_microseconds_since_unix_epoch()) {
- prefixes_to_clear.emplace_back(PendingRequestKeyPrefix(
- registration_proto.creation_microseconds_since_unix_epoch(),
- registration_id_));
- }
- }
-
- service_worker_context()->ClearRegistrationUserDataByKeyPrefixes(
- registration_id_.service_worker_registration_id(), prefixes_to_clear,
- base::Bind(&DeleteRegistrationTask::DidDeleteRegistration,
- weak_factory_.GetWeakPtr()));
- }
-
- void DidDeleteRegistration(ServiceWorkerStatusCode status) {
- switch (ToDatabaseStatus(status)) {
- case DatabaseStatus::kOk:
- case DatabaseStatus::kNotFound:
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE);
- Finished(); // Destroys |this|.
- return;
- case DatabaseStatus::kFailed:
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR);
- Finished(); // Destroys |this|.
- return;
- }
- }
-
- BackgroundFetchRegistrationId registration_id_;
- BackgroundFetchDataManager::DeleteRegistrationCallback callback_;
-
- base::WeakPtrFactory<DeleteRegistrationTask> weak_factory_; // Keep as last.
-
- DISALLOW_COPY_AND_ASSIGN(DeleteRegistrationTask);
-};
-
-} // namespace
-
// The Registration Data class encapsulates the data stored for a particular
// Background Fetch registration. This roughly matches the on-disk format that
// will be adhered to in the future.
class BackgroundFetchDataManager::RegistrationData {
public:
- RegistrationData(const std::vector<ServiceWorkerFetchRequest>& requests,
+ RegistrationData(const BackgroundFetchRegistrationId& registration_id,
+ const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options)
- : options_(options) {
+ : registration_id_(registration_id), options_(options) {
int request_index = 0;
// Convert the given |requests| to BackgroundFetchRequestInfo objects.
@@ -462,6 +74,8 @@ class BackgroundFetchDataManager::RegistrationData {
auto request = pending_requests_.front();
pending_requests_.pop();
+ request->InitializeDownloadGuid();
+
// The |request| is considered to be active now.
active_requests_.push_back(request);
@@ -513,15 +127,24 @@ class BackgroundFetchDataManager::RegistrationData {
void SetTitle(const std::string& title) { options_.title = title; }
+ const BackgroundFetchRegistrationId& registration_id() const {
+ return registration_id_;
+ }
+
const BackgroundFetchOptions& options() const { return options_; }
- uint64_t GetDownloaded(Controller* controller) {
- return complete_requests_downloaded_bytes_ +
- (controller ? controller->GetInProgressDownloadedBytes() : 0);
+ uint64_t GetDownloaded() const { return complete_requests_downloaded_bytes_; }
+
+ int GetTotalNumberOfRequests() const {
+ return pending_requests_.size() + active_requests_.size() +
+ completed_requests_.size();
}
private:
+ BackgroundFetchRegistrationId registration_id_;
BackgroundFetchOptions options_;
+ // Number of bytes downloaded as part of completed downloads. (In-progress
+ // downloads are tracked elsewhere).
uint64_t complete_requests_downloaded_bytes_ = 0;
base::queue<scoped_refptr<BackgroundFetchRequestInfo>> pending_requests_;
@@ -550,34 +173,36 @@ BackgroundFetchDataManager::BackgroundFetchDataManager(
blob_storage_context_ =
base::WrapRefCounted(ChromeBlobStorageContext::GetFor(browser_context));
DCHECK(blob_storage_context_);
-}
-BackgroundFetchDataManager::~BackgroundFetchDataManager() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ BrowserThread::PostAfterStartupTask(
+ FROM_HERE, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ // Normally weak pointers must be obtained on the IO thread, but it's ok
+ // here as the factory cannot be destroyed before the constructor ends.
+ base::Bind(&BackgroundFetchDataManager::Cleanup,
+ weak_ptr_factory_.GetWeakPtr()));
}
-void BackgroundFetchDataManager::SetController(
- const BackgroundFetchRegistrationId& registration_id,
- Controller* controller) {
- if (controller) {
- DCHECK_EQ(0u, controllers_.count(registration_id.unique_id()));
- controllers_.emplace(registration_id.unique_id(), controller);
- } else {
- DCHECK_EQ(1u, controllers_.count(registration_id.unique_id()));
- controllers_.erase(registration_id.unique_id());
+void BackgroundFetchDataManager::Cleanup() {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBackgroundFetchPersistence)) {
+ AddDatabaseTask(std::make_unique<background_fetch::CleanupTask>(this));
}
}
+BackgroundFetchDataManager::~BackgroundFetchDataManager() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+}
+
void BackgroundFetchDataManager::CreateRegistration(
const BackgroundFetchRegistrationId& registration_id,
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
- blink::mojom::BackgroundFetchService::FetchCallback callback) {
+ GetRegistrationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
- AddDatabaseTask(std::make_unique<CreateRegistrationTask>(
+ AddDatabaseTask(std::make_unique<background_fetch::CreateRegistrationTask>(
this, registration_id, requests, options, std::move(callback)));
return;
}
@@ -589,21 +214,21 @@ void BackgroundFetchDataManager::CreateRegistration(
std::make_tuple(registration_id.service_worker_registration_id(),
registration_id.origin(), registration_id.developer_id());
- if (active_unique_ids_.count(developer_id_tuple)) {
+ if (active_registration_unique_ids_.count(developer_id_tuple)) {
std::move(callback).Run(
- blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID,
- base::nullopt);
+ blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID, nullptr);
return;
}
// Mark |unique_id| as the currently active registration for
// |developer_id_tuple|.
- active_unique_ids_.emplace(std::move(developer_id_tuple),
- registration_id.unique_id());
+ active_registration_unique_ids_.emplace(std::move(developer_id_tuple),
+ registration_id.unique_id());
// Create the |RegistrationData|, and store it for easy access.
- registrations_.emplace(registration_id.unique_id(),
- std::make_unique<RegistrationData>(requests, options));
+ registrations_.emplace(
+ registration_id.unique_id(),
+ std::make_unique<RegistrationData>(registration_id, requests, options));
// Re-use GetRegistration to compile the BackgroundFetchRegistration object.
// WARNING: GetRegistration doesn't use the |unique_id| when looking up the
@@ -619,16 +244,24 @@ void BackgroundFetchDataManager::GetRegistration(
int64_t service_worker_registration_id,
const url::Origin& origin,
const std::string& developer_id,
- blink::mojom::BackgroundFetchService::GetRegistrationCallback callback) {
+ GetRegistrationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBackgroundFetchPersistence)) {
+ AddDatabaseTask(std::make_unique<background_fetch::GetRegistrationTask>(
+ this, service_worker_registration_id, origin, developer_id,
+ std::move(callback)));
+ return;
+ }
+
auto developer_id_tuple =
std::make_tuple(service_worker_registration_id, origin, developer_id);
- auto iter = active_unique_ids_.find(developer_id_tuple);
- if (iter == active_unique_ids_.end()) {
+ auto iter = active_registration_unique_ids_.find(developer_id_tuple);
+ if (iter == active_registration_unique_ids_.end()) {
std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_ID,
- base::nullopt /* registration */);
+ nullptr /* registration */);
return;
}
@@ -637,25 +270,18 @@ void BackgroundFetchDataManager::GetRegistration(
DCHECK_EQ(1u, registrations_.count(unique_id));
RegistrationData* data = registrations_[unique_id].get();
- auto controllers_iter = controllers_.find(unique_id);
- Controller* controller = controllers_iter != controllers_.end()
- ? controllers_iter->second
- : nullptr;
-
// Compile the BackgroundFetchRegistration object for the developer.
- BackgroundFetchRegistration registration;
- registration.developer_id = developer_id;
- registration.unique_id = unique_id;
- registration.icons = data->options().icons;
- registration.title = data->options().title;
+ auto registration = std::make_unique<BackgroundFetchRegistration>();
+ registration->developer_id = developer_id;
+ registration->unique_id = unique_id;
// TODO(crbug.com/774054): Uploads are not yet supported.
- registration.upload_total = 0;
- registration.uploaded = 0;
- registration.download_total = data->options().download_total;
- registration.downloaded = data->GetDownloaded(controller);
+ registration->upload_total = 0;
+ registration->uploaded = 0;
+ registration->download_total = data->options().download_total;
+ registration->downloaded = data->GetDownloaded();
std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE,
- registration);
+ std::move(registration));
}
void BackgroundFetchDataManager::UpdateRegistrationUI(
@@ -673,11 +299,6 @@ void BackgroundFetchDataManager::UpdateRegistrationUI(
// Update stored registration.
registrations_iter->second->SetTitle(title);
- // Update any active JobController that cached this data for notifications.
- auto controllers_iter = controllers_.find(unique_id);
- if (controllers_iter != controllers_.end())
- controllers_iter->second->UpdateUI(title);
-
std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE);
}
@@ -686,10 +307,16 @@ void BackgroundFetchDataManager::PopNextRequest(
NextRequestCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- auto iter = registrations_.find(registration_id.unique_id());
- DCHECK(iter != registrations_.end());
+ if (!IsActive(registration_id)) {
+ // Stop giving out requests as registration aborted (or otherwise finished).
+ std::move(callback).Run(nullptr /* request */);
+ return;
+ }
- RegistrationData* registration_data = iter->second.get();
+ auto registration_iter = registrations_.find(registration_id.unique_id());
+ DCHECK(registration_iter != registrations_.end());
+
+ RegistrationData* registration_data = registration_iter->second.get();
scoped_refptr<BackgroundFetchRequestInfo> next_request;
if (registration_data->HasPendingRequests())
@@ -746,7 +373,7 @@ void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
std::vector<BackgroundFetchSettledFetch> settled_fetches;
settled_fetches.reserve(requests.size());
- std::vector<std::unique_ptr<BlobHandle>> blob_handles;
+ std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles;
for (const auto& request : requests) {
BackgroundFetchSettledFetch settled_fetch;
@@ -770,17 +397,32 @@ void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
if (request->GetFileSize() > 0) {
DCHECK(!request->GetFilePath().empty());
- std::unique_ptr<BlobHandle> blob_handle =
- blob_storage_context_->CreateFileBackedBlob(
- request->GetFilePath(), 0 /* offset */, request->GetFileSize(),
- base::Time() /* expected_modification_time */);
-
- // TODO(peter): Appropriately handle !blob_handle
- if (blob_handle) {
- settled_fetch.response.blob_uuid = blob_handle->GetUUID();
- settled_fetch.response.blob_size = request->GetFileSize();
-
- blob_handles.push_back(std::move(blob_handle));
+ DCHECK(blob_storage_context_);
+
+ storage::BlobDataBuilder blob_builder(base::GenerateGUID());
+ blob_builder.AppendFile(request->GetFilePath(), 0 /* offset */,
+ request->GetFileSize(),
+ base::Time() /* expected_modification_time */);
+
+ auto blob_data_handle =
+ GetBlobStorageContext(blob_storage_context_.get())
+ ->AddFinishedBlob(&blob_builder);
+
+ // TODO(peter): Appropriately handle !blob_data_handle
+ if (blob_data_handle) {
+ settled_fetch.response.blob_uuid = blob_data_handle->uuid();
+ settled_fetch.response.blob_size = blob_data_handle->size();
+ if (features::IsMojoBlobsEnabled()) {
+ blink::mojom::BlobPtr blob_ptr;
+ storage::BlobImpl::Create(
+ std::make_unique<storage::BlobDataHandle>(*blob_data_handle),
+ MakeRequest(&blob_ptr));
+
+ settled_fetch.response.blob =
+ base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr));
+ }
+
+ blob_data_handles.push_back(std::move(blob_data_handle));
}
}
} else {
@@ -789,70 +431,139 @@ void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
background_fetch_succeeded = false;
}
- // TODO: settled_fetch.response.error
+ // TODO(delphick): settled_fetch.response.error
settled_fetch.response.response_time = request->GetResponseTime();
- // TODO: settled_fetch.response.cors_exposed_header_names
+ // TODO(delphick): settled_fetch.response.cors_exposed_header_names
background_fetch_succeeded = background_fetch_succeeded && IsOK(*request);
settled_fetches.push_back(settled_fetch);
}
- std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE,
- background_fetch_succeeded,
- std::move(settled_fetches), std::move(blob_handles));
+ std::move(callback).Run(
+ blink::mojom::BackgroundFetchError::NONE, background_fetch_succeeded,
+ std::move(settled_fetches), std::move(blob_data_handles));
}
-void BackgroundFetchDataManager::DeleteRegistration(
+void BackgroundFetchDataManager::MarkRegistrationForDeletion(
const BackgroundFetchRegistrationId& registration_id,
- DeleteRegistrationCallback callback) {
+ HandleBackgroundFetchErrorCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
- AddDatabaseTask(std::make_unique<DeleteRegistrationTask>(
- this, registration_id, std::move(callback)));
+ AddDatabaseTask(
+ std::make_unique<background_fetch::MarkRegistrationForDeletionTask>(
+ this, registration_id, std::move(callback)));
return;
}
- // TODO(crbug.com/757760): In future removing entries from
- // active_unique_ids_ and from registrations_ will happen separately,
- // since entries in registrations_ must persist for as long as JavaScript
- // retains a reference to them, even once completed/failed/aborted.
+ auto developer_id_tuple =
+ std::make_tuple(registration_id.service_worker_registration_id(),
+ registration_id.origin(), registration_id.developer_id());
+
+ auto active_unique_id_iter =
+ active_registration_unique_ids_.find(developer_id_tuple);
- if (!registrations_.erase(registration_id.unique_id())) {
+ // The |unique_id| must also match, as a website can create multiple
+ // registrations with the same |developer_id_tuple| (even though only one can
+ // be active at once).
+ if (active_unique_id_iter == active_registration_unique_ids_.end() ||
+ active_unique_id_iter->second != registration_id.unique_id()) {
std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_ID);
return;
}
- auto developer_id_tuple =
- std::make_tuple(registration_id.service_worker_registration_id(),
- registration_id.origin(), registration_id.developer_id());
- active_unique_ids_.erase(developer_id_tuple);
+ active_registration_unique_ids_.erase(active_unique_id_iter);
std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE);
}
+void BackgroundFetchDataManager::DeleteRegistration(
+ const BackgroundFetchRegistrationId& registration_id,
+ HandleBackgroundFetchErrorCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBackgroundFetchPersistence)) {
+ AddDatabaseTask(std::make_unique<background_fetch::DeleteRegistrationTask>(
+ this, registration_id.service_worker_registration_id(),
+ registration_id.unique_id(), std::move(callback)));
+ return;
+ }
+
+ DCHECK(!IsActive(registration_id))
+ << "MarkRegistrationForDeletion must already have been called";
+
+ std::move(callback).Run(registrations_.erase(registration_id.unique_id())
+ ? blink::mojom::BackgroundFetchError::NONE
+ : blink::mojom::BackgroundFetchError::INVALID_ID);
+}
+
void BackgroundFetchDataManager::GetDeveloperIdsForServiceWorker(
int64_t service_worker_registration_id,
+ const url::Origin& origin,
blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBackgroundFetchPersistence)) {
+ AddDatabaseTask(std::make_unique<background_fetch::GetDeveloperIdsTask>(
+ this, service_worker_registration_id, origin, std::move(callback)));
+ return;
+ }
+
std::vector<std::string> developer_ids;
- for (const auto& entry : active_unique_ids_) {
- if (service_worker_registration_id == std::get<0>(entry.first))
+ for (const auto& entry : active_registration_unique_ids_) {
+ if (service_worker_registration_id == std::get<0>(entry.first) &&
+ origin == std::get<1>(entry.first)) {
developer_ids.emplace_back(std::get<2>(entry.first));
+ }
}
std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE,
developer_ids);
}
+int BackgroundFetchDataManager::GetTotalNumberOfRequests(
+ const BackgroundFetchRegistrationId& registration_id) const {
+ return registrations_.find(registration_id.unique_id())
+ ->second->GetTotalNumberOfRequests();
+}
+
+bool BackgroundFetchDataManager::IsActive(
+ const BackgroundFetchRegistrationId& registration_id) {
+ auto developer_id_tuple =
+ std::make_tuple(registration_id.service_worker_registration_id(),
+ registration_id.origin(), registration_id.developer_id());
+
+ auto active_unique_id_iter =
+ active_registration_unique_ids_.find(developer_id_tuple);
+
+ // The |unique_id| must also match, as a website can create multiple
+ // registrations with the same |developer_id_tuple| (even though only one can
+ // be active at once).
+ return active_unique_id_iter != active_registration_unique_ids_.end() &&
+ active_unique_id_iter->second == registration_id.unique_id();
+}
+
void BackgroundFetchDataManager::AddDatabaseTask(
- std::unique_ptr<DatabaseTask> task) {
+ std::unique_ptr<background_fetch::DatabaseTask> task) {
database_tasks_.push(std::move(task));
if (database_tasks_.size() == 1)
- database_tasks_.front()->Run();
+ database_tasks_.front()->Start();
+}
+
+void BackgroundFetchDataManager::OnDatabaseTaskFinished(
+ background_fetch::DatabaseTask* task) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ DCHECK(!database_tasks_.empty());
+ DCHECK_EQ(database_tasks_.front().get(), task);
+
+ database_tasks_.pop();
+ if (!database_tasks_.empty())
+ database_tasks_.front()->Start();
}
} // namespace content
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 43d22a8f920..c901b40774c 100644
--- a/chromium/content/browser/background_fetch/background_fetch_data_manager.h
+++ b/chromium/content/browser/background_fetch/background_fetch_data_manager.h
@@ -7,24 +7,30 @@
#include <map>
#include <memory>
+#include <set>
#include <string>
#include <tuple>
+#include <vector>
#include "base/callback_forward.h"
-#include "base/containers/flat_map.h"
#include "base/containers/queue.h"
+#include "base/gtest_prod_util.h"
#include "base/macros.h"
-#include "base/optional.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
+#include "content/browser/background_fetch/background_fetch_request_manager.h"
+#include "content/browser/background_fetch/storage/database_task.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h"
#include "url/origin.h"
+namespace storage {
+class BlobDataHandle;
+}
+
namespace content {
class BackgroundFetchRequestInfo;
struct BackgroundFetchSettledFetch;
-class BlobHandle;
class BrowserContext;
class ChromeBlobStorageContext;
class ServiceWorkerContextWrapper;
@@ -39,44 +45,23 @@ class ServiceWorkerContextWrapper;
// Service Worker database (except for deletions, e.g. it's safe for the Service
// Worker code to remove a ServiceWorkerRegistration and all its keys).
//
-// Storage schema is documented in the .cc file.
-class CONTENT_EXPORT BackgroundFetchDataManager {
+// Storage schema is documented in storage/README.md
+class CONTENT_EXPORT BackgroundFetchDataManager
+ : public BackgroundFetchRequestManager {
public:
- using DeleteRegistrationCallback =
- base::OnceCallback<void(blink::mojom::BackgroundFetchError)>;
- using NextRequestCallback =
- base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>;
- using MarkedCompleteCallback =
- base::OnceCallback<void(bool /* has_pending_or_active_requests */)>;
- using SettledFetchesCallback =
+ using SettledFetchesCallback = base::OnceCallback<void(
+ blink::mojom::BackgroundFetchError,
+ bool /* background_fetch_succeeded */,
+ std::vector<BackgroundFetchSettledFetch>,
+ std::vector<std::unique_ptr<storage::BlobDataHandle>>)>;
+ using GetRegistrationCallback =
base::OnceCallback<void(blink::mojom::BackgroundFetchError,
- bool /* background_fetch_succeeded */,
- std::vector<BackgroundFetchSettledFetch>,
- std::vector<std::unique_ptr<BlobHandle>>)>;
-
- class DatabaseTask;
-
- class Controller {
- public:
- virtual ~Controller() {}
-
- // Called once UpdateRegistrationUI has been persisted to the database.
- virtual void UpdateUI(const std::string& title) = 0;
-
- // Should return the sum of the bytes downloaded by in progress requests.
- virtual uint64_t GetInProgressDownloadedBytes() = 0;
- };
+ std::unique_ptr<BackgroundFetchRegistration>)>;
BackgroundFetchDataManager(
BrowserContext* browser_context,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
- ~BackgroundFetchDataManager();
-
- // Sets the JobController that handles in-progress requests for a
- // registration, and will be notified of relevant changes to the registration
- // data. Must outlive |this| or call SetController(nullptr) in its destructor.
- void SetController(const BackgroundFetchRegistrationId& registration_id,
- Controller* controller);
+ ~BackgroundFetchDataManager() override;
// Creates and stores a new registration with the given properties. Will
// invoke the |callback| when the registration has been created, which may
@@ -85,14 +70,13 @@ class CONTENT_EXPORT BackgroundFetchDataManager {
const BackgroundFetchRegistrationId& registration_id,
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
- blink::mojom::BackgroundFetchService::FetchCallback callback);
+ GetRegistrationCallback callback);
// Get the BackgroundFetchOptions for a registration.
- void GetRegistration(
- int64_t service_worker_registration_id,
- const url::Origin& origin,
- const std::string& developer_id,
- blink::mojom::BackgroundFetchService::GetRegistrationCallback callback);
+ void GetRegistration(int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ const std::string& developer_id,
+ GetRegistrationCallback callback);
// Updates the UI values for a Background Fetch registration.
void UpdateRegistrationUI(
@@ -100,25 +84,6 @@ class CONTENT_EXPORT BackgroundFetchDataManager {
const std::string& title,
blink::mojom::BackgroundFetchService::UpdateUICallback callback);
- // Removes the next request, if any, from the pending requests queue, and
- // invokes the |callback| with that request, else a null request.
- void PopNextRequest(const BackgroundFetchRegistrationId& registration_id,
- NextRequestCallback callback);
-
- // Marks that the |request|, part of the Background Fetch identified by
- // |registration_id|, has been started as |download_guid|.
- void MarkRequestAsStarted(
- const BackgroundFetchRegistrationId& registration_id,
- BackgroundFetchRequestInfo* request,
- const std::string& download_guid);
-
- // Marks that the |request|, part of the Background Fetch identified by
- // |registration_id|, has completed.
- void MarkRequestAsComplete(
- const BackgroundFetchRegistrationId& registration_id,
- BackgroundFetchRequestInfo* request,
- MarkedCompleteCallback callback);
-
// Reads all settled fetches for the given |registration_id|. Both the Request
// and Response objects will be initialised based on the stored data. Will
// invoke the |callback| when the list of fetches has been compiled.
@@ -126,23 +91,64 @@ class CONTENT_EXPORT BackgroundFetchDataManager {
const BackgroundFetchRegistrationId& registration_id,
SettledFetchesCallback callback);
- // Deletes the registration identified by |registration_id|. Will invoke the
- // |callback| when the registration has been deleted from storage.
+ // Marks that the backgroundfetched/backgroundfetchfail/backgroundfetchabort
+ // event is being dispatched. It's not possible to call DeleteRegistration at
+ // this point as JavaScript may hold a reference to a
+ // BackgroundFetchRegistration object and we need to keep the corresponding
+ // data around until the last such reference is released (or until shutdown).
+ // We can't just move the Background Fetch registration's data to RAM as it
+ // might consume too much memory. So instead this step disassociates the
+ // |developer_id| from the |unique_id|, so that existing JS objects with a
+ // reference to |unique_id| can still access the data, but it can no longer be
+ // reached using GetIds or GetRegistration.
+ void MarkRegistrationForDeletion(
+ const BackgroundFetchRegistrationId& registration_id,
+ HandleBackgroundFetchErrorCallback callback);
+
+ // Deletes the registration identified by |registration_id|. Should only be
+ // called once the refcount of JavaScript BackgroundFetchRegistration objects
+ // referring to this registration drops to zero. Will invoke the |callback|
+ // when the registration has been deleted from storage.
void DeleteRegistration(const BackgroundFetchRegistrationId& registration_id,
- DeleteRegistrationCallback callback);
+ HandleBackgroundFetchErrorCallback callback);
// List all Background Fetch registration |developer_id|s for a Service
// Worker.
void GetDeveloperIdsForServiceWorker(
int64_t service_worker_registration_id,
+ const url::Origin& origin,
blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback);
+ int GetTotalNumberOfRequests(
+ const BackgroundFetchRegistrationId& registration_id) const;
+
+ // BackgroundFetchRequestManager implementation:
+ void PopNextRequest(const BackgroundFetchRegistrationId& registration_id,
+ NextRequestCallback callback) override;
+ void MarkRequestAsStarted(
+ const BackgroundFetchRegistrationId& registration_id,
+ BackgroundFetchRequestInfo* request,
+ const std::string& download_guid) override;
+ void MarkRequestAsComplete(
+ const BackgroundFetchRegistrationId& registration_id,
+ BackgroundFetchRequestInfo* request,
+ MarkedCompleteCallback callback) override;
+
private:
+ FRIEND_TEST_ALL_PREFIXES(BackgroundFetchDataManagerTest, Cleanup);
friend class BackgroundFetchDataManagerTest;
+ friend class background_fetch::DatabaseTask;
class RegistrationData;
- void AddDatabaseTask(std::unique_ptr<DatabaseTask> task);
+ void AddDatabaseTask(std::unique_ptr<background_fetch::DatabaseTask> task);
+
+ void OnDatabaseTaskFinished(background_fetch::DatabaseTask* task);
+
+ // Returns true if not aborted/completed/failed.
+ bool IsActive(const BackgroundFetchRegistrationId& registration_id);
+
+ void Cleanup();
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
@@ -154,19 +160,21 @@ class CONTENT_EXPORT BackgroundFetchDataManager {
// completed/failed/aborted, so there will never be more than one entry for a
// given key).
std::map<std::tuple<int64_t, url::Origin, std::string>, std::string>
- active_unique_ids_;
+ active_registration_unique_ids_;
// Map from the |unique_id|s of known (but possibly inactive) background fetch
// registrations to their associated data.
std::map<std::string, std::unique_ptr<RegistrationData>> registrations_;
- // Map from background fetch registration |unique_id|s to the controller that
- // needs to be notified about changes to the registration.
- base::flat_map<std::string, Controller*> controllers_;
-
// Pending database operations, serialized to ensure consistency.
// Invariant: the frontmost task, if any, has already been started.
- base::queue<std::unique_ptr<DatabaseTask>> database_tasks_;
+ base::queue<std::unique_ptr<background_fetch::DatabaseTask>> database_tasks_;
+
+ // The |unique_id|s of registrations that have been deactivated since the
+ // browser was last started. They will be automatically deleted when the
+ // refcount of JavaScript objects that refers to them goes to zero, unless
+ // the browser is shutdown first.
+ std::set<std::string> ref_counted_unique_ids_;
base::WeakPtrFactory<BackgroundFetchDataManager> weak_ptr_factory_;
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 4291be8ed60..1c9f5c0a295 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
@@ -6,6 +6,8 @@
#include <memory>
#include <string>
+#include <utility>
+#include <vector>
#include "base/barrier_closure.h"
#include "base/bind_helpers.h"
@@ -16,37 +18,90 @@
#include "base/run_loop.h"
#include "content/browser/background_fetch/background_fetch_request_info.h"
#include "content/browser/background_fetch/background_fetch_test_base.h"
+#include "content/browser/background_fetch/storage/database_helpers.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
+#include "testing/gmock/include/gmock/gmock.h"
namespace content {
namespace {
+using ::testing::UnorderedElementsAre;
+using ::testing::IsEmpty;
+
+enum class BackgroundFetchRegistrationStorage { kPersistent, kNonPersistent };
+
+const char kUserDataPrefix[] = "bgfetch_";
+
const char kExampleDeveloperId[] = "my-example-id";
+const char kAlternativeDeveloperId[] = "my-other-id";
const char kExampleUniqueId[] = "7e57ab1e-c0de-a150-ca75-1e75f005ba11";
const char kAlternativeUniqueId[] = "bb48a9fb-c21f-4c2d-a9ae-58bd48a9fb53";
-// A "bgfetch_registration_developer_id_to_unique_id_" and
-// "bgfetch_registration_" per registration (not including keys for requests).
-const size_t kUserDataKeysPerRegistration = 2u;
-// A "bgfetch_request_" and "bgfetch_pending_request_" per request. See schema
-// documentation in background_fetch_data_manager.cc.
-const size_t kUserDataKeysPerRequest = 2u;
+// See schema documentation in background_fetch_data_manager.cc.
+// A "bgfetch_registration_" per registration (not including keys for requests).
+constexpr size_t kUserDataKeysPerInactiveRegistration = 1u;
+
+// A "bgfetch_request_" per request.
+constexpr size_t kUserDataKeysPerInactiveRequest = 1u;
+
+void DidCreateRegistration(
+ base::Closure quit_closure,
+ blink::mojom::BackgroundFetchError* out_error,
+ blink::mojom::BackgroundFetchError error,
+ std::unique_ptr<BackgroundFetchRegistration> registration) {
+ *out_error = error;
+ quit_closure.Run();
+}
+
+void DidGetError(base::Closure quit_closure,
+ blink::mojom::BackgroundFetchError* out_error,
+ blink::mojom::BackgroundFetchError error) {
+ *out_error = error;
+ quit_closure.Run();
+}
+
+void DidGetRegistrationUserDataByKeyPrefix(base::Closure quit_closure,
+ std::vector<std::string>* out_data,
+ const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status) {
+ DCHECK(out_data);
+ DCHECK_EQ(SERVICE_WORKER_OK, status);
+ *out_data = data;
+ quit_closure.Run();
+}
} // namespace
-class BackgroundFetchDataManagerTest : public BackgroundFetchTestBase {
+class BackgroundFetchDataManagerTest
+ : public BackgroundFetchTestBase,
+ public ::testing::WithParamInterface<BackgroundFetchRegistrationStorage> {
public:
BackgroundFetchDataManagerTest() {
+ registration_storage_ = GetParam();
+ if (registration_storage_ ==
+ BackgroundFetchRegistrationStorage::kPersistent) {
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableBackgroundFetchPersistence);
+ }
RestartDataManagerFromPersistentStorage();
}
+
~BackgroundFetchDataManagerTest() override = default;
// Re-creates the data manager. Useful for testing that data was persisted.
+ // If the test is non-persistent mode (e.g. testing the old code path), then
+ // this does nothing after the first call.
void RestartDataManagerFromPersistentStorage() {
+ if (registration_storage_ ==
+ BackgroundFetchRegistrationStorage::kNonPersistent &&
+ background_fetch_data_manager_) {
+ return;
+ }
+
background_fetch_data_manager_ =
- base::MakeUnique<BackgroundFetchDataManager>(
+ std::make_unique<BackgroundFetchDataManager>(
browser_context(),
embedded_worker_test_helper()->context_wrapper());
}
@@ -62,12 +117,62 @@ class BackgroundFetchDataManagerTest : public BackgroundFetchTestBase {
base::RunLoop run_loop;
background_fetch_data_manager_->CreateRegistration(
registration_id, requests, options,
- base::BindOnce(&BackgroundFetchDataManagerTest::DidCreateRegistration,
- base::Unretained(this), run_loop.QuitClosure(),
+ base::BindOnce(&DidCreateRegistration, run_loop.QuitClosure(),
out_error));
run_loop.Run();
}
+ std::unique_ptr<BackgroundFetchRegistration> GetRegistration(
+ int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ const std::string developer_id,
+ blink::mojom::BackgroundFetchError* out_error) {
+ DCHECK(out_error);
+
+ std::unique_ptr<BackgroundFetchRegistration> registration;
+ base::RunLoop run_loop;
+ background_fetch_data_manager_->GetRegistration(
+ service_worker_registration_id, origin, developer_id,
+ base::BindOnce(&BackgroundFetchDataManagerTest::DidGetRegistration,
+ base::Unretained(this), run_loop.QuitClosure(),
+ out_error, &registration));
+ run_loop.Run();
+
+ return registration;
+ }
+
+ std::vector<std::string> GetDeveloperIds(
+ int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ blink::mojom::BackgroundFetchError* out_error) {
+ DCHECK(out_error);
+
+ std::vector<std::string> ids;
+ base::RunLoop run_loop;
+ background_fetch_data_manager_->GetDeveloperIdsForServiceWorker(
+ service_worker_registration_id, origin,
+ base::BindOnce(&BackgroundFetchDataManagerTest::DidGetDeveloperIds,
+ base::Unretained(this), run_loop.QuitClosure(),
+ out_error, &ids));
+ run_loop.Run();
+
+ return ids;
+ }
+
+ // Synchronous version of
+ // BackgroundFetchDataManager::MarkRegistrationForDeletion().
+ void MarkRegistrationForDeletion(
+ const BackgroundFetchRegistrationId& registration_id,
+ blink::mojom::BackgroundFetchError* out_error) {
+ DCHECK(out_error);
+
+ base::RunLoop run_loop;
+ background_fetch_data_manager_->MarkRegistrationForDeletion(
+ registration_id,
+ base::BindOnce(&DidGetError, run_loop.QuitClosure(), out_error));
+ run_loop.Run();
+ }
+
// Synchronous version of BackgroundFetchDataManager::DeleteRegistration().
void DeleteRegistration(const BackgroundFetchRegistrationId& registration_id,
blink::mojom::BackgroundFetchError* out_error) {
@@ -76,9 +181,7 @@ class BackgroundFetchDataManagerTest : public BackgroundFetchTestBase {
base::RunLoop run_loop;
background_fetch_data_manager_->DeleteRegistration(
registration_id,
- base::BindOnce(&BackgroundFetchDataManagerTest::DidDeleteRegistration,
- base::Unretained(this), run_loop.QuitClosure(),
- out_error));
+ base::BindOnce(&DidGetError, run_loop.QuitClosure(), out_error));
run_loop.Run();
}
@@ -94,51 +197,58 @@ class BackgroundFetchDataManagerTest : public BackgroundFetchTestBase {
->context_wrapper()
->GetRegistrationUserDataByKeyPrefix(
service_worker_registration_id, key_prefix,
- base::Bind(&BackgroundFetchDataManagerTest::
- DidGetRegistrationUserDataByKeyPrefix,
- base::Unretained(this), run_loop.QuitClosure(), &data));
+ base::Bind(&DidGetRegistrationUserDataByKeyPrefix,
+ run_loop.QuitClosure(), &data));
run_loop.Run();
return data;
}
- void DidCreateRegistration(
+ protected:
+ void DidGetRegistration(
base::Closure quit_closure,
blink::mojom::BackgroundFetchError* out_error,
+ std::unique_ptr<BackgroundFetchRegistration>* out_registration,
blink::mojom::BackgroundFetchError error,
- const base::Optional<BackgroundFetchRegistration>& registration) {
+ std::unique_ptr<BackgroundFetchRegistration> registration) {
+ if (error == blink::mojom::BackgroundFetchError::NONE) {
+ DCHECK(registration);
+ }
*out_error = error;
+ *out_registration = std::move(registration);
quit_closure.Run();
}
- void DidDeleteRegistration(base::Closure quit_closure,
- blink::mojom::BackgroundFetchError* out_error,
- blink::mojom::BackgroundFetchError error) {
+ void DidGetDeveloperIds(base::Closure quit_closure,
+ blink::mojom::BackgroundFetchError* out_error,
+ std::vector<std::string>* out_ids,
+ blink::mojom::BackgroundFetchError error,
+ const std::vector<std::string>& ids) {
*out_error = error;
+ *out_ids = ids;
quit_closure.Run();
}
- protected:
+ BackgroundFetchRegistrationStorage registration_storage_;
std::unique_ptr<BackgroundFetchDataManager> background_fetch_data_manager_;
-
- private:
- void DidGetRegistrationUserDataByKeyPrefix(
- base::Closure quit_closure,
- std::vector<std::string>* out_data,
- const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
- DCHECK(out_data);
- DCHECK_EQ(SERVICE_WORKER_OK, status);
- *out_data = data;
- quit_closure.Run();
- }
};
-TEST_F(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
+INSTANTIATE_TEST_CASE_P(
+ Persistent,
+ BackgroundFetchDataManagerTest,
+ ::testing::Values(BackgroundFetchRegistrationStorage::kPersistent));
+
+INSTANTIATE_TEST_CASE_P(
+ NonPersistent,
+ BackgroundFetchDataManagerTest,
+ ::testing::Values(BackgroundFetchRegistrationStorage::kNonPersistent));
+
+TEST_P(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
// Tests that the BackgroundFetchDataManager correctly rejects creating a
- // registration that's already known to the system.
+ // registration with a |developer_id| for which there is already an active
+ // registration.
int64_t service_worker_registration_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
@@ -153,8 +263,8 @@ TEST_F(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
blink::mojom::BackgroundFetchError error;
- // Deleting the not-yet-created registration should fail.
- DeleteRegistration(registration_id1, &error);
+ // Deactivating the not-yet-created registration should fail.
+ MarkRegistrationForDeletion(registration_id1, &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);
// Creating the initial registration should succeed.
@@ -172,46 +282,124 @@ TEST_F(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
CreateRegistration(registration_id2, requests, options, &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID);
- // Deleting the second registration that failed to be created should fail.
- DeleteRegistration(registration_id2, &error);
+ // Deactivating the second registration that failed to be created should fail.
+ MarkRegistrationForDeletion(registration_id2, &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);
- // Deleting the initial registration should succeed.
- DeleteRegistration(registration_id1, &error);
+ // Deactivating the initial registration should succeed.
+ MarkRegistrationForDeletion(registration_id1, &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- // And now registering the second registration should work fine.
+ // And now registering the second registration should work fine, since there
+ // is no longer an *active* registration with the same |developer_id|, even
+ // though the initial registration has not yet been deleted.
CreateRegistration(registration_id2, requests, options, &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
-TEST_F(BackgroundFetchDataManagerTest, CreateAndDeleteRegistrationPersisted) {
- // Tests that the BackgroundFetchDataManager persists created registrations to
- // the Service Worker DB.
+TEST_P(BackgroundFetchDataManagerTest, GetDeveloperIds) {
+ int64_t sw_id = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableBackgroundFetchPersistence);
+ std::vector<ServiceWorkerFetchRequest> requests(2u);
+ BackgroundFetchOptions options;
+ blink::mojom::BackgroundFetchError error;
+
+ // Verify that no developer IDs can be found.
+ auto developer_ids = GetDeveloperIds(sw_id, origin(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_THAT(developer_ids, IsEmpty());
+ // Create a single registration.
+ BackgroundFetchRegistrationId registration_id1(
+ sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
+ CreateRegistration(registration_id1, requests, options, &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ // Verify that the developer ID can be found.
+ developer_ids = GetDeveloperIds(sw_id, origin(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_THAT(developer_ids, UnorderedElementsAre(kExampleDeveloperId));
+
+ RestartDataManagerFromPersistentStorage();
+
+ // After a restart, GetDeveloperIds should still find the IDs.
+ developer_ids = GetDeveloperIds(sw_id, origin(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_THAT(developer_ids, UnorderedElementsAre(kExampleDeveloperId));
+
+ // Create another registration.
+ BackgroundFetchRegistrationId registration_id2(
+ sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId);
+ CreateRegistration(registration_id2, requests, options, &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ // Verify that both developer IDs can be found.
+ developer_ids = GetDeveloperIds(sw_id, origin(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_THAT(developer_ids, UnorderedElementsAre(kExampleDeveloperId,
+ kAlternativeDeveloperId));
+ RestartDataManagerFromPersistentStorage();
+
+ // After a restart, GetDeveloperIds should still find the IDs.
+ developer_ids = GetDeveloperIds(sw_id, origin(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_THAT(developer_ids, UnorderedElementsAre(kExampleDeveloperId,
+ kAlternativeDeveloperId));
+}
+
+TEST_P(BackgroundFetchDataManagerTest, GetRegistration) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
- BackgroundFetchRegistrationId registration_id1(
+ BackgroundFetchRegistrationId registration_id(
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
std::vector<ServiceWorkerFetchRequest> requests(2u);
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
- size_t expected_data_count =
- kUserDataKeysPerRegistration + requests.size() * kUserDataKeysPerRequest;
+ // Create a single registration.
+ CreateRegistration(registration_id, requests, options, &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_EQ(0u, GetRegistrationUserDataByKeyPrefix(sw_id, "bgfetch_").size());
+ // Verify that the registration can be retrieved.
+ auto registration =
+ GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ ASSERT_TRUE(registration);
+ EXPECT_EQ(kExampleUniqueId, registration->unique_id);
+ EXPECT_EQ(kExampleDeveloperId, registration->developer_id);
+
+ // Verify that retrieving using the wrong developer id doesn't work.
+ registration =
+ GetRegistration(sw_id, origin(), kAlternativeDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);
+ ASSERT_FALSE(registration);
+
+ RestartDataManagerFromPersistentStorage();
+
+ // After a restart, GetRegistration should still find the registration.
+ registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ ASSERT_TRUE(registration);
+ EXPECT_EQ(kExampleUniqueId, registration->unique_id);
+ EXPECT_EQ(kExampleDeveloperId, registration->developer_id);
+}
+
+TEST_P(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
+ 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;
- // Creating the initial registration should succeed.
CreateRegistration(registration_id1, requests, options, &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_EQ(expected_data_count,
- GetRegistrationUserDataByKeyPrefix(sw_id, "bgfetch_").size());
RestartDataManagerFromPersistentStorage();
@@ -226,22 +414,109 @@ TEST_F(BackgroundFetchDataManagerTest, CreateAndDeleteRegistrationPersisted) {
CreateRegistration(registration_id2, requests, options, &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID);
- // Deleting the registration should succeed.
- DeleteRegistration(registration_id1, &error);
+ // Verify that the registration can be retrieved before deletion.
+ auto registration =
+ GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ ASSERT_TRUE(registration);
+ EXPECT_EQ(kExampleUniqueId, registration->unique_id);
+ EXPECT_EQ(kExampleDeveloperId, registration->developer_id);
+
+ // Deactivating the registration should succeed.
+ MarkRegistrationForDeletion(registration_id1, &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_EQ(0u, GetRegistrationUserDataByKeyPrefix(sw_id, "bgfetch_").size());
+
+ // Verify that the registration cannot be retrieved after deletion
+ registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);
+ ASSERT_FALSE(registration);
RestartDataManagerFromPersistentStorage();
+ // Verify again that the registration cannot be retrieved after deletion and
+ // a restart.
+ registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);
+ ASSERT_FALSE(registration);
+
// And now registering the second registration should work fine, even after
- // restarting.
+ // restarting, since there is no longer an *active* registration with the same
+ // |developer_id|, even though the initial registration has not yet been
+ // deleted.
CreateRegistration(registration_id2, requests, options, &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_EQ(expected_data_count,
- GetRegistrationUserDataByKeyPrefix(sw_id, "bgfetch_").size());
+
+ RestartDataManagerFromPersistentStorage();
+
+ // Deleting the inactive first registration should succeed.
+ DeleteRegistration(registration_id1, &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+}
+
+TEST_P(BackgroundFetchDataManagerTest, Cleanup) {
+ // Tests that the BackgroundFetchDataManager cleans up registrations
+ // marked for deletion.
+
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableBackgroundFetchPersistence);
+
+ int64_t sw_id = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
+
+ BackgroundFetchRegistrationId registration_id(
+ sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
+
+ std::vector<ServiceWorkerFetchRequest> requests(2u);
+ BackgroundFetchOptions options;
+ blink::mojom::BackgroundFetchError error;
+
+ size_t expected_inactive_data_count =
+ kUserDataKeysPerInactiveRegistration +
+ requests.size() * kUserDataKeysPerInactiveRequest;
+
+ if (registration_storage_ ==
+ BackgroundFetchRegistrationStorage::kPersistent) {
+ EXPECT_EQ(
+ 0u, GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
+ }
+
+ // Create a registration.
+ CreateRegistration(registration_id, requests, options, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ // And deactivate it.
+ MarkRegistrationForDeletion(registration_id, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ RestartDataManagerFromPersistentStorage();
+
+ if (registration_storage_ ==
+ BackgroundFetchRegistrationStorage::kPersistent) {
+ EXPECT_EQ(
+ expected_inactive_data_count,
+ GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
+ }
+
+ // Cleanup should delete the registration.
+ background_fetch_data_manager_->Cleanup();
+ base::RunLoop().RunUntilIdle();
+ if (registration_storage_ ==
+ BackgroundFetchRegistrationStorage::kPersistent) {
+ EXPECT_EQ(
+ 0u, GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
+ }
+
+ RestartDataManagerFromPersistentStorage();
+
+ // The deletion should have been persisted.
+ if (registration_storage_ ==
+ BackgroundFetchRegistrationStorage::kPersistent) {
+ EXPECT_EQ(
+ 0u, GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
+ }
}
-TEST_F(BackgroundFetchDataManagerTest, CreateInParallel) {
+TEST_P(BackgroundFetchDataManagerTest, CreateInParallel) {
// Tests that multiple parallel calls to the BackgroundFetchDataManager are
// linearized and handled one at a time, rather than producing inconsistent
// results due to interleaving.
@@ -271,8 +546,7 @@ TEST_F(BackgroundFetchDataManagerTest, CreateInParallel) {
background_fetch_data_manager_->CreateRegistration(
registration_id, requests, options,
- base::BindOnce(&BackgroundFetchDataManagerTest::DidCreateRegistration,
- base::Unretained(this), quit_once_all_finished_closure,
+ base::BindOnce(&DidCreateRegistration, quit_once_all_finished_closure,
&errors[i]));
}
run_loop.Run();
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 87f5b77535e..e249c54227e 100644
--- a/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc
@@ -6,7 +6,6 @@
#include <utility>
-#include "base/guid.h"
#include "base/memory/ptr_util.h"
#include "content/browser/background_fetch/background_fetch_job_controller.h"
#include "content/public/browser/background_fetch_delegate.h"
@@ -40,7 +39,21 @@ class BackgroundFetchDelegateProxy::Core
return weak_ptr_factory_.GetWeakPtr();
}
- void StartRequest(const std::string& guid,
+ void CreateDownloadJob(const std::string& job_unique_id,
+ const std::string& title,
+ const url::Origin& origin,
+ int completed_parts,
+ int total_parts,
+ const std::vector<std::string>& current_guids) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (delegate_) {
+ delegate_->CreateDownloadJob(job_unique_id, title, origin,
+ completed_parts, total_parts, current_guids);
+ }
+ }
+
+ void StartRequest(const std::string& job_unique_id,
const url::Origin& origin,
scoped_refptr<BackgroundFetchRequestInfo> request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -92,25 +105,36 @@ class BackgroundFetchDelegateProxy::Core
// Append the Origin header for requests whose CORS flag is set, or whose
// request method is not GET or HEAD. See section 3.1 of the standard:
// https://fetch.spec.whatwg.org/#origin-header
- if (fetch_request.mode == FETCH_REQUEST_MODE_CORS ||
- fetch_request.mode == FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT ||
+ if (fetch_request.mode == network::mojom::FetchRequestMode::kCORS ||
+ fetch_request.mode ==
+ network::mojom::FetchRequestMode::kCORSWithForcedPreflight ||
(fetch_request.method != "GET" && fetch_request.method != "POST")) {
headers.SetHeader("Origin", origin.Serialize());
}
- delegate_->DownloadUrl(guid, fetch_request.method, fetch_request.url,
+ delegate_->DownloadUrl(job_unique_id, request->download_guid(),
+ fetch_request.method, fetch_request.url,
traffic_annotation, headers);
}
+ void Abort(const std::string& job_unique_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (delegate_)
+ delegate_->Abort(job_unique_id);
+ }
+
// BackgroundFetchDelegate::Client implementation:
- void OnDownloadUpdated(const std::string& guid,
+ void OnJobCancelled(const std::string& job_unique_id) override;
+ void OnDownloadUpdated(const std::string& job_unique_id,
+ const std::string& guid,
uint64_t bytes_downloaded) override;
void OnDownloadComplete(
+ const std::string& job_unique_id,
const std::string& guid,
std::unique_ptr<BackgroundFetchResult> result) override;
- void OnDownloadFailed(const std::string& guid,
- BackgroundFetchDelegate::FailureReason reason) override;
void OnDownloadStarted(
+ const std::string& job_unique_id,
const std::string& guid,
std::unique_ptr<content::BackgroundFetchResponse> response) override;
void OnDelegateShutdown() override;
@@ -128,33 +152,39 @@ class BackgroundFetchDelegateProxy::Core
DISALLOW_COPY_AND_ASSIGN(Core);
};
+void BackgroundFetchDelegateProxy::Core::OnJobCancelled(
+ const std::string& job_unique_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&BackgroundFetchDelegateProxy::OnJobCancelled, io_parent_,
+ job_unique_id));
+}
+
void BackgroundFetchDelegateProxy::Core::OnDownloadUpdated(
+ const std::string& job_unique_id,
const std::string& guid,
uint64_t bytes_downloaded) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&BackgroundFetchDelegateProxy::OnDownloadUpdated,
- io_parent_, guid, bytes_downloaded));
+ io_parent_, job_unique_id, guid, bytes_downloaded));
}
void BackgroundFetchDelegateProxy::Core::OnDownloadComplete(
+ const std::string& job_unique_id,
const std::string& guid,
std::unique_ptr<BackgroundFetchResult> result) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&BackgroundFetchDelegateProxy::OnDownloadComplete,
- io_parent_, guid, std::move(result)));
-}
-
-void BackgroundFetchDelegateProxy::Core::OnDownloadFailed(
- const std::string& guid,
- BackgroundFetchDelegate::FailureReason reason) {
- // TODO(delphick): do something with this
+ io_parent_, job_unique_id, guid, std::move(result)));
}
void BackgroundFetchDelegateProxy::Core::OnDownloadStarted(
+ const std::string& job_unique_id,
const std::string& guid,
std::unique_ptr<content::BackgroundFetchResponse> response) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -162,13 +192,22 @@ void BackgroundFetchDelegateProxy::Core::OnDownloadStarted(
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&BackgroundFetchDelegateProxy::DidStartRequest, io_parent_,
- guid, std::move(response)));
+ job_unique_id, guid, std::move(response)));
}
void BackgroundFetchDelegateProxy::Core::OnDelegateShutdown() {
delegate_ = nullptr;
}
+BackgroundFetchDelegateProxy::JobDetails::JobDetails(
+ base::WeakPtr<Controller> controller)
+ : controller(controller) {}
+
+BackgroundFetchDelegateProxy::JobDetails::JobDetails(JobDetails&& details) =
+ default;
+
+BackgroundFetchDelegateProxy::JobDetails::~JobDetails() = default;
+
BackgroundFetchDelegateProxy::BackgroundFetchDelegateProxy(
BackgroundFetchDelegate* delegate)
: weak_ptr_factory_(this) {
@@ -188,79 +227,146 @@ BackgroundFetchDelegateProxy::~BackgroundFetchDelegateProxy() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
+void BackgroundFetchDelegateProxy::CreateDownloadJob(
+ const std::string& job_unique_id,
+ const std::string& title,
+ const url::Origin& origin,
+ base::WeakPtr<Controller> controller,
+ int completed_parts,
+ int total_parts,
+ const std::vector<std::string>& current_guids) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ DCHECK(!job_details_map_.count(job_unique_id));
+ job_details_map_.emplace(job_unique_id, JobDetails(controller));
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&Core::CreateDownloadJob, ui_core_ptr_, job_unique_id,
+ title, origin, completed_parts, total_parts,
+ current_guids));
+}
+
void BackgroundFetchDelegateProxy::StartRequest(
- base::WeakPtr<Controller> job_controller,
+ const std::string& job_unique_id,
const url::Origin& origin,
scoped_refptr<BackgroundFetchRequestInfo> request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(job_controller);
- std::string guid(base::GenerateGUID());
+ DCHECK(job_details_map_.count(job_unique_id));
+ JobDetails& job_details = job_details_map_.find(job_unique_id)->second;
+ DCHECK(job_details.controller);
- controller_map_[guid] = std::make_pair(request, job_controller);
+ std::string download_guid = request->download_guid();
+ DCHECK(!download_guid.empty());
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&Core::StartRequest, ui_core_ptr_, guid, origin, request));
+ 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));
}
-void BackgroundFetchDelegateProxy::UpdateUI(const std::string& title) {
+void BackgroundFetchDelegateProxy::UpdateUI(const std::string& job_unique_id,
+ const std::string& title) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// TODO(delphick): Update the user interface with |title|.
}
-void BackgroundFetchDelegateProxy::Abort() {
+void BackgroundFetchDelegateProxy::Abort(const std::string& job_unique_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&Core::Abort, ui_core_ptr_, job_unique_id));
+
+ job_details_map_.erase(job_details_map_.find(job_unique_id));
+}
+
+void BackgroundFetchDelegateProxy::OnJobCancelled(
+ const std::string& job_unique_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // TODO(delphick): Abort all in-progress downloads.
+ // TODO(delphick): The controller may not exist as persistence is not yet
+ // implemented.
+ auto job_details_iter = job_details_map_.find(job_unique_id);
+ if (job_details_iter == job_details_map_.end())
+ return;
+
+ JobDetails& job_details = job_details_iter->second;
+ if (job_details.controller)
+ job_details.controller->AbortFromUser();
}
void BackgroundFetchDelegateProxy::DidStartRequest(
+ const std::string& job_unique_id,
const std::string& guid,
std::unique_ptr<BackgroundFetchResponse> response) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_EQ(controller_map_.count(guid), 1u);
+
+ // TODO(delphick): The controller may not exist as persistence is not yet
+ // implemented.
+ auto job_details_iter = job_details_map_.find(job_unique_id);
+ if (job_details_iter == job_details_map_.end())
+ return;
+
+ JobDetails& job_details = job_details_iter->second;
const scoped_refptr<BackgroundFetchRequestInfo>& request_info =
- controller_map_[guid].first;
- base::WeakPtr<Controller> job_controller = controller_map_[guid].second;
+ job_details.current_request_map[guid];
+ DCHECK_EQ(guid, request_info->download_guid());
request_info->PopulateWithResponse(std::move(response));
- if (job_controller)
- job_controller->DidStartRequest(request_info, guid);
+ if (job_details.controller)
+ job_details.controller->DidStartRequest(request_info);
}
void BackgroundFetchDelegateProxy::OnDownloadUpdated(
+ const std::string& job_unique_id,
const std::string& guid,
uint64_t bytes_downloaded) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_EQ(controller_map_.count(guid), 1u);
- const scoped_refptr<BackgroundFetchRequestInfo>& request_info =
- controller_map_[guid].first;
- base::WeakPtr<Controller> job_controller = controller_map_[guid].second;
+ // TODO(delphick): The controller may not exist as persistence is not yet
+ // implemented.
+ auto job_details_iter = job_details_map_.find(job_unique_id);
+ if (job_details_iter == job_details_map_.end())
+ return;
+
+ JobDetails& job_details = job_details_iter->second;
// TODO(peter): Should we update the |request_info| with the progress?
- if (job_controller)
- job_controller->DidUpdateRequest(request_info, guid, bytes_downloaded);
+ if (job_details.controller) {
+ const scoped_refptr<BackgroundFetchRequestInfo>& request_info =
+ job_details.current_request_map[guid];
+ DCHECK_EQ(guid, request_info->download_guid());
+ job_details.controller->DidUpdateRequest(request_info, bytes_downloaded);
+ }
}
void BackgroundFetchDelegateProxy::OnDownloadComplete(
+ const std::string& job_unique_id,
const std::string& guid,
std::unique_ptr<BackgroundFetchResult> result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_EQ(controller_map_.count(guid), 1u);
- const scoped_refptr<BackgroundFetchRequestInfo>& request_info =
- controller_map_[guid].first;
- base::WeakPtr<Controller> job_controller = controller_map_[guid].second;
+ // TODO(delphick): The controller may not exist as persistence is not yet
+ // implemented.
+ auto job_details_iter = job_details_map_.find(job_unique_id);
+ if (job_details_iter == job_details_map_.end())
+ return;
+
+ JobDetails& job_details = job_details_iter->second;
+ const scoped_refptr<BackgroundFetchRequestInfo>& request_info =
+ job_details.current_request_map[guid];
+ DCHECK_EQ(guid, request_info->download_guid());
request_info->SetResult(std::move(result));
- if (job_controller)
- job_controller->DidCompleteRequest(request_info, guid);
+ if (job_details.controller)
+ job_details.controller->DidCompleteRequest(request_info);
}
} // namespace content
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 1042844d8cd..4bf35b18c97 100644
--- a/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h
+++ b/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h
@@ -10,17 +10,17 @@
#include <memory>
#include <string>
#include <utility>
+#include <vector>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/background_fetch/background_fetch_request_info.h"
+#include "content/public/browser/background_fetch_response.h"
#include "content/public/browser/browser_thread.h"
namespace content {
class BackgroundFetchDelegate;
-class BackgroundFetchJobController;
-struct BackgroundFetchResponse;
// Proxy class for passing messages between BackgroundFetchJobControllers on the
// IO thread and BackgroundFetchDelegate on the UI thread.
@@ -30,23 +30,22 @@ class CONTENT_EXPORT BackgroundFetchDelegateProxy {
// will be called on the IO thread.
class Controller {
public:
- // Called when the given |request| has started fetching, after having been
- // assigned the |download_guid| by the download system.
+ // Called when the given |request| has started fetching.
virtual void DidStartRequest(
- const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid) = 0;
+ const scoped_refptr<BackgroundFetchRequestInfo>& request) = 0;
// Called when the given |request| has an update, meaning that a total of
// |bytes_downloaded| are now available for the response.
virtual void DidUpdateRequest(
const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid,
uint64_t bytes_downloaded) = 0;
// Called when the given |request| has been completed.
virtual void DidCompleteRequest(
- const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid) = 0;
+ const scoped_refptr<BackgroundFetchRequestInfo>& request) = 0;
+
+ // Called when the user aborts a Background Fetch registration.
+ virtual void AbortFromUser() = 0;
virtual ~Controller() {}
};
@@ -55,49 +54,83 @@ class CONTENT_EXPORT BackgroundFetchDelegateProxy {
~BackgroundFetchDelegateProxy();
+ // Creates a new download grouping identified by |job_unique_id|. Further
+ // downloads started by StartRequest will also use this |job_unique_id| so
+ // that a notification can be updated with the current status. If the download
+ // was already started in a previous browser session, then |current_guids|
+ // should contain the GUIDs of in progress downloads, while completed
+ // downloads are recorded in |completed_parts|.
+ // Should only be called from the Controller (on the IO
+ // thread).
+ void CreateDownloadJob(const std::string& job_unique_id,
+ const std::string& title,
+ const url::Origin& origin,
+ base::WeakPtr<Controller> controller,
+ int completed_parts,
+ int total_parts,
+ const std::vector<std::string>& current_guids);
+
// Requests that the download manager start fetching |request|.
// Should only be called from the Controller (on the IO
// thread).
- void StartRequest(base::WeakPtr<Controller> job_controller,
+ void StartRequest(const std::string& job_unique_id,
const url::Origin& origin,
scoped_refptr<BackgroundFetchRequestInfo> request);
- // Updates the representation of this Background Fetch in the user interface
- // to match the given |title|.
- // Should only be called from the BackgroundFetchJobController (on the IO
- // thread).
- void UpdateUI(const std::string& title);
+ // Updates the representation of this registration in the user interface to
+ // match the given |title|. Called from the Controller (on the IO thread).
+ void UpdateUI(const std::string& job_unique_id, const std::string& title);
- // Immediately aborts this Background Fetch by request of the developer.
- // Should only be called from the BackgroundFetchJobController (on the IO
- // thread).
- void Abort();
+ // Aborts in progress downloads for the given registration. Called from the
+ // Controller (on the IO thread) after it is aborted, either by the user or
+ // website. May occur even if all requests already called OnDownloadComplete.
+ void Abort(const std::string& job_unique_id);
private:
class Core;
- // Called when the given download identified by |guid| has been completed.
+ // 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);
+
+ // Called when the download identified by |guid| has succeeded/failed/aborted.
// Should only be called on the IO thread.
- void OnDownloadComplete(const std::string& guid,
+ void OnDownloadComplete(const std::string& job_unique_id,
+ const std::string& guid,
std::unique_ptr<BackgroundFetchResult> result);
- // Called when progerss has been made for the download identified by |guid|.
+ // Called when progress has been made for the download identified by |guid|.
// Should only be called on the IO thread.
- void OnDownloadUpdated(const std::string& guid, uint64_t bytes_downloaded);
+ void OnDownloadUpdated(const std::string& job_unique_id,
+ const std::string& guid,
+ uint64_t bytes_downloaded);
// Should only be called from the BackgroundFetchDelegate (on the IO thread).
- void DidStartRequest(const std::string& guid,
+ void DidStartRequest(const std::string& job_unique_id,
+ const std::string& guid,
std::unique_ptr<BackgroundFetchResponse> response);
std::unique_ptr<Core, BrowserThread::DeleteOnUIThread> ui_core_;
base::WeakPtr<Core> ui_core_ptr_;
- // Map from DownloadService GUIDs to the RequestInfo and the JobController
- // that started the download.
- std::map<std::string,
- std::pair<scoped_refptr<BackgroundFetchRequestInfo>,
- base::WeakPtr<Controller>>>
- controller_map_;
+ struct JobDetails {
+ explicit JobDetails(base::WeakPtr<Controller> controller);
+ JobDetails(JobDetails&& details);
+ ~JobDetails();
+
+ base::WeakPtr<Controller> controller;
+
+ // Map from DownloadService GUIDs to their corresponding request.
+ base::flat_map<std::string, scoped_refptr<BackgroundFetchRequestInfo>>
+ current_request_map;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(JobDetails);
+ };
+
+ // Map from unique job ids to a JobDetails containing the outstanding download
+ // GUIDs and the controller that started the download.
+ std::map<std::string, JobDetails> job_details_map_;
base::WeakPtrFactory<BackgroundFetchDelegateProxy> weak_ptr_factory_;
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 0b3eae2bfc6..1beeeaad401 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
@@ -4,6 +4,7 @@
#include "content/browser/background_fetch/background_fetch_delegate_proxy.h"
+#include <set>
#include <vector>
#include "base/memory/weak_ptr.h"
@@ -17,11 +18,23 @@ namespace content {
namespace {
+const char kExampleUniqueId[] = "7e57ab1e-c0de-a150-ca75-1e75f005ba11";
+const char kExampleUniqueId2[] = "17467386-60b4-4c5b-b66c-aabf793fd39b";
+
class FakeBackgroundFetchDelegate : public BackgroundFetchDelegate {
public:
FakeBackgroundFetchDelegate() {}
- void DownloadUrl(const std::string& guid,
+ // BackgroundFetchDelegate implementation:
+ void CreateDownloadJob(
+ const std::string& job_unique_id,
+ const std::string& title,
+ const url::Origin& origin,
+ int completed_parts,
+ int total_parts,
+ const std::vector<std::string>& current_guids) override {}
+ void DownloadUrl(const std::string& job_unique_id,
+ const std::string& guid,
const std::string& method,
const GURL& url,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
@@ -29,26 +42,44 @@ class FakeBackgroundFetchDelegate : public BackgroundFetchDelegate {
if (!client())
return;
+ download_guid_to_job_id_map_[guid] = job_unique_id;
+
auto response = std::make_unique<BackgroundFetchResponse>(
std::vector<GURL>({url}),
base::MakeRefCounted<net::HttpResponseHeaders>("200 OK"));
- client()->OnDownloadStarted(guid, std::move(response));
+ client()->OnDownloadStarted(job_unique_id, guid, std::move(response));
if (complete_downloads_) {
- auto result = std::make_unique<BackgroundFetchResult>(
- base::Time::Now(), base::FilePath(), 10u);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::BindOnce(&BackgroundFetchDelegate::Client::OnDownloadComplete,
- client(), guid, std::move(result)));
+ base::BindOnce(&FakeBackgroundFetchDelegate::CompleteDownload,
+ base::Unretained(this), job_unique_id, guid));
}
}
+ void Abort(const std::string& job_unique_id) override {
+ aborted_jobs_.insert(job_unique_id);
+ }
void set_complete_downloads(bool complete_downloads) {
complete_downloads_ = complete_downloads;
}
private:
+ void CompleteDownload(const std::string& job_unique_id,
+ const std::string& guid) {
+ if (!client())
+ return;
+
+ 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(), 10u));
+ }
+
+ std::set<std::string> aborted_jobs_;
+ std::map<std::string, std::string> download_guid_to_job_id_map_;
bool complete_downloads_ = true;
};
@@ -56,22 +87,22 @@ class FakeController : public BackgroundFetchDelegateProxy::Controller {
public:
FakeController() : weak_ptr_factory_(this) {}
- void DidStartRequest(const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid) override {
+ void DidStartRequest(
+ const scoped_refptr<BackgroundFetchRequestInfo>& request) override {
request_started_ = true;
}
void DidUpdateRequest(
const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid,
uint64_t bytes_downloaded) override {}
void DidCompleteRequest(
- const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid) override {
+ const scoped_refptr<BackgroundFetchRequestInfo>& request) override {
request_completed_ = true;
}
+ void AbortFromUser() override {}
+
bool request_started_ = false;
bool request_completed_ = false;
base::WeakPtrFactory<FakeController> weak_ptr_factory_;
@@ -86,6 +117,15 @@ class BackgroundFetchDelegateProxyTest : public BackgroundFetchTestBase {
BackgroundFetchDelegateProxy delegate_proxy_;
};
+scoped_refptr<BackgroundFetchRequestInfo> CreateRequestInfo(
+ int request_index,
+ const ServiceWorkerFetchRequest& fetch_request) {
+ auto request = base::MakeRefCounted<BackgroundFetchRequestInfo>(
+ request_index, fetch_request);
+ request->InitializeDownloadGuid();
+ return request;
+}
+
} // namespace
TEST_F(BackgroundFetchDelegateProxyTest, SetDelegate) {
@@ -95,14 +135,16 @@ TEST_F(BackgroundFetchDelegateProxyTest, SetDelegate) {
TEST_F(BackgroundFetchDelegateProxyTest, StartRequest) {
FakeController controller;
ServiceWorkerFetchRequest fetch_request;
- auto request = base::MakeRefCounted<BackgroundFetchRequestInfo>(
- 0 /* request_index */, fetch_request);
+ auto request = CreateRequestInfo(0 /* request_index */, fetch_request);
EXPECT_FALSE(controller.request_started_);
EXPECT_FALSE(controller.request_completed_);
- delegate_proxy_.StartRequest(controller.weak_ptr_factory_.GetWeakPtr(),
- url::Origin(), request);
+ delegate_proxy_.CreateDownloadJob(kExampleUniqueId, "Job 1", url::Origin(),
+ controller.weak_ptr_factory_.GetWeakPtr(),
+ 0, 1, {});
+
+ delegate_proxy_.StartRequest(kExampleUniqueId, url::Origin(), request);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(controller.request_started_);
@@ -112,19 +154,53 @@ TEST_F(BackgroundFetchDelegateProxyTest, StartRequest) {
TEST_F(BackgroundFetchDelegateProxyTest, StartRequest_NotCompleted) {
FakeController controller;
ServiceWorkerFetchRequest fetch_request;
- auto request = base::MakeRefCounted<BackgroundFetchRequestInfo>(
- 0 /* request_index */, fetch_request);
+ auto request = CreateRequestInfo(0 /* request_index */, fetch_request);
EXPECT_FALSE(controller.request_started_);
EXPECT_FALSE(controller.request_completed_);
delegate_.set_complete_downloads(false);
- delegate_proxy_.StartRequest(controller.weak_ptr_factory_.GetWeakPtr(),
- url::Origin(), request);
+ delegate_proxy_.CreateDownloadJob(kExampleUniqueId, "Job 1", url::Origin(),
+ controller.weak_ptr_factory_.GetWeakPtr(),
+ 0, 1, {});
+
+ delegate_proxy_.StartRequest(kExampleUniqueId, url::Origin(), request);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(controller.request_started_);
EXPECT_FALSE(controller.request_completed_);
}
+TEST_F(BackgroundFetchDelegateProxyTest, Abort) {
+ FakeController controller;
+ FakeController controller2;
+ ServiceWorkerFetchRequest fetch_request;
+ ServiceWorkerFetchRequest fetch_request2;
+ auto request = CreateRequestInfo(0 /* request_index */, fetch_request);
+ auto request2 = CreateRequestInfo(1 /* request_index */, fetch_request2);
+
+ EXPECT_FALSE(controller.request_started_);
+ EXPECT_FALSE(controller.request_completed_);
+ EXPECT_FALSE(controller2.request_started_);
+ EXPECT_FALSE(controller2.request_completed_);
+
+ delegate_proxy_.CreateDownloadJob(kExampleUniqueId, "Job 1", url::Origin(),
+ controller.weak_ptr_factory_.GetWeakPtr(),
+ 0, 1, {});
+
+ delegate_proxy_.CreateDownloadJob(kExampleUniqueId2, "Job 2", url::Origin(),
+ controller2.weak_ptr_factory_.GetWeakPtr(),
+ 0, 1, {});
+
+ delegate_proxy_.StartRequest(kExampleUniqueId, url::Origin(), request);
+ delegate_proxy_.StartRequest(kExampleUniqueId2, url::Origin(), request2);
+ delegate_proxy_.Abort(kExampleUniqueId);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(controller.request_started_) << "Aborted job started";
+ EXPECT_FALSE(controller.request_completed_) << "Aborted job completed";
+ EXPECT_TRUE(controller2.request_started_) << "Normal job did not start";
+ EXPECT_TRUE(controller2.request_completed_) << "Normal job did not complete";
+}
+
} // namespace content
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 abd9b283925..84aea94f66b 100644
--- a/chromium/content/browser/background_fetch/background_fetch_job_controller.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_job_controller.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/memory/ptr_util.h"
+#include "content/browser/background_fetch/background_fetch_request_manager.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -16,36 +17,42 @@ BackgroundFetchJobController::BackgroundFetchJobController(
const BackgroundFetchRegistrationId& registration_id,
const BackgroundFetchOptions& options,
const BackgroundFetchRegistration& registration,
- BackgroundFetchDataManager* data_manager,
+ BackgroundFetchRequestManager* request_manager,
ProgressCallback progress_callback,
- CompletedCallback completed_callback)
+ FinishedCallback finished_callback)
: registration_id_(registration_id),
options_(options),
complete_requests_downloaded_bytes_cache_(registration.downloaded),
- data_manager_(data_manager),
+ request_manager_(request_manager),
delegate_proxy_(delegate_proxy),
progress_callback_(std::move(progress_callback)),
- completed_callback_(std::move(completed_callback)),
+ finished_callback_(std::move(finished_callback)),
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- data_manager_->SetController(registration_id, this);
+}
+
+void BackgroundFetchJobController::InitializeRequestStatus(
+ int completed_downloads,
+ int total_downloads,
+ const std::vector<std::string>& outstanding_guids) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ delegate_proxy_->CreateDownloadJob(
+ registration_id_.unique_id(), options_.title, registration_id_.origin(),
+ GetWeakPtr(), completed_downloads, total_downloads, outstanding_guids);
}
BackgroundFetchJobController::~BackgroundFetchJobController() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- data_manager_->SetController(registration_id_, nullptr);
}
void BackgroundFetchJobController::Start() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_EQ(state_, State::INITIALIZED);
-
- state_ = State::FETCHING;
// TODO(crbug.com/741609): Enforce kMaximumBackgroundFetchParallelRequests
// globally and/or per origin rather than per fetch.
for (size_t i = 0; i < kMaximumBackgroundFetchParallelRequests; i++) {
- data_manager_->PopNextRequest(
+ request_manager_->PopNextRequest(
registration_id_,
base::BindOnce(&BackgroundFetchJobController::StartRequest,
weak_ptr_factory_.GetWeakPtr()));
@@ -55,33 +62,31 @@ void BackgroundFetchJobController::Start() {
void BackgroundFetchJobController::StartRequest(
scoped_refptr<BackgroundFetchRequestInfo> request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_EQ(state_, State::FETCHING);
if (!request) {
// This can happen when |Start| tries to start multiple initial requests,
// but the fetch does not contain that many pending requests; or when
// |DidMarkRequestCompleted| tries to start the next request but there are
- // none left.
+ // none left, perhaps because the registration was aborted.
return;
}
- delegate_proxy_->StartRequest(weak_ptr_factory_.GetWeakPtr(),
+ delegate_proxy_->StartRequest(registration_id_.unique_id(),
registration_id_.origin(), request);
}
void BackgroundFetchJobController::DidStartRequest(
- const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid) {
+ const scoped_refptr<BackgroundFetchRequestInfo>& request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- data_manager_->MarkRequestAsStarted(registration_id_, request.get(),
- download_guid);
+ request_manager_->MarkRequestAsStarted(registration_id_, request.get(),
+ request->download_guid());
}
void BackgroundFetchJobController::DidUpdateRequest(
const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid,
uint64_t bytes_downloaded) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ const std::string& download_guid = request->download_guid();
if (active_request_download_bytes_[download_guid] == bytes_downloaded)
return;
@@ -93,24 +98,16 @@ void BackgroundFetchJobController::DidUpdateRequest(
}
void BackgroundFetchJobController::DidCompleteRequest(
- const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid) {
+ const scoped_refptr<BackgroundFetchRequestInfo>& request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(state_ == State::FETCHING || state_ == State::ABORTED);
-
- // TODO(delphick): When ABORT is implemented correctly we should hopefully
- // never get here and the DCHECK above should only allow FETCHING.
- if (state_ == State::ABORTED)
- return;
- // This request is no longer in-progress, so the DataManager will take over
- // responsibility for storing its downloaded bytes, though still need a cache.
- active_request_download_bytes_.erase(download_guid);
+ active_request_download_bytes_.erase(request->download_guid());
complete_requests_downloaded_bytes_cache_ += request->GetFileSize();
- // The DataManager must acknowledge that it stored the data and that there are
- // no more pending requests to avoid marking this job as completed too early.
- data_manager_->MarkRequestAsComplete(
+ // The RequestManager must acknowledge that it stored the data and that there
+ // are no more pending requests to avoid marking this job as completed too
+ // early.
+ request_manager_->MarkRequestAsComplete(
registration_id_, request.get(),
base::BindOnce(&BackgroundFetchJobController::DidMarkRequestCompleted,
weak_ptr_factory_.GetWeakPtr()));
@@ -119,12 +116,11 @@ void BackgroundFetchJobController::DidCompleteRequest(
void BackgroundFetchJobController::DidMarkRequestCompleted(
bool has_pending_or_active_requests) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_EQ(state_, State::FETCHING);
// If not all requests have completed, start a pending request if there are
// any left, and bail.
if (has_pending_or_active_requests) {
- data_manager_->PopNextRequest(
+ request_manager_->PopNextRequest(
registration_id_,
base::BindOnce(&BackgroundFetchJobController::StartRequest,
weak_ptr_factory_.GetWeakPtr()));
@@ -132,14 +128,25 @@ void BackgroundFetchJobController::DidMarkRequestCompleted(
}
// Otherwise the job this controller is responsible for has completed.
- state_ = State::COMPLETED;
- std::move(completed_callback_).Run(this);
+ if (finished_callback_) {
+ // Copy registration_id_ onto stack as finished_callback_ may delete |this|.
+ BackgroundFetchRegistrationId registration_id(registration_id_);
+
+ // This call will be ignored if the job has already been aborted.
+ std::move(finished_callback_).Run(registration_id, false /* aborted */);
+ }
+}
+
+void BackgroundFetchJobController::AbortFromUser() {
+ // Aborts from user come via the BackgroundFetchDelegate, which will have
+ // already cancelled the download.
+ Abort(false /* cancel_download */);
}
void BackgroundFetchJobController::UpdateUI(const std::string& title) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- delegate_proxy_->UpdateUI(title);
+ delegate_proxy_->UpdateUI(registration_id_.unique_id(), title);
}
uint64_t BackgroundFetchJobController::GetInProgressDownloadedBytes() {
@@ -152,20 +159,21 @@ uint64_t BackgroundFetchJobController::GetInProgressDownloadedBytes() {
void BackgroundFetchJobController::Abort() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- switch (state_) {
- case State::INITIALIZED:
- case State::FETCHING:
- break;
- case State::ABORTED:
- case State::COMPLETED:
- return; // Ignore attempt to abort after completion/abort.
- }
+ Abort(true /* cancel_download */);
+}
+
+void BackgroundFetchJobController::Abort(bool cancel_download) {
+ if (cancel_download)
+ delegate_proxy_->Abort(registration_id_.unique_id());
+
+ if (!finished_callback_)
+ return;
- delegate_proxy_->Abort();
+ // Copy registration_id_ onto stack as finished_callback_ may delete |this|.
+ BackgroundFetchRegistrationId registration_id(registration_id_);
- state_ = State::ABORTED;
- // Inform the owner of the controller about the job having aborted.
- std::move(completed_callback_).Run(this);
+ // This call will be ignored if job has already completed/failed/aborted.
+ std::move(finished_callback_).Run(registration_id, true /* aborted */);
}
} // 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 443c707b702..cfd75f5cd73 100644
--- a/chromium/content/browser/background_fetch/background_fetch_job_controller.h
+++ b/chromium/content/browser/background_fetch/background_fetch_job_controller.h
@@ -8,12 +8,11 @@
#include <stdint.h>
#include <memory>
#include <string>
-#include <unordered_map>
+#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "content/browser/background_fetch/background_fetch_data_manager.h"
#include "content/browser/background_fetch/background_fetch_delegate_proxy.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/background_fetch/background_fetch_request_info.h"
@@ -23,44 +22,57 @@
namespace content {
+class BackgroundFetchRequestManager;
+
// The JobController will be responsible for coordinating communication with the
-// DownloadManager. It will get requests from the DataManager and dispatch them
-// to the DownloadManager. It lives entirely on the IO thread.
+// DownloadManager. It will get requests from the RequestManager and dispatch
+// them to the DownloadService. It lives entirely on the IO thread.
+//
+// Lifetime: It is created lazily only once a Background Fetch registration
+// starts downloading, and it is destroyed once no more communication with the
+// DownloadService or Offline Items Collection is necessary (i.e. once the
+// registration has been aborted, or once it has completed/failed and the
+// waitUntil promise has been resolved so UpdateUI can no longer be called).
class CONTENT_EXPORT BackgroundFetchJobController final
- : public BackgroundFetchDelegateProxy::Controller,
- public BackgroundFetchDataManager::Controller {
+ : public BackgroundFetchDelegateProxy::Controller {
public:
- enum class State { INITIALIZED, FETCHING, ABORTED, COMPLETED };
+ using FinishedCallback =
+ base::OnceCallback<void(const BackgroundFetchRegistrationId&,
+ bool /* aborted */)>;
using ProgressCallback =
base::RepeatingCallback<void(const std::string& /* unique_id */,
uint64_t /* download_total */,
uint64_t /* downloaded */)>;
- using CompletedCallback =
- base::OnceCallback<void(BackgroundFetchJobController*)>;
-
BackgroundFetchJobController(
BackgroundFetchDelegateProxy* delegate_proxy,
const BackgroundFetchRegistrationId& registration_id,
const BackgroundFetchOptions& options,
const BackgroundFetchRegistration& registration,
- BackgroundFetchDataManager* data_manager,
+ BackgroundFetchRequestManager* request_manager,
ProgressCallback progress_callback,
- CompletedCallback completed_callback);
+ FinishedCallback finished_callback);
~BackgroundFetchJobController() override;
// Starts fetching the first few requests. The controller will continue to
// fetch new content until all requests have been handled.
void Start();
- // BackgroundFetchDataManager::Controller implementation:
- void UpdateUI(const std::string& title) override;
- uint64_t GetInProgressDownloadedBytes() override;
+ // Initializes the job controller with the status of the active and completed
+ // downloads. Only called when this has been loaded from the database.
+ void InitializeRequestStatus(
+ int completed_downloads,
+ int total_downloads,
+ const std::vector<std::string>& outstanding_guids);
- // Immediately aborts this Background Fetch by request of the developer.
- void Abort();
+ // Gets the number of bytes downloaded for jobs that are currently running.
+ uint64_t GetInProgressDownloadedBytes();
+
+ // Updates the UI (currently only job title) that's shown to the user as part
+ // of a notification for instance.
+ void UpdateUI(const std::string& title);
- // Returns the current state of this Job Controller.
- State state() const { return state_; }
+ // Aborts the job including cancelling any ongoing downloads.
+ void Abort();
// Returns the registration id for which this job is fetching data.
const BackgroundFetchRegistrationId& registration_id() const {
@@ -75,17 +87,21 @@ class CONTENT_EXPORT BackgroundFetchJobController final
}
// BackgroundFetchDelegateProxy::Controller implementation:
- void DidStartRequest(const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid) override;
+ void DidStartRequest(
+ const scoped_refptr<BackgroundFetchRequestInfo>& request) override;
void DidUpdateRequest(
const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid,
uint64_t bytes_downloaded) override;
void DidCompleteRequest(
- const scoped_refptr<BackgroundFetchRequestInfo>& request,
- const std::string& download_guid) override;
+ const scoped_refptr<BackgroundFetchRequestInfo>& request) override;
+ void AbortFromUser() override;
private:
+ // Aborts a job updating the registration with the new state. If
+ // |cancel_download| is true, the ongoing download is also cancelled
+ // (otherwise it assumes that has already happened).
+ void Abort(bool cancel_download);
+
// Requests the download manager to start fetching |request|.
void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request);
@@ -105,12 +121,9 @@ class CONTENT_EXPORT BackgroundFetchJobController final
// delivering progress events without having to read from the database.
uint64_t complete_requests_downloaded_bytes_cache_;
- // The current state of this Job Controller.
- State state_ = State::INITIALIZED;
-
- // The DataManager's lifetime is controlled by the BackgroundFetchContext and
- // will be kept alive until after the JobController is destroyed.
- BackgroundFetchDataManager* data_manager_;
+ // The RequestManager's lifetime is controlled by the BackgroundFetchContext
+ // and will be kept alive until after the JobController is destroyed.
+ BackgroundFetchRequestManager* request_manager_;
// Proxy for interacting with the BackgroundFetchDelegate across thread
// boundaries. It is owned by the BackgroundFetchContext.
@@ -119,8 +132,8 @@ class CONTENT_EXPORT BackgroundFetchJobController final
// Callback run each time download progress updates.
ProgressCallback progress_callback_;
- // Callback for when all fetches have been completed.
- CompletedCallback completed_callback_;
+ // Callback for when all fetches have completed/failed/aborted.
+ FinishedCallback finished_callback_;
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 c20ad28a75a..99b9ebaf186 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
@@ -41,12 +41,15 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
embedded_worker_test_helper()->context_wrapper()) {}
~BackgroundFetchJobControllerTest() override = default;
- // 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|. Should be wrapped in ASSERT_NO_FATAL_FAILURE().
+ // 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
+ // immediately receive a successful response. Should be wrapped in
+ // ASSERT_NO_FATAL_FAILURE().
void CreateRegistrationForRequests(
BackgroundFetchRegistrationId* registration_id,
- std::map<GURL, std::string /* method */> request_data) {
+ std::map<GURL, std::string /* method */> request_data,
+ bool auto_complete_requests) {
DCHECK(registration_id);
int64_t service_worker_registration_id = RegisterServiceWorker();
@@ -78,19 +81,22 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- // Provide fake responses for the given |request_data| pairs.
- for (const auto& pair : request_data) {
- CreateRequestWithProvidedResponse(
- pair.second, pair.first,
- TestResponseBuilder(200 /* response_code */)
- .SetResponseData(kExampleResponseData)
- .Build());
+ if (auto_complete_requests) {
+ // Provide fake responses for the given |request_data| pairs.
+ for (const auto& pair : request_data) {
+ CreateRequestWithProvidedResponse(
+ pair.second /* method */, pair.first /* url */,
+ TestResponseBuilder(200 /* response_code */)
+ .SetResponseData(kExampleResponseData)
+ .Build());
+ }
}
}
// Creates a new BackgroundFetchJobController instance.
std::unique_ptr<BackgroundFetchJobController> CreateJobController(
- const BackgroundFetchRegistrationId& registration_id) {
+ const BackgroundFetchRegistrationId& registration_id,
+ int total_downloads = 1) {
delegate_ = browser_context()->GetBackgroundFetchDelegate();
DCHECK(delegate_);
delegate_proxy_ = std::make_unique<BackgroundFetchDelegateProxy>(delegate_);
@@ -99,21 +105,26 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
registration.developer_id = registration_id.developer_id();
registration.unique_id = registration_id.unique_id();
- return std::make_unique<BackgroundFetchJobController>(
+ auto controller = std::make_unique<BackgroundFetchJobController>(
delegate_proxy_.get(), registration_id, BackgroundFetchOptions(),
registration, &data_manager_,
base::BindRepeating(
&BackgroundFetchJobControllerTest::DidUpdateProgress,
base::Unretained(this)),
- base::BindOnce(&BackgroundFetchJobControllerTest::DidCompleteJob,
+ base::BindOnce(&BackgroundFetchJobControllerTest::DidFinishJob,
base::Unretained(this)));
+
+ controller->InitializeRequestStatus(0, total_downloads,
+ std::vector<std::string>());
+ return controller;
}
protected:
BackgroundFetchDataManager data_manager_;
uint64_t last_downloaded_ = 0;
- bool did_complete_job_ = false;
+ bool did_finish_job_ = false;
+ bool was_aborted_ = false;
// Closure that will be invoked every time the JobController receives a
// progress update from a download.
@@ -131,7 +142,7 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
blink::mojom::BackgroundFetchError* out_error,
const base::Closure& quit_closure,
blink::mojom::BackgroundFetchError error,
- const base::Optional<BackgroundFetchRegistration>& registration) {
+ std::unique_ptr<BackgroundFetchRegistration> registration) {
DCHECK(out_error);
*out_error = error;
@@ -148,13 +159,10 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
job_progress_closure_.Run();
}
- void DidCompleteJob(BackgroundFetchJobController* controller) {
- DCHECK(controller);
- EXPECT_TRUE(
- controller->state() == BackgroundFetchJobController::State::ABORTED ||
- controller->state() == BackgroundFetchJobController::State::COMPLETED);
-
- did_complete_job_ = true;
+ void DidFinishJob(const BackgroundFetchRegistrationId& registration_id,
+ bool aborted) {
+ did_finish_job_ = true;
+ was_aborted_ = aborted;
if (job_completed_closure_)
std::move(job_completed_closure_).Run();
@@ -167,18 +175,16 @@ TEST_F(BackgroundFetchJobControllerTest, SingleRequestJob) {
BackgroundFetchRegistrationId registration_id;
ASSERT_NO_FATAL_FAILURE(CreateRegistrationForRequests(
- &registration_id, {{GURL("https://example.com/funny_cat.png"), "GET"}}));
+ &registration_id, {{GURL("https://example.com/funny_cat.png"), "GET"}},
+ true /* auto_complete_requests */));
std::unique_ptr<BackgroundFetchJobController> controller =
CreateJobController(registration_id);
- EXPECT_EQ(controller->state(),
- BackgroundFetchJobController::State::INITIALIZED);
-
controller->Start();
- EXPECT_EQ(controller->state(), BackgroundFetchJobController::State::FETCHING);
- // Mark the single download item as finished, completing the job.
+ // Continue spinning until the Job Controller has completed the request.
+ // The Delegate has been told to automatically mark it as finished.
{
base::RunLoop run_loop;
job_completed_closure_ = run_loop.QuitClosure();
@@ -186,9 +192,8 @@ TEST_F(BackgroundFetchJobControllerTest, SingleRequestJob) {
run_loop.Run();
}
- EXPECT_EQ(controller->state(),
- BackgroundFetchJobController::State::COMPLETED);
- EXPECT_TRUE(did_complete_job_);
+ EXPECT_TRUE(did_finish_job_);
+ EXPECT_FALSE(was_aborted_);
}
TEST_F(BackgroundFetchJobControllerTest, MultipleRequestJob) {
@@ -199,74 +204,65 @@ TEST_F(BackgroundFetchJobControllerTest, MultipleRequestJob) {
ASSERT_GT(5u, kMaximumBackgroundFetchParallelRequests);
ASSERT_NO_FATAL_FAILURE(CreateRegistrationForRequests(
- &registration_id, {{GURL("https://example.com/funny_cat.png"), "GET"},
- {GURL("https://example.com/scary_cat.png"), "GET"},
- {GURL("https://example.com/crazy_cat.png"), "GET"},
- {GURL("https://example.com/silly_cat.png"), "GET"},
- {GURL("https://example.com/happy_cat.png"), "GET"}}));
+ &registration_id,
+ {{GURL("https://example.com/funny_cat.png"), "GET"},
+ {GURL("https://example.com/scary_cat.png"), "GET"},
+ {GURL("https://example.com/crazy_cat.png"), "GET"},
+ {GURL("https://example.com/silly_cat.png"), "GET"},
+ {GURL("https://example.com/happy_cat.png"), "GET"}},
+ true /* auto_complete_requests */));
std::unique_ptr<BackgroundFetchJobController> controller =
CreateJobController(registration_id);
- EXPECT_EQ(controller->state(),
- BackgroundFetchJobController::State::INITIALIZED);
-
// Continue spinning until the Job Controller has completed all the requests.
- // The Download Manager has been told to automatically mark them as finished.
+ // The Delegate has been told to automatically mark them as finished.
{
base::RunLoop run_loop;
job_completed_closure_ = run_loop.QuitClosure();
controller->Start();
- EXPECT_EQ(controller->state(),
- BackgroundFetchJobController::State::FETCHING);
run_loop.Run();
}
- EXPECT_EQ(controller->state(),
- BackgroundFetchJobController::State::COMPLETED);
- EXPECT_TRUE(did_complete_job_);
+ EXPECT_TRUE(did_finish_job_);
+ EXPECT_FALSE(was_aborted_);
}
-TEST_F(BackgroundFetchJobControllerTest, AbortJob) {
+TEST_F(BackgroundFetchJobControllerTest, Abort) {
BackgroundFetchRegistrationId registration_id;
ASSERT_NO_FATAL_FAILURE(CreateRegistrationForRequests(
- &registration_id, {{GURL("https://example.com/sad_cat.png"), "GET"}}));
+ &registration_id, {{GURL("https://example.com/sad_cat.png"), "GET"}},
+ false /* auto_complete_requests */));
std::unique_ptr<BackgroundFetchJobController> controller =
CreateJobController(registration_id);
- EXPECT_EQ(controller->state(),
- BackgroundFetchJobController::State::INITIALIZED);
-
- // Start the first few requests, and abort them immediately after.
- {
- base::RunLoop run_loop;
- job_completed_closure_ = run_loop.QuitClosure();
-
- controller->Start();
- EXPECT_EQ(controller->state(),
- BackgroundFetchJobController::State::FETCHING);
+ // Start the request, and abort it immediately after.
+ controller->Start();
- controller->Abort();
+ // TODO(delphick): Add test for AbortFromUser as well.
+ controller->Abort();
- run_loop.Run();
- }
+ // Run until idle to ensure that spurious download successful tasks are not
+ // executed.
+ base::RunLoop().RunUntilIdle();
// TODO(peter): Verify that the issued download items have had their state
// updated to be cancelled as well.
- EXPECT_EQ(controller->state(), BackgroundFetchJobController::State::ABORTED);
- EXPECT_TRUE(did_complete_job_);
+ EXPECT_TRUE(did_finish_job_);
+ EXPECT_TRUE(was_aborted_);
}
TEST_F(BackgroundFetchJobControllerTest, Progress) {
BackgroundFetchRegistrationId registration_id;
ASSERT_NO_FATAL_FAILURE(CreateRegistrationForRequests(
- &registration_id, {{GURL("https://example.com/slow_cat.png"), "GET"}}));
+ &registration_id, {{GURL("https://example.com/slow_cat.png"), "GET"}},
+ true /* auto_complete_requests */));
std::unique_ptr<BackgroundFetchJobController> controller =
CreateJobController(registration_id);
@@ -288,7 +284,7 @@ TEST_F(BackgroundFetchJobControllerTest, Progress) {
run_loop.Run();
}
- EXPECT_TRUE(did_complete_job_);
+ EXPECT_TRUE(did_finish_job_);
EXPECT_EQ(last_downloaded_, strlen(kExampleResponseData));
}
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 dd17f375098..4590bb371e7 100644
--- a/chromium/content/browser/background_fetch/background_fetch_registration_notifier.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_registration_notifier.cc
@@ -20,6 +20,8 @@ void BackgroundFetchRegistrationNotifier::AddObserver(
// Observe connection errors, which occur when the JavaScript object or the
// renderer hosting them goes away. (For example through navigation.) The
// observer gets freed together with |this|, thus the Unretained is safe.
+ // TODO(crbug.com/777764): This doesn't actually work for the cases where
+ // the closing of the binding is non-exceptional.
observer.set_connection_error_handler(
base::BindOnce(&BackgroundFetchRegistrationNotifier::OnConnectionError,
base::Unretained(this), unique_id, observer.get()));
@@ -38,9 +40,13 @@ void BackgroundFetchRegistrationNotifier::Notify(const std::string& unique_id,
}
}
-void BackgroundFetchRegistrationNotifier::RemoveObservers(
- const std::string& unique_id) {
- observers_.erase(unique_id);
+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::OnConnectionError(
@@ -51,6 +57,13 @@ 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 75392d84e9c..28a8981d88f 100644
--- a/chromium/content/browser/background_fetch/background_fetch_registration_notifier.h
+++ b/chromium/content/browser/background_fetch/background_fetch_registration_notifier.h
@@ -9,6 +9,7 @@
#include <map>
#include <string>
+#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
@@ -31,14 +32,16 @@ class CONTENT_EXPORT BackgroundFetchRegistrationNotifier {
// 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);
- // Removes the observers for the registration identified by the |unique_id|.
- // When the background fetch was successful, the Notify() function should have
- // been called beforehand to inform developers of the final state.
- void RemoveObservers(const std::string& unique_id);
+ // 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);
base::WeakPtr<BackgroundFetchRegistrationNotifier> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
@@ -51,11 +54,15 @@ class CONTENT_EXPORT BackgroundFetchRegistrationNotifier {
const std::string& unique_id,
blink::mojom::BackgroundFetchRegistrationObserver* observer);
- // Storage of observers keyed by the unique id of a registration.
+ // Storage of observers keyed by the |unique_id| of a registration.
std::multimap<std::string,
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 de138d42252..2e3f89b593c 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
@@ -96,12 +96,16 @@ class BackgroundFetchRegistrationNotifierTest : public ::testing::Test {
task_runner_->RunUntilIdle();
}
+ void CollectGarbage() { garbage_collected_ = true; }
+
protected:
scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
base::ThreadTaskRunnerHandle handle_;
std::unique_ptr<BackgroundFetchRegistrationNotifier> notifier_;
+ bool garbage_collected_ = false;
+
private:
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchRegistrationNotifierTest);
};
@@ -159,27 +163,6 @@ TEST_F(BackgroundFetchRegistrationNotifierTest, NotifyMultipleObservers) {
}
TEST_F(BackgroundFetchRegistrationNotifierTest,
- NotifyFollowingNotifierInitiatedRemoval) {
- auto observer = std::make_unique<TestRegistrationObserver>();
-
- notifier_->AddObserver(kPrimaryUniqueId, observer->GetPtr());
- ASSERT_EQ(observer->progress_updates().size(), 0u);
-
- Notify(kPrimaryUniqueId, kDownloadTotal, kDownloaded);
-
- ASSERT_EQ(observer->progress_updates().size(), 1u);
-
- // Remove the observers from |kPrimaryUniqueId| from the notifier.
- notifier_->RemoveObservers(kPrimaryUniqueId);
-
- Notify(kPrimaryUniqueId, kDownloadTotal, kDownloaded);
-
- // The observers for |kPrimaryUniqueId| were removed, so no second update
- // should have been received by the |observer|.
- ASSERT_EQ(observer->progress_updates().size(), 1u);
-}
-
-TEST_F(BackgroundFetchRegistrationNotifierTest,
NotifyFollowingObserverInitiatedRemoval) {
auto observer = std::make_unique<TestRegistrationObserver>();
@@ -213,5 +196,38 @@ TEST_F(BackgroundFetchRegistrationNotifierTest, NotifyWithoutObservers) {
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) {
+ 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();
+
+ // 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.";
+}
+
} // namespace
} // namespace content
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 05d56e1a42a..fbd7db34a9a 100644
--- a/chromium/content/browser/background_fetch/background_fetch_request_info.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_request_info.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/guid.h"
#include "base/strings/string_util.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "content/public/browser/background_fetch_response.h"
@@ -27,6 +28,20 @@ BackgroundFetchRequestInfo::~BackgroundFetchRequestInfo() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
+void BackgroundFetchRequestInfo::InitializeDownloadGuid() {
+ DCHECK(download_guid_.empty());
+
+ download_guid_ = base::GenerateGUID();
+}
+
+void BackgroundFetchRequestInfo::SetDownloadGuid(
+ const std::string& download_guid) {
+ DCHECK(!download_guid.empty());
+ DCHECK(download_guid_.empty());
+
+ download_guid_ = download_guid;
+}
+
void BackgroundFetchRequestInfo::PopulateWithResponse(
std::unique_ptr<BackgroundFetchResponse> response) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
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 01132c10985..a446f8f1876 100644
--- a/chromium/content/browser/background_fetch/background_fetch_request_info.h
+++ b/chromium/content/browser/background_fetch/background_fetch_request_info.h
@@ -35,6 +35,14 @@ class CONTENT_EXPORT BackgroundFetchRequestInfo
BackgroundFetchRequestInfo(int request_index,
const ServiceWorkerFetchRequest& fetch_request);
+ // Sets the download GUID to a newly generated value. Can only be used if no
+ // GUID is already set.
+ void InitializeDownloadGuid();
+
+ // Sets the download GUID to a given value (to be used when requests are
+ // 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);
@@ -43,6 +51,10 @@ class CONTENT_EXPORT BackgroundFetchRequestInfo
// Returns the index of this request within a Background Fetch registration.
int request_index() const { return request_index_; }
+ // Returns the GUID used to identify this download. (Empty before the download
+ // becomes active).
+ const std::string& download_guid() const { return download_guid_; }
+
// Returns the Fetch API Request object that details the developer's request.
const ServiceWorkerFetchRequest& fetch_request() const {
return fetch_request_;
@@ -80,7 +92,6 @@ class CONTENT_EXPORT BackgroundFetchRequestInfo
~BackgroundFetchRequestInfo();
// ---- Data associated with the request -------------------------------------
-
int request_index_ = kInvalidBackgroundFetchRequestIndex;
ServiceWorkerFetchRequest fetch_request_;
diff --git a/chromium/content/browser/background_fetch/background_fetch_request_manager.h b/chromium/content/browser/background_fetch/background_fetch_request_manager.h
new file mode 100644
index 00000000000..f987104ce1a
--- /dev/null
+++ b/chromium/content/browser/background_fetch/background_fetch_request_manager.h
@@ -0,0 +1,53 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_REQUEST_MANAGER_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_REQUEST_MANAGER_H_
+
+#include <string>
+
+#include "base/callback_forward.h"
+#include "base/memory/scoped_refptr.h"
+
+namespace content {
+
+class BackgroundFetchRegistrationId;
+class BackgroundFetchRequestInfo;
+
+// Interface for manager requests that are part of a Background Fetch.
+// Implementations maintain a queue of requests for each given
+// |BackgroundFetchRegistrationId| that may be backed by a database.
+class BackgroundFetchRequestManager {
+ public:
+ using NextRequestCallback =
+ base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>;
+ using MarkedCompleteCallback =
+ base::OnceCallback<void(bool /* has_pending_or_active_requests */)>;
+
+ virtual ~BackgroundFetchRequestManager() {}
+
+ // Removes the next request, if any, from the pending requests queue, and
+ // invokes the |callback| with that request, else a null request.
+ virtual void PopNextRequest(
+ const BackgroundFetchRegistrationId& registration_id,
+ NextRequestCallback callback) = 0;
+
+ // Marks that the |request|, part of the Background Fetch identified by
+ // |registration_id|, has been started as |download_guid|.
+ virtual void MarkRequestAsStarted(
+ const BackgroundFetchRegistrationId& registration_id,
+ BackgroundFetchRequestInfo* request,
+ const std::string& download_guid) = 0;
+
+ // Marks that the |request|, part of the Background Fetch identified by
+ // |registration_id|, has completed.
+ virtual void MarkRequestAsComplete(
+ const BackgroundFetchRegistrationId& registration_id,
+ BackgroundFetchRequestInfo* request,
+ MarkedCompleteCallback callback) = 0;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_REQUEST_MANAGER_H_
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 0cbe43b08e7..3be70517586 100644
--- a/chromium/content/browser/background_fetch/background_fetch_service_impl.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_service_impl.cc
@@ -4,16 +4,12 @@
#include "content/browser/background_fetch/background_fetch_service_impl.h"
+#include <memory>
+
#include "base/guid.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/optional.h"
#include "content/browser/background_fetch/background_fetch_context.h"
-#include "content/browser/background_fetch/background_fetch_job_controller.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/bad_message.h"
-#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/common/background_fetch/background_fetch_types.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -38,7 +34,7 @@ void BackgroundFetchServiceImpl::Create(
blink::mojom::BackgroundFetchServiceRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
mojo::MakeStrongBinding(
- base::MakeUnique<BackgroundFetchServiceImpl>(
+ std::make_unique<BackgroundFetchServiceImpl>(
render_process_id, std::move(background_fetch_context)),
std::move(request));
}
@@ -97,28 +93,25 @@ void BackgroundFetchServiceImpl::UpdateUI(const std::string& unique_id,
return;
}
- background_fetch_context_->data_manager().UpdateRegistrationUI(
- unique_id, title, std::move(callback));
+ background_fetch_context_->UpdateUI(unique_id, title, std::move(callback));
}
-void BackgroundFetchServiceImpl::Abort(const std::string& unique_id,
+void BackgroundFetchServiceImpl::Abort(int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ const std::string& developer_id,
+ const std::string& unique_id,
AbortCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!ValidateUniqueId(unique_id)) {
+ if (!ValidateDeveloperId(developer_id) || !ValidateUniqueId(unique_id)) {
std::move(callback).Run(
blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
return;
}
- BackgroundFetchJobController* controller =
- background_fetch_context_->GetActiveFetch(unique_id);
-
- if (controller)
- controller->Abort();
-
- std::move(callback).Run(controller
- ? blink::mojom::BackgroundFetchError::NONE
- : blink::mojom::BackgroundFetchError::INVALID_ID);
+ background_fetch_context_->Abort(
+ BackgroundFetchRegistrationId(service_worker_registration_id, origin,
+ developer_id, unique_id),
+ std::move(callback));
}
void BackgroundFetchServiceImpl::GetRegistration(
@@ -134,9 +127,9 @@ void BackgroundFetchServiceImpl::GetRegistration(
return;
}
- background_fetch_context_->data_manager().GetRegistration(
- service_worker_registration_id, origin, developer_id,
- std::move(callback));
+ background_fetch_context_->GetRegistration(service_worker_registration_id,
+ origin, developer_id,
+ std::move(callback));
}
void BackgroundFetchServiceImpl::GetDeveloperIds(
@@ -144,8 +137,8 @@ void BackgroundFetchServiceImpl::GetDeveloperIds(
const url::Origin& origin,
GetDeveloperIdsCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- background_fetch_context_->data_manager().GetDeveloperIdsForServiceWorker(
- service_worker_registration_id, std::move(callback));
+ background_fetch_context_->GetDeveloperIdsForServiceWorker(
+ service_worker_registration_id, origin, std::move(callback));
}
void BackgroundFetchServiceImpl::AddRegistrationObserver(
@@ -172,7 +165,7 @@ bool BackgroundFetchServiceImpl::ValidateDeveloperId(
bool BackgroundFetchServiceImpl::ValidateUniqueId(
const std::string& unique_id) {
- if (!base::IsValidGUID(unique_id)) {
+ if (!base::IsValidGUIDOutputString(unique_id)) {
bad_message::ReceivedBadMessage(render_process_id_,
bad_message::BFSI_INVALID_UNIQUE_ID);
return false;
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 001ba5d492d..b5b44636576 100644
--- a/chromium/content/browser/background_fetch/background_fetch_service_impl.h
+++ b/chromium/content/browser/background_fetch/background_fetch_service_impl.h
@@ -48,7 +48,11 @@ class CONTENT_EXPORT BackgroundFetchServiceImpl
void UpdateUI(const std::string& unique_id,
const std::string& title,
UpdateUICallback callback) override;
- void Abort(const std::string& unique_id, AbortCallback callback) override;
+ void Abort(int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ const std::string& developer_id,
+ const std::string& unique_id,
+ AbortCallback callback) override;
void GetRegistration(int64_t service_worker_registration_id,
const url::Origin& origin,
const std::string& developer_id,
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 28795b75dee..bbe524effa2 100644
--- a/chromium/content/browser/background_fetch/background_fetch_service_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -23,6 +23,7 @@
namespace content {
namespace {
+const char kExampleUniqueId[] = "7e57ab1e-c0de-a150-ca75-1e75f005ba11";
const char kExampleDeveloperId[] = "my-background-fetch";
const char kAlternativeDeveloperId[] = "my-alternative-fetch";
@@ -86,12 +87,15 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
}
// Synchronous wrapper for BackgroundFetchServiceImpl::Abort().
- void Abort(const std::string& unique_id,
+ void Abort(int64_t service_worker_registration_id,
+ const std::string& developer_id,
+ const std::string& unique_id,
blink::mojom::BackgroundFetchError* out_error) {
DCHECK(out_error);
base::RunLoop run_loop;
- service_->Abort(unique_id,
+ service_->Abort(service_worker_registration_id, origin(), developer_id,
+ unique_id,
base::BindOnce(&BackgroundFetchServiceTest::DidGetError,
base::Unretained(this),
run_loop.QuitClosure(), out_error));
@@ -119,6 +123,7 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
// Synchronous wrapper for BackgroundFetchServiceImpl::GetDeveloperIds().
void GetDeveloperIds(int64_t service_worker_registration_id,
+ const url::Origin& origin,
blink::mojom::BackgroundFetchError* out_error,
std::vector<std::string>* out_developer_ids) {
DCHECK(out_error);
@@ -126,7 +131,7 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
base::RunLoop run_loop;
service_->GetDeveloperIds(
- service_worker_registration_id, origin(),
+ service_worker_registration_id, origin,
base::BindOnce(&BackgroundFetchServiceTest::DidGetDeveloperIds,
base::Unretained(this), run_loop.QuitClosure(),
out_error, out_developer_ids));
@@ -142,7 +147,7 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
browser_context(),
base::WrapRefCounted(embedded_worker_test_helper()->context_wrapper()));
- service_ = base::MakeUnique<BackgroundFetchServiceImpl>(
+ service_ = std::make_unique<BackgroundFetchServiceImpl>(
0 /* render_process_id */, context_);
}
@@ -257,15 +262,7 @@ TEST_F(BackgroundFetchServiceTest, FetchRegistrationProperties) {
// The |registration| should reflect the options given in |options|.
EXPECT_EQ(registration.developer_id, kExampleDeveloperId);
- ASSERT_EQ(registration.icons.size(), options.icons.size());
- for (size_t i = 0; i < registration.icons.size(); ++i) {
- EXPECT_EQ(registration.icons[i].src, options.icons[i].src);
- EXPECT_EQ(registration.icons[i].sizes, options.icons[i].sizes);
- EXPECT_EQ(registration.icons[i].type, options.icons[i].type);
- }
-
- EXPECT_EQ(registration.title, options.title);
EXPECT_EQ(registration.download_total, options.download_total);
blink::mojom::BackgroundFetchError second_error;
@@ -277,15 +274,7 @@ TEST_F(BackgroundFetchServiceTest, FetchRegistrationProperties) {
// The |second_registration| should reflect the options given in |options|.
EXPECT_EQ(second_registration.developer_id, kExampleDeveloperId);
- ASSERT_EQ(second_registration.icons.size(), options.icons.size());
-
- for (size_t i = 0; i < second_registration.icons.size(); ++i) {
- EXPECT_EQ(second_registration.icons[i].src, options.icons[i].src);
- EXPECT_EQ(second_registration.icons[i].sizes, options.icons[i].sizes);
- EXPECT_EQ(second_registration.icons[i].type, options.icons[i].type);
- }
- EXPECT_EQ(second_registration.title, options.title);
EXPECT_EQ(second_registration.download_total, options.download_total);
}
@@ -423,7 +412,7 @@ TEST_F(BackgroundFetchServiceTest, FetchSuccessEventDispatch) {
// TODO(peter): change-detector tests for unsupported properties.
EXPECT_EQ(fetches[i].response.error,
- blink::kWebServiceWorkerResponseErrorUnknown);
+ blink::mojom::ServiceWorkerResponseError::kUnknown);
// Verify that all properties have a sensible value.
EXPECT_FALSE(fetches[i].response.response_time.is_null());
@@ -518,7 +507,7 @@ TEST_F(BackgroundFetchServiceTest, FetchFailEventDispatch) {
// TODO(peter): change-detector tests for unsupported properties.
EXPECT_EQ(fetches[i].response.error,
- blink::kWebServiceWorkerResponseErrorUnknown);
+ blink::mojom::ServiceWorkerResponseError::kUnknown);
EXPECT_TRUE(fetches[i].response.cors_exposed_header_names.empty());
}
}
@@ -548,7 +537,6 @@ TEST_F(BackgroundFetchServiceTest, UpdateUI) {
Fetch(service_worker_registration_id, kExampleDeveloperId, requests,
options, &error, &registration);
ASSERT_EQ(blink::mojom::BackgroundFetchError::NONE, error);
- ASSERT_EQ(options.title, registration.title);
std::string second_title = "2nd title";
@@ -562,8 +550,6 @@ TEST_F(BackgroundFetchServiceTest, UpdateUI) {
GetRegistration(service_worker_registration_id, kExampleDeveloperId, &error,
&second_registration);
ASSERT_EQ(blink::mojom::BackgroundFetchError::NONE, error);
- EXPECT_NE(options.title, second_registration.title);
- EXPECT_EQ(second_title, second_registration.title);
}
TEST_F(BackgroundFetchServiceTest, Abort) {
@@ -591,7 +577,8 @@ TEST_F(BackgroundFetchServiceTest, Abort) {
blink::mojom::BackgroundFetchError abort_error;
// Immediately abort the registration. This also is expected to succeed.
- Abort(registration_id.unique_id(), &abort_error);
+ Abort(service_worker_registration_id, kExampleDeveloperId,
+ registration_id.unique_id(), &abort_error);
ASSERT_EQ(abort_error, blink::mojom::BackgroundFetchError::NONE);
// Wait for the response of the Mojo IPC to dispatch
// BackgroundFetchAbortEvent.
@@ -606,13 +593,25 @@ TEST_F(BackgroundFetchServiceTest, Abort) {
ASSERT_EQ(second_error, blink::mojom::BackgroundFetchError::INVALID_ID);
}
+TEST_F(BackgroundFetchServiceTest, AbortInvalidDeveloperIdArgument) {
+ // This test verifies that the Abort() function will kill the renderer and
+ // return INVALID_ARGUMENT when an invalid |developer_id| is sent over the
+ // Mojo channel.
+
+ blink::mojom::BackgroundFetchError error;
+ Abort(42 /* service_worker_registration_id */, "" /* developer_id */,
+ kExampleUniqueId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
+}
+
TEST_F(BackgroundFetchServiceTest, AbortInvalidUniqueIdArgument) {
// This test verifies that the Abort() function will kill the renderer and
// return INVALID_ARGUMENT when an invalid |unique_id| is sent over the Mojo
// channel.
blink::mojom::BackgroundFetchError error;
- Abort("not a GUID" /* unique_id */, &error);
+ Abort(42 /* service_worker_registration_id */, kExampleDeveloperId,
+ "not a GUID" /* unique_id */, &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
}
@@ -621,7 +620,8 @@ TEST_F(BackgroundFetchServiceTest, AbortUnknownUniqueId) {
// |unique_id| that does not correspond to an active fetch kindly tells us so.
blink::mojom::BackgroundFetchError error;
- Abort("7e57ab1e-c0de-a150-ca75-1e75f005ba11" /* unique_id */, &error);
+ Abort(42 /* service_worker_registration_id */, kExampleDeveloperId,
+ kExampleUniqueId, &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);
}
@@ -667,7 +667,8 @@ TEST_F(BackgroundFetchServiceTest, AbortEventDispatch) {
{
blink::mojom::BackgroundFetchError error;
- Abort(registration_id.unique_id(), &error);
+ Abort(service_worker_registration_id, kExampleDeveloperId,
+ registration_id.unique_id(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
@@ -708,7 +709,8 @@ TEST_F(BackgroundFetchServiceTest, UniqueId) {
// Immediately abort the registration so it is no longer active (everything
// that follows should behave the same if the registration had completed
// instead of being aborted).
- Abort(aborted_registration_id.unique_id(), &error);
+ Abort(service_worker_registration_id, kExampleDeveloperId,
+ aborted_registration_id.unique_id(), &error);
ASSERT_EQ(blink::mojom::BackgroundFetchError::NONE, error);
// Wait for response of the Mojo IPC to dispatch BackgroundFetchAbortEvent.
base::RunLoop().RunUntilIdle();
@@ -730,7 +732,6 @@ TEST_F(BackgroundFetchServiceTest, UniqueId) {
&gotten_registration);
EXPECT_EQ(blink::mojom::BackgroundFetchError::NONE, error);
EXPECT_EQ(second_registration.unique_id, gotten_registration.unique_id);
- EXPECT_EQ(second_registration.title, gotten_registration.title);
// Calling UpdateUI for the second registration should succeed, and update the
// title of the second registration only.
@@ -753,11 +754,11 @@ TEST_F(BackgroundFetchServiceTest, UniqueId) {
&gotten_registration);
EXPECT_EQ(blink::mojom::BackgroundFetchError::NONE, error);
EXPECT_EQ(second_registration.unique_id, gotten_registration.unique_id);
- EXPECT_EQ(updated_second_registration_title, gotten_registration.title);
// Aborting the previously aborted registration should fail with INVALID_ID
// since it is no longer active.
- Abort(aborted_registration_id.unique_id(), &error);
+ Abort(service_worker_registration_id, kExampleDeveloperId,
+ aborted_registration_id.unique_id(), &error);
EXPECT_EQ(blink::mojom::BackgroundFetchError::INVALID_ID, error);
// Wait for response of the Mojo IPC to dispatch BackgroundFetchAbortEvent.
// (MockBackgroundFetchDelegate won't complete/fail second_registration in the
@@ -771,7 +772,8 @@ TEST_F(BackgroundFetchServiceTest, UniqueId) {
EXPECT_EQ(second_registration.unique_id, gotten_registration.unique_id);
// Aborting the second registration should succeed.
- Abort(second_registration_id.unique_id(), &error);
+ Abort(service_worker_registration_id, kExampleDeveloperId,
+ second_registration_id.unique_id(), &error);
EXPECT_EQ(blink::mojom::BackgroundFetchError::NONE, error);
// Wait for response of the Mojo IPC to dispatch BackgroundFetchAbortEvent.
// (MockBackgroundFetchDelegate won't complete/fail second_registration in the
@@ -803,7 +805,8 @@ TEST_F(BackgroundFetchServiceTest, GetDeveloperIds) {
blink::mojom::BackgroundFetchError error;
std::vector<std::string> developer_ids;
- GetDeveloperIds(service_worker_registration_id, &error, &developer_ids);
+ GetDeveloperIds(service_worker_registration_id, origin(), &error,
+ &developer_ids);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_EQ(developer_ids.size(), 0u);
@@ -824,7 +827,8 @@ TEST_F(BackgroundFetchServiceTest, GetDeveloperIds) {
blink::mojom::BackgroundFetchError error;
std::vector<std::string> developer_ids;
- GetDeveloperIds(service_worker_registration_id, &error, &developer_ids);
+ GetDeveloperIds(service_worker_registration_id, origin(), &error,
+ &developer_ids);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_EQ(developer_ids.size(), 1u);
@@ -846,7 +850,8 @@ TEST_F(BackgroundFetchServiceTest, GetDeveloperIds) {
blink::mojom::BackgroundFetchError error;
std::vector<std::string> developer_ids;
- GetDeveloperIds(service_worker_registration_id, &error, &developer_ids);
+ GetDeveloperIds(service_worker_registration_id, origin(), &error,
+ &developer_ids);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_EQ(developer_ids.size(), 2u);
@@ -857,6 +862,36 @@ TEST_F(BackgroundFetchServiceTest, GetDeveloperIds) {
EXPECT_TRUE(developer_ids[0] == kAlternativeDeveloperId ||
developer_ids[1] == kAlternativeDeveloperId);
}
+
+ // Verify that using the wrong origin does not return developer ids even if
+ // the service worker registration is correct.
+ {
+ blink::mojom::BackgroundFetchError error;
+ std::vector<std::string> developer_ids;
+
+ GetDeveloperIds(service_worker_registration_id,
+ url::Origin::Create(GURL("https://www.bogus-origin.com")),
+ &error, &developer_ids);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ ASSERT_EQ(developer_ids.size(), 0u);
+ }
+
+ // Verify that using the wrong service worker id does not return developer ids
+ // even if the origin is correct.
+ {
+ blink::mojom::BackgroundFetchError error;
+ std::vector<std::string> developer_ids;
+
+ int64_t bogus_service_worker_registration_id =
+ service_worker_registration_id + 1;
+
+ GetDeveloperIds(bogus_service_worker_registration_id, origin(), &error,
+ &developer_ids);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ ASSERT_EQ(developer_ids.size(), 0u);
+ }
}
} // namespace
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 00cf909cb33..268bf6f51b7 100644
--- a/chromium/content/browser/background_fetch/background_fetch_test_base.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_test_base.cc
@@ -67,7 +67,7 @@ BackgroundFetchTestBase::BackgroundFetchTestBase()
// at time of writing EmbeddedWorkerTestHelper didn't seem to support that.
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
delegate_(browser_context_.GetBackgroundFetchDelegate()),
- origin_(GURL(kTestOrigin)) {}
+ origin_(url::Origin::Create(GURL(kTestOrigin))) {}
BackgroundFetchTestBase::~BackgroundFetchTestBase() {
DCHECK(set_up_called_);
@@ -138,13 +138,11 @@ BackgroundFetchTestBase::CreateRequestWithProvidedResponse(
const std::string& method,
const GURL& url,
std::unique_ptr<TestResponse> response) {
- GURL gurl(url);
-
// Register the |response| with the faked delegate.
delegate_->RegisterResponse(url, std::move(response));
// Create a ServiceWorkerFetchRequest request with the same information.
- return ServiceWorkerFetchRequest(gurl, method, ServiceWorkerHeaderMap(),
+ return ServiceWorkerFetchRequest(url, method, ServiceWorkerHeaderMap(),
Referrer(), false /* is_reload */);
}
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 a9a1e541af3..4ac18a40e3c 100644
--- a/chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc
+++ b/chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc
@@ -20,7 +20,7 @@ MockBackgroundFetchDelegate::TestResponse::~TestResponse() = default;
MockBackgroundFetchDelegate::TestResponseBuilder::TestResponseBuilder(
int response_code)
- : response_(base::MakeUnique<TestResponse>()) {
+ : response_(std::make_unique<TestResponse>()) {
response_->succeeded_ = (response_code >= 200 && response_code < 300);
response_->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
"HTTP/1.1 " + std::to_string(response_code));
@@ -55,7 +55,16 @@ MockBackgroundFetchDelegate::MockBackgroundFetchDelegate() {}
MockBackgroundFetchDelegate::~MockBackgroundFetchDelegate() {}
+void MockBackgroundFetchDelegate::CreateDownloadJob(
+ const std::string& job_unique_id,
+ const std::string& title,
+ const url::Origin& origin,
+ int completed_parts,
+ int total_parts,
+ const std::vector<std::string>& current_guids) {}
+
void MockBackgroundFetchDelegate::DownloadUrl(
+ const std::string& job_unique_id,
const std::string& guid,
const std::string& method,
const GURL& url,
@@ -65,6 +74,8 @@ void MockBackgroundFetchDelegate::DownloadUrl(
// use the DownloadService, we should signal StartResult::UNEXPECTED_GUID.
DCHECK(seen_guids_.find(guid) == seen_guids_.end());
+ download_guid_to_job_id_map_[guid] = job_unique_id;
+
auto url_iter = url_responses_.find(url);
if (url_iter == url_responses_.end()) {
// Since no response was provided, do not respond. This allows testing
@@ -79,23 +90,25 @@ void MockBackgroundFetchDelegate::DownloadUrl(
std::make_unique<BackgroundFetchResponse>(std::vector<GURL>({url}),
test_response->headers);
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
+ PostAbortCheckingTask(
+ job_unique_id,
base::BindOnce(&BackgroundFetchDelegate::Client::OnDownloadStarted,
- client(), guid, std::move(response)));
+ client(), job_unique_id, guid, std::move(response)));
if (test_response->data.size()) {
// Report progress at 50% complete.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
+ PostAbortCheckingTask(
+ job_unique_id,
base::BindOnce(&BackgroundFetchDelegate::Client::OnDownloadUpdated,
- client(), guid, test_response->data.size() / 2));
+ client(), job_unique_id, guid,
+ test_response->data.size() / 2));
// Report progress at 100% complete.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
+ PostAbortCheckingTask(
+ job_unique_id,
base::BindOnce(&BackgroundFetchDelegate::Client::OnDownloadUpdated,
- client(), guid, test_response->data.size()));
+ client(), job_unique_id, guid,
+ test_response->data.size()));
}
if (test_response->succeeded_) {
@@ -112,24 +125,30 @@ void MockBackgroundFetchDelegate::DownloadUrl(
base::WriteFile(response_path, test_response->data.c_str(),
test_response->data.size()));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
+ PostAbortCheckingTask(
+ job_unique_id,
base::BindOnce(
&BackgroundFetchDelegate::Client::OnDownloadComplete, client(),
- guid,
+ job_unique_id, guid,
std::make_unique<BackgroundFetchResult>(
base::Time::Now(), response_path, test_response->data.size())));
} else {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(
- &BackgroundFetchDelegate::Client::OnDownloadComplete, client(),
- guid, std::make_unique<BackgroundFetchResult>(base::Time::Now())));
+ PostAbortCheckingTask(
+ job_unique_id,
+ base::BindOnce(&BackgroundFetchDelegate::Client::OnDownloadComplete,
+ client(), job_unique_id, guid,
+ std::make_unique<BackgroundFetchResult>(
+ base::Time::Now(),
+ BackgroundFetchResult::FailureReason::UNKNOWN)));
}
seen_guids_.insert(guid);
}
+void MockBackgroundFetchDelegate::Abort(const std::string& job_unique_id) {
+ aborted_jobs_.insert(job_unique_id);
+}
+
void MockBackgroundFetchDelegate::RegisterResponse(
const GURL& url,
std::unique_ptr<TestResponse> response) {
@@ -137,4 +156,21 @@ void MockBackgroundFetchDelegate::RegisterResponse(
url_responses_[url] = std::move(response);
}
+void MockBackgroundFetchDelegate::PostAbortCheckingTask(
+ const std::string& job_unique_id,
+ base::OnceCallback<void()> callback) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&MockBackgroundFetchDelegate::RunAbortCheckingTask,
+ base::Unretained(this), job_unique_id,
+ std::move(callback)));
+}
+
+void MockBackgroundFetchDelegate::RunAbortCheckingTask(
+ const std::string& job_unique_id,
+ base::OnceCallback<void()> callback) {
+ if (!aborted_jobs_.count(job_unique_id))
+ std::move(callback).Run();
+}
+
} // namespace content
diff --git a/chromium/content/browser/background_fetch/mock_background_fetch_delegate.h b/chromium/content/browser/background_fetch/mock_background_fetch_delegate.h
index d05bce101b7..953c01e071e 100644
--- a/chromium/content/browser/background_fetch/mock_background_fetch_delegate.h
+++ b/chromium/content/browser/background_fetch/mock_background_fetch_delegate.h
@@ -9,6 +9,7 @@
#include <memory>
#include <set>
#include <string>
+#include <vector>
#include "base/files/scoped_temp_dir.h"
#include "content/public/browser/background_fetch_delegate.h"
@@ -16,7 +17,7 @@
namespace net {
class HttpResponseHeaders;
-}
+} // namespace net
namespace content {
@@ -62,16 +63,35 @@ class MockBackgroundFetchDelegate : public BackgroundFetchDelegate {
~MockBackgroundFetchDelegate() override;
// BackgroundFetchDelegate implementation:
- void DownloadUrl(const std::string& guid,
+ void CreateDownloadJob(
+ const std::string& job_unique_id,
+ const std::string& title,
+ const url::Origin& origin,
+ int completed_parts,
+ int total_parts,
+ const std::vector<std::string>& current_guids) override;
+ void DownloadUrl(const std::string& job_unique_id,
+ const std::string& guid,
const std::string& method,
const GURL& url,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
const net::HttpRequestHeaders& headers) override;
+ void Abort(const std::string& job_unique_id) override;
void RegisterResponse(const GURL& url,
std::unique_ptr<TestResponse> response);
private:
+ // Posts (to the default task runner) a callback that is only run if the job
+ // indicated by |job_unique_id| has not been aborted.
+ void PostAbortCheckingTask(const std::string& job_unique_id,
+ base::OnceCallback<void()> callback);
+
+ // Immediately runs the callback if the job indicated by |job_unique_id| has
+ // not been aborted.
+ void RunAbortCheckingTask(const std::string& job_unique_id,
+ base::OnceCallback<void()> callback);
+
// Single-use responses registered for specific URLs.
std::map<const GURL, std::unique_ptr<TestResponse>> url_responses_;
@@ -81,6 +101,12 @@ class MockBackgroundFetchDelegate : public BackgroundFetchDelegate {
// Temporary directory in which successfully downloaded files will be stored.
base::ScopedTempDir temp_directory_;
+ // Set of unique job ids that have been aborted.
+ std::set<std::string> aborted_jobs_;
+
+ // Map from download GUIDs to unique job ids.
+ std::map<std::string, std::string> download_guid_to_job_id_map_;
+
DISALLOW_COPY_AND_ASSIGN(MockBackgroundFetchDelegate);
};
diff --git a/chromium/content/browser/background_fetch/storage/README.md b/chromium/content/browser/background_fetch/storage/README.md
new file mode 100644
index 00000000000..7a2ca5dcd93
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/README.md
@@ -0,0 +1,50 @@
+# Background fetch state storage
+
+`content/browser/background_fetch/storage` contains a set of tasks that read to
+and write from the service worker database, to store the state of the currently
+running background fetches.
+
+`DatabaseTask` is the abstract base class that all other tasks extend.
+
+## Service Worker DB UserData schema
+
+[Design doc](https://docs.google.com/document/d/1-WPPTP909Gb5PnaBOKP58tPVLw2Fq0Ln-u1EBviIBns/edit)
+
+- Each key will be stored twice by the Service Worker DB, once as a
+ "REG\_HAS\_USER\_DATA:", and once as a "REG\_USER\_DATA:" - see
+ content/browser/service\_worker/service\_worker\_database.cc for details.
+- Non-padded integer values are serialized as a string by base::Int\*ToString().
+### Keys and values
+```
+key: "bgfetch_active_registration_unique_id_<developer_id>"
+value: "<unique_id>"
+```
+```
+key: "bgfetch_registration_<unique_id>"
+value: "<serialized content::proto::BackgroundFetchRegistration>"
+```
+```
+key: "bgfetch_request_<unique_id>_<request_index>"
+value: "<TODO: FetchAPIRequest serialized as a string>"
+```
+```
+key: "bgfetch_pending_request_<creation_time>_<unique_id>_<request_index>"
+value: ""
+```
+
+### Expansions
+* `<unique_id>` is a GUID (v4) that identifies a background fetch registration.
+E.g. `17467386-60b4-4c5b-b66c-aabf793fd39b`
+* `<developer_id>` is a string provided by the developer to differentiate
+background fetches within a service worker. As such it may contain any
+characters and so it should be used very carefully within keys as it may
+introduce ambiguity.
+* `<request_index>` is an `int` containing the index of a request within a
+multi-part fetch. These must be padded with zeros to ensure that the ordering
+is maintain when reading back from the database, e.g. `0000000000`.
+* `<creation_time>` is the registration creation time expressed as the number
+of microseconds since the unix epoch (internally stored as an `int64_t`).
+Without padding with zeros, this may introduce an ordering inversion in
+November 2286 and again in the year 5138, but the impact would only be on the
+relative ordering with which two different fetches were scheduled.
+
diff --git a/chromium/content/browser/background_fetch/storage/cleanup_task.cc b/chromium/content/browser/background_fetch/storage/cleanup_task.cc
new file mode 100644
index 00000000000..a95ef5b6fdd
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/cleanup_task.cc
@@ -0,0 +1,93 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/storage/cleanup_task.h"
+
+#include <memory>
+
+#include "base/containers/flat_set.h"
+#include "content/browser/background_fetch/background_fetch.pb.h"
+#include "content/browser/background_fetch/storage/database_helpers.h"
+#include "content/browser/background_fetch/storage/delete_registration_task.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+
+namespace content {
+
+namespace background_fetch {
+
+namespace {
+void EmptyErrorHandler(blink::mojom::BackgroundFetchError) {}
+} // namespace
+
+CleanupTask::CleanupTask(BackgroundFetchDataManager* data_manager)
+ : DatabaseTask(data_manager), weak_factory_(this) {}
+
+CleanupTask::~CleanupTask() = default;
+
+void CleanupTask::Start() {
+ service_worker_context()->GetUserDataForAllRegistrationsByKeyPrefix(
+ kRegistrationKeyPrefix, base::Bind(&CleanupTask::DidGetRegistrations,
+ weak_factory_.GetWeakPtr()));
+}
+
+void CleanupTask::DidGetRegistrations(
+ const std::vector<std::pair<int64_t, std::string>>& registration_data,
+ ServiceWorkerStatusCode status) {
+ if (ToDatabaseStatus(status) != DatabaseStatus::kOk ||
+ registration_data.empty()) {
+ Finished(); // Destroys |this|.
+ return;
+ }
+
+ service_worker_context()->GetUserDataForAllRegistrationsByKeyPrefix(
+ kActiveRegistrationUniqueIdKeyPrefix,
+ base::Bind(&CleanupTask::DidGetActiveUniqueIds,
+ weak_factory_.GetWeakPtr(), registration_data));
+}
+
+void CleanupTask::DidGetActiveUniqueIds(
+ const std::vector<std::pair<int64_t, std::string>>& registration_data,
+ const std::vector<std::pair<int64_t, std::string>>& active_unique_id_data,
+ ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kOk:
+ case DatabaseStatus::kNotFound:
+ break;
+ case DatabaseStatus::kFailed:
+ Finished(); // Destroys |this|.
+ return;
+ }
+
+ std::vector<std::string> active_unique_id_vector;
+ active_unique_id_vector.reserve(active_unique_id_data.size());
+ for (const auto& entry : active_unique_id_data)
+ active_unique_id_vector.push_back(entry.second);
+ base::flat_set<std::string> active_unique_ids(
+ std::move(active_unique_id_vector));
+
+ for (const auto& entry : registration_data) {
+ int64_t service_worker_registration_id = entry.first;
+ proto::BackgroundFetchRegistration registration_proto;
+ if (registration_proto.ParseFromString(entry.second)) {
+ if (registration_proto.has_unique_id()) {
+ const std::string& unique_id = registration_proto.unique_id();
+ if (!active_unique_ids.count(unique_id) &&
+ !ref_counted_unique_ids().count(unique_id)) {
+ // This |unique_id| can be safely cleaned up. Re-use
+ // DeleteRegistrationTask for the actual deletion logic.
+ AddDatabaseTask(std::make_unique<DeleteRegistrationTask>(
+ data_manager(), service_worker_registration_id, unique_id,
+ base::BindOnce(&EmptyErrorHandler)));
+ }
+ }
+ }
+ }
+
+ Finished(); // Destroys |this|.
+ return;
+}
+
+} // namespace background_fetch
+
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/cleanup_task.h b/chromium/content/browser/background_fetch/storage/cleanup_task.h
new file mode 100644
index 00000000000..92db4ae4266
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/cleanup_task.h
@@ -0,0 +1,49 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_CLEANUP_TASK_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_CLEANUP_TASK_H_
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "content/browser/background_fetch/storage/database_task.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+
+namespace content {
+
+namespace background_fetch {
+
+// Deletes inactive registrations marked for deletion.
+// TODO(crbug.com/780025): Log failed deletions to UMA.
+class CleanupTask : public background_fetch::DatabaseTask {
+ public:
+ explicit CleanupTask(BackgroundFetchDataManager* data_manager);
+
+ ~CleanupTask() override;
+
+ void Start() override;
+
+ private:
+ void DidGetRegistrations(
+ const std::vector<std::pair<int64_t, std::string>>& registration_data,
+ ServiceWorkerStatusCode status);
+
+ private:
+ void DidGetActiveUniqueIds(
+ const std::vector<std::pair<int64_t, std::string>>& registration_data,
+ const std::vector<std::pair<int64_t, std::string>>& active_unique_id_data,
+ ServiceWorkerStatusCode status);
+
+ base::WeakPtrFactory<CleanupTask> weak_factory_; // Keep as last.
+
+ DISALLOW_COPY_AND_ASSIGN(CleanupTask);
+};
+
+} // namespace background_fetch
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_CLEANUP_TASK_H_
diff --git a/chromium/content/browser/background_fetch/storage/create_registration_task.cc b/chromium/content/browser/background_fetch/storage/create_registration_task.cc
new file mode 100644
index 00000000000..e94923280f0
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/create_registration_task.cc
@@ -0,0 +1,154 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/storage/create_registration_task.h"
+
+#include <utility>
+
+#include "base/strings/string_number_conversions.h"
+#include "content/browser/background_fetch/background_fetch.pb.h"
+#include "content/browser/background_fetch/storage/database_helpers.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+
+namespace content {
+
+namespace background_fetch {
+
+std::string RequestKey(const std::string& unique_id, int request_index) {
+ // Allows looking up a request by registration id and index within that.
+ return RequestKeyPrefix(unique_id) + base::IntToString(request_index);
+}
+
+CreateRegistrationTask::CreateRegistrationTask(
+ BackgroundFetchDataManager* data_manager,
+ const BackgroundFetchRegistrationId& registration_id,
+ const std::vector<ServiceWorkerFetchRequest>& requests,
+ const BackgroundFetchOptions& options,
+ CreateRegistrationCallback callback)
+ : DatabaseTask(data_manager),
+ registration_id_(registration_id),
+ requests_(requests),
+ options_(options),
+ callback_(std::move(callback)),
+ weak_factory_(this) {}
+
+CreateRegistrationTask::~CreateRegistrationTask() = default;
+
+void CreateRegistrationTask::Start() {
+ service_worker_context()->GetRegistrationUserData(
+ registration_id_.service_worker_registration_id(),
+ {ActiveRegistrationUniqueIdKey(registration_id_.developer_id())},
+ base::Bind(&CreateRegistrationTask::DidGetUniqueId,
+ weak_factory_.GetWeakPtr()));
+}
+
+void CreateRegistrationTask::DidGetUniqueId(
+ const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kNotFound:
+ StoreRegistration();
+ return;
+ case DatabaseStatus::kOk:
+ // Can't create a registration since there is already an active
+ // registration with the same |developer_id|. It must be deactivated
+ // (completed/failed/aborted) first.
+ std::move(callback_).Run(
+ blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID,
+ nullptr /* registration */);
+ Finished(); // Destroys |this|.
+ return;
+ case DatabaseStatus::kFailed:
+ std::move(callback_).Run(
+ blink::mojom::BackgroundFetchError::STORAGE_ERROR,
+ nullptr /* registration */);
+ Finished(); // Destroys |this|.
+ return;
+ }
+}
+
+void CreateRegistrationTask::StoreRegistration() {
+ DCHECK(!registration_);
+ DCHECK(!registration_id_.origin().unique());
+
+ int64_t registration_creation_microseconds_since_unix_epoch =
+ (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds();
+
+ registration_ = std::make_unique<BackgroundFetchRegistration>();
+ registration_->developer_id = registration_id_.developer_id();
+ registration_->unique_id = registration_id_.unique_id();
+ // TODO(crbug.com/774054): Uploads are not yet supported.
+ registration_->upload_total = 0;
+ registration_->uploaded = 0;
+ registration_->download_total = options_.download_total;
+ registration_->downloaded = 0;
+
+ std::vector<std::pair<std::string, std::string>> entries;
+ entries.reserve(requests_.size() * 2 + 1);
+
+ // First serialize per-registration (as opposed to per-request) data.
+ // TODO(crbug.com/757760): Serialize BackgroundFetchOptions as part of this.
+ proto::BackgroundFetchRegistration registration_proto;
+ registration_proto.set_unique_id(registration_->unique_id);
+ registration_proto.set_developer_id(registration_->developer_id);
+ registration_proto.set_origin(registration_id_.origin().Serialize());
+ registration_proto.set_creation_microseconds_since_unix_epoch(
+ registration_creation_microseconds_since_unix_epoch);
+ // TODO(delphick): Write options to the proto.
+ std::string serialized_registration_proto;
+ if (!registration_proto.SerializeToString(&serialized_registration_proto)) {
+ // TODO(crbug.com/780025): Log failures to UMA.
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::STORAGE_ERROR,
+ nullptr /* registration */);
+ Finished(); // Destroys |this|.
+ return;
+ }
+ entries.emplace_back(
+ ActiveRegistrationUniqueIdKey(registration_id_.developer_id()),
+ registration_id_.unique_id());
+ entries.emplace_back(RegistrationKey(registration_id_.unique_id()),
+ std::move(serialized_registration_proto));
+
+ // Signed integers are used for request indexes to avoid unsigned gotchas.
+ for (int i = 0; i < base::checked_cast<int>(requests_.size()); i++) {
+ // TODO(crbug.com/757760): Serialize actual values for these entries.
+ entries.emplace_back(RequestKey(registration_id_.unique_id(), i),
+ "TODO: Serialize FetchAPIRequest as value");
+ entries.emplace_back(
+ PendingRequestKey(registration_creation_microseconds_since_unix_epoch,
+ registration_id_.unique_id(), i),
+ std::string());
+ }
+
+ service_worker_context()->StoreRegistrationUserData(
+ registration_id_.service_worker_registration_id(),
+ registration_id_.origin().GetURL(), entries,
+ base::Bind(&CreateRegistrationTask::DidStoreRegistration,
+ weak_factory_.GetWeakPtr()));
+}
+
+void CreateRegistrationTask::DidStoreRegistration(
+ ServiceWorkerStatusCode status) {
+ DCHECK(registration_);
+
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kOk:
+ break;
+ case DatabaseStatus::kFailed:
+ case DatabaseStatus::kNotFound:
+ std::move(callback_).Run(
+ blink::mojom::BackgroundFetchError::STORAGE_ERROR,
+ nullptr /* registration */);
+ Finished(); // Destroys |this|.
+ return;
+ }
+
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE,
+ std::move(registration_));
+ Finished(); // Destroys |this|.
+}
+} // namespace background_fetch
+
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/create_registration_task.h b/chromium/content/browser/background_fetch/storage/create_registration_task.h
new file mode 100644
index 00000000000..a045e21a4d9
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/create_registration_task.h
@@ -0,0 +1,62 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_CREATE_REGISTRATION_TASK_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_CREATE_REGISTRATION_TASK_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "content/browser/background_fetch/storage/database_task.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h"
+
+namespace content {
+
+namespace background_fetch {
+
+// Creates Background Fetch registration entries in the database.
+class CreateRegistrationTask : public DatabaseTask {
+ public:
+ using CreateRegistrationCallback =
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError,
+ std::unique_ptr<BackgroundFetchRegistration>)>;
+
+ CreateRegistrationTask(BackgroundFetchDataManager* data_manager,
+ const BackgroundFetchRegistrationId& registration_id,
+ const std::vector<ServiceWorkerFetchRequest>& requests,
+ const BackgroundFetchOptions& options,
+ CreateRegistrationCallback callback);
+
+ ~CreateRegistrationTask() override;
+
+ void Start() override;
+
+ private:
+ void DidGetUniqueId(const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status);
+
+ void StoreRegistration();
+
+ void DidStoreRegistration(ServiceWorkerStatusCode status);
+
+ BackgroundFetchRegistrationId registration_id_;
+ std::vector<ServiceWorkerFetchRequest> requests_;
+ BackgroundFetchOptions options_;
+ CreateRegistrationCallback callback_;
+
+ std::unique_ptr<BackgroundFetchRegistration> registration_;
+
+ base::WeakPtrFactory<CreateRegistrationTask> weak_factory_; // Keep as last.
+
+ DISALLOW_COPY_AND_ASSIGN(CreateRegistrationTask);
+};
+
+} // namespace background_fetch
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_CREATE_REGISTRATION_TASK_H_
diff --git a/chromium/content/browser/background_fetch/storage/database_helpers.cc b/chromium/content/browser/background_fetch/storage/database_helpers.cc
new file mode 100644
index 00000000000..be25d6d5837
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/database_helpers.cc
@@ -0,0 +1,101 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/storage/database_helpers.h"
+
+#include "base/strings/string_number_conversions.h"
+
+namespace content {
+
+namespace background_fetch {
+
+std::string ActiveRegistrationUniqueIdKey(const std::string& developer_id) {
+ // Allows looking up the active registration's |unique_id| by |developer_id|.
+ // Registrations are active from creation up until completed/failed/aborted.
+ // These database entries correspond to the active background fetches map:
+ // https://wicg.github.io/background-fetch/#service-worker-registration-active-background-fetches
+ return kActiveRegistrationUniqueIdKeyPrefix + developer_id;
+}
+
+std::string RegistrationKey(const std::string& unique_id) {
+ // Allows looking up a registration by |unique_id|.
+ return kRegistrationKeyPrefix + unique_id;
+}
+
+std::string RequestKeyPrefix(const std::string& unique_id) {
+ // Allows looking up all requests within a registration.
+ return kRequestKeyPrefix + unique_id + kSeparator;
+}
+
+std::string PendingRequestKeyPrefix(
+ int64_t registration_creation_microseconds_since_unix_epoch,
+ const std::string& unique_id) {
+ // These keys are ordered by the registration's creation time rather than by
+ // its |unique_id|, so that the highest priority pending requests in FIFO
+ // order can be looked up by fetching the lexicographically smallest keys.
+ // https://crbug.com/741609 may introduce more advanced prioritisation.
+ //
+ // Since the ordering must survive restarts, wall clock time is used, but that
+ // is not monotonically increasing, so the ordering is not exact, and the
+ // |unique_id| is appended to break ties in case the wall clock returns the
+ // same values more than once.
+ //
+ // On Nov 20 2286 17:46:39 the microseconds will transition from 9999999999999
+ // to 10000000000000 and pending requests will briefly sort incorrectly.
+ return kPendingRequestKeyPrefix +
+ base::Int64ToString(
+ registration_creation_microseconds_since_unix_epoch) +
+ kSeparator + unique_id + kSeparator;
+}
+
+std::string PendingRequestKey(
+ int64_t registration_creation_microseconds_since_unix_epoch,
+ const std::string& unique_id,
+ int request_index) {
+ // In addition to the ordering from PendingRequestKeyPrefix, the requests
+ // within each registration should be prioritized according to their index.
+ return PendingRequestKeyPrefix(
+ registration_creation_microseconds_since_unix_epoch, unique_id) +
+ base::IntToString(request_index);
+}
+
+DatabaseStatus ToDatabaseStatus(ServiceWorkerStatusCode status) {
+ switch (status) {
+ case SERVICE_WORKER_OK:
+ return DatabaseStatus::kOk;
+ case SERVICE_WORKER_ERROR_FAILED:
+ case SERVICE_WORKER_ERROR_ABORT:
+ // FAILED is for invalid arguments (e.g. empty key) or database errors.
+ // ABORT is for unexpected failures, e.g. because shutdown is in progress.
+ // BackgroundFetchDataManager handles both of these the same way.
+ return DatabaseStatus::kFailed;
+ case SERVICE_WORKER_ERROR_NOT_FOUND:
+ // This can also happen for writes, if the ServiceWorkerRegistration has
+ // been deleted.
+ return DatabaseStatus::kNotFound;
+ case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
+ case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
+ case SERVICE_WORKER_ERROR_EXISTS:
+ case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
+ case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
+ case SERVICE_WORKER_ERROR_IPC_FAILED:
+ case SERVICE_WORKER_ERROR_NETWORK:
+ case SERVICE_WORKER_ERROR_SECURITY:
+ case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
+ case SERVICE_WORKER_ERROR_STATE:
+ case SERVICE_WORKER_ERROR_TIMEOUT:
+ case SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED:
+ case SERVICE_WORKER_ERROR_DISK_CACHE:
+ case SERVICE_WORKER_ERROR_REDUNDANT:
+ case SERVICE_WORKER_ERROR_DISALLOWED:
+ case SERVICE_WORKER_ERROR_MAX_VALUE:
+ break;
+ }
+ NOTREACHED();
+ return DatabaseStatus::kFailed;
+}
+
+} // namespace background_fetch
+
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/database_helpers.h b/chromium/content/browser/background_fetch/storage/database_helpers.h
new file mode 100644
index 00000000000..188937b5af6
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/database_helpers.h
@@ -0,0 +1,52 @@
+// Copyright 2017 The Chromium Authors. 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_BACKGROUND_FETCH_STORAGE_DATABASE_HELPERS_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_DATABASE_HELPERS_H_
+
+#include <string>
+
+#include "content/common/service_worker/service_worker_status_code.h"
+
+namespace content {
+
+namespace background_fetch {
+
+// The database schema is content/browser/background_fetch/storage/README.md.
+// When making any changes to these keys or the related functions, you must
+// update the README.md file as well.
+
+// Warning: registration |developer_id|s may contain kSeparator characters.
+const char kSeparator[] = "_";
+
+const char kRequestKeyPrefix[] = "bgfetch_request_";
+const char kRegistrationKeyPrefix[] = "bgfetch_registration_";
+const char kPendingRequestKeyPrefix[] = "bgfetch_pending_request_";
+const char kActiveRegistrationUniqueIdKeyPrefix[] =
+ "bgfetch_active_registration_unique_id_";
+
+std::string ActiveRegistrationUniqueIdKey(const std::string& developer_id);
+
+std::string RegistrationKey(const std::string& unique_id);
+
+std::string RequestKeyPrefix(const std::string& unique_id);
+
+std::string PendingRequestKeyPrefix(
+ int64_t registration_creation_microseconds_since_unix_epoch,
+ const std::string& unique_id);
+
+std::string PendingRequestKey(
+ int64_t registration_creation_microseconds_since_unix_epoch,
+ const std::string& unique_id,
+ int request_index);
+
+enum class DatabaseStatus { kOk, kFailed, kNotFound };
+
+DatabaseStatus ToDatabaseStatus(ServiceWorkerStatusCode status);
+
+} // namespace background_fetch
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_DATABASE_HELPERS_H_
diff --git a/chromium/content/browser/background_fetch/storage/database_task.cc b/chromium/content/browser/background_fetch/storage/database_task.cc
new file mode 100644
index 00000000000..d8139c4b842
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/database_task.cc
@@ -0,0 +1,38 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/storage/database_task.h"
+
+#include <utility>
+
+#include "content/browser/background_fetch/background_fetch_data_manager.h"
+#include "content/browser/background_fetch/storage/database_helpers.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+namespace background_fetch {
+
+void DatabaseTask::Finished() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ data_manager_->OnDatabaseTaskFinished(this);
+}
+
+void DatabaseTask::AddDatabaseTask(std::unique_ptr<DatabaseTask> task) {
+ data_manager_->AddDatabaseTask(std::move(task));
+}
+
+ServiceWorkerContextWrapper* DatabaseTask::service_worker_context() {
+ DCHECK(data_manager_->service_worker_context_);
+ return data_manager_->service_worker_context_.get();
+}
+
+std::set<std::string>& DatabaseTask::ref_counted_unique_ids() {
+ return data_manager_->ref_counted_unique_ids_;
+}
+
+} // namespace background_fetch
+
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/database_task.h b/chromium/content/browser/background_fetch/storage/database_task.h
new file mode 100644
index 00000000000..a29db2d44c5
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/database_task.h
@@ -0,0 +1,69 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_DATABASE_TASK_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_DATABASE_TASK_H_
+
+#include <memory>
+#include <set>
+#include <string>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "content/browser/background_fetch/background_fetch_registration_id.h"
+#include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h"
+
+namespace content {
+
+class BackgroundFetchDataManager;
+class ServiceWorkerContextWrapper;
+
+// Note that this also handles non-error cases where the NONE is NONE.
+using HandleBackgroundFetchErrorCallback =
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError)>;
+
+namespace background_fetch {
+
+// A DatabaseTask is an asynchronous "transaction" that needs to read/write the
+// Service Worker Database.
+//
+// Only one DatabaseTask can run at once per StoragePartition, and no other code
+// reads/writes Background Fetch keys, so each task effectively has an exclusive
+// lock, except that core Service Worker code may delete all keys for a
+// ServiceWorkerRegistration or the entire database at any time.
+class DatabaseTask {
+ public:
+ virtual ~DatabaseTask() = default;
+
+ virtual void Start() = 0;
+
+ protected:
+ explicit DatabaseTask(BackgroundFetchDataManager* data_manager)
+ : data_manager_(data_manager) {
+ DCHECK(data_manager_);
+ }
+
+ // Each task MUST call this once finished, even if exceptions occur, to
+ // release their lock and allow the next task to execute.
+ void Finished();
+
+ void AddDatabaseTask(std::unique_ptr<DatabaseTask> task);
+
+ ServiceWorkerContextWrapper* service_worker_context();
+
+ std::set<std::string>& ref_counted_unique_ids();
+
+ BackgroundFetchDataManager* data_manager() { return data_manager_; }
+
+ private:
+ BackgroundFetchDataManager* data_manager_; // Owns this.
+
+ DISALLOW_COPY_AND_ASSIGN(DatabaseTask);
+};
+
+} // namespace background_fetch
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_DATABASE_TASK_H_
diff --git a/chromium/content/browser/background_fetch/storage/delete_registration_task.cc b/chromium/content/browser/background_fetch/storage/delete_registration_task.cc
new file mode 100644
index 00000000000..09653f982b3
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/delete_registration_task.cc
@@ -0,0 +1,112 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/storage/delete_registration_task.h"
+
+#include <utility>
+
+#include "content/browser/background_fetch/background_fetch.pb.h"
+#include "content/browser/background_fetch/storage/database_helpers.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+
+namespace content {
+
+namespace background_fetch {
+
+namespace {
+#if DCHECK_IS_ON()
+// Checks that the |ActiveRegistrationUniqueIdKey| either does not exist, or is
+// associated with a different |unique_id| than the given one which should have
+// been already marked for deletion.
+void DCheckRegistrationNotActive(const std::string& unique_id,
+ const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kOk:
+ DCHECK_EQ(1u, data.size());
+ DCHECK_NE(unique_id, data[0])
+ << "Must call MarkRegistrationForDeletion before DeleteRegistration";
+ return;
+ case DatabaseStatus::kFailed:
+ return; // TODO(crbug.com/780025): Consider logging failure to UMA.
+ case DatabaseStatus::kNotFound:
+ return;
+ }
+}
+#endif // DCHECK_IS_ON()
+} // namespace
+
+DeleteRegistrationTask::DeleteRegistrationTask(
+ BackgroundFetchDataManager* data_manager,
+ int64_t service_worker_registration_id,
+ const std::string& unique_id,
+ HandleBackgroundFetchErrorCallback callback)
+ : DatabaseTask(data_manager),
+ service_worker_registration_id_(service_worker_registration_id),
+ unique_id_(unique_id),
+ callback_(std::move(callback)),
+ weak_factory_(this) {}
+
+DeleteRegistrationTask::~DeleteRegistrationTask() = default;
+
+void DeleteRegistrationTask::Start() {
+#if DCHECK_IS_ON()
+ // Get the registration |developer_id| to check it was deactivated.
+ service_worker_context()->GetRegistrationUserData(
+ service_worker_registration_id_, {RegistrationKey(unique_id_)},
+ base::Bind(&DeleteRegistrationTask::DidGetRegistration,
+ weak_factory_.GetWeakPtr()));
+#else
+ DidGetRegistration({}, SERVICE_WORKER_OK);
+#endif // DCHECK_IS_ON()
+}
+
+void DeleteRegistrationTask::DidGetRegistration(
+ const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status) {
+#if DCHECK_IS_ON()
+ if (ToDatabaseStatus(status) == DatabaseStatus::kOk) {
+ DCHECK_EQ(1u, data.size());
+ proto::BackgroundFetchRegistration registration_proto;
+ if (registration_proto.ParseFromString(data[0]) &&
+ registration_proto.has_developer_id()) {
+ service_worker_context()->GetRegistrationUserData(
+ service_worker_registration_id_,
+ {ActiveRegistrationUniqueIdKey(registration_proto.developer_id())},
+ base::Bind(&DCheckRegistrationNotActive, unique_id_));
+ } else {
+ NOTREACHED()
+ << "Database is corrupt"; // TODO(crbug.com/780027): Nuke it.
+ }
+ } else {
+ // TODO(crbug.com/780025): Log failure to UMA.
+ }
+#endif // DCHECK_IS_ON()
+
+ service_worker_context()->ClearRegistrationUserDataByKeyPrefixes(
+ service_worker_registration_id_,
+ {RegistrationKey(unique_id_), RequestKeyPrefix(unique_id_)},
+ base::Bind(&DeleteRegistrationTask::DidDeleteRegistration,
+ weak_factory_.GetWeakPtr()));
+}
+
+void DeleteRegistrationTask::DidDeleteRegistration(
+ ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kOk:
+ case DatabaseStatus::kNotFound:
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE);
+ Finished(); // Destroys |this|.
+ return;
+ case DatabaseStatus::kFailed:
+ std::move(callback_).Run(
+ blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ Finished(); // Destroys |this|.
+ return;
+ }
+}
+
+} // namespace background_fetch
+
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/delete_registration_task.h b/chromium/content/browser/background_fetch/storage/delete_registration_task.h
new file mode 100644
index 00000000000..4ac2bb5da35
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/delete_registration_task.h
@@ -0,0 +1,49 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_DELETE_REGISTRATION_TASK_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_DELETE_REGISTRATION_TASK_H_
+
+#include <string>
+#include <vector>
+
+#include "content/browser/background_fetch/storage/database_task.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+
+namespace content {
+
+namespace background_fetch {
+
+// Deletes Background Fetch registration entries from the database.
+class DeleteRegistrationTask : public background_fetch::DatabaseTask {
+ public:
+ DeleteRegistrationTask(BackgroundFetchDataManager* data_manager,
+ int64_t service_worker_registration_id,
+ const std::string& unique_id,
+ HandleBackgroundFetchErrorCallback callback);
+
+ ~DeleteRegistrationTask() override;
+
+ void Start() override;
+
+ private:
+ void DidGetRegistration(const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status);
+
+ void DidDeleteRegistration(ServiceWorkerStatusCode status);
+
+ int64_t service_worker_registration_id_;
+ std::string unique_id_;
+ HandleBackgroundFetchErrorCallback callback_;
+
+ base::WeakPtrFactory<DeleteRegistrationTask> weak_factory_; // Keep as last.
+
+ DISALLOW_COPY_AND_ASSIGN(DeleteRegistrationTask);
+};
+
+} // namespace background_fetch
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_DELETE_REGISTRATION_TASK_H_
diff --git a/chromium/content/browser/background_fetch/storage/get_developer_ids_task.cc b/chromium/content/browser/background_fetch/storage/get_developer_ids_task.cc
new file mode 100644
index 00000000000..9de40d9d9cf
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/get_developer_ids_task.cc
@@ -0,0 +1,63 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/storage/get_developer_ids_task.h"
+
+#include <vector>
+
+#include "content/browser/background_fetch/storage/database_helpers.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+
+namespace content {
+
+namespace background_fetch {
+
+GetDeveloperIdsTask::GetDeveloperIdsTask(
+ BackgroundFetchDataManager* data_manager,
+ int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback)
+ : DatabaseTask(data_manager),
+ service_worker_registration_id_(service_worker_registration_id),
+ origin_(origin),
+ callback_(std::move(callback)),
+ weak_factory_(this) {}
+
+GetDeveloperIdsTask::~GetDeveloperIdsTask() = default;
+
+void GetDeveloperIdsTask::Start() {
+ service_worker_context()->GetRegistrationUserKeysAndDataByKeyPrefix(
+ service_worker_registration_id_, {kActiveRegistrationUniqueIdKeyPrefix},
+ base::Bind(&GetDeveloperIdsTask::DidGetUniqueIds,
+ weak_factory_.GetWeakPtr()));
+}
+
+void GetDeveloperIdsTask::DidGetUniqueIds(
+ const base::flat_map<std::string, std::string>& data_map,
+ ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kNotFound:
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE,
+ {} /* No results */);
+ break;
+ case DatabaseStatus::kOk: {
+ auto ids = std::vector<std::string>();
+ ids.reserve(data_map.size());
+ for (const auto& pair : data_map)
+ ids.push_back(pair.first);
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE, ids);
+ break;
+ }
+ case DatabaseStatus::kFailed:
+ std::move(callback_).Run(
+ blink::mojom::BackgroundFetchError::STORAGE_ERROR,
+ {} /* No results */);
+ break;
+ }
+ Finished(); // Destroys |this|.
+}
+
+} // namespace background_fetch
+
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/get_developer_ids_task.h b/chromium/content/browser/background_fetch/storage/get_developer_ids_task.h
new file mode 100644
index 00000000000..207fac55f00
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/get_developer_ids_task.h
@@ -0,0 +1,55 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_DEVELOPER_IDS_TASK_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_DEVELOPER_IDS_TASK_H_
+
+#include <string>
+#include <utility>
+
+#include "base/callback_forward.h"
+#include "base/containers/flat_map.h"
+#include "content/browser/background_fetch/storage/database_task.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h"
+#include "url/origin.h"
+
+namespace content {
+
+namespace background_fetch {
+
+// Gets the developer ids for all active registrations - registrations that have
+// not completed.
+class GetDeveloperIdsTask : public DatabaseTask {
+ public:
+ GetDeveloperIdsTask(
+ BackgroundFetchDataManager* data_manager,
+ int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback);
+
+ ~GetDeveloperIdsTask() override;
+
+ // DatabaseTask implementation:
+ void Start() override;
+
+ private:
+ void DidGetUniqueIds(const base::flat_map<std::string, std::string>& data_map,
+ ServiceWorkerStatusCode status);
+
+ int64_t service_worker_registration_id_;
+ url::Origin origin_;
+
+ blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback_;
+
+ base::WeakPtrFactory<GetDeveloperIdsTask> weak_factory_; // Keep as last.
+
+ DISALLOW_COPY_AND_ASSIGN(GetDeveloperIdsTask);
+};
+
+} // namespace background_fetch
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_DEVELOPER_IDS_TASK_H_
diff --git a/chromium/content/browser/background_fetch/storage/get_registration_task.cc b/chromium/content/browser/background_fetch/storage/get_registration_task.cc
new file mode 100644
index 00000000000..dd779bf475e
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/get_registration_task.cc
@@ -0,0 +1,123 @@
+// Copyright 2017 The Chromium Authors. 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/background_fetch/storage/get_registration_task.h"
+
+#include <utility>
+
+#include "content/browser/background_fetch/background_fetch.pb.h"
+#include "content/browser/background_fetch/storage/database_helpers.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace background_fetch {
+
+GetRegistrationTask::GetRegistrationTask(
+ BackgroundFetchDataManager* data_manager,
+ int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ const std::string& developer_id,
+ GetRegistrationCallback callback)
+ : DatabaseTask(data_manager),
+ service_worker_registration_id_(service_worker_registration_id),
+ origin_(origin),
+ developer_id_(developer_id),
+ callback_(std::move(callback)),
+ weak_factory_(this) {}
+
+GetRegistrationTask::~GetRegistrationTask() = default;
+
+void GetRegistrationTask::Start() {
+ service_worker_context()->GetRegistrationUserData(
+ service_worker_registration_id_,
+ {ActiveRegistrationUniqueIdKey(developer_id_)},
+ base::Bind(&GetRegistrationTask::DidGetUniqueId,
+ weak_factory_.GetWeakPtr()));
+}
+
+void GetRegistrationTask::DidGetUniqueId(const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kNotFound:
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::INVALID_ID,
+ nullptr /* registration */);
+ Finished(); // Destroys |this|.
+ return;
+ case DatabaseStatus::kOk:
+ DCHECK_EQ(1u, data.size());
+ service_worker_context()->GetRegistrationUserData(
+ service_worker_registration_id_, {RegistrationKey(data[0])},
+ base::Bind(&GetRegistrationTask::DidGetRegistration,
+ weak_factory_.GetWeakPtr()));
+ return;
+ case DatabaseStatus::kFailed:
+ std::move(callback_).Run(
+ blink::mojom::BackgroundFetchError::STORAGE_ERROR,
+ nullptr /* registration */);
+ Finished(); // Destroys |this|.
+ return;
+ }
+}
+
+void GetRegistrationTask::DidGetRegistration(
+ const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kNotFound:
+ // The database is corrupt as there's no registration data despite there
+ // being an active developer_id pointing to it.
+ std::move(callback_).Run(
+ blink::mojom::BackgroundFetchError::STORAGE_ERROR,
+ nullptr /* registration */);
+ Finished(); // Destroys |this|.
+ return;
+ case DatabaseStatus::kOk:
+ DCHECK_EQ(1u, data.size());
+ CreateRegistration(data[0]);
+ return;
+ case DatabaseStatus::kFailed:
+ std::move(callback_).Run(
+ blink::mojom::BackgroundFetchError::STORAGE_ERROR,
+ nullptr /* registration */);
+ Finished(); // Destroys |this|.
+ return;
+ }
+}
+
+void GetRegistrationTask::CreateRegistration(
+ const std::string& registration_data) {
+ proto::BackgroundFetchRegistration registration_proto;
+ if (!registration_proto.ParseFromString(registration_data)) {
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::STORAGE_ERROR,
+ nullptr /* registration */);
+ Finished();
+ return;
+ }
+
+ auto registration = std::make_unique<BackgroundFetchRegistration>();
+ if (registration_proto.developer_id() != developer_id_ ||
+ !origin_.IsSameOriginWith(
+ url::Origin::Create(GURL(registration_proto.origin())))) {
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::STORAGE_ERROR,
+ nullptr /* registration */);
+ Finished();
+ return;
+ }
+
+ registration->developer_id = registration_proto.developer_id();
+ registration->unique_id = registration_proto.unique_id();
+
+ // TODO(delphick): Initialize all the other parts of the registration once
+ // they're persisted.
+
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE,
+ std::move(registration));
+ Finished();
+}
+
+} // namespace background_fetch
+
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/get_registration_task.h b/chromium/content/browser/background_fetch/storage/get_registration_task.h
new file mode 100644
index 00000000000..e4498f84904
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/get_registration_task.h
@@ -0,0 +1,63 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_REGISTRATION_TASK_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_REGISTRATION_TASK_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "content/browser/background_fetch/storage/database_task.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+#include "url/origin.h"
+
+namespace content {
+
+namespace background_fetch {
+
+// Gets an active Background Fetch registration entry from the database.
+class GetRegistrationTask : public DatabaseTask {
+ public:
+ using GetRegistrationCallback =
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError,
+ std::unique_ptr<BackgroundFetchRegistration>)>;
+
+ GetRegistrationTask(BackgroundFetchDataManager* data_manager,
+ int64_t service_worker_registration_id,
+ const url::Origin& origin,
+ const std::string& developer_id,
+ GetRegistrationCallback callback);
+
+ ~GetRegistrationTask() override;
+
+ // DatabaseTask implementation:
+ void Start() override;
+
+ private:
+ void DidGetUniqueId(const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status);
+
+ void DidGetRegistration(const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status);
+
+ void CreateRegistration(const std::string& registration_data);
+
+ int64_t service_worker_registration_id_;
+ url::Origin origin_;
+ std::string developer_id_;
+
+ GetRegistrationCallback callback_;
+
+ base::WeakPtrFactory<GetRegistrationTask> weak_factory_; // Keep as last.
+
+ DISALLOW_COPY_AND_ASSIGN(GetRegistrationTask);
+};
+
+} // namespace background_fetch
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_REGISTRATION_TASK_H_
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
new file mode 100644
index 00000000000..d665c8bcbb1
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc
@@ -0,0 +1,110 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/storage/mark_registration_for_deletion_task.h"
+
+#include <utility>
+
+#include "content/browser/background_fetch/background_fetch.pb.h"
+#include "content/browser/background_fetch/background_fetch_data_manager.h"
+#include "content/browser/background_fetch/storage/database_helpers.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+
+namespace content {
+
+namespace background_fetch {
+
+MarkRegistrationForDeletionTask::MarkRegistrationForDeletionTask(
+ BackgroundFetchDataManager* data_manager,
+ const BackgroundFetchRegistrationId& registration_id,
+ HandleBackgroundFetchErrorCallback callback)
+ : DatabaseTask(data_manager),
+ registration_id_(registration_id),
+ callback_(std::move(callback)),
+ weak_factory_(this) {}
+
+MarkRegistrationForDeletionTask::~MarkRegistrationForDeletionTask() = default;
+
+void MarkRegistrationForDeletionTask::Start() {
+ // Look up if there is already an active |unique_id| entry for this
+ // |developer_id|.
+ service_worker_context()->GetRegistrationUserData(
+ registration_id_.service_worker_registration_id(),
+ {ActiveRegistrationUniqueIdKey(registration_id_.developer_id()),
+ RegistrationKey(registration_id_.unique_id())},
+ base::Bind(&MarkRegistrationForDeletionTask::DidGetActiveUniqueId,
+ weak_factory_.GetWeakPtr()));
+}
+
+void MarkRegistrationForDeletionTask::DidGetActiveUniqueId(
+ const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kOk:
+ break;
+ case DatabaseStatus::kNotFound:
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::INVALID_ID);
+ Finished(); // Destroys |this|.
+ return;
+ case DatabaseStatus::kFailed:
+ std::move(callback_).Run(
+ blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ Finished(); // Destroys |this|.
+ return;
+ }
+
+ DCHECK_EQ(2u, data.size());
+
+ // If the |unique_id| does not match, then the registration identified by
+ // |registration_id_.unique_id()| was already deactivated.
+ if (data[0] != registration_id_.unique_id()) {
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::INVALID_ID);
+ Finished(); // Destroys |this|.
+ return;
+ }
+
+ proto::BackgroundFetchRegistration registration_proto;
+ if (registration_proto.ParseFromString(data[1]) &&
+ registration_proto.has_creation_microseconds_since_unix_epoch()) {
+ // 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(
+ registration_id_.service_worker_registration_id(),
+ {ActiveRegistrationUniqueIdKey(registration_id_.developer_id()),
+ PendingRequestKeyPrefix(
+ registration_proto.creation_microseconds_since_unix_epoch(),
+ registration_id_.unique_id())},
+ base::Bind(&MarkRegistrationForDeletionTask::DidDeactivate,
+ weak_factory_.GetWeakPtr()));
+ } else {
+ NOTREACHED() << "Database is corrupt"; // TODO(crbug.com/780027): Nuke it.
+ }
+}
+
+void MarkRegistrationForDeletionTask::DidDeactivate(
+ ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kOk:
+ case DatabaseStatus::kNotFound:
+ break;
+ case DatabaseStatus::kFailed:
+ std::move(callback_).Run(
+ blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ Finished(); // Destroys |this|.
+ return;
+ }
+
+ // If CleanupTask runs after this, it shouldn't clean up the
+ // |unique_id| as there may still be JavaScript references to it.
+ ref_counted_unique_ids().emplace(registration_id_.unique_id());
+
+ std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE);
+ Finished(); // Destroys |this|.
+}
+
+} // namespace background_fetch
+
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.h b/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.h
new file mode 100644
index 00000000000..d43a587fe86
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.h
@@ -0,0 +1,51 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_MARK_REGISTRATION_FOR_DELETION_TASK_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_MARK_REGISTRATION_FOR_DELETION_TASK_H_
+
+#include <string>
+#include <vector>
+
+#include "content/browser/background_fetch/storage/database_task.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+
+namespace content {
+
+namespace background_fetch {
+
+// Marks Background Fetch registrations for deletion from the database. This is
+// used when some parts of the registration may still be in use and cannot be
+// completely removed.
+class MarkRegistrationForDeletionTask : public background_fetch::DatabaseTask {
+ public:
+ MarkRegistrationForDeletionTask(
+ BackgroundFetchDataManager* data_manager,
+ const BackgroundFetchRegistrationId& registration_id,
+ HandleBackgroundFetchErrorCallback callback);
+
+ ~MarkRegistrationForDeletionTask() override;
+
+ void Start() override;
+
+ private:
+ void DidGetActiveUniqueId(const std::vector<std::string>& data,
+ ServiceWorkerStatusCode status);
+
+ void DidDeactivate(ServiceWorkerStatusCode status);
+
+ BackgroundFetchRegistrationId registration_id_;
+ HandleBackgroundFetchErrorCallback callback_;
+
+ base::WeakPtrFactory<MarkRegistrationForDeletionTask>
+ weak_factory_; // Keep as last.
+
+ DISALLOW_COPY_AND_ASSIGN(MarkRegistrationForDeletionTask);
+};
+
+} // namespace background_fetch
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_MARK_REGISTRATION_FOR_DELETION_TASK_H_
diff --git a/chromium/content/browser/background_sync/background_sync_manager.cc b/chromium/content/browser/background_sync/background_sync_manager.cc
index 06bcd97add3..c5fd8e3c799 100644
--- a/chromium/content/browser/background_sync/background_sync_manager.cc
+++ b/chromium/content/browser/background_sync/background_sync_manager.cc
@@ -285,7 +285,7 @@ BackgroundSyncManager::BackgroundSyncManager(
parameters_(new BackgroundSyncParameters()),
disabled_(false),
num_firing_registrations_(0),
- clock_(new base::DefaultClock()),
+ clock_(base::DefaultClock::GetInstance()),
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -324,7 +324,7 @@ void BackgroundSyncManager::InitImpl(base::OnceClosure callback) {
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&GetControllerParameters, service_worker_context_,
- base::Passed(base::MakeUnique<BackgroundSyncParameters>(
+ base::Passed(std::make_unique<BackgroundSyncParameters>(
*parameters_))),
base::BindOnce(&BackgroundSyncManager::InitDidGetControllerParameters,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
@@ -532,7 +532,7 @@ void BackgroundSyncManager::RegisterDidAskForPermission(
FROM_HERE,
base::BindOnce(
std::move(callback), BACKGROUND_SYNC_STATUS_OK,
- base::Passed(base::MakeUnique<BackgroundSyncRegistration>(
+ base::Passed(std::make_unique<BackgroundSyncRegistration>(
*existing_registration))));
return;
}
@@ -705,7 +705,7 @@ void BackgroundSyncManager::RegisterDidStore(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), BACKGROUND_SYNC_STATUS_OK,
- base::Passed(base::MakeUnique<BackgroundSyncRegistration>(
+ base::Passed(std::make_unique<BackgroundSyncRegistration>(
new_registration))));
}
@@ -822,7 +822,7 @@ void BackgroundSyncManager::GetRegistrationsImpl(
const BackgroundSyncRegistration& registration =
tag_and_registration.second;
out_registrations.push_back(
- base::MakeUnique<BackgroundSyncRegistration>(registration));
+ std::make_unique<BackgroundSyncRegistration>(registration));
}
}
diff --git a/chromium/content/browser/background_sync/background_sync_manager.h b/chromium/content/browser/background_sync/background_sync_manager.h
index 06fc25da562..c5b144e53e4 100644
--- a/chromium/content/browser/background_sync/background_sync_manager.h
+++ b/chromium/content/browser/background_sync/background_sync_manager.h
@@ -95,9 +95,9 @@ class CONTENT_EXPORT BackgroundSyncManager
return network_observer_.get();
}
- void set_clock(std::unique_ptr<base::Clock> clock) {
+ void set_clock(base::Clock* clock) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- clock_ = std::move(clock);
+ clock_ = clock;
}
// Called from DevTools
@@ -299,7 +299,7 @@ class CONTENT_EXPORT BackgroundSyncManager
std::unique_ptr<BackgroundSyncNetworkObserver> network_observer_;
- std::unique_ptr<base::Clock> clock_;
+ base::Clock* clock_;
base::WeakPtrFactory<BackgroundSyncManager> weak_ptr_factory_;
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 1e50d17844b..7b20c5bbcfe 100644
--- a/chromium/content/browser/background_sync/background_sync_manager_unittest.cc
+++ b/chromium/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -28,7 +28,7 @@
#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_dispatcher_host.h"
-#include "content/browser/service_worker/service_worker_registration_handle.h"
+#include "content/browser/service_worker/service_worker_registration_object_host.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/background_sync_parameters.h"
@@ -82,31 +82,6 @@ void UnregisterServiceWorkerCallback(bool* called,
*called = true;
}
-void DispatchSyncSuccessfulCallback(
- int* count,
- const scoped_refptr<ServiceWorkerVersion>& active_version,
- const ServiceWorkerVersion::LegacyStatusCallback& callback) {
- *count += 1;
- callback.Run(SERVICE_WORKER_OK);
-}
-
-void DispatchSyncFailedCallback(
- int* count,
- const scoped_refptr<ServiceWorkerVersion>& active_version,
- const ServiceWorkerVersion::LegacyStatusCallback& callback) {
- *count += 1;
- callback.Run(SERVICE_WORKER_ERROR_FAILED);
-}
-
-void DispatchSyncDelayedCallback(
- int* count,
- ServiceWorkerVersion::LegacyStatusCallback* out_callback,
- const scoped_refptr<ServiceWorkerVersion>& active_version,
- const ServiceWorkerVersion::LegacyStatusCallback& callback) {
- *count += 1;
- *out_callback = callback;
-}
-
} // namespace
class BackgroundSyncManagerTest : public testing::Test {
@@ -237,8 +212,7 @@ class BackgroundSyncManagerTest : public testing::Test {
new TestBackgroundSyncManager(helper_->context_wrapper());
background_sync_manager_.reset(test_background_sync_manager_);
- test_clock_ = new base::SimpleTestClock();
- background_sync_manager_->set_clock(base::WrapUnique(test_clock_));
+ background_sync_manager_->set_clock(&test_clock_);
// Many tests do not expect the sync event to fire immediately after
// register (and cleanup up the sync registrations). Tests can control when
@@ -273,7 +247,6 @@ class BackgroundSyncManagerTest : public testing::Test {
void DeleteBackgroundSyncManager() {
background_sync_manager_.reset();
test_background_sync_manager_ = nullptr;
- test_clock_ = nullptr;
}
bool Register(const BackgroundSyncRegistrationOptions& sync_options) {
@@ -380,32 +353,49 @@ class BackgroundSyncManagerTest : public testing::Test {
SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
}
+ void DispatchSyncStatusCallback(
+ ServiceWorkerStatusCode status,
+ scoped_refptr<ServiceWorkerVersion> active_version,
+ ServiceWorkerVersion::StatusCallback callback) {
+ sync_events_called_++;
+ std::move(callback).Run(status);
+ }
+
void InitSyncEventTest() {
- SetupForSyncEvent(base::BindRepeating(DispatchSyncSuccessfulCallback,
- &sync_events_called_));
+ SetupForSyncEvent(base::BindRepeating(
+ &BackgroundSyncManagerTest::DispatchSyncStatusCallback,
+ base::Unretained(this), SERVICE_WORKER_OK));
}
void InitFailedSyncEventTest() {
- SetupForSyncEvent(
- base::BindRepeating(DispatchSyncFailedCallback, &sync_events_called_));
+ SetupForSyncEvent(base::BindRepeating(
+ &BackgroundSyncManagerTest::DispatchSyncStatusCallback,
+ base::Unretained(this), SERVICE_WORKER_ERROR_FAILED));
+ }
+
+ void DispatchSyncDelayedCallback(
+ scoped_refptr<ServiceWorkerVersion> active_version,
+ ServiceWorkerVersion::StatusCallback callback) {
+ sync_events_called_++;
+ sync_fired_callback_ = std::move(callback);
}
void InitDelayedSyncEventTest() {
- SetupForSyncEvent(base::BindRepeating(DispatchSyncDelayedCallback,
- &sync_events_called_,
- &sync_fired_callback_));
+ SetupForSyncEvent(base::BindRepeating(
+ &BackgroundSyncManagerTest::DispatchSyncDelayedCallback,
+ base::Unretained(this)));
}
void RegisterAndVerifySyncEventDelayed(
const BackgroundSyncRegistrationOptions& sync_options) {
int sync_events_called = sync_events_called_;
- EXPECT_TRUE(sync_fired_callback_.is_null());
+ EXPECT_FALSE(sync_fired_callback_);
EXPECT_TRUE(Register(sync_options));
EXPECT_EQ(sync_events_called + 1, sync_events_called_);
EXPECT_TRUE(GetRegistration(sync_options_1_));
- EXPECT_FALSE(sync_fired_callback_.is_null());
+ EXPECT_TRUE(sync_fired_callback_);
}
void DeleteServiceWorkerAndStartOver() {
@@ -430,7 +420,7 @@ class BackgroundSyncManagerTest : public testing::Test {
std::unique_ptr<BackgroundSyncManager> background_sync_manager_;
std::unique_ptr<StoragePartitionImpl> storage_partition_impl_;
TestBackgroundSyncManager* test_background_sync_manager_ = nullptr;
- base::SimpleTestClock* test_clock_ = nullptr;
+ base::SimpleTestClock test_clock_;
int64_t sw_registration_id_1_;
int64_t sw_registration_id_2_;
@@ -447,7 +437,7 @@ class BackgroundSyncManagerTest : public testing::Test {
callback_registrations_;
ServiceWorkerStatusCode callback_sw_status_code_ = SERVICE_WORKER_OK;
int sync_events_called_ = 0;
- ServiceWorkerVersion::LegacyStatusCallback sync_fired_callback_;
+ ServiceWorkerVersion::StatusCallback sync_fired_callback_;
};
TEST_F(BackgroundSyncManagerTest, Register) {
@@ -469,17 +459,9 @@ TEST_F(BackgroundSyncManagerTest, RegisterWithoutLiveSWRegistration) {
ServiceWorkerProviderHost* provider_host =
sw_registration_1_->active_version()->provider_host();
ASSERT_TRUE(provider_host);
- int process_id = provider_host->process_id();
- int provider_id = provider_host->provider_id();
-
- // Remove the registration handle registered on the dispatcher host.
- ServiceWorkerDispatcherHost* dispatcher_host =
- helper_->context()->GetDispatcherHost(process_id);
- ServiceWorkerRegistrationHandle* handle =
- dispatcher_host->FindRegistrationHandle(provider_id,
- sw_registration_1_->id());
- dispatcher_host->UnregisterServiceWorkerRegistrationHandle(
- handle->handle_id());
+
+ // Remove the registration object host.
+ provider_host->registration_object_hosts_.clear();
// Ensure |sw_registration_1_| is the last reference to the registration.
ASSERT_TRUE(sw_registration_1_->HasOneRef());
@@ -840,12 +822,14 @@ TEST_F(BackgroundSyncManagerTest, ReregisterMidSyncFirstAttemptFails) {
EXPECT_TRUE(Register(sync_options_1_));
// The first sync attempt fails.
- sync_fired_callback_.Run(SERVICE_WORKER_ERROR_FAILED);
+ ASSERT_TRUE(sync_fired_callback_);
+ std::move(sync_fired_callback_).Run(SERVICE_WORKER_ERROR_FAILED);
base::RunLoop().RunUntilIdle();
// It should fire again since it was reregistered mid-sync.
EXPECT_TRUE(GetRegistration(sync_options_1_));
- sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ ASSERT_TRUE(sync_fired_callback_);
+ std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
EXPECT_FALSE(GetRegistration(sync_options_1_));
}
@@ -857,12 +841,14 @@ TEST_F(BackgroundSyncManagerTest, ReregisterMidSyncFirstAttemptSucceeds) {
EXPECT_TRUE(Register(sync_options_1_));
// The first sync event succeeds.
- sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ ASSERT_TRUE(sync_fired_callback_);
+ std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
// It should fire again since it was reregistered mid-sync.
EXPECT_TRUE(GetRegistration(sync_options_1_));
- sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ ASSERT_TRUE(sync_fired_callback_);
+ std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
EXPECT_FALSE(GetRegistration(sync_options_1_));
}
@@ -915,7 +901,8 @@ TEST_F(BackgroundSyncManagerTest, DisableWhileFiring) {
// Successfully complete the firing event. We can't verify that it actually
// completed but at least we can test that it doesn't crash.
- sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ ASSERT_TRUE(sync_fired_callback_);
+ std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
}
@@ -1003,7 +990,8 @@ TEST_F(BackgroundSyncManagerTest, DelayMidSync) {
RegisterAndVerifySyncEventDelayed(sync_options_1_);
// Finish firing the event and verify that the registration is removed.
- sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ ASSERT_TRUE(sync_fired_callback_);
+ std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, sync_events_called_);
EXPECT_FALSE(GetRegistration(sync_options_1_));
@@ -1015,7 +1003,8 @@ TEST_F(BackgroundSyncManagerTest, BadBackendMidSync) {
RegisterAndVerifySyncEventDelayed(sync_options_1_);
test_background_sync_manager_->set_corrupt_backend(true);
- sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ ASSERT_TRUE(sync_fired_callback_);
+ std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
// The backend should now be disabled because it couldn't unregister the
@@ -1031,7 +1020,8 @@ TEST_F(BackgroundSyncManagerTest, UnregisterServiceWorkerMidSync) {
RegisterAndVerifySyncEventDelayed(sync_options_1_);
UnregisterServiceWorker(sw_registration_id_1_);
- sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ ASSERT_TRUE(sync_fired_callback_);
+ std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
// The backend isn't disabled, but the first service worker registration is
// gone.
@@ -1169,7 +1159,8 @@ TEST_F(BackgroundSyncManagerTest, WakeBrowserCalled) {
GetController()->run_in_background_min_ms()));
// Finish the sync.
- sync_fired_callback_.Run(SERVICE_WORKER_OK);
+ ASSERT_TRUE(sync_fired_callback_);
+ std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(GetController()->run_in_background_enabled());
}
@@ -1199,7 +1190,7 @@ TEST_F(BackgroundSyncManagerTest, TwoAttempts) {
test_background_sync_manager_->delayed_task_delta());
// Fire again and this time it should permanently fail.
- test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_clock_.Advance(test_background_sync_manager_->delayed_task_delta());
test_background_sync_manager_->RunDelayedTask();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(GetRegistration(sync_options_1_));
@@ -1217,7 +1208,7 @@ TEST_F(BackgroundSyncManagerTest, ThreeAttempts) {
// The second run will fail but it will setup a timer to try again.
base::TimeDelta first_delta =
test_background_sync_manager_->delayed_task_delta();
- test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_clock_.Advance(test_background_sync_manager_->delayed_task_delta());
test_background_sync_manager_->RunDelayedTask();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(GetRegistration(sync_options_1_));
@@ -1226,7 +1217,7 @@ TEST_F(BackgroundSyncManagerTest, ThreeAttempts) {
EXPECT_LT(first_delta, test_background_sync_manager_->delayed_task_delta());
// The third run will permanently fail.
- test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_clock_.Advance(test_background_sync_manager_->delayed_task_delta());
test_background_sync_manager_->RunDelayedTask();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(GetRegistration(sync_options_1_));
@@ -1243,8 +1234,8 @@ TEST_F(BackgroundSyncManagerTest, WaitsFullDelayTime) {
// Fire again one second before it's ready to retry. Expect it to reschedule
// the delay timer for one more second.
- test_clock_->Advance(test_background_sync_manager_->delayed_task_delta() -
- base::TimeDelta::FromSeconds(1));
+ test_clock_.Advance(test_background_sync_manager_->delayed_task_delta() -
+ base::TimeDelta::FromSeconds(1));
test_background_sync_manager_->RunDelayedTask();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(GetRegistration(sync_options_1_));
@@ -1252,7 +1243,7 @@ TEST_F(BackgroundSyncManagerTest, WaitsFullDelayTime) {
test_background_sync_manager_->delayed_task_delta());
// Fire one second later and it should fail permanently.
- test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ test_clock_.Advance(base::TimeDelta::FromSeconds(1));
test_background_sync_manager_->RunDelayedTask();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(GetRegistration(sync_options_1_));
@@ -1270,7 +1261,7 @@ TEST_F(BackgroundSyncManagerTest, RetryOnBrowserRestart) {
base::TimeDelta delta = test_background_sync_manager_->delayed_task_delta();
CreateBackgroundSyncManager();
InitFailedSyncEventTest();
- test_clock_->Advance(delta);
+ test_clock_.Advance(delta);
InitBackgroundSyncManager();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(GetRegistration(sync_options_1_));
@@ -1288,7 +1279,7 @@ TEST_F(BackgroundSyncManagerTest, RescheduleOnBrowserRestart) {
base::TimeDelta delta = test_background_sync_manager_->delayed_task_delta();
CreateBackgroundSyncManager();
InitFailedSyncEventTest();
- test_clock_->Advance(delta - base::TimeDelta::FromSeconds(1));
+ test_clock_.Advance(delta - base::TimeDelta::FromSeconds(1));
InitBackgroundSyncManager();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(GetRegistration(sync_options_1_));
@@ -1307,7 +1298,7 @@ TEST_F(BackgroundSyncManagerTest, RetryIfClosedMidSync) {
// fire once and then fail permanently.
CreateBackgroundSyncManager();
InitFailedSyncEventTest();
- test_clock_->Advance(delta);
+ test_clock_.Advance(delta);
InitBackgroundSyncManager();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(GetRegistration(sync_options_1_));
@@ -1321,7 +1312,7 @@ TEST_F(BackgroundSyncManagerTest, AllTestsEventuallyFire) {
EXPECT_TRUE(Register(sync_options_1_));
// Run it a second time.
- test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_clock_.Advance(test_background_sync_manager_->delayed_task_delta());
test_background_sync_manager_->RunDelayedTask();
base::RunLoop().RunUntilIdle();
@@ -1333,7 +1324,7 @@ TEST_F(BackgroundSyncManagerTest, AllTestsEventuallyFire) {
EXPECT_GT(delay_delta, test_background_sync_manager_->delayed_task_delta());
while (test_background_sync_manager_->IsDelayedTaskScheduled()) {
- test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_clock_.Advance(test_background_sync_manager_->delayed_task_delta());
test_background_sync_manager_->RunDelayedTask();
EXPECT_FALSE(test_background_sync_manager_->IsDelayedTaskScheduled());
base::RunLoop().RunUntilIdle();
@@ -1353,7 +1344,7 @@ TEST_F(BackgroundSyncManagerTest, LastChance) {
EXPECT_TRUE(GetRegistration(sync_options_1_));
// Run it again.
- test_clock_->Advance(test_background_sync_manager_->delayed_task_delta());
+ test_clock_.Advance(test_background_sync_manager_->delayed_task_delta());
test_background_sync_manager_->RunDelayedTask();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(GetRegistration(sync_options_1_));
diff --git a/chromium/content/browser/bad_message.h b/chromium/content/browser/bad_message.h
index b435e289779..68d2a000655 100644
--- a/chromium/content/browser/bad_message.h
+++ b/chromium/content/browser/bad_message.h
@@ -29,40 +29,40 @@ enum BadMessageReason {
RFH_SANDBOX_FLAGS = 3,
RFH_NO_PROXY_TO_PARENT = 4,
RPH_DESERIALIZATION_FAILED = 5,
- RVH_CAN_ACCESS_FILES_OF_PAGE_STATE = 6,
+ OBSOLETE_RVH_CAN_ACCESS_FILES_OF_PAGE_STATE = 6,
RFH_FILE_CHOOSER_PATH = 7,
- RWH_SYNTHETIC_GESTURE = 8,
- RWH_FOCUS = 9, // obsolete; no longer used
- RWH_BLUR = 10,
+ OBSOLETE_RWH_SYNTHETIC_GESTURE = 8,
+ OBSOLETE_RWH_FOCUS = 9,
+ OBSOLETE_RWH_BLUR = 10,
RWH_SHARED_BITMAP = 11,
RWH_BAD_ACK_MESSAGE = 12,
- RWHVA_SHARED_MEMORY = 13,
+ OBSOLETE_RWHVA_SHARED_MEMORY = 13,
SERVICE_WORKER_BAD_URL = 14,
- WC_INVALID_FRAME_SOURCE = 15,
- RWHVM_UNEXPECTED_FRAME_TYPE = 16, // obsolete; no longer used
+ OBSOLETE_WC_INVALID_FRAME_SOURCE = 15,
+ OBSOLETE_RWHVM_UNEXPECTED_FRAME_TYPE = 16,
RFPH_DETACH = 17,
DFH_BAD_EMBEDDER_MESSAGE = 18,
NC_AUTO_SUBFRAME = 19,
CSDH_NOT_RECOGNIZED = 20,
- DSMF_OPEN_STORAGE = 21, // obsolete; no longer used
+ OBSOLETE_DSMF_OPEN_STORAGE = 21,
DSMF_LOAD_STORAGE = 22,
- DBMF_INVALID_ORIGIN_ON_OPEN = 23, // obsolete; no longer used
- DBMF_DB_NOT_OPEN_ON_MODIFY = 24, // obsolete; no longer used
- DBMF_DB_NOT_OPEN_ON_CLOSE = 25, // obsolete; no longer used
- DBMF_INVALID_ORIGIN_ON_SQLITE_ERROR = 26, // obsolete; no longer used
+ OBSOLETE_DBMF_INVALID_ORIGIN_ON_OPEN = 23,
+ OBSOLETE_DBMF_DB_NOT_OPEN_ON_MODIFY = 24,
+ OBSOLETE_DBMF_DB_NOT_OPEN_ON_CLOSE = 25,
+ OBSOLETE_DBMF_INVALID_ORIGIN_ON_SQLITE_ERROR = 26,
RDH_INVALID_PRIORITY = 27,
RDH_REQUEST_NOT_TRANSFERRING = 28,
RDH_BAD_DOWNLOAD = 29,
- NMF_NO_PERMISSION_SHOW = 30, // obsolete; no longer used
- NMF_NO_PERMISSION_CLOSE = 31, // obsolete; no longer used
- NMF_NO_PERMISSION_VERIFY = 32, // obsolete; no longer used
+ OBSOLETE_NMF_NO_PERMISSION_SHOW = 30,
+ OBSOLETE_NMF_NO_PERMISSION_CLOSE = 31,
+ OBSOLETE_NMF_NO_PERMISSION_VERIFY = 32,
MH_INVALID_MIDI_PORT = 33,
MH_SYS_EX_PERMISSION = 34,
ACDH_REGISTER = 35,
ACDH_UNREGISTER = 36,
ACDH_SET_SPAWNING = 37,
ACDH_SELECT_CACHE = 38,
- ACDH_SELECT_CACHE_FOR_WORKER = 39,
+ OBSOLETE_ACDH_SELECT_CACHE_FOR_WORKER = 39,
ACDH_SELECT_CACHE_FOR_SHARED_WORKER = 40,
ACDH_MARK_AS_FOREIGN_ENTRY = 41,
ACDH_PENDING_REPLY_IN_GET_STATUS = 42,
@@ -72,59 +72,59 @@ enum BadMessageReason {
ACDH_PENDING_REPLY_IN_SWAP_CACHE = 46,
ACDH_SWAP_CACHE = 47,
SWDH_NOT_HANDLED = 48,
- SWDH_REGISTER_BAD_URL = 49,
- SWDH_REGISTER_NO_HOST = 50,
- SWDH_REGISTER_CANNOT = 51,
- SWDH_UNREGISTER_BAD_URL = 52,
- SWDH_UNREGISTER_NO_HOST = 53,
- SWDH_UNREGISTER_CANNOT = 54,
- SWDH_GET_REGISTRATION_BAD_URL = 55,
- SWDH_GET_REGISTRATION_NO_HOST = 56,
- SWDH_GET_REGISTRATION_CANNOT = 57,
- SWDH_GET_REGISTRATION_FOR_READY_NO_HOST = 58,
- SWDH_GET_REGISTRATION_FOR_READY_ALREADY_IN_PROGRESS = 59,
+ OBSOLETE_SWDH_REGISTER_BAD_URL = 49,
+ OBSOLETE_SWDH_REGISTER_NO_HOST = 50,
+ OBSOLETE_SWDH_REGISTER_CANNOT = 51,
+ OBSOLETE_SWDH_UNREGISTER_BAD_URL = 52,
+ OBSOLETE_SWDH_UNREGISTER_NO_HOST = 53,
+ OBSOLETE_SWDH_UNREGISTER_CANNOT = 54,
+ OBSOLETE_SWDH_GET_REGISTRATION_BAD_URL = 55,
+ OBSOLETE_SWDH_GET_REGISTRATION_NO_HOST = 56,
+ OBSOLETE_SWDH_GET_REGISTRATION_CANNOT = 57,
+ OBSOLETE_SWDH_GET_REGISTRATION_FOR_READY_NO_HOST = 58,
+ OBSOLETE_SWDH_GET_REGISTRATION_FOR_READY_ALREADY_IN_PROGRESS = 59,
SWDH_POST_MESSAGE = 60,
- SWDH_PROVIDER_CREATED_NO_HOST = 61, // obsolete; no longer used
- SWDH_PROVIDER_DESTROYED_NO_HOST = 62, // obsolete; no longer used
- SWDH_SET_HOSTED_VERSION_NO_HOST = 63,
+ OBSOLETE_SWDH_PROVIDER_CREATED_NO_HOST = 61,
+ OBSOLETE_SWDH_PROVIDER_DESTROYED_NO_HOST = 62,
+ OBSOLETE_SWDH_SET_HOSTED_VERSION_NO_HOST = 63,
OBSOLETE_SWDH_SET_HOSTED_VERSION = 64,
- SWDH_WORKER_SCRIPT_LOAD_NO_HOST = 65,
+ OBSOLETE_SWDH_WORKER_SCRIPT_LOAD_NO_HOST = 65,
SWDH_INCREMENT_WORKER_BAD_HANDLE = 66,
SWDH_DECREMENT_WORKER_BAD_HANDLE = 67,
- SWDH_INCREMENT_REGISTRATION_BAD_HANDLE = 68,
- SWDH_DECREMENT_REGISTRATION_BAD_HANDLE = 69,
+ OBSOLETE_SWDH_INCREMENT_REGISTRATION_BAD_HANDLE = 68,
+ OBSOLETE_SWDH_DECREMENT_REGISTRATION_BAD_HANDLE = 69,
SWDH_TERMINATE_BAD_HANDLE = 70,
- FAMF_APPEND_ITEM_TO_BLOB = 71,
- FAMF_APPEND_SHARED_MEMORY_TO_BLOB = 72,
- FAMF_MALFORMED_STREAM_URL = 73,
- FAMF_APPEND_ITEM_TO_STREAM = 74,
- FAMF_APPEND_SHARED_MEMORY_TO_STREAM = 75,
- IDBDH_CAN_READ_FILE = 76,
- IDBDH_GET_OR_TERMINATE = 77,
+ OBSOLETE_FAMF_APPEND_ITEM_TO_BLOB = 71,
+ OBSOLETE_FAMF_APPEND_SHARED_MEMORY_TO_BLOB = 72,
+ OBSOLETE_FAMF_MALFORMED_STREAM_URL = 73,
+ OBSOLETE_FAMF_APPEND_ITEM_TO_STREAM = 74,
+ OBSOLETE_FAMF_APPEND_SHARED_MEMORY_TO_STREAM = 75,
+ OBSOLETE_IDBDH_CAN_READ_FILE = 76,
+ OBSOLETE_IDBDH_GET_OR_TERMINATE = 77,
RFMF_SET_COOKIE_BAD_ORIGIN = 78,
RFMF_GET_COOKIES_BAD_ORIGIN = 79,
- SWDH_GET_REGISTRATIONS_NO_HOST = 80,
- SWDH_GET_REGISTRATIONS_INVALID_ORIGIN = 81,
- AOAH_UNAUTHORIZED_URL = 82,
+ OBSOLETE_SWDH_GET_REGISTRATIONS_NO_HOST = 80,
+ OBSOLETE_SWDH_GET_REGISTRATIONS_INVALID_ORIGIN = 81,
+ OBSOLETE_AOAH_UNAUTHORIZED_URL = 82,
BDH_INVALID_SERVICE_ID = 83,
- RFH_COMMIT_DESERIALIZATION_FAILED = 84,
+ OBSOLETE_RFH_COMMIT_DESERIALIZATION_FAILED = 84,
BDH_INVALID_CHARACTERISTIC_ID = 85,
- SWDH_UPDATE_NO_HOST = 86,
- SWDH_UPDATE_BAD_REGISTRATION_ID = 87,
- SWDH_UPDATE_CANNOT = 88,
- SWDH_UNREGISTER_BAD_REGISTRATION_ID = 89,
+ OBSOLETE_SWDH_UPDATE_NO_HOST = 86,
+ OBSOLETE_SWDH_UPDATE_BAD_REGISTRATION_ID = 87,
+ OBSOLETE_SWDH_UPDATE_CANNOT = 88,
+ OBSOLETE_SWDH_UNREGISTER_BAD_REGISTRATION_ID = 89,
BDH_INVALID_WRITE_VALUE_LENGTH = 90,
- WC_MEMORY_CACHE_RESOURCE_BAD_SECURITY_INFO = 91, // obsolete; no longer used
- WC_RENDERER_DID_NAVIGATE_BAD_SECURITY_INFO = 92, // obsolete; no longer used
+ OBSOLETE_WC_MEMORY_CACHE_RESOURCE_BAD_SECURITY_INFO = 91,
+ OBSOLETE_WC_RENDERER_DID_NAVIGATE_BAD_SECURITY_INFO = 92,
OBSOLETE_BDH_DUPLICATE_REQUEST_DEVICE_ID = 93,
CSDH_INVALID_ORIGIN = 94,
RDH_ILLEGAL_ORIGIN = 95,
- RDH_UNAUTHORIZED_HEADER_REQUEST = 96,
+ OBSOLETE_RDH_UNAUTHORIZED_HEADER_REQUEST = 96,
RDH_INVALID_URL = 97,
- BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED = 98,
+ OBSOLETE_BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED = 98,
RFH_OWNER_PROPERTY = 99,
- BDH_EMPTY_OR_INVALID_FILTERS = 100, // obsolete; no longer used
- WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO = 101, // obsolete; not used
+ OBSOLETE_BDH_EMPTY_OR_INVALID_FILTERS = 100,
+ OBSOLETE_WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO = 101,
RFMF_RENDERER_FAKED_ITS_OWN_DEATH = 102,
DWNLD_INVALID_SAVABLE_RESOURCE_LINKS_RESPONSE = 103,
DWNLD_INVALID_SERIALIZE_AS_MHTML_RESPONSE = 104,
@@ -142,18 +142,18 @@ enum BadMessageReason {
BDH_CONSTRUCTION_FAILED = 116,
BDH_INVALID_REFCOUNT_OPERATION = 117,
BDH_INVALID_URL_OPERATION = 118,
- IDBDH_INVALID_ORIGIN = 119,
+ OBSOLETE_IDBDH_INVALID_ORIGIN = 119,
RFH_FAIL_PROVISIONAL_LOAD_NO_HANDLE = 120,
- RFH_FAIL_PROVISIONAL_LOAD_NO_ERROR = 121,
+ OBSOLETE_RFH_FAIL_PROVISIONAL_LOAD_NO_ERROR = 121,
NI_IN_PAGE_NAVIGATION = 122,
RPH_MOJO_PROCESS_ERROR = 123,
- DBMF_INVALID_ORIGIN_ON_GET_SPACE = 124,
- DBMF_INVALID_ORIGIN_ON_MODIFIED = 125, // obsolete; not used
- DBMF_INVALID_ORIGIN_ON_CLOSED = 126, // obsolete; not used
+ OBSOLETE_DBMF_INVALID_ORIGIN_ON_GET_SPACE = 124,
+ OBSOLETE_DBMF_INVALID_ORIGIN_ON_MODIFIED = 125,
+ OBSOLETE_DBMF_INVALID_ORIGIN_ON_CLOSED = 126,
WSI_INVALID_HEADER_VALUE = 127,
- SWDH_SET_HOSTED_VERSION_INVALID_HOST = 128,
- SWDH_SET_HOSTED_VERSION_PROCESS_MISMATCH = 129,
- MSDH_INVALID_FRAME_ID = 130,
+ OBSOLETE_SWDH_SET_HOSTED_VERSION_INVALID_HOST = 128,
+ OBSOLETE_SWDH_SET_HOSTED_VERSION_PROCESS_MISMATCH = 129,
+ OBSOLETE_MSDH_INVALID_FRAME_ID = 130,
SDH_INVALID_PORT_RANGE = 131,
SCO_INVALID_ARGUMENT = 132,
RFH_INCONSISTENT_DEVTOOLS_MESSAGE = 133,
@@ -165,28 +165,28 @@ enum BadMessageReason {
BDH_DISALLOWED_ORIGIN = 139,
ARH_CREATED_STREAM_WITHOUT_AUTHORIZATION = 140,
MDDH_INVALID_DEVICE_TYPE_REQUEST = 141,
- MDDH_UNAUTHORIZED_ORIGIN = 142, // obsolete; no longer used
- SWDH_ENABLE_NAVIGATION_PRELOAD_NO_HOST = 143,
- SWDH_ENABLE_NAVIGATION_PRELOAD_INVALID_ORIGIN = 144,
- SWDH_ENABLE_NAVIGATION_PRELOAD_BAD_REGISTRATION_ID = 145,
+ OBSOLETE_MDDH_UNAUTHORIZED_ORIGIN = 142,
+ OBSOLETE_SWDH_ENABLE_NAVIGATION_PRELOAD_NO_HOST = 143,
+ OBSOLETE_SWDH_ENABLE_NAVIGATION_PRELOAD_INVALID_ORIGIN = 144,
+ OBSOLETE_SWDH_ENABLE_NAVIGATION_PRELOAD_BAD_REGISTRATION_ID = 145,
RDH_TRANSFERRING_REQUEST_NOT_FOUND = 146, // Disabled - crbug.com/659613.
RDH_TRANSFERRING_NONNAVIGATIONAL_REQUEST = 147,
- SWDH_GET_NAVIGATION_PRELOAD_STATE_NO_HOST = 148,
- SWDH_GET_NAVIGATION_PRELOAD_STATE_INVALID_ORIGIN = 149,
- SWDH_GET_NAVIGATION_PRELOAD_STATE_BAD_REGISTRATION_ID = 150,
- SWDH_SET_NAVIGATION_PRELOAD_HEADER_NO_HOST = 151,
- SWDH_SET_NAVIGATION_PRELOAD_HEADER_INVALID_ORIGIN = 152,
- SWDH_SET_NAVIGATION_PRELOAD_HEADER_BAD_REGISTRATION_ID = 153,
- SWDH_SET_NAVIGATION_PRELOAD_HEADER_BAD_VALUE = 154,
+ OBSOLETE_SWDH_GET_NAVIGATION_PRELOAD_STATE_NO_HOST = 148,
+ OBSOLETE_SWDH_GET_NAVIGATION_PRELOAD_STATE_INVALID_ORIGIN = 149,
+ OBSOLETE_SWDH_GET_NAVIGATION_PRELOAD_STATE_BAD_REGISTRATION_ID = 150,
+ OBSOLETE_SWDH_SET_NAVIGATION_PRELOAD_HEADER_NO_HOST = 151,
+ OBSOLETE_SWDH_SET_NAVIGATION_PRELOAD_HEADER_INVALID_ORIGIN = 152,
+ OBSOLETE_SWDH_SET_NAVIGATION_PRELOAD_HEADER_BAD_REGISTRATION_ID = 153,
+ OBSOLETE_SWDH_SET_NAVIGATION_PRELOAD_HEADER_BAD_VALUE = 154,
MDDH_INVALID_SUBSCRIPTION_REQUEST = 155,
- MDDH_INVALID_UNSUBSCRIPTION_REQUEST = 156,
- AOAH_NONSENSE_DEVICE_ID = 157,
+ OBSOLETE_MDDH_INVALID_UNSUBSCRIPTION_REQUEST = 156,
+ OBSOLETE_AOAH_NONSENSE_DEVICE_ID = 157,
BDH_INVALID_OPTIONS = 158,
RFH_DID_ADD_CONSOLE_MESSAGE_BAD_SEVERITY = 159,
AIRH_VOLUME_OUT_OF_RANGE = 160,
BDH_INVALID_DESCRIPTOR_ID = 161,
- RWH_INVALID_BEGIN_FRAME_ACK_DID_NOT_SWAP = 162,
- RWH_INVALID_BEGIN_FRAME_ACK_COMPOSITOR_FRAME = 163,
+ OBSOLETE_RWH_INVALID_BEGIN_FRAME_ACK_DID_NOT_SWAP = 162,
+ OBSOLETE_RWH_INVALID_BEGIN_FRAME_ACK_COMPOSITOR_FRAME = 163,
BFSI_INVALID_DEVELOPER_ID = 164,
BFSI_INVALID_REQUESTS = 165,
BFSI_INVALID_TITLE = 166,
@@ -196,13 +196,21 @@ enum BadMessageReason {
RFH_ILLEGAL_UPLOAD_PARAMS = 170,
RFH_BASE_URL_FOR_DATA_URL_SPECIFIED = 171,
RFPH_ILLEGAL_UPLOAD_PARAMS = 172,
- SWDH_PROVIDER_CREATED_ILLEGAL_TYPE = 173, // obsolete; no longer used
+ OBSOLETE_SWDH_PROVIDER_CREATED_ILLEGAL_TYPE = 173,
SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_NOT_WINDOW = 174,
SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_CONTROLLER = 175,
SWDH_PROVIDER_CREATED_DUPLICATE_ID = 176,
SWDH_PROVIDER_CREATED_BAD_ID = 177,
RFH_KEEP_ALIVE_HANDLE_REQUESTED_INCORRECTLY = 178,
BFSI_INVALID_UNIQUE_ID = 179,
+ BPE_UNEXPECTED_MESSAGE_BEFORE_BPGM_CREATION = 180,
+ WEBUI_SEND_FROM_UNAUTHORIZED_PROCESS = 181,
+ CPFC_RESIZE_PARAMS_CHANGED_LOCAL_SURFACE_ID_UNCHANGED = 182,
+ BPG_RESIZE_PARAMS_CHANGED_LOCAL_SURFACE_ID_UNCHANGED = 183,
+ RFH_NEGATIVE_SELECTION_START_OFFSET = 184,
+ WEBUI_BAD_SCHEME_ACCESS = 185,
+ CSDH_UNEXPECTED_OPERATION = 186,
+ RMF_BAD_URL_CACHEABLE_METADATA = 187,
// Please add new elements here. The naming convention is abbreviated class
// name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/chromium/content/browser/battery_monitor_browsertest.cc b/chromium/content/browser/battery_monitor_browsertest.cc
index 500a8167d0e..b68bf4bfa4b 100644
--- a/chromium/content/browser/battery_monitor_browsertest.cc
+++ b/chromium/content/browser/battery_monitor_browsertest.cc
@@ -74,7 +74,7 @@ class BatteryMonitorTest : public ContentBrowserTest {
BatteryMonitorTest() = default;
void SetUpOnMainThread() override {
- mock_battery_monitor_ = base::MakeUnique<MockBatteryMonitor>();
+ mock_battery_monitor_ = std::make_unique<MockBatteryMonitor>();
// Because Device Service also runs in this process(browser process), here
// we can directly set our binder to intercept interface requests against
// it.
diff --git a/chromium/content/browser/blob_storage/DEPS b/chromium/content/browser/blob_storage/DEPS
deleted file mode 100644
index 9c44314db21..00000000000
--- a/chromium/content/browser/blob_storage/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
- "+storage/public/interfaces",
-]
diff --git a/chromium/content/browser/blob_storage/blob_dispatcher_host.cc b/chromium/content/browser/blob_storage/blob_dispatcher_host.cc
index da775662b02..557e1292d31 100644
--- a/chromium/content/browser/blob_storage/blob_dispatcher_host.cc
+++ b/chromium/content/browser/blob_storage/blob_dispatcher_host.cc
@@ -81,16 +81,29 @@ void BlobDispatcherHost::OnChannelClosing() {
bool BlobDispatcherHost::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
// Note: The only time a renderer sends a blob status message is to cancel.
- IPC_BEGIN_MESSAGE_MAP(BlobDispatcherHost, message)
- IPC_MESSAGE_HANDLER(BlobStorageMsg_RegisterBlob, OnRegisterBlob)
- IPC_MESSAGE_HANDLER(BlobStorageMsg_MemoryItemResponse, OnMemoryItemResponse)
- IPC_MESSAGE_HANDLER(BlobStorageMsg_SendBlobStatus, OnCancelBuildingBlob)
- IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementRefCount, OnIncrementBlobRefCount)
- IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementRefCount, OnDecrementBlobRefCount)
- IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicURL, OnRegisterPublicBlobURL)
- IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicURL, OnRevokePublicBlobURL)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
+ if (features::IsMojoBlobsEnabled()) {
+ IPC_BEGIN_MESSAGE_MAP(BlobDispatcherHost, message)
+ IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicURL,
+ OnRegisterPublicBlobURL)
+ IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicURL, OnRevokePublicBlobURL)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ } else {
+ IPC_BEGIN_MESSAGE_MAP(BlobDispatcherHost, message)
+ IPC_MESSAGE_HANDLER(BlobStorageMsg_RegisterBlob, OnRegisterBlob)
+ IPC_MESSAGE_HANDLER(BlobStorageMsg_MemoryItemResponse,
+ OnMemoryItemResponse)
+ IPC_MESSAGE_HANDLER(BlobStorageMsg_SendBlobStatus, OnCancelBuildingBlob)
+ IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementRefCount,
+ OnIncrementBlobRefCount)
+ IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementRefCount,
+ OnDecrementBlobRefCount)
+ IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicURL,
+ OnRegisterPublicBlobURL)
+ IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicURL, OnRevokePublicBlobURL)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ }
return handled;
}
@@ -157,7 +170,9 @@ void BlobDispatcherHost::OnRegisterBlob(
// originally created by other processes? If so, is that cool?
break;
}
+ case storage::DataElement::TYPE_RAW_FILE:
case storage::DataElement::TYPE_UNKNOWN:
+ case storage::DataElement::TYPE_DATA_PIPE:
case storage::DataElement::TYPE_DISK_CACHE_ENTRY: {
NOTREACHED(); // Should have been caught by IPC deserialization.
break;
@@ -167,6 +182,7 @@ void BlobDispatcherHost::OnRegisterBlob(
HostedBlobState hosted_state(transport_host_.StartBuildingBlob(
uuid, content_type, content_disposition, descriptions, context,
+ file_system_context_,
base::Bind(&BlobDispatcherHost::SendMemoryRequest, base::Unretained(this),
uuid),
base::Bind(&BlobDispatcherHost::SendFinalBlobStatus,
diff --git a/chromium/content/browser/blob_storage/blob_dispatcher_host_unittest.cc b/chromium/content/browser/blob_storage/blob_dispatcher_host_unittest.cc
index 6bb5934810a..a836dee1a89 100644
--- a/chromium/content/browser/blob_storage/blob_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/blob_storage/blob_dispatcher_host_unittest.cc
@@ -12,8 +12,10 @@
#include "base/memory/shared_memory.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
+#include "base/test/scoped_feature_list.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/common/fileapi/webblob_messages.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -95,7 +97,7 @@ class BlobDispatcherHostTest : public testing::Test {
: chrome_blob_storage_context_(
ChromeBlobStorageContext::GetFor(&browser_context_)) {
file_system_context_ =
- CreateFileSystemContextForTesting(NULL, base::FilePath());
+ CreateFileSystemContextForTesting(nullptr, base::FilePath());
host_ = new TestableBlobDispatcherHost(chrome_blob_storage_context_,
file_system_context_.get(), &sink_);
}
@@ -106,6 +108,7 @@ class BlobDispatcherHostTest : public testing::Test {
if (!command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) {
command_line->AppendSwitch(switches::kDisableKillAfterBadIPC);
}
+ scoped_feature_list_.InitAndDisableFeature(features::kMojoBlobs);
// We run the run loop to initialize the chrome blob storage context.
base::RunLoop().RunUntilIdle();
context_ = chrome_blob_storage_context_->context();
@@ -262,6 +265,7 @@ class BlobDispatcherHostTest : public testing::Test {
return BlobStatusIsPending(context_->GetBlobStatus(uuid));
}
+ base::test::ScopedFeatureList scoped_feature_list_;
IPC::TestSink sink_;
TestBrowserThreadBundle browser_thread_bundle_;
TestBrowserContext browser_context_;
diff --git a/chromium/content/browser/blob_storage/blob_internals_url_loader.cc b/chromium/content/browser/blob_storage/blob_internals_url_loader.cc
index 688e1e40dfa..b5e2c98012a 100644
--- a/chromium/content/browser/blob_storage/blob_internals_url_loader.cc
+++ b/chromium/content/browser/blob_storage/blob_internals_url_loader.cc
@@ -40,7 +40,7 @@ void StartBlobInternalsURLLoader(
CHECK_EQ(result, MOJO_RESULT_OK);
client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
- ResourceRequestCompletionStatus status(net::OK);
+ network::URLLoaderCompletionStatus status(net::OK);
status.encoded_data_length = output.size();
status.encoded_body_length = output.size();
client->OnComplete(status);
diff --git a/chromium/content/browser/blob_storage/blob_registry_wrapper.cc b/chromium/content/browser/blob_storage/blob_registry_wrapper.cc
index 9f769e2f6d3..03b270823ec 100644
--- a/chromium/content/browser/blob_storage/blob_registry_wrapper.cc
+++ b/chromium/content/browser/blob_storage/blob_registry_wrapper.cc
@@ -8,6 +8,7 @@
#include "content/browser/child_process_security_policy_impl.h"
#include "content/public/common/content_features.h"
#include "storage/browser/blob/blob_registry_impl.h"
+#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/fileapi/file_system_context.h"
namespace content {
@@ -58,12 +59,11 @@ BlobRegistryWrapper::BlobRegistryWrapper() {
DCHECK(features::IsMojoBlobsEnabled());
}
-void BlobRegistryWrapper::Bind(
- int process_id,
- storage::mojom::BlobRegistryRequest request) {
+void BlobRegistryWrapper::Bind(int process_id,
+ blink::mojom::BlobRegistryRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
blob_registry_->Bind(std::move(request),
- base::MakeUnique<BindingDelegate>(process_id));
+ std::make_unique<BindingDelegate>(process_id));
}
BlobRegistryWrapper::~BlobRegistryWrapper() {}
@@ -72,8 +72,9 @@ void BlobRegistryWrapper::InitializeOnIOThread(
scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
scoped_refptr<storage::FileSystemContext> file_system_context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- blob_registry_ = base::MakeUnique<storage::BlobRegistryImpl>(
- blob_storage_context->context(), std::move(file_system_context));
+ blob_registry_ = std::make_unique<storage::BlobRegistryImpl>(
+ blob_storage_context->context()->AsWeakPtr(),
+ std::move(file_system_context));
}
} // namespace content
diff --git a/chromium/content/browser/blob_storage/blob_registry_wrapper.h b/chromium/content/browser/blob_storage/blob_registry_wrapper.h
index 42d980b5545..4f8531f1671 100644
--- a/chromium/content/browser/blob_storage/blob_registry_wrapper.h
+++ b/chromium/content/browser/blob_storage/blob_registry_wrapper.h
@@ -7,7 +7,7 @@
#include "base/memory/ref_counted.h"
#include "content/public/browser/browser_thread.h"
-#include "storage/public/interfaces/blobs.mojom.h"
+#include "third_party/WebKit/common/blob/blob_registry.mojom.h"
namespace storage {
class BlobRegistryImpl;
@@ -31,8 +31,7 @@ class BlobRegistryWrapper
scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
scoped_refptr<storage::FileSystemContext> file_system_context);
- void Bind(int process_id,
- storage::mojom::BlobRegistryRequest request);
+ void Bind(int process_id, blink::mojom::BlobRegistryRequest request);
private:
BlobRegistryWrapper();
diff --git a/chromium/content/browser/blob_storage/blob_transport_host_unittest.cc b/chromium/content/browser/blob_storage/blob_transport_host_unittest.cc
index 41c31fe64ee..e9561d4f602 100644
--- a/chromium/content/browser/blob_storage/blob_transport_host_unittest.cc
+++ b/chromium/content/browser/blob_storage/blob_transport_host_unittest.cc
@@ -116,6 +116,7 @@ class BlobTransportHostTest : public testing::Test {
status_called_ = false;
*storage = host_.StartBuildingBlob(
uuid, kContentType, kContentDisposition, descriptions, &context_,
+ nullptr,
base::Bind(&BlobTransportHostTest::RequestMemoryCallback,
base::Unretained(this)),
base::Bind(&BlobTransportHostTest::StatusCallback,
diff --git a/chromium/content/browser/blob_storage/blob_url_browsertest.cc b/chromium/content/browser/blob_storage/blob_url_browsertest.cc
index db20d8e2268..c74d2578ddf 100644
--- a/chromium/content/browser/blob_storage/blob_url_browsertest.cc
+++ b/chromium/content/browser/blob_storage/blob_url_browsertest.cc
@@ -71,7 +71,7 @@ IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToUniqueOriginBlob) {
IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToSameOriginBlob) {
// Using an http page, click a link that opens a popup to a same-origin blob.
GURL url = embedded_test_server()->GetURL("chromium.org", "/title1.html");
- url::Origin origin(url);
+ url::Origin origin = url::Origin::Create(url);
NavigateToURL(shell(), url);
ShellAddedObserver new_shell_observer;
@@ -104,7 +104,7 @@ IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToSameOriginBlobWithAuthority) {
// Using an http page, click a link that opens a popup to a same-origin blob
// that has a spoofy authority section applied. This should be blocked.
GURL url = embedded_test_server()->GetURL("chromium.org", "/title1.html");
- url::Origin origin(url);
+ url::Origin origin = url::Origin::Create(url);
NavigateToURL(shell(), url);
ShellAddedObserver new_shell_observer;
@@ -142,7 +142,7 @@ IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, ReplaceStateToAddAuthorityToBlob) {
// history.replaceState from a validly loaded blob URL shouldn't allow adding
// an authority to the inner URL, which would be spoofy.
GURL url = embedded_test_server()->GetURL("chromium.org", "/title1.html");
- url::Origin origin(url);
+ url::Origin origin = url::Origin::Create(url);
NavigateToURL(shell(), url);
ShellAddedObserver new_shell_observer;
diff --git a/chromium/content/browser/blob_storage/blob_url_loader_factory.cc b/chromium/content/browser/blob_storage/blob_url_loader_factory.cc
index 920a1ea0c68..2b159286fb1 100644
--- a/chromium/content/browser/blob_storage/blob_url_loader_factory.cc
+++ b/chromium/content/browser/blob_storage/blob_url_loader_factory.cc
@@ -28,7 +28,6 @@
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/blob/blob_url_request_job.h"
#include "storage/browser/blob/mojo_blob_reader.h"
-#include "storage/browser/fileapi/file_system_context.h"
namespace content {
@@ -45,8 +44,7 @@ class BlobURLLoader : public storage::MojoBlobReader::Delegate,
BlobURLLoader(mojom::URLLoaderRequest url_loader_request,
const ResourceRequest& request,
mojom::URLLoaderClientPtr client,
- std::unique_ptr<storage::BlobDataHandle> blob_handle,
- storage::FileSystemContext* file_system_context)
+ std::unique_ptr<storage::BlobDataHandle> blob_handle)
: binding_(this, std::move(url_loader_request)),
client_(std::move(client)),
blob_handle_(std::move(blob_handle)),
@@ -55,14 +53,12 @@ class BlobURLLoader : public storage::MojoBlobReader::Delegate,
// PostTask since it might destruct.
base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&BlobURLLoader::Start, weak_factory_.GetWeakPtr(),
- request, base::WrapRefCounted(file_system_context)));
+ FROM_HERE, base::BindOnce(&BlobURLLoader::Start,
+ weak_factory_.GetWeakPtr(), request));
}
private:
- void Start(const ResourceRequest& request,
- scoped_refptr<storage::FileSystemContext> file_system_context) {
+ void Start(const ResourceRequest& request) {
if (!blob_handle_) {
OnComplete(net::ERR_FILE_NOT_FOUND, 0);
delete this;
@@ -96,8 +92,7 @@ class BlobURLLoader : public storage::MojoBlobReader::Delegate,
}
}
- storage::MojoBlobReader::Create(file_system_context.get(),
- blob_handle_.get(), byte_range_,
+ storage::MojoBlobReader::Create(blob_handle_.get(), byte_range_,
base::WrapUnique(this));
}
@@ -160,7 +155,7 @@ class BlobURLLoader : public storage::MojoBlobReader::Delegate,
response.mime_type = mime_type;
// TODO(jam): some of this code can be shared with
- // content/network/url_loader_impl.h
+ // content/network/url_loader.h
client_->OnReceiveResponse(response, base::nullopt, nullptr);
sent_headers_ = true;
@@ -189,13 +184,13 @@ class BlobURLLoader : public storage::MojoBlobReader::Delegate,
status_code, nullptr, nullptr, 0, 0);
client_->OnReceiveResponse(response, base::nullopt, nullptr);
}
- ResourceRequestCompletionStatus request_complete_data;
+ network::URLLoaderCompletionStatus status;
// TODO(kinuko): We should probably set the error_code here,
// while it makes existing tests fail. crbug.com/732750
- request_complete_data.completion_time = base::TimeTicks::Now();
- request_complete_data.encoded_body_length = total_written_bytes;
- request_complete_data.decoded_body_length = total_written_bytes;
- client_->OnComplete(request_complete_data);
+ status.completion_time = base::TimeTicks::Now();
+ status.encoded_body_length = total_written_bytes;
+ status.decoded_body_length = total_written_bytes;
+ client_->OnComplete(status);
}
mojo::Binding<mojom::URLLoader> binding_;
@@ -219,11 +214,9 @@ class BlobURLLoader : public storage::MojoBlobReader::Delegate,
// static
scoped_refptr<BlobURLLoaderFactory> BlobURLLoaderFactory::Create(
- BlobContextGetter blob_storage_context_getter,
- scoped_refptr<storage::FileSystemContext> file_system_context) {
+ BlobContextGetter blob_storage_context_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- auto factory = base::MakeRefCounted<BlobURLLoaderFactory>(
- std::move(file_system_context));
+ auto factory = base::MakeRefCounted<BlobURLLoaderFactory>();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&BlobURLLoaderFactory::InitializeOnIO, factory,
@@ -239,9 +232,7 @@ void BlobURLLoaderFactory::HandleRequest(
std::move(request)));
}
-BlobURLLoaderFactory::BlobURLLoaderFactory(
- scoped_refptr<storage::FileSystemContext> file_system_context)
- : file_system_context_(std::move(file_system_context)) {}
+BlobURLLoaderFactory::BlobURLLoaderFactory() {}
BlobURLLoaderFactory::~BlobURLLoaderFactory() {}
@@ -261,10 +252,9 @@ void BlobURLLoaderFactory::CreateLoaderAndStart(
mojom::URLLoaderRequest loader,
const ResourceRequest& request,
mojom::URLLoaderClientPtr client,
- std::unique_ptr<storage::BlobDataHandle> blob_handle,
- storage::FileSystemContext* file_system_context) {
+ std::unique_ptr<storage::BlobDataHandle> blob_handle) {
new BlobURLLoader(std::move(loader), request, std::move(client),
- std::move(blob_handle), file_system_context);
+ std::move(blob_handle));
}
void BlobURLLoaderFactory::CreateLoaderAndStart(
@@ -281,7 +271,7 @@ void BlobURLLoaderFactory::CreateLoaderAndStart(
blob_handle = blob_storage_context_->GetBlobDataFromPublicURL(request.url);
}
CreateLoaderAndStart(std::move(loader), request, std::move(client),
- std::move(blob_handle), file_system_context_.get());
+ std::move(blob_handle));
}
void BlobURLLoaderFactory::Clone(mojom::URLLoaderFactoryRequest request) {
diff --git a/chromium/content/browser/blob_storage/blob_url_loader_factory.h b/chromium/content/browser/blob_storage/blob_url_loader_factory.h
index 11a2af8ff65..5393eb2eaa5 100644
--- a/chromium/content/browser/blob_storage/blob_url_loader_factory.h
+++ b/chromium/content/browser/blob_storage/blob_url_loader_factory.h
@@ -16,7 +16,6 @@
namespace storage {
class BlobDataHandle;
class BlobStorageContext;
-class FileSystemContext;
}
namespace content {
@@ -32,8 +31,7 @@ class BlobURLLoaderFactory
base::OnceCallback<base::WeakPtr<storage::BlobStorageContext>()>;
static CONTENT_EXPORT scoped_refptr<BlobURLLoaderFactory> Create(
- BlobContextGetter blob_storage_context_getter,
- scoped_refptr<storage::FileSystemContext> file_system_context);
+ BlobContextGetter blob_storage_context_getter);
// Creates a URLLoaderFactory interface pointer for serving blob requests.
// Called on the UI thread.
@@ -47,8 +45,7 @@ class BlobURLLoaderFactory
mojom::URLLoaderRequest url_loader_request,
const ResourceRequest& request,
mojom::URLLoaderClientPtr client,
- std::unique_ptr<storage::BlobDataHandle> blob_handle,
- storage::FileSystemContext* file_system_context);
+ std::unique_ptr<storage::BlobDataHandle> blob_handle);
// mojom::URLLoaderFactory implementation:
void CreateLoaderAndStart(mojom::URLLoaderRequest loader,
@@ -67,15 +64,13 @@ class BlobURLLoaderFactory
template <typename T, typename... Args>
friend scoped_refptr<T> base::MakeRefCounted(Args&&... args);
- BlobURLLoaderFactory(
- scoped_refptr<storage::FileSystemContext> file_system_context);
+ BlobURLLoaderFactory();
~BlobURLLoaderFactory() override;
void InitializeOnIO(BlobContextGetter blob_storage_context_getter);
void BindOnIO(mojom::URLLoaderFactoryRequest request);
base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
- scoped_refptr<storage::FileSystemContext> file_system_context_;
// Used on the IO thread.
mojo::BindingSet<mojom::URLLoaderFactory> loader_factory_bindings_;
diff --git a/chromium/content/browser/blob_storage/blob_url_unittest.cc b/chromium/content/browser/blob_storage/blob_url_unittest.cc
index dbfa815e6b8..b0df6c9367b 100644
--- a/chromium/content/browser/blob_storage/blob_url_unittest.cc
+++ b/chromium/content/browser/blob_storage/blob_url_unittest.cc
@@ -143,8 +143,7 @@ class BlobURLRequestJobTest : public testing::TestWithParam<bool> {
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
return new BlobURLRequestJob(request, network_delegate,
- test_->GetHandleFromBuilder(),
- test_->file_system_context_.get());
+ test_->GetHandleFromBuilder());
}
private:
@@ -181,7 +180,7 @@ class BlobURLRequestJobTest : public testing::TestWithParam<bool> {
disk_cache_backend_.get(), kTestDiskCacheKey1, kTestDiskCacheData1);
url_request_job_factory_.SetProtocolHandler(
- "blob", base::MakeUnique<MockProtocolHandler>(this));
+ "blob", std::make_unique<MockProtocolHandler>(this));
url_request_context_.set_job_factory(&url_request_job_factory_);
}
@@ -195,7 +194,7 @@ class BlobURLRequestJobTest : public testing::TestWithParam<bool> {
void SetUpFileSystem() {
// Prepare file system.
file_system_context_ =
- CreateFileSystemContextForTesting(NULL, temp_dir_.GetPath());
+ CreateFileSystemContextForTesting(nullptr, temp_dir_.GetPath());
file_system_context_->OpenFileSystem(
GURL(kFileSystemURLOrigin), kFileSystemType,
@@ -284,8 +283,7 @@ class BlobURLRequestJobTest : public testing::TestWithParam<bool> {
scoped_refptr<BlobURLLoaderFactory> factory =
BlobURLLoaderFactory::Create(
base::BindOnce(&BlobURLRequestJobTest::GetStorageContext,
- base::Unretained(this)),
- file_system_context_);
+ base::Unretained(this)));
base::RunLoop().RunUntilIdle();
factory->CreateLoaderAndStart(mojo::MakeRequest(&url_loader), 0, 0,
mojom::kURLLoadOptionNone, request,
@@ -342,7 +340,8 @@ class BlobURLRequestJobTest : public testing::TestWithParam<bool> {
*expected_result += std::string(kTestDiskCacheData1);
blob_data_->AppendFileSystemFile(temp_file_system_file1_, 3, 4,
- temp_file_system_file_modification_time1_);
+ temp_file_system_file_modification_time1_,
+ file_system_context_);
*expected_result += std::string(kTestFileSystemFileData1 + 3, 4);
blob_data_->AppendData(kTestData2 + 4, 5);
@@ -352,7 +351,8 @@ class BlobURLRequestJobTest : public testing::TestWithParam<bool> {
*expected_result += std::string(kTestFileData2 + 5, 6);
blob_data_->AppendFileSystemFile(temp_file_system_file2_, 6, 7,
- temp_file_system_file_modification_time2_);
+ temp_file_system_file_modification_time2_,
+ file_system_context_);
*expected_result += std::string(kTestFileSystemFileData2 + 6, 7);
}
@@ -467,7 +467,7 @@ TEST_P(BlobURLRequestJobTest, TestGetSimpleFileSystemFileRequest) {
SetUpFileSystem();
blob_data_->AppendFileSystemFile(temp_file_system_file1_, 0,
std::numeric_limits<uint64_t>::max(),
- base::Time());
+ base::Time(), file_system_context_);
TestSuccessNonrangeRequest(kTestFileSystemFileData1,
arraysize(kTestFileSystemFileData1) - 1);
}
@@ -480,27 +480,29 @@ TEST_P(BlobURLRequestJobTest, TestGetLargeFileSystemFileRequest) {
large_data.append(1, static_cast<char>(i % 256));
const char kFilename[] = "LargeBlob.dat";
- WriteFileSystemFile(kFilename, large_data.data(), large_data.size(), NULL);
+ WriteFileSystemFile(kFilename, large_data.data(), large_data.size(), nullptr);
blob_data_->AppendFileSystemFile(GetFileSystemURL(kFilename), 0,
std::numeric_limits<uint64_t>::max(),
- base::Time());
+ base::Time(), file_system_context_);
TestSuccessNonrangeRequest(large_data, large_data.size());
}
TEST_P(BlobURLRequestJobTest, TestGetNonExistentFileSystemFileRequest) {
SetUpFileSystem();
GURL non_existent_file = GetFileSystemURL("non-existent.dat");
- blob_data_->AppendFileSystemFile(
- non_existent_file, 0, std::numeric_limits<uint64_t>::max(), base::Time());
+ blob_data_->AppendFileSystemFile(non_existent_file, 0,
+ std::numeric_limits<uint64_t>::max(),
+ base::Time(), file_system_context_);
TestErrorRequest(404);
}
TEST_P(BlobURLRequestJobTest, TestGetInvalidFileSystemFileRequest) {
SetUpFileSystem();
GURL invalid_file;
- blob_data_->AppendFileSystemFile(
- invalid_file, 0, std::numeric_limits<uint64_t>::max(), base::Time());
+ blob_data_->AppendFileSystemFile(invalid_file, 0,
+ std::numeric_limits<uint64_t>::max(),
+ base::Time(), file_system_context_);
TestErrorRequest(500);
}
@@ -508,14 +510,16 @@ TEST_P(BlobURLRequestJobTest, TestGetChangedFileSystemFileRequest) {
SetUpFileSystem();
base::Time old_time = temp_file_system_file_modification_time1_ -
base::TimeDelta::FromSeconds(10);
- blob_data_->AppendFileSystemFile(temp_file_system_file1_, 0, 3, old_time);
+ blob_data_->AppendFileSystemFile(temp_file_system_file1_, 0, 3, old_time,
+ file_system_context_);
TestErrorRequest(404);
}
TEST_P(BlobURLRequestJobTest, TestGetSlicedFileSystemFileRequest) {
SetUpFileSystem();
blob_data_->AppendFileSystemFile(temp_file_system_file1_, 2, 4,
- temp_file_system_file_modification_time1_);
+ temp_file_system_file_modification_time1_,
+ file_system_context_);
std::string result(kTestFileSystemFileData1 + 2, 4);
TestSuccessNonrangeRequest(result, 4);
}
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 325736ab142..bf41a25bcd2 100644
--- a/chromium/content/browser/blob_storage/chrome_blob_storage_context.cc
+++ b/chromium/content/browser/blob_storage/chrome_blob_storage_context.cc
@@ -35,8 +35,6 @@ using storage::BlobStorageContext;
namespace content {
namespace {
-const FilePath::CharType kBlobStorageContextKeyName[] =
- FILE_PATH_LITERAL("content_blob_storage_context");
const FilePath::CharType kBlobStorageParentDirectory[] =
FILE_PATH_LITERAL("blob_storage");
@@ -87,7 +85,7 @@ ChromeBlobStorageContext* ChromeBlobStorageContext::GetFor(
new ChromeBlobStorageContext();
context->SetUserData(
kBlobStorageContextKeyName,
- base::MakeUnique<UserDataAdapter<ChromeBlobStorageContext>>(
+ std::make_unique<UserDataAdapter<ChromeBlobStorageContext>>(
blob.get()));
// Check first to avoid memory leak in unittests.
@@ -145,11 +143,13 @@ void ChromeBlobStorageContext::InitializeOnIOThread(
std::unique_ptr<BlobHandle> ChromeBlobStorageContext::CreateMemoryBackedBlob(
const char* data,
- size_t length) {
+ size_t length,
+ const std::string& content_type) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::string uuid(base::GenerateGUID());
storage::BlobDataBuilder blob_data_builder(uuid);
+ blob_data_builder.set_content_type(content_type);
blob_data_builder.AppendData(data, length);
std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
@@ -197,7 +197,7 @@ void ChromeBlobStorageContext::DeleteOnCorrectThread() const {
storage::BlobStorageContext* GetBlobStorageContext(
ChromeBlobStorageContext* blob_storage_context) {
if (!blob_storage_context)
- return NULL;
+ return nullptr;
return blob_storage_context->context();
}
@@ -223,4 +223,6 @@ bool GetBodyBlobDataHandles(ResourceRequestBody* body,
return true;
}
+const char kBlobStorageContextKeyName[] = "content_blob_storage_context";
+
} // namespace content
diff --git a/chromium/content/browser/blob_storage/chrome_blob_storage_context.h b/chromium/content/browser/blob_storage/chrome_blob_storage_context.h
index 00b61232c39..2412f15c5fb 100644
--- a/chromium/content/browser/blob_storage/chrome_blob_storage_context.h
+++ b/chromium/content/browser/blob_storage/chrome_blob_storage_context.h
@@ -57,8 +57,10 @@ class CONTENT_EXPORT ChromeBlobStorageContext
storage::BlobStorageContext* context() const { return context_.get(); }
// Returns a NULL scoped_ptr on failure.
- std::unique_ptr<BlobHandle> CreateMemoryBackedBlob(const char* data,
- size_t length);
+ std::unique_ptr<BlobHandle> CreateMemoryBackedBlob(
+ const char* data,
+ size_t length,
+ const std::string& content_type);
// Returns a NULL scoped_ptr on failure.
std::unique_ptr<BlobHandle> CreateFileBackedBlob(
@@ -101,6 +103,8 @@ bool GetBodyBlobDataHandles(ResourceRequestBody* body,
ResourceContext* resource_context,
BlobHandles* blob_handles);
+extern const char kBlobStorageContextKeyName[];
+
} // namespace content
#endif // CONTENT_BROWSER_FILEAPI_CHROME_BLOB_STORAGE_CONTEXT_H_
diff --git a/chromium/content/browser/bluetooth/bluetooth_allowed_devices_unittest.cc b/chromium/content/browser/bluetooth/bluetooth_allowed_devices_unittest.cc
index f62cbd9348b..ba6220bfd7d 100644
--- a/chromium/content/browser/bluetooth/bluetooth_allowed_devices_unittest.cc
+++ b/chromium/content/browser/bluetooth/bluetooth_allowed_devices_unittest.cc
@@ -14,8 +14,10 @@ using device::BluetoothUUID;
namespace content {
namespace {
-const url::Origin kTestOrigin1(GURL("https://www.example1.com"));
-const url::Origin kTestOrigin2(GURL("https://www.example2.com"));
+const url::Origin kTestOrigin1 =
+ url::Origin::Create(GURL("https://www.example1.com"));
+const url::Origin kTestOrigin2 =
+ url::Origin::Create(GURL("https://www.example2.com"));
const std::string kDeviceAddress1 = "00:00:00";
const std::string kDeviceAddress2 = "11:11:11";
diff --git a/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc b/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
index 3beb85b93e9..1f54fa0fd5b 100644
--- a/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
+++ b/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
@@ -42,35 +42,40 @@ namespace {
// displayed levels.
//
// RSSI values from UMA in RecordRSSISignalStrength are charted here:
-// https://goo.gl/photos/pCoAkF7mPyza9B1k7 (2016-12-08)
+// https://photos.app.goo.gl/6R0ksxWzBsfvrbXH2 (2017-10-18)
// with a copy-paste of table data at every 5dBm:
// dBm CDF* Histogram Bucket Quantity (hand drawn estimate)
-// -100 00.0% -
-// -95 00.4% --
-// -90 01.9% ---
-// -85 05.1% ---
-// -80 09.2% ----
-// -75 14.9% -----
-// -70 22.0% ------
-// -65 32.4% --------
-// -60 47.9% ---------
-// -55 60.4% --------
-// -50 72.8% ---------
-// -45 85.5% -------
-// -40 94.5% -----
-// -35 97.4% ---
-// -30 99.0% --
-// -25 99.7% -
+// -100 00.26%
+// -95 01.22% ---
+// -90 04.14% -----------
+// -85 11.24% ----------------------------
+// -80 18.29% ----------------------------
+// -75 27.13% -----------------------------------
+// -70 37.72% ------------------------------------------
+// -65 49.42% ----------------------------------------------
+// -60 62.91% -----------------------------------------------------
+// -55 74.35% ---------------------------------------------
+// -50 83.07% ----------------------------------
+// -45 88.43% ---------------------
+// -40 92.41% ---------------
+// -35 94.84% ---------
+// -30 95.96% ----
+// -25 96.60% --
+// -20 96.90% -
+// -15 97.07%
+// -10 97.21%
+// -5 97.34%
+// 0 97.47%
//
// CDF: Cumulative Distribution Function:
// https://en.wikipedia.org/wiki/Cumulative_distribution_function
//
// Conversion to signal strengths is done by selecting 4 threshold points
// equally spaced through the CDF.
-const int k20thPercentileRSSI = -71;
-const int k40thPercentileRSSI = -63;
-const int k60thPercentileRSSI = -55;
-const int k80thPercentileRSSI = -47;
+const int k20thPercentileRSSI = -79;
+const int k40thPercentileRSSI = -69;
+const int k60thPercentileRSSI = -61;
+const int k80thPercentileRSSI = -52;
} // namespace
@@ -218,7 +223,7 @@ std::unique_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter(
// devices so performing a Dual scan will find devices that the API is not
// able to interact with. To avoid wasting power and confusing users with
// devices they are not able to interact with, we only perform an LE Scan.
- auto discovery_filter = base::MakeUnique<device::BluetoothDiscoveryFilter>(
+ auto discovery_filter = std::make_unique<device::BluetoothDiscoveryFilter>(
device::BLUETOOTH_TRANSPORT_LE);
for (const BluetoothUUID& service : services) {
discovery_filter->AddUUID(service);
diff --git a/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc b/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc
index 42e689d8d34..cb23903c1eb 100644
--- a/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc
+++ b/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc
@@ -13,25 +13,25 @@ TEST_F(BluetoothDeviceChooserControllerTest, CalculateSignalStrengthLevel) {
EXPECT_EQ(
0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-128));
EXPECT_EQ(
- 0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-72));
+ 0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-80));
EXPECT_EQ(
- 1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-71));
+ 1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-79));
EXPECT_EQ(
- 1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-64));
+ 1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-70));
EXPECT_EQ(
- 2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-63));
+ 2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-69));
EXPECT_EQ(
- 2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-56));
+ 2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-62));
EXPECT_EQ(
- 3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-55));
+ 3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-61));
EXPECT_EQ(
- 3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-48));
+ 3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-53));
EXPECT_EQ(
- 4, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-47));
+ 4, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-52));
EXPECT_EQ(
4, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(127));
}
diff --git a/chromium/content/browser/bluetooth/frame_connected_bluetooth_devices.cc b/chromium/content/browser/bluetooth/frame_connected_bluetooth_devices.cc
index f36b44cbc85..e64676e7745 100644
--- a/chromium/content/browser/bluetooth/frame_connected_bluetooth_devices.cc
+++ b/chromium/content/browser/bluetooth/frame_connected_bluetooth_devices.cc
@@ -64,7 +64,7 @@ void FrameConnectedBluetoothDevices::Insert(
}
device_address_to_id_map_[connection->GetDeviceAddress()] = device_id;
auto gatt_connection_and_client =
- base::MakeUnique<GATTConnectionAndServerClient>(std::move(connection),
+ std::make_unique<GATTConnectionAndServerClient>(std::move(connection),
std::move(client));
device_id_to_connection_map_[device_id] =
std::move(gatt_connection_and_client);
diff --git a/chromium/content/browser/bluetooth/frame_connected_bluetooth_devices_unittest.cc b/chromium/content/browser/bluetooth/frame_connected_bluetooth_devices_unittest.cc
index 4c784217ea6..1cf49611197 100644
--- a/chromium/content/browser/bluetooth/frame_connected_bluetooth_devices_unittest.cc
+++ b/chromium/content/browser/bluetooth/frame_connected_bluetooth_devices_unittest.cc
@@ -41,7 +41,7 @@ constexpr char kDeviceName1[] = "Device1";
blink::mojom::WebBluetoothServerClientAssociatedPtr CreateServerClient() {
blink::mojom::WebBluetoothServerClientAssociatedPtr client;
- mojo::MakeIsolatedRequest(&client);
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&client);
return client;
}
@@ -101,7 +101,7 @@ class FrameConnectedBluetoothDevicesTest
std::unique_ptr<NiceMockBluetoothGattConnection> GetConnection(
const std::string& address) {
- return base::MakeUnique<NiceMockBluetoothGattConnection>(adapter_.get(),
+ return std::make_unique<NiceMockBluetoothGattConnection>(adapter_.get(),
address);
}
diff --git a/chromium/content/browser/bluetooth/web_bluetooth_service_impl.cc b/chromium/content/browser/bluetooth/web_bluetooth_service_impl.cc
index 13d802fa72c..e5c7291dcc8 100644
--- a/chromium/content/browser/bluetooth/web_bluetooth_service_impl.cc
+++ b/chromium/content/browser/bluetooth/web_bluetooth_service_impl.cc
@@ -1029,7 +1029,7 @@ void WebBluetoothServiceImpl::OnStartNotifySessionSuccess(
std::move(callback).Run(blink::mojom::WebBluetoothResult::SUCCESS);
// Saving the BluetoothGattNotifySession keeps notifications active.
auto gatt_notify_session_and_client =
- base::MakeUnique<GATTNotifySessionAndCharacteristicClient>(
+ std::make_unique<GATTNotifySessionAndCharacteristicClient>(
std::move(notify_session), std::move(client));
characteristic_id_to_notify_session_[characteristic_instance_id] =
std::move(gatt_notify_session_and_client);
diff --git a/chromium/content/browser/broadcast_channel/broadcast_channel_provider.cc b/chromium/content/browser/broadcast_channel/broadcast_channel_provider.cc
index 652cac18595..17f996c1f5d 100644
--- a/chromium/content/browser/broadcast_channel/broadcast_channel_provider.cc
+++ b/chromium/content/browser/broadcast_channel/broadcast_channel_provider.cc
@@ -24,9 +24,9 @@ class BroadcastChannelProvider::Connection
blink::mojom::BroadcastChannelClientAssociatedRequest connection,
BroadcastChannelProvider* service);
- void OnMessage(const std::vector<uint8_t>& message) override;
- void MessageToClient(const std::vector<uint8_t>& message) const {
- client_->OnMessage(message);
+ void OnMessage(blink::CloneableMessage message) override;
+ void MessageToClient(const blink::CloneableMessage& message) const {
+ client_->OnMessage(message.ShallowClone());
}
const url::Origin& origin() const { return origin_; }
const std::string& name() const { return name_; }
@@ -59,7 +59,7 @@ BroadcastChannelProvider::Connection::Connection(
}
void BroadcastChannelProvider::Connection::OnMessage(
- const std::vector<uint8_t>& message) {
+ blink::CloneableMessage message) {
service_->ReceivedMessageOnConnection(this, message);
}
@@ -102,7 +102,7 @@ void BroadcastChannelProvider::UnregisterConnection(Connection* c) {
void BroadcastChannelProvider::ReceivedMessageOnConnection(
Connection* c,
- const std::vector<uint8_t>& message) {
+ const blink::CloneableMessage& message) {
auto& connections = connections_[c->origin()];
for (auto it = connections.lower_bound(c->name()),
end = connections.upper_bound(c->name());
diff --git a/chromium/content/browser/broadcast_channel/broadcast_channel_provider.h b/chromium/content/browser/broadcast_channel/broadcast_channel_provider.h
index 6445bff5e9a..5394a923f60 100644
--- a/chromium/content/browser/broadcast_channel/broadcast_channel_provider.h
+++ b/chromium/content/browser/broadcast_channel/broadcast_channel_provider.h
@@ -36,7 +36,7 @@ class BroadcastChannelProvider
void UnregisterConnection(Connection*);
void ReceivedMessageOnConnection(Connection*,
- const std::vector<uint8_t>& message);
+ const blink::CloneableMessage& message);
mojo::BindingSet<blink::mojom::BroadcastChannelProvider> bindings_;
std::map<url::Origin, std::multimap<std::string, std::unique_ptr<Connection>>>
diff --git a/chromium/content/browser/browser_associated_interface_unittest.cc b/chromium/content/browser/browser_associated_interface_unittest.cc
index bf814f2aa97..72b9a79b588 100644
--- a/chromium/content/browser/browser_associated_interface_unittest.cc
+++ b/chromium/content/browser/browser_associated_interface_unittest.cc
@@ -47,13 +47,16 @@ class ProxyRunner : public IPC::Listener {
std::unique_ptr<IPC::ChannelFactory> factory;
if (for_server) {
factory = IPC::ChannelMojo::CreateServerFactory(
- std::move(pipe), ipc_task_runner);
+ std::move(pipe), ipc_task_runner,
+ base::ThreadTaskRunnerHandle::Get());
} else {
factory = IPC::ChannelMojo::CreateClientFactory(
- std::move(pipe), ipc_task_runner);
+ std::move(pipe), ipc_task_runner,
+ base::ThreadTaskRunnerHandle::Get());
}
- channel_ = IPC::ChannelProxy::Create(
- std::move(factory), this, ipc_task_runner);
+ channel_ =
+ IPC::ChannelProxy::Create(std::move(factory), this, ipc_task_runner,
+ base::ThreadTaskRunnerHandle::Get());
}
void ShutDown() { channel_.reset(); }
@@ -148,9 +151,7 @@ class TestClientRunner {
driver->RequestQuit(base::MessageLoop::QuitWhenIdleClosure());
- base::MessageLoop::ScopedNestableTaskAllower allow_nested_loops(
- base::MessageLoop::current());
- base::RunLoop().Run();
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).Run();
proxy.ShutDown();
io_thread.Stop();
diff --git a/chromium/content/browser/browser_child_process_host_impl.cc b/chromium/content/browser/browser_child_process_host_impl.cc
index 3da990139bd..ff2ab2cb1aa 100644
--- a/chromium/content/browser/browser_child_process_host_impl.cc
+++ b/chromium/content/browser/browser_child_process_host_impl.cc
@@ -27,12 +27,10 @@
#include "build/build_config.h"
#include "components/tracing/common/tracing_switches.h"
#include "content/browser/histogram_controller.h"
-#include "content/browser/histogram_message_filter.h"
#include "content/browser/loader/resource_message_filter.h"
#include "content/browser/service_manager/service_manager_context.h"
#include "content/browser/tracing/trace_message_filter.h"
#include "content/common/child_process_host_impl.h"
-#include "content/common/child_process_messages.h"
#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"
@@ -63,30 +61,31 @@ static base::LazyInstance<
g_child_process_list = LAZY_INSTANCE_INITIALIZER;
base::LazyInstance<base::ObserverList<BrowserChildProcessObserver>>::
- DestructorAtExit g_observers = LAZY_INSTANCE_INITIALIZER;
+ DestructorAtExit g_browser_child_process_observers =
+ LAZY_INSTANCE_INITIALIZER;
void NotifyProcessLaunchedAndConnected(const ChildProcessData& data) {
- for (auto& observer : g_observers.Get())
+ for (auto& observer : g_browser_child_process_observers.Get())
observer.BrowserChildProcessLaunchedAndConnected(data);
}
void NotifyProcessHostConnected(const ChildProcessData& data) {
- for (auto& observer : g_observers.Get())
+ for (auto& observer : g_browser_child_process_observers.Get())
observer.BrowserChildProcessHostConnected(data);
}
void NotifyProcessHostDisconnected(const ChildProcessData& data) {
- for (auto& observer : g_observers.Get())
+ for (auto& observer : g_browser_child_process_observers.Get())
observer.BrowserChildProcessHostDisconnected(data);
}
void NotifyProcessCrashed(const ChildProcessData& data, int exit_code) {
- for (auto& observer : g_observers.Get())
+ for (auto& observer : g_browser_child_process_observers.Get())
observer.BrowserChildProcessCrashed(data, exit_code);
}
void NotifyProcessKilled(const ChildProcessData& data, int exit_code) {
- for (auto& observer : g_observers.Get())
+ for (auto& observer : g_browser_child_process_observers.Get())
observer.BrowserChildProcessKilled(data, exit_code);
}
@@ -132,14 +131,14 @@ BrowserChildProcessHostImpl::BrowserChildProcessList*
void BrowserChildProcessHostImpl::AddObserver(
BrowserChildProcessObserver* observer) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- g_observers.Get().AddObserver(observer);
+ g_browser_child_process_observers.Get().AddObserver(observer);
}
// static
void BrowserChildProcessHostImpl::RemoveObserver(
BrowserChildProcessObserver* observer) {
// TODO(phajdan.jr): Check thread after fixing http://crbug.com/167126.
- g_observers.Get().RemoveObserver(observer);
+ g_browser_child_process_observers.Get().RemoveObserver(observer);
}
BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
@@ -157,7 +156,6 @@ BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
child_process_host_.reset(ChildProcessHost::Create(this));
AddFilter(new TraceMessageFilter(data_.id));
- AddFilter(new HistogramMessageFilter);
g_child_process_list.Get().push_back(this);
GetContentClient()->browser()->BrowserChildProcessHostCreated(this);
diff --git a/chromium/content/browser/browser_context.cc b/chromium/content/browser/browser_context.cc
index 1e3eb64f87b..125078b9cb4 100644
--- a/chromium/content/browser/browser_context.cc
+++ b/chromium/content/browser/browser_context.cc
@@ -15,6 +15,7 @@
#include "base/base64.h"
#include "base/command_line.h"
+#include "base/files/file_path.h"
#include "base/guid.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
@@ -41,6 +42,8 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
+#include "media/capabilities/video_decode_stats_db_impl.h"
+#include "media/mojo/services/video_decode_perf_history.h"
#include "net/cookies/cookie_store.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/channel_id_store.h"
@@ -84,6 +87,7 @@ const char kMojoWasInitialized[] = "mojo-was-initialized";
const char kServiceManagerConnection[] = "service-manager-connection";
const char kServiceUserId[] = "service-user-id";
const char kStoragePartitionMapKeyName[] = "content_storage_partition_map";
+const char kVideoDecodePerfHistoryId[] = "video-decode-perf-history";
#if defined(OS_CHROMEOS)
const char kMountPointsKey[] = "mount_points";
@@ -106,7 +110,7 @@ StoragePartitionImplMap* GetStoragePartitionMap(
browser_context->GetUserData(kStoragePartitionMapKeyName));
if (!partition_map) {
auto partition_map_owned =
- base::MakeUnique<StoragePartitionImplMap>(browser_context);
+ std::make_unique<StoragePartitionImplMap>(browser_context);
partition_map = partition_map_owned.get();
browser_context->SetUserData(kStoragePartitionMapKeyName,
std::move(partition_map_owned));
@@ -204,9 +208,7 @@ DownloadManager* BrowserContext::GetDownloadManager(
BrowserContext* context) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!context->GetUserData(kDownloadManagerKeyName)) {
- DownloadManager* download_manager =
- new DownloadManagerImpl(
- GetContentClient()->browser()->GetNetLog(), context);
+ DownloadManager* download_manager = new DownloadManagerImpl(context);
SetDownloadManager(context, base::WrapUnique(download_manager));
download_manager->SetDelegate(context->GetDownloadManagerDelegate());
@@ -230,14 +232,14 @@ storage::ExternalMountPoints* BrowserContext::GetMountPoints(
storage::ExternalMountPoints::CreateRefCounted();
context->SetUserData(
kMountPointsKey,
- base::MakeUnique<UserDataAdapter<storage::ExternalMountPoints>>(
+ std::make_unique<UserDataAdapter<storage::ExternalMountPoints>>(
mount_points.get()));
}
return UserDataAdapter<storage::ExternalMountPoints>::Get(context,
kMountPointsKey);
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -248,7 +250,7 @@ content::BrowsingDataRemover* content::BrowserContext::GetBrowsingDataRemover(
if (!context->GetUserData(kBrowsingDataRemoverKey)) {
std::unique_ptr<BrowsingDataRemoverImpl> remover =
- base::MakeUnique<BrowsingDataRemoverImpl>(context);
+ std::make_unique<BrowsingDataRemoverImpl>(context);
remover->SetEmbedderDelegate(context->GetBrowsingDataRemoverDelegate());
context->SetUserData(kBrowsingDataRemoverKey, std::move(remover));
}
@@ -305,22 +307,25 @@ void BrowserContext::ForEachStoragePartition(
StoragePartition* BrowserContext::GetDefaultStoragePartition(
BrowserContext* browser_context) {
- return GetStoragePartition(browser_context, NULL);
+ return GetStoragePartition(browser_context, nullptr);
}
// static
void BrowserContext::CreateMemoryBackedBlob(BrowserContext* browser_context,
- const char* data, size_t length,
- const BlobCallback& callback) {
+ const char* data,
+ size_t length,
+ const std::string& content_type,
+ BlobCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
ChromeBlobStorageContext* blob_context =
ChromeBlobStorageContext::GetFor(browser_context);
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::IO, FROM_HERE,
- base::Bind(&ChromeBlobStorageContext::CreateMemoryBackedBlob,
- base::WrapRefCounted(blob_context), data, length),
- callback);
+ base::BindOnce(&ChromeBlobStorageContext::CreateMemoryBackedBlob,
+ base::WrapRefCounted(blob_context), data, length,
+ content_type),
+ std::move(callback));
}
// static
@@ -330,17 +335,17 @@ void BrowserContext::CreateFileBackedBlob(
int64_t offset,
int64_t size,
const base::Time& expected_modification_time,
- const BlobCallback& callback) {
+ BlobCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
ChromeBlobStorageContext* blob_context =
ChromeBlobStorageContext::GetFor(browser_context);
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::IO, FROM_HERE,
- base::Bind(&ChromeBlobStorageContext::CreateFileBackedBlob,
- base::WrapRefCounted(blob_context), path, offset, size,
- expected_modification_time),
- callback);
+ base::BindOnce(&ChromeBlobStorageContext::CreateFileBackedBlob,
+ base::WrapRefCounted(blob_context), path, offset, size,
+ expected_modification_time),
+ std::move(callback));
}
// static
@@ -458,10 +463,10 @@ void BrowserContext::Initialize(
RemoveBrowserContextFromUserIdMap(browser_context);
g_user_id_to_context.Get()[new_id] = browser_context;
browser_context->SetUserData(kServiceUserId,
- base::MakeUnique<ServiceUserIdHolder>(new_id));
+ std::make_unique<ServiceUserIdHolder>(new_id));
browser_context->SetUserData(
- kMojoWasInitialized, base::MakeUnique<base::SupportsUserData::Data>());
+ kMojoWasInitialized, std::make_unique<base::SupportsUserData::Data>());
ServiceManagerConnection* service_manager_connection =
ServiceManagerConnection::GetForProcess();
@@ -579,4 +584,22 @@ std::string BrowserContext::CreateRandomMediaDeviceIDSalt() {
return salt;
}
+media::VideoDecodePerfHistory* BrowserContext::GetVideoDecodePerfHistory() {
+ media::VideoDecodePerfHistory* decode_history =
+ static_cast<media::VideoDecodePerfHistory*>(
+ GetUserData(kVideoDecodePerfHistoryId));
+
+ // Lazily created. Note, this does not trigger loading the DB from disk. That
+ // 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));
+ }
+
+ return decode_history;
+}
+
} // namespace content
diff --git a/chromium/content/browser/browser_ipc_logging.cc b/chromium/content/browser/browser_ipc_logging.cc
index ad323632980..ea431e0d338 100644
--- a/chromium/content/browser/browser_ipc_logging.cc
+++ b/chromium/content/browser/browser_ipc_logging.cc
@@ -5,10 +5,12 @@
#include "content/public/browser/browser_ipc_logging.h"
#include "base/bind.h"
-#include "content/common/child_process_messages.h"
+#include "content/common/child_control.mojom.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/common/bind_interface_helpers.h"
+#include "content/public/common/child_process_host.h"
#include "ipc/ipc_logging.h"
namespace content {
@@ -20,7 +22,9 @@ void EnableIPCLoggingForChildProcesses(bool enabled) {
BrowserChildProcessHostIterator i; // default constr references a singleton
while (!i.Done()) {
- i.Send(new ChildProcessMsg_SetIPCLoggingEnabled(enabled));
+ mojom::ChildControlPtr child_control;
+ content::BindInterface(i.GetHost(), &child_control);
+ child_control->SetIPCLoggingEnabled(enabled);
++i;
}
}
@@ -42,8 +46,11 @@ void EnableIPCLogging(bool enable) {
// Finally, tell the renderers which don't derive from ChildProcess.
// Messages to the renderers must be done on the UI (main) thread.
for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
- !i.IsAtEnd(); i.Advance())
- i.GetCurrentValue()->Send(new ChildProcessMsg_SetIPCLoggingEnabled(enable));
+ !i.IsAtEnd(); i.Advance()) {
+ mojom::ChildControlPtr child_control;
+ content::BindInterface(i.GetCurrentValue(), &child_control);
+ child_control->SetIPCLoggingEnabled(enable);
+ }
}
#endif // BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
diff --git a/chromium/content/browser/browser_main.cc b/chromium/content/browser/browser_main.cc
index 772010cf709..d706269f9db 100644
--- a/chromium/content/browser/browser_main.cc
+++ b/chromium/content/browser/browser_main.cc
@@ -33,7 +33,7 @@ class ScopedBrowserMainEvent {
int BrowserMain(const MainFunctionParams& parameters) {
ScopedBrowserMainEvent scoped_browser_main_event;
- base::trace_event::TraceLog::GetInstance()->SetProcessName("Browser");
+ base::trace_event::TraceLog::GetInstance()->set_process_name("Browser");
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventBrowserProcessSortIndex);
diff --git a/chromium/content/browser/browser_main_loop.cc b/chromium/content/browser/browser_main_loop.cc
index aaf4b0897fa..e176746203a 100644
--- a/chromium/content/browser/browser_main_loop.cc
+++ b/chromium/content/browser/browser_main_loop.cc
@@ -53,13 +53,16 @@
#include "components/tracing/common/trace_to_console.h"
#include "components/tracing/common/tracing_switches.h"
#include "components/viz/common/switches.h"
+#include "components/viz/host/forwarding_compositing_mode_reporter_impl.h"
#include "components/viz/host/host_frame_sink_manager.h"
+#include "components/viz/service/display_embedder/compositing_mode_reporter_impl.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/compositor/gpu_process_transport_factory.h"
#include "content/browser/compositor/surface_utils.h"
+#include "content/browser/compositor/viz_process_transport_factory.h"
#include "content/browser/dom_storage/dom_storage_area.h"
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/download/save_file_manager.h"
@@ -76,6 +79,7 @@
#include "content/browser/media/media_internals.h"
#include "content/browser/memory/memory_coordinator_impl.h"
#include "content/browser/memory/swap_metrics_delegate_uma.h"
+#include "content/browser/mus_util.h"
#include "content/browser/net/browser_online_state_observer.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
@@ -127,6 +131,9 @@
#include "sql/sql_memory_dump_provider.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/ui_base_switches.h"
+#include "ui/base/ui_base_switches_util.h"
+#include "ui/display/display_switches.h"
#include "ui/gfx/switches.h"
#if defined(USE_AURA) || defined(OS_MACOSX)
@@ -169,9 +176,10 @@
#include <shellapi.h>
#include "base/memory/memory_pressure_monitor_win.h"
-#include "content/common/sandbox_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
#if defined(OS_CHROMEOS)
@@ -232,6 +240,10 @@
#include "gpu/vulkan/vulkan_implementation.h"
#endif
+#if BUILDFLAG(ENABLE_MUS)
+#include "services/ui/common/image_cursors_set.h"
+#endif
+
// One of the linux specific headers defines this as a macro.
#ifdef DestroyAll
#undef DestroyAll
@@ -240,14 +252,6 @@
namespace content {
namespace {
-bool IsUsingMus() {
-#if defined(USE_AURA)
- return aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS;
-#else
- return false;
-#endif
-}
-
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \
!defined(OS_FUCHSIA)
void SetupSandbox(const base::CommandLine& parsed_command_line) {
@@ -309,14 +313,12 @@ static void SetUpGLibLogHandler() {
const char* const kLogDomains[] =
{ nullptr, "Gtk", "Gdk", "GLib", "GLib-GObject" };
for (size_t i = 0; i < arraysize(kLogDomains); i++) {
- g_log_set_handler(kLogDomains[i],
- static_cast<GLogLevelFlags>(G_LOG_FLAG_RECURSION |
- G_LOG_FLAG_FATAL |
- G_LOG_LEVEL_ERROR |
- G_LOG_LEVEL_CRITICAL |
- G_LOG_LEVEL_WARNING),
- GLibLogHandler,
- NULL);
+ g_log_set_handler(
+ kLogDomains[i],
+ static_cast<GLogLevelFlags>(G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL |
+ G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL |
+ G_LOG_LEVEL_WARNING),
+ GLibLogHandler, nullptr);
}
}
#endif // defined(USE_GLIB)
@@ -406,12 +408,12 @@ CreateWinMemoryPressureMonitor(const base::CommandLine& parsed_command_line) {
base::StringToInt(thresholds[1], &critical_threshold_mb) &&
moderate_threshold_mb >= critical_threshold_mb &&
critical_threshold_mb >= 0) {
- return base::MakeUnique<base::win::MemoryPressureMonitor>(
+ return std::make_unique<base::win::MemoryPressureMonitor>(
moderate_threshold_mb, critical_threshold_mb);
}
// In absence of valid switches use the automatic defaults.
- return base::MakeUnique<base::win::MemoryPressureMonitor>();
+ return std::make_unique<base::win::MemoryPressureMonitor>();
}
#endif // defined(OS_WIN)
@@ -427,7 +429,7 @@ std::unique_ptr<base::TaskScheduler::InitParams>
GetDefaultTaskSchedulerInitParams() {
#if defined(OS_ANDROID)
// Mobile config, for iOS see ios/web/app/web_main_loop.cc.
- return base::MakeUnique<base::TaskScheduler::InitParams>(
+ return std::make_unique<base::TaskScheduler::InitParams>(
base::SchedulerWorkerPoolParams(
base::RecommendedMaxNumberOfThreadsInPool(2, 8, 0.1, 0),
base::TimeDelta::FromSeconds(30)),
@@ -442,7 +444,7 @@ GetDefaultTaskSchedulerInitParams() {
base::TimeDelta::FromSeconds(60)));
#else
// Desktop config.
- return base::MakeUnique<base::TaskScheduler::InitParams>(
+ return std::make_unique<base::TaskScheduler::InitParams>(
base::SchedulerWorkerPoolParams(
base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0),
base::TimeDelta::FromSeconds(30)),
@@ -452,13 +454,14 @@ GetDefaultTaskSchedulerInitParams() {
base::SchedulerWorkerPoolParams(
base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0),
base::TimeDelta::FromSeconds(30)),
- // Tasks posted to SequencedWorkerPool or BrowserThreadImpl may be
- // redirected to this pool. Since COM STA is initialized in these
- // environments, it must also be initialized in this pool.
base::SchedulerWorkerPoolParams(
base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0),
- base::TimeDelta::FromSeconds(60),
- base::SchedulerBackwardCompatibility::INIT_COM_STA));
+ base::TimeDelta::FromSeconds(60))
+#if defined(OS_WIN)
+ ,
+ base::TaskScheduler::InitParams::SharedWorkerPoolEnvironment::COM_MTA
+#endif // defined(OS_WIN)
+ );
#endif
}
@@ -522,8 +525,50 @@ class GpuDataManagerVisualProxy : public GpuDataManagerObserver {
} // namespace internal
#endif
+#if defined(OS_WIN)
+namespace {
+
+// Provides a bridge whereby display::win::ScreenWin can ask the GPU process
+// about the HDR status of the system.
+class HDRProxy {
+ public:
+ static void Initialize() {
+ display::win::ScreenWin::SetRequestHDRStatusCallback(
+ base::Bind(&HDRProxy::RequestHDRStatus));
+ }
+
+ static void RequestHDRStatus() {
+ // The request must be sent to the GPU process from the IO thread.
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&HDRProxy::RequestOnIOThread));
+ }
+
+ private:
+ static void RequestOnIOThread() {
+ auto* gpu_process_host =
+ GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false);
+ if (gpu_process_host) {
+ gpu_process_host->RequestHDRStatus(
+ base::Bind(&HDRProxy::GotResultOnIOThread));
+ } else {
+ bool hdr_enabled = false;
+ GotResultOnIOThread(hdr_enabled);
+ }
+ }
+ static void GotResultOnIOThread(bool hdr_enabled) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&HDRProxy::GotResult, hdr_enabled));
+ }
+ static void GotResult(bool hdr_enabled) {
+ display::win::ScreenWin::SetHDREnabled(hdr_enabled);
+ }
+};
+
+} // namespace
+#endif
+
// The currently-running BrowserMainLoop. There can be one or zero.
-BrowserMainLoop* g_current_browser_main_loop = NULL;
+BrowserMainLoop* g_current_browser_main_loop = nullptr;
#if defined(OS_ANDROID)
bool g_browser_main_loop_shutting_down = false;
@@ -558,7 +603,7 @@ BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters)
BrowserMainLoop::~BrowserMainLoop() {
DCHECK_EQ(this, g_current_browser_main_loop);
ui::Clipboard::DestroyClipboardForCurrentThread();
- g_current_browser_main_loop = NULL;
+ g_current_browser_main_loop = nullptr;
}
void BrowserMainLoop::Init() {
@@ -726,7 +771,7 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
if (parameters_.create_discardable_memory) {
discardable_shared_memory_manager_ =
- base::MakeUnique<discardable_memory::DiscardableSharedMemoryManager>();
+ std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
// TODO(boliu): kSingleProcess check is a temporary workaround for
// in-process Android WebView. crbug.com/503724 tracks proper fix.
if (!parsed_command_line_.HasSwitch(switches::kSingleProcess)) {
@@ -871,11 +916,8 @@ int BrowserMainLoop::PreCreateThreads() {
policy->AddIsolatedOrigins(
GetContentClient()->browser()->GetOriginsRequiringDedicatedProcess());
- EVP_set_buggy_rsa_parser(
- base::FeatureList::IsEnabled(features::kBuggyRSAParser));
-
// Record metrics about which site isolation flags have been turned on.
- SiteIsolationPolicy::RecordSiteIsolationFlagUsage();
+ SiteIsolationPolicy::StartRecordingSiteIsolationFlagUsage();
return result_code_;
}
@@ -891,10 +933,10 @@ void BrowserMainLoop::CreateStartupTasks() {
DCHECK(!startup_task_runner_);
#if defined(OS_ANDROID)
- startup_task_runner_ = base::MakeUnique<StartupTaskRunner>(
+ startup_task_runner_ = std::make_unique<StartupTaskRunner>(
base::Bind(&BrowserStartupComplete), base::ThreadTaskRunnerHandle::Get());
#else
- startup_task_runner_ = base::MakeUnique<StartupTaskRunner>(
+ startup_task_runner_ = std::make_unique<StartupTaskRunner>(
base::Callback<void(int)>(), base::ThreadTaskRunnerHandle::Get());
#endif
StartupTask pre_create_threads =
@@ -1184,6 +1226,12 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
if (RenderProcessHost::run_renderer_in_process())
RenderProcessHostImpl::ShutDownInProcessRenderer();
+#if BUILDFLAG(ENABLE_MUS)
+ // NOTE: because of dependencies this has to happen before
+ // PostMainMessageLoopRun().
+ image_cursors_set_.reset();
+#endif
+
if (parts_) {
TRACE_EVENT0("shutdown",
"BrowserMainLoop::Subsystem:PostMainMessageLoopRun");
@@ -1226,13 +1274,15 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
#if !defined(OS_ANDROID)
host_frame_sink_manager_.reset();
frame_sink_manager_impl_.reset();
+ compositing_mode_reporter_impl_.reset();
+ forwarding_compositing_mode_reporter_impl_.reset();
#endif
- // The device monitors are using |system_monitor_| as dependency, so delete
- // them before |system_monitor_| goes away.
- // On Mac and windows, the monitor needs to be destroyed on the same thread
- // as they were created. On Linux, the monitor will be deleted when IO thread
- // goes away.
+// The device monitors are using |system_monitor_| as dependency, so delete
+// them before |system_monitor_| goes away.
+// On Mac and windows, the monitor needs to be destroyed on the same thread
+// as they were created. On Linux, the monitor will be deleted when IO thread
+// goes away.
#if defined(OS_WIN)
system_message_window_.reset();
#elif defined(OS_MACOSX)
@@ -1247,6 +1297,9 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
service_manager_context_.reset();
mojo_ipc_support_.reset();
+ if (save_file_manager_)
+ save_file_manager_->Shutdown();
+
{
base::ThreadRestrictions::ScopedAllowWait allow_wait_for_join;
@@ -1277,10 +1330,6 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
}
case BrowserThread::FILE: {
TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:FileThread");
- // Clean up state that lives on or uses the FILE thread before it goes
- // away.
- if (save_file_manager_)
- save_file_manager_->Shutdown();
ResetThread_FILE();
break;
}
@@ -1369,6 +1418,26 @@ viz::FrameSinkManagerImpl* BrowserMainLoop::GetFrameSinkManager() const {
}
#endif
+void BrowserMainLoop::GetCompositingModeReporter(
+ viz::mojom::CompositingModeReporterRequest request) {
+#if defined(OS_ANDROID)
+ // Android doesn't support non-gpu compositing modes, and doesn't make a
+ // CompositingModeReporter.
+ return;
+#else
+ if (IsUsingMus()) {
+ // Mus == ChromeOS, which doesn't support software compositing, so no need
+ // to report compositing mode.
+ return;
+ }
+
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableViz))
+ forwarding_compositing_mode_reporter_impl_->BindRequest(std::move(request));
+ else
+ compositing_mode_reporter_impl_->BindRequest(std::move(request));
+#endif
+}
+
void BrowserMainLoop::StopStartupTracingTimer() {
startup_trace_timer_.Stop();
}
@@ -1390,11 +1459,8 @@ int BrowserMainLoop::BrowserThreadsStarted() {
// so this cannot happen any earlier than now.
InitializeMojo();
- const bool is_mus = IsUsingMus();
-#if defined(USE_AURA)
- if (is_mus) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kIsRunningInMash);
+#if BUILDFLAG(ENABLE_MUS)
+ if (IsUsingMus()) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableSurfaceSynchronization);
}
@@ -1407,10 +1473,8 @@ int BrowserMainLoop::BrowserThreadsStarted() {
#endif
#if BUILDFLAG(ENABLE_VULKAN)
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableVulkan)) {
+ if (parsed_command_line_.HasSwitch(switches::kEnableVulkan))
gpu::InitializeVulkan();
- }
#endif
// Initialize the GPU shader cache. This needs to be initialized before
@@ -1419,6 +1483,9 @@ int BrowserMainLoop::BrowserThreadsStarted() {
InitShaderCacheFactorySingleton(
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ // If mus is not hosting viz, then the browser must.
+ bool browser_is_viz_host = !switches::IsMusHostingViz();
+
bool always_uses_gpu = true;
bool established_gpu_channel = false;
#if defined(OS_ANDROID)
@@ -1426,54 +1493,56 @@ int BrowserMainLoop::BrowserThreadsStarted() {
established_gpu_channel = false;
always_uses_gpu = ShouldStartGpuProcessOnBrowserStartup();
BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
-#elif defined(USE_AURA) || defined(OS_MACOSX)
+#else
established_gpu_channel = true;
- if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor() ||
+ if (parsed_command_line_.HasSwitch(switches::kDisableGpu) ||
+ parsed_command_line_.HasSwitch(switches::kDisableGpuCompositing) ||
parsed_command_line_.HasSwitch(switches::kDisableGpuEarlyInit) ||
- is_mus) {
+ !browser_is_viz_host) {
established_gpu_channel = always_uses_gpu = false;
}
- gpu::GpuChannelEstablishFactory* factory =
- GetContentClient()->browser()->GetGpuChannelEstablishFactory();
- if (!factory) {
+
+ if (browser_is_viz_host) {
+ host_frame_sink_manager_ = std::make_unique<viz::HostFrameSinkManager>();
BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
- factory = BrowserGpuChannelHostFactory::instance();
- }
-#if !defined(OS_ANDROID)
- if (!is_mus) {
- // TODO(kylechar): Remove flag along with surface sequences.
- // See https://crbug.com/676384.
- auto surface_lifetime_type =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableSurfaceReferences)
- ? viz::SurfaceManager::LifetimeType::SEQUENCES
- : viz::SurfaceManager::LifetimeType::REFERENCES;
- frame_sink_manager_impl_ =
- std::make_unique<viz::FrameSinkManagerImpl>(surface_lifetime_type);
-
- host_frame_sink_manager_ = base::MakeUnique<viz::HostFrameSinkManager>();
-
- // TODO(danakj): Don't make a FrameSinkManagerImpl when display is in the
- // Gpu process, instead get the mojo pointer from the Gpu process.
- surface_utils::ConnectWithLocalFrameSinkManager(
- host_frame_sink_manager_.get(), frame_sink_manager_impl_.get());
+ if (parsed_command_line_.HasSwitch(switches::kEnableViz)) {
+ forwarding_compositing_mode_reporter_impl_ =
+ std::make_unique<viz::ForwardingCompositingModeReporterImpl>();
+
+ auto transport_factory = std::make_unique<VizProcessTransportFactory>(
+ BrowserGpuChannelHostFactory::instance(), GetResizeTaskRunner(),
+ forwarding_compositing_mode_reporter_impl_.get());
+ transport_factory->ConnectHostFrameSinkManager();
+ ImageTransportFactory::SetFactory(std::move(transport_factory));
+ } else {
+ // TODO(crbug.com/676384): Remove flag along with surface sequences.
+ auto surface_lifetime_type =
+ parsed_command_line_.HasSwitch(switches::kDisableSurfaceReferences)
+ ? viz::SurfaceManager::LifetimeType::SEQUENCES
+ : viz::SurfaceManager::LifetimeType::REFERENCES;
+ frame_sink_manager_impl_ =
+ std::make_unique<viz::FrameSinkManagerImpl>(surface_lifetime_type);
+
+ surface_utils::ConnectWithLocalFrameSinkManager(
+ host_frame_sink_manager_.get(), frame_sink_manager_impl_.get());
+
+ compositing_mode_reporter_impl_ =
+ std::make_unique<viz::CompositingModeReporterImpl>();
+
+ ImageTransportFactory::SetFactory(
+ std::make_unique<GpuProcessTransportFactory>(
+ BrowserGpuChannelHostFactory::instance(),
+ compositing_mode_reporter_impl_.get(), GetResizeTaskRunner()));
+ }
}
-#endif
- DCHECK(factory);
- if (!is_mus) {
- ImageTransportFactory::SetFactory(
- std::make_unique<GpuProcessTransportFactory>(GetResizeTaskRunner()));
- ImageTransportFactory::GetInstance()->SetGpuChannelEstablishFactory(
- factory);
- }
#if defined(USE_AURA)
- if (env_->mode() == aura::Env::Mode::LOCAL) {
+ if (browser_is_viz_host) {
env_->set_context_factory(GetContextFactory());
env_->set_context_factory_private(GetContextFactoryPrivate());
}
#endif // defined(USE_AURA)
-#endif // defined(OS_ANDROID)
+#endif // !defined(OS_ANDROID)
#if defined(OS_ANDROID)
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
@@ -1492,6 +1561,8 @@ int BrowserMainLoop::BrowserThreadsStarted() {
}
#if defined(OS_WIN)
+ if (base::FeatureList::IsEnabled(features::kHighDynamicRange))
+ HDRProxy::Initialize();
system_message_window_.reset(new media::SystemMessageWindowWin);
#elif defined(OS_LINUX) && defined(USE_UDEV)
device_monitor_linux_.reset(
@@ -1515,7 +1586,8 @@ int BrowserMainLoop::BrowserThreadsStarted() {
// network service.
resource_dispatcher_host_.reset(new ResourceDispatcherHostImpl(
base::Bind(&DownloadResourceHandler::Create),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ !parsed_command_line_.HasSwitch(switches::kDisableResourceScheduler)));
GetContentClient()->browser()->ResourceDispatcherHostCreated();
loader_delegate_.reset(new LoaderDelegateImpl());
@@ -1566,9 +1638,9 @@ int BrowserMainLoop::BrowserThreadsStarted() {
// When running the GPU thread in-process, avoid optimistically starting it
// since creating the GPU thread races against creation of the one-and-only
// ChildProcess instance which is created by the renderer thread.
- if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL) &&
+ if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(nullptr) &&
!established_gpu_channel && always_uses_gpu && !UsingInProcessGpu() &&
- !is_mus) {
+ browser_is_viz_host) {
TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
TRACE_EVENT_SCOPE_THREAD);
BrowserThread::PostTask(
@@ -1601,12 +1673,12 @@ void BrowserMainLoop::InitializeMemoryManagementComponent() {
#if defined(OS_CHROMEOS)
if (chromeos::switches::MemoryPressureHandlingEnabled()) {
memory_pressure_monitor_ =
- base::MakeUnique<base::chromeos::MemoryPressureMonitor>(
+ std::make_unique<base::chromeos::MemoryPressureMonitor>(
chromeos::switches::GetMemoryPressureThresholds());
}
#elif defined(OS_MACOSX)
memory_pressure_monitor_ =
- base::MakeUnique<base::mac::MemoryPressureMonitor>();
+ std::make_unique<base::mac::MemoryPressureMonitor>();
#elif defined(OS_WIN)
memory_pressure_monitor_ =
CreateWinMemoryPressureMonitor(parsed_command_line_);
@@ -1660,6 +1732,11 @@ bool BrowserMainLoop::InitializeToolkit() {
env_ = aura::Env::CreateInstance(parameters_.env_mode);
#endif // defined(USE_AURA)
+#if BUILDFLAG(ENABLE_MUS)
+ if (parsed_command_line_.HasSwitch(switches::kMus))
+ image_cursors_set_ = base::MakeUnique<ui::ImageCursorsSet>();
+#endif
+
if (parts_)
parts_->ToolkitInitialized();
@@ -1704,7 +1781,7 @@ void BrowserMainLoop::InitializeMojo() {
GetContentClient()->OnServiceManagerConnected(
ServiceManagerConnection::GetForProcess());
- tracing_controller_ = base::MakeUnique<content::TracingControllerImpl>();
+ tracing_controller_ = std::make_unique<content::TracingControllerImpl>();
content::BackgroundTracingManagerImpl::GetInstance()
->AddMetadataGeneratorFunction();
@@ -1823,9 +1900,9 @@ void BrowserMainLoop::CreateAudioManager() {
audio_manager_ = GetContentClient()->browser()->CreateAudioManager(
MediaInternals::GetInstance());
if (!audio_manager_) {
- audio_manager_ = media::AudioManager::Create(
- base::MakeUnique<media::AudioThreadImpl>(),
- MediaInternals::GetInstance());
+ audio_manager_ =
+ media::AudioManager::Create(std::make_unique<media::AudioThreadImpl>(),
+ MediaInternals::GetInstance());
}
CHECK(audio_manager_);
audio_system_ = media::AudioSystem::CreateInstance();
diff --git a/chromium/content/browser/browser_main_loop.h b/chromium/content/browser/browser_main_loop.h
index e1d0f0cec1f..64e626c995c 100644
--- a/chromium/content/browser/browser_main_loop.h
+++ b/chromium/content/browser/browser_main_loop.h
@@ -15,6 +15,9 @@
#include "build/build_config.h"
#include "content/browser/browser_process_sub_thread.h"
#include "content/public/browser/browser_main_runner.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "services/viz/public/interfaces/compositing/compositing_mode_watcher.mojom.h"
+#include "ui/base/ui_features.h"
#if defined(USE_AURA)
namespace aura {
@@ -78,7 +81,15 @@ class ClientNativePixmapFactory;
} // namespace gfx
#endif
+#if BUILDFLAG(ENABLE_MUS)
+namespace ui {
+class ImageCursorsSet;
+}
+#endif
+
namespace viz {
+class CompositingModeReporterImpl;
+class ForwardingCompositingModeReporterImpl;
class FrameSinkManagerImpl;
class HostFrameSinkManager;
}
@@ -169,6 +180,10 @@ class CONTENT_EXPORT BrowserMainLoop {
return startup_trace_file_;
}
+#if BUILDFLAG(ENABLE_MUS)
+ ui::ImageCursorsSet* image_cursors_set() { return image_cursors_set_.get(); }
+#endif
+
// Returns the task runner for tasks that that are critical to producing a new
// CompositorFrame on resize. On Mac this will be the task runner provided by
// WindowResizeHelperMac, on other platforms it will just be the thread task
@@ -193,6 +208,10 @@ class CONTENT_EXPORT BrowserMainLoop {
viz::FrameSinkManagerImpl* GetFrameSinkManager() const;
#endif
+ // Fulfills a mojo pointer to the singleton CompositingModeReporter.
+ void GetCompositingModeReporter(
+ viz::mojom::CompositingModeReporterRequest request);
+
void StopStartupTracingTimer();
#if defined(OS_MACOSX) && !defined(OS_IOS)
@@ -273,6 +292,9 @@ class CONTENT_EXPORT BrowserMainLoop {
#if defined(USE_AURA)
std::unique_ptr<aura::Env> env_;
#endif
+#if BUILDFLAG(ENABLE_MUS)
+ std::unique_ptr<ui::ImageCursorsSet> image_cursors_set_;
+#endif
#if defined(OS_ANDROID)
// Android implementation of ScreenOrientationDelegate
@@ -363,6 +385,16 @@ class CONTENT_EXPORT BrowserMainLoop {
// |host_frame_sink_manager_| instead which uses Mojo. See
// http://crbug.com/657959.
std::unique_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_impl_;
+
+ // Forwards requests to watch the compositing mode on to the viz process. This
+ // is null if the display compositor in this process.
+ std::unique_ptr<viz::ForwardingCompositingModeReporterImpl>
+ forwarding_compositing_mode_reporter_impl_;
+ // Reports on the compositing mode in the system for clients to submit
+ // resources of the right type. This is null if the display compositor
+ // is not in this process.
+ std::unique_ptr<viz::CompositingModeReporterImpl>
+ compositing_mode_reporter_impl_;
#endif
// DO NOT add members here. Add them to the right categories above.
diff --git a/chromium/content/browser/browser_main_runner.cc b/chromium/content/browser/browser_main_runner.cc
index 6d510b3fcd9..7848d47a3fa 100644
--- a/chromium/content/browser/browser_main_runner.cc
+++ b/chromium/content/browser/browser_main_runner.cc
@@ -210,9 +210,9 @@ class BrowserMainRunnerImpl : public BrowserMainRunner {
if (base::RunLoop::IsRunningOnCurrentThread())
base::RunLoop::QuitCurrentDeprecated();
#endif
- main_loop_.reset(NULL);
+ main_loop_.reset(nullptr);
- notification_service_.reset(NULL);
+ notification_service_.reset(nullptr);
is_shutdown_ = true;
}
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc b/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
index 6e0a3d4f543..d3bf567e44f 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
@@ -4,6 +4,7 @@
#include "content/browser/browser_plugin/browser_plugin_embedder.h"
+#include "content/browser/bad_message.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -46,24 +47,6 @@ void BrowserPluginEmbedder::DragLeftGuest(BrowserPluginGuest* guest) {
}
// static
-bool BrowserPluginEmbedder::NotifyScreenInfoChanged(
- WebContents* guest_web_contents) {
- if (guest_web_contents->GetRenderViewHost()) {
- auto* render_widget_host = RenderWidgetHostImpl::From(
- guest_web_contents->GetRenderViewHost()->GetWidget());
- render_widget_host->NotifyScreenInfoChanged();
- }
-
- // Returns false to iterate over all guests.
- return false;
-}
-
-void BrowserPluginEmbedder::ScreenInfoChanged() {
- GetBrowserPluginGuestManager()->ForEachGuest(web_contents(), base::Bind(
- &BrowserPluginEmbedder::NotifyScreenInfoChanged));
-}
-
-// static
bool BrowserPluginEmbedder::CancelDialogs(WebContents* guest_web_contents) {
static_cast<WebContentsImpl*>(guest_web_contents)
->CancelActiveAndPendingDialogs();
@@ -73,6 +56,9 @@ bool BrowserPluginEmbedder::CancelDialogs(WebContents* guest_web_contents) {
}
void BrowserPluginEmbedder::CancelGuestDialogs() {
+ if (!GetBrowserPluginGuestManager())
+ return;
+
GetBrowserPluginGuestManager()->ForEachGuest(
web_contents(), base::Bind(&BrowserPluginEmbedder::CancelDialogs));
}
@@ -110,6 +96,9 @@ bool BrowserPluginEmbedder::DidSendScreenRectsCallback(
}
void BrowserPluginEmbedder::DidSendScreenRects() {
+ if (!GetBrowserPluginGuestManager())
+ return;
+
GetBrowserPluginGuestManager()->ForEachGuest(
web_contents(),
base::Bind(&BrowserPluginEmbedder::DidSendScreenRectsCallback));
@@ -127,8 +116,12 @@ bool BrowserPluginEmbedder::OnMessageReceived(
return handled;
}
-void BrowserPluginEmbedder::DragSourceEndedAt(int client_x, int client_y,
- int screen_x, int screen_y, blink::WebDragOperation operation) {
+void BrowserPluginEmbedder::DragSourceEndedAt(
+ float client_x,
+ float client_y,
+ float screen_x,
+ float screen_y,
+ blink::WebDragOperation operation) {
if (guest_started_drag_) {
gfx::Point guest_offset =
guest_started_drag_->GetScreenCoordinates(gfx::Point());
@@ -157,6 +150,12 @@ void BrowserPluginEmbedder::OnAttach(
RenderFrameHost* render_frame_host,
int browser_plugin_instance_id,
const BrowserPluginHostMsg_Attach_Params& params) {
+ if (!GetBrowserPluginGuestManager()) {
+ bad_message::ReceivedBadMessage(
+ render_frame_host->GetProcess(),
+ bad_message::BPE_UNEXPECTED_MESSAGE_BEFORE_BPGM_CREATION);
+ return;
+ }
WebContents* guest_web_contents =
GetBrowserPluginGuestManager()->GetGuestByInstanceID(
render_frame_host->GetProcess()->GetID(),
@@ -200,6 +199,9 @@ bool BrowserPluginEmbedder::GuestRecentlyAudibleCallback(WebContents* guest) {
}
bool BrowserPluginEmbedder::WereAnyGuestsRecentlyAudible() {
+ if (!GetBrowserPluginGuestManager())
+ return false;
+
return GetBrowserPluginGuestManager()->ForEachGuest(
web_contents(),
base::Bind(&BrowserPluginEmbedder::GuestRecentlyAudibleCallback));
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_embedder.h b/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
index 68d02bc73c0..b73418b463a 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
@@ -42,8 +42,11 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
RenderFrameHost* render_frame_host) override;
// Sends a 'dragend' message to the guest that started the drag.
- void DragSourceEndedAt(int client_x, int client_y, int screen_x,
- int screen_y, blink::WebDragOperation operation);
+ void DragSourceEndedAt(float client_x,
+ float client_y,
+ float screen_x,
+ float screen_y,
+ blink::WebDragOperation operation);
// Indicates that a drag operation has entered into the bounds of a given
// |guest|. Returns whether the |guest| also started the operation.
@@ -52,9 +55,6 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
// Indicates that a drag operation has left the bounds of a given |guest|.
void DragLeftGuest(BrowserPluginGuest* guest);
- // Called when the screen info has changed.
- void ScreenInfoChanged();
-
// Closes modal dialogs in all of the guests.
void CancelGuestDialogs();
@@ -92,9 +92,6 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
static bool DidSendScreenRectsCallback(WebContents* guest_web_contents);
- // Notifies a guest that the embedder's screen info has changed.
- static bool NotifyScreenInfoChanged(WebContents* guest_web_contents);
-
// Closes modal dialogs in |guest_web_contents|.
static bool CancelDialogs(WebContents* guest_web_contents);
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
index c73f9f0c640..ccdafd2e928 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -28,6 +28,7 @@
#include "content/browser/frame_host/render_frame_proxy_host.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/mus_util.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
@@ -188,11 +189,11 @@ int BrowserPluginGuest::LoadURLWithParams(
return GetGuestProxyRoutingID();
}
-void BrowserPluginGuest::GuestResizeDueToAutoResize(const gfx::Size& new_size) {
- if (last_seen_view_size_ != new_size) {
- delegate_->GuestSizeChanged(new_size);
- last_seen_view_size_ = new_size;
- }
+void BrowserPluginGuest::ResizeDueToAutoResize(const gfx::Size& new_size,
+ uint64_t sequence_number) {
+ SendMessageToEmbedder(
+ base::MakeUnique<BrowserPluginMsg_ResizeDueToAutoResize>(
+ browser_plugin_instance_id_, sequence_number));
}
void BrowserPluginGuest::SizeContents(const gfx::Size& new_size) {
@@ -256,7 +257,7 @@ void BrowserPluginGuest::SetTooltipText(const base::string16& tooltip_text) {
return;
current_tooltip_text_ = tooltip_text;
- SendMessageToEmbedder(base::MakeUnique<BrowserPluginMsg_SetTooltipText>(
+ SendMessageToEmbedder(std::make_unique<BrowserPluginMsg_SetTooltipText>(
browser_plugin_instance_id_, tooltip_text));
}
@@ -309,7 +310,8 @@ bool BrowserPluginGuest::OnMessageReceivedFromEmbedder(
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetFocus, OnSetFocus)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetVisibility, OnSetVisibility)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UnlockMouse_ACK, OnUnlockMouseAck)
- IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateGeometry, OnUpdateGeometry)
+ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateResizeParams,
+ OnUpdateResizeParams)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SatisfySequence, OnSatisfySequence)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_RequireSequence, OnRequireSequence)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -328,7 +330,7 @@ void BrowserPluginGuest::InitInternal(
UpdateVisibility();
is_full_page_plugin_ = params.is_full_page_plugin;
- guest_window_rect_ = params.view_rect;
+ frame_rect_ = params.frame_rect;
if (owner_web_contents_ != owner_web_contents) {
WebContentsViewGuest* new_view = nullptr;
@@ -426,7 +428,7 @@ void BrowserPluginGuest::EmbedderVisibilityChanged(bool visible) {
}
void BrowserPluginGuest::PointerLockPermissionResponse(bool allow) {
- SendMessageToEmbedder(base::MakeUnique<BrowserPluginMsg_SetMouseLock>(
+ SendMessageToEmbedder(std::make_unique<BrowserPluginMsg_SetMouseLock>(
browser_plugin_instance_id(), allow));
}
@@ -434,8 +436,11 @@ void BrowserPluginGuest::SetChildFrameSurface(
const viz::SurfaceInfo& surface_info,
const viz::SurfaceSequence& sequence) {
has_attached_since_surface_set_ = false;
- SendMessageToEmbedder(base::MakeUnique<BrowserPluginMsg_SetChildFrameSurface>(
- browser_plugin_instance_id(), surface_info, sequence));
+ if (!IsUsingMus()) {
+ SendMessageToEmbedder(
+ std::make_unique<BrowserPluginMsg_SetChildFrameSurface>(
+ browser_plugin_instance_id(), surface_info, sequence));
+ }
}
void BrowserPluginGuest::OnSatisfySequence(
@@ -460,7 +465,7 @@ void BrowserPluginGuest::ResendEventToEmbedder(
RenderWidgetHostViewBase* view =
static_cast<RenderWidgetHostViewBase*>(GetOwnerRenderWidgetHostView());
- gfx::Vector2d offset_from_embedder = guest_window_rect_.OffsetFromOrigin();
+ gfx::Vector2d offset_from_embedder = frame_rect_.OffsetFromOrigin();
if (event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) {
blink::WebGestureEvent resent_gesture_event;
memcpy(&resent_gesture_event, &event, sizeof(blink::WebGestureEvent));
@@ -498,9 +503,8 @@ gfx::Point BrowserPluginGuest::GetCoordinatesInEmbedderWebContents(
gfx::Point point(relative_point);
// Add the offset form the embedder web contents view.
- point +=
- owner_rwhv->TransformPointToRootCoordSpace(guest_window_rect_.origin())
- .OffsetFromOrigin();
+ point += owner_rwhv->TransformPointToRootCoordSpace(frame_rect_.origin())
+ .OffsetFromOrigin();
if (embedder_web_contents()->GetBrowserPluginGuest()) {
// |point| is currently with respect to the top-most view (outermost
// WebContents). We should subtract a displacement to find the point with
@@ -522,7 +526,7 @@ gfx::Point BrowserPluginGuest::GetScreenCoordinates(
return relative_position;
gfx::Point screen_pos(relative_position);
- screen_pos += guest_window_rect_.OffsetFromOrigin();
+ screen_pos += frame_rect_.OffsetFromOrigin();
return screen_pos;
}
@@ -547,14 +551,13 @@ void BrowserPluginGuest::SendMessageToEmbedder(
rwh->Send(msg.release());
}
-void BrowserPluginGuest::DragSourceEndedAt(int client_x,
- int client_y,
- int screen_x,
- int screen_y,
+void BrowserPluginGuest::DragSourceEndedAt(float client_x,
+ float client_y,
+ float screen_x,
+ float screen_y,
blink::WebDragOperation operation) {
web_contents()->GetRenderViewHost()->GetWidget()->DragSourceEndedAt(
- gfx::Point(client_x, client_y),
- gfx::Point(screen_x, screen_y),
+ gfx::PointF(client_x, client_y), gfx::PointF(screen_x, screen_y),
operation);
seen_embedder_drag_source_ended_at_ = true;
EndSystemDragIfApplicable();
@@ -700,7 +703,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()) {
+ if (attached() && !IsUsingMus()) {
RenderWidgetHostViewGuest* rwhv = static_cast<RenderWidgetHostViewGuest*>(
web_contents()->GetRenderWidgetHostView());
if (rwhv) {
@@ -715,7 +718,7 @@ void BrowserPluginGuest::RenderViewReady() {
}
void BrowserPluginGuest::RenderProcessGone(base::TerminationStatus status) {
- SendMessageToEmbedder(base::MakeUnique<BrowserPluginMsg_GuestGone>(
+ SendMessageToEmbedder(std::make_unique<BrowserPluginMsg_GuestGone>(
browser_plugin_instance_id()));
switch (status) {
#if defined(OS_CHROMEOS)
@@ -848,7 +851,7 @@ void BrowserPluginGuest::OnWillAttachComplete(
RenderWidgetHostViewGuest* rwhv = static_cast<RenderWidgetHostViewGuest*>(
web_contents()->GetRenderWidgetHostView());
if (rwhv)
- rwhv->RegisterFrameSinkId();
+ rwhv->OnAttached();
has_render_view_ = true;
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Attached"));
@@ -879,7 +882,7 @@ void BrowserPluginGuest::OnDragStatusUpdate(int browser_plugin_instance_id,
blink::WebDragStatus drag_status,
const DropData& drop_data,
blink::WebDragOperationsMask mask,
- const gfx::Point& location) {
+ const gfx::PointF& location) {
RenderViewHost* host = GetWebContents()->GetRenderViewHost();
auto* embedder = owner_web_contents_->GetBrowserPluginEmbedder();
DropData filtered_data(drop_data);
@@ -902,7 +905,7 @@ void BrowserPluginGuest::OnDragStatusUpdate(int browser_plugin_instance_id,
break;
case blink::kWebDragStatusLeave:
embedder->DragLeftGuest(this);
- widget->DragTargetDragLeave(gfx::Point(), gfx::Point());
+ widget->DragTargetDragLeave(gfx::PointF(), gfx::PointF());
ignore_dragged_url_ = true;
break;
case blink::kWebDragStatusDrop:
@@ -1050,7 +1053,7 @@ void BrowserPluginGuest::OnSetVisibility(int browser_plugin_instance_id,
}
void BrowserPluginGuest::OnUnlockMouse() {
- SendMessageToEmbedder(base::MakeUnique<BrowserPluginMsg_SetMouseLock>(
+ SendMessageToEmbedder(std::make_unique<BrowserPluginMsg_SetMouseLock>(
browser_plugin_instance_id(), false));
}
@@ -1066,25 +1069,46 @@ void BrowserPluginGuest::OnUnlockMouseAck(int browser_plugin_instance_id) {
mouse_locked_ = false;
}
-void BrowserPluginGuest::OnUpdateGeometry(
+void BrowserPluginGuest::OnUpdateResizeParams(
int browser_plugin_instance_id,
- const gfx::Rect& view_rect,
+ const gfx::Rect& frame_rect,
+ const ScreenInfo& screen_info,
+ uint64_t sequence_number,
const viz::LocalSurfaceId& local_surface_id) {
- // The plugin has moved within the embedder without resizing or the
- // embedder/container's view rect changing.
- guest_window_rect_ = view_rect;
+ if ((frame_rect_.size() != frame_rect.size() ||
+ screen_info_ != screen_info) &&
+ local_surface_id_ == local_surface_id) {
+ SiteInstance* owner_site_instance = delegate_->GetOwnerSiteInstance();
+ bad_message::ReceivedBadMessage(
+ owner_site_instance->GetProcess(),
+ bad_message::BPG_RESIZE_PARAMS_CHANGED_LOCAL_SURFACE_ID_UNCHANGED);
+ return;
+ }
+
+ screen_info_ = screen_info;
+ frame_rect_ = frame_rect;
GetWebContents()->SendScreenRects();
- if (local_surface_id_ != local_surface_id) {
- local_surface_id_ = local_surface_id;
- RenderWidgetHostView* view = web_contents()->GetRenderWidgetHostView();
- if (view)
- view->GetRenderWidgetHost()->WasResized();
+ local_surface_id_ = local_surface_id;
+
+ RenderWidgetHostView* view = web_contents()->GetRenderWidgetHostView();
+ if (!view)
+ return;
+
+ RenderWidgetHostImpl* render_widget_host =
+ RenderWidgetHostImpl::From(view->GetRenderWidgetHost());
+ DCHECK(render_widget_host);
+
+ if (render_widget_host->auto_resize_enabled()) {
+ render_widget_host->DidAllocateLocalSurfaceIdForAutoResize(sequence_number);
+ return;
}
+
+ render_widget_host->WasResized();
}
void BrowserPluginGuest::OnHasTouchEventHandlers(bool accept) {
SendMessageToEmbedder(
- base::MakeUnique<BrowserPluginMsg_ShouldAcceptTouchEvents>(
+ std::make_unique<BrowserPluginMsg_ShouldAcceptTouchEvents>(
browser_plugin_instance_id(), accept));
}
@@ -1099,7 +1123,7 @@ void BrowserPluginGuest::OnShowPopup(
guest->GetRenderWidgetHostView()->TransformPointToRootCoordSpace(
translated_bounds.origin()));
} else {
- translated_bounds.Offset(guest_window_rect_.OffsetFromOrigin());
+ translated_bounds.Offset(frame_rect_.OffsetFromOrigin());
}
BrowserPluginPopupMenuHelper popup_menu_helper(
owner_web_contents_->GetMainFrame(), render_frame_host);
@@ -1120,7 +1144,7 @@ void BrowserPluginGuest::OnShowWidget(int route_id,
}
void BrowserPluginGuest::OnTakeFocus(bool reverse) {
- SendMessageToEmbedder(base::MakeUnique<BrowserPluginMsg_AdvanceFocus>(
+ SendMessageToEmbedder(std::make_unique<BrowserPluginMsg_AdvanceFocus>(
browser_plugin_instance_id(), reverse));
}
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.h b/chromium/content/browser/browser_plugin/browser_plugin_guest.h
index ba024158dfa..f47d0397eb8 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.h
@@ -31,11 +31,12 @@
#include "build/build_config.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "content/common/edit_command.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/public/browser/browser_plugin_guest_delegate.h"
#include "content/public/browser/guest_host.h"
#include "content/public/browser/readback_types.h"
#include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/input_event_ack_state.h"
+#include "content/public/common/screen_info.h"
#include "third_party/WebKit/public/platform/WebDragOperation.h"
#include "third_party/WebKit/public/platform/WebFocusType.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
@@ -73,6 +74,7 @@ class RenderWidgetHostView;
class RenderWidgetHostViewBase;
class SiteInstance;
struct DropData;
+struct ScreenInfo;
struct TextInputState;
// A browser plugin guest provides functionality for WebContents to operate in
@@ -151,6 +153,12 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
// within an embedder.
int browser_plugin_instance_id() const { return browser_plugin_instance_id_; }
+ // Returns the ScreenInfo used by the guest to render.
+ const ScreenInfo& screen_info() const { return screen_info_; }
+
+ // Returns the current rect used by the guest to render.
+ const gfx::Rect& frame_rect() const { return frame_rect_; }
+
bool OnMessageReceivedFromEmbedder(const IPC::Message& message);
WebContentsImpl* embedder_web_contents() const {
@@ -176,6 +184,9 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
BrowserPluginGuestManager* GetBrowserPluginGuestManager() const;
+ void ResizeDueToAutoResize(const gfx::Size& new_size,
+ uint64_t sequence_number);
+
// WebContentsObserver implementation.
void DidFinishNavigation(NavigationHandle* navigation_handle) override;
@@ -188,7 +199,6 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
// GuestHost implementation.
int LoadURLWithParams(
const NavigationController::LoadURLParams& load_params) override;
- void GuestResizeDueToAutoResize(const gfx::Size& new_size) override;
void SizeContents(const gfx::Size& new_size) override;
void WillDestroy() override;
@@ -233,8 +243,11 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
// |message|.
static bool ShouldForwardToBrowserPluginGuest(const IPC::Message& message);
- void DragSourceEndedAt(int client_x, int client_y, int screen_x,
- int screen_y, blink::WebDragOperation operation);
+ void DragSourceEndedAt(float client_x,
+ float client_y,
+ float screen_x,
+ float screen_y,
+ blink::WebDragOperation operation);
// Called when the drag started by this guest ends at an OS-level.
void EmbedderSystemDragEnded();
@@ -302,7 +315,7 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
blink::WebDragStatus drag_status,
const DropData& drop_data,
blink::WebDragOperationsMask drag_mask,
- const gfx::Point& location);
+ const gfx::PointF& location);
// Instructs the guest to execute an edit command decoded in the embedder.
void OnExecuteEditCommand(int instance_id,
const std::string& command);
@@ -339,9 +352,11 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
void OnSetVisibility(int instance_id, bool visible);
void OnUnlockMouse();
void OnUnlockMouseAck(int instance_id);
- void OnUpdateGeometry(int instance_id,
- const gfx::Rect& view_rect,
- const viz::LocalSurfaceId& local_surface_id);
+ void OnUpdateResizeParams(int instance_id,
+ const gfx::Rect& frame_rect,
+ const ScreenInfo& screen_info,
+ uint64_t sequence_number,
+ const viz::LocalSurfaceId& local_surface_id);
void OnTextInputStateChanged(const TextInputState& params);
void OnImeSetComposition(
@@ -409,7 +424,7 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
// An identifier that uniquely identifies a browser plugin within an embedder.
int browser_plugin_instance_id_;
- gfx::Rect guest_window_rect_;
+ gfx::Rect frame_rect_;
bool focused_;
bool mouse_locked_;
bool pending_lock_request_;
@@ -425,9 +440,6 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
// maintains a JavaScript reference to its opener.
bool has_render_view_;
- // Last seen size of guest contents (by SwapCompositorFrame).
- gfx::Size last_seen_view_size_;
-
bool is_in_destruction_;
// BrowserPluginGuest::Init can only be called once. This flag allows it to
@@ -463,6 +475,7 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
bool can_use_cross_process_frames_;
viz::LocalSurfaceId local_surface_id_;
+ ScreenInfo screen_info_;
// Weak pointer used to ask GeolocationPermissionContext about geolocation
// permission.
diff --git a/chromium/content/browser/browser_shutdown_profile_dumper.cc b/chromium/content/browser/browser_shutdown_profile_dumper.cc
index 6840acd1edb..84ccc3f09a8 100644
--- a/chromium/content/browser/browser_shutdown_profile_dumper.cc
+++ b/chromium/content/browser/browser_shutdown_profile_dumper.cc
@@ -21,10 +21,7 @@ namespace content {
BrowserShutdownProfileDumper::BrowserShutdownProfileDumper(
const base::FilePath& dump_file_name)
- : dump_file_name_(dump_file_name),
- blocks_(0),
- dump_file_(NULL) {
-}
+ : dump_file_name_(dump_file_name), blocks_(0), dump_file_(nullptr) {}
BrowserShutdownProfileDumper::~BrowserShutdownProfileDumper() {
WriteTracesToDisc();
@@ -144,7 +141,7 @@ void BrowserShutdownProfileDumper::CloseFile() {
if (!dump_file_)
return;
base::CloseFile(dump_file_);
- dump_file_ = NULL;
+ dump_file_ = nullptr;
}
} // namespace content
diff --git a/chromium/content/browser/browser_side_navigation_browsertest.cc b/chromium/content/browser/browser_side_navigation_browsertest.cc
index 6e7cd3b3799..350aaa88764 100644
--- a/chromium/content/browser/browser_side_navigation_browsertest.cc
+++ b/chromium/content/browser/browser_side_navigation_browsertest.cc
@@ -452,12 +452,11 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserDisableWebSecurityTest,
file_url, // base_url_for_data_url
GURL(), PREVIEWS_UNSPECIFIED, base::TimeTicks::Now(), "GET", nullptr,
base::Optional<SourceLocation>(), CSPDisposition::CHECK,
- false /* started_from_context_menu */);
+ false /* started_from_context_menu */, false /* has_user_gesture */);
BeginNavigationParams begin_params(
- std::string(), net::LOAD_NORMAL, false, false,
- REQUEST_CONTEXT_TYPE_LOCATION,
+ std::string(), net::LOAD_NORMAL, false, REQUEST_CONTEXT_TYPE_LOCATION,
blink::WebMixedContentContextType::kBlockable, false,
- url::Origin(data_url));
+ url::Origin::Create(data_url));
FrameHostMsg_BeginNavigation msg(rfh->GetRoutingID(), common_params,
begin_params);
diff --git a/chromium/content/browser/browser_thread_unittest.cc b/chromium/content/browser/browser_thread_unittest.cc
index 866b51db09c..b5d98ca13ca 100644
--- a/chromium/content/browser/browser_thread_unittest.cc
+++ b/chromium/content/browser/browser_thread_unittest.cc
@@ -32,39 +32,39 @@ class BrowserThreadTest : public testing::Test {
protected:
void SetUp() override {
ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI));
- file_thread_.reset(new BrowserThreadImpl(BrowserThread::FILE));
+ io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO));
ui_thread_->Start();
- file_thread_->Start();
+ io_thread_->Start();
}
void TearDown() override {
StopUIThread();
- file_thread_->Stop();
+ io_thread_->Stop();
ui_thread_ = nullptr;
- file_thread_ = nullptr;
+ io_thread_ = nullptr;
BrowserThreadImpl::ResetGlobalsForTesting(BrowserThread::UI);
- BrowserThreadImpl::ResetGlobalsForTesting(BrowserThread::FILE);
+ BrowserThreadImpl::ResetGlobalsForTesting(BrowserThread::IO);
}
static void BasicFunction(base::MessageLoop* message_loop) {
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
message_loop->task_runner()->PostTask(
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
- class DeletedOnFile
- : public base::RefCountedThreadSafe<
- DeletedOnFile, BrowserThread::DeleteOnFileThread> {
+ class DeletedOnIO
+ : public base::RefCountedThreadSafe<DeletedOnIO,
+ BrowserThread::DeleteOnIOThread> {
public:
- explicit DeletedOnFile(base::MessageLoop* message_loop)
+ explicit DeletedOnIO(base::MessageLoop* message_loop)
: message_loop_(message_loop) {}
private:
- friend struct BrowserThread::DeleteOnThread<BrowserThread::FILE>;
- friend class base::DeleteHelper<DeletedOnFile>;
+ friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
+ friend class base::DeleteHelper<DeletedOnIO>;
- ~DeletedOnFile() {
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ ~DeletedOnIO() {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
message_loop_->task_runner()->PostTask(
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}
@@ -74,7 +74,7 @@ class BrowserThreadTest : public testing::Test {
private:
std::unique_ptr<BrowserThreadImpl> ui_thread_;
- std::unique_ptr<BrowserThreadImpl> file_thread_;
+ std::unique_ptr<BrowserThreadImpl> io_thread_;
// It's kind of ugly to make this mutable - solely so we can post the Quit
// Task from Release(). This should be fixed.
mutable base::MessageLoop loop_;
@@ -120,7 +120,7 @@ class UIThreadDestructionObserver
TEST_F(BrowserThreadTest, PostTask) {
BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
+ BrowserThread::IO, FROM_HERE,
base::BindOnce(&BasicFunction, base::MessageLoop::current()));
base::RunLoop().Run();
}
@@ -132,15 +132,15 @@ TEST_F(BrowserThreadTest, Release) {
TEST_F(BrowserThreadTest, ReleasedOnCorrectThread) {
{
- scoped_refptr<DeletedOnFile> test(
- new DeletedOnFile(base::MessageLoop::current()));
+ scoped_refptr<DeletedOnIO> test(
+ new DeletedOnIO(base::MessageLoop::current()));
}
base::RunLoop().Run();
}
TEST_F(BrowserThreadTest, PostTaskViaTaskRunner) {
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE);
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
task_runner->PostTask(
FROM_HERE, base::BindOnce(&BasicFunction, base::MessageLoop::current()));
base::RunLoop().Run();
@@ -157,7 +157,7 @@ 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.
ASSERT_TRUE(BrowserThread::PostTaskAndReply(
- BrowserThread::FILE, FROM_HERE, base::BindOnce(&base::DoNothing),
+ BrowserThread::IO, FROM_HERE, base::BindOnce(&base::DoNothing),
base::BindOnce(&base::RunLoop::QuitCurrentWhenIdleDeprecated)));
base::RunLoop().Run();
}
diff --git a/chromium/content/browser/browser_url_handler_impl.cc b/chromium/content/browser/browser_url_handler_impl.cc
index feef0ca919a..ef78ddd5e26 100644
--- a/chromium/content/browser/browser_url_handler_impl.cc
+++ b/chromium/content/browser/browser_url_handler_impl.cc
@@ -12,6 +12,7 @@
#include "content/browser/webui/web_ui_impl.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/url_utils.h"
#include "url/gurl.h"
namespace content {
@@ -82,7 +83,7 @@ BrowserURLHandler* BrowserURLHandler::GetInstance() {
// static
BrowserURLHandler::URLHandler BrowserURLHandler::null_handler() {
// Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
- return NULL;
+ return nullptr;
}
// static
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 18f93a6502f..e77b3a492e2 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
@@ -51,7 +51,7 @@ bool MatchesURL(
: url.host()) !=
registerable_domains.end());
- bool found_origin = (origins.find(url::Origin(url)) != origins.end());
+ bool found_origin = (origins.find(url::Origin::Create(url)) != origins.end());
return ((found_domain || found_origin) ==
(mode == BrowsingDataFilterBuilder::WHITELIST));
@@ -115,7 +115,7 @@ bool NoopFilter(const GURL& url) {
// static
std::unique_ptr<BrowsingDataFilterBuilder>
BrowsingDataFilterBuilder::Create(Mode mode) {
- return base::MakeUnique<BrowsingDataFilterBuilderImpl>(mode);
+ return std::make_unique<BrowsingDataFilterBuilderImpl>(mode);
}
// static
@@ -199,7 +199,7 @@ BrowsingDataFilterBuilderImpl::GetMode() const {
std::unique_ptr<BrowsingDataFilterBuilder>
BrowsingDataFilterBuilderImpl::Copy() const {
std::unique_ptr<BrowsingDataFilterBuilderImpl> copy =
- base::MakeUnique<BrowsingDataFilterBuilderImpl>(mode_);
+ std::make_unique<BrowsingDataFilterBuilderImpl>(mode_);
copy->origins_ = origins_;
copy->domains_ = domains_;
return std::move(copy);
diff --git a/chromium/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc b/chromium/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc
index 470c9a8dbbd..81fc09dc81e 100644
--- a/chromium/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc
+++ b/chromium/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc
@@ -442,8 +442,8 @@ TEST(BrowsingDataFilterBuilderImplTest,
TEST(BrowsingDataFilterBuilderImplTest, OriginWhitelist) {
BrowsingDataFilterBuilderImpl builder(
BrowsingDataFilterBuilderImpl::WHITELIST);
- builder.AddOrigin(url::Origin(GURL("https://www.google.com")));
- builder.AddOrigin(url::Origin(GURL("http://www.example.com")));
+ builder.AddOrigin(url::Origin::Create(GURL("https://www.google.com")));
+ builder.AddOrigin(url::Origin::Create(GURL("http://www.example.com")));
base::Callback<bool(const GURL&)> filter = builder.BuildGeneralFilter();
TestCase test_cases[] = {
@@ -473,8 +473,8 @@ TEST(BrowsingDataFilterBuilderImplTest, OriginWhitelist) {
TEST(BrowsingDataFilterBuilderImplTest, OriginBlacklist) {
BrowsingDataFilterBuilderImpl builder(
BrowsingDataFilterBuilderImpl::BLACKLIST);
- builder.AddOrigin(url::Origin(GURL("https://www.google.com")));
- builder.AddOrigin(url::Origin(GURL("http://www.example.com")));
+ builder.AddOrigin(url::Origin::Create(GURL("https://www.google.com")));
+ builder.AddOrigin(url::Origin::Create(GURL("http://www.example.com")));
base::Callback<bool(const GURL&)> filter = builder.BuildGeneralFilter();
TestCase test_cases[] = {
@@ -505,7 +505,7 @@ TEST(BrowsingDataFilterBuilderImplTest, OriginBlacklist) {
TEST(BrowsingDataFilterBuilderImplTest, CombinedWhitelist) {
BrowsingDataFilterBuilderImpl builder(
BrowsingDataFilterBuilderImpl::WHITELIST);
- builder.AddOrigin(url::Origin(GURL("https://google.com")));
+ builder.AddOrigin(url::Origin::Create(GURL("https://google.com")));
builder.AddRegisterableDomain("example.com");
base::Callback<bool(const GURL&)> filter = builder.BuildGeneralFilter();
@@ -528,7 +528,7 @@ TEST(BrowsingDataFilterBuilderImplTest, CombinedWhitelist) {
TEST(BrowsingDataFilterBuilderImplTest, CombinedBlacklist) {
BrowsingDataFilterBuilderImpl builder(
BrowsingDataFilterBuilderImpl::BLACKLIST);
- builder.AddOrigin(url::Origin(GURL("https://google.com")));
+ builder.AddOrigin(url::Origin::Create(GURL("https://google.com")));
builder.AddRegisterableDomain("example.com");
base::Callback<bool(const GURL&)> filter = builder.BuildGeneralFilter();
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 2e762da66f9..3e14f9e05f2 100644
--- a/chromium/content/browser/browsing_data/browsing_data_remover_impl.cc
+++ b/chromium/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -174,6 +174,7 @@ BrowsingDataRemoverImpl::BrowsingDataRemoverImpl(
synchronous_clear_operations_(sub_task_forward_callback_),
clear_embedder_data_(sub_task_forward_callback_),
clear_cache_(sub_task_forward_callback_),
+ clear_networking_history_(sub_task_forward_callback_),
clear_channel_ids_(sub_task_forward_callback_),
clear_http_auth_cache_(sub_task_forward_callback_),
clear_storage_partition_data_(sub_task_forward_callback_),
@@ -490,6 +491,12 @@ void BrowsingDataRemoverImpl::RemoveImpl(
: filter,
clear_cache_.GetCompletionCallback());
+ // When clearing cache, wipe accumulated network related data
+ // (TransportSecurityState and HttpServerPropertiesManager data).
+ clear_networking_history_.Start();
+ storage_partition->GetNetworkContext()->ClearNetworkingHistorySince(
+ delete_begin, clear_networking_history_.GetCompletionCallback());
+
// Tell the shader disk cache to clear.
base::RecordAction(UserMetricsAction("ClearBrowsingData_ShaderCache"));
storage_partition_remove_mask |=
@@ -580,6 +587,7 @@ BrowsingDataRemoverImpl::RemovalTask::~RemovalTask() {}
bool BrowsingDataRemoverImpl::AllDone() {
return !synchronous_clear_operations_.is_pending() &&
!clear_embedder_data_.is_pending() && !clear_cache_.is_pending() &&
+ !clear_networking_history_.is_pending() &&
!clear_channel_ids_.is_pending() &&
!clear_http_auth_cache_.is_pending() &&
!clear_storage_partition_data_.is_pending();
diff --git a/chromium/content/browser/browsing_data/browsing_data_remover_impl.h b/chromium/content/browser/browsing_data/browsing_data_remover_impl.h
index 81b62a776ac..c974deb82f6 100644
--- a/chromium/content/browser/browsing_data/browsing_data_remover_impl.h
+++ b/chromium/content/browser/browsing_data/browsing_data_remover_impl.h
@@ -218,6 +218,7 @@ class CONTENT_EXPORT BrowsingDataRemoverImpl
SubTask synchronous_clear_operations_;
SubTask clear_embedder_data_;
SubTask clear_cache_;
+ SubTask clear_networking_history_;
SubTask clear_channel_ids_;
SubTask clear_http_auth_cache_;
SubTask clear_storage_partition_data_;
diff --git a/chromium/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc b/chromium/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc
new file mode 100644
index 00000000000..efcbe0e8ec6
--- /dev/null
+++ b/chromium/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc
@@ -0,0 +1,160 @@
+// Copyright 2017 The Chromium Authors. 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/browsing_data_remover.h"
+
+#include <memory>
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browsing_data_remover.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/network_service.mojom.h"
+#include "content/public/common/simple_url_loader.h"
+#include "content/public/test/browsing_data_remover_test_util.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/simple_url_loader_test_helper.h"
+#include "content/shell/browser/shell.h"
+#include "net/base/net_errors.h"
+#include "net/dns/mock_host_resolver.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/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace {
+
+const char kHstsPath[] = "/hsts";
+const char kHstsResponseBody[] = "HSTS set";
+
+std::unique_ptr<net::test_server::HttpResponse> HandleHstsRequest(
+ const net::test_server::HttpRequest& request) {
+ if (request.relative_url == kHstsPath) {
+ std::unique_ptr<net::test_server::BasicHttpResponse> hsts_response =
+ std::make_unique<net::test_server::BasicHttpResponse>();
+ hsts_response->AddCustomHeader("Strict-Transport-Security",
+ "max-age=1000000");
+ hsts_response->set_content(kHstsResponseBody);
+ return hsts_response;
+ }
+ return nullptr;
+}
+
+} // namespace
+
+namespace content {
+
+class BrowsingDataRemoverImplBrowserTest : public ContentBrowserTest {
+ public:
+ BrowsingDataRemoverImplBrowserTest()
+ : ssl_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {
+ // Use localhost instead of 127.0.0.1, as HSTS isn't allowed on IPs.
+ ssl_server_.SetSSLConfig(
+ net::test_server::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+ ssl_server_.AddDefaultHandlers(
+ base::FilePath(FILE_PATH_LITERAL("content/test/data")));
+ ssl_server_.RegisterRequestHandler(base::Bind(&HandleHstsRequest));
+ EXPECT_TRUE(ssl_server_.Start());
+ }
+
+ void SetUpOnMainThread() override {}
+
+ void RemoveAndWait(int remove_mask) {
+ content::BrowsingDataRemover* remover =
+ content::BrowserContext::GetBrowsingDataRemover(
+ shell()->web_contents()->GetBrowserContext());
+ content::BrowsingDataRemoverCompletionObserver completion_observer(remover);
+ remover->RemoveAndReply(
+ base::Time(), base::Time::Max(), remove_mask,
+ content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
+ &completion_observer);
+ completion_observer.BlockUntilCompletion();
+ }
+
+ // Issues a request for kHstsPath on localhost, and expects it to enable HSTS
+ // for the domain.
+ void IssueRequestThatSetsHsts() {
+ std::unique_ptr<ResourceRequest> request =
+ std::make_unique<ResourceRequest>();
+ request->url = ssl_server_.GetURL("localhost", kHstsPath);
+
+ SimpleURLLoaderTestHelper loader_helper;
+ std::unique_ptr<SimpleURLLoader> loader = SimpleURLLoader::Create(
+ std::move(request), TRAFFIC_ANNOTATION_FOR_TESTS);
+ loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+ url_loader_factory(), loader_helper.GetCallback());
+ loader_helper.WaitForCallback();
+ ASSERT_TRUE(loader_helper.response_body());
+ EXPECT_EQ(kHstsResponseBody, *loader_helper.response_body());
+
+ EXPECT_TRUE(IsHstsSet());
+ }
+
+ // Returns true if HSTS is set on localhost. Does this by issuing an HTTP
+ // request to the embedded test server, and expecting it to be redirected from
+ // HTTP to HTTPS if HSTS is enabled. If the request succeeds, it was sent
+ // over HTTPS, so HSTS is enabled. If it fails, the request was send using
+ // HTTP instead, so HSTS is not enabled for the domain.
+ bool IsHstsSet() {
+ GURL url = ssl_server_.GetURL("localhost", "/echo");
+ GURL::Replacements replacements;
+ replacements.SetSchemeStr("http");
+ url = url.ReplaceComponents(replacements);
+ std::unique_ptr<ResourceRequest> request =
+ std::make_unique<ResourceRequest>();
+ request->url = url;
+
+ std::unique_ptr<SimpleURLLoader> loader = SimpleURLLoader::Create(
+ std::move(request), TRAFFIC_ANNOTATION_FOR_TESTS);
+ SimpleURLLoaderTestHelper loader_helper;
+ loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+ url_loader_factory(), loader_helper.GetCallback());
+ loader_helper.WaitForCallback();
+
+ // On success, HSTS was enabled for the domain.
+ if (loader_helper.response_body()) {
+ EXPECT_EQ("Echo", *loader_helper.response_body());
+ return true;
+ }
+
+ // On failure, the server just hangs up, since it didn't receive an SSL
+ // handshake.
+ EXPECT_EQ(net::ERR_EMPTY_RESPONSE, loader->NetError());
+ return false;
+ }
+
+ mojom::URLLoaderFactory* url_loader_factory() {
+ return BrowserContext::GetDefaultStoragePartition(
+ shell()->web_contents()->GetBrowserContext())
+ ->GetURLLoaderFactoryForBrowserProcess();
+ }
+
+ private:
+ net::test_server::EmbeddedTestServer ssl_server_;
+};
+
+// Verify that TransportSecurityState data is cleared for REMOVE_CACHE.
+IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverImplBrowserTest,
+ ClearTransportSecurityState) {
+ IssueRequestThatSetsHsts();
+
+ RemoveAndWait(BrowsingDataRemover::DATA_TYPE_CACHE);
+ EXPECT_FALSE(IsHstsSet());
+}
+
+// Verify that TransportSecurityState data is not cleared if REMOVE_CACHE is not
+// set.
+IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverImplBrowserTest,
+ PreserveTransportSecurityState) {
+ IssueRequestThatSetsHsts();
+
+ RemoveAndWait(BrowsingDataRemover::DATA_TYPE_DOWNLOADS);
+ EXPECT_TRUE(IsHstsSet());
+}
+
+} // namespace content
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 3ec36b89181..8ef80765f0c 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
@@ -118,7 +118,7 @@ struct StoragePartitionRemovalData {
net::CanonicalCookie CreateCookieWithHost(const GURL& source) {
std::unique_ptr<net::CanonicalCookie> cookie(
- base::MakeUnique<net::CanonicalCookie>(
+ std::make_unique<net::CanonicalCookie>(
"A", "1", source.host(), "/", base::Time::Now(), base::Time::Now(),
base::Time(), false, false, net::CookieSameSite::DEFAULT_MODE,
net::COOKIE_PRIORITY_MEDIUM));
@@ -135,14 +135,7 @@ class StoragePartitionRemovalTestStoragePartition
void ClearDataForOrigin(uint32_t remove_mask,
uint32_t quota_storage_remove_mask,
const GURL& storage_origin,
- net::URLRequestContextGetter* rq_context,
- const base::Closure& callback) override {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(
- &StoragePartitionRemovalTestStoragePartition::AsyncRunCallback,
- base::Unretained(this), callback));
- }
+ net::URLRequestContextGetter* rq_context) override {}
void ClearData(uint32_t remove_mask,
uint32_t quota_storage_remove_mask,
@@ -150,7 +143,7 @@ class StoragePartitionRemovalTestStoragePartition
const OriginMatcherFunction& origin_matcher,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) override {
+ base::OnceClosure callback) override {
// Store stuff to verify parameters' correctness later.
storage_partition_removal_data_.remove_mask = remove_mask;
storage_partition_removal_data_.quota_storage_remove_mask =
@@ -163,7 +156,7 @@ class StoragePartitionRemovalTestStoragePartition
BrowserThread::UI, FROM_HERE,
base::BindOnce(
&StoragePartitionRemovalTestStoragePartition::AsyncRunCallback,
- base::Unretained(this), callback));
+ base::Unretained(this), std::move(callback)));
}
void ClearData(uint32_t remove_mask,
@@ -172,7 +165,7 @@ class StoragePartitionRemovalTestStoragePartition
const CookieMatcherFunction& cookie_matcher,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) override {
+ base::OnceClosure callback) override {
// Store stuff to verify parameters' correctness later.
storage_partition_removal_data_.remove_mask = remove_mask;
storage_partition_removal_data_.quota_storage_remove_mask =
@@ -186,7 +179,7 @@ class StoragePartitionRemovalTestStoragePartition
BrowserThread::UI, FROM_HERE,
base::BindOnce(
&StoragePartitionRemovalTestStoragePartition::AsyncRunCallback,
- base::Unretained(this), callback));
+ base::Unretained(this), std::move(callback)));
}
StoragePartitionRemovalData GetStoragePartitionRemovalData() {
@@ -194,7 +187,9 @@ class StoragePartitionRemovalTestStoragePartition
}
private:
- void AsyncRunCallback(const base::Closure& callback) { callback.Run(); }
+ void AsyncRunCallback(base::OnceClosure callback) {
+ std::move(callback).Run();
+ }
StoragePartitionRemovalData storage_partition_removal_data_;
@@ -345,7 +340,7 @@ class RemoveChannelIDTester : public net::SSLConfigService::Observer {
void AddChannelIDWithTimes(const std::string& server_identifier,
base::Time creation_time) {
GetChannelIDStore()->SetChannelID(
- base::MakeUnique<net::ChannelIDStore::ChannelID>(
+ std::make_unique<net::ChannelIDStore::ChannelID>(
server_identifier, creation_time, crypto::ECPrivateKey::Create()));
}
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 dcc9b914aa3..6ae2becc42e 100644
--- a/chromium/content/browser/browsing_data/clear_site_data_throttle.cc
+++ b/chromium/content/browser/browsing_data/clear_site_data_throttle.cc
@@ -4,6 +4,7 @@
#include "content/browser/browsing_data/clear_site_data_throttle.h"
+#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/scoped_observer.h"
@@ -18,6 +19,7 @@
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/origin_util.h"
#include "content/public/common/resource_response_info.h"
#include "content/public/common/resource_type.h"
@@ -37,6 +39,7 @@ const char kNameForLogging[] = "ClearSiteDataThrottle";
const char kClearSiteDataHeader[] = "Clear-Site-Data";
// Datatypes.
+const char kDatatypeWildcard[] = "\"*\"";
const char kDatatypeCookies[] = "\"cookies\"";
const char kDatatypeStorage[] = "\"storage\"";
const char kDatatypeCache[] = "\"cache\"";
@@ -46,6 +49,11 @@ const char kConsoleMessageTemplate[] = "Clear-Site-Data header on '%s': %s";
const char kConsoleMessageCleared[] = "Cleared data types: %s.";
const char kConsoleMessageDatatypeSeparator[] = ", ";
+bool AreExperimentalFeaturesEnabled() {
+ return base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableExperimentalWebPlatformFeatures);
+}
+
bool IsNavigationRequest(net::URLRequest* request) {
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
return info && IsResourceTypeFrame(info->GetResourceType());
@@ -270,7 +278,7 @@ ClearSiteDataThrottle::MaybeCreateThrottleForRequest(net::URLRequest* request) {
return nullptr;
return base::WrapUnique(new ClearSiteDataThrottle(
- request, base::MakeUnique<ConsoleMessagesDelegate>()));
+ request, std::make_unique<ConsoleMessagesDelegate>()));
}
ClearSiteDataThrottle::~ClearSiteDataThrottle() {
@@ -354,7 +362,7 @@ bool ClearSiteDataThrottle::HandleHeader() {
return false;
}
- url::Origin origin(GetCurrentURL());
+ url::Origin origin = url::Origin::Create(GetCurrentURL());
if (origin.unique()) {
delegate_->AddMessage(GetCurrentURL(), "Not supported for unique origins.",
CONSOLE_MESSAGE_LEVEL_ERROR);
@@ -447,25 +455,33 @@ bool ClearSiteDataThrottle::ParseHeader(const std::string& header,
*clear_storage = false;
*clear_cache = false;
- std::string type_names;
- for (const base::StringPiece& type : base::SplitStringPiece(
- header, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
+ std::vector<std::string> input_types = base::SplitString(
+ header, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ std::string output_types;
+
+ for (unsigned i = 0; i < input_types.size(); i++) {
bool* data_type = nullptr;
- if (type == kDatatypeCookies) {
+ if (AreExperimentalFeaturesEnabled() &&
+ input_types[i] == kDatatypeWildcard) {
+ input_types.push_back(kDatatypeCookies);
+ input_types.push_back(kDatatypeStorage);
+ input_types.push_back(kDatatypeCache);
+ continue;
+ } else if (input_types[i] == kDatatypeCookies) {
data_type = clear_cookies;
- } else if (type == kDatatypeStorage) {
+ } else if (input_types[i] == kDatatypeStorage) {
data_type = clear_storage;
- } else if (type == kDatatypeCache) {
+ } else if (input_types[i] == kDatatypeCache) {
delegate->AddMessage(
current_url, "The \"cache\" datatype is temporarily not supported.",
CONSOLE_MESSAGE_LEVEL_ERROR);
continue;
} else {
- delegate->AddMessage(current_url,
- base::StringPrintf("Unrecognized type: %s.",
- type.as_string().c_str()),
- CONSOLE_MESSAGE_LEVEL_ERROR);
+ delegate->AddMessage(
+ current_url,
+ base::StringPrintf("Unrecognized type: %s.", input_types[i].c_str()),
+ CONSOLE_MESSAGE_LEVEL_ERROR);
continue;
}
@@ -475,9 +491,9 @@ bool ClearSiteDataThrottle::ParseHeader(const std::string& header,
continue;
*data_type = true;
- if (!type_names.empty())
- type_names += kConsoleMessageDatatypeSeparator;
- type_names += type.as_string();
+ if (!output_types.empty())
+ output_types += kConsoleMessageDatatypeSeparator;
+ output_types += input_types[i];
}
if (!*clear_cookies && !*clear_storage && !*clear_cache) {
@@ -489,7 +505,7 @@ bool ClearSiteDataThrottle::ParseHeader(const std::string& header,
// Pretty-print which types are to be cleared.
delegate->AddMessage(
current_url,
- base::StringPrintf(kConsoleMessageCleared, type_names.c_str()),
+ base::StringPrintf(kConsoleMessageCleared, output_types.c_str()),
CONSOLE_MESSAGE_LEVEL_INFO);
return true;
diff --git a/chromium/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc b/chromium/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
index c8824b59894..892e45a9018 100644
--- a/chromium/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
+++ b/chromium/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
@@ -437,7 +437,8 @@ IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest,
AddQuery(&urls[i], "header", kClearCookiesHeader);
if (mask & (1 << i))
- delegate()->ExpectClearSiteDataCookiesCall(url::Origin(urls[i]));
+ delegate()->ExpectClearSiteDataCookiesCall(
+ url::Origin::Create(urls[i]));
}
// Set up redirects between urls 0 --> 1 --> 2.
@@ -484,7 +485,8 @@ IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest,
AddQuery(&urls[i], "header", kClearCookiesHeader);
if (mask & (1 << i))
- delegate()->ExpectClearSiteDataCookiesCall(url::Origin(urls[i]));
+ delegate()->ExpectClearSiteDataCookiesCall(
+ url::Origin::Create(urls[i]));
}
// Set up redirects between urls 0 --> 1 --> 2.
@@ -572,13 +574,13 @@ IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest,
AddQuery(&secure_page, "html", content_with_secure_image);
// Secure resource on an insecure page does execute Clear-Site-Data.
- delegate()->ExpectClearSiteDataCookiesCall(url::Origin(secure_image));
+ delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(secure_image));
NavigateToURL(shell(), secure_page);
delegate()->VerifyAndClearExpectations();
// Secure resource on a secure page does execute Clear-Site-Data.
- delegate()->ExpectClearSiteDataCookiesCall(url::Origin(secure_image));
+ delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(secure_image));
NavigateToURL(shell(), secure_page);
delegate()->VerifyAndClearExpectations();
@@ -620,10 +622,10 @@ IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, ServiceWorker) {
// but not by the "/resource_from_sw" fetch. |origin3| and |origin4| prove
// that the number of calls is dependent on the number of network responses,
// i.e. that it isn't always 1 as in the case of |origin1| and |origin2|.
- delegate()->ExpectClearSiteDataCookiesCall(url::Origin(origin1));
- delegate()->ExpectClearSiteDataCookiesCall(url::Origin(origin4));
- delegate()->ExpectClearSiteDataCookiesCall(url::Origin(origin2));
- delegate()->ExpectClearSiteDataCookiesCall(url::Origin(origin4));
+ delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(origin1));
+ delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(origin4));
+ delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(origin2));
+ delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(origin4));
url = https_server()->GetURL("origin1.com", "/anything-in-workers-scope");
AddQuery(&url, "origin1", origin1.spec());
@@ -693,7 +695,7 @@ IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, MAYBE_Credentials) {
AddQuery(&page, "html", content);
if (test_case.should_run)
- delegate()->ExpectClearSiteDataCookiesCall(url::Origin(resource));
+ delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(resource));
NavigateToURL(shell(), page);
WaitForTitle(shell(), "done");
@@ -734,7 +736,7 @@ IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest,
"</script></body></html>",
urls[0].spec().c_str());
- delegate()->ExpectClearSiteDataCookiesCall(url::Origin(urls[0]));
+ delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(urls[0]));
GURL page = https_server()->GetURL("origin1.com", "/");
AddQuery(&page, "html", content);
@@ -772,8 +774,8 @@ IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, Types) {
AddQuery(&url, "header", test_case.value);
delegate()->ExpectClearSiteDataCall(
- url::Origin(url), test_case.remove_cookies, test_case.remove_storage,
- test_case.remove_cache);
+ url::Origin::Create(url), test_case.remove_cookies,
+ test_case.remove_storage, test_case.remove_cache);
NavigateToURL(shell(), url);
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 977f4d83dca..6406afa3378 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
@@ -13,6 +13,7 @@
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_task_environment.h"
#include "content/public/browser/resource_request_info.h"
+#include "content/public/common/content_switches.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/load_flags.h"
@@ -161,7 +162,7 @@ TEST_F(ClearSiteDataThrottleTest, MaybeCreateThrottleForRequest) {
// We can create the throttle for a valid ResourceRequestInfo.
ResourceRequestInfo::AllocateForTesting(request.get(), RESOURCE_TYPE_IMAGE,
nullptr, 0, 0, 0, false, true, true,
- false);
+ false, nullptr);
EXPECT_TRUE(
ClearSiteDataThrottle::MaybeCreateThrottleForRequest(request.get()));
}
@@ -172,7 +173,9 @@ TEST_F(ClearSiteDataThrottleTest, ParseHeaderAndExecuteClearingTask) {
bool cookies;
bool storage;
bool cache;
- } test_cases[] = {
+ };
+
+ std::vector<TestCase> standard_test_cases = {
// One data type.
{"\"cookies\"", true, false, false},
{"\"storage\"", false, true, false},
@@ -195,6 +198,11 @@ TEST_F(ClearSiteDataThrottleTest, ParseHeaderAndExecuteClearingTask) {
{"\"cache\", \"cookies\", \"storage\"", true, true, false},
{"\"cookies\", \"storage\", \"cache\"", true, true, false},
+ // The wildcard datatype is not yet shipped.
+ {"\"*\", \"storage\"", false, true, false},
+ {"\"cookies\", \"*\", \"storage\"", true, true, false},
+ {"\"*\", \"cookies\", \"*\"", true, false, false},
+
// Different formatting.
{"\"cookies\"", true, false, false},
@@ -209,44 +217,65 @@ TEST_F(ClearSiteDataThrottleTest, ParseHeaderAndExecuteClearingTask) {
{"\"storage\", \"foo\"", false, true, false},
};
- for (const TestCase& test_case : test_cases) {
- SCOPED_TRACE(test_case.header);
+ std::vector<TestCase> experimental_test_cases = {
+ // Wildcard.
+ // TODO(crbug.com/762417): The "cache" parameter is temporarily disabled.
+ {"\"*\"", true, true, false},
+ {"\"*\", \"storage\"", true, true, false},
+ {"\"cache\", \"*\", \"storage\"", true, true, false},
+ {"\"*\", \"cookies\", \"*\"", true, true, false},
+ };
- // Test that ParseHeader works correctly.
- bool actual_cookies;
- bool actual_storage;
- bool actual_cache;
+ const std::vector<TestCase>* test_case_sets[] = {&standard_test_cases,
+ &experimental_test_cases};
- GURL url("https://example.com");
- ConsoleMessagesDelegate console_delegate;
+ for (const std::vector<TestCase>* test_cases : test_case_sets) {
+ base::test::ScopedCommandLine scoped_command_line;
+ if (test_cases == &experimental_test_cases) {
+ scoped_command_line.GetProcessCommandLine()->AppendSwitch(
+ switches::kEnableExperimentalWebPlatformFeatures);
+ }
- EXPECT_TRUE(ClearSiteDataThrottle::ParseHeaderForTesting(
- test_case.header, &actual_cookies, &actual_storage, &actual_cache,
- &console_delegate, url));
+ for (const TestCase& test_case : *test_cases) {
+ SCOPED_TRACE(test_case.header);
- EXPECT_EQ(test_case.cookies, actual_cookies);
- EXPECT_EQ(test_case.storage, actual_storage);
- EXPECT_EQ(test_case.cache, actual_cache);
+ // Test that ParseHeader works correctly.
+ bool actual_cookies;
+ bool actual_storage;
+ bool actual_cache;
- // Test that a call with the above parameters actually reaches
- // ExecuteClearingTask().
- net::TestURLRequestContext context;
- std::unique_ptr<net::URLRequest> request(context.CreateRequest(
- url, net::DEFAULT_PRIORITY, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS));
- TestThrottle throttle(request.get(),
- base::MakeUnique<ConsoleMessagesDelegate>());
- MockResourceThrottleDelegate delegate;
- throttle.set_delegate_for_testing(&delegate);
- throttle.SetResponseHeaders(std::string(kClearSiteDataHeaderPrefix) +
- test_case.header);
+ GURL url("https://example.com");
+ ConsoleMessagesDelegate console_delegate;
- EXPECT_CALL(throttle, ClearSiteData(url::Origin(url), test_case.cookies,
- test_case.storage, test_case.cache));
- bool defer;
- throttle.WillProcessResponse(&defer);
- EXPECT_TRUE(defer);
+ EXPECT_TRUE(ClearSiteDataThrottle::ParseHeaderForTesting(
+ test_case.header, &actual_cookies, &actual_storage, &actual_cache,
+ &console_delegate, url));
- testing::Mock::VerifyAndClearExpectations(&throttle);
+ EXPECT_EQ(test_case.cookies, actual_cookies);
+ EXPECT_EQ(test_case.storage, actual_storage);
+ EXPECT_EQ(test_case.cache, actual_cache);
+
+ // Test that a call with the above parameters actually reaches
+ // ExecuteClearingTask().
+ net::TestURLRequestContext context;
+ std::unique_ptr<net::URLRequest> request(context.CreateRequest(
+ url, net::DEFAULT_PRIORITY, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS));
+ TestThrottle throttle(request.get(),
+ std::make_unique<ConsoleMessagesDelegate>());
+ MockResourceThrottleDelegate delegate;
+ throttle.set_delegate_for_testing(&delegate);
+ throttle.SetResponseHeaders(std::string(kClearSiteDataHeaderPrefix) +
+ test_case.header);
+
+ EXPECT_CALL(throttle,
+ ClearSiteData(url::Origin::Create(url), test_case.cookies,
+ test_case.storage, test_case.cache));
+ bool defer;
+ throttle.WillProcessResponse(&defer);
+ EXPECT_TRUE(defer);
+
+ testing::Mock::VerifyAndClearExpectations(&throttle);
+ }
}
}
@@ -264,8 +293,9 @@ TEST_F(ClearSiteDataThrottleTest, InvalidHeader) {
{"\"cache\"",
"The \"cache\" datatype is temporarily not supported.\n"
"No recognized types specified.\n"},
- {"[ \"list\" ]",
- "Unrecognized type: [ \"list\" ].\n"
+ // The wildcard datatype is not yet shipped.
+ {"[ \"*\" ]",
+ "Unrecognized type: [ \"*\" ].\n"
"No recognized types specified.\n"},
{"[ \"list\" ]",
"Unrecognized type: [ \"list\" ].\n"
@@ -472,7 +502,7 @@ TEST_F(ClearSiteDataThrottleTest, DeferAndResume) {
context.CreateRequest(GURL(test_origin.origin), net::DEFAULT_PRIORITY,
nullptr, TRAFFIC_ANNOTATION_FOR_TESTS));
TestThrottle throttle(request.get(),
- base::MakeUnique<ConsoleMessagesDelegate>());
+ std::make_unique<ConsoleMessagesDelegate>());
throttle.SetResponseHeaders(test_case.response_headers);
MockResourceThrottleDelegate delegate;
@@ -487,7 +517,8 @@ TEST_F(ClearSiteDataThrottleTest, DeferAndResume) {
if (expected_defer) {
testing::Expectation expectation = EXPECT_CALL(
throttle,
- ClearSiteData(url::Origin(GURL(test_origin.origin)), _, _, _));
+ ClearSiteData(url::Origin::Create(GURL(test_origin.origin)), _, _,
+ _));
EXPECT_CALL(delegate, Resume()).After(expectation);
} else {
EXPECT_CALL(throttle, ClearSiteData(_, _, _, _)).Times(0);
@@ -580,13 +611,13 @@ TEST_F(ClearSiteDataThrottleTest, FormattedConsoleOutput) {
ResourceRequestInfo::AllocateForTesting(
request.get(),
navigation ? RESOURCE_TYPE_SUB_FRAME : RESOURCE_TYPE_IMAGE, nullptr, 0,
- 0, 0, false, true, true, false);
+ 0, 0, false, true, true, false, nullptr);
std::string output_buffer;
std::unique_ptr<RedirectableTestThrottle> throttle =
- base::MakeUnique<RedirectableTestThrottle>(
+ std::make_unique<RedirectableTestThrottle>(
request.get(),
- base::MakeUnique<StringConsoleMessagesDelegate>(&output_buffer));
+ std::make_unique<StringConsoleMessagesDelegate>(&output_buffer));
MockResourceThrottleDelegate delegate;
throttle->set_delegate_for_testing(&delegate);
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 57a8b12d4fd..4f6d6122fcb 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
@@ -45,14 +45,14 @@ bool HasHttpsExampleOrigin(const GURL& url) {
class ConditionalCacheDeletionHelperBrowserTest : public ContentBrowserTest {
public:
void SetUpOnMainThread() override {
- cache_util_ = base::MakeUnique<CacheTestUtil>(
+ cache_util_ = std::make_unique<CacheTestUtil>(
content::BrowserContext::GetDefaultStoragePartition(
shell()->web_contents()->GetBrowserContext()));
done_callback_ =
base::Bind(&ConditionalCacheDeletionHelperBrowserTest::DoneCallback,
base::Unretained(this));
// UI and IO thread synchronization.
- waitable_event_ = base::MakeUnique<base::WaitableEvent>(
+ waitable_event_ = std::make_unique<base::WaitableEvent>(
base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
}
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 a405c158312..a35112576b8 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
@@ -64,10 +64,10 @@ StoragePartitionHttpCacheDataRemover::CreateForURLsAndRange(
StoragePartitionHttpCacheDataRemover::~StoragePartitionHttpCacheDataRemover() {}
void StoragePartitionHttpCacheDataRemover::Remove(
- const base::Closure& done_callback) {
+ base::OnceClosure done_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!done_callback.is_null());
- done_callback_ = done_callback;
+ done_callback_ = std::move(done_callback);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -87,7 +87,7 @@ void StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread() {
void StoragePartitionHttpCacheDataRemover::ClearedHttpCache() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- done_callback_.Run();
+ std::move(done_callback_).Run();
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
@@ -160,12 +160,12 @@ void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache,
base::Unretained(this)));
}
- cache_ = NULL;
+ cache_ = nullptr;
}
break;
}
case CacheState::DONE: {
- cache_ = NULL;
+ cache_ = nullptr;
next_cache_state_ = CacheState::NONE;
// Notify the UI thread that we are done.
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 3e929a92198..6d644173b52 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
@@ -47,7 +47,7 @@ class StoragePartitionHttpCacheDataRemover {
base::Time delete_end);
// Calls |done_callback| upon completion and also destroys itself.
- void Remove(const base::Closure& done_callback);
+ void Remove(base::OnceClosure done_callback);
private:
enum CacheState {
@@ -85,7 +85,7 @@ class StoragePartitionHttpCacheDataRemover {
const scoped_refptr<net::URLRequestContextGetter> main_context_getter_;
const scoped_refptr<net::URLRequestContextGetter> media_context_getter_;
- base::Closure done_callback_;
+ base::OnceClosure done_callback_;
// IO.
int next_cache_state_;
diff --git a/chromium/content/browser/byte_stream.cc b/chromium/content/browser/byte_stream.cc
index 0244811c37c..48c6dbbda28 100644
--- a/chromium/content/browser/byte_stream.cc
+++ b/chromium/content/browser/byte_stream.cc
@@ -185,7 +185,7 @@ ByteStreamWriterImpl::ByteStreamWriterImpl(
my_lifetime_flag_(lifetime_flag),
input_contents_size_(0),
output_size_used_(0),
- peer_(NULL) {
+ peer_(nullptr) {
DCHECK(my_lifetime_flag_.get());
my_lifetime_flag_->is_alive = true;
}
@@ -313,7 +313,7 @@ ByteStreamReaderImpl::ByteStreamReaderImpl(
received_status_(false),
status_(0),
unreported_consumed_bytes_(0),
- peer_(NULL) {
+ peer_(nullptr) {
DCHECK(my_lifetime_flag_.get());
my_lifetime_flag_->is_alive = true;
}
diff --git a/chromium/content/browser/cache_storage/cache_storage.cc b/chromium/content/browser/cache_storage/cache_storage.cc
index fa919c192ad..8bc95186ccf 100644
--- a/chromium/content/browser/cache_storage/cache_storage.cc
+++ b/chromium/content/browser/cache_storage/cache_storage.cc
@@ -42,6 +42,7 @@
#include "storage/browser/quota/quota_manager_proxy.h"
using base::LazyInstance;
+using blink::mojom::CacheStorageError;
using crypto::SymmetricKey;
namespace content {
@@ -158,14 +159,12 @@ class CacheStorage::CacheLoader {
// Called when CacheStorage has created a cache. Used to hold onto a handle to
// the cache if necessary.
- virtual void NotifyCacheCreated(
- const std::string& cache_name,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle) {}
+ virtual void NotifyCacheCreated(const std::string& cache_name,
+ CacheStorageCacheHandle cache_handle) {}
// Notification that the cache for |cache_handle| has been doomed. If the
// loader is holding a handle to the cache, it should drop it now.
- virtual void NotifyCacheDoomed(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle) {}
+ virtual void NotifyCacheDoomed(CacheStorageCacheHandle cache_handle) {}
protected:
scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
@@ -228,26 +227,23 @@ class CacheStorage::MemoryLoader : public CacheStorage::CacheLoader {
}
void LoadIndex(CacheStorageIndexLoadCallback callback) override {
- std::move(callback).Run(base::MakeUnique<CacheStorageIndex>());
+ std::move(callback).Run(std::make_unique<CacheStorageIndex>());
}
- void NotifyCacheCreated(
- const std::string& cache_name,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle) override {
+ void NotifyCacheCreated(const std::string& cache_name,
+ CacheStorageCacheHandle cache_handle) override {
DCHECK(!base::ContainsKey(cache_handles_, cache_name));
cache_handles_.insert(std::make_pair(cache_name, std::move(cache_handle)));
};
- void NotifyCacheDoomed(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle) override {
+ void NotifyCacheDoomed(CacheStorageCacheHandle cache_handle) override {
DCHECK(
- base::ContainsKey(cache_handles_, cache_handle->value()->cache_name()));
- cache_handles_.erase(cache_handle->value()->cache_name());
+ base::ContainsKey(cache_handles_, cache_handle.value()->cache_name()));
+ cache_handles_.erase(cache_handle.value()->cache_name());
};
private:
- typedef std::map<std::string, std::unique_ptr<CacheStorageCacheHandle>>
- CacheHandles;
+ typedef std::map<std::string, CacheStorageCacheHandle> CacheHandles;
~MemoryLoader() override {}
// Keep a reference to each cache to ensure that it's not freed before the
@@ -399,7 +395,7 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader {
}
// Atomically rename the temporary index file to become the real one.
- return base::ReplaceFile(tmp_path, index_path, NULL);
+ return base::ReplaceFile(tmp_path, index_path, nullptr);
}
void LoadIndex(CacheStorageIndexLoadCallback callback) override {
@@ -420,7 +416,7 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader {
std::unique_ptr<std::set<std::string>> cache_dirs(
new std::set<std::string>);
- auto index = base::MakeUnique<CacheStorageIndex>();
+ auto index = std::make_unique<CacheStorageIndex>();
for (int i = 0, max = protobuf_index.cache_size(); i < max; ++i) {
const proto::CacheStorageIndex::Cache& cache = protobuf_index.cache(i);
DCHECK(cache.has_cache_dir());
@@ -458,13 +454,12 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader {
std::move(callback).Run(std::move(index));
}
- void NotifyCacheDoomed(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle) override {
+ void NotifyCacheDoomed(CacheStorageCacheHandle cache_handle) override {
DCHECK(base::ContainsKey(cache_name_to_cache_dir_,
- cache_handle->value()->cache_name()));
+ cache_handle.value()->cache_name()));
auto iter =
- cache_name_to_cache_dir_.find(cache_handle->value()->cache_name());
- doomed_cache_to_path_[cache_handle->value()] = iter->second;
+ cache_name_to_cache_dir_.find(cache_handle.value()->cache_name());
+ doomed_cache_to_path_[cache_handle.value()] = iter->second;
cache_name_to_cache_dir_.erase(iter);
};
@@ -632,8 +627,8 @@ void CacheStorage::HasCache(const std::string& cache_name,
scheduler_->WrapCallbackToRunNext(std::move(callback))));
}
-void CacheStorage::DeleteCache(const std::string& cache_name,
- BoolAndErrorCallback callback) {
+void CacheStorage::DoomCache(const std::string& cache_name,
+ BoolAndErrorCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!initialized_)
@@ -644,7 +639,7 @@ void CacheStorage::DeleteCache(const std::string& cache_name,
storage::kStorageTypeTemporary);
scheduler_->ScheduleOperation(base::BindOnce(
- &CacheStorage::DeleteCacheImpl, weak_factory_.GetWeakPtr(), cache_name,
+ &CacheStorage::DoomCacheImpl, weak_factory_.GetWeakPtr(), cache_name,
scheduler_->WrapCallbackToRunNext(std::move(callback))));
}
@@ -841,10 +836,10 @@ void CacheStorage::LazyInitDidLoadIndex(
void CacheStorage::OpenCacheImpl(const std::string& cache_name,
CacheAndErrorCallback callback) {
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- GetLoadedCache(cache_name);
- if (cache_handle) {
- std::move(callback).Run(std::move(cache_handle), CACHE_STORAGE_OK);
+ CacheStorageCacheHandle cache_handle = GetLoadedCache(cache_name);
+ if (cache_handle.value()) {
+ std::move(callback).Run(std::move(cache_handle),
+ CacheStorageError::kSuccess);
return;
}
@@ -864,8 +859,8 @@ void CacheStorage::CreateCacheDidCreateCache(
static_cast<bool>(cache));
if (!cache) {
- std::move(callback).Run(std::unique_ptr<CacheStorageCacheHandle>(),
- CACHE_STORAGE_ERROR_STORAGE);
+ std::move(callback).Run(CacheStorageCacheHandle(),
+ CacheStorageError::kErrorStorage);
return;
}
@@ -889,34 +884,33 @@ void CacheStorage::CreateCacheDidCreateCache(
void CacheStorage::CreateCacheDidWriteIndex(
CacheAndErrorCallback callback,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
bool success) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(cache_handle);
+ DCHECK(cache_handle.value());
// TODO(jkarlin): Handle !success.
- std::move(callback).Run(std::move(cache_handle), CACHE_STORAGE_OK);
+ std::move(callback).Run(std::move(cache_handle), CacheStorageError::kSuccess);
}
void CacheStorage::HasCacheImpl(const std::string& cache_name,
BoolAndErrorCallback callback) {
bool has_cache = base::ContainsKey(cache_map_, cache_name);
- std::move(callback).Run(has_cache, CACHE_STORAGE_OK);
+ std::move(callback).Run(has_cache, CacheStorageError::kSuccess);
}
-void CacheStorage::DeleteCacheImpl(const std::string& cache_name,
- BoolAndErrorCallback callback) {
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- GetLoadedCache(cache_name);
- if (!cache_handle) {
+void CacheStorage::DoomCacheImpl(const std::string& cache_name,
+ BoolAndErrorCallback callback) {
+ CacheStorageCacheHandle cache_handle = GetLoadedCache(cache_name);
+ if (!cache_handle.value()) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), false,
- CACHE_STORAGE_ERROR_NOT_FOUND));
+ CacheStorageError::kErrorNotFound));
return;
}
- cache_handle->value()->SetObserver(nullptr);
+ cache_handle.value()->SetObserver(nullptr);
cache_index_->DoomCache(cache_name);
cache_loader_->WriteIndex(
*cache_index_, base::BindOnce(&CacheStorage::DeleteCacheDidWriteIndex,
@@ -926,7 +920,7 @@ void CacheStorage::DeleteCacheImpl(const std::string& cache_name,
}
void CacheStorage::DeleteCacheDidWriteIndex(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
BoolAndErrorCallback callback,
bool success) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -934,15 +928,15 @@ void CacheStorage::DeleteCacheDidWriteIndex(
if (!success) {
// Undo any changes if the index couldn't be written to disk.
cache_index_->RestoreDoomedCache();
- cache_handle->value()->SetObserver(this);
- std::move(callback).Run(false, CACHE_STORAGE_ERROR_STORAGE);
+ cache_handle.value()->SetObserver(this);
+ std::move(callback).Run(false, CacheStorageError::kErrorStorage);
return;
}
cache_index_->FinalizeDoomedCache();
CacheMap::iterator map_iter =
- cache_map_.find(cache_handle->value()->cache_name());
+ cache_map_.find(cache_handle.value()->cache_name());
DCHECK(map_iter != cache_map_.end());
doomed_caches_.insert(
@@ -953,7 +947,7 @@ void CacheStorage::DeleteCacheDidWriteIndex(
if (cache_storage_manager_)
cache_storage_manager_->NotifyCacheListChanged(origin_);
- std::move(callback).Run(true, CACHE_STORAGE_OK);
+ std::move(callback).Run(true, CacheStorageError::kSuccess);
}
// Call this once the last handle to a doomed cache is gone. It's okay if this
@@ -985,11 +979,10 @@ void CacheStorage::MatchCacheImpl(
std::unique_ptr<ServiceWorkerFetchRequest> request,
const CacheStorageCacheQueryParams& match_params,
CacheStorageCache::ResponseCallback callback) {
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- GetLoadedCache(cache_name);
+ CacheStorageCacheHandle cache_handle = GetLoadedCache(cache_name);
- if (!cache_handle) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_CACHE_NAME_NOT_FOUND,
+ if (!cache_handle.value()) {
+ std::move(callback).Run(CacheStorageError::kErrorCacheNameNotFound,
std::unique_ptr<ServiceWorkerResponse>(),
std::unique_ptr<storage::BlobDataHandle>());
return;
@@ -997,7 +990,7 @@ void CacheStorage::MatchCacheImpl(
// Pass the cache handle along to the callback to keep the cache open until
// match is done.
- CacheStorageCache* cache_ptr = cache_handle->value();
+ CacheStorageCache* cache_ptr = cache_handle.value();
cache_ptr->Match(std::move(request), match_params,
base::BindOnce(&CacheStorage::MatchCacheDidMatch,
weak_factory_.GetWeakPtr(),
@@ -1006,7 +999,7 @@ void CacheStorage::MatchCacheImpl(
}
void CacheStorage::MatchCacheDidMatch(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheStorageCache::ResponseCallback callback,
CacheStorageError error,
std::unique_ptr<ServiceWorkerResponse> response,
@@ -1030,13 +1023,12 @@ void CacheStorage::MatchAllCachesImpl(
size_t idx = 0;
for (const auto& cache_metadata : cache_index_->ordered_cache_metadata()) {
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- GetLoadedCache(cache_metadata.name);
- DCHECK(cache_handle);
+ CacheStorageCacheHandle cache_handle = GetLoadedCache(cache_metadata.name);
+ DCHECK(cache_handle.value());
- CacheStorageCache* cache_ptr = cache_handle->value();
+ CacheStorageCache* cache_ptr = cache_handle.value();
cache_ptr->Match(
- base::MakeUnique<ServiceWorkerFetchRequest>(*request), match_params,
+ std::make_unique<ServiceWorkerFetchRequest>(*request), match_params,
base::BindOnce(&CacheStorage::MatchAllCachesDidMatch,
weak_factory_.GetWeakPtr(),
base::Passed(std::move(cache_handle)),
@@ -1046,7 +1038,7 @@ void CacheStorage::MatchAllCachesImpl(
}
void CacheStorage::MatchAllCachesDidMatch(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheMatchResponse* out_match_response,
const base::RepeatingClosure& barrier_closure,
CacheStorageError error,
@@ -1063,14 +1055,14 @@ void CacheStorage::MatchAllCachesDidMatchAll(
std::unique_ptr<std::vector<CacheMatchResponse>> match_responses,
CacheStorageCache::ResponseCallback callback) {
for (CacheMatchResponse& match_response : *match_responses) {
- if (match_response.error == CACHE_STORAGE_ERROR_NOT_FOUND)
+ if (match_response.error == CacheStorageError::kErrorNotFound)
continue;
std::move(callback).Run(match_response.error,
std::move(match_response.service_worker_response),
std::move(match_response.blob_data_handle));
return;
}
- std::move(callback).Run(CACHE_STORAGE_ERROR_NOT_FOUND,
+ std::move(callback).Run(CacheStorageError::kErrorNotFound,
std::unique_ptr<ServiceWorkerResponse>(),
std::unique_ptr<storage::BlobDataHandle>());
}
@@ -1109,21 +1101,21 @@ void CacheStorage::DropCacheHandleRef(CacheStorageCache* cache) {
}
}
-std::unique_ptr<CacheStorageCacheHandle> CacheStorage::CreateCacheHandle(
+CacheStorageCacheHandle CacheStorage::CreateCacheHandle(
CacheStorageCache* cache) {
DCHECK(cache);
- return std::unique_ptr<CacheStorageCacheHandle>(new CacheStorageCacheHandle(
- cache->AsWeakPtr(), weak_factory_.GetWeakPtr()));
+ return CacheStorageCacheHandle(cache->AsWeakPtr(),
+ weak_factory_.GetWeakPtr());
}
-std::unique_ptr<CacheStorageCacheHandle> CacheStorage::GetLoadedCache(
+CacheStorageCacheHandle CacheStorage::GetLoadedCache(
const std::string& cache_name) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(initialized_);
CacheMap::iterator map_iter = cache_map_.find(cache_name);
if (map_iter == cache_map_.end())
- return std::unique_ptr<CacheStorageCacheHandle>();
+ return CacheStorageCacheHandle();
CacheStorageCache* cache = map_iter->second.get();
@@ -1143,12 +1135,12 @@ std::unique_ptr<CacheStorageCacheHandle> CacheStorage::GetLoadedCache(
return CreateCacheHandle(cache);
}
-void CacheStorage::SizeRetrievedFromCache(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- base::OnceClosure closure,
- int64_t* accumulator,
- int64_t size) {
- cache_index_->SetCacheSize(cache_handle->value()->cache_name(), size);
+void CacheStorage::SizeRetrievedFromCache(CacheStorageCacheHandle cache_handle,
+ base::OnceClosure closure,
+ int64_t* accumulator,
+ int64_t size) {
+ if (doomed_caches_.find(cache_handle.value()) == doomed_caches_.end())
+ cache_index_->SetCacheSize(cache_handle.value()->cache_name(), size);
*accumulator += size;
std::move(closure).Run();
}
@@ -1161,19 +1153,27 @@ void CacheStorage::GetSizeThenCloseAllCachesImpl(SizeCallback callback) {
int64_t* accumulator_ptr = accumulator.get();
base::RepeatingClosure barrier_closure =
- base::BarrierClosure(cache_index_->num_entries(),
+ base::BarrierClosure(cache_index_->num_entries() + doomed_caches_.size(),
base::BindOnce(&SizeRetrievedFromAllCaches,
base::Passed(std::move(accumulator)),
std::move(callback)));
for (const auto& cache_metadata : cache_index_->ordered_cache_metadata()) {
auto cache_handle = GetLoadedCache(cache_metadata.name);
- CacheStorageCache* cache = cache_handle->value();
+ CacheStorageCache* cache = cache_handle.value();
cache->GetSizeThenClose(base::BindOnce(
&CacheStorage::SizeRetrievedFromCache, weak_factory_.GetWeakPtr(),
base::Passed(std::move(cache_handle)), barrier_closure,
accumulator_ptr));
}
+
+ for (const auto& cache_it : doomed_caches_) {
+ CacheStorageCache* cache = cache_it.first;
+ cache->GetSizeThenClose(base::BindOnce(
+ &CacheStorage::SizeRetrievedFromCache, weak_factory_.GetWeakPtr(),
+ CacheStorageCacheHandle(cache->AsWeakPtr(), weak_factory_.GetWeakPtr()),
+ barrier_closure, accumulator_ptr));
+ }
}
void CacheStorage::SizeImpl(SizeCallback callback) {
@@ -1202,9 +1202,8 @@ void CacheStorage::SizeImpl(SizeCallback callback) {
barrier_closure.Run();
continue;
}
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- GetLoadedCache(cache_metadata.name);
- CacheStorageCache* cache = cache_handle->value();
+ CacheStorageCacheHandle cache_handle = GetLoadedCache(cache_metadata.name);
+ CacheStorageCache* cache = cache_handle.value();
cache->Size(base::BindOnce(&CacheStorage::SizeRetrievedFromCache,
weak_factory_.GetWeakPtr(),
base::Passed(std::move(cache_handle)),
diff --git a/chromium/content/browser/cache_storage/cache_storage.h b/chromium/content/browser/cache_storage/cache_storage.h
index c9c4f2de92c..9f50974ad12 100644
--- a/chromium/content/browser/cache_storage/cache_storage.h
+++ b/chromium/content/browser/cache_storage/cache_storage.h
@@ -20,6 +20,7 @@
#include "base/memory/weak_ptr.h"
#include "content/browser/cache_storage/cache_storage_cache.h"
#include "content/browser/cache_storage/cache_storage_cache_observer.h"
+#include "third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h"
namespace base {
class SequencedTaskRunner;
@@ -49,10 +50,10 @@ class CONTENT_EXPORT CacheStorage : public CacheStorageCacheObserver {
constexpr static int64_t kSizeUnknown = -1;
using BoolAndErrorCallback =
- base::OnceCallback<void(bool, CacheStorageError)>;
+ base::OnceCallback<void(bool, blink::mojom::CacheStorageError)>;
using CacheAndErrorCallback =
- base::OnceCallback<void(std::unique_ptr<CacheStorageCacheHandle>,
- CacheStorageError)>;
+ base::OnceCallback<void(CacheStorageCacheHandle,
+ blink::mojom::CacheStorageError)>;
using IndexCallback = base::OnceCallback<void(const CacheStorageIndex&)>;
using SizeCallback = base::OnceCallback<void(int64_t)>;
@@ -83,13 +84,11 @@ class CONTENT_EXPORT CacheStorage : public CacheStorageCacheObserver {
void HasCache(const std::string& cache_name, BoolAndErrorCallback callback);
// Deletes the cache if it exists. If it doesn't exist,
- // CACHE_STORAGE_ERROR_NOT_FOUND is returned. Any existing
- // CacheStorageCacheHandle(s) to the cache will remain valid but future
- // CacheStorage operations won't be able to access the cache. The cache
+ // blink::mojom::CacheStorageError::kErrorNotFound is returned. Any
+ // existing CacheStorageCacheHandle(s) to the cache will remain valid but
+ // future CacheStorage operations won't be able to access the cache. The cache
// isn't actually erased from disk until the last handle is dropped.
- // TODO(jkarlin): Rename to DoomCache.
- void DeleteCache(const std::string& cache_name,
- BoolAndErrorCallback callback);
+ void DoomCache(const std::string& cache_name, BoolAndErrorCallback callback);
// Calls the callback with the cache index.
void EnumerateCaches(IndexCallback callback);
@@ -103,13 +102,14 @@ class CONTENT_EXPORT CacheStorage : public CacheStorageCacheObserver {
// Calls match on all of the caches in parallel, calling |callback| with the
// response from the first cache (in order of cache creation) to have the
// entry. If no response is found then |callback| is called with
- // CACHE_STORAGE_ERROR_NOT_FOUND.
+ // blink::mojom::CacheStorageError::kErrorNotFound.
void MatchAllCaches(std::unique_ptr<ServiceWorkerFetchRequest> request,
const CacheStorageCacheQueryParams& match_params,
CacheStorageCache::ResponseCallback callback);
// Sums the sizes of each cache and closes them. Runs |callback| with the
- // size.
+ // size. The sizes include any doomed caches and will also force close all
+ // caches even if there are existing handles to them.
void GetSizeThenCloseAllCaches(SizeCallback callback);
// The size of all of the origin's contents. This value should be used as an
@@ -145,15 +145,13 @@ class CONTENT_EXPORT CacheStorage : public CacheStorageCacheObserver {
static void GenerateNewKeyForTesting();
// Functions for exposing handles to CacheStorageCache to clients.
- std::unique_ptr<CacheStorageCacheHandle> CreateCacheHandle(
- CacheStorageCache* cache);
+ CacheStorageCacheHandle CreateCacheHandle(CacheStorageCache* cache);
void AddCacheHandleRef(CacheStorageCache* cache);
void DropCacheHandleRef(CacheStorageCache* cache);
// Returns a CacheStorageCacheHandle for the given name if the name is known.
// If the CacheStorageCache has been deleted, creates a new one.
- std::unique_ptr<CacheStorageCacheHandle> GetLoadedCache(
- const std::string& cache_name);
+ CacheStorageCacheHandle GetLoadedCache(const std::string& cache_name);
// Initializer and its callback are below.
void LazyInit();
@@ -166,22 +164,20 @@ class CONTENT_EXPORT CacheStorage : public CacheStorageCacheObserver {
void CreateCacheDidCreateCache(const std::string& cache_name,
CacheAndErrorCallback callback,
std::unique_ptr<CacheStorageCache> cache);
- void CreateCacheDidWriteIndex(
- CacheAndErrorCallback callback,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- bool success);
+ void CreateCacheDidWriteIndex(CacheAndErrorCallback callback,
+ CacheStorageCacheHandle cache_handle,
+ bool success);
// The HasCache callbacks are below.
void HasCacheImpl(const std::string& cache_name,
BoolAndErrorCallback callback);
// The DeleteCache callbacks are below.
- void DeleteCacheImpl(const std::string& cache_name,
- BoolAndErrorCallback callback);
- void DeleteCacheDidWriteIndex(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- BoolAndErrorCallback callback,
- bool success);
+ void DoomCacheImpl(const std::string& cache_name,
+ BoolAndErrorCallback callback);
+ void DeleteCacheDidWriteIndex(CacheStorageCacheHandle cache_handle,
+ BoolAndErrorCallback callback,
+ bool success);
void DeleteCacheFinalize(CacheStorageCache* doomed_cache);
void DeleteCacheDidGetSize(CacheStorageCache* doomed_cache,
int64_t cache_size);
@@ -195,9 +191,9 @@ class CONTENT_EXPORT CacheStorage : public CacheStorageCacheObserver {
std::unique_ptr<ServiceWorkerFetchRequest> request,
const CacheStorageCacheQueryParams& match_params,
CacheStorageCache::ResponseCallback callback);
- void MatchCacheDidMatch(std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ void MatchCacheDidMatch(CacheStorageCacheHandle cache_handle,
CacheStorageCache::ResponseCallback callback,
- CacheStorageError error,
+ blink::mojom::CacheStorageError error,
std::unique_ptr<ServiceWorkerResponse> response,
std::unique_ptr<storage::BlobDataHandle> handle);
@@ -206,10 +202,10 @@ class CONTENT_EXPORT CacheStorage : public CacheStorageCacheObserver {
const CacheStorageCacheQueryParams& match_params,
CacheStorageCache::ResponseCallback callback);
void MatchAllCachesDidMatch(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheMatchResponse* out_match_response,
const base::RepeatingClosure& barrier_closure,
- CacheStorageError error,
+ blink::mojom::CacheStorageError error,
std::unique_ptr<ServiceWorkerResponse> service_worker_response,
std::unique_ptr<storage::BlobDataHandle> handle);
void MatchAllCachesDidMatchAll(
@@ -219,11 +215,10 @@ class CONTENT_EXPORT CacheStorage : public CacheStorageCacheObserver {
void GetSizeThenCloseAllCachesImpl(SizeCallback callback);
void SizeImpl(SizeCallback callback);
- void SizeRetrievedFromCache(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- base::OnceClosure closure,
- int64_t* accumulator,
- int64_t size);
+ void SizeRetrievedFromCache(CacheStorageCacheHandle cache_handle,
+ base::OnceClosure closure,
+ int64_t* accumulator,
+ int64_t size);
void NotifyCacheContentChanged(const std::string& cache_name);
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 a650aaa6b7b..4eaf403f1b6 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
@@ -62,8 +62,7 @@ class NullURLRequestContextGetter : public net::URLRequestContextGetter {
// the memory.
std::unique_ptr<storage::BlobProtocolHandler> CreateMockBlobProtocolHandler(
storage::BlobStorageContext* blob_storage_context) {
- return base::MakeUnique<storage::BlobProtocolHandler>(blob_storage_context,
- nullptr);
+ return std::make_unique<storage::BlobProtocolHandler>(blob_storage_context);
}
// A CacheStorageBlobToDiskCache that can delay reading from blobs.
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache.cc b/chromium/content/browser/cache_storage/cache_storage_cache.cc
index fbcb30c940b..abf93d28473 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_cache.cc
@@ -19,6 +19,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "base/numerics/checked_math.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -47,6 +48,8 @@
#include "storage/common/blob_storage/blob_handle.h"
#include "storage/common/storage_histograms.h"
+using blink::mojom::CacheStorageError;
+
namespace content {
namespace {
@@ -74,15 +77,14 @@ const int32_t kCachePaddingAlgorithmVersion = 2;
class CacheStorageCacheDataHandle
: public storage::BlobDataBuilder::DataHandle {
public:
- CacheStorageCacheDataHandle(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- disk_cache::ScopedEntryPtr entry)
+ CacheStorageCacheDataHandle(CacheStorageCacheHandle cache_handle,
+ disk_cache::ScopedEntryPtr entry)
: cache_handle_(std::move(cache_handle)), entry_(std::move(entry)) {}
private:
~CacheStorageCacheDataHandle() override {}
- std::unique_ptr<CacheStorageCacheHandle> cache_handle_;
+ CacheStorageCacheHandle cache_handle_;
disk_cache::ScopedEntryPtr entry_;
DISALLOW_COPY_AND_ASSIGN(CacheStorageCacheDataHandle);
@@ -224,7 +226,7 @@ void ReadMetadataDidReadMetadata(disk_cache::Entry* entry,
std::unique_ptr<ServiceWorkerFetchRequest> CreateRequest(
const proto::CacheMetadata& metadata,
const GURL& request_url) {
- auto request = base::MakeUnique<ServiceWorkerFetchRequest>(
+ auto request = std::make_unique<ServiceWorkerFetchRequest>(
request_url, metadata.request().method(), ServiceWorkerHeaderMap(),
Referrer(), false);
@@ -241,7 +243,7 @@ std::unique_ptr<ServiceWorkerResponse> CreateResponse(
const proto::CacheMetadata& metadata,
const std::string& cache_name) {
std::unique_ptr<std::vector<GURL>> url_list =
- base::MakeUnique<std::vector<GURL>>();
+ std::make_unique<std::vector<GURL>>();
// From Chrome 57, proto::CacheMetadata's url field was deprecated.
UMA_HISTOGRAM_BOOLEAN("ServiceWorkerCache.Response.HasDeprecatedURL",
metadata.response().has_url());
@@ -254,7 +256,7 @@ std::unique_ptr<ServiceWorkerResponse> CreateResponse(
}
std::unique_ptr<ServiceWorkerHeaderMap> headers =
- base::MakeUnique<ServiceWorkerHeaderMap>();
+ std::make_unique<ServiceWorkerHeaderMap>();
for (int i = 0; i < metadata.response().headers_size(); ++i) {
const proto::CacheHeaderMap header = metadata.response().headers(i);
DCHECK_EQ(std::string::npos, header.name().find('\0'));
@@ -262,15 +264,15 @@ std::unique_ptr<ServiceWorkerResponse> CreateResponse(
headers->insert(std::make_pair(header.name(), header.value()));
}
- return base::MakeUnique<ServiceWorkerResponse>(
+ return std::make_unique<ServiceWorkerResponse>(
std::move(url_list), metadata.response().status_code(),
metadata.response().status_text(),
ProtoResponseTypeToFetchResponseType(metadata.response().response_type()),
std::move(headers), "", 0, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown,
+ blink::mojom::ServiceWorkerResponseError::kUnknown,
base::Time::FromInternalValue(metadata.response().response_time()),
true /* is_in_cache_storage */, cache_name,
- base::MakeUnique<ServiceWorkerHeaderList>(
+ std::make_unique<ServiceWorkerHeaderList>(
metadata.response().cors_exposed_header_names().begin(),
metadata.response().cors_exposed_header_names().end()));
}
@@ -341,19 +343,24 @@ int64_t CalculateResponsePaddingInternal(
// The state needed to pass between CacheStorageCache::Put callbacks.
struct CacheStorageCache::PutContext {
- PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
- std::unique_ptr<ServiceWorkerResponse> response,
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
- CacheStorageCache::ErrorCallback callback)
+ PutContext(
+ std::unique_ptr<ServiceWorkerFetchRequest> request,
+ std::unique_ptr<ServiceWorkerResponse> response,
+ std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
+ std::unique_ptr<storage::BlobDataHandle> side_data_blob_data_handle,
+ CacheStorageCache::ErrorCallback callback)
: request(std::move(request)),
response(std::move(response)),
blob_data_handle(std::move(blob_data_handle)),
+ side_data_blob_data_handle(std::move(side_data_blob_data_handle)),
callback(std::move(callback)) {}
// Input parameters to the Put function.
std::unique_ptr<ServiceWorkerFetchRequest> request;
std::unique_ptr<ServiceWorkerResponse> response;
std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
+ std::unique_ptr<storage::BlobDataHandle> side_data_blob_data_handle;
+
CacheStorageCache::ErrorCallback callback;
disk_cache::ScopedEntryPtr cache_entry;
@@ -380,7 +387,7 @@ struct CacheStorageCache::QueryCacheContext {
options(options),
callback(std::move(callback)),
query_types(query_types),
- matches(base::MakeUnique<QueryCacheResults>()) {}
+ matches(std::make_unique<QueryCacheResults>()) {}
~QueryCacheContext() {
// If the CacheStorageCache is deleted before a backend operation to open
@@ -459,7 +466,7 @@ void CacheStorageCache::Match(
const CacheStorageCacheQueryParams& match_params,
ResponseCallback callback) {
if (backend_state_ == BACKEND_CLOSED) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE,
+ std::move(callback).Run(CacheStorageError::kErrorStorage,
std::unique_ptr<ServiceWorkerResponse>(),
std::unique_ptr<storage::BlobDataHandle>());
return;
@@ -476,8 +483,8 @@ void CacheStorageCache::MatchAll(
const CacheStorageCacheQueryParams& match_params,
ResponsesCallback callback) {
if (backend_state_ == BACKEND_CLOSED) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE,
- std::unique_ptr<Responses>(),
+ std::move(callback).Run(CacheStorageError::kErrorStorage,
+ std::vector<ServiceWorkerResponse>(),
std::unique_ptr<BlobDataHandles>());
return;
}
@@ -496,7 +503,7 @@ void CacheStorageCache::WriteSideData(ErrorCallback callback,
if (backend_state_ == BACKEND_CLOSED) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(std::move(callback), CACHE_STORAGE_ERROR_STORAGE));
+ base::BindOnce(std::move(callback), CacheStorageError::kErrorStorage));
return;
}
@@ -513,24 +520,38 @@ void CacheStorageCache::WriteSideData(ErrorCallback callback,
void CacheStorageCache::BatchOperation(
const std::vector<CacheStorageBatchOperation>& operations,
- ErrorCallback callback) {
+ ErrorCallback callback,
+ BadMessageCallback bad_message_callback) {
if (backend_state_ == BACKEND_CLOSED) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(std::move(callback), CACHE_STORAGE_ERROR_STORAGE));
+ base::BindOnce(std::move(callback), CacheStorageError::kErrorStorage));
return;
}
// Estimate the required size of the put operations. The size of the deletes
// is unknown and not considered.
- int64_t space_required = 0;
+ base::CheckedNumeric<uint64_t> safe_space_required = 0;
+ base::CheckedNumeric<uint64_t> safe_side_data_size = 0;
for (const auto& operation : operations) {
if (operation.operation_type == CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT) {
- space_required +=
- operation.request.blob_size + operation.response.blob_size;
+ safe_space_required += operation.request.blob_size;
+ safe_space_required += operation.response.blob_size;
+ safe_side_data_size += operation.response.side_data_blob_size;
}
}
- if (space_required > 0) {
+ if (!safe_space_required.IsValid() || !safe_side_data_size.IsValid()) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(std::move(bad_message_callback),
+ bad_message::CSDH_UNEXPECTED_OPERATION));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), CacheStorageError::kErrorStorage));
+ return;
+ }
+ uint64_t space_required = safe_space_required.ValueOrDie();
+ uint64_t side_data_size = safe_side_data_size.ValueOrDie();
+ if (space_required || side_data_size) {
// GetUsageAndQuota is called before entering a scheduled operation since it
// can call Size, another scheduled operation. This is racy. The decision
// to commit is made before the scheduled Put operation runs. By the time
@@ -539,32 +560,50 @@ void CacheStorageCache::BatchOperation(
quota_manager_proxy_->GetUsageAndQuota(
base::ThreadTaskRunnerHandle::Get().get(), origin_,
storage::kStorageTypeTemporary,
- base::AdaptCallbackForRepeating(
- base::BindOnce(&CacheStorageCache::BatchDidGetUsageAndQuota,
- weak_ptr_factory_.GetWeakPtr(), operations,
- std::move(callback), space_required)));
+ base::AdaptCallbackForRepeating(base::BindOnce(
+ &CacheStorageCache::BatchDidGetUsageAndQuota,
+ weak_ptr_factory_.GetWeakPtr(), operations, std::move(callback),
+ std::move(bad_message_callback), space_required, side_data_size)));
return;
}
- BatchDidGetUsageAndQuota(operations, std::move(callback),
- 0 /* space_required */, storage::kQuotaStatusOk,
- 0 /* usage */, 0 /* quota */);
+ BatchDidGetUsageAndQuota(
+ operations, std::move(callback), std::move(bad_message_callback),
+ 0 /* space_required */, 0 /* side_data_size */, storage::kQuotaStatusOk,
+ 0 /* usage */, 0 /* quota */);
}
void CacheStorageCache::BatchDidGetUsageAndQuota(
const std::vector<CacheStorageBatchOperation>& operations,
ErrorCallback callback,
- int64_t space_required,
+ BadMessageCallback bad_message_callback,
+ uint64_t space_required,
+ uint64_t side_data_size,
storage::QuotaStatusCode status_code,
int64_t usage,
int64_t quota) {
+ base::CheckedNumeric<uint64_t> safe_space_required = space_required;
+ base::CheckedNumeric<uint64_t> safe_space_required_with_side_data;
+ safe_space_required += usage;
+ safe_space_required_with_side_data = safe_space_required + side_data_size;
+ if (!safe_space_required.IsValid() ||
+ !safe_space_required_with_side_data.IsValid()) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(std::move(bad_message_callback),
+ bad_message::CSDH_UNEXPECTED_OPERATION));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), CacheStorageError::kErrorStorage));
+ return;
+ }
if (status_code != storage::kQuotaStatusOk ||
- space_required > quota - usage) {
+ safe_space_required.ValueOrDie() > quota) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
- CACHE_STORAGE_ERROR_QUOTA_EXCEEDED));
+ CacheStorageError::kErrorQuotaExceeded));
return;
}
+ bool skip_side_data = safe_space_required_with_side_data.ValueOrDie() > quota;
// The following relies on the guarantee that the RepeatingCallback returned
// from AdaptCallbackForRepeating invokes the original callback on the first
@@ -583,12 +622,20 @@ void CacheStorageCache::BatchDidGetUsageAndQuota(
// last reference to this instance. Hold a handle for the duration of this
// loop. (Asynchronous tasks scheduled by the operations use weak ptrs which
// will no-op automatically.)
- std::unique_ptr<CacheStorageCacheHandle> handle = CreateCacheHandle();
+ CacheStorageCacheHandle handle = CreateCacheHandle();
for (const auto& operation : operations) {
switch (operation.operation_type) {
case CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT:
- Put(operation, completion_callback);
+ if (skip_side_data) {
+ CacheStorageBatchOperation new_operation = operation;
+ new_operation.response.side_data_blob_uuid = std::string();
+ new_operation.response.side_data_blob_size = 0;
+ new_operation.response.side_data_blob = nullptr;
+ Put(new_operation, completion_callback);
+ } else {
+ Put(operation, completion_callback);
+ }
break;
case CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE:
DCHECK_EQ(1u, operations.size());
@@ -598,7 +645,7 @@ void CacheStorageCache::BatchDidGetUsageAndQuota(
NOTREACHED();
// TODO(nhiroki): This should return "TypeError".
// http://crbug.com/425505
- completion_callback.Run(CACHE_STORAGE_ERROR_STORAGE);
+ completion_callback.Run(CacheStorageError::kErrorStorage);
break;
}
}
@@ -608,7 +655,7 @@ void CacheStorageCache::BatchDidOneOperation(
base::OnceClosure completion_closure,
ErrorCallback error_callback,
CacheStorageError error) {
- if (error != CACHE_STORAGE_OK) {
+ if (error != CacheStorageError::kSuccess) {
// This relies on |callback| being created by AdaptCallbackForRepeating
// and ignoring anything but the first invocation.
std::move(error_callback).Run(error);
@@ -620,14 +667,14 @@ void CacheStorageCache::BatchDidOneOperation(
void CacheStorageCache::BatchDidAllOperations(ErrorCallback callback) {
// This relies on |callback| being created by AdaptCallbackForRepeating
// and ignoring anything but the first invocation.
- std::move(callback).Run(CACHE_STORAGE_OK);
+ std::move(callback).Run(CacheStorageError::kSuccess);
}
void CacheStorageCache::Keys(std::unique_ptr<ServiceWorkerFetchRequest> request,
const CacheStorageCacheQueryParams& options,
RequestsCallback callback) {
if (backend_state_ == BACKEND_CLOSED) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE,
+ std::move(callback).Run(CacheStorageError::kErrorStorage,
std::unique_ptr<Requests>());
return;
}
@@ -726,15 +773,15 @@ 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(CACHE_STORAGE_ERROR_STORAGE,
+ std::move(callback).Run(CacheStorageError::kErrorStorage,
std::unique_ptr<QueryCacheResults>());
return;
}
if (!options.ignore_method && request && !request->method.empty() &&
request->method != "GET") {
- std::move(callback).Run(CACHE_STORAGE_OK,
- base::MakeUnique<QueryCacheResults>());
+ std::move(callback).Run(CacheStorageError::kSuccess,
+ std::make_unique<QueryCacheResults>());
return;
}
@@ -769,7 +816,8 @@ void CacheStorageCache::QueryCacheDidOpenFastPath(
if (rv != net::OK) {
QueryCacheContext* results = query_cache_context.get();
std::move(results->callback)
- .Run(CACHE_STORAGE_OK, std::move(query_cache_context->matches));
+ .Run(CacheStorageError::kSuccess,
+ std::move(query_cache_context->matches));
return;
}
QueryCacheFilterEntry(std::move(query_cache_context), rv);
@@ -785,7 +833,8 @@ void CacheStorageCache::QueryCacheOpenNextEntry(
query_cache_context->matches->end(), QueryCacheResultCompare);
std::move(query_cache_context->callback)
- .Run(CACHE_STORAGE_OK, std::move(query_cache_context->matches));
+ .Run(CacheStorageError::kSuccess,
+ std::move(query_cache_context->matches));
return;
}
@@ -815,7 +864,7 @@ void CacheStorageCache::QueryCacheFilterEntry(
if (rv < 0) {
std::move(query_cache_context->callback)
- .Run(CACHE_STORAGE_ERROR_STORAGE,
+ .Run(CacheStorageError::kErrorStorage,
std::move(query_cache_context->matches));
return;
}
@@ -825,7 +874,7 @@ void CacheStorageCache::QueryCacheFilterEntry(
if (backend_state_ == BACKEND_CLOSED) {
std::move(query_cache_context->callback)
- .Run(CACHE_STORAGE_ERROR_NOT_FOUND,
+ .Run(CacheStorageError::kErrorNotFound,
std::move(query_cache_context->matches));
return;
}
@@ -893,7 +942,7 @@ void CacheStorageCache::QueryCacheDidReadMetadata(
match->request->EstimatedStructSize();
if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
std::move(query_cache_context->callback)
- .Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
+ .Run(CacheStorageError::kErrorQueryTooLarge,
std::unique_ptr<QueryCacheResults>());
return;
}
@@ -906,7 +955,7 @@ void CacheStorageCache::QueryCacheDidReadMetadata(
match->response->EstimatedStructSize();
if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
std::move(query_cache_context->callback)
- .Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
+ .Run(CacheStorageError::kErrorQueryTooLarge,
std::unique_ptr<QueryCacheResults>());
return;
}
@@ -917,7 +966,7 @@ void CacheStorageCache::QueryCacheDidReadMetadata(
if (!blob_storage_context_) {
std::move(query_cache_context->callback)
- .Run(CACHE_STORAGE_ERROR_STORAGE,
+ .Run(CacheStorageError::kErrorStorage,
std::unique_ptr<QueryCacheResults>());
return;
}
@@ -967,26 +1016,26 @@ void CacheStorageCache::MatchImpl(
void CacheStorageCache::MatchDidMatchAll(
ResponseCallback callback,
CacheStorageError match_all_error,
- std::unique_ptr<Responses> match_all_responses,
+ std::vector<ServiceWorkerResponse> match_all_responses,
std::unique_ptr<BlobDataHandles> match_all_handles) {
- if (match_all_error != CACHE_STORAGE_OK) {
+ if (match_all_error != CacheStorageError::kSuccess) {
std::move(callback).Run(match_all_error,
std::unique_ptr<ServiceWorkerResponse>(),
std::unique_ptr<storage::BlobDataHandle>());
return;
}
- if (match_all_responses->empty()) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_NOT_FOUND,
+ if (match_all_responses.empty()) {
+ std::move(callback).Run(CacheStorageError::kErrorNotFound,
std::unique_ptr<ServiceWorkerResponse>(),
std::unique_ptr<storage::BlobDataHandle>());
return;
}
std::unique_ptr<ServiceWorkerResponse> response =
- base::MakeUnique<ServiceWorkerResponse>(match_all_responses->at(0));
+ std::make_unique<ServiceWorkerResponse>(match_all_responses[0]);
- std::move(callback).Run(CACHE_STORAGE_OK, std::move(response),
+ std::move(callback).Run(CacheStorageError::kSuccess, std::move(response),
std::move(match_all_handles->at(0)));
}
@@ -996,8 +1045,8 @@ void CacheStorageCache::MatchAllImpl(
ResponsesCallback callback) {
DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
if (backend_state_ != BACKEND_OPEN) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE,
- std::unique_ptr<Responses>(),
+ std::move(callback).Run(CacheStorageError::kErrorStorage,
+ std::vector<ServiceWorkerResponse>(),
std::unique_ptr<BlobDataHandles>());
return;
}
@@ -1013,24 +1062,24 @@ void CacheStorageCache::MatchAllDidQueryCache(
ResponsesCallback callback,
CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results) {
- if (error != CACHE_STORAGE_OK) {
- std::move(callback).Run(error, std::unique_ptr<Responses>(),
+ if (error != CacheStorageError::kSuccess) {
+ std::move(callback).Run(error, std::vector<ServiceWorkerResponse>(),
std::unique_ptr<BlobDataHandles>());
return;
}
- std::unique_ptr<Responses> out_responses = base::MakeUnique<Responses>();
+ std::vector<ServiceWorkerResponse> out_responses;
std::unique_ptr<BlobDataHandles> out_handles =
- base::MakeUnique<BlobDataHandles>();
- out_responses->reserve(query_cache_results->size());
+ std::make_unique<BlobDataHandles>();
+ out_responses.reserve(query_cache_results->size());
out_handles->reserve(query_cache_results->size());
for (auto& result : *query_cache_results) {
- out_responses->push_back(*result.response);
+ out_responses.push_back(*result.response);
out_handles->push_back(std::move(result.blob_handle));
}
- std::move(callback).Run(CACHE_STORAGE_OK, std::move(out_responses),
+ std::move(callback).Run(CacheStorageError::kSuccess, std::move(out_responses),
std::move(out_handles));
}
@@ -1046,7 +1095,7 @@ void CacheStorageCache::WriteSideDataDidGetQuota(
if (status_code != storage::kQuotaStatusOk || (buf_len > quota - usage)) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
- CACHE_STORAGE_ERROR_QUOTA_EXCEEDED));
+ CacheStorageError::kErrorQuotaExceeded));
return;
}
@@ -1063,7 +1112,7 @@ void CacheStorageCache::WriteSideDataImpl(ErrorCallback callback,
int buf_len) {
DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
if (backend_state_ != BACKEND_OPEN) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE);
+ std::move(callback).Run(CacheStorageError::kErrorStorage);
return;
}
@@ -1089,7 +1138,7 @@ void CacheStorageCache::WriteSideDataDidOpenEntry(
std::unique_ptr<disk_cache::Entry*> entry_ptr,
int rv) {
if (rv != net::OK) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_NOT_FOUND);
+ std::move(callback).Run(CacheStorageError::kErrorNotFound);
return;
}
disk_cache::ScopedEntryPtr entry(*entry_ptr);
@@ -1111,7 +1160,7 @@ void CacheStorageCache::WriteSideDataDidReadMetaData(
if (!headers ||
headers->response().response_time() !=
expected_response_time.ToInternalValue()) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_NOT_FOUND);
+ std::move(callback).Run(CacheStorageError::kErrorNotFound);
return;
}
// Get a temporary copy of the entry pointer before passing it in base::Bind.
@@ -1149,7 +1198,7 @@ void CacheStorageCache::WriteSideDataDidWrite(
if (rv != expected_bytes) {
entry->Doom();
UpdateCacheSize(
- base::BindOnce(std::move(callback), CACHE_STORAGE_ERROR_NOT_FOUND));
+ base::BindOnce(std::move(callback), CacheStorageError::kErrorNotFound));
return;
}
@@ -1164,7 +1213,8 @@ void CacheStorageCache::WriteSideDataDidWrite(
response.get(), cache_padding_key_.get(), rv);
}
- UpdateCacheSize(base::BindOnce(std::move(callback), CACHE_STORAGE_OK));
+ UpdateCacheSize(
+ base::BindOnce(std::move(callback), CacheStorageError::kSuccess));
}
void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
@@ -1179,19 +1229,34 @@ void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
operation.request.is_reload));
std::unique_ptr<ServiceWorkerResponse> response =
- base::MakeUnique<ServiceWorkerResponse>(operation.response);
+ std::make_unique<ServiceWorkerResponse>(operation.response);
std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
+ std::unique_ptr<storage::BlobDataHandle> side_data_blob_data_handle;
if (!response->blob_uuid.empty()) {
DCHECK_EQ(response->blob != nullptr, features::IsMojoBlobsEnabled());
if (!blob_storage_context_) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE);
+ std::move(callback).Run(CacheStorageError::kErrorStorage);
return;
}
blob_data_handle =
blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid);
if (!blob_data_handle) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE);
+ std::move(callback).Run(CacheStorageError::kErrorStorage);
+ return;
+ }
+ }
+ if (!response->side_data_blob_uuid.empty()) {
+ DCHECK_EQ(response->side_data_blob != nullptr,
+ features::IsMojoBlobsEnabled());
+ if (!blob_storage_context_) {
+ std::move(callback).Run(CacheStorageError::kErrorStorage);
+ return;
+ }
+ side_data_blob_data_handle = blob_storage_context_->GetBlobDataFromUUID(
+ response->side_data_blob_uuid);
+ if (!side_data_blob_data_handle) {
+ std::move(callback).Run(CacheStorageError::kErrorStorage);
return;
}
}
@@ -1203,6 +1268,7 @@ void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
std::unique_ptr<PutContext> put_context(new PutContext(
std::move(request), std::move(response), std::move(blob_data_handle),
+ std::move(side_data_blob_data_handle),
scheduler_->WrapCallbackToRunNext(std::move(callback))));
scheduler_->ScheduleOperation(base::BindOnce(
@@ -1213,7 +1279,7 @@ void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
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(CACHE_STORAGE_ERROR_STORAGE);
+ std::move(put_context->callback).Run(CacheStorageError::kErrorStorage);
return;
}
@@ -1222,7 +1288,7 @@ void CacheStorageCache::PutImpl(std::unique_ptr<PutContext> put_context) {
// cache padding.
// TODO(cmumford): Research alternatives to this explicit delete as it
// seriously impacts put performance.
- auto delete_request = base::MakeUnique<ServiceWorkerFetchRequest>(
+ auto delete_request = std::make_unique<ServiceWorkerFetchRequest>(
put_context->request->url, "", ServiceWorkerHeaderMap(), Referrer(),
false);
@@ -1239,11 +1305,12 @@ void CacheStorageCache::PutDidDeleteEntry(
std::unique_ptr<PutContext> put_context,
CacheStorageError error) {
if (backend_state_ != BACKEND_OPEN) {
- std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE);
+ std::move(put_context->callback).Run(CacheStorageError::kErrorStorage);
return;
}
- if (error != CACHE_STORAGE_OK && error != CACHE_STORAGE_ERROR_NOT_FOUND) {
+ if (error != CacheStorageError::kSuccess &&
+ error != CacheStorageError::kErrorNotFound) {
std::move(put_context->callback).Run(error);
return;
}
@@ -1274,7 +1341,7 @@ void CacheStorageCache::PutDidCreateEntry(
put_context->cache_entry.reset(*entry_ptr);
if (rv != net::OK) {
- std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_EXISTS);
+ std::move(put_context->callback).Run(CacheStorageError::kErrorExists);
return;
}
@@ -1315,7 +1382,7 @@ void CacheStorageCache::PutDidCreateEntry(
std::unique_ptr<std::string> serialized(new std::string());
if (!metadata.SerializeToString(serialized.get())) {
- std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE);
+ std::move(put_context->callback).Run(CacheStorageError::kErrorStorage);
return;
}
@@ -1345,7 +1412,7 @@ void CacheStorageCache::PutDidWriteHeaders(
int rv) {
if (rv != expected_bytes) {
put_context->cache_entry->Doom();
- std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE);
+ std::move(put_context->callback).Run(CacheStorageError::kErrorStorage);
return;
}
@@ -1359,28 +1426,36 @@ void CacheStorageCache::PutDidWriteHeaders(
// The metadata is written, now for the response content. The data is streamed
// from the blob into the cache entry.
-
if (put_context->response->blob_uuid.empty()) {
- UpdateCacheSize(
- base::BindOnce(std::move(put_context->callback), CACHE_STORAGE_OK));
+ UpdateCacheSize(base::BindOnce(std::move(put_context->callback),
+ CacheStorageError::kSuccess));
return;
}
+ PutWriteBlobToCache(std::move(put_context), INDEX_RESPONSE_BODY);
+}
+
+void CacheStorageCache::PutWriteBlobToCache(
+ std::unique_ptr<PutContext> put_context,
+ int disk_cache_body_index) {
+ DCHECK(disk_cache_body_index == INDEX_RESPONSE_BODY ||
+ disk_cache_body_index == INDEX_SIDE_DATA);
- DCHECK(put_context->blob_data_handle);
+ std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
+ disk_cache_body_index == INDEX_RESPONSE_BODY
+ ? std::move(put_context->blob_data_handle)
+ : std::move(put_context->side_data_blob_data_handle);
+ DCHECK(blob_data_handle);
disk_cache::ScopedEntryPtr entry(std::move(put_context->cache_entry));
- put_context->cache_entry = NULL;
+ put_context->cache_entry = nullptr;
- auto blob_to_cache = base::MakeUnique<CacheStorageBlobToDiskCache>();
+ auto blob_to_cache = std::make_unique<CacheStorageBlobToDiskCache>();
CacheStorageBlobToDiskCache* blob_to_cache_raw = blob_to_cache.get();
BlobToDiskCacheIDMap::KeyType blob_to_cache_key =
active_blob_to_disk_cache_writers_.Add(std::move(blob_to_cache));
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
- std::move(put_context->blob_data_handle);
-
blob_to_cache_raw->StreamBlobToCache(
- std::move(entry), INDEX_RESPONSE_BODY, request_context_getter_.get(),
+ std::move(entry), disk_cache_body_index, request_context_getter_.get(),
std::move(blob_data_handle),
base::BindOnce(&CacheStorageCache::PutDidWriteBlobToCache,
weak_ptr_factory_.GetWeakPtr(),
@@ -1399,12 +1474,17 @@ void CacheStorageCache::PutDidWriteBlobToCache(
if (!success) {
put_context->cache_entry->Doom();
- std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE);
+ std::move(put_context->callback).Run(CacheStorageError::kErrorStorage);
return;
}
- UpdateCacheSize(
- base::BindOnce(std::move(put_context->callback), CACHE_STORAGE_OK));
+ if (put_context->side_data_blob_data_handle) {
+ PutWriteBlobToCache(std::move(put_context), INDEX_SIDE_DATA);
+ return;
+ }
+
+ UpdateCacheSize(base::BindOnce(std::move(put_context->callback),
+ CacheStorageError::kSuccess));
}
void CacheStorageCache::CalculateCacheSizePadding(
@@ -1440,7 +1520,7 @@ void CacheStorageCache::PaddingDidQueryCache(
CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results) {
int64_t cache_padding = 0;
- if (error == CACHE_STORAGE_OK) {
+ if (error == CacheStorageError::kSuccess) {
for (const auto& result : *query_cache_results) {
if (ShouldPadResourceSize(result.response.get())) {
int32_t side_data_size =
@@ -1475,7 +1555,7 @@ void CacheStorageCache::UpdateCacheSize(base::OnceClosure callback) {
}
void CacheStorageCache::UpdateCacheSizeGotSize(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
base::OnceClosure callback,
int current_cache_size) {
DCHECK_NE(current_cache_size, CacheStorage::kSizeUnknown);
@@ -1520,7 +1600,7 @@ void CacheStorageCache::DeleteImpl(
ErrorCallback callback) {
DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
if (backend_state_ != BACKEND_OPEN) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE);
+ std::move(callback).Run(CacheStorageError::kErrorStorage);
return;
}
@@ -1535,13 +1615,13 @@ void CacheStorageCache::DeleteDidQueryCache(
ErrorCallback callback,
CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results) {
- if (error != CACHE_STORAGE_OK) {
+ if (error != CacheStorageError::kSuccess) {
std::move(callback).Run(error);
return;
}
if (query_cache_results->empty()) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_NOT_FOUND);
+ std::move(callback).Run(CacheStorageError::kErrorNotFound);
return;
}
@@ -1555,7 +1635,8 @@ void CacheStorageCache::DeleteDidQueryCache(
entry->Doom();
}
- UpdateCacheSize(base::BindOnce(std::move(callback), CACHE_STORAGE_OK));
+ UpdateCacheSize(
+ base::BindOnce(std::move(callback), CacheStorageError::kSuccess));
}
void CacheStorageCache::KeysImpl(
@@ -1564,7 +1645,7 @@ void CacheStorageCache::KeysImpl(
RequestsCallback callback) {
DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
if (backend_state_ != BACKEND_OPEN) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE,
+ std::move(callback).Run(CacheStorageError::kErrorStorage,
std::unique_ptr<Requests>());
return;
}
@@ -1579,17 +1660,17 @@ void CacheStorageCache::KeysDidQueryCache(
RequestsCallback callback,
CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results) {
- if (error != CACHE_STORAGE_OK) {
+ if (error != CacheStorageError::kSuccess) {
std::move(callback).Run(error, std::unique_ptr<Requests>());
return;
}
- std::unique_ptr<Requests> out_requests = base::MakeUnique<Requests>();
+ std::unique_ptr<Requests> out_requests = std::make_unique<Requests>();
out_requests->reserve(query_cache_results->size());
for (const auto& result : *query_cache_results)
out_requests->push_back(*result.request);
- std::move(callback).Run(CACHE_STORAGE_OK, std::move(out_requests));
+ std::move(callback).Run(CacheStorageError::kSuccess, std::move(out_requests));
}
void CacheStorageCache::CloseImpl(base::OnceClosure callback) {
@@ -1647,7 +1728,7 @@ void CacheStorageCache::CreateBackend(ErrorCallback callback) {
int rv = disk_cache::CreateCacheBackend(
cache_type, net::CACHE_BACKEND_SIMPLE, path_, kMaxCacheBytes,
false, /* force */
- NULL, backend,
+ nullptr, backend,
base::BindOnce(&CacheStorageCache::DeleteBackendCompletedIO,
weak_ptr_factory_.GetWeakPtr()),
create_cache_callback);
@@ -1660,12 +1741,12 @@ void CacheStorageCache::CreateBackendDidCreate(
std::unique_ptr<ScopedBackendPtr> backend_ptr,
int rv) {
if (rv != net::OK) {
- std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE);
+ std::move(callback).Run(CacheStorageError::kErrorStorage);
return;
}
backend_ = std::move(*backend_ptr);
- std::move(callback).Run(CACHE_STORAGE_OK);
+ std::move(callback).Run(CacheStorageError::kSuccess);
}
void CacheStorageCache::InitBackend() {
@@ -1685,7 +1766,7 @@ void CacheStorageCache::InitBackend() {
void CacheStorageCache::InitDidCreateBackend(
base::OnceClosure callback,
CacheStorageError cache_create_error) {
- if (cache_create_error != CACHE_STORAGE_OK) {
+ if (cache_create_error != CacheStorageError::kSuccess) {
InitGotCacheSize(std::move(callback), cache_create_error, 0);
return;
}
@@ -1703,7 +1784,7 @@ void CacheStorageCache::InitDidCreateBackend(
void CacheStorageCache::InitGotCacheSize(base::OnceClosure callback,
CacheStorageError cache_create_error,
int cache_size) {
- if (cache_create_error != CACHE_STORAGE_OK) {
+ if (cache_create_error != CacheStorageError::kSuccess) {
InitGotCacheSizeAndPadding(std::move(callback), cache_create_error, 0, 0);
return;
}
@@ -1754,13 +1835,14 @@ void CacheStorageCache::InitGotCacheSizeAndPadding(
cache_padding_ = cache_padding;
initializing_ = false;
- backend_state_ = (cache_create_error == CACHE_STORAGE_OK && backend_ &&
- backend_state_ == BACKEND_UNINITIALIZED)
+ backend_state_ = (cache_create_error == CacheStorageError::kSuccess &&
+ backend_ && backend_state_ == BACKEND_UNINITIALIZED)
? BACKEND_OPEN
: BACKEND_CLOSED;
UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.InitBackendResult",
- cache_create_error, CACHE_STORAGE_ERROR_LAST + 1);
+ cache_create_error,
+ static_cast<int>(CacheStorageError::kLast) + 1);
if (cache_observer_)
cache_observer_->CacheSizeUpdated(this);
@@ -1785,9 +1867,9 @@ CacheStorageCache::PopulateResponseBody(disk_cache::ScopedEntryPtr entry,
auto result = blob_storage_context_->AddFinishedBlob(&blob_data);
if (features::IsMojoBlobsEnabled()) {
- storage::mojom::BlobPtr blob_ptr;
+ blink::mojom::BlobPtr blob_ptr;
storage::BlobImpl::Create(
- base::MakeUnique<storage::BlobDataHandle>(*result),
+ std::make_unique<storage::BlobDataHandle>(*result),
MakeRequest(&blob_ptr));
response->blob =
base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr));
@@ -1796,8 +1878,7 @@ CacheStorageCache::PopulateResponseBody(disk_cache::ScopedEntryPtr entry,
return result;
}
-std::unique_ptr<CacheStorageCacheHandle>
-CacheStorageCache::CreateCacheHandle() {
+CacheStorageCacheHandle CacheStorageCache::CreateCacheHandle() {
return cache_storage_->CreateCacheHandle(this);
}
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache.h b/chromium/content/browser/cache_storage/cache_storage_cache.h
index 84f4bc8562f..8fc71174914 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache.h
+++ b/chromium/content/browser/cache_storage/cache_storage_cache.h
@@ -16,11 +16,13 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "content/browser/bad_message.h"
#include "content/common/cache_storage/cache_storage_types.h"
#include "content/common/service_worker/service_worker_types.h"
#include "net/base/io_buffer.h"
#include "net/disk_cache/disk_cache.h"
#include "storage/common/quota/quota_status_code.h"
+#include "third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h"
namespace crypto {
class SymmetricKey;
@@ -55,20 +57,23 @@ class CacheResponse;
// will be called so long as the cache object lives.
class CONTENT_EXPORT CacheStorageCache {
public:
- using ErrorCallback = base::OnceCallback<void(CacheStorageError)>;
+ using ErrorCallback =
+ base::OnceCallback<void(blink::mojom::CacheStorageError)>;
+ using BadMessageCallback =
+ base::OnceCallback<void(bad_message::BadMessageReason)>;
using ResponseCallback =
- base::OnceCallback<void(CacheStorageError,
+ base::OnceCallback<void(blink::mojom::CacheStorageError,
std::unique_ptr<ServiceWorkerResponse>,
std::unique_ptr<storage::BlobDataHandle>)>;
- using Responses = std::vector<ServiceWorkerResponse>;
using BlobDataHandles = std::vector<std::unique_ptr<storage::BlobDataHandle>>;
using ResponsesCallback =
- base::OnceCallback<void(CacheStorageError,
- std::unique_ptr<Responses>,
+ base::OnceCallback<void(blink::mojom::CacheStorageError,
+ std::vector<ServiceWorkerResponse>,
std::unique_ptr<BlobDataHandles>)>;
using Requests = std::vector<ServiceWorkerFetchRequest>;
using RequestsCallback =
- base::OnceCallback<void(CacheStorageError, std::unique_ptr<Requests>)>;
+ base::OnceCallback<void(blink::mojom::CacheStorageError,
+ std::unique_ptr<Requests>)>;
using SizeCallback = base::OnceCallback<void(int64_t)>;
using SizePaddingCallback = base::OnceCallback<void(int64_t, int64_t)>;
@@ -104,15 +109,16 @@ class CONTENT_EXPORT CacheStorageCache {
const CacheStorageCacheQueryParams& match_params,
ResponseCallback callback);
- // Returns CACHE_STORAGE_OK and matched responses in this cache. If there are
- // no responses, returns CACHE_STORAGE_OK and an empty vector.
+ // Returns blink::mojom::CacheStorageError::kSuccess and matched
+ // responses in this cache. If there are no responses, returns
+ // blink::mojom::CacheStorageError::kSuccess and an empty vector.
void MatchAll(std::unique_ptr<ServiceWorkerFetchRequest> request,
const CacheStorageCacheQueryParams& match_params,
ResponsesCallback callback);
// Writes the side data (ex: V8 code cache) for the specified cache entry.
// If it doesn't exist, or the |expected_response_time| differs from the
- // entry's, CACHE_STORAGE_ERROR_NOT_FOUND is returned.
+ // entry's, blink::mojom::CacheStorageError::kErrorNotFound is returned.
// Note: This "side data" is same meaning as "metadata" in HTTPCache. We use
// "metadata" in cache_storage.proto for the pair of headers of a request and
// a response. To avoid the confusion we use "side data" here.
@@ -136,11 +142,14 @@ class CONTENT_EXPORT CacheStorageCache {
// TODO(nhiroki): This function should run all operations atomically.
// http://crbug.com/486637
void BatchOperation(const std::vector<CacheStorageBatchOperation>& operations,
- ErrorCallback callback);
+ ErrorCallback callback,
+ BadMessageCallback bad_message_callback);
void BatchDidGetUsageAndQuota(
const std::vector<CacheStorageBatchOperation>& operations,
ErrorCallback callback,
- int64_t space_required,
+ BadMessageCallback bad_message_callback,
+ uint64_t space_required,
+ uint64_t side_data_size,
storage::QuotaStatusCode status_code,
int64_t usage,
int64_t quota);
@@ -149,12 +158,13 @@ class CONTENT_EXPORT CacheStorageCache {
// completion.
void BatchDidOneOperation(base::OnceClosure completion_closure,
ErrorCallback error_callback,
- CacheStorageError error);
+ blink::mojom::CacheStorageError error);
// Callback invoked once all BatchDidOneOperation() calls have run.
// Invokes |error_callback|.
void BatchDidAllOperations(ErrorCallback error_callback);
- // Returns CACHE_STORAGE_OK and a vector of requests if there are no errors.
+ // Returns blink::mojom::CacheStorageError::kSuccess and a vector of
+ // requests if there are no errors.
void Keys(std::unique_ptr<ServiceWorkerFetchRequest> request,
const CacheStorageCacheQueryParams& options,
RequestsCallback callback);
@@ -224,7 +234,7 @@ class CONTENT_EXPORT CacheStorageCache {
using QueryTypes = int32_t;
using QueryCacheResults = std::vector<QueryCacheResult>;
using QueryCacheCallback =
- base::OnceCallback<void(CacheStorageError,
+ base::OnceCallback<void(blink::mojom::CacheStorageError,
std::unique_ptr<QueryCacheResults>)>;
using Entries = std::vector<disk_cache::Entry*>;
using ScopedBackendPtr = std::unique_ptr<disk_cache::Backend>;
@@ -273,8 +283,8 @@ class CONTENT_EXPORT CacheStorageCache {
const CacheStorageCacheQueryParams& match_params,
ResponseCallback callback);
void MatchDidMatchAll(ResponseCallback callback,
- CacheStorageError match_all_error,
- std::unique_ptr<Responses> match_all_responses,
+ blink::mojom::CacheStorageError match_all_error,
+ std::vector<ServiceWorkerResponse> match_all_responses,
std::unique_ptr<BlobDataHandles> match_all_handles);
// MatchAll callbacks
@@ -283,7 +293,7 @@ class CONTENT_EXPORT CacheStorageCache {
ResponsesCallback callback);
void MatchAllDidQueryCache(
ResponsesCallback callback,
- CacheStorageError error,
+ blink::mojom::CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results);
// WriteSideData callbacks
@@ -336,7 +346,7 @@ class CONTENT_EXPORT CacheStorageCache {
void Put(const CacheStorageBatchOperation& operation, ErrorCallback callback);
void PutImpl(std::unique_ptr<PutContext> put_context);
void PutDidDeleteEntry(std::unique_ptr<PutContext> put_context,
- CacheStorageError error);
+ blink::mojom::CacheStorageError error);
void PutDidGetUsageAndQuota(std::unique_ptr<PutContext> put_context,
storage::QuotaStatusCode status_code,
int64_t usage,
@@ -347,6 +357,8 @@ class CONTENT_EXPORT CacheStorageCache {
void PutDidWriteHeaders(std::unique_ptr<PutContext> put_context,
int expected_bytes,
int rv);
+ void PutWriteBlobToCache(std::unique_ptr<PutContext> put_context,
+ int disk_cache_body_index);
void PutDidWriteBlobToCache(std::unique_ptr<PutContext> put_context,
BlobToDiskCacheIDMap::KeyType blob_to_cache_key,
disk_cache::ScopedEntryPtr entry,
@@ -356,7 +368,7 @@ class CONTENT_EXPORT CacheStorageCache {
// manager of any change from the last report, and sets cache_size_ to the new
// size.
void UpdateCacheSize(base::OnceClosure callback);
- void UpdateCacheSizeGotSize(std::unique_ptr<CacheStorageCacheHandle>,
+ void UpdateCacheSizeGotSize(CacheStorageCacheHandle,
base::OnceClosure callback,
int current_cache_size);
@@ -368,7 +380,7 @@ class CONTENT_EXPORT CacheStorageCache {
ErrorCallback callback);
void DeleteDidQueryCache(
ErrorCallback callback,
- CacheStorageError error,
+ blink::mojom::CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results);
// Keys callbacks.
@@ -377,7 +389,7 @@ class CONTENT_EXPORT CacheStorageCache {
RequestsCallback callback);
void KeysDidQueryCache(
RequestsCallback callback,
- CacheStorageError error,
+ blink::mojom::CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results);
void CloseImpl(base::OnceClosure callback);
@@ -400,7 +412,7 @@ class CONTENT_EXPORT CacheStorageCache {
void PaddingDidQueryCache(
SizePaddingCallback callback,
int cache_size,
- CacheStorageError error,
+ blink::mojom::CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results);
// Calculate the size (but not padding) of the cache.
@@ -408,14 +420,15 @@ class CONTENT_EXPORT CacheStorageCache {
void InitBackend();
void InitDidCreateBackend(base::OnceClosure callback,
- CacheStorageError cache_create_error);
+ blink::mojom::CacheStorageError cache_create_error);
void InitGotCacheSize(base::OnceClosure callback,
- CacheStorageError cache_create_error,
+ blink::mojom::CacheStorageError cache_create_error,
int cache_size);
- void InitGotCacheSizeAndPadding(base::OnceClosure callback,
- CacheStorageError cache_create_error,
- int64_t cache_size,
- int64_t cache_padding);
+ void InitGotCacheSizeAndPadding(
+ base::OnceClosure callback,
+ blink::mojom::CacheStorageError cache_create_error,
+ int64_t cache_size,
+ int64_t cache_padding);
void DeleteBackendCompletedIO();
std::unique_ptr<storage::BlobDataHandle> PopulateResponseBody(
@@ -423,7 +436,7 @@ class CONTENT_EXPORT CacheStorageCache {
ServiceWorkerResponse* response);
// Virtual for testing.
- virtual std::unique_ptr<CacheStorageCacheHandle> CreateCacheHandle();
+ virtual CacheStorageCacheHandle CreateCacheHandle();
// Be sure to check |backend_state_| before use.
std::unique_ptr<disk_cache::Backend> backend_;
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache_handle.cc b/chromium/content/browser/cache_storage/cache_storage_cache_handle.cc
index 13cdebd541e..ae3f68fed34 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache_handle.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_cache_handle.cc
@@ -2,18 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "content/browser/cache_storage/cache_storage_cache_handle.h"
namespace content {
+CacheStorageCacheHandle::CacheStorageCacheHandle() = default;
+
+CacheStorageCacheHandle::CacheStorageCacheHandle(
+ CacheStorageCacheHandle&& other)
+ : cache_storage_cache_(std::move(other.cache_storage_cache_)),
+ cache_storage_(std::move(other.cache_storage_)) {}
+
CacheStorageCacheHandle::~CacheStorageCacheHandle() {
if (cache_storage_ && cache_storage_cache_)
cache_storage_->DropCacheHandleRef(cache_storage_cache_.get());
}
-std::unique_ptr<CacheStorageCacheHandle> CacheStorageCacheHandle::Clone() {
- return std::unique_ptr<CacheStorageCacheHandle>(
- new CacheStorageCacheHandle(cache_storage_cache_, cache_storage_));
+CacheStorageCacheHandle CacheStorageCacheHandle::Clone() const {
+ return CacheStorageCacheHandle(cache_storage_cache_, cache_storage_);
}
CacheStorageCacheHandle::CacheStorageCacheHandle(
@@ -25,4 +33,13 @@ CacheStorageCacheHandle::CacheStorageCacheHandle(
cache_storage_->AddCacheHandleRef(cache_storage_cache_.get());
}
+CacheStorageCacheHandle& CacheStorageCacheHandle::operator=(
+ CacheStorageCacheHandle&& rhs) {
+ if (cache_storage_ && cache_storage_cache_)
+ cache_storage_->DropCacheHandleRef(cache_storage_cache_.get());
+ cache_storage_cache_ = std::move(rhs.cache_storage_cache_);
+ cache_storage_ = std::move(rhs.cache_storage_);
+ return *this;
+}
+
} // namespace content
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache_handle.h b/chromium/content/browser/cache_storage/cache_storage_cache_handle.h
index 9a043bbd0e8..28f1e828718 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache_handle.h
+++ b/chromium/content/browser/cache_storage/cache_storage_cache_handle.h
@@ -16,13 +16,17 @@ namespace content {
// CacheStorage is deleted.
class CONTENT_EXPORT CacheStorageCacheHandle {
public:
+ CacheStorageCacheHandle();
+ CacheStorageCacheHandle(CacheStorageCacheHandle&& other);
~CacheStorageCacheHandle();
// Returns the underlying CacheStorageCache*. Will return nullptr if the
// CacheStorage has been deleted.
CacheStorageCache* value() { return cache_storage_cache_.get(); }
- std::unique_ptr<CacheStorageCacheHandle> Clone();
+ CacheStorageCacheHandle Clone() const;
+
+ CacheStorageCacheHandle& operator=(CacheStorageCacheHandle&& rhs);
private:
friend class CacheStorage;
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 fbb55650f0a..952cadbc085 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -26,6 +26,7 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/referrer.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -39,6 +40,7 @@
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_data_snapshot.h"
+#include "storage/browser/blob/blob_impl.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/blob/blob_url_request_job_factory.h"
#include "storage/browser/quota/quota_manager_proxy.h"
@@ -47,6 +49,8 @@
#include "storage/common/blob_storage/blob_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
+using blink::mojom::CacheStorageError;
+
namespace content {
namespace {
@@ -59,7 +63,7 @@ const char kCacheName[] = "test_cache";
std::unique_ptr<storage::BlobProtocolHandler> CreateMockBlobProtocolHandler(
storage::BlobStorageContext* blob_storage_context) {
return base::WrapUnique(
- new storage::BlobProtocolHandler(blob_storage_context, nullptr));
+ new storage::BlobProtocolHandler(blob_storage_context));
}
// A disk_cache::Backend wrapper that can delay operations.
@@ -280,6 +284,11 @@ std::unique_ptr<crypto::SymmetricKey> CreateTestPaddingKey() {
"abc123");
}
+void OnBadMessage(base::Optional<bad_message::BadMessageReason>* result,
+ bad_message::BadMessageReason reason) {
+ *result = reason;
+}
+
} // namespace
// A CacheStorageCache that can optionally delay during backend creation.
@@ -305,6 +314,8 @@ class TestCacheStorageCache : public CacheStorageCache {
CreateTestPaddingKey()),
delay_backend_creation_(false) {}
+ ~TestCacheStorageCache() override { base::RunLoop().RunUntilIdle(); }
+
void CreateBackend(ErrorCallback callback) override {
backend_creation_callback_ = std::move(callback);
if (delay_backend_creation_)
@@ -333,10 +344,10 @@ class TestCacheStorageCache : public CacheStorageCache {
void Init() { InitBackend(); }
private:
- std::unique_ptr<CacheStorageCacheHandle> CreateCacheHandle() override {
+ CacheStorageCacheHandle CreateCacheHandle() override {
// Returns an empty handle. There is no need for CacheStorage and its
// handles in these tests.
- return std::unique_ptr<CacheStorageCacheHandle>();
+ return CacheStorageCacheHandle();
}
bool delay_backend_creation_;
@@ -386,7 +397,7 @@ class CacheStorageCacheTest : public testing::Test {
CreateRequests(blob_storage_context);
- cache_ = base::MakeUnique<TestCacheStorageCache>(
+ cache_ = std::make_unique<TestCacheStorageCache>(
GURL(kOrigin), kCacheName, temp_dir_path, nullptr /* CacheStorage */,
BrowserContext::GetDefaultStoragePartition(&browser_context_)
->GetURLRequestContext(),
@@ -421,31 +432,35 @@ class CacheStorageCacheTest : public testing::Test {
for (int i = 0; i < 100; ++i)
expected_blob_data_ += kTestData;
- std::unique_ptr<storage::BlobDataBuilder> blob_data(
- new storage::BlobDataBuilder("blob-id:myblob"));
- blob_data->AppendData(expected_blob_data_);
+ blob_handle_ = BuildBlobHandle("blob-id:myblob", expected_blob_data_);
- blob_handle_ =
- blob_storage_context->context()->AddFinishedBlob(blob_data.get());
+ scoped_refptr<storage::BlobHandle> blob;
+ if (features::IsMojoBlobsEnabled()) {
+ blink::mojom::BlobPtr blob_ptr;
+ storage::BlobImpl::Create(
+ std::make_unique<storage::BlobDataHandle>(*blob_handle_),
+ MakeRequest(&blob_ptr));
+ blob = base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr));
+ }
body_response_ = CreateResponse(
"http://example.com/body.html",
- base::MakeUnique<ServiceWorkerHeaderMap>(headers), blob_handle_->uuid(),
- expected_blob_data_.size(),
- base::MakeUnique<
+ std::make_unique<ServiceWorkerHeaderMap>(headers), blob_handle_->uuid(),
+ expected_blob_data_.size(), blob,
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */);
body_response_with_query_ =
CreateResponse("http://example.com/body.html?query=test",
- base::MakeUnique<ServiceWorkerHeaderMap>(headers),
- blob_handle_->uuid(), expected_blob_data_.size(),
- base::MakeUnique<ServiceWorkerHeaderList>(
+ std::make_unique<ServiceWorkerHeaderMap>(headers),
+ blob_handle_->uuid(), expected_blob_data_.size(), blob,
+ std::make_unique<ServiceWorkerHeaderList>(
1, "a") /* cors_exposed_header_names */);
no_body_response_ = CreateResponse(
"http://example.com/no_body.html",
- base::MakeUnique<ServiceWorkerHeaderMap>(headers), "", 0,
- base::MakeUnique<
+ std::make_unique<ServiceWorkerHeaderMap>(headers), "", 0, nullptr,
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */);
}
@@ -454,20 +469,44 @@ class CacheStorageCacheTest : public testing::Test {
std::unique_ptr<ServiceWorkerHeaderMap> headers,
const std::string& blob_uuid,
uint64_t blob_size,
+ scoped_refptr<storage::BlobHandle> blob_handle,
std::unique_ptr<ServiceWorkerHeaderList> cors_exposed_header_names) {
return ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(1, GURL(url)), 200, "OK",
+ std::make_unique<std::vector<GURL>>(1, GURL(url)), 200, "OK",
network::mojom::FetchResponseType::kDefault, std::move(headers),
- blob_uuid, blob_size, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown, base::Time::Now(),
+ blob_uuid, blob_size, std::move(blob_handle),
+ blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time::Now(),
false /* is_in_cache_storage */,
std::string() /* cache_storage_cache_name */,
std::move(cors_exposed_header_names));
}
+ std::unique_ptr<storage::BlobDataHandle> BuildBlobHandle(
+ const std::string& uuid,
+ const std::string& data) {
+ std::unique_ptr<storage::BlobDataBuilder> builder =
+ std::make_unique<storage::BlobDataBuilder>(uuid);
+ builder->AppendData(data);
+ return blob_storage_context_->AddFinishedBlob(builder.get());
+ }
+
+ void CopySideDataToResponse(storage::BlobDataHandle* side_data_blob_handle,
+ ServiceWorkerResponse* response) {
+ response->side_data_blob_uuid = side_data_blob_handle->uuid();
+ response->side_data_blob_size = side_data_blob_handle->size();
+ if (features::IsMojoBlobsEnabled()) {
+ blink::mojom::BlobPtr blob_ptr;
+ storage::BlobImpl::Create(
+ std::make_unique<storage::BlobDataHandle>(*side_data_blob_handle),
+ MakeRequest(&blob_ptr));
+ response->side_data_blob =
+ base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr));
+ }
+ }
+
std::unique_ptr<ServiceWorkerFetchRequest> CopyFetchRequest(
const ServiceWorkerFetchRequest& request) {
- return base::MakeUnique<ServiceWorkerFetchRequest>(
+ return std::make_unique<ServiceWorkerFetchRequest>(
request.url, request.method, request.headers, request.referrer,
request.is_reload);
}
@@ -479,7 +518,8 @@ class CacheStorageCacheTest : public testing::Test {
cache_->BatchOperation(
operations,
base::BindOnce(&CacheStorageCacheTest::ErrorTypeCallback,
- base::Unretained(this), base::Unretained(loop.get())));
+ base::Unretained(this), base::Unretained(loop.get())),
+ base::BindOnce(&OnBadMessage, base::Unretained(&bad_message_reason_)));
// TODO(jkarlin): These functions should use base::RunLoop().RunUntilIdle()
// once the cache uses a passed in task runner instead of the CACHE thread.
loop->Run();
@@ -496,7 +536,7 @@ class CacheStorageCacheTest : public testing::Test {
CacheStorageError error =
BatchOperation(std::vector<CacheStorageBatchOperation>(1, operation));
- return error == CACHE_STORAGE_OK;
+ return error == CacheStorageError::kSuccess;
}
bool Match(const ServiceWorkerFetchRequest& request,
@@ -510,13 +550,13 @@ class CacheStorageCacheTest : public testing::Test {
base::Unretained(this), base::Unretained(loop.get())));
loop->Run();
- return callback_error_ == CACHE_STORAGE_OK;
+ return callback_error_ == CacheStorageError::kSuccess;
}
bool MatchAll(
const ServiceWorkerFetchRequest& request,
const CacheStorageCacheQueryParams& match_params,
- std::unique_ptr<CacheStorageCache::Responses>* responses,
+ std::vector<ServiceWorkerResponse>* responses,
std::unique_ptr<CacheStorageCache::BlobDataHandles>* body_handles) {
base::RunLoop loop;
cache_->MatchAll(
@@ -525,11 +565,11 @@ class CacheStorageCacheTest : public testing::Test {
base::Unretained(this), loop.QuitClosure(), responses,
body_handles));
loop.Run();
- return callback_error_ == CACHE_STORAGE_OK;
+ return callback_error_ == CacheStorageError::kSuccess;
}
bool MatchAll(
- std::unique_ptr<CacheStorageCache::Responses>* responses,
+ std::vector<ServiceWorkerResponse>* responses,
std::unique_ptr<CacheStorageCache::BlobDataHandles>* body_handles) {
return MatchAll(ServiceWorkerFetchRequest(), CacheStorageCacheQueryParams(),
responses, body_handles);
@@ -545,7 +585,7 @@ class CacheStorageCacheTest : public testing::Test {
CacheStorageError error =
BatchOperation(std::vector<CacheStorageBatchOperation>(1, operation));
- return error == CACHE_STORAGE_OK;
+ return error == CacheStorageError::kSuccess;
}
bool Keys(
@@ -560,7 +600,7 @@ class CacheStorageCacheTest : public testing::Test {
base::Unretained(this), base::Unretained(loop.get())));
loop->Run();
- return callback_error_ == CACHE_STORAGE_OK;
+ return callback_error_ == CacheStorageError::kSuccess;
}
bool Close() {
@@ -584,7 +624,7 @@ class CacheStorageCacheTest : public testing::Test {
url, expected_response_time, buffer, buf_len);
run_loop.Run();
- return callback_error_ == CACHE_STORAGE_OK;
+ return callback_error_ == CacheStorageError::kSuccess;
}
int64_t Size() {
@@ -650,7 +690,8 @@ class CacheStorageCacheTest : public testing::Test {
callback_error_ = error;
callback_response_ = std::move(response);
callback_response_data_.reset();
- if (error == CACHE_STORAGE_OK && !callback_response_->blob_uuid.empty())
+ if (error == CacheStorageError::kSuccess &&
+ !callback_response_->blob_uuid.empty())
callback_response_data_ = std::move(body_handle);
if (run_loop)
@@ -659,13 +700,13 @@ class CacheStorageCacheTest : public testing::Test {
void ResponsesAndErrorCallback(
base::OnceClosure quit_closure,
- std::unique_ptr<CacheStorageCache::Responses>* responses_out,
+ std::vector<ServiceWorkerResponse>* responses_out,
std::unique_ptr<CacheStorageCache::BlobDataHandles>* body_handles_out,
CacheStorageError error,
- std::unique_ptr<CacheStorageCache::Responses> responses,
+ std::vector<ServiceWorkerResponse> responses,
std::unique_ptr<CacheStorageCache::BlobDataHandles> body_handles) {
callback_error_ = error;
- responses_out->swap(responses);
+ *responses_out = std::move(responses);
body_handles_out->swap(body_handles);
std::move(quit_closure).Run();
}
@@ -729,10 +770,11 @@ class CacheStorageCacheTest : public testing::Test {
std::unique_ptr<storage::BlobDataHandle> blob_handle_;
std::string expected_blob_data_;
- CacheStorageError callback_error_ = CACHE_STORAGE_OK;
+ CacheStorageError callback_error_ = CacheStorageError::kSuccess;
std::unique_ptr<ServiceWorkerResponse> callback_response_;
std::unique_ptr<storage::BlobDataHandle> callback_response_data_;
std::vector<std::string> callback_strings_;
+ base::Optional<bad_message::BadMessageReason> bad_message_reason_;
bool callback_closed_ = false;
int64_t callback_size_ = 0;
};
@@ -777,7 +819,7 @@ TEST_P(CacheStorageCacheTestP, PutBody_Multiple) {
operations.push_back(operation2);
operations.push_back(operation3);
- EXPECT_EQ(CACHE_STORAGE_OK, BatchOperation(operations));
+ EXPECT_EQ(CacheStorageError::kSuccess, BatchOperation(operations));
EXPECT_TRUE(Match(operation1.request));
EXPECT_TRUE(Match(operation2.request));
EXPECT_TRUE(Match(operation3.request));
@@ -794,7 +836,7 @@ TEST_P(CacheStorageCacheTestP, MatchLimit) {
SetMaxQuerySizeBytes(max_size - 1);
EXPECT_FALSE(Match(no_body_request_));
- EXPECT_EQ(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorQueryTooLarge, callback_error_);
}
TEST_P(CacheStorageCacheTestP, MatchAllLimit) {
@@ -807,29 +849,29 @@ TEST_P(CacheStorageCacheTestP, MatchAllLimit) {
size_t query_request_size = body_request_with_query_.EstimatedStructSize() +
callback_response_->EstimatedStructSize();
- std::unique_ptr<CacheStorageCache::Responses> responses;
+ std::vector<ServiceWorkerResponse> responses;
std::unique_ptr<CacheStorageCache::BlobDataHandles> body_handles;
CacheStorageCacheQueryParams match_params;
// There is enough room for both requests and responses
SetMaxQuerySizeBytes(body_request_size + query_request_size);
EXPECT_TRUE(MatchAll(body_request_, match_params, &responses, &body_handles));
- EXPECT_EQ(1u, responses->size());
+ EXPECT_EQ(1u, responses.size());
match_params.ignore_search = true;
EXPECT_TRUE(MatchAll(body_request_, match_params, &responses, &body_handles));
- EXPECT_EQ(2u, responses->size());
+ EXPECT_EQ(2u, responses.size());
// There is not enough room for both requests and responses
SetMaxQuerySizeBytes(body_request_size);
match_params.ignore_search = false;
EXPECT_TRUE(MatchAll(body_request_, match_params, &responses, &body_handles));
- EXPECT_EQ(1u, responses->size());
+ EXPECT_EQ(1u, responses.size());
match_params.ignore_search = true;
EXPECT_FALSE(
MatchAll(body_request_, match_params, &responses, &body_handles));
- EXPECT_EQ(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorQueryTooLarge, callback_error_);
}
TEST_P(CacheStorageCacheTestP, KeysLimit) {
@@ -843,7 +885,7 @@ TEST_P(CacheStorageCacheTestP, KeysLimit) {
SetMaxQuerySizeBytes(no_body_request_.EstimatedStructSize());
EXPECT_FALSE(Keys());
- EXPECT_EQ(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorQueryTooLarge, callback_error_);
}
// TODO(nhiroki): Add a test for the case where one of PUT operations fails.
@@ -871,7 +913,7 @@ TEST_P(CacheStorageCacheTestP, ResponseURLEmpty) {
EXPECT_EQ(0u, callback_response_->url_list.size());
}
-TEST_F(CacheStorageCacheTest, PutBodyDropBlobRef) {
+TEST_P(CacheStorageCacheTestP, PutBodyDropBlobRef) {
CacheStorageBatchOperation operation;
operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT;
operation.request = body_request_;
@@ -881,13 +923,29 @@ TEST_F(CacheStorageCacheTest, PutBodyDropBlobRef) {
cache_->BatchOperation(
std::vector<CacheStorageBatchOperation>(1, operation),
base::BindOnce(&CacheStorageCacheTestP::ErrorTypeCallback,
- base::Unretained(this), base::Unretained(loop.get())));
+ base::Unretained(this), base::Unretained(loop.get())),
+ CacheStorageCache::BadMessageCallback());
// The handle should be held by the cache now so the deref here should be
// okay.
blob_handle_.reset();
loop->Run();
- EXPECT_EQ(CACHE_STORAGE_OK, callback_error_);
+ EXPECT_EQ(CacheStorageError::kSuccess, callback_error_);
+}
+
+TEST_P(CacheStorageCacheTestP, PutBadMessage) {
+ CacheStorageBatchOperation operation;
+ operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT;
+ operation.request = body_request_;
+ operation.response = body_response_;
+ operation.response.blob_size = UINT64_MAX;
+
+ std::vector<CacheStorageBatchOperation> operations =
+ std::vector<CacheStorageBatchOperation>(2, operation);
+ EXPECT_EQ(CacheStorageError::kErrorStorage, BatchOperation(operations));
+ EXPECT_EQ(bad_message::CSDH_UNEXPECTED_OPERATION, *bad_message_reason_);
+
+ EXPECT_FALSE(Match(body_request_));
}
TEST_P(CacheStorageCacheTestP, PutReplace) {
@@ -919,7 +977,7 @@ TEST_P(CacheStorageCacheTestP, PutReplaceInBatch) {
operations.push_back(operation1);
operations.push_back(operation2);
- EXPECT_EQ(CACHE_STORAGE_OK, BatchOperation(operations));
+ EXPECT_EQ(CacheStorageError::kSuccess, BatchOperation(operations));
// |operation2| should win.
EXPECT_TRUE(Match(operation2.request));
@@ -949,37 +1007,37 @@ TEST_P(CacheStorageCacheTestP, MatchBodyHead) {
}
TEST_P(CacheStorageCacheTestP, MatchAll_Empty) {
- std::unique_ptr<CacheStorageCache::Responses> responses;
+ std::vector<ServiceWorkerResponse> responses;
std::unique_ptr<CacheStorageCache::BlobDataHandles> body_handles;
EXPECT_TRUE(MatchAll(&responses, &body_handles));
- EXPECT_TRUE(responses->empty());
+ EXPECT_TRUE(responses.empty());
EXPECT_TRUE(body_handles->empty());
}
TEST_P(CacheStorageCacheTestP, MatchAll_NoBody) {
EXPECT_TRUE(Put(no_body_request_, no_body_response_));
- std::unique_ptr<CacheStorageCache::Responses> responses;
+ std::vector<ServiceWorkerResponse> responses;
std::unique_ptr<CacheStorageCache::BlobDataHandles> body_handles;
EXPECT_TRUE(MatchAll(&responses, &body_handles));
- ASSERT_EQ(1u, responses->size());
+ ASSERT_EQ(1u, responses.size());
EXPECT_TRUE(
- ResponseMetadataEqual(SetCacheName(no_body_response_), responses->at(0)));
+ ResponseMetadataEqual(SetCacheName(no_body_response_), responses[0]));
EXPECT_FALSE(body_handles->at(0));
}
TEST_P(CacheStorageCacheTestP, MatchAll_Body) {
EXPECT_TRUE(Put(body_request_, body_response_));
- std::unique_ptr<CacheStorageCache::Responses> responses;
+ std::vector<ServiceWorkerResponse> responses;
std::unique_ptr<CacheStorageCache::BlobDataHandles> body_handles;
EXPECT_TRUE(MatchAll(&responses, &body_handles));
- ASSERT_EQ(1u, responses->size());
+ ASSERT_EQ(1u, responses.size());
ASSERT_EQ(1u, body_handles->size());
EXPECT_TRUE(
- ResponseMetadataEqual(SetCacheName(body_response_), responses->at(0)));
+ ResponseMetadataEqual(SetCacheName(body_response_), responses[0]));
EXPECT_TRUE(ResponseBodiesEqual(expected_blob_data_, *body_handles->at(0)));
}
@@ -987,27 +1045,27 @@ TEST_P(CacheStorageCacheTestP, MatchAll_TwoResponsesThenOne) {
EXPECT_TRUE(Put(no_body_request_, no_body_response_));
EXPECT_TRUE(Put(body_request_, body_response_));
- std::unique_ptr<CacheStorageCache::Responses> responses;
+ std::vector<ServiceWorkerResponse> responses;
std::unique_ptr<CacheStorageCache::BlobDataHandles> body_handles;
EXPECT_TRUE(MatchAll(&responses, &body_handles));
ASSERT_TRUE(body_handles->at(1));
EXPECT_TRUE(
- ResponseMetadataEqual(SetCacheName(no_body_response_), responses->at(0)));
+ ResponseMetadataEqual(SetCacheName(no_body_response_), responses[0]));
EXPECT_FALSE(body_handles->at(0));
EXPECT_TRUE(
- ResponseMetadataEqual(SetCacheName(body_response_), responses->at(1)));
+ ResponseMetadataEqual(SetCacheName(body_response_), responses[1]));
EXPECT_TRUE(ResponseBodiesEqual(expected_blob_data_, *body_handles->at(1)));
- responses->clear();
+ responses.clear();
body_handles->clear();
EXPECT_TRUE(Delete(body_request_));
EXPECT_TRUE(MatchAll(&responses, &body_handles));
- ASSERT_EQ(1u, responses->size());
+ ASSERT_EQ(1u, responses.size());
EXPECT_TRUE(
- ResponseMetadataEqual(SetCacheName(no_body_response_), responses->at(0)));
+ ResponseMetadataEqual(SetCacheName(no_body_response_), responses[0]));
ASSERT_EQ(1u, body_handles->size());
EXPECT_FALSE(body_handles->at(0));
}
@@ -1129,36 +1187,36 @@ TEST_P(CacheStorageCacheTestP, MatchAll_IgnoreMethod) {
ServiceWorkerFetchRequest post_request = body_request_;
post_request.method = "POST";
- std::unique_ptr<CacheStorageCache::Responses> responses;
+ std::vector<ServiceWorkerResponse> responses;
std::unique_ptr<CacheStorageCache::BlobDataHandles> body_handles;
CacheStorageCacheQueryParams match_params;
EXPECT_TRUE(MatchAll(post_request, match_params, &responses, &body_handles));
- EXPECT_EQ(0u, responses->size());
+ EXPECT_EQ(0u, responses.size());
match_params.ignore_method = true;
EXPECT_TRUE(MatchAll(post_request, match_params, &responses, &body_handles));
- EXPECT_EQ(1u, responses->size());
+ EXPECT_EQ(1u, responses.size());
}
TEST_P(CacheStorageCacheTestP, MatchAll_IgnoreVary) {
body_request_.headers["vary_foo"] = "foo";
body_response_.headers["vary"] = "vary_foo";
EXPECT_TRUE(Put(body_request_, body_response_));
- std::unique_ptr<CacheStorageCache::Responses> responses;
+ std::vector<ServiceWorkerResponse> responses;
std::unique_ptr<CacheStorageCache::BlobDataHandles> body_handles;
CacheStorageCacheQueryParams match_params;
EXPECT_TRUE(MatchAll(body_request_, match_params, &responses, &body_handles));
- EXPECT_EQ(1u, responses->size());
+ EXPECT_EQ(1u, responses.size());
body_request_.headers["vary_foo"] = "bar";
EXPECT_TRUE(MatchAll(body_request_, match_params, &responses, &body_handles));
- EXPECT_EQ(0u, responses->size());
+ EXPECT_EQ(0u, responses.size());
match_params.ignore_vary = true;
EXPECT_TRUE(MatchAll(body_request_, match_params, &responses, &body_handles));
- EXPECT_EQ(1u, responses->size());
+ EXPECT_EQ(1u, responses.size());
}
TEST_P(CacheStorageCacheTestP, MatchAll_IgnoreSearch) {
@@ -1166,18 +1224,18 @@ TEST_P(CacheStorageCacheTestP, MatchAll_IgnoreSearch) {
EXPECT_TRUE(Put(body_request_with_query_, body_response_with_query_));
EXPECT_TRUE(Put(no_body_request_, no_body_response_));
- std::unique_ptr<CacheStorageCache::Responses> responses;
+ std::vector<ServiceWorkerResponse> responses;
std::unique_ptr<CacheStorageCache::BlobDataHandles> body_handles;
CacheStorageCacheQueryParams match_params;
match_params.ignore_search = true;
EXPECT_TRUE(MatchAll(body_request_, match_params, &responses, &body_handles));
- ASSERT_EQ(2u, responses->size());
+ ASSERT_EQ(2u, responses.size());
ASSERT_EQ(2u, body_handles->size());
// Order of returned responses is not guaranteed.
std::set<std::string> matched_set;
- for (const ServiceWorkerResponse& response : *responses) {
+ for (const ServiceWorkerResponse& response : responses) {
ASSERT_EQ(1u, response.url_list.size());
if (response.url_list[0].spec() ==
"http://example.com/body.html?query=test") {
@@ -1196,22 +1254,22 @@ TEST_P(CacheStorageCacheTestP, MatchAll_IgnoreSearch) {
TEST_P(CacheStorageCacheTestP, MatchAll_Head) {
EXPECT_TRUE(Put(body_request_, body_response_));
- std::unique_ptr<CacheStorageCache::Responses> responses;
+ std::vector<ServiceWorkerResponse> responses;
std::unique_ptr<CacheStorageCache::BlobDataHandles> body_handles;
CacheStorageCacheQueryParams match_params;
match_params.ignore_search = true;
EXPECT_TRUE(
MatchAll(body_head_request_, match_params, &responses, &body_handles));
- EXPECT_TRUE(responses->empty());
+ EXPECT_TRUE(responses.empty());
EXPECT_TRUE(body_handles->empty());
match_params.ignore_method = true;
EXPECT_TRUE(
MatchAll(body_head_request_, match_params, &responses, &body_handles));
- ASSERT_EQ(1u, responses->size());
+ ASSERT_EQ(1u, responses.size());
ASSERT_EQ(1u, body_handles->size());
EXPECT_TRUE(
- ResponseMetadataEqual(SetCacheName(body_response_), responses->at(0)));
+ ResponseMetadataEqual(SetCacheName(body_response_), responses[0]));
EXPECT_TRUE(ResponseBodiesEqual(expected_blob_data_, *body_handles->at(0)));
}
@@ -1432,6 +1490,83 @@ TEST_P(CacheStorageCacheTestP, PutResponseType) {
TestResponseType(network::mojom::FetchResponseType::kOpaqueRedirect));
}
+TEST_P(CacheStorageCacheTestP, PutWithSideData) {
+ ServiceWorkerResponse response(body_response_);
+
+ const std::string expected_side_data = "SideData";
+ std::unique_ptr<storage::BlobDataHandle> side_data_blob_handle =
+ BuildBlobHandle("blob-id:mysideblob", expected_side_data);
+
+ CopySideDataToResponse(side_data_blob_handle.get(), &response);
+ EXPECT_TRUE(Put(body_request_, response));
+
+ EXPECT_TRUE(Match(body_request_));
+ EXPECT_TRUE(callback_response_data_);
+ EXPECT_TRUE(
+ ResponseBodiesEqual(expected_blob_data_, *callback_response_data_));
+ EXPECT_TRUE(
+ ResponseSideDataEqual(expected_side_data, *callback_response_data_));
+}
+
+TEST_P(CacheStorageCacheTestP, PutWithSideData_QuotaExceeded) {
+ mock_quota_manager_->SetQuota(GURL(kOrigin), storage::kStorageTypeTemporary,
+ expected_blob_data_.size() - 1);
+ ServiceWorkerResponse response(body_response_);
+ const std::string expected_side_data = "SideData";
+ std::unique_ptr<storage::BlobDataHandle> side_data_blob_handle =
+ BuildBlobHandle("blob-id:mysideblob", expected_side_data);
+
+ CopySideDataToResponse(side_data_blob_handle.get(), &response);
+ // When the available space is not enough for the body, Put operation must
+ // fail.
+ EXPECT_FALSE(Put(body_request_, response));
+ EXPECT_EQ(CacheStorageError::kErrorQuotaExceeded, callback_error_);
+}
+
+TEST_P(CacheStorageCacheTestP, PutWithSideData_QuotaExceededSkipSideData) {
+ mock_quota_manager_->SetQuota(GURL(kOrigin), storage::kStorageTypeTemporary,
+ expected_blob_data_.size());
+ ServiceWorkerResponse response(body_response_);
+ const std::string expected_side_data = "SideData";
+ std::unique_ptr<storage::BlobDataHandle> side_data_blob_handle =
+ BuildBlobHandle("blob-id:mysideblob", expected_side_data);
+
+ CopySideDataToResponse(side_data_blob_handle.get(), &response);
+ // When the available space is enough for the body but not enough for the side
+ // data, Put operation must succeed.
+ EXPECT_TRUE(Put(body_request_, response));
+
+ EXPECT_TRUE(Match(body_request_));
+ EXPECT_TRUE(callback_response_data_);
+ EXPECT_TRUE(
+ ResponseBodiesEqual(expected_blob_data_, *callback_response_data_));
+ // The side data should not be written.
+ EXPECT_TRUE(ResponseSideDataEqual("", *callback_response_data_));
+}
+
+TEST_P(CacheStorageCacheTestP, PutWithSideData_BadMessage) {
+ ServiceWorkerResponse response(body_response_);
+
+ const std::string expected_side_data = "SideData";
+ std::unique_ptr<storage::BlobDataHandle> side_data_blob_handle =
+ BuildBlobHandle("blob-id:mysideblob", expected_side_data);
+
+ CopySideDataToResponse(side_data_blob_handle.get(), &response);
+
+ CacheStorageBatchOperation operation;
+ operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT;
+ operation.request = body_request_;
+ operation.response = response;
+ operation.response.blob_size = UINT64_MAX;
+
+ std::vector<CacheStorageBatchOperation> operations =
+ std::vector<CacheStorageBatchOperation>(1, operation);
+ EXPECT_EQ(CacheStorageError::kErrorStorage, BatchOperation(operations));
+ EXPECT_EQ(bad_message::CSDH_UNEXPECTED_OPERATION, *bad_message_reason_);
+
+ EXPECT_FALSE(Match(body_request_));
+}
+
TEST_P(CacheStorageCacheTestP, WriteSideData) {
base::Time response_time(base::Time::Now());
ServiceWorkerResponse response(body_response_);
@@ -1479,7 +1614,7 @@ TEST_P(CacheStorageCacheTestP, WriteSideData_QuotaExceeded) {
memset(buffer->data(), 0, kSize);
EXPECT_FALSE(
WriteSideData(no_body_request_.url, response_time, buffer, kSize));
- EXPECT_EQ(CACHE_STORAGE_ERROR_QUOTA_EXCEEDED, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorQuotaExceeded, callback_error_);
ASSERT_TRUE(Delete(no_body_request_));
}
@@ -1516,7 +1651,7 @@ TEST_P(CacheStorageCacheTestP, WriteSideData_DifferentTimeStamp) {
EXPECT_FALSE(WriteSideData(no_body_request_.url,
response_time + base::TimeDelta::FromSeconds(1),
buffer, kSize));
- EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorNotFound, callback_error_);
ASSERT_TRUE(Delete(no_body_request_));
}
@@ -1526,20 +1661,20 @@ TEST_P(CacheStorageCacheTestP, WriteSideData_NotFound) {
memset(buffer->data(), 0, kSize);
EXPECT_FALSE(WriteSideData(GURL("http://www.example.com/not_exist"),
base::Time::Now(), buffer, kSize));
- EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorNotFound, callback_error_);
}
TEST_F(CacheStorageCacheTest, CaselessServiceWorkerResponseHeaders) {
// CacheStorageCache depends on ServiceWorkerResponse having caseless
// headers so that it can quickly lookup vary headers.
ServiceWorkerResponse response(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), "", 0, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown, base::Time(),
+ std::make_unique<ServiceWorkerHeaderMap>(), "", 0, nullptr /* blob */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time(),
false /* is_in_cache_storage */,
std::string() /* cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */);
response.headers["content-type"] = "foo";
response.headers["Content-Type"] = "bar";
@@ -1591,7 +1726,7 @@ TEST_P(CacheStorageCacheTestP, PutObeysQuotaLimits) {
mock_quota_manager_->SetQuota(GURL(kOrigin), storage::kStorageTypeTemporary,
0);
EXPECT_FALSE(Put(body_request_, body_response_));
- EXPECT_EQ(CACHE_STORAGE_ERROR_QUOTA_EXCEEDED, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorQuotaExceeded, callback_error_);
}
TEST_P(CacheStorageCacheTestP, Size) {
@@ -1760,7 +1895,8 @@ TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) {
std::vector<CacheStorageBatchOperation>(1, operation1),
base::BindOnce(&CacheStorageCacheTest::SequenceCallback,
base::Unretained(this), 1, &sequence_out,
- close_loop1.get()));
+ close_loop1.get()),
+ CacheStorageCache::BadMessageCallback());
// Blocks on creating the cache entry.
base::RunLoop().RunUntilIdle();
@@ -1776,7 +1912,8 @@ TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) {
std::vector<CacheStorageBatchOperation>(1, operation2),
base::BindOnce(&CacheStorageCacheTest::SequenceCallback,
base::Unretained(this), 2, &sequence_out,
- close_loop2.get()));
+ close_loop2.get()),
+ CacheStorageCache::BadMessageCallback());
// The second put operation should wait for the first to complete.
base::RunLoop().RunUntilIdle();
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 c3bb6db5ceb..8e1bb016e43 100644
--- a/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc
@@ -24,54 +24,30 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/origin_util.h"
#include "storage/browser/blob/blob_data_handle.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCacheError.h"
+#include "third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
+using blink::mojom::CacheStorageError;
+
namespace content {
namespace {
-const uint32_t kFilteredMessageClasses[] = {CacheStorageMsgStart};
+const uint32_t kCacheFilteredMessageClasses[] = {CacheStorageMsgStart};
const int32_t kCachePreservationSeconds = 5;
-blink::WebServiceWorkerCacheError ToWebServiceWorkerCacheError(
- CacheStorageError err) {
- switch (err) {
- case CACHE_STORAGE_OK:
- NOTREACHED();
- return blink::kWebServiceWorkerCacheErrorNotImplemented;
- case CACHE_STORAGE_ERROR_EXISTS:
- return blink::kWebServiceWorkerCacheErrorExists;
- case CACHE_STORAGE_ERROR_STORAGE:
- // TODO(nhiroki): Add WebServiceWorkerCacheError equivalent to
- // CACHE_STORAGE_ERROR_STORAGE.
- return blink::kWebServiceWorkerCacheErrorNotFound;
- case CACHE_STORAGE_ERROR_NOT_FOUND:
- return blink::kWebServiceWorkerCacheErrorNotFound;
- case CACHE_STORAGE_ERROR_QUOTA_EXCEEDED:
- return blink::kWebServiceWorkerCacheErrorQuotaExceeded;
- case CACHE_STORAGE_ERROR_CACHE_NAME_NOT_FOUND:
- return blink::kWebServiceWorkerCacheErrorCacheNameNotFound;
- case CACHE_STORAGE_ERROR_QUERY_TOO_LARGE:
- return blink::kWebServiceWorkerCacheErrorTooLarge;
- }
- NOTREACHED();
- return blink::kWebServiceWorkerCacheErrorNotImplemented;
-}
-
bool OriginCanAccessCacheStorage(const url::Origin& origin) {
return !origin.unique() && IsOriginSecure(origin.GetURL());
}
-void StopPreservingCache(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle) {}
+void StopPreservingCache(CacheStorageCacheHandle cache_handle) {}
} // namespace
CacheStorageDispatcherHost::CacheStorageDispatcherHost()
- : BrowserMessageFilter(kFilteredMessageClasses,
- arraysize(kFilteredMessageClasses)) {}
+ : BrowserMessageFilter(kCacheFilteredMessageClasses,
+ arraysize(kCacheFilteredMessageClasses)) {}
CacheStorageDispatcherHost::~CacheStorageDispatcherHost() {
}
@@ -224,13 +200,13 @@ void CacheStorageDispatcherHost::OnCacheMatch(
const ServiceWorkerFetchRequest& request,
const CacheStorageCacheQueryParams& match_params) {
IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
- if (it == id_to_cache_map_.end() || !it->second->value()) {
+ if (it == id_to_cache_map_.end() || !it->second.value()) {
Send(new CacheStorageMsg_CacheMatchError(
- thread_id, request_id, blink::kWebServiceWorkerCacheErrorNotFound));
+ thread_id, request_id, CacheStorageError::kErrorNotFound));
return;
}
- CacheStorageCache* cache = it->second->value();
+ CacheStorageCache* cache = it->second.value();
std::unique_ptr<ServiceWorkerFetchRequest> scoped_request(
new ServiceWorkerFetchRequest(request.url, request.method,
request.headers, request.referrer,
@@ -238,7 +214,7 @@ void CacheStorageDispatcherHost::OnCacheMatch(
cache->Match(
std::move(scoped_request), match_params,
base::BindOnce(&CacheStorageDispatcherHost::OnCacheMatchCallback, this,
- thread_id, request_id, base::Passed(it->second->Clone())));
+ thread_id, request_id, base::Passed(it->second.Clone())));
}
void CacheStorageDispatcherHost::OnCacheMatchAll(
@@ -248,19 +224,19 @@ void CacheStorageDispatcherHost::OnCacheMatchAll(
const ServiceWorkerFetchRequest& request,
const CacheStorageCacheQueryParams& match_params) {
IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
- if (it == id_to_cache_map_.end() || !it->second->value()) {
+ if (it == id_to_cache_map_.end() || !it->second.value()) {
Send(new CacheStorageMsg_CacheMatchError(
- thread_id, request_id, blink::kWebServiceWorkerCacheErrorNotFound));
+ thread_id, request_id, CacheStorageError::kErrorNotFound));
return;
}
- CacheStorageCache* cache = it->second->value();
+ CacheStorageCache* cache = it->second.value();
if (request.url.is_empty()) {
cache->MatchAll(
std::unique_ptr<ServiceWorkerFetchRequest>(), match_params,
base::BindOnce(&CacheStorageDispatcherHost::OnCacheMatchAllCallback,
this, thread_id, request_id,
- base::Passed(it->second->Clone())));
+ base::Passed(it->second.Clone())));
return;
}
@@ -273,14 +249,14 @@ void CacheStorageDispatcherHost::OnCacheMatchAll(
std::move(scoped_request), match_params,
base::BindOnce(&CacheStorageDispatcherHost::OnCacheMatchAllCallback,
this, thread_id, request_id,
- base::Passed(it->second->Clone())));
+ base::Passed(it->second.Clone())));
return;
}
cache->Match(
std::move(scoped_request), match_params,
base::BindOnce(
&CacheStorageDispatcherHost::OnCacheMatchAllCallbackAdapter, this,
- thread_id, request_id, base::Passed(it->second->Clone())));
+ thread_id, request_id, base::Passed(it->second.Clone())));
}
void CacheStorageDispatcherHost::OnCacheKeys(
@@ -290,13 +266,13 @@ void CacheStorageDispatcherHost::OnCacheKeys(
const ServiceWorkerFetchRequest& request,
const CacheStorageCacheQueryParams& match_params) {
IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
- if (it == id_to_cache_map_.end() || !it->second->value()) {
- Send(new CacheStorageMsg_CacheKeysError(
- thread_id, request_id, blink::kWebServiceWorkerCacheErrorNotFound));
+ if (it == id_to_cache_map_.end() || !it->second.value()) {
+ Send(new CacheStorageMsg_CacheKeysError(thread_id, request_id,
+ CacheStorageError::kErrorNotFound));
return;
}
- CacheStorageCache* cache = it->second->value();
+ CacheStorageCache* cache = it->second.value();
std::unique_ptr<ServiceWorkerFetchRequest> request_ptr(
new ServiceWorkerFetchRequest(request.url, request.method,
request.headers, request.referrer,
@@ -304,7 +280,7 @@ void CacheStorageDispatcherHost::OnCacheKeys(
cache->Keys(
std::move(request_ptr), match_params,
base::BindOnce(&CacheStorageDispatcherHost::OnCacheKeysCallback, this,
- thread_id, request_id, base::Passed(it->second->Clone())));
+ thread_id, request_id, base::Passed(it->second.Clone())));
}
void CacheStorageDispatcherHost::OnCacheBatch(
@@ -313,17 +289,18 @@ void CacheStorageDispatcherHost::OnCacheBatch(
int cache_id,
const std::vector<CacheStorageBatchOperation>& operations) {
IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
- if (it == id_to_cache_map_.end() || !it->second->value()) {
+ if (it == id_to_cache_map_.end() || !it->second.value()) {
Send(new CacheStorageMsg_CacheBatchError(
- thread_id, request_id, blink::kWebServiceWorkerCacheErrorNotFound));
+ thread_id, request_id, CacheStorageError::kErrorNotFound));
return;
}
- CacheStorageCache* cache = it->second->value();
+ CacheStorageCache* cache = it->second.value();
cache->BatchOperation(
operations,
base::BindOnce(&CacheStorageDispatcherHost::OnCacheBatchCallback, this,
- thread_id, request_id, base::Passed(it->second->Clone())));
+ thread_id, request_id, base::Passed(it->second.Clone())),
+ base::BindOnce(&CacheStorageDispatcherHost::OnBadMessage, this));
}
void CacheStorageDispatcherHost::OnCacheClosed(int cache_id) {
@@ -339,14 +316,14 @@ void CacheStorageDispatcherHost::OnCacheStorageHasCallback(
int request_id,
bool has_cache,
CacheStorageError error) {
- if (error != CACHE_STORAGE_OK) {
- Send(new CacheStorageMsg_CacheStorageHasError(
- thread_id, request_id, ToWebServiceWorkerCacheError(error)));
+ if (error != CacheStorageError::kSuccess) {
+ Send(
+ new CacheStorageMsg_CacheStorageHasError(thread_id, request_id, error));
return;
}
if (!has_cache) {
Send(new CacheStorageMsg_CacheStorageHasError(
- thread_id, request_id, blink::kWebServiceWorkerCacheErrorNotFound));
+ thread_id, request_id, CacheStorageError::kErrorNotFound));
return;
}
Send(new CacheStorageMsg_CacheStorageHasSuccess(thread_id, request_id));
@@ -355,11 +332,11 @@ void CacheStorageDispatcherHost::OnCacheStorageHasCallback(
void CacheStorageDispatcherHost::OnCacheStorageOpenCallback(
int thread_id,
int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheStorageError error) {
- if (error != CACHE_STORAGE_OK) {
- Send(new CacheStorageMsg_CacheStorageOpenError(
- thread_id, request_id, ToWebServiceWorkerCacheError(error)));
+ if (error != CacheStorageError::kSuccess) {
+ Send(new CacheStorageMsg_CacheStorageOpenError(thread_id, request_id,
+ error));
return;
}
@@ -367,7 +344,7 @@ void CacheStorageDispatcherHost::OnCacheStorageOpenCallback(
// and reopens it the cache backend won't have to be reinitialized.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
- base::BindOnce(&StopPreservingCache, base::Passed(cache_handle->Clone())),
+ base::BindOnce(&StopPreservingCache, base::Passed(cache_handle.Clone())),
base::TimeDelta::FromSeconds(kCachePreservationSeconds));
CacheID cache_id = StoreCacheReference(std::move(cache_handle));
@@ -380,9 +357,9 @@ void CacheStorageDispatcherHost::OnCacheStorageDeleteCallback(
int request_id,
bool deleted,
CacheStorageError error) {
- if (!deleted || error != CACHE_STORAGE_OK) {
- Send(new CacheStorageMsg_CacheStorageDeleteError(
- thread_id, request_id, ToWebServiceWorkerCacheError(error)));
+ if (!deleted || error != CacheStorageError::kSuccess) {
+ Send(new CacheStorageMsg_CacheStorageDeleteError(thread_id, request_id,
+ error));
return;
}
Send(new CacheStorageMsg_CacheStorageDeleteSuccess(thread_id, request_id));
@@ -405,9 +382,9 @@ void CacheStorageDispatcherHost::OnCacheStorageMatchCallback(
CacheStorageError error,
std::unique_ptr<ServiceWorkerResponse> response,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle) {
- if (error != CACHE_STORAGE_OK) {
- Send(new CacheStorageMsg_CacheStorageMatchError(
- thread_id, request_id, ToWebServiceWorkerCacheError(error)));
+ if (error != CacheStorageError::kSuccess) {
+ Send(new CacheStorageMsg_CacheStorageMatchError(thread_id, request_id,
+ error));
return;
}
@@ -421,13 +398,12 @@ void CacheStorageDispatcherHost::OnCacheStorageMatchCallback(
void CacheStorageDispatcherHost::OnCacheMatchCallback(
int thread_id,
int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheStorageError error,
std::unique_ptr<ServiceWorkerResponse> response,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle) {
- if (error != CACHE_STORAGE_OK) {
- Send(new CacheStorageMsg_CacheMatchError(
- thread_id, request_id, ToWebServiceWorkerCacheError(error)));
+ if (error != CacheStorageError::kSuccess) {
+ Send(new CacheStorageMsg_CacheMatchError(thread_id, request_id, error));
return;
}
@@ -440,17 +416,16 @@ void CacheStorageDispatcherHost::OnCacheMatchCallback(
void CacheStorageDispatcherHost::OnCacheMatchAllCallbackAdapter(
int thread_id,
int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheStorageError error,
std::unique_ptr<ServiceWorkerResponse> response,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle) {
- std::unique_ptr<CacheStorageCache::Responses> responses(
- new CacheStorageCache::Responses);
+ std::vector<ServiceWorkerResponse> responses;
std::unique_ptr<CacheStorageCache::BlobDataHandles> blob_data_handles(
new CacheStorageCache::BlobDataHandles);
- if (error == CACHE_STORAGE_OK) {
+ if (error == CacheStorageError::kSuccess) {
DCHECK(response);
- responses->push_back(*response);
+ responses.push_back(*response);
if (blob_data_handle)
blob_data_handles->push_back(std::move(blob_data_handle));
}
@@ -461,13 +436,13 @@ void CacheStorageDispatcherHost::OnCacheMatchAllCallbackAdapter(
void CacheStorageDispatcherHost::OnCacheMatchAllCallback(
int thread_id,
int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheStorageError error,
- std::unique_ptr<CacheStorageCache::Responses> responses,
+ std::vector<ServiceWorkerResponse> responses,
std::unique_ptr<CacheStorageCache::BlobDataHandles> blob_data_handles) {
- if (error != CACHE_STORAGE_OK && error != CACHE_STORAGE_ERROR_NOT_FOUND) {
- Send(new CacheStorageMsg_CacheMatchAllError(
- thread_id, request_id, ToWebServiceWorkerCacheError(error)));
+ if (error != CacheStorageError::kSuccess &&
+ error != CacheStorageError::kErrorNotFound) {
+ Send(new CacheStorageMsg_CacheMatchAllError(thread_id, request_id, error));
return;
}
@@ -477,18 +452,17 @@ void CacheStorageDispatcherHost::OnCacheMatchAllCallback(
}
Send(new CacheStorageMsg_CacheMatchAllSuccess(thread_id, request_id,
- *responses));
+ responses));
}
void CacheStorageDispatcherHost::OnCacheKeysCallback(
int thread_id,
int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheStorageError error,
std::unique_ptr<CacheStorageCache::Requests> requests) {
- if (error != CACHE_STORAGE_OK) {
- Send(new CacheStorageMsg_CacheKeysError(
- thread_id, request_id, ToWebServiceWorkerCacheError(error)));
+ if (error != CacheStorageError::kSuccess) {
+ Send(new CacheStorageMsg_CacheKeysError(thread_id, request_id, error));
return;
}
@@ -498,20 +472,24 @@ void CacheStorageDispatcherHost::OnCacheKeysCallback(
void CacheStorageDispatcherHost::OnCacheBatchCallback(
int thread_id,
int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheStorageError error) {
- if (error != CACHE_STORAGE_OK) {
- Send(new CacheStorageMsg_CacheBatchError(
- thread_id, request_id, ToWebServiceWorkerCacheError(error)));
+ if (error != CacheStorageError::kSuccess) {
+ Send(new CacheStorageMsg_CacheBatchError(thread_id, request_id, error));
return;
}
Send(new CacheStorageMsg_CacheBatchSuccess(thread_id, request_id));
}
+void CacheStorageDispatcherHost::OnBadMessage(
+ bad_message::BadMessageReason reason) {
+ bad_message::ReceivedBadMessage(this, reason);
+}
+
CacheStorageDispatcherHost::CacheID
CacheStorageDispatcherHost::StoreCacheReference(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle) {
+ CacheStorageCacheHandle cache_handle) {
int cache_id = next_cache_id_++;
id_to_cache_map_[cache_id] = std::move(cache_handle);
return cache_id;
diff --git a/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.h b/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.h
index 5206dac5f66..459a6ee7d5f 100644
--- a/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.h
+++ b/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.h
@@ -14,6 +14,7 @@
#include <vector>
#include "base/macros.h"
+#include "content/browser/bad_message.h"
#include "content/browser/cache_storage/cache_storage.h"
#include "content/browser/cache_storage/cache_storage_index.h"
#include "content/public/browser/browser_message_filter.h"
@@ -46,8 +47,7 @@ class CONTENT_EXPORT CacheStorageDispatcherHost : public BrowserMessageFilter {
friend class base::DeleteHelper<CacheStorageDispatcherHost>;
typedef int32_t CacheID; // TODO(jkarlin): Bump to 64 bit.
- typedef std::map<CacheID, std::unique_ptr<CacheStorageCacheHandle>>
- IDToCacheMap;
+ typedef std::map<CacheID, CacheStorageCacheHandle> IDToCacheMap;
typedef std::map<std::string, std::list<storage::BlobDataHandle>>
UUIDToBlobDataHandleList;
@@ -100,23 +100,22 @@ class CONTENT_EXPORT CacheStorageDispatcherHost : public BrowserMessageFilter {
void OnCacheStorageHasCallback(int thread_id,
int request_id,
bool has_cache,
- CacheStorageError error);
- void OnCacheStorageOpenCallback(
- int thread_id,
- int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- CacheStorageError error);
+ blink::mojom::CacheStorageError error);
+ void OnCacheStorageOpenCallback(int thread_id,
+ int request_id,
+ CacheStorageCacheHandle cache_handle,
+ blink::mojom::CacheStorageError error);
void OnCacheStorageDeleteCallback(int thread_id,
int request_id,
bool deleted,
- CacheStorageError error);
+ blink::mojom::CacheStorageError error);
void OnCacheStorageKeysCallback(int thread_id,
int request_id,
const CacheStorageIndex& cache_index);
void OnCacheStorageMatchCallback(
int thread_id,
int request_id,
- CacheStorageError error,
+ blink::mojom::CacheStorageError error,
std::unique_ptr<ServiceWorkerResponse> response,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle);
@@ -124,23 +123,23 @@ class CONTENT_EXPORT CacheStorageDispatcherHost : public BrowserMessageFilter {
void OnCacheMatchCallback(
int thread_id,
int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- CacheStorageError error,
+ CacheStorageCacheHandle cache_handle,
+ blink::mojom::CacheStorageError error,
std::unique_ptr<ServiceWorkerResponse> response,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle);
void OnCacheMatchAllCallbackAdapter(
int thread_id,
int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- CacheStorageError error,
+ CacheStorageCacheHandle cache_handle,
+ blink::mojom::CacheStorageError error,
std::unique_ptr<ServiceWorkerResponse> response,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle);
void OnCacheMatchAllCallback(
int thread_id,
int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- CacheStorageError error,
- std::unique_ptr<std::vector<ServiceWorkerResponse>> responses,
+ CacheStorageCacheHandle cache_handle,
+ blink::mojom::CacheStorageError error,
+ std::vector<ServiceWorkerResponse> responses,
std::unique_ptr<CacheStorageCache::BlobDataHandles> blob_data_handles);
void OnCacheMatchAll(int thread_id,
int request_id,
@@ -150,19 +149,20 @@ class CONTENT_EXPORT CacheStorageDispatcherHost : public BrowserMessageFilter {
void OnCacheKeysCallback(
int thread_id,
int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- CacheStorageError error,
+ CacheStorageCacheHandle cache_handle,
+ blink::mojom::CacheStorageError error,
std::unique_ptr<CacheStorageCache::Requests> requests);
- void OnCacheBatchCallback(
- int thread_id,
- int request_id,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- CacheStorageError error);
+ void OnCacheBatchCallback(int thread_id,
+ int request_id,
+ CacheStorageCacheHandle cache_handle,
+ blink::mojom::CacheStorageError error);
+
+ // Called when a bad message is detected while executing operations.
+ void OnBadMessage(bad_message::BadMessageReason reason);
// Hangs onto a cache handle. Returns a unique cache_id. Call
// DropCacheReference when the reference is no longer needed.
- CacheID StoreCacheReference(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle);
+ CacheID StoreCacheReference(CacheStorageCacheHandle cache_handle);
void DropCacheReference(CacheID cache_id);
// Stores blob handles while waiting for acknowledgement of receipt from the
diff --git a/chromium/content/browser/cache_storage/cache_storage_manager.cc b/chromium/content/browser/cache_storage/cache_storage_manager.cc
index 8457a2f9c83..30dc6bd3fb8 100644
--- a/chromium/content/browser/cache_storage/cache_storage_manager.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_manager.cc
@@ -204,7 +204,7 @@ void CacheStorageManager::DeleteCache(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
CacheStorage* cache_storage = FindOrCreateCacheStorage(origin);
- cache_storage->DeleteCache(cache_name, std::move(callback));
+ cache_storage->DoomCache(cache_name, std::move(callback));
}
void CacheStorageManager::EnumerateCaches(
@@ -265,13 +265,13 @@ void CacheStorageManager::RemoveObserver(
void CacheStorageManager::NotifyCacheListChanged(const GURL& origin) {
for (auto& observer : observers_)
- observer.OnCacheListChanged(url::Origin(origin));
+ observer.OnCacheListChanged(url::Origin::Create(origin));
}
void CacheStorageManager::NotifyCacheContentChanged(const GURL& origin,
const std::string& name) {
for (auto& observer : observers_)
- observer.OnCacheContentChanged(url::Origin(origin), name);
+ observer.OnCacheContentChanged(url::Origin::Create(origin), name);
}
void CacheStorageManager::GetAllOriginsUsage(
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 46a8d4a5fb7..823d7244ff7 100644
--- a/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -33,6 +33,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cache_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_bundle.h"
#include "content/public/test/test_utils.h"
@@ -43,6 +44,7 @@
#include "services/network/public/interfaces/fetch_api.mojom.h"
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_data_handle.h"
+#include "storage/browser/blob/blob_impl.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/blob/blob_url_request_job_factory.h"
#include "storage/browser/quota/quota_manager_proxy.h"
@@ -50,7 +52,9 @@
#include "storage/browser/test/mock_special_storage_policy.h"
#include "storage/common/blob_storage/blob_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h"
+using blink::mojom::CacheStorageError;
using network::mojom::FetchResponseType;
namespace content {
@@ -107,7 +111,7 @@ class TestCacheStorageObserver : public CacheStorageContextImpl::Observer {
std::unique_ptr<storage::BlobProtocolHandler> CreateMockBlobProtocolHandler(
storage::BlobStorageContext* blob_storage_context) {
return base::WrapUnique(
- new storage::BlobProtocolHandler(blob_storage_context, nullptr));
+ new storage::BlobProtocolHandler(blob_storage_context));
}
class CacheStorageManagerTest : public testing::Test {
@@ -116,7 +120,7 @@ class CacheStorageManagerTest : public testing::Test {
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
blob_storage_context_(nullptr),
callback_bool_(false),
- callback_error_(CACHE_STORAGE_OK),
+ callback_error_(CacheStorageError::kSuccess),
origin1_("http://example1.com"),
origin2_("http://example2.com") {}
@@ -149,10 +153,9 @@ class CacheStorageManagerTest : public testing::Test {
run_loop->Quit();
}
- void CacheAndErrorCallback(
- base::RunLoop* run_loop,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- CacheStorageError error) {
+ void CacheAndErrorCallback(base::RunLoop* run_loop,
+ CacheStorageCacheHandle cache_handle,
+ CacheStorageError error) {
callback_cache_handle_ = std::move(cache_handle);
callback_error_ = error;
run_loop->Quit();
@@ -256,6 +259,14 @@ class CacheStorageManagerTest : public testing::Test {
void DestroyStorageManager() {
if (quota_manager_proxy_)
quota_manager_proxy_->SimulateQuotaManagerDestroyed();
+
+ callback_cache_handle_ = CacheStorageCacheHandle();
+ callback_bool_ = false;
+ callback_cache_handle_response_ = nullptr;
+ callback_data_handle_ = nullptr;
+ callback_cache_index_ = CacheStorageIndex();
+ callback_all_origins_usage_.clear();
+
base::RunLoop().RunUntilIdle();
quota_manager_proxy_ = nullptr;
@@ -265,13 +276,6 @@ class CacheStorageManagerTest : public testing::Test {
quota_policy_ = nullptr;
mock_quota_manager_ = nullptr;
- callback_cache_handle_ = nullptr;
- callback_bool_ = false;
- callback_cache_handle_response_ = nullptr;
- callback_data_handle_ = nullptr;
- callback_cache_index_ = CacheStorageIndex();
- callback_all_origins_usage_.clear();
-
cache_manager_ = nullptr;
}
@@ -283,11 +287,11 @@ class CacheStorageManagerTest : public testing::Test {
base::Unretained(this), base::Unretained(&loop)));
loop.Run();
- bool error = callback_error_ != CACHE_STORAGE_OK;
+ bool error = callback_error_ != CacheStorageError::kSuccess;
if (error)
- EXPECT_FALSE(callback_cache_handle_);
+ EXPECT_FALSE(callback_cache_handle_.value());
else
- EXPECT_TRUE(callback_cache_handle_);
+ EXPECT_TRUE(callback_cache_handle_.value());
return !error;
}
@@ -340,7 +344,7 @@ class CacheStorageManagerTest : public testing::Test {
const CacheStorageCacheQueryParams& match_params =
CacheStorageCacheQueryParams()) {
std::unique_ptr<ServiceWorkerFetchRequest> unique_request =
- base::MakeUnique<ServiceWorkerFetchRequest>(request);
+ std::make_unique<ServiceWorkerFetchRequest>(request);
base::RunLoop loop;
cache_manager_->MatchCache(
@@ -349,7 +353,7 @@ class CacheStorageManagerTest : public testing::Test {
base::Unretained(this), base::Unretained(&loop)));
loop.Run();
- return callback_error_ == CACHE_STORAGE_OK;
+ return callback_error_ == CacheStorageError::kSuccess;
}
bool StorageMatchAll(const GURL& origin,
@@ -367,7 +371,7 @@ class CacheStorageManagerTest : public testing::Test {
const CacheStorageCacheQueryParams& match_params =
CacheStorageCacheQueryParams()) {
std::unique_ptr<ServiceWorkerFetchRequest> unique_request =
- base::MakeUnique<ServiceWorkerFetchRequest>(request);
+ std::make_unique<ServiceWorkerFetchRequest>(request);
base::RunLoop loop;
cache_manager_->MatchAllCaches(
origin, std::move(unique_request), match_params,
@@ -375,7 +379,7 @@ class CacheStorageManagerTest : public testing::Test {
base::Unretained(this), base::Unretained(&loop)));
loop.Run();
- return callback_error_ == CACHE_STORAGE_OK;
+ return callback_error_ == CacheStorageError::kSuccess;
}
bool CachePut(CacheStorageCache* cache,
@@ -403,23 +407,33 @@ class CacheStorageManagerTest : public testing::Test {
FetchResponseType response_type = FetchResponseType::kDefault,
const ServiceWorkerHeaderMap& response_headers =
ServiceWorkerHeaderMap()) {
+ std::string blob_uuid = base::GenerateGUID();
std::unique_ptr<storage::BlobDataBuilder> blob_data(
- new storage::BlobDataBuilder(base::GenerateGUID()));
+ new storage::BlobDataBuilder(blob_uuid));
blob_data->AppendData(request.url.spec());
- std::unique_ptr<storage::BlobDataHandle> blob_handle =
+ std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
blob_storage_context_->AddFinishedBlob(blob_data.get());
+
+ scoped_refptr<storage::BlobHandle> blob_handle;
+ if (features::IsMojoBlobsEnabled()) {
+ blink::mojom::BlobPtr blob;
+ storage::BlobImpl::Create(std::move(blob_data_handle),
+ MakeRequest(&blob));
+ blob_handle = base::MakeRefCounted<storage::BlobHandle>(std::move(blob));
+ }
+
std::unique_ptr<std::vector<GURL>> url_list =
- base::MakeUnique<std::vector<GURL>>();
+ std::make_unique<std::vector<GURL>>();
url_list->push_back(request.url);
ServiceWorkerResponse response(
std::move(url_list), status_code, "OK", response_type,
- base::MakeUnique<ServiceWorkerHeaderMap>(response_headers),
- blob_handle->uuid(), request.url.spec().size(), nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown, base::Time(),
+ std::make_unique<ServiceWorkerHeaderMap>(response_headers), blob_uuid,
+ request.url.spec().size(), blob_handle,
+ blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time(),
false /* is_in_cache_storage */,
std::string() /* cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */);
CacheStorageBatchOperation operation;
@@ -431,10 +445,11 @@ class CacheStorageManagerTest : public testing::Test {
cache->BatchOperation(
std::vector<CacheStorageBatchOperation>(1, operation),
base::BindOnce(&CacheStorageManagerTest::CachePutCallback,
- base::Unretained(this), base::Unretained(&loop)));
+ base::Unretained(this), base::Unretained(&loop)),
+ CacheStorageCache::BadMessageCallback());
loop.Run();
- return callback_error_ == CACHE_STORAGE_OK;
+ return callback_error_ == CacheStorageError::kSuccess;
}
bool CacheDelete(CacheStorageCache* cache, const GURL& url) {
@@ -451,10 +466,11 @@ class CacheStorageManagerTest : public testing::Test {
cache->BatchOperation(
std::vector<CacheStorageBatchOperation>(1, operation),
base::BindOnce(&CacheStorageManagerTest::CacheDeleteCallback,
- base::Unretained(this), base::Unretained(&loop)));
+ base::Unretained(this), base::Unretained(&loop)),
+ CacheStorageCache::BadMessageCallback());
loop.Run();
- return callback_error_ == CACHE_STORAGE_OK;
+ return callback_error_ == CacheStorageError::kSuccess;
}
bool CacheMatch(CacheStorageCache* cache, const GURL& url) {
@@ -468,7 +484,7 @@ class CacheStorageManagerTest : public testing::Test {
base::Unretained(this), base::Unretained(&loop)));
loop.Run();
- return callback_error_ == CACHE_STORAGE_OK;
+ return callback_error_ == CacheStorageError::kSuccess;
}
CacheStorage* CacheStorageForOrigin(const GURL& origin) {
@@ -560,7 +576,7 @@ class CacheStorageManagerTest : public testing::Test {
scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
std::unique_ptr<CacheStorageManager> cache_manager_;
- std::unique_ptr<CacheStorageCacheHandle> callback_cache_handle_;
+ CacheStorageCacheHandle callback_cache_handle_;
int callback_bool_;
CacheStorageError callback_error_;
std::unique_ptr<ServiceWorkerResponse> callback_cache_handle_response_;
@@ -603,26 +619,23 @@ TEST_P(CacheStorageManagerTestP, OpenTwoCaches) {
TEST_P(CacheStorageManagerTestP, CachePointersDiffer) {
EXPECT_TRUE(Open(origin1_, "foo"));
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
EXPECT_TRUE(Open(origin1_, "bar"));
- EXPECT_NE(callback_cache_handle_->value(), cache_handle->value());
+ EXPECT_NE(callback_cache_handle_.value(), cache_handle.value());
}
TEST_P(CacheStorageManagerTestP, Open2CachesSameNameDiffOrigins) {
EXPECT_TRUE(Open(origin1_, "foo"));
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
EXPECT_TRUE(Open(origin2_, "foo"));
- EXPECT_NE(cache_handle->value(), callback_cache_handle_->value());
+ EXPECT_NE(cache_handle.value(), callback_cache_handle_.value());
}
TEST_P(CacheStorageManagerTestP, OpenExistingCache) {
EXPECT_TRUE(Open(origin1_, "foo"));
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_EQ(callback_cache_handle_->value(), cache_handle->value());
+ EXPECT_EQ(callback_cache_handle_.value(), cache_handle.value());
}
TEST_P(CacheStorageManagerTestP, HasCache) {
@@ -645,13 +658,13 @@ TEST_P(CacheStorageManagerTestP, DeleteTwice) {
EXPECT_TRUE(Open(origin1_, "foo"));
EXPECT_TRUE(Delete(origin1_, "foo"));
EXPECT_FALSE(Delete(origin1_, "foo"));
- EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorNotFound, callback_error_);
}
TEST_P(CacheStorageManagerTestP, DeleteCacheReducesOriginSize) {
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
// The quota manager gets updated after the put operation runs its callback so
// run the event loop.
base::RunLoop().RunUntilIdle();
@@ -660,7 +673,7 @@ TEST_P(CacheStorageManagerTestP, DeleteCacheReducesOriginSize) {
EXPECT_TRUE(Delete(origin1_, "foo"));
// Drop the cache handle so that the cache can be erased from disk.
- callback_cache_handle_ = nullptr;
+ callback_cache_handle_ = CacheStorageCacheHandle();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(-1 * quota_manager_proxy_->last_notified_delta(), put_delta);
@@ -694,45 +707,45 @@ TEST_P(CacheStorageManagerTestP, DeletedKeysGone) {
TEST_P(CacheStorageManagerTestP, StorageMatchEntryExists) {
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_TRUE(StorageMatch(origin1_, "foo", GURL("http://example.com/foo")));
}
TEST_P(CacheStorageManagerTestP, StorageMatchNoEntry) {
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_FALSE(StorageMatch(origin1_, "foo", GURL("http://example.com/bar")));
- EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorNotFound, callback_error_);
}
TEST_P(CacheStorageManagerTestP, StorageMatchNoCache) {
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_FALSE(StorageMatch(origin1_, "bar", GURL("http://example.com/foo")));
- EXPECT_EQ(CACHE_STORAGE_ERROR_CACHE_NAME_NOT_FOUND, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorCacheNameNotFound, callback_error_);
}
TEST_P(CacheStorageManagerTestP, StorageMatchAllEntryExists) {
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
}
TEST_P(CacheStorageManagerTestP, StorageMatchAllNoEntry) {
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_FALSE(StorageMatchAll(origin1_, GURL("http://example.com/bar")));
- EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorNotFound, callback_error_);
}
TEST_P(CacheStorageManagerTestP, StorageMatchAllNoCaches) {
EXPECT_FALSE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
- EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND, callback_error_);
+ EXPECT_EQ(CacheStorageError::kErrorNotFound, callback_error_);
}
TEST_F(CacheStorageManagerTest, StorageReuseCacheName) {
@@ -740,8 +753,8 @@ TEST_F(CacheStorageManagerTest, StorageReuseCacheName) {
// with the same URL should work. (see crbug.com/542668)
const GURL kTestURL = GURL("http://example.com/foo");
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(), kTestURL));
- EXPECT_TRUE(CacheMatch(callback_cache_handle_->value(), kTestURL));
+ EXPECT_TRUE(CachePut(callback_cache_handle_.value(), kTestURL));
+ EXPECT_TRUE(CacheMatch(callback_cache_handle_.value(), kTestURL));
std::unique_ptr<storage::BlobDataHandle> data_handle =
std::move(callback_data_handle_);
@@ -749,7 +762,7 @@ TEST_F(CacheStorageManagerTest, StorageReuseCacheName) {
// The cache is deleted but the handle to one of its entries is still
// open. Creating a new cache in the same directory would fail on Windows.
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(), kTestURL));
+ EXPECT_TRUE(CachePut(callback_cache_handle_.value(), kTestURL));
}
TEST_P(CacheStorageManagerTestP, DropRefAfterNewCacheWithSameNameCreated) {
@@ -759,8 +772,7 @@ TEST_P(CacheStorageManagerTestP, DropRefAfterNewCacheWithSameNameCreated) {
// 1. Create cache A and hang onto the handle
const GURL kTestURL = GURL("http://example.com/foo");
EXPECT_TRUE(Open(origin1_, "foo"));
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
// 2. Doom the cache
EXPECT_TRUE(Delete(origin1_, "foo"));
@@ -769,10 +781,10 @@ TEST_P(CacheStorageManagerTestP, DropRefAfterNewCacheWithSameNameCreated) {
EXPECT_TRUE(Open(origin1_, "foo"));
// 4. Drop handle to A
- cache_handle.reset();
+ cache_handle = CacheStorageCacheHandle();
// 5. Verify that B still works
- EXPECT_FALSE(CacheMatch(callback_cache_handle_->value(), kTestURL));
+ EXPECT_FALSE(CacheMatch(callback_cache_handle_.value(), kTestURL));
}
TEST_P(CacheStorageManagerTestP, DeleteCorrectDirectory) {
@@ -780,8 +792,7 @@ TEST_P(CacheStorageManagerTestP, DeleteCorrectDirectory) {
// 1. Cache A with name "foo" is created
const GURL kTestURL = GURL("http://example.com/foo");
EXPECT_TRUE(Open(origin1_, "foo"));
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
// 2. Cache A is doomed, but js hangs onto the handle.
EXPECT_TRUE(Delete(origin1_, "foo"));
@@ -791,14 +802,13 @@ TEST_P(CacheStorageManagerTestP, DeleteCorrectDirectory) {
// 4. Cache B is doomed, and both handles are reset.
EXPECT_TRUE(Delete(origin1_, "foo"));
- cache_handle.reset();
- callback_cache_handle_.reset();
+ cache_handle = CacheStorageCacheHandle();
// Do some busy work on a different cache to move the cache pool threads
// along and trigger the bug.
EXPECT_TRUE(Open(origin1_, "bar"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(), kTestURL));
- EXPECT_TRUE(CacheMatch(callback_cache_handle_->value(), kTestURL));
+ EXPECT_TRUE(CachePut(callback_cache_handle_.value(), kTestURL));
+ EXPECT_TRUE(CacheMatch(callback_cache_handle_.value(), kTestURL));
}
TEST_P(CacheStorageManagerTestP, StorageMatchAllEntryExistsTwice) {
@@ -806,10 +816,10 @@ TEST_P(CacheStorageManagerTestP, StorageMatchAllEntryExistsTwice) {
ServiceWorkerFetchRequest request;
request.url = GURL("http://example.com/foo");
EXPECT_TRUE(
- CachePutWithStatusCode(callback_cache_handle_->value(), request, 200));
+ CachePutWithStatusCode(callback_cache_handle_.value(), request, 200));
EXPECT_TRUE(Open(origin1_, "bar"));
EXPECT_TRUE(
- CachePutWithStatusCode(callback_cache_handle_->value(), request, 201));
+ CachePutWithStatusCode(callback_cache_handle_.value(), request, 201));
EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
@@ -821,8 +831,8 @@ TEST_P(CacheStorageManagerTestP, StorageMatchAllEntryExistsTwice) {
TEST_P(CacheStorageManagerTestP, StorageMatchInOneOfMany) {
EXPECT_TRUE(Open(origin1_, "foo"));
EXPECT_TRUE(Open(origin1_, "bar"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_TRUE(Open(origin1_, "baz"));
EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
@@ -830,20 +840,18 @@ TEST_P(CacheStorageManagerTestP, StorageMatchInOneOfMany) {
TEST_P(CacheStorageManagerTestP, Chinese) {
EXPECT_TRUE(Open(origin1_, "你好"));
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
EXPECT_TRUE(Open(origin1_, "你好"));
- EXPECT_EQ(callback_cache_handle_->value(), cache_handle->value());
+ EXPECT_EQ(callback_cache_handle_.value(), cache_handle.value());
EXPECT_EQ(1u, Keys(origin1_));
EXPECT_STREQ("你好", GetFirstIndexName().c_str());
}
TEST_F(CacheStorageManagerTest, EmptyKey) {
EXPECT_TRUE(Open(origin1_, ""));
- std::unique_ptr<CacheStorageCacheHandle> cache_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
EXPECT_TRUE(Open(origin1_, ""));
- EXPECT_EQ(cache_handle->value(), callback_cache_handle_->value());
+ EXPECT_EQ(cache_handle.value(), callback_cache_handle_.value());
EXPECT_EQ(1u, Keys(origin1_));
EXPECT_STREQ("", GetFirstIndexName().c_str());
EXPECT_TRUE(Has(origin1_, ""));
@@ -897,13 +905,13 @@ TEST_F(CacheStorageManagerTest, BadOriginName) {
TEST_F(CacheStorageManagerTest, DropReference) {
EXPECT_TRUE(Open(origin1_, "foo"));
base::WeakPtr<CacheStorageCache> cache =
- callback_cache_handle_->value()->AsWeakPtr();
+ callback_cache_handle_.value()->AsWeakPtr();
// Run a cache operation to ensure that the cache has finished initializing so
// that when the handle is dropped it can close immediately.
- EXPECT_FALSE(CacheMatch(callback_cache_handle_->value(),
+ EXPECT_FALSE(CacheMatch(callback_cache_handle_.value(),
GURL("http://example.com/foo")));
- callback_cache_handle_ = nullptr;
+ callback_cache_handle_ = CacheStorageCacheHandle();
EXPECT_FALSE(cache);
}
@@ -914,15 +922,14 @@ TEST_P(CacheStorageManagerTestP, CacheWorksAfterDelete) {
const GURL kBarURL("http://example.com/bar");
const GURL kBazURL("http://example.com/baz");
EXPECT_TRUE(Open(origin1_, "foo"));
- std::unique_ptr<CacheStorageCacheHandle> original_handle =
- std::move(callback_cache_handle_);
- EXPECT_TRUE(CachePut(original_handle->value(), kFooURL));
+ CacheStorageCacheHandle original_handle = std::move(callback_cache_handle_);
+ EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
EXPECT_TRUE(Delete(origin1_, "foo"));
// Verify that the existing cache handle still works.
- EXPECT_TRUE(CacheMatch(original_handle->value(), kFooURL));
- EXPECT_TRUE(CachePut(original_handle->value(), kBarURL));
- EXPECT_TRUE(CacheMatch(original_handle->value(), kBarURL));
+ EXPECT_TRUE(CacheMatch(original_handle.value(), kFooURL));
+ EXPECT_TRUE(CachePut(original_handle.value(), kBarURL));
+ EXPECT_TRUE(CacheMatch(original_handle.value(), kBarURL));
// The cache shouldn't be visible to subsequent storage operations.
EXPECT_EQ(0u, Keys(origin1_));
@@ -930,17 +937,16 @@ TEST_P(CacheStorageManagerTestP, CacheWorksAfterDelete) {
// Open a new cache with the same name, it should create a new cache, but not
// interfere with the original cache.
EXPECT_TRUE(Open(origin1_, "foo"));
- std::unique_ptr<CacheStorageCacheHandle> new_handle =
- std::move(callback_cache_handle_);
- EXPECT_TRUE(CachePut(new_handle->value(), kBazURL));
+ CacheStorageCacheHandle new_handle = std::move(callback_cache_handle_);
+ EXPECT_TRUE(CachePut(new_handle.value(), kBazURL));
- EXPECT_FALSE(CacheMatch(new_handle->value(), kFooURL));
- EXPECT_FALSE(CacheMatch(new_handle->value(), kBarURL));
- EXPECT_TRUE(CacheMatch(new_handle->value(), kBazURL));
+ EXPECT_FALSE(CacheMatch(new_handle.value(), kFooURL));
+ EXPECT_FALSE(CacheMatch(new_handle.value(), kBarURL));
+ EXPECT_TRUE(CacheMatch(new_handle.value(), kBazURL));
- EXPECT_TRUE(CacheMatch(original_handle->value(), kFooURL));
- EXPECT_TRUE(CacheMatch(original_handle->value(), kBarURL));
- EXPECT_FALSE(CacheMatch(original_handle->value(), kBazURL));
+ EXPECT_TRUE(CacheMatch(original_handle.value(), kFooURL));
+ EXPECT_TRUE(CacheMatch(original_handle.value(), kBarURL));
+ EXPECT_FALSE(CacheMatch(original_handle.value(), kBazURL));
}
// Deleted caches can still be modified, but all changes will eventually be
@@ -953,23 +959,23 @@ TEST_F(CacheStorageManagerTest, DeletedCacheIgnoredInIndex) {
EXPECT_TRUE(Open(origin1_, kCacheName));
auto original_handle = std::move(callback_cache_handle_);
- EXPECT_TRUE(CachePut(original_handle->value(), kFooURL));
+ EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
EXPECT_TRUE(Delete(origin1_, kCacheName));
// Now a second cache using the same name, but with different data.
EXPECT_TRUE(Open(origin1_, kCacheName));
auto new_handle = std::move(callback_cache_handle_);
- EXPECT_TRUE(CachePut(new_handle->value(), kFooURL));
- EXPECT_TRUE(CachePut(new_handle->value(), kBarURL));
- EXPECT_TRUE(CachePut(new_handle->value(), kBazURL));
+ EXPECT_TRUE(CachePut(new_handle.value(), kFooURL));
+ EXPECT_TRUE(CachePut(new_handle.value(), kBarURL));
+ EXPECT_TRUE(CachePut(new_handle.value(), kBazURL));
auto new_cache_size = Size(origin1_);
// Now modify the first cache.
- EXPECT_TRUE(CachePut(original_handle->value(), kBarURL));
+ EXPECT_TRUE(CachePut(original_handle.value(), kBarURL));
// Now deref both caches, and recreate the storage manager.
- original_handle = nullptr;
- new_handle = nullptr;
+ original_handle = CacheStorageCacheHandle();
+ new_handle = CacheStorageCacheHandle();
EXPECT_TRUE(FlushCacheStorageIndex(origin1_));
DestroyStorageManager();
CreateStorageManager();
@@ -986,15 +992,15 @@ TEST_F(CacheStorageManagerTest, TestErrorInitializingCache) {
EXPECT_TRUE(Open(origin1_, kCacheName));
auto original_handle = std::move(callback_cache_handle_);
- EXPECT_TRUE(CachePut(original_handle->value(), kFooURL));
+ EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
auto size_before_close = Size(origin1_);
EXPECT_GT(size_before_close, 0);
CacheStorage* cache_storage = CacheStorageForOrigin(origin1_);
auto cache_handle = cache_storage->GetLoadedCache(kCacheName);
- CacheStorageCache* cache = cache_handle->value();
+ CacheStorageCache* cache = cache_handle.value();
base::FilePath index_path = cache->path().AppendASCII("index");
- cache_handle.reset();
+ cache_handle = CacheStorageCacheHandle();
DestroyStorageManager();
@@ -1014,7 +1020,7 @@ TEST_F(CacheStorageManagerTest, CacheSizeCorrectAfterReopen) {
EXPECT_TRUE(Open(origin1_, kCacheName));
auto original_handle = std::move(callback_cache_handle_);
- EXPECT_TRUE(CachePut(original_handle->value(), kFooURL));
+ EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
auto size_before_close = Size(origin1_);
EXPECT_GT(size_before_close, 0);
@@ -1034,8 +1040,7 @@ TEST_F(CacheStorageManagerTest, CacheSizePaddedAfterReopen) {
EXPECT_EQ(0, quota_manager_proxy_->notify_storage_modified_count());
EXPECT_TRUE(Open(origin1_, kCacheName));
- std::unique_ptr<CacheStorageCacheHandle> original_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle original_handle = std::move(callback_cache_handle_);
base::RunLoop().RunUntilIdle();
put_delta += quota_manager_proxy_->last_notified_delta();
@@ -1043,10 +1048,10 @@ TEST_F(CacheStorageManagerTest, CacheSizePaddedAfterReopen) {
EXPECT_EQ(0, quota_manager_proxy_->notify_storage_modified_count());
EXPECT_TRUE(
- CachePut(original_handle->value(), kFooURL, FetchResponseType::kOpaque));
+ CachePut(original_handle.value(), kFooURL, FetchResponseType::kOpaque));
int64_t cache_size_before_close = Size(origin1_);
- base::FilePath storage_dir = original_handle->value()->path().DirName();
- original_handle = nullptr;
+ base::FilePath storage_dir = original_handle.value()->path().DirName();
+ original_handle = CacheStorageCacheHandle();
EXPECT_GT(cache_size_before_close, 0);
base::RunLoop().RunUntilIdle();
@@ -1082,11 +1087,10 @@ TEST_F(CacheStorageManagerTest, PersistedCacheKeyUsed) {
const std::string kCacheName = "foo";
EXPECT_TRUE(Open(origin1_, kCacheName));
- std::unique_ptr<CacheStorageCacheHandle> original_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle original_handle = std::move(callback_cache_handle_);
EXPECT_TRUE(
- CachePut(original_handle->value(), kFooURL, FetchResponseType::kOpaque));
+ CachePut(original_handle.value(), kFooURL, FetchResponseType::kOpaque));
int64_t cache_size_after_put = Size(origin1_);
EXPECT_LT(0, cache_size_after_put);
@@ -1118,10 +1122,9 @@ TEST_F(CacheStorageManagerTest, PersistedCacheKeyUsed) {
// Now put the exact same resource back into the cache. This time we expect to
// see a different size as the padding is calculated with a different key.
- std::unique_ptr<CacheStorageCacheHandle> new_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle new_handle = std::move(callback_cache_handle_);
EXPECT_TRUE(
- CachePut(new_handle->value(), kFooURL, FetchResponseType::kOpaque));
+ CachePut(new_handle.value(), kFooURL, FetchResponseType::kOpaque));
EXPECT_NE(cache_size_after_put, Size(origin1_));
}
@@ -1131,8 +1134,8 @@ TEST_F(CacheStorageManagerTest, PersistedCacheKeyUsed) {
TEST_F(CacheStorageManagerMemoryOnlyTest, MemoryLosesReferenceOnlyAfterDelete) {
EXPECT_TRUE(Open(origin1_, "foo"));
base::WeakPtr<CacheStorageCache> cache =
- callback_cache_handle_->value()->AsWeakPtr();
- callback_cache_handle_ = nullptr;
+ callback_cache_handle_.value()->AsWeakPtr();
+ callback_cache_handle_ = CacheStorageCacheHandle();
EXPECT_TRUE(cache);
EXPECT_TRUE(Delete(origin1_, "foo"));
base::RunLoop().RunUntilIdle();
@@ -1142,7 +1145,7 @@ TEST_F(CacheStorageManagerMemoryOnlyTest, MemoryLosesReferenceOnlyAfterDelete) {
TEST_P(CacheStorageManagerTestP, DeleteBeforeRelease) {
EXPECT_TRUE(Open(origin1_, "foo"));
EXPECT_TRUE(Delete(origin1_, "foo"));
- EXPECT_TRUE(callback_cache_handle_->value());
+ EXPECT_TRUE(callback_cache_handle_.value());
}
TEST_P(CacheStorageManagerTestP, OpenRunsSerially) {
@@ -1157,27 +1160,27 @@ TEST_P(CacheStorageManagerTestP, OpenRunsSerially) {
base::Unretained(this), base::Unretained(&open_loop)));
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(callback_cache_handle_);
+ EXPECT_FALSE(callback_cache_handle_.value());
cache_storage->CompleteAsyncOperationForTesting();
open_loop.Run();
- EXPECT_TRUE(callback_cache_handle_);
+ EXPECT_TRUE(callback_cache_handle_.value());
}
TEST_P(CacheStorageManagerTestP, GetOriginUsage) {
EXPECT_EQ(0, GetOriginUsage(origin1_));
EXPECT_TRUE(Open(origin1_, "foo"));
EXPECT_EQ(0, GetOriginUsage(origin1_));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
int64_t foo_size = GetOriginUsage(origin1_);
EXPECT_LT(0, GetOriginUsage(origin1_));
EXPECT_EQ(0, GetOriginUsage(origin2_));
// Add the same entry into a second cache, the size should double.
EXPECT_TRUE(Open(origin1_, "bar"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_EQ(2 * foo_size, GetOriginUsage(origin1_));
}
@@ -1185,15 +1188,15 @@ TEST_P(CacheStorageManagerTestP, GetAllOriginsUsage) {
EXPECT_EQ(0ULL, GetAllOriginsUsage().size());
// Put one entry in a cache on origin 1.
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
// Put two entries (of identical size) in a cache on origin 2.
EXPECT_TRUE(Open(origin2_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/bar")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/bar")));
std::vector<CacheStorageUsageInfo> usage = GetAllOriginsUsage();
EXPECT_EQ(2ULL, usage.size());
@@ -1220,13 +1223,12 @@ TEST_F(CacheStorageManagerTest, GetAllOriginsUsageWithOldIndex) {
const GURL kFooURL = origin1_.Resolve("foo");
const std::string kCacheName = "foo";
EXPECT_TRUE(Open(origin1_, kCacheName));
- std::unique_ptr<CacheStorageCacheHandle> original_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle original_handle = std::move(callback_cache_handle_);
- EXPECT_TRUE(CachePut(original_handle->value(), kFooURL));
+ EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
int64_t cache_size_v1 = Size(origin1_);
- base::FilePath storage_dir = original_handle->value()->path().DirName();
- original_handle = nullptr;
+ base::FilePath storage_dir = original_handle.value()->path().DirName();
+ original_handle = CacheStorageCacheHandle();
EXPECT_GE(cache_size_v1, 0);
// Close the caches and cache manager.
@@ -1249,8 +1251,8 @@ TEST_F(CacheStorageManagerTest, GetAllOriginsUsageWithOldIndex) {
EXPECT_TRUE(Open(origin1_, kCacheName));
original_handle = std::move(callback_cache_handle_);
const GURL kBarURL = origin1_.Resolve("bar");
- EXPECT_TRUE(CachePut(original_handle->value(), kBarURL));
- original_handle = nullptr;
+ EXPECT_TRUE(CachePut(original_handle.value(), kBarURL));
+ original_handle = CacheStorageCacheHandle();
std::vector<CacheStorageUsageInfo> usage = GetAllOriginsUsage();
ASSERT_EQ(1ULL, usage.size());
@@ -1282,13 +1284,12 @@ TEST_F(CacheStorageManagerTest, GetOriginSizeWithOldIndex) {
const GURL kFooURL = origin1_.Resolve("foo");
const std::string kCacheName = "foo";
EXPECT_TRUE(Open(origin1_, kCacheName));
- std::unique_ptr<CacheStorageCacheHandle> original_handle =
- std::move(callback_cache_handle_);
+ CacheStorageCacheHandle original_handle = std::move(callback_cache_handle_);
- EXPECT_TRUE(CachePut(original_handle->value(), kFooURL));
+ EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
int64_t cache_size_v1 = Size(origin1_);
- base::FilePath storage_dir = original_handle->value()->path().DirName();
- original_handle = nullptr;
+ base::FilePath storage_dir = original_handle.value()->path().DirName();
+ original_handle = CacheStorageCacheHandle();
EXPECT_GE(cache_size_v1, 0);
// Close the caches and cache manager.
@@ -1311,8 +1312,8 @@ TEST_F(CacheStorageManagerTest, GetOriginSizeWithOldIndex) {
EXPECT_TRUE(Open(origin1_, kCacheName));
original_handle = std::move(callback_cache_handle_);
const GURL kBarURL = origin1_.Resolve("bar");
- EXPECT_TRUE(CachePut(original_handle->value(), kBarURL));
- original_handle = nullptr;
+ EXPECT_TRUE(CachePut(original_handle.value(), kBarURL));
+ original_handle = CacheStorageCacheHandle();
int64_t cache_size_v2 = Size(origin1_);
EXPECT_GE(cache_size_v2, 0);
@@ -1336,27 +1337,49 @@ TEST_F(CacheStorageManagerTest, GetOriginSizeWithOldIndex) {
TEST_P(CacheStorageManagerTestP, GetSizeThenCloseAllCaches) {
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
+ EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
GURL("http://example.com/foo2")));
EXPECT_TRUE(Open(origin1_, "bar"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/bar")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/bar")));
int64_t origin_size = GetOriginUsage(origin1_);
EXPECT_LT(0, origin_size);
EXPECT_EQ(origin_size, GetSizeThenCloseAllCaches(origin1_));
- EXPECT_FALSE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/baz")));
+ EXPECT_FALSE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/baz")));
+}
+
+TEST_P(CacheStorageManagerTestP, GetSizeThenCloseAllCachesAfterDelete) {
+ // Tests that doomed caches are also deleted by GetSizeThenCloseAllCaches.
+ EXPECT_TRUE(Open(origin1_, "foo"));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
+
+ int64_t size_after_put = GetOriginUsage(origin1_);
+ EXPECT_LT(0, size_after_put);
+
+ // Keep a handle to a (soon-to-be deleted cache).
+ auto saved_cache_handle = callback_cache_handle_.Clone();
+
+ // Delete will only doom the cache because there is still at least one handle
+ // referencing an open cache.
+ EXPECT_TRUE(Delete(origin1_, "foo"));
+
+ // GetSizeThenCloseAllCaches should close the cache (which is then deleted)
+ // even though there is still an open handle.
+ EXPECT_EQ(size_after_put, GetSizeThenCloseAllCaches(origin1_));
+ EXPECT_EQ(0, GetOriginUsage(origin1_));
}
TEST_F(CacheStorageManagerTest, DeleteUnreferencedCacheDirectories) {
// Create a referenced cache.
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
// Create an unreferenced directory next to the referenced one.
base::FilePath origin_path = CacheStorageManager::ConstructOriginPath(
@@ -1372,7 +1395,7 @@ TEST_F(CacheStorageManagerTest, DeleteUnreferencedCacheDirectories) {
// Verify that the referenced cache still works.
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CacheMatch(callback_cache_handle_->value(),
+ EXPECT_TRUE(CacheMatch(callback_cache_handle_.value(),
GURL("http://example.com/foo")));
// Verify that the unreferenced cache is gone.
@@ -1436,8 +1459,8 @@ TEST_P(CacheStorageManagerTestP, NotifyCacheListChanged_Created) {
EXPECT_EQ(0, observer.notify_list_changed_count);
EXPECT_TRUE(Open(origin1_, "foo"));
EXPECT_EQ(1, observer.notify_list_changed_count);
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_EQ(1, observer.notify_list_changed_count);
}
@@ -1474,12 +1497,12 @@ TEST_P(CacheStorageManagerTestP, NotifyCacheContentChanged_PutEntry) {
EXPECT_EQ(0, observer.notify_content_changed_count);
EXPECT_TRUE(Open(origin1_, "foo"));
EXPECT_EQ(0, observer.notify_content_changed_count);
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_EQ(1, observer.notify_content_changed_count);
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
+ EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
GURL("http://example.com/foo1")));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
+ EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
GURL("http://example.com/foo2")));
EXPECT_EQ(3, observer.notify_content_changed_count);
}
@@ -1493,13 +1516,13 @@ TEST_P(CacheStorageManagerTestP, NotifyCacheContentChanged_DeleteEntry) {
EXPECT_EQ(0, observer.notify_content_changed_count);
EXPECT_TRUE(Open(origin1_, "foo"));
EXPECT_EQ(0, observer.notify_content_changed_count);
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_EQ(1, observer.notify_content_changed_count);
- EXPECT_TRUE(CacheDelete(callback_cache_handle_->value(),
+ EXPECT_TRUE(CacheDelete(callback_cache_handle_.value(),
GURL("http://example.com/foo")));
EXPECT_EQ(2, observer.notify_content_changed_count);
- EXPECT_FALSE(CacheDelete(callback_cache_handle_->value(),
+ EXPECT_FALSE(CacheDelete(callback_cache_handle_.value(),
GURL("http://example.com/foo")));
EXPECT_EQ(2, observer.notify_content_changed_count);
}
@@ -1511,23 +1534,23 @@ TEST_P(CacheStorageManagerTestP, NotifyCacheContentChanged_DeleteThenPutEntry) {
EXPECT_EQ(0, observer.notify_content_changed_count);
EXPECT_TRUE(Open(origin1_, "foo"));
EXPECT_EQ(0, observer.notify_content_changed_count);
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_EQ(1, observer.notify_content_changed_count);
- EXPECT_TRUE(CacheDelete(callback_cache_handle_->value(),
+ EXPECT_TRUE(CacheDelete(callback_cache_handle_.value(),
GURL("http://example.com/foo")));
EXPECT_EQ(2, observer.notify_content_changed_count);
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_EQ(3, observer.notify_content_changed_count);
- EXPECT_TRUE(CacheDelete(callback_cache_handle_->value(),
+ EXPECT_TRUE(CacheDelete(callback_cache_handle_.value(),
GURL("http://example.com/foo")));
EXPECT_EQ(4, observer.notify_content_changed_count);
}
TEST_P(CacheStorageManagerTestP, StorageMatch_IgnoreSearch) {
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
+ EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
GURL("http://example.com/foo?bar")));
EXPECT_FALSE(StorageMatch(origin1_, "foo", GURL("http://example.com/foo")));
@@ -1541,7 +1564,7 @@ TEST_P(CacheStorageManagerTestP, StorageMatch_IgnoreSearch) {
TEST_P(CacheStorageManagerTestP, StorageMatch_IgnoreMethod) {
GURL url = GURL("http://example.com/foo");
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(), url));
+ EXPECT_TRUE(CachePut(callback_cache_handle_.value(), url));
ServiceWorkerFetchRequest post_request;
post_request.url = url;
@@ -1565,7 +1588,7 @@ TEST_P(CacheStorageManagerTestP, StorageMatch_IgnoreVary) {
ServiceWorkerHeaderMap response_headers;
response_headers["vary"] = "vary_foo";
- EXPECT_TRUE(CachePutWithRequestAndHeaders(callback_cache_handle_->value(),
+ EXPECT_TRUE(CachePutWithRequestAndHeaders(callback_cache_handle_.value(),
request, response_headers));
EXPECT_TRUE(StorageMatchWithRequest(origin1_, "foo", request));
@@ -1579,7 +1602,7 @@ TEST_P(CacheStorageManagerTestP, StorageMatch_IgnoreVary) {
TEST_P(CacheStorageManagerTestP, StorageMatchAll_IgnoreSearch) {
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
+ EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
GURL("http://example.com/foo?bar")));
EXPECT_FALSE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
@@ -1593,7 +1616,7 @@ TEST_P(CacheStorageManagerTestP, StorageMatchAll_IgnoreSearch) {
TEST_P(CacheStorageManagerTestP, StorageMatchAll_IgnoreMethod) {
GURL url = GURL("http://example.com/foo");
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(), url));
+ EXPECT_TRUE(CachePut(callback_cache_handle_.value(), url));
ServiceWorkerFetchRequest post_request;
post_request.url = url;
@@ -1616,7 +1639,7 @@ TEST_P(CacheStorageManagerTestP, StorageMatchAll_IgnoreVary) {
ServiceWorkerHeaderMap response_headers;
response_headers["vary"] = "vary_foo";
- EXPECT_TRUE(CachePutWithRequestAndHeaders(callback_cache_handle_->value(),
+ EXPECT_TRUE(CachePutWithRequestAndHeaders(callback_cache_handle_.value(),
request, response_headers));
EXPECT_TRUE(StorageMatchAllWithRequest(origin1_, request));
@@ -1725,8 +1748,8 @@ TEST_P(CacheStorageQuotaClientTestP, QuotaID) {
TEST_P(CacheStorageQuotaClientTestP, QuotaGetOriginUsage) {
EXPECT_EQ(0, QuotaGetOriginUsage(origin1_));
EXPECT_TRUE(Open(origin1_, "foo"));
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_LT(0, QuotaGetOriginUsage(origin1_));
}
@@ -1755,8 +1778,8 @@ TEST_P(CacheStorageQuotaClientTestP, QuotaDeleteOriginData) {
EXPECT_EQ(0, QuotaGetOriginUsage(origin1_));
EXPECT_TRUE(Open(origin1_, "foo"));
// Call put to test that initialized caches are properly deleted too.
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
EXPECT_TRUE(Open(origin1_, "bar"));
EXPECT_TRUE(Open(origin2_, "baz"));
@@ -1780,12 +1803,12 @@ TEST_P(CacheStorageQuotaClientTestP, QuotaDeleteEmptyOrigin) {
TEST_F(CacheStorageQuotaClientDiskOnlyTest, QuotaDeleteUnloadedOriginData) {
EXPECT_TRUE(Open(origin1_, "foo"));
// Call put to test that initialized caches are properly deleted too.
- EXPECT_TRUE(CachePut(callback_cache_handle_->value(),
- GURL("http://example.com/foo")));
+ EXPECT_TRUE(
+ CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
// Close the cache backend so that it writes out its index to disk.
base::RunLoop run_loop;
- callback_cache_handle_->value()->Close(run_loop.QuitClosure());
+ callback_cache_handle_.value()->Close(run_loop.QuitClosure());
run_loop.Run();
// Create a new CacheStorageManager that hasn't yet loaded the origin.
diff --git a/chromium/content/browser/cache_storage/cache_storage_operation_unittest.cc b/chromium/content/browser/cache_storage/cache_storage_operation_unittest.cc
index efb9860fee6..792f324ba1a 100644
--- a/chromium/content/browser/cache_storage/cache_storage_operation_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_operation_unittest.cc
@@ -38,7 +38,7 @@ class CacheStorageOperationTest : public testing::Test {
protected:
CacheStorageOperationTest()
: mock_task_runner_(new base::TestMockTimeTaskRunner()) {
- operation_ = base::MakeUnique<CacheStorageOperation>(
+ operation_ = std::make_unique<CacheStorageOperation>(
base::BindOnce(&TestTask::Run, base::Unretained(&task_)),
CacheStorageSchedulerClient::CLIENT_STORAGE, mock_task_runner_);
}
diff --git a/chromium/content/browser/cache_storage/cache_storage_scheduler.cc b/chromium/content/browser/cache_storage/cache_storage_scheduler.cc
index 0ceb62983cc..759fd61c92b 100644
--- a/chromium/content/browser/cache_storage/cache_storage_scheduler.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_scheduler.cc
@@ -28,7 +28,7 @@ void CacheStorageScheduler::ScheduleOperation(base::OnceClosure closure) {
CACHE_STORAGE_SCHEDULER_UMA(COUNTS_10000, "QueueLength", client_type_,
pending_operations_.size());
- pending_operations_.push_back(base::MakeUnique<CacheStorageOperation>(
+ pending_operations_.push_back(std::make_unique<CacheStorageOperation>(
std::move(closure), client_type_, base::ThreadTaskRunnerHandle::Get()));
RunOperationIfIdle();
}
diff --git a/chromium/content/browser/child_process_launcher.cc b/chromium/content/browser/child_process_launcher.cc
index f6d984071cd..4e65368d28d 100644
--- a/chromium/content/browser/child_process_launcher.cc
+++ b/chromium/content/browser/child_process_launcher.cc
@@ -31,8 +31,6 @@ ChildProcessLauncher::ChildProcessLauncher(
termination_status_(base::TERMINATION_STATUS_NORMAL_TERMINATION),
exit_code_(RESULT_CODE_NORMAL_EXIT),
starting_(true),
- broker_client_invitation_(std::move(broker_client_invitation)),
- process_error_callback_(process_error_callback),
#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
defined(UNDEFINED_SANITIZER)
@@ -45,9 +43,9 @@ ChildProcessLauncher::ChildProcessLauncher(
CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_));
helper_ = new ChildProcessLauncherHelper(
- child_process_id, client_thread_id_,
- std::move(command_line), std::move(delegate),
- weak_factory_.GetWeakPtr(), terminate_on_shutdown);
+ child_process_id, client_thread_id_, std::move(command_line),
+ std::move(delegate), weak_factory_.GetWeakPtr(), terminate_on_shutdown,
+ std::move(broker_client_invitation), process_error_callback);
helper_->StartLaunchOnClientThread();
}
@@ -73,24 +71,12 @@ void ChildProcessLauncher::SetProcessPriority(
void ChildProcessLauncher::Notify(
ChildProcessLauncherHelper::Process process,
- mojo::edk::ScopedPlatformHandle server_handle,
int error_code) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
starting_ = false;
process_ = std::move(process);
- // Take ownership of the broker client invitation here so it's destroyed when
- // we go out of scope regardless of the outcome below.
- std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation> invitation =
- std::move(broker_client_invitation_);
if (process_.process.IsValid()) {
- // Set up Mojo IPC to the new process.
- DCHECK(invitation);
- invitation->Send(
- process_.process.Handle(),
- mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy,
- std::move(server_handle)),
- process_error_callback_);
client_->OnProcessLaunched();
} else {
termination_status_ = base::TERMINATION_STATUS_LAUNCH_FAILED;
@@ -134,8 +120,10 @@ base::TerminationStatus ChildProcessLauncher::GetChildTerminationStatus(
// However, if GetTerminationStatus didn't reap the child (because it was
// still running), we'll need to Terminate via ProcessWatcher. So we can't
// close the handle here.
- if (termination_status_ != base::TERMINATION_STATUS_STILL_RUNNING)
+ if (termination_status_ != base::TERMINATION_STATUS_STILL_RUNNING) {
+ process_.process.Exited(exit_code_);
process_.process.Close();
+ }
return termination_status_;
}
diff --git a/chromium/content/browser/child_process_launcher.h b/chromium/content/browser/child_process_launcher.h
index 34a83320d89..7763d0c2860 100644
--- a/chromium/content/browser/child_process_launcher.h
+++ b/chromium/content/browser/child_process_launcher.h
@@ -164,7 +164,6 @@ class CONTENT_EXPORT ChildProcessLauncher {
// Notifies the client about the result of the operation.
void Notify(internal::ChildProcessLauncherHelper::Process process,
- mojo::edk::ScopedPlatformHandle server_handle,
int error_code);
Client* client_;
@@ -177,9 +176,6 @@ class CONTENT_EXPORT ChildProcessLauncher {
base::TerminationStatus termination_status_;
int exit_code_;
bool starting_;
- std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
- broker_client_invitation_;
- const mojo::edk::ProcessErrorCallback process_error_callback_;
// Controls whether the child process should be terminated on browser
// shutdown. Default behavior is to terminate the child.
diff --git a/chromium/content/browser/child_process_launcher_helper.cc b/chromium/content/browser/child_process_launcher_helper.cc
index 7b5ce4eae65..d5471c5bceb 100644
--- a/chromium/content/browser/child_process_launcher_helper.cc
+++ b/chromium/content/browser/child_process_launcher_helper.cc
@@ -56,14 +56,18 @@ ChildProcessLauncherHelper::ChildProcessLauncherHelper(
std::unique_ptr<base::CommandLine> command_line,
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
const base::WeakPtr<ChildProcessLauncher>& child_process_launcher,
- bool terminate_on_shutdown)
+ bool terminate_on_shutdown,
+ std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
+ broker_client_invitation,
+ const mojo::edk::ProcessErrorCallback& process_error_callback)
: child_process_id_(child_process_id),
client_thread_id_(client_thread_id),
command_line_(std::move(command_line)),
delegate_(std::move(delegate)),
child_process_launcher_(child_process_launcher),
- terminate_on_shutdown_(terminate_on_shutdown) {
-}
+ terminate_on_shutdown_(terminate_on_shutdown),
+ broker_client_invitation_(std::move(broker_client_invitation)),
+ process_error_callback_(process_error_callback) {}
ChildProcessLauncherHelper::~ChildProcessLauncherHelper() {
}
@@ -96,14 +100,15 @@ void ChildProcessLauncherHelper::LaunchOnLauncherThread() {
bool is_synchronous_launch = true;
int launch_result = LAUNCH_RESULT_FAILURE;
base::LaunchOptions options;
- BeforeLaunchOnLauncherThread(*files_to_register, &options);
- Process process = LaunchProcessOnLauncherThread(options,
- std::move(files_to_register),
- &is_synchronous_launch,
- &launch_result);
+ Process process;
+ if (BeforeLaunchOnLauncherThread(*files_to_register, &options)) {
+ process =
+ LaunchProcessOnLauncherThread(options, std::move(files_to_register),
+ &is_synchronous_launch, &launch_result);
- AfterLaunchOnLauncherThread(process, options);
+ AfterLaunchOnLauncherThread(process, options);
+ }
if (is_synchronous_launch) {
PostLaunchOnLauncherThread(std::move(process), launch_result);
@@ -123,6 +128,20 @@ void ChildProcessLauncherHelper::PostLaunchOnLauncherThread(
begin_launch_time_);
}
+ // Take ownership of the broker client invitation here so it's destroyed when
+ // we go out of scope regardless of the outcome below.
+ std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation> invitation =
+ std::move(broker_client_invitation_);
+ if (process.process.IsValid()) {
+ // Set up Mojo IPC to the new process.
+ DCHECK(invitation);
+ invitation->Send(
+ process.process.Handle(),
+ mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy,
+ std::move(mojo_server_handle_)),
+ process_error_callback_);
+ }
+
BrowserThread::PostTask(
client_thread_id_, FROM_HERE,
base::BindOnce(&ChildProcessLauncherHelper::PostLaunchOnClientThread,
@@ -133,8 +152,7 @@ void ChildProcessLauncherHelper::PostLaunchOnClientThread(
ChildProcessLauncherHelper::Process process,
int error_code) {
if (child_process_launcher_) {
- child_process_launcher_->Notify(
- std::move(process), std::move(mojo_server_handle_), error_code);
+ child_process_launcher_->Notify(std::move(process), error_code);
} else if (process.process.IsValid() && terminate_on_shutdown_) {
// Client is gone, terminate the process.
ForceNormalProcessTerminationAsync(std::move(process));
diff --git a/chromium/content/browser/child_process_launcher_helper.h b/chromium/content/browser/child_process_launcher_helper.h
index d9dcc0a4f8a..deb6d686f45 100644
--- a/chromium/content/browser/child_process_launcher_helper.h
+++ b/chromium/content/browser/child_process_launcher_helper.h
@@ -15,6 +15,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/common/result_codes.h"
#include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/embedder/outgoing_broker_client_invitation.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "services/catalog/public/cpp/manifest_parsing_util.h"
@@ -86,7 +87,10 @@ class ChildProcessLauncherHelper :
std::unique_ptr<base::CommandLine> command_line,
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
const base::WeakPtr<ChildProcessLauncher>& child_process_launcher,
- bool terminate_on_shutdown);
+ bool terminate_on_shutdown,
+ std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
+ broker_client_invitation,
+ const mojo::edk::ProcessErrorCallback& process_error_callback);
// The methods below are defined in the order they are called.
@@ -104,8 +108,11 @@ class ChildProcessLauncherHelper :
// Platform specific.
std::unique_ptr<FileMappedForLaunch> GetFilesToMap();
- // Platform specific.
- void BeforeLaunchOnLauncherThread(
+ // Platform specific, returns success or failure. If failure is returned,
+ // LaunchOnLauncherThread will not call LaunchProcessOnLauncherThread and
+ // AfterLaunchOnLauncherThread, and the launch_result will be reported as
+ // LAUNCH_RESULT_FAILURE.
+ bool BeforeLaunchOnLauncherThread(
const FileMappedForLaunch& files_to_register,
base::LaunchOptions* options);
@@ -210,6 +217,9 @@ class ChildProcessLauncherHelper :
mojo::edk::ScopedPlatformHandle mojo_client_handle_;
mojo::edk::ScopedPlatformHandle mojo_server_handle_;
bool terminate_on_shutdown_;
+ std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
+ broker_client_invitation_;
+ const mojo::edk::ProcessErrorCallback process_error_callback_;
#if defined(OS_MACOSX)
std::unique_ptr<sandbox::SeatbeltExecClient> seatbelt_exec_client_;
diff --git a/chromium/content/browser/child_process_launcher_helper_android.cc b/chromium/content/browser/child_process_launcher_helper_android.cc
index d25fe75862f..345bc4ddcae 100644
--- a/chromium/content/browser/child_process_launcher_helper_android.cc
+++ b/chromium/content/browser/child_process_launcher_helper_android.cc
@@ -84,9 +84,11 @@ ChildProcessLauncherHelper::GetFilesToMap() {
return files_to_register;
}
-void ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
+bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
const PosixFileDescriptorInfo& files_to_register,
- base::LaunchOptions* options) {}
+ base::LaunchOptions* options) {
+ return true;
+}
ChildProcessLauncherHelper::Process
ChildProcessLauncherHelper::LaunchProcessOnLauncherThread(
diff --git a/chromium/content/browser/child_process_launcher_helper_fuchsia.cc b/chromium/content/browser/child_process_launcher_helper_fuchsia.cc
index 33acb2c17f0..6d5e6cacb3e 100644
--- a/chromium/content/browser/child_process_launcher_helper_fuchsia.cc
+++ b/chromium/content/browser/child_process_launcher_helper_fuchsia.cc
@@ -69,7 +69,7 @@ ChildProcessLauncherHelper::GetFilesToMap() {
return std::unique_ptr<FileMappedForLaunch>();
}
-void ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
+bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
const PosixFileDescriptorInfo& files_to_register,
base::LaunchOptions* options) {
DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
@@ -78,6 +78,8 @@ void ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
mojo_client_handle(), command_line(), &options->handles_to_transfer);
UpdateLaunchOptionsForSandbox(delegate_->GetSandboxType(), options);
+
+ return true;
}
ChildProcessLauncherHelper::Process
diff --git a/chromium/content/browser/child_process_launcher_helper_linux.cc b/chromium/content/browser/child_process_launcher_helper_linux.cc
index 99b8f8189cb..ffd7cc33cd2 100644
--- a/chromium/content/browser/child_process_launcher_helper_linux.cc
+++ b/chromium/content/browser/child_process_launcher_helper_linux.cc
@@ -10,14 +10,15 @@
#include "content/browser/sandbox_host_linux.h"
#include "content/browser/zygote_host/zygote_communication_linux.h"
#include "content/browser/zygote_host/zygote_host_impl_linux.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/zygote_handle_linux.h"
+#include "content/public/common/common_sandbox_support_linux.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "gpu/config/gpu_switches.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
namespace content {
namespace internal {
@@ -40,7 +41,7 @@ ChildProcessLauncherHelper::GetFilesToMap() {
GetProcessType(), command_line());
}
-void ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
+bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
const PosixFileDescriptorInfo& files_to_register,
base::LaunchOptions* options) {
// Convert FD mapping to FileHandleMappingVector
@@ -56,6 +57,8 @@ void ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
}
options->environ = delegate_->GetEnvironment();
+
+ return true;
}
ChildProcessLauncherHelper::Process
diff --git a/chromium/content/browser/child_process_launcher_helper_mac.cc b/chromium/content/browser/child_process_launcher_helper_mac.cc
index 6a3d8522a0a..f9eab476d3e 100644
--- a/chromium/content/browser/child_process_launcher_helper_mac.cc
+++ b/chromium/content/browser/child_process_launcher_helper_mac.cc
@@ -45,7 +45,7 @@ ChildProcessLauncherHelper::GetFilesToMap() {
command_line());
}
-void ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
+bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
const FileMappedForLaunch& files_to_register,
base::LaunchOptions* options) {
// Convert FD mapping to FileHandleMappingVector.
@@ -58,13 +58,21 @@ void ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
if (base::FeatureList::IsEnabled(features::kMacV2Sandbox) &&
GetProcessType() == switches::kRendererProcess && !no_sandbox) {
- seatbelt_exec_client_ = base::MakeUnique<sandbox::SeatbeltExecClient>();
+ // Disable os logging to com.apple.diagnosticd which is a performance
+ // problem.
+ options->environ.insert(std::make_pair("OS_ACTIVITY_MODE", "disable"));
+
+ seatbelt_exec_client_ = std::make_unique<sandbox::SeatbeltExecClient>();
seatbelt_exec_client_->SetProfile(
service_manager::kSeatbeltPolicyString_renderer_v2);
SetupRendererSandboxParameters(seatbelt_exec_client_.get());
int pipe = seatbelt_exec_client_->SendProfileAndGetFD();
+ if (pipe < 0) {
+ LOG(ERROR) << "pipe for sending sandbox profile is an invalid FD";
+ return false;
+ }
base::FilePath helper_executable;
CHECK(PathService::Get(content::CHILD_PROCESS_EXE, &helper_executable));
@@ -90,6 +98,8 @@ void ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
// Make sure the MachBroker is running, and inform it to expect a check-in
// from the new process.
broker->EnsureRunning();
+
+ return true;
}
ChildProcessLauncherHelper::Process
diff --git a/chromium/content/browser/child_process_launcher_helper_win.cc b/chromium/content/browser/child_process_launcher_helper_win.cc
index 59289019991..b9183469740 100644
--- a/chromium/content/browser/child_process_launcher_helper_win.cc
+++ b/chromium/content/browser/child_process_launcher_helper_win.cc
@@ -10,7 +10,6 @@
#include "base/win/win_util.h"
#include "content/browser/child_process_launcher.h"
#include "content/browser/child_process_launcher_helper.h"
-#include "content/common/sandbox_win.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/sandbox_init.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
@@ -18,6 +17,7 @@
#include "mojo/edk/embedder/platform_channel_pair.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "sandbox/win/src/sandbox_types.h"
+#include "services/service_manager/sandbox/win/sandbox_win.h"
namespace content {
namespace internal {
@@ -43,10 +43,11 @@ ChildProcessLauncherHelper::GetFilesToMap() {
return std::unique_ptr<FileMappedForLaunch>();
}
-void ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
+bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
const FileMappedForLaunch& files_to_register,
base::LaunchOptions* options) {
DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
+ return true;
}
ChildProcessLauncherHelper::Process
diff --git a/chromium/content/browser/child_process_security_policy_impl.cc b/chromium/content/browser/child_process_security_policy_impl.cc
index 3af4399e9bf..cf8e191df89 100644
--- a/chromium/content/browser/child_process_security_policy_impl.cc
+++ b/chromium/content/browser/child_process_security_policy_impl.cc
@@ -83,7 +83,7 @@ bool IsMalformedBlobUrl(const GURL& url) {
// If the part after blob: survives a roundtrip through url::Origin, then
// it's a normal blob URL.
- std::string canonical_origin = url::Origin(url).Serialize();
+ std::string canonical_origin = url::Origin::Create(url).Serialize();
canonical_origin.append(1, '/');
if (base::StartsWith(url.GetContent(), canonical_origin,
base::CompareCase::INSENSITIVE_ASCII))
@@ -215,7 +215,7 @@ class ChildProcessSecurityPolicyImpl::SecurityState {
return true;
// Otherwise, check for permission for specific origin.
- if (CanCommitOrigin(url::Origin(url)))
+ if (CanCommitOrigin(url::Origin::Create(url)))
return true;
// file:// URLs are more granular. The child may have been given
@@ -656,7 +656,7 @@ bool ChildProcessSecurityPolicyImpl::CanRequestURL(
if (IsMalformedBlobUrl(url))
return false;
- url::Origin origin(url);
+ url::Origin origin = url::Origin::Create(url);
return origin.unique() || IsWebSafeScheme(origin.scheme()) ||
CanCommitURL(child_id, GURL(origin.Serialize()));
}
@@ -719,7 +719,7 @@ bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id,
if (IsMalformedBlobUrl(url))
return false;
- url::Origin origin(url);
+ url::Origin origin = url::Origin::Create(url);
return origin.unique() || CanCommitURL(child_id, GURL(origin.Serialize()));
}
@@ -1025,7 +1025,7 @@ void ChildProcessSecurityPolicyImpl::AddChild(int child_id) {
return;
}
- security_state_[child_id] = base::MakeUnique<SecurityState>();
+ security_state_[child_id] = std::make_unique<SecurityState>();
}
bool ChildProcessSecurityPolicyImpl::ChildProcessHasPermissionsForFile(
@@ -1045,7 +1045,7 @@ bool ChildProcessSecurityPolicyImpl::CanAccessDataForOrigin(int child_id,
// 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 = SiteInstanceImpl::GetSiteForURL(NULL, url);
+ GURL site_url = SiteInstanceImpl::GetSiteForURL(nullptr, url);
base::AutoLock lock(lock_);
SecurityStateMap::iterator state = security_state_.find(child_id);
@@ -1060,6 +1060,8 @@ bool ChildProcessSecurityPolicyImpl::CanAccessDataForOrigin(int child_id,
// keys that will help understand the circumstances of that kill.
base::debug::SetCrashKeyValue("requested_site_url", site_url.spec());
base::debug::SetCrashKeyValue("requested_origin", url.GetOrigin().spec());
+ base::debug::SetCrashKeyValue("killed_process_origin_lock",
+ state->second->origin_lock().spec());
}
return can_access;
}
@@ -1077,7 +1079,7 @@ bool ChildProcessSecurityPolicyImpl::HasSpecificPermissionForOrigin(
void ChildProcessSecurityPolicyImpl::LockToOrigin(int child_id,
const GURL& gurl) {
// "gurl" can be currently empty in some cases, such as file://blah.
- DCHECK(SiteInstanceImpl::GetSiteForURL(NULL, gurl) == gurl);
+ DCHECK(SiteInstanceImpl::GetSiteForURL(nullptr, gurl) == gurl);
base::AutoLock lock(lock_);
SecurityStateMap::iterator state = security_state_.find(child_id);
DCHECK(state != security_state_.end());
diff --git a/chromium/content/browser/child_process_security_policy_impl.h b/chromium/content/browser/child_process_security_policy_impl.h
index 9f522762eec..bdcdef28af4 100644
--- a/chromium/content/browser/child_process_security_policy_impl.h
+++ b/chromium/content/browser/child_process_security_policy_impl.h
@@ -92,6 +92,8 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
bool CanAccessDataForOrigin(int child_id, const GURL& url) override;
bool HasSpecificPermissionForOrigin(int child_id,
const url::Origin& origin) override;
+ bool GetMatchingIsolatedOrigin(const url::Origin& origin,
+ url::Origin* result) override;
// Returns if |child_id| can read all of the |files|.
bool CanReadAllFiles(int child_id, const std::vector<base::FilePath>& files);
@@ -246,26 +248,6 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// about port.
bool IsIsolatedOrigin(const url::Origin& origin);
- // This function will check whether |origin| requires process isolation, and
- // if so, it will return true and put the most specific matching isolated
- // origin into |result|.
- //
- // If |origin| does not require process isolation, this function will return
- // false, and |result| will be a unique origin. This means that neither
- // |origin|, nor any origins for which |origin| is a subdomain, have been
- // registered as isolated origins.
- //
- // For example, if both https://isolated.com/ and
- // https://bar.foo.isolated.com/ are registered as isolated origins, then the
- // values returned in |result| are:
- // https://isolated.com/ --> https://isolated.com/
- // https://foo.isolated.com/ --> https://isolated.com/
- // https://bar.foo.isolated.com/ --> https://bar.foo.isolated.com/
- // https://baz.bar.foo.isolated.com/ --> https://bar.foo.isolated.com/
- // https://unisolated.com/ --> (unique origin)
- bool GetMatchingIsolatedOrigin(const url::Origin& origin,
- url::Origin* result);
-
// Removes a previously added isolated origin, currently only used in tests.
//
// TODO(alexmos): Exposing this more generally will require extra care, such
diff --git a/chromium/content/browser/child_process_security_policy_unittest.cc b/chromium/content/browser/child_process_security_policy_unittest.cc
index 1cf98396e0d..cfcb80341f9 100644
--- a/chromium/content/browser/child_process_security_policy_unittest.cc
+++ b/chromium/content/browser/child_process_security_policy_unittest.cc
@@ -57,8 +57,7 @@ class ChildProcessSecurityPolicyTestBrowserClient
class ChildProcessSecurityPolicyTest : public testing::Test {
public:
- ChildProcessSecurityPolicyTest() : old_browser_client_(NULL) {
- }
+ ChildProcessSecurityPolicyTest() : old_browser_client_(nullptr) {}
void SetUp() override {
old_browser_client_ = SetBrowserClientForTesting(&test_browser_client_);
@@ -944,7 +943,7 @@ TEST_F(ChildProcessSecurityPolicyTest, OriginGranting) {
EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url_foo2));
EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url_bar));
- p->GrantOrigin(kRendererID, url::Origin(url_foo1));
+ p->GrantOrigin(kRendererID, url::Origin::Create(url_foo1));
EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo1));
EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo2));
diff --git a/chromium/content/browser/cocoa/system_hotkey_helper_mac.mm b/chromium/content/browser/cocoa/system_hotkey_helper_mac.mm
index 635a29dc9f7..258f0ff7b32 100644
--- a/chromium/content/browser/cocoa/system_hotkey_helper_mac.mm
+++ b/chromium/content/browser/cocoa/system_hotkey_helper_mac.mm
@@ -49,7 +49,7 @@ SystemHotkeyHelperMac::~SystemHotkeyHelperMac() {
}
void SystemHotkeyHelperMac::LoadSystemHotkeys() {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
std::string library_path(base::mac::GetUserLibraryPath().value());
NSString* expanded_file_path =
diff --git a/chromium/content/browser/compositor/OWNERS b/chromium/content/browser/compositor/OWNERS
index 06eeb6d16ce..50d7b2cf637 100644
--- a/chromium/content/browser/compositor/OWNERS
+++ b/chromium/content/browser/compositor/OWNERS
@@ -5,4 +5,6 @@ per-file *mus*=fsamuel@chromium.org
per-file *mus*=sadrul@chromium.org
per-file *mus*=rjkroege@chromium.org
+per-file *viz*=file://components/viz/OWNERS
+
# COMPONENT: Internals>Compositing
diff --git a/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc b/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc
index a5b47e38f42..a18042e14e1 100644
--- a/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc
@@ -29,7 +29,7 @@ GpuBrowserCompositorOutputSurface::GpuBrowserCompositorOutputSurface(
: BrowserCompositorOutputSurface(std::move(context),
update_vsync_parameters_callback,
std::move(overlay_candidate_validator)),
- weak_ptr_factory_(this) {
+ latency_info_cache_(this) {
if (capabilities_.uses_default_gl_framebuffer) {
capabilities_.flipped_output_surface =
context_provider()->ContextCapabilities().flips_vertically;
@@ -39,8 +39,14 @@ GpuBrowserCompositorOutputSurface::GpuBrowserCompositorOutputSurface(
}
GpuBrowserCompositorOutputSurface::~GpuBrowserCompositorOutputSurface() {
+ // Reset GetCommandBufferProxy() callbacks to avoid calling those callbacks
+ // from dtor of the base class.
+ GetCommandBufferProxy()->SetSwapBuffersCompletionCallback(
+ gpu::CommandBufferProxyImpl::SwapBuffersCompletionCallback());
GetCommandBufferProxy()->SetUpdateVSyncParametersCallback(
UpdateVSyncParametersCallback());
+ GetCommandBufferProxy()->SetPresentationCallback(
+ gpu::CommandBufferProxyImpl::PresentationCallback());
}
void GpuBrowserCompositorOutputSurface::SetNeedsVSync(bool needs_vsync) {
@@ -52,11 +58,15 @@ void GpuBrowserCompositorOutputSurface::SetNeedsVSync(bool needs_vsync) {
}
void GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result,
+ const gfx::SwapResponse& response,
const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) {
+ client_->DidReceiveSwapBuffersAck(response.swap_id);
+ latency_info_cache_.OnSwapBuffersCompleted(response);
+}
+
+void GpuBrowserCompositorOutputSurface::LatencyInfoCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info) {
RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(latency_info);
- client_->DidReceiveSwapBuffersAck();
}
void GpuBrowserCompositorOutputSurface::OnReflectorChanged() {
@@ -75,11 +85,16 @@ void GpuBrowserCompositorOutputSurface::BindToClient(
DCHECK(!client_);
client_ = client;
+ // CommandBufferProxy() will always call below callbacks directly (no
+ // PostTask), so it is safe to use base::Unretained(this).
GetCommandBufferProxy()->SetSwapBuffersCompletionCallback(
base::Bind(&GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted,
- weak_ptr_factory_.GetWeakPtr()));
+ base::Unretained(this)));
GetCommandBufferProxy()->SetUpdateVSyncParametersCallback(
update_vsync_parameters_callback_);
+ GetCommandBufferProxy()->SetPresentationCallback(
+ base::Bind(&GpuBrowserCompositorOutputSurface::OnPresentation,
+ base::Unretained(this)));
}
void GpuBrowserCompositorOutputSurface::EnsureBackbuffer() {}
@@ -107,7 +122,8 @@ void GpuBrowserCompositorOutputSurface::Reshape(
void GpuBrowserCompositorOutputSurface::SwapBuffers(
viz::OutputSurfaceFrame frame) {
- GetCommandBufferProxy()->AddLatencyInfo(frame.latency_info);
+ if (latency_info_cache_.WillSwap(std::move(frame.latency_info)))
+ GetCommandBufferProxy()->SetSnapshotRequested();
gfx::Size surface_size = frame.size;
if (reflector_) {
@@ -174,6 +190,13 @@ void GpuBrowserCompositorOutputSurface::SetDrawRectangle(
rect.x(), rect.y(), rect.width(), rect.height());
}
+void GpuBrowserCompositorOutputSurface::OnPresentation(
+ uint64_t swap_id,
+ const gfx::PresentationFeedback& feedback) {
+ DCHECK(client_);
+ client_->DidReceivePresentationFeedback(swap_id, feedback);
+}
+
gpu::CommandBufferProxyImpl*
GpuBrowserCompositorOutputSurface::GetCommandBufferProxy() {
ui::ContextProviderCommandBuffer* provider_command_buffer =
diff --git a/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h b/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h
index e075623986b..da2c17e2e9e 100644
--- a/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h
@@ -8,7 +8,6 @@
#include <memory>
#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
#include "content/browser/compositor/gpu_vsync_begin_frame_source.h"
@@ -18,6 +17,10 @@ namespace viz {
class CompositorOverlayCandidateValidator;
}
+namespace gfx {
+struct PresentationFeedback;
+}
+
namespace gpu {
class CommandBufferProxyImpl;
struct GpuProcessHostedCALayerTreeParamsMac;
@@ -25,7 +28,6 @@ struct GpuProcessHostedCALayerTreeParamsMac;
namespace ui {
class ContextProviderCommandBuffer;
-class LatencyInfo;
}
namespace content {
@@ -34,8 +36,10 @@ class ReflectorTexture;
// Adapts a WebGraphicsContext3DCommandBufferImpl into a
// viz::OutputSurface that also handles vsync parameter updates
// arriving from the GPU process.
-class GpuBrowserCompositorOutputSurface : public BrowserCompositorOutputSurface,
- public GpuVSyncControl {
+class GpuBrowserCompositorOutputSurface
+ : public BrowserCompositorOutputSurface,
+ public GpuVSyncControl,
+ public viz::OutputSurface::LatencyInfoCache::Client {
public:
GpuBrowserCompositorOutputSurface(
scoped_refptr<ui::ContextProviderCommandBuffer> context,
@@ -51,8 +55,7 @@ class GpuBrowserCompositorOutputSurface : public BrowserCompositorOutputSurface,
// TODO(ccameron): Remove |params_mac| when the CALayer tree is hosted in the
// browser process.
virtual void OnGpuSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result,
+ const gfx::SwapResponse& response,
const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac);
// BrowserCompositorOutputSurface implementation.
@@ -83,7 +86,13 @@ class GpuBrowserCompositorOutputSurface : public BrowserCompositorOutputSurface,
// GpuVSyncControl implementation.
void SetNeedsVSync(bool needs_vsync) override;
+ // OutputSurface::LatencyInfoCache::Client implementation.
+ void LatencyInfoCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info) override;
+
protected:
+ void OnPresentation(uint64_t swap_id,
+ const gfx::PresentationFeedback& feedback);
gpu::CommandBufferProxyImpl* GetCommandBufferProxy();
viz::OutputSurfaceClient* client_ = nullptr;
@@ -93,7 +102,7 @@ class GpuBrowserCompositorOutputSurface : public BrowserCompositorOutputSurface,
// True if the draw rectangle has been set at all since the last resize.
bool has_set_draw_rectangle_since_last_resize_ = false;
gfx::Size size_;
- base::WeakPtrFactory<GpuBrowserCompositorOutputSurface> weak_ptr_factory_;
+ LatencyInfoCache latency_info_cache_;
private:
DISALLOW_COPY_AND_ASSIGN(GpuBrowserCompositorOutputSurface);
diff --git a/chromium/content/browser/compositor/gpu_output_surface_mac.h b/chromium/content/browser/compositor/gpu_output_surface_mac.h
index 3ff7f20e87b..73f30b302f8 100644
--- a/chromium/content/browser/compositor/gpu_output_surface_mac.h
+++ b/chromium/content/browser/compositor/gpu_output_surface_mac.h
@@ -30,8 +30,7 @@ class GpuOutputSurfaceMac
// BrowserCompositorOutputSurface implementation.
void OnGpuSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result,
+ const gfx::SwapResponse& response,
const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) override;
void SetSurfaceSuspendedForRecycle(bool suspended) override;
diff --git a/chromium/content/browser/compositor/gpu_output_surface_mac.mm b/chromium/content/browser/compositor/gpu_output_surface_mac.mm
index 5a011ca5e98..67a86939c17 100644
--- a/chromium/content/browser/compositor/gpu_output_surface_mac.mm
+++ b/chromium/content/browser/compositor/gpu_output_surface_mac.mm
@@ -80,8 +80,7 @@ void GpuOutputSurfaceMac::SwapBuffers(viz::OutputSurfaceFrame frame) {
}
void GpuOutputSurfaceMac::OnGpuSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result,
+ const gfx::SwapResponse& response,
const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) {
remote_layers_->UpdateLayers(params_mac->ca_context_id,
params_mac->fullscreen_low_power_ca_context_id);
@@ -106,7 +105,7 @@ void GpuOutputSurfaceMac::OnGpuSwapBuffersCompleted(
}
client_->DidReceiveTextureInUseResponses(params_mac->responses);
GpuSurfacelessBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
- latency_info, result, params_mac);
+ response, params_mac);
}
void GpuOutputSurfaceMac::SetSurfaceSuspendedForRecycle(bool suspended) {
diff --git a/chromium/content/browser/compositor/gpu_process_transport_factory.cc b/chromium/content/browser/compositor/gpu_process_transport_factory.cc
index 45bf6b1b461..cddd17ca868 100644
--- a/chromium/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/chromium/content/browser/compositor/gpu_process_transport_factory.cc
@@ -30,7 +30,7 @@
#include "components/viz/host/renderer_settings_creation.h"
#include "components/viz/service/display/display.h"
#include "components/viz/service/display/display_scheduler.h"
-#include "components/viz/service/display/texture_mailbox_deleter.h"
+#include "components/viz/service/display_embedder/compositing_mode_reporter_impl.h"
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
@@ -44,6 +44,7 @@
#include "content/browser/compositor/software_browser_compositor_output_surface.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
+#include "content/browser/mus_util.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/gpu_stream_constants.h"
#include "content/public/common/content_switches.h"
@@ -59,6 +60,7 @@
#include "services/service_manager/runner/common/client_util.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "third_party/khronos/GLES2/gl2.h"
+#include "ui/base/ui_base_switches_util.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_switches.h"
#include "ui/compositor/layer.h"
@@ -77,21 +79,21 @@
#if defined(OS_WIN)
#include "base/win/windows_version.h"
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_win.h"
-#include "content/browser/compositor/software_output_device_win.h"
+#include "components/viz/service/display_embedder/software_output_device_win.h"
#include "ui/gfx/win/rendering_window_manager.h"
#elif defined(USE_OZONE)
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h"
-#include "content/browser/compositor/software_output_device_ozone.h"
+#include "components/viz/service/display_embedder/software_output_device_ozone.h"
#include "ui/ozone/public/overlay_candidates_ozone.h"
#include "ui/ozone/public/overlay_manager_ozone.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/ozone_switches.h"
#elif defined(USE_X11)
-#include "content/browser/compositor/software_output_device_x11.h"
+#include "components/viz/service/display_embedder/software_output_device_x11.h"
#elif defined(OS_MACOSX)
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_mac.h"
+#include "components/viz/service/display_embedder/software_output_device_mac.h"
#include "content/browser/compositor/gpu_output_surface_mac.h"
-#include "content/browser/compositor/software_output_device_mac.h"
#include "ui/base/cocoa/remote_layer_api.h"
#include "ui/base/ui_base_switches.h"
#elif defined(OS_ANDROID)
@@ -110,7 +112,6 @@ using gpu::gles2::GLES2Interface;
namespace {
-const int kNumRetriesBeforeSoftwareFallback = 4;
// The client_id used here should not conflict with the client_id generated
// from RenderWidgetHostImpl.
constexpr uint32_t kDefaultClientId = 0u;
@@ -126,56 +127,6 @@ bool IsGpuVSyncSignalSupported() {
#endif // defined(OS_WIN)
}
-scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon(
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
- gpu::SurfaceHandle surface_handle,
- bool need_alpha_channel,
- bool need_stencil_bits,
- bool support_locking,
- ui::ContextProviderCommandBuffer* shared_context_provider,
- ui::command_buffer_metrics::ContextType type) {
- DCHECK(
- content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor());
- DCHECK(gpu_channel_host);
-
- // All browser contexts get the same stream id because we don't use sync
- // tokens for browser surfaces.
- int32_t stream_id = content::kGpuStreamIdDefault;
- gpu::SchedulingPriority stream_priority = content::kGpuStreamPriorityUI;
-
- // This is called from a few places to create different contexts:
- // - The shared main thread context (offscreen).
- // - The compositor context, which is used by the browser compositor
- // (offscreen) for synchronization mostly, and by the display compositor
- // (onscreen, except for with mus) for actual GL drawing.
- // - The compositor worker context (offscreen) used for GPU raster.
- // So ask for capabilities needed by any of these cases (we can optimize by
- // branching on |surface_handle| being null if these needs diverge).
- //
- // The default framebuffer for an offscreen context is not used, so it does
- // not need alpha, stencil, depth, antialiasing. The display compositor does
- // not use these things either (except for alpha when using mus for
- // non-opaque ui that overlaps the system's window borders or stencil bits
- // for overdraw feedback), so we can request only that when needed.
- gpu::gles2::ContextCreationAttribHelper attributes;
- attributes.alpha_size = need_alpha_channel ? 8 : -1;
- attributes.depth_size = 0;
- attributes.stencil_size = need_stencil_bits ? 8 : 0;
- attributes.samples = 0;
- attributes.sample_buffers = 0;
- attributes.bind_generates_resource = false;
- attributes.lose_context_when_out_of_memory = true;
- attributes.buffer_preserved = false;
-
- constexpr bool automatic_flushes = false;
-
- GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
- return base::MakeRefCounted<ui::ContextProviderCommandBuffer>(
- std::move(gpu_channel_host), stream_id, stream_priority, surface_handle,
- url, automatic_flushes, support_locking, gpu::SharedMemoryLimits(),
- attributes, shared_context_provider, type);
-}
-
#if defined(OS_MACOSX)
bool IsCALayersDisabledFromCommandLine() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
@@ -231,13 +182,18 @@ struct GpuProcessTransportFactory::PerCompositorData {
};
GpuProcessTransportFactory::GpuProcessTransportFactory(
+ gpu::GpuChannelEstablishFactory* gpu_channel_factory,
+ viz::CompositingModeReporterImpl* compositing_mode_reporter,
scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner)
: frame_sink_id_allocator_(kDefaultClientId),
renderer_settings_(
viz::CreateRendererSettings(CreateBufferToTextureTargetMap())),
resize_task_runner_(std::move(resize_task_runner)),
task_graph_runner_(new cc::SingleThreadTaskGraphRunner),
+ gpu_channel_factory_(gpu_channel_factory),
+ compositing_mode_reporter_(compositing_mode_reporter),
callback_factory_(this) {
+ DCHECK(gpu_channel_factory_);
cc::SetClientNameForMetrics("Browser");
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
@@ -258,13 +214,21 @@ GpuProcessTransportFactory::GpuProcessTransportFactory(
task_graph_runner_->Start("CompositorTileWorker1",
base::SimpleThread::Options());
#if defined(OS_WIN)
- software_backing_.reset(new OutputDeviceBacking);
+ software_backing_ = std::make_unique<viz::OutputDeviceBacking>();
#endif
+
+ if (command_line->HasSwitch(switches::kDisableGpu) ||
+ command_line->HasSwitch(switches::kDisableGpuCompositing)) {
+ DisableGpuCompositing(nullptr);
+ }
}
GpuProcessTransportFactory::~GpuProcessTransportFactory() {
DCHECK(per_compositor_data_.empty());
+ if (shared_main_thread_contexts_)
+ shared_main_thread_contexts_->RemoveObserver(this);
+
// Make sure the lost context callback doesn't try to run during destruction.
callback_factory_.InvalidateWeakPtrs();
@@ -273,29 +237,28 @@ GpuProcessTransportFactory::~GpuProcessTransportFactory() {
std::unique_ptr<viz::SoftwareOutputDevice>
GpuProcessTransportFactory::CreateSoftwareOutputDevice(
- ui::Compositor* compositor) {
+ gfx::AcceleratedWidget widget) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kHeadless))
return base::WrapUnique(new viz::SoftwareOutputDevice);
#if defined(USE_AURA)
- if (aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS) {
+ if (switches::IsMusHostingViz()) {
NOTREACHED();
return nullptr;
}
#endif
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(OS_WIN)
- return std::unique_ptr<viz::SoftwareOutputDevice>(
- new SoftwareOutputDeviceWin(software_backing_.get(), compositor));
+ return std::make_unique<viz::SoftwareOutputDeviceWin>(software_backing_.get(),
+ widget);
#elif defined(USE_OZONE)
- return SoftwareOutputDeviceOzone::Create(compositor);
+ return viz::SoftwareOutputDeviceOzone::Create(widget);
#elif defined(USE_X11)
- return std::unique_ptr<viz::SoftwareOutputDevice>(
- new SoftwareOutputDeviceX11(compositor));
+ return std::make_unique<viz::SoftwareOutputDeviceX11>(widget);
#elif defined(OS_MACOSX)
- return std::unique_ptr<viz::SoftwareOutputDevice>(
- new SoftwareOutputDeviceMac(compositor));
+ return std::make_unique<viz::SoftwareOutputDeviceMac>(widget);
#else
NOTREACHED();
return std::unique_ptr<viz::SoftwareOutputDevice>();
@@ -336,24 +299,12 @@ CreateOverlayCandidateValidator(
#elif defined(OS_ANDROID)
validator.reset(new viz::CompositorOverlayCandidateValidatorAndroid());
#elif defined(OS_WIN)
- validator = base::MakeUnique<viz::CompositorOverlayCandidateValidatorWin>();
+ validator = std::make_unique<viz::CompositorOverlayCandidateValidatorWin>();
#endif
return validator;
}
-static bool ShouldCreateGpuLayerTreeFrameSink(ui::Compositor* compositor) {
-#if defined(OS_CHROMEOS)
- // Software fallback does not happen on Chrome OS.
- return true;
-#endif
-
- if (compositor->force_software_compositor())
- return false;
-
- return GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor();
-}
-
void GpuProcessTransportFactory::CreateLayerTreeFrameSink(
base::WeakPtr<ui::Compositor> compositor) {
DCHECK(!!compositor);
@@ -373,28 +324,34 @@ void GpuProcessTransportFactory::CreateLayerTreeFrameSink(
#endif
const bool use_vulkan = static_cast<bool>(SharedVulkanContextProvider());
- const bool create_gpu_output_surface =
- ShouldCreateGpuLayerTreeFrameSink(compositor.get());
- if (create_gpu_output_surface && !use_vulkan) {
- gpu::GpuChannelEstablishedCallback callback(
- base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel,
- callback_factory_.GetWeakPtr(), compositor,
- create_gpu_output_surface, 0));
- DCHECK(gpu_channel_factory_);
- gpu_channel_factory_->EstablishGpuChannel(callback);
+ const bool use_gpu_compositing =
+ !compositor->force_software_compositor() && !is_gpu_compositing_disabled_;
+ if (use_gpu_compositing && !use_vulkan) {
+ gpu_channel_factory_->EstablishGpuChannel(base::Bind(
+ &GpuProcessTransportFactory::EstablishedGpuChannel,
+ callback_factory_.GetWeakPtr(), compositor, use_gpu_compositing));
} else {
- EstablishedGpuChannel(compositor, create_gpu_output_surface, 0, nullptr);
+ EstablishedGpuChannel(compositor, use_gpu_compositing, nullptr);
}
}
void GpuProcessTransportFactory::EstablishedGpuChannel(
base::WeakPtr<ui::Compositor> compositor,
- bool create_gpu_output_surface,
- int num_attempts,
- scoped_refptr<gpu::GpuChannelHost> established_channel_host) {
+ bool use_gpu_compositing,
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
if (!compositor)
return;
+ if (gpu_channel_host &&
+ gpu_channel_host->gpu_feature_info()
+ .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] !=
+ gpu::kGpuFeatureStatusEnabled) {
+ use_gpu_compositing = false;
+ }
+ // Gpu compositing may have been disabled in the meantime.
+ if (is_gpu_compositing_disabled_)
+ use_gpu_compositing = false;
+
// The widget might have been released in the meantime.
PerCompositorDataMap::iterator it =
per_compositor_data_.find(compositor.get());
@@ -404,16 +361,6 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
PerCompositorData* data = it->second.get();
DCHECK(data);
- if (num_attempts > kNumRetriesBeforeSoftwareFallback) {
- bool fatal = false;
-#if defined(OS_CHROMEOS)
- fatal = true;
-#endif
- LOG_IF(FATAL, fatal) << "Unable to create a UI graphics context, and "
- << "cannot use software compositing on ChromeOS.";
- create_gpu_output_surface = false;
- }
-
bool support_stencil = false;
#if defined(OS_CHROMEOS)
// ChromeOS uses surfaceless when running on a real device and stencil
@@ -432,77 +379,95 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
scoped_refptr<viz::VulkanInProcessContextProvider> vulkan_context_provider =
SharedVulkanContextProvider();
scoped_refptr<ui::ContextProviderCommandBuffer> context_provider;
- if (create_gpu_output_surface && !vulkan_context_provider) {
+
+ if (!use_gpu_compositing || vulkan_context_provider) {
+ // If not using GL compositing, don't keep the old shared worker context.
+ shared_worker_context_provider_ = nullptr;
+ } else if (!gpu_channel_host) {
+ // Failed to establish a channel, which is a fatal error, so stop trying to
+ // use gpu compositing.
+ use_gpu_compositing = false;
+ shared_worker_context_provider_ = nullptr;
+ } else {
// Try to reuse existing worker context provider.
if (shared_worker_context_provider_) {
bool lost;
{
// Note: If context is lost, we delete reference after releasing the
// lock.
- base::AutoLock lock(*shared_worker_context_provider_->GetLock());
- lost = shared_worker_context_provider_->ContextGL()
- ->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
+ viz::ContextProvider::ScopedContextLock lock(
+ shared_worker_context_provider_.get());
+ lost = lock.ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
}
if (lost)
shared_worker_context_provider_ = nullptr;
}
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host;
- if (GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
- gpu_channel_host = std::move(established_channel_host);
-
- if (!gpu_channel_host) {
- shared_worker_context_provider_ = nullptr;
- } else {
- if (!shared_worker_context_provider_) {
- bool need_alpha_channel = false;
- const bool support_locking = true;
- shared_worker_context_provider_ = CreateContextCommon(
- gpu_channel_host, gpu::kNullSurfaceHandle, need_alpha_channel,
- false /* support_stencil */, support_locking, nullptr,
- ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT);
- if (!shared_worker_context_provider_->BindToCurrentThread())
- shared_worker_context_provider_ = nullptr;
+ if (!shared_worker_context_provider_) {
+ bool need_alpha_channel = false;
+ const bool support_locking = true;
+ shared_worker_context_provider_ = CreateContextCommon(
+ gpu_channel_host, gpu::kNullSurfaceHandle, need_alpha_channel,
+ false /* support_stencil */, support_locking, nullptr,
+ ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT);
+ auto result = shared_worker_context_provider_->BindToCurrentThread();
+ if (result != gpu::ContextResult::kSuccess) {
+ shared_worker_context_provider_ = nullptr;
+ if (result == gpu::ContextResult::kFatalFailure)
+ use_gpu_compositing = false;
}
+ }
- // The |context_provider| is used for both the browser compositor and the
- // display compositor. It shares resources with the worker context, so if
- // we failed to make a worker context, just start over and try again.
- if (shared_worker_context_provider_) {
- // For mus, we create an offscreen context for a mus window, and we will
- // use CommandBufferProxyImpl::TakeFrontBuffer() to take the context's
- // front buffer into a mailbox, insert a sync token, and send the
- // mailbox+sync to the ui service process.
- gpu::SurfaceHandle surface_handle = data->surface_handle;
- bool need_alpha_channel = false;
- bool support_locking = false;
- context_provider = CreateContextCommon(
- std::move(gpu_channel_host), surface_handle, need_alpha_channel,
- support_stencil, support_locking,
- shared_worker_context_provider_.get(),
- ui::command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT);
- // On Mac, GpuCommandBufferMsg_SwapBuffersCompleted must be handled in
- // a nested run loop during resize.
- context_provider->SetDefaultTaskRunner(resize_task_runner_);
- if (!context_provider->BindToCurrentThread())
- context_provider = nullptr;
+ // The |context_provider| is used for both the browser compositor and the
+ // display compositor. It shares resources with the worker context, so if
+ // we failed to make a worker context, just start over and try again.
+ if (shared_worker_context_provider_) {
+ // For mus, we create an offscreen context for a mus window, and we will
+ // use CommandBufferProxyImpl::TakeFrontBuffer() to take the context's
+ // front buffer into a mailbox, insert a sync token, and send the
+ // mailbox+sync to the ui service process.
+ gpu::SurfaceHandle surface_handle = data->surface_handle;
+ bool need_alpha_channel = false;
+ bool support_locking = false;
+ context_provider = CreateContextCommon(
+ std::move(gpu_channel_host), surface_handle, need_alpha_channel,
+ support_stencil, support_locking,
+ shared_worker_context_provider_.get(),
+ ui::command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT);
+ // On Mac, GpuCommandBufferMsg_SwapBuffersCompleted must be handled in
+ // a nested run loop during resize.
+ context_provider->SetDefaultTaskRunner(resize_task_runner_);
+ auto result = context_provider->BindToCurrentThread();
+ if (result != gpu::ContextResult::kSuccess) {
+ context_provider = nullptr;
+ if (result == gpu::ContextResult::kFatalFailure)
+ use_gpu_compositing = false;
}
}
+ }
- bool created_gpu_browser_compositor =
- !!context_provider && !!shared_worker_context_provider_;
-
- UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor",
- created_gpu_browser_compositor);
+ bool gpu_compositing_ready =
+ vulkan_context_provider ||
+ (context_provider && shared_worker_context_provider_);
+ UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor",
+ gpu_compositing_ready);
+ if (!gpu_compositing_ready) {
+#if defined(OS_CHROMEOS)
+ // A fatal context error occured, and we can not fall back to software
+ // compositing on ChromeOS. These can be unrecoverable hardware errors,
+ // or bugs that should not happen: either from the client's context request,
+ // in the service, or a transient error was miscategorized as fatal.
+ CHECK(use_gpu_compositing);
+#endif
- if (!created_gpu_browser_compositor) {
- // Try again.
- gpu::GpuChannelEstablishedCallback callback(
- base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel,
- callback_factory_.GetWeakPtr(), compositor,
- create_gpu_output_surface, num_attempts + 1));
- DCHECK(gpu_channel_factory_);
- gpu_channel_factory_->EstablishGpuChannel(callback);
+ // Try again if we didn't give up on gpu. Otherwise, drop the shared context
+ // if it exists and won't be used.
+ if (!use_gpu_compositing) {
+ shared_worker_context_provider_ = nullptr;
+ } else {
+ gpu_channel_factory_->EstablishGpuChannel(base::Bind(
+ &GpuProcessTransportFactory::EstablishedGpuChannel,
+ callback_factory_.GetWeakPtr(), compositor, use_gpu_compositing));
return;
}
}
@@ -527,17 +492,26 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
#endif
if (!display_output_surface) {
- if (!create_gpu_output_surface) {
+ if (!use_gpu_compositing) {
+ if (!is_gpu_compositing_disabled_ &&
+ !compositor->force_software_compositor()) {
+ // This will cause all other display compositors and FrameSink clients
+ // to fall back to software compositing. If the compositor is
+ // |force_software_compositor()|, then it is not a signal to others to
+ // use software too - but such compositors can not embed external
+ // surfaces as they are not following the correct mode.
+ DisableGpuCompositing(compositor.get());
+ }
display_output_surface =
- base::MakeUnique<SoftwareBrowserCompositorOutputSurface>(
- CreateSoftwareOutputDevice(compositor.get()), vsync_callback,
+ std::make_unique<SoftwareBrowserCompositorOutputSurface>(
+ CreateSoftwareOutputDevice(compositor->widget()), vsync_callback,
compositor->task_runner());
} else {
DCHECK(context_provider);
const auto& capabilities = context_provider->ContextCapabilities();
if (data->surface_handle == gpu::kNullSurfaceHandle) {
display_output_surface =
- base::MakeUnique<OffscreenBrowserCompositorOutputSurface>(
+ std::make_unique<OffscreenBrowserCompositorOutputSurface>(
context_provider, vsync_callback,
std::unique_ptr<viz::CompositorOverlayCandidateValidator>());
} else if (capabilities.surfaceless) {
@@ -545,7 +519,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
const auto& gpu_feature_info = context_provider->GetGpuFeatureInfo();
bool disable_overlay_ca_layers = gpu_feature_info.IsWorkaroundEnabled(
gpu::DISABLE_OVERLAY_CA_LAYERS);
- display_output_surface = base::MakeUnique<GpuOutputSurfaceMac>(
+ display_output_surface = std::make_unique<GpuOutputSurfaceMac>(
compositor->widget(), context_provider, data->surface_handle,
vsync_callback,
CreateOverlayCandidateValidator(compositor->widget(),
@@ -553,7 +527,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
GetGpuMemoryBufferManager());
#else
auto gpu_output_surface =
- base::MakeUnique<GpuSurfacelessBrowserCompositorOutputSurface>(
+ std::make_unique<GpuSurfacelessBrowserCompositorOutputSurface>(
context_provider, data->surface_handle, vsync_callback,
CreateOverlayCandidateValidator(compositor->widget()),
GL_TEXTURE_2D, GL_RGB,
@@ -572,7 +546,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
validator = CreateOverlayCandidateValidator(compositor->widget());
#endif
auto gpu_output_surface =
- base::MakeUnique<GpuBrowserCompositorOutputSurface>(
+ std::make_unique<GpuBrowserCompositorOutputSurface>(
context_provider, vsync_callback, std::move(validator));
gpu_vsync_control = gpu_output_surface.get();
display_output_surface = std::move(gpu_output_surface);
@@ -591,24 +565,25 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
viz::BeginFrameSource* begin_frame_source = nullptr;
if (compositor->external_begin_frames_enabled()) {
external_begin_frame_controller =
- base::MakeUnique<ExternalBeginFrameController>(compositor.get());
+ std::make_unique<ExternalBeginFrameController>(compositor.get());
begin_frame_source = external_begin_frame_controller->begin_frame_source();
} else if (!disable_display_vsync_) {
if (gpu_vsync_control && IsGpuVSyncSignalSupported()) {
gpu_vsync_begin_frame_source =
- base::MakeUnique<GpuVSyncBeginFrameSource>(gpu_vsync_control);
+ std::make_unique<GpuVSyncBeginFrameSource>(gpu_vsync_control);
begin_frame_source = gpu_vsync_begin_frame_source.get();
} else {
synthetic_begin_frame_source =
- base::MakeUnique<viz::DelayBasedBeginFrameSource>(
- base::MakeUnique<viz::DelayBasedTimeSource>(
- compositor->task_runner().get()));
+ std::make_unique<viz::DelayBasedBeginFrameSource>(
+ std::make_unique<viz::DelayBasedTimeSource>(
+ compositor->task_runner().get()),
+ viz::BeginFrameSource::kNotRestartableId);
begin_frame_source = synthetic_begin_frame_source.get();
}
} else {
synthetic_begin_frame_source =
- base::MakeUnique<viz::BackToBackBeginFrameSource>(
- base::MakeUnique<viz::DelayBasedTimeSource>(
+ std::make_unique<viz::BackToBackBeginFrameSource>(
+ std::make_unique<viz::DelayBasedTimeSource>(
compositor->task_runner().get()));
begin_frame_source = synthetic_begin_frame_source.get();
}
@@ -629,18 +604,17 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
data->display->RemoveObserver(data->external_begin_frame_controller.get());
}
- auto scheduler = base::MakeUnique<viz::DisplayScheduler>(
+ auto scheduler = std::make_unique<viz::DisplayScheduler>(
begin_frame_source, compositor->task_runner().get(),
display_output_surface->capabilities().max_frames_pending,
wait_for_all_pipeline_stages_before_draw_);
// The Display owns and uses the |display_output_surface| created above.
- data->display = base::MakeUnique<viz::Display>(
+ data->display = std::make_unique<viz::Display>(
viz::ServerSharedBitmapManager::current(), GetGpuMemoryBufferManager(),
renderer_settings_, compositor->frame_sink_id(),
std::move(display_output_surface), std::move(scheduler),
- base::MakeUnique<viz::TextureMailboxDeleter>(
- compositor->task_runner().get()));
+ compositor->task_runner());
GetFrameSinkManager()->RegisterBeginFrameSource(begin_frame_source,
compositor->frame_sink_id());
// Note that we are careful not to destroy prior BeginFrameSource objects
@@ -658,12 +632,12 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
// same ContextProvider as the Display's output surface.
auto layer_tree_frame_sink =
vulkan_context_provider
- ? base::MakeUnique<viz::DirectLayerTreeFrameSink>(
+ ? std::make_unique<viz::DirectLayerTreeFrameSink>(
compositor->frame_sink_id(), GetHostFrameSinkManager(),
GetFrameSinkManager(), data->display.get(),
static_cast<scoped_refptr<viz::VulkanContextProvider>>(
vulkan_context_provider))
- : base::MakeUnique<viz::DirectLayerTreeFrameSink>(
+ : std::make_unique<viz::DirectLayerTreeFrameSink>(
compositor->frame_sink_id(), GetHostFrameSinkManager(),
GetFrameSinkManager(), data->display.get(), context_provider,
shared_worker_context_provider_, GetGpuMemoryBufferManager(),
@@ -673,6 +647,52 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
compositor->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
}
+void GpuProcessTransportFactory::DisableGpuCompositing(
+ ui::Compositor* guilty_compositor) {
+ // Change the result of IsGpuCompositingDisabled() before notifying anything.
+ is_gpu_compositing_disabled_ = true;
+
+ // This will notify all CompositingModeWatchers.
+ compositing_mode_reporter_->SetUsingSoftwareCompositing();
+
+ // Consumers of the shared main thread context aren't CompositingModeWatchers,
+ // so inform them about the compositing mode switch by acting like the context
+ // was lost. This also destroys the contexts since they aren't created when
+ // gpu compositing isn't being used.
+ OnLostMainThreadSharedContext();
+
+ // This class chooses the compositing mode for all ui::Compositors and display
+ // compositors, so it is not a CompositingModeWatcher also. Here we remove the
+ // FrameSink from every compositor that needs to fall back to software
+ // compositing (except the |guilty_compositor| which is already doing so).
+ //
+ // Releasing the FrameSink from the compositor will remove it from
+ // |per_compositor_data_|, so we can't do that while iterating though the
+ // collection.
+ std::vector<ui::Compositor*> to_release;
+ to_release.reserve(per_compositor_data_.size());
+ for (auto& pair : per_compositor_data_) {
+ ui::Compositor* compositor = pair.first;
+ // The |guilty_compositor| is in the process of setting up its FrameSink
+ // so removing it from |per_compositor_data_| would be both pointless and
+ // the cause of a crash.
+ // Compositors with |force_software_compositor()| do not follow the global
+ // compositing mode, so they do not need to changed.
+ if (compositor != guilty_compositor &&
+ !compositor->force_software_compositor())
+ to_release.push_back(compositor);
+ }
+ for (ui::Compositor* compositor : to_release) {
+ // Compositor expects to be not visible when releasing its FrameSink.
+ bool visible = compositor->IsVisible();
+ compositor->SetVisible(false);
+ gfx::AcceleratedWidget widget = compositor->ReleaseAcceleratedWidget();
+ compositor->SetAcceleratedWidget(widget);
+ if (visible)
+ compositor->SetVisible(true);
+ }
+}
+
std::unique_ptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector(
ui::Compositor* source_compositor,
ui::Layer* target_layer) {
@@ -755,6 +775,10 @@ cc::TaskGraphRunner* GpuProcessTransportFactory::GetTaskGraphRunner() {
return task_graph_runner_.get();
}
+bool GpuProcessTransportFactory::IsGpuCompositingDisabled() {
+ return is_gpu_compositing_disabled_;
+}
+
ui::ContextFactory* GpuProcessTransportFactory::GetContextFactory() {
return this;
}
@@ -905,12 +929,6 @@ viz::GLHelper* GpuProcessTransportFactory::GetGLHelper() {
return gl_helper_.get();
}
-void GpuProcessTransportFactory::SetGpuChannelEstablishFactory(
- gpu::GpuChannelEstablishFactory* factory) {
- DCHECK(!gpu_channel_factory_ || !factory);
- gpu_channel_factory_ = factory;
-}
-
#if defined(OS_MACOSX)
void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
ui::Compositor* compositor,
@@ -927,17 +945,23 @@ void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
scoped_refptr<ContextProvider>
GpuProcessTransportFactory::SharedMainThreadContextProvider() {
+ if (is_gpu_compositing_disabled_)
+ return nullptr;
+
if (shared_main_thread_contexts_)
return shared_main_thread_contexts_;
- if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
- return nullptr;
-
- DCHECK(gpu_channel_factory_);
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
- gpu_channel_factory_->EstablishGpuChannelSync();
- if (!gpu_channel_host)
+ gpu_channel_factory_->EstablishGpuChannelSync(nullptr);
+ if (!gpu_channel_host ||
+ gpu_channel_host->gpu_feature_info()
+ .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] !=
+ gpu::kGpuFeatureStatusEnabled) {
+ DisableGpuCompositing(nullptr);
+ if (gpu_channel_host)
+ gpu_channel_host->DestroyChannel();
return nullptr;
+ }
// We need a separate context from the compositor's so that skia and gl_helper
// don't step on each other.
@@ -947,11 +971,12 @@ GpuProcessTransportFactory::SharedMainThreadContextProvider() {
std::move(gpu_channel_host), gpu::kNullSurfaceHandle, need_alpha_channel,
false, support_locking, nullptr,
ui::command_buffer_metrics::BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT);
- shared_main_thread_contexts_->SetLostContextCallback(base::Bind(
- &GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback,
- callback_factory_.GetWeakPtr()));
- if (!shared_main_thread_contexts_->BindToCurrentThread())
+ shared_main_thread_contexts_->AddObserver(this);
+ auto result = shared_main_thread_contexts_->BindToCurrentThread();
+ if (result != gpu::ContextResult::kSuccess) {
+ shared_main_thread_contexts_->RemoveObserver(this);
shared_main_thread_contexts_ = nullptr;
+ }
return shared_main_thread_contexts_;
}
@@ -962,7 +987,7 @@ GpuProcessTransportFactory::CreatePerCompositorData(
gfx::AcceleratedWidget widget = compositor->widget();
- auto data = base::MakeUnique<PerCompositorData>();
+ auto data = std::make_unique<PerCompositorData>();
if (widget == gfx::kNullAcceleratedWidget) {
data->surface_handle = gpu::kNullSurfaceHandle;
} else {
@@ -980,13 +1005,6 @@ GpuProcessTransportFactory::CreatePerCompositorData(
return return_ptr;
}
-void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&GpuProcessTransportFactory::OnLostMainThreadSharedContext,
- callback_factory_.GetWeakPtr()));
-}
-
void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
LOG(ERROR) << "Lost UI shared context.";
@@ -994,9 +1012,11 @@ void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
// new resources are created if needed.
// Kill shared contexts for both threads in tandem so they are always in
// the same share group.
+ if (shared_main_thread_contexts_)
+ shared_main_thread_contexts_->RemoveObserver(this);
scoped_refptr<ContextProvider> lost_shared_main_thread_contexts =
shared_main_thread_contexts_;
- shared_main_thread_contexts_ = NULL;
+ shared_main_thread_contexts_ = nullptr;
std::unique_ptr<viz::GLHelper> lost_gl_helper = std::move(gl_helper_);
@@ -1005,7 +1025,7 @@ void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
// Kill things that use the shared context before killing the shared context.
lost_gl_helper.reset();
- lost_shared_main_thread_contexts = NULL;
+ lost_shared_main_thread_contexts = nullptr;
}
scoped_refptr<viz::VulkanInProcessContextProvider>
@@ -1022,4 +1042,61 @@ GpuProcessTransportFactory::SharedVulkanContextProvider() {
return shared_vulkan_context_provider_;
}
+void GpuProcessTransportFactory::OnContextLost() {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&GpuProcessTransportFactory::OnLostMainThreadSharedContext,
+ callback_factory_.GetWeakPtr()));
+}
+
+scoped_refptr<ui::ContextProviderCommandBuffer>
+GpuProcessTransportFactory::CreateContextCommon(
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
+ gpu::SurfaceHandle surface_handle,
+ bool need_alpha_channel,
+ bool need_stencil_bits,
+ bool support_locking,
+ ui::ContextProviderCommandBuffer* shared_context_provider,
+ ui::command_buffer_metrics::ContextType type) {
+ DCHECK(gpu_channel_host);
+ DCHECK(!is_gpu_compositing_disabled_);
+
+ // All browser contexts get the same stream id because we don't use sync
+ // tokens for browser surfaces.
+ int32_t stream_id = content::kGpuStreamIdDefault;
+ gpu::SchedulingPriority stream_priority = content::kGpuStreamPriorityUI;
+
+ // This is called from a few places to create different contexts:
+ // - The shared main thread context (offscreen).
+ // - The compositor context, which is used by the browser compositor
+ // (offscreen) for synchronization mostly, and by the display compositor
+ // (onscreen, except for with mus) for actual GL drawing.
+ // - The compositor worker context (offscreen) used for GPU raster.
+ // So ask for capabilities needed by any of these cases (we can optimize by
+ // branching on |surface_handle| being null if these needs diverge).
+ //
+ // The default framebuffer for an offscreen context is not used, so it does
+ // not need alpha, stencil, depth, antialiasing. The display compositor does
+ // not use these things either (except for alpha when using mus for
+ // non-opaque ui that overlaps the system's window borders or stencil bits
+ // for overdraw feedback), so we can request only that when needed.
+ gpu::gles2::ContextCreationAttribHelper attributes;
+ attributes.alpha_size = need_alpha_channel ? 8 : -1;
+ attributes.depth_size = 0;
+ attributes.stencil_size = need_stencil_bits ? 8 : 0;
+ attributes.samples = 0;
+ attributes.sample_buffers = 0;
+ attributes.bind_generates_resource = false;
+ attributes.lose_context_when_out_of_memory = true;
+ attributes.buffer_preserved = false;
+
+ constexpr bool automatic_flushes = false;
+
+ GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
+ return base::MakeRefCounted<ui::ContextProviderCommandBuffer>(
+ std::move(gpu_channel_host), stream_id, stream_priority, surface_handle,
+ url, automatic_flushes, support_locking, gpu::SharedMemoryLimits(),
+ attributes, shared_context_provider, 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 25340e53bef..a2c6a967c46 100644
--- a/chromium/content/browser/compositor/gpu_process_transport_factory.h
+++ b/chromium/content/browser/compositor/gpu_process_transport_factory.h
@@ -17,10 +17,12 @@
#include "base/observer_list.h"
#include "build/build_config.h"
#include "components/viz/common/display/renderer_settings.h"
+#include "components/viz/common/gpu/context_lost_observer.h"
#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "gpu/ipc/client/gpu_channel_host.h"
+#include "services/ui/public/cpp/gpu/command_buffer_metrics.h"
#include "ui/compositor/compositor.h"
namespace base {
@@ -33,23 +35,31 @@ class SingleThreadTaskGraphRunner;
class SurfaceManager;
}
+namespace gpu {
+class GpuChannelEstablishFactory;
+}
+
namespace ui {
class ContextProviderCommandBuffer;
}
namespace viz {
+class CompositingModeReporterImpl;
+class OutputDeviceBacking;
class SoftwareOutputDevice;
class VulkanInProcessContextProvider;
}
namespace content {
-class OutputDeviceBacking;
class GpuProcessTransportFactory : public ui::ContextFactory,
public ui::ContextFactoryPrivate,
- public ImageTransportFactory {
+ public ImageTransportFactory,
+ public viz::ContextLostObserver {
public:
- explicit GpuProcessTransportFactory(
+ GpuProcessTransportFactory(
+ gpu::GpuChannelEstablishFactory* gpu_channel_factory,
+ viz::CompositingModeReporterImpl* compositing_mode_reporter,
scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner);
~GpuProcessTransportFactory() override;
@@ -89,12 +99,11 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
void SetOutputIsSecure(ui::Compositor* compositor, bool secure) override;
// ImageTransportFactory implementation.
+ bool IsGpuCompositingDisabled() override;
ui::ContextFactory* GetContextFactory() override;
ui::ContextFactoryPrivate* GetContextFactoryPrivate() override;
viz::FrameSinkManagerImpl* GetFrameSinkManager() override;
viz::GLHelper* GetGLHelper() override;
- void SetGpuChannelEstablishFactory(
- gpu::GpuChannelEstablishFactory* factory) override;
#if defined(OS_MACOSX)
void SetCompositorSuspendedForRecycle(ui::Compositor* compositor,
bool suspended) override;
@@ -105,24 +114,36 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
PerCompositorData* CreatePerCompositorData(ui::Compositor* compositor);
std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice(
- ui::Compositor* compositor);
+ gfx::AcceleratedWidget widget);
void EstablishedGpuChannel(
base::WeakPtr<ui::Compositor> compositor,
- bool create_gpu_output_surface,
- int num_attempts,
+ bool use_gpu_compositing,
scoped_refptr<gpu::GpuChannelHost> established_channel_host);
- void OnLostMainThreadSharedContextInsideCallback();
+ void DisableGpuCompositing(ui::Compositor* guilty_compositor);
+
void OnLostMainThreadSharedContext();
scoped_refptr<viz::VulkanInProcessContextProvider>
SharedVulkanContextProvider();
+ // viz::ContextLostObserver implementation.
+ void OnContextLost() override;
+
+ scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon(
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
+ gpu::SurfaceHandle surface_handle,
+ bool need_alpha_channel,
+ bool need_stencil_bits,
+ bool support_locking,
+ ui::ContextProviderCommandBuffer* shared_context_provider,
+ ui::command_buffer_metrics::ContextType type);
+
viz::FrameSinkIdAllocator frame_sink_id_allocator_;
#if defined(OS_WIN)
// Used by output surface, stored in PerCompositorData.
- std::unique_ptr<OutputDeviceBacking> software_backing_;
+ std::unique_ptr<viz::OutputDeviceBacking> software_backing_;
#endif
// Depends on SurfaceManager.
@@ -139,13 +160,17 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
scoped_refptr<ui::ContextProviderCommandBuffer>
shared_worker_context_provider_;
+ bool is_gpu_compositing_disabled_ = false;
bool disable_display_vsync_ = false;
bool wait_for_all_pipeline_stages_before_draw_ = false;
bool shared_vulkan_context_provider_initialized_ = false;
scoped_refptr<viz::VulkanInProcessContextProvider>
shared_vulkan_context_provider_;
- gpu::GpuChannelEstablishFactory* gpu_channel_factory_ = nullptr;
+ gpu::GpuChannelEstablishFactory* const gpu_channel_factory_;
+ // Service-side impl that controls the compositing mode based on what mode the
+ // display compositors are using.
+ viz::CompositingModeReporterImpl* const compositing_mode_reporter_;
base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_;
diff --git a/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc b/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
index 3875f7648bf..67230cc056d 100644
--- a/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
@@ -111,20 +111,20 @@ void GpuSurfacelessBrowserCompositorOutputSurface::Reshape(
}
void GpuSurfacelessBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result,
+ const gfx::SwapResponse& response,
const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) {
+ gfx::SwapResponse modified_response(response);
bool force_swap = false;
- if (result == gfx::SwapResult::SWAP_NAK_RECREATE_BUFFERS) {
+ if (response.result == gfx::SwapResult::SWAP_NAK_RECREATE_BUFFERS) {
// Even through the swap failed, this is a fixable error so we can pretend
// it succeeded to the rest of the system.
- result = gfx::SwapResult::SWAP_ACK;
+ modified_response.result = gfx::SwapResult::SWAP_ACK;
buffer_queue_->RecreateBuffers();
force_swap = true;
}
buffer_queue_->PageFlipComplete();
GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
- latency_info, result, params_mac);
+ modified_response, params_mac);
if (force_swap)
client_->SetNeedsRedrawRect(gfx::Rect(swap_size_));
}
diff --git a/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h b/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h
index 3e5cca62a0a..2e5b2ce3cb0 100644
--- a/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h
@@ -51,8 +51,7 @@ class GpuSurfacelessBrowserCompositorOutputSurface
// BrowserCompositorOutputSurface implementation.
void OnGpuSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result,
+ const gfx::SwapResponse& response,
const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) override;
private:
diff --git a/chromium/content/browser/compositor/image_transport_factory.cc b/chromium/content/browser/compositor/image_transport_factory.cc
index c8016887a2f..8687663cc9a 100644
--- a/chromium/content/browser/compositor/image_transport_factory.cc
+++ b/chromium/content/browser/compositor/image_transport_factory.cc
@@ -9,26 +9,26 @@
namespace content {
namespace {
-ImageTransportFactory* g_factory = nullptr;
+ImageTransportFactory* g_image_transport_factory = nullptr;
} // namespace
// static
void ImageTransportFactory::SetFactory(
std::unique_ptr<ImageTransportFactory> factory) {
- DCHECK(!g_factory);
- g_factory = factory.release();
+ DCHECK(!g_image_transport_factory);
+ g_image_transport_factory = factory.release();
}
// static
void ImageTransportFactory::Terminate() {
- delete g_factory;
- g_factory = nullptr;
+ delete g_image_transport_factory;
+ g_image_transport_factory = nullptr;
}
// static
ImageTransportFactory* ImageTransportFactory::GetInstance() {
- return g_factory;
+ return g_image_transport_factory;
}
} // namespace content
diff --git a/chromium/content/browser/compositor/image_transport_factory.h b/chromium/content/browser/compositor/image_transport_factory.h
index 0d11f33ba48..1ac2c66a4e5 100644
--- a/chromium/content/browser/compositor/image_transport_factory.h
+++ b/chromium/content/browser/compositor/image_transport_factory.h
@@ -20,10 +20,6 @@ namespace viz {
class GLHelper;
}
-namespace gpu {
-class GpuChannelEstablishFactory;
-}
-
namespace content {
// This class provides the interface for creating the support for the
@@ -43,6 +39,11 @@ class CONTENT_EXPORT ImageTransportFactory {
// Gets the factory instance.
static ImageTransportFactory* GetInstance();
+ // Whether gpu compositing is being used or is disabled for software
+ // compositing. Clients of the compositor should give resources that match
+ // the appropriate mode.
+ virtual bool IsGpuCompositingDisabled() = 0;
+
// Gets the image transport factory as a context factory for the compositor.
virtual ui::ContextFactory* GetContextFactory() = 0;
@@ -56,9 +57,6 @@ class CONTENT_EXPORT ImageTransportFactory {
// (ImageTransportFactoryObserver::OnLostResources is called).
virtual viz::GLHelper* GetGLHelper() = 0;
- virtual void SetGpuChannelEstablishFactory(
- gpu::GpuChannelEstablishFactory* factory) = 0;
-
#if defined(OS_MACOSX)
// Called with |suspended| as true when the ui::Compositor has been
// disconnected from an NSView and may be attached to another one. Called
diff --git a/chromium/content/browser/compositor/image_transport_factory_browsertest.cc b/chromium/content/browser/compositor/image_transport_factory_browsertest.cc
index 768d897a241..8a918a746a9 100644
--- a/chromium/content/browser/compositor/image_transport_factory_browsertest.cc
+++ b/chromium/content/browser/compositor/image_transport_factory_browsertest.cc
@@ -8,10 +8,10 @@
#include "build/build_config.h"
#include "components/viz/common/gpu/context_provider.h"
#include "content/browser/compositor/owned_mailbox.h"
-#include "content/public/browser/gpu_data_manager.h"
#include "content/public/test/content_browser_test.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/config/gpu_feature_info.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "ui/compositor/compositor.h"
@@ -36,11 +36,16 @@ class MockContextFactoryObserver : public ui::ContextFactoryObserver {
// resources are reset.
IN_PROC_BROWSER_TEST_F(ImageTransportFactoryBrowserTest,
MAYBE_TestLostContext) {
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+
// This test doesn't make sense in software compositing mode.
- if (!GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor())
+ scoped_refptr<viz::ContextProvider> context_provider =
+ factory->GetContextFactory()->SharedMainThreadContextProvider();
+ if (context_provider->GetGpuFeatureInfo()
+ .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] !=
+ gpu::kGpuFeatureStatusEnabled) {
return;
-
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+ }
scoped_refptr<OwnedMailbox> mailbox =
new OwnedMailbox(factory->GetGLHelper());
@@ -53,9 +58,7 @@ IN_PROC_BROWSER_TEST_F(ImageTransportFactoryBrowserTest,
EXPECT_CALL(observer, OnLostResources())
.WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
- ui::ContextFactory* context_factory = factory->GetContextFactory();
- gpu::gles2::GLES2Interface* gl =
- context_factory->SharedMainThreadContextProvider()->ContextGL();
+ gpu::gles2::GLES2Interface* gl = context_provider->ContextGL();
gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
GL_INNOCENT_CONTEXT_RESET_ARB);
@@ -97,10 +100,16 @@ class ImageTransportFactoryTearDownBrowserTest : public ContentBrowserTest {
// called and the created resources are reset.
IN_PROC_BROWSER_TEST_F(ImageTransportFactoryTearDownBrowserTest,
MAYBE_LoseOnTearDown) {
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
// This test doesn't make sense in software compositing mode.
- if (!GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor())
+ scoped_refptr<viz::ContextProvider> context_provider =
+ factory->GetContextFactory()->SharedMainThreadContextProvider();
+ if (context_provider->GetGpuFeatureInfo()
+ .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] !=
+ gpu::kGpuFeatureStatusEnabled) {
return;
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+ }
+
viz::GLHelper* helper = factory->GetGLHelper();
ASSERT_TRUE(helper);
mailbox_ = new OwnedMailbox(helper);
diff --git a/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc b/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
index 82259e58294..a36dfd62691 100644
--- a/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
@@ -163,7 +163,7 @@ void OffscreenBrowserCompositorOutputSurface::SwapBuffers(
sync_token,
base::Bind(
&OffscreenBrowserCompositorOutputSurface::OnSwapBuffersComplete,
- weak_ptr_factory_.GetWeakPtr(), frame.latency_info));
+ weak_ptr_factory_.GetWeakPtr(), frame.latency_info, ++swap_id_));
}
bool OffscreenBrowserCompositorOutputSurface::IsDisplayedAsOverlayPlane()
@@ -198,9 +198,11 @@ void OffscreenBrowserCompositorOutputSurface::OnReflectorChanged() {
}
void OffscreenBrowserCompositorOutputSurface::OnSwapBuffersComplete(
- const std::vector<ui::LatencyInfo>& latency_info) {
+ const std::vector<ui::LatencyInfo>& latency_info,
+ uint64_t swap_id) {
RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(latency_info);
- client_->DidReceiveSwapBuffersAck();
+ client_->DidReceiveSwapBuffersAck(swap_id);
+ client_->DidReceivePresentationFeedback(swap_id, gfx::PresentationFeedback());
}
} // namespace content
diff --git a/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.h b/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.h
index eed57b60b45..f58cd0001cf 100644
--- a/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.h
@@ -59,13 +59,15 @@ class OffscreenBrowserCompositorOutputSurface
void SetSurfaceSuspendedForRecycle(bool suspended) override {}
#endif
- void OnSwapBuffersComplete(const std::vector<ui::LatencyInfo>& latency_info);
+ void OnSwapBuffersComplete(const std::vector<ui::LatencyInfo>& latency_info,
+ uint64_t swap_id);
viz::OutputSurfaceClient* client_ = nullptr;
gfx::Size reshape_size_;
uint32_t fbo_ = 0;
bool reflector_changed_ = false;
std::unique_ptr<ReflectorTexture> reflector_texture_;
+ uint64_t swap_id_ = 0;
base::WeakPtrFactory<OffscreenBrowserCompositorOutputSurface>
weak_ptr_factory_;
diff --git a/chromium/content/browser/compositor/owned_mailbox.cc b/chromium/content/browser/compositor/owned_mailbox.cc
index ecf7f3ba6f3..69e1687c9d0 100644
--- a/chromium/content/browser/compositor/owned_mailbox.cc
+++ b/chromium/content/browser/compositor/owned_mailbox.cc
@@ -14,6 +14,10 @@ OwnedMailbox::OwnedMailbox(viz::GLHelper* gl_helper)
: texture_id_(0), gl_helper_(gl_helper) {
texture_id_ = gl_helper_->CreateTexture();
mailbox_holder_ = gl_helper_->ProduceMailboxHolderFromTexture(texture_id_);
+ // The texture target is not exposed on this class, as GLHelper assumes
+ // GL_TEXTURE_2D.
+ DCHECK_EQ(mailbox_holder_.texture_target,
+ static_cast<uint32_t>(GL_TEXTURE_2D));
ImageTransportFactory::GetInstance()->GetContextFactory()->AddObserver(this);
}
@@ -34,7 +38,7 @@ void OwnedMailbox::Destroy() {
gl_helper_->DeleteTexture(texture_id_);
texture_id_ = 0;
mailbox_holder_ = gpu::MailboxHolder();
- gl_helper_ = NULL;
+ gl_helper_ = nullptr;
}
void OwnedMailbox::OnLostResources() {
diff --git a/chromium/content/browser/compositor/owned_mailbox.h b/chromium/content/browser/compositor/owned_mailbox.h
index 3f9aa12efb8..d703dfa5b99 100644
--- a/chromium/content/browser/compositor/owned_mailbox.h
+++ b/chromium/content/browser/compositor/owned_mailbox.h
@@ -34,7 +34,6 @@ class CONTENT_EXPORT OwnedMailbox : public base::RefCounted<OwnedMailbox>,
return mailbox_holder_.sync_token;
}
uint32_t texture_id() const { return texture_id_; }
- uint32_t target() const { return mailbox_holder_.texture_target; }
void UpdateSyncToken(const gpu::SyncToken& sync_token);
void Destroy();
diff --git a/chromium/content/browser/compositor/reflector_impl.cc b/chromium/content/browser/compositor/reflector_impl.cc
index 69b3639827d..31544bdbe22 100644
--- a/chromium/content/browser/compositor/reflector_impl.cc
+++ b/chromium/content/browser/compositor/reflector_impl.cc
@@ -7,8 +7,10 @@
#include "base/bind.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
+#include "components/viz/common/resources/transferable_resource.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
#include "content/browser/compositor/owned_mailbox.h"
+#include "third_party/khronos/GLES2/gl2.h"
#include "ui/compositor/layer.h"
namespace content {
@@ -74,7 +76,7 @@ void ReflectorImpl::AddMirroringLayer(ui::Layer* layer) {
DCHECK(layer->GetCompositor());
DCHECK(mirroring_layers_.end() == FindLayerData(layer));
- mirroring_layers_.push_back(base::MakeUnique<LayerData>(layer));
+ mirroring_layers_.push_back(std::make_unique<LayerData>(layer));
if (mailbox_)
mirroring_layers_.back()->needs_set_mailbox = true;
mirrored_compositor_->ScheduleFullRedraw();
@@ -157,8 +159,10 @@ void ReflectorImpl::UpdateTexture(ReflectorImpl::LayerData* layer_data,
const gfx::Size& source_size,
const gfx::Rect& redraw_rect) {
if (layer_data->needs_set_mailbox) {
- layer_data->layer->SetTextureMailbox(
- viz::TextureMailbox(mailbox_->holder()),
+ layer_data->layer->SetTransferableResource(
+ viz::TransferableResource::MakeGL(mailbox_->holder().mailbox, GL_LINEAR,
+ mailbox_->holder().texture_target,
+ mailbox_->holder().sync_token),
viz::SingleReleaseCallback::Create(
base::Bind(ReleaseMailbox, mailbox_)),
source_size);
diff --git a/chromium/content/browser/compositor/reflector_impl_unittest.cc b/chromium/content/browser/compositor/reflector_impl_unittest.cc
index 54696138e0b..bcf802ad67b 100644
--- a/chromium/content/browser/compositor/reflector_impl_unittest.cc
+++ b/chromium/content/browser/compositor/reflector_impl_unittest.cc
@@ -134,16 +134,17 @@ class ReflectorImplTest : public testing::Test {
ui::ContextFactory* context_factory = nullptr;
ui::ContextFactoryPrivate* context_factory_private = nullptr;
- message_loop_ = base::MakeUnique<base::MessageLoop>();
+ message_loop_ = std::make_unique<base::MessageLoop>();
ui::InitializeContextFactoryForTests(enable_pixel_output, &context_factory,
&context_factory_private);
ImageTransportFactory::SetFactory(
std::make_unique<NoTransportImageTransportFactory>());
task_runner_ = message_loop_->task_runner();
compositor_task_runner_ = new FakeTaskRunner();
- begin_frame_source_.reset(new viz::DelayBasedBeginFrameSource(
- base::MakeUnique<viz::DelayBasedTimeSource>(
- compositor_task_runner_.get())));
+ begin_frame_source_ = std::make_unique<viz::DelayBasedBeginFrameSource>(
+ std::make_unique<viz::DelayBasedTimeSource>(
+ compositor_task_runner_.get()),
+ viz::BeginFrameSource::kNotRestartableId);
compositor_.reset(new ui::Compositor(
context_factory_private->AllocateFrameSinkId(), context_factory,
context_factory_private, compositor_task_runner_.get(),
@@ -154,7 +155,7 @@ class ReflectorImplTest : public testing::Test {
auto context_provider = cc::TestContextProvider::Create();
context_provider->BindToCurrentThread();
output_surface_ =
- base::MakeUnique<TestOutputSurface>(std::move(context_provider));
+ std::make_unique<TestOutputSurface>(std::move(context_provider));
root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
compositor_->SetRootLayer(root_layer_.get());
@@ -166,7 +167,7 @@ class ReflectorImplTest : public testing::Test {
}
void SetUpReflector() {
- reflector_ = base::MakeUnique<ReflectorImpl>(compositor_.get(),
+ reflector_ = std::make_unique<ReflectorImpl>(compositor_.get(),
mirroring_layer_.get());
reflector_->OnSourceSurfaceReady(output_surface_.get());
}
@@ -174,9 +175,9 @@ class ReflectorImplTest : public testing::Test {
void TearDown() override {
if (reflector_)
reflector_->RemoveMirroringLayer(mirroring_layer_.get());
- viz::TextureMailbox mailbox;
+ viz::TransferableResource resource;
std::unique_ptr<viz::SingleReleaseCallback> release;
- if (mirroring_layer_->PrepareTextureMailbox(&mailbox, &release)) {
+ if (mirroring_layer_->PrepareTransferableResource(&resource, &release)) {
release->Run(gpu::SyncToken(), false);
}
compositor_.reset();
diff --git a/chromium/content/browser/compositor/software_browser_compositor_output_surface.cc b/chromium/content/browser/compositor/software_browser_compositor_output_surface.cc
index 92d65615c77..253e832b8ea 100644
--- a/chromium/content/browser/compositor/software_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/software_browser_compositor_output_surface.cc
@@ -85,18 +85,33 @@ void SoftwareBrowserCompositorOutputSurface::SwapBuffers(
frame.latency_info));
gfx::VSyncProvider* vsync_provider = software_device()->GetVSyncProvider();
- if (vsync_provider)
- vsync_provider->GetVSyncParameters(update_vsync_parameters_callback_);
+ if (vsync_provider) {
+ vsync_provider->GetVSyncParameters(
+ base::Bind(&SoftwareBrowserCompositorOutputSurface::UpdateVSyncCallback,
+ weak_factory_.GetWeakPtr()));
+ }
+ ++swap_id_;
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&SoftwareBrowserCompositorOutputSurface::SwapBuffersCallback,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr(), swap_id_));
+}
+
+void SoftwareBrowserCompositorOutputSurface::SwapBuffersCallback(
+ uint64_t swap_id) {
+ client_->DidReceiveSwapBuffersAck(swap_id);
+ client_->DidReceivePresentationFeedback(
+ swap_id,
+ gfx::PresentationFeedback(base::TimeTicks::Now(), refresh_interval_, 0u));
}
-void SoftwareBrowserCompositorOutputSurface::SwapBuffersCallback() {
- client_->DidReceiveSwapBuffersAck();
+void SoftwareBrowserCompositorOutputSurface::UpdateVSyncCallback(
+ const base::TimeTicks timebase,
+ const base::TimeDelta interval) {
+ refresh_interval_ = interval;
+ update_vsync_parameters_callback_.Run(timebase, interval);
}
bool SoftwareBrowserCompositorOutputSurface::IsDisplayedAsOverlayPlane() const {
diff --git a/chromium/content/browser/compositor/software_browser_compositor_output_surface.h b/chromium/content/browser/compositor/software_browser_compositor_output_surface.h
index ce2ea081fe6..ab0061d0d36 100644
--- a/chromium/content/browser/compositor/software_browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/software_browser_compositor_output_surface.h
@@ -52,10 +52,14 @@ class CONTENT_EXPORT SoftwareBrowserCompositorOutputSurface
void SetSurfaceSuspendedForRecycle(bool suspended) override;
#endif
- void SwapBuffersCallback();
+ void SwapBuffersCallback(uint64_t swap_id);
+ void UpdateVSyncCallback(const base::TimeTicks timebase,
+ const base::TimeDelta interval);
viz::OutputSurfaceClient* client_ = nullptr;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ uint64_t swap_id_ = 0;
+ base::TimeDelta refresh_interval_;
base::WeakPtrFactory<SoftwareBrowserCompositorOutputSurface> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SoftwareBrowserCompositorOutputSurface);
diff --git a/chromium/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc b/chromium/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc
index 4e8cc64d2f8..27b9096d98a 100644
--- a/chromium/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc
+++ b/chromium/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc
@@ -65,8 +65,9 @@ class FakeSoftwareOutputDevice : public viz::SoftwareOutputDevice {
class SoftwareBrowserCompositorOutputSurfaceTest : public testing::Test {
public:
SoftwareBrowserCompositorOutputSurfaceTest()
- : begin_frame_source_(base::MakeUnique<viz::DelayBasedTimeSource>(
- message_loop_.task_runner().get())) {}
+ : begin_frame_source_(std::make_unique<viz::DelayBasedTimeSource>(
+ message_loop_.task_runner().get()),
+ viz::BeginFrameSource::kNotRestartableId) {}
~SoftwareBrowserCompositorOutputSurfaceTest() override = default;
void SetUp() override;
@@ -118,7 +119,7 @@ void SoftwareBrowserCompositorOutputSurfaceTest::TearDown() {
std::unique_ptr<content::BrowserCompositorOutputSurface>
SoftwareBrowserCompositorOutputSurfaceTest::CreateSurface(
std::unique_ptr<viz::SoftwareOutputDevice> device) {
- return base::MakeUnique<content::SoftwareBrowserCompositorOutputSurface>(
+ return std::make_unique<content::SoftwareBrowserCompositorOutputSurface>(
std::move(device),
base::Bind(
&SoftwareBrowserCompositorOutputSurfaceTest::UpdateVSyncParameters,
@@ -140,7 +141,7 @@ TEST_F(SoftwareBrowserCompositorOutputSurfaceTest, NoVSyncProvider) {
output_surface_->BindToClient(&output_surface_client);
output_surface_->SwapBuffers(viz::OutputSurfaceFrame());
- EXPECT_EQ(NULL, output_surface_->software_device()->GetVSyncProvider());
+ EXPECT_EQ(nullptr, output_surface_->software_device()->GetVSyncProvider());
EXPECT_EQ(0, update_vsync_parameters_call_count_);
}
diff --git a/chromium/content/browser/compositor/software_output_device_mac.h b/chromium/content/browser/compositor/software_output_device_mac.h
deleted file mode 100644
index 227827e4300..00000000000
--- a/chromium/content/browser/compositor/software_output_device_mac.h
+++ /dev/null
@@ -1,94 +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_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_MAC_H_
-#define CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_MAC_H_
-
-#include <IOSurface/IOSurface.h>
-#include <list>
-
-#include "base/mac/scoped_cftyperef.h"
-#include "base/macros.h"
-#include "components/viz/service/display/software_output_device.h"
-#include "content/common/content_export.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "ui/gfx/vsync_provider.h"
-
-class SkCanvas;
-
-namespace ui {
-class Compositor;
-}
-
-namespace content {
-
-class CONTENT_EXPORT SoftwareOutputDeviceMac : public viz::SoftwareOutputDevice,
- public gfx::VSyncProvider {
- public:
- explicit SoftwareOutputDeviceMac(ui::Compositor* compositor);
- ~SoftwareOutputDeviceMac() override;
-
- // viz::SoftwareOutputDevice implementation.
- void Resize(const gfx::Size& pixel_size, float scale_factor) override;
- SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
- void EndPaint() override;
- void DiscardBackbuffer() override;
- void EnsureBackbuffer() override;
- gfx::VSyncProvider* GetVSyncProvider() override;
-
- // gfx::VSyncProvider implementation.
- void GetVSyncParameters(
- const gfx::VSyncProvider::UpdateVSyncCallback& callback) override;
-
- // Testing methods.
- SkRegion LastCopyRegionForTesting() const {
- return last_copy_region_for_testing_;
- }
- IOSurfaceRef CurrentPaintIOSurfaceForTesting() const {
- return current_paint_buffer_->io_surface.get();
- }
- size_t BufferQueueSizeForTesting() const { return buffer_queue_.size(); }
-
- private:
- struct Buffer {
- Buffer();
- ~Buffer();
- base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
- // The damage of all BeginPaints since this buffer was the back buffer.
- SkRegion accumulated_damage;
- };
-
- // Copy the pixels from the previous buffer to the new buffer, and union
- // |new_damage_rect| into all |buffer_queue_|'s accumulated damages.
- void UpdateAndCopyBufferDamage(Buffer* previous_paint_buffer,
- const SkRegion& new_damage_rect);
-
- ui::Compositor* compositor_ = nullptr;
- gfx::Size pixel_size_;
- float scale_factor_ = 1;
-
- // The queue of buffers. The back is the most recently painted buffer
- // (sometimes equal to |current_paint_buffer_|), and the front is the
- // least recently painted buffer.
- std::list<std::unique_ptr<Buffer>> buffer_queue_;
-
- // A pointer to the last element of |buffer_queue_| during paint. It is only
- // valid between BeginPaint and EndPaint.
- Buffer* current_paint_buffer_ = nullptr;
-
- // The SkCanvas wraps the mapped |current_paint_buffer_|'s IOSurface. It is
- // valid only between BeginPaint and EndPaint.
- std::unique_ptr<SkCanvas> current_paint_canvas_;
-
- gfx::VSyncProvider::UpdateVSyncCallback update_vsync_callback_;
-
- SkRegion last_copy_region_for_testing_;
-
- DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceMac);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_MAC_H_
diff --git a/chromium/content/browser/compositor/software_output_device_mac.mm b/chromium/content/browser/compositor/software_output_device_mac.mm
deleted file mode 100644
index 88c5956c404..00000000000
--- a/chromium/content/browser/compositor/software_output_device_mac.mm
+++ /dev/null
@@ -1,215 +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/browser/compositor/software_output_device_mac.h"
-
-#include "base/mac/foundation_util.h"
-#include "base/trace_event/trace_event.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
-#include "ui/compositor/compositor.h"
-#include "ui/gfx/mac/io_surface.h"
-#include "ui/gfx/skia_util.h"
-
-namespace content {
-
-SoftwareOutputDeviceMac::Buffer::Buffer() = default;
-SoftwareOutputDeviceMac::Buffer::~Buffer() = default;
-
-SoftwareOutputDeviceMac::SoftwareOutputDeviceMac(ui::Compositor* compositor)
- : compositor_(compositor) {}
-
-SoftwareOutputDeviceMac::~SoftwareOutputDeviceMac() {
-}
-
-void SoftwareOutputDeviceMac::Resize(const gfx::Size& pixel_size,
- float scale_factor) {
- if (pixel_size_ == pixel_size && scale_factor_ == scale_factor)
- return;
-
- pixel_size_ = pixel_size;
- scale_factor_ = scale_factor;
-
- DiscardBackbuffer();
-}
-
-void SoftwareOutputDeviceMac::UpdateAndCopyBufferDamage(
- Buffer* previous_paint_buffer,
- const SkRegion& new_damage_region) {
- TRACE_EVENT0("browser", "CopyPreviousBufferDamage");
-
- // Expand the |accumulated_damage| of all buffers to include this frame's
- // damage.
- for (auto& buffer : buffer_queue_)
- buffer->accumulated_damage.op(new_damage_region, SkRegion::kUnion_Op);
-
- // Compute the region to copy from |previous_paint_buffer| to
- // |current_paint_buffer_| by subtracting |new_damage_region| (which we will
- // be painting) from |current_paint_buffer_|'s |accumulated_damage|.
- SkRegion copy_region;
- current_paint_buffer_->accumulated_damage.swap(copy_region);
- bool copy_region_nonempty =
- copy_region.op(new_damage_region, SkRegion::kDifference_Op);
- last_copy_region_for_testing_ = copy_region;
- if (!copy_region_nonempty)
- return;
-
- // If we have anything to copy, we had better have a buffer to copy it from.
- if (!previous_paint_buffer) {
- DLOG(ERROR) << "No previous paint buffer to copy accumulated damage from.";
- last_copy_region_for_testing_.setEmpty();
- return;
- }
-
- // It is possible for |previous_paint_buffer| to equal
- // |current_paint_buffer_|, but if it does, we should not need to do a copy.
- CHECK_NE(previous_paint_buffer, current_paint_buffer_);
-
- IOSurfaceRef previous_io_surface = previous_paint_buffer->io_surface.get();
-
- {
- TRACE_EVENT0("browser", "IOSurfaceLock for software copy");
- IOReturn io_result = IOSurfaceLock(
- previous_io_surface, kIOSurfaceLockReadOnly | kIOSurfaceLockAvoidSync,
- nullptr);
- if (io_result) {
- DLOG(ERROR) << "Failed to lock previous IOSurface " << io_result;
- return;
- }
- }
-
- uint8_t* pixels =
- static_cast<uint8_t*>(IOSurfaceGetBaseAddress(previous_io_surface));
- size_t stride = IOSurfaceGetBytesPerRow(previous_io_surface);
- size_t bytes_per_element = 4;
- for (SkRegion::Iterator it(copy_region); !it.done(); it.next()) {
- const SkIRect& rect = it.rect();
- current_paint_canvas_->writePixels(
- SkImageInfo::MakeN32Premul(rect.width(), rect.height()),
- pixels + bytes_per_element * rect.x() + stride * rect.y(), stride,
- rect.x(), rect.y());
- }
-
- {
- TRACE_EVENT0("browser", "IOSurfaceUnlock");
- IOReturn io_result = IOSurfaceUnlock(
- previous_io_surface, kIOSurfaceLockReadOnly | kIOSurfaceLockAvoidSync,
- nullptr);
- if (io_result)
- DLOG(ERROR) << "Failed to unlock previous IOSurface " << io_result;
- }
-}
-
-SkCanvas* SoftwareOutputDeviceMac::BeginPaint(
- const gfx::Rect& new_damage_rect) {
- // Record the previous paint buffer.
- Buffer* previous_paint_buffer =
- buffer_queue_.empty() ? nullptr : buffer_queue_.back().get();
-
- // Find any buffer in the queue that is not in use by the window server, and
- // re-use it as the buffer for this paint. Note that this can be any buffer in
- // any position in the list.
- for (auto iter = buffer_queue_.begin(); iter != buffer_queue_.end(); ++iter) {
- Buffer* iter_buffer = iter->get();
- if (IOSurfaceIsInUse(iter_buffer->io_surface))
- continue;
- current_paint_buffer_ = iter_buffer;
- buffer_queue_.splice(buffer_queue_.end(), buffer_queue_, iter);
- break;
- }
-
- // If we failed to find a suitable buffer, allocate a new one, and initialize
- // it with complete damage.
- if (!current_paint_buffer_) {
- std::unique_ptr<Buffer> new_buffer(new Buffer);
- new_buffer->io_surface.reset(
- gfx::CreateIOSurface(pixel_size_, gfx::BufferFormat::BGRA_8888));
- if (!new_buffer->io_surface)
- return nullptr;
- // Set the initial damage to be the full buffer.
- new_buffer->accumulated_damage.setRect(
- gfx::RectToSkIRect(gfx::Rect(pixel_size_)));
- current_paint_buffer_ = new_buffer.get();
- buffer_queue_.push_back(std::move(new_buffer));
- }
- DCHECK(current_paint_buffer_);
-
- // Animating in steady-state should require no more than 4 buffers. If we have
- // more than that, then purge the older buffers (the window server will
- // continue to hold on to the IOSurfaces as long as is needed, so the
- // consequence will be extra allocate-free cycles).
- size_t kMaxBuffers = 4;
- while (buffer_queue_.size() > kMaxBuffers)
- buffer_queue_.pop_front();
-
- // Lock the |current_paint_buffer_|'s IOSurface and wrap it in
- // |current_paint_canvas_|.
- {
- TRACE_EVENT0("browser", "IOSurfaceLock for software paint");
- IOReturn io_result = IOSurfaceLock(current_paint_buffer_->io_surface,
- kIOSurfaceLockAvoidSync, nullptr);
- if (io_result) {
- DLOG(ERROR) << "Failed to lock IOSurface " << io_result;
- current_paint_buffer_ = nullptr;
- return nullptr;
- }
- }
- {
- SkPMColor* pixels = static_cast<SkPMColor*>(
- IOSurfaceGetBaseAddress(current_paint_buffer_->io_surface));
- size_t stride = IOSurfaceGetBytesPerRow(current_paint_buffer_->io_surface);
- current_paint_canvas_ = SkCanvas::MakeRasterDirectN32(
- pixel_size_.width(), pixel_size_.height(), pixels, stride);
- }
-
- UpdateAndCopyBufferDamage(previous_paint_buffer,
- SkRegion(gfx::RectToSkIRect(new_damage_rect)));
-
- return current_paint_canvas_.get();
-}
-
-void SoftwareOutputDeviceMac::EndPaint() {
- SoftwareOutputDevice::EndPaint();
- {
- TRACE_EVENT0("browser", "IOSurfaceUnlock");
- IOReturn io_result = IOSurfaceUnlock(current_paint_buffer_->io_surface,
- kIOSurfaceLockAvoidSync, nullptr);
- if (io_result)
- DLOG(ERROR) << "Failed to unlock IOSurface " << io_result;
- }
- current_paint_canvas_.reset();
-
- if (compositor_) {
- ui::AcceleratedWidgetMac* widget =
- ui::AcceleratedWidgetMac::Get(compositor_->widget());
- if (widget) {
- widget->GotIOSurfaceFrame(current_paint_buffer_->io_surface, pixel_size_,
- scale_factor_);
- base::TimeTicks vsync_timebase;
- base::TimeDelta vsync_interval;
- widget->GetVSyncParameters(&vsync_timebase, &vsync_interval);
- if (!update_vsync_callback_.is_null())
- update_vsync_callback_.Run(vsync_timebase, vsync_interval);
- }
- }
-
- current_paint_buffer_ = nullptr;
-}
-
-void SoftwareOutputDeviceMac::DiscardBackbuffer() {
- buffer_queue_.clear();
-}
-
-void SoftwareOutputDeviceMac::EnsureBackbuffer() {}
-
-gfx::VSyncProvider* SoftwareOutputDeviceMac::GetVSyncProvider() {
- return this;
-}
-
-void SoftwareOutputDeviceMac::GetVSyncParameters(
- const gfx::VSyncProvider::UpdateVSyncCallback& callback) {
- update_vsync_callback_ = callback;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/compositor/software_output_device_mac_unittest.mm b/chromium/content/browser/compositor/software_output_device_mac_unittest.mm
deleted file mode 100644
index ab5d95bac43..00000000000
--- a/chromium/content/browser/compositor/software_output_device_mac_unittest.mm
+++ /dev/null
@@ -1,120 +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/browser/compositor/software_output_device_mac.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/skia_util.h"
-
-namespace content {
-
-namespace {
-
-TEST(SoftwareOutputDeviceMacTest, Basics) {
- std::unique_ptr<SoftwareOutputDeviceMac> device(
- new SoftwareOutputDeviceMac(nullptr));
- gfx::Size pixel_size(512, 512);
- float scale_factor = 1;
-
- EXPECT_EQ(device->BufferQueueSizeForTesting(), 0u);
- device->Resize(pixel_size, scale_factor);
-
- // Frame 0.
- gfx::Rect damage0(pixel_size);
- device->BeginPaint(damage0);
- IOSurfaceRef io_surface0 = device->CurrentPaintIOSurfaceForTesting();
- device->EndPaint();
-
- // Frame 1.
- // We didn't set the IOSurface in use, so it should be re-used, and we should
- // have no copy.
- gfx::Rect damage1(10, 10, 10, 10);
- device->BeginPaint(damage1);
- IOSurfaceRef io_surface1 = device->CurrentPaintIOSurfaceForTesting();
- device->EndPaint();
- EXPECT_EQ(io_surface0, io_surface1);
- EXPECT_EQ(device->BufferQueueSizeForTesting(), 1u);
- EXPECT_TRUE(device->LastCopyRegionForTesting().isEmpty());
-
- // Frame 2.
- // The IOSurface is in use, so we should allocate a new one. We'll do a full
- // copy because it's a new buffer.
- IOSurfaceIncrementUseCount(io_surface1);
- gfx::Rect damage2(20, 20, 10, 10);
- device->BeginPaint(damage2);
- IOSurfaceRef io_surface2 = device->CurrentPaintIOSurfaceForTesting();
- device->EndPaint();
- EXPECT_NE(io_surface1, io_surface2);
- EXPECT_EQ(device->BufferQueueSizeForTesting(), 2u);
- SkRegion copy_region2(gfx::RectToSkIRect(gfx::Rect(pixel_size)));
- copy_region2.op(gfx::RectToSkIRect(damage2), SkRegion::kDifference_Op);
- EXPECT_EQ(device->LastCopyRegionForTesting(), copy_region2);
-
- // Frame 3.
- // Both IOSurfaces are in use, so we'll allocate yet a new one and do another
- // full copy.
- IOSurfaceIncrementUseCount(io_surface2);
- gfx::Rect damage3(30, 30, 10, 10);
- device->BeginPaint(damage3);
- IOSurfaceRef io_surface3 = device->CurrentPaintIOSurfaceForTesting();
- device->EndPaint();
- EXPECT_NE(io_surface1, io_surface3);
- EXPECT_NE(io_surface2, io_surface3);
- EXPECT_EQ(device->BufferQueueSizeForTesting(), 3u);
- SkRegion copy_region3(gfx::RectToSkIRect(gfx::Rect(pixel_size)));
- copy_region3.op(gfx::RectToSkIRect(damage3), SkRegion::kDifference_Op);
- EXPECT_EQ(device->LastCopyRegionForTesting(), copy_region3);
-
- // Frame 4.
- // The IOSurface from frame1 is free, so we should re-use it. We should be
- // copying the damage from frame2 and frame3.
- IOSurfaceIncrementUseCount(io_surface3);
- IOSurfaceDecrementUseCount(io_surface1);
- gfx::Rect damage4(35, 35, 15, 15);
- device->BeginPaint(damage4);
- IOSurfaceRef io_surface4 = device->CurrentPaintIOSurfaceForTesting();
- device->EndPaint();
- EXPECT_EQ(io_surface1, io_surface4);
- EXPECT_EQ(device->BufferQueueSizeForTesting(), 3u);
- SkRegion copy_region4;
- copy_region4.op(gfx::RectToSkIRect(damage2), SkRegion::kUnion_Op);
- copy_region4.op(gfx::RectToSkIRect(damage3), SkRegion::kUnion_Op);
- copy_region4.op(gfx::RectToSkIRect(damage4), SkRegion::kDifference_Op);
- EXPECT_EQ(device->LastCopyRegionForTesting(), copy_region4);
-
- // Frame 5.
- // All IOSurfaces are allocated, allocate another.
- IOSurfaceIncrementUseCount(io_surface4);
- gfx::Rect damage5(50, 50, 10, 10);
- device->BeginPaint(damage5);
- IOSurfaceRef io_surface5 = device->CurrentPaintIOSurfaceForTesting();
- EXPECT_NE(io_surface5, io_surface2);
- EXPECT_NE(io_surface5, io_surface3);
- EXPECT_NE(io_surface5, io_surface4);
- device->EndPaint();
- EXPECT_EQ(device->BufferQueueSizeForTesting(), 4u);
-
- // Frame 6.
- // All IOSurfaces are in use, allocate another, but free the one from frame2
- // (add an extra retain and check to retain count to verify that it steps
- // down).
- IOSurfaceIncrementUseCount(io_surface5);
- CFRetain(io_surface2);
- EXPECT_EQ(CFGetRetainCount(io_surface2), 2u);
- gfx::Rect damage6(60, 60, 10, 10);
- device->BeginPaint(damage6);
- IOSurfaceRef io_surface6 = device->CurrentPaintIOSurfaceForTesting();
- device->EndPaint();
- EXPECT_EQ(device->BufferQueueSizeForTesting(), 4u);
- EXPECT_NE(io_surface6, io_surface2);
- EXPECT_NE(io_surface6, io_surface3);
- EXPECT_NE(io_surface6, io_surface4);
- EXPECT_NE(io_surface6, io_surface5);
- EXPECT_EQ(CFGetRetainCount(io_surface2), 1u);
- CFRelease(io_surface2);
-}
-
-} // namespace
-
-} // namespace content
diff --git a/chromium/content/browser/compositor/software_output_device_ozone.cc b/chromium/content/browser/compositor/software_output_device_ozone.cc
deleted file mode 100644
index da854ec419d..00000000000
--- a/chromium/content/browser/compositor/software_output_device_ozone.cc
+++ /dev/null
@@ -1,71 +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/browser/compositor/software_output_device_ozone.h"
-
-#include <memory>
-
-#include "ui/compositor/compositor.h"
-#include "ui/gfx/skia_util.h"
-#include "ui/gfx/vsync_provider.h"
-#include "ui/ozone/public/ozone_platform.h"
-#include "ui/ozone/public/surface_factory_ozone.h"
-#include "ui/ozone/public/surface_ozone_canvas.h"
-
-namespace content {
-
-// static
-std::unique_ptr<SoftwareOutputDeviceOzone> SoftwareOutputDeviceOzone::Create(
- ui::Compositor* compositor) {
- std::unique_ptr<SoftwareOutputDeviceOzone> result(
- new SoftwareOutputDeviceOzone(compositor));
- if (!result->surface_ozone_)
- return nullptr;
- return result;
-}
-
-SoftwareOutputDeviceOzone::SoftwareOutputDeviceOzone(ui::Compositor* compositor)
- : compositor_(compositor) {
- ui::SurfaceFactoryOzone* factory =
- ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone();
-
- surface_ozone_ = factory->CreateCanvasForWidget(compositor_->widget());
-
- if (!surface_ozone_) {
- LOG(ERROR) << "Failed to initialize canvas";
- return;
- }
-
- vsync_provider_ = surface_ozone_->CreateVSyncProvider();
-}
-
-SoftwareOutputDeviceOzone::~SoftwareOutputDeviceOzone() {
-}
-
-void SoftwareOutputDeviceOzone::Resize(const gfx::Size& viewport_pixel_size,
- float scale_factor) {
- if (viewport_pixel_size_ == viewport_pixel_size)
- return;
-
- viewport_pixel_size_ = viewport_pixel_size;
-
- surface_ozone_->ResizeCanvas(viewport_pixel_size_);
-}
-
-SkCanvas* SoftwareOutputDeviceOzone::BeginPaint(const gfx::Rect& damage_rect) {
- DCHECK(gfx::Rect(viewport_pixel_size_).Contains(damage_rect));
-
- // Get canvas for next frame.
- surface_ = surface_ozone_->GetSurface();
-
- return SoftwareOutputDevice::BeginPaint(damage_rect);
-}
-
-void SoftwareOutputDeviceOzone::EndPaint() {
- SoftwareOutputDevice::EndPaint();
-
- surface_ozone_->PresentCanvas(damage_rect_);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/compositor/software_output_device_ozone.h b/chromium/content/browser/compositor/software_output_device_ozone.h
deleted file mode 100644
index 5e6b9e5470f..00000000000
--- a/chromium/content/browser/compositor/software_output_device_ozone.h
+++ /dev/null
@@ -1,48 +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_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_OZONE_H_
-#define CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_OZONE_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "components/viz/service/display/software_output_device.h"
-#include "content/common/content_export.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace ui {
-class Compositor;
-class SurfaceOzoneCanvas;
-}
-
-namespace content {
-
-// Ozone implementation which relies on software rendering. Ozone will present
-// an accelerated widget as a SkCanvas. SoftwareOutputDevice will then use the
-// Ozone provided canvas to draw.
-class CONTENT_EXPORT SoftwareOutputDeviceOzone
- : public viz::SoftwareOutputDevice {
- public:
- static std::unique_ptr<SoftwareOutputDeviceOzone> Create(
- ui::Compositor* compositor);
- ~SoftwareOutputDeviceOzone() override;
-
- void Resize(const gfx::Size& viewport_pixel_size,
- float scale_factor) override;
- SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
- void EndPaint() override;
-
- private:
- explicit SoftwareOutputDeviceOzone(ui::Compositor* compositor);
- ui::Compositor* compositor_;
-
- std::unique_ptr<ui::SurfaceOzoneCanvas> surface_ozone_;
-
- DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceOzone);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_OZONE_H_
diff --git a/chromium/content/browser/compositor/software_output_device_ozone_unittest.cc b/chromium/content/browser/compositor/software_output_device_ozone_unittest.cc
deleted file mode 100644
index 2b34384e78e..00000000000
--- a/chromium/content/browser/compositor/software_output_device_ozone_unittest.cc
+++ /dev/null
@@ -1,153 +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/browser/compositor/software_output_device_ozone.h"
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/compositor/compositor.h"
-#include "ui/compositor/test/context_factories_for_test.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/skia_util.h"
-#include "ui/gfx/vsync_provider.h"
-#include "ui/gl/gl_implementation.h"
-#include "ui/ozone/public/ozone_platform.h"
-#include "ui/ozone/public/surface_ozone_canvas.h"
-#include "ui/platform_window/platform_window.h"
-#include "ui/platform_window/platform_window_delegate.h"
-
-namespace {
-
-class TestPlatformWindowDelegate : public ui::PlatformWindowDelegate {
- public:
- TestPlatformWindowDelegate() : widget_(gfx::kNullAcceleratedWidget) {}
- ~TestPlatformWindowDelegate() override {}
-
- gfx::AcceleratedWidget GetAcceleratedWidget() const { return widget_; }
-
- // ui::PlatformWindowDelegate:
- void OnBoundsChanged(const gfx::Rect& new_bounds) override {}
- void OnDamageRect(const gfx::Rect& damaged_region) override {}
- void DispatchEvent(ui::Event* event) override {}
- void OnCloseRequest() override {}
- void OnClosed() override {}
- void OnWindowStateChanged(ui::PlatformWindowState new_state) override {}
- void OnLostCapture() override {}
- void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget,
- float device_pixel_ratio) override {
- widget_ = widget;
- }
- void OnAcceleratedWidgetDestroyed() override {
- NOTREACHED();
- }
- void OnActivationChanged(bool active) override {}
-
- private:
- gfx::AcceleratedWidget widget_;
-
- DISALLOW_COPY_AND_ASSIGN(TestPlatformWindowDelegate);
-};
-
-} // namespace
-
-class SoftwareOutputDeviceOzoneTest : public testing::Test {
- public:
- SoftwareOutputDeviceOzoneTest();
- ~SoftwareOutputDeviceOzoneTest() override;
-
- void SetUp() override;
- void TearDown() override;
-
- protected:
- std::unique_ptr<content::SoftwareOutputDeviceOzone> output_device_;
- bool enable_pixel_output_ = false;
-
- private:
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- std::unique_ptr<ui::Compositor> compositor_;
- TestPlatformWindowDelegate window_delegate_;
- std::unique_ptr<ui::PlatformWindow> window_;
-
- DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceOzoneTest);
-};
-
-SoftwareOutputDeviceOzoneTest::SoftwareOutputDeviceOzoneTest()
- : scoped_task_environment_(
- base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
-
-SoftwareOutputDeviceOzoneTest::~SoftwareOutputDeviceOzoneTest() {
-}
-
-void SoftwareOutputDeviceOzoneTest::SetUp() {
- ui::ContextFactory* context_factory = nullptr;
- ui::ContextFactoryPrivate* context_factory_private = nullptr;
- ui::InitializeContextFactoryForTests(enable_pixel_output_, &context_factory,
- &context_factory_private);
-
- const gfx::Size size(500, 400);
- window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow(
- &window_delegate_, gfx::Rect(size));
- compositor_.reset(
- new ui::Compositor(viz::FrameSinkId(1, 1), context_factory, nullptr,
- base::ThreadTaskRunnerHandle::Get(),
- false /* enable_surface_synchronization */,
- false /* enable_pixel_canvas */));
- compositor_->SetAcceleratedWidget(window_delegate_.GetAcceleratedWidget());
- compositor_->SetScaleAndSize(1.0f, size);
-
- output_device_ =
- content::SoftwareOutputDeviceOzone::Create(compositor_.get());
- if (output_device_)
- output_device_->Resize(size, 1.f);
-}
-
-void SoftwareOutputDeviceOzoneTest::TearDown() {
- output_device_.reset();
- compositor_.reset();
- window_.reset();
- ui::TerminateContextFactoryForTests();
-}
-
-class SoftwareOutputDeviceOzonePixelTest
- : public SoftwareOutputDeviceOzoneTest {
- protected:
- void SetUp() override;
-};
-
-void SoftwareOutputDeviceOzonePixelTest::SetUp() {
- enable_pixel_output_ = true;
- SoftwareOutputDeviceOzoneTest::SetUp();
-}
-
-TEST_F(SoftwareOutputDeviceOzoneTest, CheckCorrectResizeBehavior) {
- // Check if software rendering mode is not supported.
- if (!output_device_)
- return;
-
- gfx::Rect damage(0, 0, 100, 100);
- gfx::Size size(200, 100);
- // Reduce size.
- output_device_->Resize(size, 1.f);
-
- SkCanvas* canvas = output_device_->BeginPaint(damage);
- gfx::Size canvas_size(canvas->getBaseLayerSize().width(),
- canvas->getBaseLayerSize().height());
- EXPECT_EQ(size.ToString(), canvas_size.ToString());
-
- size.SetSize(1000, 500);
- // Increase size.
- output_device_->Resize(size, 1.f);
-
- canvas = output_device_->BeginPaint(damage);
- canvas_size.SetSize(canvas->getBaseLayerSize().width(),
- canvas->getBaseLayerSize().height());
- EXPECT_EQ(size.ToString(), canvas_size.ToString());
-
-}
-
diff --git a/chromium/content/browser/compositor/software_output_device_win.cc b/chromium/content/browser/compositor/software_output_device_win.cc
deleted file mode 100644
index e1a99680697..00000000000
--- a/chromium/content/browser/compositor/software_output_device_win.cc
+++ /dev/null
@@ -1,206 +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/browser/compositor/software_output_device_win.h"
-
-#include "base/debug/alias.h"
-#include "base/memory/shared_memory.h"
-#include "components/viz/common/quads/shared_bitmap.h"
-#include "content/public/browser/browser_thread.h"
-#include "skia/ext/platform_canvas.h"
-#include "skia/ext/skia_utils_win.h"
-#include "ui/base/win/internal_constants.h"
-#include "ui/compositor/compositor.h"
-#include "ui/gfx/gdi_util.h"
-#include "ui/gfx/skia_util.h"
-
-namespace content {
-
-// If a window is larger than this in bytes, don't even try to create a
-// backing bitmap for it.
-static const size_t kMaxBitmapSizeBytes = 4 * (16384 * 8192);
-
-OutputDeviceBacking::OutputDeviceBacking() : created_byte_size_(0) {
-}
-
-OutputDeviceBacking::~OutputDeviceBacking() {
- DCHECK(devices_.empty());
-}
-
-void OutputDeviceBacking::Resized() {
- size_t new_size = GetMaxByteSize();
- if (new_size == created_byte_size_)
- return;
- for (SoftwareOutputDeviceWin* device : devices_) {
- device->ReleaseContents();
- }
- backing_.reset();
- created_byte_size_ = 0;
-}
-
-void OutputDeviceBacking::RegisterOutputDevice(
- SoftwareOutputDeviceWin* device) {
- devices_.push_back(device);
-}
-
-void OutputDeviceBacking::UnregisterOutputDevice(
- SoftwareOutputDeviceWin* device) {
- auto it = std::find(devices_.begin(), devices_.end(), device);
- DCHECK(it != devices_.end());
- devices_.erase(it);
- Resized();
-}
-
-base::SharedMemory* OutputDeviceBacking::GetSharedMemory(
- const gfx::Size& size) {
- if (backing_)
- return backing_.get();
- size_t expected_byte_size = GetMaxByteSize();
- size_t required_size;
- if (!viz::SharedBitmap::SizeInBytes(size, &required_size))
- return nullptr;
- if (required_size > expected_byte_size)
- return nullptr;
-
- created_byte_size_ = expected_byte_size;
-
- backing_.reset(new base::SharedMemory);
- base::debug::Alias(&expected_byte_size);
- CHECK(backing_->CreateAnonymous(created_byte_size_));
- return backing_.get();
-}
-
-size_t OutputDeviceBacking::GetMaxByteSize() {
- // Minimum byte size is 1 because creating a 0-byte-long SharedMemory fails.
- size_t max_size = 1;
- for (const SoftwareOutputDeviceWin* device : devices_) {
- size_t current_size;
- if (!viz::SharedBitmap::SizeInBytes(device->viewport_pixel_size(),
- &current_size))
- continue;
- if (current_size > kMaxBitmapSizeBytes)
- continue;
- max_size = std::max(max_size, current_size);
- }
- return max_size;
-}
-
-SoftwareOutputDeviceWin::SoftwareOutputDeviceWin(OutputDeviceBacking* backing,
- ui::Compositor* compositor)
- : hwnd_(compositor->widget()),
- is_hwnd_composited_(false),
- backing_(backing),
- in_paint_(false) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- is_hwnd_composited_ = !!::GetProp(hwnd_, ui::kWindowTranslucent);
- // Layered windows must be completely updated every time, so they can't
- // share contents with other windows.
- if (is_hwnd_composited_)
- backing_ = nullptr;
- if (backing_)
- backing_->RegisterOutputDevice(this);
-}
-
-SoftwareOutputDeviceWin::~SoftwareOutputDeviceWin() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(!in_paint_);
- if (backing_)
- backing_->UnregisterOutputDevice(this);
-}
-
-void SoftwareOutputDeviceWin::Resize(const gfx::Size& viewport_pixel_size,
- float scale_factor) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(!in_paint_);
-
- if (viewport_pixel_size_ == viewport_pixel_size)
- return;
-
- viewport_pixel_size_ = viewport_pixel_size;
- if (backing_)
- backing_->Resized();
- contents_.reset();
-}
-
-SkCanvas* SoftwareOutputDeviceWin::BeginPaint(const gfx::Rect& damage_rect) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(!in_paint_);
- if (!contents_) {
- HANDLE shared_section = NULL;
- bool can_create_contents = true;
- if (backing_) {
- base::SharedMemory* memory =
- backing_->GetSharedMemory(viewport_pixel_size_);
- if (memory) {
- shared_section = memory->handle().GetHandle();
- } else {
- can_create_contents = false;
- }
- }
- if (can_create_contents) {
- contents_ = skia::CreatePlatformCanvasWithSharedSection(
- viewport_pixel_size_.width(), viewport_pixel_size_.height(), true,
- shared_section, skia::CRASH_ON_FAILURE);
- }
- }
-
- damage_rect_ = damage_rect;
- in_paint_ = true;
- return contents_.get();
-}
-
-void SoftwareOutputDeviceWin::EndPaint() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(in_paint_);
-
- in_paint_ = false;
- SoftwareOutputDevice::EndPaint();
-
- if (!contents_)
- return;
-
- gfx::Rect rect = damage_rect_;
- rect.Intersect(gfx::Rect(viewport_pixel_size_));
- if (rect.IsEmpty())
- return;
-
- HDC dib_dc = skia::GetNativeDrawingContext(contents_.get());
-
- if (is_hwnd_composited_) {
- RECT wr;
- GetWindowRect(hwnd_, &wr);
- SIZE size = {wr.right - wr.left, wr.bottom - wr.top};
- POINT position = {wr.left, wr.top};
- POINT zero = {0, 0};
- BLENDFUNCTION blend = {AC_SRC_OVER, 0x00, 0xFF, AC_SRC_ALPHA};
-
- DWORD style = GetWindowLong(hwnd_, GWL_EXSTYLE);
- DCHECK(!(style & WS_EX_COMPOSITED));
- style |= WS_EX_LAYERED;
- SetWindowLong(hwnd_, GWL_EXSTYLE, style);
-
- ::UpdateLayeredWindow(hwnd_, NULL, &position, &size, dib_dc, &zero,
- RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA);
- } else {
- HDC hdc = ::GetDC(hwnd_);
- RECT src_rect = rect.ToRECT();
- skia::CopyHDC(dib_dc,
- hdc,
- rect.x(),
- rect.y(),
- contents_.get()->imageInfo().isOpaque(),
- src_rect,
- contents_.get()->getTotalMatrix());
-
- ::ReleaseDC(hwnd_, hdc);
- }
-}
-
-void SoftwareOutputDeviceWin::ReleaseContents() {
- DCHECK(!in_paint_);
- contents_.reset();
-}
-
-} // namespace content
diff --git a/chromium/content/browser/compositor/software_output_device_win.h b/chromium/content/browser/compositor/software_output_device_win.h
deleted file mode 100644
index 3713d21bdfc..00000000000
--- a/chromium/content/browser/compositor/software_output_device_win.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_WIN_H_
-#define CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_WIN_H_
-
-#include <stddef.h>
-#include <windows.h>
-
-#include <memory>
-#include <vector>
-
-#include "base/macros.h"
-#include "components/viz/service/display/software_output_device.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
-
-namespace base {
-class SharedMemory;
-}
-
-namespace ui {
-class Compositor;
-}
-
-namespace content {
-class SoftwareOutputDeviceWin;
-
-class OutputDeviceBacking {
- public:
- OutputDeviceBacking();
- ~OutputDeviceBacking();
-
- void Resized();
- void RegisterOutputDevice(SoftwareOutputDeviceWin* device);
- void UnregisterOutputDevice(SoftwareOutputDeviceWin* device);
- base::SharedMemory* GetSharedMemory(const gfx::Size& size);
-
- private:
- size_t GetMaxByteSize();
-
- std::vector<SoftwareOutputDeviceWin*> devices_;
- std::unique_ptr<base::SharedMemory> backing_;
- size_t created_byte_size_;
-
- DISALLOW_COPY_AND_ASSIGN(OutputDeviceBacking);
-};
-
-class SoftwareOutputDeviceWin : public viz::SoftwareOutputDevice {
- public:
- SoftwareOutputDeviceWin(OutputDeviceBacking* backing,
- ui::Compositor* compositor);
- ~SoftwareOutputDeviceWin() override;
-
- void Resize(const gfx::Size& viewport_pixel_size,
- float scale_factor) override;
- SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
- void EndPaint() override;
-
- gfx::Size viewport_pixel_size() const { return viewport_pixel_size_; }
- void ReleaseContents();
-
- private:
- HWND hwnd_;
- std::unique_ptr<SkCanvas> contents_;
- bool is_hwnd_composited_;
- OutputDeviceBacking* backing_;
- bool in_paint_;
-
- DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceWin);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_WIN_H_
diff --git a/chromium/content/browser/compositor/software_output_device_x11.cc b/chromium/content/browser/compositor/software_output_device_x11.cc
deleted file mode 100644
index d2e6606166f..00000000000
--- a/chromium/content/browser/compositor/software_output_device_x11.cc
+++ /dev/null
@@ -1,128 +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/browser/compositor/software_output_device_x11.h"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#include "content/public/browser/browser_thread.h"
-#include "third_party/skia/include/core/SkImageInfo.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/base/x/x11_util_internal.h"
-#include "ui/compositor/compositor.h"
-#include "ui/gfx/x/x11_types.h"
-
-namespace content {
-
-SoftwareOutputDeviceX11::SoftwareOutputDeviceX11(ui::Compositor* compositor)
- : compositor_(compositor), display_(gfx::GetXDisplay()), gc_(NULL) {
- // TODO(skaslev) Remove this when crbug.com/180702 is fixed.
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- gc_ = XCreateGC(display_, compositor_->widget(), 0, NULL);
- if (!XGetWindowAttributes(display_, compositor_->widget(), &attributes_)) {
- LOG(ERROR) << "XGetWindowAttributes failed for window "
- << compositor_->widget();
- return;
- }
-}
-
-SoftwareOutputDeviceX11::~SoftwareOutputDeviceX11() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- XFreeGC(display_, gc_);
-}
-
-void SoftwareOutputDeviceX11::EndPaint() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- SoftwareOutputDevice::EndPaint();
-
- if (!surface_)
- return;
-
- gfx::Rect rect = damage_rect_;
- rect.Intersect(gfx::Rect(viewport_pixel_size_));
- if (rect.IsEmpty())
- return;
-
- int bpp = gfx::BitsPerPixelForPixmapDepth(display_, attributes_.depth);
-
- if (bpp != 32 && bpp != 16 && ui::QueryRenderSupport(display_)) {
- // gfx::PutARGBImage only supports 16 and 32 bpp, but Xrender can do other
- // conversions.
- Pixmap pixmap = XCreatePixmap(
- display_, compositor_->widget(), rect.width(), rect.height(), 32);
- GC gc = XCreateGC(display_, pixmap, 0, NULL);
- XImage image;
- memset(&image, 0, sizeof(image));
-
- SkPixmap skia_pixmap;
- surface_->peekPixels(&skia_pixmap);
- image.width = viewport_pixel_size_.width();
- image.height = viewport_pixel_size_.height();
- image.depth = 32;
- image.bits_per_pixel = 32;
- image.format = ZPixmap;
- image.byte_order = LSBFirst;
- image.bitmap_unit = 8;
- image.bitmap_bit_order = LSBFirst;
- image.bytes_per_line = skia_pixmap.rowBytes();
- image.red_mask = 0xff;
- image.green_mask = 0xff00;
- image.blue_mask = 0xff0000;
- image.data = const_cast<char*>(static_cast<const char*>(
- skia_pixmap.addr()));
-
- XPutImage(display_,
- pixmap,
- gc,
- &image,
- rect.x(),
- rect.y() /* source x, y */,
- 0,
- 0 /* dest x, y */,
- rect.width(),
- rect.height());
- XFreeGC(display_, gc);
- Picture picture = XRenderCreatePicture(
- display_, pixmap, ui::GetRenderARGB32Format(display_), 0, NULL);
- XRenderPictFormat* pictformat =
- XRenderFindVisualFormat(display_, attributes_.visual);
- Picture dest_picture = XRenderCreatePicture(
- display_, compositor_->widget(), pictformat, 0, NULL);
- XRenderComposite(display_,
- PictOpSrc, // op
- picture, // src
- 0, // mask
- dest_picture, // dest
- 0, // src_x
- 0, // src_y
- 0, // mask_x
- 0, // mask_y
- rect.x(), // dest_x
- rect.y(), // dest_y
- rect.width(), // width
- rect.height()); // height
- XRenderFreePicture(display_, picture);
- XRenderFreePicture(display_, dest_picture);
- XFreePixmap(display_, pixmap);
- return;
- }
-
- // TODO(jbauman): Switch to XShmPutImage since it's async.
- SkPixmap pixmap;
- surface_->peekPixels(&pixmap);
- gfx::PutARGBImage(
- display_, attributes_.visual, attributes_.depth, compositor_->widget(),
- gc_, static_cast<const uint8_t*>(pixmap.addr()),
- viewport_pixel_size_.width(), viewport_pixel_size_.height(), rect.x(),
- rect.y(), rect.x(), rect.y(), rect.width(), rect.height());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/compositor/software_output_device_x11.h b/chromium/content/browser/compositor/software_output_device_x11.h
deleted file mode 100644
index 26db31bb49a..00000000000
--- a/chromium/content/browser/compositor/software_output_device_x11.h
+++ /dev/null
@@ -1,39 +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_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_X11_H_
-#define CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_X11_H_
-
-#include <X11/Xlib.h>
-
-#include "base/macros.h"
-#include "components/viz/service/display/software_output_device.h"
-#include "ui/gfx/x/x11_types.h"
-
-namespace ui {
-class Compositor;
-}
-
-namespace content {
-
-class SoftwareOutputDeviceX11 : public viz::SoftwareOutputDevice {
- public:
- explicit SoftwareOutputDeviceX11(ui::Compositor* compositor);
-
- ~SoftwareOutputDeviceX11() override;
-
- void EndPaint() override;
-
- private:
- ui::Compositor* compositor_;
- XDisplay* display_;
- GC gc_;
- XWindowAttributes attributes_;
-
- DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceX11);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_X11_H_
diff --git a/chromium/content/browser/compositor/surface_utils.cc b/chromium/content/browser/compositor/surface_utils.cc
index 618fe2334e2..bebc99902c3 100644
--- a/chromium/content/browser/compositor/surface_utils.cc
+++ b/chromium/content/browser/compositor/surface_utils.cc
@@ -60,18 +60,23 @@ void PrepareTextureCopyOutputResult(
const SkColorType color_type,
const content::ReadbackRequestCallback& callback,
std::unique_ptr<viz::CopyOutputResult> result) {
+ base::ScopedClosureRunner scoped_callback_runner(
+ base::BindOnce(callback, SkBitmap(), content::READBACK_FAILED));
+
#if defined(OS_ANDROID) && !defined(USE_AURA)
// TODO(wjmaclean): See if there's an equivalent pathway for Android and
// implement it here.
- callback.Run(SkBitmap(), content::READBACK_FAILED);
+ return;
#else
- base::ScopedClosureRunner scoped_callback_runner(
- base::BindOnce(callback, SkBitmap(), content::READBACK_FAILED));
+
+ DCHECK_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE);
+ if (result->IsEmpty())
+ return;
// TODO(siva.gunturi): We should be able to validate the format here using
// GLHelper::IsReadbackConfigSupported before we processs the result.
// See crbug.com/415682 and crbug.com/415131.
- std::unique_ptr<SkBitmap> bitmap(new SkBitmap);
+ auto bitmap = std::make_unique<SkBitmap>();
if (!bitmap->tryAllocPixels(SkImageInfo::Make(
dst_size_in_pixel.width(), dst_size_in_pixel.height(), color_type,
kOpaque_SkAlphaType))) {
@@ -88,20 +93,16 @@ void PrepareTextureCopyOutputResult(
uint8_t* pixels = static_cast<uint8_t*>(bitmap->getPixels());
- viz::TextureMailbox texture_mailbox;
- std::unique_ptr<viz::SingleReleaseCallback> release_callback;
- if (auto* mailbox = result->GetTextureMailbox()) {
- texture_mailbox = *mailbox;
- release_callback = result->TakeTextureOwnership();
- }
- if (!texture_mailbox.IsTexture())
- return;
+ gpu::Mailbox mailbox = result->GetTextureResult()->mailbox;
+ gpu::SyncToken sync_token = result->GetTextureResult()->sync_token;
+ std::unique_ptr<viz::SingleReleaseCallback> release_callback =
+ result->TakeTextureOwnership();
ignore_result(scoped_callback_runner.Release());
gl_helper->CropScaleReadbackAndCleanMailbox(
- texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(),
- dst_size_in_pixel, pixels, color_type,
+ mailbox, sync_token, result->size(), dst_size_in_pixel, pixels,
+ color_type,
base::Bind(&CopyFromCompositingSurfaceFinished, callback,
base::Passed(&release_callback), base::Passed(&bitmap)),
viz::GLHelper::SCALER_QUALITY_GOOD);
@@ -224,6 +225,12 @@ void CopyFromCompositingSurfaceHasResult(
PrepareBitmapCopyOutputResult(output_size_in_pixel, color_type, callback,
std::move(result));
break;
+
+ case viz::CopyOutputResult::Format::I420_PLANES:
+ // No code path external to the VIZ component should have asked for this.
+ NOTREACHED();
+ callback.Run(SkBitmap(), READBACK_FAILED);
+ break;
}
}
diff --git a/chromium/content/browser/compositor/viz_process_transport_factory.cc b/chromium/content/browser/compositor/viz_process_transport_factory.cc
new file mode 100644
index 00000000000..7c85001610a
--- /dev/null
+++ b/chromium/content/browser/compositor/viz_process_transport_factory.cc
@@ -0,0 +1,488 @@
+// Copyright 2017 The Chromium Authors. 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/compositor/viz_process_transport_factory.h"
+
+#include <utility>
+
+#include "base/command_line.h"
+#include "base/single_thread_task_runner.h"
+#include "cc/raster/single_thread_task_graph_runner.h"
+#include "components/viz/client/client_layer_tree_frame_sink.h"
+#include "components/viz/client/local_surface_id_provider.h"
+#include "components/viz/common/features.h"
+#include "components/viz/common/gpu/context_provider.h"
+#include "components/viz/host/forwarding_compositing_mode_reporter_impl.h"
+#include "components/viz/host/host_frame_sink_manager.h"
+#include "components/viz/host/renderer_settings_creation.h"
+#include "content/browser/browser_main_loop.h"
+#include "content/browser/browser_thread_impl.h"
+#include "content/browser/gpu/compositor_util.h"
+#include "content/browser/gpu/gpu_process_host.h"
+#include "content/common/gpu_stream_constants.h"
+#include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/context_result.h"
+#include "gpu/ipc/client/gpu_channel_host.h"
+#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
+#include "ui/compositor/reflector.h"
+
+namespace content {
+namespace {
+
+// The client id for the browser process. It must not conflict with any
+// child process client id.
+constexpr uint32_t kBrowserClientId = 0u;
+
+scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextProviderImpl(
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
+ bool support_locking,
+ ui::ContextProviderCommandBuffer* shared_context_provider,
+ ui::command_buffer_metrics::ContextType type) {
+ constexpr bool kAutomaticFlushes = false;
+
+ gpu::gles2::ContextCreationAttribHelper attributes;
+ attributes.alpha_size = -1;
+ attributes.depth_size = 0;
+ attributes.stencil_size = 0;
+ attributes.samples = 0;
+ attributes.sample_buffers = 0;
+ attributes.bind_generates_resource = false;
+ attributes.lose_context_when_out_of_memory = true;
+ attributes.buffer_preserved = false;
+
+ GURL url("chrome://gpu/VizProcessTransportFactory::CreateContextProvider");
+ return base::MakeRefCounted<ui::ContextProviderCommandBuffer>(
+ std::move(gpu_channel_host), kGpuStreamIdDefault, kGpuStreamPriorityUI,
+ gpu::kNullSurfaceHandle, std::move(url), kAutomaticFlushes,
+ support_locking, gpu::SharedMemoryLimits(), attributes,
+ shared_context_provider, type);
+}
+
+bool CheckContextLost(viz::ContextProvider* context_provider) {
+ if (!context_provider)
+ return false;
+
+ auto status = context_provider->ContextGL()->GetGraphicsResetStatusKHR();
+ return status != GL_NO_ERROR;
+}
+
+} // namespace
+
+VizProcessTransportFactory::VizProcessTransportFactory(
+ gpu::GpuChannelEstablishFactory* gpu_channel_establish_factory,
+ scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner,
+ viz::ForwardingCompositingModeReporterImpl* forwarding_mode_reporter)
+ : gpu_channel_establish_factory_(gpu_channel_establish_factory),
+ resize_task_runner_(std::move(resize_task_runner)),
+ forwarding_mode_reporter_(forwarding_mode_reporter),
+ frame_sink_id_allocator_(kBrowserClientId),
+ task_graph_runner_(std::make_unique<cc::SingleThreadTaskGraphRunner>()),
+ renderer_settings_(
+ viz::CreateRendererSettings(CreateBufferToTextureTargetMap())),
+ compositing_mode_watcher_binding_(this),
+ weak_ptr_factory_(this) {
+ DCHECK(gpu_channel_establish_factory_);
+ task_graph_runner_->Start("CompositorTileWorker1",
+ base::SimpleThread::Options());
+ GetHostFrameSinkManager()->SetConnectionLostCallback(
+ base::BindRepeating(&VizProcessTransportFactory::OnGpuProcessLost,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kDisableGpu) ||
+ command_line->HasSwitch(switches::kDisableGpuCompositing)) {
+ CompositingModeFallbackToSoftware();
+ } else {
+ // Make |this| a CompositingModeWatcher for the |forwarding_mode_reporter_|.
+ viz::mojom::CompositingModeWatcherPtr watcher_ptr;
+ compositing_mode_watcher_binding_.Bind(mojo::MakeRequest(&watcher_ptr));
+ forwarding_mode_reporter_->AddCompositingModeWatcher(
+ std::move(watcher_ptr));
+ }
+}
+
+VizProcessTransportFactory::~VizProcessTransportFactory() {
+ task_graph_runner_->Shutdown();
+}
+
+void VizProcessTransportFactory::ConnectHostFrameSinkManager() {
+ viz::mojom::FrameSinkManagerPtr frame_sink_manager;
+ viz::mojom::FrameSinkManagerRequest frame_sink_manager_request =
+ mojo::MakeRequest(&frame_sink_manager);
+ viz::mojom::FrameSinkManagerClientPtr frame_sink_manager_client;
+ viz::mojom::FrameSinkManagerClientRequest frame_sink_manager_client_request =
+ mojo::MakeRequest(&frame_sink_manager_client);
+
+ // Setup HostFrameSinkManager with interface endpoints.
+ GetHostFrameSinkManager()->BindAndSetManager(
+ std::move(frame_sink_manager_client_request), resize_task_runner_,
+ std::move(frame_sink_manager));
+
+ // The ForwardingCompositingModeReporterImpl wants to watch the reporter in
+ // the viz process. We give a mojo pointer to it over to that process and have
+ // the viz process connect it to the reporter there directly, instead of
+ // requesting a pointer to that reporter from this process.
+ viz::mojom::CompositingModeWatcherPtr mode_watch_ptr =
+ forwarding_mode_reporter_->BindAsWatcher();
+
+ // Hop to the IO thread, then send the other side of interface to viz process.
+ auto connect_on_io_thread =
+ [](viz::mojom::FrameSinkManagerRequest request,
+ viz::mojom::FrameSinkManagerClientPtrInfo client,
+ viz::mojom::CompositingModeWatcherPtrInfo mode_watcher) {
+ // TODO(kylechar): Check GpuProcessHost isn't null but don't enter a
+ // restart loop.
+ GpuProcessHost::Get()->ConnectFrameSinkManager(
+ std::move(request), std::move(client), std::move(mode_watcher));
+ };
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(connect_on_io_thread,
+ std::move(frame_sink_manager_request),
+ frame_sink_manager_client.PassInterface(),
+ mode_watch_ptr.PassInterface()));
+}
+
+void VizProcessTransportFactory::CreateLayerTreeFrameSink(
+ base::WeakPtr<ui::Compositor> compositor) {
+ if (is_gpu_compositing_disabled_ || compositor->force_software_compositor()) {
+ OnEstablishedGpuChannel(compositor, nullptr);
+ return;
+ }
+ gpu_channel_establish_factory_->EstablishGpuChannel(
+ base::Bind(&VizProcessTransportFactory::OnEstablishedGpuChannel,
+ weak_ptr_factory_.GetWeakPtr(), compositor));
+}
+
+scoped_refptr<viz::ContextProvider>
+VizProcessTransportFactory::SharedMainThreadContextProvider() {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+void VizProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
+ compositor_data_map_.erase(compositor);
+}
+
+double VizProcessTransportFactory::GetRefreshRate() const {
+ // TODO(kylechar): Delete this function from ContextFactoryPrivate.
+ return 60.0;
+}
+
+gpu::GpuMemoryBufferManager*
+VizProcessTransportFactory::GetGpuMemoryBufferManager() {
+ return gpu_channel_establish_factory_->GetGpuMemoryBufferManager();
+}
+
+cc::TaskGraphRunner* VizProcessTransportFactory::GetTaskGraphRunner() {
+ return task_graph_runner_.get();
+}
+
+const viz::ResourceSettings& VizProcessTransportFactory::GetResourceSettings()
+ const {
+ return renderer_settings_.resource_settings;
+}
+
+void VizProcessTransportFactory::AddObserver(
+ ui::ContextFactoryObserver* observer) {
+ observer_list_.AddObserver(observer);
+}
+
+void VizProcessTransportFactory::RemoveObserver(
+ ui::ContextFactoryObserver* observer) {
+ observer_list_.RemoveObserver(observer);
+}
+
+std::unique_ptr<ui::Reflector> VizProcessTransportFactory::CreateReflector(
+ ui::Compositor* source,
+ ui::Layer* target) {
+ // TODO(crbug.com/601869): Reflector needs to be rewritten for viz.
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+void VizProcessTransportFactory::RemoveReflector(ui::Reflector* reflector) {
+ // TODO(crbug.com/601869): Reflector needs to be rewritten for viz.
+ NOTIMPLEMENTED();
+}
+
+viz::FrameSinkId VizProcessTransportFactory::AllocateFrameSinkId() {
+ return frame_sink_id_allocator_.NextFrameSinkId();
+}
+
+viz::HostFrameSinkManager*
+VizProcessTransportFactory::GetHostFrameSinkManager() {
+ return BrowserMainLoop::GetInstance()->host_frame_sink_manager();
+}
+
+void VizProcessTransportFactory::SetDisplayVisible(ui::Compositor* compositor,
+ bool visible) {
+ auto iter = compositor_data_map_.find(compositor);
+ if (iter == compositor_data_map_.end() || !iter->second.display_private)
+ return;
+ iter->second.display_private->SetDisplayVisible(visible);
+}
+
+void VizProcessTransportFactory::ResizeDisplay(ui::Compositor* compositor,
+ const gfx::Size& size) {
+ // Do nothing and resize when a CompositorFrame with a new size arrives.
+}
+
+void VizProcessTransportFactory::SetDisplayColorSpace(
+ ui::Compositor* compositor,
+ const gfx::ColorSpace& blending_color_space,
+ const gfx::ColorSpace& output_color_space) {
+ auto iter = compositor_data_map_.find(compositor);
+ if (iter == compositor_data_map_.end() || !iter->second.display_private)
+ return;
+ iter->second.display_private->SetDisplayColorSpace(blending_color_space,
+ output_color_space);
+}
+
+void VizProcessTransportFactory::SetAuthoritativeVSyncInterval(
+ ui::Compositor* compositor,
+ base::TimeDelta interval) {
+ auto iter = compositor_data_map_.find(compositor);
+ if (iter == compositor_data_map_.end() || !iter->second.display_private)
+ return;
+ iter->second.display_private->SetAuthoritativeVSyncInterval(interval);
+}
+
+void VizProcessTransportFactory::SetDisplayVSyncParameters(
+ ui::Compositor* compositor,
+ base::TimeTicks timebase,
+ base::TimeDelta interval) {
+ // TODO(crbug.com/772524): Deal with vsync later.
+ NOTIMPLEMENTED();
+}
+
+void VizProcessTransportFactory::IssueExternalBeginFrame(
+ ui::Compositor* compositor,
+ const viz::BeginFrameArgs& args) {
+ // TODO(crbug.com/772524): Deal with vsync later.
+ NOTIMPLEMENTED();
+}
+
+void VizProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor,
+ bool secure) {
+ auto iter = compositor_data_map_.find(compositor);
+ if (iter == compositor_data_map_.end() || !iter->second.display_private)
+ return;
+ iter->second.display_private->SetOutputIsSecure(secure);
+}
+
+viz::FrameSinkManagerImpl* VizProcessTransportFactory::GetFrameSinkManager() {
+ // FrameSinkManagerImpl is in the gpu process, not the browser process.
+ NOTREACHED();
+ return nullptr;
+}
+
+bool VizProcessTransportFactory::IsGpuCompositingDisabled() {
+ return is_gpu_compositing_disabled_;
+}
+
+ui::ContextFactory* VizProcessTransportFactory::GetContextFactory() {
+ return this;
+}
+
+ui::ContextFactoryPrivate*
+VizProcessTransportFactory::GetContextFactoryPrivate() {
+ return this;
+}
+
+viz::GLHelper* VizProcessTransportFactory::GetGLHelper() {
+ // TODO(kylechar): Figure out if GLHelper in the host process makes sense.
+ NOTREACHED();
+ return nullptr;
+}
+
+#if defined(OS_MACOSX)
+void VizProcessTransportFactory::SetCompositorSuspendedForRecycle(
+ ui::Compositor* compositor,
+ bool suspended) {
+ NOTIMPLEMENTED();
+}
+#endif
+
+void VizProcessTransportFactory::CompositingModeFallbackToSoftware() {
+ // This may happen multiple times, since when the viz process (re)starts, it
+ // will send this notification if gpu is disabled.
+ if (is_gpu_compositing_disabled_)
+ return;
+
+ // Change the result of IsGpuCompositingDisabled() before notifying anything.
+ is_gpu_compositing_disabled_ = true;
+
+ // Consumers of the shared main thread context aren't CompositingModeWatchers,
+ // so inform them about the compositing mode switch by acting like the context
+ // was lost. This also destroys the contexts since they aren't created when
+ // gpu compositing isn't being used.
+ OnLostMainThreadSharedContext();
+
+ // Drop our reference on the gpu contexts for the compositors.
+ shared_worker_context_provider_ = nullptr;
+ compositor_context_provider_ = nullptr;
+
+ // Here we remove the FrameSink from every compositor that needs to fall back
+ // to software compositing.
+ //
+ // Releasing the FrameSink from the compositor will remove it from
+ // |compositor_data_map_|, so we can't do that while iterating though the
+ // collection.
+ std::vector<ui::Compositor*> to_release;
+ to_release.reserve(compositor_data_map_.size());
+ for (auto& pair : compositor_data_map_) {
+ ui::Compositor* compositor = pair.first;
+ if (!compositor->force_software_compositor())
+ to_release.push_back(compositor);
+ }
+ for (ui::Compositor* compositor : to_release) {
+ // Compositor expects to be not visible when releasing its FrameSink.
+ bool visible = compositor->IsVisible();
+ compositor->SetVisible(false);
+ gfx::AcceleratedWidget widget = compositor->ReleaseAcceleratedWidget();
+ compositor->SetAcceleratedWidget(widget);
+ if (visible)
+ compositor->SetVisible(true);
+ }
+}
+
+void VizProcessTransportFactory::OnGpuProcessLost() {
+ // Reconnect HostFrameSinkManager to new GPU process.
+ ConnectHostFrameSinkManager();
+
+ OnLostMainThreadSharedContext();
+}
+
+void VizProcessTransportFactory::OnEstablishedGpuChannel(
+ base::WeakPtr<ui::Compositor> compositor_weak_ptr,
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
+ ui::Compositor* compositor = compositor_weak_ptr.get();
+ if (!compositor)
+ return;
+
+ bool gpu_compositing =
+ !is_gpu_compositing_disabled_ && !compositor->force_software_compositor();
+
+ // Only try to make contexts for gpu compositing.
+ if (gpu_compositing) {
+ if (!gpu_channel_host ||
+ !CreateContextProviders(std::move(gpu_channel_host))) {
+ // Retry on failure. If this isn't possible we should hear that we're
+ // falling back to software compositing from the viz process eventually.
+ gpu_channel_establish_factory_->EstablishGpuChannel(
+ base::Bind(&VizProcessTransportFactory::OnEstablishedGpuChannel,
+ weak_ptr_factory_.GetWeakPtr(), compositor_weak_ptr));
+ return;
+ }
+ }
+
+ // TODO(crbug.com/776050): Deal with context loss.
+
+ // Create interfaces for a root CompositorFrameSink.
+ viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info;
+ viz::mojom::CompositorFrameSinkAssociatedRequest sink_request =
+ mojo::MakeRequest(&sink_info);
+ viz::mojom::CompositorFrameSinkClientPtr client;
+ viz::mojom::CompositorFrameSinkClientRequest client_request =
+ mojo::MakeRequest(&client);
+ viz::mojom::DisplayPrivateAssociatedRequest display_private_request =
+ mojo::MakeRequest(&compositor_data_map_[compositor].display_private);
+
+#if defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW)
+ gpu::SurfaceHandle surface_handle = compositor->widget();
+#else
+ // TODO(kylechar): Fix this when we support macOS.
+ gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
+#endif
+
+ // Creates the viz end of the root CompositorFrameSink.
+ // TODO(crbug.com/730660): If compositor->force_software_compositor() then
+ // make a software-based RootCompositorFrameSink.
+ GetHostFrameSinkManager()->CreateRootCompositorFrameSink(
+ compositor->frame_sink_id(), surface_handle, renderer_settings_,
+ std::move(sink_request), std::move(client),
+ std::move(display_private_request));
+
+ // Create LayerTreeFrameSink with the browser end of CompositorFrameSink.
+ viz::ClientLayerTreeFrameSink::InitParams params;
+ params.gpu_memory_buffer_manager = GetGpuMemoryBufferManager();
+ params.pipes.compositor_frame_sink_associated_info = std::move(sink_info);
+ params.pipes.client_request = std::move(client_request);
+ params.local_surface_id_provider =
+ std::make_unique<viz::DefaultLocalSurfaceIdProvider>();
+ params.enable_surface_synchronization =
+ features::IsSurfaceSynchronizationEnabled();
+
+ scoped_refptr<ui::ContextProviderCommandBuffer> compositor_context;
+ scoped_refptr<ui::ContextProviderCommandBuffer> worker_context;
+ if (gpu_compositing) {
+ // Only pass the contexts to the compositor if it will use gpu compositing.
+ compositor_context = compositor_context_provider_;
+ worker_context = shared_worker_context_provider_;
+ }
+ compositor->SetLayerTreeFrameSink(
+ std::make_unique<viz::ClientLayerTreeFrameSink>(
+ std::move(compositor_context), std::move(worker_context), &params));
+}
+
+bool VizProcessTransportFactory::CreateContextProviders(
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
+ constexpr bool kSharedWorkerContextSupportsLocking = true;
+ constexpr bool kCompositorContextSupportsLocking = false;
+
+ if (CheckContextLost(compositor_context_provider_.get())) {
+ // Both will be lost because they are in the same share group.
+ shared_worker_context_provider_ = nullptr;
+ compositor_context_provider_ = nullptr;
+ }
+
+ if (!shared_worker_context_provider_) {
+ shared_worker_context_provider_ = CreateContextProviderImpl(
+ gpu_channel_host, kSharedWorkerContextSupportsLocking, nullptr,
+ ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT);
+
+ auto result = shared_worker_context_provider_->BindToCurrentThread();
+ if (result != gpu::ContextResult::kSuccess) {
+ shared_worker_context_provider_ = nullptr;
+ return false;
+ }
+ }
+
+ if (!compositor_context_provider_) {
+ compositor_context_provider_ = CreateContextProviderImpl(
+ std::move(gpu_channel_host), kCompositorContextSupportsLocking,
+ shared_worker_context_provider_.get(),
+ ui::command_buffer_metrics::UI_COMPOSITOR_CONTEXT);
+ compositor_context_provider_->SetDefaultTaskRunner(resize_task_runner_);
+
+ auto result = compositor_context_provider_->BindToCurrentThread();
+ if (result != gpu::ContextResult::kSuccess) {
+ compositor_context_provider_ = nullptr;
+ shared_worker_context_provider_ = nullptr;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void VizProcessTransportFactory::OnLostMainThreadSharedContext() {
+ // TODO(danakj): When we implement making the shared context, we'll also
+ // have to recreate it here before calling OnLostResources().
+ for (auto& observer : observer_list_)
+ observer.OnLostResources();
+}
+
+VizProcessTransportFactory::CompositorData::CompositorData() = default;
+VizProcessTransportFactory::CompositorData::CompositorData(
+ CompositorData&& other) = default;
+VizProcessTransportFactory::CompositorData::~CompositorData() = default;
+VizProcessTransportFactory::CompositorData&
+VizProcessTransportFactory::CompositorData::operator=(CompositorData&& other) =
+ default;
+
+} // namespace content
diff --git a/chromium/content/browser/compositor/viz_process_transport_factory.h b/chromium/content/browser/compositor/viz_process_transport_factory.h
new file mode 100644
index 00000000000..8a48b5524eb
--- /dev/null
+++ b/chromium/content/browser/compositor/viz_process_transport_factory.h
@@ -0,0 +1,177 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_COMPOSITOR_VIZ_PROCESS_TRANSPORT_FACTORY_H_
+#define CONTENT_BROWSER_COMPOSITOR_VIZ_PROCESS_TRANSPORT_FACTORY_H_
+
+#include <memory>
+
+#include "base/containers/flat_map.h"
+#include "base/macros.h"
+#include "build/build_config.h"
+#include "components/viz/common/display/renderer_settings.h"
+#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
+#include "content/browser/compositor/image_transport_factory.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h"
+#include "services/viz/public/interfaces/compositing/compositing_mode_watcher.mojom.h"
+#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
+#include "ui/compositor/compositor.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace cc {
+class SingleThreadTaskGraphRunner;
+}
+
+namespace gpu {
+class GpuChannelEstablishFactory;
+}
+
+namespace ui {
+class ContextProviderCommandBuffer;
+}
+
+namespace viz {
+class ForwardingCompositingModeReporterImpl;
+}
+
+namespace content {
+
+// A replacement for GpuProcessTransportFactory to be used when running viz. In
+// this configuration the display compositor is located in the viz process
+// instead of in the browser process. Any interaction with the display
+// compositor must happen over IPC.
+class VizProcessTransportFactory : public ui::ContextFactory,
+ public ui::ContextFactoryPrivate,
+ public ImageTransportFactory,
+ public viz::mojom::CompositingModeWatcher {
+ public:
+ VizProcessTransportFactory(
+ gpu::GpuChannelEstablishFactory* gpu_channel_establish_factory,
+ scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner,
+ viz::ForwardingCompositingModeReporterImpl* forwarding_mode_reporter);
+ ~VizProcessTransportFactory() override;
+
+ // Connects HostFrameSinkManager to FrameSinkManagerImpl in viz process.
+ void ConnectHostFrameSinkManager();
+
+ // ui::ContextFactory implementation.
+ void CreateLayerTreeFrameSink(
+ base::WeakPtr<ui::Compositor> compositor) override;
+ scoped_refptr<viz::ContextProvider> SharedMainThreadContextProvider()
+ override;
+ void RemoveCompositor(ui::Compositor* compositor) override;
+ double GetRefreshRate() const override;
+ gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
+ cc::TaskGraphRunner* GetTaskGraphRunner() override;
+ const viz::ResourceSettings& GetResourceSettings() const override;
+ void AddObserver(ui::ContextFactoryObserver* observer) override;
+ void RemoveObserver(ui::ContextFactoryObserver* observer) override;
+
+ // ui::ContextFactoryPrivate implementation.
+ std::unique_ptr<ui::Reflector> CreateReflector(ui::Compositor* source,
+ ui::Layer* target) override;
+ void RemoveReflector(ui::Reflector* reflector) override;
+ viz::FrameSinkId AllocateFrameSinkId() override;
+ viz::HostFrameSinkManager* GetHostFrameSinkManager() override;
+ void SetDisplayVisible(ui::Compositor* compositor, bool visible) override;
+ void ResizeDisplay(ui::Compositor* compositor,
+ const gfx::Size& size) override;
+ 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;
+ void IssueExternalBeginFrame(ui::Compositor* compositor,
+ const viz::BeginFrameArgs& args) override;
+ void SetOutputIsSecure(ui::Compositor* compositor, bool secure) override;
+ viz::FrameSinkManagerImpl* GetFrameSinkManager() override;
+
+ // ImageTransportFactory implementation.
+ bool IsGpuCompositingDisabled() override;
+ ui::ContextFactory* GetContextFactory() override;
+ ui::ContextFactoryPrivate* GetContextFactoryPrivate() override;
+ viz::GLHelper* GetGLHelper() override;
+#if defined(OS_MACOSX)
+ void SetCompositorSuspendedForRecycle(ui::Compositor* compositor,
+ bool suspended) override;
+#endif
+
+ // viz::mojom::CompositingModeWatcher implementation.
+ void CompositingModeFallbackToSoftware() override;
+
+ private:
+ struct CompositorData {
+ CompositorData();
+ CompositorData(CompositorData&& other);
+ ~CompositorData();
+ CompositorData& operator=(CompositorData&& other);
+
+ // Privileged interface that controls the display for a root
+ // CompositorFrameSink.
+ viz::mojom::DisplayPrivateAssociatedPtr display_private;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CompositorData);
+ };
+
+ // Provided as a callback when the GPU process has crashed.
+ void OnGpuProcessLost();
+
+ // Finishes creation of LayerTreeFrameSink after GPU channel has been
+ // established.
+ void OnEstablishedGpuChannel(
+ base::WeakPtr<ui::Compositor> compositor_weak_ptr,
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel);
+
+ // Creates the necessary shared worker and compositor ContextProviders. If the
+ // ContextProviders already exist and haven't been lost then it will do
+ // nothing. Returns true if ContextProviders exist.
+ bool CreateContextProviders(
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host);
+
+ void OnLostMainThreadSharedContext();
+
+ gpu::GpuChannelEstablishFactory* const gpu_channel_establish_factory_;
+ scoped_refptr<base::SingleThreadTaskRunner> const resize_task_runner_;
+ // Acts as a proxy from the mojo connection to the authoritive
+ // |compositing_mode_reporter_|. This will forward the state on to clients of
+ // the browser process (eg the renderers). Since the browser process is not
+ // restartable, it prevents these clients from having to reconnect to their
+ // CompositingModeReporter.
+ viz::ForwardingCompositingModeReporterImpl* const forwarding_mode_reporter_;
+
+ base::flat_map<ui::Compositor*, CompositorData> compositor_data_map_;
+ bool is_gpu_compositing_disabled_ = false;
+
+ // TODO(kylechar): Call OnContextLost() on observers when GPU crashes.
+ base::ObserverList<ui::ContextFactoryObserver> observer_list_;
+
+ scoped_refptr<ui::ContextProviderCommandBuffer>
+ shared_worker_context_provider_;
+ scoped_refptr<ui::ContextProviderCommandBuffer> compositor_context_provider_;
+
+ viz::FrameSinkIdAllocator frame_sink_id_allocator_;
+ std::unique_ptr<cc::SingleThreadTaskGraphRunner> task_graph_runner_;
+ const viz::RendererSettings renderer_settings_;
+
+ // The class is a CompositingModeWatcher, which is bound to mojo through
+ // this member.
+ mojo::Binding<viz::mojom::CompositingModeWatcher>
+ compositing_mode_watcher_binding_;
+
+ base::WeakPtrFactory<VizProcessTransportFactory> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(VizProcessTransportFactory);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_COMPOSITOR_VIZ_PROCESS_TRANSPORT_FACTORY_H_
diff --git a/chromium/content/browser/cross_site_transfer_browsertest.cc b/chromium/content/browser/cross_site_transfer_browsertest.cc
index f18e9930b0c..d8348f3bf02 100644
--- a/chromium/content/browser/cross_site_transfer_browsertest.cc
+++ b/chromium/content/browser/cross_site_transfer_browsertest.cc
@@ -62,7 +62,7 @@ class TrackingResourceDispatcherHostDelegate
ASSERT_FALSE(throttle_created_);
// If this is a request for the tracked URL, add a throttle to track it.
if (request->url() == tracked_url_)
- throttles->push_back(base::MakeUnique<TrackingThrottle>(request, this));
+ throttles->push_back(std::make_unique<TrackingThrottle>(request, this));
}
// Starts tracking a URL. The request for previously tracked URL, if any,
diff --git a/chromium/content/browser/dedicated_worker/OWNERS b/chromium/content/browser/dedicated_worker/OWNERS
new file mode 100644
index 00000000000..eb8bfba6870
--- /dev/null
+++ b/chromium/content/browser/dedicated_worker/OWNERS
@@ -0,0 +1,4 @@
+nhiroki@chromium.org
+
+# TEAM: worker-dev@chromium.org
+# COMPONENT: Blink>Workers
diff --git a/chromium/content/browser/dedicated_worker/README.md b/chromium/content/browser/dedicated_worker/README.md
new file mode 100644
index 00000000000..a11d35f3c4e
--- /dev/null
+++ b/chromium/content/browser/dedicated_worker/README.md
@@ -0,0 +1,8 @@
+# Dedicated Worker Host
+
+`content/browser/dedicated_worker` implements the host side of dedicated worker.
+It tracks the security principal of the worker in the renderer and uses it to
+broker access to mojo interfaces providing powerful web APIs. See: [Design
+doc].
+
+[Design doc]: https://docs.google.com/document/d/1Bg84lQqeJ8D2J-_wOOLlRVAtZNMstEUHmVhJqCxpjUk/edit?usp=sharing
diff --git a/chromium/content/browser/dedicated_worker/dedicated_worker_host.cc b/chromium/content/browser/dedicated_worker/dedicated_worker_host.cc
new file mode 100644
index 00000000000..aa6d1c3c33e
--- /dev/null
+++ b/chromium/content/browser/dedicated_worker/dedicated_worker_host.cc
@@ -0,0 +1,88 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+#include <utility>
+
+#include "content/browser/dedicated_worker/dedicated_worker_host.h"
+
+#include "content/browser/interface_provider_filtering.h"
+#include "content/browser/renderer_interface_binders.h"
+#include "content/public/browser/render_process_host.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
+#include "url/origin.h"
+
+namespace content {
+namespace {
+
+// A host for a single dedicated worker. Its lifetime is managed by the
+// DedicatedWorkerGlobalScope of the corresponding worker in the renderer via a
+// StrongBinding.
+class DedicatedWorkerHost : public service_manager::mojom::InterfaceProvider {
+ public:
+ DedicatedWorkerHost(int process_id, const url::Origin& origin)
+ : process_id_(process_id), origin_(origin) {}
+
+ // service_manager::mojom::InterfaceProvider:
+ void GetInterface(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) override {
+ RenderProcessHost* process = RenderProcessHost::FromID(process_id_);
+ if (!process)
+ return;
+
+ BindWorkerInterface(interface_name, std::move(interface_pipe), process,
+ origin_);
+ }
+
+ private:
+ const int process_id_;
+ const url::Origin origin_;
+
+ DISALLOW_COPY_AND_ASSIGN(DedicatedWorkerHost);
+};
+
+// A factory for creating DedicatedWorkerHosts. Its lifetime is managed by
+// the renderer over mojo via a StrongBinding.
+class DedicatedWorkerFactoryImpl : public blink::mojom::DedicatedWorkerFactory {
+ public:
+ DedicatedWorkerFactoryImpl(int process_id,
+ const url::Origin& parent_context_origin)
+ : process_id_(process_id),
+ parent_context_origin_(parent_context_origin) {}
+
+ // blink::mojom::DedicatedWorkerFactory:
+ void CreateDedicatedWorker(
+ const url::Origin& origin,
+ service_manager::mojom::InterfaceProviderRequest request) override {
+ // TODO(crbug.com/729021): Once |parent_context_origin_| is no longer races
+ // with the request for |DedicatedWorkerFactory|, enforce that the worker's
+ // origin either matches the creating document's origin, or is unique.
+ mojo::MakeStrongBinding(
+ std::make_unique<DedicatedWorkerHost>(process_id_, origin),
+ FilterRendererExposedInterfaces(
+ blink::mojom::kNavigation_DedicatedWorkerSpec, process_id_,
+ std::move(request)));
+ }
+
+ private:
+ const int process_id_;
+ const url::Origin parent_context_origin_;
+
+ DISALLOW_COPY_AND_ASSIGN(DedicatedWorkerFactoryImpl);
+};
+
+} // namespace
+
+void CreateDedicatedWorkerHostFactory(
+ blink::mojom::DedicatedWorkerFactoryRequest request,
+ RenderProcessHost* host,
+ const url::Origin& origin) {
+ mojo::MakeStrongBinding(
+ std::make_unique<DedicatedWorkerFactoryImpl>(host->GetID(), origin),
+ std::move(request));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/dedicated_worker/dedicated_worker_host.h b/chromium/content/browser/dedicated_worker/dedicated_worker_host.h
new file mode 100644
index 00000000000..514a483e8f1
--- /dev/null
+++ b/chromium/content/browser/dedicated_worker/dedicated_worker_host.h
@@ -0,0 +1,24 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEDICATED_WORKER_DEDICATED_WORKER_HOST_H_
+#define CONTENT_BROWSER_DEDICATED_WORKER_DEDICATED_WORKER_HOST_H_
+
+#include "third_party/WebKit/public/platform/dedicated_worker_factory.mojom.h"
+
+namespace url {
+class Origin;
+}
+
+namespace content {
+class RenderProcessHost;
+
+void CreateDedicatedWorkerHostFactory(
+ blink::mojom::DedicatedWorkerFactoryRequest request,
+ RenderProcessHost* host,
+ const url::Origin& origin);
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEDICATED_WORKER_DEDICATED_WORKER_HOST_H_
diff --git a/chromium/content/browser/device_sensors/device_sensor_browsertest.cc b/chromium/content/browser/device_sensors/device_sensor_browsertest.cc
index 06f0d2c5234..eb2fffce7a0 100644
--- a/chromium/content/browser/device_sensors/device_sensor_browsertest.cc
+++ b/chromium/content/browser/device_sensors/device_sensor_browsertest.cc
@@ -14,9 +14,12 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
+#include "components/network_session_configurator/common/network_switches.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/content_switches.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_navigation_observer.h"
@@ -30,6 +33,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/buffer.h"
+#include "net/dns/mock_host_resolver.h"
#include "services/device/public/cpp/generic_sensor/platform_sensor_configuration.h"
#include "services/device/public/cpp/generic_sensor/sensor_reading.h"
#include "services/device/public/interfaces/constants.mojom.h"
@@ -296,7 +300,7 @@ class FakeSensorProvider : public device::mojom::SensorProvider {
switch (type) {
case device::mojom::SensorType::ACCELEROMETER:
if (accelerometer_is_available_) {
- sensor = base::MakeUnique<FakeSensor>(
+ sensor = std::make_unique<FakeSensor>(
device::mojom::SensorType::ACCELEROMETER);
reading.accel.x = 4;
reading.accel.y = 5;
@@ -305,7 +309,7 @@ class FakeSensorProvider : public device::mojom::SensorProvider {
break;
case device::mojom::SensorType::LINEAR_ACCELERATION:
if (linear_acceleration_sensor_is_available_) {
- sensor = base::MakeUnique<FakeSensor>(
+ sensor = std::make_unique<FakeSensor>(
device::mojom::SensorType::LINEAR_ACCELERATION);
reading.accel.x = 1;
reading.accel.y = 2;
@@ -314,7 +318,7 @@ class FakeSensorProvider : public device::mojom::SensorProvider {
break;
case device::mojom::SensorType::GYROSCOPE:
if (gyroscope_is_available_) {
- sensor = base::MakeUnique<FakeSensor>(
+ sensor = std::make_unique<FakeSensor>(
device::mojom::SensorType::GYROSCOPE);
reading.gyro.x = 7;
reading.gyro.y = 8;
@@ -359,6 +363,16 @@ class DeviceSensorBrowserTest : public ContentBrowserTest {
base::WaitableEvent::InitialState::NOT_SIGNALED) {}
void SetUpOnMainThread() override {
+ https_embedded_test_server_.reset(
+ new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS));
+ // Serve both a.com and b.com (and any other domain).
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(https_embedded_test_server_->InitializeAndListen());
+ content::SetupCrossSiteRedirector(https_embedded_test_server_.get());
+ https_embedded_test_server_->ServeFilesFromSourceDirectory(
+ "content/test/data/device_sensors");
+ https_embedded_test_server_->StartAcceptingConnections();
+
// Initialize the RunLoops now that the main thread has been created.
orientation_started_runloop_.reset(new base::RunLoop());
orientation_stopped_runloop_.reset(new base::RunLoop());
@@ -376,6 +390,12 @@ class DeviceSensorBrowserTest : public ContentBrowserTest {
io_loop_finished_event_.Wait();
}
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ // HTTPS server only serves a valid cert for localhost, so this is needed
+ // to load pages from other hosts without an error.
+ command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
+ }
+
void SetUpFetcher() {
fetcher_ = new FakeDataFetcher();
fetcher_->SetOrientationStartedCallback(
@@ -425,6 +445,7 @@ class DeviceSensorBrowserTest : public ContentBrowserTest {
FakeDataFetcher* fetcher_;
std::unique_ptr<FakeSensorProvider> sensor_provider_;
+ std::unique_ptr<net::EmbeddedTestServer> https_embedded_test_server_;
// NOTE: These can only be initialized once the main thread has been created
// and so must be pointers instead of plain objects.
@@ -513,8 +534,9 @@ IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, MotionNullTest) {
EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
}
+// Disabled due to flakiness: https://crbug.com/783891
IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest,
- MotionOnlySomeSensorsAreAvailableTest) {
+ DISABLED_MotionOnlySomeSensorsAreAvailableTest) {
// The test page registers an event handler for motion events and
// expects to get an event with only the gyroscope and linear acceleration
// sensor values, because no accelerometer values can be provided.
@@ -553,6 +575,52 @@ IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, NullTestWithAlert) {
EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
}
+IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest,
+ DeviceMotionCrossOriginIframeTest) {
+ // Main frame is on a.com, iframe is on b.com.
+ GURL main_frame_url =
+ https_embedded_test_server_->GetURL("a.com", "/cross_origin_iframe.html");
+ GURL iframe_url =
+ https_embedded_test_server_->GetURL("b.com", "/device_motion_test.html");
+
+ // Wait for the main frame, subframe, and the #pass/#fail commits.
+ TestNavigationObserver navigation_observer(shell()->web_contents(), 3);
+
+ EXPECT_TRUE(NavigateToURL(shell(), main_frame_url));
+ EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(),
+ "cross_origin_iframe", iframe_url));
+
+ navigation_observer.Wait();
+
+ content::RenderFrameHost* iframe =
+ ChildFrameAt(shell()->web_contents()->GetMainFrame(), 0);
+ ASSERT_TRUE(iframe);
+ EXPECT_EQ("pass", iframe->GetLastCommittedURL().ref());
+}
+
+IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest,
+ DeviceOrientationCrossOriginIframeTest) {
+ // Main frame is on a.com, iframe is on b.com.
+ GURL main_frame_url =
+ https_embedded_test_server_->GetURL("a.com", "/cross_origin_iframe.html");
+ GURL iframe_url = https_embedded_test_server_->GetURL(
+ "b.com", "/device_orientation_test.html");
+
+ // Wait for the main frame, subframe, and the #pass/#fail commits.
+ TestNavigationObserver navigation_observer(shell()->web_contents(), 3);
+
+ EXPECT_TRUE(NavigateToURL(shell(), main_frame_url));
+ EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(),
+ "cross_origin_iframe", iframe_url));
+
+ navigation_observer.Wait();
+
+ content::RenderFrameHost* iframe =
+ ChildFrameAt(shell()->web_contents()->GetMainFrame(), 0);
+ ASSERT_TRUE(iframe);
+ EXPECT_EQ("pass", iframe->GetLastCommittedURL().ref());
+}
+
} // namespace
} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_agent_host_impl.cc b/chromium/content/browser/devtools/devtools_agent_host_impl.cc
index 87e2259d1c4..d7c072cc667 100644
--- a/chromium/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/chromium/content/browser/devtools/devtools_agent_host_impl.cc
@@ -30,11 +30,12 @@
namespace content {
namespace {
-typedef std::map<std::string, DevToolsAgentHostImpl*> Instances;
-base::LazyInstance<Instances>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER;
+typedef std::map<std::string, DevToolsAgentHostImpl*> DevToolsMap;
+base::LazyInstance<DevToolsMap>::Leaky g_devtools_instances =
+ LAZY_INSTANCE_INITIALIZER;
base::LazyInstance<base::ObserverList<DevToolsAgentHostObserver>>::Leaky
- g_observers = LAZY_INSTANCE_INITIALIZER;
+ g_devtools_observers = LAZY_INSTANCE_INITIALIZER;
} // namespace
const char DevToolsAgentHost::kTypePage[] = "page";
@@ -77,28 +78,14 @@ DevToolsAgentHost::List DevToolsAgentHost::GetOrCreateAll() {
#if DCHECK_IS_ON()
for (auto it : result) {
DevToolsAgentHostImpl* host = static_cast<DevToolsAgentHostImpl*>(it.get());
- DCHECK(g_instances.Get().find(host->id_) != g_instances.Get().end());
+ DCHECK(g_devtools_instances.Get().find(host->id_) !=
+ g_devtools_instances.Get().end());
}
#endif
return result;
}
-// Called on the UI thread.
-// static
-scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForWorker(
- int worker_process_id,
- int worker_route_id) {
- if (scoped_refptr<DevToolsAgentHost> host =
- SharedWorkerDevToolsManager::GetInstance()
- ->GetDevToolsAgentHostForWorker(worker_process_id,
- worker_route_id)) {
- return host;
- }
- return ServiceWorkerDevToolsManager::GetInstance()
- ->GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id);
-}
-
DevToolsAgentHostImpl::DevToolsAgentHostImpl(const std::string& id) : id_(id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
@@ -111,11 +98,11 @@ DevToolsAgentHostImpl::~DevToolsAgentHostImpl() {
// static
scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForId(
const std::string& id) {
- if (g_instances == NULL)
- return NULL;
- Instances::iterator it = g_instances.Get().find(id);
- if (it == g_instances.Get().end())
- return NULL;
+ if (g_devtools_instances == nullptr)
+ return nullptr;
+ DevToolsMap::iterator it = g_devtools_instances.Get().find(id);
+ if (it == g_devtools_instances.Get().end())
+ return nullptr;
return it->second;
}
@@ -167,7 +154,7 @@ void DevToolsAgentHostImpl::ForceAttachClient(DevToolsAgentHostClient* client) {
return;
scoped_refptr<DevToolsAgentHostImpl> protect(this);
if (!sessions_.empty())
- ForceDetachAllClients(true);
+ ForceDetachAllClients();
DCHECK(sessions_.empty());
InnerAttachClient(client);
}
@@ -262,7 +249,7 @@ BrowserContext* DevToolsAgentHostImpl::GetBrowserContext() {
}
WebContents* DevToolsAgentHostImpl::GetWebContents() {
- return NULL;
+ return nullptr;
}
void DevToolsAgentHostImpl::DisconnectWebContents() {
@@ -280,19 +267,19 @@ bool DevToolsAgentHostImpl::Inspect() {
return false;
}
-void DevToolsAgentHostImpl::ForceDetachAllClients(bool replaced) {
+void DevToolsAgentHostImpl::ForceDetachAllClients() {
scoped_refptr<DevToolsAgentHostImpl> protect(this);
while (!session_by_client_.empty()) {
DevToolsAgentHostClient* client = session_by_client_.begin()->first;
InnerDetachClient(client);
- client->AgentHostClosed(this, replaced);
+ client->AgentHostClosed(this);
}
}
void DevToolsAgentHostImpl::ForceDetachSession(DevToolsSession* session) {
DevToolsAgentHostClient* client = session->client();
InnerDetachClient(client);
- client->AgentHostClosed(this, false);
+ client->AgentHostClosed(this);
}
void DevToolsAgentHostImpl::InspectElement(
@@ -303,15 +290,15 @@ void DevToolsAgentHostImpl::InspectElement(
// static
void DevToolsAgentHost::DetachAllClients() {
- if (g_instances == NULL)
+ if (g_devtools_instances == nullptr)
return;
// Make a copy, since detaching may lead to agent destruction, which
// removes it from the instances.
- Instances copy = g_instances.Get();
- for (Instances::iterator it(copy.begin()); it != copy.end(); ++it) {
+ DevToolsMap copy = g_devtools_instances.Get();
+ for (DevToolsMap::iterator it(copy.begin()); it != copy.end(); ++it) {
DevToolsAgentHostImpl* agent_host = it->second;
- agent_host->ForceDetachAllClients(true);
+ agent_host->ForceDetachAllClients();
}
}
@@ -325,8 +312,8 @@ void DevToolsAgentHost::AddObserver(DevToolsAgentHostObserver* observer) {
DevToolsAgentHostImpl::s_force_creation_count_++;
}
- g_observers.Get().AddObserver(observer);
- for (const auto& id_host : g_instances.Get())
+ g_devtools_observers.Get().AddObserver(observer);
+ for (const auto& id_host : g_devtools_instances.Get())
observer->DevToolsAgentHostCreated(id_host.second);
}
@@ -334,7 +321,7 @@ void DevToolsAgentHost::AddObserver(DevToolsAgentHostObserver* observer) {
void DevToolsAgentHost::RemoveObserver(DevToolsAgentHostObserver* observer) {
if (observer->ShouldForceDevToolsAgentHostCreation())
DevToolsAgentHostImpl::s_force_creation_count_--;
- g_observers.Get().RemoveObserver(observer);
+ g_devtools_observers.Get().RemoveObserver(observer);
}
// static
@@ -343,42 +330,45 @@ bool DevToolsAgentHostImpl::ShouldForceCreation() {
}
void DevToolsAgentHostImpl::NotifyCreated() {
- DCHECK(g_instances.Get().find(id_) == g_instances.Get().end());
- g_instances.Get()[id_] = this;
- for (auto& observer : g_observers.Get())
+ DCHECK(g_devtools_instances.Get().find(id_) ==
+ g_devtools_instances.Get().end());
+ g_devtools_instances.Get()[id_] = this;
+ for (auto& observer : g_devtools_observers.Get())
observer.DevToolsAgentHostCreated(this);
}
void DevToolsAgentHostImpl::NotifyNavigated() {
- for (auto& observer : g_observers.Get())
+ for (auto& observer : g_devtools_observers.Get())
observer.DevToolsAgentHostNavigated(this);
}
void DevToolsAgentHostImpl::NotifyAttached() {
- for (auto& observer : g_observers.Get())
+ for (auto& observer : g_devtools_observers.Get())
observer.DevToolsAgentHostAttached(this);
}
void DevToolsAgentHostImpl::NotifyDetached() {
- for (auto& observer : g_observers.Get())
+ for (auto& observer : g_devtools_observers.Get())
observer.DevToolsAgentHostDetached(this);
}
void DevToolsAgentHostImpl::NotifyDestroyed() {
- DCHECK(g_instances.Get().find(id_) != g_instances.Get().end());
- for (auto& observer : g_observers.Get())
+ DCHECK(g_devtools_instances.Get().find(id_) !=
+ g_devtools_instances.Get().end());
+ for (auto& observer : g_devtools_observers.Get())
observer.DevToolsAgentHostDestroyed(this);
- g_instances.Get().erase(id_);
+ g_devtools_instances.Get().erase(id_);
}
// DevToolsMessageChunkProcessor -----------------------------------------------
DevToolsMessageChunkProcessor::DevToolsMessageChunkProcessor(
+ const SendMessageIPCCallback& ipc_callback,
const SendMessageCallback& callback)
- : callback_(callback),
+ : ipc_callback_(ipc_callback),
+ callback_(callback),
message_buffer_size_(0),
- last_call_id_(0) {
-}
+ last_call_id_(0) {}
DevToolsMessageChunkProcessor::~DevToolsMessageChunkProcessor() {
}
@@ -393,7 +383,7 @@ bool DevToolsMessageChunkProcessor::ProcessChunkedMessageFromAgent(
if (chunk.is_first && chunk.is_last) {
if (message_buffer_size_ != 0)
return false;
- callback_.Run(chunk.session_id, chunk.data);
+ ipc_callback_.Run(chunk.session_id, chunk.data);
return true;
}
@@ -410,7 +400,41 @@ bool DevToolsMessageChunkProcessor::ProcessChunkedMessageFromAgent(
if (chunk.is_last) {
if (message_buffer_.size() != message_buffer_size_)
return false;
- callback_.Run(chunk.session_id, message_buffer_);
+ ipc_callback_.Run(chunk.session_id, message_buffer_);
+ message_buffer_ = std::string();
+ message_buffer_size_ = 0;
+ }
+ return true;
+}
+
+bool DevToolsMessageChunkProcessor::ProcessChunkedMessageFromAgent(
+ mojom::DevToolsMessageChunkPtr chunk) {
+ if (chunk->is_last && !chunk->post_state.empty())
+ state_cookie_ = chunk->post_state;
+ if (chunk->is_last)
+ last_call_id_ = chunk->call_id;
+
+ if (chunk->is_first && chunk->is_last) {
+ if (message_buffer_size_ != 0)
+ return false;
+ callback_.Run(chunk->data);
+ return true;
+ }
+
+ if (chunk->is_first) {
+ message_buffer_ = std::string();
+ message_buffer_.reserve(chunk->message_size);
+ message_buffer_size_ = chunk->message_size;
+ }
+
+ if (message_buffer_.size() + chunk->data.size() > message_buffer_size_)
+ return false;
+ message_buffer_.append(chunk->data);
+
+ if (chunk->is_last) {
+ if (message_buffer_.size() != message_buffer_size_)
+ return false;
+ callback_.Run(message_buffer_);
message_buffer_ = std::string();
message_buffer_size_ = 0;
}
diff --git a/chromium/content/browser/devtools/devtools_agent_host_impl.h b/chromium/content/browser/devtools/devtools_agent_host_impl.h
index 7d7bf9a434a..72951e7d039 100644
--- a/chromium/content/browser/devtools/devtools_agent_host_impl.h
+++ b/chromium/content/browser/devtools/devtools_agent_host_impl.h
@@ -14,6 +14,7 @@
#include "base/containers/flat_set.h"
#include "content/browser/devtools/devtools_io_context.h"
#include "content/common/content_export.h"
+#include "content/common/devtools.mojom.h"
#include "content/common/devtools_messages.h"
#include "content/public/browser/devtools_agent_host.h"
@@ -64,7 +65,7 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
void NotifyCreated();
void NotifyNavigated();
- void ForceDetachAllClients(bool replaced);
+ void ForceDetachAllClients();
void ForceDetachSession(DevToolsSession* session);
DevToolsIOContext* GetIOContext() { return &io_context_; }
@@ -93,17 +94,21 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
class DevToolsMessageChunkProcessor {
public:
- using SendMessageCallback = base::Callback<void(int, const std::string&)>;
- explicit DevToolsMessageChunkProcessor(const SendMessageCallback& callback);
+ using SendMessageIPCCallback = base::Callback<void(int, const std::string&)>;
+ using SendMessageCallback = base::Callback<void(const std::string&)>;
+ DevToolsMessageChunkProcessor(const SendMessageIPCCallback& ipc_callback,
+ const SendMessageCallback& callback);
~DevToolsMessageChunkProcessor();
const std::string& state_cookie() const { return state_cookie_; }
void set_state_cookie(const std::string& cookie) { state_cookie_ = cookie; }
int last_call_id() const { return last_call_id_; }
bool ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk);
+ bool ProcessChunkedMessageFromAgent(mojom::DevToolsMessageChunkPtr chunk);
void Reset();
private:
+ SendMessageIPCCallback ipc_callback_;
SendMessageCallback callback_;
std::string message_buffer_;
uint32_t message_buffer_size_;
diff --git a/chromium/content/browser/devtools/devtools_frontend_host_impl.cc b/chromium/content/browser/devtools/devtools_frontend_host_impl.cc
index ab6e4b0140e..afa8104c058 100644
--- a/chromium/content/browser/devtools/devtools_frontend_host_impl.cc
+++ b/chromium/content/browser/devtools/devtools_frontend_host_impl.cc
@@ -5,16 +5,14 @@
#include "content/browser/devtools/devtools_frontend_host_impl.h"
#include <stddef.h>
-
#include <string>
#include "content/browser/bad_message.h"
#include "content/browser/devtools/grit/devtools_resources_map.h"
-#include "content/common/devtools_messages.h"
-#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
namespace content {
@@ -27,19 +25,20 @@ const char kCompatibilityScriptSourceURL[] =
// static
DevToolsFrontendHost* DevToolsFrontendHost::Create(
- RenderFrameHost* frontend_main_frame,
+ RenderFrameHost* frame_host,
const HandleMessageCallback& handle_message_callback) {
- return new DevToolsFrontendHostImpl(frontend_main_frame,
- handle_message_callback);
+ DCHECK(!frame_host->GetParent());
+ return new DevToolsFrontendHostImpl(frame_host, handle_message_callback);
}
// static
void DevToolsFrontendHost::SetupExtensionsAPI(
- RenderFrameHost* frame,
+ RenderFrameHost* frame_host,
const std::string& extension_api) {
- DCHECK(frame->GetParent());
- frame->Send(new DevToolsMsg_SetupDevToolsClient(frame->GetRoutingID(),
- extension_api));
+ DCHECK(frame_host->GetParent());
+ mojom::DevToolsFrontendAssociatedPtr frontend;
+ frame_host->GetRemoteAssociatedInterfaces()->GetInterface(&frontend);
+ frontend->SetupDevToolsExtensionAPI(extension_api);
}
// static
@@ -55,41 +54,31 @@ base::StringPiece DevToolsFrontendHost::GetFrontendResource(
}
DevToolsFrontendHostImpl::DevToolsFrontendHostImpl(
- RenderFrameHost* frontend_main_frame,
+ RenderFrameHost* frame_host,
const HandleMessageCallback& handle_message_callback)
- : WebContentsObserver(
- WebContents::FromRenderFrameHost(frontend_main_frame)),
- handle_message_callback_(handle_message_callback) {
- frontend_main_frame->Send(new DevToolsMsg_SetupDevToolsClient(
- frontend_main_frame->GetRoutingID(),
- DevToolsFrontendHost::GetFrontendResource(kCompatibilityScript)
- .as_string() +
- kCompatibilityScriptSourceURL));
+ : web_contents_(WebContents::FromRenderFrameHost(frame_host)),
+ handle_message_callback_(handle_message_callback),
+ binding_(this) {
+ mojom::DevToolsFrontendAssociatedPtr frontend;
+ frame_host->GetRemoteAssociatedInterfaces()->GetInterface(&frontend);
+ std::string api_script =
+ content::DevToolsFrontendHost::GetFrontendResource(kCompatibilityScript)
+ .as_string() +
+ kCompatibilityScriptSourceURL;
+ mojom::DevToolsFrontendHostAssociatedPtrInfo host;
+ binding_.Bind(mojo::MakeRequest(&host));
+ frontend->SetupDevToolsFrontend(api_script, std::move(host));
}
DevToolsFrontendHostImpl::~DevToolsFrontendHostImpl() {
}
void DevToolsFrontendHostImpl::BadMessageRecieved() {
- bad_message::ReceivedBadMessage(web_contents()->GetMainFrame()->GetProcess(),
+ bad_message::ReceivedBadMessage(web_contents_->GetMainFrame()->GetProcess(),
bad_message::DFH_BAD_EMBEDDER_MESSAGE);
}
-bool DevToolsFrontendHostImpl::OnMessageReceived(
- const IPC::Message& message,
- RenderFrameHost* render_frame_host) {
- if (render_frame_host != web_contents()->GetMainFrame())
- return false;
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(DevToolsFrontendHostImpl, message)
- IPC_MESSAGE_HANDLER(DevToolsHostMsg_DispatchOnEmbedder,
- OnDispatchOnEmbedder)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void DevToolsFrontendHostImpl::OnDispatchOnEmbedder(
+void DevToolsFrontendHostImpl::DispatchEmbedderMessage(
const std::string& message) {
handle_message_callback_.Run(message);
}
diff --git a/chromium/content/browser/devtools/devtools_frontend_host_impl.h b/chromium/content/browser/devtools/devtools_frontend_host_impl.h
index b2e3dba4f5a..054cf5acc62 100644
--- a/chromium/content/browser/devtools/devtools_frontend_host_impl.h
+++ b/chromium/content/browser/devtools/devtools_frontend_host_impl.h
@@ -6,29 +6,32 @@
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_FRONTEND_HOST_IMPL_H_
#include "base/macros.h"
+#include "content/common/devtools.mojom.h"
#include "content/public/browser/devtools_frontend_host.h"
-#include "content/public/browser/web_contents_observer.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
namespace content {
+class WebContents;
+
class DevToolsFrontendHostImpl : public DevToolsFrontendHost,
- public WebContentsObserver {
+ public mojom::DevToolsFrontendHost {
public:
DevToolsFrontendHostImpl(
- RenderFrameHost* frontend_main_frame,
+ RenderFrameHost* frame_host,
const HandleMessageCallback& handle_message_callback);
~DevToolsFrontendHostImpl() override;
void BadMessageRecieved() override;
private:
- // WebContentsObserver overrides.
- bool OnMessageReceived(const IPC::Message& message,
- RenderFrameHost* render_frame_host) override;
-
- void OnDispatchOnEmbedder(const std::string& message);
+ // mojom::DevToolsFrontendHost implementation.
+ void DispatchEmbedderMessage(const std::string& message) override;
+ WebContents* web_contents_;
HandleMessageCallback handle_message_callback_;
+ mojo::AssociatedBinding<mojom::DevToolsFrontendHost> binding_;
+
DISALLOW_COPY_AND_ASSIGN(DevToolsFrontendHostImpl);
};
diff --git a/chromium/content/browser/devtools/devtools_http_handler.cc b/chromium/content/browser/devtools/devtools_http_handler.cc
index 4468bc4be35..72ffe59f522 100644
--- a/chromium/content/browser/devtools/devtools_http_handler.cc
+++ b/chromium/content/browser/devtools/devtools_http_handler.cc
@@ -279,16 +279,13 @@ class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient {
agent_host_->DetachClient(this);
}
- void AgentHostClosed(DevToolsAgentHost* agent_host,
- bool replaced_with_another_client) override {
+ void AgentHostClosed(DevToolsAgentHost* agent_host) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(agent_host == agent_host_.get());
- std::string message = base::StringPrintf(
+ std::string message =
"{ \"method\": \"Inspector.detached\", "
- "\"params\": { \"reason\": \"%s\"} }",
- replaced_with_another_client ?
- "replaced_with_devtools" : "target_closed");
+ "\"params\": { \"reason\": \"target_closed\"} }";
DispatchProtocolMessage(agent_host, message);
agent_host_ = nullptr;
@@ -497,9 +494,7 @@ void DevToolsHttpHandler::OnJsonRequest(
std::string command;
std::string target_id;
if (!ParseJsonPath(path, &command, &target_id)) {
- SendJson(connection_id,
- net::HTTP_NOT_FOUND,
- NULL,
+ SendJson(connection_id, net::HTTP_NOT_FOUND, nullptr,
"Malformed query: " + info.path);
return;
}
@@ -547,7 +542,7 @@ void DevToolsHttpHandler::OnJsonRequest(
scoped_refptr<DevToolsAgentHost> agent_host = nullptr;
agent_host = delegate_->CreateNewTarget(url);
if (!agent_host) {
- SendJson(connection_id, net::HTTP_INTERNAL_SERVER_ERROR, NULL,
+ SendJson(connection_id, net::HTTP_INTERNAL_SERVER_ERROR, nullptr,
"Could not create new page");
return;
}
@@ -562,20 +557,16 @@ void DevToolsHttpHandler::OnJsonRequest(
scoped_refptr<DevToolsAgentHost> agent_host =
DevToolsAgentHost::GetForId(target_id);
if (!agent_host) {
- SendJson(connection_id,
- net::HTTP_NOT_FOUND,
- NULL,
+ SendJson(connection_id, net::HTTP_NOT_FOUND, nullptr,
"No such target id: " + target_id);
return;
}
if (command == "activate") {
if (agent_host->Activate()) {
- SendJson(connection_id, net::HTTP_OK, NULL, "Target activated");
+ SendJson(connection_id, net::HTTP_OK, nullptr, "Target activated");
} else {
- SendJson(connection_id,
- net::HTTP_INTERNAL_SERVER_ERROR,
- NULL,
+ SendJson(connection_id, net::HTTP_INTERNAL_SERVER_ERROR, nullptr,
"Could not activate target id: " + target_id);
}
return;
@@ -583,19 +574,15 @@ void DevToolsHttpHandler::OnJsonRequest(
if (command == "close") {
if (agent_host->Close()) {
- SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing");
+ SendJson(connection_id, net::HTTP_OK, nullptr, "Target is closing");
} else {
- SendJson(connection_id,
- net::HTTP_INTERNAL_SERVER_ERROR,
- NULL,
+ SendJson(connection_id, net::HTTP_INTERNAL_SERVER_ERROR, nullptr,
"Could not close target id: " + target_id);
}
return;
}
}
- SendJson(connection_id,
- net::HTTP_NOT_FOUND,
- NULL,
+ SendJson(connection_id, net::HTTP_NOT_FOUND, nullptr,
"Unknown command: " + command);
return;
}
diff --git a/chromium/content/browser/devtools/devtools_interceptor_controller.cc b/chromium/content/browser/devtools/devtools_interceptor_controller.cc
new file mode 100644
index 00000000000..df8f30b1f27
--- /dev/null
+++ b/chromium/content/browser/devtools/devtools_interceptor_controller.cc
@@ -0,0 +1,137 @@
+// Copyright 2017 The Chromium Authors. 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_interceptor_controller.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/supports_user_data.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"
+
+namespace content {
+
+namespace {
+const char kDevToolsInterceptorController[] = "DevToolsInterceptorController";
+}
+
+std::unique_ptr<InterceptionHandle>
+DevToolsInterceptorController::StartInterceptingRequests(
+ const FrameTreeNode* target_frame,
+ std::vector<Pattern> intercepted_patterns,
+ RequestInterceptedCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ const base::UnguessableToken& target_id =
+ target_frame->devtools_frame_token();
+
+ auto filter_entry =
+ std::make_unique<DevToolsURLRequestInterceptor::FilterEntry>(
+ target_id, std::move(intercepted_patterns), std::move(callback));
+ DevToolsTargetRegistry::RegistrationHandle registration_handle =
+ target_registry_->RegisterWebContents(
+ WebContentsImpl::FromFrameTreeNode(target_frame));
+ std::unique_ptr<InterceptionHandle> handle(new InterceptionHandle(
+ std::move(registration_handle), interceptor_, filter_entry.get()));
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&DevToolsURLRequestInterceptor::AddFilterEntry,
+ interceptor_, std::move(filter_entry)));
+ return handle;
+}
+
+void DevToolsInterceptorController::ContinueInterceptedRequest(
+ std::string interception_id,
+ std::unique_ptr<Modifications> modifications,
+ std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&DevToolsURLRequestInterceptor::ContinueInterceptedRequest,
+ interceptor_, interception_id,
+ base::Passed(std::move(modifications)),
+ base::Passed(std::move(callback))));
+}
+
+bool DevToolsInterceptorController::ShouldCancelNavigation(
+ const GlobalRequestID& global_request_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ auto it = canceled_navigation_requests_.find(global_request_id);
+ if (it == canceled_navigation_requests_.end())
+ return false;
+ canceled_navigation_requests_.erase(it);
+ return true;
+}
+
+void DevToolsInterceptorController::GetResponseBody(
+ std::string interception_id,
+ std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&DevToolsURLRequestInterceptor::GetResponseBody,
+ interceptor_, std::move(interception_id),
+ std::move(callback)));
+}
+
+void DevToolsInterceptorController::NavigationStarted(
+ const std::string& interception_id,
+ const GlobalRequestID& request_id) {
+ navigation_requests_[interception_id] = request_id;
+}
+
+void DevToolsInterceptorController::NavigationFinished(
+ const std::string& interception_id) {
+ navigation_requests_.erase(interception_id);
+}
+
+// static
+DevToolsInterceptorController*
+DevToolsInterceptorController::FromBrowserContext(BrowserContext* context) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return static_cast<DevToolsInterceptorController*>(
+ context->GetUserData(kDevToolsInterceptorController));
+}
+
+DevToolsInterceptorController::DevToolsInterceptorController(
+ base::WeakPtr<DevToolsURLRequestInterceptor> interceptor,
+ std::unique_ptr<DevToolsTargetRegistry> target_registry,
+ BrowserContext* browser_context)
+ : interceptor_(interceptor),
+ target_registry_(std::move(target_registry)),
+ weak_factory_(this) {
+ browser_context->SetUserData(
+ kDevToolsInterceptorController,
+ std::unique_ptr<DevToolsInterceptorController>(this));
+}
+
+DevToolsInterceptorController::~DevToolsInterceptorController() = default;
+
+InterceptionHandle::InterceptionHandle(
+ DevToolsTargetRegistry::RegistrationHandle registration,
+ base::WeakPtr<DevToolsURLRequestInterceptor> interceptor,
+ DevToolsURLRequestInterceptor::FilterEntry* entry)
+ : registration_(registration),
+ interceptor_(std::move(interceptor)),
+ entry_(entry) {}
+
+InterceptionHandle::~InterceptionHandle() {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&DevToolsURLRequestInterceptor::RemoveFilterEntry,
+ interceptor_, entry_));
+}
+
+void InterceptionHandle::UpdatePatterns(
+ std::vector<DevToolsURLRequestInterceptor::Pattern> patterns) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&DevToolsURLRequestInterceptor::UpdatePatterns,
+ interceptor_, base::Unretained(entry_),
+ std::move(patterns)));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_interceptor_controller.h b/chromium/content/browser/devtools/devtools_interceptor_controller.h
new file mode 100644
index 00000000000..f83aca70b20
--- /dev/null
+++ b/chromium/content/browser/devtools/devtools_interceptor_controller.h
@@ -0,0 +1,98 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_INTERCEPTOR_CONTROLLER_
+#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_INTERCEPTOR_CONTROLLER_
+
+#include <string>
+
+#include "base/containers/flat_map.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/supports_user_data.h"
+#include "base/unguessable_token.h"
+#include "content/browser/devtools/devtools_url_request_interceptor.h"
+
+namespace content {
+
+class BrowserContext;
+class FrameTreeNode;
+class InterceptionHandle;
+
+struct GlobalRequestID;
+
+class DevToolsInterceptorController : public base::SupportsUserData::Data {
+ public:
+ using GetResponseBodyForInterceptionCallback =
+ DevToolsURLRequestInterceptor::GetResponseBodyForInterceptionCallback;
+ using RequestInterceptedCallback =
+ DevToolsURLRequestInterceptor::RequestInterceptedCallback;
+ using ContinueInterceptedRequestCallback =
+ DevToolsURLRequestInterceptor::ContinueInterceptedRequestCallback;
+ using Modifications = DevToolsURLRequestInterceptor::Modifications;
+ using Pattern = DevToolsURLRequestInterceptor::Pattern;
+
+ static DevToolsInterceptorController* FromBrowserContext(
+ BrowserContext* context);
+
+ void ContinueInterceptedRequest(
+ std::string interception_id,
+ std::unique_ptr<Modifications> modifications,
+ std::unique_ptr<ContinueInterceptedRequestCallback> callback);
+
+ std::unique_ptr<InterceptionHandle> StartInterceptingRequests(
+ const FrameTreeNode* target_frame,
+ std::vector<Pattern> intercepted_patterns,
+ RequestInterceptedCallback callback);
+
+ bool ShouldCancelNavigation(const GlobalRequestID& global_request_id);
+
+ void GetResponseBody(
+ std::string request_id,
+ std::unique_ptr<GetResponseBodyForInterceptionCallback> callback);
+
+ ~DevToolsInterceptorController() override;
+
+ private:
+ friend class DevToolsURLRequestInterceptor;
+
+ DevToolsInterceptorController(
+ base::WeakPtr<DevToolsURLRequestInterceptor> interceptor,
+ std::unique_ptr<DevToolsTargetRegistry> target_registry,
+ BrowserContext* browser_context);
+
+ void NavigationStarted(const std::string& interception_id,
+ const GlobalRequestID& request_id);
+ void NavigationFinished(const std::string& interception_id);
+
+ base::WeakPtr<DevToolsURLRequestInterceptor> interceptor_;
+ std::unique_ptr<DevToolsTargetRegistry> target_registry_;
+ base::flat_map<std::string, GlobalRequestID> navigation_requests_;
+ base::flat_set<GlobalRequestID> canceled_navigation_requests_;
+ base::WeakPtrFactory<DevToolsInterceptorController> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsInterceptorController);
+};
+
+class InterceptionHandle {
+ public:
+ ~InterceptionHandle();
+ void UpdatePatterns(std::vector<DevToolsURLRequestInterceptor::Pattern>);
+
+ private:
+ friend class DevToolsInterceptorController;
+ InterceptionHandle(DevToolsTargetRegistry::RegistrationHandle registration,
+ base::WeakPtr<DevToolsURLRequestInterceptor> interceptor,
+ DevToolsURLRequestInterceptor::FilterEntry* entry);
+
+ DevToolsTargetRegistry::RegistrationHandle registration_;
+ base::WeakPtr<DevToolsURLRequestInterceptor> interceptor_;
+ DevToolsURLRequestInterceptor::FilterEntry* entry_;
+
+ DISALLOW_COPY_AND_ASSIGN(InterceptionHandle);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_INTERCEPTOR_CONTROLLER_
diff --git a/chromium/content/browser/devtools/devtools_io_context.cc b/chromium/content/browser/devtools/devtools_io_context.cc
index 4598f165337..98488055870 100644
--- a/chromium/content/browser/devtools/devtools_io_context.cc
+++ b/chromium/content/browser/devtools/devtools_io_context.cc
@@ -84,7 +84,7 @@ TempFileStream::~TempFileStream() {
bool TempFileStream::InitOnFileSequenceIfNeeded() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
if (had_errors_)
return false;
if (file_.IsValid())
@@ -206,7 +206,6 @@ class BlobStream : public DevToolsIOContext::ROStream {
~BlobStream() override = default;
void OpenOnIO(scoped_refptr<ChromeBlobStorageContext> blob_context,
- scoped_refptr<storage::FileSystemContext> fs_context,
const std::string& uuid,
OpenCallback callback);
void ReadOnIO(std::unique_ptr<ReadRequest> request);
@@ -231,7 +230,6 @@ class BlobStream : public DevToolsIOContext::ROStream {
std::unique_ptr<storage::BlobDataHandle> blob_handle_;
OpenCallback open_callback_;
- scoped_refptr<storage::FileSystemContext> fs_context_;
std::unique_ptr<BlobReader> blob_reader_;
base::queue<std::unique_ptr<ReadRequest>> pending_reads_;
scoped_refptr<net::IOBufferWithSize> io_buf_;
@@ -265,12 +263,9 @@ void BlobStream::Open(scoped_refptr<ChromeBlobStorageContext> context,
StoragePartition* partition,
const std::string& handle,
OpenCallback callback) {
- scoped_refptr<storage::FileSystemContext> fs_context =
- partition->GetFileSystemContext();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&BlobStream::OpenOnIO, this, context, fs_context, handle,
- std::move(callback)));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&BlobStream::OpenOnIO, this, context,
+ handle, std::move(callback)));
}
void BlobStream::Read(off_t position, size_t max_size, ReadCallback callback) {
@@ -288,7 +283,6 @@ void BlobStream::Close(bool invoke_pending_callbacks) {
}
void BlobStream::OpenOnIO(scoped_refptr<ChromeBlobStorageContext> blob_context,
- scoped_refptr<storage::FileSystemContext> fs_context,
const std::string& uuid,
OpenCallback callback) {
DCHECK(!blob_handle_);
@@ -302,7 +296,6 @@ void BlobStream::OpenOnIO(scoped_refptr<ChromeBlobStorageContext> blob_context,
}
is_binary_ = !IsTextMimeType(blob_handle_->content_type());
open_callback_ = std::move(callback);
- fs_context_ = std::move(fs_context);
blob_handle_->RunOnConstructionComplete(
base::Bind(&BlobStream::OnBlobConstructionComplete, this));
}
@@ -426,7 +419,7 @@ void BlobStream::OnReadComplete(int bytes_read) {
void BlobStream::CreateReader() {
DCHECK(!blob_reader_);
- blob_reader_ = blob_handle_->CreateReader(fs_context_.get());
+ blob_reader_ = blob_handle_->CreateReader();
BlobReader::Status status = blob_reader_->CalculateSize(
base::Bind(&BlobStream::OnCalculateSizeComplete, this));
if (status != BlobReader::Status::IO_PENDING) {
diff --git a/chromium/content/browser/devtools/devtools_manager.cc b/chromium/content/browser/devtools/devtools_manager.cc
index 886e59e10ab..22ae3b2c62a 100644
--- a/chromium/content/browser/devtools/devtools_manager.cc
+++ b/chromium/content/browser/devtools/devtools_manager.cc
@@ -9,6 +9,7 @@
#include "base/message_loop/message_loop.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/devtools_http_handler.h"
+#include "content/browser/devtools/devtools_pipe_handler.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_socket_factory.h"
@@ -24,9 +25,15 @@ void DevToolsAgentHost::StartRemoteDebuggingServer(
DevToolsManager* manager = DevToolsManager::GetInstance();
if (!manager->delegate())
return;
- manager->SetHttpHandler(base::WrapUnique(new DevToolsHttpHandler(
+ manager->SetHttpHandler(std::make_unique<DevToolsHttpHandler>(
manager->delegate(), std::move(server_socket_factory), frontend_url,
- active_port_output_directory, debug_frontend_dir)));
+ active_port_output_directory, debug_frontend_dir));
+}
+
+// static
+void DevToolsAgentHost::StartRemoteDebuggingPipeHandler() {
+ DevToolsManager* manager = DevToolsManager::GetInstance();
+ manager->SetPipeHandler(std::make_unique<DevToolsPipeHandler>());
}
// static
@@ -52,4 +59,9 @@ void DevToolsManager::SetHttpHandler(
http_handler_ = std::move(http_handler);
}
+void DevToolsManager::SetPipeHandler(
+ std::unique_ptr<DevToolsPipeHandler> pipe_handler) {
+ pipe_handler_ = std::move(pipe_handler);
+}
+
} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_manager.h b/chromium/content/browser/devtools/devtools_manager.h
index 90f075d36ea..eb8cc0bf739 100644
--- a/chromium/content/browser/devtools/devtools_manager.h
+++ b/chromium/content/browser/devtools/devtools_manager.h
@@ -16,6 +16,7 @@
namespace content {
class DevToolsHttpHandler;
+class DevToolsPipeHandler;
// This class is a singleton that manage global DevTools state for the whole
// browser.
@@ -33,11 +34,14 @@ class CONTENT_EXPORT DevToolsManager {
void SetHttpHandler(std::unique_ptr<DevToolsHttpHandler> http_handler);
+ void SetPipeHandler(std::unique_ptr<DevToolsPipeHandler> pipe_handler);
+
private:
friend struct base::DefaultSingletonTraits<DevToolsManager>;
std::unique_ptr<DevToolsManagerDelegate> delegate_;
std::unique_ptr<DevToolsHttpHandler> http_handler_;
+ std::unique_ptr<DevToolsPipeHandler> pipe_handler_;
DISALLOW_COPY_AND_ASSIGN(DevToolsManager);
};
diff --git a/chromium/content/browser/devtools/devtools_manager_unittest.cc b/chromium/content/browser/devtools/devtools_manager_unittest.cc
index 0f40f6b6eef..e5e81e5a4c9 100644
--- a/chromium/content/browser/devtools/devtools_manager_unittest.cc
+++ b/chromium/content/browser/devtools/devtools_manager_unittest.cc
@@ -39,10 +39,7 @@ namespace {
class TestDevToolsClientHost : public DevToolsAgentHostClient {
public:
- TestDevToolsClientHost()
- : last_sent_message(NULL),
- closed_(false) {
- }
+ TestDevToolsClientHost() : last_sent_message(nullptr), closed_(false) {}
~TestDevToolsClientHost() override { EXPECT_TRUE(closed_); }
@@ -53,9 +50,7 @@ class TestDevToolsClientHost : public DevToolsAgentHostClient {
closed_ = true;
}
- void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override {
- FAIL();
- }
+ void AgentHostClosed(DevToolsAgentHost* agent_host) override { FAIL(); }
void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
const std::string& message) override {
@@ -171,7 +166,7 @@ TEST_F(DevToolsManagerTest, NoUnresponsiveDialogInInspectedContents) {
base::RunLoop().Run();
EXPECT_TRUE(delegate.renderer_unresponsive_received());
- contents()->SetDelegate(NULL);
+ contents()->SetDelegate(nullptr);
}
TEST_F(DevToolsManagerTest, ReattachOnCancelPendingNavigation) {
diff --git a/chromium/content/browser/devtools/devtools_network_transaction_factory.cc b/chromium/content/browser/devtools/devtools_network_transaction_factory.cc
index 33b8eeeb15a..7ac2a9225d4 100644
--- a/chromium/content/browser/devtools/devtools_network_transaction_factory.cc
+++ b/chromium/content/browser/devtools/devtools_network_transaction_factory.cc
@@ -4,13 +4,13 @@
#include "content/public/browser/devtools_network_transaction_factory.h"
-#include "content/common/devtools/devtools_network_transaction_factory.h"
+#include "content/network/throttling/throttling_network_transaction_factory.h"
namespace content {
std::unique_ptr<net::HttpTransactionFactory>
CreateDevToolsNetworkTransactionFactory(net::HttpNetworkSession* session) {
- return std::make_unique<DevToolsNetworkTransactionFactory>(session);
+ return std::make_unique<ThrottlingNetworkTransactionFactory>(session);
}
} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_pipe_handler.cc b/chromium/content/browser/devtools/devtools_pipe_handler.cc
new file mode 100644
index 00000000000..dce8d284663
--- /dev/null
+++ b/chromium/content/browser/devtools/devtools_pipe_handler.cc
@@ -0,0 +1,270 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/devtools/devtools_pipe_handler.h"
+
+#if defined(OS_WIN)
+#include <io.h>
+#include <windows.h>
+#else
+#include <sys/socket.h>
+#endif
+
+#include <stdio.h>
+#include <cstdlib>
+#include <string>
+#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/message_loop/message_loop.h"
+#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/threading/thread.h"
+#include "build/build_config.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/devtools_agent_host.h"
+#include "net/server/http_connection.h"
+
+const size_t kReceiveBufferSizeForDevTools = 100 * 1024 * 1024; // 100Mb
+const size_t kWritePacketSize = 1 << 16;
+const int kReadFD = 3;
+const int kWriteFD = 4;
+
+namespace content {
+
+namespace {
+
+const char kDevToolsPipeHandlerReadThreadName[] =
+ "DevToolsPipeHandlerReadThread";
+const char kDevToolsPipeHandlerWriteThreadName[] =
+ "DevToolsPipeHandlerWriteThread";
+
+void WriteIntoPipe(int write_fd, const std::string& message) {
+#if defined(OS_WIN)
+ HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(write_fd));
+#endif
+
+ size_t total_written = 0;
+ while (total_written < message.length()) {
+ size_t length = message.length() - total_written;
+ if (length > kWritePacketSize)
+ length = kWritePacketSize;
+#if defined(OS_WIN)
+ DWORD result = 0;
+ WriteFile(handle, message.data() + total_written,
+ static_cast<DWORD>(length), &result, nullptr);
+#else
+ int result = write(write_fd, message.data() + total_written, length);
+#endif
+ if (!result) {
+ LOG(ERROR) << "Could not write into pipe";
+ return;
+ }
+ total_written += result;
+ }
+#if defined(OS_WIN)
+ DWORD result = 0;
+ WriteFile(handle, "\n", 1, &result, nullptr);
+#else
+ int result = write(write_fd, "\n", 1);
+#endif
+ if (!result) {
+ LOG(ERROR) << "Could not write into pipe";
+ return;
+ }
+}
+
+} // namespace
+
+// PipeReader ------------------------------------------------------------------
+
+class PipeReader {
+ public:
+ PipeReader(base::WeakPtr<DevToolsPipeHandler> devtools_handler, int read_fd);
+ ~PipeReader() = default;
+ void ReadLoop();
+
+ private:
+ bool HandleReadResult(int result);
+
+ void ConnectionClosed();
+
+ scoped_refptr<net::HttpConnection::ReadIOBuffer> read_buffer_;
+ base::WeakPtr<DevToolsPipeHandler> devtools_handler_;
+#if defined(OS_WIN)
+ HANDLE read_handle_;
+#else
+ int read_fd_;
+#endif
+};
+
+PipeReader::PipeReader(base::WeakPtr<DevToolsPipeHandler> devtools_handler,
+ int read_fd)
+ : devtools_handler_(devtools_handler) {
+#if defined(OS_WIN)
+ read_handle_ = reinterpret_cast<HANDLE>(_get_osfhandle(read_fd));
+#else
+ read_fd_ = read_fd;
+#endif
+
+ read_buffer_ = new net::HttpConnection::ReadIOBuffer();
+ read_buffer_->set_max_buffer_size(kReceiveBufferSizeForDevTools);
+}
+
+void PipeReader::ReadLoop() {
+ while (true) {
+ if (read_buffer_->RemainingCapacity() == 0 &&
+ !read_buffer_->IncreaseCapacity()) {
+ LOG(ERROR) << "Connection closed, not enough capacity";
+ break;
+ }
+
+#if defined(OS_WIN)
+ DWORD result = 0;
+ ReadFile(read_handle_, read_buffer_->data(),
+ read_buffer_->RemainingCapacity(), &result, nullptr);
+#else
+ int result =
+ read(read_fd_, read_buffer_->data(), read_buffer_->RemainingCapacity());
+#endif
+
+ if (!HandleReadResult(result))
+ break;
+ }
+
+ ConnectionClosed();
+}
+
+bool PipeReader::HandleReadResult(int result) {
+ if (result == 0) {
+ LOG(ERROR) << "Connection terminated while reading from pipe";
+ return false;
+ }
+
+ read_buffer_->DidRead(result);
+
+ // Go over the last read chunk, look for \n, extract messages.
+ int offset = 0;
+ for (int i = read_buffer_->GetSize() - result; i < read_buffer_->GetSize();
+ ++i) {
+ if (read_buffer_->StartOfBuffer()[i] == '\n') {
+ std::string str(read_buffer_->StartOfBuffer() + offset, i - offset);
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&DevToolsPipeHandler::HandleMessage, devtools_handler_,
+ std::move(str)));
+ offset = i + 1;
+ }
+ }
+ if (offset)
+ read_buffer_->DidConsume(offset);
+ return true;
+}
+
+void PipeReader::ConnectionClosed() {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&DevToolsPipeHandler::Shutdown, devtools_handler_));
+}
+
+// DevToolsPipeHandler ---------------------------------------------------
+
+DevToolsPipeHandler::DevToolsPipeHandler()
+ : read_fd_(kReadFD), write_fd_(kWriteFD), weak_factory_(this) {
+ read_thread_.reset(new base::Thread(kDevToolsPipeHandlerReadThreadName));
+ base::Thread::Options options;
+ options.message_loop_type = base::MessageLoop::TYPE_IO;
+ if (!read_thread_->StartWithOptions(options)) {
+ read_thread_.reset();
+ Shutdown();
+ return;
+ }
+
+ write_thread_.reset(new base::Thread(kDevToolsPipeHandlerWriteThreadName));
+ if (!write_thread_->StartWithOptions(options)) {
+ write_thread_.reset();
+ Shutdown();
+ return;
+ }
+
+ browser_target_ = DevToolsAgentHost::CreateForDiscovery();
+ browser_target_->AttachClient(this);
+
+ pipe_reader_.reset(new PipeReader(weak_factory_.GetWeakPtr(), read_fd_));
+ base::TaskRunner* task_runner = read_thread_->task_runner().get();
+ task_runner->PostTask(FROM_HERE,
+ base::BindOnce(&PipeReader::ReadLoop,
+ base::Unretained(pipe_reader_.get())));
+}
+
+void DevToolsPipeHandler::Shutdown() {
+ // Is there is no read thread, there is nothing, it is safe to proceed.
+ if (!read_thread_)
+ return;
+
+ // If there is no write thread, only take care of the read thread.
+ if (!write_thread_) {
+ base::PostTaskWithTraits(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
+ base::BindOnce([](base::Thread* rthread) { delete rthread; },
+ read_thread_.release()));
+ return;
+ }
+
+ // There were threads, disconnect from the target.
+ DCHECK(browser_target_);
+ browser_target_->DetachClient(this);
+ browser_target_ = nullptr;
+
+// Concurrently discard the pipe handles to successfully join threads.
+#if defined(OS_WIN)
+ CloseHandle(reinterpret_cast<HANDLE>(_get_osfhandle(read_fd_)));
+ CloseHandle(reinterpret_cast<HANDLE>(_get_osfhandle(write_fd_)));
+#else
+ shutdown(read_fd_, SHUT_RDWR);
+ shutdown(write_fd_, SHUT_RDWR);
+#endif
+
+ // Post PipeReader and WeakPtr factory destruction on the reader thread.
+ read_thread_->task_runner()->PostTask(
+ FROM_HERE, base::BindOnce([](PipeReader* reader) { delete reader; },
+ pipe_reader_.release()));
+
+ // Post background task that would join and destroy the threads.
+ base::PostTaskWithTraits(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
+ base::BindOnce(
+ [](base::Thread* rthread, base::Thread* wthread) {
+ delete rthread;
+ delete wthread;
+ },
+ read_thread_.release(), write_thread_.release()));
+}
+
+DevToolsPipeHandler::~DevToolsPipeHandler() {
+ Shutdown();
+}
+
+void DevToolsPipeHandler::HandleMessage(const std::string& message) {
+ if (browser_target_)
+ browser_target_->DispatchProtocolMessage(this, message);
+}
+
+void DevToolsPipeHandler::DetachFromTarget() {}
+
+void DevToolsPipeHandler::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
+ const std::string& message) {
+ if (!write_thread_)
+ return;
+ base::TaskRunner* task_runner = write_thread_->task_runner().get();
+ task_runner->PostTask(
+ FROM_HERE, base::BindOnce(&WriteIntoPipe, write_fd_, std::move(message)));
+}
+
+void DevToolsPipeHandler::AgentHostClosed(DevToolsAgentHost* agent_host) {}
+
+} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_pipe_handler.h b/chromium/content/browser/devtools/devtools_pipe_handler.h
new file mode 100644
index 00000000000..ec8be1cfd20
--- /dev/null
+++ b/chromium/content/browser/devtools/devtools_pipe_handler.h
@@ -0,0 +1,49 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PIPE_HANDLER_H_
+#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PIPE_HANDLER_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "content/public/browser/devtools_agent_host_client.h"
+
+namespace base {
+class Thread;
+}
+
+namespace content {
+
+class PipeReader;
+
+class DevToolsPipeHandler : public DevToolsAgentHostClient {
+ public:
+ DevToolsPipeHandler();
+ ~DevToolsPipeHandler() override;
+
+ void HandleMessage(const std::string& message);
+ void DetachFromTarget();
+
+ // DevToolsAgentHostClient overrides
+ void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
+ const std::string& message) override;
+ void AgentHostClosed(DevToolsAgentHost* agent_host) override;
+
+ void Shutdown();
+
+ private:
+ std::unique_ptr<PipeReader> pipe_reader_;
+ std::unique_ptr<base::Thread> read_thread_;
+ std::unique_ptr<base::Thread> write_thread_;
+ scoped_refptr<DevToolsAgentHost> browser_target_;
+ int read_fd_;
+ int write_fd_;
+ base::WeakPtrFactory<DevToolsPipeHandler> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsPipeHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PIPE_HANDLER_H_
diff --git a/chromium/content/browser/devtools/devtools_session.cc b/chromium/content/browser/devtools/devtools_session.cc
index a3b91db3a4d..0b8bb215e93 100644
--- a/chromium/content/browser/devtools/devtools_session.cc
+++ b/chromium/content/browser/devtools/devtools_session.cc
@@ -8,21 +8,36 @@
#include "base/json/json_writer.h"
#include "content/browser/devtools/devtools_manager.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"
namespace content {
+// static
+bool DevToolsSession::ShouldSendOnIO(const std::string& method) {
+ // Keep in sync with WebDevToolsAgent::ShouldInterruptForMethod.
+ // TODO(dgozman): find a way to share this.
+ return method == "Debugger.pause" || method == "Debugger.setBreakpoint" ||
+ method == "Debugger.setBreakpointByUrl" ||
+ method == "Debugger.removeBreakpoint" ||
+ method == "Debugger.setBreakpointsActive" ||
+ method == "Performance.getMetrics";
+}
+
DevToolsSession::DevToolsSession(DevToolsAgentHostImpl* agent_host,
DevToolsAgentHostClient* client,
int session_id)
- : agent_host_(agent_host),
+ : binding_(this),
+ agent_host_(agent_host),
client_(client),
session_id_(session_id),
process_(nullptr),
host_(nullptr),
dispatcher_(new protocol::UberDispatcher(this)),
- chunk_processor_(base::Bind(&DevToolsSession::SendMessageFromProcessor,
+ chunk_processor_(base::Bind(&DevToolsSession::SendMessageFromProcessorIPC,
+ base::Unretained(this)),
+ base::Bind(&DevToolsSession::SendMessageFromProcessor,
base::Unretained(this))),
weak_factory_(this) {}
@@ -56,12 +71,34 @@ void DevToolsSession::SetFallThroughForNotFound(bool value) {
dispatcher_->setFallThroughForNotFound(value);
}
+void DevToolsSession::AttachToAgent(
+ const mojom::DevToolsAgentAssociatedPtr& agent) {
+ mojom::DevToolsSessionHostAssociatedPtrInfo host_ptr_info;
+ binding_.Bind(mojo::MakeRequest(&host_ptr_info));
+ agent->AttachDevToolsSession(
+ std::move(host_ptr_info), mojo::MakeRequest(&session_ptr_),
+ mojo::MakeRequest(&io_session_ptr_), base::Optional<std::string>());
+ session_ptr_.set_connection_error_handler(base::BindOnce(
+ &DevToolsSession::MojoConnectionDestroyed, base::Unretained(this)));
+}
+
+void DevToolsSession::ReattachToAgent(
+ const mojom::DevToolsAgentAssociatedPtr& agent) {
+ mojom::DevToolsSessionHostAssociatedPtrInfo host_ptr_info;
+ binding_.Bind(mojo::MakeRequest(&host_ptr_info));
+ agent->AttachDevToolsSession(
+ std::move(host_ptr_info), mojo::MakeRequest(&session_ptr_),
+ mojo::MakeRequest(&io_session_ptr_), state_cookie());
+ session_ptr_.set_connection_error_handler(base::BindOnce(
+ &DevToolsSession::MojoConnectionDestroyed, base::Unretained(this)));
+}
+
void DevToolsSession::SendMessageToClient(const std::string& message) {
client_->DispatchProtocolMessage(agent_host_, message);
}
-void DevToolsSession::SendMessageFromProcessor(int session_id,
- const std::string& message) {
+void DevToolsSession::SendMessageFromProcessorIPC(int session_id,
+ const std::string& message) {
if (session_id != session_id_)
return;
int id = chunk_processor_.last_call_id();
@@ -70,6 +107,13 @@ void DevToolsSession::SendMessageFromProcessor(int session_id,
// |this| may be deleted at this point.
}
+void DevToolsSession::SendMessageFromProcessor(const std::string& message) {
+ int id = chunk_processor_.last_call_id();
+ waiting_for_response_messages_.erase(id);
+ client_->DispatchProtocolMessage(agent_host_, message);
+ // |this| may be deleted at this point.
+}
+
void DevToolsSession::SendResponse(
std::unique_ptr<base::DictionaryValue> response) {
std::string json;
@@ -77,6 +121,12 @@ void DevToolsSession::SendResponse(
client_->DispatchProtocolMessage(agent_host_, json);
}
+void DevToolsSession::MojoConnectionDestroyed() {
+ binding_.Close();
+ session_ptr_.reset();
+ io_session_ptr_.reset();
+}
+
protocol::Response::Status DevToolsSession::Dispatch(
const std::string& message,
int* call_id,
@@ -103,6 +153,24 @@ protocol::Response::Status DevToolsSession::Dispatch(
call_id, method);
}
+void DevToolsSession::DispatchProtocolMessageToAgent(
+ int call_id,
+ const std::string& method,
+ const std::string& message) {
+ if (ShouldSendOnIO(method)) {
+ if (io_session_ptr_)
+ io_session_ptr_->DispatchProtocolMessage(call_id, method, message);
+ } else {
+ if (session_ptr_)
+ session_ptr_->DispatchProtocolMessage(call_id, method, message);
+ }
+}
+
+void DevToolsSession::InspectElement(const gfx::Point& point) {
+ if (session_ptr_)
+ session_ptr_->InspectElement(point);
+}
+
bool DevToolsSession::ReceiveMessageChunk(const DevToolsMessageChunk& chunk) {
return chunk_processor_.ProcessChunkedMessageFromAgent(chunk);
}
@@ -121,4 +189,32 @@ void DevToolsSession::sendProtocolNotification(
void DevToolsSession::flushProtocolNotifications() {
}
+void DevToolsSession::DispatchProtocolMessage(
+ mojom::DevToolsMessageChunkPtr chunk) {
+ if (chunk_processor_.ProcessChunkedMessageFromAgent(std::move(chunk)))
+ return;
+
+ MojoConnectionDestroyed();
+ if (process_) {
+ bad_message::ReceivedBadMessage(
+ process_, bad_message::RFH_INCONSISTENT_DEVTOOLS_MESSAGE);
+ }
+}
+
+void DevToolsSession::RequestNewWindow(int32_t frame_routing_id,
+ RequestNewWindowCallback callback) {
+ bool success = false;
+ RenderFrameHostImpl* frame_host =
+ process_
+ ? RenderFrameHostImpl::FromID(process_->GetID(), frame_routing_id)
+ : nullptr;
+ if (frame_host) {
+ scoped_refptr<DevToolsAgentHost> agent =
+ RenderFrameDevToolsAgentHost::GetOrCreateFor(
+ frame_host->frame_tree_node());
+ success = static_cast<DevToolsAgentHostImpl*>(agent.get())->Inspect();
+ }
+ std::move(callback).Run(success);
+}
+
} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_session.h b/chromium/content/browser/devtools/devtools_session.h
index 2f94ebacfbb..9e84c0bf7cf 100644
--- a/chromium/content/browser/devtools/devtools_session.h
+++ b/chromium/content/browser/devtools/devtools_session.h
@@ -13,13 +13,16 @@
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/protocol/devtools_domain_handler.h"
#include "content/browser/devtools/protocol/protocol.h"
+#include "content/common/devtools.mojom.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
namespace content {
class DevToolsAgentHostClient;
class RenderFrameHostImpl;
-class DevToolsSession : public protocol::FrontendChannel {
+class DevToolsSession : public protocol::FrontendChannel,
+ public mojom::DevToolsSessionHost {
public:
DevToolsSession(DevToolsAgentHostImpl* agent_host,
DevToolsAgentHostClient* client,
@@ -33,7 +36,10 @@ class DevToolsSession : public protocol::FrontendChannel {
void SetRenderer(RenderProcessHost* process_host,
RenderFrameHostImpl* frame_host);
void SetFallThroughForNotFound(bool value);
+ void AttachToAgent(const mojom::DevToolsAgentAssociatedPtr& agent);
+ void ReattachToAgent(const mojom::DevToolsAgentAssociatedPtr& agent);
+ static bool ShouldSendOnIO(const std::string& method);
struct Message {
std::string method;
std::string message;
@@ -46,6 +52,10 @@ class DevToolsSession : public protocol::FrontendChannel {
const std::string& message,
int* call_id,
std::string* method);
+ void DispatchProtocolMessageToAgent(int call_id,
+ const std::string& method,
+ const std::string& message);
+ void InspectElement(const gfx::Point& point);
bool ReceiveMessageChunk(const DevToolsMessageChunk& chunk);
void SendMessageToClient(const std::string& message);
@@ -65,8 +75,10 @@ class DevToolsSession : public protocol::FrontendChannel {
}
private:
- void SendMessageFromProcessor(int session_id, const std::string& message);
+ void SendMessageFromProcessorIPC(int session_id, const std::string& message);
+ void SendMessageFromProcessor(const std::string& message);
void SendResponse(std::unique_ptr<base::DictionaryValue> response);
+ void MojoConnectionDestroyed();
// protocol::FrontendChannel implementation.
void sendProtocolResponse(
@@ -76,6 +88,14 @@ class DevToolsSession : public protocol::FrontendChannel {
std::unique_ptr<protocol::Serializable> message) override;
void flushProtocolNotifications() override;
+ // mojom::DevToolsSessionHost implementation.
+ void DispatchProtocolMessage(mojom::DevToolsMessageChunkPtr chunk) override;
+ void RequestNewWindow(int32_t frame_routing_id,
+ RequestNewWindowCallback callback) override;
+
+ mojo::AssociatedBinding<mojom::DevToolsSessionHost> binding_;
+ mojom::DevToolsSessionAssociatedPtr session_ptr_;
+ mojom::DevToolsSessionPtr io_session_ptr_;
DevToolsAgentHostImpl* agent_host_;
DevToolsAgentHostClient* client_;
int session_id_;
diff --git a/chromium/content/browser/devtools/devtools_target_registry.cc b/chromium/content/browser/devtools/devtools_target_registry.cc
new file mode 100644
index 00000000000..eefc74d8d0a
--- /dev/null
+++ b/chromium/content/browser/devtools/devtools_target_registry.cc
@@ -0,0 +1,211 @@
+// Copyright 2017 The Chromium Authors. 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_target_registry.h"
+
+#include "base/task_runner.h"
+#include "base/threading/thread_checker.h"
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/web_contents_observer.h"
+
+namespace content {
+
+namespace {
+
+std::unique_ptr<const DevToolsTargetRegistry::TargetInfo> BuildTargetInfo(
+ RenderFrameHost* rfh) {
+ std::unique_ptr<DevToolsTargetRegistry::TargetInfo> info(
+ new DevToolsTargetRegistry::TargetInfo());
+ info->child_id = rfh->GetProcess()->GetID();
+ info->routing_id = rfh->GetRoutingID();
+
+ const FrameTreeNode* ftn =
+ static_cast<RenderFrameHostImpl*>(rfh)->frame_tree_node();
+ info->devtools_token = ftn->devtools_frame_token();
+ info->frame_tree_node_id = ftn->frame_tree_node_id();
+
+ // TODO(crbug.com/777516): this actually needs to return the nearest local
+ // root (or self). However, for now we keep the existing semantics of request
+ // matching in interceptor, which is intercepting all requests for given
+ // web contents, that tests (and potentially some clients) depend on.
+ // When those are fixed, the condition in the loop below should include
+ // !rfh->IsCrossProcessSubframe().
+ // Watch out for current (leaf) frame host being null
+ // when it's being destroyed.
+ while (!ftn->IsMainFrame()) {
+ ftn = ftn->parent();
+ rfh = ftn->current_frame_host();
+ }
+ info->devtools_target_id = ftn->devtools_frame_token();
+
+ return std::move(info);
+}
+
+} // namespace
+
+class DevToolsTargetRegistry::Impl : public DevToolsTargetRegistry::Resolver {
+ public:
+ using TargetInfo = DevToolsTargetRegistry::TargetInfo;
+
+ const DevToolsTargetRegistry::TargetInfo* GetInfoByFrameTreeNodeId(
+ int frame_node_id) override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ auto it = target_info_by_ftn_id_.find(frame_node_id);
+ return it != target_info_by_ftn_id_.end() ? it->second : nullptr;
+ }
+
+ const DevToolsTargetRegistry::TargetInfo* GetInfoByRenderFramePair(
+ int child_id,
+ int routing_id) override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ auto it = target_info_by_render_frame_pair_.find(
+ std::make_pair(child_id, routing_id));
+ return it != target_info_by_render_frame_pair_.end() ? it->second.get()
+ : nullptr;
+ }
+
+ void Add(std::unique_ptr<const TargetInfo> info) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (info->frame_tree_node_id != -1) {
+ target_info_by_ftn_id_.insert(
+ std::make_pair(info->frame_tree_node_id, info.get()));
+ }
+ auto key = std::make_pair(info->child_id, info->routing_id);
+ target_info_by_render_frame_pair_.insert(
+ std::make_pair(key, std::move(info)));
+ }
+
+ void Remove(const TargetInfo& info) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (info.frame_tree_node_id != -1)
+ target_info_by_ftn_id_.erase(info.frame_tree_node_id);
+ target_info_by_render_frame_pair_.erase(
+ std::make_pair(info.child_id, info.routing_id));
+ }
+
+ void AddAll(std::vector<std::unique_ptr<const TargetInfo>> infos) {
+ for (auto& info : infos)
+ Add(std::move(info));
+ }
+
+ void RemoveAll(std::vector<std::unique_ptr<const TargetInfo>> infos) {
+ for (auto& info : infos)
+ Remove(*info);
+ }
+
+ void Update(std::unique_ptr<const TargetInfo> old_info,
+ std::unique_ptr<const TargetInfo> new_info) {
+ if (old_info)
+ Remove(*old_info);
+ if (new_info)
+ Add(std::move(new_info));
+ }
+
+ Impl() : weak_factory_(this) { DETACH_FROM_THREAD(thread_checker_); }
+ ~Impl() override = default;
+
+ private:
+ friend class DevToolsTargetRegistry;
+
+ base::flat_map<std::pair<int, int>, std::unique_ptr<const TargetInfo>>
+ target_info_by_render_frame_pair_;
+ base::flat_map<int, const TargetInfo*> target_info_by_ftn_id_;
+ THREAD_CHECKER(thread_checker_);
+
+ base::WeakPtrFactory<DevToolsTargetRegistry::Impl> weak_factory_;
+};
+
+class DevToolsTargetRegistry::ContentsObserver : public ObserverBase,
+ public WebContentsObserver {
+ public:
+ ContentsObserver(WebContents* web_contents, DevToolsTargetRegistry* registry)
+ : WebContentsObserver(web_contents), registry_(registry) {}
+
+ private:
+ void RenderFrameHostChanged(RenderFrameHost* old_host,
+ RenderFrameHost* new_host) override {
+ std::unique_ptr<const TargetInfo> old_target;
+ if (old_host)
+ old_target = BuildTargetInfo(old_host);
+ std::unique_ptr<const TargetInfo> new_target = BuildTargetInfo(new_host);
+ registry_->impl_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DevToolsTargetRegistry::Impl::Update, registry_->impl_,
+ std::move(old_target), std::move(new_target)));
+ }
+
+ void FrameDeleted(RenderFrameHost* render_frame_host) override {
+ registry_->impl_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DevToolsTargetRegistry::Impl::Update, registry_->impl_,
+ BuildTargetInfo(render_frame_host), nullptr));
+ }
+
+ void WebContentsDestroyed() override {
+ NOTREACHED() << "DevToolsTarget Registry clients should be destroyed "
+ "before WebContents";
+ }
+
+ ~ContentsObserver() override {
+ registry_->UnregisterWebContents(web_contents());
+ }
+
+ DevToolsTargetRegistry* registry_;
+};
+
+DevToolsTargetRegistry::RegistrationHandle
+DevToolsTargetRegistry::RegisterWebContents(WebContents* web_contents) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ auto it = observers_.find(web_contents);
+ if (it != observers_.end())
+ return it->second;
+
+ scoped_refptr<ContentsObserver> observer =
+ new DevToolsTargetRegistry::ContentsObserver(web_contents, this);
+ observers_.insert(std::make_pair(web_contents, observer.get()));
+ std::vector<std::unique_ptr<const TargetInfo>> infos;
+ for (RenderFrameHost* render_frame_host : web_contents->GetAllFrames())
+ infos.push_back(BuildTargetInfo(render_frame_host));
+
+ impl_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&DevToolsTargetRegistry::Impl::AddAll, impl_,
+ std::move(infos)));
+ return observer;
+}
+
+std::unique_ptr<DevToolsTargetRegistry::Resolver>
+DevToolsTargetRegistry::CreateResolver() {
+ DCHECK(!impl_);
+
+ auto impl = std::make_unique<Impl>();
+ impl_ = impl->weak_factory_.GetWeakPtr();
+ return std::move(impl);
+}
+
+void DevToolsTargetRegistry::UnregisterWebContents(WebContents* web_contents) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ size_t count = observers_.erase(web_contents);
+ DCHECK_NE(count, 0ul);
+
+ std::vector<std::unique_ptr<const TargetInfo>> infos;
+ for (RenderFrameHost* render_frame_host : web_contents->GetAllFrames())
+ infos.push_back(BuildTargetInfo(render_frame_host));
+
+ impl_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&DevToolsTargetRegistry::Impl::RemoveAll, impl_,
+ std::move(infos)));
+}
+
+DevToolsTargetRegistry::DevToolsTargetRegistry(
+ scoped_refptr<base::SequencedTaskRunner> impl_task_runner)
+ : impl_task_runner_(impl_task_runner) {}
+
+DevToolsTargetRegistry::~DevToolsTargetRegistry() = default;
+
+} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_target_registry.h b/chromium/content/browser/devtools/devtools_target_registry.h
new file mode 100644
index 00000000000..27d5e68922f
--- /dev/null
+++ b/chromium/content/browser/devtools/devtools_target_registry.h
@@ -0,0 +1,77 @@
+// Copyright 2017 The Chromium Authors. 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_TARGET_REGISTRY_H_
+#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TARGET_REGISTRY_H_
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "base/containers/flat_map.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/singleton.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner.h"
+#include "base/threading/thread_checker.h"
+#include "base/unguessable_token.h"
+
+namespace content {
+
+class WebContents;
+
+class DevToolsTargetRegistry {
+ public:
+ struct TargetInfo {
+ int child_id;
+ int routing_id;
+ int frame_tree_node_id;
+ base::UnguessableToken devtools_token;
+ base::UnguessableToken devtools_target_id;
+ };
+
+ class ObserverBase : public base::RefCounted<ObserverBase> {
+ protected:
+ friend class base::RefCounted<ObserverBase>;
+ virtual ~ObserverBase() {}
+ };
+ using RegistrationHandle = scoped_refptr<ObserverBase>;
+
+ // Impl thread methods
+ class Resolver {
+ public:
+ virtual const TargetInfo* GetInfoByFrameTreeNodeId(int frame_node_id) = 0;
+ virtual const TargetInfo* GetInfoByRenderFramePair(int child_id,
+ int routing_id) = 0;
+ virtual ~Resolver() {}
+ };
+
+ // UI thread method
+ RegistrationHandle RegisterWebContents(WebContents* web_contents);
+ std::unique_ptr<Resolver> CreateResolver();
+
+ explicit DevToolsTargetRegistry(
+ scoped_refptr<base::SequencedTaskRunner> impl_task_runner);
+ ~DevToolsTargetRegistry();
+
+ private:
+ void UnregisterWebContents(WebContents* web_contents);
+
+ class ContentsObserver;
+ class Impl;
+
+ scoped_refptr<base::SequencedTaskRunner> impl_task_runner_;
+ // Observers are owned by the clients and are cleaned up from this
+ // map when destroyed.
+ base::flat_map<WebContents*, ContentsObserver*> observers_;
+
+ base::WeakPtr<Impl> impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsTargetRegistry);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TARGET_REGISTRY_H_
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 b7e3abdd971..5ddde72bf0a 100644
--- a/chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc
+++ b/chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc
@@ -4,12 +4,14 @@
#include "content/browser/devtools/devtools_url_interceptor_request_job.h"
+#include "base/base64.h"
#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/devtools/protocol/network_handler.h"
#include "content/browser/devtools/protocol/page.h"
#include "content/browser/loader/resource_request_info_impl.h"
+#include "ipc/ipc_channel.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/io_buffer.h"
#include "net/base/upload_bytes_element_reader.h"
@@ -20,115 +22,452 @@
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request_context.h"
+namespace {
+static const int kInitialBufferSize = 4096;
+static const int kMaxBufferSize = IPC::Channel::kMaximumMessageSize / 4;
+} // namespace
+
namespace content {
-namespace {
-const char* ResourceTypeToString(ResourceType resource_type) {
- switch (resource_type) {
- case RESOURCE_TYPE_MAIN_FRAME:
- return protocol::Page::ResourceTypeEnum::Document;
- case RESOURCE_TYPE_SUB_FRAME:
- return protocol::Page::ResourceTypeEnum::Document;
- case RESOURCE_TYPE_STYLESHEET:
- return protocol::Page::ResourceTypeEnum::Stylesheet;
- case RESOURCE_TYPE_SCRIPT:
- return protocol::Page::ResourceTypeEnum::Script;
- case RESOURCE_TYPE_IMAGE:
- return protocol::Page::ResourceTypeEnum::Image;
- case RESOURCE_TYPE_FONT_RESOURCE:
- return protocol::Page::ResourceTypeEnum::Font;
- case RESOURCE_TYPE_SUB_RESOURCE:
- return protocol::Page::ResourceTypeEnum::Other;
- case RESOURCE_TYPE_OBJECT:
- return protocol::Page::ResourceTypeEnum::Other;
- case RESOURCE_TYPE_MEDIA:
- return protocol::Page::ResourceTypeEnum::Media;
- case RESOURCE_TYPE_WORKER:
- return protocol::Page::ResourceTypeEnum::Other;
- case RESOURCE_TYPE_SHARED_WORKER:
- return protocol::Page::ResourceTypeEnum::Other;
- case RESOURCE_TYPE_PREFETCH:
- return protocol::Page::ResourceTypeEnum::Fetch;
- case RESOURCE_TYPE_FAVICON:
- return protocol::Page::ResourceTypeEnum::Other;
- case RESOURCE_TYPE_XHR:
- return protocol::Page::ResourceTypeEnum::XHR;
- case RESOURCE_TYPE_PING:
- return protocol::Page::ResourceTypeEnum::Other;
- case RESOURCE_TYPE_SERVICE_WORKER:
- return protocol::Page::ResourceTypeEnum::Other;
- case RESOURCE_TYPE_CSP_REPORT:
- return protocol::Page::ResourceTypeEnum::Other;
- case RESOURCE_TYPE_PLUGIN_RESOURCE:
- return protocol::Page::ResourceTypeEnum::Other;
- default:
- return protocol::Page::ResourceTypeEnum::Other;
+// DevToolsURLInterceptorRequestJob::SubRequest ---------------------
+
+// If the request was either allowed or modified, a SubRequest will be used to
+// perform the fetch and the results proxied to the original request. This
+// gives us the flexibility to pretend redirects didn't happen if the user
+// chooses to mock the response. Note this SubRequest is ignored by the
+// interceptor.
+class DevToolsURLInterceptorRequestJob::SubRequest
+ : public net::URLRequest::Delegate {
+ public:
+ SubRequest(DevToolsURLInterceptorRequestJob::RequestDetails& request_details,
+ DevToolsURLInterceptorRequestJob* devtools_interceptor_request_job,
+ DevToolsURLRequestInterceptor* interceptor);
+ ~SubRequest() override;
+
+ // net::URLRequest::Delegate methods:
+ void OnAuthRequired(net::URLRequest* request,
+ net::AuthChallengeInfo* auth_info) override;
+ void OnCertificateRequested(
+ net::URLRequest* request,
+ net::SSLCertRequestInfo* cert_request_info) override;
+ void OnSSLCertificateError(net::URLRequest* request,
+ const net::SSLInfo& ssl_info,
+ bool fatal) override;
+ void OnResponseStarted(net::URLRequest* request, int net_error) override;
+ void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
+ void OnReceivedRedirect(net::URLRequest* request,
+ const net::RedirectInfo& redirect_info,
+ bool* defer_redirect) override;
+
+ virtual int Read(net::IOBuffer* buf, int buf_size);
+ void Cancel();
+
+ net::URLRequest* request() const { return request_.get(); }
+
+ protected:
+ std::unique_ptr<net::URLRequest> request_;
+
+ DevToolsURLInterceptorRequestJob*
+ devtools_interceptor_request_job_; // NOT OWNED.
+
+ DevToolsURLRequestInterceptor* const interceptor_;
+ bool fetch_in_progress_;
+};
+
+DevToolsURLInterceptorRequestJob::SubRequest::SubRequest(
+ DevToolsURLInterceptorRequestJob::RequestDetails& request_details,
+ DevToolsURLInterceptorRequestJob* devtools_interceptor_request_job,
+ DevToolsURLRequestInterceptor* interceptor)
+ : devtools_interceptor_request_job_(devtools_interceptor_request_job),
+ interceptor_(interceptor),
+ fetch_in_progress_(true) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("devtools_interceptor", R"(
+ semantics {
+ sender: "Developer Tools"
+ description:
+ "When user is debugging a page, all actions resulting in a network "
+ "request are intercepted to enrich the debugging experience."
+ trigger:
+ "User triggers an action that requires network request (like "
+ "navigation, download, etc.) while debugging the page."
+ data:
+ "Any data that user action sends."
+ destination: WEBSITE
+ }
+ policy {
+ cookies_allowed: YES
+ cookies_store: "user"
+ setting:
+ "This feature cannot be disabled in settings, however it happens "
+ "only when user is debugging a page."
+ chrome_policy {
+ DeveloperToolsDisabled {
+ DeveloperToolsDisabled: true
+ }
+ }
+ })");
+ request_ = request_details.url_request_context->CreateRequest(
+ request_details.url, request_details.priority, this, traffic_annotation);
+ request_->set_method(request_details.method);
+ request_->SetExtraRequestHeaders(request_details.extra_request_headers);
+
+ // Mimic the ResourceRequestInfoImpl of the original request.
+ const ResourceRequestInfoImpl* resource_request_info =
+ static_cast<const ResourceRequestInfoImpl*>(
+ ResourceRequestInfo::ForRequest(
+ devtools_interceptor_request_job->request()));
+ ResourceRequestInfoImpl* extra_data = new ResourceRequestInfoImpl(
+ resource_request_info->requester_info(),
+ resource_request_info->GetRouteID(),
+ resource_request_info->GetFrameTreeNodeId(),
+ resource_request_info->GetPluginChildID(),
+ resource_request_info->GetRequestID(),
+ resource_request_info->GetRenderFrameID(),
+ resource_request_info->IsMainFrame(),
+ resource_request_info->GetResourceType(),
+ resource_request_info->GetPageTransition(),
+ resource_request_info->should_replace_current_entry(),
+ resource_request_info->IsDownload(), resource_request_info->is_stream(),
+ resource_request_info->allow_download(),
+ resource_request_info->HasUserGesture(),
+ resource_request_info->is_load_timing_enabled(),
+ resource_request_info->is_upload_progress_enabled(),
+ resource_request_info->do_not_prompt_for_login(),
+ resource_request_info->keepalive(),
+ resource_request_info->GetReferrerPolicy(),
+ resource_request_info->GetVisibilityState(),
+ resource_request_info->GetContext(),
+ resource_request_info->ShouldReportRawHeaders(),
+ resource_request_info->IsAsync(),
+ resource_request_info->GetPreviewsState(), resource_request_info->body(),
+ resource_request_info->initiated_in_secure_context());
+ extra_data->AssociateWithRequest(request_.get());
+
+ if (request_details.post_data)
+ request_->set_upload(std::move(request_details.post_data));
+
+ interceptor_->RegisterSubRequest(request_.get());
+ request_->Start();
+}
+
+DevToolsURLInterceptorRequestJob::SubRequest::~SubRequest() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ fetch_in_progress_ = false;
+ interceptor_->UnregisterSubRequest(request_.get());
+}
+
+void DevToolsURLInterceptorRequestJob::SubRequest::Cancel() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (!fetch_in_progress_)
+ return;
+
+ fetch_in_progress_ = false;
+ request_->Cancel();
+}
+
+void DevToolsURLInterceptorRequestJob::SubRequest::OnAuthRequired(
+ net::URLRequest* request,
+ net::AuthChallengeInfo* auth_info) {
+ devtools_interceptor_request_job_->OnSubRequestAuthRequired(auth_info);
+}
+
+void DevToolsURLInterceptorRequestJob::SubRequest::OnCertificateRequested(
+ net::URLRequest* request,
+ net::SSLCertRequestInfo* cert_request_info) {
+ devtools_interceptor_request_job_->NotifyCertificateRequested(
+ cert_request_info);
+}
+
+void DevToolsURLInterceptorRequestJob::SubRequest::OnSSLCertificateError(
+ net::URLRequest* request,
+ const net::SSLInfo& ssl_info,
+ bool fatal) {
+ devtools_interceptor_request_job_->NotifySSLCertificateError(ssl_info, fatal);
+}
+
+void DevToolsURLInterceptorRequestJob::SubRequest::OnResponseStarted(
+ net::URLRequest* request,
+ int net_error) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_NE(net::ERR_IO_PENDING, net_error);
+ devtools_interceptor_request_job_->OnSubRequestResponseStarted(
+ static_cast<net::Error>(net_error));
+}
+
+void DevToolsURLInterceptorRequestJob::SubRequest::OnReadCompleted(
+ net::URLRequest* request,
+ int bytes_read) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_NE(bytes_read, net::ERR_IO_PENDING);
+ // OnReadCompleted may get called while canceling the subrequest, in that
+ // event theres no need to call ReadRawDataComplete.
+ if (fetch_in_progress_)
+ devtools_interceptor_request_job_->ReadRawDataComplete(bytes_read);
+}
+
+void DevToolsURLInterceptorRequestJob::SubRequest::OnReceivedRedirect(
+ net::URLRequest* request,
+ const net::RedirectInfo& redirectinfo,
+ bool* defer_redirect) {
+ devtools_interceptor_request_job_->OnSubRequestRedirectReceived(
+ *request, redirectinfo, defer_redirect);
+}
+
+int DevToolsURLInterceptorRequestJob::SubRequest::Read(net::IOBuffer* buf,
+ int buf_size) {
+ return request_->Read(buf, buf_size);
+}
+
+// DevToolsURLInterceptorRequestJob::InterceptedRequest ---------------------
+
+class DevToolsURLInterceptorRequestJob::InterceptedRequest
+ : public DevToolsURLInterceptorRequestJob::SubRequest {
+ public:
+ InterceptedRequest(
+ DevToolsURLInterceptorRequestJob::RequestDetails& request_details,
+ DevToolsURLInterceptorRequestJob* devtools_interceptor_request_job,
+ DevToolsURLRequestInterceptor* interceptor);
+ ~InterceptedRequest() override {}
+
+ // net::URLRequest::Delegate methods.
+ void OnResponseStarted(net::URLRequest* request, int net_error) override;
+ void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
+
+ int Read(net::IOBuffer* buf, int buf_size) override;
+
+ // Can only call FetchResponseBody() after OnInterceptedRequestResponseStarted
+ // has been fired and before call to Read().
+ void FetchResponseBody();
+
+ private:
+ void OnDataChunkRead(int result);
+ bool ShouldContinueRead();
+ void ReadIntoBuffer();
+
+ scoped_refptr<net::GrowableIOBuffer> response_buffer_;
+ int read_response_result_;
+ bool read_started_;
+};
+
+DevToolsURLInterceptorRequestJob::InterceptedRequest::InterceptedRequest(
+ DevToolsURLInterceptorRequestJob::RequestDetails& request_details,
+ DevToolsURLInterceptorRequestJob* devtools_interceptor_request_job,
+ DevToolsURLRequestInterceptor* interceptor)
+ : SubRequest(request_details,
+ devtools_interceptor_request_job,
+ interceptor),
+ response_buffer_(new net::GrowableIOBuffer()),
+ read_response_result_(0),
+ read_started_(false) {}
+
+void DevToolsURLInterceptorRequestJob::InterceptedRequest::OnResponseStarted(
+ net::URLRequest* request,
+ int net_error) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_NE(net::ERR_IO_PENDING, net_error);
+
+ if (net_error != net::OK) {
+ // If we have an error here, we cannot read the body, so we
+ // flag it here as already read and set the result.
+ DCHECK_EQ(read_response_result_, 0);
+ read_started_ = true;
+ read_response_result_ = net_error;
}
+ response_buffer_->SetCapacity(kInitialBufferSize);
+
+ devtools_interceptor_request_job_->OnInterceptedRequestResponseStarted(
+ static_cast<net::Error>(net_error));
}
-bool IsNavigationRequest(ResourceType resource_type) {
- return resource_type == RESOURCE_TYPE_MAIN_FRAME ||
- resource_type == RESOURCE_TYPE_SUB_FRAME;
+void DevToolsURLInterceptorRequestJob::InterceptedRequest::OnReadCompleted(
+ net::URLRequest* request,
+ int result) {
+ // OnReadComplete may be called while request is being cancelled, in this
+ // event the result should be |net::ERR_ABORTED| which should complete any
+ // |pending_body_requests_|.
+ OnDataChunkRead(result);
+ if (ShouldContinueRead())
+ ReadIntoBuffer();
}
-void UnregisterNavigationRequestOnUI(
- base::WeakPtr<protocol::NetworkHandler> network_handler,
- std::string interception_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!network_handler)
+bool DevToolsURLInterceptorRequestJob::InterceptedRequest::
+ ShouldContinueRead() {
+ return fetch_in_progress_ && read_response_result_ == net::ERR_IO_PENDING;
+}
+
+void DevToolsURLInterceptorRequestJob::InterceptedRequest::OnDataChunkRead(
+ int result) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_NE(result, net::ERR_IO_PENDING);
+ if (result == 0) {
+ read_response_result_ = response_buffer_->offset();
+ // Response is done so, reset buffer to zero so it can be read from the
+ // beginning as an IOBuffer.
+ response_buffer_->set_offset(0);
+ } else if (result < 0) {
+ read_response_result_ = result;
+ } else {
+ response_buffer_->set_offset(response_buffer_->offset() + result);
+ }
+
+ if (response_buffer_->offset() > kMaxBufferSize) {
+ response_buffer_->SetCapacity(0);
+ read_response_result_ = net::ERR_FILE_TOO_BIG;
+ }
+ if (read_response_result_ != net::ERR_IO_PENDING) {
+ devtools_interceptor_request_job_->OnInterceptedRequestResponseReady(
+ *response_buffer_.get(), read_response_result_);
return;
- network_handler->InterceptedNavigationRequestFinished(interception_id);
+ }
}
-void SendRequestInterceptedEventOnUiThread(
- base::WeakPtr<protocol::NetworkHandler> network_handler,
- std::string interception_id,
- GlobalRequestID global_request_id,
- std::unique_ptr<protocol::Network::Request> network_request,
- ResourceType resource_type) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!network_handler)
+int DevToolsURLInterceptorRequestJob::InterceptedRequest::Read(
+ net::IOBuffer* buf,
+ int buf_size) {
+ DCHECK(read_started_);
+ DCHECK_NE(read_response_result_, net::ERR_IO_PENDING);
+ if (read_response_result_ <= 0)
+ return read_response_result_;
+ int read_size = std::min(buf_size, read_response_result_);
+ std::memcpy(buf->data(), response_buffer_->data(), read_size);
+ response_buffer_->set_offset(response_buffer_->offset() + read_size);
+ read_response_result_ -= read_size;
+ return read_size;
+}
+
+void DevToolsURLInterceptorRequestJob::InterceptedRequest::FetchResponseBody() {
+ if (read_started_) {
+ if (read_response_result_ != net::ERR_IO_PENDING) {
+ devtools_interceptor_request_job_->OnInterceptedRequestResponseReady(
+ *response_buffer_.get(), read_response_result_);
+ }
+ return;
+ }
+ if (!fetch_in_progress_) {
+ // Cannot request body on cancelled request.
+ devtools_interceptor_request_job_->OnInterceptedRequestResponseReady(
+ *response_buffer_.get(), net::ERR_ABORTED);
return;
- if (IsNavigationRequest(resource_type)) {
- network_handler->InterceptedNavigationRequest(global_request_id,
- interception_id);
}
- network_handler->frontend()->RequestIntercepted(
- interception_id, std::move(network_request),
- ResourceTypeToString(resource_type), IsNavigationRequest(resource_type));
+ read_started_ = true;
+ read_response_result_ = net::ERR_IO_PENDING;
+ ReadIntoBuffer();
}
-void SendRedirectInterceptedEventOnUiThread(
- base::WeakPtr<protocol::NetworkHandler> network_handler,
- std::string interception_id,
- std::unique_ptr<protocol::Network::Request> network_request,
- ResourceType resource_type,
- std::unique_ptr<protocol::Object> headers_object,
- int http_status_code,
- std::string redirect_url) {
+void DevToolsURLInterceptorRequestJob::InterceptedRequest::ReadIntoBuffer() {
+ // OnReadCompleted may get called while canceling the subrequest, in that
+ // event we cannot call URLRequest::Read().
+ DCHECK(fetch_in_progress_);
+ while (ShouldContinueRead()) {
+ if (response_buffer_->RemainingCapacity() == 0)
+ response_buffer_->SetCapacity(response_buffer_->capacity() * 2);
+ int result = request_->Read(response_buffer_.get(),
+ response_buffer_->RemainingCapacity());
+ if (result == net::ERR_IO_PENDING)
+ return;
+ OnDataChunkRead(result);
+ }
+}
+
+class DevToolsURLInterceptorRequestJob::MockResponseDetails {
+ public:
+ MockResponseDetails(std::string response_bytes,
+ base::TimeTicks response_time);
+
+ MockResponseDetails(
+ const scoped_refptr<net::HttpResponseHeaders>& response_headers,
+ std::string response_bytes,
+ size_t read_offset,
+ base::TimeTicks response_time);
+
+ ~MockResponseDetails();
+
+ scoped_refptr<net::HttpResponseHeaders>& response_headers() {
+ return response_headers_;
+ }
+
+ base::TimeTicks response_time() const { return response_time_; }
+
+ int ReadRawData(net::IOBuffer* buf, int buf_size);
+
+ private:
+ scoped_refptr<net::HttpResponseHeaders> response_headers_;
+ std::string response_bytes_;
+ size_t read_offset_;
+ base::TimeTicks response_time_;
+};
+
+DevToolsURLInterceptorRequestJob::MockResponseDetails::MockResponseDetails(
+ std::string response_bytes,
+ base::TimeTicks response_time)
+ : response_bytes_(std::move(response_bytes)),
+ read_offset_(0),
+ response_time_(response_time) {
+ int header_size = net::HttpUtil::LocateEndOfHeaders(response_bytes_.c_str(),
+ response_bytes_.size());
+ if (header_size == -1) {
+ LOG(WARNING) << "Can't find headers in result";
+ response_headers_ = new net::HttpResponseHeaders("");
+ } else {
+ response_headers_ =
+ new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
+ response_bytes_.c_str(), header_size));
+ read_offset_ = header_size;
+ }
+
+ CHECK_LE(read_offset_, response_bytes_.size());
+}
+
+DevToolsURLInterceptorRequestJob::MockResponseDetails::MockResponseDetails(
+ const scoped_refptr<net::HttpResponseHeaders>& response_headers,
+ std::string response_bytes,
+ size_t read_offset,
+ base::TimeTicks response_time)
+ : response_headers_(response_headers),
+ response_bytes_(std::move(response_bytes)),
+ read_offset_(read_offset),
+ response_time_(response_time) {}
+
+DevToolsURLInterceptorRequestJob::MockResponseDetails::~MockResponseDetails() {}
+
+int DevToolsURLInterceptorRequestJob::MockResponseDetails::ReadRawData(
+ net::IOBuffer* buf,
+ int buf_size) {
+ size_t bytes_available = response_bytes_.size() - read_offset_;
+ size_t bytes_to_copy =
+ std::min(static_cast<size_t>(buf_size), bytes_available);
+ if (bytes_to_copy > 0) {
+ std::memcpy(buf->data(), &response_bytes_.data()[read_offset_],
+ bytes_to_copy);
+ read_offset_ += bytes_to_copy;
+ }
+ return bytes_to_copy;
+}
+
+namespace {
+
+void SendPendingBodyRequestsOnUiThread(
+ std::vector<std::unique_ptr<
+ protocol::Network::Backend::GetResponseBodyForInterceptionCallback>>
+ callbacks,
+ std::string content) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!network_handler)
- return;
- network_handler->frontend()->RequestIntercepted(
- interception_id, std::move(network_request),
- ResourceTypeToString(resource_type), IsNavigationRequest(resource_type),
- std::move(headers_object), http_status_code, redirect_url);
+ std::string encoded_response;
+ base::Base64Encode(content, &encoded_response);
+ for (auto&& callback : callbacks)
+ callback->sendSuccess(encoded_response, true);
}
-void SendAuthRequiredEventOnUiThread(
- base::WeakPtr<protocol::NetworkHandler> network_handler,
- std::string interception_id,
- std::unique_ptr<protocol::Network::Request> network_request,
- ResourceType resource_type,
- std::unique_ptr<protocol::Network::AuthChallenge> auth_challenge) {
+void SendPendingBodyRequestsWithErrorOnUiThread(
+ std::vector<std::unique_ptr<
+ protocol::Network::Backend::GetResponseBodyForInterceptionCallback>>
+ callbacks,
+ protocol::DispatchResponse error) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!network_handler)
- return;
- network_handler->frontend()->RequestIntercepted(
- interception_id, std::move(network_request),
- ResourceTypeToString(resource_type), IsNavigationRequest(resource_type),
- protocol::Maybe<protocol::Network::Headers>(), protocol::Maybe<int>(),
- protocol::Maybe<protocol::String>(), std::move(auth_challenge));
+ for (auto&& callback : callbacks)
+ callback->sendFailure(error);
}
class ProxyUploadElementReader : public net::UploadElementReader {
@@ -176,27 +515,28 @@ std::unique_ptr<net::UploadDataStream> GetUploadData(net::URLRequest* request) {
proxy_readers.reserve(readers->size());
for (auto& reader : *readers) {
proxy_readers.push_back(
- base::MakeUnique<ProxyUploadElementReader>(reader.get()));
+ std::make_unique<ProxyUploadElementReader>(reader.get()));
}
- return base::MakeUnique<net::ElementsUploadDataStream>(
+ return std::make_unique<net::ElementsUploadDataStream>(
std::move(proxy_readers), 0);
}
+
} // namespace
DevToolsURLInterceptorRequestJob::DevToolsURLInterceptorRequestJob(
- scoped_refptr<DevToolsURLRequestInterceptor::State>
- devtools_url_request_interceptor_state,
+ DevToolsURLRequestInterceptor* interceptor,
const std::string& interception_id,
+ intptr_t owning_entry_id,
net::URLRequest* original_request,
net::NetworkDelegate* original_network_delegate,
- WebContents* web_contents,
- base::WeakPtr<protocol::NetworkHandler> network_handler,
+ const base::UnguessableToken& devtools_token,
+ DevToolsURLRequestInterceptor::RequestInterceptedCallback callback,
bool is_redirect,
- ResourceType resource_type)
+ ResourceType resource_type,
+ InterceptionStage stage_to_intercept)
: net::URLRequestJob(original_request, original_network_delegate),
- devtools_url_request_interceptor_state_(
- devtools_url_request_interceptor_state),
+ interceptor_(interceptor),
request_details_(original_request->url(),
original_request->method(),
GetUploadData(original_request),
@@ -204,29 +544,22 @@ DevToolsURLInterceptorRequestJob::DevToolsURLInterceptorRequestJob(
original_request->priority(),
original_request->context()),
waiting_for_user_response_(WaitingForUserResponse::NOT_WAITING),
- intercepting_requests_(true),
- killed_(false),
interception_id_(interception_id),
- web_contents_(web_contents),
- network_handler_(network_handler),
+ owning_entry_id_(owning_entry_id),
+ devtools_token_(devtools_token),
+ callback_(callback),
is_redirect_(is_redirect),
resource_type_(resource_type),
+ stage_to_intercept_(stage_to_intercept),
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (const ResourceRequestInfo* info =
- ResourceRequestInfo::ForRequest(original_request)) {
- global_request_id_ = info->GetGlobalRequestID();
- }
}
DevToolsURLInterceptorRequestJob::~DevToolsURLInterceptorRequestJob() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (IsNavigationRequest(resource_type_)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(UnregisterNavigationRequestOnUI,
- network_handler_, interception_id_));
- }
- devtools_url_request_interceptor_state_->JobFinished(interception_id_);
+ interceptor_->JobFinished(
+ interception_id_,
+ DevToolsURLRequestInterceptor::IsNavigationRequest(resource_type_));
}
// net::URLRequestJob implementation:
@@ -237,28 +570,47 @@ void DevToolsURLInterceptorRequestJob::SetExtraRequestHeaders(
void DevToolsURLInterceptorRequestJob::Start() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (is_redirect_ || !intercepting_requests_) {
- // If this is a fetch in response to a redirect, we have already sent the
- // Network.requestIntercepted event and the user opted to allow it so
- // there's no need to send another. We can just start the SubRequest.
- // If we're not intercepting results we can also just start the SubRequest.
- sub_request_.reset(new SubRequest(request_details_, this,
- devtools_url_request_interceptor_state_));
- } else {
- waiting_for_user_response_ =
- WaitingForUserResponse::WAITING_FOR_INTERCEPTION_RESPONSE;
- std::unique_ptr<protocol::Network::Request> network_request =
- protocol::NetworkHandler::CreateRequestFromURLRequest(request());
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(SendRequestInterceptedEventOnUiThread, network_handler_,
- interception_id_, global_request_id_,
- base::Passed(&network_request), resource_type_));
+ if (stage_to_intercept_ == InterceptionStage::DONT_INTERCEPT) {
+ sub_request_.reset(new SubRequest(request_details_, this, interceptor_));
+ return;
}
+
+ if (is_redirect_) {
+ if (stage_to_intercept_ == InterceptionStage::REQUEST) {
+ // If we are a redirect and we do not plan on grabbing the response we are
+ // done. If we are here this means we must have already sent an
+ // intercepted event to front-end for this redirect and the front-end
+ // allowed it. Since we have already allowed the redirect and we are only
+ // intercepting the request, we only need to catch it again if it's
+ // another redirect, which SubRequest will send the
+ // OnSubRequestRedirectReceived event.
+ sub_request_.reset(new SubRequest(request_details_, this, interceptor_));
+ } else {
+ // Otherwise we have already issued the request interception and had a
+ // continue and now we must issue a response interception for the
+ // redirect.
+ sub_request_.reset(
+ new InterceptedRequest(request_details_, this, interceptor_));
+ }
+ return;
+ }
+
+ if (stage_to_intercept_ == InterceptionStage::RESPONSE) {
+ // We are only a response interception, we go right to dispatching the
+ // request.
+ sub_request_.reset(
+ new InterceptedRequest(request_details_, this, interceptor_));
+ return;
+ }
+
+ 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()));
}
void DevToolsURLInterceptorRequestJob::Kill() {
- killed_ = true;
if (sub_request_)
sub_request_->Cancel();
@@ -267,13 +619,11 @@ void DevToolsURLInterceptorRequestJob::Kill() {
int DevToolsURLInterceptorRequestJob::ReadRawData(net::IOBuffer* buf,
int buf_size) {
- if (sub_request_) {
- int size = sub_request_->request()->Read(buf, buf_size);
- return size;
- } else {
- CHECK(mock_response_details_);
+ if (mock_response_details_)
return mock_response_details_->ReadRawData(buf, buf_size);
- }
+
+ CHECK(sub_request_);
+ return sub_request_->Read(buf, buf_size);
}
int DevToolsURLInterceptorRequestJob::GetResponseCode() const {
@@ -353,14 +703,11 @@ void DevToolsURLInterceptorRequestJob::CancelAuth() {
auth_info_ = nullptr;
}
-void DevToolsURLInterceptorRequestJob::OnAuthRequired(
- net::URLRequest* request,
+void DevToolsURLInterceptorRequestJob::OnSubRequestAuthRequired(
net::AuthChallengeInfo* auth_info) {
- DCHECK(sub_request_);
- DCHECK_EQ(request, sub_request_->request());
auth_info_ = auth_info;
- if (!intercepting_requests_) {
+ if (stage_to_intercept_ == InterceptionStage::DONT_INTERCEPT) {
// This should trigger default auth behavior.
// See comment in ProcessAuthRespose.
NotifyHeadersComplete();
@@ -372,12 +719,10 @@ void DevToolsURLInterceptorRequestJob::OnAuthRequired(
// the auth, provide the credentials or proxy it the original
// URLRequest::Delegate.
- waiting_for_user_response_ =
- WaitingForUserResponse::WAITING_FOR_AUTH_RESPONSE;
+ waiting_for_user_response_ = WaitingForUserResponse::WAITING_FOR_AUTH_ACK;
- std::unique_ptr<protocol::Network::Request> network_request =
- protocol::NetworkHandler::CreateRequestFromURLRequest(this->request());
- std::unique_ptr<protocol::Network::AuthChallenge> auth_challenge =
+ std::unique_ptr<InterceptedRequestInfo> request_info = BuildRequestInfo();
+ request_info->auth_challenge =
protocol::Network::AuthChallenge::Create()
.SetSource(auth_info->is_proxy
? protocol::Network::AuthChallenge::SourceEnum::Proxy
@@ -386,71 +731,38 @@ void DevToolsURLInterceptorRequestJob::OnAuthRequired(
.SetScheme(auth_info->scheme)
.SetRealm(auth_info->realm)
.Build();
-
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(SendAuthRequiredEventOnUiThread, network_handler_,
- interception_id_, base::Passed(&network_request),
- resource_type_, base::Passed(&auth_challenge)));
-}
-
-void DevToolsURLInterceptorRequestJob::OnCertificateRequested(
- net::URLRequest* request,
- net::SSLCertRequestInfo* cert_request_info) {
- DCHECK(sub_request_);
- DCHECK_EQ(request, sub_request_->request());
- NotifyCertificateRequested(cert_request_info);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::BindOnce(callback_, std::move(request_info)));
}
-void DevToolsURLInterceptorRequestJob::OnSSLCertificateError(
- net::URLRequest* request,
- const net::SSLInfo& ssl_info,
- bool fatal) {
- DCHECK(sub_request_);
- DCHECK_EQ(request, sub_request_->request());
- NotifySSLCertificateError(ssl_info, fatal);
-}
-
-void DevToolsURLInterceptorRequestJob::OnResponseStarted(
- net::URLRequest* request,
- int net_error) {
+void DevToolsURLInterceptorRequestJob::OnSubRequestResponseStarted(
+ const net::Error& net_error) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(sub_request_);
- DCHECK_EQ(request, sub_request_->request());
- DCHECK_NE(net::ERR_IO_PENDING, net_error);
-
if (net_error != net::OK) {
sub_request_->Cancel();
-
- NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- static_cast<net::Error>(net_error)));
+ NotifyStartError(
+ net::URLRequestStatus(net::URLRequestStatus::FAILED, net_error));
return;
}
NotifyHeadersComplete();
}
-void DevToolsURLInterceptorRequestJob::OnReadCompleted(net::URLRequest* request,
- int num_bytes) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(sub_request_);
- DCHECK_EQ(request, sub_request_->request());
-
- // OnReadCompleted may get called while canceling the subrequest, in that
- // event theres no need to call ReadRawDataComplete.
- if (!killed_)
- ReadRawDataComplete(num_bytes);
-}
-
-void DevToolsURLInterceptorRequestJob::OnReceivedRedirect(
- net::URLRequest* request,
+void DevToolsURLInterceptorRequestJob::OnSubRequestRedirectReceived(
+ const net::URLRequest& request,
const net::RedirectInfo& redirectinfo,
bool* defer_redirect) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(sub_request_);
- DCHECK_EQ(request, sub_request_->request());
// If we're not intercepting results then just exit.
- if (!intercepting_requests_) {
+ if (stage_to_intercept_ == InterceptionStage::DONT_INTERCEPT) {
+ *defer_redirect = false;
+ return;
+ }
+ // If we're a response interception only, we will pick it up on the followup
+ // request in DevToolsURLInterceptorRequestJob::Start().
+ if (stage_to_intercept_ == InterceptionStage::RESPONSE) {
+ interceptor_->ExpectRequestAfterRedirect(this->request(), interception_id_);
*defer_redirect = false;
return;
}
@@ -463,8 +775,8 @@ void DevToolsURLInterceptorRequestJob::OnReceivedRedirect(
std::string header_value;
std::unique_ptr<protocol::DictionaryValue> headers_dict(
protocol::DictionaryValue::create());
- while (request->response_headers()->EnumerateHeaderLines(&iter, &header_name,
- &header_value)) {
+ while (request.response_headers()->EnumerateHeaderLines(&iter, &header_name,
+ &header_value)) {
headers_dict->setString(header_name, header_value);
}
@@ -472,48 +784,111 @@ void DevToolsURLInterceptorRequestJob::OnReceivedRedirect(
sub_request_->Cancel();
sub_request_.reset();
- waiting_for_user_response_ =
- WaitingForUserResponse::WAITING_FOR_INTERCEPTION_RESPONSE;
+ waiting_for_user_response_ = WaitingForUserResponse::WAITING_FOR_REQUEST_ACK;
- std::unique_ptr<protocol::Network::Request> network_request =
- protocol::NetworkHandler::CreateRequestFromURLRequest(this->request());
- std::unique_ptr<protocol::Object> headers_object =
+ std::unique_ptr<InterceptedRequestInfo> request_info = BuildRequestInfo();
+ request_info->response_headers =
protocol::Object::fromValue(headers_dict.get(), nullptr);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(SendRedirectInterceptedEventOnUiThread, network_handler_,
- interception_id_, base::Passed(&network_request),
- resource_type_, base::Passed(&headers_object),
- redirectinfo.status_code, redirectinfo.new_url.spec()));
+ 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)));
+}
+
+void DevToolsURLInterceptorRequestJob::OnInterceptedRequestResponseStarted(
+ const net::Error& net_error) {
+ DCHECK_NE(waiting_for_user_response_,
+ WaitingForUserResponse::WAITING_FOR_RESPONSE_ACK);
+ if (stage_to_intercept_ == InterceptionStage::DONT_INTERCEPT)
+ return;
+ waiting_for_user_response_ = WaitingForUserResponse::WAITING_FOR_RESPONSE_ACK;
+
+ std::unique_ptr<InterceptedRequestInfo> request_info = BuildRequestInfo();
+ if (net_error < 0) {
+ request_info->response_error_code = net_error;
+ } else {
+ std::unique_ptr<protocol::DictionaryValue> headers_dict(
+ protocol::DictionaryValue::create());
+ if (sub_request_->request()->response_headers()) {
+ size_t iter = 0;
+ std::string name;
+ std::string value;
+ while (sub_request_->request()->response_headers()->EnumerateHeaderLines(
+ &iter, &name, &value)) {
+ headers_dict->setString(name, value);
+ }
+ }
+ request_info->http_response_status_code =
+ sub_request_->request()->GetResponseCode();
+ request_info->response_headers =
+ protocol::Object::fromValue(headers_dict.get(), nullptr);
+ }
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::BindOnce(callback_, std::move(request_info)));
+}
+
+// If result is < 0 it means error.
+void DevToolsURLInterceptorRequestJob::OnInterceptedRequestResponseReady(
+ const net::IOBuffer& buf,
+ int result) {
+ DCHECK(sub_request_);
+ if (result < 0) {
+ sub_request_->Cancel();
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(
+ &SendPendingBodyRequestsWithErrorOnUiThread,
+ std::move(pending_body_requests_),
+ protocol::Response::Error(base::StringPrintf(
+ "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)));
+ }
+ if (request_->status().status() == net::URLRequestStatus::CANCELED ||
+ waiting_for_user_response_ != WaitingForUserResponse::NOT_WAITING) {
+ return;
+ }
+ if (result < 0) {
+ NotifyStartError(net::URLRequestStatus::FromError(result));
+ } else {
+ // This call may consume the buffer.
+ NotifyHeadersComplete();
+ }
}
void DevToolsURLInterceptorRequestJob::StopIntercepting() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- intercepting_requests_ = false;
+ stage_to_intercept_ = InterceptionStage::DONT_INTERCEPT;
+ callback_.Reset();
// Allow the request to continue if we're waiting for user input.
switch (waiting_for_user_response_) {
case WaitingForUserResponse::NOT_WAITING:
return;
- case WaitingForUserResponse::WAITING_FOR_INTERCEPTION_RESPONSE:
+ case WaitingForUserResponse::WAITING_FOR_RESPONSE_ACK:
+ // Fallthough.
+ case WaitingForUserResponse::WAITING_FOR_REQUEST_ACK:
ProcessInterceptionRespose(
- base::MakeUnique<DevToolsURLRequestInterceptor::Modifications>(
+ std::make_unique<DevToolsURLRequestInterceptor::Modifications>(
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));
return;
-
- case WaitingForUserResponse::WAITING_FOR_AUTH_RESPONSE: {
+ case WaitingForUserResponse::WAITING_FOR_AUTH_ACK: {
std::unique_ptr<protocol::Network::AuthChallengeResponse> auth_response =
protocol::Network::AuthChallengeResponse::Create()
.SetResponse(protocol::Network::AuthChallengeResponse::
ResponseEnum::Default)
.Build();
ProcessAuthRespose(
- base::MakeUnique<DevToolsURLRequestInterceptor::Modifications>(
+ std::make_unique<DevToolsURLRequestInterceptor::Modifications>(
base::nullopt, base::nullopt, protocol::Maybe<std::string>(),
protocol::Maybe<std::string>(), protocol::Maybe<std::string>(),
protocol::Maybe<protocol::Network::Headers>(),
@@ -541,7 +916,9 @@ void DevToolsURLInterceptorRequestJob::ContinueInterceptedRequest(
"Response already processed.")));
break;
- case WaitingForUserResponse::WAITING_FOR_INTERCEPTION_RESPONSE:
+ case WaitingForUserResponse::WAITING_FOR_RESPONSE_ACK:
+ // Fallthough.
+ case WaitingForUserResponse::WAITING_FOR_REQUEST_ACK:
if (modifications->auth_challenge_response.isJust()) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
@@ -558,7 +935,7 @@ void DevToolsURLInterceptorRequestJob::ContinueInterceptedRequest(
base::Passed(std::move(callback))));
break;
- case WaitingForUserResponse::WAITING_FOR_AUTH_RESPONSE:
+ case WaitingForUserResponse::WAITING_FOR_AUTH_ACK:
if (!modifications->auth_challenge_response.isJust()) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
@@ -589,9 +966,52 @@ void DevToolsURLInterceptorRequestJob::ContinueInterceptedRequest(
}
}
+void DevToolsURLInterceptorRequestJob::GetResponseBody(
+ std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ std::string error_reason;
+ if (stage_to_intercept_ == InterceptionStage::REQUEST) {
+ error_reason =
+ "Can only get response body on HeadersReceived pattern matched "
+ "requests.";
+ } else if (waiting_for_user_response_ !=
+ WaitingForUserResponse::WAITING_FOR_RESPONSE_ACK) {
+ error_reason =
+ "Can only get response body on requests captured after headers "
+ "received.";
+ }
+ if (error_reason.size()) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(
+ &GetResponseBodyForInterceptionCallback::sendFailure,
+ std::move(callback),
+ protocol::Response::InvalidParams(std::move(error_reason))));
+ return;
+ }
+ DCHECK(sub_request_);
+ pending_body_requests_.push_back(std::move(callback));
+ static_cast<InterceptedRequest*>(sub_request_.get())->FetchResponseBody();
+}
+
+std::unique_ptr<InterceptedRequestInfo>
+DevToolsURLInterceptorRequestJob::BuildRequestInfo() {
+ auto result = std::make_unique<InterceptedRequestInfo>();
+ result->interception_id = interception_id_;
+ result->network_request =
+ protocol::NetworkHandler::CreateRequestFromURLRequest(request());
+ result->frame_id = devtools_token_;
+ result->resource_type = resource_type_;
+ result->is_navigation =
+ DevToolsURLRequestInterceptor::IsNavigationRequest(resource_type_);
+ return result;
+}
+
void DevToolsURLInterceptorRequestJob::ProcessInterceptionRespose(
std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
modifications) {
+ bool is_response_ack = waiting_for_user_response_ ==
+ WaitingForUserResponse::WAITING_FOR_RESPONSE_ACK;
waiting_for_user_response_ = WaitingForUserResponse::NOT_WAITING;
if (modifications->mark_as_canceled) {
@@ -602,6 +1022,10 @@ void DevToolsURLInterceptorRequestJob::ProcessInterceptionRespose(
}
if (modifications->error_reason) {
+ if (sub_request_) {
+ sub_request_->Cancel();
+ sub_request_.reset();
+ }
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
*modifications->error_reason));
return;
@@ -613,14 +1037,19 @@ void DevToolsURLInterceptorRequestJob::ProcessInterceptionRespose(
std::string value;
if (mock_response_details_->response_headers()->IsRedirect(&value)) {
- devtools_url_request_interceptor_state_->ExpectRequestAfterRedirect(
- request(), interception_id_);
+ interceptor_->ExpectRequestAfterRedirect(request(), interception_id_);
+ }
+
+ if (sub_request_) {
+ sub_request_->Cancel();
+ sub_request_.reset();
}
NotifyHeadersComplete();
return;
}
if (redirect_) {
+ DCHECK(!is_response_ack);
// NOTE we don't append the text form of the status code because
// net::HttpResponseHeaders doesn't need that.
std::string raw_headers =
@@ -635,9 +1064,14 @@ void DevToolsURLInterceptorRequestJob::ProcessInterceptionRespose(
base::TimeTicks::Now()));
redirect_.reset();
- devtools_url_request_interceptor_state_->ExpectRequestAfterRedirect(
- request(), interception_id_);
+ interceptor_->ExpectRequestAfterRedirect(request(), interception_id_);
NotifyHeadersComplete();
+ } else if (is_response_ack) {
+ DCHECK(sub_request_);
+ // If we are continuing the request without change we fetch the body.
+ // If the body is already ready we will get a
+ // OnInterceptedRequestResponseReady event which will begin the read.
+ static_cast<InterceptedRequest*>(sub_request_.get())->FetchResponseBody();
} else {
// Note this redirect is not visible to the caller by design. If they want a
// visible redirect they can mock a response with a 302.
@@ -653,7 +1087,7 @@ void DevToolsURLInterceptorRequestJob::ProcessInterceptionRespose(
std::vector<char> data(post_data.begin(), post_data.end());
request_details_.post_data =
net::ElementsUploadDataStream::CreateWithReader(
- base::MakeUnique<net::UploadOwnedBytesElementReader>(&data), 0);
+ std::make_unique<net::UploadOwnedBytesElementReader>(&data), 0);
}
if (modifications->modified_headers.isJust()) {
@@ -672,8 +1106,7 @@ void DevToolsURLInterceptorRequestJob::ProcessInterceptionRespose(
// The reason we start a sub request is because we are in full control of it
// and can choose to ignore it if, for example, the fetch encounters a
// redirect that the user chooses to replace with a mock response.
- sub_request_.reset(new SubRequest(request_details_, this,
- devtools_url_request_interceptor_state_));
+ sub_request_.reset(new SubRequest(request_details_, this, interceptor_));
}
}
@@ -730,146 +1163,4 @@ DevToolsURLInterceptorRequestJob::RequestDetails::RequestDetails(
DevToolsURLInterceptorRequestJob::RequestDetails::~RequestDetails() {}
-DevToolsURLInterceptorRequestJob::SubRequest::SubRequest(
- DevToolsURLInterceptorRequestJob::RequestDetails& request_details,
- DevToolsURLInterceptorRequestJob* devtools_interceptor_request_job,
- scoped_refptr<DevToolsURLRequestInterceptor::State>
- devtools_url_request_interceptor_state)
- : devtools_interceptor_request_job_(devtools_interceptor_request_job),
- devtools_url_request_interceptor_state_(
- devtools_url_request_interceptor_state),
- fetch_in_progress_(true) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- net::NetworkTrafficAnnotationTag traffic_annotation =
- net::DefineNetworkTrafficAnnotation("devtools_interceptor", R"(
- semantics {
- sender: "Developer Tools"
- description:
- "When user is debugging a page, all actions resulting in a network "
- "request are intercepted to enrich the debugging experience."
- trigger:
- "User triggers an action that requires network request (like "
- "navigation, download, etc.) while debugging the page."
- data:
- "Any data that user action sends."
- destination: WEBSITE
- }
- policy {
- cookies_allowed: YES
- cookies_store: "user"
- setting:
- "This feature cannot be disabled in settings, however it happens "
- "only when user is debugging a page."
- chrome_policy {
- DeveloperToolsDisabled {
- DeveloperToolsDisabled: true
- }
- }
- })");
- request_ = request_details.url_request_context->CreateRequest(
- request_details.url, request_details.priority,
- devtools_interceptor_request_job_, traffic_annotation);
- request_->set_method(request_details.method);
- request_->SetExtraRequestHeaders(request_details.extra_request_headers);
-
- // Mimic the ResourceRequestInfoImpl of the original request.
- const ResourceRequestInfoImpl* resource_request_info =
- static_cast<const ResourceRequestInfoImpl*>(
- ResourceRequestInfo::ForRequest(
- devtools_interceptor_request_job->request()));
- ResourceRequestInfoImpl* extra_data = new ResourceRequestInfoImpl(
- resource_request_info->requester_info(),
- resource_request_info->GetRouteID(),
- resource_request_info->GetFrameTreeNodeId(),
- resource_request_info->GetOriginPID(),
- resource_request_info->GetRequestID(),
- resource_request_info->GetRenderFrameID(),
- resource_request_info->IsMainFrame(),
- resource_request_info->GetResourceType(),
- resource_request_info->GetPageTransition(),
- resource_request_info->should_replace_current_entry(),
- resource_request_info->IsDownload(), resource_request_info->is_stream(),
- resource_request_info->allow_download(),
- resource_request_info->HasUserGesture(),
- resource_request_info->is_load_timing_enabled(),
- resource_request_info->is_upload_progress_enabled(),
- resource_request_info->do_not_prompt_for_login(),
- resource_request_info->keepalive(),
- resource_request_info->GetReferrerPolicy(),
- resource_request_info->GetVisibilityState(),
- resource_request_info->GetContext(),
- resource_request_info->ShouldReportRawHeaders(),
- resource_request_info->IsAsync(),
- resource_request_info->GetPreviewsState(), resource_request_info->body(),
- resource_request_info->initiated_in_secure_context());
- extra_data->AssociateWithRequest(request_.get());
-
- if (request_details.post_data)
- request_->set_upload(std::move(request_details.post_data));
-
- devtools_url_request_interceptor_state_->RegisterSubRequest(request_.get());
- request_->Start();
-}
-
-DevToolsURLInterceptorRequestJob::SubRequest::~SubRequest() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- devtools_url_request_interceptor_state_->UnregisterSubRequest(request_.get());
-}
-
-void DevToolsURLInterceptorRequestJob::SubRequest::Cancel() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!fetch_in_progress_)
- return;
-
- fetch_in_progress_ = false;
- request_->Cancel();
-}
-
-DevToolsURLInterceptorRequestJob::MockResponseDetails::MockResponseDetails(
- std::string response_bytes,
- base::TimeTicks response_time)
- : response_bytes_(std::move(response_bytes)),
- read_offset_(0),
- response_time_(response_time) {
- int header_size = net::HttpUtil::LocateEndOfHeaders(response_bytes_.c_str(),
- response_bytes_.size());
- if (header_size == -1) {
- LOG(WARNING) << "Can't find headers in result";
- response_headers_ = new net::HttpResponseHeaders("");
- } else {
- response_headers_ =
- new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
- response_bytes_.c_str(), header_size));
- read_offset_ = header_size;
- }
-
- CHECK_LE(read_offset_, response_bytes_.size());
-}
-
-DevToolsURLInterceptorRequestJob::MockResponseDetails::MockResponseDetails(
- const scoped_refptr<net::HttpResponseHeaders>& response_headers,
- std::string response_bytes,
- size_t read_offset,
- base::TimeTicks response_time)
- : response_headers_(response_headers),
- response_bytes_(std::move(response_bytes)),
- read_offset_(read_offset),
- response_time_(response_time) {}
-
-DevToolsURLInterceptorRequestJob::MockResponseDetails::~MockResponseDetails() {}
-
-int DevToolsURLInterceptorRequestJob::MockResponseDetails::ReadRawData(
- net::IOBuffer* buf,
- int buf_size) {
- size_t bytes_available = response_bytes_.size() - read_offset_;
- size_t bytes_to_copy =
- std::min(static_cast<size_t>(buf_size), bytes_available);
- if (bytes_to_copy > 0) {
- std::memcpy(buf->data(), &response_bytes_.data()[read_offset_],
- bytes_to_copy);
- read_offset_ += bytes_to_copy;
- }
- return bytes_to_copy;
-}
-
} // namespace content
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 33d1a442737..e438fb74032 100644
--- a/chromium/content/browser/devtools/devtools_url_interceptor_request_job.h
+++ b/chromium/content/browser/devtools/devtools_url_interceptor_request_job.h
@@ -7,10 +7,10 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/unguessable_token.h"
#include "content/browser/devtools/devtools_url_request_interceptor.h"
#include "content/browser/devtools/protocol/network.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/global_request_id.h"
#include "content/public/common/resource_type.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
@@ -24,19 +24,19 @@ namespace content {
// A URLRequestJob that allows programmatic request blocking / modification or
// response mocking. This class should only be accessed on the IO thread.
-class DevToolsURLInterceptorRequestJob : public net::URLRequestJob,
- public net::URLRequest::Delegate {
+class DevToolsURLInterceptorRequestJob : public net::URLRequestJob {
public:
DevToolsURLInterceptorRequestJob(
- scoped_refptr<DevToolsURLRequestInterceptor::State>
- devtools_url_request_interceptor_state,
+ DevToolsURLRequestInterceptor* interceptor,
const std::string& interception_id,
+ intptr_t owning_entry_id,
net::URLRequest* original_request,
net::NetworkDelegate* original_network_delegate,
- WebContents* web_contents,
- base::WeakPtr<protocol::NetworkHandler> network_handler,
+ const base::UnguessableToken& devtools_token,
+ DevToolsURLRequestInterceptor::RequestInterceptedCallback callback,
bool is_redirect,
- ResourceType resource_type);
+ ResourceType resource_type,
+ DevToolsURLRequestInterceptor::InterceptionStage stage_to_intercept);
~DevToolsURLInterceptorRequestJob() override;
@@ -57,37 +57,31 @@ class DevToolsURLInterceptorRequestJob : public net::URLRequestJob,
void SetAuth(const net::AuthCredentials& credentials) override;
void CancelAuth() override;
- // net::URLRequest::Delegate methods:
- void OnAuthRequired(net::URLRequest* request,
- net::AuthChallengeInfo* auth_info) override;
- void OnCertificateRequested(
- net::URLRequest* request,
- net::SSLCertRequestInfo* cert_request_info) override;
- void OnSSLCertificateError(net::URLRequest* request,
- const net::SSLInfo& ssl_info,
- bool fatal) override;
- void OnResponseStarted(net::URLRequest* request, int net_error) override;
- void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
- void OnReceivedRedirect(net::URLRequest* request,
- const net::RedirectInfo& redirect_info,
- bool* defer_redirect) override;
-
// Must be called on IO thread.
void StopIntercepting();
using ContinueInterceptedRequestCallback =
protocol::Network::Backend::ContinueInterceptedRequestCallback;
+ using GetResponseBodyForInterceptionCallback =
+ protocol::Network::Backend::GetResponseBodyForInterceptionCallback;
+ using InterceptionStage = DevToolsURLRequestInterceptor::InterceptionStage;
// Must be called only once per interception. Must be called on IO thread.
void ContinueInterceptedRequest(
std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
modifications,
std::unique_ptr<ContinueInterceptedRequestCallback> callback);
+ void GetResponseBody(
+ std::unique_ptr<GetResponseBodyForInterceptionCallback> callback);
- WebContents* web_contents() const { return web_contents_; }
+ intptr_t owning_entry_id() const { return owning_entry_id_; }
private:
+ std::unique_ptr<InterceptedRequestInfo> BuildRequestInfo();
+
class SubRequest;
+ class InterceptedRequest;
+ class MockResponseDetails;
// We keep a copy of the original request details to facilitate the
// Network.modifyRequest command which could potentially change any of these
@@ -109,62 +103,17 @@ class DevToolsURLInterceptorRequestJob : public net::URLRequestJob,
const net::URLRequestContext* url_request_context;
};
- // If the request was either allowed or modified, a SubRequest will be used to
- // perform the fetch and the results proxied to the original request. This
- // gives us the flexibility to pretend redirects didn't happen if the user
- // chooses to mock the response. Note this SubRequest is ignored by the
- // interceptor.
- class SubRequest {
- public:
- SubRequest(
- DevToolsURLInterceptorRequestJob::RequestDetails& request_details,
- DevToolsURLInterceptorRequestJob* devtools_interceptor_request_job,
- scoped_refptr<DevToolsURLRequestInterceptor::State>
- devtools_url_request_interceptor_state);
- ~SubRequest();
-
- void Cancel();
-
- net::URLRequest* request() const { return request_.get(); }
-
- private:
- std::unique_ptr<net::URLRequest> request_;
-
- DevToolsURLInterceptorRequestJob*
- devtools_interceptor_request_job_; // NOT OWNED.
-
- scoped_refptr<DevToolsURLRequestInterceptor::State>
- devtools_url_request_interceptor_state_;
- bool fetch_in_progress_;
- };
-
- class MockResponseDetails {
- public:
- MockResponseDetails(std::string response_bytes,
- base::TimeTicks response_time);
-
- MockResponseDetails(
- const scoped_refptr<net::HttpResponseHeaders>& response_headers,
- std::string response_bytes,
- size_t read_offset,
- base::TimeTicks response_time);
-
- ~MockResponseDetails();
+ // Callbacks from SubRequest.
+ void OnSubRequestAuthRequired(net::AuthChallengeInfo* auth_info);
+ void OnSubRequestRedirectReceived(const net::URLRequest& request,
+ const net::RedirectInfo& redirectinfo,
+ bool* defer_redirect);
+ void OnSubRequestResponseStarted(const net::Error& net_error);
+ void OnSubRequestHeadersReceived(const net::Error& net_error);
- scoped_refptr<net::HttpResponseHeaders>& response_headers() {
- return response_headers_;
- }
-
- base::TimeTicks response_time() const { return response_time_; }
-
- int ReadRawData(net::IOBuffer* buf, int buf_size);
-
- private:
- scoped_refptr<net::HttpResponseHeaders> response_headers_;
- std::string response_bytes_;
- size_t read_offset_;
- base::TimeTicks response_time_;
- };
+ // Callbacks from InterceptedRequest.
+ void OnInterceptedRequestResponseStarted(const net::Error& net_error);
+ void OnInterceptedRequestResponseReady(const net::IOBuffer& buf, int result);
// Retrieves the response headers from either the |sub_request_| or the
// |mock_response_|. In some cases (e.g. file access) this may be null.
@@ -180,27 +129,29 @@ class DevToolsURLInterceptorRequestJob : public net::URLRequestJob,
enum class WaitingForUserResponse {
NOT_WAITING,
- WAITING_FOR_INTERCEPTION_RESPONSE,
- WAITING_FOR_AUTH_RESPONSE,
+ WAITING_FOR_REQUEST_ACK,
+ WAITING_FOR_RESPONSE_ACK,
+ WAITING_FOR_AUTH_ACK,
};
- scoped_refptr<DevToolsURLRequestInterceptor::State>
- devtools_url_request_interceptor_state_;
+ DevToolsURLRequestInterceptor* const interceptor_;
RequestDetails request_details_;
std::unique_ptr<SubRequest> sub_request_;
std::unique_ptr<MockResponseDetails> mock_response_details_;
std::unique_ptr<net::RedirectInfo> redirect_;
WaitingForUserResponse waiting_for_user_response_;
- bool intercepting_requests_;
- bool killed_;
scoped_refptr<net::AuthChallengeInfo> auth_info_;
const std::string interception_id_;
- WebContents* const web_contents_;
- const base::WeakPtr<protocol::NetworkHandler> network_handler_;
+ const intptr_t owning_entry_id_;
+ const base::UnguessableToken devtools_token_;
+ DevToolsURLRequestInterceptor::RequestInterceptedCallback callback_;
const bool is_redirect_;
const ResourceType resource_type_;
- GlobalRequestID global_request_id_;
+ DevToolsURLRequestInterceptor::InterceptionStage stage_to_intercept_;
+ std::vector<std::unique_ptr<GetResponseBodyForInterceptionCallback>>
+ pending_body_requests_;
+
base::WeakPtrFactory<DevToolsURLInterceptorRequestJob> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DevToolsURLInterceptorRequestJob);
diff --git a/chromium/content/browser/devtools/devtools_url_request_interceptor.cc b/chromium/content/browser/devtools/devtools_url_request_interceptor.cc
index 6b2c5fa771f..a755fcf30ac 100644
--- a/chromium/content/browser/devtools/devtools_url_request_interceptor.cc
+++ b/chromium/content/browser/devtools/devtools_url_request_interceptor.cc
@@ -7,53 +7,50 @@
#include "base/memory/ptr_util.h"
#include "base/strings/pattern.h"
#include "base/strings/stringprintf.h"
-#include "base/supports_user_data.h"
-#include "content/browser/devtools/devtools_agent_host_impl.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_context.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/devtools_agent_host.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/render_process_host.h"
#include "content/public/browser/resource_request_info.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_observer.h"
-#include "net/http/http_request_headers.h"
#include "net/url_request/url_request.h"
namespace content {
-namespace {
-const char kDevToolsURLRequestInterceptorKeyName[] =
- "DevToolsURLRequestInterceptor";
+InterceptedRequestInfo::InterceptedRequestInfo()
+ : response_error_code(net::OK) {}
-class DevToolsURLRequestInterceptorUserData
- : public base::SupportsUserData::Data {
- public:
- explicit DevToolsURLRequestInterceptorUserData(
- DevToolsURLRequestInterceptor* devtools_url_request_interceptor)
- : devtools_url_request_interceptor_(devtools_url_request_interceptor) {}
+InterceptedRequestInfo::~InterceptedRequestInfo() = default;
- DevToolsURLRequestInterceptor* devtools_url_request_interceptor() const {
- return devtools_url_request_interceptor_;
- }
-
- private:
- DevToolsURLRequestInterceptor* devtools_url_request_interceptor_;
+DevToolsURLRequestInterceptor::FilterEntry::FilterEntry(
+ const base::UnguessableToken& target_id,
+ std::vector<Pattern> patterns,
+ RequestInterceptedCallback callback)
+ : target_id(target_id),
+ patterns(std::move(patterns)),
+ callback(std::move(callback)) {}
- DISALLOW_COPY_AND_ASSIGN(DevToolsURLRequestInterceptorUserData);
-};
+DevToolsURLRequestInterceptor::FilterEntry::FilterEntry(FilterEntry&&) {}
+DevToolsURLRequestInterceptor::FilterEntry::~FilterEntry() {}
-} // namespace
+// static
+bool DevToolsURLRequestInterceptor::IsNavigationRequest(
+ ResourceType resource_type) {
+ return resource_type == RESOURCE_TYPE_MAIN_FRAME ||
+ resource_type == RESOURCE_TYPE_SUB_FRAME;
+}
DevToolsURLRequestInterceptor::DevToolsURLRequestInterceptor(
BrowserContext* browser_context)
- : browser_context_(browser_context), state_(new State()) {
+ : next_id_(0), weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- browser_context_->SetUserData(
- kDevToolsURLRequestInterceptorKeyName,
- base::MakeUnique<DevToolsURLRequestInterceptorUserData>(this));
+ auto target_registry = std::make_unique<DevToolsTargetRegistry>(
+ content::BrowserThread::GetTaskRunnerForThread(
+ content::BrowserThread::IO));
+ target_resolver_ = target_registry->CreateResolver();
+ // Controller lifetime is managed by the browser context.
+ auto* controller = new DevToolsInterceptorController(
+ weak_factory_.GetWeakPtr(), std::move(target_registry), browser_context);
+ controller_ = controller->weak_factory_.GetWeakPtr();
}
DevToolsURLRequestInterceptor::~DevToolsURLRequestInterceptor() {
@@ -61,12 +58,55 @@ DevToolsURLRequestInterceptor::~DevToolsURLRequestInterceptor() {
// DevToolsURLRequestInterceptorUserData explicitly.
}
+DevToolsURLRequestInterceptor::Pattern::Pattern() = default;
+
+DevToolsURLRequestInterceptor::Pattern::~Pattern() = default;
+
+DevToolsURLRequestInterceptor::Pattern::Pattern(const Pattern& other) = default;
+
+DevToolsURLRequestInterceptor::Pattern::Pattern(
+ const std::string& url_pattern,
+ base::flat_set<ResourceType> resource_types,
+ InterceptionStage interception_stage)
+ : url_pattern(url_pattern),
+ resource_types(std::move(resource_types)),
+ interception_stage(interception_stage) {}
+
+const DevToolsTargetRegistry::TargetInfo*
+DevToolsURLRequestInterceptor::TargetInfoForRequestInfo(
+ const ResourceRequestInfo* request_info) const {
+ int frame_node_id = request_info->GetFrameTreeNodeId();
+ if (frame_node_id != -1)
+ return target_resolver_->GetInfoByFrameTreeNodeId(frame_node_id);
+ return target_resolver_->GetInfoByRenderFramePair(
+ request_info->GetChildID(), request_info->GetRenderFrameID());
+}
+
+void DevToolsURLRequestInterceptor::ContinueInterceptedRequest(
+ std::string interception_id,
+ std::unique_ptr<Modifications> modifications,
+ std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DevToolsURLInterceptorRequestJob* job = GetJob(interception_id);
+ if (!job) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(
+ &ContinueInterceptedRequestCallback::sendFailure,
+ base::Passed(std::move(callback)),
+ protocol::Response::InvalidParams("Invalid InterceptionId.")));
+ return;
+ }
+
+ job->ContinueInterceptedRequest(std::move(modifications),
+ std::move(callback));
+}
+
net::URLRequestJob* DevToolsURLRequestInterceptor::MaybeInterceptRequest(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return state()->MaybeCreateDevToolsURLInterceptorRequestJob(request,
- network_delegate);
+ return const_cast<DevToolsURLRequestInterceptor*>(this)
+ ->InnerMaybeInterceptRequest(request, network_delegate);
}
net::URLRequestJob* DevToolsURLRequestInterceptor::MaybeInterceptRedirect(
@@ -82,316 +122,182 @@ net::URLRequestJob* DevToolsURLRequestInterceptor::MaybeInterceptResponse(
return nullptr;
}
-DevToolsURLRequestInterceptor::State::State() : next_id_(0) {}
-
-DevToolsURLRequestInterceptor::State::~State() {}
-
-DevToolsURLRequestInterceptor::State::RenderFrameHostInfo::RenderFrameHostInfo(
- RenderFrameHost* host)
- : routing_id(host->GetRoutingID()),
- frame_tree_node_id(host->GetFrameTreeNodeId()),
- process_id(host->GetProcess()->GetID()) {}
-
-void DevToolsURLRequestInterceptor::State::ContinueInterceptedRequest(
- std::string interception_id,
- std::unique_ptr<Modifications> modifications,
- std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &DevToolsURLRequestInterceptor::State::ContinueInterceptedRequestOnIO,
- this, interception_id, base::Passed(std::move(modifications)),
- base::Passed(std::move(callback))));
-}
-
-void DevToolsURLRequestInterceptor::State::ContinueInterceptedRequestOnIO(
+void DevToolsURLRequestInterceptor::GetResponseBody(
std::string interception_id,
- std::unique_ptr<Modifications> modifications,
- std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
+ std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DevToolsURLInterceptorRequestJob* job = GetJob(interception_id);
if (!job) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(
- &ContinueInterceptedRequestCallback::sendFailure,
- base::Passed(std::move(callback)),
+ &GetResponseBodyForInterceptionCallback::sendFailure,
+ std::move(callback),
protocol::Response::InvalidParams("Invalid InterceptionId.")));
return;
}
- job->ContinueInterceptedRequest(std::move(modifications),
- std::move(callback));
+ job->GetResponseBody(std::move(callback));
}
-DevToolsURLInterceptorRequestJob* DevToolsURLRequestInterceptor::State::
- MaybeCreateDevToolsURLInterceptorRequestJob(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate) {
+net::URLRequestJob* DevToolsURLRequestInterceptor::InnerMaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Bail out if we're not intercepting anything.
- if (intercepted_render_frames_.empty()) {
- DCHECK(intercepted_frame_tree_nodes_.empty());
+ if (target_id_to_entries_.empty())
return nullptr;
- }
-
// Don't try to intercept blob resources.
if (request->url().SchemeIsBlob())
return nullptr;
-
const ResourceRequestInfo* resource_request_info =
ResourceRequestInfo::ForRequest(request);
if (!resource_request_info)
return nullptr;
- int child_id = resource_request_info->GetChildID();
- int frame_tree_node_id = resource_request_info->GetFrameTreeNodeId();
- WebContents* web_contents = nullptr;
- if (frame_tree_node_id == -1) {
- // |frame_tree_node_id| is not set for renderer side requests, fall back to
- // the RenderFrameID.
- int render_frame_id = resource_request_info->GetRenderFrameID();
- const auto find_it = intercepted_render_frames_.find(
- std::make_pair(render_frame_id, child_id));
- if (find_it == intercepted_render_frames_.end())
- return nullptr;
- web_contents = find_it->second;
- } else {
- // |frame_tree_node_id| is set for browser side navigations, so use that
- // because the RenderFrameID isn't known (neither is the ChildID).
- const auto find_it = intercepted_frame_tree_nodes_.find(frame_tree_node_id);
- if (find_it == intercepted_frame_tree_nodes_.end())
- return nullptr;
- web_contents = find_it->second;
- }
-
- DCHECK(intercepted_page_for_web_contents_.count(web_contents));
-
- const InterceptedPage& intercepted_page =
- *intercepted_page_for_web_contents_.find(web_contents)->second;
+ const DevToolsTargetRegistry::TargetInfo* target_info =
+ TargetInfoForRequestInfo(resource_request_info);
+ if (!target_info)
+ return nullptr;
// We don't want to intercept our own sub requests.
if (sub_requests_.find(request) != sub_requests_.end())
return nullptr;
- // If we are only intercepting certain resource types then bail out if the
- // request is for the wrong type.
- if (!intercepted_page.intercepted_resource_types.empty() &&
- intercepted_page.intercepted_resource_types.find(
- resource_request_info->GetResourceType()) ==
- intercepted_page.intercepted_resource_types.end()) {
- return nullptr;
- }
-
- bool matchFound = false;
- const std::string url =
- protocol::NetworkHandler::ClearUrlRef(request->url()).spec();
- for (const std::string& pattern : intercepted_page.intercepted_url_patterns) {
- if (base::MatchPattern(url, pattern)) {
- matchFound = true;
- break;
- }
- }
- if (!matchFound)
+ ResourceType resource_type = resource_request_info->GetResourceType();
+ InterceptionStage interception_stage;
+ FilterEntry* entry =
+ FilterEntryForRequest(target_info->devtools_target_id, request->url(),
+ resource_type, &interception_stage);
+ if (!entry)
return nullptr;
+ DCHECK(interception_stage != DONT_INTERCEPT);
bool is_redirect;
- std::string interception_id = GetIdForRequestOnIO(request, &is_redirect);
- DevToolsURLInterceptorRequestJob* job = new DevToolsURLInterceptorRequestJob(
- this, interception_id, request, network_delegate, web_contents,
- intercepted_page.network_handler, is_redirect,
- resource_request_info->GetResourceType());
- interception_id_to_job_map_[interception_id] = job;
- return job;
-}
-
-class DevToolsURLRequestInterceptor::State::InterceptedWebContentsObserver
- : public WebContentsObserver {
- public:
- InterceptedWebContentsObserver(
- WebContents* web_contents,
- scoped_refptr<DevToolsURLRequestInterceptor::State> state,
- base::WeakPtr<protocol::NetworkHandler> network_handler)
- : WebContentsObserver(web_contents), state_(state) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- }
-
- void RenderFrameHostChanged(RenderFrameHost* old_host,
- RenderFrameHost* new_host) override {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- base::Optional<DevToolsURLRequestInterceptor::State::RenderFrameHostInfo>
- old_host_info;
- DevToolsURLRequestInterceptor::State::RenderFrameHostInfo new_host_info(
- new_host);
- if (old_host) {
- old_host_info.emplace(
- DevToolsURLRequestInterceptor::State::RenderFrameHostInfo(old_host));
- }
+ std::string interception_id = GetIdForRequest(request, &is_redirect);
+ if (IsNavigationRequest(resource_type)) {
BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &DevToolsURLRequestInterceptor::State::RenderFrameHostChangedOnIO,
- state_, old_host_info, new_host_info, web_contents()));
- }
-
- void FrameDeleted(RenderFrameHost* render_frame_host) override {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &DevToolsURLRequestInterceptor::State::
- StopInterceptingRequestsForHostInfoOnIO,
- state_,
- DevToolsURLRequestInterceptor::State::RenderFrameHostInfo(
- render_frame_host)));
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&DevToolsInterceptorController::NavigationStarted,
+ controller_, interception_id,
+ resource_request_info->GetGlobalRequestID()));
}
- private:
- scoped_refptr<DevToolsURLRequestInterceptor::State> state_;
-};
-
-void DevToolsURLRequestInterceptor::State::RenderFrameHostChangedOnIO(
- base::Optional<RenderFrameHostInfo> old_host_info,
- RenderFrameHostInfo new_host_info,
- WebContents* web_contents) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (old_host_info)
- StopInterceptingRequestsForHostInfoOnIO(old_host_info.value());
- StartInterceptingRequestsForHostInfoOnIOInternal(new_host_info, web_contents);
-}
-
-void DevToolsURLRequestInterceptor::State::
- StartInterceptingRequestsForHostInfoOnIOInternal(
- RenderFrameHostInfo host_info,
- WebContents* web_contents) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(intercepted_page_for_web_contents_.count(web_contents));
-
- // We can assume that if there are frames already in the map they are in the
- // same web_contents as before.
- intercepted_render_frames_[std::make_pair(
- host_info.routing_id, host_info.process_id)] = web_contents;
- intercepted_frame_tree_nodes_[host_info.frame_tree_node_id] = web_contents;
+ DevToolsURLInterceptorRequestJob* job = new DevToolsURLInterceptorRequestJob(
+ this, interception_id, reinterpret_cast<intptr_t>(entry), request,
+ network_delegate, target_info->devtools_token, entry->callback,
+ is_redirect, resource_request_info->GetResourceType(),
+ interception_stage);
+ interception_id_to_job_map_[interception_id] = job;
+ return job;
}
-void DevToolsURLRequestInterceptor::State::StartInterceptingRequestsOnIO(
- std::vector<RenderFrameHostInfo> host_info_list,
- WebContents* web_contents,
- std::unique_ptr<InterceptedPage> interceptedPage) {
+void DevToolsURLRequestInterceptor::AddFilterEntry(
+ std::unique_ptr<FilterEntry> entry) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- intercepted_page_for_web_contents_[web_contents] = std::move(interceptedPage);
- for (const auto host_info : host_info_list)
- StartInterceptingRequestsForHostInfoOnIOInternal(host_info, web_contents);
+ const base::UnguessableToken& target_id = entry->target_id;
+ auto it = target_id_to_entries_.find(target_id);
+ if (it == target_id_to_entries_.end()) {
+ it = target_id_to_entries_
+ .emplace(target_id, std::vector<std::unique_ptr<FilterEntry>>())
+ .first;
+ }
+ it->second.push_back(std::move(entry));
}
-void DevToolsURLRequestInterceptor::State::
- StopInterceptingRequestsForHostInfoOnIO(RenderFrameHostInfo host_info) {
+void DevToolsURLRequestInterceptor::RemoveFilterEntry(
+ const FilterEntry* entry) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // Since Devtools has not unregistered to the web_contents, we do not remove
- // it from the map.
- intercepted_render_frames_.erase(
- std::make_pair(host_info.routing_id, host_info.process_id));
- intercepted_frame_tree_nodes_.erase(host_info.frame_tree_node_id);
-}
-void DevToolsURLRequestInterceptor::State::StartInterceptingRequests(
- WebContents* web_contents,
- base::WeakPtr<protocol::NetworkHandler> network_handler,
- std::vector<std::string> intercepted_url_patterns,
- base::flat_set<ResourceType> intercepted_resource_types) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- std::vector<RenderFrameHostInfo> host_info_list;
- for (RenderFrameHost* render_frame_host : web_contents->GetAllFrames())
- host_info_list.push_back(RenderFrameHostInfo(render_frame_host));
+ // NOTE: Calling DevToolsURLInterceptorRequestJob::StopIntercepting can
+ // destruct the jobs which can remove entries in
+ // |interception_id_to_job_map_|, so we make a copy.
+ base::flat_map<std::string, DevToolsURLInterceptorRequestJob*> jobs(
+ interception_id_to_job_map_);
+ for (const auto pair : jobs) {
+ if (pair.second->owning_entry_id() == reinterpret_cast<intptr_t>(entry))
+ pair.second->StopIntercepting();
+ }
- std::unique_ptr<InterceptedPage> intercepted_page(
- new InterceptedPage(network_handler, std::move(intercepted_url_patterns),
- std::move(intercepted_resource_types)));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &DevToolsURLRequestInterceptor::State::StartInterceptingRequestsOnIO,
- this, std::move(host_info_list), web_contents,
- std::move(intercepted_page)));
-
- // Listen for future updates.
- observers_.emplace(web_contents,
- base::MakeUnique<InterceptedWebContentsObserver>(
- web_contents, this, network_handler));
+ auto it = target_id_to_entries_.find(entry->target_id);
+ if (it == target_id_to_entries_.end())
+ return;
+ base::EraseIf(it->second, [entry](const std::unique_ptr<FilterEntry>& e) {
+ return e.get() == entry;
+ });
+ if (it->second.empty())
+ target_id_to_entries_.erase(it);
}
-void DevToolsURLRequestInterceptor::State::StopInterceptingRequests(
- WebContents* web_contents) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- observers_.erase(web_contents);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &DevToolsURLRequestInterceptor::State::StopInterceptingRequestsOnIO,
- this, web_contents));
+void DevToolsURLRequestInterceptor::UpdatePatterns(
+ FilterEntry* entry,
+ std::vector<Pattern> patterns) {
+ entry->patterns = std::move(patterns);
}
-void DevToolsURLRequestInterceptor::State::StopInterceptingRequestsOnIO(
- WebContents* web_contents) {
+DevToolsURLRequestInterceptor::FilterEntry*
+DevToolsURLRequestInterceptor::FilterEntryForRequest(
+ const base::UnguessableToken target_id,
+ const GURL& url,
+ ResourceType resource_type,
+ InterceptionStage* stage) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // Remove any intercepted render frames associated with |web_contents|.
- base::flat_map<std::pair<int, int>, WebContents*>
- remaining_intercepted_render_frames;
- for (const auto& pair : intercepted_render_frames_) {
- DCHECK(intercepted_page_for_web_contents_.count(pair.second));
- if (pair.second == web_contents)
- continue;
- remaining_intercepted_render_frames.insert(pair);
- }
- std::swap(remaining_intercepted_render_frames, intercepted_render_frames_);
-
- // Remove any intercepted frame tree nodes associated with |web_contents|.
- base::flat_map<FrameTreeNodeId, WebContents*>
- remaining_intercepted_frame_tree_nodes;
- for (const auto& pair : intercepted_frame_tree_nodes_) {
- DCHECK(intercepted_page_for_web_contents_.count(pair.second));
- if (pair.second == web_contents)
- continue;
- remaining_intercepted_frame_tree_nodes.insert(pair);
- }
- std::swap(remaining_intercepted_frame_tree_nodes,
- intercepted_frame_tree_nodes_);
+ *stage = DONT_INTERCEPT;
- intercepted_page_for_web_contents_.erase(web_contents);
+ auto it = target_id_to_entries_.find(target_id);
+ if (it == target_id_to_entries_.end())
+ return nullptr;
- // Tell any jobs associated with |web_contents| to stop intercepting.
- for (const auto pair : interception_id_to_job_map_) {
- if (pair.second->web_contents() == web_contents)
- pair.second->StopIntercepting();
+ const std::vector<std::unique_ptr<FilterEntry>>& entries = it->second;
+ const std::string url_str = protocol::NetworkHandler::ClearUrlRef(url).spec();
+ for (const auto& entry : entries) {
+ for (const Pattern& pattern : entry->patterns) {
+ if (!pattern.resource_types.empty() &&
+ pattern.resource_types.find(resource_type) ==
+ pattern.resource_types.end()) {
+ continue;
+ }
+ if (base::MatchPattern(url_str, pattern.url_pattern)) {
+ if (pattern.interception_stage == REQUEST && *stage == RESPONSE) {
+ *stage = BOTH;
+ break;
+ } else if (pattern.interception_stage == RESPONSE &&
+ *stage == REQUEST) {
+ *stage = BOTH;
+ break;
+ }
+ *stage = pattern.interception_stage;
+ }
+ }
+ if (*stage != DONT_INTERCEPT)
+ return entry.get();
}
+ return nullptr;
}
-void DevToolsURLRequestInterceptor::State::RegisterSubRequest(
+void DevToolsURLRequestInterceptor::RegisterSubRequest(
const net::URLRequest* sub_request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(sub_requests_.find(sub_request) == sub_requests_.end());
sub_requests_.insert(sub_request);
}
-void DevToolsURLRequestInterceptor::State::UnregisterSubRequest(
+void DevToolsURLRequestInterceptor::UnregisterSubRequest(
const net::URLRequest* sub_request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(sub_requests_.find(sub_request) != sub_requests_.end());
sub_requests_.erase(sub_request);
}
-void DevToolsURLRequestInterceptor::State::ExpectRequestAfterRedirect(
+void DevToolsURLRequestInterceptor::ExpectRequestAfterRedirect(
const net::URLRequest* request,
std::string id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
expected_redirects_[request] = id;
}
-std::string DevToolsURLRequestInterceptor::State::GetIdForRequestOnIO(
+std::string DevToolsURLRequestInterceptor::GetIdForRequest(
const net::URLRequest* request,
bool* is_redirect) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -406,7 +312,7 @@ std::string DevToolsURLRequestInterceptor::State::GetIdForRequestOnIO(
return id;
}
-DevToolsURLInterceptorRequestJob* DevToolsURLRequestInterceptor::State::GetJob(
+DevToolsURLInterceptorRequestJob* DevToolsURLRequestInterceptor::GetJob(
const std::string& interception_id) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
const auto it = interception_id_to_job_map_.find(interception_id);
@@ -415,22 +321,17 @@ DevToolsURLInterceptorRequestJob* DevToolsURLRequestInterceptor::State::GetJob(
return it->second;
}
-void DevToolsURLRequestInterceptor::State::JobFinished(
- const std::string& interception_id) {
+void DevToolsURLRequestInterceptor::JobFinished(
+ const std::string& interception_id,
+ bool is_navigation) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
interception_id_to_job_map_.erase(interception_id);
-}
-
-// static
-DevToolsURLRequestInterceptor*
-DevToolsURLRequestInterceptor::FromBrowserContext(BrowserContext* context) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- auto* interceptor_user_data =
- static_cast<DevToolsURLRequestInterceptorUserData*>(
- context->GetUserData(kDevToolsURLRequestInterceptorKeyName));
- if (!interceptor_user_data)
- return nullptr;
- return interceptor_user_data->devtools_url_request_interceptor();
+ if (!is_navigation)
+ return;
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&DevToolsInterceptorController::NavigationFinished,
+ controller_, interception_id));
}
DevToolsURLRequestInterceptor::Modifications::Modifications(
@@ -454,15 +355,4 @@ DevToolsURLRequestInterceptor::Modifications::Modifications(
DevToolsURLRequestInterceptor::Modifications::~Modifications() {}
-DevToolsURLRequestInterceptor::State::InterceptedPage::InterceptedPage(
- base::WeakPtr<protocol::NetworkHandler> network_handler,
- std::vector<std::string> intercepted_url_patterns,
- base::flat_set<ResourceType> intercepted_resource_types)
- : network_handler(network_handler),
- intercepted_url_patterns(std::move(intercepted_url_patterns)),
- intercepted_resource_types(std::move(intercepted_resource_types)) {}
-
-DevToolsURLRequestInterceptor::State::InterceptedPage::~InterceptedPage() =
- default;
-
} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_url_request_interceptor.h b/chromium/content/browser/devtools/devtools_url_request_interceptor.h
index a465dffa49d..0d804661741 100644
--- a/chromium/content/browser/devtools/devtools_url_request_interceptor.h
+++ b/chromium/content/browser/devtools/devtools_url_request_interceptor.h
@@ -8,50 +8,59 @@
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
+#include "base/unguessable_token.h"
+#include "content/browser/devtools/devtools_target_registry.h"
#include "content/browser/devtools/protocol/network.h"
-#include "content/public/browser/browser_thread.h"
#include "content/public/common/resource_type.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request_interceptor.h"
namespace content {
-namespace protocol {
-class NetworkHandler;
-} // namespace
class BrowserContext;
+class DevToolsInterceptorController;
+class DevToolsTargetRegistry;
class DevToolsURLInterceptorRequestJob;
-class WebContents;
-class RenderFrameHost;
+class ResourceRequestInfo;
+
+struct InterceptedRequestInfo {
+ InterceptedRequestInfo();
+ ~InterceptedRequestInfo();
+
+ std::string interception_id;
+ std::unique_ptr<protocol::Network::Request> network_request;
+ base::UnguessableToken frame_id;
+ ResourceType resource_type;
+ bool is_navigation;
+ protocol::Maybe<protocol::Object> redirect_headers;
+ protocol::Maybe<int> redirect_status_code;
+ protocol::Maybe<protocol::String> redirect_url;
+ protocol::Maybe<protocol::Network::AuthChallenge> auth_challenge;
+ int response_error_code;
+ protocol::Maybe<int> http_response_status_code;
+ protocol::Maybe<protocol::Object> response_headers;
+};
// An interceptor that creates DevToolsURLInterceptorRequestJobs for requests
// from pages where interception has been enabled via
// Network.setRequestInterceptionEnabled.
+// This class is constructed on the UI thread but only accessed on IO thread.
class DevToolsURLRequestInterceptor : public net::URLRequestInterceptor {
public:
- explicit DevToolsURLRequestInterceptor(BrowserContext* browser_context);
- ~DevToolsURLRequestInterceptor() override;
+ using RequestInterceptedCallback =
+ base::Callback<void(std::unique_ptr<InterceptedRequestInfo>)>;
- // Must be called on UI thread.
- static DevToolsURLRequestInterceptor* FromBrowserContext(
- BrowserContext* context);
+ static bool IsNavigationRequest(ResourceType resource_type);
- // net::URLRequestInterceptor implementation:
- net::URLRequestJob* MaybeInterceptRequest(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate) const override;
-
- net::URLRequestJob* MaybeInterceptRedirect(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- const GURL& location) const override;
+ explicit DevToolsURLRequestInterceptor(BrowserContext* browser_context);
+ ~DevToolsURLRequestInterceptor() override;
- net::URLRequestJob* MaybeInterceptResponse(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate) const override;
+ using ContinueInterceptedRequestCallback =
+ protocol::Network::Backend::ContinueInterceptedRequestCallback;
+ using GetResponseBodyForInterceptionCallback =
+ protocol::Network::Backend::GetResponseBodyForInterceptionCallback;
struct Modifications {
Modifications(base::Optional<net::Error> error_reason,
@@ -85,146 +94,122 @@ class DevToolsURLRequestInterceptor : public net::URLRequestInterceptor {
bool mark_as_canceled;
};
- // The State needs to be accessed on both UI and IO threads.
- class State : public base::RefCountedThreadSafe<State> {
+ enum InterceptionStage {
+ REQUEST,
+ RESPONSE,
+ // Note: Both is not sent from front-end. It is used if both Request
+ // and HeadersReceived was found it upgrades it to Both.
+ BOTH,
+ DONT_INTERCEPT
+ };
+
+ struct Pattern {
public:
- State();
-
- using FrameTreeNodeId = int;
- using ContinueInterceptedRequestCallback =
- protocol::Network::Backend::ContinueInterceptedRequestCallback;
-
- // Must be called on the UI thread.
- void ContinueInterceptedRequest(
- std::string interception_id,
- std::unique_ptr<Modifications> modifications,
- std::unique_ptr<ContinueInterceptedRequestCallback> callback);
-
- // Returns a DevToolsURLInterceptorRequestJob if the request should be
- // intercepted, otherwise returns nullptr. Must be called on the IO thread.
- DevToolsURLInterceptorRequestJob*
- MaybeCreateDevToolsURLInterceptorRequestJob(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate);
-
- // Must be called on the UI thread.
- void StartInterceptingRequests(
- WebContents* web_contents,
- base::WeakPtr<protocol::NetworkHandler> network_handler,
- std::vector<std::string> patterns,
- base::flat_set<ResourceType> intercepted_resource_types);
-
- // Must be called on the UI thread.
- void StopInterceptingRequests(WebContents* web_contents);
-
- // Registers a |sub_request| that should not be intercepted.
- void RegisterSubRequest(const net::URLRequest* sub_request);
-
- // Unregisters a |sub_request|. Must be called on the IO thread.
- void UnregisterSubRequest(const net::URLRequest* sub_request);
-
- // To make the user's life easier we make sure requests in a redirect chain
- // all have the same id. Must be called on the IO thread.
- void ExpectRequestAfterRedirect(const net::URLRequest* request,
- std::string id);
-
- // Must be called on the IO thread.
- void JobFinished(const std::string& interception_id);
-
- private:
- class InterceptedWebContentsObserver;
-
- struct RenderFrameHostInfo {
- explicit RenderFrameHostInfo(RenderFrameHost* host);
- const int routing_id;
- const FrameTreeNodeId frame_tree_node_id;
- const int process_id;
- };
-
- struct InterceptedPage {
- InterceptedPage(base::WeakPtr<protocol::NetworkHandler> network_handler,
- std::vector<std::string> patterns,
- base::flat_set<ResourceType> intercepted_resource_types);
- ~InterceptedPage();
-
- const base::WeakPtr<protocol::NetworkHandler> network_handler;
- const std::vector<std::string> intercepted_url_patterns;
- // If not empty, only resource types from this set will be intercepted.
- const base::flat_set<ResourceType> intercepted_resource_types;
- };
-
- void ContinueInterceptedRequestOnIO(
- std::string interception_id,
- std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
- modifications,
- std::unique_ptr<ContinueInterceptedRequestCallback> callback);
-
- void RenderFrameHostChangedOnIO(
- base::Optional<RenderFrameHostInfo> old_host_info,
- RenderFrameHostInfo new_host_info,
- WebContents* web_contents);
-
- void StartInterceptingRequestsForHostInfoOnIOInternal(
- RenderFrameHostInfo host_info,
- WebContents* web_contents);
-
- void StartInterceptingRequestsOnIO(
- std::vector<RenderFrameHostInfo> host_info_list,
- WebContents* web_contents,
- std::unique_ptr<InterceptedPage> interceptedPage);
-
- void StopInterceptingRequestsForHostInfoOnIO(RenderFrameHostInfo host_info);
- void StopInterceptingRequestsOnIO(WebContents* web_contents);
-
- std::string GetIdForRequestOnIO(const net::URLRequest* request,
- bool* is_redirect);
-
- // Returns a WeakPtr to the DevToolsURLInterceptorRequestJob corresponding
- // to |interception_id|. Must be called on the IO thread.
- DevToolsURLInterceptorRequestJob* GetJob(
- const std::string& interception_id) const;
-
- // |intercepted_page_for_web_contents_| should always have an entry if
- // |intercepted_render_frames_| or |intercepted_frame_tree_nodes_| have
- // values. Entries in |intercepted_page_for_web_contents_| only get removed
- // if WebContents goes away.
- base::flat_map<WebContents*, std::unique_ptr<InterceptedPage>>
- intercepted_page_for_web_contents_;
- // First item is routing_id second is process_id.
- base::flat_map<std::pair<int, int>, WebContents*>
- intercepted_render_frames_;
- base::flat_map<FrameTreeNodeId, WebContents*> intercepted_frame_tree_nodes_;
-
- // UI thread only.
- base::flat_map<WebContents*,
- std::unique_ptr<InterceptedWebContentsObserver>>
- observers_;
-
- base::flat_map<std::string, DevToolsURLInterceptorRequestJob*>
- interception_id_to_job_map_;
-
- // The DevToolsURLInterceptorRequestJob proxies a sub request to actually
- // fetch the bytes from the network. We don't want to intercept those
- // requests.
- base::flat_set<const net::URLRequest*> sub_requests_;
-
- // To simplify handling of redirect chains for the end user, we arrange for
- // all requests in the chain to have the same interception id.
- base::flat_map<const net::URLRequest*, std::string> expected_redirects_;
- size_t next_id_;
-
- private:
- friend class base::RefCountedThreadSafe<State>;
- ~State();
- DISALLOW_COPY_AND_ASSIGN(State);
+ Pattern();
+ ~Pattern();
+ Pattern(const Pattern& other);
+ Pattern(const std::string& url_pattern,
+ base::flat_set<ResourceType> resource_types,
+ InterceptionStage interception_stage);
+ const std::string url_pattern;
+ const base::flat_set<ResourceType> resource_types;
+ InterceptionStage interception_stage;
};
- const scoped_refptr<State>& state() const { return state_; }
+ struct FilterEntry {
+ FilterEntry(const base::UnguessableToken& target_id,
+ std::vector<Pattern> patterns,
+ RequestInterceptedCallback callback);
+ FilterEntry(FilterEntry&&);
+ ~FilterEntry();
+
+ const base::UnguessableToken target_id;
+ std::vector<Pattern> patterns;
+ const DevToolsURLRequestInterceptor::RequestInterceptedCallback callback;
+
+ DISALLOW_COPY_AND_ASSIGN(FilterEntry);
+ };
+
+ void AddFilterEntry(std::unique_ptr<FilterEntry> entry);
+ void RemoveFilterEntry(const FilterEntry* entry);
+ void UpdatePatterns(FilterEntry* entry, std::vector<Pattern> patterns);
+
+ // net::URLRequestInterceptor implementation:
+ net::URLRequestJob* MaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override;
+
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override;
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override;
+
+ // Registers a |sub_request| that should not be intercepted.
+ void RegisterSubRequest(const net::URLRequest* sub_request);
+
+ // Unregisters a |sub_request|.
+ void UnregisterSubRequest(const net::URLRequest* sub_request);
+
+ // To make the user's life easier we make sure requests in a redirect chain
+ // all have the same id.
+ void ExpectRequestAfterRedirect(const net::URLRequest* request,
+ std::string id);
+
+ void JobFinished(const std::string& interception_id, bool is_navigation);
+ void GetResponseBody(
+ std::string interception_id,
+ std::unique_ptr<GetResponseBodyForInterceptionCallback> callback);
+ void ContinueInterceptedRequest(
+ std::string interception_id,
+ std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
+ modifications,
+ std::unique_ptr<ContinueInterceptedRequestCallback> callback);
private:
- BrowserContext* const browser_context_;
+ net::URLRequestJob* InnerMaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate);
+
+ FilterEntry* FilterEntryForRequest(const base::UnguessableToken target_id,
+ const GURL& url,
+ ResourceType resource_type,
+ InterceptionStage* stage);
+
+ const DevToolsTargetRegistry::TargetInfo* TargetInfoForRequestInfo(
+ const ResourceRequestInfo* request_info) const;
+
+ std::string GetIdForRequest(const net::URLRequest* request,
+ bool* is_redirect);
+ // Returns a WeakPtr to the DevToolsURLInterceptorRequestJob corresponding
+ // to |interception_id|.
+ DevToolsURLInterceptorRequestJob* GetJob(
+ const std::string& interception_id) const;
+
+ std::unique_ptr<DevToolsTargetRegistry::Resolver> target_resolver_;
+ base::WeakPtr<DevToolsInterceptorController> controller_;
+
+ base::flat_map<base::UnguessableToken,
+ std::vector<std::unique_ptr<FilterEntry>>>
+ target_id_to_entries_;
+
+ base::flat_map<std::string, DevToolsURLInterceptorRequestJob*>
+ interception_id_to_job_map_;
+
+ // The DevToolsURLInterceptorRequestJob proxies a sub request to actually
+ // fetch the bytes from the network. We don't want to intercept those
+ // requests.
+ base::flat_set<const net::URLRequest*> sub_requests_;
+
+ // To simplify handling of redirect chains for the end user, we arrange for
+ // all requests in the chain to have the same interception id.
+ base::flat_map<const net::URLRequest*, std::string> expected_redirects_;
+ size_t next_id_;
- scoped_refptr<State> state_;
+ base::WeakPtrFactory<DevToolsURLRequestInterceptor> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DevToolsURLRequestInterceptor);
};
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 cb057ac0474..860585dbe12 100644
--- a/chromium/content/browser/devtools/protocol/devtools_download_manager_delegate.cc
+++ b/chromium/content/browser/devtools/protocol/devtools_download_manager_delegate.cc
@@ -156,7 +156,7 @@ void DevToolsDownloadManagerDelegate::GenerateFilename(
const std::string& mime_type,
const base::FilePath& suggested_directory,
const FilenameDeterminedCallback& callback) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
base::FilePath generated_name =
net::GenerateFileName(url, content_disposition, std::string(),
suggested_filename, mime_type, "download");
diff --git a/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index 7ac59b8799b..744b2694c2f 100644
--- a/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -27,6 +27,7 @@
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/download_task_runner.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
+#include "content/browser/frame_host/navigator.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/devtools_agent_host.h"
@@ -153,6 +154,7 @@ class TestJavaScriptDialogManager : public JavaScriptDialogManager,
};
void RunBeforeUnloadDialog(WebContents* web_contents,
+ RenderFrameHost* render_frame_host,
bool is_reload,
DialogClosedCallback callback) override {}
@@ -243,7 +245,7 @@ class DevToolsProtocolTest : public ContentBrowserTest,
return result_.get();
}
in_dispatch_ = false;
- return nullptr;
+ return result_.get();
}
void WaitForResponse() {
@@ -252,7 +254,7 @@ class DevToolsProtocolTest : public ContentBrowserTest,
}
bool HasValue(const std::string& path) {
- base::Value* value = 0;
+ base::Value* value = nullptr;
return result_->Get(path, &value);
}
@@ -473,7 +475,7 @@ class DevToolsProtocolTest : public ContentBrowserTest,
}
}
- void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override {
+ void AgentHostClosed(DevToolsAgentHost* agent_host) override {
if (!agent_host_can_close_)
NOTREACHED();
}
@@ -560,52 +562,52 @@ IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyboardEventAck) {
Attach();
ASSERT_TRUE(content::ExecuteScript(
shell()->web_contents()->GetRenderViewHost(),
- "document.body.addEventListener('keydown', () => console.log('x'));"));
+ "document.body.addEventListener('keydown', () => {debugger;});"));
- scoped_refptr<InputMsgWatcher> filter = new InputMsgWatcher(
+ auto filter = std::make_unique<InputMsgWatcher>(
RenderWidgetHostImpl::From(
shell()->web_contents()->GetRenderViewHost()->GetWidget()),
- blink::WebInputEvent::kMouseMove);
+ blink::WebInputEvent::kRawKeyDown);
- SendCommand("Runtime.enable", nullptr);
+ SendCommand("Debugger.enable", nullptr);
SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter", false);
- // We expect that the console log message event arrives *before* the input
+ // We expect that the debugger message event arrives *before* the input
// event ack, and the subsequent command response for Input.dispatchKeyEvent.
- WaitForNotification("Runtime.consoleAPICalled");
- EXPECT_THAT(console_messages_, ElementsAre("x"));
+ WaitForNotification("Debugger.paused");
EXPECT_FALSE(filter->HasReceivedAck());
EXPECT_EQ(1u, result_ids_.size());
- WaitForResponse();
- EXPECT_EQ(2u, result_ids_.size());
+ SendCommand("Debugger.resume", nullptr);
+ filter->WaitForAck();
+ EXPECT_EQ(3u, result_ids_.size());
}
-IN_PROC_BROWSER_TEST_F(SyntheticMouseEventTest, MouseEventAck) {
+IN_PROC_BROWSER_TEST_F(SyntheticMouseEventTest, DISABLED_MouseEventAck) {
NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
Attach();
ASSERT_TRUE(content::ExecuteScript(
shell()->web_contents()->GetRenderViewHost(),
- "document.body.addEventListener('mousemove', () => console.log('x'));"));
+ "document.body.addEventListener('mousemove', () => {debugger;});"));
- scoped_refptr<InputMsgWatcher> filter = new InputMsgWatcher(
+ auto filter = std::make_unique<InputMsgWatcher>(
RenderWidgetHostImpl::From(
shell()->web_contents()->GetRenderViewHost()->GetWidget()),
blink::WebInputEvent::kMouseMove);
- SendCommand("Runtime.enable", nullptr);
+ SendCommand("Debugger.enable", nullptr);
SendMouseEvent("mouseMoved", 15, 15, false);
- // We expect that the console log message event arrives *before* the input
+ // We expect that the debugger message event arrives *before* the input
// event ack, and the subsequent command response for
// Input.dispatchMouseEvent.
- WaitForNotification("Runtime.consoleAPICalled");
- EXPECT_THAT(console_messages_, ElementsAre("x"));
+ WaitForNotification("Debugger.paused");
EXPECT_FALSE(filter->HasReceivedAck());
EXPECT_EQ(1u, result_ids_.size());
- WaitForResponse();
- EXPECT_EQ(2u, result_ids_.size());
+ SendCommand("Debugger.resume", nullptr);
+ filter->WaitForAck();
+ EXPECT_EQ(3u, result_ids_.size());
}
namespace {
@@ -1500,19 +1502,21 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, PageStopLoading) {
ASSERT_TRUE(embedded_test_server()->Start());
// Navigate to about:blank first so we can make sure there is a target page we
- // can attach to, and have Network.setRequestInterceptionEnabled complete
+ // can attach to, and have Network.setRequestInterception complete
// before we start the navigations we're interested in.
NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
Attach();
std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
- params->SetBoolean("enabled", true);
- SendCommand("Network.setRequestInterceptionEnabled", std::move(params), true);
+ std::unique_ptr<base::ListValue> patterns(new base::ListValue());
+ patterns->Append(std::make_unique<base::DictionaryValue>());
+ params->Set("patterns", std::move(patterns));
+ SendCommand("Network.setRequestInterception", std::move(params), true);
LoadFinishedObserver load_finished_observer(shell()->web_contents());
// The page will try to navigate twice, however since
- // Network.setRequestInterceptionEnabled is true,
+ // Network.setRequestInterception is true,
// it'll wait for confirmation before committing to the navigation.
GURL test_url = embedded_test_server()->GetURL(
"/devtools/control_navigations/meta_tag.html");
@@ -1529,14 +1533,16 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, ControlNavigationsMainFrame) {
ASSERT_TRUE(embedded_test_server()->Start());
// Navigate to about:blank first so we can make sure there is a target page we
- // can attach to, and have Network.setRequestInterceptionEnabled complete
+ // can attach to, and have Network.setRequestInterception complete
// before we start the navigations we're interested in.
NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
Attach();
std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
- params->SetBoolean("enabled", true);
- SendCommand("Network.setRequestInterceptionEnabled", std::move(params), true);
+ std::unique_ptr<base::ListValue> patterns(new base::ListValue());
+ patterns->Append(std::make_unique<base::DictionaryValue>());
+ params->Set("patterns", std::move(patterns));
+ SendCommand("Network.setRequestInterception", std::move(params), true);
NavigationFinishedObserver navigation_finished_observer(
shell()->web_contents());
@@ -1579,14 +1585,16 @@ IN_PROC_BROWSER_TEST_F(IsolatedDevToolsProtocolTest,
ASSERT_TRUE(embedded_test_server()->Start());
// Navigate to about:blank first so we can make sure there is a target page we
- // can attach to, and have Network.setRequestInterceptionEnabled complete
+ // can attach to, and have Network.setRequestInterception complete
// before we start the navigations we're interested in.
NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
Attach();
std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
- params->SetBoolean("enabled", true);
- SendCommand("Network.setRequestInterceptionEnabled", std::move(params), true);
+ std::unique_ptr<base::ListValue> patterns(new base::ListValue());
+ patterns->Append(std::make_unique<base::DictionaryValue>());
+ params->Set("patterns", std::move(patterns));
+ SendCommand("Network.setRequestInterception", std::move(params), true);
NavigationFinishedObserver navigation_finished_observer(
shell()->web_contents());
@@ -1874,7 +1882,7 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, TargetDiscovery) {
EXPECT_TRUE(notifications_.empty());
WebContents::CreateParams create_params(
- ShellContentBrowserClient::Get()->browser_context(), NULL);
+ ShellContentBrowserClient::Get()->browser_context(), nullptr);
std::unique_ptr<content::WebContents> web_contents(
content::WebContents::Create(create_params));
EXPECT_TRUE(notifications_.empty());
@@ -1956,7 +1964,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsProtocolTest, TargetNoDiscovery) {
Attach();
command_params.reset(new base::DictionaryValue());
command_params->SetBoolean("autoAttach", true);
- command_params->SetBoolean("waitForDebuggerOnStart", true);
+ command_params->SetBoolean("waitForDebuggerOnStart", false);
SendCommand("Target.setAutoAttach", std::move(command_params), true);
EXPECT_TRUE(notifications_.empty());
command_params.reset(new base::DictionaryValue());
@@ -2163,8 +2171,7 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CertificateExplanations) {
// There should be one explanation containing the server's certificate chain.
net::SHA256HashValue cert_chain_fingerprint =
- net::X509Certificate::CalculateChainFingerprint256(
- cert->os_cert_handle(), cert->GetIntermediateCertificates());
+ cert->CalculateChainFingerprint256();
// Read the certificate out of the first explanation.
const base::ListValue* certificate;
@@ -2184,9 +2191,7 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CertificateExplanations) {
net::X509Certificate::CreateFromDERCertChain(cert_string_piece);
ASSERT_TRUE(explanation_cert);
EXPECT_EQ(cert_chain_fingerprint,
- net::X509Certificate::CalculateChainFingerprint256(
- explanation_cert->os_cert_handle(),
- explanation_cert->GetIntermediateCertificates()));
+ explanation_cert->CalculateChainFingerprint256());
}
// Download tests are flaky on Android: https://crbug.com/7546
@@ -2214,12 +2219,12 @@ class CountingDownloadFile : public DownloadFileImpl {
CountingDownloadFile(std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_downloads_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer)
: DownloadFileImpl(std::move(save_info),
default_downloads_directory,
std::move(stream),
- net_log,
+ download_id,
observer) {}
~CountingDownloadFile() override {
@@ -2271,11 +2276,11 @@ class CountingDownloadFileFactory : public DownloadFileFactory {
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_downloads_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer) override {
return new CountingDownloadFile(std::move(save_info),
default_downloads_directory,
- std::move(stream), net_log, observer);
+ std::move(stream), download_id, observer);
}
};
diff --git a/chromium/content/browser/devtools/protocol/emulation_handler.cc b/chromium/content/browser/devtools/protocol/emulation_handler.cc
index 2a971aa0169..09e9fd24f71 100644
--- a/chromium/content/browser/devtools/protocol/emulation_handler.cc
+++ b/chromium/content/browser/devtools/protocol/emulation_handler.cc
@@ -14,16 +14,14 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/view_messages.h"
#include "content/public/common/url_constants.h"
-#include "device/geolocation/geolocation_context.h"
-#include "device/geolocation/geoposition.h"
+#include "device/geolocation/public/cpp/geoposition.h"
+#include "device/geolocation/public/interfaces/geolocation_context.mojom.h"
+#include "device/geolocation/public/interfaces/geoposition.mojom.h"
#include "ui/events/gesture_detection/gesture_provider_config_helper.h"
namespace content {
namespace protocol {
-using GeolocationContext = device::GeolocationContext;
-using Geoposition = device::Geoposition;
-
namespace {
blink::WebScreenOrientationType WebScreenOrientationTypeFromString(
@@ -96,18 +94,20 @@ Response EmulationHandler::SetGeolocationOverride(
if (!GetWebContents())
return Response::InternalError();
- GeolocationContext* geolocation_context =
- GetWebContents()->GetGeolocationContext();
- std::unique_ptr<Geoposition> geoposition(new Geoposition());
+ auto* geolocation_context = GetWebContents()->GetGeolocationContext();
+ auto geoposition = device::mojom::Geoposition::New();
if (latitude.isJust() && longitude.isJust() && accuracy.isJust()) {
geoposition->latitude = latitude.fromJust();
geoposition->longitude = longitude.fromJust();
geoposition->accuracy = accuracy.fromJust();
geoposition->timestamp = base::Time::Now();
- if (!geoposition->Validate())
+
+ if (!device::ValidateGeoposition(*geoposition))
return Response::Error("Invalid geolocation");
+
} else {
- geoposition->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
+ geoposition->error_code =
+ device::mojom::Geoposition::ErrorCode::POSITION_UNAVAILABLE;
}
geolocation_context->SetOverride(std::move(geoposition));
return Response::OK();
@@ -117,8 +117,7 @@ Response EmulationHandler::ClearGeolocationOverride() {
if (!GetWebContents())
return Response::InternalError();
- GeolocationContext* geolocation_context =
- GetWebContents()->GetGeolocationContext();
+ auto* geolocation_context = GetWebContents()->GetGeolocationContext();
geolocation_context->ClearOverride();
return Response::OK();
}
@@ -191,9 +190,8 @@ Response EmulationHandler::SetDeviceMetricsOverride(
return Response::InvalidParams("deviceScaleFactor must be non-negative");
if (scale.fromMaybe(1) <= 0 || scale.fromMaybe(1) > max_scale) {
- return Response::InvalidParams(
- "scale must be positive, not greater than " +
- base::DoubleToString(max_scale));
+ return Response::InvalidParams("scale must be positive, not greater than " +
+ base::NumberToString(max_scale));
}
blink::WebScreenOrientationType orientationType =
@@ -246,19 +244,31 @@ Response EmulationHandler::SetDeviceMetricsOverride(
params.viewport_scale);
}
- if (device_emulation_enabled_ && params == device_emulation_params_)
+ bool size_changed = false;
+ if (!dont_set_visible_size.fromMaybe(false) && width > 0 && height > 0) {
+ gfx::Size new_size(width, height);
+ if (widget_host->GetView()->GetViewBounds().size() != new_size) {
+ if (original_view_size_.IsEmpty())
+ original_view_size_ = widget_host->GetView()->GetViewBounds().size();
+ widget_host->GetView()->SetSize(new_size);
+ size_changed = true;
+ }
+ }
+
+ if (device_emulation_enabled_ && params == device_emulation_params_) {
+ // Renderer should answer after size was changed, so that the response is
+ // only sent to the client once updates were applied.
+ if (size_changed)
+ return Response::FallThrough();
return Response::OK();
+ }
device_emulation_enabled_ = true;
device_emulation_params_ = params;
- if (!dont_set_visible_size.fromMaybe(false) && width > 0 && height > 0) {
- original_view_size_ = widget_host->GetView()->GetViewBounds().size();
- widget_host->GetView()->SetSize(gfx::Size(width, height));
- } else {
- original_view_size_ = gfx::Size();
- }
UpdateDeviceEmulationState();
- return Response::OK();
+ // Renderer should answer after emulation params were updated, so that the
+ // response is only sent to the client once updates were applied.
+ return Response::FallThrough();
}
Response EmulationHandler::ClearDeviceMetricsOverride() {
@@ -275,7 +285,9 @@ Response EmulationHandler::ClearDeviceMetricsOverride() {
widget_host->GetView()->SetSize(original_view_size_);
original_view_size_ = gfx::Size();
UpdateDeviceEmulationState();
- return Response::OK();
+ // Renderer should answer after emulation was disabled, so that the response
+ // is only sent to the client once updates were applied.
+ return Response::FallThrough();
}
Response EmulationHandler::SetVisibleSize(int width, int height) {
@@ -333,6 +345,13 @@ void EmulationHandler::UpdateDeviceEmulationState() {
host_ ? host_->GetRenderWidgetHost() : nullptr;
if (!widget_host)
return;
+ // TODO(eseckler): Once we change this to mojo, we should wait for an ack to
+ // these messages from the renderer. The renderer should send the ack once the
+ // 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.
if (device_emulation_enabled_) {
widget_host->Send(new ViewMsg_EnableDeviceEmulation(
widget_host->GetRoutingID(), device_emulation_params_));
diff --git a/chromium/content/browser/devtools/protocol/input_handler.cc b/chromium/content/browser/devtools/protocol/input_handler.cc
index f4be3474e43..c8a746b79db 100644
--- a/chromium/content/browser/devtools/protocol/input_handler.cc
+++ b/chromium/content/browser/devtools/protocol/input_handler.cc
@@ -62,7 +62,10 @@ bool StringToGestureSourceType(Maybe<std::string> in,
return false;
}
-int GetEventModifiers(int modifiers, bool auto_repeat, bool is_keypad) {
+int GetEventModifiers(int modifiers,
+ bool auto_repeat,
+ bool is_keypad,
+ int location) {
int result = 0;
if (auto_repeat)
result |= blink::WebInputEvent::kIsAutoRepeat;
@@ -77,6 +80,11 @@ int GetEventModifiers(int modifiers, bool auto_repeat, bool is_keypad) {
result |= blink::WebInputEvent::kMetaKey;
if (modifiers & 8)
result |= blink::WebInputEvent::kShiftKey;
+
+ if (location & 1)
+ result |= blink::WebInputEvent::kIsLeft;
+ if (location & 2)
+ result |= blink::WebInputEvent::kIsRight;
return result;
}
@@ -282,7 +290,9 @@ void InputHandler::OnInputEvent(const blink::WebInputEvent& event) {
input_queued_ = true;
}
-void InputHandler::OnInputEventAck(const blink::WebInputEvent& event) {
+void InputHandler::OnInputEventAck(InputEventAckSource source,
+ InputEventAckState state,
+ const blink::WebInputEvent& event) {
if (blink::WebInputEvent::IsKeyboardEventType(event.GetType()) &&
!pending_key_callbacks_.empty()) {
pending_key_callbacks_.front()->sendSuccess();
@@ -334,6 +344,7 @@ void InputHandler::DispatchKeyEvent(
Maybe<bool> auto_repeat,
Maybe<bool> is_keypad,
Maybe<bool> is_system_key,
+ Maybe<int> location,
std::unique_ptr<DispatchKeyEventCallback> callback) {
blink::WebInputEvent::Type web_event_type;
@@ -355,7 +366,7 @@ void InputHandler::DispatchKeyEvent(
web_event_type,
GetEventModifiers(modifiers.fromMaybe(blink::WebInputEvent::kNoModifiers),
auto_repeat.fromMaybe(false),
- is_keypad.fromMaybe(false)),
+ is_keypad.fromMaybe(false), location.fromMaybe(0)),
GetEventTimeTicks(std::move(timestamp)));
if (!SetKeyboardEventText(event.text, std::move(text))) {
@@ -437,7 +448,7 @@ void InputHandler::DispatchMouseEvent(
int modifiers = GetEventModifiers(
maybe_modifiers.fromMaybe(blink::WebInputEvent::kNoModifiers), false,
- false);
+ false, 0);
modifiers |= button_modifiers;
double timestamp = GetEventTimestamp(std::move(maybe_timestamp));
@@ -512,7 +523,7 @@ void InputHandler::DispatchTouchEvent(
int modifiers = GetEventModifiers(
maybe_modifiers.fromMaybe(blink::WebInputEvent::kNoModifiers), false,
- false);
+ false, 0);
double timestamp = GetEventTimestamp(std::move(maybe_timestamp));
if ((type == blink::WebInputEvent::kTouchStart ||
@@ -670,19 +681,23 @@ Response InputHandler::EmulateTouchFromMouseEvent(const std::string& type,
event_type,
GetEventModifiers(
modifiers.fromMaybe(blink::WebInputEvent::kNoModifiers), false,
- false) |
+ false, 0) |
button_modifiers,
GetEventTimestamp(timestamp));
mouse_event = wheel_event;
event.reset(wheel_event);
wheel_event->delta_x = static_cast<float>(delta_x.fromJust());
wheel_event->delta_y = static_cast<float>(delta_y.fromJust());
+ if (base::FeatureList::IsEnabled(
+ features::kTouchpadAndWheelScrollLatching)) {
+ wheel_event->phase = blink::WebMouseWheelEvent::kPhaseBegan;
+ }
} else {
mouse_event = new blink::WebMouseEvent(
event_type,
GetEventModifiers(
modifiers.fromMaybe(blink::WebInputEvent::kNoModifiers), false,
- false) |
+ false, 0) |
button_modifiers,
GetEventTimestamp(timestamp));
event.reset(mouse_event);
@@ -697,10 +712,20 @@ Response InputHandler::EmulateTouchFromMouseEvent(const std::string& type,
if (!host_ || !host_->GetRenderWidgetHost())
return Response::InternalError();
- if (wheel_event)
+ if (wheel_event) {
host_->GetRenderWidgetHost()->ForwardWheelEvent(*wheel_event);
- else
+ if (base::FeatureList::IsEnabled(
+ features::kTouchpadAndWheelScrollLatching)) {
+ // Send a synthetic wheel event with phaseEnded to finish scrolling.
+ wheel_event->delta_x = 0;
+ wheel_event->delta_y = 0;
+ wheel_event->phase = blink::WebMouseWheelEvent::kPhaseEnded;
+ wheel_event->dispatch_type = blink::WebInputEvent::kEventNonBlocking;
+ host_->GetRenderWidgetHost()->ForwardWheelEvent(*wheel_event);
+ }
+ } else {
host_->GetRenderWidgetHost()->ForwardMouseEvent(*mouse_event);
+ }
return Response::OK();
}
diff --git a/chromium/content/browser/devtools/protocol/input_handler.h b/chromium/content/browser/devtools/protocol/input_handler.h
index 3d75934df25..e87dd6479c9 100644
--- a/chromium/content/browser/devtools/protocol/input_handler.h
+++ b/chromium/content/browser/devtools/protocol/input_handler.h
@@ -58,6 +58,7 @@ class InputHandler : public DevToolsDomainHandler,
Maybe<bool> auto_repeat,
Maybe<bool> is_keypad,
Maybe<bool> is_system_key,
+ Maybe<int> location,
std::unique_ptr<DispatchKeyEventCallback> callback) override;
void DispatchMouseEvent(
@@ -125,7 +126,9 @@ class InputHandler : public DevToolsDomainHandler,
private:
// InputEventObserver
void OnInputEvent(const blink::WebInputEvent& event) override;
- void OnInputEventAck(const blink::WebInputEvent& event) override;
+ void OnInputEventAck(InputEventAckSource source,
+ InputEventAckState state,
+ const blink::WebInputEvent& event) override;
void SynthesizeRepeatingScroll(
SyntheticSmoothScrollGestureParams gesture_params,
diff --git a/chromium/content/browser/devtools/protocol/network_handler.cc b/chromium/content/browser/devtools/protocol/network_handler.cc
index d50afce1ac0..1bedb329a45 100644
--- a/chromium/content/browser/devtools/protocol/network_handler.cc
+++ b/chromium/content/browser/devtools/protocol/network_handler.cc
@@ -16,15 +16,13 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
+#include "content/browser/devtools/devtools_interceptor_controller.h"
#include "content/browser/devtools/devtools_session.h"
-#include "content/browser/devtools/devtools_url_interceptor_request_job.h"
#include "content/browser/devtools/protocol/page.h"
#include "content/browser/devtools/protocol/security.h"
#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/navigation_request.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
-#include "content/common/devtools/devtools_network_conditions.h"
-#include "content/common/devtools/devtools_network_controller.h"
-#include "content/common/devtools/devtools_network_transaction.h"
#include "content/common/navigation_params.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -32,6 +30,7 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/service_worker_context.h"
@@ -42,17 +41,20 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/resource_devtools_info.h"
#include "content/public/common/resource_request.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "content/public/common/resource_response.h"
#include "net/base/net_errors.h"
#include "net/base/upload_bytes_element_reader.h"
+#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_store.h"
#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
namespace content {
namespace protocol {
+
namespace {
using ProtocolCookieArray = Array<Network::Cookie>;
@@ -64,6 +66,9 @@ using DeleteCookiesCallback = Network::Backend::DeleteCookiesCallback;
using ClearBrowserCookiesCallback =
Network::Backend::ClearBrowserCookiesCallback;
+const char kDevToolsEmulateNetworkConditionsClientId[] =
+ "X-DevTools-Emulate-Network-Conditions-Client-Id";
+
class CookieRetriever : public base::RefCountedThreadSafe<CookieRetriever> {
public:
CookieRetriever(std::unique_ptr<GetCookiesCallback> callback)
@@ -143,7 +148,7 @@ class CookieRetriever : public base::RefCountedThreadSafe<CookieRetriever> {
.SetValue(cookie.Value())
.SetDomain(cookie.Domain())
.SetPath(cookie.Path())
- .SetExpires(cookie.ExpiryDate().ToDoubleT())
+ .SetExpires(cookie.ExpiryDate().is_null() ? -1 : cookie.ExpiryDate().ToDoubleT())
.SetSize(cookie.Name().length() + cookie.Value().length())
.SetHttpOnly(cookie.IsHttpOnly())
.SetSecure(cookie.IsSecure())
@@ -317,10 +322,17 @@ void SetCookieOnIO(net::URLRequestContextGetter* context_getter,
if (same_site == Network::CookieSameSiteEnum::Strict)
css = net::CookieSameSite::STRICT_MODE;
- request_context->cookie_store()->SetCookieWithDetailsAsync(
- url, name, value, normalized_domain, path, base::Time(), expiration_date,
- base::Time(), secure, http_only, css, net::COOKIE_PRIORITY_DEFAULT,
- std::move(callback));
+ std::unique_ptr<net::CanonicalCookie> cc(
+ net::CanonicalCookie::CreateSanitizedCookie(
+ url, name, value, normalized_domain, path, base::Time(),
+ expiration_date, base::Time(), secure, http_only, css,
+ net::COOKIE_PRIORITY_DEFAULT));
+ if (!cc) {
+ std::move(callback).Run(false);
+ return;
+ }
+ request_context->cookie_store()->SetCanonicalCookieAsync(
+ std::move(cc), secure, true /*modify_http_only*/, std::move(callback));
}
void CookiesSetOnIO(std::unique_ptr<SetCookiesCallback> callback,
@@ -458,6 +470,17 @@ String securityState(const GURL& url, const net::CertStatus& cert_status) {
return Security::SecurityStateEnum::Secure;
}
+DevToolsURLRequestInterceptor::InterceptionStage ToInterceptorStage(
+ const protocol::Network::InterceptionStage& interceptor_stage) {
+ if (interceptor_stage == protocol::Network::InterceptionStageEnum::Request)
+ return DevToolsURLRequestInterceptor::REQUEST;
+ if (interceptor_stage ==
+ protocol::Network::InterceptionStageEnum::HeadersReceived)
+ return DevToolsURLRequestInterceptor::RESPONSE;
+ NOTREACHED();
+ return DevToolsURLRequestInterceptor::REQUEST;
+}
+
net::Error NetErrorFromString(const std::string& error, bool* ok) {
*ok = true;
if (error == Network::ErrorReasonEnum::Failed)
@@ -488,6 +511,32 @@ net::Error NetErrorFromString(const std::string& error, bool* ok) {
return net::ERR_FAILED;
}
+String NetErrorToString(int net_error) {
+ if (net_error == net::ERR_ABORTED)
+ return Network::ErrorReasonEnum::Aborted;
+ if (net_error == net::ERR_TIMED_OUT)
+ return Network::ErrorReasonEnum::TimedOut;
+ if (net_error == net::ERR_ACCESS_DENIED)
+ return Network::ErrorReasonEnum::AccessDenied;
+ if (net_error == net::ERR_CONNECTION_CLOSED)
+ return Network::ErrorReasonEnum::ConnectionClosed;
+ if (net_error == net::ERR_CONNECTION_RESET)
+ return Network::ErrorReasonEnum::ConnectionReset;
+ if (net_error == net::ERR_CONNECTION_REFUSED)
+ return Network::ErrorReasonEnum::ConnectionRefused;
+ if (net_error == net::ERR_CONNECTION_ABORTED)
+ return Network::ErrorReasonEnum::ConnectionAborted;
+ if (net_error == net::ERR_CONNECTION_FAILED)
+ return Network::ErrorReasonEnum::ConnectionFailed;
+ if (net_error == net::ERR_NAME_NOT_RESOLVED)
+ return Network::ErrorReasonEnum::NameNotResolved;
+ if (net_error == net::ERR_INTERNET_DISCONNECTED)
+ return Network::ErrorReasonEnum::InternetDisconnected;
+ if (net_error == net::ERR_ADDRESS_UNREACHABLE)
+ return Network::ErrorReasonEnum::AddressUnreachable;
+ return Network::ErrorReasonEnum::Failed;
+}
+
bool AddInterceptedResourceType(
const std::string& resource_type,
base::flat_set<ResourceType>* intercepted_resource_types) {
@@ -637,8 +686,7 @@ class NetworkNavigationThrottle : public content::NavigationThrottle {
void ConfigureServiceWorkerContextOnIO() {
std::set<std::string> headers;
- headers.insert(
- DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId);
+ headers.insert(kDevToolsEmulateNetworkConditionsClientId);
content::ServiceWorkerContext::AddExcludedHeadersForFetchEvent(headers);
}
@@ -649,8 +697,8 @@ NetworkHandler::NetworkHandler(const std::string& host_id)
process_(nullptr),
host_(nullptr),
enabled_(false),
- interception_enabled_(false),
host_id_(host_id),
+ bypass_service_worker_(false),
weak_factory_(this) {
static bool have_configured_service_worker_context = false;
if (have_configured_service_worker_context)
@@ -690,25 +738,48 @@ Response NetworkHandler::Enable(Maybe<int> max_total_size,
Response NetworkHandler::Disable() {
enabled_ = false;
user_agent_ = std::string();
- SetRequestInterceptionEnabled(false, Maybe<protocol::Array<String>>(),
- Maybe<protocol::Array<String>>());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&DevToolsNetworkController::SetNetworkState, host_id_,
- nullptr));
+ interception_handle_.reset();
+ SetNetworkConditions(nullptr);
+ extra_headers_.clear();
return Response::FallThrough();
}
-Response NetworkHandler::ClearBrowserCache() {
- if (!process_)
- return Response::InternalError();
+class DevtoolsClearCacheObserver
+ : public content::BrowsingDataRemover::Observer {
+ public:
+ explicit DevtoolsClearCacheObserver(
+ content::BrowsingDataRemover* remover,
+ std::unique_ptr<NetworkHandler::ClearBrowserCacheCallback> callback)
+ : remover_(remover), callback_(std::move(callback)) {
+ remover_->AddObserver(this);
+ }
+
+ ~DevtoolsClearCacheObserver() override { remover_->RemoveObserver(this); }
+ void OnBrowsingDataRemoverDone() override {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ callback_->sendSuccess();
+ delete this;
+ }
+
+ private:
+ content::BrowsingDataRemover* remover_;
+ std::unique_ptr<NetworkHandler::ClearBrowserCacheCallback> callback_;
+};
+
+void NetworkHandler::ClearBrowserCache(
+ std::unique_ptr<ClearBrowserCacheCallback> callback) {
+ if (!process_) {
+ callback->sendFailure(Response::InternalError());
+ return;
+ }
content::BrowsingDataRemover* remover =
content::BrowserContext::GetBrowsingDataRemover(
process_->GetBrowserContext());
- remover->Remove(base::Time(), base::Time::Max(),
- content::BrowsingDataRemover::DATA_TYPE_CACHE,
- content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB);
- return Response::OK();
+ remover->RemoveAndReply(
+ base::Time(), base::Time::Max(),
+ content::BrowsingDataRemover::DATA_TYPE_CACHE,
+ content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
+ new DevtoolsClearCacheObserver(remover, std::move(callback)));
}
void NetworkHandler::ClearBrowserCookies(
@@ -852,6 +923,25 @@ Response NetworkHandler::SetUserAgentOverride(const std::string& user_agent) {
return Response::FallThrough();
}
+Response NetworkHandler::SetExtraHTTPHeaders(
+ std::unique_ptr<protocol::Network::Headers> headers) {
+ std::vector<std::pair<std::string, std::string>> new_headers;
+ std::unique_ptr<protocol::DictionaryValue> object = headers->toValue();
+ for (size_t i = 0; i < object->size(); ++i) {
+ auto entry = object->at(i);
+ std::string value;
+ if (!entry.second->asString(&value))
+ return Response::InvalidParams("Invalid header value, string expected");
+ if (!net::HttpUtil::IsValidHeaderName(entry.first))
+ return Response::InvalidParams("Invalid header name");
+ if (!net::HttpUtil::IsValidHeaderValue(value))
+ return Response::InvalidParams("Invalid header value");
+ new_headers.emplace_back(entry.first, value);
+ }
+ extra_headers_.swap(new_headers);
+ return Response::FallThrough();
+}
+
Response NetworkHandler::CanEmulateNetworkConditions(bool* result) {
*result = true;
return Response::OK();
@@ -863,15 +953,22 @@ Response NetworkHandler::EmulateNetworkConditions(
double download_throughput,
double upload_throughput,
Maybe<protocol::Network::ConnectionType>) {
- std::unique_ptr<DevToolsNetworkConditions> conditions(
- new DevToolsNetworkConditions(offline, std::max(latency, 0.0),
- std::max(download_throughput, 0.0),
- std::max(upload_throughput, 0.0)));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&DevToolsNetworkController::SetNetworkState, host_id_,
- std::move(conditions)));
+ mojom::NetworkConditionsPtr network_conditions;
+ bool throttling_enabled = offline || latency > 0 || download_throughput > 0 ||
+ upload_throughput > 0;
+ if (throttling_enabled) {
+ network_conditions = mojom::NetworkConditions::New();
+ network_conditions->offline = offline;
+ network_conditions->latency = base::TimeDelta::FromMilliseconds(latency);
+ network_conditions->download_throughput = download_throughput;
+ network_conditions->upload_throughput = upload_throughput;
+ }
+ SetNetworkConditions(std::move(network_conditions));
+ return Response::FallThrough();
+}
+Response NetworkHandler::SetBypassServiceWorker(bool bypass) {
+ bypass_service_worker_ = bypass;
return Response::FallThrough();
}
@@ -964,54 +1061,53 @@ void NetworkHandler::NavigationPreloadResponseReceived(
void NetworkHandler::NavigationPreloadCompleted(
const std::string& request_id,
- const ResourceRequestCompletionStatus& completion_status) {
+ const network::URLLoaderCompletionStatus& status) {
if (!enabled_)
return;
- if (completion_status.error_code != net::OK) {
+ if (status.error_code != net::OK) {
frontend_->LoadingFailed(
request_id,
base::TimeTicks::Now().ToInternalValue() /
static_cast<double>(base::Time::kMicrosecondsPerSecond),
- Page::ResourceTypeEnum::Other,
- net::ErrorToString(completion_status.error_code),
- completion_status.error_code == net::Error::ERR_ABORTED);
+ Page::ResourceTypeEnum::Other, net::ErrorToString(status.error_code),
+ status.error_code == net::Error::ERR_ABORTED);
}
frontend_->LoadingFinished(
request_id,
- completion_status.completion_time.ToInternalValue() /
+ status.completion_time.ToInternalValue() /
static_cast<double>(base::Time::kMicrosecondsPerSecond),
- completion_status.encoded_data_length);
+ status.encoded_data_length);
}
-void NetworkHandler::NavigationFailed(
- const CommonNavigationParams& common_params,
- const BeginNavigationParams& begin_params,
- net::Error error_code) {
+void NetworkHandler::NavigationFailed(NavigationRequest* navigation_request) {
if (!enabled_)
return;
static int next_id = 0;
std::string request_id = base::IntToString(base::GetCurrentProcId()) + "." +
base::IntToString(++next_id);
- std::string error_string = net::ErrorToString(error_code);
- bool cancelled = error_code == net::Error::ERR_ABORTED;
+ std::string error_string =
+ net::ErrorToString(navigation_request->net_error());
+ bool cancelled = navigation_request->net_error() == net::Error::ERR_ABORTED;
std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create());
net::HttpRequestHeaders headers;
- headers.AddHeadersFromString(begin_params.headers);
+ headers.AddHeadersFromString(navigation_request->begin_params().headers);
for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();)
headers_dict->setString(it.name(), it.value());
frontend_->RequestWillBeSent(
- request_id, "" /* loader_id */, common_params.url.spec(),
+ request_id, "" /* loader_id */,
+ navigation_request->common_params().url.spec(),
Network::Request::Create()
- .SetUrl(common_params.url.spec())
- .SetMethod(common_params.method)
+ .SetUrl(navigation_request->common_params().url.spec())
+ .SetMethod(navigation_request->common_params().method)
.SetHeaders(Object::fromValue(headers_dict.get(), nullptr))
// Note: the priority value is copied from
// ResourceDispatcherHostImpl::BeginNavigationRequest but there isn't
// a good way of sharing this.
.SetInitialPriority(resourcePriority(net::HIGHEST))
- .SetReferrerPolicy(referrerPolicy(common_params.referrer.policy))
+ .SetReferrerPolicy(referrerPolicy(
+ navigation_request->common_params().referrer.policy))
.Build(),
base::TimeTicks::Now().ToInternalValue() /
static_cast<double>(base::Time::kMicrosecondsPerSecond),
@@ -1029,56 +1125,49 @@ void NetworkHandler::NavigationFailed(
Page::ResourceTypeEnum::Document, error_string, cancelled);
}
-std::string NetworkHandler::UserAgentOverride() const {
- return enabled_ ? user_agent_ : std::string();
-}
-
-DispatchResponse NetworkHandler::SetRequestInterceptionEnabled(
- bool enabled,
- Maybe<protocol::Array<std::string>> patterns,
- Maybe<protocol::Array<std::string>> resource_types) {
+DispatchResponse NetworkHandler::SetRequestInterception(
+ std::unique_ptr<protocol::Array<protocol::Network::RequestPattern>>
+ patterns) {
WebContents* web_contents = WebContents::FromRenderFrameHost(host_);
if (!web_contents)
return Response::InternalError();
- DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
- DevToolsURLRequestInterceptor::FromBrowserContext(
+ DevToolsInterceptorController* interceptor =
+ DevToolsInterceptorController::FromBrowserContext(
web_contents->GetBrowserContext());
- if (!devtools_url_request_interceptor)
+ if (!interceptor)
return Response::Error("Interception not supported");
- std::vector<std::string> new_patterns;
- if (enabled) {
- if (patterns.isJust()) {
- for (size_t i = 0; i < patterns.fromJust()->length(); i++)
- new_patterns.push_back(patterns.fromJust()->get(i));
- } else {
- new_patterns.push_back("*");
- }
+ if (!patterns->length()) {
+ interception_handle_.reset();
+ return Response::OK();
}
- interception_enabled_ = new_patterns.size();
-
- base::flat_set<ResourceType> intercepted_resource_types;
- if (resource_types.isJust()) {
- for (size_t i = 0; i < resource_types.fromJust()->length(); i++) {
- if (!AddInterceptedResourceType(resource_types.fromJust()->get(i),
- &intercepted_resource_types))
- return Response::Error(
- base::StringPrintf("Cannot intercept resources of type '%s'",
- resource_types.fromJust()->get(i).c_str()));
+
+ std::vector<DevToolsURLRequestInterceptor::Pattern> interceptor_patterns;
+ for (size_t i = 0; i < patterns->length(); ++i) {
+ base::flat_set<ResourceType> resource_types;
+ std::string resource_type = patterns->get(i)->GetResourceType("");
+ if (!resource_type.empty()) {
+ if (!AddInterceptedResourceType(resource_type, &resource_types)) {
+ return Response::InvalidParams(base::StringPrintf(
+ "Cannot intercept resources of type '%s'", resource_type.c_str()));
+ }
}
+ interceptor_patterns.push_back(DevToolsURLRequestInterceptor::Pattern(
+ patterns->get(i)->GetUrlPattern("*"), std::move(resource_types),
+ ToInterceptorStage(patterns->get(i)->GetInterceptionStage(
+ protocol::Network::InterceptionStageEnum::Request))));
}
- if (interception_enabled_) {
- devtools_url_request_interceptor->state()->StartInterceptingRequests(
- web_contents, weak_factory_.GetWeakPtr(), std::move(new_patterns),
- std::move(intercepted_resource_types));
+ if (interception_handle_) {
+ interception_handle_->UpdatePatterns(std::move(interceptor_patterns));
} else {
- devtools_url_request_interceptor->state()->StopInterceptingRequests(
- web_contents);
- navigation_requests_.clear();
- canceled_navigation_requests_.clear();
+ interception_handle_ = interceptor->StartInterceptingRequests(
+ host_->frame_tree_node(), std::move(interceptor_patterns),
+ base::Bind(&NetworkHandler::RequestIntercepted,
+ weak_factory_.GetWeakPtr()));
}
+
return Response::OK();
}
@@ -1092,6 +1181,7 @@ bool GetPostData(const net::URLRequest* request, std::string* post_data) {
return false;
const auto* element_readers = stream->GetElementReaders();
+
if (element_readers->empty())
return false;
@@ -1099,6 +1189,11 @@ bool GetPostData(const net::URLRequest* request, std::string* post_data) {
for (const auto& element_reader : *element_readers) {
const net::UploadBytesElementReader* reader =
element_reader->AsBytesReader();
+ // TODO(caseq): Also support blobs.
+ if (!reader) {
+ *post_data = "";
+ return false;
+ }
// TODO(alexclarke): This should really be base64 encoded.
*post_data += std::string(reader->bytes(), reader->length());
}
@@ -1106,7 +1201,6 @@ bool GetPostData(const net::URLRequest* request, std::string* post_data) {
}
} // namespace
-// TODO(alexclarke): Support structured data as well as |base64_raw_response|.
void NetworkHandler::ContinueInterceptedRequest(
const std::string& interception_id,
Maybe<std::string> error_reason,
@@ -1117,10 +1211,10 @@ void NetworkHandler::ContinueInterceptedRequest(
Maybe<protocol::Network::Headers> headers,
Maybe<protocol::Network::AuthChallengeResponse> auth_challenge_response,
std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
- DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
- DevToolsURLRequestInterceptor::FromBrowserContext(
+ DevToolsInterceptorController* interceptor =
+ DevToolsInterceptorController::FromBrowserContext(
process_->GetBrowserContext());
- if (!devtools_url_request_interceptor) {
+ if (!interceptor) {
callback->sendFailure(Response::InternalError());
return;
}
@@ -1146,28 +1240,31 @@ void NetworkHandler::ContinueInterceptedRequest(
}
mark_as_canceled = true;
-
- if (error_reason.fromJust() == Network::ErrorReasonEnum::Aborted) {
- auto it = navigation_requests_.find(interception_id);
- if (it != navigation_requests_.end()) {
- canceled_navigation_requests_.insert(it->second);
- // To successfully cancel navigation the request must succeed. We
- // provide simple mock response to avoid pointless network fetch.
- error.reset();
- raw_response = std::string("HTTP/1.1 200 OK\r\n\r\n");
- }
- }
}
- devtools_url_request_interceptor->state()->ContinueInterceptedRequest(
+ interceptor->ContinueInterceptedRequest(
interception_id,
- base::MakeUnique<DevToolsURLRequestInterceptor::Modifications>(
+ std::make_unique<DevToolsURLRequestInterceptor::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(callback));
}
+void NetworkHandler::GetResponseBodyForInterception(
+ const String& interception_id,
+ std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) {
+ DevToolsInterceptorController* interceptor =
+ DevToolsInterceptorController::FromBrowserContext(
+ process_->GetBrowserContext());
+
+ if (!interceptor) {
+ callback->sendFailure(Response::InternalError());
+ return;
+ }
+ interceptor->GetResponseBody(interception_id, std::move(callback));
+}
+
// static
GURL NetworkHandler::ClearUrlRef(const GURL& url) {
if (!url.has_ref())
@@ -1201,31 +1298,104 @@ std::unique_ptr<Network::Request> NetworkHandler::CreateRequestFromURLRequest(
std::unique_ptr<NavigationThrottle> NetworkHandler::CreateThrottleForNavigation(
NavigationHandle* navigation_handle) {
- if (!interception_enabled_)
+ if (!interception_handle_)
return nullptr;
std::unique_ptr<NavigationThrottle> throttle(new NetworkNavigationThrottle(
weak_factory_.GetWeakPtr(), navigation_handle));
return throttle;
}
-void NetworkHandler::InterceptedNavigationRequest(
- const GlobalRequestID& global_request_id,
- const std::string& interception_id) {
- navigation_requests_[interception_id] = global_request_id;
+bool NetworkHandler::ShouldCancelNavigation(
+ const GlobalRequestID& global_request_id) {
+ WebContents* web_contents = WebContents::FromRenderFrameHost(host_);
+ if (!web_contents)
+ return false;
+ DevToolsInterceptorController* interceptor =
+ DevToolsInterceptorController::FromBrowserContext(
+ web_contents->GetBrowserContext());
+ return interceptor && interceptor->ShouldCancelNavigation(global_request_id);
+}
+
+void NetworkHandler::AppendDevToolsHeaders(net::HttpRequestHeaders* headers) {
+ headers->SetHeader(kDevToolsEmulateNetworkConditionsClientId, host_id_);
+ if (!user_agent_.empty())
+ headers->SetHeader(net::HttpRequestHeaders::kUserAgent, user_agent_);
+ for (auto& entry : extra_headers_)
+ headers->SetHeader(entry.first, entry.second);
}
-void NetworkHandler::InterceptedNavigationRequestFinished(
- const std::string& interception_id) {
- navigation_requests_.erase(interception_id);
+bool NetworkHandler::ShouldBypassServiceWorker() const {
+ return bypass_service_worker_;
}
-bool NetworkHandler::ShouldCancelNavigation(
- const GlobalRequestID& global_request_id) {
- auto it = canceled_navigation_requests_.find(global_request_id);
- if (it == canceled_navigation_requests_.end())
- return false;
- canceled_navigation_requests_.erase(it);
- return true;
+namespace {
+
+const char* ResourceTypeToString(ResourceType resource_type) {
+ switch (resource_type) {
+ case RESOURCE_TYPE_MAIN_FRAME:
+ return protocol::Page::ResourceTypeEnum::Document;
+ case RESOURCE_TYPE_SUB_FRAME:
+ return protocol::Page::ResourceTypeEnum::Document;
+ case RESOURCE_TYPE_STYLESHEET:
+ return protocol::Page::ResourceTypeEnum::Stylesheet;
+ case RESOURCE_TYPE_SCRIPT:
+ return protocol::Page::ResourceTypeEnum::Script;
+ case RESOURCE_TYPE_IMAGE:
+ return protocol::Page::ResourceTypeEnum::Image;
+ case RESOURCE_TYPE_FONT_RESOURCE:
+ return protocol::Page::ResourceTypeEnum::Font;
+ case RESOURCE_TYPE_SUB_RESOURCE:
+ return protocol::Page::ResourceTypeEnum::Other;
+ case RESOURCE_TYPE_OBJECT:
+ return protocol::Page::ResourceTypeEnum::Other;
+ case RESOURCE_TYPE_MEDIA:
+ return protocol::Page::ResourceTypeEnum::Media;
+ case RESOURCE_TYPE_WORKER:
+ return protocol::Page::ResourceTypeEnum::Other;
+ case RESOURCE_TYPE_SHARED_WORKER:
+ return protocol::Page::ResourceTypeEnum::Other;
+ case RESOURCE_TYPE_PREFETCH:
+ return protocol::Page::ResourceTypeEnum::Fetch;
+ case RESOURCE_TYPE_FAVICON:
+ return protocol::Page::ResourceTypeEnum::Other;
+ case RESOURCE_TYPE_XHR:
+ return protocol::Page::ResourceTypeEnum::XHR;
+ case RESOURCE_TYPE_PING:
+ return protocol::Page::ResourceTypeEnum::Other;
+ case RESOURCE_TYPE_SERVICE_WORKER:
+ return protocol::Page::ResourceTypeEnum::Other;
+ case RESOURCE_TYPE_CSP_REPORT:
+ return protocol::Page::ResourceTypeEnum::Other;
+ case RESOURCE_TYPE_PLUGIN_RESOURCE:
+ return protocol::Page::ResourceTypeEnum::Other;
+ default:
+ return protocol::Page::ResourceTypeEnum::Other;
+ }
+}
+
+} // namespace
+
+void NetworkHandler::RequestIntercepted(
+ std::unique_ptr<InterceptedRequestInfo> info) {
+ protocol::Maybe<protocol::Network::ErrorReason> error_reason;
+ if (info->response_error_code < 0)
+ error_reason = NetErrorToString(info->response_error_code);
+ frontend_->RequestIntercepted(
+ info->interception_id, std::move(info->network_request),
+ info->frame_id.ToString(), ResourceTypeToString(info->resource_type),
+ info->is_navigation, std::move(info->redirect_url),
+ std::move(info->auth_challenge), std::move(error_reason),
+ std::move(info->http_response_status_code),
+ std::move(info->response_headers));
+}
+
+void NetworkHandler::SetNetworkConditions(
+ mojom::NetworkConditionsPtr conditions) {
+ if (!process_)
+ return;
+ StoragePartition* partition = process_->GetStoragePartition();
+ mojom::NetworkContext* context = partition->GetNetworkContext();
+ context->SetNetworkConditions(host_id_, std::move(conditions));
}
} // namespace protocol
diff --git a/chromium/content/browser/devtools/protocol/network_handler.h b/chromium/content/browser/devtools/protocol/network_handler.h
index a7beb866e9d..76a06e5aa28 100644
--- a/chromium/content/browser/devtools/protocol/network_handler.h
+++ b/chromium/content/browser/devtools/protocol/network_handler.h
@@ -13,24 +13,30 @@
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/protocol/devtools_domain_handler.h"
#include "content/browser/devtools/protocol/network.h"
+#include "content/public/common/network_service.mojom.h"
#include "net/base/net_errors.h"
#include "net/cookies/canonical_cookie.h"
namespace net {
+class HttpRequestHeaders;
class URLRequest;
} // namespace net
-namespace content {
+namespace network {
+struct URLLoaderCompletionStatus;
+} // namespace network
+namespace content {
class DevToolsAgentHostImpl;
class RenderFrameHostImpl;
-struct BeginNavigationParams;
-struct CommonNavigationParams;
struct GlobalRequestID;
+class InterceptionHandle;
class NavigationHandle;
+class NavigationRequest;
class NavigationThrottle;
+struct GlobalRequestID;
+struct InterceptedRequestInfo;
struct ResourceRequest;
-struct ResourceRequestCompletionStatus;
struct ResourceResponseHead;
namespace protocol {
@@ -51,7 +57,9 @@ class NetworkHandler : public DevToolsDomainHandler,
Maybe<int> max_resource_size) override;
Response Disable() override;
- Response ClearBrowserCache() override;
+ void ClearBrowserCache(
+ std::unique_ptr<ClearBrowserCacheCallback> callback) override;
+
void ClearBrowserCookies(
std::unique_ptr<ClearBrowserCookiesCallback> callback) override;
@@ -78,6 +86,8 @@ class NetworkHandler : public DevToolsDomainHandler,
std::unique_ptr<SetCookiesCallback> callback) override;
Response SetUserAgentOverride(const std::string& user_agent) override;
+ Response SetExtraHTTPHeaders(
+ std::unique_ptr<Network::Headers> headers) override;
Response CanEmulateNetworkConditions(bool* result) override;
Response EmulateNetworkConditions(
bool offline,
@@ -85,11 +95,11 @@ class NetworkHandler : public DevToolsDomainHandler,
double download_throughput,
double upload_throughput,
Maybe<protocol::Network::ConnectionType> connection_type) override;
+ Response SetBypassServiceWorker(bool bypass) override;
- DispatchResponse SetRequestInterceptionEnabled(
- bool enabled,
- Maybe<protocol::Array<std::string>> patterns,
- Maybe<protocol::Array<std::string>> resource_types) override;
+ DispatchResponse SetRequestInterception(
+ std::unique_ptr<protocol::Array<protocol::Network::RequestPattern>>
+ patterns) override;
void ContinueInterceptedRequest(
const std::string& request_id,
Maybe<std::string> error_reason,
@@ -101,6 +111,11 @@ class NetworkHandler : public DevToolsDomainHandler,
Maybe<protocol::Network::AuthChallengeResponse> auth_challenge_response,
std::unique_ptr<ContinueInterceptedRequestCallback> callback) override;
+ void GetResponseBodyForInterception(
+ const String& interception_id,
+ std::unique_ptr<GetResponseBodyForInterceptionCallback> callback)
+ override;
+
void NavigationPreloadRequestSent(int worker_version_id,
const std::string& request_id,
const ResourceRequest& request);
@@ -110,13 +125,10 @@ class NetworkHandler : public DevToolsDomainHandler,
const ResourceResponseHead& head);
void NavigationPreloadCompleted(
const std::string& request_id,
- const ResourceRequestCompletionStatus& completion_status);
- void NavigationFailed(const CommonNavigationParams& common_params,
- const BeginNavigationParams& begin_params,
- net::Error error_code);
+ const network::URLLoaderCompletionStatus& completion_status);
+ void NavigationFailed(NavigationRequest* navigation_request);
bool enabled() const { return enabled_; }
- std::string UserAgentOverride() const;
Network::Frontend* frontend() const { return frontend_.get(); }
@@ -126,21 +138,23 @@ class NetworkHandler : public DevToolsDomainHandler,
std::unique_ptr<NavigationThrottle> CreateThrottleForNavigation(
NavigationHandle* navigation_handle);
- void InterceptedNavigationRequest(const GlobalRequestID& global_request_id,
- const std::string& interception_id);
- void InterceptedNavigationRequestFinished(const std::string& interception_id);
bool ShouldCancelNavigation(const GlobalRequestID& global_request_id);
+ void AppendDevToolsHeaders(net::HttpRequestHeaders* headers);
+ bool ShouldBypassServiceWorker() const;
private:
+ void RequestIntercepted(std::unique_ptr<InterceptedRequestInfo> request_info);
+ void SetNetworkConditions(mojom::NetworkConditionsPtr conditions);
+
std::unique_ptr<Network::Frontend> frontend_;
RenderProcessHost* process_;
RenderFrameHostImpl* host_;
bool enabled_;
- bool interception_enabled_;
std::string user_agent_;
- base::flat_map<std::string, GlobalRequestID> navigation_requests_;
- base::flat_set<GlobalRequestID> canceled_navigation_requests_;
+ std::vector<std::pair<std::string, std::string>> extra_headers_;
std::string host_id_;
+ std::unique_ptr<InterceptionHandle> interception_handle_;
+ bool bypass_service_worker_;
base::WeakPtrFactory<NetworkHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(NetworkHandler);
diff --git a/chromium/content/browser/devtools/protocol/page_handler.cc b/chromium/content/browser/devtools/protocol/page_handler.cc
index a7b8ce50f19..bab5656d392 100644
--- a/chromium/content/browser/devtools/protocol/page_handler.cc
+++ b/chromium/content/browser/devtools/protocol/page_handler.cc
@@ -25,10 +25,12 @@
#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"
+#include "content/browser/frame_host/navigation_request.h"
#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/browser/web_contents/web_contents_view.h"
+#include "content/common/content_switches_internal.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -41,6 +43,7 @@
#include "content/public/browser/notification_types.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/referrer.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/page_transition_types.h"
@@ -49,6 +52,7 @@
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_util.h"
+#include "ui/gfx/skbitmap_operations.h"
#include "ui/snapshot/snapshot.h"
namespace content {
@@ -302,17 +306,21 @@ Response PageHandler::Reload(Maybe<bool> bypassCache,
}
}
-Response PageHandler::Navigate(const std::string& url,
- Maybe<std::string> referrer,
- Maybe<std::string> maybe_transition_type,
- Page::FrameId* frame_id) {
+void PageHandler::Navigate(const std::string& url,
+ Maybe<std::string> referrer,
+ Maybe<std::string> maybe_transition_type,
+ std::unique_ptr<NavigateCallback> callback) {
GURL gurl(url);
- if (!gurl.is_valid())
- return Response::Error("Cannot navigate to invalid URL");
+ if (!gurl.is_valid()) {
+ callback->sendFailure(Response::Error("Cannot navigate to invalid URL"));
+ return;
+ }
WebContentsImpl* web_contents = GetWebContents();
- if (!web_contents)
- return Response::InternalError();
+ if (!web_contents) {
+ callback->sendFailure(Response::InternalError());
+ return;
+ }
ui::PageTransition type;
std::string transition_type =
@@ -346,7 +354,40 @@ Response PageHandler::Navigate(const std::string& url,
gurl,
Referrer(GURL(referrer.fromMaybe("")), blink::kWebReferrerPolicyDefault),
type, std::string());
- return Response::FallThrough();
+ if (IsBrowserSideNavigationEnabled()) {
+ if (navigate_callback_) {
+ std::string frame_id =
+ web_contents->GetMainFrame()->GetDevToolsFrameToken().ToString();
+ std::string error_string = net::ErrorToString(net::ERR_ABORTED);
+ navigate_callback_->sendSuccess(frame_id, Maybe<std::string>(),
+ Maybe<std::string>(error_string));
+ }
+ navigate_callback_ = std::move(callback);
+ return;
+ }
+ callback->fallThrough();
+}
+
+void PageHandler::NavigationReset(NavigationRequest* navigation_request) {
+ if (!navigate_callback_)
+ return;
+ WebContentsImpl* web_contents = GetWebContents();
+ if (!web_contents) {
+ navigate_callback_->sendFailure(Response::InternalError());
+ return;
+ }
+
+ std::string frame_id =
+ web_contents->GetMainFrame()->GetDevToolsFrameToken().ToString();
+ bool success = navigation_request->net_error() != net::OK;
+ std::string error_string =
+ net::ErrorToString(navigation_request->net_error());
+ navigate_callback_->sendSuccess(
+ frame_id,
+ Maybe<std::string>(
+ navigation_request->devtools_navigation_token().ToString()),
+ success ? Maybe<std::string>(error_string) : Maybe<std::string>());
+ navigate_callback_.reset();
}
static const char* TransitionTypeName(ui::PageTransition type) {
@@ -439,7 +480,7 @@ void PageHandler::CaptureScreenshot(
widget_host->GetSnapshotFromBrowser(
base::Bind(&PageHandler::ScreenshotCaptured, weak_factory_.GetWeakPtr(),
base::Passed(std::move(callback)), screenshot_format,
- screenshot_quality, gfx::Size(),
+ screenshot_quality, gfx::Size(), gfx::Size(),
blink::WebDeviceEmulationParams()),
false);
return;
@@ -461,9 +502,9 @@ void PageHandler::CaptureScreenshot(
gfx::Size emulated_view_size = modified_params.view_size;
double dpfactor = 1;
+ ScreenInfo screen_info;
+ widget_host->GetScreenInfo(&screen_info);
if (emulation_enabled) {
- ScreenInfo screen_info;
- widget_host->GetScreenInfo(&screen_info);
// When emulating, emulate again and scale to make resulting image match
// physical DP resolution. If view_size is not overriden, use actual view
// size.
@@ -517,11 +558,26 @@ void PageHandler::CaptureScreenshot(
widget_host->GetView()->SetSize(
gfx::ScaleToFlooredSize(emulated_view_size, dpfactor));
}
+ gfx::Size requested_image_size = gfx::Size();
+ if (emulation_enabled || clip.isJust()) {
+ if (clip.isJust()) {
+ requested_image_size =
+ gfx::Size(clip.fromJust()->GetWidth(), clip.fromJust()->GetHeight());
+ } else {
+ requested_image_size = emulated_view_size;
+ }
+ double scale = emulation_enabled ? original_params.device_scale_factor
+ : screen_info.device_scale_factor;
+ if (clip.isJust())
+ scale *= clip.fromJust()->GetScale();
+ requested_image_size = gfx::ScaleToRoundedSize(requested_image_size, scale);
+ }
widget_host->GetSnapshotFromBrowser(
base::Bind(&PageHandler::ScreenshotCaptured, weak_factory_.GetWeakPtr(),
base::Passed(std::move(callback)), screenshot_format,
- screenshot_quality, original_view_size, original_params),
+ screenshot_quality, original_view_size, requested_image_size,
+ original_params),
true);
}
@@ -628,6 +684,7 @@ Response PageHandler::BringToFront() {
WebContentsImpl* wc = GetWebContents();
if (wc) {
wc->Activate();
+ wc->Focus();
return Response::OK();
}
return Response::InternalError();
@@ -703,8 +760,11 @@ void PageHandler::InnerSwapCompositorFrame() {
// http://crbug.com/73362
viz::CompositorFrameMetadata& metadata = last_compositor_frame_metadata_;
- gfx::SizeF viewport_size_dip = gfx::ScaleSize(
- metadata.scrollable_viewport_size, metadata.page_scale_factor);
+ float css_to_dip = metadata.page_scale_factor;
+ if (IsUseZoomForDSFEnabled())
+ css_to_dip /= metadata.device_scale_factor;
+ gfx::SizeF viewport_size_dip =
+ gfx::ScaleSize(metadata.scrollable_viewport_size, css_to_dip);
gfx::SizeF screen_size_dip =
gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()),
1 / metadata.device_scale_factor);
@@ -783,11 +843,17 @@ void PageHandler::ScreencastFrameEncoded(viz::CompositorFrameMetadata metadata,
gfx::SizeF screen_size_dip =
gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()),
1 / metadata.device_scale_factor);
+ float css_to_dip = metadata.page_scale_factor;
+ float top_offset_dip =
+ metadata.top_controls_height * metadata.top_controls_shown_ratio;
+ if (IsUseZoomForDSFEnabled()) {
+ css_to_dip /= metadata.device_scale_factor;
+ top_offset_dip /= metadata.device_scale_factor;
+ }
std::unique_ptr<Page::ScreencastFrameMetadata> param_metadata =
Page::ScreencastFrameMetadata::Create()
- .SetPageScaleFactor(metadata.page_scale_factor)
- .SetOffsetTop(metadata.top_controls_height *
- metadata.top_controls_shown_ratio)
+ .SetPageScaleFactor(css_to_dip)
+ .SetOffsetTop(top_offset_dip)
.SetDeviceWidth(screen_size_dip.width())
.SetDeviceHeight(screen_size_dip.height())
.SetScrollOffsetX(metadata.root_scroll_offset.x())
@@ -802,6 +868,7 @@ void PageHandler::ScreenshotCaptured(
const std::string& format,
int quality,
const gfx::Size& original_view_size,
+ const gfx::Size& requested_image_size,
const blink::WebDeviceEmulationParams& original_emulation_params,
const gfx::Image& image) {
if (original_view_size.width()) {
@@ -815,7 +882,18 @@ void PageHandler::ScreenshotCaptured(
return;
}
- callback->sendSuccess(EncodeImage(image, format, quality));
+ if (!requested_image_size.IsEmpty() &&
+ (image.Width() != requested_image_size.width() ||
+ image.Height() != requested_image_size.height())) {
+ const SkBitmap* bitmap = image.ToSkBitmap();
+ SkBitmap cropped = SkBitmapOperations::CreateTiledBitmap(
+ *bitmap, 0, 0, requested_image_size.width(),
+ requested_image_size.height());
+ gfx::Image croppedImage = gfx::Image::CreateFrom1xBitmap(cropped);
+ callback->sendSuccess(EncodeImage(croppedImage, format, quality));
+ } else {
+ callback->sendSuccess(EncodeImage(image, format, quality));
+ }
}
Response PageHandler::StopLoading() {
diff --git a/chromium/content/browser/devtools/protocol/page_handler.h b/chromium/content/browser/devtools/protocol/page_handler.h
index 854428933ad..4d3fcaf86c4 100644
--- a/chromium/content/browser/devtools/protocol/page_handler.h
+++ b/chromium/content/browser/devtools/protocol/page_handler.h
@@ -40,6 +40,7 @@ struct WebDeviceEmulationParams;
namespace content {
class DevToolsAgentHostImpl;
+class NavigationRequest;
class RenderFrameHostImpl;
class WebContentsImpl;
@@ -77,16 +78,17 @@ class PageHandler : public DevToolsDomainHandler,
void DidRunBeforeUnloadConfirm(const GURL& url,
JavaScriptDialogCallback callback);
void DidCloseJavaScriptDialog(bool success, const base::string16& user_input);
+ void NavigationReset(NavigationRequest* navigation_request);
Response Enable() override;
Response Disable() override;
Response Reload(Maybe<bool> bypassCache,
Maybe<std::string> script_to_evaluate_on_load) override;
- Response Navigate(const std::string& url,
- Maybe<std::string> referrer,
- Maybe<std::string> transition_type,
- Page::FrameId* frame_id) override;
+ void Navigate(const std::string& url,
+ Maybe<std::string> referrer,
+ Maybe<std::string> transition_type,
+ std::unique_ptr<NavigateCallback> callback) override;
Response StopLoading() override;
using NavigationEntries = protocol::Array<Page::NavigationEntry>;
@@ -150,6 +152,7 @@ class PageHandler : public DevToolsDomainHandler,
const std::string& format,
int quality,
const gfx::Size& original_view_size,
+ const gfx::Size& requested_image_size,
const blink::WebDeviceEmulationParams& original_params,
const gfx::Image& image);
@@ -180,6 +183,7 @@ class PageHandler : public DevToolsDomainHandler,
NotificationRegistrar registrar_;
JavaScriptDialogCallback pending_dialog_;
scoped_refptr<DevToolsDownloadManagerDelegate> download_manager_delegate_;
+ std::unique_ptr<NavigateCallback> navigate_callback_;
base::WeakPtrFactory<PageHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PageHandler);
diff --git a/chromium/content/browser/devtools/protocol/service_worker_handler.cc b/chromium/content/browser/devtools/protocol/service_worker_handler.cc
index a6588407512..d2478ae3147 100644
--- a/chromium/content/browser/devtools/protocol/service_worker_handler.cc
+++ b/chromium/content/browser/devtools/protocol/service_worker_handler.cc
@@ -5,13 +5,14 @@
#include "content/browser/devtools/protocol/service_worker_handler.h"
#include "base/bind.h"
+#include "base/containers/flat_set.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/containers/flat_set.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"
#include "content/browser/devtools/service_worker_devtools_manager.h"
+#include "content/browser/devtools/shared_worker_devtools_manager.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/service_worker/embedded_worker_status.h"
@@ -28,6 +29,8 @@
#include "content/public/browser/web_contents.h"
#include "content/public/common/push_event_payload.h"
#include "content/public/common/push_messaging_status.mojom.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "url/gurl.h"
namespace content {
@@ -282,7 +285,7 @@ Response ServiceWorkerHandler::InspectWorker(const std::string& version_id) {
if (!context_)
return CreateContextErrorResponse();
- int64_t id = kInvalidServiceWorkerVersionId;
+ int64_t id = blink::mojom::kInvalidServiceWorkerVersionId;
if (!base::StringToInt64(version_id, &id))
return CreateInvalidVersionIdErrorResponse();
BrowserThread::PostTask(
@@ -381,7 +384,8 @@ void ServiceWorkerHandler::OnWorkerVersionUpdated(
base::flat_set<std::string> client_set;
for (const auto& client : version.clients) {
- if (client.second.type == SERVICE_WORKER_PROVIDER_FOR_WINDOW) {
+ if (client.second.type ==
+ blink::mojom::ServiceWorkerProviderType::kForWindow) {
// PlzNavigate: a navigation may not yet be associated with a
// RenderFrameHost. Use the |web_contents_getter| instead.
WebContents* web_contents =
@@ -395,13 +399,6 @@ void ServiceWorkerHandler::OnWorkerVersionUpdated(
continue;
client_set.insert(
DevToolsAgentHost::GetOrCreateFor(web_contents)->GetId());
- } else if (client.second.type ==
- SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER) {
- scoped_refptr<DevToolsAgentHost> agent_host(
- DevToolsAgentHost::GetForWorker(client.second.process_id,
- client.second.route_id));
- if (agent_host)
- client_set.insert(agent_host->GetId());
}
}
std::unique_ptr<protocol::Array<std::string>> clients =
diff --git a/chromium/content/browser/devtools/protocol/storage_handler.cc b/chromium/content/browser/devtools/protocol/storage_handler.cc
index d81fed2d9f3..5d816d60f14 100644
--- a/chromium/content/browser/devtools/protocol/storage_handler.cc
+++ b/chromium/content/browser/devtools/protocol/storage_handler.cc
@@ -248,7 +248,7 @@ StorageHandler::~StorageHandler() {
}
void StorageHandler::Wire(UberDispatcher* dispatcher) {
- frontend_ = base::MakeUnique<Storage::Frontend>(dispatcher->channel());
+ frontend_ = std::make_unique<Storage::Frontend>(dispatcher->channel());
Storage::Dispatcher::wire(dispatcher, this);
}
@@ -306,11 +306,8 @@ Response StorageHandler::ClearDataForOrigin(
return Response::InvalidParams("No valid storage type specified");
partition->ClearDataForOrigin(
- remove_mask,
- StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL,
- GURL(origin),
- partition->GetURLRequestContext(),
- base::Bind(&base::DoNothing));
+ remove_mask, StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL,
+ GURL(origin), partition->GetURLRequestContext());
return Response::OK();
}
@@ -346,7 +343,7 @@ Response StorageHandler::TrackCacheStorageForOrigin(const std::string& origin) {
BrowserThread::IO, FROM_HERE,
base::BindOnce(&CacheStorageObserver::TrackOriginOnIOThread,
base::Unretained(GetCacheStorageObserver()),
- url::Origin(origin_url)));
+ url::Origin::Create(origin_url)));
return Response::OK();
}
@@ -363,7 +360,7 @@ Response StorageHandler::UntrackCacheStorageForOrigin(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&CacheStorageObserver::UntrackOriginOnIOThread,
base::Unretained(GetCacheStorageObserver()),
- url::Origin(origin_url)));
+ url::Origin::Create(origin_url)));
return Response::OK();
}
@@ -378,7 +375,7 @@ Response StorageHandler::TrackIndexedDBForOrigin(const std::string& origin) {
GetIndexedDBObserver()->TaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&IndexedDBObserver::TrackOriginOnIDBThread,
base::Unretained(GetIndexedDBObserver()),
- url::Origin(origin_url)));
+ url::Origin::Create(origin_url)));
return Response::OK();
}
@@ -393,7 +390,7 @@ Response StorageHandler::UntrackIndexedDBForOrigin(const std::string& origin) {
GetIndexedDBObserver()->TaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&IndexedDBObserver::UntrackOriginOnIDBThread,
base::Unretained(GetIndexedDBObserver()),
- url::Origin(origin_url)));
+ url::Origin::Create(origin_url)));
return Response::OK();
}
diff --git a/chromium/content/browser/devtools/protocol/target_auto_attacher.cc b/chromium/content/browser/devtools/protocol/target_auto_attacher.cc
index 3c045396132..114a5df6d62 100644
--- a/chromium/content/browser/devtools/protocol/target_auto_attacher.cc
+++ b/chromium/content/browser/devtools/protocol/target_auto_attacher.cc
@@ -9,7 +9,9 @@
#include "content/browser/devtools/service_worker_devtools_agent_host.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/public/common/browser_side_navigation_policy.h"
namespace content {
namespace protocol {
@@ -138,6 +140,30 @@ void TargetAutoAttacher::AgentHostClosed(DevToolsAgentHost* host) {
auto_attached_hosts_.erase(base::WrapRefCounted(host));
}
+bool TargetAutoAttacher::ShouldThrottleFramesNavigation() {
+ return IsBrowserSideNavigationEnabled() && auto_attach_ &&
+ attach_to_frames_ && wait_for_debugger_on_start_;
+}
+
+DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame(
+ NavigationHandle* navigation_handle) {
+ if (!ShouldThrottleFramesNavigation())
+ return nullptr;
+ if (!navigation_handle->GetRenderFrameHost() ||
+ !navigation_handle->GetRenderFrameHost()->IsCrossProcessSubframe()) {
+ return nullptr;
+ }
+ scoped_refptr<DevToolsAgentHost> agent_host =
+ RenderFrameDevToolsAgentHost::GetOrCreateForDangling(
+ static_cast<NavigationHandleImpl*>(navigation_handle)
+ ->frame_tree_node());
+ if (auto_attached_hosts_.find(agent_host) != auto_attached_hosts_.end())
+ return nullptr;
+ attach_callback_.Run(agent_host.get(), true /* waiting_for_debugger */);
+ auto_attached_hosts_.insert(agent_host);
+ return agent_host.get();
+}
+
void TargetAutoAttacher::ReattachServiceWorkers(bool waiting_for_debugger) {
if (!auto_attach_)
return;
diff --git a/chromium/content/browser/devtools/protocol/target_auto_attacher.h b/chromium/content/browser/devtools/protocol/target_auto_attacher.h
index 87dbbce6199..c0b00481293 100644
--- a/chromium/content/browser/devtools/protocol/target_auto_attacher.h
+++ b/chromium/content/browser/devtools/protocol/target_auto_attacher.h
@@ -11,6 +11,7 @@
namespace content {
+class NavigationHandle;
class RenderFrameHostImpl;
namespace protocol {
@@ -33,6 +34,9 @@ class TargetAutoAttacher : public ServiceWorkerDevToolsManager::Observer {
void UpdateFrames();
void AgentHostClosed(DevToolsAgentHost* host);
+ bool ShouldThrottleFramesNavigation();
+ DevToolsAgentHost* AutoAttachToFrame(NavigationHandle* navigation_handle);
+
private:
using Hosts = base::flat_set<scoped_refptr<DevToolsAgentHost>>;
diff --git a/chromium/content/browser/devtools/protocol/target_handler.cc b/chromium/content/browser/devtools/protocol/target_handler.cc
index 48b47db4642..a4d405f837b 100644
--- a/chromium/content/browser/devtools/protocol/target_handler.cc
+++ b/chromium/content/browser/devtools/protocol/target_handler.cc
@@ -4,16 +4,22 @@
#include "content/browser/devtools/protocol/target_handler.h"
+#include "base/json/json_reader.h"
#include "base/strings/stringprintf.h"
+#include "base/values.h"
#include "content/browser/devtools/devtools_manager.h"
#include "content/browser/devtools/devtools_session.h"
#include "content/public/browser/devtools_agent_host_client.h"
+#include "content/public/browser/navigation_throttle.h"
namespace content {
namespace protocol {
namespace {
+static const char kMethod[] = "method";
+static const char kResumeMethod[] = "Runtime.runIfWaitingForDebugger";
+
std::unique_ptr<Target::TargetInfo> CreateInfo(DevToolsAgentHost* host) {
std::unique_ptr<Target::TargetInfo> target_info =
Target::TargetInfo::Create()
@@ -30,6 +36,26 @@ std::unique_ptr<Target::TargetInfo> CreateInfo(DevToolsAgentHost* host) {
} // namespace
+// Throttle is owned externally by the navigation subsystem.
+class TargetHandler::Throttle : public content::NavigationThrottle {
+ public:
+ Throttle(base::WeakPtr<protocol::TargetHandler> target_handler,
+ content::NavigationHandle* navigation_handle);
+ ~Throttle() override;
+ void Clear();
+ // content::NavigationThrottle implementation:
+ NavigationThrottle::ThrottleCheckResult WillProcessResponse() override;
+ const char* GetNameForLogging() override;
+
+ private:
+ void CleanupPointers();
+
+ base::WeakPtr<protocol::TargetHandler> target_handler_;
+ scoped_refptr<DevToolsAgentHost> agent_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(Throttle);
+};
+
class TargetHandler::Session : public DevToolsAgentHostClient {
public:
static std::string Attach(TargetHandler* handler,
@@ -61,7 +87,21 @@ class TargetHandler::Session : public DevToolsAgentHostClient {
handler_->attached_sessions_.erase(id_);
}
+ void SetThrottle(Throttle* throttle) { throttle_ = throttle; }
+
void SendMessageToAgentHost(const std::string& message) {
+ if (throttle_) {
+ bool resuming = false;
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(message);
+ if (value && value->is_dict()) {
+ base::Value* method = value->FindKey(kMethod);
+ resuming = method && method->is_string() &&
+ method->GetString() == kResumeMethod;
+ }
+ if (resuming)
+ throttle_->Clear();
+ }
+
agent_host_->DispatchProtocolMessage(this, message);
}
@@ -83,8 +123,7 @@ class TargetHandler::Session : public DevToolsAgentHostClient {
agent_host_->GetId());
}
- void AgentHostClosed(DevToolsAgentHost* agent_host,
- bool replaced_with_another_client) override {
+ void AgentHostClosed(DevToolsAgentHost* agent_host) override {
DCHECK(agent_host == agent_host_.get());
Detach(true);
}
@@ -92,16 +131,67 @@ class TargetHandler::Session : public DevToolsAgentHostClient {
TargetHandler* handler_;
scoped_refptr<DevToolsAgentHost> agent_host_;
std::string id_;
+ Throttle* throttle_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(Session);
};
+TargetHandler::Throttle::Throttle(
+ base::WeakPtr<protocol::TargetHandler> target_handler,
+ content::NavigationHandle* navigation_handle)
+ : content::NavigationThrottle(navigation_handle),
+ target_handler_(target_handler) {
+ target_handler->throttles_.insert(this);
+}
+
+TargetHandler::Throttle::~Throttle() {
+ CleanupPointers();
+}
+
+void TargetHandler::Throttle::CleanupPointers() {
+ if (target_handler_ && agent_host_) {
+ auto it = target_handler_->auto_attached_sessions_.find(agent_host_.get());
+ if (it != target_handler_->auto_attached_sessions_.end())
+ it->second->SetThrottle(nullptr);
+ }
+ if (target_handler_) {
+ target_handler_->throttles_.erase(this);
+ target_handler_ = nullptr;
+ }
+}
+
+NavigationThrottle::ThrottleCheckResult
+TargetHandler::Throttle::WillProcessResponse() {
+ if (!target_handler_)
+ return PROCEED;
+ agent_host_ =
+ target_handler_->auto_attacher_.AutoAttachToFrame(navigation_handle());
+ if (!agent_host_.get())
+ return PROCEED;
+ target_handler_->auto_attached_sessions_[agent_host_.get()]->SetThrottle(
+ this);
+ return DEFER;
+}
+
+const char* TargetHandler::Throttle::GetNameForLogging() {
+ return "DevToolsTargetNavigationThrottle";
+}
+
+void TargetHandler::Throttle::Clear() {
+ CleanupPointers();
+ if (agent_host_) {
+ agent_host_ = nullptr;
+ Resume();
+ }
+}
+
TargetHandler::TargetHandler()
: DevToolsDomainHandler(Target::Metainfo::domainName),
auto_attacher_(
base::Bind(&TargetHandler::AutoAttach, base::Unretained(this)),
base::Bind(&TargetHandler::AutoDetach, base::Unretained(this))),
- discover_(false) {}
+ discover_(false),
+ weak_factory_(this) {}
TargetHandler::~TargetHandler() {
}
@@ -139,6 +229,21 @@ void TargetHandler::RenderFrameHostChanged() {
auto_attacher_.UpdateFrames();
}
+std::unique_ptr<NavigationThrottle> TargetHandler::CreateThrottleForNavigation(
+ NavigationHandle* navigation_handle) {
+ if (!auto_attacher_.ShouldThrottleFramesNavigation())
+ return nullptr;
+ return std::make_unique<Throttle>(weak_factory_.GetWeakPtr(),
+ navigation_handle);
+}
+
+void TargetHandler::ClearThrottles() {
+ base::flat_set<Throttle*> copy(throttles_);
+ for (Throttle* throttle : copy)
+ throttle->Clear();
+ throttles_.clear();
+}
+
void TargetHandler::AutoAttach(DevToolsAgentHost* host,
bool waiting_for_debugger) {
std::string session_id = Session::Attach(this, host, waiting_for_debugger);
@@ -205,11 +310,15 @@ Response TargetHandler::SetDiscoverTargets(bool discover) {
Response TargetHandler::SetAutoAttach(
bool auto_attach, bool wait_for_debugger_on_start) {
auto_attacher_.SetAutoAttach(auto_attach, wait_for_debugger_on_start);
+ if (!auto_attacher_.ShouldThrottleFramesNavigation())
+ ClearThrottles();
return Response::FallThrough();
}
Response TargetHandler::SetAttachToFrames(bool value) {
auto_attacher_.SetAttachToFrames(value);
+ if (!auto_attacher_.ShouldThrottleFramesNavigation())
+ ClearThrottles();
return Response::OK();
}
diff --git a/chromium/content/browser/devtools/protocol/target_handler.h b/chromium/content/browser/devtools/protocol/target_handler.h
index f25ff625550..d9d4a8955aa 100644
--- a/chromium/content/browser/devtools/protocol/target_handler.h
+++ b/chromium/content/browser/devtools/protocol/target_handler.h
@@ -8,6 +8,8 @@
#include <map>
#include <set>
+#include "base/containers/flat_set.h"
+#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/protocol/devtools_domain_handler.h"
#include "content/browser/devtools/protocol/target.h"
#include "content/browser/devtools/protocol/target_auto_attacher.h"
@@ -16,6 +18,8 @@
namespace content {
class DevToolsAgentHostImpl;
+class NavigationHandle;
+class NavigationThrottle;
class RenderFrameHostImpl;
namespace protocol {
@@ -36,6 +40,8 @@ class TargetHandler : public DevToolsDomainHandler,
void DidCommitNavigation();
void RenderFrameHostChanged();
+ std::unique_ptr<NavigationThrottle> CreateThrottleForNavigation(
+ NavigationHandle* navigation_handle);
// Domain implementation.
Response SetDiscoverTargets(bool discover) override;
@@ -72,6 +78,7 @@ class TargetHandler : public DevToolsDomainHandler,
private:
class Session;
+ class Throttle;
void AutoAttach(DevToolsAgentHost* host, bool waiting_for_debugger);
void AutoDetach(DevToolsAgentHost* host);
@@ -79,6 +86,7 @@ class TargetHandler : public DevToolsDomainHandler,
Maybe<std::string> target_id,
Session** session,
bool fall_through);
+ void ClearThrottles();
// DevToolsAgentHostObserver implementation.
bool ShouldForceDevToolsAgentHostCreation() override;
@@ -95,6 +103,8 @@ class TargetHandler : public DevToolsDomainHandler,
std::map<DevToolsAgentHost*, Session*> auto_attached_sessions_;
std::set<DevToolsAgentHost*> reported_hosts_;
int last_session_id_ = 0;
+ base::flat_set<Throttle*> throttles_;
+ base::WeakPtrFactory<TargetHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(TargetHandler);
};
diff --git a/chromium/content/browser/devtools/protocol/tethering_handler.cc b/chromium/content/browser/devtools/protocol/tethering_handler.cc
index 36a9d39091d..44f21028563 100644
--- a/chromium/content/browser/devtools/protocol/tethering_handler.cc
+++ b/chromium/content/browser/devtools/protocol/tethering_handler.cc
@@ -25,10 +25,10 @@ using UnbindCallback = Tethering::Backend::UnbindCallback;
namespace {
const int kListenBacklog = 5;
-const int kBufferSize = 16 * 1024;
+const int kSocketPumpBufferSize = 16 * 1024;
const int kMinTetheringPort = 1024;
-const int kMaxTetheringPort = 32767;
+const int kMaxTetheringPort = 65535;
using CreateServerSocketCallback =
base::Callback<std::unique_ptr<net::ServerSocket>(std::string*)>;
@@ -75,12 +75,12 @@ class SocketPump {
}
void Pump(net::StreamSocket* from, net::StreamSocket* to) {
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize);
- int result = from->Read(
- buffer.get(),
- kBufferSize,
- base::Bind(
- &SocketPump::OnRead, base::Unretained(this), from, to, buffer));
+ scoped_refptr<net::IOBuffer> buffer =
+ new net::IOBuffer(kSocketPumpBufferSize);
+ int result =
+ from->Read(buffer.get(), kSocketPumpBufferSize,
+ base::Bind(&SocketPump::OnRead, base::Unretained(this), from,
+ to, buffer));
if (result != net::ERR_IO_PENDING)
OnRead(from, to, buffer, result);
}
@@ -167,9 +167,8 @@ class BoundSocket {
const CreateServerSocketCallback& socket_callback)
: accepted_callback_(accepted_callback),
socket_callback_(socket_callback),
- socket_(new net::TCPServerSocket(NULL, net::NetLogSource())),
- port_(0) {
- }
+ socket_(new net::TCPServerSocket(nullptr, net::NetLogSource())),
+ port_(0) {}
virtual ~BoundSocket() {
}
@@ -272,7 +271,7 @@ void TetheringHandler::TetheringImpl::Bind(
BoundSocket::AcceptedCallback accepted = base::Bind(
&TetheringHandler::TetheringImpl::Accepted, base::Unretained(this));
std::unique_ptr<BoundSocket> bound_socket =
- base::MakeUnique<BoundSocket>(accepted, socket_callback_);
+ std::make_unique<BoundSocket>(accepted, socket_callback_);
if (!bound_socket->Listen(port)) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
diff --git a/chromium/content/browser/devtools/protocol/tracing_handler.cc b/chromium/content/browser/devtools/protocol/tracing_handler.cc
index 9820ee6168a..b1a10b896a7 100644
--- a/chromium/content/browser/devtools/protocol/tracing_handler.cc
+++ b/chromium/content/browser/devtools/protocol/tracing_handler.cc
@@ -179,7 +179,7 @@ void TracingHandler::OnTraceDataCollected(
void TracingHandler::OnTraceComplete() {
if (!trace_data_buffer_state_.data.empty())
- OnTraceDataCollected(base::MakeUnique<std::string>(""));
+ OnTraceDataCollected(std::make_unique<std::string>(""));
DCHECK(trace_data_buffer_state_.data.empty());
DCHECK_EQ(0u, trace_data_buffer_state_.pos);
diff --git a/chromium/content/browser/devtools/protocol_config.json b/chromium/content/browser/devtools/protocol_config.json
index 0c8220c133a..480a81f0493 100644
--- a/chromium/content/browser/devtools/protocol_config.json
+++ b/chromium/content/browser/devtools/protocol_config.json
@@ -16,8 +16,7 @@
{
"domain": "DOM",
"include": ["setFileInputFiles"],
- "include_events": [],
- "include_types": ["NodeId", "BackendNodeId", "RGBA"]
+ "include_events": []
},
{
"domain": "Emulation",
@@ -41,11 +40,9 @@
},
{
"domain": "Network",
- "include": ["enable", "disable", "clearBrowserCache", "clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookies", "setCookie", "setCookies", "setUserAgentOverride", "canEmulateNetworkConditions", "emulateNetworkConditions", "setRequestInterceptionEnabled", "continueInterceptedRequest"],
- "include_types": ["CookieSameSite", "Cookie", "CookieParam", "Response", "Headers", "Request", "ResourceTiming", "SecurityDetails", "SignedCertificateTimestamp", "Initiator", "ResourcePriority", "RequestWillBeSentNotification", "ResponseReceivedNotification", "LoadingFinishedNotification", "LoadingFailedNotification", "RequestWillBeSentNotification",
- "ErrorReason", "RequestInterceptedNotification", "AuthChallenge", "AuthChallengeResponse", "ConnectionType"],
+ "include": ["enable", "disable", "clearBrowserCache", "clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookies", "setCookie", "setCookies", "setUserAgentOverride", "setExtraHTTPHeaders", "canEmulateNetworkConditions", "emulateNetworkConditions", "setBypassServiceWorker", "setRequestInterception", "continueInterceptedRequest", "getResponseBodyForInterception"],
"include_events": ["requestWillBeSent", "responseReceived", "loadingFinished", "loadingFailed", "requestIntercepted"],
- "async": ["clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookies", "setCookie", "setCookies", "continueInterceptedRequest"]
+ "async": ["clearBrowserCookies", "clearBrowserCache", "getCookies", "getAllCookies", "deleteCookies", "setCookie", "setCookies", "continueInterceptedRequest", "getResponseBodyForInterception"]
},
{
"domain": "Page",
@@ -53,11 +50,10 @@
"startScreencast", "stopScreencast", "screencastFrameAck", "handleJavaScriptDialog", "setColorPickerEnabled", "requestAppBanner",
"printToPDF", "bringToFront", "setDownloadBehavior"],
"include_events": ["colorPicked", "interstitialShown", "interstitialHidden", "javascriptDialogOpening", "javascriptDialogClosed", "screencastVisibilityChanged", "screencastFrame"],
- "async": ["captureScreenshot", "printToPDF"]
+ "async": ["captureScreenshot", "printToPDF", "navigate"]
},
{
"domain": "Runtime",
- "include_types": ["StackTrace", "CallFrame"],
"include_events": [],
"include": []
},
diff --git a/chromium/content/browser/devtools/protocol_string.cc b/chromium/content/browser/devtools/protocol_string.cc
index 891e59c6795..327d97e1c18 100644
--- a/chromium/content/browser/devtools/protocol_string.cc
+++ b/chromium/content/browser/devtools/protocol_string.cc
@@ -76,7 +76,7 @@ std::unique_ptr<base::Value> toBaseValue(
if (!value || !depth)
return nullptr;
if (value->type() == protocol::Value::TypeNull)
- return base::MakeUnique<base::Value>();
+ return std::make_unique<base::Value>();
if (value->type() == protocol::Value::TypeBoolean) {
bool inner;
value->asBoolean(&inner);
diff --git a/chromium/content/browser/devtools/protocol_string.h b/chromium/content/browser/devtools/protocol_string.h
index 71f4e2a4c01..75d7b796969 100644
--- a/chromium/content/browser/devtools/protocol_string.h
+++ b/chromium/content/browser/devtools/protocol_string.h
@@ -47,7 +47,7 @@ class CONTENT_EXPORT StringUtil {
return base::IntToString(number);
}
static String fromDouble(double number) {
- String s = base::DoubleToString(number);
+ String s = base::NumberToString(number);
if (!s.empty() && s[0] == '.')
s = "0" + s;
return s;
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 bf365f89153..7a4960991b8 100644
--- a/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -33,6 +33,7 @@
#include "content/browser/devtools/protocol/target_handler.h"
#include "content/browser/devtools/protocol/tracing_handler.h"
#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/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -47,6 +48,8 @@
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_features.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
#if defined(OS_ANDROID)
#include "content/public/browser/render_widget_host_view.h"
@@ -55,20 +58,22 @@
namespace content {
-typedef std::vector<RenderFrameDevToolsAgentHost*> Instances;
+typedef std::vector<RenderFrameDevToolsAgentHost*> RenderFrameDevToolsArray;
namespace {
-base::LazyInstance<Instances>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<RenderFrameDevToolsArray>::Leaky g_agent_host_instances =
+ LAZY_INSTANCE_INITIALIZER;
RenderFrameDevToolsAgentHost* FindAgentHost(FrameTreeNode* frame_tree_node) {
- if (g_instances == NULL)
- return NULL;
- for (Instances::iterator it = g_instances.Get().begin();
- it != g_instances.Get().end(); ++it) {
+ if (g_agent_host_instances == nullptr)
+ return nullptr;
+ for (RenderFrameDevToolsArray::iterator it =
+ g_agent_host_instances.Get().begin();
+ it != g_agent_host_instances.Get().end(); ++it) {
if ((*it)->frame_tree_node() == frame_tree_node)
return *it;
}
- return NULL;
+ return nullptr;
}
bool ShouldCreateDevToolsForHost(RenderFrameHost* rfh) {
@@ -76,7 +81,7 @@ bool ShouldCreateDevToolsForHost(RenderFrameHost* rfh) {
}
bool ShouldCreateDevToolsForNode(FrameTreeNode* ftn) {
- return ShouldCreateDevToolsForHost(ftn->current_frame_host());
+ return !ftn->parent() || ftn->current_frame_host()->IsCrossProcessSubframe();
}
FrameTreeNode* GetFrameTreeNodeAncestor(FrameTreeNode* frame_tree_node) {
@@ -86,8 +91,6 @@ FrameTreeNode* GetFrameTreeNodeAncestor(FrameTreeNode* frame_tree_node) {
return frame_tree_node;
}
-const char* kPageNavigateCommand = "Page.navigate";
-
} // namespace
// RenderFrameDevToolsAgentHost::FrameHostHolder -------------------------------
@@ -108,7 +111,6 @@ class RenderFrameDevToolsAgentHost::FrameHostHolder {
const std::string& method,
const std::string& message);
void InspectElement(int session_id, int x, int y);
- bool ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk);
void Suspend();
void Resume();
std::string StateCookie(int session_id) const;
@@ -119,42 +121,153 @@ class RenderFrameDevToolsAgentHost::FrameHostHolder {
std::string method;
std::string message;
};
- struct SessionInfo {
- std::unique_ptr<DevToolsMessageChunkProcessor> chunk_processor;
- std::vector<std::string> pending_messages;
+
+ class SessionHost : public mojom::DevToolsSessionHost {
+ public:
+ SessionHost(FrameHostHolder* owner,
+ int session_id,
+ const base::Optional<std::string>& reattach_state)
+ : owner_(owner),
+ session_id_(session_id),
+ binding_(this),
+ chunk_processor_(
+ base::Callback<void(int, const std::string&)>(),
+ base::Bind(&RenderFrameDevToolsAgentHost::FrameHostHolder::
+ SessionHost::SendMessageFromProcessor,
+ base::Unretained(this))) {
+ if (reattach_state.has_value())
+ chunk_processor_.set_state_cookie(reattach_state.value());
+ mojom::DevToolsSessionHostAssociatedPtrInfo host_ptr_info;
+ binding_.Bind(mojo::MakeRequest(&host_ptr_info));
+ owner_->agent_ptr_->AttachDevToolsSession(
+ std::move(host_ptr_info), mojo::MakeRequest(&session_ptr_),
+ mojo::MakeRequest(&io_session_ptr_), reattach_state);
+ }
+
+ void RedispatchProtocolMessagesFrom(SessionHost* other) {
+ for (const auto& pair : other->sent_messages_) {
+ DispatchProtocolMessage(pair.first, pair.second.method,
+ pair.second.message);
+ }
+ }
+
+ const std::string& state_cookie() const {
+ return chunk_processor_.state_cookie();
+ }
+
+ void DispatchProtocolMessage(int call_id,
+ const std::string& method,
+ const std::string& message) {
+ if (DevToolsSession::ShouldSendOnIO(method))
+ io_session_ptr_->DispatchProtocolMessage(call_id, method, message);
+ else
+ session_ptr_->DispatchProtocolMessage(call_id, method, message);
+ sent_messages_[call_id] = {method, message};
+ }
+
+ void InspectElement(int x, int y) {
+ session_ptr_->InspectElement(gfx::Point(x, y));
+ }
+
+ // mojom::DevToolsSessionHost implementation.
+ void DispatchProtocolMessage(
+ mojom::DevToolsMessageChunkPtr chunk) override {
+ if (chunk_processor_.ProcessChunkedMessageFromAgent(std::move(chunk)))
+ return;
+
+ binding_.Close();
+ if (owner_->host_->GetProcess()) {
+ bad_message::ReceivedBadMessage(
+ owner_->host_->GetProcess(),
+ bad_message::RFH_INCONSISTENT_DEVTOOLS_MESSAGE);
+ }
+ }
+
+ void RequestNewWindow(int32_t frame_routing_id,
+ RequestNewWindowCallback callback) override {
+ bool success = false;
+ RenderFrameHostImpl* frame_host =
+ owner_->host_->GetProcess()
+ ? RenderFrameHostImpl::FromID(
+ owner_->host_->GetProcess()->GetID(), frame_routing_id)
+ : nullptr;
+ if (frame_host) {
+ scoped_refptr<DevToolsAgentHost> agent =
+ RenderFrameDevToolsAgentHost::GetOrCreateFor(
+ frame_host->frame_tree_node());
+ success = static_cast<DevToolsAgentHostImpl*>(agent.get())->Inspect();
+ }
+ std::move(callback).Run(success);
+ }
+
+ void SendMessageFromProcessor(const std::string& message) {
+ int id = chunk_processor_.last_call_id();
+ Message sent_message = std::move(sent_messages_[id]);
+ sent_messages_.erase(id);
+ if (suspended_) {
+ pending_messages_.push_back(message);
+ } else {
+ DevToolsSession* session = owner_->agent_->SessionById(session_id_);
+ if (session)
+ session->SendMessageToClient(message);
+ // |this| may be deleted at this point.
+ }
+ }
+
+ void Suspend() { suspended_ = true; }
+
+ void Resume() {
+ suspended_ = false;
+ DevToolsSession* session = owner_->agent_->SessionById(session_id_);
+ std::vector<std::string> messages;
+ messages.swap(pending_messages_);
+ for (std::string& message : messages)
+ session->SendMessageToClient(message);
+ }
+
+ private:
+ FrameHostHolder* owner_;
+ int session_id_;
+ mojo::AssociatedBinding<mojom::DevToolsSessionHost> binding_;
+ mojom::DevToolsSessionAssociatedPtr session_ptr_;
+ mojom::DevToolsSessionPtr io_session_ptr_;
+ DevToolsMessageChunkProcessor chunk_processor_;
+ std::vector<std::string> pending_messages_;
using CallId = int;
- std::map<CallId, Message> sent_messages;
- };
+ std::map<CallId, Message> sent_messages_;
+ bool suspended_ = false;
- void SendChunkedMessage(int session_id, const std::string& message);
- SessionInfo& InitInfo(int session_id);
+ DISALLOW_COPY_AND_ASSIGN(SessionHost);
+ };
RenderFrameDevToolsAgentHost* agent_;
RenderFrameHostImpl* host_;
- bool suspended_;
- base::flat_map<int, SessionInfo> infos_;
+ mojom::DevToolsAgentAssociatedPtr agent_ptr_;
+ base::flat_map<int, std::unique_ptr<SessionHost>> session_hosts_;
};
RenderFrameDevToolsAgentHost::FrameHostHolder::FrameHostHolder(
RenderFrameDevToolsAgentHost* agent,
RenderFrameHostImpl* host)
- : agent_(agent), host_(host), suspended_(false) {
+ : agent_(agent), host_(host) {
DCHECK(!IsBrowserSideNavigationEnabled());
DCHECK(agent_);
DCHECK(host_);
}
RenderFrameDevToolsAgentHost::FrameHostHolder::~FrameHostHolder() {
- if (!infos_.empty())
+ if (!session_hosts_.empty())
agent_->RevokePolicy(host_);
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::Attach(
DevToolsSession* session) {
- host_->Send(new DevToolsAgentMsg_Attach(
- host_->GetRoutingID(), agent_->GetId(), session->session_id()));
agent_->GrantPolicy(host_);
- InitInfo(session->session_id());
+ // |agent_ptr_| is used by SessionHost in constructor to attach.
+ if (!agent_ptr_)
+ host_->GetRemoteAssociatedInterfaces()->GetInterface(&agent_ptr_);
+ session_hosts_[session->session_id()].reset(
+ new SessionHost(this, session->session_id(), base::nullopt));
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::Reattach(
@@ -165,37 +278,35 @@ void RenderFrameDevToolsAgentHost::FrameHostHolder::Reattach(
ReattachWithCookie(session, std::move(cookie));
if (!old)
continue;
- auto it = old->infos_.find(session_id);
- if (it == old->infos_.end())
- continue;
- for (const auto& pair : it->second.sent_messages) {
- DispatchProtocolMessage(session_id, pair.first, pair.second.method,
- pair.second.message);
+ auto it = old->session_hosts_.find(session_id);
+ if (it != old->session_hosts_.end()) {
+ session_hosts_[session_id]->RedispatchProtocolMessagesFrom(
+ it->second.get());
}
}
}
std::string RenderFrameDevToolsAgentHost::FrameHostHolder::StateCookie(
int session_id) const {
- auto it = infos_.find(session_id);
- if (it == infos_.end())
- return std::string();
- return it->second.chunk_processor->state_cookie();
+ auto it = session_hosts_.find(session_id);
+ return it == session_hosts_.end() ? std::string()
+ : it->second->state_cookie();
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::ReattachWithCookie(
DevToolsSession* session,
std::string cookie) {
- InitInfo(session->session_id()).chunk_processor->set_state_cookie(cookie);
- host_->Send(new DevToolsAgentMsg_Reattach(
- host_->GetRoutingID(), agent_->GetId(), session->session_id(), cookie));
agent_->GrantPolicy(host_);
+ // |agent_ptr_| is used by SessionHost in constructor to attach.
+ if (!agent_ptr_)
+ host_->GetRemoteAssociatedInterfaces()->GetInterface(&agent_ptr_);
+ session_hosts_[session->session_id()].reset(
+ new SessionHost(this, session->session_id(), cookie));
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::Detach(int session_id) {
- host_->Send(new DevToolsAgentMsg_Detach(host_->GetRoutingID(), session_id));
agent_->RevokePolicy(host_);
- infos_.erase(session_id);
+ session_hosts_.erase(session_id);
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::DispatchProtocolMessage(
@@ -203,70 +314,26 @@ void RenderFrameDevToolsAgentHost::FrameHostHolder::DispatchProtocolMessage(
int call_id,
const std::string& method,
const std::string& message) {
- host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
- host_->GetRoutingID(), session_id, call_id, method, message));
- infos_[session_id].sent_messages[call_id] = {method, message};
+ auto it = session_hosts_.find(session_id);
+ if (it != session_hosts_.end())
+ it->second->DispatchProtocolMessage(call_id, method, message);
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::InspectElement(
int session_id, int x, int y) {
- host_->Send(new DevToolsAgentMsg_InspectElement(
- host_->GetRoutingID(), session_id, x, y));
-}
-
-bool
-RenderFrameDevToolsAgentHost::FrameHostHolder::ProcessChunkedMessageFromAgent(
- const DevToolsMessageChunk& chunk) {
- auto it = infos_.find(chunk.session_id);
- if (it != infos_.end())
- return it->second.chunk_processor->ProcessChunkedMessageFromAgent(chunk);
- return true;
-}
-
-void RenderFrameDevToolsAgentHost::FrameHostHolder::SendChunkedMessage(
- int session_id,
- const std::string& message) {
- auto it = infos_.find(session_id);
- if (it == infos_.end())
- return;
- SessionInfo& info = it->second;
- int id = info.chunk_processor->last_call_id();
- Message sent_message = std::move(info.sent_messages[id]);
- info.sent_messages.erase(id);
- if (suspended_) {
- info.pending_messages.push_back(message);
- } else {
- DevToolsSession* session = agent_->SessionById(session_id);
- if (session)
- session->SendMessageToClient(message);
- // |this| may be deleted at this point.
- }
+ auto it = session_hosts_.find(session_id);
+ if (it != session_hosts_.end())
+ it->second->InspectElement(x, y);
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::Suspend() {
- suspended_ = true;
+ for (auto& pair : session_hosts_)
+ pair.second->Suspend();
}
void RenderFrameDevToolsAgentHost::FrameHostHolder::Resume() {
- suspended_ = false;
- for (DevToolsSession* session : agent_->sessions()) {
- auto it = infos_.find(session->session_id());
- if (it == infos_.end())
- return;
- SessionInfo& info = it->second;
- std::vector<std::string> messages = std::move(info.pending_messages);
- for (std::string& message : messages)
- session->SendMessageToClient(message);
- }
-}
-
-RenderFrameDevToolsAgentHost::FrameHostHolder::SessionInfo&
-RenderFrameDevToolsAgentHost::FrameHostHolder::InitInfo(int session_id) {
- SessionInfo& info = infos_[session_id];
- info.chunk_processor.reset(new DevToolsMessageChunkProcessor(base::Bind(
- &RenderFrameDevToolsAgentHost::FrameHostHolder::SendChunkedMessage,
- base::Unretained(this))));
- return info;
+ for (auto& pair : session_hosts_)
+ pair.second->Resume();
}
// RenderFrameDevToolsAgentHost ------------------------------------------------
@@ -294,6 +361,21 @@ scoped_refptr<DevToolsAgentHost> RenderFrameDevToolsAgentHost::GetOrCreateFor(
}
// static
+scoped_refptr<DevToolsAgentHost>
+RenderFrameDevToolsAgentHost::GetOrCreateForDangling(
+ FrameTreeNode* frame_tree_node) {
+ // Note that this method does not use FrameTreeNode::current_frame_host(),
+ // since it is used while the frame host may not be set as current yet,
+ // for example right before commit time.
+ // So the caller must be sure that passed frame will indeed be a correct
+ // devtools target (see ShouldCreateDevToolsForNode above).
+ RenderFrameDevToolsAgentHost* result = FindAgentHost(frame_tree_node);
+ if (!result)
+ result = new RenderFrameDevToolsAgentHost(frame_tree_node);
+ return result;
+}
+
+// static
bool DevToolsAgentHost::HasFor(WebContents* web_contents) {
FrameTreeNode* node =
static_cast<WebContentsImpl*>(web_contents)->GetFrameTree()->root();
@@ -350,41 +432,58 @@ void RenderFrameDevToolsAgentHost::OnBeforeNavigation(
}
// static
-void RenderFrameDevToolsAgentHost::OnFailedNavigation(
- RenderFrameHost* host,
- const CommonNavigationParams& common_params,
- const BeginNavigationParams& begin_params,
- net::Error error_code) {
+void RenderFrameDevToolsAgentHost::OnResetNavigationRequest(
+ NavigationRequest* navigation_request) {
RenderFrameDevToolsAgentHost* agent_host =
- FindAgentHost(static_cast<RenderFrameHostImpl*>(host)->frame_tree_node());
+ FindAgentHost(navigation_request->frame_tree_node());
if (!agent_host)
return;
- for (auto* network : protocol::NetworkHandler::ForAgentHost(agent_host))
- network->NavigationFailed(common_params, begin_params, error_code);
+ if (navigation_request->net_error() != net::OK) {
+ for (auto* network : protocol::NetworkHandler::ForAgentHost(agent_host))
+ network->NavigationFailed(navigation_request);
+ }
+ for (auto* page : protocol::PageHandler::ForAgentHost(agent_host))
+ page->NavigationReset(navigation_request);
}
// static
-std::unique_ptr<NavigationThrottle>
-RenderFrameDevToolsAgentHost::CreateThrottleForNavigation(
+std::vector<std::unique_ptr<NavigationThrottle>>
+RenderFrameDevToolsAgentHost::CreateNavigationThrottles(
NavigationHandle* navigation_handle) {
+ std::vector<std::unique_ptr<NavigationThrottle>> result;
FrameTreeNode* frame_tree_node =
static_cast<NavigationHandleImpl*>(navigation_handle)->frame_tree_node();
- while (frame_tree_node && frame_tree_node->parent()) {
- frame_tree_node = frame_tree_node->parent();
- }
+
+ // Interception might throttle navigations in inspected frames.
RenderFrameDevToolsAgentHost* agent_host = FindAgentHost(frame_tree_node);
- // Note Network.setRequestInterceptionEnabled is intended to control
- // navigations in the main frame and all child frames.
- if (!agent_host)
- return nullptr;
- for (auto* network_handler :
- protocol::NetworkHandler::ForAgentHost(agent_host)) {
- std::unique_ptr<NavigationThrottle> throttle =
- network_handler->CreateThrottleForNavigation(navigation_handle);
- if (throttle)
- return throttle;
+ if (agent_host) {
+ for (auto* network_handler :
+ protocol::NetworkHandler::ForAgentHost(agent_host)) {
+ std::unique_ptr<NavigationThrottle> throttle =
+ network_handler->CreateThrottleForNavigation(navigation_handle);
+ if (throttle)
+ result.push_back(std::move(throttle));
+ }
}
- return nullptr;
+
+ agent_host = nullptr;
+ if (frame_tree_node->parent()) {
+ // Target domain of the parent frame's DevTools may want to pause
+ // this frame to do some setup.
+ agent_host =
+ FindAgentHost(GetFrameTreeNodeAncestor(frame_tree_node->parent()));
+ }
+ if (agent_host) {
+ for (auto* target_handler :
+ protocol::TargetHandler::ForAgentHost(agent_host)) {
+ std::unique_ptr<NavigationThrottle> throttle =
+ target_handler->CreateThrottleForNavigation(navigation_handle);
+ if (throttle)
+ result.push_back(std::move(throttle));
+ }
+ }
+
+ return result;
}
// static
@@ -405,27 +504,26 @@ bool RenderFrameDevToolsAgentHost::IsNetworkHandlerEnabled(
void RenderFrameDevToolsAgentHost::AppendDevToolsHeaders(
FrameTreeNode* frame_tree_node,
net::HttpRequestHeaders* headers) {
- static const char kDevToolsEmulateNetworkConditionsClientId[] =
- "X-DevTools-Emulate-Network-Conditions-Client-Id";
-
frame_tree_node = GetFrameTreeNodeAncestor(frame_tree_node);
RenderFrameDevToolsAgentHost* agent_host = FindAgentHost(frame_tree_node);
if (!agent_host)
return;
- std::string ua_override;
- bool enabled = false;
+ for (auto* network : protocol::NetworkHandler::ForAgentHost(agent_host))
+ network->AppendDevToolsHeaders(headers);
+}
+
+// static
+bool RenderFrameDevToolsAgentHost::ShouldBypassServiceWorker(
+ FrameTreeNode* frame_tree_node) {
+ frame_tree_node = GetFrameTreeNodeAncestor(frame_tree_node);
+ RenderFrameDevToolsAgentHost* agent_host = FindAgentHost(frame_tree_node);
+ if (!agent_host)
+ return false;
for (auto* network : protocol::NetworkHandler::ForAgentHost(agent_host)) {
- enabled = enabled || network->enabled();
- ua_override = network->UserAgentOverride();
- if (!ua_override.empty())
- break;
+ if (network->ShouldBypassServiceWorker())
+ return true;
}
- if (!enabled)
- return;
- headers->SetHeader(kDevToolsEmulateNetworkConditionsClientId,
- agent_host->GetId());
- if (!ua_override.empty())
- headers->SetHeader(net::HttpRequestHeaders::kUserAgent, ua_override);
+ return false;
}
// static
@@ -461,7 +559,7 @@ RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost(
current_frame_crashed_ = true;
}
- g_instances.Get().push_back(this);
+ g_agent_host_instances.Get().push_back(this);
AddRef(); // Balanced in RenderFrameHostDestroyed.
NotifyCreated();
@@ -548,10 +646,8 @@ void RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) {
}
if (IsBrowserSideNavigationEnabled()) {
- if (frame_host_) {
- frame_host_->Send(new DevToolsAgentMsg_Attach(
- frame_host_->GetRoutingID(), GetId(), session->session_id()));
- }
+ if (EnsureAgent())
+ session->AttachToAgent(agent_ptr_);
} else {
if (current_)
current_->Attach(session);
@@ -564,10 +660,7 @@ void RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) {
void RenderFrameDevToolsAgentHost::DetachSession(int session_id) {
if (IsBrowserSideNavigationEnabled()) {
- if (frame_host_) {
- frame_host_->Send(
- new DevToolsAgentMsg_Detach(frame_host_->GetRoutingID(), session_id));
- }
+ // Destroying session automatically detaches in renderer.
suspended_messages_by_session_id_.erase(session_id);
} else {
if (current_)
@@ -591,15 +684,12 @@ bool RenderFrameDevToolsAgentHost::DispatchProtocolMessage(
}
if (IsBrowserSideNavigationEnabled()) {
- if (!navigation_handles_.empty() || method == kPageNavigateCommand) {
+ if (!navigation_handles_.empty()) {
suspended_messages_by_session_id_[session_id].push_back(
{call_id, method, message});
return true;
}
- if (frame_host_) {
- frame_host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
- frame_host_->GetRoutingID(), session_id, call_id, method, message));
- }
+ session->DispatchProtocolMessageToAgent(call_id, method, message);
session->waiting_messages()[call_id] = {method, message};
} else {
if (current_)
@@ -615,10 +705,7 @@ void RenderFrameDevToolsAgentHost::InspectElement(
int x,
int y) {
if (IsBrowserSideNavigationEnabled()) {
- if (frame_host_) {
- frame_host_->Send(new DevToolsAgentMsg_InspectElement(
- frame_host_->GetRoutingID(), session->session_id(), x, y));
- }
+ session->InspectElement(gfx::Point(x, y));
} else {
if (current_)
current_->InspectElement(session->session_id(), x, y);
@@ -646,11 +733,11 @@ void RenderFrameDevToolsAgentHost::OnClientsDetached() {
}
RenderFrameDevToolsAgentHost::~RenderFrameDevToolsAgentHost() {
- Instances::iterator it = std::find(g_instances.Get().begin(),
- g_instances.Get().end(),
- this);
- if (it != g_instances.Get().end())
- g_instances.Get().erase(it);
+ RenderFrameDevToolsArray::iterator it =
+ std::find(g_agent_host_instances.Get().begin(),
+ g_agent_host_instances.Get().end(), this);
+ if (it != g_agent_host_instances.Get().end())
+ g_agent_host_instances.Get().erase(it);
}
void RenderFrameDevToolsAgentHost::ReadyToCommitNavigation(
@@ -706,11 +793,8 @@ void RenderFrameDevToolsAgentHost::DidFinishNavigation(
int session_id = pair.first;
DevToolsSession* session = SessionById(session_id);
for (const Message& message : pair.second) {
- if (frame_host_) {
- frame_host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
- frame_host_->GetRoutingID(), session_id, message.call_id,
- message.method, message.message));
- }
+ session->DispatchProtocolMessageToAgent(message.call_id, message.method,
+ message.message);
session->waiting_messages()[message.call_id] = {message.method,
message.message};
}
@@ -743,6 +827,7 @@ void RenderFrameDevToolsAgentHost::UpdateFrameHost(
}
frame_host_ = frame_host;
+ agent_ptr_.reset();
render_frame_alive_ = true;
if (IsAttached()) {
GrantPolicy(frame_host_);
@@ -754,18 +839,15 @@ void RenderFrameDevToolsAgentHost::UpdateFrameHost(
void RenderFrameDevToolsAgentHost::MaybeReattachToRenderFrame() {
DCHECK(IsBrowserSideNavigationEnabled());
- if (!frame_host_)
+ if (!EnsureAgent())
return;
for (DevToolsSession* session : sessions()) {
- frame_host_->Send(new DevToolsAgentMsg_Reattach(
- frame_host_->GetRoutingID(), GetId(), session->session_id(),
- session->state_cookie()));
+ session->ReattachToAgent(agent_ptr_);
for (const auto& pair : session->waiting_messages()) {
int call_id = pair.first;
const DevToolsSession::Message& message = pair.second;
- frame_host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
- frame_host_->GetRoutingID(), session->session_id(), call_id,
- message.method, message.message));
+ session->DispatchProtocolMessageToAgent(call_id, message.method,
+ message.message);
}
}
}
@@ -786,7 +868,7 @@ void RenderFrameDevToolsAgentHost::RevokePolicy(RenderFrameHostImpl* host) {
bool process_has_agents = false;
RenderProcessHost* process_host = host->GetProcess();
- for (RenderFrameDevToolsAgentHost* agent : g_instances.Get()) {
+ for (RenderFrameDevToolsAgentHost* agent : g_agent_host_instances.Get()) {
if (!agent->IsAttached())
continue;
if (IsBrowserSideNavigationEnabled()) {
@@ -911,8 +993,10 @@ void RenderFrameDevToolsAgentHost::FrameDeleted(RenderFrameHost* rfh) {
void RenderFrameDevToolsAgentHost::RenderFrameDeleted(RenderFrameHost* rfh) {
if (IsBrowserSideNavigationEnabled()) {
- if (rfh == frame_host_)
+ if (rfh == frame_host_) {
render_frame_alive_ = false;
+ agent_ptr_.reset();
+ }
DCHECK(CheckConsistency());
return;
}
@@ -928,8 +1012,9 @@ void RenderFrameDevToolsAgentHost::DestroyOnRenderFrameGone() {
UpdateProtocolHandlers(nullptr);
if (IsAttached())
OnClientsDetached();
- ForceDetachAllClients(false);
+ ForceDetachAllClients();
frame_host_ = nullptr;
+ agent_ptr_.reset();
pending_.reset();
current_.reset();
frame_tree_node_ = nullptr;
@@ -967,8 +1052,8 @@ device::mojom::WakeLock* RenderFrameDevToolsAgentHost::GetWakeLock() {
web_contents()->GetWakeLockContext();
if (wake_lock_context) {
wake_lock_context->GetWakeLock(
- device::mojom::WakeLockType::PreventDisplaySleep,
- device::mojom::WakeLockReason::ReasonOther, "DevTools",
+ device::mojom::WakeLockType::kPreventDisplaySleep,
+ device::mojom::WakeLockReason::kOther, "DevTools",
std::move(request));
}
}
@@ -1001,32 +1086,6 @@ void RenderFrameDevToolsAgentHost::RenderProcessGone(
DCHECK(CheckConsistency());
}
-bool RenderFrameDevToolsAgentHost::OnMessageReceived(
- const IPC::Message& message,
- RenderFrameHost* render_frame_host) {
- if (IsBrowserSideNavigationEnabled()) {
- if (render_frame_host != frame_host_)
- return false;
- } else {
- bool is_current = current_ && current_->host() == render_frame_host;
- bool is_pending = pending_ && pending_->host() == render_frame_host;
- if (!is_current && !is_pending)
- return false;
- }
- if (!IsAttached())
- return false;
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(RenderFrameDevToolsAgentHost, message,
- render_frame_host)
- IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
- OnDispatchOnInspectorFrontend)
- IPC_MESSAGE_HANDLER(DevToolsAgentHostMsg_RequestNewWindow,
- OnRequestNewWindow)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
void RenderFrameDevToolsAgentHost::DidAttachInterstitialPage() {
for (auto* page : protocol::PageHandler::ForAgentHost(this))
page->DidAttachInterstitialPage();
@@ -1315,45 +1374,12 @@ void RenderFrameDevToolsAgentHost::SynchronousSwapCompositorFrame(
}
}
-void RenderFrameDevToolsAgentHost::OnDispatchOnInspectorFrontend(
- RenderFrameHost* sender,
- const DevToolsMessageChunk& message) {
- bool success = true;
- if (IsBrowserSideNavigationEnabled()) {
- if (sender == frame_host_) {
- DevToolsSession* session = SessionById(message.session_id);
- if (session)
- success = session->ReceiveMessageChunk(message);
- }
- } else {
- if (current_ && current_->host() == sender)
- success = current_->ProcessChunkedMessageFromAgent(message);
- else if (pending_ && pending_->host() == sender)
- success = pending_->ProcessChunkedMessageFromAgent(message);
- }
- if (!success) {
- bad_message::ReceivedBadMessage(
- sender->GetProcess(),
- bad_message::RFH_INCONSISTENT_DEVTOOLS_MESSAGE);
- }
-}
-
-void RenderFrameDevToolsAgentHost::OnRequestNewWindow(
- RenderFrameHost* sender,
- int new_routing_id) {
- RenderFrameHostImpl* frame_host = RenderFrameHostImpl::FromID(
- sender->GetProcess()->GetID(), new_routing_id);
-
- bool success = false;
- if (IsAttached() && sender->GetRoutingID() != new_routing_id && frame_host) {
- scoped_refptr<DevToolsAgentHost> agent =
- RenderFrameDevToolsAgentHost::GetOrCreateFor(
- frame_host->frame_tree_node());
- success = static_cast<DevToolsAgentHostImpl*>(agent.get())->Inspect();
- }
-
- sender->Send(new DevToolsAgentMsg_RequestNewWindow_ACK(
- sender->GetRoutingID(), success));
+bool RenderFrameDevToolsAgentHost::EnsureAgent() {
+ if (!frame_host_ || !render_frame_alive_)
+ return false;
+ if (!agent_ptr_)
+ frame_host_->GetRemoteAssociatedInterfaces()->GetInterface(&agent_ptr_);
+ return true;
}
bool RenderFrameDevToolsAgentHost::IsChildFrame() {
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 002de51f69a..17300dc2d3f 100644
--- a/chromium/content/browser/devtools/render_frame_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -15,6 +15,7 @@
#include "build/build_config.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/common/content_export.h"
+#include "content/common/devtools.mojom.h"
#include "content/public/browser/web_contents_observer.h"
#include "net/base/net_errors.h"
@@ -38,10 +39,9 @@ class DevToolsFrameTraceRecorder;
class FrameTreeNode;
class NavigationHandle;
class NavigationHandleImpl;
+class NavigationRequest;
class NavigationThrottle;
class RenderFrameHostImpl;
-struct BeginNavigationParams;
-struct CommonNavigationParams;
class CONTENT_EXPORT RenderFrameDevToolsAgentHost
: public DevToolsAgentHostImpl,
@@ -51,19 +51,24 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
static scoped_refptr<DevToolsAgentHost> GetOrCreateFor(
FrameTreeNode* frame_tree_node);
+ // This method does not climb up to the suitable parent frame,
+ // so only use it when we are sure the frame will be a local root.
+ // Prefer GetOrCreateFor instead.
+ static scoped_refptr<DevToolsAgentHost> GetOrCreateForDangling(
+ FrameTreeNode* frame_tree_node);
+
static void OnCancelPendingNavigation(RenderFrameHost* pending,
RenderFrameHost* current);
static void OnBeforeNavigation(RenderFrameHost* current,
RenderFrameHost* pending);
- static void OnFailedNavigation(RenderFrameHost* host,
- const CommonNavigationParams& common_params,
- const BeginNavigationParams& begin_params,
- net::Error error_code);
- static std::unique_ptr<NavigationThrottle> CreateThrottleForNavigation(
- NavigationHandle* navigation_handle);
+ static void OnResetNavigationRequest(NavigationRequest* navigation_request);
+
+ static std::vector<std::unique_ptr<NavigationThrottle>>
+ CreateNavigationThrottles(NavigationHandle* navigation_handle);
static bool IsNetworkHandlerEnabled(FrameTreeNode* frame_tree_node);
static void AppendDevToolsHeaders(FrameTreeNode* frame_tree_node,
net::HttpRequestHeaders* headers);
+ static bool ShouldBypassServiceWorker(FrameTreeNode* frame_tree_node);
static void WebContentsCreated(WebContents* web_contents);
static void SignalSynchronousSwapCompositorFrame(
@@ -115,8 +120,6 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
void FrameDeleted(RenderFrameHost* rfh) override;
void RenderFrameDeleted(RenderFrameHost* rfh) override;
void RenderProcessGone(base::TerminationStatus status) override;
- bool OnMessageReceived(const IPC::Message& message,
- RenderFrameHost* render_frame_host) override;
void DidAttachInterstitialPage() override;
void DidDetachInterstitialPage() override;
void WasShown() override;
@@ -138,10 +141,6 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
void RenderFrameCrashed();
void OnSwapCompositorFrame(const IPC::Message& message);
- void OnDispatchOnInspectorFrontend(
- RenderFrameHost* sender,
- const DevToolsMessageChunk& message);
- void OnRequestNewWindow(RenderFrameHost* sender, int new_routing_id);
void DestroyOnRenderFrameGone();
bool CheckConsistency();
@@ -156,6 +155,7 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
void SynchronousSwapCompositorFrame(
viz::CompositorFrameMetadata frame_metadata);
+ bool EnsureAgent();
class FrameHostHolder;
@@ -176,6 +176,7 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
// The active host we are talking to.
RenderFrameHostImpl* frame_host_ = nullptr;
+ 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 e24253d1f95..63fb5617eb0 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc
@@ -55,7 +55,8 @@ ServiceWorkerDevToolsAgentHost::ServiceWorkerDevToolsAgentHost(
WorkerId worker_id,
const ServiceWorkerIdentifier& service_worker,
bool is_installed_version)
- : WorkerDevToolsAgentHost(worker_id),
+ : WorkerDevToolsAgentHost(service_worker.devtools_worker_token(),
+ worker_id),
service_worker_(new ServiceWorkerIdentifier(service_worker)),
version_installed_time_(is_installed_version ? base::Time::Now()
: base::Time()) {
@@ -136,9 +137,9 @@ void ServiceWorkerDevToolsAgentHost::NavigationPreloadResponseReceived(
void ServiceWorkerDevToolsAgentHost::NavigationPreloadCompleted(
const std::string& request_id,
- const ResourceRequestCompletionStatus& completion_status) {
+ const network::URLLoaderCompletionStatus& status) {
for (auto* network : protocol::NetworkHandler::ForAgentHost(this))
- network->NavigationPreloadCompleted(request_id, completion_status);
+ network->NavigationPreloadCompleted(request_id, status);
}
int64_t ServiceWorkerDevToolsAgentHost::service_worker_version_id() const {
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 a4fd5f8b465..c0acba18325 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/service_worker_devtools_agent_host.h
@@ -14,11 +14,14 @@
#include "content/browser/devtools/service_worker_devtools_manager.h"
#include "content/browser/devtools/worker_devtools_agent_host.h"
+namespace network {
+struct URLLoaderCompletionStatus;
+}
+
namespace content {
struct ResourceRequest;
struct ResourceResponseHead;
-struct ResourceRequestCompletionStatus;
class ServiceWorkerDevToolsAgentHost : public WorkerDevToolsAgentHost {
public:
@@ -55,7 +58,7 @@ class ServiceWorkerDevToolsAgentHost : public WorkerDevToolsAgentHost {
const ResourceResponseHead& head);
void NavigationPreloadCompleted(
const std::string& request_id,
- const ResourceRequestCompletionStatus& completion_status);
+ const network::URLLoaderCompletionStatus& status);
int64_t service_worker_version_id() const;
GURL scope() const;
diff --git a/chromium/content/browser/devtools/service_worker_devtools_manager.cc b/chromium/content/browser/devtools/service_worker_devtools_manager.cc
index c0778994177..053de7155b0 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_manager.cc
+++ b/chromium/content/browser/devtools/service_worker_devtools_manager.cc
@@ -8,7 +8,6 @@
#include "content/browser/devtools/service_worker_devtools_agent_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/worker_service.h"
#include "ipc/ipc_listener.h"
namespace content {
@@ -18,20 +17,19 @@ ServiceWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier(
base::WeakPtr<ServiceWorkerContextCore> context_weak,
int64_t version_id,
const GURL& url,
- const GURL& scope)
+ const GURL& scope,
+ const base::UnguessableToken& devtools_worker_token)
: context_(context),
context_weak_(context_weak),
version_id_(version_id),
url_(url),
- scope_(scope) {}
+ scope_(scope),
+ devtools_worker_token_(devtools_worker_token) {
+ DCHECK(!devtools_worker_token_.is_empty());
+}
ServiceWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier(
- const ServiceWorkerIdentifier& other)
- : context_(other.context_),
- context_weak_(other.context_weak_),
- version_id_(other.version_id_),
- url_(other.url_),
- scope_(other.scope_) {}
+ const ServiceWorkerIdentifier& other) = default;
ServiceWorkerDevToolsManager::
ServiceWorkerIdentifier::~ServiceWorkerIdentifier() {
@@ -101,7 +99,6 @@ bool ServiceWorkerDevToolsManager::WorkerCreated(
agent_host->WorkerRestarted(id);
workers_.erase(it);
workers_[id] = agent_host;
-
return agent_host->IsAttached();
}
diff --git a/chromium/content/browser/devtools/service_worker_devtools_manager.h b/chromium/content/browser/devtools/service_worker_devtools_manager.h
index 764df29f936..079b18c221e 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_manager.h
+++ b/chromium/content/browser/devtools/service_worker_devtools_manager.h
@@ -13,6 +13,7 @@
#include "base/memory/singleton.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
+#include "base/unguessable_token.h"
#include "content/public/browser/devtools_agent_host.h"
namespace content {
@@ -48,7 +49,8 @@ class CONTENT_EXPORT ServiceWorkerDevToolsManager {
base::WeakPtr<ServiceWorkerContextCore> context_weak,
int64_t version_id,
const GURL& url,
- const GURL& scope);
+ const GURL& scope,
+ const base::UnguessableToken& devtools_worker_token);
ServiceWorkerIdentifier(const ServiceWorkerIdentifier& other);
~ServiceWorkerIdentifier();
@@ -61,6 +63,9 @@ class CONTENT_EXPORT ServiceWorkerDevToolsManager {
int64_t version_id() const { return version_id_; }
GURL url() const { return url_; }
GURL scope() const { return scope_; }
+ const base::UnguessableToken& devtools_worker_token() const {
+ return devtools_worker_token_;
+ }
private:
const ServiceWorkerContextCore* const context_;
@@ -68,6 +73,7 @@ class CONTENT_EXPORT ServiceWorkerDevToolsManager {
const int64_t version_id_;
const GURL url_;
const GURL scope_;
+ const base::UnguessableToken devtools_worker_token_;
};
// Returns the ServiceWorkerDevToolsManager singleton.
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 a8dda2a57ed..4e326578fb0 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc
@@ -11,20 +11,10 @@
namespace content {
-namespace {
-
-void TerminateSharedWorkerOnIO(
- WorkerDevToolsAgentHost::WorkerId worker_id) {
- SharedWorkerServiceImpl::GetInstance()->TerminateWorker(
- worker_id.first, worker_id.second);
-}
-
-} // namespace
-
SharedWorkerDevToolsAgentHost::SharedWorkerDevToolsAgentHost(
WorkerId worker_id,
const SharedWorkerInstance& shared_worker)
- : WorkerDevToolsAgentHost(worker_id),
+ : WorkerDevToolsAgentHost(shared_worker.devtools_worker_token(), worker_id),
shared_worker_(new SharedWorkerInstance(shared_worker)) {
NotifyCreated();
}
@@ -49,9 +39,8 @@ void SharedWorkerDevToolsAgentHost::Reload() {
}
bool SharedWorkerDevToolsAgentHost::Close() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&TerminateSharedWorkerOnIO, worker_id()));
+ static_cast<SharedWorkerServiceImpl*>(SharedWorkerService::GetInstance())
+ ->TerminateWorkerById(worker_id().first, worker_id().second);
return true;
}
diff --git a/chromium/content/browser/devtools/shared_worker_devtools_manager.cc b/chromium/content/browser/devtools/shared_worker_devtools_manager.cc
index 4d38241e613..9903398a7aa 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_manager.cc
+++ b/chromium/content/browser/devtools/shared_worker_devtools_manager.cc
@@ -16,15 +16,6 @@ SharedWorkerDevToolsManager* SharedWorkerDevToolsManager::GetInstance() {
return base::Singleton<SharedWorkerDevToolsManager>::get();
}
-DevToolsAgentHostImpl*
-SharedWorkerDevToolsManager::GetDevToolsAgentHostForWorker(
- int worker_process_id,
- int worker_route_id) {
- AgentHostMap::iterator it = workers_.find(
- WorkerId(worker_process_id, worker_route_id));
- return it == workers_.end() ? NULL : it->second;
-}
-
void SharedWorkerDevToolsManager::AddAllAgentHosts(
SharedWorkerDevToolsAgentHost::List* result) {
for (auto& worker : workers_) {
diff --git a/chromium/content/browser/devtools/shared_worker_devtools_manager.h b/chromium/content/browser/devtools/shared_worker_devtools_manager.h
index 40d1ffcfccd..c7f4f7c5697 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_manager.h
+++ b/chromium/content/browser/devtools/shared_worker_devtools_manager.h
@@ -14,7 +14,6 @@
namespace content {
-class DevToolsAgentHostImpl;
class SharedWorkerDevToolsAgentHost;
class SharedWorkerInstance;
@@ -27,8 +26,6 @@ class CONTENT_EXPORT SharedWorkerDevToolsManager {
// Returns the SharedWorkerDevToolsManager singleton.
static SharedWorkerDevToolsManager* GetInstance();
- DevToolsAgentHostImpl* GetDevToolsAgentHostForWorker(int worker_process_id,
- int worker_route_id);
void AddAllAgentHosts(
std::vector<scoped_refptr<SharedWorkerDevToolsAgentHost>>* result);
diff --git a/chromium/content/browser/devtools/shared_worker_devtools_manager_unittest.cc b/chromium/content/browser/devtools/shared_worker_devtools_manager_unittest.cc
index 27e298273a9..66c5747ba8f 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_manager_unittest.cc
+++ b/chromium/content/browser/devtools/shared_worker_devtools_manager_unittest.cc
@@ -31,7 +31,7 @@ class TestDevToolsClientHost : public DevToolsAgentHostClient {
~TestDevToolsClientHost() override {}
void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
const std::string& message) override {}
- void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override {}
+ void AgentHostClosed(DevToolsAgentHost* agent_host) override {}
void InspectAgentHost(DevToolsAgentHost* agent_host) {
if (agent_host_.get())
@@ -54,15 +54,15 @@ class SharedWorkerDevToolsManagerTest : public testing::Test {
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
browser_context_(new TestBrowserContext()),
partition_(new WorkerStoragePartition(
- BrowserContext::GetDefaultStoragePartition(browser_context_.get())->
- GetURLRequestContext(),
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL)),
+ BrowserContext::GetDefaultStoragePartition(browser_context_.get())
+ ->GetURLRequestContext(),
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr)),
partition_id_(*partition_.get()) {}
protected:
@@ -76,24 +76,30 @@ class SharedWorkerDevToolsManagerTest : public testing::Test {
void CheckWorkerState(int worker_process_id,
int worker_route_id,
WorkerState state) {
- const SharedWorkerDevToolsManager::WorkerId id(worker_process_id,
- worker_route_id);
- SharedWorkerDevToolsManager::AgentHostMap::iterator it =
- manager_->workers_.find(id);
- EXPECT_TRUE(manager_->workers_.end() != it);
- EXPECT_EQ(state, it->second->state_);
+ SharedWorkerDevToolsAgentHost* host =
+ GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id);
+ EXPECT_TRUE(!!host);
+ EXPECT_EQ(state, host->state_);
}
void CheckWorkerNotExist(int worker_process_id, int worker_route_id) {
- const SharedWorkerDevToolsManager::WorkerId id(worker_process_id,
- worker_route_id);
- EXPECT_TRUE(manager_->workers_.end() == manager_->workers_.find(id));
+ EXPECT_TRUE(
+ !GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id));
}
void CheckWorkerCount(size_t size) {
EXPECT_EQ(size, manager_->workers_.size());
}
+ SharedWorkerDevToolsAgentHost* GetDevToolsAgentHostForWorker(
+ int worker_process_id,
+ int worker_route_id) {
+ const SharedWorkerDevToolsManager::WorkerId id(worker_process_id,
+ worker_route_id);
+ auto it = manager_->workers_.find(id);
+ return it == manager_->workers_.end() ? nullptr : it->second;
+ }
+
TestBrowserThreadBundle browser_thread_bundle_;
std::unique_ptr<TestBrowserContext> browser_context_;
std::unique_ptr<WorkerStoragePartition> partition_;
@@ -105,13 +111,14 @@ TEST_F(SharedWorkerDevToolsManagerTest, BasicTest) {
scoped_refptr<DevToolsAgentHostImpl> agent_host;
SharedWorkerInstance instance1(
- GURL("http://example.com/w.js"), std::string(), std::string(),
+ GURL("http://example.com/w.js"), std::string(),
+ url::Origin::Create(GURL("http://example.com/")), std::string(),
blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic,
browser_context_->GetResourceContext(), partition_id_,
blink::mojom::SharedWorkerCreationContextType::kNonsecure,
- false /* data_saver_enabled */);
+ base::UnguessableToken::Create());
- agent_host = manager_->GetDevToolsAgentHostForWorker(1, 1);
+ agent_host = GetDevToolsAgentHostForWorker(1, 1);
EXPECT_FALSE(agent_host.get());
// Created -> Started -> Destroyed
@@ -127,15 +134,15 @@ TEST_F(SharedWorkerDevToolsManagerTest, BasicTest) {
CheckWorkerNotExist(1, 2);
manager_->WorkerCreated(1, 2, instance1);
CheckWorkerState(1, 2, WorkerState::WORKER_UNINSPECTED);
- agent_host = manager_->GetDevToolsAgentHostForWorker(1, 2);
+ agent_host = GetDevToolsAgentHostForWorker(1, 2);
EXPECT_TRUE(agent_host.get());
CheckWorkerState(1, 2, WorkerState::WORKER_UNINSPECTED);
- EXPECT_EQ(agent_host.get(), manager_->GetDevToolsAgentHostForWorker(1, 2));
+ EXPECT_EQ(agent_host.get(), GetDevToolsAgentHostForWorker(1, 2));
manager_->WorkerReadyForInspection(1, 2);
CheckWorkerState(1, 2, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerDestroyed(1, 2);
CheckWorkerState(1, 2, WorkerState::WORKER_TERMINATED);
- agent_host = NULL;
+ agent_host = nullptr;
CheckWorkerNotExist(1, 2);
// Created -> Started -> GetDevToolsAgentHost -> Destroyed
@@ -144,12 +151,12 @@ TEST_F(SharedWorkerDevToolsManagerTest, BasicTest) {
CheckWorkerState(1, 3, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerReadyForInspection(1, 3);
CheckWorkerState(1, 3, WorkerState::WORKER_UNINSPECTED);
- agent_host = manager_->GetDevToolsAgentHostForWorker(1, 3);
+ agent_host = GetDevToolsAgentHostForWorker(1, 3);
EXPECT_TRUE(agent_host.get());
CheckWorkerState(1, 3, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerDestroyed(1, 3);
CheckWorkerState(1, 3, WorkerState::WORKER_TERMINATED);
- agent_host = NULL;
+ agent_host = nullptr;
CheckWorkerNotExist(1, 3);
// Created -> Destroyed
@@ -163,22 +170,22 @@ TEST_F(SharedWorkerDevToolsManagerTest, BasicTest) {
CheckWorkerNotExist(1, 5);
manager_->WorkerCreated(1, 5, instance1);
CheckWorkerState(1, 5, WorkerState::WORKER_UNINSPECTED);
- agent_host = manager_->GetDevToolsAgentHostForWorker(1, 5);
+ agent_host = GetDevToolsAgentHostForWorker(1, 5);
EXPECT_TRUE(agent_host.get());
CheckWorkerState(1, 5, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerDestroyed(1, 5);
CheckWorkerState(1, 5, WorkerState::WORKER_TERMINATED);
- agent_host = NULL;
+ agent_host = nullptr;
CheckWorkerNotExist(1, 5);
// Created -> GetDevToolsAgentHost -> Free agent_host -> Destroyed
CheckWorkerNotExist(1, 6);
manager_->WorkerCreated(1, 6, instance1);
CheckWorkerState(1, 6, WorkerState::WORKER_UNINSPECTED);
- agent_host = manager_->GetDevToolsAgentHostForWorker(1, 6);
+ agent_host = GetDevToolsAgentHostForWorker(1, 6);
EXPECT_TRUE(agent_host.get());
CheckWorkerState(1, 6, WorkerState::WORKER_UNINSPECTED);
- agent_host = NULL;
+ agent_host = nullptr;
manager_->WorkerDestroyed(1, 6);
CheckWorkerNotExist(1, 6);
}
@@ -188,17 +195,19 @@ TEST_F(SharedWorkerDevToolsManagerTest, AttachTest) {
scoped_refptr<DevToolsAgentHostImpl> agent_host2;
SharedWorkerInstance instance1(
- GURL("http://example.com/w1.js"), std::string(), std::string(),
+ GURL("http://example.com/w1.js"), std::string(),
+ url::Origin::Create(GURL("http://example.com/")), std::string(),
blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic,
browser_context_->GetResourceContext(), partition_id_,
blink::mojom::SharedWorkerCreationContextType::kNonsecure,
- false /* data_saver_enabled */);
+ base::UnguessableToken::Create());
SharedWorkerInstance instance2(
- GURL("http://example.com/w2.js"), std::string(), std::string(),
+ GURL("http://example.com/w2.js"), std::string(),
+ url::Origin::Create(GURL("http://example.com/")), std::string(),
blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic,
browser_context_->GetResourceContext(), partition_id_,
blink::mojom::SharedWorkerCreationContextType::kNonsecure,
- false /* data_saver_enabled */);
+ base::UnguessableToken::Create());
// Created -> GetDevToolsAgentHost -> Register -> Started -> Destroyed
std::unique_ptr<TestDevToolsClientHost> client_host1(
@@ -206,17 +215,17 @@ TEST_F(SharedWorkerDevToolsManagerTest, AttachTest) {
CheckWorkerNotExist(2, 1);
manager_->WorkerCreated(2, 1, instance1);
CheckWorkerState(2, 1, WorkerState::WORKER_UNINSPECTED);
- agent_host1 = manager_->GetDevToolsAgentHostForWorker(2, 1);
+ agent_host1 = GetDevToolsAgentHostForWorker(2, 1);
EXPECT_TRUE(agent_host1.get());
CheckWorkerState(2, 1, WorkerState::WORKER_UNINSPECTED);
- EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
+ EXPECT_EQ(agent_host1.get(), GetDevToolsAgentHostForWorker(2, 1));
client_host1->InspectAgentHost(agent_host1.get());
CheckWorkerState(2, 1, WorkerState::WORKER_INSPECTED);
manager_->WorkerReadyForInspection(2, 1);
CheckWorkerState(2, 1, WorkerState::WORKER_INSPECTED);
manager_->WorkerDestroyed(2, 1);
CheckWorkerState(2, 1, WorkerState::WORKER_TERMINATED);
- EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
+ EXPECT_EQ(agent_host1.get(), GetDevToolsAgentHostForWorker(2, 1));
// Created -> Started -> GetDevToolsAgentHost -> Register -> Destroyed
std::unique_ptr<TestDevToolsClientHost> client_host2(
@@ -225,29 +234,29 @@ TEST_F(SharedWorkerDevToolsManagerTest, AttachTest) {
CheckWorkerState(2, 2, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerReadyForInspection(2, 2);
CheckWorkerState(2, 2, WorkerState::WORKER_UNINSPECTED);
- agent_host2 = manager_->GetDevToolsAgentHostForWorker(2, 2);
+ agent_host2 = GetDevToolsAgentHostForWorker(2, 2);
EXPECT_TRUE(agent_host2.get());
EXPECT_NE(agent_host1.get(), agent_host2.get());
- EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
+ EXPECT_EQ(agent_host2.get(), GetDevToolsAgentHostForWorker(2, 2));
CheckWorkerState(2, 2, WorkerState::WORKER_UNINSPECTED);
client_host2->InspectAgentHost(agent_host2.get());
CheckWorkerState(2, 2, WorkerState::WORKER_INSPECTED);
manager_->WorkerDestroyed(2, 2);
CheckWorkerState(2, 2, WorkerState::WORKER_TERMINATED);
- EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
+ EXPECT_EQ(agent_host2.get(), GetDevToolsAgentHostForWorker(2, 2));
// Re-created -> Started -> ClientHostClosing -> Destroyed
CheckWorkerState(2, 1, WorkerState::WORKER_TERMINATED);
manager_->WorkerCreated(2, 3, instance1);
CheckWorkerNotExist(2, 1);
CheckWorkerState(2, 3, WorkerState::WORKER_PAUSED_FOR_REATTACH);
- EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 3));
+ EXPECT_EQ(agent_host1.get(), GetDevToolsAgentHostForWorker(2, 3));
manager_->WorkerReadyForInspection(2, 3);
CheckWorkerState(2, 3, WorkerState::WORKER_INSPECTED);
- client_host1->InspectAgentHost(NULL);
+ client_host1->InspectAgentHost(nullptr);
manager_->WorkerDestroyed(2, 3);
CheckWorkerState(2, 3, WorkerState::WORKER_TERMINATED);
- agent_host1 = NULL;
+ agent_host1 = nullptr;
CheckWorkerNotExist(2, 3);
// Re-created -> Destroyed
@@ -255,7 +264,7 @@ TEST_F(SharedWorkerDevToolsManagerTest, AttachTest) {
manager_->WorkerCreated(2, 4, instance2);
CheckWorkerNotExist(2, 2);
CheckWorkerState(2, 4, WorkerState::WORKER_PAUSED_FOR_REATTACH);
- EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 4));
+ EXPECT_EQ(agent_host2.get(), GetDevToolsAgentHostForWorker(2, 4));
manager_->WorkerDestroyed(2, 4);
CheckWorkerNotExist(2, 2);
CheckWorkerState(2, 4, WorkerState::WORKER_TERMINATED);
@@ -264,10 +273,10 @@ TEST_F(SharedWorkerDevToolsManagerTest, AttachTest) {
manager_->WorkerCreated(2, 5, instance2);
CheckWorkerNotExist(2, 2);
CheckWorkerState(2, 5, WorkerState::WORKER_PAUSED_FOR_REATTACH);
- EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 5));
- client_host2->InspectAgentHost(NULL);
+ EXPECT_EQ(agent_host2.get(), GetDevToolsAgentHostForWorker(2, 5));
+ client_host2->InspectAgentHost(nullptr);
CheckWorkerCount(1);
- agent_host2 = NULL;
+ agent_host2 = nullptr;
CheckWorkerCount(1);
manager_->WorkerDestroyed(2, 5);
CheckWorkerCount(0);
@@ -275,18 +284,19 @@ TEST_F(SharedWorkerDevToolsManagerTest, AttachTest) {
TEST_F(SharedWorkerDevToolsManagerTest, ReattachTest) {
SharedWorkerInstance instance(
- GURL("http://example.com/w3.js"), std::string(), std::string(),
+ GURL("http://example.com/w3.js"), std::string(),
+ url::Origin::Create(GURL("http://example.com/")), std::string(),
blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic,
browser_context_->GetResourceContext(), partition_id_,
blink::mojom::SharedWorkerCreationContextType::kNonsecure,
- false /* data_saver_enabled */);
+ base::UnguessableToken::Create());
std::unique_ptr<TestDevToolsClientHost> client_host(
new TestDevToolsClientHost());
// Created -> GetDevToolsAgentHost -> Register -> Destroyed
manager_->WorkerCreated(3, 1, instance);
CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED);
scoped_refptr<DevToolsAgentHost> agent_host(
- manager_->GetDevToolsAgentHostForWorker(3, 1));
+ GetDevToolsAgentHostForWorker(3, 1));
EXPECT_TRUE(agent_host.get());
CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED);
client_host->InspectAgentHost(agent_host.get());
@@ -294,11 +304,11 @@ TEST_F(SharedWorkerDevToolsManagerTest, ReattachTest) {
manager_->WorkerDestroyed(3, 1);
CheckWorkerState(3, 1, WorkerState::WORKER_TERMINATED);
// ClientHostClosing -> Re-created -> release agent_host -> Destroyed
- client_host->InspectAgentHost(NULL);
+ client_host->InspectAgentHost(nullptr);
CheckWorkerState(3, 1, WorkerState::WORKER_TERMINATED);
manager_->WorkerCreated(3, 2, instance);
CheckWorkerState(3, 2, WorkerState::WORKER_UNINSPECTED);
- agent_host = NULL;
+ agent_host = nullptr;
CheckWorkerState(3, 2, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerDestroyed(3, 2);
CheckWorkerNotExist(3, 2);
@@ -307,18 +317,18 @@ TEST_F(SharedWorkerDevToolsManagerTest, ReattachTest) {
TEST_F(SharedWorkerDevToolsManagerTest, PauseOnStartTest) {
SharedWorkerInstance instance(
- GURL("http://example.com/w3.js"), std::string(), std::string(),
+ GURL("http://example.com/w3.js"), std::string(),
+ url::Origin::Create(GURL("http://example.com/")), std::string(),
blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic,
browser_context_->GetResourceContext(), partition_id_,
blink::mojom::SharedWorkerCreationContextType::kNonsecure,
- false /* data_saver_enabled */);
+ base::UnguessableToken::Create());
std::unique_ptr<TestDevToolsClientHost> client_host(
new TestDevToolsClientHost());
manager_->WorkerCreated(3, 1, instance);
CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED);
- scoped_refptr<WorkerDevToolsAgentHost> agent_host(
- static_cast<WorkerDevToolsAgentHost*>(
- manager_->GetDevToolsAgentHostForWorker(3, 1)));
+ scoped_refptr<SharedWorkerDevToolsAgentHost> agent_host(
+ GetDevToolsAgentHostForWorker(3, 1));
EXPECT_TRUE(agent_host.get());
CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED);
agent_host->PauseForDebugOnStart();
diff --git a/chromium/content/browser/devtools/site_per_process_devtools_browsertest.cc b/chromium/content/browser/devtools/site_per_process_devtools_browsertest.cc
index 8b976de043f..c40de12c83b 100644
--- a/chromium/content/browser/devtools/site_per_process_devtools_browsertest.cc
+++ b/chromium/content/browser/devtools/site_per_process_devtools_browsertest.cc
@@ -45,9 +45,7 @@ class TestClient: public DevToolsAgentHostClient {
}
}
- void AgentHostClosed(
- DevToolsAgentHost* agent_host,
- bool replaced_with_another_client) override {
+ void AgentHostClosed(DevToolsAgentHost* agent_host) override {
closed_ = true;
}
diff --git a/chromium/content/browser/devtools/worker_devtools_agent_host.cc b/chromium/content/browser/devtools/worker_devtools_agent_host.cc
index 74e75f6cfe5..f7163f24463 100644
--- a/chromium/content/browser/devtools/worker_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/worker_devtools_agent_host.cc
@@ -28,8 +28,8 @@ void WorkerDevToolsAgentHost::AttachSession(DevToolsSession* session) {
}
if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) {
session->SetRenderer(host, nullptr);
- host->Send(new DevToolsAgentMsg_Attach(
- worker_id_.second, GetId(), session->session_id()));
+ host->Send(
+ new DevToolsAgentMsg_Attach(worker_id_.second, session->session_id()));
}
session->SetFallThroughForNotFound(true);
session->AddHandler(base::WrapUnique(new protocol::InspectorHandler()));
@@ -106,9 +106,8 @@ void WorkerDevToolsAgentHost::WorkerReadyForInspection() {
if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) {
for (DevToolsSession* session : sessions()) {
session->SetRenderer(host, nullptr);
- host->Send(new DevToolsAgentMsg_Reattach(worker_id_.second, GetId(),
- session->session_id(),
- session->state_cookie()));
+ host->Send(new DevToolsAgentMsg_Reattach(
+ worker_id_.second, session->session_id(), session->state_cookie()));
for (const auto& pair : session->waiting_messages()) {
int call_id = pair.first;
const DevToolsSession::Message& message = pair.second;
@@ -152,8 +151,10 @@ bool WorkerDevToolsAgentHost::IsTerminated() {
return state_ == WORKER_TERMINATED;
}
-WorkerDevToolsAgentHost::WorkerDevToolsAgentHost(WorkerId worker_id)
- : DevToolsAgentHostImpl(base::GenerateGUID()),
+WorkerDevToolsAgentHost::WorkerDevToolsAgentHost(
+ const base::UnguessableToken& devtools_worker_token,
+ WorkerId worker_id)
+ : DevToolsAgentHostImpl(devtools_worker_token.ToString()),
state_(WORKER_UNINSPECTED),
worker_id_(worker_id) {
WorkerCreated();
diff --git a/chromium/content/browser/devtools/worker_devtools_agent_host.h b/chromium/content/browser/devtools/worker_devtools_agent_host.h
index b77176a36d3..5cbb578c4a2 100644
--- a/chromium/content/browser/devtools/worker_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/worker_devtools_agent_host.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_DEVTOOLS_WORKER_DEVTOOLS_AGENT_HOST_H_
#include "base/macros.h"
+#include "base/unguessable_token.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/common/content_export.h"
#include "ipc/ipc_listener.h"
@@ -42,7 +43,8 @@ class CONTENT_EXPORT WorkerDevToolsAgentHost : public DevToolsAgentHostImpl,
bool IsTerminated();
protected:
- explicit WorkerDevToolsAgentHost(WorkerId worker_id);
+ WorkerDevToolsAgentHost(const base::UnguessableToken& devtools_worker_token,
+ WorkerId worker_id);
~WorkerDevToolsAgentHost() override;
enum WorkerState {
diff --git a/chromium/content/browser/dom_storage/dom_storage_area.cc b/chromium/content/browser/dom_storage/dom_storage_area.cc
index d11eb7049c1..2e4a765ee16 100644
--- a/chromium/content/browser/dom_storage/dom_storage_area.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_area.cc
@@ -304,7 +304,7 @@ DOMStorageArea* DOMStorageArea::ShallowCopy(
DCHECK_NE(kLocalStorageNamespaceId, destination_namespace_id);
auto original_persistent_namespace_ids =
- base::MakeUnique<std::vector<std::string>>();
+ std::make_unique<std::vector<std::string>>();
original_persistent_namespace_ids->push_back(persistent_namespace_id_);
if (original_persistent_namespace_ids_) {
original_persistent_namespace_ids->insert(
@@ -449,7 +449,7 @@ void DOMStorageArea::Shutdown() {
PopulateCommitBatchValues();
}
- map_ = NULL;
+ map_ = nullptr;
if (!backing_)
return;
@@ -735,7 +735,7 @@ void DOMStorageArea::ShutdownInCommitSequence() {
}
commit_batches_.clear();
backing_.reset();
- session_storage_backing_ = NULL;
+ session_storage_backing_ = nullptr;
}
} // namespace content
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 4fd7d350eca..b96f5cc83a6 100644
--- a/chromium/content/browser/dom_storage/dom_storage_area_unittest.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_area_unittest.cc
@@ -105,7 +105,7 @@ INSTANTIATE_TEST_CASE_P(_, DOMStorageAreaParamTest, ::testing::Bool());
TEST_P(DOMStorageAreaParamTest, DOMStorageAreaBasics) {
scoped_refptr<DOMStorageArea> area(
- new DOMStorageArea(1, std::string(), NULL, kOrigin, NULL, NULL));
+ new DOMStorageArea(1, std::string(), nullptr, kOrigin, nullptr, nullptr));
const bool values_cached = GetParam();
area->SetCacheOnlyKeys(!values_cached);
base::string16 old_value;
@@ -175,8 +175,8 @@ TEST_F(DOMStorageAreaTest, BackingDatabaseOpened) {
// No directory, backing should be null.
{
scoped_refptr<DOMStorageArea> area(
- new DOMStorageArea(kOrigin, base::FilePath(), NULL));
- EXPECT_EQ(NULL, area->backing_.get());
+ new DOMStorageArea(kOrigin, base::FilePath(), nullptr));
+ EXPECT_EQ(nullptr, area->backing_.get());
EXPECT_EQ(DOMStorageArea::LOAD_STATE_KEYS_AND_VALUES, area->load_state_);
EXPECT_FALSE(base::PathExists(kExpectedOriginFilePath));
}
@@ -184,16 +184,17 @@ TEST_F(DOMStorageAreaTest, BackingDatabaseOpened) {
// Valid directory and origin but no session storage backing. Backing should
// be null.
{
- scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
- kSessionStorageNamespaceId, std::string(), NULL, kOrigin, NULL, NULL));
- EXPECT_EQ(NULL, area->backing_.get());
+ scoped_refptr<DOMStorageArea> area(
+ new DOMStorageArea(kSessionStorageNamespaceId, std::string(), nullptr,
+ kOrigin, nullptr, nullptr));
+ EXPECT_EQ(nullptr, area->backing_.get());
base::NullableString16 old_value;
EXPECT_TRUE(area->SetItem(kKey, kValue, old_value, &old_value));
ASSERT_TRUE(old_value.is_null());
// Check that saving a value has still left us without a backing database.
- EXPECT_EQ(NULL, area->backing_.get());
+ EXPECT_EQ(nullptr, area->backing_.get());
EXPECT_FALSE(base::PathExists(kExpectedOriginFilePath));
}
@@ -243,7 +244,7 @@ TEST_P(DOMStorageAreaParamTest, ShallowCopyWithBacking) {
scoped_refptr<SessionStorageDatabase> db =
new SessionStorageDatabase(temp_dir.GetPath());
scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
- 1, kNamespaceId, NULL, kOrigin, db.get(),
+ 1, kNamespaceId, nullptr, kOrigin, db.get(),
new MockDOMStorageTaskRunner(base::ThreadTaskRunnerHandle::Get().get())));
EXPECT_TRUE(area->backing_.get());
EXPECT_TRUE(area->session_storage_backing_);
@@ -306,7 +307,7 @@ TEST_P(DOMStorageAreaParamTest, ShallowCopyWithBacking) {
TEST_F(DOMStorageAreaTest, SetCacheOnlyKeysWithoutBacking) {
scoped_refptr<DOMStorageArea> area(
- new DOMStorageArea(1, std::string(), NULL, kOrigin, NULL, NULL));
+ new DOMStorageArea(1, std::string(), nullptr, kOrigin, nullptr, nullptr));
EXPECT_EQ(DOMStorageArea::LOAD_STATE_KEYS_AND_VALUES,
area->desired_load_state_);
EXPECT_FALSE(area->map_->has_only_keys());
diff --git a/chromium/content/browser/dom_storage/dom_storage_browsertest.cc b/chromium/content/browser/dom_storage/dom_storage_browsertest.cc
index 2e5e1265f68..91e83e09320 100644
--- a/chromium/content/browser/dom_storage/dom_storage_browsertest.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_browsertest.cc
@@ -16,6 +16,7 @@
#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_launcher.h"
#include "content/shell/browser/shell.h"
namespace content {
@@ -123,9 +124,7 @@ class DOMStorageMigrationBrowserTest : public DOMStorageBrowserTest {
void SetUpCommandLine(base::CommandLine* command_line) override {
ContentBrowserTest::SetUpCommandLine(command_line);
// Only enable mojo local storage if this is not a PRE_ test.
- const testing::TestInfo* test =
- testing::UnitTest::GetInstance()->current_test_info();
- if (base::StartsWith(test->name(), "PRE_", base::CompareCase::SENSITIVE))
+ if (IsPreTest())
command_line->AppendSwitch(switches::kDisableMojoLocalStorage);
}
};
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 ef9c99b90a7..adc1d1a851f 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_impl.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_context_impl.cc
@@ -42,11 +42,11 @@ namespace {
// Limits on the cache size and number of areas in memory, over which the areas
// are purged.
#if defined(OS_ANDROID)
-const unsigned kMaxStorageAreaCount = 20;
-const size_t kMaxCacheSize = 2 * 1024 * 1024;
+const unsigned kMaxDomStorageAreaCount = 20;
+const size_t kMaxDomStorageCacheSize = 2 * 1024 * 1024;
#else
-const unsigned kMaxStorageAreaCount = 100;
-const size_t kMaxCacheSize = 20 * 1024 * 1024;
+const unsigned kMaxDomStorageAreaCount = 100;
+const size_t kMaxDomStorageCacheSize = 20 * 1024 * 1024;
#endif
const int kSessionStoraceScavengingSeconds = 60;
@@ -107,7 +107,7 @@ DOMStorageContextImpl::~DOMStorageContextImpl() {
// shouldn't happen on this thread.
SessionStorageDatabase* to_release = session_storage_database_.get();
to_release->AddRef();
- session_storage_database_ = NULL;
+ session_storage_database_ = nullptr;
task_runner_->PostShutdownBlockingTask(
FROM_HERE, DOMStorageTaskRunner::COMMIT_SEQUENCE,
base::BindOnce(&SessionStorageDatabase::Release,
@@ -118,7 +118,7 @@ DOMStorageContextImpl::~DOMStorageContextImpl() {
DOMStorageNamespace* DOMStorageContextImpl::GetStorageNamespace(
int64_t namespace_id) {
if (is_shutdown_)
- return NULL;
+ return nullptr;
StorageNamespaceMap::iterator found = namespaces_.find(namespace_id);
if (found == namespaces_.end()) {
if (namespace_id == kLocalStorageNamespaceId) {
@@ -134,7 +134,7 @@ DOMStorageNamespace* DOMStorageContextImpl::GetStorageNamespace(
namespaces_[kLocalStorageNamespaceId] = local;
return local;
}
- return NULL;
+ return nullptr;
}
return found->second.get();
}
@@ -206,7 +206,7 @@ void DOMStorageContextImpl::GetSessionStorageUsage(
void DOMStorageContextImpl::DeleteLocalStorageForPhysicalOrigin(
const GURL& origin_url) {
DCHECK(!is_shutdown_);
- url::Origin origin(origin_url);
+ url::Origin origin = url::Origin::Create(origin_url);
DOMStorageNamespace* local = GetStorageNamespace(kLocalStorageNamespaceId);
std::vector<GURL> origins;
local->GetOriginsWithAreas(&origins);
@@ -214,7 +214,7 @@ void DOMStorageContextImpl::DeleteLocalStorageForPhysicalOrigin(
// deleted as well.
// https://w3c.github.io/webappsec-suborigins/
for (const auto& origin_candidate_url : origins) {
- url::Origin origin_candidate(origin_candidate_url);
+ url::Origin origin_candidate = url::Origin::Create(origin_candidate_url);
// |origin| is guaranteed to be deleted below, so don't delete it until
// then. That is, only suborigins at the same physical origin as |origin|
// should be deleted at this point.
@@ -243,7 +243,7 @@ void DOMStorageContextImpl::DeleteLocalStorage(const GURL& origin_url) {
void DOMStorageContextImpl::DeleteSessionStorage(
const SessionStorageUsageInfo& usage_info) {
DCHECK(!is_shutdown_);
- DOMStorageNamespace* dom_storage_namespace = NULL;
+ DOMStorageNamespace* dom_storage_namespace = nullptr;
std::map<std::string, int64_t>::const_iterator it =
persistent_namespace_id_to_namespace_id_.find(
usage_info.persistent_namespace_id);
@@ -493,9 +493,9 @@ void DOMStorageContextImpl::PurgeMemory(PurgeOption purge_option) {
// Purging is done based on the cache sizes without including the database
// size since it can be expensive trying to estimate the sqlite usage for
// all databases. For low end devices purge all inactive areas.
- if (initial_stats.total_cache_size > kMaxCacheSize)
+ if (initial_stats.total_cache_size > kMaxDomStorageCacheSize)
purge_reason = "SizeLimitExceeded";
- else if (initial_stats.total_area_count > kMaxStorageAreaCount)
+ else if (initial_stats.total_area_count > kMaxDomStorageAreaCount)
purge_reason = "AreaCountLimitExceeded";
else if (is_low_end_device_)
purge_reason = "InactiveOnLowEndDevice";
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 eb4587cfd43..77f4be32c92 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
@@ -13,6 +13,7 @@
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/dom_storage/dom_storage_area.h"
#include "content/browser/dom_storage/dom_storage_namespace.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
@@ -63,7 +64,7 @@ class DOMStorageContextImplTest : public testing::Test {
void VerifySingleOriginRemains(const GURL& origin) {
// Use a new instance to examine the contexts of temp_dir_.
scoped_refptr<DOMStorageContextImpl> context = new DOMStorageContextImpl(
- temp_dir_.GetPath(), base::FilePath(), NULL, NULL);
+ temp_dir_.GetPath(), base::FilePath(), nullptr, nullptr);
std::vector<LocalStorageUsageInfo> infos;
context->GetLocalStorageUsage(&infos, kDontIncludeFileInfo);
ASSERT_EQ(1u, infos.size());
@@ -115,13 +116,13 @@ TEST_F(DOMStorageContextImplTest, UsageInfo) {
->OpenStorageArea(kOrigin)
->SetItem(kKey, kValue, old_value, &old_value));
context_->Shutdown();
- context_ = NULL;
+ context_ = nullptr;
base::RunLoop().RunUntilIdle();
// Create a new context that points to the same directory, see that
// it knows about the origin that we stored data for.
context_ = new DOMStorageContextImpl(temp_dir_.GetPath(), base::FilePath(),
- NULL, NULL);
+ nullptr, nullptr);
context_->GetLocalStorageUsage(&infos, kDontIncludeFileInfo);
EXPECT_EQ(1u, infos.size());
EXPECT_EQ(kOrigin, infos[0].origin);
@@ -150,7 +151,7 @@ TEST_F(DOMStorageContextImplTest, SessionOnly) {
->OpenStorageArea(kSessionOnlyOrigin)
->SetItem(kKey, kValue, old_value, &old_value));
context_->Shutdown();
- context_ = NULL;
+ context_ = nullptr;
base::RunLoop().RunUntilIdle();
// Verify that the session-only origin data is gone.
@@ -169,7 +170,7 @@ TEST_F(DOMStorageContextImplTest, SetForceKeepSessionState) {
->SetItem(kKey, kValue, old_value, &old_value));
context_->SetForceKeepSessionState(); // Should override clear behavior.
context_->Shutdown();
- context_ = NULL;
+ context_ = nullptr;
base::RunLoop().RunUntilIdle();
VerifySingleOriginRemains(kSessionOnlyOrigin);
@@ -204,7 +205,14 @@ TEST_F(DOMStorageContextImplTest, PersistentIds) {
EXPECT_EQ(kClonedPersistentId, cloned_area->persistent_namespace_id_);
}
+// Disable this test on Android as on Android we always delete our old session
+// storage on startup. This is because we don't do any session restoration for
+// the android system. See crbug.com/770307.
+#if defined(OS_ANDROID)
+TEST_F(DOMStorageContextImplTest, DISABLED_DeleteSessionStorage) {
+#else
TEST_F(DOMStorageContextImplTest, DeleteSessionStorage) {
+#endif
// Create a DOMStorageContextImpl which will save sessionStorage on disk.
context_->Shutdown();
context_ =
@@ -229,7 +237,7 @@ TEST_F(DOMStorageContextImplTest, DeleteSessionStorage) {
// Destroy and recreate the DOMStorageContextImpl.
context_->Shutdown();
- context_ = NULL;
+ context_ = nullptr;
base::RunLoop().RunUntilIdle();
context_ =
new DOMStorageContextImpl(temp_dir_.GetPath(), temp_dir_.GetPath(),
@@ -252,7 +260,7 @@ TEST_F(DOMStorageContextImplTest, DeleteSessionStorage) {
// Destroy and recreate again.
context_->Shutdown();
- context_ = NULL;
+ context_ = nullptr;
base::RunLoop().RunUntilIdle();
context_ =
new DOMStorageContextImpl(temp_dir_.GetPath(), temp_dir_.GetPath(),
@@ -268,7 +276,7 @@ TEST_F(DOMStorageContextImplTest, DeleteSessionStorage) {
EXPECT_EQ(0u, area->Length());
dom_namespace->CloseStorageArea(area);
context_->Shutdown();
- context_ = NULL;
+ context_ = nullptr;
base::RunLoop().RunUntilIdle();
}
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 520158f3672..382ccdddff2 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -25,6 +25,7 @@
#include "content/browser/dom_storage/dom_storage_context_impl.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
#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/content_browser_client.h"
#include "content/public/browser/local_storage_usage_info.h"
@@ -49,7 +50,7 @@ void GetLocalStorageUsageHelper(
base::SingleThreadTaskRunner* reply_task_runner,
DOMStorageContextImpl* context,
const DOMStorageContext::GetLocalStorageUsageCallback& callback) {
- auto infos = base::MakeUnique<std::vector<LocalStorageUsageInfo>>();
+ auto infos = std::make_unique<std::vector<LocalStorageUsageInfo>>();
context->GetLocalStorageUsage(infos.get(), true);
reply_task_runner->PostTask(
FROM_HERE, base::BindOnce(&InvokeLocalStorageUsageCallbackHelper,
@@ -135,6 +136,15 @@ DOMStorageContextWrapper::DOMStorageContextWrapper(
storage_dir, special_storage_policy);
}
+ if (base::FeatureList::IsEnabled(features::kMojoSessionStorage)) {
+ base::FilePath session_storage_dir;
+ if (!profile_path.empty())
+ session_storage_dir =
+ local_partition_path.AppendASCII(kSessionStorageDirectory);
+ mojo_session_state_ = std::make_unique<SessionStorageContextMojo>(
+ connector, session_storage_dir);
+ }
+
if (base::FeatureList::IsEnabled(features::kMemoryCoordinator)) {
base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
} else {
@@ -151,7 +161,7 @@ void DOMStorageContextWrapper::GetLocalStorageUsage(
const GetLocalStorageUsageCallback& callback) {
DCHECK(context_.get());
if (mojo_state_) {
- auto infos = base::MakeUnique<std::vector<LocalStorageUsageInfo>>();
+ 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,
@@ -212,7 +222,8 @@ void DOMStorageContextWrapper::DeleteLocalStorageForPhysicalOrigin(
mojo_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&LocalStorageContextMojo::DeleteStorageForPhysicalOrigin,
- base::Unretained(mojo_state_), url::Origin(origin)));
+ base::Unretained(mojo_state_),
+ url::Origin::Create(origin)));
}
}
@@ -228,9 +239,9 @@ void DOMStorageContextWrapper::DeleteLocalStorage(const GURL& origin) {
// as soon as that task is posted, mojo_state_ is set to null, preventing
// further tasks from being queued.
mojo_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&LocalStorageContextMojo::DeleteStorage,
- base::Unretained(mojo_state_), url::Origin(origin)));
+ FROM_HERE, base::BindOnce(&LocalStorageContextMojo::DeleteStorage,
+ base::Unretained(mojo_state_),
+ url::Origin::Create(origin)));
}
}
@@ -331,6 +342,16 @@ void DOMStorageContextWrapper::OpenLocalStorage(
std::move(request)));
}
+void DOMStorageContextWrapper::OpenSessionStorage(
+ int64_t namespace_id,
+ const url::Origin& origin,
+ mojom::LevelDBWrapperRequest request) {
+ if (!mojo_session_state_)
+ return;
+ mojo_session_state_->OpenSessionStorage(namespace_id, origin,
+ std::move(request));
+}
+
void DOMStorageContextWrapper::SetLocalStorageDatabaseForTesting(
leveldb::mojom::LevelDBDatabaseAssociatedPtr database) {
if (!mojo_state_)
@@ -345,6 +366,12 @@ void DOMStorageContextWrapper::SetLocalStorageDatabaseForTesting(
base::Unretained(mojo_state_), std::move(database)));
}
+base::WeakPtr<SessionStorageContextMojo>
+DOMStorageContextWrapper::GetMojoSessionStateWeakPtr() {
+ return mojo_session_state_ ? mojo_session_state_->AsWeakPtr()
+ : base::WeakPtr<SessionStorageContextMojo>();
+}
+
void DOMStorageContextWrapper::OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
DOMStorageContextImpl::PurgeOption purge_option =
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 ef74dc3066b..ccc7d2f2edd 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
+++ b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -12,6 +12,7 @@
#include "base/memory/memory_coordinator_client.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "content/browser/dom_storage/dom_storage_context_impl.h"
#include "content/common/content_export.h"
#include "content/common/storage_partition_service.mojom.h"
@@ -34,6 +35,7 @@ namespace content {
class DOMStorageContextImpl;
class LocalStorageContextMojo;
+class SessionStorageContextMojo;
// This is owned by Storage Partition and encapsulates all its dom storage
// state.
@@ -76,6 +78,9 @@ class CONTENT_EXPORT DOMStorageContextWrapper
// See mojom::StoragePartitionService interface.
void OpenLocalStorage(const url::Origin& origin,
mojom::LevelDBWrapperRequest request);
+ void OpenSessionStorage(int64_t namespace_id,
+ const url::Origin& origin,
+ mojom::LevelDBWrapperRequest request);
void SetLocalStorageDatabaseForTesting(
leveldb::mojom::LevelDBDatabaseAssociatedPtr database);
@@ -88,6 +93,10 @@ class CONTENT_EXPORT DOMStorageContextWrapper
~DOMStorageContextWrapper() override;
DOMStorageContextImpl* context() const { return context_.get(); }
+ SessionStorageContextMojo* mojo_session_state() {
+ return mojo_session_state_.get();
+ }
+ base::WeakPtr<SessionStorageContextMojo> GetMojoSessionStateWeakPtr();
// Called on UI thread when the system is under memory pressure.
void OnMemoryPressure(
@@ -103,6 +112,7 @@ class CONTENT_EXPORT DOMStorageContextWrapper
// asynchronously on the |mojo_task_runner_|.
LocalStorageContextMojo* mojo_state_ = nullptr;
scoped_refptr<base::SingleThreadTaskRunner> mojo_task_runner_;
+ std::unique_ptr<SessionStorageContextMojo> mojo_session_state_;
// To receive memory pressure signals.
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
diff --git a/chromium/content/browser/dom_storage/dom_storage_database.cc b/chromium/content/browser/dom_storage/dom_storage_database.cc
index 2f47c3af03e..5bf7d94dee6 100644
--- a/chromium/content/browser/dom_storage/dom_storage_database.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_database.cc
@@ -304,7 +304,7 @@ bool DOMStorageDatabase::UpgradeVersion1To2() {
}
void DOMStorageDatabase::Close() {
- db_.reset(NULL);
+ db_.reset(nullptr);
}
} // namespace content
diff --git a/chromium/content/browser/dom_storage/dom_storage_host.cc b/chromium/content/browser/dom_storage/dom_storage_host.cc
index a509f08bc34..3f060d3e0ce 100644
--- a/chromium/content/browser/dom_storage/dom_storage_host.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_host.cc
@@ -155,14 +155,14 @@ bool DOMStorageHost::HasAreaOpen(
DOMStorageArea* DOMStorageHost::GetOpenArea(int connection_id) const {
const auto found = connections_.find(connection_id);
if (found == connections_.end())
- return NULL;
+ return nullptr;
return found->second.area_.get();
}
DOMStorageNamespace* DOMStorageHost::GetNamespace(int connection_id) const {
const auto found = connections_.find(connection_id);
if (found == connections_.end())
- return NULL;
+ return nullptr;
return found->second.namespace_.get();
}
diff --git a/chromium/content/browser/dom_storage/dom_storage_message_filter.cc b/chromium/content/browser/dom_storage/dom_storage_message_filter.cc
index 70315b7efaa..6c823a62b9d 100644
--- a/chromium/content/browser/dom_storage/dom_storage_message_filter.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_message_filter.cc
@@ -61,7 +61,7 @@ base::TaskRunner* DOMStorageMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& message) {
if (IPC_MESSAGE_CLASS(message) == DOMStorageMsgStart)
return context_->task_runner();
- return NULL;
+ return nullptr;
}
bool DOMStorageMessageFilter::OnMessageReceived(const IPC::Message& message) {
diff --git a/chromium/content/browser/dom_storage/dom_storage_namespace.cc b/chromium/content/browser/dom_storage/dom_storage_namespace.cc
index 5a44fb6bf15..09a3746ebf2 100644
--- a/chromium/content/browser/dom_storage/dom_storage_namespace.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_namespace.cc
@@ -72,7 +72,7 @@ DOMStorageArea* DOMStorageNamespace::GetOpenStorageArea(const GURL& origin) {
AreaHolder* holder = GetAreaHolder(origin);
if (holder && holder->open_count_)
return holder->area_.get();
- return NULL;
+ return nullptr;
}
DOMStorageNamespace* DOMStorageNamespace::Clone(
@@ -215,7 +215,7 @@ DOMStorageNamespace::AreaHolder*
DOMStorageNamespace::GetAreaHolder(const GURL& origin) {
AreaMap::iterator found = areas_.find(origin);
if (found == areas_.end())
- return NULL;
+ return nullptr;
return &(found->second);
}
diff --git a/chromium/content/browser/dom_storage/dom_storage_session.cc b/chromium/content/browser/dom_storage/dom_storage_session.cc
index 3cdaded64f7..a8a4595a844 100644
--- a/chromium/content/browser/dom_storage/dom_storage_session.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_session.cc
@@ -9,11 +9,15 @@
#include "base/logging.h"
#include "content/browser/dom_storage/dom_storage_context_impl.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
+#include "content/browser/dom_storage/session_storage_context_mojo.h"
namespace content {
-DOMStorageSession::DOMStorageSession(DOMStorageContextImpl* context)
+DOMStorageSession::DOMStorageSession(
+ DOMStorageContextImpl* context,
+ base::WeakPtr<SessionStorageContextMojo> mojo_context)
: context_(context),
+ mojo_context_(mojo_context),
namespace_id_(context->AllocateSessionId()),
persistent_namespace_id_(context->AllocatePersistentSessionId()),
should_persist_(false) {
@@ -21,11 +25,17 @@ DOMStorageSession::DOMStorageSession(DOMStorageContextImpl* context)
FROM_HERE,
base::BindOnce(&DOMStorageContextImpl::CreateSessionNamespace, context_,
namespace_id_, persistent_namespace_id_));
+ if (mojo_context_)
+ mojo_context_->CreateSessionNamespace(namespace_id_,
+ persistent_namespace_id_);
}
-DOMStorageSession::DOMStorageSession(DOMStorageContextImpl* context,
- const std::string& persistent_namespace_id)
+DOMStorageSession::DOMStorageSession(
+ DOMStorageContextImpl* context,
+ base::WeakPtr<SessionStorageContextMojo> mojo_context,
+ const std::string& persistent_namespace_id)
: context_(context),
+ mojo_context_(mojo_context),
namespace_id_(context->AllocateSessionId()),
persistent_namespace_id_(persistent_namespace_id),
should_persist_(false) {
@@ -33,6 +43,9 @@ DOMStorageSession::DOMStorageSession(DOMStorageContextImpl* context,
FROM_HERE,
base::BindOnce(&DOMStorageContextImpl::CreateSessionNamespace, context_,
namespace_id_, persistent_namespace_id_));
+ if (mojo_context_)
+ mojo_context_->CreateSessionNamespace(namespace_id_,
+ persistent_namespace_id_);
}
void DOMStorageSession::SetShouldPersist(bool should_persist) {
@@ -48,25 +61,34 @@ bool DOMStorageSession::IsFromContext(DOMStorageContextImpl* context) {
}
DOMStorageSession* DOMStorageSession::Clone() {
- return CloneFrom(context_.get(), namespace_id_);
+ return CloneFrom(context_.get(), mojo_context_, namespace_id_);
}
// static
-DOMStorageSession* DOMStorageSession::CloneFrom(DOMStorageContextImpl* context,
- int64_t namepace_id_to_clone) {
+DOMStorageSession* DOMStorageSession::CloneFrom(
+ DOMStorageContextImpl* context,
+ base::WeakPtr<SessionStorageContextMojo> mojo_context,
+ int64_t namespace_id_to_clone) {
int64_t clone_id = context->AllocateSessionId();
std::string persistent_clone_id = context->AllocatePersistentSessionId();
context->task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&DOMStorageContextImpl::CloneSessionNamespace, context,
- namepace_id_to_clone, clone_id, persistent_clone_id));
- return new DOMStorageSession(context, clone_id, persistent_clone_id);
+ namespace_id_to_clone, clone_id, persistent_clone_id));
+ if (mojo_context)
+ mojo_context->CloneSessionNamespace(namespace_id_to_clone, clone_id,
+ persistent_clone_id);
+ return new DOMStorageSession(context, std::move(mojo_context), clone_id,
+ persistent_clone_id);
}
-DOMStorageSession::DOMStorageSession(DOMStorageContextImpl* context,
- int64_t namespace_id,
- const std::string& persistent_namespace_id)
+DOMStorageSession::DOMStorageSession(
+ DOMStorageContextImpl* context,
+ base::WeakPtr<SessionStorageContextMojo> mojo_context,
+ int64_t namespace_id,
+ const std::string& persistent_namespace_id)
: context_(context),
+ mojo_context_(mojo_context),
namespace_id_(namespace_id),
persistent_namespace_id_(persistent_namespace_id),
should_persist_(false) {
@@ -77,6 +99,8 @@ DOMStorageSession::~DOMStorageSession() {
context_->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&DOMStorageContextImpl::DeleteSessionNamespace,
context_, namespace_id_, should_persist_));
+ if (mojo_context_)
+ mojo_context_->DeleteSessionNamespace(namespace_id_, should_persist_);
}
} // namespace content
diff --git a/chromium/content/browser/dom_storage/dom_storage_session.h b/chromium/content/browser/dom_storage/dom_storage_session.h
index 08e54f35c1b..352a41e86dc 100644
--- a/chromium/content/browser/dom_storage/dom_storage_session.h
+++ b/chromium/content/browser/dom_storage/dom_storage_session.h
@@ -11,11 +11,13 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
namespace content {
class DOMStorageContextImpl;
+class SessionStorageContextMojo;
// This refcounted class determines the lifetime of a session
// storage namespace and provides an interface to Clone() an
@@ -25,11 +27,14 @@ class CONTENT_EXPORT DOMStorageSession
: public base::RefCountedThreadSafe<DOMStorageSession> {
public:
// Constructs a |DOMStorageSession| and allocates new IDs for it.
- explicit DOMStorageSession(DOMStorageContextImpl* context);
+ explicit DOMStorageSession(
+ DOMStorageContextImpl* context,
+ base::WeakPtr<SessionStorageContextMojo> mojo_context);
// Constructs a |DOMStorageSession| and assigns |persistent_namespace_id|
// to it. Allocates a new non-persistent ID.
DOMStorageSession(DOMStorageContextImpl* context,
+ base::WeakPtr<SessionStorageContextMojo> mojo_context,
const std::string& persistent_namespace_id);
int64_t namespace_id() const { return namespace_id_; }
@@ -43,18 +48,22 @@ class CONTENT_EXPORT DOMStorageSession
// Constructs a |DOMStorageSession| by cloning
// |namespace_id_to_clone|. Allocates new IDs for it.
- static DOMStorageSession* CloneFrom(DOMStorageContextImpl* context,
- int64_t namepace_id_to_clone);
+ static DOMStorageSession* CloneFrom(
+ DOMStorageContextImpl* context,
+ base::WeakPtr<SessionStorageContextMojo> mojo_context,
+ int64_t namepace_id_to_clone);
private:
friend class base::RefCountedThreadSafe<DOMStorageSession>;
DOMStorageSession(DOMStorageContextImpl* context,
+ base::WeakPtr<SessionStorageContextMojo> mojo_context,
int64_t namespace_id,
const std::string& persistent_namespace_id);
~DOMStorageSession();
scoped_refptr<DOMStorageContextImpl> context_;
+ base::WeakPtr<SessionStorageContextMojo> mojo_context_;
int64_t namespace_id_;
std::string persistent_namespace_id_;
bool should_persist_;
diff --git a/chromium/content/browser/dom_storage/local_storage_context_mojo.cc b/chromium/content/browser/dom_storage/local_storage_context_mojo.cc
index 9ff671e719a..ba831708157 100644
--- a/chromium/content/browser/dom_storage/local_storage_context_mojo.cc
+++ b/chromium/content/browser/dom_storage/local_storage_context_mojo.cc
@@ -14,6 +14,7 @@
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "base/trace_event/memory_dump_manager.h"
+#include "build/build_config.h"
#include "components/leveldb/public/cpp/util.h"
#include "components/leveldb/public/interfaces/leveldb.mojom.h"
#include "content/browser/dom_storage/dom_storage_area.h"
@@ -52,7 +53,7 @@ const char kOriginSeparator = '\x00';
const char kDataPrefix[] = "_";
const uint8_t kMetaPrefix[] = {'M', 'E', 'T', 'A', ':'};
const int64_t kMinSchemaVersion = 1;
-const int64_t kCurrentSchemaVersion = 1;
+const int64_t kCurrentLocalStorageSchemaVersion = 1;
// After this many consecutive commit errors we'll throw away the entire
// database.
@@ -61,11 +62,11 @@ const int kCommitErrorThreshold = 8;
// Limits on the cache size and number of areas in memory, over which the areas
// are purged.
#if defined(OS_ANDROID)
-const unsigned kMaxStorageAreaCount = 10;
-const size_t kMaxCacheSize = 2 * 1024 * 1024;
+const unsigned kMaxLocalStorageAreaCount = 10;
+const size_t kMaxLocalStorageCacheSize = 2 * 1024 * 1024;
#else
-const unsigned kMaxStorageAreaCount = 50;
-const size_t kMaxCacheSize = 20 * 1024 * 1024;
+const unsigned kMaxLocalStorageAreaCount = 50;
+const size_t kMaxLocalStorageCacheSize = 20 * 1024 * 1024;
#endif
static const uint8_t kUTF16Format = 0;
@@ -91,7 +92,7 @@ void MigrateStorageHelper(
DOMStorageDatabase db(db_path);
DOMStorageValuesMap map;
db.ReadAllValues(&map);
- auto values = base::MakeUnique<LevelDBWrapperImpl::ValueMap>();
+ auto values = std::make_unique<LevelDBWrapperImpl::ValueMap>();
for (const auto& it : map) {
(*values)[LocalStorageContextMojo::MigrateString(it.first)] =
LocalStorageContextMojo::MigrateString(it.second.string());
@@ -171,19 +172,31 @@ class LocalStorageContextMojo::LevelDBWrapperHolder final
: context_(context), origin_(origin) {
// Delay for a moment after a value is set in anticipation
// of other values being set, so changes are batched.
- const int kCommitDefaultDelaySecs = 5;
+ constexpr base::TimeDelta kCommitDefaultDelaySecs =
+ base::TimeDelta::FromSeconds(5);
// To avoid excessive IO we apply limits to the amount of data being written
// and the frequency of writes.
const int kMaxBytesPerHour = kPerStorageAreaQuota;
const int kMaxCommitsPerHour = 60;
- level_db_wrapper_ = base::MakeUnique<LevelDBWrapperImpl>(
+ LevelDBWrapperImpl::Options options;
+ options.max_size = kPerStorageAreaQuota + kPerStorageAreaOverQuotaAllowance;
+ options.default_commit_delay = kCommitDefaultDelaySecs;
+ options.max_bytes_per_hour = kMaxBytesPerHour;
+ options.max_commits_per_hour = kMaxCommitsPerHour;
+#if defined(OS_ANDROID)
+ options.cache_mode = LevelDBWrapperImpl::CacheMode::KEYS_ONLY_WHEN_POSSIBLE;
+#else
+ options.cache_mode = LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES;
+ if (base::SysInfo::IsLowEndDevice()) {
+ options.cache_mode =
+ LevelDBWrapperImpl::CacheMode::KEYS_ONLY_WHEN_POSSIBLE;
+ }
+#endif
+ level_db_wrapper_ = std::make_unique<LevelDBWrapperImpl>(
context_->database_.get(),
- kDataPrefix + origin_.Serialize() + kOriginSeparator,
- kPerStorageAreaQuota + kPerStorageAreaOverQuotaAllowance,
- base::TimeDelta::FromSeconds(kCommitDefaultDelaySecs), kMaxBytesPerHour,
- kMaxCommitsPerHour, this);
+ kDataPrefix + origin_.Serialize() + kOriginSeparator, this, options);
level_db_wrapper_ptr_ = level_db_wrapper_.get();
}
@@ -207,7 +220,7 @@ class LocalStorageContextMojo::LevelDBWrapperHolder final
item->type = leveldb::mojom::BatchOperationType::PUT_KEY;
item->key = leveldb::StdStringToUint8Vector(kVersionKey);
item->value = leveldb::StdStringToUint8Vector(
- base::Int64ToString(kCurrentSchemaVersion));
+ base::Int64ToString(kCurrentLocalStorageSchemaVersion));
operations.push_back(std::move(item));
context_->database_initialized_ = true;
}
@@ -222,7 +235,7 @@ class LocalStorageContextMojo::LevelDBWrapperHolder final
item->type = leveldb::mojom::BatchOperationType::PUT_KEY;
LocalStorageOriginMetaData data;
data.set_last_modified(base::Time::Now().ToInternalValue());
- data.set_size_bytes(level_db_wrapper()->bytes_used());
+ data.set_size_bytes(level_db_wrapper()->storage_used());
item->value = leveldb::StdStringToUint8Vector(data.SerializeAsString());
}
operations.push_back(std::move(item));
@@ -444,8 +457,16 @@ void LocalStorageContextMojo::ShutdownAndDelete() {
connection_state_ = CONNECTION_SHUTDOWN;
// Flush any uncommitted data.
- for (const auto& it : level_db_wrappers_)
- it.second->level_db_wrapper()->ScheduleImmediateCommit();
+ for (const auto& it : level_db_wrappers_) {
+ auto* wrapper = it.second->level_db_wrapper();
+ LOCAL_HISTOGRAM_BOOLEAN(
+ "LocalStorageContext.ShutdownAndDelete.MaybeDroppedChanges",
+ wrapper->has_pending_load_tasks());
+ wrapper->ScheduleImmediateCommit();
+ // TODO(dmurph): Monitor the above histogram, and if dropping changes is
+ // common then handle that here.
+ wrapper->CancelAllPendingRequests();
+ }
// Respect the content policy settings about what to
// keep and what to discard.
@@ -498,9 +519,9 @@ void LocalStorageContextMojo::PurgeUnusedWrappersIfNeeded() {
CachePurgeReason purge_reason = CachePurgeReason::NotNeeded;
- if (total_cache_size > kMaxCacheSize)
+ if (total_cache_size > kMaxLocalStorageCacheSize)
purge_reason = CachePurgeReason::SizeLimitExceeded;
- else if (level_db_wrappers_.size() > kMaxStorageAreaCount)
+ else if (level_db_wrappers_.size() > kMaxLocalStorageAreaCount)
purge_reason = CachePurgeReason::AreaCountLimitExceeded;
else if (is_low_end_device_)
purge_reason = CachePurgeReason::InactiveOnLowEndDevice;
@@ -735,7 +756,8 @@ void LocalStorageContextMojo::OnGotDatabaseVersion(
int64_t db_version;
if (!base::StringToInt64(leveldb::Uint8VectorToStdString(value),
&db_version) ||
- db_version < kMinSchemaVersion || db_version > kCurrentSchemaVersion) {
+ db_version < kMinSchemaVersion ||
+ db_version > kCurrentLocalStorageSchemaVersion) {
LogDatabaseOpenResult(OpenResult::INVALID_VERSION);
DeleteAndRecreateDatabase(
"LocalStorageContext.OpenResultAfterInvalidVersion");
@@ -782,8 +804,10 @@ void LocalStorageContextMojo::OnConnectionFinished() {
void LocalStorageContextMojo::DeleteAndRecreateDatabase(
const char* histogram_name) {
- // We're about to set database_ to null, so delete and LevelDBWrappers
+ // We're about to set database_ to null, so delete the LevelDBWrappers
// that might still be using the old database.
+ for (const auto& it : level_db_wrappers_)
+ it.second->level_db_wrapper()->CancelAllPendingRequests();
level_db_wrappers_.clear();
// Reset state to be in process of connecting. This will cause requests for
@@ -863,7 +887,7 @@ LocalStorageContextMojo::GetOrCreateDBWrapper(const url::Origin& origin) {
PurgeUnusedWrappersIfNeeded();
- auto holder = base::MakeUnique<LevelDBWrapperHolder>(this, origin);
+ auto holder = std::make_unique<LevelDBWrapperHolder>(this, origin);
LevelDBWrapperHolder* holder_ptr = holder.get();
level_db_wrappers_[origin] = std::move(holder);
return holder_ptr;
@@ -903,7 +927,7 @@ void LocalStorageContextMojo::OnGotMetaData(
LocalStorageUsageInfo info;
info.origin = GURL(leveldb::Uint8VectorToStdString(row->key).substr(
arraysize(kMetaPrefix)));
- origins.insert(url::Origin(info.origin));
+ origins.insert(url::Origin::Create(info.origin));
if (!info.origin.is_valid()) {
// TODO(mek): Deal with database corruption.
continue;
@@ -941,7 +965,7 @@ void LocalStorageContextMojo::OnGotStorageUsageForDeletePhysicalOrigin(
const url::Origin& origin,
std::vector<LocalStorageUsageInfo> usage) {
for (const auto& info : usage) {
- url::Origin origin_candidate(info.origin);
+ url::Origin origin_candidate = url::Origin::Create(info.origin);
if (!origin_candidate.IsSameOriginWith(origin) &&
origin_candidate.IsSamePhysicalOriginWith(origin))
DeleteStorage(origin_candidate);
@@ -958,7 +982,7 @@ void LocalStorageContextMojo::OnGotStorageUsageForShutdown(
if (!special_storage_policy_->IsStorageSessionOnly(info.origin))
continue;
- AddDeleteOriginOperations(&operations, url::Origin(info.origin));
+ AddDeleteOriginOperations(&operations, url::Origin::Create(info.origin));
}
if (!operations.empty()) {
@@ -981,7 +1005,7 @@ void LocalStorageContextMojo::GetStatistics(size_t* total_cache_size,
*total_cache_size = 0;
*unused_wrapper_count = 0;
for (const auto& it : level_db_wrappers_) {
- *total_cache_size += it.second->level_db_wrapper()->bytes_used();
+ *total_cache_size += it.second->level_db_wrapper()->memory_used();
if (!it.second->has_bindings())
(*unused_wrapper_count)++;
}
diff --git a/chromium/content/browser/dom_storage/local_storage_context_mojo.h b/chromium/content/browser/dom_storage/local_storage_context_mojo.h
index 0dda7b23b70..e1005726733 100644
--- a/chromium/content/browser/dom_storage/local_storage_context_mojo.h
+++ b/chromium/content/browser/dom_storage/local_storage_context_mojo.h
@@ -5,9 +5,15 @@
#ifndef CONTENT_BROWSER_DOM_STORAGE_LOCAL_STORAGE_CONTEXT_MOJO_H_
#define CONTENT_BROWSER_DOM_STORAGE_LOCAL_STORAGE_CONTEXT_MOJO_H_
+#include <stdint.h>
+#include <map>
#include <memory>
+#include <string>
+#include <vector>
+#include "base/callback_forward.h"
#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
#include "base/trace_event/memory_dump_provider.h"
#include "content/common/content_export.h"
#include "content/common/leveldb_wrapper.mojom.h"
diff --git a/chromium/content/browser/dom_storage/local_storage_context_mojo_unittest.cc b/chromium/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
index 012fd36e506..e8357d8143f 100644
--- a/chromium/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
+++ b/chromium/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
@@ -22,7 +22,7 @@
#include "content/public/browser/local_storage_usage_info.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
-#include "content/test/mock_leveldb_database.h"
+#include "content/test/fake_leveldb_database.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
@@ -47,6 +47,14 @@ namespace {
void NoOpSuccess(bool success) {}
+void SuccessCallback(base::OnceClosure callback,
+ bool* success_out,
+ bool success) {
+ if (success_out)
+ *success_out = success;
+ std::move(callback).Run();
+}
+
void GetStorageUsageCallback(const base::Closure& callback,
std::vector<LocalStorageUsageInfo>* out_result,
std::vector<LocalStorageUsageInfo> result) {
@@ -118,17 +126,25 @@ class TestLevelDBObserver : public mojom::LevelDBObserver {
class GetAllCallback : public mojom::LevelDBWrapperGetAllCallback {
public:
- static mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo CreateAndBind() {
+ static mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo CreateAndBind(
+ base::OnceClosure callback) {
mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo ptr_info;
auto request = mojo::MakeRequest(&ptr_info);
- mojo::MakeStrongAssociatedBinding(base::WrapUnique(new GetAllCallback),
- std::move(request));
+ mojo::MakeStrongAssociatedBinding(
+ base::WrapUnique(new GetAllCallback(std::move(callback))),
+ std::move(request));
return ptr_info;
}
private:
- GetAllCallback() {}
- void Complete(bool success) override {}
+ GetAllCallback(base::OnceClosure callback) : callback_(std::move(callback)) {}
+
+ void Complete(bool success) override {
+ EXPECT_TRUE(success);
+ std::move(callback_).Run();
+ }
+
+ base::OnceClosure callback_;
};
} // namespace
@@ -161,7 +177,7 @@ class LocalStorageContextMojoTest : public testing::Test {
special_storage_policy());
leveldb::mojom::LevelDBDatabaseAssociatedPtr database_ptr;
leveldb::mojom::LevelDBDatabaseAssociatedRequest request =
- MakeIsolatedRequest(&database_ptr);
+ MakeRequestAssociatedWithDedicatedPipe(&database_ptr);
context_->SetDatabaseForTesting(std::move(database_ptr));
db_binding_.Bind(std::move(request));
}
@@ -207,11 +223,28 @@ class LocalStorageContextMojoTest : public testing::Test {
return result;
}
+ base::Optional<std::vector<uint8_t>> DoTestGet(
+ const std::vector<uint8_t>& key) {
+ const url::Origin kOrigin = url::Origin::Create(GURL("http://foobar.com"));
+ mojom::LevelDBWrapperPtr wrapper;
+ mojom::LevelDBWrapperPtr dummy_wrapper; // To make sure values are cached.
+ context()->OpenLocalStorage(kOrigin, MakeRequest(&wrapper));
+ context()->OpenLocalStorage(kOrigin, MakeRequest(&dummy_wrapper));
+ base::RunLoop run_loop;
+ bool success = false;
+ std::vector<uint8_t> result;
+ wrapper->Get(key, base::BindOnce(&GetCallback, run_loop.QuitClosure(),
+ &success, &result));
+ run_loop.Run();
+ return success ? base::Optional<std::vector<uint8_t>>(result)
+ : base::nullopt;
+ }
+
private:
TestBrowserThreadBundle thread_bundle_;
base::ScopedTempDir temp_path_;
std::map<std::vector<uint8_t>, std::vector<uint8_t>> mock_data_;
- MockLevelDBDatabase db_;
+ FakeLevelDBDatabase db_;
mojo::AssociatedBinding<leveldb::mojom::LevelDBDatabase> db_binding_;
scoped_refptr<MockDOMStorageTaskRunner> task_runner_;
@@ -229,7 +262,7 @@ TEST_F(LocalStorageContextMojoTest, Basic) {
auto value = StdStringToUint8Vector("value");
mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ context()->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper));
wrapper->Put(key, value, base::nullopt, "source",
base::BindOnce(&NoOpSuccess));
@@ -243,8 +276,8 @@ TEST_F(LocalStorageContextMojoTest, Basic) {
}
TEST_F(LocalStorageContextMojoTest, OriginsAreIndependent) {
- url::Origin origin1(GURL("http://foobar.com:123"));
- url::Origin origin2(GURL("http://foobar.com:1234"));
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com:123"));
+ url::Origin origin2 = url::Origin::Create(GURL("http://foobar.com:1234"));
auto key1 = StdStringToUint8Vector("4key");
auto key2 = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
@@ -270,11 +303,14 @@ TEST_F(LocalStorageContextMojoTest, WrapperOutlivesMojoConnection) {
// Write some data to the DB.
mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
+ mojom::LevelDBWrapperPtr dummy_wrapper; // To make sure values are cached.
+ const url::Origin kOrigin(url::Origin::Create(GURL("http://foobar.com")));
+ context()->OpenLocalStorage(kOrigin, MakeRequest(&wrapper));
+ context()->OpenLocalStorage(kOrigin, MakeRequest(&dummy_wrapper));
wrapper->Put(key, value, base::nullopt, "source",
base::BindOnce(&NoOpSuccess));
wrapper.reset();
+ dummy_wrapper.reset();
base::RunLoop().RunUntilIdle();
// Clear all the data from the backing database.
@@ -283,36 +319,13 @@ TEST_F(LocalStorageContextMojoTest, WrapperOutlivesMojoConnection) {
// Data should still be readable, because despite closing the wrapper
// connection above, the actual wrapper instance should have been kept alive.
- {
- base::RunLoop run_loop;
- bool success = false;
- std::vector<uint8_t> result;
- context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
- wrapper->Get(key, base::BindOnce(&GetCallback, run_loop.QuitClosure(),
- &success, &result));
- run_loop.Run();
- EXPECT_TRUE(success);
- EXPECT_EQ(value, result);
- wrapper.reset();
- }
+ EXPECT_EQ(value, DoTestGet(key));
// Now purge memory.
context()->PurgeMemory();
// And make sure caches were actually cleared.
- {
- base::RunLoop run_loop;
- bool success = false;
- std::vector<uint8_t> result;
- context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
- wrapper->Get(key, base::BindOnce(&GetCallback, run_loop.QuitClosure(),
- &success, &result));
- run_loop.Run();
- EXPECT_FALSE(success);
- wrapper.reset();
- }
+ EXPECT_EQ(base::nullopt, DoTestGet(key));
}
TEST_F(LocalStorageContextMojoTest, OpeningWrappersPurgesInactiveWrappers) {
@@ -321,7 +334,7 @@ TEST_F(LocalStorageContextMojoTest, OpeningWrappersPurgesInactiveWrappers) {
// Write some data to the DB.
mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ context()->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper));
wrapper->Put(key, value, base::nullopt, "source",
base::BindOnce(&NoOpSuccess));
@@ -334,76 +347,33 @@ TEST_F(LocalStorageContextMojoTest, OpeningWrappersPurgesInactiveWrappers) {
// Now open many new wrappers (for different origins) to trigger clean up.
for (int i = 1; i <= 100; ++i) {
- context()->OpenLocalStorage(
- url::Origin(GURL(base::StringPrintf("http://example.com:%d", i))),
- MakeRequest(&wrapper));
+ context()->OpenLocalStorage(url::Origin::Create(GURL(base::StringPrintf(
+ "http://example.com:%d", i))),
+ MakeRequest(&wrapper));
wrapper.reset();
}
// And make sure caches were actually cleared.
- base::RunLoop run_loop;
- bool success = true;
- std::vector<uint8_t> result;
- context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
- wrapper->Get(key, base::BindOnce(&GetCallback, run_loop.QuitClosure(),
- &success, &result));
- run_loop.Run();
- EXPECT_FALSE(success);
- wrapper.reset();
+ EXPECT_EQ(base::nullopt, DoTestGet(key));
}
TEST_F(LocalStorageContextMojoTest, ValidVersion) {
set_mock_data("VERSION", "1");
set_mock_data(std::string("_http://foobar.com") + '\x00' + "key", "value");
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
-
- base::RunLoop run_loop;
- bool success = false;
- std::vector<uint8_t> result;
- wrapper->Get(
- StdStringToUint8Vector("key"),
- base::BindOnce(&GetCallback, run_loop.QuitClosure(), &success, &result));
- run_loop.Run();
- EXPECT_TRUE(success);
- EXPECT_EQ(StdStringToUint8Vector("value"), result);
+ EXPECT_EQ(StdStringToUint8Vector("value"),
+ DoTestGet(StdStringToUint8Vector("key")));
}
TEST_F(LocalStorageContextMojoTest, InvalidVersion) {
set_mock_data("VERSION", "foobar");
set_mock_data(std::string("_http://foobar.com") + '\x00' + "key", "value");
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
-
- base::RunLoop run_loop;
- bool success = false;
- std::vector<uint8_t> result;
- wrapper->Get(
- StdStringToUint8Vector("key"),
- base::BindOnce(&GetCallback, run_loop.QuitClosure(), &success, &result));
- run_loop.Run();
- EXPECT_FALSE(success);
+ EXPECT_EQ(base::nullopt, DoTestGet(StdStringToUint8Vector("key")));
}
TEST_F(LocalStorageContextMojoTest, VersionOnlyWrittenOnCommit) {
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
-
- base::RunLoop run_loop;
- bool success = false;
- std::vector<uint8_t> result;
- wrapper->Get(
- StdStringToUint8Vector("key"),
- base::BindOnce(&GetCallback, run_loop.QuitClosure(), &success, &result));
- run_loop.Run();
- EXPECT_FALSE(success);
- wrapper.reset();
+ EXPECT_EQ(base::nullopt, DoTestGet(StdStringToUint8Vector("key")));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(mock_data().empty());
@@ -415,8 +385,8 @@ TEST_F(LocalStorageContextMojoTest, GetStorageUsage_NoData) {
}
TEST_F(LocalStorageContextMojoTest, GetStorageUsage_Data) {
- url::Origin origin1(GURL("http://foobar.com"));
- url::Origin origin2(GURL("http://example.com"));
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ url::Origin origin2 = url::Origin::Create(GURL("http://example.com"));
auto key1 = StdStringToUint8Vector("key1");
auto key2 = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
@@ -440,10 +410,10 @@ TEST_F(LocalStorageContextMojoTest, GetStorageUsage_Data) {
// that used localstorage with zero size.
std::vector<LocalStorageUsageInfo> info = GetStorageUsageSync();
ASSERT_EQ(2u, info.size());
- if (url::Origin(info[0].origin) == origin2)
+ if (url::Origin::Create(info[0].origin) == origin2)
std::swap(info[0], info[1]);
- EXPECT_EQ(origin1, url::Origin(info[0].origin));
- EXPECT_EQ(origin2, url::Origin(info[1].origin));
+ EXPECT_EQ(origin1, url::Origin::Create(info[0].origin));
+ EXPECT_EQ(origin2, url::Origin::Create(info[1].origin));
EXPECT_LE(before_write, info[0].last_modified);
EXPECT_LE(before_write, info[1].last_modified);
EXPECT_EQ(0u, info[0].data_size);
@@ -456,10 +426,10 @@ TEST_F(LocalStorageContextMojoTest, GetStorageUsage_Data) {
info = GetStorageUsageSync();
ASSERT_EQ(2u, info.size());
- if (url::Origin(info[0].origin) == origin2)
+ if (url::Origin::Create(info[0].origin) == origin2)
std::swap(info[0], info[1]);
- EXPECT_EQ(origin1, url::Origin(info[0].origin));
- EXPECT_EQ(origin2, url::Origin(info[1].origin));
+ EXPECT_EQ(origin1, url::Origin::Create(info[0].origin));
+ EXPECT_EQ(origin2, url::Origin::Create(info[1].origin));
EXPECT_LE(before_write, info[0].last_modified);
EXPECT_LE(before_write, info[1].last_modified);
EXPECT_GE(after_write, info[0].last_modified);
@@ -468,8 +438,8 @@ TEST_F(LocalStorageContextMojoTest, GetStorageUsage_Data) {
}
TEST_F(LocalStorageContextMojoTest, MetaDataClearedOnDelete) {
- url::Origin origin1(GURL("http://foobar.com"));
- url::Origin origin2(GURL("http://example.com"));
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ url::Origin origin2 = url::Origin::Create(GURL("http://example.com"));
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
@@ -503,8 +473,8 @@ TEST_F(LocalStorageContextMojoTest, MetaDataClearedOnDelete) {
}
TEST_F(LocalStorageContextMojoTest, MetaDataClearedOnDeleteAll) {
- url::Origin origin1(GURL("http://foobar.com"));
- url::Origin origin2(GURL("http://example.com"));
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ url::Origin origin2 = url::Origin::Create(GURL("http://example.com"));
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
@@ -542,14 +512,14 @@ TEST_F(LocalStorageContextMojoTest, DeleteStorage) {
set_mock_data("VERSION", "1");
set_mock_data(std::string("_http://foobar.com") + '\x00' + "key", "value");
- context()->DeleteStorage(url::Origin(GURL("http://foobar.com")));
+ context()->DeleteStorage(url::Origin::Create(GURL("http://foobar.com")));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, mock_data().size());
}
TEST_F(LocalStorageContextMojoTest, DeleteStorageWithoutConnection) {
- url::Origin origin1(GURL("http://foobar.com"));
- url::Origin origin2(GURL("http://example.com"));
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ url::Origin origin2 = url::Origin::Create(GURL("http://example.com"));
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
@@ -585,8 +555,8 @@ TEST_F(LocalStorageContextMojoTest, DeleteStorageWithoutConnection) {
}
TEST_F(LocalStorageContextMojoTest, DeleteStorageNotifiesWrapper) {
- url::Origin origin1(GURL("http://foobar.com"));
- url::Origin origin2(GURL("http://example.com"));
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ url::Origin origin2 = url::Origin::Create(GURL("http://example.com"));
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
@@ -631,8 +601,8 @@ TEST_F(LocalStorageContextMojoTest, DeleteStorageNotifiesWrapper) {
}
TEST_F(LocalStorageContextMojoTest, DeleteStorageWithPendingWrites) {
- url::Origin origin1(GURL("http://foobar.com"));
- url::Origin origin2(GURL("http://example.com"));
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ url::Origin origin2 = url::Origin::Create(GURL("http://example.com"));
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
@@ -681,9 +651,10 @@ TEST_F(LocalStorageContextMojoTest, DeleteStorageWithPendingWrites) {
}
TEST_F(LocalStorageContextMojoTest, DeleteStorageForPhysicalOrigin) {
- url::Origin origin1a(GURL("http://foobar.com"));
- url::Origin origin1b(GURL("http-so://suborigin.foobar.com"));
- url::Origin origin2(GURL("https://foobar.com"));
+ url::Origin origin1a = url::Origin::Create(GURL("http://foobar.com"));
+ url::Origin origin1b =
+ url::Origin::Create(GURL("http-so://suborigin.foobar.com"));
+ url::Origin origin2 = url::Origin::Create(GURL("https://foobar.com"));
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
@@ -725,8 +696,8 @@ TEST_F(LocalStorageContextMojoTest, DeleteStorageForPhysicalOrigin) {
}
TEST_F(LocalStorageContextMojoTest, Migration) {
- url::Origin origin1(GURL("http://foobar.com"));
- url::Origin origin2(GURL("http://example.com"));
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ url::Origin origin2 = url::Origin::Create(GURL("http://example.com"));
base::string16 key = base::ASCIIToUTF16("key");
base::string16 value = base::ASCIIToUTF16("value");
base::string16 key2 = base::ASCIIToUTF16("key2");
@@ -744,13 +715,17 @@ TEST_F(LocalStorageContextMojoTest, Migration) {
// Opening origin2 and accessing its data should not migrate anything.
mojom::LevelDBWrapperPtr wrapper;
context()->OpenLocalStorage(origin2, MakeRequest(&wrapper));
+ mojom::LevelDBWrapperPtr dummy_wrapper; // To make sure values are cached.
+ context()->OpenLocalStorage(origin2, MakeRequest(&dummy_wrapper));
wrapper->Get(std::vector<uint8_t>(), base::BindOnce(&NoOpGet));
wrapper.reset();
+ dummy_wrapper.reset();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(mock_data().empty());
// Opening origin1 and accessing its data should migrate its storage.
context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
+ context()->OpenLocalStorage(origin1, MakeRequest(&dummy_wrapper));
wrapper->Get(std::vector<uint8_t>(), base::BindOnce(&NoOpGet));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(mock_data().empty());
@@ -813,8 +788,11 @@ TEST_F(LocalStorageContextMojoTest, FixUp) {
"value3");
mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ mojom::LevelDBWrapperPtr dummy_wrapper; // To make sure values are cached.
+ context()->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper));
+ context()->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
+ MakeRequest(&dummy_wrapper));
{
base::RunLoop run_loop;
@@ -850,8 +828,8 @@ TEST_F(LocalStorageContextMojoTest, FixUp) {
}
TEST_F(LocalStorageContextMojoTest, ShutdownClearsData) {
- url::Origin origin1(GURL("http://foobar.com"));
- url::Origin origin2(GURL("http://example.com"));
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ url::Origin origin2 = url::Origin::Create(GURL("http://example.com"));
auto key1 = StdStringToUint8Vector("key1");
auto key2 = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
@@ -932,8 +910,7 @@ class ServiceTestClient : public service_manager::test::ServiceTestClient,
class LocalStorageContextMojoTestWithService
: public service_manager::test::ServiceTest {
public:
- LocalStorageContextMojoTestWithService()
- : ServiceTest("content_unittests", false) {}
+ LocalStorageContextMojoTestWithService() : ServiceTest("content_unittests") {}
~LocalStorageContextMojoTestWithService() override {}
protected:
@@ -951,7 +928,7 @@ class LocalStorageContextMojoTestWithService
}
std::unique_ptr<service_manager::Service> CreateService() override {
- return base::MakeUnique<ServiceTestClient>(this);
+ return std::make_unique<ServiceTestClient>(this);
}
const base::FilePath& temp_path() { return temp_path_.GetPath(); }
@@ -967,10 +944,15 @@ class LocalStorageContextMojoTestWithService
const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value) {
mojom::LevelDBWrapperPtr wrapper;
- context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ bool success = false;
+ base::RunLoop run_loop;
+ context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source",
- base::BindOnce(&NoOpSuccess));
+ wrapper->Put(
+ key, value, base::nullopt, "source",
+ base::BindOnce(&SuccessCallback, run_loop.QuitClosure(), &success));
+ run_loop.Run();
+ EXPECT_TRUE(success);
wrapper.reset();
base::RunLoop().RunUntilIdle();
}
@@ -979,14 +961,29 @@ class LocalStorageContextMojoTestWithService
const std::vector<uint8_t>& key,
std::vector<uint8_t>* result) {
mojom::LevelDBWrapperPtr wrapper;
- context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper));
+
base::RunLoop run_loop;
- bool success = false;
- wrapper->Get(key, base::BindOnce(&GetCallback, run_loop.QuitClosure(),
- &success, result));
+ std::vector<content::mojom::KeyValuePtr> data;
+ auto callback = [](std::vector<content::mojom::KeyValuePtr>* data_out,
+ leveldb::mojom::DatabaseError status,
+ std::vector<content::mojom::KeyValuePtr> data) {
+ EXPECT_EQ(status, leveldb::mojom::DatabaseError::OK);
+ data_out->swap(data);
+ };
+ wrapper->GetAll(GetAllCallback::CreateAndBind(run_loop.QuitClosure()),
+ base::BindOnce(callback, &data));
run_loop.Run();
- return success;
+
+ for (auto& entry : data) {
+ if (key == entry->key) {
+ *result = std::move(entry->value);
+ return true;
+ }
+ }
+ result->clear();
+ return false;
}
private:
@@ -1003,7 +1000,7 @@ TEST_F(LocalStorageContextMojoTestWithService, InMemory) {
auto value = StdStringToUint8Vector("value");
mojom::LevelDBWrapperPtr wrapper;
- context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper));
DoTestPut(context, key, value);
std::vector<uint8_t> result;
@@ -1033,7 +1030,7 @@ TEST_F(LocalStorageContextMojoTestWithService, InMemoryInvalidPath) {
auto value = StdStringToUint8Vector("value");
mojom::LevelDBWrapperPtr wrapper;
- context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper));
DoTestPut(context, key, value);
@@ -1078,13 +1075,7 @@ TEST_F(LocalStorageContextMojoTestWithService, OnDisk) {
context->ShutdownAndDelete();
}
-// Flaky on Android. https://crbug.com/756550
-#if defined(OS_ANDROID)
-#define MAYBE_InvalidVersionOnDisk DISABLED_InvalidVersionOnDisk
-#else
-#define MAYBE_InvalidVersionOnDisk InvalidVersionOnDisk
-#endif
-TEST_F(LocalStorageContextMojoTestWithService, MAYBE_InvalidVersionOnDisk) {
+TEST_F(LocalStorageContextMojoTestWithService, InvalidVersionOnDisk) {
base::FilePath test_path(FILE_PATH_LITERAL("test_path"));
// Create context and add some data to it.
@@ -1192,7 +1183,7 @@ TEST_F(LocalStorageContextMojoTestWithService, CorruptionOnDisk) {
namespace {
-class MockLevelDBService : public leveldb::mojom::LevelDBService {
+class FakeLevelDBService : public leveldb::mojom::LevelDBService {
public:
void Open(filesystem::mojom::DirectoryPtr,
const std::string& dbname,
@@ -1263,11 +1254,11 @@ class MockLevelDBService : public leveldb::mojom::LevelDBService {
mojo::BindingSet<leveldb::mojom::LevelDBService> bindings_;
};
-class MockLevelDBDatabaseErrorOnWrite : public MockLevelDBDatabase {
+class FakeLevelDBDatabaseErrorOnWrite : public FakeLevelDBDatabase {
public:
- explicit MockLevelDBDatabaseErrorOnWrite(
+ explicit FakeLevelDBDatabaseErrorOnWrite(
std::map<std::vector<uint8_t>, std::vector<uint8_t>>* mock_data)
- : MockLevelDBDatabase(mock_data) {}
+ : FakeLevelDBDatabase(mock_data) {}
void Write(std::vector<leveldb::mojom::BatchedOperationPtr> operations,
WriteCallback callback) override {
@@ -1278,10 +1269,10 @@ class MockLevelDBDatabaseErrorOnWrite : public MockLevelDBDatabase {
} // namespace
TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
- MockLevelDBService mock_leveldb_service;
+ FakeLevelDBService mock_leveldb_service;
service_manager::ServiceContext::SetGlobalBinderForTesting(
file::mojom::kServiceName, leveldb::mojom::LevelDBService::Name_,
- base::Bind(&MockLevelDBService::Bind,
+ base::Bind(&FakeLevelDBService::Bind,
base::Unretained(&mock_leveldb_service)));
std::map<std::vector<uint8_t>, std::vector<uint8_t>> test_data;
@@ -1302,11 +1293,11 @@ TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
{
base::RunLoop loop;
mock_leveldb_service.on_open_callback_ = loop.QuitClosure();
- context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper1));
- context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper2));
- context->OpenLocalStorage(url::Origin(GURL("http://example.com")),
+ context->OpenLocalStorage(url::Origin::Create(GURL("http://example.com")),
MakeRequest(&wrapper3));
loop.Run();
}
@@ -1322,7 +1313,7 @@ TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
ASSERT_EQ(1u, mock_leveldb_service.open_requests_.size());
auto& open_request = mock_leveldb_service.open_requests_[0];
auto mock_db = mojo::MakeStrongAssociatedBinding(
- base::MakeUnique<MockLevelDBDatabaseErrorOnWrite>(&test_data),
+ std::make_unique<FakeLevelDBDatabaseErrorOnWrite>(&test_data),
std::move(open_request.request));
std::move(open_request.callback).Run(leveldb::mojom::DatabaseError::OK);
mock_leveldb_service.open_requests_.clear();
@@ -1359,7 +1350,8 @@ TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
values_written++;
// And we need to flush after every change. Otherwise changes get batched up
// and only one commit is done some time later.
- context->FlushOriginForTesting(url::Origin(GURL("http://foobar.com")));
+ context->FlushOriginForTesting(
+ url::Origin::Create(GURL("http://foobar.com")));
}
// Make sure all messages to the DB have been processed (Flush above merely
// schedules a commit, but there is no guarantee about those having been
@@ -1377,13 +1369,20 @@ TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
EXPECT_EQ(1u, mock_leveldb_service.destroy_requests_.size());
// Reconnect wrapper1 to the database, and try to read a value.
- context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper1));
- base::RunLoop get_loop;
- std::vector<uint8_t> result;
+ base::RunLoop delete_loop;
bool success = true;
- wrapper1->Get(key, base::BindOnce(&GetCallback, get_loop.QuitClosure(),
- &success, &result));
+ auto callback = [](bool* success_out, const base::Closure& callback,
+ bool success) {
+ *success_out = success;
+ callback.Run();
+ };
+ TestLevelDBObserver observer3;
+ wrapper1->AddObserver(observer3.Bind());
+ wrapper1->Delete(
+ key, base::nullopt, "source",
+ base::BindOnce(callback, &success, delete_loop.QuitClosure()));
// Wait for LocalStorageContextMojo to try to reconnect to the database, and
// connect that new request to a properly functioning database.
@@ -1391,15 +1390,15 @@ TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
ASSERT_EQ(1u, mock_leveldb_service.open_requests_.size());
auto& reopen_request = mock_leveldb_service.open_requests_[0];
mock_db = mojo::MakeStrongAssociatedBinding(
- base::MakeUnique<MockLevelDBDatabase>(&test_data),
+ std::make_unique<FakeLevelDBDatabase>(&test_data),
std::move(reopen_request.request));
std::move(reopen_request.callback).Run(leveldb::mojom::DatabaseError::OK);
mock_leveldb_service.open_requests_.clear();
- // And reading the value from the new wrapper should have failed (as the
+ // And deleting the value from the new wrapper should have failed (as the
// database is empty).
- get_loop.Run();
- EXPECT_FALSE(success);
+ delete_loop.Run();
+ EXPECT_EQ(0u, observer3.observations().size());
wrapper1 = nullptr;
{
@@ -1424,10 +1423,10 @@ TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
TEST_F(LocalStorageContextMojoTestWithService,
DontRecreateOnRepeatedCommitFailure) {
- MockLevelDBService mock_leveldb_service;
+ FakeLevelDBService mock_leveldb_service;
service_manager::ServiceContext::SetGlobalBinderForTesting(
file::mojom::kServiceName, leveldb::mojom::LevelDBService::Name_,
- base::Bind(&MockLevelDBService::Bind,
+ base::Bind(&FakeLevelDBService::Bind,
base::Unretained(&mock_leveldb_service)));
std::map<std::vector<uint8_t>, std::vector<uint8_t>> test_data;
@@ -1445,7 +1444,7 @@ TEST_F(LocalStorageContextMojoTestWithService,
{
base::RunLoop loop;
mock_leveldb_service.on_open_callback_ = loop.QuitClosure();
- context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper));
loop.Run();
}
@@ -1455,7 +1454,7 @@ TEST_F(LocalStorageContextMojoTestWithService,
ASSERT_EQ(1u, mock_leveldb_service.open_requests_.size());
auto& open_request = mock_leveldb_service.open_requests_[0];
auto mock_db = mojo::MakeStrongAssociatedBinding(
- base::MakeUnique<MockLevelDBDatabaseErrorOnWrite>(&test_data),
+ std::make_unique<FakeLevelDBDatabaseErrorOnWrite>(&test_data),
std::move(open_request.request));
std::move(open_request.callback).Run(leveldb::mojom::DatabaseError::OK);
mock_leveldb_service.open_requests_.clear();
@@ -1467,23 +1466,26 @@ TEST_F(LocalStorageContextMojoTestWithService,
mock_leveldb_service.on_open_callback_ = reopen_loop.QuitClosure();
// Repeatedly write data to the database, to trigger enough commit errors.
+ base::Optional<std::vector<uint8_t>> old_value;
while (!wrapper.encountered_error()) {
base::RunLoop put_loop;
// Every write needs to be different to make sure there actually is a
// change to commit.
value[0]++;
wrapper.set_connection_error_handler(put_loop.QuitClosure());
- wrapper->Put(key, value, base::nullopt, "source",
+ wrapper->Put(key, value, old_value, "source",
base::BindOnce(
[](base::Closure quit_closure, bool success) {
EXPECT_TRUE(success);
quit_closure.Run();
},
put_loop.QuitClosure()));
+ old_value = std::vector<uint8_t>(value);
put_loop.RunUntilIdle();
// And we need to flush after every change. Otherwise changes get batched up
// and only one commit is done some time later.
- context->FlushOriginForTesting(url::Origin(GURL("http://foobar.com")));
+ context->FlushOriginForTesting(
+ url::Origin::Create(GURL("http://foobar.com")));
}
// Make sure all messages to the DB have been processed (Flush above merely
// schedules a commit, but there is no guarantee about those having been
@@ -1501,7 +1503,7 @@ TEST_F(LocalStorageContextMojoTestWithService,
ASSERT_EQ(1u, mock_leveldb_service.open_requests_.size());
auto& reopen_request = mock_leveldb_service.open_requests_[0];
mock_db = mojo::MakeStrongAssociatedBinding(
- base::MakeUnique<MockLevelDBDatabaseErrorOnWrite>(&test_data),
+ std::make_unique<FakeLevelDBDatabaseErrorOnWrite>(&test_data),
std::move(reopen_request.request));
std::move(reopen_request.callback).Run(leveldb::mojom::DatabaseError::OK);
mock_leveldb_service.open_requests_.clear();
@@ -1512,15 +1514,16 @@ TEST_F(LocalStorageContextMojoTestWithService,
// Reconnect a wrapper to the database, and repeatedly write data to it again.
// This time all should just keep getting written, and commit errors are
// getting ignored.
- context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+ context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
MakeRequest(&wrapper));
+ old_value = base::nullopt;
for (int i = 0; i < 64; ++i) {
base::RunLoop put_loop;
// Every write needs to be different to make sure there actually is a
// change to commit.
value[0]++;
wrapper.set_connection_error_handler(put_loop.QuitClosure());
- wrapper->Put(key, value, base::nullopt, "source",
+ wrapper->Put(key, value, old_value, "source",
base::BindOnce(
[](base::Closure quit_closure, bool success) {
EXPECT_TRUE(success);
@@ -1528,9 +1531,11 @@ TEST_F(LocalStorageContextMojoTestWithService,
},
put_loop.QuitClosure()));
put_loop.RunUntilIdle();
+ old_value = value;
// And we need to flush after every change. Otherwise changes get batched up
// and only one commit is done some time later.
- context->FlushOriginForTesting(url::Origin(GURL("http://foobar.com")));
+ context->FlushOriginForTesting(
+ url::Origin::Create(GURL("http://foobar.com")));
}
// Make sure all messages to the DB have been processed (Flush above merely
// schedules a commit, but there is no guarantee about those having been
diff --git a/chromium/content/browser/dom_storage/session_storage_context_mojo.cc b/chromium/content/browser/dom_storage/session_storage_context_mojo.cc
new file mode 100644
index 00000000000..7ed27d6e686
--- /dev/null
+++ b/chromium/content/browser/dom_storage/session_storage_context_mojo.cc
@@ -0,0 +1,58 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/dom_storage/session_storage_context_mojo.h"
+
+#include "content/browser/leveldb_wrapper_impl.h"
+#include "content/common/dom_storage/dom_storage_types.h"
+#include "content/public/common/content_features.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+namespace content {
+
+SessionStorageContextMojo::SessionStorageContextMojo(
+ service_manager::Connector* connector,
+ base::FilePath subdirectory)
+ : connector_(connector ? connector->Clone() : nullptr),
+ subdirectory_(std::move(subdirectory)),
+ weak_ptr_factory_(this) {
+ DCHECK(base::FeatureList::IsEnabled(features::kMojoSessionStorage));
+}
+
+SessionStorageContextMojo::~SessionStorageContextMojo() {}
+
+void SessionStorageContextMojo::OpenSessionStorage(
+ int64_t namespace_id,
+ const url::Origin& origin,
+ mojom::LevelDBWrapperRequest request) {
+ NOTREACHED();
+}
+
+void SessionStorageContextMojo::CreateSessionNamespace(
+ int64_t namespace_id,
+ const std::string& persistent_namespace_id) {
+ NOTREACHED();
+}
+
+void SessionStorageContextMojo::CloneSessionNamespace(
+ int64_t namespace_id_to_clone,
+ int64_t clone_namespace_id,
+ const std::string& clone_persistent_namespace_id) {
+ NOTREACHED();
+}
+
+void SessionStorageContextMojo::DeleteSessionNamespace(int64_t namespace_id,
+ bool should_persist) {
+ NOTREACHED();
+}
+
+void SessionStorageContextMojo::PurgeMemory() {
+ NOTREACHED();
+}
+
+void SessionStorageContextMojo::PurgeUnusedWrappersIfNeeded() {
+ NOTREACHED();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/dom_storage/session_storage_context_mojo.h b/chromium/content/browser/dom_storage/session_storage_context_mojo.h
new file mode 100644
index 00000000000..49465ccf7d2
--- /dev/null
+++ b/chromium/content/browser/dom_storage/session_storage_context_mojo.h
@@ -0,0 +1,62 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_CONTEXT_MOJO_H_
+#define CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_CONTEXT_MOJO_H_
+
+#include <stdint.h>
+#include <memory>
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+#include "content/common/leveldb_wrapper.mojom.h"
+#include "url/origin.h"
+
+namespace service_manager {
+class Connector;
+} // namespace service_manager
+
+namespace content {
+
+// Used for mojo-based SessionStorage implementation.
+class CONTENT_EXPORT SessionStorageContextMojo {
+ public:
+ SessionStorageContextMojo(service_manager::Connector* connector,
+ base::FilePath subdirectory);
+ ~SessionStorageContextMojo();
+
+ void OpenSessionStorage(int64_t namespace_id,
+ const url::Origin& origin,
+ mojom::LevelDBWrapperRequest request);
+
+ void CreateSessionNamespace(int64_t namespace_id,
+ const std::string& persistent_namespace_id);
+ void CloneSessionNamespace(int64_t namespace_id_to_clone,
+ int64_t clone_namespace_id,
+ const std::string& clone_persistent_namespace_id);
+ void DeleteSessionNamespace(int64_t namespace_id, bool should_persist);
+
+ // Clears any caches, to free up as much memory as possible. Next access to
+ // storage for a particular origin will reload the data from the database.
+ void PurgeMemory();
+
+ // Clears unused leveldb wrappers, when thresholds are reached.
+ void PurgeUnusedWrappersIfNeeded();
+
+ base::WeakPtr<SessionStorageContextMojo> AsWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+ }
+
+ private:
+ std::unique_ptr<service_manager::Connector> connector_;
+ const base::FilePath subdirectory_;
+
+ base::WeakPtrFactory<SessionStorageContextMojo> weak_ptr_factory_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_CONTEXT_MOJO_H_
diff --git a/chromium/content/browser/dom_storage/session_storage_database.cc b/chromium/content/browser/dom_storage/session_storage_database.cc
index 0d8944ce580..914e7276e50 100644
--- a/chromium/content/browser/dom_storage/session_storage_database.cc
+++ b/chromium/content/browser/dom_storage/session_storage_database.cc
@@ -17,6 +17,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
+#include "build/build_config.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/leveldb_chrome.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
@@ -360,33 +361,23 @@ bool SessionStorageDatabase::ReadNamespacesAndOrigins(
void SessionStorageDatabase::OnMemoryDump(
base::trace_event::ProcessMemoryDump* pmd) {
- std::string db_memory_usage;
- {
- base::AutoLock lock(db_lock_);
- if (!db_)
- return;
-
- bool res =
- db_->GetProperty("leveldb.approximate-memory-usage", &db_memory_usage);
- DCHECK(res);
- }
-
- uint64_t size;
- bool res = base::StringToUint64(db_memory_usage, &size);
- DCHECK(res);
+ base::AutoLock lock(db_lock_);
+ if (!db_)
+ return;
+ // All leveldb databases are already dumped by leveldb_env::DBTracker. Add
+ // an edge to the existing dump.
+ auto* tracker_dump =
+ leveldb_env::DBTracker::GetOrCreateAllocatorDump(pmd, db_.get());
+ if (!tracker_dump)
+ return;
auto* mad = pmd->CreateAllocatorDump(
base::StringPrintf("site_storage/session_storage_0x%" PRIXPTR,
reinterpret_cast<uintptr_t>(this)));
+ pmd->AddOwnershipEdge(mad->guid(), tracker_dump->guid());
mad->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
- base::trace_event::MemoryAllocatorDump::kUnitsBytes, size);
-
- // All leveldb databases are already dumped by leveldb_env::DBTracker. Add
- // an edge to avoid double counting.
- auto* tracker_dump =
- leveldb_env::DBTracker::GetOrCreateAllocatorDump(pmd, db_.get());
- if (tracker_dump)
- pmd->AddOwnershipEdge(mad->guid(), tracker_dump->guid());
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ tracker_dump->GetSizeInternal());
}
bool SessionStorageDatabase::LazyOpen(bool create_if_needed) {
@@ -468,11 +459,19 @@ leveldb::Status SessionStorageDatabase::TryToOpen(
// memory allocation in RAM from a log file recovery.
options.write_buffer_size = 64 * 1024;
options.block_cache = leveldb_chrome::GetSharedWebBlockCache();
- return leveldb_env::OpenDB(options, file_path_.AsUTF8Unsafe(), db);
+
+ std::string db_name = file_path_.AsUTF8Unsafe();
+#if defined(OS_ANDROID)
+ // On Android there is no support for session storage restoring, and since
+ // the restoring code is responsible for database cleanup, we must manually
+ // delete the old database here before we open it.
+ leveldb::DestroyDB(db_name, options);
+#endif
+ return leveldb_env::OpenDB(options, db_name, db);
}
bool SessionStorageDatabase::IsOpen() const {
- return db_.get() != NULL;
+ return db_.get() != nullptr;
}
bool SessionStorageDatabase::CallerErrorCheck(bool ok) const {
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 0811fab4da8..b241ef79195 100644
--- a/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc
+++ b/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc
@@ -6,24 +6,29 @@
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/dom_storage_session.h"
+#include "content/browser/dom_storage/session_storage_context_mojo.h"
namespace content {
SessionStorageNamespaceImpl::SessionStorageNamespaceImpl(
DOMStorageContextWrapper* context)
- : session_(new DOMStorageSession(context->context())) {
-}
+ : session_(new DOMStorageSession(context->context(),
+ context->GetMojoSessionStateWeakPtr())) {}
SessionStorageNamespaceImpl::SessionStorageNamespaceImpl(
DOMStorageContextWrapper* context,
int64_t namepace_id_to_clone)
- : session_(DOMStorageSession::CloneFrom(context->context(),
- namepace_id_to_clone)) {}
+ : session_(
+ DOMStorageSession::CloneFrom(context->context(),
+ context->GetMojoSessionStateWeakPtr(),
+ namepace_id_to_clone)) {}
SessionStorageNamespaceImpl::SessionStorageNamespaceImpl(
- DOMStorageContextWrapper* context, const std::string& persistent_id)
- : session_(new DOMStorageSession(context->context(), persistent_id)) {
-}
+ DOMStorageContextWrapper* context,
+ const std::string& persistent_id)
+ : session_(new DOMStorageSession(context->context(),
+ context->GetMojoSessionStateWeakPtr(),
+ persistent_id)) {}
int64_t SessionStorageNamespaceImpl::id() const {
return session_->namespace_id();
diff --git a/chromium/content/browser/download/base_file.cc b/chromium/content/browser/download/base_file.cc
index 0da99a1bd1a..230234dbb65 100644
--- a/chromium/content/browser/download/base_file.cc
+++ b/chromium/content/browser/download/base_file.cc
@@ -11,23 +11,60 @@
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/pickle.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
+#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "content/browser/download/download_interrupt_reasons_impl.h"
-#include "content/browser/download/download_net_log_parameters.h"
#include "content/browser/download/download_stats.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/download_item.h"
#include "content/public/common/quarantine.h"
#include "crypto/secure_hash.h"
#include "net/base/net_errors.h"
-#include "net/log/net_log.h"
-#include "net/log/net_log_event_type.h"
+
+#define CONDITIONAL_TRACE(trace) \
+ do { \
+ if (download_id_ != DownloadItem::kInvalidId) \
+ TRACE_EVENT_##trace; \
+ } while (0)
namespace content {
-BaseFile::BaseFile(const net::NetLogWithSource& net_log) : net_log_(net_log) {
+namespace {
+class FileErrorData : public base::trace_event::ConvertableToTraceFormat {
+ public:
+ FileErrorData(const char* operation,
+ int os_error,
+ DownloadInterruptReason interrupt_reason)
+ : operation_(operation),
+ os_error_(os_error),
+ interrupt_reason_(interrupt_reason) {}
+
+ ~FileErrorData() override = default;
+
+ void AppendAsTraceFormat(std::string* out) const override {
+ out->append("{");
+ out->append(
+ base::StringPrintf("\"operation\":\"%s\",", operation_.c_str()));
+ out->append(base::StringPrintf("\"os_error\":\"%d\",", os_error_));
+ out->append(base::StringPrintf(
+ "\"interrupt_reason\":\"%s\",",
+ DownloadInterruptReasonToString(interrupt_reason_).c_str()));
+ out->append("}");
+ }
+
+ private:
+ std::string operation_;
+ int os_error_;
+ DownloadInterruptReason interrupt_reason_;
+ DISALLOW_COPY_AND_ASSIGN(FileErrorData);
+};
+} // namespace
+
+BaseFile::BaseFile(uint32_t download_id) : download_id_(download_id) {
DETACH_FROM_SEQUENCE(sequence_checker_);
}
@@ -103,7 +140,10 @@ DownloadInterruptReason BaseFile::WriteDataToFile(int64_t offset,
if (data_len == 0)
return DOWNLOAD_INTERRUPT_REASON_NONE;
- net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN);
+ // Use nestable async event instead of sync event so that all the writes
+ // belong to the same download will be grouped together.
+ CONDITIONAL_TRACE(
+ NESTABLE_ASYNC_BEGIN0("download", "DownloadFileWrite", download_id_));
int write_result = file_.Write(offset, data, data_len);
DCHECK_NE(0, write_result);
@@ -120,8 +160,8 @@ DownloadInterruptReason BaseFile::WriteDataToFile(int64_t offset,
}
bytes_so_far_ += data_len;
- net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN,
- net::NetLog::Int64Callback("bytes", data_len));
+ CONDITIONAL_TRACE(NESTABLE_ASYNC_END1("download", "DownloadFileWrite",
+ download_id_, "bytes", data_len));
if (secure_hash_)
secure_hash_->Update(data, data_len);
@@ -144,9 +184,9 @@ DownloadInterruptReason BaseFile::Rename(const base::FilePath& new_path) {
Close();
- net_log_.BeginEvent(
- net::NetLogEventType::DOWNLOAD_FILE_RENAMED,
- base::Bind(&FileRenamedNetLogCallback, &full_path_, &new_path));
+ CONDITIONAL_TRACE(BEGIN2("download", "DownloadFileRename", "old_filename",
+ full_path_.AsUTF8Unsafe(), "new_filename",
+ new_path.AsUTF8Unsafe()));
base::CreateDirectory(new_path.DirName());
@@ -154,7 +194,7 @@ DownloadInterruptReason BaseFile::Rename(const base::FilePath& new_path) {
// permissions / security descriptors that makes sense in the new directory.
rename_result = MoveFileAndAdjustPermissions(new_path);
- net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_RENAMED);
+ CONDITIONAL_TRACE(END0("download", "DownloadFileRename"));
if (rename_result == DOWNLOAD_INTERRUPT_REASON_NONE)
full_path_ = new_path;
@@ -171,19 +211,22 @@ DownloadInterruptReason BaseFile::Rename(const base::FilePath& new_path) {
void BaseFile::Detach() {
detached_ = true;
- net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_FILE_DETACHED);
+ CONDITIONAL_TRACE(
+ INSTANT0("download", "DownloadFileDetached", TRACE_EVENT_SCOPE_THREAD));
}
void BaseFile::Cancel() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!detached_);
- net_log_.AddEvent(net::NetLogEventType::CANCELLED);
+ CONDITIONAL_TRACE(
+ INSTANT0("download", "DownloadCancelled", TRACE_EVENT_SCOPE_THREAD));
Close();
if (!full_path_.empty()) {
- net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_FILE_DELETED);
+ CONDITIONAL_TRACE(
+ INSTANT0("download", "DownloadFileDeleted", TRACE_EVENT_SCOPE_THREAD));
base::DeleteFile(full_path_, false);
}
@@ -294,9 +337,9 @@ DownloadInterruptReason BaseFile::Open(const std::string& hash_so_far) {
}
}
- net_log_.BeginEvent(
- net::NetLogEventType::DOWNLOAD_FILE_OPENED,
- base::Bind(&FileOpenedNetLogCallback, &full_path_, bytes_so_far_));
+ CONDITIONAL_TRACE(NESTABLE_ASYNC_BEGIN2(
+ "download", "DownloadFileOpen", download_id_, "file_name",
+ full_path_.AsUTF8Unsafe(), "bytes_so_far", bytes_so_far_));
// For sparse file, skip hash validation.
if (is_sparse_file_) {
@@ -356,14 +399,16 @@ void BaseFile::ClearFile() {
// This should only be called when we have a stream.
DCHECK(file_.IsValid());
file_.Close();
- net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_OPENED);
+ CONDITIONAL_TRACE(
+ NESTABLE_ASYNC_END0("download", "DownloadFileOpen", download_id_));
}
DownloadInterruptReason BaseFile::LogNetError(
const char* operation,
net::Error error) {
- net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_FILE_ERROR,
- base::Bind(&FileErrorNetLogCallback, operation, error));
+ CONDITIONAL_TRACE(INSTANT2("download", "DownloadFileError",
+ TRACE_EVENT_SCOPE_THREAD, "operation", operation,
+ "net_error", error));
return ConvertNetErrorToInterruptReason(error, DOWNLOAD_INTERRUPT_FROM_DISK);
}
@@ -384,9 +429,11 @@ DownloadInterruptReason BaseFile::LogInterruptReason(
DVLOG(1) << __func__ << "() operation:" << operation
<< " os_error:" << os_error
<< " reason:" << DownloadInterruptReasonToString(reason);
- net_log_.AddEvent(
- net::NetLogEventType::DOWNLOAD_FILE_ERROR,
- base::Bind(&FileInterruptedNetLogCallback, operation, os_error, reason));
+ auto error_data =
+ base::MakeUnique<FileErrorData>(operation, os_error, reason);
+ CONDITIONAL_TRACE(INSTANT1("download", "DownloadFileError",
+ TRACE_EVENT_SCOPE_THREAD, "file_error",
+ std::move(error_data)));
return reason;
}
@@ -433,11 +480,12 @@ DownloadInterruptReason BaseFile::AnnotateWithSourceInformation(
DCHECK(!detached_);
DCHECK(!full_path_.empty());
- net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_FILE_ANNOTATED);
+ CONDITIONAL_TRACE(BEGIN0("download", "DownloadFileAnnotate"));
QuarantineFileResult result = QuarantineFile(
full_path_, GetEffectiveAuthorityURL(source_url, referrer_url),
referrer_url, client_guid);
- net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_ANNOTATED);
+ CONDITIONAL_TRACE(END0("download", "DownloadFileAnnotate"));
+
switch (result) {
case QuarantineFileResult::OK:
return DOWNLOAD_INTERRUPT_REASON_NONE;
diff --git a/chromium/content/browser/download/base_file.h b/chromium/content/browser/download/base_file.h
index 8b548777051..f7775678293 100644
--- a/chromium/content/browser/download/base_file.h
+++ b/chromium/content/browser/download/base_file.h
@@ -22,7 +22,6 @@
#include "content/public/browser/download_interrupt_reasons.h"
#include "crypto/secure_hash.h"
#include "net/base/net_errors.h"
-#include "net/log/net_log_with_source.h"
#include "url/gurl.h"
namespace content {
@@ -36,7 +35,7 @@ class CONTENT_EXPORT BaseFile {
public:
// May be constructed on any thread. All other routines (including
// destruction) must occur on the same sequence.
- BaseFile(const net::NetLogWithSource& net_log);
+ BaseFile(uint32_t download_id);
~BaseFile();
// Returns DOWNLOAD_INTERRUPT_REASON_NONE on success, or a
@@ -252,7 +251,8 @@ class CONTENT_EXPORT BaseFile {
// verify that writes are not overlapping.
bool is_sparse_file_ = false;
- net::NetLogWithSource net_log_;
+ // ID of the download, used for trace events.
+ uint32_t download_id_;
SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chromium/content/browser/download/base_file_unittest.cc b/chromium/content/browser/download/base_file_unittest.cc
index 3dad6688c25..dd03ecad8e3 100644
--- a/chromium/content/browser/download/base_file_unittest.cc
+++ b/chromium/content/browser/download/base_file_unittest.cc
@@ -17,6 +17,7 @@
#include "base/test/test_file_util.h"
#include "build/build_config.h"
#include "content/public/browser/download_interrupt_reasons.h"
+#include "content/public/browser/download_item.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "crypto/secure_hash.h"
#include "crypto/sha2.h"
@@ -60,7 +61,7 @@ class BaseFileTest : public testing::Test {
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- base_file_.reset(new BaseFile(net::NetLogWithSource()));
+ base_file_.reset(new BaseFile(DownloadItem::kInvalidId));
}
void TearDown() override {
@@ -118,7 +119,7 @@ class BaseFileTest : public testing::Test {
// Create a file. Returns the complete file path.
base::FilePath CreateTestFile() {
base::FilePath file_name;
- BaseFile file((net::NetLogWithSource()));
+ BaseFile file(DownloadItem::kInvalidId);
EXPECT_EQ(
DOWNLOAD_INTERRUPT_REASON_NONE,
@@ -140,7 +141,7 @@ class BaseFileTest : public testing::Test {
// Create a file with the specified file name.
void CreateFileWithName(const base::FilePath& file_name) {
EXPECT_NE(base::FilePath::StringType(), file_name.value());
- BaseFile duplicate_file((net::NetLogWithSource()));
+ BaseFile duplicate_file(DownloadItem::kInvalidId);
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
duplicate_file.Initialize(file_name, temp_dir_.GetPath(),
base::File(), 0, std::string(),
@@ -292,7 +293,7 @@ TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) {
ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path));
// Create another file
- BaseFile second_file((net::NetLogWithSource()));
+ BaseFile second_file(DownloadItem::kInvalidId);
ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
second_file.Initialize(new_file_path,
base::FilePath(),
@@ -418,7 +419,7 @@ TEST_F(BaseFileTest, WriteWithError) {
// Pass a file handle which was opened without the WRITE flag.
// This should result in an error when writing.
base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ);
- base_file_.reset(new BaseFile(net::NetLogWithSource()));
+ base_file_.reset(new BaseFile(DownloadItem::kInvalidId));
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
base_file_->Initialize(path, base::FilePath(), std::move(file), 0,
std::string(),
@@ -460,7 +461,7 @@ TEST_F(BaseFileTest, AppendToBaseFile) {
set_expected_data(kTestData4);
// Use the file we've just created.
- base_file_.reset(new BaseFile(net::NetLogWithSource()));
+ base_file_.reset(new BaseFile(DownloadItem::kInvalidId));
ASSERT_EQ(
DOWNLOAD_INTERRUPT_REASON_NONE,
base_file_->Initialize(existing_file_name, base::FilePath(), base::File(),
@@ -491,7 +492,7 @@ TEST_F(BaseFileTest, ReadonlyBaseFile) {
EXPECT_TRUE(base::MakeFileUnwritable(readonly_file_name));
// Try to overwrite it.
- base_file_.reset(new BaseFile(net::NetLogWithSource()));
+ base_file_.reset(new BaseFile(DownloadItem::kInvalidId));
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
base_file_->Initialize(readonly_file_name, base::FilePath(),
base::File(), 0, std::string(),
diff --git a/chromium/content/browser/download/base_file_win.cc b/chromium/content/browser/download/base_file_win.cc
index 53b109d44a2..77498cf301b 100644
--- a/chromium/content/browser/download/base_file_win.cc
+++ b/chromium/content/browser/download/base_file_win.cc
@@ -294,7 +294,7 @@ DownloadInterruptReason MapShFileOperationCodes(int code) {
// Returns a network error, or net::OK for success.
DownloadInterruptReason BaseFile::MoveFileAndAdjustPermissions(
const base::FilePath& new_path) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
// The parameters to SHFileOperation must be terminated with 2 NULL chars.
base::FilePath::StringType source = full_path_.value();
diff --git a/chromium/content/browser/download/base_file_win_unittest.cc b/chromium/content/browser/download/base_file_win_unittest.cc
index f29f79e87ab..1b1c929b5c4 100644
--- a/chromium/content/browser/download/base_file_win_unittest.cc
+++ b/chromium/content/browser/download/base_file_win_unittest.cc
@@ -7,6 +7,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "content/public/browser/download_interrupt_reasons.h"
+#include "content/public/browser/download_item.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/filename_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -68,7 +69,7 @@ TEST(BaseFileWin, AnnotateWithSourceInformation) {
SCOPED_TRACE(::testing::Message() << "Source URL: " << url.spec()
<< " Referrer: " << test_case.referrer);
- BaseFile base_file((net::NetLogWithSource()));
+ BaseFile base_file(DownloadItem::kInvalidId);
ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
base_file.Initialize(base::FilePath(), target_directory.GetPath(),
base::File(), 0, std::string(),
diff --git a/chromium/content/browser/download/download_browsertest.cc b/chromium/content/browser/download/download_browsertest.cc
index fa9989e549c..53a8fa1e650 100644
--- a/chromium/content/browser/download/download_browsertest.cc
+++ b/chromium/content/browser/download/download_browsertest.cc
@@ -40,7 +40,6 @@
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/download/download_task_runner.h"
#include "content/browser/download/parallel_download_utils.h"
-#include "content/browser/download/slow_download_http_response.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/download_danger_type.h"
@@ -53,8 +52,10 @@
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
-#include "content/public/test/test_download_request_handler.h"
+#include "content/public/test/slow_download_http_response.h"
+#include "content/public/test/test_download_http_response.h"
#include "content/public/test/test_file_error_injector.h"
+#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
@@ -96,6 +97,28 @@ constexpr int kTestRequestCount = 3;
const std::string kOriginOne = "one.example";
const std::string kOriginTwo = "two.example";
+const std::string kOriginThree = "example.com";
+
+class TestResourceDispatcherHostDelegate
+ : public ResourceDispatcherHostDelegate {
+ public:
+ TestResourceDispatcherHostDelegate() = default;
+
+ bool AllowRenderingMhtmlOverHttp(net::URLRequest* request) const override {
+ return allowed_rendering_mhtml_over_http_;
+ }
+
+ void SetDelegate() { ResourceDispatcherHost::Get()->SetDelegate(this); }
+
+ void set_allowed_rendering_mhtml_over_http(bool allowed) {
+ allowed_rendering_mhtml_over_http_ = allowed;
+ }
+
+ private:
+ bool allowed_rendering_mhtml_over_http_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
+};
class MockDownloadItemObserver : public DownloadItem::Observer {
public:
@@ -126,7 +149,7 @@ class MockDownloadManagerObserver : public DownloadManager::Observer {
MockManagerGoingDown(manager);
manager_->RemoveObserver(this);
- manager_ = NULL;
+ manager_ = nullptr;
}
MOCK_METHOD1(MockManagerGoingDown, void(DownloadManager*));
@@ -149,7 +172,7 @@ class DownloadFileWithDelay : public DownloadFileImpl {
DownloadFileWithDelay(std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer,
base::WeakPtr<DownloadFileWithDelayFactory> owner);
@@ -194,7 +217,7 @@ class DownloadFileWithDelayFactory : public DownloadFileFactory {
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer) override;
void AddRenameCallback(base::Closure callback);
@@ -215,13 +238,13 @@ DownloadFileWithDelay::DownloadFileWithDelay(
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer,
base::WeakPtr<DownloadFileWithDelayFactory> owner)
: DownloadFileImpl(std::move(save_info),
default_download_directory,
std::move(stream),
- net_log,
+ download_id,
observer),
owner_(owner) {}
@@ -274,14 +297,11 @@ DownloadFile* DownloadFileWithDelayFactory::CreateFile(
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer) {
- return new DownloadFileWithDelay(std::move(save_info),
- default_download_directory,
- std::move(stream),
- net_log,
- observer,
- weak_ptr_factory_.GetWeakPtr());
+ return new DownloadFileWithDelay(
+ std::move(save_info), default_download_directory, std::move(stream),
+ download_id, observer, weak_ptr_factory_.GetWeakPtr());
}
void DownloadFileWithDelayFactory::AddRenameCallback(base::Closure callback) {
@@ -312,12 +332,12 @@ class CountingDownloadFile : public DownloadFileImpl {
CountingDownloadFile(std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_downloads_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer)
: DownloadFileImpl(std::move(save_info),
default_downloads_directory,
std::move(stream),
- net_log,
+ download_id,
observer) {}
~CountingDownloadFile() override {
@@ -370,16 +390,113 @@ class CountingDownloadFileFactory : public DownloadFileFactory {
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_downloads_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer) override {
return new CountingDownloadFile(std::move(save_info),
default_downloads_directory,
- std::move(stream),
- net_log,
- observer);
+ std::move(stream), download_id, observer);
}
};
+class ErrorInjectionDownloadFile : public DownloadFileImpl {
+ public:
+ ErrorInjectionDownloadFile(
+ std::unique_ptr<DownloadSaveInfo> save_info,
+ const base::FilePath& default_downloads_directory,
+ std::unique_ptr<DownloadManager::InputStream> stream,
+ uint32_t download_id,
+ base::WeakPtr<DownloadDestinationObserver> observer,
+ int64_t error_stream_offset,
+ int64_t error_stream_length)
+ : DownloadFileImpl(std::move(save_info),
+ default_downloads_directory,
+ std::move(stream),
+ download_id,
+ observer),
+ error_stream_offset_(error_stream_offset),
+ error_stream_length_(error_stream_length) {}
+
+ ~ErrorInjectionDownloadFile() override = default;
+
+ void InjectStreamError(int64_t error_stream_offset,
+ int64_t error_stream_length) {
+ error_stream_offset_ = error_stream_offset;
+ error_stream_length_ = error_stream_length;
+ }
+
+ DownloadInterruptReason HandleStreamCompletionStatus(
+ SourceStream* source_stream) override {
+ if (source_stream->offset() == error_stream_offset_ &&
+ source_stream->bytes_written() >= error_stream_length_) {
+ return DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED;
+ }
+ return DownloadFileImpl::HandleStreamCompletionStatus(source_stream);
+ }
+
+ private:
+ int64_t error_stream_offset_;
+ int64_t error_stream_length_;
+};
+
+// Factory for creating download files that allow error injection. All routines
+// on this class must be called on the UI thread.
+class ErrorInjectionDownloadFileFactory : public DownloadFileFactory {
+ public:
+ ErrorInjectionDownloadFileFactory()
+ : download_file_(nullptr), weak_ptr_factory_(this) {}
+ ~ErrorInjectionDownloadFileFactory() override = default;
+
+ // DownloadFileFactory interface.
+ DownloadFile* CreateFile(
+ std::unique_ptr<DownloadSaveInfo> save_info,
+ const base::FilePath& default_download_directory,
+ std::unique_ptr<DownloadManager::InputStream> stream,
+ uint32_t download_id,
+ base::WeakPtr<DownloadDestinationObserver> observer) override {
+ ErrorInjectionDownloadFile* download_file = new ErrorInjectionDownloadFile(
+ std::move(save_info), default_download_directory, std::move(stream),
+ download_id, observer, injected_error_offset_, injected_error_length_);
+ // If the InjectError() is not called yet, memorize |download_file| and wait
+ // for error to be injected.
+ if (injected_error_offset_ < 0)
+ download_file_ = download_file;
+ injected_error_offset_ = -1;
+ injected_error_length_ = 0;
+ return download_file;
+ }
+
+ void InjectError(int64_t offset, int64_t length) {
+ injected_error_offset_ = offset;
+ injected_error_length_ = length;
+ if (!download_file_)
+ return;
+ InjectErrorIntoDownloadFile();
+ }
+
+ base::WeakPtr<ErrorInjectionDownloadFileFactory> GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+ }
+
+ private:
+ void InjectErrorIntoDownloadFile() {
+ GetDownloadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ErrorInjectionDownloadFile::InjectStreamError,
+ base::Unretained(download_file_), injected_error_offset_,
+ injected_error_length_));
+ injected_error_offset_ = -1;
+ injected_error_length_ = 0;
+ download_file_ = nullptr;
+ }
+
+ ErrorInjectionDownloadFile* download_file_;
+ int64_t injected_error_offset_ = -1;
+ int64_t injected_error_length_ = 0;
+ base::WeakPtrFactory<ErrorInjectionDownloadFileFactory> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ErrorInjectionDownloadFileFactory);
+};
+
class TestShellDownloadManagerDelegate : public ShellDownloadManagerDelegate {
public:
TestShellDownloadManagerDelegate()
@@ -415,20 +532,20 @@ class TestShellDownloadManagerDelegate : public ShellDownloadManagerDelegate {
class DownloadCreateObserver : DownloadManager::Observer {
public:
DownloadCreateObserver(DownloadManager* manager)
- : manager_(manager), item_(NULL) {
+ : manager_(manager), item_(nullptr) {
manager_->AddObserver(this);
}
~DownloadCreateObserver() override {
if (manager_)
manager_->RemoveObserver(this);
- manager_ = NULL;
+ manager_ = nullptr;
}
void ManagerGoingDown(DownloadManager* manager) override {
DCHECK_EQ(manager_, manager);
manager_->RemoveObserver(this);
- manager_ = NULL;
+ manager_ = nullptr;
}
void OnDownloadCreated(DownloadManager* manager,
@@ -518,52 +635,42 @@ net::EmbeddedTestServer::HandleRequestCallback CreateBasicResponseHandler(
}
// Helper class to "flatten" handling of
-// TestDownloadRequestHandler::OnStartHandler.
-class TestRequestStartHandler {
+// TestDownloadHttpResponse::OnPauseHandler.
+class TestRequestPauseHandler {
public:
- // Construct an OnStartHandler that can be set as the on_start_handler for
- // TestDownloadRequestHandler::Parameters.
- TestDownloadRequestHandler::OnStartHandler GetOnStartHandler() {
- EXPECT_FALSE(used_) << "GetOnStartHandler() should only be called once for "
- "an instance of TestRequestStartHandler.";
+ // Construct an OnPauseHandler that can be set as the on_pause_handler for
+ // TestDownloadHttpResponse::Parameters.
+ TestDownloadHttpResponse::OnPauseHandler GetOnPauseHandler() {
+ EXPECT_FALSE(used_) << "GetOnPauseHandler() should only be called once for "
+ "an instance of TestRequestPauseHandler.";
used_ = true;
- return base::Bind(&TestRequestStartHandler::OnStartHandler,
+ return base::Bind(&TestRequestPauseHandler::OnPauseHandler,
base::Unretained(this));
}
- // Wait until the OnStartHandlers returned in a prior call to
- // GetOnStartHandler() is invoked.
+ // Wait until the OnPauseHandler returned in a prior call to
+ // GetOnPauseHandler() is invoked.
void WaitForCallback() {
- if (response_callback_.is_null())
+ if (resume_callback_.is_null())
run_loop_.Run();
}
- // Respond to the OnStartHandler() invocation using |headers| and |error|.
- void RespondWith(const std::string& headers, net::Error error) {
- ASSERT_FALSE(response_callback_.is_null());
- response_callback_.Run(headers, error);
- }
-
- // Return the headers returned from the invocation of OnStartHandler.
- const net::HttpRequestHeaders& headers() const {
- EXPECT_FALSE(response_callback_.is_null());
- return request_headers_;
+ // Resume the server response.
+ void Resume() {
+ ASSERT_FALSE(resume_callback_.is_null());
+ std::move(resume_callback_).Run();
}
private:
- void OnStartHandler(const net::HttpRequestHeaders& headers,
- const TestDownloadRequestHandler::OnStartResponseCallback&
- response_callback) {
- request_headers_ = headers;
- response_callback_ = response_callback;
+ void OnPauseHandler(const base::Closure& resume_callback) {
+ resume_callback_ = resume_callback;
if (run_loop_.running())
run_loop_.Quit();
}
bool used_ = false;
base::RunLoop run_loop_;
- net::HttpRequestHeaders request_headers_;
- TestDownloadRequestHandler::OnStartResponseCallback response_callback_;
+ base::OnceClosure resume_callback_;
};
class DownloadContentTest : public ContentBrowserTest {
@@ -584,13 +691,25 @@ class DownloadContentTest : public ContentBrowserTest {
embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
embedded_test_server()->RegisterRequestHandler(
base::Bind(&SlowDownloadHttpResponse::HandleSlowDownloadRequest));
+ test_response_handler_.RegisterToTestServer(embedded_test_server());
ASSERT_TRUE(embedded_test_server()->Start());
const std::string real_host =
embedded_test_server()->host_port_pair().host();
host_resolver()->AddRule(kOriginOne, real_host);
host_resolver()->AddRule(kOriginTwo, real_host);
+ host_resolver()->AddRule(kOriginThree, real_host);
host_resolver()->AddRule(SlowDownloadHttpResponse::kSlowDownloadHostName,
real_host);
+ host_resolver()->AddRule(TestDownloadHttpResponse::kTestDownloadHostName,
+ real_host);
+
+ test_resource_dispatcher_host_delegate_ =
+ std::make_unique<TestResourceDispatcherHostDelegate>();
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::BindOnce(
+ &TestResourceDispatcherHostDelegate::SetDelegate,
+ base::Unretained(test_resource_dispatcher_host_delegate_.get())));
}
void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -649,6 +768,20 @@ class DownloadContentTest : public ContentBrowserTest {
return CountingDownloadFile::GetNumberActiveFilesFromFileThread() == 0;
}
+ void WaitForServerToFinishAllResponses(size_t request_num) {
+ while (test_response_handler_.completed_requests().size() != request_num)
+ base::RunLoop().RunUntilIdle();
+ }
+
+ void SetupErrorInjectionDownloads() {
+ auto factory = std::make_unique<ErrorInjectionDownloadFileFactory>();
+ inject_error_callback_ = base::Bind(
+ &ErrorInjectionDownloadFileFactory::InjectError, factory->GetWeakPtr());
+
+ DownloadManagerForShell(shell())->SetDownloadFileFactoryForTesting(
+ std::move(factory));
+ }
+
void NavigateToURLAndWaitForDownload(
Shell* shell,
const GURL& url,
@@ -699,6 +832,10 @@ class DownloadContentTest : public ContentBrowserTest {
return observer->WaitForFinished();
}
+ TestDownloadResponseHandler* test_response_handler() {
+ return &test_response_handler_;
+ }
+
static bool PathExists(const base::FilePath& path) {
base::ThreadRestrictions::ScopedAllowIO allow_io_during_test_verification;
return base::PathExists(path);
@@ -714,7 +851,7 @@ class DownloadContentTest : public ContentBrowserTest {
ASSERT_EQ(expected_size, file_length);
const int64_t kBufferSize = 64 * 1024;
- std::vector<char> pattern;
+ std::string pattern;
std::vector<char> data;
pattern.resize(kBufferSize);
data.resize(kBufferSize);
@@ -723,69 +860,59 @@ class DownloadContentTest : public ContentBrowserTest {
ASSERT_LT(0, bytes_read);
ASSERT_GE(kBufferSize, bytes_read);
- TestDownloadRequestHandler::GetPatternBytes(seed, offset, bytes_read,
- &pattern.front());
- ASSERT_EQ(0, memcmp(&pattern.front(), &data.front(), bytes_read))
+ pattern =
+ TestDownloadHttpResponse::GetPatternBytes(seed, offset, bytes_read);
+ ASSERT_EQ(0, memcmp(pattern.data(), &data.front(), bytes_read))
<< "Comparing block at offset " << offset << " and length "
<< bytes_read;
offset += bytes_read;
}
}
+ TestDownloadHttpResponse::InjectErrorCallback inject_error_callback() {
+ return inject_error_callback_;
+ }
+
+ TestResourceDispatcherHostDelegate* test_resource_dispatcher_host_delegate() {
+ return test_resource_dispatcher_host_delegate_.get();
+ }
+
private:
// Location of the downloads directory for these tests
base::ScopedTempDir downloads_directory_;
std::unique_ptr<TestShellDownloadManagerDelegate> test_delegate_;
+ TestDownloadResponseHandler test_response_handler_;
+ TestDownloadHttpResponse::InjectErrorCallback inject_error_callback_;
+ std::unique_ptr<TestResourceDispatcherHostDelegate>
+ test_resource_dispatcher_host_delegate_;
};
// Test fixture for parallel downloading.
class ParallelDownloadTest : public DownloadContentTest {
protected:
- void SetUp() override {
- field_trial_list_ = base::MakeUnique<base::FieldTrialList>(
- base::MakeUnique<base::MockEntropyProvider>());
- SetupConfig();
- DownloadContentTest::SetUp();
+ ParallelDownloadTest() {
+ std::map<std::string, std::string> params = {
+ {content::kMinSliceSizeFinchKey, "1"},
+ {content::kParallelRequestCountFinchKey,
+ base::IntToString(kTestRequestCount)},
+ {content::kParallelRequestDelayFinchKey, "0"},
+ {content::kParallelRequestRemainingTimeFinchKey, "0"}};
+ scoped_feature_list_.InitAndEnableFeatureWithParameters(
+ features::kParallelDownloading, params);
}
+ ~ParallelDownloadTest() override {}
+
private:
- // TODO(xingliu): Use this technique in parallel download unit tests to load
- // the finch configuration.
- void SetupConfig() {
- const std::string kTrialName = "trial_name";
- const std::string kGroupName = "group_name";
-
- std::map<std::string, std::string> params;
- params[content::kMinSliceSizeFinchKey] = "1";
- params[content::kParallelRequestCountFinchKey] =
- base::IntToString(kTestRequestCount);
- params[content::kParallelRequestDelayFinchKey] = "0";
- params[content::kParallelRequestRemainingTimeFinchKey] = "0";
-
- scoped_refptr<base::FieldTrial> trial =
- base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
- base::AssociateFieldTrialParams(kTrialName, kGroupName, params);
- std::unique_ptr<base::FeatureList> feature_list =
- base::MakeUnique<base::FeatureList>();
- feature_list->RegisterFieldTrialOverride(
- features::kParallelDownloading.name,
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
- scoped_feature_list_.InitWithFeatureList(std::move(feature_list));
- }
-
- std::unique_ptr<base::FieldTrialList> field_trial_list_;
base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(ParallelDownloadTest);
};
} // namespace
-#if defined(OS_ANDROID)
-// Failing/Flaky on Android: https://crbug.com/754679
-#define MAYBE_DownloadCancelled DISABLED_DownloadCancelled
-#else
-#define MAYBE_DownloadCancelled DownloadCancelled
-#endif
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, MAYBE_DownloadCancelled) {
+// Flaky. See https://crbug.com/754679.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, DISABLED_DownloadCancelled) {
SetupEnsureNoPendingDownloads();
// Create a download, wait until it's started, and confirm
@@ -1094,18 +1221,19 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) {
// Test resumption with a response that contains strong validators.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, StrongValidators) {
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- const TestDownloadRequestHandler::InjectedError interruption =
- parameters.injected_errors.front();
- request_handler.StartServing(parameters);
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ SetupErrorInjectionDownloads();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
+
+ int64_t interruption_offset = parameters.injected_errors.front();
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
- ASSERT_EQ(interruption.offset, download->GetReceivedBytes());
+ ASSERT_EQ(interruption_offset, download->GetReceivedBytes());
ASSERT_EQ(parameters.size, download->GetTotalBytes());
download->Resume();
@@ -1121,75 +1249,82 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, StrongValidators) {
// that were sent out while downloading our resource. These requests
// correspond to the requests that were generated by the browser and the
// downloads system and may change as implementation details change.
- TestDownloadRequestHandler::CompletedRequests requests;
- request_handler.GetCompletedRequestInfo(&requests);
+ const TestDownloadResponseHandler::CompletedRequests& requests =
+ test_response_handler()->completed_requests();
ASSERT_EQ(2u, requests.size());
// The first request only transferrs bytes up until the interruption point.
- EXPECT_EQ(interruption.offset, requests[0]->transferred_byte_count);
+ EXPECT_EQ(interruption_offset, requests[0]->transferred_byte_count);
// The next request should only have transferred the remainder of the
// resource.
- EXPECT_EQ(parameters.size - interruption.offset,
+ EXPECT_EQ(parameters.size - interruption_offset,
requests[1]->transferred_byte_count);
std::string value;
- ASSERT_TRUE(requests[1]->request_headers.GetHeader(
- net::HttpRequestHeaders::kIfRange, &value));
- EXPECT_EQ(parameters.etag, value);
+ ASSERT_TRUE(requests[1]->http_request.headers.find(
+ net::HttpRequestHeaders::kIfRange) !=
+ requests[1]->http_request.headers.end());
+ EXPECT_EQ(parameters.etag, requests[1]->http_request.headers.at(
+ net::HttpRequestHeaders::kIfRange));
- ASSERT_TRUE(requests[1]->request_headers.GetHeader(
- net::HttpRequestHeaders::kRange, &value));
- EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset),
- value);
+ ASSERT_TRUE(
+ requests[1]->http_request.headers.find(net::HttpRequestHeaders::kRange) !=
+ requests[1]->http_request.headers.end());
+ EXPECT_EQ(
+ base::StringPrintf("bytes=%" PRId64 "-", interruption_offset),
+ requests[1]->http_request.headers.at(net::HttpRequestHeaders::kRange));
}
// Resumption should only attempt to contact the final URL if the download has a
// URL chain.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RedirectBeforeResume) {
- TestDownloadRequestHandler request_handler_1(
- GURL("http://example.com/first-url"));
- request_handler_1.StartServingStaticResponse(
- "HTTP/1.1 302 Redirect\r\n"
- "Location: http://example.com/second-url\r\n"
- "\r\n");
-
- TestDownloadRequestHandler request_handler_2(
- GURL("http://example.com/second-url"));
- request_handler_2.StartServingStaticResponse(
- "HTTP/1.1 302 Redirect\r\n"
- "Location: http://example.com/third-url\r\n"
- "\r\n");
-
- TestDownloadRequestHandler request_handler_3(
- GURL("http://example.com/third-url"));
- request_handler_3.StartServingStaticResponse(
- "HTTP/1.1 302 Redirect\r\n"
- "Location: http://example.com/download\r\n"
- "\r\n");
-
- TestDownloadRequestHandler resumable_request_handler(
- GURL("http://example.com/download"));
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- resumable_request_handler.StartServing(parameters);
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler_1.url());
+ SetupErrorInjectionDownloads();
+ GURL first_url = embedded_test_server()->GetURL("example.com", "/first-url");
+ GURL second_url =
+ embedded_test_server()->GetURL("example.com", "/second-url");
+ GURL third_url = embedded_test_server()->GetURL("example.com", "/third-url");
+ GURL download_url =
+ embedded_test_server()->GetURL("example.com", "/download");
+ TestDownloadHttpResponse::StartServingStaticResponse(
+ base::StringPrintf("HTTP/1.1 302 Redirect\r\n"
+ "Location: %s\r\n\r\n",
+ second_url.spec().c_str()),
+ first_url);
+
+ TestDownloadHttpResponse::StartServingStaticResponse(
+ base::StringPrintf("HTTP/1.1 302 Redirect\r\n"
+ "Location: %s\r\n\r\n",
+ third_url.spec().c_str()),
+ second_url);
+
+ TestDownloadHttpResponse::StartServingStaticResponse(
+ base::StringPrintf("HTTP/1.1 302 Redirect\r\n"
+ "Location: %s\r\n\r\n",
+ download_url.spec().c_str()),
+ third_url);
+
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
+ TestDownloadHttpResponse::StartServing(parameters, download_url);
+
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), first_url);
WaitForInterrupt(download);
EXPECT_EQ(4u, download->GetUrlChain().size());
- EXPECT_EQ(request_handler_1.url(), download->GetOriginalUrl());
- EXPECT_EQ(resumable_request_handler.url(), download->GetURL());
+ EXPECT_EQ(first_url, download->GetOriginalUrl());
+ EXPECT_EQ(download_url, download->GetURL());
// Now that the download is interrupted, make all intermediate servers return
// a 404. The only way a resumption request would succeed if the resumption
// request is sent to the final server in the chain.
const char k404Response[] = "HTTP/1.1 404 Not found\r\n\r\n";
- request_handler_1.StartServingStaticResponse(k404Response);
- request_handler_2.StartServingStaticResponse(k404Response);
- request_handler_3.StartServingStaticResponse(k404Response);
+ TestDownloadHttpResponse::StartServingStaticResponse(k404Response, first_url);
+ TestDownloadHttpResponse::StartServingStaticResponse(k404Response,
+ second_url);
+ TestDownloadHttpResponse::StartServingStaticResponse(k404Response, third_url);
download->Resume();
WaitForCompletion(download);
@@ -1202,30 +1337,31 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RedirectBeforeResume) {
// If a resumption request results in a redirect, the response should be ignored
// and the download should be marked as interrupted again.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RedirectWhileResume) {
- TestDownloadRequestHandler request_handler(
- GURL("http://example.com/first-url"));
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ SetupErrorInjectionDownloads();
+ GURL first_url = embedded_test_server()->GetURL("example.com", "/first-url");
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
++parameters.pattern_generator_seed;
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::StartServing(parameters, first_url);
// We should never send a request to the decoy. If we do, the request will
// always succeed, which results in behavior that diverges from what we want,
// which is for the download to return to being interrupted.
- TestDownloadRequestHandler decoy_request_handler(
- GURL("http://example.com/decoy"));
- decoy_request_handler.StartServing(TestDownloadRequestHandler::Parameters());
+ GURL second_url = embedded_test_server()->GetURL("example.com", "/decoy");
+ TestDownloadHttpResponse::StartServing(TestDownloadHttpResponse::Parameters(),
+ second_url);
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), first_url);
WaitForInterrupt(download);
// Upon resumption, the server starts responding with a redirect. This
// response should not be accepted.
- request_handler.StartServingStaticResponse(
- "HTTP/1.1 302 Redirect\r\n"
- "Location: http://example.com/decoy\r\n"
- "\r\n");
+ TestDownloadHttpResponse::StartServingStaticResponse(
+ base::StringPrintf("HTTP/1.1 302 Redirect\r\n"
+ "Location: %s\r\n\r\n",
+ second_url.spec().c_str()),
+ first_url);
download->Resume();
WaitForInterrupt(download);
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE,
@@ -1233,7 +1369,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RedirectWhileResume) {
// Back to the original request handler. Resumption should now succeed, and
// use the partial data it had prior to the first interruption.
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::StartServing(parameters, first_url);
download->Resume();
WaitForCompletion(download);
@@ -1247,8 +1383,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RedirectWhileResume) {
// that were sent out while downloading our resource. These requests
// correspond to the requests that were generated by the browser and the
// downloads system and may change as implementation details change.
- TestDownloadRequestHandler::CompletedRequests requests;
- request_handler.GetCompletedRequestInfo(&requests);
+ const TestDownloadResponseHandler::CompletedRequests& requests =
+ test_response_handler()->completed_requests();
ASSERT_EQ(3u, requests.size());
@@ -1264,20 +1400,23 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RedirectWhileResume) {
// header), then the download should be marked as interrupted again without
// discarding the partial state.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, BadRangeHeader) {
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- request_handler.StartServing(parameters);
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ SetupErrorInjectionDownloads();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
+
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
// Upon resumption, the server starts responding with a bad range header.
- request_handler.StartServingStaticResponse(
+ TestDownloadHttpResponse::StartServingStaticResponse(
"HTTP/1.1 206 Partial Content\r\n"
"Content-Range: bytes 1000000-2000000/3000000\r\n"
- "\r\n");
+ "\r\n",
+ server_url);
download->Resume();
WaitForInterrupt(download);
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
@@ -1285,20 +1424,22 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, BadRangeHeader) {
// Or this time, the server sends a response with an invalid Content-Range
// header.
- request_handler.StartServingStaticResponse(
+ TestDownloadHttpResponse::StartServingStaticResponse(
"HTTP/1.1 206 Partial Content\r\n"
"Content-Range: ooga-booga-booga-booga\r\n"
- "\r\n");
+ "\r\n",
+ server_url);
download->Resume();
WaitForInterrupt(download);
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
download->GetLastReason());
// Or no Content-Range header at all.
- request_handler.StartServingStaticResponse(
+ TestDownloadHttpResponse::StartServingStaticResponse(
"HTTP/1.1 206 Partial Content\r\n"
"Some-Headers: ooga-booga-booga-booga\r\n"
- "\r\n");
+ "\r\n",
+ server_url);
download->Resume();
WaitForInterrupt(download);
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
@@ -1306,7 +1447,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, BadRangeHeader) {
// Back to the original request handler. Resumption should now succeed, and
// use the partial data it had prior to the first interruption.
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
download->Resume();
WaitForCompletion(download);
@@ -1320,8 +1461,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, BadRangeHeader) {
// that were sent out while downloading our resource. These requests
// correspond to the requests that were generated by the browser and the
// downloads system and may change as implementation details change.
- TestDownloadRequestHandler::CompletedRequests requests;
- request_handler.GetCompletedRequestInfo(&requests);
+ const TestDownloadResponseHandler::CompletedRequests& requests =
+ test_response_handler()->completed_requests();
ASSERT_EQ(5u, requests.size());
@@ -1339,29 +1480,29 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, BadRangeHeader) {
// respond with a 200. So this test case covers both validation failure and
// ignoring the range request.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RestartIfNotPartialResponse) {
+ SetupErrorInjectionDownloads();
const int kOriginalPatternGeneratorSeed = 1;
const int kNewPatternGeneratorSeed = 2;
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed;
- const TestDownloadRequestHandler::InjectedError interruption =
- parameters.injected_errors.front();
+ int64_t interruption_offset = parameters.injected_errors.front();
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(parameters);
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
- ASSERT_EQ(interruption.offset, download->GetReceivedBytes());
+ ASSERT_EQ(interruption_offset, download->GetReceivedBytes());
ASSERT_EQ(parameters.size, download->GetTotalBytes());
- parameters = TestDownloadRequestHandler::Parameters();
+ parameters = TestDownloadHttpResponse::Parameters();
parameters.support_byte_ranges = false;
parameters.pattern_generator_seed = kNewPatternGeneratorSeed;
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
download->Resume();
WaitForCompletion(download);
@@ -1377,48 +1518,53 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RestartIfNotPartialResponse) {
// see two requests:
// * The original request which transfers upto our interruption point.
// * The resumption attempt, which receives the entire entity.
- TestDownloadRequestHandler::CompletedRequests requests;
- request_handler.GetCompletedRequestInfo(&requests);
+ const TestDownloadResponseHandler::CompletedRequests& requests =
+ test_response_handler()->completed_requests();
ASSERT_EQ(2u, requests.size());
// The first request only transfers data up to the interruption point.
- EXPECT_EQ(interruption.offset, requests[0]->transferred_byte_count);
+ EXPECT_EQ(interruption_offset, requests[0]->transferred_byte_count);
// The second request transfers the entire response.
EXPECT_EQ(parameters.size, requests[1]->transferred_byte_count);
- std::string value;
- ASSERT_TRUE(requests[1]->request_headers.GetHeader(
- net::HttpRequestHeaders::kIfRange, &value));
- EXPECT_EQ(parameters.etag, value);
+ ASSERT_TRUE(requests[1]->http_request.headers.find(
+ net::HttpRequestHeaders::kIfRange) !=
+ requests[1]->http_request.headers.end());
+ EXPECT_EQ(parameters.etag, requests[1]->http_request.headers.at(
+ net::HttpRequestHeaders::kIfRange));
- ASSERT_TRUE(requests[1]->request_headers.GetHeader(
- net::HttpRequestHeaders::kRange, &value));
- EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset),
- value);
+ ASSERT_TRUE(
+ requests[1]->http_request.headers.find(net::HttpRequestHeaders::kRange) !=
+ requests[1]->http_request.headers.end());
+ EXPECT_EQ(
+ base::StringPrintf("bytes=%" PRId64 "-", interruption_offset),
+ requests[1]->http_request.headers.at(net::HttpRequestHeaders::kRange));
}
// Confirm we restart if we don't have a verifier.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RestartIfNoETag) {
+ SetupErrorInjectionDownloads();
const int kOriginalPatternGeneratorSeed = 1;
const int kNewPatternGeneratorSeed = 2;
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
ASSERT_EQ(1u, parameters.injected_errors.size());
parameters.etag.clear();
parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed;
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(parameters);
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
parameters.pattern_generator_seed = kNewPatternGeneratorSeed;
parameters.ClearInjectedErrors();
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
download->Resume();
WaitForCompletion(download);
@@ -1429,28 +1575,31 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RestartIfNoETag) {
ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size,
download->GetTargetFilePath()));
- TestDownloadRequestHandler::CompletedRequests requests;
- request_handler.GetCompletedRequestInfo(&requests);
+ const TestDownloadResponseHandler::CompletedRequests& requests =
+ test_response_handler()->completed_requests();
// Neither If-Range nor Range headers should be present in the second request.
ASSERT_EQ(2u, requests.size());
- std::string value;
- EXPECT_FALSE(requests[1]->request_headers.GetHeader(
- net::HttpRequestHeaders::kIfRange, &value));
- EXPECT_FALSE(requests[1]->request_headers.GetHeader(
- net::HttpRequestHeaders::kRange, &value));
+ EXPECT_TRUE(requests[1]->http_request.headers.find(
+ net::HttpRequestHeaders::kIfRange) ==
+ requests[1]->http_request.headers.end());
+ EXPECT_TRUE(
+ requests[1]->http_request.headers.find(net::HttpRequestHeaders::kRange) ==
+ requests[1]->http_request.headers.end());
}
// Partial file goes missing before the download is resumed. The download should
// restart.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RestartIfNoPartialFile) {
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
-
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(parameters);
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ SetupErrorInjectionDownloads();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
+
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
// Delete the intermediate file.
@@ -1461,7 +1610,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RestartIfNoPartialFile) {
}
parameters.ClearInjectedErrors();
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
download->Resume();
WaitForCompletion(download);
@@ -1474,8 +1623,10 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RestartIfNoPartialFile) {
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RecoverFromInitFileError) {
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(TestDownloadRequestHandler::Parameters());
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(TestDownloadHttpResponse::Parameters(),
+ server_url);
// Setup the error injector.
scoped_refptr<TestFileErrorInjector> injector(
@@ -1487,8 +1638,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RecoverFromInitFileError) {
injector->InjectError(err);
// Start and watch for interrupt.
- DownloadItem* download(
- StartDownloadAndReturnItem(shell(), request_handler.url()));
+ DownloadItem* download(StartDownloadAndReturnItem(shell(), server_url));
WaitForInterrupt(download);
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
@@ -1514,8 +1664,10 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RecoverFromInitFileError) {
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
RecoverFromIntermediateFileRenameError) {
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(TestDownloadRequestHandler::Parameters());
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(TestDownloadHttpResponse::Parameters(),
+ server_url);
// Setup the error injector.
scoped_refptr<TestFileErrorInjector> injector(
@@ -1527,8 +1679,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
injector->InjectError(err);
// Start and watch for interrupt.
- DownloadItem* download(
- StartDownloadAndReturnItem(shell(), request_handler.url()));
+ DownloadItem* download(StartDownloadAndReturnItem(shell(), server_url));
WaitForInterrupt(download);
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
@@ -1554,8 +1705,10 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RecoverFromFinalRenameError) {
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(TestDownloadRequestHandler::Parameters());
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(TestDownloadHttpResponse::Parameters(),
+ server_url);
// Setup the error injector.
scoped_refptr<TestFileErrorInjector> injector(
@@ -1567,8 +1720,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RecoverFromFinalRenameError) {
injector->InjectError(err);
// Start and watch for interrupt.
- DownloadItem* download(
- StartDownloadAndReturnItem(shell(), request_handler.url()));
+ DownloadItem* download(StartDownloadAndReturnItem(shell(), server_url));
WaitForInterrupt(download);
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, download->GetLastReason());
@@ -1591,37 +1743,33 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RecoverFromFinalRenameError) {
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_Hash) {
- using InjectedError = TestDownloadRequestHandler::InjectedError;
const char kExpectedHash[] =
"\xa7\x44\x49\x86\x24\xc6\x84\x6c\x89\xdf\xd8\xec\xa0\xe0\x61\x12\xdc\x80"
"\x13\xf2\x83\x49\xa9\x14\x52\x32\xf0\x95\x20\xca\x5b\x30";
std::string expected_hash(kExpectedHash);
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
+ TestDownloadHttpResponse::Parameters parameters;
// As a control, let's try GetHash() on an uninterrupted download.
- request_handler.StartServing(parameters);
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
DownloadItem* uninterrupted_download(
- StartDownloadAndReturnItem(shell(), request_handler.url()));
+ StartDownloadAndReturnItem(shell(), server_url));
WaitForCompletion(uninterrupted_download);
EXPECT_EQ(expected_hash, uninterrupted_download->GetHash());
+ SetupErrorInjectionDownloads();
// Now with interruptions.
- parameters.injected_errors.push(
- InjectedError(100, net::ERR_CONNECTION_RESET));
- parameters.injected_errors.push(
- InjectedError(211, net::ERR_CONNECTION_RESET));
- parameters.injected_errors.push(
- InjectedError(337, net::ERR_CONNECTION_RESET));
- parameters.injected_errors.push(
- InjectedError(400, net::ERR_CONNECTION_RESET));
- parameters.injected_errors.push(
- InjectedError(512, net::ERR_CONNECTION_RESET));
- request_handler.StartServing(parameters);
+ parameters.inject_error_cb = inject_error_callback();
+ parameters.injected_errors.push(100);
+ parameters.injected_errors.push(211);
+ parameters.injected_errors.push(337);
+ parameters.injected_errors.push(400);
+ parameters.injected_errors.push(512);
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
// Start and watch for interrupt.
- DownloadItem* download(
- StartDownloadAndReturnItem(shell(), request_handler.url()));
+ DownloadItem* download(StartDownloadAndReturnItem(shell(), server_url));
WaitForInterrupt(download);
download->Resume();
@@ -1645,12 +1793,15 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_Hash) {
// An interrupted download should remove the intermediate file when it is
// cancelled.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) {
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(
- TestDownloadRequestHandler::Parameters::WithSingleInterruption());
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ SetupErrorInjectionDownloads();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback()),
+ server_url);
+
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
base::FilePath intermediate_path = download->GetFullPath();
@@ -1666,12 +1817,15 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) {
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveInterruptedDownload) {
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(
- TestDownloadRequestHandler::Parameters::WithSingleInterruption());
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ SetupErrorInjectionDownloads();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback()),
+ server_url);
+
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
base::FilePath intermediate_path = download->GetFullPath();
@@ -1688,12 +1842,14 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveInterruptedDownload) {
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveCompletedDownload) {
// A completed download shouldn't delete the downloaded file when it is
// removed.
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(TestDownloadRequestHandler::Parameters());
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(TestDownloadHttpResponse::Parameters(),
+ server_url);
+
std::unique_ptr<DownloadTestObserver> completion_observer(
CreateWaiter(shell(), 1));
- DownloadItem* download(
- StartDownloadAndReturnItem(shell(), request_handler.url()));
+ DownloadItem* download(StartDownloadAndReturnItem(shell(), server_url));
completion_observer->WaitForFinished();
// The target path should exist.
@@ -1707,13 +1863,14 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveCompletedDownload) {
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) {
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(parameters);
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ SetupErrorInjectionDownloads();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
base::FilePath intermediate_path(download->GetFullPath());
@@ -1723,46 +1880,47 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) {
// Resume and remove download. We expect only a single OnDownloadCreated()
// call, and that's for the second download created below.
MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
- EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
+ EXPECT_CALL(dm_observer, OnDownloadCreated(_, _)).Times(1);
- TestRequestStartHandler request_start_handler;
- parameters.on_start_handler = request_start_handler.GetOnStartHandler();
- request_handler.StartServing(parameters);
+ TestRequestPauseHandler request_pause_handler;
+ parameters.on_pause_handler = request_pause_handler.GetOnPauseHandler();
+ parameters.pause_offset = -1;
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
download->Resume();
- request_start_handler.WaitForCallback();
+ request_pause_handler.WaitForCallback();
// At this point, the download resumption request has been sent out, but the
// response hasn't been received yet.
download->Remove();
-
- request_start_handler.RespondWith(std::string(), net::OK);
+ request_pause_handler.Resume();
// The intermediate file should now be gone.
RunAllTasksUntilIdle();
EXPECT_FALSE(PathExists(intermediate_path));
parameters.ClearInjectedErrors();
- parameters.on_start_handler.Reset();
- request_handler.StartServing(parameters);
+ parameters.on_pause_handler.Reset();
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
// Start the second download and wait until it's done. This exercises the
// entire downloads stack and effectively flushes all of our worker threads.
// We are testing whether the URL request created in the previous
// DownloadItem::Resume() call reulted in a new download or not.
- NavigateToURLAndWaitForDownload(shell(), request_handler.url(),
- DownloadItem::COMPLETE);
+ NavigateToURLAndWaitForDownload(shell(), server_url, DownloadItem::COMPLETE);
EXPECT_TRUE(EnsureNoPendingDownloads());
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) {
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(parameters);
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ SetupErrorInjectionDownloads();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
+
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
base::FilePath intermediate_path(download->GetFullPath());
@@ -1774,18 +1932,19 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) {
MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
- TestRequestStartHandler request_start_handler;
- parameters.on_start_handler = request_start_handler.GetOnStartHandler();
- request_handler.StartServing(parameters);
+ TestRequestPauseHandler request_pause_handler;
+ parameters.on_pause_handler = request_pause_handler.GetOnPauseHandler();
+ parameters.pause_offset = -1;
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
download->Resume();
- request_start_handler.WaitForCallback();
+ request_pause_handler.WaitForCallback();
// At this point, the download item has initiated a network request for the
// resumption attempt, but hasn't received a response yet.
download->Cancel(true /* user_cancel */);
- request_start_handler.RespondWith(std::string(), net::OK);
+ request_pause_handler.Resume();
// The intermediate file should now be gone.
RunAllPendingInMessageLoop(BrowserThread::IO);
@@ -1793,26 +1952,27 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) {
EXPECT_FALSE(PathExists(intermediate_path));
parameters.ClearInjectedErrors();
- parameters.on_start_handler.Reset();
- request_handler.StartServing(parameters);
+ parameters.on_pause_handler.Reset();
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
// Start the second download and wait until it's done. This exercises the
// entire downloads stack and effectively flushes all of our worker threads.
// We are testing whether the URL request created in the previous
// DownloadItem::Resume() call reulted in a new download or not.
- NavigateToURLAndWaitForDownload(shell(), request_handler.url(),
- DownloadItem::COMPLETE);
+ NavigateToURLAndWaitForDownload(shell(), server_url, DownloadItem::COMPLETE);
EXPECT_TRUE(EnsureNoPendingDownloads());
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumedDownload) {
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(parameters);
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ SetupErrorInjectionDownloads();
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
+
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
base::FilePath intermediate_path(download->GetFullPath());
@@ -1835,16 +1995,19 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumedDownload) {
EXPECT_FALSE(PathExists(intermediate_path));
EXPECT_FALSE(PathExists(target_path));
EXPECT_TRUE(EnsureNoPendingDownloads());
+ WaitForServerToFinishAllResponses(2);
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumedDownload) {
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- TestDownloadRequestHandler request_handler;
- request_handler.StartServing(parameters);
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ SetupErrorInjectionDownloads();
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
+
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
WaitForInterrupt(download);
base::FilePath intermediate_path(download->GetFullPath());
@@ -1867,19 +2030,21 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumedDownload) {
EXPECT_FALSE(PathExists(intermediate_path));
EXPECT_FALSE(PathExists(target_path));
EXPECT_TRUE(EnsureNoPendingDownloads());
+ WaitForServerToFinishAllResponses(2);
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_NoFile) {
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::Parameters parameters;
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
base::FilePath intermediate_file_path =
GetDownloadDirectory().AppendASCII("intermediate");
std::vector<GURL> url_chain;
const int kIntermediateSize = 1331;
- url_chain.push_back(request_handler.url());
+ url_chain.push_back(server_url);
DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem(
"F7FB1F59-7DE1-4845-AFDB-8A688F70F583", 1, intermediate_file_path,
@@ -1899,8 +2064,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_NoFile) {
parameters.size,
download->GetTargetFilePath());
- TestDownloadRequestHandler::CompletedRequests completed_requests;
- request_handler.GetCompletedRequestInfo(&completed_requests);
+ const TestDownloadResponseHandler::CompletedRequests& requests =
+ test_response_handler()->completed_requests();
// There will be two requests. The first one is issued optimistically assuming
// that the intermediate file exists and matches the size expectations set
@@ -1919,30 +2084,30 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_NoFile) {
//
// TODO(asanka): Ideally we'll check that the intermediate file matches
// expectations prior to issuing the first resumption request.
- ASSERT_EQ(2u, completed_requests.size());
- EXPECT_EQ(parameters.size, completed_requests[1]->transferred_byte_count);
+ ASSERT_EQ(2u, requests.size());
+ EXPECT_EQ(parameters.size, requests[1]->transferred_byte_count);
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_NoHash) {
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::Parameters parameters;
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
base::FilePath intermediate_file_path =
GetDownloadDirectory().AppendASCII("intermediate");
std::vector<GURL> url_chain;
const int kIntermediateSize = 1331;
- std::vector<char> buffer(kIntermediateSize);
- request_handler.GetPatternBytes(
- parameters.pattern_generator_seed, 0, buffer.size(), buffer.data());
+ std::string output = TestDownloadHttpResponse::GetPatternBytes(
+ parameters.pattern_generator_seed, 0, kIntermediateSize);
{
base::ThreadRestrictions::ScopedAllowIO allow_io_for_test_setup;
ASSERT_EQ(kIntermediateSize, base::WriteFile(intermediate_file_path,
- buffer.data(), buffer.size()));
+ output.data(), output.size()));
}
- url_chain.push_back(request_handler.url());
+ url_chain.push_back(server_url);
DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem(
"F7FB1F59-7DE1-4845-AFDB-8A688F70F583", 1, intermediate_file_path,
@@ -1962,8 +2127,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_NoHash) {
parameters.size,
download->GetTargetFilePath());
- TestDownloadRequestHandler::CompletedRequests completed_requests;
- request_handler.GetCompletedRequestInfo(&completed_requests);
+ const TestDownloadResponseHandler::CompletedRequests& completed_requests =
+ test_response_handler()->completed_requests();
// There's only one network request issued, and that is for the remainder of
// the file.
@@ -1974,25 +2139,25 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_NoHash) {
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
ResumeRestoredDownload_EtagMismatch) {
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::Parameters parameters;
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
base::FilePath intermediate_file_path =
GetDownloadDirectory().AppendASCII("intermediate");
std::vector<GURL> url_chain;
const int kIntermediateSize = 1331;
- std::vector<char> buffer(kIntermediateSize);
- request_handler.GetPatternBytes(
- parameters.pattern_generator_seed + 1, 0, buffer.size(), buffer.data());
+ std::string output = TestDownloadHttpResponse::GetPatternBytes(
+ parameters.pattern_generator_seed + 1, 0, kIntermediateSize);
{
base::ThreadRestrictions::ScopedAllowIO allow_io_for_test_setup;
ASSERT_EQ(kIntermediateSize, base::WriteFile(intermediate_file_path,
- buffer.data(), buffer.size()));
+ output.data(), output.size()));
}
- url_chain.push_back(request_handler.url());
+ url_chain.push_back(server_url);
DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem(
"F7FB1F59-7DE1-4845-AFDB-8A688F70F583", 1, intermediate_file_path,
@@ -2012,8 +2177,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
parameters.size,
download->GetTargetFilePath());
- TestDownloadRequestHandler::CompletedRequests completed_requests;
- request_handler.GetCompletedRequestInfo(&completed_requests);
+ const TestDownloadResponseHandler::CompletedRequests& completed_requests =
+ test_response_handler()->completed_requests();
// There's only one network request issued. The If-Range header allows the
// server to respond with the entire entity in one go. The existing contents
@@ -2024,22 +2189,22 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
ResumeRestoredDownload_CorrectHash) {
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::Parameters parameters;
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
base::FilePath intermediate_file_path =
GetDownloadDirectory().AppendASCII("intermediate");
std::vector<GURL> url_chain;
const int kIntermediateSize = 1331;
- std::vector<char> buffer(kIntermediateSize);
- request_handler.GetPatternBytes(
- parameters.pattern_generator_seed, 0, buffer.size(), buffer.data());
+ std::string output = TestDownloadHttpResponse::GetPatternBytes(
+ parameters.pattern_generator_seed, 0, kIntermediateSize);
{
base::ThreadRestrictions::ScopedAllowIO allow_io_for_test_setup;
ASSERT_EQ(kIntermediateSize, base::WriteFile(intermediate_file_path,
- buffer.data(), buffer.size()));
+ output.data(), output.size()));
}
// SHA-256 hash of the pattern bytes in buffer.
static const uint8_t kPartialHash[] = {
@@ -2047,7 +2212,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
0xcf, 0xdd, 0x46, 0xa2, 0x61, 0x96, 0xff, 0xc3, 0xbb, 0x49, 0x30,
0xaf, 0x31, 0x3a, 0x64, 0x0b, 0xd5, 0xfa, 0xb1, 0xe3, 0x81};
- url_chain.push_back(request_handler.url());
+ url_chain.push_back(server_url);
DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem(
"F7FB1F59-7DE1-4845-AFDB-8A688F70F583", 1, intermediate_file_path,
@@ -2068,8 +2233,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
parameters.size,
download->GetTargetFilePath());
- TestDownloadRequestHandler::CompletedRequests completed_requests;
- request_handler.GetCompletedRequestInfo(&completed_requests);
+ const TestDownloadResponseHandler::CompletedRequests& completed_requests =
+ test_response_handler()->completed_requests();
// There's only one network request issued, and that is for the remainder of
// the file.
@@ -2087,9 +2252,10 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_WrongHash) {
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::Parameters parameters;
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
base::FilePath intermediate_file_path =
GetDownloadDirectory().AppendASCII("intermediate");
@@ -2109,7 +2275,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_WrongHash) {
0xcf, 0xdd, 0x46, 0xa2, 0x61, 0x96, 0xff, 0xc3, 0xbb, 0x49, 0x30,
0xaf, 0x31, 0x3a, 0x64, 0x0b, 0xd5, 0xfa, 0xb1, 0xe3, 0x81};
- url_chain.push_back(request_handler.url());
+ url_chain.push_back(server_url);
DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem(
"F7FB1F59-7DE1-4845-AFDB-8A688F70F583", 1, intermediate_file_path,
@@ -2130,8 +2296,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_WrongHash) {
parameters.size,
download->GetTargetFilePath());
- TestDownloadRequestHandler::CompletedRequests completed_requests;
- request_handler.GetCompletedRequestInfo(&completed_requests);
+ const TestDownloadResponseHandler::CompletedRequests& completed_requests =
+ test_response_handler()->completed_requests();
// There will be two requests. The first one is issued optimistically assuming
// that the intermediate file exists and matches the size expectations set
@@ -2162,9 +2328,10 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_WrongHash) {
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_ShortFile) {
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::Parameters parameters;
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
base::FilePath intermediate_file_path =
GetDownloadDirectory().AppendASCII("intermediate");
@@ -2172,16 +2339,15 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_ShortFile) {
const int kIntermediateSize = 1331;
// Size of file is slightly shorter than the size known to DownloadItem.
- std::vector<char> buffer(kIntermediateSize - 100);
- request_handler.GetPatternBytes(
- parameters.pattern_generator_seed, 0, buffer.size(), buffer.data());
+ std::string output = TestDownloadHttpResponse::GetPatternBytes(
+ parameters.pattern_generator_seed, 0, kIntermediateSize - 100);
{
base::ThreadRestrictions::ScopedAllowIO allow_io_for_test_setup;
ASSERT_EQ(
kIntermediateSize - 100,
- base::WriteFile(intermediate_file_path, buffer.data(), buffer.size()));
+ base::WriteFile(intermediate_file_path, output.data(), output.size()));
}
- url_chain.push_back(request_handler.url());
+ url_chain.push_back(server_url);
DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem(
"F7FB1F59-7DE1-4845-AFDB-8A688F70F583", 1, intermediate_file_path,
@@ -2201,8 +2367,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_ShortFile) {
parameters.size,
download->GetTargetFilePath());
- TestDownloadRequestHandler::CompletedRequests completed_requests;
- request_handler.GetCompletedRequestInfo(&completed_requests);
+ const TestDownloadResponseHandler::CompletedRequests& completed_requests =
+ test_response_handler()->completed_requests();
// There will be two requests. The first one is issued optimistically assuming
// that the intermediate file exists and matches the size expectations set
@@ -2231,26 +2397,26 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_LongFile) {
const int kFileSize = 1024 * 1024;
const int kIntermediateSize = kFileSize / 2 + 111;
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
+ TestDownloadHttpResponse::Parameters parameters;
parameters.size = kFileSize;
- request_handler.StartServing(parameters);
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
base::FilePath intermediate_file_path =
GetDownloadDirectory().AppendASCII("intermediate");
std::vector<GURL> url_chain;
// Size of file is slightly longer than the size known to DownloadItem.
- std::vector<char> buffer(kIntermediateSize + 100);
- request_handler.GetPatternBytes(
- parameters.pattern_generator_seed, 0, buffer.size(), buffer.data());
+ std::string output = TestDownloadHttpResponse::GetPatternBytes(
+ parameters.pattern_generator_seed, 0, kIntermediateSize + 100);
{
base::ThreadRestrictions::ScopedAllowIO allow_io_for_test_setup;
ASSERT_EQ(
kIntermediateSize + 100,
- base::WriteFile(intermediate_file_path, buffer.data(), buffer.size()));
+ base::WriteFile(intermediate_file_path, output.data(), output.size()));
}
- url_chain.push_back(request_handler.url());
+ url_chain.push_back(server_url);
DownloadItem* download = DownloadManagerForShell(shell())->CreateDownloadItem(
"F7FB1F59-7DE1-4845-AFDB-8A688F70F583", 1, intermediate_file_path,
@@ -2270,8 +2436,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_LongFile) {
parameters.size,
download->GetTargetFilePath());
- TestDownloadRequestHandler::CompletedRequests completed_requests;
- request_handler.GetCompletedRequestInfo(&completed_requests);
+ const TestDownloadResponseHandler::CompletedRequests& completed_requests =
+ test_response_handler()->completed_requests();
// There should be only one request. The intermediate file should be truncated
// to the expected size, and the request should be issued for the remainder.
@@ -2286,14 +2452,17 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeRestoredDownload_LongFile) {
// Test that the referrer header is set correctly for a download that's resumed
// partially.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ReferrerForPartialResumption) {
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- request_handler.StartServing(parameters);
+ SetupErrorInjectionDownloads();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
GURL document_url = embedded_test_server()->GetURL(
std::string("/download/download-link.html?dl=")
- .append(request_handler.url().spec()));
+ .append(server_url.spec()));
DownloadItem* download = StartDownloadAndReturnItem(shell(), document_url);
WaitForInterrupt(download);
@@ -2307,11 +2476,15 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ReferrerForPartialResumption) {
parameters.pattern_generator_seed, parameters.size,
download->GetTargetFilePath()));
- TestDownloadRequestHandler::CompletedRequests requests;
- request_handler.GetCompletedRequestInfo(&requests);
+ const TestDownloadResponseHandler::CompletedRequests& requests =
+ test_response_handler()->completed_requests();
ASSERT_GE(2u, requests.size());
- EXPECT_EQ(document_url.spec(), requests.back()->referrer);
+ net::test_server::HttpRequest last_request = requests.back()->http_request;
+ EXPECT_TRUE(last_request.headers.find(net::HttpRequestHeaders::kReferer) !=
+ last_request.headers.end());
+ EXPECT_EQ(document_url.spec(),
+ last_request.headers.at(net::HttpRequestHeaders::kReferer));
}
// Test that the referrer header is dropped for HTTP downloads from HTTPS.
@@ -2526,32 +2699,26 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeServerError) {
download->GetLastReason());
}
-namespace {
-
-void ErrorReturningRequestHandler(
- const net::HttpRequestHeaders& headers,
- const TestDownloadRequestHandler::OnStartResponseCallback& callback) {
- callback.Run(std::string(), net::ERR_INTERNET_DISCONNECTED);
-}
-
-} // namespace
-
// A request that fails before it gets a response from the server should also
// result in a DownloadItem that's created in an interrupted state.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeNetworkError) {
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
-
- parameters.on_start_handler = base::Bind(&ErrorReturningRequestHandler);
- request_handler.StartServing(parameters);
+ SetupErrorInjectionDownloads();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters;
+ // Simulate a network failure by injecting an error before the response
+ // header.
+ parameters.injected_errors.push(-1);
+ parameters.inject_error_cb = inject_error_callback();
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
GURL document_url = embedded_test_server()->GetURL(
std::string("/download/download-attribute.html?target=") +
- request_handler.url().spec());
+ server_url.spec());
DownloadItem* download = StartDownloadAndReturnItem(shell(), document_url);
WaitForInterrupt(download);
- EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
+ EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED,
download->GetLastReason());
}
@@ -2728,23 +2895,34 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, ParallelDownloadComplete) {
EXPECT_TRUE(base::FeatureList::IsEnabled(features::kParallelDownloading));
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters;
parameters.etag = "ABC";
parameters.size = 5097152;
+
// Only parallel download needs to specify the connection type to http 1.1,
// other tests will automatically fall back to non-parallel download even if
// the ParallelDownloading feature is enabled based on
// fieldtrial_testing_config.json.
parameters.connection_type = net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1;
- request_handler.StartServing(parameters);
-
- DownloadItem* download =
- StartDownloadAndReturnItem(shell(), request_handler.url());
+ TestRequestPauseHandler request_pause_handler;
+ parameters.on_pause_handler = request_pause_handler.GetOnPauseHandler();
+ parameters.pause_offset = DownloadRequestCore::kDownloadByteStreamSize;
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
+
+ DownloadItem* download = StartDownloadAndReturnItem(shell(), server_url);
+ // Send some data for the first request and pause it so download won't
+ // complete before other parallel requests are created.
+ request_pause_handler.WaitForCallback();
+ while (test_response_handler()->completed_requests().size() == 0)
+ base::RunLoop().RunUntilIdle();
+ // Now resume the first request.
+ request_pause_handler.Resume();
WaitForCompletion(download);
- TestDownloadRequestHandler::CompletedRequests completed_requests;
- request_handler.GetCompletedRequestInfo(&completed_requests);
+ const TestDownloadResponseHandler::CompletedRequests& completed_requests =
+ test_response_handler()->completed_requests();
EXPECT_EQ(kTestRequestCount, static_cast<int>(completed_requests.size()));
ReadAndVerifyFileContents(parameters.pattern_generator_seed, parameters.size,
@@ -2755,41 +2933,40 @@ IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, ParallelDownloadComplete) {
IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, ParallelDownloadResumption) {
EXPECT_TRUE(base::FeatureList::IsEnabled(features::kParallelDownloading));
- TestDownloadRequestHandler request_handler;
- TestDownloadRequestHandler::Parameters parameters;
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters;
parameters.etag = "ABC";
parameters.size = 3000000;
parameters.last_modified = std::string();
parameters.connection_type = net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1;
- request_handler.StartServing(parameters);
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
base::FilePath intermediate_file_path =
GetDownloadDirectory().AppendASCII("intermediate");
std::vector<GURL> url_chain;
- url_chain.push_back(request_handler.url());
+ url_chain.push_back(server_url);
// Create an intermediate file that contains 3 chunks of data.
const int kIntermediateSize = 1000;
- std::vector<char> buffer(kIntermediateSize);
- request_handler.GetPatternBytes(parameters.pattern_generator_seed, 0,
- buffer.size(), buffer.data());
+ std::string output;
{
base::ThreadRestrictions::ScopedAllowIO allow_io_for_test_setup;
base::File file(intermediate_file_path,
base::File::FLAG_CREATE | base::File::FLAG_WRITE);
ASSERT_TRUE(file.IsValid());
- request_handler.GetPatternBytes(parameters.pattern_generator_seed, 0,
- buffer.size(), buffer.data());
+ output = TestDownloadHttpResponse::GetPatternBytes(
+ parameters.pattern_generator_seed, 0, kIntermediateSize);
EXPECT_EQ(kIntermediateSize,
- file.Write(0, buffer.data(), kIntermediateSize));
- request_handler.GetPatternBytes(parameters.pattern_generator_seed, 1000000,
- buffer.size(), buffer.data());
+ file.Write(0, output.data(), kIntermediateSize));
+ output = TestDownloadHttpResponse::GetPatternBytes(
+ parameters.pattern_generator_seed, 1000000, kIntermediateSize);
EXPECT_EQ(kIntermediateSize,
- file.Write(1000000, buffer.data(), kIntermediateSize));
- request_handler.GetPatternBytes(parameters.pattern_generator_seed, 2000000,
- buffer.size(), buffer.data());
+ file.Write(1000000, output.data(), kIntermediateSize));
+ output = TestDownloadHttpResponse::GetPatternBytes(
+ parameters.pattern_generator_seed, 2000000, kIntermediateSize);
EXPECT_EQ(kIntermediateSize,
- file.Write(2000000, buffer.data(), kIntermediateSize));
+ file.Write(2000000, output.data(), kIntermediateSize));
file.Close();
}
@@ -2813,8 +2990,8 @@ IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, ParallelDownloadResumption) {
download->Resume();
WaitForCompletion(download);
- TestDownloadRequestHandler::CompletedRequests completed_requests;
- request_handler.GetCompletedRequestInfo(&completed_requests);
+ const TestDownloadResponseHandler::CompletedRequests& completed_requests =
+ test_response_handler()->completed_requests();
EXPECT_EQ(kTestRequestCount, static_cast<int>(completed_requests.size()));
ReadAndVerifyFileContents(parameters.pattern_generator_seed, parameters.size,
@@ -2890,19 +3067,18 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, FetchErrorResponseBody) {
// and the second response is HTTP 404, the response body of 404 should be
// fetched.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, FetchErrorResponseBodyResumption) {
- const std::string kNotFoundResponseBody = "This is 404 response body.";
- GURL url;
-
- TestDownloadRequestHandler server;
- TestDownloadRequestHandler::Parameters server_params =
- TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- url = server.url();
- server.StartServing(server_params);
+ SetupErrorInjectionDownloads();
+ GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
+ GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
+ TestDownloadHttpResponse::Parameters parameters =
+ TestDownloadHttpResponse::Parameters::WithSingleInterruption(
+ inject_error_callback());
+ TestDownloadHttpResponse::StartServing(parameters, server_url);
// Wait for an interrupted download.
std::unique_ptr<DownloadUrlParameters> download_parameters(
DownloadUrlParameters::CreateForWebContentsMainFrame(
- shell()->web_contents(), url, TRAFFIC_ANNOTATION_FOR_TESTS));
+ shell()->web_contents(), server_url, TRAFFIC_ANNOTATION_FOR_TESTS));
download_parameters->set_fetch_error_body(true);
DownloadManager* download_manager = DownloadManagerForShell(shell());
@@ -2910,17 +3086,16 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, FetchErrorResponseBodyResumption) {
observer.reset(new content::DownloadTestObserverInterrupted(
download_manager, 1,
content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
-
download_manager->DownloadUrl(std::move(download_parameters));
observer->WaitForFinished();
-
std::vector<DownloadItem*> items;
download_manager->GetAllDownloads(&items);
EXPECT_EQ(1u, items.size());
// Now server will start to response 404 with empty body.
const std::string k404ResponseHeader = "HTTP/1.1 404 Not found\r\n\r\n";
- server.StartServingStaticResponse(k404ResponseHeader);
+ TestDownloadHttpResponse::StartServingStaticResponse(k404ResponseHeader,
+ server_url);
DownloadItem* download = items[0];
// The fetch error body should be cached in download item. The download should
@@ -2938,4 +3113,29 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, FetchErrorResponseBodyResumption) {
}
}
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, ForceDownloadMhtml) {
+ // Force downloading the MHTML.
+ test_resource_dispatcher_host_delegate()
+ ->set_allowed_rendering_mhtml_over_http(false);
+
+ NavigateToURLAndWaitForDownload(
+ shell(), embedded_test_server()->GetURL("/download/hello.mhtml"),
+ DownloadItem::COMPLETE);
+}
+
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, AllowRenderMhtml) {
+ // Allows loading the MHTML, instead of downloading it.
+ test_resource_dispatcher_host_delegate()
+ ->set_allowed_rendering_mhtml_over_http(true);
+
+ GURL url = embedded_test_server()->GetURL("/download/hello.mhtml");
+ auto observer = std::make_unique<content::TestNavigationObserver>(url);
+ observer->WatchExistingWebContents();
+ observer->StartWatchingNewWebContents();
+
+ NavigateToURL(shell(), url);
+
+ observer->WaitForNavigationFinished();
+}
+
} // namespace content
diff --git a/chromium/content/browser/download/download_create_info.cc b/chromium/content/browser/download/download_create_info.cc
index 4f795e10c25..e7741fb7cfa 100644
--- a/chromium/content/browser/download/download_create_info.cc
+++ b/chromium/content/browser/download/download_create_info.cc
@@ -15,7 +15,6 @@ namespace content {
DownloadCreateInfo::DownloadCreateInfo(
const base::Time& start_time,
- const net::NetLogWithSource& net_log,
std::unique_ptr<DownloadSaveInfo> save_info)
: download_id(DownloadItem::kInvalidId),
start_time(start_time),
@@ -25,14 +24,12 @@ DownloadCreateInfo::DownloadCreateInfo(
transient(false),
result(DOWNLOAD_INTERRUPT_REASON_NONE),
save_info(std::move(save_info)),
- request_net_log(net_log),
accept_range(false),
connection_info(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN),
method("GET") {}
DownloadCreateInfo::DownloadCreateInfo()
: DownloadCreateInfo(base::Time(),
- net::NetLogWithSource(),
base::WrapUnique(new DownloadSaveInfo)) {}
DownloadCreateInfo::~DownloadCreateInfo() {}
diff --git a/chromium/content/browser/download/download_create_info.h b/chromium/content/browser/download/download_create_info.h
index af6eac17076..acc0da4217b 100644
--- a/chromium/content/browser/download/download_create_info.h
+++ b/chromium/content/browser/download/download_create_info.h
@@ -21,7 +21,6 @@
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/download_save_info.h"
#include "net/http/http_response_info.h"
-#include "net/log/net_log_with_source.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"
@@ -35,7 +34,6 @@ namespace content {
// want to pass |DownloadItem|s between threads.
struct CONTENT_EXPORT DownloadCreateInfo {
DownloadCreateInfo(const base::Time& start_time,
- const net::NetLogWithSource& net_log,
std::unique_ptr<DownloadSaveInfo> save_info);
DownloadCreateInfo();
~DownloadCreateInfo();
@@ -105,10 +103,6 @@ struct CONTENT_EXPORT DownloadCreateInfo {
// The handle to the URLRequest sourcing this download.
std::unique_ptr<DownloadRequestHandleInterface> request_handle;
- // The request's |NetLogWithSource|, for "source_dependency" linking with the
- // download item's.
- const net::NetLogWithSource request_net_log;
-
// ---------------------------------------------------------------------------
// The remaining fields are Entity-body properties. These are only set if
// |result| is DOWNLOAD_INTERRUPT_REASON_NONE.
diff --git a/chromium/content/browser/download/download_file.h b/chromium/content/browser/download/download_file.h
index d54d410d83a..6caa42598a1 100644
--- a/chromium/content/browser/download/download_file.h
+++ b/chromium/content/browser/download/download_file.h
@@ -98,7 +98,9 @@ class CONTENT_EXPORT DownloadFile {
virtual const base::FilePath& FullPath() const = 0;
virtual bool InProgress() const = 0;
- virtual void WasPaused() = 0;
+
+ virtual void Pause() = 0;
+ virtual void Resume() = 0;
};
} // namespace content
diff --git a/chromium/content/browser/download/download_file_factory.cc b/chromium/content/browser/download/download_file_factory.cc
index db80e1f487c..90303539832 100644
--- a/chromium/content/browser/download/download_file_factory.cc
+++ b/chromium/content/browser/download/download_file_factory.cc
@@ -16,10 +16,10 @@ DownloadFile* DownloadFileFactory::CreateFile(
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_downloads_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer) {
return new DownloadFileImpl(std::move(save_info), default_downloads_directory,
- std::move(stream), net_log, observer);
+ std::move(stream), download_id, observer);
}
} // namespace content
diff --git a/chromium/content/browser/download/download_file_factory.h b/chromium/content/browser/download/download_file_factory.h
index 832c7072826..bad3ad2af98 100644
--- a/chromium/content/browser/download/download_file_factory.h
+++ b/chromium/content/browser/download/download_file_factory.h
@@ -16,10 +16,6 @@
#include "content/common/content_export.h"
#include "url/gurl.h"
-namespace net {
-class NetLogWithSource;
-}
-
namespace content {
class DownloadDestinationObserver;
@@ -34,7 +30,7 @@ class CONTENT_EXPORT DownloadFileFactory {
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_downloads_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer);
};
diff --git a/chromium/content/browser/download/download_file_impl.cc b/chromium/content/browser/download/download_file_impl.cc
index 0b6ad7459a7..278594afb0c 100644
--- a/chromium/content/browser/download/download_file_impl.cc
+++ b/chromium/content/browser/download/download_file_impl.cc
@@ -18,19 +18,15 @@
#include "content/browser/download/download_create_info.h"
#include "content/browser/download/download_destination_observer.h"
#include "content/browser/download/download_interrupt_reasons_impl.h"
-#include "content/browser/download/download_net_log_parameters.h"
#include "content/browser/download/download_stats.h"
#include "content/browser/download/download_utils.h"
#include "content/browser/download/parallel_download_utils.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_features.h"
#include "crypto/secure_hash.h"
#include "crypto/sha2.h"
#include "mojo/public/c/system/types.h"
#include "net/base/io_buffer.h"
-#include "net/log/net_log.h"
-#include "net/log/net_log_event_type.h"
-#include "net/log/net_log_source.h"
-#include "net/log/net_log_source_type.h"
namespace content {
@@ -78,12 +74,12 @@ DownloadFileImpl::SourceStream::~SourceStream() = default;
void DownloadFileImpl::SourceStream::Initialize() {
if (stream_handle_.is_null())
return;
- binding_ = base::MakeUnique<mojo::Binding<mojom::DownloadStreamClient>>(
+ binding_ = std::make_unique<mojo::Binding<mojom::DownloadStreamClient>>(
this, std::move(stream_handle_->client_request));
binding_->set_connection_error_handler(base::Bind(
&DownloadFileImpl::SourceStream::OnStreamCompleted,
base::Unretained(this), mojom::NetworkRequestStatus::USER_CANCELED));
- handle_watcher_ = base::MakeUnique<mojo::SimpleWatcher>(
+ handle_watcher_ = std::make_unique<mojo::SimpleWatcher>(
FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC);
}
@@ -200,25 +196,22 @@ DownloadFileImpl::DownloadFileImpl(
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& download_item_net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer)
: DownloadFileImpl(std::move(save_info),
default_download_directory,
- download_item_net_log,
+ download_id,
observer) {
- source_streams_[save_info_->offset] = base::MakeUnique<SourceStream>(
+ source_streams_[save_info_->offset] = std::make_unique<SourceStream>(
save_info_->offset, save_info_->length, std::move(stream));
}
DownloadFileImpl::DownloadFileImpl(
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
- const net::NetLogWithSource& download_item_net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer)
- : net_log_(
- net::NetLogWithSource::Make(download_item_net_log.net_log(),
- net::NetLogSourceType::DOWNLOAD_FILE)),
- file_(net_log_),
+ : file_(download_id),
save_info_(std::move(save_info)),
default_download_directory_(default_download_directory),
potential_file_length_(kUnknownContentLength),
@@ -227,14 +220,14 @@ DownloadFileImpl::DownloadFileImpl(
record_stream_bandwidth_(false),
bytes_seen_with_parallel_streams_(0),
bytes_seen_without_parallel_streams_(0),
+ is_paused_(false),
+ download_id_(download_id),
observer_(observer),
weak_factory_(this) {
- download_item_net_log.AddEvent(
- net::NetLogEventType::DOWNLOAD_FILE_CREATED,
- net_log_.source().ToEventParametersCallback());
- net_log_.BeginEvent(
- net::NetLogEventType::DOWNLOAD_FILE_ACTIVE,
- download_item_net_log.source().ToEventParametersCallback());
+ TRACE_EVENT_INSTANT0("download", "DownloadFileCreated",
+ TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("download", "DownloadFileActive",
+ download_id);
DETACH_FROM_SEQUENCE(sequence_checker_);
}
@@ -242,7 +235,8 @@ DownloadFileImpl::DownloadFileImpl(
DownloadFileImpl::~DownloadFileImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_ACTIVE);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("download", "DownloadFileActive",
+ download_id_);
}
void DownloadFileImpl::Initialize(
@@ -296,7 +290,7 @@ void DownloadFileImpl::AddInputStream(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
source_streams_[offset] =
- base::MakeUnique<SourceStream>(offset, length, std::move(stream));
+ std::make_unique<SourceStream>(offset, length, std::move(stream));
OnSourceStreamAdded(source_streams_[offset].get());
}
@@ -400,6 +394,22 @@ bool DownloadFileImpl::ShouldRetryFailedRename(DownloadInterruptReason reason) {
return reason == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR;
}
+DownloadInterruptReason DownloadFileImpl::HandleStreamCompletionStatus(
+ SourceStream* source_stream) {
+ DownloadInterruptReason reason = source_stream->GetCompletionStatus();
+ if (source_stream->length() == DownloadSaveInfo::kLengthFullContent &&
+ !received_slices_.empty() &&
+ (source_stream->offset() == received_slices_.back().offset +
+ received_slices_.back().received_bytes) &&
+ reason ==
+ DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE) {
+ // We are probably reaching the end of the stream, don't treat this
+ // as an error.
+ return DOWNLOAD_INTERRUPT_REASON_NONE;
+ }
+ return reason;
+}
+
void DownloadFileImpl::RenameWithRetryInternal(
std::unique_ptr<RenameParameters> parameters) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -504,15 +514,34 @@ bool DownloadFileImpl::InProgress() const {
return file_.in_progress();
}
-void DownloadFileImpl::WasPaused() {
+void DownloadFileImpl::Pause() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ is_paused_ = true;
record_stream_bandwidth_ = false;
}
-// TODO(qinmin): This only works with byte stream now, need to handle callback
-// from data pipe.
+void DownloadFileImpl::Resume() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(is_paused_);
+ is_paused_ = false;
+
+ if (!base::FeatureList::IsEnabled(features::kNetworkService))
+ return;
+
+ for (auto& stream : source_streams_) {
+ SourceStream* source_stream = stream.second.get();
+ if (!source_stream->is_finished()) {
+ StreamActive(source_stream, MOJO_RESULT_OK);
+ }
+ }
+}
+
void DownloadFileImpl::StreamActive(SourceStream* source_stream,
MojoResult result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (base::FeatureList::IsEnabled(features::kNetworkService) && is_paused_)
+ return;
+
base::TimeTicks start(base::TimeTicks::Now());
base::TimeTicks now;
scoped_refptr<net::IOBuffer> incoming_data;
@@ -595,25 +624,14 @@ void DownloadFileImpl::StreamActive(SourceStream* source_stream,
else
NotifyObserver(source_stream, reason, state, should_terminate);
- if (net_log_.IsCapturing()) {
- net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED,
- base::Bind(&FileStreamDrainedNetLogCallback,
- total_incoming_data_size, num_buffers));
- }
+ TRACE_EVENT_INSTANT2("download", "DownloadStreamDrained",
+ TRACE_EVENT_SCOPE_THREAD, "stream_size",
+ total_incoming_data_size, "num_buffers", num_buffers);
}
void DownloadFileImpl::OnStreamCompleted(SourceStream* source_stream) {
- DownloadInterruptReason reason = source_stream->GetCompletionStatus();
- if (source_stream->length() == DownloadSaveInfo::kLengthFullContent &&
- !received_slices_.empty() &&
- (source_stream->offset() == received_slices_.back().offset +
- received_slices_.back().received_bytes) &&
- reason ==
- DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE) {
- // We are probably reaching the end of the stream, don't treat this
- // as an error.
- reason = DOWNLOAD_INTERRUPT_REASON_NONE;
- }
+ DownloadInterruptReason reason = HandleStreamCompletionStatus(source_stream);
+
SendUpdate();
NotifyObserver(source_stream, reason, SourceStream::COMPLETE, false);
diff --git a/chromium/content/browser/download/download_file_impl.h b/chromium/content/browser/download/download_file_impl.h
index e28d39f7353..3285a64b31d 100644
--- a/chromium/content/browser/download/download_file_impl.h
+++ b/chromium/content/browser/download/download_file_impl.h
@@ -30,7 +30,6 @@
#include "content/public/common/download_stream.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/simple_watcher.h"
-#include "net/log/net_log_with_source.h"
namespace content {
class ByteStreamReader;
@@ -49,7 +48,7 @@ class CONTENT_EXPORT DownloadFileImpl : public DownloadFile {
DownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_downloads_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer);
~DownloadFileImpl() override;
@@ -76,28 +75,10 @@ class CONTENT_EXPORT DownloadFileImpl : public DownloadFile {
void SetPotentialFileLength(int64_t length) override;
const base::FilePath& FullPath() const override;
bool InProgress() const override;
- void WasPaused() override;
+ void Pause() override;
+ void Resume() override;
protected:
- // For test class overrides.
- // Write data from the offset to the file.
- // On OS level, it will seek to the |offset| and write from there.
- virtual DownloadInterruptReason WriteDataToFile(int64_t offset,
- const char* data,
- size_t data_len);
-
- virtual base::TimeDelta GetRetryDelayForFailedRename(int attempt_number);
-
- virtual bool ShouldRetryFailedRename(DownloadInterruptReason reason);
-
- private:
- friend class DownloadFileTest;
-
- DownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info,
- const base::FilePath& default_downloads_directory,
- const net::NetLogWithSource& net_log,
- base::WeakPtr<DownloadDestinationObserver> observer);
-
// Wrapper of a ByteStreamReader or ScopedDataPipeConsumerHandle, and the meta
// data needed to write to a slice of the target file.
//
@@ -205,8 +186,27 @@ class CONTENT_EXPORT DownloadFileImpl : public DownloadFile {
DISALLOW_COPY_AND_ASSIGN(SourceStream);
};
- typedef std::unordered_map<int64_t, std::unique_ptr<SourceStream>>
- SourceStreams;
+ // For test class overrides.
+ // Write data from the offset to the file.
+ // On OS level, it will seek to the |offset| and write from there.
+ virtual DownloadInterruptReason WriteDataToFile(int64_t offset,
+ const char* data,
+ size_t data_len);
+
+ virtual base::TimeDelta GetRetryDelayForFailedRename(int attempt_number);
+
+ virtual bool ShouldRetryFailedRename(DownloadInterruptReason reason);
+
+ virtual DownloadInterruptReason HandleStreamCompletionStatus(
+ SourceStream* source_stream);
+
+ private:
+ friend class DownloadFileTest;
+
+ DownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info,
+ const base::FilePath& default_downloads_directory,
+ uint32_t download_id,
+ base::WeakPtr<DownloadDestinationObserver> observer);
// Options for RenameWithRetryInternal.
enum RenameOption {
@@ -305,8 +305,6 @@ class CONTENT_EXPORT DownloadFileImpl : public DownloadFile {
// Print the internal states for debugging.
void DebugStates() const;
- net::NetLogWithSource net_log_;
-
// The base file instance.
BaseFile file_;
@@ -320,6 +318,8 @@ class CONTENT_EXPORT DownloadFileImpl : public DownloadFile {
// Map of the offset and the source stream that represents the slice
// starting from offset.
+ typedef std::unordered_map<int64_t, std::unique_ptr<SourceStream>>
+ SourceStreams;
SourceStreams source_streams_;
// Used to cancel the request on UI thread, since the ByteStreamReader can't
@@ -348,6 +348,13 @@ class CONTENT_EXPORT DownloadFileImpl : public DownloadFile {
std::vector<DownloadItem::ReceivedSlice> received_slices_;
+ // Used to track whether the download is paused or not. This value is ignored
+ // when network service is disabled as download pause/resumption is handled
+ // by DownloadRequestCore in that case.
+ bool is_paused_;
+
+ uint32_t download_id_;
+
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtr<DownloadDestinationObserver> observer_;
diff --git a/chromium/content/browser/download/download_file_unittest.cc b/chromium/content/browser/download/download_file_unittest.cc
index 64192135bd1..9b7b0d0f8e7 100644
--- a/chromium/content/browser/download/download_file_unittest.cc
+++ b/chromium/content/browser/download/download_file_unittest.cc
@@ -30,7 +30,6 @@
#include "net/base/file_stream.h"
#include "net/base/mock_file_stream.h"
#include "net/base/net_errors.h"
-#include "net/log/net_log_with_source.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -121,12 +120,12 @@ class TestDownloadFileImpl : public DownloadFileImpl {
TestDownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_downloads_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer)
: DownloadFileImpl(std::move(save_info),
default_downloads_directory,
std::move(stream),
- net_log,
+ download_id,
observer) {}
protected:
@@ -165,7 +164,7 @@ class DownloadFileTest : public testing::Test {
DownloadFileTest()
: observer_(new StrictMock<MockDownloadDestinationObserver>),
observer_factory_(observer_.get()),
- input_stream_(NULL),
+ input_stream_(nullptr),
additional_streams_(
std::vector<StrictMock<MockByteStreamReader>*>{nullptr, nullptr}),
bytes_(-1),
@@ -228,9 +227,9 @@ class DownloadFileTest : public testing::Test {
download_file_.reset(new TestDownloadFileImpl(
std::move(save_info), base::FilePath(),
- base::MakeUnique<DownloadManager::InputStream>(
+ std::make_unique<DownloadManager::InputStream>(
std::unique_ptr<ByteStreamReader>(input_stream_)),
- net::NetLogWithSource(), observer_factory_.GetWeakPtr()));
+ DownloadItem::kInvalidId, observer_factory_.GetWeakPtr()));
EXPECT_CALL(*input_stream_, Read(_, _))
.WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
@@ -653,7 +652,7 @@ TEST_F(DownloadFileTest, RenameUniquifies) {
base::WriteFile(path_1, file_data, sizeof(file_data)));
ASSERT_TRUE(base::PathExists(path_1));
- EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, RenameAndUniquify(path_1, NULL));
+ EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, RenameAndUniquify(path_1, nullptr));
EXPECT_TRUE(base::PathExists(path_1_suffixed));
FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
@@ -704,7 +703,7 @@ TEST_P(DownloadFileTestWithRename, RenameError) {
// Expect nulling out of further processing.
EXPECT_CALL(*input_stream_, RegisterCallback(IsNullCallback()));
- ExpectPermissionError(InvokeSelectedRenameMethod(target_path, NULL));
+ ExpectPermissionError(InvokeSelectedRenameMethod(target_path, nullptr));
EXPECT_FALSE(base::PathExists(target_path_suffixed));
}
@@ -814,7 +813,7 @@ TEST_F(DownloadFileTest, StreamEmptySuccess) {
// Test that calling the sink_callback_ on an empty stream shouldn't
// do anything.
- AppendDataToFile(NULL, 0);
+ AppendDataToFile(nullptr, 0);
// Finish the download this way and make sure we see it on the observer.
FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
@@ -919,7 +918,7 @@ TEST_F(DownloadFileTest, MutipleStreamsWrite) {
// Activate the streams.
download_file_->AddInputStream(
- base::MakeUnique<DownloadManager::InputStream>(
+ std::make_unique<DownloadManager::InputStream>(
std::unique_ptr<ByteStreamReader>(additional_streams_[0])),
stream_0_length, DownloadSaveInfo::kLengthFullContent);
sink_callback_.Run();
@@ -966,11 +965,11 @@ TEST_F(DownloadFileTest, MutipleStreamsLimitedLength) {
// Activate all the streams.
download_file_->AddInputStream(
- base::MakeUnique<DownloadManager::InputStream>(
+ std::make_unique<DownloadManager::InputStream>(
std::unique_ptr<ByteStreamReader>(additional_streams_[0])),
stream_0_length, stream_1_length);
download_file_->AddInputStream(
- base::MakeUnique<DownloadManager::InputStream>(
+ std::make_unique<DownloadManager::InputStream>(
std::unique_ptr<ByteStreamReader>(additional_streams_[1])),
stream_0_length + stream_1_length, DownloadSaveInfo::kLengthFullContent);
sink_callback_.Run();
@@ -1012,7 +1011,7 @@ TEST_F(DownloadFileTest, MutipleStreamsFirstStreamWriteAllData) {
additional_streams_[0] = new StrictMock<MockByteStreamReader>();
download_file_->AddInputStream(
- base::MakeUnique<DownloadManager::InputStream>(
+ std::make_unique<DownloadManager::InputStream>(
std::unique_ptr<ByteStreamReader>(additional_streams_[0])),
stream_0_length - 1, DownloadSaveInfo::kLengthFullContent);
base::RunLoop().RunUntilIdle();
@@ -1053,7 +1052,7 @@ TEST_F(DownloadFileTest, SecondStreamStartingOffsetAlreadyWritten) {
.RetiresOnSaturation();
download_file_->AddInputStream(
- base::MakeUnique<DownloadManager::InputStream>(
+ std::make_unique<DownloadManager::InputStream>(
std::unique_ptr<ByteStreamReader>(additional_streams_[0])),
0, DownloadSaveInfo::kLengthFullContent);
diff --git a/chromium/content/browser/download/download_item_factory.h b/chromium/content/browser/download/download_item_factory.h
index c9a083b11fa..a1f64a885bb 100644
--- a/chromium/content/browser/download/download_item_factory.h
+++ b/chromium/content/browser/download/download_item_factory.h
@@ -23,10 +23,6 @@ namespace base {
class FilePath;
}
-namespace net {
-class NetLogWithSource;
-}
-
namespace content {
class DownloadItem;
@@ -65,14 +61,12 @@ public:
bool opened,
base::Time last_access_time,
bool transient,
- const std::vector<DownloadItem::ReceivedSlice>& received_slices,
- const net::NetLogWithSource& net_log) = 0;
+ const std::vector<DownloadItem::ReceivedSlice>& received_slices) = 0;
virtual DownloadItemImpl* CreateActiveItem(
DownloadItemImplDelegate* delegate,
uint32_t download_id,
- const DownloadCreateInfo& info,
- const net::NetLogWithSource& net_log) = 0;
+ const DownloadCreateInfo& info) = 0;
virtual DownloadItemImpl* CreateSavePageItem(
DownloadItemImplDelegate* delegate,
@@ -80,8 +74,7 @@ public:
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
- std::unique_ptr<DownloadRequestHandleInterface> request_handle,
- const net::NetLogWithSource& net_log) = 0;
+ std::unique_ptr<DownloadRequestHandleInterface> request_handle) = 0;
};
} // namespace content
diff --git a/chromium/content/browser/download/download_item_impl.cc b/chromium/content/browser/download/download_item_impl.cc
index 80844327b5e..2b5c11bded7 100644
--- a/chromium/content/browser/download/download_item_impl.cc
+++ b/chromium/content/browser/download/download_item_impl.cc
@@ -37,13 +37,13 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
+#include "components/download/downloader/in_progress/in_progress_cache.h"
#include "content/browser/download/download_create_info.h"
#include "content/browser/download/download_file.h"
#include "content/browser/download/download_interrupt_reasons_impl.h"
#include "content/browser/download/download_item_impl_delegate.h"
#include "content/browser/download/download_job_factory.h"
#include "content/browser/download/download_job_impl.h"
-#include "content/browser/download/download_net_log_parameters.h"
#include "content/browser/download/download_request_handle.h"
#include "content/browser/download/download_stats.h"
#include "content/browser/download/download_task_runner.h"
@@ -61,10 +61,6 @@
#include "content/public/common/referrer.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
-#include "net/log/net_log.h"
-#include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
-#include "net/log/net_log_source.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
namespace content {
@@ -127,6 +123,101 @@ bool IsCancellation(DownloadInterruptReason reason) {
reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED;
}
+std::string GetDownloadTypeNames(DownloadItem::DownloadType type) {
+ switch (type) {
+ case DownloadItem::TYPE_ACTIVE_DOWNLOAD:
+ return "NEW_DOWNLOAD";
+ case DownloadItem::TYPE_HISTORY_IMPORT:
+ return "HISTORY_IMPORT";
+ case DownloadItem::TYPE_SAVE_PAGE_AS:
+ return "SAVE_PAGE_AS";
+ default:
+ NOTREACHED();
+ return "INVALID_TYPE";
+ }
+}
+
+std::string GetDownloadDangerNames(DownloadDangerType type) {
+ switch (type) {
+ case DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
+ return "NOT_DANGEROUS";
+ case DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE:
+ return "DANGEROUS_FILE";
+ case DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
+ return "DANGEROUS_URL";
+ case DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
+ return "DANGEROUS_CONTENT";
+ case DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
+ return "MAYBE_DANGEROUS_CONTENT";
+ case DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT:
+ return "UNCOMMON_CONTENT";
+ case DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
+ return "USER_VALIDATED";
+ case DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
+ return "DANGEROUS_HOST";
+ case DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED:
+ return "POTENTIALLY_UNWANTED";
+ default:
+ NOTREACHED();
+ return "UNKNOWN_DANGER_TYPE";
+ }
+}
+
+class DownloadItemActivatedData
+ : public base::trace_event::ConvertableToTraceFormat {
+ public:
+ DownloadItemActivatedData(DownloadItem::DownloadType download_type,
+ uint32_t download_id,
+ std::string original_url,
+ std::string final_url,
+ std::string file_name,
+ DownloadDangerType danger_type,
+ int64_t start_offset,
+ bool has_user_gesture)
+ : download_type_(download_type),
+ download_id_(download_id),
+ original_url_(original_url),
+ final_url_(final_url),
+ file_name_(file_name),
+ danger_type_(danger_type),
+ start_offset_(start_offset),
+ has_user_gesture_(has_user_gesture) {}
+
+ ~DownloadItemActivatedData() override = default;
+
+ void AppendAsTraceFormat(std::string* out) const override {
+ out->append("{");
+ out->append(base::StringPrintf(
+ "\"type\":\"%s\",", GetDownloadTypeNames(download_type_).c_str()));
+ out->append(base::StringPrintf("\"id\":\"%d\",", download_id_));
+ out->append(
+ base::StringPrintf("\"original_url\":\"%s\",", original_url_.c_str()));
+ out->append(
+ base::StringPrintf("\"final_url\":\"%s\",", final_url_.c_str()));
+ out->append(
+ base::StringPrintf("\"file_name\":\"%s\",", file_name_.c_str()));
+ out->append(
+ base::StringPrintf("\"danger_type\":\"%s\",",
+ GetDownloadDangerNames(danger_type_).c_str()));
+ out->append(
+ base::StringPrintf("\"start_offset\":\"%" PRId64 "\",", start_offset_));
+ out->append(base::StringPrintf("\"has_user_gesture\":\"%s\"",
+ has_user_gesture_ ? "true" : "false"));
+ out->append("}");
+ }
+
+ private:
+ DownloadItem::DownloadType download_type_;
+ uint32_t download_id_;
+ std::string original_url_;
+ std::string final_url_;
+ std::string file_name_;
+ DownloadDangerType danger_type_;
+ int64_t start_offset_;
+ bool has_user_gesture_;
+ DISALLOW_COPY_AND_ASSIGN(DownloadItemActivatedData);
+};
+
} // namespace
const uint32_t DownloadItem::kInvalidId = 0;
@@ -220,8 +311,7 @@ DownloadItemImpl::DownloadItemImpl(
bool opened,
base::Time last_access_time,
bool transient,
- const std::vector<DownloadItem::ReceivedSlice>& received_slices,
- const net::NetLogWithSource& net_log)
+ const std::vector<DownloadItem::ReceivedSlice>& received_slices)
: request_info_(url_chain,
referrer_url,
site_url,
@@ -255,21 +345,19 @@ DownloadItemImpl::DownloadItemImpl(
last_modified_time_(last_modified),
etag_(etag),
received_slices_(received_slices),
- net_log_(net_log),
is_updating_observers_(false),
weak_ptr_factory_(this) {
delegate_->Attach();
DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL ||
state_ == CANCELLED_INTERNAL);
DCHECK(base::IsValidGUID(guid_));
- Init(false /* not actively downloading */, SRC_HISTORY_IMPORT);
+ Init(false /* not actively downloading */, TYPE_HISTORY_IMPORT);
}
// Constructing for a regular download:
DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
uint32_t download_id,
- const DownloadCreateInfo& info,
- const net::NetLogWithSource& net_log)
+ const DownloadCreateInfo& info)
: request_info_(info.url_chain,
info.referrer_url,
info.site_url,
@@ -300,21 +388,13 @@ DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
: TARGET_DISPOSITION_OVERWRITE),
last_modified_time_(info.last_modified),
etag_(info.etag),
- net_log_(net_log),
is_updating_observers_(false),
fetch_error_body_(info.fetch_error_body),
weak_ptr_factory_(this) {
delegate_->Attach();
- Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD);
+ Init(true /* actively downloading */, TYPE_ACTIVE_DOWNLOAD);
- // Link the event sources.
- net_log_.AddEvent(
- net::NetLogEventType::DOWNLOAD_URL_REQUEST,
- info.request_net_log.source().ToEventParametersCallback());
-
- info.request_net_log.AddEvent(
- net::NetLogEventType::DOWNLOAD_STARTED,
- net_log_.source().ToEventParametersCallback());
+ TRACE_EVENT_INSTANT0("download", "DownloadStarted", TRACE_EVENT_SCOPE_THREAD);
}
// Constructing for the "Save Page As..." feature:
@@ -324,8 +404,7 @@ DownloadItemImpl::DownloadItemImpl(
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
- std::unique_ptr<DownloadRequestHandleInterface> request_handle,
- const net::NetLogWithSource& net_log)
+ std::unique_ptr<DownloadRequestHandleInterface> request_handle)
: request_info_(url),
guid_(base::GenerateGUID()),
download_id_(download_id),
@@ -335,13 +414,12 @@ DownloadItemImpl::DownloadItemImpl(
state_(IN_PROGRESS_INTERNAL),
delegate_(delegate),
destination_info_(path, path, 0, false, std::string(), base::Time()),
- net_log_(net_log),
is_updating_observers_(false),
weak_ptr_factory_(this) {
job_ = DownloadJobFactory::CreateJob(this, std::move(request_handle),
DownloadCreateInfo(), true);
delegate_->Attach();
- Init(true /* actively downloading */, SRC_SAVE_PAGE_AS);
+ Init(true /* actively downloading */, TYPE_SAVE_PAGE_AS);
}
DownloadItemImpl::~DownloadItemImpl() {
@@ -398,9 +476,9 @@ void DownloadItemImpl::ValidateDangerousDownload() {
danger_type_ = DOWNLOAD_DANGER_TYPE_USER_VALIDATED;
- net_log_.AddEvent(
- net::NetLogEventType::DOWNLOAD_ITEM_SAFETY_STATE_UPDATED,
- base::Bind(&ItemCheckedNetLogCallback, GetDangerType()));
+ TRACE_EVENT_INSTANT1("download", "DownloadItemSaftyStateUpdated",
+ TRACE_EVENT_SCOPE_THREAD, "danger_type",
+ GetDownloadDangerNames(danger_type_).c_str());
UpdateObservers(); // TODO(asanka): This is potentially unsafe. The download
// may not be in a consistent state or around at all after
@@ -465,13 +543,6 @@ void DownloadItemImpl::Pause() {
case TARGET_PENDING_INTERNAL:
job_->Pause();
UpdateObservers();
- if (download_file_) {
- GetDownloadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&DownloadFile::WasPaused,
- // Safe because we control download file lifetime.
- base::Unretained(download_file_.get())));
- }
return;
case MAX_DOWNLOAD_INTERNAL_STATE:
@@ -859,7 +930,8 @@ bool DownloadItemImpl::CanOpenDownload() {
// they aren't owned by the download system.
const bool is_complete = GetState() == DownloadItem::COMPLETE;
return (!IsDone() || is_complete) && !IsTemporary() &&
- !file_externally_removed_;
+ !file_externally_removed_ &&
+ delegate_->IsMostRecentDownloadItemAtFilePath(this);
}
bool DownloadItemImpl::ShouldOpenFileBasedOnExtension() {
@@ -1160,10 +1232,6 @@ DownloadItemImpl::DestinationObserverAsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
-const net::NetLogWithSource& DownloadItemImpl::GetNetLogWithSource() const {
- return net_log_;
-}
-
void DownloadItemImpl::SetTotalBytes(int64_t total_bytes) {
total_bytes_ = total_bytes;
}
@@ -1227,11 +1295,9 @@ void DownloadItemImpl::DestinationUpdate(
UpdateProgress(bytes_so_far, bytes_per_sec);
received_slices_ = received_slices;
- if (net_log_.IsCapturing()) {
- net_log_.AddEvent(
- net::NetLogEventType::DOWNLOAD_ITEM_UPDATED,
- net::NetLog::Int64Callback("bytes_so_far", GetReceivedBytes()));
- }
+ TRACE_EVENT_INSTANT1("download", "DownloadItemUpdated",
+ TRACE_EVENT_SCOPE_THREAD, "bytes_so_far",
+ GetReceivedBytes());
UpdateObservers();
}
@@ -1274,11 +1340,11 @@ void DownloadItemImpl::DestinationCompleted(
// **** Download progression cascade
void DownloadItemImpl::Init(bool active,
- DownloadType download_type) {
+ DownloadItem::DownloadType download_type) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::string file_name;
- if (download_type == SRC_HISTORY_IMPORT) {
+ if (download_type == TYPE_HISTORY_IMPORT) {
// target_path_ works for History and Save As versions.
file_name = GetTargetFilePath().AsUTF8Unsafe();
} else {
@@ -1292,14 +1358,17 @@ void DownloadItemImpl::Init(bool active,
file_name = GetURL().ExtractFileName();
}
- net::NetLogParametersCallback active_data =
- base::Bind(&ItemActivatedNetLogCallback, this, download_type, &file_name);
+ auto active_data = base::MakeUnique<DownloadItemActivatedData>(
+ download_type, GetId(), GetOriginalUrl().spec(), GetURL().spec(),
+ file_name, GetDangerType(), GetReceivedBytes(), HasUserGesture());
+
if (active) {
- net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_ITEM_ACTIVE,
- active_data);
+ TRACE_EVENT_ASYNC_BEGIN1("download", "DownloadItemActive", download_id_,
+ "download_item", std::move(active_data));
} else {
- net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_ITEM_ACTIVE,
- active_data);
+ TRACE_EVENT_INSTANT1("download", "DownloadItemActive",
+ TRACE_EVENT_SCOPE_THREAD, "download_item",
+ std::move(active_data));
}
DVLOG(20) << __func__ << "() " << DebugString(true);
@@ -1439,6 +1508,9 @@ void DownloadItemImpl::OnDownloadTargetDetermined(
const base::FilePath& intermediate_path,
DownloadInterruptReason interrupt_reason) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (state_ == CANCELLED_INTERNAL)
+ return;
+
DCHECK(state_ == TARGET_PENDING_INTERNAL ||
state_ == INTERRUPTED_TARGET_PENDING_INTERNAL);
DVLOG(20) << __func__ << "() target_path:" << target_path.value()
@@ -1695,11 +1767,13 @@ void DownloadItemImpl::Completed() {
DCHECK(AllDataSaved());
destination_info_.end_time = base::Time::Now();
TransitionTo(COMPLETE_INTERNAL);
- RecordDownloadCompleted(start_tick_, GetReceivedBytes());
+
+ bool is_parallelizable = job_ && job_->IsParallelizable();
+ RecordDownloadCompleted(start_tick_, GetReceivedBytes(), is_parallelizable);
if (!GetBrowserContext()->IsOffTheRecord()) {
RecordDownloadCount(COMPLETED_COUNT_NORMAL_PROFILE);
}
- if (job_ && job_->IsParallelizable()) {
+ if (is_parallelizable) {
RecordParallelizableDownloadCount(COMPLETED_COUNT,
IsParallelDownloadEnabled());
int64_t content_length = -1;
@@ -2020,37 +2094,39 @@ void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) {
DCHECK(GetFullPath() == GetTargetFilePath())
<< "Current output path must match target path.";
- net_log_.AddEvent(
- net::NetLogEventType::DOWNLOAD_ITEM_COMPLETING,
- base::Bind(&ItemCompletingNetLogCallback, GetReceivedBytes(),
- &destination_info_.hash));
+ TRACE_EVENT_INSTANT2("download", "DownloadItemCompleting",
+ TRACE_EVENT_SCOPE_THREAD, "bytes_so_far",
+ GetReceivedBytes(), "final_hash",
+ destination_info_.hash);
break;
case COMPLETE_INTERNAL:
- net_log_.AddEvent(
- net::NetLogEventType::DOWNLOAD_ITEM_FINISHED,
- base::Bind(&ItemFinishedNetLogCallback, auto_opened_));
+ TRACE_EVENT_INSTANT1("download", "DownloadItemFinished",
+ TRACE_EVENT_SCOPE_THREAD, "auto_opened",
+ auto_opened_ ? "yes" : "no");
break;
case INTERRUPTED_INTERNAL:
DCHECK(!download_file_)
<< "Download file must be released prior to interruption.";
DCHECK_NE(last_reason_, DOWNLOAD_INTERRUPT_REASON_NONE);
- net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_ITEM_INTERRUPTED,
- base::Bind(&ItemInterruptedNetLogCallback, last_reason_,
- GetReceivedBytes()));
+ TRACE_EVENT_INSTANT2("download", "DownloadItemInterrupted",
+ TRACE_EVENT_SCOPE_THREAD, "interrupt_reason",
+ DownloadInterruptReasonToString(last_reason_),
+ "bytes_so_far", GetReceivedBytes());
break;
case RESUMING_INTERNAL:
- net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_ITEM_RESUMED,
- base::Bind(&ItemResumingNetLogCallback, false,
- last_reason_, GetReceivedBytes()));
+ TRACE_EVENT_INSTANT2("download", "DownloadItemResumed",
+ TRACE_EVENT_SCOPE_THREAD, "interrupt_reason",
+ DownloadInterruptReasonToString(last_reason_),
+ "bytes_so_far", GetReceivedBytes());
break;
case CANCELLED_INTERNAL:
- net_log_.AddEvent(
- net::NetLogEventType::DOWNLOAD_ITEM_CANCELED,
- base::Bind(&ItemCanceledNetLogCallback, GetReceivedBytes()));
+ TRACE_EVENT_INSTANT1("download", "DownloadItemCancelled",
+ TRACE_EVENT_SCOPE_THREAD, "bytes_so_far",
+ GetReceivedBytes());
break;
case MAX_DOWNLOAD_INTERNAL_STATE:
@@ -2070,22 +2146,25 @@ void DownloadItemImpl::TransitionTo(DownloadInternalState new_state) {
// Termination
if (is_done && !was_done)
- net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_ITEM_ACTIVE);
+ TRACE_EVENT_ASYNC_END0("download", "DownloadItemActive", download_id_);
// Resumption
if (was_done && !is_done) {
std::string file_name(GetTargetFilePath().BaseName().AsUTF8Unsafe());
- net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_ITEM_ACTIVE,
- base::Bind(&ItemActivatedNetLogCallback, this,
- SRC_ACTIVE_DOWNLOAD, &file_name));
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
+ "download", "DownloadItemActive", download_id_, "download_item",
+ base::MakeUnique<DownloadItemActivatedData>(
+ TYPE_ACTIVE_DOWNLOAD, GetId(), GetOriginalUrl().spec(),
+ GetURL().spec(), file_name, GetDangerType(), GetReceivedBytes(),
+ HasUserGesture()));
}
}
void DownloadItemImpl::SetDangerType(DownloadDangerType danger_type) {
if (danger_type != danger_type_) {
- net_log_.AddEvent(
- net::NetLogEventType::DOWNLOAD_ITEM_SAFETY_STATE_UPDATED,
- base::Bind(&ItemCheckedNetLogCallback, danger_type));
+ TRACE_EVENT_INSTANT1("download", "DownloadItemSaftyStateUpdated",
+ TRACE_EVENT_SCOPE_THREAD, "danger_type",
+ GetDownloadDangerNames(danger_type).c_str());
}
// Only record the Malicious UMA stat if it's going from {not malicious} ->
// {malicious}.
@@ -2108,9 +2187,10 @@ void DownloadItemImpl::SetFullPath(const base::FilePath& new_path) {
<< DebugString(true);
DCHECK(!new_path.empty());
- net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_ITEM_RENAMED,
- base::Bind(&ItemRenamedNetLogCallback,
- &destination_info_.current_path, &new_path));
+ TRACE_EVENT_INSTANT2("download", "DownloadItemRenamed",
+ TRACE_EVENT_SCOPE_THREAD, "old_filename",
+ destination_info_.current_path.AsUTF8Unsafe(),
+ "new_filename", new_path.AsUTF8Unsafe());
destination_info_.current_path = new_path;
}
@@ -2204,6 +2284,16 @@ void DownloadItemImpl::ResumeInterruptedDownload(
download_params->set_hash_state(std::move(hash_state_));
download_params->set_fetch_error_body(fetch_error_body_);
+ auto* manager_delegate = GetBrowserContext()->GetDownloadManagerDelegate();
+ if (manager_delegate) {
+ download::InProgressCache* in_progress_cache =
+ manager_delegate->GetInProgressCache();
+ download::DownloadEntry* entry =
+ in_progress_cache->RetrieveEntry(GetGuid());
+ if (entry)
+ download_params->set_request_origin(entry->request_origin);
+ }
+
// Note that resumed downloads disallow redirects. Hence the referrer URL
// (which is the contents of the Referer header for the last download request)
// will only be sent to the URL returned by GetURL().
diff --git a/chromium/content/browser/download/download_item_impl.h b/chromium/content/browser/download/download_item_impl.h
index 6a7fc588cce..ed6795de65b 100644
--- a/chromium/content/browser/download/download_item_impl.h
+++ b/chromium/content/browser/download/download_item_impl.h
@@ -18,12 +18,10 @@
#include "base/observer_list.h"
#include "base/time/time.h"
#include "content/browser/download/download_destination_observer.h"
-#include "content/browser/download/download_net_log_parameters.h"
#include "content/browser/download/download_request_handle.h"
#include "content/common/content_export.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/download_item.h"
-#include "net/log/net_log_with_source.h"
#include "url/gurl.h"
namespace content {
@@ -178,15 +176,13 @@ class CONTENT_EXPORT DownloadItemImpl
bool opened,
base::Time last_access_time,
bool transient,
- const std::vector<DownloadItem::ReceivedSlice>& received_slices,
- const net::NetLogWithSource& net_log);
+ const std::vector<DownloadItem::ReceivedSlice>& received_slices);
// Constructing for a regular download.
// |net_log| is constructed externally for our use.
DownloadItemImpl(DownloadItemImplDelegate* delegate,
uint32_t id,
- const DownloadCreateInfo& info,
- const net::NetLogWithSource& net_log);
+ const DownloadCreateInfo& info);
// Constructing for the "Save Page As..." feature:
// |net_log| is constructed externally for our use.
@@ -196,8 +192,7 @@ class CONTENT_EXPORT DownloadItemImpl
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
- std::unique_ptr<DownloadRequestHandleInterface> request_handle,
- const net::NetLogWithSource& net_log);
+ std::unique_ptr<DownloadRequestHandleInterface> request_handle);
~DownloadItemImpl() override;
@@ -307,9 +302,6 @@ class CONTENT_EXPORT DownloadItemImpl
virtual base::WeakPtr<DownloadDestinationObserver>
DestinationObserverAsWeakPtr();
- // Get the download's NetLogWithSource.
- virtual const net::NetLogWithSource& GetNetLogWithSource() const;
-
// DownloadItemImpl routines only needed by SavePackage ----------------------
// Called by SavePackage to set the total number of bytes on the item.
@@ -497,9 +489,8 @@ class CONTENT_EXPORT DownloadItemImpl
// Construction common to all constructors. |active| should be true for new
// downloads and false for downloads from the history.
- // |download_type| indicates to the net log system what kind of download
- // this is.
- void Init(bool active, DownloadType download_type);
+ // |download_type| indicates to the trace event what kind of download this is.
+ void Init(bool active, DownloadItem::DownloadType download_type);
// Callback from file thread when we initialize the DownloadFile.
void OnDownloadFileInitialized(DownloadInterruptReason result);
@@ -747,9 +738,6 @@ class CONTENT_EXPORT DownloadItemImpl
// The data slices that have been received so far.
std::vector<DownloadItem::ReceivedSlice> received_slices_;
- // Net log to use for this download.
- const net::NetLogWithSource net_log_;
-
std::unique_ptr<DownloadJob> job_;
// Value of |received_bytes_| at the time the download was interrupted with
diff --git a/chromium/content/browser/download/download_item_impl_delegate.cc b/chromium/content/browser/download/download_item_impl_delegate.cc
index 2e3367aa07f..73424b5f31a 100644
--- a/chromium/content/browser/download/download_item_impl_delegate.cc
+++ b/chromium/content/browser/download/download_item_impl_delegate.cc
@@ -65,13 +65,18 @@ void DownloadItemImplDelegate::ResumeInterruptedDownload(
uint32_t id) {}
BrowserContext* DownloadItemImplDelegate::GetBrowserContext() const {
- return NULL;
+ return nullptr;
}
void DownloadItemImplDelegate::UpdatePersistence(DownloadItemImpl* download) {}
void DownloadItemImplDelegate::OpenDownload(DownloadItemImpl* download) {}
+bool DownloadItemImplDelegate::IsMostRecentDownloadItemAtFilePath(
+ DownloadItemImpl* download) {
+ return true;
+}
+
void DownloadItemImplDelegate::ShowDownloadInShell(DownloadItemImpl* download) {
}
diff --git a/chromium/content/browser/download/download_item_impl_delegate.h b/chromium/content/browser/download/download_item_impl_delegate.h
index fd193ac464d..9e6fe9792a8 100644
--- a/chromium/content/browser/download/download_item_impl_delegate.h
+++ b/chromium/content/browser/download/download_item_impl_delegate.h
@@ -85,6 +85,10 @@ class CONTENT_EXPORT DownloadItemImplDelegate {
// Opens the file associated with this download.
virtual void OpenDownload(DownloadItemImpl* download);
+ // Returns whether this is the most recent download in the rare event where
+ // multiple downloads are associated with the same file path.
+ virtual bool IsMostRecentDownloadItemAtFilePath(DownloadItemImpl* download);
+
// Shows the download via the OS shell.
virtual void ShowDownloadInShell(DownloadItemImpl* download);
diff --git a/chromium/content/browser/download/download_item_impl_unittest.cc b/chromium/content/browser/download/download_item_impl_unittest.cc
index f682b55cf8d..6b0e71bf323 100644
--- a/chromium/content/browser/download/download_item_impl_unittest.cc
+++ b/chromium/content/browser/download/download_item_impl_unittest.cc
@@ -277,9 +277,8 @@ class DownloadItemTest : public testing::Test {
DownloadItemImpl* CreateDownloadItemWithCreateInfo(
std::unique_ptr<DownloadCreateInfo> info) {
- DownloadItemImpl* download =
- new DownloadItemImpl(mock_delegate(), next_download_id_++,
- *(info.get()), net::NetLogWithSource());
+ DownloadItemImpl* download = new DownloadItemImpl(
+ mock_delegate(), next_download_id_++, *(info.get()));
allocated_downloads_[download] = base::WrapUnique(download);
return download;
}
@@ -296,9 +295,8 @@ class DownloadItemTest : public testing::Test {
// called.
DownloadItemImpl* CreateDownloadItem() {
create_info_->download_id = ++next_download_id_;
- DownloadItemImpl* download =
- new DownloadItemImpl(mock_delegate(), create_info_->download_id,
- *create_info_, net::NetLogWithSource());
+ DownloadItemImpl* download = new DownloadItemImpl(
+ mock_delegate(), create_info_->download_id, *create_info_);
allocated_downloads_[download] = base::WrapUnique(download);
return download;
}
@@ -322,7 +320,7 @@ class DownloadItemTest : public testing::Test {
}
std::unique_ptr<MockRequestHandle> request_handle =
- base::MakeUnique<NiceMock<MockRequestHandle>>();
+ std::make_unique<NiceMock<MockRequestHandle>>();
item->Start(std::move(download_file), std::move(request_handle),
*create_info_);
task_environment_.RunUntilIdle();
@@ -852,9 +850,9 @@ TEST_F(DownloadItemTest, AutomaticResumption_AttemptLimit) {
for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) {
SCOPED_TRACE(::testing::Message() << "Iteration " << i);
- mock_download_file = base::MakeUnique<NiceMock<MockDownloadFile>>();
+ mock_download_file = std::make_unique<NiceMock<MockDownloadFile>>();
mock_download_file_ref = mock_download_file.get();
- mock_request_handle = base::MakeUnique<NiceMock<MockRequestHandle>>();
+ mock_request_handle = std::make_unique<NiceMock<MockRequestHandle>>();
ON_CALL(*mock_download_file_ref, FullPath())
.WillByDefault(ReturnRefOfCopy(base::FilePath()));
@@ -1168,9 +1166,9 @@ TEST_F(DownloadItemTest, Start) {
// file initialization failing.
TEST_F(DownloadItemTest, InitDownloadFileFails) {
DownloadItemImpl* item = CreateDownloadItem();
- std::unique_ptr<MockDownloadFile> file = base::MakeUnique<MockDownloadFile>();
+ std::unique_ptr<MockDownloadFile> file = std::make_unique<MockDownloadFile>();
std::unique_ptr<MockRequestHandle> request_handle =
- base::MakeUnique<MockRequestHandle>();
+ std::make_unique<MockRequestHandle>();
base::HistogramTester histogram_tester;
EXPECT_CALL(*file, Cancel());
@@ -1242,7 +1240,7 @@ TEST_F(DownloadItemTest, StartFailedDownload) {
DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED),
1);
EXPECT_EQ(target_path, item->GetTargetFilePath());
- CleanupItem(item, NULL, DownloadItem::INTERRUPTED);
+ CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
}
// Test that the delegate is invoked after the download file is renamed.
diff --git a/chromium/content/browser/download/download_job.cc b/chromium/content/browser/download/download_job.cc
index 30e0d437cbe..eb8a11da517 100644
--- a/chromium/content/browser/download/download_job.cc
+++ b/chromium/content/browser/download/download_job.cc
@@ -28,9 +28,18 @@ void DownloadJob::Cancel(bool user_cancel) {
}
void DownloadJob::Pause() {
+ is_paused_ = true;
+
+ DownloadFile* download_file = download_item_->download_file_.get();
+ if (download_file) {
+ GetDownloadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DownloadFile::Pause,
+ // Safe because we control download file lifetime.
+ base::Unretained(download_file)));
+ }
if (request_handle_)
request_handle_->PauseRequest();
- is_paused_ = true;
}
void DownloadJob::Resume(bool resume_request) {
@@ -38,6 +47,15 @@ void DownloadJob::Resume(bool resume_request) {
if (!resume_request)
return;
+ DownloadFile* download_file = download_item_->download_file_.get();
+ if (download_file) {
+ GetDownloadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DownloadFile::Resume,
+ // Safe because we control download file lifetime.
+ base::Unretained(download_file)));
+ }
+
if (request_handle_)
request_handle_->ResumeRequest();
}
diff --git a/chromium/content/browser/download/download_job_factory.cc b/chromium/content/browser/download/download_job_factory.cc
index 79a9376eb96..0c7e01e3587 100644
--- a/chromium/content/browser/download/download_job_factory.cc
+++ b/chromium/content/browser/download/download_job_factory.cc
@@ -96,20 +96,19 @@ std::unique_ptr<DownloadJob> DownloadJobFactory::CreateJob(
const DownloadCreateInfo& create_info,
bool is_save_package_download) {
if (is_save_package_download) {
- return base::MakeUnique<SavePackageDownloadJob>(download_item,
+ return std::make_unique<SavePackageDownloadJob>(download_item,
std::move(req_handle));
}
bool is_parallelizable = IsParallelizableDownload(create_info, download_item);
// Build parallel download job.
if (IsParallelDownloadEnabled() && is_parallelizable) {
- return base::MakeUnique<ParallelDownloadJob>(download_item,
- std::move(req_handle),
- create_info);
+ return std::make_unique<ParallelDownloadJob>(
+ download_item, std::move(req_handle), create_info);
}
// An ordinary download job.
- return base::MakeUnique<DownloadJobImpl>(download_item, std::move(req_handle),
+ return std::make_unique<DownloadJobImpl>(download_item, std::move(req_handle),
is_parallelizable);
}
diff --git a/chromium/content/browser/download/download_job_unittest.cc b/chromium/content/browser/download/download_job_unittest.cc
index ee758ad2f8b..9721059d0b2 100644
--- a/chromium/content/browser/download/download_job_unittest.cc
+++ b/chromium/content/browser/download/download_job_unittest.cc
@@ -24,10 +24,10 @@ class DownloadJobTest : public testing::Test {
~DownloadJobTest() override = default;
void SetUp() override {
- item_delegate_ = base::MakeUnique<DownloadItemImplDelegate>();
+ item_delegate_ = std::make_unique<DownloadItemImplDelegate>();
download_item_ =
- base::MakeUnique<NiceMock<MockDownloadItemImpl>>(item_delegate_.get());
- download_job_ = base::MakeUnique<MockDownloadJob>(download_item_.get());
+ std::make_unique<NiceMock<MockDownloadItemImpl>>(item_delegate_.get());
+ download_job_ = std::make_unique<MockDownloadJob>(download_item_.get());
}
content::TestBrowserThreadBundle browser_threads_;
diff --git a/chromium/content/browser/download/download_manager_impl.cc b/chromium/content/browser/download/download_manager_impl.cc
index 68293acdadc..360d672ee13 100644
--- a/chromium/content/browser/download/download_manager_impl.cc
+++ b/chromium/content/browser/download/download_manager_impl.cc
@@ -22,6 +22,8 @@
#include "base/supports_user_data.h"
#include "base/synchronization/lock.h"
#include "build/build_config.h"
+#include "components/download/downloader/in_progress/download_entry.h"
+#include "components/download/downloader/in_progress/in_progress_cache.h"
#include "content/browser/byte_stream.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/download/download_create_info.h"
@@ -49,6 +51,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_features.h"
#include "content/public/common/previews_state.h"
#include "content/public/common/referrer.h"
@@ -56,8 +59,6 @@
#include "net/base/load_flags.h"
#include "net/base/request_priority.h"
#include "net/base/upload_bytes_element_reader.h"
-#include "net/log/net_log_source_type.h"
-#include "net/log/net_log_with_source.h"
#include "net/url_request/url_request_context.h"
#include "storage/browser/blob/blob_url_request_job_factory.h"
#include "url/origin.h"
@@ -69,6 +70,19 @@
namespace content {
namespace {
+WebContents* GetWebContents(int render_process_id,
+ int render_frame_id,
+ int frame_tree_node_id) {
+ DCHECK(IsBrowserSideNavigationEnabled());
+
+ WebContents* web_contents = WebContents::FromRenderFrameHost(
+ RenderFrameHost::FromID(render_process_id, render_frame_id));
+ if (web_contents)
+ return web_contents;
+
+ return WebContents::FromFrameTreeNodeId(frame_tree_node_id);
+}
+
StoragePartitionImpl* GetStoragePartition(BrowserContext* context,
int render_process_id,
int render_frame_id) {
@@ -103,7 +117,7 @@ void CreateInterruptedDownload(
base::WeakPtr<DownloadManagerImpl> download_manager) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::unique_ptr<DownloadCreateInfo> failed_created_info(
- new DownloadCreateInfo(base::Time::Now(), net::NetLogWithSource(),
+ new DownloadCreateInfo(base::Time::Now(),
base::WrapUnique(new DownloadSaveInfo)));
failed_created_info->url_chain.push_back(params->url());
failed_created_info->result = reason;
@@ -112,7 +126,7 @@ void CreateInterruptedDownload(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&DownloadManager::StartDownload, download_manager,
std::move(failed_created_info),
- base::MakeUnique<DownloadManager::InputStream>(
+ std::make_unique<DownloadManager::InputStream>(
std::move(empty_byte_stream)),
params->callback()));
}
@@ -180,36 +194,57 @@ DownloadManagerImpl::UniqueUrlDownloadHandlerPtr BeginResourceDownload(
return nullptr;
}
+ ResourceRequestInfo::WebContentsGetter getter =
+ base::Bind(&GetWebContents, params->render_process_host_id(),
+ params->render_frame_host_routing_id(), -1);
+ // TODO(qinmin): Check the storage permission before creating the URLLoader.
+ // This is already done for context menu download, but it is missing for
+ // download service and download resumption.
return DownloadManagerImpl::UniqueUrlDownloadHandlerPtr(
ResourceDownloader::BeginDownload(
download_manager, std::move(params), std::move(request),
- url_loader_factory_getter, file_system_context, download_id, false)
+ url_loader_factory_getter, file_system_context, getter, download_id,
+ false)
.release());
}
// Creates a ResourceDownloader to own the URLLoader and intercept the response,
// and passes it back to the DownloadManager.
void InterceptNavigationResponse(
- base::OnceCallback<void(DownloadManagerImpl::UniqueUrlDownloadHandlerPtr)>
- callback,
base::WeakPtr<DownloadManagerImpl> download_manager,
const scoped_refptr<ResourceResponse>& response,
mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const SSLStatus& ssl_status,
+ net::CertStatus cert_status,
+ int frame_tree_node_id,
std::unique_ptr<ResourceRequest> resource_request,
std::unique_ptr<ThrottlingURLLoader> url_loader,
- base::Optional<ResourceRequestCompletionStatus> completion_status) {
+ std::vector<GURL> url_chain,
+ base::Optional<network::URLLoaderCompletionStatus> status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DownloadManagerImpl::UniqueUrlDownloadHandlerPtr resource_downloader(
- ResourceDownloader::InterceptNavigationResponse(
- download_manager, std::move(resource_request), response,
- std::move(consumer_handle), ssl_status, std::move(url_loader),
- std::move(completion_status))
- .release());
+ GURL url = resource_request->url;
+ std::string method = resource_request->method;
+ ResourceRequestInfo::WebContentsGetter getter =
+ base::Bind(&GetWebContents, ChildProcessHost::kInvalidUniqueID,
+ MSG_ROUTING_NONE, frame_tree_node_id);
+ std::unique_ptr<ResourceDownloader> resource_downloader =
+ ResourceDownloader::CreateWithURLLoader(
+ download_manager, std::move(resource_request), getter,
+ std::move(url_loader), std::move(status));
+
+ // Use Unretained() is safe as |resource_downloader| will be deleted on
+ // the IO thread.
+ base::OnceClosure start_interception_cb = base::BindOnce(
+ &ResourceDownloader::StartNavigationInterception,
+ base::Unretained(resource_downloader.get()), response,
+ std::move(consumer_handle), cert_status, std::move(url_chain));
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), std::move(resource_downloader)));
+ base::BindOnce(&DownloadManagerImpl::CheckDownloadAllowed,
+ download_manager, getter, url, method,
+ DownloadManagerImpl::UniqueUrlDownloadHandlerPtr(
+ resource_downloader.release()),
+ std::move(start_interception_cb)));
}
class DownloadItemFactoryImpl : public DownloadItemFactory {
@@ -243,22 +278,20 @@ class DownloadItemFactoryImpl : public DownloadItemFactory {
bool opened,
base::Time last_access_time,
bool transient,
- const std::vector<DownloadItem::ReceivedSlice>& received_slices,
- const net::NetLogWithSource& net_log) override {
+ const std::vector<DownloadItem::ReceivedSlice>& received_slices)
+ override {
return new DownloadItemImpl(
delegate, guid, download_id, current_path, target_path, url_chain,
referrer_url, site_url, tab_url, tab_refererr_url, mime_type,
original_mime_type, start_time, end_time, etag, last_modified,
received_bytes, total_bytes, hash, state, danger_type, interrupt_reason,
- opened, last_access_time, transient, received_slices, net_log);
+ opened, last_access_time, transient, received_slices);
}
- DownloadItemImpl* CreateActiveItem(
- DownloadItemImplDelegate* delegate,
- uint32_t download_id,
- const DownloadCreateInfo& info,
- const net::NetLogWithSource& net_log) override {
- return new DownloadItemImpl(delegate, download_id, info, net_log);
+ DownloadItemImpl* CreateActiveItem(DownloadItemImplDelegate* delegate,
+ uint32_t download_id,
+ const DownloadCreateInfo& info) override {
+ return new DownloadItemImpl(delegate, download_id, info);
}
DownloadItemImpl* CreateSavePageItem(
@@ -267,10 +300,9 @@ class DownloadItemFactoryImpl : public DownloadItemFactory {
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
- std::unique_ptr<DownloadRequestHandleInterface> request_handle,
- const net::NetLogWithSource& net_log) override {
+ std::unique_ptr<DownloadRequestHandleInterface> request_handle) override {
return new DownloadItemImpl(delegate, download_id, path, url, mime_type,
- std::move(request_handle), net_log);
+ std::move(request_handle));
}
};
@@ -283,15 +315,60 @@ base::FilePath GetTemporaryDownloadDirectory() {
} // namespace
-DownloadManagerImpl::DownloadManagerImpl(net::NetLog* net_log,
- BrowserContext* browser_context)
+// Responsible for persisting the in-progress metadata associated with a
+// download.
+class InProgressDownloadObserver : public DownloadItem::Observer {
+ public:
+ explicit InProgressDownloadObserver(
+ download::InProgressCache* in_progress_cache);
+ ~InProgressDownloadObserver() override;
+
+ private:
+ // DownloadItem::Observer
+ void OnDownloadUpdated(DownloadItem* download) override;
+ void OnDownloadRemoved(DownloadItem* download) override;
+
+ // The persistent cache to store in-progress metadata.
+ download::InProgressCache* in_progress_cache_;
+
+ DISALLOW_COPY_AND_ASSIGN(InProgressDownloadObserver);
+};
+
+InProgressDownloadObserver::InProgressDownloadObserver(
+ download::InProgressCache* in_progress_cache)
+ : in_progress_cache_(in_progress_cache) {}
+
+InProgressDownloadObserver::~InProgressDownloadObserver() = default;
+
+void InProgressDownloadObserver::OnDownloadUpdated(DownloadItem* download) {
+ // TODO(crbug.com/778425): Properly handle fail/resume/retry for downloads
+ // that are in the INTERRUPTED state for a long time.
+ switch (download->GetState()) {
+ case DownloadItem::DownloadState::COMPLETE:
+ case DownloadItem::DownloadState::CANCELLED:
+ if (in_progress_cache_)
+ in_progress_cache_->RemoveEntry(download->GetGuid());
+ break;
+ case DownloadItem::DownloadState::IN_PROGRESS:
+ // TODO(crbug.com/778425): After RetrieveEntry has been implemented, do a
+ // check to make sure the entry exists in the cache.
+ break;
+ default:
+ break;
+ }
+}
+
+void InProgressDownloadObserver::OnDownloadRemoved(DownloadItem* download) {
+ in_progress_cache_->RemoveEntry(download->GetGuid());
+}
+
+DownloadManagerImpl::DownloadManagerImpl(BrowserContext* browser_context)
: item_factory_(new DownloadItemFactoryImpl()),
file_factory_(new DownloadFileFactory()),
shutdown_needed_(true),
initialized_(false),
browser_context_(browser_context),
delegate_(nullptr),
- net_log_(net_log),
weak_factory_(this) {
DCHECK(browser_context);
}
@@ -305,10 +382,7 @@ DownloadItemImpl* DownloadManagerImpl::CreateActiveItem(
const DownloadCreateInfo& info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!base::ContainsKey(downloads_, id));
- net::NetLogWithSource net_log =
- net::NetLogWithSource::Make(net_log_, net::NetLogSourceType::DOWNLOAD);
- DownloadItemImpl* download =
- item_factory_->CreateActiveItem(this, id, info, net_log);
+ DownloadItemImpl* download = item_factory_->CreateActiveItem(this, id, info);
downloads_[id] = base::WrapUnique(download);
downloads_by_guid_[download->GetGuid()] = download;
return download;
@@ -468,10 +542,10 @@ void DownloadManagerImpl::StartDownloadWithId(
base::FilePath default_download_directory;
#if defined(USE_X11)
- // TODO(thomasanderson): Remove this when all Linux distros with
- // versions of GTK lower than 3.14.7 are no longer supported. This
- // should happen when support for Ubuntu Trusty and Debian Jessie
- // are removed.
+ // TODO(thomasanderson,crbug.com/784010): Remove this when all Linux
+ // distros with versions of GTK lower than 3.14.7 are no longer
+ // supported. This should happen when support for Ubuntu Trusty and
+ // Debian Jessie are removed.
default_download_directory = GetTemporaryDownloadDirectory();
#else
if (delegate_) {
@@ -482,14 +556,23 @@ void DownloadManagerImpl::StartDownloadWithId(
}
#endif
+ if (delegate_) {
+ if (!in_progress_download_observer_) {
+ in_progress_download_observer_.reset(
+ new InProgressDownloadObserver(delegate_->GetInProgressCache()));
+ }
+ // May already observe this item, remove observer first.
+ download->RemoveObserver(in_progress_download_observer_.get());
+ download->AddObserver(in_progress_download_observer_.get());
+ }
+
std::unique_ptr<DownloadFile> download_file;
if (info->result == DOWNLOAD_INTERRUPT_REASON_NONE) {
DCHECK(stream.get());
download_file.reset(file_factory_->CreateFile(
std::move(info->save_info), default_download_directory,
- std::move(stream), download->GetNetLogWithSource(),
- download->DestinationObserverAsWeakPtr()));
+ std::move(stream), id, download->DestinationObserverAsWeakPtr()));
}
// It is important to leave info->save_info intact in the case of an interrupt
// so that the DownloadItem can salvage what it can out of a failed resumption
@@ -574,11 +657,8 @@ void DownloadManagerImpl::CreateSavePackageDownloadItemWithId(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_NE(content::DownloadItem::kInvalidId, id);
DCHECK(!base::ContainsKey(downloads_, id));
- net::NetLogWithSource net_log =
- net::NetLogWithSource::Make(net_log_, net::NetLogSourceType::DOWNLOAD);
DownloadItemImpl* download_item = item_factory_->CreateSavePageItem(
- this, id, main_file_path, page_url, mime_type, std::move(request_handle),
- net_log);
+ this, id, main_file_path, page_url, mime_type, std::move(request_handle));
downloads_[download_item->GetId()] = base::WrapUnique(download_item);
DCHECK(!base::ContainsKey(downloads_by_guid_, download_item->GetGuid()));
downloads_by_guid_[download_item->GetGuid()] = download_item;
@@ -594,15 +674,10 @@ void DownloadManagerImpl::CreateSavePackageDownloadItemWithId(
void DownloadManagerImpl::ResumeInterruptedDownload(
std::unique_ptr<content::DownloadUrlParameters> params,
uint32_t id) {
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&BeginDownload, base::Passed(&params),
- browser_context_->GetResourceContext(), id,
- weak_factory_.GetWeakPtr()),
- base::Bind(&DownloadManagerImpl::AddUrlDownloadHandler,
- weak_factory_.GetWeakPtr()));
+ BeginDownloadInternal(std::move(params), id);
}
+
void DownloadManagerImpl::SetDownloadItemFactoryForTesting(
std::unique_ptr<DownloadItemFactory> item_factory) {
item_factory_ = std::move(item_factory);
@@ -691,13 +766,36 @@ NavigationURLLoader::NavigationInterceptionCB
DownloadManagerImpl::GetNavigationInterceptionCB(
const scoped_refptr<ResourceResponse>& response,
mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const SSLStatus& ssl_status) {
+ net::CertStatus cert_status,
+ int frame_tree_node_id) {
return base::BindOnce(
- &InterceptNavigationResponse,
- base::BindOnce(&DownloadManagerImpl::AddUrlDownloadHandler,
- weak_factory_.GetWeakPtr()),
- weak_factory_.GetWeakPtr(), response, std::move(consumer_handle),
- ssl_status);
+ &InterceptNavigationResponse, weak_factory_.GetWeakPtr(), response,
+ std::move(consumer_handle), cert_status, frame_tree_node_id);
+}
+
+void DownloadManagerImpl::CheckDownloadAllowed(
+ const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
+ const GURL& url,
+ const std::string& request_method,
+ UniqueUrlDownloadHandlerPtr downloader,
+ base::OnceClosure callback) {
+ if (delegate_) {
+ delegate_->CheckDownloadAllowed(
+ web_contents_getter, url, request_method,
+ base::BindOnce(&DownloadManagerImpl::OnDownloadAllowedCheckComplete,
+ weak_factory_.GetWeakPtr(), std::move(downloader),
+ std::move(callback)));
+ }
+}
+
+void DownloadManagerImpl::OnDownloadAllowedCheckComplete(
+ UniqueUrlDownloadHandlerPtr downloader,
+ base::OnceClosure callback,
+ bool allow) {
+ if (!allow)
+ return;
+ AddUrlDownloadHandler(std::move(downloader));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, std::move(callback));
}
int DownloadManagerImpl::RemoveDownloadsByURLAndTime(
@@ -731,34 +829,7 @@ void DownloadManagerImpl::DownloadUrl(
DCHECK_EQ("POST", params->method());
}
- // TODO(qinmin): remove false from the if statement once download works when
- // network service is enabled, or once we disable the tests that are currently
- // passing with the URLRequest code path.
- if (base::FeatureList::IsEnabled(features::kNetworkService)) {
- std::unique_ptr<ResourceRequest> request = CreateResourceRequest(
- params.get());
- StoragePartitionImpl* storage_partition =
- GetStoragePartition(browser_context_, params->render_process_host_id(),
- params->render_frame_host_routing_id());
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &BeginResourceDownload, std::move(params), std::move(request),
- storage_partition->url_loader_factory_getter(),
- base::WrapRefCounted(storage_partition->GetFileSystemContext()),
- content::DownloadItem::kInvalidId, weak_factory_.GetWeakPtr()),
- base::BindOnce(&DownloadManagerImpl::AddUrlDownloadHandler,
- weak_factory_.GetWeakPtr()));
- } else {
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&BeginDownload, std::move(params),
- browser_context_->GetResourceContext(),
- content::DownloadItem::kInvalidId,
- weak_factory_.GetWeakPtr()),
- base::BindOnce(&DownloadManagerImpl::AddUrlDownloadHandler,
- weak_factory_.GetWeakPtr()));
- }
+ BeginDownloadInternal(std::move(params), content::DownloadItem::kInvalidId);
}
void DownloadManagerImpl::AddObserver(Observer* observer) {
@@ -805,8 +876,7 @@ DownloadItem* DownloadManagerImpl::CreateDownloadItem(
site_url, tab_url, tab_refererr_url, mime_type, original_mime_type,
start_time, end_time, etag, last_modified, received_bytes, total_bytes,
hash, state, danger_type, interrupt_reason, opened, last_access_time,
- transient, received_slices,
- net::NetLogWithSource::Make(net_log_, net::NetLogSourceType::DOWNLOAD));
+ transient, received_slices);
downloads_[id] = base::WrapUnique(item);
downloads_by_guid_[guid] = item;
for (auto& observer : observers_)
@@ -898,9 +968,52 @@ void DownloadManagerImpl::OpenDownload(DownloadItemImpl* download) {
delegate_->OpenDownload(download);
}
+bool DownloadManagerImpl::IsMostRecentDownloadItemAtFilePath(
+ DownloadItemImpl* download) {
+ return delegate_ ? delegate_->IsMostRecentDownloadItemAtFilePath(download)
+ : false;
+}
+
void DownloadManagerImpl::ShowDownloadInShell(DownloadItemImpl* download) {
if (delegate_)
delegate_->ShowDownloadInShell(download);
}
+void DownloadManagerImpl::BeginDownloadInternal(
+ std::unique_ptr<content::DownloadUrlParameters> params,
+ uint32_t id) {
+ download::InProgressCache* in_progress_cache =
+ GetBrowserContext()->GetDownloadManagerDelegate()->GetInProgressCache();
+ if (in_progress_cache) {
+ in_progress_cache->AddOrReplaceEntry(
+ download::DownloadEntry(params->guid(), params->request_origin(),
+ ToDownloadSource(params->download_source())));
+ }
+
+ if (base::FeatureList::IsEnabled(features::kNetworkService)) {
+ std::unique_ptr<ResourceRequest> request = CreateResourceRequest(
+ params.get());
+ StoragePartitionImpl* storage_partition =
+ GetStoragePartition(browser_context_, params->render_process_host_id(),
+ params->render_frame_host_routing_id());
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(
+ &BeginResourceDownload, std::move(params), std::move(request),
+ storage_partition->url_loader_factory_getter(),
+ base::WrapRefCounted(storage_partition->GetFileSystemContext()),
+ id, weak_factory_.GetWeakPtr()),
+ base::BindOnce(&DownloadManagerImpl::AddUrlDownloadHandler,
+ weak_factory_.GetWeakPtr()));
+ } else {
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&BeginDownload, std::move(params),
+ browser_context_->GetResourceContext(), id,
+ weak_factory_.GetWeakPtr()),
+ base::BindOnce(&DownloadManagerImpl::AddUrlDownloadHandler,
+ weak_factory_.GetWeakPtr()));
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/download/download_manager_impl.h b/chromium/content/browser/download/download_manager_impl.h
index 14e66faf298..7d2815aaeab 100644
--- a/chromium/content/browser/download/download_manager_impl.h
+++ b/chromium/content/browser/download/download_manager_impl.h
@@ -30,10 +30,6 @@
#include "content/public/browser/download_url_parameters.h"
#include "content/public/browser/ssl_status.h"
-namespace net {
-class NetLog;
-}
-
namespace content {
class DownloadFileFactory;
class DownloadItemFactory;
@@ -51,7 +47,7 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
// Caller guarantees that |net_log| will remain valid
// for the lifetime of DownloadManagerImpl (until Shutdown() is called).
- DownloadManagerImpl(net::NetLog* net_log, BrowserContext* browser_context);
+ explicit DownloadManagerImpl(BrowserContext* browser_context);
~DownloadManagerImpl() override;
// Implementation functions (not part of the DownloadManager interface).
@@ -151,7 +147,17 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
NavigationURLLoader::NavigationInterceptionCB GetNavigationInterceptionCB(
const scoped_refptr<ResourceResponse>& response,
mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const SSLStatus& ssl_status);
+ net::CertStatus cert_status,
+ int frame_tree_node_id);
+
+ // Checks if a download is allowed, |on_download_allowed_cb| is called if
+ // the download is allowed.
+ void CheckDownloadAllowed(
+ const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
+ const GURL& url,
+ const std::string& request_method,
+ UniqueUrlDownloadHandlerPtr downloader,
+ base::OnceClosure on_download_allowed_cb);
private:
using DownloadSet = std::set<DownloadItem*>;
@@ -206,11 +212,22 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
std::unique_ptr<content::DownloadUrlParameters> params,
uint32_t id) override;
void OpenDownload(DownloadItemImpl* download) override;
+ bool IsMostRecentDownloadItemAtFilePath(DownloadItemImpl* download) override;
void ShowDownloadInShell(DownloadItemImpl* download) override;
void DownloadRemoved(DownloadItemImpl* download) override;
void AddUrlDownloadHandler(UniqueUrlDownloadHandlerPtr downloader);
+ // Helper method to start or resume a download.
+ void BeginDownloadInternal(
+ std::unique_ptr<content::DownloadUrlParameters> params,
+ uint32_t id);
+
+ // Called when download permission check is complete.
+ void OnDownloadAllowedCheckComplete(UniqueUrlDownloadHandlerPtr downloader,
+ base::OnceClosure callback,
+ bool allow);
+
// Factory for creation of downloads items.
std::unique_ptr<DownloadItemFactory> item_factory_;
@@ -240,14 +257,15 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
// Observers that want to be notified of changes to the set of downloads.
base::ObserverList<Observer> observers_;
+ // Stores information about in-progress download items.
+ std::unique_ptr<DownloadItem::Observer> in_progress_download_observer_;
+
// The current active browser context.
BrowserContext* browser_context_;
// Allows an embedder to control behavior. Guaranteed to outlive this object.
DownloadManagerDelegate* delegate_;
- net::NetLog* net_log_;
-
std::vector<UniqueUrlDownloadHandlerPtr> url_download_handlers_;
base::WeakPtrFactory<DownloadManagerImpl> weak_factory_;
diff --git a/chromium/content/browser/download/download_manager_impl_unittest.cc b/chromium/content/browser/download/download_manager_impl_unittest.cc
index 9e4379afb9b..9d6350c3a93 100644
--- a/chromium/content/browser/download/download_manager_impl_unittest.cc
+++ b/chromium/content/browser/download/download_manager_impl_unittest.cc
@@ -40,7 +40,6 @@
#include "content/public/test/mock_download_item.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
-#include "net/log/net_log_with_source.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gmock_mutant.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -127,6 +126,10 @@ class MockDownloadItemFactory
// we don't keep dangling pointers.
void RemoveItem(int id);
+ // Sets |has_observer_calls_| to reflect whether we expect to add/remove
+ // observers during the CreateActiveItem.
+ void SetHasObserverCalls(bool observer_calls);
+
// Overridden methods from DownloadItemFactory.
DownloadItemImpl* CreatePersistedItem(
DownloadItemImplDelegate* delegate,
@@ -154,42 +157,40 @@ class MockDownloadItemFactory
bool opened,
base::Time last_access_time,
bool transient,
- const std::vector<DownloadItem::ReceivedSlice>& received_slices,
- const net::NetLogWithSource& net_log) override;
- DownloadItemImpl* CreateActiveItem(
- DownloadItemImplDelegate* delegate,
- uint32_t download_id,
- const DownloadCreateInfo& info,
- const net::NetLogWithSource& net_log) override;
+ const std::vector<DownloadItem::ReceivedSlice>& received_slices) override;
+ DownloadItemImpl* CreateActiveItem(DownloadItemImplDelegate* delegate,
+ uint32_t download_id,
+ const DownloadCreateInfo& info) override;
DownloadItemImpl* CreateSavePageItem(
DownloadItemImplDelegate* delegate,
uint32_t download_id,
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
- std::unique_ptr<DownloadRequestHandleInterface> request_handle,
- const net::NetLogWithSource& net_log) override;
+ std::unique_ptr<DownloadRequestHandleInterface> request_handle) override;
private:
std::map<uint32_t, MockDownloadItemImpl*> items_;
DownloadItemImplDelegate item_delegate_;
+ bool has_observer_calls_;
DISALLOW_COPY_AND_ASSIGN(MockDownloadItemFactory);
};
-MockDownloadItemFactory::MockDownloadItemFactory() {}
+MockDownloadItemFactory::MockDownloadItemFactory()
+ : has_observer_calls_(false) {}
MockDownloadItemFactory::~MockDownloadItemFactory() {}
MockDownloadItemImpl* MockDownloadItemFactory::GetItem(int id) {
if (items_.find(id) == items_.end())
- return NULL;
+ return nullptr;
return items_[id];
}
MockDownloadItemImpl* MockDownloadItemFactory::PopItem() {
if (items_.empty())
- return NULL;
+ return nullptr;
std::map<uint32_t, MockDownloadItemImpl*>::iterator first_item =
items_.begin();
@@ -203,6 +204,10 @@ void MockDownloadItemFactory::RemoveItem(int id) {
items_.erase(id);
}
+void MockDownloadItemFactory::SetHasObserverCalls(bool has_observer_calls) {
+ has_observer_calls_ = has_observer_calls;
+}
+
DownloadItemImpl* MockDownloadItemFactory::CreatePersistedItem(
DownloadItemImplDelegate* delegate,
const std::string& guid,
@@ -229,8 +234,7 @@ DownloadItemImpl* MockDownloadItemFactory::CreatePersistedItem(
bool opened,
base::Time last_access_time,
bool transient,
- const std::vector<DownloadItem::ReceivedSlice>& received_slices,
- const net::NetLogWithSource& net_log) {
+ const std::vector<DownloadItem::ReceivedSlice>& received_slices) {
DCHECK(items_.find(download_id) == items_.end());
MockDownloadItemImpl* result =
new StrictMock<MockDownloadItemImpl>(&item_delegate_);
@@ -244,8 +248,7 @@ DownloadItemImpl* MockDownloadItemFactory::CreatePersistedItem(
DownloadItemImpl* MockDownloadItemFactory::CreateActiveItem(
DownloadItemImplDelegate* delegate,
uint32_t download_id,
- const DownloadCreateInfo& info,
- const net::NetLogWithSource& net_log) {
+ const DownloadCreateInfo& info) {
DCHECK(items_.find(download_id) == items_.end());
MockDownloadItemImpl* result =
@@ -260,6 +263,12 @@ DownloadItemImpl* MockDownloadItemFactory::CreateActiveItem(
// the download.
EXPECT_CALL(*result, MockStart(_, _));
+ // In the StartDownload case, expect the remove/add observer calls.
+ if (has_observer_calls_) {
+ EXPECT_CALL(*result, RemoveObserver(_));
+ EXPECT_CALL(*result, AddObserver(_));
+ }
+
return result;
}
@@ -269,8 +278,7 @@ DownloadItemImpl* MockDownloadItemFactory::CreateSavePageItem(
const base::FilePath& path,
const GURL& url,
const std::string& mime_type,
- std::unique_ptr<DownloadRequestHandleInterface> request_handle,
- const net::NetLogWithSource& net_log) {
+ std::unique_ptr<DownloadRequestHandleInterface> request_handle) {
DCHECK(items_.find(download_id) == items_.end());
MockDownloadItemImpl* result =
@@ -298,7 +306,7 @@ class MockDownloadFileFactory
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
std::unique_ptr<DownloadManager::InputStream> stream,
- const net::NetLogWithSource& net_log,
+ uint32_t download_id,
base::WeakPtr<DownloadDestinationObserver> observer) override {
return MockCreateFile(*save_info, stream.get());
}
@@ -410,8 +418,8 @@ class DownloadManagerTest : public testing::Test {
EXPECT_CALL(*mock_browser_context_.get(), IsOffTheRecord())
.WillRepeatedly(Return(false));
- download_manager_.reset(new DownloadManagerImpl(
- NULL, mock_browser_context_.get()));
+ download_manager_.reset(
+ new DownloadManagerImpl(mock_browser_context_.get()));
download_manager_->SetDownloadItemFactoryForTesting(
std::unique_ptr<DownloadItemFactory>(
mock_download_item_factory_.get()));
@@ -509,6 +517,10 @@ class DownloadManagerTest : public testing::Test {
base::Unretained(this)));
}
+ void SetHasObserverCalls(bool has_observer_calls) {
+ mock_download_item_factory_->SetHasObserverCalls(has_observer_calls);
+ }
+
protected:
// Key test variable; we'll keep it available to sub-classes.
std::unique_ptr<DownloadManagerImpl> download_manager_;
@@ -537,6 +549,8 @@ class DownloadManagerTest : public testing::Test {
// Confirm the appropriate invocations occur when you start a download.
TEST_F(DownloadManagerTest, StartDownload) {
+ SetHasObserverCalls(true);
+
std::unique_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
std::unique_ptr<ByteStreamReader> stream(new MockByteStreamReader);
uint32_t local_id(5); // Random value
@@ -558,7 +572,7 @@ TEST_F(DownloadManagerTest, StartDownload) {
.WillRepeatedly(Return("client-id"));
MockDownloadFile* mock_file = new MockDownloadFile;
auto input_stream =
- base::MakeUnique<DownloadManager::InputStream>(std::move(stream));
+ std::make_unique<DownloadManager::InputStream>(std::move(stream));
EXPECT_CALL(*mock_download_file_factory_.get(),
MockCreateFile(Ref(*info->save_info.get()), input_stream.get()))
.WillOnce(Return(mock_file));
@@ -566,6 +580,8 @@ TEST_F(DownloadManagerTest, StartDownload) {
download_manager_->StartDownload(std::move(info), std::move(input_stream),
DownloadUrlParameters::OnStartedCallback());
EXPECT_TRUE(download_manager_->GetDownload(local_id));
+
+ SetHasObserverCalls(false);
}
// Confirm that calling DetermineDownloadTarget behaves properly if the delegate
diff --git a/chromium/content/browser/download/download_net_log_parameters.cc b/chromium/content/browser/download/download_net_log_parameters.cc
deleted file mode 100644
index d74de475edd..00000000000
--- a/chromium/content/browser/download/download_net_log_parameters.cc
+++ /dev/null
@@ -1,212 +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/browser/download/download_net_log_parameters.h"
-
-#include <utility>
-
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/values.h"
-#include "content/public/browser/download_interrupt_reasons.h"
-#include "net/base/net_errors.h"
-#include "net/log/net_log_capture_mode.h"
-#include "url/gurl.h"
-
-namespace content {
-
-namespace {
-
-static const char* const download_type_names[] = {
- "NEW_DOWNLOAD",
- "HISTORY_IMPORT",
- "SAVE_PAGE_AS"
-};
-static const char* const download_danger_names[] = {
- "NOT_DANGEROUS",
- "DANGEROUS_FILE",
- "DANGEROUS_URL",
- "DANGEROUS_CONTENT",
- "MAYBE_DANGEROUS_CONTENT",
- "UNCOMMON_CONTENT",
- "USER_VALIDATED",
- "DANGEROUS_HOST",
- "POTENTIALLY_UNWANTED"
-};
-
-static_assert(arraysize(download_type_names) == SRC_SAVE_PAGE_AS + 1,
- "download type enum has changed");
-static_assert(arraysize(download_danger_names) == DOWNLOAD_DANGER_TYPE_MAX,
- "download danger enum has changed");
-
-} // namespace
-
-std::unique_ptr<base::Value> ItemActivatedNetLogCallback(
- const DownloadItem* download_item,
- DownloadType download_type,
- const std::string* file_name,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("type", download_type_names[download_type]);
- dict->SetString("id", base::UintToString(download_item->GetId()));
- dict->SetString("original_url", download_item->GetOriginalUrl().spec());
- dict->SetString("final_url", download_item->GetURL().spec());
- dict->SetString("file_name", *file_name);
- dict->SetString("danger_type",
- download_danger_names[download_item->GetDangerType()]);
- dict->SetString("start_offset",
- base::Int64ToString(download_item->GetReceivedBytes()));
- dict->SetBoolean("has_user_gesture", download_item->HasUserGesture());
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> ItemCheckedNetLogCallback(
- DownloadDangerType danger_type,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("danger_type", download_danger_names[danger_type]);
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> ItemRenamedNetLogCallback(
- const base::FilePath* old_filename,
- const base::FilePath* new_filename,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("old_filename", old_filename->AsUTF8Unsafe());
- dict->SetString("new_filename", new_filename->AsUTF8Unsafe());
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> ItemInterruptedNetLogCallback(
- DownloadInterruptReason reason,
- int64_t bytes_so_far,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason));
- dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far));
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> ItemResumingNetLogCallback(
- bool user_initiated,
- DownloadInterruptReason reason,
- int64_t bytes_so_far,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("user_initiated", user_initiated ? "true" : "false");
- dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason));
- dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far));
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> ItemCompletingNetLogCallback(
- int64_t bytes_so_far,
- const std::string* final_hash,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far));
- dict->SetString("final_hash",
- base::HexEncode(final_hash->data(), final_hash->size()));
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> ItemFinishedNetLogCallback(
- bool auto_opened,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("auto_opened", auto_opened ? "yes" : "no");
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> ItemCanceledNetLogCallback(
- int64_t bytes_so_far,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("bytes_so_far", base::Int64ToString(bytes_so_far));
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> FileOpenedNetLogCallback(
- const base::FilePath* file_name,
- int64_t start_offset,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("file_name", file_name->AsUTF8Unsafe());
- dict->SetString("start_offset", base::Int64ToString(start_offset));
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> FileStreamDrainedNetLogCallback(
- size_t stream_size,
- size_t num_buffers,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetInteger("stream_size", static_cast<int>(stream_size));
- dict->SetInteger("num_buffers", static_cast<int>(num_buffers));
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> FileRenamedNetLogCallback(
- const base::FilePath* old_filename,
- const base::FilePath* new_filename,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("old_filename", old_filename->AsUTF8Unsafe());
- dict->SetString("new_filename", new_filename->AsUTF8Unsafe());
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> FileErrorNetLogCallback(
- const char* operation,
- net::Error net_error,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("operation", operation);
- dict->SetInteger("net_error", net_error);
-
- return std::move(dict);
-}
-
-std::unique_ptr<base::Value> FileInterruptedNetLogCallback(
- const char* operation,
- int os_error,
- DownloadInterruptReason reason,
- net::NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetString("operation", operation);
- if (os_error != 0)
- dict->SetInteger("os_error", os_error);
- dict->SetString("interrupt_reason", DownloadInterruptReasonToString(reason));
-
- return std::move(dict);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/download/download_net_log_parameters.h b/chromium/content/browser/download/download_net_log_parameters.h
deleted file mode 100644
index 0e816b37799..00000000000
--- a/chromium/content/browser/download/download_net_log_parameters.h
+++ /dev/null
@@ -1,113 +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_BROWSER_DOWNLOAD_DOWNLOAD_NET_LOG_PARAMETERS_H_
-#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_NET_LOG_PARAMETERS_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <string>
-
-#include "content/public/browser/download_item.h"
-#include "net/base/net_errors.h"
-
-namespace base {
-class FilePath;
-class Value;
-}
-
-namespace net {
-class NetLogCaptureMode;
-}
-
-namespace content {
-
-enum DownloadType {
- SRC_ACTIVE_DOWNLOAD,
- SRC_HISTORY_IMPORT,
- SRC_SAVE_PAGE_AS
-};
-
-// Returns NetLog parameters when a DownloadItem is activated.
-std::unique_ptr<base::Value> ItemActivatedNetLogCallback(
- const DownloadItem* download_item,
- DownloadType download_type,
- const std::string* file_name,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a DownloadItem is checked for danger.
-std::unique_ptr<base::Value> ItemCheckedNetLogCallback(
- DownloadDangerType danger_type,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a DownloadItem is renamed.
-std::unique_ptr<base::Value> ItemRenamedNetLogCallback(
- const base::FilePath* old_filename,
- const base::FilePath* new_filename,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a DownloadItem is interrupted.
-std::unique_ptr<base::Value> ItemInterruptedNetLogCallback(
- DownloadInterruptReason reason,
- int64_t bytes_so_far,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a DownloadItem is resumed.
-std::unique_ptr<base::Value> ItemResumingNetLogCallback(
- bool user_initiated,
- DownloadInterruptReason reason,
- int64_t bytes_so_far,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a DownloadItem is completing.
-std::unique_ptr<base::Value> ItemCompletingNetLogCallback(
- int64_t bytes_so_far,
- const std::string* final_hash,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a DownloadItem is finished.
-std::unique_ptr<base::Value> ItemFinishedNetLogCallback(
- bool auto_opened,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a DownloadItem is canceled.
-std::unique_ptr<base::Value> ItemCanceledNetLogCallback(
- int64_t bytes_so_far,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a DownloadFile is opened.
-std::unique_ptr<base::Value> FileOpenedNetLogCallback(
- const base::FilePath* file_name,
- int64_t start_offset,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a DownloadFile is opened.
-std::unique_ptr<base::Value> FileStreamDrainedNetLogCallback(
- size_t stream_size,
- size_t num_buffers,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a DownloadFile is renamed.
-std::unique_ptr<base::Value> FileRenamedNetLogCallback(
- const base::FilePath* old_filename,
- const base::FilePath* new_filename,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters when a File has an error.
-std::unique_ptr<base::Value> FileErrorNetLogCallback(
- const char* operation,
- net::Error net_error,
- net::NetLogCaptureMode capture_mode);
-
-// Returns NetLog parameters for a download interruption.
-std::unique_ptr<base::Value> FileInterruptedNetLogCallback(
- const char* operation,
- int os_error,
- DownloadInterruptReason reason,
- net::NetLogCaptureMode capture_mode);
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_NET_LOG_PARAMETERS_H_
diff --git a/chromium/content/browser/download/download_request_core.cc b/chromium/content/browser/download/download_request_core.cc
index 669ff10c1f7..afe70902405 100644
--- a/chromium/content/browser/download/download_request_core.cc
+++ b/chromium/content/browser/download/download_request_core.cc
@@ -31,6 +31,7 @@
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/download_manager_delegate.h"
+#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/web_contents.h"
@@ -56,7 +57,7 @@ class DownloadRequestData : public base::SupportsUserData::Data {
static void Attach(net::URLRequest* request,
DownloadUrlParameters* download_parameters,
uint32_t download_id);
- static DownloadRequestData* Get(net::URLRequest* request);
+ static DownloadRequestData* Get(const net::URLRequest* request);
static void Detach(net::URLRequest* request);
std::unique_ptr<DownloadSaveInfo> TakeSaveInfo() {
@@ -69,6 +70,7 @@ class DownloadRequestData : public base::SupportsUserData::Data {
const DownloadUrlParameters::OnStartedCallback& callback() const {
return on_started_callback_;
}
+ std::string request_origin() const { return request_origin_; }
private:
static const int kKey;
@@ -79,6 +81,7 @@ class DownloadRequestData : public base::SupportsUserData::Data {
bool fetch_error_body_ = false;
bool transient_ = false;
DownloadUrlParameters::OnStartedCallback on_started_callback_;
+ std::string request_origin_;
};
// static
@@ -88,7 +91,7 @@ const int DownloadRequestData::kKey = 0;
void DownloadRequestData::Attach(net::URLRequest* request,
DownloadUrlParameters* parameters,
uint32_t download_id) {
- auto request_data = base::MakeUnique<DownloadRequestData>();
+ auto request_data = std::make_unique<DownloadRequestData>();
request_data->save_info_.reset(
new DownloadSaveInfo(parameters->GetSaveInfo()));
request_data->download_id_ = download_id;
@@ -96,11 +99,12 @@ void DownloadRequestData::Attach(net::URLRequest* request,
request_data->fetch_error_body_ = parameters->fetch_error_body();
request_data->transient_ = parameters->is_transient();
request_data->on_started_callback_ = parameters->callback();
+ request_data->request_origin_ = parameters->request_origin();
request->SetUserData(&kKey, std::move(request_data));
}
// static
-DownloadRequestData* DownloadRequestData::Get(net::URLRequest* request) {
+DownloadRequestData* DownloadRequestData::Get(const net::URLRequest* request) {
return static_cast<DownloadRequestData*>(request->GetUserData(&kKey));
}
@@ -128,6 +132,15 @@ DownloadRequestCore::CreateRequestOnIOThread(uint32_t download_id,
return request;
}
+// static impl of DownloadRequestUtils
+std::string DownloadRequestUtils::GetRequestOriginFromRequest(
+ const net::URLRequest* request) {
+ DownloadRequestData* data = DownloadRequestData::Get(request);
+ if (data)
+ return data->request_origin();
+ return std::string(); // Empty string if data does not exist.
+}
+
DownloadRequestCore::DownloadRequestCore(net::URLRequest* request,
Delegate* delegate,
bool is_parallel_request)
@@ -157,8 +170,8 @@ DownloadRequestCore::DownloadRequestCore(net::URLRequest* request,
connector->BindInterface(device::mojom::kServiceName,
mojo::MakeRequest(&wake_lock_provider));
wake_lock_provider->GetWakeLockWithoutContext(
- device::mojom::WakeLockType::PreventAppSuspension,
- device::mojom::WakeLockReason::ReasonOther, "Download in progress",
+ device::mojom::WakeLockType::kPreventAppSuspension,
+ device::mojom::WakeLockReason::kOther, "Download in progress",
mojo::MakeRequest(&wake_lock_));
wake_lock_->RequestWakeLock();
@@ -190,8 +203,8 @@ std::unique_ptr<DownloadCreateInfo>
DownloadRequestCore::CreateDownloadCreateInfo(DownloadInterruptReason result) {
DCHECK(!started_);
started_ = true;
- std::unique_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo(
- base::Time::Now(), request()->net_log(), std::move(save_info_)));
+ std::unique_ptr<DownloadCreateInfo> create_info(
+ new DownloadCreateInfo(base::Time::Now(), std::move(save_info_)));
if (result == DOWNLOAD_INTERRUPT_REASON_NONE)
create_info->remote_address = request()->GetSocketAddress().host();
@@ -330,7 +343,7 @@ bool DownloadRequestCore::OnReadCompleted(int bytes_read, bool* defer) {
last_stream_pause_time_ = base::TimeTicks::Now();
}
- read_buffer_ = NULL; // Drop our reference.
+ read_buffer_ = nullptr; // Drop our reference.
if (pause_count_ > 0)
*defer = was_deferred_ = true;
diff --git a/chromium/content/browser/download/download_request_core_unittest.cc b/chromium/content/browser/download/download_request_core_unittest.cc
index d94c5b3fb01..d2adc595b03 100644
--- a/chromium/content/browser/download/download_request_core_unittest.cc
+++ b/chromium/content/browser/download/download_request_core_unittest.cc
@@ -29,7 +29,7 @@ class DownloadRequestCoreTest : public testing::Test {
std::unique_ptr<DownloadUrlParameters> BuildDownloadParameters(
const std::string& url) const {
GURL gurl(url);
- return base::MakeUnique<DownloadUrlParameters>(
+ return std::make_unique<DownloadUrlParameters>(
gurl, request_context_getter_.get(), TRAFFIC_ANNOTATION_FOR_TESTS);
}
diff --git a/chromium/content/browser/download/download_resource_handler.cc b/chromium/content/browser/download/download_resource_handler.cc
index d8a680d9565..8d037024424 100644
--- a/chromium/content/browser/download/download_resource_handler.cc
+++ b/chromium/content/browser/download/download_resource_handler.cc
@@ -81,7 +81,7 @@ static void StartOnUIThread(
download_manager->StartDownload(
std::move(info),
- base::MakeUnique<DownloadManager::InputStream>(std::move(stream)),
+ std::make_unique<DownloadManager::InputStream>(std::move(stream)),
started_cb);
}
diff --git a/chromium/content/browser/download/download_response_handler.cc b/chromium/content/browser/download/download_response_handler.cc
index ef01d617775..50c7f32e3a9 100644
--- a/chromium/content/browser/download/download_response_handler.cc
+++ b/chromium/content/browser/download/download_response_handler.cc
@@ -51,16 +51,19 @@ DownloadResponseHandler::DownloadResponseHandler(
std::unique_ptr<DownloadSaveInfo> save_info,
bool is_parallel_request,
bool is_transient,
- bool fetch_error_body)
+ bool fetch_error_body,
+ std::vector<GURL> url_chain)
: delegate_(delegate),
started_(false),
save_info_(std::move(save_info)),
- url_chain_(1, resource_request->url),
+ url_chain_(std::move(url_chain)),
method_(resource_request->method),
referrer_(resource_request->referrer),
is_transient_(is_transient),
fetch_error_body_(fetch_error_body),
- has_strong_validators_(false) {
+ has_strong_validators_(false),
+ is_partial_request_(save_info_->offset > 0),
+ abort_reason_(DOWNLOAD_INTERRUPT_REASON_NONE) {
if (!is_parallel_request)
RecordDownloadCount(UNTHROTTLED_COUNT);
if (resource_request->request_initiator.has_value())
@@ -108,7 +111,7 @@ DownloadResponseHandler::CreateDownloadCreateInfo(
// TODO(qinmin): instead of using NetLogWithSource, introduce new logging
// class for download.
auto create_info = base::MakeUnique<DownloadCreateInfo>(
- base::Time::Now(), net::NetLogWithSource(), std::move(save_info_));
+ base::Time::Now(), std::move(save_info_));
DownloadInterruptReason result =
head.headers
@@ -128,6 +131,7 @@ DownloadResponseHandler::CreateDownloadCreateInfo(
create_info->response_headers = head.headers;
create_info->offset = create_info->save_info->offset;
create_info->mime_type = head.mime_type;
+ create_info->fetch_error_body = fetch_error_body_;
HandleResponseHeaders(head.headers.get(), create_info.get());
return create_info;
@@ -135,7 +139,15 @@ DownloadResponseHandler::CreateDownloadCreateInfo(
void DownloadResponseHandler::OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
- const content::ResourceResponseHead& head) {
+ const ResourceResponseHead& head) {
+ if (is_partial_request_) {
+ // A redirect while attempting a partial resumption indicates a potential
+ // middle box. Trigger another interruption so that the DownloadItem can
+ // retry.
+ abort_reason_ = DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE;
+ OnComplete(network::URLLoaderCompletionStatus(net::OK));
+ return;
+ }
url_chain_.push_back(redirect_info.new_url);
method_ = redirect_info.new_method;
referrer_ = GURL(redirect_info.new_referrer);
@@ -169,10 +181,10 @@ void DownloadResponseHandler::OnStartLoadingResponseBody(
}
void DownloadResponseHandler::OnComplete(
- const content::ResourceRequestCompletionStatus& completion_status) {
+ const network::URLLoaderCompletionStatus& status) {
DownloadInterruptReason reason = HandleRequestCompletionStatus(
- static_cast<net::Error>(completion_status.error_code),
- has_strong_validators_, cert_status_, DOWNLOAD_INTERRUPT_REASON_NONE);
+ static_cast<net::Error>(status.error_code), has_strong_validators_,
+ cert_status_, abort_reason_);
if (client_ptr_) {
client_ptr_->OnStreamCompleted(
@@ -186,6 +198,7 @@ void DownloadResponseHandler::OnComplete(
// happen when the request was aborted.
create_info_ = CreateDownloadCreateInfo(ResourceResponseHead());
create_info_->result = reason;
+
OnResponseStarted(mojom::DownloadStreamHandlePtr());
}
diff --git a/chromium/content/browser/download/download_response_handler.h b/chromium/content/browser/download/download_response_handler.h
index 51151106e02..db1fda3d0b2 100644
--- a/chromium/content/browser/download/download_response_handler.h
+++ b/chromium/content/browser/download/download_response_handler.h
@@ -39,7 +39,8 @@ class DownloadResponseHandler : public mojom::URLLoaderClient {
std::unique_ptr<DownloadSaveInfo> save_info,
bool is_parallel_request,
bool is_transient,
- bool fetch_error_body);
+ bool fetch_error_body,
+ std::vector<GURL> url_chain);
~DownloadResponseHandler() override;
// mojom::URLLoaderClient
@@ -47,7 +48,7 @@ class DownloadResponseHandler : public mojom::URLLoaderClient {
const base::Optional<net::SSLInfo>& ssl_info,
mojom::DownloadedTempFilePtr downloaded_file) override;
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
- const content::ResourceResponseHead& head) override;
+ const ResourceResponseHead& head) override;
void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override;
void OnUploadProgress(int64_t current_position,
int64_t total_size,
@@ -56,8 +57,7 @@ class DownloadResponseHandler : public mojom::URLLoaderClient {
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- void OnComplete(const content::ResourceRequestCompletionStatus&
- completion_status) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
private:
std::unique_ptr<DownloadCreateInfo> CreateDownloadCreateInfo(
@@ -82,6 +82,10 @@ class DownloadResponseHandler : public mojom::URLLoaderClient {
net::CertStatus cert_status_;
bool has_strong_validators_;
GURL origin_;
+ bool is_partial_request_;
+
+ // The abort reason if this class decides to block the download.
+ DownloadInterruptReason abort_reason_;
// Mojo interface ptr to send the completion status to the download sink.
mojom::DownloadStreamClientPtr client_ptr_;
diff --git a/chromium/content/browser/download/download_stats.cc b/chromium/content/browser/download/download_stats.cc
index efc2c4321e0..24d6481d2da 100644
--- a/chromium/content/browser/download/download_stats.cc
+++ b/chromium/content/browser/download/download_stats.cc
@@ -208,7 +208,33 @@ constexpr const base::FilePath::CharType* kDangerousFileTypes[] = {
FILE_PATH_LITERAL(".imgpart"), FILE_PATH_LITERAL(".ndif"),
FILE_PATH_LITERAL(".smi"), FILE_PATH_LITERAL(".sparsebundle"),
FILE_PATH_LITERAL(".sparseimage"), FILE_PATH_LITERAL(".toast"),
- FILE_PATH_LITERAL(".udif"),
+ FILE_PATH_LITERAL(".udif"), FILE_PATH_LITERAL(".run"), // 262
+ FILE_PATH_LITERAL(".mpkg"), FILE_PATH_LITERAL(".as"), // 264
+ FILE_PATH_LITERAL(".cpgz"), FILE_PATH_LITERAL(".pax"), // 266
+ FILE_PATH_LITERAL(".xip"), FILE_PATH_LITERAL(".docx"), // 268
+ FILE_PATH_LITERAL(".docm"), FILE_PATH_LITERAL(".dott"), // 270
+ FILE_PATH_LITERAL(".dotm"), FILE_PATH_LITERAL(".docb"), // 272
+ FILE_PATH_LITERAL(".xlsx"), FILE_PATH_LITERAL(".xlsm"), // 274
+ FILE_PATH_LITERAL(".xltx"), FILE_PATH_LITERAL(".xltm"), // 276
+ FILE_PATH_LITERAL(".pptx"), FILE_PATH_LITERAL(".pptm"), // 278
+ FILE_PATH_LITERAL(".potx"), FILE_PATH_LITERAL(".ppam"), // 280
+ FILE_PATH_LITERAL(".ppsx"), FILE_PATH_LITERAL(".sldx"), // 282
+ FILE_PATH_LITERAL(".sldm"), FILE_PATH_LITERAL(".htm"), // 284
+ FILE_PATH_LITERAL(".html"), FILE_PATH_LITERAL(".xht"), // 286
+ FILE_PATH_LITERAL(".xhtm"), FILE_PATH_LITERAL(".xhtml"), // 288
+ FILE_PATH_LITERAL(".vdx"), FILE_PATH_LITERAL(".vsx"), // 290
+ FILE_PATH_LITERAL(".vtx"), FILE_PATH_LITERAL(".vsdx"), // 292
+ FILE_PATH_LITERAL(".vssx"), FILE_PATH_LITERAL(".vstx"), // 294
+ FILE_PATH_LITERAL(".vsdm"), FILE_PATH_LITERAL(".vssm"), // 296
+ FILE_PATH_LITERAL(".vstm"), FILE_PATH_LITERAL(".btapp"), // 298
+ FILE_PATH_LITERAL(".btbtskin"), FILE_PATH_LITERAL(".btinstall"), // 300
+ FILE_PATH_LITERAL(".btkey"), FILE_PATH_LITERAL(".btsearch"), // 302
+ FILE_PATH_LITERAL(".dhtml"), FILE_PATH_LITERAL(".dhtm"), // 304
+ FILE_PATH_LITERAL(".dht"), FILE_PATH_LITERAL(".shtml"), // 306
+ FILE_PATH_LITERAL(".shtm"), FILE_PATH_LITERAL(".sht"), // 308
+ // NOTE! When you add a type here, please add the UMA value as a comment.
+ // These must all match DownloadItem.DangerousFileType in enums.xml.
+ // From 263 onward, they should also match SBClientDownloadExtensions.
};
// The maximum size in KB for the file size metric, file size larger than this
@@ -247,13 +273,14 @@ void RecordDownloadCount(DownloadCountTypes type) {
"Download.Counts", type, DOWNLOAD_COUNT_TYPES_LAST_ENTRY);
}
-void RecordDownloadSource(DownloadSource source) {
+void RecordDownloadSource(DownloadTriggerSource source) {
UMA_HISTOGRAM_ENUMERATION(
"Download.Sources", source, DOWNLOAD_SOURCE_LAST_ENTRY);
}
void RecordDownloadCompleted(const base::TimeTicks& start,
- int64_t download_len) {
+ int64_t download_len,
+ bool is_parallelizable) {
RecordDownloadCount(COMPLETED_COUNT);
UMA_HISTOGRAM_LONG_TIMES("Download.Time", (base::TimeTicks::Now() - start));
int64_t max = 1024 * 1024 * 1024; // One Terabyte.
@@ -263,6 +290,10 @@ void RecordDownloadCompleted(const base::TimeTicks& start,
1,
max,
256);
+ if (is_parallelizable) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Download.DownloadSize.Parallelizable",
+ download_len, 1, max, 256);
+ }
}
void RecordDownloadInterrupted(DownloadInterruptReason reason,
diff --git a/chromium/content/browser/download/download_stats.h b/chromium/content/browser/download/download_stats.h
index 62ee585d07c..ca82af1c38d 100644
--- a/chromium/content/browser/download/download_stats.h
+++ b/chromium/content/browser/download/download_stats.h
@@ -123,7 +123,8 @@ enum DownloadCountTypes {
DOWNLOAD_COUNT_TYPES_LAST_ENTRY
};
-enum DownloadSource {
+// TODO(xingliu): Deprecate this enum.
+enum DownloadTriggerSource {
// The download was initiated when the SavePackage system rejected
// a Save Page As ... by returning false from
// SavePackage::IsSaveableContents().
@@ -205,11 +206,12 @@ enum class ParallelDownloadCreationEvent {
void RecordDownloadCount(DownloadCountTypes type);
// Record initiation of a download from a specific source.
-void RecordDownloadSource(DownloadSource source);
+void RecordDownloadSource(DownloadTriggerSource source);
// Record COMPLETED_COUNT and how long the download took.
void RecordDownloadCompleted(const base::TimeTicks& start,
- int64_t download_len);
+ int64_t download_len,
+ bool is_parallelizable);
// Record INTERRUPTED_COUNT, |reason|, |received| and |total| bytes.
void RecordDownloadInterrupted(DownloadInterruptReason reason,
diff --git a/chromium/content/browser/download/download_utils.cc b/chromium/content/browser/download/download_utils.cc
index 07c9a0c9863..5f198aa0e4f 100644
--- a/chromium/content/browser/download/download_utils.cc
+++ b/chromium/content/browser/download/download_utils.cc
@@ -53,7 +53,7 @@ int GetLoadFlags(DownloadUrlParameters* params, bool has_upload_data) {
std::unique_ptr<net::HttpRequestHeaders> GetAdditionalRequestHeaders(
DownloadUrlParameters* params) {
- auto headers = base::MakeUnique<net::HttpRequestHeaders>();
+ auto headers = std::make_unique<net::HttpRequestHeaders>();
if (params->offset() == 0 &&
params->length() == DownloadSaveInfo::kLengthFullContent) {
AppendExtraHeaders(headers.get(), params);
@@ -172,16 +172,10 @@ std::unique_ptr<ResourceRequest> CreateResourceRequest(
request->referrer_policy = params->referrer().policy;
request->download_to_file = true;
request->allow_download = true;
+ request->is_main_frame = true;
- if (params->render_process_host_id()) {
- request->origin_pid = params->render_process_host_id();
- RenderFrameHost* render_frame_host =
- RenderFrameHost::FromID(params->render_process_host_id(),
- params->render_frame_host_routing_id());
- request->is_main_frame = !render_frame_host->GetParent();
-
+ if (params->render_process_host_id() >= 0)
request->render_frame_id = params->render_frame_host_routing_id();
- }
bool has_upload_data = false;
if (!params->post_body().empty()) {
@@ -243,7 +237,7 @@ CreateURLRequestOnIOThread(DownloadUrlParameters* params) {
DCHECK(params->prefer_cache());
DCHECK_EQ("POST", params->method());
std::vector<std::unique_ptr<net::UploadElementReader>> element_readers;
- request->set_upload(base::MakeUnique<net::ElementsUploadDataStream>(
+ request->set_upload(std::make_unique<net::ElementsUploadDataStream>(
std::move(element_readers), params->post_id()));
}
@@ -411,4 +405,40 @@ void HandleResponseHeaders(const net::HttpResponseHeaders* headers,
headers->response_code() == net::HTTP_PARTIAL_CONTENT);
}
+download::DownloadSource ToDownloadSource(
+ content::DownloadSource download_source) {
+ switch (download_source) {
+ case DownloadSource::UNKNOWN:
+ return download::DownloadSource::UNKNOWN;
+ case DownloadSource::NAVIGATION:
+ return download::DownloadSource::NAVIGATION;
+ case DownloadSource::DRAG_AND_DROP:
+ return download::DownloadSource::DRAG_AND_DROP;
+ case DownloadSource::MANUAL_RESUMPTION:
+ return download::DownloadSource::MANUAL_RESUMPTION;
+ case DownloadSource::AUTO_RESUMPTION:
+ return download::DownloadSource::AUTO_RESUMPTION;
+ case DownloadSource::FROM_RENDERER:
+ return download::DownloadSource::FROM_RENDERER;
+ case DownloadSource::EXTENSION_API:
+ return download::DownloadSource::EXTENSION_API;
+ case DownloadSource::EXTENSION_INSTALLER:
+ return download::DownloadSource::EXTENSION_INSTALLER;
+ case DownloadSource::PLUGIN:
+ return download::DownloadSource::PLUGIN;
+ case DownloadSource::PLUGIN_INSTALLER:
+ return download::DownloadSource::PLUGIN_INSTALLER;
+ case DownloadSource::INTERNAL_API:
+ return download::DownloadSource::INTERNAL_API;
+ case DownloadSource::SAVE_PACKAGE:
+ return download::DownloadSource::SAVE_PACKAGE;
+ case DownloadSource::OFFLINE_PAGE:
+ return download::DownloadSource::OFFLINE_PAGE;
+ case DownloadSource::COUNT:
+ break;
+ }
+ NOTREACHED();
+ return download::DownloadSource::UNKNOWN;
+}
+
} // namespace content
diff --git a/chromium/content/browser/download/download_utils.h b/chromium/content/browser/download/download_utils.h
index b1cafe2ace1..dd7856c0577 100644
--- a/chromium/content/browser/download/download_utils.h
+++ b/chromium/content/browser/download/download_utils.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_UTILS_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_UTILS_H_
+#include "components/download/downloader/in_progress/download_source.h"
#include "content/public/browser/download_interrupt_reasons.h"
+#include "content/public/browser/download_source.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_status_flags.h"
#include "net/http/http_response_headers.h"
@@ -48,6 +50,10 @@ CONTENT_EXPORT void HandleResponseHeaders(
const net::HttpResponseHeaders* headers,
DownloadCreateInfo* create_info);
+// Converts content::DownloadSource to download::DownloadSource.
+CONTENT_EXPORT download::DownloadSource ToDownloadSource(
+ content::DownloadSource download_source);
+
} // namespace content
#endif // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_UTILS_H_
diff --git a/chromium/content/browser/download/download_worker.cc b/chromium/content/browser/download/download_worker.cc
index 24f770c1373..e8403e1a3bf 100644
--- a/chromium/content/browser/download/download_worker.cc
+++ b/chromium/content/browser/download/download_worker.cc
@@ -11,7 +11,7 @@
namespace content {
namespace {
-const int kVerboseLevel = 1;
+const int kWorkerVerboseLevel = 1;
class CompletedByteStreamReader : public ByteStreamReader {
public:
@@ -104,7 +104,8 @@ void DownloadWorker::OnUrlDownloadStarted(
// Destroy the request if user canceled.
if (is_canceled_) {
- VLOG(kVerboseLevel) << "Byte stream arrived after user cancel the request.";
+ VLOG(kWorkerVerboseLevel)
+ << "Byte stream arrived after user cancel the request.";
create_info->request_handle->CancelRequest(is_user_cancel_);
return;
}
@@ -112,8 +113,9 @@ void DownloadWorker::OnUrlDownloadStarted(
// TODO(xingliu): Add metric for error handling.
if (create_info->result !=
DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE) {
- VLOG(kVerboseLevel) << "Parallel download sub-request failed. reason = "
- << create_info->result;
+ VLOG(kWorkerVerboseLevel)
+ << "Parallel download sub-request failed. reason = "
+ << create_info->result;
input_stream->stream_reader_.reset(
new CompletedByteStreamReader(create_info->result));
}
@@ -122,7 +124,8 @@ void DownloadWorker::OnUrlDownloadStarted(
// Pause the stream if user paused, still push the stream reader to the sink.
if (is_paused_) {
- VLOG(kVerboseLevel) << "Byte stream arrived after user pause the request.";
+ VLOG(kWorkerVerboseLevel)
+ << "Byte stream arrived after user pause the request.";
Pause();
}
diff --git a/chromium/content/browser/download/drag_download_file.cc b/chromium/content/browser/download/drag_download_file.cc
index da0ab7b1392..da99ae77e96 100644
--- a/chromium/content/browser/download/drag_download_file.cc
+++ b/chromium/content/browser/download/drag_download_file.cc
@@ -52,7 +52,7 @@ class DragDownloadFile::DragDownloadFileUI : public DownloadItem::Observer {
referrer_(referrer),
referrer_encoding_(referrer_encoding),
web_contents_(web_contents),
- download_item_(NULL),
+ download_item_(nullptr),
weak_ptr_factory_(this) {
DCHECK(on_completed_task_runner_);
DCHECK(!on_completed_.is_null());
@@ -151,7 +151,7 @@ class DragDownloadFile::DragDownloadFileUI : public DownloadItem::Observer {
on_completed_.Reset();
}
download_item_->RemoveObserver(this);
- download_item_ = NULL;
+ download_item_ = nullptr;
}
// Ignore other states.
}
@@ -167,7 +167,7 @@ class DragDownloadFile::DragDownloadFileUI : public DownloadItem::Observer {
on_completed_.Reset();
}
download_item_->RemoveObserver(this);
- download_item_ = NULL;
+ download_item_ = nullptr;
}
scoped_refptr<base::SingleThreadTaskRunner> const on_completed_task_runner_;
@@ -194,7 +194,7 @@ DragDownloadFile::DragDownloadFile(const base::FilePath& file_path,
file_(std::move(file)),
drag_task_runner_(base::ThreadTaskRunnerHandle::Get()),
state_(INITIALIZED),
- drag_ui_(NULL),
+ drag_ui_(nullptr),
weak_ptr_factory_(this) {
drag_ui_ = new DragDownloadFileUI(
url, referrer, referrer_encoding, web_contents, drag_task_runner_,
@@ -213,7 +213,7 @@ DragDownloadFile::~DragDownloadFile() {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&DragDownloadFileUI::Delete, base::Unretained(drag_ui_)));
- drag_ui_ = NULL;
+ drag_ui_ = nullptr;
}
void DragDownloadFile::Start(ui::DownloadFileObserver* observer) {
@@ -260,7 +260,7 @@ void DragDownloadFile::DownloadCompleted(bool is_successful) {
observer_->OnDownloadAborted();
// Release the observer since we do not need it any more.
- observer_ = NULL;
+ observer_ = nullptr;
if (nested_loop_.running())
nested_loop_.Quit();
diff --git a/chromium/content/browser/download/drag_download_file_browsertest.cc b/chromium/content/browser/download/drag_download_file_browsertest.cc
index a023cdf41a1..8fb11555640 100644
--- a/chromium/content/browser/download/drag_download_file_browsertest.cc
+++ b/chromium/content/browser/download/drag_download_file_browsertest.cc
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
#include "content/browser/download/download_file_factory.h"
#include "content/browser/download/download_file_impl.h"
#include "content/browser/download/download_item_impl.h"
@@ -16,6 +17,7 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/content_paths.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
@@ -69,13 +71,10 @@ class DragDownloadFileTest : public ContentBrowserTest {
shell()->web_contents()->GetBrowserContext()
->GetDownloadManagerDelegate());
delegate->SetDownloadBehaviorForTesting(downloads_directory());
- }
-
- void SetUpServer() {
- base::FilePath mock_base(GetTestFilePath("download", ""));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&net::URLRequestMockHTTPJob::AddUrlHandlers, mock_base));
+ base::FilePath test_data_dir;
+ ASSERT_TRUE(PathService::Get(content::DIR_TEST_DATA, &test_data_dir));
+ embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
+ ASSERT_TRUE(embedded_test_server()->Start());
}
const base::FilePath& downloads_directory() const {
@@ -91,7 +90,8 @@ class DragDownloadFileTest : public ContentBrowserTest {
IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_NetError) {
base::FilePath name(downloads_directory().AppendASCII(
"DragDownloadFileTest_NetError.txt"));
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
+ GURL url = embedded_test_server()->GetURL("/download/download-test.lib");
+ ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
Referrer referrer;
std::string referrer_encoding;
scoped_refptr<DragDownloadFile> file(
@@ -110,10 +110,9 @@ IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_NetError) {
IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_Complete) {
base::FilePath name(downloads_directory().AppendASCII(
"DragDownloadFileTest_Complete.txt"));
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
+ GURL url = embedded_test_server()->GetURL("/download/download-test.lib");
Referrer referrer;
std::string referrer_encoding;
- SetUpServer();
scoped_refptr<DragDownloadFile> file(new DragDownloadFile(
name, base::File(), url, referrer,
referrer_encoding, shell()->web_contents()));
diff --git a/chromium/content/browser/download/drag_download_util.cc b/chromium/content/browser/download/drag_download_util.cc
index 5e376100382..0996ac70e2c 100644
--- a/chromium/content/browser/download/drag_download_util.cc
+++ b/chromium/content/browser/download/drag_download_util.cc
@@ -109,7 +109,7 @@ PromiseFileFinalizer::~PromiseFileFinalizer() {}
void PromiseFileFinalizer::Cleanup() {
if (drag_file_downloader_.get())
- drag_file_downloader_ = NULL;
+ drag_file_downloader_ = nullptr;
}
} // namespace content
diff --git a/chromium/content/browser/download/mhtml_extra_parts_impl.cc b/chromium/content/browser/download/mhtml_extra_parts_impl.cc
index c9614772009..da76fdb27d2 100644
--- a/chromium/content/browser/download/mhtml_extra_parts_impl.cc
+++ b/chromium/content/browser/download/mhtml_extra_parts_impl.cc
@@ -12,11 +12,14 @@ const int kMHTMLExtraPartsKey = 0;
namespace content {
MHTMLExtraDataPart::MHTMLExtraDataPart() = default;
-
-MHTMLExtraDataPart::~MHTMLExtraDataPart() = default;
-
MHTMLExtraDataPart::MHTMLExtraDataPart(const MHTMLExtraDataPart& other) =
default;
+MHTMLExtraDataPart::MHTMLExtraDataPart(MHTMLExtraDataPart&& other) = default;
+MHTMLExtraDataPart& MHTMLExtraDataPart::operator=(
+ const MHTMLExtraDataPart& other) = default;
+MHTMLExtraDataPart& MHTMLExtraDataPart::operator=(MHTMLExtraDataPart&& other) =
+ default;
+MHTMLExtraDataPart::~MHTMLExtraDataPart() = default;
MHTMLExtraPartsImpl::MHTMLExtraPartsImpl() = default;
@@ -54,7 +57,7 @@ void MHTMLExtraPartsImpl::AddExtraMHTMLPart(const std::string& content_type,
// Add this part to the list of parts to be saved out when the file is
// written.
- parts_.push_back(part);
+ parts_.emplace_back(std::move(part));
}
} // namespace content
diff --git a/chromium/content/browser/download/mhtml_extra_parts_impl.h b/chromium/content/browser/download/mhtml_extra_parts_impl.h
index ef890ddfad8..abef47219ea 100644
--- a/chromium/content/browser/download/mhtml_extra_parts_impl.h
+++ b/chromium/content/browser/download/mhtml_extra_parts_impl.h
@@ -17,8 +17,11 @@ struct MHTMLExtraDataPart {
std::string body;
MHTMLExtraDataPart();
- ~MHTMLExtraDataPart();
MHTMLExtraDataPart(const MHTMLExtraDataPart& other);
+ MHTMLExtraDataPart(MHTMLExtraDataPart&& other);
+ MHTMLExtraDataPart& operator=(const MHTMLExtraDataPart& other);
+ MHTMLExtraDataPart& operator=(MHTMLExtraDataPart&& other);
+ ~MHTMLExtraDataPart();
};
// Class used as a data object for WebContents UserData to represent an MHTML
diff --git a/chromium/content/browser/download/mhtml_generation_manager.cc b/chromium/content/browser/download/mhtml_generation_manager.cc
index 2475cecd84c..f3751309faa 100644
--- a/chromium/content/browser/download/mhtml_generation_manager.cc
+++ b/chromium/content/browser/download/mhtml_generation_manager.cc
@@ -112,15 +112,16 @@ class MHTMLGenerationManager::Job : public RenderProcessHostObserver {
MhtmlSaveStatus save_status,
const std::string& boundary,
base::File file,
- const MHTMLExtraPartsImpl* extra_parts);
+ const std::vector<MHTMLExtraDataPart>& extra_data_parts);
void AddFrame(RenderFrameHost* render_frame_host);
// If we have any extra MHTML parts to write out, write them into the file
// while on the file thread. Returns true for success, or if there is no data
// to write.
- static bool WriteExtraDataParts(const std::string& boundary,
- base::File& file,
- const MHTMLExtraPartsImpl* extra_parts);
+ static bool WriteExtraDataParts(
+ const std::string& boundary,
+ base::File& file,
+ const std::vector<MHTMLExtraDataPart>& extra_data_parts);
// Writes the footer into the MHTML file. Returns false for faiulre.
static bool WriteFooter(const std::string& boundary, base::File& file);
@@ -182,7 +183,7 @@ class MHTMLGenerationManager::Job : public RenderProcessHostObserver {
bool is_finished_;
// Any extra data parts that should be emitted into the output MHTML.
- MHTMLExtraPartsImpl* extra_parts_;
+ std::vector<MHTMLExtraDataPart> extra_data_parts_;
// RAII helper for registering this Job as a RenderProcessHost observer.
ScopedObserver<RenderProcessHost, MHTMLGenerationManager::Job>
@@ -215,8 +216,10 @@ MHTMLGenerationManager::Job::Job(int job_id,
->parent() == nullptr);
// Save off any extra data.
- extra_parts_ = static_cast<MHTMLExtraPartsImpl*>(
+ auto* extra_parts = static_cast<MHTMLExtraPartsImpl*>(
MHTMLExtraParts::FromWebContents(web_contents));
+ if (extra_parts)
+ extra_data_parts_ = extra_parts->parts();
}
MHTMLGenerationManager::Job::~Job() {
@@ -389,7 +392,7 @@ void MHTMLGenerationManager::Job::CloseFile(
save_status,
(save_status == MhtmlSaveStatus::SUCCESS ? mhtml_boundary_marker_
: std::string()),
- base::Passed(&browser_file_), extra_parts_),
+ base::Passed(&browser_file_), base::Passed(&extra_data_parts_)),
callback);
}
@@ -439,7 +442,7 @@ MHTMLGenerationManager::Job::FinalizeAndCloseFileOnFileThread(
MhtmlSaveStatus save_status,
const std::string& boundary,
base::File file,
- const MHTMLExtraPartsImpl* extra_parts) {
+ const std::vector<MHTMLExtraDataPart>& extra_data_parts) {
DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
// If no previous error occurred the boundary should have been provided.
@@ -449,7 +452,7 @@ MHTMLGenerationManager::Job::FinalizeAndCloseFileOnFileThread(
DCHECK(!boundary.empty());
// Write the extra data into a part of its own, if we have any.
- if (!WriteExtraDataParts(boundary, file, extra_parts)) {
+ if (!WriteExtraDataParts(boundary, file, extra_data_parts)) {
save_status = MhtmlSaveStatus::FILE_WRITTING_ERROR;
}
@@ -475,13 +478,9 @@ MHTMLGenerationManager::Job::FinalizeAndCloseFileOnFileThread(
bool MHTMLGenerationManager::Job::WriteExtraDataParts(
const std::string& boundary,
base::File& file,
- const MHTMLExtraPartsImpl* extra_parts) {
+ const std::vector<MHTMLExtraDataPart>& extra_data_parts) {
DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
// Don't write an extra data part if there is none.
- if (extra_parts == nullptr)
- return true;
-
- const std::vector<MHTMLExtraDataPart>& extra_data_parts(extra_parts->parts());
if (extra_data_parts.empty())
return true;
@@ -489,7 +488,7 @@ bool MHTMLGenerationManager::Job::WriteExtraDataParts(
// For each extra part, serialize that part and add to our accumulator
// string.
- for (auto part : extra_data_parts) {
+ for (const auto& part : extra_data_parts) {
// Write a newline, then a boundary, a newline, then the content
// location, a newline, the content type, a newline, extra_headers,
// two newlines, the body, and end with a newline.
diff --git a/chromium/content/browser/download/mock_download_file.h b/chromium/content/browser/download/mock_download_file.h
index 176047f7f63..76f6a60c7a9 100644
--- a/chromium/content/browser/download/mock_download_file.h
+++ b/chromium/content/browser/download/mock_download_file.h
@@ -62,7 +62,6 @@ class MockDownloadFile : public DownloadFile {
MOCK_METHOD0(Finish, void());
MOCK_CONST_METHOD0(FullPath, const base::FilePath&());
MOCK_CONST_METHOD0(InProgress, bool());
- MOCK_METHOD0(WasPaused, void());
MOCK_CONST_METHOD0(BytesSoFar, int64_t());
MOCK_CONST_METHOD0(CurrentSpeed, int64_t());
MOCK_METHOD1(GetHash, bool(std::string* hash));
@@ -70,6 +69,8 @@ class MockDownloadFile : public DownloadFile {
MOCK_CONST_METHOD0(Id, int());
MOCK_METHOD0(GetDownloadManager, DownloadManager*());
MOCK_CONST_METHOD0(DebugString, std::string());
+ MOCK_METHOD0(Pause, void());
+ MOCK_METHOD0(Resume, void());
};
} // namespace content
diff --git a/chromium/content/browser/download/mock_download_item_impl.cc b/chromium/content/browser/download/mock_download_item_impl.cc
index 37a92c9ee55..ab1eb1f3732 100644
--- a/chromium/content/browser/download/mock_download_item_impl.cc
+++ b/chromium/content/browser/download/mock_download_item_impl.cc
@@ -32,8 +32,7 @@ MockDownloadItemImpl::MockDownloadItemImpl(DownloadItemImplDelegate* delegate)
false,
base::Time(),
true,
- DownloadItem::ReceivedSlices(),
- net::NetLogWithSource()) {}
+ DownloadItem::ReceivedSlices()) {}
MockDownloadItemImpl::~MockDownloadItemImpl() = default;
diff --git a/chromium/content/browser/download/parallel_download_job.cc b/chromium/content/browser/download/parallel_download_job.cc
index c67d5301bdc..ae292af719d 100644
--- a/chromium/content/browser/download/parallel_download_job.cc
+++ b/chromium/content/browser/download/parallel_download_job.cc
@@ -19,7 +19,7 @@
namespace content {
namespace {
-const int kVerboseLevel = 1;
+const int kDownloadJobVerboseLevel = 1;
} // namespace
@@ -121,13 +121,13 @@ void ParallelDownloadJob::OnByteStreamReady(
DownloadWorker* worker,
std::unique_ptr<ByteStreamReader> stream_reader) {
bool success = DownloadJob::AddInputStream(
- base::MakeUnique<DownloadManager::InputStream>(std::move(stream_reader)),
+ std::make_unique<DownloadManager::InputStream>(std::move(stream_reader)),
worker->offset(), worker->length());
RecordParallelDownloadAddStreamSuccess(success);
// Destroy the request if the sink is gone.
if (!success) {
- VLOG(kVerboseLevel)
+ VLOG(kDownloadJobVerboseLevel)
<< "Byte stream arrived after download file is released.";
worker->Cancel(false);
}
@@ -158,7 +158,7 @@ void ParallelDownloadJob::BuildParallelRequests() {
// previous session only has one stream writing to disk. In these cases, fall
// back to non parallel download.
if (initial_request_offset_ > first_slice_offset) {
- VLOG(kVerboseLevel)
+ VLOG(kDownloadJobVerboseLevel)
<< "Received slices data mismatch initial request offset.";
return;
}
@@ -234,7 +234,7 @@ void ParallelDownloadJob::CreateRequest(int64_t offset, int64_t length) {
DCHECK(download_item_);
std::unique_ptr<DownloadWorker> worker =
- base::MakeUnique<DownloadWorker>(this, offset, length);
+ std::make_unique<DownloadWorker>(this, offset, length);
StoragePartition* storage_partition =
BrowserContext::GetStoragePartitionForSite(
diff --git a/chromium/content/browser/download/parallel_download_job_unittest.cc b/chromium/content/browser/download/parallel_download_job_unittest.cc
index 36fc08661a0..1ce7294bf2e 100644
--- a/chromium/content/browser/download/parallel_download_job_unittest.cc
+++ b/chromium/content/browser/download/parallel_download_job_unittest.cc
@@ -86,7 +86,7 @@ class ParallelDownloadJobForTest : public ParallelDownloadJob {
void CreateRequest(int64_t offset, int64_t length) override {
std::unique_ptr<DownloadWorker> worker =
- base::MakeUnique<DownloadWorker>(this, offset, length);
+ std::make_unique<DownloadWorker>(this, offset, length);
DCHECK(workers_.find(offset) == workers_.end());
workers_[offset] = std::move(worker);
@@ -133,10 +133,10 @@ class ParallelDownloadJobTest : public testing::Test {
int request_count,
int64_t min_slice_size,
int min_remaining_time) {
- item_delegate_ = base::MakeUnique<DownloadItemImplDelegate>();
+ item_delegate_ = std::make_unique<DownloadItemImplDelegate>();
received_slices_ = slices;
download_item_ =
- base::MakeUnique<NiceMock<MockDownloadItemImpl>>(item_delegate_.get());
+ std::make_unique<NiceMock<MockDownloadItemImpl>>(item_delegate_.get());
EXPECT_CALL(*download_item_, GetTotalBytes())
.WillRepeatedly(Return(initial_request_offset + content_length));
EXPECT_CALL(*download_item_, GetReceivedBytes())
@@ -148,9 +148,9 @@ class ParallelDownloadJobTest : public testing::Test {
info.offset = initial_request_offset;
info.total_bytes = content_length;
std::unique_ptr<MockDownloadRequestHandle> request_handle =
- base::MakeUnique<MockDownloadRequestHandle>();
+ std::make_unique<MockDownloadRequestHandle>();
mock_request_handle_ = request_handle.get();
- job_ = base::MakeUnique<ParallelDownloadJobForTest>(
+ job_ = std::make_unique<ParallelDownloadJobForTest>(
download_item_.get(), std::move(request_handle), info, request_count,
min_slice_size, min_remaining_time);
file_initialized_ = false;
@@ -177,12 +177,12 @@ class ParallelDownloadJobTest : public testing::Test {
UrlDownloadHandler::Delegate* delegate =
static_cast<UrlDownloadHandler::Delegate*>(worker);
std::unique_ptr<DownloadCreateInfo> create_info =
- base::MakeUnique<DownloadCreateInfo>();
+ std::make_unique<DownloadCreateInfo>();
create_info->request_handle = std::move(request_handle);
delegate->OnUrlDownloadStarted(
std::move(create_info),
- base::MakeUnique<DownloadManager::InputStream>(
- base::MakeUnique<MockByteStreamReader>()),
+ std::make_unique<DownloadManager::InputStream>(
+ std::make_unique<MockByteStreamReader>()),
DownloadUrlParameters::OnStartedCallback());
}
@@ -395,7 +395,7 @@ TEST_F(ParallelDownloadJobTest, EarlyCancelBeforeByteStreamReady) {
for (auto& worker : job_->workers()) {
std::unique_ptr<MockDownloadRequestHandle> mock_handle =
- base::MakeUnique<MockDownloadRequestHandle>();
+ std::make_unique<MockDownloadRequestHandle>();
EXPECT_CALL(*mock_handle.get(), CancelRequest(_));
MakeWorkerReady(worker.second.get(), std::move(mock_handle));
}
@@ -420,7 +420,7 @@ TEST_F(ParallelDownloadJobTest, EarlyPauseBeforeByteStreamReady) {
for (auto& worker : job_->workers()) {
EXPECT_CALL(*job_.get(), CountOnByteStreamReady());
std::unique_ptr<MockDownloadRequestHandle> mock_handle =
- base::MakeUnique<MockDownloadRequestHandle>();
+ std::make_unique<MockDownloadRequestHandle>();
EXPECT_CALL(*mock_handle.get(), PauseRequest());
MakeWorkerReady(worker.second.get(), std::move(mock_handle));
}
@@ -441,18 +441,18 @@ TEST_F(ParallelDownloadJobTest, RemainingContentWillFinishSoon) {
// Test that parallel request is not created until download file is initialized.
TEST_F(ParallelDownloadJobTest, ParallelRequestNotCreatedUntilFileInitialized) {
- auto save_info = base::MakeUnique<DownloadSaveInfo>();
+ auto save_info = std::make_unique<DownloadSaveInfo>();
StrictMock<MockByteStreamReader>* input_stream =
new StrictMock<MockByteStreamReader>();
auto observer =
- base::MakeUnique<StrictMock<MockDownloadDestinationObserver>>();
+ std::make_unique<StrictMock<MockDownloadDestinationObserver>>();
base::WeakPtrFactory<DownloadDestinationObserver> observer_factory(
observer.get());
- auto download_file = base::MakeUnique<DownloadFileImpl>(
+ auto download_file = std::make_unique<DownloadFileImpl>(
std::move(save_info), base::FilePath(),
- base::MakeUnique<DownloadManager::InputStream>(
+ std::make_unique<DownloadManager::InputStream>(
std::unique_ptr<ByteStreamReader>(input_stream)),
- net::NetLogWithSource(), observer_factory.GetWeakPtr());
+ DownloadItem::kInvalidId, observer_factory.GetWeakPtr());
CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 0, 0);
job_->Start(download_file.get(),
base::Bind(&ParallelDownloadJobTest::OnFileInitialized,
diff --git a/chromium/content/browser/download/resource_downloader.cc b/chromium/content/browser/download/resource_downloader.cc
index a4be18d4125..a7e5501f94c 100644
--- a/chromium/content/browser/download/resource_downloader.cc
+++ b/chromium/content/browser/download/resource_downloader.cc
@@ -13,32 +13,66 @@
namespace content {
+// This object monitors the URLLoaderCompletionStatus change when
+// ResourceDownloader is asking |delegate_| whether download can proceed.
+class URLLoaderStatusMonitor : public mojom::URLLoaderClient {
+ public:
+ using URLLoaderStatusChangeCallback =
+ base::OnceCallback<void(const network::URLLoaderCompletionStatus&)>;
+ explicit URLLoaderStatusMonitor(URLLoaderStatusChangeCallback callback);
+ ~URLLoaderStatusMonitor() override = default;
+
+ // mojom::URLLoaderClient
+ void OnReceiveResponse(
+ const ResourceResponseHead& head,
+ const base::Optional<net::SSLInfo>& ssl_info,
+ mojom::DownloadedTempFilePtr downloaded_file) override {}
+ void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& head) override {}
+ void OnDataDownloaded(int64_t data_length, int64_t encoded_length) 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;
+
+ private:
+ URLLoaderStatusChangeCallback callback_;
+ DISALLOW_COPY_AND_ASSIGN(URLLoaderStatusMonitor);
+};
+
+URLLoaderStatusMonitor::URLLoaderStatusMonitor(
+ URLLoaderStatusChangeCallback callback)
+ : callback_(std::move(callback)) {}
+
+void URLLoaderStatusMonitor::OnComplete(
+ const network::URLLoaderCompletionStatus& status) {
+ std::move(callback_).Run(status);
+}
+
// This class is only used for providing the WebContents to DownloadItemImpl.
class RequestHandle : public DownloadRequestHandleInterface {
public:
- RequestHandle(int render_process_id, int render_frame_id)
- : render_process_id_(render_process_id),
- render_frame_id_(render_frame_id) {}
+ explicit RequestHandle(const ResourceRequestInfo::WebContentsGetter& getter)
+ : web_contents_getter_(getter) {}
RequestHandle(RequestHandle&& other)
- : render_process_id_(other.render_process_id_),
- render_frame_id_(other.render_frame_id_) {}
+ : web_contents_getter_(other.web_contents_getter_) {}
// DownloadRequestHandleInterface
WebContents* GetWebContents() const override {
- RenderFrameHost* host =
- RenderFrameHost::FromID(render_process_id_, render_frame_id_);
- if (host)
- return WebContents::FromRenderFrameHost(host);
- return nullptr;
+ return web_contents_getter_.Run();
}
+
DownloadManager* GetDownloadManager() const override { return nullptr; }
void PauseRequest() const override {}
void ResumeRequest() const override {}
void CancelRequest(bool user_cancel) const override {}
private:
- int render_process_id_;
- int render_frame_id_;
+ ResourceRequestInfo::WebContentsGetter web_contents_getter_;
DISALLOW_COPY_AND_ASSIGN(RequestHandle);
};
@@ -50,107 +84,122 @@ std::unique_ptr<ResourceDownloader> ResourceDownloader::BeginDownload(
std::unique_ptr<ResourceRequest> request,
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
scoped_refptr<storage::FileSystemContext> file_system_context,
+ const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
uint32_t download_id,
bool is_parallel_request) {
- mojom::URLLoaderFactoryPtr* factory =
- params->url().SchemeIs(url::kBlobScheme)
- ? url_loader_factory_getter->GetBlobFactory()
- : url_loader_factory_getter->GetNetworkFactory();
- auto downloader = base::MakeUnique<ResourceDownloader>(
- delegate, std::move(request),
- base::MakeUnique<DownloadSaveInfo>(params->GetSaveInfo()), download_id,
- params->guid(), is_parallel_request, params->is_transient(),
- params->fetch_error_body());
- downloader->Start(factory, file_system_context, std::move(params));
+ auto downloader = std::make_unique<ResourceDownloader>(
+ delegate, std::move(request), web_contents_getter, download_id);
+
+ downloader->Start(url_loader_factory_getter, file_system_context,
+ std::move(params), is_parallel_request);
return downloader;
}
// static
-std::unique_ptr<ResourceDownloader>
-ResourceDownloader::InterceptNavigationResponse(
+std::unique_ptr<ResourceDownloader> ResourceDownloader::CreateWithURLLoader(
base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
std::unique_ptr<ResourceRequest> resource_request,
- const scoped_refptr<ResourceResponse>& response,
- mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const SSLStatus& ssl_status,
+ const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
std::unique_ptr<ThrottlingURLLoader> url_loader,
- base::Optional<ResourceRequestCompletionStatus> completion_status) {
- auto downloader = base::MakeUnique<ResourceDownloader>(
- delegate, std::move(resource_request),
- base::MakeUnique<DownloadSaveInfo>(), content::DownloadItem::kInvalidId,
- std::string(), false, false, false);
- downloader->InterceptResponse(std::move(url_loader), response,
- std::move(consumer_handle), ssl_status,
- std::move(completion_status));
+ base::Optional<network::URLLoaderCompletionStatus> status) {
+ auto downloader = std::make_unique<ResourceDownloader>(
+ delegate, std::move(resource_request), web_contents_getter,
+ DownloadItem::kInvalidId);
+ downloader->InitializeURLLoader(std::move(url_loader), std::move(status));
return downloader;
}
ResourceDownloader::ResourceDownloader(
base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
std::unique_ptr<ResourceRequest> resource_request,
- std::unique_ptr<DownloadSaveInfo> save_info,
- uint32_t download_id,
- std::string guid,
- bool is_parallel_request,
- bool is_transient,
- bool fetch_error_body)
+ const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
+ uint32_t download_id)
: delegate_(delegate),
resource_request_(std::move(resource_request)),
- response_handler_(resource_request_.get(),
- this,
- std::move(save_info),
- is_parallel_request,
- is_transient,
- fetch_error_body),
- blob_client_binding_(&response_handler_),
download_id_(download_id),
- guid_(guid),
+ web_contents_getter_(web_contents_getter),
weak_ptr_factory_(this) {}
ResourceDownloader::~ResourceDownloader() = default;
void ResourceDownloader::Start(
- mojom::URLLoaderFactoryPtr* factory,
+ scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
scoped_refptr<storage::FileSystemContext> file_system_context,
- std::unique_ptr<DownloadUrlParameters> download_url_parameters) {
+ std::unique_ptr<DownloadUrlParameters> download_url_parameters,
+ bool is_parallel_request) {
callback_ = download_url_parameters->callback();
+ guid_ = download_url_parameters->guid();
+ url_loader_client_ = base::MakeUnique<DownloadResponseHandler>(
+ resource_request_.get(), this,
+ std::make_unique<DownloadSaveInfo>(
+ download_url_parameters->GetSaveInfo()),
+ is_parallel_request, download_url_parameters->is_transient(),
+ download_url_parameters->fetch_error_body(),
+ std::vector<GURL>(1, resource_request_->url));
+
if (download_url_parameters->url().SchemeIs(url::kBlobScheme)) {
+ // To avoid race conditions with blob URL being immediately revoked after
+ // the download starting (which ThrottlingURLLoader doesn't handle), call
+ // directly into BlobURLLoaderFactory for blob URLs.
mojom::URLLoaderRequest url_loader_request;
mojom::URLLoaderClientPtr client;
- blob_client_binding_.Bind(mojo::MakeRequest(&client));
+ blob_client_binding_ =
+ base::MakeUnique<mojo::Binding<mojom::URLLoaderClient>>(
+ url_loader_client_.get());
+ blob_client_binding_->Bind(mojo::MakeRequest(&client));
BlobURLLoaderFactory::CreateLoaderAndStart(
std::move(url_loader_request), *(resource_request_.get()),
- std::move(client), download_url_parameters->GetBlobDataHandle(),
- file_system_context.get());
+ std::move(client), download_url_parameters->GetBlobDataHandle());
} else {
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
- factory->get(), std::vector<std::unique_ptr<URLLoaderThrottle>>(),
+ url_loader_factory_getter->GetNetworkFactory(),
+ std::vector<std::unique_ptr<URLLoaderThrottle>>(),
0, // routing_id
0, // request_id
- mojom::kURLLoadOptionSendSSLInfo | mojom::kURLLoadOptionSniffMimeType,
- *(resource_request_.get()), &response_handler_,
- download_url_parameters->GetNetworkTrafficAnnotation());
+ mojom::kURLLoadOptionSendSSLInfoWithResponse |
+ mojom::kURLLoadOptionSniffMimeType,
+ *(resource_request_.get()), url_loader_client_.get(),
+ download_url_parameters->GetNetworkTrafficAnnotation(),
+ base::ThreadTaskRunnerHandle::Get());
url_loader_->SetPriority(net::RequestPriority::IDLE,
0 /* intra_priority_value */);
}
}
-void ResourceDownloader::InterceptResponse(
+void ResourceDownloader::InitializeURLLoader(
std::unique_ptr<ThrottlingURLLoader> url_loader,
+ base::Optional<network::URLLoaderCompletionStatus> status) {
+ url_loader_status_ = std::move(status);
+ url_loader_ = std::move(url_loader);
+ url_loader_client_ = base::MakeUnique<URLLoaderStatusMonitor>(
+ base::Bind(&ResourceDownloader::OnURLLoaderStatusChanged,
+ weak_ptr_factory_.GetWeakPtr()));
+ url_loader_->set_forwarding_client(url_loader_client_.get());
+}
+
+void ResourceDownloader::OnURLLoaderStatusChanged(
+ const network::URLLoaderCompletionStatus& status) {
+ DCHECK(!url_loader_status_);
+ url_loader_status_ = status;
+}
+
+void ResourceDownloader::StartNavigationInterception(
const scoped_refptr<ResourceResponse>& response,
mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const SSLStatus& ssl_status,
- base::Optional<ResourceRequestCompletionStatus> completion_status) {
- url_loader_ = std::move(url_loader);
- url_loader_->set_forwarding_client(&response_handler_);
+ net::CertStatus cert_status,
+ std::vector<GURL> url_chain) {
+ url_loader_client_ = base::MakeUnique<DownloadResponseHandler>(
+ resource_request_.get(), this, std::make_unique<DownloadSaveInfo>(),
+ false, false, false, url_chain);
+ url_loader_->set_forwarding_client(url_loader_client_.get());
net::SSLInfo info;
- info.cert_status = ssl_status.cert_status;
- response_handler_.OnReceiveResponse(response->head,
- base::Optional<net::SSLInfo>(info),
- mojom::DownloadedTempFilePtr());
- response_handler_.OnStartLoadingResponseBody(std::move(consumer_handle));
- if (completion_status.has_value())
- response_handler_.OnComplete(completion_status.value());
+ info.cert_status = cert_status;
+ url_loader_client_->OnReceiveResponse(response->head,
+ base::Optional<net::SSLInfo>(info),
+ mojom::DownloadedTempFilePtr());
+ url_loader_client_->OnStartLoadingResponseBody(std::move(consumer_handle));
+ if (url_loader_status_)
+ url_loader_client_->OnComplete(url_loader_status_.value());
}
void ResourceDownloader::OnResponseStarted(
@@ -158,15 +207,14 @@ void ResourceDownloader::OnResponseStarted(
mojom::DownloadStreamHandlePtr stream_handle) {
download_create_info->download_id = download_id_;
download_create_info->guid = guid_;
- if (resource_request_->origin_pid >= 0) {
- download_create_info->request_handle.reset(new RequestHandle(
- resource_request_->origin_pid, resource_request_->render_frame_id));
- }
+ download_create_info->request_handle.reset(
+ new RequestHandle(web_contents_getter_));
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&UrlDownloadHandler::Delegate::OnUrlDownloadStarted,
delegate_, std::move(download_create_info),
- base::MakeUnique<DownloadManager::InputStream>(
+ std::make_unique<DownloadManager::InputStream>(
std::move(stream_handle)),
callback_));
}
diff --git a/chromium/content/browser/download/resource_downloader.h b/chromium/content/browser/download/resource_downloader.h
index a542a804ea9..3c4e1306249 100644
--- a/chromium/content/browser/download/resource_downloader.h
+++ b/chromium/content/browser/download/resource_downloader.h
@@ -8,11 +8,16 @@
#include "content/browser/download/download_response_handler.h"
#include "content/browser/download/url_download_handler.h"
#include "content/browser/url_loader_factory_getter.h"
+#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/common/resource_request.h"
#include "content/public/common/url_loader.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
+namespace storage {
+class FileSystemContext;
+}
+
namespace content {
class ThrottlingURLLoader;
@@ -28,29 +33,23 @@ class ResourceDownloader : public UrlDownloadHandler,
std::unique_ptr<ResourceRequest> request,
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
scoped_refptr<storage::FileSystemContext> file_system_context,
+ const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
uint32_t download_id,
bool is_parallel_request);
- // Called to intercept a navigation response.
- static std::unique_ptr<ResourceDownloader> InterceptNavigationResponse(
+ // Create the object with a URLLoader.
+ static std::unique_ptr<ResourceDownloader> CreateWithURLLoader(
base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
std::unique_ptr<ResourceRequest> resource_request,
- const scoped_refptr<ResourceResponse>& response,
- mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const SSLStatus& ssl_status,
+ const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
std::unique_ptr<ThrottlingURLLoader> url_loader,
- base::Optional<ResourceRequestCompletionStatus> completion_status);
-
- ResourceDownloader(base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
- std::unique_ptr<ResourceRequest> resource_request,
- std::unique_ptr<DownloadSaveInfo> save_info,
- uint32_t download_id,
- std::string guid,
- bool is_parallel_request,
- bool is_transient,
- bool fetch_error_body);
- ResourceDownloader(base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
- std::unique_ptr<ThrottlingURLLoader> url_loader);
+ base::Optional<network::URLLoaderCompletionStatus> status);
+
+ ResourceDownloader(
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
+ std::unique_ptr<ResourceRequest> resource_request,
+ const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
+ uint32_t download_id);
~ResourceDownloader() override;
// DownloadResponseHandler::Delegate
@@ -59,11 +58,24 @@ class ResourceDownloader : public UrlDownloadHandler,
mojom::DownloadStreamHandlePtr stream_handle) override;
void OnReceiveRedirect() override;
+ // Helper method to start the navigation interception.
+ void StartNavigationInterception(
+ const scoped_refptr<ResourceResponse>& response,
+ mojo::ScopedDataPipeConsumerHandle consumer_handle,
+ net::CertStatus cert_status,
+ std::vector<GURL> url_chain);
+
private:
// Helper method to start the network request.
- void Start(mojom::URLLoaderFactoryPtr* factory,
+ void Start(scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
scoped_refptr<storage::FileSystemContext> file_system_context,
- std::unique_ptr<DownloadUrlParameters> download_url_parameters);
+ std::unique_ptr<DownloadUrlParameters> download_url_parameters,
+ bool is_parallel_request);
+
+ // Initializes |url_loader_| to take ownership of the |url_loader|.
+ void InitializeURLLoader(
+ std::unique_ptr<ThrottlingURLLoader> url_loader,
+ base::Optional<network::URLLoaderCompletionStatus> status);
// Intercepts the navigation response and takes ownership of the |url_loader|.
void InterceptResponse(
@@ -71,7 +83,13 @@ class ResourceDownloader : public UrlDownloadHandler,
const scoped_refptr<ResourceResponse>& response,
mojo::ScopedDataPipeConsumerHandle consumer_handle,
const SSLStatus& ssl_status,
- base::Optional<ResourceRequestCompletionStatus> completion_status);
+ int frame_tree_node_id,
+ std::vector<GURL> url_chain,
+ base::Optional<network::URLLoaderCompletionStatus> status);
+
+ // Called when URLLoader status is changed.
+ void OnURLLoaderStatusChanged(
+ const network::URLLoaderCompletionStatus& status);
base::WeakPtr<UrlDownloadHandler::Delegate> delegate_;
@@ -82,10 +100,11 @@ class ResourceDownloader : public UrlDownloadHandler,
std::unique_ptr<ResourceRequest> resource_request_;
// Object for handing the server response.
- DownloadResponseHandler response_handler_;
+ std::unique_ptr<mojom::URLLoaderClient> url_loader_client_;
// URLLoaderClient binding for loading a blob.
- mojo::Binding<mojom::URLLoaderClient> blob_client_binding_;
+ std::unique_ptr<mojo::Binding<mojom::URLLoaderClient>> blob_client_binding_;
+ // mojo::Binding<mojom::URLLoaderClient> blob_client_binding_;
// ID of the download, or DownloadItem::kInvalidId if this is a new
// download.
@@ -97,6 +116,12 @@ class ResourceDownloader : public UrlDownloadHandler,
// Callback to run after download starts.
DownloadUrlParameters::OnStartedCallback callback_;
+ // Used to get WebContents in browser process.
+ ResourceRequestInfo::WebContentsGetter web_contents_getter_;
+
+ // URLLoader status when intercepting the navigation request.
+ base::Optional<network::URLLoaderCompletionStatus> url_loader_status_;
+
base::WeakPtrFactory<ResourceDownloader> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ResourceDownloader);
diff --git a/chromium/content/browser/download/save_file.cc b/chromium/content/browser/download/save_file.cc
index a9b0aaee08c..ac029b17209 100644
--- a/chromium/content/browser/download/save_file.cc
+++ b/chromium/content/browser/download/save_file.cc
@@ -6,7 +6,7 @@
#include "base/logging.h"
#include "content/browser/download/download_task_runner.h"
-#include "net/log/net_log_with_source.h"
+#include "content/public/browser/download_item.h"
namespace content {
@@ -15,7 +15,7 @@ namespace content {
// Unfortunately, as it is, constructors of SaveFile don't always
// have access to the SavePackage at this point.
SaveFile::SaveFile(const SaveFileCreateInfo* info, bool calculate_hash)
- : file_(net::NetLogWithSource()), info_(info) {
+ : file_(DownloadItem::kInvalidId), info_(info) {
DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
DCHECK(info);
diff --git a/chromium/content/browser/download/save_file_manager.cc b/chromium/content/browser/download/save_file_manager.cc
index b2458d298c5..44046744c7f 100644
--- a/chromium/content/browser/download/save_file_manager.cc
+++ b/chromium/content/browser/download/save_file_manager.cc
@@ -183,7 +183,7 @@ void SaveFileManager::StartSave(SaveFileCreateInfo* info) {
DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
DCHECK(info);
// No need to calculate hash.
- std::unique_ptr<SaveFile> save_file = base::MakeUnique<SaveFile>(info, false);
+ std::unique_ptr<SaveFile> save_file = std::make_unique<SaveFile>(info, false);
// TODO(phajdan.jr): We should check the return value and handle errors here.
save_file->Initialize();
@@ -327,7 +327,7 @@ void SaveFileManager::OnSaveURL(const GURL& url,
policy_exception_justification: "Not implemented."
})");
std::unique_ptr<net::URLRequest> request(request_context->CreateRequest(
- url, net::DEFAULT_PRIORITY, NULL, traffic_annotation));
+ url, net::DEFAULT_PRIORITY, nullptr, traffic_annotation));
request->set_method("GET");
// The URLRequest needs to be initialized with the referrer and other
diff --git a/chromium/content/browser/download/save_package.cc b/chromium/content/browser/download/save_package.cc
index 7e94e7d13c4..185e2d5350b 100644
--- a/chromium/content/browser/download/save_package.cc
+++ b/chromium/content/browser/download/save_package.cc
@@ -139,7 +139,7 @@ class SavePackageRequestHandle : public DownloadRequestHandleInterface {
}
private:
- base::WeakPtr<SavePackage> save_package_;
+ base::WeakPtr<SavePackage> const save_package_;
};
} // namespace
@@ -335,13 +335,9 @@ void SavePackage::OnMHTMLGenerated(int64_t size) {
download_->OnAllDataSaved(size, std::unique_ptr<crypto::SecureHash>());
- if (!download_manager_->GetDelegate()) {
- Finish();
- return;
- }
-
- if (download_manager_->GetDelegate()->ShouldCompleteDownload(
- download_, base::Bind(&SavePackage::Finish, this))) {
+ auto* delegate = download_manager_->GetDelegate();
+ if (!delegate || delegate->ShouldCompleteDownload(
+ download_, base::Bind(&SavePackage::Finish, this))) {
Finish();
}
}
@@ -360,6 +356,7 @@ uint32_t SavePackage::GetMaxPathLengthForDirectory(
#endif
}
+// static
bool SavePackage::TruncateBaseNameToFitPathConstraints(
const base::FilePath& dir_path,
const base::FilePath::StringType& file_name_ext,
@@ -430,58 +427,63 @@ bool SavePackage::GenerateFileName(const std::string& disposition,
// Check whether we already have same name in a case insensitive manner.
FileNameSet::const_iterator iter = file_name_set_.find(file_name);
if (iter == file_name_set_.end()) {
+ DCHECK(!file_name.empty());
file_name_set_.insert(file_name);
+ generated_name->assign(file_name);
+ return true;
+ }
+
+ // Found same name, increase the ordinal number for the file name.
+ base_name = base::FilePath(*iter).RemoveExtension().BaseName().value();
+ base::FilePath::StringType base_file_name = StripOrdinalNumber(base_name);
+
+ // We need to make sure the length of base file name plus maximum ordinal
+ // number path will be less than or equal to kMaxFilePathLength.
+ if (!TruncateBaseNameToFitPathConstraints(
+ saved_main_directory_path_, file_name_ext,
+ max_path - kMaxFileOrdinalNumberPartLength, &base_file_name)) {
+ return false;
+ }
+
+ // Prepare the new ordinal number.
+ uint32_t ordinal_number;
+ FileNameCountMap::iterator 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;
+ ordinal_number = 1;
} else {
- // Found same name, increase the ordinal number for the file name.
- base_name = base::FilePath(*iter).RemoveExtension().BaseName().value();
- base::FilePath::StringType base_file_name = StripOrdinalNumber(base_name);
-
- // We need to make sure the length of base file name plus maximum ordinal
- // number path will be less than or equal to kMaxFilePathLength.
- if (!TruncateBaseNameToFitPathConstraints(
- saved_main_directory_path_, file_name_ext,
- max_path - kMaxFileOrdinalNumberPartLength, &base_file_name))
- return false;
+ // We have met same base-name conflict, use latest ordinal number.
+ ordinal_number = it->second;
+ }
- // Prepare the new ordinal number.
- uint32_t ordinal_number;
- FileNameCountMap::iterator 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;
- ordinal_number = 1;
- } else {
- // We have met same base-name conflict, use latest ordinal number.
- ordinal_number = it->second;
+ if (ordinal_number > kMaxFileOrdinalNumber - 1) {
+ // Use a random file from temporary file.
+ base::FilePath temp_file;
+ base::CreateTemporaryFile(&temp_file);
+ file_name = temp_file.RemoveExtension().BaseName().value();
+ // Get safe pure file name.
+ if (!TruncateBaseNameToFitPathConstraints(saved_main_directory_path_,
+ base::FilePath::StringType(),
+ max_path, &file_name)) {
+ return false;
}
-
- if (ordinal_number > (kMaxFileOrdinalNumber - 1)) {
- // Use a random file from temporary file.
- base::FilePath temp_file;
- base::CreateTemporaryFile(&temp_file);
- file_name = temp_file.RemoveExtension().BaseName().value();
- // Get safe pure file name.
- if (!TruncateBaseNameToFitPathConstraints(saved_main_directory_path_,
- base::FilePath::StringType(),
- max_path, &file_name))
- return false;
- } else {
- for (int i = ordinal_number; i < kMaxFileOrdinalNumber; ++i) {
- base::FilePath::StringType new_name = base_file_name +
- base::StringPrintf(FILE_PATH_LITERAL("(%d)"), i) + file_name_ext;
- if (file_name_set_.find(new_name) == file_name_set_.end()) {
- // Resolved name conflict.
- file_name = new_name;
- file_name_count_map_[base_file_name] = ++i;
- break;
- }
+ } else {
+ for (int i = ordinal_number; i < kMaxFileOrdinalNumber; ++i) {
+ base::FilePath::StringType new_name =
+ base_file_name + base::StringPrintf(FILE_PATH_LITERAL("(%d)"), i) +
+ file_name_ext;
+ if (!base::ContainsKey(file_name_set_, new_name)) {
+ // Resolved name conflict.
+ file_name = new_name;
+ file_name_count_map_[base_file_name] = ++i;
+ break;
}
}
-
- file_name_set_.insert(file_name);
}
DCHECK(!file_name.empty());
+ file_name_set_.insert(file_name);
generated_name->assign(file_name);
return true;
@@ -833,33 +835,7 @@ int64_t SavePackage::CurrentSpeed() const {
void SavePackage::DoSavingProcess() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (save_type_ == SAVE_PAGE_TYPE_AS_COMPLETE_HTML) {
- // We guarantee that images and JavaScripts must be downloaded first.
- // So when finishing all those sub-resources, we will know which
- // sub-resource's link can be replaced with local file path, which
- // sub-resource's link need to be replaced with absolute URL which
- // point to its internet address because it got error when saving its data.
-
- // Start a new SaveItem job if we still have job in waiting queue.
- if (waiting_item_queue_.size()) {
- DCHECK_EQ(NET_FILES, wait_state_);
- const SaveItem* save_item = waiting_item_queue_.front().get();
- if (save_item->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) {
- SaveNextFile(false);
- } else if (!in_process_count()) {
- // If there is no in-process SaveItem, it means all sub-resources
- // have been processed. Now we need to start serializing HTML DOM
- // for the current page to get the generated HTML data.
- wait_state_ = HTML_DATA;
- // All non-HTML resources have been finished, start all remaining
- // HTML files.
- SaveNextFile(true);
- }
- } else if (in_process_count()) {
- // Continue asking for HTML data.
- DCHECK_EQ(HTML_DATA, wait_state_);
- }
- } else {
+ if (save_type_ != SAVE_PAGE_TYPE_AS_COMPLETE_HTML) {
// Save as HTML only or MHTML.
DCHECK_EQ(NET_FILES, wait_state_);
DCHECK((save_type_ == SAVE_PAGE_TYPE_AS_ONLY_HTML) ||
@@ -869,6 +845,33 @@ void SavePackage::DoSavingProcess() {
DCHECK_EQ(all_save_items_count_, waiting_item_queue_.size());
SaveNextFile(false);
}
+ return;
+ }
+
+ // We guarantee that images and JavaScripts must be downloaded first.
+ // So when finishing all those sub-resources, we will know which
+ // sub-resource's link can be replaced with local file path, which
+ // sub-resource's link need to be replaced with absolute URL which
+ // point to its internet address because it got error when saving its data.
+
+ // Start a new SaveItem job if we still have job in waiting queue.
+ if (!waiting_item_queue_.empty()) {
+ DCHECK_EQ(NET_FILES, wait_state_);
+ const SaveItem* save_item = waiting_item_queue_.front().get();
+ if (save_item->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) {
+ SaveNextFile(false);
+ } else if (!in_process_count()) {
+ // If there is no in-process SaveItem, it means all sub-resources
+ // have been processed. Now we need to start serializing HTML DOM
+ // for the current page to get the generated HTML data.
+ wait_state_ = HTML_DATA;
+ // All non-HTML resources have been finished, start all remaining
+ // HTML files.
+ SaveNextFile(true);
+ }
+ } else if (in_process_count()) {
+ // Continue asking for HTML data.
+ DCHECK_EQ(HTML_DATA, wait_state_);
}
}
@@ -1143,7 +1146,7 @@ SaveItem* SavePackage::CreatePendingSaveItem(
return save_item;
}
-SaveItem* SavePackage::CreatePendingSaveItemDeduplicatingByUrl(
+void SavePackage::CreatePendingSaveItemDeduplicatingByUrl(
int container_frame_tree_node_id,
int save_item_frame_tree_node_id,
const GURL& url,
@@ -1155,20 +1158,15 @@ SaveItem* SavePackage::CreatePendingSaveItemDeduplicatingByUrl(
// Frames should not be deduplicated by URL.
DCHECK_NE(SaveFileCreateInfo::SAVE_FILE_FROM_DOM, save_source);
- SaveItem* save_item;
auto it = url_to_save_item_.find(url);
if (it != url_to_save_item_.end()) {
- save_item = it->second;
frame_tree_node_id_to_contained_save_items_[container_frame_tree_node_id]
- .push_back(save_item);
+ .push_back(it->second);
} else {
- save_item = CreatePendingSaveItem(container_frame_tree_node_id,
- save_item_frame_tree_node_id, url,
- referrer, save_source);
- url_to_save_item_[url] = save_item;
+ url_to_save_item_[url] = CreatePendingSaveItem(container_frame_tree_node_id,
+ save_item_frame_tree_node_id,
+ url, referrer, save_source);
}
-
- return save_item;
}
void SavePackage::EnqueueSavableResource(int container_frame_tree_node_id,
@@ -1267,8 +1265,7 @@ base::FilePath SavePackage::GetSuggestedNameForSaveAs(
url_formatter::IDNToUnicode(page_url.host()));
}
} else {
- name_with_proper_ext =
- base::FilePath::FromUTF8Unsafe(std::string("dataurl"));
+ name_with_proper_ext = base::FilePath::FromUTF8Unsafe("dataurl");
}
}
@@ -1286,7 +1283,7 @@ base::FilePath SavePackage::GetSuggestedNameForSaveAs(
// static
base::FilePath SavePackage::EnsureHtmlExtension(const base::FilePath& name) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
base::FilePath::StringType ext = name.Extension();
if (!ext.empty())
@@ -1303,7 +1300,7 @@ base::FilePath SavePackage::EnsureHtmlExtension(const base::FilePath& name) {
// static
base::FilePath SavePackage::EnsureMimeExtension(const base::FilePath& name,
const std::string& contents_mime_type) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
// Start extension at 1 to skip over period if non-empty.
base::FilePath::StringType ext = name.Extension();
@@ -1327,14 +1324,14 @@ const base::FilePath::CharType* SavePackage::ExtensionForMimeType(
static const struct {
const char* mime_type;
const base::FilePath::CharType* suggested_extension;
- } extensions[] = {
- { "text/html", kDefaultHtmlExtension },
- { "text/xml", FILE_PATH_LITERAL("xml") },
- { "application/xhtml+xml", FILE_PATH_LITERAL("xhtml") },
- { "text/plain", FILE_PATH_LITERAL("txt") },
- { "text/css", FILE_PATH_LITERAL("css") },
+ } kExtensions[] = {
+ {"text/html", kDefaultHtmlExtension},
+ {"text/xml", FILE_PATH_LITERAL("xml")},
+ {"application/xhtml+xml", FILE_PATH_LITERAL("xhtml")},
+ {"text/plain", FILE_PATH_LITERAL("txt")},
+ {"text/css", FILE_PATH_LITERAL("css")},
};
- for (const auto& extension : extensions) {
+ for (const auto& extension : kExtensions) {
if (contents_mime_type == extension.mime_type)
return extension.suggested_extension;
}
diff --git a/chromium/content/browser/download/save_package.h b/chromium/content/browser/download/save_package.h
index 1a5c6bd4c60..0df676c5545 100644
--- a/chromium/content/browser/download/save_package.h
+++ b/chromium/content/browser/download/save_package.h
@@ -152,6 +152,8 @@ class CONTENT_EXPORT SavePackage
const base::FilePath& file_full_path,
const base::FilePath& directory_full_path);
+ ~SavePackage() override;
+
void InitWithDownloadItem(
const SavePackageDownloadCreatedCallback& download_created_callback,
DownloadItemImpl* item);
@@ -159,8 +161,6 @@ class CONTENT_EXPORT SavePackage
// Callback for WebContents::GenerateMHTML().
void OnMHTMLGenerated(int64_t size);
- ~SavePackage() override;
-
// Notes from Init() above applies here as well.
void InternalInit();
@@ -246,7 +246,7 @@ class CONTENT_EXPORT SavePackage
// Helper for finding a SaveItem with the given url, or falling back to
// creating a SaveItem with the given parameters.
- SaveItem* CreatePendingSaveItemDeduplicatingByUrl(
+ void CreatePendingSaveItemDeduplicatingByUrl(
int container_frame_tree_node_id,
int save_item_frame_tree_node_id,
const GURL& url,
@@ -394,12 +394,12 @@ class CONTENT_EXPORT SavePackage
DownloadItemImpl* download_ = nullptr;
// The URL of the page the user wants to save.
- GURL page_url_;
+ const GURL page_url_;
base::FilePath saved_main_file_path_;
base::FilePath saved_main_directory_path_;
// The title of the page the user wants to save.
- base::string16 title_;
+ const base::string16 title_;
// Used to calculate package download speed (in files per second).
const base::TimeTicks start_tick_;
diff --git a/chromium/content/browser/download/save_package_browsertest.cc b/chromium/content/browser/download/save_package_browsertest.cc
index 6d4eb46c736..6cfc1705305 100644
--- a/chromium/content/browser/download/save_package_browsertest.cc
+++ b/chromium/content/browser/download/save_package_browsertest.cc
@@ -100,7 +100,7 @@ class SavePackageBrowserTest : public ContentBrowserTest {
static_cast<DownloadManagerImpl*>(BrowserContext::GetDownloadManager(
shell()->web_contents()->GetBrowserContext()));
auto delegate =
- base::MakeUnique<TestShellDownloadManagerDelegate>(save_page_type);
+ std::make_unique<TestShellDownloadManagerDelegate>(save_page_type);
delegate->download_dir_ = save_dir_.GetPath();
auto* old_delegate = download_manager->GetDelegate();
download_manager->SetDelegate(delegate.get());
diff --git a/chromium/content/browser/download/slow_download_http_response.cc b/chromium/content/browser/download/slow_download_http_response.cc
deleted file mode 100644
index 2f0249a4b9a..00000000000
--- a/chromium/content/browser/download/slow_download_http_response.cc
+++ /dev/null
@@ -1,106 +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/browser/download/slow_download_http_response.h"
-
-#include "base/bind.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_task_runner_handle.h"
-
-namespace content {
-
-namespace {
-
-static bool g_should_finish_download = false;
-
-void SendResponseBodyDone(const net::test_server::SendBytesCallback& send,
- const net::test_server::SendCompleteCallback& done);
-
-// Sends the response body with the given size.
-void SendResponseBody(const net::test_server::SendBytesCallback& send,
- const net::test_server::SendCompleteCallback& done,
- bool finish_download) {
- int data_size = finish_download
- ? SlowDownloadHttpResponse::kSecondDownloadSize
- : SlowDownloadHttpResponse::kFirstDownloadSize;
- std::string response(data_size, '*');
-
- if (finish_download)
- send.Run(response, done);
- else
- send.Run(response, base::Bind(&SendResponseBodyDone, send, done));
-}
-
-// Called when the response body was sucessfully sent.
-void SendResponseBodyDone(const net::test_server::SendBytesCallback& send,
- const net::test_server::SendCompleteCallback& done) {
- if (g_should_finish_download) {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::Bind(&SendResponseBody, send, done, true),
- base::TimeDelta::FromMilliseconds(100));
- } else {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::Bind(&SendResponseBodyDone, send, done),
- base::TimeDelta::FromMilliseconds(100));
- }
-}
-
-} // namespace
-
-// static
-const char SlowDownloadHttpResponse::kSlowDownloadHostName[] =
- "url.handled.by.slow.download";
-const char SlowDownloadHttpResponse::kUnknownSizeUrl[] =
- "/download-unknown-size";
-const char SlowDownloadHttpResponse::kKnownSizeUrl[] = "/download-known-size";
-const char SlowDownloadHttpResponse::kFinishDownloadUrl[] = "/download-finish";
-
-const int SlowDownloadHttpResponse::kFirstDownloadSize = 1024 * 35;
-const int SlowDownloadHttpResponse::kSecondDownloadSize = 1024 * 10;
-
-// static
-std::unique_ptr<net::test_server::HttpResponse>
-SlowDownloadHttpResponse::HandleSlowDownloadRequest(
- const net::test_server::HttpRequest& request) {
- if (request.relative_url != kUnknownSizeUrl &&
- request.relative_url != kKnownSizeUrl &&
- request.relative_url != kFinishDownloadUrl) {
- return nullptr;
- }
- auto response =
- base::MakeUnique<SlowDownloadHttpResponse>(request.relative_url);
- return std::move(response);
-}
-
-SlowDownloadHttpResponse::SlowDownloadHttpResponse(const std::string& url)
- : url_(url) {}
-
-SlowDownloadHttpResponse::~SlowDownloadHttpResponse() = default;
-
-void SlowDownloadHttpResponse::SendResponse(
- const net::test_server::SendBytesCallback& send,
- const net::test_server::SendCompleteCallback& done) {
- std::string response;
- response.append("HTTP/1.1 200 OK\r\n");
- if (base::LowerCaseEqualsASCII(kFinishDownloadUrl, url_)) {
- response.append("Content-type: text/plain\r\n");
- response.append("\r\n");
-
- g_should_finish_download = true;
- send.Run(response, done);
- } else {
- response.append("Content-type: application/octet-stream\r\n");
- response.append("Cache-Control: max-age=0\r\n");
-
- if (base::LowerCaseEqualsASCII(kKnownSizeUrl, url_)) {
- response.append(base::StringPrintf(
- "Content-Length: %d\r\n", kFirstDownloadSize + kSecondDownloadSize));
- }
- response.append("\r\n");
- send.Run(response, base::Bind(&SendResponseBody, send, done, false));
- }
-}
-
-} // namespace content
diff --git a/chromium/content/browser/download/slow_download_http_response.h b/chromium/content/browser/download/slow_download_http_response.h
deleted file mode 100644
index 1a42a9988b3..00000000000
--- a/chromium/content/browser/download/slow_download_http_response.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_BROWSER_DOWNLOAD_SLOW_DOWNLOAD_HTTP_RESPONSE_H_
-#define CONTENT_BROWSER_DOWNLOAD_SLOW_DOWNLOAD_HTTP_RESPONSE_H_
-
-#include <set>
-#include <string>
-
-#include "net/test/embedded_test_server/http_request.h"
-#include "net/test/embedded_test_server/http_response.h"
-
-namespace content {
-
-/*
- * Download response that won't complete until |kFinishDownloadUrl| request is
- * received.
- */
-class SlowDownloadHttpResponse : public net::test_server::HttpResponse {
- public:
- // Test URLs.
- static const char kSlowDownloadHostName[];
- static const char kUnknownSizeUrl[];
- static const char kKnownSizeUrl[];
- static const char kFinishDownloadUrl[];
- static const int kFirstDownloadSize;
- static const int kSecondDownloadSize;
-
- static std::unique_ptr<net::test_server::HttpResponse>
- HandleSlowDownloadRequest(const net::test_server::HttpRequest& request);
-
- SlowDownloadHttpResponse(const std::string& url);
- ~SlowDownloadHttpResponse() override;
-
- // net::test_server::HttpResponse implementations.
- void SendResponse(
- const net::test_server::SendBytesCallback& send,
- const net::test_server::SendCompleteCallback& done) override;
-
- private:
- std::string url_;
-
- DISALLOW_COPY_AND_ASSIGN(SlowDownloadHttpResponse);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_DOWNLOAD_SLOW_DOWNLOAD_HTTP_RESPONSE_H_
diff --git a/chromium/content/browser/download/url_downloader.cc b/chromium/content/browser/download/url_downloader.cc
index f6b3a4a6ebf..2568bf82e89 100644
--- a/chromium/content/browser/download/url_downloader.cc
+++ b/chromium/content/browser/download/url_downloader.cc
@@ -218,7 +218,7 @@ void UrlDownloader::OnStart(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&UrlDownloadHandler::Delegate::OnUrlDownloadStarted,
delegate_, std::move(create_info),
- base::MakeUnique<DownloadManager::InputStream>(
+ std::make_unique<DownloadManager::InputStream>(
std::move(stream_reader)),
callback));
}
diff --git a/chromium/content/browser/field_trial_recorder.cc b/chromium/content/browser/field_trial_recorder.cc
index 02c672dad1c..ed847e7fe89 100644
--- a/chromium/content/browser/field_trial_recorder.cc
+++ b/chromium/content/browser/field_trial_recorder.cc
@@ -17,7 +17,7 @@ FieldTrialRecorder::~FieldTrialRecorder() = default;
// static
void FieldTrialRecorder::Create(
mojom::FieldTrialRecorderRequest request) {
- mojo::MakeStrongBinding(base::MakeUnique<FieldTrialRecorder>(),
+ mojo::MakeStrongBinding(std::make_unique<FieldTrialRecorder>(),
std::move(request));
}
diff --git a/chromium/content/browser/file_url_loader_factory.cc b/chromium/content/browser/file_url_loader_factory.cc
new file mode 100644
index 00000000000..28b6cd80113
--- /dev/null
+++ b/chromium/content/browser/file_url_loader_factory.cc
@@ -0,0 +1,589 @@
+// Copyright 2017 The Chromium Authors. 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/file_url_loader_factory.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#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/numerics/safe_conversions.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_util.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/file_url_loader.h"
+#include "content/public/common/resource_request.h"
+#include "content/public/common/url_loader.mojom.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"
+#include "mojo/public/cpp/system/string_data_pipe_producer.h"
+#include "net/base/directory_lister.h"
+#include "net/base/directory_listing.h"
+#include "net/base/filename_util.h"
+#include "net/base/mime_sniffer.h"
+#include "net/base/mime_util.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_byte_range.h"
+#include "net/http/http_util.h"
+#include "net/url_request/redirect_info.h"
+#include "url/gurl.h"
+
+#if defined(OS_WIN)
+#include "base/win/shortcut.h"
+#endif
+
+namespace content {
+namespace {
+
+constexpr size_t kDefaultFileUrlPipeSize = 65536;
+
+// Because this makes things simpler.
+static_assert(kDefaultFileUrlPipeSize >= net::kMaxBytesToSniff,
+ "Default file data pipe size must be at least as large as a MIME-"
+ "type sniffing buffer.");
+
+// Policy to control how a FileURLLoader will handle directory URLs.
+enum class DirectoryLoadingPolicy {
+ // File paths which refer to directories are allowed and will load as an
+ // HTML directory listing.
+ kRespondWithListing,
+
+ // File paths which refer to directories are treated as non-existent and
+ // will result in FILE_NOT_FOUND errors.
+ kFail,
+};
+
+// Policy to control whether or not file access constraints imposed by content
+// or its embedder should be honored by a FileURLLoader.
+enum class FileAccessPolicy {
+ // Enforces file acccess policy defined by content and/or its embedder.
+ kRestricted,
+
+ // Ignores file access policy, allowing contents to be loaded from any
+ // resolvable file path given.
+ kUnrestricted,
+};
+
+// Policy to control whether or not a FileURLLoader should follow filesystem
+// links (e.g. Windows shortcuts) where applicable.
+enum class LinkFollowingPolicy {
+ kFollow,
+ kDoNotFollow,
+};
+
+class FileURLDirectoryLoader
+ : public mojom::URLLoader,
+ public net::DirectoryLister::DirectoryListerDelegate {
+ public:
+ static void CreateAndStart(const base::FilePath& profile_path,
+ const ResourceRequest& request,
+ mojom::URLLoaderRequest loader,
+ 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* file_url_loader = new FileURLDirectoryLoader;
+ file_url_loader->Start(profile_path, request, std::move(loader),
+ std::move(client_info));
+ }
+
+ // mojom::URLLoader:
+ void FollowRedirect() override {}
+ void SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) override {}
+ void PauseReadingBodyFromNet() override {}
+ void ResumeReadingBodyFromNet() override {}
+
+ private:
+ FileURLDirectoryLoader() : binding_(this) {}
+ ~FileURLDirectoryLoader() override = default;
+
+ void Start(const base::FilePath& profile_path,
+ const ResourceRequest& request,
+ mojom::URLLoaderRequest loader,
+ mojom::URLLoaderClientPtrInfo client_info) {
+ binding_.Bind(std::move(loader));
+ binding_.set_connection_error_handler(base::BindOnce(
+ &FileURLDirectoryLoader::OnConnectionError, base::Unretained(this)));
+
+ mojom::URLLoaderClientPtr client;
+ client.Bind(std::move(client_info));
+
+ if (!net::FileURLToFilePath(request.url, &path_)) {
+ client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ return;
+ }
+
+ base::File::Info info;
+ if (!base::GetFileInfo(path_, &info) || !info.is_directory) {
+ client->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_FILE_NOT_FOUND));
+ return;
+ }
+
+ if (!GetContentClient()->browser()->IsFileAccessAllowed(
+ path_, base::MakeAbsoluteFilePath(path_), profile_path)) {
+ client->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED));
+ return;
+ }
+
+ mojo::DataPipe pipe(kDefaultFileUrlPipeSize);
+ if (!pipe.consumer_handle.is_valid()) {
+ client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ return;
+ }
+
+ ResourceResponseHead head;
+ head.mime_type = "text/html";
+ head.charset = "utf-8";
+ client->OnReceiveResponse(head, base::nullopt, nullptr);
+ client->OnStartLoadingResponseBody(std::move(pipe.consumer_handle));
+ client_ = std::move(client);
+
+ lister_ = std::make_unique<net::DirectoryLister>(path_, this);
+ lister_->Start();
+
+ data_producer_ = std::make_unique<mojo::StringDataPipeProducer>(
+ std::move(pipe.producer_handle));
+ }
+
+ void OnConnectionError() {
+ binding_.Close();
+ MaybeDeleteSelf();
+ }
+
+ void MaybeDeleteSelf() {
+ if (!binding_.is_bound() && !client_.is_bound() && !lister_)
+ delete this;
+ }
+
+ // net::DirectoryLister::DirectoryListerDelegate:
+ void OnListFile(
+ const net::DirectoryLister::DirectoryListerData& data) override {
+ if (!wrote_header_) {
+ wrote_header_ = true;
+
+#if defined(OS_WIN)
+ const base::string16& title = path_.value();
+#elif defined(OS_POSIX)
+ const base::string16& title =
+ base::WideToUTF16(base::SysNativeMBToWide(path_.value()));
+#endif
+ pending_data_.append(net::GetDirectoryListingHeader(title));
+
+ // If not a top-level directory, add a link to the parent directory. To
+ // figure this out, first normalize |path_| by stripping trailing
+ // separators. Then compare the result to its DirName(). For the top-level
+ // directory, e.g. "/" or "c:\\", the normalized path is equal to its own
+ // DirName().
+ base::FilePath stripped_path = path_.StripTrailingSeparators();
+ if (stripped_path != stripped_path.DirName())
+ pending_data_.append(net::GetParentDirectoryLink());
+ }
+
+ // Skip current / parent links from the listing.
+ base::FilePath filename = data.info.GetName();
+ if (filename.value() != base::FilePath::kCurrentDirectory &&
+ filename.value() != base::FilePath::kParentDirectory) {
+#if defined(OS_WIN)
+ std::string raw_bytes; // Empty on Windows means UTF-8 encoded name.
+#elif defined(OS_POSIX)
+ const std::string& raw_bytes = filename.value();
+#endif
+ pending_data_.append(net::GetDirectoryListingEntry(
+ filename.LossyDisplayName(), raw_bytes, data.info.IsDirectory(),
+ data.info.GetSize(), data.info.GetLastModifiedTime()));
+ }
+
+ MaybeTransferPendingData();
+ }
+
+ void OnListDone(int error) override {
+ listing_result_ = error;
+ lister_.reset();
+ MaybeDeleteSelf();
+ }
+
+ void MaybeTransferPendingData() {
+ if (transfer_in_progress_)
+ return;
+
+ transfer_in_progress_ = true;
+ data_producer_->Write(pending_data_,
+ base::BindOnce(&FileURLDirectoryLoader::OnDataWritten,
+ base::Unretained(this)));
+ // The producer above will have already copied any parts of |pending_data_|
+ // that couldn't be written immediately, so we can wipe it out here to begin
+ // accumulating more data.
+ pending_data_.clear();
+ }
+
+ void OnDataWritten(MojoResult result) {
+ transfer_in_progress_ = false;
+
+ int completion_status;
+ if (result == MOJO_RESULT_OK) {
+ if (!pending_data_.empty()) {
+ // Keep flushing the data buffer as long as it's non-empty and pipe
+ // writes are succeeding.
+ MaybeTransferPendingData();
+ return;
+ }
+
+ // If there's no pending data but the lister is still active, we simply
+ // wait for more listing results.
+ if (lister_)
+ return;
+
+ // At this point we know the listing is complete and all available data
+ // has been transferred. We inherit the status of the listing operation.
+ completion_status = listing_result_;
+ } else {
+ completion_status = net::ERR_FAILED;
+ }
+
+ client_->OnComplete(network::URLLoaderCompletionStatus(completion_status));
+ client_.reset();
+ MaybeDeleteSelf();
+ }
+
+ base::FilePath path_;
+ std::unique_ptr<net::DirectoryLister> lister_;
+ bool wrote_header_ = false;
+ int listing_result_;
+
+ mojo::Binding<mojom::URLLoader> binding_;
+ mojom::URLLoaderClientPtr client_;
+
+ std::unique_ptr<mojo::StringDataPipeProducer> data_producer_;
+ std::string pending_data_;
+ bool transfer_in_progress_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(FileURLDirectoryLoader);
+};
+
+class FileURLLoader : public mojom::URLLoader {
+ public:
+ static void CreateAndStart(const base::FilePath& profile_path,
+ const ResourceRequest& request,
+ mojom::URLLoaderRequest loader,
+ mojom::URLLoaderClientPtrInfo client_info,
+ DirectoryLoadingPolicy directory_loading_policy,
+ FileAccessPolicy file_access_policy,
+ LinkFollowingPolicy link_following_policy) {
+ // 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* file_url_loader = new FileURLLoader;
+ file_url_loader->Start(profile_path, request, std::move(loader),
+ std::move(client_info), directory_loading_policy,
+ file_access_policy, link_following_policy);
+ }
+
+ // mojom::URLLoader:
+ void FollowRedirect() override {}
+ void SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) override {}
+ void PauseReadingBodyFromNet() override {}
+ void ResumeReadingBodyFromNet() override {}
+
+ private:
+ FileURLLoader() : binding_(this) {}
+ ~FileURLLoader() override = default;
+
+ void Start(const base::FilePath& profile_path,
+ const ResourceRequest& request,
+ mojom::URLLoaderRequest loader,
+ mojom::URLLoaderClientPtrInfo client_info,
+ DirectoryLoadingPolicy directory_loading_policy,
+ FileAccessPolicy file_access_policy,
+ LinkFollowingPolicy link_following_policy) {
+ ResourceResponseHead head;
+ head.request_start = base::TimeTicks::Now();
+ head.response_start = base::TimeTicks::Now();
+ binding_.Bind(std::move(loader));
+ binding_.set_connection_error_handler(base::BindOnce(
+ &FileURLLoader::OnConnectionError, base::Unretained(this)));
+
+ mojom::URLLoaderClientPtr client;
+ client.Bind(std::move(client_info));
+
+ base::FilePath path;
+ if (!net::FileURLToFilePath(request.url, &path)) {
+ client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ return;
+ }
+
+ base::File::Info info;
+ if (!base::GetFileInfo(path, &info)) {
+ client->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_FILE_NOT_FOUND));
+ return;
+ }
+
+ if (info.is_directory) {
+ if (directory_loading_policy == DirectoryLoadingPolicy::kFail) {
+ client->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_FILE_NOT_FOUND));
+ return;
+ }
+
+ DCHECK_EQ(directory_loading_policy,
+ DirectoryLoadingPolicy::kRespondWithListing);
+
+ GURL directory_url = request.url;
+ if (!path.EndsWithSeparator()) {
+ // If the named path is a directory with no trailing slash, redirect to
+ // the same path, but with a trailing slash.
+ std::string new_path = directory_url.path() + '/';
+ GURL::Replacements replacements;
+ replacements.SetPathStr(new_path);
+ directory_url = directory_url.ReplaceComponents(replacements);
+
+ net::RedirectInfo redirect_info;
+ redirect_info.new_method = "GET";
+ redirect_info.status_code = 301;
+ redirect_info.new_url = directory_url;
+ head.encoded_data_length = 0;
+ client->OnReceiveRedirect(redirect_info, head);
+ }
+
+ // Restart the request with a directory loader.
+ ResourceRequest new_request = request;
+ new_request.url = directory_url;
+ FileURLDirectoryLoader::CreateAndStart(
+ profile_path, new_request, binding_.Unbind(), client.PassInterface());
+ MaybeDeleteSelf();
+ return;
+ }
+
+#if defined(OS_WIN)
+ base::FilePath shortcut_target;
+ if (link_following_policy == LinkFollowingPolicy::kFollow &&
+ base::LowerCaseEqualsASCII(path.Extension(), ".lnk") &&
+ base::win::ResolveShortcut(path, &shortcut_target, nullptr)) {
+ // Follow Windows shortcuts
+ GURL new_url = net::FilePathToFileURL(shortcut_target);
+
+ net::RedirectInfo redirect_info;
+ redirect_info.new_method = "GET";
+ redirect_info.status_code = 301;
+ redirect_info.new_url = new_url;
+ head.encoded_data_length = 0;
+ client->OnReceiveRedirect(redirect_info, head);
+
+ // Restart the request with the new URL.
+ ResourceRequest new_request = request;
+ new_request.url = redirect_info.new_url;
+ return Start(profile_path, request, binding_.Unbind(),
+ client.PassInterface(), directory_loading_policy,
+ file_access_policy, link_following_policy);
+ }
+#endif // defined(OS_WIN)
+
+ if (file_access_policy == FileAccessPolicy::kRestricted &&
+ !GetContentClient()->browser()->IsFileAccessAllowed(
+ path, base::MakeAbsoluteFilePath(path), profile_path)) {
+ client->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED));
+ return;
+ }
+
+ mojo::DataPipe pipe(kDefaultFileUrlPipeSize);
+ if (!pipe.consumer_handle.is_valid()) {
+ client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ return;
+ }
+
+ // Should never be possible for this to be a directory. If FileURLLoader
+ // is used to respond to a directory request, it must be because the URL
+ // path didn't have a trailing path separator. In that case we finish with
+ // a redirect above which will in turn be handled by FileURLDirectoryLoader.
+ DCHECK(!info.is_directory);
+
+ base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+ char initial_read_buffer[net::kMaxBytesToSniff];
+ int initial_read_result =
+ file.ReadAtCurrentPos(initial_read_buffer, net::kMaxBytesToSniff);
+ if (initial_read_result < 0) {
+ client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ return;
+ }
+ size_t initial_read_size = static_cast<size_t>(initial_read_result);
+
+ std::string range_header;
+ net::HttpByteRange byte_range;
+ if (request.headers.GetHeader(net::HttpRequestHeaders::kRange,
+ &range_header)) {
+ // Handle a simple Range header for a single range.
+ std::vector<net::HttpByteRange> ranges;
+ bool fail = false;
+ if (net::HttpUtil::ParseRangeHeader(range_header, &ranges) &&
+ ranges.size() == 1) {
+ byte_range = ranges[0];
+ if (!byte_range.ComputeBounds(info.size))
+ fail = true;
+ } else {
+ fail = true;
+ }
+
+ if (fail) {
+ client->OnComplete(network::URLLoaderCompletionStatus(
+ net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ return;
+ }
+ }
+
+ size_t first_byte_to_send = 0;
+ size_t total_bytes_to_send = static_cast<size_t>(info.size);
+ if (byte_range.IsValid()) {
+ 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;
+ }
+
+ head.content_length = base::saturated_cast<int64_t>(total_bytes_to_send);
+
+ if (first_byte_to_send < initial_read_size) {
+ // Write any data we read for MIME sniffing, constraining by range where
+ // applicable. This will always fit in the pipe (see assertion near
+ // |kDefaultFileUrlPipeSize| definition).
+ uint32_t write_size = std::min(
+ static_cast<uint32_t>(initial_read_size - first_byte_to_send),
+ static_cast<uint32_t>(total_bytes_to_send));
+ const uint32_t expected_write_size = write_size;
+ MojoResult result = pipe.producer_handle->WriteData(
+ &initial_read_buffer[first_byte_to_send], &write_size,
+ MOJO_WRITE_DATA_FLAG_NONE);
+ if (result != MOJO_RESULT_OK || write_size != expected_write_size) {
+ OnFileWritten(result);
+ return;
+ }
+
+ // Discount the bytes we just sent from the total range.
+ first_byte_to_send = initial_read_size;
+ total_bytes_to_send -= write_size;
+ }
+
+ if (!net::GetMimeTypeFromFile(path, &head.mime_type)) {
+ net::SniffMimeType(initial_read_buffer, initial_read_result, request.url,
+ head.mime_type, &head.mime_type);
+ }
+ client->OnReceiveResponse(head, base::nullopt, nullptr);
+ client->OnStartLoadingResponseBody(std::move(pipe.consumer_handle));
+ client_ = std::move(client);
+
+ if (total_bytes_to_send == 0) {
+ // There's definitely 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));
+ data_producer_->WriteFromFile(
+ std::move(file), total_bytes_to_send,
+ base::BindOnce(&FileURLLoader::OnFileWritten, base::Unretained(this)));
+ }
+
+ void OnConnectionError() {
+ binding_.Close();
+ MaybeDeleteSelf();
+ }
+
+ void MaybeDeleteSelf() {
+ if (!binding_.is_bound() && !client_.is_bound())
+ delete this;
+ }
+
+ void OnFileWritten(MojoResult result) {
+ if (result == MOJO_RESULT_OK)
+ client_->OnComplete(network::URLLoaderCompletionStatus(net::OK));
+ else
+ client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ client_.reset();
+ MaybeDeleteSelf();
+ }
+
+ std::unique_ptr<mojo::FileDataPipeProducer> data_producer_;
+ mojo::Binding<mojom::URLLoader> binding_;
+ mojom::URLLoaderClientPtr client_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileURLLoader);
+};
+
+} // namespace
+
+FileURLLoaderFactory::FileURLLoaderFactory(
+ const base::FilePath& profile_path,
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : profile_path_(profile_path), task_runner_(std::move(task_runner)) {}
+
+FileURLLoaderFactory::~FileURLLoaderFactory() = default;
+
+void FileURLLoaderFactory::CreateLoaderAndStart(
+ mojom::URLLoaderRequest loader,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const ResourceRequest& request,
+ mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
+ base::FilePath file_path;
+ const bool is_file = net::FileURLToFilePath(request.url, &file_path);
+ if (is_file && file_path.EndsWithSeparator() && file_path.IsAbsolute()) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&FileURLDirectoryLoader::CreateAndStart, profile_path_,
+ request, std::move(loader), client.PassInterface()));
+ } else {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&FileURLLoader::CreateAndStart, profile_path_, request,
+ std::move(loader), client.PassInterface(),
+ DirectoryLoadingPolicy::kRespondWithListing,
+ FileAccessPolicy::kRestricted,
+ LinkFollowingPolicy::kFollow));
+ }
+}
+
+void FileURLLoaderFactory::Clone(mojom::URLLoaderFactoryRequest loader) {
+ bindings_.AddBinding(this, std::move(loader));
+}
+
+void CreateFileURLLoader(const ResourceRequest& request,
+ mojom::URLLoaderRequest loader,
+ mojom::URLLoaderClientPtr client) {
+ auto task_runner = base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&FileURLLoader::CreateAndStart, base::FilePath(), request,
+ std::move(loader), client.PassInterface(),
+ DirectoryLoadingPolicy::kFail,
+ FileAccessPolicy::kUnrestricted,
+ LinkFollowingPolicy::kDoNotFollow));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/file_url_loader_factory.h b/chromium/content/browser/file_url_loader_factory.h
new file mode 100644
index 00000000000..cf511c339c7
--- /dev/null
+++ b/chromium/content/browser/file_url_loader_factory.h
@@ -0,0 +1,49 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_FILE_URL_LOADER_FACTORY_H_
+#define CONTENT_BROWSER_FILE_URL_LOADER_FACTORY_H_
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
+#include "content/common/content_export.h"
+#include "content/public/common/url_loader_factory.mojom.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+
+namespace content {
+
+// A URLLoaderFactory used for the file:// scheme used when Network Service is
+// enabled.
+class CONTENT_EXPORT FileURLLoaderFactory : public 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.
+ FileURLLoaderFactory(const base::FilePath& profile_path,
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
+ ~FileURLLoaderFactory() override;
+
+ private:
+ // mojom::URLLoaderFactory:
+ void CreateLoaderAndStart(mojom::URLLoaderRequest loader,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const ResourceRequest& request,
+ mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag&
+ traffic_annotation) override;
+ void Clone(mojom::URLLoaderFactoryRequest loader) override;
+
+ const base::FilePath profile_path_;
+ const scoped_refptr<base::SequencedTaskRunner> task_runner_;
+ mojo::BindingSet<mojom::URLLoaderFactory> bindings_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileURLLoaderFactory);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_FILE_URL_LOADER_FACTORY_H_
diff --git a/chromium/content/browser/fileapi/DEPS b/chromium/content/browser/fileapi/DEPS
index 9d10bbaf469..87b83c0917d 100644
--- a/chromium/content/browser/fileapi/DEPS
+++ b/chromium/content/browser/fileapi/DEPS
@@ -1,6 +1,3 @@
include_rules = [
"+third_party/leveldatabase/src/include/leveldb",
-
- # TODO(pilgrim) jsbell says this smells funny
- "+third_party/leveldatabase/src/db/filename.h",
]
diff --git a/chromium/content/browser/fileapi/OWNERS b/chromium/content/browser/fileapi/OWNERS
index bd016af34e0..c72d620620e 100644
--- a/chromium/content/browser/fileapi/OWNERS
+++ b/chromium/content/browser/fileapi/OWNERS
@@ -1,4 +1,6 @@
+jsbell@chromium.org
michaeln@chromium.org
+pwnall@chromium.org
jianli@chromium.org
tzik@chromium.org
nhiroki@chromium.org
diff --git a/chromium/content/browser/fileapi/browser_file_system_helper.cc b/chromium/content/browser/fileapi/browser_file_system_helper.cc
index 23f303a4ff4..fb3533d5bca 100644
--- a/chromium/content/browser/fileapi/browser_file_system_helper.cc
+++ b/chromium/content/browser/fileapi/browser_file_system_helper.cc
@@ -61,7 +61,7 @@ FileSystemOptions CreateBrowserFileSystemOptions(bool is_incognito) {
switches::kAllowFileAccessFromFiles)) {
additional_allowed_schemes.push_back(url::kFileScheme);
}
- return FileSystemOptions(profile_mode, additional_allowed_schemes, NULL);
+ return FileSystemOptions(profile_mode, additional_allowed_schemes, nullptr);
}
} // namespace
@@ -110,7 +110,7 @@ bool FileSystemURLIsValid(storage::FileSystemContext* context,
if (!url.is_valid())
return false;
- return context->GetFileSystemBackend(url.type()) != NULL;
+ return context->GetFileSystemBackend(url.type()) != nullptr;
}
void SyncGetPlatformPath(storage::FileSystemContext* context,
diff --git a/chromium/content/browser/fileapi/file_system_operation_runner_unittest.cc b/chromium/content/browser/fileapi/file_system_operation_runner_unittest.cc
index 9f654ef775e..fd4444df480 100644
--- a/chromium/content/browser/fileapi/file_system_operation_runner_unittest.cc
+++ b/chromium/content/browser/fileapi/file_system_operation_runner_unittest.cc
@@ -187,7 +187,6 @@ class MultiThreadFileSystemOperationRunnerTest : public testing::Test {
public:
MultiThreadFileSystemOperationRunnerTest()
: thread_bundle_(
- content::TestBrowserThreadBundle::REAL_FILE_THREAD |
content::TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
diff --git a/chromium/content/browser/fileapi/fileapi_message_filter.cc b/chromium/content/browser/fileapi/fileapi_message_filter.cc
index cb152ccfc97..f2727575f83 100644
--- a/chromium/content/browser/fileapi/fileapi_message_filter.cc
+++ b/chromium/content/browser/fileapi/fileapi_message_filter.cc
@@ -54,7 +54,8 @@ namespace content {
namespace {
-const uint32_t kFilteredMessageClasses[] = {FileSystemMsgStart, BlobMsgStart};
+const uint32_t kFileApiFilteredMessageClasses[] = {FileSystemMsgStart,
+ BlobMsgStart};
void RevokeFilePermission(int child_id, const base::FilePath& path) {
ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile(
@@ -68,13 +69,13 @@ FileAPIMessageFilter::FileAPIMessageFilter(
net::URLRequestContextGetter* request_context_getter,
storage::FileSystemContext* file_system_context,
ChromeBlobStorageContext* blob_storage_context)
- : BrowserMessageFilter(kFilteredMessageClasses,
- arraysize(kFilteredMessageClasses)),
+ : BrowserMessageFilter(kFileApiFilteredMessageClasses,
+ arraysize(kFileApiFilteredMessageClasses)),
process_id_(process_id),
context_(file_system_context),
security_policy_(ChildProcessSecurityPolicyImpl::GetInstance()),
request_context_getter_(request_context_getter),
- request_context_(NULL),
+ request_context_(nullptr),
blob_storage_context_(blob_storage_context) {
DCHECK(context_);
DCHECK(request_context_getter_.get());
@@ -86,8 +87,8 @@ FileAPIMessageFilter::FileAPIMessageFilter(
net::URLRequestContext* request_context,
storage::FileSystemContext* file_system_context,
ChromeBlobStorageContext* blob_storage_context)
- : BrowserMessageFilter(kFilteredMessageClasses,
- arraysize(kFilteredMessageClasses)),
+ : BrowserMessageFilter(kFileApiFilteredMessageClasses,
+ arraysize(kFileApiFilteredMessageClasses)),
process_id_(process_id),
context_(file_system_context),
security_policy_(ChildProcessSecurityPolicyImpl::GetInstance()),
@@ -104,7 +105,7 @@ void FileAPIMessageFilter::OnChannelConnected(int32_t peer_pid) {
if (request_context_getter_.get()) {
DCHECK(!request_context_);
request_context_ = request_context_getter_->GetURLRequestContext();
- request_context_getter_ = NULL;
+ request_context_getter_ = nullptr;
DCHECK(request_context_);
}
@@ -124,7 +125,7 @@ base::TaskRunner* FileAPIMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& message) {
if (message.type() == FileSystemHostMsg_SyncGetPlatformPath::ID)
return context_->default_file_task_runner();
- return NULL;
+ return nullptr;
}
bool FileAPIMessageFilter::OnMessageReceived(const IPC::Message& message) {
diff --git a/chromium/content/browser/fileapi/fileapi_message_filter_unittest.cc b/chromium/content/browser/fileapi/fileapi_message_filter_unittest.cc
index 18eef3b3cab..0c6ee255bfe 100644
--- a/chromium/content/browser/fileapi/fileapi_message_filter_unittest.cc
+++ b/chromium/content/browser/fileapi/fileapi_message_filter_unittest.cc
@@ -43,7 +43,7 @@ class FileAPIMessageFilterTest : public testing::Test {
protected:
void SetUp() override {
file_system_context_ =
- CreateFileSystemContextForTesting(NULL, base::FilePath());
+ CreateFileSystemContextForTesting(nullptr, base::FilePath());
std::vector<storage::FileSystemType> types;
file_system_context_->GetFileSystemTypes(&types);
diff --git a/chromium/content/browser/fileapi/upload_file_system_file_element_reader.cc b/chromium/content/browser/fileapi/upload_file_system_file_element_reader.cc
deleted file mode 100644
index 1951b94c12b..00000000000
--- a/chromium/content/browser/fileapi/upload_file_system_file_element_reader.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/fileapi/upload_file_system_file_element_reader.h"
-
-#include <algorithm>
-#include <limits>
-
-#include "base/bind.h"
-#include "base/numerics/safe_conversions.h"
-#include "net/base/net_errors.h"
-#include "storage/browser/fileapi/file_stream_reader.h"
-#include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/fileapi/file_system_url.h"
-
-namespace content {
-
-UploadFileSystemFileElementReader::UploadFileSystemFileElementReader(
- storage::FileSystemContext* file_system_context,
- const GURL& url,
- uint64_t range_offset,
- uint64_t range_length,
- const base::Time& expected_modification_time)
- : file_system_context_(file_system_context),
- url_(url),
- range_offset_(range_offset),
- range_length_(range_length),
- expected_modification_time_(expected_modification_time),
- stream_length_(0),
- position_(0),
- weak_ptr_factory_(this) {}
-
-UploadFileSystemFileElementReader::~UploadFileSystemFileElementReader() {
-}
-
-int UploadFileSystemFileElementReader::Init(
- const net::CompletionCallback& callback) {
- // Reset states.
- weak_ptr_factory_.InvalidateWeakPtrs();
- stream_length_ = 0;
- position_ = 0;
-
- // Initialize the stream reader and the length.
- stream_reader_ = file_system_context_->CreateFileStreamReader(
- file_system_context_->CrackURL(url_), range_offset_,
- range_length_ == std::numeric_limits<uint64_t>::max()
- ? storage::kMaximumLength
- : base::checked_cast<int64_t>(range_length_),
- expected_modification_time_);
- DCHECK(stream_reader_);
-
- const int64_t result = stream_reader_->GetLength(
- base::Bind(&UploadFileSystemFileElementReader::OnGetLength,
- weak_ptr_factory_.GetWeakPtr(), callback));
- if (result >= 0) {
- stream_length_ = result;
- return net::OK;
- }
-
- // The error code can be casted to int.
- return static_cast<int>(result);
-}
-
-uint64_t UploadFileSystemFileElementReader::GetContentLength() const {
- return std::min(stream_length_, range_length_);
-}
-
-uint64_t UploadFileSystemFileElementReader::BytesRemaining() const {
- return GetContentLength() - position_;
-}
-
-int UploadFileSystemFileElementReader::Read(
- net::IOBuffer* buf,
- int buf_length,
- const net::CompletionCallback& callback) {
- DCHECK_LT(0, buf_length);
- DCHECK(stream_reader_);
-
- const uint64_t num_bytes_to_read =
- std::min(BytesRemaining(), static_cast<uint64_t>(buf_length));
-
- if (num_bytes_to_read == 0)
- return 0;
-
- const int result = stream_reader_->Read(
- buf, num_bytes_to_read,
- base::Bind(&UploadFileSystemFileElementReader::OnRead,
- weak_ptr_factory_.GetWeakPtr(),
- callback));
- if (result >= 0)
- OnRead(net::CompletionCallback(), result);
- return result;
-}
-
-void UploadFileSystemFileElementReader::OnGetLength(
- const net::CompletionCallback& callback,
- int64_t result) {
- if (result >= 0) {
- stream_length_ = result;
- callback.Run(net::OK);
- return;
- }
- callback.Run(result);
-}
-
-void UploadFileSystemFileElementReader::OnRead(
- const net::CompletionCallback& callback,
- int result) {
- if (result > 0) {
- position_ += result;
- DCHECK_LE(position_, GetContentLength());
- }
- if (!callback.is_null())
- callback.Run(result);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/fileapi/upload_file_system_file_element_reader.h b/chromium/content/browser/fileapi/upload_file_system_file_element_reader.h
deleted file mode 100644
index be6e313da3f..00000000000
--- a/chromium/content/browser/fileapi/upload_file_system_file_element_reader.h
+++ /dev/null
@@ -1,71 +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_BROWSER_FILEAPI_UPLOAD_FILE_SYSTEM_FILE_ELEMENT_READER_H_
-#define CONTENT_BROWSER_FILEAPI_UPLOAD_FILE_SYSTEM_FILE_ELEMENT_READER_H_
-
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
-#include "content/common/content_export.h"
-#include "net/base/upload_element_reader.h"
-#include "url/gurl.h"
-
-namespace storage {
-class FileStreamReader;
-}
-
-namespace storage {
-class FileSystemContext;
-}
-
-namespace content {
-
-// An UploadElementReader implementation for filesystem file.
-class CONTENT_EXPORT UploadFileSystemFileElementReader
- : public net::UploadElementReader {
- public:
- UploadFileSystemFileElementReader(
- storage::FileSystemContext* file_system_context,
- const GURL& url,
- uint64_t range_offset,
- uint64_t range_length,
- const base::Time& expected_modification_time);
- ~UploadFileSystemFileElementReader() override;
-
- // UploadElementReader overrides:
- int Init(const net::CompletionCallback& callback) override;
- uint64_t GetContentLength() const override;
- uint64_t BytesRemaining() const override;
- int Read(net::IOBuffer* buf,
- int buf_length,
- const net::CompletionCallback& callback) override;
-
- private:
- void OnGetLength(const net::CompletionCallback& callback, int64_t result);
- void OnRead(const net::CompletionCallback& callback, int result);
-
- scoped_refptr<storage::FileSystemContext> file_system_context_;
- const GURL url_;
- const uint64_t range_offset_;
- const uint64_t range_length_;
- const base::Time expected_modification_time_;
-
- std::unique_ptr<storage::FileStreamReader> stream_reader_;
-
- uint64_t stream_length_;
- uint64_t position_;
-
- base::WeakPtrFactory<UploadFileSystemFileElementReader> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(UploadFileSystemFileElementReader);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_FILEAPI_UPLOAD_FILE_SYSTEM_FILE_ELEMENT_READER_H_
diff --git a/chromium/content/browser/fileapi/upload_file_system_file_element_reader_unittest.cc b/chromium/content/browser/fileapi/upload_file_system_file_element_reader_unittest.cc
deleted file mode 100644
index d248c036bfe..00000000000
--- a/chromium/content/browser/fileapi/upload_file_system_file_element_reader_unittest.cc
+++ /dev/null
@@ -1,283 +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/fileapi/upload_file_system_file_element_reader.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <limits>
-
-#include "base/files/scoped_temp_dir.h"
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "net/base/io_buffer.h"
-#include "net/base/test_completion_callback.h"
-#include "storage/browser/fileapi/file_system_backend.h"
-#include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/fileapi/file_system_operation_context.h"
-#include "storage/browser/fileapi/file_system_url.h"
-#include "storage/browser/test/async_file_test_helper.h"
-#include "storage/browser/test/test_file_system_context.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using content::AsyncFileTestHelper;
-using storage::FileSystemContext;
-using storage::FileSystemType;
-using storage::FileSystemURL;
-
-namespace content {
-
-namespace {
-
-const char kFileSystemURLOrigin[] = "http://remote";
-const storage::FileSystemType kFileSystemType =
- storage::kFileSystemTypeTemporary;
-
-} // namespace
-
-class UploadFileSystemFileElementReaderTest : public testing::Test {
- public:
- UploadFileSystemFileElementReaderTest() {}
-
- void SetUp() override {
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
- file_system_context_ =
- CreateFileSystemContextForTesting(NULL, temp_dir_.GetPath());
-
- file_system_context_->OpenFileSystem(
- GURL(kFileSystemURLOrigin), kFileSystemType,
- storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
- base::BindOnce(&UploadFileSystemFileElementReaderTest::OnOpenFileSystem,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
- ASSERT_TRUE(file_system_root_url_.is_valid());
-
- // Prepare a file on file system.
- const char kTestData[] = "abcdefghijklmnop0123456789";
- file_data_.assign(kTestData, kTestData + arraysize(kTestData) - 1);
- const char kFilename[] = "File.dat";
- file_url_ = GetFileSystemURL(kFilename);
- WriteFileSystemFile(kFilename, &file_data_[0], file_data_.size(),
- &file_modification_time_);
-
- // Create and initialize a reader.
- reader_.reset(new UploadFileSystemFileElementReader(
- file_system_context_.get(), file_url_, 0,
- std::numeric_limits<uint64_t>::max(), file_modification_time_));
- net::TestCompletionCallback callback;
- ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(callback.callback()));
- EXPECT_EQ(net::OK, callback.WaitForResult());
- EXPECT_EQ(file_data_.size(), reader_->GetContentLength());
- EXPECT_EQ(file_data_.size(), reader_->BytesRemaining());
- EXPECT_FALSE(reader_->IsInMemory());
- }
-
- void TearDown() override {
- reader_.reset();
- base::RunLoop().RunUntilIdle();
- }
-
- protected:
- GURL GetFileSystemURL(const std::string& filename) {
- return GURL(file_system_root_url_.spec() + filename);
- }
-
- void WriteFileSystemFile(const std::string& filename,
- const char* buf,
- int buf_size,
- base::Time* modification_time) {
- storage::FileSystemURL url =
- file_system_context_->CreateCrackedFileSystemURL(
- GURL(kFileSystemURLOrigin),
- kFileSystemType,
- base::FilePath().AppendASCII(filename));
-
- ASSERT_EQ(base::File::FILE_OK,
- AsyncFileTestHelper::CreateFileWithData(
- file_system_context_.get(), url, buf, buf_size));
-
- base::File::Info file_info;
- ASSERT_EQ(base::File::FILE_OK,
- AsyncFileTestHelper::GetMetadata(
- file_system_context_.get(), url, &file_info));
- *modification_time = file_info.last_modified;
- }
-
- void OnOpenFileSystem(const GURL& root,
- const std::string& name,
- base::File::Error result) {
- ASSERT_EQ(base::File::FILE_OK, result);
- ASSERT_TRUE(root.is_valid());
- file_system_root_url_ = root;
- }
-
- base::MessageLoopForIO message_loop_;
- base::ScopedTempDir temp_dir_;
- scoped_refptr<FileSystemContext> file_system_context_;
- GURL file_system_root_url_;
- std::vector<char> file_data_;
- GURL file_url_;
- base::Time file_modification_time_;
- std::unique_ptr<UploadFileSystemFileElementReader> reader_;
-};
-
-TEST_F(UploadFileSystemFileElementReaderTest, ReadAll) {
- scoped_refptr<net::IOBufferWithSize> buf =
- new net::IOBufferWithSize(file_data_.size());
- net::TestCompletionCallback read_callback;
- ASSERT_EQ(net::ERR_IO_PENDING,
- reader_->Read(buf.get(), buf->size(), read_callback.callback()));
- EXPECT_EQ(buf->size(), read_callback.WaitForResult());
- EXPECT_EQ(0U, reader_->BytesRemaining());
- EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data()));
- // Try to read again.
- EXPECT_EQ(0, reader_->Read(buf.get(), buf->size(), read_callback.callback()));
-}
-
-TEST_F(UploadFileSystemFileElementReaderTest, ReadPartially) {
- const size_t kHalfSize = file_data_.size() / 2;
- ASSERT_EQ(file_data_.size(), kHalfSize * 2);
-
- scoped_refptr<net::IOBufferWithSize> buf =
- new net::IOBufferWithSize(kHalfSize);
-
- net::TestCompletionCallback read_callback1;
- ASSERT_EQ(net::ERR_IO_PENDING,
- reader_->Read(buf.get(), buf->size(), read_callback1.callback()));
- EXPECT_EQ(buf->size(), read_callback1.WaitForResult());
- EXPECT_EQ(file_data_.size() - buf->size(), reader_->BytesRemaining());
- EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.begin() + kHalfSize,
- buf->data()));
-
- net::TestCompletionCallback read_callback2;
- EXPECT_EQ(net::ERR_IO_PENDING,
- reader_->Read(buf.get(), buf->size(), read_callback2.callback()));
- EXPECT_EQ(buf->size(), read_callback2.WaitForResult());
- EXPECT_EQ(0U, reader_->BytesRemaining());
- EXPECT_TRUE(std::equal(file_data_.begin() + kHalfSize, file_data_.end(),
- buf->data()));
-}
-
-TEST_F(UploadFileSystemFileElementReaderTest, ReadTooMuch) {
- const size_t kTooLargeSize = file_data_.size() * 2;
- scoped_refptr<net::IOBufferWithSize> buf =
- new net::IOBufferWithSize(kTooLargeSize);
- net::TestCompletionCallback read_callback;
- ASSERT_EQ(net::ERR_IO_PENDING,
- reader_->Read(buf.get(), buf->size(), read_callback.callback()));
- EXPECT_EQ(static_cast<int>(file_data_.size()), read_callback.WaitForResult());
- EXPECT_EQ(0U, reader_->BytesRemaining());
- EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data()));
-}
-
-TEST_F(UploadFileSystemFileElementReaderTest, MultipleInit) {
- scoped_refptr<net::IOBufferWithSize> buf =
- new net::IOBufferWithSize(file_data_.size());
-
- // Read all.
- net::TestCompletionCallback read_callback1;
- ASSERT_EQ(net::ERR_IO_PENDING,
- reader_->Read(buf.get(), buf->size(), read_callback1.callback()));
- EXPECT_EQ(buf->size(), read_callback1.WaitForResult());
- EXPECT_EQ(0U, reader_->BytesRemaining());
- EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data()));
-
- // Call Init() again to reset the state.
- net::TestCompletionCallback init_callback;
- ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback()));
- EXPECT_EQ(net::OK, init_callback.WaitForResult());
- EXPECT_EQ(file_data_.size(), reader_->GetContentLength());
- EXPECT_EQ(file_data_.size(), reader_->BytesRemaining());
-
- // Read again.
- net::TestCompletionCallback read_callback2;
- ASSERT_EQ(net::ERR_IO_PENDING,
- reader_->Read(buf.get(), buf->size(), read_callback2.callback()));
- EXPECT_EQ(buf->size(), read_callback2.WaitForResult());
- EXPECT_EQ(0U, reader_->BytesRemaining());
- EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data()));
-}
-
-TEST_F(UploadFileSystemFileElementReaderTest, InitDuringAsyncOperation) {
- scoped_refptr<net::IOBufferWithSize> buf =
- new net::IOBufferWithSize(file_data_.size());
-
- // Start reading all.
- net::TestCompletionCallback read_callback1;
- EXPECT_EQ(net::ERR_IO_PENDING,
- reader_->Read(buf.get(), buf->size(), read_callback1.callback()));
-
- // Call Init to cancel the previous read.
- net::TestCompletionCallback init_callback1;
- EXPECT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback1.callback()));
-
- // Call Init again to cancel the previous init.
- net::TestCompletionCallback init_callback2;
- EXPECT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback2.callback()));
- EXPECT_EQ(net::OK, init_callback2.WaitForResult());
- EXPECT_EQ(file_data_.size(), reader_->GetContentLength());
- EXPECT_EQ(file_data_.size(), reader_->BytesRemaining());
-
- // Read half.
- scoped_refptr<net::IOBufferWithSize> buf2 =
- new net::IOBufferWithSize(file_data_.size() / 2);
- net::TestCompletionCallback read_callback2;
- EXPECT_EQ(net::ERR_IO_PENDING,
- reader_->Read(buf2.get(), buf2->size(), read_callback2.callback()));
- EXPECT_EQ(buf2->size(), read_callback2.WaitForResult());
- EXPECT_EQ(file_data_.size() - buf2->size(), reader_->BytesRemaining());
- EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.begin() + buf2->size(),
- buf2->data()));
-
- // Make sure callbacks are not called for cancelled operations.
- EXPECT_FALSE(read_callback1.have_result());
- EXPECT_FALSE(init_callback1.have_result());
-}
-
-TEST_F(UploadFileSystemFileElementReaderTest, Range) {
- const int kOffset = 2;
- const int kLength = file_data_.size() - kOffset * 3;
- reader_.reset(new UploadFileSystemFileElementReader(
- file_system_context_.get(), file_url_, kOffset, kLength, base::Time()));
- net::TestCompletionCallback init_callback;
- ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback()));
- EXPECT_EQ(net::OK, init_callback.WaitForResult());
- EXPECT_EQ(static_cast<uint64_t>(kLength), reader_->GetContentLength());
- EXPECT_EQ(static_cast<uint64_t>(kLength), reader_->BytesRemaining());
- scoped_refptr<net::IOBufferWithSize> buf = new net::IOBufferWithSize(kLength);
- net::TestCompletionCallback read_callback;
- ASSERT_EQ(net::ERR_IO_PENDING,
- reader_->Read(buf.get(), buf->size(), read_callback.callback()));
- EXPECT_EQ(kLength, read_callback.WaitForResult());
- EXPECT_TRUE(std::equal(file_data_.begin() + kOffset,
- file_data_.begin() + kOffset + kLength,
- buf->data()));
-}
-
-TEST_F(UploadFileSystemFileElementReaderTest, FileChanged) {
- // Expect one second before the actual modification time to simulate change.
- const base::Time expected_modification_time =
- file_modification_time_ - base::TimeDelta::FromSeconds(1);
- reader_.reset(new UploadFileSystemFileElementReader(
- file_system_context_.get(), file_url_, 0,
- std::numeric_limits<uint64_t>::max(), expected_modification_time));
- net::TestCompletionCallback init_callback;
- ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback()));
- EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, init_callback.WaitForResult());
-}
-
-TEST_F(UploadFileSystemFileElementReaderTest, WrongURL) {
- const GURL wrong_url = GetFileSystemURL("wrong_file_name.dat");
- reader_.reset(new UploadFileSystemFileElementReader(
- file_system_context_.get(), wrong_url, 0,
- std::numeric_limits<uint64_t>::max(), base::Time()));
- net::TestCompletionCallback init_callback;
- ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback()));
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, init_callback.WaitForResult());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/find_request_manager.cc b/chromium/content/browser/find_request_manager.cc
index f224f709bb1..b38fc35cc14 100644
--- a/chromium/content/browser/find_request_manager.cc
+++ b/chromium/content/browser/find_request_manager.cc
@@ -563,7 +563,7 @@ void FindRequestManager::FindInternal(const FindRequest& request) {
// This is an initial find operation.
Reset(request);
for (WebContentsImpl* contents : contents_->GetWebContentsAndAllInner()) {
- frame_observers_.push_back(base::MakeUnique<FrameObserver>(contents, this));
+ frame_observers_.push_back(std::make_unique<FrameObserver>(contents, this));
for (FrameTreeNode* node : contents->GetFrameTree()->Nodes()) {
AddFrame(node->current_frame_host(), false /* force */);
}
diff --git a/chromium/content/browser/find_request_manager_browsertest.cc b/chromium/content/browser/find_request_manager_browsertest.cc
index 33ef82557d9..3476548135e 100644
--- a/chromium/content/browser/find_request_manager_browsertest.cc
+++ b/chromium/content/browser/find_request_manager_browsertest.cc
@@ -4,6 +4,7 @@
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/notification_types.h"
#include "content/public/common/content_switches.h"
@@ -445,7 +446,15 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(FindNewMatches)) {
EXPECT_EQ(4, results.active_match_ordinal);
}
-IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(FindInPage_Issue627799)) {
+// TODO(crbug.com/615291): These tests frequently fail on Android.
+// TODO(crbug.com/779912): Flaky timeout on Win7 (dbg).
+#if defined(OS_ANDROID) || (defined(OS_WIN) && !defined(NDEBUG))
+#define MAYBE_FindInPage_Issue627799 DISABLED_FindInPage_Issue627799
+#else
+#define MAYBE_FindInPage_Issue627799 FindInPage_Issue627799
+#endif
+
+IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE_FindInPage_Issue627799) {
LoadAndWait("/find_in_long_page.html");
blink::WebFindOptions options;
diff --git a/chromium/content/browser/frame_host/ancestor_throttle.cc b/chromium/content/browser/frame_host/ancestor_throttle.cc
index db6ac057b52..86f1df5ad43 100644
--- a/chromium/content/browser/frame_host/ancestor_throttle.cc
+++ b/chromium/content/browser/frame_host/ancestor_throttle.cc
@@ -134,7 +134,8 @@ AncestorThrottle::WillProcessResponse() {
case HeaderDisposition::SAMEORIGIN: {
// Block the request when any ancestor is not same-origin.
FrameTreeNode* parent = handle->frame_tree_node()->parent();
- url::Origin current_origin(navigation_handle()->GetURL());
+ url::Origin current_origin =
+ url::Origin::Create(navigation_handle()->GetURL());
while (parent) {
if (!parent->current_origin().IsSameOriginWith(current_origin)) {
RecordXFrameOptionsUsage(SAMEORIGIN_BLOCKED);
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 b36d503fc10..177e00c4a80 100644
--- a/chromium/content/browser/frame_host/cross_process_frame_connector.cc
+++ b/chromium/content/browser/frame_host/cross_process_frame_connector.cc
@@ -8,6 +8,7 @@
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "components/viz/service/surfaces/surface.h"
#include "components/viz/service/surfaces/surface_hittest.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"
@@ -20,7 +21,9 @@
#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/renderer_host/render_widget_host_view_child_frame.h"
+#include "content/common/content_switches_internal.h"
#include "content/common/frame_messages.h"
+#include "content/public/common/screen_info.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "ui/gfx/geometry/dip_util.h"
@@ -29,7 +32,8 @@ namespace content {
CrossProcessFrameConnector::CrossProcessFrameConnector(
RenderFrameProxyHost* frame_proxy_in_parent_renderer)
- : frame_proxy_in_parent_renderer_(frame_proxy_in_parent_renderer),
+ : FrameConnectorDelegate(IsUseZoomForDSFEnabled()),
+ frame_proxy_in_parent_renderer_(frame_proxy_in_parent_renderer),
view_(nullptr),
is_scroll_bubbling_(false) {}
@@ -42,11 +46,13 @@ bool CrossProcessFrameConnector::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(CrossProcessFrameConnector, msg)
- IPC_MESSAGE_HANDLER(FrameHostMsg_FrameRectChanged, OnFrameRectChanged)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateResizeParams, OnUpdateResizeParams)
IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateViewportIntersection,
OnUpdateViewportIntersection)
IPC_MESSAGE_HANDLER(FrameHostMsg_VisibilityChanged, OnVisibilityChanged)
IPC_MESSAGE_HANDLER(FrameHostMsg_SetIsInert, OnSetIsInert)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateRenderThrottlingStatus,
+ OnUpdateRenderThrottlingStatus)
IPC_MESSAGE_HANDLER(FrameHostMsg_SatisfySequence, OnSatisfySequence)
IPC_MESSAGE_HANDLER(FrameHostMsg_RequireSequence, OnRequireSequence)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -87,7 +93,6 @@ void CrossProcessFrameConnector::SetView(RenderWidgetHostViewChildFrame* view) {
// try to move these updates to a single IPC (see https://crbug.com/750179).
if (view_) {
view_->SetFrameConnectorDelegate(this);
- SetRect(child_frame_rect_);
if (is_hidden_)
OnVisibilityChanged(false);
frame_proxy_in_parent_renderer_->Send(new FrameMsg_ViewChanged(
@@ -119,10 +124,6 @@ void CrossProcessFrameConnector::OnRequireSequence(
GetFrameSinkManager()->surface_manager()->RequireSequence(id, sequence);
}
-gfx::Rect CrossProcessFrameConnector::ChildFrameRect() {
- return child_frame_rect_;
-}
-
void CrossProcessFrameConnector::UpdateCursor(const WebCursor& cursor) {
RenderWidgetHostViewBase* root_view = GetRootRenderWidgetHostView();
// UpdateCursor messages are ignored if the root view does not support
@@ -131,20 +132,20 @@ void CrossProcessFrameConnector::UpdateCursor(const WebCursor& cursor) {
root_view->GetCursorManager()->UpdateCursor(view_, cursor);
}
-gfx::Point CrossProcessFrameConnector::TransformPointToRootCoordSpace(
- const gfx::Point& point,
+gfx::PointF CrossProcessFrameConnector::TransformPointToRootCoordSpace(
+ const gfx::PointF& point,
const viz::SurfaceId& surface_id) {
- gfx::Point transformed_point;
+ gfx::PointF transformed_point;
TransformPointToCoordSpaceForView(point, GetRootRenderWidgetHostView(),
surface_id, &transformed_point);
return transformed_point;
}
bool CrossProcessFrameConnector::TransformPointToLocalCoordSpace(
- const gfx::Point& point,
+ const gfx::PointF& point,
const viz::SurfaceId& original_surface,
const viz::SurfaceId& local_surface_id,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
if (original_surface == local_surface_id) {
*transformed_point = point;
return true;
@@ -166,10 +167,10 @@ bool CrossProcessFrameConnector::TransformPointToLocalCoordSpace(
}
bool CrossProcessFrameConnector::TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
const viz::SurfaceId& local_surface_id,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
RenderWidgetHostViewBase* root_view = GetRootRenderWidgetHostView();
if (!root_view)
return false;
@@ -214,7 +215,7 @@ void CrossProcessFrameConnector::BubbleScrollEvent(
->delegate()
->GetInputEventRouter();
- gfx::Vector2d offset_from_parent = child_frame_rect_.OffsetFromOrigin();
+ gfx::Vector2d offset_from_parent = frame_rect_in_dip_.OffsetFromOrigin();
blink::WebGestureEvent resent_gesture_event(event);
// TODO(kenrb, wjmaclean): Do we need to account for transforms here?
// See https://crbug.com/626020.
@@ -271,12 +272,43 @@ void CrossProcessFrameConnector::UnlockMouse() {
root_view->UnlockMouse();
}
-void CrossProcessFrameConnector::OnFrameRectChanged(
+void CrossProcessFrameConnector::OnUpdateResizeParams(
const gfx::Rect& frame_rect,
- const viz::LocalSurfaceId& local_surface_id) {
- local_surface_id_ = local_surface_id;
- if (!frame_rect.size().IsEmpty())
- SetRect(frame_rect);
+ const ScreenInfo& screen_info,
+ uint64_t sequence_number,
+ const viz::SurfaceId& surface_id) {
+ // If the |frame_rect| or |screen_info| of the frame has changed, then the
+ // viz::LocalSurfaceId must also change.
+ if ((last_received_frame_rect_.size() != frame_rect.size() ||
+ screen_info_ != screen_info) &&
+ local_surface_id_ == surface_id.local_surface_id()) {
+ bad_message::ReceivedBadMessage(
+ frame_proxy_in_parent_renderer_->GetProcess(),
+ bad_message::CPFC_RESIZE_PARAMS_CHANGED_LOCAL_SURFACE_ID_UNCHANGED);
+ return;
+ }
+
+ screen_info_ = screen_info;
+ last_received_frame_rect_ = frame_rect;
+ local_surface_id_ = surface_id.local_surface_id();
+ SetRect(frame_rect);
+
+ if (!view_)
+ return;
+#if defined(USE_AURA)
+ view_->SetFrameSinkId(surface_id.frame_sink_id());
+#endif // defined(USE_AURA)
+
+ RenderWidgetHostImpl* render_widget_host =
+ RenderWidgetHostImpl::From(view_->GetRenderWidgetHost());
+ DCHECK(render_widget_host);
+
+ if (render_widget_host->auto_resize_enabled()) {
+ render_widget_host->DidAllocateLocalSurfaceIdForAutoResize(sequence_number);
+ return;
+ }
+
+ render_widget_host->WasResized();
}
void CrossProcessFrameConnector::OnUpdateViewportIntersection(
@@ -320,28 +352,6 @@ void CrossProcessFrameConnector::OnSetIsInert(bool inert) {
view_->SetIsInert();
}
-void CrossProcessFrameConnector::SetRect(const gfx::Rect& frame_rect) {
- gfx::Rect old_rect = child_frame_rect_;
- child_frame_rect_ = frame_rect;
- if (view_) {
- view_->SetBounds(frame_rect);
-
- // Other local root frames nested underneath this one implicitly have their
- // view rects changed when their ancestor is repositioned, and therefore
- // need to have their screen rects updated.
- FrameTreeNode* proxy_node =
- frame_proxy_in_parent_renderer_->frame_tree_node();
- if (old_rect.x() != child_frame_rect_.x() ||
- old_rect.y() != child_frame_rect_.y()) {
- for (FrameTreeNode* node :
- proxy_node->frame_tree()->SubtreeNodes(proxy_node)) {
- if (node != proxy_node && node->current_frame_host()->is_local_root())
- node->current_frame_host()->GetRenderWidgetHost()->SendScreenRects();
- }
- }
- }
-}
-
RenderWidgetHostViewBase*
CrossProcessFrameConnector::GetRootRenderWidgetHostView() {
// Tests may not have frame_proxy_in_parent_renderer_ set.
@@ -408,6 +418,13 @@ void CrossProcessFrameConnector::EmbedRendererWindowTreeClientInParent(
}
#endif
+void CrossProcessFrameConnector::ResizeDueToAutoResize(
+ const gfx::Size& new_size,
+ uint64_t sequence_number) {
+ frame_proxy_in_parent_renderer_->Send(new FrameMsg_ResizeDueToAutoResize(
+ frame_proxy_in_parent_renderer_->GetRoutingID(), sequence_number));
+}
+
void CrossProcessFrameConnector::SetVisibilityForChildViews(
bool visible) const {
frame_proxy_in_parent_renderer_->frame_tree_node()
@@ -415,9 +432,54 @@ void CrossProcessFrameConnector::SetVisibilityForChildViews(
->SetVisibilityForChildViews(visible);
}
+void CrossProcessFrameConnector::SetRect(
+ const gfx::Rect& frame_rect_in_pixels) {
+ gfx::Rect old_rect = frame_rect_in_pixels_;
+ FrameConnectorDelegate::SetRect(frame_rect_in_pixels);
+
+ if (view_) {
+ view_->SetBounds(frame_rect_in_dip_);
+
+ // Other local root frames nested underneath this one implicitly have their
+ // view rects changed when their ancestor is repositioned, and therefore
+ // need to have their screen rects updated.
+ FrameTreeNode* proxy_node =
+ frame_proxy_in_parent_renderer_->frame_tree_node();
+ if (old_rect.x() != frame_rect_in_pixels_.x() ||
+ old_rect.y() != frame_rect_in_pixels_.y()) {
+ for (FrameTreeNode* node :
+ proxy_node->frame_tree()->SubtreeNodes(proxy_node)) {
+ if (node != proxy_node && node->current_frame_host()->is_local_root())
+ node->current_frame_host()->GetRenderWidgetHost()->SendScreenRects();
+ }
+ }
+ }
+}
+
void CrossProcessFrameConnector::ResetFrameRect() {
local_surface_id_ = viz::LocalSurfaceId();
- child_frame_rect_ = gfx::Rect();
+ frame_rect_in_pixels_ = gfx::Rect();
+ frame_rect_in_dip_ = gfx::Rect();
+}
+
+void CrossProcessFrameConnector::OnUpdateRenderThrottlingStatus(
+ bool is_throttled,
+ bool subtree_throttled) {
+ if (is_throttled != is_throttled_ ||
+ subtree_throttled != subtree_throttled_) {
+ is_throttled_ = is_throttled;
+ subtree_throttled_ = subtree_throttled;
+ if (view_)
+ view_->UpdateRenderThrottlingStatus();
+ }
+}
+
+bool CrossProcessFrameConnector::IsThrottled() const {
+ return is_throttled_;
+}
+
+bool CrossProcessFrameConnector::IsSubtreeThrottled() const {
+ return subtree_throttled_;
}
} // namespace content
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 83ce854fe1c..9add9fc2534 100644
--- a/chromium/content/browser/frame_host/cross_process_frame_connector.h
+++ b/chromium/content/browser/frame_host/cross_process_frame_connector.h
@@ -9,6 +9,7 @@
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/surfaces/local_surface_id.h"
+#include "components/viz/common/surfaces/surface_id.h"
#include "content/browser/renderer_host/frame_connector_delegate.h"
#include "content/common/content_export.h"
@@ -18,6 +19,7 @@ class Message;
namespace content {
class RenderFrameProxyHost;
+struct ScreenInfo;
// CrossProcessFrameConnector provides the platform view abstraction for
// RenderWidgetHostViewChildFrame allowing RWHVChildFrame to remain ignorant
@@ -76,20 +78,19 @@ class CONTENT_EXPORT CrossProcessFrameConnector
void RenderProcessGone() override;
void SetChildFrameSurface(const viz::SurfaceInfo& surface_info,
const viz::SurfaceSequence& sequence) override;
- gfx::Rect ChildFrameRect() override;
void UpdateCursor(const WebCursor& cursor) override;
- gfx::Point TransformPointToRootCoordSpace(
- const gfx::Point& point,
+ gfx::PointF TransformPointToRootCoordSpace(
+ const gfx::PointF& point,
const viz::SurfaceId& surface_id) override;
- bool TransformPointToLocalCoordSpace(const gfx::Point& point,
+ bool TransformPointToLocalCoordSpace(const gfx::PointF& point,
const viz::SurfaceId& original_surface,
const viz::SurfaceId& local_surface_id,
- gfx::Point* transformed_point) override;
+ gfx::PointF* transformed_point) override;
bool TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
const viz::SurfaceId& local_surface_id,
- gfx::Point* transformed_point) override;
+ gfx::PointF* transformed_point) override;
void ForwardProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) override;
void BubbleScrollEvent(const blink::WebGestureEvent& event) override;
@@ -99,15 +100,21 @@ class CONTENT_EXPORT CrossProcessFrameConnector
void UnlockMouse() override;
bool IsInert() const override;
bool IsHidden() const override;
+ bool IsThrottled() const override;
+ bool IsSubtreeThrottled() const override;
#if defined(USE_AURA)
void EmbedRendererWindowTreeClientInParent(
ui::mojom::WindowTreeClientPtr window_tree_client) override;
#endif
+ void ResizeDueToAutoResize(const gfx::Size& new_size,
+ uint64_t sequence_number) override;
// Set the visibility of immediate child views, i.e. views whose parent view
// is |view_|.
void SetVisibilityForChildViews(bool visible) const override;
+ void SetRect(const gfx::Rect& frame_rect_in_pixels) override;
+
// Exposed for tests.
RenderWidgetHostViewBase* GetRootRenderWidgetHostViewForTesting() {
return GetRootRenderWidgetHostView();
@@ -121,17 +128,19 @@ class CONTENT_EXPORT CrossProcessFrameConnector
void ResetFrameRect();
// Handlers for messages received from the parent frame.
- void OnFrameRectChanged(const gfx::Rect& frame_rect,
- const viz::LocalSurfaceId& local_surface_id);
+ void OnUpdateResizeParams(const gfx::Rect& frame_rect,
+ const ScreenInfo& screen_info,
+ uint64_t sequence_number,
+ const viz::SurfaceId& surface_id);
void OnUpdateViewportIntersection(const gfx::Rect& viewport_intersection);
void OnVisibilityChanged(bool visible);
void OnSetIsInert(bool);
+ void OnUpdateRenderThrottlingStatus(bool is_throttled,
+ bool subtree_throttled);
void OnSatisfySequence(const viz::SurfaceSequence& sequence);
void OnRequireSequence(const viz::SurfaceId& id,
const viz::SurfaceSequence& sequence);
- void SetRect(const gfx::Rect& frame_rect);
-
// The RenderFrameProxyHost that routes messages to the parent frame's
// renderer process.
RenderFrameProxyHost* frame_proxy_in_parent_renderer_;
@@ -139,14 +148,22 @@ class CONTENT_EXPORT CrossProcessFrameConnector
// The RenderWidgetHostView for the frame. Initially NULL.
RenderWidgetHostViewChildFrame* view_;
- gfx::Rect child_frame_rect_;
bool is_inert_ = false;
+ bool is_throttled_ = false;
+ bool subtree_throttled_ = false;
+
// Visibility state of the corresponding frame owner element in parent process
// which is set through CSS.
bool is_hidden_ = false;
bool is_scroll_bubbling_;
+
+ // The last frame rect received from the parent renderer.
+ // |last_received_frame_rect_| may be in DIP if use zoom for DSF is off.
+ gfx::Rect last_received_frame_rect_;
+
+ DISALLOW_COPY_AND_ASSIGN(CrossProcessFrameConnector);
};
} // namespace content
diff --git a/chromium/content/browser/frame_host/data_url_navigation_browsertest.cc b/chromium/content/browser/frame_host/data_url_navigation_browsertest.cc
index 036e7910b20..b52a8ec954a 100644
--- a/chromium/content/browser/frame_host/data_url_navigation_browsertest.cc
+++ b/chromium/content/browser/frame_host/data_url_navigation_browsertest.cc
@@ -508,13 +508,25 @@ IN_PROC_BROWSER_TEST_F(DataUrlNavigationBrowserTest, HTML_Navigation_Block) {
NAVIGATION_BLOCKED);
}
+class DataUrlNavigationBrowserTestWithFeatureFlag
+ : public DataUrlNavigationBrowserTest {
+ public:
+ DataUrlNavigationBrowserTestWithFeatureFlag() {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAllowContentInitiatedDataUrlNavigations);
+ }
+ ~DataUrlNavigationBrowserTestWithFeatureFlag() override {}
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(DataUrlNavigationBrowserTestWithFeatureFlag);
+};
+
// Tests that a content initiated navigation to a data URL is allowed if
// blocking is disabled with a feature flag.
-IN_PROC_BROWSER_TEST_F(DataUrlNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_F(DataUrlNavigationBrowserTestWithFeatureFlag,
HTML_Navigation_Allow_FeatureFlag) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kAllowContentInitiatedDataUrlNavigations);
NavigateToURL(shell(),
embedded_test_server()->GetURL("/data_url_navigations.html"));
ExecuteScriptAndCheckNavigation(
diff --git a/chromium/content/browser/frame_host/data_url_navigation_throttle.cc b/chromium/content/browser/frame_host/data_url_navigation_throttle.cc
index 115629fe0ae..0fd3d9abcdc 100644
--- a/chromium/content/browser/frame_host/data_url_navigation_throttle.cc
+++ b/chromium/content/browser/frame_host/data_url_navigation_throttle.cc
@@ -66,13 +66,13 @@ const char* DataUrlNavigationThrottle::GetNameForLogging() {
std::unique_ptr<NavigationThrottle>
DataUrlNavigationThrottle::CreateThrottleForNavigation(
NavigationHandle* navigation_handle) {
- if (navigation_handle->GetURL().SchemeIs(url::kDataScheme) &&
- navigation_handle->IsInMainFrame() &&
+ if (navigation_handle->IsInMainFrame() &&
navigation_handle->IsRendererInitiated() &&
!navigation_handle->IsSameDocument() &&
+ navigation_handle->GetURL().SchemeIs(url::kDataScheme) &&
!base::FeatureList::IsEnabled(
features::kAllowContentInitiatedDataUrlNavigations)) {
- return base::MakeUnique<DataUrlNavigationThrottle>(navigation_handle);
+ return std::make_unique<DataUrlNavigationThrottle>(navigation_handle);
}
return nullptr;
}
diff --git a/chromium/content/browser/frame_host/debug_urls.cc b/chromium/content/browser/frame_host/debug_urls.cc
index c1764c51128..46954327b9c 100644
--- a/chromium/content/browser/frame_host/debug_urls.cc
+++ b/chromium/content/browser/frame_host/debug_urls.cc
@@ -217,21 +217,4 @@ bool HandleDebugURL(const GURL& url, ui::PageTransition transition) {
return false;
}
-bool IsRendererDebugURL(const GURL& url) {
- if (!url.is_valid())
- return false;
-
- if (url.SchemeIs(url::kJavaScriptScheme))
- return true;
-
- return url == kChromeUICheckCrashURL ||
- url == kChromeUIBadCastCrashURL ||
- url == kChromeUICrashURL ||
- url == kChromeUIDumpURL ||
- url == kChromeUIKillURL ||
- url == kChromeUIHangURL ||
- url == kChromeUIShorthangURL ||
- url == kChromeUIMemoryExhaustURL;
-}
-
} // namespace content
diff --git a/chromium/content/browser/frame_host/debug_urls.h b/chromium/content/browser/frame_host/debug_urls.h
index bab8a6d1d4d..189ac16a4aa 100644
--- a/chromium/content/browser/frame_host/debug_urls.h
+++ b/chromium/content/browser/frame_host/debug_urls.h
@@ -16,12 +16,6 @@ namespace content {
// handles it and returns true.
bool HandleDebugURL(const GURL& url, ui::PageTransition transition);
-// Returns whether the given url is either a debugging url handled in the
-// renderer process, such as one that crashes or hangs the renderer, or a
-// javascript: URL that operates on the current page in the renderer. Such URLs
-// do not represent actual navigations and can be loaded in any SiteInstance.
-CONTENT_EXPORT bool IsRendererDebugURL(const GURL& url);
-
} // namespace content
#endif // CONTENT_BROWSER_FRAME_HOST_DEBUG_URLS_H_
diff --git a/chromium/content/browser/frame_host/form_submission_throttle.cc b/chromium/content/browser/frame_host/form_submission_throttle.cc
index 5a235d8698e..426d66ac5d7 100644
--- a/chromium/content/browser/frame_host/form_submission_throttle.cc
+++ b/chromium/content/browser/frame_host/form_submission_throttle.cc
@@ -50,6 +50,24 @@ const char* FormSubmissionThrottle::GetNameForLogging() {
NavigationThrottle::ThrottleCheckResult
FormSubmissionThrottle::CheckContentSecurityPolicyFormAction(bool is_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
+ // the moment instead. For redirects, the behavior was already broken before
+ // using the browser side checks.
+ // See https://crbug.com/700964 and https://crbug.com/798698.
+ //
+ // In absence of redirects, the target URL is sufficiently verified against
+ // the form-action CSP by the frame that hosts the form element + initiates
+ // form submission + declares the form-action CSP (i.e. the same frame does
+ // all those 4 things). Because in this scenario there are no frame or
+ // renderer boundaries crossed, we don't have to worry about one (potentially
+ // 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)
+ return NavigationThrottle::PROCEED;
+
NavigationHandleImpl* handle =
static_cast<NavigationHandleImpl*>(navigation_handle());
@@ -57,6 +75,10 @@ FormSubmissionThrottle::CheckContentSecurityPolicyFormAction(bool is_redirect) {
return NavigationThrottle::PROCEED;
const GURL& url = handle->GetURL();
+
+ // TODO(arthursonzogni): This is not the right RenderFrameHostImpl. The one
+ // that has initiated the navigation must be used instead.
+ // See https://crbug.com/700964
RenderFrameHostImpl* render_frame =
handle->frame_tree_node()->current_frame_host();
diff --git a/chromium/content/browser/frame_host/form_submission_throttle.h b/chromium/content/browser/frame_host/form_submission_throttle.h
index 631a993220e..9c11df352a5 100644
--- a/chromium/content/browser/frame_host/form_submission_throttle.h
+++ b/chromium/content/browser/frame_host/form_submission_throttle.h
@@ -16,8 +16,12 @@ class NavigationHandle;
// A FormSubmissionThrottle is responsible for enforcing the 'form-action' CSP
// directive, blocking requests which violate them.
-// It is enforcing it only if PlzNavigate is enabled. Blink is still enforcing
-// the 'form-action' directive on the renderer process.
+// The form-action CSP is enforced here only for redirects. Blink is enforcing
+// it for the initial URL.
+// TODO(arthursonzogni): https://crbug.com/663512: Depending on specification
+// clarification, we might be able to delete FormSubmissionThrottle altogether.
+// It will be deleted if the final specification clarifies that form-action
+// should NOT be enforced on redirects.
class CONTENT_EXPORT FormSubmissionThrottle : public NavigationThrottle {
public:
static std::unique_ptr<NavigationThrottle> MaybeCreateThrottleFor(
diff --git a/chromium/content/browser/frame_host/form_submission_throttle_browsertest.cc b/chromium/content/browser/frame_host/form_submission_throttle_browsertest.cc
index 0f876a37778..266765fa6eb 100644
--- a/chromium/content/browser/frame_host/form_submission_throttle_browsertest.cc
+++ b/chromium/content/browser/frame_host/form_submission_throttle_browsertest.cc
@@ -33,7 +33,6 @@ IN_PROC_BROWSER_TEST_F(FormSubmissionBrowserTest,
const struct {
GURL main_page_url;
GURL form_page_url;
- NavigationThrottle::ThrottleAction start_expectation;
NavigationThrottle::ThrottleAction redirect_expectation;
} kTestCases[] = {
// Form submissions is allowed by default when there is no CSP.
@@ -41,7 +40,6 @@ IN_PROC_BROWSER_TEST_F(FormSubmissionBrowserTest,
embedded_test_server()->GetURL(
"/form_submission_throttle/no_csp.html"),
embedded_test_server()->GetURL("/simple_page.html"),
- NavigationThrottle::PROCEED, // start expectation.
NavigationThrottle::PROCEED // redirect expectation.
},
@@ -51,23 +49,8 @@ IN_PROC_BROWSER_TEST_F(FormSubmissionBrowserTest,
embedded_test_server()->GetURL(
"/form_submission_throttle/form_action_none.html"),
embedded_test_server()->GetURL("/simple_page.html"),
- NavigationThrottle::CANCEL, // start expectation.
NavigationThrottle::CANCEL // redirect expectation.
},
-
- // The path of the source-expression is only enforced when there is no
- // redirection. By using this behavior, this test can check a case where
- // the request is canceled in WillStartRequest() but not in
- // WillRedirectRequest().
- // See https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects for
- // details.
- {
- embedded_test_server()->GetURL(
- "/form_submission_throttle/form_action_with_path.html"),
- embedded_test_server()->GetURL("/not_the_file.html"),
- NavigationThrottle::CANCEL, // start expectation.
- NavigationThrottle::PROCEED // redirect expectation.
- },
};
for (const auto& test : kTestCases) {
@@ -99,7 +82,9 @@ IN_PROC_BROWSER_TEST_F(FormSubmissionBrowserTest,
std::unique_ptr<NavigationThrottle> throttle =
FormSubmissionThrottle::MaybeCreateThrottleFor(handle.get());
ASSERT_TRUE(throttle);
- EXPECT_EQ(test.start_expectation, throttle->WillStartRequest());
+ // Browser side checks have been disabled on the initial load. Only the
+ // renderer side checks occurs. Related issue: https://crbug.com/798698.
+ EXPECT_EQ(NavigationThrottle::PROCEED, throttle->WillStartRequest());
EXPECT_EQ(test.redirect_expectation, throttle->WillRedirectRequest());
}
}
diff --git a/chromium/content/browser/frame_host/frame_navigation_entry.cc b/chromium/content/browser/frame_host/frame_navigation_entry.cc
index 490d608f4ac..2ecfb5d349f 100644
--- a/chromium/content/browser/frame_host/frame_navigation_entry.cc
+++ b/chromium/content/browser/frame_host/frame_navigation_entry.cc
@@ -23,6 +23,8 @@ FrameNavigationEntry::FrameNavigationEntry(
scoped_refptr<SiteInstanceImpl> source_site_instance,
const GURL& url,
const Referrer& referrer,
+ const std::vector<GURL>& redirect_chain,
+ const PageState& page_state,
const std::string& method,
int64_t post_id)
: frame_unique_name_(frame_unique_name),
@@ -32,6 +34,8 @@ FrameNavigationEntry::FrameNavigationEntry(
source_site_instance_(std::move(source_site_instance)),
url_(url),
referrer_(referrer),
+ redirect_chain_(redirect_chain),
+ page_state_(page_state),
method_(method),
post_id_(post_id) {}
@@ -76,14 +80,17 @@ void FrameNavigationEntry::UpdateEntry(
void FrameNavigationEntry::set_item_sequence_number(
int64_t item_sequence_number) {
- // TODO(creis): Assert that this does not change after being assigned, once
- // location.replace is classified as NEW_PAGE rather than EXISTING_PAGE.
- // Same for document sequence number. See https://crbug.com/596707.
+ // Once assigned, the item sequence number shouldn't change.
+ DCHECK(item_sequence_number_ == -1 ||
+ item_sequence_number_ == item_sequence_number);
item_sequence_number_ = item_sequence_number;
}
void FrameNavigationEntry::set_document_sequence_number(
int64_t document_sequence_number) {
+ // Once assigned, the document sequence number shouldn't change.
+ DCHECK(document_sequence_number_ == -1 ||
+ document_sequence_number_ == document_sequence_number);
document_sequence_number_ = document_sequence_number;
}
diff --git a/chromium/content/browser/frame_host/frame_navigation_entry.h b/chromium/content/browser/frame_host/frame_navigation_entry.h
index ed54dfb5045..46c19d7e7ca 100644
--- a/chromium/content/browser/frame_host/frame_navigation_entry.h
+++ b/chromium/content/browser/frame_host/frame_navigation_entry.h
@@ -38,6 +38,8 @@ class CONTENT_EXPORT FrameNavigationEntry
scoped_refptr<SiteInstanceImpl> source_site_instance,
const GURL& url,
const Referrer& referrer,
+ const std::vector<GURL>& redirect_chain,
+ const PageState& page_state,
const std::string& method,
int64_t post_id);
diff --git a/chromium/content/browser/frame_host/frame_tree.cc b/chromium/content/browser/frame_host/frame_tree.cc
index 7d3d5d7bf45..f7ac86c71b7 100644
--- a/chromium/content/browser/frame_host/frame_tree.cc
+++ b/chromium/content/browser/frame_host/frame_tree.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <queue>
+#include <set>
#include <utility>
#include "base/bind.h"
@@ -28,7 +29,7 @@
#include "content/common/frame_owner_properties.h"
#include "content/common/input_messages.h"
#include "content/common/site_isolation_policy.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "third_party/WebKit/common/frame_policy.h"
namespace content {
@@ -109,6 +110,7 @@ FrameTree::FrameTree(Navigator* navigator,
blink::WebTreeScopeType::kDocument,
std::string(),
std::string(),
+ false,
base::UnguessableToken::Create(),
FrameOwnerProperties())),
focused_frame_tree_node_id_(FrameTreeNode::kFrameTreeNodeInvalidId),
@@ -171,16 +173,18 @@ FrameTree::NodeRange FrameTree::NodesExceptSubtree(FrameTreeNode* node) {
return NodeRange(root_, node);
}
-bool FrameTree::AddFrame(FrameTreeNode* parent,
- int process_id,
- int new_routing_id,
- blink::WebTreeScopeType scope,
- const std::string& frame_name,
- const std::string& frame_unique_name,
- const base::UnguessableToken& devtools_frame_token,
- blink::WebSandboxFlags sandbox_flags,
- const ParsedFeaturePolicyHeader& container_policy,
- const FrameOwnerProperties& frame_owner_properties) {
+bool FrameTree::AddFrame(
+ FrameTreeNode* parent,
+ int process_id,
+ int new_routing_id,
+ service_manager::mojom::InterfaceProviderRequest interface_provider_request,
+ blink::WebTreeScopeType scope,
+ const std::string& frame_name,
+ const std::string& frame_unique_name,
+ bool is_created_by_script,
+ const base::UnguessableToken& devtools_frame_token,
+ const blink::FramePolicy& frame_policy,
+ const FrameOwnerProperties& frame_owner_properties) {
CHECK_NE(new_routing_id, MSG_ROUTING_NONE);
// A child frame always starts with an initial empty document, which means
@@ -193,29 +197,35 @@ bool FrameTree::AddFrame(FrameTreeNode* parent,
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, devtools_frame_token, frame_owner_properties));
+ 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
// empty document in the frame. This needs to happen before the call to
// AddChild so that the effective policy is sent to any newly-created
// RenderFrameProxy objects when the RenderFrameHost is created.
- new_node->SetPendingSandboxFlags(sandbox_flags);
- new_node->SetPendingContainerPolicy(container_policy);
+ new_node->SetPendingFramePolicy(frame_policy);
new_node->CommitPendingFramePolicy();
// Add the new node to the FrameTree, creating the RenderFrameHost.
FrameTreeNode* added_node =
parent->AddChild(std::move(new_node), process_id, new_routing_id);
+ DCHECK(interface_provider_request.is_pending());
+ added_node->current_frame_host()->BindInterfaceProviderRequest(
+ std::move(interface_provider_request));
+
// The last committed NavigationEntry may have a FrameNavigationEntry with the
// same |frame_unique_name|, since we don't remove FrameNavigationEntries if
// their frames are deleted. If there is a stale one, remove it to avoid
// conflicts on future updates.
NavigationEntryImpl* last_committed_entry = static_cast<NavigationEntryImpl*>(
parent->navigator()->GetController()->GetLastCommittedEntry());
- if (last_committed_entry)
- last_committed_entry->ClearStaleFrameEntriesForNewFrame(added_node);
+ if (last_committed_entry) {
+ last_committed_entry->RemoveEntryForFrame(
+ added_node, /* only_if_different_position = */ true);
+ }
// Now that the new node is part of the FrameTree and has a RenderFrameHost,
// we can announce the creation of the initial RenderFrame which already
diff --git a/chromium/content/browser/frame_host/frame_tree.h b/chromium/content/browser/frame_host/frame_tree.h
index 379ecda1287..889aa003aee 100644
--- a/chromium/content/browser/frame_host/frame_tree.h
+++ b/chromium/content/browser/frame_host/frame_tree.h
@@ -17,6 +17,11 @@
#include "base/macros.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/common/content_export.h"
+#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
+
+namespace blink {
+struct FramePolicy;
+} // namespace blink
namespace content {
@@ -121,15 +126,21 @@ class CONTENT_EXPORT FrameTree {
// Adds a new child frame to the frame tree. |process_id| is required to
// disambiguate |new_routing_id|, and it must match the process of the
// |parent| node. Otherwise no child is added and this method returns false.
+ // |interface_provider_request| is the request end of the InterfaceProvider
+ // interface through which the child RenderFrame can access Mojo services
+ // exposed by the corresponding RenderFrameHost. The caller takes care of
+ // sending the client end of the interface down to the RenderFrame.
bool AddFrame(FrameTreeNode* parent,
int process_id,
int new_routing_id,
+ service_manager::mojom::InterfaceProviderRequest
+ interface_provider_request,
blink::WebTreeScopeType scope,
const std::string& frame_name,
const std::string& frame_unique_name,
+ bool is_created_by_script,
const base::UnguessableToken& devtools_frame_token,
- blink::WebSandboxFlags sandbox_flags,
- const ParsedFeaturePolicyHeader& container_policy,
+ const blink::FramePolicy& frame_policy,
const FrameOwnerProperties& frame_owner_properties);
// Removes a frame from the frame tree. |child|, its children, and objects
diff --git a/chromium/content/browser/frame_host/frame_tree_browsertest.cc b/chromium/content/browser/frame_host/frame_tree_browsertest.cc
index 41c2dacbb39..a105ea70fea 100644
--- a/chromium/content/browser/frame_host/frame_tree_browsertest.cc
+++ b/chromium/content/browser/frame_host/frame_tree_browsertest.cc
@@ -24,7 +24,7 @@
#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 "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "third_party/WebKit/common/sandbox_flags.h"
#include "url/url_constants.h"
namespace content {
@@ -463,10 +463,10 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, ChildFrameWithSrcdoc) {
child, "domAutomationController.send(document.origin);", &frame_origin));
EXPECT_TRUE(
child->current_frame_host()->GetLastCommittedOrigin().IsSameOriginWith(
- url::Origin(GURL(frame_origin))));
+ url::Origin::Create(GURL(frame_origin))));
EXPECT_FALSE(
root->current_frame_host()->GetLastCommittedOrigin().IsSameOriginWith(
- url::Origin(GURL(frame_origin))));
+ url::Origin::Create(GURL(frame_origin))));
// Create a new iframe with srcdoc and add it to the main frame. It should
// be created in the same SiteInstance as the parent.
@@ -507,6 +507,58 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, ChildFrameWithSrcdoc) {
}
}
+// Ensure that sandbox flags are correctly set in the main frame when set by
+// Content-Security-Policy header.
+IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, SandboxFlagsSetForMainFrame) {
+ GURL main_url(embedded_test_server()->GetURL("/csp_sandboxed_frame.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 = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ // Verify that sandbox flags are set properly for the root FrameTreeNode and
+ // RenderFrameHost. Root frame is sandboxed with "allow-scripts".
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->active_sandbox_flags());
+ EXPECT_EQ(root->active_sandbox_flags(),
+ root->current_frame_host()->active_sandbox_flags());
+
+ // Verify that child frames inherit sandbox flags from the root. First frame
+ // has no explicitly set flags of its own, and should inherit those from the
+ // root. Second frame is completely sandboxed.
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->active_sandbox_flags());
+ EXPECT_EQ(root->child_at(0)->active_sandbox_flags(),
+ root->child_at(0)->current_frame_host()->active_sandbox_flags());
+ EXPECT_EQ(blink::WebSandboxFlags::kAll,
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll,
+ root->child_at(1)->active_sandbox_flags());
+ EXPECT_EQ(root->child_at(1)->active_sandbox_flags(),
+ root->child_at(1)->current_frame_host()->active_sandbox_flags());
+
+ // Navigating the main frame to a different URL should clear sandbox flags.
+ GURL unsandboxed_url(embedded_test_server()->GetURL("/title1.html"));
+ NavigateFrameToURL(root, unsandboxed_url);
+
+ // Verify that sandbox flags are cleared properly for the root FrameTreeNode
+ // and RenderFrameHost.
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kNone, root->active_sandbox_flags());
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->current_frame_host()->active_sandbox_flags());
+}
+
// Ensure that sandbox flags are correctly set when child frames are created.
IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, SandboxFlagsSetForChildFrames) {
GURL main_url(embedded_test_server()->GetURL("/sandboxed_frames.html"));
@@ -521,16 +573,17 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, SandboxFlagsSetForChildFrames) {
// which resets both SandboxFlags::Scripts and
// SandboxFlags::AutomaticFeatures bits per blink::parseSandboxPolicy(), and
// third frame has "allow-scripts allow-same-origin".
- EXPECT_EQ(blink::WebSandboxFlags::kNone, root->effective_sandbox_flags());
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->effective_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kAll,
- root->child_at(0)->effective_sandbox_flags());
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
~blink::WebSandboxFlags::kAutomaticFeatures,
- root->child_at(1)->effective_sandbox_flags());
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
~blink::WebSandboxFlags::kAutomaticFeatures &
~blink::WebSandboxFlags::kOrigin,
- root->child_at(2)->effective_sandbox_flags());
+ root->child_at(2)->effective_frame_policy().sandbox_flags);
// Sandboxed frames should set a unique origin unless they have the
// "allow-same-origin" directive.
@@ -543,7 +596,81 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, SandboxFlagsSetForChildFrames) {
GURL frame_url(embedded_test_server()->GetURL("/title1.html"));
NavigateFrameToURL(root->child_at(0), frame_url);
EXPECT_EQ(blink::WebSandboxFlags::kAll,
- root->child_at(0)->effective_sandbox_flags());
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
+}
+
+// Ensure that sandbox flags are correctly set in the child frames when set by
+// Content-Security-Policy header, and in combination with the sandbox iframe
+// attribute.
+IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest,
+ SandboxFlagsSetByCSPForChildFrames) {
+ GURL main_url(embedded_test_server()->GetURL("/sandboxed_frames_csp.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 = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ // Verify that sandbox flags are set properly for all FrameTreeNodes.
+ // First frame has no iframe sandbox flags, but the framed document is served
+ // with a CSP header which sets "allow-scripts", "allow-popups" and
+ // "allow-pointer-lock".
+ // Second frame is sandboxed with "allow-scripts", "allow-pointer-lock" and
+ // "allow-orientation-lock", and the framed document is also served with a CSP
+ // header which uses "allow-popups" and "allow-pointer-lock". The resulting
+ // sandbox for the frame should only have "allow-pointer-lock".
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kNone, root->active_sandbox_flags());
+ EXPECT_EQ(root->active_sandbox_flags(),
+ root->current_frame_host()->active_sandbox_flags());
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures &
+ ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kPointerLock,
+ root->child_at(0)->active_sandbox_flags());
+ EXPECT_EQ(root->child_at(0)->active_sandbox_flags(),
+ root->child_at(0)->current_frame_host()->active_sandbox_flags());
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kOrientationLock,
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures &
+ ~blink::WebSandboxFlags::kPointerLock,
+ root->child_at(1)->active_sandbox_flags());
+ EXPECT_EQ(root->child_at(1)->active_sandbox_flags(),
+ root->child_at(1)->current_frame_host()->active_sandbox_flags());
+
+ // Navigating to a different URL *should* clear CSP-set sandbox flags, but
+ // should retain those flags set by the frame owner.
+ GURL frame_url(embedded_test_server()->GetURL("/title1.html"));
+
+ NavigateFrameToURL(root->child_at(0), frame_url);
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->child_at(0)->active_sandbox_flags());
+ EXPECT_EQ(root->child_at(0)->active_sandbox_flags(),
+ root->child_at(0)->current_frame_host()->active_sandbox_flags());
+
+ NavigateFrameToURL(root->child_at(1), frame_url);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kOrientationLock,
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kOrientationLock,
+ root->child_at(1)->active_sandbox_flags());
+ EXPECT_EQ(root->child_at(1)->active_sandbox_flags(),
+ root->child_at(1)->current_frame_host()->active_sandbox_flags());
}
// Ensure that a popup opened from a subframe sets its opener to the subframe's
@@ -691,6 +818,44 @@ IN_PROC_BROWSER_TEST_F(CrossProcessFrameTreeBrowserTest,
EXPECT_EQ(root->child_at(1)->current_origin().Serialize(), "null");
}
+// Ensure that a popup opened from a sandboxed main frame inherits sandbox flags
+// from its opener.
+IN_PROC_BROWSER_TEST_F(CrossProcessFrameTreeBrowserTest,
+ SandboxFlagsSetForNewWindow) {
+ GURL main_url(
+ embedded_test_server()->GetURL("/sandboxed_main_frame_script.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 = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ // Open a new window from the main frame.
+ GURL popup_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
+ Shell* new_shell = OpenPopup(root->current_frame_host(), popup_url, "");
+ EXPECT_TRUE(new_shell);
+ WebContents* new_contents = new_shell->web_contents();
+
+ // Check that the new window's sandbox flags correctly reflect the opener's
+ // flags. Main frame sets allow-popups, allow-pointer-lock and allow-scripts.
+ FrameTreeNode* popup_root =
+ static_cast<WebContentsImpl*>(new_contents)->GetFrameTree()->root();
+ blink::WebSandboxFlags main_frame_sandbox_flags =
+ root->current_frame_host()->active_sandbox_flags();
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ main_frame_sandbox_flags);
+
+ EXPECT_EQ(main_frame_sandbox_flags,
+ popup_root->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(main_frame_sandbox_flags, popup_root->active_sandbox_flags());
+ EXPECT_EQ(main_frame_sandbox_flags,
+ popup_root->current_frame_host()->active_sandbox_flags());
+}
+
// FrameTreeBrowserTest variant where we isolate http://*.is, Iceland's top
// level domain. This is an analogue to isolating extensions, which we can use
// inside content_browsertests, where extensions don't exist. Iceland, like an
diff --git a/chromium/content/browser/frame_host/frame_tree_node.cc b/chromium/content/browser/frame_host/frame_tree_node.cc
index b84c937c430..8990d03d02d 100644
--- a/chromium/content/browser/frame_host/frame_tree_node.cc
+++ b/chromium/content/browser/frame_host/frame_tree_node.cc
@@ -15,6 +15,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
+#include "content/browser/devtools/render_frame_devtools_agent_host.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/navigation_request.h"
#include "content/browser/frame_host/navigator.h"
@@ -24,7 +25,7 @@
#include "content/common/site_isolation_policy.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/browser_side_navigation_policy.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "third_party/WebKit/common/sandbox_flags.h"
namespace content {
@@ -136,6 +137,7 @@ FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
blink::WebTreeScopeType scope,
const std::string& name,
const std::string& unique_name,
+ bool is_created_by_script,
const base::UnguessableToken& devtools_frame_token,
const FrameOwnerProperties& frame_owner_properties)
: frame_tree_(frame_tree),
@@ -154,11 +156,10 @@ FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
scope,
name,
unique_name,
- blink::WebSandboxFlags::kNone,
false /* should enforce strict mixed content checking */,
false /* is a potentially trustworthy unique origin */,
false /* has received a user gesture */),
- pending_sandbox_flags_(blink::WebSandboxFlags::kNone),
+ is_created_by_script_(is_created_by_script),
devtools_frame_token_(devtools_frame_token),
frame_owner_properties_(frame_owner_properties),
loading_progress_(kLoadingProgressNotStarted),
@@ -175,7 +176,22 @@ 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_);
+
+ // 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.
+ // See also https://crbug.com/784356.
+ if (is_created_by_script_ && parent_) {
+ NavigationEntryImpl* nav_entry = static_cast<NavigationEntryImpl*>(
+ navigator()->GetController()->GetLastCommittedEntry());
+ if (nav_entry) {
+ nav_entry->RemoveEntryForFrame(this,
+ /* only_if_different_position = */ false);
+ }
+ }
+
frame_tree_->FrameRemoved(this);
for (auto& observer : observers_)
observer.OnFrameTreeNodeDestroyed(this);
@@ -253,6 +269,18 @@ void FrameTreeNode::ResetForNewProcess() {
std::vector<std::unique_ptr<FrameTreeNode>>().swap(children_);
}
+void FrameTreeNode::ResetForNavigation() {
+ // Discard any CSP headers from the previous document.
+ replication_state_.accumulated_csp_headers.clear();
+ render_manager_.OnDidResetContentSecurityPolicy();
+
+ // Clear the declared feature policy for the frame.
+ replication_state_.feature_policy_header.clear();
+
+ // Clear any CSP-set sandbox flags in the frame.
+ UpdateActiveSandboxFlags(blink::WebSandboxFlags::kNone);
+}
+
void FrameTreeNode::SetOpener(FrameTreeNode* opener) {
if (opener_) {
opener_->RemoveObserver(opener_observer_.get());
@@ -262,7 +290,7 @@ void FrameTreeNode::SetOpener(FrameTreeNode* opener) {
opener_ = opener;
if (opener_) {
- opener_observer_ = base::MakeUnique<OpenerDestroyedObserver>(this, false);
+ opener_observer_ = std::make_unique<OpenerDestroyedObserver>(this, false);
opener_->AddObserver(opener_observer_.get());
}
}
@@ -280,7 +308,7 @@ void FrameTreeNode::SetOriginalOpener(FrameTreeNode* opener) {
if (original_opener_) {
original_opener_observer_ =
- base::MakeUnique<OpenerDestroyedObserver>(this, true);
+ std::make_unique<OpenerDestroyedObserver>(this, true);
original_opener_->AddObserver(original_opener_observer_.get());
}
}
@@ -341,14 +369,10 @@ void FrameTreeNode::SetFrameName(const std::string& name,
}
void FrameTreeNode::SetFeaturePolicyHeader(
- const ParsedFeaturePolicyHeader& parsed_header) {
+ const blink::ParsedFeaturePolicy& parsed_header) {
replication_state_.feature_policy_header = parsed_header;
}
-void FrameTreeNode::ResetFeaturePolicyHeader() {
- replication_state_.feature_policy_header.clear();
-}
-
void FrameTreeNode::AddContentSecurityPolicies(
const std::vector<ContentSecurityPolicyHeader>& headers) {
replication_state_.accumulated_csp_headers.insert(
@@ -357,11 +381,6 @@ void FrameTreeNode::AddContentSecurityPolicies(
render_manager_.OnDidAddContentSecurityPolicies(headers);
}
-void FrameTreeNode::ResetCspHeaders() {
- replication_state_.accumulated_csp_headers.clear();
- render_manager_.OnDidResetContentSecurityPolicy();
-}
-
void FrameTreeNode::SetInsecureRequestPolicy(
blink::WebInsecureRequestPolicy policy) {
if (policy == replication_state_.insecure_request_policy)
@@ -370,21 +389,16 @@ void FrameTreeNode::SetInsecureRequestPolicy(
replication_state_.insecure_request_policy = policy;
}
-void FrameTreeNode::SetPendingSandboxFlags(
- blink::WebSandboxFlags sandbox_flags) {
- pending_sandbox_flags_ = sandbox_flags;
+void FrameTreeNode::SetPendingFramePolicy(blink::FramePolicy frame_policy) {
+ pending_frame_policy_.sandbox_flags = frame_policy.sandbox_flags;
- // Subframes should always inherit their parent's sandbox flags.
- if (parent())
- pending_sandbox_flags_ |= parent()->effective_sandbox_flags();
-}
-
-void FrameTreeNode::SetPendingContainerPolicy(
- const ParsedFeaturePolicyHeader& container_policy) {
- // This should only be called on subframes; container policy is not mutable on
- // main frame.
- DCHECK(!IsMainFrame());
- pending_container_policy_ = container_policy;
+ if (parent()) {
+ // Subframes should always inherit their parent's sandbox flags.
+ pending_frame_policy_.sandbox_flags |= parent()->active_sandbox_flags();
+ // This is only applied on subframes; container policy is not mutable on
+ // main frame.
+ pending_frame_policy_.container_policy = frame_policy.container_policy;
+ }
}
bool FrameTreeNode::IsDescendantOf(FrameTreeNode* other) const {
@@ -431,14 +445,18 @@ bool FrameTreeNode::IsLoading() const {
}
bool FrameTreeNode::CommitPendingFramePolicy() {
- bool did_change_flags =
- pending_sandbox_flags_ != replication_state_.sandbox_flags;
+ bool did_change_flags = pending_frame_policy_.sandbox_flags !=
+ replication_state_.frame_policy.sandbox_flags;
bool did_change_container_policy =
- pending_container_policy_ != replication_state_.container_policy;
+ pending_frame_policy_.container_policy !=
+ replication_state_.frame_policy.container_policy;
if (did_change_flags)
- replication_state_.sandbox_flags = pending_sandbox_flags_;
+ replication_state_.frame_policy.sandbox_flags =
+ pending_frame_policy_.sandbox_flags;
if (did_change_container_policy)
- replication_state_.container_policy = pending_container_policy_;
+ replication_state_.frame_policy.container_policy =
+ pending_frame_policy_.container_policy;
+ UpdateActiveSandboxFlags(pending_frame_policy_.sandbox_flags);
return did_change_flags || did_change_container_policy;
}
@@ -481,6 +499,9 @@ void FrameTreeNode::ResetNavigationRequest(bool keep_state,
if (!navigation_request_)
return;
+ RenderFrameDevToolsAgentHost::OnResetNavigationRequest(
+ navigation_request_.get());
+
// The renderer should be informed if the caller allows to do so and the
// navigation came from a BeginNavigation IPC.
int need_to_inform_renderer =
@@ -514,7 +535,6 @@ void FrameTreeNode::ResetNavigationRequest(bool keep_state,
current_frame_host()->Send(
new FrameMsg_DroppedNavigation(current_frame_host()->GetRoutingID()));
}
-
}
bool FrameTreeNode::has_started_loading() const {
@@ -644,4 +664,17 @@ FrameTreeNode* FrameTreeNode::GetSibling(int relative_offset) const {
return nullptr;
}
+void FrameTreeNode::UpdateActiveSandboxFlags(
+ blink::WebSandboxFlags sandbox_flags) {
+ // TODO(iclelland): Kill the renderer if sandbox flags is not a subset of the
+ // currently effective sandbox flags from the frame. https://crbug.com/740556
+ blink::WebSandboxFlags original_flags =
+ replication_state_.active_sandbox_flags;
+ replication_state_.active_sandbox_flags =
+ sandbox_flags | effective_frame_policy().sandbox_flags;
+ // Notify any proxies if the flags have been changed.
+ if (replication_state_.active_sandbox_flags != original_flags)
+ render_manager()->OnDidSetActiveSandboxFlags();
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/frame_tree_node.h b/chromium/content/browser/frame_host/frame_tree_node.h
index 65ae66be5cd..eb5fbc7c314 100644
--- a/chromium/content/browser/frame_host/frame_tree_node.h
+++ b/chromium/content/browser/frame_host/frame_tree_node.h
@@ -20,6 +20,7 @@
#include "content/common/content_export.h"
#include "content/common/frame_owner_properties.h"
#include "content/common/frame_replication_state.h"
+#include "third_party/WebKit/common/frame_policy.h"
#include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -66,6 +67,7 @@ class CONTENT_EXPORT FrameTreeNode {
blink::WebTreeScopeType scope,
const std::string& name,
const std::string& unique_name,
+ bool is_created_by_script,
const base::UnguessableToken& devtools_frame_token,
const FrameOwnerProperties& frame_owner_properties);
@@ -84,6 +86,13 @@ class CONTENT_EXPORT FrameTreeNode {
// Clears process specific-state in this node to prepare for a new process.
void ResetForNewProcess();
+ // Clears any state in this node which was set by the document itself (CSP
+ // Headers, Feature Policy Headers, and CSP-set sandbox flags), and notifies
+ // proxies as appropriate. Invoked after committing navigation to a new
+ // document (since the new document comes with a fresh set of CSP and
+ // Feature-Policy HTTP headers).
+ void ResetForNavigation();
+
FrameTree* frame_tree() const {
return frame_tree_;
}
@@ -141,7 +150,7 @@ class CONTENT_EXPORT FrameTreeNode {
// Returns the URL of the last committed page in the current frame.
const GURL& current_url() const {
- return current_frame_host()->last_committed_url();
+ return current_frame_host()->GetLastCommittedURL();
}
// Sets the last committed URL for this frame and updates
@@ -184,73 +193,50 @@ class CONTENT_EXPORT FrameTreeNode {
void SetFrameName(const std::string& name, const std::string& unique_name);
// Set the frame's feature policy header, clearing any existing header.
- void SetFeaturePolicyHeader(const ParsedFeaturePolicyHeader& parsed_header);
-
- // Clear any feature policy header associated with the frame.
- void ResetFeaturePolicyHeader();
+ void SetFeaturePolicyHeader(const blink::ParsedFeaturePolicy& parsed_header);
// Add CSP headers to replication state, notify proxies about the update.
void AddContentSecurityPolicies(
const std::vector<ContentSecurityPolicyHeader>& headers);
- // Discards previous CSP headers and notifies proxies about the update.
- // Typically invoked after committing navigation to a new document (since the
- // new document comes with a fresh set of CSP http headers).
- void ResetCspHeaders();
-
// Sets the current insecure request policy, and notifies proxies about the
// update.
void SetInsecureRequestPolicy(blink::WebInsecureRequestPolicy policy);
- // Returns the currently active sandbox flags for this frame. This includes
- // flags inherited from parent frames and the currently active flags from the
- // <iframe> element hosting this frame. This does not include flags that
- // have been updated in an <iframe> element but have not taken effect yet;
- // use pending_sandbox_flags() for those.
- blink::WebSandboxFlags effective_sandbox_flags() const {
- return replication_state_.sandbox_flags;
+ // Returns the latest frame policy (sandbox flags and container policy) for
+ // this frame. This includes flags inherited from parent frames and the latest
+ // flags from the <iframe> element hosting this frame. The returned policies
+ // may not yet have taken effect, since "sandbox" and "allow" attribute
+ // updates in an <iframe> element take effect on next navigation. To retrieve
+ // the currently active policy for this frame, use effective_frame_policy().
+ const blink::FramePolicy& pending_frame_policy() const {
+ return pending_frame_policy_;
}
- // Returns the latest sandbox flags for this frame. This includes flags
- // inherited from parent frames and the latest flags from the <iframe>
- // element hosting this frame. The returned flags may not yet have taken
- // effect, since sandbox flag updates in an <iframe> element take effect on
- // next navigation. To retrieve the currently active sandbox flags for this
- // frame, use effective_sandbox_flags().
- blink::WebSandboxFlags pending_sandbox_flags() const {
- return pending_sandbox_flags_;
+ // Update this frame's sandbox flags and container policy. This is called
+ // when a parent frame updates the "sandbox" attribute in the <iframe> element
+ // for this frame, or any of the attributes which affect the container policy
+ // ("allowfullscreen", "allowpaymentrequest", "allow", and "src".)
+ // These policies won't take effect until next navigation. If this frame's
+ // parent is itself sandboxed, the parent's sandbox flags are combined with
+ // those in |frame_policy|.
+ // Attempting to change the container policy on the main frame will have no
+ // effect.
+ void SetPendingFramePolicy(blink::FramePolicy frame_policy);
+
+ // Returns the currently active frame policy for this frame, including the
+ // sandbox flags which were present at the time the document was loaded, and
+ // the feature policy container policy, which is set by the iframe's
+ // allowfullscreen, allowpaymentrequest, and allow attributes, along with the
+ // origin of the iframe's src attribute (which may be different from the URL
+ // of the document currently loaded into the frame). This does not include
+ // policy changes that have been made by updating the containing iframe
+ // element attributes since the frame was last navigated; use
+ // pending_frame_policy() for those.
+ const blink::FramePolicy& effective_frame_policy() const {
+ return replication_state_.frame_policy;
}
- const ParsedFeaturePolicyHeader& pending_container_policy() const {
- return pending_container_policy_;
- }
-
- // Update this frame's sandbox flags. This is used when a parent frame
- // updates sandbox flags in the <iframe> element for this frame. These flags
- // won't take effect until next navigation. If this frame's parent is itself
- // sandboxed, the parent's sandbox flags are combined with |sandbox_flags|.
- void SetPendingSandboxFlags(blink::WebSandboxFlags sandbox_flags);
-
- // Returns the currently active container policy for this frame, which is set
- // by the iframe allowfullscreen, allowpaymentrequest, and allow attributes,
- // along with the origin of the iframe's src attribute (which may be different
- // from the URL of the document currently loaded into the frame). This does
- // not include policy changes that have been made by updating the containing
- // iframe element attributes since the frame was last navigated.
- const ParsedFeaturePolicyHeader& effective_container_policy() const {
- return replication_state_.container_policy;
- }
-
- // Update this frame's container policy. This is used when a parent frame
- // updates feature-policy attributes in the <iframe> element for this frame.
- // These attributes include allow, allowfullscreen, allowpaymentrequest, and
- // src. Updates to the container policy will not take effect until next
- // navigation.
- // This method must only be called on a subframe; changing the container
- // policy on the main frame is not allowed.
- void SetPendingContainerPolicy(
- const ParsedFeaturePolicyHeader& container_policy);
-
// Set any pending sandbox flags and container policy as active, and return
// true if either was changed.
bool CommitPendingFramePolicy();
@@ -358,6 +344,25 @@ class CONTENT_EXPORT FrameTreeNode {
void OnSetHasReceivedUserGesture();
+ // Returns the sandbox flags currently in effect for this frame. This includes
+ // flags inherited from parent frames, the currently active flags from the
+ // <iframe> element hosting this frame, as well as any flags set from a
+ // Content-Security-Policy HTTP header. This does not include flags that have
+ // have been updated in an <iframe> element but have not taken effect yet; use
+ // pending_frame_policy() for those. To see the flags which will take effect
+ // on navigation (which does not include the CSP-set flags), use
+ // effective_frame_policy().
+ blink::WebSandboxFlags active_sandbox_flags() const {
+ return replication_state_.active_sandbox_flags;
+ }
+
+ // Updates the active sandbox flags in this frame, in response to a
+ // Content-Security-Policy header adding additional flags, in addition to
+ // those given to this frame by its parent. Note that on navigation, these
+ // updates will be cleared, and the flags in the pending frame policy will be
+ // applied to the frame.
+ void UpdateActiveSandboxFlags(blink::WebSandboxFlags sandbox_flags);
+
private:
FRIEND_TEST_ALL_PREFIXES(SitePerProcessFeaturePolicyBrowserTest,
ContainerPolicyDynamic);
@@ -425,18 +430,18 @@ class CONTENT_EXPORT FrameTreeNode {
// proxies for this frame.
FrameReplicationState replication_state_;
- // Track the pending sandbox flags for this frame. When a parent frame
- // dynamically updates sandbox flags in the <iframe> element for a child
- // frame, these updated flags are stored here and are transferred into
- // replication_state_.sandbox_flags when they take effect on the next frame
- // navigation.
- blink::WebSandboxFlags pending_sandbox_flags_;
-
- // Tracks the computed container policy for this frame. When the iframe
- // allowfullscreen, allowpaymentrequest, allow or src attributes are changed,
- // the updated policy for the frame is stored here, and transferred into
- // replication_state_.container_policy on the next frame navigation.
- ParsedFeaturePolicyHeader pending_container_policy_;
+ // Track the pending sandbox flags and container policy for this frame. When a
+ // parent frame dynamically updates 'sandbox', 'allow', 'allowfullscreen',
+ // 'allowpaymentrequest' or 'src' attributes, the updated policy for the frame
+ // is stored here, and transferred into replication_state_.frame_policy when
+ // they take effect on the next frame navigation.
+ blink::FramePolicy pending_frame_policy_;
+
+ // Whether the frame was created by javascript. This is useful to prune
+ // history entries when the frame is removed (because frames created by
+ // scripts are never recreated with the same unique name - see
+ // https://crbug.com/500260).
+ bool is_created_by_script_;
// Used for devtools instrumentation and trace-ability. The token is
// propagated to Blink's LocalFrame and both Blink and content/
diff --git a/chromium/content/browser/frame_host/frame_tree_node_blame_context.cc b/chromium/content/browser/frame_host/frame_tree_node_blame_context.cc
index bae5f2a0368..a99affdbb9d 100644
--- a/chromium/content/browser/frame_host/frame_tree_node_blame_context.cc
+++ b/chromium/content/browser/frame_host/frame_tree_node_blame_context.cc
@@ -63,7 +63,7 @@ void FrameTreeNodeBlameContext::AsValueInto(
value->EndDictionary();
}
- GURL url = current_frame_host->last_committed_url();
+ GURL url = current_frame_host->GetLastCommittedURL();
if (url.is_valid())
value->SetString("url", url.spec());
}
diff --git a/chromium/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc b/chromium/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc
index b08c37bf91c..1d080003058 100644
--- a/chromium/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc
+++ b/chromium/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc
@@ -4,6 +4,11 @@
#include "content/browser/frame_host/frame_tree_node_blame_context.h"
+#include <algorithm>
+#include <memory>
+#include <set>
+#include <string>
+
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/test/trace_event_analyzer.h"
@@ -15,7 +20,7 @@
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "third_party/WebKit/common/frame_policy.h"
namespace content {
@@ -132,10 +137,12 @@ class FrameTreeNodeBlameContextTest : public RenderViewHostImplTestHarness {
for (int child_num = 1; shape[consumption++] == '('; ++child_num) {
int child_id = self_id * 10 + child_num;
tree()->AddFrame(
- node, process_id(), child_id, blink::WebTreeScopeType::kDocument,
- std::string(), base::StringPrintf("uniqueName%d", child_id),
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ node, process_id(), child_id,
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(),
+ base::StringPrintf("uniqueName%d", child_id), false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
FrameTreeNode* child = node->child_at(child_num - 1);
consumption += CreateSubframes(child, child_id, shape + consumption);
}
diff --git a/chromium/content/browser/frame_host/frame_tree_unittest.cc b/chromium/content/browser/frame_host/frame_tree_unittest.cc
index eebf250f086..83fa660afc3 100644
--- a/chromium/content/browser/frame_host/frame_tree_unittest.cc
+++ b/chromium/content/browser/frame_host/frame_tree_unittest.cc
@@ -24,7 +24,7 @@
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "third_party/WebKit/common/frame_policy.h"
namespace content {
@@ -52,6 +52,11 @@ void AppendTreeNodeState(FrameTreeNode* node, std::string* result) {
result->append("]");
}
+service_manager::mojom::InterfaceProviderRequest
+CreateStubInterfaceProviderRequest() {
+ return TestRenderFrameHost::CreateStubInterfaceProviderRequest();
+}
+
// Logs calls to WebContentsObserver along with the state of the frame tree,
// for later use in EXPECT_EQ().
class TreeWalkingWebContentsLogger : public WebContentsObserver {
@@ -157,36 +162,36 @@ TEST_F(FrameTreeTest, Shape) {
EXPECT_EQ("2: []", GetTreeState(frame_tree));
// Simulate attaching a series of frames to build the frame tree.
- frame_tree->AddFrame(root, process_id, 14, blink::WebTreeScopeType::kDocument,
- std::string(), "uniqueName0",
- base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
- frame_tree->AddFrame(root, process_id, 15, blink::WebTreeScopeType::kDocument,
- std::string(), "uniqueName1",
- base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
- frame_tree->AddFrame(root, process_id, 16, blink::WebTreeScopeType::kDocument,
- std::string(), "uniqueName2",
- base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ frame_tree->AddFrame(root, process_id, 14,
+ CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(),
+ "uniqueName0", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
+ frame_tree->AddFrame(root, process_id, 15,
+ CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(),
+ "uniqueName1", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
+ frame_tree->AddFrame(root, process_id, 16,
+ CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(),
+ "uniqueName2", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
frame_tree->AddFrame(root->child_at(0), process_id, 244,
+ CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, std::string(),
- "uniqueName3", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName3", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
frame_tree->AddFrame(root->child_at(1), process_id, 255,
+ CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, no_children_node,
- "uniqueName4", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName4", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
frame_tree->AddFrame(root->child_at(0), process_id, 245,
+ CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, std::string(),
- "uniqueName5", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName5", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
EXPECT_EQ(
"2: [14: [244: [], 245: []], "
@@ -196,52 +201,52 @@ TEST_F(FrameTreeTest, Shape) {
FrameTreeNode* child_16 = root->child_at(2);
frame_tree->AddFrame(child_16, process_id, 264,
+ CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, std::string(),
- "uniqueName6", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName6", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
frame_tree->AddFrame(child_16, process_id, 265,
+ CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, std::string(),
- "uniqueName7", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName7", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
frame_tree->AddFrame(child_16, process_id, 266,
+ CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, std::string(),
- "uniqueName8", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName8", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
frame_tree->AddFrame(child_16, process_id, 267,
+ CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, deep_subtree,
- "uniqueName9", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName9", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
frame_tree->AddFrame(child_16, process_id, 268,
+ CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, std::string(),
- "uniqueName10", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName10", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
FrameTreeNode* child_267 = child_16->child_at(3);
frame_tree->AddFrame(child_267, process_id, 365,
+ CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, std::string(),
- "uniqueName11", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName11", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
frame_tree->AddFrame(child_267->child_at(0), process_id, 455,
+ CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, std::string(),
- "uniqueName12", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName12", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
frame_tree->AddFrame(child_267->child_at(0)->child_at(0), process_id, 555,
+ CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(),
+ "uniqueName13", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
+ frame_tree->AddFrame(child_267->child_at(0)->child_at(0)->child_at(0),
+ process_id, 655, CreateStubInterfaceProviderRequest(),
blink::WebTreeScopeType::kDocument, std::string(),
- "uniqueName13", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
- frame_tree->AddFrame(
- child_267->child_at(0)->child_at(0)->child_at(0), process_id, 655,
- blink::WebTreeScopeType::kDocument, std::string(), "uniqueName14",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ "uniqueName14", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
// Now that's it's fully built, verify the tree structure is as expected.
EXPECT_EQ(
@@ -313,27 +318,30 @@ TEST_F(FrameTreeTest, FindFrames) {
FrameTreeNode* root = frame_tree->root();
main_test_rfh()->OnCreateChildFrame(
- 22, blink::WebTreeScopeType::kDocument, "child0", "uniqueName0",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 22, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "child0", "uniqueName0", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(
- 23, blink::WebTreeScopeType::kDocument, "child1", "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 23, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "child1", "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(
- 24, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName2",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 24, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), "uniqueName2", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
FrameTreeNode* child0 = root->child_at(0);
FrameTreeNode* child1 = root->child_at(1);
-
FrameTreeNode* child2 = root->child_at(2);
// Add one grandchild frame.
child1->current_frame_host()->OnCreateChildFrame(
- 33, blink::WebTreeScopeType::kDocument, "grandchild", "uniqueName3",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 33, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "grandchild", "uniqueName3", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
FrameTreeNode* grandchild = child1->child_at(0);
// Ensure they can be found by FTN id.
@@ -370,26 +378,30 @@ TEST_F(FrameTreeTest, GetSibling) {
FrameTree* frame_tree = contents()->GetFrameTree();
FrameTreeNode* root = frame_tree->root();
main_test_rfh()->OnCreateChildFrame(
- 22, blink::WebTreeScopeType::kDocument, "child0", "uniqueName0",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 22, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "child0", "uniqueName0", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(
- 23, blink::WebTreeScopeType::kDocument, "child1", "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 23, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "child1", "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(
- 24, blink::WebTreeScopeType::kDocument, "child2", "uniqueName2",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 24, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "child2", "uniqueName2", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
FrameTreeNode* child0 = root->child_at(0);
FrameTreeNode* child1 = root->child_at(1);
FrameTreeNode* child2 = root->child_at(2);
// Add one grandchild frame.
child1->current_frame_host()->OnCreateChildFrame(
- 33, blink::WebTreeScopeType::kDocument, "grandchild", "uniqueName3",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 33, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "grandchild", "uniqueName3", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
FrameTreeNode* grandchild = child1->child_at(0);
// Test PreviousSibling().
@@ -419,17 +431,19 @@ TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) {
// Simulate attaching a series of frames to build the frame tree.
main_test_rfh()->OnCreateChildFrame(
- 14, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 14, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
EXPECT_EQ(
"RenderFrameHostChanged(new)(14) -> 2: []\n"
"RenderFrameCreated(14) -> 2: [14: []]",
activity.GetLog());
main_test_rfh()->OnCreateChildFrame(
- 18, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 18, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
EXPECT_EQ(
"RenderFrameHostChanged(new)(18) -> 2: [14: []]\n"
"RenderFrameCreated(18) -> 2: [14: [], 18: []]",
@@ -448,17 +462,19 @@ TEST_F(FrameTreeTest, ObserverWalksTreeAfterCrash) {
EXPECT_EQ("RenderFrameCreated(2) -> 2: []", activity.GetLog());
main_test_rfh()->OnCreateChildFrame(
- 22, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 22, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
EXPECT_EQ(
"RenderFrameHostChanged(new)(22) -> 2: []\n"
"RenderFrameCreated(22) -> 2: [22: []]",
activity.GetLog());
main_test_rfh()->OnCreateChildFrame(
- 23, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 23, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
EXPECT_EQ(
"RenderFrameHostChanged(new)(23) -> 2: [22: []]\n"
"RenderFrameCreated(23) -> 2: [22: [], 23: []]",
@@ -486,9 +502,9 @@ TEST_F(FrameTreeTest, FailAddFrameWithWrongProcessId) {
// Simulate attaching a frame from mismatched process id.
ASSERT_FALSE(frame_tree->AddFrame(
- root, process_id + 1, 1, blink::WebTreeScopeType::kDocument,
- std::string(), "uniqueName0", base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
+ root, process_id + 1, 1, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties()));
ASSERT_EQ("2: []", GetTreeState(frame_tree));
}
@@ -502,20 +518,23 @@ TEST_F(FrameTreeTest, ProcessCrashClearsGlobalMap) {
FrameTreeNode* root = contents()->GetFrameTree()->root();
main_test_rfh()->OnCreateChildFrame(
- 22, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 22, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(
- 23, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ 23, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
// Add one grandchild frame.
RenderFrameHostImpl* child1_rfh = root->child_at(0)->current_frame_host();
- child1_rfh->OnCreateChildFrame(
- 33, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName2",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ child1_rfh->OnCreateChildFrame(33, CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument,
+ std::string(), "uniqueName2", false,
+ base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
// Ensure they can be found by id.
int id1 = root->child_at(0)->frame_tree_node_id();
diff --git a/chromium/content/browser/frame_host/input/OWNERS b/chromium/content/browser/frame_host/input/OWNERS
index cf2b318416b..86bfa17ec3d 100644
--- a/chromium/content/browser/frame_host/input/OWNERS
+++ b/chromium/content/browser/frame_host/input/OWNERS
@@ -1,4 +1,3 @@
-aelias@chromium.org
dtapuska@chromium.org
tdresser@chromium.org
diff --git a/chromium/content/browser/frame_host/input/input_injector_impl.cc b/chromium/content/browser/frame_host/input/input_injector_impl.cc
index cf14431c5ac..cdbfd9257b3 100644
--- a/chromium/content/browser/frame_host/input/input_injector_impl.cc
+++ b/chromium/content/browser/frame_host/input/input_injector_impl.cc
@@ -26,7 +26,7 @@ InputInjectorImpl::~InputInjectorImpl() {}
void InputInjectorImpl::Create(base::WeakPtr<RenderFrameHostImpl> frame_host,
mojom::InputInjectorRequest request) {
- mojo::MakeStrongBinding(base::MakeUnique<InputInjectorImpl>(frame_host),
+ mojo::MakeStrongBinding(std::make_unique<InputInjectorImpl>(frame_host),
std::move(request));
}
diff --git a/chromium/content/browser/frame_host/input/legacy_ipc_frame_input_handler.cc b/chromium/content/browser/frame_host/input/legacy_ipc_frame_input_handler.cc
index c4c2621cae6..592c24ee194 100644
--- a/chromium/content/browser/frame_host/input/legacy_ipc_frame_input_handler.cc
+++ b/chromium/content/browser/frame_host/input/legacy_ipc_frame_input_handler.cc
@@ -33,32 +33,32 @@ void LegacyIPCFrameInputHandler::SetCompositionFromExistingText(
ime_text_spans.push_back(blink_ime_text_span);
}
- SendInput(base::MakeUnique<InputMsg_SetCompositionFromExistingText>(
+ SendInput(std::make_unique<InputMsg_SetCompositionFromExistingText>(
routing_id_, start, end, ime_text_spans));
}
void LegacyIPCFrameInputHandler::ExtendSelectionAndDelete(int32_t before,
int32_t after) {
- SendInput(base::MakeUnique<InputMsg_ExtendSelectionAndDelete>(routing_id_,
+ SendInput(std::make_unique<InputMsg_ExtendSelectionAndDelete>(routing_id_,
before, after));
}
void LegacyIPCFrameInputHandler::DeleteSurroundingText(int32_t before,
int32_t after) {
- SendInput(base::MakeUnique<InputMsg_DeleteSurroundingText>(routing_id_,
+ SendInput(std::make_unique<InputMsg_DeleteSurroundingText>(routing_id_,
before, after));
}
void LegacyIPCFrameInputHandler::DeleteSurroundingTextInCodePoints(
int32_t before,
int32_t after) {
- SendInput(base::MakeUnique<InputMsg_DeleteSurroundingTextInCodePoints>(
+ SendInput(std::make_unique<InputMsg_DeleteSurroundingTextInCodePoints>(
routing_id_, before, after));
}
void LegacyIPCFrameInputHandler::SetEditableSelectionOffsets(int32_t start,
int32_t end) {
- SendInput(base::MakeUnique<InputMsg_SetEditableSelectionOffsets>(routing_id_,
+ SendInput(std::make_unique<InputMsg_SetEditableSelectionOffsets>(routing_id_,
start, end));
}
@@ -66,72 +66,72 @@ void LegacyIPCFrameInputHandler::ExecuteEditCommand(
const std::string& command,
const base::Optional<base::string16>& value) {
if (!value) {
- SendInput(base::MakeUnique<InputMsg_ExecuteNoValueEditCommand>(routing_id_,
+ SendInput(std::make_unique<InputMsg_ExecuteNoValueEditCommand>(routing_id_,
command));
}
}
void LegacyIPCFrameInputHandler::Undo() {
- SendInput(base::MakeUnique<InputMsg_Undo>(routing_id_));
+ SendInput(std::make_unique<InputMsg_Undo>(routing_id_));
}
void LegacyIPCFrameInputHandler::Redo() {
- SendInput(base::MakeUnique<InputMsg_Redo>(routing_id_));
+ SendInput(std::make_unique<InputMsg_Redo>(routing_id_));
}
void LegacyIPCFrameInputHandler::Cut() {
- SendInput(base::MakeUnique<InputMsg_Cut>(routing_id_));
+ SendInput(std::make_unique<InputMsg_Cut>(routing_id_));
}
void LegacyIPCFrameInputHandler::Copy() {
- SendInput(base::MakeUnique<InputMsg_Copy>(routing_id_));
+ SendInput(std::make_unique<InputMsg_Copy>(routing_id_));
}
void LegacyIPCFrameInputHandler::CopyToFindPboard() {
#if defined(OS_MACOSX)
- SendInput(base::MakeUnique<InputMsg_CopyToFindPboard>(routing_id_));
+ SendInput(std::make_unique<InputMsg_CopyToFindPboard>(routing_id_));
#endif
}
void LegacyIPCFrameInputHandler::Paste() {
- SendInput(base::MakeUnique<InputMsg_Paste>(routing_id_));
+ SendInput(std::make_unique<InputMsg_Paste>(routing_id_));
}
void LegacyIPCFrameInputHandler::PasteAndMatchStyle() {
- SendInput(base::MakeUnique<InputMsg_PasteAndMatchStyle>(routing_id_));
+ SendInput(std::make_unique<InputMsg_PasteAndMatchStyle>(routing_id_));
}
void LegacyIPCFrameInputHandler::Replace(const base::string16& word) {
- SendInput(base::MakeUnique<InputMsg_Replace>(routing_id_, word));
+ SendInput(std::make_unique<InputMsg_Replace>(routing_id_, word));
}
void LegacyIPCFrameInputHandler::ReplaceMisspelling(
const base::string16& word) {
- SendInput(base::MakeUnique<InputMsg_ReplaceMisspelling>(routing_id_, word));
+ SendInput(std::make_unique<InputMsg_ReplaceMisspelling>(routing_id_, word));
}
void LegacyIPCFrameInputHandler::Delete() {
- SendInput(base::MakeUnique<InputMsg_Delete>(routing_id_));
+ SendInput(std::make_unique<InputMsg_Delete>(routing_id_));
}
void LegacyIPCFrameInputHandler::SelectAll() {
- SendInput(base::MakeUnique<InputMsg_SelectAll>(routing_id_));
+ SendInput(std::make_unique<InputMsg_SelectAll>(routing_id_));
}
void LegacyIPCFrameInputHandler::CollapseSelection() {
- SendInput(base::MakeUnique<InputMsg_CollapseSelection>(routing_id_));
+ SendInput(std::make_unique<InputMsg_CollapseSelection>(routing_id_));
}
void LegacyIPCFrameInputHandler::SelectRange(const gfx::Point& point,
const gfx::Point& extent) {
- SendInput(base::MakeUnique<InputMsg_SelectRange>(routing_id_, point, extent));
+ SendInput(std::make_unique<InputMsg_SelectRange>(routing_id_, point, extent));
}
void LegacyIPCFrameInputHandler::AdjustSelectionByCharacterOffset(
int32_t start,
int32_t end,
blink::mojom::SelectionMenuBehavior selection_menu_behavior) {
- SendInput(base::MakeUnique<InputMsg_AdjustSelectionByCharacterOffset>(
+ SendInput(std::make_unique<InputMsg_AdjustSelectionByCharacterOffset>(
routing_id_, start, end,
selection_menu_behavior == blink::mojom::SelectionMenuBehavior::kShow));
}
@@ -139,21 +139,22 @@ void LegacyIPCFrameInputHandler::AdjustSelectionByCharacterOffset(
void LegacyIPCFrameInputHandler::MoveRangeSelectionExtent(
const gfx::Point& extent) {
SendInput(
- base::MakeUnique<InputMsg_MoveRangeSelectionExtent>(routing_id_, extent));
+ std::make_unique<InputMsg_MoveRangeSelectionExtent>(routing_id_, extent));
}
void LegacyIPCFrameInputHandler::ScrollFocusedEditableNodeIntoRect(
const gfx::Rect& rect) {
- SendInput(base::MakeUnique<InputMsg_ScrollFocusedEditableNodeIntoRect>(
+ SendInput(std::make_unique<InputMsg_ScrollFocusedEditableNodeIntoRect>(
routing_id_, rect));
}
void LegacyIPCFrameInputHandler::MoveCaret(const gfx::Point& point) {
- SendInput(base::MakeUnique<InputMsg_MoveCaret>(routing_id_, point));
+ SendInput(std::make_unique<InputMsg_MoveCaret>(routing_id_, point));
}
void LegacyIPCFrameInputHandler::GetWidgetInputHandler(
- mojom::WidgetInputHandlerAssociatedRequest interface_request) {
+ mojom::WidgetInputHandlerAssociatedRequest interface_request,
+ mojom::WidgetInputHandlerHostPtr host) {
NOTREACHED();
}
diff --git a/chromium/content/browser/frame_host/input/legacy_ipc_frame_input_handler.h b/chromium/content/browser/frame_host/input/legacy_ipc_frame_input_handler.h
index 4f566275edc..8fc6bf9076b 100644
--- a/chromium/content/browser/frame_host/input/legacy_ipc_frame_input_handler.h
+++ b/chromium/content/browser/frame_host/input/legacy_ipc_frame_input_handler.h
@@ -53,7 +53,8 @@ class CONTENT_EXPORT LegacyIPCFrameInputHandler
void ScrollFocusedEditableNodeIntoRect(const gfx::Rect& rect) override;
void MoveCaret(const gfx::Point& point) override;
void GetWidgetInputHandler(
- mojom::WidgetInputHandlerAssociatedRequest interface_request) override;
+ mojom::WidgetInputHandlerAssociatedRequest interface_request,
+ mojom::WidgetInputHandlerHostPtr host) override;
private:
void SendInput(std::unique_ptr<IPC::Message> message);
diff --git a/chromium/content/browser/frame_host/interstitial_page_impl.cc b/chromium/content/browser/frame_host/interstitial_page_impl.cc
index 5db34c6d5f9..2f24f1b959d 100644
--- a/chromium/content/browser/frame_host/interstitial_page_impl.cc
+++ b/chromium/content/browser/frame_host/interstitial_page_impl.cc
@@ -131,7 +131,7 @@ InterstitialPage* InterstitialPage::GetInterstitialPage(
InterstitialPageMap::const_iterator iter =
g_web_contents_to_interstitial_page->find(web_contents);
if (iter == g_web_contents_to_interstitial_page->end())
- return NULL;
+ return nullptr;
return iter->second;
}
@@ -160,14 +160,14 @@ InterstitialPageImpl::InterstitialPageImpl(
should_discard_pending_nav_entry_(new_navigation),
enabled_(true),
action_taken_(NO_ACTION),
- render_view_host_(NULL),
+ render_view_host_(nullptr),
// TODO(nasko): The InterstitialPageImpl will need to provide its own
// NavigationControllerImpl to the Navigator, which is separate from
// the WebContents one, so we can enforce no navigation policy here.
// While we get the code to a point to do this, pass NULL for it.
// TODO(creis): We will also need to pass delegates for the RVHM as we
// start to use it.
- frame_tree_(base::MakeUnique<FrameTree>(
+ frame_tree_(std::make_unique<FrameTree>(
new InterstitialPageNavigatorImpl(this, controller_),
this,
this,
@@ -297,7 +297,7 @@ void InterstitialPageImpl::Hide() {
weak_ptr_factory_.GetWeakPtr()));
bool has_focus = render_view_host_->GetWidget()->GetView() &&
render_view_host_->GetWidget()->GetView()->HasFocus();
- render_view_host_ = NULL;
+ render_view_host_ = nullptr;
frame_tree_->root()->ResetForNewProcess();
controller_->delegate()->DetachInterstitialPage(has_focus);
// Let's revert to the original title if necessary.
@@ -315,7 +315,7 @@ void InterstitialPageImpl::Hide() {
// Clear the WebContents pointer, because it may now be deleted.
// This signifies that we are in the process of shutting down.
- web_contents_ = NULL;
+ web_contents_ = nullptr;
}
void InterstitialPageImpl::Observe(
@@ -583,7 +583,7 @@ WebContents* InterstitialPageImpl::web_contents() const {
RenderViewHostImpl* InterstitialPageImpl::CreateRenderViewHost() {
if (!enabled())
- return NULL;
+ return nullptr;
// Interstitial pages don't want to share the session storage so we mint a
// new one.
@@ -609,7 +609,7 @@ RenderViewHostImpl* InterstitialPageImpl::CreateRenderViewHost() {
WebContentsView* InterstitialPageImpl::CreateWebContentsView() {
if (!enabled() || !create_view_)
- return NULL;
+ return nullptr;
WebContentsView* wcv =
static_cast<WebContentsImpl*>(web_contents())->GetView();
RenderWidgetHostViewBase* view =
@@ -1005,15 +1005,6 @@ void InterstitialPageImpl::GetScreenInfo(ScreenInfo* screen_info) {
web_contents_impl->GetView()->GetScreenInfo(screen_info);
}
-void InterstitialPageImpl::UpdateDeviceScaleFactor(double device_scale_factor) {
- WebContentsImpl* web_contents_impl =
- static_cast<WebContentsImpl*>(web_contents_);
- if (!web_contents_impl)
- return;
-
- web_contents_impl->UpdateDeviceScaleFactor(device_scale_factor);
-}
-
RenderWidgetHostInputEventRouter* InterstitialPageImpl::GetInputEventRouter() {
WebContentsImpl* web_contents_impl =
static_cast<WebContentsImpl*>(web_contents_);
diff --git a/chromium/content/browser/frame_host/interstitial_page_impl.h b/chromium/content/browser/frame_host/interstitial_page_impl.h
index 4af4ea8353b..250db67ba74 100644
--- a/chromium/content/browser/frame_host/interstitial_page_impl.h
+++ b/chromium/content/browser/frame_host/interstitial_page_impl.h
@@ -168,7 +168,6 @@ class CONTENT_EXPORT InterstitialPageImpl : public InterstitialPage,
void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override;
TextInputManager* GetTextInputManager() override;
void GetScreenInfo(content::ScreenInfo* screen_info) override;
- void UpdateDeviceScaleFactor(double device_scale_factor) override;
RenderWidgetHostInputEventRouter* GetInputEventRouter() override;
bool enabled() const { return enabled_; }
diff --git a/chromium/content/browser/frame_host/interstitial_page_impl_browsertest.cc b/chromium/content/browser/frame_host/interstitial_page_impl_browsertest.cc
index 7ec70faf0b3..b09aee92183 100644
--- a/chromium/content/browser/frame_host/interstitial_page_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/interstitial_page_impl_browsertest.cc
@@ -10,7 +10,7 @@
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/common/clipboard_messages.h"
+#include "content/common/clipboard.mojom.h"
#include "content/common/frame_messages.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"
@@ -22,6 +22,8 @@
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "ipc/message_filter.h"
+#include "ui/base/clipboard/clipboard_monitor.h"
+#include "ui/base/clipboard/clipboard_observer.h"
namespace content {
@@ -64,66 +66,29 @@ class TestInterstitialPageDelegate : public InterstitialPageDelegate {
}
};
-// A message filter that watches for WriteText and CommitWrite clipboard IPC
-// messages to make sure cut/copy is working properly. It will mark these events
-// as handled to prevent modification of the actual clipboard.
-class ClipboardMessageWatcher : public IPC::MessageFilter {
+class ClipboardChangedObserver : ui::ClipboardObserver {
public:
- explicit ClipboardMessageWatcher(InterstitialPage* interstitial) {
- interstitial->GetMainFrame()->GetProcess()->GetChannel()->AddFilter(this);
+ ClipboardChangedObserver() {
+ ui::ClipboardMonitor::GetInstance()->AddObserver(this);
}
- void InitWait() {
- DCHECK(!run_loop_);
- run_loop_.reset(new base::RunLoop());
+ ~ClipboardChangedObserver() override {
+ ui::ClipboardMonitor::GetInstance()->RemoveObserver(this);
}
- void WaitForWriteCommit() {
- DCHECK(run_loop_);
- run_loop_->Run();
- run_loop_.reset();
- }
-
- const std::string& last_text() const { return last_text_; }
-
- private:
- ~ClipboardMessageWatcher() override {}
-
- void OnWriteText(const std::string& text) { last_text_ = text; }
-
- void OnCommitWrite() {
- DCHECK(run_loop_);
- run_loop_->Quit();
+ void OnClipboardDataChanged() override {
+ DCHECK(!quit_closure_.is_null());
+ std::move(quit_closure_).Run();
}
- // IPC::MessageFilter:
- bool OnMessageReceived(const IPC::Message& message) override {
- if (!run_loop_)
- return false;
-
- if (message.type() == ClipboardHostMsg_WriteText::ID) {
- ClipboardHostMsg_WriteText::Param params;
- if (ClipboardHostMsg_WriteText::Read(&message, &params)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&ClipboardMessageWatcher::OnWriteText, this,
- base::UTF16ToUTF8(std::get<1>(params))));
- }
- return true;
- }
- if (message.type() == ClipboardHostMsg_CommitWrite::ID) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&ClipboardMessageWatcher::OnCommitWrite, this));
- return true;
- }
- return false;
+ void WaitForWriteCommit() {
+ base::RunLoop run_loop;
+ quit_closure_ = run_loop.QuitClosure();
+ run_loop.Run();
}
- std::unique_ptr<base::RunLoop> run_loop_;
- std::string last_text_;
-
- DISALLOW_COPY_AND_ASSIGN(ClipboardMessageWatcher);
+ private:
+ base::OnceClosure quit_closure_;
};
} // namespace
@@ -156,9 +121,6 @@ class InterstitialPageImplTest : public ContentBrowserTest {
->SetFocusedFrame(frame_tree->root(),
frame_tree->GetMainFrame()->GetSiteInstance());
- clipboard_message_watcher_ =
- new ClipboardMessageWatcher(interstitial_.get());
-
// Wait until page loads completely.
ASSERT_TRUE(WaitForRenderFrameReady(interstitial_->GetMainFrame()));
}
@@ -196,26 +158,24 @@ class InterstitialPageImplTest : public ContentBrowserTest {
"set_selection_change_listener()");
}
- std::string PerformCut() {
- clipboard_message_watcher_->InitWait();
+ void PerformCut() {
+ ClipboardChangedObserver clipboard_observer;
const base::string16 expected_title = base::UTF8ToUTF16("TEXT_CHANGED");
content::TitleWatcher title_watcher(shell()->web_contents(),
expected_title);
RenderFrameHostImpl* rfh =
static_cast<RenderFrameHostImpl*>(interstitial_->GetMainFrame());
rfh->GetRenderWidgetHost()->delegate()->Cut();
- clipboard_message_watcher_->WaitForWriteCommit();
+ clipboard_observer.WaitForWriteCommit();
EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
- return clipboard_message_watcher_->last_text();
}
- std::string PerformCopy() {
- clipboard_message_watcher_->InitWait();
+ void PerformCopy() {
+ ClipboardChangedObserver clipboard_observer;
RenderFrameHostImpl* rfh =
static_cast<RenderFrameHostImpl*>(interstitial_->GetMainFrame());
rfh->GetRenderWidgetHost()->delegate()->Copy();
- clipboard_message_watcher_->WaitForWriteCommit();
- return clipboard_message_watcher_->last_text();
+ clipboard_observer.WaitForWriteCommit();
}
void PerformPaste() {
@@ -241,24 +201,20 @@ class InterstitialPageImplTest : public ContentBrowserTest {
private:
std::unique_ptr<InterstitialPageImpl> interstitial_;
- scoped_refptr<ClipboardMessageWatcher> clipboard_message_watcher_;
DISALLOW_COPY_AND_ASSIGN(InterstitialPageImplTest);
};
-// Has errors on TSan. See https://crbug.com/631322.
-#if defined(THREAD_SANITIZER)
-#define MAYBE_Cut DISABLED_Cut
-#else
-#define MAYBE_Cut Cut
-#endif
-IN_PROC_BROWSER_TEST_F(InterstitialPageImplTest, MAYBE_Cut) {
+IN_PROC_BROWSER_TEST_F(InterstitialPageImplTest, Cut) {
+ BrowserTestClipboardScope clipboard;
SetUpInterstitialPage();
ASSERT_TRUE(CreateInputAndSetText("text-to-cut"));
ASSERT_TRUE(FocusInputAndSelectText());
- std::string clipboard_text = PerformCut();
+ PerformCut();
+ std::string clipboard_text;
+ clipboard.GetText(&clipboard_text);
EXPECT_EQ("text-to-cut", clipboard_text);
std::string input_text;
@@ -269,12 +225,15 @@ IN_PROC_BROWSER_TEST_F(InterstitialPageImplTest, MAYBE_Cut) {
}
IN_PROC_BROWSER_TEST_F(InterstitialPageImplTest, Copy) {
+ BrowserTestClipboardScope clipboard;
SetUpInterstitialPage();
ASSERT_TRUE(CreateInputAndSetText("text-to-copy"));
ASSERT_TRUE(FocusInputAndSelectText());
- std::string clipboard_text = PerformCopy();
+ PerformCopy();
+ std::string clipboard_text;
+ clipboard.GetText(&clipboard_text);
EXPECT_EQ("text-to-copy", clipboard_text);
std::string input_text;
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 08ab0345546..ceb21ec514f 100644
--- a/chromium/content/browser/frame_host/keep_alive_handle_factory.cc
+++ b/chromium/content/browser/frame_host/keep_alive_handle_factory.cc
@@ -16,10 +16,6 @@
namespace content {
-namespace {
-constexpr base::TimeDelta kDefaultTimeout = base::TimeDelta::FromSeconds(30);
-} // namespace
-
class KeepAliveHandleFactory::Context final : public base::RefCounted<Context> {
public:
explicit Context(RenderProcessHost* process_host)
@@ -41,10 +37,10 @@ class KeepAliveHandleFactory::Context final : public base::RefCounted<Context> {
void DetachLater() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- auto timeout = kDefaultTimeout;
+ auto timeout = timeout_;
int timeout_set_by_finch_in_sec = base::GetFieldTrialParamByFeatureAsInt(
features::kKeepAliveRendererForKeepaliveRequests, "timeout_in_sec",
- kDefaultTimeout.InSeconds());
+ timeout.InSeconds());
// Adopt only "reasonable" values.
if (timeout_set_by_finch_in_sec > 0 && timeout_set_by_finch_in_sec <= 60) {
timeout = base::TimeDelta::FromSeconds(timeout_set_by_finch_in_sec);
@@ -64,6 +60,8 @@ class KeepAliveHandleFactory::Context final : public base::RefCounted<Context> {
binding_set_.AddBinding(std::move(impl), std::move(request));
}
+ void set_timeout(base::TimeDelta timeout) { timeout_ = timeout; }
+
private:
friend class base::RefCounted<Context>;
~Context() { Detach(); }
@@ -71,6 +69,7 @@ class KeepAliveHandleFactory::Context final : public base::RefCounted<Context> {
mojo::StrongBindingSet<mojom::KeepAliveHandle> binding_set_;
const int process_id_;
bool detached_ = false;
+ base::TimeDelta timeout_;
base::WeakPtrFactory<Context> weak_ptr_factory_;
@@ -98,8 +97,12 @@ KeepAliveHandleFactory::~KeepAliveHandleFactory() {
}
void KeepAliveHandleFactory::Create(mojom::KeepAliveHandleRequest request) {
- context_->AddBinding(base::MakeUnique<KeepAliveHandleImpl>(context_),
+ context_->AddBinding(std::make_unique<KeepAliveHandleImpl>(context_),
std::move(request));
}
+void KeepAliveHandleFactory::SetTimeout(base::TimeDelta timeout) {
+ context_->set_timeout(timeout);
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/keep_alive_handle_factory.h b/chromium/content/browser/frame_host/keep_alive_handle_factory.h
index a03493e988f..226886ed6e6 100644
--- a/chromium/content/browser/frame_host/keep_alive_handle_factory.h
+++ b/chromium/content/browser/frame_host/keep_alive_handle_factory.h
@@ -15,9 +15,8 @@ class RenderProcessHost;
// A KeepAliveHandleFactory creates mojom::KeepAliveHandle. Each created
// handle prolongs the associated renderer's lifetime by using
// RenderProcessHost's KeepAliveRefCounts while alive.
-// When a certain time (default: 30sec) passes after the factory is destroyed,
-// all created handles are invalidated, which will result in render process
-// shutdown.
+// When a certain time passes after the factory is destroyed, all created
+// handles are invalidated, which will result in render process shutdown.
class KeepAliveHandleFactory final {
public:
// |process_host->DisableKeepAliveRefCount()| must be false.
@@ -26,6 +25,9 @@ class KeepAliveHandleFactory final {
void Create(mojom::KeepAliveHandleRequest request);
+ // Sets the timeout after which all created handles will be invalidated.
+ void SetTimeout(base::TimeDelta timeout);
+
private:
class KeepAliveHandleImpl;
class Context;
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 fd45a4876fa..24042867287 100644
--- a/chromium/content/browser/frame_host/mixed_content_navigation_throttle.cc
+++ b/chromium/content/browser/frame_host/mixed_content_navigation_throttle.cc
@@ -24,9 +24,9 @@
#include "url/url_constants.h"
#include "url/url_util.h"
-namespace {
+namespace content {
-using namespace content;
+namespace {
// Should return the same value as SchemeRegistry::shouldTreatURLSchemeAsSecure.
bool IsSecureScheme(const std::string& scheme) {
@@ -39,32 +39,15 @@ bool ShouldTreatURLSchemeAsCORSEnabled(const GURL& url) {
return base::ContainsValue(url::GetCORSEnabledSchemes(), url.scheme());
}
-// Should return the same value as SecurityOrigin::isSecure.
-// TODO(carlosk): secure origin checks don't match between content and Blink
-// hence this implementation here instead of a direct call to IsOriginSecure (in
-// origin_util.cc). See https://crbug.com/629059.
-bool IsOriginSecure(const GURL& url) {
- if (IsSecureScheme(url.scheme()))
- return true;
-
- if (url.SchemeIsFileSystem() || url.SchemeIsBlob()) {
- // Should use inner URL.
- url::Origin origin(url);
- if (IsSecureScheme(origin.scheme()))
- return true;
- }
-
- return IsOriginWhiteListedTrustworthy(url::Origin(url));
-}
-
// Should return the same value as the resource URL checks assigned to
// |isAllowed| made inside MixedContentChecker::isMixedContent.
bool IsUrlPotentiallySecure(const GURL& url) {
// blob: and filesystem: URLs never hit the network, and access is restricted
// to same-origin contexts, so they are not blocked.
- bool is_secure =
- url.SchemeIs(url::kBlobScheme) || url.SchemeIs(url::kFileSystemScheme) ||
- IsOriginSecure(url) || IsPotentiallyTrustworthyOrigin(url::Origin(url));
+ bool is_secure = url.SchemeIs(url::kBlobScheme) ||
+ url.SchemeIs(url::kFileSystemScheme) ||
+ IsOriginSecure(url) ||
+ IsPotentiallyTrustworthyOrigin(url::Origin::Create(url));
// TODO(mkwst): Remove this once the following draft is implemented:
// https://tools.ietf.org/html/draft-west-let-localhost-be-localhost-03. See:
@@ -107,8 +90,6 @@ void UpdateRendererOnMixedContentFound(NavigationHandleImpl* navigation_handle,
} // namespace
-namespace content {
-
// static
std::unique_ptr<NavigationThrottle>
MixedContentNavigationThrottle::CreateThrottleForNavigation(
@@ -360,7 +341,7 @@ void MixedContentNavigationThrottle::ReportBasicMixedContentFeatures(
bool MixedContentNavigationThrottle::IsMixedContentForTesting(
const GURL& origin_url,
const GURL& url) {
- const url::Origin origin(origin_url);
+ const url::Origin origin = url::Origin::Create(origin_url);
return !IsUrlPotentiallySecure(url) &&
DoesOriginSchemeRestrictMixedContent(origin);
}
diff --git a/chromium/content/browser/frame_host/navigation_controller_android.cc b/chromium/content/browser/frame_host/navigation_controller_android.cc
index e1b224fb1e2..c016daaaf7c 100644
--- a/chromium/content/browser/frame_host/navigation_controller_android.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_android.cc
@@ -31,7 +31,8 @@ using base::android::ScopedJavaLocalRef;
namespace {
// static
-static base::android::ScopedJavaLocalRef<jobject> CreateJavaNavigationEntry(
+static base::android::ScopedJavaLocalRef<jobject>
+JNI_NavigationControllerImpl_CreateJavaNavigationEntry(
JNIEnv* env,
content::NavigationEntry* entry,
int index) {
@@ -56,12 +57,15 @@ static base::android::ScopedJavaLocalRef<jobject> CreateJavaNavigationEntry(
entry->GetTransitionType());
}
-static void AddNavigationEntryToHistory(JNIEnv* env,
- const JavaRef<jobject>& history,
- content::NavigationEntry* entry,
- int index) {
+static void JNI_NavigationControllerImpl_AddNavigationEntryToHistory(
+ JNIEnv* env,
+ const JavaRef<jobject>& history,
+ content::NavigationEntry* entry,
+ int index) {
content::Java_NavigationControllerImpl_addToNavigationHistory(
- env, history, CreateJavaNavigationEntry(env, entry, index));
+ env, history,
+ JNI_NavigationControllerImpl_CreateJavaNavigationEntry(env, entry,
+ index));
}
} // namespace
@@ -259,7 +263,7 @@ jint NavigationControllerAndroid::GetNavigationHistory(
// Iterate through navigation entries to populate the list
int count = navigation_controller_->GetEntryCount();
for (int i = 0; i < count; ++i) {
- AddNavigationEntryToHistory(
+ JNI_NavigationControllerImpl_AddNavigationEntryToHistory(
env, history, navigation_controller_->GetEntryAtIndex(i), i);
}
@@ -282,7 +286,7 @@ void NavigationControllerAndroid::GetDirectedNavigationHistory(
if (num_added >= max_entries)
break;
- AddNavigationEntryToHistory(
+ JNI_NavigationControllerImpl_AddNavigationEntryToHistory(
env, history, navigation_controller_->GetEntryAtIndex(i), i);
num_added++;
}
@@ -348,7 +352,8 @@ NavigationControllerAndroid::GetEntryAtIndex(JNIEnv* env,
content::NavigationEntry* entry =
navigation_controller_->GetEntryAtIndex(index);
- return CreateJavaNavigationEntry(env, entry, index);
+ return JNI_NavigationControllerImpl_CreateJavaNavigationEntry(env, entry,
+ index);
}
base::android::ScopedJavaLocalRef<jobject>
@@ -359,7 +364,7 @@ NavigationControllerAndroid::GetPendingEntry(JNIEnv* env,
if (!entry)
return base::android::ScopedJavaLocalRef<jobject>();
- return CreateJavaNavigationEntry(
+ return JNI_NavigationControllerImpl_CreateJavaNavigationEntry(
env, entry, navigation_controller_->GetPendingEntryIndex());
}
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.cc b/chromium/content/browser/frame_host/navigation_controller_impl.cc
index bebde463db6..aec0212366f 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.cc
@@ -76,6 +76,7 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/url_utils.h"
#include "media/base/mime_util.h"
#include "net/base/escape.h"
#include "skia/ext/platform_canvas.h"
@@ -138,6 +139,10 @@ bool ShouldTreatNavigationAsReload(const NavigationEntry* entry) {
if (!entry)
return false;
+ // Skip navigations initiated by external applications.
+ if (entry->GetTransitionType() & ui::PAGE_TRANSITION_FROM_API)
+ return false;
+
// We treat (PAGE_TRANSITION_RELOAD | PAGE_TRANSITION_FROM_ADDRESS_BAR),
// PAGE_TRANSITION_TYPED or PAGE_TRANSITION_LINK transitions as navigations
// which should be treated as reloads.
@@ -197,12 +202,9 @@ std::unique_ptr<NavigationEntry> NavigationController::CreateNavigationEntry(
&loaded_url, browser_context, &reverse_on_redirect);
NavigationEntryImpl* entry = new NavigationEntryImpl(
- NULL, // The site instance for tabs is sent on navigation
- // (WebContents::GetSiteInstance).
- loaded_url,
- referrer,
- base::string16(),
- transition,
+ nullptr, // The site instance for tabs is sent on navigation
+ // (WebContents::GetSiteInstance).
+ loaded_url, referrer, base::string16(), transition,
is_renderer_initiated);
entry->SetVirtualURL(dest_url);
entry->set_user_typed_url(dest_url);
@@ -309,7 +311,7 @@ void NavigationControllerImpl::Reload(ReloadType reload_type,
return;
}
- NavigationEntryImpl* entry = NULL;
+ NavigationEntryImpl* entry = nullptr;
int current_index = -1;
// If we are reloading the initial navigation, just use the current
@@ -516,7 +518,7 @@ int NavigationControllerImpl::GetCurrentEntryIndex() const {
NavigationEntryImpl* NavigationControllerImpl::GetLastCommittedEntry() const {
if (last_committed_entry_index_ == -1)
- return NULL;
+ return nullptr;
return entries_[last_committed_entry_index_].get();
}
@@ -861,7 +863,6 @@ bool NavigationControllerImpl::RendererDidNavigate(
navigation_handle);
break;
case NAVIGATION_TYPE_EXISTING_PAGE:
- details->did_replace_entry = details->is_same_document;
RendererDidNavigateToExistingPage(rfh, params, details->is_same_document,
was_restored, navigation_handle);
break;
@@ -924,12 +925,10 @@ bool NavigationControllerImpl::RendererDidNavigate(
active_entry->GetFrameEntry(rfh->frame_tree_node());
if (frame_entry && frame_entry->site_instance() != rfh->GetSiteInstance())
frame_entry = nullptr;
- // Update the frame-specific PageState and RedirectChain
- // We may not find a frame_entry in some cases; ignore the PageState if so.
+ // Make sure we've updated the PageState in one of the helper methods.
// TODO(creis): Remove the "if" once https://crbug.com/522193 is fixed.
if (frame_entry) {
- frame_entry->SetPageState(params.page_state);
- frame_entry->set_redirect_chain(params.redirects);
+ DCHECK(params.page_state == frame_entry->page_state());
}
// Use histogram to track memory impact of redirect chain because it's now
@@ -1003,18 +1002,6 @@ NavigationType NavigationControllerImpl::ClassifyNavigation(
return NAVIGATION_TYPE_NEW_SUBFRAME;
}
- // Cross-process location.replace navigations should be classified as New with
- // replacement rather than ExistingPage, since it is not safe to reuse the
- // NavigationEntry.
- // TODO(creis): Have the renderer classify location.replace as
- // did_create_new_entry for all cases and eliminate this special case. This
- // requires updating several test expectations. See https://crbug.com/596707.
- if (!rfh->GetParent() && GetLastCommittedEntry() &&
- GetLastCommittedEntry()->site_instance() != rfh->GetSiteInstance() &&
- params.should_replace_current_entry) {
- return NAVIGATION_TYPE_NEW_PAGE;
- }
-
// We only clear the session history when navigating to a new page.
DCHECK(!params.history_list_was_cleared);
@@ -1041,8 +1028,7 @@ NavigationType NavigationControllerImpl::ClassifyNavigation(
if (!last_committed)
return NAVIGATION_TYPE_NAV_IGNORE;
- // This is history.replaceState(), history.reload(), or a client-side
- // redirect.
+ // This is history.replaceState() or history.reload().
return NAVIGATION_TYPE_EXISTING_PAGE;
}
@@ -1117,7 +1103,9 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage(
FrameNavigationEntry* frame_entry = new FrameNavigationEntry(
rfh->frame_tree_node()->unique_name(), params.item_sequence_number,
params.document_sequence_number, rfh->GetSiteInstance(), nullptr,
- params.url, params.referrer, params.method, params.post_id);
+ params.url, params.referrer, params.redirects, params.page_state,
+ params.method, params.post_id);
+
new_entry = GetLastCommittedEntry()->CloneAndReplace(
frame_entry, true, rfh->frame_tree_node(),
delegate_->GetFrameTree()->root());
@@ -1164,7 +1152,7 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage(
new_entry = pending_entry_->Clone();
update_virtual_url = new_entry->update_virtual_url_with_url();
- new_entry->GetSSL() = handle->ssl_status();
+ new_entry->GetSSL() = SSLStatus(handle->GetSSLInfo());
if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
handle->GetNetErrorCode() == net::OK) {
@@ -1192,7 +1180,7 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage(
// to show chrome://bookmarks/#1 when the bookmarks webui extension changes
// the URL.
update_virtual_url = needs_update;
- new_entry->GetSSL() = handle->ssl_status();
+ new_entry->GetSSL() = SSLStatus(handle->GetSSLInfo());
if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
handle->GetNetErrorCode() == net::OK) {
@@ -1223,6 +1211,8 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage(
frame_entry->set_frame_unique_name(rfh->frame_tree_node()->unique_name());
frame_entry->set_item_sequence_number(params.item_sequence_number);
frame_entry->set_document_sequence_number(params.document_sequence_number);
+ frame_entry->set_redirect_chain(params.redirects);
+ frame_entry->SetPageState(params.page_state);
frame_entry->set_method(params.method);
frame_entry->set_post_id(params.post_id);
@@ -1259,9 +1249,6 @@ void NavigationControllerImpl::RendererDidNavigateToExistingPage(
// We should only get here for main frame navigations.
DCHECK(!rfh->GetParent());
- // TODO(creis): Classify location.replace as NEW_PAGE instead of EXISTING_PAGE
- // in https://crbug.com/596707.
-
NavigationEntryImpl* entry;
if (params.intended_as_new_entry) {
// This was intended as a new entry but the pending entry was lost in the
@@ -1271,7 +1258,7 @@ void NavigationControllerImpl::RendererDidNavigateToExistingPage(
// If this is a same document navigation, then there's no SSLStatus in the
// NavigationHandle so don't overwrite the existing entry's SSLStatus.
if (!is_same_document)
- entry->GetSSL() = handle->ssl_status();
+ entry->GetSSL() = SSLStatus(handle->GetSSLInfo());
if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
handle->GetNetErrorCode() == net::OK) {
@@ -1305,12 +1292,14 @@ void NavigationControllerImpl::RendererDidNavigateToExistingPage(
entry->GetSSL() = last_entry->GetSSL();
}
} else {
- // When restoring a tab, the serialized NavigationEntry doesn't have the
- // SSL state.
- // Only copy in the restore case since this code path can be taken during
- // navigation. See http://crbug.com/727892
- if (was_restored)
- entry->GetSSL() = handle->ssl_status();
+ // In rapid back/forward navigations |handle| sometimes won't have a cert
+ // (http://crbug.com/727892). So we use the handle's cert if it exists,
+ // otherwise we only reuse the existing cert if the origins match.
+ if (handle->GetSSLInfo().is_valid()) {
+ entry->GetSSL() = SSLStatus(handle->GetSSLInfo());
+ } else if (entry->GetURL().GetOrigin() != handle->GetURL().GetOrigin()) {
+ entry->GetSSL() = SSLStatus();
+ }
}
if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
@@ -1339,14 +1328,14 @@ void NavigationControllerImpl::RendererDidNavigateToExistingPage(
}
} else {
// This is renderer-initiated. The only kinds of renderer-initated
- // navigations that are EXISTING_PAGE are reloads and location.replace,
+ // navigations that are EXISTING_PAGE are reloads and history.replaceState,
// which land us at the last committed entry.
entry = GetLastCommittedEntry();
// If this is a same document navigation, then there's no SSLStatus in the
// NavigationHandle so don't overwrite the existing entry's SSLStatus.
if (!is_same_document)
- entry->GetSSL() = handle->ssl_status();
+ entry->GetSSL() = SSLStatus(handle->GetSSLInfo());
if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
handle->GetNetErrorCode() == net::OK) {
@@ -1438,7 +1427,7 @@ void NavigationControllerImpl::RendererDidNavigateToSamePage(
// If a user presses enter in the omnibox and the server redirects, the URL
// might change (but it's still considered a SAME_PAGE navigation). So we must
// update the SSL status.
- existing_entry->GetSSL() = handle->ssl_status();
+ existing_entry->GetSSL() = SSLStatus(handle->GetSSLInfo());
if (existing_entry->GetURL().SchemeIs(url::kHttpsScheme) &&
!rfh->GetParent() && handle->GetNetErrorCode() == net::OK) {
@@ -1479,7 +1468,9 @@ void NavigationControllerImpl::RendererDidNavigateNewSubframe(
scoped_refptr<FrameNavigationEntry> frame_entry(new FrameNavigationEntry(
rfh->frame_tree_node()->unique_name(), params.item_sequence_number,
params.document_sequence_number, rfh->GetSiteInstance(), nullptr,
- params.url, params.referrer, params.method, params.post_id));
+ params.url, params.referrer, params.redirects, params.page_state,
+ params.method, params.post_id));
+
std::unique_ptr<NavigationEntryImpl> new_entry =
GetLastCommittedEntry()->CloneAndReplace(
frame_entry.get(), is_same_document, rfh->frame_tree_node(),
@@ -1801,7 +1792,7 @@ NavigationControllerImpl::GetSessionStorageNamespace(SiteInstance* instance) {
SessionStorageNamespace*
NavigationControllerImpl::GetDefaultSessionStorageNamespace() {
// TODO(ajwong): Remove if statement in GetSessionStorageNamespace().
- return GetSessionStorageNamespace(NULL);
+ return GetSessionStorageNamespace(nullptr);
}
const SessionStorageNamespaceMap&
@@ -2105,7 +2096,7 @@ void NavigationControllerImpl::FindFramesToNavigate(
if (old_item &&
new_item->document_sequence_number() ==
old_item->document_sequence_number() &&
- !frame->current_frame_host()->last_committed_url().is_empty()) {
+ !frame->current_frame_host()->GetLastCommittedURL().is_empty()) {
same_document_loads->push_back(std::make_pair(frame, new_item));
// TODO(avi, creis): This is a bug; we should not return here. Rather, we
@@ -2259,7 +2250,7 @@ int NavigationControllerImpl::GetEntryIndexWithUniqueID(
NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const {
if (transient_entry_index_ == -1)
- return NULL;
+ return nullptr;
return entries_[transient_entry_index_].get();
}
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 b37577a034e..69cdeea08be 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -45,6 +45,7 @@
#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/controllable_http_response.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
@@ -63,9 +64,6 @@ static const char kAddNamedFrameScript[] =
"var f = document.createElement('iframe');"
"f.name = 'foo-frame-name';"
"document.body.appendChild(f);";
-static const char kAddFrameScript[] =
- "var f = document.createElement('iframe');"
- "document.body.appendChild(f);";
static const char kRemoveFrameScript[] =
"var f = document.querySelector('iframe');"
"f.parentNode.removeChild(f);";
@@ -633,12 +631,20 @@ class FrameNavigateParamsCapturer : public WebContentsObserver {
return is_same_documents_[0];
}
+ bool did_replace_entry() {
+ EXPECT_EQ(1U, did_replace_entries_.size());
+ return did_replace_entries_[0];
+ }
+
const std::vector<ui::PageTransition>& transitions() { return transitions_; }
const std::vector<GURL>& urls() { return urls_; }
const std::vector<NavigationType>& navigation_types() {
return navigation_types_;
}
const std::vector<bool>& is_same_documents() { return is_same_documents_; }
+ const std::vector<bool>& did_replace_entries() {
+ return did_replace_entries_;
+ }
private:
void DidFinishNavigation(NavigationHandle* navigation_handle) override {
@@ -655,6 +661,7 @@ class FrameNavigateParamsCapturer : public WebContentsObserver {
static_cast<NavigationHandleImpl*>(navigation_handle)
->navigation_type());
is_same_documents_.push_back(navigation_handle->IsSameDocument());
+ did_replace_entries_.push_back(navigation_handle->DidReplaceEntry());
if (!navigations_remaining_ &&
(!web_contents()->IsLoading() || !wait_for_load_))
message_loop_runner_->Quit();
@@ -678,6 +685,7 @@ class FrameNavigateParamsCapturer : public WebContentsObserver {
std::vector<GURL> urls_;
std::vector<NavigationType> navigation_types_;
std::vector<bool> is_same_documents_;
+ std::vector<bool> did_replace_entries_;
// The MessageLoopRunner used to spin the message loop.
scoped_refptr<MessageLoopRunner> message_loop_runner_;
@@ -990,16 +998,15 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_EQ(2, controller.GetEntryCount());
}
- // Navigate again to the page that fails to load. It must result in an error
- // page, the EXISTING_PAGE navigation type, and no addition to the history
- // list. We do not use SAME_PAGE here; that case only differs in that it
- // clears the pending entry, and there is no pending entry after a load
- // failure.
+ // Navigate again to the page that fails to load. It results in an error page,
+ // the NEW_PAGE navigation type with replacement, and no addition to the
+ // history list.
{
FrameNavigateParamsCapturer capturer(root);
NavigateFrameToURL(root, error_url);
capturer.Wait();
- EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.navigation_type());
+ EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, capturer.navigation_type());
+ EXPECT_TRUE(capturer.did_replace_entry());
NavigationEntry* entry = controller.GetLastCommittedEntry();
EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
EXPECT_EQ(2, controller.GetEntryCount());
@@ -1010,14 +1017,12 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_EQ(3, controller.GetEntryCount());
// ... and replace it with a failed load.
- // TODO(creis): Make this be NEW_PAGE along with the other location.replace
- // cases. There isn't much impact to having this be EXISTING_PAGE for now.
- // See https://crbug.com/596707.
{
FrameNavigateParamsCapturer capturer(root);
RendererLocationReplace(shell(), error_url);
capturer.Wait();
- EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.navigation_type());
+ EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, capturer.navigation_type());
+ EXPECT_TRUE(capturer.did_replace_entry());
NavigationEntry* entry = controller.GetLastCommittedEntry();
EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
EXPECT_EQ(3, controller.GetEntryCount());
@@ -1036,6 +1041,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
RendererLocationReplace(shell(), error_url);
capturer.Wait();
EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, capturer.navigation_type());
+ EXPECT_TRUE(capturer.did_replace_entry());
NavigationEntry* entry = controller.GetLastCommittedEntry();
EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
EXPECT_EQ(4, controller.GetEntryCount());
@@ -1125,21 +1131,20 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_TRUE(capturer.is_same_document());
}
- if (AreAllSitesIsolatedForTesting()) {
- // Cross-process location.replace().
- FrameNavigateParamsCapturer capturer(root);
- GURL frame_url(embedded_test_server()->GetURL(
- "foo.com", "/navigation_controller/simple_page_1.html"));
- std::string script = "location.replace('" + frame_url.spec() + "')";
- EXPECT_TRUE(ExecuteScript(root, script));
- capturer.Wait();
- EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
- capturer.transition(),
- ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK |
- ui::PAGE_TRANSITION_CLIENT_REDIRECT)));
- EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, capturer.navigation_type());
- EXPECT_FALSE(capturer.is_same_document());
- }
+ // location.replace().
+ FrameNavigateParamsCapturer capturer(root);
+ GURL frame_url(embedded_test_server()->GetURL(
+ "foo.com", "/navigation_controller/simple_page_1.html"));
+ std::string script = "location.replace('" + frame_url.spec() + "')";
+ EXPECT_TRUE(ExecuteScript(root, script));
+ capturer.Wait();
+ EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
+ capturer.transition(),
+ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK |
+ ui::PAGE_TRANSITION_CLIENT_REDIRECT)));
+ EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, capturer.navigation_type());
+ EXPECT_TRUE(capturer.did_replace_entry());
+ EXPECT_FALSE(capturer.is_same_document());
}
// Verify that navigations for NAVIGATION_TYPE_EXISTING_PAGE are correctly
@@ -1267,8 +1272,6 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
{
// location.replace().
- // TODO(creis): Change this to be NEW_PAGE with replacement in
- // https://crbug.com/596707.
FrameNavigateParamsCapturer capturer(root);
GURL frame_url(embedded_test_server()->GetURL(
"/navigation_controller/simple_page_1.html"));
@@ -1279,13 +1282,29 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
capturer.transition(),
ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK |
ui::PAGE_TRANSITION_CLIENT_REDIRECT)));
- EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.navigation_type());
+ EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, capturer.navigation_type());
+ EXPECT_TRUE(capturer.did_replace_entry());
EXPECT_FALSE(capturer.is_same_document());
}
// Now, various same document navigations.
{
+ // Same-document location.replace().
+ FrameNavigateParamsCapturer capturer(root);
+ std::string script = "location.replace('#foo')";
+ EXPECT_TRUE(ExecuteScript(root, script));
+ capturer.Wait();
+ EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
+ capturer.transition(),
+ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK |
+ ui::PAGE_TRANSITION_CLIENT_REDIRECT)));
+ EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.navigation_type());
+ EXPECT_TRUE(capturer.did_replace_entry());
+ EXPECT_TRUE(capturer.is_same_document());
+ }
+
+ {
// history.replaceState().
FrameNavigateParamsCapturer capturer(root);
std::string script =
@@ -1657,7 +1676,8 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
capturer.transitions()[1],
ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK |
ui::PAGE_TRANSITION_CLIENT_REDIRECT)));
- EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.navigation_types()[1]);
+ EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, capturer.navigation_types()[1]);
+ EXPECT_TRUE(capturer.did_replace_entries()[1]);
}
}
@@ -1961,8 +1981,9 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// the initial blank page of an iframe with no committed entry. Prevents
// regression of https://crbug.com/600743.
// Flaky test: See https://crbug.com/610801
-IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
- DISABLED_FrameNavigationEntry_NoCommitNestedAutoSubframe) {
+IN_PROC_BROWSER_TEST_F(
+ NavigationControllerBrowserTest,
+ DISABLED_FrameNavigationEntry_NoCommitNestedAutoSubframe) {
GURL main_url(embedded_test_server()->GetURL(
"/navigation_controller/simple_page_1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -3020,13 +3041,12 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
EXPECT_EQ(entry1, controller.GetLastCommittedEntry());
- // The entry should have both the stale FrameNavigationEntry with the old
- // name and the new FrameNavigationEntry for the fallback navigation.
- ASSERT_EQ(2U, entry1->root_node()->children.size());
+ // There should be only 1 FNE, because when the child frame is dynamically
+ // created or recreated from javascript, it's FNE will be removed when the
+ // frame is removed.
+ ASSERT_EQ(1U, entry1->root_node()->children.size());
EXPECT_EQ("data",
entry1->root_node()->children[0]->frame_entry->url().scheme());
- EXPECT_EQ("data",
- entry1->root_node()->children[1]->frame_entry->url().scheme());
// The iframe commit should have been classified AUTO_SUBFRAME and not
// NEW_SUBFRAME, so we should still be able to go forward.
@@ -3177,8 +3197,13 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
EXPECT_EQ(entry, controller.GetLastCommittedEntry());
- // The entry should have FrameNavigationEntries for the subframes.
+ // There is only 1 child frame in the frame tree and only 1 FNE, because when
+ // the child frame is dynamically created or recreated from javascript, it's
+ // FNE will be removed when the frame is removed.
+ ASSERT_EQ(1U, root->child_count());
ASSERT_EQ(1U, entry->root_node()->children.size());
+
+ // The entry should have FrameNavigationEntries for the subframes.
EXPECT_EQ(blank_url, entry->root_node()->children[0]->frame_entry->url());
EXPECT_EQ(inner_url,
entry->root_node()->children[0]->children[0]->frame_entry->url());
@@ -3195,13 +3220,15 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
}
// Verify that we correctly load a nested iframe created by an injected iframe
-// srcdoc if we go back and recreate the frames. Also verify that form values
-// are correctly restored for forms within srcdoc frames, unlike forms injected
-// into about:blank pages (as tested in
-// FrameNavigationEntry_RecreatedInjectedBlankSubframe).
+// srcdoc if we go back and recreate the frames.
+//
+// This test is similar to
+// NavigationControllerBrowserTest.FrameNavigationEntry_RecreatedInjectedBlankSubframe
+// and RenderFrameHostManagerTest.RestoreSubframeFileAccessForHistoryNavigation.
//
// This test worked before and after the fix for https://crbug.com/657896, but
-// it failed with a preliminary version of the fix.
+// it failed with a preliminary version of the fix (see also
+// https://crbug.com/657896#c9).
IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
FrameNavigationEntry_RecreatedInjectedSrcdocSubframe) {
// 1. Start on a page that injects a nested iframe srcdoc which contains a
@@ -3270,21 +3297,32 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
EXPECT_EQ(entry, controller.GetLastCommittedEntry());
- // The entry should have FrameNavigationEntries for the subframes.
+ // There is only 1 child frame in the frame tree and only 1 FNE, because when
+ // the child frame is dynamically created or recreated from javascript, it's
+ // FNE will be removed when the frame is removed.
+ ASSERT_EQ(1U, root->child_count());
ASSERT_EQ(1U, entry->root_node()->children.size());
+
+ // The entry should have FrameNavigationEntries for the subframes.
EXPECT_EQ(srcdoc_url, entry->root_node()->children[0]->frame_entry->url());
EXPECT_EQ(inner_url,
entry->root_node()->children[0]->children[0]->frame_entry->url());
- // With injected iframe srcdoc pages, we do restore form values from
- // PageState.
- std::string form_value;
+ // With *injected* iframe srcdoc pages, we don't restore form values from
+ // PageState (because iframes injected by javascript always get a fresh,
+ // random unique name each time they are created or recreated - see
+ // https://crbug.com/500260).
+ //
+ // Note that restoring form values in srcdoc frames created via static html is
+ // expected to work and is tested by
+ // RenderFrameHostManagerTest.RestoreSubframeFileAccessForHistoryNavigation.
+ std::string form_value = "fail";
EXPECT_TRUE(
ExecuteScriptAndExtractString(root->child_at(0)->child_at(0),
"window.domAutomationController.send("
"document.getElementById('itext').value);",
&form_value));
- EXPECT_EQ("modified", form_value);
+ EXPECT_EQ("", form_value);
}
// Verify that we can load about:blank in an iframe when going back to a page,
@@ -3928,8 +3966,8 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
subframe->current_frame_host()->GetSiteInstance());
FrameNavigationEntry* subframe_entry =
controller.GetLastCommittedEntry()->GetFrameEntry(subframe);
- std::string unnamed_subframe_name = "<!--framePath //<!--frame0-->-->";
- EXPECT_EQ(unnamed_subframe_name, subframe_entry->frame_unique_name());
+ EXPECT_THAT(subframe_entry->frame_unique_name(),
+ testing::HasSubstr("dynamicFrame"));
// 3. Add a named subframe.
{
@@ -3952,8 +3990,8 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
foo_subframe->current_frame_host()->GetSiteInstance());
FrameNavigationEntry* foo_subframe_entry =
controller.GetLastCommittedEntry()->GetFrameEntry(foo_subframe);
- std::string named_subframe_name = "foo";
- EXPECT_EQ(named_subframe_name, foo_subframe_entry->frame_unique_name());
+ EXPECT_THAT(foo_subframe_entry->frame_unique_name(),
+ testing::HasSubstr("dynamicFrame"));
// 4. Navigating in the subframes cross-process shouldn't change their names.
// TODO(creis): Fix the unnamed case in https://crbug.com/502317.
@@ -3975,7 +4013,8 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
foo_subframe_entry =
controller.GetLastCommittedEntry()->GetFrameEntry(foo_subframe);
- EXPECT_EQ(named_subframe_name, foo_subframe_entry->frame_unique_name());
+ EXPECT_THAT(foo_subframe_entry->frame_unique_name(),
+ testing::HasSubstr("dynamicFrame"));
}
// Ensure we don't crash when cloning a named window. This happened in
@@ -4903,7 +4942,8 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, ReloadOriginalRequest) {
capturer.transition(),
ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK |
ui::PAGE_TRANSITION_CLIENT_REDIRECT)));
- EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.navigation_type());
+ EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, capturer.navigation_type());
+ EXPECT_TRUE(capturer.did_replace_entry());
}
// Modify an entry in the session history and reload the original request.
@@ -5944,8 +5984,16 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, PostViaOpenUrlMsg) {
// Tests that inserting a named subframe into the FrameTree clears any
// previously existing FrameNavigationEntry objects for the same name.
// See https://crbug.com/628677.
+// Crashes inconsistently on windows only: https://crbug.com/783806.
+#if defined(OS_WIN)
+#define MAYBE_EnsureFrameNavigationEntriesClearedOnMismatch \
+ DISABLED_EnsureFrameNavigationEntriesClearedOnMismatch
+#else
+#define MAYBE_EnsureFrameNavigationEntriesClearedOnMismatch \
+ EnsureFrameNavigationEntriesClearedOnMismatch
+#endif
IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
- EnsureFrameNavigationEntriesClearedOnMismatch) {
+ MAYBE_EnsureFrameNavigationEntriesClearedOnMismatch) {
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
NavigationControllerImpl& controller = web_contents->GetController();
@@ -5966,16 +6014,17 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_NE(nullptr, root_entry);
EXPECT_EQ("", root_entry->frame_unique_name());
EXPECT_EQ(3U, entry->root_node()->children.size());
+ EXPECT_EQ(2U, entry->root_node()->children[0]->children.size());
// * The first child of the main frame is named and has two more children.
- FrameTreeNode* frame = root->child_at(0);
+ FrameTreeNode* frame = root->child_at(0)->child_at(0);
NavigationEntryImpl::TreeNode* tree_node = entry->GetTreeNode(frame);
FrameNavigationEntry* frame_entry = entry->GetFrameEntry(frame);
EXPECT_NE(nullptr, tree_node);
EXPECT_NE(nullptr, frame_entry);
- EXPECT_EQ("1-1-name", frame_entry->frame_unique_name());
+ EXPECT_EQ("1-1: 2-1: name", frame_entry->frame_unique_name());
EXPECT_EQ(frame_entry, tree_node->frame_entry);
- EXPECT_EQ(2U, tree_node->children.size());
+ EXPECT_EQ(0U, tree_node->children.size());
}
// Removing the first child of the main frame should remove the corresponding
@@ -5989,6 +6038,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
FrameNavigationEntry* root_entry = entry->GetFrameEntry(root);
EXPECT_NE(nullptr, root_entry);
EXPECT_EQ(3U, entry->root_node()->children.size());
+ EXPECT_EQ(2U, entry->root_node()->children[0]->children.size());
// Since child count is known only to the FrameNavigationEntry::TreeNode,
// traverse the root entry to find the correct one matching the
@@ -5999,15 +6049,14 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// Traverse the FrameNavigationEntry tree, since the FrameTreeNode has
// been deleted and cannot be used for looking up the TreeNode.
NavigationEntryImpl::TreeNode* tree_node = nullptr;
- for (auto& node : entry->root_node()->children) {
- if (node->frame_entry->frame_unique_name() == "1-1-name") {
+ for (auto& node : entry->root_node()->children[0]->children) {
+ if (node->frame_entry->frame_unique_name() == "1-1: 2-1: name") {
tree_node = node.get();
break;
}
}
-
EXPECT_TRUE(tree_node);
- EXPECT_EQ(2U, tree_node->children.size());
+ EXPECT_EQ(0U, tree_node->children.size());
}
// Now, insert a frame with the same name as the previously removed one
@@ -6018,68 +6067,25 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
std::string add_matching_name_frame_script =
"var f = document.createElement('iframe');"
"f.name = '1-1-name';"
+ "f.src = '1-1.html';"
"document.body.appendChild(f);";
+ TestNavigationObserver observer(web_contents, 1);
EXPECT_TRUE(ExecuteScript(subframe, add_matching_name_frame_script));
EXPECT_EQ(1U, subframe->child_count());
+ observer.Wait();
// Verify that the FrameNavigationEntry for the original frame is now gone.
{
FrameNavigationEntry* root_entry = entry->GetFrameEntry(root);
EXPECT_NE(nullptr, root_entry);
- EXPECT_EQ(2U, entry->root_node()->children.size());
- }
-}
-
-// Tests that sending a PageState update from a named subframe does not get
-// incorrectly set on previously existing FrameNavigationEntry for the same
-// name. It is similar to EnsureFrameNavigationEntriesClearedOnMismatch, but
-// doesn't navigate the iframes to real URLs when added to the DOM.
-// See https://crbug.com/628677.
-IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
- EnsureFrameNavigationEntriesClearedOnMismatchNoSrc) {
- WebContentsImpl* web_contents =
- static_cast<WebContentsImpl*>(shell()->web_contents());
- FrameTreeNode* root = web_contents->GetFrameTree()->root();
-
- GURL start_url(embedded_test_server()->GetURL("/title1.html"));
- EXPECT_TRUE(NavigateToURL(shell(), start_url));
- NavigationEntryImpl* nav_entry =
- web_contents->GetController().GetLastCommittedEntry();
-
- EXPECT_TRUE(ExecuteScript(root, kAddNamedFrameScript));
- EXPECT_EQ(1U, root->child_count());
- EXPECT_EQ("foo-frame-name", root->child_at(0)->frame_name());
-
- EXPECT_TRUE(ExecuteScript(root, kRemoveFrameScript));
- EXPECT_EQ(0U, root->child_count());
-
- // When a frame is removed from the page, the corresponding
- // FrameNavigationEntry is not removed. This is done intentionally to support
- // back-forward navigations in subframes and more intuitive UX on tab restore.
- EXPECT_EQ(1U, nav_entry->root_node()->children.size());
- FrameNavigationEntry* frame_entry =
- nav_entry->root_node()->children[0]->frame_entry.get();
- EXPECT_EQ("foo-frame-name", frame_entry->frame_unique_name());
-
- EXPECT_TRUE(ExecuteScript(root, kAddFrameScript));
- EXPECT_EQ(1U, root->child_count());
- EXPECT_NE("foo-frame-name", root->child_at(0)->frame_name());
-
- // Add a nested frame with the previously used name.
- EXPECT_TRUE(ExecuteScript(root->child_at(0), kAddNamedFrameScript));
- EXPECT_EQ(1U, root->child_at(0)->child_count());
- EXPECT_EQ("foo-frame-name", root->child_at(0)->child_at(0)->frame_name());
-
- EXPECT_EQ(1U, nav_entry->root_node()->children.size());
-
- EXPECT_EQ(1U, nav_entry->root_node()->children[0]->children.size());
-
- const auto& tree_node = nav_entry->root_node()->children[0]->children[0];
- EXPECT_EQ(0U, tree_node->children.size());
- EXPECT_EQ("foo-frame-name", tree_node->frame_entry->frame_unique_name());
+ EXPECT_EQ(3U, entry->root_node()->children.size());
- EXPECT_TRUE(ExecuteScript(root->child_at(0), kRemoveFrameScript));
- EXPECT_EQ(0U, root->child_at(0)->child_count());
+ // Both children of |entry->root_node()->children[0]| should be removed by
+ // NavigationEntryImpl::RemoveEntryForFrame, because both will have
+ // colliding unique names (the removed parent and the newly added frame both
+ // load '1-1.html' - which has 2 named framse).
+ EXPECT_EQ(0U, entry->root_node()->children[0]->children.size());
+ }
}
// This test ensures that the comparison of tree position between a
@@ -6097,23 +6103,25 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
web_contents->GetController().GetLastCommittedEntry();
// Add, then remove a named frame. It will create a FrameNavigationEntry
- // for the name and leave it around.
+ // for the name and remove it (since this is a frame created by script).
EXPECT_TRUE(ExecuteScript(root, kAddNamedFrameScript));
EXPECT_EQ(1U, root->child_count());
EXPECT_EQ(1U, nav_entry->root_node()->children.size());
+ // |tree_node| will becoma a dangling pointer when the frame is removed below.
auto* tree_node = nav_entry->root_node()->children[0].get();
EXPECT_TRUE(ExecuteScript(root, kRemoveFrameScript));
EXPECT_EQ(0U, root->child_count());
- EXPECT_EQ(1U, nav_entry->root_node()->children.size());
+ EXPECT_EQ(0U, nav_entry->root_node()->children.size());
- // Add another frame with the same name as before. The matching logic
- // should consider them the same and result in the FrameNavigationEntry
- // being reused.
+ // Add another frame with the same name as before. The matching logic should
+ // NOT consider them the same and should NOT result in the
+ // FrameNavigationEntry being reused (because the frame injected by javascript
+ // will get a fresh, random unique name each time it is created or recreated).
EXPECT_TRUE(ExecuteScript(root, kAddNamedFrameScript));
EXPECT_EQ(1U, root->child_count());
EXPECT_EQ(1U, nav_entry->root_node()->children.size());
- EXPECT_EQ(tree_node, nav_entry->root_node()->children[0].get());
+ EXPECT_NE(tree_node, nav_entry->root_node()->children[0].get());
EXPECT_TRUE(ExecuteScript(root, kRemoveFrameScript));
EXPECT_EQ(0U, root->child_count());
@@ -6667,7 +6675,7 @@ class WebContentsLoadFinishedWaiter : public WebContentsObserver {
: WebContentsObserver(web_contents),
expected_url_(expected_url),
message_loop_runner_(new MessageLoopRunner) {
- EXPECT_TRUE(web_contents != NULL);
+ EXPECT_TRUE(web_contents != nullptr);
}
void Wait() { message_loop_runner_->Run(); }
@@ -6864,6 +6872,67 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, StopDuringLoad) {
ASSERT_EQ(controller.GetPendingEntry(), nullptr);
}
+// Tests that reloading a page that has no title doesn't inherit the title from
+// the previous version of the page.
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, ReloadDoesntKeepTitle) {
+ NavigationController& controller = shell()->web_contents()->GetController();
+ GURL start_url(embedded_test_server()->GetURL(
+ "/navigation_controller/simple_page_1.html"));
+ GURL intermediate_url(embedded_test_server()->GetURL(
+ "/navigation_controller/simple_page_2.html"));
+ base::string16 title = base::UTF8ToUTF16("title");
+
+ // Reload from the browser side.
+ {
+ EXPECT_TRUE(NavigateToURL(shell(), start_url));
+
+ NavigationEntry* entry = controller.GetLastCommittedEntry();
+ EXPECT_TRUE(entry->GetTitle().empty());
+ entry->SetTitle(title);
+
+ controller.Reload(ReloadType::NORMAL, false);
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+ EXPECT_TRUE(entry->GetTitle().empty());
+ }
+
+ // Load an unrelated page; this disconnects these two tests.
+ EXPECT_TRUE(NavigateToURL(shell(), intermediate_url));
+
+ // Reload from the renderer side.
+ {
+ EXPECT_TRUE(NavigateToURL(shell(), start_url));
+
+ NavigationEntry* entry = controller.GetLastCommittedEntry();
+ EXPECT_TRUE(entry->GetTitle().empty());
+ entry->SetTitle(title);
+
+ TestNavigationObserver reload_observer(shell()->web_contents());
+ EXPECT_TRUE(ExecuteScript(shell(), "location.reload()"));
+ reload_observer.Wait();
+
+ EXPECT_TRUE(entry->GetTitle().empty());
+ }
+
+ // Load an unrelated page; this disconnects these two tests.
+ EXPECT_TRUE(NavigateToURL(shell(), intermediate_url));
+
+ // "Reload" by loading the same page again.
+ {
+ EXPECT_TRUE(NavigateToURL(shell(), start_url));
+
+ NavigationEntry* entry1 = controller.GetLastCommittedEntry();
+ EXPECT_TRUE(entry1->GetTitle().empty());
+ entry1->SetTitle(title);
+
+ EXPECT_TRUE(NavigateToURL(shell(), start_url));
+ NavigationEntry* entry2 = controller.GetLastCommittedEntry();
+
+ EXPECT_EQ(entry1, entry2);
+ EXPECT_TRUE(entry1->GetTitle().empty());
+ }
+}
+
// Verify that session history navigations (back/forward) correctly hit the
// cache instead of going to the server. The test loads a page with no-cache
// header, stops the server, and goes back expecting successful navigation.
@@ -7189,4 +7258,217 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_THAT(messages, testing::IsEmpty());
}
+// This test helps verify that the browser does not retain history entries
+// for removed frames *if* the removed frame was created by a script.
+// Such frames get a fresh, random, unique name every time they are created
+// or recreated and therefore in such case will never match previous history
+// entries. See also https://crbug.com/784356.
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ PruningOfEntriesForDynamicFrames_ChildRemoved) {
+ GURL main_url(embedded_test_server()->GetURL("/title1.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ // Repeatedly create and remove a frame from a script.
+ std::string result;
+ std::string script = R"(
+ var iterations_left = 5;
+ function runOneIteration() {
+ if (iterations_left == 0) {
+ domAutomationController.send("done-with-test");
+ return;
+ }
+
+ var iframe = document.createElement("iframe");
+ document.body.appendChild(iframe);
+ document.body.removeChild(iframe);
+
+ iterations_left = iterations_left - 1;
+ setTimeout(runOneIteration, 0);
+ }
+ runOneIteration(); )";
+ EXPECT_TRUE(ExecuteScriptAndExtractString(shell(), script, &result));
+ EXPECT_EQ("done-with-test", result);
+
+ // Grab the last committed entry.
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ EXPECT_EQ(1, controller.GetEntryCount());
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
+ EXPECT_EQ(main_url, entry->GetURL());
+
+ // Verify that the number of FrameNavigationEntries stayed low (i.e. that we
+ // do not retain history entries for the 5 frames removed by the test).
+ EXPECT_EQ(0U, entry->root_node()->children.size());
+
+ // Sanity check - there are no children in the frame tree.
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ ASSERT_EQ(0U, root->child_count());
+}
+
+// This test helps verify that the browser does not retain history entries
+// for removed frames *if* the removed frame was created by a script.
+// Such frames get a fresh, random, unique name every time they are created
+// or recreated and therefore in such case will never match previous history
+// entries. See also https://crbug.com/784356.
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ PruningOfEntriesForDynamicFrames_ParentNavigatedAway) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/navigation_controller/page_with_iframe_simple.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+
+ // Add 5 dynamic subframes to |frame|.
+ RenderFrameHost* frame = shell()->web_contents()->GetAllFrames()[1];
+ std::string script = R"(
+ for (var i = 0; i < 5; i++) {
+ var iframe = document.createElement("iframe");
+ document.body.appendChild(iframe);
+ }; )";
+ EXPECT_TRUE(ExecuteScript(frame, script));
+
+ // Verify that now there are 5 FNEs for the dynamic frames.
+ EXPECT_EQ(1, controller.GetEntryCount());
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
+ EXPECT_EQ(main_url, entry->GetURL());
+ EXPECT_EQ(1U, entry->root_node()->children.size());
+ EXPECT_EQ(5U, entry->root_node()->children[0]->children.size());
+
+ // Navigate |frame| (the parent of the dynamic frames) away.
+ // This will destroy the 5 dynamic children of |frame|.
+ GURL next_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
+ EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "frame", next_url));
+
+ // Verify that there are now 0 FNEs for the dynamic frames.
+ EXPECT_EQ(2, controller.GetEntryCount());
+ EXPECT_EQ(main_url, entry->GetURL());
+ EXPECT_EQ(1U, entry->root_node()->children.size());
+ EXPECT_EQ(0U, entry->root_node()->children[0]->children.size());
+}
+
+// This test helps verify that the browser does not retain history entries
+// for removed frames *if* the removed frame was created by a script.
+// Such frames get a fresh, random, unique name every time they are created
+// or recreated and therefore in such case will never match previous history
+// entries. See also https://crbug.com/784356.
+IN_PROC_BROWSER_TEST_F(
+ NavigationControllerBrowserTest,
+ PruningOfEntriesForDynamicFrames_MainFrameNavigatedAway) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/navigation_controller/page_with_iframe_simple.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+
+ // Add 5 dynamic subframes to |frame|.
+ RenderFrameHost* frame = shell()->web_contents()->GetAllFrames()[1];
+ std::string script = R"(
+ for (var i = 0; i < 5; i++) {
+ var iframe = document.createElement("iframe");
+ document.body.appendChild(iframe);
+ }; )";
+ EXPECT_TRUE(ExecuteScript(frame, script));
+
+ // Verify that now there are 5 FNEs for the dynamic frames.
+ EXPECT_EQ(1, controller.GetEntryCount());
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
+ EXPECT_EQ(main_url, entry->GetURL());
+ EXPECT_EQ(1U, entry->root_node()->children.size());
+ EXPECT_EQ(5U, entry->root_node()->children[0]->children.size());
+
+ // Navigate the main frame (the grandparent of the dynamic frames) away.
+ // This will destroy the 5 dynamic children of |frame|.
+ GURL next_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), next_url));
+
+ // Verify that there are now 0 FNEs for the dynamic frames.
+ EXPECT_EQ(2, controller.GetEntryCount());
+ EXPECT_EQ(main_url, entry->GetURL());
+ EXPECT_EQ(1U, entry->root_node()->children.size());
+ EXPECT_EQ(0U, entry->root_node()->children[0]->children.size());
+}
+
+// This test reproduces issue 769645. It happens when the user reloads the page
+// and an "unload" event triggers a back navigation. If the reload navigation
+// has reached the ReadyToCommit stage but has not committed, the back
+// navigation may interrupt its load.
+// See https://crbug.com/769645.
+// See https://crbug.com/773683.
+IN_PROC_BROWSER_TEST_F(ContentBrowserTest, HistoryBackInUnloadCancelsReload) {
+ ControllableHttpResponse response_1(embedded_test_server(), "/main_document");
+ ControllableHttpResponse response_2(embedded_test_server(),
+ "/main_document?attribute=1");
+
+ EXPECT_TRUE(embedded_test_server()->Start());
+
+ // 1) Navigate to a document that will:
+ // * Use history.pushState() during page load.
+ // * Use history.back() on "unload".
+ GURL main_document_url(embedded_test_server()->GetURL("/main_document"));
+ shell()->LoadURL(main_document_url);
+ response_1.WaitForRequest();
+ response_1.Send(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "\r\n"
+ "<iframe srcdoc=\""
+ " <script>"
+ " parent.history.pushState({},'','?attribute=1');"
+ " window.addEventListener('unload', function() {"
+ " parent.history.back();"
+ " });"
+ " </script>"
+ "\"></iframe>");
+ response_1.Done();
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+ // 2) Reload. Due to https://crbug.com/773683, two parallel navigations will
+ // happen:
+ // * The reload.
+ // * The parent.history.back().
+ GURL main_document_url_page_2(main_document_url.spec() + "?attribute=1");
+ TestNavigationManager observer_reload(shell()->web_contents(),
+ main_document_url_page_2);
+ TestNavigationManager observer_back(shell()->web_contents(),
+ main_document_url);
+
+ shell()->Reload();
+
+ // 2.1) The reload reaches the ReadyToCommitNavigation stage.
+ EXPECT_TRUE(observer_reload.WaitForRequestStart());
+ observer_reload.ResumeNavigation();
+ response_2.WaitForRequest();
+ response_2.Send(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "\r\n"
+ "<html><body>First part of the response...");
+ EXPECT_TRUE(observer_reload.WaitForResponse());
+ observer_reload.ResumeNavigation();
+
+ // 2.2) Back navigation starts and commits.
+ observer_back.WaitForNavigationFinished();
+
+ // The server sends the remaining part of the response.
+ response_2.Send(" ...and the second part!</body></html>");
+ response_2.Done();
+
+ observer_reload.WaitForNavigationFinished();
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+ // Test what is in the loaded document.
+ std::string html_content;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ shell(), "domAutomationController.send(document.body.textContent)",
+ &html_content));
+
+ EXPECT_EQ("First part of the response... ...and the second part!",
+ html_content);
+}
+
} // 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 56a66a661a3..7024ee4de7f 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <memory>
+#include <string>
#include <tuple>
#include <utility>
@@ -50,7 +51,7 @@
#include "content/test/test_web_contents.h"
#include "skia/ext/platform_canvas.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "third_party/WebKit/common/frame_policy.h"
using base::Time;
@@ -271,9 +272,8 @@ class NavigationControllerTest
class TestWebContentsDelegate : public WebContentsDelegate {
public:
- explicit TestWebContentsDelegate() :
- navigation_state_change_count_(0),
- repost_form_warning_count_(0) {}
+ TestWebContentsDelegate()
+ : navigation_state_change_count_(0), repost_form_warning_count_(0) {}
int navigation_state_change_count() {
return navigation_state_change_count_;
@@ -675,7 +675,7 @@ TEST_F(NavigationControllerTest, LoadURLSameTime) {
}
void CheckNavigationEntryMatchLoadParams(
- NavigationController::LoadURLParams& load_params,
+ const NavigationController::LoadURLParams& load_params,
NavigationEntryImpl* entry) {
EXPECT_EQ(load_params.url, entry->GetURL());
EXPECT_EQ(load_params.referrer.url, entry->GetReferrer().url);
@@ -867,7 +867,8 @@ TEST_F(NavigationControllerTest, LoadURL_SamePage_DifferentMethod) {
params.transition = ui::PAGE_TRANSITION_TYPED;
params.method = "POST";
params.post_id = 123;
- params.page_state = PageState::CreateForTesting(url1, false, 0, 0);
+ params.page_state =
+ PageState::CreateForTesting(url1, false, nullptr, nullptr);
main_test_rfh()->PrepareForCommit();
main_test_rfh()->SendNavigateWithParams(&params);
@@ -1196,7 +1197,7 @@ TEST_F(NavigationControllerTest, LoadURL_IgnorePreemptsPending) {
EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
EXPECT_EQ(2, delegate->navigation_state_change_count());
- contents()->SetDelegate(NULL);
+ contents()->SetDelegate(nullptr);
}
// Tests that the pending entry state is correct after an abort.
@@ -1249,7 +1250,7 @@ TEST_F(NavigationControllerTest, LoadURL_AbortDoesntCancelPending) {
EXPECT_EQ(pending_entry, controller.GetPendingEntry());
EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
- contents()->SetDelegate(NULL);
+ contents()->SetDelegate(nullptr);
}
// Tests that the pending URL is not visible during a renderer-initiated
@@ -1316,7 +1317,7 @@ TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) {
// so that no spoof is possible.
EXPECT_EQ(kExistingURL, controller.GetVisibleEntry()->GetURL());
- contents()->SetDelegate(NULL);
+ contents()->SetDelegate(nullptr);
}
// Ensure that NavigationEntries track which bindings their RenderViewHost had
@@ -2221,9 +2222,10 @@ TEST_F(NavigationControllerTest, NewSubframe) {
// Prereq: add a subframe with an initial auto-subframe navigation.
std::string unique_name("uniqueName0");
main_test_rfh()->OnCreateChildFrame(
- process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument,
- std::string(), unique_name, base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
+ process()->GetNextRoutingID(),
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), unique_name, false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>(
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host());
@@ -2298,9 +2300,10 @@ TEST_F(NavigationControllerTest, AutoSubframe) {
// Add a subframe and navigate it.
std::string unique_name0("uniqueName0");
main_test_rfh()->OnCreateChildFrame(
- process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument,
- std::string(), unique_name0, base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
+ process()->GetNextRoutingID(),
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), unique_name0, false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>(
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host());
@@ -2343,9 +2346,10 @@ TEST_F(NavigationControllerTest, AutoSubframe) {
// Add a second subframe and navigate.
std::string unique_name1("uniqueName1");
main_test_rfh()->OnCreateChildFrame(
- process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument,
- std::string(), unique_name1, base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
+ process()->GetNextRoutingID(),
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), unique_name1, false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
TestRenderFrameHost* subframe2 = static_cast<TestRenderFrameHost*>(
contents()->GetFrameTree()->root()->child_at(1)->current_frame_host());
@@ -2388,9 +2392,10 @@ TEST_F(NavigationControllerTest, AutoSubframe) {
// Add a nested subframe and navigate.
std::string unique_name2("uniqueName2");
subframe->OnCreateChildFrame(
- process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument,
- std::string(), unique_name2, base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
+ process()->GetNextRoutingID(),
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), unique_name2, false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
TestRenderFrameHost* subframe3 =
static_cast<TestRenderFrameHost*>(contents()
@@ -2451,9 +2456,10 @@ TEST_F(NavigationControllerTest, BackSubframe) {
// Prereq: add a subframe with an initial auto-subframe navigation.
std::string unique_name("uniqueName0");
main_test_rfh()->OnCreateChildFrame(
- process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument,
- std::string(), unique_name, base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
+ process()->GetNextRoutingID(),
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), unique_name, false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>(
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host());
@@ -2616,11 +2622,12 @@ TEST_F(NavigationControllerTest, SameDocument) {
EXPECT_EQ(1U, navigation_entry_committed_counter_);
navigation_entry_committed_counter_ = 0;
- // Ensure main page navigation to same url respects the
- // was_within_same_document hint provided in the params.
+ // Ensure renderer-initiated main frame navigation to same url replaces the
+ // current entry. This behavior differs from the browser-initiated case.
FrameHostMsg_DidCommitProvisionalLoad_Params self_params;
self_params.nav_entry_id = 0;
- self_params.did_create_new_entry = false;
+ self_params.did_create_new_entry = true;
+ self_params.should_replace_current_entry = true;
self_params.url = url1;
self_params.transition = ui::PAGE_TRANSITION_LINK;
self_params.should_update_history = false;
@@ -2631,7 +2638,7 @@ TEST_F(NavigationControllerTest, SameDocument) {
self_params.page_state = PageState::CreateForTestingWithSequenceNumbers(
url1, self_params.item_sequence_number,
self_params.document_sequence_number);
- self_params.was_within_same_document = true;
+ self_params.was_within_same_document = false;
LoadCommittedDetailsObserver observer(contents());
main_test_rfh()->SendRendererInitiatedNavigationRequest(url1, false);
@@ -2640,7 +2647,7 @@ TEST_F(NavigationControllerTest, SameDocument) {
NavigationEntry* entry1 = controller.GetLastCommittedEntry();
EXPECT_EQ(1U, navigation_entry_committed_counter_);
navigation_entry_committed_counter_ = 0;
- EXPECT_TRUE(observer.is_same_document());
+ EXPECT_FALSE(observer.is_same_document());
EXPECT_TRUE(observer.did_replace_entry());
EXPECT_EQ(1, controller.GetEntryCount());
@@ -2674,6 +2681,7 @@ TEST_F(NavigationControllerTest, SameDocument) {
controller.GoBack();
back_params.nav_entry_id = entry1->GetUniqueID();
back_params.did_create_new_entry = false;
+ back_params.was_within_same_document = true;
main_test_rfh()->SendNavigateWithParams(&back_params);
EXPECT_EQ(1U, navigation_entry_committed_counter_);
navigation_entry_committed_counter_ = 0;
@@ -2737,11 +2745,12 @@ TEST_F(NavigationControllerTest, SameDocument_Replace) {
EXPECT_EQ(1U, navigation_entry_committed_counter_);
navigation_entry_committed_counter_ = 0;
- // First navigation.
+ // First navigation (using location.replace).
const GURL url2("http://foo#a");
FrameHostMsg_DidCommitProvisionalLoad_Params params;
params.nav_entry_id = 0;
params.did_create_new_entry = false;
+ params.should_replace_current_entry = true;
params.url = url2;
params.transition = ui::PAGE_TRANSITION_LINK;
params.should_update_history = false;
@@ -2785,12 +2794,13 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) {
navigation_entry_committed_counter_ = 0;
}
- // Navigate within the page.
+ // Navigate within the page using location.replace.
{
const GURL url("http://foo2/#a");
FrameHostMsg_DidCommitProvisionalLoad_Params params;
params.nav_entry_id = 0;
params.did_create_new_entry = false;
+ params.should_replace_current_entry = true;
params.url = url;
params.transition = ui::PAGE_TRANSITION_LINK;
params.redirects.push_back(url);
@@ -2849,8 +2859,7 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) {
}
}
-TEST_F(NavigationControllerTest, PushStateWithoutPreviousEntry)
-{
+TEST_F(NavigationControllerTest, PushStateWithoutPreviousEntry) {
ASSERT_FALSE(controller_impl().GetLastCommittedEntry());
FrameHostMsg_DidCommitProvisionalLoad_Params params;
GURL url("http://foo");
@@ -3716,21 +3725,21 @@ TEST_F(NavigationControllerTest, IsSameDocumentNavigation) {
const GURL blank_url(url::kAboutBlankURL);
const url::Origin blank_origin;
main_test_rfh()->NavigateAndCommitRendererInitiated(true, blank_url);
- EXPECT_TRUE(controller.IsURLSameDocumentNavigation(url, url::Origin(url),
- true, main_test_rfh()));
+ EXPECT_TRUE(controller.IsURLSameDocumentNavigation(
+ url, url::Origin::Create(url), true, main_test_rfh()));
// Navigate to URL with no refs.
NavigationSimulator::NavigateAndCommitFromDocument(url, main_test_rfh());
// Reloading the page is not a same-document navigation.
- EXPECT_FALSE(controller.IsURLSameDocumentNavigation(url, url::Origin(url),
- false, main_test_rfh()));
+ EXPECT_FALSE(controller.IsURLSameDocumentNavigation(
+ url, url::Origin::Create(url), false, main_test_rfh()));
const GURL other_url("http://www.google.com/add.html");
EXPECT_FALSE(controller.IsURLSameDocumentNavigation(
- other_url, url::Origin(other_url), false, main_test_rfh()));
+ other_url, url::Origin::Create(other_url), false, main_test_rfh()));
const GURL url_with_ref("http://www.google.com/home.html#my_ref");
EXPECT_TRUE(controller.IsURLSameDocumentNavigation(
- url_with_ref, url::Origin(url_with_ref), true, main_test_rfh()));
+ url_with_ref, url::Origin::Create(url_with_ref), true, main_test_rfh()));
// Navigate to URL with refs.
NavigationSimulator::NavigateAndCommitFromDocument(url_with_ref,
@@ -3738,30 +3747,30 @@ TEST_F(NavigationControllerTest, IsSameDocumentNavigation) {
// Reloading the page is not a same-document navigation.
EXPECT_FALSE(controller.IsURLSameDocumentNavigation(
- url_with_ref, url::Origin(url_with_ref), false, main_test_rfh()));
- EXPECT_FALSE(controller.IsURLSameDocumentNavigation(url, url::Origin(url),
- false, main_test_rfh()));
+ url_with_ref, url::Origin::Create(url_with_ref), false, main_test_rfh()));
+ EXPECT_FALSE(controller.IsURLSameDocumentNavigation(
+ url, url::Origin::Create(url), false, main_test_rfh()));
EXPECT_FALSE(controller.IsURLSameDocumentNavigation(
- other_url, url::Origin(other_url), false, main_test_rfh()));
+ other_url, url::Origin::Create(other_url), false, main_test_rfh()));
const GURL other_url_with_ref("http://www.google.com/home.html#my_other_ref");
EXPECT_TRUE(controller.IsURLSameDocumentNavigation(
- other_url_with_ref, url::Origin(other_url_with_ref), true,
+ other_url_with_ref, url::Origin::Create(other_url_with_ref), true,
main_test_rfh()));
// Going to the same url again will be considered same-document navigation
// if the renderer says it is even if the navigation type isn't SAME_DOCUMENT.
EXPECT_TRUE(controller.IsURLSameDocumentNavigation(
- url_with_ref, url::Origin(url_with_ref), true, main_test_rfh()));
+ url_with_ref, url::Origin::Create(url_with_ref), true, main_test_rfh()));
// Going back to the non ref url will be considered same-document navigation
// if the navigation type is SAME_DOCUMENT.
- EXPECT_TRUE(controller.IsURLSameDocumentNavigation(url, url::Origin(url),
- true, main_test_rfh()));
+ EXPECT_TRUE(controller.IsURLSameDocumentNavigation(
+ url, url::Origin::Create(url), true, main_test_rfh()));
// If the renderer says this is a same-origin same-document navigation,
// believe it. This is the pushState/replaceState case.
EXPECT_TRUE(controller.IsURLSameDocumentNavigation(
- other_url, url::Origin(other_url), true, main_test_rfh()));
+ other_url, url::Origin::Create(other_url), true, main_test_rfh()));
// Don't believe the renderer if it claims a cross-origin navigation is
// a same-document navigation.
@@ -3769,7 +3778,7 @@ TEST_F(NavigationControllerTest, IsSameDocumentNavigation) {
MockRenderProcessHost* rph = main_test_rfh()->GetProcess();
EXPECT_EQ(0, rph->bad_msg_count());
EXPECT_FALSE(controller.IsURLSameDocumentNavigation(
- different_origin_url, url::Origin(different_origin_url), true,
+ different_origin_url, url::Origin::Create(different_origin_url), true,
main_test_rfh()));
EXPECT_EQ(1, rph->bad_msg_count());
}
@@ -3792,13 +3801,13 @@ TEST_F(NavigationControllerTest,
// Allow same-document navigation to be cross-origin if existing URL is file
// scheme.
const GURL file_url("file:///foo/index.html");
- const url::Origin file_origin(file_url);
+ const url::Origin file_origin = url::Origin::Create(file_url);
main_test_rfh()->NavigateAndCommitRendererInitiated(true, file_url);
EXPECT_TRUE(
file_origin.IsSameOriginWith(main_test_rfh()->GetLastCommittedOrigin()));
EXPECT_EQ(0, rph->bad_msg_count());
EXPECT_TRUE(controller.IsURLSameDocumentNavigation(
- different_origin_url, url::Origin(different_origin_url), true,
+ different_origin_url, url::Origin::Create(different_origin_url), true,
main_test_rfh()));
EXPECT_EQ(0, rph->bad_msg_count());
@@ -3825,7 +3834,7 @@ TEST_F(NavigationControllerTest,
EXPECT_TRUE(
file_origin.IsSameOriginWith(main_test_rfh()->GetLastCommittedOrigin()));
EXPECT_TRUE(controller.IsURLSameDocumentNavigation(
- file_url, url::Origin(file_url), true, main_test_rfh()));
+ file_url, url::Origin::Create(file_url), true, main_test_rfh()));
EXPECT_EQ(0, rph->bad_msg_count());
// Don't honor allow_universal_access_from_file_urls if actual URL is
@@ -3833,7 +3842,7 @@ TEST_F(NavigationControllerTest,
const GURL url("http://www.google.com/home.html");
main_test_rfh()->NavigateAndCommitRendererInitiated(true, url);
EXPECT_FALSE(controller.IsURLSameDocumentNavigation(
- different_origin_url, url::Origin(different_origin_url), true,
+ different_origin_url, url::Origin::Create(different_origin_url), true,
main_test_rfh()));
EXPECT_EQ(1, rph->bad_msg_count());
}
@@ -3855,9 +3864,10 @@ TEST_F(NavigationControllerTest, SameSubframe) {
// Add and navigate a subframe that would normally count as in-page.
std::string unique_name("uniqueName0");
main_test_rfh()->OnCreateChildFrame(
- process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument,
- std::string(), unique_name, base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
+ process()->GetNextRoutingID(),
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), unique_name, false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>(
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host());
@@ -4030,9 +4040,10 @@ TEST_F(NavigationControllerTest, SubframeWhilePending) {
// automatically loaded. Auto subframes don't increment the page ID.
std::string unique_name("uniqueName0");
main_test_rfh()->OnCreateChildFrame(
- process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument,
- std::string(), unique_name, base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
+ process()->GetNextRoutingID(),
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), unique_name, false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>(
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host());
@@ -4539,7 +4550,8 @@ TEST_F(NavigationControllerTest, HistoryNavigate) {
EXPECT_EQ(0, controller.GetPendingEntryIndex());
// The actual cross-navigation is suspended until the current RVH tells us
// it unloaded, simulate that.
- contents()->ProceedWithCrossSiteNavigation();
+ if (!IsBrowserSideNavigationEnabled())
+ contents()->GetMainFrame()->PrepareForCommitIfNecessary();
// Also make sure we told the page to navigate.
GURL nav_url = GetLastNavigationURL();
EXPECT_EQ(url1, nav_url);
@@ -4551,7 +4563,8 @@ TEST_F(NavigationControllerTest, HistoryNavigate) {
EXPECT_EQ(2, controller.GetPendingEntryIndex());
// The actual cross-navigation is suspended until the current RVH tells us
// it unloaded, simulate that.
- contents()->ProceedWithCrossSiteNavigation();
+ if (!IsBrowserSideNavigationEnabled())
+ contents()->GetMainFrame()->PrepareForCommitIfNecessary();
nav_url = GetLastNavigationURL();
EXPECT_EQ(url3, nav_url);
contents()->CommitPendingNavigation();
diff --git a/chromium/content/browser/frame_host/navigation_entry_impl.cc b/chromium/content/browser/frame_host/navigation_entry_impl.cc
index c6231296f56..aadd13429bb 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_entry_impl.cc
@@ -6,6 +6,9 @@
#include <stddef.h>
+#include <algorithm>
+#include <map>
+#include <string>
#include <utility>
#include "base/containers/queue.h"
@@ -34,7 +37,7 @@ namespace {
// Use this to get a new unique ID for a NavigationEntry during construction.
// The returned ID is guaranteed to be nonzero (which is the "no ID" indicator).
-int GetUniqueIDInConstructor() {
+int CreateUniqueEntryID() {
static int unique_id_counter = 0;
return ++unique_id_counter;
}
@@ -43,14 +46,6 @@ void RecursivelyGenerateFrameEntries(
const ExplodedFrameState& state,
const std::vector<base::Optional<base::string16>>& referenced_files,
NavigationEntryImpl::TreeNode* node) {
- node->frame_entry = new FrameNavigationEntry(
- UTF16ToUTF8(state.target.value_or(base::string16())),
- state.item_sequence_number, state.document_sequence_number, nullptr,
- nullptr, GURL(state.url_string.value_or(base::string16())),
- Referrer(GURL(state.referrer.value_or(base::string16())),
- state.referrer_policy),
- "GET", -1);
-
// Set a single-frame PageState on the entry.
ExplodedPageState page_state;
@@ -66,7 +61,14 @@ void RecursivelyGenerateFrameEntries(
std::string data;
EncodePageState(page_state, &data);
DCHECK(!data.empty()) << "Shouldn't generate an empty PageState.";
- node->frame_entry->SetPageState(PageState::CreateFromEncodedData(data));
+
+ node->frame_entry = new FrameNavigationEntry(
+ UTF16ToUTF8(state.target.value_or(base::string16())),
+ state.item_sequence_number, state.document_sequence_number, nullptr,
+ nullptr, GURL(state.url_string.value_or(base::string16())),
+ Referrer(GURL(state.referrer.value_or(base::string16())),
+ state.referrer_policy),
+ std::vector<GURL>(), PageState::CreateFromEncodedData(data), "GET", -1);
// Don't pass the file list to subframes, since that would result in multiple
// copies of it ending up in the combined list in GetPageState (via
@@ -75,7 +77,7 @@ void RecursivelyGenerateFrameEntries(
for (const ExplodedFrameState& child_state : state.children) {
node->children.push_back(
- base::MakeUnique<NavigationEntryImpl::TreeNode>(node, nullptr));
+ std::make_unique<NavigationEntryImpl::TreeNode>(node, nullptr));
RecursivelyGenerateFrameEntries(child_state, empty_file_list,
node->children.back().get());
}
@@ -252,9 +254,11 @@ NavigationEntryImpl::NavigationEntryImpl(
nullptr,
url,
referrer,
+ std::vector<GURL>(),
+ PageState(),
"GET",
-1))),
- unique_id_(GetUniqueIDInConstructor()),
+ unique_id_(CreateUniqueEntryID()),
bindings_(kInvalidBindings),
page_type_(PAGE_TYPE_NORMAL),
update_virtual_url_with_url_(false),
@@ -664,10 +668,13 @@ CommonNavigationParams NavigationEntryImpl::ConstructCommonNavigationParams(
FrameMsg_UILoadMetricsReportType::Value report_type =
FrameMsg_UILoadMetricsReportType::NO_REPORT;
base::TimeTicks ui_timestamp = base::TimeTicks();
+ bool user_gesture = false;
+
#if defined(OS_ANDROID)
if (!intent_received_timestamp().is_null())
report_type = FrameMsg_UILoadMetricsReportType::REPORT_INTENT;
ui_timestamp = intent_received_timestamp();
+ user_gesture = has_user_gesture();
#endif
std::string method;
@@ -686,7 +693,7 @@ CommonNavigationParams NavigationEntryImpl::ConstructCommonNavigationParams(
navigation_start, method, post_body ? post_body : post_data_,
base::Optional<SourceLocation>(),
CSPDisposition::CHECK /* should_check_main_world_csp */,
- has_started_from_context_menu());
+ has_started_from_context_menu(), user_gesture);
}
StartNavigationParams NavigationEntryImpl::ConstructStartNavigationParams()
@@ -726,17 +733,13 @@ RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
current_length_to_send = 0;
}
- bool user_gesture = false;
-#if defined(OS_ANDROID)
- user_gesture = has_user_gesture();
-#endif
RequestNavigationParams request_params(
GetIsOverridingUserAgent(), redirects, original_url, original_method,
GetCanLoadLocalResources(), frame_entry.page_state(), GetUniqueID(),
is_history_navigation_in_new_child, subframe_unique_names,
has_committed_real_load, intended_as_new_entry, pending_offset_to_send,
current_offset_to_send, current_length_to_send, IsViewSourceMode(),
- should_clear_history_list(), user_gesture);
+ should_clear_history_list());
#if defined(OS_ANDROID)
if (GetDataURLAsString() &&
GetDataURLAsString()->size() <= kMaxLengthOfDataURLString) {
@@ -860,12 +863,10 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(
// or unique name.
FrameNavigationEntry* frame_entry = new FrameNavigationEntry(
unique_name, item_sequence_number, document_sequence_number,
- site_instance, std::move(source_site_instance), url, referrer, method,
- post_id);
- frame_entry->SetPageState(page_state);
- frame_entry->set_redirect_chain(redirect_chain);
+ site_instance, std::move(source_site_instance), url, referrer,
+ redirect_chain, page_state, method, post_id);
parent_node->children.push_back(
- base::MakeUnique<NavigationEntryImpl::TreeNode>(parent_node,
+ std::make_unique<NavigationEntryImpl::TreeNode>(parent_node,
frame_entry));
}
@@ -908,44 +909,28 @@ std::map<std::string, bool> NavigationEntryImpl::GetSubframeUniqueNames(
return names;
}
-void NavigationEntryImpl::ClearStaleFrameEntriesForNewFrame(
- FrameTreeNode* frame_tree_node) {
+void NavigationEntryImpl::RemoveEntryForFrame(FrameTreeNode* frame_tree_node,
+ bool only_if_different_position) {
DCHECK(!frame_tree_node->IsMainFrame());
- NavigationEntryImpl::TreeNode* node = nullptr;
- base::queue<NavigationEntryImpl::TreeNode*> work_queue;
- int count = 0;
-
- work_queue.push(root_node());
- while (!work_queue.empty()) {
- node = work_queue.front();
- work_queue.pop();
-
- // Enqueue any children and keep looking if the current node doesn't match.
- if (!node->MatchesFrame(frame_tree_node)) {
- for (const auto& child : node->children) {
- work_queue.push(child.get());
- }
- continue;
- }
+ NavigationEntryImpl::TreeNode* node = GetTreeNode(frame_tree_node);
+ if (!node)
+ return;
- // Remove the node from the tree if it is not in the same position in the
- // tree of FrameNavigationEntries and the FrameTree.
- if (!InSameTreePosition(frame_tree_node, node)) {
- NavigationEntryImpl::TreeNode* parent_node = node->parent;
- auto it = std::find_if(
- parent_node->children.begin(), parent_node->children.end(),
- [node](const std::unique_ptr<NavigationEntryImpl::TreeNode>& item) {
- return item.get() == node;
- });
- CHECK(it != parent_node->children.end());
- parent_node->children.erase(it);
- }
- ++count;
+ // Remove the |node| from the tree if either 1) |only_if_different_position|
+ // was not asked for or 2) if it is not in the same position in the tree of
+ // FrameNavigationEntries and the FrameTree.
+ if (!only_if_different_position ||
+ !InSameTreePosition(frame_tree_node, node)) {
+ NavigationEntryImpl::TreeNode* parent_node = node->parent;
+ auto it = std::find_if(
+ parent_node->children.begin(), parent_node->children.end(),
+ [node](const std::unique_ptr<NavigationEntryImpl::TreeNode>& item) {
+ return item.get() == node;
+ });
+ CHECK(it != parent_node->children.end());
+ parent_node->children.erase(it);
}
-
- // At most one match is expected, since it is based on unique frame name.
- DCHECK_LE(count, 1);
}
void NavigationEntryImpl::SetScreenshotPNGData(
diff --git a/chromium/content/browser/frame_host/navigation_entry_impl.h b/chromium/content/browser/frame_host/navigation_entry_impl.h
index ee3362e236e..fc75a4be22a 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl.h
+++ b/chromium/content/browser/frame_host/navigation_entry_impl.h
@@ -9,6 +9,7 @@
#include <map>
#include <memory>
+#include <string>
#include <vector>
#include "base/macros.h"
@@ -256,7 +257,12 @@ class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry {
// |frame_tree_node|, and all of their children. There should be at most one,
// since collisions are avoided but leave old FrameNavigationEntries in the
// tree after their frame has been detached.
- void ClearStaleFrameEntriesForNewFrame(FrameTreeNode* frame_tree_node);
+ //
+ // If |only_if_different_position| is specified, then the removal is only
+ // done if the found FNE is in a different tree position than the
+ // |frame_tree_node|.
+ void RemoveEntryForFrame(FrameTreeNode* frame_tree_node,
+ bool only_if_different_position);
void set_unique_id(int unique_id) {
unique_id_ = unique_id;
@@ -413,7 +419,7 @@ class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry {
return has_user_gesture_;
}
- void set_has_user_gesture (bool has_user_gesture) {
+ void set_has_user_gesture(bool has_user_gesture) {
has_user_gesture_ = has_user_gesture;
}
#endif
diff --git a/chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc b/chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc
index 73b50be56d7..328727d0001 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc
@@ -32,7 +32,7 @@ class TestSSLStatusData : public SSLStatus::UserData {
// SSLStatus implementation:
std::unique_ptr<SSLStatus::UserData> Clone() override {
std::unique_ptr<TestSSLStatusData> cloned =
- base::MakeUnique<TestSSLStatusData>();
+ std::make_unique<TestSSLStatusData>();
cloned->set_user_data_flag(user_data_flag_);
return std::move(cloned);
}
@@ -46,13 +46,12 @@ class TestSSLStatusData : public SSLStatus::UserData {
class NavigationEntryTest : public testing::Test {
public:
- NavigationEntryTest() : instance_(NULL) {
- }
+ NavigationEntryTest() : instance_(nullptr) {}
void SetUp() override {
entry1_.reset(new NavigationEntryImpl);
- instance_ = SiteInstanceImpl::Create(NULL);
+ instance_ = SiteInstanceImpl::Create(nullptr);
entry2_.reset(new NavigationEntryImpl(
instance_, GURL("test:url"),
Referrer(GURL("from"), blink::kWebReferrerPolicyDefault),
@@ -176,7 +175,7 @@ TEST_F(NavigationEntryTest, NavigationEntrySSLStatus) {
TEST_F(NavigationEntryTest, SSLStatusUserData) {
// Set up an SSLStatus with some user data on it.
SSLStatus ssl;
- ssl.user_data = base::MakeUnique<TestSSLStatusData>();
+ ssl.user_data = std::make_unique<TestSSLStatusData>();
TestSSLStatusData* ssl_data =
static_cast<TestSSLStatusData*>(ssl.user_data.get());
ASSERT_TRUE(ssl_data);
@@ -194,7 +193,7 @@ TEST_F(NavigationEntryTest, SSLStatusUserData) {
// Test other basic accessors
TEST_F(NavigationEntryTest, NavigationEntryAccessors) {
// SiteInstance
- EXPECT_TRUE(entry1_->site_instance() == NULL);
+ EXPECT_TRUE(entry1_->site_instance() == nullptr);
EXPECT_EQ(instance_, entry2_->site_instance());
entry1_->set_site_instance(instance_);
EXPECT_EQ(instance_, entry1_->site_instance());
diff --git a/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.cc b/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.cc
index 46b61dab6f8..5ea71b39e19 100644
--- a/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.cc
+++ b/chromium/content/browser/frame_host/navigation_entry_screenshot_manager.cc
@@ -183,7 +183,7 @@ bool NavigationEntryScreenshotManager::ClearScreenshot(
if (!entry->screenshot().get())
return false;
- entry->SetScreenshotPNGData(NULL);
+ entry->SetScreenshotPNGData(nullptr);
return true;
}
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl.cc b/chromium/content/browser/frame_host/navigation_handle_impl.cc
index e56b81ef55e..5c6f35d85de 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_handle_impl.cc
@@ -35,6 +35,7 @@
#include "content/public/common/content_client.h"
#include "content/public/common/resource_request_body.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/url_utils.h"
#include "net/base/net_errors.h"
#include "net/url_request/redirect_info.h"
#include "url/gurl.h"
@@ -46,7 +47,7 @@ namespace {
// Use this to get a new unique ID for a NavigationHandle during construction.
// The returned ID is guaranteed to be nonzero (zero is the "no ID" indicator).
-int64_t GetUniqueIDInConstructor() {
+int64_t CreateUniqueHandleID() {
static int64_t unique_id_counter = 0;
return ++unique_id_counter;
}
@@ -108,6 +109,7 @@ NavigationHandleImpl::NavigationHandleImpl(
should_update_history_(false),
subframe_entry_committed_(false),
connection_info_(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN),
+ should_ssl_errors_be_fatal_(false),
original_url_(url),
state_(INITIAL),
is_transferring_(false),
@@ -118,7 +120,7 @@ NavigationHandleImpl::NavigationHandleImpl(
request_context_type_(REQUEST_CONTEXT_TYPE_UNSPECIFIED),
mixed_content_context_type_(
blink::WebMixedContentContextType::kBlockable),
- navigation_id_(GetUniqueIDInConstructor()),
+ navigation_id_(CreateUniqueHandleID()),
should_replace_current_entry_(false),
redirect_chain_(redirect_chain),
is_download_(false),
@@ -283,6 +285,13 @@ bool NavigationHandleImpl::IsPost() {
return method_ == "POST";
}
+const scoped_refptr<ResourceRequestBody>&
+NavigationHandleImpl::GetResourceRequestBody() {
+ CHECK_NE(INITIAL, state_)
+ << "This accessor should not be called before the request is started.";
+ return resource_request_body_;
+}
+
const Referrer& NavigationHandleImpl::GetReferrer() {
CHECK_NE(INITIAL, state_)
<< "This accessor should not be called before the request is started.";
@@ -334,6 +343,14 @@ NavigationHandleImpl::GetConnectionInfo() {
return connection_info_;
}
+const net::SSLInfo& NavigationHandleImpl::GetSSLInfo() {
+ return ssl_info_;
+}
+
+bool NavigationHandleImpl::ShouldSSLErrorsBeFatal() {
+ return should_ssl_errors_be_fatal_;
+}
+
bool NavigationHandleImpl::HasCommitted() {
return state_ == DID_COMMIT || state_ == DID_COMMIT_ERROR_PAGE;
}
@@ -364,7 +381,7 @@ const GURL& NavigationHandleImpl::GetPreviousURL() {
}
net::HostPortPair NavigationHandleImpl::GetSocketAddress() {
- DCHECK(state_ == DID_COMMIT || state_ == DID_COMMIT_ERROR_PAGE);
+ DCHECK(state_ >= WILL_PROCESS_RESPONSE);
return socket_address_;
}
@@ -436,6 +453,19 @@ NavigationHandleImpl::CallWillRedirectRequestForTesting(
}
NavigationThrottle::ThrottleCheckResult
+NavigationHandleImpl::CallWillFailRequestForTesting(
+ base::Optional<net::SSLInfo> ssl_info,
+ bool should_ssl_errors_be_fatal) {
+ NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER;
+ WillFailRequest(ssl_info, should_ssl_errors_be_fatal,
+ base::Bind(&UpdateThrottleCheckResult, &result));
+
+ // Reset the callback to ensure it will not be called later.
+ complete_callback_.Reset();
+ return result;
+}
+
+NavigationThrottle::ThrottleCheckResult
NavigationHandleImpl::CallWillProcessResponseForTesting(
content::RenderFrameHost* render_frame_host,
const std::string& raw_response_headers) {
@@ -444,8 +474,8 @@ NavigationHandleImpl::CallWillProcessResponseForTesting(
NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER;
WillProcessResponse(static_cast<RenderFrameHostImpl*>(render_frame_host),
headers, net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
- SSLStatus(), GlobalRequestID(), false, false, false,
- base::Closure(),
+ net::HostPortPair(), net::SSLInfo(), GlobalRequestID(),
+ false, false, false, base::Closure(),
base::Bind(&UpdateThrottleCheckResult, &result));
// Reset the callback to ensure it will not be called later.
@@ -682,11 +712,40 @@ void NavigationHandleImpl::WillRedirectRequest(
RunCompleteCallback(result);
}
+void NavigationHandleImpl::WillFailRequest(
+ base::Optional<net::SSLInfo> ssl_info,
+ bool should_ssl_errors_be_fatal,
+ const ThrottleChecksFinishedCallback& callback) {
+ TRACE_EVENT_ASYNC_STEP_INTO0("navigation", "NavigationHandle", this,
+ "WillFailRequest");
+ if (ssl_info.has_value())
+ ssl_info_ = ssl_info.value();
+ should_ssl_errors_be_fatal_ = should_ssl_errors_be_fatal;
+ complete_callback_ = callback;
+ state_ = WILL_FAIL_REQUEST;
+
+ // Notify each throttle of the request.
+ base::Closure on_defer_callback_copy = on_defer_callback_for_testing_;
+ NavigationThrottle::ThrottleCheckResult result = CheckWillFailRequest();
+ if (result.action() == NavigationThrottle::DEFER) {
+ if (!on_defer_callback_copy.is_null())
+ on_defer_callback_copy.Run();
+ // DO NOT ADD CODE: the NavigationHandle might have been destroyed during
+ // one of the NavigationThrottle checks.
+ return;
+ }
+
+ TRACE_EVENT_ASYNC_STEP_INTO1("navigation", "NavigationHandle", this,
+ "WillFailRequest", "result", result.action());
+ RunCompleteCallback(result);
+}
+
void NavigationHandleImpl::WillProcessResponse(
RenderFrameHostImpl* render_frame_host,
scoped_refptr<net::HttpResponseHeaders> response_headers,
net::HttpResponseInfo::ConnectionInfo connection_info,
- const SSLStatus& ssl_status,
+ const net::HostPortPair& socket_address,
+ const net::SSLInfo& ssl_info,
const GlobalRequestID& request_id,
bool should_replace_current_entry,
bool is_download,
@@ -705,7 +764,8 @@ void NavigationHandleImpl::WillProcessResponse(
is_download_ = is_download;
is_stream_ = is_stream;
state_ = WILL_PROCESS_RESPONSE;
- ssl_status_ = ssl_status;
+ ssl_info_ = ssl_info;
+ socket_address_ = socket_address;
complete_callback_ = callback;
transfer_callback_ = transfer_callback;
@@ -781,7 +841,6 @@ void NavigationHandleImpl::DidCommitNavigation(
render_frame_host_ = render_frame_host;
previous_url_ = previous_url;
base_url_ = params.base_url;
- socket_address_ = params.socket_address;
navigation_type_ = navigation_type;
// For back-forward navigations, record metrics.
@@ -968,6 +1027,52 @@ NavigationHandleImpl::CheckWillRedirectRequest() {
}
NavigationThrottle::ThrottleCheckResult
+NavigationHandleImpl::CheckWillFailRequest() {
+ DCHECK(state_ == WILL_FAIL_REQUEST || state_ == DEFERRING_FAILURE);
+ DCHECK(state_ != WILL_FAIL_REQUEST || next_index_ == 0);
+ DCHECK(state_ != DEFERRING_FAILURE || next_index_ != 0);
+
+ base::WeakPtr<NavigationHandleImpl> weak_ref = weak_factory_.GetWeakPtr();
+ for (size_t i = next_index_; i < throttles_.size(); ++i) {
+ NavigationThrottle::ThrottleCheckResult result =
+ throttles_[i]->WillFailRequest();
+ if (!weak_ref) {
+ // The NavigationThrottle execution has destroyed this NavigationHandle.
+ // Return immediately.
+ return NavigationThrottle::DEFER;
+ }
+ TRACE_EVENT_ASYNC_STEP_INTO0(
+ "navigation", "NavigationHandle", this,
+ base::StringPrintf("CheckWillFailRequest: %s: %d",
+ throttles_[i]->GetNameForLogging(),
+ result.action()));
+ switch (result.action()) {
+ case NavigationThrottle::PROCEED:
+ continue;
+
+ case NavigationThrottle::CANCEL:
+ case NavigationThrottle::CANCEL_AND_IGNORE:
+ state_ = CANCELING;
+ return result;
+
+ case NavigationThrottle::DEFER:
+ state_ = DEFERRING_FAILURE;
+ next_index_ = i + 1;
+ return result;
+
+ case NavigationThrottle::BLOCK_REQUEST:
+ case NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE:
+ case NavigationThrottle::BLOCK_RESPONSE:
+ NOTREACHED();
+ }
+ }
+ next_index_ = 0;
+ state_ = WILL_FAIL_REQUEST;
+
+ return {NavigationThrottle::PROCEED, net_error_code_};
+}
+
+NavigationThrottle::ThrottleCheckResult
NavigationHandleImpl::CheckWillProcessResponse() {
DCHECK(state_ == WILL_PROCESS_RESPONSE || state_ == DEFERRING_RESPONSE);
DCHECK(state_ != WILL_PROCESS_RESPONSE || next_index_ == 0);
@@ -1015,7 +1120,7 @@ NavigationHandleImpl::CheckWillProcessResponse() {
void NavigationHandleImpl::ResumeInternal() {
DCHECK(state_ == DEFERRING_START || state_ == DEFERRING_REDIRECT ||
- state_ == DEFERRING_RESPONSE)
+ state_ == DEFERRING_FAILURE || state_ == DEFERRING_RESPONSE)
<< "Called ResumeInternal() in state " << state_;
TRACE_EVENT_ASYNC_STEP_INTO0("navigation", "NavigationHandle", this,
"Resume");
@@ -1040,6 +1145,15 @@ void NavigationHandleImpl::ResumeInternal() {
// one of the NavigationThrottle checks.
return;
}
+ } else if (state_ == DEFERRING_FAILURE) {
+ result = CheckWillFailRequest();
+ if (result.action() == NavigationThrottle::DEFER) {
+ if (!on_defer_callback_copy.is_null())
+ on_defer_callback_copy.Run();
+ // DO NOT ADD CODE: the NavigationHandle might have been destroyed during
+ // one of the NavigationThrottle checks.
+ return;
+ }
} else {
result = CheckWillProcessResponse();
if (result.action() == NavigationThrottle::DEFER) {
@@ -1070,7 +1184,7 @@ void NavigationHandleImpl::ResumeInternal() {
void NavigationHandleImpl::CancelDeferredNavigationInternal(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK(state_ == DEFERRING_START || state_ == DEFERRING_REDIRECT ||
- state_ == DEFERRING_RESPONSE);
+ state_ == DEFERRING_FAILURE || state_ == DEFERRING_RESPONSE);
DCHECK(result.action() == NavigationThrottle::CANCEL_AND_IGNORE ||
result.action() == NavigationThrottle::CANCEL ||
result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
@@ -1219,7 +1333,10 @@ void NavigationHandleImpl::RegisterNavigationThrottles() {
AddThrottle(
MixedContentNavigationThrottle::CreateThrottleForNavigation(this));
- AddThrottle(RenderFrameDevToolsAgentHost::CreateThrottleForNavigation(this));
+ for (auto& throttle :
+ RenderFrameDevToolsAgentHost::CreateNavigationThrottles(this)) {
+ AddThrottle(std::move(throttle));
+ }
// Insert all testing NavigationThrottles last.
throttles_.insert(throttles_.end(),
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl.h b/chromium/content/browser/frame_host/navigation_handle_impl.h
index 711b50c3f45..fe65b9e995e 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl.h
+++ b/chromium/content/browser/frame_host/navigation_handle_impl.h
@@ -17,6 +17,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/optional.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/common/content_export.h"
@@ -25,7 +26,6 @@
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/navigation_type.h"
#include "content/public/browser/restore_type.h"
-#include "content/public/browser/ssl_status.h"
#include "content/public/common/request_context_type.h"
#include "third_party/WebKit/public/platform/WebMixedContentContextType.h"
#include "url/gurl.h"
@@ -103,6 +103,8 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
DEFERRING_START,
WILL_REDIRECT_REQUEST,
DEFERRING_REDIRECT,
+ WILL_FAIL_REQUEST,
+ DEFERRING_FAILURE,
CANCELING,
WILL_PROCESS_RESPONSE,
DEFERRING_RESPONSE,
@@ -124,6 +126,7 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
RenderFrameHostImpl* GetParentFrame() override;
const base::TimeTicks& NavigationStart() override;
bool IsPost() override;
+ const scoped_refptr<ResourceRequestBody>& GetResourceRequestBody() override;
const Referrer& GetReferrer() override;
bool HasUserGesture() override;
ui::PageTransition GetPageTransition() override;
@@ -140,6 +143,8 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
net::HostPortPair GetSocketAddress() override;
const net::HttpResponseHeaders* GetResponseHeaders() override;
net::HttpResponseInfo::ConnectionInfo GetConnectionInfo() override;
+ const net::SSLInfo& GetSSLInfo() override;
+ bool ShouldSSLErrorsBeFatal() override;
void RegisterThrottleForTesting(
std::unique_ptr<NavigationThrottle> navigation_throttle) override;
NavigationThrottle::ThrottleCheckResult CallWillStartRequestForTesting(
@@ -153,6 +158,9 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
bool new_method_is_post,
const GURL& new_referrer_url,
bool new_is_external_protocol) override;
+ NavigationThrottle::ThrottleCheckResult CallWillFailRequestForTesting(
+ base::Optional<net::SSLInfo> ssl_info,
+ bool should_ssl_errors_be_fatal) override;
NavigationThrottle::ThrottleCheckResult CallWillProcessResponseForTesting(
RenderFrameHost* render_frame_host,
const std::string& raw_response_header) override;
@@ -240,13 +248,6 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
render_frame_host_ = render_frame_host;
}
- // Returns the POST body associated with this navigation. This will be
- // null for GET and/or other non-POST requests (or if a response to a POST
- // request was a redirect that changed the method to GET - for example 302).
- const scoped_refptr<ResourceRequestBody>& resource_request_body() const {
- return resource_request_body_;
- }
-
// PlzNavigate
void InitServiceWorkerHandle(
ServiceWorkerContextWrapper* service_worker_context);
@@ -307,6 +308,14 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
RenderProcessHost* post_redirect_process,
const ThrottleChecksFinishedCallback& callback);
+ // Called when the URLRequest will fail. |callback| will be called when all
+ // throttles check have completed. This will allow the caller to explicitly
+ // cancel the navigation (with a custom error code and/or custom error page
+ // HTML) or let the failure proceed as normal.
+ void WillFailRequest(base::Optional<net::SSLInfo> ssl_info,
+ bool should_ssl_errors_be_fatal,
+ const ThrottleChecksFinishedCallback& callback);
+
// Called when the URLRequest has delivered response headers and metadata.
// |callback| will be called when all throttle checks have completed,
// allowing the caller to cancel the navigation or let it proceed.
@@ -320,7 +329,8 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
RenderFrameHostImpl* render_frame_host,
scoped_refptr<net::HttpResponseHeaders> response_headers,
net::HttpResponseInfo::ConnectionInfo connection_info,
- const SSLStatus& ssl_status,
+ const net::HostPortPair& socket_address,
+ const net::SSLInfo& ssl_info,
const GlobalRequestID& request_id,
bool should_replace_current_entry,
bool is_download,
@@ -357,8 +367,6 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
navigation_data_ = std::move(navigation_data);
}
- SSLStatus ssl_status() { return ssl_status_; }
-
// Called when the navigation is transferred to a different renderer.
void Transfer();
@@ -419,6 +427,7 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
NavigationThrottle::ThrottleCheckResult CheckWillStartRequest();
NavigationThrottle::ThrottleCheckResult CheckWillRedirectRequest();
+ NavigationThrottle::ThrottleCheckResult CheckWillFailRequest();
NavigationThrottle::ThrottleCheckResult CheckWillProcessResponse();
void ResumeInternal();
@@ -485,6 +494,8 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
bool subframe_entry_committed_;
scoped_refptr<net::HttpResponseHeaders> response_headers_;
net::HttpResponseInfo::ConnectionInfo connection_info_;
+ net::SSLInfo ssl_info_;
+ bool should_ssl_errors_be_fatal_;
// The original url of the navigation. This may differ from |url_| if the
// navigation encounters redirects.
@@ -560,8 +571,6 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
// Embedder data from the UI thread tied to this navigation.
std::unique_ptr<NavigationUIData> navigation_ui_data_;
- SSLStatus ssl_status_;
-
// The unique id to identify this to navigation with.
int64_t navigation_id_;
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 d8584ddeb24..000ac7f401a 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc
@@ -5,9 +5,11 @@
#include "base/command_line.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/weak_ptr.h"
+#include "base/strings/stringprintf.h"
#include "content/browser/frame_host/debug_urls.h"
#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/bindings_policy.h"
@@ -31,6 +33,13 @@
#include "ui/base/page_transition_types.h"
#include "url/url_constants.h"
+namespace {
+
+// Text to place in an HTML body. Should not contain any markup.
+const char kBodyTextContent[] = "some plain text content";
+
+} // namespace
+
namespace content {
namespace {
@@ -42,18 +51,22 @@ class TestNavigationThrottle : public NavigationThrottle {
public:
TestNavigationThrottle(
NavigationHandle* handle,
- NavigationThrottle::ThrottleAction will_start_result,
- NavigationThrottle::ThrottleAction will_redirect_result,
- NavigationThrottle::ThrottleAction will_process_result,
+ NavigationThrottle::ThrottleCheckResult will_start_result,
+ NavigationThrottle::ThrottleCheckResult will_redirect_result,
+ NavigationThrottle::ThrottleCheckResult will_fail_result,
+ NavigationThrottle::ThrottleCheckResult will_process_result,
base::Closure did_call_will_start,
base::Closure did_call_will_redirect,
+ base::Closure did_call_will_fail,
base::Closure did_call_will_process)
: NavigationThrottle(handle),
will_start_result_(will_start_result),
will_redirect_result_(will_redirect_result),
+ will_fail_result_(will_fail_result),
will_process_result_(will_process_result),
did_call_will_start_(did_call_will_start),
did_call_will_redirect_(did_call_will_redirect),
+ did_call_will_fail_(did_call_will_fail),
did_call_will_process_(did_call_will_process) {}
~TestNavigationThrottle() override {}
@@ -92,6 +105,16 @@ class TestNavigationThrottle : public NavigationThrottle {
return will_redirect_result_;
}
+ NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
+ NavigationHandleImpl* navigation_handle_impl =
+ static_cast<NavigationHandleImpl*>(navigation_handle());
+ CHECK_EQ(request_context_type_,
+ navigation_handle_impl->request_context_type());
+
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, did_call_will_fail_);
+ return will_fail_result_;
+ }
+
NavigationThrottle::ThrottleCheckResult WillProcessResponse() override {
NavigationHandleImpl* navigation_handle_impl =
static_cast<NavigationHandleImpl*>(navigation_handle());
@@ -103,11 +126,13 @@ class TestNavigationThrottle : public NavigationThrottle {
return will_process_result_;
}
- NavigationThrottle::ThrottleAction will_start_result_;
- NavigationThrottle::ThrottleAction will_redirect_result_;
- NavigationThrottle::ThrottleAction will_process_result_;
+ NavigationThrottle::ThrottleCheckResult will_start_result_;
+ NavigationThrottle::ThrottleCheckResult will_redirect_result_;
+ NavigationThrottle::ThrottleCheckResult will_fail_result_;
+ NavigationThrottle::ThrottleCheckResult will_process_result_;
base::Closure did_call_will_start_;
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;
};
@@ -120,13 +145,15 @@ class TestNavigationThrottleInstaller : public WebContentsObserver {
public:
TestNavigationThrottleInstaller(
WebContents* web_contents,
- NavigationThrottle::ThrottleAction will_start_result,
- NavigationThrottle::ThrottleAction will_redirect_result,
- NavigationThrottle::ThrottleAction will_process_result,
+ NavigationThrottle::ThrottleCheckResult will_start_result,
+ NavigationThrottle::ThrottleCheckResult will_redirect_result,
+ NavigationThrottle::ThrottleCheckResult will_fail_result,
+ NavigationThrottle::ThrottleCheckResult will_process_result,
const GURL& expected_start_url = GURL())
: WebContentsObserver(web_contents),
will_start_result_(will_start_result),
will_redirect_result_(will_redirect_result),
+ will_fail_result_(will_fail_result),
will_process_result_(will_process_result),
expected_start_url_(expected_start_url),
weak_factory_(this) {}
@@ -150,6 +177,14 @@ class TestNavigationThrottleInstaller : public WebContentsObserver {
will_redirect_loop_runner_ = nullptr;
}
+ void WaitForThrottleWillFail() {
+ if (will_fail_called_)
+ return;
+ will_fail_loop_runner_ = new MessageLoopRunner();
+ will_fail_loop_runner_->Run();
+ will_fail_loop_runner_ = nullptr;
+ }
+
void WaitForThrottleWillProcess() {
if (will_process_called_)
return;
@@ -168,6 +203,7 @@ class TestNavigationThrottleInstaller : public WebContentsObserver {
int will_start_called() { return will_start_called_; }
int will_redirect_called() { return will_redirect_called_; }
+ int will_fail_called() { return will_fail_called_; }
int will_process_called() { return will_process_called_; }
int install_count() { return install_count_; }
@@ -185,6 +221,12 @@ class TestNavigationThrottleInstaller : public WebContentsObserver {
will_redirect_loop_runner_->Quit();
}
+ virtual void DidCallWillFailRequest() {
+ will_fail_called_++;
+ if (will_fail_loop_runner_)
+ will_fail_loop_runner_->Quit();
+ }
+
virtual void DidCallWillProcessResponse() {
will_process_called_++;
if (will_process_loop_runner_)
@@ -198,11 +240,14 @@ class TestNavigationThrottleInstaller : public WebContentsObserver {
return;
std::unique_ptr<NavigationThrottle> throttle(new TestNavigationThrottle(
- handle, will_start_result_, will_redirect_result_, will_process_result_,
+ handle, will_start_result_, will_redirect_result_, will_fail_result_,
+ will_process_result_,
base::Bind(&TestNavigationThrottleInstaller::DidCallWillStartRequest,
weak_factory_.GetWeakPtr()),
base::Bind(&TestNavigationThrottleInstaller::DidCallWillRedirectRequest,
weak_factory_.GetWeakPtr()),
+ base::Bind(&TestNavigationThrottleInstaller::DidCallWillFailRequest,
+ weak_factory_.GetWeakPtr()),
base::Bind(&TestNavigationThrottleInstaller::DidCallWillProcessResponse,
weak_factory_.GetWeakPtr())));
navigation_throttle_ = static_cast<TestNavigationThrottle*>(throttle.get());
@@ -218,16 +263,19 @@ class TestNavigationThrottleInstaller : public WebContentsObserver {
navigation_throttle_ = nullptr;
}
- NavigationThrottle::ThrottleAction will_start_result_;
- NavigationThrottle::ThrottleAction will_redirect_result_;
- NavigationThrottle::ThrottleAction will_process_result_;
+ NavigationThrottle::ThrottleCheckResult will_start_result_;
+ NavigationThrottle::ThrottleCheckResult will_redirect_result_;
+ NavigationThrottle::ThrottleCheckResult will_fail_result_;
+ NavigationThrottle::ThrottleCheckResult will_process_result_;
int will_start_called_ = 0;
int will_redirect_called_ = 0;
+ int will_fail_called_ = 0;
int will_process_called_ = 0;
TestNavigationThrottle* navigation_throttle_ = nullptr;
int install_count_ = 0;
scoped_refptr<MessageLoopRunner> will_start_loop_runner_;
scoped_refptr<MessageLoopRunner> will_redirect_loop_runner_;
+ scoped_refptr<MessageLoopRunner> will_fail_loop_runner_;
scoped_refptr<MessageLoopRunner> will_process_loop_runner_;
GURL expected_start_url_;
@@ -244,17 +292,20 @@ class TestDeferringNavigationThrottleInstaller
public:
TestDeferringNavigationThrottleInstaller(
WebContents* web_contents,
- NavigationThrottle::ThrottleAction will_start_result,
- NavigationThrottle::ThrottleAction will_redirect_result,
- NavigationThrottle::ThrottleAction will_process_result,
+ NavigationThrottle::ThrottleCheckResult will_start_result,
+ NavigationThrottle::ThrottleCheckResult will_redirect_result,
+ NavigationThrottle::ThrottleCheckResult will_fail_result,
+ NavigationThrottle::ThrottleCheckResult will_process_result,
GURL expected_start_url = GURL())
: TestNavigationThrottleInstaller(web_contents,
NavigationThrottle::DEFER,
NavigationThrottle::DEFER,
NavigationThrottle::DEFER,
+ NavigationThrottle::DEFER,
expected_start_url),
will_start_deferred_result_(will_start_result),
will_redirect_deferred_result_(will_redirect_result),
+ will_fail_deferred_result_(will_fail_result),
will_process_deferred_result_(will_process_result) {}
protected:
@@ -268,15 +319,21 @@ class TestDeferringNavigationThrottleInstaller
Continue(will_redirect_deferred_result_);
}
+ void DidCallWillFailRequest() override {
+ TestNavigationThrottleInstaller::DidCallWillStartRequest();
+ Continue(will_fail_deferred_result_);
+ }
+
void DidCallWillProcessResponse() override {
TestNavigationThrottleInstaller::DidCallWillStartRequest();
Continue(will_process_deferred_result_);
}
private:
- NavigationThrottle::ThrottleAction will_start_deferred_result_;
- NavigationThrottle::ThrottleAction will_redirect_deferred_result_;
- NavigationThrottle::ThrottleAction will_process_deferred_result_;
+ NavigationThrottle::ThrottleCheckResult will_start_deferred_result_;
+ NavigationThrottle::ThrottleCheckResult will_redirect_deferred_result_;
+ NavigationThrottle::ThrottleCheckResult will_fail_deferred_result_;
+ NavigationThrottle::ThrottleCheckResult will_process_deferred_result_;
};
// Records all navigation start URLs from the WebContents.
@@ -473,6 +530,28 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, VerifyRedirect) {
}
}
+// Ensure that a certificate error results in a committed navigation with
+// the appropriate error code on the handle.
+IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
+ VerifyCertErrorFailure) {
+ if (!IsBrowserSideNavigationEnabled()) {
+ return;
+ }
+
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
+ ASSERT_TRUE(https_server.Start());
+ GURL url(https_server.GetURL("/title1.html"));
+
+ NavigationHandleObserver observer(shell()->web_contents(), url);
+
+ EXPECT_FALSE(NavigateToURL(shell(), url));
+
+ EXPECT_TRUE(observer.has_committed());
+ EXPECT_TRUE(observer.is_error());
+ EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, observer.net_error_code());
+}
+
// Ensure that the IsRendererInitiated() method on NavigationHandle behaves
// correctly.
IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
@@ -632,7 +711,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleCancelStart) {
NavigationHandleObserver observer(shell()->web_contents(), redirect_url);
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::CANCEL,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
EXPECT_FALSE(NavigateToURL(shell(), redirect_url));
@@ -658,7 +738,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
NavigationHandleObserver observer(shell()->web_contents(), redirect_url);
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::CANCEL, NavigationThrottle::PROCEED);
+ NavigationThrottle::CANCEL, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
EXPECT_FALSE(NavigateToURL(shell(), redirect_url));
@@ -674,7 +755,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
NavigationHandleObserver observer(shell()->web_contents(), no_redirect_url);
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::CANCEL, NavigationThrottle::PROCEED);
+ NavigationThrottle::CANCEL, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
EXPECT_TRUE(NavigateToURL(shell(), no_redirect_url));
@@ -685,6 +767,80 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
}
}
+// Ensure that a NavigationThrottle can respond CANCEL when a navigation fails.
+IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleCancelFailure) {
+ if (!IsBrowserSideNavigationEnabled()) {
+ return;
+ }
+
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
+ ASSERT_TRUE(https_server.Start());
+ GURL url(https_server.GetURL("/title1.html"));
+
+ // A navigation with a cert error failure should be canceled. CANCEL has a
+ // default net error of ERR_ABORTED, which should prevent the navigation from
+ // committing.
+ {
+ TestNavigationThrottleInstaller installer(
+ shell()->web_contents(), NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED, NavigationThrottle::CANCEL,
+ NavigationThrottle::PROCEED);
+
+ NavigationHandleObserver observer(shell()->web_contents(), url);
+
+ EXPECT_FALSE(observer.has_committed());
+ EXPECT_FALSE(observer.is_error());
+
+ EXPECT_FALSE(NavigateToURL(shell(), url));
+
+ EXPECT_FALSE(installer.will_fail_called());
+ EXPECT_FALSE(observer.has_committed());
+ EXPECT_TRUE(observer.is_error());
+ EXPECT_EQ(net::ERR_ABORTED, observer.net_error_code());
+ }
+
+ // A navigation with a cert error failure should be canceled.
+ // A custom net error should result in a committed error page.
+ {
+ TestNavigationThrottleInstaller installer(
+ shell()->web_contents(), NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED,
+ NavigationThrottle::ThrottleCheckResult(NavigationThrottle::CANCEL,
+ net::ERR_CERT_DATE_INVALID),
+ NavigationThrottle::PROCEED);
+
+ NavigationHandleObserver observer(shell()->web_contents(), url);
+
+ EXPECT_FALSE(observer.has_committed());
+ EXPECT_FALSE(observer.is_error());
+
+ EXPECT_FALSE(NavigateToURL(shell(), url));
+
+ EXPECT_TRUE(installer.will_fail_called());
+ EXPECT_TRUE(observer.has_committed());
+ EXPECT_TRUE(observer.is_error());
+ EXPECT_EQ(net::ERR_CERT_DATE_INVALID, observer.net_error_code());
+ }
+
+ // A navigation without a cert error should be successful, without calling
+ // WillFailRequest() on the throttle. (We set the failure method response to
+ // CANCEL, but that shouldn't matter if the test passes.)
+ {
+ GURL url(embedded_test_server()->GetURL("/title2.html"));
+ NavigationHandleObserver observer(shell()->web_contents(), url);
+ TestNavigationThrottleInstaller installer(
+ shell()->web_contents(), NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED, NavigationThrottle::CANCEL,
+ NavigationThrottle::PROCEED);
+
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+
+ EXPECT_FALSE(installer.will_fail_called());
+ EXPECT_FALSE(observer.is_error());
+ }
+}
+
// Ensure that a NavigationThrottle can cancel the navigation when the response
// is received.
IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
@@ -697,7 +853,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
NavigationHandleObserver observer(shell()->web_contents(), redirect_url);
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::CANCEL);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::CANCEL);
EXPECT_FALSE(NavigateToURL(shell(), redirect_url));
@@ -721,7 +878,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleDefer) {
NavigationHandleObserver observer(shell()->web_contents(), redirect_url);
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::DEFER,
- NavigationThrottle::DEFER, NavigationThrottle::DEFER);
+ NavigationThrottle::DEFER, NavigationThrottle::DEFER,
+ NavigationThrottle::DEFER);
shell()->LoadURL(redirect_url);
@@ -729,6 +887,7 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleDefer) {
installer.WaitForThrottleWillStart();
EXPECT_EQ(1, installer.will_start_called());
EXPECT_EQ(0, installer.will_redirect_called());
+ EXPECT_EQ(0, installer.will_fail_called());
EXPECT_EQ(0, installer.will_process_called());
installer.navigation_throttle()->ResumeNavigation();
@@ -736,6 +895,7 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleDefer) {
installer.WaitForThrottleWillRedirect();
EXPECT_EQ(1, installer.will_start_called());
EXPECT_EQ(1, installer.will_redirect_called());
+ EXPECT_EQ(0, installer.will_fail_called());
EXPECT_EQ(0, installer.will_process_called());
installer.navigation_throttle()->ResumeNavigation();
@@ -743,6 +903,7 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleDefer) {
installer.WaitForThrottleWillProcess();
EXPECT_EQ(1, installer.will_start_called());
EXPECT_EQ(1, installer.will_redirect_called());
+ EXPECT_EQ(0, installer.will_fail_called());
EXPECT_EQ(1, installer.will_process_called());
installer.navigation_throttle()->ResumeNavigation();
@@ -756,6 +917,51 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleDefer) {
GURL(embedded_test_server()->GetURL("bar.com", "/title2.html")));
}
+// Ensure that a NavigationThrottle can defer and resume the navigation at
+// navigation start and navigation failure.
+IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, ThrottleDeferFailure) {
+ if (!IsBrowserSideNavigationEnabled()) {
+ return;
+ }
+
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
+ ASSERT_TRUE(https_server.Start());
+ GURL failure_url(https_server.GetURL("/title1.html"));
+
+ TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
+ NavigationHandleObserver observer(shell()->web_contents(), failure_url);
+ TestNavigationThrottleInstaller installer(
+ shell()->web_contents(), NavigationThrottle::DEFER,
+ NavigationThrottle::DEFER, NavigationThrottle::DEFER,
+ NavigationThrottle::DEFER);
+
+ shell()->LoadURL(failure_url);
+
+ // Wait for WillStartRequest.
+ installer.WaitForThrottleWillStart();
+ EXPECT_EQ(1, installer.will_start_called());
+ EXPECT_EQ(0, installer.will_redirect_called());
+ EXPECT_EQ(0, installer.will_fail_called());
+ EXPECT_EQ(0, installer.will_process_called());
+ installer.navigation_throttle()->ResumeNavigation();
+
+ // Wait for WillFailRequest.
+ installer.WaitForThrottleWillFail();
+ EXPECT_EQ(1, installer.will_start_called());
+ EXPECT_EQ(0, installer.will_redirect_called());
+ EXPECT_EQ(1, installer.will_fail_called());
+ EXPECT_EQ(0, installer.will_process_called());
+ installer.navigation_throttle()->ResumeNavigation();
+
+ // Wait for the end of the navigation.
+ navigation_observer.Wait();
+
+ EXPECT_TRUE(observer.has_committed());
+ EXPECT_TRUE(observer.is_error());
+ EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, observer.net_error_code());
+}
+
// Ensure that a NavigationThrottle can block the navigation and collapse the
// frame owner both on request start as well as after a redirect. Plus, ensure
// that the frame is restored on the subsequent non-error-page navigation.
@@ -806,12 +1012,12 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
new TestDeferringNavigationThrottleInstaller(
shell()->web_contents(), test_case.will_start_result,
test_case.will_redirect_result, NavigationThrottle::PROCEED,
- blocked_subframe_url));
+ NavigationThrottle::PROCEED, blocked_subframe_url));
} else {
subframe_throttle_installer.reset(new TestNavigationThrottleInstaller(
shell()->web_contents(), test_case.will_start_result,
test_case.will_redirect_result, NavigationThrottle::PROCEED,
- blocked_subframe_url));
+ NavigationThrottle::PROCEED, blocked_subframe_url));
}
{
@@ -874,7 +1080,7 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
TestNavigationThrottleInstaller subframe_throttle_installer(
shell()->web_contents(), NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE,
NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
- blocked_subframe_url);
+ NavigationThrottle::PROCEED, blocked_subframe_url);
{
SCOPED_TRACE("Initial navigation blocked on main frame load.");
@@ -917,7 +1123,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
TestNavigationManager main_manager(shell()->web_contents(), main_url);
TestNavigationManager b_manager(shell()->web_contents(), b_url);
TestNavigationManager c_manager(shell()->web_contents(), c_url);
@@ -968,7 +1175,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
TestNavigationManager link_manager(shell()->web_contents(), link_url);
NavigationStartUrlRecorder url_recorder(shell()->web_contents());
@@ -1004,7 +1212,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
TestNavigationManager post_manager(shell()->web_contents(), post_url);
NavigationStartUrlRecorder url_recorder(shell()->web_contents());
@@ -1041,7 +1250,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
// WillStartRequest.
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::CANCEL_AND_IGNORE,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver observer(shell()->web_contents(), kUrl);
// Try to navigate to the url. The navigation should be canceled and the
@@ -1055,7 +1265,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
// WillRedirectRequest.
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::CANCEL_AND_IGNORE, NavigationThrottle::PROCEED);
+ NavigationThrottle::CANCEL_AND_IGNORE, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver observer(shell()->web_contents(), kRedirectingUrl);
// Try to navigate to the url. The navigation should be canceled and the
@@ -1069,7 +1280,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
// WillProcessResponse.
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::CANCEL_AND_IGNORE);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::CANCEL_AND_IGNORE);
NavigationHandleObserver observer(shell()->web_contents(), kUrl);
// Try to navigate to the url. The navigation should be canceled and the
@@ -1083,7 +1295,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
// WillStartRequest.
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::BLOCK_REQUEST,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver observer(shell()->web_contents(), kUrl);
// Try to navigate to the url. The navigation should be canceled and the
@@ -1098,7 +1311,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
// WillRedirectRequest.
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED);
+ NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver observer(shell()->web_contents(), kRedirectingUrl);
// Try to navigate to the url. The navigation should be canceled and the
@@ -1128,7 +1342,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
// WillStartRequest.
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::CANCEL_AND_IGNORE,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
EXPECT_FALSE(NavigateToURL(shell(), kUrl2));
}
@@ -1146,7 +1361,8 @@ class NavigationHandleImplHttpsUpgradeBrowserTest
NavigationStartUrlRecorder url_recorder(shell()->web_contents());
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
TestNavigationManager navigation_manager(shell()->web_contents(),
iframe_secure_url);
@@ -1208,7 +1424,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
{
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver observer(shell()->web_contents(), url);
EXPECT_TRUE(NavigateToURL(shell(), url));
EXPECT_EQ(1, installer.will_start_called());
@@ -1220,7 +1437,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
{
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver observer(shell()->web_contents(), url_fragment_1);
EXPECT_TRUE(NavigateToURL(shell(), url_fragment_1));
EXPECT_EQ(0, installer.will_start_called());
@@ -1232,7 +1450,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
{
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver observer(shell()->web_contents(), url_fragment_2);
EXPECT_TRUE(NavigateToURL(shell(), url_fragment_2));
EXPECT_EQ(0, installer.will_start_called());
@@ -1244,7 +1463,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
{
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver observer(shell()->web_contents(), url_fragment_2);
EXPECT_TRUE(NavigateToURL(shell(), url_fragment_2));
EXPECT_EQ(1, installer.will_start_called());
@@ -1256,7 +1476,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
{
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver observer(shell()->web_contents(), url);
EXPECT_TRUE(NavigateToURL(shell(), url));
EXPECT_EQ(1, installer.will_start_called());
@@ -1322,7 +1543,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, BlockedOnRedirect) {
// WillRedirectRequest.
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED);
+ NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver observer(shell()->web_contents(), kRedirectingUrl);
NavigationLogger logger(shell()->web_contents());
@@ -1408,9 +1630,10 @@ IN_PROC_BROWSER_TEST_F(PlzNavigateNavigationHandleImplBrowserTest,
scoped_refptr<SiteInstance> site_instance =
shell()->web_contents()->GetMainFrame()->GetSiteInstance();
- auto installer = base::MakeUnique<TestNavigationThrottleInstaller>(
+ auto installer = std::make_unique<TestNavigationThrottleInstaller>(
shell()->web_contents(), NavigationThrottle::BLOCK_REQUEST,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
{
// A blocked, renderer-initiated navigation should commit an error page
@@ -1476,9 +1699,10 @@ IN_PROC_BROWSER_TEST_F(PlzNavigateNavigationHandleImplBrowserTest,
shell()->web_contents()->GetMainFrame()->GetSiteInstance());
}
- installer = base::MakeUnique<TestNavigationThrottleInstaller>(
+ installer = std::make_unique<TestNavigationThrottleInstaller>(
shell()->web_contents(), NavigationThrottle::BLOCK_REQUEST,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
{
// A blocked, browser-initiated navigation should commit an error page in a
@@ -1553,7 +1777,8 @@ IN_PROC_BROWSER_TEST_F(PlzNavigateNavigationHandleImplBrowserTest,
GURL blocked_url("http://blocked-by-throttle.example.cc");
TestNavigationThrottleInstaller installer(
web_contents, NavigationThrottle::BLOCK_REQUEST,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigationHandleObserver commit_observer(web_contents, blocked_url);
EXPECT_FALSE(NavigateToURL(shell(), blocked_url));
NavigationEntry* last_committed =
@@ -1698,7 +1923,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
iframe_url);
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
NavigateIframeToURL(shell()->web_contents(), "child0", iframe_url);
@@ -1756,7 +1982,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplDownloadBrowserTest,
NavigationHandleObserver observer(shell()->web_contents(), url);
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::CANCEL,
- NavigationThrottle::PROCEED, NavigationThrottle::PROCEED);
+ NavigationThrottle::PROCEED, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
EXPECT_FALSE(NavigateToURL(shell(), url));
EXPECT_FALSE(observer.has_committed());
@@ -1782,7 +2009,8 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplDownloadBrowserTest,
NavigationHandleObserver observer(shell()->web_contents(), redirect_url);
TestNavigationThrottleInstaller installer(
shell()->web_contents(), NavigationThrottle::PROCEED,
- NavigationThrottle::CANCEL, NavigationThrottle::PROCEED);
+ NavigationThrottle::CANCEL, NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED);
EXPECT_FALSE(NavigateToURL(shell(), redirect_url));
@@ -1792,4 +2020,36 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplDownloadBrowserTest,
EXPECT_TRUE(observer.was_redirected());
}
+IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
+ ThrottleFailureWithErrorPageContent) {
+ if (!IsBrowserSideNavigationEnabled())
+ return;
+
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
+ ASSERT_TRUE(https_server.Start());
+ GURL url(https_server.GetURL("/title1.html"));
+
+ NavigationThrottle::ThrottleCheckResult cancel_result = {
+ NavigationThrottle::CANCEL, net::ERR_CERT_COMMON_NAME_INVALID,
+ base::StringPrintf("<html><body>%s</body><html>", kBodyTextContent)};
+
+ NavigationHandleObserver observer(shell()->web_contents(), url);
+ TestNavigationThrottleInstaller installer(
+ shell()->web_contents(), NavigationThrottle::PROCEED,
+ NavigationThrottle::PROCEED, cancel_result, NavigationThrottle::PROCEED);
+
+ EXPECT_FALSE(NavigateToURL(shell(), url));
+
+ EXPECT_TRUE(observer.has_committed());
+ EXPECT_TRUE(observer.is_error());
+
+ std::string result;
+ const std::string javascript =
+ "domAutomationController.send(document.body.textContent)";
+ content::RenderFrameHost* rfh = shell()->web_contents()->GetMainFrame();
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(rfh, javascript, &result));
+ EXPECT_EQ(kBodyTextContent, result);
+}
+
} // namespace content
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 467a882fa87..5f7e8cba351 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc
@@ -4,6 +4,7 @@
#include "content/browser/frame_host/navigation_handle_impl.h"
#include "base/macros.h"
+#include "base/optional.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/common/browser_side_navigation_policy.h"
@@ -14,6 +15,7 @@
#include "content/test/test_content_browser_client.h"
#include "content/test/test_render_frame_host.h"
#include "content/test/test_web_contents.h"
+#include "net/ssl/ssl_connection_status_flags.h"
namespace content {
@@ -55,6 +57,11 @@ class DeletingNavigationThrottle : public NavigationThrottle {
return NavigationThrottle::PROCEED;
}
+ NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
+ deletion_callback_.Run();
+ return NavigationThrottle::PROCEED;
+ }
+
NavigationThrottle::ThrottleCheckResult WillProcessResponse() override {
deletion_callback_.Run();
return NavigationThrottle::PROCEED;
@@ -89,22 +96,6 @@ class NavigationHandleImplTest : public RenderViewHostImplTestHarness {
RenderViewHostImplTestHarness::TearDown();
}
- bool IsDeferringStart() {
- return test_handle_->state() == NavigationHandleImpl::DEFERRING_START;
- }
-
- bool IsDeferringRedirect() {
- return test_handle_->state() == NavigationHandleImpl::DEFERRING_REDIRECT;
- }
-
- bool IsDeferringResponse() {
- return test_handle_->state() == NavigationHandleImpl::DEFERRING_RESPONSE;
- }
-
- bool IsCanceling() {
- return test_handle_->state() == NavigationHandleImpl::CANCELING;
- }
-
void Resume() { test_handle_->ResumeInternal(); }
void CancelDeferredNavigation(
@@ -147,6 +138,24 @@ class NavigationHandleImplTest : public RenderViewHostImplTestHarness {
base::Unretained(this)));
}
+ // Helper function to call WillFailRequest on |handle|. If this function
+ // returns DEFER, |callback_result_| will be set to the actual result of the
+ // throttle checks when they are finished.
+ void SimulateWillFailRequest(
+ net::Error net_error_code,
+ const base::Optional<net::SSLInfo> ssl_info = base::nullopt) {
+ was_callback_called_ = false;
+ callback_result_ = NavigationThrottle::DEFER;
+ test_handle_->set_net_error_code(net_error_code);
+
+ // It's safe to use base::Unretained since the NavigationHandle is owned by
+ // the NavigationHandleImplTest.
+ test_handle_->WillFailRequest(
+ ssl_info, false,
+ base::Bind(&NavigationHandleImplTest::UpdateThrottleCheckResult,
+ base::Unretained(this)));
+ }
+
// Helper function to call WillProcessResponse on |handle|. If this function
// returns DEFER, |callback_result_| will be set to the actual result of the
// throttle checks when they are finished.
@@ -162,8 +171,8 @@ class NavigationHandleImplTest : public RenderViewHostImplTestHarness {
// in both cases.
test_handle_->WillProcessResponse(
main_test_rfh(), scoped_refptr<net::HttpResponseHeaders>(),
- net::HttpResponseInfo::CONNECTION_INFO_QUIC_35, SSLStatus(),
- GlobalRequestID(), false, false, false, base::Closure(),
+ net::HttpResponseInfo::CONNECTION_INFO_QUIC_35, net::HostPortPair(),
+ net::SSLInfo(), GlobalRequestID(), false, false, false, base::Closure(),
base::Bind(&NavigationHandleImplTest::UpdateThrottleCheckResult,
base::Unretained(this)));
}
@@ -179,8 +188,37 @@ class NavigationHandleImplTest : public RenderViewHostImplTestHarness {
return callback_result_;
}
- // Creates, register and returns a TestNavigationThrottle that will return
- // |result| on checks.
+ NavigationHandleImpl::State state() { return test_handle_->state(); }
+
+ bool is_deferring() {
+ switch (state()) {
+ case NavigationHandleImpl::DEFERRING_START:
+ case NavigationHandleImpl::DEFERRING_REDIRECT:
+ case NavigationHandleImpl::DEFERRING_FAILURE:
+ case NavigationHandleImpl::DEFERRING_RESPONSE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool call_counts_match(TestNavigationThrottle* throttle,
+ int start,
+ int redirect,
+ int failure,
+ int process) {
+ return start == throttle->GetCallCount(
+ TestNavigationThrottle::WILL_START_REQUEST) &&
+ redirect == throttle->GetCallCount(
+ TestNavigationThrottle::WILL_REDIRECT_REQUEST) &&
+ failure == throttle->GetCallCount(
+ TestNavigationThrottle::WILL_FAIL_REQUEST) &&
+ process == throttle->GetCallCount(
+ TestNavigationThrottle::WILL_PROCESS_RESPONSE);
+ }
+
+ // Creates, register and returns a TestNavigationThrottle that will
+ // synchronously return |result| on checks by default.
TestNavigationThrottle* CreateTestNavigationThrottle(
NavigationThrottle::ThrottleCheckResult result) {
TestNavigationThrottle* test_throttle =
@@ -192,12 +230,25 @@ class NavigationHandleImplTest : public RenderViewHostImplTestHarness {
return test_throttle;
}
+ // Creates, register and returns a TestNavigationThrottle that will
+ // synchronously return |result| on check for the given |method|, and
+ // NavigationThrottle::PROCEED otherwise.
+ TestNavigationThrottle* CreateTestNavigationThrottle(
+ TestNavigationThrottle::ThrottleMethod method,
+ NavigationThrottle::ThrottleCheckResult result) {
+ TestNavigationThrottle* test_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
+ test_throttle->SetResponse(method, TestNavigationThrottle::SYNCHRONOUS,
+ result);
+ return test_throttle;
+ }
+
// Creates and register a NavigationThrottle that will delete the
// NavigationHandle in checks.
void AddDeletingNavigationThrottle() {
DCHECK(test_handle_);
test_handle()->RegisterThrottleForTesting(
- base::MakeUnique<DeletingNavigationThrottle>(
+ std::make_unique<DeletingNavigationThrottle>(
test_handle(), base::BindRepeating(
&NavigationHandleImplTest::ResetNavigationHandle,
base::Unretained(this))));
@@ -215,8 +266,9 @@ class NavigationHandleImplTest : public RenderViewHostImplTestHarness {
}
private:
- // The callback provided to NavigationHandleImpl::WillStartRequest and
- // NavigationHandleImpl::WillRedirectRequest during the tests.
+ // The callback provided to NavigationHandleImpl::WillStartRequest,
+ // NavigationHandleImpl::WillRedirectRequest, and
+ // NavigationHandleImpl::WillFailRequest during the tests.
void UpdateThrottleCheckResult(
NavigationThrottle::ThrottleCheckResult result) {
callback_result_ = result;
@@ -241,7 +293,7 @@ class NavigationHandleImplThrottleInsertionTest
RenderViewHostImplTestHarness::SetUp();
contents()->GetMainFrame()->InitializeRenderFrameIfNeeded();
test_browser_client_ =
- base::MakeUnique<ThrottleInserterContentBrowserClient>(
+ std::make_unique<ThrottleInserterContentBrowserClient>(
base::Bind(&NavigationHandleImplThrottleInsertionTest::GetThrottles,
base::Unretained(this)));
old_browser_client_ =
@@ -258,7 +310,7 @@ class NavigationHandleImplThrottleInsertionTest
private:
std::vector<std::unique_ptr<NavigationThrottle>> GetThrottles(
NavigationHandle* handle) {
- auto throttle = base::MakeUnique<TestNavigationThrottle>(handle);
+ auto throttle = std::make_unique<TestNavigationThrottle>(handle);
std::vector<std::unique_ptr<NavigationThrottle>> vec;
throttles_inserted_++;
vec.push_back(std::move(throttle));
@@ -286,7 +338,7 @@ TEST_F(NavigationHandleImplThrottleInsertionTest,
// Checks that the request_context_type is properly set.
// Note: can be extended to cover more internal members.
-TEST_F(NavigationHandleImplTest, SimpleDataChecks) {
+TEST_F(NavigationHandleImplTest, SimpleDataChecksRedirectAndProcess) {
SimulateWillStartRequest();
EXPECT_EQ(REQUEST_CONTEXT_TYPE_LOCATION,
test_handle()->request_context_type());
@@ -316,149 +368,122 @@ TEST_F(NavigationHandleImplTest, SimpleDataCheckNoRedirect) {
test_handle()->GetConnectionInfo());
}
-// Checks that a deferred navigation can be properly resumed.
-TEST_F(NavigationHandleImplTest, ResumeDeferred) {
+TEST_F(NavigationHandleImplTest, SimpleDataChecksFailure) {
+ SimulateWillStartRequest();
+ EXPECT_EQ(REQUEST_CONTEXT_TYPE_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,
+ test_handle()->request_context_type());
+ EXPECT_EQ(net::ERR_CERT_DATE_INVALID, test_handle()->GetNetErrorCode());
+}
+
+// Checks that a navigation deferred by WillRedirectRequest can be properly
+// resumed.
+TEST_F(NavigationHandleImplTest, ResumeDeferredWillRedirectRequest) {
TestNavigationThrottle* test_throttle =
CreateTestNavigationThrottle(NavigationThrottle::DEFER);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
// Simulate WillStartRequest. The request should be deferred. The callback
// should not have been called.
SimulateWillStartRequest();
- EXPECT_TRUE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_START, state());
EXPECT_FALSE(was_callback_called());
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
// Resume the request. It should no longer be deferred and the callback
// should have been called.
Resume();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_FALSE(is_deferring());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
// Simulate WillRedirectRequest. The request should be deferred. The callback
// should not have been called.
SimulateWillRedirectRequest();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_TRUE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_REDIRECT, state());
EXPECT_FALSE(was_callback_called());
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 1, 0, 0));
// Resume the request. It should no longer be deferred and the callback
// should have been called.
Resume();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_FALSE(is_deferring());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 1, 0, 0));
// Simulate WillProcessResponse. It will be deferred. The callback should not
// have been called.
SimulateWillProcessResponse();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_TRUE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_RESPONSE, state());
EXPECT_FALSE(was_callback_called());
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 1, 0, 1));
// Resume the request. It should no longer be deferred and the callback should
// have been called.
Resume();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_FALSE(is_deferring());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 1, 0, 1));
EXPECT_TRUE(test_handle()->GetRenderFrameHost());
}
+// Checks that a navigation deferred by WillFailRequest can be properly resumed.
+TEST_F(NavigationHandleImplTest, ResumeDeferredWillFailRequest) {
+ TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
+ TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
+
+ // Simulate WillStartRequest.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
+
+ // Simulate WillFailRequest. The request should be deferred. The callback
+ // should not have been called.
+ SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_FAILURE, state());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
+
+ // Resume the request. It should no longer be deferred and the callback
+ // should have been called.
+ Resume();
+ EXPECT_FALSE(is_deferring());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
+}
+
// Checks that a navigation deferred during WillStartRequest can be properly
// cancelled.
TEST_F(NavigationHandleImplTest, CancelDeferredWillStart) {
TestNavigationThrottle* test_throttle =
CreateTestNavigationThrottle(NavigationThrottle::DEFER);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
// Simulate WillStartRequest. The request should be deferred. The callback
// should not have been called.
SimulateWillStartRequest();
- EXPECT_TRUE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_START, state());
EXPECT_FALSE(was_callback_called());
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
// Cancel the request. The callback should have been called.
CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_TRUE(IsCanceling());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
}
// Checks that a navigation deferred during WillRedirectRequest can be properly
@@ -466,178 +491,182 @@ TEST_F(NavigationHandleImplTest, CancelDeferredWillStart) {
TEST_F(NavigationHandleImplTest, CancelDeferredWillRedirect) {
TestNavigationThrottle* test_throttle =
CreateTestNavigationThrottle(NavigationThrottle::DEFER);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should be deferred. The callback
// should not have been called.
SimulateWillRedirectRequest();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_TRUE(IsDeferringRedirect());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_REDIRECT, state());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0));
+
+ // Cancel the request. The callback should have been called.
+ CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
+ EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0));
+}
+
+// Checks that a navigation deferred during WillFailRequest can be properly
+// cancelled.
+TEST_F(NavigationHandleImplTest, CancelDeferredWillFail) {
+ TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
+ TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
+
+ // Simulate WillStartRequest.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
+
+ // Simulate WillFailRequest. The request should be deferred. The callback
+ // should not have been called.
+ SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_FAILURE, state());
EXPECT_FALSE(was_callback_called());
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
// Cancel the request. The callback should have been called.
CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_TRUE(IsCanceling());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
}
// Checks that a navigation deferred can be canceled and not ignored.
-TEST_F(NavigationHandleImplTest, CancelDeferredNoIgnore) {
+TEST_F(NavigationHandleImplTest, CancelDeferredWillRedirectNoIgnore) {
TestNavigationThrottle* test_throttle =
CreateTestNavigationThrottle(NavigationThrottle::DEFER);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
- // Simulate WillRedirectRequest. The request should be deferred. The callback
+ // Simulate WillStartRequest. The request should be deferred. The callback
// should not have been called.
SimulateWillStartRequest();
- EXPECT_TRUE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_START, state());
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
+
+ // Cancel the request. The callback should have been called with CANCEL, and
+ // not CANCEL_AND_IGNORE.
+ CancelDeferredNavigation(NavigationThrottle::CANCEL);
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
+}
+
+// Checks that a navigation deferred by WillFailRequest can be canceled and not
+// ignored.
+TEST_F(NavigationHandleImplTest, CancelDeferredWillFailNoIgnore) {
+ TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
+ TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
+
+ // Simulate WillStartRequest.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
+
+ // Simulate WillFailRequest. The request should be deferred. The callback
+ // should not have been called.
+ SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_FAILURE, state());
EXPECT_FALSE(was_callback_called());
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
// Cancel the request. The callback should have been called with CANCEL, and
// not CANCEL_AND_IGNORE.
CancelDeferredNavigation(NavigationThrottle::CANCEL);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_TRUE(IsCanceling());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
- EXPECT_EQ(1, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, test_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
}
-// Checks that a NavigationThrottle asking to defer followed by a
-// NavigationThrottle asking to proceed behave correctly.
-TEST_F(NavigationHandleImplTest, DeferThenProceed) {
+// Checks that a NavigationThrottle asking during WillRedirectRequest to defer
+// followed by a NavigationThrottle asking to proceed behave correctly.
+TEST_F(NavigationHandleImplTest, DeferThenProceedWillRedirect) {
TestNavigationThrottle* defer_throttle =
CreateTestNavigationThrottle(NavigationThrottle::DEFER);
TestNavigationThrottle* proceed_throttle =
CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(defer_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
// Simulate WillStartRequest. The request should be deferred. The callback
// should not have been called. The second throttle should not have been
// notified.
SimulateWillStartRequest();
- EXPECT_TRUE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_START, state());
EXPECT_FALSE(was_callback_called());
- EXPECT_EQ(1, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
// Resume the request. It should no longer be deferred and the callback
// should have been called. The second throttle should have been notified.
Resume();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_FALSE(is_deferring());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
- EXPECT_EQ(1, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(1, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 1, 0, 0, 0));
// Simulate WillRedirectRequest. The request should be deferred. The callback
// should not have been called. The second throttle should not have been
// notified.
SimulateWillRedirectRequest();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_TRUE(IsDeferringRedirect());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_REDIRECT, state());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 1, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 1, 0, 0, 0));
+
+ // Resume the request. It should no longer be deferred and the callback
+ // should have been called. The second throttle should have been notified.
+ Resume();
+ EXPECT_FALSE(is_deferring());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 1, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 1, 1, 0, 0));
+}
+
+// Checks that a NavigationThrottle asking during WillFailRequest to defer
+// followed by a NavigationThrottle asking to proceed behave correctly.
+TEST_F(NavigationHandleImplTest, DeferThenProceedWillFail) {
+ TestNavigationThrottle* defer_throttle = CreateTestNavigationThrottle(
+ TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
+ TestNavigationThrottle* proceed_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(defer_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
+
+ // Simulate WillStartRequest.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 1, 0, 0, 0));
+
+ // Simulate WillFailRequest. The request should be deferred. The callback
+ // should not have been called. The second throttle should not have been
+ // notified.
+ SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_FAILURE, state());
EXPECT_FALSE(was_callback_called());
- EXPECT_EQ(1, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(1, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 0, 1, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 1, 0, 0, 0));
// Resume the request. It should no longer be deferred and the callback
// should have been called. The second throttle should have been notified.
Resume();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_FALSE(is_deferring());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::PROCEED, callback_result());
- EXPECT_EQ(1, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(1, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 0, 1, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 1, 0, 1, 0));
}
// Checks that a NavigationThrottle asking to defer followed by a
@@ -647,55 +676,27 @@ TEST_F(NavigationHandleImplTest, DeferThenCancelWillStartRequest) {
CreateTestNavigationThrottle(NavigationThrottle::DEFER);
TestNavigationThrottle* cancel_throttle =
CreateTestNavigationThrottle(NavigationThrottle::CANCEL_AND_IGNORE);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(defer_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
// Simulate WillStartRequest. The request should be deferred. The callback
// should not have been called. The second throttle should not have been
// notified.
SimulateWillStartRequest();
- EXPECT_TRUE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_START, state());
EXPECT_FALSE(was_callback_called());
- EXPECT_EQ(1, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
// Resume the request. The callback should have been called. The second
// throttle should have been notified.
Resume();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_TRUE(IsCanceling());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
- EXPECT_EQ(1, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(1, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 1, 0, 0, 0));
}
// Checks that a NavigationThrottle asking to defer followed by a
@@ -705,55 +706,63 @@ TEST_F(NavigationHandleImplTest, DeferThenCancelWillRedirectRequest) {
CreateTestNavigationThrottle(NavigationThrottle::DEFER);
TestNavigationThrottle* cancel_throttle =
CreateTestNavigationThrottle(NavigationThrottle::CANCEL_AND_IGNORE);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(defer_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should be deferred. The callback
// should not have been called. The second throttle should not have been
// notified.
SimulateWillRedirectRequest();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_TRUE(IsDeferringRedirect());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_REDIRECT, state());
EXPECT_FALSE(was_callback_called());
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_TRUE(call_counts_match(defer_throttle, 0, 1, 0, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
// Resume the request. The callback should have been called. The second
// throttle should have been notified.
Resume();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_TRUE(IsCanceling());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, defer_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_TRUE(call_counts_match(defer_throttle, 0, 1, 0, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 1, 0, 0));
+}
+
+// Checks that a NavigationThrottle asking to defer followed by a
+// NavigationThrottle asking to cancel behave correctly in WillFailRequest.
+TEST_F(NavigationHandleImplTest, DeferThenCancelWillFailRequest) {
+ TestNavigationThrottle* defer_throttle = CreateTestNavigationThrottle(
+ TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
+ TestNavigationThrottle* cancel_throttle =
+ CreateTestNavigationThrottle(TestNavigationThrottle::WILL_FAIL_REQUEST,
+ NavigationThrottle::CANCEL_AND_IGNORE);
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(defer_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
+
+ // Simulate WillStartRequest.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 1, 0, 0, 0));
+
+ // Simulate WillFailRequest. The request should be deferred. The callback
+ // should not have been called. The second throttle should not have been
+ // notified.
+ SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_FAILURE, state());
+ EXPECT_FALSE(was_callback_called());
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 0, 1, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 1, 0, 0, 0));
+
+ // Resume the request. The callback should have been called. The second
+ // throttle should have been notified.
+ Resume();
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
+ EXPECT_TRUE(call_counts_match(defer_throttle, 1, 0, 1, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 1, 0, 1, 0));
}
// Checks that a NavigationThrottle asking to cancel followed by a
@@ -765,37 +774,19 @@ TEST_F(NavigationHandleImplTest, CancelThenProceedWillStartRequest) {
CreateTestNavigationThrottle(NavigationThrottle::CANCEL_AND_IGNORE);
TestNavigationThrottle* proceed_throttle =
CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
// Simulate WillStartRequest. The request should not be deferred. The
// callback should not have been called. The second throttle should not have
// been notified.
SimulateWillStartRequest();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_FALSE(is_deferring());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
- EXPECT_EQ(1, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 1, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
}
// Checks that a NavigationThrottle asking to cancel followed by a
@@ -807,37 +798,49 @@ TEST_F(NavigationHandleImplTest, CancelThenProceedWillRedirectRequest) {
CreateTestNavigationThrottle(NavigationThrottle::CANCEL_AND_IGNORE);
TestNavigationThrottle* proceed_throttle =
CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should not have been called. The second throttle should not have
// been notified.
SimulateWillRedirectRequest();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_FALSE(is_deferring());
+ EXPECT_TRUE(was_callback_called());
+ EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 1, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
+}
+
+// Checks that a NavigationThrottle asking to cancel followed by a
+// NavigationThrottle asking to proceed behave correctly in WillFailRequest.
+// The navigation will be canceled directly, and the second throttle will not
+// be called.
+TEST_F(NavigationHandleImplTest, CancelThenProceedWillFailRequest) {
+ TestNavigationThrottle* cancel_throttle =
+ CreateTestNavigationThrottle(TestNavigationThrottle::WILL_FAIL_REQUEST,
+ NavigationThrottle::CANCEL_AND_IGNORE);
+ TestNavigationThrottle* proceed_throttle =
+ CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
+
+ // Simulate WillStartRequest.
+ SimulateWillStartRequest();
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 1, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 1, 0, 0, 0));
+
+ // Simulate WillFailRequest. The request should not be deferred. The
+ // callback should not have been called. The second throttle should not have
+ // been notified.
+ SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
+ EXPECT_FALSE(is_deferring());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 1, 0, 1, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 1, 0, 0, 0));
}
// Checks that a NavigationThrottle asking to proceed followed by a
@@ -848,40 +851,18 @@ TEST_F(NavigationHandleImplTest, ProceedThenCancelWillProcessResponse) {
CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
TestNavigationThrottle* cancel_throttle =
CreateTestNavigationThrottle(NavigationThrottle::CANCEL_AND_IGNORE);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called.
SimulateWillProcessResponse();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
+ EXPECT_FALSE(is_deferring());
EXPECT_TRUE(was_callback_called());
EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(1, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(1, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 1));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 1));
}
// Checks that a NavigationThrottle asking to cancel followed by a
@@ -893,41 +874,19 @@ TEST_F(NavigationHandleImplTest, CancelThenProceedWillProcessResponse) {
CreateTestNavigationThrottle(NavigationThrottle::CANCEL_AND_IGNORE);
TestNavigationThrottle* proceed_throttle =
CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
// Simulate WillProcessResponse. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillProcessResponse();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
- EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(1, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 1));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
}
// Checks that a NavigationThrottle asking to block the response followed by a
@@ -939,141 +898,80 @@ TEST_F(NavigationHandleImplTest, BlockResponseThenProceedWillProcessResponse) {
CreateTestNavigationThrottle(NavigationThrottle::BLOCK_RESPONSE);
TestNavigationThrottle* proceed_throttle =
CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
+ EXPECT_EQ(NavigationHandleImpl::INITIAL, state());
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 0));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillProcessResponse();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
- EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_RESPONSE, callback_result());
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(1, cancel_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, proceed_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(cancel_throttle, 0, 0, 0, 1));
+ EXPECT_TRUE(call_counts_match(proceed_throttle, 0, 0, 0, 0));
}
TEST_F(NavigationHandleImplTest, BlockRequestCustomNetError) {
- TestNavigationThrottle* blocked_throttle = CreateTestNavigationThrottle(
+ TestNavigationThrottle* block_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_REQUEST, net::ERR_BLOCKED_BY_ADMINISTRATOR});
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillStartRequest();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
- EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result().action());
EXPECT_EQ(net::ERR_BLOCKED_BY_ADMINISTRATOR,
callback_result().net_error_code());
EXPECT_FALSE(callback_result().error_page_content().has_value());
- EXPECT_EQ(1, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 1, 0, 0, 0));
}
TEST_F(NavigationHandleImplTest, BlockRequestCustomNetErrorAndErrorHTML) {
std::string expected_error_page_content("<html><body>test</body></html>");
- TestNavigationThrottle* blocked_throttle = CreateTestNavigationThrottle(
+ TestNavigationThrottle* block_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_REQUEST, net::ERR_BLOCKED_BY_ADMINISTRATOR,
expected_error_page_content});
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillStartRequest();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
- EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result());
EXPECT_EQ(net::ERR_BLOCKED_BY_ADMINISTRATOR,
callback_result().net_error_code());
EXPECT_TRUE(callback_result().error_page_content().has_value());
EXPECT_EQ(expected_error_page_content,
callback_result().error_page_content().value());
- EXPECT_EQ(1, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 1, 0, 0, 0));
}
TEST_F(NavigationHandleImplTest, BlockRequestCustomNetErrorInRedirect) {
// BLOCK_REQUEST on redirect requires PlzNavigate.
EnableBrowserSideNavigation();
- TestNavigationThrottle* blocked_throttle = CreateTestNavigationThrottle(
+ TestNavigationThrottle* block_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_REQUEST, net::ERR_FILE_NOT_FOUND});
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillRedirectRequest();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
- EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result().action());
EXPECT_EQ(net::ERR_FILE_NOT_FOUND, callback_result().net_error_code());
EXPECT_FALSE(callback_result().error_page_content().has_value());
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 0, 1, 0, 0));
}
TEST_F(NavigationHandleImplTest,
@@ -1081,67 +979,41 @@ TEST_F(NavigationHandleImplTest,
// BLOCK_REQUEST on redirect requires PlzNavigate.
EnableBrowserSideNavigation();
std::string expected_error_page_content("<html><body>test</body></html>");
- TestNavigationThrottle* blocked_throttle = CreateTestNavigationThrottle(
+ TestNavigationThrottle* block_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_REQUEST, net::ERR_FILE_NOT_FOUND,
expected_error_page_content});
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillRedirectRequest();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
- EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result());
EXPECT_EQ(NavigationThrottle::BLOCK_REQUEST, callback_result().action());
EXPECT_EQ(net::ERR_FILE_NOT_FOUND, callback_result().net_error_code());
EXPECT_TRUE(callback_result().error_page_content().has_value());
EXPECT_EQ(expected_error_page_content,
callback_result().error_page_content().value());
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(1, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, blocked_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 0, 1, 0, 0));
}
TEST_F(NavigationHandleImplTest, BlockResponseCustomNetError) {
TestNavigationThrottle* block_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_RESPONSE, net::ERR_FILE_VIRUS_INFECTED});
- EXPECT_EQ(0, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillProcessResponse();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
- EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_RESPONSE, callback_result());
EXPECT_EQ(NavigationThrottle::BLOCK_RESPONSE, callback_result().action());
EXPECT_EQ(net::ERR_FILE_VIRUS_INFECTED, callback_result().net_error_code());
EXPECT_FALSE(callback_result().error_page_content().has_value());
- EXPECT_EQ(0, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(1, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 0, 0, 0, 1));
}
TEST_F(NavigationHandleImplTest, BlockResponseCustomNetErrorAndErrorHTML) {
@@ -1149,33 +1021,20 @@ TEST_F(NavigationHandleImplTest, BlockResponseCustomNetErrorAndErrorHTML) {
TestNavigationThrottle* block_throttle = CreateTestNavigationThrottle(
{NavigationThrottle::BLOCK_RESPONSE, net::ERR_FILE_VIRUS_INFECTED,
expected_error_page_content});
- EXPECT_EQ(0, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(0, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 0, 0, 0, 0));
// Simulate WillRedirectRequest. The request should not be deferred. The
// callback should have been called. The second throttle should not have
// been notified.
SimulateWillProcessResponse();
- EXPECT_FALSE(IsDeferringStart());
- EXPECT_FALSE(IsDeferringRedirect());
- EXPECT_FALSE(IsDeferringResponse());
+ EXPECT_EQ(NavigationHandleImpl::CANCELING, state());
EXPECT_TRUE(was_callback_called());
- EXPECT_TRUE(IsCanceling());
EXPECT_EQ(NavigationThrottle::BLOCK_RESPONSE, callback_result());
EXPECT_EQ(NavigationThrottle::BLOCK_RESPONSE, callback_result().action());
EXPECT_EQ(net::ERR_FILE_VIRUS_INFECTED, callback_result().net_error_code());
EXPECT_TRUE(callback_result().error_page_content().has_value());
EXPECT_EQ(expected_error_page_content,
callback_result().error_page_content().value());
- EXPECT_EQ(0, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_START_REQUEST));
- EXPECT_EQ(0, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_REDIRECT_REQUEST));
- EXPECT_EQ(1, block_throttle->GetCallCount(
- TestNavigationThrottle::WILL_PROCESS_RESPONSE));
+ EXPECT_TRUE(call_counts_match(block_throttle, 0, 0, 0, 1));
}
// Checks that a NavigationHandle can be safely deleted by teh execution of one
@@ -1232,6 +1091,29 @@ TEST_F(NavigationHandleImplTest, DeletionByNavigationThrottle) {
EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
}
+ // Test deletion in WillFailRequest.
+ CreateNavigationHandle();
+ SimulateWillStartRequest();
+ AddDeletingNavigationThrottle();
+ SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
+ EXPECT_EQ(nullptr, test_handle());
+ if (IsBrowserSideNavigationEnabled()) {
+ EXPECT_FALSE(was_callback_called());
+ }
+
+ // Test deletion in WillFailRequest after being deferred.
+ CreateNavigationHandle();
+ SimulateWillStartRequest();
+ CreateTestNavigationThrottle(NavigationThrottle::DEFER);
+ AddDeletingNavigationThrottle();
+ SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
+ EXPECT_NE(nullptr, test_handle());
+ Resume();
+ EXPECT_EQ(nullptr, test_handle());
+ if (IsBrowserSideNavigationEnabled()) {
+ EXPECT_FALSE(was_callback_called());
+ }
+
// Test deletion in WillProcessResponse.
CreateNavigationHandle();
SimulateWillStartRequest();
@@ -1260,4 +1142,24 @@ TEST_F(NavigationHandleImplTest, DeletionByNavigationThrottle) {
}
}
+// Checks that data from the SSLInfo passed into SimulateWillStartRequest() is
+// stored on the handle.
+TEST_F(NavigationHandleImplTest, WillFailRequestSetsSSLInfo) {
+ uint16_t cipher_suite = 0xc02f; // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ int connection_status = 0;
+ net::SSLConnectionStatusSetCipherSuite(cipher_suite, &connection_status);
+
+ // Set some test values.
+ net::SSLInfo ssl_info;
+ ssl_info.cert_status = net::CERT_STATUS_AUTHORITY_INVALID;
+ ssl_info.connection_status = connection_status;
+
+ SimulateWillStartRequest();
+ SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID, ssl_info);
+
+ EXPECT_EQ(net::CERT_STATUS_AUTHORITY_INVALID,
+ test_handle()->GetSSLInfo().cert_status);
+ EXPECT_EQ(connection_status, test_handle()->GetSSLInfo().connection_status);
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigation_request.cc b/chromium/content/browser/frame_host/navigation_request.cc
index a9d1909d17f..f8875a7473d 100644
--- a/chromium/content/browser/frame_host/navigation_request.cc
+++ b/chromium/content/browser/frame_host/navigation_request.cc
@@ -56,8 +56,8 @@
#include "net/base/url_util.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/redirect_info.h"
+#include "third_party/WebKit/common/sandbox_flags.h"
#include "third_party/WebKit/public/platform/WebMixedContentContextType.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
namespace content {
@@ -164,6 +164,11 @@ void AddAdditionalRequestHeaders(net::HttpRequestHeaders* headers,
if (embedder_additional_headers)
headers->MergeFrom(*(embedder_additional_headers.get()));
+ // Tack an 'Upgrade-Insecure-Requests' header to outgoing navigational
+ // requests, as described in
+ // https://w3c.github.io/webappsec/specs/upgrade/#feature-detect
+ headers->SetHeaderIfMissing("Upgrade-Insecure-Requests", "1");
+
headers->SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent,
user_agent_override.empty()
? GetContentClient()->GetUserAgent()
@@ -173,11 +178,6 @@ void AddAdditionalRequestHeaders(net::HttpRequestHeaders* headers,
// after setting the default user agent, or append throttling control header.
RenderFrameDevToolsAgentHost::AppendDevToolsHeaders(frame_tree_node, headers);
- // Tack an 'Upgrade-Insecure-Requests' header to outgoing navigational
- // requests, as described in
- // https://w3c.github.io/webappsec/specs/upgrade/#feature-detect
- headers->AddHeaderFromString("Upgrade-Insecure-Requests: 1");
-
// Next, set the HTTP Origin if needed.
if (!NeedsHTTPOrigin(headers, method))
return;
@@ -186,8 +186,8 @@ void AddAdditionalRequestHeaders(net::HttpRequestHeaders* headers,
url::Origin origin;
if (frame_tree_node->IsMainFrame()) {
// For main frame, the origin is the url currently loading.
- origin = url::Origin(url);
- } else if ((frame_tree_node->effective_sandbox_flags() &
+ origin = url::Origin::Create(url);
+ } else if ((frame_tree_node->active_sandbox_flags() &
blink::WebSandboxFlags::kOrigin) ==
blink::WebSandboxFlags::kNone) {
// The origin should be the origin of the root, except for sandboxed
@@ -269,7 +269,6 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest(
frame_tree_node, common_params,
BeginNavigationParams(entry.extra_headers(), net::LOAD_NORMAL,
- false, // has_user_gestures
false, // skip_service_worker
REQUEST_CONTEXT_TYPE_LOCATION,
blink::WebMixedContentContextType::kBlockable,
@@ -317,8 +316,7 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateRendererInitiated(
// history-navigations do not use this path. See comments above.
current_history_list_offset, current_history_list_length,
false, // is_view_source
- false, // should_clear_history_list
- begin_params.has_user_gesture);
+ false /*should_clear_history_list*/);
std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest(
frame_tree_node, common_params, begin_params, request_params,
false, // browser_initiated
@@ -348,6 +346,9 @@ NavigationRequest::NavigationRequest(
response_should_be_rendered_(true),
associated_site_instance_type_(AssociatedSiteInstanceType::NONE),
from_begin_navigation_(from_begin_navigation),
+ has_stale_copy_in_cache_(false),
+ net_error_(net::OK),
+ devtools_navigation_token_(base::UnguessableToken::Create()),
weak_factory_(this) {
DCHECK(!browser_initiated || (entry != nullptr && frame_entry != nullptr));
TRACE_EVENT_ASYNC_BEGIN2("navigation", "NavigationRequest", this,
@@ -413,6 +414,10 @@ NavigationRequest::NavigationRequest(
}
}
begin_params_.headers = headers.ToString();
+
+ // Check whether DevTools wants to skip the service worker.
+ if (RenderFrameDevToolsAgentHost::ShouldBypassServiceWorker(frame_tree_node))
+ begin_params_.skip_service_worker = true;
}
NavigationRequest::~NavigationRequest() {
@@ -433,7 +438,7 @@ void NavigationRequest::BeginNavigation() {
GetContentClient()->browser()->ShouldOverrideUrlLoading(
frame_tree_node_->frame_tree_node_id(), browser_initiated_,
request_params_.original_url, request_params_.original_method,
- request_params_.has_user_gesture, false,
+ common_params_.has_user_gesture, false,
frame_tree_node_->IsMainFrame(), common_params_.transition);
// The content/ embedder might cause |this| to be deleted while
@@ -460,7 +465,8 @@ void NavigationRequest::BeginNavigation() {
// Create a navigation handle so that the correct error code can be set on
// it by OnRequestFailed().
CreateNavigationHandle();
- OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT, base::nullopt, false);
+ OnRequestFailedInternal(false, net::ERR_BLOCKED_BY_CLIENT, base::nullopt,
+ false, false);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
@@ -474,7 +480,8 @@ void NavigationRequest::BeginNavigation() {
// Create a navigation handle so that the correct error code can be set on
// it by OnRequestFailed().
CreateNavigationHandle();
- OnRequestFailed(false, net::ERR_ABORTED, base::nullopt, false);
+ OnRequestFailedInternal(false, net::ERR_ABORTED, base::nullopt, false,
+ false);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
@@ -495,7 +502,7 @@ void NavigationRequest::BeginNavigation() {
common_params_.method, common_params_.post_data,
Referrer::SanitizeForRequest(common_params_.url,
common_params_.referrer),
- begin_params_.has_user_gesture, common_params_.transition,
+ common_params_.has_user_gesture, common_params_.transition,
is_external_protocol, begin_params_.request_context_type,
begin_params_.mixed_content_context_type,
base::Bind(&NavigationRequest::OnStartChecksComplete,
@@ -726,12 +733,12 @@ void NavigationRequest::OnResponseStarted(
const scoped_refptr<ResourceResponse>& response,
std::unique_ptr<StreamHandle> body,
mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const SSLStatus& ssl_status,
+ const net::SSLInfo& ssl_info,
std::unique_ptr<NavigationData> navigation_data,
const GlobalRequestID& request_id,
bool is_download,
bool is_stream,
- mojom::URLLoaderFactoryPtrInfo subresource_loader_factory_info) {
+ base::Optional<SubresourceLoaderParams> subresource_loader_params) {
DCHECK(state_ == STARTED);
DCHECK(response);
TRACE_EVENT_ASYNC_STEP_INTO0("navigation", "NavigationRequest", this,
@@ -803,10 +810,10 @@ void NavigationRequest::OnResponseStarted(
response_ = response;
body_ = std::move(body);
handle_ = std::move(consumer_handle);
- ssl_status_ = ssl_status;
+ ssl_info_ = ssl_info;
is_download_ = is_download;
- subresource_loader_factory_info_ = std::move(subresource_loader_factory_info);
+ subresource_loader_params_ = std::move(subresource_loader_params);
// Since we've made the final pick for the RenderFrameHost above, the picked
// RenderFrameHost's process should be considered "tainted" for future
@@ -840,19 +847,29 @@ void NavigationRequest::OnResponseStarted(
// Check if the navigation should be allowed to proceed.
navigation_handle_->WillProcessResponse(
render_frame_host, response->head.headers.get(),
- response->head.connection_info, ssl_status, request_id,
- common_params_.should_replace_current_entry, is_download, is_stream,
- base::Closure(),
+ response->head.connection_info, response->head.socket_address, ssl_info_,
+ request_id, common_params_.should_replace_current_entry, is_download,
+ is_stream, base::Closure(),
base::Bind(&NavigationRequest::OnWillProcessResponseChecksComplete,
base::Unretained(this)));
}
-// TODO(crbug.com/751941): Pass certificate_error_info to navigation throttles.
void NavigationRequest::OnRequestFailed(
bool has_stale_copy_in_cache,
int net_error,
const base::Optional<net::SSLInfo>& ssl_info,
bool should_ssl_errors_be_fatal) {
+ NavigationRequest::OnRequestFailedInternal(has_stale_copy_in_cache, net_error,
+ ssl_info,
+ should_ssl_errors_be_fatal, false);
+}
+
+void NavigationRequest::OnRequestFailedInternal(
+ bool has_stale_copy_in_cache,
+ int net_error,
+ const base::Optional<net::SSLInfo>& ssl_info,
+ bool should_ssl_errors_be_fatal,
+ bool skip_throttles) {
DCHECK(state_ == STARTED || state_ == RESPONSE_STARTED);
// TODO(https://crbug.com/757633): Check that ssl_info.has_value() if
// net_error is a certificate error.
@@ -902,6 +919,7 @@ void NavigationRequest::OnRequestFailed(
render_frame_host =
frame_tree_node_->render_manager()->GetFrameHostForNavigation(*this);
}
+ DCHECK(render_frame_host);
// Don't ask the renderer to commit an URL if the browser will kill it when
// it does.
@@ -910,12 +928,20 @@ void NavigationRequest::OnRequestFailed(
NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(render_frame_host,
common_params_.url);
- TransferNavigationHandleOwnership(render_frame_host);
- render_frame_host->navigation_handle()->ReadyToCommitNavigation(
- render_frame_host);
- render_frame_host->FailedNavigation(common_params_, begin_params_,
- request_params_, has_stale_copy_in_cache,
- net_error);
+ has_stale_copy_in_cache_ = has_stale_copy_in_cache;
+ net_error_ = net_error;
+
+ if (skip_throttles || IsRendererDebugURL(common_params_.url)) {
+ // The NavigationHandle shouldn't be notified about renderer-debug URLs.
+ // They will be handled by the renderer process.
+ CommitErrorPage(render_frame_host, base::nullopt);
+ } else {
+ // Check if the navigation should be allowed to proceed.
+ navigation_handle_->WillFailRequest(
+ ssl_info, should_ssl_errors_be_fatal,
+ base::Bind(&NavigationRequest::OnFailureChecksComplete,
+ base::Unretained(this), render_frame_host));
+ }
}
void NavigationRequest::OnRequestStarted(base::TimeTicks timestamp) {
@@ -954,9 +980,9 @@ void NavigationRequest::OnStartChecksComplete(
// PostTask to avoid that.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(&NavigationRequest::OnRequestFailed,
+ base::BindOnce(&NavigationRequest::OnRequestFailedInternal,
weak_factory_.GetWeakPtr(), false,
- result.net_error_code(), base::nullopt, false));
+ result.net_error_code(), base::nullopt, false, true));
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
@@ -984,7 +1010,7 @@ void NavigationRequest::OnStartChecksComplete(
// Only initialize the ServiceWorkerNavigationHandle if it can be created for
// this frame.
bool can_create_service_worker =
- (frame_tree_node_->pending_sandbox_flags() &
+ (frame_tree_node_->pending_frame_policy().sandbox_flags &
blink::WebSandboxFlags::kOrigin) != blink::WebSandboxFlags::kOrigin;
request_params_.should_create_service_worker = can_create_service_worker;
if (can_create_service_worker) {
@@ -1042,7 +1068,7 @@ void NavigationRequest::OnStartChecksComplete(
loader_ = NavigationURLLoader::Create(
browser_context->GetResourceContext(), partition,
- base::MakeUnique<NavigationRequestInfo>(
+ std::make_unique<NavigationRequestInfo>(
common_params_, begin_params_, site_for_cookies,
frame_tree_node_->IsMainFrame(), parent_is_main_frame,
IsSecureFrame(frame_tree_node_->parent()),
@@ -1063,7 +1089,8 @@ void NavigationRequest::OnRedirectChecksComplete(
result.action() == NavigationThrottle::CANCEL) {
// TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE if needed.
DCHECK_EQ(net::ERR_ABORTED, result.net_error_code());
- OnRequestFailed(false, result.net_error_code(), base::nullopt, false);
+ OnRequestFailedInternal(false, result.net_error_code(), base::nullopt,
+ false, true);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
@@ -1073,7 +1100,8 @@ void NavigationRequest::OnRedirectChecksComplete(
if (result.action() == NavigationThrottle::BLOCK_REQUEST ||
result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) {
DCHECK_EQ(net::ERR_BLOCKED_BY_CLIENT, result.net_error_code());
- OnRequestFailed(false, result.net_error_code(), base::nullopt, false);
+ OnRequestFailedInternal(false, result.net_error_code(), base::nullopt,
+ false, true);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
return;
@@ -1082,6 +1110,25 @@ void NavigationRequest::OnRedirectChecksComplete(
loader_->FollowRedirect();
}
+void NavigationRequest::OnFailureChecksComplete(
+ RenderFrameHostImpl* render_frame_host,
+ NavigationThrottle::ThrottleCheckResult result) {
+ DCHECK(result.action() != NavigationThrottle::DEFER);
+
+ net_error_ = result.net_error_code();
+ navigation_handle_->set_net_error_code(static_cast<net::Error>(net_error_));
+
+ // TODO(crbug.com/774663): We may want to take result.action() into account..
+ if (net::ERR_ABORTED == net_error_) {
+ frame_tree_node_->ResetNavigationRequest(false, true);
+ return;
+ }
+
+ CommitErrorPage(render_frame_host, result.error_page_content());
+ // DO NOT ADD CODE after this. The previous call to CommitErrorPage caused
+ // the destruction of the NavigationRequest.
+}
+
void NavigationRequest::OnWillProcessResponseChecksComplete(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK(result.action() != NavigationThrottle::DEFER);
@@ -1099,7 +1146,8 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
BrowserContext::GetDownloadManager(browser_context));
loader_->InterceptNavigation(
download_manager->GetNavigationInterceptionCB(
- response_, std::move(handle_), ssl_status_));
+ response_, std::move(handle_), ssl_info_.cert_status,
+ frame_tree_node_->frame_tree_node_id()));
OnRequestFailed(false, net::ERR_ABORTED, base::nullopt, false);
return;
}
@@ -1117,7 +1165,7 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
net_error = net::ERR_ABORTED;
// TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE.
DCHECK_EQ(net::ERR_ABORTED, net_error);
- OnRequestFailed(false, net_error, base::nullopt, false);
+ OnRequestFailedInternal(false, net_error, base::nullopt, false, true);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
@@ -1126,7 +1174,8 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
if (result.action() == NavigationThrottle::BLOCK_RESPONSE) {
DCHECK_EQ(net::ERR_BLOCKED_BY_RESPONSE, result.net_error_code());
- OnRequestFailed(false, result.net_error_code(), base::nullopt, false);
+ OnRequestFailedInternal(false, result.net_error_code(), base::nullopt,
+ false, true);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
return;
@@ -1138,6 +1187,17 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
// the destruction of the NavigationRequest.
}
+void NavigationRequest::CommitErrorPage(
+ RenderFrameHostImpl* render_frame_host,
+ const base::Optional<std::string>& error_page_content) {
+ TransferNavigationHandleOwnership(render_frame_host);
+ render_frame_host->navigation_handle()->ReadyToCommitNavigation(
+ render_frame_host);
+ render_frame_host->FailedNavigation(common_params_, begin_params_,
+ request_params_, has_stale_copy_in_cache_,
+ net_error_, error_page_content);
+}
+
void NavigationRequest::CommitNavigation() {
DCHECK(response_ || !IsURLHandledByNetworkStack(common_params_.url) ||
navigation_handle_->IsSameDocument());
@@ -1153,12 +1213,10 @@ void NavigationRequest::CommitNavigation() {
TransferNavigationHandleOwnership(render_frame_host);
- DCHECK_EQ(request_params_.has_user_gesture, begin_params_.has_user_gesture);
-
render_frame_host->CommitNavigation(
response_.get(), std::move(body_), std::move(handle_), common_params_,
- request_params_, is_view_source_,
- std::move(subresource_loader_factory_info_));
+ request_params_, is_view_source_, std::move(subresource_loader_params_),
+ devtools_navigation_token_);
frame_tree_node_->ResetNavigationRequest(true, true);
}
@@ -1240,8 +1298,8 @@ NavigationRequest::CheckCredentialedSubresource() const {
FrameTreeNode* parent_ftn = frame_tree_node_->parent();
DCHECK(parent_ftn);
const GURL& parent_url = parent_ftn->current_url();
- if (url::Origin(parent_url)
- .IsSameOriginWith(url::Origin(common_params_.url)) &&
+ if (url::Origin::Create(parent_url)
+ .IsSameOriginWith(url::Origin::Create(common_params_.url)) &&
parent_url.username() == common_params_.url.username() &&
parent_url.password() == common_params_.url.password()) {
return CredentialedSubresourceCheckResult::ALLOW_REQUEST;
diff --git a/chromium/content/browser/frame_host/navigation_request.h b/chromium/content/browser/frame_host/navigation_request.h
index 450142ccd4b..2cddf276540 100644
--- a/chromium/content/browser/frame_host/navigation_request.h
+++ b/chromium/content/browser/frame_host/navigation_request.h
@@ -11,11 +11,13 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/loader/navigation_url_loader_delegate.h"
#include "content/common/content_export.h"
#include "content/common/frame_message_enums.h"
#include "content/common/navigation_params.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/common/previews_state.h"
#include "mojo/public/cpp/system/data_pipe.h"
@@ -31,6 +33,7 @@ class NavigationData;
class ResourceRequestBody;
class SiteInstanceImpl;
class StreamHandle;
+struct SubresourceLoaderParams;
// PlzNavigate
// A UI thread object that owns a navigation request until it commits. It
@@ -155,6 +158,8 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
return navigation_handle_.get();
}
+ int net_error() { return net_error_; }
+
void SetWaitingForRendererResponse();
// Creates a NavigationHandle. This should be called after any previous
@@ -176,6 +181,20 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
int nav_entry_id() const { return nav_entry_id_; }
+ // For automation driver-initiated navigations over the devtools protocol,
+ // |devtools_navigation_token_| is used to tag the navigation. This navigation
+ // token is then sent into the renderer and lands on the DocumentLoader. That
+ // way subsequent Blink-level frame lifecycle events can be associated with
+ // the concrete navigation.
+ // - The value should not be sent back to the browser.
+ // - The value on DocumentLoader may be generated in the renderer in some
+ // cases, and thus shouldn't be trusted.
+ // TODO(crbug.com/783506): Replace devtools navigation token with the generic
+ // navigation token that can be passed from renderer to the browser.
+ const base::UnguessableToken& devtools_navigation_token() const {
+ return devtools_navigation_token_;
+ }
+
private:
// This enum describes the result of a Content Security Policy (CSP) check for
// the request.
@@ -203,26 +222,42 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
void OnResponseStarted(const scoped_refptr<ResourceResponse>& response,
std::unique_ptr<StreamHandle> body,
mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const SSLStatus& ssl_status,
+ const net::SSLInfo& ssl_info,
std::unique_ptr<NavigationData> navigation_data,
const GlobalRequestID& request_id,
bool is_download,
bool is_stream,
- mojom::URLLoaderFactoryPtrInfo
- subresource_url_loader_factory_info) override;
+ base::Optional<SubresourceLoaderParams>
+ subresource_loader_params) override;
void OnRequestFailed(bool has_stale_copy_in_cache,
int net_error,
const base::Optional<net::SSLInfo>& ssl_info,
bool should_ssl_errors_be_fatal) override;
void OnRequestStarted(base::TimeTicks timestamp) override;
+ // A version of OnRequestFailed() that allows skipping throttles, to be used
+ // when a request failed due to a throttle result itself.
+ void OnRequestFailedInternal(bool has_stale_copy_in_cache,
+ int net_error,
+ const base::Optional<net::SSLInfo>& ssl_info,
+ bool should_ssl_errors_be_fatal,
+ bool skip_throttles);
+
// Called when the NavigationThrottles have been checked by the
// NavigationHandle.
void OnStartChecksComplete(NavigationThrottle::ThrottleCheckResult result);
void OnRedirectChecksComplete(NavigationThrottle::ThrottleCheckResult result);
+ void OnFailureChecksComplete(RenderFrameHostImpl* render_frame_host,
+ NavigationThrottle::ThrottleCheckResult result);
void OnWillProcessResponseChecksComplete(
NavigationThrottle::ThrottleCheckResult result);
+ // Called either by OnFailureChecksComplete() or OnRequestFailed() directly.
+ // |error_page_content| contains the content of the error page (i.e. flattened
+ // HTML, JS, CSS).
+ void CommitErrorPage(RenderFrameHostImpl* render_frame_host,
+ const base::Optional<std::string>& error_page_content);
+
// Have a RenderFrameHost commit the navigation. The NavigationRequest will
// be destroyed after this call.
void CommitNavigation();
@@ -317,14 +352,22 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
scoped_refptr<ResourceResponse> response_;
std::unique_ptr<StreamHandle> body_;
mojo::ScopedDataPipeConsumerHandle handle_;
- SSLStatus ssl_status_;
+ net::SSLInfo ssl_info_;
bool is_download_;
+ // Holds information for the navigation while the WillFailRequest
+ // checks are performed by the NavigationHandle.
+ bool has_stale_copy_in_cache_;
+ int net_error_;
+
base::Closure on_start_checks_complete_closure_;
- // Used in the network service world to pass the subressource loader factory
- // to the renderer. Currently only used by AppCache.
- mojom::URLLoaderFactoryPtrInfo subresource_loader_factory_info_;
+ // Used in the network service world to pass the subressource loader params
+ // to the renderer. Used by AppCache and ServiceWorker.
+ base::Optional<SubresourceLoaderParams> subresource_loader_params_;
+
+ // See comment on accessor.
+ base::UnguessableToken devtools_navigation_token_;
base::WeakPtrFactory<NavigationRequest> weak_factory_;
diff --git a/chromium/content/browser/frame_host/navigation_request_info.cc b/chromium/content/browser/frame_host/navigation_request_info.cc
index 3501c374cb8..523ba351bd5 100644
--- a/chromium/content/browser/frame_host/navigation_request_info.cc
+++ b/chromium/content/browser/frame_host/navigation_request_info.cc
@@ -4,6 +4,7 @@
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
namespace content {
@@ -17,7 +18,7 @@ NavigationRequestInfo::NavigationRequestInfo(
int frame_tree_node_id,
bool is_for_guests_only,
bool report_raw_headers,
- blink::WebPageVisibilityState page_visibility_state)
+ blink::mojom::PageVisibilityState page_visibility_state)
: common_params(common_params),
begin_params(begin_params),
site_for_cookies(site_for_cookies),
diff --git a/chromium/content/browser/frame_host/navigation_request_info.h b/chromium/content/browser/frame_host/navigation_request_info.h
index 48c0ff43b5e..c83503ea11e 100644
--- a/chromium/content/browser/frame_host/navigation_request_info.h
+++ b/chromium/content/browser/frame_host/navigation_request_info.h
@@ -11,7 +11,7 @@
#include "content/common/content_export.h"
#include "content/common/navigation_params.h"
#include "content/public/common/referrer.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -21,16 +21,17 @@ namespace content {
// ResourceDispatcherHost. It is initialized on the UI thread, and then passed
// to the IO thread by a NavigationRequest object.
struct CONTENT_EXPORT NavigationRequestInfo {
- NavigationRequestInfo(const CommonNavigationParams& common_params,
- const BeginNavigationParams& begin_params,
- const GURL& site_for_cookies,
- bool is_main_frame,
- bool parent_is_main_frame,
- bool are_ancestors_secure,
- int frame_tree_node_id,
- bool is_for_guests_only,
- bool report_raw_headers,
- blink::WebPageVisibilityState page_visibility_state);
+ NavigationRequestInfo(
+ const CommonNavigationParams& common_params,
+ const BeginNavigationParams& begin_params,
+ const GURL& site_for_cookies,
+ bool is_main_frame,
+ bool parent_is_main_frame,
+ bool are_ancestors_secure,
+ int frame_tree_node_id,
+ bool is_for_guests_only,
+ bool report_raw_headers,
+ blink::mojom::PageVisibilityState page_visibility_state);
~NavigationRequestInfo();
const CommonNavigationParams common_params;
@@ -53,7 +54,7 @@ struct CONTENT_EXPORT NavigationRequestInfo {
const bool report_raw_headers;
- blink::WebPageVisibilityState page_visibility_state;
+ blink::mojom::PageVisibilityState page_visibility_state;
};
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigator.cc b/chromium/content/browser/frame_host/navigator.cc
index c1fc47b7309..f6cd6d0cdcd 100644
--- a/chromium/content/browser/frame_host/navigator.cc
+++ b/chromium/content/browser/frame_host/navigator.cc
@@ -14,7 +14,7 @@ NavigatorDelegate* Navigator::GetDelegate() {
}
NavigationController* Navigator::GetController() {
- return NULL;
+ return nullptr;
}
bool Navigator::NavigateToPendingEntry(FrameTreeNode* frame_tree_node,
diff --git a/chromium/content/browser/frame_host/navigator.h b/chromium/content/browser/frame_host/navigator.h
index b0c45197ab3..544b97b47b1 100644
--- a/chromium/content/browser/frame_host/navigator.h
+++ b/chromium/content/browser/frame_host/navigator.h
@@ -54,12 +54,12 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
RenderFrameHostImpl* render_frame_host,
const GURL& url,
const std::vector<GURL>& redirect_chain,
- const base::TimeTicks& navigation_start) {};
+ const base::TimeTicks& navigation_start) {}
// The RenderFrameHostImpl has failed a provisional load.
virtual void DidFailProvisionalLoadWithError(
RenderFrameHostImpl* render_frame_host,
- const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) {};
+ const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) {}
// The RenderFrameHostImpl has failed to load the document.
virtual void DidFailLoadWithError(RenderFrameHostImpl* render_frame_host,
@@ -120,7 +120,6 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
const std::string& extra_headers,
const Referrer& referrer,
WindowOpenDisposition disposition,
- bool force_new_process_for_new_contents,
bool should_replace_current_entry,
bool user_gesture,
blink::WebTriggeringEventInfo triggering_event_info) {}
@@ -176,8 +175,8 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
// TODO(carlosk): once PlzNavigate is the only navigation implementation
// remove the URL parameter and rename this method to better suit its naming
// conventions.
- virtual void LogResourceRequestTime(
- base::TimeTicks timestamp, const GURL& url) {};
+ virtual void LogResourceRequestTime(base::TimeTicks timestamp,
+ const GURL& url) {}
// Called to record the time it took to execute the before unload hook for the
// current navigation.
diff --git a/chromium/content/browser/frame_host/navigator_impl.cc b/chromium/content/browser/frame_host/navigator_impl.cc
index ef506cebcde..f6dcc5ff535 100644
--- a/chromium/content/browser/frame_host/navigator_impl.cc
+++ b/chromium/content/browser/frame_host/navigator_impl.cc
@@ -45,6 +45,7 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/resource_response.h"
#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/public/common/url_utils.h"
#include "net/base/net_errors.h"
#include "url/gurl.h"
#include "url/url_util.h"
@@ -594,8 +595,7 @@ void NavigatorImpl::DidNavigate(
// <meta> elements - we need to reset CSP and Feature Policy.
if (!is_same_document_navigation) {
render_frame_host->ResetContentSecurityPolicies();
- frame_tree_node->ResetCspHeaders();
- frame_tree_node->ResetFeaturePolicyHeader();
+ frame_tree_node->ResetForNavigation();
}
frame_tree_node->render_manager()->DidNavigateFrame(
@@ -644,27 +644,7 @@ void NavigatorImpl::DidNavigate(
site_instance);
}
- // Keep track of the last committed URL and origin in the RenderFrameHost
- // itself. These allow GetLastCommittedURL and GetLastCommittedOrigin to
- // stay correct even if the render_frame_host later becomes pending deletion.
- // The URL is set regardless of whether it's for a net error or not.
- frame_tree_node->SetCurrentURL(params.url);
- render_frame_host->SetLastCommittedOrigin(params.origin);
-
- // Separately, update the frame's last successful URL except for net error
- // pages, since those do not end up in the correct process after transfers
- // (see https://crbug.com/560511). Instead, the next cross-process navigation
- // or transfer should decide whether to swap as if the net error had not
- // occurred.
- // TODO(creis): Remove this block and always set the URL once transfers handle
- // network errors or PlzNavigate is enabled. See https://crbug.com/588314.
- if (!params.url_is_unreachable)
- render_frame_host->set_last_successful_url(params.url);
-
- // After setting the last committed origin, reset the feature policy in the
- // RenderFrameHost to a blank policy based on the parent frame.
- if (!is_same_document_navigation)
- render_frame_host->ResetFeaturePolicy();
+ render_frame_host->DidNavigate(params, is_same_document_navigation);
// Send notification about committed provisional loads. This notification is
// different from the NAV_ENTRY_COMMITTED notification which doesn't include
@@ -710,7 +690,6 @@ void NavigatorImpl::RequestOpenURL(
const std::string& extra_headers,
const Referrer& referrer,
WindowOpenDisposition disposition,
- bool force_new_process_for_new_contents,
bool should_replace_current_entry,
bool user_gesture,
blink::WebTriggeringEventInfo triggering_event_info) {
@@ -754,8 +733,6 @@ void NavigatorImpl::RequestOpenURL(
OpenURLParams params(dest_url, referrer, frame_tree_node_id, disposition,
ui::PAGE_TRANSITION_LINK,
true /* is_renderer_initiated */);
- params.force_new_process_for_new_contents =
- force_new_process_for_new_contents;
params.uses_post = uses_post;
params.post_data = body;
params.extra_headers = extra_headers;
@@ -891,6 +868,7 @@ void NavigatorImpl::RequestTransferURL(
extra_headers, controller_->GetBrowserContext()));
entry->root_node()->frame_entry->set_source_site_instance(
static_cast<SiteInstanceImpl*>(source_site_instance));
+ entry->root_node()->frame_entry->set_method(method);
entry->SetRedirectChain(redirect_chain);
}
@@ -915,7 +893,7 @@ void NavigatorImpl::RequestTransferURL(
frame_entry = new FrameNavigationEntry(
node->unique_name(), -1, -1, nullptr,
static_cast<SiteInstanceImpl*>(source_site_instance), dest_url,
- referrer_to_use, method, -1);
+ referrer_to_use, redirect_chain, PageState(), method, -1);
}
NavigateToEntry(node, *frame_entry, *entry.get(), ReloadType::NONE, false,
false, false, post_body);
@@ -999,7 +977,7 @@ void NavigatorImpl::OnBeginNavigation(
// is not user-initiated.
if (ongoing_navigation_request &&
ongoing_navigation_request->browser_initiated() &&
- !begin_params.has_user_gesture) {
+ !common_params.has_user_gesture) {
RenderFrameHost* current_frame_host =
frame_tree_node->render_manager()->current_frame_host();
current_frame_host->Send(
@@ -1188,7 +1166,7 @@ void NavigatorImpl::RequestNavigation(
nullptr, // body
mojo::ScopedDataPipeConsumerHandle(), scoped_request->common_params(),
scoped_request->request_params(), scoped_request->is_view_source(),
- mojom::URLLoaderFactoryPtrInfo());
+ base::nullopt, scoped_request->devtools_navigation_token());
return;
}
diff --git a/chromium/content/browser/frame_host/navigator_impl.h b/chromium/content/browser/frame_host/navigator_impl.h
index f81edf42456..2aecc39d61c 100644
--- a/chromium/content/browser/frame_host/navigator_impl.h
+++ b/chromium/content/browser/frame_host/navigator_impl.h
@@ -71,7 +71,6 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
const std::string& extra_headers,
const Referrer& referrer,
WindowOpenDisposition disposition,
- bool force_new_process_for_new_contents,
bool should_replace_current_entry,
bool user_gesture,
blink::WebTriggeringEventInfo triggering_event_info) override;
diff --git a/chromium/content/browser/frame_host/navigator_impl_unittest.cc b/chromium/content/browser/frame_host/navigator_impl_unittest.cc
index 4c45871e86b..93e4baa7b74 100644
--- a/chromium/content/browser/frame_host/navigator_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigator_impl_unittest.cc
@@ -17,6 +17,7 @@
#include "content/browser/frame_host/render_frame_host_manager.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/streams/stream.h"
+#include "content/common/frame.mojom.h"
#include "content/common/frame_messages.h"
#include "content/common/navigation_params.h"
#include "content/common/site_isolation_policy.h"
@@ -93,18 +94,6 @@ class NavigatorTestWithBrowserSideNavigation
node->render_manager()->speculative_render_frame_host_.get());
}
- // Checks if this RenderFrameHost sent a single FrameMsg_CommitNavigation
- // since the last clearing of the sink.
- // Note: caller must invoke ClearMessages on the sink at some point before
- // the tracked commit happens to clear up commit messages from previous
- // navigations.
- bool DidRenderFrameHostRequestCommit(TestRenderFrameHost* rfh) {
- const IPC::Message* message =
- rfh->GetProcess()->sink().GetUniqueMessageMatching(
- FrameMsg_CommitNavigation::ID);
- return message && rfh->GetRoutingID() == message->routing_id();
- }
-
scoped_refptr<SiteInstance> ConvertToSiteInstance(
RenderFrameHostManager* rfhm,
const SiteInstanceDescriptor& descriptor,
@@ -141,7 +130,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
scoped_refptr<ResourceResponse> response(new ResourceResponse);
GetLoaderForNavigationRequest(request)->CallOnResponseStarted(
response, MakeEmptyStream(), nullptr);
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(main_test_rfh()));
+ EXPECT_TRUE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
EXPECT_TRUE(main_test_rfh()->is_loading());
EXPECT_FALSE(node->navigation_request());
@@ -178,7 +167,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
FrameHostMsg_DidStopLoading(main_test_rfh()->GetRoutingID()));
// Start a renderer-initiated non-user-initiated navigation.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
auto navigation =
NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
navigation->SetTransition(ui::PageTransitionFromInt(
@@ -192,7 +181,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// The navigation is immediately started as there's no need to wait for
// beforeUnload to be executed.
EXPECT_EQ(NavigationRequest::STARTED, request->state());
- EXPECT_FALSE(request->begin_params().has_user_gesture);
+ EXPECT_FALSE(request->common_params().has_user_gesture);
EXPECT_EQ(kUrl2, request->common_params().url);
EXPECT_FALSE(request->browser_initiated());
EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
@@ -200,7 +189,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Have the current RenderFrameHost commit the navigation
navigation->ReadyToCommit();
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(main_test_rfh()));
+ EXPECT_TRUE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
EXPECT_TRUE(main_test_rfh()->is_loading());
EXPECT_FALSE(node->navigation_request());
@@ -229,7 +218,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
int32_t site_instance_id_1 = main_test_rfh()->GetSiteInstance()->GetId();
// Start a renderer-initiated navigation.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
auto navigation =
NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
navigation->Start();
@@ -254,13 +243,11 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
if (AreAllSitesIsolatedForTesting()) {
EXPECT_EQ(navigation->GetFinalRenderFrameHost(),
GetSpeculativeRenderFrameHost(node));
- EXPECT_TRUE(
- DidRenderFrameHostRequestCommit(GetSpeculativeRenderFrameHost(node)));
} else {
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(main_test_rfh()));
- EXPECT_EQ(navigation->GetFinalRenderFrameHost(), main_test_rfh());
+ EXPECT_TRUE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
}
EXPECT_FALSE(node->navigation_request());
+ EXPECT_TRUE(process()->did_frame_commit_navigation());
// Commit the navigation.
navigation->Commit();
@@ -399,7 +386,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, NoContent) {
FrameTreeNode* node = main_test_rfh()->frame_tree_node();
// Navigate to a different site.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
RequestNavigation(node, kUrl2);
main_test_rfh()->SendBeforeUnloadACK(true);
@@ -419,7 +406,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, NoContent) {
// There should be no pending nor speculative RenderFrameHost; the navigation
// was aborted.
- EXPECT_FALSE(DidRenderFrameHostRequestCommit(main_test_rfh()));
+ EXPECT_FALSE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
EXPECT_FALSE(node->navigation_request());
EXPECT_FALSE(node->render_manager()->pending_frame_host());
EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
@@ -427,7 +414,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, NoContent) {
// Now, repeat the test with 205 Reset Content.
// Navigate to a different site again.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
RequestNavigation(node, kUrl2);
main_test_rfh()->SendBeforeUnloadACK(true);
@@ -445,7 +432,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, NoContent) {
// There should be no pending nor speculative RenderFrameHost; the navigation
// was aborted.
- EXPECT_FALSE(DidRenderFrameHostRequestCommit(main_test_rfh()));
+ EXPECT_FALSE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
EXPECT_FALSE(node->navigation_request());
EXPECT_FALSE(node->render_manager()->pending_frame_host());
EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
@@ -462,7 +449,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, CrossSiteNavigation) {
FrameTreeNode* node = main_test_rfh()->frame_tree_node();
// Navigate to a different site.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
int entry_id = RequestNavigation(node, kUrl2);
NavigationRequest* main_request = node->navigation_request();
ASSERT_TRUE(main_request);
@@ -477,8 +464,8 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, CrossSiteNavigation) {
GetLoaderForNavigationRequest(main_request)
->CallOnResponseStarted(response, MakeEmptyStream(), nullptr);
EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(speculative_rfh));
- EXPECT_FALSE(DidRenderFrameHostRequestCommit(main_test_rfh()));
+ EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
+ EXPECT_FALSE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
speculative_rfh->SendNavigate(entry_id, true, kUrl2);
@@ -501,7 +488,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, RedirectCrossSite) {
FrameTreeNode* node = main_test_rfh()->frame_tree_node();
// Navigate to a URL on the same site.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
int entry_id = RequestNavigation(node, kUrl1);
main_test_rfh()->SendBeforeUnloadACK(true);
NavigationRequest* main_request = node->navigation_request();
@@ -522,7 +509,8 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, RedirectCrossSite) {
TestRenderFrameHost* final_speculative_rfh =
GetSpeculativeRenderFrameHost(node);
EXPECT_TRUE(final_speculative_rfh);
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(final_speculative_rfh));
+ EXPECT_TRUE(
+ final_speculative_rfh->GetProcess()->did_frame_commit_navigation());
// Commit the navigation.
final_speculative_rfh->SendNavigate(entry_id, true, kUrl2);
@@ -551,7 +539,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
FrameTreeNode* node = main_test_rfh()->frame_tree_node();
// Request navigation to the 1st URL.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
RequestNavigation(node, kUrl1);
main_test_rfh()->SendBeforeUnloadACK(true);
NavigationRequest* request1 = node->navigation_request();
@@ -590,8 +578,8 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
scoped_refptr<ResourceResponse> response(new ResourceResponse);
GetLoaderForNavigationRequest(request2)->CallOnResponseStarted(
response, MakeEmptyStream(), nullptr);
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(speculative_rfh));
- EXPECT_FALSE(DidRenderFrameHostRequestCommit(main_test_rfh()));
+ EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
+ EXPECT_FALSE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
// Commit the navigation.
speculative_rfh->SendNavigate(entry_id, true, kUrl2);
@@ -619,7 +607,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Start a browser-initiated navigation to the 1st URL and receive its
// beforeUnload ACK.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
RequestNavigation(node, kUrl1);
main_test_rfh()->SendBeforeUnloadACK(true);
NavigationRequest* request1 = node->navigation_request();
@@ -644,7 +632,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
ASSERT_TRUE(request2);
EXPECT_EQ(kUrl2, request2->common_params().url);
EXPECT_FALSE(request2->browser_initiated());
- EXPECT_TRUE(request2->begin_params().has_user_gesture);
+ EXPECT_TRUE(request2->common_params().has_user_gesture);
// Confirm that the first loader got destroyed.
EXPECT_FALSE(loader1);
@@ -660,10 +648,11 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Have the RenderFrameHost commit the navigation.
navigation->ReadyToCommit();
if (AreAllSitesIsolatedForTesting()) {
- EXPECT_TRUE(
- DidRenderFrameHostRequestCommit(GetSpeculativeRenderFrameHost(node)));
+ EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)
+ ->GetProcess()
+ ->did_frame_commit_navigation());
} else {
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(main_test_rfh()));
+ EXPECT_TRUE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
}
// Commit the navigation.
@@ -688,7 +677,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
FrameTreeNode* node = main_test_rfh()->frame_tree_node();
// Start a renderer-initiated user-initiated navigation to the 1st URL.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
auto user_initiated_navigation =
NavigationSimulator::CreateRendererInitiated(kUrl1, main_test_rfh());
user_initiated_navigation->SetTransition(ui::PAGE_TRANSITION_LINK);
@@ -698,7 +687,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
ASSERT_TRUE(request1);
EXPECT_EQ(kUrl1, request1->common_params().url);
EXPECT_FALSE(request1->browser_initiated());
- EXPECT_TRUE(request1->begin_params().has_user_gesture);
+ EXPECT_TRUE(request1->common_params().has_user_gesture);
if (AreAllSitesIsolatedForTesting()) {
EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
} else {
@@ -718,7 +707,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
EXPECT_NE(request1, request2);
EXPECT_EQ(kUrl2, request2->common_params().url);
EXPECT_FALSE(request2->browser_initiated());
- EXPECT_FALSE(request2->begin_params().has_user_gesture);
+ EXPECT_FALSE(request2->common_params().has_user_gesture);
if (AreAllSitesIsolatedForTesting()) {
EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
} else {
@@ -728,10 +717,11 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Have the RenderFrameHost commit the navigation.
non_user_initiated_navigation->ReadyToCommit();
if (AreAllSitesIsolatedForTesting()) {
- EXPECT_TRUE(
- DidRenderFrameHostRequestCommit(GetSpeculativeRenderFrameHost(node)));
+ EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)
+ ->GetProcess()
+ ->did_frame_commit_navigation());
} else {
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(main_test_rfh()));
+ EXPECT_TRUE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
}
// Commit the navigation.
@@ -752,7 +742,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
FrameTreeNode* node = main_test_rfh()->frame_tree_node();
// Start a browser-initiated navigation to the 1st URL.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
int entry_id = RequestNavigation(node, kUrl1);
NavigationRequest* request1 = node->navigation_request();
ASSERT_TRUE(request1);
@@ -771,12 +761,11 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
BeginNavigationParams begin_params(
std::string(), // headers
net::LOAD_NORMAL, // load_flags
- false, // has_user_gesture
false, // skip_service_worker
REQUEST_CONTEXT_TYPE_SCRIPT,
blink::WebMixedContentContextType::kBlockable,
false, // is_form_submission
- url::Origin(kUrl0));
+ url::Origin::Create(kUrl0));
main_test_rfh()->OnMessageReceived(FrameHostMsg_BeginNavigation(
main_test_rfh()->GetRoutingID(), common_params, begin_params));
}
@@ -796,8 +785,8 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
scoped_refptr<ResourceResponse> response(new ResourceResponse);
GetLoaderForNavigationRequest(request2)->CallOnResponseStarted(
response, MakeEmptyStream(), nullptr);
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(speculative_rfh));
- EXPECT_FALSE(DidRenderFrameHostRequestCommit(main_test_rfh()));
+ EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
+ EXPECT_FALSE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
// Commit the navigation.
speculative_rfh->SendNavigate(entry_id, true, kUrl1);
@@ -818,7 +807,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
int32_t site_instance_id_0 = main_test_rfh()->GetSiteInstance()->GetId();
// Start a renderer-initiated non-user-initiated navigation to the 1st URL.
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
auto navigation1 =
NavigationSimulator::CreateRendererInitiated(kUrl1, main_test_rfh());
navigation1->SetTransition(ui::PageTransitionFromInt(
@@ -829,7 +818,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
ASSERT_TRUE(request1);
EXPECT_EQ(kUrl1, request1->common_params().url);
EXPECT_FALSE(request1->browser_initiated());
- EXPECT_FALSE(request1->begin_params().has_user_gesture);
+ EXPECT_FALSE(request1->common_params().has_user_gesture);
if (AreAllSitesIsolatedForTesting()) {
EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
} else {
@@ -849,7 +838,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
NavigationRequest* request2 = node->navigation_request();
EXPECT_EQ(kUrl2, request2->common_params().url);
EXPECT_FALSE(request2->browser_initiated());
- EXPECT_FALSE(request2->begin_params().has_user_gesture);
+ EXPECT_FALSE(request2->common_params().has_user_gesture);
if (AreAllSitesIsolatedForTesting()) {
EXPECT_TRUE(GetSpeculativeRenderFrameHost(node));
} else {
@@ -862,10 +851,11 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Have the RenderFrameHost commit the navigation.
navigation2->ReadyToCommit();
if (AreAllSitesIsolatedForTesting()) {
- EXPECT_TRUE(
- DidRenderFrameHostRequestCommit(GetSpeculativeRenderFrameHost(node)));
+ EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)
+ ->GetProcess()
+ ->did_frame_commit_navigation());
} else {
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(main_test_rfh()));
+ EXPECT_TRUE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
}
// Commit the navigation.
@@ -892,7 +882,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, Reload) {
int entry_id = controller().GetPendingEntry()->GetUniqueID();
// A NavigationRequest should have been generated.
NavigationRequest* main_request = node->navigation_request();
- ASSERT_TRUE(main_request != NULL);
+ ASSERT_TRUE(main_request != nullptr);
EXPECT_EQ(FrameMsg_Navigate_Type::RELOAD,
main_request->common_params().navigation_type);
main_test_rfh()->PrepareForCommit();
@@ -905,7 +895,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, Reload) {
controller().Reload(ReloadType::BYPASSING_CACHE, false);
// A NavigationRequest should have been generated.
main_request = node->navigation_request();
- ASSERT_TRUE(main_request != NULL);
+ ASSERT_TRUE(main_request != nullptr);
EXPECT_EQ(FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE,
main_request->common_params().navigation_type);
main_test_rfh()->PrepareForCommit();
@@ -923,7 +913,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Begin navigating to another site.
const GURL kUrl("http://google.com/");
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
int entry_id = RequestNavigation(node, kUrl);
TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
ASSERT_TRUE(speculative_rfh);
@@ -943,7 +933,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
GetLoaderForNavigationRequest(node->navigation_request())
->CallOnResponseStarted(response, MakeEmptyStream(), nullptr);
EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(speculative_rfh));
+ EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
EXPECT_EQ(site_instance_id, speculative_rfh->GetSiteInstance()->GetId());
EXPECT_FALSE(node->render_manager()->pending_frame_host());
@@ -966,7 +956,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Begin navigating to another site.
const GURL kUrl("http://google.com/");
- process()->sink().ClearMessages();
+ process()->set_did_frame_commit_navigation(false);
int entry_id = RequestNavigation(node, kUrl);
TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
ASSERT_TRUE(speculative_rfh);
@@ -1005,7 +995,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
->CallOnResponseStarted(response, MakeEmptyStream(), nullptr);
speculative_rfh = GetSpeculativeRenderFrameHost(node);
ASSERT_TRUE(speculative_rfh);
- EXPECT_TRUE(DidRenderFrameHostRequestCommit(speculative_rfh));
+ EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
EXPECT_EQ(init_site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
EXPECT_TRUE(rfh_deleted_observer.deleted());
@@ -1200,7 +1190,7 @@ void SetWithinSameDocument(
FrameHostMsg_DidCommitProvisionalLoad_Params* params) {
params->was_within_same_document = true;
params->url = url;
- params->origin = url::Origin(url);
+ params->origin = url::Origin::Create(url);
}
}
@@ -1306,14 +1296,16 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
contents()->NavigateAndCommit(kUrl1);
// Check the feature policy before navigation.
- FeaturePolicy* original_feature_policy = main_test_rfh()->feature_policy();
+ blink::FeaturePolicy* original_feature_policy =
+ main_test_rfh()->feature_policy();
ASSERT_TRUE(original_feature_policy);
// Navigate to the new URL.
contents()->NavigateAndCommit(kUrl2);
// Check the feature policy after navigation.
- FeaturePolicy* final_feature_policy = main_test_rfh()->feature_policy();
+ blink::FeaturePolicy* final_feature_policy =
+ main_test_rfh()->feature_policy();
ASSERT_TRUE(final_feature_policy);
ASSERT_NE(original_feature_policy, final_feature_policy);
}
@@ -1328,14 +1320,16 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
contents()->NavigateAndCommit(kUrl1);
// Check the feature policy before navigation.
- FeaturePolicy* original_feature_policy = main_test_rfh()->feature_policy();
+ blink::FeaturePolicy* original_feature_policy =
+ main_test_rfh()->feature_policy();
ASSERT_TRUE(original_feature_policy);
// Navigate to the new URL.
contents()->NavigateAndCommit(kUrl2);
// Check the feature policy after navigation.
- FeaturePolicy* final_feature_policy = main_test_rfh()->feature_policy();
+ blink::FeaturePolicy* final_feature_policy =
+ main_test_rfh()->feature_policy();
ASSERT_EQ(original_feature_policy, final_feature_policy);
}
@@ -1355,9 +1349,10 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, FeaturePolicyNewChild) {
ui::PAGE_TRANSITION_AUTO_SUBFRAME);
subframe_rfh->SendNavigateWithParams(&params);
- FeaturePolicy* subframe_feature_policy = subframe_rfh->feature_policy();
+ blink::FeaturePolicy* subframe_feature_policy =
+ subframe_rfh->feature_policy();
ASSERT_TRUE(subframe_feature_policy);
- ASSERT_FALSE(subframe_feature_policy->origin_.unique());
+ ASSERT_FALSE(subframe_feature_policy->GetOriginForTest().unique());
}
} // namespace content
diff --git a/chromium/content/browser/frame_host/render_frame_host_android.cc b/chromium/content/browser/frame_host/render_frame_host_android.cc
index 7a463265a94..a042afe6ac3 100644
--- a/chromium/content/browser/frame_host/render_frame_host_android.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_android.cc
@@ -4,8 +4,10 @@
#include "content/browser/frame_host/render_frame_host_android.h"
+#include "base/android/callback_android.h"
#include "base/android/jni_string.h"
#include "base/android/unguessable_token_android.h"
+#include "base/bind.h"
#include "base/logging.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
@@ -21,6 +23,20 @@ using base::android::ScopedJavaLocalRef;
namespace content {
+namespace {
+void OnGetCanonicalUrlForSharing(
+ const base::android::JavaRef<jobject>& jcallback,
+ const base::Optional<GURL>& url) {
+ if (!url) {
+ base::android::RunCallbackAndroid(jcallback, ScopedJavaLocalRef<jstring>());
+ return;
+ }
+
+ base::android::RunCallbackAndroid(
+ jcallback, ConvertUTF8ToJavaString(AttachCurrentThread(), url->spec()));
+}
+} // namespace
+
RenderFrameHostAndroid::RenderFrameHostAndroid(
RenderFrameHostImpl* render_frame_host,
service_manager::mojom::InterfaceProviderPtr interface_provider_ptr)
@@ -60,6 +76,15 @@ ScopedJavaLocalRef<jstring> RenderFrameHostAndroid::GetLastCommittedURL(
env, render_frame_host_->GetLastCommittedURL().spec());
}
+void RenderFrameHostAndroid::GetCanonicalUrlForSharing(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>&,
+ const base::android::JavaParamRef<jobject>& jcallback) const {
+ render_frame_host_->GetCanonicalUrlForSharing(base::BindOnce(
+ &OnGetCanonicalUrlForSharing,
+ base::android::ScopedJavaGlobalRef<jobject>(env, jcallback)));
+}
+
ScopedJavaLocalRef<jobject>
RenderFrameHostAndroid::GetAndroidOverlayRoutingToken(
JNIEnv* env,
diff --git a/chromium/content/browser/frame_host/render_frame_host_android.h b/chromium/content/browser/frame_host/render_frame_host_android.h
index 27ffcd49e80..686f2089320 100644
--- a/chromium/content/browser/frame_host/render_frame_host_android.h
+++ b/chromium/content/browser/frame_host/render_frame_host_android.h
@@ -39,6 +39,11 @@ class RenderFrameHostAndroid : public base::SupportsUserData::Data {
JNIEnv* env,
const base::android::JavaParamRef<jobject>&) const;
+ void GetCanonicalUrlForSharing(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>&,
+ const base::android::JavaParamRef<jobject>& jcallback) const;
+
// Returns UnguessableToken.
base::android::ScopedJavaLocalRef<jobject> GetAndroidOverlayRoutingToken(
JNIEnv* env,
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 7f23cd15013..9d3a7d99e6b 100644
--- a/chromium/content/browser/frame_host/render_frame_host_delegate.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_delegate.cc
@@ -34,7 +34,7 @@ bool RenderFrameHostDelegate::DidAddMessageToConsole(
}
WebContents* RenderFrameHostDelegate::GetAsWebContents() {
- return NULL;
+ return nullptr;
}
InterstitialPage* RenderFrameHostDelegate::GetAsInterstitialPage() {
@@ -73,7 +73,8 @@ RenderFrameHost* RenderFrameHostDelegate::GetGuestByInstanceID(
return nullptr;
}
-device::GeolocationContext* RenderFrameHostDelegate::GetGeolocationContext() {
+device::mojom::GeolocationContext*
+RenderFrameHostDelegate::GetGeolocationContext() {
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 cf2fc73c8db..a6549978563 100644
--- a/chromium/content/browser/frame_host/render_frame_host_delegate.h
+++ b/chromium/content/browser/frame_host/render_frame_host_delegate.h
@@ -18,6 +18,7 @@
#include "content/public/browser/site_instance.h"
#include "content/public/common/javascript_dialog_type.h"
#include "content/public/common/media_stream_request.h"
+#include "device/geolocation/public/interfaces/geolocation_context.mojom.h"
#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
#include "net/http/http_response_headers.h"
#include "services/device/public/interfaces/wake_lock.mojom.h"
@@ -38,10 +39,6 @@ namespace IPC {
class Message;
}
-namespace device {
-class GeolocationContext;
-}
-
namespace gfx {
class Rect;
}
@@ -130,6 +127,9 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
virtual void RunFileChooser(RenderFrameHost* render_frame_host,
const FileChooserParams& params) {}
+ // The pending page load was canceled, so the address bar should be updated.
+ virtual void DidCancelLoading() {}
+
// Another page accessed the top-level initial empty document, which means it
// is no longer safe to display a pending URL without risking a URL spoof.
virtual void DidAccessInitialDocument() {}
@@ -201,7 +201,7 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
int browser_plugin_instance_id);
// Gets the GeolocationContext associated with this delegate.
- virtual device::GeolocationContext* GetGeolocationContext();
+ virtual device::mojom::GeolocationContext* GetGeolocationContext();
// Gets the WakeLock that serves wake lock requests from the renderer.
virtual device::mojom::WakeLock* GetRendererWakeLock();
@@ -325,6 +325,9 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
const url::Origin& origin,
const GURL& resource_url);
+ // Opens a new view-source tab for the last committed document in |frame|.
+ virtual void ViewSource(RenderFrameHostImpl* frame) {}
+
#if defined(OS_ANDROID)
virtual base::android::ScopedJavaLocalRef<jobject>
GetJavaRenderFrameHostDelegate();
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 f94453e3f67..4276b86c21a 100644
--- a/chromium/content/browser/frame_host/render_frame_host_factory.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_factory.cc
@@ -12,7 +12,7 @@
namespace content {
// static
-RenderFrameHostFactory* RenderFrameHostFactory::factory_ = NULL;
+RenderFrameHostFactory* RenderFrameHostFactory::factory_ = nullptr;
// static
std::unique_ptr<RenderFrameHostImpl> RenderFrameHostFactory::Create(
@@ -47,7 +47,7 @@ void RenderFrameHostFactory::RegisterFactory(RenderFrameHostFactory* factory) {
// static
void RenderFrameHostFactory::UnregisterFactory() {
DCHECK(factory_) << "No factory to unregister.";
- factory_ = NULL;
+ factory_ = nullptr;
}
} // namespace content
diff --git a/chromium/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc b/chromium/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
index 2475dd915b7..cd89cfe3284 100644
--- a/chromium/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
@@ -4,14 +4,15 @@
#include <vector>
-#include "content/common/feature_policy/feature_policy.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_renderer_host.h"
#include "content/test/test_render_frame_host.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicyFeature.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/frame_policy.h"
+#include "third_party/WebKit/common/sandbox_flags.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -29,10 +30,10 @@ class RenderFrameHostFeaturePolicyTest
static constexpr const char* kOrigin3 = "https://example.com";
static constexpr const char* kOrigin4 = "https://test.com";
- static const blink::WebFeaturePolicyFeature kDefaultEnabledFeature =
- blink::WebFeaturePolicyFeature::kDocumentWrite;
- static const blink::WebFeaturePolicyFeature kDefaultSelfFeature =
- blink::WebFeaturePolicyFeature::kGeolocation;
+ static const blink::FeaturePolicyFeature kDefaultEnabledFeature =
+ blink::FeaturePolicyFeature::kDocumentWrite;
+ static const blink::FeaturePolicyFeature kDefaultSelfFeature =
+ blink::FeaturePolicyFeature::kGeolocation;
RenderFrameHost* GetMainRFH(const char* origin) {
RenderFrameHost* result = web_contents()->GetMainFrame();
@@ -52,22 +53,22 @@ class RenderFrameHostFeaturePolicyTest
// The header policy should only be set once on page load, so we refresh the
// page to simulate that.
void RefreshPageAndSetHeaderPolicy(RenderFrameHost** rfh,
- blink::WebFeaturePolicyFeature feature,
+ blink::FeaturePolicyFeature feature,
const std::vector<std::string>& origins) {
RenderFrameHost* current = *rfh;
SimulateNavigation(&current, current->GetLastCommittedURL());
- static_cast<TestRenderFrameHost*>(current)->OnDidSetFeaturePolicyHeader(
- CreateFPHeader(feature, origins));
+ static_cast<TestRenderFrameHost*>(current)->OnDidSetFramePolicyHeaders(
+ blink::WebSandboxFlags::kNone, CreateFPHeader(feature, origins));
*rfh = current;
}
void SetContainerPolicy(RenderFrameHost* parent,
RenderFrameHost* child,
- blink::WebFeaturePolicyFeature feature,
+ blink::FeaturePolicyFeature feature,
const std::vector<std::string>& origins) {
static_cast<TestRenderFrameHost*>(parent)->OnDidChangeFramePolicy(
- child->GetRoutingID(), blink::WebSandboxFlags(),
- CreateFPHeader(feature, origins));
+ child->GetRoutingID(),
+ {blink::WebSandboxFlags::kNone, CreateFPHeader(feature, origins)});
}
void SimulateNavigation(RenderFrameHost** rfh, const GURL& url) {
@@ -78,14 +79,14 @@ class RenderFrameHostFeaturePolicyTest
}
private:
- ParsedFeaturePolicyHeader CreateFPHeader(
- blink::WebFeaturePolicyFeature feature,
+ blink::ParsedFeaturePolicy CreateFPHeader(
+ blink::FeaturePolicyFeature feature,
const std::vector<std::string>& origins) {
- ParsedFeaturePolicyHeader result(1);
+ blink::ParsedFeaturePolicy result(1);
result[0].feature = feature;
result[0].matches_all_origins = false;
for (const std::string& origin : origins)
- result[0].origins.push_back(url::Origin(GURL(origin)));
+ result[0].origins.push_back(url::Origin::Create(GURL(origin)));
return result;
}
};
@@ -178,4 +179,4 @@ TEST_F(RenderFrameHostFeaturePolicyTest, HeaderAndContainerPolicy) {
EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature));
}
-} // namespace content \ No newline at end of file
+} // namespace content
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 a89eefd4403..1a444024199 100644
--- a/chromium/content/browser/frame_host/render_frame_host_impl.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_impl.cc
@@ -18,6 +18,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/process/kill.h"
+#include "base/task_scheduler/post_task.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
@@ -29,6 +30,7 @@
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
#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/frame_host/cross_process_frame_connector.h"
#include "content/browser/frame_host/debug_urls.h"
#include "content/browser/frame_host/frame_tree.h"
@@ -47,6 +49,7 @@
#include "content/browser/geolocation/geolocation_service_impl.h"
#include "content/browser/image_capture/image_capture_impl.h"
#include "content/browser/installedapp/installed_app_provider_impl_default.h"
+#include "content/browser/interface_provider_filtering.h"
#include "content/browser/keyboard_lock/keyboard_lock_service_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_scheduler_filter.h"
@@ -65,9 +68,11 @@
#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"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
+#include "content/browser/renderer_interface_binders.h"
#include "content/browser/shared_worker/shared_worker_connector_impl.h"
#include "content/browser/shared_worker/shared_worker_service_impl.h"
#include "content/browser/storage_partition_impl.h"
@@ -87,12 +92,14 @@
#include "content/common/input_messages.h"
#include "content/common/inter_process_time_ticks_converter.h"
#include "content/common/navigation_params.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "content/common/render_message_filter.mojom.h"
#include "content/common/renderer.mojom.h"
#include "content/common/site_isolation_policy.h"
#include "content/common/swapped_out_messages.h"
+#include "content/common/url_loader_factory_bundle.mojom.h"
#include "content/common/widget.mojom.h"
-#include "content/network/restricted_cookie_manager_impl.h"
+#include "content/network/restricted_cookie_manager.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"
@@ -130,26 +137,23 @@
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "services/device/public/cpp/device_features.h"
-#include "services/device/public/interfaces/constants.mojom.h"
#include "services/device/public/interfaces/sensor_provider.mojom.h"
-#include "services/device/public/interfaces/vibration_manager.mojom.h"
#include "services/device/public/interfaces/wake_lock.mojom.h"
#include "services/device/public/interfaces/wake_lock_context.mojom.h"
+#include "services/resource_coordinator/public/cpp/frame_resource_coordinator.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
-#include "services/resource_coordinator/public/cpp/resource_coordinator_interface.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
-#include "services/shape_detection/public/interfaces/barcodedetection.mojom.h"
-#include "services/shape_detection/public/interfaces/constants.mojom.h"
-#include "services/shape_detection/public/interfaces/facedetection_provider.mojom.h"
-#include "services/shape_detection/public/interfaces/textdetection.mojom.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
+#include "third_party/WebKit/common/frame_policy.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "ui/accessibility/ax_tree.h"
#include "ui/accessibility/ax_tree_id_registry.h"
#include "ui/accessibility/ax_tree_update.h"
#include "ui/gfx/geometry/quad_f.h"
#include "url/gurl.h"
#include "url/origin.h"
+#include "url/url_constants.h"
#if defined(OS_ANDROID)
#include "content/browser/android/java_interfaces_impl.h"
@@ -198,6 +202,9 @@ typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*>
base::LazyInstance<RoutingIDFrameMap>::DestructorAtExit g_routing_id_frame_map =
LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<RenderFrameHostImpl::CreateNetworkFactoryCallback>::Leaky
+ g_url_loader_factory_callback_for_test = LAZY_INSTANCE_INITIALIZER;
+
using TokenFrameMap = base::hash_map<base::UnguessableToken,
RenderFrameHostImpl*,
base::UnguessableTokenHash>;
@@ -266,7 +273,7 @@ class RemoterFactoryImpl final : public media::mojom::RemoterFactory {
int routing_id,
media::mojom::RemoterFactoryRequest request) {
mojo::MakeStrongBinding(
- base::MakeUnique<RemoterFactoryImpl>(process_id, routing_id),
+ std::make_unique<RemoterFactoryImpl>(process_id, routing_id),
std::move(request));
}
@@ -286,9 +293,9 @@ class RemoterFactoryImpl final : public media::mojom::RemoterFactory {
};
#endif // BUILDFLAG(ENABLE_MEDIA_REMOTING)
-void CreateResourceCoordinatorFrameInterface(
+void CreateFrameResourceCoordinator(
RenderFrameHostImpl* render_frame_host,
- resource_coordinator::mojom::CoordinationUnitRequest request) {
+ resource_coordinator::mojom::FrameCoordinationUnitRequest request) {
render_frame_host->GetFrameResourceCoordinator()->AddBinding(
std::move(request));
}
@@ -347,25 +354,6 @@ void LookupRenderFrameHostOrProxy(int process_id,
*rfph = RenderFrameProxyHost::FromID(process_id, routing_id);
}
-// Forwards service requests to Service Manager.
-template <typename Interface>
-void ForwardRequest(const char* service_name,
- mojo::InterfaceRequest<Interface> request) {
- // TODO(beng): This should really be using the per-profile connector.
- service_manager::Connector* connector =
- ServiceManagerConnection::GetForProcess()->GetConnector();
- connector->BindInterface(service_name, std::move(request));
-}
-
-void CreatePaymentManager(RenderFrameHostImpl* rfh,
- payments::mojom::PaymentManagerRequest request) {
- StoragePartitionImpl* storage_partition =
- static_cast<StoragePartitionImpl*>(BrowserContext::GetStoragePartition(
- rfh->GetSiteInstance()->GetBrowserContext(), rfh->GetSiteInstance()));
- storage_partition->GetPaymentAppContext()->CreatePaymentManager(
- std::move(request));
-}
-
void NotifyResourceSchedulerOfNavigation(
int render_process_id,
const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
@@ -407,12 +395,13 @@ bool RenderFrameHost::IsDataUrlNavigationAllowedForAndroidWebView() {
return g_allow_data_url_navigation;
}
-void CreateMediaPlayerRenderer(
- int process_id,
- int routing_id,
- media::mojom::RendererRequest request) {
+void CreateMediaPlayerRenderer(int process_id,
+ int routing_id,
+ RenderFrameHostDelegate* delegate,
+ media::mojom::RendererRequest request) {
std::unique_ptr<MediaPlayerRenderer> renderer =
- base::MakeUnique<MediaPlayerRenderer>(process_id, routing_id);
+ std::make_unique<MediaPlayerRenderer>(process_id, routing_id,
+ delegate->GetAsWebContents());
// base::Unretained is safe here because the lifetime of the MediaPlayerRender
// is tied to the lifetime of the MojoRendererService.
@@ -461,6 +450,17 @@ RenderFrameHostImpl* RenderFrameHostImpl::FromOverlayRoutingToken(
return it == g_token_frame_map.Get().end() ? nullptr : it->second;
}
+// static
+void RenderFrameHostImpl::SetNetworkFactoryForTesting(
+ const CreateNetworkFactoryCallback& url_loader_factory_callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(url_loader_factory_callback.is_null() ||
+ g_url_loader_factory_callback_for_test.Get().is_null())
+ << "It is not expected that this is called with non-null callback when "
+ << "another overriding callback is already set.";
+ g_url_loader_factory_callback_for_test.Get() = url_loader_factory_callback;
+}
+
RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
RenderViewHostImpl* render_view_host,
RenderFrameHostDelegate* delegate,
@@ -498,10 +498,12 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
has_selection_(false),
is_audible_(false),
last_navigation_previews_state_(PREVIEWS_UNSPECIFIED),
- frame_host_interface_broker_binding_(this),
frame_host_associated_binding_(this),
waiting_for_init_(renderer_initiated_creation),
has_focused_editable_element_(false),
+ active_sandbox_flags_(blink::WebSandboxFlags::kNone),
+ interface_provider_binding_(this),
+ keep_alive_timeout_(base::TimeDelta::FromSeconds(30)),
weak_ptr_factory_(this) {
frame_tree_->AddRenderViewHostRef(render_view_host_);
GetProcess()->AddRoute(routing_id_, this);
@@ -527,6 +529,7 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
}
SetUpMojoIfNeeded();
+
swapout_event_monitor_timeout_.reset(new TimeoutMonitor(base::Bind(
&RenderFrameHostImpl::OnSwappedOut, weak_ptr_factory_.GetWeakPtr())));
beforeunload_timeout_.reset(
@@ -545,26 +548,32 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
RenderWidgetHostImpl::FromID(GetProcess()->GetID(), widget_routing_id);
mojom::WidgetInputHandlerAssociatedPtr widget_handler;
+ mojom::WidgetInputHandlerHostRequest host_request;
if (frame_input_handler_) {
+ mojom::WidgetInputHandlerHostPtr host;
+ host_request = mojo::MakeRequest(&host);
frame_input_handler_->GetWidgetInputHandler(
- mojo::MakeRequest(&widget_handler));
+ mojo::MakeRequest(&widget_handler), std::move(host));
}
if (!render_widget_host_) {
DCHECK(frame_tree_node->parent());
-
- render_widget_host_ = new RenderWidgetHostImpl(rwh_delegate, GetProcess(),
- widget_routing_id,
- std::move(widget), hidden);
+ render_widget_host_ = RenderWidgetHostFactory::Create(
+ rwh_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());
render_widget_host_->SetWidget(std::move(widget));
}
- render_widget_host_->SetWidgetInputHandler(std::move(widget_handler));
+ render_widget_host_->SetWidgetInputHandler(std::move(widget_handler),
+ std::move(host_request));
render_widget_host_->input_router()->SetFrameTreeNodeId(
frame_tree_node_->frame_tree_node_id());
}
ResetFeaturePolicy();
+
+ ax_tree_id_ = ui::AXTreeIDRegistry::GetInstance()->GetOrCreateAXTreeID(
+ GetProcess()->GetID(), routing_id_);
}
RenderFrameHostImpl::~RenderFrameHostImpl() {
@@ -623,6 +632,8 @@ RenderFrameHostImpl::~RenderFrameHostImpl() {
// Notify the FrameTree that this RFH is going away, allowing it to shut down
// the corresponding RenderViewHost if it is no longer needed.
frame_tree_->ReleaseRenderViewHostRef(render_view_host_);
+
+ ui::AXTreeIDRegistry::GetInstance()->RemoveAXTreeID(ax_tree_id_);
}
int RenderFrameHostImpl::GetRoutingID() {
@@ -630,8 +641,7 @@ int RenderFrameHostImpl::GetRoutingID() {
}
ui::AXTreeIDRegistry::AXTreeID RenderFrameHostImpl::GetAXTreeID() {
- return ui::AXTreeIDRegistry::GetInstance()->GetOrCreateAXTreeID(
- GetProcess()->GetID(), routing_id_);
+ return ax_tree_id_;
}
const base::UnguessableToken& RenderFrameHostImpl::GetOverlayRoutingToken() {
@@ -674,17 +684,23 @@ bool RenderFrameHostImpl::IsCrossProcessSubframe() {
}
const GURL& RenderFrameHostImpl::GetLastCommittedURL() {
- return last_committed_url();
+ return last_committed_url_;
}
const url::Origin& RenderFrameHostImpl::GetLastCommittedOrigin() {
return last_committed_origin_;
}
+void RenderFrameHostImpl::GetCanonicalUrlForSharing(
+ mojom::Frame::GetCanonicalUrlForSharingCallback callback) {
+ DCHECK(frame_);
+ frame_->GetCanonicalUrlForSharing(std::move(callback));
+}
+
gfx::NativeView RenderFrameHostImpl::GetNativeView() {
RenderWidgetHostView* view = render_view_host_->GetWidget()->GetView();
if (!view)
- return NULL;
+ return nullptr;
return view->GetNativeView();
}
@@ -775,7 +791,7 @@ service_manager::InterfaceProvider* RenderFrameHostImpl::GetRemoteInterfaces() {
return remote_interfaces_.get();
}
-AssociatedInterfaceProvider*
+blink::AssociatedInterfaceProvider*
RenderFrameHostImpl::GetRemoteAssociatedInterfaces() {
if (!remote_associated_interfaces_) {
mojom::AssociatedInterfaceProviderAssociatedPtr remote_interfaces;
@@ -788,7 +804,7 @@ RenderFrameHostImpl::GetRemoteAssociatedInterfaces() {
} else {
// The channel may not be initialized in some tests environments. In this
// case we set up a dummy interface provider.
- mojo::MakeIsolatedRequest(&remote_interfaces);
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&remote_interfaces);
}
remote_associated_interfaces_.reset(new AssociatedInterfaceProviderImpl(
std::move(remote_interfaces)));
@@ -796,7 +812,7 @@ RenderFrameHostImpl::GetRemoteAssociatedInterfaces() {
return remote_associated_interfaces_.get();
}
-blink::WebPageVisibilityState RenderFrameHostImpl::GetVisibilityState() {
+blink::mojom::PageVisibilityState RenderFrameHostImpl::GetVisibilityState() {
// Works around the crashes seen in https://crbug.com/501863, where the
// active WebContents from a browser iterator may contain a render frame
// detached from the frame tree. This tries to find a RenderWidgetHost
@@ -812,12 +828,12 @@ blink::WebPageVisibilityState RenderFrameHostImpl::GetVisibilityState() {
frame = frame->GetParent();
}
if (!frame)
- return blink::kWebPageVisibilityStateHidden;
+ return blink::mojom::PageVisibilityState::kHidden;
- blink::WebPageVisibilityState visibility_state =
+ blink::mojom::PageVisibilityState visibility_state =
GetRenderWidgetHost()->is_hidden()
- ? blink::kWebPageVisibilityStateHidden
- : blink::kWebPageVisibilityStateVisible;
+ ? blink::mojom::PageVisibilityState::kHidden
+ : blink::mojom::PageVisibilityState::kVisible;
GetContentClient()->browser()->OverridePageVisibilityState(this,
&visibility_state);
return visibility_state;
@@ -893,8 +909,8 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
OnDidAccessInitialDocument)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeOpener, OnDidChangeOpener)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeName, OnDidChangeName)
- IPC_MESSAGE_HANDLER(FrameHostMsg_DidSetFeaturePolicyHeader,
- OnDidSetFeaturePolicyHeader)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidSetFramePolicyHeaders,
+ OnDidSetFramePolicyHeaders)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidAddContentSecurityPolicies,
OnDidAddContentSecurityPolicies)
IPC_MESSAGE_HANDLER(FrameHostMsg_EnforceInsecureRequestPolicy,
@@ -936,6 +952,8 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER(FrameHostMsg_FocusedNodeChanged, OnFocusedNodeChanged)
IPC_MESSAGE_HANDLER(FrameHostMsg_SetHasReceivedUserGesture,
OnSetHasReceivedUserGesture)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_ScrollRectToVisibleInParentFrame,
+ OnScrollRectToVisibleInParentFrame)
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
IPC_MESSAGE_HANDLER(FrameHostMsg_ShowPopup, OnShowPopup)
IPC_MESSAGE_HANDLER(FrameHostMsg_HidePopup, OnHidePopup)
@@ -1005,7 +1023,7 @@ void RenderFrameHostImpl::AccessibilityReset() {
}
void RenderFrameHostImpl::AccessibilityFatalError() {
- browser_accessibility_manager_.reset(NULL);
+ browser_accessibility_manager_.reset(nullptr);
if (accessibility_reset_token_)
return;
@@ -1039,7 +1057,7 @@ gfx::NativeViewAccessible
render_view_host_->GetWidget()->GetView());
if (view)
return view->AccessibilityGetNativeViewAccessible();
- return NULL;
+ return nullptr;
}
void RenderFrameHostImpl::RenderProcessGone(SiteInstanceImpl* site_instance) {
@@ -1086,9 +1104,11 @@ void RenderFrameHostImpl::SanitizeDataForUseInCspViolation(
// There is no need to sanitize data when it is same-origin with the current
// url of the renderer.
- if (url::Origin(*blocked_url).IsSameOriginWith(last_committed_origin_))
+ if (url::Origin::Create(*blocked_url)
+ .IsSameOriginWith(last_committed_origin_))
sanitize_blocked_url = false;
- if (url::Origin(source_location_url).IsSameOriginWith(last_committed_origin_))
+ if (url::Origin::Create(source_location_url)
+ .IsSameOriginWith(last_committed_origin_))
sanitize_source_location = false;
// When a renderer tries to do a form submission, it already knows the url of
@@ -1140,7 +1160,11 @@ bool RenderFrameHostImpl::CreateRenderFrame(int proxy_routing_id,
DCHECK(GetProcess()->HasConnection());
+ service_manager::mojom::InterfaceProviderPtr interface_provider;
+ BindInterfaceProviderRequest(mojo::MakeRequest(&interface_provider));
+
mojom::CreateFrameParamsPtr params = mojom::CreateFrameParams::New();
+ params->interface_provider = interface_provider.PassInterface();
params->routing_id = routing_id_;
params->proxy_routing_id = proxy_routing_id;
params->opener_routing_id = opener_routing_id;
@@ -1155,10 +1179,8 @@ bool RenderFrameHostImpl::CreateRenderFrame(int proxy_routing_id,
// policy, since it is being created as part of the navigation that will
// commit it. (I.e., the RenderFrame needs to know the policy to use when
// initializing the new document once it commits).
- params->replication_state.sandbox_flags =
- frame_tree_node()->pending_sandbox_flags();
- params->replication_state.container_policy =
- frame_tree_node()->pending_container_policy();
+ params->replication_state.frame_policy =
+ frame_tree_node()->pending_frame_policy();
params->frame_owner_properties =
FrameOwnerProperties(frame_tree_node()->frame_owner_properties());
@@ -1232,9 +1254,13 @@ void RenderFrameHostImpl::SetRenderFrameCreated(bool created) {
if (frame_input_handler_) {
mojom::WidgetInputHandlerAssociatedPtr widget_handler;
+ mojom::WidgetInputHandlerHostPtr host;
+ mojom::WidgetInputHandlerHostRequest host_request =
+ mojo::MakeRequest(&host);
frame_input_handler_->GetWidgetInputHandler(
- mojo::MakeRequest(&widget_handler));
- render_widget_host_->SetWidgetInputHandler(std::move(widget_handler));
+ mojo::MakeRequest(&widget_handler), std::move(host));
+ render_widget_host_->SetWidgetInputHandler(std::move(widget_handler),
+ std::move(host_request));
}
render_widget_host_->InitForFrame();
@@ -1253,11 +1279,10 @@ void RenderFrameHostImpl::Init() {
return;
waiting_for_init_ = false;
- if (pendinging_navigate_) {
+ if (pending_navigate_) {
frame_tree_node()->navigator()->OnBeginNavigation(
- frame_tree_node(), pendinging_navigate_->first,
- pendinging_navigate_->second);
- pendinging_navigate_.reset();
+ frame_tree_node(), pending_navigate_->first, pending_navigate_->second);
+ pending_navigate_.reset();
}
}
@@ -1270,8 +1295,7 @@ void RenderFrameHostImpl::OnAudibleStateChanged(bool is_audible) {
GetProcess()->OnMediaStreamRemoved();
is_audible_ = is_audible;
- GetFrameResourceCoordinator()->SetProperty(
- resource_coordinator::mojom::PropertyType::kAudible, is_audible_);
+ GetFrameResourceCoordinator()->SetAudibility(is_audible_);
}
void RenderFrameHostImpl::OnDidAddMessageToConsole(
@@ -1308,15 +1332,18 @@ void RenderFrameHostImpl::OnDidAddMessageToConsole(
void RenderFrameHostImpl::OnCreateChildFrame(
int new_routing_id,
+ service_manager::mojom::InterfaceProviderRequest
+ new_interface_provider_provider_request,
blink::WebTreeScopeType scope,
const std::string& frame_name,
const std::string& frame_unique_name,
+ bool is_created_by_script,
const base::UnguessableToken& devtools_frame_token,
- blink::WebSandboxFlags sandbox_flags,
- const ParsedFeaturePolicyHeader& container_policy,
+ const blink::FramePolicy& frame_policy,
const FrameOwnerProperties& frame_owner_properties) {
// TODO(lukasza): Call ReceivedBadMessage when |frame_unique_name| is empty.
DCHECK(!frame_unique_name.empty());
+ DCHECK(new_interface_provider_provider_request.is_pending());
// The RenderFrame corresponding to this host sent an IPC message to create a
// child, but by the time we get here, it's possible for the host to have been
@@ -1325,12 +1352,43 @@ void RenderFrameHostImpl::OnCreateChildFrame(
if (!is_active() || !IsCurrent() || !render_frame_created_)
return;
- // |new_routing_id| and |devtools_frame_token| were generated on the browser's
- // IO thread and not taken from the renderer process.
+ // |new_routing_id|, |new_interface_provider_provider_request|, and
+ // |devtools_frame_token| were generated on the browser's IO thread and not
+ // taken from the renderer process.
frame_tree_->AddFrame(frame_tree_node_, GetProcess()->GetID(), new_routing_id,
+ std::move(new_interface_provider_provider_request),
scope, frame_name, frame_unique_name,
- devtools_frame_token, sandbox_flags, container_policy,
- frame_owner_properties);
+ is_created_by_script, devtools_frame_token,
+ frame_policy, frame_owner_properties);
+}
+
+void RenderFrameHostImpl::DidNavigate(
+ const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
+ bool is_same_document_navigation) {
+ // Keep track of the last committed URL and origin in the RenderFrameHost
+ // itself. These allow GetLastCommittedURL and GetLastCommittedOrigin to
+ // stay correct even if the render_frame_host later becomes pending deletion.
+ // The URL is set regardless of whether it's for a net error or not.
+ frame_tree_node_->SetCurrentURL(params.url);
+ SetLastCommittedOrigin(params.origin);
+
+ // Separately, update the frame's last successful URL except for net error
+ // pages, since those do not end up in the correct process after transfers
+ // (see https://crbug.com/560511). Instead, the next cross-process navigation
+ // or transfer should decide whether to swap as if the net error had not
+ // occurred.
+ // TODO(creis): Remove this block and always set the URL once transfers handle
+ // network errors or PlzNavigate is enabled. See https://crbug.com/588314.
+ if (!params.url_is_unreachable)
+ last_successful_url_ = params.url;
+
+ // After setting the last committed origin, reset the feature policy and
+ // sandbox flags in the RenderFrameHost to a blank policy based on the parent
+ // frame.
+ if (!is_same_document_navigation) {
+ ResetFeaturePolicy();
+ active_sandbox_flags_ = frame_tree_node()->active_sandbox_flags();
+ }
}
void RenderFrameHostImpl::SetLastCommittedOrigin(const url::Origin& origin) {
@@ -1372,22 +1430,11 @@ void RenderFrameHostImpl::OnOpenURL(const FrameHostMsg_OpenURL_Params& params) {
TRACE_EVENT1("navigation", "RenderFrameHostImpl::OpenURL", "url",
validated_url.possibly_invalid_spec());
- // When |params.disposition| asks OpenURL to create new contents, it always
- // happens because of an explicit user request for new content creation (i.e.
- // opening a link using ctrl-click or middle click). In such cases, the new
- // content should be created in a new renderer to break opener relationship
- // (see https://crbug.com/658386) and to conserve memory per renderer (see
- // https://crbug.com/23815). Note that new content creation that wasn't
- // explicitly requested by the user (i.e. left-clicking a link with
- // target=_blank) goes through a different code path (through
- // WebViewClient::CreateView).
- bool kForceNewProcessForNewContents = true;
-
frame_tree_node_->navigator()->RequestOpenURL(
this, validated_url, params.uses_post, params.resource_request_body,
params.extra_headers, params.referrer, params.disposition,
- kForceNewProcessForNewContents, params.should_replace_current_entry,
- params.user_gesture, params.triggering_event_info);
+ params.should_replace_current_entry, params.user_gesture,
+ params.triggering_event_info);
}
void RenderFrameHostImpl::OnCancelInitialHistoryLoad() {
@@ -1446,7 +1493,7 @@ void RenderFrameHostImpl::OnDidFailProvisionalLoadWithError(
"error", params.error_code);
// TODO(clamy): Kill the renderer with RFH_FAIL_PROVISIONAL_LOAD_NO_HANDLE and
// return early if navigation_handle_ is null, once we prevent that case from
- // happening in practice.
+ // happening in practice. See https://crbug.com/605289.
// Update the error code in the NavigationHandle of the navigation.
if (navigation_handle_) {
@@ -1497,8 +1544,7 @@ void RenderFrameHostImpl::DidCommitProvisionalLoad(
// navigating already and sent it before hearing the FrameMsg_Stop message.
// Treat this as an implicit beforeunload ack to allow the pending navigation
// to continue.
- if (is_waiting_for_beforeunload_ack_ &&
- unload_ack_is_for_navigation_ &&
+ if (is_waiting_for_beforeunload_ack_ && unload_ack_is_for_navigation_ &&
!GetParent()) {
base::TimeTicks approx_renderer_start_time = send_before_unload_start_time_;
OnBeforeUnloadACK(true, approx_renderer_start_time, base::TimeTicks::Now());
@@ -1806,8 +1852,11 @@ void RenderFrameHostImpl::OnBeforeUnloadACK(
}
// If canceled, notify the delegate to cancel its pending navigation entry.
+ // This is usually redundant with the dialog closure code in WebContentsImpl's
+ // OnDialogClosed, but there may be some cases that Blink returns !proceed
+ // without showing the dialog. We also update the address bar here to be safe.
if (!proceed)
- render_view_host_->GetDelegate()->DidCancelLoading();
+ delegate_->DidCancelLoading();
}
bool RenderFrameHostImpl::IsWaitingForUnloadACK() const {
@@ -1836,6 +1885,7 @@ void RenderFrameHostImpl::OnRenderProcessGone(int status, int exit_code) {
// reset.
SetRenderFrameCreated(false);
InvalidateMojoConnection();
+ interface_provider_binding_.Close();
// Execute any pending AX tree snapshot callbacks with an empty response,
// since we're never going to get a response from this renderer.
@@ -1926,6 +1976,11 @@ void RenderFrameHostImpl::OnContextMenu(const ContextMenuParams& params) {
validated_params.x = transformed_point.x();
validated_params.y = transformed_point.y();
+ if (validated_params.selection_start_offset < 0) {
+ bad_message::ReceivedBadMessage(
+ GetProcess(), bad_message::RFH_NEGATIVE_SELECTION_START_OFFSET);
+ }
+
delegate_->ShowContextMenu(this, validated_params);
}
@@ -1984,10 +2039,8 @@ void RenderFrameHostImpl::OnRunJavaScriptDialog(
const GURL& frame_url,
JavaScriptDialogType dialog_type,
IPC::Message* reply_msg) {
- if (dialog_type == JavaScriptDialogType::JAVASCRIPT_DIALOG_TYPE_ALERT) {
- GetFrameResourceCoordinator()->SendEvent(
- resource_coordinator::mojom::Event::kAlertFired);
- }
+ if (dialog_type == JavaScriptDialogType::JAVASCRIPT_DIALOG_TYPE_ALERT)
+ GetFrameResourceCoordinator()->OnAlertFired();
if (IsWaitingForUnloadACK()) {
SendJavaScriptDialogReply(reply_msg, true, base::string16());
@@ -2152,11 +2205,15 @@ bool RenderFrameHostImpl::IsBeforeUnloadHangMonitorDisabledForTesting() {
}
bool RenderFrameHostImpl::IsFeatureEnabled(
- blink::WebFeaturePolicyFeature feature) {
+ blink::FeaturePolicyFeature feature) {
return feature_policy_ && feature_policy_->IsFeatureEnabledForOrigin(
feature, GetLastCommittedOrigin());
}
+void RenderFrameHostImpl::ViewSource() {
+ delegate_->ViewSource(this);
+}
+
void RenderFrameHostImpl::OnDidAccessInitialDocument() {
delegate_->DidAccessInitialDocument();
}
@@ -2183,11 +2240,17 @@ void RenderFrameHostImpl::OnDidChangeName(const std::string& name,
delegate_->DidChangeName(this, name);
}
-void RenderFrameHostImpl::OnDidSetFeaturePolicyHeader(
- const ParsedFeaturePolicyHeader& parsed_header) {
+void RenderFrameHostImpl::OnDidSetFramePolicyHeaders(
+ blink::WebSandboxFlags sandbox_flags,
+ const blink::ParsedFeaturePolicy& parsed_header) {
+ if (!is_active())
+ return;
frame_tree_node()->SetFeaturePolicyHeader(parsed_header);
ResetFeaturePolicy();
feature_policy_->SetHeaderPolicy(parsed_header);
+ frame_tree_node()->UpdateActiveSandboxFlags(sandbox_flags);
+ // Save a copy of the now-active sandbox flags on this RFHI.
+ active_sandbox_flags_ = frame_tree_node()->active_sandbox_flags();
}
void RenderFrameHostImpl::OnDidAddContentSecurityPolicies(
@@ -2236,8 +2299,7 @@ FrameTreeNode* RenderFrameHostImpl::FindAndVerifyChild(
void RenderFrameHostImpl::OnDidChangeFramePolicy(
int32_t frame_routing_id,
- blink::WebSandboxFlags flags,
- const ParsedFeaturePolicyHeader& container_policy) {
+ const blink::FramePolicy& frame_policy) {
// Ensure that a frame can only update sandbox flags or feature policy for its
// immediate children. If this is not the case, the renderer is considered
// malicious and is killed.
@@ -2247,8 +2309,7 @@ void RenderFrameHostImpl::OnDidChangeFramePolicy(
if (!child)
return;
- child->SetPendingSandboxFlags(flags);
- child->SetPendingContainerPolicy(container_policy);
+ child->SetPendingFramePolicy(frame_policy);
// Notify the RenderFrame if it lives in a different process from its parent.
// The frame's proxies in other processes also need to learn about the updated
@@ -2258,7 +2319,7 @@ void RenderFrameHostImpl::OnDidChangeFramePolicy(
RenderFrameHost* child_rfh = child->current_frame_host();
if (child_rfh->GetSiteInstance() != GetSiteInstance()) {
child_rfh->Send(new FrameMsg_DidUpdateFramePolicy(child_rfh->GetRoutingID(),
- flags, container_policy));
+ frame_policy));
}
}
@@ -2336,7 +2397,7 @@ void RenderFrameHostImpl::OnBeginNavigation(
return;
if (waiting_for_init_) {
- pendinging_navigate_ = base::MakeUnique<PendingNavigation>(
+ pending_navigate_ = std::make_unique<PendingNavigation>(
validated_params, validated_begin_params);
return;
}
@@ -2515,12 +2576,33 @@ void RenderFrameHostImpl::OnAccessibilityFindInPageResult(
void RenderFrameHostImpl::OnAccessibilityChildFrameHitTestResult(
const gfx::Point& point,
- int hit_obj_id,
+ int child_frame_routing_id,
+ int child_frame_browser_plugin_instance_id,
ui::AXEvent event_to_fire) {
- if (browser_accessibility_manager_) {
- browser_accessibility_manager_->OnChildFrameHitTestResult(point, hit_obj_id,
- event_to_fire);
+ RenderFrameHostImpl* child_frame = nullptr;
+ if (child_frame_routing_id) {
+ RenderFrameProxyHost* rfph = nullptr;
+ LookupRenderFrameHostOrProxy(GetProcess()->GetID(), child_frame_routing_id,
+ &child_frame, &rfph);
+ if (rfph)
+ child_frame = rfph->frame_tree_node()->current_frame_host();
+ } else if (child_frame_browser_plugin_instance_id) {
+ child_frame =
+ static_cast<RenderFrameHostImpl*>(delegate()->GetGuestByInstanceID(
+ this, child_frame_browser_plugin_instance_id));
+ } else {
+ NOTREACHED();
}
+
+ if (!child_frame)
+ return;
+
+ ui::AXActionData action_data;
+ action_data.target_point = point;
+ action_data.action = ui::AX_ACTION_HIT_TEST;
+ action_data.hit_test_event_to_fire = event_to_fire;
+
+ child_frame->AccessibilityPerformAction(action_data);
}
void RenderFrameHostImpl::OnAccessibilitySnapshotResponse(
@@ -2581,7 +2663,7 @@ void RenderFrameHostImpl::OnToggleFullscreen(bool enter_fullscreen) {
// TODO(alexmos): See if this can use the last committed origin instead.
if (enter_fullscreen)
- delegate_->EnterFullscreenMode(last_committed_url().GetOrigin());
+ delegate_->EnterFullscreenMode(GetLastCommittedURL().GetOrigin());
else
delegate_->ExitFullscreenMode(/* will_cause_resize */ true);
@@ -2695,6 +2777,16 @@ void RenderFrameHostImpl::OnSetHasReceivedUserGesture() {
frame_tree_node_->OnSetHasReceivedUserGesture();
}
+void RenderFrameHostImpl::OnScrollRectToVisibleInParentFrame(
+ const gfx::Rect& rect_to_scroll,
+ const blink::WebRemoteScrollProperties& properties) {
+ RenderFrameProxyHost* proxy =
+ frame_tree_node_->render_manager()->GetProxyToParent();
+ if (!proxy)
+ return;
+ proxy->ScrollRectToVisible(rect_to_scroll, properties);
+}
+
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
void RenderFrameHostImpl::OnShowPopup(
const FrameHostMsg_ShowPopup_Params& params) {
@@ -2730,6 +2822,23 @@ void RenderFrameHostImpl::OnRequestOverlayRoutingToken() {
*overlay_routing_token_));
}
+void RenderFrameHostImpl::BindInterfaceProviderRequest(
+ service_manager::mojom::InterfaceProviderRequest
+ interface_provider_request) {
+ DCHECK(!interface_provider_binding_.is_bound());
+ DCHECK(interface_provider_request.is_pending());
+ interface_provider_binding_.Bind(FilterRendererExposedInterfaces(
+ mojom::kNavigation_FrameSpec, GetProcess()->GetID(),
+ std::move(interface_provider_request)));
+}
+
+void RenderFrameHostImpl::SetKeepAliveTimeoutForTesting(
+ base::TimeDelta timeout) {
+ keep_alive_timeout_ = timeout;
+ if (keep_alive_handle_factory_)
+ keep_alive_handle_factory_->SetTimeout(keep_alive_timeout_);
+}
+
void RenderFrameHostImpl::OnShowCreatedWindow(int pending_widget_routing_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
@@ -2755,18 +2864,15 @@ void RenderFrameHostImpl::CreateNewWindow(
bool can_create_window =
IsCurrent() && render_frame_created_ &&
GetContentClient()->browser()->CanCreateWindow(
- this, last_committed_url(),
- frame_tree_node_->frame_tree()->GetMainFrame()->last_committed_url(),
+ this, GetLastCommittedURL(),
+ frame_tree_node_->frame_tree()->GetMainFrame()->GetLastCommittedURL(),
last_committed_origin_.GetURL(), params->window_container_type,
params->target_url, params->referrer, params->frame_name,
params->disposition, *params->features, params->user_gesture,
params->opener_suppressed, &no_javascript_access);
- mojom::CreateNewWindowReplyPtr reply = mojom::CreateNewWindowReply::New();
if (!can_create_window) {
- RunCreateWindowCompleteCallback(std::move(callback), std::move(reply),
- MSG_ROUTING_NONE, MSG_ROUTING_NONE,
- MSG_ROUTING_NONE, 0);
+ std::move(callback).Run(mojom::CreateNewWindowStatus::kIgnore, nullptr);
return;
}
@@ -2775,14 +2881,11 @@ void RenderFrameHostImpl::CreateNewWindow(
// window.open() will return "window" and navigate it to whatever URL was
// passed.
if (!render_view_host_->GetWebkitPreferences().supports_multiple_windows) {
- RunCreateWindowCompleteCallback(std::move(callback), std::move(reply),
- render_view_host_->GetRoutingID(),
- MSG_ROUTING_NONE, MSG_ROUTING_NONE, 0);
+ std::move(callback).Run(mojom::CreateNewWindowStatus::kReuse, nullptr);
return;
}
// This will clone the sessionStorage for namespace_id_to_clone.
-
StoragePartition* storage_partition = BrowserContext::GetStoragePartition(
GetSiteInstance()->GetBrowserContext(), GetSiteInstance());
DOMStorageContextWrapper* dom_storage_context =
@@ -2790,7 +2893,6 @@ void RenderFrameHostImpl::CreateNewWindow(
storage_partition->GetDOMStorageContext());
auto cloned_namespace = base::MakeRefCounted<SessionStorageNamespaceImpl>(
dom_storage_context, params->session_storage_namespace_id);
- reply->cloned_session_storage_namespace_id = cloned_namespace->id();
// If the opener is suppressed or script access is disallowed, we should
// open the window in a new BrowsingInstance, and thus a new process. That
@@ -2831,28 +2933,43 @@ void RenderFrameHostImpl::CreateNewWindow(
main_frame_widget_route_id, *params,
cloned_namespace.get());
- // If we did not create a WebContents to host the renderer-created
- // RenderFrame/RenderView/RenderWidget objects, make sure to send invalid
- // routing ids back to the renderer.
- if (main_frame_route_id != MSG_ROUTING_NONE) {
- bool succeeded =
- RenderWidgetHost::FromID(render_process_id,
- main_frame_widget_route_id) != nullptr;
- if (!succeeded) {
- DCHECK(!RenderFrameHost::FromID(render_process_id, main_frame_route_id));
- DCHECK(!RenderViewHost::FromID(render_process_id, render_view_route_id));
- RunCreateWindowCompleteCallback(std::move(callback), std::move(reply),
- MSG_ROUTING_NONE, MSG_ROUTING_NONE,
- MSG_ROUTING_NONE, 0);
- return;
- }
- DCHECK(RenderFrameHost::FromID(render_process_id, main_frame_route_id));
- DCHECK(RenderViewHost::FromID(render_process_id, render_view_route_id));
+ if (main_frame_route_id == MSG_ROUTING_NONE) {
+ // Opener suppressed or Javascript access disabled. Never tell the renderer
+ // about the new window.
+ std::move(callback).Run(mojom::CreateNewWindowStatus::kIgnore, nullptr);
+ return;
+ }
+
+ bool succeeded =
+ RenderWidgetHost::FromID(render_process_id, main_frame_widget_route_id) !=
+ nullptr;
+ if (!succeeded) {
+ // If we did not create a WebContents to host the renderer-created
+ // RenderFrame/RenderView/RenderWidget objects, signal failure to the
+ // renderer.
+ DCHECK(!RenderFrameHost::FromID(render_process_id, main_frame_route_id));
+ DCHECK(!RenderViewHost::FromID(render_process_id, render_view_route_id));
+ std::move(callback).Run(mojom::CreateNewWindowStatus::kIgnore, nullptr);
+ return;
}
- RunCreateWindowCompleteCallback(
- std::move(callback), std::move(reply), render_view_route_id,
- main_frame_route_id, main_frame_widget_route_id, cloned_namespace->id());
+ // The view, widget, and frame should all be routable now.
+ DCHECK(RenderViewHost::FromID(render_process_id, render_view_route_id));
+ RenderFrameHostImpl* rfh =
+ RenderFrameHostImpl::FromID(GetProcess()->GetID(), main_frame_route_id);
+ DCHECK(rfh);
+
+ service_manager::mojom::InterfaceProviderPtrInfo
+ main_frame_interface_provider_info;
+ rfh->BindInterfaceProviderRequest(
+ mojo::MakeRequest(&main_frame_interface_provider_info));
+
+ mojom::CreateNewWindowReplyPtr reply = mojom::CreateNewWindowReply::New(
+ render_view_route_id, main_frame_route_id, main_frame_widget_route_id,
+ std::move(main_frame_interface_provider_info), cloned_namespace->id(),
+ rfh->GetDevToolsFrameToken());
+ std::move(callback).Run(mojom::CreateNewWindowStatus::kSuccess,
+ std::move(reply));
}
void RenderFrameHostImpl::IssueKeepAliveHandle(
@@ -2869,7 +2986,8 @@ void RenderFrameHostImpl::IssueKeepAliveHandle(
if (!keep_alive_handle_factory_) {
keep_alive_handle_factory_ =
- base::MakeUnique<KeepAliveHandleFactory>(GetProcess());
+ std::make_unique<KeepAliveHandleFactory>(GetProcess());
+ keep_alive_handle_factory_->SetTimeout(keep_alive_timeout_);
}
keep_alive_handle_factory_->Create(std::move(request));
}
@@ -2898,21 +3016,6 @@ void GetRestrictedCookieManager(
} // anonymous namespace
-void RenderFrameHostImpl::RunCreateWindowCompleteCallback(
- CreateNewWindowCallback callback,
- mojom::CreateNewWindowReplyPtr reply,
- int render_view_route_id,
- int main_frame_route_id,
- int main_frame_widget_route_id,
- int cloned_session_storage_namespace_id) {
- reply->route_id = render_view_route_id;
- reply->main_frame_route_id = main_frame_route_id;
- reply->main_frame_widget_route_id = main_frame_widget_route_id;
- reply->cloned_session_storage_namespace_id =
- cloned_session_storage_namespace_id;
- std::move(callback).Run(std::move(reply));
-}
-
void RenderFrameHostImpl::RegisterMojoInterfaces() {
#if !defined(OS_ANDROID)
// The default (no-op) implementation of InstalledAppProvider. On Android, the
@@ -2924,8 +3027,7 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
GetProcess()->GetBrowserContext()->GetPermissionManager();
if (delegate_) {
- device::GeolocationContext* geolocation_context =
- delegate_->GetGeolocationContext();
+ auto* geolocation_context = delegate_->GetGeolocationContext();
if (geolocation_context && permission_manager) {
geolocation_service_.reset(new GeolocationServiceImpl(
geolocation_context, permission_manager, this));
@@ -2967,7 +3069,7 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
// Creates a MojoRendererService, passing it a MediaPlayerRender.
registry_->AddInterface<media::mojom::Renderer>(
base::Bind(&content::CreateMediaPlayerRenderer, GetProcess()->GetID(),
- GetRoutingID()));
+ GetRoutingID(), delegate_));
#endif // defined(OS_ANDROID)
registry_->AddInterface(base::Bind(
@@ -2997,8 +3099,8 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
}
if (resource_coordinator::IsResourceCoordinatorEnabled()) {
- registry_->AddInterface(base::Bind(&CreateResourceCoordinatorFrameInterface,
- base::Unretained(this)));
+ registry_->AddInterface(
+ base::Bind(&CreateFrameResourceCoordinator, base::Unretained(this)));
}
#if BUILDFLAG(ENABLE_WEBRTC)
@@ -3013,7 +3115,6 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
registry_->AddInterface(
base::Bind(&MediaDevicesDispatcherHost::Create, GetProcess()->GetID(),
GetRoutingID(),
- GetProcess()->GetBrowserContext()->GetMediaDeviceIDSalt(),
base::Unretained(media_stream_manager)),
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
}
@@ -3029,23 +3130,13 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
registry_->AddInterface(base::Bind(&ImageCaptureImpl::Create));
- registry_->AddInterface(
- base::Bind(&ForwardRequest<shape_detection::mojom::BarcodeDetection>,
- shape_detection::mojom::kServiceName));
- registry_->AddInterface(
- base::Bind(&ForwardRequest<shape_detection::mojom::FaceDetectionProvider>,
- shape_detection::mojom::kServiceName));
- registry_->AddInterface(
- base::Bind(&ForwardRequest<shape_detection::mojom::TextDetection>,
- shape_detection::mojom::kServiceName));
-
- registry_->AddInterface(
- base::Bind(&CreatePaymentManager, base::Unretained(this)));
-
+#if !defined(OS_ANDROID)
if (base::FeatureList::IsEnabled(features::kWebAuth)) {
registry_->AddInterface(
- base::Bind(&AuthenticatorImpl::Create, base::Unretained(this)));
+ base::Bind(&RenderFrameHostImpl::BindAuthenticatorRequest,
+ base::Unretained(this)));
}
+#endif // !defined(OS_ANDROID)
if (permission_manager) {
sensor_provider_proxy_.reset(
@@ -3056,10 +3147,6 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
}
registry_->AddInterface(
- base::Bind(&ForwardRequest<device::mojom::VibrationManager>,
- device::mojom::kServiceName));
-
- registry_->AddInterface(
base::Bind(&media::WatchTimeRecorder::CreateWatchTimeRecorderProvider));
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -3068,10 +3155,16 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
base::Bind(&InputInjectorImpl::Create, weak_ptr_factory_.GetWeakPtr()));
}
- registry_->AddInterface(base::Bind(&media::VideoDecodeStatsRecorder::Create));
-
registry_->AddInterface(
base::BindRepeating(GetRestrictedCookieManager, base::Unretained(this)));
+
+ // Only save decode stats when on-the-record.
+ if (!GetSiteInstance()->GetBrowserContext()->IsOffTheRecord()) {
+ media::VideoDecodePerfHistory* video_perf_history =
+ GetSiteInstance()->GetBrowserContext()->GetVideoDecodePerfHistory();
+ registry_->AddInterface(base::BindRepeating(
+ &media::VideoDecodeStatsRecorder::Create, video_perf_history));
+ }
}
void RenderFrameHostImpl::ResetWaitingState() {
@@ -3112,7 +3205,8 @@ bool RenderFrameHostImpl::CanCommitOrigin(
return true;
// Standard URLs must match the reported origin.
- if (url.IsStandard() && !origin.IsSamePhysicalOriginWith(url::Origin(url)))
+ if (url.IsStandard() &&
+ !origin.IsSamePhysicalOriginWith(url::Origin::Create(url)))
return false;
// A non-unique origin must be a valid URL, which allows us to safely do a
@@ -3177,11 +3271,12 @@ void RenderFrameHostImpl::NavigateToInterstitialURL(const GURL& data_url) {
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 /* started_from_context_menu */, false /* has_user_gesture */);
if (IsBrowserSideNavigationEnabled()) {
CommitNavigation(nullptr, nullptr, mojo::ScopedDataPipeConsumerHandle(),
common_params, RequestNavigationParams(), false,
- mojom::URLLoaderFactoryPtrInfo());
+ base::nullopt,
+ base::UnguessableToken::Create() /* not traced */);
} else {
Navigate(common_params, StartNavigationParams(), RequestNavigationParams());
}
@@ -3332,7 +3427,8 @@ void RenderFrameHostImpl::CommitNavigation(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
bool is_view_source,
- mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_info) {
+ base::Optional<SubresourceLoaderParams> subresource_loader_params,
+ const base::UnguessableToken& devtools_navigation_token) {
TRACE_EVENT2("navigation", "RenderFrameHostImpl::CommitNavigation",
"frame_tree_node", frame_tree_node_->frame_tree_node_id(), "url",
common_params.url.possibly_invalid_spec());
@@ -3343,15 +3439,19 @@ void RenderFrameHostImpl::CommitNavigation(
FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type) ||
IsRendererDebugURL(common_params.url));
+ const bool is_first_navigation = !has_committed_any_navigation_;
+ has_committed_any_navigation_ = true;
+
// TODO(arthursonzogni): Consider using separate methods and IPCs for
// javascript-url navigation. Excluding this case from the general one will
// prevent us from doing inappropriate things with javascript-url.
// See https://crbug.com/766149.
if (common_params.url.SchemeIs(url::kJavaScriptScheme)) {
- Send(new FrameMsg_CommitNavigation(
- routing_id_, ResourceResponseHead(), GURL(),
- FrameMsg_CommitDataNetworkService_Params(), common_params,
- request_params));
+ GetNavigationControl()->CommitNavigation(
+ ResourceResponseHead(), GURL(), common_params, request_params,
+ mojo::ScopedDataPipeConsumerHandle(),
+ /*subresource_loader_factories=*/base::nullopt,
+ devtools_navigation_token);
return;
}
@@ -3371,26 +3471,108 @@ void RenderFrameHostImpl::CommitNavigation(
const GURL body_url = body.get() ? body->GetURL() : GURL();
const ResourceResponseHead head = response ?
response->head : ResourceResponseHead();
- FrameMsg_CommitDataNetworkService_Params commit_data;
- commit_data.handle = handle.release();
+ const bool is_same_document =
+ FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type);
+
// TODO(scottmg): Pass a factory for SW, etc. once we have one.
- if (base::FeatureList::IsEnabled(features::kNetworkService)) {
- if (!subresource_url_loader_factory_info.is_valid()) {
+ base::Optional<URLLoaderFactoryBundle> subresource_loader_factories;
+ if (base::FeatureList::IsEnabled(features::kNetworkService) &&
+ (!is_same_document || is_first_navigation)) {
+ subresource_loader_factories.emplace();
+ // NOTE: On Network Service navigations, we want to ensure that a frame is
+ // given everything it will need to load any accessible subresources. We
+ // however only do this for cross-document navigations, because the
+ // alternative would be redundant effort.
+ mojom::URLLoaderFactoryPtr default_factory;
+ StoragePartitionImpl* storage_partition =
+ static_cast<StoragePartitionImpl*>(BrowserContext::GetStoragePartition(
+ GetSiteInstance()->GetBrowserContext(), GetSiteInstance()));
+ if (subresource_loader_params &&
+ subresource_loader_params->loader_factory_info.is_valid()) {
+ // If the caller has supplied a default URLLoaderFactory override (for
+ // e.g. appcache, Service Worker, etc.), use that.
+ default_factory.Bind(
+ std::move(subresource_loader_params->loader_factory_info));
+ } else {
+ std::string scheme = common_params.url.scheme();
const auto& schemes = URLDataManagerBackend::GetWebUISchemes();
- if (std::find(schemes.begin(), schemes.end(),
- common_params.url.scheme()) != schemes.end()) {
- commit_data.url_loader_factory = CreateWebUIURLLoader(frame_tree_node_)
- .PassInterface()
- .PassHandle()
- .release();
+ if (std::find(schemes.begin(), schemes.end(), scheme) != schemes.end()) {
+ mojom::URLLoaderFactoryPtr factory_for_webui =
+ CreateWebUIURLLoader(this, scheme);
+ if (enabled_bindings_ & BINDINGS_POLICY_WEB_UI) {
+ // If the renderer has webui bindings, then don't give it access to
+ // network loader for security reasons.
+ default_factory = std::move(factory_for_webui);
+ } 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->RegisterFactory(
+ scheme, std::move(factory_for_webui));
+ }
}
- } else {
- commit_data.url_loader_factory =
- subresource_url_loader_factory_info.PassHandle().release();
+ }
+
+ if (!default_factory.is_bound()) {
+ // Otherwise default to a Network Service-backed loader from the
+ // appropriate NetworkContext.
+ if (g_url_loader_factory_callback_for_test.Get().is_null()) {
+ storage_partition->GetNetworkContext()->CreateURLLoaderFactory(
+ mojo::MakeRequest(&default_factory), GetProcess()->GetID());
+ } else {
+ mojom::URLLoaderFactoryPtr original_factory;
+ storage_partition->GetNetworkContext()->CreateURLLoaderFactory(
+ mojo::MakeRequest(&original_factory), GetProcess()->GetID());
+ g_url_loader_factory_callback_for_test.Get().Run(
+ mojo::MakeRequest(&default_factory), GetProcess()->GetID(),
+ original_factory.PassInterface());
+ }
+ }
+
+ DCHECK(default_factory.is_bound());
+ subresource_loader_factories->SetDefaultFactory(std::move(default_factory));
+
+ // Everyone gets a blob loader.
+ mojom::URLLoaderFactoryPtr blob_factory;
+ storage_partition->GetBlobURLLoaderFactory()->HandleRequest(
+ mojo::MakeRequest(&blob_factory));
+ subresource_loader_factories->RegisterFactory(url::kBlobScheme,
+ std::move(blob_factory));
+
+ non_network_url_loader_factories_.clear();
+
+ if (common_params.url.SchemeIsFile()) {
+ // Only file resources can load file subresources
+ auto file_factory = std::make_unique<FileURLLoaderFactory>(
+ GetProcess()->GetBrowserContext()->GetPath(),
+ base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}));
+ non_network_url_loader_factories_.emplace(url::kFileScheme,
+ std::move(file_factory));
+ }
+
+ GetContentClient()
+ ->browser()
+ ->RegisterNonNetworkSubresourceURLLoaderFactories(
+ this, common_params.url, &non_network_url_loader_factories_);
+
+ for (auto& factory : non_network_url_loader_factories_) {
+ mojom::URLLoaderFactoryPtr factory_proxy;
+ factory.second->Clone(mojo::MakeRequest(&factory_proxy));
+ subresource_loader_factories->RegisterFactory(factory.first,
+ std::move(factory_proxy));
}
}
- Send(new FrameMsg_CommitNavigation(routing_id_, head, body_url, commit_data,
- common_params, request_params));
+
+ // It is imperative that cross-document navigations always provide a set of
+ // subresource ULFs when the Network Service is enabled.
+ DCHECK(!base::FeatureList::IsEnabled(features::kNetworkService) ||
+ is_same_document || !is_first_navigation ||
+ subresource_loader_factories.has_value());
+
+ GetNavigationControl()->CommitNavigation(
+ head, body_url, common_params, request_params, std::move(handle),
+ std::move(subresource_loader_factories), devtools_navigation_token);
// If a network request was made, update the Previews state.
if (IsURLHandledByNetworkStack(common_params.url) &&
@@ -3404,19 +3586,13 @@ void RenderFrameHostImpl::CommitNavigation(
// same-document navigation would not load any new ones for replacement.
// The user would finish with a half loaded document.
// See https://crbug.com/769645.
- if (!FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type)) {
+ if (!is_same_document) {
// Released in OnStreamHandleConsumed().
stream_handle_ = std::move(body);
}
- // When navigating to a debug url, no commit is expected from the
- // RenderFrameHost, nor should the throbber start. The NavigationRequest is
- // also not stored in the FrameTreeNode. Therefore do not reset it, as this
- // could cancel an existing pending navigation.
- if (!IsRendererDebugURL(common_params.url)) {
- pending_commit_ = true;
- is_loading_ = true;
- }
+ pending_commit_ = true;
+ is_loading_ = true;
}
void RenderFrameHostImpl::FailedNavigation(
@@ -3424,7 +3600,8 @@ void RenderFrameHostImpl::FailedNavigation(
const BeginNavigationParams& begin_params,
const RequestNavigationParams& request_params,
bool has_stale_copy_in_cache,
- int error_code) {
+ int error_code,
+ const base::Optional<std::string>& error_page_content) {
TRACE_EVENT2("navigation", "RenderFrameHostImpl::FailedNavigation",
"frame_tree_node", frame_tree_node_->frame_tree_node_id(),
"error", error_code);
@@ -3438,10 +3615,8 @@ void RenderFrameHostImpl::FailedNavigation(
ResetWaitingState();
Send(new FrameMsg_FailedNavigation(routing_id_, common_params, request_params,
- has_stale_copy_in_cache, error_code));
-
- RenderFrameDevToolsAgentHost::OnFailedNavigation(
- this, common_params, begin_params, static_cast<net::Error>(error_code));
+ has_stale_copy_in_cache, error_code,
+ error_page_content));
// An error page is expected to commit, hence why is_loading_ is set to true.
is_loading_ = true;
@@ -3454,24 +3629,20 @@ void RenderFrameHostImpl::SetUpMojoIfNeeded() {
if (registry_.get())
return;
- associated_registry_ = base::MakeUnique<AssociatedInterfaceRegistryImpl>();
- registry_ = base::MakeUnique<service_manager::BinderRegistry>();
+ associated_registry_ = std::make_unique<AssociatedInterfaceRegistryImpl>();
+ registry_ = std::make_unique<service_manager::BinderRegistry>();
auto make_binding = [](RenderFrameHostImpl* impl,
mojom::FrameHostAssociatedRequest request) {
impl->frame_host_associated_binding_.Bind(std::move(request));
};
- static_cast<AssociatedInterfaceRegistry*>(associated_registry_.get())
+ static_cast<blink::AssociatedInterfaceRegistry*>(associated_registry_.get())
->AddInterface(base::Bind(make_binding, base::Unretained(this)));
RegisterMojoInterfaces();
mojom::FrameFactoryPtr frame_factory;
BindInterface(GetProcess(), &frame_factory);
-
- mojom::FrameHostInterfaceBrokerPtr broker_proxy;
- frame_host_interface_broker_binding_.Bind(mojo::MakeRequest(&broker_proxy));
- frame_factory->CreateFrame(routing_id_, MakeRequest(&frame_),
- std::move(broker_proxy));
+ frame_factory->CreateFrame(routing_id_, MakeRequest(&frame_));
service_manager::mojom::InterfaceProviderPtr remote_interfaces;
frame_->GetInterfaceProvider(mojo::MakeRequest(&remote_interfaces));
@@ -3489,8 +3660,9 @@ void RenderFrameHostImpl::InvalidateMojoConnection() {
registry_.reset();
frame_.reset();
- frame_host_interface_broker_binding_.Close();
frame_bindings_control_.reset();
+ frame_host_associated_binding_.Close();
+ navigation_control_.reset();
// Disconnect with ImageDownloader Mojo service in RenderFrame.
mojo_image_downloader_.reset();
@@ -3608,24 +3780,23 @@ RenderFrameHostImpl::GetMojoImageDownloader() {
return mojo_image_downloader_;
}
-resource_coordinator::ResourceCoordinatorInterface*
+resource_coordinator::FrameResourceCoordinator*
RenderFrameHostImpl::GetFrameResourceCoordinator() {
if (frame_resource_coordinator_)
return frame_resource_coordinator_.get();
if (!resource_coordinator::IsResourceCoordinatorEnabled()) {
frame_resource_coordinator_ =
- base::MakeUnique<resource_coordinator::ResourceCoordinatorInterface>(
- nullptr, resource_coordinator::CoordinationUnitType::kFrame);
+ std::make_unique<resource_coordinator::FrameResourceCoordinator>(
+ nullptr);
} else {
auto* connection = ServiceManagerConnection::GetForProcess();
frame_resource_coordinator_ =
- base::MakeUnique<resource_coordinator::ResourceCoordinatorInterface>(
- connection ? connection->GetConnector() : nullptr,
- resource_coordinator::CoordinationUnitType::kFrame);
+ std::make_unique<resource_coordinator::FrameResourceCoordinator>(
+ connection ? connection->GetConnector() : nullptr);
}
if (parent_) {
- parent_->GetFrameResourceCoordinator()->AddChild(
+ parent_->GetFrameResourceCoordinator()->AddChildFrame(
*frame_resource_coordinator_);
}
return frame_resource_coordinator_.get();
@@ -3653,6 +3824,10 @@ void RenderFrameHostImpl::ClearFocusedElement() {
}
bool RenderFrameHostImpl::CanCommitURL(const GURL& url) {
+ // Renderer-debug URLs can never be committed.
+ if (IsRendererDebugURL(url))
+ return false;
+
// TODO(creis): We should also check for WebUI pages here. Also, when the
// out-of-process iframes implementation is ready, we should check for
// cross-site URLs that are not allowed to commit in this process.
@@ -3800,17 +3975,6 @@ bool RenderFrameHostImpl::HasSelection() {
return has_selection_;
}
-void RenderFrameHostImpl::GetInterfaceProvider(
- service_manager::mojom::InterfaceProviderRequest interfaces) {
- service_manager::Identity child_identity = GetProcess()->GetChildIdentity();
- service_manager::Connector* connector =
- BrowserContext::GetConnectorFor(GetProcess()->GetBrowserContext());
- service_manager::mojom::InterfaceProviderPtr provider;
- interface_provider_bindings_.AddBinding(this, mojo::MakeRequest(&provider));
- connector->FilterInterfaces(mojom::kNavigation_FrameSpec, child_identity,
- std::move(interfaces), std::move(provider));
-}
-
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
#if defined(OS_MACOSX)
@@ -4062,7 +4226,7 @@ WebBluetoothServiceImpl* RenderFrameHostImpl::CreateWebBluetoothService(
// |binding_| which may run the error handler. |binding_| can't run the error
// handler after it's destroyed so it can't run after the RFHI is destroyed.
auto web_bluetooth_service =
- base::MakeUnique<WebBluetoothServiceImpl>(this, std::move(request));
+ std::make_unique<WebBluetoothServiceImpl>(this, std::move(request));
web_bluetooth_service->SetClientConnectionErrorHandler(
base::Bind(&RenderFrameHostImpl::DeleteWebBluetoothService,
base::Unretained(this), web_bluetooth_service.get()));
@@ -4084,11 +4248,11 @@ void RenderFrameHostImpl::DeleteWebBluetoothService(
void RenderFrameHostImpl::ResetFeaturePolicy() {
RenderFrameHostImpl* parent_frame_host = GetParent();
- const FeaturePolicy* parent_policy =
+ const blink::FeaturePolicy* parent_policy =
parent_frame_host ? parent_frame_host->feature_policy() : nullptr;
- ParsedFeaturePolicyHeader container_policy =
- frame_tree_node()->effective_container_policy();
- feature_policy_ = FeaturePolicy::CreateFromParentPolicy(
+ blink::ParsedFeaturePolicy container_policy =
+ frame_tree_node()->effective_frame_policy().container_policy;
+ feature_policy_ = blink::FeaturePolicy::CreateFromParentPolicy(
parent_policy, container_policy, last_committed_origin_);
}
@@ -4139,13 +4303,24 @@ void RenderFrameHostImpl::BindPresentationServiceRequest(
presentation_service_->Bind(std::move(request));
}
+#if !defined(OS_ANDROID)
+void RenderFrameHostImpl::BindAuthenticatorRequest(
+ webauth::mojom::AuthenticatorRequest request) {
+ if (!authenticator_impl_)
+ authenticator_impl_.reset(new AuthenticatorImpl(this));
+
+ authenticator_impl_->Bind(std::move(request));
+}
+#endif
+
void RenderFrameHostImpl::GetInterface(
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
if (!registry_ ||
!registry_->TryBindInterface(interface_name, &interface_pipe)) {
delegate_->OnInterfaceRequest(this, interface_name, &interface_pipe);
- if (interface_pipe->is_valid()) {
+ if (interface_pipe->is_valid() &&
+ !TryBindFrameInterface(interface_name, &interface_pipe, this)) {
GetContentClient()->browser()->BindInterfaceRequestFromFrame(
this, interface_name, std::move(interface_pipe));
}
@@ -4326,7 +4501,7 @@ RenderFrameHostImpl::GetJavaRenderFrameHost() {
GetUserData(kRenderFrameHostAndroidKey));
if (!render_frame_host_android) {
service_manager::mojom::InterfaceProviderPtr interface_provider_ptr;
- java_interface_registry_ = base::MakeUnique<JavaInterfaceProvider>(
+ java_interface_registry_ = std::make_unique<JavaInterfaceProvider>(
base::Bind(&RenderFrameHostImpl::ForwardGetInterfaceToRenderFrame,
weak_ptr_factory_.GetWeakPtr()),
mojo::MakeRequest(&interface_provider_ptr));
@@ -4384,4 +4559,10 @@ void RenderFrameHostImpl::SetVisibilityForChildViews(bool visible) {
visible));
}
+mojom::FrameNavigationControl* RenderFrameHostImpl::GetNavigationControl() {
+ if (!navigation_control_)
+ GetRemoteAssociatedInterfaces()->GetInterface(&navigation_control_);
+ return navigation_control_.get();
+}
+
} // namespace content
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 ec9ec442469..7c242dc8762 100644
--- a/chromium/content/browser/frame_host/render_frame_host_impl.h
+++ b/chromium/content/browser/frame_host/render_frame_host_impl.h
@@ -42,22 +42,24 @@
#include "content/common/frame_replication_state.h"
#include "content/common/image_downloader/image_downloader.mojom.h"
#include "content/common/input/input_handler.mojom.h"
-#include "content/common/navigation_params.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/javascript_dialog_type.h"
#include "content/public/common/previews_state.h"
-#include "content/public/common/url_loader_factory.mojom.h"
#include "media/mojo/interfaces/interface_factory.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/http/http_response_headers.h"
#include "services/device/public/interfaces/wake_lock_context.mojom.h"
#include "services/service_manager/public/cpp/binder_registry.h"
+#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
#include "third_party/WebKit/public/platform/WebFocusType.h"
#include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h"
#include "third_party/WebKit/public/platform/WebSuddenTerminationDisablerType.h"
#include "third_party/WebKit/public/platform/modules/bluetooth/web_bluetooth.mojom.h"
#include "third_party/WebKit/public/platform/modules/presentation/presentation.mojom.h"
+#include "third_party/WebKit/public/platform/modules/webauth/authenticator.mojom.h"
#include "third_party/WebKit/public/web/WebTextDirection.h"
#include "third_party/WebKit/public/web/WebTreeScopeType.h"
#include "ui/accessibility/ax_modes.h"
@@ -85,15 +87,21 @@ namespace base {
class ListValue;
}
+namespace blink {
+struct FramePolicy;
+struct WebRemoteScrollProperties;
+}
+
namespace gfx {
class Range;
+class Rect;
}
namespace content {
class AssociatedInterfaceProviderImpl;
class AssociatedInterfaceRegistryImpl;
+class AuthenticatorImpl;
class LegacyIPCFrameInputHandler;
-class FeaturePolicy;
class FrameTree;
class FrameTreeNode;
class GeolocationServiceImpl;
@@ -115,17 +123,22 @@ class SensorProviderProxyImpl;
class StreamHandle;
class TimeoutMonitor;
class WebBluetoothServiceImpl;
+struct BeginNavigationParams;
+struct CommonNavigationParams;
struct ContextMenuParams;
struct FileChooserParams;
struct FrameOwnerProperties;
struct FileChooserParams;
+struct NavigationParams;
+struct RequestNavigationParams;
struct ResourceResponse;
+struct SubresourceLoaderParams;
+struct StartNavigationParams;
class CONTENT_EXPORT RenderFrameHostImpl
: public RenderFrameHost,
public base::SupportsUserData,
public mojom::FrameHost,
- public mojom::FrameHostInterfaceBroker,
public BrowserAccessibilityDelegate,
public SiteInstanceImpl::Observer,
public service_manager::mojom::InterfaceProvider,
@@ -148,6 +161,15 @@ class CONTENT_EXPORT RenderFrameHostImpl
static RenderFrameHostImpl* FromOverlayRoutingToken(
const base::UnguessableToken& token);
+ // Allows overriding the URLLoaderFactory creation for subresources.
+ // Passing a null callback will restore the default behavior.
+ using CreateNetworkFactoryCallback =
+ base::Callback<void(mojom::URLLoaderFactoryRequest request,
+ int process_id,
+ mojom::URLLoaderFactoryPtrInfo original_factory)>;
+ static void SetNetworkFactoryForTesting(
+ const CreateNetworkFactoryCallback& url_loader_factory_callback);
+
~RenderFrameHostImpl() override;
// RenderFrameHost
@@ -185,8 +207,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
void SaveImageAt(int x, int y) override;
RenderViewHost* GetRenderViewHost() override;
service_manager::InterfaceProvider* GetRemoteInterfaces() override;
- AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override;
- blink::WebPageVisibilityState GetVisibilityState() override;
+ blink::AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override;
+ blink::mojom::PageVisibilityState GetVisibilityState() override;
bool IsRenderFrameLive() override;
bool IsCurrent() override;
int GetProxyCount() override;
@@ -204,12 +226,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
bool IsBeforeUnloadHangMonitorDisabledForTesting() override;
bool GetSuddenTerminationDisablerState(
blink::WebSuddenTerminationDisablerType disabler_type) override;
-
- bool IsFeatureEnabled(blink::WebFeaturePolicyFeature feature) override;
-
- // mojom::FrameHostInterfaceBroker
- void GetInterfaceProvider(
- service_manager::mojom::InterfaceProviderRequest interfaces) override;
+ bool IsFeatureEnabled(blink::FeaturePolicyFeature feature) override;
+ void ViewSource() override;
// IPC::Sender
bool Send(IPC::Message* msg) override;
@@ -271,24 +289,31 @@ class CONTENT_EXPORT RenderFrameHostImpl
// that was partially handled on the IO thread (to allocate |new_routing_id|
// and |devtools_frame_token|), and is forwarded here. The renderer has
// already been told to create a RenderFrame with the specified ID values.
+ // |interface_provider_request| is the request end of the InterfaceProvider
+ // interface that the RenderFrameHost corresponding to the child frame should
+ // bind to expose services to the renderer process. The caller takes care of
+ // sending down the client end of the pipe to the child RenderFrame to use.
void OnCreateChildFrame(int new_routing_id,
+ service_manager::mojom::InterfaceProviderRequest
+ interface_provider_request,
blink::WebTreeScopeType scope,
const std::string& frame_name,
const std::string& frame_unique_name,
+ bool is_created_by_script,
const base::UnguessableToken& devtools_frame_token,
- blink::WebSandboxFlags sandbox_flags,
- const ParsedFeaturePolicyHeader& container_policy,
+ const blink::FramePolicy& frame_policy,
const FrameOwnerProperties& frame_owner_properties);
- // Update this frame's last committed origin.
- void SetLastCommittedOrigin(const url::Origin& origin);
+ // Update this frame's state at the appropriate time when a navigation
+ // commits. This is called by NavigatorImpl::DidNavigate as a helper, in the
+ // midst of a DidCommitProvisionalLoad call.
+ void DidNavigate(const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
+ bool is_same_document_navigation);
RenderViewHostImpl* render_view_host() { return render_view_host_; }
RenderFrameHostDelegate* delegate() { return delegate_; }
FrameTreeNode* frame_tree_node() { return frame_tree_node_; }
- const GURL& last_committed_url() const { return last_committed_url_; }
-
// 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.
@@ -297,9 +322,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
// The most recent non-net-error URL to commit in this frame. In almost all
// cases, use GetLastCommittedURL instead.
const GURL& last_successful_url() { return last_successful_url_; }
- void set_last_successful_url(const GURL& url) {
- last_successful_url_ = url;
- }
+
+ // Fetch the link-rel canonical URL to be used for sharing to external
+ // applications.
+ void GetCanonicalUrlForSharing(
+ mojom::Frame::GetCanonicalUrlForSharingCallback callback);
// Returns the associated WebUI or null if none applies.
WebUIImpl* web_ui() const { return web_ui_.get(); }
@@ -337,7 +364,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
// This method crashes if this RenderFrameHostImpl does not own a
// a RenderWidgetHost and nor does any of its ancestors. That would
// typically mean that the frame has been detached from the frame tree.
- RenderWidgetHostImpl* GetRenderWidgetHost();
+ virtual RenderWidgetHostImpl* GetRenderWidgetHost();
GlobalFrameRoutingId GetGlobalFrameRoutingId();
@@ -540,9 +567,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
// PlzNavigate: Indicates that a navigation is ready to commit and can be
// handled by this RenderFrame.
- // |subresource_url_loader_factory_info| is used in network service land to
- // allow factories interested in handling subresource requests to the
- // renderer. E.g. AppCache.
+ // |subresource_loader_params| is used in network service land to pass
+ // the parameters to create a custom subresource loader in the renderer
+ // process, e.g. by AppCache etc.
void CommitNavigation(
ResourceResponse* response,
std::unique_ptr<StreamHandle> body,
@@ -550,7 +577,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
bool is_view_source,
- mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_info);
+ base::Optional<SubresourceLoaderParams> subresource_loader_params,
+ const base::UnguessableToken& devtools_navigation_token);
// PlzNavigate
// Indicates that a navigation failed and that this RenderFrame should display
@@ -559,7 +587,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
const BeginNavigationParams& begin_params,
const RequestNavigationParams& request_params,
bool has_stale_copy_in_cache,
- int error_code);
+ int error_code,
+ const base::Optional<std::string>& error_page_content);
// Sets up the Mojo connection between this instance and its associated render
// frame if it has not yet been set up.
@@ -597,19 +626,15 @@ class CONTENT_EXPORT RenderFrameHostImpl
// Returns the Mojo ImageDownloader service.
const content::mojom::ImageDownloaderPtr& GetMojoImageDownloader();
- resource_coordinator::ResourceCoordinatorInterface*
- GetFrameResourceCoordinator() override;
+ resource_coordinator::FrameResourceCoordinator* GetFrameResourceCoordinator()
+ override;
// Resets the loading state. Following this call, the RenderFrameHost will be
// in a non-loading state.
void ResetLoadingState();
// Returns the feature policy which should be enforced on this RenderFrame.
- FeaturePolicy* feature_policy() { return feature_policy_.get(); }
-
- // Clears any existing policy and constructs a new policy for this frame,
- // based on its parent frame.
- void ResetFeaturePolicy();
+ blink::FeaturePolicy* feature_policy() { return feature_policy_.get(); }
// Tells the renderer that this RenderFrame will soon be swapped out, and thus
// not to create any new modal dialogs until it happens. This must be done
@@ -656,6 +681,14 @@ class CONTENT_EXPORT RenderFrameHostImpl
// sending a mojo overlay factory.
const base::UnguessableToken& GetOverlayRoutingToken();
+ // Binds the request end of the InterfaceProvider interface through which
+ // services provided by this RenderFrameHost are exposed to the correponding
+ // RenderFrame. The caller is responsible for plumbing the client end to the
+ // the renderer process.
+ void BindInterfaceProviderRequest(
+ service_manager::mojom::InterfaceProviderRequest
+ interface_provider_request);
+
const StreamHandle* stream_handle_for_testing() const {
return stream_handle_.get();
}
@@ -665,6 +698,12 @@ class CONTENT_EXPORT RenderFrameHostImpl
return frame_host_associated_binding_;
}
+ void SetKeepAliveTimeoutForTesting(base::TimeDelta timeout);
+
+ blink::WebSandboxFlags active_sandbox_flags() {
+ return active_sandbox_flags_;
+ }
+
protected:
friend class RenderFrameHostFactory;
@@ -710,6 +749,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
LoadEventForwardingWhilePendingDeletion);
FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
ContextMenuAfterCrossProcessNavigation);
+ FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
+ ActiveSandboxFlagsRetainedAfterSwapOut);
FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest,
AttemptDuplicateRenderViewHost);
@@ -759,8 +800,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnDidAccessInitialDocument();
void OnDidChangeOpener(int32_t opener_routing_id);
void OnDidChangeName(const std::string& name, const std::string& unique_name);
- void OnDidSetFeaturePolicyHeader(
- const ParsedFeaturePolicyHeader& parsed_header);
+ void OnDidSetFramePolicyHeaders(
+ blink::WebSandboxFlags sandbox_flags,
+ const blink::ParsedFeaturePolicy& parsed_header);
// A new set of CSP |policies| has been added to the document.
void OnDidAddContentSecurityPolicies(
@@ -768,10 +810,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnEnforceInsecureRequestPolicy(blink::WebInsecureRequestPolicy policy);
void OnUpdateToUniqueOrigin(bool is_potentially_trustworthy_unique_origin);
- void OnDidChangeFramePolicy(
- int32_t frame_routing_id,
- blink::WebSandboxFlags flags,
- const ParsedFeaturePolicyHeader& container_policy);
+ void OnDidChangeFramePolicy(int32_t frame_routing_id,
+ const blink::FramePolicy& frame_policy);
void OnDidChangeFrameOwnerProperties(int32_t frame_routing_id,
const FrameOwnerProperties& properties);
void OnUpdateTitle(const base::string16& title,
@@ -790,9 +830,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
const std::vector<AccessibilityHostMsg_LocationChangeParams>& params);
void OnAccessibilityFindInPageResult(
const AccessibilityHostMsg_FindInPageResultParams& params);
- void OnAccessibilityChildFrameHitTestResult(const gfx::Point& point,
- int hit_obj_id,
- ui::AXEvent event_to_fire);
+ void OnAccessibilityChildFrameHitTestResult(
+ const gfx::Point& point,
+ int child_frame_routing_id,
+ int child_frame_browser_plugin_instance_id,
+ ui::AXEvent event_to_fire);
void OnAccessibilitySnapshotResponse(
int callback_id,
const AXContentTreeUpdate& snapshot);
@@ -817,6 +859,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnFocusedNodeChanged(bool is_editable_element,
const gfx::Rect& bounds_in_frame_widget);
void OnSetHasReceivedUserGesture();
+ void OnScrollRectToVisibleInParentFrame(
+ const gfx::Rect& rect_to_scroll,
+ const blink::WebRemoteScrollProperties& properties);
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
void OnShowPopup(const FrameHostMsg_ShowPopup_Params& params);
@@ -836,7 +881,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
const gfx::Rect& initial_rect,
bool user_gesture);
- // mojom::FrameHost
+ // mojom::FrameHost:
void CreateNewWindow(mojom::CreateNewWindowParamsPtr params,
CreateNewWindowCallback callback) override;
void IssueKeepAliveHandle(mojom::KeepAliveHandleRequest request) override;
@@ -844,13 +889,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
validated_params) override;
- void RunCreateWindowCompleteCallback(CreateNewWindowCallback callback,
- mojom::CreateNewWindowReplyPtr reply,
- int render_view_route_id,
- int main_frame_route_id,
- int main_frame_widget_route_id,
- int cloned_session_storage_namespace_id);
-
// Registers Mojo interfaces that this frame host makes available.
void RegisterMojoInterfaces();
@@ -957,6 +995,10 @@ class CONTENT_EXPORT RenderFrameHostImpl
void BindPresentationServiceRequest(
blink::mojom::PresentationServiceRequest request);
+#if !defined(OS_ANDROID)
+ void BindAuthenticatorRequest(webauth::mojom::AuthenticatorRequest request);
+#endif
+
// service_manager::mojom::InterfaceProvider:
void GetInterface(const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override;
@@ -977,11 +1019,18 @@ class CONTENT_EXPORT RenderFrameHostImpl
// Called by |beforeunload_timeout_| when the beforeunload timeout fires.
void BeforeUnloadTimeout();
+ // Update this frame's last committed origin.
+ void SetLastCommittedOrigin(const url::Origin& origin);
+
// Called when a navigation commits succesfully to |url|. This will update
// |last_committed_site_url_| if it's not equal to the site url corresponding
// to |url|.
void SetLastCommittedSiteUrl(const GURL& url);
+ // Clears any existing policy and constructs a new policy for this frame,
+ // based on its parent frame.
+ void ResetFeaturePolicy();
+
// PlzNavigate: Called when the frame has consumed the StreamHandle and it
// can be released.
void OnStreamHandleConsumed(const GURL& stream_url);
@@ -1008,6 +1057,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
void ForEachImmediateLocalRoot(
const base::Callback<void(RenderFrameHostImpl*)>& callback);
+ // Lazily initializes and returns the mojom::FrameNavigationControl interface
+ // for this frame. May be overridden by friend subclasses for e.g. tests which
+ // wish to intercept outgoing navigation control messages.
+ virtual mojom::FrameNavigationControl* GetNavigationControl();
+
// 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
@@ -1172,6 +1226,10 @@ class CONTENT_EXPORT RenderFrameHostImpl
// The last AXContentTreeData for this frame received from the RenderFrame.
AXContentTreeData ax_content_tree_data_;
+ // The AX tree ID of this frame.
+ ui::AXTreeIDRegistry::AXTreeID ax_tree_id_ =
+ ui::AXTreeIDRegistry::kNoAXTreeID;
+
// The AX tree ID of the embedder, if this is a browser plugin guest.
ui::AXTreeIDRegistry::AXTreeID browser_plugin_embedder_ax_tree_id_;
@@ -1203,7 +1261,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
content::mojom::ImageDownloaderPtr mojo_image_downloader_;
// Holds the interface wrapper to the Global Resource Coordinator service.
- std::unique_ptr<resource_coordinator::ResourceCoordinatorInterface>
+ std::unique_ptr<resource_coordinator::FrameResourceCoordinator>
frame_resource_coordinator_;
// Tracks a navigation happening in this frame. Note that while there can be
@@ -1242,11 +1300,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
// same Previews status as the top-level frame.
PreviewsState last_navigation_previews_state_;
- mojo::Binding<mojom::FrameHostInterfaceBroker>
- frame_host_interface_broker_binding_;
+ bool has_committed_any_navigation_ = false;
mojo::AssociatedBinding<mojom::FrameHost> frame_host_associated_binding_;
mojom::FramePtr frame_;
mojom::FrameBindingsControlAssociatedPtr frame_bindings_control_;
+ mojom::FrameNavigationControlAssociatedPtr navigation_control_;
// If this is true then this object was created in response to a renderer
// initiated request. Init() will be called, and until then navigation
@@ -1258,7 +1316,13 @@ class CONTENT_EXPORT RenderFrameHostImpl
typedef std::pair<CommonNavigationParams, BeginNavigationParams>
PendingNavigation;
- std::unique_ptr<PendingNavigation> pendinging_navigate_;
+ std::unique_ptr<PendingNavigation> pending_navigate_;
+
+ // A collection of non-network URLLoaderFactory implementations which are used
+ // to service any supported non-network subresource requests for the currently
+ // committed navigation.
+ ContentBrowserClient::NonNetworkURLLoaderFactoryMap
+ non_network_url_loader_factories_;
// Bitfield for renderer-side state that blocks fast shutdown of the frame.
blink::WebSuddenTerminationDisablerType
@@ -1277,6 +1341,10 @@ class CONTENT_EXPORT RenderFrameHostImpl
// Hosts blink::mojom::PresentationService for the RenderFrame.
std::unique_ptr<PresentationServiceImpl> presentation_service_;
+#if !defined(OS_ANDROID)
+ std::unique_ptr<AuthenticatorImpl> authenticator_impl_;
+#endif
+
std::unique_ptr<AssociatedInterfaceProviderImpl>
remote_associated_interfaces_;
@@ -1285,7 +1353,15 @@ class CONTENT_EXPORT RenderFrameHostImpl
int enabled_bindings_ = 0;
// Tracks the feature policy which has been set on this frame.
- std::unique_ptr<FeaturePolicy> feature_policy_;
+ std::unique_ptr<blink::FeaturePolicy> feature_policy_;
+
+ // Tracks the sandbox flags which are in effect on this frame. This includes
+ // any flags which have been set by a Content-Security-Policy header, in
+ // addition to those which are set by the embedding frame. This is initially a
+ // copy of the active sandbox flags which are stored in the FrameTreeNode for
+ // this RenderFrameHost, but may diverge if this RenderFrameHost is pending
+ // deletion.
+ blink::WebSandboxFlags active_sandbox_flags_;
#if defined(OS_ANDROID)
// An InterfaceProvider for Java-implemented interfaces that are scoped to
@@ -1300,8 +1376,17 @@ class CONTENT_EXPORT RenderFrameHostImpl
std::unique_ptr<JavaInterfaceProvider> java_interface_registry_;
#endif
- mojo::BindingSet<service_manager::mojom::InterfaceProvider>
- interface_provider_bindings_;
+ // Binding for the InterfaceProvider through which this RFHI exposes Mojo
+ // services to the corresonding RenderFrame.
+ //
+ // Normally, whoever creates this RFHI, is responsible for creating a message
+ // pipe, then supplying the request end to BindInterfaceProviderRequest(), and
+ // plumbing the client end to the RenderFrame in the renderer process.
+ //
+ // Currently the only exception to this rule are out-of-process iframes, where
+ // the child RFHI takes care of this internally in CreateRenderFrame().
+ mojo::Binding<service_manager::mojom::InterfaceProvider>
+ interface_provider_binding_;
// IPC-friendly token that represents this host for AndroidOverlays, if we
// have created one yet.
@@ -1311,6 +1396,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
std::unique_ptr<LegacyIPCFrameInputHandler> legacy_frame_input_handler_;
std::unique_ptr<KeepAliveHandleFactory> keep_alive_handle_factory_;
+ base::TimeDelta keep_alive_timeout_;
// NOTE: This must be the last member.
base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_;
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 541d9619b2d..40fa602aa07 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
@@ -28,6 +28,7 @@
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
namespace content {
@@ -39,25 +40,25 @@ class PrerenderTestContentBrowserClient : public TestContentBrowserClient {
public:
PrerenderTestContentBrowserClient()
: override_enabled_(false),
- visibility_override_(blink::kWebPageVisibilityStateVisible) {}
+ visibility_override_(blink::mojom::PageVisibilityState::kVisible) {}
~PrerenderTestContentBrowserClient() override {}
void EnableVisibilityOverride(
- blink::WebPageVisibilityState visibility_override) {
+ blink::mojom::PageVisibilityState visibility_override) {
override_enabled_ = true;
visibility_override_ = visibility_override;
}
void OverridePageVisibilityState(
RenderFrameHost* render_frame_host,
- blink::WebPageVisibilityState* visibility_state) override {
+ blink::mojom::PageVisibilityState* visibility_state) override {
if (override_enabled_)
*visibility_state = visibility_override_;
}
private:
bool override_enabled_;
- blink::WebPageVisibilityState visibility_override_;
+ blink::mojom::PageVisibilityState visibility_override_;
DISALLOW_COPY_AND_ASSIGN(PrerenderTestContentBrowserClient);
};
@@ -148,11 +149,11 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
WebContents* web_contents = shell()->web_contents();
web_contents->WasShown();
- EXPECT_EQ(blink::kWebPageVisibilityStateVisible,
+ EXPECT_EQ(blink::mojom::PageVisibilityState::kVisible,
web_contents->GetMainFrame()->GetVisibilityState());
web_contents->WasHidden();
- EXPECT_EQ(blink::kWebPageVisibilityStateHidden,
+ EXPECT_EQ(blink::mojom::PageVisibilityState::kHidden,
web_contents->GetMainFrame()->GetVisibilityState());
}
@@ -166,11 +167,12 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
web_contents->WasShown();
- EXPECT_EQ(blink::kWebPageVisibilityStateVisible,
+ EXPECT_EQ(blink::mojom::PageVisibilityState::kVisible,
web_contents->GetMainFrame()->GetVisibilityState());
- new_client.EnableVisibilityOverride(blink::kWebPageVisibilityStatePrerender);
- EXPECT_EQ(blink::kWebPageVisibilityStatePrerender,
+ new_client.EnableVisibilityOverride(
+ blink::mojom::PageVisibilityState::kPrerender);
+ EXPECT_EQ(blink::mojom::PageVisibilityState::kPrerender,
web_contents->GetMainFrame()->GetVisibilityState());
SetBrowserClientForTesting(old_client);
@@ -181,7 +183,8 @@ namespace {
class TestJavaScriptDialogManager : public JavaScriptDialogManager,
public WebContentsDelegate {
public:
- TestJavaScriptDialogManager() : message_loop_runner_(new MessageLoopRunner) {}
+ TestJavaScriptDialogManager()
+ : message_loop_runner_(new MessageLoopRunner), url_invalidate_count_(0) {}
~TestJavaScriptDialogManager() override {}
void Wait() {
@@ -209,6 +212,7 @@ class TestJavaScriptDialogManager : public JavaScriptDialogManager,
bool* did_suppress_message) override {}
void RunBeforeUnloadDialog(WebContents* web_contents,
+ RenderFrameHost* render_frame_host,
bool is_reload,
DialogClosedCallback callback) override {
callback_ = std::move(callback);
@@ -223,12 +227,26 @@ class TestJavaScriptDialogManager : public JavaScriptDialogManager,
void CancelDialogs(WebContents* web_contents, bool reset_state) override {}
+ // Keep track of whether the tab has notified us of a navigation state change
+ // which invalidates the displayed URL.
+ void NavigationStateChanged(WebContents* source,
+ InvalidateTypes changed_flags) override {
+ if (changed_flags & INVALIDATE_TYPE_URL)
+ url_invalidate_count_++;
+ }
+
+ int url_invalidate_count() { return url_invalidate_count_; }
+ void reset_url_invalidate_count() { url_invalidate_count_ = 0; }
+
private:
DialogClosedCallback callback_;
// The MessageLoopRunner used to spin the message loop.
scoped_refptr<MessageLoopRunner> message_loop_runner_;
+ // The number of times NavigationStateChanged has been called.
+ int url_invalidate_count_;
+
DISALLOW_COPY_AND_ASSIGN(TestJavaScriptDialogManager);
};
@@ -340,6 +358,43 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
wc->SetJavaScriptDialogManagerForTesting(nullptr);
}
+// Test for crbug.com/80401. Canceling a beforeunload dialog should reset
+// the URL to the previous page's URL.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
+ CancelBeforeUnloadResetsURL) {
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
+ TestJavaScriptDialogManager dialog_manager;
+ wc->SetDelegate(&dialog_manager);
+
+ GURL url(GetTestUrl("render_frame_host", "beforeunload.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ PrepContentsForBeforeUnloadTest(wc);
+
+ // Navigate to a page that triggers a cross-site transition.
+ GURL url2(embedded_test_server()->GetURL("foo.com", "/title1.html"));
+ shell()->LoadURL(url2);
+ dialog_manager.Wait();
+
+ // Cancel the dialog.
+ dialog_manager.reset_url_invalidate_count();
+ std::move(dialog_manager.callback()).Run(false, base::string16());
+ EXPECT_FALSE(wc->IsLoading());
+
+ // Verify there are no pending history items after the dialog is cancelled.
+ // (see crbug.com/93858)
+ NavigationEntry* entry = wc->GetController().GetPendingEntry();
+ EXPECT_EQ(nullptr, entry);
+ EXPECT_EQ(url, wc->GetVisibleURL());
+
+ // There should have been at least one NavigationStateChange event for
+ // invalidating the URL in the address bar, to avoid leaving the stale URL
+ // visible.
+ EXPECT_GE(dialog_manager.url_invalidate_count(), 1);
+
+ wc->SetDelegate(nullptr);
+ wc->SetJavaScriptDialogManagerForTesting(nullptr);
+}
+
namespace {
// A helper to execute some script in a frame just before it is deleted, such
@@ -754,4 +809,70 @@ IN_PROC_BROWSER_TEST_F(ContentBrowserTest,
}
}
+// Test that a same-document browser-initiated navigation doesn't prevent a
+// document from loading. See https://crbug.com/769645.
+IN_PROC_BROWSER_TEST_F(
+ ContentBrowserTest,
+ SameDocumentBrowserInitiatedNavigationWhileDocumentIsLoading) {
+ ControllableHttpResponse response(embedded_test_server(), "/main_document");
+ EXPECT_TRUE(embedded_test_server()->Start());
+
+ // 1) Load a new document. It reaches the ReadyToCommit stage and then is slow
+ // to load.
+ GURL url(embedded_test_server()->GetURL("/main_document"));
+ TestNavigationManager observer_new_document(shell()->web_contents(), url);
+ shell()->LoadURL(url);
+
+ // The navigation starts
+ EXPECT_TRUE(observer_new_document.WaitForRequestStart());
+ observer_new_document.ResumeNavigation();
+
+ // The server sends the first part of the response and waits.
+ response.WaitForRequest();
+ response.Send(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "\r\n"
+ "<html>"
+ " <body>"
+ " <div id=\"anchor\"></div>"
+ " <script>"
+ " domAutomationController.send('First part received')"
+ " </script>");
+
+ // The browser reaches the ReadyToCommit stage.
+ EXPECT_TRUE(observer_new_document.WaitForResponse());
+ RenderFrameHostImpl* main_rfh = static_cast<RenderFrameHostImpl*>(
+ shell()->web_contents()->GetMainFrame());
+ DOMMessageQueue dom_message_queue(WebContents::FromRenderFrameHost(main_rfh));
+ observer_new_document.ResumeNavigation();
+
+ // Wait for the renderer to load the first part of the response.
+ std::string first_part_received;
+ EXPECT_TRUE(dom_message_queue.WaitForMessage(&first_part_received));
+ EXPECT_EQ("\"First part received\"", first_part_received);
+
+ // 2) In the meantime, a browser-initiated same-document navigation commits.
+ GURL anchor_url(url.spec() + "#anchor");
+ TestNavigationManager observer_same_document(shell()->web_contents(),
+ anchor_url);
+ shell()->LoadURL(anchor_url);
+ observer_same_document.WaitForNavigationFinished();
+
+ // 3) The last part of the response is received.
+ response.Send(
+ " <script>"
+ " domAutomationController.send('Second part received')"
+ " </script>"
+ " </body>"
+ "</html>");
+ response.Done();
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+ // The renderer should be able to load the end of the response.
+ std::string second_part_received;
+ EXPECT_TRUE(dom_message_queue.WaitForMessage(&second_part_received));
+ EXPECT_EQ("\"Second part received\"", second_part_received);
+}
+
} // namespace content
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 f7b53cd5b94..18050d184b8 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_manager.cc
@@ -413,7 +413,7 @@ void RenderFrameHostManager::OnCrossSiteResponse(
referrer, page_transition, global_request_id,
should_replace_current_entry,
transfer_navigation_handle_->IsPost() ? "POST" : "GET",
- transfer_navigation_handle_->resource_request_body(), extra_headers);
+ transfer_navigation_handle_->GetResourceRequestBody(), extra_headers);
// If the navigation continued, the NavigationHandle should have been
// transfered to a RenderFrameHost. In the other cases, it should be cleared.
@@ -450,7 +450,6 @@ void RenderFrameHostManager::CommitPendingIfNecessary(
// We should only hear this from our current renderer.
DCHECK_EQ(render_frame_host_.get(), render_frame_host);
- EnsureRenderFrameHostVisibilityConsistent();
// If the current RenderFrameHost has a pending WebUI it must be committed.
// Note: When one tries to move same-site commit logic into RenderFrameHost
@@ -547,6 +546,10 @@ void RenderFrameHostManager::CommitPendingFramePolicy() {
// Policy updates can only happen when the frame has a parent.
CHECK(frame_tree_node_->parent());
+ // There should be no children of this frame; any policy changes should only
+ // happen on navigation commit.
+ DCHECK(!frame_tree_node_->child_count());
+
// Notify all of the frame's proxies about updated policies, excluding
// the parent process since it already knows the latest state.
SiteInstance* parent_site_instance =
@@ -555,12 +558,18 @@ void RenderFrameHostManager::CommitPendingFramePolicy() {
if (pair.second->GetSiteInstance() != parent_site_instance) {
pair.second->Send(new FrameMsg_DidUpdateFramePolicy(
pair.second->GetRoutingID(),
- frame_tree_node_->current_replication_state().sandbox_flags,
- frame_tree_node_->current_replication_state().container_policy));
+ frame_tree_node_->current_replication_state().frame_policy));
}
}
}
+void RenderFrameHostManager::OnDidSetActiveSandboxFlags() {
+ for (const auto& pair : proxy_hosts_) {
+ pair.second->Send(new FrameMsg_DidSetActiveSandboxFlags(
+ pair.second->GetRoutingID(), frame_tree_node_->active_sandbox_flags()));
+ }
+}
+
void RenderFrameHostManager::SwapOutOldFrame(
std::unique_ptr<RenderFrameHostImpl> old_render_frame_host) {
TRACE_EVENT1("navigation", "RenderFrameHostManager::SwapOutOldFrame",
@@ -721,8 +730,21 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
// not be recreated if the URL didn't change. So instead of calling
// CleanUpNavigation just discard the speculative RenderFrameHost if one
// exists.
- if (speculative_render_frame_host_)
+ if (speculative_render_frame_host_) {
+ // If the speculative RenderFrameHost is trying to commit a navigation,
+ // inform the NavigationController that the load of the corresponding
+ // NavigationEntry stopped if needed. This is the case if the new
+ // navigation was started from BeginNavigation. If the navigation was
+ // started through the NavigationController, the NavigationController has
+ // already updated its state properly, and doesn't need to be notified.
+ if (speculative_render_frame_host_->navigation_handle() &&
+ request.from_begin_navigation()) {
+ frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded(
+ speculative_render_frame_host_->navigation_handle()
+ ->pending_nav_entry_id());
+ }
DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
+ }
// Short-term solution: avoid creating a WebUI for subframes because
// non-PlzNavigate code path doesn't do it and some WebUI pages don't
@@ -746,6 +768,21 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
if (!speculative_render_frame_host_ ||
speculative_render_frame_host_->GetSiteInstance() !=
dest_site_instance.get()) {
+ // If there is a speculative RenderFrameHost trying to commit a
+ // navigation, inform the NavigationController that the load of the
+ // corresponding NavigationEntry stopped if needed. This is the case if
+ // the new navigation was started from BeginNavigation. If the navigation
+ // was started through the NavigationController, the NavigationController
+ // has already updated its state properly, and doesn't need to be
+ // notified.
+ if (speculative_render_frame_host_ &&
+ speculative_render_frame_host_->navigation_handle() &&
+ request.from_begin_navigation()) {
+ frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded(
+ speculative_render_frame_host_->navigation_handle()
+ ->pending_nav_entry_id());
+ }
+
// If a previous speculative RenderFrameHost didn't exist or if its
// SiteInstance differs from the one for the current URL, a new one needs
// to be created.
@@ -814,6 +851,7 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
notify_webui_of_rf_creation = true;
if (navigation_rfh == render_frame_host_.get()) {
+ EnsureRenderFrameHostVisibilityConsistent();
// TODO(nasko): This is a very ugly hack. The Chrome extensions process
// manager still uses NotificationService and expects to see a
// RenderViewHost changed notification after WebContents and
@@ -966,9 +1004,10 @@ RenderFrameHostManager::SiteInstanceDescriptor::SiteInstanceDescriptor(
BrowserContext* browser_context,
GURL dest_url,
SiteInstanceRelation relation_to_current)
- : existing_site_instance(nullptr), relation(relation_to_current) {
- new_site_url = SiteInstance::GetSiteForURL(browser_context, dest_url);
-}
+ : existing_site_instance(nullptr),
+ dest_url(dest_url),
+ browser_context(browser_context),
+ relation(relation_to_current) {}
void RenderFrameHostManager::RenderProcessGone(SiteInstanceImpl* instance) {
GetRenderFrameProxyHost(instance)->set_render_frame_proxy_created(false);
@@ -1224,7 +1263,8 @@ RenderFrameHostManager::GetSiteInstanceForNavigation(
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
if (!frame_tree_node_->IsMainFrame() && !new_instance_impl->HasProcess() &&
new_instance_impl->HasSite() &&
- policy->IsIsolatedOrigin(url::Origin(new_instance_impl->GetSiteURL()))) {
+ policy->IsIsolatedOrigin(
+ url::Origin::Create(new_instance_impl->GetSiteURL()))) {
new_instance_impl->set_process_reuse_policy(
SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE);
}
@@ -1311,19 +1351,9 @@ RenderFrameHostManager::DetermineSiteInstanceForURL(
return SiteInstanceDescriptor(current_instance_impl);
}
- // If the parent frame is a chrome:// page and the subframe is as well, keep
- // the subframe in the parent's process even if they would be considered
- // different sites. This avoids unnecessary OOPIFs on pages like
- // chrome://settings, which currently has multiple "cross-site" subframes that
- // don't need isolation.
if (!frame_tree_node_->IsMainFrame()) {
SiteInstance* parent_site_instance =
frame_tree_node_->parent()->current_frame_host()->GetSiteInstance();
- if (parent_site_instance->GetSiteURL().SchemeIs(kChromeUIScheme) &&
- dest_url.SchemeIs(kChromeUIScheme)) {
- return SiteInstanceDescriptor(parent_site_instance);
- }
-
// TEMPORARY HACK: Don't create OOPIFs on the NTP. Remove this when the NTP
// supports OOPIFs or is otherwise omitted from site isolation policy.
// See https://crbug.com/566091.
@@ -1396,10 +1426,8 @@ RenderFrameHostManager::DetermineSiteInstanceForURL(
// renderers created for particular chrome urls (e.g. the chrome-native://
// scheme) can be reused for subsequent navigations in the same WebContents.
// See http://crbug.com/386542.
- if (dest_is_restore &&
- GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) {
+ if (dest_is_restore && SiteInstanceImpl::ShouldAssignSiteForURL(dest_url))
current_instance_impl->SetSite(dest_url);
- }
return SiteInstanceDescriptor(current_instance_impl);
}
@@ -1455,22 +1483,31 @@ RenderFrameHostManager::DetermineSiteInstanceForURL(
if (IsCurrentlySameSite(render_frame_host_.get(), dest_url))
return SiteInstanceDescriptor(render_frame_host_->GetSiteInstance());
- if (SiteIsolationPolicy::IsTopDocumentIsolationEnabled()) {
- // TODO(nick): Looking at the main frame and openers is required for TDI
- // mode, but should be safe to enable unconditionally.
- if (!frame_tree_node_->IsMainFrame()) {
- RenderFrameHostImpl* main_frame =
- frame_tree_node_->frame_tree()->root()->current_frame_host();
- if (IsCurrentlySameSite(main_frame, dest_url))
- return SiteInstanceDescriptor(main_frame->GetSiteInstance());
- }
-
- if (frame_tree_node_->opener()) {
- RenderFrameHostImpl* opener_frame =
- frame_tree_node_->opener()->current_frame_host();
- if (IsCurrentlySameSite(opener_frame, dest_url))
- return SiteInstanceDescriptor(opener_frame->GetSiteInstance());
- }
+ // Shortcut some common cases for reusing an existing frame's SiteInstance.
+ // Looking at the main frame and openers is required for TDI mode. It also
+ // helps with hosted apps, allowing same-site, non-app subframes to be kept
+ // inside the hosted app process.
+ //
+ // TODO(alexmos): Normally, we'd find these SiteInstances later, as part of
+ // creating a new related SiteInstance from
+ // BrowsingInstance::GetSiteInstanceForURL(), but the lookup there does not
+ // properly deal with hosted apps. Once that's refactored to skip effective
+ // URLs when necessary, this can be removed. See https://crbug.com/718516.
+ if (!frame_tree_node_->IsMainFrame()) {
+ RenderFrameHostImpl* main_frame =
+ frame_tree_node_->frame_tree()->root()->current_frame_host();
+ if (IsCurrentlySameSite(main_frame, dest_url))
+ return SiteInstanceDescriptor(main_frame->GetSiteInstance());
+ RenderFrameHostImpl* parent =
+ frame_tree_node_->parent()->current_frame_host();
+ if (IsCurrentlySameSite(parent, dest_url))
+ return SiteInstanceDescriptor(parent->GetSiteInstance());
+ }
+ if (frame_tree_node_->opener()) {
+ RenderFrameHostImpl* opener_frame =
+ frame_tree_node_->opener()->current_frame_host();
+ if (IsCurrentlySameSite(opener_frame, dest_url))
+ return SiteInstanceDescriptor(opener_frame->GetSiteInstance());
}
if (!frame_tree_node_->IsMainFrame() &&
@@ -1578,7 +1615,7 @@ scoped_refptr<SiteInstance> RenderFrameHostManager::ConvertToSiteInstance(
// Note: If the |candidate_instance| matches the descriptor,
// GetRelatedSiteInstance will return it.
if (descriptor.relation == SiteInstanceRelation::RELATED)
- return current_instance->GetRelatedSiteInstance(descriptor.new_site_url);
+ return current_instance->GetRelatedSiteInstance(descriptor.dest_url);
if (descriptor.relation == SiteInstanceRelation::RELATED_DEFAULT_SUBFRAME)
return current_instance->GetDefaultSubframeSiteInstance();
@@ -1587,14 +1624,16 @@ scoped_refptr<SiteInstance> RenderFrameHostManager::ConvertToSiteInstance(
// check if the candidate matches.
if (candidate_instance &&
!current_instance->IsRelatedSiteInstance(candidate_instance) &&
- candidate_instance->GetSiteURL() == descriptor.new_site_url) {
+ candidate_instance->GetSiteURL() ==
+ SiteInstance::GetSiteForURL(descriptor.browser_context,
+ descriptor.dest_url)) {
return candidate_instance;
}
// Otherwise return a newly created one.
return SiteInstance::CreateForURL(
delegate_->GetControllerForRenderManager().GetBrowserContext(),
- descriptor.new_site_url);
+ descriptor.dest_url);
}
bool RenderFrameHostManager::IsCurrentlySameSite(RenderFrameHostImpl* candidate,
@@ -1602,29 +1641,49 @@ bool RenderFrameHostManager::IsCurrentlySameSite(RenderFrameHostImpl* candidate,
BrowserContext* browser_context =
delegate_->GetControllerForRenderManager().GetBrowserContext();
+ // Don't compare effective URLs for subframe navigations, since we don't want
+ // to create OOPIFs based on that mechanism (e.g., for hosted apps).
+ // See https://crbug.com/718516.
+ // TODO(creis): This should eventually call out to embedder to help decide,
+ // if we can find a way to make decisions about popups based on their opener.
+ bool should_compare_effective_urls = frame_tree_node_->IsMainFrame();
+
// If the process type is incorrect, reject the candidate even if |dest_url|
// is same-site. (The URL may have been installed as an app since
// the last time we visited it.)
- if (candidate->GetSiteInstance()->HasWrongProcessForURL(dest_url))
+ //
+ // This check must be skipped to keep same-site subframe navigations from a
+ // hosted app to non-hosted app, and vice versa, in the same process.
+ // Otherwise, this would return false due to a process privilege level
+ // mismatch.
+ bool src_or_dest_has_effective_url =
+ (SiteInstanceImpl::HasEffectiveURL(browser_context, dest_url) ||
+ SiteInstanceImpl::HasEffectiveURL(
+ browser_context, candidate->GetSiteInstance()->original_url()));
+ bool should_check_for_wrong_process =
+ should_compare_effective_urls || !src_or_dest_has_effective_url;
+ if (should_check_for_wrong_process &&
+ candidate->GetSiteInstance()->HasWrongProcessForURL(dest_url))
return false;
// If we don't have a last successful URL, we can't trust the origin or URL
- // stored on the frame, so we fall back to GetSiteURL(). This case occurs
- // after commits of net errors, since net errors do not currently swap
- // processes for transfer navigations. Note: browser-initiated net errors do
- // swap processes, but the frame's last successful URL will still be empty in
- // that case.
+ // stored on the frame, so we fall back to the SiteInstance URL. This case
+ // matters for newly created frames which haven't committed a navigation yet,
+ // as well as for net errors. Note that we use the SiteInstance's
+ // original_url() and not the site URL, so that we can do this comparison
+ // without the effective URL resolution if needed.
if (candidate->last_successful_url().is_empty()) {
- // TODO(creis): GetSiteURL() is not 100% accurate. Eliminate this fallback.
- return SiteInstance::IsSameWebSite(
- browser_context, candidate->GetSiteInstance()->GetSiteURL(), dest_url);
+ return SiteInstanceImpl::IsSameWebSite(
+ browser_context, candidate->GetSiteInstance()->original_url(), dest_url,
+ should_compare_effective_urls);
}
// In the common case, we use the RenderFrameHost's last successful URL. Thus,
// we compare against the last successful commit when deciding whether to swap
// this time.
- if (SiteInstance::IsSameWebSite(browser_context,
- candidate->last_successful_url(), dest_url)) {
+ if (SiteInstanceImpl::IsSameWebSite(
+ browser_context, candidate->last_successful_url(), dest_url,
+ should_compare_effective_urls)) {
return true;
}
@@ -1632,9 +1691,10 @@ bool RenderFrameHostManager::IsCurrentlySameSite(RenderFrameHostImpl* candidate,
// example, "about:blank"). If so, examine the replicated origin to determine
// the site.
if (!candidate->GetLastCommittedOrigin().unique() &&
- SiteInstance::IsSameWebSite(
+ SiteInstanceImpl::IsSameWebSite(
browser_context,
- GURL(candidate->GetLastCommittedOrigin().Serialize()), dest_url)) {
+ GURL(candidate->GetLastCommittedOrigin().Serialize()), dest_url,
+ should_compare_effective_urls)) {
return true;
}
@@ -2244,7 +2304,19 @@ void RenderFrameHostManager::CommitPending() {
render_frame_host_->GetView()->Focus();
} else {
// The main frame's view is already focused, but we need to set
- // page-level focus in the subframe's renderer.
+ // page-level focus in the subframe's renderer. Before doing that, also
+ // tell the new renderer what the focused frame is if that frame is not
+ // in its process, so that Blink's page-level focus logic won't try to
+ // reset frame focus to the main frame. See https://crbug.com/802156.
+ FrameTreeNode* focused_frame =
+ frame_tree_node_->frame_tree()->GetFocusedFrame();
+ if (focused_frame && !focused_frame->IsMainFrame() &&
+ focused_frame->current_frame_host()->GetSiteInstance() !=
+ render_frame_host_->GetSiteInstance()) {
+ focused_frame->render_manager()
+ ->GetRenderFrameProxyHost(render_frame_host_->GetSiteInstance())
+ ->SetFocusedFrame();
+ }
frame_tree_node_->frame_tree()->SetPageFocus(
render_frame_host_->GetSiteInstance(), true);
}
@@ -2753,7 +2825,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(resolved_url).unique()) {
+ if (url::Origin::Create(resolved_url).unique()) {
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 9f33a6eb40c..71ba448f2cb 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager.h
+++ b/chromium/content/browser/frame_host/render_frame_host_manager.h
@@ -429,6 +429,11 @@ class CONTENT_EXPORT RenderFrameHostManager
// skipping the parent process.
void OnDidUpdateFrameOwnerProperties(const FrameOwnerProperties& properties);
+ // Notify the proxies that the active sandbox flags on the frame have been
+ // changed during page load. This happens when a CSP header sets sandbox
+ // flags.
+ void OnDidSetActiveSandboxFlags();
+
// Send updated origin to all frame proxies when the frame navigates to a new
// origin.
void OnDidUpdateOrigin(const url::Origin& origin,
@@ -549,8 +554,12 @@ class CONTENT_EXPORT RenderFrameHostManager
// Set with an existing SiteInstance to be reused.
content::SiteInstance* existing_site_instance;
- // In case |existing_site_instance| is null, specify a new site URL.
- GURL new_site_url;
+ // In case |existing_site_instance| is null, specify a destination URL.
+ GURL dest_url;
+
+ // In case |existing_site_instance| is null, specify a BrowsingContext, to
+ // be used with |dest_url| to resolve the site URL.
+ BrowserContext* browser_context;
// In case |existing_site_instance| is null, specify how the new site is
// related to the current BrowsingInstance.
@@ -706,7 +715,6 @@ class CONTENT_EXPORT RenderFrameHostManager
// Helper to call CommitPending() in all necessary cases.
void CommitPendingIfNecessary(RenderFrameHostImpl* render_frame_host,
bool was_caused_by_user_gesture);
-
// Commits any pending sandbox flag or feature policy updates when the
// renderer's frame navigates.
void CommitPendingFramePolicy();
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 8198fbf28ec..040dad26e51 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
@@ -47,6 +47,7 @@
#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/controllable_http_response.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
@@ -200,7 +201,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, NoScriptAccessAfterSwapOut) {
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Open a same-site link in a new window.
ShellAddedObserver new_shell_observer;
@@ -277,7 +278,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a rel=noreferrer + target=blank link.
ShellAddedObserver new_shell_observer;
@@ -323,7 +324,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a rel=noreferrer + target=blank link.
ShellAddedObserver new_shell_observer;
@@ -442,7 +443,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a same-site rel=noreferrer + target=foo link.
ShellAddedObserver new_shell_observer;
@@ -490,7 +491,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a same-site rel=noopener + target=foo link.
ShellAddedObserver new_shell_observer;
@@ -541,7 +542,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a target=blank link.
ShellAddedObserver new_shell_observer;
@@ -580,7 +581,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a rel=noreferrer link.
bool success = false;
@@ -617,7 +618,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a rel=noreferrer link.
bool success = false;
@@ -655,7 +656,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a target=foo link.
ShellAddedObserver new_shell_observer;
@@ -729,7 +730,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, MAYBE_DisownOpener) {
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a target=_blank link.
ShellAddedObserver new_shell_observer;
@@ -823,7 +824,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Open a popup using window.open with a 'foo' window.name.
Shell* new_shell = OpenPopup(shell(), GURL(url::kAboutBlankURL), "foo");
@@ -886,7 +887,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
WebContents* opener_contents = shell()->web_contents();
scoped_refptr<SiteInstance> orig_site_instance(
opener_contents->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
RenderFrameHostManager* opener_manager = static_cast<WebContentsImpl*>(
opener_contents)->GetRenderManagerForTesting();
@@ -1023,7 +1024,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
WebContents* opener_contents = shell()->web_contents();
scoped_refptr<SiteInstance> orig_site_instance(
opener_contents->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
RenderFrameHostManager* opener_manager = static_cast<WebContentsImpl*>(
opener_contents)->GetRenderManagerForTesting();
@@ -1106,7 +1107,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
WebContents* orig_contents = shell()->web_contents();
scoped_refptr<SiteInstance> orig_site_instance(
orig_contents->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a target=foo link.
ShellAddedObserver new_shell_observer;
@@ -1206,7 +1207,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Test clicking a target=foo link.
ShellAddedObserver new_shell_observer;
@@ -1261,7 +1262,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, ClickLinkAfter204Error) {
// Get the original SiteInstance for later comparison.
scoped_refptr<SiteInstance> orig_site_instance(
shell()->web_contents()->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance.get() != NULL);
+ EXPECT_TRUE(orig_site_instance.get() != nullptr);
// Load a cross-site page that fails with a 204 error.
EXPECT_TRUE(
@@ -1498,6 +1499,220 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerSpoofingTest,
EXPECT_FALSE(contents->GetController().GetVisibleEntry());
}
+// Ensures that a pending navigation's URL is no longer visible after the
+// speculative RFH is discarded due to a concurrent renderer-initiated
+// navigation. See https://crbug.com/760342.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ ResetVisibleURLOnCrossProcessNavigationInterrupted) {
+ if (!IsBrowserSideNavigationEnabled())
+ return;
+ const std::string kVictimPath = "/victim.html";
+ const std::string kAttackPath = "/attack.html";
+ ControllableHttpResponse victim_response(embedded_test_server(), kVictimPath);
+ ControllableHttpResponse attack_response(embedded_test_server(), kAttackPath);
+ EXPECT_TRUE(embedded_test_server()->Start());
+
+ const GURL kVictimURL = embedded_test_server()->GetURL("a.com", kVictimPath);
+ const GURL kAttackURL = embedded_test_server()->GetURL("b.com", kAttackPath);
+
+ // First navigate to the attacker page. This page will be cross-site compared
+ // to the next navigations we will attempt.
+ const GURL kAttackInitialURL =
+ embedded_test_server()->GetURL("b.com", "/title1.html");
+ NavigateToURL(shell(), kAttackInitialURL);
+ EXPECT_EQ(kAttackInitialURL, shell()->web_contents()->GetVisibleURL());
+
+ // Now, start a browser-initiated cross-site navigation to a new page that
+ // will hang at ready to commit stage.
+ TestNavigationManager victim_navigation(shell()->web_contents(), kVictimURL);
+ shell()->LoadURL(kVictimURL);
+ EXPECT_TRUE(victim_navigation.WaitForRequestStart());
+ victim_navigation.ResumeNavigation();
+
+ victim_response.WaitForRequest();
+ victim_response.Send(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "\r\n");
+ EXPECT_TRUE(victim_navigation.WaitForResponse());
+ victim_navigation.ResumeNavigation();
+
+ // The navigation is ready to commit: it has been handed to the speculative
+ // RenderFrameHost for commit.
+ RenderFrameHostImpl* speculative_rfh =
+ static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root()
+ ->render_manager()
+ ->speculative_frame_host();
+ CHECK(speculative_rfh);
+ EXPECT_TRUE(speculative_rfh->is_loading());
+
+ // Since we have a browser-initiated pending navigation, the navigation URL is
+ // showing in the address bar.
+ EXPECT_EQ(kVictimURL, shell()->web_contents()->GetVisibleURL());
+
+ // The attacker page requests a navigation to a new document while the
+ // browser-initiated navigation hasn't committed yet.
+ TestNavigationManager attack_navigation(shell()->web_contents(), kAttackURL);
+ EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
+ shell()->web_contents(),
+ "location.href = \"" + kAttackURL.spec() + "\";"));
+ EXPECT_TRUE(attack_navigation.WaitForRequestStart());
+
+ // This deletes the speculative RenderFrameHost that was supposed to commit
+ // the browser-initiated navigation.
+ speculative_rfh = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root()
+ ->render_manager()
+ ->speculative_frame_host();
+ EXPECT_FALSE(speculative_rfh);
+
+ // The URL of the browser-initiated navigation should no longer be shown in
+ // the address bar since the RenderFrameHost that was supposed to commit it
+ // has been discarded. Instead, we should be showing the URL of the current
+ // page as we do not show the URL of pending navigations when they are
+ // renderer-initiated.
+ EXPECT_NE(kVictimURL, shell()->web_contents()->GetVisibleURL());
+ EXPECT_EQ(kAttackInitialURL, shell()->web_contents()->GetVisibleURL());
+
+ // The attacker navigation results in a 204.
+ attack_navigation.ResumeNavigation();
+ attack_response.WaitForRequest();
+ attack_response.Send(
+ "HTTP/1.1 204 OK\r\n"
+ "Connection: close\r\n"
+ "\r\n");
+ attack_navigation.WaitForNavigationFinished();
+ speculative_rfh = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root()
+ ->render_manager()
+ ->speculative_frame_host();
+ EXPECT_FALSE(speculative_rfh);
+
+ // We are still showing the URL of the current page.
+ EXPECT_EQ(kAttackInitialURL, shell()->web_contents()->GetVisibleURL());
+}
+
+// Ensures that deleting a speculative RenderFrameHost trying to commit a
+// navigation to the pending NavigationEntry will not crash if it happens
+// because a new navigation to the same pending NavigationEntry started. This is
+// a regression test for crbug.com/796135.
+IN_PROC_BROWSER_TEST_F(
+ RenderFrameHostManagerTest,
+ DeleteSpeculativeRFHPedningCommitOfPendingEntryOnInterrupted) {
+ const std::string kOriginalPath = "/original.html";
+ const std::string kFirstRedirectPath = "/redirect1.html";
+ const std::string kSecondRedirectPath = "/reidrect2.html";
+ ControllableHttpResponse original_response1(embedded_test_server(),
+ kOriginalPath);
+ ControllableHttpResponse original_response2(embedded_test_server(),
+ kOriginalPath);
+ ControllableHttpResponse original_response3(embedded_test_server(),
+ kOriginalPath);
+ ControllableHttpResponse first_redirect_response(embedded_test_server(),
+ kFirstRedirectPath);
+ ControllableHttpResponse second_redirect_response(embedded_test_server(),
+ kSecondRedirectPath);
+ EXPECT_TRUE(embedded_test_server()->Start());
+
+ const GURL kOriginalURL =
+ embedded_test_server()->GetURL("a.com", kOriginalPath);
+ const GURL kFirstRedirectURL =
+ embedded_test_server()->GetURL("b.com", kFirstRedirectPath);
+ const GURL kSecondRedirectURL =
+ embedded_test_server()->GetURL("c.com", kSecondRedirectPath);
+
+ // First navigate to the initial URL. This page will have a cross-site
+ // redirect.
+ shell()->LoadURL(kOriginalURL);
+ original_response1.WaitForRequest();
+ original_response1.Send(
+ "HTTP/1.1 302 FOUND\r\n"
+ "Location: " +
+ kFirstRedirectURL.spec() +
+ "\r\n"
+ "\r\n");
+ original_response1.Done();
+ first_redirect_response.WaitForRequest();
+ first_redirect_response.Send(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "\r\n");
+ first_redirect_response.Send(
+ "<html>"
+ "<body></body>"
+ "</html>");
+ first_redirect_response.Done();
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+ EXPECT_EQ(kFirstRedirectURL, shell()->web_contents()->GetVisibleURL());
+
+ // Now reload the original request, but redirect to yet another site.
+ TestNavigationManager first_reload(shell()->web_contents(), kOriginalURL);
+ shell()->web_contents()->GetController().Reload(
+ ReloadType::ORIGINAL_REQUEST_URL, false);
+ EXPECT_TRUE(first_reload.WaitForRequestStart());
+ first_reload.ResumeNavigation();
+
+ original_response2.WaitForRequest();
+ original_response2.Send(
+ "HTTP/1.1 302 FOUND\r\n"
+ "Location: " +
+ kSecondRedirectURL.spec() +
+ "\r\n"
+ "\r\n");
+ original_response2.Done();
+ second_redirect_response.WaitForRequest();
+ second_redirect_response.Send(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "\r\n");
+ EXPECT_TRUE(first_reload.WaitForResponse());
+ first_reload.ResumeNavigation();
+
+ // The navigation is ready to commit: it has been handed to the speculative
+ // RenderFrameHost for commit.
+ RenderFrameHostImpl* speculative_rfh =
+ static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root()
+ ->render_manager()
+ ->speculative_frame_host();
+ CHECK(speculative_rfh);
+ EXPECT_TRUE(speculative_rfh->is_loading());
+
+ // The user requests a new reload while the previous reload hasn't committed
+ // yet. The navigation start deletes the speculative RenderFrameHost that was
+ // supposed to commit the browser-initiated navigation. This should not crash.
+ TestNavigationManager second_reload(shell()->web_contents(), kOriginalURL);
+ shell()->web_contents()->GetController().Reload(
+ ReloadType::ORIGINAL_REQUEST_URL, false);
+ EXPECT_TRUE(second_reload.WaitForRequestStart());
+ speculative_rfh = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root()
+ ->render_manager()
+ ->speculative_frame_host();
+ EXPECT_FALSE(speculative_rfh);
+
+ // The second reload results in a 204.
+ second_reload.ResumeNavigation();
+ original_response3.WaitForRequest();
+ original_response3.Send(
+ "HTTP/1.1 204 OK\r\n"
+ "Connection: close\r\n"
+ "\r\n");
+ second_reload.WaitForNavigationFinished();
+ speculative_rfh = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root()
+ ->render_manager()
+ ->speculative_frame_host();
+ EXPECT_FALSE(speculative_rfh);
+}
+
// Test for crbug.com/9682. We should not show the URL for a pending renderer-
// initiated navigation in a new tab if it is not the initial navigation. In
// this case, the renderer will not notify us of a modification, so we cannot
@@ -1831,8 +2046,9 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Ensure that such URLs can still work as the initial navigation of a tab.
// We postpone the initial navigation of the tab using an empty GURL, so that
// we can add a watcher for crashes.
- Shell* shell2 = Shell::CreateNewWindow(
- shell()->web_contents()->GetBrowserContext(), GURL(), NULL, gfx::Size());
+ Shell* shell2 =
+ Shell::CreateNewWindow(shell()->web_contents()->GetBrowserContext(),
+ GURL(), nullptr, gfx::Size());
RenderProcessHostWatcher crash_observer2(
shell2->web_contents(),
RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
@@ -1841,49 +2057,6 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
crash_observer2.Wait();
}
-// Ensure that renderer-side debug URLs don't take effect on crashed renderers,
-// even when going back/forward.
-// See https://crbug.com/477606.
-
-// This test is flaky on Android. crbug.com/585327
-#if defined(OS_ANDROID)
-#define MAYBE_IgnoreForwardToRendererDebugURLsWhenCrashed \
- DISABLED_IgnoreForwardToRendererDebugURLsWhenCrashed
-#else
-#define MAYBE_IgnoreForwardToRendererDebugURLsWhenCrashed \
- IgnoreForwardToRendererDebugURLsWhenCrashed
-#endif
-IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
- MAYBE_IgnoreForwardToRendererDebugURLsWhenCrashed) {
- // Visit a WebUI page with bindings.
- GURL webui_url = GURL(std::string(kChromeUIScheme) + "://" +
- std::string(kChromeUIGpuHost));
- NavigateToURL(shell(), webui_url);
- EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
- shell()->web_contents()->GetMainFrame()->GetProcess()->GetID()));
-
- // Visit a debug URL that manages to commit, then go back.
- NavigateToURL(shell(), GURL(kChromeUIDumpURL));
- TestNavigationObserver back_nav_load_observer(shell()->web_contents());
- shell()->web_contents()->GetController().GoBack();
- back_nav_load_observer.Wait();
-
- // Crash the renderer of the WebUI page.
- RenderProcessHostWatcher crash_observer(
- shell()->web_contents(),
- RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
- EXPECT_TRUE(
- NavigateToURLAndExpectNoCommit(shell(), GURL(kChromeUICrashURL)));
- crash_observer.Wait();
-
- // Going forward with no live renderer should have no effect, and should not
- // crash.
- EXPECT_TRUE(shell()->web_contents()->GetController().CanGoForward());
- shell()->web_contents()->GetController().GoForward();
- EXPECT_FALSE(shell()->web_contents()->GetController().GetPendingEntry());
- EXPECT_TRUE(shell()->web_contents()->GetController().CanGoForward());
-}
-
// Ensure that pending_and_current_web_ui_ is cleared when a URL commits.
// Otherwise it might get picked up by InitRenderView when granting bindings
// to other RenderViewHosts. See http://crbug.com/330811.
@@ -1971,7 +2144,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, WebUIGetsBindings) {
// Open a new tab. Initially it gets a render view in the original tab's
// current site instance.
- TestNavigationObserver nav_observer(NULL);
+ TestNavigationObserver nav_observer(nullptr);
nav_observer.StartWatchingNewWebContents();
ShellAddedObserver shao;
OpenUrlViaClickTarget(shell(), url2);
@@ -2050,7 +2223,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
WebUIImpl* web_ui = rfh->web_ui();
EXPECT_TRUE(web_ui->CanCallJavascript());
- auto handler_owner = base::MakeUnique<TestWebUIMessageHandler>();
+ auto handler_owner = std::make_unique<TestWebUIMessageHandler>();
TestWebUIMessageHandler* handler = handler_owner.get();
web_ui->AddMessageHandler(std::move(handler_owner));
@@ -3186,7 +3359,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, LastCommittedOrigin) {
RenderFrameHostImpl* rfh_a = root->current_frame_host();
rfh_a->DisableSwapOutTimerForTesting();
- EXPECT_EQ(url::Origin(url_a), rfh_a->GetLastCommittedOrigin());
+ EXPECT_EQ(url::Origin::Create(url_a), rfh_a->GetLastCommittedOrigin());
EXPECT_EQ(rfh_a, web_contents->GetMainFrame());
// Start a navigation to a b.com URL, and don't wait for commit.
@@ -3203,22 +3376,22 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, LastCommittedOrigin) {
? root->render_manager()->speculative_frame_host()
: root->render_manager()->pending_frame_host();
EXPECT_EQ("null", rfh_b->GetLastCommittedOrigin().Serialize());
- EXPECT_EQ(url::Origin(url_a), rfh_a->GetLastCommittedOrigin());
+ EXPECT_EQ(url::Origin::Create(url_a), rfh_a->GetLastCommittedOrigin());
// Verify that the last committed origin is set for the b.com RHF once it
// commits.
commit_observer.WaitForCommit();
- EXPECT_EQ(url::Origin(url_b), rfh_b->GetLastCommittedOrigin());
+ EXPECT_EQ(url::Origin::Create(url_b), rfh_b->GetLastCommittedOrigin());
EXPECT_EQ(rfh_b, web_contents->GetMainFrame());
// The old RFH should now be pending deletion. Verify it still has correct
// last committed origin.
- EXPECT_EQ(url::Origin(url_a), rfh_a->GetLastCommittedOrigin());
+ EXPECT_EQ(url::Origin::Create(url_a), rfh_a->GetLastCommittedOrigin());
EXPECT_FALSE(rfh_a->is_active());
// Wait for |rfh_a| to be deleted and double-check |rfh_b|'s origin.
deleted_observer.WaitUntilDeleted();
- EXPECT_EQ(url::Origin(url_b), rfh_b->GetLastCommittedOrigin());
+ EXPECT_EQ(url::Origin::Create(url_b), rfh_b->GetLastCommittedOrigin());
// Navigate to a same-origin page with an about:blank iframe. The iframe
// should also have a b.com origin.
@@ -3226,11 +3399,11 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, LastCommittedOrigin) {
"b.com", "/navigation_controller/page_with_iframe.html"));
EXPECT_TRUE(NavigateToURL(shell(), url_b_with_frame));
EXPECT_EQ(rfh_b, web_contents->GetMainFrame());
- EXPECT_EQ(url::Origin(url_b), rfh_b->GetLastCommittedOrigin());
+ EXPECT_EQ(url::Origin::Create(url_b), rfh_b->GetLastCommittedOrigin());
FrameTreeNode* child = root->child_at(0);
RenderFrameHostImpl* child_rfh_b = root->child_at(0)->current_frame_host();
child_rfh_b->DisableSwapOutTimerForTesting();
- EXPECT_EQ(url::Origin(url_b), child_rfh_b->GetLastCommittedOrigin());
+ EXPECT_EQ(url::Origin::Create(url_b), child_rfh_b->GetLastCommittedOrigin());
// Navigate subframe to c.com. Wait for commit but not full load, and then
// verify the subframe's origin.
@@ -3241,7 +3414,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, LastCommittedOrigin) {
ExecuteScript(child, "location.href = '" + url_c.spec() + "';"));
commit_observer.WaitForCommit();
}
- EXPECT_EQ(url::Origin(url_c),
+ EXPECT_EQ(url::Origin::Create(url_c),
child->current_frame_host()->GetLastCommittedOrigin());
// With OOPIFs, this navigation used a cross-process transfer. Ensure that
@@ -3250,78 +3423,8 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, LastCommittedOrigin) {
if (AreAllSitesIsolatedForTesting()) {
EXPECT_FALSE(child_rfh_b->is_active());
EXPECT_NE(child_rfh_b, child->current_frame_host());
- EXPECT_EQ(url::Origin(url_b), child_rfh_b->GetLastCommittedOrigin());
- }
-}
-
-// Verify that with Site Isolation enabled, chrome:// pages with subframes
-// to other chrome:// URLs all stay in the same process.
-IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
- ChromeSchemeSubframesStayInProcessWithParent) {
- // Enable Site Isolation so subframes with different chrome:// URLs will be
- // treated as cross-site.
- IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());
- StartEmbeddedServer();
-
- GURL chrome_top_url = GURL(std::string(kChromeUIScheme) + "://" +
- std::string(kChromeUIBlobInternalsHost));
- GURL chrome_child_url = GURL(std::string(kChromeUIScheme) + "://" +
- std::string(kChromeUIHistogramHost));
- GURL regular_web_url(embedded_test_server()->GetURL("/title1.html"));
-
- NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
- shell()->web_contents()->GetController());
- FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()
- ->root();
-
- // Navigate the main frame to the top chrome:// URL.
- NavigateToURL(shell(), chrome_top_url);
-
- // Inject a frame in the page and navigate it to a chrome:// URL as well.
- {
- std::string script = base::StringPrintf(
- "var frame = document.createElement('iframe');\n"
- "frame.src = '%s';\n"
- "document.body.appendChild(frame);\n",
- chrome_child_url.spec().c_str());
-
- TestNavigationObserver navigation_observer(shell()->web_contents());
- EXPECT_TRUE(ExecuteScript(shell(), script));
- navigation_observer.Wait();
- EXPECT_EQ(1U, root->child_count());
-
- // Ensure the subframe navigated to the expected URL and that it is in the
- // same SiteInstance as the parent frame.
- NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
- ASSERT_EQ(1U, entry->root_node()->children.size());
- EXPECT_EQ(chrome_child_url,
- entry->root_node()->children[0]->frame_entry->url());
- EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
- root->child_at(0)->current_frame_host()->GetSiteInstance());
- }
-
- // Ensure that non-chrome:// pages get a different SiteInstance and process.
- {
- std::string script = base::StringPrintf(
- "var frame = document.createElement('iframe');\n"
- "frame.src = '%s';\n"
- "document.body.appendChild(frame);\n",
- regular_web_url.spec().c_str());
-
- TestNavigationObserver navigation_observer(shell()->web_contents());
- EXPECT_TRUE(ExecuteScript(shell(), script));
- navigation_observer.Wait();
- EXPECT_EQ(2U, root->child_count());
-
- // Ensure the subframe navigated to the expected URL and that it is in a
- // different SiteInstance from the parent frame.
- NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
- ASSERT_EQ(2U, entry->root_node()->children.size());
- EXPECT_EQ(regular_web_url,
- entry->root_node()->children[1]->frame_entry->url());
- EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
- root->child_at(1)->current_frame_host()->GetSiteInstance());
+ EXPECT_EQ(url::Origin::Create(url_b),
+ child_rfh_b->GetLastCommittedOrigin());
}
}
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 c6ea752e8d7..334e84d333e 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
@@ -6,15 +6,19 @@
#include <stdint.h>
+#include <string>
#include <tuple>
#include <utility>
+#include <vector>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
@@ -40,6 +44,7 @@
#include "content/public/browser/web_ui_controller.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/browser_side_navigation_policy.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/javascript_dialog_type.h"
#include "content/public/common/previews_state.h"
#include "content/public/common/url_constants.h"
@@ -49,15 +54,17 @@
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_notification_tracker.h"
#include "content/public/test/test_utils.h"
+#include "content/test/mock_widget_input_handler.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
#include "content/test/test_render_frame_host.h"
#include "content/test/test_render_view_host.h"
+#include "content/test/test_render_widget_host.h"
#include "content/test/test_web_contents.h"
#include "net/base/load_flags.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/common/frame_policy.h"
#include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
#include "ui/base/page_transition_types.h"
namespace content {
@@ -77,6 +84,17 @@ void VerifyPageFocusMessage(MockRenderProcessHost* rph,
EXPECT_EQ(expected_focus, std::get<0>(params));
}
+// VerifyPageFocusMessage from the mojo input handler.
+void VerifyPageFocusMessage(TestRenderWidgetHost* twh, bool expected_focus) {
+ MockWidgetInputHandler::MessageVector events =
+ twh->GetMockWidgetInputHandler()->GetAndResetDispatchedMessages();
+ EXPECT_EQ(1u, events.size());
+ MockWidgetInputHandler::DispatchedFocusMessage* focus_message =
+ events.at(0)->ToFocus();
+ EXPECT_TRUE(focus_message);
+ EXPECT_EQ(expected_focus, focus_message->focused());
+}
+
// Helper function for strict mixed content checking tests.
void CheckInsecureRequestPolicyIPC(
TestRenderFrameHost* rfh,
@@ -180,21 +198,20 @@ class CloseWebContentsDelegate : public WebContentsDelegate {
bool is_closed() { return close_called_; }
private:
- DISALLOW_COPY_AND_ASSIGN(CloseWebContentsDelegate);
-
bool close_called_;
+
+ DISALLOW_COPY_AND_ASSIGN(CloseWebContentsDelegate);
};
// This observer keeps track of the last deleted RenderViewHost to avoid
// accessing it and causing use-after-free condition.
class RenderViewHostDeletedObserver : public WebContentsObserver {
public:
- RenderViewHostDeletedObserver(RenderViewHost* rvh)
+ explicit RenderViewHostDeletedObserver(RenderViewHost* rvh)
: WebContentsObserver(WebContents::FromRenderViewHost(rvh)),
process_id_(rvh->GetProcess()->GetID()),
routing_id_(rvh->GetRoutingID()),
- deleted_(false) {
- }
+ deleted_(false) {}
void RenderViewDeleted(RenderViewHost* render_view_host) override {
if (render_view_host->GetProcess()->GetID() == process_id_ &&
@@ -219,10 +236,8 @@ class RenderViewHostDeletedObserver : public WebContentsObserver {
// to ensure that no RenderFrameHost objects are created when not expected.
class RenderFrameHostCreatedObserver : public WebContentsObserver {
public:
- RenderFrameHostCreatedObserver(WebContents* web_contents)
- : WebContentsObserver(web_contents),
- created_(false) {
- }
+ explicit RenderFrameHostCreatedObserver(WebContents* web_contents)
+ : WebContentsObserver(web_contents), created_(false) {}
void RenderFrameCreated(RenderFrameHost* render_frame_host) override {
created_ = true;
@@ -241,7 +256,7 @@ class RenderFrameHostCreatedObserver : public WebContentsObserver {
// This WebContents observer keep track of its RVH change.
class RenderViewHostChangedObserver : public WebContentsObserver {
public:
- RenderViewHostChangedObserver(WebContents* web_contents)
+ explicit RenderViewHostChangedObserver(WebContents* web_contents)
: WebContentsObserver(web_contents), host_changed_(false) {}
// WebContentsObserver.
@@ -270,10 +285,10 @@ class RenderViewHostChangedObserver : public WebContentsObserver {
// See http://crbug.com/351815
class PluginFaviconMessageObserver : public WebContentsObserver {
public:
- PluginFaviconMessageObserver(WebContents* web_contents)
+ explicit PluginFaviconMessageObserver(WebContents* web_contents)
: WebContentsObserver(web_contents),
plugin_crashed_(false),
- favicon_received_(false) { }
+ favicon_received_(false) {}
void PluginCrashed(const base::FilePath& plugin_path,
base::ProcessId plugin_pid) override {
@@ -304,6 +319,7 @@ class PluginFaviconMessageObserver : public WebContentsObserver {
class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
public:
void SetUp() override {
+ mojo_feature_list_.InitAndEnableFeature(features::kMojoInputMessages);
RenderViewHostImplTestHarness::SetUp();
WebUIControllerFactory::RegisterFactory(&factory_);
}
@@ -364,7 +380,7 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
EXPECT_TRUE(rfh_observer.deleted());
}
EXPECT_EQ(active_rfh, contents()->GetMainFrame());
- EXPECT_EQ(NULL, contents()->GetPendingMainFrame());
+ EXPECT_EQ(nullptr, contents()->GetPendingMainFrame());
}
bool ShouldSwapProcesses(RenderFrameHostManager* manager,
@@ -492,6 +508,7 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
RenderFrameHostManager*)>& commit_lambda);
private:
+ base::test::ScopedFeatureList mojo_feature_list_;
RenderFrameHostManagerTestWebUIControllerFactory factory_;
};
@@ -515,7 +532,7 @@ TEST_F(RenderFrameHostManagerTest, NewTabPageProcesses) {
// Make a second tab.
std::unique_ptr<TestWebContents> contents2(
- TestWebContents::Create(browser_context(), NULL));
+ TestWebContents::Create(browser_context(), nullptr));
// Load the two URLs in the second tab. Note that the first navigation creates
// a RFH that's not pending (since there is no cross-site transition), so
@@ -908,14 +925,13 @@ TEST_F(RenderFrameHostManagerTest, Navigate) {
RenderViewHostChangedObserver change_observer(web_contents.get());
RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
- RenderFrameHostImpl* host = NULL;
+ RenderFrameHostImpl* host = nullptr;
// 1) The first navigation. --------------------------
const GURL kUrl1("http://www.google.com/");
NavigationEntryImpl entry1(
- NULL /* instance */, kUrl1, Referrer(),
- base::string16() /* title */, ui::PAGE_TRANSITION_TYPED,
- false /* is_renderer_init */);
+ nullptr /* instance */, kUrl1, Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED, false /* is_renderer_init */);
host = NavigateToEntry(manager, entry1);
// The RenderFrameHost created in Init will be reused.
@@ -934,7 +950,7 @@ TEST_F(RenderFrameHostManagerTest, Navigate) {
// 2) Navigate to next site. -------------------------
const GURL kUrl2("http://www.google.com/foo");
- NavigationEntryImpl entry2(NULL /* instance */, kUrl2,
+ NavigationEntryImpl entry2(nullptr /* instance */, kUrl2,
Referrer(kUrl1, blink::kWebReferrerPolicyDefault),
base::string16() /* title */,
ui::PAGE_TRANSITION_LINK,
@@ -956,7 +972,7 @@ TEST_F(RenderFrameHostManagerTest, Navigate) {
// 3) Cross-site navigate to next site. --------------
const GURL kUrl3("http://webkit.org/");
- NavigationEntryImpl entry3(NULL /* instance */, kUrl3,
+ NavigationEntryImpl entry3(nullptr /* instance */, kUrl3,
Referrer(kUrl2, blink::kWebReferrerPolicyDefault),
base::string16() /* title */,
ui::PAGE_TRANSITION_LINK,
@@ -1000,10 +1016,9 @@ TEST_F(RenderFrameHostManagerTest, WebUI) {
EXPECT_TRUE(initial_rfh);
const GURL kUrl("chrome://foo");
- NavigationEntryImpl entry(NULL /* instance */, kUrl,
- Referrer(), base::string16() /* title */,
- ui::PAGE_TRANSITION_TYPED,
- false /* is_renderer_init */);
+ NavigationEntryImpl entry(
+ nullptr /* instance */, kUrl, Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED, false /* is_renderer_init */);
RenderFrameHostImpl* host = NavigateToEntry(manager, entry);
// We commit the pending RenderFrameHost immediately because the previous
@@ -1063,10 +1078,9 @@ TEST_F(RenderFrameHostManagerTest, WebUIInNewTab) {
// Navigate to a WebUI page.
const GURL kUrl1("chrome://foo");
- NavigationEntryImpl entry1(NULL /* instance */, kUrl1,
- Referrer(), base::string16() /* title */,
- ui::PAGE_TRANSITION_TYPED,
- false /* is_renderer_init */);
+ NavigationEntryImpl entry1(
+ nullptr /* instance */, kUrl1, Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED, false /* is_renderer_init */);
RenderFrameHostImpl* host1 = NavigateToEntry(manager1, entry1);
// We should have a pending navigation to the WebUI RenderViewHost.
@@ -1094,10 +1108,9 @@ TEST_F(RenderFrameHostManagerTest, WebUIInNewTab) {
EXPECT_TRUE(manager2->current_host()->IsRenderViewLive());
const GURL kUrl2("chrome://foo/bar");
- NavigationEntryImpl entry2(NULL /* instance */, kUrl2,
- Referrer(), base::string16() /* title */,
- ui::PAGE_TRANSITION_LINK,
- true /* is_renderer_init */);
+ NavigationEntryImpl entry2(
+ nullptr /* instance */, kUrl2, Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_LINK, true /* is_renderer_init */);
RenderFrameHostImpl* host2 = NavigateToEntry(manager2, entry2);
// No cross-process transition happens because we are already in the right
@@ -1202,19 +1215,20 @@ TEST_F(RenderFrameHostManagerTest, PageDoesBackAndReload) {
// That should NOT have cancelled the pending RFH, because the reload did
// not have a user gesture. Thus, the pending back navigation will still
// eventually commit.
- EXPECT_TRUE(contents()->GetRenderManagerForTesting()->
- pending_render_view_host() != NULL);
+ EXPECT_TRUE(
+ contents()->GetRenderManagerForTesting()->pending_render_view_host() !=
+ nullptr);
EXPECT_TRUE(contents()->GetRenderManagerForTesting()->pending_frame_host() !=
- NULL);
+ nullptr);
EXPECT_EQ(evil_rfh,
contents()->GetRenderManagerForTesting()->current_frame_host());
EXPECT_EQ(evil_rfh->GetRenderViewHost(),
contents()->GetRenderManagerForTesting()->current_host());
// Also we should not have a pending navigation entry.
- EXPECT_TRUE(contents()->GetController().GetPendingEntry() == NULL);
+ EXPECT_TRUE(contents()->GetController().GetPendingEntry() == nullptr);
NavigationEntry* entry = contents()->GetController().GetVisibleEntry();
- ASSERT_TRUE(entry != NULL);
+ ASSERT_TRUE(entry != nullptr);
EXPECT_EQ(kUrl2, entry->GetURL());
// Now do the same but as a user gesture.
@@ -1224,19 +1238,20 @@ TEST_F(RenderFrameHostManagerTest, PageDoesBackAndReload) {
evil_rfh->SimulateNavigationStop();
// User navigation should have cancelled the pending RFH.
- EXPECT_TRUE(contents()->GetRenderManagerForTesting()->
- pending_render_view_host() == NULL);
+ EXPECT_TRUE(
+ contents()->GetRenderManagerForTesting()->pending_render_view_host() ==
+ nullptr);
EXPECT_TRUE(contents()->GetRenderManagerForTesting()->pending_frame_host() ==
- NULL);
+ nullptr);
EXPECT_EQ(evil_rfh,
contents()->GetRenderManagerForTesting()->current_frame_host());
EXPECT_EQ(evil_rfh->GetRenderViewHost(),
contents()->GetRenderManagerForTesting()->current_host());
// Also we should not have a pending navigation entry.
- EXPECT_TRUE(contents()->GetController().GetPendingEntry() == NULL);
+ EXPECT_TRUE(contents()->GetController().GetPendingEntry() == nullptr);
entry = contents()->GetController().GetVisibleEntry();
- ASSERT_TRUE(entry != NULL);
+ ASSERT_TRUE(entry != nullptr);
EXPECT_EQ(kUrl2, entry->GetURL());
}
@@ -1606,14 +1621,13 @@ TEST_F(RenderFrameHostManagerTest, NoSwapOnGuestNavigations) {
RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting();
- RenderFrameHostImpl* host = NULL;
+ RenderFrameHostImpl* host = nullptr;
// 1) The first navigation. --------------------------
const GURL kUrl1("http://www.google.com/");
NavigationEntryImpl entry1(
- NULL /* instance */, kUrl1, Referrer(),
- base::string16() /* title */, ui::PAGE_TRANSITION_TYPED,
- false /* is_renderer_init */);
+ nullptr /* instance */, kUrl1, Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED, false /* is_renderer_init */);
host = NavigateToEntry(manager, entry1);
// The RenderFrameHost created in Init will be reused.
@@ -1631,7 +1645,7 @@ TEST_F(RenderFrameHostManagerTest, NoSwapOnGuestNavigations) {
// 2) Navigate to a different domain. -------------------------
// Guests stay in the same process on navigation.
const GURL kUrl2("http://www.chromium.org");
- NavigationEntryImpl entry2(NULL /* instance */, kUrl2,
+ NavigationEntryImpl entry2(nullptr /* instance */, kUrl2,
Referrer(kUrl1, blink::kWebReferrerPolicyDefault),
base::string16() /* title */,
ui::PAGE_TRANSITION_LINK,
@@ -1667,10 +1681,9 @@ TEST_F(RenderFrameHostManagerTest, NavigateWithEarlyClose) {
// 1) The first navigation. --------------------------
const GURL kUrl1("http://www.google.com/");
- NavigationEntryImpl entry1(NULL /* instance */, kUrl1,
- Referrer(), base::string16() /* title */,
- ui::PAGE_TRANSITION_TYPED,
- false /* is_renderer_init */);
+ NavigationEntryImpl entry1(
+ nullptr /* instance */, kUrl1, Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED, false /* is_renderer_init */);
RenderFrameHostImpl* host = NavigateToEntry(manager, entry1);
// The RenderFrameHost created in Init will be reused.
@@ -1691,9 +1704,8 @@ TEST_F(RenderFrameHostManagerTest, NavigateWithEarlyClose) {
// 2) Cross-site navigate to next site. -------------------------
const GURL kUrl2("http://www.example.com");
NavigationEntryImpl entry2(
- NULL /* instance */, kUrl2, Referrer(),
- base::string16() /* title */, ui::PAGE_TRANSITION_TYPED,
- false /* is_renderer_init */);
+ nullptr /* instance */, kUrl2, Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED, false /* is_renderer_init */);
RenderFrameHostImpl* host2 = NavigateToEntry(manager, entry2);
// A new RenderFrameHost should be created.
@@ -1775,7 +1787,7 @@ TEST_F(RenderFrameHostManagerTest, DeleteFrameAfterSwapOutACK) {
ui::PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(rfh2, contents()->GetMainFrame());
- EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL);
+ EXPECT_TRUE(contents()->GetPendingMainFrame() == nullptr);
EXPECT_TRUE(rfh2->is_active());
EXPECT_FALSE(rfh1->is_active());
@@ -1784,7 +1796,7 @@ TEST_F(RenderFrameHostManagerTest, DeleteFrameAfterSwapOutACK) {
// rfh1 should have been deleted.
EXPECT_TRUE(rfh_deleted_observer.deleted());
- rfh1 = NULL;
+ rfh1 = nullptr;
}
// Tests that the RenderFrameHost is properly swapped out when the SwapOut ACK
@@ -1817,7 +1829,7 @@ TEST_F(RenderFrameHostManagerTest, SwapOutFrameAfterSwapOutACK) {
ui::PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(rfh2, contents()->GetMainFrame());
- EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL);
+ EXPECT_TRUE(contents()->GetPendingMainFrame() == nullptr);
EXPECT_FALSE(rfh1->is_active());
EXPECT_TRUE(rfh2->is_active());
@@ -1862,7 +1874,7 @@ TEST_F(RenderFrameHostManagerTest,
ui::PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(rfh2, contents()->GetMainFrame());
- EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL);
+ EXPECT_TRUE(contents()->GetPendingMainFrame() == nullptr);
EXPECT_FALSE(rfh1->is_active());
EXPECT_TRUE(rfh2->is_active());
@@ -1881,7 +1893,7 @@ TEST_F(RenderFrameHostManagerTest,
CancelPendingProperlyDeletesOrSwaps) {
const GURL kUrl1("http://www.google.com/");
const GURL kUrl2("http://www.chromium.org/");
- RenderFrameHostImpl* pending_rfh = NULL;
+ RenderFrameHostImpl* pending_rfh = nullptr;
base::TimeTicks now = base::TimeTicks::Now();
// Navigate to the first page.
@@ -1949,14 +1961,16 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation, DetachPendingChild) {
contents()->NavigateAndCommit(kUrlA);
contents()->GetMainFrame()->OnCreateChildFrame(
contents()->GetMainFrame()->GetProcess()->GetNextRoutingID(),
- blink::WebTreeScopeType::kDocument, "frame_name", "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "frame_name", "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
contents()->GetMainFrame()->OnCreateChildFrame(
contents()->GetMainFrame()->GetProcess()->GetNextRoutingID(),
- blink::WebTreeScopeType::kDocument, "frame_name", "uniqueName2",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "frame_name", "uniqueName2", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
RenderFrameHostManager* root_manager =
contents()->GetFrameTree()->root()->render_manager();
RenderFrameHostManager* iframe1 =
@@ -1965,10 +1979,9 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation, DetachPendingChild) {
contents()->GetFrameTree()->root()->child_at(1)->render_manager();
// 1) The first navigation.
- NavigationEntryImpl entryA(NULL /* instance */, kUrlA,
- Referrer(), base::string16() /* title */,
- ui::PAGE_TRANSITION_TYPED,
- false /* is_renderer_init */);
+ NavigationEntryImpl entryA(
+ nullptr /* instance */, kUrlA, Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED, false /* is_renderer_init */);
RenderFrameHostImpl* host1 = NavigateToEntry(iframe1, entryA);
// The RenderFrameHost created in Init will be reused.
@@ -1983,7 +1996,7 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation, DetachPendingChild) {
EXPECT_TRUE(host1->GetSiteInstance()->HasSite());
// 2) Cross-site navigate both frames to next site.
- NavigationEntryImpl entryB(NULL /* instance */, kUrlB,
+ NavigationEntryImpl entryB(nullptr /* instance */, kUrlB,
Referrer(kUrlA, blink::kWebReferrerPolicyDefault),
base::string16() /* title */,
ui::PAGE_TRANSITION_LINK,
@@ -2030,7 +2043,7 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation, DetachPendingChild) {
// not yet destroy proxies in |site_instance| since the other child remains.
iframe1->current_frame_host()->OnMessageReceived(
FrameHostMsg_Detach(iframe1->current_frame_host()->GetRoutingID()));
- iframe1 = NULL; // Was just destroyed.
+ iframe1 = nullptr; // Was just destroyed.
EXPECT_TRUE(delete_watcher1.deleted());
EXPECT_FALSE(delete_watcher2.deleted());
@@ -2046,7 +2059,7 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation, DetachPendingChild) {
// RenderFrameProxyHosts in |site_instance|.
iframe2->current_frame_host()->OnMessageReceived(
FrameHostMsg_Detach(iframe2->current_frame_host()->GetRoutingID()));
- iframe2 = NULL; // Was just destroyed.
+ iframe2 = nullptr; // Was just destroyed.
EXPECT_TRUE(delete_watcher1.deleted());
EXPECT_TRUE(delete_watcher2.deleted());
@@ -2090,12 +2103,13 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation,
// |contents1| creates an out of process iframe.
contents1->GetMainFrame()->OnCreateChildFrame(
contents1->GetMainFrame()->GetProcess()->GetNextRoutingID(),
- blink::WebTreeScopeType::kDocument, "frame_name", "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "frame_name", "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
RenderFrameHostManager* iframe =
contents()->GetFrameTree()->root()->child_at(0)->render_manager();
- NavigationEntryImpl entry(NULL /* instance */, kUrl2,
+ NavigationEntryImpl entry(nullptr /* instance */, kUrl2,
Referrer(kUrl1, blink::kWebReferrerPolicyDefault),
base::string16() /* title */,
ui::PAGE_TRANSITION_LINK,
@@ -2140,9 +2154,10 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation,
EXPECT_TRUE(main_rfh->IsRenderFrameLive());
main_rfh->OnCreateChildFrame(
main_rfh->GetProcess()->GetNextRoutingID(),
- blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
RenderFrameHostManager* subframe_rfhm =
contents()->GetFrameTree()->root()->child_at(0)->render_manager();
@@ -2298,16 +2313,16 @@ TEST_F(RenderFrameHostManagerTest, TraverseComplexOpenerChain) {
FrameTree* tree1 = contents()->GetFrameTree();
FrameTreeNode* root1 = tree1->root();
int process_id = root1->current_frame_host()->GetProcess()->GetID();
- tree1->AddFrame(root1, process_id, 12, blink::WebTreeScopeType::kDocument,
- std::string(), "uniqueName0",
- base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
- FrameOwnerProperties());
- tree1->AddFrame(root1, process_id, 13, blink::WebTreeScopeType::kDocument,
- std::string(), "uniqueName1",
- base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
- FrameOwnerProperties());
+ tree1->AddFrame(root1, process_id, 12,
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(),
+ "uniqueName0", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
+ tree1->AddFrame(root1, process_id, 13,
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(),
+ "uniqueName1", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
std::unique_ptr<TestWebContents> tab2(
TestWebContents::Create(browser_context(), nullptr));
@@ -2315,16 +2330,16 @@ TEST_F(RenderFrameHostManagerTest, TraverseComplexOpenerChain) {
FrameTree* tree2 = tab2->GetFrameTree();
FrameTreeNode* root2 = tree2->root();
process_id = root2->current_frame_host()->GetProcess()->GetID();
- tree2->AddFrame(root2, process_id, 22, blink::WebTreeScopeType::kDocument,
- std::string(), "uniqueName2",
- base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
- FrameOwnerProperties());
- tree2->AddFrame(root2, process_id, 23, blink::WebTreeScopeType::kDocument,
- std::string(), "uniqueName3",
- base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
- FrameOwnerProperties());
+ tree2->AddFrame(root2, process_id, 22,
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(),
+ "uniqueName2", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
+ tree2->AddFrame(root2, process_id, 23,
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(),
+ "uniqueName3", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
std::unique_ptr<TestWebContents> tab3(
TestWebContents::Create(browser_context(), nullptr));
@@ -2337,11 +2352,11 @@ TEST_F(RenderFrameHostManagerTest, TraverseComplexOpenerChain) {
FrameTree* tree4 = tab4->GetFrameTree();
FrameTreeNode* root4 = tree4->root();
process_id = root4->current_frame_host()->GetProcess()->GetID();
- tree4->AddFrame(root4, process_id, 42, blink::WebTreeScopeType::kDocument,
- std::string(), "uniqueName4",
- base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
- FrameOwnerProperties());
+ tree4->AddFrame(root4, process_id, 42,
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(),
+ "uniqueName4", false, base::UnguessableToken::Create(),
+ blink::FramePolicy(), FrameOwnerProperties());
root1->child_at(1)->SetOpener(root1->child_at(1));
root1->SetOpener(root2->child_at(1));
@@ -2389,19 +2404,22 @@ TEST_F(RenderFrameHostManagerTest, PageFocusPropagatesToSubframeProcesses) {
contents()->NavigateAndCommit(kUrlA);
main_test_rfh()->OnCreateChildFrame(
main_test_rfh()->GetProcess()->GetNextRoutingID(),
- blink::WebTreeScopeType::kDocument, "frame1", "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "frame1", "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(
main_test_rfh()->GetProcess()->GetNextRoutingID(),
- blink::WebTreeScopeType::kDocument, "frame2", "uniqueName2",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "frame2", "uniqueName2", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
main_test_rfh()->OnCreateChildFrame(
main_test_rfh()->GetProcess()->GetNextRoutingID(),
- blink::WebTreeScopeType::kDocument, "frame3", "uniqueName3",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "frame3", "uniqueName3", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
FrameTreeNode* root = contents()->GetFrameTree()->root();
RenderFrameHostManager* child1 = root->child_at(0)->render_manager();
@@ -2445,6 +2463,7 @@ TEST_F(RenderFrameHostManagerTest, PageFocusPropagatesToSubframeProcesses) {
RenderFrameProxyHost* proxyC =
root->render_manager()->GetRenderFrameProxyHost(host3->GetSiteInstance());
EXPECT_TRUE(proxyC);
+ base::RunLoop().RunUntilIdle();
// Focus the main page, and verify that the focus message was sent to all
// processes. The message to A should be sent through the main frame's
@@ -2454,8 +2473,8 @@ TEST_F(RenderFrameHostManagerTest, PageFocusPropagatesToSubframeProcesses) {
host1->GetProcess()->sink().ClearMessages();
host3->GetProcess()->sink().ClearMessages();
main_test_rfh()->GetRenderWidgetHost()->Focus();
- VerifyPageFocusMessage(main_test_rfh()->GetProcess(), true,
- main_test_rfh()->GetRenderViewHost()->GetRoutingID());
+ base::RunLoop().RunUntilIdle();
+ VerifyPageFocusMessage(main_test_rfh()->GetRenderWidgetHost(), true);
VerifyPageFocusMessage(host1->GetProcess(), true, proxyB->GetRoutingID());
VerifyPageFocusMessage(host3->GetProcess(), true, proxyC->GetRoutingID());
@@ -2465,8 +2484,8 @@ TEST_F(RenderFrameHostManagerTest, PageFocusPropagatesToSubframeProcesses) {
host1->GetProcess()->sink().ClearMessages();
host3->GetProcess()->sink().ClearMessages();
main_test_rfh()->GetRenderWidgetHost()->Blur();
- VerifyPageFocusMessage(main_test_rfh()->GetProcess(), false,
- main_test_rfh()->GetRenderViewHost()->GetRoutingID());
+ base::RunLoop().RunUntilIdle();
+ VerifyPageFocusMessage(main_test_rfh()->GetRenderWidgetHost(), false);
VerifyPageFocusMessage(host1->GetProcess(), false, proxyB->GetRoutingID());
VerifyPageFocusMessage(host3->GetProcess(), false, proxyC->GetRoutingID());
}
@@ -2490,9 +2509,10 @@ TEST_F(RenderFrameHostManagerTest,
contents()->NavigateAndCommit(kUrlA);
main_test_rfh()->OnCreateChildFrame(
main_test_rfh()->GetProcess()->GetNextRoutingID(),
- blink::WebTreeScopeType::kDocument, "frame1", "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "frame1", "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
FrameTreeNode* root = contents()->GetFrameTree()->root();
RenderFrameHostManager* child = root->child_at(0)->render_manager();
@@ -2617,10 +2637,9 @@ void RenderFrameHostManagerTest::BaseSimultaneousNavigationWithOneWebUI(
// Navigation request to a non-WebUI page.
const GURL kUrl("http://google.com");
- NavigationEntryImpl entry(NULL /* instance */, kUrl,
- Referrer(), base::string16() /* title */,
- ui::PAGE_TRANSITION_TYPED,
- false /* is_renderer_init */);
+ NavigationEntryImpl entry(
+ nullptr /* instance */, kUrl, Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED, false /* is_renderer_init */);
RenderFrameHostImpl* host2 = NavigateToEntry(manager, entry);
ASSERT_TRUE(host2);
@@ -2709,10 +2728,9 @@ void RenderFrameHostManagerTest::BaseSimultaneousNavigationWithTwoWebUIs(
// Navigation another WebUI page, with a different type.
set_webui_type(2);
const GURL kUrl("chrome://bar/");
- NavigationEntryImpl entry(NULL /* instance */, kUrl,
- Referrer(), base::string16() /* title */,
- ui::PAGE_TRANSITION_TYPED,
- false /* is_renderer_init */);
+ NavigationEntryImpl entry(
+ nullptr /* instance */, kUrl, Referrer(), base::string16() /* title */,
+ ui::PAGE_TRANSITION_TYPED, false /* is_renderer_init */);
RenderFrameHostImpl* host2 = NavigateToEntry(manager, entry);
ASSERT_TRUE(host2);
@@ -2818,7 +2836,7 @@ TEST_F(RenderFrameHostManagerTest, CanCommitOrigin) {
for (const auto& test_case : cases) {
params.url = GURL(test_case.url);
- params.origin = url::Origin(GURL(test_case.origin));
+ params.origin = url::Origin::Create(GURL(test_case.origin));
int expected_bad_msg_count = process()->bad_msg_count();
if (test_case.mismatch)
@@ -3035,9 +3053,10 @@ TEST_F(RenderFrameHostManagerTestWithSiteIsolation,
// Create a child frame and navigate it cross-site.
main_test_rfh()->OnCreateChildFrame(
main_test_rfh()->GetProcess()->GetNextRoutingID(),
- blink::WebTreeScopeType::kDocument, "frame1", "uniqueName1",
- base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone,
- ParsedFeaturePolicyHeader(), FrameOwnerProperties());
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, "frame1", "uniqueName1", false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
+ FrameOwnerProperties());
FrameTreeNode* root = contents()->GetFrameTree()->root();
RenderFrameHostManager* child = root->child_at(0)->render_manager();
@@ -3187,4 +3206,66 @@ TEST_F(RenderFrameHostManagerTest,
EXPECT_FALSE(initial_rfh->navigation_handle());
}
+// Tests that sandbox flags received after a navigation away has started do not
+// affect the document being navigated to.
+TEST_F(RenderFrameHostManagerTest, ReceivedFramePolicyAfterNavigationStarted) {
+ const GURL kUrl1("http://www.google.com");
+ const GURL kUrl2("http://www.chromium.org");
+
+ contents()->NavigateAndCommit(kUrl1);
+ TestRenderFrameHost* initial_rfh = main_test_rfh();
+
+ // The RFH should start out with an empty frame policy.
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ initial_rfh->frame_tree_node()->active_sandbox_flags());
+
+ // Navigate cross-site but don't commit the navigation.
+ auto navigation_to_kUrl2 =
+ NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
+ navigation_to_kUrl2->ReadyToCommit();
+
+ // Now send the frame policy for the initial page.
+ initial_rfh->SendFramePolicy(blink::WebSandboxFlags::kAll, {});
+ // Verify that the policy landed in the frame tree.
+ EXPECT_EQ(blink::WebSandboxFlags::kAll,
+ initial_rfh->frame_tree_node()->active_sandbox_flags());
+
+ // Commit the naviagation; the new frame should have a clear frame policy.
+ navigation_to_kUrl2->Commit();
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ main_test_rfh()->frame_tree_node()->active_sandbox_flags());
+}
+
+// Check that after a navigation, the final SiteInstance has the correct
+// original URL that was used to determine its site URL.
+TEST_F(RenderFrameHostManagerTest,
+ SiteInstanceOriginalURLIsPreservedAfterNavigation) {
+ const GURL kFooUrl("https://foo.com");
+ const GURL kOriginalUrl("https://original.com");
+ const GURL kTranslatedUrl("https://translated.com");
+ EffectiveURLContentBrowserClient modified_client(kOriginalUrl,
+ kTranslatedUrl);
+ ContentBrowserClient* regular_client =
+ SetBrowserClientForTesting(&modified_client);
+
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kFooUrl);
+ scoped_refptr<SiteInstanceImpl> initial_instance =
+ main_test_rfh()->GetSiteInstance();
+ EXPECT_EQ(kFooUrl, initial_instance->original_url());
+ EXPECT_EQ(kFooUrl, initial_instance->GetSiteURL());
+
+ // Simulate a browser-initiated navigation to an app URL, which should swap
+ // processes and create a new related SiteInstance in the same
+ // BrowsingInstance. This new SiteInstance should have correct site URL and
+ // |original_url()|.
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kOriginalUrl);
+ EXPECT_NE(initial_instance.get(), main_test_rfh()->GetSiteInstance());
+ EXPECT_TRUE(initial_instance->IsRelatedSiteInstance(
+ main_test_rfh()->GetSiteInstance()));
+ EXPECT_EQ(kOriginalUrl, main_test_rfh()->GetSiteInstance()->original_url());
+ EXPECT_EQ(kTranslatedUrl, main_test_rfh()->GetSiteInstance()->GetSiteURL());
+
+ SetBrowserClientForTesting(regular_client);
+}
+
} // namespace content
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 a842664b32a..4099c6a7ea9 100644
--- a/chromium/content/browser/frame_host/render_frame_message_filter.cc
+++ b/chromium/content/browser/frame_host/render_frame_message_filter.cc
@@ -4,6 +4,11 @@
#include "content/browser/frame_host/render_frame_message_filter.h"
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
#include "base/command_line.h"
#include "base/debug/alias.h"
#include "base/macros.h"
@@ -30,14 +35,18 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "gpu/GLES2/gl2extchromium.h"
+#include "mojo/public/cpp/system/message_pipe.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_options.h"
#include "net/cookies/cookie_store.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "ppapi/features/features.h"
+#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
#include "storage/browser/blob/blob_storage_context.h"
+#include "third_party/WebKit/common/frame_policy.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -60,16 +69,18 @@ namespace {
const int kPluginsRefreshThresholdInSeconds = 3;
#endif
-void CreateChildFrameOnUI(int process_id,
- int parent_routing_id,
- blink::WebTreeScopeType scope,
- const std::string& frame_name,
- const std::string& frame_unique_name,
- const base::UnguessableToken& devtools_frame_token,
- blink::WebSandboxFlags sandbox_flags,
- const ParsedFeaturePolicyHeader& container_policy,
- const FrameOwnerProperties& frame_owner_properties,
- int new_routing_id) {
+void CreateChildFrameOnUI(
+ int process_id,
+ int parent_routing_id,
+ blink::WebTreeScopeType scope,
+ const std::string& frame_name,
+ const std::string& frame_unique_name,
+ bool is_created_by_script,
+ const base::UnguessableToken& devtools_frame_token,
+ const blink::FramePolicy& frame_policy,
+ const FrameOwnerProperties& frame_owner_properties,
+ int new_routing_id,
+ mojo::ScopedMessagePipeHandle interface_provider_request_handle) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderFrameHostImpl* render_frame_host =
RenderFrameHostImpl::FromID(process_id, parent_routing_id);
@@ -77,9 +88,11 @@ void CreateChildFrameOnUI(int process_id,
// processing a subframe creation message.
if (render_frame_host) {
render_frame_host->OnCreateChildFrame(
- new_routing_id, scope, frame_name, frame_unique_name,
- devtools_frame_token, sandbox_flags, container_policy,
- frame_owner_properties);
+ new_routing_id,
+ service_manager::mojom::InterfaceProviderRequest(
+ std::move(interface_provider_request_handle)),
+ scope, frame_name, frame_unique_name, is_created_by_script,
+ devtools_frame_token, frame_policy, frame_owner_properties);
}
}
@@ -342,16 +355,25 @@ void RenderFrameMessageFilter::DownloadUrl(int render_view_id,
void RenderFrameMessageFilter::OnCreateChildFrame(
const FrameHostMsg_CreateChildFrame_Params& params,
int* new_routing_id,
+ mojo::MessagePipeHandle* new_interface_provider,
base::UnguessableToken* devtools_frame_token) {
*new_routing_id = render_widget_helper_->GetNextRoutingID();
+
+ service_manager::mojom::InterfaceProviderPtr interface_provider;
+ auto interface_provider_request(mojo::MakeRequest(&interface_provider));
+ *new_interface_provider =
+ interface_provider.PassInterface().PassHandle().release();
+
*devtools_frame_token = base::UnguessableToken::Create();
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&CreateChildFrameOnUI, render_process_id_,
params.parent_routing_id, params.scope, params.frame_name,
- params.frame_unique_name, *devtools_frame_token,
- params.sandbox_flags, params.container_policy,
- params.frame_owner_properties, *new_routing_id));
+ params.frame_unique_name, params.is_created_by_script,
+ *devtools_frame_token, params.frame_policy,
+ params.frame_owner_properties, *new_routing_id,
+ interface_provider_request.PassMessagePipe()));
}
void RenderFrameMessageFilter::OnCookiesEnabled(int render_frame_id,
@@ -378,7 +400,7 @@ void RenderFrameMessageFilter::CheckPolicyForCookies(
if (context && GetContentClient()->browser()->AllowGetCookie(
url, site_for_cookies, cookie_list, resource_context_,
render_process_id_, render_frame_id)) {
- std::move(callback).Run(net::CookieStore::BuildCookieLine(cookie_list));
+ std::move(callback).Run(net::CanonicalCookie::BuildCookieLine(cookie_list));
} else {
std::move(callback).Run(std::string());
}
@@ -427,7 +449,9 @@ void RenderFrameMessageFilter::OnRenderProcessGone() {
void RenderFrameMessageFilter::SetCookie(int32_t render_frame_id,
const GURL& url,
const GURL& site_for_cookies,
- const std::string& cookie) {
+ const std::string& cookie_line,
+ SetCookieCallback callback) {
+ std::move(callback).Run();
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
if (!policy->CanAccessDataForOrigin(render_process_id_, url)) {
@@ -437,28 +461,30 @@ void RenderFrameMessageFilter::SetCookie(int32_t render_frame_id,
}
net::CookieOptions options;
+ std::unique_ptr<net::CanonicalCookie> cookie = net::CanonicalCookie::Create(
+ url, cookie_line, base::Time::Now(), options);
+ if (!cookie)
+ return;
+
if (!GetContentClient()->browser()->AllowSetCookie(
- url, site_for_cookies, cookie, resource_context_, render_process_id_,
+ url, site_for_cookies, *cookie, resource_context_, render_process_id_,
render_frame_id, options))
return;
if (base::FeatureList::IsEnabled(features::kNetworkService)) {
- // TODO: modify GetRequestContextForURL to work with network service.
- // TODO: merge this with code path below for non-network service.
- std::unique_ptr<net::CanonicalCookie> cc =
- net::CanonicalCookie::Create(url, cookie, base::Time::Now(), options);
- if (cc) {
- cookie_manager_->SetCanonicalCookie(
- *cc, url.SchemeIsCryptographic(), !options.exclude_httponly(),
- net::CookieStore::SetCookiesCallback());
- }
+ // TODO(jam): modify GetRequestContextForURL to work with network service.
+ // Merge this with code path below for non-network service.
+ cookie_manager_->SetCanonicalCookie(*cookie, url.SchemeIsCryptographic(),
+ !options.exclude_httponly(),
+ net::CookieStore::SetCookiesCallback());
return;
}
net::URLRequestContext* context = GetRequestContextForURL(url);
// Pass a null callback since we don't care about when the 'set' completes.
- context->cookie_store()->SetCookieWithOptionsAsync(
- url, cookie, options, net::CookieStore::SetCookiesCallback());
+ context->cookie_store()->SetCanonicalCookieAsync(
+ std::move(cookie), url.SchemeIsCryptographic(),
+ !options.exclude_httponly(), net::CookieStore::SetCookiesCallback());
}
void RenderFrameMessageFilter::GetCookies(int render_frame_id,
@@ -488,8 +514,8 @@ void RenderFrameMessageFilter::GetCookies(int render_frame_id,
}
if (base::FeatureList::IsEnabled(features::kNetworkService)) {
- // TODO: modify GetRequestContextForURL to work with network service.
- // TODO: merge this with code path below for non-network service.
+ // TODO(jam): modify GetRequestContextForURL to work with network service.
+ // Merge this with code path below for non-network service.
cookie_manager_->GetCookieList(
url, options,
base::BindOnce(&RenderFrameMessageFilter::CheckPolicyForCookies, this,
@@ -636,8 +662,7 @@ void RenderFrameMessageFilter::OnOpenChannelToPpapiBroker(
int routing_id,
const base::FilePath& path) {
plugin_service_->OpenChannelToPpapiBroker(
- render_process_id_,
- path,
+ render_process_id_, routing_id, path,
new OpenChannelToPpapiBrokerCallback(this, routing_id));
}
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 1826101c76d..0b884a7558a 100644
--- a/chromium/content/browser/frame_host/render_frame_message_filter.h
+++ b/chromium/content/browser/frame_host/render_frame_message_filter.h
@@ -27,6 +27,10 @@ struct FrameHostMsg_CreateChildFrame_Params;
struct FrameHostMsg_DownloadUrl_Params;
class GURL;
+namespace mojo {
+class MessagePipeHandle;
+}
+
namespace net {
class URLRequestContext;
class URLRequestContextGetter;
@@ -92,6 +96,7 @@ class CONTENT_EXPORT RenderFrameMessageFilter
// Browser process defines them for the renderer process.
void OnCreateChildFrame(const FrameHostMsg_CreateChildFrame_Params& params,
int* new_render_frame_id,
+ mojo::MessagePipeHandle* new_interface_provider,
base::UnguessableToken* devtools_frame_token);
void OnCookiesEnabled(int render_frame_id,
const GURL& url,
@@ -122,7 +127,8 @@ class CONTENT_EXPORT RenderFrameMessageFilter
void SetCookie(int32_t render_frame_id,
const GURL& url,
const GURL& site_for_cookies,
- const std::string& cookie) override;
+ const std::string& cookie_line,
+ SetCookieCallback callback) override;
void GetCookies(int render_frame_id,
const GURL& url,
const GURL& site_for_cookies,
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 aeda6847dd2..f743a8451c2 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
@@ -4,6 +4,8 @@
#include <string>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/test/histogram_tester.h"
@@ -234,10 +236,11 @@ IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest,
->PostTask(FROM_HERE, base::BindOnce(
[](RenderFrameHost* frame) {
GetFilterForProcess(frame->GetProcess())
- ->SetCookie(frame->GetRoutingID(),
- GURL("https://baz.com/"),
- GURL("https://baz.com/"),
- "pwn=ed");
+ ->SetCookie(
+ frame->GetRoutingID(),
+ GURL("https://baz.com/"),
+ GURL("https://baz.com/"), "pwn=ed",
+ base::BindOnce(&base::DoNothing));
},
main_frame));
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 6a345e5c095..42684015a6e 100644
--- a/chromium/content/browser/frame_host/render_frame_proxy_host.cc
+++ b/chromium/content/browser/frame_host/render_frame_proxy_host.cc
@@ -226,6 +226,13 @@ void RenderFrameProxyHost::SetFocusedFrame() {
Send(new FrameMsg_SetFocusedFrame(routing_id_));
}
+void RenderFrameProxyHost::ScrollRectToVisible(
+ const gfx::Rect& rect_to_scroll,
+ const blink::WebRemoteScrollProperties properties) {
+ Send(new FrameMsg_ScrollRectToVisible(routing_id_, rect_to_scroll,
+ properties));
+}
+
void RenderFrameProxyHost::SetDestructionCallback(
DestructionCallback destruction_callback) {
destruction_callback_ = std::move(destruction_callback);
diff --git a/chromium/content/browser/frame_host/render_frame_proxy_host.h b/chromium/content/browser/frame_host/render_frame_proxy_host.h
index e7a9908121d..aafe9cf74c4 100644
--- a/chromium/content/browser/frame_host/render_frame_proxy_host.h
+++ b/chromium/content/browser/frame_host/render_frame_proxy_host.h
@@ -19,6 +19,14 @@
struct FrameHostMsg_OpenURL_Params;
struct FrameMsg_PostMessage_Params;
+namespace blink {
+struct WebRemoteScrollProperties;
+}
+
+namespace gfx {
+class Rect;
+}
+
namespace content {
class CrossProcessFrameConnector;
@@ -110,6 +118,13 @@ class RenderFrameProxyHost
// becomes focused.
void SetFocusedFrame();
+ // Scroll |rect_to_scroll| into view, starting from this proxy's FrameOwner
+ // element in the frame's parent. Calling this continues a scroll started in
+ // the frame's current process. |rect_to_scroll| is with respect to the
+ // coordinates of the originating frame in OOPIF process.
+ void ScrollRectToVisible(const gfx::Rect& rect_to_scroll,
+ const blink::WebRemoteScrollProperties properties);
+
void set_render_frame_proxy_created(bool created) {
render_frame_proxy_created_ = created;
}
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 e885721017f..30520709763 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
@@ -13,10 +13,13 @@
#include "base/message_loop/message_loop.h"
#include "build/build_config.h"
#include "components/viz/common/surfaces/surface_sequence.h"
+#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "components/viz/service/surfaces/surface.h"
+#include "components/viz/service/surfaces/surface_hittest.h"
#include "components/viz/service/surfaces/surface_manager.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/compositor/surface_utils.h"
+#include "content/browser/mus_util.h"
#include "content/browser/renderer_host/input/input_router.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
@@ -31,6 +34,7 @@
#include "gpu/ipc/common/gpu_messages.h"
#include "skia/ext/platform_canvas.h"
#include "ui/events/base_event_utils.h"
+#include "ui/gfx/geometry/dip_util.h"
#if defined(OS_MACOSX)
#import "content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h"
@@ -38,6 +42,7 @@
#if defined(USE_AURA)
#include "content/browser/renderer_host/ui_events_helper.h"
+#include "ui/aura/env.h"
#endif
namespace content {
@@ -84,7 +89,7 @@ RenderWidgetHostViewGuest::RenderWidgetHostViewGuest(
// |guest| is NULL during test.
guest_(guest ? guest->AsWeakPtr() : base::WeakPtr<BrowserPluginGuest>()),
platform_view_(platform_view),
- should_forward_text_selection_(false) {
+ weak_ptr_factory_(this) {
// In tests |guest_| and therefore |owner| can be null.
auto* owner = GetOwnerRenderWidgetHostView();
if (owner)
@@ -143,7 +148,6 @@ void RenderWidgetHostViewGuest::Hide() {
}
void RenderWidgetHostViewGuest::SetSize(const gfx::Size& size) {
- size_ = size;
host_->WasResized();
}
@@ -223,14 +227,99 @@ gfx::Rect RenderWidgetHostViewGuest::GetViewBounds() const {
gfx::Rect embedder_bounds;
if (rwhv)
embedder_bounds = rwhv->GetViewBounds();
- return gfx::Rect(
- guest_->GetScreenCoordinates(embedder_bounds.origin()), size_);
+ return gfx::Rect(guest_->GetScreenCoordinates(embedder_bounds.origin()),
+ guest_->frame_rect().size());
}
gfx::Rect RenderWidgetHostViewGuest::GetBoundsInRootWindow() {
return GetViewBounds();
}
+namespace {
+
+RenderWidgetHostViewBase* GetRootView(RenderWidgetHostViewBase* rwhv) {
+ // If we're a pdf in a WebView, we could have nested guest views here.
+ while (rwhv && rwhv->IsRenderWidgetHostViewGuest()) {
+ rwhv = static_cast<RenderWidgetHostViewGuest*>(rwhv)
+ ->GetOwnerRenderWidgetHostView();
+ }
+ if (!rwhv)
+ return nullptr;
+
+ // We could be a guest inside an oopif frame, in which case we're not the
+ // root.
+ if (rwhv->IsRenderWidgetHostViewChildFrame()) {
+ rwhv = static_cast<RenderWidgetHostViewChildFrame*>(rwhv)
+ ->GetRootRenderWidgetHostView();
+ }
+ return rwhv;
+}
+
+} // namespace
+
+gfx::PointF RenderWidgetHostViewGuest::TransformPointToRootCoordSpaceF(
+ const gfx::PointF& point) {
+ if (!guest_ || !last_received_local_surface_id_.is_valid())
+ return point;
+
+ RenderWidgetHostViewBase* root_rwhv = GetRootView(this);
+ if (!root_rwhv)
+ return point;
+
+ gfx::PointF transformed_point = point;
+ // TODO(wjmaclean): If we knew that TransformPointToLocalCoordSpace would
+ // guarantee not to change transformed_point on failure, then we could skip
+ // checking the function return value and directly return transformed_point.
+ if (!root_rwhv->TransformPointToLocalCoordSpace(
+ point,
+ viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_),
+ &transformed_point)) {
+ return point;
+ }
+ return transformed_point;
+}
+
+bool RenderWidgetHostViewGuest::TransformPointToLocalCoordSpace(
+ const gfx::PointF& point,
+ const viz::SurfaceId& original_surface,
+ gfx::PointF* transformed_point) {
+ *transformed_point = point;
+ if (!guest_ || !last_received_local_surface_id_.is_valid())
+ return false;
+
+ auto local_surface_id =
+ viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_);
+ if (original_surface == local_surface_id)
+ return true;
+
+ *transformed_point =
+ gfx::ConvertPointToPixel(current_surface_scale_factor(), point);
+ viz::SurfaceHittest hittest(nullptr,
+ GetFrameSinkManager()->surface_manager());
+ if (!hittest.TransformPointToTargetSurface(original_surface, local_surface_id,
+ transformed_point)) {
+ return false;
+ }
+
+ *transformed_point = gfx::ConvertPointToDIP(current_surface_scale_factor(),
+ *transformed_point);
+ return true;
+}
+
+gfx::PointF RenderWidgetHostViewGuest::TransformRootPointToViewCoordSpace(
+ const gfx::PointF& point) {
+ RenderWidgetHostViewBase* root_rwhv = GetRootView(this);
+ if (!root_rwhv)
+ return point;
+
+ gfx::PointF transformed_point;
+ if (!root_rwhv->TransformPointToCoordSpaceForView(point, this,
+ &transformed_point)) {
+ return point;
+ }
+ return transformed_point;
+}
+
void RenderWidgetHostViewGuest::RenderProcessGone(
base::TerminationStatus status,
int error_code) {
@@ -251,13 +340,12 @@ void RenderWidgetHostViewGuest::Destroy() {
}
gfx::Size RenderWidgetHostViewGuest::GetPhysicalBackingSize() const {
- // We obtain the reference to native view from the owner RenderWidgetHostView.
- // If the guest is embedded inside a cross-process frame, it is possible to
- // reach here after the frame is detached in which case there will be no owner
- // view.
- if (!GetOwnerRenderWidgetHostView())
- return gfx::Size();
- return RenderWidgetHostViewBase::GetPhysicalBackingSize();
+ gfx::Size size;
+ if (guest_) {
+ size = gfx::ScaleToCeiledSize(guest_->frame_rect().size(),
+ guest_->screen_info().device_scale_factor);
+ }
+ return size;
}
base::string16 RenderWidgetHostViewGuest::GetSelectedText() {
@@ -271,7 +359,7 @@ void RenderWidgetHostViewGuest::SetNeedsBeginFrames(bool needs_begin_frames) {
TouchSelectionControllerClientManager*
RenderWidgetHostViewGuest::GetTouchSelectionControllerClientManager() {
- RenderWidgetHostView* root_view = GetOwnerRenderWidgetHostView();
+ RenderWidgetHostView* root_view = GetRootView(this);
if (!root_view)
return nullptr;
@@ -294,11 +382,13 @@ void RenderWidgetHostViewGuest::SendSurfaceInfoToEmbedderImpl(
void RenderWidgetHostViewGuest::SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) {
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) {
TRACE_EVENT0("content", "RenderWidgetHostViewGuest::OnSwapCompositorFrame");
last_scroll_offset_ = frame.metadata.root_scroll_offset;
- ProcessCompositorFrame(local_surface_id, std::move(frame));
+ ProcessCompositorFrame(local_surface_id, std::move(frame),
+ std::move(hit_test_region_list));
// If after detaching we are sent a frame, we should finish processing it, and
// then we should clear the surface so that we are not holding resources we
@@ -307,6 +397,18 @@ void RenderWidgetHostViewGuest::SubmitCompositorFrame(
ClearCompositorSurfaceIfNecessary();
}
+void RenderWidgetHostViewGuest::OnAttached() {
+ RegisterFrameSinkId();
+#if defined(USE_AURA)
+ if (IsUsingMus()) {
+ aura::Env::GetInstance()->ScheduleEmbed(
+ GetWindowTreeClientFromRenderer(),
+ base::BindOnce(&RenderWidgetHostViewGuest::OnGotEmbedToken,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+#endif
+}
+
bool RenderWidgetHostViewGuest::OnMessageReceived(const IPC::Message& msg) {
if (!platform_view_) {
// In theory, we can get here if there's a delay between Destroy()
@@ -319,7 +421,8 @@ bool RenderWidgetHostViewGuest::OnMessageReceived(const IPC::Message& msg) {
void RenderWidgetHostViewGuest::InitAsChild(
gfx::NativeView parent_view) {
- platform_view_->InitAsChild(parent_view);
+ // This should never get called.
+ NOTREACHED();
}
void RenderWidgetHostViewGuest::InitAsPopup(
@@ -462,7 +565,7 @@ bool RenderWidgetHostViewGuest::LockMouse() {
}
void RenderWidgetHostViewGuest::UnlockMouse() {
- return platform_view_->UnlockMouse();
+ platform_view_->UnlockMouse();
}
viz::LocalSurfaceId RenderWidgetHostViewGuest::GetLocalSurfaceId() const {
@@ -488,7 +591,6 @@ void RenderWidgetHostViewGuest::ShowDefinitionForSelection() {
if (!guest_)
return;
- gfx::Point origin;
gfx::Rect guest_bounds = GetViewBounds();
RenderWidgetHostView* rwhv = guest_->GetOwnerRenderWidgetHostView();
gfx::Rect embedder_bounds;
@@ -613,6 +715,22 @@ InputEventAckState RenderWidgetHostViewGuest::FilterInputEvent(
return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
}
+void RenderWidgetHostViewGuest::GetScreenInfo(ScreenInfo* screen_info) {
+ DCHECK(screen_info);
+ if (!guest_) {
+ *screen_info = ScreenInfo();
+ return;
+ }
+ *screen_info = guest_->screen_info();
+}
+
+void RenderWidgetHostViewGuest::ResizeDueToAutoResize(
+ const gfx::Size& new_size,
+ uint64_t sequence_number) {
+ if (guest_)
+ guest_->ResizeDueToAutoResize(new_size, sequence_number);
+}
+
bool RenderWidgetHostViewGuest::IsRenderWidgetHostViewGuest() {
return true;
}
@@ -715,4 +833,16 @@ bool RenderWidgetHostViewGuest::HasEmbedderChanged() {
return guest_ && guest_->has_attached_since_surface_set();
}
+#if defined(USE_AURA)
+void RenderWidgetHostViewGuest::OnGotEmbedToken(
+ const base::UnguessableToken& token) {
+ if (!guest_)
+ return;
+
+ guest_->SendMessageToEmbedder(
+ base::MakeUnique<BrowserPluginMsg_SetMusEmbedToken>(
+ guest_->browser_plugin_instance_id(), token));
+}
+#endif
+
} // namespace content
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 6ba40d26039..b7d2da23242 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
@@ -24,6 +24,10 @@
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/native_widget_types.h"
+namespace base {
+class UnguessableToken;
+}
+
namespace content {
class BrowserPluginGuest;
class RenderWidgetHost;
@@ -53,6 +57,9 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
bool OnMessageReceivedFromEmbedder(const IPC::Message& message,
RenderWidgetHostImpl* embedder);
+ // Called when this RenderWidgetHostViewGuest is attached.
+ void OnAttached();
+
// RenderWidgetHostView implementation.
bool OnMessageReceived(const IPC::Message& msg) override;
void InitAsChild(gfx::NativeView parent_view) override;
@@ -71,6 +78,13 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
void SetNeedsBeginFrames(bool needs_begin_frames) override;
TouchSelectionControllerClientManager*
GetTouchSelectionControllerClientManager() override;
+ gfx::PointF TransformPointToRootCoordSpaceF(
+ const gfx::PointF& point) override;
+ bool TransformPointToLocalCoordSpace(const gfx::PointF& point,
+ const viz::SurfaceId& original_surface,
+ gfx::PointF* transformed_point) override;
+ gfx::PointF TransformRootPointToViewCoordSpace(
+ const gfx::PointF& point) override;
// RenderWidgetHostViewBase implementation.
void InitAsPopup(RenderWidgetHostView* parent_host_view,
@@ -94,8 +108,10 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
const gfx::Range& range) override;
void SelectionBoundsChanged(
const ViewHostMsg_SelectionBounds_Params& params) override;
- void SubmitCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) override;
+ void SubmitCompositorFrame(
+ const viz::LocalSurfaceId& local_surface_id,
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) override;
#if defined(USE_AURA)
void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) override;
@@ -135,6 +151,11 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
bool IsRenderWidgetHostViewGuest() override;
RenderWidgetHostViewBase* GetOwnerRenderWidgetHostView() const;
+ void GetScreenInfo(ScreenInfo* screen_info) override;
+
+ void ResizeDueToAutoResize(const gfx::Size& new_size,
+ uint64_t sequence_number) override;
+
private:
friend class RenderWidgetHostView;
@@ -163,10 +184,14 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
bool HasEmbedderChanged() override;
+#if defined(USE_AURA)
+ void OnGotEmbedToken(const base::UnguessableToken& token);
+#endif
+
// BrowserPluginGuest and RenderWidgetHostViewGuest's lifetimes are not tied
// to one another, therefore we access |guest_| through WeakPtr.
base::WeakPtr<BrowserPluginGuest> guest_;
- gfx::Size size_;
+
// The platform view for this RenderWidgetHostView.
// RenderWidgetHostViewGuest mostly only cares about stuff related to
// compositing, the rest are directly forwarded to this |platform_view_|.
@@ -175,7 +200,9 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
// When true the guest will forward its selection updates to the owner RWHV.
// The guest may forward its updates only when there is an ongoing IME
// session.
- bool should_forward_text_selection_;
+ bool should_forward_text_selection_ = false;
+
+ base::WeakPtrFactory<RenderWidgetHostViewGuest> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewGuest);
};
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 0f618c398d9..b0534696bbf 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
@@ -53,12 +53,12 @@ class RenderWidgetHostViewGuestTest : public testing::Test {
new MockRenderProcessHost(browser_context_.get());
int32_t routing_id = process_host->GetNextRoutingID();
mojom::WidgetPtr widget;
- widget_impl_ = base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ widget_impl_ = std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
widget_host_ = new RenderWidgetHostImpl(
&delegate_, process_host, routing_id, std::move(widget), false);
view_ = RenderWidgetHostViewGuest::Create(
- widget_host_, NULL,
+ widget_host_, nullptr,
(new TestRenderWidgetHostView(widget_host_))->GetWeakPtr());
}
@@ -157,7 +157,7 @@ class RenderWidgetHostViewGuestSurfaceTest
int32_t routing_id = process_host->GetNextRoutingID();
mojom::WidgetPtr widget;
- widget_impl_ = base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ widget_impl_ = std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
widget_host_ = new RenderWidgetHostImpl(
&delegate_, process_host, routing_id, std::move(widget), false);
@@ -170,7 +170,7 @@ class RenderWidgetHostViewGuestSurfaceTest
viz::mojom::CompositorFrameSinkClientRequest client_request =
mojo::MakeRequest(&renderer_compositor_frame_sink_ptr_);
renderer_compositor_frame_sink_ =
- base::MakeUnique<FakeRendererCompositorFrameSink>(
+ std::make_unique<FakeRendererCompositorFrameSink>(
std::move(sink), std::move(client_request));
view_->DidCreateNewRendererCompositorFrameSink(
renderer_compositor_frame_sink_ptr_.get());
@@ -250,7 +250,7 @@ TEST_F(RenderWidgetHostViewGuestSurfaceTest, TestGuestSurface) {
browser_plugin_guest_->set_attached(true);
view_->SubmitCompositorFrame(
local_surface_id,
- CreateDelegatedFrame(scale_factor, view_size, view_rect));
+ CreateDelegatedFrame(scale_factor, view_size, view_rect), nullptr);
viz::SurfaceId id = GetSurfaceId();
@@ -274,7 +274,7 @@ TEST_F(RenderWidgetHostViewGuestSurfaceTest, TestGuestSurface) {
view_->SubmitCompositorFrame(
local_surface_id,
- CreateDelegatedFrame(scale_factor, view_size, view_rect));
+ CreateDelegatedFrame(scale_factor, view_size, view_rect), nullptr);
// Since we have not changed the frame size and scale factor, the same surface
// id must be used.
@@ -294,7 +294,7 @@ TEST_F(RenderWidgetHostViewGuestSurfaceTest, TestGuestSurface) {
view_->SubmitCompositorFrame(
local_surface_id,
- CreateDelegatedFrame(scale_factor, view_size, view_rect));
+ CreateDelegatedFrame(scale_factor, view_size, view_rect), nullptr);
// Since guest is not attached, the CompositorFrame must be processed but the
// frame must be evicted to return the resources immediately.
EXPECT_FALSE(view_->has_frame());
diff --git a/chromium/content/browser/generic_sensor_browsertest.cc b/chromium/content/browser/generic_sensor_browsertest.cc
index e28b4911468..8f2c6adebba 100644
--- a/chromium/content/browser/generic_sensor_browsertest.cc
+++ b/chromium/content/browser/generic_sensor_browsertest.cc
@@ -3,14 +3,16 @@
// found in the LICENSE file.
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/macros.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_feature_list.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
+#include "components/network_session_configurator/common/network_switches.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/content_switches.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_navigation_observer.h"
@@ -21,6 +23,8 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/buffer.h"
+#include "net/dns/mock_host_resolver.h"
+#include "services/device/public/cpp/device_features.h"
#include "services/device/public/cpp/generic_sensor/platform_sensor_configuration.h"
#include "services/device/public/cpp/generic_sensor/sensor_reading.h"
#include "services/device/public/cpp/generic_sensor/sensor_traits.h"
@@ -143,7 +147,7 @@ class FakeSensorProvider : public device::mojom::SensorProvider {
GetSensorCallback callback) override {
switch (type) {
case device::mojom::SensorType::AMBIENT_LIGHT: {
- auto sensor = base::MakeUnique<FakeAmbientLightSensor>();
+ auto sensor = std::make_unique<FakeAmbientLightSensor>();
auto init_params = device::mojom::SensorInitParams::New();
init_params->memory = sensor->GetSharedBufferHandle();
@@ -173,13 +177,24 @@ class GenericSensorBrowserTest : public ContentBrowserTest {
: io_loop_finished_event_(
base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED) {
- base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
- cmd_line->AppendSwitchASCII(switches::kEnableFeatures,
- "GenericSensor, GenericSensorExtraClasses");
+ scoped_feature_list_.InitWithFeatures(
+ {features::kGenericSensor, features::kGenericSensorExtraClasses}, {});
}
+ ~GenericSensorBrowserTest() override {}
+
void SetUpOnMainThread() override {
- fake_sensor_provider_ = base::MakeUnique<FakeSensorProvider>();
+ https_embedded_test_server_.reset(
+ new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS));
+ // Serve both a.com and b.com (and any other domain).
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(https_embedded_test_server_->InitializeAndListen());
+ content::SetupCrossSiteRedirector(https_embedded_test_server_.get());
+ https_embedded_test_server_->ServeFilesFromSourceDirectory(
+ "content/test/data/generic_sensor");
+ https_embedded_test_server_->StartAcceptingConnections();
+
+ fake_sensor_provider_ = std::make_unique<FakeSensorProvider>();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&GenericSensorBrowserTest::SetBinderOnIOThread,
@@ -188,6 +203,12 @@ class GenericSensorBrowserTest : public ContentBrowserTest {
io_loop_finished_event_.Wait();
}
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ // HTTPS server only serves a valid cert for localhost, so this is needed
+ // to load pages from other hosts without an error.
+ command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
+ }
+
void SetBinderOnIOThread() {
// Because Device Service also runs in this process(browser process), here
// we can directly set our binder to intercept interface requests against
@@ -200,7 +221,11 @@ class GenericSensorBrowserTest : public ContentBrowserTest {
io_loop_finished_event_.Signal();
}
+ protected:
+ std::unique_ptr<net::EmbeddedTestServer> https_embedded_test_server_;
+
private:
+ base::test::ScopedFeatureList scoped_feature_list_;
base::WaitableEvent io_loop_finished_event_;
std::unique_ptr<FakeSensorProvider> fake_sensor_provider_;
@@ -216,6 +241,29 @@ IN_PROC_BROWSER_TEST_F(GenericSensorBrowserTest, AmbientLightSensorTest) {
EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
}
+IN_PROC_BROWSER_TEST_F(GenericSensorBrowserTest,
+ AmbientLightSensorCrossOriginIframeTest) {
+ // Main frame is on a.com, iframe is on b.com.
+ GURL main_frame_url =
+ https_embedded_test_server_->GetURL("a.com", "/cross_origin_iframe.html");
+ GURL iframe_url = https_embedded_test_server_->GetURL(
+ "b.com", "/ambient_light_sensor_cross_origin_iframe_test.html");
+
+ // Wait for the main frame, subframe, and the #pass/#fail commits.
+ TestNavigationObserver navigation_observer(shell()->web_contents(), 3);
+
+ EXPECT_TRUE(NavigateToURL(shell(), main_frame_url));
+ EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(),
+ "cross_origin_iframe", iframe_url));
+
+ navigation_observer.Wait();
+
+ content::RenderFrameHost* iframe =
+ ChildFrameAt(shell()->web_contents()->GetMainFrame(), 0);
+ ASSERT_TRUE(iframe);
+ EXPECT_EQ("pass", iframe->GetLastCommittedURL().ref());
+}
+
} // namespace
} // namespace content
diff --git a/chromium/content/browser/geolocation/geolocation_service_impl.cc b/chromium/content/browser/geolocation/geolocation_service_impl.cc
index a9f030d51f1..cf764612b5a 100644
--- a/chromium/content/browser/geolocation/geolocation_service_impl.cc
+++ b/chromium/content/browser/geolocation/geolocation_service_impl.cc
@@ -8,8 +8,7 @@
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_features.h"
-#include "device/geolocation/geolocation_context.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicyFeature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
namespace content {
@@ -19,16 +18,20 @@ GeolocationServiceImplContext::GeolocationServiceImplContext(
request_id_(PermissionManager::kNoPendingOperation) {}
GeolocationServiceImplContext::~GeolocationServiceImplContext() {
- if (request_id_ == PermissionManager::kNoPendingOperation)
- return;
-
- CancelPermissionRequest();
+ permission_manager_->CancelPermissionRequest(request_id_);
}
void GeolocationServiceImplContext::RequestPermission(
RenderFrameHost* render_frame_host,
bool user_gesture,
const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+ if (request_id_ != PermissionManager::kNoPendingOperation) {
+ mojo::ReportBadMessage(
+ "GeolocationService client may only create one Geolocation at a "
+ "time.");
+ return;
+ }
+
request_id_ = permission_manager_->RequestPermission(
PermissionType::GEOLOCATION, render_frame_host,
render_frame_host->GetLastCommittedOrigin().GetURL(), user_gesture,
@@ -38,18 +41,6 @@ void GeolocationServiceImplContext::RequestPermission(
base::Unretained(this), std::move(callback)));
}
-void GeolocationServiceImplContext::CancelPermissionRequest() {
- if (request_id_ == PermissionManager::kNoPendingOperation) {
- mojo::ReportBadMessage(
- "GeolocationService client may only create one Geolocation at a "
- "time.");
- return;
- }
-
- permission_manager_->CancelPermissionRequest(request_id_);
- request_id_ = PermissionManager::kNoPendingOperation;
-}
-
void GeolocationServiceImplContext::HandlePermissionStatus(
const base::Callback<void(blink::mojom::PermissionStatus)>& callback,
blink::mojom::PermissionStatus permission_status) {
@@ -58,7 +49,7 @@ void GeolocationServiceImplContext::HandlePermissionStatus(
}
GeolocationServiceImpl::GeolocationServiceImpl(
- device::GeolocationContext* geolocation_context,
+ device::mojom::GeolocationContext* geolocation_context,
PermissionManager* permission_manager,
RenderFrameHost* render_frame_host)
: geolocation_context_(geolocation_context),
@@ -72,10 +63,10 @@ GeolocationServiceImpl::GeolocationServiceImpl(
GeolocationServiceImpl::~GeolocationServiceImpl() {}
void GeolocationServiceImpl::Bind(
- device::mojom::GeolocationServiceRequest request) {
+ blink::mojom::GeolocationServiceRequest request) {
binding_set_.AddBinding(
this, std::move(request),
- base::MakeUnique<GeolocationServiceImplContext>(permission_manager_));
+ std::make_unique<GeolocationServiceImplContext>(permission_manager_));
}
void GeolocationServiceImpl::CreateGeolocation(
@@ -84,7 +75,7 @@ void GeolocationServiceImpl::CreateGeolocation(
if (base::FeatureList::IsEnabled(features::kFeaturePolicy) &&
base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions) &&
!render_frame_host_->IsFeatureEnabled(
- blink::WebFeaturePolicyFeature::kGeolocation)) {
+ blink::FeaturePolicyFeature::kGeolocation)) {
return;
}
@@ -102,7 +93,7 @@ void GeolocationServiceImpl::CreateGeolocationWithPermissionStatus(
if (permission_status != blink::mojom::PermissionStatus::GRANTED)
return;
- geolocation_context_->Bind(std::move(request));
+ geolocation_context_->BindGeolocation(std::move(request));
}
} // namespace content
diff --git a/chromium/content/browser/geolocation/geolocation_service_impl.h b/chromium/content/browser/geolocation/geolocation_service_impl.h
index e8af52b9ade..d7a37f52eb9 100644
--- a/chromium/content/browser/geolocation/geolocation_service_impl.h
+++ b/chromium/content/browser/geolocation/geolocation_service_impl.h
@@ -7,7 +7,9 @@
#include "content/common/content_export.h"
#include "device/geolocation/public/interfaces/geolocation.mojom.h"
+#include "device/geolocation/public/interfaces/geolocation_context.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
+#include "third_party/WebKit/public/platform/modules/geolocation/geolocation_service.mojom.h"
namespace blink {
namespace mojom {
@@ -15,10 +17,6 @@ enum class PermissionStatus;
}
} // namespace blink
-namespace device {
-class GeolocationContext;
-}
-
namespace content {
class RenderFrameHost;
class PermissionManager;
@@ -31,7 +29,6 @@ class GeolocationServiceImplContext {
RenderFrameHost* render_frame_host,
bool user_gesture,
const base::Callback<void(blink::mojom::PermissionStatus)>& callback);
- void CancelPermissionRequest();
private:
PermissionManager* permission_manager_;
@@ -44,15 +41,15 @@ class GeolocationServiceImplContext {
};
class CONTENT_EXPORT GeolocationServiceImpl
- : public device::mojom::GeolocationService {
+ : public blink::mojom::GeolocationService {
public:
- GeolocationServiceImpl(device::GeolocationContext* geolocation_context,
+ GeolocationServiceImpl(device::mojom::GeolocationContext* geolocation_context,
PermissionManager* permission_manager,
RenderFrameHost* render_frame_host);
~GeolocationServiceImpl() override;
// Binds to the GeolocationService.
- void Bind(device::mojom::GeolocationServiceRequest request);
+ void Bind(blink::mojom::GeolocationServiceRequest request);
// Creates a Geolocation instance.
// This may not be called a second time until the Geolocation instance has
@@ -66,14 +63,14 @@ class CONTENT_EXPORT GeolocationServiceImpl
device::mojom::GeolocationRequest request,
blink::mojom::PermissionStatus permission_status);
- device::GeolocationContext* geolocation_context_;
+ device::mojom::GeolocationContext* geolocation_context_;
PermissionManager* permission_manager_;
RenderFrameHost* render_frame_host_;
// Along with each GeolocationService, we store a
// GeolocationServiceImplContext which primarily exists to manage a
// Permission Request ID.
- mojo::BindingSet<device::mojom::GeolocationService,
+ mojo::BindingSet<blink::mojom::GeolocationService,
std::unique_ptr<GeolocationServiceImplContext>>
binding_set_;
diff --git a/chromium/content/browser/geolocation/geolocation_service_impl_unittest.cc b/chromium/content/browser/geolocation/geolocation_service_impl_unittest.cc
index c1d26024bfa..23e619a08fd 100644
--- a/chromium/content/browser/geolocation/geolocation_service_impl_unittest.cc
+++ b/chromium/content/browser/geolocation/geolocation_service_impl_unittest.cc
@@ -13,21 +13,19 @@
#include "content/test/mock_permission_manager.h"
#include "content/test/test_render_frame_host.h"
#include "device/geolocation/geolocation_context.h"
-#include "device/geolocation/geoposition.h"
#include "device/geolocation/public/interfaces/geolocation.mojom.h"
#include "device/geolocation/public/interfaces/geoposition.mojom.h"
#include "services/service_manager/public/cpp/bind_source_info.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicyFeature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
using base::test::ScopedFeatureList;
using blink::mojom::PermissionStatus;
using device::GeolocationContext;
-using device::Geoposition;
using device::mojom::GeolocationPtr;
using device::mojom::GeopositionPtr;
-using device::mojom::GeolocationService;
-using device::mojom::GeolocationServicePtr;
+using blink::mojom::GeolocationService;
+using blink::mojom::GeolocationServicePtr;
typedef base::Callback<void(PermissionStatus)> PermissionCallback;
@@ -57,8 +55,10 @@ class TestPermissionManager : public MockPermissionManager {
}
void CancelPermissionRequest(int request_id) override {
- EXPECT_EQ(request_id, request_id_);
- cancel_callback_.Run();
+ if (request_id != PermissionManager::kNoPendingOperation) {
+ EXPECT_EQ(request_id, request_id_);
+ cancel_callback_.Run();
+ }
}
void SetRequestId(int request_id) { request_id_ = request_id; }
@@ -95,8 +95,8 @@ class GeolocationServiceTest : public RenderViewHostImplTestHarness {
if (allow_via_feature_policy) {
RenderFrameHostTester::For(main_rfh())
->SimulateFeaturePolicyHeader(
- blink::WebFeaturePolicyFeature::kGeolocation,
- std::vector<url::Origin>{url::Origin(kEmbeddedUrl)});
+ blink::FeaturePolicyFeature::kGeolocation,
+ std::vector<url::Origin>{url::Origin::Create(kEmbeddedUrl)});
}
RenderFrameHost* embedded_rfh =
RenderFrameHostTester::For(main_rfh())->AppendChild("");
@@ -122,8 +122,10 @@ class GeolocationServiceTest : public RenderViewHostImplTestHarness {
}
private:
- std::unique_ptr<GeolocationServiceImpl> service_;
+ // The |permission_manager_| needs to come before the |service_| since
+ // GeolocationService calls PermissionManager in its destructor.
std::unique_ptr<TestPermissionManager> permission_manager_;
+ std::unique_ptr<GeolocationServiceImpl> service_;
GeolocationServicePtr service_ptr_;
GeolocationContext context_;
@@ -152,7 +154,7 @@ TEST_F(GeolocationServiceTest, PermissionGrantedPolicyViolation) {
geolocation->QueryNextPosition(base::BindOnce([](GeopositionPtr geoposition) {
ADD_FAILURE() << "Position updated unexpectedly";
}));
- auto mock_geoposition = base::MakeUnique<Geoposition>();
+ auto mock_geoposition = device::mojom::Geoposition::New();
mock_geoposition->latitude = kMockLatitude;
mock_geoposition->longitude = kMockLongitude;
context()->SetOverride(std::move(mock_geoposition));
@@ -184,7 +186,7 @@ TEST_F(GeolocationServiceTest, PermissionGrantedNoPolicyViolation) {
callback.Run();
},
loop.QuitClosure()));
- auto mock_geoposition = base::MakeUnique<Geoposition>();
+ auto mock_geoposition = device::mojom::Geoposition::New();
mock_geoposition->latitude = kMockLatitude;
mock_geoposition->longitude = kMockLongitude;
context()->SetOverride(std::move(mock_geoposition));
@@ -211,7 +213,7 @@ TEST_F(GeolocationServiceTest, PermissionGrantedSync) {
callback.Run();
},
loop.QuitClosure()));
- auto mock_geoposition = base::MakeUnique<Geoposition>();
+ auto mock_geoposition = device::mojom::Geoposition::New();
mock_geoposition->latitude = kMockLatitude;
mock_geoposition->longitude = kMockLongitude;
context()->SetOverride(std::move(mock_geoposition));
@@ -233,7 +235,7 @@ TEST_F(GeolocationServiceTest, PermissionDeniedSync) {
geolocation->QueryNextPosition(base::BindOnce([](GeopositionPtr geoposition) {
ADD_FAILURE() << "Position updated unexpectedly";
}));
- auto mock_geoposition = base::MakeUnique<Geoposition>();
+ auto mock_geoposition = device::mojom::Geoposition::New();
mock_geoposition->latitude = kMockLatitude;
mock_geoposition->longitude = kMockLongitude;
context()->SetOverride(std::move(mock_geoposition));
@@ -266,7 +268,7 @@ TEST_F(GeolocationServiceTest, PermissionGrantedAsync) {
callback.Run();
},
loop.QuitClosure()));
- auto mock_geoposition = base::MakeUnique<Geoposition>();
+ auto mock_geoposition = device::mojom::Geoposition::New();
mock_geoposition->latitude = kMockLatitude;
mock_geoposition->longitude = kMockLongitude;
context()->SetOverride(std::move(mock_geoposition));
@@ -294,7 +296,7 @@ TEST_F(GeolocationServiceTest, PermissionDeniedAsync) {
geolocation->QueryNextPosition(base::BindOnce([](GeopositionPtr geoposition) {
ADD_FAILURE() << "Position updated unexpectedly";
}));
- auto mock_geoposition = base::MakeUnique<Geoposition>();
+ auto mock_geoposition = device::mojom::Geoposition::New();
mock_geoposition->latitude = kMockLatitude;
mock_geoposition->longitude = kMockLongitude;
context()->SetOverride(std::move(mock_geoposition));
@@ -317,7 +319,7 @@ TEST_F(GeolocationServiceTest, ServiceClosedBeforePermissionResponse) {
geolocation->QueryNextPosition(base::BindOnce([](GeopositionPtr geoposition) {
ADD_FAILURE() << "Position updated unexpectedly";
}));
- auto mock_geoposition = base::MakeUnique<Geoposition>();
+ auto mock_geoposition = device::mojom::Geoposition::New();
mock_geoposition->latitude = kMockLatitude;
mock_geoposition->longitude = kMockLongitude;
context()->SetOverride(std::move(mock_geoposition));
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 9555552dc83..44577c7447a 100644
--- a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -11,6 +11,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/timer/timer.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
@@ -18,25 +19,29 @@
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/gpu/shader_cache_factory.h"
+#include "content/browser/mus_util.h"
#include "content/common/child_process_host_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/gpu_switches.h"
-#include "gpu/ipc/common/gpu_messages.h"
-#include "ipc/ipc_channel_handle.h"
-#include "ipc/message_filter.h"
#include "services/resource_coordinator/public/interfaces/memory_instrumentation/constants.mojom.h"
#include "services/service_manager/runner/common/client_util.h"
-
-#if defined(USE_AURA)
-#include "ui/aura/env.h"
-#endif
+#include "ui/base/ui_base_switches_util.h"
namespace content {
-BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL;
+#if defined(OS_ANDROID)
+namespace {
+void TimedOut() {
+ LOG(FATAL) << "Timed out waiting for GPU channel.";
+}
+} // namespace
+#endif // OS_ANDROID
+
+BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = nullptr;
class BrowserGpuChannelHostFactory::EstablishRequest
: public base::RefCountedThreadSafe<EstablishRequest> {
@@ -46,7 +51,9 @@ class BrowserGpuChannelHostFactory::EstablishRequest
void Wait();
void Cancel();
- IPC::ChannelHandle& channel_handle() { return channel_handle_; }
+ mojo::ScopedMessagePipeHandle TakeChannelHandle() {
+ return std::move(channel_handle_);
+ }
const gpu::GPUInfo& gpu_info() const { return gpu_info_; }
const gpu::GpuFeatureInfo& gpu_feature_info() const {
return gpu_feature_info_;
@@ -54,10 +61,11 @@ class BrowserGpuChannelHostFactory::EstablishRequest
private:
friend class base::RefCountedThreadSafe<EstablishRequest>;
- explicit EstablishRequest(int gpu_client_id, uint64_t gpu_client_tracing_id);
+ EstablishRequest(int gpu_client_id, uint64_t gpu_client_tracing_id);
~EstablishRequest() {}
+ void RestartTimeout();
void EstablishOnIO();
- void OnEstablishedOnIO(const IPC::ChannelHandle& channel_handle,
+ void OnEstablishedOnIO(mojo::ScopedMessagePipeHandle channel_handle,
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info,
GpuProcessHost::EstablishChannelStatus status);
@@ -67,7 +75,7 @@ class BrowserGpuChannelHostFactory::EstablishRequest
base::WaitableEvent event_;
const int gpu_client_id_;
const uint64_t gpu_client_tracing_id_;
- IPC::ChannelHandle channel_handle_;
+ mojo::ScopedMessagePipeHandle channel_handle_;
gpu::GPUInfo gpu_info_;
gpu::GpuFeatureInfo gpu_feature_info_;
bool finished_;
@@ -101,6 +109,12 @@ BrowserGpuChannelHostFactory::EstablishRequest::EstablishRequest(
finished_(false),
main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
+void BrowserGpuChannelHostFactory::EstablishRequest::RestartTimeout() {
+ BrowserGpuChannelHostFactory* factory =
+ BrowserGpuChannelHostFactory::instance();
+ factory->RestartTimeout();
+}
+
void BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO() {
GpuProcessHost* host = GpuProcessHost::Get();
if (!host) {
@@ -121,18 +135,26 @@ void BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO() {
}
void BrowserGpuChannelHostFactory::EstablishRequest::OnEstablishedOnIO(
- const IPC::ChannelHandle& channel_handle,
+ mojo::ScopedMessagePipeHandle channel_handle,
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info,
GpuProcessHost::EstablishChannelStatus status) {
- if (!channel_handle.mojo_handle.is_valid() &&
- status == GpuProcessHost::EstablishChannelStatus::GPU_HOST_INVALID) {
+ if (!channel_handle.is_valid() &&
+ status == GpuProcessHost::EstablishChannelStatus::GPU_HOST_INVALID &&
+ // Ask client every time instead of passing this down from UI thread to
+ // avoid having the value be stale.
+ GetContentClient()->browser()->AllowGpuLaunchRetryOnIOThread()) {
DVLOG(1) << "Failed to create channel on existing GPU process. Trying to "
"restart GPU process.";
+ main_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &BrowserGpuChannelHostFactory::EstablishRequest::RestartTimeout,
+ this));
EstablishOnIO();
return;
}
- channel_handle_ = channel_handle;
+ channel_handle_ = std::move(channel_handle);
gpu_info_ = gpu_info;
gpu_feature_info_ = gpu_feature_info;
FinishOnIO();
@@ -194,16 +216,13 @@ void BrowserGpuChannelHostFactory::Initialize(bool establish_gpu_channel) {
void BrowserGpuChannelHostFactory::Terminate() {
DCHECK(instance_);
delete instance_;
- instance_ = NULL;
+ instance_ = nullptr;
}
BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
: gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
gpu_client_tracing_id_(
memory_instrumentation::mojom::kServiceTracingProcessId),
- shutdown_event_(new base::WaitableEvent(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED)),
gpu_memory_buffer_manager_(
new BrowserGpuMemoryBufferManager(gpu_client_id_,
gpu_client_tracing_id_)) {
@@ -213,8 +232,8 @@ BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
base::FilePath cache_dir =
GetContentClient()->browser()->GetShaderDiskCacheDirectory();
if (!cache_dir.empty()) {
- GetIOThreadTaskRunner()->PostTask(
- FROM_HERE,
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
base::BindOnce(
&BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO,
gpu_client_id_, cache_dir));
@@ -223,50 +242,33 @@ BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
}
BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() {
- DCHECK(IsMainThread());
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (pending_request_.get())
pending_request_->Cancel();
- shutdown_event_->Signal();
if (gpu_channel_) {
gpu_channel_->DestroyChannel();
- gpu_channel_ = NULL;
+ gpu_channel_ = nullptr;
}
}
-bool BrowserGpuChannelHostFactory::IsMainThread() {
- return BrowserThread::CurrentlyOn(BrowserThread::UI);
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-BrowserGpuChannelHostFactory::GetIOThreadTaskRunner() {
- return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
-}
-
-std::unique_ptr<base::SharedMemory>
-BrowserGpuChannelHostFactory::AllocateSharedMemory(size_t size) {
- std::unique_ptr<base::SharedMemory> shm(new base::SharedMemory());
- if (!shm->CreateAnonymous(size))
- return std::unique_ptr<base::SharedMemory>();
- return shm;
-}
-
void BrowserGpuChannelHostFactory::EstablishGpuChannel(
const gpu::GpuChannelEstablishedCallback& callback) {
#if defined(USE_AURA)
- DCHECK_EQ(aura::Env::Mode::LOCAL, aura::Env::GetInstance()->mode());
+ DCHECK(!switches::IsMusHostingViz());
#endif
- DCHECK(IsMainThread());
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (gpu_channel_.get() && gpu_channel_->IsLost()) {
DCHECK(!pending_request_.get());
// Recreate the channel if it has been lost.
gpu_channel_->DestroyChannel();
- gpu_channel_ = NULL;
+ gpu_channel_ = nullptr;
}
if (!gpu_channel_.get() && !pending_request_.get()) {
// We should only get here if the context was lost.
pending_request_ =
EstablishRequest::Create(gpu_client_id_, gpu_client_tracing_id_);
+ RestartTimeout();
}
if (!callback.is_null()) {
@@ -281,11 +283,13 @@ void BrowserGpuChannelHostFactory::EstablishGpuChannel(
// (Opening the initial channel to a child process involves handling a reply
// task on the UI thread first, so we cannot block here.)
scoped_refptr<gpu::GpuChannelHost>
-BrowserGpuChannelHostFactory::EstablishGpuChannelSync() {
+BrowserGpuChannelHostFactory::EstablishGpuChannelSync(bool* connection_error) {
#if defined(OS_ANDROID)
NOTREACHED();
return nullptr;
#endif
+ if (connection_error)
+ *connection_error = false;
EstablishGpuChannel(gpu::GpuChannelEstablishedCallback());
if (pending_request_.get())
@@ -303,23 +307,25 @@ gpu::GpuChannelHost* BrowserGpuChannelHostFactory::GetGpuChannel() {
if (gpu_channel_.get() && !gpu_channel_->IsLost())
return gpu_channel_.get();
- return NULL;
+ return nullptr;
}
void BrowserGpuChannelHostFactory::GpuChannelEstablished() {
- DCHECK(IsMainThread());
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(pending_request_.get());
- if (!pending_request_->channel_handle().mojo_handle.is_valid()) {
+ mojo::ScopedMessagePipeHandle handle(pending_request_->TakeChannelHandle());
+ if (!handle.is_valid()) {
DCHECK(!gpu_channel_.get());
} else {
GetContentClient()->SetGpuInfo(pending_request_->gpu_info());
- gpu_channel_ = gpu::GpuChannelHost::Create(
- this, gpu_client_id_, pending_request_->gpu_info(),
- pending_request_->gpu_feature_info(),
- pending_request_->channel_handle(), shutdown_event_.get(),
+ gpu_channel_ = base::MakeRefCounted<gpu::GpuChannelHost>(
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ gpu_client_id_, pending_request_->gpu_info(),
+ pending_request_->gpu_feature_info(), std::move(handle),
gpu_memory_buffer_manager_.get());
}
- pending_request_ = NULL;
+ pending_request_ = nullptr;
+ timeout_.Stop();
std::vector<gpu::GpuChannelEstablishedCallback> established_callbacks;
established_callbacks_.swap(established_callbacks);
@@ -327,6 +333,33 @@ void BrowserGpuChannelHostFactory::GpuChannelEstablished() {
callback.Run(gpu_channel_);
}
+void BrowserGpuChannelHostFactory::RestartTimeout() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+// Only implement timeout on Android, which does not have a software fallback.
+#if defined(OS_ANDROID)
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableTimeoutsForProfiling)) {
+ return;
+ }
+
+ if (!pending_request_)
+ return;
+
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
+ defined(SYZYASAN) || defined(CYGPROFILE_INSTRUMENTATION)
+ constexpr int64_t kGpuChannelTimeoutInSeconds = 40;
+#else
+ // The GPU watchdog timeout is 15 seconds (1.5x the kGpuTimeout value due to
+ // logic in GpuWatchdogThread). Make this slightly longer to give the GPU a
+ // chance to crash itself before crashing the browser.
+ constexpr int64_t kGpuChannelTimeoutInSeconds = 20;
+#endif
+ timeout_.Start(FROM_HERE,
+ base::TimeDelta::FromSeconds(kGpuChannelTimeoutInSeconds),
+ base::Bind(&TimedOut));
+#endif // OS_ANDROID
+}
+
// static
void BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO(
int gpu_client_id,
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 a2ba4d1fff5..b425c3148a4 100644
--- a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -24,19 +24,12 @@ namespace content {
class BrowserGpuMemoryBufferManager;
class CONTENT_EXPORT BrowserGpuChannelHostFactory
- : public gpu::GpuChannelHostFactory,
- public gpu::GpuChannelEstablishFactory {
+ : public gpu::GpuChannelEstablishFactory {
public:
static void Initialize(bool establish_gpu_channel);
static void Terminate();
static BrowserGpuChannelHostFactory* instance() { return instance_; }
- // Overridden from gpu::GpuChannelHostFactory:
- bool IsMainThread() override;
- scoped_refptr<base::SingleThreadTaskRunner> GetIOThreadTaskRunner() override;
- std::unique_ptr<base::SharedMemory> AllocateSharedMemory(
- size_t size) override;
-
gpu::GpuChannelHost* GetGpuChannel();
int GetGpuChannelId() { return gpu_client_id_; }
@@ -49,7 +42,8 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
// shutdown.
void EstablishGpuChannel(
const gpu::GpuChannelEstablishedCallback& callback) override;
- scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync() override;
+ scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync(
+ bool* connection_error) override;
gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
private:
@@ -60,18 +54,20 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
~BrowserGpuChannelHostFactory() override;
void GpuChannelEstablished();
+ void RestartTimeout();
static void InitializeShaderDiskCacheOnIO(int gpu_client_id,
const base::FilePath& cache_dir);
const int gpu_client_id_;
const uint64_t gpu_client_tracing_id_;
- std::unique_ptr<base::WaitableEvent> shutdown_event_;
scoped_refptr<gpu::GpuChannelHost> gpu_channel_;
std::unique_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager_;
scoped_refptr<EstablishRequest> pending_request_;
std::vector<gpu::GpuChannelEstablishedCallback> established_callbacks_;
+ base::OneShotTimer timeout_;
+
static BrowserGpuChannelHostFactory* instance_;
DISALLOW_COPY_AND_ASSIGN(BrowserGpuChannelHostFactory);
diff --git a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
index ba34e093eca..bab50551cf8 100644
--- a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
+++ b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -136,7 +136,7 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess(
}
auto handle = gpu::GpuMemoryBufferImplSharedMemory::CreateGpuMemoryBuffer(
- id, size, format);
+ id, size, format, usage);
buffers.find(id)->second.shared_memory_guid = handle.handle.GetGUID();
callback.Run(handle);
}
@@ -292,7 +292,7 @@ void BrowserGpuMemoryBufferManager::HandleCreateGpuMemoryBufferOnIO(
// Note: Unretained is safe as IO thread is stopped before manager is
// destroyed.
request->result = gpu::GpuMemoryBufferImplSharedMemory::Create(
- new_id, request->size, request->format,
+ new_id, request->size, request->format, request->usage,
base::Bind(
&GpuMemoryBufferDeleted,
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
diff --git a/chromium/content/browser/gpu/compositor_util.cc b/chromium/content/browser/gpu/compositor_util.cc
index 122282d3cc7..53031f36825 100644
--- a/chromium/content/browser/gpu/compositor_util.cc
+++ b/chromium/content/browser/gpu/compositor_util.cc
@@ -20,7 +20,6 @@
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
-#include "content/public/browser/gpu_utils.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "gpu/config/gpu_feature_type.h"
@@ -64,7 +63,6 @@ const GpuFeatureInfo GetGpuFeatureInfo(size_t index, bool* eof) {
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
- gpu::GpuPreferences gpu_preferences = GetGpuPreferencesFromCommandLine();
const GpuFeatureInfo kGpuFeatureInfo[] = {
{"2d_canvas",
@@ -109,23 +107,6 @@ const GpuFeatureInfo GetGpuFeatureInfo(size_t index, bool* eof) {
"Accelerated video decode has been disabled, either via blacklist,"
" about:flags or the command line.",
true},
-#if BUILDFLAG(ENABLE_WEBRTC)
- {"video_encode",
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE),
- command_line.HasSwitch(switches::kDisableWebRtcHWEncoding),
- "Accelerated video encode has been disabled, either via blacklist,"
- " about:flags or the command line.",
- true},
-#endif
-#if defined(OS_CHROMEOS)
- {"panel_fitting",
- manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING),
- command_line.HasSwitch(switches::kDisablePanelFitting),
- "Panel fitting has been disabled, either via blacklist, about:flags or"
- " the command line.",
- false},
-#endif
{kRasterizationFeatureName,
IsGpuRasterizationBlacklisted() && !IsGpuRasterizationEnabled() &&
!IsForceGpuRasterizationEnabled(),
@@ -294,9 +275,6 @@ bool IsCheckerImagingEnabled() {
}
bool IsGpuAsyncWorkerContextEnabled() {
- if (!base::FeatureList::IsEnabled(features::kGpuScheduler))
- return false;
-
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGpuAsyncWorkerContext))
return false;
@@ -321,7 +299,7 @@ std::unique_ptr<base::DictionaryValue> GetFeatureStatus() {
bool gpu_access_blocked =
!manager->GpuAccessAllowed(&gpu_access_blocked_reason);
- auto feature_status_dict = base::MakeUnique<base::DictionaryValue>();
+ auto feature_status_dict = std::make_unique<base::DictionaryValue>();
bool eof = false;
for (size_t i = 0; !eof; ++i) {
@@ -384,15 +362,15 @@ std::unique_ptr<base::ListValue> GetProblems() {
bool gpu_access_blocked =
!manager->GpuAccessAllowed(&gpu_access_blocked_reason);
- auto problem_list = base::MakeUnique<base::ListValue>();
+ auto problem_list = std::make_unique<base::ListValue>();
manager->GetBlacklistReasons(problem_list.get());
if (gpu_access_blocked) {
- auto problem = base::MakeUnique<base::DictionaryValue>();
+ auto problem = std::make_unique<base::DictionaryValue>();
problem->SetString("description",
"GPU process was unable to boot: " + gpu_access_blocked_reason);
- problem->Set("crBugs", base::MakeUnique<base::ListValue>());
- auto disabled_features = base::MakeUnique<base::ListValue>();
+ problem->Set("crBugs", std::make_unique<base::ListValue>());
+ auto disabled_features = std::make_unique<base::ListValue>();
disabled_features->AppendString("all");
problem->Set("affectedGpuSettings", std::move(disabled_features));
problem->SetString("tag", "disabledFeatures");
diff --git a/chromium/content/browser/gpu/gpu_client.cc b/chromium/content/browser/gpu/gpu_client.cc
index a3f9c1e0c23..a1e66633311 100644
--- a/chromium/content/browser/gpu/gpu_client.cc
+++ b/chromium/content/browser/gpu/gpu_client.cc
@@ -4,7 +4,6 @@
#include "content/browser/gpu/gpu_client.h"
-#include "build/build_config.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/common/child_process_host_impl.h"
@@ -22,6 +21,7 @@ GpuClient::GpuClient(int render_process_id)
}
GpuClient::~GpuClient() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
bindings_.CloseAllBindings();
OnError();
}
@@ -31,6 +31,7 @@ void GpuClient::Add(ui::mojom::GpuRequest request) {
}
void GpuClient::OnError() {
+ ClearCallback();
if (!bindings_.empty())
return;
BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager =
@@ -39,33 +40,43 @@ void GpuClient::OnError() {
gpu_memory_buffer_manager->ProcessRemoved(render_process_id_);
}
+void GpuClient::PreEstablishGpuChannel() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&GpuClient::EstablishGpuChannel, base::Unretained(this),
+ EstablishGpuChannelCallback()));
+}
+
void GpuClient::OnEstablishGpuChannel(
- const EstablishGpuChannelCallback& callback,
- const IPC::ChannelHandle& channel,
+ mojo::ScopedMessagePipeHandle channel_handle,
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info,
GpuProcessHost::EstablishChannelStatus status) {
-#if !defined(OS_ANDROID)
- if (status == GpuProcessHost::EstablishChannelStatus::GPU_ACCESS_DENIED) {
- // GPU access is not allowed. Notify the client immediately.
- DCHECK(!channel.mojo_handle.is_valid());
- callback.Run(render_process_id_, mojo::ScopedMessagePipeHandle(), gpu_info,
- gpu_feature_info);
- return;
- }
+ DCHECK_EQ(channel_handle.is_valid(),
+ status == GpuProcessHost::EstablishChannelStatus::SUCCESS);
+ gpu_channel_requested_ = false;
+ EstablishGpuChannelCallback callback = std::move(callback_);
+ DCHECK(!callback_);
if (status == GpuProcessHost::EstablishChannelStatus::GPU_HOST_INVALID) {
// GPU process may have crashed or been killed. Try again.
- DCHECK(!channel.mojo_handle.is_valid());
EstablishGpuChannel(callback);
return;
}
- DCHECK(channel.mojo_handle.is_valid());
-#endif
- mojo::ScopedMessagePipeHandle channel_handle;
- channel_handle.reset(channel.mojo_handle);
- callback.Run(render_process_id_, std::move(channel_handle), gpu_info,
- gpu_feature_info);
+ if (callback) {
+ // A request is waiting.
+ callback.Run(render_process_id_, std::move(channel_handle), gpu_info,
+ gpu_feature_info);
+ return;
+ }
+ if (status == GpuProcessHost::EstablishChannelStatus::SUCCESS) {
+ // This is the case we pre-establish a channel before a request arrives.
+ // Cache the channel for a future request.
+ channel_handle_ = std::move(channel_handle);
+ gpu_info_ = gpu_info;
+ gpu_feature_info_ = gpu_feature_info;
+ }
}
void GpuClient::OnCreateGpuMemoryBuffer(
@@ -74,16 +85,44 @@ void GpuClient::OnCreateGpuMemoryBuffer(
callback.Run(handle);
}
+void GpuClient::ClearCallback() {
+ if (!callback_)
+ return;
+ EstablishGpuChannelCallback callback = std::move(callback_);
+ callback.Run(render_process_id_, mojo::ScopedMessagePipeHandle(),
+ gpu::GPUInfo(), gpu::GpuFeatureInfo());
+ DCHECK(!callback_);
+}
+
void GpuClient::EstablishGpuChannel(
const EstablishGpuChannelCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // At most one channel should be requested. So clear previous request first.
+ ClearCallback();
+ if (channel_handle_.is_valid()) {
+ // If a channel has been pre-established and cached,
+ // 1) if callback is valid, return it right away.
+ // 2) if callback is empty, it's PreEstablishGpyChannel() being called
+ // more than once, no need to do anything.
+ if (callback) {
+ callback.Run(render_process_id_, std::move(channel_handle_), gpu_info_,
+ gpu_feature_info_);
+ DCHECK(!channel_handle_.is_valid());
+ }
+ return;
+ }
GpuProcessHost* host = GpuProcessHost::Get();
if (!host) {
- OnEstablishGpuChannel(
- callback, IPC::ChannelHandle(), gpu::GPUInfo(), gpu::GpuFeatureInfo(),
- GpuProcessHost::EstablishChannelStatus::GPU_ACCESS_DENIED);
+ if (callback) {
+ callback.Run(render_process_id_, mojo::ScopedMessagePipeHandle(),
+ gpu::GPUInfo(), gpu::GpuFeatureInfo());
+ }
return;
}
-
+ callback_ = callback;
+ if (gpu_channel_requested_)
+ return;
+ gpu_channel_requested_ = true;
bool preempts = false;
bool allow_view_command_buffers = false;
bool allow_real_time_streams = false;
@@ -92,12 +131,12 @@ void GpuClient::EstablishGpuChannel(
ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
render_process_id_),
preempts, allow_view_command_buffers, allow_real_time_streams,
- base::Bind(&GpuClient::OnEstablishGpuChannel, weak_factory_.GetWeakPtr(),
- callback));
+ base::Bind(&GpuClient::OnEstablishGpuChannel,
+ weak_factory_.GetWeakPtr()));
}
void GpuClient::CreateJpegDecodeAccelerator(
- media::mojom::GpuJpegDecodeAcceleratorRequest jda_request) {
+ media::mojom::JpegDecodeAcceleratorRequest jda_request) {
GpuProcessHost* host = GpuProcessHost::Get();
if (host)
host->gpu_service()->CreateJpegDecodeAccelerator(std::move(jda_request));
diff --git a/chromium/content/browser/gpu/gpu_client.h b/chromium/content/browser/gpu/gpu_client.h
index 3f982de4049..a0a36fa2623 100644
--- a/chromium/content/browser/gpu/gpu_client.h
+++ b/chromium/content/browser/gpu/gpu_client.h
@@ -7,7 +7,6 @@
#include "base/memory/weak_ptr.h"
#include "content/browser/gpu/gpu_process_host.h"
-#include "ipc/ipc_channel_handle.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/ui/public/interfaces/gpu.mojom.h"
@@ -20,21 +19,23 @@ class GpuClient : public ui::mojom::Gpu {
void Add(ui::mojom::GpuRequest request);
+ void PreEstablishGpuChannel();
+
private:
void OnError();
- void OnEstablishGpuChannel(const EstablishGpuChannelCallback& callback,
- const IPC::ChannelHandle& channel,
+ void OnEstablishGpuChannel(mojo::ScopedMessagePipeHandle channel_handle,
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info,
GpuProcessHost::EstablishChannelStatus status);
void OnCreateGpuMemoryBuffer(const CreateGpuMemoryBufferCallback& callback,
const gfx::GpuMemoryBufferHandle& handle);
+ void ClearCallback();
// ui::mojom::Gpu overrides:
void EstablishGpuChannel(
const EstablishGpuChannelCallback& callback) override;
void CreateJpegDecodeAccelerator(
- media::mojom::GpuJpegDecodeAcceleratorRequest jda_request) override;
+ media::mojom::JpegDecodeAcceleratorRequest jda_request) override;
void CreateVideoEncodeAcceleratorProvider(
media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request)
override;
@@ -49,6 +50,11 @@ class GpuClient : public ui::mojom::Gpu {
const int render_process_id_;
mojo::BindingSet<ui::mojom::Gpu> bindings_;
+ bool gpu_channel_requested_ = false;
+ EstablishGpuChannelCallback callback_;
+ mojo::ScopedMessagePipeHandle channel_handle_;
+ gpu::GPUInfo gpu_info_;
+ gpu::GpuFeatureInfo gpu_feature_info_;
base::WeakPtrFactory<GpuClient> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(GpuClient);
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl.cc b/chromium/content/browser/gpu/gpu_data_manager_impl.cc
index 1400bc7fc9c..fc442119e19 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl.cc
@@ -51,7 +51,7 @@ void GpuDataManagerImpl::BlacklistWebGLForTesting() {
0, // exceptions count
nullptr, // exceptions
};
- static const gpu::GpuControlListData kData("1.0", 1, &kEntry);
+ static const gpu::GpuControlListData kData(1, &kEntry);
gpu::GPUInfo gpu_info;
@@ -165,11 +165,6 @@ bool GpuDataManagerImpl::HardwareAccelerationEnabled() const {
private_->GpuAccessAllowed(nullptr);
}
-bool GpuDataManagerImpl::CanUseGpuBrowserCompositor() const {
- base::AutoLock auto_lock(lock_);
- return private_->CanUseGpuBrowserCompositor();
-}
-
void GpuDataManagerImpl::GetDisabledExtensions(
std::string* disabled_extensions) const {
base::AutoLock auto_lock(lock_);
@@ -226,16 +221,6 @@ void GpuDataManagerImpl::UpdateGpuPreferences(
private_->UpdateGpuPreferences(gpu_preferences);
}
-std::string GpuDataManagerImpl::GetBlacklistVersion() const {
- base::AutoLock auto_lock(lock_);
- return private_->GetBlacklistVersion();
-}
-
-std::string GpuDataManagerImpl::GetDriverBugListVersion() const {
- base::AutoLock auto_lock(lock_);
- return private_->GetDriverBugListVersion();
-}
-
void GpuDataManagerImpl::GetBlacklistReasons(base::ListValue* reasons) const {
base::AutoLock auto_lock(lock_);
private_->GetBlacklistReasons(reasons);
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl.h b/chromium/content/browser/gpu/gpu_data_manager_impl.h
index 430ffc347fc..6f81e672768 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl.h
@@ -95,7 +95,6 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager {
std::string* gl_version) override;
void DisableHardwareAcceleration() override;
bool HardwareAccelerationEnabled() const override;
- bool CanUseGpuBrowserCompositor() const override;
void GetDisabledExtensions(std::string* disabled_extensions) const override;
void SetGpuInfo(const gpu::GPUInfo& gpu_info) override;
@@ -130,9 +129,6 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager {
// Update GpuPreferences based on blacklisting decisions.
void UpdateGpuPreferences(gpu::GpuPreferences* gpu_preferences) const;
- std::string GetBlacklistVersion() const;
- std::string GetDriverBugListVersion() const;
-
// Returns the reasons for the latest run of blacklisting decisions.
// For the structure of returned value, see documentation for
// GpuBlacklist::GetBlacklistedReasons().
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 51aa672cb2f..47d2eebcee4 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -27,6 +27,7 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/gpu_data_manager_observer.h"
+#include "content/public/browser/gpu_utils.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
@@ -41,6 +42,7 @@
#include "gpu/config/gpu_switches.h"
#include "gpu/config/gpu_util.h"
#include "gpu/config/software_rendering_list_autogen.h"
+#include "gpu/ipc/common/gpu_preferences_util.h"
#include "gpu/ipc/common/memory_stats.h"
#include "gpu/ipc/host/shader_disk_cache.h"
#include "gpu/ipc/service/switches.h"
@@ -335,14 +337,6 @@ void GpuDataManagerImplPrivate::InitializeForTesting(
}
bool GpuDataManagerImplPrivate::IsFeatureBlacklisted(int feature) const {
-#if defined(OS_CHROMEOS)
- if (feature == gpu::GPU_FEATURE_TYPE_PANEL_FITTING &&
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisablePanelFitting)) {
- return true;
- }
-#endif // OS_CHROMEOS
-
// SwiftShader blacklists all features
return use_swiftshader_ || (blacklisted_features_.count(feature) == 1);
}
@@ -646,14 +640,12 @@ void GpuDataManagerImplPrivate::Initialize() {
if (!force_software_gl &&
!command_line->HasSwitch(switches::kIgnoreGpuBlacklist) &&
!command_line->HasSwitch(switches::kUseGpuInTests)) {
- gpu_blacklist_data = {gpu::kSoftwareRenderingListVersion,
- gpu::kSoftwareRenderingListEntryCount,
+ gpu_blacklist_data = {gpu::kSoftwareRenderingListEntryCount,
gpu::kSoftwareRenderingListEntries};
}
InitializeImpl(gpu_blacklist_data, gpu_info);
if (in_process_gpu_) {
- command_line->AppendSwitch(switches::kDisableGpuWatchdog);
AppendGpuCommandLine(command_line);
}
}
@@ -718,17 +710,17 @@ void GpuDataManagerImplPrivate::AppendRendererCommandLine(
if (ShouldDisableAcceleratedVideoDecode(command_line))
command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
-
-#if defined(USE_AURA)
- if (!CanUseGpuBrowserCompositor())
- command_line->AppendSwitch(switches::kDisableGpuCompositing);
-#endif
}
void GpuDataManagerImplPrivate::AppendGpuCommandLine(
base::CommandLine* command_line) const {
DCHECK(command_line);
+ gpu::GpuPreferences gpu_prefs = GetGpuPreferencesFromCommandLine();
+ UpdateGpuPreferences(&gpu_prefs);
+ command_line->AppendSwitchASCII(switches::kGpuPreferences,
+ gpu::GpuPreferencesToSwitchValue(gpu_prefs));
+
std::string use_gl =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kUseGL);
@@ -747,10 +739,6 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine(
command_line->AppendSwitchASCII(switches::kUseGL, use_gl);
}
- if (ShouldDisableAcceleratedVideoDecode(command_line)) {
- command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
- }
-
#if defined(USE_OZONE)
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableDrmAtomic)) {
@@ -815,16 +803,12 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine(
void GpuDataManagerImplPrivate::UpdateRendererWebPrefs(
WebPreferences* prefs) const {
DCHECK(prefs);
-
-#if defined(USE_AURA)
- if (!CanUseGpuBrowserCompositor()) {
- prefs->accelerated_2d_canvas_enabled = false;
- prefs->pepper_3d_enabled = false;
- }
-#endif
-
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
+ // TODO(zmo): Remove this when we check on the renderer side for 2d canvas.
+ if (command_line->HasSwitch(switches::kDisableGpuCompositing)) {
+ prefs->accelerated_2d_canvas_enabled = false;
+ }
if (!ShouldDisableAcceleratedVideoDecode(command_line) &&
!command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
prefs->pepper_accelerated_video_decode_enabled = true;
@@ -835,14 +819,6 @@ void GpuDataManagerImplPrivate::UpdateGpuPreferences(
gpu::GpuPreferences* gpu_preferences) const {
DCHECK(gpu_preferences);
- const base::CommandLine* command_line =
- base::CommandLine::ForCurrentProcess();
-
- if (base::FeatureList::IsEnabled(features::kGpuScheduler))
- gpu_preferences->enable_gpu_scheduler = true;
-
- if (ShouldDisableAcceleratedVideoDecode(command_line))
- gpu_preferences->disable_accelerated_video_decode = true;
gpu_preferences->gpu_program_cache_size =
gpu::ShaderDiskCache::CacheSizeBytes();
@@ -871,22 +847,6 @@ void GpuDataManagerImplPrivate::SetGpuInfo(const gpu::GPUInfo& gpu_info) {
DCHECK(IsCompleteGpuInfoAvailable());
}
-std::string GpuDataManagerImplPrivate::GetBlacklistVersion() const {
- if (gpu_blacklist_)
- return gpu_blacklist_->version();
- return "0";
-}
-
-std::string GpuDataManagerImplPrivate::GetDriverBugListVersion() const {
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGpuDriverBugWorkarounds)) {
- std::unique_ptr<gpu::GpuDriverBugList> bug_list(
- gpu::GpuDriverBugList::Create());
- return bug_list->version();
- }
- return "0";
-}
-
void GpuDataManagerImplPrivate::GetBlacklistReasons(
base::ListValue* reasons) const {
if (gpu_blacklist_)
@@ -935,7 +895,7 @@ void GpuDataManagerImplPrivate::ProcessCrashed(
std::unique_ptr<base::ListValue> GpuDataManagerImplPrivate::GetLogMessages()
const {
- auto value = base::MakeUnique<base::ListValue>();
+ auto value = std::make_unique<base::ListValue>();
for (size_t ii = 0; ii < log_messages_.size(); ++ii) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("level", log_messages_[ii].level);
@@ -997,33 +957,14 @@ bool GpuDataManagerImplPrivate::UpdateActiveGpu(uint32_t vendor_id,
return true;
}
-bool GpuDataManagerImplPrivate::CanUseGpuBrowserCompositor() const {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGpuCompositing))
- return false;
- if (ShouldUseSwiftShader())
- return false;
- if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING))
- return false;
- return true;
-}
-
bool GpuDataManagerImplPrivate::ShouldDisableAcceleratedVideoDecode(
const base::CommandLine* command_line) const {
- // Make sure that we initialize the experiment first to make sure that
- // statistics are bucket correctly in all cases.
- // This experiment is temporary and will be removed once enough data
- // to resolve crbug/442039 has been collected.
- const std::string group_name = base::FieldTrialList::FindFullName(
- "DisableAcceleratedVideoDecode");
if (command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
// It was already disabled on the command line.
return false;
}
if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE))
return true;
- if (group_name == "Disabled")
- return true;
// Accelerated decode is never available with --disable-gpu.
return ShouldDisableHardwareAcceleration();
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 6b04e9fd3dc..369d07b0b58 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -81,9 +81,6 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
void UpdateGpuPreferences(gpu::GpuPreferences* gpu_preferences) const;
- std::string GetBlacklistVersion() const;
- std::string GetDriverBugListVersion() const;
-
void GetBlacklistReasons(base::ListValue* reasons) const;
std::vector<std::string> GetDriverBugWorkarounds() const;
@@ -98,7 +95,6 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
void HandleGpuSwitch();
- bool CanUseGpuBrowserCompositor() const;
bool ShouldDisableAcceleratedVideoDecode(
const base::CommandLine* command_line) const;
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 aad34184776..ece02a8126d 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
@@ -144,7 +144,7 @@ TEST_F(GpuDataManagerImplPrivateTest, GpuSideBlacklisting) {
gpu::kGpuDataManagerTestingEntries
[gpu::kGpuDataManagerImplPrivateTest_GpuSideBlacklisting_1],
};
- const gpu::GpuControlListData kData("1.0", 2, kEntries);
+ const gpu::GpuControlListData kData(2, kEntries);
gpu::GPUInfo gpu_info;
gpu_info.gpu.vendor_id = 0x10de;
@@ -202,7 +202,7 @@ TEST_F(GpuDataManagerImplPrivateTest, GpuSideBlacklistingWebGL) {
gpu::kGpuDataManagerTestingEntries
[gpu::kGpuDataManagerImplPrivateTest_GpuSideBlacklistingWebGL_1],
};
- const gpu::GpuControlListData kData("1.0", 2, kEntries);
+ const gpu::GpuControlListData kData(2, kEntries);
gpu::GPUInfo gpu_info;
gpu_info.gpu.vendor_id = 0x10de;
@@ -242,20 +242,20 @@ TEST_F(GpuDataManagerImplPrivateTest, GpuSideBlacklistingWebGL) {
TEST_F(GpuDataManagerImplPrivateTest, GpuSideExceptions) {
ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
const gpu::GpuControlList::Entry kEntries[] = {
gpu::kGpuDataManagerTestingEntries
[gpu::kGpuDataManagerImplPrivateTest_GpuSideException],
};
- const gpu::GpuControlListData kData("1.0", 1, kEntries);
+ const gpu::GpuControlListData kData(1, kEntries);
gpu::GPUInfo gpu_info;
gpu_info.gpu.vendor_id = 0x10de;
gpu_info.gpu.device_id = 0x0640;
manager->InitializeForTesting(kData, gpu_info);
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
EXPECT_EQ(manager->ShouldUseSwiftShader()
? static_cast<size_t>(gpu::NUMBER_OF_GPU_FEATURE_TYPES)
: 1u,
@@ -264,7 +264,7 @@ TEST_F(GpuDataManagerImplPrivateTest, GpuSideExceptions) {
// Now assume gpu process launches and full GPU info is collected.
gpu_info.gl_renderer = "NVIDIA GeForce GT 120";
manager->UpdateGpuInfo(gpu_info);
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
// Since SwiftShader was enabled by first gpu_info, UpdateGpuInfo
// should have failed and SwiftShader should still be active
EXPECT_EQ(manager->ShouldUseSwiftShader()
@@ -300,11 +300,12 @@ TEST_F(GpuDataManagerImplPrivateTest, SwiftShaderRendering) {
const gpu::GpuControlListData kData;
manager->InitializeForTesting(kData, gpu::GPUInfo());
EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
EXPECT_FALSE(manager->ShouldUseSwiftShader());
manager->DisableHardwareAcceleration();
- EXPECT_EQ(manager->ShouldUseSwiftShader(), manager->GpuAccessAllowed(NULL));
+ EXPECT_EQ(manager->ShouldUseSwiftShader(),
+ manager->GpuAccessAllowed(nullptr));
EXPECT_EQ(static_cast<size_t>(gpu::NUMBER_OF_GPU_FEATURE_TYPES),
manager->GetBlacklistedFeatureCount());
EXPECT_TRUE(manager->IsFeatureBlacklisted(
@@ -319,14 +320,14 @@ TEST_F(GpuDataManagerImplPrivateTest, SwiftShaderRendering2) {
const gpu::GpuControlListData kData;
manager->InitializeForTesting(kData, gpu::GPUInfo());
EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
EXPECT_FALSE(manager->ShouldUseSwiftShader());
manager->DisableHardwareAcceleration();
if (manager->ShouldUseSwiftShader()) {
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
} else {
- EXPECT_FALSE(manager->GpuAccessAllowed(NULL));
+ EXPECT_FALSE(manager->GpuAccessAllowed(nullptr));
}
EXPECT_EQ(static_cast<size_t>(gpu::NUMBER_OF_GPU_FEATURE_TYPES),
manager->GetBlacklistedFeatureCount());
@@ -364,9 +365,9 @@ TEST_F(GpuDataManagerImplPrivateTest, NoGpuInfoUpdateWithSwiftShader) {
manager->DisableHardwareAcceleration();
if (manager->ShouldUseSwiftShader()) {
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
} else {
- EXPECT_FALSE(manager->GpuAccessAllowed(NULL));
+ EXPECT_FALSE(manager->GpuAccessAllowed(nullptr));
}
{
@@ -526,13 +527,13 @@ TEST_F(GpuDataManagerImplPrivateTest, SetGLStrings) {
ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
const gpu::GpuControlList::Entry kEntries[] = {
gpu::kGpuDataManagerTestingEntries
[gpu::kGpuDataManagerImplPrivateTest_SetGLStrings],
};
- const gpu::GpuControlListData kData("1.0", 1, kEntries);
+ const gpu::GpuControlListData kData(1, kEntries);
gpu::GPUInfo gpu_info;
gpu_info.gpu.vendor_id = 0x8086;
@@ -540,7 +541,7 @@ TEST_F(GpuDataManagerImplPrivateTest, SetGLStrings) {
manager->InitializeForTesting(kData, gpu_info);
// Not enough GPUInfo.
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
if (manager->ShouldUseSwiftShader()) {
EXPECT_EQ(static_cast<size_t>(gpu::NUMBER_OF_GPU_FEATURE_TYPES),
manager->GetBlacklistedFeatureCount());
@@ -553,7 +554,7 @@ TEST_F(GpuDataManagerImplPrivateTest, SetGLStrings) {
// However, GPU process is not blocked because this is all browser side and
// happens before renderer launching.
manager->SetGLStrings(kGLVendorMesa, kGLRendererMesa, kGLVersionMesa801);
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
if (manager->ShouldUseSwiftShader()) {
EXPECT_EQ(static_cast<size_t>(gpu::NUMBER_OF_GPU_FEATURE_TYPES),
manager->GetBlacklistedFeatureCount());
@@ -572,13 +573,13 @@ TEST_F(GpuDataManagerImplPrivateTest, SetGLStringsNoEffects) {
ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
const gpu::GpuControlList::Entry kEntries[] = {
gpu::kGpuDataManagerTestingEntries
[gpu::kGpuDataManagerImplPrivateTest_SetGLStringsNoEffects],
};
- const gpu::GpuControlListData kData("1.0", 1, kEntries);
+ const gpu::GpuControlListData kData(1, kEntries);
gpu::GPUInfo gpu_info;
gpu_info.gpu.vendor_id = 0x8086;
@@ -591,7 +592,7 @@ TEST_F(GpuDataManagerImplPrivateTest, SetGLStringsNoEffects) {
manager->InitializeForTesting(kData, gpu_info);
// Full GPUInfo, the entry applies.
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
if (manager->ShouldUseSwiftShader()) {
EXPECT_EQ(static_cast<size_t>(gpu::NUMBER_OF_GPU_FEATURE_TYPES),
manager->GetBlacklistedFeatureCount());
@@ -605,7 +606,7 @@ TEST_F(GpuDataManagerImplPrivateTest, SetGLStringsNoEffects) {
// SetGLStrings() has no effects because GPUInfo already got these strings.
// (Otherwise the entry should not apply.)
manager->SetGLStrings(kGLVendorMesa, kGLRendererMesa, kGLVersionMesa802);
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
if (manager->ShouldUseSwiftShader()) {
EXPECT_EQ(static_cast<size_t>(gpu::NUMBER_OF_GPU_FEATURE_TYPES),
manager->GetBlacklistedFeatureCount());
@@ -623,13 +624,13 @@ TEST_F(GpuDataManagerImplPrivateTest, SetGLStringsDefered) {
ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
const gpu::GpuControlList::Entry kEntries[] = {
gpu::kGpuDataManagerTestingEntries
[gpu::kGpuDataManagerImplPrivateTest_SetGLStringsDefered],
};
- const gpu::GpuControlListData kData("1.0", 1, kEntries);
+ const gpu::GpuControlListData kData(1, kEntries);
// Check that it is allowed to call SetGLStrings before Initialize.
@@ -641,7 +642,7 @@ TEST_F(GpuDataManagerImplPrivateTest, SetGLStringsDefered) {
gpu_info.gpu.device_id = 0x0042;
manager->InitializeForTesting(kData, gpu_info);
- EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->GpuAccessAllowed(nullptr));
if (manager->ShouldUseSwiftShader()) {
EXPECT_EQ(static_cast<size_t>(gpu::NUMBER_OF_GPU_FEATURE_TYPES),
manager->GetBlacklistedFeatureCount());
@@ -665,7 +666,7 @@ TEST_F(GpuDataManagerImplPrivateTest, BlacklistAllFeatures) {
gpu::kGpuDataManagerTestingEntries
[gpu::kGpuDataManagerImplPrivateTest_BlacklistAllFeatures],
};
- const gpu::GpuControlListData kData("1.0", 1, kEntries);
+ const gpu::GpuControlListData kData(1, kEntries);
gpu::GPUInfo gpu_info;
gpu_info.gpu.vendor_id = 0x10de;
@@ -687,7 +688,7 @@ TEST_F(GpuDataManagerImplPrivateTest, UpdateActiveGpu) {
gpu::kGpuDataManagerTestingEntries
[gpu::kGpuDataManagerImplPrivateTest_UpdateActiveGpu],
};
- const gpu::GpuControlListData kData("1.0", 1, kEntries);
+ const gpu::GpuControlListData kData(1, kEntries);
// Two GPUs, the secondary Intel GPU is active.
gpu::GPUInfo gpu_info;
diff --git a/chromium/content/browser/gpu/gpu_data_manager_testing_arrays_and_structs_autogen.h b/chromium/content/browser/gpu/gpu_data_manager_testing_arrays_and_structs_autogen.h
index eae84643540..a1b299a2e36 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_testing_arrays_and_structs_autogen.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_testing_arrays_and_structs_autogen.h
@@ -94,18 +94,16 @@ const GpuControlList::DriverInfo kDriverInfoForEntry8 = {
nullptr}, // driver_date
};
-const int kFeatureListForEntry9[11] = {
+const int kFeatureListForEntry9[9] = {
GPU_FEATURE_TYPE_FLASH_STAGE3D,
GPU_FEATURE_TYPE_GPU_COMPOSITING,
- GPU_FEATURE_TYPE_PANEL_FITTING,
- GPU_FEATURE_TYPE_FLASH3D,
GPU_FEATURE_TYPE_GPU_RASTERIZATION,
+ GPU_FEATURE_TYPE_FLASH3D,
+ GPU_FEATURE_TYPE_ACCELERATED_WEBGL2,
GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE,
- GPU_FEATURE_TYPE_ACCELERATED_WEBGL2,
GPU_FEATURE_TYPE_ACCELERATED_WEBGL,
GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE,
- GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE,
};
const int kFeatureListForEntry10[1] = {
diff --git a/chromium/content/browser/gpu/gpu_data_manager_testing_autogen.cc b/chromium/content/browser/gpu/gpu_data_manager_testing_autogen.cc
index 2680c7e3d61..05c1e100eb4 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_testing_autogen.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_testing_autogen.cc
@@ -15,8 +15,6 @@
namespace gpu {
-const char kGpuDataManagerTestingVersion[] = "1.0";
-
const GpuControlList::Entry kGpuDataManagerTestingEntries[] = {
{
1, // id
diff --git a/chromium/content/browser/gpu/gpu_data_manager_testing_autogen.h b/chromium/content/browser/gpu/gpu_data_manager_testing_autogen.h
index b64a0b7d1d4..71e91acb088 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_testing_autogen.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_testing_autogen.h
@@ -14,7 +14,6 @@
#include "gpu/config/gpu_control_list.h"
namespace gpu {
-extern const char kGpuDataManagerTestingVersion[];
extern const size_t kGpuDataManagerTestingEntryCount;
extern const GpuControlList::Entry kGpuDataManagerTestingEntries[];
} // namespace gpu
diff --git a/chromium/content/browser/gpu/gpu_feature_checker_impl.cc b/chromium/content/browser/gpu/gpu_feature_checker_impl.cc
index 1e3f5c3c900..7c3b5f6fd59 100644
--- a/chromium/content/browser/gpu/gpu_feature_checker_impl.cc
+++ b/chromium/content/browser/gpu/gpu_feature_checker_impl.cc
@@ -16,7 +16,7 @@ namespace {
// A false return value is always valid, but a true one is only valid if full
// GPU info has been collected in a GPU process.
bool IsFeatureAllowed(GpuDataManager* manager, gpu::GpuFeatureType feature) {
- return (manager->GpuAccessAllowed(NULL) &&
+ return (manager->GpuAccessAllowed(nullptr) &&
!manager->IsFeatureBlacklisted(feature));
}
diff --git a/chromium/content/browser/gpu/gpu_internals_ui.cc b/chromium/content/browser/gpu/gpu_internals_ui.cc
index 73a2bf310c9..4c6264f0015 100644
--- a/chromium/content/browser/gpu/gpu_internals_ui.cc
+++ b/chromium/content/browser/gpu/gpu_internals_ui.cc
@@ -38,6 +38,7 @@
#include "content/public/common/url_constants.h"
#include "gpu/config/gpu_feature_type.h"
#include "gpu/config/gpu_info.h"
+#include "gpu/config/gpu_lists_version.h"
#include "gpu/ipc/host/gpu_memory_buffer_support.h"
#include "skia/ext/skia_commit_hash.h"
#include "third_party/angle/src/common/version.h"
@@ -51,7 +52,7 @@
#include "ui/gfx/win/physical_size.h"
#endif
-#if defined(OS_LINUX) && defined(USE_X11)
+#if defined(USE_X11)
#include "ui/base/x/x11_util.h" // nogncheck
#include "ui/gfx/x/x11_atom_cache.h" // nogncheck
#endif
@@ -90,7 +91,7 @@ std::unique_ptr<base::DictionaryValue> NewDescriptionValuePair(
#if defined(OS_WIN)
// Output DxDiagNode tree as nested array of {description,value} pairs
std::unique_ptr<base::ListValue> DxDiagNodeToList(const gpu::DxDiagNode& node) {
- auto list = base::MakeUnique<base::ListValue>();
+ auto list = std::make_unique<base::ListValue>();
for (std::map<std::string, std::string>::const_iterator it =
node.values.begin();
it != node.values.end();
@@ -122,21 +123,21 @@ std::string GPUDeviceToString(const gpu::GPUInfo::GPUDevice& gpu) {
std::unique_ptr<base::DictionaryValue> GpuInfoAsDictionaryValue() {
gpu::GPUInfo gpu_info = GpuDataManagerImpl::GetInstance()->GetGPUInfo();
- auto basic_info = base::MakeUnique<base::ListValue>();
+ auto basic_info = std::make_unique<base::ListValue>();
basic_info->Append(NewDescriptionValuePair(
"Initialization time",
base::Int64ToString(gpu_info.initialization_time.InMilliseconds())));
basic_info->Append(NewDescriptionValuePair(
"In-process GPU",
- base::MakeUnique<base::Value>(gpu_info.in_process_gpu)));
+ std::make_unique<base::Value>(gpu_info.in_process_gpu)));
basic_info->Append(NewDescriptionValuePair(
"Passthrough Command Decoder",
- base::MakeUnique<base::Value>(gpu_info.passthrough_cmd_decoder)));
+ std::make_unique<base::Value>(gpu_info.passthrough_cmd_decoder)));
basic_info->Append(NewDescriptionValuePair(
"Supports overlays",
- base::MakeUnique<base::Value>(gpu_info.supports_overlays)));
+ std::make_unique<base::Value>(gpu_info.supports_overlays)));
basic_info->Append(NewDescriptionValuePair(
- "Sandboxed", base::MakeUnique<base::Value>(gpu_info.sandboxed)));
+ "Sandboxed", std::make_unique<base::Value>(gpu_info.sandboxed)));
basic_info->Append(NewDescriptionValuePair(
"GPU0", GPUDeviceToString(gpu_info.gpu)));
for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) {
@@ -145,12 +146,12 @@ std::unique_ptr<base::DictionaryValue> GpuInfoAsDictionaryValue() {
GPUDeviceToString(gpu_info.secondary_gpus[i])));
}
basic_info->Append(NewDescriptionValuePair(
- "Optimus", base::MakeUnique<base::Value>(gpu_info.optimus)));
+ "Optimus", std::make_unique<base::Value>(gpu_info.optimus)));
basic_info->Append(NewDescriptionValuePair(
- "Optimus", base::MakeUnique<base::Value>(gpu_info.optimus)));
+ "Optimus", std::make_unique<base::Value>(gpu_info.optimus)));
basic_info->Append(NewDescriptionValuePair(
"AMD switchable",
- base::MakeUnique<base::Value>(gpu_info.amd_switchable)));
+ std::make_unique<base::Value>(gpu_info.amd_switchable)));
#if defined(OS_WIN)
std::string compositor =
ui::win::IsAeroGlassEnabled() ? "Aero Glass" : "none";
@@ -209,7 +210,7 @@ std::unique_ptr<base::DictionaryValue> GpuInfoAsDictionaryValue() {
gpu_info.gl_ws_version));
basic_info->Append(NewDescriptionValuePair("Window system binding extensions",
gpu_info.gl_ws_extensions));
-#if defined(OS_LINUX) && defined(USE_X11)
+#if defined(USE_X11)
basic_info->Append(NewDescriptionValuePair("Window manager",
ui::GuessWindowManagerName()));
{
@@ -237,12 +238,12 @@ std::unique_ptr<base::DictionaryValue> GpuInfoAsDictionaryValue() {
basic_info->Append(NewDescriptionValuePair(
"GPU process crash count",
- base::MakeUnique<base::Value>(gpu_info.process_crash_count)));
+ std::make_unique<base::Value>(gpu_info.process_crash_count)));
- auto info = base::MakeUnique<base::DictionaryValue>();
+ auto info = std::make_unique<base::DictionaryValue>();
#if defined(OS_WIN)
- auto dx_info = base::MakeUnique<base::Value>();
+ auto dx_info = std::make_unique<base::Value>();
if (gpu_info.dx_diagnostics.children.size())
dx_info = DxDiagNodeToList(gpu_info.dx_diagnostics);
info->Set("diagnostics", std::move(dx_info));
@@ -287,6 +288,8 @@ const char* BufferFormatToString(gfx::BufferFormat format) {
return "RGBA_8888";
case gfx::BufferFormat::BGRX_8888:
return "BGRX_8888";
+ case gfx::BufferFormat::BGRX_1010102:
+ return "BGRX_1010102";
case gfx::BufferFormat::BGRA_8888:
return "BGRA_8888";
case gfx::BufferFormat::RGBA_F16:
@@ -324,7 +327,7 @@ const char* BufferUsageToString(gfx::BufferUsage usage) {
}
std::unique_ptr<base::ListValue> CompositorInfo() {
- auto compositor_info = base::MakeUnique<base::ListValue>();
+ auto compositor_info = std::make_unique<base::ListValue>();
compositor_info->Append(NewDescriptionValuePair(
"Tile Update Mode",
@@ -336,7 +339,7 @@ std::unique_ptr<base::ListValue> CompositorInfo() {
}
std::unique_ptr<base::ListValue> GpuMemoryBufferInfo() {
- auto gpu_memory_buffer_info = base::MakeUnique<base::ListValue>();
+ auto gpu_memory_buffer_info = std::make_unique<base::ListValue>();
const auto native_configurations =
gpu::GetNativeGpuMemoryBufferConfigurations();
@@ -366,7 +369,7 @@ std::unique_ptr<base::ListValue> GpuMemoryBufferInfo() {
}
std::unique_ptr<base::ListValue> getDisplayInfo() {
- auto display_info = base::MakeUnique<base::ListValue>();
+ auto display_info = std::make_unique<base::ListValue>();
const std::vector<display::Display> displays =
display::Screen::GetScreen()->GetAllDisplays();
for (const auto& display : displays) {
@@ -382,6 +385,92 @@ std::unique_ptr<base::ListValue> getDisplayInfo() {
return display_info;
}
+std::string GetProfileName(gpu::VideoCodecProfile profile) {
+ switch (profile) {
+ case gpu::VIDEO_CODEC_PROFILE_UNKNOWN:
+ return "unknown";
+ case gpu::H264PROFILE_BASELINE:
+ return "h264 baseline";
+ case gpu::H264PROFILE_MAIN:
+ return "h264 main";
+ case gpu::H264PROFILE_EXTENDED:
+ return "h264 extended";
+ case gpu::H264PROFILE_HIGH:
+ return "h264 high";
+ case gpu::H264PROFILE_HIGH10PROFILE:
+ return "h264 high 10";
+ case gpu::H264PROFILE_HIGH422PROFILE:
+ return "h264 high 4:2:2";
+ case gpu::H264PROFILE_HIGH444PREDICTIVEPROFILE:
+ return "h264 high 4:4:4 predictive";
+ case gpu::H264PROFILE_SCALABLEBASELINE:
+ return "h264 scalable baseline";
+ case gpu::H264PROFILE_SCALABLEHIGH:
+ return "h264 scalable high";
+ case gpu::H264PROFILE_STEREOHIGH:
+ return "h264 stereo high";
+ case gpu::H264PROFILE_MULTIVIEWHIGH:
+ return "h264 multiview high";
+ case gpu::HEVCPROFILE_MAIN:
+ return "hevc main";
+ case gpu::HEVCPROFILE_MAIN10:
+ return "hevc main 10";
+ case gpu::HEVCPROFILE_MAIN_STILL_PICTURE:
+ return "hevc main still-picture";
+ case gpu::VP8PROFILE_ANY:
+ return "vp8";
+ case gpu::VP9PROFILE_PROFILE0:
+ return "vp9 profile0";
+ case gpu::VP9PROFILE_PROFILE1:
+ return "vp9 profile1";
+ case gpu::VP9PROFILE_PROFILE2:
+ return "vp9 profile2";
+ case gpu::VP9PROFILE_PROFILE3:
+ return "vp9 profile3";
+ case gpu::DOLBYVISION_PROFILE0:
+ return "dolby vision profile 0";
+ case gpu::DOLBYVISION_PROFILE4:
+ return "dolby vision profile 4";
+ case gpu::DOLBYVISION_PROFILE5:
+ return "dolby vision profile 5";
+ case gpu::DOLBYVISION_PROFILE7:
+ return "dolby vision profile 7";
+ case gpu::THEORAPROFILE_ANY:
+ return "theora";
+ case gpu::AV1PROFILE_PROFILE0:
+ return "av1 profile0";
+ }
+ NOTREACHED();
+ return "";
+}
+
+std::unique_ptr<base::ListValue> GetVideoAcceleratorsInfo() {
+ gpu::GPUInfo gpu_info = GpuDataManagerImpl::GetInstance()->GetGPUInfo();
+ auto info = std::make_unique<base::ListValue>();
+
+ for (const auto& profile :
+ gpu_info.video_decode_accelerator_capabilities.supported_profiles) {
+ std::string codec_string = base::StringPrintf(
+ "Decode %s", GetProfileName(profile.profile).c_str());
+ std::string resolution_string = base::StringPrintf(
+ "up to %s pixels %s", profile.max_resolution.ToString().c_str(),
+ profile.encrypted_only ? "(encrypted)" : "");
+ info->Append(NewDescriptionValuePair(codec_string, resolution_string));
+ }
+
+ for (const auto& profile :
+ gpu_info.video_encode_accelerator_supported_profiles) {
+ std::string codec_string = base::StringPrintf(
+ "Encode %s", GetProfileName(profile.profile).c_str());
+ std::string resolution_string = base::StringPrintf(
+ "up to %s pixels and/or %.3f fps",
+ profile.max_resolution.ToString().c_str(),
+ static_cast<double>(profile.max_framerate_numerator) /
+ profile.max_framerate_denominator);
+ info->Append(NewDescriptionValuePair(codec_string, resolution_string));
+ }
+ return info;
+}
// This class receives javascript messages from the renderer.
// Note that the WebUI infrastructure runs on the UI thread, therefore all of
// this class's methods are expected to run on the UI thread.
@@ -460,7 +549,7 @@ void GpuMessageHandler::OnCallAsync(const base::ListValue* args) {
ok = args->GetString(1, &submessage);
DCHECK(ok);
- auto submessageArgs = base::MakeUnique<base::ListValue>();
+ auto submessageArgs = std::make_unique<base::ListValue>();
for (size_t i = 2; i < args->GetSize(); ++i) {
const base::Value* arg;
ok = args->Get(i, &arg);
@@ -514,7 +603,7 @@ std::unique_ptr<base::DictionaryValue> GpuMessageHandler::OnRequestClientInfo(
const base::ListValue* list) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- auto dict = base::MakeUnique<base::DictionaryValue>();
+ auto dict = std::make_unique<base::DictionaryValue>();
dict->SetString("version", GetContentClient()->GetProduct());
dict->SetString("command_line",
@@ -526,10 +615,7 @@ std::unique_ptr<base::DictionaryValue> GpuMessageHandler::OnRequestClientInfo(
dict->SetString("graphics_backend",
std::string("Skia/" STRINGIZE(SK_MILESTONE)
" " SKIA_COMMIT_HASH));
- dict->SetString("blacklist_version",
- GpuDataManagerImpl::GetInstance()->GetBlacklistVersion());
- dict->SetString("driver_bug_list_version",
- GpuDataManagerImpl::GetInstance()->GetDriverBugListVersion());
+ dict->SetString("revision_identifier", GPU_LISTS_VERSION);
return dict;
}
@@ -547,10 +633,10 @@ void GpuMessageHandler::OnGpuInfoUpdate() {
GpuInfoAsDictionaryValue());
// Add in blacklisting features
- auto feature_status = base::MakeUnique<base::DictionaryValue>();
+ auto feature_status = std::make_unique<base::DictionaryValue>();
feature_status->Set("featureStatus", GetFeatureStatus());
feature_status->Set("problems", GetProblems());
- auto workarounds = base::MakeUnique<base::ListValue>();
+ auto workarounds = std::make_unique<base::ListValue>();
for (const std::string& workaround : GetDriverBugWorkarounds())
workarounds->AppendString(workaround);
feature_status->Set("workarounds", std::move(workarounds));
@@ -558,6 +644,7 @@ void GpuMessageHandler::OnGpuInfoUpdate() {
gpu_info_val->Set("compositorInfo", CompositorInfo());
gpu_info_val->Set("gpuMemoryBufferInfo", GpuMemoryBufferInfo());
gpu_info_val->Set("displayInfo", getDisplayInfo());
+ gpu_info_val->Set("videoAcceleratorsInfo", GetVideoAcceleratorsInfo());
// Send GPU Info to javascript.
web_ui()->CallJavascriptFunctionUnsafe("browserBridge.onGpuInfoUpdate",
@@ -579,7 +666,7 @@ void GpuMessageHandler::OnGpuSwitched() {
GpuInternalsUI::GpuInternalsUI(WebUI* web_ui)
: WebUIController(web_ui) {
- web_ui->AddMessageHandler(base::MakeUnique<GpuMessageHandler>());
+ web_ui->AddMessageHandler(std::make_unique<GpuMessageHandler>());
// Set up the chrome://gpu/ source.
BrowserContext* browser_context =
diff --git a/chromium/content/browser/gpu/gpu_ipc_browsertests.cc b/chromium/content/browser/gpu/gpu_ipc_browsertests.cc
index b547bd8c541..5573fc78ff1 100644
--- a/chromium/content/browser/gpu/gpu_ipc_browsertests.cc
+++ b/chromium/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -6,6 +6,7 @@
#include "base/memory/ptr_util.h"
#include "base/run_loop.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"
@@ -14,6 +15,7 @@
#include "content/public/browser/gpu_utils.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/content_browser_test.h"
+#include "gpu/ipc/client/command_buffer_proxy_impl.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h"
@@ -54,26 +56,37 @@ void OnEstablishedGpuChannel(
quit_closure.Run();
}
-class EstablishGpuChannelHelper {
+scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSyncRunLoop() {
+ gpu::GpuChannelEstablishFactory* factory =
+ content::BrowserMainLoop::GetInstance()->gpu_channel_establish_factory();
+ CHECK(factory);
+ base::RunLoop run_loop;
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host;
+ factory->EstablishGpuChannel(base::Bind(
+ &OnEstablishedGpuChannel, run_loop.QuitClosure(), &gpu_channel_host));
+ run_loop.Run();
+ return gpu_channel_host;
+}
+
+// RunLoop implementation that runs until it observes OnContextLost().
+class ContextLostRunLoop : public viz::ContextLostObserver {
public:
- EstablishGpuChannelHelper() {}
- ~EstablishGpuChannelHelper() {}
-
- scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSyncRunLoop() {
- gpu::GpuChannelEstablishFactory* factory =
- content::BrowserMainLoop::GetInstance()
- ->gpu_channel_establish_factory();
- CHECK(factory);
- base::RunLoop run_loop;
- factory->EstablishGpuChannel(base::Bind(
- &OnEstablishedGpuChannel, run_loop.QuitClosure(), &gpu_channel_host_));
- run_loop.Run();
- return std::move(gpu_channel_host_);
+ ContextLostRunLoop(viz::ContextProvider* context_provider)
+ : context_provider_(context_provider) {
+ context_provider_->AddObserver(this);
}
+ ~ContextLostRunLoop() override { context_provider_->RemoveObserver(this); }
+
+ void RunUntilContextLost() { run_loop_.Run(); }
private:
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host_;
- DISALLOW_COPY_AND_ASSIGN(EstablishGpuChannelHelper);
+ // viz::LostContextProvider:
+ void OnContextLost() override { run_loop_.Quit(); }
+
+ viz::ContextProvider* const context_provider_;
+ base::RunLoop run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContextLostRunLoop);
};
class ContextTestBase : public content::ContentBrowserTest {
@@ -84,14 +97,13 @@ class ContextTestBase : public content::ContentBrowserTest {
if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(nullptr))
return;
- EstablishGpuChannelHelper helper;
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
- helper.EstablishGpuChannelSyncRunLoop();
+ EstablishGpuChannelSyncRunLoop();
CHECK(gpu_channel_host);
provider_ = CreateContext(std::move(gpu_channel_host));
- bool bound = provider_->BindToCurrentThread();
- CHECK(bound);
+ auto result = provider_->BindToCurrentThread();
+ CHECK_EQ(result, gpu::ContextResult::kSuccess);
gl_ = provider_->ContextGL();
context_support_ = provider_->ContextSupport();
@@ -157,8 +169,7 @@ class BrowserGpuChannelHostFactoryTest : public ContentBrowserTest {
}
void EstablishAndWait() {
- EstablishGpuChannelHelper helper;
- gpu_channel_host_ = helper.EstablishGpuChannelSyncRunLoop();
+ gpu_channel_host_ = EstablishGpuChannelSyncRunLoop();
}
gpu::GpuChannelHost* GetGpuChannel() { return gpu_channel_host_.get(); }
@@ -176,7 +187,7 @@ class BrowserGpuChannelHostFactoryTest : public ContentBrowserTest {
IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, MAYBE_Basic) {
DCHECK(!IsChannelEstablished());
EstablishAndWait();
- EXPECT_TRUE(GetGpuChannel() != NULL);
+ EXPECT_TRUE(GetGpuChannel() != nullptr);
}
#if !defined(OS_ANDROID)
@@ -191,7 +202,7 @@ IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
MAYBE_AlreadyEstablished) {
DCHECK(!IsChannelEstablished());
scoped_refptr<gpu::GpuChannelHost> gpu_channel =
- GetFactory()->EstablishGpuChannelSync();
+ GetFactory()->EstablishGpuChannelSync(nullptr);
// Expect established callback immediately.
bool event = false;
@@ -226,7 +237,7 @@ IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
// retain the host after provider is destroyed.
scoped_refptr<ui::ContextProviderCommandBuffer> provider =
CreateContext(GetGpuChannel());
- EXPECT_TRUE(provider->BindToCurrentThread());
+ ASSERT_EQ(provider->BindToCurrentThread(), gpu::ContextResult::kSuccess);
sk_sp<GrContext> gr_context = sk_ref_sp(provider->GrContext());
@@ -273,21 +284,16 @@ IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
scoped_refptr<ui::ContextProviderCommandBuffer> provider =
CreateContext(GetGpuChannel());
- base::RunLoop run_loop;
- int counter = 0;
- provider->SetLostContextCallback(
- base::Bind(&BrowserGpuChannelHostFactoryTest::OnContextLost,
- base::Unretained(this), run_loop.QuitClosure(), &counter));
- EXPECT_TRUE(provider->BindToCurrentThread());
+ ContextLostRunLoop run_loop(provider.get());
+ ASSERT_EQ(provider->BindToCurrentThread(), gpu::ContextResult::kSuccess);
GpuProcessHost::CallOnIO(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
false /* force_create */,
base::Bind([](GpuProcessHost* host) {
if (host)
host->gpu_service()->Crash();
}));
- run_loop.Run();
+ run_loop.RunUntilContextLost();
- EXPECT_EQ(1, counter);
EXPECT_FALSE(IsChannelEstablished());
EstablishAndWait();
EXPECT_TRUE(IsChannelEstablished());
@@ -303,4 +309,66 @@ IN_PROC_BROWSER_TEST_F(GpuProcessHostBrowserTest, Shutdown) {
run_loop.Run();
}
+// Disabled outside linux like other tests here sadface.
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, CreateTransferBuffer) {
+ DCHECK(!IsChannelEstablished());
+ EstablishAndWait();
+
+ // This is for an offscreen context, so the default framebuffer doesn't need
+ // any alpha, depth, stencil, antialiasing.
+ gpu::gles2::ContextCreationAttribHelper attributes;
+ attributes.alpha_size = -1;
+ attributes.depth_size = 0;
+ attributes.stencil_size = 0;
+ attributes.samples = 0;
+ attributes.sample_buffers = 0;
+ attributes.bind_generates_resource = false;
+
+ auto impl = std::make_unique<gpu::CommandBufferProxyImpl>(
+ GetGpuChannel(), content::kGpuStreamIdDefault,
+ base::ThreadTaskRunnerHandle::Get());
+ ASSERT_EQ(
+ impl->Initialize(gpu::kNullSurfaceHandle, nullptr,
+ content::kGpuStreamPriorityDefault, attributes, GURL()),
+ gpu::ContextResult::kSuccess);
+
+ // Creating a transfer buffer works normally.
+ int32_t id = -1;
+ scoped_refptr<gpu::Buffer> buffer = impl->CreateTransferBuffer(100, &id);
+ EXPECT_TRUE(buffer);
+ EXPECT_GE(id, 0);
+
+ // If the context is lost, creating a transfer buffer still works. This is
+ // important for initializing a client side context. If it is lost for some
+ // transient reason, we don't want that to be confused with a fatal error,
+ // like failing to make a transfer buffer.
+
+ // Lose the connection to the gpu to lose the context.
+ GetGpuChannel()->DestroyChannel();
+ // It's not visible until we run the task queue.
+ EXPECT_EQ(impl->GetLastState().error, gpu::error::kNoError);
+
+ // Wait to see the error occur. The DestroyChannel() will destroy the IPC
+ // 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)
+ ->PostTask(FROM_HERE, wait_for_io_run_loop.QuitClosure());
+ // Waits for the IO thread to run.
+ wait_for_io_run_loop.Run();
+
+ // Waits for the main thread to run.
+ base::RunLoop().RunUntilIdle();
+ // The error has become visible on the main thread now.
+ EXPECT_NE(impl->GetLastState().error, gpu::error::kNoError);
+
+ // Creating a transfer buffer still works.
+ id = -1;
+ buffer = impl->CreateTransferBuffer(100, &id);
+ EXPECT_TRUE(buffer);
+ EXPECT_GE(id, 0);
+}
+#endif
+
} // namespace content
diff --git a/chromium/content/browser/gpu/gpu_main_thread_factory.h b/chromium/content/browser/gpu/gpu_main_thread_factory.h
index 57ed8bfa4cc..d1fba87d78c 100644
--- a/chromium/content/browser/gpu/gpu_main_thread_factory.h
+++ b/chromium/content/browser/gpu/gpu_main_thread_factory.h
@@ -11,11 +11,16 @@ namespace base {
class Thread;
}
+namespace gpu {
+struct GpuPreferences;
+}
+
namespace content {
class InProcessChildThreadParams;
typedef base::Thread* (*GpuMainThreadFactoryFunction)(
- const InProcessChildThreadParams&);
+ const InProcessChildThreadParams&,
+ const gpu::GpuPreferences&);
CONTENT_EXPORT void RegisterGpuMainThreadFactory(
GpuMainThreadFactoryFunction create);
diff --git a/chromium/content/browser/gpu/gpu_process_host.cc b/chromium/content/browser/gpu/gpu_process_host.cc
index eb380f6b29a..e195e75d56c 100644
--- a/chromium/content/browser/gpu/gpu_process_host.cc
+++ b/chromium/content/browser/gpu/gpu_process_host.cc
@@ -27,6 +27,7 @@
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/tracing/common/tracing_switches.h"
+#include "components/viz/common/switches.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/field_trial_recorder.h"
@@ -56,8 +57,6 @@
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/ipc/host/shader_disk_cache.h"
#include "gpu/ipc/service/switches.h"
-#include "ipc/ipc_channel_handle.h"
-#include "ipc/message_filter.h"
#include "media/base/media_switches.h"
#include "media/media_features.h"
#include "mojo/edk/embedder/embedder.h"
@@ -65,6 +64,7 @@
#include "services/service_manager/public/cpp/interface_provider.h"
#include "services/service_manager/runner/common/client_util.h"
#include "services/service_manager/sandbox/sandbox_type.h"
+#include "services/service_manager/sandbox/switches.h"
#include "ui/base/ui_base_switches.h"
#include "ui/display/display_switches.h"
#include "ui/gfx/switches.h"
@@ -78,8 +78,8 @@
#endif
#if defined(OS_WIN)
-#include "content/common/sandbox_win.h"
#include "sandbox/win/src/sandbox_policy.h"
+#include "services/service_manager/sandbox/win/sandbox_win.h"
#include "ui/gfx/switches.h"
#include "ui/gfx/win/rendering_window_manager.h"
#endif
@@ -111,14 +111,14 @@ namespace {
// Command-line switches to propagate to the GPU process.
static const char* const kSwitchNames[] = {
- switches::kDisableAcceleratedVideoDecode,
+ service_manager::switches::kDisableSeccompFilterSandbox,
+ service_manager::switches::kGpuSandboxAllowSysVShm,
+ service_manager::switches::kGpuSandboxFailuresFatal,
switches::kDisableBreakpad,
switches::kDisableGpuRasterization,
switches::kDisableGpuSandbox,
- switches::kDisableGpuWatchdog,
switches::kDisableGLExtensions,
switches::kDisableLogging,
- switches::kDisableSeccompFilterSandbox,
switches::kDisableShaderNameHashing,
#if BUILDFLAG(ENABLE_WEBRTC)
switches::kDisableWebRtcHWEncoding,
@@ -130,13 +130,7 @@ static const char* const kSwitchNames[] = {
switches::kEnableHeapProfiling,
switches::kEnableLogging,
switches::kEnableOOPRasterization,
-#if defined(OS_CHROMEOS)
- switches::kDisableVaapiAcceleratedVideoEncode,
-#endif
- switches::kGpuStartupDialog,
- switches::kGpuSandboxAllowSysVShm,
- switches::kGpuSandboxFailuresFatal,
- switches::kGpuSandboxStartEarly,
+ switches::kEnableViz,
switches::kHeadless,
switches::kLoggingLevel,
switches::kEnableLowEndDeviceMode,
@@ -158,6 +152,7 @@ static const char* const kSwitchNames[] = {
#endif
#if defined(USE_OZONE)
switches::kOzonePlatform,
+ switches::kOzoneDumpFile,
#endif
#if defined(USE_X11)
switches::kX11Display,
@@ -166,9 +161,12 @@ static const char* const kSwitchNames[] = {
switches::kGpuTestingGLRenderer,
switches::kGpuTestingGLVersion,
switches::kDisableGpuDriverBugWorkarounds,
- switches::kUsePassthroughCmdDecoder,
+ switches::kUseCmdDecoder,
switches::kIgnoreGpuBlacklist,
switches::kForceVideoOverlays,
+#if defined(OS_ANDROID)
+ switches::kMadviseRandomExecutableCode,
+#endif
};
enum GPUProcessLifetimeEvent {
@@ -250,7 +248,8 @@ class GpuSandboxedProcessLauncherDelegate
// Open GL path.
policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
sandbox::USER_LIMITED);
- SetJobLevel(cmd_line_, sandbox::JOB_UNPROTECTED, 0, policy);
+ service_manager::SandboxWin::SetJobLevel(
+ cmd_line_, sandbox::JOB_UNPROTECTED, 0, policy);
policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
} else {
policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
@@ -262,12 +261,12 @@ class GpuSandboxedProcessLauncherDelegate
// turn blocks on the browser UI thread. So, instead we forgo a window
// message pump entirely and just add job restrictions to prevent child
// processes.
- SetJobLevel(cmd_line_, sandbox::JOB_LIMITED_USER,
- JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS |
- JOB_OBJECT_UILIMIT_DESKTOP |
- JOB_OBJECT_UILIMIT_EXITWINDOWS |
- JOB_OBJECT_UILIMIT_DISPLAYSETTINGS,
- policy);
+ service_manager::SandboxWin::SetJobLevel(
+ cmd_line_, sandbox::JOB_LIMITED_USER,
+ JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_DESKTOP |
+ JOB_OBJECT_UILIMIT_EXITWINDOWS |
+ JOB_OBJECT_UILIMIT_DISPLAYSETTINGS,
+ policy);
policy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
}
@@ -380,8 +379,8 @@ GpuProcessHost* GpuProcessHost::Get(GpuProcessKind kind, bool force_create) {
// Don't grant further access to GPU if it is not allowed.
GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
DCHECK(gpu_data_manager);
- if (!gpu_data_manager->GpuAccessAllowed(NULL))
- return NULL;
+ if (!gpu_data_manager->GpuAccessAllowed(nullptr))
+ return nullptr;
if (g_gpu_process_hosts[kind] && ValidateHost(g_gpu_process_hosts[kind]))
return g_gpu_process_hosts[kind];
@@ -406,16 +405,15 @@ GpuProcessHost* GpuProcessHost::Get(GpuProcessKind kind, bool force_create) {
host->RecordProcessCrash();
delete host;
- return NULL;
+ return nullptr;
}
// static
-void GpuProcessHost::GetHasGpuProcess(
- const base::Callback<void(bool)>& callback) {
+void GpuProcessHost::GetHasGpuProcess(base::OnceCallback<void(bool)> callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::BindOnce(&GpuProcessHost::GetHasGpuProcess, callback));
+ base::BindOnce(&GpuProcessHost::GetHasGpuProcess, std::move(callback)));
return;
}
bool has_gpu = false;
@@ -426,8 +424,7 @@ void GpuProcessHost::GetHasGpuProcess(
break;
}
}
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(callback, has_gpu));
+ std::move(callback).Run(has_gpu);
}
// static
@@ -460,7 +457,7 @@ GpuProcessHost* GpuProcessHost::FromID(int host_id) {
return host;
}
- return NULL;
+ return nullptr;
}
GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind)
@@ -482,7 +479,7 @@ GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind)
// If the 'single GPU process' policy ever changes, we still want to maintain
// it for 'gpu thread' mode and only create one instance of host and thread.
- DCHECK(!in_process_ || g_gpu_process_hosts[kind] == NULL);
+ DCHECK(!in_process_ || g_gpu_process_hosts[kind] == nullptr);
g_gpu_process_hosts[kind] = this;
@@ -510,7 +507,7 @@ GpuProcessHost::~GpuProcessHost() {
// This is only called on the IO thread so no race against the constructor
// for another GpuProcessHost.
if (g_gpu_process_hosts[kind_] == this)
- g_gpu_process_hosts[kind_] = NULL;
+ g_gpu_process_hosts[kind_] = nullptr;
#if defined(OS_MACOSX) || defined(OS_ANDROID)
UMA_HISTOGRAM_COUNTS_100("GPU.AtExitSurfaceCount",
@@ -591,21 +588,22 @@ bool GpuProcessHost::Init() {
// May be null during test execution.
if (ServiceManagerConnection::GetForProcess()) {
ServiceManagerConnection::GetForProcess()->AddConnectionFilter(
- base::MakeUnique<ConnectionFilterImpl>());
+ std::make_unique<ConnectionFilterImpl>());
}
process_->GetHost()->CreateChannelMojo();
- gpu::GpuPreferences gpu_preferences = GetGpuPreferencesFromCommandLine();
- GpuDataManagerImpl::GetInstance()->UpdateGpuPreferences(&gpu_preferences);
if (in_process_) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(GetGpuMainThreadFactory());
- in_process_gpu_thread_.reset(
- GetGpuMainThreadFactory()(InProcessChildThreadParams(
+ gpu::GpuPreferences gpu_preferences = GetGpuPreferencesFromCommandLine();
+ GpuDataManagerImpl::GetInstance()->UpdateGpuPreferences(&gpu_preferences);
+ in_process_gpu_thread_.reset(GetGpuMainThreadFactory()(
+ InProcessChildThreadParams(
base::ThreadTaskRunnerHandle::Get(),
process_->GetInProcessBrokerClientInvitation(),
- process_->child_connection()->service_token())));
+ process_->child_connection()->service_token()),
+ gpu_preferences));
base::Thread::Options options;
#if defined(OS_WIN)
// WGL needs to create its own window and pump messages on it.
@@ -627,7 +625,7 @@ bool GpuProcessHost::Init() {
viz::mojom::GpuHostPtr host_proxy;
gpu_host_binding_.Bind(mojo::MakeRequest(&host_proxy));
gpu_main_ptr_->CreateGpuService(mojo::MakeRequest(&gpu_service_ptr_),
- std::move(host_proxy), gpu_preferences,
+ std::move(host_proxy),
activity_flags_.CloneHandle());
#if defined(USE_OZONE)
@@ -690,9 +688,10 @@ void GpuProcessHost::EstablishGpuChannel(
TRACE_EVENT0("gpu", "GpuProcessHost::EstablishGpuChannel");
// If GPU features are already blacklisted, no need to establish the channel.
- if (!GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL)) {
+ if (!GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(nullptr)) {
DVLOG(1) << "GPU blacklisted, refusing to open a GPU channel.";
- callback.Run(IPC::ChannelHandle(), gpu::GPUInfo(), gpu::GpuFeatureInfo(),
+ callback.Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
+ gpu::GpuFeatureInfo(),
EstablishChannelStatus::GPU_ACCESS_DENIED);
return;
}
@@ -738,6 +737,20 @@ void GpuProcessHost::DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
gpu_service_ptr_->DestroyGpuMemoryBuffer(id, client_id, sync_token);
}
+void GpuProcessHost::ConnectFrameSinkManager(
+ viz::mojom::FrameSinkManagerRequest request,
+ viz::mojom::FrameSinkManagerClientPtrInfo client,
+ viz::mojom::CompositingModeWatcherPtrInfo mode_watcher) {
+ TRACE_EVENT0("gpu", "GpuProcessHost::ConnectFrameSinkManager");
+ viz::mojom::FrameSinkManagerParamsPtr params =
+ viz::mojom::FrameSinkManagerParams::New();
+ params->restart_id = host_id_;
+ params->frame_sink_manager = std::move(request);
+ params->frame_sink_manager_client = std::move(client);
+ params->compositing_mode_watcher = std::move(mode_watcher);
+ gpu_main_ptr_->CreateFrameSinkManager(std::move(params));
+}
+
void GpuProcessHost::RequestGPUInfo(RequestGPUInfoCallback request_cb) {
if (status_ == SUCCESS || status_ == FAILURE) {
std::move(request_cb).Run(GpuDataManagerImpl::GetInstance()->GetGPUInfo());
@@ -747,6 +760,10 @@ void GpuProcessHost::RequestGPUInfo(RequestGPUInfoCallback request_cb) {
request_gpu_info_callbacks_.push_back(std::move(request_cb));
}
+void GpuProcessHost::RequestHDRStatus(RequestHDRStatusCallback request_cb) {
+ gpu_service_ptr_->RequestHDRStatus(std::move(request_cb));
+}
+
#if defined(OS_ANDROID)
void GpuProcessHost::SendDestroyingVideoSurface(int surface_id,
const base::Closure& done_cb) {
@@ -775,15 +792,15 @@ void GpuProcessHost::OnChannelEstablished(
if (channel_handle.is_valid() &&
!gpu_data_manager->GpuAccessAllowed(nullptr)) {
gpu_service_ptr_->CloseChannel(client_id);
- callback.Run(IPC::ChannelHandle(), gpu::GPUInfo(), gpu::GpuFeatureInfo(),
+ callback.Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
+ gpu::GpuFeatureInfo(),
EstablishChannelStatus::GPU_ACCESS_DENIED);
RecordLogMessage(logging::LOG_WARNING, "WARNING",
"Hardware acceleration is unavailable.");
return;
}
- callback.Run(IPC::ChannelHandle(channel_handle.release()),
- gpu_data_manager->GetGPUInfo(),
+ callback.Run(std::move(channel_handle), gpu_data_manager->GetGPUInfo(),
gpu_data_manager->GetGpuFeatureInfo(),
EstablishChannelStatus::SUCCESS);
}
@@ -834,7 +851,7 @@ void GpuProcessHost::OnProcessCrashed(int exit_code) {
SendOutstandingReplies();
RecordProcessCrash();
GpuDataManagerImpl::GetInstance()->ProcessCrashed(
- process_->GetTerminationStatus(true /* known_dead */, NULL));
+ process_->GetTerminationStatus(true /* known_dead */, nullptr));
}
void GpuProcessHost::DidInitialize(
@@ -868,6 +885,15 @@ void GpuProcessHost::DidFailInitialize() {
RunRequestGPUInfoCallbacks(gpu_data_manager->GetGPUInfo());
}
+void GpuProcessHost::DidCreateContextSuccessfully() {
+#if defined(OS_ANDROID)
+ // Android may kill the GPU process to free memory, especially when the app
+ // is the background, so Android cannot have a hard limit on GPU starts.
+ // Reset crash count on Android when context creation succeeds.
+ gpu_recent_crash_count_ = 0;
+#endif
+}
+
void GpuProcessHost::DidCreateOffscreenContext(const GURL& url) {
urls_with_live_offscreen_contexts_.insert(url);
}
@@ -932,30 +958,27 @@ void GpuProcessHost::SetChildSurface(gpu::SurfaceHandle parent_handle,
constexpr char kBadMessageError[] = "Bad parenting request from gpu process.";
if (!in_process_) {
DCHECK(process_);
- {
- DWORD process_id = 0;
- DWORD thread_id = GetWindowThreadProcessId(parent_handle, &process_id);
- if (!thread_id || process_id != ::GetCurrentProcessId()) {
- process_->TerminateOnBadMessageReceived(kBadMessageError);
- return;
- }
+ DWORD parent_process_id = 0;
+ DWORD parent_thread_id =
+ GetWindowThreadProcessId(parent_handle, &parent_process_id);
+ if (!parent_thread_id || parent_process_id != ::GetCurrentProcessId()) {
+ LOG(ERROR) << kBadMessageError;
+ return;
}
- {
- DWORD process_id = 0;
- DWORD thread_id = GetWindowThreadProcessId(window_handle, &process_id);
-
- if (!thread_id || process_id != process_->GetProcess().Pid()) {
- process_->TerminateOnBadMessageReceived(kBadMessageError);
- return;
- }
+ DWORD child_process_id = 0;
+ DWORD child_thread_id =
+ GetWindowThreadProcessId(window_handle, &child_process_id);
+ if (!child_thread_id || child_process_id != process_->GetProcess().Pid()) {
+ LOG(ERROR) << kBadMessageError;
+ return;
}
}
if (!gfx::RenderingWindowManager::GetInstance()->RegisterChild(
parent_handle, window_handle)) {
- process_->TerminateOnBadMessageReceived(kBadMessageError);
+ LOG(ERROR) << kBadMessageError;
}
#endif
}
@@ -986,7 +1009,7 @@ void GpuProcessHost::ForceShutdown() {
// This is only called on the IO thread so no race against the constructor
// for another GpuProcessHost.
if (g_gpu_process_hosts[kind_] == this)
- g_gpu_process_hosts[kind_] = NULL;
+ g_gpu_process_hosts[kind_] = nullptr;
process_->ForceShutdown();
}
@@ -1003,7 +1026,7 @@ bool GpuProcessHost::LaunchGpuProcess() {
// at startup with EACCES. As a workaround ignore this here, since the
// executable name is actually not used or useful anyways.
std::unique_ptr<base::CommandLine> cmd_line =
- base::MakeUnique<base::CommandLine>(base::CommandLine::NO_PROGRAM);
+ std::make_unique<base::CommandLine>(base::CommandLine::NO_PROGRAM);
#else
#if defined(OS_LINUX)
int child_flags = gpu_launcher.empty() ? ChildProcessHost::CHILD_ALLOW_SELF :
@@ -1017,7 +1040,7 @@ bool GpuProcessHost::LaunchGpuProcess() {
return false;
std::unique_ptr<base::CommandLine> cmd_line =
- base::MakeUnique<base::CommandLine>(exe_path);
+ std::make_unique<base::CommandLine>(exe_path);
#endif
cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess);
@@ -1070,7 +1093,7 @@ bool GpuProcessHost::LaunchGpuProcess() {
cmd_line->PrependWrapper(gpu_launcher);
std::unique_ptr<GpuSandboxedProcessLauncherDelegate> delegate =
- base::MakeUnique<GpuSandboxedProcessLauncherDelegate>(*cmd_line);
+ std::make_unique<GpuSandboxedProcessLauncherDelegate>(*cmd_line);
process_->Launch(std::move(delegate), std::move(cmd_line), true);
process_launched_ = true;
@@ -1086,7 +1109,8 @@ void GpuProcessHost::SendOutstandingReplies() {
while (!channel_requests_.empty()) {
auto callback = channel_requests_.front();
channel_requests_.pop();
- callback.Run(IPC::ChannelHandle(), gpu::GPUInfo(), gpu::GpuFeatureInfo(),
+ callback.Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
+ gpu::GpuFeatureInfo(),
EstablishChannelStatus::GPU_HOST_INVALID);
}
@@ -1118,10 +1142,16 @@ void GpuProcessHost::BlockLiveOffscreenContexts() {
}
void GpuProcessHost::RecordProcessCrash() {
+#if !defined(OS_ANDROID)
// Maximum number of times the GPU process is allowed to crash in a session.
// Once this limit is reached, any request to launch the GPU process will
// fail.
const int kGpuMaxCrashCount = 3;
+#else
+ // On android there is no way to recover without gpu, and the OS can kill the
+ // gpu process arbitrarily, so use a higher count to allow for that.
+ const int kGpuMaxCrashCount = 6;
+#endif
// Last time the GPU process crashed.
static base::Time last_gpu_crash_time;
@@ -1169,7 +1199,16 @@ void GpuProcessHost::RecordProcessCrash() {
if ((gpu_recent_crash_count_ >= kGpuMaxCrashCount ||
status_ == FAILURE) &&
!disable_crash_limit) {
-#if !defined(OS_CHROMEOS)
+#if defined(OS_ANDROID)
+ // Android can not fall back to software. If things are too unstable
+ // then we just crash chrome to reset everything. Sorry.
+ LOG(FATAL) << "Unable to start gpu process, giving up.";
+#elif defined(OS_CHROMEOS)
+ // ChromeOS also can not fall back to software. There we will just
+ // keep retrying to make the gpu process forever. Good luck.
+ DLOG(ERROR) << "Gpu process is unstable and crashing repeatedly, if "
+ "you didn't notice already.";
+#else
// The GPU process is too unstable to use. Disable it for current
// session.
hardware_gpu_enabled_ = false;
diff --git a/chromium/content/browser/gpu/gpu_process_host.h b/chromium/content/browser/gpu/gpu_process_host.h
index adf4d68f748..53eec4a9bb7 100644
--- a/chromium/content/browser/gpu/gpu_process_host.h
+++ b/chromium/content/browser/gpu/gpu_process_host.h
@@ -29,11 +29,11 @@
#include "gpu/config/gpu_info.h"
#include "gpu/ipc/common/surface_handle.h"
#include "ipc/ipc_sender.h"
-#include "ipc/message_filter.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "services/ui/gpu/interfaces/gpu_main.mojom.h"
+#include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h"
#include "services/viz/privileged/interfaces/gl/gpu_host.mojom.h"
#include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h"
+#include "services/viz/privileged/interfaces/viz_main.mojom.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "url/gurl.h"
@@ -42,10 +42,6 @@ namespace base {
class Thread;
}
-namespace IPC {
-struct ChannelHandle;
-}
-
namespace gpu {
class ShaderDiskCache;
struct SyncToken;
@@ -73,7 +69,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
SUCCESS
};
using EstablishChannelCallback =
- base::Callback<void(const IPC::ChannelHandle&,
+ base::Callback<void(mojo::ScopedMessagePipeHandle channel_handle,
const gpu::GPUInfo&,
const gpu::GpuFeatureInfo&,
EstablishChannelStatus status)>;
@@ -87,8 +83,8 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
BufferCreationStatus status)>;
using RequestGPUInfoCallback = base::Callback<void(const gpu::GPUInfo&)>;
+ using RequestHDRStatusCallback = base::Callback<void(bool)>;
- static bool gpu_enabled() { return gpu_enabled_; }
static int gpu_crash_count() { return gpu_crash_count_; }
// Creates a new GpuProcessHost (if |force_create| is turned on) or gets an
@@ -102,7 +98,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
bool force_create = true);
// Returns whether there is an active GPU process or not.
- static void GetHasGpuProcess(const base::Callback<void(bool)>& callback);
+ static void GetHasGpuProcess(base::OnceCallback<void(bool)> callback);
// Helper function to run a callback on the IO thread. The callback receives
// the appropriate GpuProcessHost instance. Note that the callback can be
@@ -148,7 +144,16 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
int client_id,
const gpu::SyncToken& sync_token);
+ // Connects to FrameSinkManager running in the viz process. In this
+ // configuration the display compositor runs in the viz process and the
+ // browser must submit CompositorFrames over IPC.
+ void ConnectFrameSinkManager(
+ viz::mojom::FrameSinkManagerRequest request,
+ viz::mojom::FrameSinkManagerClientPtrInfo client,
+ viz::mojom::CompositingModeWatcherPtrInfo mode_watcher);
+
void RequestGPUInfo(RequestGPUInfoCallback request_cb);
+ void RequestHDRStatus(RequestHDRStatusCallback request_cb);
#if defined(OS_ANDROID)
// Tells the GPU process that the given surface is being destroyed so that it
@@ -193,6 +198,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
void DidInitialize(const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info) override;
void DidFailInitialize() override;
+ void DidCreateContextSuccessfully() override;
void DidCreateOffscreenContext(const GURL& url) override;
void DidDestroyOffscreenContext(const GURL& url) override;
void DidDestroyChannel(int32_t client_id) override;
@@ -273,8 +279,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
base::TimeTicks init_start_time_;
// Master switch for enabling/disabling GPU acceleration for the current
- // browser session. It does not change the acceleration settings for
- // existing tabs, just the future ones.
+ // browser session.
static bool gpu_enabled_;
static bool hardware_gpu_enabled_;
@@ -305,7 +310,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
bool wake_up_gpu_before_drawing_ = false;
bool dont_disable_webgl_when_compositor_context_lost_ = false;
- ui::mojom::GpuMainAssociatedPtr gpu_main_ptr_;
+ viz::mojom::VizMainAssociatedPtr gpu_main_ptr_;
viz::mojom::GpuServicePtr gpu_service_ptr_;
mojo::Binding<viz::mojom::GpuHost> gpu_host_binding_;
gpu::GpuProcessHostActivityFlags activity_flags_;
diff --git a/chromium/content/browser/histogram_controller.cc b/chromium/content/browser/histogram_controller.cc
index 2860b84ce29..de5084d7471 100644
--- a/chromium/content/browser/histogram_controller.cc
+++ b/chromium/content/browser/histogram_controller.cc
@@ -8,7 +8,6 @@
#include "base/metrics/histogram_macros.h"
#include "base/process/process_handle.h"
#include "content/browser/histogram_subscriber.h"
-#include "content/common/child_process_messages.h"
#include "content/common/histogram_fetcher.mojom.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
#include "content/public/browser/browser_thread.h"
@@ -25,8 +24,7 @@ HistogramController* HistogramController::GetInstance() {
HistogramController>>::get();
}
-HistogramController::HistogramController() : subscriber_(NULL) {
-}
+HistogramController::HistogramController() : subscriber_(nullptr) {}
HistogramController::~HistogramController() {
}
@@ -95,7 +93,7 @@ void HistogramController::Register(HistogramSubscriber* subscriber) {
void HistogramController::Unregister(
const HistogramSubscriber* subscriber) {
DCHECK_EQ(subscriber_, subscriber);
- subscriber_ = NULL;
+ subscriber_ = nullptr;
}
template <class T>
diff --git a/chromium/content/browser/histogram_internals_url_loader.cc b/chromium/content/browser/histogram_internals_url_loader.cc
index 3c1e98577ea..b69269a3baf 100644
--- a/chromium/content/browser/histogram_internals_url_loader.cc
+++ b/chromium/content/browser/histogram_internals_url_loader.cc
@@ -26,7 +26,7 @@ void StartHistogramInternalsURLLoader(const ResourceRequest& request,
CHECK(mojo::common::BlockingCopyFromString(data, data_pipe.producer_handle));
client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
- ResourceRequestCompletionStatus status(net::OK);
+ network::URLLoaderCompletionStatus status(net::OK);
status.encoded_data_length = data.size();
status.encoded_body_length = data.size();
client->OnComplete(status);
diff --git a/chromium/content/browser/histogram_message_filter.cc b/chromium/content/browser/histogram_message_filter.cc
deleted file mode 100644
index 669b2d84b49..00000000000
--- a/chromium/content/browser/histogram_message_filter.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/browser/histogram_message_filter.h"
-
-#include "base/command_line.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/statistics_recorder.h"
-#include "content/browser/histogram_controller.h"
-#include "content/common/child_process_messages.h"
-#include "content/public/common/content_switches.h"
-
-namespace content {
-
-HistogramMessageFilter::HistogramMessageFilter()
- : BrowserMessageFilter(ChildProcessMsgStart) {}
-
-bool HistogramMessageFilter::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(HistogramMessageFilter, message)
- IPC_MESSAGE_HANDLER(ChildProcessHostMsg_GetBrowserHistogram,
- OnGetBrowserHistogram)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-HistogramMessageFilter::~HistogramMessageFilter() {}
-
-void HistogramMessageFilter::OnGetBrowserHistogram(
- const std::string& name,
- std::string* histogram_json) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- // Security: Only allow access to browser histograms when running in the
- // context of a test.
- bool using_stats_collection_controller =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kStatsCollectionController);
- if (!using_stats_collection_controller) {
- LOG(ERROR) << "Attempt at reading browser histogram without specifying "
- << "--" << switches::kStatsCollectionController << " switch.";
- return;
- }
- base::HistogramBase* histogram =
- base::StatisticsRecorder::FindHistogram(name);
- if (!histogram) {
- *histogram_json = "{}";
- } else {
- histogram->WriteJSON(histogram_json);
- }
-}
-
-} // namespace content
diff --git a/chromium/content/browser/histogram_message_filter.h b/chromium/content/browser/histogram_message_filter.h
deleted file mode 100644
index fc65cad1e2a..00000000000
--- a/chromium/content/browser/histogram_message_filter.h
+++ /dev/null
@@ -1,37 +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_BROWSER_HISTOGRAM_MESSAGE_FILTER_H_
-#define CONTENT_BROWSER_HISTOGRAM_MESSAGE_FILTER_H_
-
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "content/public/browser/browser_message_filter.h"
-#include "content/public/common/process_type.h"
-
-namespace content {
-
-// This class sends and receives histogram messages in the browser process.
-class HistogramMessageFilter : public BrowserMessageFilter {
- public:
- HistogramMessageFilter();
-
- // BrowserMessageFilter implementation.
- bool OnMessageReceived(const IPC::Message& message) override;
-
- private:
- ~HistogramMessageFilter() override;
-
- // Message handlers.
- void OnGetBrowserHistogram(const std::string& name,
- std::string* histogram_json);
-
- DISALLOW_COPY_AND_ASSIGN(HistogramMessageFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_HISTOGRAM_MESSAGE_FILTER_H_
diff --git a/chromium/content/browser/histogram_synchronizer.cc b/chromium/content/browser/histogram_synchronizer.cc
index 90da2edb6fb..bbfb0e4877c 100644
--- a/chromium/content/browser/histogram_synchronizer.cc
+++ b/chromium/content/browser/histogram_synchronizer.cc
@@ -97,7 +97,7 @@ class HistogramSynchronizer::RequestContext {
RequestContextMap::iterator it =
outstanding_requests_.Get().find(sequence_number);
if (it == outstanding_requests_.Get().end())
- return NULL;
+ return nullptr;
RequestContext* request = it->second;
DCHECK_EQ(sequence_number, request->sequence_number_);
@@ -198,7 +198,7 @@ void HistogramSynchronizer::FetchHistograms() {
HistogramSynchronizer* current_synchronizer =
HistogramSynchronizer::GetInstance();
- if (current_synchronizer == NULL)
+ if (current_synchronizer == nullptr)
return;
current_synchronizer->RegisterAndNotifyAllProcesses(
diff --git a/chromium/content/browser/host_zoom_map_impl.cc b/chromium/content/browser/host_zoom_map_impl.cc
index 788ed10be5c..96267b1b368 100644
--- a/chromium/content/browser/host_zoom_map_impl.cc
+++ b/chromium/content/browser/host_zoom_map_impl.cc
@@ -52,6 +52,7 @@ std::string GetHostFromProcessView(int render_process_id, int render_view_id) {
} // namespace
GURL HostZoomMap::GetURLFromEntry(const NavigationEntry* entry) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
switch (entry->GetPageType()) {
case PAGE_TYPE_ERROR:
return GURL(kUnreachableWebDataURL);
@@ -63,6 +64,7 @@ GURL HostZoomMap::GetURLFromEntry(const NavigationEntry* entry) {
}
HostZoomMap* HostZoomMap::GetDefaultForBrowserContext(BrowserContext* context) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
StoragePartition* partition =
BrowserContext::GetDefaultStoragePartition(context);
DCHECK(partition);
@@ -70,6 +72,7 @@ HostZoomMap* HostZoomMap::GetDefaultForBrowserContext(BrowserContext* context) {
}
HostZoomMap* HostZoomMap::Get(SiteInstance* instance) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
StoragePartition* partition = BrowserContext::GetStoragePartition(
instance->GetBrowserContext(), instance);
DCHECK(partition);
@@ -77,6 +80,7 @@ HostZoomMap* HostZoomMap::Get(SiteInstance* instance) {
}
HostZoomMap* HostZoomMap::GetForWebContents(const WebContents* contents) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
// TODO(wjmaclean): Update this behaviour to work with OOPIF.
// See crbug.com/528407.
StoragePartition* partition =
@@ -89,6 +93,7 @@ HostZoomMap* HostZoomMap::GetForWebContents(const WebContents* contents) {
// Helper function for setting/getting zoom levels for WebContents without
// having to import HostZoomMapImpl everywhere.
double HostZoomMap::GetZoomLevel(const WebContents* web_contents) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
HostZoomMap::GetForWebContents(web_contents));
return host_zoom_map->GetZoomLevelForWebContents(
@@ -96,6 +101,7 @@ double HostZoomMap::GetZoomLevel(const WebContents* web_contents) {
}
bool HostZoomMap::PageScaleFactorIsOne(const WebContents* web_contents) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
HostZoomMap::GetForWebContents(web_contents));
return host_zoom_map->PageScaleFactorIsOneForWebContents(
@@ -103,6 +109,7 @@ bool HostZoomMap::PageScaleFactorIsOne(const WebContents* web_contents) {
}
void HostZoomMap::SetZoomLevel(const WebContents* web_contents, double level) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
HostZoomMap::GetForWebContents(web_contents));
host_zoom_map->SetZoomLevelForWebContents(
@@ -111,6 +118,7 @@ void HostZoomMap::SetZoomLevel(const WebContents* web_contents, double level) {
void HostZoomMap::SendErrorPageZoomLevelRefresh(
const WebContents* web_contents) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
HostZoomMapImpl* host_zoom_map =
static_cast<HostZoomMapImpl*>(HostZoomMap::GetDefaultForBrowserContext(
web_contents->GetBrowserContext()));
@@ -120,44 +128,32 @@ void HostZoomMap::SendErrorPageZoomLevelRefresh(
HostZoomMapImpl::HostZoomMapImpl()
: default_zoom_level_(0.0),
store_last_modified_(false),
- clock_(new base::DefaultClock) {}
+ clock_(base::DefaultClock::GetInstance()) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+}
void HostZoomMapImpl::CopyFrom(HostZoomMap* copy_interface) {
- // This can only be called on the UI thread to avoid deadlocks, otherwise
- // UI: a.CopyFrom(b);
- // IO: b.CopyFrom(a);
- // can deadlock.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
HostZoomMapImpl* copy = static_cast<HostZoomMapImpl*>(copy_interface);
- base::AutoLock auto_lock(lock_);
- base::AutoLock copy_auto_lock(copy->lock_);
- host_zoom_levels_.
- insert(copy->host_zoom_levels_.begin(), copy->host_zoom_levels_.end());
- for (SchemeHostZoomLevels::const_iterator i(copy->
- scheme_host_zoom_levels_.begin());
- i != copy->scheme_host_zoom_levels_.end(); ++i) {
- scheme_host_zoom_levels_[i->first] = HostZoomLevels();
- scheme_host_zoom_levels_[i->first].
- insert(i->second.begin(), i->second.end());
+ host_zoom_levels_.insert(copy->host_zoom_levels_.begin(),
+ copy->host_zoom_levels_.end());
+ for (const auto& it : copy->scheme_host_zoom_levels_) {
+ const std::string& host = it.first;
+ scheme_host_zoom_levels_[host] = HostZoomLevels();
+ scheme_host_zoom_levels_[host].insert(it.second.begin(), it.second.end());
}
default_zoom_level_ = copy->default_zoom_level_;
}
double HostZoomMapImpl::GetZoomLevelForHost(const std::string& host) const {
- base::AutoLock auto_lock(lock_);
- return GetZoomLevelForHostInternal(host);
-}
-
-double HostZoomMapImpl::GetZoomLevelForHostInternal(
- const std::string& host) const {
- HostZoomLevels::const_iterator i(host_zoom_levels_.find(host));
- return (i == host_zoom_levels_.end()) ? default_zoom_level_ : i->second.level;
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ const auto it = host_zoom_levels_.find(host);
+ return it != host_zoom_levels_.end() ? it->second.level : default_zoom_level_;
}
bool HostZoomMapImpl::HasZoomLevel(const std::string& scheme,
const std::string& host) const {
- base::AutoLock auto_lock(lock_);
-
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
SchemeHostZoomLevels::const_iterator scheme_iterator(
scheme_host_zoom_levels_.find(scheme));
@@ -166,13 +162,13 @@ bool HostZoomMapImpl::HasZoomLevel(const std::string& scheme,
? scheme_iterator->second
: host_zoom_levels_;
- HostZoomLevels::const_iterator i(zoom_levels.find(host));
- return i != zoom_levels.end();
+ return base::ContainsKey(zoom_levels, host);
}
-double HostZoomMapImpl::GetZoomLevelForHostAndSchemeInternal(
+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));
if (scheme_iterator != scheme_host_zoom_levels_.end()) {
@@ -181,51 +177,43 @@ double HostZoomMapImpl::GetZoomLevelForHostAndSchemeInternal(
return i->second.level;
}
- return GetZoomLevelForHostInternal(host);
-}
-
-double HostZoomMapImpl::GetZoomLevelForHostAndScheme(
- const std::string& scheme,
- const std::string& host) const {
- base::AutoLock auto_lock(lock_);
- return GetZoomLevelForHostAndSchemeInternal(scheme, host);
+ return GetZoomLevelForHost(host);
}
HostZoomMap::ZoomLevelVector HostZoomMapImpl::GetAllZoomLevels() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
HostZoomMap::ZoomLevelVector result;
- {
- base::AutoLock auto_lock(lock_);
- result.reserve(host_zoom_levels_.size() + scheme_host_zoom_levels_.size());
- for (const auto& entry : host_zoom_levels_) {
+ result.reserve(host_zoom_levels_.size() + scheme_host_zoom_levels_.size());
+ for (const auto& entry : host_zoom_levels_) {
+ ZoomLevelChange change = {
+ HostZoomMap::ZOOM_CHANGED_FOR_HOST,
+ entry.first, // host
+ std::string(), // scheme
+ entry.second.level, // zoom level
+ entry.second.last_modified // last modified
+ };
+ result.push_back(change);
+ }
+ for (const auto& scheme_entry : scheme_host_zoom_levels_) {
+ const std::string& scheme = scheme_entry.first;
+ const HostZoomLevels& host_zoom_levels = scheme_entry.second;
+ for (const auto& entry : host_zoom_levels) {
ZoomLevelChange change = {
- HostZoomMap::ZOOM_CHANGED_FOR_HOST,
+ HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST,
entry.first, // host
- std::string(), // scheme
+ scheme, // scheme
entry.second.level, // zoom level
entry.second.last_modified // last modified
};
result.push_back(change);
}
- for (const auto& scheme_entry : scheme_host_zoom_levels_) {
- const std::string& scheme = scheme_entry.first;
- const HostZoomLevels& host_zoom_levels = scheme_entry.second;
- for (const auto& entry : host_zoom_levels) {
- ZoomLevelChange change = {
- HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST,
- entry.first, // host
- scheme, // scheme
- entry.second.level, // zoom level
- entry.second.last_modified // last modified
- };
- result.push_back(change);
- }
- }
}
return result;
}
void HostZoomMapImpl::SetZoomLevelForHost(const std::string& host,
double level) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::Time last_modified =
store_last_modified_ ? clock_->Now() : base::Time();
SetZoomLevelForHostInternal(host, level, last_modified);
@@ -234,6 +222,7 @@ void HostZoomMapImpl::SetZoomLevelForHost(const std::string& host,
void HostZoomMapImpl::InitializeZoomLevelForHost(const std::string& host,
double level,
base::Time last_modified) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
SetZoomLevelForHostInternal(host, level, last_modified);
}
@@ -242,16 +231,12 @@ void HostZoomMapImpl::SetZoomLevelForHostInternal(const std::string& host,
base::Time last_modified) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- {
- base::AutoLock auto_lock(lock_);
-
- if (ZoomValuesEqual(level, default_zoom_level_)) {
- host_zoom_levels_.erase(host);
- } else {
- ZoomLevel& zoomLevel = host_zoom_levels_[host];
- zoomLevel.level = level;
- zoomLevel.last_modified = last_modified;
- }
+ if (ZoomValuesEqual(level, default_zoom_level_)) {
+ host_zoom_levels_.erase(host);
+ } else {
+ ZoomLevel& zoomLevel = host_zoom_levels_[host];
+ zoomLevel.level = level;
+ zoomLevel.last_modified = last_modified;
}
// TODO(wjmaclean) Should we use a GURL here? crbug.com/384486
@@ -270,12 +255,9 @@ void HostZoomMapImpl::SetZoomLevelForHostAndScheme(const std::string& scheme,
const std::string& host,
double level) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- {
- base::AutoLock auto_lock(lock_);
- // No last_modified timestamp for scheme and host because they are
- // not persistet and are used for special cases only.
- scheme_host_zoom_levels_[scheme][host].level = level;
- }
+ // No last_modified timestamp for scheme and host because they are
+ // not persistet and are used for special cases only.
+ scheme_host_zoom_levels_[scheme][host].level = level;
SendZoomLevelChange(scheme, host, level);
@@ -303,14 +285,11 @@ void HostZoomMapImpl::SetDefaultZoomLevel(double level) {
default_zoom_level_ = level;
// First, remove all entries that match the new default zoom level.
- {
- base::AutoLock auto_lock(lock_);
- for (auto it = host_zoom_levels_.begin(); it != host_zoom_levels_.end(); ) {
- if (ZoomValuesEqual(it->second.level, default_zoom_level_))
- it = host_zoom_levels_.erase(it);
- else
- it++;
- }
+ for (auto it = host_zoom_levels_.begin(); it != host_zoom_levels_.end();) {
+ if (ZoomValuesEqual(it->second.level, default_zoom_level_))
+ it = host_zoom_levels_.erase(it);
+ else
+ it++;
}
// Second, update zoom levels for all pages that do not have an overriding
@@ -362,11 +341,13 @@ void HostZoomMapImpl::SetDefaultZoomLevel(double level) {
std::unique_ptr<HostZoomMap::Subscription>
HostZoomMapImpl::AddZoomLevelChangedCallback(
const ZoomLevelChangedCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
return zoom_level_changed_callbacks_.Add(callback);
}
double HostZoomMapImpl::GetZoomLevelForWebContents(
const WebContentsImpl& web_contents_impl) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
int render_process_id =
web_contents_impl.GetRenderViewHost()->GetProcess()->GetID();
int routing_id = web_contents_impl.GetRenderViewHost()->GetRoutingID();
@@ -391,6 +372,7 @@ double HostZoomMapImpl::GetZoomLevelForWebContents(
void HostZoomMapImpl::SetZoomLevelForWebContents(
const WebContentsImpl& web_contents_impl,
double level) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
int render_process_id =
web_contents_impl.GetRenderViewHost()->GetProcess()->GetID();
int render_view_id = web_contents_impl.GetRenderViewHost()->GetRoutingID();
@@ -417,6 +399,7 @@ void HostZoomMapImpl::SetZoomLevelForView(int render_process_id,
int render_view_id,
double level,
const std::string& host) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (UsesTemporaryZoomLevel(render_process_id, render_view_id))
SetTemporaryZoomLevel(render_process_id, render_view_id, level);
else
@@ -426,11 +409,9 @@ void HostZoomMapImpl::SetZoomLevelForView(int render_process_id,
void HostZoomMapImpl::SetPageScaleFactorIsOneForView(int render_process_id,
int render_view_id,
bool is_one) {
- {
- base::AutoLock auto_lock(lock_);
- view_page_scale_factors_are_one_[RenderViewKey(render_process_id,
- render_view_id)] = is_one;
- }
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ view_page_scale_factors_are_one_[RenderViewKey(render_process_id,
+ render_view_id)] = is_one;
HostZoomMap::ZoomLevelChange change;
change.mode = HostZoomMap::PAGE_SCALE_IS_ONE_CHANGED;
zoom_level_changed_callbacks_.Notify(change);
@@ -438,40 +419,36 @@ void HostZoomMapImpl::SetPageScaleFactorIsOneForView(int render_process_id,
bool HostZoomMapImpl::PageScaleFactorIsOneForWebContents(
const WebContentsImpl& web_contents_impl) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!web_contents_impl.GetRenderViewHost()->GetProcess())
return true;
- base::AutoLock auto_lock(lock_);
- auto found = view_page_scale_factors_are_one_.find(RenderViewKey(
+
+ const auto it = view_page_scale_factors_are_one_.find(RenderViewKey(
web_contents_impl.GetRenderViewHost()->GetProcess()->GetID(),
web_contents_impl.GetRenderViewHost()->GetRoutingID()));
- if (found == view_page_scale_factors_are_one_.end())
- return true;
- return found->second;
+ return it != view_page_scale_factors_are_one_.end() ? it->second : true;
}
void HostZoomMapImpl::ClearPageScaleFactorIsOneForView(int render_process_id,
int render_view_id) {
- base::AutoLock auto_lock(lock_);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
view_page_scale_factors_are_one_.erase(
RenderViewKey(render_process_id, render_view_id));
}
bool HostZoomMapImpl::UsesTemporaryZoomLevel(int render_process_id,
int render_view_id) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderViewKey key(render_process_id, render_view_id);
-
- base::AutoLock auto_lock(lock_);
return base::ContainsKey(temporary_zoom_levels_, key);
}
double HostZoomMapImpl::GetTemporaryZoomLevel(int render_process_id,
int render_view_id) const {
- base::AutoLock auto_lock(lock_);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderViewKey key(render_process_id, render_view_id);
- if (!base::ContainsKey(temporary_zoom_levels_, key))
- return 0;
-
- return temporary_zoom_levels_.find(key)->second;
+ const auto it = temporary_zoom_levels_.find(key);
+ return it != temporary_zoom_levels_.end() ? it->second : 0;
}
void HostZoomMapImpl::SetTemporaryZoomLevel(int render_process_id,
@@ -479,11 +456,8 @@ void HostZoomMapImpl::SetTemporaryZoomLevel(int render_process_id,
double level) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- {
- RenderViewKey key(render_process_id, render_view_id);
- base::AutoLock auto_lock(lock_);
- temporary_zoom_levels_[key] = level;
- }
+ RenderViewKey key(render_process_id, render_view_id);
+ temporary_zoom_levels_[key] = level;
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(
@@ -501,20 +475,21 @@ void HostZoomMapImpl::SetTemporaryZoomLevel(int render_process_id,
double HostZoomMapImpl::GetZoomLevelForView(const GURL& url,
int render_process_id,
int render_view_id) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderViewKey key(render_process_id, render_view_id);
- base::AutoLock auto_lock(lock_);
if (base::ContainsKey(temporary_zoom_levels_, key))
return temporary_zoom_levels_.find(key)->second;
- return GetZoomLevelForHostAndSchemeInternal(url.scheme(),
- net::GetHostOrSpecFromURL(url));
+ return GetZoomLevelForHostAndScheme(url.scheme(),
+ net::GetHostOrSpecFromURL(url));
}
void HostZoomMapImpl::ClearZoomLevels(base::Time delete_begin,
base::Time delete_end) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
double default_zoom_level = GetDefaultZoomLevel();
- for (auto& zoom_level : GetAllZoomLevels()) {
+ for (const auto& zoom_level : GetAllZoomLevels()) {
if (zoom_level.scheme.empty() && delete_begin <= zoom_level.last_modified &&
(delete_end.is_null() || zoom_level.last_modified < delete_end)) {
SetZoomLevelForHost(zoom_level.host, default_zoom_level);
@@ -523,19 +498,19 @@ void HostZoomMapImpl::ClearZoomLevels(base::Time delete_begin,
}
void HostZoomMapImpl::SetStoreLastModified(bool store_last_modified) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
store_last_modified_ = store_last_modified;
}
void HostZoomMapImpl::ClearTemporaryZoomLevel(int render_process_id,
int render_view_id) {
- {
- base::AutoLock auto_lock(lock_);
- RenderViewKey key(render_process_id, render_view_id);
- TemporaryZoomLevels::iterator it = temporary_zoom_levels_.find(key);
- if (it == temporary_zoom_levels_.end())
- return;
- temporary_zoom_levels_.erase(it);
- }
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RenderViewKey key(render_process_id, render_view_id);
+ TemporaryZoomLevels::iterator it = temporary_zoom_levels_.find(key);
+ if (it == temporary_zoom_levels_.end())
+ return;
+
+ temporary_zoom_levels_.erase(it);
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(
RenderViewHost::FromID(render_process_id, render_view_id)));
@@ -546,6 +521,7 @@ void HostZoomMapImpl::ClearTemporaryZoomLevel(int render_process_id,
void HostZoomMapImpl::SendZoomLevelChange(const std::string& scheme,
const std::string& host,
double level) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
// We'll only send to WebContents not using temporary zoom levels. The one
// other case of interest is where the renderer is hosting a plugin document;
// that should be reflected in our temporary zoom level map, but we will
@@ -566,6 +542,7 @@ void HostZoomMapImpl::SendZoomLevelChange(const std::string& scheme,
}
void HostZoomMapImpl::SendErrorPageZoomLevelRefresh() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
GURL error_url(kUnreachableWebDataURL);
std::string host = net::GetHostOrSpecFromURL(error_url);
double error_page_zoom_level = GetZoomLevelForHost(host);
@@ -575,6 +552,7 @@ void HostZoomMapImpl::SendErrorPageZoomLevelRefresh() {
void HostZoomMapImpl::WillCloseRenderView(int render_process_id,
int render_view_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
ClearTemporaryZoomLevel(render_process_id, render_view_id);
ClearPageScaleFactorIsOneForView(render_process_id, render_view_id);
}
@@ -583,8 +561,8 @@ HostZoomMapImpl::~HostZoomMapImpl() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
-void HostZoomMapImpl::SetClockForTesting(std::unique_ptr<base::Clock> clock) {
- clock_ = std::move(clock);
+void HostZoomMapImpl::SetClockForTesting(base::Clock* clock) {
+ clock_ = clock;
}
} // namespace content
diff --git a/chromium/content/browser/host_zoom_map_impl.h b/chromium/content/browser/host_zoom_map_impl.h
index 418acedf75c..c3d813d5229 100644
--- a/chromium/content/browser/host_zoom_map_impl.h
+++ b/chromium/content/browser/host_zoom_map_impl.h
@@ -13,15 +13,13 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/sequenced_task_runner_helpers.h"
-#include "base/synchronization/lock.h"
#include "content/public/browser/host_zoom_map.h"
namespace content {
class WebContentsImpl;
-// HostZoomMap needs to be deleted on the UI thread because it listens
-// to notifications on there.
+// HostZoomMap lives on the UI thread.
class CONTENT_EXPORT HostZoomMapImpl : public HostZoomMap {
public:
HostZoomMapImpl();
@@ -84,15 +82,11 @@ class CONTENT_EXPORT HostZoomMapImpl : public HostZoomMap {
// Returns the temporary zoom level that's only valid for the lifetime of
// the given WebContents (i.e. isn't saved and doesn't affect other
// WebContentses) if it exists, the default zoom level otherwise.
- //
- // This may be called on any thread.
double GetTemporaryZoomLevel(int render_process_id,
int render_view_id) const;
// Returns the zoom level regardless of whether it's temporary, host-keyed or
// scheme+host-keyed.
- //
- // This may be called on any thread.
double GetZoomLevelForView(const GURL& url,
int render_process_id,
int render_view_id) const;
@@ -101,7 +95,7 @@ class CONTENT_EXPORT HostZoomMapImpl : public HostZoomMap {
void WillCloseRenderView(int render_process_id, int render_view_id);
- void SetClockForTesting(std::unique_ptr<base::Clock> clock) override;
+ void SetClockForTesting(base::Clock* clock) override;
private:
struct ZoomLevel {
@@ -128,12 +122,6 @@ class CONTENT_EXPORT HostZoomMapImpl : public HostZoomMap {
double GetZoomLevelForHost(const std::string& host) const;
- // Non-locked versions for internal use. These should only be called within
- // a scope where a lock has been acquired.
- double GetZoomLevelForHostInternal(const std::string& host) const;
- double GetZoomLevelForHostAndSchemeInternal(const std::string& scheme,
- const std::string& host) const;
-
// Set a zoom level for |host| and store the |last_modified| timestamp.
// Use only to explicitly set a timestamp.
void SetZoomLevelForHostInternal(const std::string& host,
@@ -151,7 +139,7 @@ class CONTENT_EXPORT HostZoomMapImpl : public HostZoomMap {
base::CallbackList<void(const ZoomLevelChange&)>
zoom_level_changed_callbacks_;
- // Copy of the pref data, so that we can read it on the IO thread.
+ // Copy of the pref data.
HostZoomLevels host_zoom_levels_;
SchemeHostZoomLevels scheme_host_zoom_levels_;
double default_zoom_level_;
@@ -161,14 +149,9 @@ class CONTENT_EXPORT HostZoomMapImpl : public HostZoomMap {
TemporaryZoomLevels temporary_zoom_levels_;
- // Used around accesses to |host_zoom_levels_|, |default_zoom_level_|,
- // |temporary_zoom_levels_|, and |view_page_scale_factors_are_one_| to
- // guarantee thread safety.
- mutable base::Lock lock_;
-
bool store_last_modified_;
- std::unique_ptr<base::Clock> clock_;
+ base::Clock* clock_;
DISALLOW_COPY_AND_ASSIGN(HostZoomMapImpl);
};
diff --git a/chromium/content/browser/host_zoom_map_impl_unittest.cc b/chromium/content/browser/host_zoom_map_impl_unittest.cc
index a7df2efaab1..843f88a6188 100644
--- a/chromium/content/browser/host_zoom_map_impl_unittest.cc
+++ b/chromium/content/browser/host_zoom_map_impl_unittest.cc
@@ -93,16 +93,15 @@ TEST_F(HostZoomMapTest, LastModifiedTimestamp) {
host_zoom_map.SetStoreLastModified(true);
base::Time now = base::Time::Now();
- auto test_clock = base::MakeUnique<base::SimpleTestClock>();
- base::SimpleTestClock* clock = test_clock.get();
- host_zoom_map.SetClockForTesting(std::move(test_clock));
+ base::SimpleTestClock test_clock;
+ host_zoom_map.SetClockForTesting(&test_clock);
- clock->SetNow(now);
+ test_clock.SetNow(now);
host_zoom_map.SetZoomLevelForHost("zoomed.com", 1.5);
host_zoom_map.SetZoomLevelForHost("zoomed2.com", 2.0);
base::Time later = now + base::TimeDelta::FromSeconds(1);
- clock->SetNow(later);
+ test_clock.SetNow(later);
host_zoom_map.SetZoomLevelForHost("zoomed2.com", 2.5);
host_zoom_map.SetZoomLevelForHost("zoomzoom.com", 3);
host_zoom_map.SetZoomLevelForHostAndScheme("chrome", "login", 3);
@@ -131,14 +130,13 @@ TEST_F(HostZoomMapTest, ClearZoomLevels) {
HostZoomMapImpl host_zoom_map;
host_zoom_map.SetStoreLastModified(true);
- auto test_clock = base::MakeUnique<base::SimpleTestClock>();
- base::SimpleTestClock* clock = test_clock.get();
- host_zoom_map.SetClockForTesting(std::move(test_clock));
+ base::SimpleTestClock test_clock;
+ host_zoom_map.SetClockForTesting(&test_clock);
base::Time now = base::Time::Now();
- clock->SetNow(now - base::TimeDelta::FromHours(3));
+ test_clock.SetNow(now - base::TimeDelta::FromHours(3));
host_zoom_map.SetZoomLevelForHost("zoomzoom.com", 3.5);
- clock->SetNow(now - base::TimeDelta::FromHours(1));
+ test_clock.SetNow(now - base::TimeDelta::FromHours(1));
host_zoom_map.SetZoomLevelForHost("zoom.com", 1.5);
EXPECT_EQ(2u, host_zoom_map.GetAllZoomLevels().size());
diff --git a/chromium/content/browser/host_zoom_map_observer.cc b/chromium/content/browser/host_zoom_map_observer.cc
index 90f2695a32d..beefe1e282b 100644
--- a/chromium/content/browser/host_zoom_map_observer.cc
+++ b/chromium/content/browser/host_zoom_map_observer.cc
@@ -9,7 +9,7 @@
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/storage_partition.h"
-#include "content/public/common/associated_interface_provider.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
namespace content {
diff --git a/chromium/content/browser/hyphenation/hyphenation_impl.cc b/chromium/content/browser/hyphenation/hyphenation_impl.cc
index d7ebbfa1d5e..a943bf4297a 100644
--- a/chromium/content/browser/hyphenation/hyphenation_impl.cc
+++ b/chromium/content/browser/hyphenation/hyphenation_impl.cc
@@ -62,7 +62,7 @@ HyphenationImpl::~HyphenationImpl() {}
// static
void HyphenationImpl::Create(blink::mojom::HyphenationRequest request) {
- mojo::MakeStrongBinding(base::MakeUnique<HyphenationImpl>(),
+ mojo::MakeStrongBinding(std::make_unique<HyphenationImpl>(),
std::move(request));
}
diff --git a/chromium/content/browser/image_capture/image_capture_impl.cc b/chromium/content/browser/image_capture/image_capture_impl.cc
index 91865a783be..dabcc914bdb 100644
--- a/chromium/content/browser/image_capture/image_capture_impl.cc
+++ b/chromium/content/browser/image_capture/image_capture_impl.cc
@@ -98,7 +98,7 @@ void ImageCaptureImpl::Create(
if (!base::FeatureList::IsEnabled(features::kImageCaptureAPI))
return;
- mojo::MakeStrongBinding(base::MakeUnique<ImageCaptureImpl>(),
+ mojo::MakeStrongBinding(std::make_unique<ImageCaptureImpl>(),
std::move(request));
}
diff --git a/chromium/content/browser/indexed_db/cursor_impl.cc b/chromium/content/browser/indexed_db/cursor_impl.cc
index fd8a17acdf3..0e5b3099b83 100644
--- a/chromium/content/browser/indexed_db/cursor_impl.cc
+++ b/chromium/content/browser/indexed_db/cursor_impl.cc
@@ -111,8 +111,8 @@ void CursorImpl::IDBSequenceHelper::Continue(
const IndexedDBKey& primary_key,
scoped_refptr<IndexedDBCallbacks> callbacks) {
cursor_->Continue(
- key.IsValid() ? base::MakeUnique<IndexedDBKey>(key) : nullptr,
- primary_key.IsValid() ? base::MakeUnique<IndexedDBKey>(primary_key)
+ key.IsValid() ? std::make_unique<IndexedDBKey>(key) : nullptr,
+ primary_key.IsValid() ? std::make_unique<IndexedDBKey>(primary_key)
: nullptr,
std::move(callbacks));
}
diff --git a/chromium/content/browser/indexed_db/database_impl.cc b/chromium/content/browser/indexed_db/database_impl.cc
index 9799c389c24..3bba48262ba 100644
--- a/chromium/content/browser/indexed_db/database_impl.cc
+++ b/chromium/content/browser/indexed_db/database_impl.cc
@@ -631,7 +631,7 @@ void DatabaseImpl::IDBSequenceHelper::Get(
return;
connection_->database()->Get(transaction, object_store_id, index_id,
- base::MakeUnique<IndexedDBKeyRange>(key_range),
+ std::make_unique<IndexedDBKeyRange>(key_range),
key_only, callbacks);
}
@@ -654,7 +654,7 @@ void DatabaseImpl::IDBSequenceHelper::GetAll(
connection_->database()->GetAll(
transaction, object_store_id, index_id,
- base::MakeUnique<IndexedDBKeyRange>(key_range), key_only, max_count,
+ std::make_unique<IndexedDBKeyRange>(key_range), key_only, max_count,
std::move(callbacks));
}
@@ -687,7 +687,7 @@ void DatabaseImpl::IDBSequenceHelper::Put(
swap(value.bits, mojo_value->bits);
swap(value.blob_info, blob_info);
connection_->database()->Put(transaction, object_store_id, &value, &handles,
- base::MakeUnique<IndexedDBKey>(key), mode,
+ std::make_unique<IndexedDBKey>(key), mode,
std::move(callbacks), index_keys);
// Size can't be big enough to overflow because it represents the
@@ -710,7 +710,7 @@ void DatabaseImpl::IDBSequenceHelper::SetIndexKeys(
return;
connection_->database()->SetIndexKeys(
- transaction, object_store_id, base::MakeUnique<IndexedDBKey>(primary_key),
+ transaction, object_store_id, std::make_unique<IndexedDBKey>(primary_key),
index_keys);
}
@@ -751,7 +751,7 @@ void DatabaseImpl::IDBSequenceHelper::OpenCursor(
connection_->database()->OpenCursor(
transaction, object_store_id, index_id,
- base::MakeUnique<IndexedDBKeyRange>(key_range), direction, key_only,
+ std::make_unique<IndexedDBKeyRange>(key_range), direction, key_only,
task_type, std::move(callbacks));
}
@@ -771,7 +771,7 @@ void DatabaseImpl::IDBSequenceHelper::Count(
return;
connection_->database()->Count(transaction, object_store_id, index_id,
- base::MakeUnique<IndexedDBKeyRange>(key_range),
+ std::make_unique<IndexedDBKeyRange>(key_range),
std::move(callbacks));
}
@@ -790,7 +790,7 @@ void DatabaseImpl::IDBSequenceHelper::DeleteRange(
connection_->database()->DeleteRange(
transaction, object_store_id,
- base::MakeUnique<IndexedDBKeyRange>(key_range), std::move(callbacks));
+ std::make_unique<IndexedDBKeyRange>(key_range), std::move(callbacks));
}
void DatabaseImpl::IDBSequenceHelper::Clear(
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 883ec0d8c28..700d595c1f4 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
@@ -135,7 +135,7 @@ base::Closure IndexedDBActiveBlobRegistry::GetAddBlobRefCallback(
void IndexedDBActiveBlobRegistry::ForceShutdown() {
weak_factory_.InvalidateWeakPtrs();
use_tracker_.clear();
- backing_store_ = NULL;
+ backing_store_ = nullptr;
}
} // namespace content
diff --git a/chromium/content/browser/indexed_db/indexed_db_active_blob_registry_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_active_blob_registry_unittest.cc
index 8b6eccc2492..01b85d834da 100644
--- a/chromium/content/browser/indexed_db/indexed_db_active_blob_registry_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_active_blob_registry_unittest.cc
@@ -108,7 +108,7 @@ class IndexedDBActiveBlobRegistryTest : public testing::Test {
factory_(new RegistryTestMockFactory),
backing_store_(
new MockIDBBackingStore(factory_.get(), task_runner_.get())),
- registry_(base::MakeUnique<IndexedDBActiveBlobRegistry>(
+ registry_(std::make_unique<IndexedDBActiveBlobRegistry>(
backing_store_.get())) {}
void RunUntilIdle() { task_runner_->RunUntilIdle(); }
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 9efac70bb65..236e4ee09c6 100644
--- a/chromium/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -395,8 +395,8 @@ Status DeleteBlobsInRange(IndexedDBBackingStore::Transaction* transaction,
INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
return InternalInconsistencyStatus();
}
- transaction->PutBlobInfo(database_id, object_store_id, user_key, NULL,
- NULL);
+ transaction->PutBlobInfo(database_id, object_store_id, user_key, nullptr,
+ nullptr);
}
return s;
}
@@ -865,7 +865,7 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
data_loss_info->status = blink::kWebIDBDataLossNone;
*status = Status::OK();
- std::unique_ptr<LevelDBComparator> comparator(base::MakeUnique<Comparator>());
+ std::unique_ptr<LevelDBComparator> comparator(std::make_unique<Comparator>());
if (!base::IsStringASCII(path_base.AsUTF8Unsafe())) {
HistogramOpenStatus(
@@ -967,7 +967,7 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
LOG(ERROR) << "IndexedDB backing store cleanup succeeded, reopening";
*status =
- leveldb_factory->OpenLevelDB(file_path, comparator.get(), &db, NULL);
+ leveldb_factory->OpenLevelDB(file_path, comparator.get(), &db, nullptr);
if (!status->ok()) {
DCHECK(!db);
LOG(ERROR) << "IndexedDB backing store reopen after recovery failed";
@@ -1021,7 +1021,7 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory(
Status* status) {
IDB_TRACE("IndexedDBBackingStore::OpenInMemory");
- std::unique_ptr<LevelDBComparator> comparator(base::MakeUnique<Comparator>());
+ std::unique_ptr<LevelDBComparator> comparator(std::make_unique<Comparator>());
std::unique_ptr<LevelDBDatabase> db =
LevelDBDatabase::OpenInMemory(comparator.get());
if (!db) {
@@ -1037,8 +1037,8 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory(
db.get(), "IndexedDBBackingStore", task_runner,
base::trace_event::MemoryDumpProvider::Options());
- return Create(NULL /* indexed_db_factory */, origin, FilePath(),
- NULL /* request_context */, std::move(db),
+ return Create(nullptr /* indexed_db_factory */, origin, FilePath(),
+ nullptr /* request_context */, std::move(db),
std::move(comparator), task_runner, status);
}
@@ -1260,7 +1260,7 @@ Status IndexedDBBackingStore::DeleteRecord(
database_id, object_store_id, record_identifier.primary_key());
leveldb_transaction->Remove(object_store_data_key);
Status s = transaction->PutBlobInfoIfNeeded(
- database_id, object_store_id, object_store_data_key, NULL, NULL);
+ database_id, object_store_id, object_store_data_key, nullptr, nullptr);
if (!s.ok())
return s;
@@ -1490,7 +1490,7 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
content::BrowserThread::DeleteSoon(
content::BrowserThread::IO, FROM_HERE, delegate_.release());
if (aborted_) {
- self_ref_ = NULL;
+ self_ref_ = nullptr;
return;
}
if (iter_->size() != -1 && iter_->size() != bytes_written)
@@ -1601,7 +1601,7 @@ class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
task_runner_.get(), file_path, 0,
storage::FileStreamWriter::CREATE_NEW_FILE));
std::unique_ptr<FileWriterDelegate> delegate(
- base::MakeUnique<FileWriterDelegate>(
+ std::make_unique<FileWriterDelegate>(
std::move(writer), storage::FlushPolicy::FLUSH_ON_COMPLETION));
DCHECK(blob_url.is_valid());
@@ -1653,7 +1653,7 @@ class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
IndexedDBBackingStore::Transaction::ChainedBlobWriter* raw_tmp =
chained_blob_writer_.get();
raw_tmp->AddRef();
- chained_blob_writer_ = NULL;
+ chained_blob_writer_ = nullptr;
task_runner_->ReleaseSoon(FROM_HERE, raw_tmp);
}
friend class base::RefCountedThreadSafe<LocalWriteClosure>;
@@ -2179,7 +2179,7 @@ IndexedDBBackingStore::Cursor::Cursor(
transaction_(other->transaction_),
database_id_(other->database_id_),
cursor_options_(other->cursor_options_),
- current_key_(base::MakeUnique<IndexedDBKey>(*other->current_key_)) {
+ current_key_(std::make_unique<IndexedDBKey>(*other->current_key_)) {
if (other->iterator_) {
iterator_ = transaction_->transaction()->CreateIterator();
@@ -2213,7 +2213,7 @@ bool IndexedDBBackingStore::Cursor::FirstSeek(Status* s) {
if (!s->ok())
return false;
}
- return Continue(0, READY, s);
+ return Continue(nullptr, READY, s);
}
bool IndexedDBBackingStore::Cursor::Advance(uint32_t count, Status* s) {
@@ -2469,7 +2469,7 @@ class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor {
// IndexedDBBackingStore::Cursor
IndexedDBValue* value() override {
NOTREACHED();
- return NULL;
+ return nullptr;
}
bool LoadCurrentRow(Status* s) override;
@@ -2620,7 +2620,7 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
// IndexedDBBackingStore::Cursor
IndexedDBValue* value() override {
NOTREACHED();
- return NULL;
+ return nullptr;
}
const IndexedDBKey& primary_key() const override { return *primary_key_; }
const IndexedDBBackingStore::RecordIdentifier& record_identifier()
@@ -2649,7 +2649,7 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
private:
explicit IndexKeyCursorImpl(const IndexKeyCursorImpl* other)
: IndexedDBBackingStore::Cursor(other),
- primary_key_(base::MakeUnique<IndexedDBKey>(*other->primary_key_)) {}
+ primary_key_(std::make_unique<IndexedDBKey>(*other->primary_key_)) {}
std::unique_ptr<IndexedDBKey> primary_key_;
@@ -2763,7 +2763,7 @@ class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
private:
explicit IndexCursorImpl(const IndexCursorImpl* other)
: IndexedDBBackingStore::Cursor(other),
- primary_key_(base::MakeUnique<IndexedDBKey>(*other->primary_key_)),
+ primary_key_(std::make_unique<IndexedDBKey>(*other->primary_key_)),
current_value_(other->current_value_),
primary_leveldb_key_(other->primary_leveldb_key_) {}
@@ -2867,7 +2867,7 @@ IndexedDBBackingStore::OpenObjectStoreCursor(
return std::unique_ptr<IndexedDBBackingStore::Cursor>();
}
std::unique_ptr<ObjectStoreCursorImpl> cursor(
- base::MakeUnique<ObjectStoreCursorImpl>(this, transaction, database_id,
+ std::make_unique<ObjectStoreCursorImpl>(this, transaction, database_id,
cursor_options));
if (!cursor->FirstSeek(s))
return std::unique_ptr<IndexedDBBackingStore::Cursor>();
@@ -2893,7 +2893,7 @@ IndexedDBBackingStore::OpenObjectStoreKeyCursor(
return std::unique_ptr<IndexedDBBackingStore::Cursor>();
}
std::unique_ptr<ObjectStoreKeyCursorImpl> cursor(
- base::MakeUnique<ObjectStoreKeyCursorImpl>(this, transaction, database_id,
+ std::make_unique<ObjectStoreKeyCursorImpl>(this, transaction, database_id,
cursor_options));
if (!cursor->FirstSeek(s))
return std::unique_ptr<IndexedDBBackingStore::Cursor>();
@@ -2918,7 +2918,7 @@ IndexedDBBackingStore::OpenIndexKeyCursor(
index_id, range, direction, &cursor_options, s))
return std::unique_ptr<IndexedDBBackingStore::Cursor>();
std::unique_ptr<IndexKeyCursorImpl> cursor(
- base::MakeUnique<IndexKeyCursorImpl>(this, transaction, database_id,
+ std::make_unique<IndexKeyCursorImpl>(this, transaction, database_id,
cursor_options));
if (!cursor->FirstSeek(s))
return std::unique_ptr<IndexedDBBackingStore::Cursor>();
@@ -3061,7 +3061,7 @@ bool IndexedDBBackingStore::Transaction::CollectBlobFilesToRemove() {
if (!BlobEntryKey::FromObjectStoreDataKey(&key_piece, &blob_entry_key)) {
NOTREACHED();
INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD);
- transaction_ = NULL;
+ transaction_ = nullptr;
return false;
}
if (database_id_ < 0)
@@ -3077,7 +3077,7 @@ bool IndexedDBBackingStore::Transaction::CollectBlobFilesToRemove() {
std::vector<IndexedDBBlobInfo> blob_info;
if (!DecodeBlobData(blob_entry_value_bytes, &blob_info)) {
INTERNAL_READ_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD);
- transaction_ = NULL;
+ transaction_ = nullptr;
return false;
}
for (const auto& blob : blob_info) {
@@ -3115,7 +3115,7 @@ Status IndexedDBBackingStore::Transaction::CommitPhaseOne(
s = HandleBlobPreTransaction(&new_blob_entries, &new_files_to_write);
if (!s.ok()) {
INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD);
- transaction_ = NULL;
+ transaction_ = nullptr;
return s;
}
@@ -3123,7 +3123,7 @@ Status IndexedDBBackingStore::Transaction::CommitPhaseOne(
KeyPrefix::IsValidDatabaseId(database_id_));
if (!CollectBlobFilesToRemove()) {
INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD);
- transaction_ = NULL;
+ transaction_ = nullptr;
return InternalInconsistencyStatus();
}
@@ -3193,7 +3193,7 @@ Status IndexedDBBackingStore::Transaction::CommitPhaseTwo() {
// reflect pending blob work - dead files that should be deleted
// immediately, and live files to monitor.
s = transaction_->Commit();
- transaction_ = NULL;
+ transaction_ = nullptr;
if (!s.ok()) {
INTERNAL_WRITE_ERROR(TRANSACTION_COMMIT_METHOD);
@@ -3308,12 +3308,12 @@ void IndexedDBBackingStore::Transaction::Rollback() {
if (chained_blob_writer_.get()) {
chained_blob_writer_->Abort();
- chained_blob_writer_ = NULL;
+ chained_blob_writer_ = nullptr;
}
if (!transaction_)
return;
transaction_->Rollback();
- transaction_ = NULL;
+ transaction_ = nullptr;
}
uint64_t IndexedDBBackingStore::Transaction::GetTransactionSize() {
@@ -3351,7 +3351,7 @@ IndexedDBBackingStore::BlobChangeRecord::Clone() const {
for (const auto& handle : handles_) {
record->handles_.push_back(
- base::MakeUnique<storage::BlobDataHandle>(*handle));
+ std::make_unique<storage::BlobDataHandle>(*handle));
}
return record;
}
@@ -3405,7 +3405,7 @@ void IndexedDBBackingStore::Transaction::PutBlobInfo(
BlobChangeRecord* record = nullptr;
if (it == blob_change_map_.end()) {
std::unique_ptr<BlobChangeRecord> new_record =
- base::MakeUnique<BlobChangeRecord>(object_store_data_key,
+ std::make_unique<BlobChangeRecord>(object_store_data_key,
object_store_id);
record = new_record.get();
blob_change_map_[object_store_data_key] = std::move(new_record);
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 46c36bc5527..652fc666697 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/time/default_clock.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/indexed_db/indexed_db_factory_impl.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
@@ -89,7 +90,7 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
DCHECK(!path_base.empty());
std::unique_ptr<LevelDBComparator> comparator =
- base::MakeUnique<Comparator>();
+ std::make_unique<Comparator>();
if (!base::CreateDirectory(path_base)) {
*status = leveldb::Status::IOError("Unable to create base dir");
@@ -193,7 +194,7 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
class TestIDBFactory : public IndexedDBFactoryImpl {
public:
explicit TestIDBFactory(IndexedDBContextImpl* idb_context)
- : IndexedDBFactoryImpl(idb_context) {}
+ : IndexedDBFactoryImpl(idb_context, base::DefaultClock::GetInstance()) {}
scoped_refptr<TestableIndexedDBBackingStore> OpenBackingStoreForTest(
const Origin& origin,
@@ -251,7 +252,8 @@ class IndexedDBBackingStoreTest : public testing::Test {
idb_context_->TaskRunner()->PostTask(
FROM_HERE, base::BindOnce(
[](IndexedDBBackingStoreTest* test) {
- const Origin origin(GURL("http://localhost:81"));
+ const Origin origin =
+ Origin::Create(GURL("http://localhost:81"));
test->idb_factory_ =
base::MakeRefCounted<TestIDBFactory>(
test->idb_context_.get());
@@ -507,7 +509,7 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) {
[](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
// Initiate transaction1 - writing blobs.
state->transaction1 =
- base::MakeUnique<IndexedDBBackingStore::Transaction>(
+ std::make_unique<IndexedDBBackingStore::Transaction>(
test->backing_store());
state->transaction1->Begin();
std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
@@ -558,7 +560,7 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) {
// Initiate transaction3, deleting blobs.
state->transaction3 =
- base::MakeUnique<IndexedDBBackingStore::Transaction>(
+ std::make_unique<IndexedDBBackingStore::Transaction>(
test->backing_store());
state->transaction3->Begin();
EXPECT_TRUE(test->backing_store()
@@ -636,7 +638,7 @@ TEST_F(IndexedDBBackingStoreTest, DeleteRange) {
// Initiate transaction1 - write records.
state->transaction1 =
- base::MakeUnique<IndexedDBBackingStore::Transaction>(
+ std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store);
state->transaction1->Begin();
std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
@@ -672,7 +674,7 @@ TEST_F(IndexedDBBackingStoreTest, DeleteRange) {
// Initiate transaction 2 - delete range.
state->transaction2 =
- base::MakeUnique<IndexedDBBackingStore::Transaction>(
+ std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store);
state->transaction2->Begin();
IndexedDBValue result_value;
@@ -761,7 +763,7 @@ TEST_F(IndexedDBBackingStoreTest, DeleteRangeEmptyRange) {
// Initiate transaction1 - write records.
state->transaction1 =
- base::MakeUnique<IndexedDBBackingStore::Transaction>(
+ std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store);
state->transaction1->Begin();
@@ -797,7 +799,7 @@ TEST_F(IndexedDBBackingStoreTest, DeleteRangeEmptyRange) {
// Initiate transaction 2 - delete range.
state->transaction2 =
- base::MakeUnique<IndexedDBBackingStore::Transaction>(
+ std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store);
state->transaction2->Begin();
IndexedDBValue result_value;
@@ -846,7 +848,7 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, BlobJournalInterleavedTransactions) {
[](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
// Initiate transaction1.
state->transaction1 =
- base::MakeUnique<IndexedDBBackingStore::Transaction>(
+ std::make_unique<IndexedDBBackingStore::Transaction>(
test->backing_store());
state->transaction1->Begin();
std::vector<std::unique_ptr<storage::BlobDataHandle>> handles1;
@@ -875,7 +877,7 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, BlobJournalInterleavedTransactions) {
// Initiate transaction2.
state->transaction2 =
- base::MakeUnique<IndexedDBBackingStore::Transaction>(
+ std::make_unique<IndexedDBBackingStore::Transaction>(
test->backing_store());
state->transaction2->Begin();
std::vector<std::unique_ptr<storage::BlobDataHandle>> handles2;
@@ -927,7 +929,7 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) {
base::BindOnce(
[](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) {
state->transaction1 =
- base::MakeUnique<IndexedDBBackingStore::Transaction>(
+ std::make_unique<IndexedDBBackingStore::Transaction>(
test->backing_store());
state->transaction1->Begin();
std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
@@ -977,7 +979,7 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) {
}
state->transaction3 =
- base::MakeUnique<IndexedDBBackingStore::Transaction>(
+ std::make_unique<IndexedDBBackingStore::Transaction>(
test->backing_store());
state->transaction3->Begin();
EXPECT_TRUE(test->backing_store()
@@ -1334,7 +1336,7 @@ TEST_F(IndexedDBBackingStoreTest, ReadCorruptionInfo) {
message.clear();
const base::FilePath path_base = temp_dir_.GetPath();
- const Origin origin(GURL("http://www.google.com/"));
+ const Origin origin = Origin::Create(GURL("http://www.google.com/"));
ASSERT_FALSE(path_base.empty());
ASSERT_TRUE(PathIsWritable(path_base));
diff --git a/chromium/content/browser/indexed_db/indexed_db_browsertest.cc b/chromium/content/browser/indexed_db/indexed_db_browsertest.cc
index 2ddcc64b1e2..f104a33e07f 100644
--- a/chromium/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -71,7 +71,7 @@ class IndexedDBBrowserTest : public ContentBrowserTest,
}
void TearDown() override {
- IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(NULL);
+ IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(nullptr);
ContentBrowserTest::TearDown();
}
@@ -164,7 +164,7 @@ class IndexedDBBrowserTest : public ContentBrowserTest,
PostTaskAndReplyWithResult(
GetContext()->TaskRunner(), FROM_HERE,
base::BindOnce(&IndexedDBContextImpl::GetOriginBlobFileCount,
- GetContext(), Origin(GURL("file:///"))),
+ GetContext(), Origin::Create(GURL("file:///"))),
base::BindOnce(&IndexedDBBrowserTest::DidGetBlobFileCount,
base::Unretained(this)));
scoped_refptr<base::ThreadTestHelper> helper(
@@ -711,7 +711,7 @@ static std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, OperationOnCorruptedOpenDatabase) {
ASSERT_TRUE(embedded_test_server()->Started() ||
embedded_test_server()->InitializeAndListen());
- const Origin origin(embedded_test_server()->base_url());
+ const Origin origin = Origin::Create(embedded_test_server()->base_url());
embedded_test_server()->RegisterRequestHandler(
base::Bind(&CorruptDBRequestHandler, base::Unretained(GetContext()),
origin, s_corrupt_db_test_prefix, this));
@@ -837,7 +837,7 @@ IN_PROC_BROWSER_TEST_F(
// Verify that a "close" event is fired at database connections when
// the backing store is deleted.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ForceCloseEventTest) {
- NavigateAndWaitForTitle(shell(), "force_close_event.html", NULL,
+ NavigateAndWaitForTitle(shell(), "force_close_event.html", nullptr,
"connection ready");
// TODO(jsbell): Remove static_cast<> when overloads are eliminated.
GetContext()->TaskRunner()->PostTask(
diff --git a/chromium/content/browser/indexed_db/indexed_db_callbacks.cc b/chromium/content/browser/indexed_db/indexed_db_callbacks.cc
index 08cb300c79e..9b73711c1ac 100644
--- a/chromium/content/browser/indexed_db/indexed_db_callbacks.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_callbacks.cc
@@ -557,7 +557,7 @@ void IndexedDBCallbacks::IOThreadHelper::SendUpgradeNeeded(
return;
}
- auto database = base::MakeUnique<DatabaseImpl>(
+ auto database = std::make_unique<DatabaseImpl>(
std::move(connection_wrapper.connection), origin_, dispatcher_host_.get(),
idb_runner_);
@@ -581,7 +581,7 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessDatabase(
}
::indexed_db::mojom::DatabaseAssociatedPtrInfo ptr_info;
if (connection_wrapper.connection) {
- auto database = base::MakeUnique<DatabaseImpl>(
+ auto database = std::make_unique<DatabaseImpl>(
std::move(connection_wrapper.connection), origin_,
dispatcher_host_.get(), idb_runner_);
@@ -605,7 +605,7 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursor(
OnConnectionError();
return;
}
- auto cursor_impl = base::MakeUnique<CursorImpl>(
+ auto cursor_impl = std::make_unique<CursorImpl>(
std::move(cursor.cursor), origin_, dispatcher_host_.get(), idb_runner_);
if (value && !CreateAllBlobs(blob_info, &value->blob_or_file_info))
@@ -768,10 +768,10 @@ bool IndexedDBCallbacks::IOThreadHelper::CreateAllBlobs(
for (size_t i = 0; i < blob_info.size(); ++i) {
std::string uuid = CreateBlobData(blob_info[i]);
if (features::IsMojoBlobsEnabled()) {
- storage::mojom::BlobPtr blob_ptr;
+ blink::mojom::BlobPtrInfo blob_ptr_info;
storage::BlobImpl::Create(blob_context->GetBlobDataFromUUID(uuid),
- MakeRequest(&blob_ptr));
- (*blob_or_file_info)[i]->blob = std::move(blob_ptr);
+ MakeRequest(&blob_ptr_info));
+ (*blob_or_file_info)[i]->blob = std::move(blob_ptr_info);
}
(*blob_or_file_info)[i]->uuid = std::move(uuid);
}
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 45890604d3c..9ee60096832 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
@@ -47,12 +47,12 @@ class BustedLevelDBDatabase : public LevelDBDatabase {
static std::unique_ptr<LevelDBDatabase> Open(
const base::FilePath& file_name,
const LevelDBComparator* /*comparator*/) {
- return base::MakeUnique<BustedLevelDBDatabase>();
+ return std::make_unique<BustedLevelDBDatabase>();
}
leveldb::Status Get(const base::StringPiece& key,
std::string* value,
bool* found,
- const LevelDBSnapshot* = 0) override {
+ const LevelDBSnapshot* = nullptr) override {
return leveldb::Status::IOError("It's busted!");
}
@@ -65,7 +65,7 @@ class BustedLevelDBFactory : public LevelDBFactory {
leveldb::Status OpenLevelDB(const base::FilePath& file_name,
const LevelDBComparator* comparator,
std::unique_ptr<LevelDBDatabase>* db,
- bool* is_disk_full = 0) override {
+ bool* is_disk_full = nullptr) override {
if (open_error_.ok())
*db = BustedLevelDBDatabase::Open(file_name, comparator);
return open_error_;
@@ -82,8 +82,8 @@ class BustedLevelDBFactory : public LevelDBFactory {
};
TEST(IndexedDBIOErrorTest, CleanUpTest) {
- content::IndexedDBFactory* factory = NULL;
- const url::Origin origin(GURL("http://localhost:81"));
+ content::IndexedDBFactory* factory = nullptr;
+ const url::Origin origin = url::Origin::Create(GURL("http://localhost:81"));
base::ScopedTempDir temp_directory;
ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
const base::FilePath path = temp_directory.GetPath();
@@ -100,7 +100,7 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) {
EXPECT_CALL(mock_leveldb_factory, DestroyLevelDB(_)).Times(Exactly(1));
content::IndexedDBDataLossInfo data_loss_info;
bool disk_full = false;
- base::SequencedTaskRunner* task_runner = NULL;
+ base::SequencedTaskRunner* task_runner = nullptr;
bool clean_journal = false;
leveldb::Status s;
scoped_refptr<IndexedDBBackingStore> backing_store =
@@ -110,15 +110,15 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) {
}
TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
- content::IndexedDBFactory* factory = NULL;
- const url::Origin origin(GURL("http://localhost:81"));
+ 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();
content::IndexedDBDataLossInfo data_loss_info;
bool disk_full = false;
- base::SequencedTaskRunner* task_runner = NULL;
+ base::SequencedTaskRunner* task_runner = nullptr;
bool clean_journal = false;
leveldb::Status s;
diff --git a/chromium/content/browser/indexed_db/indexed_db_connection.cc b/chromium/content/browser/indexed_db/indexed_db_connection.cc
index c7744d42dfa..c820dce99b0 100644
--- a/chromium/content/browser/indexed_db/indexed_db_connection.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_connection.cc
@@ -68,7 +68,7 @@ void IndexedDBConnection::VersionChangeIgnored() {
}
bool IndexedDBConnection::IsConnected() {
- return database_.get() != NULL;
+ return database_.get() != nullptr;
}
// The observers begin listening to changes only once they are activated.
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 a42d79246fd..e6862842cc4 100644
--- a/chromium/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -19,6 +19,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_restrictions.h"
+#include "base/time/default_clock.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
@@ -74,15 +75,18 @@ void GetAllOriginsAndPaths(const base::FilePath& indexeddb_path,
file_path.RemoveExtension().Extension() == kIndexedDBExtension) {
std::string origin_id = file_path.BaseName().RemoveExtension()
.RemoveExtension().MaybeAsASCII();
- origins->push_back(Origin(storage::GetOriginFromIdentifier(origin_id)));
+ origins->push_back(
+ Origin::Create(storage::GetOriginFromIdentifier(origin_id)));
if (file_paths)
file_paths->push_back(file_path);
}
}
}
+} // namespace
+
// This will be called after the IndexedDBContext is destroyed.
-void ClearSessionOnlyOrigins(
+void IndexedDBContextImpl::ClearSessionOnlyOrigins(
const base::FilePath& indexeddb_path,
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy) {
// TODO(jsbell): DCHECK that this is running on an IndexedDB sequence,
@@ -103,8 +107,6 @@ void ClearSessionOnlyOrigins(
}
}
-} // namespace
-
IndexedDBContextImpl::IndexedDBContextImpl(
const base::FilePath& data_path,
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy,
@@ -128,7 +130,8 @@ IndexedDBFactory* IndexedDBContextImpl::GetIDBFactory() {
// Prime our cache of origins with existing databases so we can
// detect when dbs are newly created.
GetOriginSet();
- factory_ = new IndexedDBFactoryImpl(this);
+ factory_ =
+ new IndexedDBFactoryImpl(this, base::DefaultClock::GetInstance());
}
return factory_.get();
}
@@ -168,16 +171,16 @@ base::ListValue* IndexedDBContextImpl::GetAllOriginsDetails() {
std::sort(origins.begin(), origins.end(), HostNameComparator);
- std::unique_ptr<base::ListValue> list(base::MakeUnique<base::ListValue>());
+ std::unique_ptr<base::ListValue> list(std::make_unique<base::ListValue>());
for (const auto& origin : origins) {
std::unique_ptr<base::DictionaryValue> info(
- base::MakeUnique<base::DictionaryValue>());
+ std::make_unique<base::DictionaryValue>());
info->SetString("url", origin.Serialize());
info->SetString("size", ui::FormatBytes(GetOriginDiskUsage(origin)));
info->SetDouble("last_modified", GetOriginLastModified(origin).ToJsTime());
if (!is_incognito()) {
std::unique_ptr<base::ListValue> paths(
- base::MakeUnique<base::ListValue>());
+ std::make_unique<base::ListValue>());
for (const base::FilePath& path : GetStoragePaths(origin))
paths->AppendString(path.value());
info->Set("paths", std::move(paths));
@@ -194,14 +197,14 @@ base::ListValue* IndexedDBContextImpl::GetAllOriginsDetails() {
range = factory_->GetOpenDatabasesForOrigin(origin);
// TODO(jsbell): Sort by name?
std::unique_ptr<base::ListValue> database_list(
- base::MakeUnique<base::ListValue>());
+ std::make_unique<base::ListValue>());
for (IndexedDBFactory::OriginDBMapIterator it = range.first;
it != range.second;
++it) {
const IndexedDBDatabase* db = it->second;
std::unique_ptr<base::DictionaryValue> db_info(
- base::MakeUnique<base::DictionaryValue>());
+ std::make_unique<base::DictionaryValue>());
db_info->SetString("name", db->name());
db_info->SetDouble("connection_count", db->ConnectionCount());
@@ -209,12 +212,12 @@ base::ListValue* IndexedDBContextImpl::GetAllOriginsDetails() {
db_info->SetDouble("pending_open_delete", db->PendingOpenDeleteCount());
std::unique_ptr<base::ListValue> transaction_list(
- base::MakeUnique<base::ListValue>());
+ std::make_unique<base::ListValue>());
std::vector<const IndexedDBTransaction*> transactions =
db->transaction_coordinator().GetTransactions();
for (const auto* transaction : transactions) {
std::unique_ptr<base::DictionaryValue> transaction_info(
- base::MakeUnique<base::DictionaryValue>());
+ std::make_unique<base::DictionaryValue>());
const char* const kModes[] =
{ "readonly", "readwrite", "versionchange" };
@@ -254,7 +257,7 @@ base::ListValue* IndexedDBContextImpl::GetAllOriginsDetails() {
"tasks_completed", transaction->diagnostics().tasks_completed);
std::unique_ptr<base::ListValue> scope(
- base::MakeUnique<base::ListValue>());
+ std::make_unique<base::ListValue>());
for (const auto& id : transaction->scope()) {
const auto& it = db->metadata().object_stores.find(id);
if (it != db->metadata().object_stores.end())
@@ -290,7 +293,7 @@ int IndexedDBContextImpl::GetOriginBlobFileCount(const Origin& origin) {
// TODO(jsbell): Update callers to use url::Origin overload and remove.
int64_t IndexedDBContextImpl::GetOriginDiskUsage(const GURL& origin_url) {
- return GetOriginDiskUsage(Origin(origin_url));
+ return GetOriginDiskUsage(Origin::Create(origin_url));
}
int64_t IndexedDBContextImpl::GetOriginDiskUsage(const Origin& origin) {
@@ -314,7 +317,7 @@ base::Time IndexedDBContextImpl::GetOriginLastModified(const Origin& origin) {
// TODO(jsbell): Update callers to use url::Origin overload and remove.
void IndexedDBContextImpl::DeleteForOrigin(const GURL& origin_url) {
- DeleteForOrigin(Origin(origin_url));
+ DeleteForOrigin(Origin::Create(origin_url));
}
void IndexedDBContextImpl::DeleteForOrigin(const Origin& origin) {
@@ -347,7 +350,7 @@ void IndexedDBContextImpl::DeleteForOrigin(const Origin& origin) {
// TODO(jsbell): Update callers to use url::Origin overload and remove.
void IndexedDBContextImpl::CopyOriginData(const GURL& origin_url,
IndexedDBContext* dest_context) {
- CopyOriginData(Origin(origin_url), dest_context);
+ CopyOriginData(Origin::Create(origin_url), dest_context);
}
void IndexedDBContextImpl::CopyOriginData(const Origin& origin,
@@ -418,7 +421,7 @@ std::vector<base::FilePath> IndexedDBContextImpl::GetStoragePaths(
// TODO(jsbell): Update callers to use url::Origin overload and remove.
base::FilePath IndexedDBContextImpl::GetFilePathForTesting(
const GURL& origin_url) const {
- return GetFilePathForTesting(Origin(origin_url));
+ return GetFilePathForTesting(Origin::Create(origin_url));
}
base::FilePath IndexedDBContextImpl::GetFilePathForTesting(
@@ -588,9 +591,9 @@ void IndexedDBContextImpl::QueryDiskAndUpdateQuotaUsage(const Origin& origin) {
std::set<Origin>* IndexedDBContextImpl::GetOriginSet() {
if (!origin_set_) {
std::vector<Origin> origins;
- GetAllOriginsAndPaths(data_path_, &origins, NULL);
+ GetAllOriginsAndPaths(data_path_, &origins, nullptr);
origin_set_ =
- base::MakeUnique<std::set<Origin>>(origins.begin(), origins.end());
+ std::make_unique<std::set<Origin>>(origins.begin(), origins.end());
}
return origin_set_.get();
}
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 865f880fe6c..11b6592ba17 100644
--- a/chromium/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/chromium/content/browser/indexed_db/indexed_db_context_impl.h
@@ -47,6 +47,8 @@ class CONTENT_EXPORT IndexedDBContextImpl : public IndexedDBContext {
FORCE_CLOSE_BACKING_STORE_FAILURE,
FORCE_CLOSE_INTERNALS_PAGE,
FORCE_CLOSE_COPY_ORIGIN,
+ // Append new values here and update IDBContextForcedCloseReason in
+ // enums.xml.
FORCE_CLOSE_REASON_MAX
};
@@ -160,6 +162,10 @@ class CONTENT_EXPORT IndexedDBContextImpl : public IndexedDBContext {
class IndexedDBGetUsageAndQuotaCallback;
+ static void ClearSessionOnlyOrigins(
+ const base::FilePath& indexeddb_path,
+ scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy);
+
base::FilePath GetBlobStorePath(const url::Origin& origin) const;
base::FilePath GetLevelDBPath(const url::Origin& origin) const;
diff --git a/chromium/content/browser/indexed_db/indexed_db_database.cc b/chromium/content/browser/indexed_db/indexed_db_database.cc
index 62e01ca606e..e0cff5261bb 100644
--- a/chromium/content/browser/indexed_db/indexed_db_database.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_database.cc
@@ -398,7 +398,7 @@ IndexedDBDatabase::IndexedDBDatabase(
identifier_(unique_identifier),
factory_(factory),
metadata_coding_(std::move(metadata_coding)) {
- DCHECK(factory != NULL);
+ DCHECK(factory != nullptr);
}
void IndexedDBDatabase::AddObjectStore(
@@ -480,7 +480,7 @@ std::unique_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection(
scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
int child_process_id) {
std::unique_ptr<IndexedDBConnection> connection(
- base::MakeUnique<IndexedDBConnection>(child_process_id, this,
+ std::make_unique<IndexedDBConnection>(child_process_id, this,
database_callbacks));
connections_.insert(connection.get());
backing_store_->GrantChildProcessPermissions(child_process_id);
@@ -1187,12 +1187,12 @@ static std::unique_ptr<IndexedDBKey> GenerateKey(
&current_number);
if (!s.ok()) {
LOG(ERROR) << "Failed to GetKeyGeneratorCurrentNumber";
- return base::MakeUnique<IndexedDBKey>();
+ return std::make_unique<IndexedDBKey>();
}
if (current_number < 0 || current_number > max_generator_value)
- return base::MakeUnique<IndexedDBKey>();
+ return std::make_unique<IndexedDBKey>();
- return base::MakeUnique<IndexedDBKey>(current_number, kWebIDBKeyTypeNumber);
+ return std::make_unique<IndexedDBKey>(current_number, kWebIDBKeyTypeNumber);
}
// Called at the end of a "put" operation. The key is a number that was either
@@ -1248,7 +1248,7 @@ void IndexedDBDatabase::Put(
DCHECK(key);
DCHECK(value);
std::unique_ptr<PutOperationParams> params(
- base::MakeUnique<PutOperationParams>());
+ std::make_unique<PutOperationParams>());
params->object_store_id = object_store_id;
params->value.swap(*value);
params->handles.swap(*handles);
@@ -1492,7 +1492,7 @@ void IndexedDBDatabase::OpenCursor(
return;
std::unique_ptr<OpenCursorOperationParams> params(
- base::MakeUnique<OpenCursorOperationParams>());
+ std::make_unique<OpenCursorOperationParams>());
params->object_store_id = object_store_id;
params->index_id = index_id;
params->key_range = std::move(key_range);
@@ -1573,7 +1573,7 @@ Status IndexedDBDatabase::OpenCursorOperation(
return s;
}
- std::unique_ptr<IndexedDBCursor> cursor = base::MakeUnique<IndexedDBCursor>(
+ std::unique_ptr<IndexedDBCursor> cursor = std::make_unique<IndexedDBCursor>(
std::move(backing_store_cursor), params->cursor_type, params->task_type,
transaction);
IndexedDBCursor* cursor_ptr = cursor.get();
@@ -1841,13 +1841,13 @@ void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) {
void IndexedDBDatabase::OpenConnection(
std::unique_ptr<IndexedDBPendingConnection> connection) {
- AppendRequest(base::MakeUnique<OpenRequest>(this, std::move(connection)));
+ AppendRequest(std::make_unique<OpenRequest>(this, std::move(connection)));
}
void IndexedDBDatabase::DeleteDatabase(
scoped_refptr<IndexedDBCallbacks> callbacks,
bool force_close) {
- AppendRequest(base::MakeUnique<DeleteRequest>(this, callbacks));
+ AppendRequest(std::make_unique<DeleteRequest>(this, callbacks));
// Close the connections only after the request is queued to make sure
// the store is still open.
if (force_close)
diff --git a/chromium/content/browser/indexed_db/indexed_db_database_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_database_unittest.cc
index 6e878a43f7a..e2825b4967c 100644
--- a/chromium/content/browser/indexed_db/indexed_db_database_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_database_unittest.cc
@@ -46,7 +46,7 @@ class IndexedDBDatabaseTest : public ::testing::Test {
backing_store_ = new IndexedDBFakeBackingStore();
factory_ = new MockIndexedDBFactory();
std::unique_ptr<FakeIndexedDBMetadataCoding> metadata_coding =
- base::MakeUnique<FakeIndexedDBMetadataCoding>();
+ std::make_unique<FakeIndexedDBMetadataCoding>();
metadata_coding_ = metadata_coding.get();
EXPECT_TRUE(backing_store_->HasOneRef());
leveldb::Status s;
@@ -70,7 +70,7 @@ class IndexedDBDatabaseTest : public ::testing::Test {
TEST_F(IndexedDBDatabaseTest, BackingStoreRetention) {
EXPECT_FALSE(backing_store_->HasOneRef()); // local and db
- db_ = NULL;
+ db_ = nullptr;
EXPECT_TRUE(backing_store_->HasOneRef()); // local
}
@@ -80,7 +80,7 @@ TEST_F(IndexedDBDatabaseTest, ConnectionLifecycle) {
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
std::unique_ptr<IndexedDBPendingConnection> connection1(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
db_->OpenConnection(std::move(connection1));
@@ -92,7 +92,7 @@ TEST_F(IndexedDBDatabaseTest, ConnectionLifecycle) {
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id2 = 2;
std::unique_ptr<IndexedDBPendingConnection> connection2(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
request2, callbacks2, kFakeChildProcessId, transaction_id2,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
db_->OpenConnection(std::move(connection2));
@@ -110,7 +110,7 @@ TEST_F(IndexedDBDatabaseTest, ConnectionLifecycle) {
EXPECT_TRUE(backing_store_->HasOneRef());
EXPECT_FALSE(db_->backing_store());
- db_ = NULL;
+ db_ = nullptr;
}
TEST_F(IndexedDBDatabaseTest, ForcedClose) {
@@ -119,7 +119,7 @@ TEST_F(IndexedDBDatabaseTest, ForcedClose) {
scoped_refptr<MockIndexedDBCallbacks> request(new MockIndexedDBCallbacks());
const int64_t upgrade_transaction_id = 3;
std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
request, callbacks, kFakeChildProcessId, upgrade_transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
db_->OpenConnection(std::move(connection));
@@ -170,7 +170,7 @@ TEST_F(IndexedDBDatabaseTest, PendingDelete) {
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
db_->OpenConnection(std::move(connection));
@@ -214,7 +214,7 @@ TEST_F(IndexedDBDatabaseTest, OpenDeleteClear) {
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
std::unique_ptr<IndexedDBPendingConnection> connection1(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
kDatabaseVersion));
db_->OpenConnection(std::move(connection1));
@@ -230,7 +230,7 @@ TEST_F(IndexedDBDatabaseTest, OpenDeleteClear) {
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id2 = 2;
std::unique_ptr<IndexedDBPendingConnection> connection2(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
request2, callbacks2, kFakeChildProcessId, transaction_id2,
kDatabaseVersion));
db_->OpenConnection(std::move(connection2));
@@ -246,7 +246,7 @@ TEST_F(IndexedDBDatabaseTest, OpenDeleteClear) {
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id3 = 3;
std::unique_ptr<IndexedDBPendingConnection> connection3(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
request3, callbacks3, kFakeChildProcessId, transaction_id3,
kDatabaseVersion));
db_->OpenConnection(std::move(connection3));
@@ -280,7 +280,7 @@ TEST_F(IndexedDBDatabaseTest, ForceDelete) {
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
db_->OpenConnection(std::move(connection));
@@ -315,7 +315,7 @@ class IndexedDBDatabaseOperationTest : public testing::Test {
void SetUp() override {
backing_store_ = new IndexedDBFakeBackingStore();
std::unique_ptr<FakeIndexedDBMetadataCoding> metadata_coding =
- base::MakeUnique<FakeIndexedDBMetadataCoding>();
+ std::make_unique<FakeIndexedDBMetadataCoding>();
metadata_coding_ = metadata_coding.get();
leveldb::Status s;
std::tie(db_, s) = IndexedDBDatabase::Create(
@@ -327,13 +327,13 @@ class IndexedDBDatabaseOperationTest : public testing::Test {
callbacks_ = new MockIndexedDBDatabaseCallbacks();
const int64_t transaction_id = 1;
std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
request_, callbacks_, kFakeChildProcessId, transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
db_->OpenConnection(std::move(connection));
EXPECT_EQ(IndexedDBDatabaseMetadata::NO_VERSION, db_->metadata().version);
- connection_ = base::MakeUnique<IndexedDBConnection>(kFakeChildProcessId,
+ connection_ = std::make_unique<IndexedDBConnection>(kFakeChildProcessId,
db_, callbacks_);
transaction_ = connection_->CreateTransaction(
transaction_id, std::set<int64_t>() /*scope*/,
@@ -453,7 +453,7 @@ TEST_F(IndexedDBDatabaseOperationTest, CreatePutDelete) {
// Put is asynchronous
IndexedDBValue value("value1", std::vector<IndexedDBBlobInfo>());
std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
- std::unique_ptr<IndexedDBKey> key(base::MakeUnique<IndexedDBKey>("key"));
+ std::unique_ptr<IndexedDBKey> key(std::make_unique<IndexedDBKey>("key"));
std::vector<IndexedDBIndexKeys> index_keys;
scoped_refptr<MockIndexedDBCallbacks> request(
new MockIndexedDBCallbacks(false));
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 4e5299f6391..7dc346eae3e 100644
--- a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -359,7 +359,7 @@ void IndexedDBDispatcherHost::IDBSequenceHelper::OpenOnIDBThread(
// created) if this origin is already over quota.
callbacks->SetConnectionOpenStartTime(begin_time);
std::unique_ptr<IndexedDBPendingConnection> connection =
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
callbacks, database_callbacks, ipc_process_id_, transaction_id,
version);
DCHECK(request_context_getter_);
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 1bca7a009b1..0eba783cca8 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
@@ -187,7 +187,7 @@ class IndexedDBDispatcherHostTest : public testing::Test {
void SetUp() override {
FactoryAssociatedRequest request =
- ::mojo::MakeIsolatedRequest(&idb_mojo_factory_);
+ ::mojo::MakeRequestAssociatedWithDedicatedPipe(&idb_mojo_factory_);
host_->AddBinding(std::move(request));
}
@@ -210,7 +210,7 @@ TEST_F(IndexedDBDispatcherHostTest, CloseConnectionBeforeUpgrade) {
const int64_t kDBVersion = 1;
const int64_t kTransactionId = 1;
- TestDatabaseConnection connection(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -240,7 +240,7 @@ TEST_F(IndexedDBDispatcherHostTest, CloseAfterUpgrade) {
const char kObjectStoreName[] = "os";
// Open connection.
- TestDatabaseConnection connection(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
@@ -297,7 +297,7 @@ TEST_F(IndexedDBDispatcherHostTest, OpenNewConnectionWhileUpgrading) {
const char kObjectStoreName[] = "os";
// Open connection 1, and expect the upgrade needed.
- TestDatabaseConnection connection1(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection1(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
DatabaseAssociatedPtrInfo database_info1;
@@ -322,7 +322,7 @@ TEST_F(IndexedDBDispatcherHostTest, OpenNewConnectionWhileUpgrading) {
// Open connection 2, but expect that we won't be called back.
DatabaseAssociatedPtrInfo database_info2;
IndexedDBDatabaseMetadata metadata2;
- TestDatabaseConnection connection2(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection2(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, 0);
connection2.Open(idb_mojo_factory_.get());
@@ -369,7 +369,7 @@ TEST_F(IndexedDBDispatcherHostTest, PutWithInvalidBlob) {
const char kObjectStoreName[] = "os";
// Open connection.
- TestDatabaseConnection connection(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
@@ -403,7 +403,7 @@ TEST_F(IndexedDBDispatcherHostTest, PutWithInvalidBlob) {
base::Closure quit_closure = base::BarrierClosure(3, loop.QuitClosure());
auto put_callbacks =
- base::MakeUnique<StrictMock<MockMojoIndexedDBCallbacks>>();
+ std::make_unique<StrictMock<MockMojoIndexedDBCallbacks>>();
EXPECT_CALL(*put_callbacks,
Error(blink::kWebIDBDatabaseExceptionUnknownError, _))
@@ -445,7 +445,7 @@ TEST_F(IndexedDBDispatcherHostTest, CompactDatabaseWithConnection) {
const int64_t kTransactionId = 1;
// Open connection.
- TestDatabaseConnection connection(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -478,7 +478,7 @@ TEST_F(IndexedDBDispatcherHostTest, CompactDatabaseWithConnection) {
::testing::InSequence dummy;
base::RunLoop loop;
base::Closure quit_closure = base::BarrierClosure(3, loop.QuitClosure());
- const url::Origin origin = url::Origin(GURL(kOrigin));
+ const url::Origin origin = url::Origin::Create(GURL(kOrigin));
EXPECT_CALL(*connection.connection_callbacks, Complete(kTransactionId))
.Times(1)
@@ -506,7 +506,7 @@ TEST_F(IndexedDBDispatcherHostTest, CompactDatabaseWhileDoingTransaction) {
const char kObjectStoreName[] = "os";
// Open connection.
- TestDatabaseConnection connection(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -539,7 +539,7 @@ TEST_F(IndexedDBDispatcherHostTest, CompactDatabaseWhileDoingTransaction) {
::testing::InSequence dummy;
base::RunLoop loop;
base::Closure quit_closure = base::BarrierClosure(4, loop.QuitClosure());
- const url::Origin origin = url::Origin(GURL(kOrigin));
+ const url::Origin origin = url::Origin::Create(GURL(kOrigin));
EXPECT_CALL(
*connection.connection_callbacks,
@@ -572,7 +572,7 @@ TEST_F(IndexedDBDispatcherHostTest, CompactDatabaseWhileUpgrading) {
const int64_t kTransactionId = 1;
// Open connection.
- TestDatabaseConnection connection(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -605,7 +605,7 @@ TEST_F(IndexedDBDispatcherHostTest, CompactDatabaseWhileUpgrading) {
::testing::InSequence dummy;
base::RunLoop loop;
base::Closure quit_closure = base::BarrierClosure(4, loop.QuitClosure());
- const url::Origin origin = url::Origin(GURL(kOrigin));
+ const url::Origin origin = url::Origin::Create(GURL(kOrigin));
EXPECT_CALL(
*connection.connection_callbacks,
@@ -636,7 +636,7 @@ TEST_F(IndexedDBDispatcherHostTest,
const int64_t kTransactionId = 1;
// Open connection.
- TestDatabaseConnection connection(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -669,7 +669,7 @@ TEST_F(IndexedDBDispatcherHostTest,
::testing::InSequence dummy;
base::RunLoop loop;
base::Closure quit_closure = base::BarrierClosure(4, loop.QuitClosure());
- const url::Origin origin = url::Origin(GURL(kOrigin));
+ const url::Origin origin = url::Origin::Create(GURL(kOrigin));
EXPECT_CALL(*connection.connection_callbacks, Complete(kTransactionId))
.Times(1)
@@ -700,7 +700,7 @@ TEST_F(IndexedDBDispatcherHostTest, AbortTransactionsWhileDoingTransaction) {
const char kObjectStoreName[] = "os";
// Open connection.
- TestDatabaseConnection connection(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -733,7 +733,7 @@ TEST_F(IndexedDBDispatcherHostTest, AbortTransactionsWhileDoingTransaction) {
::testing::InSequence dummy;
base::RunLoop loop;
base::Closure quit_closure = base::BarrierClosure(4, loop.QuitClosure());
- const url::Origin origin = url::Origin(GURL(kOrigin));
+ const url::Origin origin = url::Origin::Create(GURL(kOrigin));
EXPECT_CALL(
*connection.connection_callbacks,
@@ -766,7 +766,7 @@ TEST_F(IndexedDBDispatcherHostTest, AbortTransactionsWhileUpgrading) {
const int64_t kTransactionId = 1;
// Open connection.
- TestDatabaseConnection connection(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -799,7 +799,7 @@ TEST_F(IndexedDBDispatcherHostTest, AbortTransactionsWhileUpgrading) {
::testing::InSequence dummy;
base::RunLoop loop;
base::Closure quit_closure = base::BarrierClosure(4, loop.QuitClosure());
- const url::Origin origin = url::Origin(GURL(kOrigin));
+ const url::Origin origin = url::Origin::Create(GURL(kOrigin));
EXPECT_CALL(
*connection.connection_callbacks,
@@ -841,7 +841,7 @@ TEST_F(IndexedDBDispatcherHostTest, DISABLED_NotifyIndexedDBListChanged) {
context_impl_->AddObserver(&observer);
// Open connection 1.
- TestDatabaseConnection connection1(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection1(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion1, kTransactionId1);
IndexedDBDatabaseMetadata metadata1;
@@ -897,7 +897,7 @@ TEST_F(IndexedDBDispatcherHostTest, DISABLED_NotifyIndexedDBListChanged) {
connection1.database->Close();
// Open connection 2.
- TestDatabaseConnection connection2(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection2(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion2, kTransactionId2);
IndexedDBDatabaseMetadata metadata2;
@@ -947,7 +947,7 @@ TEST_F(IndexedDBDispatcherHostTest, DISABLED_NotifyIndexedDBListChanged) {
connection2.database->Close();
// Open connection 3.
- TestDatabaseConnection connection3(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection3(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion3, kTransactionId3);
IndexedDBDatabaseMetadata metadata3;
@@ -1009,7 +1009,7 @@ TEST_F(IndexedDBDispatcherHostTest, NotifyIndexedDBContentChanged) {
context_impl_->AddObserver(&observer);
// Open connection 1.
- TestDatabaseConnection connection1(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection1(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion1, kTransactionId1);
IndexedDBDatabaseMetadata metadata1;
@@ -1043,7 +1043,7 @@ TEST_F(IndexedDBDispatcherHostTest, NotifyIndexedDBContentChanged) {
base::Closure quit_closure = base::BarrierClosure(3, loop.QuitClosure());
auto put_callbacks =
- base::MakeUnique<StrictMock<MockMojoIndexedDBCallbacks>>();
+ std::make_unique<StrictMock<MockMojoIndexedDBCallbacks>>();
EXPECT_CALL(*put_callbacks, SuccessKey(_))
.Times(1)
@@ -1077,7 +1077,7 @@ TEST_F(IndexedDBDispatcherHostTest, NotifyIndexedDBContentChanged) {
connection1.database->Close();
// Open connection 2.
- TestDatabaseConnection connection2(url::Origin(GURL(kOrigin)),
+ TestDatabaseConnection connection2(url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion2, kTransactionId2);
IndexedDBDatabaseMetadata metadata2;
@@ -1109,7 +1109,7 @@ TEST_F(IndexedDBDispatcherHostTest, NotifyIndexedDBContentChanged) {
base::Closure quit_closure = base::BarrierClosure(3, loop.QuitClosure());
auto clear_callbacks =
- base::MakeUnique<StrictMock<MockMojoIndexedDBCallbacks>>();
+ std::make_unique<StrictMock<MockMojoIndexedDBCallbacks>>();
EXPECT_CALL(*clear_callbacks, Success())
.Times(1)
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 22ca3685fb0..fa8fd12ffa9 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -9,17 +9,19 @@
#include <utility>
#include <vector>
+#include "base/callback_helpers.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "base/rand_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/time/default_clock.h"
-#include "base/time/time.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
+#include "content/browser/indexed_db/indexed_db_class_factory.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_leveldb_operations.h"
#include "content/browser/indexed_db/indexed_db_metadata_coding.h"
#include "content/browser/indexed_db/indexed_db_pre_close_task_queue.h"
#include "content/browser/indexed_db/indexed_db_tombstone_sweeper.h"
@@ -47,17 +49,54 @@ const int kTombstoneSweeperRoundIterations = 1000;
// The maximum total iterations for the tombstone sweeper.
const int kTombstoneSweeperMaxIterations = 10 * 1000 * 1000;
+constexpr const base::TimeDelta kMinEarliestOriginSweepFromNow =
+ base::TimeDelta::FromDays(1);
+static_assert(kMinEarliestOriginSweepFromNow <
+ IndexedDBFactoryImpl::kMaxEarliestOriginSweepFromNow,
+ "Min < Max");
+
+constexpr const base::TimeDelta kMinEarliestGlobalSweepFromNow =
+ base::TimeDelta::FromMinutes(10);
+static_assert(kMinEarliestGlobalSweepFromNow <
+ IndexedDBFactoryImpl::kMaxEarliestGlobalSweepFromNow,
+ "Min < Max");
+
+base::Time GenerateNextOriginSweepTime(base::Time now) {
+ uint64_t range =
+ IndexedDBFactoryImpl::kMaxEarliestOriginSweepFromNow.InMilliseconds() -
+ kMinEarliestOriginSweepFromNow.InMilliseconds();
+ int64_t rand_millis = kMinEarliestOriginSweepFromNow.InMilliseconds() +
+ static_cast<int64_t>(base::RandGenerator(range));
+ return now + base::TimeDelta::FromMilliseconds(rand_millis);
+}
+
+base::Time GenerateNextGlobalSweepTime(base::Time now) {
+ uint64_t range =
+ IndexedDBFactoryImpl::kMaxEarliestGlobalSweepFromNow.InMilliseconds() -
+ kMinEarliestGlobalSweepFromNow.InMilliseconds();
+ int64_t rand_millis = kMinEarliestGlobalSweepFromNow.InMilliseconds() +
+ static_cast<int64_t>(base::RandGenerator(range));
+ return now + base::TimeDelta::FromMilliseconds(rand_millis);
+}
+
+} // namespace
+
const base::Feature kIDBTombstoneStatistics{"IDBTombstoneStatistics",
base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kIDBTombstoneDeletion{"IDBTombstoneDeletion",
base::FEATURE_DISABLED_BY_DEFAULT};
-} // namespace
+constexpr const base::TimeDelta
+ IndexedDBFactoryImpl::kMaxEarliestGlobalSweepFromNow;
+constexpr const base::TimeDelta
+ IndexedDBFactoryImpl::kMaxEarliestOriginSweepFromNow;
-IndexedDBFactoryImpl::IndexedDBFactoryImpl(IndexedDBContextImpl* context)
- : context_(context) {
-}
+IndexedDBFactoryImpl::IndexedDBFactoryImpl(IndexedDBContextImpl* context,
+ base::Clock* clock)
+ : context_(context),
+ clock_(clock),
+ earliest_sweep_(GenerateNextGlobalSweepTime(clock_->Now())) {}
IndexedDBFactoryImpl::~IndexedDBFactoryImpl() {
}
@@ -129,36 +168,63 @@ void IndexedDBFactoryImpl::MaybeStartPreCloseTasks(const Origin& origin) {
if (!HasLastBackingStoreReference(origin))
return;
+ base::ScopedClosureRunner maybe_close_backing_store_runner(
+ base::BindOnce(&IndexedDBFactoryImpl::MaybeCloseBackingStore,
+ base::Unretained(this), origin));
+
+ base::Time now = clock_->Now();
+
+ // Check that the last sweep hasn't run too recently.
+ if (earliest_sweep_ > now)
+ return;
+
bool tombstone_stats_enabled =
base::FeatureList::IsEnabled(kIDBTombstoneStatistics);
bool tombstone_deletion_enabled =
base::FeatureList::IsEnabled(kIDBTombstoneDeletion);
- if (tombstone_stats_enabled == tombstone_deletion_enabled) {
- // We can't have both stats and deletion, so NOOP if both are enabled.
- MaybeCloseBackingStore(origin);
+ // After this check, exactly one of the flags must be true.
+ if (tombstone_stats_enabled == tombstone_deletion_enabled)
return;
- }
+
scoped_refptr<IndexedDBBackingStore> store = backing_store_map_[origin];
- // TODO(next patch in this cl): Create logic about which tasks get put here.
- // * Min time since last sweep,
- // * Only one sweep at a time for a context (or globaly?)
+
+ base::Time origin_earliest_sweep;
+ leveldb::Status s =
+ indexed_db::GetEarliestSweepTime(store->db(), &origin_earliest_sweep);
+ // TODO(dmurph): Log this or report to UMA.
+ if (!s.ok())
+ return;
+
+ // This origin hasn't been swept too recently.
+ if (origin_earliest_sweep > now)
+ return;
+
+ // A sweep will happen now, so reset the sweep timers.
+ earliest_sweep_ = GenerateNextGlobalSweepTime(now);
+ scoped_refptr<LevelDBTransaction> txn =
+ IndexedDBClassFactory::Get()->CreateLevelDBTransaction(store->db());
+ indexed_db::SetEarliestSweepTime(txn.get(), GenerateNextOriginSweepTime(now));
+ s = txn->Commit();
+
+ // TODO(dmurph): Log this or report to UMA.
+ if (!s.ok())
+ return;
+
std::list<std::unique_ptr<PreCloseTask>> tasks;
IndexedDBTombstoneSweeper::Mode mode =
tombstone_stats_enabled ? IndexedDBTombstoneSweeper::Mode::STATISTICS
: IndexedDBTombstoneSweeper::Mode::DELETION;
- tasks.push_back(base::MakeUnique<IndexedDBTombstoneSweeper>(
+ tasks.push_back(std::make_unique<IndexedDBTombstoneSweeper>(
mode, kTombstoneSweeperRoundIterations, kTombstoneSweeperMaxIterations,
store->db()->db()));
// TODO(dmurph): Add compaction task that compacts all indexes if we have
// more than X deletions.
- store->SetPreCloseTaskList(base::MakeUnique<IndexedDBPreCloseTaskQueue>(
- std::move(tasks),
- base::BindOnce(&IndexedDBFactoryImpl::MaybeCloseBackingStore, this,
- origin),
+ store->SetPreCloseTaskList(std::make_unique<IndexedDBPreCloseTaskQueue>(
+ std::move(tasks), maybe_close_backing_store_runner.Release(),
base::TimeDelta::FromSeconds(kPreCloseTasksMaxRunPeriodSeconds),
- base::MakeUnique<base::OneShotTimer>()));
+ std::make_unique<base::OneShotTimer>()));
store->StartPreCloseTasks();
}
@@ -250,7 +316,7 @@ void IndexedDBFactoryImpl::ContextDestroyed() {
}
backing_store_map_.clear();
backing_stores_with_active_blobs_.clear();
- context_ = NULL;
+ context_ = nullptr;
}
void IndexedDBFactoryImpl::ReportOutstandingBlobs(const Origin& origin,
@@ -305,13 +371,13 @@ void IndexedDBFactoryImpl::GetDatabaseNames(
"Internal error opening backing store for "
"indexedDB.webkitGetDatabaseNames.");
callbacks->OnError(error);
- backing_store = NULL;
+ backing_store = nullptr;
if (s.IsCorruption())
HandleBackingStoreCorruption(origin, error);
return;
}
callbacks->OnSuccess(names);
- backing_store = NULL;
+ backing_store = nullptr;
ReleaseBackingStore(origin, false /* immediate */);
}
@@ -361,7 +427,7 @@ void IndexedDBFactoryImpl::DeleteDatabase(
"Internal error opening backing store for "
"indexedDB.deleteDatabase.");
callbacks->OnError(error);
- backing_store = NULL;
+ backing_store = nullptr;
if (s.IsCorruption())
HandleBackingStoreCorruption(origin, error);
return;
@@ -369,7 +435,7 @@ void IndexedDBFactoryImpl::DeleteDatabase(
if (!base::ContainsValue(names, name)) {
const int64_t version = 0;
callbacks->OnSuccess(version);
- backing_store = NULL;
+ backing_store = nullptr;
ReleaseBackingStore(origin, false /* immediate */);
return;
}
@@ -377,7 +443,7 @@ void IndexedDBFactoryImpl::DeleteDatabase(
scoped_refptr<IndexedDBDatabase> database;
std::tie(database, s) = IndexedDBDatabase::Create(
name, backing_store.get(), this,
- base::MakeUnique<IndexedDBMetadataCoding>(), unique_identifier);
+ std::make_unique<IndexedDBMetadataCoding>(), unique_identifier);
if (!database.get()) {
IndexedDBDatabaseError error(
blink::kWebIDBDatabaseExceptionUnknownError,
@@ -385,7 +451,7 @@ void IndexedDBFactoryImpl::DeleteDatabase(
"indexedDB.deleteDatabase."));
callbacks->OnError(error);
if (s.IsCorruption()) {
- backing_store = NULL;
+ backing_store = nullptr;
HandleBackingStoreCorruption(origin, error);
}
return;
@@ -395,8 +461,8 @@ void IndexedDBFactoryImpl::DeleteDatabase(
origin_dbs_.insert(std::make_pair(origin, database.get()));
database->DeleteDatabase(callbacks, force_close);
RemoveDatabaseFromMaps(unique_identifier);
- database = NULL;
- backing_store = NULL;
+ database = nullptr;
+ backing_store = nullptr;
ReleaseBackingStore(origin, false /* immediate */);
}
@@ -524,10 +590,13 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore(
const auto& it2 = backing_store_map_.find(origin);
if (it2 != backing_store_map_.end()) {
- it2->second->close_timer()->Stop();
+ // Grab a refptr so the completion of the preclose task list doesn't close
+ // the backing store.
+ scoped_refptr<IndexedDBBackingStore> backing_store = it2->second;
+ backing_store->close_timer()->Stop();
if (it2->second->pre_close_task_queue()) {
- it2->second->pre_close_task_queue()->StopForNewConnection();
- it2->second->SetPreCloseTaskList(nullptr);
+ backing_store->pre_close_task_queue()->StopForNewConnection();
+ backing_store->SetPreCloseTaskList(nullptr);
}
return it2->second;
}
@@ -560,7 +629,7 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore(
return backing_store;
}
- return 0;
+ return nullptr;
}
void IndexedDBFactoryImpl::Open(
@@ -602,7 +671,7 @@ void IndexedDBFactoryImpl::Open(
std::tie(database, s) = IndexedDBDatabase::Create(
name, backing_store.get(), this,
- base::MakeUnique<IndexedDBMetadataCoding>(), unique_identifier);
+ std::make_unique<IndexedDBMetadataCoding>(), unique_identifier);
if (!database.get()) {
DLOG(ERROR) << "Unable to create the database";
IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError,
@@ -611,7 +680,8 @@ void IndexedDBFactoryImpl::Open(
"indexedDB.open."));
connection->callbacks->OnError(error);
if (s.IsCorruption()) {
- backing_store = NULL; // Closes the LevelDB so that it can be deleted
+ backing_store =
+ nullptr; // Closes the LevelDB so that it can be deleted
HandleBackingStoreCorruption(origin, error);
}
return;
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 4131a648895..cb730b49a1c 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_impl.h
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -13,8 +13,14 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
+#include "base/time/clock.h"
+#include "base/time/time.h"
#include "content/browser/indexed_db/indexed_db_factory.h"
+namespace base {
+struct Feature;
+}
+
namespace url {
class Origin;
}
@@ -23,9 +29,23 @@ namespace content {
class IndexedDBContextImpl;
+CONTENT_EXPORT extern const base::Feature kIDBTombstoneStatistics;
+CONTENT_EXPORT extern const base::Feature kIDBTombstoneDeletion;
+
class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
public:
- explicit IndexedDBFactoryImpl(IndexedDBContextImpl* context);
+ // Maximum time interval between runs of the IndexedDBSweeper. Sweeping only
+ // occurs after backing store close.
+ // Visible for testing.
+ static constexpr const base::TimeDelta kMaxEarliestGlobalSweepFromNow =
+ base::TimeDelta::FromHours(2);
+ // Maximum time interval between runs of the IndexedDBSweeper for a given
+ // origin. Sweeping only occurs after backing store close.
+ // Visible for testing.
+ static constexpr const base::TimeDelta kMaxEarliestOriginSweepFromNow =
+ base::TimeDelta::FromDays(7);
+
+ IndexedDBFactoryImpl(IndexedDBContextImpl* context, base::Clock* clock);
// content::IndexedDBFactory overrides:
void ReleaseDatabase(const IndexedDBDatabase::Identifier& identifier,
@@ -116,6 +136,8 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
BackingStoreReleasedOnForcedClose);
FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest,
BackingStoreReleaseDelayedOnClose);
+ FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest, BackingStoreRunPreCloseTasks);
+ FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest, BackingStoreNoSweeping);
FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest, DatabaseFailedOpen);
FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest,
DeleteDatabaseClosesBackingStore);
@@ -155,6 +177,9 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
backing_stores_with_active_blobs_;
std::set<url::Origin> backends_opened_since_boot_;
+ base::Clock* clock_;
+ base::Time earliest_sweep_;
+
DISALLOW_COPY_AND_ASSIGN(IndexedDBFactoryImpl);
};
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 8bb4f12e16c..73d2f19e1da 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -13,8 +13,11 @@
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/simple_test_clock.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/time/default_clock.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_data_format_version.h"
@@ -40,7 +43,9 @@ namespace {
class MockIDBFactory : public IndexedDBFactoryImpl {
public:
explicit MockIDBFactory(IndexedDBContextImpl* context)
- : IndexedDBFactoryImpl(context) {}
+ : MockIDBFactory(context, base::DefaultClock::GetInstance()) {}
+ MockIDBFactory(IndexedDBContextImpl* context, base::Clock* clock)
+ : IndexedDBFactoryImpl(context, clock) {}
scoped_refptr<IndexedDBBackingStore> TestOpenBackingStore(
const Origin& origin,
const base::FilePath& data_directory) {
@@ -109,8 +114,8 @@ TEST_F(IndexedDBFactoryTest, BackingStoreLifetime) {
scoped_refptr<MockIDBFactory> factory =
base::MakeRefCounted<MockIDBFactory>(context);
- const Origin origin1(GURL("http://localhost:81"));
- const Origin origin2(GURL("http://localhost:82"));
+ const Origin origin1 = Origin::Create(GURL("http://localhost:81"));
+ const Origin origin2 = Origin::Create(GURL("http://localhost:82"));
scoped_refptr<IndexedDBBackingStore> disk_store1 =
factory->TestOpenBackingStore(origin1, context->data_path());
@@ -146,7 +151,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreLazyClose) {
scoped_refptr<MockIDBFactory> factory =
base::MakeRefCounted<MockIDBFactory>(context);
- const Origin origin(GURL("http://localhost:81"));
+ const Origin origin = Origin::Create(GURL("http://localhost:81"));
scoped_refptr<IndexedDBBackingStore> store =
factory->TestOpenBackingStore(origin, context->data_path());
@@ -175,6 +180,151 @@ TEST_F(IndexedDBFactoryTest, BackingStoreLazyClose) {
RunAllTasksUntilIdle();
}
+TEST_F(IndexedDBFactoryTest, BackingStoreNoSweeping) {
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context) {
+ base::SimpleTestClock clock;
+ clock.SetNow(base::Time::Now());
+
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context, &clock);
+
+ const Origin origin = Origin::Create(GURL("http://localhost:81"));
+
+ scoped_refptr<IndexedDBBackingStore> store =
+ factory->TestOpenBackingStore(origin, context->data_path());
+
+ // Give up the local refptr so that the factory has the only
+ // outstanding reference.
+ IndexedDBBackingStore* store_ptr = store.get();
+ store = nullptr;
+ EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
+ factory->TestReleaseBackingStore(store_ptr, false);
+ EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
+ EXPECT_EQ(nullptr, store_ptr->pre_close_task_queue());
+
+ // Reset the timer & stop the closing.
+ factory->TestOpenBackingStore(origin, context->data_path());
+ EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
+ factory->TestReleaseBackingStore(store_ptr, false);
+ EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
+ store_ptr->close_timer()->user_task().Run();
+
+ // Backing store should be totally closed.
+ EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
+
+ store = factory->TestOpenBackingStore(origin, context->data_path());
+ store_ptr = store.get();
+ store = nullptr;
+ EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
+
+ // Move the clock to start the next sweep.
+ clock.Advance(IndexedDBFactoryImpl::kMaxEarliestGlobalSweepFromNow);
+ factory->TestReleaseBackingStore(store_ptr, false);
+
+ // Sweep should NOT be occurring.
+ EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
+ store_ptr->close_timer()->user_task().Run();
+
+ // Backing store should be totally closed.
+ EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
+ },
+ base::Unretained(context())));
+ RunAllTasksUntilIdle();
+}
+
+TEST_F(IndexedDBFactoryTest, BackingStoreRunPreCloseTasks) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures({kIDBTombstoneStatistics},
+ {kIDBTombstoneDeletion});
+
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context) {
+ base::SimpleTestClock clock;
+ clock.SetNow(base::Time::Now());
+
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context, &clock);
+
+ const Origin origin = Origin::Create(GURL("http://localhost:81"));
+
+ scoped_refptr<IndexedDBBackingStore> store =
+ factory->TestOpenBackingStore(origin, context->data_path());
+
+ // Give up the local refptr so that the factory has the only
+ // outstanding reference.
+ IndexedDBBackingStore* store_ptr = store.get();
+ store = nullptr;
+ EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
+ factory->TestReleaseBackingStore(store_ptr, false);
+ EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
+ EXPECT_EQ(nullptr, store_ptr->pre_close_task_queue());
+
+ // Reset the timer & stop the closing.
+ factory->TestOpenBackingStore(origin, context->data_path());
+ EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
+ factory->TestReleaseBackingStore(store_ptr, false);
+ EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
+ store_ptr->close_timer()->user_task().Run();
+
+ // Backing store should be totally closed.
+ EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
+
+ store = factory->TestOpenBackingStore(origin, context->data_path());
+ store_ptr = store.get();
+ store = nullptr;
+ EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
+
+ // Move the clock to start the next sweep.
+ clock.Advance(IndexedDBFactoryImpl::kMaxEarliestGlobalSweepFromNow);
+ factory->TestReleaseBackingStore(store_ptr, false);
+
+ // Sweep should be occuring.
+ EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
+ store_ptr->close_timer()->user_task().Run();
+ store_ptr->close_timer()->AbandonAndStop();
+ ASSERT_NE(nullptr, store_ptr->pre_close_task_queue());
+ EXPECT_TRUE(store_ptr->pre_close_task_queue()->started());
+
+ // Stop sweep by opening a connection.
+ factory->TestOpenBackingStore(origin, context->data_path());
+ EXPECT_EQ(nullptr, store_ptr->pre_close_task_queue());
+
+ // Move clock forward to trigger next sweep, but origin has longer
+ // sweep minimum, so nothing happens.
+ clock.Advance(IndexedDBFactoryImpl::kMaxEarliestGlobalSweepFromNow);
+
+ factory->TestReleaseBackingStore(store_ptr, false);
+ EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
+ EXPECT_EQ(nullptr, store_ptr->pre_close_task_queue());
+
+ // Reset, and move clock forward so the origin should allow a sweep.
+ factory->TestOpenBackingStore(origin, context->data_path());
+ EXPECT_EQ(nullptr, store_ptr->pre_close_task_queue());
+ clock.Advance(IndexedDBFactoryImpl::kMaxEarliestOriginSweepFromNow);
+ factory->TestReleaseBackingStore(store_ptr, false);
+
+ // Sweep should be occuring.
+ EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
+ store_ptr->close_timer()->user_task().Run();
+ store_ptr->close_timer()->AbandonAndStop();
+ ASSERT_NE(nullptr, store_ptr->pre_close_task_queue());
+ EXPECT_TRUE(store_ptr->pre_close_task_queue()->started());
+
+ // Take back a ref ptr and ensure that the actual close
+ // stops a running timer.
+ store = store_ptr;
+ factory->TestCloseBackingStore(store_ptr);
+ },
+ base::Unretained(context())));
+
+ RunAllTasksUntilIdle();
+}
+
TEST_F(IndexedDBFactoryTest, MemoryBackingStoreLifetime) {
context()->TaskRunner()->PostTask(
FROM_HERE,
@@ -184,8 +334,8 @@ TEST_F(IndexedDBFactoryTest, MemoryBackingStoreLifetime) {
scoped_refptr<MockIDBFactory> factory =
base::MakeRefCounted<MockIDBFactory>(context);
- const Origin origin1(GURL("http://localhost:81"));
- const Origin origin2(GURL("http://localhost:82"));
+ const Origin origin1 = Origin::Create(GURL("http://localhost:81"));
+ const Origin origin2 = Origin::Create(GURL("http://localhost:82"));
scoped_refptr<IndexedDBBackingStore> mem_store1 =
factory->TestOpenBackingStore(origin1, base::FilePath());
@@ -230,13 +380,15 @@ TEST_F(IndexedDBFactoryTest, RejectLongOrigins) {
base::MakeRefCounted<MockIDBFactory>(context);
std::string origin(limit + 1, 'x');
- Origin too_long_origin(GURL("http://" + origin + ":81/"));
+ Origin too_long_origin =
+ Origin::Create(GURL("http://" + origin + ":81/"));
scoped_refptr<IndexedDBBackingStore> diskStore1 =
factory->TestOpenBackingStore(too_long_origin,
context->data_path());
EXPECT_FALSE(diskStore1.get());
- Origin ok_origin(GURL("http://someorigin.com:82/"));
+ Origin ok_origin =
+ Origin::Create(GURL("http://someorigin.com:82/"));
scoped_refptr<IndexedDBBackingStore> diskStore2 =
factory->TestOpenBackingStore(ok_origin, context->data_path());
EXPECT_TRUE(diskStore2.get());
@@ -252,7 +404,7 @@ TEST_F(IndexedDBFactoryTest, RejectLongOrigins) {
class DiskFullFactory : public IndexedDBFactoryImpl {
public:
explicit DiskFullFactory(IndexedDBContextImpl* context)
- : IndexedDBFactoryImpl(context) {}
+ : IndexedDBFactoryImpl(context, base::DefaultClock::GetInstance()) {}
private:
~DiskFullFactory() override {}
@@ -306,12 +458,12 @@ TEST_F(IndexedDBFactoryTest, QuotaErrorOnDiskFull) {
scoped_refptr<IndexedDBDatabaseCallbacks>
dummy_database_callbacks) {
- const Origin origin(GURL("http://localhost:81"));
+ const Origin origin = Origin::Create(GURL("http://localhost:81"));
scoped_refptr<DiskFullFactory> factory =
base::MakeRefCounted<DiskFullFactory>(context);
const base::string16 name(ASCIIToUTF16("name"));
std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
callbacks, dummy_database_callbacks,
0 /* child_process_id */, 2 /* transaction_id */,
1 /* version */));
@@ -336,10 +488,10 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose) {
scoped_refptr<MockIDBFactory> factory =
base::MakeRefCounted<MockIDBFactory>(context);
- const Origin origin(GURL("http://localhost:81"));
+ const Origin origin = Origin::Create(GURL("http://localhost:81"));
const int64_t transaction_id = 1;
std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
callbacks, db_callbacks, 0 /* child_process_id */,
transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
@@ -374,10 +526,10 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) {
scoped_refptr<MockIDBFactory> factory =
base::MakeRefCounted<MockIDBFactory>(context);
- const Origin origin(GURL("http://localhost:81"));
+ const Origin origin = Origin::Create(GURL("http://localhost:81"));
const int64_t transaction_id = 1;
std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
callbacks, db_callbacks, 0 /* child_process_id */,
transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
@@ -422,7 +574,7 @@ TEST_F(IndexedDBFactoryTest, DeleteDatabaseClosesBackingStore) {
scoped_refptr<MockIDBFactory> factory =
base::MakeRefCounted<MockIDBFactory>(context);
- const Origin origin(GURL("http://localhost:81"));
+ const Origin origin = Origin::Create(GURL("http://localhost:81"));
EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
factory->DeleteDatabase(
@@ -454,7 +606,7 @@ TEST_F(IndexedDBFactoryTest, GetDatabaseNamesClosesBackingStore) {
scoped_refptr<MockIDBFactory> factory =
base::MakeRefCounted<MockIDBFactory>(context);
- const Origin origin(GURL("http://localhost:81"));
+ const Origin origin = Origin::Create(GURL("http://localhost:81"));
EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
factory->GetDatabaseNames(callbacks, origin, context->data_path(),
@@ -486,10 +638,10 @@ TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) {
scoped_refptr<MockIDBFactory> factory =
base::MakeRefCounted<MockIDBFactory>(context);
- const Origin origin(GURL("http://localhost:81"));
+ const Origin origin = Origin::Create(GURL("http://localhost:81"));
const int64_t transaction_id = 1;
std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
callbacks, db_callbacks, 0 /* child_process_id */,
transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
@@ -562,7 +714,7 @@ class ErrorCallbacks : public MockIndexedDBCallbacks {
};
TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) {
- const Origin origin(GURL("http://localhost:81"));
+ const Origin origin = Origin::Create(GURL("http://localhost:81"));
const base::string16 db_name(ASCIIToUTF16("db"));
const int64_t transaction_id = 1;
@@ -591,7 +743,7 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) {
const int64_t db_version = 2;
(*factory)->Open(
db_name,
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
*upgrade_callbacks, db_callbacks, 0 /* child_process_id */,
transaction_id, db_version),
nullptr /* request_context */, origin, context->data_path());
@@ -631,7 +783,7 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) {
{
const int64_t db_version = 1;
std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
failed_open_callbacks, db_callbacks,
0 /* child_process_id */, transaction_id, db_version));
factory->Open(db_name, std::move(connection),
@@ -707,7 +859,7 @@ TEST_F(IndexedDBFactoryTest, DataFormatVersion) {
*factory = base::MakeRefCounted<MockIDBFactory>(context);
(*factory)->Open(
ASCIIToUTF16("test_db"),
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
*callbacks, db_callbacks, 0 /* child_process_id */,
transaction_id, 1 /* version */),
nullptr /* request_context */, origin, context->data_path());
@@ -757,7 +909,7 @@ TEST_F(IndexedDBFactoryTest, DataFormatVersion) {
};
for (const auto& test : kTestCases) {
SCOPED_TRACE(test.origin);
- const Origin origin(GURL(test.origin));
+ const Origin origin = Origin::Create(GURL(test.origin));
ASSERT_EQ(kWebIDBDataLossNone, try_open(origin, test.open_version_1));
EXPECT_EQ(test.expected_data_loss, try_open(origin, test.open_version_2));
}
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 a025e844e86..3c68fcd7cba 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
@@ -10,20 +10,20 @@
namespace content {
IndexedDBFakeBackingStore::IndexedDBFakeBackingStore()
- : IndexedDBBackingStore(NULL /* indexed_db_factory */,
- url::Origin(GURL("http://localhost:81")),
+ : 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>(),
- NULL /* task_runner */) {}
+ nullptr /* task_runner */) {}
IndexedDBFakeBackingStore::IndexedDBFakeBackingStore(
IndexedDBFactory* factory,
base::SequencedTaskRunner* task_runner)
: IndexedDBBackingStore(factory,
- url::Origin(GURL("http://localhost:81")),
+ url::Origin::Create(GURL("http://localhost:81")),
base::FilePath(),
- NULL /* request_context */,
+ nullptr /* request_context */,
std::unique_ptr<LevelDBDatabase>(),
std::unique_ptr<LevelDBComparator>(),
task_runner) {}
@@ -148,8 +148,7 @@ IndexedDBFakeBackingStore::OpenIndexCursor(
IndexedDBFakeBackingStore::FakeTransaction::FakeTransaction(
leveldb::Status result)
- : IndexedDBBackingStore::Transaction(NULL), result_(result) {
-}
+ : IndexedDBBackingStore::Transaction(nullptr), result_(result) {}
void IndexedDBFakeBackingStore::FakeTransaction::Begin() {}
leveldb::Status IndexedDBFakeBackingStore::FakeTransaction::CommitPhaseOne(
scoped_refptr<BlobWriteCallback> callback) {
diff --git a/chromium/content/browser/indexed_db/indexed_db_index_writer.cc b/chromium/content/browser/indexed_db/indexed_db_index_writer.cc
index 2059dfec59a..6493041b243 100644
--- a/chromium/content/browser/indexed_db/indexed_db_index_writer.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_index_writer.cc
@@ -137,7 +137,7 @@ bool MakeIndexWriters(IndexedDBTransaction* transaction,
keys.second.push_back(primary_key);
std::unique_ptr<IndexWriter> index_writer(
- base::MakeUnique<IndexWriter>(index, keys));
+ std::make_unique<IndexWriter>(index, keys));
bool can_add_keys = false;
bool backing_store_success =
index_writer->VerifyIndexKeys(backing_store,
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 6b5bb1e3edf..64ff9c3deb6 100644
--- a/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc
@@ -8,8 +8,11 @@
#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
+#include "base/task_scheduler/post_task.h"
#include "base/threading/platform_thread.h"
#include "base/values.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
@@ -151,7 +154,7 @@ bool IndexedDBInternalsUI::GetOriginData(
if (!args->GetString(1, &url_string))
return false;
- *origin = Origin(GURL(url_string));
+ *origin = Origin::Create(GURL(url_string));
return GetOriginContext(*partition_path, *origin, context);
}
@@ -225,8 +228,7 @@ void IndexedDBInternalsUI::DownloadOriginDataOnIndexedDBThread(
if (!temp_dir.CreateUniqueTempDir())
return;
- // This will get cleaned up on the File thread after the download
- // has completed.
+ // This will get cleaned up after the download has completed.
base::FilePath temp_path = temp_dir.Take();
std::string origin_id = storage::GetIdentifierFromOrigin(origin.GetURL());
@@ -346,7 +348,7 @@ void FileDeleter::OnDownloadUpdated(DownloadItem* item) {
case DownloadItem::CANCELLED:
case DownloadItem::INTERRUPTED: {
item->RemoveObserver(this);
- BrowserThread::DeleteOnFileThread::Destruct(this);
+ delete this;
break;
}
default:
@@ -355,9 +357,11 @@ void FileDeleter::OnDownloadUpdated(DownloadItem* item) {
}
FileDeleter::~FileDeleter() {
- base::ScopedTempDir path;
- bool will_delete = path.Set(temp_dir_);
- DCHECK(will_delete);
+ base::PostTaskWithTraits(FROM_HERE,
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
+ base::Bind(base::IgnoreResult(&base::DeleteFile),
+ std::move(temp_dir_), true));
}
void IndexedDBInternalsUI::OnDownloadStarted(
diff --git a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc
index e3ba87f10cb..ca991f9bb82 100644
--- a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.cc
@@ -64,8 +64,9 @@ static const unsigned char kMaxDatabaseIdTypeByte = 1;
static const unsigned char kDataVersionTypeByte = 2;
static const unsigned char kBlobJournalTypeByte = 3;
static const unsigned char kLiveBlobJournalTypeByte = 4;
+static const unsigned char kEarliestSweepTimeTypeByte = 5;
static const unsigned char kMaxSimpleGlobalMetaDataTypeByte =
- 5; // Insert before this and increment.
+ 6; // Insert before this and increment.
static const unsigned char kDatabaseFreeListTypeByte = 100;
static const unsigned char kDatabaseNameTypeByte = 201;
@@ -376,7 +377,7 @@ bool DecodeIDBKey(StringPiece* slice, std::unique_ptr<IndexedDBKey>* value) {
switch (type) {
case kIndexedDBKeyNullTypeByte:
- *value = base::MakeUnique<IndexedDBKey>();
+ *value = std::make_unique<IndexedDBKey>();
return true;
case kIndexedDBKeyArrayTypeByte: {
@@ -390,35 +391,35 @@ bool DecodeIDBKey(StringPiece* slice, std::unique_ptr<IndexedDBKey>* value) {
return false;
array.push_back(*key);
}
- *value = base::MakeUnique<IndexedDBKey>(array);
+ *value = std::make_unique<IndexedDBKey>(array);
return true;
}
case kIndexedDBKeyBinaryTypeByte: {
std::string binary;
if (!DecodeBinary(slice, &binary))
return false;
- *value = base::MakeUnique<IndexedDBKey>(binary);
+ *value = std::make_unique<IndexedDBKey>(binary);
return true;
}
case kIndexedDBKeyStringTypeByte: {
base::string16 s;
if (!DecodeStringWithLength(slice, &s))
return false;
- *value = base::MakeUnique<IndexedDBKey>(s);
+ *value = std::make_unique<IndexedDBKey>(s);
return true;
}
case kIndexedDBKeyDateTypeByte: {
double d;
if (!DecodeDouble(slice, &d))
return false;
- *value = base::MakeUnique<IndexedDBKey>(d, kWebIDBKeyTypeDate);
+ *value = std::make_unique<IndexedDBKey>(d, kWebIDBKeyTypeDate);
return true;
}
case kIndexedDBKeyNumberTypeByte: {
double d;
if (!DecodeDouble(slice, &d))
return false;
- *value = base::MakeUnique<IndexedDBKey>(d, kWebIDBKeyTypeNumber);
+ *value = std::make_unique<IndexedDBKey>(d, kWebIDBKeyTypeNumber);
return true;
}
}
@@ -1217,6 +1218,12 @@ std::string LiveBlobJournalKey::Encode() {
return ret;
}
+std::string EarliestSweepKey::Encode() {
+ std::string ret = KeyPrefix::EncodeEmpty();
+ ret.push_back(kEarliestSweepTimeTypeByte);
+ return ret;
+}
+
DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {}
bool DatabaseFreeListKey::Decode(StringPiece* slice,
diff --git a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h
index c7cd4bd7fd8..d44085b0070 100644
--- a/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h
+++ b/chromium/content/browser/indexed_db/indexed_db_leveldb_coding.h
@@ -206,6 +206,11 @@ class LiveBlobJournalKey {
static std::string Encode();
};
+class EarliestSweepKey {
+ public:
+ static std::string Encode();
+};
+
class DatabaseFreeListKey {
public:
DatabaseFreeListKey();
diff --git a/chromium/content/browser/indexed_db/indexed_db_leveldb_operations.cc b/chromium/content/browser/indexed_db/indexed_db_leveldb_operations.cc
index bebc588b0bc..8254366528a 100644
--- a/chromium/content/browser/indexed_db/indexed_db_leveldb_operations.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_leveldb_operations.cc
@@ -423,5 +423,29 @@ bool UpdateBlobKeyGeneratorCurrentNumber(
return true;
}
+Status GetEarliestSweepTime(LevelDBDatabase* db, base::Time* earliest_sweep) {
+ const std::string earliest_sweep_time_key = EarliestSweepKey::Encode();
+ *earliest_sweep = base::Time();
+ bool found = false;
+ int64_t time_micros = 0;
+ Status s =
+ indexed_db::GetInt(db, earliest_sweep_time_key, &time_micros, &found);
+ if (!s.ok())
+ return s;
+ if (!found)
+ time_micros = 0;
+
+ DCHECK_GE(time_micros, 0);
+ *earliest_sweep += base::TimeDelta::FromMicroseconds(time_micros);
+
+ return s;
+}
+
+void SetEarliestSweepTime(LevelDBTransaction* txn, base::Time earliest_sweep) {
+ const std::string earliest_sweep_time_key = EarliestSweepKey::Encode();
+ int64_t time_micros = (earliest_sweep - base::Time()).InMicroseconds();
+ indexed_db::PutInt(txn, earliest_sweep_time_key, time_micros);
+}
+
} // namespace indexed_db
} // namespace content
diff --git a/chromium/content/browser/indexed_db/indexed_db_leveldb_operations.h b/chromium/content/browser/indexed_db/indexed_db_leveldb_operations.h
index 71135ef04bc..ab9a260ca94 100644
--- a/chromium/content/browser/indexed_db/indexed_db_leveldb_operations.h
+++ b/chromium/content/browser/indexed_db/indexed_db_leveldb_operations.h
@@ -9,12 +9,14 @@
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
+#include "base/time/time.h"
#include "content/common/indexed_db/indexed_db_key_path.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"
// Contains common operations for LevelDBTransactions and/or LevelDBDatabases.
namespace content {
+class LevelDBDatabase;
class LevelDBIterator;
class LevelDBTransaction;
@@ -127,6 +129,12 @@ WARN_UNUSED_RESULT bool UpdateBlobKeyGeneratorCurrentNumber(
int64_t database_id,
int64_t blob_key_generator_current_number);
+WARN_UNUSED_RESULT leveldb::Status GetEarliestSweepTime(
+ LevelDBDatabase* db,
+ base::Time* earliest_sweep);
+
+void SetEarliestSweepTime(LevelDBTransaction* txn, base::Time earliest_sweep);
+
} // namespace indexed_db
} // namespace content
diff --git a/chromium/content/browser/indexed_db/indexed_db_quota_client_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
index ee800d05301..fa90cef8238 100644
--- a/chromium/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
@@ -69,7 +69,7 @@ class IndexedDBQuotaClientTest : public testing::Test {
~IndexedDBQuotaClientTest() override {
RunAllTasksUntilIdle();
- idb_context_ = NULL;
+ idb_context_ = nullptr;
browser_context_.reset();
base::RunLoop().RunUntilIdle();
}
diff --git a/chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper.cc b/chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper.cc
index 2ecdf6d0acb..dea4d9a52c2 100644
--- a/chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper.cc
@@ -226,11 +226,13 @@ void IndexedDBTombstoneSweeper::RecordUMAStats(
size_histogram->Add(metrics_.seen_tombstones_size);
// We put our max at 20 instead of 100 to reduce the number of buckets.
- const static int kIndexPercentageBucketCount = 20;
- LOCAL_HISTOGRAM_ENUMERATION(
- "WebCore.IndexedDB.TombstoneSweeper.IndexScanPercent",
- indices_scanned_ * kIndexPercentageBucketCount / total_indices_,
- kIndexPercentageBucketCount + 1);
+ if (total_indices_ > 0) {
+ const static int kIndexPercentageBucketCount = 20;
+ LOCAL_HISTOGRAM_ENUMERATION(
+ "WebCore.IndexedDB.TombstoneSweeper.IndexScanPercent",
+ indices_scanned_ * kIndexPercentageBucketCount / total_indices_,
+ kIndexPercentageBucketCount + 1);
+ }
}
leveldb::Status IndexedDBTombstoneSweeper::FlushDeletions() {
diff --git a/chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper_unittest.cc
index 3e648fc95df..820cec2863b 100644
--- a/chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper_unittest.cc
@@ -131,7 +131,7 @@ class IndexedDBTombstoneSweeperTest : public testing::TestWithParam<Mode> {
}
void SetupMockDB() {
- sweeper_ = base::MakeUnique<IndexedDBTombstoneSweeper>(
+ sweeper_ = std::make_unique<IndexedDBTombstoneSweeper>(
GetParam(), kRoundIterations, kMaxIterations, &mock_db_);
sweeper_->SetStartSeedsForTesting(0, 0, 0);
}
@@ -139,7 +139,7 @@ class IndexedDBTombstoneSweeperTest : public testing::TestWithParam<Mode> {
void SetupRealDB() {
comparator_.reset(new Comparator());
in_memory_db_ = LevelDBDatabase::OpenInMemory(comparator_.get());
- sweeper_ = base::MakeUnique<IndexedDBTombstoneSweeper>(
+ sweeper_ = std::make_unique<IndexedDBTombstoneSweeper>(
GetParam(), kRoundIterations, kMaxIterations, in_memory_db_->db());
sweeper_->SetStartSeedsForTesting(0, 0, 0);
}
diff --git a/chromium/content/browser/indexed_db/indexed_db_transaction.cc b/chromium/content/browser/indexed_db/indexed_db_transaction.cc
index 1f0fce71a72..5288b189c70 100644
--- a/chromium/content/browser/indexed_db/indexed_db_transaction.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_transaction.cc
@@ -552,7 +552,7 @@ void IndexedDBTransaction::AddPendingObserver(
int32_t observer_id,
const IndexedDBObserver::Options& options) {
DCHECK_NE(mode(), blink::kWebIDBTransactionModeVersionChange);
- pending_observers_.push_back(base::MakeUnique<IndexedDBObserver>(
+ pending_observers_.push_back(std::make_unique<IndexedDBObserver>(
observer_id, object_store_ids_, options));
}
diff --git a/chromium/content/browser/indexed_db/indexed_db_transaction_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_transaction_unittest.cc
index c246ba42047..b5ba5ab17b9 100644
--- a/chromium/content/browser/indexed_db/indexed_db_transaction_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_transaction_unittest.cc
@@ -55,7 +55,7 @@ class IndexedDBTransactionTest : public testing::Test {
leveldb::Status s;
std::tie(db_, s) = IndexedDBDatabase::Create(
base::ASCIIToUTF16("db"), backing_store_.get(), factory_.get(),
- base::MakeUnique<FakeIndexedDBMetadataCoding>(),
+ std::make_unique<FakeIndexedDBMetadataCoding>(),
IndexedDBDatabase::Identifier());
ASSERT_TRUE(s.ok());
}
@@ -97,7 +97,7 @@ TEST_F(IndexedDBTransactionTest, Timeout) {
const std::set<int64_t> scope;
const leveldb::Status commit_success = leveldb::Status::OK();
std::unique_ptr<IndexedDBConnection> connection(
- base::MakeUnique<IndexedDBConnection>(
+ std::make_unique<IndexedDBConnection>(
kFakeProcessId, db_, new MockIndexedDBDatabaseCallbacks()));
std::unique_ptr<IndexedDBTransaction> transaction =
std::unique_ptr<IndexedDBTransaction>(new IndexedDBTransaction(
@@ -143,7 +143,7 @@ TEST_F(IndexedDBTransactionTest, NoTimeoutReadOnly) {
const std::set<int64_t> scope;
const leveldb::Status commit_success = leveldb::Status::OK();
std::unique_ptr<IndexedDBConnection> connection(
- base::MakeUnique<IndexedDBConnection>(
+ std::make_unique<IndexedDBConnection>(
kFakeProcessId, db_, new MockIndexedDBDatabaseCallbacks()));
std::unique_ptr<IndexedDBTransaction> transaction =
std::unique_ptr<IndexedDBTransaction>(new IndexedDBTransaction(
@@ -178,7 +178,7 @@ TEST_P(IndexedDBTransactionTestMode, ScheduleNormalTask) {
const std::set<int64_t> scope;
const leveldb::Status commit_success = leveldb::Status::OK();
std::unique_ptr<IndexedDBConnection> connection(
- base::MakeUnique<IndexedDBConnection>(
+ std::make_unique<IndexedDBConnection>(
kFakeProcessId, db_, new MockIndexedDBDatabaseCallbacks()));
std::unique_ptr<IndexedDBTransaction> transaction =
std::unique_ptr<IndexedDBTransaction>(new IndexedDBTransaction(
@@ -240,7 +240,7 @@ TEST_P(IndexedDBTransactionTestMode, TaskFails) {
const std::set<int64_t> scope;
const leveldb::Status commit_success = leveldb::Status::OK();
std::unique_ptr<IndexedDBConnection> connection(
- base::MakeUnique<IndexedDBConnection>(
+ std::make_unique<IndexedDBConnection>(
kFakeProcessId, db_, new MockIndexedDBDatabaseCallbacks()));
std::unique_ptr<IndexedDBTransaction> transaction =
std::unique_ptr<IndexedDBTransaction>(new IndexedDBTransaction(
@@ -305,7 +305,7 @@ TEST_F(IndexedDBTransactionTest, SchedulePreemptiveTask) {
const std::set<int64_t> scope;
const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch.");
std::unique_ptr<IndexedDBConnection> connection(
- base::MakeUnique<IndexedDBConnection>(
+ std::make_unique<IndexedDBConnection>(
kFakeProcessId, db_, new MockIndexedDBDatabaseCallbacks()));
std::unique_ptr<IndexedDBTransaction> transaction =
std::unique_ptr<IndexedDBTransaction>(new IndexedDBTransaction(
@@ -367,7 +367,7 @@ TEST_P(IndexedDBTransactionTestMode, AbortTasks) {
const std::set<int64_t> scope;
const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch.");
std::unique_ptr<IndexedDBConnection> connection(
- base::MakeUnique<IndexedDBConnection>(
+ std::make_unique<IndexedDBConnection>(
kFakeProcessId, db_, new MockIndexedDBDatabaseCallbacks()));
std::unique_ptr<IndexedDBTransaction> transaction =
std::unique_ptr<IndexedDBTransaction>(new IndexedDBTransaction(
@@ -396,7 +396,7 @@ TEST_P(IndexedDBTransactionTestMode, AbortPreemptive) {
const std::set<int64_t> scope;
const leveldb::Status commit_success = leveldb::Status::OK();
std::unique_ptr<IndexedDBConnection> connection(
- base::MakeUnique<IndexedDBConnection>(
+ std::make_unique<IndexedDBConnection>(
kFakeProcessId, db_, new MockIndexedDBDatabaseCallbacks()));
std::unique_ptr<IndexedDBTransaction> transaction =
std::unique_ptr<IndexedDBTransaction>(new IndexedDBTransaction(
@@ -450,7 +450,7 @@ TEST_F(IndexedDBTransactionTest, IndexedDBObserver) {
const std::set<int64_t> scope;
const leveldb::Status commit_success = leveldb::Status::OK();
std::unique_ptr<IndexedDBConnection> connection(
- base::MakeUnique<IndexedDBConnection>(
+ std::make_unique<IndexedDBConnection>(
kFakeProcessId, db_, new MockIndexedDBDatabaseCallbacks()));
base::WeakPtr<IndexedDBTransaction> transaction =
diff --git a/chromium/content/browser/indexed_db/indexed_db_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_unittest.cc
index 973b518a199..80c9b85019b 100644
--- a/chromium/content/browser/indexed_db/indexed_db_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_unittest.cc
@@ -37,8 +37,8 @@ class IndexedDBTest : public testing::Test {
const Origin kSessionOnlyOrigin;
IndexedDBTest()
- : kNormalOrigin(GURL("http://normal/")),
- kSessionOnlyOrigin(GURL("http://session-only/")),
+ : kNormalOrigin(url::Origin::Create(GURL("http://normal/"))),
+ kSessionOnlyOrigin(url::Origin::Create(GURL("http://session-only/"))),
special_storage_policy_(
base::MakeRefCounted<MockSpecialStoragePolicy>()),
quota_manager_proxy_(
@@ -159,7 +159,7 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) {
special_storage_policy_.get(),
quota_manager_proxy_.get());
- const Origin kTestOrigin(GURL("http://test/"));
+ const Origin kTestOrigin = Origin::Create(GURL("http://test/"));
idb_context->TaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(
@@ -181,14 +181,14 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) {
idb_context->GetFilePathForTesting(origin);
factory->Open(base::ASCIIToUTF16("opendb"),
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
open_callbacks, open_db_callbacks,
child_process_id, host_transaction_id, version),
request_context, origin, idb_context->data_path());
EXPECT_TRUE(base::DirectoryExists(test_path));
factory->Open(base::ASCIIToUTF16("closeddb"),
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
closed_callbacks, closed_db_callbacks,
child_process_id, host_transaction_id, version),
request_context, origin, idb_context->data_path());
@@ -213,7 +213,7 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) {
TEST_F(IndexedDBTest, DeleteFailsIfDirectoryLocked) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- const Origin kTestOrigin(GURL("http://test/"));
+ const Origin kTestOrigin = Origin::Create(GURL("http://test/"));
scoped_refptr<IndexedDBContextImpl> idb_context =
base::MakeRefCounted<IndexedDBContextImpl>(temp_dir.GetPath(),
@@ -252,7 +252,7 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) {
[](IndexedDBContextImpl* idb_context, const base::FilePath temp_path,
scoped_refptr<MockIndexedDBCallbacks> callbacks,
scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks) {
- const Origin kTestOrigin(GURL("http://test/"));
+ const Origin kTestOrigin = Origin::Create(GURL("http://test/"));
scoped_refptr<IndexedDBFactoryImpl> factory =
static_cast<IndexedDBFactoryImpl*>(
@@ -263,7 +263,7 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) {
const scoped_refptr<net::URLRequestContextGetter> request_context;
std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
+ std::make_unique<IndexedDBPendingConnection>(
callbacks, db_callbacks, child_process_id, transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
factory->Open(base::ASCIIToUTF16("db"), std::move(connection),
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc b/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc
index 8de78a3f503..415c057faa8 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc
@@ -275,12 +275,12 @@ std::unique_ptr<LevelDBLock> LevelDBDatabase::LockForTesting(
const base::FilePath& file_name) {
leveldb::Env* env = LevelDBEnv::Get();
base::FilePath lock_path = file_name.AppendASCII("LOCK");
- leveldb::FileLock* lock = NULL;
+ leveldb::FileLock* lock = nullptr;
leveldb::Status status = env->LockFile(lock_path.AsUTF8Unsafe(), &lock);
if (!status.ok())
return std::unique_ptr<LevelDBLock>();
DCHECK(lock);
- return base::MakeUnique<LockImpl>(env, lock);
+ return std::make_unique<LockImpl>(env, lock);
}
// static
@@ -293,7 +293,7 @@ leveldb::Status LevelDBDatabase::Open(const base::FilePath& file_name,
base::TimeTicks begin_time = base::TimeTicks::Now();
std::unique_ptr<ComparatorAdapter> comparator_adapter(
- base::MakeUnique<ComparatorAdapter>(comparator));
+ std::make_unique<ComparatorAdapter>(comparator));
std::unique_ptr<leveldb::DB> db;
std::unique_ptr<const leveldb::FilterPolicy> filter_policy;
@@ -332,7 +332,7 @@ leveldb::Status LevelDBDatabase::Open(const base::FilePath& file_name,
std::unique_ptr<LevelDBDatabase> LevelDBDatabase::OpenInMemory(
const LevelDBComparator* comparator) {
std::unique_ptr<ComparatorAdapter> comparator_adapter(
- base::MakeUnique<ComparatorAdapter>(comparator));
+ std::make_unique<ComparatorAdapter>(comparator));
std::unique_ptr<leveldb::Env> in_memory_env(
leveldb_chrome::NewMemEnv(LevelDBEnv::Get()));
@@ -397,7 +397,7 @@ leveldb::Status LevelDBDatabase::Get(const StringPiece& key,
leveldb::ReadOptions read_options;
read_options.verify_checksums = true; // TODO(jsbell): Disable this if the
// performance impact is too great.
- read_options.snapshot = snapshot ? snapshot->snapshot_ : 0;
+ read_options.snapshot = snapshot ? snapshot->snapshot_ : nullptr;
const leveldb::Status s =
db_->Get(read_options, leveldb_env::MakeSlice(key), value);
@@ -434,7 +434,7 @@ std::unique_ptr<LevelDBIterator> LevelDBDatabase::CreateIterator(
leveldb::ReadOptions read_options;
read_options.verify_checksums = true; // TODO(jsbell): Disable this if the
// performance impact is too great.
- read_options.snapshot = snapshot ? snapshot->snapshot_ : 0;
+ read_options.snapshot = snapshot ? snapshot->snapshot_ : nullptr;
num_iterators_++;
max_iterators_ = std::max(max_iterators_, num_iterators_);
@@ -456,29 +456,33 @@ void LevelDBDatabase::Compact(const base::StringPiece& start,
const leveldb::Slice start_slice = leveldb_env::MakeSlice(start);
const leveldb::Slice stop_slice = leveldb_env::MakeSlice(stop);
// NULL batch means just wait for earlier writes to be done
- db_->Write(leveldb::WriteOptions(), NULL);
+ db_->Write(leveldb::WriteOptions(), nullptr);
db_->CompactRange(&start_slice, &stop_slice);
}
-void LevelDBDatabase::CompactAll() { db_->CompactRange(NULL, NULL); }
+void LevelDBDatabase::CompactAll() {
+ db_->CompactRange(nullptr, nullptr);
+}
bool LevelDBDatabase::OnMemoryDump(
const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) {
if (!db_)
return false;
-
- std::string value;
- uint64_t size;
- bool res = db_->GetProperty("leveldb.approximate-memory-usage", &value);
- DCHECK(res);
- base::StringToUint64(value, &size);
+ // All leveldb databases are already dumped by leveldb_env::DBTracker. Add
+ // an edge to the existing database.
+ auto* tracker_dump =
+ leveldb_env::DBTracker::GetOrCreateAllocatorDump(pmd, db_.get());
+ if (!tracker_dump)
+ return true;
auto* dump = pmd->CreateAllocatorDump(
base::StringPrintf("site_storage/index_db/0x%" PRIXPTR,
reinterpret_cast<uintptr_t>(db_.get())));
dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
- base::trace_event::MemoryAllocatorDump::kUnitsBytes, size);
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ tracker_dump->GetSizeInternal());
+ pmd->AddOwnershipEdge(dump->guid(), tracker_dump->guid());
// Dumps in BACKGROUND mode cannot have strings or edges in order to minimize
// trace size and instrumentation overhead.
@@ -488,14 +492,6 @@ bool LevelDBDatabase::OnMemoryDump(
}
dump->AddString("file_name", "", file_name_for_tracing);
-
- // All leveldb databases are already dumped by leveldb_env::DBTracker. Add
- // an edge to avoid double counting.
- auto* tracker_dump =
- leveldb_env::DBTracker::GetOrCreateAllocatorDump(pmd, db_.get());
- if (tracker_dump)
- pmd->AddOwnershipEdge(dump->guid(), tracker_dump->guid());
-
return true;
}
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_database.h b/chromium/content/browser/indexed_db/leveldb/leveldb_database.h
index c27dea066f0..039cccc317f 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_database.h
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_database.h
@@ -136,7 +136,6 @@ class CONTENT_EXPORT LevelDBDatabase
};
// Despite the type name, this object uses LRU eviction.
- size_t lru_max_size_ = 0;
base::HashingMRUCache<LevelDBIterator*, DetachIteratorOnDestruct>
iterator_lru_;
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc b/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc
index b2e83c42b23..dc1452d0cad 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc
@@ -49,7 +49,7 @@ void LevelDBTransaction::Set(const StringPiece& key,
DataType::iterator it = data_.find(key);
if (it == data_.end()) {
- std::unique_ptr<Record> record = base::MakeUnique<Record>();
+ std::unique_ptr<Record> record = std::make_unique<Record>();
size_ += SizeOfRecordInMap(key.size()) + value->size();
record->key.assign(key.begin(), key.end() - key.begin());
record->value.swap(*value);
@@ -383,7 +383,7 @@ void LevelDBTransaction::TransactionIterator::Delete() {
transaction_->size_ -= data_iterator_->Value().size();
data_iterator_->Delete();
} else {
- std::unique_ptr<Record> record = base::MakeUnique<Record>();
+ std::unique_ptr<Record> record = std::make_unique<Record>();
record->key = Key().as_string();
record->deleted = true;
transaction_->size_ +=
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_unittest.cc b/chromium/content/browser/indexed_db/leveldb/leveldb_unittest.cc
index 3c69af2827a..4ec7a8ea616 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_unittest.cc
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_unittest.cc
@@ -17,6 +17,7 @@
#include "content/browser/indexed_db/leveldb/leveldb_env.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/env_chromium.h"
+#include "third_party/leveldatabase/leveldb_chrome.h"
namespace content {
@@ -66,10 +67,8 @@ TEST(LevelDBDatabaseTest, CorruptionTest) {
leveldb.reset();
EXPECT_FALSE(leveldb);
- base::FilePath file_path = temp_directory.GetPath().AppendASCII("CURRENT");
- base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_WRITE);
- file.SetLength(0);
- file.Close();
+ EXPECT_TRUE(
+ leveldb_chrome::CorruptClosedDBForTesting(temp_directory.GetPath()));
status = LevelDBDatabase::Open(temp_directory.GetPath(), &comparator,
kDefaultMaxOpenIteratorsPerDatabase, &leveldb);
diff --git a/chromium/content/browser/indexed_db/leveldb_coding_scheme.md b/chromium/content/browser/indexed_db/leveldb_coding_scheme.md
index 1a449d3b399..83e5546523c 100644
--- a/chromium/content/browser/indexed_db/leveldb_coding_scheme.md
+++ b/chromium/content/browser/indexed_db/leveldb_coding_scheme.md
@@ -153,6 +153,7 @@ key | value
«0, 0, 0, 2» | data format version (Int) [`DataVersionKey`]
«0, 0, 0, 3» | primary BlobJournal [`BlobJournalKey`]
«0, 0, 0, 4» | live BlobJournal [`LiveBlobJournalKey`]
+«0, 0, 0, 5» | earliest sweep time (microseconds) (Int) [`EarliestSweepKey`]
«0, 0, 0, 100, database id (VarInt)» | Existence implies the database id is in the free list [`DatabaseFreeListKey`] - _obsolete_
«0, 0, 0, 201, origin (StringWithLength), database name (StringWithLength)» | Database id (Int) [`DatabaseNameKey`]
diff --git a/chromium/content/browser/indexed_db/list_set_unittest.cc b/chromium/content/browser/indexed_db/list_set_unittest.cc
index b5b7145669a..615b547955a 100644
--- a/chromium/content/browser/indexed_db/list_set_unittest.cc
+++ b/chromium/content/browser/indexed_db/list_set_unittest.cc
@@ -166,9 +166,9 @@ TEST(ListSetTest, ListSetObject) {
}
TEST(ListSetTest, ListSetPointer) {
- std::unique_ptr<Wrapped<int>> w0 = base::MakeUnique<Wrapped<int>>(0);
- std::unique_ptr<Wrapped<int>> w1 = base::MakeUnique<Wrapped<int>>(1);
- std::unique_ptr<Wrapped<int>> w2 = base::MakeUnique<Wrapped<int>>(2);
+ std::unique_ptr<Wrapped<int>> w0 = std::make_unique<Wrapped<int>>(0);
+ std::unique_ptr<Wrapped<int>> w1 = std::make_unique<Wrapped<int>>(1);
+ std::unique_ptr<Wrapped<int>> w2 = std::make_unique<Wrapped<int>>(2);
list_set<Wrapped<int>*> set;
EXPECT_EQ(0u, set.size());
diff --git a/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc b/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc
index 36bf7ffa968..266205bdb14 100644
--- a/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc
+++ b/chromium/content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc
@@ -318,14 +318,14 @@ MockBrowserTestIndexedDBClassFactory::CreateIteratorImpl(
instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] =
instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] + 1;
if (only_trace_calls_) {
- return base::MakeUnique<LevelDBTraceIteratorImpl>(
+ return std::make_unique<LevelDBTraceIteratorImpl>(
std::move(iterator), db, snapshot,
instance_count_[FAIL_CLASS_LEVELDB_ITERATOR]);
} else {
if (failure_class_ == FAIL_CLASS_LEVELDB_ITERATOR &&
instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] ==
fail_on_instance_num_[FAIL_CLASS_LEVELDB_ITERATOR]) {
- return base::MakeUnique<LevelDBTestIteratorImpl>(
+ return std::make_unique<LevelDBTestIteratorImpl>(
std::move(iterator), db, snapshot, failure_method_,
fail_on_call_num_[FAIL_CLASS_LEVELDB_ITERATOR]);
} else {
diff --git a/chromium/content/browser/installedapp/installed_app_provider_impl_default.cc b/chromium/content/browser/installedapp/installed_app_provider_impl_default.cc
index a71e9d87ce5..3a77bd75c01 100644
--- a/chromium/content/browser/installedapp/installed_app_provider_impl_default.cc
+++ b/chromium/content/browser/installedapp/installed_app_provider_impl_default.cc
@@ -23,7 +23,7 @@ void InstalledAppProviderImplDefault::FilterInstalledApps(
// static
void InstalledAppProviderImplDefault::Create(
blink::mojom::InstalledAppProviderRequest request) {
- mojo::MakeStrongBinding(base::MakeUnique<InstalledAppProviderImplDefault>(),
+ mojo::MakeStrongBinding(std::make_unique<InstalledAppProviderImplDefault>(),
std::move(request));
}
diff --git a/chromium/content/browser/interface_provider_filtering.cc b/chromium/content/browser/interface_provider_filtering.cc
new file mode 100644
index 00000000000..d330e24ae2c
--- /dev/null
+++ b/chromium/content/browser/interface_provider_filtering.cc
@@ -0,0 +1,57 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/interface_provider_filtering.h"
+
+#include <utility>
+
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+namespace content {
+namespace {
+
+void FilterInterfacesImpl(
+ const char* spec,
+ int process_id,
+ service_manager::mojom::InterfaceProviderRequest request,
+ service_manager::mojom::InterfaceProviderPtr provider) {
+ RenderProcessHost* process = RenderProcessHost::FromID(process_id);
+ if (!process)
+ return;
+
+ service_manager::Connector* connector =
+ BrowserContext::GetConnectorFor(process->GetBrowserContext());
+ // |connector| is null in unit tests.
+ if (!connector)
+ return;
+
+ connector->FilterInterfaces(spec, process->GetChildIdentity(),
+ std::move(request), std::move(provider));
+}
+
+} // namespace
+
+service_manager::mojom::InterfaceProviderRequest
+FilterRendererExposedInterfaces(
+ const char* spec,
+ int process_id,
+ service_manager::mojom::InterfaceProviderRequest request) {
+ service_manager::mojom::InterfaceProviderPtr provider;
+ auto filtered_request = mojo::MakeRequest(&provider);
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&FilterInterfacesImpl, spec, process_id,
+ std::move(request), std::move(provider)));
+ } else {
+ FilterInterfacesImpl(spec, process_id, std::move(request),
+ std::move(provider));
+ }
+ return filtered_request;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/interface_provider_filtering.h b/chromium/content/browser/interface_provider_filtering.h
new file mode 100644
index 00000000000..9d0d84cec9a
--- /dev/null
+++ b/chromium/content/browser/interface_provider_filtering.h
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_INTERFACE_PROVIDER_FILTERING_H_
+#define CONTENT_BROWSER_INTERFACE_PROVIDER_FILTERING_H_
+
+#include "base/strings/string_piece.h"
+#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
+
+namespace content {
+
+// Filters interface requests received from an execution context of the type
+// corresponding to |spec| in the renderer process with ID |process_id|.
+// |request| is the InterfaceProviderRequest from the renderer; an equivalent
+// InterfaceProviderRequest where GetInterface requests have been filtered.
+//
+// If |process_id| does not refer to a renderer process or if that renderer's
+// BrowserContext does not have a Connector, the connection is broken instead;
+// that is, |request| and the InterfacePtr corresponding to the returned request
+// are both closed.
+service_manager::mojom::InterfaceProviderRequest
+FilterRendererExposedInterfaces(
+ const char* spec,
+ int process_id,
+ service_manager::mojom::InterfaceProviderRequest request);
+
+} // namespace content
+#endif // CONTENT_BROWSER_INTERFACE_PROVIDER_FILTERING_H_
diff --git a/chromium/content/browser/isolated_origin_browsertest.cc b/chromium/content/browser/isolated_origin_browsertest.cc
index cef4700c066..3bd370341db 100644
--- a/chromium/content/browser/isolated_origin_browsertest.cc
+++ b/chromium/content/browser/isolated_origin_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 <sstream>
+
#include "base/command_line.h"
#include "base/macros.h"
#include "base/test/scoped_feature_list.h"
@@ -266,7 +268,7 @@ IN_PROC_BROWSER_TEST_F(IsolatedOriginTest,
// main frame's SiteInstance.
GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
- EXPECT_FALSE(policy->IsIsolatedOrigin(url::Origin(bar_url)));
+ EXPECT_FALSE(policy->IsIsolatedOrigin(url::Origin::Create(bar_url)));
NavigateIframeToURL(web_contents(), "test_iframe", bar_url);
EXPECT_EQ(web_contents()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
@@ -577,9 +579,9 @@ IN_PROC_BROWSER_TEST_F(IsolatedOriginTest,
EXPECT_EQ(web_contents()->GetMainFrame()->GetProcess(),
new_shell->web_contents()->GetMainFrame()->GetProcess());
- // Wait for response from the redirect in the first tab. This should notice
- // that the first process is no longer suitable for the final destination
- // (which is an unisolated URL) and transfer to another process. In
+ // Wait for response from the first tab. This should notice that the first
+ // process is no longer suitable for the final destination (which is an
+ // unisolated URL) and transfer to another process. In
// https://crbug.com/773809, this led to a CHECK due to origin lock mismatch.
manager.WaitForNavigationFinished();
@@ -893,7 +895,8 @@ class StoragePartitonInterceptor
// security checks can be tested.
void OpenLocalStorage(const url::Origin& origin,
mojom::LevelDBWrapperRequest request) override {
- url::Origin mismatched_origin(GURL("http://abc.foo.com"));
+ url::Origin mismatched_origin =
+ url::Origin::Create(GURL("http://abc.foo.com"));
GetForwardingInterface()->OpenLocalStorage(mismatched_origin,
std::move(request));
}
@@ -961,4 +964,74 @@ IN_PROC_BROWSER_TEST_F(IsolatedOriginFieldTrialTest, Test) {
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.
+class IsolatedOriginLongListTest : public ContentBrowserTest {
+ public:
+ IsolatedOriginLongListTest() {}
+ ~IsolatedOriginLongListTest() override {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
+
+ std::ostringstream origin_list;
+ origin_list
+ << embedded_test_server()->GetURL("isolated.foo.com", "/").spec();
+ for (int i = 0; i < 1000; i++) {
+ std::ostringstream hostname;
+ hostname << "foo" << i << ".com";
+
+ origin_list << ","
+ << embedded_test_server()->GetURL(hostname.str(), "/").spec();
+ }
+ command_line->AppendSwitchASCII(switches::kIsolateOrigins,
+ origin_list.str());
+ }
+
+ void SetUpOnMainThread() override {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ embedded_test_server()->StartAcceptingConnections();
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(IsolatedOriginLongListTest, Test) {
+ GURL test_url(embedded_test_server()->GetURL(
+ "bar1.com",
+ "/cross_site_iframe_factory.html?"
+ "bar1.com(isolated.foo.com,foo999.com,bar2.com)"));
+ EXPECT_TRUE(NavigateToURL(shell(), test_url));
+
+ EXPECT_EQ(4u, shell()->web_contents()->GetAllFrames().size());
+ RenderFrameHost* main_frame = shell()->web_contents()->GetMainFrame();
+ RenderFrameHost* subframe1 = shell()->web_contents()->GetAllFrames()[1];
+ RenderFrameHost* subframe2 = shell()->web_contents()->GetAllFrames()[2];
+ RenderFrameHost* subframe3 = shell()->web_contents()->GetAllFrames()[3];
+ EXPECT_EQ("bar1.com", main_frame->GetLastCommittedOrigin().GetURL().host());
+ EXPECT_EQ("isolated.foo.com",
+ subframe1->GetLastCommittedOrigin().GetURL().host());
+ EXPECT_EQ("foo999.com", subframe2->GetLastCommittedOrigin().GetURL().host());
+ EXPECT_EQ("bar2.com", subframe3->GetLastCommittedOrigin().GetURL().host());
+
+ // bar1.com and bar2.com are not on the list of origins to isolate - they
+ // should stay in the same process, unless --site-per-process has also been
+ // specified.
+ if (!AreAllSitesIsolatedForTesting()) {
+ EXPECT_EQ(main_frame->GetProcess()->GetID(),
+ subframe3->GetProcess()->GetID());
+ EXPECT_EQ(main_frame->GetSiteInstance(), subframe3->GetSiteInstance());
+ }
+
+ // isolated.foo.com and foo999.com are on the list of origins to isolate -
+ // they should be isolated from everything else.
+ EXPECT_NE(main_frame->GetProcess()->GetID(),
+ subframe1->GetProcess()->GetID());
+ EXPECT_NE(main_frame->GetSiteInstance(), subframe1->GetSiteInstance());
+ EXPECT_NE(main_frame->GetProcess()->GetID(),
+ subframe2->GetProcess()->GetID());
+ EXPECT_NE(main_frame->GetSiteInstance(), subframe2->GetSiteInstance());
+ EXPECT_NE(subframe1->GetProcess()->GetID(), subframe2->GetProcess()->GetID());
+ EXPECT_NE(subframe1->GetSiteInstance(), subframe2->GetSiteInstance());
+}
+
} // namespace content
diff --git a/chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.cc b/chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
index f4e2127ebf1..49d3535cbdc 100644
--- a/chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
+++ b/chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
@@ -26,8 +26,8 @@ void KeyboardLockServiceImpl::CreateMojoService(
RenderFrameHost* render_frame_host,
blink::mojom::KeyboardLockServiceRequest request) {
mojo::MakeStrongBinding(
- base::MakeUnique<KeyboardLockServiceImpl>(render_frame_host),
- std::move(request));
+ std::make_unique<KeyboardLockServiceImpl>(render_frame_host),
+ std::move(request));
}
void KeyboardLockServiceImpl::RequestKeyboardLock(
diff --git a/chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.h b/chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.h
index 67c538a385c..e217d71c8ea 100644
--- a/chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.h
+++ b/chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.h
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#ifndef CONTENT_BROWSER_KEYBOARD_LOCK_KEYBOARD_LOCK_SERVICE_IMPL_H_
+#define CONTENT_BROWSER_KEYBOARD_LOCK_KEYBOARD_LOCK_SERVICE_IMPL_H_
+
#include <string>
#include <vector>
@@ -34,3 +37,5 @@ class CONTENT_EXPORT KeyboardLockServiceImpl
};
} // namespace
+
+#endif // CONTENT_BROWSER_KEYBOARD_LOCK_KEYBOARD_LOCK_SERVICE_IMPL_H_
diff --git a/chromium/content/browser/leveldb_wrapper_impl.cc b/chromium/content/browser/leveldb_wrapper_impl.cc
index e20d2eeea70..d5173bf1ad1 100644
--- a/chromium/content/browser/leveldb_wrapper_impl.cc
+++ b/chromium/content/browser/leveldb_wrapper_impl.cc
@@ -5,6 +5,8 @@
#include "content/browser/leveldb_wrapper_impl.h"
#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_dump_manager.h"
@@ -13,6 +15,13 @@
#include "content/public/browser/browser_thread.h"
namespace content {
+namespace {
+using leveldb::mojom::BatchedOperation;
+using leveldb::mojom::BatchedOperationPtr;
+using leveldb::mojom::DatabaseError;
+} // namespace
+
+LevelDBWrapperImpl::Delegate::~Delegate() {}
void LevelDBWrapperImpl::Delegate::MigrateData(
base::OnceCallback<void(std::unique_ptr<ValueMap>)> callback) {
@@ -24,7 +33,7 @@ std::vector<LevelDBWrapperImpl::Change> LevelDBWrapperImpl::Delegate::FixUpData(
return std::vector<Change>();
}
-void LevelDBWrapperImpl::Delegate::OnMapLoaded(leveldb::mojom::DatabaseError) {}
+void LevelDBWrapperImpl::Delegate::OnMapLoaded(DatabaseError) {}
bool LevelDBWrapperImpl::s_aggressive_flushing_enabled_ = false;
@@ -52,32 +61,67 @@ LevelDBWrapperImpl::CommitBatch::~CommitBatch() {}
LevelDBWrapperImpl::LevelDBWrapperImpl(
leveldb::mojom::LevelDBDatabase* database,
const std::string& prefix,
- size_t max_size,
- base::TimeDelta default_commit_delay,
- int max_bytes_per_hour,
- int max_commits_per_hour,
- Delegate* delegate)
+ Delegate* delegate,
+ const Options& options)
: prefix_(leveldb::StdStringToUint8Vector(prefix)),
delegate_(delegate),
database_(database),
- bytes_used_(0),
- max_size_(max_size),
+ cache_mode_(database ? options.cache_mode : CacheMode::KEYS_AND_VALUES),
+ storage_used_(0),
+ max_size_(options.max_size),
+ memory_used_(0),
start_time_(base::TimeTicks::Now()),
- default_commit_delay_(default_commit_delay),
- data_rate_limiter_(max_bytes_per_hour, base::TimeDelta::FromHours(1)),
- commit_rate_limiter_(max_commits_per_hour, base::TimeDelta::FromHours(1)),
+ default_commit_delay_(options.default_commit_delay),
+ data_rate_limiter_(options.max_bytes_per_hour,
+ base::TimeDelta::FromHours(1)),
+ commit_rate_limiter_(options.max_commits_per_hour,
+ base::TimeDelta::FromHours(1)),
weak_ptr_factory_(this) {
bindings_.set_connection_error_handler(base::Bind(
&LevelDBWrapperImpl::OnConnectionError, base::Unretained(this)));
}
LevelDBWrapperImpl::~LevelDBWrapperImpl() {
+ DCHECK(!has_pending_load_tasks());
if (commit_batch_)
CommitChanges();
}
void LevelDBWrapperImpl::Bind(mojom::LevelDBWrapperRequest request) {
bindings_.AddBinding(this, std::move(request));
+ // If the number of bindings is more than 1, then the |client_old_value| sent
+ // by the clients need not be valid due to races on updates from multiple
+ // clients. So, cache the values in the service. Setting cache mode back to
+ // only keys when the number of bindings goes back to 1 could cause
+ // inconsistency due to the async notifications of mutations to the client
+ // reaching late.
+ if (cache_mode_ == CacheMode::KEYS_ONLY_WHEN_POSSIBLE &&
+ bindings_.size() > 1) {
+ SetCacheMode(LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES);
+ }
+}
+
+std::unique_ptr<LevelDBWrapperImpl> LevelDBWrapperImpl::ForkToNewPrefix(
+ const std::string& new_prefix,
+ Delegate* delegate,
+ const Options& options) {
+ auto forked_wrapper = std::make_unique<LevelDBWrapperImpl>(
+ database_, new_prefix, delegate, options);
+
+ forked_wrapper->map_state_ = MapState::LOADING_FROM_FORK;
+
+ if (IsMapLoaded()) {
+ DoForkOperation(forked_wrapper->weak_ptr_factory_.GetWeakPtr());
+ } else {
+ LoadMap(base::BindOnce(&LevelDBWrapperImpl::DoForkOperation,
+ weak_ptr_factory_.GetWeakPtr(),
+ forked_wrapper->weak_ptr_factory_.GetWeakPtr()));
+ }
+ return forked_wrapper;
+}
+
+void LevelDBWrapperImpl::CancelAllPendingRequests() {
+ on_load_complete_tasks_.clear();
}
void LevelDBWrapperImpl::EnableAggressiveCommitDelay() {
@@ -86,8 +130,8 @@ void LevelDBWrapperImpl::EnableAggressiveCommitDelay() {
void LevelDBWrapperImpl::ScheduleImmediateCommit() {
if (!on_load_complete_tasks_.empty()) {
- LoadMap(base::Bind(&LevelDBWrapperImpl::ScheduleImmediateCommit,
- base::Unretained(this)));
+ LoadMap(base::BindOnce(&LevelDBWrapperImpl::ScheduleImmediateCommit,
+ base::Unretained(this)));
return;
}
@@ -99,7 +143,7 @@ void LevelDBWrapperImpl::ScheduleImmediateCommit() {
void LevelDBWrapperImpl::OnMemoryDump(
const std::string& name,
base::trace_event::ProcessMemoryDump* pmd) {
- if (!map_)
+ if (!IsMapLoaded())
return;
const char* system_allocator_name =
@@ -107,8 +151,11 @@ void LevelDBWrapperImpl::OnMemoryDump(
->system_allocator_pool_name();
if (commit_batch_) {
size_t data_size = 0;
+ for (const auto& iter : commit_batch_->changed_values)
+ data_size += iter.first.size() + iter.second.size();
for (const auto& key : commit_batch_->changed_keys)
data_size += key.size();
+
auto* commit_batch_mad = pmd->CreateAllocatorDump(name + "/commit_batch");
commit_batch_mad->AddScalar(
base::trace_event::MemoryAllocatorDump::kNameSize,
@@ -118,31 +165,43 @@ void LevelDBWrapperImpl::OnMemoryDump(
}
// Do not add storage map usage if less than 1KB.
- if (bytes_used_ < 1024)
+ if (memory_used_ < 1024)
return;
auto* map_mad = pmd->CreateAllocatorDump(name + "/storage_map");
map_mad->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- bytes_used_);
+ memory_used_);
+ map_mad->AddString("load_state", "",
+ map_state_ == MapState::LOADED_KEYS_ONLY
+ ? "keys_only"
+ : "keys_and_values");
if (system_allocator_name)
pmd->AddSuballocation(map_mad->guid(), system_allocator_name);
}
void LevelDBWrapperImpl::PurgeMemory() {
- if (!map_ || // We're not using any memory.
- commit_batch_ || // We leave things alone with changes pending.
+ if (!IsMapLoaded() || // We're not using any memory.
+ commit_batch_ || // We leave things alone with changes pending.
!database_) { // Don't purge anything if we're not backed by a database.
return;
}
- map_.reset();
+ map_state_ = MapState::UNLOADED;
+ keys_only_map_.clear();
+ keys_values_map_.clear();
+}
+
+void LevelDBWrapperImpl::SetCacheModeForTesting(CacheMode cache_mode) {
+ SetCacheMode(cache_mode);
}
void LevelDBWrapperImpl::AddObserver(
mojom::LevelDBObserverAssociatedPtrInfo observer) {
mojom::LevelDBObserverAssociatedPtr observer_ptr;
observer_ptr.Bind(std::move(observer));
+ if (cache_mode_ == CacheMode::KEYS_AND_VALUES)
+ observer_ptr->ShouldSendOldValueOnMutations(false);
observers_.AddPtr(std::move(observer_ptr));
}
@@ -152,45 +211,99 @@ void LevelDBWrapperImpl::Put(
const base::Optional<std::vector<uint8_t>>& client_old_value,
const std::string& source,
PutCallback callback) {
- if (!map_) {
- LoadMap(base::Bind(&LevelDBWrapperImpl::Put, base::Unretained(this), key,
- value, client_old_value, source,
- base::Passed(&callback)));
+ if (!IsMapLoaded() || IsMapUpgradeNeeded()) {
+ LoadMap(base::BindOnce(&LevelDBWrapperImpl::Put, base::Unretained(this),
+ key, value, client_old_value, source,
+ std::move(callback)));
return;
}
- bool has_old_item = false;
size_t old_item_size = 0;
- auto found = map_->find(key);
- if (found != map_->end()) {
- if (found->second == value) {
- std::move(callback).Run(true); // Key already has this value.
- return;
+ size_t old_item_memory = 0;
+ size_t new_item_memory = 0;
+ base::Optional<std::vector<uint8_t>> old_value;
+ if (map_state_ == MapState::LOADED_KEYS_ONLY) {
+ KeysOnlyMap::const_iterator found = keys_only_map_.find(key);
+ if (found != keys_only_map_.end()) {
+ if (client_old_value &&
+ client_old_value.value().size() == found->second) {
+ if (client_old_value == value) {
+ std::move(callback).Run(true); // Key already has this value.
+ return;
+ }
+ old_value = client_old_value.value();
+ } else {
+#if DCHECK_IS_ON()
+ // If |client_old_value| was not provided or if it's size does not
+ // match, then we still let the change go through. But the notification
+ // sent to clients will not contain old value. This is okay since
+ // currently the only observer to these notification is the client
+ // itself.
+ DVLOG(1) << "Wrapper with prefix "
+ << leveldb::Uint8VectorToStdString(prefix_)
+ << ": past value has length of " << found->second << ", but:";
+ if (client_old_value) {
+ DVLOG(1) << "Given past value has incorrect length of "
+ << client_old_value.value().size();
+ } else {
+ DVLOG(1) << "No given past value was provided.";
+ }
+#endif
+ }
+ old_item_size = key.size() + found->second;
+ old_item_memory = key.size() + sizeof(size_t);
+ }
+ 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);
+ if (found != keys_values_map_.end()) {
+ if (found->second == value) {
+ std::move(callback).Run(true); // Key already has this value.
+ return;
+ }
+ old_value = std::move(found->second);
+ old_item_size = key.size() + old_value.value().size();
+ old_item_memory = old_item_size;
}
- old_item_size = key.size() + found->second.size();
- has_old_item = true;
+ new_item_memory = key.size() + value.size();
}
+
size_t new_item_size = key.size() + value.size();
- size_t new_bytes_used = bytes_used_ - old_item_size + new_item_size;
+ size_t new_storage_used = storage_used_ - old_item_size + new_item_size;
// Only check quota if the size is increasing, this allows
// shrinking changes to pre-existing maps that are over budget.
- if (new_item_size > old_item_size && new_bytes_used > max_size_) {
- std::move(callback).Run(false);
+ if (new_item_size > old_item_size && new_storage_used > max_size_) {
+ if (map_state_ == MapState::LOADED_KEYS_ONLY) {
+ bindings_.ReportBadMessage(
+ "The quota in browser cannot exceed when there is only one "
+ "renderer.");
+ } else {
+ std::move(callback).Run(false);
+ }
return;
}
if (database_) {
CreateCommitBatchIfNeeded();
- commit_batch_->changed_keys.insert(key);
+ // No need to store values in |commit_batch_| if values are already
+ // available in |keys_values_map_|, since CommitChanges() will take values
+ // from there.
+ if (map_state_ == MapState::LOADED_KEYS_ONLY)
+ commit_batch_->changed_values[key] = value;
+ else
+ commit_batch_->changed_keys.insert(key);
}
- std::vector<uint8_t> old_value;
- if (has_old_item)
- old_value.swap((*map_)[key]);
- (*map_)[key] = value;
- bytes_used_ = new_bytes_used;
- if (!has_old_item) {
+ if (map_state_ == MapState::LOADED_KEYS_ONLY)
+ keys_only_map_[key] = value.size();
+ else
+ keys_values_map_[key] = value;
+
+ storage_used_ = new_storage_used;
+ memory_used_ += new_item_memory - old_item_memory;
+ if (!old_value) {
// We added a new key/value pair.
observers_.ForAllPtrs(
[&key, &value, &source](mojom::LevelDBObserver* observer) {
@@ -200,7 +313,7 @@ void LevelDBWrapperImpl::Put(
// We changed the value for an existing key.
observers_.ForAllPtrs(
[&key, &value, &source, &old_value](mojom::LevelDBObserver* observer) {
- observer->KeyChanged(key, value, old_value, source);
+ observer->KeyChanged(key, value, old_value.value(), source);
});
}
std::move(callback).Run(true);
@@ -211,26 +324,65 @@ void LevelDBWrapperImpl::Delete(
const base::Optional<std::vector<uint8_t>>& client_old_value,
const std::string& source,
DeleteCallback callback) {
- if (!map_) {
- LoadMap(base::Bind(&LevelDBWrapperImpl::Delete, base::Unretained(this), key,
- client_old_value, source, base::Passed(&callback)));
- return;
- }
-
- auto found = map_->find(key);
- if (found == map_->end()) {
- std::move(callback).Run(true);
+ // Map upgrade check is required because the cache state could be changed
+ // due to multiple bindings, and when multiple bindings are involved the
+ // |client_old_value| can race. Thus any changes require checking for an
+ // upgrade.
+ if (!IsMapLoaded() || IsMapUpgradeNeeded()) {
+ LoadMap(base::BindOnce(&LevelDBWrapperImpl::Delete, base::Unretained(this),
+ key, client_old_value, source, std::move(callback)));
return;
}
- if (database_) {
+ if (database_)
CreateCommitBatchIfNeeded();
- commit_batch_->changed_keys.insert(std::move(found->first));
+
+ std::vector<uint8_t> old_value;
+ if (map_state_ == MapState::LOADED_KEYS_ONLY) {
+ KeysOnlyMap::const_iterator found = keys_only_map_.find(key);
+ if (found == keys_only_map_.end()) {
+ std::move(callback).Run(true);
+ return;
+ }
+ if (client_old_value && client_old_value.value().size() == found->second) {
+ old_value = client_old_value.value();
+ } else {
+#if DCHECK_IS_ON()
+ // If |client_old_value| was not provided or if it's size does not match,
+ // then we still let the change go through. But the notification sent to
+ // clients will not contain old value. This is okay since currently the
+ // only observer to these notification is the client itself.
+ DVLOG(1) << "Wrapper with prefix "
+ << leveldb::Uint8VectorToStdString(prefix_)
+ << ": past value has length of " << found->second << ", but:";
+ if (client_old_value) {
+ DVLOG(1) << "Given past value has incorrect length of "
+ << client_old_value.value().size();
+ } else {
+ DVLOG(1) << "No given past value was provided.";
+ }
+#endif
+ }
+ storage_used_ -= key.size() + found->second;
+ keys_only_map_.erase(found);
+ memory_used_ -= key.size() + sizeof(size_t);
+ if (commit_batch_)
+ 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);
+ if (found == keys_values_map_.end()) {
+ std::move(callback).Run(true);
+ return;
+ }
+ old_value.swap(found->second);
+ keys_values_map_.erase(found);
+ memory_used_ -= key.size() + old_value.size();
+ storage_used_ -= key.size() + old_value.size();
+ if (commit_batch_)
+ commit_batch_->changed_keys.insert(key);
}
- std::vector<uint8_t> old_value(std::move(found->second));
- map_->erase(found);
- bytes_used_ -= key.size() + old_value.size();
observers_.ForAllPtrs(
[&key, &source, &old_value](mojom::LevelDBObserver* observer) {
observer->KeyDeleted(key, old_value, source);
@@ -240,13 +392,24 @@ void LevelDBWrapperImpl::Delete(
void LevelDBWrapperImpl::DeleteAll(const std::string& source,
DeleteAllCallback callback) {
- if (!map_) {
- LoadMap(base::Bind(&LevelDBWrapperImpl::DeleteAll, base::Unretained(this),
- source, base::Passed(&callback)));
+ // Don't check if a map upgrade is needed here and instead just create an
+ // empty map ourself.
+ if (!IsMapLoaded()) {
+ LoadMap(base::BindOnce(&LevelDBWrapperImpl::DeleteAll,
+ base::Unretained(this), source,
+ std::move(callback)));
return;
}
- if (map_->empty()) {
+ bool already_empty = IsMapLoadedAndEmpty();
+
+ // Upgrade map state if needed.
+ if (IsMapUpgradeNeeded()) {
+ DCHECK(keys_values_map_.empty());
+ map_state_ = MapState::LOADED_KEYS_AND_VALUES;
+ }
+
+ if (already_empty) {
std::move(callback).Run(true);
return;
}
@@ -254,11 +417,15 @@ void LevelDBWrapperImpl::DeleteAll(const std::string& source,
if (database_) {
CreateCommitBatchIfNeeded();
commit_batch_->clear_all_first = true;
+ commit_batch_->changed_values.clear();
commit_batch_->changed_keys.clear();
}
- map_->clear();
- bytes_used_ = 0;
+ keys_only_map_.clear();
+ keys_values_map_.clear();
+
+ storage_used_ = 0;
+ memory_used_ = 0;
observers_.ForAllPtrs(
[&source](mojom::LevelDBObserver* observer) {
observer->AllDeleted(source);
@@ -268,14 +435,20 @@ void LevelDBWrapperImpl::DeleteAll(const std::string& source,
void LevelDBWrapperImpl::Get(const std::vector<uint8_t>& key,
GetCallback callback) {
- if (!map_) {
- LoadMap(base::Bind(&LevelDBWrapperImpl::Get, base::Unretained(this), key,
- base::Passed(&callback)));
+ // TODO(ssid): Remove this method since it is not supported in only keys mode,
+ // crbug.com/764127.
+ if (cache_mode_ == CacheMode::KEYS_ONLY_WHEN_POSSIBLE) {
+ NOTREACHED();
+ return;
+ }
+ if (!IsMapLoaded() || IsMapUpgradeNeeded()) {
+ LoadMap(base::BindOnce(&LevelDBWrapperImpl::Get, base::Unretained(this),
+ key, std::move(callback)));
return;
}
- auto found = map_->find(key);
- if (found == map_->end()) {
+ auto found = keys_values_map_.find(key);
+ if (found == keys_values_map_.end()) {
std::move(callback).Run(false, std::vector<uint8_t>());
return;
}
@@ -285,21 +458,21 @@ void LevelDBWrapperImpl::Get(const std::vector<uint8_t>& key,
void LevelDBWrapperImpl::GetAll(
mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo complete_callback,
GetAllCallback callback) {
- if (!map_) {
- LoadMap(base::Bind(&LevelDBWrapperImpl::GetAll, base::Unretained(this),
- base::Passed(&complete_callback),
- base::Passed(&callback)));
+ // The map must always be loaded for the KEYS_ONLY_WHEN_POSSIBLE mode.
+ if (map_state_ != MapState::LOADED_KEYS_AND_VALUES) {
+ LoadMap(base::BindOnce(&LevelDBWrapperImpl::GetAll, base::Unretained(this),
+ std::move(complete_callback), std::move(callback)));
return;
}
std::vector<mojom::KeyValuePtr> all;
- for (const auto& it : (*map_)) {
+ for (const auto& it : keys_values_map_) {
mojom::KeyValuePtr kv = mojom::KeyValue::New();
kv->key = it.first;
kv->value = it.second;
all.push_back(std::move(kv));
}
- std::move(callback).Run(leveldb::mojom::DatabaseError::OK, std::move(all));
+ std::move(callback).Run(DatabaseError::OK, std::move(all));
if (complete_callback.is_valid()) {
mojom::LevelDBWrapperGetAllCallbackAssociatedPtr complete_ptr;
complete_ptr.Bind(std::move(complete_callback));
@@ -307,6 +480,24 @@ void LevelDBWrapperImpl::GetAll(
}
}
+void LevelDBWrapperImpl::SetCacheMode(CacheMode cache_mode) {
+ if (cache_mode_ == cache_mode ||
+ (!database_ && cache_mode == CacheMode::KEYS_ONLY_WHEN_POSSIBLE)) {
+ return;
+ }
+ cache_mode_ = cache_mode;
+ bool should_send_values = cache_mode == CacheMode::KEYS_ONLY_WHEN_POSSIBLE;
+ observers_.ForAllPtrs([should_send_values](mojom::LevelDBObserver* observer) {
+ observer->ShouldSendOldValueOnMutations(should_send_values);
+ });
+
+ // If the |keys_only_map_| is loaded and desired state needs values, no point
+ // keeping around the map since the next change would require reload. On the
+ // other hand if only keys are desired, the keys and values map can still be
+ // used. Consider not unloading when the map is still useful.
+ UnloadMapIfPossible();
+}
+
void LevelDBWrapperImpl::OnConnectionError() {
if (!bindings_.empty())
return;
@@ -317,14 +508,35 @@ void LevelDBWrapperImpl::OnConnectionError() {
delegate_->OnNoBindings();
}
-void LevelDBWrapperImpl::LoadMap(const base::Closure& completion_callback) {
- DCHECK(!map_);
- on_load_complete_tasks_.push_back(completion_callback);
- if (on_load_complete_tasks_.size() > 1)
+void LevelDBWrapperImpl::LoadMap(base::OnceClosure completion_callback) {
+ DCHECK_NE(map_state_, MapState::LOADED_KEYS_AND_VALUES);
+ DCHECK(keys_values_map_.empty());
+
+ // Current commit batch needs to be applied before re-loading the map. The
+ // re-load of map occurs only when GetAll() is called or CacheMode is set to
+ // keys and values, and the |keys_only_map_| is already loaded. In this case
+ // commit batch needs to be committed before reading the database.
+ if (map_state_ == MapState::LOADED_KEYS_ONLY) {
+ DCHECK(on_load_complete_tasks_.empty());
+ DCHECK(database_);
+ if (commit_batch_)
+ CommitChanges();
+ // Make sure the keys only map is not used when on load tasks are in queue.
+ // The changes to the wrapper will be queued to on load tasks.
+ keys_only_map_.clear();
+ map_state_ = MapState::UNLOADED;
+ }
+
+ on_load_complete_tasks_.push_back(std::move(completion_callback));
+ if (map_state_ == MapState::LOADING_FROM_DATABASE ||
+ map_state_ == MapState::LOADING_FROM_FORK) {
return;
+ }
+
+ map_state_ = MapState::LOADING_FROM_DATABASE;
if (!database_) {
- OnMapLoaded(leveldb::mojom::DatabaseError::IO_ERROR,
+ OnMapLoaded(DatabaseError::IO_ERROR,
std::vector<leveldb::mojom::KeyValuePtr>());
return;
}
@@ -335,69 +547,75 @@ void LevelDBWrapperImpl::LoadMap(const base::Closure& completion_callback) {
}
void LevelDBWrapperImpl::OnMapLoaded(
- leveldb::mojom::DatabaseError status,
+ DatabaseError status,
std::vector<leveldb::mojom::KeyValuePtr> data) {
- DCHECK(!map_);
+ DCHECK(keys_values_map_.empty());
+ DCHECK_EQ(map_state_, MapState::LOADING_FROM_DATABASE);
- if (data.empty() && status == leveldb::mojom::DatabaseError::OK) {
+ if (data.empty() && status == DatabaseError::OK) {
delegate_->MigrateData(
base::BindOnce(&LevelDBWrapperImpl::OnGotMigrationData,
weak_ptr_factory_.GetWeakPtr()));
return;
}
+ keys_only_map_.clear();
+ map_state_ = MapState::LOADED_KEYS_AND_VALUES;
- map_.reset(new ValueMap);
- bytes_used_ = 0;
+ keys_values_map_.clear();
for (auto& it : data) {
DCHECK_GE(it->key.size(), prefix_.size());
- (*map_)[std::vector<uint8_t>(it->key.begin() + prefix_.size(),
- it->key.end())] = it->value;
- bytes_used_ += it->key.size() - prefix_.size() + it->value.size();
+ keys_values_map_[std::vector<uint8_t>(it->key.begin() + prefix_.size(),
+ it->key.end())] =
+ std::move(it->value);
}
+ CalculateStorageAndMemoryUsed();
- std::vector<Change> changes = delegate_->FixUpData(*map_);
+ std::vector<Change> changes = delegate_->FixUpData(keys_values_map_);
if (!changes.empty()) {
DCHECK(database_);
CreateCommitBatchIfNeeded();
for (auto& change : changes) {
- auto it = map_->find(change.first);
+ auto it = keys_values_map_.find(change.first);
if (!change.second) {
- DCHECK(it != map_->end());
- bytes_used_ -= it->first.size() + it->second.size();
- map_->erase(it);
+ DCHECK(it != keys_values_map_.end());
+ keys_values_map_.erase(it);
} else {
- if (it != map_->end()) {
- bytes_used_ -= it->second.size();
+ if (it != keys_values_map_.end()) {
it->second = std::move(*change.second);
- bytes_used_ += it->second.size();
} else {
- bytes_used_ += change.first.size() + change.second->size();
- (*map_)[change.first] = std::move(*change.second);
+ keys_values_map_[change.first] = std::move(*change.second);
}
}
+ // No need to store values in |commit_batch_| if values are already
+ // available in |keys_values_map_|, since CommitChanges() will take values
+ // from there.
commit_batch_->changed_keys.insert(std::move(change.first));
}
+ CalculateStorageAndMemoryUsed();
CommitChanges();
}
// We proceed without using a backing store, nothing will be persisted but the
// class is functional for the lifetime of the object.
delegate_->OnMapLoaded(status);
- if (status != leveldb::mojom::DatabaseError::OK)
+ if (status != DatabaseError::OK) {
database_ = nullptr;
+ SetCacheMode(CacheMode::KEYS_AND_VALUES);
+ }
OnLoadComplete();
}
void LevelDBWrapperImpl::OnGotMigrationData(std::unique_ptr<ValueMap> data) {
- map_ = data ? std::move(data) : base::MakeUnique<ValueMap>();
- bytes_used_ = 0;
- for (const auto& it : *map_)
- bytes_used_ += it.first.size() + it.second.size();
+ keys_only_map_.clear();
+ keys_values_map_ = data ? std::move(*data) : ValueMap();
+ map_state_ = MapState::LOADED_KEYS_AND_VALUES;
+ CalculateStorageAndMemoryUsed();
if (database_ && !empty()) {
CreateCommitBatchIfNeeded();
- for (const auto& it : *map_)
+ // CommitChanges() will take values from |keys_values_map_|.
+ for (const auto& it : keys_values_map_)
commit_batch_->changed_keys.insert(it.first);
CommitChanges();
}
@@ -405,11 +623,42 @@ void LevelDBWrapperImpl::OnGotMigrationData(std::unique_ptr<ValueMap> data) {
OnLoadComplete();
}
+void LevelDBWrapperImpl::CalculateStorageAndMemoryUsed() {
+ memory_used_ = 0;
+ storage_used_ = 0;
+
+ for (auto& it : keys_values_map_)
+ memory_used_ += it.first.size() + it.second.size();
+ storage_used_ = memory_used_;
+
+ for (auto& it : keys_only_map_) {
+ memory_used_ += it.first.size() + sizeof(size_t);
+ storage_used_ += it.first.size() + it.second;
+ }
+}
+
void LevelDBWrapperImpl::OnLoadComplete() {
- std::vector<base::Closure> tasks;
+ DCHECK(IsMapLoaded());
+
+ std::vector<base::OnceClosure> tasks;
on_load_complete_tasks_.swap(tasks);
- for (auto& task : tasks)
- task.Run();
+ for (auto it = tasks.begin(); it != tasks.end(); ++it) {
+ // Some tasks (like GetAll) can require a reload if they need a different
+ // map type. If this happens, stop our task execution. Appending tasks is
+ // required (instead of replacing) because the task that required the
+ // reload-requesting-task put itself on the task queue and it still needs
+ // to be executed before the rest of the tasks.
+ if (!IsMapLoaded()) {
+ on_load_complete_tasks_.reserve(on_load_complete_tasks_.size() +
+ (tasks.end() - it));
+ std::move(it, tasks.end(), std::back_inserter(on_load_complete_tasks_));
+ return;
+ }
+ std::move(*it).Run();
+ }
+
+ // Call before |OnNoBindings| as delegate can destroy this object.
+ UnloadMapIfPossible();
// We might need to call the no_bindings_callback_ here if bindings became
// empty while waiting for load to complete.
@@ -420,6 +669,7 @@ void LevelDBWrapperImpl::OnLoadComplete() {
void LevelDBWrapperImpl::CreateCommitBatchIfNeeded() {
if (commit_batch_)
return;
+ DCHECK(database_);
commit_batch_.reset(new CommitBatch());
BrowserThread::PostAfterStartupTask(
@@ -465,36 +715,73 @@ void LevelDBWrapperImpl::CommitChanges() {
return;
DCHECK(database_);
- DCHECK(map_);
+ DCHECK(IsMapLoaded()) << static_cast<int>(map_state_);
commit_rate_limiter_.add_samples(1);
// Commit all our changes in a single batch.
- std::vector<leveldb::mojom::BatchedOperationPtr> operations =
- delegate_->PrepareToCommit();
+ std::vector<BatchedOperationPtr> operations = delegate_->PrepareToCommit();
+ bool has_changes = !operations.empty() ||
+ !commit_batch_->changed_values.empty() ||
+ !commit_batch_->changed_keys.empty();
+
if (commit_batch_->clear_all_first) {
- leveldb::mojom::BatchedOperationPtr item =
- leveldb::mojom::BatchedOperation::New();
+ BatchedOperationPtr item = BatchedOperation::New();
item->type = leveldb::mojom::BatchOperationType::DELETE_PREFIXED_KEY;
item->key = prefix_;
operations.push_back(std::move(item));
}
size_t data_size = 0;
- for (const auto& key : commit_batch_->changed_keys) {
- data_size += key.size();
- leveldb::mojom::BatchedOperationPtr item =
- leveldb::mojom::BatchedOperation::New();
- item->key.reserve(prefix_.size() + key.size());
- item->key.insert(item->key.end(), prefix_.begin(), prefix_.end());
- item->key.insert(item->key.end(), key.begin(), key.end());
- auto it = map_->find(key);
- if (it == map_->end()) {
- item->type = leveldb::mojom::BatchOperationType::DELETE_KEY;
- } else {
- item->type = leveldb::mojom::BatchOperationType::PUT_KEY;
- item->value = it->second;
- data_size += it->second.size();
+ if (map_state_ == MapState::LOADED_KEYS_AND_VALUES) {
+ DCHECK(commit_batch_->changed_values.empty())
+ << "Map state and commit state out of sync.";
+ for (const auto& key : commit_batch_->changed_keys) {
+ data_size += key.size();
+ BatchedOperationPtr item = BatchedOperation::New();
+ item->key.reserve(prefix_.size() + key.size());
+ item->key.insert(item->key.end(), prefix_.begin(), prefix_.end());
+ item->key.insert(item->key.end(), key.begin(), key.end());
+ auto kv_it = keys_values_map_.find(key);
+ if (kv_it != keys_values_map_.end()) {
+ item->type = leveldb::mojom::BatchOperationType::PUT_KEY;
+ data_size += kv_it->second.size();
+ item->value = kv_it->second;
+ } else {
+ item->type = leveldb::mojom::BatchOperationType::DELETE_KEY;
+ }
+ operations.push_back(std::move(item));
+ }
+ } else {
+ DCHECK(commit_batch_->changed_keys.empty())
+ << "Map state and commit state out of sync.";
+ DCHECK_EQ(map_state_, MapState::LOADED_KEYS_ONLY);
+ for (auto& it : commit_batch_->changed_values) {
+ const auto& key = it.first;
+ data_size += key.size();
+ BatchedOperationPtr item = BatchedOperation::New();
+ item->key.reserve(prefix_.size() + key.size());
+ item->key.insert(item->key.end(), prefix_.begin(), prefix_.end());
+ item->key.insert(item->key.end(), key.begin(), key.end());
+ auto kv_it = keys_only_map_.find(key);
+ if (kv_it != keys_only_map_.end()) {
+ item->type = leveldb::mojom::BatchOperationType::PUT_KEY;
+ data_size += it.second.size();
+ item->value = std::move(it.second);
+ } else {
+ item->type = leveldb::mojom::BatchOperationType::DELETE_KEY;
+ }
+ operations.push_back(std::move(item));
}
+ }
+ // Schedule the copy, and ignore if |clear_all_first| is specified and there
+ // are no changing keys.
+ if (commit_batch_->copy_to_prefix) {
+ DCHECK(!has_changes);
+ DCHECK(!commit_batch_->clear_all_first);
+ BatchedOperationPtr item = BatchedOperation::New();
+ item->type = leveldb::mojom::BatchOperationType::COPY_PREFIXED_KEY;
+ item->key = prefix_;
+ item->value = std::move(commit_batch_->copy_to_prefix.value());
operations.push_back(std::move(item));
}
commit_batch_.reset();
@@ -503,17 +790,102 @@ void LevelDBWrapperImpl::CommitChanges() {
++commit_batches_in_flight_;
- // TODO(michaeln): Currently there is no guarantee LevelDBDatabaseImp::Write
+ // TODO(michaeln): Currently there is no guarantee LevelDBDatabaseImpl::Write
// will run during a clean shutdown. We need that to avoid dataloss.
database_->Write(std::move(operations),
base::BindOnce(&LevelDBWrapperImpl::OnCommitComplete,
weak_ptr_factory_.GetWeakPtr()));
}
-void LevelDBWrapperImpl::OnCommitComplete(leveldb::mojom::DatabaseError error) {
+void LevelDBWrapperImpl::OnCommitComplete(DatabaseError error) {
--commit_batches_in_flight_;
StartCommitTimer();
+
+ if (error != DatabaseError::OK)
+ SetCacheMode(CacheMode::KEYS_AND_VALUES);
+
+ // Call before |DidCommit| as delegate can destroy this object.
+ UnloadMapIfPossible();
+
delegate_->DidCommit(error);
}
+void LevelDBWrapperImpl::UnloadMapIfPossible() {
+ // Do not unload the map if:
+ // * The desired cache mode isn't key-only,
+ // * The map isn't a loaded key-value map,
+ // * There are pending tasks waiting on the key-value map being loaded, or
+ // * There is no database connection.
+ // * We have commit batches in-flight.
+ if (cache_mode_ != CacheMode::KEYS_ONLY_WHEN_POSSIBLE ||
+ map_state_ != MapState::LOADED_KEYS_AND_VALUES ||
+ has_pending_load_tasks() || !database_ || commit_batches_in_flight_ > 0) {
+ return;
+ }
+
+ keys_only_map_.clear();
+ memory_used_ = 0;
+ for (auto& it : keys_values_map_) {
+ keys_only_map_.insert(std::make_pair(it.first, it.second.size()));
+ }
+ if (commit_batch_) {
+ for (const auto& key : commit_batch_->changed_keys) {
+ auto value_it = keys_values_map_.find(key);
+ commit_batch_->changed_values[key] = value_it == keys_values_map_.end()
+ ? std::vector<uint8_t>()
+ : std::move(value_it->second);
+ }
+ commit_batch_->changed_keys.clear();
+ }
+
+ keys_values_map_.clear();
+ map_state_ = MapState::LOADED_KEYS_ONLY;
+
+ CalculateStorageAndMemoryUsed();
+}
+
+void LevelDBWrapperImpl::DoForkOperation(
+ const base::WeakPtr<LevelDBWrapperImpl>& forked_wrapper) {
+ if (!forked_wrapper)
+ return;
+
+ DCHECK(IsMapLoaded());
+ // TODO(dmurph): If these commits fails, then the disk could be in an
+ // inconsistant state. Ideally all further operations will fail and the code
+ // will correctly delete the database?
+ if (database_) {
+ // All changes must be stored in the database before the copy operation.
+ if (has_changes_to_commit())
+ CommitChanges();
+ CreateCommitBatchIfNeeded();
+ commit_batch_->copy_to_prefix = forked_wrapper->prefix_;
+ CommitChanges();
+ }
+
+ forked_wrapper->OnForkStateLoaded(database_ != nullptr, keys_values_map_,
+ keys_only_map_);
+}
+
+void LevelDBWrapperImpl::OnForkStateLoaded(bool database_enabled,
+ const ValueMap& value_map,
+ const KeysOnlyMap& keys_only_map) {
+ // This callback can get either the value map or the key only map depending
+ // on parent operations and other things. So handle both.
+ if (!value_map.empty() || keys_only_map.empty()) {
+ keys_values_map_ = value_map;
+ map_state_ = MapState::LOADED_KEYS_AND_VALUES;
+ } else {
+ keys_only_map_ = keys_only_map;
+ map_state_ = MapState::LOADED_KEYS_ONLY;
+ }
+
+ if (!database_enabled) {
+ database_ = nullptr;
+ cache_mode_ = CacheMode::KEYS_AND_VALUES;
+ }
+
+ CalculateStorageAndMemoryUsed();
+ OnLoadComplete();
+}
+
} // namespace content
diff --git a/chromium/content/browser/leveldb_wrapper_impl.h b/chromium/content/browser/leveldb_wrapper_impl.h
index 876efd24e6f..bf6855d2d04 100644
--- a/chromium/content/browser/leveldb_wrapper_impl.h
+++ b/chromium/content/browser/leveldb_wrapper_impl.h
@@ -11,9 +11,11 @@
#include <vector>
#include "base/callback.h"
+#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/time/time.h"
+#include "content/common/content_export.h"
#include "content/common/leveldb_wrapper.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h"
@@ -36,15 +38,19 @@ namespace content {
// 2) Enforces a max_size constraint.
// 3) Informs observers when values scoped by prefix are modified.
// 4) Throttles requests to avoid overwhelming the disk.
+//
+// The wrapper supports two different caching modes.
class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
public:
using ValueMap = std::map<std::vector<uint8_t>, std::vector<uint8_t>>;
using ValueMapCallback = base::OnceCallback<void(std::unique_ptr<ValueMap>)>;
using Change =
std::pair<std::vector<uint8_t>, base::Optional<std::vector<uint8_t>>>;
+ using KeysOnlyMap = std::map<std::vector<uint8_t>, size_t>;
class CONTENT_EXPORT Delegate {
public:
+ virtual ~Delegate();
virtual void OnNoBindings() = 0;
virtual std::vector<leveldb::mojom::BatchedOperationPtr>
PrepareToCommit() = 0;
@@ -57,26 +63,75 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
virtual void OnMapLoaded(leveldb::mojom::DatabaseError error);
};
+ enum class CacheMode {
+ // The cache stores only keys (required to maintain max size constraints)
+ // when there is only one client binding to save memory. The client is
+ // asked to send old values on mutations for sending notifications to
+ // observers.
+ KEYS_ONLY_WHEN_POSSIBLE,
+ // The cache always stores keys and values.
+ KEYS_AND_VALUES
+ };
+
+ // Options provided to constructor.
+ struct Options {
+ CacheMode cache_mode = CacheMode::KEYS_AND_VALUES;
+
+ // Max bytes of storage that can be used by key value pairs.
+ size_t max_size = 0;
+ // Minimum time between 2 commits to disk.
+ base::TimeDelta default_commit_delay;
+ // Maximum number of bytes written to disk in one hour.
+ int max_bytes_per_hour = 0;
+ // Maximum number of disk write batches in one hour.
+ int max_commits_per_hour = 0;
+ };
+
// |no_bindings_callback| will be called when this object has no more
// bindings and all pending modifications have been processed.
LevelDBWrapperImpl(leveldb::mojom::LevelDBDatabase* database,
const std::string& prefix,
- size_t max_size,
- base::TimeDelta default_commit_delay,
- int max_bytes_per_hour,
- int max_commits_per_hour,
- Delegate* delegate);
+ Delegate* delegate,
+ const Options& options);
~LevelDBWrapperImpl() override;
void Bind(mojom::LevelDBWrapperRequest request);
- bool empty() const { return bytes_used_ == 0; }
- size_t bytes_used() const { return bytes_used_; }
+ // Forks, or copies, all data in this prefix to another prefix.
+ // Note: this object (the parent) must stay alive until the forked wrapper
+ // has been loaded (see initialized()).
+ std::unique_ptr<LevelDBWrapperImpl> ForkToNewPrefix(
+ const std::string& new_prefix,
+ Delegate* delegate,
+ const Options& options);
+
+ // Cancels all pending load tasks. Useful for emergency destructions. If the
+ // wrapper is unloaded (initialized() returns false), this will DROP all
+ // pending changes to the database, and any uninitialized wrappers created
+ // through |ForkToNewPrefix| will stay BROKEN and unresponsive.
+ void CancelAllPendingRequests();
+
+ // The total bytes used by items which counts towards the quota.
+ size_t storage_used() const { return storage_used_; }
+ // The physical memory used by the cache.
+ size_t memory_used() const { return memory_used_; }
+
+ bool empty() const { return storage_used_ == 0; }
+
+ // If this wrapper is loaded and sending changes to the database.
+ bool initialized() const { return IsMapLoaded(); }
+ CacheMode cache_mode() const { return cache_mode_; }
+
+ // Tasks that are waiting for the map to be loaded.
bool has_pending_load_tasks() const {
return !on_load_complete_tasks_.empty();
}
+ bool has_changes_to_commit() const { return commit_batch_.get(); }
+
+ const std::vector<uint8_t>& prefix() { return prefix_; }
+
// Commence aggressive flushing. This should be called early during startup,
// before any localStorage writing. Currently scheduled writes will not be
// rescheduled and will be flushed at the scheduled time after which
@@ -97,6 +152,10 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
void OnMemoryDump(const std::string& name,
base::trace_event::ProcessMemoryDump* pmd);
+ // Sets cache mode to either store only keys or keys and values. See
+ // SetCacheMode().
+ void SetCacheModeForTesting(CacheMode cache_mode);
+
// LevelDBWrapper:
void AddObserver(mojom::LevelDBObserverAssociatedPtrInfo observer) override;
void Put(const std::vector<uint8_t>& key,
@@ -116,6 +175,13 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
GetAllCallback callback) override;
private:
+ FRIEND_TEST_ALL_PREFIXES(LevelDBWrapperImplTest, GetAllAfterSetCacheMode);
+ FRIEND_TEST_ALL_PREFIXES(LevelDBWrapperImplTest,
+ PutLoadsValuesAfterCacheModeUpgrade);
+ FRIEND_TEST_ALL_PREFIXES(LevelDBWrapperImplTest, SetCacheModeConsistent);
+ FRIEND_TEST_ALL_PREFIXES(LevelDBWrapperImplParamTest,
+ CommitOnDifferentCacheModes);
+
// Used to rate limit commits.
class RateLimiter {
public:
@@ -133,47 +199,122 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
base::TimeDelta ComputeDelayNeeded(
const base::TimeDelta elapsed_time) const;
+ float rate() const { return rate_; }
+
private:
float rate_;
float samples_;
base::TimeDelta time_quantum_;
};
+ // There can be only one fork operation per commit batch.
struct CommitBatch {
bool clear_all_first;
+ // Prefix copying is performed before applying changes.
+ base::Optional<std::vector<uint8_t>> copy_to_prefix;
+ // Used if the map_type_ is LOADED_KEYS_ONLY.
+ std::map<std::vector<uint8_t>, std::vector<uint8_t>> changed_values;
+ // Used if the map_type_ is LOADED_KEYS_AND_VALUES.
std::set<std::vector<uint8_t>> changed_keys;
CommitBatch();
~CommitBatch();
};
+ enum class MapState {
+ UNLOADED,
+ // Loading from the database connection.
+ LOADING_FROM_DATABASE,
+ // Loading from another LevelDBWrapperImpl that we have forked from.
+ LOADING_FROM_FORK,
+ LOADED_KEYS_ONLY,
+ LOADED_KEYS_AND_VALUES
+ };
+
+ using LoadStateForForkCallback = base::OnceCallback<
+ void(bool database_enabled, const ValueMap&, const KeysOnlyMap&)>;
+ using ForkSourceEarlyDeathCallback =
+ base::OnceCallback<void(std::vector<uint8_t> source_prefix)>;
+
+ // Changes the cache mode of the wrapper. If applicable, this will change the
+ // internal storage type after the next commit. The keys-only mode can only
+ // be set only when there is one client binding. It automatically changes to
+ // keys-and-values mode when more than one binding exists.
+ // Notifications to observers when an item is mutated depends on the
+ // |client_old_value| when in keys-only mode. Using GetAll during
+ // keys-only mode will cause extra disk access.
+ void SetCacheMode(CacheMode cache_mode);
+
void OnConnectionError();
- void LoadMap(const base::Closure& completion_callback);
+
+ // Always loads the |keys_values_map_|, sets the |map_state_| to
+ // LOADED_KEYS_AND_VALUES, and calls through all the completion callbacks.
+ //
+ // Then if the |cache_mode_| is keys-only, it unloads the map to the
+ // |keys_only_map_| and sets the |map_state_| to LOADED_KEYS_ONLY
+ void LoadMap(base::OnceClosure completion_callback);
void OnMapLoaded(leveldb::mojom::DatabaseError status,
std::vector<leveldb::mojom::KeyValuePtr> data);
void OnGotMigrationData(std::unique_ptr<ValueMap> data);
+ void CalculateStorageAndMemoryUsed();
void OnLoadComplete();
+
void CreateCommitBatchIfNeeded();
void StartCommitTimer();
base::TimeDelta ComputeCommitDelay() const;
+
void CommitChanges();
void OnCommitComplete(leveldb::mojom::DatabaseError error);
+ void UnloadMapIfPossible();
+
+ bool IsMapUpgradeNeeded() const {
+ return map_state_ == MapState::LOADED_KEYS_ONLY &&
+ cache_mode_ == CacheMode::KEYS_AND_VALUES;
+ }
+
+ bool IsMapLoaded() const {
+ return map_state_ == MapState::LOADED_KEYS_ONLY ||
+ map_state_ == MapState::LOADED_KEYS_AND_VALUES;
+ }
+
+ bool IsMapLoadedAndEmpty() const {
+ return (map_state_ == MapState::LOADED_KEYS_ONLY &&
+ keys_only_map_.empty()) ||
+ (map_state_ == MapState::LOADED_KEYS_AND_VALUES &&
+ keys_values_map_.empty());
+ }
+
+ void DoForkOperation(const base::WeakPtr<LevelDBWrapperImpl>& forked_wrapper);
+ void OnForkStateLoaded(bool database_enabled,
+ const ValueMap& map,
+ const KeysOnlyMap& key_only_map);
+
std::vector<uint8_t> prefix_;
mojo::BindingSet<mojom::LevelDBWrapper> bindings_;
mojo::AssociatedInterfacePtrSet<mojom::LevelDBObserver> observers_;
Delegate* delegate_;
leveldb::mojom::LevelDBDatabase* database_;
- std::unique_ptr<ValueMap> map_;
- std::vector<base::Closure> on_load_complete_tasks_;
- size_t bytes_used_;
+
+ // For commits to work correctly the map loaded state (keys vs keys & values)
+ // must stay consistent for a given commit batch.
+ MapState map_state_ = MapState::UNLOADED;
+ CacheMode cache_mode_;
+ ValueMap keys_values_map_;
+ KeysOnlyMap keys_only_map_;
+ // These are always consumed & cleared when the map is loaded.
+ std::vector<base::OnceClosure> on_load_complete_tasks_;
+
+ size_t storage_used_;
size_t max_size_;
+ size_t memory_used_;
base::TimeTicks start_time_;
base::TimeDelta default_commit_delay_;
RateLimiter data_rate_limiter_;
RateLimiter commit_rate_limiter_;
int commit_batches_in_flight_ = 0;
std::unique_ptr<CommitBatch> commit_batch_;
+
base::WeakPtrFactory<LevelDBWrapperImpl> weak_ptr_factory_;
static bool s_aggressive_flushing_enabled_;
diff --git a/chromium/content/browser/leveldb_wrapper_impl_unittest.cc b/chromium/content/browser/leveldb_wrapper_impl_unittest.cc
index e76436d6a5e..ac7b59e5dea 100644
--- a/chromium/content/browser/leveldb_wrapper_impl_unittest.cc
+++ b/chromium/content/browser/leveldb_wrapper_impl_unittest.cc
@@ -4,64 +4,134 @@
#include "content/browser/leveldb_wrapper_impl.h"
+#include "base/atomic_ref_count.h"
+#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/task_runner_util.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/threading/thread.h"
#include "components/leveldb/public/cpp/util.h"
+#include "components/leveldb/public/interfaces/leveldb.mojom.h"
#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/test/mock_leveldb_database.h"
+#include "content/test/fake_leveldb_database.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-using leveldb::StdStringToUint8Vector;
-using leveldb::Uint8VectorToStdString;
-
namespace content {
namespace {
+using CacheMode = LevelDBWrapperImpl::CacheMode;
+using DatabaseError = leveldb::mojom::DatabaseError;
-const char* kTestPrefix = "abc";
const char* kTestSource = "source";
const size_t kTestSizeLimit = 512;
+std::string ToString(const std::vector<uint8_t>& input) {
+ return leveldb::Uint8VectorToStdString(input);
+}
+
+std::vector<uint8_t> ToBytes(const std::string& input) {
+ return leveldb::StdStringToUint8Vector(input);
+}
+
+class InternalIncrementalBarrier {
+ public:
+ InternalIncrementalBarrier(base::OnceClosure done_closure)
+ : num_callbacks_left_(1), done_closure_(std::move(done_closure)) {}
+
+ void Dec() {
+ // This is the same as in BarrierClosure.
+ DCHECK(!num_callbacks_left_.IsZero());
+ if (!num_callbacks_left_.Decrement()) {
+ base::OnceClosure done = std::move(done_closure_);
+ delete this;
+ std::move(done).Run();
+ }
+ }
+
+ base::OnceClosure Inc() {
+ num_callbacks_left_.Increment();
+ return base::BindOnce(&InternalIncrementalBarrier::Dec,
+ base::Unretained(this));
+ }
+
+ private:
+ base::AtomicRefCount num_callbacks_left_;
+ base::OnceClosure done_closure_;
+
+ DISALLOW_COPY_AND_ASSIGN(InternalIncrementalBarrier);
+};
+
+// The callbacks returned by Get might get called after destruction of this
+// class (and thus the done_closure), so there needs to be an internal class
+// to hold the final callback & manage the refcount.
+class IncrementalBarrier {
+ public:
+ explicit IncrementalBarrier(base::OnceClosure done_closure)
+ : internal_barrier_(
+ new InternalIncrementalBarrier(std::move(done_closure))) {}
+
+ ~IncrementalBarrier() { internal_barrier_->Dec(); }
+
+ base::OnceClosure Get() { return internal_barrier_->Inc(); }
+
+ private:
+ InternalIncrementalBarrier* internal_barrier_; // self-deleting
+
+ DISALLOW_COPY_AND_ASSIGN(IncrementalBarrier);
+};
+
class GetAllCallback : public mojom::LevelDBWrapperGetAllCallback {
public:
static mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo CreateAndBind(
bool* result,
- const base::Closure& callback) {
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo ptr_info;
- auto request = mojo::MakeRequest(&ptr_info);
+ base::OnceClosure callback) {
+ mojom::LevelDBWrapperGetAllCallbackAssociatedPtr ptr;
+ auto request = mojo::MakeRequestAssociatedWithDedicatedPipe(&ptr);
mojo::MakeStrongAssociatedBinding(
- base::WrapUnique(new GetAllCallback(result, callback)),
+ base::WrapUnique(new GetAllCallback(result, std::move(callback))),
std::move(request));
- return ptr_info;
+ return ptr.PassInterface();
}
private:
- GetAllCallback(bool* result, const base::Closure& callback)
- : m_result(result), m_callback(callback) {}
+ GetAllCallback(bool* result, base::OnceClosure callback)
+ : result_(result), callback_(std::move(callback)) {}
void Complete(bool success) override {
- *m_result = success;
- m_callback.Run();
+ *result_ = success;
+ if (callback_)
+ std::move(callback_).Run();
}
- bool* m_result;
- base::Closure m_callback;
+ bool* result_;
+ base::OnceClosure callback_;
};
class MockDelegate : public LevelDBWrapperImpl::Delegate {
public:
+ MockDelegate() {}
+ ~MockDelegate() override {}
+
void OnNoBindings() override {}
std::vector<leveldb::mojom::BatchedOperationPtr> PrepareToCommit() override {
return std::vector<leveldb::mojom::BatchedOperationPtr>();
}
- void DidCommit(leveldb::mojom::DatabaseError error) override {}
- void OnMapLoaded(leveldb::mojom::DatabaseError error) override {
- map_load_count_++;
+ void DidCommit(DatabaseError error) override {
+ if (error != DatabaseError::OK)
+ LOG(ERROR) << "error committing!";
+ if (committed_)
+ std::move(committed_).Run();
}
+ void OnMapLoaded(DatabaseError error) override { map_load_count_++; }
std::vector<LevelDBWrapperImpl::Change> FixUpData(
const LevelDBWrapperImpl::ValueMap& data) override {
- return mock_changes_;
+ return std::move(mock_changes_);
}
int map_load_count() const { return map_load_count_; }
@@ -69,65 +139,110 @@ class MockDelegate : public LevelDBWrapperImpl::Delegate {
mock_changes_ = std::move(changes);
}
+ void SetDidCommitCallback(base::OnceClosure committed) {
+ committed_ = std::move(committed);
+ }
+
private:
int map_load_count_ = 0;
std::vector<LevelDBWrapperImpl::Change> mock_changes_;
+ base::OnceClosure committed_;
};
-void GetCallback(const base::Closure& callback,
+void GetCallback(base::OnceClosure callback,
bool* success_out,
std::vector<uint8_t>* value_out,
bool success,
const std::vector<uint8_t>& value) {
*success_out = success;
*value_out = value;
- callback.Run();
+ std::move(callback).Run();
+}
+
+base::OnceCallback<void(bool, const std::vector<uint8_t>&)> MakeGetCallback(
+ base::OnceClosure callback,
+ bool* success_out,
+ std::vector<uint8_t>* value_out) {
+ return base::BindOnce(&GetCallback, std::move(callback), success_out,
+ value_out);
+}
+
+void GetAllDataCallback(leveldb::mojom::DatabaseError* status_out,
+ std::vector<mojom::KeyValuePtr>* data_out,
+ leveldb::mojom::DatabaseError status,
+ std::vector<mojom::KeyValuePtr> data) {
+ *status_out = status;
+ *data_out = std::move(data);
+}
+
+base::OnceCallback<void(leveldb::mojom::DatabaseError status,
+ std::vector<mojom::KeyValuePtr> data)>
+MakeGetAllCallback(leveldb::mojom::DatabaseError* status_out,
+ std::vector<mojom::KeyValuePtr>* data_out) {
+ return base::BindOnce(&GetAllDataCallback, status_out, data_out);
}
-void SuccessCallback(const base::Closure& callback,
+void SuccessCallback(base::OnceClosure callback,
bool* success_out,
bool success) {
*success_out = success;
- callback.Run();
+ std::move(callback).Run();
+}
+
+base::OnceCallback<void(bool)> MakeSuccessCallback(base::OnceClosure callback,
+ bool* success_out) {
+ return base::BindOnce(&SuccessCallback, std::move(callback), success_out);
}
void NoOpSuccessCallback(bool success) {}
+LevelDBWrapperImpl::Options GetDefaultTestingOptions(CacheMode cache_mode) {
+ LevelDBWrapperImpl::Options options;
+ options.max_size = kTestSizeLimit;
+ options.default_commit_delay = base::TimeDelta::FromSeconds(5);
+ options.max_bytes_per_hour = 10 * 1024 * 1024;
+ options.max_commits_per_hour = 60;
+ options.cache_mode = cache_mode;
+ return options;
+}
+
} // namespace
class LevelDBWrapperImplTest : public testing::Test,
public mojom::LevelDBObserver {
public:
struct Observation {
- enum { kAdd, kChange, kDelete, kDeleteAll } type;
+ enum { kAdd, kChange, kDelete, kDeleteAll, kSendOldValue } type;
std::string key;
std::string old_value;
std::string new_value;
std::string source;
+ bool should_send_old_value;
};
- LevelDBWrapperImplTest()
- : db_(&mock_data_),
- level_db_wrapper_(&db_,
- kTestPrefix,
- kTestSizeLimit,
- base::TimeDelta::FromSeconds(5),
- 10 * 1024 * 1024 /* max_bytes_per_hour */,
- 60 /* max_commits_per_hour */,
- &delegate_),
- observer_binding_(this) {
- set_mock_data(std::string(kTestPrefix) + "def", "defdata");
- set_mock_data(std::string(kTestPrefix) + "123", "123data");
+ LevelDBWrapperImplTest() : db_(&mock_data_), observer_binding_(this) {
+ auto request = mojo::MakeRequest(&level_db_database_ptr_);
+ db_.Bind(std::move(request));
+
+ LevelDBWrapperImpl::Options options =
+ GetDefaultTestingOptions(CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
+ level_db_wrapper_ = std::make_unique<LevelDBWrapperImpl>(
+ level_db_database_ptr_.get(), test_prefix_, &delegate_, options);
+
+ set_mock_data(test_prefix_ + test_key1_, test_value1_);
+ set_mock_data(test_prefix_ + test_key2_, test_value2_);
set_mock_data("123", "baddata");
- level_db_wrapper_.Bind(mojo::MakeRequest(&level_db_wrapper_ptr_));
+ level_db_wrapper_->Bind(mojo::MakeRequest(&level_db_wrapper_ptr_));
mojom::LevelDBObserverAssociatedPtrInfo ptr_info;
observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
level_db_wrapper_ptr_->AddObserver(std::move(ptr_info));
}
+ ~LevelDBWrapperImplTest() override {}
+
void set_mock_data(const std::string& key, const std::string& value) {
- mock_data_[StdStringToUint8Vector(key)] = StdStringToUint8Vector(value);
+ mock_data_[ToBytes(key)] = ToBytes(value);
}
void set_mock_data(const std::vector<uint8_t>& key,
@@ -136,129 +251,239 @@ class LevelDBWrapperImplTest : public testing::Test,
}
bool has_mock_data(const std::string& key) {
- return mock_data_.find(StdStringToUint8Vector(key)) != mock_data_.end();
+ return mock_data_.find(ToBytes(key)) != mock_data_.end();
}
std::string get_mock_data(const std::string& key) {
- return has_mock_data(key)
- ? Uint8VectorToStdString(mock_data_[StdStringToUint8Vector(key)])
- : "";
+ return has_mock_data(key) ? ToString(mock_data_[ToBytes(key)]) : "";
}
void clear_mock_data() { mock_data_.clear(); }
mojom::LevelDBWrapper* wrapper() { return level_db_wrapper_ptr_.get(); }
- LevelDBWrapperImpl* wrapper_impl() { return &level_db_wrapper_; }
+ LevelDBWrapperImpl* wrapper_impl() { return level_db_wrapper_.get(); }
- bool GetSync(const std::vector<uint8_t>& key, std::vector<uint8_t>* result) {
- base::RunLoop run_loop;
+ bool GetSync(mojom::LevelDBWrapper* wrapper,
+ const std::vector<uint8_t>& key,
+ std::vector<uint8_t>* result) {
bool success = false;
- wrapper()->Get(key, base::BindOnce(&GetCallback, run_loop.QuitClosure(),
- &success, result));
- run_loop.Run();
+ base::RunLoop loop;
+ wrapper->Get(key, MakeGetCallback(loop.QuitClosure(), &success, result));
+ loop.Run();
return success;
}
- bool PutSync(const std::vector<uint8_t>& key,
+ bool PutSync(mojom::LevelDBWrapper* wrapper,
+ const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value,
const base::Optional<std::vector<uint8_t>>& client_old_value,
std::string source = kTestSource) {
- base::RunLoop run_loop;
bool success = false;
- wrapper()->Put(
- key, value, client_old_value, source,
- base::BindOnce(&SuccessCallback, run_loop.QuitClosure(), &success));
- run_loop.Run();
+ base::RunLoop loop;
+ wrapper->Put(key, value, client_old_value, source,
+ MakeSuccessCallback(loop.QuitClosure(), &success));
+ loop.Run();
return success;
}
bool DeleteSync(
+ mojom::LevelDBWrapper* wrapper,
const std::vector<uint8_t>& key,
const base::Optional<std::vector<uint8_t>>& client_old_value) {
- base::RunLoop run_loop;
bool success = false;
- wrapper()->Delete(
- key, client_old_value, kTestSource,
- base::BindOnce(&SuccessCallback, run_loop.QuitClosure(), &success));
- run_loop.Run();
+ base::RunLoop loop;
+ wrapper->Delete(key, client_old_value, test_source_,
+ MakeSuccessCallback(loop.QuitClosure(), &success));
+ loop.Run();
return success;
}
- bool DeleteAllSync() {
- base::RunLoop run_loop;
+ bool DeleteAllSync(mojom::LevelDBWrapper* wrapper) {
bool success = false;
- wrapper()->DeleteAll(
- kTestSource,
- base::BindOnce(&SuccessCallback, run_loop.QuitClosure(), &success));
- run_loop.Run();
+ base::RunLoop loop;
+ wrapper->DeleteAll(test_source_,
+ MakeSuccessCallback(loop.QuitClosure(), &success));
+ loop.Run();
return success;
}
- void CommitChanges() { level_db_wrapper_.ScheduleImmediateCommit(); }
+ bool GetSync(const std::vector<uint8_t>& key, std::vector<uint8_t>* result) {
+ return GetSync(wrapper(), key, result);
+ }
+
+ bool PutSync(const std::vector<uint8_t>& key,
+ const std::vector<uint8_t>& value,
+ const base::Optional<std::vector<uint8_t>>& client_old_value,
+ std::string source = kTestSource) {
+ return PutSync(wrapper(), key, value, client_old_value, source);
+ }
+
+ bool DeleteSync(
+ const std::vector<uint8_t>& key,
+ const base::Optional<std::vector<uint8_t>>& client_old_value) {
+ return DeleteSync(wrapper(), key, client_old_value);
+ }
+
+ bool DeleteAllSync() { return DeleteAllSync(wrapper()); }
+
+ std::string GetSyncStrUsingGetAll(LevelDBWrapperImpl* wrapper_impl,
+ const std::string& key) {
+ leveldb::mojom::DatabaseError status;
+ std::vector<mojom::KeyValuePtr> data;
+ bool done = false;
+
+ base::RunLoop loop;
+ // Testing the 'Sync' mojo version is a big headache involving 3 threads, so
+ // just test the async version.
+ wrapper_impl->GetAll(
+ GetAllCallback::CreateAndBind(&done, loop.QuitClosure()),
+ MakeGetAllCallback(&status, &data));
+ loop.Run();
+
+ if (!done)
+ return "";
+
+ if (status != leveldb::mojom::DatabaseError::OK)
+ return "";
+
+ for (const auto& key_value : data) {
+ if (key_value->key == ToBytes(key)) {
+ return ToString(key_value->value);
+ }
+ }
+ return "";
+ }
+
+ void BlockingCommit() { BlockingCommit(&delegate_, level_db_wrapper_.get()); }
+
+ void BlockingCommit(MockDelegate* delegate, LevelDBWrapperImpl* wrapper) {
+ while (wrapper->has_pending_load_tasks() ||
+ wrapper->has_changes_to_commit()) {
+ base::RunLoop loop;
+ delegate->SetDidCommitCallback(loop.QuitClosure());
+ wrapper->ScheduleImmediateCommit();
+ loop.Run();
+ }
+ }
const std::vector<Observation>& observations() { return observations_; }
MockDelegate* delegate() { return &delegate_; }
+ void should_record_send_old_value_observations(bool value) {
+ should_record_send_old_value_observations_ = value;
+ }
+
+ protected:
+ const std::string test_prefix_ = "abc";
+ const std::string test_key1_ = "def";
+ const std::string test_key2_ = "123";
+ const std::string test_value1_ = "defdata";
+ const std::string test_value2_ = "123data";
+ const std::string test_copy_prefix1_ = "www";
+ const std::string test_copy_prefix2_ = "xxx";
+ const std::string test_copy_prefix3_ = "yyy";
+ const std::string test_source_ = kTestSource;
+
+ const std::vector<uint8_t> test_prefix_bytes_ = ToBytes(test_prefix_);
+ const std::vector<uint8_t> test_key1_bytes_ = ToBytes(test_key1_);
+ const std::vector<uint8_t> test_key2_bytes_ = ToBytes(test_key2_);
+ const std::vector<uint8_t> test_value1_bytes_ = ToBytes(test_value1_);
+ const std::vector<uint8_t> test_value2_bytes_ = ToBytes(test_value2_);
+
private:
// LevelDBObserver:
void KeyAdded(const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value,
const std::string& source) override {
- observations_.push_back({Observation::kAdd, Uint8VectorToStdString(key), "",
- Uint8VectorToStdString(value), source});
+ observations_.push_back(
+ {Observation::kAdd, ToString(key), "", ToString(value), source, false});
}
void KeyChanged(const std::vector<uint8_t>& key,
const std::vector<uint8_t>& new_value,
const std::vector<uint8_t>& old_value,
const std::string& source) override {
- observations_.push_back({Observation::kChange, Uint8VectorToStdString(key),
- Uint8VectorToStdString(old_value),
- Uint8VectorToStdString(new_value), source});
+ observations_.push_back({Observation::kChange, ToString(key),
+ ToString(old_value), ToString(new_value), source,
+ false});
}
void KeyDeleted(const std::vector<uint8_t>& key,
const std::vector<uint8_t>& old_value,
const std::string& source) override {
- observations_.push_back({Observation::kDelete, Uint8VectorToStdString(key),
- Uint8VectorToStdString(old_value), "", source});
+ observations_.push_back({Observation::kDelete, ToString(key),
+ ToString(old_value), "", source, false});
}
void AllDeleted(const std::string& source) override {
- observations_.push_back({Observation::kDeleteAll, "", "", "", source});
+ observations_.push_back(
+ {Observation::kDeleteAll, "", "", "", source, false});
+ }
+ void ShouldSendOldValueOnMutations(bool value) override {
+ if (should_record_send_old_value_observations_)
+ observations_.push_back(
+ {Observation::kSendOldValue, "", "", "", "", value});
}
- void ShouldSendOldValueOnMutations(bool value) override {}
TestBrowserThreadBundle thread_bundle_;
std::map<std::vector<uint8_t>, std::vector<uint8_t>> mock_data_;
- MockLevelDBDatabase db_;
+ FakeLevelDBDatabase db_;
+ leveldb::mojom::LevelDBDatabasePtr level_db_database_ptr_;
MockDelegate delegate_;
- LevelDBWrapperImpl level_db_wrapper_;
+ std::unique_ptr<LevelDBWrapperImpl> level_db_wrapper_;
mojom::LevelDBWrapperPtr level_db_wrapper_ptr_;
mojo::AssociatedBinding<mojom::LevelDBObserver> observer_binding_;
std::vector<Observation> observations_;
+ bool should_record_send_old_value_observations_ = false;
+};
+
+class LevelDBWrapperImplParamTest
+ : public LevelDBWrapperImplTest,
+ public testing::WithParamInterface<CacheMode> {
+ public:
+ LevelDBWrapperImplParamTest() {}
+ ~LevelDBWrapperImplParamTest() override {}
};
+INSTANTIATE_TEST_CASE_P(LevelDBWrapperImplTest,
+ LevelDBWrapperImplParamTest,
+ testing::Values(CacheMode::KEYS_ONLY_WHEN_POSSIBLE,
+ CacheMode::KEYS_AND_VALUES));
+
TEST_F(LevelDBWrapperImplTest, GetLoadedFromMap) {
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
std::vector<uint8_t> result;
- EXPECT_TRUE(GetSync(StdStringToUint8Vector("123"), &result));
- EXPECT_EQ(StdStringToUint8Vector("123data"), result);
+ EXPECT_TRUE(GetSync(test_key2_bytes_, &result));
+ EXPECT_EQ(test_value2_bytes_, result);
- EXPECT_FALSE(GetSync(StdStringToUint8Vector("x"), &result));
+ EXPECT_FALSE(GetSync(ToBytes("x"), &result));
}
TEST_F(LevelDBWrapperImplTest, GetFromPutOverwrite) {
- std::vector<uint8_t> key = StdStringToUint8Vector("123");
- std::vector<uint8_t> value = StdStringToUint8Vector("foo");
-
- EXPECT_TRUE(PutSync(key, value, StdStringToUint8Vector("123data")));
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ std::vector<uint8_t> key = test_key2_bytes_;
+ std::vector<uint8_t> value = ToBytes("foo");
+ base::RunLoop loop;
+ bool put_success = false;
std::vector<uint8_t> result;
- EXPECT_TRUE(GetSync(key, &result));
+ bool get_success = false;
+ {
+ IncrementalBarrier barrier(loop.QuitClosure());
+ wrapper()->Put(key, value, test_value2_bytes_, test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success));
+ wrapper()->Get(key, MakeGetCallback(barrier.Get(), &get_success, &result));
+ }
+
+ loop.Run();
+ EXPECT_TRUE(put_success);
+ EXPECT_TRUE(get_success);
+
EXPECT_EQ(value, result);
}
TEST_F(LevelDBWrapperImplTest, GetFromPutNewKey) {
- std::vector<uint8_t> key = StdStringToUint8Vector("newkey");
- std::vector<uint8_t> value = StdStringToUint8Vector("foo");
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ std::vector<uint8_t> key = ToBytes("newkey");
+ std::vector<uint8_t> value = ToBytes("foo");
EXPECT_TRUE(PutSync(key, value, base::nullopt));
@@ -267,63 +492,103 @@ TEST_F(LevelDBWrapperImplTest, GetFromPutNewKey) {
EXPECT_EQ(value, result);
}
-TEST_F(LevelDBWrapperImplTest, GetAll) {
- leveldb::mojom::DatabaseError status;
+TEST_F(LevelDBWrapperImplTest, PutLoadsValuesAfterCacheModeUpgrade) {
+ std::vector<uint8_t> key = ToBytes("newkey");
+ std::vector<uint8_t> value1 = ToBytes("foo");
+ std::vector<uint8_t> value2 = ToBytes("bar");
+
+ ASSERT_EQ(CacheMode::KEYS_ONLY_WHEN_POSSIBLE, wrapper_impl()->cache_mode());
+
+ // Do a put to load the key-only cache.
+ EXPECT_TRUE(PutSync(key, value1, base::nullopt));
+ EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY,
+ wrapper_impl()->map_state_);
+
+ // Change cache mode.
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ // Loading new map isn't necessary yet.
+ EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY,
+ wrapper_impl()->map_state_);
+
+ // Do another put and check that the map has been upgraded
+ EXPECT_TRUE(PutSync(key, value2, value1));
+ EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_AND_VALUES,
+ wrapper_impl()->map_state_);
+}
+
+TEST_P(LevelDBWrapperImplParamTest, GetAll) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
+ DatabaseError status;
std::vector<mojom::KeyValuePtr> data;
- base::RunLoop run_loop;
bool result = false;
- EXPECT_TRUE(wrapper()->GetAll(
- GetAllCallback::CreateAndBind(&result, run_loop.QuitClosure()), &status,
- &data));
+
+ base::RunLoop loop;
+ // Testing the 'Sync' mojo version is a big headache involving 3 threads, so
+ // just test the async version.
+ wrapper_impl()->GetAll(
+ GetAllCallback::CreateAndBind(&result, loop.QuitClosure()),
+ MakeGetAllCallback(&status, &data));
+ loop.Run();
EXPECT_EQ(leveldb::mojom::DatabaseError::OK, status);
EXPECT_EQ(2u, data.size());
- EXPECT_FALSE(result);
- run_loop.Run();
EXPECT_TRUE(result);
}
-TEST_F(LevelDBWrapperImplTest, CommitPutToDB) {
- std::string key1 = "123";
+TEST_P(LevelDBWrapperImplParamTest, CommitPutToDB) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
+ std::string key1 = test_key2_;
std::string value1 = "foo";
- std::string key2 = "abc";
+ std::string key2 = test_prefix_;
std::string value2 = "data abc";
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key1),
- StdStringToUint8Vector(value1),
- StdStringToUint8Vector("123data")));
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key2),
- StdStringToUint8Vector("old value"), base::nullopt));
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key2),
- StdStringToUint8Vector(value2),
- StdStringToUint8Vector("old value")));
+ base::RunLoop loop;
+ bool put_success1 = false;
+ bool put_success2 = false;
+ bool put_success3 = false;
+ {
+ IncrementalBarrier barrier(loop.QuitClosure());
+
+ wrapper()->Put(ToBytes(key1), ToBytes(value1), test_value2_bytes_,
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success1));
+ wrapper()->Put(ToBytes(key2), ToBytes("old value"), base::nullopt,
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success2));
+ wrapper()->Put(ToBytes(key2), ToBytes(value2), ToBytes("old value"),
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success3));
+ }
+
+ loop.Run();
+ EXPECT_TRUE(put_success1);
+ EXPECT_TRUE(put_success2);
+ EXPECT_TRUE(put_success3);
- EXPECT_FALSE(has_mock_data(kTestPrefix + key2));
+ EXPECT_FALSE(has_mock_data(test_prefix_ + key2));
- CommitChanges();
- EXPECT_TRUE(has_mock_data(kTestPrefix + key1));
- EXPECT_EQ(value1, get_mock_data(kTestPrefix + key1));
- EXPECT_TRUE(has_mock_data(kTestPrefix + key2));
- EXPECT_EQ(value2, get_mock_data(kTestPrefix + key2));
+ BlockingCommit();
+ EXPECT_TRUE(has_mock_data(test_prefix_ + key1));
+ EXPECT_EQ(value1, get_mock_data(test_prefix_ + key1));
+ EXPECT_TRUE(has_mock_data(test_prefix_ + key2));
+ EXPECT_EQ(value2, get_mock_data(test_prefix_ + key2));
}
-TEST_F(LevelDBWrapperImplTest, PutObservations) {
+TEST_P(LevelDBWrapperImplParamTest, PutObservations) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
std::string key = "new_key";
std::string value1 = "foo";
std::string value2 = "data abc";
std::string source1 = "source1";
std::string source2 = "source2";
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key),
- StdStringToUint8Vector(value1), base::nullopt, source1));
+ EXPECT_TRUE(PutSync(ToBytes(key), ToBytes(value1), base::nullopt, source1));
ASSERT_EQ(1u, observations().size());
EXPECT_EQ(Observation::kAdd, observations()[0].type);
EXPECT_EQ(key, observations()[0].key);
EXPECT_EQ(value1, observations()[0].new_value);
EXPECT_EQ(source1, observations()[0].source);
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key),
- StdStringToUint8Vector(value2),
- StdStringToUint8Vector(value1), source2));
+ EXPECT_TRUE(PutSync(ToBytes(key), ToBytes(value2), ToBytes(value1), source2));
ASSERT_EQ(2u, observations().size());
EXPECT_EQ(Observation::kChange, observations()[1].type);
EXPECT_EQ(key, observations()[1].key);
@@ -332,53 +597,53 @@ TEST_F(LevelDBWrapperImplTest, PutObservations) {
EXPECT_EQ(source2, observations()[1].source);
// Same put should not cause another observation.
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key),
- StdStringToUint8Vector(value2), base::nullopt, source2));
+ EXPECT_TRUE(PutSync(ToBytes(key), ToBytes(value2), ToBytes(value2), source2));
ASSERT_EQ(2u, observations().size());
}
-TEST_F(LevelDBWrapperImplTest, DeleteNonExistingKey) {
- EXPECT_TRUE(DeleteSync(StdStringToUint8Vector("doesn't exist"),
- std::vector<uint8_t>()));
+TEST_P(LevelDBWrapperImplParamTest, DeleteNonExistingKey) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
+ EXPECT_TRUE(DeleteSync(ToBytes("doesn't exist"), std::vector<uint8_t>()));
EXPECT_EQ(0u, observations().size());
}
-TEST_F(LevelDBWrapperImplTest, DeleteExistingKey) {
+TEST_P(LevelDBWrapperImplParamTest, DeleteExistingKey) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
std::string key = "newkey";
std::string value = "foo";
- set_mock_data(kTestPrefix + key, value);
+ set_mock_data(test_prefix_ + key, value);
- EXPECT_TRUE(
- DeleteSync(StdStringToUint8Vector(key), StdStringToUint8Vector(value)));
+ EXPECT_TRUE(DeleteSync(ToBytes(key), ToBytes(value)));
ASSERT_EQ(1u, observations().size());
EXPECT_EQ(Observation::kDelete, observations()[0].type);
EXPECT_EQ(key, observations()[0].key);
EXPECT_EQ(value, observations()[0].old_value);
- EXPECT_EQ(kTestSource, observations()[0].source);
+ EXPECT_EQ(test_source_, observations()[0].source);
- EXPECT_TRUE(has_mock_data(kTestPrefix + key));
+ EXPECT_TRUE(has_mock_data(test_prefix_ + key));
- CommitChanges();
- EXPECT_FALSE(has_mock_data(kTestPrefix + key));
+ BlockingCommit();
+ EXPECT_FALSE(has_mock_data(test_prefix_ + key));
}
-TEST_F(LevelDBWrapperImplTest, DeleteAllWithoutLoadedMap) {
+TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithoutLoadedMap) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
std::string key = "newkey";
std::string value = "foo";
std::string dummy_key = "foobar";
set_mock_data(dummy_key, value);
- set_mock_data(kTestPrefix + key, value);
+ set_mock_data(test_prefix_ + key, value);
EXPECT_TRUE(DeleteAllSync());
ASSERT_EQ(1u, observations().size());
EXPECT_EQ(Observation::kDeleteAll, observations()[0].type);
- EXPECT_EQ(kTestSource, observations()[0].source);
+ EXPECT_EQ(test_source_, observations()[0].source);
- EXPECT_TRUE(has_mock_data(kTestPrefix + key));
+ EXPECT_TRUE(has_mock_data(test_prefix_ + key));
EXPECT_TRUE(has_mock_data(dummy_key));
- CommitChanges();
- EXPECT_FALSE(has_mock_data(kTestPrefix + key));
+ BlockingCommit();
+ EXPECT_FALSE(has_mock_data(test_prefix_ + key));
EXPECT_TRUE(has_mock_data(dummy_key));
// Deleting all again should still work, but not cause an observation.
@@ -390,58 +655,61 @@ TEST_F(LevelDBWrapperImplTest, DeleteAllWithoutLoadedMap) {
std::vector<uint8_t>(), base::nullopt));
}
-TEST_F(LevelDBWrapperImplTest, DeleteAllWithLoadedMap) {
+TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithLoadedMap) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
std::string key = "newkey";
std::string value = "foo";
std::string dummy_key = "foobar";
set_mock_data(dummy_key, value);
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key),
- StdStringToUint8Vector(value), base::nullopt));
+ EXPECT_TRUE(PutSync(ToBytes(key), ToBytes(value), base::nullopt));
EXPECT_TRUE(DeleteAllSync());
ASSERT_EQ(2u, observations().size());
EXPECT_EQ(Observation::kDeleteAll, observations()[1].type);
- EXPECT_EQ(kTestSource, observations()[1].source);
+ EXPECT_EQ(test_source_, observations()[1].source);
EXPECT_TRUE(has_mock_data(dummy_key));
- CommitChanges();
- EXPECT_FALSE(has_mock_data(kTestPrefix + key));
+ BlockingCommit();
+ EXPECT_FALSE(has_mock_data(test_prefix_ + key));
EXPECT_TRUE(has_mock_data(dummy_key));
}
-TEST_F(LevelDBWrapperImplTest, DeleteAllWithPendingMapLoad) {
+TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithPendingMapLoad) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
std::string key = "newkey";
std::string value = "foo";
std::string dummy_key = "foobar";
set_mock_data(dummy_key, value);
- wrapper()->Put(StdStringToUint8Vector(key), StdStringToUint8Vector(value),
- base::nullopt, kTestSource,
+ wrapper()->Put(ToBytes(key), ToBytes(value), base::nullopt, kTestSource,
base::BindOnce(&NoOpSuccessCallback));
EXPECT_TRUE(DeleteAllSync());
ASSERT_EQ(2u, observations().size());
EXPECT_EQ(Observation::kDeleteAll, observations()[1].type);
- EXPECT_EQ(kTestSource, observations()[1].source);
+ EXPECT_EQ(test_source_, observations()[1].source);
EXPECT_TRUE(has_mock_data(dummy_key));
- CommitChanges();
- EXPECT_FALSE(has_mock_data(kTestPrefix + key));
+ BlockingCommit();
+ EXPECT_FALSE(has_mock_data(test_prefix_ + key));
EXPECT_TRUE(has_mock_data(dummy_key));
}
-TEST_F(LevelDBWrapperImplTest, DeleteAllWithoutLoadedEmptyMap) {
+TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithoutLoadedEmptyMap) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
clear_mock_data();
EXPECT_TRUE(DeleteAllSync());
ASSERT_EQ(0u, observations().size());
}
-TEST_F(LevelDBWrapperImplTest, PutOverQuotaLargeValue) {
- std::vector<uint8_t> key = StdStringToUint8Vector("newkey");
+TEST_F(LevelDBWrapperImplParamTest, PutOverQuotaLargeValue) {
+ wrapper_impl()->SetCacheModeForTesting(
+ LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES);
+ std::vector<uint8_t> key = ToBytes("newkey");
std::vector<uint8_t> value(kTestSizeLimit, 4);
EXPECT_FALSE(PutSync(key, value, base::nullopt));
@@ -450,9 +718,11 @@ TEST_F(LevelDBWrapperImplTest, PutOverQuotaLargeValue) {
EXPECT_TRUE(PutSync(key, value, base::nullopt));
}
-TEST_F(LevelDBWrapperImplTest, PutOverQuotaLargeKey) {
+TEST_F(LevelDBWrapperImplParamTest, PutOverQuotaLargeKey) {
+ wrapper_impl()->SetCacheModeForTesting(
+ LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES);
std::vector<uint8_t> key(kTestSizeLimit, 'a');
- std::vector<uint8_t> value = StdStringToUint8Vector("newvalue");
+ std::vector<uint8_t> value = ToBytes("newvalue");
EXPECT_FALSE(PutSync(key, value, base::nullopt));
@@ -460,47 +730,49 @@ TEST_F(LevelDBWrapperImplTest, PutOverQuotaLargeKey) {
EXPECT_TRUE(PutSync(key, value, base::nullopt));
}
-TEST_F(LevelDBWrapperImplTest, PutWhenAlreadyOverQuota) {
+TEST_F(LevelDBWrapperImplParamTest, PutWhenAlreadyOverQuota) {
+ wrapper_impl()->SetCacheModeForTesting(
+ LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES);
std::string key = "largedata";
std::vector<uint8_t> value(kTestSizeLimit, 4);
std::vector<uint8_t> old_value = value;
- set_mock_data(kTestPrefix + key, Uint8VectorToStdString(value));
+ set_mock_data(test_prefix_ + key, ToString(value));
// Put with same data should succeed.
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key), value, base::nullopt));
+ EXPECT_TRUE(PutSync(ToBytes(key), value, base::nullopt));
// Put with same data size should succeed.
value[1] = 13;
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key), value, old_value));
+ EXPECT_TRUE(PutSync(ToBytes(key), value, old_value));
// Adding a new key when already over quota should not succeed.
- EXPECT_FALSE(
- PutSync(StdStringToUint8Vector("newkey"), {1, 2, 3}, base::nullopt));
+ EXPECT_FALSE(PutSync(ToBytes("newkey"), {1, 2, 3}, base::nullopt));
// Reducing size should also succeed.
old_value = value;
value.resize(kTestSizeLimit / 2);
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key), value, old_value));
+ EXPECT_TRUE(PutSync(ToBytes(key), value, old_value));
// Increasing size again should succeed, as still under the limit.
old_value = value;
value.resize(value.size() + 1);
- EXPECT_TRUE(PutSync(StdStringToUint8Vector(key), value, old_value));
+ EXPECT_TRUE(PutSync(ToBytes(key), value, old_value));
// But increasing back to original size should fail.
old_value = value;
value.resize(kTestSizeLimit);
- EXPECT_FALSE(PutSync(StdStringToUint8Vector(key), value, old_value));
+ EXPECT_FALSE(PutSync(ToBytes(key), value, old_value));
}
-TEST_F(LevelDBWrapperImplTest, PutWhenAlreadyOverQuotaBecauseOfLargeKey) {
+TEST_F(LevelDBWrapperImplParamTest, PutWhenAlreadyOverQuotaBecauseOfLargeKey) {
+ wrapper_impl()->SetCacheModeForTesting(
+ LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES);
std::vector<uint8_t> key(kTestSizeLimit, 'x');
- std::vector<uint8_t> value = StdStringToUint8Vector("value");
+ std::vector<uint8_t> value = ToBytes("value");
std::vector<uint8_t> old_value = value;
- set_mock_data(kTestPrefix + Uint8VectorToStdString(key),
- Uint8VectorToStdString(value));
+ set_mock_data(test_prefix_ + ToString(key), ToString(value));
// Put with same data size should succeed.
value[0] = 'X';
@@ -517,61 +789,625 @@ TEST_F(LevelDBWrapperImplTest, PutWhenAlreadyOverQuotaBecauseOfLargeKey) {
EXPECT_FALSE(PutSync(key, value, old_value));
}
-TEST_F(LevelDBWrapperImplTest, GetAfterPurgeMemory) {
+TEST_P(LevelDBWrapperImplParamTest, PutAfterPurgeMemory) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
std::vector<uint8_t> result;
- EXPECT_TRUE(GetSync(StdStringToUint8Vector("123"), &result));
- EXPECT_EQ(StdStringToUint8Vector("123data"), result);
+ const auto key = test_key2_bytes_;
+ const auto value = test_value2_bytes_;
+ EXPECT_TRUE(PutSync(key, value, value));
EXPECT_EQ(delegate()->map_load_count(), 1);
- // Reading again doesn't load map again.
- EXPECT_TRUE(GetSync(StdStringToUint8Vector("123"), &result));
+ // Adding again doesn't load map again.
+ EXPECT_TRUE(PutSync(key, value, value));
EXPECT_EQ(delegate()->map_load_count(), 1);
wrapper_impl()->PurgeMemory();
- // Now reading should still work, and load map again.
- result.clear();
- EXPECT_TRUE(GetSync(StdStringToUint8Vector("123"), &result));
- EXPECT_EQ(StdStringToUint8Vector("123data"), result);
+ // Now adding should still work, and load map again.
+ EXPECT_TRUE(PutSync(key, value, value));
EXPECT_EQ(delegate()->map_load_count(), 2);
}
-TEST_F(LevelDBWrapperImplTest, PurgeMemoryWithPendingChanges) {
- std::vector<uint8_t> key = StdStringToUint8Vector("123");
- std::vector<uint8_t> value = StdStringToUint8Vector("foo");
- EXPECT_TRUE(PutSync(key, value, StdStringToUint8Vector("123data")));
+TEST_P(LevelDBWrapperImplParamTest, PurgeMemoryWithPendingChanges) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
+ std::vector<uint8_t> key = test_key2_bytes_;
+ std::vector<uint8_t> value = ToBytes("foo");
+ EXPECT_TRUE(PutSync(key, value, test_value2_bytes_));
EXPECT_EQ(delegate()->map_load_count(), 1);
// Purge memory, and read. Should not actually have purged, so should not have
// triggered a load.
wrapper_impl()->PurgeMemory();
- std::vector<uint8_t> result;
- EXPECT_TRUE(GetSync(key, &result));
- EXPECT_EQ(value, result);
+ EXPECT_TRUE(PutSync(key, value, value));
EXPECT_EQ(delegate()->map_load_count(), 1);
}
-TEST_F(LevelDBWrapperImplTest, FixUpData) {
+TEST_P(LevelDBWrapperImplParamTest, FixUpData) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
std::vector<LevelDBWrapperImpl::Change> changes;
- changes.push_back(std::make_pair(StdStringToUint8Vector("def"),
- StdStringToUint8Vector("foo")));
- changes.push_back(
- std::make_pair(StdStringToUint8Vector("123"), base::nullopt));
- changes.push_back(std::make_pair(StdStringToUint8Vector("abc"),
- StdStringToUint8Vector("bla")));
+ changes.push_back(std::make_pair(test_key1_bytes_, ToBytes("foo")));
+ changes.push_back(std::make_pair(test_key2_bytes_, base::nullopt));
+ changes.push_back(std::make_pair(test_prefix_bytes_, ToBytes("bla")));
delegate()->set_mock_changes(std::move(changes));
+ leveldb::mojom::DatabaseError status;
+ std::vector<mojom::KeyValuePtr> data;
+ bool result = false;
+
+ base::RunLoop loop;
+ // Testing the 'Sync' mojo version is a big headache involving 3 threads, so
+ // just test the async version.
+ wrapper_impl()->GetAll(
+ GetAllCallback::CreateAndBind(&result, loop.QuitClosure()),
+ MakeGetAllCallback(&status, &data));
+ loop.Run();
+
+ EXPECT_EQ(leveldb::mojom::DatabaseError::OK, status);
+ ASSERT_EQ(2u, data.size());
+ EXPECT_EQ(test_prefix_, ToString(data[0]->key));
+ EXPECT_EQ("bla", ToString(data[0]->value));
+ EXPECT_EQ(test_key1_, ToString(data[1]->key));
+ EXPECT_EQ("foo", ToString(data[1]->value));
+
+ EXPECT_FALSE(has_mock_data(test_prefix_ + test_key2_));
+ EXPECT_EQ("foo", get_mock_data(test_prefix_ + test_key1_));
+ EXPECT_EQ("bla", get_mock_data(test_prefix_ + test_prefix_));
+}
+
+TEST_F(LevelDBWrapperImplTest, SetOnlyKeysWithoutDatabase) {
+ std::vector<uint8_t> key = test_key2_bytes_;
+ std::vector<uint8_t> value = ToBytes("foo");
+ MockDelegate delegate;
+ LevelDBWrapperImpl level_db_wrapper(
+ nullptr, test_prefix_, &delegate,
+ GetDefaultTestingOptions(CacheMode::KEYS_ONLY_WHEN_POSSIBLE));
+ mojom::LevelDBWrapperPtr level_db_wrapper_ptr;
+ level_db_wrapper.Bind(mojo::MakeRequest(&level_db_wrapper_ptr));
+ // Setting only keys mode is noop.
+ level_db_wrapper.SetCacheModeForTesting(CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
+
+ EXPECT_FALSE(level_db_wrapper.initialized());
+ EXPECT_EQ(CacheMode::KEYS_AND_VALUES, level_db_wrapper.cache_mode());
+
+ // Put and Get can work synchronously without reload.
+ bool put_callback_called = false;
+ level_db_wrapper.Put(key, value, base::nullopt, "source",
+ base::BindOnce(
+ [](bool* put_callback_called, bool success) {
+ EXPECT_TRUE(success);
+ *put_callback_called = true;
+ },
+ &put_callback_called));
+ EXPECT_TRUE(put_callback_called);
+
+ std::vector<uint8_t> expected_value;
+ level_db_wrapper.Get(
+ key, base::BindOnce(
+ [](std::vector<uint8_t>* expected_value, bool success,
+ const std::vector<uint8_t>& value) {
+ EXPECT_TRUE(success);
+ *expected_value = value;
+ },
+ &expected_value));
+ EXPECT_EQ(expected_value, value);
+}
+
+TEST_P(LevelDBWrapperImplParamTest, CommitOnDifferentCacheModes) {
+ wrapper_impl()->SetCacheModeForTesting(GetParam());
+ std::vector<uint8_t> key = test_key2_bytes_;
+ std::vector<uint8_t> value = ToBytes("foo");
+ std::vector<uint8_t> value2 = ToBytes("foobar");
+
+ // The initial map always has values, so a nullopt is fine for the old value.
+ ASSERT_TRUE(PutSync(key, value, base::nullopt));
+ ASSERT_TRUE(wrapper_impl()->commit_batch_);
+
+ if (GetParam() == CacheMode::KEYS_AND_VALUES) {
+ EXPECT_TRUE(wrapper_impl()->commit_batch_->changed_values.empty());
+ auto* changes = &wrapper_impl()->commit_batch_->changed_keys;
+ ASSERT_EQ(1u, changes->size());
+ EXPECT_EQ(key, *changes->begin());
+ } else {
+ EXPECT_TRUE(wrapper_impl()->commit_batch_->changed_keys.empty());
+ auto* changes = &wrapper_impl()->commit_batch_->changed_values;
+ ASSERT_EQ(1u, changes->size());
+ auto it = changes->begin();
+ EXPECT_EQ(key, it->first);
+ EXPECT_EQ(value, it->second);
+ }
+
+ BlockingCommit();
+
+ EXPECT_EQ("foo", get_mock_data(test_prefix_ + test_key2_));
+ if (GetParam() == CacheMode::KEYS_AND_VALUES)
+ EXPECT_EQ(2u, wrapper_impl()->keys_values_map_.size());
+ else
+ EXPECT_EQ(2u, wrapper_impl()->keys_only_map_.size());
+ ASSERT_TRUE(PutSync(key, value, value));
+ EXPECT_FALSE(wrapper_impl()->commit_batch_);
+ ASSERT_TRUE(PutSync(key, value2, value));
+ ASSERT_TRUE(wrapper_impl()->commit_batch_);
+
+ if (GetParam() == CacheMode::KEYS_AND_VALUES) {
+ auto* changes = &wrapper_impl()->commit_batch_->changed_keys;
+ EXPECT_EQ(1u, changes->size());
+ auto it = changes->find(key);
+ ASSERT_NE(it, changes->end());
+ } else {
+ auto* changes = &wrapper_impl()->commit_batch_->changed_values;
+ EXPECT_EQ(1u, changes->size());
+ auto it = changes->find(key);
+ ASSERT_NE(it, changes->end());
+ EXPECT_EQ(value2, it->second);
+ }
+
+ clear_mock_data();
+ EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+ BlockingCommit();
+ EXPECT_EQ("foobar", get_mock_data(test_prefix_ + test_key2_));
+ EXPECT_FALSE(wrapper_impl()->has_changes_to_commit());
+}
+
+TEST_F(LevelDBWrapperImplTest, GetAllWhenCacheOnlyKeys) {
+ std::vector<uint8_t> key = test_key2_bytes_;
+ std::vector<uint8_t> value = ToBytes("foo");
+ std::vector<uint8_t> value2 = ToBytes("foobar");
+
+ // Go to load state only keys.
+ ASSERT_TRUE(PutSync(key, value, base::nullopt));
+ BlockingCommit();
+ ASSERT_TRUE(PutSync(key, value2, value));
+ EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+
+ leveldb::mojom::DatabaseError status;
+ std::vector<mojom::KeyValuePtr> data;
+ bool result = false;
+
+ base::RunLoop loop;
+
+ bool put_result1 = false;
+ bool put_result2 = false;
+ {
+ IncrementalBarrier barrier(loop.QuitClosure());
+
+ wrapper_impl()->Put(key, value, value2, test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_result1));
+
+ wrapper_impl()->GetAll(
+ GetAllCallback::CreateAndBind(&result, barrier.Get()),
+ MakeGetAllCallback(&status, &data));
+ wrapper_impl()->Put(key, value2, value, test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_result2));
+ }
+
+ // GetAll triggers a commit when it's switching map types.
+ EXPECT_TRUE(put_result1);
+ EXPECT_EQ("foo", get_mock_data(test_prefix_ + test_key2_));
+
+ EXPECT_FALSE(put_result2);
+ EXPECT_FALSE(result);
+ loop.Run();
+
+ EXPECT_TRUE(result);
+ EXPECT_TRUE(put_result1);
+
+ EXPECT_EQ(2u, data.size());
+ EXPECT_TRUE(
+ data[1]->Equals(mojom::KeyValue(test_key1_bytes_, test_value1_bytes_)))
+ << ToString(data[1]->value) << " vs expected " << test_value1_;
+ EXPECT_TRUE(data[0]->Equals(mojom::KeyValue(key, value)))
+ << ToString(data[0]->value) << " vs expected " << ToString(value);
+
+ EXPECT_EQ(leveldb::mojom::DatabaseError::OK, status);
+
+ // The last "put" isn't committed yet.
+ EXPECT_EQ("foo", get_mock_data(test_prefix_ + test_key2_));
+
+ ASSERT_TRUE(wrapper_impl()->has_changes_to_commit());
+ BlockingCommit();
+
+ EXPECT_EQ("foobar", get_mock_data(test_prefix_ + test_key2_));
+}
+
+TEST_F(LevelDBWrapperImplTest, GetAllAfterSetCacheMode) {
+ std::vector<uint8_t> key = test_key2_bytes_;
+ std::vector<uint8_t> value = ToBytes("foo");
+ std::vector<uint8_t> value2 = ToBytes("foobar");
+
+ // Go to load state only keys.
+ ASSERT_TRUE(PutSync(key, value, base::nullopt));
+ BlockingCommit();
+ EXPECT_TRUE(wrapper_impl()->map_state_ ==
+ LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY);
+ ASSERT_TRUE(PutSync(key, value2, value));
+ EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+
+ // Cache isn't cleared when commit batch exists.
+ EXPECT_TRUE(wrapper_impl()->map_state_ ==
+ LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY);
+
+ base::RunLoop loop;
+
+ bool put_success = false;
+ leveldb::mojom::DatabaseError status;
+ std::vector<mojom::KeyValuePtr> data;
+ bool get_all_success = false;
+ bool delete_success = false;
+ {
+ IncrementalBarrier barrier(loop.QuitClosure());
+
+ wrapper_impl()->Put(key, value, value2, test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success));
+
+ // Put task triggers database upgrade, so there are no more changes
+ // to commit.
+ EXPECT_FALSE(wrapper_impl()->has_changes_to_commit());
+ EXPECT_TRUE(wrapper_impl()->has_pending_load_tasks());
+
+ wrapper_impl()->GetAll(
+ GetAllCallback::CreateAndBind(&get_all_success, barrier.Get()),
+ MakeGetAllCallback(&status, &data));
+
+ // This Delete() should not affect the value returned by GetAll().
+ wrapper_impl()->Delete(key, value, test_source_,
+ MakeSuccessCallback(barrier.Get(), &delete_success));
+ }
+ loop.Run();
+
+ EXPECT_EQ(2u, data.size());
+ EXPECT_TRUE(
+ data[1]->Equals(mojom::KeyValue(test_key1_bytes_, test_value1_bytes_)))
+ << ToString(data[1]->value) << " vs expected " << test_value1_;
+ EXPECT_TRUE(data[0]->Equals(mojom::KeyValue(key, value)))
+ << ToString(data[0]->value) << " vs expected " << ToString(value2);
+
+ EXPECT_EQ(leveldb::mojom::DatabaseError::OK, status);
+
+ EXPECT_TRUE(put_success);
+ EXPECT_TRUE(get_all_success);
+ EXPECT_TRUE(delete_success);
+
+ // GetAll shouldn't trigger a commit before it runs now because the value
+ // map should be loading.
+ EXPECT_EQ("foobar", get_mock_data(test_prefix_ + test_key2_));
+
+ ASSERT_TRUE(wrapper_impl()->has_changes_to_commit());
+ BlockingCommit();
+
+ EXPECT_FALSE(has_mock_data(test_prefix_ + test_key2_));
+}
+
+TEST_F(LevelDBWrapperImplTest, SetCacheModeConsistent) {
+ std::vector<uint8_t> key = test_key2_bytes_;
+ std::vector<uint8_t> value = ToBytes("foo");
+ std::vector<uint8_t> value2 = ToBytes("foobar");
+
+ EXPECT_FALSE(wrapper_impl()->IsMapLoaded());
+ EXPECT_TRUE(wrapper_impl()->cache_mode() ==
+ CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
+
+ // Clear the database before the wrapper loads data.
+ clear_mock_data();
+
+ EXPECT_TRUE(PutSync(key, value, base::nullopt));
+ EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+ BlockingCommit();
+
+ EXPECT_TRUE(PutSync(key, value2, value));
+ EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+
+ // Setting cache mode does not reload the cache till it is required.
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY,
+ wrapper_impl()->map_state_);
+
+ // Put operation should change the mode.
+ EXPECT_TRUE(PutSync(key, value, value2));
+ EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+ EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_AND_VALUES,
+ wrapper_impl()->map_state_);
std::vector<uint8_t> result;
- EXPECT_FALSE(GetSync(StdStringToUint8Vector("123"), &result));
- EXPECT_TRUE(GetSync(StdStringToUint8Vector("def"), &result));
- EXPECT_EQ(StdStringToUint8Vector("foo"), result);
- EXPECT_TRUE(GetSync(StdStringToUint8Vector("abc"), &result));
- EXPECT_EQ(StdStringToUint8Vector("bla"), result);
-
- EXPECT_FALSE(has_mock_data(kTestPrefix + std::string("123")));
- EXPECT_EQ("foo", get_mock_data(kTestPrefix + std::string("def")));
- EXPECT_EQ("bla", get_mock_data(kTestPrefix + std::string("abc")));
+ EXPECT_TRUE(GetSync(key, &result));
+ EXPECT_EQ(value, result);
+ EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_AND_VALUES,
+ wrapper_impl()->map_state_);
+
+ BlockingCommit();
+
+ // Test that the map will unload correctly
+ EXPECT_TRUE(PutSync(key, value2, value));
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
+ EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY,
+ wrapper_impl()->map_state_);
+ BlockingCommit();
+ EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY,
+ wrapper_impl()->map_state_);
+
+ // Test the map will unload right away when there are no changes.
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ EXPECT_TRUE(GetSync(key, &result));
+ EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_AND_VALUES,
+ wrapper_impl()->map_state_);
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
+ EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY,
+ wrapper_impl()->map_state_);
+}
+
+TEST_F(LevelDBWrapperImplTest, SendOldValueObservations) {
+ should_record_send_old_value_observations(true);
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ // Flush tasks on mojo thread to observe callback.
+ EXPECT_TRUE(DeleteSync(ToBytes("doesn't exist"), base::nullopt));
+ wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
+ // Flush tasks on mojo thread to observe callback.
+ EXPECT_TRUE(DeleteSync(ToBytes("doesn't exist"), base::nullopt));
+
+ ASSERT_EQ(2u, observations().size());
+ EXPECT_EQ(Observation::kSendOldValue, observations()[0].type);
+ EXPECT_FALSE(observations()[0].should_send_old_value);
+ EXPECT_EQ(Observation::kSendOldValue, observations()[1].type);
+ EXPECT_TRUE(observations()[1].should_send_old_value);
+}
+
+TEST_P(LevelDBWrapperImplParamTest, PrefixForking) {
+ std::string value3 = "value3";
+ std::string value4 = "value4";
+ std::string value5 = "value5";
+
+ // In order to test the interaction between forking and mojo calls where
+ // forking can happen in between a request and reply to the wrapper mojo
+ // service, all calls are done on the 'impl' object itself.
+
+ // Operations in the same run cycle:
+ // Fork 1 created from original
+ // Put on fork 1
+ // Fork 2 create from fork 1
+ // Put on fork 1
+ // Put on original
+ // Fork 3 created from original
+ std::unique_ptr<LevelDBWrapperImpl> fork1;
+ MockDelegate fork1_delegate;
+ std::unique_ptr<LevelDBWrapperImpl> fork2;
+ MockDelegate fork2_delegate;
+ std::unique_ptr<LevelDBWrapperImpl> fork3;
+ MockDelegate fork3_delegate;
+
+ auto options = GetDefaultTestingOptions(GetParam());
+ bool put_success1 = false;
+ bool put_success2 = false;
+ bool put_success3 = false;
+ base::RunLoop loop;
+ {
+ IncrementalBarrier barrier(loop.QuitClosure());
+
+ // Create fork 1.
+ fork1 = wrapper_impl()->ForkToNewPrefix(test_copy_prefix1_, &fork1_delegate,
+ options);
+
+ // Do a put on fork 1 and create fork 2.
+ // Note - these are 'skipping' the mojo layer, which is why the fork isn't
+ // scheduled.
+ fork1->Put(test_key2_bytes_, ToBytes(value4), test_value2_bytes_,
+ test_source_, MakeSuccessCallback(barrier.Get(), &put_success1));
+ fork2 =
+ fork1->ForkToNewPrefix(test_copy_prefix2_, &fork2_delegate, options);
+ fork1->Put(test_key2_bytes_, ToBytes(value5), ToBytes(value4), test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success2));
+
+ // Do a put on original and create fork 3, which is key-only.
+ wrapper_impl()->Put(test_key1_bytes_, ToBytes(value3), test_value1_bytes_,
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success3));
+ fork3 = wrapper_impl()->ForkToNewPrefix(
+ test_copy_prefix3_, &fork3_delegate,
+ GetDefaultTestingOptions(CacheMode::KEYS_ONLY_WHEN_POSSIBLE));
+ }
+ loop.Run();
+ EXPECT_TRUE(put_success1);
+ EXPECT_TRUE(put_success2);
+ EXPECT_TRUE(fork2.get());
+ EXPECT_TRUE(fork3.get());
+
+ EXPECT_EQ(value3, GetSyncStrUsingGetAll(wrapper_impl(), test_key1_));
+ EXPECT_EQ(test_value1_, GetSyncStrUsingGetAll(fork1.get(), test_key1_));
+ EXPECT_EQ(test_value1_, GetSyncStrUsingGetAll(fork2.get(), test_key1_));
+ EXPECT_EQ(value3, GetSyncStrUsingGetAll(fork3.get(), test_key1_));
+
+ EXPECT_EQ(test_value2_, GetSyncStrUsingGetAll(wrapper_impl(), test_key2_));
+ EXPECT_EQ(value5, GetSyncStrUsingGetAll(fork1.get(), test_key2_));
+ EXPECT_EQ(value4, GetSyncStrUsingGetAll(fork2.get(), test_key2_));
+ EXPECT_EQ(test_value2_, GetSyncStrUsingGetAll(fork3.get(), test_key2_));
+
+ BlockingCommit(delegate(), wrapper_impl());
+ BlockingCommit(&fork1_delegate, fork1.get());
+
+ // test_key1_ values.
+ EXPECT_EQ(value3, get_mock_data(test_prefix_ + test_key1_));
+ EXPECT_EQ(test_value1_, get_mock_data(test_copy_prefix1_ + test_key1_));
+ EXPECT_EQ(test_value1_, get_mock_data(test_copy_prefix2_ + test_key1_));
+ EXPECT_EQ(value3, get_mock_data(test_copy_prefix3_ + test_key1_));
+
+ // test_key2_ values.
+ EXPECT_EQ(test_value2_, get_mock_data(test_prefix_ + test_key2_));
+ EXPECT_EQ(value5, get_mock_data(test_copy_prefix1_ + test_key2_));
+ EXPECT_EQ(value4, get_mock_data(test_copy_prefix2_ + test_key2_));
+ EXPECT_EQ(test_value2_, get_mock_data(test_copy_prefix3_ + test_key2_));
+}
+
+TEST_P(LevelDBWrapperImplParamTest, PrefixForkAfterLoad) {
+ const std::string kValue = "foo";
+ const std::vector<uint8_t> kValueVec = ToBytes(kValue);
+
+ // Do a sync put so the map loads.
+ EXPECT_TRUE(PutSync(test_key1_bytes_, kValueVec, base::nullopt));
+
+ // Execute the fork.
+ MockDelegate fork1_delegate;
+ std::unique_ptr<LevelDBWrapperImpl> fork1 =
+ wrapper_impl()->ForkToNewPrefix(test_copy_prefix1_, &fork1_delegate,
+ GetDefaultTestingOptions(GetParam()));
+
+ // Check our forked state.
+ EXPECT_EQ(kValue, GetSyncStrUsingGetAll(fork1.get(), test_key1_));
+
+ BlockingCommit(delegate(), wrapper_impl());
+
+ EXPECT_EQ(kValue, get_mock_data(test_copy_prefix1_ + test_key1_));
+}
+
+namespace {
+std::string GetNewPrefix(int* i) {
+ std::string prefix = "prefix-" + base::Int64ToString(*i) + "-";
+ (*i)++;
+ return prefix;
+}
+
+struct FuzzState {
+ base::Optional<std::vector<uint8_t>> val1;
+ base::Optional<std::vector<uint8_t>> val2;
+};
+} // namespace
+
+TEST_F(LevelDBWrapperImplTest, PrefixForkingPsuedoFuzzer) {
+ const std::string kKey1 = "key1";
+ const std::vector<uint8_t> kKey1Vec = ToBytes(kKey1);
+ const std::string kKey2 = "key2";
+ const std::vector<uint8_t> kKey2Vec = ToBytes(kKey2);
+ const int kTotalWrappers = 1000;
+
+ // This tests tries to throw all possible enumartions of operations and
+ // forking at wrappers. The purpose is to hit all edge cases possible to
+ // expose any loading bugs.
+
+ std::vector<FuzzState> states(kTotalWrappers);
+ std::vector<std::unique_ptr<LevelDBWrapperImpl>> wrappers(kTotalWrappers);
+ std::vector<MockDelegate> delegates(kTotalWrappers);
+ std::list<bool> successes;
+ int curr_prefix = 0;
+
+ base::RunLoop loop;
+ {
+ IncrementalBarrier barrier(loop.QuitClosure());
+ for (int64_t i = 0; i < kTotalWrappers; i++) {
+ FuzzState& state = states[i];
+ if (!wrappers[i]) {
+ wrappers[i] = wrapper_impl()->ForkToNewPrefix(
+ GetNewPrefix(&curr_prefix), &delegates[i],
+ GetDefaultTestingOptions(CacheMode::KEYS_ONLY_WHEN_POSSIBLE));
+ }
+ int64_t forks = i;
+ if ((i % 5 == 0 || i % 6 == 0) && forks + 1 < kTotalWrappers) {
+ forks++;
+ states[forks] = state;
+ wrappers[forks] = wrappers[i]->ForkToNewPrefix(
+ GetNewPrefix(&curr_prefix), &delegates[forks],
+ GetDefaultTestingOptions(CacheMode::KEYS_AND_VALUES));
+ }
+ if (i % 13 == 0) {
+ FuzzState old_state = state;
+ state.val1 = base::nullopt;
+ successes.push_back(false);
+ wrappers[i]->Delete(
+ kKey1Vec, old_state.val1, test_source_,
+ MakeSuccessCallback(barrier.Get(), &successes.back()));
+ }
+ if (i % 4 == 0) {
+ FuzzState old_state = state;
+ state.val2 = base::make_optional<std::vector<uint8_t>>(
+ {static_cast<uint8_t>(i)});
+ successes.push_back(false);
+ wrappers[i]->Put(kKey2Vec, state.val2.value(), old_state.val2,
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &successes.back()));
+ }
+ if (i % 3 == 0) {
+ FuzzState old_state = state;
+ state.val1 = base::make_optional<std::vector<uint8_t>>(
+ {static_cast<uint8_t>(i + 5)});
+ successes.push_back(false);
+ wrappers[i]->Put(kKey1Vec, state.val1.value(), old_state.val1,
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &successes.back()));
+ }
+ if (i % 11 == 0) {
+ state.val1 = base::nullopt;
+ state.val2 = base::nullopt;
+ successes.push_back(false);
+ wrappers[i]->DeleteAll(
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &successes.back()));
+ }
+ if (i % 2 == 0 && forks + 1 < kTotalWrappers) {
+ CacheMode mode = i % 3 == 0 ? CacheMode::KEYS_AND_VALUES
+ : CacheMode::KEYS_ONLY_WHEN_POSSIBLE;
+ forks++;
+ states[forks] = state;
+ wrappers[forks] = wrappers[i]->ForkToNewPrefix(
+ GetNewPrefix(&curr_prefix), &delegates[forks],
+ GetDefaultTestingOptions(mode));
+ }
+ if (i % 3 == 0) {
+ FuzzState old_state = state;
+ state.val1 = base::make_optional<std::vector<uint8_t>>(
+ {static_cast<uint8_t>(i + 9)});
+ successes.push_back(false);
+ wrappers[i]->Put(kKey1Vec, state.val1.value(), old_state.val1,
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &successes.back()));
+ }
+ }
+ }
+ loop.Run();
+
+ // This section checks that we get the correct values when we query the
+ // wrappers (which may or may not be maintaining their own cache).
+ for (size_t i = 0; i < kTotalWrappers; i++) {
+ FuzzState& state = states[i];
+ std::vector<uint8_t> result;
+
+ // Note: this will cause all keys-only wrappers to commit.
+ std::string result1 = GetSyncStrUsingGetAll(wrappers[i].get(), kKey1);
+ std::string result2 = GetSyncStrUsingGetAll(wrappers[i].get(), kKey2);
+ EXPECT_EQ(!!state.val1, !result1.empty()) << i;
+ if (state.val1)
+ EXPECT_EQ(state.val1.value(), ToBytes(result1));
+ EXPECT_EQ(!!state.val2, !result2.empty()) << i;
+ if (state.val2)
+ EXPECT_EQ(state.val2.value(), ToBytes(result2)) << i;
+ }
+
+ // This section verifies that all wrappers have committed their changes to
+ // the database.
+ ASSERT_EQ(wrappers.size(), delegates.size());
+ size_t half = kTotalWrappers / 2;
+ for (size_t i = 0; i < half; i++) {
+ BlockingCommit(&delegates[i], wrappers[i].get());
+ }
+
+ for (size_t i = kTotalWrappers - 1; i >= half; i--) {
+ BlockingCommit(&delegates[i], wrappers[i].get());
+ }
+
+ // This section checks the data in the database itself to verify all wrappers
+ // committed changes correctly.
+ for (size_t i = 0; i < kTotalWrappers; ++i) {
+ FuzzState& state = states[i];
+
+ std::vector<uint8_t> prefix = wrappers[i]->prefix();
+ std::string key1 = ToString(prefix) + kKey1;
+ std::string key2 = ToString(prefix) + kKey2;
+ EXPECT_EQ(!!state.val1, has_mock_data(key1));
+ if (state.val1)
+ EXPECT_EQ(ToString(state.val1.value()), get_mock_data(key1));
+ EXPECT_EQ(!!state.val2, has_mock_data(key2));
+ if (state.val2)
+ EXPECT_EQ(ToString(state.val2.value()), get_mock_data(key2));
+
+ EXPECT_FALSE(wrappers[i]->has_pending_load_tasks()) << i;
+ }
}
} // namespace content
diff --git a/chromium/content/browser/loader/DEPS b/chromium/content/browser/loader/DEPS
deleted file mode 100644
index 194a58803b2..00000000000
--- a/chromium/content/browser/loader/DEPS
+++ /dev/null
@@ -1,351 +0,0 @@
-# The core loading code in this directory is being transitioned into a separate
-# Mojo networking service. See http://crbug.com/598073. The first stage is to
-# decouple the code that will be moved from the rest of content. These rules
-# help ensure that we don't add more includes, and can progressively reduce the
-# code's dependencies.
-#
-# For each file, the first section shows includes that are allowed (i.e. because
-# they are for files that will be moving as well). The second section, separated
-# by a comment, lists files that we will have to decouple.
-specific_include_rules = {
- "async_resource_handler\.(cc|h)": [
- "-content",
- "+content/browser/loader/async_resource_handler.h",
- "+content/browser/loader/downloaded_temp_file_impl.h",
- "+content/browser/loader/netlog_observer.h",
- "+content/browser/loader/resource_buffer.h",
- "+content/browser/loader/resource_controller.h",
- "+content/browser/loader/resource_dispatcher_host_impl.h",
- "+content/browser/loader/resource_handler.h",
- "+content/browser/loader/resource_message_delegate.h",
- "+content/browser/loader/resource_message_filter.h",
- "+content/browser/loader/resource_request_info_impl.h",
- "+content/browser/loader/upload_progress_tracker.h",
- "+content/common/content_export.h",
- "+content/public/common/resource_response.h",
-
- # TODO: these all have to be removed.
- "+content/public/common/content_features.h",
-
- # TODO: To be replaced by mojo.
- "+content/common/resource_messages.h",
- "+content/common/view_messages.h",
- "+content/public/common/resource_request_completion_status.h",
- ],
- "downloaded_temp_file_impl\.(cc|h)": [
- "-content",
- "+content/browser/loader/downloaded_temp_file_impl.h",
- "+content/browser/loader/resource_dispatcher_host_impl.h",
- "+content/common/content_export.h",
- "+content/public/common/url_loader_factory.mojom.h"
- ],
- "resource_buffer.*\.(cc|h)": [
- "-content",
- "+content/browser/loader/resource_buffer.h",
- "+content/common/content_export.h",
- ],
- "global_routing_id\.h": [
- "-content",
- ],
- "layered_resource_handler\.(cc|h)": [
- "-content",
- "+content/browser/loader/layered_resource_handler.h",
- "+content/browser/loader/resource_controller.h",
- "+content/browser/loader/resource_handler.h",
- "+content/common/content_export.h",
- ],
- "mojo_async_resource_handler\.(cc|h)": [
- "-content",
- "+content/browser/loader/async_resource_handler.h",
- "+content/browser/loader/downloaded_temp_file_impl.h",
- "+content/browser/loader/mojo_async_resource_handler.h",
- "+content/browser/loader/netlog_observer.h",
- "+content/browser/loader/resource_controller.h",
- "+content/browser/loader/resource_dispatcher_host_impl.h",
- "+content/browser/loader/resource_handler.h",
- "+content/browser/loader/resource_request_info_impl.h",
- "+content/browser/loader/resource_scheduler.h",
- "+content/browser/loader/upload_progress_tracker.h",
- "+content/common/content_export.h",
- "+content/public/browser/global_request_id.h",
- "+content/public/common/resource_request_completion_status.h",
- "+content/public/common/resource_response.h",
- "+content/public/common/resource_type.h",
- "+content/public/common/url_loader.mojom.h",
- ],
- "mojo_async_resource_handler_unittest\.cc": [
- "-content",
- "+content/browser/loader/mock_resource_loader.h",
- "+content/browser/loader/mojo_async_resource_handler.h",
- "+content/browser/loader/resource_controller.h",
- "+content/browser/loader/resource_dispatcher_host_impl.h",
- "+content/browser/loader/resource_request_info_impl.h",
- "+content/browser/loader/resource_scheduler.h",
- "+content/public/browser/appcache_service.h",
- "+content/public/browser/navigation_data.h",
- "+content/public/browser/resource_context.h",
- "+content/public/browser/resource_dispatcher_host_delegate.h",
- "+content/public/browser/resource_throttle.h",
- "+content/public/browser/stream_info.h",
- "+content/public/common/previews_state.h",
- "+content/public/common/resource_request.h",
- "+content/public/common/resource_request_completion_status.h",
- "+content/public/common/resource_response.h",
- "+content/public/common/resource_type.h",
- "+content/public/common/url_loader.mojom.h",
- "+content/public/common/url_loader_factory.mojom.h",
- "+content/public/test/test_browser_context.h",
- "+content/public/test/test_browser_thread_bundle.h",
- "+content/public/test/test_url_loader_client.h",
- ],
- "netlog_observer\.(cc|h)": [
- "-content",
- "+content/browser/loader/netlog_observer.h",
- "+content/browser/loader/resource_request_info_impl.h",
- "+content/public/common/resource_response.h",
-
- # TODO: These all have to be removed.
- "+content/public/browser/browser_thread.h", # Only for DCHECK.
- "+content/public/common/resource_devtools_info.h",
- ],
- "resource_dispatcher_host_impl\.(cc|h)": [
- "-content",
- "+content/browser/loader/async_resource_handler.h",
- "+content/browser/loader/cross_site_document_resource_handler.h",
- "+content/browser/loader/global_routing_id.h",
- "+content/browser/loader/loader_delegate.h",
- "+content/browser/loader/mojo_async_resource_handler.h",
- "+content/browser/loader/null_resource_controller.h",
- "+content/browser/loader/resource_dispatcher_host_impl.h",
- "+content/browser/loader/resource_loader.h",
- "+content/browser/loader/resource_loader_delegate.h",
- "+content/browser/loader/resource_message_filter.h",
- "+content/browser/loader/resource_request_info_impl.h",
- "+content/browser/loader/resource_requester_info.h",
- "+content/browser/loader/resource_scheduler.h",
- "+content/browser/loader/stream_resource_handler.h",
- "+content/browser/loader/sync_resource_handler.h",
- "+content/browser/loader/throttling_resource_handler.h",
- "+content/browser/loader/wake_lock_resource_throttle.h",
- "+content/common/resource_request_body.h",
- "+content/public/browser/global_request_id.h",
- "+content/public/browser/resource_dispatcher_host.h",
- "+content/public/browser/resource_dispatcher_host_delegate.h",
- "+content/public/browser/resource_request_info.h",
- "+content/public/browser/resource_throttle.h",
- "+content/public/common/previews_state.h",
- "+content/public/common/resource_request_body.h",
- "+content/public/common/url_loader.mojom.h",
-
- # TODO: These all have to be removed.
- "+content/browser/appcache/appcache_interceptor.h",
- "+content/browser/appcache/appcache_navigation_handle_core.h",
- "+content/browser/appcache/chrome_appcache_service.h",
- "+content/browser/bad_message.h",
- "+content/browser/blob_storage/chrome_blob_storage_context.h",
- "+content/browser/browsing_data/clear_site_data_throttle.h",
- "+content/browser/child_process_security_policy_impl.h",
- "+content/browser/frame_host/navigation_request_info.h",
- "+content/browser/loader/cross_site_resource_handler.h",
- "+content/browser/loader/detachable_resource_handler.h",
- "+content/browser/loader/intercepting_resource_handler.h",
- "+content/browser/loader/mime_sniffing_resource_handler.h",
- "+content/browser/loader/navigation_resource_handler.h",
- "+content/browser/loader/navigation_resource_throttle.h",
- "+content/browser/loader/navigation_url_loader_impl_core.h",
- "+content/browser/loader/redirect_to_file_resource_handler.h",
- "+content/browser/loader/upload_data_stream_builder.h",
- "+content/browser/resource_context_impl.h",
- "+content/browser/service_worker/foreign_fetch_request_handler.h",
- "+content/browser/service_worker/link_header_support.h",
- "+content/browser/service_worker/service_worker_context_wrapper.h",
- "+content/browser/service_worker/service_worker_navigation_handle_core.h",
- "+content/browser/service_worker/service_worker_request_handler.h",
- "+content/browser/streams/stream.h",
- "+content/browser/streams/stream_context.h",
- "+content/browser/streams/stream_registry.h",
- "+content/common/content_export.h",
- "+content/common/net/url_request_service_worker_data.h",
- "+content/common/site_isolation_policy.h",
- "+content/public/browser/browser_thread.h",
- "+content/public/browser/navigation_ui_data.h",
- "+content/public/browser/plugin_service.h",
- "+content/public/browser/resource_request_details.h",
- "+content/public/browser/stream_handle.h",
- "+content/public/browser/stream_info.h",
- "+content/public/common/browser_side_navigation_policy.h",
- "+content/public/common/content_features.h",
- "+content/public/common/content_switches.h",
- "+content/public/common/request_context_type.h",
- "+content/public/common/resource_type.h",
-
- # TODO: To be replaced by mojo.
- "+content/common/resource_messages.h",
- "+content/common/view_messages.h",
- "+content/public/common/resource_request.h",
- "+content/public/common/resource_request_completion_status.h",
- ],
- "resource_handler\.(cc|h)": [
- "-content",
- "+content/browser/loader/resource_controller.h",
- "+content/browser/loader/resource_handler.h",
- "+content/browser/loader/resource_request_info_impl.h",
- "+content/common/content_export.h",
- ],
- "resource_loader\.(cc|h)": [
- "-content",
- "+content/browser/loader/resource_controller.h",
- "+content/browser/loader/resource_handler.h",
- "+content/browser/loader/resource_loader.h",
- "+content/browser/loader/resource_loader_delegate.h",
- "+content/browser/loader/resource_request_info_impl.h",
- "+content/browser/ssl/ssl_client_auth_handler.h",
- "+content/browser/ssl/ssl_error_handler.h",
- "+content/common/content_export.h",
- "+content/common/loader_util.h",
- "+content/public/browser/resource_dispatcher_host_login_delegate.h",
- "+content/public/common/browser_side_navigation_policy.h",
- "+content/public/common/previews_state.h",
- "+content/public/common/resource_response.h",
- "+content/public/common/resource_type.h",
-
- # TODO: these all have to be removed.
- "+content/browser/appcache/appcache_interceptor.h",
- "+content/browser/child_process_security_policy_impl.h",
- "+content/browser/loader/cross_site_resource_handler.h",
- "+content/browser/loader/detachable_resource_handler.h",
- "+content/browser/service_worker/service_worker_request_handler.h",
- "+content/browser/service_worker/service_worker_response_info.h",
- "+content/browser/ssl/ssl_manager.h",
- "+content/public/common/content_client.h",
- "+content/public/common/content_switches.h",
- ],
- "resource_handler_delegate\.h": [
- "-content",
- ],
- "resource_request_info_impl\.(cc|h)": [
- "-content",
- "+content/browser/blob_storage/chrome_blob_storage_context.h",
- "+content/browser/loader/global_routing_id.h",
- "+content/browser/loader/resource_handler.h",
- "+content/browser/loader/resource_message_filter.h",
- "+content/browser/loader/resource_request_info_impl.h",
- "+content/browser/loader/resource_requester_info.h",
- "+content/common/content_export.h",
- "+content/public/browser/global_request_id.h",
- "+content/public/browser/resource_request_info.h",
- "+content/public/common/previews_state.h",
- "+content/public/common/referrer.h",
- "+content/public/common/resource_request_body.h",
- "+content/public/common/resource_type.h",
- "+content/public/common/url_loader.mojom.h",
-
- # TODO: these all have to be removed.
- "+content/browser/frame_host/frame_tree_node.h",
- "+content/browser/web_contents/web_contents_impl.h",
- "+content/common/net/url_request_service_worker_data.h",
- "+content/common/net/url_request_user_data.h",
- "+content/public/browser/browser_thread.h",
- "+content/public/browser/navigation_ui_data.h",
- "+content/public/common/browser_side_navigation_policy.h",
- "+content/public/common/process_type.h",
- ],
- "resource_requester_info\.(cc|h)": [
- "-content",
- "+content/browser/loader/resource_controller.h",
- "+content/browser/loader/resource_requester_info.h",
- "+content/common/content_export.h",
- "+content/public/browser/resource_context.h",
- "+content/public/common/resource_type.h",
-
- # TODO: these all have to be removed.
- "+content/browser/appcache/chrome_appcache_service.h",
- "+content/browser/blob_storage/chrome_blob_storage_context.h",
- "+content/browser/service_worker/service_worker_context_wrapper.h",
- "+content/public/browser/browser_thread.h",
- "+content/public/common/browser_side_navigation_policy.h",
- ],
- "resource_scheduler\.(cc|h)": [
- "-content",
- "+content/browser/loader/resource_controller.h",
- "+content/browser/loader/resource_scheduler.h",
- "+content/common/content_export.h",
- "+content/public/browser/resource_request_info.h",
- "+content/public/browser/resource_throttle.h",
-
- # TODO: To be replaced by mojo.
- "+content/common/resource_messages.h",
- ],
- "resource_scheduler_filter\.(cc|h)": [
- "-content",
- "+content/browser/loader/resource_dispatcher_host_impl.h",
- "+content/browser/loader/resource_scheduler.h",
- "+content/browser/loader/resource_scheduler_filter.h",
-
- # TODO: To be replaced by mojo.
- "+content/common/frame_messages.h",
- "+content/common/view_messages.h",
- "+content/public/browser/browser_message_filter.h",
- ],
- "sync_resource_handler\.(cc|h)": [
- "-content",
- "+content/browser/loader/netlog_observer.h",
- "+content/browser/loader/resource_controller.h",
- "+content/browser/loader/resource_dispatcher_host_impl.h",
- "+content/browser/loader/resource_handler.h",
- "+content/browser/loader/resource_request_info_impl.h",
- "+content/browser/loader/sync_resource_handler.h",
- "+content/public/browser/resource_dispatcher_host_delegate.h",
- "+content/public/browser/resource_request_info.h",
- "+content/public/common/resource_response.h",
-
-
- # TODO: To be replaced by mojo.
- "+content/common/resource_messages.h",
- ],
- "upload_progress_tracker\.(cc|h)": [
- "-content",
- "+content/browser/loader/upload_progress_tracker.h",
- "+content/common/content_export.h",
- ],
- "url_loader_factory_impl\.(cc|h)": [
- "-content",
- "+content/browser/loader/resource_dispatcher_host_impl.h",
- "+content/browser/loader/resource_requester_info.h",
- "+content/browser/loader/url_loader_factory_impl.h",
- "+content/common/content_export.h",
- "+content/public/common/resource_request.h",
- "+content/public/common/url_loader.mojom.h",
- "+content/public/common/url_loader_factory.mojom.h",
- ],
- "url_loader_factory_impl_unittest\.cc": [
- "-content",
- "+content/browser/child_process_security_policy_impl.h",
- "+content/browser/loader/mojo_async_resource_handler.h",
- "+content/browser/loader/resource_dispatcher_host_impl.h",
- "+content/browser/loader/resource_message_filter.h",
- "+content/browser/loader/resource_request_info_impl.h",
- "+content/browser/loader/url_loader_factory_impl.h",
- "+content/browser/loader_delegate_impl.h",
- "+content/public/browser/resource_context.h",
- "+content/public/browser/resource_dispatcher_host_delegate.h",
- "+content/public/common/content_paths.h",
- "+content/public/common/resource_request.h",
- "+content/public/common/resource_request_completion_status.h",
- "+content/public/common/url_loader.mojom.h",
- "+content/public/common/url_loader_factory.mojom.h",
- "+content/public/test/test_browser_context.h",
- "+content/public/test/test_browser_thread_bundle.h",
- "+content/public/test/test_url_loader_client.h",
-
- #TODO: To be removed when PlzNavigate lands.
- "+content/browser/loader/navigation_resource_throttle.h"
- ],
- "wake_lock_resource_throttle\.(cc|h)": [
- "-content",
- "+content/browser/loader/wake_lock_resource_throttle.h",
- "+content/browser/service_manager/service_manager_context.h",
- "+content/public/browser/browser_thread.h",
- "+content/public/browser/resource_throttle.h",
- ],
-}
diff --git a/chromium/content/browser/loader/async_resource_handler.cc b/chromium/content/browser/loader/async_resource_handler.cc
index 0dee7154a93..aeea9dc4b49 100644
--- a/chromium/content/browser/loader/async_resource_handler.cc
+++ b/chromium/content/browser/loader/async_resource_handler.cc
@@ -7,7 +7,6 @@
#include <algorithm>
#include <vector>
-#include "base/command_line.h"
#include "base/containers/hash_tables.h"
#include "base/debug/alias.h"
#include "base/logging.h"
@@ -15,23 +14,22 @@
#include "base/memory/ptr_util.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "content/browser/loader/resource_buffer.h"
#include "content/browser/loader/resource_controller.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/upload_progress_tracker.h"
#include "content/common/resource_messages.h"
#include "content/common/view_messages.h"
-#include "content/public/common/resource_request_completion_status.h"
+#include "content/network/upload_progress_tracker.h"
#include "content/public/common/resource_response.h"
#include "ipc/ipc_message_macros.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/upload_progress.h"
#include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
using base::TimeDelta;
using base::TimeTicks;
@@ -39,38 +37,22 @@ using base::TimeTicks;
namespace content {
namespace {
-static int kBufferSize = 1024 * 512;
-static int kMinAllocationSize = 1024 * 4;
-static int kMaxAllocationSize = 1024 * 32;
-
-void GetNumericArg(const std::string& name, int* result) {
- const std::string& value =
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(name);
- if (!value.empty())
- base::StringToInt(value, result);
-}
-
-void InitializeResourceBufferConstants() {
- static bool did_init = false;
- if (did_init)
- return;
- did_init = true;
-
- GetNumericArg("resource-buffer-size", &kBufferSize);
- GetNumericArg("resource-buffer-min-allocation-size", &kMinAllocationSize);
- GetNumericArg("resource-buffer-max-allocation-size", &kMaxAllocationSize);
-}
+static int g_async_loader_buffer_size = 1024 * 512;
+static int g_async_loader_min_buffer_allocation_size = 1024 * 4;
+static int g_async_loader_max_buffer_allocation_size = 1024 * 32;
} // namespace
-class DependentIOBuffer : public net::WrappedIOBuffer {
+// Used to write into an existing IOBuffer at a given offset. This is
+// very similar to DependentIOBufferForRedirectToFile and
+// DependentIOBufferForMimeSniffing but not identical.
+class DependentIOBufferForAsyncLoading : public net::WrappedIOBuffer {
public:
- DependentIOBuffer(ResourceBuffer* backing, char* memory)
- : net::WrappedIOBuffer(memory),
- backing_(backing) {
- }
+ DependentIOBufferForAsyncLoading(ResourceBuffer* backing, char* memory)
+ : net::WrappedIOBuffer(memory), backing_(backing) {}
+
private:
- ~DependentIOBuffer() override {}
+ ~DependentIOBufferForAsyncLoading() override {}
scoped_refptr<ResourceBuffer> backing_;
};
@@ -95,6 +77,19 @@ AsyncResourceHandler::~AsyncResourceHandler() {
rdh_->FinishedWithResourcesForRequest(request());
}
+void AsyncResourceHandler::InitializeResourceBufferConstants() {
+ static bool did_init = false;
+ if (did_init)
+ return;
+ did_init = true;
+
+ GetNumericArg("resource-buffer-size", &g_async_loader_buffer_size);
+ GetNumericArg("resource-buffer-min-allocation-size",
+ &g_async_loader_min_buffer_allocation_size);
+ GetNumericArg("resource-buffer-max-allocation-size",
+ &g_async_loader_max_buffer_allocation_size);
+}
+
bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(AsyncResourceHandler, message)
@@ -220,7 +215,7 @@ void AsyncResourceHandler::OnWillStart(
if (GetRequestInfo()->is_upload_progress_enabled() &&
request()->has_upload()) {
- upload_progress_tracker_ = base::MakeUnique<UploadProgressTracker>(
+ upload_progress_tracker_ = std::make_unique<UploadProgressTracker>(
FROM_HERE,
base::BindRepeating(&AsyncResourceHandler::SendUploadProgress,
base::Unretained(this)),
@@ -249,7 +244,7 @@ void AsyncResourceHandler::OnWillRead(
char* memory = buffer_->Allocate(&allocation_size_);
CHECK(memory);
- *buf = new DependentIOBuffer(buffer_.get(), memory);
+ *buf = new DependentIOBufferForAsyncLoading(buffer_.get(), memory);
*buf_size = allocation_size_;
controller->Resume();
@@ -290,8 +285,7 @@ void AsyncResourceHandler::OnReadCompleted(
return;
}
filter->Send(new ResourceMsg_SetDataBuffer(
- GetRequestID(), handle, buffer_->GetSharedMemory().mapped_size(),
- filter->peer_pid()));
+ GetRequestID(), handle, buffer_->GetSharedMemory().mapped_size()));
sent_data_buffer_msg_ = true;
}
@@ -319,7 +313,7 @@ void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) {
}
void AsyncResourceHandler::OnResponseCompleted(
- const net::URLRequestStatus& status,
+ const net::URLRequestStatus& request_status,
std::unique_ptr<ResourceController> controller) {
ResourceMessageFilter* filter = GetFilter();
if (!filter) {
@@ -346,25 +340,23 @@ void AsyncResourceHandler::OnResponseCompleted(
// WebURLLoaderImpl::OnCompletedRequest that routes this message to a WebCore
// ResourceHandleInternal which asserts on its state and crashes. By crashing
// when the message is sent, we should get better crash reports.
- CHECK(status.status() != net::URLRequestStatus::SUCCESS ||
+ CHECK(request_status.status() != net::URLRequestStatus::SUCCESS ||
sent_received_response_msg_);
- int error_code = status.error();
+ int error_code = request_status.error();
- DCHECK(status.status() != net::URLRequestStatus::IO_PENDING);
+ DCHECK(request_status.status() != net::URLRequestStatus::IO_PENDING);
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = error_code;
- request_complete_data.exists_in_cache = request()->response_info().was_cached;
- request_complete_data.completion_time = TimeTicks::Now();
- request_complete_data.encoded_data_length =
- request()->GetTotalReceivedBytes();
- request_complete_data.encoded_body_length = request()->GetRawBodyBytes();
- request_complete_data.decoded_body_length = total_read_body_bytes_;
- filter->Send(
- new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data));
+ network::URLLoaderCompletionStatus loader_status;
+ loader_status.error_code = error_code;
+ loader_status.exists_in_cache = request()->response_info().was_cached;
+ loader_status.completion_time = TimeTicks::Now();
+ loader_status.encoded_data_length = request()->GetTotalReceivedBytes();
+ loader_status.encoded_body_length = request()->GetRawBodyBytes();
+ loader_status.decoded_body_length = total_read_body_bytes_;
+ filter->Send(new ResourceMsg_RequestComplete(GetRequestID(), loader_status));
- if (status.is_success())
+ if (request_status.is_success())
RecordHistogram();
controller->Resume();
}
@@ -376,9 +368,9 @@ bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() {
return true;
buffer_ = new ResourceBuffer();
- return buffer_->Initialize(kBufferSize,
- kMinAllocationSize,
- kMaxAllocationSize);
+ return buffer_->Initialize(g_async_loader_buffer_size,
+ g_async_loader_min_buffer_allocation_size,
+ g_async_loader_max_buffer_allocation_size);
}
void AsyncResourceHandler::ResumeIfDeferred() {
diff --git a/chromium/content/browser/loader/async_resource_handler.h b/chromium/content/browser/loader/async_resource_handler.h
index a3250bb57a3..1ddccd83428 100644
--- a/chromium/content/browser/loader/async_resource_handler.h
+++ b/chromium/content/browser/loader/async_resource_handler.h
@@ -74,6 +74,7 @@ class CONTENT_EXPORT AsyncResourceHandler : public ResourceHandler,
int CalculateEncodedBodyLengthToReport();
void RecordHistogram();
void SendUploadProgress(const net::UploadProgress& progress);
+ static void InitializeResourceBufferConstants();
scoped_refptr<ResourceBuffer> buffer_;
ResourceDispatcherHostImpl* rdh_;
diff --git a/chromium/content/browser/loader/async_resource_handler_browsertest.cc b/chromium/content/browser/loader/async_resource_handler_browsertest.cc
index 36b90ed76df..9b385549538 100644
--- a/chromium/content/browser/loader/async_resource_handler_browsertest.cc
+++ b/chromium/content/browser/loader/async_resource_handler_browsertest.cc
@@ -65,7 +65,14 @@ std::unique_ptr<net::test_server::HttpResponse> HandlePostAndRedirectURLs(
} // namespace
-class AsyncResourceHandlerBrowserTest
+// https://crbug.com/788748
+#if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
+#define MAYBE_AsyncResourceHandlerBrowserTest \
+ DISABLED_AsyncResourceHandlerBrowserTest
+#else
+#define MAYBE_AsyncResourceHandlerBrowserTest AsyncResourceHandlerBrowserTest
+#endif // defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
+class MAYBE_AsyncResourceHandlerBrowserTest
: public ContentBrowserTest,
public testing::WithParamInterface<bool> {
void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -76,7 +83,7 @@ class AsyncResourceHandlerBrowserTest
}
};
-IN_PROC_BROWSER_TEST_P(AsyncResourceHandlerBrowserTest, UploadProgress) {
+IN_PROC_BROWSER_TEST_P(MAYBE_AsyncResourceHandlerBrowserTest, UploadProgress) {
net::EmbeddedTestServer* test_server = embedded_test_server();
test_server->RegisterRequestHandler(
base::Bind(&HandlePostAndRedirectURLs, kPostPath));
@@ -93,7 +100,7 @@ IN_PROC_BROWSER_TEST_P(AsyncResourceHandlerBrowserTest, UploadProgress) {
EXPECT_EQ(js_result, "success");
}
-IN_PROC_BROWSER_TEST_P(AsyncResourceHandlerBrowserTest,
+IN_PROC_BROWSER_TEST_P(MAYBE_AsyncResourceHandlerBrowserTest,
UploadProgressRedirect) {
net::EmbeddedTestServer* test_server = embedded_test_server();
test_server->RegisterRequestHandler(
@@ -111,8 +118,8 @@ IN_PROC_BROWSER_TEST_P(AsyncResourceHandlerBrowserTest,
EXPECT_EQ(js_result, "success");
}
-INSTANTIATE_TEST_CASE_P(AsyncResourceHandlerBrowserTest,
- AsyncResourceHandlerBrowserTest,
+INSTANTIATE_TEST_CASE_P(MAYBE_AsyncResourceHandlerBrowserTest,
+ MAYBE_AsyncResourceHandlerBrowserTest,
::testing::Values(false, true));
} // namespace content
diff --git a/chromium/content/browser/loader/async_resource_handler_unittest.cc b/chromium/content/browser/loader/async_resource_handler_unittest.cc
index d37a5831e73..6e5fdc46c56 100644
--- a/chromium/content/browser/loader/async_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/async_resource_handler_unittest.cc
@@ -50,6 +50,7 @@
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"
@@ -158,47 +159,47 @@ class AsyncResourceHandlerTest : public ::testing::Test,
void CreateRequestWithResponseDataSize(size_t response_data_size) {
test_job_factory_.SetProtocolHandler(
- "test", base::MakeUnique<TestProtocolHandler>(response_data_size));
+ "test", std::make_unique<TestProtocolHandler>(response_data_size));
context_.set_job_factory(&test_job_factory_);
context_.Init();
std::unique_ptr<net::URLRequest> request =
context_.CreateRequest(GURL("test:test"), net::DEFAULT_PRIORITY,
nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
- resource_context_ = base::MakeUnique<MockResourceContext>(&context_);
+ resource_context_ = std::make_unique<MockResourceContext>(&context_);
filter_ =
new RecordingResourceMessageFilter(resource_context_.get(), &context_);
ResourceRequestInfoImpl* info = new ResourceRequestInfoImpl(
filter_->requester_info_for_test(),
- 0, // route_id
- -1, // frame_tree_node_id
- 0, // origin_pid
- 0, // request_id
- 0, // render_frame_id
- false, // is_main_frame
- RESOURCE_TYPE_IMAGE, // resource_type
- ui::PAGE_TRANSITION_LINK, // transition_type
- false, // should_replace_current_entry
- false, // is_download
- false, // is_stream
- false, // allow_download
- false, // has_user_gesture
- false, // enable load timing
- false, // enable upload progress
- false, // do_not_prompt_for_login
- false, // keep_alive
- blink::kWebReferrerPolicyDefault, // referrer_policy
- blink::kWebPageVisibilityStateVisible, // visibility_state
- resource_context_.get(), // context
- false, // report_raw_headers
- true, // is_async
- PREVIEWS_OFF, // previews_state
- nullptr, // body
- false); // initiated_in_secure_context
+ 0, // route_id
+ -1, // frame_tree_node_id
+ 0, // origin_pid
+ 0, // request_id
+ 0, // render_frame_id
+ false, // is_main_frame
+ RESOURCE_TYPE_IMAGE, // resource_type
+ ui::PAGE_TRANSITION_LINK, // transition_type
+ false, // should_replace_current_entry
+ false, // is_download
+ false, // is_stream
+ false, // allow_download
+ false, // has_user_gesture
+ false, // enable load timing
+ false, // enable upload progress
+ false, // do_not_prompt_for_login
+ false, // keep_alive
+ blink::kWebReferrerPolicyDefault, // referrer_policy
+ blink::mojom::PageVisibilityState::kVisible, // visibility_state
+ resource_context_.get(), // context
+ false, // report_raw_headers
+ true, // is_async
+ PREVIEWS_OFF, // previews_state
+ nullptr, // body
+ false); // initiated_in_secure_context
info->AssociateWithRequest(request.get());
std::unique_ptr<AsyncResourceHandler> handler =
- base::MakeUnique<AsyncResourceHandler>(request.get(), &rdh_);
- loader_ = base::MakeUnique<ResourceLoader>(
- std::move(request), std::move(handler), this);
+ std::make_unique<AsyncResourceHandler>(request.get(), &rdh_);
+ loader_ = std::make_unique<ResourceLoader>(std::move(request),
+ std::move(handler), this);
}
void StartRequestAndWaitWithResponseDataSize(size_t response_data_size) {
@@ -267,12 +268,10 @@ TEST_F(AsyncResourceHandlerTest, OneChunkLengths) {
ASSERT_EQ(ResourceMsg_RequestComplete::ID, messages[3]->type());
ResourceMsg_RequestComplete::Param completion_params;
ResourceMsg_RequestComplete::Read(messages[3].get(), &completion_params);
- ResourceRequestCompletionStatus completion_status =
- std::get<1>(completion_params);
+ network::URLLoaderCompletionStatus status = std::get<1>(completion_params);
- EXPECT_EQ(TotalReceivedBytes(kDataSize),
- completion_status.encoded_data_length);
- EXPECT_EQ(kDataSize, completion_status.encoded_body_length);
+ EXPECT_EQ(TotalReceivedBytes(kDataSize), status.encoded_data_length);
+ EXPECT_EQ(kDataSize, status.encoded_body_length);
}
TEST_F(AsyncResourceHandlerTest, TwoChunksLengths) {
@@ -297,11 +296,9 @@ TEST_F(AsyncResourceHandlerTest, TwoChunksLengths) {
ASSERT_EQ(ResourceMsg_RequestComplete::ID, messages[4]->type());
ResourceMsg_RequestComplete::Param completion_params;
ResourceMsg_RequestComplete::Read(messages[4].get(), &completion_params);
- ResourceRequestCompletionStatus completion_status =
- std::get<1>(completion_params);
- EXPECT_EQ(TotalReceivedBytes(kDataSize),
- completion_status.encoded_data_length);
- EXPECT_EQ(kDataSize, completion_status.encoded_body_length);
+ network::URLLoaderCompletionStatus status = std::get<1>(completion_params);
+ EXPECT_EQ(TotalReceivedBytes(kDataSize), status.encoded_data_length);
+ EXPECT_EQ(kDataSize, status.encoded_body_length);
}
} // namespace
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 ff3f1423c00..7f278e8f836 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
@@ -495,7 +495,8 @@ class CrossSiteDocumentResourceHandlerTest
true, // is_main_frame
true, // allow_download
true, // is_async
- PREVIEWS_OFF); // previews_state
+ PREVIEWS_OFF, // previews_state
+ nullptr); // navigation_ui_data
request_->set_initiator(url::Origin::Create(GURL(initiator_origin)));
// Create a sink handler to capture results.
diff --git a/chromium/content/browser/loader/cross_site_resource_handler_browsertest.cc b/chromium/content/browser/loader/cross_site_resource_handler_browsertest.cc
index 2e986ad1ed6..07d00e511a7 100644
--- a/chromium/content/browser/loader/cross_site_resource_handler_browsertest.cc
+++ b/chromium/content/browser/loader/cross_site_resource_handler_browsertest.cc
@@ -57,7 +57,7 @@ class TestResourceDispatcherHostDelegate
ASSERT_FALSE(throttle_created_);
throttle_created_ = true;
- throttles->push_back(base::MakeUnique<CallbackRunningResourceThrottle>(
+ throttles->push_back(std::make_unique<CallbackRunningResourceThrottle>(
request, this, run_on_start_));
}
}
diff --git a/chromium/content/browser/loader/detachable_resource_handler.cc b/chromium/content/browser/loader/detachable_resource_handler.cc
index 00420872b33..d68f8057c83 100644
--- a/chromium/content/browser/loader/detachable_resource_handler.cc
+++ b/chromium/content/browser/loader/detachable_resource_handler.cc
@@ -8,7 +8,6 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "content/browser/loader/null_resource_controller.h"
#include "content/browser/loader/resource_controller.h"
@@ -82,7 +81,7 @@ DetachableResourceHandler::DetachableResourceHandler(
DetachableResourceHandler::~DetachableResourceHandler() {
// Cleanup back-pointer stored on the request info.
- GetRequestInfo()->set_detachable_handler(NULL);
+ GetRequestInfo()->set_detachable_handler(nullptr);
}
void DetachableResourceHandler::SetDelegate(Delegate* delegate) {
@@ -103,7 +102,7 @@ void DetachableResourceHandler::Detach() {
// TODO(mmenke): Get rid of NullResourceController and do something more
// reasonable.
next_handler_->OnResponseCompleted(
- status, base::MakeUnique<NullResourceController>(&was_resumed));
+ status, std::make_unique<NullResourceController>(&was_resumed));
DCHECK(was_resumed);
// If |next_handler_| were to defer its shutdown in OnResponseCompleted,
// this would destroy it anyway. Fortunately, AsyncResourceHandler never
@@ -166,7 +165,7 @@ void DetachableResourceHandler::OnRequestRedirected(
HoldController(std::move(controller));
next_handler_->OnRequestRedirected(redirect_info, response,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void DetachableResourceHandler::OnResponseStarted(
@@ -181,7 +180,7 @@ void DetachableResourceHandler::OnResponseStarted(
HoldController(std::move(controller));
next_handler_->OnResponseStarted(response,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void DetachableResourceHandler::OnWillStart(
@@ -195,7 +194,7 @@ void DetachableResourceHandler::OnWillStart(
}
HoldController(std::move(controller));
- next_handler_->OnWillStart(url, base::MakeUnique<Controller>(this));
+ next_handler_->OnWillStart(url, std::make_unique<Controller>(this));
}
void DetachableResourceHandler::OnWillRead(
@@ -215,7 +214,7 @@ void DetachableResourceHandler::OnWillRead(
parent_read_buffer_size_ = buf_size;
HoldController(std::move(controller));
- next_handler_->OnWillRead(buf, buf_size, base::MakeUnique<Controller>(this));
+ next_handler_->OnWillRead(buf, buf_size, std::make_unique<Controller>(this));
}
void DetachableResourceHandler::OnReadCompleted(
@@ -230,16 +229,12 @@ void DetachableResourceHandler::OnReadCompleted(
HoldController(std::move(controller));
next_handler_->OnReadCompleted(bytes_read,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void DetachableResourceHandler::OnResponseCompleted(
const net::URLRequestStatus& status,
std::unique_ptr<ResourceController> controller) {
- UMA_HISTOGRAM_MEDIUM_TIMES(
- "Net.DetachableResourceHandler.Duration",
- base::TimeTicks::Now() - request()->creation_time());
-
// No DCHECK(!is_deferred_) as the request may have been cancelled while
// deferred.
@@ -252,7 +247,7 @@ void DetachableResourceHandler::OnResponseCompleted(
HoldController(std::move(controller));
next_handler_->OnResponseCompleted(status,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) {
diff --git a/chromium/content/browser/loader/detachable_resource_handler_unittest.cc b/chromium/content/browser/loader/detachable_resource_handler_unittest.cc
index 0c1f12d51d1..a64eb433590 100644
--- a/chromium/content/browser/loader/detachable_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/detachable_resource_handler_unittest.cc
@@ -63,26 +63,27 @@ class DetachableResourceHandlerTest
TRAFFIC_ANNOTATION_FOR_TESTS)) {
ResourceRequestInfo::AllocateForTesting(request_.get(),
RESOURCE_TYPE_MAIN_FRAME,
- nullptr, // context
- 0, // render_process_id
- 0, // render_view_id
- 0, // render_frame_id
- true, // is_main_frame
- true, // allow_download
- true, // is_async
- PREVIEWS_OFF); // previews_state
+ nullptr, // context
+ 0, // render_process_id
+ 0, // render_view_id
+ 0, // render_frame_id
+ true, // is_main_frame
+ true, // allow_download
+ true, // is_async
+ PREVIEWS_OFF, // previews_state
+ nullptr); // navigation_ui_data
std::unique_ptr<TestResourceHandler> test_handler;
if (GetParam() != DetachPhase::DETACHED_FROM_CREATION) {
- test_handler = base::MakeUnique<TestResourceHandler>();
+ test_handler = std::make_unique<TestResourceHandler>();
test_handler_ = test_handler->GetWeakPtr();
}
// TODO(mmenke): This file currently has no timeout tests. Should it?
- detachable_handler_ = base::MakeUnique<DetachableResourceHandler>(
+ detachable_handler_ = std::make_unique<DetachableResourceHandler>(
request_.get(), base::TimeDelta::FromMinutes(30),
std::move(test_handler));
mock_loader_ =
- base::MakeUnique<MockResourceLoader>(detachable_handler_.get());
+ std::make_unique<MockResourceLoader>(detachable_handler_.get());
}
// If the DetachableResourceHandler is supposed to detach the next handler at
diff --git a/chromium/content/browser/loader/downloaded_temp_file_impl.cc b/chromium/content/browser/loader/downloaded_temp_file_impl.cc
index 878e3e2eac1..7bbb539d181 100644
--- a/chromium/content/browser/loader/downloaded_temp_file_impl.cc
+++ b/chromium/content/browser/loader/downloaded_temp_file_impl.cc
@@ -15,7 +15,7 @@ mojom::DownloadedTempFilePtr DownloadedTempFileImpl::Create(int child_id,
int request_id) {
mojo::InterfacePtr<mojom::DownloadedTempFile> ptr;
mojo::MakeStrongBinding(
- base::MakeUnique<DownloadedTempFileImpl>(child_id, request_id),
+ std::make_unique<DownloadedTempFileImpl>(child_id, request_id),
mojo::MakeRequest(&ptr));
return ptr;
}
diff --git a/chromium/content/browser/loader/intercepting_resource_handler.cc b/chromium/content/browser/loader/intercepting_resource_handler.cc
index f74db04137f..d1b2ccc5d16 100644
--- a/chromium/content/browser/loader/intercepting_resource_handler.cc
+++ b/chromium/content/browser/loader/intercepting_resource_handler.cc
@@ -161,7 +161,7 @@ void InterceptingResourceHandler::OnResponseCompleted(
// TODO(mmenke): Get rid of NullResourceController and do something more
// reasonable.
next_handler_->OnResponseCompleted(
- status, base::MakeUnique<NullResourceController>(&was_resumed));
+ status, std::make_unique<NullResourceController>(&was_resumed));
DCHECK(was_resumed);
state_ = State::PASS_THROUGH;
@@ -265,7 +265,7 @@ void InterceptingResourceHandler::SendOnWillReadToOldHandler() {
state_ = State::WAITING_FOR_OLD_HANDLERS_BUFFER;
next_handler_->OnWillRead(&first_read_buffer_, &first_read_buffer_size_,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void InterceptingResourceHandler::OnBufferReceived() {
@@ -293,7 +293,7 @@ void InterceptingResourceHandler::OnBufferReceived() {
void InterceptingResourceHandler::SendOnResponseStartedToOldHandler() {
state_ = State::SENDING_PAYLOAD_TO_OLD_HANDLER;
next_handler_->OnResponseStarted(response_.get(),
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void InterceptingResourceHandler::SendPayloadToOldHandler() {
@@ -311,13 +311,13 @@ void InterceptingResourceHandler::SendPayloadToOldHandler() {
// TODO(mmenke): Get rid of NullResourceController and do something more
// reasonable.
next_handler_->OnResponseCompleted(
- status, base::MakeUnique<NullResourceController>(&was_resumed));
+ status, std::make_unique<NullResourceController>(&was_resumed));
DCHECK(was_resumed);
next_handler_ = std::move(new_handler_);
state_ = State::SENDING_ON_WILL_START_TO_NEW_HANDLER;
next_handler_->OnWillStart(request()->url(),
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
return;
}
@@ -335,7 +335,7 @@ void InterceptingResourceHandler::SendPayloadToOldHandler() {
DCHECK(!first_read_buffer_size_);
next_handler_->OnWillRead(&first_read_buffer_, &first_read_buffer_size_,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void InterceptingResourceHandler::ReceivedBufferFromOldHandler() {
@@ -357,13 +357,13 @@ void InterceptingResourceHandler::ReceivedBufferFromOldHandler() {
state_ = State::SENDING_PAYLOAD_TO_OLD_HANDLER;
next_handler_->OnReadCompleted(bytes_to_copy,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void InterceptingResourceHandler::SendOnResponseStartedToNewHandler() {
state_ = State::SENDING_ON_RESPONSE_STARTED_TO_NEW_HANDLER;
next_handler_->OnResponseStarted(response_.get(),
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void InterceptingResourceHandler::SendFirstReadBufferToNewHandler() {
@@ -381,7 +381,7 @@ void InterceptingResourceHandler::SendFirstReadBufferToNewHandler() {
state_ = State::SENDING_BUFFER_TO_NEW_HANDLER_WAITING_FOR_BUFFER;
next_handler_->OnWillRead(&new_handler_read_buffer_,
&new_handler_read_buffer_size_,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void InterceptingResourceHandler::ReceivedBufferFromNewHandler() {
@@ -403,7 +403,7 @@ void InterceptingResourceHandler::ReceivedBufferFromNewHandler() {
state_ = State::SENDING_BUFFER_TO_NEW_HANDLER;
next_handler_->OnReadCompleted(bytes_to_copy,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
} // namespace content
diff --git a/chromium/content/browser/loader/intercepting_resource_handler_unittest.cc b/chromium/content/browser/loader/intercepting_resource_handler_unittest.cc
index a7218ef79f4..54e36ec40d8 100644
--- a/chromium/content/browser/loader/intercepting_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/intercepting_resource_handler_unittest.cc
@@ -48,22 +48,23 @@ class InterceptingResourceHandlerTest : public testing::Test {
net::URLRequestStatus::FromError(net::ERR_IO_PENDING)) {
ResourceRequestInfo::AllocateForTesting(request_.get(),
RESOURCE_TYPE_MAIN_FRAME,
- nullptr, // context
- 0, // render_process_id
- 0, // render_view_id
- 0, // render_frame_id
- true, // is_main_frame
- true, // allow_download
- true, // is_async
- PREVIEWS_OFF); // previews_state
+ nullptr, // context
+ 0, // render_process_id
+ 0, // render_view_id
+ 0, // render_frame_id
+ true, // is_main_frame
+ true, // allow_download
+ true, // is_async
+ PREVIEWS_OFF, // previews_state
+ nullptr); // navigation_ui_data
std::unique_ptr<TestResourceHandler> old_handler(
new TestResourceHandler(&old_handler_status_, &old_handler_body_));
old_handler_ = old_handler->GetWeakPtr();
- intercepting_handler_ = base::MakeUnique<InterceptingResourceHandler>(
+ intercepting_handler_ = std::make_unique<InterceptingResourceHandler>(
std::move(old_handler), request_.get());
mock_loader_ =
- base::MakeUnique<MockResourceLoader>(intercepting_handler_.get());
+ std::make_unique<MockResourceLoader>(intercepting_handler_.get());
}
protected:
diff --git a/chromium/content/browser/loader/loader_delegate.h b/chromium/content/browser/loader/loader_delegate.h
index 71d27a6bb94..fed8520f8ea 100644
--- a/chromium/content/browser/loader/loader_delegate.h
+++ b/chromium/content/browser/loader/loader_delegate.h
@@ -45,11 +45,6 @@ class CONTENT_EXPORT LoaderDelegate {
const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
std::unique_ptr<ResourceRequestDetails> details) = 0;
- // Notification that a redirect was received while requesting a resource.
- virtual void DidGetRedirectForResourceRequest(
- const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
- std::unique_ptr<ResourceRedirectDetails> details) = 0;
-
// Called when the network stack started handling the navigation request.
virtual void LogResourceRequestTime(base::TimeTicks timestamp,
int render_process_id,
diff --git a/chromium/content/browser/loader/mime_sniffing_resource_handler.cc b/chromium/content/browser/loader/mime_sniffing_resource_handler.cc
index 482bb55c2bf..130041fe86c 100644
--- a/chromium/content/browser/loader/mime_sniffing_resource_handler.cc
+++ b/chromium/content/browser/loader/mime_sniffing_resource_handler.cc
@@ -45,22 +45,16 @@ namespace content {
namespace {
-const char kAcceptHeader[] = "Accept";
-const char kFrameAcceptHeader[] =
- "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,"
- "image/apng,*/*;q=0.8";
-const char kStylesheetAcceptHeader[] = "text/css,*/*;q=0.1";
-const char kImageAcceptHeader[] = "image/webp,image/apng,image/*,*/*;q=0.8";
-const char kDefaultAcceptHeader[] = "*/*";
-
-// Used to write into an existing IOBuffer at a given offset.
-class DependentIOBuffer : public net::WrappedIOBuffer {
+// Used to write into an existing IOBuffer at a given offset. This is
+// very similar to DependentIOBufferForRedirectToFile and
+// DependentIOBufferForAsyncLoading but not identical.
+class DependentIOBufferForMimeSniffing : public net::WrappedIOBuffer {
public:
- DependentIOBuffer(net::IOBuffer* buf, int offset)
+ DependentIOBufferForMimeSniffing(net::IOBuffer* buf, int offset)
: net::WrappedIOBuffer(buf->data() + offset), buf_(buf) {}
private:
- ~DependentIOBuffer() override {}
+ ~DependentIOBufferForMimeSniffing() override {}
scoped_refptr<net::IOBuffer> buf_;
};
@@ -137,42 +131,7 @@ void MimeSniffingResourceHandler::OnWillStart(
std::unique_ptr<ResourceController> controller) {
DCHECK(!has_controller());
- const char* accept_value = nullptr;
- switch (GetRequestInfo()->GetResourceType()) {
- case RESOURCE_TYPE_MAIN_FRAME:
- case RESOURCE_TYPE_SUB_FRAME:
- accept_value = kFrameAcceptHeader;
- break;
- case RESOURCE_TYPE_STYLESHEET:
- accept_value = kStylesheetAcceptHeader;
- break;
- case RESOURCE_TYPE_FAVICON:
- case RESOURCE_TYPE_IMAGE:
- accept_value = kImageAcceptHeader;
- break;
- case RESOURCE_TYPE_SCRIPT:
- case RESOURCE_TYPE_FONT_RESOURCE:
- case RESOURCE_TYPE_SUB_RESOURCE:
- case RESOURCE_TYPE_OBJECT:
- case RESOURCE_TYPE_MEDIA:
- case RESOURCE_TYPE_WORKER:
- case RESOURCE_TYPE_SHARED_WORKER:
- case RESOURCE_TYPE_PREFETCH:
- case RESOURCE_TYPE_XHR:
- case RESOURCE_TYPE_PING:
- case RESOURCE_TYPE_SERVICE_WORKER:
- case RESOURCE_TYPE_CSP_REPORT:
- case RESOURCE_TYPE_PLUGIN_RESOURCE:
- accept_value = kDefaultAcceptHeader;
- break;
- case RESOURCE_TYPE_LAST_TYPE:
- NOTREACHED();
- break;
- }
-
- // The false parameter prevents overwriting an existing accept header value,
- // which is needed because JS can manually set an accept header on an XHR.
- request()->SetExtraRequestHeaderByName(kAcceptHeader, accept_value, false);
+ AttachAcceptHeader(GetRequestInfo()->GetResourceType(), request());
next_handler_->OnWillStart(url, std::move(controller));
}
@@ -233,7 +192,8 @@ void MimeSniffingResourceHandler::OnWillRead(
if (read_buffer_.get()) {
CHECK_LT(bytes_read_, read_buffer_size_);
- *buf = new DependentIOBuffer(read_buffer_.get(), bytes_read_);
+ *buf =
+ new DependentIOBufferForMimeSniffing(read_buffer_.get(), bytes_read_);
*buf_size = read_buffer_size_ - bytes_read_;
controller->Resume();
return;
@@ -375,7 +335,7 @@ void MimeSniffingResourceHandler::CallOnWillRead() {
state_ = STATE_WAITING_FOR_BUFFER;
next_handler_->OnWillRead(&read_buffer_, &read_buffer_size_,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void MimeSniffingResourceHandler::BufferReceived() {
@@ -400,7 +360,7 @@ void MimeSniffingResourceHandler::ReplayResponseReceived() {
DCHECK_EQ(STATE_INTERCEPTION_CHECK_DONE, state_);
state_ = STATE_REPLAYING_RESPONSE_RECEIVED;
next_handler_->OnResponseStarted(response_.get(),
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void MimeSniffingResourceHandler::ReplayReadCompleted() {
@@ -420,7 +380,7 @@ void MimeSniffingResourceHandler::ReplayReadCompleted() {
bytes_read_ = 0;
next_handler_->OnReadCompleted(bytes_read,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
bool MimeSniffingResourceHandler::MaybeStartInterception() {
@@ -490,7 +450,7 @@ bool MimeSniffingResourceHandler::CheckForPluginHandler(
bool has_plugin = plugin_service_->GetPluginInfo(
info->GetChildID(), info->GetRenderFrameID(), info->GetContext(),
request()->url(), url::Origin(), response_->head.mime_type,
- allow_wildcard, &stale, &plugin, NULL);
+ allow_wildcard, &stale, &plugin, nullptr);
if (stale) {
// Refresh the plugins asynchronously.
@@ -564,6 +524,14 @@ bool MimeSniffingResourceHandler::MustDownload() {
host_->delegate()->ShouldForceDownloadResource(
request()->url(), response_->head.mime_type)) {
must_download_ = true;
+ } else if (request()->url().SchemeIsHTTPOrHTTPS() &&
+ // The MHTML mime type should be same as the one we check in
+ // Blink's DocumentLoader.
+ response_->head.mime_type == "multipart/related" &&
+ !host_->delegate()->AllowRenderingMhtmlOverHttp(request())) {
+ // Force to download the MHTML page from the remote server, instead of
+ // loading it.
+ must_download_ = true;
} else {
must_download_ = false;
}
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 52be940f0ce..30ce49f4a8b 100644
--- a/chromium/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
@@ -235,9 +235,10 @@ MimeSniffingResourceHandlerTest::TestAcceptHeaderSettingWithURLRequest(
0, // render_view_id
0, // render_frame_id
is_main_frame, // is_main_frame
- false, // allow_download
- true, // is_async
- PREVIEWS_OFF); // previews_state
+ false, // allow_download
+ true, // is_async
+ PREVIEWS_OFF, // previews_state
+ nullptr); // navigation_ui_data
std::unique_ptr<TestResourceHandler> scoped_test_handler(
new TestResourceHandler());
@@ -266,14 +267,15 @@ bool MimeSniffingResourceHandlerTest::TestStreamIsIntercepted(
TRAFFIC_ANNOTATION_FOR_TESTS));
bool is_main_frame = request_resource_type == RESOURCE_TYPE_MAIN_FRAME;
ResourceRequestInfo::AllocateForTesting(request.get(), request_resource_type,
- nullptr, // context
- 0, // render_process_id
- 0, // render_view_id
- 0, // render_frame_id
- is_main_frame, // is_main_frame
+ nullptr, // context
+ 0, // render_process_id
+ 0, // render_view_id
+ 0, // render_frame_id
+ is_main_frame, // is_main_frame
allow_download, // allow_download
true, // is_async
- PREVIEWS_OFF); // previews_state
+ PREVIEWS_OFF, // previews_state
+ nullptr); // navigation_ui_data
TestResourceDispatcherHost host(stream_has_handler_);
TestResourceDispatcherHostDelegate host_delegate(must_download);
@@ -282,7 +284,7 @@ bool MimeSniffingResourceHandlerTest::TestStreamIsIntercepted(
TestFakePluginService plugin_service(plugin_available_, plugin_stale_);
std::unique_ptr<InterceptingResourceHandler> intercepting_handler(
- new InterceptingResourceHandler(base::MakeUnique<TestResourceHandler>(),
+ new InterceptingResourceHandler(std::make_unique<TestResourceHandler>(),
nullptr));
std::unique_ptr<TestResourceHandler> scoped_test_handler(
new TestResourceHandler());
@@ -326,14 +328,15 @@ void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
TRAFFIC_ANNOTATION_FOR_TESTS));
ResourceRequestInfo::AllocateForTesting(request.get(),
RESOURCE_TYPE_MAIN_FRAME,
- nullptr, // context
- 0, // render_process_id
- 0, // render_view_id
- 0, // render_frame_id
- true, // is_main_frame
- false, // allow_download
- true, // is_async
- PREVIEWS_OFF); // previews_state
+ nullptr, // context
+ 0, // render_process_id
+ 0, // render_view_id
+ 0, // render_frame_id
+ true, // is_main_frame
+ false, // allow_download
+ true, // is_async
+ PREVIEWS_OFF, // previews_state
+ nullptr); // navigation_ui_data
TestResourceDispatcherHost host(false);
TestResourceDispatcherHostDelegate host_delegate(false);
@@ -341,7 +344,7 @@ void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
TestFakePluginService plugin_service(plugin_available_, plugin_stale_);
std::unique_ptr<InterceptingResourceHandler> intercepting_handler(
- new InterceptingResourceHandler(base::MakeUnique<TestResourceHandler>(),
+ new InterceptingResourceHandler(std::make_unique<TestResourceHandler>(),
nullptr));
std::unique_ptr<TestResourceHandler> scoped_test_handler(
@@ -488,14 +491,15 @@ void MimeSniffingResourceHandlerTest::TestHandlerNoSniffing(
TRAFFIC_ANNOTATION_FOR_TESTS));
ResourceRequestInfo::AllocateForTesting(request.get(),
RESOURCE_TYPE_MAIN_FRAME,
- nullptr, // context
- 0, // render_process_id
- 0, // render_view_id
- 0, // render_frame_id
- true, // is_main_frame
- false, // allow_download
- true, // is_async
- PREVIEWS_OFF); // previews_state
+ nullptr, // context
+ 0, // render_process_id
+ 0, // render_view_id
+ 0, // render_frame_id
+ true, // is_main_frame
+ false, // allow_download
+ true, // is_async
+ PREVIEWS_OFF, // previews_state
+ nullptr); // navigation_ui_data
TestResourceDispatcherHost host(false);
TestResourceDispatcherHostDelegate host_delegate(false);
@@ -503,7 +507,7 @@ void MimeSniffingResourceHandlerTest::TestHandlerNoSniffing(
TestFakePluginService plugin_service(plugin_available_, plugin_stale_);
std::unique_ptr<InterceptingResourceHandler> intercepting_handler(
- new InterceptingResourceHandler(base::MakeUnique<TestResourceHandler>(),
+ new InterceptingResourceHandler(std::make_unique<TestResourceHandler>(),
nullptr));
std::unique_ptr<TestResourceHandler> scoped_test_handler(
@@ -868,14 +872,15 @@ TEST_F(MimeSniffingResourceHandlerTest, 304Handling) {
TRAFFIC_ANNOTATION_FOR_TESTS));
ResourceRequestInfo::AllocateForTesting(request.get(),
RESOURCE_TYPE_MAIN_FRAME,
- nullptr, // context
- 0, // render_process_id
- 0, // render_view_id
- 0, // render_frame_id
- true, // is_main_frame
- true, // allow_download
- true, // is_async
- PREVIEWS_OFF); // previews_state
+ nullptr, // context
+ 0, // render_process_id
+ 0, // render_view_id
+ 0, // render_frame_id
+ true, // is_main_frame
+ true, // allow_download
+ true, // is_async
+ PREVIEWS_OFF, // previews_state
+ nullptr); // navigation_ui_data
TestResourceDispatcherHost host(false);
TestResourceDispatcherHostDelegate host_delegate(false);
@@ -883,7 +888,7 @@ TEST_F(MimeSniffingResourceHandlerTest, 304Handling) {
TestFakePluginService plugin_service(false, false);
std::unique_ptr<ResourceHandler> intercepting_handler(
- new InterceptingResourceHandler(base::MakeUnique<TestResourceHandler>(),
+ new InterceptingResourceHandler(std::make_unique<TestResourceHandler>(),
nullptr));
MimeSniffingResourceHandler mime_sniffing_handler(
std::unique_ptr<ResourceHandler>(new TestResourceHandler()), &host,
@@ -919,20 +924,21 @@ TEST_F(MimeSniffingResourceHandlerTest, FetchShouldDisableMimeSniffing) {
TRAFFIC_ANNOTATION_FOR_TESTS));
ResourceRequestInfo::AllocateForTesting(request.get(),
RESOURCE_TYPE_MAIN_FRAME,
- nullptr, // context
- 0, // render_process_id
- 0, // render_view_id
- 0, // render_frame_id
- true, // is_main_frame
- false, // allow_download
- true, // is_async
- PREVIEWS_OFF); // previews_state
+ nullptr, // context
+ 0, // render_process_id
+ 0, // render_view_id
+ 0, // render_frame_id
+ true, // is_main_frame
+ false, // allow_download
+ true, // is_async
+ PREVIEWS_OFF, // previews_state
+ nullptr); // navigation_ui_data
TestResourceDispatcherHost host(false);
TestFakePluginService plugin_service(false, false);
std::unique_ptr<InterceptingResourceHandler> intercepting_handler(
- new InterceptingResourceHandler(base::MakeUnique<TestResourceHandler>(),
+ new InterceptingResourceHandler(std::make_unique<TestResourceHandler>(),
nullptr));
std::unique_ptr<TestResourceHandler> scoped_test_handler(
diff --git a/chromium/content/browser/loader/mock_resource_loader.cc b/chromium/content/browser/loader/mock_resource_loader.cc
index 6971ab411fe..1497d92d6ae 100644
--- a/chromium/content/browser/loader/mock_resource_loader.cc
+++ b/chromium/content/browser/loader/mock_resource_loader.cc
@@ -46,7 +46,7 @@ MockResourceLoader::Status MockResourceLoader::OnWillStart(const GURL& url) {
EXPECT_EQ(Status::IDLE, status_);
status_ = Status::CALLING_HANDLER;
- resource_handler_->OnWillStart(url, base::MakeUnique<TestResourceController>(
+ resource_handler_->OnWillStart(url, std::make_unique<TestResourceController>(
weak_factory_.GetWeakPtr()));
if (status_ == Status::CALLING_HANDLER)
status_ = Status::CALLBACK_PENDING;
@@ -65,7 +65,7 @@ MockResourceLoader::Status MockResourceLoader::OnRequestRedirected(
// needs to hold onto its own pointer to it.
resource_handler_->OnRequestRedirected(
redirect_info, response.get(),
- base::MakeUnique<TestResourceController>(weak_factory_.GetWeakPtr()));
+ std::make_unique<TestResourceController>(weak_factory_.GetWeakPtr()));
if (status_ == Status::CALLING_HANDLER)
status_ = Status::CALLBACK_PENDING;
return status_;
@@ -82,7 +82,7 @@ MockResourceLoader::Status MockResourceLoader::OnResponseStarted(
// needs to hold onto its own pointer to it.
resource_handler_->OnResponseStarted(
response.get(),
- base::MakeUnique<TestResourceController>(weak_factory_.GetWeakPtr()));
+ std::make_unique<TestResourceController>(weak_factory_.GetWeakPtr()));
if (status_ == Status::CALLING_HANDLER)
status_ = Status::CALLBACK_PENDING;
return status_;
@@ -96,7 +96,7 @@ MockResourceLoader::Status MockResourceLoader::OnWillRead() {
waiting_on_buffer_ = true;
resource_handler_->OnWillRead(
&io_buffer_, &io_buffer_size_,
- base::MakeUnique<TestResourceController>(weak_factory_.GetWeakPtr()));
+ std::make_unique<TestResourceController>(weak_factory_.GetWeakPtr()));
if (status_ == Status::CALLING_HANDLER) {
// Shouldn't update |io_buffer_| or |io_buffer_size_| yet if Resume()
// hasn't yet been called.
@@ -121,7 +121,7 @@ MockResourceLoader::Status MockResourceLoader::OnReadCompleted(
io_buffer_size_ = 0;
resource_handler_->OnReadCompleted(
bytes.size(),
- base::MakeUnique<TestResourceController>(weak_factory_.GetWeakPtr()));
+ std::make_unique<TestResourceController>(weak_factory_.GetWeakPtr()));
if (status_ == Status::CALLING_HANDLER)
status_ = Status::CALLBACK_PENDING;
return status_;
@@ -141,7 +141,7 @@ MockResourceLoader::Status MockResourceLoader::OnResponseCompleted(
status_ = Status::CALLING_HANDLER;
resource_handler_->OnResponseCompleted(
status,
- base::MakeUnique<TestResourceController>(weak_factory_.GetWeakPtr()));
+ std::make_unique<TestResourceController>(weak_factory_.GetWeakPtr()));
if (status_ == Status::CALLING_HANDLER)
status_ = Status::CALLBACK_PENDING;
EXPECT_NE(Status::CANCELED, status_);
@@ -162,7 +162,7 @@ MockResourceLoader::OnResponseCompletedFromExternalOutOfBandCancel(
resource_handler_->OnResponseCompleted(
url_request_status,
- base::MakeUnique<TestResourceController>(weak_factory_.GetWeakPtr()));
+ std::make_unique<TestResourceController>(weak_factory_.GetWeakPtr()));
if (status_ == Status::CALLING_HANDLER)
status_ = Status::CALLBACK_PENDING;
EXPECT_NE(Status::CANCELED, status_);
diff --git a/chromium/content/browser/loader/mojo_async_resource_handler.cc b/chromium/content/browser/loader/mojo_async_resource_handler.cc
index 516ddfc0fcd..6a0c5e0af4c 100644
--- a/chromium/content/browser/loader/mojo_async_resource_handler.cc
+++ b/chromium/content/browser/loader/mojo_async_resource_handler.cc
@@ -9,27 +9,24 @@
#include <vector>
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "content/browser/loader/downloaded_temp_file_impl.h"
#include "content/browser/loader/resource_controller.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/loader/resource_scheduler.h"
-#include "content/browser/loader/upload_progress_tracker.h"
#include "content/public/browser/global_request_id.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "content/public/common/resource_response.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/cpp/bindings/message.h"
#include "net/base/mime_sniffer.h"
#include "net/base/net_errors.h"
#include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
namespace content {
namespace {
@@ -43,22 +40,6 @@ constexpr size_t kMinAllocationSize = 2 * net::kMaxBytesToSniff;
constexpr size_t kMaxChunkSize = 32 * 1024;
-void GetNumericArg(const std::string& name, int* result) {
- const std::string& value =
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(name);
- if (!value.empty())
- base::StringToInt(value, result);
-}
-
-void InitializeResourceBufferConstants() {
- static bool did_init = false;
- if (did_init)
- return;
- did_init = true;
-
- GetNumericArg("resource-buffer-size", &g_allocation_size);
-}
-
void NotReached(mojom::URLLoaderRequest mojo_request,
mojom::URLLoaderClientPtr url_loader_client) {
NOTREACHED();
@@ -143,6 +124,15 @@ MojoAsyncResourceHandler::~MojoAsyncResourceHandler() {
rdh_->FinishedWithResourcesForRequest(request());
}
+void MojoAsyncResourceHandler::InitializeResourceBufferConstants() {
+ static bool did_init = false;
+ if (did_init)
+ return;
+ did_init = true;
+
+ GetNumericArg("resource-buffer-size", &g_allocation_size);
+}
+
void MojoAsyncResourceHandler::OnRequestRedirected(
const net::RedirectInfo& redirect_info,
ResourceResponse* response,
@@ -424,7 +414,7 @@ net::IOBufferWithSize* MojoAsyncResourceHandler::GetResponseMetadata(
}
void MojoAsyncResourceHandler::OnResponseCompleted(
- const net::URLRequestStatus& status,
+ const net::URLRequestStatus& request_status,
std::unique_ptr<ResourceController> controller) {
// Ensure sending the final upload progress message here, since
// OnResponseCompleted can be called without OnResponseStarted on cancellation
@@ -443,23 +433,22 @@ void MojoAsyncResourceHandler::OnResponseCompleted(
// WebURLLoaderImpl::OnCompletedRequest that routes this message to a WebCore
// ResourceHandleInternal which asserts on its state and crashes. By crashing
// when the message is sent, we should get better crash reports.
- CHECK(status.status() != net::URLRequestStatus::SUCCESS ||
+ CHECK(request_status.status() != net::URLRequestStatus::SUCCESS ||
sent_received_response_message_);
- int error_code = status.error();
+ int error_code = request_status.error();
- DCHECK_NE(status.status(), net::URLRequestStatus::IO_PENDING);
+ DCHECK_NE(request_status.status(), net::URLRequestStatus::IO_PENDING);
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = error_code;
- request_complete_data.exists_in_cache = request()->response_info().was_cached;
- request_complete_data.completion_time = base::TimeTicks::Now();
- request_complete_data.encoded_data_length =
- request()->GetTotalReceivedBytes();
- request_complete_data.encoded_body_length = request()->GetRawBodyBytes();
- request_complete_data.decoded_body_length = total_written_bytes_;
+ network::URLLoaderCompletionStatus loader_status;
+ loader_status.error_code = error_code;
+ loader_status.exists_in_cache = request()->response_info().was_cached;
+ loader_status.completion_time = base::TimeTicks::Now();
+ loader_status.encoded_data_length = request()->GetTotalReceivedBytes();
+ loader_status.encoded_body_length = request()->GetRawBodyBytes();
+ loader_status.decoded_body_length = total_written_bytes_;
- url_loader_client_->OnComplete(request_complete_data);
+ url_loader_client_->OnComplete(loader_status);
controller->Resume();
}
@@ -579,7 +568,7 @@ std::unique_ptr<UploadProgressTracker>
MojoAsyncResourceHandler::CreateUploadProgressTracker(
const base::Location& from_here,
UploadProgressTracker::UploadProgressReportCallback callback) {
- return base::MakeUnique<UploadProgressTracker>(from_here, std::move(callback),
+ return std::make_unique<UploadProgressTracker>(from_here, std::move(callback),
request());
}
diff --git a/chromium/content/browser/loader/mojo_async_resource_handler.h b/chromium/content/browser/loader/mojo_async_resource_handler.h
index c189a6acd63..f9e92a74649 100644
--- a/chromium/content/browser/loader/mojo_async_resource_handler.h
+++ b/chromium/content/browser/loader/mojo_async_resource_handler.h
@@ -14,8 +14,8 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/loader/resource_handler.h"
-#include "content/browser/loader/upload_progress_tracker.h"
#include "content/common/content_export.h"
+#include "content/network/upload_progress_tracker.h"
#include "content/public/common/resource_type.h"
#include "content/public/common/url_loader.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -126,6 +126,7 @@ class CONTENT_EXPORT MojoAsyncResourceHandler : public ResourceHandler,
mojom::URLLoaderClientPtr url_loader_client);
void SendUploadProgress(const net::UploadProgress& progress);
void OnUploadProgressACK();
+ static void InitializeResourceBufferConstants();
ResourceDispatcherHostImpl* rdh_;
mojo::Binding<mojom::URLLoader> binding_;
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 c6b18d9a8ee..45579133d18 100644
--- a/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc
@@ -30,7 +30,6 @@
#include "content/public/browser/resource_throttle.h"
#include "content/public/browser/stream_info.h"
#include "content/public/common/previews_state.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "content/public/common/resource_response.h"
#include "content/public/common/resource_type.h"
#include "content/public/common/url_loader.mojom.h"
@@ -55,6 +54,7 @@
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_util.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/page_transition_types.h"
@@ -180,10 +180,11 @@ class TestResourceDispatcherHostDelegate final
ADD_FAILURE() << "RequestComplete should not be called.";
}
- PreviewsState GetPreviewsState(const net::URLRequest& url_request,
- content::ResourceContext* resource_context,
- PreviewsState previews_to_allow) override {
- ADD_FAILURE() << "GetPreviewsState should not be called.";
+ PreviewsState DeterminePreviewsState(
+ net::URLRequest* url_request,
+ content::ResourceContext* resource_context,
+ PreviewsState previews_to_allow) override {
+ ADD_FAILURE() << "DeterminePreviewsState should not be called.";
return PREVIEWS_UNSPECIFIED;
}
@@ -267,7 +268,7 @@ class MojoAsyncResourceHandlerWithStubOperations
UploadProgressTracker::UploadProgressReportCallback callback) override {
DCHECK(!upload_progress_tracker_);
- auto upload_progress_tracker = base::MakeUnique<FakeUploadProgressTracker>(
+ auto upload_progress_tracker = std::make_unique<FakeUploadProgressTracker>(
from_here, std::move(callback), request(), task_runner_);
upload_progress_tracker_ = upload_progress_tracker.get();
return std::move(upload_progress_tracker);
@@ -345,12 +346,12 @@ class MojoAsyncResourceHandlerTestBase {
true, // is_main_frame
false, // allow_download
true, // is_async
- PREVIEWS_OFF // previews_state
- );
+ PREVIEWS_OFF, // previews_state
+ nullptr); // navigation_ui_data
ResourceRequest request;
base::WeakPtr<mojo::StrongBinding<mojom::URLLoaderFactory>> weak_binding =
- mojo::MakeStrongBinding(base::MakeUnique<TestURLLoaderFactory>(),
+ mojo::MakeStrongBinding(std::make_unique<TestURLLoaderFactory>(),
mojo::MakeRequest(&url_loader_factory_));
url_loader_factory_->CreateLoaderAndStart(
@@ -455,7 +456,7 @@ class MojoAsyncResourceHandlerUploadTest
protected:
MojoAsyncResourceHandlerUploadTest()
: MojoAsyncResourceHandlerTestBase(
- base::MakeUnique<DummyUploadDataStream>()) {}
+ std::make_unique<DummyUploadDataStream>()) {}
};
TEST_F(MojoAsyncResourceHandlerTest, InFlightRequests) {
diff --git a/chromium/content/browser/loader/navigation_resource_handler.cc b/chromium/content/browser/loader/navigation_resource_handler.cc
index 4a522b1291a..6ce77516873 100644
--- a/chromium/content/browser/loader/navigation_resource_handler.cc
+++ b/chromium/content/browser/loader/navigation_resource_handler.cc
@@ -18,7 +18,6 @@
#include "content/browser/streams/stream_context.h"
#include "content/public/browser/navigation_data.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
-#include "content/public/browser/ssl_status.h"
#include "content/public/browser/stream_handle.h"
#include "content/public/common/resource_response.h"
#include "net/base/net_errors.h"
@@ -42,13 +41,6 @@ bool ShouldSSLErrorsBeFatal(net::URLRequest* request) {
namespace content {
-void NavigationResourceHandler::GetSSLStatusForRequest(
- const net::SSLInfo& ssl_info,
- SSLStatus* ssl_status) {
- DCHECK(ssl_info.cert);
- *ssl_status = SSLStatus(ssl_info);
-}
-
NavigationResourceHandler::NavigationResourceHandler(
net::URLRequest* request,
std::unique_ptr<ResourceHandler> next_handler,
@@ -117,7 +109,7 @@ void NavigationResourceHandler::OnRequestRedirected(
HoldController(std::move(controller));
response_ = response;
- redirect_info_ = base::MakeUnique<net::RedirectInfo>(redirect_info);
+ redirect_info_ = std::make_unique<net::RedirectInfo>(redirect_info);
}
void NavigationResourceHandler::OnResponseStarted(
@@ -146,13 +138,10 @@ void NavigationResourceHandler::OnResponseStarted(
cloned_data = navigation_data->Clone();
}
- SSLStatus ssl_status;
- if (request()->ssl_info().cert.get())
- GetSSLStatusForRequest(request()->ssl_info(), &ssl_status);
-
- core_->NotifyResponseStarted(
- response, std::move(stream_handle_), ssl_status, std::move(cloned_data),
- info->GetGlobalRequestID(), info->IsDownload(), info->is_stream());
+ core_->NotifyResponseStarted(response, std::move(stream_handle_),
+ request()->ssl_info(), std::move(cloned_data),
+ info->GetGlobalRequestID(), info->IsDownload(),
+ info->is_stream());
HoldController(std::move(controller));
response_ = response;
}
diff --git a/chromium/content/browser/loader/navigation_resource_handler.h b/chromium/content/browser/loader/navigation_resource_handler.h
index 31b61a7af89..ae6e205110f 100644
--- a/chromium/content/browser/loader/navigation_resource_handler.h
+++ b/chromium/content/browser/loader/navigation_resource_handler.h
@@ -12,23 +12,15 @@
#include "content/browser/loader/layered_resource_handler.h"
#include "content/public/browser/stream_handle.h"
-namespace net {
-class SSLInfo;
-}
-
namespace content {
class NavigationURLLoaderImplCore;
class ResourceController;
class ResourceDispatcherHostDelegate;
-struct SSLStatus;
// PlzNavigate: The ResourceHandler used with NavigationURLLoaderImplCore to
// control the flow of navigation requests.
class NavigationResourceHandler : public LayeredResourceHandler {
public:
- static void GetSSLStatusForRequest(const net::SSLInfo& ssl_info,
- SSLStatus* ssl_status);
-
NavigationResourceHandler(
net::URLRequest* request,
std::unique_ptr<ResourceHandler> next_handler,
diff --git a/chromium/content/browser/loader/navigation_resource_throttle.cc b/chromium/content/browser/loader/navigation_resource_throttle.cc
index 825bae6095b..e81bef989b1 100644
--- a/chromium/content/browser/loader/navigation_resource_throttle.cc
+++ b/chromium/content/browser/loader/navigation_resource_throttle.cc
@@ -144,7 +144,8 @@ void WillProcessResponseOnUIThread(
int render_frame_host_id,
scoped_refptr<net::HttpResponseHeaders> headers,
net::HttpResponseInfo::ConnectionInfo connection_info,
- const SSLStatus& ssl_status,
+ const net::HostPortPair& socket_address,
+ const net::SSLInfo& ssl_info,
const GlobalRequestID& request_id,
bool should_replace_current_entry,
bool is_download,
@@ -169,9 +170,9 @@ void WillProcessResponseOnUIThread(
RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
DCHECK(render_frame_host);
navigation_handle->WillProcessResponse(
- render_frame_host, headers, connection_info, ssl_status, request_id,
- should_replace_current_entry, is_download, is_stream, transfer_callback,
- base::Bind(&SendCheckResultToIOThread, callback));
+ render_frame_host, headers, connection_info, socket_address, ssl_info,
+ request_id, should_replace_current_entry, is_download, is_stream,
+ transfer_callback, base::Bind(&SendCheckResultToIOThread, callback));
}
} // namespace
@@ -309,18 +310,13 @@ void NavigationResourceThrottle::WillProcessResponse(bool* defer) {
base::Bind(&NavigationResourceThrottle::InitiateTransfer,
weak_ptr_factory_.GetWeakPtr());
- SSLStatus ssl_status;
- if (request_->ssl_info().cert.get()) {
- NavigationResourceHandler::GetSSLStatusForRequest(request_->ssl_info(),
- &ssl_status);
- }
-
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&WillProcessResponseOnUIThread, callback,
render_process_id, render_frame_id, response_headers,
- request_->response_info().connection_info, ssl_status,
- info->GetGlobalRequestID(),
+ request_->response_info().connection_info,
+ request_->response_info().socket_address,
+ request_->ssl_info(), info->GetGlobalRequestID(),
info->should_replace_current_entry(), info->IsDownload(),
info->is_stream(), transfer_callback,
base::Passed(&cloned_data)));
diff --git a/chromium/content/browser/loader/navigation_url_loader.cc b/chromium/content/browser/loader/navigation_url_loader.cc
index 9c62df0146f..a6a42301399 100644
--- a/chromium/content/browser/loader/navigation_url_loader.cc
+++ b/chromium/content/browser/loader/navigation_url_loader.cc
@@ -18,7 +18,7 @@
namespace content {
-static NavigationURLLoaderFactory* g_factory = nullptr;
+static NavigationURLLoaderFactory* g_loader_factory = nullptr;
std::unique_ptr<NavigationURLLoader> NavigationURLLoader::Create(
ResourceContext* resource_context,
@@ -28,18 +28,18 @@ std::unique_ptr<NavigationURLLoader> NavigationURLLoader::Create(
ServiceWorkerNavigationHandle* service_worker_handle,
AppCacheNavigationHandle* appcache_handle,
NavigationURLLoaderDelegate* delegate) {
- if (g_factory) {
- return g_factory->CreateLoader(
+ if (g_loader_factory) {
+ return g_loader_factory->CreateLoader(
resource_context, storage_partition, std::move(request_info),
std::move(navigation_ui_data), service_worker_handle, delegate);
}
if (base::FeatureList::IsEnabled(features::kNetworkService)) {
- return base::MakeUnique<NavigationURLLoaderNetworkService>(
+ return std::make_unique<NavigationURLLoaderNetworkService>(
resource_context, storage_partition, std::move(request_info),
std::move(navigation_ui_data), service_worker_handle, appcache_handle,
delegate, std::vector<std::unique_ptr<URLLoaderRequestHandler>>());
} else {
- return base::MakeUnique<NavigationURLLoaderImpl>(
+ return std::make_unique<NavigationURLLoaderImpl>(
resource_context, storage_partition, std::move(request_info),
std::move(navigation_ui_data), service_worker_handle, appcache_handle,
delegate);
@@ -48,8 +48,8 @@ std::unique_ptr<NavigationURLLoader> NavigationURLLoader::Create(
void NavigationURLLoader::SetFactoryForTesting(
NavigationURLLoaderFactory* factory) {
- DCHECK(g_factory == nullptr || factory == nullptr);
- g_factory = factory;
+ DCHECK(g_loader_factory == nullptr || factory == nullptr);
+ g_loader_factory = factory;
}
} // namespace content
diff --git a/chromium/content/browser/loader/navigation_url_loader.h b/chromium/content/browser/loader/navigation_url_loader.h
index 208fa147d6b..bb784aa61a2 100644
--- a/chromium/content/browser/loader/navigation_url_loader.h
+++ b/chromium/content/browser/loader/navigation_url_loader.h
@@ -6,12 +6,15 @@
#define CONTENT_BROWSER_LOADER_NAVIGATION_URL_LOADER_H_
#include <memory>
+#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/optional.h"
#include "content/common/content_export.h"
-#include "content/public/common/resource_request_completion_status.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
+
+class GURL;
namespace content {
@@ -63,12 +66,13 @@ class CONTENT_EXPORT NavigationURLLoader {
// Callback to intercept the response from the URLLoader. Only used when
// network service is enabled. Args: the initial resource request,
- // the URLLoader for sending the request, optional completion status if
- // it has already been received.
- using NavigationInterceptionCB =
- base::OnceCallback<void(std::unique_ptr<ResourceRequest>,
- std::unique_ptr<ThrottlingURLLoader>,
- base::Optional<ResourceRequestCompletionStatus>)>;
+ // the URLLoader for sending the request, url chain, optional completion
+ // status if it has already been received.
+ using NavigationInterceptionCB = base::OnceCallback<void(
+ std::unique_ptr<ResourceRequest>,
+ std::unique_ptr<ThrottlingURLLoader>,
+ std::vector<GURL>,
+ base::Optional<network::URLLoaderCompletionStatus>)>;
// This method is called to intercept the url response. Caller is responsible
// for handling the URLLoader later on. The callback should be called on the
diff --git a/chromium/content/browser/loader/navigation_url_loader_delegate.h b/chromium/content/browser/loader/navigation_url_loader_delegate.h
index 2dbb64f3d8d..8432bffefa5 100644
--- a/chromium/content/browser/loader/navigation_url_loader_delegate.h
+++ b/chromium/content/browser/loader/navigation_url_loader_delegate.h
@@ -9,8 +9,8 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/optional.h"
#include "content/common/content_export.h"
-#include "content/public/common/url_loader_factory.mojom.h"
#include "mojo/public/cpp/system/data_pipe.h"
namespace net {
@@ -24,7 +24,7 @@ class NavigationData;
class StreamHandle;
struct GlobalRequestID;
struct ResourceResponse;
-struct SSLStatus;
+struct SubresourceLoaderParams;
// PlzNavigate: The delegate interface to NavigationURLLoader.
class CONTENT_EXPORT NavigationURLLoaderDelegate {
@@ -40,30 +40,29 @@ class CONTENT_EXPORT NavigationURLLoaderDelegate {
// |body_stream|. |navigation_data| is passed to the NavigationHandle.
// If --enable-network-service, then |consumer_handle| will be used,
// otherwise |body_stream|. Only one of these will ever be non-null.
- // |subresource_url_loader_factory_info| is used in the network service only
- // for passing factories which are interested in handling subresource
- // requests like AppCache.
+ // |subresource_loader_params| is used in the network service only
+ // for passing necessary info to create a custom subresource loader in
+ // the renderer process if the navigated context is controlled by a request
+ // interceptor like AppCache or ServiceWorker.
virtual void OnResponseStarted(
const scoped_refptr<ResourceResponse>& response,
std::unique_ptr<StreamHandle> body_stream,
mojo::ScopedDataPipeConsumerHandle consumer_handle,
- const SSLStatus& ssl_status,
+ const net::SSLInfo& ssl_info,
std::unique_ptr<NavigationData> navigation_data,
const GlobalRequestID& request_id,
bool is_download,
bool is_stream,
- mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_info) = 0;
+ base::Optional<SubresourceLoaderParams> subresource_loader_params) = 0;
// Called if the request fails before receving a response. |net_error| is a
// network error code for the failure. |has_stale_copy_in_cache| is true if
// there is a stale copy of the unreachable page in cache. |ssl_info| is the
// SSL info for the request. |should_ssl_errors_be_fatal| indicates
- // whether SSL errors for the request should be fatal.
- // If |net_error| is a certificate error, the caller should pass a value for
- // |ssl_info|. If |net_error| is not a certificate error, |ssl_info| and
- // |fatal_cert_error| are ignored.
- // TODO(https://crbug.com/757633): Change "should pass a value for |ssl_info|"
- // to "must pass..."
+ // whether SSL errors for the request should be fatal. If |net_error| is a
+ // certificate error and the navigation request was for the main frame, the
+ // caller must pass a value for |ssl_info|. If |net_error| is not a
+ // certificate error, |ssl_info| and |should_ssl_errors_be_fatal| are ignored.
virtual void OnRequestFailed(bool has_stale_copy_in_cache,
int net_error,
const base::Optional<net::SSLInfo>& ssl_info,
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl.cc b/chromium/content/browser/loader/navigation_url_loader_impl.cc
index 6b77e7f04b8..47f0a270f06 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_impl.cc
@@ -16,6 +16,7 @@
#include "content/browser/loader/navigation_url_loader_delegate.h"
#include "content/browser/loader/navigation_url_loader_impl_core.h"
#include "content/browser/service_worker/service_worker_navigation_handle.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_request_id.h"
@@ -23,6 +24,7 @@
#include "content/public/browser/navigation_ui_data.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/stream_handle.h"
+#include "net/url_request/url_request_context_getter.h"
namespace content {
@@ -55,7 +57,7 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
&NavigationURLLoaderImplCore::Start, core_, resource_context,
- storage_partition->GetURLRequestContext(),
+ base::Unretained(storage_partition->GetURLRequestContext()),
base::Unretained(storage_partition->GetFileSystemContext()),
service_worker_handle_core, appcache_handle_core,
base::Passed(&request_info), base::Passed(&navigation_ui_data)));
@@ -99,17 +101,17 @@ void NavigationURLLoaderImpl::NotifyRequestRedirected(
void NavigationURLLoaderImpl::NotifyResponseStarted(
const scoped_refptr<ResourceResponse>& response,
std::unique_ptr<StreamHandle> body,
- const SSLStatus& ssl_status,
+ const net::SSLInfo& ssl_info,
std::unique_ptr<NavigationData> navigation_data,
const GlobalRequestID& request_id,
bool is_download,
bool is_stream) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- delegate_->OnResponseStarted(
- response, std::move(body), mojo::ScopedDataPipeConsumerHandle(),
- ssl_status, std::move(navigation_data), request_id, is_download,
- is_stream, mojom::URLLoaderFactoryPtrInfo());
+ delegate_->OnResponseStarted(response, std::move(body),
+ mojo::ScopedDataPipeConsumerHandle(), ssl_info,
+ std::move(navigation_data), request_id,
+ is_download, is_stream, base::nullopt);
}
void NavigationURLLoaderImpl::NotifyRequestFailed(
bool in_cache,
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl.h b/chromium/content/browser/loader/navigation_url_loader_impl.h
index 86f0e021871..49c745e105e 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl.h
+++ b/chromium/content/browser/loader/navigation_url_loader_impl.h
@@ -28,7 +28,6 @@ class ServiceWorkerNavigationHandle;
class StreamHandle;
struct GlobalRequestID;
struct ResourceResponse;
-struct SSLStatus;
class NavigationURLLoaderImpl : public NavigationURLLoader {
public:
@@ -57,7 +56,7 @@ class NavigationURLLoaderImpl : public NavigationURLLoader {
// Notifies the delegate that the response has started.
void NotifyResponseStarted(const scoped_refptr<ResourceResponse>& response,
std::unique_ptr<StreamHandle> body,
- const SSLStatus& ssl_status,
+ const net::SSLInfo& ssl_info,
std::unique_ptr<NavigationData> navigation_data,
const GlobalRequestID& request_id,
bool is_download,
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl_core.cc b/chromium/content/browser/loader/navigation_url_loader_impl_core.cc
index 01668321e24..db3ebeca8a5 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl_core.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_impl_core.cc
@@ -28,7 +28,7 @@ namespace content {
NavigationURLLoaderImplCore::NavigationURLLoaderImplCore(
const base::WeakPtr<NavigationURLLoaderImpl>& loader)
- : loader_(loader), resource_handler_(nullptr) {
+ : loader_(loader), resource_handler_(nullptr), weak_factory_(this) {
// This object is created on the UI thread but otherwise is accessed and
// deleted on the IO thread.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -46,10 +46,8 @@ void NavigationURLLoaderImplCore::Start(
std::unique_ptr<NavigationUIData> navigation_ui_data) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&NavigationURLLoaderImpl::NotifyRequestStarted, loader_,
- base::TimeTicks::Now()));
+ base::WeakPtr<NavigationURLLoaderImplCore> weak_this =
+ weak_factory_.GetWeakPtr();
// The ResourceDispatcherHostImpl can be null in unit tests.
if (ResourceDispatcherHostImpl::Get()) {
@@ -59,6 +57,15 @@ void NavigationURLLoaderImplCore::Start(
std::move(navigation_ui_data), this, service_worker_handle_core,
appcache_handle_core);
}
+
+ // Careful, |this| could be destroyed at this point. Don't notify start if
+ // that's the case (i.e. the request failed).
+ if (!weak_this)
+ return;
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&NavigationURLLoaderImpl::NotifyRequestStarted, loader_,
+ base::TimeTicks::Now()));
}
void NavigationURLLoaderImplCore::FollowRedirect() {
@@ -109,7 +116,7 @@ void NavigationURLLoaderImplCore::NotifyRequestRedirected(
void NavigationURLLoaderImplCore::NotifyResponseStarted(
ResourceResponse* response,
std::unique_ptr<StreamHandle> body,
- const SSLStatus& ssl_status,
+ const net::SSLInfo& ssl_info,
std::unique_ptr<NavigationData> navigation_data,
const GlobalRequestID& request_id,
bool is_download,
@@ -131,7 +138,7 @@ void NavigationURLLoaderImplCore::NotifyResponseStarted(
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&NavigationURLLoaderImpl::NotifyResponseStarted, loader_,
- response->DeepCopy(), base::Passed(&body), ssl_status,
+ response->DeepCopy(), base::Passed(&body), ssl_info,
base::Passed(&navigation_data), request_id, is_download,
is_stream));
}
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl_core.h b/chromium/content/browser/loader/navigation_url_loader_impl_core.h
index 2d5d5f88002..72310d8bb9f 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl_core.h
+++ b/chromium/content/browser/loader/navigation_url_loader_impl_core.h
@@ -31,7 +31,6 @@ class ServiceWorkerNavigationHandleCore;
class StreamHandle;
struct GlobalRequestID;
struct ResourceResponse;
-struct SSLStatus;
// The IO-thread counterpart to the NavigationURLLoaderImpl. It lives on the IO
// thread and is owned by the UI-thread NavigationURLLoaderImpl and the
@@ -76,7 +75,7 @@ class NavigationURLLoaderImplCore
// Notifies |loader_| on the UI thread that the response started.
void NotifyResponseStarted(ResourceResponse* response,
std::unique_ptr<StreamHandle> body,
- const SSLStatus& ssl_status,
+ const net::SSLInfo& ssl_info,
std::unique_ptr<NavigationData> navigation_data,
const GlobalRequestID& request_id,
bool is_download,
@@ -95,6 +94,8 @@ class NavigationURLLoaderImplCore
base::WeakPtr<NavigationURLLoaderImpl> loader_;
NavigationResourceHandler* resource_handler_;
+ base::WeakPtrFactory<NavigationURLLoaderImplCore> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(NavigationURLLoaderImplCore);
};
diff --git a/chromium/content/browser/loader/navigation_url_loader_network_service.cc b/chromium/content/browser/loader/navigation_url_loader_network_service.cc
index dadbbdcc8fc..70148056059 100644
--- a/chromium/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_network_service.cc
@@ -7,10 +7,13 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/task_scheduler/post_task.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
#include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
+#include "content/browser/file_url_loader_factory.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/navigation_resource_handler.h"
@@ -26,6 +29,7 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/webui/url_data_manager_backend.h"
#include "content/browser/webui/web_ui_url_loader_factory.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "content/common/throttling_url_loader.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -38,9 +42,12 @@
#include "content/public/common/referrer.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/public/common/url_utils.h"
#include "net/base/load_flags.h"
#include "net/http/http_content_disposition.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "net/url_request/redirect_util.h"
+#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "services/service_manager/public/cpp/connector.h"
#include "third_party/WebKit/common/mime_util/mime_util.h"
@@ -53,8 +60,13 @@ namespace {
// as ResourceDispatcherHostImpl.
int g_next_request_id = -2;
-// Max number of http redirects to follow. Same number as the net library.
-const int kMaxRedirects = 20;
+size_t GetCertificateChainsSizeInKB(const net::SSLInfo& ssl_info) {
+ base::Pickle cert_pickle;
+ ssl_info.cert->Persist(&cert_pickle);
+ base::Pickle unverified_cert_pickle;
+ ssl_info.unverified_cert->Persist(&unverified_cert_pickle);
+ return (cert_pickle.size() + unverified_cert_pickle.size()) / 1000;
+}
WebContents* GetWebContentsFromFrameTreeNodeID(int frame_tree_node_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -66,7 +78,7 @@ WebContents* GetWebContentsFromFrameTreeNodeID(int frame_tree_node_id) {
return WebContentsImpl::FromFrameTreeNode(frame_tree_node);
}
-const net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+const net::NetworkTrafficAnnotationTag kNavigationUrlLoaderTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("navigation_url_loader", R"(
semantics {
sender: "Navigation URL Loader"
@@ -137,12 +149,14 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
AppCacheNavigationHandleCore* appcache_handle_core,
std::unique_ptr<NavigationRequestInfo> request_info,
mojom::URLLoaderFactoryPtrInfo factory_for_webui,
- const base::Callback<WebContents*(void)>& web_contents_getter,
+ int frame_tree_node_id,
std::unique_ptr<service_manager::Connector> connector) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!started_);
+ frame_tree_node_id_ = frame_tree_node_id;
started_ = true;
- web_contents_getter_ = web_contents_getter;
+ web_contents_getter_ =
+ base::Bind(&GetWebContentsFromFrameTreeNodeID, frame_tree_node_id);
const ResourceType resource_type = request_info->is_main_frame
? RESOURCE_TYPE_MAIN_FRAME
: RESOURCE_TYPE_SUB_FRAME;
@@ -160,8 +174,9 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
webui_factory_ptr_.get(),
GetContentClient()->browser()->CreateURLLoaderThrottles(
web_contents_getter_),
- 0 /* routing_id? */, 0 /* request_id? */, mojom::kURLLoadOptionNone,
- *resource_request_, this, kTrafficAnnotation);
+ 0 /* routing_id */, 0 /* request_id? */, mojom::kURLLoadOptionNone,
+ *resource_request_, this, kNavigationUrlLoaderTrafficAnnotation,
+ base::ThreadTaskRunnerHandle::Get());
return;
}
@@ -179,7 +194,7 @@ class NavigationURLLoaderNetworkService::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);
+ request_info->common_params.post_data, web_contents_getter_);
if (service_worker_handler)
handlers_.push_back(std::move(service_worker_handler));
}
@@ -207,34 +222,59 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
url_loader_.reset();
handler_index_ = 0;
received_response_ = false;
- MaybeStartLoader(StartLoaderCallback());
+ MaybeStartLoader(nullptr /* handler */, StartLoaderCallback());
}
- void MaybeStartLoader(StartLoaderCallback start_loader_callback) {
+ // |handler| is the one who called this method (as a LoaderCallback), nullptr
+ // if this method is not called by a handler.
+ // |start_loader_callback| is the callback given by the |handler|, non-null
+ // if the |handler| wants to handle the request.
+ void MaybeStartLoader(URLLoaderRequestHandler* handler,
+ StartLoaderCallback start_loader_callback) {
if (start_loader_callback) {
+ // |handler| wants to handle the request.
+ DCHECK(handler);
default_loader_used_ = false;
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
std::move(start_loader_callback),
GetContentClient()->browser()->CreateURLLoaderThrottles(
web_contents_getter_),
- *resource_request_, this, kTrafficAnnotation);
+ frame_tree_node_id_, *resource_request_, this,
+ kNavigationUrlLoaderTrafficAnnotation,
+ base::ThreadTaskRunnerHandle::Get());
- DCHECK_GT(handler_index_, 0U);
+ subresource_loader_params_ =
+ handler->MaybeCreateSubresourceLoaderParams();
- mojom::URLLoaderFactoryPtr subresource_loader_factory =
- handlers_[handler_index_ - 1]->MaybeCreateSubresourceFactory();
- if (subresource_loader_factory.get()) {
- subresource_url_loader_factory_ptr_info_ =
- subresource_loader_factory.PassInterface();
- }
return;
}
+ // Before falling back to the next handler, see if |handler| still wants
+ // to give additional info to the frame for subresource loading.
+ // In that case we will just fall back to the default loader (i.e.
+ // won't go on to the next handlers) but send the subresource_loader_params
+ // to the child process. This is necessary for correctness in the cases
+ // where, e.g. there's a controlling ServiceWorker that doesn't handle main
+ // resource loading, but may still want to control the page and/or handle
+ // subresource loading. In that case we want to skip APpCache.
+ if (handler) {
+ subresource_loader_params_ =
+ handler->MaybeCreateSubresourceLoaderParams();
+
+ // If non-null |subresource_loader_params_| is returned, make sure
+ // we skip the next handlers.
+ if (subresource_loader_params_)
+ handler_index_ = handlers_.size();
+ }
+
+ // See if the next handler wants to handle the request.
if (handler_index_ < handlers_.size()) {
- handlers_[handler_index_++]->MaybeCreateLoader(
+ DCHECK(!subresource_loader_params_);
+ auto* next_handler = handlers_[handler_index_++].get();
+ next_handler->MaybeCreateLoader(
*resource_request_, resource_context_,
base::BindOnce(&URLLoaderRequestController::MaybeStartLoader,
- base::Unretained(this)));
+ base::Unretained(this), next_handler));
return;
}
@@ -247,18 +287,36 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
mojom::URLLoaderFactory* factory = nullptr;
DCHECK_EQ(handlers_.size(), handler_index_);
if (resource_request_->url.SchemeIs(url::kBlobScheme)) {
- factory = default_url_loader_factory_getter_->GetBlobFactory()->get();
+ factory = default_url_loader_factory_getter_->GetBlobFactory();
+ } else if (!IsURLHandledByNetworkService(resource_request_->url) &&
+ !resource_request_->url.SchemeIs(url::kDataScheme)) {
+ 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::BindOnce(&NavigationURLLoaderNetworkService ::
+ BindNonNetworkURLLoaderFactoryRequest,
+ owner_, resource_request_->url,
+ mojo::MakeRequest(&non_network_factory)));
+ }
+ factory = non_network_factory.get();
} else {
- factory = default_url_loader_factory_getter_->GetNetworkFactory()->get();
+ factory = default_url_loader_factory_getter_->GetNetworkFactory();
default_loader_used_ = true;
}
+ url_chain_.push_back(resource_request_->url);
+ uint32_t options = mojom::kURLLoadOptionSendSSLInfoWithResponse |
+ mojom::kURLLoadOptionSniffMimeType;
+ if (resource_request_->resource_type == RESOURCE_TYPE_MAIN_FRAME)
+ options |= mojom::kURLLoadOptionSendSSLInfoForCertificateError;
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
factory,
GetContentClient()->browser()->CreateURLLoaderThrottles(
web_contents_getter_),
- 0 /* routing_id? */, 0 /* request_id? */,
- mojom::kURLLoadOptionSendSSLInfo | mojom::kURLLoadOptionSniffMimeType,
- *resource_request_, this, kTrafficAnnotation);
+ frame_tree_node_id_, 0 /* request_id? */, options, *resource_request_,
+ this, kNavigationUrlLoaderTrafficAnnotation,
+ base::ThreadTaskRunnerHandle::Get());
}
void FollowRedirect() {
@@ -275,84 +333,41 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
// a. For subframe navigations, the Origin header may need to be modified
// differently?
// b. How should redirect_info_.referred_token_binding_host be handled?
- // c. Maybe refactor for code reuse.
-
- if (redirect_info_.new_method != resource_request_->method) {
- resource_request_->method = redirect_info_.new_method;
-
- // TODO(davidben): This logic still needs to be replicated at the
- // consumers.
- //
- // The Origin header is sent on anything that is not a GET or HEAD, which
- // suggests all redirects that change methods (since they always change to
- // GET) should drop the Origin header.
- // See https://fetch.spec.whatwg.org/#origin-header
- // TODO(jww): This is Origin header removal is probably layering
- // violation and should be refactored into //content.
- // See https://crbug.com/471397.
- // See also: https://crbug.com/760487
- resource_request_->headers.RemoveHeader(net::HttpRequestHeaders::kOrigin);
-
- // The inclusion of a multipart Content-Type header can cause problems
- // with some servers:
- // http://code.google.com/p/chromium/issues/detail?id=843
- resource_request_->headers.RemoveHeader(
- net::HttpRequestHeaders::kContentLength);
- resource_request_->headers.RemoveHeader(
- net::HttpRequestHeaders::kContentType);
+ bool should_clear_upload = false;
+ net::RedirectUtil::UpdateHttpRequest(
+ resource_request_->url, resource_request_->method, redirect_info_,
+ &resource_request_->headers, &should_clear_upload);
+ if (should_clear_upload) {
// The request body is no longer applicable.
resource_request_->request_body = nullptr;
blob_handles_.clear();
}
- // Cross-origin redirects should not result in an Origin header value that
- // is equal to the original request's Origin header. This is necessary to
- // a reflection of POST requests to bypass CSRF protections. If the header
- // was prevent not set to "null", a POST request from origin A to a
- // malicious origin M could be redirected by M back to A.
- //
- // This behavior is specified in step 10 of the HTTP-redirect fetch
- // algorithm[1] (which supercedes the behavior outlined in RFC 6454[2].
- //
- // [1]: https://fetch.spec.whatwg.org/#http-redirect-fetch
- // [2]: https://tools.ietf.org/html/rfc6454#section-7
- //
- // TODO(jww): This is a layering violation and should be refactored
- // somewhere up into //net's embedder. https://crbug.com/471397
- if (!url::Origin(redirect_info_.new_url)
- .IsSameOriginWith(url::Origin(resource_request_->url)) &&
- resource_request_->headers.HasHeader(
- net::HttpRequestHeaders::kOrigin)) {
- resource_request_->headers.SetHeader(net::HttpRequestHeaders::kOrigin,
- url::Origin().Serialize());
- }
-
resource_request_->url = redirect_info_.new_url;
+ resource_request_->method = redirect_info_.new_method;
resource_request_->site_for_cookies = redirect_info_.new_site_for_cookies;
resource_request_->referrer = GURL(redirect_info_.new_referrer);
resource_request_->referrer_policy =
Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
redirect_info_.new_referrer_policy);
+ url_chain_.push_back(redirect_info_.new_url);
Restart();
}
// Navigation is intercepted, transfer the |resource_request_|, |url_loader_|
- // and the |completion_status_| to the new owner. The new owner is
- // responsible for handling all the mojom::URLLoaderClient callbacks from now
- // on.
+ // and the |status_| to the new owner. The new owner is responsible for
+ // handling all the mojom::URLLoaderClient callbacks from now on.
void InterceptNavigation(
NavigationURLLoader::NavigationInterceptionCB callback) {
std::move(callback).Run(std::move(resource_request_),
- std::move(url_loader_),
- std::move(completion_status_));
+ std::move(url_loader_), std::move(url_chain_),
+ std::move(status_));
}
- // Ownership of the URLLoaderFactoryPtrInfo instance is transferred to the
- // caller.
- mojom::URLLoaderFactoryPtrInfo GetSubresourceURLLoaderFactory() {
- return std::move(subresource_url_loader_factory_ptr_info_);
+ base::Optional<SubresourceLoaderParams> TakeSubresourceLoaderParams() {
+ return std::move(subresource_loader_params_);
}
private:
@@ -386,7 +401,8 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
const ResourceResponseHead& head) override {
if (--redirect_limit_ == 0) {
- OnComplete(ResourceRequestCompletionStatus(net::ERR_TOO_MANY_REDIRECTS));
+ OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_TOO_MANY_REDIRECTS));
return;
}
@@ -425,20 +441,28 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
owner_, base::Passed(&body)));
}
- void OnComplete(
- const ResourceRequestCompletionStatus& completion_status) override {
- if (completion_status.error_code != net::OK && !received_response_) {
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override {
+ UMA_HISTOGRAM_BOOLEAN(
+ "Navigation.URLLoaderNetworkService.OnCompleteHadSSLInfo",
+ status.ssl_info.has_value());
+ if (status.ssl_info.has_value()) {
+ UMA_HISTOGRAM_MEMORY_KB(
+ "Navigation.URLLoaderNetworkService.OnCompleteCertificateChainsSize",
+ GetCertificateChainsSizeInKB(status.ssl_info.value()));
+ }
+
+ if (status.error_code != net::OK && !received_response_) {
// If the default loader (network) was used to handle the URL load
// request we need to see if the handlers want to potentially create a
// new loader for the response. e.g. AppCache.
if (MaybeCreateLoaderForResponse(ResourceResponseHead()))
return;
}
- completion_status_ = completion_status;
+ status_ = status;
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&NavigationURLLoaderNetworkService::OnComplete, owner_,
- completion_status));
+ status));
}
// Returns true if a handler wants to handle the response, i.e. return a
@@ -464,18 +488,20 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
size_t handler_index_ = 0;
std::unique_ptr<ResourceRequest> resource_request_;
+ int frame_tree_node_id_ = 0;
net::RedirectInfo redirect_info_;
- int redirect_limit_ = kMaxRedirects;
+ int redirect_limit_ = net::URLRequest::kMaxRedirects;
ResourceContext* resource_context_;
base::Callback<WebContents*()> web_contents_getter_;
scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_;
mojom::URLLoaderFactoryPtr webui_factory_ptr_;
std::unique_ptr<ThrottlingURLLoader> url_loader_;
BlobHandles blob_handles_;
+ std::vector<GURL> url_chain_;
// Currently used by the AppCache loader to pass its factory to the
// renderer which enables it to handle subresources.
- mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_ptr_info_;
+ base::Optional<SubresourceLoaderParams> subresource_loader_params_;
// This is referenced only on the UI thread.
base::WeakPtr<NavigationURLLoaderNetworkService> owner_;
@@ -498,11 +524,16 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
bool started_ = false;
+ // Lazily initialized and used in the case of non-network resource
+ // navigations. Keyed by URL scheme.
+ std::map<std::string, mojom::URLLoaderFactoryPtr>
+ non_network_url_loader_factories_;
+
// The completion status if it has been received. This is needed to handle
// the case that the response is intercepted by download, and OnComplete() is
// already called while we are transferring the |url_loader_| and response
// body to download code.
- base::Optional<ResourceRequestCompletionStatus> completion_status_;
+ base::Optional<network::URLLoaderCompletionStatus> status_;
DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
};
@@ -520,19 +551,21 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
allow_download_(request_info->common_params.allow_download),
weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ int frame_tree_node_id = request_info->frame_tree_node_id;
TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
"navigation", "Navigation timeToResponseStarted", this,
request_info->common_params.navigation_start, "FrameTreeNode id",
- request_info->frame_tree_node_id);
+ frame_tree_node_id);
// TODO(scottmg): Port over stuff from RDHI::BeginNavigationRequest() here.
- auto new_request = base::MakeUnique<ResourceRequest>();
+ auto new_request = std::make_unique<ResourceRequest>();
new_request->method = request_info->common_params.method;
new_request->url = request_info->common_params.url;
new_request->site_for_cookies = request_info->site_for_cookies;
new_request->priority = net::HIGHEST;
+ new_request->render_frame_id = frame_tree_node_id;
// The code below to set fields like request_initiator, referrer, etc has
// been copied from ResourceDispatcherHostImpl. We did not refactor the
@@ -543,6 +576,10 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
new_request->referrer_policy = request_info->common_params.referrer.policy;
new_request->headers.AddHeadersFromString(request_info->begin_params.headers);
+ new_request->resource_type = request_info->is_main_frame
+ ? RESOURCE_TYPE_MAIN_FRAME
+ : RESOURCE_TYPE_SUB_FRAME;
+
int load_flags = request_info->begin_params.load_flags;
load_flags |= net::LOAD_VERIFY_EV_CERT;
if (request_info->is_main_frame)
@@ -557,46 +594,62 @@ NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
new_request->request_body = request_info->common_params.post_data.get();
new_request->report_raw_headers = request_info->report_raw_headers;
new_request->allow_download = allow_download_;
+ new_request->enable_load_timing = true;
- new_request->fetch_request_mode = FETCH_REQUEST_MODE_NAVIGATE;
- new_request->fetch_credentials_mode = FETCH_CREDENTIALS_MODE_INCLUDE;
+ new_request->fetch_request_mode = network::mojom::FetchRequestMode::kNavigate;
+ new_request->fetch_credentials_mode =
+ network::mojom::FetchCredentialsMode::kInclude;
new_request->fetch_redirect_mode = FetchRedirectMode::MANUAL_MODE;
- int frame_tree_node_id = request_info->frame_tree_node_id;
-
// Check if a web UI scheme wants to handle this request.
+ FrameTreeNode* frame_tree_node =
+ FrameTreeNode::GloballyFindByID(frame_tree_node_id);
mojom::URLLoaderFactoryPtrInfo factory_for_webui;
const auto& schemes = URLDataManagerBackend::GetWebUISchemes();
- if (std::find(schemes.begin(), schemes.end(), new_request->url.scheme()) !=
- schemes.end()) {
- FrameTreeNode* frame_tree_node =
- FrameTreeNode::GloballyFindByID(frame_tree_node_id);
- factory_for_webui = CreateWebUIURLLoader(frame_tree_node).PassInterface();
+ std::string scheme = new_request->url.scheme();
+ if (std::find(schemes.begin(), schemes.end(), scheme) != schemes.end()) {
+ factory_for_webui =
+ CreateWebUIURLLoader(frame_tree_node->current_frame_host(), scheme)
+ .PassInterface();
}
g_next_request_id--;
+ auto* partition = static_cast<StoragePartitionImpl*>(storage_partition);
DCHECK(!request_controller_);
- request_controller_ = base::MakeUnique<URLLoaderRequestController>(
+ request_controller_ = std::make_unique<URLLoaderRequestController>(
std::move(initial_handlers), std::move(new_request), resource_context,
- static_cast<StoragePartitionImpl*>(storage_partition)
- ->url_loader_factory_getter(),
- weak_factory_.GetWeakPtr());
+ partition->url_loader_factory_getter(), weak_factory_.GetWeakPtr());
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &URLLoaderRequestController::Start,
- base::Unretained(request_controller_.get()),
- service_worker_navigation_handle
- ? service_worker_navigation_handle->core()
- : nullptr,
- appcache_handle ? appcache_handle->core() : nullptr,
- base::Passed(std::move(request_info)),
- base::Passed(std::move(factory_for_webui)),
- base::Bind(&GetWebContentsFromFrameTreeNodeID, frame_tree_node_id),
- base::Passed(ServiceManagerConnection::GetForProcess()
- ->GetConnector()
- ->Clone())));
+ base::BindOnce(&URLLoaderRequestController::Start,
+ base::Unretained(request_controller_.get()),
+ service_worker_navigation_handle
+ ? service_worker_navigation_handle->core()
+ : nullptr,
+ appcache_handle ? appcache_handle->core() : nullptr,
+ base::Passed(std::move(request_info)),
+ base::Passed(std::move(factory_for_webui)),
+ frame_tree_node_id,
+ base::Passed(ServiceManagerConnection::GetForProcess()
+ ->GetConnector()
+ ->Clone())));
+
+ non_network_url_loader_factories_[url::kFileScheme] =
+ std::make_unique<FileURLLoaderFactory>(
+ partition->browser_context()->GetPath(),
+ base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}));
+
+ if (frame_tree_node) {
+ // |frame_tree_node| may be null in some unit test environments.
+ GetContentClient()
+ ->browser()
+ ->RegisterNonNetworkNavigationURLLoaderFactories(
+ frame_tree_node->current_frame_host(),
+ &non_network_url_loader_factories_);
+ }
}
NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {
@@ -629,10 +682,9 @@ void NavigationURLLoaderNetworkService::OnReceiveResponse(
// TODO(scottmg): This needs to do more of what
// NavigationResourceHandler::OnResponseStarted() does. Or maybe in
// OnStartLoadingResponseBody().
- if (ssl_info && ssl_info->cert)
- NavigationResourceHandler::GetSSLStatusForRequest(*ssl_info, &ssl_status_);
response_ = std::move(response);
- ssl_info_ = ssl_info;
+ if (ssl_info.has_value())
+ ssl_info_ = ssl_info.value();
}
void NavigationURLLoaderNetworkService::OnReceiveRedirect(
@@ -654,15 +706,15 @@ void NavigationURLLoaderNetworkService::OnStartLoadingResponseBody(
// delegate until PlzNavigate has shipped and we can be comfortable fully
// switching to the data pipe.
delegate_->OnResponseStarted(
- response_, nullptr, std::move(body), ssl_status_,
+ response_, nullptr, std::move(body), ssl_info_,
std::unique_ptr<NavigationData>(), GlobalRequestID(-1, g_next_request_id),
IsDownload(), false /* is_stream */,
- request_controller_->GetSubresourceURLLoaderFactory());
+ request_controller_->TakeSubresourceLoaderParams());
}
void NavigationURLLoaderNetworkService::OnComplete(
- const ResourceRequestCompletionStatus& completion_status) {
- if (completion_status.error_code == net::OK)
+ const network::URLLoaderCompletionStatus& status) {
+ if (status.error_code == net::OK)
return;
TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this,
@@ -672,10 +724,8 @@ void NavigationURLLoaderNetworkService::OnComplete(
// TODO(https://crbug.com/757633): Pass real values in the case of cert
// errors.
bool should_ssl_errors_be_fatal = true;
-
- delegate_->OnRequestFailed(completion_status.exists_in_cache,
- completion_status.error_code, ssl_info_,
- should_ssl_errors_be_fatal);
+ delegate_->OnRequestFailed(status.exists_in_cache, status.error_code,
+ status.ssl_info, should_ssl_errors_be_fatal);
}
bool NavigationURLLoaderNetworkService::IsDownload() const {
@@ -706,4 +756,15 @@ bool NavigationURLLoaderNetworkService::IsDownload() const {
response_->head.headers->response_code() / 100 == 2);
}
+void NavigationURLLoaderNetworkService::BindNonNetworkURLLoaderFactoryRequest(
+ const GURL& url,
+ mojom::URLLoaderFactoryRequest factory) {
+ auto it = non_network_url_loader_factories_.find(url.scheme());
+ if (it == non_network_url_loader_factories_.end()) {
+ DVLOG(1) << "Ignoring request with unknown scheme: " << url.spec();
+ return;
+ }
+ it->second->Clone(std::move(factory));
+}
+
} // namespace content
diff --git a/chromium/content/browser/loader/navigation_url_loader_network_service.h b/chromium/content/browser/loader/navigation_url_loader_network_service.h
index 4db32092590..9306d9fbd7c 100644
--- a/chromium/content/browser/loader/navigation_url_loader_network_service.h
+++ b/chromium/content/browser/loader/navigation_url_loader_network_service.h
@@ -8,8 +8,10 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/loader/navigation_url_loader.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/common/url_loader.mojom.h"
+#include "content/public/common/url_loader_factory.mojom.h"
namespace net {
struct RedirectInfo;
@@ -19,6 +21,7 @@ namespace content {
class ResourceContext;
class NavigationPostDataHandler;
+class StoragePartition;
class URLLoaderRequestHandler;
// This is an implementation of NavigationURLLoader used when
@@ -50,24 +53,31 @@ class CONTENT_EXPORT NavigationURLLoaderNetworkService
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
scoped_refptr<ResourceResponse> response);
void OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body);
- void OnComplete(const ResourceRequestCompletionStatus& completion_status);
+ void OnComplete(const network::URLLoaderCompletionStatus& status);
private:
class URLLoaderRequestController;
bool IsDownload() const;
+ void BindNonNetworkURLLoaderFactoryRequest(
+ const GURL& url,
+ mojom::URLLoaderFactoryRequest factory);
+
NavigationURLLoaderDelegate* delegate_;
scoped_refptr<ResourceResponse> response_;
- base::Optional<net::SSLInfo> ssl_info_;
- SSLStatus ssl_status_;
+ net::SSLInfo ssl_info_;
// Lives on the IO thread.
std::unique_ptr<URLLoaderRequestController> request_controller_;
bool allow_download_;
+ // Factories to handle navigation requests for non-network resources.
+ ContentBrowserClient::NonNetworkURLLoaderFactoryMap
+ non_network_url_loader_factories_;
+
base::WeakPtrFactory<NavigationURLLoaderNetworkService> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(NavigationURLLoaderNetworkService);
diff --git a/chromium/content/browser/loader/navigation_url_loader_network_service_unittest.cc b/chromium/content/browser/loader/navigation_url_loader_network_service_unittest.cc
index 6dd434ac981..88a731a2af6 100644
--- a/chromium/content/browser/loader/navigation_url_loader_network_service_unittest.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_network_service_unittest.cc
@@ -12,7 +12,7 @@
#include "content/common/navigation_params.h"
#include "content/common/service_manager/service_manager_connection_impl.h"
#include "content/network/network_context.h"
-#include "content/network/url_loader_impl.h"
+#include "content/network/url_loader.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_ui_data.h"
@@ -27,6 +27,7 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
namespace content {
@@ -51,14 +52,11 @@ class TestURLLoaderRequestHandler : public URLLoaderRequestHandler {
mojom::URLLoaderRequest request,
mojom::URLLoaderClientPtr client) {
*most_recent_resource_request_ = resource_request;
- // The URLLoaderImpl will delete itself upon completion.
- new URLLoaderImpl(context_.get(), std::move(request), 0 /* options */,
- resource_request, false /* report_raw_headers */,
- std::move(client), TRAFFIC_ANNOTATION_FOR_TESTS);
- }
-
- mojom::URLLoaderFactoryPtr MaybeCreateSubresourceFactory() override {
- return nullptr;
+ // The URLLoader will delete itself upon completion.
+ new URLLoader(context_.get(), std::move(request), 0 /* options */,
+ resource_request, false /* report_raw_headers */,
+ std::move(client), TRAFFIC_ANNOTATION_FOR_TESTS,
+ 0 /* process_id */);
}
bool MaybeCreateLoaderForResponse(
@@ -90,7 +88,7 @@ class NavigationURLLoaderNetworkServiceTest : public testing::Test {
// GetNetworkService.
service_manager::mojom::ServicePtr service;
ServiceManagerConnection::SetForProcess(
- base::MakeUnique<ServiceManagerConnectionImpl>(
+ std::make_unique<ServiceManagerConnectionImpl>(
mojo::MakeRequest(&service),
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
@@ -110,10 +108,10 @@ class NavigationURLLoaderNetworkServiceTest : public testing::Test {
NavigationURLLoaderDelegate* delegate,
bool allow_download = false) {
BeginNavigationParams begin_params(
- headers, net::LOAD_NORMAL, false /* has_user_gesture */,
- false /* skip_service_worker */, REQUEST_CONTEXT_TYPE_LOCATION,
+ headers, net::LOAD_NORMAL, false /* skip_service_worker */,
+ REQUEST_CONTEXT_TYPE_LOCATION,
blink::WebMixedContentContextType::kBlockable,
- false /* is_form_submission */, url::Origin(url));
+ false /* is_form_submission */, url::Origin::Create(url));
CommonNavigationParams common_params;
common_params.url = url;
@@ -126,14 +124,14 @@ class NavigationURLLoaderNetworkServiceTest : public testing::Test {
false /* parent_is_main_frame */, false /* are_ancestors_secure */,
-1 /* frame_tree_node_id */, false /* is_for_guests_only */,
false /* report_raw_headers */,
- blink::kWebPageVisibilityStateVisible));
+ blink::mojom::PageVisibilityState::kVisible));
std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers;
most_recent_resource_request_ = base::nullopt;
- handlers.push_back(base::MakeUnique<TestURLLoaderRequestHandler>(
+ handlers.push_back(std::make_unique<TestURLLoaderRequestHandler>(
&most_recent_resource_request_));
- return base::MakeUnique<NavigationURLLoaderNetworkService>(
+ return std::make_unique<NavigationURLLoaderNetworkService>(
browser_context_->GetResourceContext(),
BrowserContext::GetDefaultStoragePartition(browser_context_.get()),
std::move(request_info), nullptr /* navigation_ui_data */,
diff --git a/chromium/content/browser/loader/navigation_url_loader_unittest.cc b/chromium/content/browser/loader/navigation_url_loader_unittest.cc
index 6138cb1e309..3a57147ebb9 100644
--- a/chromium/content/browser/loader/navigation_url_loader_unittest.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_unittest.cc
@@ -44,6 +44,7 @@
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "url/origin.h"
namespace content {
@@ -106,7 +107,7 @@ class RequestBlockingResourceDispatcherHostDelegate
std::unique_ptr<ResourceHandler> CreateDownloadResourceHandler(
net::URLRequest* request) {
- return base::MakeUnique<TestResourceHandler>();
+ return std::make_unique<TestResourceHandler>();
}
} // namespace
@@ -117,7 +118,8 @@ class NavigationURLLoaderTest : public testing::Test {
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
browser_context_(new TestBrowserContext),
host_(base::Bind(&CreateDownloadResourceHandler),
- base::ThreadTaskRunnerHandle::Get()) {
+ base::ThreadTaskRunnerHandle::Get(),
+ /* enable_resource_scheduler */ true) {
host_.SetLoaderDelegate(&loader_delegate_);
BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
base::RunLoop().RunUntilIdle();
@@ -127,10 +129,10 @@ class NavigationURLLoaderTest : public testing::Test {
job_factory_.SetProtocolHandler(
"test", net::URLRequestTestJob::CreateProtocolHandler());
job_factory_.SetProtocolHandler(
- "blob", base::MakeUnique<StreamProtocolHandler>(
+ "blob", std::make_unique<StreamProtocolHandler>(
StreamContext::GetFor(browser_context_.get())->registry()));
job_factory_.SetProtocolHandler(
- "download", base::MakeUnique<DownloadProtocolHandler>());
+ "download", std::make_unique<DownloadProtocolHandler>());
request_context->set_job_factory(&job_factory_);
// NavigationURLLoader is only used for browser-side navigations.
@@ -149,11 +151,10 @@ class NavigationURLLoaderTest : public testing::Test {
NavigationURLLoaderDelegate* delegate,
bool allow_download) {
BeginNavigationParams begin_params(
- std::string(), net::LOAD_NORMAL, false, false,
- REQUEST_CONTEXT_TYPE_LOCATION,
+ std::string(), net::LOAD_NORMAL, false, REQUEST_CONTEXT_TYPE_LOCATION,
blink::WebMixedContentContextType::kBlockable,
false, // is_form_submission
- url::Origin(url));
+ url::Origin::Create(url));
CommonNavigationParams common_params;
common_params.url = url;
common_params.allow_download = allow_download;
@@ -161,7 +162,7 @@ class NavigationURLLoaderTest : public testing::Test {
std::unique_ptr<NavigationRequestInfo> request_info(
new NavigationRequestInfo(common_params, begin_params, url, true, false,
false, -1, false, false,
- blink::kWebPageVisibilityStateVisible));
+ blink::mojom::PageVisibilityState::kVisible));
return NavigationURLLoader::Create(
browser_context_->GetResourceContext(),
BrowserContext::GetDefaultStoragePartition(browser_context_.get()),
@@ -223,7 +224,7 @@ TEST_F(NavigationURLLoaderTest, RequestFailedNoCertError) {
// Wait for the request to fail as expected.
delegate.WaitForRequestFailed();
EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME, delegate.net_error());
- EXPECT_FALSE(delegate.ssl_info().has_value());
+ EXPECT_FALSE(delegate.ssl_info().is_valid());
EXPECT_EQ(1, delegate.on_request_handled_counter());
}
@@ -243,8 +244,8 @@ TEST_F(NavigationURLLoaderTest, RequestFailedCertError) {
// Wait for the request to fail as expected.
delegate.WaitForRequestFailed();
ASSERT_EQ(net::ERR_ABORTED, delegate.net_error());
- net::SSLInfo ssl_info = delegate.ssl_info().value();
- EXPECT_TRUE(net::MapCertStatusToNetError(ssl_info.is_valid()));
+ net::SSLInfo ssl_info = delegate.ssl_info();
+ EXPECT_TRUE(ssl_info.is_valid());
EXPECT_TRUE(https_server.GetCertificate()->Equals(ssl_info.cert.get()));
EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID,
net::MapCertStatusToNetError(ssl_info.cert_status));
@@ -276,8 +277,8 @@ TEST_F(NavigationURLLoaderTest, RequestFailedCertErrorFatal) {
// Wait for the request to fail as expected.
delegate.WaitForRequestFailed();
ASSERT_EQ(net::ERR_ABORTED, delegate.net_error());
- net::SSLInfo ssl_info = delegate.ssl_info().value();
- EXPECT_TRUE(net::MapCertStatusToNetError(ssl_info.is_valid()));
+ net::SSLInfo ssl_info = delegate.ssl_info();
+ EXPECT_TRUE(ssl_info.is_valid());
EXPECT_TRUE(https_server.GetCertificate()->Equals(ssl_info.cert.get()));
EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID,
net::MapCertStatusToNetError(ssl_info.cert_status));
@@ -393,7 +394,9 @@ TEST_F(NavigationURLLoaderTest, RequestBlocked) {
// Wait for the request to fail as expected.
delegate.WaitForRequestFailed();
EXPECT_EQ(net::ERR_ABORTED, delegate.net_error());
- EXPECT_EQ(1, delegate.on_request_handled_counter());
+
+ // Failing before start means OnRequestStarted is never called.
+ EXPECT_EQ(0, delegate.on_request_handled_counter());
host_.SetDelegate(nullptr);
}
diff --git a/chromium/content/browser/loader/redirect_to_file_resource_handler.cc b/chromium/content/browser/loader/redirect_to_file_resource_handler.cc
index d6acbbca87a..722831e21bf 100644
--- a/chromium/content/browser/loader/redirect_to_file_resource_handler.cc
+++ b/chromium/content/browser/loader/redirect_to_file_resource_handler.cc
@@ -34,14 +34,13 @@ namespace {
// somewhat fragile, however, and depending on it is dangerous. A more
// principled approach would require significant refactoring, however, so for
// the moment we're relying on fragile properties.
-class DependentIOBuffer : public net::WrappedIOBuffer {
+class DependentIOBufferForRedirectToFile : public net::WrappedIOBuffer {
public:
- DependentIOBuffer(net::IOBuffer* backing, char* memory)
- : net::WrappedIOBuffer(memory),
- backing_(backing) {
- }
+ DependentIOBufferForRedirectToFile(net::IOBuffer* backing, char* memory)
+ : net::WrappedIOBuffer(memory), backing_(backing) {}
+
private:
- ~DependentIOBuffer() override {}
+ ~DependentIOBufferForRedirectToFile() override {}
scoped_refptr<net::IOBuffer> backing_;
};
@@ -85,7 +84,7 @@ class RedirectToFileResourceHandler::Writer {
}
void Close() {
- handler_ = NULL;
+ handler_ = nullptr;
if (!is_writing_)
CloseAndDelete();
}
@@ -140,7 +139,7 @@ RedirectToFileResourceHandler::~RedirectToFileResourceHandler() {
// Orphan the writer to asynchronously close and release the temporary file.
if (writer_) {
writer_->Close();
- writer_ = NULL;
+ writer_ = nullptr;
}
}
@@ -343,8 +342,9 @@ bool RedirectToFileResourceHandler::WriteMore() {
// Also note that Write may increase the refcount of "wrapped" deep in the
// bowels of its implementation, the use of scoped_refptr here is not
// spurious.
- scoped_refptr<DependentIOBuffer> wrapped = new DependentIOBuffer(
- buf_.get(), buf_->StartOfBuffer() + write_cursor_);
+ scoped_refptr<DependentIOBufferForRedirectToFile> wrapped =
+ new DependentIOBufferForRedirectToFile(
+ buf_.get(), buf_->StartOfBuffer() + write_cursor_);
int write_len = buf_->offset() - write_cursor_;
int rv = writer_->Write(wrapped.get(), write_len);
diff --git a/chromium/content/browser/loader/redirect_to_file_resource_handler_unittest.cc b/chromium/content/browser/loader/redirect_to_file_resource_handler_unittest.cc
index 5eac03920a6..26c61f089a0 100644
--- a/chromium/content/browser/loader/redirect_to_file_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/redirect_to_file_resource_handler_unittest.cc
@@ -214,7 +214,7 @@ class RedirectToFileResourceHandlerTest
TRAFFIC_ANNOTATION_FOR_TESTS)) {
base::CreateTemporaryFile(&temp_file_path_);
std::unique_ptr<TestResourceHandler> test_handler =
- base::MakeUnique<TestResourceHandler>();
+ std::make_unique<TestResourceHandler>();
test_handler->set_expect_on_data_downloaded(true);
if (GetParam() == CompletionMode::ASYNC) {
// Don't defer OnResponseCompleted, by default, since that's really
@@ -224,16 +224,16 @@ class RedirectToFileResourceHandlerTest
}
test_handler_ = test_handler->GetWeakPtr();
- redirect_to_file_handler_ = base::MakeUnique<RedirectToFileResourceHandler>(
+ redirect_to_file_handler_ = std::make_unique<RedirectToFileResourceHandler>(
std::move(test_handler), url_request_.get());
mock_loader_ =
- base::MakeUnique<MockResourceLoader>(redirect_to_file_handler_.get());
+ std::make_unique<MockResourceLoader>(redirect_to_file_handler_.get());
redirect_to_file_handler_->SetCreateTemporaryFileStreamFunctionForTesting(
base::Bind(&RedirectToFileResourceHandlerTest::
SetCreateTemporaryFileStreamCallback,
base::Unretained(this)));
- file_stream_ = base::MakeUnique<MockFileStream>();
+ file_stream_ = std::make_unique<MockFileStream>();
file_stream_->set_open_result(
MockFileStream::OperationResult(net::OK, GetParam()));
file_stream_->set_all_write_results(MockFileStream::OperationResult(
diff --git a/chromium/content/browser/loader/resource_buffer.cc b/chromium/content/browser/loader/resource_buffer.cc
index 3f5a5c89b97..5e34dd24f15 100644
--- a/chromium/content/browser/loader/resource_buffer.cc
+++ b/chromium/content/browser/loader/resource_buffer.cc
@@ -58,7 +58,7 @@ bool ResourceBuffer::Initialize(int buffer_size,
}
bool ResourceBuffer::IsInitialized() const {
- return shared_mem_.memory() != NULL;
+ return shared_mem_.memory() != nullptr;
}
base::SharedMemory& ResourceBuffer::GetSharedMemory() {
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc b/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc
index 3a1f764db73..1104418f7c6 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_browsertest.cc
@@ -261,7 +261,7 @@ std::unique_ptr<net::test_server::HttpResponse> CancelOnRequest(
base::Unretained(ResourceDispatcherHostImpl::Get()),
child_id));
- return base::MakeUnique<net::test_server::HungResponse>();
+ return std::make_unique<net::test_server::HungResponse>();
}
} // namespace
@@ -643,14 +643,14 @@ class PreviewsStateResourceDispatcherHostDelegate
ResourceDispatcherHost::Get()->SetDelegate(this);
}
- PreviewsState GetPreviewsState(
- const net::URLRequest& request,
+ PreviewsState DeterminePreviewsState(
+ net::URLRequest* request,
content::ResourceContext* resource_context,
content::PreviewsState previews_to_allow) override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
EXPECT_FALSE(should_get_previews_state_called_);
should_get_previews_state_called_ = true;
- EXPECT_EQ(main_frame_url_, request.url());
+ EXPECT_EQ(main_frame_url_, request->url());
return previews_state_;
}
@@ -843,7 +843,7 @@ class RequestDataResourceDispatcherHostDelegate
AppCacheService* appcache_service,
ResourceType resource_type,
std::vector<std::unique_ptr<ResourceThrottle>>* throttles) override {
- requests_.push_back(base::MakeUnique<RequestDataForDelegate>(
+ requests_.push_back(std::make_unique<RequestDataForDelegate>(
request->url(), request->site_for_cookies(), request->initiator(),
request->load_flags(), request->referrer()));
}
@@ -885,7 +885,7 @@ class RequestDataResourceDispatcherHostBrowserTest : public ContentBrowserTest {
IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, Basic) {
GURL top_url(embedded_test_server()->GetURL("/page_with_subresources.html"));
- url::Origin top_origin(top_url);
+ url::Origin top_origin = url::Origin::Create(top_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
@@ -917,7 +917,7 @@ IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, Basic) {
IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest,
LinkRelPrefetch) {
GURL top_url(embedded_test_server()->GetURL("/link_rel_prefetch.html"));
- url::Origin top_origin(top_url);
+ url::Origin top_origin = url::Origin::Create(top_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
@@ -932,7 +932,7 @@ IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest,
LinkRelPrefetchReferrerPolicy) {
GURL top_url(embedded_test_server()->GetURL(
"/link_rel_prefetch_referrer_policy.html"));
- url::Origin top_origin(top_url);
+ url::Origin top_origin = url::Origin::Create(top_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
@@ -950,8 +950,8 @@ IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest,
"a.com", "/nested_page_with_subresources.html"));
GURL nested_url(embedded_test_server()->GetURL(
"not-a.com", "/page_with_subresources.html"));
- url::Origin top_origin(top_url);
- url::Origin nested_origin(nested_url);
+ url::Origin top_origin = url::Origin::Create(top_url);
+ url::Origin nested_origin = url::Origin::Create(nested_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
@@ -989,7 +989,7 @@ IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest,
GURL top_url(embedded_test_server()->GetURL("/page_with_iframe.html"));
GURL image_url(embedded_test_server()->GetURL("/image.jpg"));
GURL nested_url(embedded_test_server()->GetURL("/title1.html"));
- url::Origin top_origin(top_url);
+ url::Origin top_origin = url::Origin::Create(top_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
@@ -1024,7 +1024,7 @@ IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest,
SameOriginAuxiliary) {
GURL top_url(embedded_test_server()->GetURL("/simple_links.html"));
GURL auxiliary_url(embedded_test_server()->GetURL("/title2.html"));
- url::Origin top_origin(top_url);
+ url::Origin top_origin = url::Origin::Create(top_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
@@ -1063,7 +1063,7 @@ IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest,
CrossOriginAuxiliary) {
GURL top_url(embedded_test_server()->GetURL("/simple_links.html"));
GURL auxiliary_url(embedded_test_server()->GetURL("foo.com", "/title2.html"));
- url::Origin top_origin(top_url);
+ url::Origin top_origin = url::Origin::Create(top_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
@@ -1111,7 +1111,7 @@ IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest,
// Navigating to this URL will fail, as we haven't taught the host resolver
// about 'a.com'.
GURL top_url(embedded_test_server()->GetURL("a.com", "/simple_page.html"));
- url::Origin top_origin(top_url);
+ url::Origin top_origin = url::Origin::Create(top_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
@@ -1140,8 +1140,8 @@ IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest,
"b.com", "/cross_site_iframe_factory.html?b()"));
GURL nested_js_url(
embedded_test_server()->GetURL("b.com", "/tree_parser_util.js"));
- url::Origin top_origin(top_url);
- url::Origin nested_origin(nested_url);
+ url::Origin top_origin = url::Origin::Create(top_url);
+ url::Origin nested_origin = url::Origin::Create(nested_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
index b372f8a6f76..210ed592e24 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -66,19 +66,21 @@
#include "content/browser/loader/upload_data_stream_builder.h"
#include "content/browser/loader/wake_lock_resource_throttle.h"
#include "content/browser/resource_context_impl.h"
-#include "content/browser/service_worker/foreign_fetch_request_handler.h"
-#include "content/browser/service_worker/link_header_support.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
#include "content/browser/streams/stream.h"
#include "content/browser/streams/stream_context.h"
#include "content/browser/streams/stream_registry.h"
+#include "content/common/loader_util.h"
#include "content/common/net/url_request_service_worker_data.h"
#include "content/common/resource_messages.h"
#include "content/common/site_isolation_policy.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/child_process_data.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/navigation_ui_data.h"
#include "content/public/browser/plugin_service.h"
@@ -88,10 +90,12 @@
#include "content/public/browser/stream_handle.h"
#include "content/public/browser/stream_info.h"
#include "content/public/common/browser_side_navigation_policy.h"
+#include "content/public/common/child_process_host.h"
+#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/origin_util.h"
#include "content/public/common/resource_request.h"
#include "content/public/common/resource_request_body.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_start.h"
#include "net/base/auth.h"
@@ -115,12 +119,14 @@
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_job_factory.h"
#include "ppapi/features/features.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/blob/blob_url_request_job_factory.h"
#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/file_permission_policy.h"
#include "storage/browser/fileapi/file_system_context.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "url/third_party/mozilla/url_parse.h"
#include "url/url_constants.h"
@@ -133,36 +139,6 @@ using SyncLoadResultCallback =
// ----------------------------------------------------------------------------
-namespace {
-
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
- net::DefineNetworkTrafficAnnotation("resource_dispatcher_host",
- R"(
- semantics {
- sender: "Resource Dispatcher Host"
- description:
- "Navigation-initiated request or renderer process initiated "
- "request, which includes all resources for normal page loads, "
- "chrome URLs, resources for installed extensions, as well as "
- "downloads."
- trigger:
- "Navigating to a URL or downloading a file. A webpage, "
- "ServiceWorker, chrome:// page, or extension may also initiate "
- "requests in the background."
- data: "Anything the initiator wants to send."
- destination: OTHER
- }
- policy {
- cookies_allowed: YES
- cookies_store: "user or per-app cookie store"
- setting: "These requests cannot be disabled."
- policy_exception_justification:
- "Not implemented. Without these requests, Chrome will be unable to "
- "load any webpage."
- })");
-
-} // namespace
-
namespace content {
namespace {
@@ -211,18 +187,17 @@ void AbortRequestBeforeItStarts(
sync_result_handler.Run(&result);
} else {
// Tell the renderer that this request was disallowed.
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = net::ERR_ABORTED;
- request_complete_data.exists_in_cache = false;
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::ERR_ABORTED;
+ status.exists_in_cache = false;
// No security info needed, connection not established.
- request_complete_data.completion_time = base::TimeTicks();
- request_complete_data.encoded_data_length = 0;
- request_complete_data.encoded_body_length = 0;
+ status.completion_time = base::TimeTicks();
+ status.encoded_data_length = 0;
+ status.encoded_body_length = 0;
if (url_loader_client) {
- url_loader_client->OnComplete(request_complete_data);
+ url_loader_client->OnComplete(status);
} else {
- sender->Send(
- new ResourceMsg_RequestComplete(request_id, request_complete_data));
+ sender->Send(new ResourceMsg_RequestComplete(request_id, status));
}
}
}
@@ -243,11 +218,11 @@ bool IsValidatedSCT(
// If previews_to_allow is set to anything other than PREVIEWS_UNSPECIFIED,
// it is either the values passed in for a sub-frame to use, or if this is
// the main frame, it is a limitation on which previews to allow.
-PreviewsState GetPreviewsState(PreviewsState previews_to_allow,
- ResourceDispatcherHostDelegate* delegate,
- const net::URLRequest& request,
- ResourceContext* resource_context,
- bool is_main_frame) {
+PreviewsState DeterminePreviewsState(PreviewsState previews_to_allow,
+ ResourceDispatcherHostDelegate* delegate,
+ net::URLRequest* request,
+ ResourceContext* resource_context,
+ bool is_main_frame) {
// If previews have already been turned off, or we are inheriting values on a
// sub-frame, don't check any further.
if (previews_to_allow & PREVIEWS_OFF ||
@@ -257,8 +232,8 @@ PreviewsState GetPreviewsState(PreviewsState previews_to_allow,
}
// Get the mask of previews we could apply to the current navigation.
- PreviewsState previews_state =
- delegate->GetPreviewsState(request, resource_context, previews_to_allow);
+ PreviewsState previews_state = delegate->DeterminePreviewsState(
+ request, resource_context, previews_to_allow);
return previews_state;
}
@@ -279,6 +254,32 @@ void HandleSyncLoadResult(base::WeakPtr<ResourceMessageFilter> filter,
filter->Send(sync_result.release());
}
+bool ValidatePluginChildId(int plugin_child_id) {
+ if (plugin_child_id == ChildProcessHost::kInvalidUniqueID)
+ return true;
+
+#if BUILDFLAG(ENABLE_PLUGINS)
+ // TODO(nick): These checks could be stricter, since they enforce only that
+ // |plugin_child_id| is a valid plugin process, and not that it has a plugin
+ // instance owned by the renderer process making the resource request. Fix
+ // this by eliminating |plugin_child_id| altogether, and stop proxying plugin
+ // URL requests through the renderer (https://crbug.com/778711).
+ auto* plugin_host = BrowserChildProcessHost::FromID(plugin_child_id);
+ if (plugin_host) {
+ int process_type = plugin_host->GetData().process_type;
+ if (process_type == PROCESS_TYPE_PPAPI_PLUGIN) {
+ return true;
+ } else if (process_type >= PROCESS_TYPE_CONTENT_END) {
+ if (GetContentClient()->browser()->GetExternalBrowserPpapiHost(
+ plugin_child_id) != nullptr) {
+ return true;
+ }
+ }
+ }
+#endif
+ return false;
+}
+
// Used to log the cache flags for back-forward navigation requests.
// Because this enum is used to back a histogrma, DO NOT REMOVE OR RENAME VALUES
// in this enum. Instead, add a new one at the end.
@@ -335,9 +336,11 @@ ResourceDispatcherHost* ResourceDispatcherHost::Get() {
ResourceDispatcherHostImpl::ResourceDispatcherHostImpl(
CreateDownloadHandlerIntercept download_handler_intercept,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_runner)
+ const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_runner,
+ bool enable_resource_scheduler)
: request_id_(-1),
is_shutdown_(false),
+ enable_resource_scheduler_(enable_resource_scheduler),
num_in_flight_requests_(0),
max_num_in_flight_requests_(base::SharedMemory::GetHandleLimit()),
max_num_in_flight_requests_per_process_(static_cast<int>(
@@ -364,7 +367,7 @@ ResourceDispatcherHostImpl::ResourceDispatcherHostImpl(
FROM_HERE, base::BindOnce(&ResourceDispatcherHostImpl::OnInit,
base::Unretained(this)));
- update_load_states_timer_ = base::MakeUnique<base::RepeatingTimer>();
+ update_load_states_timer_ = std::make_unique<base::RepeatingTimer>();
// Monitor per-tab outstanding requests only if OOPIF is not enabled, because
// the routing id doesn't represent tabs in OOPIF modes.
@@ -372,7 +375,7 @@ ResourceDispatcherHostImpl::ResourceDispatcherHostImpl(
!SiteIsolationPolicy::IsTopDocumentIsolationEnabled() &&
!SiteIsolationPolicy::AreIsolatedOriginsEnabled()) {
record_outstanding_requests_stats_timer_ =
- base::MakeUnique<base::RepeatingTimer>();
+ std::make_unique<base::RepeatingTimer>();
}
}
@@ -380,14 +383,15 @@ ResourceDispatcherHostImpl::ResourceDispatcherHostImpl(
// the main thread and the IO thread are the same for unittests.
ResourceDispatcherHostImpl::ResourceDispatcherHostImpl()
: ResourceDispatcherHostImpl(CreateDownloadHandlerIntercept(),
- base::ThreadTaskRunnerHandle::Get()) {}
+ base::ThreadTaskRunnerHandle::Get(),
+ /* enable_resource_scheduler */ true) {}
ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() {
DCHECK(outstanding_requests_stats_map_.empty());
DCHECK(outstanding_requests_per_tab_map_.empty());
DCHECK(g_resource_dispatcher_host);
DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
- g_resource_dispatcher_host = NULL;
+ g_resource_dispatcher_host = nullptr;
}
// static
@@ -579,7 +583,7 @@ ResourceDispatcherHostImpl::CreateLoginDelegate(
ResourceLoader* loader,
net::AuthChallengeInfo* auth_info) {
if (!delegate_)
- return NULL;
+ return nullptr;
return delegate_->CreateLoginDelegate(auth_info, loader->request());
}
@@ -628,21 +632,6 @@ void ResourceDispatcherHostImpl::DidReceiveRedirect(
delegate_->OnRequestRedirected(
new_url, loader->request(), info->GetContext(), response);
}
-
- // Don't notify WebContents observers for requests known to be
- // downloads; they aren't really associated with the Webcontents.
- // Note that not all downloads are known before content sniffing.
- if (info->IsDownload())
- return;
-
- // Notify the observers on the UI thread.
- net::URLRequest* request = loader->request();
- std::unique_ptr<ResourceRedirectDetails> detail(new ResourceRedirectDetails(
- loader->request(),
- !!request->ssl_info().cert,
- new_url));
- loader_delegate_->DidGetRedirectForResourceRequest(
- info->GetWebContentsGetterForRequest(), std::move(detail));
}
void ResourceDispatcherHostImpl::DidReceiveResponse(
@@ -657,8 +646,6 @@ void ResourceDispatcherHostImpl::DidReceiveResponse(
info->GetChildID(), info->GetRouteID());
}
- ProcessRequestForLinkHeaders(request);
-
if (delegate_)
delegate_->OnResponseStarted(request, info->GetContext(), response);
@@ -678,6 +665,9 @@ void ResourceDispatcherHostImpl::DidReceiveResponse(
void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) {
ResourceRequestInfoImpl* info = loader->GetRequestInfo();
+ base::TimeDelta request_loading_time(base::TimeTicks::Now() -
+ loader->request()->creation_time());
+
// Record final result of all resource loads.
if (info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME) {
// This enumeration has "3" appended to its name to distinguish it from
@@ -685,6 +675,10 @@ void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) {
UMA_HISTOGRAM_SPARSE_SLOWLY(
"Net.ErrorCodesForMainFrame3",
-loader->request()->status().error());
+ if (loader->request()->status().error() == net::OK) {
+ UMA_HISTOGRAM_LONG_TIMES("Net.RequestTime2Success.MainFrame",
+ request_loading_time);
+ }
if (loader->request()->status().error() == net::ERR_ABORTED) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Net.ErrAborted.SentBytes",
loader->request()->GetTotalSentBytes(), 1,
@@ -713,6 +707,10 @@ void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) {
"Net.CertificateTransparency.MainFrameValidSCTCount", num_valid_scts);
}
} else {
+ if (loader->request()->status().error() == net::OK) {
+ UMA_HISTOGRAM_LONG_TIMES("Net.RequestTime2Success.Subresource",
+ request_loading_time);
+ }
if (info->GetResourceType() == RESOURCE_TYPE_IMAGE) {
UMA_HISTOGRAM_SPARSE_SLOWLY(
"Net.ErrorCodesForImages",
@@ -738,11 +736,7 @@ std::unique_ptr<net::ClientCertStore>
}
void ResourceDispatcherHostImpl::OnInit() {
- // In some tests |delegate_| does not get set, when that happens assume the
- // scheduler is enabled.
- bool enable_resource_scheduler =
- delegate_ ? delegate_->ShouldUseResourceScheduler() : true;
- scheduler_.reset(new ResourceScheduler(enable_resource_scheduler));
+ scheduler_.reset(new ResourceScheduler(enable_resource_scheduler_));
}
void ResourceDispatcherHostImpl::OnShutdown() {
@@ -874,7 +868,7 @@ void ResourceDispatcherHostImpl::OnSyncLoad(
base::Passed(WrapUnique(sync_result)));
BeginRequest(requester_info, request_id, request_data,
true /* is_sync_load */, callback, sync_result->routing_id(),
- nullptr, nullptr, kTrafficAnnotation);
+ nullptr, nullptr, GetTrafficAnnotation());
}
bool ResourceDispatcherHostImpl::IsRequestIDInUse(
@@ -926,9 +920,8 @@ void ResourceDispatcherHostImpl::UpdateRequestForTransfer(
// ResourceHandlers should always get state related to the request from the
// ResourceRequestInfo rather than caching it locally. This lets us update
// the info object when a transfer occurs.
- info->UpdateForTransfer(route_id, request_data.render_frame_id,
- request_data.origin_pid, request_id, requester_info,
- std::move(mojo_request),
+ info->UpdateForTransfer(route_id, request_data.render_frame_id, request_id,
+ requester_info, std::move(mojo_request),
std::move(url_loader_client));
// Update maps that used the old IDs, if necessary. Some transfers in tests
@@ -1015,7 +1008,6 @@ void ResourceDispatcherHostImpl::CompleteTransfer(
// Renderer sent transferred_request_request_id and/or
// transferred_request_child_id that doesn't correspond to an actually
// transferring loader on the browser side.
- base::debug::Alias(pending_loader);
bad_message::ReceivedBadMessage(requester_info->filter(),
bad_message::RDH_REQUEST_NOT_TRANSFERRING);
return;
@@ -1091,8 +1083,8 @@ void ResourceDispatcherHostImpl::BeginRequest(
return;
}
- ResourceContext* resource_context = NULL;
- net::URLRequestContext* request_context = NULL;
+ ResourceContext* resource_context = nullptr;
+ net::URLRequestContext* request_context = nullptr;
requester_info->GetContexts(request_data.resource_type, &resource_context,
&request_context);
@@ -1208,8 +1200,8 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
IsBrowserSideNavigationEnabled() &&
IsResourceTypeFrame(request_data.resource_type);
- ResourceContext* resource_context = NULL;
- net::URLRequestContext* request_context = NULL;
+ ResourceContext* resource_context = nullptr;
+ net::URLRequestContext* request_context = nullptr;
requester_info->GetContexts(request_data.resource_type, &resource_context,
&request_context);
@@ -1258,7 +1250,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
if (request_data.originated_from_service_worker) {
new_request->SetUserData(URLRequestServiceWorkerData::kUserDataKey,
- base::MakeUnique<URLRequestServiceWorkerData>());
+ std::make_unique<URLRequestServiceWorkerData>());
}
// If the request is a MAIN_FRAME request, the first-party URL gets updated
@@ -1312,6 +1304,17 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
report_raw_headers = false;
}
+ // Do not report raw headers if the request's site needs to be isolated
+ // from the current process.
+ if (report_raw_headers) {
+ bool is_isolated =
+ SiteIsolationPolicy::UseDedicatedProcessesForAllSites() ||
+ policy->IsIsolatedOrigin(url::Origin::Create(request_data.url));
+ if (is_isolated &&
+ !policy->CanAccessDataForOrigin(child_id, request_data.url))
+ report_raw_headers = false;
+ }
+
if (request_data.resource_type == RESOURCE_TYPE_PREFETCH ||
request_data.resource_type == RESOURCE_TYPE_FAVICON) {
do_not_prompt_for_login = true;
@@ -1347,8 +1350,9 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
// Update the previews state, but only if this is not using PlzNavigate.
PreviewsState previews_state = request_data.previews_state;
if (!IsBrowserSideNavigationEnabled()) {
- previews_state = GetPreviewsState(
- request_data.previews_state, delegate_, *new_request, resource_context,
+ previews_state = DeterminePreviewsState(
+ request_data.previews_state, delegate_, new_request.get(),
+ resource_context,
request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME);
}
@@ -1356,7 +1360,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
ResourceRequestInfoImpl* extra_info = new ResourceRequestInfoImpl(
requester_info, route_id,
-1, // frame_tree_node_id
- request_data.origin_pid, request_id, request_data.render_frame_id,
+ request_data.plugin_child_id, request_id, request_data.render_frame_id,
request_data.is_main_frame, request_data.resource_type,
request_data.transition_type, request_data.should_replace_current_entry,
false, // is download
@@ -1401,17 +1405,9 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
service_worker_mode != ServiceWorkerMode::ALL,
request_data.fetch_request_mode, request_data.fetch_credentials_mode,
request_data.fetch_redirect_mode, request_data.fetch_integrity,
- request_data.resource_type, request_data.fetch_request_context_type,
- request_data.fetch_frame_type, request_data.request_body);
-
- ForeignFetchRequestHandler::InitializeHandler(
- new_request.get(), requester_info->service_worker_context(),
- blob_context, child_id, request_data.service_worker_provider_id,
- service_worker_mode, request_data.fetch_request_mode,
- request_data.fetch_credentials_mode, request_data.fetch_redirect_mode,
- request_data.fetch_integrity, request_data.resource_type,
+ request_data.keepalive, request_data.resource_type,
request_data.fetch_request_context_type, request_data.fetch_frame_type,
- request_data.request_body, request_data.initiated_in_secure_context);
+ request_data.request_body);
// Have the appcache associate its extra info with the request.
AppCacheInterceptor::SetExtraRequestInfo(
@@ -1482,7 +1478,7 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
}
std::unique_ptr<DetachableResourceHandler> detachable_handler =
- base::MakeUnique<DetachableResourceHandler>(request, timeout,
+ std::make_unique<DetachableResourceHandler>(request, timeout,
std::move(handler));
if (start_detached)
detachable_handler->Detach();
@@ -1519,7 +1515,7 @@ ResourceDispatcherHostImpl::AddStandardHandlers(
net::URLRequest* request,
ResourceType resource_type,
ResourceContext* resource_context,
- FetchRequestMode fetch_request_mode,
+ network::mojom::FetchRequestMode fetch_request_mode,
RequestContextType fetch_request_context_type,
blink::WebMixedContentContextType fetch_mixed_content_context_type,
AppCacheService* appcache_service,
@@ -1541,7 +1537,7 @@ ResourceDispatcherHostImpl::AddStandardHandlers(
// PlzNavigate: the throttle is unnecessary as communication with the UI
// thread is handled by the NavigationResourceHandler below.
if (!IsBrowserSideNavigationEnabled() && IsResourceTypeFrame(resource_type)) {
- throttles.push_back(base::MakeUnique<NavigationResourceThrottle>(
+ throttles.push_back(std::make_unique<NavigationResourceThrottle>(
request, delegate_, fetch_request_context_type,
fetch_mixed_content_context_type));
}
@@ -1557,7 +1553,7 @@ ResourceDispatcherHostImpl::AddStandardHandlers(
if (request->has_upload()) {
// Request wake lock while uploading data.
throttles.push_back(
- base::MakeUnique<WakeLockResourceThrottle>(request->url().host()));
+ std::make_unique<WakeLockResourceThrottle>(request->url().host()));
}
// The Clear-Site-Data throttle.
@@ -1624,7 +1620,7 @@ ResourceDispatcherHostImpl::AddStandardHandlers(
// will be read, and since it looks at the original mime type.
bool is_nocors_plugin_request =
resource_type == RESOURCE_TYPE_PLUGIN_RESOURCE &&
- fetch_request_mode == FETCH_REQUEST_MODE_NO_CORS;
+ fetch_request_mode == network::mojom::FetchRequestMode::kNoCORS;
handler.reset(new CrossSiteDocumentResourceHandler(
std::move(handler), request, is_nocors_plugin_request));
}
@@ -1711,8 +1707,9 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
return new ResourceRequestInfoImpl(
ResourceRequesterInfo::CreateForDownloadOrPageSave(child_id),
render_view_route_id,
- -1, // frame_tree_node_id
- 0, MakeRequestID(), render_frame_route_id,
+ -1, // frame_tree_node_id
+ ChildProcessHost::kInvalidUniqueID, // plugin_child_id
+ MakeRequestID(), render_frame_route_id,
false, // is_main_frame
RESOURCE_TYPE_SUB_RESOURCE, ui::PAGE_TRANSITION_LINK,
false, // should_replace_current_entry
@@ -1724,8 +1721,8 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
false, // enable_upload_progress
false, // do_not_prompt_for_login
false, // keepalive
- blink::kWebReferrerPolicyDefault, blink::kWebPageVisibilityStateVisible,
- context,
+ blink::kWebReferrerPolicyDefault,
+ blink::mojom::PageVisibilityState::kVisible, context,
false, // report_raw_headers
true, // is_async
previews_state, // previews_state
@@ -1794,11 +1791,7 @@ void ResourceDispatcherHostImpl::CancelRequestsForRoute(
if (loader.first.child_id != child_id)
continue;
- // Added for http://crbug.com/754704; remove when that bug is resolved.
- loader.second->AssertURLRequestPresent();
-
ResourceRequestInfoImpl* info = loader.second->GetRequestInfo();
- CHECK(info);
GlobalRequestID id(child_id, loader.first.request_id);
DCHECK(id == loader.first);
@@ -2080,7 +2073,7 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
std::unique_ptr<net::URLRequest> new_request;
new_request = request_context->CreateRequest(
- info.common_params.url, net::HIGHEST, nullptr, kTrafficAnnotation);
+ info.common_params.url, net::HIGHEST, nullptr, GetTrafficAnnotation());
new_request->set_method(info.common_params.method);
new_request->set_site_for_cookies(info.site_for_cookies);
@@ -2119,9 +2112,9 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
.get()));
}
- PreviewsState previews_state =
- GetPreviewsState(info.common_params.previews_state, delegate_,
- *new_request, resource_context, info.is_main_frame);
+ PreviewsState previews_state = DeterminePreviewsState(
+ info.common_params.previews_state, delegate_, new_request.get(),
+ resource_context, info.is_main_frame);
// Make extra info and read footer (contains request ID).
//
@@ -2134,7 +2127,7 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
: scoped_refptr<ServiceWorkerContextWrapper>()),
-1, // route_id
info.frame_tree_node_id,
- -1, // request_data.origin_pid,
+ ChildProcessHost::kInvalidUniqueID, // plugin_child_id
MakeRequestID(),
-1, // request_data.render_frame_id,
info.is_main_frame, resource_type, info.common_params.transition,
@@ -2143,7 +2136,7 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
false,
false, // is download
false, // is stream
- info.common_params.allow_download, info.begin_params.has_user_gesture,
+ info.common_params.allow_download, info.common_params.has_user_gesture,
true, // enable_load_timing
false, // enable_upload_progress
false, // do_not_prompt_for_login
@@ -2201,12 +2194,13 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
->stream()
->CreateHandle();
- // Safe to consider navigations as NO_CORS.
+ // Safe to consider navigations as kNoCORS.
// TODO(davidben): Fix the dependency on child_id/route_id. Those are used
// by the ResourceScheduler. currently it's a no-op.
handler = AddStandardHandlers(
new_request.get(), resource_type, resource_context,
- FETCH_REQUEST_MODE_NO_CORS, info.begin_params.request_context_type,
+ network::mojom::FetchRequestMode::kNoCORS,
+ info.begin_params.request_context_type,
info.begin_params.mixed_content_context_type,
appcache_handle_core ? appcache_handle_core->GetAppCacheService()
: nullptr,
@@ -2301,7 +2295,7 @@ void ResourceDispatcherHostImpl::BeginRequestInternal(
// reasonable.
handler->OnResponseCompleted(
request->status(),
- base::MakeUnique<NullResourceController>(&was_resumed));
+ std::make_unique<NullResourceController>(&was_resumed));
// TODO(darin): The handler is not ready for us to kill the request. Oops!
DCHECK(was_resumed);
@@ -2427,7 +2421,7 @@ net::URLRequest* ResourceDispatcherHostImpl::GetURLRequest(
const GlobalRequestID& id) {
ResourceLoader* loader = GetLoader(id);
if (!loader)
- return NULL;
+ return nullptr;
return loader->request();
}
@@ -2552,7 +2546,7 @@ void ResourceDispatcherHostImpl::BlockRequestsForRoute(
blocked_loaders_map_.end())
<< "BlockRequestsForRoute called multiple time for the same RFH";
blocked_loaders_map_[global_routing_id] =
- base::MakeUnique<BlockedLoadersList>();
+ std::make_unique<BlockedLoadersList>();
}
void ResourceDispatcherHostImpl::ResumeBlockedRequestsForRoute(
@@ -2601,8 +2595,15 @@ ResourceDispatcherHostImpl::HttpAuthRelationTypeOf(
if (net::registry_controlled_domains::SameDomainOrHost(
first_party, request_url,
- net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES))
+ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) {
+ // If the first party is secure but the subresource is not, this is
+ // mixed-content. Do not allow the image.
+ if (!allow_cross_origin_auth_prompt() && IsOriginSecure(first_party) &&
+ !IsOriginSecure(request_url)) {
+ return HTTP_AUTH_RELATION_BLOCKED_CROSS;
+ }
return HTTP_AUTH_RELATION_SAME_DOMAIN;
+ }
if (allow_cross_origin_auth_prompt())
return HTTP_AUTH_RELATION_ALLOWED_CROSS;
@@ -2626,7 +2627,7 @@ ResourceLoader* ResourceDispatcherHostImpl::GetLoader(
LoaderMap::const_iterator i = pending_loaders_.find(id);
if (i == pending_loaders_.end())
- return NULL;
+ return nullptr;
return i->second.get();
}
@@ -2661,28 +2662,6 @@ void ResourceDispatcherHostImpl::UnregisterResourceMessageDelegate(
}
}
-int ResourceDispatcherHostImpl::BuildLoadFlagsForRequest(
- const ResourceRequest& request_data,
- bool is_sync_load) {
- int load_flags = request_data.load_flags;
-
- // Although EV status is irrelevant to sub-frames and sub-resources, we have
- // to perform EV certificate verification on all resources because an HTTP
- // keep-alive connection created to load a sub-frame or a sub-resource could
- // be reused to load a main frame.
- load_flags |= net::LOAD_VERIFY_EV_CERT;
- if (request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME) {
- load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED;
- } else if (request_data.resource_type == RESOURCE_TYPE_PREFETCH) {
- load_flags |= net::LOAD_PREFETCH;
- }
-
- if (is_sync_load)
- load_flags |= net::LOAD_IGNORE_LIMITS;
-
- return load_flags;
-}
-
bool ResourceDispatcherHostImpl::ShouldServiceRequest(
int child_id,
const ResourceRequest& request_data,
@@ -2729,6 +2708,14 @@ bool ResourceDispatcherHostImpl::ShouldServiceRequest(
return false;
}
+ // Check that |plugin_child_id|, if present, is actually a plugin process.
+ if (!ValidatePluginChildId(request_data.plugin_child_id)) {
+ NOTREACHED() << "Invalid request_data.plugin_child_id: "
+ << request_data.plugin_child_id << " (" << child_id << ", "
+ << request_data.render_frame_id << ")";
+ return false;
+ }
+
return true;
}
@@ -2770,4 +2757,35 @@ bool ResourceDispatcherHostImpl::HasRequestsFromMultipleActiveTabs() {
return false;
}
+// static
+// We have this function at the bottom of this file because it confuses
+// syntax highliting.
+net::NetworkTrafficAnnotationTag
+ResourceDispatcherHostImpl::GetTrafficAnnotation() {
+ return net::DefineNetworkTrafficAnnotation("resource_dispatcher_host",
+ R"(
+ semantics {
+ sender: "Resource Dispatcher Host"
+ description:
+ "Navigation-initiated request or renderer process initiated "
+ "request, which includes all resources for normal page loads, "
+ "chrome URLs, resources for installed extensions, as well as "
+ "downloads."
+ trigger:
+ "Navigating to a URL or downloading a file. A webpage, "
+ "ServiceWorker, chrome:// page, or extension may also initiate "
+ "requests in the background."
+ data: "Anything the initiator wants to send."
+ destination: OTHER
+ }
+ policy {
+ cookies_allowed: YES
+ cookies_store: "user or per-app cookie store"
+ setting: "These requests cannot be disabled."
+ policy_exception_justification:
+ "Not implemented. Without these requests, Chrome will be unable to "
+ "load any webpage."
+ })");
+}
+
} // namespace content
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.h b/chromium/content/browser/loader/resource_dispatcher_host_impl.h
index 2fb715de446..b915e86a3de 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.h
@@ -98,7 +98,8 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
// ResourceDispatcherHostImpl.
ResourceDispatcherHostImpl(
CreateDownloadHandlerIntercept download_handler_intercept,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_runner);
+ const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_runner,
+ bool enable_resource_scheduler);
ResourceDispatcherHostImpl();
~ResourceDispatcherHostImpl() override;
@@ -638,7 +639,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
net::URLRequest* request,
ResourceType resource_type,
ResourceContext* resource_context,
- FetchRequestMode fetch_request_mode,
+ network::mojom::FetchRequestMode fetch_request_mode,
RequestContextType fetch_request_context_type,
blink::WebMixedContentContextType fetch_mixed_content_context_type,
AppCacheService* appcache_service,
@@ -695,9 +696,6 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
void UnregisterResourceMessageDelegate(const GlobalRequestID& id,
ResourceMessageDelegate* delegate);
- int BuildLoadFlagsForRequest(const ResourceRequest& request_data,
- bool is_sync_load);
-
// Consults the RendererSecurity policy to determine whether the
// ResourceDispatcherHostImpl should service this request. A request might
// be disallowed if the renderer is not authorized to retrieve the request
@@ -724,6 +722,8 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
// (i.e. have at least three outstanding requests).
bool HasRequestsFromMultipleActiveTabs();
+ static net::NetworkTrafficAnnotationTag GetTrafficAnnotation();
+
LoaderMap pending_loaders_;
// Collection of temp files downloaded for child processes via
@@ -755,6 +755,8 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
// True if the resource dispatcher host has been shut down.
bool is_shutdown_;
+ const bool enable_resource_scheduler_;
+
using BlockedLoadersList = std::vector<std::unique_ptr<ResourceLoader>>;
using BlockedLoadersMap =
std::map<GlobalFrameRoutingId, std::unique_ptr<BlockedLoadersList>>;
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc b/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
index 760fbfabd3f..add2be7d241 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -87,6 +87,7 @@
#include "net/url_request/url_request_test_util.h"
#include "storage/browser/blob/shareable_file_reference.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
// TODO(eroman): Write unit tests for SafeBrowsing that exercise
// SafeBrowsingResourceHandler.
@@ -167,10 +168,11 @@ static ResourceRequest CreateResourceRequest(const char* method,
request.method = std::string(method);
request.url = url;
request.site_for_cookies = url; // bypass third-party cookie blocking
- request.request_initiator = url::Origin(url); // ensure initiator is set
+ request.request_initiator =
+ url::Origin::Create(url); // ensure initiator is set
request.referrer_policy = blink::kWebReferrerPolicyDefault;
request.load_flags = 0;
- request.origin_pid = 0;
+ request.plugin_child_id = -1;
request.resource_type = type;
request.request_context = 0;
request.appcache_host_id = kAppCacheNoHostId;
@@ -261,10 +263,10 @@ class TestFilterSpecifyingChild : public ResourceMessageFilter {
int process_id)
: ResourceMessageFilter(
process_id,
- NULL,
- NULL,
- NULL,
- NULL,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
base::Bind(&TestFilterSpecifyingChild::GetContexts,
base::Unretained(this)),
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)),
@@ -394,7 +396,7 @@ class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
LOG(ERROR)
<< "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
<< "; may result in leaks.";
- list_head_ = NULL;
+ list_head_ = nullptr;
}
}
@@ -420,8 +422,8 @@ class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
URLRequestTestDelayedStartJob* next_;
};
-URLRequestTestDelayedStartJob*
-URLRequestTestDelayedStartJob::list_head_ = NULL;
+URLRequestTestDelayedStartJob* URLRequestTestDelayedStartJob::list_head_ =
+ nullptr;
// This class is a variation on URLRequestTestJob in that it
// returns IO_pending errors before every read, not just the first one.
@@ -658,12 +660,12 @@ class GenericResourceThrottle : public ResourceThrottle {
~GenericResourceThrottle() override {
if (active_throttle_ == this)
- active_throttle_ = NULL;
+ active_throttle_ = nullptr;
}
// ResourceThrottle implementation:
void WillStartRequest(bool* defer) override {
- ASSERT_EQ(NULL, active_throttle_);
+ ASSERT_EQ(nullptr, active_throttle_);
if (flags_ & DEFER_STARTING_REQUEST) {
active_throttle_ = this;
*defer = true;
@@ -679,7 +681,7 @@ class GenericResourceThrottle : public ResourceThrottle {
}
void WillProcessResponse(bool* defer) override {
- ASSERT_EQ(NULL, active_throttle_);
+ ASSERT_EQ(nullptr, active_throttle_);
if (flags_ & DEFER_PROCESSING_RESPONSE) {
active_throttle_ = this;
*defer = true;
@@ -700,7 +702,7 @@ class GenericResourceThrottle : public ResourceThrottle {
void AssertAndResume() {
ASSERT_TRUE(this == active_throttle_);
- active_throttle_ = NULL;
+ active_throttle_ = nullptr;
ResourceThrottle::Resume();
}
@@ -720,7 +722,7 @@ class GenericResourceThrottle : public ResourceThrottle {
static GenericResourceThrottle* active_throttle_;
};
// static
-GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL;
+GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = nullptr;
class TestResourceDispatcherHostDelegate
: public ResourceDispatcherHostDelegate {
@@ -762,10 +764,10 @@ class TestResourceDispatcherHostDelegate
}
if (flags_ != NONE) {
- throttles->push_back(base::MakeUnique<GenericResourceThrottle>(
+ throttles->push_back(std::make_unique<GenericResourceThrottle>(
flags_, error_code_for_cancellation_));
if (create_two_throttles_)
- throttles->push_back(base::MakeUnique<GenericResourceThrottle>(
+ throttles->push_back(std::make_unique<GenericResourceThrottle>(
flags_, error_code_for_cancellation_));
}
}
@@ -808,14 +810,8 @@ class TestWebContentsObserver : public WebContentsObserver {
public:
explicit TestWebContentsObserver(WebContents* web_contents)
: WebContentsObserver(web_contents),
- resource_request_redirect_count_(0),
resource_response_start_count_(0) {}
- void DidGetRedirectForResourceRequest(
- const ResourceRedirectDetails& details) override {
- ++resource_request_redirect_count_;
- }
-
void DidGetResourceResponseStart(
const ResourceRequestDetails& details) override {
++resource_response_start_count_;
@@ -823,12 +819,7 @@ class TestWebContentsObserver : public WebContentsObserver {
int resource_response_start_count() { return resource_response_start_count_; }
- int resource_request_redirect_count() {
- return resource_request_redirect_count_;
- }
-
private:
- int resource_request_redirect_count_;
int resource_response_start_count_;
};
@@ -855,7 +846,8 @@ class ResourceDispatcherHostTest : public testing::Test, public IPC::Sender {
ResourceDispatcherHostTest()
: thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
host_(base::Bind(&DownloadResourceHandler::Create),
- base::ThreadTaskRunnerHandle::Get()),
+ base::ThreadTaskRunnerHandle::Get(),
+ /* enable_resource_scheduler */ true),
use_test_ssl_certificate_(false),
send_data_received_acks_(false),
auto_advance_(false) {
@@ -1072,17 +1064,16 @@ class ResourceDispatcherHostTest : public testing::Test, public IPC::Sender {
// Make a navigation request.
TestNavigationURLLoaderDelegate delegate;
BeginNavigationParams begin_params(
- std::string(), net::LOAD_NORMAL, false, false,
- REQUEST_CONTEXT_TYPE_LOCATION,
+ std::string(), net::LOAD_NORMAL, false, REQUEST_CONTEXT_TYPE_LOCATION,
blink::WebMixedContentContextType::kBlockable,
false, // is_form_submission
- url::Origin(url));
+ url::Origin::Create(url));
CommonNavigationParams common_params;
common_params.url = url;
std::unique_ptr<NavigationRequestInfo> request_info(
- new NavigationRequestInfo(common_params, begin_params, url, true,
- false, false, -1, false, false,
- blink::kWebPageVisibilityStateVisible));
+ new NavigationRequestInfo(
+ common_params, begin_params, url, true, false, false, -1, false,
+ false, blink::mojom::PageVisibilityState::kVisible));
std::unique_ptr<NavigationURLLoader> test_loader =
NavigationURLLoader::Create(
browser_context_->GetResourceContext(),
@@ -1206,7 +1197,8 @@ void ResourceDispatcherHostTest::
const GURL& url,
ResourceType type) {
ResourceRequest request = CreateResourceRequest("GET", type, url);
- request.origin_pid = web_contents_->GetMainFrame()->GetProcess()->GetID();
+ DCHECK_EQ(web_contents_filter_->child_id(),
+ web_contents_->GetMainFrame()->GetProcess()->GetID());
request.render_frame_id = web_contents_->GetMainFrame()->GetRoutingID();
ResourceHostMsg_RequestResource msg(
web_contents_->GetRenderViewHost()->GetRoutingID(), request_id, request,
@@ -1244,7 +1236,7 @@ void ResourceDispatcherHostTest::MakeWebContentsAssociatedDownloadRequest(
net::URLRequestContext* request_context =
browser_context_->GetResourceContext()->GetRequestContext();
std::unique_ptr<net::URLRequest> request(request_context->CreateRequest(
- url, net::DEFAULT_PRIORITY, NULL, TRAFFIC_ANNOTATION_FOR_TESTS));
+ url, net::DEFAULT_PRIORITY, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS));
DownloadManagerImpl::BeginDownloadRequest(
std::move(request), Referrer(), browser_context_->GetResourceContext(),
false, // is_content_initiated
@@ -2310,7 +2302,7 @@ TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
net::URLRequestContext context;
std::unique_ptr<net::URLRequest> req(context.CreateRequest(
- GURL("http://www.google.com"), net::DEFAULT_PRIORITY, NULL,
+ GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS));
EXPECT_EQ(4425, ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(
req.get()));
@@ -3485,7 +3477,7 @@ TEST_F(ResourceDispatcherHostTest, ReleaseTemporiesOnProcessExit) {
// Register it for a resource request.
host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
- deletable_file = NULL;
+ deletable_file = nullptr;
// Should be readable now.
EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
@@ -3751,19 +3743,6 @@ TEST_F(ResourceDispatcherHostTest, TransferResponseStarted) {
web_contents_observer_->resource_response_start_count());
}
-// Confirm that request redirected notifications are correctly
-// transmitted to the WebContents.
-TEST_F(ResourceDispatcherHostTest, TransferRequestRedirected) {
- int initial_count = web_contents_observer_->resource_request_redirect_count();
-
- MakeWebContentsAssociatedTestRequest(
- 1, net::URLRequestTestJob::test_url_redirect_to_url_2());
- content::RunAllTasksUntilIdle();
-
- EXPECT_EQ(initial_count + 1,
- web_contents_observer_->resource_request_redirect_count());
-}
-
// Confirm that DidChangePriority messages are respected.
TEST_F(ResourceDispatcherHostTest, DidChangePriority) {
// ResourceScheduler only throttles http and https requests.
@@ -3813,18 +3792,6 @@ TEST_F(ResourceDispatcherHostTest, TransferResponseStartedDownload) {
web_contents_observer_->resource_response_start_count());
}
-// Confirm that request redirected notifications for downloads are not
-// transmitted to the WebContents.
-TEST_F(ResourceDispatcherHostTest, TransferRequestRedirectedDownload) {
- int initial_count(web_contents_observer_->resource_request_redirect_count());
-
- MakeWebContentsAssociatedDownloadRequest(
- 1, net::URLRequestTestJob::test_url_redirect_to_url_2());
- content::RunAllTasksUntilIdle();
- EXPECT_EQ(initial_count,
- web_contents_observer_->resource_request_redirect_count());
-}
-
// 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) {
diff --git a/chromium/content/browser/loader/resource_handler.cc b/chromium/content/browser/loader/resource_handler.cc
index 57c0bc23708..25aacfc1a99 100644
--- a/chromium/content/browser/loader/resource_handler.cc
+++ b/chromium/content/browser/loader/resource_handler.cc
@@ -4,6 +4,8 @@
#include "content/browser/loader/resource_handler.h"
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
#include "content/browser/loader/resource_request_info_impl.h"
namespace content {
@@ -50,6 +52,13 @@ void ResourceHandler::OutOfBandCancel(int error_code, bool tell_renderer) {
delegate_->OutOfBandCancel(error_code, tell_renderer);
}
+void ResourceHandler::GetNumericArg(const std::string& name, int* result) {
+ const std::string& value =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(name);
+ if (!value.empty())
+ base::StringToInt(value, result);
+}
+
ResourceRequestInfoImpl* ResourceHandler::GetRequestInfo() const {
return ResourceRequestInfoImpl::ForRequest(request_);
}
diff --git a/chromium/content/browser/loader/resource_handler.h b/chromium/content/browser/loader/resource_handler.h
index b787b9c0d02..63c683d7048 100644
--- a/chromium/content/browser/loader/resource_handler.h
+++ b/chromium/content/browser/loader/resource_handler.h
@@ -163,6 +163,7 @@ class CONTENT_EXPORT ResourceHandler {
net::URLRequest* request() const { return request_; }
// Convenience functions.
+ static void GetNumericArg(const std::string& name, int* result);
ResourceRequestInfoImpl* GetRequestInfo() const;
int GetRequestID() const;
ResourceMessageFilter* GetFilter() const;
diff --git a/chromium/content/browser/loader/resource_hints_impl.cc b/chromium/content/browser/loader/resource_hints_impl.cc
index 46faed62fe5..a0ab5b2884b 100644
--- a/chromium/content/browser/loader/resource_hints_impl.cc
+++ b/chromium/content/browser/loader/resource_hints_impl.cc
@@ -104,8 +104,8 @@ int PreresolveUrl(net::URLRequestContextGetter* getter,
if (!request_context)
return net::ERR_CONTEXT_SHUT_DOWN;
- auto request_holder = base::MakeUnique<RequestHolder>();
- auto addresses = base::MakeUnique<net::AddressList>();
+ auto request_holder = std::make_unique<RequestHolder>();
+ 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();
diff --git a/chromium/content/browser/loader/resource_loader.cc b/chromium/content/browser/loader/resource_loader.cc
index 9b952d8f8c9..e64c2587751 100644
--- a/chromium/content/browser/loader/resource_loader.cc
+++ b/chromium/content/browser/loader/resource_loader.cc
@@ -8,7 +8,6 @@
#include "base/callback_helpers.h"
#include "base/command_line.h"
-#include "base/debug/dump_without_crashing.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
@@ -110,11 +109,11 @@ void PopulateResourceResponse(
net::IsLegacySymantecCert(request->ssl_info().public_key_hashes);
response->head.cert_validity_start =
request->ssl_info().cert->valid_start();
+ response->head.cert_status = request->ssl_info().cert_status;
if (info->ShouldReportRawHeaders()) {
// Only pass these members when the network panel of the DevTools is open,
// i.e. ShouldReportRawHeaders() is set. These data are used to populate
// the requests in the security panel too.
- response->head.cert_status = request->ssl_info().cert_status;
response->head.ssl_connection_status =
request->ssl_info().connection_status;
response->head.ssl_key_exchange_group =
@@ -232,13 +231,9 @@ ResourceLoader::ResourceLoader(std::unique_ptr<net::URLRequest> request,
times_cancelled_before_request_start_(0),
started_request_(false),
times_cancelled_after_request_start_(0),
- request_context_(request_->context()),
weak_ptr_factory_(this) {
request_->set_delegate(this);
handler_->SetDelegate(this);
- // Added for http://crbug.com/754704; remove when that bug is resolved.
- if (!GetRequestInfo())
- base::debug::DumpWithoutCrashing();
}
ResourceLoader::~ResourceLoader() {
@@ -256,7 +251,7 @@ void ResourceLoader::StartRequest() {
TRACE_EVENT_FLAG_FLOW_OUT);
ScopedDeferral scoped_deferral(this, DEFERRED_START);
- handler_->OnWillStart(request_->url(), base::MakeUnique<Controller>(this));
+ handler_->OnWillStart(request_->url(), std::make_unique<Controller>(this));
}
void ResourceLoader::CancelRequest(bool from_renderer) {
@@ -316,19 +311,13 @@ ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() {
}
void ResourceLoader::ClearLoginDelegate() {
- login_delegate_ = NULL;
+ login_delegate_ = nullptr;
}
void ResourceLoader::OutOfBandCancel(int error_code, bool tell_renderer) {
CancelRequestInternal(error_code, !tell_renderer);
}
-void ResourceLoader::AssertURLRequestPresent() const {
- DCHECK(request_context_);
- CHECK(request_);
- request_context_->AssertURLRequestPresent(request_.get());
-}
-
void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused,
const net::RedirectInfo& redirect_info,
bool* defer) {
@@ -370,7 +359,7 @@ void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused,
// |defer| to false instead of calling back into the URLRequest.
deferred_stage_ = DEFERRED_SYNC;
handler_->OnRequestRedirected(redirect_info, response.get(),
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
if (is_deferred()) {
*defer = true;
deferred_redirect_url_ = redirect_info.new_url;
@@ -429,14 +418,14 @@ void ResourceLoader::OnSSLCertificateError(net::URLRequest* request,
info->GetWebContentsGetterForRequest(), ssl_info, fatal);
}
-void ResourceLoader::OnResponseStarted(net::URLRequest* unused) {
+void ResourceLoader::OnResponseStarted(net::URLRequest* unused, int net_error) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
"ResourceLoader::OnResponseStarted");
DCHECK_EQ(request_.get(), unused);
DVLOG(1) << "OnResponseStarted: " << request_->url().spec();
- if (!request_->status().is_success()) {
+ if (net_error != net::OK) {
ResponseCompleted();
return;
}
@@ -597,6 +586,8 @@ void ResourceLoader::StartRequestInternal() {
request_->SetResponseHeadersCallback(base::Bind(
&ResourceLoader::SetRawResponseHeaders, base::Unretained(this)));
}
+ UMA_HISTOGRAM_TIMES("Net.ResourceLoader.TimeToURLRequestStart",
+ base::TimeTicks::Now() - request_->creation_time());
request_->Start();
delegate_->DidStartRequest(this);
@@ -626,7 +617,7 @@ void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) {
if (login_delegate_.get()) {
login_delegate_->OnRequestCancelled();
- login_delegate_ = NULL;
+ login_delegate_ = nullptr;
}
ssl_client_auth_handler_.reset();
@@ -686,7 +677,7 @@ void ResourceLoader::CompleteResponseStarted() {
// defers handling of the response.
deferred_stage_ = DEFERRED_SYNC;
handler_->OnResponseStarted(response.get(),
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
if (is_deferred()) {
deferred_stage_ = DEFERRED_READ;
} else {
@@ -702,7 +693,7 @@ void ResourceLoader::PrepareToReadMore(bool handle_result_async) {
deferred_stage_ = DEFERRED_SYNC;
handler_->OnWillRead(&read_buffer_, &read_buffer_size_,
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
if (is_deferred()) {
deferred_stage_ = DEFERRED_ON_WILL_READ;
@@ -760,7 +751,7 @@ void ResourceLoader::CompleteRead(int bytes_read) {
ScopedDeferral scoped_deferral(
this, bytes_read > 0 ? DEFERRED_READ : DEFERRED_RESPONSE_COMPLETE);
- handler_->OnReadCompleted(bytes_read, base::MakeUnique<Controller>(this));
+ handler_->OnReadCompleted(bytes_read, std::make_unique<Controller>(this));
}
void ResourceLoader::ResponseCompleted() {
@@ -772,7 +763,7 @@ void ResourceLoader::ResponseCompleted() {
ScopedDeferral scoped_deferral(this, DEFERRED_FINISH);
handler_->OnResponseCompleted(request_->status(),
- base::MakeUnique<Controller>(this));
+ std::make_unique<Controller>(this));
}
void ResourceLoader::CallDidFinishLoading() {
diff --git a/chromium/content/browser/loader/resource_loader.h b/chromium/content/browser/loader/resource_loader.h
index e9d32c5495b..2a3fa1e0343 100644
--- a/chromium/content/browser/loader/resource_loader.h
+++ b/chromium/content/browser/loader/resource_loader.h
@@ -60,10 +60,6 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate,
// ResourceHandler::Delegate implementation:
void OutOfBandCancel(int error_code, bool tell_renderer) override;
- // CHECKs that the associated URLRequest is still present on its context.
- // Added for http://crbug.com/754704; remove when that bug is resolved.
- void AssertURLRequestPresent() const;
-
private:
// ResourceController implementation for the ResourceLoader.
class Controller;
@@ -79,7 +75,7 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate,
void OnSSLCertificateError(net::URLRequest* request,
const net::SSLInfo& info,
bool fatal) override;
- void OnResponseStarted(net::URLRequest* request) override;
+ void OnResponseStarted(net::URLRequest* request, int net_error) override;
void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
// SSLErrorHandler::Delegate implementation:
@@ -189,10 +185,6 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate,
net::HttpRawRequestHeaders raw_request_headers_;
scoped_refptr<const net::HttpResponseHeaders> raw_response_headers_;
- // URLRequestContext of the associated URLRequest.
- // Added for http://crbug.com/754704; remove when that bug is resolved.
- const net::URLRequestContext* request_context_;
-
base::ThreadChecker thread_checker_;
base::WeakPtrFactory<ResourceLoader> weak_ptr_factory_;
diff --git a/chromium/content/browser/loader/resource_loader_unittest.cc b/chromium/content/browser/loader/resource_loader_unittest.cc
index 99e5fd051bd..f8f3b770326 100644
--- a/chromium/content/browser/loader/resource_loader_unittest.cc
+++ b/chromium/content/browser/loader/resource_loader_unittest.cc
@@ -352,8 +352,8 @@ class ResourceLoaderTest : public testing::Test,
: thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
test_url_request_context_(true),
resource_context_(&test_url_request_context_),
- raw_ptr_resource_handler_(NULL),
- raw_ptr_to_request_(NULL) {
+ raw_ptr_resource_handler_(nullptr),
+ raw_ptr_to_request_(nullptr) {
test_url_request_context_.set_job_factory(&job_factory_);
test_url_request_context_.set_network_quality_estimator(
&network_quality_estimator_);
@@ -410,7 +410,8 @@ class ResourceLoaderTest : public testing::Test,
request.get(), resource_type, &resource_context_,
rfh->GetProcess()->GetID(), rfh->GetRenderViewHost()->GetRoutingID(),
rfh->GetRoutingID(), belongs_to_main_frame, true /* allow_download */,
- false /* is_async */, PREVIEWS_OFF /* previews_state */);
+ false /* is_async */, PREVIEWS_OFF /* previews_state */,
+ nullptr /* navigation_ui_data */);
std::unique_ptr<TestResourceHandler> resource_handler(
new TestResourceHandler(nullptr, nullptr));
raw_ptr_resource_handler_ = resource_handler.get();
@@ -460,7 +461,7 @@ class ResourceLoaderTest : public testing::Test,
ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
ResourceLoader* loader,
net::AuthChallengeInfo* auth_info) override {
- return NULL;
+ return nullptr;
}
bool HandleExternalProtocol(ResourceLoader* loader,
const GURL& url) override {
@@ -595,6 +596,15 @@ class HTTPSSecurityInfoResourceLoaderTest : public ResourceLoaderTest {
const GURL test_https_redirect_url_;
};
+TEST_F(HTTPSSecurityInfoResourceLoaderTest, CertStatusOnResponse) {
+ SetUpResourceLoaderForUrl(test_https_url());
+ loader_->StartRequest();
+ raw_ptr_resource_handler_->WaitUntilResponseComplete();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(kTestCertError,
+ raw_ptr_resource_handler_->resource_response()->head.cert_status);
+}
+
// Tests that client certificates are requested with ClientCertStore lookup.
TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) {
// Set up the test client cert store.
@@ -727,6 +737,19 @@ TEST_F(ClientCertResourceLoaderTest, StoreAsyncCancel) {
base::RunLoop().RunUntilIdle();
}
+// Tests that a RESOURCE_TYPE_PREFETCH request sets the LOAD_PREFETCH flag.
+TEST_F(ResourceLoaderTest, PrefetchFlag) {
+ std::unique_ptr<net::URLRequest> request(
+ resource_context_.GetRequestContext()->CreateRequest(
+ test_async_url(), net::DEFAULT_PRIORITY, nullptr /* delegate */,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
+ SetUpResourceLoader(std::move(request), RESOURCE_TYPE_PREFETCH, true);
+
+ loader_->StartRequest();
+ raw_ptr_resource_handler_->WaitUntilResponseComplete();
+ EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body());
+}
+
// Test the case the ResourceHandler defers nothing.
TEST_F(ResourceLoaderTest, SyncResourceHandler) {
loader_->StartRequest();
diff --git a/chromium/content/browser/loader/resource_message_filter.cc b/chromium/content/browser/loader/resource_message_filter.cc
index 5f4d3a7cfd4..28bd4bce6cc 100644
--- a/chromium/content/browser/loader/resource_message_filter.cc
+++ b/chromium/content/browser/loader/resource_message_filter.cc
@@ -12,10 +12,15 @@
#include "content/browser/loader/url_loader_factory_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/common/resource_messages.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
#include "storage/browser/fileapi/file_system_context.h"
namespace content {
+namespace {
+mojom::URLLoaderFactory* g_test_factory;
+ResourceMessageFilter* g_current_filter;
+} // namespace
ResourceMessageFilter::ResourceMessageFilter(
int child_id,
@@ -96,6 +101,15 @@ void ResourceMessageFilter::CreateLoaderAndStart(
const ResourceRequest& url_request,
mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
+ if (g_test_factory && !g_current_filter) {
+ g_current_filter = this;
+ g_test_factory->CreateLoaderAndStart(std::move(request), routing_id,
+ request_id, options, url_request,
+ std::move(client), traffic_annotation);
+ g_current_filter = nullptr;
+ return;
+ }
+
URLLoaderFactoryImpl::CreateLoaderAndStart(
requester_info_.get(), std::move(request), routing_id, request_id,
options, url_request, std::move(client),
@@ -114,6 +128,18 @@ void ResourceMessageFilter::InitializeForTest() {
InitializeOnIOThread();
}
+void ResourceMessageFilter::SetNetworkFactoryForTesting(
+ mojom::URLLoaderFactory* test_factory) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(!test_factory || !g_test_factory);
+ g_test_factory = test_factory;
+}
+
+ResourceMessageFilter* ResourceMessageFilter::GetCurrentForTesting() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ return g_current_filter;
+}
+
void ResourceMessageFilter::InitializeOnIOThread() {
DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
// The WeakPtr of the filter must be created on the IO thread. So sets the
diff --git a/chromium/content/browser/loader/resource_message_filter.h b/chromium/content/browser/loader/resource_message_filter.h
index f00cb19e7f4..96f68649741 100644
--- a/chromium/content/browser/loader/resource_message_filter.h
+++ b/chromium/content/browser/loader/resource_message_filter.h
@@ -88,6 +88,16 @@ class CONTENT_EXPORT ResourceMessageFilter
}
void InitializeForTest();
+ // Overrides the network URLLoaderFactory for subsequent requests. Passing a
+ // null pointer will restore the default behavior.
+ // When the testing pointer's CreateLoaderAndStart() is being called,
+ // |GetCurrentForTesting()| will return the filter that's calling the testing
+ // pointer. Also, the testing pointer won't be used for nested
+ // CreateLoaderAndStart's. Must be called on the IO thread.
+ static void SetNetworkFactoryForTesting(
+ mojom::URLLoaderFactory* test_factory);
+ static ResourceMessageFilter* GetCurrentForTesting();
+
protected:
// Protected destructor so that we can be overriden in tests.
~ResourceMessageFilter() override;
diff --git a/chromium/content/browser/loader/resource_request_info_impl.cc b/chromium/content/browser/loader/resource_request_info_impl.cc
index e892f87ba2d..d875a4f6637 100644
--- a/chromium/content/browser/loader/resource_request_info_impl.cc
+++ b/chromium/content/browser/loader/resource_request_info_impl.cc
@@ -15,6 +15,7 @@
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/process_type.h"
#include "net/url_request/url_request.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
namespace content {
@@ -42,49 +43,52 @@ const ResourceRequestInfo* ResourceRequestInfo::ForRequest(
}
// static
-void ResourceRequestInfo::AllocateForTesting(net::URLRequest* request,
- ResourceType resource_type,
- ResourceContext* context,
- int render_process_id,
- int render_view_id,
- int render_frame_id,
- bool is_main_frame,
- bool allow_download,
- bool is_async,
- PreviewsState previews_state) {
+void ResourceRequestInfo::AllocateForTesting(
+ net::URLRequest* request,
+ ResourceType resource_type,
+ ResourceContext* context,
+ int render_process_id,
+ int render_view_id,
+ int render_frame_id,
+ bool is_main_frame,
+ bool allow_download,
+ bool is_async,
+ PreviewsState previews_state,
+ std::unique_ptr<NavigationUIData> navigation_ui_data) {
// Make sure RESOURCE_TYPE_MAIN_FRAME is declared as being fetched as part of
// the main frame.
DCHECK(resource_type != RESOURCE_TYPE_MAIN_FRAME || is_main_frame);
ResourceRequestInfoImpl* info = new ResourceRequestInfoImpl(
ResourceRequesterInfo::CreateForRendererTesting(
- render_process_id), // resource_requester_info
- render_view_id, // route_id
- -1, // frame_tree_node_id
- 0, // origin_pid
- 0, // request_id
- render_frame_id, // render_frame_id
- is_main_frame, // is_main_frame
- resource_type, // resource_type
- ui::PAGE_TRANSITION_LINK, // transition_type
- false, // should_replace_current_entry
- false, // is_download
- false, // is_stream
- allow_download, // allow_download
- false, // has_user_gesture
- false, // enable load timing
- request->has_upload(), // enable upload progress
- false, // do_not_prompt_for_login
- false, // keep_alive
- blink::kWebReferrerPolicyDefault, // referrer_policy
- blink::kWebPageVisibilityStateVisible, // visibility_state
- context, // context
- false, // report_raw_headers
- is_async, // is_async
- previews_state, // previews_state
- nullptr, // body
- false); // initiated_in_secure_context
+ render_process_id), // resource_requester_info
+ render_view_id, // route_id
+ -1, // frame_tree_node_id
+ ChildProcessHost::kInvalidUniqueID, // plugin_child_id
+ 0, // request_id
+ render_frame_id, // render_frame_id
+ is_main_frame, // is_main_frame
+ resource_type, // resource_type
+ ui::PAGE_TRANSITION_LINK, // transition_type
+ false, // should_replace_current_entry
+ false, // is_download
+ false, // is_stream
+ allow_download, // allow_download
+ false, // has_user_gesture
+ false, // enable load timing
+ request->has_upload(), // enable upload progress
+ false, // do_not_prompt_for_login
+ false, // keep_alive
+ blink::kWebReferrerPolicyDefault, // referrer_policy
+ blink::mojom::PageVisibilityState::kVisible, // visibility_state
+ context, // context
+ false, // report_raw_headers
+ is_async, // is_async
+ previews_state, // previews_state
+ nullptr, // body
+ false); // initiated_in_secure_context
info->AssociateWithRequest(request);
+ info->set_navigation_ui_data(std::move(navigation_ui_data));
}
// static
@@ -128,7 +132,7 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
scoped_refptr<ResourceRequesterInfo> requester_info,
int route_id,
int frame_tree_node_id,
- int origin_pid,
+ int plugin_child_id,
int request_id,
int render_frame_id,
bool is_main_frame,
@@ -144,18 +148,18 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
bool do_not_prompt_for_login,
bool keepalive,
blink::WebReferrerPolicy referrer_policy,
- blink::WebPageVisibilityState visibility_state,
+ blink::mojom::PageVisibilityState visibility_state,
ResourceContext* context,
bool report_raw_headers,
bool is_async,
PreviewsState previews_state,
const scoped_refptr<ResourceRequestBody> body,
bool initiated_in_secure_context)
- : detachable_handler_(NULL),
+ : detachable_handler_(nullptr),
requester_info_(std::move(requester_info)),
route_id_(route_id),
frame_tree_node_id_(frame_tree_node_id),
- origin_pid_(origin_pid),
+ plugin_child_id_(plugin_child_id),
request_id_(request_id),
render_frame_id_(render_frame_id),
is_main_frame_(is_main_frame),
@@ -242,8 +246,8 @@ GlobalRequestID ResourceRequestInfoImpl::GetGlobalRequestID() const {
return GlobalRequestID(GetChildID(), request_id_);
}
-int ResourceRequestInfoImpl::GetOriginPID() const {
- return origin_pid_;
+int ResourceRequestInfoImpl::GetPluginChildID() const {
+ return plugin_child_id_;
}
int ResourceRequestInfoImpl::GetRenderFrameID() const {
@@ -271,8 +275,8 @@ blink::WebReferrerPolicy ResourceRequestInfoImpl::GetReferrerPolicy() const {
return referrer_policy_;
}
-blink::WebPageVisibilityState
-ResourceRequestInfoImpl::GetVisibilityState() const {
+blink::mojom::PageVisibilityState ResourceRequestInfoImpl::GetVisibilityState()
+ const {
return visibility_state_;
}
@@ -317,14 +321,12 @@ bool ResourceRequestInfoImpl::CanceledByDevTools() const {
}
void ResourceRequestInfoImpl::AssociateWithRequest(net::URLRequest* request) {
- // Added for http://crbug.com/754704; remove when that bug is resolved.
- CHECK(this);
request->SetUserData(kResourceRequestInfoImplKey, base::WrapUnique(this));
int render_process_id;
int render_frame_id;
if (GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) {
request->SetUserData(URLRequestUserData::kUserDataKey,
- base::MakeUnique<URLRequestUserData>(render_process_id,
+ std::make_unique<URLRequestUserData>(render_process_id,
render_frame_id));
}
}
@@ -340,14 +342,13 @@ GlobalRoutingID ResourceRequestInfoImpl::GetGlobalRoutingID() const {
void ResourceRequestInfoImpl::UpdateForTransfer(
int route_id,
int render_frame_id,
- int origin_pid,
int request_id,
ResourceRequesterInfo* requester_info,
mojom::URLLoaderRequest url_loader_request,
mojom::URLLoaderClientPtr url_loader_client) {
route_id_ = route_id;
render_frame_id_ = render_frame_id;
- origin_pid_ = origin_pid;
+ plugin_child_id_ = ChildProcessHost::kInvalidUniqueID;
request_id_ = request_id;
requester_info_ = requester_info;
diff --git a/chromium/content/browser/loader/resource_request_info_impl.h b/chromium/content/browser/loader/resource_request_info_impl.h
index 8d6c57903a1..d21c5eefc87 100644
--- a/chromium/content/browser/loader/resource_request_info_impl.h
+++ b/chromium/content/browser/loader/resource_request_info_impl.h
@@ -16,7 +16,6 @@
#include "base/supports_user_data.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/loader/resource_requester_info.h"
-#include "content/public/browser/navigation_ui_data.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/previews_state.h"
#include "content/public/common/referrer.h"
@@ -51,7 +50,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
scoped_refptr<ResourceRequesterInfo> requester_info,
int route_id,
int frame_tree_node_id,
- int origin_pid,
+ int plugin_child_id,
int request_id,
int render_frame_id,
bool is_main_frame,
@@ -67,7 +66,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
bool do_not_prompt_for_login,
bool keepalive,
blink::WebReferrerPolicy referrer_policy,
- blink::WebPageVisibilityState visibility_state,
+ blink::mojom::PageVisibilityState visibility_state,
ResourceContext* context,
bool report_raw_headers,
bool is_async,
@@ -83,14 +82,14 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
int GetChildID() const override;
int GetRouteID() const override;
GlobalRequestID GetGlobalRequestID() const override;
- int GetOriginPID() const override;
+ int GetPluginChildID() const override;
int GetRenderFrameID() const override;
int GetFrameTreeNodeId() const override;
bool IsMainFrame() const override;
ResourceType GetResourceType() const override;
int GetProcessType() const override;
blink::WebReferrerPolicy GetReferrerPolicy() const override;
- blink::WebPageVisibilityState GetVisibilityState() const override;
+ blink::mojom::PageVisibilityState GetVisibilityState() const override;
ui::PageTransition GetPageTransition() const override;
bool HasUserGesture() const override;
bool GetAssociatedRenderFrame(int* render_process_id,
@@ -123,7 +122,6 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
// does not need to be updated.
void UpdateForTransfer(int route_id,
int render_frame_id,
- int origin_pid,
int request_id,
ResourceRequesterInfo* requester_info,
mojom::URLLoaderRequest url_loader_request,
@@ -215,7 +213,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
scoped_refptr<ResourceRequesterInfo> requester_info_;
int route_id_;
const int frame_tree_node_id_;
- int origin_pid_;
+ int plugin_child_id_;
int request_id_;
int render_frame_id_;
bool is_main_frame_;
@@ -233,7 +231,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
ui::PageTransition transition_type_;
int memory_cost_;
blink::WebReferrerPolicy referrer_policy_;
- blink::WebPageVisibilityState visibility_state_;
+ blink::mojom::PageVisibilityState visibility_state_;
ResourceContext* context_;
bool report_raw_headers_;
bool is_async_;
diff --git a/chromium/content/browser/loader/resource_scheduler.cc b/chromium/content/browser/loader/resource_scheduler.cc
index 7c7d739df50..af17d6d96ea 100644
--- a/chromium/content/browser/loader/resource_scheduler.cc
+++ b/chromium/content/browser/loader/resource_scheduler.cc
@@ -255,7 +255,7 @@ class ResourceScheduler::ScheduledResourceRequest : public ResourceThrottle {
host_port_pair_(net::HostPortPair::FromURL(request->url())),
weak_ptr_factory_(this) {
DCHECK(!request_->GetUserData(kUserDataKey));
- request_->SetUserData(kUserDataKey, base::MakeUnique<UnownedPointer>(this));
+ request_->SetUserData(kUserDataKey, std::make_unique<UnownedPointer>(this));
}
~ScheduledResourceRequest() override {
@@ -1165,7 +1165,7 @@ ResourceScheduler::Client* ResourceScheduler::GetClient(int child_id,
ClientId client_id = MakeClientId(child_id, route_id);
ClientMap::iterator client_it = client_map_.find(client_id);
if (client_it == client_map_.end()) {
- return NULL;
+ return nullptr;
}
return client_it->second;
}
diff --git a/chromium/content/browser/loader/resource_scheduler_browsertest.cc b/chromium/content/browser/loader/resource_scheduler_browsertest.cc
index f35589b777f..e5d07767a03 100644
--- a/chromium/content/browser/loader/resource_scheduler_browsertest.cc
+++ b/chromium/content/browser/loader/resource_scheduler_browsertest.cc
@@ -6,10 +6,6 @@
#include <string>
#include "base/memory/ptr_util.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/field_trial_param_associator.h"
-#include "base/metrics/field_trial_params.h"
-#include "base/test/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"
@@ -22,42 +18,15 @@ namespace {
class ResourceSchedulerBrowserTest : public ContentBrowserTest {
protected:
- ResourceSchedulerBrowserTest() : field_trial_list_(nullptr) {}
+ ResourceSchedulerBrowserTest() {}
+ ~ResourceSchedulerBrowserTest() override {}
void SetUpInProcessBrowserTestFixture() override {
ASSERT_TRUE(embedded_test_server()->Start());
- InitializeMaxDelayableRequestsExperiment();
- }
-
- void InitializeMaxDelayableRequestsExperiment() {
- base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
- const char kTrialName[] = "TrialName";
- const char kGroupName[] = "GroupName";
- const char kMaxDelayableRequestsNetworkOverride[] =
- "MaxDelayableRequestsNetworkOverride";
-
- std::map<std::string, std::string> params;
- params["MaxEffectiveConnectionType"] = "2G";
- params["MaxBDPKbits1"] = "130";
- params["MaxDelayableRequests1"] = "2";
- params["MaxBDPKbits2"] = "160";
- params["MaxDelayableRequests2"] = "4";
-
- base::AssociateFieldTrialParams(kTrialName, kGroupName, params);
- base::FieldTrial* field_trial =
- base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
-
- std::unique_ptr<base::FeatureList> feature_list(
- base::MakeUnique<base::FeatureList>());
- feature_list->RegisterFieldTrialOverride(
- kMaxDelayableRequestsNetworkOverride,
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, field_trial);
- feature_list_.InitWithFeatureList(std::move(feature_list));
}
private:
- base::FieldTrialList field_trial_list_;
- base::test::ScopedFeatureList feature_list_;
+ DISALLOW_COPY_AND_ASSIGN(ResourceSchedulerBrowserTest);
};
IN_PROC_BROWSER_TEST_F(ResourceSchedulerBrowserTest,
diff --git a/chromium/content/browser/loader/resource_scheduler_unittest.cc b/chromium/content/browser/loader/resource_scheduler_unittest.cc
index 201969dd508..1b723170bb4 100644
--- a/chromium/content/browser/loader/resource_scheduler_unittest.cc
+++ b/chromium/content/browser/loader/resource_scheduler_unittest.cc
@@ -163,8 +163,8 @@ class CancelingTestRequest : public TestRequest {
class FakeResourceContext : public ResourceContext {
private:
- net::HostResolver* GetHostResolver() override { return NULL; }
- net::URLRequestContext* GetRequestContext() override { return NULL; }
+ net::HostResolver* GetHostResolver() override { return nullptr; }
+ net::URLRequestContext* GetRequestContext() override { return nullptr; }
};
class ResourceSchedulerTest : public testing::Test {
@@ -273,7 +273,7 @@ class ResourceSchedulerTest : public testing::Test {
NewURLRequestWithChildAndRoute(url, priority, child_id, route_id));
std::unique_ptr<ResourceThrottle> throttle(scheduler_->ScheduleRequest(
child_id, route_id, is_async, url_request.get()));
- auto request = base::MakeUnique<TestRequest>(
+ auto request = std::make_unique<TestRequest>(
std::move(url_request), std::move(throttle), scheduler());
request->Start();
return request;
@@ -380,7 +380,7 @@ class ResourceSchedulerTest : public testing::Test {
if (non_delayable_weight > 0.0) {
experiment_enabled = true;
params["MaxEffectiveConnectionType"] = "2G";
- params["NonDelayableWeight"] = base::DoubleToString(non_delayable_weight);
+ params["NonDelayableWeight"] = base::NumberToString(non_delayable_weight);
}
base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
@@ -394,7 +394,7 @@ class ResourceSchedulerTest : public testing::Test {
ASSERT_TRUE(field_trial);
std::unique_ptr<base::FeatureList> feature_list(
- base::MakeUnique<base::FeatureList>());
+ std::make_unique<base::FeatureList>());
feature_list->RegisterFieldTrialOverride(
"ThrottleDelayable",
experiment_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
@@ -416,7 +416,7 @@ class ResourceSchedulerTest : public testing::Test {
params["MaxEffectiveConnectionType"] = max_ect_string;
for (size_t bdp_range_index = 1; bdp_range_index <= num_bdp_ranges;
bdp_range_index++) {
- std::string index_str = base::SizeTToString(bdp_range_index);
+ std::string index_str = base::NumberToString(bdp_range_index);
params["MaxBDPKbits" + index_str] = index_str + "00";
params["MaxDelayableRequests" + index_str] = index_str + "0";
}
@@ -425,7 +425,7 @@ class ResourceSchedulerTest : public testing::Test {
base::FieldTrial* field_trial =
base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
std::unique_ptr<base::FeatureList> feature_list(
- base::MakeUnique<base::FeatureList>());
+ std::make_unique<base::FeatureList>());
feature_list->RegisterFieldTrialOverride(
kThrottleDelayable, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
field_trial);
@@ -1801,7 +1801,7 @@ TEST_F(ResourceSchedulerTest, ReadInvalidConfigTest) {
base::FieldTrial* field_trial =
base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
std::unique_ptr<base::FeatureList> feature_list(
- base::MakeUnique<base::FeatureList>());
+ std::make_unique<base::FeatureList>());
feature_list->RegisterFieldTrialOverride(
kThrottleDelayable, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
field_trial);
diff --git a/chromium/content/browser/loader/stream_resource_handler.cc b/chromium/content/browser/loader/stream_resource_handler.cc
index a72addbad56..2584039291b 100644
--- a/chromium/content/browser/loader/stream_resource_handler.cc
+++ b/chromium/content/browser/loader/stream_resource_handler.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "content/browser/loader/resource_controller.h"
+#include "net/url_request/url_request.h"
#include "net/url_request/url_request_status.h"
namespace content {
@@ -36,6 +37,7 @@ void StreamResourceHandler::OnRequestRedirected(
void StreamResourceHandler::OnResponseStarted(
ResourceResponse* resp,
std::unique_ptr<ResourceController> controller) {
+ writer_.OnResponseStarted(request()->response_info());
controller->Resume();
}
@@ -56,6 +58,9 @@ void StreamResourceHandler::OnWillRead(
void StreamResourceHandler::OnReadCompleted(
int bytes_read,
std::unique_ptr<ResourceController> controller) {
+ int64_t total_bytes_read = request()->GetTotalReceivedBytes();
+ int64_t raw_body_bytes = request()->GetRawBodyBytes();
+ writer_.UpdateNetworkStats(raw_body_bytes, total_bytes_read);
writer_.OnReadCompleted(bytes_read,
base::Bind(&ResourceController::Resume,
base::Passed(std::move(controller))));
diff --git a/chromium/content/browser/loader/stream_writer.cc b/chromium/content/browser/loader/stream_writer.cc
index 3792a17c489..08774aa64b4 100644
--- a/chromium/content/browser/loader/stream_writer.cc
+++ b/chromium/content/browser/loader/stream_writer.cc
@@ -35,6 +35,16 @@ void StreamWriter::InitializeStream(StreamRegistry* registry,
stream_ = new Stream(registry, this, url);
}
+void StreamWriter::OnResponseStarted(
+ const net::HttpResponseInfo& response_info) {
+ stream_->OnResponseStarted(response_info);
+}
+
+void StreamWriter::UpdateNetworkStats(int64_t raw_body_bytes,
+ int64_t total_bytes) {
+ stream_->UpdateNetworkStats(raw_body_bytes, total_bytes);
+}
+
void StreamWriter::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
int* buf_size,
int min_size) {
diff --git a/chromium/content/browser/loader/stream_writer.h b/chromium/content/browser/loader/stream_writer.h
index f6d974de0dd..09188b8e89d 100644
--- a/chromium/content/browser/loader/stream_writer.h
+++ b/chromium/content/browser/loader/stream_writer.h
@@ -14,6 +14,7 @@ class GURL;
namespace net {
class IOBuffer;
+class HttpResponseInfo;
}
namespace content {
@@ -46,6 +47,14 @@ class StreamWriter : public StreamWriteObserver {
const GURL& origin,
const base::Closure& cancel_callback);
+ // Passes HTTP response information associated with the response body
+ // transferred through this stream. This should be called before
+ // OnReadCompleted is ever called.
+ void OnResponseStarted(const net::HttpResponseInfo& response_info);
+
+ // Updates actual counts of bytes transferred by the network.
+ void UpdateNetworkStats(int64_t raw_body_bytes, int64_t total_bytes);
+
// Prepares a buffer to read data from the request. This call will be followed
// by either OnReadCompleted (on successful read or EOF) or destruction. The
// buffer may not be recycled until OnReadCompleted is called. If |min_size|
diff --git a/chromium/content/browser/loader/temporary_file_stream_unittest.cc b/chromium/content/browser/loader/temporary_file_stream_unittest.cc
index 7ba8fbc8300..e32ae5b2a6b 100644
--- a/chromium/content/browser/loader/temporary_file_stream_unittest.cc
+++ b/chromium/content/browser/loader/temporary_file_stream_unittest.cc
@@ -53,8 +53,8 @@ class WaitForFileStream {
}
void Release() {
- file_stream_.reset(NULL);
- deletable_file_ = NULL;
+ file_stream_.reset(nullptr);
+ deletable_file_ = nullptr;
}
private:
base::RunLoop loop_;
diff --git a/chromium/content/browser/loader/test_resource_handler.cc b/chromium/content/browser/loader/test_resource_handler.cc
index 4bcf6e296a2..459e9560fbe 100644
--- a/chromium/content/browser/loader/test_resource_handler.cc
+++ b/chromium/content/browser/loader/test_resource_handler.cc
@@ -153,7 +153,7 @@ void TestResourceHandler::OnWillRead(
// nothing may be called synchronously in response to the OnWillRead call.
std::unique_ptr<ScopedCallDepthTracker> call_depth_tracker;
if (call_depth_ == 0)
- call_depth_tracker = base::MakeUnique<ScopedCallDepthTracker>(&call_depth_);
+ call_depth_tracker = std::make_unique<ScopedCallDepthTracker>(&call_depth_);
++on_will_read_called_;
diff --git a/chromium/content/browser/loader/throttling_resource_handler_unittest.cc b/chromium/content/browser/loader/throttling_resource_handler_unittest.cc
index 369fc3d91b5..14b223d7ac9 100644
--- a/chromium/content/browser/loader/throttling_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/throttling_resource_handler_unittest.cc
@@ -208,7 +208,7 @@ class ThrottlingResourceHandlerTest : public testing::Test {
EXPECT_EQ(0, test_handler_->on_read_completed_called());
ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(0));
+ mock_loader_->OnReadCompleted(nullptr));
EXPECT_EQ(1, test_handler_->on_read_completed_called());
EXPECT_EQ(0, test_handler_->on_response_completed_called());
diff --git a/chromium/content/browser/loader/upload_data_stream_builder.cc b/chromium/content/browser/loader/upload_data_stream_builder.cc
index ba96cb2de5a..d4caecf1165 100644
--- a/chromium/content/browser/loader/upload_data_stream_builder.cc
+++ b/chromium/content/browser/loader/upload_data_stream_builder.cc
@@ -15,7 +15,6 @@
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
-#include "content/browser/fileapi/upload_file_system_file_element_reader.h"
#include "content/public/common/resource_request_body.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/upload_bytes_element_reader.h"
@@ -93,40 +92,36 @@ std::unique_ptr<net::UploadDataStream> UploadDataStreamBuilder::Build(
switch (element.type()) {
case ResourceRequestBody::Element::TYPE_BYTES:
element_readers.push_back(
- base::MakeUnique<BytesElementReader>(body, element));
+ std::make_unique<BytesElementReader>(body, element));
break;
case ResourceRequestBody::Element::TYPE_FILE:
- element_readers.push_back(base::MakeUnique<FileElementReader>(
+ element_readers.push_back(std::make_unique<FileElementReader>(
body, file_task_runner, element));
break;
- case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM:
- // If |body| contains any filesystem URLs, the caller should have
- // supplied a FileSystemContext.
- DCHECK(file_system_context);
- element_readers.push_back(
- base::MakeUnique<content::UploadFileSystemFileElementReader>(
- file_system_context, element.filesystem_url(), element.offset(),
- element.length(), element.expected_modification_time()));
- break;
case ResourceRequestBody::Element::TYPE_BLOB: {
DCHECK_EQ(std::numeric_limits<uint64_t>::max(), element.length());
DCHECK_EQ(0ul, element.offset());
std::unique_ptr<storage::BlobDataHandle> handle =
blob_context->GetBlobDataFromUUID(element.blob_uuid());
element_readers.push_back(
- base::MakeUnique<storage::UploadBlobElementReader>(
- std::move(handle), file_system_context));
+ std::make_unique<storage::UploadBlobElementReader>(
+ std::move(handle)));
break;
}
+ case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM:
+ CHECK(false) << "Should never be reached";
+ break;
+ case ResourceRequestBody::Element::TYPE_RAW_FILE:
case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
case ResourceRequestBody::Element::TYPE_BYTES_DESCRIPTION:
+ case ResourceRequestBody::Element::TYPE_DATA_PIPE:
case ResourceRequestBody::Element::TYPE_UNKNOWN:
NOTREACHED();
break;
}
}
- return base::MakeUnique<net::ElementsUploadDataStream>(
+ return std::make_unique<net::ElementsUploadDataStream>(
std::move(element_readers), body->identifier());
}
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 a6aab0887ba..2a6723743bd 100644
--- a/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc
+++ b/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc
@@ -64,7 +64,7 @@ TEST(UploadDataStreamBuilderTest, CreateUploadDataStream) {
std::unique_ptr<net::UploadDataStream> upload(
UploadDataStreamBuilder::Build(
- request_body.get(), &context, NULL,
+ request_body.get(), &context, nullptr,
base::ThreadTaskRunnerHandle::Get().get()));
EXPECT_EQ(kIdentifier, upload->identifier());
@@ -122,7 +122,7 @@ TEST(UploadDataStreamBuilderTest,
scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
std::unique_ptr<net::UploadDataStream> upload(
UploadDataStreamBuilder::Build(
- request_body.get(), &blob_storage_context, NULL,
+ request_body.get(), &blob_storage_context, nullptr,
base::ThreadTaskRunnerHandle::Get().get()));
request_body = new ResourceRequestBody();
@@ -131,7 +131,7 @@ TEST(UploadDataStreamBuilderTest,
request_body->AppendBlob(blob_id);
upload = UploadDataStreamBuilder::Build(
- request_body.get(), &blob_storage_context, NULL,
+ request_body.get(), &blob_storage_context, nullptr,
base::ThreadTaskRunnerHandle::Get().get());
ASSERT_TRUE(upload->GetElementReaders());
const auto& readers = *upload->GetElementReaders();
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 fcdfcb865df..4d38554b9d5 100644
--- a/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc
+++ b/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc
@@ -31,7 +31,6 @@
#include "content/public/browser/resource_dispatcher_host_delegate.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/resource_request.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "content/public/common/url_loader.mojom.h"
#include "content/public/common/url_loader_factory.mojom.h"
#include "content/public/test/test_browser_context.h"
@@ -52,6 +51,7 @@
#include "net/test/url_request/url_request_slow_download_job.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_filter.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
diff --git a/chromium/content/browser/loader/url_loader_request_handler.cc b/chromium/content/browser/loader/url_loader_request_handler.cc
index 731e9de8cb6..bb4197294d8 100644
--- a/chromium/content/browser/loader/url_loader_request_handler.cc
+++ b/chromium/content/browser/loader/url_loader_request_handler.cc
@@ -4,11 +4,13 @@
#include "content/browser/loader/url_loader_request_handler.h"
+#include "content/common/navigation_subresource_loader_params.h"
+
namespace content {
-mojom::URLLoaderFactoryPtr
-URLLoaderRequestHandler::MaybeCreateSubresourceFactory() {
- return nullptr;
+base::Optional<SubresourceLoaderParams>
+URLLoaderRequestHandler::MaybeCreateSubresourceLoaderParams() {
+ return base::nullopt;
}
bool URLLoaderRequestHandler::MaybeCreateLoaderForResponse(
@@ -18,4 +20,4 @@ bool URLLoaderRequestHandler::MaybeCreateLoaderForResponse(
return false;
}
-} // namespace content \ No newline at end of file
+} // namespace content
diff --git a/chromium/content/browser/loader/url_loader_request_handler.h b/chromium/content/browser/loader/url_loader_request_handler.h
index b73661873e3..629b9bbfd6b 100644
--- a/chromium/content/browser/loader/url_loader_request_handler.h
+++ b/chromium/content/browser/loader/url_loader_request_handler.h
@@ -8,6 +8,7 @@
#include <memory>
#include "base/callback_forward.h"
#include "base/macros.h"
+#include "base/optional.h"
#include "content/public/common/url_loader.mojom.h"
#include "content/public/common/url_loader_factory.mojom.h"
#include "net/url_request/redirect_info.h"
@@ -16,6 +17,7 @@ namespace content {
class ResourceContext;
struct ResourceRequest;
+struct SubresourceLoaderParams;
using StartLoaderCallback =
base::OnceCallback<void(mojom::URLLoaderRequest request,
@@ -36,10 +38,15 @@ class CONTENT_EXPORT URLLoaderRequestHandler {
ResourceContext* resource_context,
LoaderCallback callback) = 0;
- // Returns the URLLoaderFactory if any to be used for subsequent URL requests
- // going forward. Subclasses who want to handle subresource requests etc may
- // want to override this to return a custom factory.
- virtual mojom::URLLoaderFactoryPtr MaybeCreateSubresourceFactory();
+ // Returns a SubresourceLoaderParams if any to be used for subsequent URL
+ // requests going forward. Subclasses who want to set-up custom loader for
+ // subresource requests may want to override this.
+ // Note that the handler can return a null callback to MaybeCreateLoader(),
+ // and at the same time can return non-null SubresourceLoaderParams here if it
+ // does NOT want to handle the specific request given to MaybeCreateLoader()
+ // but wants to handle the subsequent resource requests.
+ virtual base::Optional<SubresourceLoaderParams>
+ MaybeCreateSubresourceLoaderParams();
// Returns true if the handler creates a loader for the |response| passed.
// An example of where this is used is AppCache, where the handler returns
diff --git a/chromium/content/browser/loader/wake_lock_resource_throttle.cc b/chromium/content/browser/loader/wake_lock_resource_throttle.cc
index 568be0b89e1..a0d45026d00 100644
--- a/chromium/content/browser/loader/wake_lock_resource_throttle.cc
+++ b/chromium/content/browser/loader/wake_lock_resource_throttle.cc
@@ -59,9 +59,9 @@ void WakeLockResourceThrottle::RequestWakeLock() {
connector->BindInterface(device::mojom::kServiceName,
mojo::MakeRequest(&wake_lock_provider));
wake_lock_provider->GetWakeLockWithoutContext(
- device::mojom::WakeLockType::PreventAppSuspension,
- device::mojom::WakeLockReason::ReasonOther,
- "Uploading data to " + host_, mojo::MakeRequest(&wake_lock_));
+ device::mojom::WakeLockType::kPreventAppSuspension,
+ device::mojom::WakeLockReason::kOther, "Uploading data to " + host_,
+ mojo::MakeRequest(&wake_lock_));
wake_lock_->RequestWakeLock();
}
diff --git a/chromium/content/browser/loader_delegate_impl.cc b/chromium/content/browser/loader_delegate_impl.cc
index de7d4a27beb..22b22a148ca 100644
--- a/chromium/content/browser/loader_delegate_impl.cc
+++ b/chromium/content/browser/loader_delegate_impl.cc
@@ -23,16 +23,6 @@ void DidGetResourceResponseStartOnUI(
web_contents->DidGetResourceResponseStart(*details.get());
}
-void DidGetRedirectForResourceRequestOnUI(
- const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
- std::unique_ptr<ResourceRedirectDetails> details) {
- WebContentsImpl* web_contents =
- static_cast<WebContentsImpl*>(web_contents_getter.Run());
- if (!web_contents)
- return;
- web_contents->DidGetRedirectForResourceRequest(*details.get());
-}
-
// This method is called in the UI thread to send the timestamp of a resource
// request to the respective Navigator (for an UMA histogram).
void DidGetLogResourceRequestTimeOnUI(base::TimeTicks timestamp,
@@ -74,16 +64,6 @@ void LoaderDelegateImpl::DidGetResourceResponseStart(
base::Passed(std::move(details))));
}
-void LoaderDelegateImpl::DidGetRedirectForResourceRequest(
- const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
- std::unique_ptr<ResourceRedirectDetails> details) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&DidGetRedirectForResourceRequestOnUI, web_contents_getter,
- base::Passed(std::move(details))));
-}
-
void LoaderDelegateImpl::LogResourceRequestTime(base::TimeTicks timestamp,
int render_process_id,
int render_frame_id,
diff --git a/chromium/content/browser/loader_delegate_impl.h b/chromium/content/browser/loader_delegate_impl.h
index a9229a97b2c..df3f3110a37 100644
--- a/chromium/content/browser/loader_delegate_impl.h
+++ b/chromium/content/browser/loader_delegate_impl.h
@@ -24,9 +24,6 @@ class CONTENT_EXPORT LoaderDelegateImpl : public LoaderDelegate {
void DidGetResourceResponseStart(
const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
std::unique_ptr<ResourceRequestDetails> details) override;
- void DidGetRedirectForResourceRequest(
- const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
- std::unique_ptr<ResourceRedirectDetails> details) override;
void LogResourceRequestTime(base::TimeTicks timestamp,
int render_process_id,
int render_frame_id,
diff --git a/chromium/content/browser/manifest/manifest_browsertest.cc b/chromium/content/browser/manifest/manifest_browsertest.cc
index f5e684e40ff..990943f8f80 100644
--- a/chromium/content/browser/manifest/manifest_browsertest.cc
+++ b/chromium/content/browser/manifest/manifest_browsertest.cc
@@ -10,6 +10,7 @@
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/manifest.h"
@@ -21,7 +22,8 @@
#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 "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/WebKit/public/platform/modules/manifest/manifest_manager.mojom.h"
namespace content {
@@ -93,7 +95,17 @@ class ManifestBrowserTest : public ContentBrowserTest,
return manifest_url_;
}
- unsigned int console_error_count() const {
+ int GetConsoleErrorCount() const {
+ // The IPCs reporting console errors are not FIFO with the manifest IPCs.
+ // Waiting for a round-trip channel-associated message will wait until any
+ // already enqueued channel-associated IPCs arrive at the browser process.
+ blink::mojom::ManifestManagerAssociatedPtr ptr;
+ shell()
+ ->web_contents()
+ ->GetMainFrame()
+ ->GetRemoteAssociatedInterfaces()
+ ->GetInterface(&ptr);
+ ptr.FlushForTesting();
return console_error_count_;
}
@@ -170,7 +182,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, NoManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
EXPECT_TRUE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
EXPECT_TRUE(reported_manifest_urls().empty());
ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
EXPECT_EQ(0u, manifests_reported_when_favicon_url_updated()[0]);
@@ -186,7 +198,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, 404Manifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
EXPECT_EQ(0u, manifests_reported_when_favicon_url_updated().size());
@@ -203,7 +215,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, EmptyManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
@@ -221,7 +233,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, ParseErrorManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(1u, console_error_count());
+ EXPECT_EQ(1, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
@@ -241,7 +253,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DummyManifest) {
EXPECT_FALSE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
@@ -301,7 +313,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DynamicManifest) {
EXPECT_EQ(0u, manifests_reported_when_favicon_url_updated()[0]);
}
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
}
// If a page's manifest lives in a different origin, it should follow the CORS
@@ -326,7 +338,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, CORSManifest) {
EXPECT_TRUE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
// 1 error for CORS violation
- EXPECT_EQ(1u, console_error_count());
+ EXPECT_EQ(1, GetConsoleErrorCount());
expected_manifest_urls.push_back(manifest_url());
EXPECT_EQ(expected_manifest_urls, reported_manifest_urls());
@@ -365,7 +377,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, CORSManifestWithAcessControls) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
@@ -394,7 +406,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, MixedContentManifest) {
EXPECT_TRUE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
// 1 error for mixed-content check violation
- EXPECT_EQ(1u, console_error_count());
+ EXPECT_EQ(1, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
@@ -412,7 +424,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, ParsingErrorsManifest) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(6u, console_error_count());
+ EXPECT_EQ(6, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
@@ -432,7 +444,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, Navigation) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
expected_manifest_urls.push_back(manifest_url());
EXPECT_EQ(expected_manifest_urls, reported_manifest_urls());
ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
@@ -447,7 +459,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, Navigation) {
GetManifestAndWait();
EXPECT_TRUE(manifest().IsEmpty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
EXPECT_TRUE(manifest_url().is_empty());
EXPECT_EQ(expected_manifest_urls, reported_manifest_urls());
ASSERT_EQ(2u, manifests_reported_when_favicon_url_updated().size());
@@ -463,7 +475,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, Navigation) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
expected_manifest_urls.push_back(manifest_url());
EXPECT_EQ(expected_manifest_urls, reported_manifest_urls());
ASSERT_EQ(3u, manifests_reported_when_favicon_url_updated().size());
@@ -489,7 +501,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, PushStateNavigation) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
ASSERT_EQ(2u, manifests_reported_when_favicon_url_updated().size());
@@ -516,7 +528,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, AnchorNavigation) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
ASSERT_EQ(2u, manifests_reported_when_favicon_url_updated().size());
@@ -576,7 +588,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, UseCredentialsSendCookies) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
@@ -636,7 +648,7 @@ IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, NoUseCredentialsNoCookies) {
GetManifestAndWait();
EXPECT_FALSE(manifest().IsEmpty());
EXPECT_FALSE(manifest_url().is_empty());
- EXPECT_EQ(0u, console_error_count());
+ EXPECT_EQ(0, GetConsoleErrorCount());
ASSERT_EQ(1u, reported_manifest_urls().size());
EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]);
ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
diff --git a/chromium/content/browser/manifest/manifest_manager_host.cc b/chromium/content/browser/manifest/manifest_manager_host.cc
index 747d0154b30..31fa59f50c6 100644
--- a/chromium/content/browser/manifest/manifest_manager_host.cc
+++ b/chromium/content/browser/manifest/manifest_manager_host.cc
@@ -10,8 +10,9 @@
#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 "content/public/common/associated_interface_provider.h"
#include "content/public/common/manifest.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
namespace content {
@@ -32,7 +33,7 @@ void ManifestManagerHost::RenderFrameDeleted(
void ManifestManagerHost::GetManifest(const GetManifestCallback& callback) {
auto& manifest_manager = GetManifestManager();
int request_id =
- callbacks_.Add(base::MakeUnique<GetManifestCallback>(callback));
+ callbacks_.Add(std::make_unique<GetManifestCallback>(callback));
manifest_manager.RequestManifest(
base::BindOnce(&ManifestManagerHost::OnRequestManifestResponse,
base::Unretained(this), request_id));
@@ -44,7 +45,7 @@ blink::mojom::ManifestManager& ManifestManagerHost::GetManifestManager() {
if (!manifest_manager_) {
manifest_manager_frame_ = web_contents()->GetMainFrame();
- manifest_manager_frame_->GetRemoteAssociatedInterfaces()->GetInterface(
+ manifest_manager_frame_->GetRemoteInterfaces()->GetInterface(
&manifest_manager_);
manifest_manager_.set_connection_error_handler(base::BindOnce(
&ManifestManagerHost::OnConnectionError, base::Unretained(this)));
@@ -64,13 +65,12 @@ void ManifestManagerHost::OnConnectionError() {
callback.Run(GURL(), Manifest());
}
-void ManifestManagerHost::OnRequestManifestResponse(
- int request_id,
- const GURL& url,
- const base::Optional<Manifest>& manifest) {
+void ManifestManagerHost::OnRequestManifestResponse(int request_id,
+ const GURL& url,
+ const Manifest& manifest) {
auto callback = std::move(*callbacks_.Lookup(request_id));
callbacks_.Remove(request_id);
- callback.Run(url, manifest.value_or(Manifest()));
+ callback.Run(url, manifest);
}
void ManifestManagerHost::ManifestUrlChanged(
diff --git a/chromium/content/browser/manifest/manifest_manager_host.h b/chromium/content/browser/manifest/manifest_manager_host.h
index b94cbdb536b..bf70d70d417 100644
--- a/chromium/content/browser/manifest/manifest_manager_host.h
+++ b/chromium/content/browser/manifest/manifest_manager_host.h
@@ -48,13 +48,13 @@ class ManifestManagerHost : public WebContentsObserver,
void OnRequestManifestResponse(int request_id,
const GURL& url,
- const base::Optional<Manifest>& manifest);
+ const Manifest& manifest);
// mojom::ManifestUrlChangeObserver:
void ManifestUrlChanged(const base::Optional<GURL>& manifest_url) override;
RenderFrameHost* manifest_manager_frame_ = nullptr;
- blink::mojom::ManifestManagerAssociatedPtr manifest_manager_;
+ blink::mojom::ManifestManagerPtr manifest_manager_;
CallbackMap callbacks_;
WebContentsFrameBindingSet<mojom::ManifestUrlChangeObserver>
diff --git a/chromium/content/browser/media/android/browser_media_player_manager.cc b/chromium/content/browser/media/android/browser_media_player_manager.cc
index d45c0f45b0f..1a5ae4769eb 100644
--- a/chromium/content/browser/media/android/browser_media_player_manager.cc
+++ b/chromium/content/browser/media/android/browser_media_player_manager.cc
@@ -46,7 +46,8 @@ namespace content {
const int kMediaPlayerThreshold = 1;
const int kInvalidMediaPlayerId = -1;
-static BrowserMediaPlayerManager::Factory g_factory = NULL;
+static BrowserMediaPlayerManager::Factory
+ g_browser_media_player_manager_factory = NULL;
static media::MediaUrlInterceptor* media_url_interceptor_ = NULL;
// static
@@ -55,8 +56,8 @@ void BrowserMediaPlayerManager::RegisterFactory(Factory factory) {
// Until Cast is fully upstreamed we want the downstream factory to take
// priority over the upstream factory. The downstream call happens first,
// so this will ensure that it does.
- if (g_factory == nullptr)
- g_factory = factory;
+ if (g_browser_media_player_manager_factory == nullptr)
+ g_browser_media_player_manager_factory = factory;
}
// static
@@ -68,13 +69,16 @@ void BrowserMediaPlayerManager::RegisterMediaUrlInterceptor(
// static
BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create(
RenderFrameHost* rfh) {
- // In chrome, |g_factory| should be set to create a RemoteMediaPlayerManager,
- // since RegisterFactory() should be called from
+ // In chrome, |g_browser_media_player_manager_factory| should be set
+ // to create a RemoteMediaPlayerManager, since RegisterFactory()
+ // should be called from
// ChromeMainDelegateAndroid::BasicStartupComplete.
//
// In webview, no factory should be set, and returning a nullptr should be
// handled by the caller.
- return g_factory != nullptr ? g_factory(rfh) : nullptr;
+ return g_browser_media_player_manager_factory != nullptr
+ ? g_browser_media_player_manager_factory(rfh)
+ : nullptr;
}
#if !defined(USE_AURA)
@@ -91,7 +95,7 @@ BrowserMediaPlayerManager::CreateMediaPlayer(
case MEDIA_PLAYER_TYPE_REMOTE_ONLY:
case MEDIA_PLAYER_TYPE_URL: {
const std::string user_agent = GetContentClient()->GetUserAgent();
- auto media_player_bridge = base::MakeUnique<MediaPlayerBridge>(
+ auto media_player_bridge = std::make_unique<MediaPlayerBridge>(
media_player_params.player_id, media_player_params.url,
media_player_params.site_for_cookies, user_agent, hide_url_log, this,
base::Bind(&BrowserMediaPlayerManager::OnDecoderResourcesReleased,
diff --git a/chromium/content/browser/media/android/media_player_renderer.cc b/chromium/content/browser/media/android/media_player_renderer.cc
index 415a5a66dbe..960327a5d8e 100644
--- a/chromium/content/browser/media/android/media_player_renderer.cc
+++ b/chromium/content/browser/media/android/media_player_renderer.cc
@@ -8,7 +8,9 @@
#include "base/callback_helpers.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_thread.h"
#include "content/public/browser/render_process_host.h"
@@ -30,14 +32,36 @@ media::MediaUrlInterceptor* g_media_url_interceptor = nullptr;
} // namespace
-MediaPlayerRenderer::MediaPlayerRenderer(int process_id, int routing_id)
+MediaPlayerRenderer::MediaPlayerRenderer(int process_id,
+ int routing_id,
+ WebContents* web_contents)
: render_process_id_(process_id),
routing_id_(routing_id),
has_error_(false),
- weak_factory_(this) {}
+ weak_factory_(this) {
+ DCHECK_EQ(static_cast<RenderFrameHostImpl*>(
+ RenderFrameHost::FromID(process_id, routing_id))
+ ->delegate()
+ ->GetAsWebContents(),
+ web_contents);
+
+ WebContentsImpl* web_contents_impl =
+ static_cast<WebContentsImpl*>(web_contents);
+ web_contents_muted_ = web_contents_impl && web_contents_impl->IsAudioMuted();
+
+ if (web_contents) {
+ MediaPlayerRendererWebContentsObserver::CreateForWebContents(web_contents);
+ web_contents_observer_ =
+ MediaPlayerRendererWebContentsObserver::FromWebContents(web_contents);
+ if (web_contents_observer_)
+ web_contents_observer_->AddMediaPlayerRenderer(this);
+ }
+}
MediaPlayerRenderer::~MediaPlayerRenderer() {
CancelScopedSurfaceRequest();
+ if (web_contents_observer_)
+ web_contents_observer_->RemoveMediaPlayerRenderer(this);
}
void MediaPlayerRenderer::Initialize(media::MediaResource* media_resource,
@@ -169,6 +193,12 @@ base::UnguessableToken MediaPlayerRenderer::InitiateScopedSurfaceRequest() {
}
void MediaPlayerRenderer::SetVolume(float volume) {
+ volume_ = volume;
+ UpdateVolume();
+}
+
+void MediaPlayerRenderer::UpdateVolume() {
+ float volume = web_contents_muted_ ? 0 : volume_;
media_player_->SetVolume(volume);
}
@@ -277,6 +307,15 @@ bool MediaPlayerRenderer::RequestPlay(int player_id,
return true;
}
+void MediaPlayerRenderer::OnUpdateAudioMutingState(bool muted) {
+ web_contents_muted_ = muted;
+ UpdateVolume();
+}
+
+void MediaPlayerRenderer::OnWebContentsDestroyed() {
+ web_contents_observer_ = nullptr;
+}
+
void MediaPlayerRenderer::OnDecoderResourcesReleased(int player_id) {
// Since we are not using a pool of MediaPlayerAndroid instances, this
// function is not relevant.
diff --git a/chromium/content/browser/media/android/media_player_renderer.h b/chromium/content/browser/media/android/media_player_renderer.h
index 6858726e29b..44ab9e046be 100644
--- a/chromium/content/browser/media/android/media_player_renderer.h
+++ b/chromium/content/browser/media/android/media_player_renderer.h
@@ -21,6 +21,9 @@
namespace content {
+class WebContents;
+class MediaPlayerRendererWebContentsObserver;
+
// MediaPlayerRenderer bridges the media::Renderer and Android MediaPlayer
// interfaces. It owns a MediaPlayerBridge, which exposes c++ methods to call
// into a native Android MediaPlayer.
@@ -42,7 +45,9 @@ class CONTENT_EXPORT MediaPlayerRenderer : public media::Renderer,
static void RegisterMediaUrlInterceptor(
media::MediaUrlInterceptor* media_url_interceptor);
- MediaPlayerRenderer(int process_id, int routing_id);
+ MediaPlayerRenderer(int process_id,
+ int routing_id,
+ WebContents* web_contents);
~MediaPlayerRenderer() override;
@@ -87,6 +92,9 @@ class CONTENT_EXPORT MediaPlayerRenderer : public media::Renderer,
base::TimeDelta duration,
bool has_audio) override;
+ void OnUpdateAudioMutingState(bool muted);
+ void OnWebContentsDestroyed();
+
// Registers a request in the content::ScopedSurfaceRequestManager, and
// returns the token associated to the request. The token can then be used to
// complete the request via the gpu::ScopedSurfaceRequestConduit.
@@ -108,6 +116,8 @@ class CONTENT_EXPORT MediaPlayerRenderer : public media::Renderer,
// it exists. No-ops otherwise.
void CancelScopedSurfaceRequest();
+ void UpdateVolume();
+
// Identifiers to find the RenderFrameHost that created |this|.
// NOTE: We store these IDs rather than a RenderFrameHost* because we do not
// know when the RenderFrameHost is destroyed.
@@ -130,6 +140,10 @@ class CONTENT_EXPORT MediaPlayerRenderer : public media::Renderer,
std::unique_ptr<media::MediaResourceGetter> media_resource_getter_;
+ bool web_contents_muted_;
+ MediaPlayerRendererWebContentsObserver* web_contents_observer_;
+ float volume_;
+
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<MediaPlayerRenderer> weak_factory_;
diff --git a/chromium/content/browser/media/android/media_player_renderer_web_contents_observer.cc b/chromium/content/browser/media/android/media_player_renderer_web_contents_observer.cc
new file mode 100644
index 00000000000..e5199578da9
--- /dev/null
+++ b/chromium/content/browser/media/android/media_player_renderer_web_contents_observer.cc
@@ -0,0 +1,47 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/android/media_player_renderer_web_contents_observer.h"
+
+#include "content/browser/media/android/media_player_renderer.h"
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(
+ content::MediaPlayerRendererWebContentsObserver);
+
+namespace content {
+
+MediaPlayerRendererWebContentsObserver::MediaPlayerRendererWebContentsObserver(
+ WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+
+MediaPlayerRendererWebContentsObserver::
+ ~MediaPlayerRendererWebContentsObserver() = default;
+
+void MediaPlayerRendererWebContentsObserver::AddMediaPlayerRenderer(
+ MediaPlayerRenderer* player) {
+ DCHECK(player);
+ DCHECK(players_.find(player) == players_.end());
+ players_.insert(player);
+}
+
+void MediaPlayerRendererWebContentsObserver::RemoveMediaPlayerRenderer(
+ MediaPlayerRenderer* player) {
+ DCHECK(player);
+ auto erase_result = players_.erase(player);
+ DCHECK_EQ(1u, erase_result);
+}
+
+void MediaPlayerRendererWebContentsObserver::DidUpdateAudioMutingState(
+ bool muted) {
+ for (MediaPlayerRenderer* player : players_)
+ player->OnUpdateAudioMutingState(muted);
+}
+
+void MediaPlayerRendererWebContentsObserver::WebContentsDestroyed() {
+ for (MediaPlayerRenderer* player : players_)
+ player->OnWebContentsDestroyed();
+ players_.clear();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/android/media_player_renderer_web_contents_observer.h b/chromium/content/browser/media/android/media_player_renderer_web_contents_observer.h
new file mode 100644
index 00000000000..f2d357e7a68
--- /dev/null
+++ b/chromium/content/browser/media/android/media_player_renderer_web_contents_observer.h
@@ -0,0 +1,45 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_WEB_CONTENTS_OBSERVER_H_
+#define CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_WEB_CONTENTS_OBSERVER_H_
+
+#include "base/containers/flat_set.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+namespace content {
+
+class MediaPlayerRenderer;
+
+// This class propagates WebContents muting updates to MediaPlayerRenderers.
+// This allows us to avoid adding N WebContentsObservers for N
+// MediaPlayerRenderers on a page. Essentially, this is a call-stack filter to
+// prevent uninteresting observer methods from calling into the
+// MediaPlayerRenderers.
+class MediaPlayerRendererWebContentsObserver
+ : public WebContentsObserver,
+ public WebContentsUserData<MediaPlayerRendererWebContentsObserver> {
+ public:
+ ~MediaPlayerRendererWebContentsObserver() override;
+
+ void AddMediaPlayerRenderer(MediaPlayerRenderer* player);
+ void RemoveMediaPlayerRenderer(MediaPlayerRenderer* player);
+
+ // WebContentsObserver implementation.
+ void DidUpdateAudioMutingState(bool muted) override;
+ void WebContentsDestroyed() override;
+
+ private:
+ explicit MediaPlayerRendererWebContentsObserver(WebContents* web_contents);
+ friend class WebContentsUserData<MediaPlayerRendererWebContentsObserver>;
+
+ base::flat_set<MediaPlayerRenderer*> players_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaPlayerRendererWebContentsObserver);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_WEB_CONTENTS_OBSERVER_H_
diff --git a/chromium/content/browser/media/audible_metrics.cc b/chromium/content/browser/media/audible_metrics.cc
index aef60623d87..b02977ca954 100644
--- a/chromium/content/browser/media/audible_metrics.cc
+++ b/chromium/content/browser/media/audible_metrics.cc
@@ -13,8 +13,7 @@ namespace content {
AudibleMetrics::AudibleMetrics()
: max_concurrent_audible_web_contents_in_session_(0),
- clock_(new base::DefaultTickClock()) {
-}
+ clock_(base::DefaultTickClock::GetInstance()) {}
AudibleMetrics::~AudibleMetrics() {
}
@@ -32,9 +31,8 @@ void AudibleMetrics::UpdateAudibleWebContentsState(
RemoveAudibleWebContents(web_contents);
}
-void AudibleMetrics::SetClockForTest(
- std::unique_ptr<base::TickClock> test_clock) {
- clock_ = std::move(test_clock);
+void AudibleMetrics::SetClockForTest(base::TickClock* test_clock) {
+ clock_ = test_clock;
}
void AudibleMetrics::AddAudibleWebContents(const WebContents* web_contents) {
diff --git a/chromium/content/browser/media/audible_metrics.h b/chromium/content/browser/media/audible_metrics.h
index 6ff9351747e..3c90da942d4 100644
--- a/chromium/content/browser/media/audible_metrics.h
+++ b/chromium/content/browser/media/audible_metrics.h
@@ -29,7 +29,7 @@ class CONTENT_EXPORT AudibleMetrics {
void UpdateAudibleWebContentsState(const WebContents* web_contents,
bool audible);
- void SetClockForTest(std::unique_ptr<base::TickClock> test_clock);
+ void SetClockForTest(base::TickClock* test_clock);
private:
void AddAudibleWebContents(const WebContents* web_contents);
@@ -37,7 +37,7 @@ class CONTENT_EXPORT AudibleMetrics {
base::TimeTicks concurrent_web_contents_start_time_;
size_t max_concurrent_audible_web_contents_in_session_;
- std::unique_ptr<base::TickClock> clock_;
+ base::TickClock* clock_;
std::set<const WebContents*> audible_web_contents_;
diff --git a/chromium/content/browser/media/audible_metrics_unittest.cc b/chromium/content/browser/media/audible_metrics_unittest.cc
index 6989dc7ee33..d122e3178c2 100644
--- a/chromium/content/browser/media/audible_metrics_unittest.cc
+++ b/chromium/content/browser/media/audible_metrics_unittest.cc
@@ -31,19 +31,13 @@ class AudibleMetricsTest : public testing::Test {
AudibleMetricsTest() = default;
void SetUp() override {
- clock_ = new base::SimpleTestTickClock();
// Set the clock to a value different than 0 so the time it gives is
// recognized as initialized.
- clock_->Advance(base::TimeDelta::FromMilliseconds(1));
- audible_metrics_.SetClockForTest(
- std::unique_ptr<base::SimpleTestTickClock>(clock_));
+ clock_.Advance(base::TimeDelta::FromMilliseconds(1));
+ audible_metrics_.SetClockForTest(&clock_);
}
- void TearDown() override {
- clock_ = nullptr;
- }
-
- base::SimpleTestTickClock* clock() { return clock_; }
+ base::SimpleTestTickClock* clock() { return &clock_; }
AudibleMetrics* audible_metrics() {
return &audible_metrics_;
@@ -59,7 +53,7 @@ class AudibleMetricsTest : public testing::Test {
}
private:
- base::SimpleTestTickClock* clock_ = nullptr;
+ base::SimpleTestTickClock clock_;
AudibleMetrics audible_metrics_;
base::HistogramTester histogram_tester_;
base::UserActionTester user_action_tester_;
diff --git a/chromium/content/browser/media/audio_stream_monitor.cc b/chromium/content/browser/media/audio_stream_monitor.cc
index 427d7dddba7..6d4bbdc2fa8 100644
--- a/chromium/content/browser/media/audio_stream_monitor.cc
+++ b/chromium/content/browser/media/audio_stream_monitor.cc
@@ -51,7 +51,7 @@ bool AudioStreamMonitor::StreamID::operator==(const StreamID& other) const {
AudioStreamMonitor::AudioStreamMonitor(WebContents* contents)
: web_contents_(contents),
- clock_(&default_tick_clock_),
+ clock_(base::DefaultTickClock::GetInstance()),
was_recently_audible_(false),
is_audible_(false) {
DCHECK(web_contents_);
diff --git a/chromium/content/browser/media/audio_stream_monitor.h b/chromium/content/browser/media/audio_stream_monitor.h
index 7433ced7186..0e8da39a146 100644
--- a/chromium/content/browser/media/audio_stream_monitor.h
+++ b/chromium/content/browser/media/audio_stream_monitor.h
@@ -79,6 +79,8 @@ class CONTENT_EXPORT AudioStreamMonitor {
was_recently_audible_ = value;
}
+ void set_is_currently_audible_for_testing(bool value) { is_audible_ = value; }
+
private:
friend class AudioStreamMonitorTest;
@@ -140,9 +142,8 @@ class CONTENT_EXPORT AudioStreamMonitor {
// pointer should be valid for the lifetime of AudioStreamMonitor.
WebContents* const web_contents_;
- // Note: |clock_| is always |&default_tick_clock_|, except during unit
+ // Note: |clock_| is always a DefaultTickClock, except during unit
// testing.
- base::DefaultTickClock default_tick_clock_;
base::TickClock* const clock_;
// Confirms single-threaded access in debug builds.
diff --git a/chromium/content/browser/media/capture/audio_mirroring_manager.cc b/chromium/content/browser/media/capture/audio_mirroring_manager.cc
index c7683cbc4b9..35793ad3965 100644
--- a/chromium/content/browser/media/capture/audio_mirroring_manager.cc
+++ b/chromium/content/browser/media/capture/audio_mirroring_manager.cc
@@ -45,7 +45,7 @@ void AudioMirroringManager::AddDiverter(
// the stream.
std::set<SourceFrameRef> candidates;
candidates.insert(routes_.back().source_render_frame);
- InitiateQueriesToFindNewDestination(NULL, candidates);
+ InitiateQueriesToFindNewDestination(nullptr, candidates);
}
void AudioMirroringManager::RemoveDiverter(Diverter* diverter) {
@@ -56,7 +56,7 @@ void AudioMirroringManager::RemoveDiverter(Diverter* diverter) {
for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
if (it->diverter == diverter) {
// Stop the diverted flow.
- RouteDivertedFlow(&(*it), NULL);
+ RouteDivertedFlow(&(*it), nullptr);
// Stop duplication flows.
for (auto& dup : it->duplications) {
@@ -107,7 +107,7 @@ void AudioMirroringManager::StopMirroring(MirroringDestination* destination) {
std::set<SourceFrameRef> redivert_candidates;
for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
if (it->destination == destination) {
- RouteDivertedFlow(&(*it), NULL);
+ RouteDivertedFlow(&(*it), nullptr);
redivert_candidates.insert(it->source_render_frame);
}
auto dup_it = it->duplications.find(destination);
@@ -182,7 +182,7 @@ void AudioMirroringManager::UpdateRoutesToDivertDestination(
} else if (!add_only) {
// Only stop diverting if the stream is currently routed to |destination|.
if (it->destination == destination) {
- RouteDivertedFlow(&(*it), NULL);
+ RouteDivertedFlow(&(*it), nullptr);
redivert_candidates.insert(it->source_render_frame);
}
}
@@ -241,7 +241,7 @@ void AudioMirroringManager::RouteDivertedFlow(
<< route->source_render_frame.second
<< " --> MirroringDestination@" << route->destination;
route->diverter->StopDiverting();
- route->destination = NULL;
+ route->destination = nullptr;
}
if (new_destination) {
@@ -256,10 +256,11 @@ void AudioMirroringManager::RouteDivertedFlow(
}
AudioMirroringManager::StreamRoutingState::StreamRoutingState(
- const SourceFrameRef& source_frame, Diverter* stream_diverter)
- : source_render_frame(source_frame),
- diverter(stream_diverter),
- destination(NULL) {}
+ const SourceFrameRef& source_frame,
+ Diverter* stream_diverter)
+ : source_render_frame(source_frame),
+ diverter(stream_diverter),
+ destination(nullptr) {}
AudioMirroringManager::StreamRoutingState::StreamRoutingState(
const StreamRoutingState& other) = default;
diff --git a/chromium/content/browser/media/capture/aura_window_capture_machine.cc b/chromium/content/browser/media/capture/aura_window_capture_machine.cc
index d95f0b3af94..274fce66609 100644
--- a/chromium/content/browser/media/capture/aura_window_capture_machine.cc
+++ b/chromium/content/browser/media/capture/aura_window_capture_machine.cc
@@ -37,7 +37,7 @@
namespace content {
AuraWindowCaptureMachine::AuraWindowCaptureMachine()
- : desktop_window_(NULL),
+ : desktop_window_(nullptr),
screen_capture_(false),
frame_capture_active_(true),
weak_factory_(this) {}
@@ -101,9 +101,9 @@ bool AuraWindowCaptureMachine::InternalStart(
connector->BindInterface(device::mojom::kServiceName,
mojo::MakeRequest(&wake_lock_provider));
wake_lock_provider->GetWakeLockWithoutContext(
- device::mojom::WakeLockType::PreventDisplaySleep,
- device::mojom::WakeLockReason::ReasonOther,
- "Desktop capturer is running", mojo::MakeRequest(&wake_lock_));
+ device::mojom::WakeLockType::kPreventDisplaySleep,
+ device::mojom::WakeLockReason::kOther, "Desktop capturer is running",
+ mojo::MakeRequest(&wake_lock_));
wake_lock_->RequestWakeLock();
}
@@ -165,7 +165,7 @@ void AuraWindowCaptureMachine::InternalStop(const base::Closure& callback) {
}
}
desktop_window_->RemoveObserver(this);
- desktop_window_ = NULL;
+ desktop_window_ = nullptr;
cursor_renderer_.reset();
}
@@ -294,6 +294,7 @@ bool AuraWindowCaptureMachine::ProcessCopyOutputResponse(
const CaptureFrameCallback& capture_frame_cb,
std::unique_ptr<viz::CopyOutputResult> result) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE);
if (!desktop_window_) {
VLOG(1) << "Ignoring CopyOutputResult: Capture target has gone away.";
@@ -329,16 +330,10 @@ bool AuraWindowCaptureMachine::ProcessCopyOutputResponse(
return false;
}
- viz::TextureMailbox texture_mailbox;
- std::unique_ptr<viz::SingleReleaseCallback> release_callback;
- if (auto* mailbox = result->GetTextureMailbox()) {
- texture_mailbox = *mailbox;
- release_callback = result->TakeTextureOwnership();
- }
- if (!texture_mailbox.IsTexture()) {
- VLOG(1) << "Aborting capture: Failed to take texture from mailbox.";
- return false;
- }
+ gpu::Mailbox mailbox = result->GetTextureResult()->mailbox;
+ gpu::SyncToken sync_token = result->GetTextureResult()->sync_token;
+ std::unique_ptr<viz::SingleReleaseCallback> release_callback =
+ result->TakeTextureOwnership();
if (!yuv_readback_pipeline_)
yuv_readback_pipeline_ = gl_helper->CreateReadbackPipelineYUV(true, true);
@@ -354,15 +349,14 @@ bool AuraWindowCaptureMachine::ProcessCopyOutputResponse(
} else if (!scaler || !scaler->IsSameScaleRatio(scale_from, scale_to)) {
std::unique_ptr<viz::GLHelper::ScalerInterface> scaler =
gl_helper->CreateScaler(viz::GLHelper::SCALER_QUALITY_FAST, scale_from,
- scale_to, false, false);
+ scale_to, false, false, false);
DCHECK(scaler); // Arguments to CreateScaler() should never be invalid.
yuv_readback_pipeline_->SetScaler(std::move(scaler));
}
cursor_renderer_->SnapshotCursorState(region_in_frame);
yuv_readback_pipeline_->ReadbackYUV(
- texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(),
- gfx::Rect(region_in_frame.size()),
+ mailbox, sync_token, result->size(), gfx::Rect(region_in_frame.size()),
video_frame->stride(media::VideoFrame::kYPlane),
video_frame->data(media::VideoFrame::kYPlane),
video_frame->stride(media::VideoFrame::kUPlane),
@@ -407,7 +401,8 @@ void AuraWindowCaptureMachine::CopyOutputFinishedForVideo(
void AuraWindowCaptureMachine::OnWindowBoundsChanged(
aura::Window* window,
const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) {
+ const gfx::Rect& new_bounds,
+ ui::PropertyChangeReason reason) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(desktop_window_ && window == desktop_window_);
diff --git a/chromium/content/browser/media/capture/aura_window_capture_machine.h b/chromium/content/browser/media/capture/aura_window_capture_machine.h
index e8de893d92e..d5bcc3faec2 100644
--- a/chromium/content/browser/media/capture/aura_window_capture_machine.h
+++ b/chromium/content/browser/media/capture/aura_window_capture_machine.h
@@ -45,7 +45,8 @@ class AuraWindowCaptureMachine : public media::VideoCaptureMachine,
// Implements aura::WindowObserver.
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) override;
+ const gfx::Rect& new_bounds,
+ ui::PropertyChangeReason reason) override;
void OnWindowDestroying(aura::Window* window) override;
void OnWindowAddedToRootWindow(aura::Window* window) override;
void OnWindowRemovingFromRootWindow(aura::Window* window,
diff --git a/chromium/content/browser/media/capture/cursor_renderer.cc b/chromium/content/browser/media/capture/cursor_renderer.cc
index f59fc2549fe..b698f1e6e20 100644
--- a/chromium/content/browser/media/capture/cursor_renderer.cc
+++ b/chromium/content/browser/media/capture/cursor_renderer.cc
@@ -29,7 +29,7 @@ CursorRenderer::CursorRenderer(gfx::NativeView view,
CursorDisplaySetting cursor_display_setting)
: captured_view_(view),
cursor_display_setting_(cursor_display_setting),
- tick_clock_(&default_tick_clock_),
+ tick_clock_(base::DefaultTickClock::GetInstance()),
weak_factory_(this) {
Clear();
}
diff --git a/chromium/content/browser/media/capture/cursor_renderer.h b/chromium/content/browser/media/capture/cursor_renderer.h
index a26e043baaa..c658e33b809 100644
--- a/chromium/content/browser/media/capture/cursor_renderer.h
+++ b/chromium/content/browser/media/capture/cursor_renderer.h
@@ -109,7 +109,6 @@ class CONTENT_EXPORT CursorRenderer {
CursorDisplaySetting cursor_display_setting_;
// Allows tests to replace the clock.
- base::DefaultTickClock default_tick_clock_;
base::TickClock* tick_clock_;
base::WeakPtrFactory<CursorRenderer> weak_factory_;
diff --git a/chromium/content/browser/media/capture/cursor_renderer_aura.cc b/chromium/content/browser/media/capture/cursor_renderer_aura.cc
index ca0d7d34da3..cccd3ad3aa4 100644
--- a/chromium/content/browser/media/capture/cursor_renderer_aura.cc
+++ b/chromium/content/browser/media/capture/cursor_renderer_aura.cc
@@ -18,7 +18,7 @@ namespace content {
// static
std::unique_ptr<CursorRenderer> CursorRenderer::Create(
gfx::NativeWindow window) {
- return base::MakeUnique<CursorRendererAura>(window,
+ return std::make_unique<CursorRendererAura>(window,
kCursorEnabledOnMouseMovement);
}
diff --git a/chromium/content/browser/media/capture/cursor_renderer_mac.mm b/chromium/content/browser/media/capture/cursor_renderer_mac.mm
index 6bb4d13e00a..66f887165cf 100644
--- a/chromium/content/browser/media/capture/cursor_renderer_mac.mm
+++ b/chromium/content/browser/media/capture/cursor_renderer_mac.mm
@@ -60,7 +60,7 @@ namespace content {
// static
std::unique_ptr<CursorRenderer> CursorRenderer::Create(gfx::NativeView view) {
- return base::MakeUnique<CursorRendererMac>(view);
+ return std::make_unique<CursorRendererMac>(view);
}
CursorRendererMac::CursorRendererMac(gfx::NativeView view)
diff --git a/chromium/content/browser/media/capture/desktop_capture_device.cc b/chromium/content/browser/media/capture/desktop_capture_device.cc
index 2c733c766a4..323d99feb5a 100644
--- a/chromium/content/browser/media/capture/desktop_capture_device.cc
+++ b/chromium/content/browser/media/capture/desktop_capture_device.cc
@@ -41,6 +41,7 @@
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
+#include "third_party/webrtc/modules/desktop_capture/fake_desktop_capturer.h"
#include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
namespace content {
@@ -415,8 +416,8 @@ void DesktopCaptureDevice::Core::RequestWakeLock(
connector->BindInterface(device::mojom::kServiceName,
mojo::MakeRequest(&wake_lock_provider));
wake_lock_provider->GetWakeLockWithoutContext(
- device::mojom::WakeLockType::PreventDisplaySleep,
- device::mojom::WakeLockReason::ReasonOther, "Desktop capture is running",
+ device::mojom::WakeLockType::kPreventDisplaySleep,
+ device::mojom::WakeLockReason::kOther, "Desktop capture is running",
mojo::MakeRequest(&wake_lock_));
wake_lock_->RequestWakeLock();
@@ -427,6 +428,14 @@ std::unique_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
const DesktopMediaID& source) {
auto options = CreateDesktopCaptureOptions();
std::unique_ptr<webrtc::DesktopCapturer> capturer;
+ std::unique_ptr<media::VideoCaptureDevice> result;
+
+ // For browser tests, to create a fake desktop capturer.
+ if (source.id == DesktopMediaID::kFakeId) {
+ capturer.reset(new webrtc::FakeDesktopCapturer());
+ result.reset(new DesktopCaptureDevice(std::move(capturer), source.type));
+ return result;
+ }
switch (source.type) {
case DesktopMediaID::TYPE_SCREEN: {
@@ -460,7 +469,6 @@ std::unique_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
default: { NOTREACHED(); }
}
- std::unique_ptr<media::VideoCaptureDevice> result;
if (capturer)
result.reset(new DesktopCaptureDevice(std::move(capturer), source.type));
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 ec0eda767bd..2ca9d760ba0 100644
--- a/chromium/content/browser/media/capture/desktop_capture_device_unittest.cc
+++ b/chromium/content/browser/media/capture/desktop_capture_device_unittest.cc
@@ -176,11 +176,10 @@ class UnpackedDesktopFrame : public webrtc::DesktopFrame {
class FakeScreenCapturer : public webrtc::DesktopCapturer {
public:
FakeScreenCapturer()
- : callback_(NULL),
+ : callback_(nullptr),
frame_index_(0),
generate_inverted_frames_(false),
- generate_cropped_frames_(false) {
- }
+ generate_cropped_frames_(false) {}
~FakeScreenCapturer() override {}
void set_generate_inverted_frames(bool generate_inverted_frames) {
diff --git a/chromium/content/browser/media/capture/fake_webcontent_capture_machine.cc b/chromium/content/browser/media/capture/fake_webcontent_capture_machine.cc
new file mode 100644
index 00000000000..cedac4e2b0c
--- /dev/null
+++ b/chromium/content/browser/media/capture/fake_webcontent_capture_machine.cc
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/capture/fake_webcontent_capture_machine.h"
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+
+namespace content {
+
+FakeWebContentCaptureMachine::FakeWebContentCaptureMachine(
+ bool enable_auto_throttling)
+ : enable_auto_throttling_(enable_auto_throttling) {
+ DVLOG(2) << "FakeWebContentCaptureMachine";
+}
+
+FakeWebContentCaptureMachine::~FakeWebContentCaptureMachine() {
+ DVLOG(2) << "FakeWebContentCaptureMachine@" << this << " destroying.";
+}
+
+void FakeWebContentCaptureMachine::Start(
+ const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy,
+ const media::VideoCaptureParams& params,
+ const base::Callback<void(bool)> callback) {
+ callback.Run(true);
+}
+void FakeWebContentCaptureMachine::Suspend() {}
+void FakeWebContentCaptureMachine::Resume() {}
+void FakeWebContentCaptureMachine::Stop(const base::Closure& callback) {}
+bool FakeWebContentCaptureMachine::IsAutoThrottlingEnabled() const {
+ return enable_auto_throttling_;
+}
+void FakeWebContentCaptureMachine::MaybeCaptureForRefresh() {}
+
+} // namespace content \ No newline at end of file
diff --git a/chromium/content/browser/media/capture/fake_webcontent_capture_machine.h b/chromium/content/browser/media/capture/fake_webcontent_capture_machine.h
new file mode 100644
index 00000000000..92a5f84a3ec
--- /dev/null
+++ b/chromium/content/browser/media/capture/fake_webcontent_capture_machine.h
@@ -0,0 +1,41 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_FAKE_WEBCONTENT_CAPTURE_MACHINE_H_
+#define CONTENT_BROWSER_MEDIA_CAPTURE_FAKE_WEBCONTENT_CAPTURE_MACHINE_H_
+
+#include "base/callback_helpers.h"
+#include "content/common/content_export.h"
+#include "media/capture/content/screen_capture_device_core.h"
+#include "media/capture/content/thread_safe_capture_oracle.h"
+#include "media/capture/video_capture_types.h"
+
+namespace content {
+
+// An implementation of VideoCaptureDevice that fakes a desktop capturer.
+class CONTENT_EXPORT FakeWebContentCaptureMachine
+ : public media::VideoCaptureMachine {
+ public:
+ FakeWebContentCaptureMachine(bool enable_auto_throttling);
+ ~FakeWebContentCaptureMachine() override;
+
+ // VideoCaptureMachine overrides.
+ void Start(const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy,
+ const media::VideoCaptureParams& params,
+ const base::Callback<void(bool)> callback) override;
+ void Suspend() override;
+ void Resume() override;
+ void Stop(const base::Closure& callback) override;
+ bool IsAutoThrottlingEnabled() const override;
+ void MaybeCaptureForRefresh() override;
+
+ private:
+ bool enable_auto_throttling_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeWebContentCaptureMachine);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_FAKE_CAPTURE_DEVICE_H_ \ No newline at end of file
diff --git a/chromium/content/browser/media/capture/screen_capture_device_android.cc b/chromium/content/browser/media/capture/screen_capture_device_android.cc
index acdd5eb6efc..a249ce5ec80 100644
--- a/chromium/content/browser/media/capture/screen_capture_device_android.cc
+++ b/chromium/content/browser/media/capture/screen_capture_device_android.cc
@@ -11,7 +11,7 @@
namespace content {
ScreenCaptureDeviceAndroid::ScreenCaptureDeviceAndroid()
- : core_(base::MakeUnique<media::ScreenCaptureMachineAndroid>()) {}
+ : core_(std::make_unique<media::ScreenCaptureMachineAndroid>()) {}
ScreenCaptureDeviceAndroid::~ScreenCaptureDeviceAndroid() {
DVLOG(2) << "ScreenCaptureDeviceAndroid@" << this << " destroying.";
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 ee0a89fbd66..c227bd59a06 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
@@ -82,14 +82,14 @@ class ScreenCaptureDeviceAndroidTest : public testing::Test {
TEST_F(ScreenCaptureDeviceAndroidTest, ConstructionDestruction) {
std::unique_ptr<media::VideoCaptureDevice> capture_device =
- base::MakeUnique<ScreenCaptureDeviceAndroid>();
+ std::make_unique<ScreenCaptureDeviceAndroid>();
}
// Place holder. Currently user input result is required to start
// MediaProjection, so we can't start a unittest that really starts capture.
TEST_F(ScreenCaptureDeviceAndroidTest, DISABLED_StartAndStop) {
std::unique_ptr<media::VideoCaptureDevice> capture_device =
- base::MakeUnique<ScreenCaptureDeviceAndroid>();
+ std::make_unique<ScreenCaptureDeviceAndroid>();
ASSERT_TRUE(capture_device);
std::unique_ptr<MockDeviceClient> client(new MockDeviceClient());
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 303d910e137..15957b6d3ec 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
@@ -15,6 +15,7 @@
#include "content/browser/media/capture/audio_mirroring_manager.h"
#include "content/browser/media/capture/web_contents_tracker.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/desktop_media_id.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"
@@ -145,7 +146,7 @@ WebContentsAudioInputStream::Impl::Impl(
mixer_stream_(mixer_stream),
state_(CONSTRUCTED),
is_target_lost_(false),
- callback_(NULL),
+ callback_(nullptr),
is_duplication_(is_duplication) {
DCHECK(mirroring_manager_);
DCHECK(tracker_);
@@ -162,9 +163,13 @@ WebContentsAudioInputStream::Impl::~Impl() {
bool WebContentsAudioInputStream::Impl::Open() {
DCHECK(thread_checker_.CalledOnValidThread());
-
DCHECK_EQ(CONSTRUCTED, state_) << "Illegal to Open more than once.";
+ // For browser tests, not to start audio track to a fake tab.
+ if (initial_render_process_id_ == DesktopMediaID::kFakeId &&
+ initial_main_render_frame_id_ == DesktopMediaID::kFakeId)
+ return true;
+
if (!mixer_stream_->Open())
return false;
@@ -195,7 +200,7 @@ void WebContentsAudioInputStream::Impl::Start(AudioInputCallback* callback) {
callback_ = callback;
if (is_target_lost_) {
ReportError();
- callback_ = NULL;
+ callback_ = nullptr;
return;
}
@@ -220,7 +225,7 @@ void WebContentsAudioInputStream::Impl::Stop() {
state_ = OPENED;
mixer_stream_->Stop();
- callback_ = NULL;
+ callback_ = nullptr;
StopMirroring();
}
@@ -367,7 +372,7 @@ WebContentsAudioInputStream* WebContentsAudioInputStream::Create(
AudioMirroringManager* audio_mirroring_manager) {
WebContentsMediaCaptureId media_id;
if (!WebContentsMediaCaptureId::Parse(device_id, &media_id)) {
- return NULL;
+ return nullptr;
}
return new WebContentsAudioInputStream(
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 bdff30f3e37..7c1911b90a2 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
@@ -188,9 +188,9 @@ class WebContentsAudioInputStreamTest : public testing::TestWithParam<bool> {
audio_thread_("Audio thread"),
mock_mirroring_manager_(new MockAudioMirroringManager()),
mock_tracker_(new MockWebContentsTracker()),
- mock_vais_(NULL),
- wcais_(NULL),
- destination_(NULL),
+ mock_vais_(nullptr),
+ wcais_(nullptr),
+ destination_(nullptr),
current_render_process_id_(kRenderProcessId),
current_render_frame_id_(kRenderFrameId),
on_data_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
@@ -250,7 +250,7 @@ class WebContentsAudioInputStreamTest : public testing::TestWithParam<bool> {
EXPECT_CALL(*mock_mirroring_manager_, StopMirroring(NotNull()))
.WillOnce(Assign(
&destination_,
- static_cast<AudioMirroringManager::MirroringDestination*>(NULL)))
+ static_cast<AudioMirroringManager::MirroringDestination*>(nullptr)))
.RetiresOnSaturation();
EXPECT_CALL(mock_input_callback_, OnData(NotNull(), _, _))
@@ -377,8 +377,8 @@ class WebContentsAudioInputStreamTest : public testing::TestWithParam<bool> {
// objects hang around until they are no longer referred to (e.g., as tasks
// on other threads shut things down).
wcais_->Close();
- wcais_ = NULL;
- mock_vais_ = NULL;
+ wcais_ = nullptr;
+ mock_vais_ = nullptr;
}
void RunOnAudioThread(const base::Closure& closure) {
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 c64ba5809f2..0bdbdf3694d 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
@@ -19,12 +19,14 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/media/capture/cursor_renderer.h"
+#include "content/browser/media/capture/fake_webcontent_capture_machine.h"
#include "content/browser/media/capture/web_contents_tracker.h"
#include "content/browser/media/capture/window_activity_tracker.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/render_widget_host_view_frame_subscriber.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/desktop_media_id.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
@@ -685,17 +687,33 @@ void WebContentsCaptureMachine::UpdateCaptureSize() {
if (!view)
return;
- // Convert the view's size from the DIP coordinate space to the pixel
- // coordinate space. When the view is being rendered on a high-DPI display,
- // this allows the high-resolution image detail to propagate through to the
- // captured video.
- const gfx::Size view_size = view->GetViewBounds().size();
- const gfx::Size physical_size = gfx::ConvertSizeToPixel(
- ui::GetScaleFactorForNativeView(view->GetNativeView()), view_size);
- VLOG(1) << "Computed physical capture size (" << physical_size.ToString()
- << ") from view size (" << view_size.ToString() << ").";
+ // The capture size is not the view's size in DIP coordinates, but instead
+ // based on the physical backing size. Thus, when a view is being rendered on
+ // a high-DPI display, the high-resolution image detail will propagate through
+ // in the captured video output.
+ const gfx::Size physical_size_pixels =
+ static_cast<RenderWidgetHostViewBase*>(view)->GetPhysicalBackingSize();
+ VLOG(1) << "Physical capture size pixels of view is "
+ << physical_size_pixels.ToString();
- oracle_proxy_->UpdateCaptureSize(physical_size);
+ oracle_proxy_->UpdateCaptureSize(physical_size_pixels);
+}
+
+std::unique_ptr<media::VideoCaptureMachine> CreateVideoCaptureMachine(
+ int render_process_id,
+ int main_render_frame_id,
+ bool enable_auto_throttling) {
+ std::unique_ptr<media::VideoCaptureMachine> video_capture_machine;
+ if (render_process_id != DesktopMediaID::kFakeId &&
+ main_render_frame_id != DesktopMediaID::kFakeId) {
+ video_capture_machine.reset(new WebContentsCaptureMachine(
+ render_process_id, main_render_frame_id, enable_auto_throttling));
+ } else { // For browser tests, to create a fake tab capturer.
+ video_capture_machine.reset(
+ new FakeWebContentCaptureMachine(enable_auto_throttling));
+ }
+
+ return video_capture_machine;
}
} // namespace
@@ -705,10 +723,9 @@ WebContentsVideoCaptureDevice::WebContentsVideoCaptureDevice(
int main_render_frame_id,
bool enable_auto_throttling)
: core_(new media::ScreenCaptureDeviceCore(
- std::unique_ptr<media::VideoCaptureMachine>(
- new WebContentsCaptureMachine(render_process_id,
- main_render_frame_id,
- enable_auto_throttling)))) {}
+ CreateVideoCaptureMachine(render_process_id,
+ main_render_frame_id,
+ enable_auto_throttling))) {}
WebContentsVideoCaptureDevice::~WebContentsVideoCaptureDevice() {
DVLOG(2) << "WebContentsVideoCaptureDevice@" << this << " destroying.";
diff --git a/chromium/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/chromium/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
index 9f2c3122d8d..35987b59a0d 100644
--- a/chromium/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
+++ b/chromium/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
@@ -22,6 +22,7 @@
#include "content/browser/browser_thread_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_view_host_factory.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_frame_subscriber.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -32,6 +33,7 @@
#include "content/public/test/test_utils.h"
#include "content/test/test_render_frame_host_factory.h"
#include "content/test/test_render_view_host.h"
+#include "content/test/test_render_widget_host_factory.h"
#include "content/test/test_web_contents.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
@@ -187,11 +189,10 @@ class CaptureTestRenderViewHost : public TestRenderViewHost {
int32_t main_frame_routing_id,
bool swapped_out)
: TestRenderViewHost(instance,
- base::MakeUnique<RenderWidgetHostImpl>(
+ TestRenderWidgetHost::Create(
widget_delegate,
instance->GetProcess(),
routing_id,
- nullptr,
false /* This means: "Is not hidden." */),
delegate,
main_frame_routing_id,
@@ -240,7 +241,7 @@ class StubClient : public media::VideoCaptureDevice::Client {
: report_callback_(report_callback),
error_callback_(error_callback) {
buffer_pool_ = new media::VideoCaptureBufferPoolImpl(
- base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), 2);
+ std::make_unique<media::VideoCaptureBufferTrackerFactoryImpl>(), 2);
}
~StubClient() override {}
@@ -469,11 +470,15 @@ class WebContentsVideoCaptureDeviceTest : public testing::Test {
// CopyFromSurfaceToVideoFrame functionality into TestRenderWidgetHostView
// itself.
- render_process_host_factory_.reset(new MockRenderProcessHostFactory());
+ render_process_host_factory_ =
+ std::make_unique<MockRenderProcessHostFactory>();
// Create our (self-registering) RVH factory, so that when we create a
// WebContents, it in turn creates CaptureTestRenderViewHosts.
- render_view_host_factory_.reset(new CaptureTestRenderViewHostFactory());
- render_frame_host_factory_.reset(new TestRenderFrameHostFactory());
+ render_view_host_factory_ =
+ std::make_unique<CaptureTestRenderViewHostFactory>();
+ render_frame_host_factory_ = std::make_unique<TestRenderFrameHostFactory>();
+ render_widget_host_factory_ =
+ std::make_unique<TestRenderWidgetHostFactory>();
browser_context_.reset(new TestBrowserContext());
@@ -507,7 +512,7 @@ class WebContentsVideoCaptureDeviceTest : public testing::Test {
base::RunLoop().RunUntilIdle();
- RenderProcessHostImpl::set_render_process_host_factory(NULL);
+ RenderProcessHostImpl::set_render_process_host_factory(nullptr);
render_frame_host_factory_.reset();
render_view_host_factory_.reset();
render_process_host_factory_.reset();
@@ -632,6 +637,9 @@ class WebContentsVideoCaptureDeviceTest : public testing::Test {
// Self-registering RenderFrameHostFactory.
std::unique_ptr<TestRenderFrameHostFactory> render_frame_host_factory_;
+ // Self-registering RenderWidgetHostFactory.
+ std::unique_ptr<TestRenderWidgetHostFactory> render_widget_host_factory_;
+
// A mocked-out browser and tab.
std::unique_ptr<TestBrowserContext> browser_context_;
std::unique_ptr<WebContents> web_contents_;
diff --git a/chromium/content/browser/media/cdm_file_impl.cc b/chromium/content/browser/media/cdm_file_impl.cc
new file mode 100644
index 00000000000..434071b2b7d
--- /dev/null
+++ b/chromium/content/browser/media/cdm_file_impl.cc
@@ -0,0 +1,363 @@
+// Copyright 2017 The Chromium Authors. 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/cdm_file_impl.h"
+
+#include <set>
+#include <utility>
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "base/task_scheduler/post_task.h"
+#include "storage/browser/fileapi/file_system_context.h"
+#include "storage/browser/fileapi/file_system_operation_context.h"
+#include "storage/browser/fileapi/file_system_url.h"
+#include "storage/browser/quota/quota_manager.h"
+#include "storage/common/fileapi/file_system_types.h"
+
+namespace content {
+
+namespace {
+
+// The CDM interface has a restriction that file names can not begin with _,
+// so use it to prefix temporary files.
+const char kTemporaryFilePrefix[] = "_";
+
+std::string GetTempFileName(const std::string& file_name) {
+ DCHECK(!base::StartsWith(file_name, kTemporaryFilePrefix,
+ base::CompareCase::SENSITIVE));
+ return kTemporaryFilePrefix + file_name;
+}
+
+// The file system is different for each CDM and each origin. So track files
+// in use based on (file system ID, origin, file name).
+struct FileLockKey {
+ FileLockKey(const std::string& file_system_id,
+ const url::Origin& origin,
+ const std::string& file_name)
+ : file_system_id(file_system_id), origin(origin), file_name(file_name) {}
+ ~FileLockKey() = default;
+
+ // Allow use as a key in std::set.
+ bool operator<(const FileLockKey& other) const {
+ return std::tie(file_system_id, origin, file_name) <
+ std::tie(other.file_system_id, other.origin, other.file_name);
+ }
+
+ std::string file_system_id;
+ url::Origin origin;
+ std::string file_name;
+};
+
+// File map shared by all CdmFileImpl objects to prevent read/write race.
+// A lock must be acquired before opening a file to ensure that the file is not
+// currently in use. The lock must be held until the file is closed.
+class FileLockMap {
+ public:
+ FileLockMap() = default;
+ ~FileLockMap() = default;
+
+ // Acquire a lock on the file represented by |key|. Returns true if |key|
+ // is not currently in use, false otherwise.
+ bool AcquireFileLock(const FileLockKey& key) {
+ DVLOG(3) << __func__ << " file: " << key.file_name;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ // Add a new entry. If |key| already has an entry, insert() tells so
+ // with the second piece of the returned value and does not modify
+ // the original.
+ return file_lock_map_.insert(key).second;
+ }
+
+ // Tests whether a lock is held on |key| or not. Returns true if |key|
+ // is currently locked, false otherwise.
+ bool IsFileLockHeld(const FileLockKey& key) {
+ DVLOG(3) << __func__ << " file: " << key.file_name;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ // Lock is held if there is an entry for |key|.
+ return file_lock_map_.count(key) > 0;
+ }
+
+ // Release the lock held on the file represented by |key|. If
+ // |on_close_callback| has been set, run it before releasing the lock.
+ void ReleaseFileLock(const FileLockKey& key) {
+ DVLOG(3) << __func__ << " file: " << key.file_name;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ auto entry = file_lock_map_.find(key);
+ if (entry == file_lock_map_.end()) {
+ NOTREACHED() << "Unable to release lock on file " << key.file_name;
+ return;
+ }
+
+ file_lock_map_.erase(entry);
+ }
+
+ private:
+ // Note that this map is never deleted. As entries are removed when a file
+ // is closed, it should never get too large.
+ std::set<FileLockKey> file_lock_map_;
+
+ THREAD_CHECKER(thread_checker_);
+ DISALLOW_COPY_AND_ASSIGN(FileLockMap);
+};
+
+// The FileLockMap is a global lock map shared by all CdmFileImpl instances.
+FileLockMap* GetFileLockMap() {
+ static auto* file_lock_map = new FileLockMap();
+ return file_lock_map;
+}
+
+} // namespace
+
+CdmFileImpl::CdmFileImpl(
+ const std::string& file_name,
+ const url::Origin& origin,
+ const std::string& file_system_id,
+ const std::string& file_system_root_uri,
+ scoped_refptr<storage::FileSystemContext> file_system_context)
+ : file_name_(file_name),
+ temp_file_name_(GetTempFileName(file_name_)),
+ origin_(origin),
+ file_system_id_(file_system_id),
+ file_system_root_uri_(file_system_root_uri),
+ file_system_context_(file_system_context),
+ weak_factory_(this) {
+ DVLOG(3) << __func__ << " " << file_name_;
+}
+
+CdmFileImpl::~CdmFileImpl() {
+ DVLOG(3) << __func__ << " " << file_name_;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ // If a file open was started but hasn't completed by now, run the callback
+ // and report an error.
+ if (pending_open_callback_) {
+ std::move(pending_open_callback_)
+ .Run(base::File(base::File::FILE_ERROR_ABORT));
+ }
+
+ if (lock_state_ == LockState::kFileAndTempFileLocked) {
+ // Temporary file is open, so close and release it.
+ if (temporary_file_on_close_callback_)
+ std::move(temporary_file_on_close_callback_).Run();
+ ReleaseFileLock(temp_file_name_);
+ }
+ if (lock_state_ != LockState::kNone) {
+ // Original file is open, so close and release it.
+ if (on_close_callback_)
+ std::move(on_close_callback_).Run();
+ ReleaseFileLock(file_name_);
+ }
+}
+
+void CdmFileImpl::Initialize(OpenFileCallback callback) {
+ DVLOG(3) << __func__ << " file: " << file_name_;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(LockState::kNone, lock_state_);
+ DCHECK(!pending_open_callback_);
+
+ // Grab the lock on |file_name_|. The lock will be held until this object is
+ // destructed.
+ if (!AcquireFileLock(file_name_)) {
+ DVLOG(3) << "File " << file_name_ << " is already in use.";
+ std::move(callback).Run(base::File(base::File::FILE_ERROR_IN_USE));
+ return;
+ }
+
+ // We have the lock on |file_name_|. Now open the file for reading. Since
+ // we don't know if this file exists or not, provide FLAG_OPEN_ALWAYS to
+ // create the file if it doesn't exist.
+ lock_state_ = LockState::kFileLocked;
+ pending_open_callback_ = std::move(callback);
+ OpenFile(file_name_, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ,
+ base::Bind(&CdmFileImpl::OnFileOpenedForReading,
+ weak_factory_.GetWeakPtr()));
+}
+
+void CdmFileImpl::OpenFile(const std::string& file_name,
+ uint32_t file_flags,
+ CreateOrOpenCallback callback) {
+ DVLOG(3) << __func__ << " file: " << file_name << ", flags: " << file_flags;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_NE(LockState::kNone, lock_state_);
+ DCHECK(IsFileLockHeld(file_name));
+ DCHECK(pending_open_callback_);
+
+ storage::FileSystemURL file_url = CreateFileSystemURL(file_name);
+ storage::AsyncFileUtil* file_util = file_system_context_->GetAsyncFileUtil(
+ storage::kFileSystemTypePluginPrivate);
+ auto operation_context =
+ std::make_unique<storage::FileSystemOperationContext>(
+ file_system_context_.get());
+ operation_context->set_allowed_bytes_growth(storage::QuotaManager::kNoLimit);
+ DVLOG(3) << "Opening " << file_url.DebugString();
+
+ file_util->CreateOrOpen(std::move(operation_context), file_url, file_flags,
+ std::move(callback));
+}
+
+void CdmFileImpl::OnFileOpenedForReading(
+ base::File file,
+ const base::Closure& on_close_callback) {
+ DVLOG(3) << __func__ << " file: " << file_name_;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(LockState::kFileLocked, lock_state_);
+ DCHECK(pending_open_callback_);
+
+ if (!file.IsValid()) {
+ // File is invalid. Note that the lock on |file_name_| is kept until this
+ // object is destructed.
+ DLOG(WARNING) << "Unable to open file " << file_name_ << ", error: "
+ << base::File::ErrorToString(file.error_details());
+ std::move(pending_open_callback_).Run(std::move(file));
+ return;
+ }
+
+ // When the file is closed, |on_close_callback| will be run.
+ on_close_callback_ = std::move(on_close_callback);
+ std::move(pending_open_callback_).Run(std::move(file));
+}
+
+void CdmFileImpl::OpenFileForWriting(OpenFileForWritingCallback callback) {
+ DVLOG(3) << __func__ << " " << file_name_;
+
+ // Fail if this is called out of order. We must have opened the original
+ // file, and there should be no call in progress.
+ if (lock_state_ != LockState::kFileLocked || pending_open_callback_) {
+ std::move(callback).Run(
+ base::File(base::File::FILE_ERROR_INVALID_OPERATION));
+ return;
+ }
+
+ // Grab a lock on the temporary file. The lock will be held until this
+ // new file is renamed in CommitWrite() (or this object is
+ // destructed).
+ if (!AcquireFileLock(temp_file_name_)) {
+ DVLOG(3) << "File " << temp_file_name_ << " is already in use.";
+ std::move(callback).Run(base::File(base::File::FILE_ERROR_IN_USE));
+ return;
+ }
+
+ // We now have locks on both |file_name_| and |temp_file_name_|. Open the
+ // temporary file for writing. Specifying FLAG_CREATE_ALWAYS which will
+ // overwrite any existing file.
+ lock_state_ = LockState::kFileAndTempFileLocked;
+ pending_open_callback_ = std::move(callback);
+ OpenFile(temp_file_name_,
+ base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE,
+ base::Bind(&CdmFileImpl::OnTempFileOpenedForWriting,
+ weak_factory_.GetWeakPtr()));
+}
+
+void CdmFileImpl::OnTempFileOpenedForWriting(
+ base::File file,
+ const base::Closure& on_close_callback) {
+ DVLOG(3) << __func__ << " file: " << file_name_;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(LockState::kFileAndTempFileLocked, lock_state_);
+ DCHECK(pending_open_callback_);
+
+ if (!file.IsValid()) {
+ DLOG(WARNING) << "Unable to open file " << temp_file_name_ << ", error: "
+ << base::File::ErrorToString(file.error_details());
+ lock_state_ = LockState::kFileLocked;
+ ReleaseFileLock(temp_file_name_);
+ std::move(pending_open_callback_).Run(std::move(file));
+ return;
+ }
+
+ temporary_file_on_close_callback_ = std::move(on_close_callback);
+ std::move(pending_open_callback_).Run(std::move(file));
+}
+
+void CdmFileImpl::CommitWrite(CommitWriteCallback callback) {
+ DVLOG(3) << __func__ << " " << temp_file_name_ << " to " << file_name_;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(LockState::kFileAndTempFileLocked, lock_state_);
+ DCHECK(IsFileLockHeld(file_name_));
+ DCHECK(IsFileLockHeld(temp_file_name_));
+
+ // TODO(jrummell): Verify that the written file does not exceed the file
+ // size limit of 32MB. If it does simply delete the written file and fail.
+
+ // Fail if this is called out of order. We must have opened both the original
+ // and the temporary file, and there should be no call in progress.
+ if (lock_state_ != LockState::kFileAndTempFileLocked ||
+ pending_open_callback_) {
+ std::move(callback).Run(
+ base::File(base::File::FILE_ERROR_INVALID_OPERATION));
+ return;
+ }
+
+ if (on_close_callback_)
+ std::move(on_close_callback_).Run();
+ if (temporary_file_on_close_callback_)
+ std::move(temporary_file_on_close_callback_).Run();
+
+ // OpenFile() will be called after the file is renamed, so save |callback|.
+ pending_open_callback_ = std::move(callback);
+
+ storage::FileSystemURL src_file_url = CreateFileSystemURL(temp_file_name_);
+ storage::FileSystemURL dest_file_url = CreateFileSystemURL(file_name_);
+ storage::AsyncFileUtil* file_util = file_system_context_->GetAsyncFileUtil(
+ storage::kFileSystemTypePluginPrivate);
+ auto operation_context =
+ std::make_unique<storage::FileSystemOperationContext>(
+ file_system_context_.get());
+ DVLOG(3) << "Renaming " << src_file_url.DebugString() << " to "
+ << dest_file_url.DebugString();
+ file_util->MoveFileLocal(
+ std::move(operation_context), src_file_url, dest_file_url,
+ storage::FileSystemOperation::OPTION_NONE,
+ base::Bind(&CdmFileImpl::OnFileRenamed, weak_factory_.GetWeakPtr()));
+}
+
+void CdmFileImpl::OnFileRenamed(base::File::Error move_result) {
+ DVLOG(3) << __func__;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(LockState::kFileAndTempFileLocked, lock_state_);
+ DCHECK(pending_open_callback_);
+
+ // Temporary file has been renamed, so we can release the lock on it.
+ ReleaseFileLock(temp_file_name_);
+ lock_state_ = LockState::kFileLocked;
+
+ // Was the rename successful?
+ if (move_result != base::File::FILE_OK) {
+ std::move(pending_open_callback_).Run(base::File(move_result));
+ return;
+ }
+
+ // Reopen the original file for reading. Specifying FLAG_OPEN as the file
+ // has to exist or something's wrong.
+ OpenFile(file_name_, base::File::FLAG_OPEN | base::File::FLAG_READ,
+ base::Bind(&CdmFileImpl::OnFileOpenedForReading,
+ weak_factory_.GetWeakPtr()));
+}
+
+storage::FileSystemURL CdmFileImpl::CreateFileSystemURL(
+ const std::string& file_name) {
+ return file_system_context_->CrackURL(
+ GURL(file_system_root_uri_ + file_name));
+}
+
+bool CdmFileImpl::AcquireFileLock(const std::string& file_name) {
+ FileLockKey file_lock_key(file_system_id_, origin_, file_name);
+ return GetFileLockMap()->AcquireFileLock(file_lock_key);
+}
+
+bool CdmFileImpl::IsFileLockHeld(const std::string& file_name) {
+ FileLockKey file_lock_key(file_system_id_, origin_, file_name);
+ return GetFileLockMap()->IsFileLockHeld(file_lock_key);
+}
+
+void CdmFileImpl::ReleaseFileLock(const std::string& file_name) {
+ FileLockKey file_lock_key(file_system_id_, origin_, file_name);
+ GetFileLockMap()->ReleaseFileLock(file_lock_key);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/cdm_file_impl.h b/chromium/content/browser/media/cdm_file_impl.h
new file mode 100644
index 00000000000..bbf3c9ab6d8
--- /dev/null
+++ b/chromium/content/browser/media/cdm_file_impl.h
@@ -0,0 +1,123 @@
+// Copyright 2017 The Chromium Authors. 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_CDM_FILE_IMPL_H_
+#define CONTENT_BROWSER_MEDIA_CDM_FILE_IMPL_H_
+
+#include <string>
+
+#include "base/callback_forward.h"
+#include "base/files/file.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "media/mojo/interfaces/cdm_storage.mojom.h"
+#include "storage/browser/fileapi/async_file_util.h"
+#include "url/origin.h"
+
+namespace storage {
+class FileSystemContext;
+class FileSystemURL;
+} // namespace storage
+
+namespace content {
+
+// This class implements the media::mojom::CdmFile interface. It uses the same
+// mojo pipe as CdmStorageImpl, to enforce message dispatch order.
+class CdmFileImpl final : public media::mojom::CdmFile {
+ public:
+ CdmFileImpl(const std::string& file_name,
+ const url::Origin& origin,
+ const std::string& file_system_id,
+ const std::string& file_system_root_uri,
+ scoped_refptr<storage::FileSystemContext> file_system_context);
+ ~CdmFileImpl() final;
+
+ // Called to open the file for read initially. Will create a file with
+ // |file_name_| if it does not exist. |file_opened_callback| will be called
+ // with the opened file descriptor on success. |file|.error_details()
+ // = base::File::FILE_ERROR_IN_USE if the file is in use by other CDMs
+ // or by the system. Note that |file_opened_callback| may destroy |this|
+ // (especially if the file can not be opened).
+ // Note that |this| should not be used anymore if Initialize() fails.
+ using OpenFileCallback = base::OnceCallback<void(base::File file)>;
+ void Initialize(OpenFileCallback file_opened_callback);
+
+ // media::mojom::CdmFile implementation. |callback| will be called with the
+ // file descriptor on success. Otherwise the file descriptor will not be
+ // valid, and error_details() provides the reason.
+ void OpenFileForWriting(OpenFileForWritingCallback callback) final;
+ void CommitWrite(CommitWriteCallback callback) final;
+
+ private:
+ using CreateOrOpenCallback = storage::AsyncFileUtil::CreateOrOpenCallback;
+
+ // Keep track of which files are locked.
+ // kFileLocked: Only the original file |file_name_| is locked.
+ // kFileAndTempFileLocked: Both |file_name_| and |temp_file_name_| are
+ // locked.
+ // Initialize() can only be called if kNone, results in kFileLocked (on
+ // success). OpenFileForWriting() can only be called if kFileLocked, results
+ // in kFileAndTempFileLocked. CommitWrite() can only be called if
+ // kFileAndTempFileLocked, results in kFileLocked (temp file closed and then
+ // renamed to replace the original).
+ enum class LockState { kNone, kFileLocked, kFileAndTempFileLocked };
+
+ // Open the file |file_name| using the flags provided in |file_flags|.
+ // |callback| is called with the result.
+ void OpenFile(const std::string& file_name,
+ uint32_t file_flags,
+ CreateOrOpenCallback callback);
+
+ void OnFileOpenedForReading(base::File file,
+ const base::Closure& on_close_callback);
+ void OnTempFileOpenedForWriting(base::File file,
+ const base::Closure& on_close_callback);
+ void OnFileRenamed(base::File::Error move_result);
+
+ // Returns the FileSystemURL for the specified |file_name|.
+ storage::FileSystemURL CreateFileSystemURL(const std::string& file_name);
+
+ // Helper methods to lock and unlock a file.
+ bool AcquireFileLock(const std::string& file_name);
+ bool IsFileLockHeld(const std::string& file_name);
+ void ReleaseFileLock(const std::string& file_name);
+
+ // Names of the files this class represents.
+ const std::string file_name_;
+ const std::string temp_file_name_;
+
+ // Files are stored in the PluginPrivateFileSystem. The following are needed
+ // to access files.
+ const url::Origin origin_;
+ const std::string file_system_id_;
+ const std::string file_system_root_uri_;
+ scoped_refptr<storage::FileSystemContext> file_system_context_;
+
+ // Keep track of which files are opened.
+ LockState lock_state_ = LockState::kNone;
+
+ // As only one open operation is allowed at a time, |pending_open_callback_|
+ // keeps track of the callback to be called when the file is opened. This
+ // ensures the callback is always called if we are destroyed while the open
+ // operation is running.
+ OpenFileCallback pending_open_callback_;
+
+ // Callbacks required to close the file when it's no longer needed.
+ // storage::AsyncFileUtil::CreateOrOpen() returns this callback on a
+ // successful open along with the base::File object, which should be
+ // called when the file is closed.
+ base::Closure on_close_callback_;
+ base::Closure temporary_file_on_close_callback_;
+
+ THREAD_CHECKER(thread_checker_);
+ base::WeakPtrFactory<CdmFileImpl> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(CdmFileImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_CDM_FILE_IMPL_H_
diff --git a/chromium/content/browser/media/cdm_storage_impl.cc b/chromium/content/browser/media/cdm_storage_impl.cc
index d7889106231..5b4be4371af 100644
--- a/chromium/content/browser/media/cdm_storage_impl.cc
+++ b/chromium/content/browser/media/cdm_storage_impl.cc
@@ -11,17 +11,17 @@
#include "base/callback.h"
#include "base/logging.h"
+#include "content/browser/media/cdm_file_impl.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
-#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "ppapi/shared_impl/ppapi_constants.h"
-#include "storage/browser/fileapi/async_file_util.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_operation_context.h"
#include "storage/browser/fileapi/isolated_context.h"
-#include "storage/browser/quota/quota_manager.h"
+#include "storage/common/fileapi/file_system_types.h"
+#include "storage/common/fileapi/file_system_util.h"
#include "url/origin.h"
// Currently this uses the PluginPrivateFileSystem as the previous CDMs ran
@@ -31,112 +31,6 @@
namespace content {
-namespace {
-
-// File map shared by all CdmStorageImpl objects to prevent read/write race.
-// A lock must be acquired before opening a file to ensure that the file is not
-// currently in use. Once the file is opened the file map must be updated to
-// include the callback used to close the file. The lock must be held until
-// the file is closed.
-class FileLockMap {
- public:
- using Key = CdmStorageImpl::FileLockKey;
-
- FileLockMap() = default;
- ~FileLockMap() = default;
-
- // Acquire a lock on the file represented by |key|. Returns true if |key|
- // is not currently in use, false otherwise.
- bool AcquireFileLock(const Key& key) {
- DVLOG(3) << __func__ << " file: " << key.file_name;
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- // Add a new entry. If |key| already has an entry, emplace() tells so
- // with the second piece of the returned value and does not modify
- // the original.
- return file_lock_map_.emplace(key, base::Closure()).second;
- }
-
- // Update the entry for the file represented by |key| so that
- // |on_close_callback| will be called when the lock is released.
- void SetOnCloseCallback(const Key& key, base::Closure on_close_callback) {
- DVLOG(3) << __func__ << " file: " << key.file_name;
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- DCHECK(!file_lock_map_.empty());
- auto entry = file_lock_map_.find(key);
- DCHECK(entry != file_lock_map_.end());
- entry->second = std::move(on_close_callback);
- }
-
- // Release the lock held on the file represented by |key|. If
- // |on_close_callback| has been set, run it before releasing the lock.
- void ReleaseFileLock(const Key& key) {
- DVLOG(3) << __func__ << " file: " << key.file_name;
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- auto entry = file_lock_map_.find(key);
- if (entry == file_lock_map_.end()) {
- NOTREACHED() << "Unable to relase lock on file " << key.file_name;
- return;
- }
-
- if (entry->second)
- entry->second.Run();
- file_lock_map_.erase(entry);
- }
-
- private:
- // Note that this map is never deleted. As entries are removed when a file
- // is closed, it should never get too large.
- std::map<Key, base::Closure> file_lock_map_;
-
- THREAD_CHECKER(thread_checker_);
- DISALLOW_COPY_AND_ASSIGN(FileLockMap);
-};
-
-FileLockMap* GetFileLockMap() {
- static auto* file_lock_map = new FileLockMap();
- return file_lock_map;
-}
-
-// mojom::CdmStorage::Open() returns a mojom::CdmFileReleaser reference to keep
-// track of the file being used. This object is created when the file is being
-// passed to the client. When the client is done using the file, the connection
-// should be broken and this will release the lock held on the file.
-class CdmFileReleaserImpl final : public media::mojom::CdmFileReleaser {
- public:
- using Key = CdmStorageImpl::FileLockKey;
-
- explicit CdmFileReleaserImpl(const Key& key) : key_(key) {
- DVLOG(1) << __func__;
- }
-
- ~CdmFileReleaserImpl() override {
- DVLOG(1) << __func__;
- GetFileLockMap()->ReleaseFileLock(key_);
- }
-
- private:
- Key key_;
-
- DISALLOW_COPY_AND_ASSIGN(CdmFileReleaserImpl);
-};
-
-} // namespace
-
-CdmStorageImpl::FileLockKey::FileLockKey(const std::string& cdm_file_system_id,
- const url::Origin& origin,
- const std::string& file_name)
- : cdm_file_system_id(cdm_file_system_id),
- origin(origin),
- file_name(file_name) {}
-
-bool CdmStorageImpl::FileLockKey::operator<(const FileLockKey& other) const {
- return std::tie(cdm_file_system_id, origin, file_name) <
- std::tie(other.cdm_file_system_id, other.origin, other.file_name);
-}
-
// static
void CdmStorageImpl::Create(RenderFrameHost* render_frame_host,
const std::string& cdm_file_system_id,
@@ -187,11 +81,6 @@ CdmStorageImpl::CdmStorageImpl(
CdmStorageImpl::~CdmStorageImpl() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- // If any file locks were taken in Open() and never made it to OnFileOpened(),
- // release them now as OnFileOpened() will never run.
- for (const auto& file_lock_key : pending_open_)
- GetFileLockMap()->ReleaseFileLock(file_lock_key);
}
void CdmStorageImpl::Open(const std::string& file_name, OpenCallback callback) {
@@ -210,109 +99,119 @@ void CdmStorageImpl::Open(const std::string& file_name, OpenCallback callback) {
return;
}
- FileLockKey file_lock_key(cdm_file_system_id_, origin(), file_name);
- if (!GetFileLockMap()->AcquireFileLock(file_lock_key)) {
- DVLOG(1) << "File " << file_name << " is already in use.";
- std::move(callback).Run(Status::kInUse, base::File(), nullptr);
+ // The file system should only be opened once. If it has been attempted and
+ // failed, we can't create the CdmFile objects.
+ if (file_system_state_ == FileSystemState::kError) {
+ std::move(callback).Run(Status::kFailure, base::File(), nullptr);
+ return;
+ }
+
+ // If the file system is already open, create and initialize the CdmFileImpl
+ // object.
+ if (file_system_state_ == FileSystemState::kOpened) {
+ CreateCdmFile(file_name, std::move(callback));
return;
}
+ // Save a file name and callback for when the file system is open. If the
+ // open is already in progress, nothing more to do until the existing
+ // OpenPluginPrivateFileSystem() call completes.
+ pending_open_calls_.emplace(pending_open_calls_.end(), file_name,
+ std::move(callback));
+ if (file_system_state_ == FileSystemState::kOpening)
+ return;
+
+ DCHECK_EQ(FileSystemState::kUnopened, file_system_state_);
+ file_system_state_ = FileSystemState::kOpening;
+
std::string fsid =
storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
storage::kFileSystemTypePluginPrivate, ppapi::kPluginPrivateRootName,
base::FilePath());
if (!storage::ValidateIsolatedFileSystemId(fsid)) {
DVLOG(1) << "Invalid file system ID.";
- GetFileLockMap()->ReleaseFileLock(file_lock_key);
- std::move(callback).Run(Status::kFailure, base::File(), nullptr);
+ OnFileSystemOpened(base::File::FILE_ERROR_NOT_FOUND);
return;
}
- // In case this object gets destroyed before OpenPluginPrivateFileSystem()
- // completes, keep track of |file_lock_key| so that it can be released if
- // OnFileSystemOpened() or OnFileOpened() never get called.
- pending_open_.insert(file_lock_key);
-
// Grant full access of isolated file system to child process.
ChildProcessSecurityPolicy::GetInstance()->GrantCreateReadWriteFileSystem(
child_process_id_, fsid);
+ // Keep track of the URI for this instance of the PluginPrivateFileSystem.
+ file_system_root_uri_ = storage::GetIsolatedFileSystemRootURIString(
+ origin().GetURL(), fsid, ppapi::kPluginPrivateRootName);
+
file_system_context_->OpenPluginPrivateFileSystem(
origin().GetURL(), storage::kFileSystemTypePluginPrivate, fsid,
cdm_file_system_id_, storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
base::Bind(&CdmStorageImpl::OnFileSystemOpened,
- weak_factory_.GetWeakPtr(), file_lock_key, fsid,
- base::Passed(&callback)));
+ weak_factory_.GetWeakPtr()));
}
-void CdmStorageImpl::OnFileSystemOpened(const FileLockKey& file_lock_key,
- const std::string& fsid,
- OpenCallback callback,
- base::File::Error error) {
+void CdmStorageImpl::OnFileSystemOpened(base::File::Error error) {
DVLOG(3) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(FileSystemState::kOpening, file_system_state_);
if (error != base::File::FILE_OK) {
- DVLOG(1) << "Unable to access the file system.";
- pending_open_.erase(file_lock_key);
- GetFileLockMap()->ReleaseFileLock(file_lock_key);
- std::move(callback).Run(Status::kFailure, base::File(), nullptr);
+ file_system_state_ = FileSystemState::kError;
+ // All pending calls will fail.
+ for (auto& pending : pending_open_calls_) {
+ std::move(pending.second).Run(Status::kFailure, base::File(), nullptr);
+ }
+ pending_open_calls_.clear();
return;
}
- std::string root = storage::GetIsolatedFileSystemRootURIString(
- origin().GetURL(), fsid, ppapi::kPluginPrivateRootName)
- .append(file_lock_key.file_name);
- storage::FileSystemURL file_url = file_system_context_->CrackURL(GURL(root));
- storage::AsyncFileUtil* file_util = file_system_context_->GetAsyncFileUtil(
- storage::kFileSystemTypePluginPrivate);
- auto operation_context =
- std::make_unique<storage::FileSystemOperationContext>(
- file_system_context_.get());
- operation_context->set_allowed_bytes_growth(storage::QuotaManager::kNoLimit);
- int flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
- base::File::FLAG_WRITE;
- DVLOG(1) << "Opening " << file_url.DebugString();
- file_util->CreateOrOpen(
- std::move(operation_context), file_url, flags,
- base::Bind(&CdmStorageImpl::OnFileOpened, weak_factory_.GetWeakPtr(),
- file_lock_key, base::Passed(&callback)));
+ // File system successfully opened, so create the CdmFileImpl object for
+ // all pending Open() calls.
+ file_system_state_ = FileSystemState::kOpened;
+ for (auto& pending : pending_open_calls_) {
+ CreateCdmFile(pending.first, std::move(pending.second));
+ }
+ pending_open_calls_.clear();
}
-void CdmStorageImpl::OnFileOpened(const FileLockKey& file_lock_key,
- OpenCallback callback,
- base::File file,
- const base::Closure& on_close_callback) {
- // |on_close_callback| should be called after the |file| is closed in the
- // child process. See AsyncFileUtil for details.
- DVLOG(3) << __func__;
+void CdmStorageImpl::CreateCdmFile(const std::string& file_name,
+ OpenCallback callback) {
+ DVLOG(3) << __func__ << " file: " << file_name;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(FileSystemState::kOpened, file_system_state_);
+
+ // File system opened successfully, so create an CdmFileImpl object and
+ // initialize it (which actually opens the file for reading).
+ auto cdm_file_impl = std::make_unique<CdmFileImpl>(
+ file_name, origin(), cdm_file_system_id_, file_system_root_uri_,
+ file_system_context_);
+ auto* cdm_file_ptr = cdm_file_impl.get();
+ cdm_file_ptr->Initialize(base::BindOnce(
+ &CdmStorageImpl::OnCdmFileInitialized, weak_factory_.GetWeakPtr(),
+ std::move(cdm_file_impl), std::move(callback)));
+}
- // |file_lock_key| will either be used by CdmFileReleaserImpl on a successful
- // open or released if |file| is not valid, so the open is no longer pending.
- pending_open_.erase(file_lock_key);
+void CdmStorageImpl::OnCdmFileInitialized(
+ std::unique_ptr<CdmFileImpl> cdm_file_impl,
+ OpenCallback callback,
+ base::File file) {
+ DVLOG(3) << __func__;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!file.IsValid()) {
- DLOG(WARNING) << "Unable to open file " << file_lock_key.file_name
- << ", error: "
- << base::File::ErrorToString(file.error_details());
- GetFileLockMap()->ReleaseFileLock(file_lock_key);
- std::move(callback).Run(Status::kFailure, base::File(), nullptr);
+ // Unable to open the file requested. Return an appropriate error.
+ Status status = (file.error_details() == base::File::FILE_ERROR_IN_USE)
+ ? Status::kInUse
+ : Status::kFailure;
+ std::move(callback).Run(status, base::File(), nullptr);
return;
}
- GetFileLockMap()->SetOnCloseCallback(file_lock_key,
- std::move(on_close_callback));
-
- // When the connection to |releaser| is closed, ReleaseFileLock() will be
- // called. This will release the lock on the file and cause
- // |on_close_callback| to be run.
- media::mojom::CdmFileReleaserAssociatedPtrInfo releaser;
- mojo::MakeStrongAssociatedBinding(
- std::make_unique<CdmFileReleaserImpl>(file_lock_key),
- mojo::MakeRequest(&releaser));
+ // File was opened successfully, so create the binding and return success.
+ media::mojom::CdmFileAssociatedPtrInfo cdm_file;
+ cdm_file_bindings_.AddBinding(std::move(cdm_file_impl),
+ mojo::MakeRequest(&cdm_file));
std::move(callback).Run(Status::kSuccess, std::move(file),
- std::move(releaser));
+ std::move(cdm_file));
}
} // namespace content
diff --git a/chromium/content/browser/media/cdm_storage_impl.h b/chromium/content/browser/media/cdm_storage_impl.h
index a90d5e49aff..331d2b9ca47 100644
--- a/chromium/content/browser/media/cdm_storage_impl.h
+++ b/chromium/content/browser/media/cdm_storage_impl.h
@@ -16,16 +16,14 @@
#include "content/common/content_export.h"
#include "content/public/browser/frame_service_base.h"
#include "media/mojo/interfaces/cdm_storage.mojom.h"
+#include "mojo/public/cpp/bindings/strong_associated_binding_set.h"
namespace storage {
class FileSystemContext;
}
-namespace url {
-class Origin;
-}
-
namespace content {
+class CdmFileImpl;
class RenderFrameHost;
// This class implements the media::mojom::CdmStorage using the
@@ -34,21 +32,6 @@ class RenderFrameHost;
class CONTENT_EXPORT CdmStorageImpl final
: public content::FrameServiceBase<media::mojom::CdmStorage> {
public:
- // The file system is different for each CDM and each origin. So track files
- // in use based on the tuple CDM file system ID, origin, and file name.
- struct FileLockKey {
- FileLockKey(const std::string& cdm_file_system_id,
- const url::Origin& origin,
- const std::string& file_name);
- ~FileLockKey() = default;
-
- // Allow use as a key in std::set.
- bool operator<(const FileLockKey& other) const;
-
- std::string cdm_file_system_id;
- url::Origin origin;
- std::string file_name;
- };
// Check if |cdm_file_system_id| is valid.
static bool IsValidCdmFileSystemId(const std::string& cdm_file_system_id);
@@ -63,39 +46,54 @@ class CONTENT_EXPORT CdmStorageImpl final
void Open(const std::string& file_name, OpenCallback callback) final;
private:
+ // File system should only be opened once, so keep track if it has already
+ // been opened (or is in the process of opening). State is kError if an error
+ // happens while opening the file system.
+ enum class FileSystemState { kUnopened, kOpening, kOpened, kError };
+
CdmStorageImpl(RenderFrameHost* render_frame_host,
const std::string& cdm_file_system_id,
scoped_refptr<storage::FileSystemContext> file_system_context,
media::mojom::CdmStorageRequest request);
~CdmStorageImpl() final;
- // Called when the file system has been opened (OpenPluginPrivateFileSystem
- // is asynchronous).
- void OnFileSystemOpened(const FileLockKey& key,
- const std::string& fsid,
- OpenCallback callback,
- base::File::Error error);
+ // Called when the file system is opened.
+ void OnFileSystemOpened(base::File::Error error);
+
+ // After the file system is opened, called to create a CdmFile object.
+ void CreateCdmFile(const std::string& file_name, OpenCallback callback);
- // Called when the requested file has been opened.
- void OnFileOpened(const FileLockKey& key,
- OpenCallback callback,
- base::File file,
- const base::Closure& on_close_callback);
+ // Called after the CdmFileImpl object has opened the file for reading.
+ void OnCdmFileInitialized(std::unique_ptr<CdmFileImpl> cdm_file_impl,
+ OpenCallback callback,
+ base::File file);
// Files are stored in the PluginPrivateFileSystem, so keep track of the
// CDM file system ID in order to open the files in the correct context.
const std::string cdm_file_system_id_;
scoped_refptr<storage::FileSystemContext> file_system_context_;
+ // The PluginPrivateFileSystem only needs to be opened once.
+ FileSystemState file_system_state_ = FileSystemState::kUnopened;
+
+ // As multiple calls to Open() could happen while the file system is being
+ // opened asynchronously, keep track of the requests so they can be
+ // processed once the file system is open.
+ using PendingOpenData = std::pair<std::string, OpenCallback>;
+ std::vector<PendingOpenData> pending_open_calls_;
+
+ // Once the PluginPrivateFileSystem is opened, keep track of the URI that
+ // refers to it.
+ std::string file_system_root_uri_;
+
// This is the child process that will actually read and write the file(s)
- // returned, and it needs permission to access the file when it's opened.
+ // returned, and it needs permission to access the file(s).
const int child_process_id_;
- // As a lock is taken on a file when Open() is called, it needs to be
- // released if the async operations to open the file haven't completed
- // by the time |this| is destroyed. So keep track of FileLockKey for files
- // that have a lock on them but failed to finish.
- std::set<FileLockKey> pending_open_;
+ // Keep track of all media::mojom::CdmFile bindings, as each CdmFileImpl
+ // object keeps a reference to |this|. If |this| goes away unexpectedly,
+ // all remaining CdmFile bindings will be closed.
+ mojo::StrongAssociatedBindingSet<media::mojom::CdmFile> cdm_file_bindings_;
base::WeakPtrFactory<CdmStorageImpl> weak_factory_;
diff --git a/chromium/content/browser/media/cdm_storage_impl_unittest.cc b/chromium/content/browser/media/cdm_storage_impl_unittest.cc
index 06cc8f39896..b7e0dbc6a43 100644
--- a/chromium/content/browser/media/cdm_storage_impl_unittest.cc
+++ b/chromium/content/browser/media/cdm_storage_impl_unittest.cc
@@ -8,6 +8,7 @@
#include "base/callback.h"
#include "base/files/file.h"
#include "base/logging.h"
+#include "base/run_loop.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/navigation_simulator.h"
@@ -18,7 +19,11 @@
#include "url/gurl.h"
#include "url/origin.h"
+using media::mojom::CdmFile;
+using media::mojom::CdmFileAssociatedPtr;
+using media::mojom::CdmFileAssociatedPtrInfo;
using media::mojom::CdmStorage;
+using media::mojom::CdmStoragePtr;
namespace content {
@@ -63,40 +68,67 @@ class CdmStorageTest : public RenderViewHostTestHarness {
}
// Open the file |name|. Returns true if the file returned is valid, false
- // otherwise. Updates |status|, |file|, and |releaser| with the values
+ // otherwise. Updates |status|, |file|, and |cdm_file| with the values
// returned by CdmStorage. If |status| = kSuccess, |file| should be valid to
- // access, and |releaser| should be reset when the file is closed.
+ // access, and |cdm_file| should be reset when the file is closed.
bool Open(const std::string& name,
CdmStorage::Status* status,
base::File* file,
- media::mojom::CdmFileReleaserAssociatedPtr* releaser) {
+ CdmFileAssociatedPtr* cdm_file) {
DVLOG(3) << __func__;
cdm_storage_->Open(
name, base::Bind(&CdmStorageTest::OpenDone, base::Unretained(this),
- status, file, releaser));
+ status, file, cdm_file));
RunAndWaitForResult();
return file->IsValid();
}
+ bool Write(CdmFile* cdm_file,
+ const std::vector<uint8_t>& data,
+ base::File* file) {
+ bool status;
+ cdm_file->OpenFileForWriting(base::Bind(&CdmStorageTest::FileOpenedForWrite,
+ base::Unretained(this), cdm_file,
+ data, file, &status));
+ RunAndWaitForResult();
+ return status;
+ }
+
private:
- void OpenDone(
- CdmStorage::Status* status,
- base::File* file,
- media::mojom::CdmFileReleaserAssociatedPtr* releaser,
- CdmStorage::Status actual_status,
- base::File actual_file,
- media::mojom::CdmFileReleaserAssociatedPtrInfo actual_releaser) {
+ void OpenDone(CdmStorage::Status* status,
+ base::File* file,
+ CdmFileAssociatedPtr* cdm_file,
+ CdmStorage::Status actual_status,
+ base::File actual_file,
+ CdmFileAssociatedPtrInfo actual_cdm_file) {
DVLOG(3) << __func__;
*status = actual_status;
*file = std::move(actual_file);
- // Open() returns a CdmFileReleaserAssociatedPtrInfo, so bind it to the
- // CdmFileReleaserAssociatedPtr provided.
- media::mojom::CdmFileReleaserAssociatedPtr releaser_ptr;
- releaser_ptr.Bind(std::move(actual_releaser));
- *releaser = std::move(releaser_ptr);
+ // Open() returns a CdmFileAssociatedPtrInfo, so bind it to the
+ // CdmFileAssociatedPtr provided.
+ CdmFileAssociatedPtr cdm_file_ptr;
+ cdm_file_ptr.Bind(std::move(actual_cdm_file));
+ *cdm_file = std::move(cdm_file_ptr);
+ run_loop_->Quit();
+ }
+ void FileOpenedForWrite(CdmFile* cdm_file,
+ const std::vector<uint8_t>& data,
+ base::File* file,
+ bool* status,
+ base::File file_to_write) {
+ int bytes_to_write = base::checked_cast<int>(data.size());
+ int bytes_written = file_to_write.Write(
+ 0, reinterpret_cast<const char*>(data.data()), bytes_to_write);
+ *status = bytes_to_write == bytes_written;
+ cdm_file->CommitWrite(
+ base::Bind(&CdmStorageTest::WriteDone, base::Unretained(this), file));
+ }
+
+ void WriteDone(base::File* file, base::File new_file_for_reading) {
+ *file = std::move(new_file_for_reading);
run_loop_->Quit();
}
@@ -107,7 +139,7 @@ class CdmStorageTest : public RenderViewHostTestHarness {
}
RenderFrameHost* rfh_ = nullptr;
- media::mojom::CdmStoragePtr cdm_storage_;
+ CdmStoragePtr cdm_storage_;
std::unique_ptr<base::RunLoop> run_loop_;
};
@@ -117,11 +149,11 @@ TEST_F(CdmStorageTest, InvalidFileSystemIdWithSlash) {
const char kFileName[] = "valid_file_name";
CdmStorage::Status status;
base::File file;
- media::mojom::CdmFileReleaserAssociatedPtr releaser;
- EXPECT_FALSE(Open(kFileName, &status, &file, &releaser));
+ CdmFileAssociatedPtr cdm_file;
+ EXPECT_FALSE(Open(kFileName, &status, &file, &cdm_file));
EXPECT_EQ(status, CdmStorage::Status::kFailure);
EXPECT_FALSE(file.IsValid());
- EXPECT_FALSE(releaser.is_bound());
+ EXPECT_FALSE(cdm_file.is_bound());
}
TEST_F(CdmStorageTest, InvalidFileSystemIdWithBackSlash) {
@@ -130,11 +162,11 @@ TEST_F(CdmStorageTest, InvalidFileSystemIdWithBackSlash) {
const char kFileName[] = "valid_file_name";
CdmStorage::Status status;
base::File file;
- media::mojom::CdmFileReleaserAssociatedPtr releaser;
- EXPECT_FALSE(Open(kFileName, &status, &file, &releaser));
+ CdmFileAssociatedPtr cdm_file;
+ EXPECT_FALSE(Open(kFileName, &status, &file, &cdm_file));
EXPECT_EQ(status, CdmStorage::Status::kFailure);
EXPECT_FALSE(file.IsValid());
- EXPECT_FALSE(releaser.is_bound());
+ EXPECT_FALSE(cdm_file.is_bound());
}
TEST_F(CdmStorageTest, InvalidFileSystemIdEmpty) {
@@ -143,11 +175,11 @@ TEST_F(CdmStorageTest, InvalidFileSystemIdEmpty) {
const char kFileName[] = "valid_file_name";
CdmStorage::Status status;
base::File file;
- media::mojom::CdmFileReleaserAssociatedPtr releaser;
- EXPECT_FALSE(Open(kFileName, &status, &file, &releaser));
+ CdmFileAssociatedPtr cdm_file;
+ EXPECT_FALSE(Open(kFileName, &status, &file, &cdm_file));
EXPECT_EQ(status, CdmStorage::Status::kFailure);
EXPECT_FALSE(file.IsValid());
- EXPECT_FALSE(releaser.is_bound());
+ EXPECT_FALSE(cdm_file.is_bound());
}
TEST_F(CdmStorageTest, InvalidFileNameEmpty) {
@@ -156,11 +188,11 @@ TEST_F(CdmStorageTest, InvalidFileNameEmpty) {
const char kFileName[] = "";
CdmStorage::Status status;
base::File file;
- media::mojom::CdmFileReleaserAssociatedPtr releaser;
- EXPECT_FALSE(Open(kFileName, &status, &file, &releaser));
+ CdmFileAssociatedPtr cdm_file;
+ EXPECT_FALSE(Open(kFileName, &status, &file, &cdm_file));
EXPECT_EQ(status, CdmStorage::Status::kFailure);
EXPECT_FALSE(file.IsValid());
- EXPECT_FALSE(releaser.is_bound());
+ EXPECT_FALSE(cdm_file.is_bound());
}
TEST_F(CdmStorageTest, OpenFile) {
@@ -169,11 +201,11 @@ TEST_F(CdmStorageTest, OpenFile) {
const char kFileName[] = "test_file_name";
CdmStorage::Status status;
base::File file;
- media::mojom::CdmFileReleaserAssociatedPtr releaser;
- EXPECT_TRUE(Open(kFileName, &status, &file, &releaser));
+ CdmFileAssociatedPtr cdm_file;
+ EXPECT_TRUE(Open(kFileName, &status, &file, &cdm_file));
EXPECT_EQ(status, CdmStorage::Status::kSuccess);
EXPECT_TRUE(file.IsValid());
- EXPECT_TRUE(releaser.is_bound());
+ EXPECT_TRUE(cdm_file.is_bound());
}
TEST_F(CdmStorageTest, OpenFileLocked) {
@@ -182,30 +214,30 @@ TEST_F(CdmStorageTest, OpenFileLocked) {
const char kFileName[] = "test_file_name";
CdmStorage::Status status;
base::File file1;
- media::mojom::CdmFileReleaserAssociatedPtr releaser1;
- EXPECT_TRUE(Open(kFileName, &status, &file1, &releaser1));
+ CdmFileAssociatedPtr cdm_file1;
+ EXPECT_TRUE(Open(kFileName, &status, &file1, &cdm_file1));
EXPECT_EQ(status, CdmStorage::Status::kSuccess);
EXPECT_TRUE(file1.IsValid());
- EXPECT_TRUE(releaser1.is_bound());
+ EXPECT_TRUE(cdm_file1.is_bound());
// Second attempt on the same file should fail as the file is locked.
base::File file2;
- media::mojom::CdmFileReleaserAssociatedPtr releaser2;
- EXPECT_FALSE(Open(kFileName, &status, &file2, &releaser2));
+ CdmFileAssociatedPtr cdm_file2;
+ EXPECT_FALSE(Open(kFileName, &status, &file2, &cdm_file2));
EXPECT_EQ(status, CdmStorage::Status::kInUse);
EXPECT_FALSE(file2.IsValid());
- EXPECT_FALSE(releaser2.is_bound());
+ EXPECT_FALSE(cdm_file2.is_bound());
// Now close the first file and try again. It should be free now.
file1.Close();
- releaser1.reset();
+ cdm_file1.reset();
base::File file3;
- media::mojom::CdmFileReleaserAssociatedPtr releaser3;
- EXPECT_TRUE(Open(kFileName, &status, &file3, &releaser3));
+ CdmFileAssociatedPtr cdm_file3;
+ EXPECT_TRUE(Open(kFileName, &status, &file3, &cdm_file3));
EXPECT_EQ(status, CdmStorage::Status::kSuccess);
EXPECT_TRUE(file3.IsValid());
- EXPECT_TRUE(releaser3.is_bound());
+ EXPECT_TRUE(cdm_file3.is_bound());
}
TEST_F(CdmStorageTest, MultipleFiles) {
@@ -214,52 +246,83 @@ TEST_F(CdmStorageTest, MultipleFiles) {
const char kFileName1[] = "file1";
CdmStorage::Status status;
base::File file1;
- media::mojom::CdmFileReleaserAssociatedPtr releaser1;
- EXPECT_TRUE(Open(kFileName1, &status, &file1, &releaser1));
+ CdmFileAssociatedPtr cdm_file1;
+ EXPECT_TRUE(Open(kFileName1, &status, &file1, &cdm_file1));
EXPECT_EQ(status, CdmStorage::Status::kSuccess);
EXPECT_TRUE(file1.IsValid());
- EXPECT_TRUE(releaser1.is_bound());
+ EXPECT_TRUE(cdm_file1.is_bound());
const char kFileName2[] = "file2";
base::File file2;
- media::mojom::CdmFileReleaserAssociatedPtr releaser2;
- EXPECT_TRUE(Open(kFileName2, &status, &file2, &releaser2));
+ CdmFileAssociatedPtr cdm_file2;
+ EXPECT_TRUE(Open(kFileName2, &status, &file2, &cdm_file2));
EXPECT_EQ(status, CdmStorage::Status::kSuccess);
EXPECT_TRUE(file2.IsValid());
- EXPECT_TRUE(releaser2.is_bound());
+ EXPECT_TRUE(cdm_file2.is_bound());
const char kFileName3[] = "file3";
base::File file3;
- media::mojom::CdmFileReleaserAssociatedPtr releaser3;
- EXPECT_TRUE(Open(kFileName3, &status, &file3, &releaser3));
+ CdmFileAssociatedPtr cdm_file3;
+ EXPECT_TRUE(Open(kFileName3, &status, &file3, &cdm_file3));
EXPECT_EQ(status, CdmStorage::Status::kSuccess);
EXPECT_TRUE(file3.IsValid());
- EXPECT_TRUE(releaser3.is_bound());
+ EXPECT_TRUE(cdm_file3.is_bound());
}
-TEST_F(CdmStorageTest, ReadWriteFile) {
+TEST_F(CdmStorageTest, WriteThenReadFile) {
Initialize(kTestFileSystemId);
const char kFileName[] = "test_file_name";
CdmStorage::Status status;
base::File file;
- media::mojom::CdmFileReleaserAssociatedPtr releaser;
- EXPECT_TRUE(Open(kFileName, &status, &file, &releaser));
+ CdmFileAssociatedPtr cdm_file;
+ EXPECT_TRUE(Open(kFileName, &status, &file, &cdm_file));
EXPECT_EQ(status, CdmStorage::Status::kSuccess);
EXPECT_TRUE(file.IsValid());
- EXPECT_TRUE(releaser.is_bound());
+ EXPECT_TRUE(cdm_file.is_bound());
// Write several bytes and read them back.
- const char kTestData[] = "random string";
+ const uint8_t kTestData[] = "random string";
const int kTestDataSize = sizeof(kTestData);
- EXPECT_EQ(kTestDataSize, file.Write(0, kTestData, kTestDataSize));
+ EXPECT_TRUE(Write(cdm_file.get(),
+ std::vector<uint8_t>(kTestData, kTestData + kTestDataSize),
+ &file));
+ EXPECT_TRUE(file.IsValid());
- char data_read[32];
+ uint8_t data_read[32];
const int kTestDataReadSize = sizeof(data_read);
EXPECT_GT(kTestDataReadSize, kTestDataSize);
- EXPECT_EQ(kTestDataSize, file.Read(0, data_read, kTestDataReadSize));
+ EXPECT_EQ(kTestDataSize, file.Read(0, reinterpret_cast<char*>(data_read),
+ kTestDataReadSize));
for (size_t i = 0; i < kTestDataSize; i++)
EXPECT_EQ(kTestData[i], data_read[i]);
}
+TEST_F(CdmStorageTest, ReadThenWriteEmptyFile) {
+ Initialize(kTestFileSystemId);
+
+ const char kFileName[] = "empty_file_name";
+ CdmStorage::Status status;
+ base::File file;
+ CdmFileAssociatedPtr cdm_file;
+ EXPECT_TRUE(Open(kFileName, &status, &file, &cdm_file));
+ EXPECT_EQ(status, CdmStorage::Status::kSuccess);
+ EXPECT_TRUE(file.IsValid());
+ EXPECT_TRUE(cdm_file.is_bound());
+
+ // New file should be empty.
+ uint8_t data_read[32];
+ const int kTestDataReadSize = sizeof(data_read);
+ EXPECT_EQ(
+ 0, file.Read(0, reinterpret_cast<char*>(data_read), kTestDataReadSize));
+
+ // Write nothing.
+ EXPECT_TRUE(Write(cdm_file.get(), std::vector<uint8_t>(), &file));
+ EXPECT_TRUE(file.IsValid());
+
+ // Should still be empty.
+ EXPECT_EQ(
+ 0, file.Read(0, reinterpret_cast<char*>(data_read), kTestDataReadSize));
+}
+
} // namespace content
diff --git a/chromium/content/browser/media/encrypted_media_browsertest.cc b/chromium/content/browser/media/encrypted_media_browsertest.cc
index 434cee39366..be9774146a4 100644
--- a/chromium/content/browser/media/encrypted_media_browsertest.cc
+++ b/chromium/content/browser/media/encrypted_media_browsertest.cc
@@ -13,6 +13,7 @@
#include "content/shell/browser/shell.h"
#include "media/base/media.h"
#include "media/base/media_switches.h"
+#include "media/base/test_data_util.h"
#include "media/media_features.h"
#include "media/mojo/features.h"
@@ -95,7 +96,7 @@ class EncryptedMediaTest : public MediaBrowserTest,
RunEncryptedMediaTest("encrypted_frame_size_change.html",
"frame_size_change-av_enc-v.webm",
kWebMVorbisAudioVP8Video, CurrentKeySystem(),
- CurrentSourceType(), kEnded);
+ CurrentSourceType(), media::kEnded);
}
void TestConfigChange(ConfigChangeType config_change_type) {
@@ -112,7 +113,8 @@ class EncryptedMediaTest : public MediaBrowserTest,
query_params.emplace_back(
"configChangeType",
base::IntToString(static_cast<int>(config_change_type)));
- RunMediaTestPage("mse_config_change.html", query_params, kEnded, true);
+ RunMediaTestPage("mse_config_change.html", query_params, media::kEnded,
+ true);
}
void RunEncryptedMediaTest(const std::string& html_page,
@@ -134,12 +136,8 @@ class EncryptedMediaTest : public MediaBrowserTest,
const std::string& media_type,
const std::string& key_system,
SrcType src_type) {
- RunEncryptedMediaTest(kDefaultEmePlayer,
- media_file,
- media_type,
- key_system,
- src_type,
- kEnded);
+ RunEncryptedMediaTest(kDefaultEmePlayer, media_file, media_type, key_system,
+ src_type, media::kEnded);
}
protected:
@@ -260,7 +258,13 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest,
TestConfigChange(ConfigChangeType::ENCRYPTED_TO_ENCRYPTED);
}
-IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, FrameSizeChangeVideo) {
+// https://crbug.com/788748
+#if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
+#define MAYBE_FrameSizeChangeVideo DISABLED_FrameSizeChangeVideo
+#else
+#define MAYBE_FrameSizeChangeVideo FrameSizeChangeVideo
+#endif
+IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, MAYBE_FrameSizeChangeVideo) {
TestFrameSizeChange();
}
diff --git a/chromium/content/browser/media/media_browsertest.cc b/chromium/content/browser/media/media_browsertest.cc
index 13450920c71..616fe408b86 100644
--- a/chromium/content/browser/media/media_browsertest.cc
+++ b/chromium/content/browser/media/media_browsertest.cc
@@ -21,19 +21,6 @@
namespace content {
-// TODO(sandersd): Change the tests to use a more unique message.
-// See http://crbug.com/592067
-
-// Common test results.
-const char MediaBrowserTest::kFailed[] = "FAILED";
-
-// Upper case event name set by Utils.installTitleEventHandler().
-const char MediaBrowserTest::kEnded[] = "ENDED";
-const char MediaBrowserTest::kErrorEvent[] = "ERROR";
-
-// Lower case event name as set by Utils.failTest().
-const char MediaBrowserTest::kError[] = "error";
-
#if defined(OS_ANDROID)
// Title set by android cleaner page after short timeout.
const char kClean[] = "CLEAN";
@@ -96,10 +83,10 @@ std::string MediaBrowserTest::EncodeErrorMessage(
}
void MediaBrowserTest::AddTitlesToAwait(content::TitleWatcher* title_watcher) {
- title_watcher->AlsoWaitForTitle(base::ASCIIToUTF16(kEnded));
- title_watcher->AlsoWaitForTitle(base::ASCIIToUTF16(kError));
- title_watcher->AlsoWaitForTitle(base::ASCIIToUTF16(kErrorEvent));
- title_watcher->AlsoWaitForTitle(base::ASCIIToUTF16(kFailed));
+ title_watcher->AlsoWaitForTitle(base::ASCIIToUTF16(media::kEnded));
+ title_watcher->AlsoWaitForTitle(base::ASCIIToUTF16(media::kError));
+ title_watcher->AlsoWaitForTitle(base::ASCIIToUTF16(media::kErrorEvent));
+ title_watcher->AlsoWaitForTitle(base::ASCIIToUTF16(media::kFailed));
}
// Tests playback and seeking of an audio or video file over file or http based
@@ -124,7 +111,7 @@ class MediaTest : public testing::WithParamInterface<bool>,
bool http) {
base::StringPairs query_params;
query_params.emplace_back(tag, media_file);
- RunMediaTestPage("player.html", query_params, kEnded, http);
+ RunMediaTestPage("player.html", query_params, media::kEnded, http);
}
void RunErrorMessageTest(const std::string& tag,
@@ -135,7 +122,7 @@ class MediaTest : public testing::WithParamInterface<bool>,
query_params.emplace_back(tag, media_file);
query_params.emplace_back("error_substr",
EncodeErrorMessage(expected_error_substring));
- RunMediaTestPage("player.html", query_params, kErrorEvent, http);
+ RunMediaTestPage("player.html", query_params, media::kErrorEvent, http);
}
void RunVideoSizeTest(const char* media_file, int width, int height) {
@@ -247,7 +234,7 @@ IN_PROC_BROWSER_TEST_F(MediaTest, VideoBearRotated270) {
#if !defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_F(MediaTest, LoadManyVideos) {
base::StringPairs query_params;
- RunMediaTestPage("load_many_videos.html", query_params, kEnded, true);
+ RunMediaTestPage("load_many_videos.html", query_params, media::kEnded, true);
}
#endif // !defined(OS_ANDROID)
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
diff --git a/chromium/content/browser/media/media_browsertest.h b/chromium/content/browser/media/media_browsertest.h
index c2f70478e7f..7e8688004f2 100644
--- a/chromium/content/browser/media/media_browsertest.h
+++ b/chromium/content/browser/media/media_browsertest.h
@@ -17,12 +17,6 @@ class TitleWatcher;
// A base class for media related browser tests.
class MediaBrowserTest : public ContentBrowserTest {
public:
- // Common test results.
- static const char kEnded[];
- static const char kError[];
- static const char kErrorEvent[];
- static const char kFailed[];
-
// ContentBrowserTest implementation.
void SetUpCommandLine(base::CommandLine* command_line) override;
diff --git a/chromium/content/browser/media/media_canplaytype_browsertest.cc b/chromium/content/browser/media/media_canplaytype_browsertest.cc
index 6b197c711b5..15bd97d9b73 100644
--- a/chromium/content/browser/media/media_canplaytype_browsertest.cc
+++ b/chromium/content/browser/media/media_canplaytype_browsertest.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "base/strings/string_util.h"
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/media/media_browsertest.h"
#include "content/public/test/browser_test_utils.h"
@@ -14,6 +15,7 @@
#include "content/shell/browser/shell.h"
#include "media/base/media_switches.h"
#include "media/media_features.h"
+#include "third_party/libaom/av1_features.h"
#include "ui/display/display_switches.h"
#if defined(OS_ANDROID)
@@ -70,9 +72,11 @@ namespace content {
class MediaCanPlayTypeTest : public MediaBrowserTest {
public:
- MediaCanPlayTypeTest() : url_("about:blank") { }
+ MediaCanPlayTypeTest() : url_("about:blank") {}
- void SetUpOnMainThread() override { NavigateToURL(shell(), url_); }
+ void SetUpOnMainThread() override {
+ NavigateToURL(shell(), url_);
+ }
std::string CanPlay(const std::string& type) {
std::string command("document.createElement('video').canPlayType(");
@@ -576,6 +580,37 @@ class MediaCanPlayTypeTest : public MediaBrowserTest {
DISALLOW_COPY_AND_ASSIGN(MediaCanPlayTypeTest);
};
+#if BUILDFLAG(ENABLE_AV1_DECODER)
+class AV1MediaCanPlayTypeTest : public MediaCanPlayTypeTest {
+ public:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ scoped_feature_list_.InitAndEnableFeature(media::kAv1Decoder);
+ MediaCanPlayTypeTest::SetUpCommandLine(command_line);
+ }
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// Note: This must be a separate test since features can not be changed after
+// the initial navigation.
+IN_PROC_BROWSER_TEST_F(AV1MediaCanPlayTypeTest, CodecSupportTest_av1) {
+ // TODO(dalecurtis): This is not the correct final string. Fix before enabling
+ // by default. This test needs to be merged into the existing mp4 and webm
+ // before release as well. http://crbug.com/784607
+ EXPECT_EQ(kProbably, CanPlay("'video/webm; codecs=\"av1\"'"));
+ EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"av1\"'"));
+}
+#endif // BUILDFLAG(ENABLE_AV1_DECODER)
+
+IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_av1_unsupported) {
+ // TODO(dalecurtis): This is not the correct final string. Fix before enabling
+ // by default. This test needs to be merged into the existing mp4 and webm
+ // before release as well. http://crbug.com/784607
+ EXPECT_EQ(kNot, CanPlay("'video/webm; codecs=\"av1\"'"));
+ EXPECT_EQ(kNot, CanPlay("'video/mp4; codecs=\"av1\"'"));
+}
+
IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_wav) {
EXPECT_EQ(kMaybe, CanPlay("'audio/wav'"));
EXPECT_EQ(kProbably, CanPlay("'audio/wav; codecs=\"1\"'"));
diff --git a/chromium/content/browser/media/media_capabilities_browsertest.cc b/chromium/content/browser/media/media_capabilities_browsertest.cc
index de84948cb38..e8084e81bf2 100644
--- a/chromium/content/browser/media/media_capabilities_browsertest.cc
+++ b/chromium/content/browser/media/media_capabilities_browsertest.cc
@@ -19,10 +19,14 @@
#include "media/base/media_switches.h"
#include "media/base/test_data_util.h"
+namespace {
+
const char kDecodeTestFile[] = "decode_capabilities_test.html";
const char kSupported[] = "SUPPORTED";
const char kUnsupported[] = "UNSUPPORTED";
const char kError[] = "ERROR";
+const char kFileString[] = "file";
+const char kMediaSourceString[] = "media-source";
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
const char* kPropSupported = kSupported;
@@ -30,7 +34,11 @@ const char* kPropSupported = kSupported;
const char* kPropSupported = kUnsupported;
#endif // USE_PROPRIETARY_CODECS
-enum ConfigType { AUDIO, VIDEO };
+enum StreamType { kAudio, kVideo };
+
+enum ConfigType { kFile, kMediaSource };
+
+} // namespace
namespace content {
@@ -43,23 +51,30 @@ class MediaCapabilitiesTest : public ContentBrowserTest {
"MediaCapabilities");
}
- std::string CanDecodeAudio(const std::string& content_type) {
- return CanDecode(content_type, ConfigType::AUDIO);
+ std::string CanDecodeAudio(const std::string& config_type,
+ const std::string& content_type) {
+ return CanDecode(config_type, content_type, StreamType::kAudio);
}
- std::string CanDecodeVideo(const std::string& content_type) {
- return CanDecode(content_type, ConfigType::VIDEO);
+ std::string CanDecodeVideo(const std::string& config_type,
+ const std::string& content_type) {
+ return CanDecode(config_type, content_type, StreamType::kVideo);
}
- std::string CanDecode(const std::string& content_type,
- ConfigType configType) {
+ std::string CanDecode(const std::string& config_type,
+ const std::string& content_type,
+ StreamType stream_type) {
std::string command;
- if (configType == ConfigType::AUDIO) {
- command.append("testAudioDecodeContentType(");
+ if (stream_type == StreamType::kAudio) {
+ command.append("testAudioConfig(");
} else {
- command.append("testVideoDecodeContentType(");
+ command.append("testVideoConfig(");
}
+ command.append("\"");
+ command.append(config_type);
+ command.append("\"");
+ command.append(", ");
command.append(content_type);
command.append(");");
@@ -76,74 +91,145 @@ class MediaCapabilitiesTest : public ContentBrowserTest {
DISALLOW_COPY_AND_ASSIGN(MediaCapabilitiesTest);
};
-// Cover basic codec support. See media_canplaytype_browsertest.cc for more
-// exhaustive codec string testing.
-IN_PROC_BROWSER_TEST_F(MediaCapabilitiesTest, VideoDecodeTypes) {
+// Adds param for query type (file vs media-source) to
+class MediaCapabilitiesTestWithConfigType
+ : public MediaCapabilitiesTest,
+ public testing::WithParamInterface<ConfigType> {
+ public:
+ std::string GetTypeString() const {
+ switch (GetParam()) {
+ case ConfigType::kFile:
+ return kFileString;
+ case ConfigType::kMediaSource:
+ return kMediaSourceString;
+ default:
+ NOTREACHED();
+ return "";
+ }
+ }
+};
+
+// Cover basic codec support of content types where the answer of support
+// (or not) should be common to both "media-source" and "file" query types.
+// for more exhaustive codec string testing.
+IN_PROC_BROWSER_TEST_P(MediaCapabilitiesTestWithConfigType,
+ CommonVideoDecodeTypes) {
base::FilePath file_path = media::GetTestDataFilePath(kDecodeTestFile);
+ const std::string& config_type = GetTypeString();
+
EXPECT_TRUE(
NavigateToURL(shell(), content::GetFileUrlWithQuery(file_path, "")));
- EXPECT_EQ(kSupported, CanDecodeVideo("'video/webm; codecs=\"vp8\"'"));
+ EXPECT_EQ(kSupported,
+ CanDecodeVideo(config_type, "'video/webm; codecs=\"vp8\"'"));
// Only support the new vp09 format which provides critical profile
// information.
- EXPECT_EQ(kUnsupported, CanDecodeVideo("'video/webm; codecs=\"vp9\"'"));
+ EXPECT_EQ(kUnsupported,
+ CanDecodeVideo(config_type, "'video/webm; codecs=\"vp9\"'"));
// Requires command line flag switches::kEnableNewVp9CodecString
- EXPECT_EQ(kSupported,
- CanDecodeVideo("'video/webm; codecs=\"vp09.00.10.08\"'"));
+ EXPECT_EQ(
+ kSupported,
+ CanDecodeVideo(config_type, "'video/webm; codecs=\"vp09.00.10.08\"'"));
// Supported when built with USE_PROPRIETARY_CODECS
EXPECT_EQ(kPropSupported,
- CanDecodeVideo("'video/mp4; codecs=\"avc1.42E01E\"'"));
- EXPECT_EQ(kPropSupported,
- CanDecodeVideo("'video/mp4; codecs=\"avc1.42101E\"'"));
+ CanDecodeVideo(config_type, "'video/mp4; codecs=\"avc1.42E01E\"'"));
EXPECT_EQ(kPropSupported,
- CanDecodeVideo("'video/mp4; codecs=\"avc1.42701E\"'"));
+ CanDecodeVideo(config_type, "'video/mp4; codecs=\"avc1.42101E\"'"));
EXPECT_EQ(kPropSupported,
- CanDecodeVideo("'video/mp4; codecs=\"avc1.42F01E\"'"));
+ CanDecodeVideo(config_type, "'video/mp4; codecs=\"avc1.42701E\"'"));
EXPECT_EQ(kPropSupported,
- CanDecodeVideo("'video/mp4; codecs=\"vp09.00.10.08\"'"));
+ CanDecodeVideo(config_type, "'video/mp4; codecs=\"avc1.42F01E\"'"));
+ EXPECT_EQ(
+ kPropSupported,
+ CanDecodeVideo(config_type, "'video/mp4; codecs=\"vp09.00.10.08\"'"));
// Test a handful of invalid strings.
- EXPECT_EQ(kUnsupported, CanDecodeVideo("'video/webm; codecs=\"theora\"'"));
EXPECT_EQ(kUnsupported,
- CanDecodeVideo("'video/webm; codecs=\"avc1.42E01E\"'"));
+ CanDecodeVideo(config_type, "'video/webm; codecs=\"theora\"'"));
+ EXPECT_EQ(
+ kUnsupported,
+ CanDecodeVideo(config_type, "'video/webm; codecs=\"avc1.42E01E\"'"));
// Only new vp09 format is supported with MP4.
- EXPECT_EQ(kUnsupported, CanDecodeVideo("'video/mp4; codecs=\"vp9\"'"));
+ EXPECT_EQ(kUnsupported,
+ CanDecodeVideo(config_type, "'video/mp4; codecs=\"vp9\"'"));
}
// Cover basic codec support. See media_canplaytype_browsertest.cc for more
// exhaustive codec string testing.
-IN_PROC_BROWSER_TEST_F(MediaCapabilitiesTest, AudioDecodeTypes) {
+IN_PROC_BROWSER_TEST_P(MediaCapabilitiesTestWithConfigType,
+ CommonAudioDecodeTypes) {
base::FilePath file_path = media::GetTestDataFilePath(kDecodeTestFile);
+ const std::string& config_type = GetTypeString();
+
EXPECT_TRUE(
NavigateToURL(shell(), content::GetFileUrlWithQuery(file_path, "")));
- EXPECT_EQ(kSupported, CanDecodeAudio("'audio/ogg; codecs=\"flac\"'"));
- EXPECT_EQ(kSupported, CanDecodeAudio("'audio/ogg; codecs=\"vorbis\"'"));
- EXPECT_EQ(kSupported, CanDecodeAudio("'audio/ogg; codecs=\"opus\"'"));
-
- EXPECT_EQ(kSupported, CanDecodeAudio("'audio/webm; codecs=\"opus\"'"));
- EXPECT_EQ(kSupported, CanDecodeAudio("'audio/webm; codecs=\"vorbis\"'"));
-
- EXPECT_EQ(kSupported, CanDecodeAudio("'audio/flac'"));
+ EXPECT_EQ(kSupported,
+ CanDecodeAudio(config_type, "'audio/webm; codecs=\"opus\"'"));
+ EXPECT_EQ(kSupported,
+ CanDecodeAudio(config_type, "'audio/webm; codecs=\"vorbis\"'"));
// Supported when built with USE_PROPRIETARY_CODECS
- EXPECT_EQ(kPropSupported, CanDecodeAudio("'audio/mpeg; codecs=\"mp4a.69\"'"));
EXPECT_EQ(kPropSupported,
- CanDecodeAudio("'audio/mp4; codecs=\"mp4a.40.02\"'"));
- EXPECT_EQ(kPropSupported, CanDecodeAudio("'audio/aac'"));
-
- // TODO(chcunningham): Differentiate kFile vs kMediaSource support for
- // FLAC-in-MP4, making MSE support for this contingent upon at least
- // base::FeatureList::IsEnabled(kMseFlacInIsobmff) and kPropSupported.
- EXPECT_EQ(kPropSupported, CanDecodeAudio("'audio/mp4; codecs=\"flac\"'"));
+ CanDecodeAudio(config_type, "'audio/mp4; codecs=\"mp4a.40.02\"'"));
+ EXPECT_EQ(kPropSupported, CanDecodeAudio(config_type, "'audio/aac'"));
+ EXPECT_EQ(kPropSupported,
+ CanDecodeAudio(config_type, "'audio/mp4; codecs=\"flac\"'"));
+ EXPECT_EQ(kPropSupported, CanDecodeAudio(config_type, "'audio/mpeg'"));
// Test a handful of invalid strings.
- EXPECT_EQ(kUnsupported, CanDecodeAudio("'audio/wav; codecs=\"mp3\"'"));
- EXPECT_EQ(kUnsupported, CanDecodeAudio("'audio/webm; codecs=\"vp8\"'"));
+ EXPECT_EQ(kUnsupported,
+ CanDecodeAudio(config_type, "'audio/wav; codecs=\"mp3\"'"));
+ EXPECT_EQ(kUnsupported,
+ CanDecodeAudio(config_type, "'audio/webm; codecs=\"vp8\"'"));
+}
+
+IN_PROC_BROWSER_TEST_P(MediaCapabilitiesTestWithConfigType,
+ NonMediaSourceDecodeTypes) {
+ base::FilePath file_path = media::GetTestDataFilePath(kDecodeTestFile);
+
+ const std::string& config_type = GetTypeString();
+
+ std::string type_supported = kSupported;
+ std::string prop_type_supported = kPropSupported;
+
+ // Content types below are supported for src=, but not MediaSource.
+ if (config_type == "media-source")
+ type_supported = prop_type_supported = kUnsupported;
+
+ EXPECT_TRUE(
+ NavigateToURL(shell(), content::GetFileUrlWithQuery(file_path, "")));
+
+ EXPECT_EQ(type_supported,
+ CanDecodeAudio(config_type, "'audio/wav; codecs=\"1\"'"));
+
+ // Flac is only supported in mp4 for MSE.
+ EXPECT_EQ(type_supported, CanDecodeAudio(config_type, "'audio/flac'"));
+
+ // Ogg is not supported in MSE.
+ EXPECT_EQ(type_supported,
+ CanDecodeAudio(config_type, "'audio/ogg; codecs=\"flac\"'"));
+ EXPECT_EQ(type_supported,
+ CanDecodeAudio(config_type, "'audio/ogg; codecs=\"vorbis\"'"));
+ EXPECT_EQ(type_supported,
+ CanDecodeAudio(config_type, "'audio/ogg; codecs=\"opus\"'"));
+
+ // MP3 is only supported via audio/mpeg for MSE.
+ EXPECT_EQ(prop_type_supported,
+ CanDecodeAudio(config_type, "'audio/mp4; codecs=\"mp4a.69\"'"));
+
+ // Ogg not supported in MSE.
+ EXPECT_EQ(type_supported,
+ CanDecodeAudio(config_type, "'audio/ogg; codecs=\"vorbis\"'"));
}
+INSTANTIATE_TEST_CASE_P(,
+ MediaCapabilitiesTestWithConfigType,
+ ::testing::Values(ConfigType::kFile,
+ ConfigType::kMediaSource));
+
} // namespace content
diff --git a/chromium/content/browser/media/media_color_browsertest.cc b/chromium/content/browser/media/media_color_browsertest.cc
index 82fbe3d9459..bf60b0e8553 100644
--- a/chromium/content/browser/media/media_color_browsertest.cc
+++ b/chromium/content/browser/media/media_color_browsertest.cc
@@ -15,8 +15,8 @@ class MediaColorTest : public MediaBrowserTest {
void RunColorTest(const std::string& video_file) {
base::FilePath path = media::GetTestDataFilePath("blackwhite.html");
std::string final_title =
- RunTest(GetFileUrlWithQuery(path, video_file), kEnded);
- EXPECT_EQ(kEnded, final_title);
+ RunTest(GetFileUrlWithQuery(path, video_file), media::kEnded);
+ EXPECT_EQ(media::kEnded, final_title);
}
};
diff --git a/chromium/content/browser/media/media_devices_permission_checker.cc b/chromium/content/browser/media/media_devices_permission_checker.cc
index b31d8a65760..ba1971a7ae8 100644
--- a/chromium/content/browser/media/media_devices_permission_checker.cc
+++ b/chromium/content/browser/media/media_devices_permission_checker.cc
@@ -44,10 +44,10 @@ MediaDevicesManager::BoolDeviceTypes DoCheckPermissionsOnUIThread(
bool mic_feature_policy = true;
bool camera_feature_policy = true;
if (base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions)) {
- mic_feature_policy = frame_host->IsFeatureEnabled(
- blink::WebFeaturePolicyFeature::kMicrophone);
+ mic_feature_policy =
+ frame_host->IsFeatureEnabled(blink::FeaturePolicyFeature::kMicrophone);
camera_feature_policy =
- frame_host->IsFeatureEnabled(blink::WebFeaturePolicyFeature::kCamera);
+ frame_host->IsFeatureEnabled(blink::FeaturePolicyFeature::kCamera);
}
MediaDevicesManager::BoolDeviceTypes result;
diff --git a/chromium/content/browser/media/media_devices_permission_checker_unittest.cc b/chromium/content/browser/media/media_devices_permission_checker_unittest.cc
index d9b45a4d010..ee97526b4a1 100644
--- a/chromium/content/browser/media/media_devices_permission_checker_unittest.cc
+++ b/chromium/content/browser/media/media_devices_permission_checker_unittest.cc
@@ -15,7 +15,7 @@
#include "content/public/test/test_renderer_host.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
#include "url/origin.h"
namespace content {
@@ -38,7 +38,7 @@ class TestWebContentsDelegate : public content::WebContentsDelegate {
class MediaDevicesPermissionCheckerTest : public RenderViewHostImplTestHarness {
public:
MediaDevicesPermissionCheckerTest()
- : origin_(GURL("https://www.google.com")),
+ : origin_(url::Origin::Create(GURL("https://www.google.com"))),
callback_run_(false),
callback_result_(false) {}
@@ -51,7 +51,7 @@ class MediaDevicesPermissionCheckerTest : public RenderViewHostImplTestHarness {
protected:
// The header policy should only be set once on page load, so we refresh the
// page to simulate that.
- void RefreshPageAndSetHeaderPolicy(blink::WebFeaturePolicyFeature feature,
+ void RefreshPageAndSetHeaderPolicy(blink::FeaturePolicyFeature feature,
bool enabled) {
NavigateAndCommit(origin_.GetURL());
std::vector<url::Origin> whitelist;
@@ -108,12 +108,12 @@ TEST_F(MediaDevicesPermissionCheckerTest, CheckPermissionWithFeaturePolicy) {
EXPECT_TRUE(CheckPermission(MEDIA_DEVICE_TYPE_AUDIO_INPUT));
EXPECT_TRUE(CheckPermission(MEDIA_DEVICE_TYPE_VIDEO_INPUT));
- RefreshPageAndSetHeaderPolicy(blink::WebFeaturePolicyFeature::kMicrophone,
+ RefreshPageAndSetHeaderPolicy(blink::FeaturePolicyFeature::kMicrophone,
/*enabled=*/false);
EXPECT_FALSE(CheckPermission(MEDIA_DEVICE_TYPE_AUDIO_INPUT));
EXPECT_TRUE(CheckPermission(MEDIA_DEVICE_TYPE_VIDEO_INPUT));
- RefreshPageAndSetHeaderPolicy(blink::WebFeaturePolicyFeature::kCamera,
+ RefreshPageAndSetHeaderPolicy(blink::FeaturePolicyFeature::kCamera,
/*enabled=*/false);
EXPECT_TRUE(CheckPermission(MEDIA_DEVICE_TYPE_AUDIO_INPUT));
EXPECT_FALSE(CheckPermission(MEDIA_DEVICE_TYPE_VIDEO_INPUT));
diff --git a/chromium/content/browser/media/media_devices_util.cc b/chromium/content/browser/media/media_devices_util.cc
index 722798c5644..0bcc5431f87 100644
--- a/chromium/content/browser/media/media_devices_util.cc
+++ b/chromium/content/browser/media/media_devices_util.cc
@@ -13,7 +13,9 @@
#include "base/strings/string_tokenizer.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_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/common/media_stream_request.h"
#include "media/base/media_switches.h"
@@ -110,4 +112,18 @@ void GetDefaultMediaDeviceID(
callback);
}
+std::pair<std::string, url::Origin> GetMediaDeviceSaltAndOrigin(
+ int render_process_id,
+ int render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RenderFrameHost* frame_host =
+ RenderFrameHost::FromID(render_process_id, render_frame_id);
+ RenderProcessHost* process_host =
+ RenderProcessHost::FromID(render_process_id);
+ return std::make_pair(
+ process_host ? process_host->GetBrowserContext()->GetMediaDeviceIDSalt()
+ : std::string(),
+ frame_host ? frame_host->GetLastCommittedOrigin() : url::Origin());
+}
+
} // namespace content
diff --git a/chromium/content/browser/media/media_devices_util.h b/chromium/content/browser/media/media_devices_util.h
index d8d8ac1f670..d41caec141e 100644
--- a/chromium/content/browser/media/media_devices_util.h
+++ b/chromium/content/browser/media/media_devices_util.h
@@ -6,10 +6,12 @@
#define CONTENT_BROWSER_MEDIA_MEDIA_DEVICES_UTIL_H_
#include <string>
+#include <utility>
#include "base/callback.h"
#include "content/common/content_export.h"
#include "content/common/media/media_devices.h"
+#include "url/origin.h"
namespace content {
@@ -21,6 +23,20 @@ void CONTENT_EXPORT GetDefaultMediaDeviceID(
int render_frame_id,
const base::Callback<void(const std::string&)>& callback);
+// Returns the current media device ID salt and security origin for the given
+// |render_process_id| and |render_frame_id|. These values are used to produce
+// unique media-device IDs for each origin and renderer process. These values
+// should not be cached since the user can explicitly change them at any time.
+// This function must run on the UI thread.
+std::pair<std::string, url::Origin> GetMediaDeviceSaltAndOrigin(
+ int render_process_id,
+ int render_frame_id);
+
+// Type definition to make it easier to use mock alternatives to
+// GetMediaDeviceSaltAndOrigin.
+using MediaDeviceSaltAndOriginCallback =
+ base::RepeatingCallback<std::pair<std::string, url::Origin>(int, int)>;
+
} // namespace content
#endif // CONTENT_BROWSER_MEDIA_MEDIA_DEVICES_UTIL_H_
diff --git a/chromium/content/browser/media/media_interface_proxy.cc b/chromium/content/browser/media/media_interface_proxy.cc
index fb25e5072a2..3513a992a30 100644
--- a/chromium/content/browser/media/media_interface_proxy.cc
+++ b/chromium/content/browser/media/media_interface_proxy.cc
@@ -266,11 +266,7 @@ media::mojom::InterfaceFactory* MediaInterfaceProxy::GetCdmInterfaceFactory(
const std::string& key_system) {
DCHECK(thread_checker_.CalledOnValidThread());
- // Set the CDM GUID to be the default user ID used when connecting to mojo
- // services. This is needed when ENABLE_STANDALONE_CDM_SERVICE is true but
- // ENABLE_LIBRARY_CDMS is false.
- std::string cdm_guid = service_manager::mojom::kInheritUserID;
-
+ std::string cdm_guid;
base::FilePath cdm_path;
std::string cdm_file_system_id;
@@ -311,7 +307,9 @@ media::mojom::InterfaceFactory* MediaInterfaceProxy::ConnectToCdmService(
DVLOG(1) << __func__ << ": cdm_guid = " << cdm_guid;
DCHECK(!cdm_interface_factory_map_.count(cdm_guid));
- service_manager::Identity identity(media::mojom::kCdmServiceName, cdm_guid);
+ service_manager::Identity identity(media::mojom::kCdmServiceName,
+ service_manager::mojom::kInheritUserID,
+ cdm_guid);
// TODO(slan): Use the BrowserContext Connector instead. See crbug.com/638950.
service_manager::Connector* connector =
diff --git a/chromium/content/browser/media/media_internals.cc b/chromium/content/browser/media/media_internals.cc
index 8f146027e2f..a8b7afa60ec 100644
--- a/chromium/content/browser/media/media_internals.cc
+++ b/chromium/content/browser/media/media_internals.cc
@@ -385,7 +385,7 @@ void MediaInternals::MediaInternalsUMAHandler::SavePlayerState(
break;
}
case media::MediaLogEvent::PIPELINE_ERROR: {
- int status;
+ int status = static_cast<media::PipelineStatus>(media::PIPELINE_OK);
event.params.GetInteger("pipeline_error", &status);
player_info.last_pipeline_status =
static_cast<media::PipelineStatus>(status);
@@ -689,7 +689,7 @@ void MediaInternals::UpdateVideoCaptureDeviceCapabilities(
video_capture_capabilities_cached_data_.Clear();
for (const auto& device_format_pair : descriptors_and_formats) {
- auto format_list = base::MakeUnique<base::ListValue>();
+ auto format_list = std::make_unique<base::ListValue>();
// TODO(nisse): Representing format information as a string, to be
// parsed by the javascript handler, is brittle. Consider passing
// a list of mappings instead.
@@ -788,12 +788,12 @@ void MediaInternals::UpdateAudioLog(AudioLogUpdateType type,
} else if (!has_entry) {
DCHECK_EQ(type, CREATE);
audio_streams_cached_data_.Set(
- cache_key, base::MakeUnique<base::Value>(value->Clone()));
+ cache_key, std::make_unique<base::Value>(value->Clone()));
} else if (type == UPDATE_AND_DELETE) {
std::unique_ptr<base::Value> out_value;
CHECK(audio_streams_cached_data_.Remove(cache_key, &out_value));
} else {
- base::DictionaryValue* existing_dict = NULL;
+ base::DictionaryValue* existing_dict = nullptr;
CHECK(
audio_streams_cached_data_.GetDictionary(cache_key, &existing_dict));
existing_dict->MergeDictionary(value);
diff --git a/chromium/content/browser/media/media_internals_ui.cc b/chromium/content/browser/media/media_internals_ui.cc
index 6e9665a04b3..c31ba5b24f6 100644
--- a/chromium/content/browser/media/media_internals_ui.cc
+++ b/chromium/content/browser/media/media_internals_ui.cc
@@ -39,7 +39,7 @@ WebUIDataSource* CreateMediaInternalsHTMLSource() {
MediaInternalsUI::MediaInternalsUI(WebUI* web_ui)
: WebUIController(web_ui) {
- web_ui->AddMessageHandler(base::MakeUnique<MediaInternalsMessageHandler>());
+ web_ui->AddMessageHandler(std::make_unique<MediaInternalsMessageHandler>());
BrowserContext* browser_context =
web_ui->GetWebContents()->GetBrowserContext();
diff --git a/chromium/content/browser/media/media_internals_unittest.cc b/chromium/content/browser/media/media_internals_unittest.cc
index e355c4b2bce..0e64d39a7bb 100644
--- a/chromium/content/browser/media/media_internals_unittest.cc
+++ b/chromium/content/browser/media/media_internals_unittest.cc
@@ -51,7 +51,7 @@ class MediaInternalsTestBase {
utf8_update.substr(first_brace, last_brace - first_brace + 1));
CHECK(output_value);
- base::DictionaryValue* output_dict = NULL;
+ base::DictionaryValue* output_dict = nullptr;
CHECK(output_value->GetAsDictionary(&output_dict));
update_data_.MergeDictionary(output_dict);
}
diff --git a/chromium/content/browser/media/media_redirect_browsertest.cc b/chromium/content/browser/media/media_redirect_browsertest.cc
index 93b1ce46276..8be45ca6a53 100644
--- a/chromium/content/browser/media/media_redirect_browsertest.cc
+++ b/chromium/content/browser/media/media_redirect_browsertest.cc
@@ -34,7 +34,7 @@ class MediaRedirectTest : public MediaBrowserTest {
http_test_server->StartAcceptingConnections();
// Run the normal media playback test.
- EXPECT_EQ(kEnded, RunTest(player_url, kEnded));
+ EXPECT_EQ(media::kEnded, RunTest(player_url, media::kEnded));
}
std::unique_ptr<net::test_server::HttpResponse> RedirectResponseHandler(
diff --git a/chromium/content/browser/media/media_source_browsertest.cc b/chromium/content/browser/media/media_source_browsertest.cc
index 51e62475668..9a63f9423e4 100644
--- a/chromium/content/browser/media/media_source_browsertest.cc
+++ b/chromium/content/browser/media/media_source_browsertest.cc
@@ -7,6 +7,7 @@
#include "build/build_config.h"
#include "content/browser/media/media_browsertest.h"
#include "media/base/media_switches.h"
+#include "media/base/test_data_util.h"
#include "media/media_features.h"
#if defined(OS_ANDROID)
@@ -56,11 +57,12 @@ class MediaSourceTest : public content::MediaBrowserTest {
};
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_VideoAudio_WebM) {
- TestSimplePlayback("bear-320x240.webm", kWebMAudioVideo, kEnded);
+ TestSimplePlayback("bear-320x240.webm", kWebMAudioVideo, media::kEnded);
}
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_VideoOnly_WebM) {
- TestSimplePlayback("bear-320x240-video-only.webm", kWebMVideoOnly, kEnded);
+ TestSimplePlayback("bear-320x240-video-only.webm", kWebMVideoOnly,
+ media::kEnded);
}
// TODO(servolk): Android is supposed to support AAC in ADTS container with
@@ -68,30 +70,32 @@ IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_VideoOnly_WebM) {
// some issue in OMX AAC decoder (crbug.com/528361)
#if BUILDFLAG(USE_PROPRIETARY_CODECS) && !defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_AudioOnly_AAC_ADTS) {
- TestSimplePlayback("sfx.adts", kAAC_ADTS_AudioOnly, kEnded);
+ TestSimplePlayback("sfx.adts", kAAC_ADTS_AudioOnly, media::kEnded);
}
#endif
// Opus is not supported in Android as of now.
#if !defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_AudioOnly_Opus_WebM) {
- TestSimplePlayback("bear-opus.webm", kWebMOpusAudioOnly, kEnded);
+ TestSimplePlayback("bear-opus.webm", kWebMOpusAudioOnly, media::kEnded);
}
#endif
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_AudioOnly_WebM) {
- TestSimplePlayback("bear-320x240-audio-only.webm", kWebMAudioOnly, kEnded);
+ TestSimplePlayback("bear-320x240-audio-only.webm", kWebMAudioOnly,
+ media::kEnded);
}
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Type_Error) {
TestSimplePlayback("bear-320x240-video-only.webm", kWebMAudioOnly,
- kErrorEvent);
+ media::kErrorEvent);
}
// Flaky test crbug.com/246308
// Test changed to skip checks resulting in flakiness. Proper fix still needed.
IN_PROC_BROWSER_TEST_F(MediaSourceTest, ConfigChangeVideo) {
- RunMediaTestPage("mse_config_change.html", base::StringPairs(), kEnded, true);
+ RunMediaTestPage("mse_config_change.html", base::StringPairs(), media::kEnded,
+ true);
}
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
@@ -102,7 +106,8 @@ IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Video_MP4_Audio_WEBM) {
base::StringPairs query_params;
query_params.push_back(std::make_pair("videoFormat", "CLEAR_MP4"));
query_params.push_back(std::make_pair("audioFormat", "CLEAR_WEBM"));
- RunMediaTestPage("mse_different_containers.html", query_params, kEnded, true);
+ RunMediaTestPage("mse_different_containers.html", query_params, media::kEnded,
+ true);
}
#endif // !defined(OS_ANDROID)
@@ -110,20 +115,21 @@ IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Video_WEBM_Audio_MP4) {
base::StringPairs query_params;
query_params.push_back(std::make_pair("videoFormat", "CLEAR_WEBM"));
query_params.push_back(std::make_pair("audioFormat", "CLEAR_MP4"));
- RunMediaTestPage("mse_different_containers.html", query_params, kEnded, true);
+ RunMediaTestPage("mse_different_containers.html", query_params, media::kEnded,
+ true);
}
IN_PROC_BROWSER_TEST_F(MediaSourceTest,
Playback_AudioOnly_FLAC_MP4_Unsupported) {
// The feature is disabled by test setup, so verify playback failure.
- TestSimplePlayback("bear-flac_frag.mp4", kMp4FlacAudioOnly, kFailed);
+ TestSimplePlayback("bear-flac_frag.mp4", kMp4FlacAudioOnly, media::kFailed);
}
#endif
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_AudioVideo_Mp2t) {
- TestSimplePlayback("bear-1280x720.ts", kMp2tAudioVideo, kEnded);
+ TestSimplePlayback("bear-1280x720.ts", kMp2tAudioVideo, media::kEnded);
}
#endif
#endif
@@ -142,7 +148,7 @@ class MediaSourceFlacInIsobmffTest : public content::MediaSourceTest {
IN_PROC_BROWSER_TEST_F(MediaSourceFlacInIsobmffTest,
Playback_AudioOnly_FLAC_MP4_Supported) {
// The feature is enabled by test setup, so verify playback success.
- TestSimplePlayback("bear-flac_frag.mp4", kMp4FlacAudioOnly, kEnded);
+ TestSimplePlayback("bear-flac_frag.mp4", kMp4FlacAudioOnly, media::kEnded);
}
#endif
diff --git a/chromium/content/browser/media/media_web_contents_observer.cc b/chromium/content/browser/media/media_web_contents_observer.cc
index 90e38f98a26..ef4144de854 100644
--- a/chromium/content/browser/media/media_web_contents_observer.cc
+++ b/chromium/content/browser/media/media_web_contents_observer.cc
@@ -167,7 +167,10 @@ void MediaWebContentsObserver::OnMediaPaused(RenderFrameHost* render_frame_host,
// Notify observers the player has been "paused".
web_contents_impl()->MediaStoppedPlaying(
WebContentsObserver::MediaPlayerInfo(removed_video, removed_audio),
- player_id);
+ player_id,
+ reached_end_of_stream
+ ? WebContentsObserver::MediaStoppedReason::kReachedEndOfStream
+ : WebContentsObserver::MediaStoppedReason::kUnspecified);
}
if (reached_end_of_stream)
@@ -259,7 +262,8 @@ void MediaWebContentsObserver::ClearWakeLocks(
bool was_video = (it != video_players.end());
bool was_audio = (audio_players.find(id) != audio_players.end());
web_contents_impl()->MediaStoppedPlaying(
- WebContentsObserver::MediaPlayerInfo(was_video, was_audio), id);
+ WebContentsObserver::MediaPlayerInfo(was_video, was_audio), id,
+ WebContentsObserver::MediaStoppedReason::kUnspecified);
}
}
@@ -272,8 +276,8 @@ device::mojom::WakeLock* MediaWebContentsObserver::GetAudioWakeLock() {
web_contents()->GetWakeLockContext();
if (wake_lock_context) {
wake_lock_context->GetWakeLock(
- device::mojom::WakeLockType::PreventAppSuspension,
- device::mojom::WakeLockReason::ReasonAudioPlayback, "Playing audio",
+ device::mojom::WakeLockType::kPreventAppSuspension,
+ device::mojom::WakeLockReason::kAudioPlayback, "Playing audio",
std::move(request));
}
}
@@ -289,8 +293,8 @@ device::mojom::WakeLock* MediaWebContentsObserver::GetVideoWakeLock() {
web_contents()->GetWakeLockContext();
if (wake_lock_context) {
wake_lock_context->GetWakeLock(
- device::mojom::WakeLockType::PreventDisplaySleep,
- device::mojom::WakeLockReason::ReasonVideoPlayback, "Playing video",
+ device::mojom::WakeLockType::kPreventDisplaySleep,
+ device::mojom::WakeLockReason::kVideoPlayback, "Playing video",
std::move(request));
}
}
diff --git a/chromium/content/browser/media/midi_host.cc b/chromium/content/browser/media/midi_host.cc
index 85e9f838aa7..5e65574d254 100644
--- a/chromium/content/browser/media/midi_host.cc
+++ b/chromium/content/browser/media/midi_host.cc
@@ -182,7 +182,7 @@ void MidiHost::ReceiveMidiData(uint32_t port,
// Lazy initialization
if (received_messages_queues_[port] == nullptr)
received_messages_queues_[port] =
- base::MakeUnique<midi::MidiMessageQueue>(true);
+ std::make_unique<midi::MidiMessageQueue>(true);
received_messages_queues_[port]->Add(data, length);
std::vector<uint8_t> message;
diff --git a/chromium/content/browser/media/session/OWNERS b/chromium/content/browser/media/session/OWNERS
index 7b427c56e8c..3cc0d9d80cc 100644
--- a/chromium/content/browser/media/session/OWNERS
+++ b/chromium/content/browser/media/session/OWNERS
@@ -1,4 +1,3 @@
-avayvod@chromium.org
mlamouri@chromium.org
# TEAM: media-dev@chromium.org
diff --git a/chromium/content/browser/media/session/audio_focus_manager_unittest.cc b/chromium/content/browser/media/session/audio_focus_manager_unittest.cc
index aa89b544e1c..46d2c1ce196 100644
--- a/chromium/content/browser/media/session/audio_focus_manager_unittest.cc
+++ b/chromium/content/browser/media/session/audio_focus_manager_unittest.cc
@@ -23,6 +23,8 @@ 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; }
diff --git a/chromium/content/browser/media/session/media_session_android.cc b/chromium/content/browser/media/session/media_session_android.cc
index 48f3e1f5e68..b9733ddb545 100644
--- a/chromium/content/browser/media/session/media_session_android.cc
+++ b/chromium/content/browser/media/session/media_session_android.cc
@@ -5,6 +5,7 @@
#include "content/browser/media/session/media_session_android.h"
#include "base/android/jni_array.h"
+#include "base/time/time.h"
#include "content/browser/media/session/media_session_impl.h"
#include "content/browser/web_contents/web_contents_android.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -39,7 +40,7 @@ MediaSessionAndroid::MediaSessionAndroid(MediaSessionImpl* session)
MediaSessionAndroid::~MediaSessionAndroid() = default;
// static
-ScopedJavaLocalRef<jobject> GetMediaSessionFromWebContents(
+ScopedJavaLocalRef<jobject> JNI_MediaSessionImpl_GetMediaSessionFromWebContents(
JNIEnv* env,
const JavaParamRef<jclass>& clazz,
const JavaParamRef<jobject>& j_contents_android) {
@@ -134,6 +135,26 @@ void MediaSessionAndroid::Stop(
media_session()->Stop(MediaSession::SuspendType::UI);
}
+void MediaSessionAndroid::SeekForward(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& j_obj,
+ const jlong millis) {
+ DCHECK(media_session());
+ DCHECK_GE(millis, 0)
+ << "Attempted to seek by a negative number of milliseconds";
+ media_session()->SeekForward(base::TimeDelta::FromMilliseconds(millis));
+}
+
+void MediaSessionAndroid::SeekBackward(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& j_obj,
+ const jlong millis) {
+ DCHECK(media_session());
+ DCHECK_GE(millis, 0)
+ << "Attempted to seek by a negative number of milliseconds";
+ media_session()->SeekBackward(base::TimeDelta::FromMilliseconds(millis));
+}
+
void MediaSessionAndroid::DidReceiveAction(JNIEnv* env,
const JavaParamRef<jobject>& obj,
int action) {
diff --git a/chromium/content/browser/media/session/media_session_android.h b/chromium/content/browser/media/session/media_session_android.h
index 614f4509505..3d3ea8ea58d 100644
--- a/chromium/content/browser/media/session/media_session_android.h
+++ b/chromium/content/browser/media/session/media_session_android.h
@@ -44,6 +44,12 @@ class MediaSessionAndroid final : public MediaSessionObserver {
void Resume(JNIEnv* env, const base::android::JavaParamRef<jobject>& j_obj);
void Suspend(JNIEnv* env, const base::android::JavaParamRef<jobject>& j_obj);
void Stop(JNIEnv* env, const base::android::JavaParamRef<jobject>& j_obj);
+ void SeekForward(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& j_obj,
+ const jlong millis);
+ void SeekBackward(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& j_obj,
+ const jlong millis);
void DidReceiveAction(JNIEnv* env,
const base::android::JavaParamRef<jobject>& j_obj,
jint action);
diff --git a/chromium/content/browser/media/session/media_session_browsertest.cc b/chromium/content/browser/media/session/media_session_browsertest.cc
index 0339ba0cc8b..1ffa6945855 100644
--- a/chromium/content/browser/media/session/media_session_browsertest.cc
+++ b/chromium/content/browser/media/session/media_session_browsertest.cc
@@ -89,8 +89,10 @@ class MediaSessionBrowserTest : public ContentBrowserTest {
run_loop_.Quit();
}
- void MediaStoppedPlaying(const MediaPlayerInfo& info,
- const MediaPlayerId& id) override {
+ void MediaStoppedPlaying(
+ const MediaPlayerInfo& info,
+ const MediaPlayerId& id,
+ WebContentsObserver::MediaStoppedReason reason) override {
if (type_ != Type::kStop)
return;
diff --git a/chromium/content/browser/media/session/media_session_controller.cc b/chromium/content/browser/media/session/media_session_controller.cc
index b9334dcda08..3a59f89f0a0 100644
--- a/chromium/content/browser/media/session/media_session_controller.cc
+++ b/chromium/content/browser/media/session/media_session_controller.cc
@@ -87,6 +87,20 @@ void MediaSessionController::OnResume(int player_id) {
new MediaPlayerDelegateMsg_Play(id_.first->GetRoutingID(), id_.second));
}
+void MediaSessionController::OnSeekForward(int player_id,
+ base::TimeDelta seek_time) {
+ DCHECK_EQ(player_id_, player_id);
+ id_.first->Send(new MediaPlayerDelegateMsg_SeekForward(
+ id_.first->GetRoutingID(), id_.second, seek_time));
+}
+
+void MediaSessionController::OnSeekBackward(int player_id,
+ base::TimeDelta seek_time) {
+ DCHECK_EQ(player_id_, player_id);
+ id_.first->Send(new MediaPlayerDelegateMsg_SeekBackward(
+ id_.first->GetRoutingID(), id_.second, seek_time));
+}
+
void MediaSessionController::OnSetVolumeMultiplier(int player_id,
double volume_multiplier) {
DCHECK_EQ(player_id_, player_id);
diff --git a/chromium/content/browser/media/session/media_session_controller.h b/chromium/content/browser/media/session/media_session_controller.h
index 5a35b25fd4b..ca3a8874a78 100644
--- a/chromium/content/browser/media/session/media_session_controller.h
+++ b/chromium/content/browser/media/session/media_session_controller.h
@@ -49,6 +49,8 @@ class CONTENT_EXPORT MediaSessionController
// MediaSessionObserver implementation.
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;
diff --git a/chromium/content/browser/media/session/media_session_controller_unittest.cc b/chromium/content/browser/media/session/media_session_controller_unittest.cc
index b4c4f8c2a09..96fd8a37b00 100644
--- a/chromium/content/browser/media/session/media_session_controller_unittest.cc
+++ b/chromium/content/browser/media/session/media_session_controller_unittest.cc
@@ -49,6 +49,16 @@ class MediaSessionControllerTest : public RenderViewHostImplTestHarness {
controller_->OnResume(controller_->get_player_id_for_testing());
}
+ void SeekForward(base::TimeDelta seek_time) {
+ controller_->OnSeekForward(controller_->get_player_id_for_testing(),
+ seek_time);
+ }
+
+ void SeekBackward(base::TimeDelta seek_time) {
+ controller_->OnSeekBackward(controller_->get_player_id_for_testing(),
+ seek_time);
+ }
+
void SetVolumeMultiplier(double multiplier) {
controller_->OnSetVolumeMultiplier(controller_->get_player_id_for_testing(),
multiplier);
@@ -70,6 +80,25 @@ class MediaSessionControllerTest : public RenderViewHostImplTestHarness {
}
template <typename T>
+ bool ReceivedMessageSeek(base::TimeDelta expected_seek_time) {
+ const IPC::Message* msg = test_sink().GetUniqueMessageMatching(T::ID);
+ if (!msg)
+ return false;
+
+ std::tuple<int, base::TimeDelta> result;
+ if (!T::Read(msg, &result))
+ return false;
+
+ EXPECT_EQ(id_.second, std::get<0>(result));
+ if (id_.second != std::get<0>(result))
+ return false;
+
+ EXPECT_EQ(expected_seek_time, std::get<1>(result));
+ test_sink().ClearMessages();
+ return expected_seek_time == std::get<1>(result);
+ }
+
+ template <typename T>
bool ReceivedMessageVolumeMultiplierUpdate(double expected_multiplier) {
const IPC::Message* msg = test_sink().GetUniqueMessageMatching(T::ID);
if (!msg)
@@ -127,6 +156,16 @@ TEST_F(MediaSessionControllerTest, BasicControls) {
Resume();
EXPECT_TRUE(ReceivedMessagePlayPause<MediaPlayerDelegateMsg_Play>());
+ // ...as well as the seek behavior.
+ const base::TimeDelta kTestSeekForwardTime = base::TimeDelta::FromSeconds(1);
+ SeekForward(kTestSeekForwardTime);
+ EXPECT_TRUE(ReceivedMessageSeek<MediaPlayerDelegateMsg_SeekForward>(
+ kTestSeekForwardTime));
+ const base::TimeDelta kTestSeekBackwardTime = base::TimeDelta::FromSeconds(2);
+ SeekBackward(kTestSeekBackwardTime);
+ EXPECT_TRUE(ReceivedMessageSeek<MediaPlayerDelegateMsg_SeekBackward>(
+ kTestSeekBackwardTime));
+
// Verify destruction of the controller removes its session.
controller_.reset();
EXPECT_FALSE(media_session()->IsActive());
diff --git a/chromium/content/browser/media/session/media_session_impl.cc b/chromium/content/browser/media/session/media_session_impl.cc
index 5a2642d43ba..107932af73d 100644
--- a/chromium/content/browser/media/session/media_session_impl.cc
+++ b/chromium/content/browser/media/session/media_session_impl.cc
@@ -395,6 +395,16 @@ void MediaSessionImpl::Stop(SuspendType suspend_type) {
AbandonSystemAudioFocusIfNeeded();
}
+void MediaSessionImpl::SeekForward(base::TimeDelta seek_time) {
+ for (const auto& it : normal_players_)
+ it.observer->OnSeekForward(it.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);
+}
+
bool MediaSessionImpl::IsControllable() const {
// Only media session having focus Gain can be controllable unless it is
// inactive. Also, the session will be uncontrollable if it contains one-shot
@@ -576,6 +586,7 @@ void MediaSessionImpl::AbandonSystemAudioFocusIfNeeded() {
return;
}
delegate_->AbandonAudioFocus();
+ is_ducking_ = false;
SetAudioFocusState(State::INACTIVE);
NotifyAboutStateChange();
diff --git a/chromium/content/browser/media/session/media_session_impl.h b/chromium/content/browser/media/session/media_session_impl.h
index 407adfea5c8..0bcdca3c3f8 100644
--- a/chromium/content/browser/media/session/media_session_impl.h
+++ b/chromium/content/browser/media/session/media_session_impl.h
@@ -127,6 +127,12 @@ class MediaSessionImpl : public MediaSession,
// |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;
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 37827e1c369..7ffbda7158d 100644
--- a/chromium/content/browser/media/session/media_session_impl_browsertest.cc
+++ b/chromium/content/browser/media/session/media_session_impl_browsertest.cc
@@ -141,6 +141,14 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
: MediaSessionImpl::State::INACTIVE);
}
+ void UISeekForward() {
+ media_session_->SeekForward(base::TimeDelta::FromSeconds(1));
+ }
+
+ void UISeekBackward() {
+ media_session_->SeekBackward(base::TimeDelta::FromSeconds(1));
+ }
+
void SystemStartDucking() { media_session_->StartDucking(); }
void SystemStopDucking() { media_session_->StopDucking(); }
@@ -182,7 +190,7 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
PlayersFromSameObserverDoNotStopEachOtherInSameSession) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -195,9 +203,9 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
PlayersFromManyObserverDoNotStopEachOtherInSameSession) {
- auto player_observer_1 = base::MakeUnique<MockMediaSessionPlayerObserver>();
- auto player_observer_2 = base::MakeUnique<MockMediaSessionPlayerObserver>();
- auto player_observer_3 = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer_1 = std::make_unique<MockMediaSessionPlayerObserver>();
+ auto player_observer_2 = std::make_unique<MockMediaSessionPlayerObserver>();
+ auto player_observer_3 = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer_1.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer_2.get(), media::MediaContentType::Persistent);
@@ -210,7 +218,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
SuspendedMediaSessionStopsPlayers) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -225,7 +233,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
ResumedMediaSessionRestartsPlayers) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -241,7 +249,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
StartedPlayerOnSuspendedSessionPlaysAlone) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -264,7 +272,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, InitialVolumeMultiplier) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -275,7 +283,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, InitialVolumeMultiplier) {
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
StartDuckingReducesVolumeMultiplier) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -291,7 +299,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
StopDuckingRecoversVolumeMultiplier) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -311,7 +319,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, AudioFocusInitialState) {
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, StartPlayerGivesFocus) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -320,7 +328,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, StartPlayerGivesFocus) {
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
SuspendGivesAwayAudioFocus) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -330,7 +338,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, StopGivesAwayAudioFocus) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -340,7 +348,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, StopGivesAwayAudioFocus) {
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumeGivesBackAudioFocus) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -352,7 +360,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumeGivesBackAudioFocus) {
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
RemovingLastPlayerDropsAudioFocus) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -368,9 +376,9 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
RemovingLastPlayerFromManyObserversDropsAudioFocus) {
- auto player_observer_1 = base::MakeUnique<MockMediaSessionPlayerObserver>();
- auto player_observer_2 = base::MakeUnique<MockMediaSessionPlayerObserver>();
- auto player_observer_3 = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer_1 = std::make_unique<MockMediaSessionPlayerObserver>();
+ auto player_observer_2 = std::make_unique<MockMediaSessionPlayerObserver>();
+ auto player_observer_3 = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer_1.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer_2.get(), media::MediaContentType::Persistent);
@@ -386,8 +394,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
RemovingAllPlayersFromObserversDropsAudioFocus) {
- auto player_observer_1 = base::MakeUnique<MockMediaSessionPlayerObserver>();
- auto player_observer_2 = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer_1 = std::make_unique<MockMediaSessionPlayerObserver>();
+ auto player_observer_2 = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer_1.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer_1.get(), media::MediaContentType::Persistent);
@@ -401,7 +409,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumePlayGivesAudioFocus) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -414,8 +422,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumePlayGivesAudioFocus) {
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
- ResumeSuspendAreSentOnlyOncePerPlayers) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ ResumeSuspendSeekAreSentOnlyOncePerPlayers) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -423,17 +431,25 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
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());
SystemSuspend(true);
EXPECT_EQ(3, player_observer->received_suspend_calls());
SystemResume();
EXPECT_EQ(3, player_observer->received_resume_calls());
+
+ UISeekForward();
+ EXPECT_EQ(3, player_observer->received_seek_forward_calls());
+
+ UISeekBackward();
+ EXPECT_EQ(3, player_observer->received_seek_backward_calls());
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
- ResumeSuspendAreSentOnlyOncePerPlayersAddedTwice) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ ResumeSuspendSeekAreSentOnlyOncePerPlayersAddedTwice) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -449,17 +465,25 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
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());
SystemSuspend(true);
EXPECT_EQ(3, player_observer->received_suspend_calls());
SystemResume();
EXPECT_EQ(3, player_observer->received_resume_calls());
+
+ UISeekForward();
+ EXPECT_EQ(3, player_observer->received_seek_forward_calls());
+
+ UISeekBackward();
+ EXPECT_EQ(3, player_observer->received_seek_backward_calls());
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
RemovingTheSamePlayerTwiceIsANoop) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -468,7 +492,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, AudioFocusType) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ 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);
@@ -520,7 +544,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ControlsShowForContent) {
EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
// Starting a player with a content type should show the media controls.
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -534,7 +558,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(false, false));
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
// Starting a player with a transient type should not show the media controls.
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
@@ -550,7 +574,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ControlsHideWhenStopped) {
MediaSessionStateChanged(false, true))
.After(showControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -565,7 +589,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -584,7 +608,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(true, false))
.After(dontShowControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
@@ -600,7 +624,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
@@ -621,7 +645,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(false, true))
.After(showControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -645,7 +669,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(false, true))
.After(showControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -664,7 +688,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(true, true))
.After(showControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -688,7 +712,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(true, true))
.After(showControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -709,7 +733,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(true, false))
.After(pauseControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
SystemSuspend(true);
@@ -727,7 +751,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(false, true))
.After(showControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -748,7 +772,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(false, true))
.After(pauseControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -769,7 +793,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(false, false))
.After(pauseControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
SystemSuspend(true);
@@ -793,7 +817,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(true, false))
.After(pauseControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
SystemSuspend(true);
@@ -816,7 +840,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(true, false))
.After(pauseControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
SystemSuspend(true);
@@ -836,7 +860,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(true, true))
.After(showControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
UISuspend();
@@ -856,7 +880,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(true, false))
.After(pauseControls);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
UISuspend();
@@ -871,7 +895,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(false, false));
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
@@ -898,7 +922,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
.Times(0)
.After(expect_2);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
RemovePlayer(player_observer.get(), 0);
@@ -916,7 +940,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionStateChanged(true, false))
.After(uncontrollable);
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
@@ -930,7 +954,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
DontSuspendWhenOneShotIsPresent) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
@@ -946,7 +970,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
DontResumeBySystemUISuspendedSessions) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -961,7 +985,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
AllowUIResumeForSystemSuspend) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -975,7 +999,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumeSuspendFromUI) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -989,7 +1013,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumeSuspendFromUI) {
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumeSuspendFromSystem) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -1003,7 +1027,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumeSuspendFromSystem) {
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, OneShotTakesGainFocus) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
EXPECT_CALL(
*mock_audio_focus_delegate(),
@@ -1019,7 +1043,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, OneShotTakesGainFocus) {
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, RemovingOneShotDropsFocus) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
EXPECT_CALL(*mock_audio_focus_delegate(), AbandonAudioFocus());
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
@@ -1028,7 +1052,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, RemovingOneShotDropsFocus) {
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
RemovingOneShotWhileStillHavingOtherPlayersKeepsFocus) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
EXPECT_CALL(*mock_audio_focus_delegate(), AbandonAudioFocus())
.Times(1); // Called in TearDown
@@ -1040,7 +1064,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
ActualPlaybackStateWhilePlayerPaused) {
EnsureMediaSessionService();
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>(
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
shell()->web_contents()->GetMainFrame());
::testing::Sequence s;
@@ -1074,7 +1098,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
ActualPlaybackStateWhilePlayerPlaying) {
EnsureMediaSessionService();
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>(
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
shell()->web_contents()->GetMainFrame());
::testing::Sequence s;
EXPECT_CALL(*mock_media_session_observer(),
@@ -1103,7 +1127,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
ActualPlaybackStateWhilePlayerRemoved) {
EnsureMediaSessionService();
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>(
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
shell()->web_contents()->GetMainFrame());
::testing::Sequence s;
@@ -1128,7 +1152,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
UMA_Suspended_SystemTransient) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -1144,7 +1168,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
UMA_Suspended_SystemPermantent) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -1159,7 +1183,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_UI) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
@@ -1175,7 +1199,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_UI) {
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Multiple) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -1200,7 +1224,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Multiple) {
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Crossing) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -1224,7 +1248,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Crossing) {
}
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Stop) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -1253,18 +1277,17 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
UMA_ActiveTime_SimpleActivation) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
- base::SimpleTestTickClock* clock = new base::SimpleTestTickClock();
- clock->SetNowTicks(base::TimeTicks::Now());
- media_session_uma_helper->SetClockForTest(
- std::unique_ptr<base::SimpleTestTickClock>(clock));
+ base::SimpleTestTickClock clock;
+ clock.SetNowTicks(base::TimeTicks::Now());
+ media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
- clock->Advance(base::TimeDelta::FromMilliseconds(1000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(1000));
media_session_->Stop(MediaSession::SuspendType::UI);
std::unique_ptr<base::HistogramSamples> samples(
@@ -1275,24 +1298,23 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
UMA_ActiveTime_ActivationWithUISuspension) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
- base::SimpleTestTickClock* clock = new base::SimpleTestTickClock();
- clock->SetNowTicks(base::TimeTicks::Now());
- media_session_uma_helper->SetClockForTest(
- std::unique_ptr<base::SimpleTestTickClock>(clock));
+ base::SimpleTestTickClock clock;
+ clock.SetNowTicks(base::TimeTicks::Now());
+ media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
- clock->Advance(base::TimeDelta::FromMilliseconds(1000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(1000));
UISuspend();
- clock->Advance(base::TimeDelta::FromMilliseconds(2000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(2000));
UIResume();
- clock->Advance(base::TimeDelta::FromMilliseconds(1000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(1000));
media_session_->Stop(MediaSession::SuspendType::UI);
std::unique_ptr<base::HistogramSamples> samples(
@@ -1303,24 +1325,23 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
UMA_ActiveTime_ActivationWithSystemSuspension) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
- base::SimpleTestTickClock* clock = new base::SimpleTestTickClock();
- clock->SetNowTicks(base::TimeTicks::Now());
- media_session_uma_helper->SetClockForTest(
- std::unique_ptr<base::SimpleTestTickClock>(clock));
+ base::SimpleTestTickClock clock;
+ clock.SetNowTicks(base::TimeTicks::Now());
+ media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
- clock->Advance(base::TimeDelta::FromMilliseconds(1000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(1000));
SystemSuspend(true);
- clock->Advance(base::TimeDelta::FromMilliseconds(2000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(2000));
SystemResume();
- clock->Advance(base::TimeDelta::FromMilliseconds(1000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(1000));
media_session_->Stop(MediaSession::SuspendType::UI);
std::unique_ptr<base::HistogramSamples> samples(
@@ -1331,17 +1352,16 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
UMA_ActiveTime_ActivateSuspendedButNotStopped) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
- base::SimpleTestTickClock* clock = new base::SimpleTestTickClock();
- clock->SetNowTicks(base::TimeTicks::Now());
- media_session_uma_helper->SetClockForTest(
- std::unique_ptr<base::SimpleTestTickClock>(clock));
+ base::SimpleTestTickClock clock;
+ clock.SetNowTicks(base::TimeTicks::Now());
+ media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
- clock->Advance(base::TimeDelta::FromMilliseconds(500));
+ clock.Advance(base::TimeDelta::FromMilliseconds(500));
SystemSuspend(true);
{
@@ -1351,7 +1371,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
}
SystemResume();
- clock->Advance(base::TimeDelta::FromMilliseconds(5000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(5000));
UISuspend();
{
@@ -1363,22 +1383,21 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
UMA_ActiveTime_ActivateSuspendStopTwice) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
- base::SimpleTestTickClock* clock = new base::SimpleTestTickClock();
- clock->SetNowTicks(base::TimeTicks::Now());
- media_session_uma_helper->SetClockForTest(
- std::unique_ptr<base::SimpleTestTickClock>(clock));
+ base::SimpleTestTickClock clock;
+ clock.SetNowTicks(base::TimeTicks::Now());
+ media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
- clock->Advance(base::TimeDelta::FromMilliseconds(500));
+ clock.Advance(base::TimeDelta::FromMilliseconds(500));
SystemSuspend(true);
media_session_->Stop(MediaSession::SuspendType::UI);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
- clock->Advance(base::TimeDelta::FromMilliseconds(5000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(5000));
SystemResume();
media_session_->Stop(MediaSession::SuspendType::UI);
@@ -1391,21 +1410,20 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
UMA_ActiveTime_MultipleActivations) {
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>();
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
- base::SimpleTestTickClock* clock = new base::SimpleTestTickClock();
- clock->SetNowTicks(base::TimeTicks::Now());
- media_session_uma_helper->SetClockForTest(
- std::unique_ptr<base::SimpleTestTickClock>(clock));
+ base::SimpleTestTickClock clock;
+ clock.SetNowTicks(base::TimeTicks::Now());
+ media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
- clock->Advance(base::TimeDelta::FromMilliseconds(10000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(10000));
RemovePlayer(player_observer.get(), 0);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
- clock->Advance(base::TimeDelta::FromMilliseconds(1000));
+ clock.Advance(base::TimeDelta::FromMilliseconds(1000));
media_session_->Stop(MediaSession::SuspendType::UI);
std::unique_ptr<base::HistogramSamples> samples(
@@ -1445,7 +1463,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
mock_media_session_service_->actions();
// Make sure the service is routed,
- auto player_observer = base::MakeUnique<MockMediaSessionPlayerObserver>(
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
shell()->web_contents()->GetMainFrame());
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
diff --git a/chromium/content/browser/media/session/media_session_impl_service_routing_unittest.cc b/chromium/content/browser/media/session/media_session_impl_service_routing_unittest.cc
index d928c9a22be..7933899da71 100644
--- a/chromium/content/browser/media/session/media_session_impl_service_routing_unittest.cc
+++ b/chromium/content/browser/media/session/media_session_impl_service_routing_unittest.cc
@@ -64,6 +64,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
MOCK_METHOD1(OnSuspend, void(int player_id));
MOCK_METHOD1(OnResume, void(int player_id));
+ MOCK_METHOD2(OnSeekForward, void(int player_id, base::TimeDelta seek_time));
+ MOCK_METHOD2(OnSeekBackward, void(int player_id, base::TimeDelta seek_time));
MOCK_METHOD2(OnSetVolumeMultiplier,
void(int player_id, double volume_multiplier));
@@ -108,8 +110,8 @@ class MediaSessionImplServiceRoutingTest
void CreateServiceForFrame(TestRenderFrameHost* frame) {
services_[frame] =
- base::MakeUnique<NiceMock<MockMediaSessionServiceImpl>>(frame);
- clients_[frame] = base::MakeUnique<NiceMock<MockMediaSessionClient>>();
+ std::make_unique<NiceMock<MockMediaSessionServiceImpl>>(frame);
+ clients_[frame] = std::make_unique<NiceMock<MockMediaSessionClient>>();
services_[frame]->SetClient(clients_[frame]->CreateInterfacePtrAndBind());
}
@@ -125,7 +127,7 @@ class MediaSessionImplServiceRoutingTest
void StartPlayerForFrame(TestRenderFrameHost* frame) {
players_[frame] =
- base::MakeUnique<NiceMock<MockMediaSessionPlayerObserver>>(frame);
+ std::make_unique<NiceMock<MockMediaSessionPlayerObserver>>(frame);
MediaSessionImpl::Get(contents())
->AddPlayer(players_[frame].get(), kPlayerId,
media::MediaContentType::Persistent);
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 523a52e2c7e..cf8d5d35ad2 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
@@ -34,6 +34,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
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 {
}
diff --git a/chromium/content/browser/media/session/media_session_impl_visibility_browsertest.cc b/chromium/content/browser/media/session/media_session_impl_visibility_browsertest.cc
index 95b22939bde..efe9d1c393a 100644
--- a/chromium/content/browser/media/session/media_session_impl_visibility_browsertest.cc
+++ b/chromium/content/browser/media/session/media_session_impl_visibility_browsertest.cc
@@ -63,7 +63,12 @@ class MediaSessionImplVisibilityBrowserTest
: public ContentBrowserTest,
public ::testing::WithParamInterface<VisibilityTestData> {
public:
- MediaSessionImplVisibilityBrowserTest() = default;
+ MediaSessionImplVisibilityBrowserTest() {
+ VisibilityTestData params = GetVisibilityTestData();
+ EnableDisableResumingBackgroundVideos(params.background_resuming ==
+ BackgroundResuming::ENABLED);
+ }
+
~MediaSessionImplVisibilityBrowserTest() override = default;
void SetUpOnMainThread() override {
@@ -109,14 +114,6 @@ class MediaSessionImplVisibilityBrowserTest
command_line->AppendSwitch(switches::kEnableMediaSuspend);
else
command_line->AppendSwitch(switches::kDisableMediaSuspend);
-
- if (params.background_resuming == BackgroundResuming::ENABLED) {
- command_line->AppendSwitchASCII(switches::kEnableFeatures,
- media::kResumeBackgroundVideo.name);
- } else {
- command_line->AppendSwitchASCII(switches::kDisableFeatures,
- media::kResumeBackgroundVideo.name);
- }
}
const VisibilityTestData& GetVisibilityTestData() {
@@ -225,6 +222,8 @@ class MediaSessionImplVisibilityBrowserTest
}
}
+ base::test::ScopedFeatureList scoped_feature_list_;
+
WebContents* web_contents_;
MediaSessionImpl* media_session_;
// MessageLoopRunners for waiting MediaSession state to change. Note that the
@@ -238,7 +237,6 @@ class MediaSessionImplVisibilityBrowserTest
std::unique_ptr<
base::CallbackList<void(MediaSessionImpl::State)>::Subscription>
media_session_state_callback_subscription_;
- base::test::ScopedFeatureList scoped_feature_list_;
DISALLOW_COPY_AND_ASSIGN(MediaSessionImplVisibilityBrowserTest);
};
diff --git a/chromium/content/browser/media/session/media_session_player_observer.h b/chromium/content/browser/media/session/media_session_player_observer.h
index 613da0191ff..93b62471ac6 100644
--- a/chromium/content/browser/media/session/media_session_player_observer.h
+++ b/chromium/content/browser/media/session/media_session_player_observer.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_MEDIA_SESSION_MEDIA_SESSION_PLAYER_OBSERVER_H_
#define CONTENT_BROWSER_MEDIA_SESSION_MEDIA_SESSION_PLAYER_OBSERVER_H_
+#include "base/time/time.h"
+
namespace content {
class RenderFrameHost;
@@ -20,6 +22,12 @@ class MediaSessionPlayerObserver {
// The given |player_id| has been resumed by the MediaSession.
virtual void OnResume(int player_id) = 0;
+ // The given |player_id| has been seeked forward by the MediaSession.
+ virtual void OnSeekForward(int player_id, base::TimeDelta seek_time) = 0;
+
+ // The given |player_id| has been seeked backward by the MediaSession.
+ virtual void OnSeekBackward(int player_id, base::TimeDelta seek_time) = 0;
+
// The given |player_id| has been set a new volume multiplier by
// the MediaSession.
virtual void OnSetVolumeMultiplier(int player_id,
diff --git a/chromium/content/browser/media/session/media_session_service_impl_browsertest.cc b/chromium/content/browser/media/session/media_session_service_impl_browsertest.cc
index 676dc1cdd27..2a11394e2b2 100644
--- a/chromium/content/browser/media/session/media_session_service_impl_browsertest.cc
+++ b/chromium/content/browser/media/session/media_session_service_impl_browsertest.cc
@@ -64,6 +64,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
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 {
}
diff --git a/chromium/content/browser/media/session/media_session_uma_helper.cc b/chromium/content/browser/media/session/media_session_uma_helper.cc
index d8f825b0c94..10073466529 100644
--- a/chromium/content/browser/media/session/media_session_uma_helper.cc
+++ b/chromium/content/browser/media/session/media_session_uma_helper.cc
@@ -15,8 +15,7 @@ namespace content {
using HistogramBase = base::HistogramBase;
MediaSessionUmaHelper::MediaSessionUmaHelper()
- : clock_(new base::DefaultTickClock())
-{}
+ : clock_(base::DefaultTickClock::GetInstance()) {}
MediaSessionUmaHelper::~MediaSessionUmaHelper()
{}
@@ -66,9 +65,8 @@ void MediaSessionUmaHelper::OnSessionInactive() {
total_active_time_ = base::TimeDelta();
}
-void MediaSessionUmaHelper::SetClockForTest(
- std::unique_ptr<base::TickClock> testing_clock) {
- clock_ = std::move(testing_clock);
+void MediaSessionUmaHelper::SetClockForTest(base::TickClock* testing_clock) {
+ clock_ = testing_clock;
}
} // namespace content
diff --git a/chromium/content/browser/media/session/media_session_uma_helper.h b/chromium/content/browser/media/session/media_session_uma_helper.h
index 78f8a30b314..bd928c3e016 100644
--- a/chromium/content/browser/media/session/media_session_uma_helper.h
+++ b/chromium/content/browser/media/session/media_session_uma_helper.h
@@ -58,12 +58,12 @@ class CONTENT_EXPORT MediaSessionUmaHelper {
void OnSessionSuspended();
void OnSessionInactive();
- void SetClockForTest(std::unique_ptr<base::TickClock> testing_clock);
+ void SetClockForTest(base::TickClock* testing_clock);
private:
base::TimeDelta total_active_time_;
base::TimeTicks current_active_time_;
- std::unique_ptr<base::TickClock> clock_;
+ base::TickClock* clock_;
};
} // namespace content
diff --git a/chromium/content/browser/media/session/media_session_uma_helper_unittest.cc b/chromium/content/browser/media/session/media_session_uma_helper_unittest.cc
index c0931d2f89d..4b6fc027436 100644
--- a/chromium/content/browser/media/session/media_session_uma_helper_unittest.cc
+++ b/chromium/content/browser/media/session/media_session_uma_helper_unittest.cc
@@ -21,17 +21,11 @@ class MediaSessionUmaHelperTest : public testing::Test {
MediaSessionUmaHelperTest() = default;
void SetUp() override {
- clock_ = new base::SimpleTestTickClock();
- clock_->SetNowTicks(base::TimeTicks::Now());
- media_session_uma_helper_.SetClockForTest(
- std::unique_ptr<base::SimpleTestTickClock>(clock_));
+ clock_.SetNowTicks(base::TimeTicks::Now());
+ media_session_uma_helper_.SetClockForTest(&clock_);
}
- void TearDown() override {
- clock_ = nullptr;
- }
-
- base::SimpleTestTickClock* clock() { return clock_; }
+ base::SimpleTestTickClock* clock() { return &clock_; }
MediaSessionUmaHelper& media_session_uma_helper() {
return media_session_uma_helper_;
@@ -43,7 +37,7 @@ class MediaSessionUmaHelperTest : public testing::Test {
}
private:
- base::SimpleTestTickClock* clock_ = nullptr;
+ base::SimpleTestTickClock clock_;
MediaSessionUmaHelper media_session_uma_helper_;
base::HistogramTester histogram_tester_;
};
diff --git a/chromium/content/browser/media/session/mock_media_session_observer.h b/chromium/content/browser/media/session/mock_media_session_observer.h
index 25db18dffb9..6421fa9b4e6 100644
--- a/chromium/content/browser/media/session/mock_media_session_observer.h
+++ b/chromium/content/browser/media/session/mock_media_session_observer.h
@@ -2,6 +2,9 @@
// 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_MOCK_MEDIA_SESSION_OBSERVER_H_
+#define CONTENT_BROWSER_MEDIA_SESSION_MOCK_MEDIA_SESSION_OBSERVER_H_
+
#include "content/public/browser/media_session_observer.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -21,3 +24,5 @@ class MockMediaSessionObserver : public MediaSessionObserver {
void(const std::set<blink::mojom::MediaSessionAction>& action));
};
}
+
+#endif // CONTENT_BROWSER_MEDIA_SESSION_MOCK_MEDIA_SESSION_OBSERVER_H_
diff --git a/chromium/content/browser/media/session/mock_media_session_player_observer.cc b/chromium/content/browser/media/session/mock_media_session_player_observer.cc
index 0de898a3591..8b6af939241 100644
--- a/chromium/content/browser/media/session/mock_media_session_player_observer.cc
+++ b/chromium/content/browser/media/session/mock_media_session_player_observer.cc
@@ -30,6 +30,20 @@ void MockMediaSessionPlayerObserver::OnResume(int player_id) {
players_[player_id].is_playing_ = true;
}
+void MockMediaSessionPlayerObserver::OnSeekForward(int player_id,
+ base::TimeDelta seek_time) {
+ EXPECT_GE(player_id, 0);
+ EXPECT_GT(players_.size(), static_cast<size_t>(player_id));
+ ++received_seek_forward_calls_;
+}
+
+void MockMediaSessionPlayerObserver::OnSeekBackward(int player_id,
+ base::TimeDelta seek_time) {
+ EXPECT_GE(player_id, 0);
+ EXPECT_GT(players_.size(), static_cast<size_t>(player_id));
+ ++received_seek_backward_calls_;
+}
+
void MockMediaSessionPlayerObserver::OnSetVolumeMultiplier(
int player_id,
double volume_multiplier) {
@@ -75,4 +89,12 @@ int MockMediaSessionPlayerObserver::received_resume_calls() const {
return received_resume_calls_;
}
+int MockMediaSessionPlayerObserver::received_seek_forward_calls() const {
+ return received_seek_forward_calls_;
+}
+
+int MockMediaSessionPlayerObserver::received_seek_backward_calls() const {
+ return received_seek_backward_calls_;
+}
+
} // namespace content
diff --git a/chromium/content/browser/media/session/mock_media_session_player_observer.h b/chromium/content/browser/media/session/mock_media_session_player_observer.h
index db2b3d73a0b..967672c51a6 100644
--- a/chromium/content/browser/media/session/mock_media_session_player_observer.h
+++ b/chromium/content/browser/media/session/mock_media_session_player_observer.h
@@ -2,9 +2,13 @@
// 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_MOCK_MEDIA_SESSION_PLAYER_OBSERVER_H_
+#define CONTENT_BROWSER_MEDIA_SESSION_MOCK_MEDIA_SESSION_PLAYER_OBSERVER_H_
+
#include <stddef.h>
#include <vector>
+#include "base/time/time.h"
#include "content/browser/media/session/media_session_player_observer.h"
namespace content {
@@ -20,6 +24,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
// Implements MediaSessionPlayerObserver.
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;
@@ -38,6 +44,8 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
int received_suspend_calls() const;
int received_resume_calls() const;
+ int received_seek_forward_calls() const;
+ int received_seek_backward_calls() const;
private:
// Internal representation of the players to keep track of their statuses.
@@ -57,6 +65,10 @@ class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
int received_resume_calls_ = 0;
int received_suspend_calls_ = 0;
+ int received_seek_forward_calls_ = 0;
+ int received_seek_backward_calls_ = 0;
};
} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_SESSION_MOCK_MEDIA_SESSION_PLAYER_OBSERVER_H_
diff --git a/chromium/content/browser/media/session/pepper_playback_observer.cc b/chromium/content/browser/media/session/pepper_playback_observer.cc
index a60ba99d14b..ab55c60796a 100644
--- a/chromium/content/browser/media/session/pepper_playback_observer.cc
+++ b/chromium/content/browser/media/session/pepper_playback_observer.cc
@@ -15,16 +15,6 @@
namespace content {
-namespace {
-
-bool ShouldDuckFlash() {
- return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kEnableAudioFocus) ==
- switches::kEnableAudioFocusDuckFlash;
-}
-
-} // anonymous namespace
-
PepperPlaybackObserver::PepperPlaybackObserver(WebContents* contents)
: contents_(contents) {}
@@ -85,8 +75,8 @@ void PepperPlaybackObserver::PepperStartsPlayback(
MediaSessionImpl::Get(contents_)->AddPlayer(
players_map_[id].get(), PepperPlayerDelegate::kPlayerId,
- ShouldDuckFlash() ? media::MediaContentType::Pepper
- : media::MediaContentType::OneShot);
+ media::IsAudioFocusDuckFlashEnabled() ? media::MediaContentType::Pepper
+ : media::MediaContentType::OneShot);
}
void PepperPlaybackObserver::PepperStopsPlayback(
diff --git a/chromium/content/browser/media/session/pepper_player_delegate.cc b/chromium/content/browser/media/session/pepper_player_delegate.cc
index 33f0aa55f6e..d3e23c458a5 100644
--- a/chromium/content/browser/media/session/pepper_player_delegate.cc
+++ b/chromium/content/browser/media/session/pepper_player_delegate.cc
@@ -16,12 +16,6 @@ namespace {
const double kDuckVolume = 0.2f;
-bool ShouldDuckFlash() {
- return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kEnableAudioFocus) ==
- switches::kEnableAudioFocusDuckFlash;
-}
-
} // anonymous namespace
const int PepperPlayerDelegate::kPlayerId = 0;
@@ -34,7 +28,7 @@ PepperPlayerDelegate::PepperPlayerDelegate(
PepperPlayerDelegate::~PepperPlayerDelegate() = default;
void PepperPlayerDelegate::OnSuspend(int player_id) {
- if (!ShouldDuckFlash())
+ if (!media::IsAudioFocusDuckFlashEnabled())
return;
// Pepper player cannot be really suspended. Duck the volume instead.
@@ -43,16 +37,26 @@ void PepperPlayerDelegate::OnSuspend(int player_id) {
}
void PepperPlayerDelegate::OnResume(int player_id) {
- if (!ShouldDuckFlash())
+ if (!media::IsAudioFocusDuckFlashEnabled())
return;
DCHECK_EQ(player_id, kPlayerId);
SetVolume(player_id, 1.0f);
}
+void PepperPlayerDelegate::OnSeekForward(int player_id,
+ base::TimeDelta seek_time) {
+ // Cannot seek pepper player. Do nothing.
+}
+
+void PepperPlayerDelegate::OnSeekBackward(int player_id,
+ base::TimeDelta seek_time) {
+ // Cannot seek pepper player. Do nothing.
+}
+
void PepperPlayerDelegate::OnSetVolumeMultiplier(int player_id,
double volume_multiplier) {
- if (!ShouldDuckFlash())
+ if (!media::IsAudioFocusDuckFlashEnabled())
return;
DCHECK_EQ(player_id, kPlayerId);
diff --git a/chromium/content/browser/media/session/pepper_player_delegate.h b/chromium/content/browser/media/session/pepper_player_delegate.h
index 78142f5e73d..5e48ca81fa6 100644
--- a/chromium/content/browser/media/session/pepper_player_delegate.h
+++ b/chromium/content/browser/media/session/pepper_player_delegate.h
@@ -26,6 +26,8 @@ class PepperPlayerDelegate : public MediaSessionPlayerObserver {
// MediaSessionPlayerObserver implementation.
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;
diff --git a/chromium/content/browser/media/url_provision_fetcher.cc b/chromium/content/browser/media/url_provision_fetcher.cc
index 935fe0a4e08..8cf4c2cec35 100644
--- a/chromium/content/browser/media/url_provision_fetcher.cc
+++ b/chromium/content/browser/media/url_provision_fetcher.cc
@@ -105,7 +105,7 @@ void URLProvisionFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
std::unique_ptr<media::ProvisionFetcher> CreateProvisionFetcher(
net::URLRequestContextGetter* context_getter) {
DCHECK(context_getter);
- return base::MakeUnique<URLProvisionFetcher>(context_getter);
+ return std::make_unique<URLProvisionFetcher>(context_getter);
}
} // namespace content
diff --git a/chromium/content/browser/memory/memory_coordinator_impl.cc b/chromium/content/browser/memory/memory_coordinator_impl.cc
index 347a3f02967..8c916774c9d 100644
--- a/chromium/content/browser/memory/memory_coordinator_impl.cc
+++ b/chromium/content/browser/memory/memory_coordinator_impl.cc
@@ -128,12 +128,12 @@ MemoryCoordinatorImpl::MemoryCoordinatorImpl(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
std::unique_ptr<MemoryMonitor> memory_monitor)
: task_runner_(task_runner),
- policy_(base::MakeUnique<MemoryCoordinatorDefaultPolicy>(this)),
+ policy_(std::make_unique<MemoryCoordinatorDefaultPolicy>(this)),
delegate_(GetContentClient()->browser()->GetMemoryCoordinatorDelegate()),
memory_monitor_(std::move(memory_monitor)),
condition_observer_(
- base::MakeUnique<MemoryConditionObserver>(this, task_runner)),
- tick_clock_(base::MakeUnique<base::DefaultTickClock>()),
+ std::make_unique<MemoryConditionObserver>(this, task_runner)),
+ tick_clock_(base::DefaultTickClock::GetInstance()),
minimum_state_transition_period_(base::TimeDelta::FromSeconds(
kDefaultMinimumTransitionPeriodSeconds)) {
DCHECK(memory_monitor_.get());
@@ -363,8 +363,8 @@ void MemoryCoordinatorImpl::AddChildForTesting(
}
void MemoryCoordinatorImpl::SetTickClockForTesting(
- std::unique_ptr<base::TickClock> tick_clock) {
- tick_clock_ = std::move(tick_clock);
+ base::TickClock* tick_clock) {
+ tick_clock_ = tick_clock;
}
void MemoryCoordinatorImpl::OnConnectionError(int render_process_id) {
diff --git a/chromium/content/browser/memory/memory_coordinator_impl.h b/chromium/content/browser/memory/memory_coordinator_impl.h
index cd3638f550f..8f42d98d386 100644
--- a/chromium/content/browser/memory/memory_coordinator_impl.h
+++ b/chromium/content/browser/memory/memory_coordinator_impl.h
@@ -169,7 +169,7 @@ class CONTENT_EXPORT MemoryCoordinatorImpl : public base::MemoryCoordinator,
mojom::ChildMemoryCoordinatorPtr child);
// Sets a TickClock for testing.
- void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
+ void SetTickClockForTesting(base::TickClock* tick_clock);
// Callback invoked by mojo when the child connection goes down. Exposed
// for testing.
@@ -207,7 +207,7 @@ class CONTENT_EXPORT MemoryCoordinatorImpl : public base::MemoryCoordinator,
std::unique_ptr<MemoryCoordinatorDelegate> delegate_;
std::unique_ptr<MemoryMonitor> memory_monitor_;
std::unique_ptr<MemoryConditionObserver> condition_observer_;
- std::unique_ptr<base::TickClock> tick_clock_;
+ base::TickClock* tick_clock_;
NotificationRegistrar notification_registrar_;
// The current memory condition.
diff --git a/chromium/content/browser/memory/memory_coordinator_impl_unittest.cc b/chromium/content/browser/memory/memory_coordinator_impl_unittest.cc
index f44c9fbf85b..2418018e57c 100644
--- a/chromium/content/browser/memory/memory_coordinator_impl_unittest.cc
+++ b/chromium/content/browser/memory/memory_coordinator_impl_unittest.cc
@@ -155,10 +155,12 @@ class TestMemoryCoordinatorImpl : public MemoryCoordinatorImpl {
TestMemoryCoordinatorImpl(
scoped_refptr<base::TestMockTimeTaskRunner> task_runner)
: MemoryCoordinatorImpl(task_runner,
- base::MakeUnique<MockMemoryMonitor>()) {
- SetDelegateForTesting(base::MakeUnique<TestMemoryCoordinatorDelegate>());
- SetPolicyForTesting(base::MakeUnique<MockMemoryCoordinatorPolicy>(this));
- SetTickClockForTesting(task_runner->GetMockTickClock());
+ std::make_unique<MockMemoryMonitor>()) {
+ SetDelegateForTesting(std::make_unique<TestMemoryCoordinatorDelegate>());
+ SetPolicyForTesting(std::make_unique<MockMemoryCoordinatorPolicy>(this));
+
+ clock_ = task_runner->GetMockTickClock();
+ SetTickClockForTesting(clock_.get());
}
~TestMemoryCoordinatorImpl() override {}
@@ -172,7 +174,7 @@ class TestMemoryCoordinatorImpl : public MemoryCoordinatorImpl {
children_.push_back(std::unique_ptr<Child>(new Child(&cmc_ptr)));
AddChildForTesting(process_id, std::move(cmc_ptr));
render_process_hosts_[process_id] =
- base::MakeUnique<MockRenderProcessHost>(&browser_context_);
+ std::make_unique<MockRenderProcessHost>(&browser_context_);
return &children_.back()->cmc;
}
@@ -204,6 +206,10 @@ class TestMemoryCoordinatorImpl : public MemoryCoordinatorImpl {
return result;
}
+ // TODO(tzik): Remove |clock_| after updating GetMockTickClock to own the
+ // instance.
+ std::unique_ptr<base::TickClock> clock_;
+
TestBrowserContext browser_context_;
std::vector<std::unique_ptr<Child>> children_;
std::map<int, std::unique_ptr<MockRenderProcessHost>> render_process_hosts_;
@@ -448,9 +454,9 @@ TEST_F(MemoryCoordinatorImplTest, MAYBE_GetStateForProcess) {
base::Process process1 = SpawnChild("process1");
base::Process process2 = SpawnChild("process2");
coordinator_->GetMockRenderProcessHost(1)->SetProcessHandle(
- base::MakeUnique<base::ProcessHandle>(process1.Handle()));
+ std::make_unique<base::ProcessHandle>(process1.Handle()));
coordinator_->GetMockRenderProcessHost(2)->SetProcessHandle(
- base::MakeUnique<base::ProcessHandle>(process2.Handle()));
+ std::make_unique<base::ProcessHandle>(process2.Handle()));
EXPECT_EQ(base::MemoryState::NORMAL,
coordinator_->GetStateForProcess(process1.Handle()));
diff --git a/chromium/content/browser/memory/memory_monitor_android.cc b/chromium/content/browser/memory/memory_monitor_android.cc
index 93a0e70e391..64ddf5ba53d 100644
--- a/chromium/content/browser/memory/memory_monitor_android.cc
+++ b/chromium/content/browser/memory/memory_monitor_android.cc
@@ -42,7 +42,7 @@ void MemoryMonitorAndroidDelegateImpl::GetMemoryInfo(MemoryInfo* out) {
}
// Called by JNI to populate ActivityManager.MemoryInfo.
-static void GetMemoryInfoCallback(
+static void JNI_MemoryMonitorAndroid_GetMemoryInfoCallback(
JNIEnv* env,
const base::android::JavaParamRef<jclass>& clazz,
jlong avail_mem,
@@ -64,9 +64,10 @@ const int kTrimMemoryLevelMax = 80;
const int kTrimMemoryRunningCritical = 15;
// Called by JNI.
-static void OnTrimMemory(JNIEnv* env,
- const base::android::JavaParamRef<jclass>& jcaller,
- jint level) {
+static void JNI_MemoryMonitorAndroid_OnTrimMemory(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jclass>& jcaller,
+ jint level) {
DCHECK(level >= 0 && level <= kTrimMemoryLevelMax);
auto* coordinator = MemoryCoordinatorImpl::GetInstance();
DCHECK(coordinator);
@@ -88,7 +89,7 @@ MemoryMonitorAndroid::MemoryMonitorAndroid(std::unique_ptr<Delegate> delegate)
DCHECK(delegate_.get());
RegisterComponentCallbacks();
application_state_listener_ =
- base::MakeUnique<base::android::ApplicationStatusListener>(
+ std::make_unique<base::android::ApplicationStatusListener>(
base::Bind(&MemoryMonitorAndroid::OnApplicationStateChange,
base::Unretained(this)));
}
diff --git a/chromium/content/browser/memory/memory_monitor_chromeos.cc b/chromium/content/browser/memory/memory_monitor_chromeos.cc
index 36d8ff87c9b..b0315ecebfe 100644
--- a/chromium/content/browser/memory/memory_monitor_chromeos.cc
+++ b/chromium/content/browser/memory/memory_monitor_chromeos.cc
@@ -44,7 +44,7 @@ int MemoryMonitorChromeOS::GetFreeMemoryUntilCriticalMB() {
// static
std::unique_ptr<MemoryMonitorChromeOS> MemoryMonitorChromeOS::Create(
MemoryMonitorDelegate* delegate) {
- return base::MakeUnique<MemoryMonitorChromeOS>(delegate);
+ return std::make_unique<MemoryMonitorChromeOS>(delegate);
}
// Implementation of factory function defined in memory_monitor.h.
diff --git a/chromium/content/browser/memory/memory_monitor_linux.cc b/chromium/content/browser/memory/memory_monitor_linux.cc
index 68421c8c4e1..2901e7f4371 100644
--- a/chromium/content/browser/memory/memory_monitor_linux.cc
+++ b/chromium/content/browser/memory/memory_monitor_linux.cc
@@ -43,7 +43,7 @@ int MemoryMonitorLinux::GetFreeMemoryUntilCriticalMB() {
// static
std::unique_ptr<MemoryMonitorLinux> MemoryMonitorLinux::Create(
MemoryMonitorDelegate* delegate) {
- return base::MakeUnique<MemoryMonitorLinux>(delegate);
+ return std::make_unique<MemoryMonitorLinux>(delegate);
}
// Implementation of factory function defined in memory_monitor.h.
diff --git a/chromium/content/browser/memory/swap_metrics_driver_impl_linux.cc b/chromium/content/browser/memory/swap_metrics_driver_impl_linux.cc
index 0d8f19782ab..1b045104fd4 100644
--- a/chromium/content/browser/memory/swap_metrics_driver_impl_linux.cc
+++ b/chromium/content/browser/memory/swap_metrics_driver_impl_linux.cc
@@ -43,15 +43,15 @@ SwapMetricsDriverImplLinux::~SwapMetricsDriverImplLinux() = default;
SwapMetricsDriver::SwapMetricsUpdateResult
SwapMetricsDriverImplLinux::UpdateMetricsInternal(base::TimeDelta interval) {
- base::SystemMemoryInfoKB memory_info;
- if (!base::GetSystemMemoryInfo(&memory_info)) {
+ base::VmStatInfo vmstat;
+ if (!base::GetVmStatInfo(&vmstat)) {
return SwapMetricsDriver::SwapMetricsUpdateResult::kSwapMetricsUpdateFailed;
}
- uint64_t in_counts = memory_info.pswpin - last_pswpin_;
- uint64_t out_counts = memory_info.pswpout - last_pswpout_;
- last_pswpin_ = memory_info.pswpin;
- last_pswpout_ = memory_info.pswpout;
+ uint64_t in_counts = vmstat.pswpin - last_pswpin_;
+ uint64_t out_counts = vmstat.pswpout - last_pswpout_;
+ last_pswpin_ = vmstat.pswpin;
+ last_pswpout_ = vmstat.pswpout;
if (interval.is_zero())
return SwapMetricsDriver::SwapMetricsUpdateResult::
diff --git a/chromium/content/browser/mime_registry_impl.cc b/chromium/content/browser/mime_registry_impl.cc
index b6b853c51ff..e5b26a666ac 100644
--- a/chromium/content/browser/mime_registry_impl.cc
+++ b/chromium/content/browser/mime_registry_impl.cc
@@ -19,7 +19,7 @@ MimeRegistryImpl::~MimeRegistryImpl() = default;
// static
void MimeRegistryImpl::Create(
blink::mojom::MimeRegistryRequest request) {
- mojo::MakeStrongBinding(base::MakeUnique<MimeRegistryImpl>(),
+ mojo::MakeStrongBinding(std::make_unique<MimeRegistryImpl>(),
std::move(request));
}
diff --git a/chromium/content/browser/mus_util.cc b/chromium/content/browser/mus_util.cc
new file mode 100644
index 00000000000..5f45f248df3
--- /dev/null
+++ b/chromium/content/browser/mus_util.cc
@@ -0,0 +1,21 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/mus_util.h"
+
+#if defined(USE_AURA)
+#include "ui/aura/env.h"
+#endif
+
+namespace content {
+
+bool IsUsingMus() {
+#if defined(USE_AURA)
+ return aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS;
+#else
+ return false;
+#endif
+}
+
+} // namespace content
diff --git a/chromium/content/browser/mus_util.h b/chromium/content/browser/mus_util.h
new file mode 100644
index 00000000000..4b7c78d3c81
--- /dev/null
+++ b/chromium/content/browser/mus_util.h
@@ -0,0 +1,16 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MUS_UTIL_H_
+#define CONTENT_BROWSER_MUS_UTIL_H_
+
+#include "content/common/content_export.h"
+
+namespace content {
+
+CONTENT_EXPORT bool IsUsingMus();
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MUS_UTIL_H_
diff --git a/chromium/content/browser/net/network_errors_listing_ui.cc b/chromium/content/browser/net/network_errors_listing_ui.cc
index 976970151cd..42e4804bbe3 100644
--- a/chromium/content/browser/net/network_errors_listing_ui.cc
+++ b/chromium/content/browser/net/network_errors_listing_ui.cc
@@ -17,7 +17,7 @@
#include "net/base/net_errors.h"
#include "net/log/net_log_util.h"
-static const char kDataFile[] = "network-error-data.json";
+static const char kNetworkErrorDataFile[] = "network-error-data.json";
static const char kErrorCodeField[] = "errorCode";
static const char kErrorCodesDataName[] = "errorCodes";
static const char kErrorIdField[] = "errorId";
@@ -57,10 +57,11 @@ std::unique_ptr<base::ListValue> GetNetworkErrorData() {
return error_list;
}
-bool HandleRequestCallback(BrowserContext* current_context,
- const std::string& path,
- const WebUIDataSource::GotDataCallback& callback) {
- if (path != kDataFile)
+bool HandleWebUIRequestCallback(
+ BrowserContext* current_context,
+ const std::string& path,
+ const WebUIDataSource::GotDataCallback& callback) {
+ if (path != kNetworkErrorDataFile)
return false;
base::DictionaryValue data;
@@ -87,7 +88,7 @@ NetworkErrorsListingUI::NetworkErrorsListingUI(WebUI* web_ui)
IDR_NETWORK_ERROR_LISTING_JS);
html_source->SetDefaultResource(IDR_NETWORK_ERROR_LISTING_HTML);
html_source->SetRequestFilter(
- base::Bind(&HandleRequestCallback,
+ base::Bind(&HandleWebUIRequestCallback,
web_ui->GetWebContents()->GetBrowserContext()));
BrowserContext* browser_context =
diff --git a/chromium/content/browser/net/network_quality_observer_impl.cc b/chromium/content/browser/net/network_quality_observer_impl.cc
index 1d871bc782b..879df3065eb 100644
--- a/chromium/content/browser/net/network_quality_observer_impl.cc
+++ b/chromium/content/browser/net/network_quality_observer_impl.cc
@@ -140,7 +140,7 @@ NetworkQualityObserverImpl::NetworkQualityObserverImpl(
network_quality_estimator_->AddRTTAndThroughputEstimatesObserver(this);
network_quality_estimator_->AddEffectiveConnectionTypeObserver(this);
- ui_thread_observer_ = base::MakeUnique<UiThreadObserver>();
+ ui_thread_observer_ = std::make_unique<UiThreadObserver>();
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&UiThreadObserver::InitOnUIThread,
@@ -217,7 +217,7 @@ void NetworkQualityObserverImpl::OnRTTOrThroughputEstimatesComputed(
std::unique_ptr<net::RTTAndThroughputEstimatesObserver>
CreateNetworkQualityObserver(
net::NetworkQualityEstimator* network_quality_estimator) {
- return base::MakeUnique<NetworkQualityObserverImpl>(
+ return std::make_unique<NetworkQualityObserverImpl>(
network_quality_estimator);
}
diff --git a/chromium/content/browser/net/quota_policy_cookie_store.cc b/chromium/content/browser/net/quota_policy_cookie_store.cc
index ec7b4b8c76f..46557601331 100644
--- a/chromium/content/browser/net/quota_policy_cookie_store.cc
+++ b/chromium/content/browser/net/quota_policy_cookie_store.cc
@@ -46,7 +46,8 @@ QuotaPolicyCookieStore::~QuotaPolicyCookieStore() {
}
const GURL url(net::cookie_util::CookieOriginToURL(cookie.first.first,
cookie.first.second));
- if (!url.is_valid() || !special_storage_policy_->IsStorageSessionOnly(url))
+ if (!url.is_valid() ||
+ !special_storage_policy_->IsStorageSessionOnlyOrBlocked(url))
continue;
session_only_cookies.push_back(cookie.first);
diff --git a/chromium/content/browser/net/reporting_service_proxy.cc b/chromium/content/browser/net/reporting_service_proxy.cc
index 4a97c159172..3118d177607 100644
--- a/chromium/content/browser/net/reporting_service_proxy.cc
+++ b/chromium/content/browser/net/reporting_service_proxy.cc
@@ -36,25 +36,62 @@ class ReportingServiceProxyImpl : public blink::mojom::ReportingServiceProxy {
void QueueInterventionReport(const GURL& url,
const std::string& message,
const std::string& source_file,
- int line_number) override {
+ int line_number,
+ int column_number) override {
auto body = std::make_unique<base::DictionaryValue>();
body->SetString("message", message);
body->SetString("sourceFile", source_file);
body->SetInteger("lineNumber", line_number);
+ body->SetInteger("columnNumber", column_number);
QueueReport(url, "default", "intervention", std::move(body));
}
void QueueDeprecationReport(const GURL& url,
const std::string& message,
const std::string& source_file,
- int line_number) override {
+ int line_number,
+ int column_number) override {
auto body = std::make_unique<base::DictionaryValue>();
body->SetString("message", message);
body->SetString("sourceFile", source_file);
body->SetInteger("lineNumber", line_number);
+ body->SetInteger("columnNumber", column_number);
QueueReport(url, "default", "deprecation", std::move(body));
}
+ void QueueCspViolationReport(const GURL& url,
+ const std::string& group,
+ const std::string& document_uri,
+ const std::string& referrer,
+ const std::string& violated_directive,
+ const std::string& effective_directive,
+ const std::string& original_policy,
+ const std::string& disposition,
+ const std::string& blocked_uri,
+ int line_number,
+ int column_number,
+ const std::string& source_file,
+ int status_code,
+ const std::string& script_sample) override {
+ auto body = std::make_unique<base::DictionaryValue>();
+ body->SetString("document-uri", document_uri);
+ body->SetString("referrer", referrer);
+ body->SetString("violated-directive", violated_directive);
+ body->SetString("effective-directive", effective_directive);
+ body->SetString("original-policy", original_policy);
+ body->SetString("disposition", disposition);
+ body->SetString("blocked-uri", blocked_uri);
+ if (line_number)
+ body->SetInteger("line-number", line_number);
+ if (column_number)
+ body->SetInteger("column-number", column_number);
+ body->SetString("source-file", source_file);
+ if (status_code)
+ body->SetInteger("status-code", status_code);
+ body->SetString("script-sample", script_sample);
+ QueueReport(url, group, "csp", std::move(body));
+ }
+
private:
void QueueReport(const GURL& url,
const std::string& group,
diff --git a/chromium/content/browser/net/view_http_cache_job_factory.cc b/chromium/content/browser/net/view_http_cache_job_factory.cc
index 5fef2a78a07..2b5ebb9e2c7 100644
--- a/chromium/content/browser/net/view_http_cache_job_factory.cc
+++ b/chromium/content/browser/net/view_http_cache_job_factory.cc
@@ -110,7 +110,7 @@ void ViewHttpCacheJob::Kill() {
weak_factory_.InvalidateWeakPtrs();
if (core_.get()) {
core_->Orphan();
- core_ = NULL;
+ core_ = nullptr;
}
net::URLRequestJob::Kill();
}
diff --git a/chromium/content/browser/net_info_browsertest.cc b/chromium/content/browser/net_info_browsertest.cc
index 16871e5ac70..769136ab448 100644
--- a/chromium/content/browser/net_info_browsertest.cc
+++ b/chromium/content/browser/net_info_browsertest.cc
@@ -116,7 +116,7 @@ class NetInfoBrowserTest : public content::ContentBrowserTest {
net::NetworkChangeNotifier::ConnectionType type,
net::NetworkChangeNotifier::ConnectionSubtype subtype) {
net::NetworkChangeNotifier::NotifyObserversOfMaxBandwidthChangeForTests(
- net::NetworkChangeNotifier::GetMaxBandwidthForConnectionSubtype(
+ net::NetworkChangeNotifier::GetMaxBandwidthMbpsForConnectionSubtype(
subtype),
type);
base::RunLoop().RunUntilIdle();
@@ -154,7 +154,7 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, VerifyNetworkStateInitialized) {
NavigateToURL(shell(), content::GetTestUrl("", "net_info.html"));
EXPECT_TRUE(RunScriptExtractBool("getOnLine()"));
EXPECT_EQ("ethernet", RunScriptExtractString("getType()"));
- EXPECT_EQ(net::NetworkChangeNotifier::GetMaxBandwidthForConnectionSubtype(
+ EXPECT_EQ(net::NetworkChangeNotifier::GetMaxBandwidthMbpsForConnectionSubtype(
net::NetworkChangeNotifier::SUBTYPE_GIGABIT_ETHERNET),
RunScriptExtractDouble("getDownlinkMax()"));
}
@@ -166,14 +166,14 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkChangePlumbsToNavigator) {
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI,
net::NetworkChangeNotifier::SUBTYPE_WIFI_N);
EXPECT_EQ("wifi", RunScriptExtractString("getType()"));
- EXPECT_EQ(net::NetworkChangeNotifier::GetMaxBandwidthForConnectionSubtype(
+ EXPECT_EQ(net::NetworkChangeNotifier::GetMaxBandwidthMbpsForConnectionSubtype(
net::NetworkChangeNotifier::SUBTYPE_WIFI_N),
RunScriptExtractDouble("getDownlinkMax()"));
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_ETHERNET,
net::NetworkChangeNotifier::SUBTYPE_GIGABIT_ETHERNET);
EXPECT_EQ("ethernet", RunScriptExtractString("getType()"));
- EXPECT_EQ(net::NetworkChangeNotifier::GetMaxBandwidthForConnectionSubtype(
+ EXPECT_EQ(net::NetworkChangeNotifier::GetMaxBandwidthMbpsForConnectionSubtype(
net::NetworkChangeNotifier::SUBTYPE_GIGABIT_ETHERNET),
RunScriptExtractDouble("getDownlinkMax()"));
}
@@ -220,8 +220,8 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
NetworkQualityEstimatorNotInitialized) {
base::HistogramTester histogram_tester;
net::TestNetworkQualityEstimator estimator(
- nullptr, std::map<std::string, std::string>(), false, false, true, true,
- base::MakeUnique<net::BoundTestNetLog>());
+ nullptr, std::map<std::string, std::string>(), false, false, true,
+ std::make_unique<net::BoundTestNetLog>());
NetworkQualityObserverImpl impl(&estimator);
EXPECT_TRUE(embedded_test_server()->Start());
@@ -240,8 +240,8 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
EffectiveConnectionTypeChangeNotfied) {
base::HistogramTester histogram_tester;
net::TestNetworkQualityEstimator estimator(
- nullptr, std::map<std::string, std::string>(), false, false, true, true,
- base::MakeUnique<net::BoundTestNetLog>());
+ nullptr, std::map<std::string, std::string>(), false, false, true,
+ std::make_unique<net::BoundTestNetLog>());
NetworkQualityObserverImpl impl(&estimator);
net::nqe::internal::NetworkQuality network_quality_1(
@@ -282,8 +282,8 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeNotified) {
base::HistogramTester histogram_tester;
net::TestNetworkQualityEstimator estimator(
- nullptr, std::map<std::string, std::string>(), false, false, true, true,
- base::MakeUnique<net::BoundTestNetLog>());
+ nullptr, std::map<std::string, std::string>(), false, false, true,
+ std::make_unique<net::BoundTestNetLog>());
NetworkQualityObserverImpl impl(&estimator);
net::nqe::internal::NetworkQuality network_quality_1(
@@ -320,8 +320,8 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeRounded) {
base::HistogramTester histogram_tester;
net::TestNetworkQualityEstimator estimator(
std::unique_ptr<net::ExternalEstimateProvider>(),
- std::map<std::string, std::string>(), false, false, true, true,
- base::MakeUnique<net::BoundTestNetLog>());
+ std::map<std::string, std::string>(), false, false, true,
+ std::make_unique<net::BoundTestNetLog>());
NetworkQualityObserverImpl impl(&estimator);
// Verify that the network quality is rounded properly.
@@ -365,8 +365,8 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeUpperLimit) {
base::HistogramTester histogram_tester;
net::TestNetworkQualityEstimator estimator(
std::unique_ptr<net::ExternalEstimateProvider>(),
- std::map<std::string, std::string>(), false, false, true, true,
- base::MakeUnique<net::BoundTestNetLog>());
+ std::map<std::string, std::string>(), false, false, true,
+ std::make_unique<net::BoundTestNetLog>());
NetworkQualityObserverImpl impl(&estimator);
net::nqe::internal::NetworkQuality network_quality(
@@ -387,8 +387,8 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityRandomized) {
base::HistogramTester histogram_tester;
net::TestNetworkQualityEstimator estimator(
std::unique_ptr<net::ExternalEstimateProvider>(),
- std::map<std::string, std::string>(), false, false, true, true,
- base::MakeUnique<net::BoundTestNetLog>());
+ std::map<std::string, std::string>(), false, false, true,
+ std::make_unique<net::BoundTestNetLog>());
NetworkQualityObserverImpl impl(&estimator);
net::nqe::internal::NetworkQuality network_quality(
@@ -448,8 +448,8 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityRandomized) {
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeNotNotified) {
base::HistogramTester histogram_tester;
net::TestNetworkQualityEstimator estimator(
- nullptr, std::map<std::string, std::string>(), false, false, true, true,
- base::MakeUnique<net::BoundTestNetLog>());
+ nullptr, std::map<std::string, std::string>(), false, false, true,
+ std::make_unique<net::BoundTestNetLog>());
NetworkQualityObserverImpl impl(&estimator);
// Verify that the network quality is rounded properly.
diff --git a/chromium/content/browser/network_service_browsertest.cc b/chromium/content/browser/network_service_browsertest.cc
new file mode 100644
index 00000000000..2e51cf1c057
--- /dev/null
+++ b/chromium/content/browser/network_service_browsertest.cc
@@ -0,0 +1,158 @@
+// Copyright 2017 The Chromium Authors. 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/memory/ref_counted_memory.h"
+#include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
+#include "content/public/browser/url_data_source.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_ui_controller.h"
+#include "content/public/browser/web_ui_controller_factory.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/url_utils.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"
+
+namespace content {
+
+namespace {
+
+class RenderProcessKilledObserver : public WebContentsObserver {
+ public:
+ explicit RenderProcessKilledObserver(WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+ ~RenderProcessKilledObserver() override {}
+
+ bool killed() const { return killed_; }
+
+ void RenderProcessGone(base::TerminationStatus status) override {
+ killed_ = true;
+ }
+
+ private:
+ bool killed_ = false;
+};
+
+class WebUITestWebUIControllerFactory : public WebUIControllerFactory {
+ public:
+ WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
+ const GURL& url) const override {
+ std::string foo(url.path());
+ if (url.path() == "/nobinding/")
+ web_ui->SetBindings(0);
+ return HasWebUIScheme(url) ? new WebUIController(web_ui) : nullptr;
+ }
+ WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
+ const GURL& url) const override {
+ return HasWebUIScheme(url) ? reinterpret_cast<WebUI::TypeID>(1) : nullptr;
+ }
+ bool UseWebUIForURL(BrowserContext* browser_context,
+ const GURL& url) const override {
+ return HasWebUIScheme(url);
+ }
+ bool UseWebUIBindingsForURL(BrowserContext* browser_context,
+ const GURL& url) const override {
+ return HasWebUIScheme(url);
+ }
+};
+
+class WebUIDataSource : public URLDataSource {
+ public:
+ WebUIDataSource() {}
+
+ private:
+ ~WebUIDataSource() override {}
+
+ std::string GetSource() const override { return "webui"; }
+
+ void StartDataRequest(
+ const std::string& path,
+ const ResourceRequestInfo::WebContentsGetter& wc_getter,
+ const URLDataSource::GotDataCallback& callback) override {
+ std::string dummy_html = "<html><body>Foo</body></html>";
+ scoped_refptr<base::RefCountedString> response =
+ base::RefCountedString::TakeString(&dummy_html);
+ callback.Run(response.get());
+ }
+
+ std::string GetMimeType(const std::string& path) const override {
+ return "text/html";
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(WebUIDataSource);
+};
+
+class NetworkServiceBrowserTest : public ContentBrowserTest {
+ public:
+ NetworkServiceBrowserTest() {
+ scoped_feature_list_.InitAndEnableFeature(features::kNetworkService);
+ EXPECT_TRUE(embedded_test_server()->Start());
+
+ WebUIControllerFactory::RegisterFactory(&factory_);
+ }
+
+ bool CheckCanLoadHttp() {
+ GURL test_url = embedded_test_server()->GetURL("/echo");
+ std::string script(
+ "var xhr = new XMLHttpRequest();"
+ "xhr.open('GET', '");
+ script += test_url.spec() +
+ "', true);"
+ "xhr.onload = function (e) {"
+ " if (xhr.readyState === 4) {"
+ " window.domAutomationController.send(xhr.status === 200);"
+ " }"
+ "};"
+ "xhr.onerror = function () {"
+ " window.domAutomationController.send(false);"
+ "};"
+ "xhr.send(null)";
+ bool xhr_result = false;
+ // The JS call will fail if disallowed because the process will be killed.
+ bool execute_result =
+ ExecuteScriptAndExtractBool(shell(), script, &xhr_result);
+ return xhr_result && execute_result;
+ }
+
+ void SetUpOnMainThread() override {
+ URLDataSource::Add(shell()->web_contents()->GetBrowserContext(),
+ new WebUIDataSource);
+ }
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ // Since we assume exploited renderer process, it can bypass the same origin
+ // policy at will. Simulate that by passing the disable-web-security flag.
+ command_line->AppendSwitch(switches::kDisableWebSecurity);
+ }
+
+ private:
+ WebUITestWebUIControllerFactory factory_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkServiceBrowserTest);
+};
+
+// Verifies that WebUI pages with WebUI bindings can't make network requests.
+IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest, WebUIBindingsNoHttp) {
+ GURL test_url("chrome://webui/");
+ NavigateToURL(shell(), test_url);
+ RenderProcessKilledObserver killed_observer(shell()->web_contents());
+ ASSERT_FALSE(CheckCanLoadHttp());
+ ASSERT_TRUE(killed_observer.killed());
+}
+
+// Verifies that WebUI pages without WebUI bindings can make network requests.
+IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest, NoWebUIBindingsHttp) {
+ GURL test_url("chrome://webui/nobinding/");
+ NavigateToURL(shell(), test_url);
+ ASSERT_TRUE(CheckCanLoadHttp());
+}
+
+} // namespace
+
+} // namespace content
diff --git a/chromium/content/browser/network_service_client.cc b/chromium/content/browser/network_service_client.cc
new file mode 100644
index 00000000000..81e01513cb5
--- /dev/null
+++ b/chromium/content/browser/network_service_client.cc
@@ -0,0 +1,60 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/network_service_client.h"
+
+#include "content/browser/ssl/ssl_error_handler.h"
+#include "content/browser/ssl/ssl_manager.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+
+namespace content {
+namespace {
+
+class SSLDelegate : public SSLErrorHandler::Delegate {
+ public:
+ explicit SSLDelegate(
+ mojom::NetworkServiceClient::OnSSLCertificateErrorCallback response)
+ : response_(std::move(response)), weak_factory_(this) {}
+ ~SSLDelegate() override {}
+ void CancelSSLRequest(int error, const net::SSLInfo* ssl_info) override {
+ std::move(response_).Run(error);
+ delete this;
+ }
+ void ContinueSSLRequest() override {
+ std::move(response_).Run(net::OK);
+ delete this;
+ }
+ base::WeakPtr<SSLDelegate> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
+
+ private:
+ mojom::NetworkServiceClient::OnSSLCertificateErrorCallback response_;
+ base::WeakPtrFactory<SSLDelegate> weak_factory_;
+};
+
+} // namespace
+
+NetworkServiceClient::NetworkServiceClient(
+ mojom::NetworkServiceClientRequest network_service_client_request)
+ : binding_(this, std::move(network_service_client_request)) {}
+
+NetworkServiceClient::~NetworkServiceClient() = default;
+
+void NetworkServiceClient::OnSSLCertificateError(
+ ResourceType resource_type,
+ const GURL& url,
+ uint32_t process_id,
+ uint32_t routing_id,
+ const net::SSLInfo& ssl_info,
+ bool fatal,
+ OnSSLCertificateErrorCallback response) {
+ SSLDelegate* delegate = new SSLDelegate(std::move(response)); // deletes self
+ base::Callback<WebContents*(void)> web_contents_getter =
+ process_id ? base::Bind(WebContentsImpl::FromRenderFrameHostID,
+ process_id, routing_id)
+ : base::Bind(WebContents::FromFrameTreeNodeId, routing_id);
+ SSLManager::OnSSLCertificateError(delegate->GetWeakPtr(), resource_type, url,
+ web_contents_getter, ssl_info, fatal);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/network_service_client.h b/chromium/content/browser/network_service_client.h
new file mode 100644
index 00000000000..6cd08f56639
--- /dev/null
+++ b/chromium/content/browser/network_service_client.h
@@ -0,0 +1,37 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_NETWORK_SERVICE_IMPL_H_
+#define CONTENT_BROWSER_NETWORK_SERVICE_IMPL_H_
+
+#include "base/macros.h"
+#include "content/public/common/network_service.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+namespace content {
+
+class NetworkServiceClient : public mojom::NetworkServiceClient {
+ public:
+ explicit NetworkServiceClient(
+ mojom::NetworkServiceClientRequest network_service_client_request);
+ ~NetworkServiceClient() override;
+
+ // mojom::NetworkServiceClient implementation:
+ void OnSSLCertificateError(ResourceType resource_type,
+ const GURL& url,
+ uint32_t process_id,
+ uint32_t routing_id,
+ const net::SSLInfo& ssl_info,
+ bool fatal,
+ OnSSLCertificateErrorCallback response) override;
+
+ private:
+ mojo::Binding<mojom::NetworkServiceClient> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkServiceClient);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_NETWORK_SERVICE_IMPL_H_
diff --git a/chromium/content/browser/network_service_restart_browsertest.cc b/chromium/content/browser/network_service_restart_browsertest.cc
new file mode 100644
index 00000000000..59f548f08de
--- /dev/null
+++ b/chromium/content/browser/network_service_restart_browsertest.cc
@@ -0,0 +1,98 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
+#include "content/public/browser/network_service_instance.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/network_service.mojom.h"
+#include "content/public/common/network_service_test.mojom.h"
+#include "content/public/common/service_manager_connection.h"
+#include "content/public/common/service_names.mojom.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 "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+namespace content {
+
+namespace {
+
+mojom::NetworkContextPtr CreateNetworkContext() {
+ mojom::NetworkContextPtr network_context;
+ mojom::NetworkContextParamsPtr context_params =
+ mojom::NetworkContextParams::New();
+ GetNetworkService()->CreateNetworkContext(mojo::MakeRequest(&network_context),
+ std::move(context_params));
+ return network_context;
+}
+
+} // namespace
+
+// This test source has been excluded from Android as Android doesn't have
+// out-of-process Network Service.
+class NetworkServiceRestartBrowserTest : public ContentBrowserTest {
+ public:
+ NetworkServiceRestartBrowserTest() {
+ scoped_feature_list_.InitAndEnableFeature(features::kNetworkService);
+ EXPECT_TRUE(embedded_test_server()->Start());
+ }
+
+ void SimulateNetworkServiceCrash() {
+ mojom::NetworkServiceTestPtr network_service_test;
+ ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
+ mojom::kNetworkServiceName, &network_service_test);
+ network_service_test->SimulateCrash();
+ network_service_test.FlushForTesting();
+ }
+
+ int LoadBasicRequest(mojom::NetworkContext* network_context) {
+ mojom::URLLoaderFactoryPtr url_loader_factory;
+ network_context->CreateURLLoaderFactory(MakeRequest(&url_loader_factory),
+ 0);
+
+ std::unique_ptr<ResourceRequest> request =
+ std::make_unique<ResourceRequest>();
+ request->url = embedded_test_server()->GetURL("/echo");
+
+ content::SimpleURLLoaderTestHelper simple_loader_helper;
+ std::unique_ptr<content::SimpleURLLoader> simple_loader =
+ content::SimpleURLLoader::Create(std::move(request),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+ url_loader_factory.get(), simple_loader_helper.GetCallback());
+ simple_loader_helper.WaitForCallback();
+
+ return simple_loader->NetError();
+ }
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkServiceRestartBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
+ NetworkServiceProcessRecovery) {
+ mojom::NetworkContextPtr network_context = CreateNetworkContext();
+ EXPECT_EQ(net::OK, LoadBasicRequest(network_context.get()));
+ EXPECT_TRUE(network_context.is_bound());
+ EXPECT_FALSE(network_context.encountered_error());
+
+ // Crash the NetworkService process. Existing interfaces should observe
+ // connection errors.
+ SimulateNetworkServiceCrash();
+ EXPECT_EQ(net::ERR_FAILED, LoadBasicRequest(network_context.get()));
+ EXPECT_TRUE(network_context.is_bound());
+ EXPECT_TRUE(network_context.encountered_error());
+
+ // NetworkService should restart automatically and return valid interface.
+ mojom::NetworkContextPtr network_context2 = CreateNetworkContext();
+ EXPECT_EQ(net::OK, LoadBasicRequest(network_context2.get()));
+ EXPECT_TRUE(network_context2.is_bound());
+ EXPECT_FALSE(network_context2.encountered_error());
+}
+
+} // namespace content
diff --git a/chromium/content/browser/notification_service_impl.cc b/chromium/content/browser/notification_service_impl.cc
index de2176990eb..9f38bb05106 100644
--- a/chromium/content/browser/notification_service_impl.cc
+++ b/chromium/content/browser/notification_service_impl.cc
@@ -40,7 +40,7 @@ bool NotificationServiceImpl::HasKey(const NotificationSourceMap& map,
}
NotificationServiceImpl::NotificationServiceImpl() {
- DCHECK(current() == NULL);
+ DCHECK(current() == nullptr);
lazy_tls_ptr.Pointer()->Set(this);
}
@@ -131,7 +131,7 @@ void NotificationServiceImpl::Notify(int type,
NotificationServiceImpl::~NotificationServiceImpl() {
- lazy_tls_ptr.Pointer()->Set(NULL);
+ lazy_tls_ptr.Pointer()->Set(nullptr);
#ifndef NDEBUG
for (int i = 0; i < static_cast<int>(observer_counts_.size()); i++) {
diff --git a/chromium/content/browser/notifications/OWNERS b/chromium/content/browser/notifications/OWNERS
index db7d72cb4b7..2c095bca8dd 100644
--- a/chromium/content/browser/notifications/OWNERS
+++ b/chromium/content/browser/notifications/OWNERS
@@ -1,6 +1,6 @@
# This OWNERS file also covers:
#
-# //content/child/notifications/
+# //content/renderer/notifications/
# //content/test/mock_platform_notification_service.*
mkwst@chromium.org
diff --git a/chromium/content/browser/notifications/blink_notification_service_impl.cc b/chromium/content/browser/notifications/blink_notification_service_impl.cc
index 5c78c0fae28..fd3420da4c6 100644
--- a/chromium/content/browser/notifications/blink_notification_service_impl.cc
+++ b/chromium/content/browser/notifications/blink_notification_service_impl.cc
@@ -28,10 +28,12 @@ BlinkNotificationServiceImpl::BlinkNotificationServiceImpl(
PlatformNotificationContextImpl* notification_context,
ResourceContext* resource_context,
int render_process_id,
+ const url::Origin& origin,
mojo::InterfaceRequest<blink::mojom::NotificationService> request)
: notification_context_(notification_context),
resource_context_(resource_context),
render_process_id_(render_process_id),
+ origin_(origin),
binding_(this, std::move(request)) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(notification_context_);
@@ -47,17 +49,15 @@ BlinkNotificationServiceImpl::~BlinkNotificationServiceImpl() {
}
void BlinkNotificationServiceImpl::GetPermissionStatus(
- const std::string& origin,
GetPermissionStatusCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
if (!Service()) {
std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
return;
}
blink::mojom::PermissionStatus permission_status =
- Service()->CheckPermissionOnIOThread(resource_context_, GURL(origin),
+ Service()->CheckPermissionOnIOThread(resource_context_, origin_.GetURL(),
render_process_id_);
std::move(callback).Run(permission_status);
diff --git a/chromium/content/browser/notifications/blink_notification_service_impl.h b/chromium/content/browser/notifications/blink_notification_service_impl.h
index 7674b8a7b1f..140784de65c 100644
--- a/chromium/content/browser/notifications/blink_notification_service_impl.h
+++ b/chromium/content/browser/notifications/blink_notification_service_impl.h
@@ -9,6 +9,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "third_party/WebKit/public/platform/modules/notifications/notification_service.mojom.h"
+#include "url/origin.h"
namespace content {
@@ -24,12 +25,12 @@ class BlinkNotificationServiceImpl : public blink::mojom::NotificationService {
PlatformNotificationContextImpl* notification_context,
ResourceContext* resource_context,
int render_process_id,
+ const url::Origin& origin,
mojo::InterfaceRequest<blink::mojom::NotificationService> request);
~BlinkNotificationServiceImpl() override;
// blink::mojom::NotificationService implementation.
- void GetPermissionStatus(const std::string& origin,
- GetPermissionStatusCallback callback) override;
+ void GetPermissionStatus(GetPermissionStatusCallback callback) override;
private:
// Called when an error is detected on binding_.
@@ -42,6 +43,9 @@ class BlinkNotificationServiceImpl : public blink::mojom::NotificationService {
int render_process_id_;
+ // The origin that this notification service is communicating with.
+ url::Origin origin_;
+
mojo::Binding<blink::mojom::NotificationService> binding_;
DISALLOW_COPY_AND_ASSIGN(BlinkNotificationServiceImpl);
diff --git a/chromium/content/browser/notifications/notification_database.cc b/chromium/content/browser/notifications/notification_database.cc
index d9f1890216a..0b1e9e99570 100644
--- a/chromium/content/browser/notifications/notification_database.cc
+++ b/chromium/content/browser/notifications/notification_database.cc
@@ -41,13 +41,13 @@ const char kNextNotificationIdKey[] = "NEXT_NOTIFICATION_ID";
const char kDataKeyPrefix[] = "DATA:";
// Separates the components of compound keys.
-const char kKeySeparator = '\x00';
+const char kNotificationKeySeparator = '\x00';
// The first notification id which to be handed out by the database.
const int64_t kFirstPersistentNotificationId = 1;
// Converts the LevelDB |status| to one of the notification database's values.
-NotificationDatabase::Status LevelDBStatusToStatus(
+NotificationDatabase::Status LevelDBStatusToNotificationDatabaseStatus(
const leveldb::Status& status) {
if (status.ok())
return NotificationDatabase::STATUS_OK;
@@ -72,7 +72,7 @@ std::string CreateDataPrefix(const GURL& origin) {
return base::StringPrintf("%s%s%c", kDataKeyPrefix,
storage::GetIdentifierFromOrigin(origin).c_str(),
- kKeySeparator);
+ kNotificationKeySeparator);
}
// Creates the compound data key in which notification data is stored.
@@ -132,7 +132,7 @@ NotificationDatabase::Status NotificationDatabase::Open(
options.env = env_.get();
}
- Status status = LevelDBStatusToStatus(
+ Status status = LevelDBStatusToNotificationDatabaseStatus(
leveldb_env::OpenDB(options, path_.AsUTF8Unsafe(), &db_));
if (status != STATUS_OK)
return status;
@@ -159,7 +159,7 @@ NotificationDatabase::Status NotificationDatabase::ReadNotificationData(
std::string key = CreateDataKey(origin, notification_id);
std::string serialized_data;
- Status status = LevelDBStatusToStatus(
+ Status status = LevelDBStatusToNotificationDatabaseStatus(
db_->Get(leveldb::ReadOptions(), key, &serialized_data));
if (status != STATUS_OK)
return status;
@@ -219,7 +219,8 @@ NotificationDatabase::Status NotificationDatabase::WriteNotificationData(
base::Int64ToString(next_persistent_notification_id_));
}
- return LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch));
+ return LevelDBStatusToNotificationDatabaseStatus(
+ db_->Write(leveldb::WriteOptions(), &batch));
}
NotificationDatabase::Status NotificationDatabase::DeleteNotificationData(
@@ -231,7 +232,8 @@ NotificationDatabase::Status NotificationDatabase::DeleteNotificationData(
DCHECK(origin.is_valid());
std::string key = CreateDataKey(origin, notification_id);
- return LevelDBStatusToStatus(db_->Delete(leveldb::WriteOptions(), key));
+ return LevelDBStatusToNotificationDatabaseStatus(
+ db_->Delete(leveldb::WriteOptions(), key));
}
NotificationDatabase::Status
@@ -268,14 +270,14 @@ NotificationDatabase::Status NotificationDatabase::Destroy() {
state_ = STATE_DISABLED;
db_.reset();
- return LevelDBStatusToStatus(
+ return LevelDBStatusToNotificationDatabaseStatus(
leveldb::DestroyDB(path_.AsUTF8Unsafe(), options));
}
NotificationDatabase::Status
NotificationDatabase::ReadNextPersistentNotificationId() {
std::string value;
- Status status = LevelDBStatusToStatus(
+ Status status = LevelDBStatusToNotificationDatabaseStatus(
db_->Get(leveldb::ReadOptions(), kNextNotificationIdKey, &value));
if (status == STATUS_ERROR_NOT_FOUND) {
@@ -331,7 +333,7 @@ NotificationDatabase::ReadAllNotificationDataInternal(
notification_data_vector->push_back(notification_database_data);
}
- return LevelDBStatusToStatus(iter->status());
+ return LevelDBStatusToNotificationDatabaseStatus(iter->status());
}
NotificationDatabase::Status
@@ -387,7 +389,8 @@ NotificationDatabase::DeleteAllNotificationDataInternal(
if (deleted_notification_ids->empty())
return STATUS_OK;
- return LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch));
+ return LevelDBStatusToNotificationDatabaseStatus(
+ db_->Write(leveldb::WriteOptions(), &batch));
}
} // namespace content
diff --git a/chromium/content/browser/notifications/notification_database_data_unittest.cc b/chromium/content/browser/notifications/notification_database_data_unittest.cc
index f3daaabc42f..e1c1038c51f 100644
--- a/chromium/content/browser/notifications/notification_database_data_unittest.cc
+++ b/chromium/content/browser/notifications/notification_database_data_unittest.cc
@@ -64,11 +64,11 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeData) {
for (size_t i = 0; i < blink::kWebNotificationMaxActions; i++) {
PlatformNotificationAction notification_action;
notification_action.type = kNotificationActionType;
- notification_action.action = base::SizeTToString(i);
- notification_action.title = base::SizeTToString16(i);
+ notification_action.action = base::NumberToString(i);
+ notification_action.title = base::NumberToString16(i);
notification_action.icon = GURL(kNotificationActionIconUrl);
notification_action.placeholder =
- base::NullableString16(base::SizeTToString16(i), false);
+ base::NullableString16(base::NumberToString16(i), false);
notification_data.actions.push_back(notification_action);
}
diff --git a/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc b/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
index 69acf7fde17..4e31a921db7 100644
--- a/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
+++ b/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -5,6 +5,7 @@
#include "content/browser/notifications/notification_event_dispatcher_impl.h"
#include "base/callback.h"
+#include "base/callback_helpers.h"
#include "base/optional.h"
#include "build/build_config.h"
#include "content/browser/notifications/notification_message_filter.h"
@@ -24,7 +25,7 @@ namespace content {
namespace {
using NotificationDispatchCompleteCallback =
- NotificationEventDispatcher::NotificationDispatchCompleteCallback;
+ base::Callback<void(PersistentNotificationStatus)>;
using NotificationOperationCallback =
base::Callback<void(const ServiceWorkerRegistration*,
const NotificationDatabaseData&)>;
@@ -370,12 +371,17 @@ void NotificationEventDispatcherImpl::DispatchNotificationClickEvent(
const GURL& origin,
const base::Optional<int>& action_index,
const base::Optional<base::string16>& reply,
- const NotificationDispatchCompleteCallback& dispatch_complete_callback) {
+ NotificationDispatchCompleteCallback dispatch_complete_callback) {
+ // TODO(peter): Remove AdaptCallbackForRepeating() when the dependencies of
+ // the NotificationEventDispatcherImpl have updated to using OnceCallbacks.
+ auto repeating_callback =
+ base::AdaptCallbackForRepeating(std::move(dispatch_complete_callback));
+
DispatchNotificationEvent(
browser_context, notification_id, origin,
base::Bind(&DoDispatchNotificationClickEvent, action_index, reply,
- dispatch_complete_callback),
- dispatch_complete_callback);
+ repeating_callback),
+ repeating_callback /* notification_error_callback */);
}
void NotificationEventDispatcherImpl::DispatchNotificationCloseEvent(
@@ -383,12 +389,17 @@ void NotificationEventDispatcherImpl::DispatchNotificationCloseEvent(
const std::string& notification_id,
const GURL& origin,
bool by_user,
- const NotificationDispatchCompleteCallback& dispatch_complete_callback) {
+ NotificationDispatchCompleteCallback dispatch_complete_callback) {
+ // TODO(peter): Remove AdaptCallbackForRepeating() when the dependencies of
+ // the NotificationEventDispatcherImpl have updated to using OnceCallbacks.
+ auto repeating_callback =
+ base::AdaptCallbackForRepeating(std::move(dispatch_complete_callback));
+
DispatchNotificationEvent(
browser_context, notification_id, origin,
base::Bind(&DoDispatchNotificationCloseEvent, notification_id, by_user,
- dispatch_complete_callback),
- dispatch_complete_callback);
+ repeating_callback),
+ repeating_callback /* notification_error_callback */);
}
void NotificationEventDispatcherImpl::RegisterNonPersistentNotification(
@@ -455,12 +466,13 @@ void NotificationEventDispatcherImpl::DispatchNonPersistentCloseEvent(
// closed.
if (!sender)
return;
+
sender->Send(new PlatformNotificationMsg_DidClose(
non_persistent_ids_[notification_id]));
- static_cast<RenderProcessHostImpl*>(sender)
- ->notification_message_filter()
- ->DidCloseNotification(notification_id);
+ // No interaction will follow anymore once the notification has been closed.
+ non_persistent_ids_.erase(notification_id);
+ renderer_ids_.erase(notification_id);
}
void NotificationEventDispatcherImpl::RendererGone(int renderer_id) {
diff --git a/chromium/content/browser/notifications/notification_event_dispatcher_impl.h b/chromium/content/browser/notifications/notification_event_dispatcher_impl.h
index 761783f0d89..ac0076c3397 100644
--- a/chromium/content/browser/notifications/notification_event_dispatcher_impl.h
+++ b/chromium/content/browser/notifications/notification_event_dispatcher_impl.h
@@ -27,15 +27,13 @@ class NotificationEventDispatcherImpl : public NotificationEventDispatcher {
const GURL& origin,
const base::Optional<int>& action_index,
const base::Optional<base::string16>& reply,
- const NotificationDispatchCompleteCallback& dispatch_complete_callback)
- override;
+ NotificationDispatchCompleteCallback dispatch_complete_callback) override;
void DispatchNotificationCloseEvent(
BrowserContext* browser_context,
const std::string& notification_id,
const GURL& origin,
bool by_user,
- const NotificationDispatchCompleteCallback& dispatch_complete_callback)
- override;
+ NotificationDispatchCompleteCallback dispatch_complete_callback) override;
void DispatchNonPersistentShowEvent(
const std::string& notification_id) override;
void DispatchNonPersistentClickEvent(
diff --git a/chromium/content/browser/notifications/notification_id_generator.cc b/chromium/content/browser/notifications/notification_id_generator.cc
index 93665fdef7b..5323a1c8cd3 100644
--- a/chromium/content/browser/notifications/notification_id_generator.cc
+++ b/chromium/content/browser/notifications/notification_id_generator.cc
@@ -6,14 +6,9 @@
#include <sstream>
-#include "base/base64.h"
-#include "base/files/file_path.h"
#include "base/logging.h"
-#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
-#include "content/public/browser/browser_context.h"
#include "url/gurl.h"
namespace content {
@@ -24,29 +19,8 @@ const char kNonPersistentNotificationPrefix[] = "n:";
const char kSeparator = '#';
-// Computes a hash based on the path in which the |browser_context| is stored.
-// Since we only store the hash, SHA-1 is used to make the probability of
-// collisions negligible.
-std::string ComputeBrowserContextHash(BrowserContext* browser_context) {
- const base::FilePath path = browser_context->GetPath();
-
-#if defined(OS_WIN)
- std::string path_hash = base::SHA1HashString(base::WideToUTF8(path.value()));
-#else
- std::string path_hash = base::SHA1HashString(path.value());
-#endif
-
- return base::HexEncode(path_hash.c_str(), path_hash.length());
-}
-
} // namespace
-NotificationIdGenerator::NotificationIdGenerator(
- BrowserContext* browser_context)
- : browser_context_(browser_context) {}
-
-NotificationIdGenerator::~NotificationIdGenerator() {}
-
// static
bool NotificationIdGenerator::IsPersistentNotification(
const base::StringPiece& notification_id) {
@@ -69,8 +43,6 @@ std::string NotificationIdGenerator::GenerateForPersistentNotification(
std::stringstream stream;
stream << kPersistentNotificationPrefix;
- stream << ComputeBrowserContextHash(browser_context_);
- stream << base::IntToString(browser_context_->IsOffTheRecord());
stream << origin;
stream << base::IntToString(!tag.empty());
@@ -93,8 +65,6 @@ std::string NotificationIdGenerator::GenerateForNonPersistentNotification(
std::stringstream stream;
stream << kNonPersistentNotificationPrefix;
- stream << ComputeBrowserContextHash(browser_context_);
- stream << base::IntToString(browser_context_->IsOffTheRecord());
stream << origin;
stream << base::IntToString(!tag.empty());
diff --git a/chromium/content/browser/notifications/notification_id_generator.h b/chromium/content/browser/notifications/notification_id_generator.h
index d279e194b37..52cff09fd58 100644
--- a/chromium/content/browser/notifications/notification_id_generator.h
+++ b/chromium/content/browser/notifications/notification_id_generator.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <string>
+#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "content/common/content_export.h"
@@ -15,15 +16,13 @@ class GURL;
namespace content {
-class BrowserContext;
-
// Generates deterministic notification ids for Web Notifications.
//
-// The notification id must be deterministic for a given browser context, origin
-// and tag, when the tag is non-empty, or unique for the given notification when
-// the tag is empty. For non-persistent notifications, the uniqueness will be
-// based on the render process id. For persistent notifications, the generated
-// id will be globally unique for the lifetime of the notification database.
+// The notification id must be deterministic for a given origin and tag, when
+// the tag is non-empty, or unique for the given notification when the tag is
+// empty. For non-persistent notifications, the uniqueness will be based on the
+// render process id. For persistent notifications, the generated id will be
+// globally unique for the lifetime of the notification database.
//
// Notifications coming from the same origin and having the same tag will result
// in the same notification id being generated. This id may then be used to
@@ -35,10 +34,12 @@ class BrowserContext;
//
// It is important to note that, for persistent notifications, the generated
// notification id can outlive the browser process responsible for creating it.
+//
+// Note that the PlatformNotificationService is expected to handle
+// distinguishing identical generated ids from different browser contexts.
class CONTENT_EXPORT NotificationIdGenerator {
public:
- explicit NotificationIdGenerator(BrowserContext* browser_context);
- ~NotificationIdGenerator();
+ NotificationIdGenerator() = default;
// Returns whether |notification_id| belongs to a persistent notification.
static bool IsPersistentNotification(
@@ -66,8 +67,7 @@ class CONTENT_EXPORT NotificationIdGenerator {
int render_process_id) const;
private:
- // The NotificationMessageFilter that owns |this| will outlive the context.
- BrowserContext* browser_context_;
+ DISALLOW_COPY_AND_ASSIGN(NotificationIdGenerator);
};
} // namespace context
diff --git a/chromium/content/browser/notifications/notification_id_generator_unittest.cc b/chromium/content/browser/notifications/notification_id_generator_unittest.cc
index 3b8b9bb4bfd..99918508027 100644
--- a/chromium/content/browser/notifications/notification_id_generator_unittest.cc
+++ b/chromium/content/browser/notifications/notification_id_generator_unittest.cc
@@ -7,7 +7,6 @@
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/notifications/notification_id_generator.h"
-#include "content/public/test/test_browser_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -19,169 +18,65 @@ const int64_t kPersistentNotificationId = 430;
const int kNonPersistentNotificationId = 5400;
const char kExampleTag[] = "example";
-class TestBrowserContextConfigurableIncognito : public TestBrowserContext {
- public:
- TestBrowserContextConfigurableIncognito() {}
- ~TestBrowserContextConfigurableIncognito() override {}
-
- void set_incognito(bool incognito) { incognito_ = incognito; }
-
- // TestBrowserContext implementation.
- bool IsOffTheRecord() const override { return incognito_; }
-
- private:
- bool incognito_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(TestBrowserContextConfigurableIncognito);
-};
-
class NotificationIdGeneratorTest : public ::testing::Test {
public:
- NotificationIdGeneratorTest() : generator_(&browser_context_) {}
-
- void SetUp() override {}
+ NotificationIdGeneratorTest() : origin_("https://example.com") {}
protected:
- GURL origin() const { return GURL("https://example.com"); }
-
- TestBrowserContextConfigurableIncognito* browser_context() {
- return &browser_context_;
- }
-
- NotificationIdGenerator* generator() { return &generator_; }
-
- private:
- TestBrowserContextConfigurableIncognito browser_context_;
+ GURL origin_;
NotificationIdGenerator generator_;
};
// -----------------------------------------------------------------------------
// Persistent and non-persistent notifications
-//
-// Tests that cover logic common to both persistent and non-persistent
-// notifications: different browser contexts, Incognito mode or not,
// Two calls to the generator with exactly the same information should result
// in exactly the same notification ids being generated.
TEST_F(NotificationIdGeneratorTest, DeterministicGeneration) {
// Persistent notifications.
- EXPECT_EQ(generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId));
-
- EXPECT_EQ(generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId));
-
- // Non-persistent notifications.
- EXPECT_EQ(generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId),
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId));
-
- EXPECT_EQ(generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId,
- kRenderProcessId),
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId,
- kRenderProcessId));
-}
-
-// Uniqueness of notification ids will be impacted by the browser context.
-TEST_F(NotificationIdGeneratorTest, DifferentBrowserContexts) {
- TestBrowserContextConfigurableIncognito second_browser_context;
- NotificationIdGenerator second_generator(&second_browser_context);
-
- // Persistent notifications.
- EXPECT_NE(generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId),
- second_generator.GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId));
+ EXPECT_EQ(generator_.GenerateForPersistentNotification(
+ origin_, kExampleTag, kPersistentNotificationId),
+ generator_.GenerateForPersistentNotification(
+ origin_, kExampleTag, kPersistentNotificationId));
- EXPECT_NE(generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId),
- second_generator.GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId));
+ EXPECT_EQ(generator_.GenerateForPersistentNotification(
+ origin_, "" /* tag */, kPersistentNotificationId),
+ generator_.GenerateForPersistentNotification(
+ origin_, "" /* tag */, kPersistentNotificationId));
// Non-persistent notifications.
- EXPECT_NE(generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId),
- second_generator.GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId));
-
- EXPECT_NE(generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId,
+ EXPECT_EQ(
+ generator_.GenerateForNonPersistentNotification(
+ origin_, kExampleTag, kNonPersistentNotificationId, kRenderProcessId),
+ generator_.GenerateForNonPersistentNotification(
+ origin_, kExampleTag, kNonPersistentNotificationId,
+ kRenderProcessId));
+
+ EXPECT_EQ(generator_.GenerateForNonPersistentNotification(
+ origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId),
- second_generator.GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId,
+ generator_.GenerateForNonPersistentNotification(
+ origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId));
}
-// Uniqueness of notification ids will be impacted by the fact whether the
-// browser context is in Incognito mode.
-TEST_F(NotificationIdGeneratorTest, DifferentIncognitoStates) {
- ASSERT_FALSE(browser_context()->IsOffTheRecord());
-
- // Persistent notifications.
- std::string normal_persistent_notification_id =
- generator()->GenerateForPersistentNotification(origin(), kExampleTag,
- kPersistentNotificationId);
-
- browser_context()->set_incognito(true);
- ASSERT_TRUE(browser_context()->IsOffTheRecord());
-
- std::string incognito_persistent_notification_id =
- generator()->GenerateForPersistentNotification(origin(), kExampleTag,
- kPersistentNotificationId);
-
- EXPECT_NE(normal_persistent_notification_id,
- incognito_persistent_notification_id);
-
- browser_context()->set_incognito(false);
-
- // Non-persistent notifications.
- ASSERT_FALSE(browser_context()->IsOffTheRecord());
-
- std::string normal_non_persistent_notification_id =
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId);
-
- browser_context()->set_incognito(true);
- ASSERT_TRUE(browser_context()->IsOffTheRecord());
-
- std::string incognito_non_persistent_notification_id =
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId);
-
- EXPECT_NE(normal_non_persistent_notification_id,
- incognito_non_persistent_notification_id);
-}
-
// The origin of the notification will impact the generated notification id.
TEST_F(NotificationIdGeneratorTest, DifferentOrigins) {
GURL different_origin("https://example2.com");
// Persistent notifications.
- EXPECT_NE(generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
+ EXPECT_NE(generator_.GenerateForPersistentNotification(
+ origin_, kExampleTag, kPersistentNotificationId),
+ generator_.GenerateForPersistentNotification(
different_origin, kExampleTag, kPersistentNotificationId));
// Non-persistent notifications.
- EXPECT_NE(generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId),
- generator()->GenerateForNonPersistentNotification(
- different_origin, kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId));
+ EXPECT_NE(
+ generator_.GenerateForNonPersistentNotification(
+ origin_, kExampleTag, kNonPersistentNotificationId, kRenderProcessId),
+ generator_.GenerateForNonPersistentNotification(
+ different_origin, kExampleTag, kNonPersistentNotificationId,
+ kRenderProcessId));
}
// The tag, when non-empty, will impact the generated notification id.
@@ -189,62 +84,62 @@ TEST_F(NotificationIdGeneratorTest, DifferentTags) {
const std::string& different_tag = std::string(kExampleTag) + "2";
// Persistent notifications.
- EXPECT_NE(generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin(), different_tag, kPersistentNotificationId));
+ EXPECT_NE(generator_.GenerateForPersistentNotification(
+ origin_, kExampleTag, kPersistentNotificationId),
+ generator_.GenerateForPersistentNotification(
+ origin_, different_tag, kPersistentNotificationId));
// Non-persistent notifications.
- EXPECT_NE(generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId),
- generator()->GenerateForNonPersistentNotification(
- origin(), different_tag, kNonPersistentNotificationId,
- kRenderProcessId));
+ EXPECT_NE(
+ generator_.GenerateForNonPersistentNotification(
+ origin_, kExampleTag, kNonPersistentNotificationId, kRenderProcessId),
+ generator_.GenerateForNonPersistentNotification(
+ origin_, different_tag, kNonPersistentNotificationId,
+ kRenderProcessId));
}
// The persistent or non-persistent notification id will impact the generated
// notification id when the tag is empty.
TEST_F(NotificationIdGeneratorTest, DifferentIds) {
// Persistent notifications.
- EXPECT_NE(generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId + 1));
+ EXPECT_NE(generator_.GenerateForPersistentNotification(
+ origin_, "" /* tag */, kPersistentNotificationId),
+ generator_.GenerateForPersistentNotification(
+ origin_, "" /* tag */, kPersistentNotificationId + 1));
// Non-persistent notifications.
- EXPECT_NE(generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId,
+ EXPECT_NE(generator_.GenerateForNonPersistentNotification(
+ origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId),
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId + 1,
+ generator_.GenerateForNonPersistentNotification(
+ origin_, "" /* tag */, kNonPersistentNotificationId + 1,
kRenderProcessId));
// Non-persistent when a tag is being used.
- EXPECT_EQ(generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId),
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId + 1));
+ EXPECT_EQ(
+ generator_.GenerateForNonPersistentNotification(
+ origin_, kExampleTag, kNonPersistentNotificationId, kRenderProcessId),
+ generator_.GenerateForNonPersistentNotification(
+ origin_, kExampleTag, kNonPersistentNotificationId,
+ kRenderProcessId + 1));
}
// Using a numeric tag that could resemble a persistent notification id should
// not be equal to a notification without a tag, but with that id.
TEST_F(NotificationIdGeneratorTest, NumericTagAmbiguity) {
// Persistent notifications.
- EXPECT_NE(generator()->GenerateForPersistentNotification(
- origin(), base::Int64ToString(kPersistentNotificationId),
+ EXPECT_NE(generator_.GenerateForPersistentNotification(
+ origin_, base::Int64ToString(kPersistentNotificationId),
kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId));
+ generator_.GenerateForPersistentNotification(
+ origin_, "" /* tag */, kPersistentNotificationId));
// Non-persistent notifications.
- EXPECT_NE(generator()->GenerateForNonPersistentNotification(
- origin(), base::IntToString(kNonPersistentNotificationId),
+ EXPECT_NE(generator_.GenerateForNonPersistentNotification(
+ origin_, base::IntToString(kNonPersistentNotificationId),
kNonPersistentNotificationId, kRenderProcessId),
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId,
+ generator_.GenerateForNonPersistentNotification(
+ origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId));
}
@@ -255,28 +150,28 @@ TEST_F(NotificationIdGeneratorTest, OriginPortAmbiguity) {
GURL origin_8051("https://example.com:8051");
// Persistent notifications.
- EXPECT_NE(generator()->GenerateForPersistentNotification(
+ EXPECT_NE(generator_.GenerateForPersistentNotification(
origin_805, "17", kPersistentNotificationId),
- generator()->GenerateForPersistentNotification(
+ generator_.GenerateForPersistentNotification(
origin_8051, "7", kPersistentNotificationId));
// Non-persistent notifications.
EXPECT_NE(
- generator()->GenerateForNonPersistentNotification(
+ generator_.GenerateForNonPersistentNotification(
origin_805, "17", kNonPersistentNotificationId, kRenderProcessId),
- generator()->GenerateForNonPersistentNotification(
+ generator_.GenerateForNonPersistentNotification(
origin_8051, "7", kNonPersistentNotificationId, kRenderProcessId));
}
// Verifies that the static Is(Non)PersistentNotification helpers can correctly
// identify persistent and non-persistent notification IDs.
TEST_F(NotificationIdGeneratorTest, DetectIdFormat) {
- std::string persistent_id = generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId);
+ std::string persistent_id = generator_.GenerateForPersistentNotification(
+ origin_, "" /* tag */, kPersistentNotificationId);
std::string non_persistent_id =
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId,
+ generator_.GenerateForNonPersistentNotification(
+ origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId);
EXPECT_TRUE(NotificationIdGenerator::IsPersistentNotification(persistent_id));
@@ -296,17 +191,17 @@ TEST_F(NotificationIdGeneratorTest, DetectIdFormat) {
// notification does not care about the renderer process that created them.
TEST_F(NotificationIdGeneratorTest, PersistentDifferentRenderProcessIds) {
- NotificationIdGenerator second_generator(browser_context());
+ NotificationIdGenerator second_generator;
- EXPECT_EQ(generator()->GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId),
+ EXPECT_EQ(generator_.GenerateForPersistentNotification(
+ origin_, kExampleTag, kPersistentNotificationId),
second_generator.GenerateForPersistentNotification(
- origin(), kExampleTag, kPersistentNotificationId));
+ origin_, kExampleTag, kPersistentNotificationId));
- EXPECT_EQ(generator()->GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId),
+ EXPECT_EQ(generator_.GenerateForPersistentNotification(
+ origin_, "" /* tag */, kPersistentNotificationId),
second_generator.GenerateForPersistentNotification(
- origin(), "" /* tag */, kPersistentNotificationId));
+ origin_, "" /* tag */, kPersistentNotificationId));
}
// -----------------------------------------------------------------------------
@@ -318,18 +213,18 @@ TEST_F(NotificationIdGeneratorTest, PersistentDifferentRenderProcessIds) {
// the count for non-persistent notification ids.
TEST_F(NotificationIdGeneratorTest, NonPersistentDifferentRenderProcessIds) {
- EXPECT_EQ(generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId),
- generator()->GenerateForNonPersistentNotification(
- origin(), kExampleTag, kNonPersistentNotificationId,
- kRenderProcessId + 1));
-
- EXPECT_NE(generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId,
+ EXPECT_EQ(
+ generator_.GenerateForNonPersistentNotification(
+ origin_, kExampleTag, kNonPersistentNotificationId, kRenderProcessId),
+ generator_.GenerateForNonPersistentNotification(
+ origin_, kExampleTag, kNonPersistentNotificationId,
+ kRenderProcessId + 1));
+
+ EXPECT_NE(generator_.GenerateForNonPersistentNotification(
+ origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId),
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, kNonPersistentNotificationId,
+ generator_.GenerateForNonPersistentNotification(
+ origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId + 1));
}
@@ -337,11 +232,11 @@ TEST_F(NotificationIdGeneratorTest, NonPersistentDifferentRenderProcessIds) {
// id should not result in the generation of a duplicated notification id.
TEST_F(NotificationIdGeneratorTest, NonPersistentRenderProcessIdAmbiguity) {
EXPECT_NE(
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, 1337 /* non_persistent_notification_id */,
+ generator_.GenerateForNonPersistentNotification(
+ origin_, "" /* tag */, 1337 /* non_persistent_notification_id */,
5 /* render_process_id */),
- generator()->GenerateForNonPersistentNotification(
- origin(), "" /* tag */, 337 /* non_persistent_notification_id */,
+ generator_.GenerateForNonPersistentNotification(
+ origin_, "" /* tag */, 337 /* non_persistent_notification_id */,
51 /* render_process_id */));
}
diff --git a/chromium/content/browser/notifications/notification_message_filter.cc b/chromium/content/browser/notifications/notification_message_filter.cc
index d56ece35bd0..234105311e6 100644
--- a/chromium/content/browser/notifications/notification_message_filter.cc
+++ b/chromium/content/browser/notifications/notification_message_filter.cc
@@ -98,16 +98,10 @@ NotificationMessageFilter::NotificationMessageFilter(
NotificationMessageFilter::~NotificationMessageFilter() = default;
-void NotificationMessageFilter::DidCloseNotification(
- const std::string& notification_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- close_closures_.erase(notification_id);
-}
-
void NotificationMessageFilter::OnDestruct() const {
if (non_persistent__notification_shown_) {
NotificationEventDispatcherImpl* event_dispatcher =
- content::NotificationEventDispatcherImpl::GetInstance();
+ NotificationEventDispatcherImpl::GetInstance();
DCHECK(event_dispatcher);
event_dispatcher->RendererGone(process_id_);
}
@@ -135,7 +129,7 @@ bool NotificationMessageFilter::OnMessageReceived(const IPC::Message& message) {
void NotificationMessageFilter::OverrideThreadForMessage(
const IPC::Message& message,
- content::BrowserThread::ID* thread) {
+ BrowserThread::ID* thread) {
if (message.type() == PlatformNotificationHostMsg_Show::ID ||
message.type() == PlatformNotificationHostMsg_Close::ID)
*thread = BrowserThread::UI;
@@ -167,18 +161,14 @@ void NotificationMessageFilter::OnShowPlatformNotification(
origin, notification_data.tag, non_persistent_notification_id,
process_id_);
NotificationEventDispatcherImpl* event_dispatcher =
- content::NotificationEventDispatcherImpl::GetInstance();
+ NotificationEventDispatcherImpl::GetInstance();
non_persistent__notification_shown_ = true;
event_dispatcher->RegisterNonPersistentNotification(
notification_id, process_id_, non_persistent_notification_id);
- base::Closure close_closure;
service->DisplayNotification(browser_context_, notification_id, origin,
SanitizeNotificationData(notification_data),
- notification_resources, &close_closure);
-
- if (!close_closure.is_null())
- close_closures_[notification_id] = close_closure;
+ notification_resources);
}
void NotificationMessageFilter::OnShowPersistentNotification(
@@ -328,11 +318,14 @@ void NotificationMessageFilter::OnClosePlatformNotification(
GetNotificationIdGenerator()->GenerateForNonPersistentNotification(
origin, tag, non_persistent_notification_id, process_id_);
- if (!close_closures_.count(notification_id))
- return;
+ PlatformNotificationService* service =
+ GetContentClient()->browser()->GetPlatformNotificationService();
+ DCHECK(service);
+
+ service->CloseNotification(browser_context_, notification_id);
- close_closures_[notification_id].Run();
- close_closures_.erase(notification_id);
+ NotificationEventDispatcherImpl::GetInstance()
+ ->DispatchNonPersistentCloseEvent(notification_id);
}
void NotificationMessageFilter::OnClosePersistentNotification(
diff --git a/chromium/content/browser/notifications/notification_message_filter.h b/chromium/content/browser/notifications/notification_message_filter.h
index e3d67c5b333..c471053935e 100644
--- a/chromium/content/browser/notifications/notification_message_filter.h
+++ b/chromium/content/browser/notifications/notification_message_filter.h
@@ -7,10 +7,8 @@
#include <stdint.h>
-#include <map>
#include <vector>
-#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/service_worker/service_worker_status_code.h"
@@ -41,10 +39,6 @@ class NotificationMessageFilter : public BrowserMessageFilter {
const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context,
BrowserContext* browser_context);
- // To be called by non-persistent notification delegates when they are closed,
- // so that the close closure associated with that notification can be removed.
- void DidCloseNotification(const std::string& notification_id);
-
// BrowserMessageFilter implementation. Called on the UI thread.
void OnDestruct() const override;
bool OnMessageReceived(const IPC::Message& message) override;
@@ -140,10 +134,6 @@ class NotificationMessageFilter : public BrowserMessageFilter {
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
BrowserContext* browser_context_;
- // Map mapping notification IDs associated with non-persistent notifications
- // to the closures that may be used for programmatically closing them.
- std::unordered_map<std::string, base::Closure> close_closures_;
-
base::WeakPtrFactory<NotificationMessageFilter> weak_factory_io_;
DISALLOW_COPY_AND_ASSIGN(NotificationMessageFilter);
diff --git a/chromium/content/browser/notifications/platform_notification_context_impl.cc b/chromium/content/browser/notifications/platform_notification_context_impl.cc
index db017fc5167..f9be0328c26 100644
--- a/chromium/content/browser/notifications/platform_notification_context_impl.cc
+++ b/chromium/content/browser/notifications/platform_notification_context_impl.cc
@@ -36,8 +36,7 @@ PlatformNotificationContextImpl::PlatformNotificationContextImpl(
const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
: path_(path),
browser_context_(browser_context),
- service_worker_context_(service_worker_context),
- notification_id_generator_(browser_context) {
+ service_worker_context_(service_worker_context) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
@@ -125,22 +124,25 @@ void PlatformNotificationContextImpl::ShutdownOnIO() {
void PlatformNotificationContextImpl::CreateService(
int render_process_id,
+ const url::Origin& origin,
blink::mojom::NotificationServiceRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&PlatformNotificationContextImpl::CreateServiceOnIO, this,
- render_process_id, browser_context_->GetResourceContext(),
+ render_process_id, origin,
+ browser_context_->GetResourceContext(),
base::Passed(&request)));
}
void PlatformNotificationContextImpl::CreateServiceOnIO(
int render_process_id,
+ const url::Origin& origin,
ResourceContext* resource_context,
mojo::InterfaceRequest<blink::mojom::NotificationService> request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
services_.push_back(std::make_unique<BlinkNotificationServiceImpl>(
- this, resource_context, render_process_id, std::move(request)));
+ this, resource_context, render_process_id, origin, std::move(request)));
}
void PlatformNotificationContextImpl::RemoveService(
diff --git a/chromium/content/browser/notifications/platform_notification_context_impl.h b/chromium/content/browser/notifications/platform_notification_context_impl.h
index af5d33522bf..157a54c54ec 100644
--- a/chromium/content/browser/notifications/platform_notification_context_impl.h
+++ b/chromium/content/browser/notifications/platform_notification_context_impl.h
@@ -29,6 +29,10 @@ namespace base {
class SequencedTaskRunner;
}
+namespace url {
+class Origin;
+}
+
namespace content {
class BlinkNotificationServiceImpl;
@@ -64,6 +68,7 @@ class CONTENT_EXPORT PlatformNotificationContextImpl
// be called on the UI thread, although the service will be created on and
// bound to the IO thread.
void CreateService(int render_process_id,
+ const url::Origin& origin,
blink::mojom::NotificationServiceRequest request);
// Removes |service| from the list of owned services, for example because the
@@ -109,6 +114,7 @@ class CONTENT_EXPORT PlatformNotificationContextImpl
void ShutdownOnIO();
void CreateServiceOnIO(
int render_process_id,
+ const url::Origin& origin,
ResourceContext* resource_context,
mojo::InterfaceRequest<blink::mojom::NotificationService> request);
diff --git a/chromium/content/browser/notifications/platform_notification_context_unittest.cc b/chromium/content/browser/notifications/platform_notification_context_unittest.cc
index 64616d96cab..6a451a2def8 100644
--- a/chromium/content/browser/notifications/platform_notification_context_unittest.cc
+++ b/chromium/content/browser/notifications/platform_notification_context_unittest.cc
@@ -32,7 +32,8 @@ const int64_t kFakeServiceWorkerRegistrationId = 42;
class NotificationBrowserClient : public TestContentBrowserClient {
public:
NotificationBrowserClient()
- : platform_notification_service_(new MockPlatformNotificationService()) {}
+ : platform_notification_service_(
+ std::make_unique<MockPlatformNotificationService>()) {}
PlatformNotificationService* GetPlatformNotificationService() override {
return platform_notification_service_.get();
diff --git a/chromium/content/browser/origin_manifest/origin_manifest_parser.cc b/chromium/content/browser/origin_manifest/origin_manifest_parser.cc
new file mode 100644
index 00000000000..1b6a3db52d2
--- /dev/null
+++ b/chromium/content/browser/origin_manifest/origin_manifest_parser.cc
@@ -0,0 +1,105 @@
+// Copyright 2017 The Chromium Authors. 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/origin_manifest/origin_manifest_parser.h"
+
+#include "base/json/json_reader.h"
+#include "base/strings/string_util.h"
+
+namespace content {
+namespace origin_manifest_parser {
+
+std::unique_ptr<blink::OriginManifest> Parse(std::string json) {
+ // TODO throw some meaningful errors when parsing does not go well
+ std::unique_ptr<base::DictionaryValue> directives_dict =
+ base::DictionaryValue::From(
+ base::JSONReader::Read(json, base::JSON_ALLOW_TRAILING_COMMAS));
+
+ std::unique_ptr<blink::OriginManifest> origin_manifest;
+
+ // TODO(dhausknecht) that's playing safe. But we should do something to tell
+ // things went wrong here.
+ if (!directives_dict)
+ return origin_manifest;
+
+ origin_manifest.reset(new blink::OriginManifest());
+
+ for (base::detail::dict_iterator_proxy::iterator it =
+ directives_dict->DictItems().begin();
+ it != directives_dict->DictItems().end(); ++it) {
+ switch (GetDirectiveType(it->first)) {
+ // content-security-policy
+ case DirectiveType::kContentSecurityPolicy:
+ ParseContentSecurityPolicy(origin_manifest.get(),
+ std::move(it->second));
+ break;
+ case DirectiveType::kUnknown:
+ // Ignore unknown directives for forward-compatibility
+ break;
+ }
+ }
+
+ return origin_manifest;
+}
+
+DirectiveType GetDirectiveType(const std::string& name) {
+ if (name == "content-security-policy") {
+ return DirectiveType::kContentSecurityPolicy;
+ }
+
+ return DirectiveType::kUnknown;
+}
+
+void ParseContentSecurityPolicy(blink::OriginManifest* const om,
+ base::Value value) {
+ // TODO give respective parsing errors
+ if (!value.is_list())
+ return;
+
+ for (auto& elem : value.GetList()) {
+ if (!elem.is_dict())
+ continue;
+
+ std::string policy = "";
+ blink::OriginManifest::ContentSecurityPolicyType disposition =
+ blink::OriginManifest::ContentSecurityPolicyType::kEnforce;
+ blink::OriginManifest::ActivationType activation_type =
+ blink::OriginManifest::ActivationType::kFallback;
+
+ const base::Value* v = elem.FindKey("policy");
+ if (v && v->is_string())
+ policy = v->GetString();
+
+ v = elem.FindKey("disposition");
+ if (v && v->is_string())
+ disposition = GetCSPDisposition(v->GetString());
+
+ v = elem.FindKey("allow-override");
+ if (v && v->is_bool()) {
+ activation_type = GetCSPActivationType(v->GetBool());
+ }
+
+ om->AddContentSecurityPolicy(policy, disposition, activation_type);
+ }
+}
+
+blink::OriginManifest::ContentSecurityPolicyType GetCSPDisposition(
+ const std::string& name) {
+ if (name == "enforce")
+ return blink::OriginManifest::ContentSecurityPolicyType::kEnforce;
+ if (name == "report-only")
+ return blink::OriginManifest::ContentSecurityPolicyType::kReport;
+
+ return blink::OriginManifest::ContentSecurityPolicyType::kEnforce;
+}
+
+blink::OriginManifest::ActivationType GetCSPActivationType(const bool value) {
+ if (value)
+ return blink::OriginManifest::ActivationType::kBaseline;
+
+ return blink::OriginManifest::ActivationType::kFallback;
+}
+
+} // namespace origin_manifest_parser
+} // namespace content
diff --git a/chromium/content/browser/origin_manifest/origin_manifest_parser.h b/chromium/content/browser/origin_manifest/origin_manifest_parser.h
new file mode 100644
index 00000000000..c937353e2c0
--- /dev/null
+++ b/chromium/content/browser/origin_manifest/origin_manifest_parser.h
@@ -0,0 +1,54 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ORIGIN_MANIFEST_ORIGIN_MANIFEST_PARSER_H_
+#define CONTENT_BROWSER_ORIGIN_MANIFEST_ORIGIN_MANIFEST_PARSER_H_
+
+#include <string>
+
+#include "base/values.h"
+#include "content/common/content_export.h"
+#include "third_party/WebKit/common/origin_manifest/origin_manifest.h"
+
+namespace base {
+class Value;
+}
+
+namespace content {
+namespace origin_manifest_parser {
+
+// Tries to parse an Origin Manifest from string. In case it fails the pointer
+// is set to nullptr.
+std::unique_ptr<blink::OriginManifest> CONTENT_EXPORT Parse(std::string json);
+
+enum class DirectiveType {
+ kContentSecurityPolicy,
+ kUnknown,
+};
+
+// Tries to parse the |DirectiveType| from string. Valid strings are all
+// top-level keywords from the Origin Manifest JSON format, e.g.
+// 'content-security-policy'. Returns kUnknown on failure.
+DirectiveType CONTENT_EXPORT GetDirectiveType(const std::string& str);
+
+// Reads out the values from |value| to add a ContentSecurityPolicy to the given
+// OriginManifest using its interface. In case invalid values are set they are
+// simply ignored. In case values are missing the respective default values are
+// set.
+void CONTENT_EXPORT ParseContentSecurityPolicy(blink::OriginManifest* const om,
+ base::Value value);
+
+// Tries to parse the |ContentSecurityPolicyType| from string. Valid values are
+// "enforce" and "report-only". Returns kUnknown on failure.
+blink::OriginManifest::ContentSecurityPolicyType CONTENT_EXPORT
+GetCSPDisposition(const std::string& json);
+
+// If |value| is true returns kBaseline, kFallback otherwise.
+blink::OriginManifest::ActivationType CONTENT_EXPORT
+GetCSPActivationType(const bool value);
+
+} // namespace origin_manifest_parser
+} // namespace content
+
+#endif // CONTENT_BROWSER_ORIGIN_MANIFEST_ORIGIN_MANIFEST_PARSER_H_
diff --git a/chromium/content/browser/origin_manifest/origin_manifest_parser_unittest.cc b/chromium/content/browser/origin_manifest/origin_manifest_parser_unittest.cc
new file mode 100644
index 00000000000..5f12ec7bac8
--- /dev/null
+++ b/chromium/content/browser/origin_manifest/origin_manifest_parser_unittest.cc
@@ -0,0 +1,386 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdio.h>
+
+#include "content/browser/origin_manifest/origin_manifest_parser.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace origin_manifest_parser {
+
+class OriginManifestParserTest : public testing::Test {};
+
+// Note that we do not initialize the persistent store here since that
+// is subject to testing the persistent store itself.
+
+TEST_F(OriginManifestParserTest, ParsingSuccess) {
+ // basically it should only create an Origin Manifest on valid JSON
+ struct TestCase {
+ std::string json;
+ bool equalsNull;
+ } cases[] = {
+ {"", true},
+ {"{ \"I am not valid\"", true},
+ {"{ }", false},
+ {"{ \"valid\": \"JSON\", \"but\": [\"unknown\", \"structure\"] }", false},
+ {"{ \"tls\": {}, \"tls\": {} }", false}};
+
+ for (const auto& test : cases) {
+ EXPECT_EQ(Parse(test.json).get() == nullptr, test.equalsNull);
+ }
+}
+
+TEST_F(OriginManifestParserTest, ParseCSPWithUnexpectedSyntax) {
+ // CSP value not a list
+ std::string json = "{ \"content-security-policy\": 42 }";
+ std::unique_ptr<blink::OriginManifest> om = Parse(json);
+ ASSERT_FALSE(om.get() == nullptr);
+ EXPECT_EQ(om->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks)
+ .size(),
+ 0ul);
+
+ // not a list of objects but directly the CSP attributes
+ json =
+ "{ \"content-security-policy\": [ \"this is not the content\", \"you are "
+ "looking for\" ] }";
+ om = Parse(json);
+ ASSERT_FALSE(om.get() == nullptr);
+ EXPECT_EQ(om->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks)
+ .size(),
+ 0ul);
+
+ // CSP alongside unknown attributes should be fine
+ json =
+ "{ "
+ "\"unknown\": 42,"
+ "\"content-security-policy\": ["
+ " { \"policy\": \"default-src 'none'\" },"
+ "],"
+ "\"hardcore\": \"unknown\","
+ " }";
+ om = Parse(json);
+ ASSERT_FALSE(om.get() == nullptr);
+ EXPECT_EQ(om->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks)
+ .size(),
+ 1ul);
+
+ // containing unknown attributes should be fine
+ json =
+ "{ "
+ "\"content-security-policy\": [ {"
+ " \"unknown\": 42,"
+ " \"policy\": \"default-src 'none'\","
+ " \"hardcore\": \"unknown\","
+ " } ],"
+ "}";
+ om = Parse(json);
+ ASSERT_FALSE(om.get() == nullptr);
+ EXPECT_EQ(om->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks)
+ .size(),
+ 1ul);
+ EXPECT_EQ(
+ om->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks)[0]
+ .policy,
+ "default-src 'none'");
+
+ // multiple CSPs
+ json =
+ "{ \"content-security-policy\": ["
+ "{ \"policy\": \"default-src 'none'\" },"
+ "{ \"policy\": \"default-src 'none'\" }"
+ "] }";
+ om = Parse(json);
+ ASSERT_FALSE(om.get() == nullptr);
+ EXPECT_EQ(om->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks)
+ .size(),
+ 2ul);
+}
+
+TEST_F(OriginManifestParserTest, ParseCSPWithMissingAttributes) {
+ // invalid values are tested separately below, no need to re-test it here
+ struct TestCase {
+ std::string policy;
+ std::string disposition;
+ std::string allow_override;
+ std::string expected_policy;
+ blink::OriginManifest::ContentSecurityPolicyType expected_disposition;
+ bool expected_allow_override;
+ } cases[] = {
+ {"", "", "", "",
+ blink::OriginManifest::ContentSecurityPolicyType::kEnforce, false},
+ {"", "report-only", "true", "",
+ blink::OriginManifest::ContentSecurityPolicyType::kReport, true},
+ {"", "", "true", "",
+ blink::OriginManifest::ContentSecurityPolicyType::kEnforce, true},
+ {"", "report-only", "", "",
+ blink::OriginManifest::ContentSecurityPolicyType::kReport, false},
+ {"default-src 'none'", "", "true", "default-src 'none'",
+ blink::OriginManifest::ContentSecurityPolicyType::kEnforce, true},
+ {"default-src 'none'", "", "", "default-src 'none'",
+ blink::OriginManifest::ContentSecurityPolicyType::kEnforce, false},
+ {"default-src 'none'", "report-only", "", "default-src 'none'",
+ blink::OriginManifest::ContentSecurityPolicyType::kReport, false},
+ {"default-src 'none'", "report-only", "true", "default-src 'none'",
+ blink::OriginManifest::ContentSecurityPolicyType::kReport, true},
+ };
+
+ for (const auto& test : cases) {
+ std::ostringstream str_stream;
+ str_stream << "{ \"content-security-policy\": [ {";
+ if (test.policy.length() > 0)
+ str_stream << "\"policy\": \"" << test.policy << "\", ";
+ if (test.disposition.length() > 0)
+ str_stream << "\"disposition\": \"" << test.disposition << "\", ";
+ if (test.allow_override.length() > 0)
+ str_stream << "\"allow-override\": " << test.allow_override << ", ";
+ str_stream << "}, ] }";
+
+ std::unique_ptr<blink::OriginManifest> om = Parse(str_stream.str());
+
+ ASSERT_FALSE(om.get() == nullptr);
+ std::vector<blink::OriginManifest::ContentSecurityPolicy>
+ baseline_fallback = om->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks);
+ ASSERT_EQ(baseline_fallback.size(), 1ul);
+
+ EXPECT_EQ(baseline_fallback[0].policy, test.expected_policy);
+ EXPECT_EQ(baseline_fallback[0].disposition, test.expected_disposition);
+
+ // if override is not allowed it is a fallback and baseline should be empty
+ std::vector<blink::OriginManifest::ContentSecurityPolicy> baseline =
+ om->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kBaselineOnly);
+ EXPECT_EQ(baseline.size(), (test.expected_allow_override) ? 1ul : 0ul);
+ }
+}
+
+TEST_F(OriginManifestParserTest, GetDirectiveType) {
+ DirectiveType type = GetDirectiveType("content-security-policy");
+ EXPECT_EQ(type, DirectiveType::kContentSecurityPolicy);
+
+ type = GetDirectiveType("asdf");
+ EXPECT_EQ(type, DirectiveType::kUnknown);
+}
+
+TEST_F(OriginManifestParserTest, GetCSPDisposition) {
+ blink::OriginManifest::ContentSecurityPolicyType type =
+ GetCSPDisposition("enforce");
+ EXPECT_EQ(type, blink::OriginManifest::ContentSecurityPolicyType::kEnforce);
+
+ type = GetCSPDisposition("report-only");
+ EXPECT_EQ(type, blink::OriginManifest::ContentSecurityPolicyType::kReport);
+
+ type = GetCSPDisposition("");
+ EXPECT_EQ(type, blink::OriginManifest::ContentSecurityPolicyType::kEnforce);
+
+ type = GetCSPDisposition("asdf");
+ EXPECT_EQ(type, blink::OriginManifest::ContentSecurityPolicyType::kEnforce);
+}
+
+TEST_F(OriginManifestParserTest, GetCSPActivationType) {
+ // the function returns the right values
+ EXPECT_EQ(GetCSPActivationType(true),
+ blink::OriginManifest::ActivationType::kBaseline);
+ EXPECT_EQ(GetCSPActivationType(false),
+ blink::OriginManifest::ActivationType::kFallback);
+
+ // check different manifest values in JSON
+ struct TestCase {
+ std::string value;
+ unsigned long expected_baseline_only_size;
+ unsigned long expected_include_fallbacks_size;
+ } tests[]{
+ {"true", 1, 1}, {"false", 0, 1}, {"42", 0, 1},
+ };
+
+ for (auto test : tests) {
+ std::ostringstream str_stream;
+ str_stream << "{ \"content-security-policy\": [ {"
+ << " \"allow-override\": " << test.value << ", "
+ << "}, ] }";
+
+ std::unique_ptr<blink::OriginManifest> om = Parse(str_stream.str());
+ // more details are checked in origin manifest unit tests
+ EXPECT_EQ(om->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kBaselineOnly)
+ .size(),
+ test.expected_baseline_only_size);
+ EXPECT_EQ(
+ om->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks)
+ .size(),
+ test.expected_include_fallbacks_size);
+ }
+}
+
+TEST_F(OriginManifestParserTest, ParseContentSecurityPolicy) {
+ // Wrong structure
+ blink::OriginManifest om;
+ base::Value dict(base::Value::Type::DICTIONARY);
+ ParseContentSecurityPolicy(&om, std::move(dict));
+ EXPECT_EQ(om.GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks)
+ .size(),
+ 0ul);
+
+ // empty list
+ om = blink::OriginManifest();
+ base::Value list(base::Value::Type::LIST);
+ ParseContentSecurityPolicy(&om, std::move(list));
+ EXPECT_EQ(om.GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks)
+ .size(),
+ 0ul);
+
+ // list with completely unexpected element
+ om = blink::OriginManifest();
+ list = base::Value(base::Value::Type::LIST);
+ list.GetList().push_back(base::Value(42));
+ ParseContentSecurityPolicy(&om, std::move(list));
+ EXPECT_EQ(om.GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks)
+ .size(),
+ 0ul);
+
+ // list with 1 valid, 2 invalid CSPs -> 3 policies (we don't validate CSPs)
+ om = blink::OriginManifest();
+ list = base::Value(base::Value::Type::LIST);
+
+ std::string policy0 = "default-src 'none'";
+ std::string policy1 = "";
+ std::string policy2 = "asdf";
+
+ base::Value csp0(base::Value::Type::DICTIONARY);
+ csp0.SetKey("policy", base::Value(policy0));
+ csp0.SetKey("disposition", base::Value("report-only"));
+ csp0.SetKey("allow-override", base::Value(true));
+ list.GetList().push_back(std::move(csp0));
+
+ base::Value csp1(base::Value::Type::DICTIONARY);
+ csp1.SetKey("policy", base::Value(policy1));
+ csp1.SetKey("disposition", base::Value(23));
+ csp1.SetKey("allow-override", base::Value(42));
+ list.GetList().push_back(std::move(csp1));
+
+ base::Value csp2(base::Value::Type::DICTIONARY);
+ csp2.SetKey("policy", base::Value(policy2));
+ list.GetList().push_back(std::move(csp2));
+
+ ParseContentSecurityPolicy(&om, std::move(list));
+
+ std::vector<blink::OriginManifest::ContentSecurityPolicy> baseline =
+ om.GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kBaselineOnly);
+ ASSERT_EQ(baseline.size(), 1ul);
+ EXPECT_TRUE(baseline[0].policy == policy0);
+
+ // we know that every CSP s a dictionary and has a unique policy here.
+ std::vector<blink::OriginManifest::ContentSecurityPolicy> baseline_fallback =
+ om.GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks);
+ ASSERT_EQ(baseline_fallback.size(), 3ul);
+ std::vector<blink::OriginManifest::ContentSecurityPolicy>::iterator it;
+ for (it = baseline_fallback.begin(); it != baseline_fallback.end(); ++it) {
+ if (it->policy == policy0)
+ break;
+ }
+ ASSERT_FALSE(it == baseline_fallback.end());
+ baseline_fallback.erase(it);
+ if (baseline_fallback[0].policy == policy1)
+ EXPECT_TRUE(baseline_fallback[1].policy == policy2);
+ else
+ EXPECT_TRUE(baseline_fallback[0].policy == policy1);
+}
+
+TEST_F(OriginManifestParserTest, CaseSensitiveKeys) {
+ struct TestCase {
+ std::string policy;
+ std::string expected_equivalent_policy;
+ } tests[]{
+ {"{ \"Content-Security-Policy\": [{ \"policy\": \"asdf\"}] }", "{}"},
+ {"{ \"content-security-policy\": [{ \"PoLiCy\": \"asdf\"}] }",
+ "{ \"content-security-policy\": [{}] }"},
+ {"{ \"content-security-policy\": [{ \"DiSpOsItIoN\": \"enforce\" }] }",
+ "{ \"content-security-policy\": [{}] }"},
+ {"{ \"content-security-policy\": [{ \"disposition\": \"EnFoRcE\" }] }",
+ "{ \"content-security-policy\": [{}] }"},
+ {"{ \"content-security-policy\": [{ \"disposition\": \"RePoRt-OnLy\" }] "
+ "}",
+ "{ \"content-security-policy\": [{}] }"},
+ {"{ \"content-security-policy\": [{ \"AlLoW-OvErRiDe\": true }] }",
+ "{ \"content-security-policy\": [{}] }"},
+ };
+
+ for (const auto& test : tests) {
+ std::unique_ptr<blink::OriginManifest> bad_case = Parse(test.policy);
+ std::unique_ptr<blink::OriginManifest> expected =
+ Parse(test.expected_equivalent_policy);
+
+ ASSERT_TRUE(bad_case.get() != nullptr);
+ ASSERT_TRUE(expected.get() != nullptr);
+
+ std::vector<blink::OriginManifest::ContentSecurityPolicy> bad_case_csps =
+ bad_case->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks);
+ std::vector<blink::OriginManifest::ContentSecurityPolicy> expected_csps =
+ expected->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks);
+
+ ASSERT_EQ(bad_case_csps.size(), expected_csps.size());
+
+ for (unsigned long i = 0; i < bad_case_csps.size(); ++i) {
+ EXPECT_EQ(bad_case_csps[i].policy, expected_csps[i].policy);
+ EXPECT_EQ(bad_case_csps[i].disposition, expected_csps[i].disposition);
+ }
+ }
+}
+
+TEST_F(OriginManifestParserTest, MultiDefinitions) {
+ struct TestCase {
+ std::string policy;
+ std::string expected_equivalent_policy;
+ } tests[]{
+ {"{ \"content-security-policy\": [{ \"policy\": \"first\"}], "
+ " \"content-security-policy\": [{ \"policy\": \"second\"}] }",
+ "{ \"content-security-policy\": [{ \"policy\": \"second\"}] }"},
+
+ {"{ \"content-security-policy\": [{ \"policy\": \"first\", \"policy\": "
+ "\"second\"}] }",
+ "{ \"content-security-policy\": [{ \"policy\": \"second\"}] }"},
+ };
+
+ for (const auto& test : tests) {
+ std::unique_ptr<blink::OriginManifest> multi = Parse(test.policy);
+ std::unique_ptr<blink::OriginManifest> expected =
+ Parse(test.expected_equivalent_policy);
+
+ ASSERT_TRUE(multi.get() != nullptr);
+ ASSERT_TRUE(expected.get() != nullptr);
+
+ std::vector<blink::OriginManifest::ContentSecurityPolicy> multi_csps =
+ multi->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks);
+ std::vector<blink::OriginManifest::ContentSecurityPolicy> expected_csps =
+ expected->GetContentSecurityPolicies(
+ blink::OriginManifest::FallbackDisposition::kIncludeFallbacks);
+
+ ASSERT_EQ(multi_csps.size(), expected_csps.size());
+
+ for (unsigned long i = 0; i < multi_csps.size(); ++i) {
+ EXPECT_EQ(multi_csps[i].policy, expected_csps[i].policy);
+ EXPECT_EQ(multi_csps[i].disposition, expected_csps[i].disposition);
+ }
+ }
+}
+
+} // namespace origin_manifest_parser
+} // namespace content
diff --git a/chromium/content/browser/payments/payment_app.proto b/chromium/content/browser/payments/payment_app.proto
index 37bac6c0350..3a357433d41 100644
--- a/chromium/content/browser/payments/payment_app.proto
+++ b/chromium/content/browser/payments/payment_app.proto
@@ -32,6 +32,8 @@ message StoredPaymentInstrumentProto {
optional string stringified_capabilities = 5;
repeated StoredPaymentInstrumentImageObject icons = 6;
optional string decoded_instrument_icon = 7;
+ repeated int32 supported_card_networks = 8;
+ repeated int32 supported_card_types = 9;
}
message StoredRelatedApplicationProto {
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 97840f7d015..50a73bf4e16 100644
--- a/chromium/content/browser/payments/payment_app_content_unittest_base.cc
+++ b/chromium/content/browser/payments/payment_app_content_unittest_base.cc
@@ -64,9 +64,12 @@ class PaymentAppContentUnitTestBase::PaymentAppForWorkerTestHelper
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info)
override {
ServiceWorkerVersion* version =
context()->GetLiveVersion(service_worker_version_id);
@@ -74,8 +77,10 @@ class PaymentAppContentUnitTestBase::PaymentAppForWorkerTestHelper
last_sw_scope_ = scope;
EmbeddedWorkerTestHelper::OnStartWorker(
embedded_worker_id, service_worker_version_id, scope, script_url,
- pause_after_download, std::move(request), std::move(instance_host),
- std::move(provider_info));
+ pause_after_download, std::move(dispatcher_request),
+ std::move(controller_request), std::move(service_worker_host),
+ std::move(instance_host), std::move(provider_info),
+ std::move(installed_scripts_info));
}
void OnPaymentRequestEvent(
diff --git a/chromium/content/browser/payments/payment_app_context_impl.cc b/chromium/content/browser/payments/payment_app_context_impl.cc
index de6c443fa37..8a2f0597503 100644
--- a/chromium/content/browser/payments/payment_app_context_impl.cc
+++ b/chromium/content/browser/payments/payment_app_context_impl.cc
@@ -70,7 +70,7 @@ void PaymentAppContextImpl::CreatePaymentAppDatabaseOnIO(
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
payment_app_database_ =
- base::MakeUnique<PaymentAppDatabase>(service_worker_context);
+ std::make_unique<PaymentAppDatabase>(service_worker_context);
}
void PaymentAppContextImpl::CreatePaymentManagerOnIO(
diff --git a/chromium/content/browser/payments/payment_app_database.cc b/chromium/content/browser/payments/payment_app_database.cc
index 037640ea9df..171848f9553 100644
--- a/chromium/content/browser/payments/payment_app_database.cc
+++ b/chromium/content/browser/payments/payment_app_database.cc
@@ -93,7 +93,7 @@ std::unique_ptr<StoredPaymentApp> ToStoredPaymentApp(const std::string& input) {
if (!app_proto.ParseFromString(input))
return std::unique_ptr<StoredPaymentApp>();
- std::unique_ptr<StoredPaymentApp> app = base::MakeUnique<StoredPaymentApp>();
+ std::unique_ptr<StoredPaymentApp> app = std::make_unique<StoredPaymentApp>();
app->registration_id = app_proto.registration_id();
app->scope = GURL(app_proto.scope());
app->name = app_proto.name();
@@ -113,7 +113,7 @@ std::unique_ptr<StoredPaymentApp> ToStoredPaymentApp(const std::string& input) {
gfx::Image icon_image = gfx::Image::CreateFrom1xPNGBytes(
reinterpret_cast<const unsigned char*>(icon_raw_data.data()),
icon_raw_data.size());
- app->icon = base::MakeUnique<SkBitmap>(icon_image.AsBitmap());
+ app->icon = std::make_unique<SkBitmap>(icon_image.AsBitmap());
}
return app;
@@ -460,6 +460,15 @@ void PaymentAppDatabase::DidReadAllPaymentInstruments(
for (const auto& method : instrument_proto.enabled_methods()) {
apps[id]->enabled_methods.push_back(method);
}
+
+ apps[id]->capabilities.emplace_back(StoredCapabilities());
+ for (const auto& network : instrument_proto.supported_card_networks()) {
+ apps[id]->capabilities.back().supported_card_networks.emplace_back(
+ network);
+ }
+ for (const auto& type : instrument_proto.supported_card_types()) {
+ apps[id]->capabilities.back().supported_card_types.emplace_back(type);
+ }
}
std::move(callback).Run(std::move(apps));
@@ -655,6 +664,12 @@ void PaymentAppDatabase::DidFindRegistrationToWritePaymentInstrument(
}
instrument_proto.set_stringified_capabilities(
instrument->stringified_capabilities);
+ for (const auto& network : instrument->supported_networks) {
+ instrument_proto.add_supported_card_networks(static_cast<int32_t>(network));
+ }
+ for (const auto& type : instrument->supported_types) {
+ instrument_proto.add_supported_card_types(static_cast<int32_t>(type));
+ }
std::string serialized_instrument;
bool success = instrument_proto.SerializeToString(&serialized_instrument);
diff --git a/chromium/content/browser/payments/payment_app_info_fetcher.cc b/chromium/content/browser/payments/payment_app_info_fetcher.cc
index 6a3e00503ad..b57e83b01b5 100644
--- a/chromium/content/browser/payments/payment_app_info_fetcher.cc
+++ b/chromium/content/browser/payments/payment_app_info_fetcher.cc
@@ -12,18 +12,17 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/manifest_icon_downloader.h"
#include "content/public/browser/manifest_icon_selector.h"
+#include "content/public/common/console_message_level.h"
#include "ui/gfx/image/image.h"
namespace content {
+PaymentAppInfoFetcher::PaymentAppInfoFetcher()
+ : fetched_payment_app_info_(std::make_unique<PaymentAppInfo>()) {}
+
PaymentAppInfoFetcher::PaymentAppInfo::PaymentAppInfo() {}
-PaymentAppInfoFetcher::PaymentAppInfo::~PaymentAppInfo() {}
-PaymentAppInfoFetcher::PaymentAppInfoFetcher()
- : context_process_id_(-1),
- context_frame_id_(-1),
- fetched_payment_app_info_(base::MakeUnique<PaymentAppInfo>()) {}
-PaymentAppInfoFetcher::~PaymentAppInfoFetcher() {}
+PaymentAppInfoFetcher::PaymentAppInfo::~PaymentAppInfo() {}
void PaymentAppInfoFetcher::Start(
const GURL& context_url,
@@ -43,6 +42,14 @@ void PaymentAppInfoFetcher::Start(
std::move(provider_hosts)));
}
+PaymentAppInfoFetcher::WebContentsHelper::WebContentsHelper(
+ WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+
+PaymentAppInfoFetcher::WebContentsHelper::~WebContentsHelper() {}
+
+PaymentAppInfoFetcher::~PaymentAppInfoFetcher() {}
+
void PaymentAppInfoFetcher::StartFromUIThread(
const std::unique_ptr<std::vector<std::pair<int, int>>>& provider_hosts) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -66,8 +73,7 @@ void PaymentAppInfoFetcher::StartFromUIThread(
continue;
}
- context_process_id_ = frame.first;
- context_frame_id_ = frame.second;
+ web_contents_helper_ = std::make_unique<WebContentsHelper>(web_content);
web_content->GetManifest(base::Bind(
&PaymentAppInfoFetcher::FetchPaymentAppManifestCallback, this));
@@ -82,7 +88,26 @@ void PaymentAppInfoFetcher::FetchPaymentAppManifestCallback(
const Manifest& manifest) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (url.is_empty() || manifest.IsEmpty()) {
+ manifest_url_ = url;
+ if (manifest_url_.is_empty()) {
+ WarnIfPossible(
+ "The page that installed the payment handler does not contain a web "
+ "app manifest link: <link rel=\"manifest\" "
+ "href=\"some-file-name-here\">. This manifest defines the payment "
+ "handler's name and icon. User may not recognize this payment handler "
+ "in UI, because it will be labeled only by its origin.");
+ PostPaymentAppInfoFetchResultToIOThread();
+ return;
+ }
+
+ if (manifest.IsEmpty()) {
+ WarnIfPossible(
+ "Unable to download a valid payment handler web app manifest from \"" +
+ manifest_url_.spec() +
+ "\". This manifest cannot be empty and must in JSON format. The "
+ "manifest defines the payment handler's name and icon. User may not "
+ "recognize this payment handler in UI, because it will be labeled only "
+ "by its origin.");
PostPaymentAppInfoFetchResultToIOThread();
return;
}
@@ -106,12 +131,22 @@ void PaymentAppInfoFetcher::FetchPaymentAppManifestCallback(
}
}
- if (manifest.name.is_null() ||
- !base::UTF16ToUTF8(manifest.name.string().c_str(),
- manifest.name.string().length(),
- &(fetched_payment_app_info_->name))) {
- PostPaymentAppInfoFetchResultToIOThread();
- return;
+ if (manifest.name.is_null()) {
+ WarnIfPossible("The payment handler's web app manifest \"" +
+ manifest_url_.spec() +
+ "\" does not contain a \"name\" field. User may not "
+ "recognize this payment handler in UI, because it will be "
+ "labeled only by its origin.");
+ } else if (manifest.name.string().empty()) {
+ WarnIfPossible(
+ "The \"name\" field in the payment handler's web app manifest \"" +
+ manifest_url_.spec() +
+ "\" is empty. User may not recognize this payment handler in UI, "
+ "because it will be labeled only by its origin.");
+ } else {
+ base::UTF16ToUTF8(manifest.name.string().c_str(),
+ manifest.name.string().length(),
+ &(fetched_payment_app_info_->name));
}
// TODO(gogerald): Choose appropriate icon size dynamically on different
@@ -121,40 +156,61 @@ void PaymentAppInfoFetcher::FetchPaymentAppManifestCallback(
const int kPaymentAppIdealIconSize = 0xFFFF;
const int kPaymentAppMinimumIconSize = 0;
- GURL icon_url = ManifestIconSelector::FindBestMatchingIcon(
- manifest.icons, kPaymentAppIdealIconSize, kPaymentAppMinimumIconSize,
- Manifest::Icon::ANY);
- if (!icon_url.is_valid()) {
+ if (manifest.icons.empty()) {
+ WarnIfPossible(
+ "Unable to download the payment handler's icon, because the web app "
+ "manifest \"" +
+ manifest_url_.spec() +
+ "\" does not contain an \"icons\" field with a valid URL in \"src\" "
+ "sub-field. User may not recognize this payment handler in UI.");
PostPaymentAppInfoFetchResultToIOThread();
return;
}
- RenderFrameHostImpl* render_frame_host =
- RenderFrameHostImpl::FromID(context_process_id_, context_frame_id_);
- if (!render_frame_host) {
+ icon_url_ = ManifestIconSelector::FindBestMatchingIcon(
+ manifest.icons, kPaymentAppIdealIconSize, kPaymentAppMinimumIconSize,
+ Manifest::Icon::ANY);
+ if (!icon_url_.is_valid()) {
+ WarnIfPossible(
+ "No suitable payment handler icon found in the \"icons\" field defined "
+ "in the web app manifest \"" +
+ manifest_url_.spec() +
+ "\". This is most likely due to unsupported MIME types in the "
+ "\"icons\" field. User may not recognize this payment handler in UI.");
PostPaymentAppInfoFetchResultToIOThread();
return;
}
- WebContents* web_content =
- WebContents::FromRenderFrameHost(render_frame_host);
- if (!web_content) {
+ if (!web_contents_helper_->web_contents()) {
+ LOG(WARNING) << "Unable to download the payment handler's icon because no "
+ "renderer was found, possibly because the page was closed "
+ "or navigated away during installation. User may not "
+ "recognize this payment handler in UI, because it will be "
+ "labeled only by its name and origin.";
PostPaymentAppInfoFetchResultToIOThread();
return;
}
- if (!content::ManifestIconDownloader::Download(
- web_content, icon_url, kPaymentAppIdealIconSize,
- kPaymentAppMinimumIconSize,
- base::Bind(&PaymentAppInfoFetcher::OnIconFetched, this))) {
- PostPaymentAppInfoFetchResultToIOThread();
- }
+ bool can_download = content::ManifestIconDownloader::Download(
+ web_contents_helper_->web_contents(), icon_url_, kPaymentAppIdealIconSize,
+ kPaymentAppMinimumIconSize,
+ base::Bind(&PaymentAppInfoFetcher::OnIconFetched, this));
+ // |can_download| is false only if web contents are null or the icon URL is
+ // not valid. Both of these conditions are manually checked above, so
+ // |can_download| should never be false. The manual checks above are necessary
+ // to provide more detailed error messages.
+ DCHECK(can_download);
}
void PaymentAppInfoFetcher::OnIconFetched(const SkBitmap& icon) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (icon.drawsNothing()) {
+ WarnIfPossible("Unable to download a valid payment handler icon from \"" +
+ icon_url_.spec() +
+ "\", which is defined in the web app manifest \"" +
+ manifest_url_.spec() +
+ "\". User may not recognize this payment handler in UI.");
PostPaymentAppInfoFetchResultToIOThread();
return;
}
@@ -175,4 +231,16 @@ void PaymentAppInfoFetcher::PostPaymentAppInfoFetchResultToIOThread() {
std::move(fetched_payment_app_info_)));
}
+void PaymentAppInfoFetcher::WarnIfPossible(const std::string& message) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(web_contents_helper_);
+
+ if (web_contents_helper_->web_contents()) {
+ web_contents_helper_->web_contents()->GetMainFrame()->AddMessageToConsole(
+ CONSOLE_MESSAGE_LEVEL_WARNING, message);
+ } else {
+ LOG(WARNING) << message;
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/payments/payment_app_info_fetcher.h b/chromium/content/browser/payments/payment_app_info_fetcher.h
index 9d11b83de6c..ebb7aac1676 100644
--- a/chromium/content/browser/payments/payment_app_info_fetcher.h
+++ b/chromium/content/browser/payments/payment_app_info_fetcher.h
@@ -5,12 +5,14 @@
#ifndef CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_INFO_FETCHER_H_
#define CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_INFO_FETCHER_H_
+#include <memory>
#include <string>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/stored_payment_app.h"
+#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/manifest.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -38,6 +40,14 @@ class PaymentAppInfoFetcher
private:
friend class base::RefCountedThreadSafe<PaymentAppInfoFetcher>;
+
+ // Keeps track of the web contents.
+ class WebContentsHelper : public WebContentsObserver {
+ public:
+ explicit WebContentsHelper(WebContents* web_contents);
+ ~WebContentsHelper() override;
+ };
+
~PaymentAppInfoFetcher();
void StartFromUIThread(
@@ -51,12 +61,17 @@ class PaymentAppInfoFetcher
void OnIconFetched(const SkBitmap& icon);
void PostPaymentAppInfoFetchResultToIOThread();
+ // Prints the warning |message| in the DevTools console, if possible.
+ // Otherwise logs the warning on command line.
+ void WarnIfPossible(const std::string& message);
+
GURL context_url_;
PaymentAppInfoFetchCallback callback_;
- int context_process_id_;
- int context_frame_id_;
+ std::unique_ptr<WebContentsHelper> web_contents_helper_;
std::unique_ptr<PaymentAppInfo> fetched_payment_app_info_;
+ GURL manifest_url_;
+ GURL icon_url_;
DISALLOW_COPY_AND_ASSIGN(PaymentAppInfoFetcher);
};
diff --git a/chromium/content/browser/payments/payment_app_provider_impl.cc b/chromium/content/browser/payments/payment_app_provider_impl.cc
index 337411c80e5..8816724941f 100644
--- a/chromium/content/browser/payments/payment_app_provider_impl.cc
+++ b/chromium/content/browser/payments/payment_app_provider_impl.cc
@@ -16,6 +16,7 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "mojo/common/time.mojom.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
namespace content {
namespace {
@@ -141,7 +142,7 @@ class RespondWithCallbacks
std::vector<std::pair<int, int>> ids;
for (const auto& controllee : service_worker_version_->controllee_map()) {
if (controllee.second->provider_type() ==
- SERVICE_WORKER_PROVIDER_FOR_WINDOW) {
+ blink::mojom::ServiceWorkerProviderType::kForWindow) {
ids.emplace_back(std::make_pair(controllee.second->process_id(),
controllee.second->frame_id()));
}
diff --git a/chromium/content/browser/payments/payment_app_provider_impl_unittest.cc b/chromium/content/browser/payments/payment_app_provider_impl_unittest.cc
index 5aef1d2e88e..aca22ef2092 100644
--- a/chromium/content/browser/payments/payment_app_provider_impl_unittest.cc
+++ b/chromium/content/browser/payments/payment_app_provider_impl_unittest.cc
@@ -40,9 +40,11 @@ void InvokePaymentAppCallback(
*called = true;
}
-void PaymentEventResultCallback(bool* out_payment_event_result,
+void PaymentEventResultCallback(base::OnceClosure callback,
+ bool* out_payment_event_result,
bool payment_event_result) {
*out_payment_event_result = payment_event_result;
+ std::move(callback).Run();
}
} // namespace
@@ -85,14 +87,12 @@ class PaymentAppProviderTest : public PaymentAppContentUnitTestBase {
PaymentAppProviderImpl::GetInstance()->CanMakePayment(
browser_context(), registration_id, std::move(event_data),
std::move(callback));
- base::RunLoop().RunUntilIdle();
}
void AbortPayment(int64_t registration_id,
PaymentAppProvider::PaymentEventResultCallback callback) {
PaymentAppProviderImpl::GetInstance()->AbortPayment(
browser_context(), registration_id, std::move(callback));
- base::RunLoop().RunUntilIdle();
}
private:
@@ -113,8 +113,11 @@ TEST_F(PaymentAppProviderTest, AbortPaymentTest) {
ASSERT_EQ(1U, apps.size());
bool payment_aborted = false;
+ base::RunLoop loop;
AbortPayment(last_sw_registration_id(),
- base::BindOnce(&PaymentEventResultCallback, &payment_aborted));
+ base::BindOnce(&PaymentEventResultCallback, loop.QuitClosure(),
+ &payment_aborted));
+ loop.Run();
ASSERT_TRUE(payment_aborted);
}
@@ -139,9 +142,11 @@ TEST_F(PaymentAppProviderTest, CanMakePaymentTest) {
event_data->method_data.push_back(std::move(methodData));
bool can_make_payment = false;
- CanMakePayment(
- last_sw_registration_id(), std::move(event_data),
- base::BindOnce(&PaymentEventResultCallback, &can_make_payment));
+ base::RunLoop loop;
+ CanMakePayment(last_sw_registration_id(), std::move(event_data),
+ base::BindOnce(&PaymentEventResultCallback, loop.QuitClosure(),
+ &can_make_payment));
+ loop.Run();
ASSERT_TRUE(can_make_payment);
}
diff --git a/chromium/content/browser/pepper_flash_settings_helper_impl.cc b/chromium/content/browser/pepper_flash_settings_helper_impl.cc
index 70092dd03bf..f2f0f8af00c 100644
--- a/chromium/content/browser/pepper_flash_settings_helper_impl.cc
+++ b/chromium/content/browser/pepper_flash_settings_helper_impl.cc
@@ -38,7 +38,7 @@ void PepperFlashSettingsHelperImpl::OpenChannelToBroker(
callback_ = callback;
PluginServiceImpl* plugin_service = PluginServiceImpl::GetInstance();
- plugin_service->OpenChannelToPpapiBroker(0, path, this);
+ plugin_service->OpenChannelToPpapiBroker(0, 0, path, this);
}
void PepperFlashSettingsHelperImpl::GetPpapiChannelInfo(
diff --git a/chromium/content/browser/permissions/permission_service_context.cc b/chromium/content/browser/permissions/permission_service_context.cc
index 2b42bcf7743..e4f237e46c0 100644
--- a/chromium/content/browser/permissions/permission_service_context.cc
+++ b/chromium/content/browser/permissions/permission_service_context.cc
@@ -72,7 +72,7 @@ PermissionServiceContext::~PermissionServiceContext() {
void PermissionServiceContext::CreateService(
blink::mojom::PermissionServiceRequest request) {
- services_.AddBinding(base::MakeUnique<PermissionServiceImpl>(this),
+ services_.AddBinding(std::make_unique<PermissionServiceImpl>(this),
std::move(request));
}
@@ -85,7 +85,7 @@ void PermissionServiceContext::CreateSubscription(
return;
auto subscription =
- base::MakeUnique<PermissionSubscription>(this, std::move(observer));
+ std::make_unique<PermissionSubscription>(this, std::move(observer));
GURL requesting_origin(origin.Serialize());
GURL embedding_origin = GetEmbeddingOrigin();
int subscription_id =
diff --git a/chromium/content/browser/permissions/permission_service_impl.cc b/chromium/content/browser/permissions/permission_service_impl.cc
index f306f7d082e..97e3e8bab87 100644
--- a/chromium/content/browser/permissions/permission_service_impl.cc
+++ b/chromium/content/browser/permissions/permission_service_impl.cc
@@ -17,7 +17,7 @@
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_features.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
using blink::mojom::PermissionDescriptorPtr;
using blink::mojom::PermissionName;
@@ -35,8 +35,6 @@ PermissionType PermissionDescriptorToPermissionType(
return PermissionType::GEOLOCATION;
case PermissionName::NOTIFICATIONS:
return PermissionType::NOTIFICATIONS;
- case PermissionName::PUSH_NOTIFICATIONS:
- return PermissionType::PUSH_MESSAGING;
case PermissionName::MIDI: {
if (descriptor->extension && descriptor->extension->is_midi() &&
descriptor->extension->get_midi()->sysex) {
@@ -58,40 +56,45 @@ PermissionType PermissionDescriptorToPermissionType(
return PermissionType::SENSORS;
case PermissionName::ACCESSIBILITY_EVENTS:
return PermissionType::ACCESSIBILITY_EVENTS;
+ case PermissionName::CLIPBOARD_READ:
+ return PermissionType::CLIPBOARD_READ;
+ case PermissionName::CLIPBOARD_WRITE:
+ return PermissionType::CLIPBOARD_WRITE;
}
NOTREACHED();
return PermissionType::NUM;
}
-blink::WebFeaturePolicyFeature PermissionTypeToFeaturePolicyFeature(
+blink::FeaturePolicyFeature PermissionTypeToFeaturePolicyFeature(
PermissionType type) {
switch (type) {
case PermissionType::MIDI:
case PermissionType::MIDI_SYSEX:
- return blink::WebFeaturePolicyFeature::kMidiFeature;
+ return blink::FeaturePolicyFeature::kMidiFeature;
case PermissionType::GEOLOCATION:
- return blink::WebFeaturePolicyFeature::kGeolocation;
+ return blink::FeaturePolicyFeature::kGeolocation;
case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
- return blink::WebFeaturePolicyFeature::kEncryptedMedia;
+ return blink::FeaturePolicyFeature::kEncryptedMedia;
case PermissionType::AUDIO_CAPTURE:
- return blink::WebFeaturePolicyFeature::kMicrophone;
+ return blink::FeaturePolicyFeature::kMicrophone;
case PermissionType::VIDEO_CAPTURE:
- return blink::WebFeaturePolicyFeature::kCamera;
- case PermissionType::PUSH_MESSAGING:
+ return blink::FeaturePolicyFeature::kCamera;
case PermissionType::NOTIFICATIONS:
case PermissionType::DURABLE_STORAGE:
case PermissionType::BACKGROUND_SYNC:
case PermissionType::FLASH:
case PermissionType::SENSORS:
case PermissionType::ACCESSIBILITY_EVENTS:
+ case PermissionType::CLIPBOARD_READ:
+ case PermissionType::CLIPBOARD_WRITE:
case PermissionType::NUM:
// These aren't exposed by feature policy.
- return blink::WebFeaturePolicyFeature::kNotFound;
+ return blink::FeaturePolicyFeature::kNotFound;
}
NOTREACHED();
- return blink::WebFeaturePolicyFeature::kNotFound;
+ return blink::FeaturePolicyFeature::kNotFound;
}
bool AllowedByFeaturePolicy(RenderFrameHost* rfh, PermissionType type) {
@@ -101,9 +104,9 @@ bool AllowedByFeaturePolicy(RenderFrameHost* rfh, PermissionType type) {
return true;
}
- blink::WebFeaturePolicyFeature feature_policy_feature =
+ blink::FeaturePolicyFeature feature_policy_feature =
PermissionTypeToFeaturePolicyFeature(type);
- if (feature_policy_feature == blink::WebFeaturePolicyFeature::kNotFound)
+ if (feature_policy_feature == blink::FeaturePolicyFeature::kNotFound)
return true;
return rfh->IsFeatureEnabled(feature_policy_feature);
@@ -118,7 +121,7 @@ void PermissionRequestResponseCallbackWrapper(
std::move(callback).Run(vector[0]);
}
-} // anonymous namespace
+} // anonymous namespace
class PermissionServiceImpl::PendingRequest {
public:
@@ -233,7 +236,7 @@ void PermissionServiceImpl::RequestPermissions(
types[i] = PermissionDescriptorToPermissionType(permissions[i]);
std::unique_ptr<PendingRequest> pending_request =
- base::MakeUnique<PendingRequest>(types, std::move(callback));
+ std::make_unique<PendingRequest>(types, std::move(callback));
std::vector<PermissionType> request_types;
for (size_t i = 0; i < types.size(); ++i) {
// Check feature policy.
diff --git a/chromium/content/browser/permissions/permission_service_impl_unittest.cc b/chromium/content/browser/permissions/permission_service_impl_unittest.cc
index cc0c05c93f9..23ecc12dced 100644
--- a/chromium/content/browser/permissions/permission_service_impl_unittest.cc
+++ b/chromium/content/browser/permissions/permission_service_impl_unittest.cc
@@ -13,7 +13,7 @@
#include "content/public/test/test_renderer_host.h"
#include "content/test/mock_permission_manager.h"
#include "mojo/public/cpp/bindings/interface_request.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
#include "third_party/WebKit/public/platform/modules/permissions/permission.mojom.h"
#include "url/origin.h"
@@ -59,12 +59,13 @@ class TestPermissionManager : public MockPermissionManager {
class PermissionServiceImplTest : public RenderViewHostTestHarness {
public:
- PermissionServiceImplTest() : origin_(GURL("https://www.google.com")) {}
+ PermissionServiceImplTest()
+ : origin_(url::Origin::Create(GURL("https://www.google.com"))) {}
void SetUp() override {
RenderViewHostTestHarness::SetUp();
static_cast<TestBrowserContext*>(browser_context())
- ->SetPermissionManager(base::MakeUnique<TestPermissionManager>());
+ ->SetPermissionManager(std::make_unique<TestPermissionManager>());
NavigateAndCommit(origin_.GetURL());
service_context_.reset(new PermissionServiceContext(main_rfh()));
service_impl_.reset(new PermissionServiceImpl(service_context_.get()));
@@ -79,7 +80,7 @@ class PermissionServiceImplTest : public RenderViewHostTestHarness {
protected:
// The header policy should only be set once on page load, so we refresh the
// page to simulate that.
- void RefreshPageAndSetHeaderPolicy(blink::WebFeaturePolicyFeature feature,
+ void RefreshPageAndSetHeaderPolicy(blink::FeaturePolicyFeature feature,
bool enabled) {
NavigateAndCommit(origin_.GetURL());
std::vector<url::Origin> whitelist;
@@ -145,7 +146,7 @@ TEST_F(PermissionServiceImplTest, HasPermissionWithFeaturePolicy) {
EXPECT_EQ(PermissionStatus::GRANTED,
HasPermission(PermissionName::GEOLOCATION));
- RefreshPageAndSetHeaderPolicy(blink::WebFeaturePolicyFeature::kGeolocation,
+ RefreshPageAndSetHeaderPolicy(blink::FeaturePolicyFeature::kGeolocation,
/*enabled=*/false);
EXPECT_EQ(PermissionStatus::DENIED,
HasPermission(PermissionName::GEOLOCATION));
@@ -154,7 +155,7 @@ TEST_F(PermissionServiceImplTest, HasPermissionWithFeaturePolicy) {
EXPECT_EQ(PermissionStatus::GRANTED, HasPermission(PermissionName::MIDI));
// Now block midi.
- RefreshPageAndSetHeaderPolicy(blink::WebFeaturePolicyFeature::kMidiFeature,
+ RefreshPageAndSetHeaderPolicy(blink::FeaturePolicyFeature::kMidiFeature,
/*enabled=*/false);
EXPECT_EQ(PermissionStatus::DENIED, HasPermission(PermissionName::MIDI));
@@ -171,7 +172,7 @@ TEST_F(PermissionServiceImplTest, RequestPermissionsWithFeaturePolicy) {
feature_list.InitAndEnableFeature(features::kUseFeaturePolicyForPermissions);
// Disable midi.
- RefreshPageAndSetHeaderPolicy(blink::WebFeaturePolicyFeature::kMidiFeature,
+ RefreshPageAndSetHeaderPolicy(blink::FeaturePolicyFeature::kMidiFeature,
/*enabled=*/false);
std::vector<PermissionStatus> result =
@@ -187,4 +188,4 @@ TEST_F(PermissionServiceImplTest, RequestPermissionsWithFeaturePolicy) {
EXPECT_EQ(PermissionStatus::GRANTED, result[1]);
}
-} // namespace \ No newline at end of file
+} // namespace content
diff --git a/chromium/content/browser/plugin_data_remover_impl.cc b/chromium/content/browser/plugin_data_remover_impl.cc
index fe5ca2f2d9d..3090fe463df 100644
--- a/chromium/content/browser/plugin_data_remover_impl.cc
+++ b/chromium/content/browser/plugin_data_remover_impl.cc
@@ -47,7 +47,7 @@ void PluginDataRemover::GetSupportedPlugins(
bool allow_wildcard = false;
std::vector<WebPluginInfo> plugins;
PluginService::GetInstance()->GetPluginInfoArray(
- GURL(), kFlashPluginSwfMimeType, allow_wildcard, &plugins, NULL);
+ GURL(), kFlashPluginSwfMimeType, allow_wildcard, &plugins, nullptr);
base::Version min_version(kMinFlashVersion);
for (std::vector<WebPluginInfo>::iterator it = plugins.begin();
it != plugins.end(); ++it) {
@@ -88,8 +88,8 @@ class PluginDataRemoverImpl::Context
// Get the plugin file path.
std::vector<WebPluginInfo> plugins;
- plugin_service->GetPluginInfoArray(
- GURL(), mime_type, false, &plugins, NULL);
+ plugin_service->GetPluginInfoArray(GURL(), mime_type, false, &plugins,
+ nullptr);
if (plugins.empty()) {
// May be empty for some tests and on the CrOS login OOBE screen.
@@ -114,7 +114,7 @@ class PluginDataRemoverImpl::Context
AddRef();
plugin_name_ = pepper_info->name;
// Use the broker since we run this function outside the sandbox.
- plugin_service->OpenChannelToPpapiBroker(0, plugin_path, this);
+ plugin_service->OpenChannelToPpapiBroker(0, 0, plugin_path, this);
}
// Called when a timeout happens in order not to block the client
@@ -195,7 +195,8 @@ class PluginDataRemoverImpl::Context
return;
DCHECK(!channel_.get());
- channel_ = IPC::Channel::CreateClient(handle, this);
+ channel_ = IPC::Channel::CreateClient(handle, this,
+ base::ThreadTaskRunnerHandle::Get());
if (!channel_->Connect()) {
NOTREACHED() << "Couldn't connect to plugin";
SignalDone();
diff --git a/chromium/content/browser/plugin_private_storage_helper.cc b/chromium/content/browser/plugin_private_storage_helper.cc
index 2049f37df5a..12ee66f4f43 100644
--- a/chromium/content/browser/plugin_private_storage_helper.cc
+++ b/chromium/content/browser/plugin_private_storage_helper.cc
@@ -146,7 +146,7 @@ void PluginPrivateDataByOriginChecker::OnFileSystemOpened(
std::string root = storage::GetIsolatedFileSystemRootURIString(
origin_, fsid_, ppapi::kPluginPrivateRootName);
std::unique_ptr<storage::FileSystemOperationContext> operation_context =
- base::MakeUnique<storage::FileSystemOperationContext>(
+ std::make_unique<storage::FileSystemOperationContext>(
filesystem_context_);
file_util->ReadDirectory(
std::move(operation_context), filesystem_context_->CrackURL(GURL(root)),
@@ -185,7 +185,7 @@ void PluginPrivateDataByOriginChecker::OnDirectoryRead(
DCHECK(!file.is_directory); // Nested directories not implemented.
std::unique_ptr<storage::FileSystemOperationContext> operation_context =
- base::MakeUnique<storage::FileSystemOperationContext>(
+ std::make_unique<storage::FileSystemOperationContext>(
filesystem_context_);
storage::FileSystemURL file_url = filesystem_context_->CrackURL(
GURL(root + StringTypeToString(file.name)));
diff --git a/chromium/content/browser/plugin_service_impl.cc b/chromium/content/browser/plugin_service_impl.cc
index 4bdfa1d5455..0378ab3c501 100644
--- a/chromium/content/browser/plugin_service_impl.cc
+++ b/chromium/content/browser/plugin_service_impl.cc
@@ -32,11 +32,14 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/plugin_service_filter.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/resource_context.h"
+#include "content/public/browser/web_contents.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "content/public/common/webplugininfo.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
namespace content {
namespace {
@@ -57,6 +60,17 @@ void WillLoadPluginsCallback(base::SequenceChecker* sequence_checker) {
DCHECK(sequence_checker->CalledOnValidSequence());
}
+void RecordBrokerUsage(int render_process_id, int render_frame_id) {
+ ukm::UkmRecorder* recorder = ukm::UkmRecorder::Get();
+ ukm::SourceId source_id = ukm::UkmRecorder::GetNewSourceID();
+ WebContents* web_contents = WebContents::FromRenderFrameHost(
+ RenderFrameHost::FromID(render_process_id, render_frame_id));
+ if (web_contents) {
+ recorder->UpdateSourceURL(source_id, web_contents->GetLastCommittedURL());
+ ukm::builders::Pepper_Broker(source_id).Record(recorder);
+ }
+}
+
} // namespace
// static
@@ -79,8 +93,7 @@ PluginServiceImpl* PluginServiceImpl::GetInstance() {
return base::Singleton<PluginServiceImpl>::get();
}
-PluginServiceImpl::PluginServiceImpl()
- : filter_(NULL) {
+PluginServiceImpl::PluginServiceImpl() : filter_(nullptr) {
plugin_list_sequence_checker_.DetachFromSequence();
// Collect the total number of browser processes (which create
@@ -116,7 +129,7 @@ PpapiPluginProcessHost* PluginServiceImpl::FindPpapiPluginProcess(
return *iter;
}
}
- return NULL;
+ return nullptr;
}
PpapiPluginProcessHost* PluginServiceImpl::FindPpapiBrokerProcess(
@@ -126,7 +139,7 @@ PpapiPluginProcessHost* PluginServiceImpl::FindPpapiBrokerProcess(
return *iter;
}
- return NULL;
+ return nullptr;
}
PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess(
@@ -137,7 +150,7 @@ PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess(
if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) {
VLOG(1) << "Unable to load ppapi plugin: " << plugin_path.MaybeAsASCII();
- return NULL;
+ return nullptr;
}
PpapiPluginProcessHost* plugin_host =
@@ -150,7 +163,7 @@ PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess(
if (!info) {
VLOG(1) << "Unable to find ppapi plugin registration for: "
<< plugin_path.MaybeAsASCII();
- return NULL;
+ return nullptr;
}
// Record when PPAPI Flash process is started for the first time.
@@ -179,7 +192,7 @@ PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path))
- return NULL;
+ return nullptr;
PpapiPluginProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path);
if (plugin_host)
@@ -188,7 +201,7 @@ PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess(
// Validate that the plugin is actually registered.
PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
if (!info)
- return NULL;
+ return nullptr;
// TODO(ddorwin): Uncomment once out of process is supported.
// DCHECK(info->is_out_of_process);
@@ -214,8 +227,13 @@ void PluginServiceImpl::OpenChannelToPpapiPlugin(
void PluginServiceImpl::OpenChannelToPpapiBroker(
int render_process_id,
+ int render_frame_id,
const base::FilePath& path,
PpapiPluginProcessHost::BrokerClient* client) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&RecordBrokerUsage, render_process_id, render_frame_id));
+
PpapiPluginProcessHost* plugin_host = FindOrStartPpapiBrokerProcess(
render_process_id, path);
if (plugin_host) {
diff --git a/chromium/content/browser/plugin_service_impl.h b/chromium/content/browser/plugin_service_impl.h
index b654bf3c98b..fb9226fd1b1 100644
--- a/chromium/content/browser/plugin_service_impl.h
+++ b/chromium/content/browser/plugin_service_impl.h
@@ -106,6 +106,7 @@ class CONTENT_EXPORT PluginServiceImpl : public PluginService {
const base::FilePath& profile_data_directory,
PpapiPluginProcessHost::PluginClient* client);
void OpenChannelToPpapiBroker(int render_process_id,
+ int render_frame_id,
const base::FilePath& path,
PpapiPluginProcessHost::BrokerClient* client);
diff --git a/chromium/content/browser/plugin_service_impl_unittest.cc b/chromium/content/browser/plugin_service_impl_unittest.cc
new file mode 100644
index 00000000000..565648223d8
--- /dev/null
+++ b/chromium/content/browser/plugin_service_impl_unittest.cc
@@ -0,0 +1,108 @@
+// Copyright 2017 The Chromium Authors. 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/plugin_service_impl.h"
+
+#include "build/build_config.h"
+#include "components/ukm/test_ukm_recorder.h"
+#include "components/ukm/ukm_source.h"
+#include "content/browser/ppapi_plugin_process_host.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 "content/public/browser/web_contents.h"
+#include "content/public/test/navigation_simulator.h"
+#include "content/public/test/test_renderer_host.h"
+#include "content/public/test/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+constexpr char kURL1[] = "http://google.com/";
+constexpr char kURL2[] = "http://youtube.com/";
+constexpr char kPepperBrokerEvent[] = "Pepper.Broker";
+
+class TestBrokerClient : public PpapiPluginProcessHost::BrokerClient {
+ public:
+ void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
+ int* renderer_id) override {}
+ void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle,
+ base::ProcessId plugin_pid,
+ int plugin_child_id) override {}
+ bool Incognito() override { return false; }
+};
+
+} // anonymous namespace
+
+class PluginServiceImplTest : public RenderViewHostTestHarness {
+ public:
+ PluginServiceImplTest() = default;
+ ~PluginServiceImplTest() override = default;
+
+ void SetUp() override {
+ RenderViewHostTestHarness::SetUp();
+
+ test_ukm_recorder_ = base::MakeUnique<ukm::TestAutoSetUkmRecorder>();
+ }
+
+ bool RecordedBrokerEvent(const GURL& url) {
+ RunAllPendingInMessageLoop(BrowserThread::UI);
+ auto entries = test_ukm_recorder_->GetEntriesByName(kPepperBrokerEvent);
+ for (const auto* const entry : entries) {
+ const ukm::UkmSource* source =
+ test_ukm_recorder_->GetSourceForSourceId(entry->source_id);
+ if (source && source->url() == url)
+ return true;
+ }
+ return false;
+ }
+
+ void ResetUKM() {
+ test_ukm_recorder_ = base::MakeUnique<ukm::TestAutoSetUkmRecorder>();
+ }
+
+ private:
+ std::unique_ptr<ukm::TestUkmRecorder> test_ukm_recorder_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginServiceImplTest);
+};
+
+TEST_F(PluginServiceImplTest, RecordBrokerUsage) {
+ TestBrokerClient client;
+
+ NavigateAndCommit(GURL(kURL1));
+ PluginServiceImpl* service = PluginServiceImpl::GetInstance();
+
+ // Internal usage of the broker should not record metrics. Internal usage will
+ // not pass a RFH.
+ service->OpenChannelToPpapiBroker(0, 0, base::FilePath(), &client);
+ EXPECT_FALSE(RecordedBrokerEvent(GURL(kURL1)));
+
+ // Top level frame usage should be recorded.
+ int render_process_id = main_rfh()->GetProcess()->GetID();
+ int render_frame_id = main_rfh()->GetRoutingID();
+ service->OpenChannelToPpapiBroker(render_process_id, render_frame_id,
+ base::FilePath(), &client);
+ EXPECT_TRUE(RecordedBrokerEvent(GURL(kURL1)));
+ EXPECT_FALSE(RecordedBrokerEvent(GURL(kURL2)));
+
+ ResetUKM();
+
+ // Iframe usage should be recorded under the top level frame origin.
+ RenderFrameHost* child_frame =
+ RenderFrameHostTester::For(main_rfh())->AppendChild("child");
+ child_frame = NavigationSimulator::NavigateAndCommitFromDocument(GURL(kURL2),
+ child_frame);
+ EXPECT_EQ(GURL(kURL2), child_frame->GetLastCommittedURL());
+ render_process_id = child_frame->GetProcess()->GetID();
+ render_frame_id = child_frame->GetRoutingID();
+ service->OpenChannelToPpapiBroker(render_process_id, render_frame_id,
+ base::FilePath(), &client);
+ EXPECT_TRUE(RecordedBrokerEvent(GURL(kURL1)));
+ EXPECT_FALSE(RecordedBrokerEvent(GURL(kURL2)));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/pointer_lock_browsertest.cc b/chromium/content/browser/pointer_lock_browsertest.cc
index da85377a9cf..dc8530c016e 100644
--- a/chromium/content/browser/pointer_lock_browsertest.cc
+++ b/chromium/content/browser/pointer_lock_browsertest.cc
@@ -33,7 +33,8 @@ class MockRenderWidgetHostView : public RenderWidgetHostViewAura {
MockRenderWidgetHostView(RenderWidgetHost* host, bool is_guest_view_hack)
: RenderWidgetHostViewAura(host,
is_guest_view_hack,
- false /* enable_surface_synchronization */),
+ false /* enable_surface_synchronization */,
+ false /* is_mus_browser_plugin_guest */),
host_(RenderWidgetHostImpl::From(host)) {}
~MockRenderWidgetHostView() override {
if (mouse_locked_)
@@ -179,6 +180,8 @@ IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockEventRouting) {
RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
child->current_frame_host()->GetView());
+ WaitForChildFrameSurfaceReady(child->current_frame_host());
+
// Request a pointer lock on the root frame's body.
EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));
@@ -243,8 +246,8 @@ IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockEventRouting) {
"var x; var y; var mX; var mY; document.addEventListener('mousemove', "
"function(e) {x = e.x; y = e.y; mX = e.movementX; mY = e.movementY;});"));
- gfx::Point transformed_point;
- root_view->TransformPointToCoordSpaceForView(gfx::Point(0, 0), child_view,
+ gfx::PointF transformed_point;
+ root_view->TransformPointToCoordSpaceForView(gfx::PointF(0, 0), child_view,
&transformed_point);
mouse_event.SetPositionInWidget(-transformed_point.x() + 14,
@@ -322,6 +325,8 @@ IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWheelEventRouting) {
RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
child->current_frame_host()->GetView());
+ WaitForChildFrameSurfaceReady(child->current_frame_host());
+
// Request a pointer lock on the root frame's body.
EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));
@@ -403,8 +408,8 @@ IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWheelEventRouting) {
MainThreadFrameObserver child_observer(child_view->GetRenderWidgetHost());
child_observer.Wait();
- gfx::Point transformed_point;
- root_view->TransformPointToCoordSpaceForView(gfx::Point(0, 0), child_view,
+ gfx::PointF transformed_point;
+ root_view->TransformPointToCoordSpaceForView(gfx::PointF(0, 0), child_view,
&transformed_point);
wheel_event.SetPositionInWidget(-transformed_point.x() + 14,
diff --git a/chromium/content/browser/ppapi_plugin_process_host.cc b/chromium/content/browser/ppapi_plugin_process_host.cc
index d1fa4e79537..ff6a01536ce 100644
--- a/chromium/content/browser/ppapi_plugin_process_host.cc
+++ b/chromium/content/browser/ppapi_plugin_process_host.cc
@@ -22,7 +22,6 @@
#include "content/browser/plugin_service_impl.h"
#include "content/browser/renderer_host/render_message_filter.h"
#include "content/common/child_process_host_impl.h"
-#include "content/common/child_process_messages.h"
#include "content/common/content_switches_internal.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_constants.h"
@@ -36,6 +35,7 @@
#include "net/base/network_change_notifier.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "services/service_manager/sandbox/sandbox_type.h"
+#include "services/service_manager/sandbox/switches.h"
#include "ui/base/ui_base_switches.h"
#if defined(OS_POSIX)
@@ -45,9 +45,9 @@
#if defined(OS_WIN)
#include "base/win/windows_version.h"
#include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h"
-#include "content/common/sandbox_win.h"
#include "sandbox/win/src/process_mitigations.h"
#include "sandbox/win/src/sandbox_policy.h"
+#include "services/service_manager/sandbox/win/sandbox_win.h"
#include "ui/display/win/dpi.h"
#include "ui/gfx/font_render_params.h"
#endif
@@ -88,8 +88,9 @@ class PpapiPluginSandboxedProcessLauncherDelegate
#if !defined(NACL_WIN64)
// We don't support PPAPI win32k lockdown prior to Windows 10.
if (base::win::GetVersion() >= base::win::VERSION_WIN10 &&
- IsWin32kLockdownEnabled()) {
- result = AddWin32kLockdownPolicy(policy, true);
+ service_manager::IsWin32kLockdownEnabled()) {
+ result =
+ service_manager::SandboxWin::AddWin32kLockdownPolicy(policy, true);
if (result != sandbox::SBOX_ALL_OK)
return false;
}
@@ -97,7 +98,7 @@ class PpapiPluginSandboxedProcessLauncherDelegate
const base::string16& sid =
browser_client->GetAppContainerSidForSandboxType(GetSandboxType());
if (!sid.empty())
- AddAppContainerPolicy(policy, sid.c_str());
+ service_manager::SandboxWin::AddAppContainerPolicy(policy, sid.c_str());
return true;
}
@@ -132,33 +133,18 @@ class PpapiPluginSandboxedProcessLauncherDelegate
};
class PpapiPluginProcessHost::PluginNetworkObserver
- : public net::NetworkChangeNotifier::IPAddressObserver,
- public net::NetworkChangeNotifier::ConnectionTypeObserver {
+ : public net::NetworkChangeNotifier::NetworkChangeObserver {
public:
explicit PluginNetworkObserver(PpapiPluginProcessHost* process_host)
: process_host_(process_host) {
- net::NetworkChangeNotifier::AddIPAddressObserver(this);
- net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
+ net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
}
~PluginNetworkObserver() override {
- net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
- net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
+ net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
}
- // IPAddressObserver implementation.
- void OnIPAddressChanged() override {
- // TODO(brettw) bug 90246: This doesn't seem correct. The online/offline
- // notification seems like it should be sufficient, but I don't see that
- // when I unplug and replug my network cable. Sending this notification when
- // "something" changes seems to make Flash reasonably happy, but seems
- // wrong. We should really be able to provide the real online state in
- // OnConnectionTypeChanged().
- process_host_->Send(new PpapiMsg_SetNetworkState(true));
- }
-
- // ConnectionTypeObserver implementation.
- void OnConnectionTypeChanged(
+ void OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) override {
process_host_->Send(new PpapiMsg_SetNetworkState(
type != net::NetworkChangeNotifier::CONNECTION_NONE));
@@ -185,7 +171,7 @@ PpapiPluginProcessHost* PpapiPluginProcessHost::CreatePluginHost(
return plugin_host;
NOTREACHED(); // Init is not expected to fail.
- return NULL;
+ return nullptr;
}
// static
@@ -197,7 +183,7 @@ PpapiPluginProcessHost* PpapiPluginProcessHost::CreateBrokerHost(
return plugin_host;
NOTREACHED(); // Init is not expected to fail.
- return NULL;
+ return nullptr;
}
// static
@@ -294,8 +280,8 @@ PpapiPluginProcessHost::PpapiPluginProcessHost(
// We don't have to do any whitelisting for APIs in this process host, so
// don't bother passing a browser context or document url here.
- if (GetContentClient()->browser()->IsPluginAllowedToUseDevChannelAPIs(
- NULL, GURL()))
+ if (GetContentClient()->browser()->IsPluginAllowedToUseDevChannelAPIs(nullptr,
+ GURL()))
base_permissions |= ppapi::PERMISSION_DEV_CHANNEL;
permissions_ = ppapi::PpapiPermissions::GetForCommandLine(base_permissions);
@@ -363,7 +349,7 @@ bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) {
}
std::unique_ptr<base::CommandLine> cmd_line =
- base::MakeUnique<base::CommandLine>(exe_path);
+ std::make_unique<base::CommandLine>(exe_path);
cmd_line->AppendSwitchASCII(switches::kProcessType,
is_broker_ ? switches::kPpapiBrokerProcess
: switches::kPpapiPluginProcess);
@@ -383,7 +369,7 @@ bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) {
if (!is_broker_) {
static const char* const kPluginForwardSwitches[] = {
- switches::kDisableSeccompFilterSandbox,
+ service_manager::switches::kDisableSeccompFilterSandbox,
#if defined(OS_MACOSX)
switches::kEnableSandboxLogging,
#endif
@@ -410,7 +396,7 @@ bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) {
#if defined(OS_WIN)
cmd_line->AppendSwitchASCII(
switches::kDeviceScaleFactor,
- base::DoubleToString(display::win::GetDPIScale()));
+ base::NumberToString(display::win::GetDPIScale()));
const gfx::FontRenderParams font_params =
gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr);
cmd_line->AppendSwitchASCII(switches::kPpapiAntialiasedTextEnabled,
@@ -427,7 +413,7 @@ bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) {
// we are not using a plugin launcher - having a plugin launcher means we need
// to use another process instead of just forking the zygote.
process_->Launch(
- base::MakeUnique<PpapiPluginSandboxedProcessLauncherDelegate>(is_broker_),
+ std::make_unique<PpapiPluginSandboxedProcessLauncherDelegate>(is_broker_),
std::move(cmd_line), true);
return true;
}
diff --git a/chromium/content/browser/presentation/OWNERS b/chromium/content/browser/presentation/OWNERS
index d16cce25238..4c81ef2dbac 100644
--- a/chromium/content/browser/presentation/OWNERS
+++ b/chromium/content/browser/presentation/OWNERS
@@ -4,7 +4,6 @@
# //content/common/presentation/
# //content/renderer/presentation/
-avayvod@chromium.org
imcheng@chromium.org
mfoltz@chromium.org
mlamouri@chromium.org
diff --git a/chromium/content/browser/presentation/presentation_service_impl.h b/chromium/content/browser/presentation/presentation_service_impl.h
index a5f783a338c..c16c56476a8 100644
--- a/chromium/content/browser/presentation/presentation_service_impl.h
+++ b/chromium/content/browser/presentation/presentation_service_impl.h
@@ -215,7 +215,7 @@ class CONTENT_EXPORT PresentationServiceImpl
const content::PresentationInfo& presentation_info,
std::vector<content::PresentationConnectionMessage> messages);
- // A callback registered to OffscreenPresentationManager when
+ // A callback registered to LocalPresentationManager when
// the PresentationServiceImpl for the presentation receiver is initialized.
// Calls |client_| to create a new PresentationConnection on receiver page.
void OnReceiverConnectionAvailable(
diff --git a/chromium/content/browser/presentation/presentation_service_impl_unittest.cc b/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
index e72f236a5ad..52e875906ac 100644
--- a/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
+++ b/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
@@ -169,12 +169,12 @@ class MockPresentationServiceDelegate
const PresentationInfo& presentation_info,
PresentationConnectionPtr controller_conn_ptr,
PresentationConnectionRequest receiver_conn_request) override {
- RegisterOffscreenPresentationConnectionRaw(
- render_process_id, render_frame_id, presentation_info,
- controller_conn_ptr.get());
+ RegisterLocalPresentationConnectionRaw(render_process_id, render_frame_id,
+ presentation_info,
+ controller_conn_ptr.get());
}
- MOCK_METHOD4(RegisterOffscreenPresentationConnectionRaw,
+ MOCK_METHOD4(RegisterLocalPresentationConnectionRaw,
void(int render_process_id,
int render_frame_id,
const PresentationInfo& presentation_info,
@@ -619,7 +619,7 @@ TEST_F(PresentationServiceImplTest, SetPresentationConnection) {
auto request = mojo::MakeRequest(&receiver_connection);
PresentationInfo expected(presentation_url1_, kPresentationId);
- EXPECT_CALL(mock_delegate_, RegisterOffscreenPresentationConnectionRaw(
+ EXPECT_CALL(mock_delegate_, RegisterLocalPresentationConnectionRaw(
_, _, InfoEquals(expected), _));
service_impl_->SetPresentationConnection(
diff --git a/chromium/content/browser/push_messaging/push_messaging_manager.cc b/chromium/content/browser/push_messaging/push_messaging_manager.cc
index a079271f561..f216c7c4ed5 100644
--- a/chromium/content/browser/push_messaging/push_messaging_manager.cc
+++ b/chromium/content/browser/push_messaging/push_messaging_manager.cc
@@ -541,12 +541,12 @@ void PushMessagingManager::Core::RegisterOnUI(
return;
}
- // Request push messaging permission (which will fail, since
+ // Request notifications permission (which will fail, since
// notifications aren't supported in incognito), so the website can't
// detect whether incognito is active.
GURL requesting_origin = data.requesting_origin;
browser_context->GetPermissionManager()->RequestPermission(
- PermissionType::PUSH_MESSAGING, render_frame_host,
+ PermissionType::NOTIFICATIONS, render_frame_host,
requesting_origin, data.user_gesture,
base::Bind(
&PushMessagingManager::Core::DidRequestPermissionInIncognito,
diff --git a/chromium/content/browser/quota_dispatcher_host.cc b/chromium/content/browser/quota_dispatcher_host.cc
index 88487ce5092..f04b400ab56 100644
--- a/chromium/content/browser/quota_dispatcher_host.cc
+++ b/chromium/content/browser/quota_dispatcher_host.cc
@@ -13,8 +13,8 @@
#include "base/memory/weak_ptr.h"
#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
-#include "content/common/quota_messages.h"
#include "content/public/browser/quota_permission_context.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/base/url_util.h"
#include "storage/browser/quota/quota_manager.h"
#include "url/gurl.h"
@@ -29,15 +29,14 @@ namespace content {
// Created one per request to carry the request's request_id around.
// Dispatches requests from renderer/worker to the QuotaManager and
// sends back the response to the renderer/worker.
+// TODO(sashab): Remove, since request_id is no longer needed.
class QuotaDispatcherHost::RequestDispatcher {
public:
- RequestDispatcher(base::WeakPtr<QuotaDispatcherHost> dispatcher_host,
- int request_id)
+ RequestDispatcher(base::WeakPtr<QuotaDispatcherHost> dispatcher_host)
: dispatcher_host_(dispatcher_host),
- render_process_id_(dispatcher_host->process_id_),
- request_id_(request_id) {
- dispatcher_host_->outstanding_requests_.AddWithID(base::WrapUnique(this),
- request_id_);
+ render_process_id_(dispatcher_host->process_id_) {
+ request_id_ =
+ dispatcher_host_->outstanding_requests_.Add(base::WrapUnique(this));
}
virtual ~RequestDispatcher() {}
@@ -52,14 +51,13 @@ class QuotaDispatcherHost::RequestDispatcher {
return dispatcher_host_.get();
}
storage::QuotaManager* quota_manager() const {
- return dispatcher_host_ ? dispatcher_host_->quota_manager_ : NULL;
+ return dispatcher_host_ ? dispatcher_host_->quota_manager_ : nullptr;
}
QuotaPermissionContext* permission_context() const {
- return dispatcher_host_ ?
- dispatcher_host_->permission_context_.get() : NULL;
+ return dispatcher_host_ ? dispatcher_host_->permission_context_.get()
+ : nullptr;
}
int render_process_id() const { return render_process_id_; }
- int request_id() const { return request_id_; }
private:
base::WeakPtr<QuotaDispatcherHost> dispatcher_host_;
@@ -72,8 +70,9 @@ class QuotaDispatcherHost::QueryUsageAndQuotaDispatcher
public:
QueryUsageAndQuotaDispatcher(
base::WeakPtr<QuotaDispatcherHost> dispatcher_host,
- int request_id)
- : RequestDispatcher(dispatcher_host, request_id),
+ QueryStorageUsageAndQuotaCallback callback)
+ : RequestDispatcher(dispatcher_host),
+ callback_(std::move(callback)),
weak_factory_(this) {}
~QueryUsageAndQuotaDispatcher() override {}
@@ -98,16 +97,11 @@ class QuotaDispatcherHost::QueryUsageAndQuotaDispatcher
// crbug.com/349708
TRACE_EVENT0("io", "QuotaDispatcherHost::RequestQuotaDispatcher"
"::DidQueryStorageUsageAndQuota");
-
- if (status != storage::kQuotaStatusOk) {
- dispatcher_host()->Send(new QuotaMsg_DidFail(request_id(), status));
- } else {
- dispatcher_host()->Send(new QuotaMsg_DidQueryStorageUsageAndQuota(
- request_id(), usage, quota));
- }
+ std::move(callback_).Run(status, usage, quota);
Completed();
}
+ QueryStorageUsageAndQuotaCallback callback_;
base::WeakPtrFactory<QueryUsageAndQuotaDispatcher> weak_factory_;
};
@@ -116,19 +110,27 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
public:
typedef RequestQuotaDispatcher self_type;
- RequestQuotaDispatcher(base::WeakPtr<QuotaDispatcherHost> dispatcher_host,
- const StorageQuotaParams& params)
- : RequestDispatcher(dispatcher_host, params.request_id),
- params_(params),
+ RequestQuotaDispatcher(
+ base::WeakPtr<QuotaDispatcherHost> dispatcher_host,
+ int64_t render_frame_id,
+ const GURL& origin_url,
+ storage::StorageType storage_type,
+ uint64_t requested_size,
+ mojom::QuotaDispatcherHost::RequestStorageQuotaCallback callback)
+ : RequestDispatcher(dispatcher_host),
+ render_frame_id_(render_frame_id),
+ origin_url_(origin_url),
+ storage_type_(storage_type),
+ requested_size_(requested_size),
+ callback_(std::move(callback)),
current_usage_(0),
current_quota_(0),
requested_quota_(0),
weak_factory_(this) {
// Convert the requested size from uint64_t to int64_t since the quota
- // backend
- // requires int64_t values.
+ // backend requires int64_t values.
// TODO(nhiroki): The backend should accept uint64_t values.
- requested_quota_ = base::saturated_cast<int64_t>(params_.requested_size);
+ requested_quota_ = base::saturated_cast<int64_t>(requested_size);
}
~RequestQuotaDispatcher() override {}
@@ -137,16 +139,16 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
// crbug.com/349708
TRACE_EVENT0("io", "QuotaDispatcherHost::RequestQuotaDispatcher::Start");
- DCHECK(params_.storage_type == storage::kStorageTypeTemporary ||
- params_.storage_type == storage::kStorageTypePersistent);
- if (params_.storage_type == storage::kStorageTypePersistent) {
+ DCHECK(storage_type_ == storage::kStorageTypeTemporary ||
+ storage_type_ == storage::kStorageTypePersistent);
+ if (storage_type_ == storage::kStorageTypePersistent) {
quota_manager()->GetUsageAndQuotaForWebApps(
- params_.origin_url, params_.storage_type,
+ origin_url_, storage_type_,
base::Bind(&self_type::DidGetPersistentUsageAndQuota,
weak_factory_.GetWeakPtr()));
} else {
quota_manager()->GetUsageAndQuotaForWebApps(
- params_.origin_url, params_.storage_type,
+ origin_url_, storage_type_,
base::Bind(&self_type::DidGetTemporaryUsageAndQuota,
weak_factory_.GetWeakPtr()));
}
@@ -163,11 +165,10 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
return;
}
- if (quota_manager()->IsStorageUnlimited(params_.origin_url,
- params_.storage_type) ||
+ if (quota_manager()->IsStorageUnlimited(origin_url_, storage_type_) ||
requested_quota_ <= quota) {
// Seems like we can just let it go.
- DidFinish(storage::kQuotaStatusOk, usage, params_.requested_size);
+ DidFinish(storage::kQuotaStatusOk, usage, requested_size_);
return;
}
current_usage_ = usage;
@@ -176,7 +177,15 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
// Otherwise we need to consult with the permission context and
// possibly show a prompt.
DCHECK(permission_context());
- permission_context()->RequestQuotaPermission(params_, render_process_id(),
+
+ StorageQuotaParams params;
+ params.render_frame_id = render_frame_id_;
+ params.origin_url = origin_url_;
+ params.storage_type = storage_type_;
+ params.requested_size = requested_size_;
+
+ permission_context()->RequestQuotaPermission(
+ params, render_process_id(),
base::Bind(&self_type::DidGetPermissionResponse,
weak_factory_.GetWeakPtr()));
}
@@ -198,7 +207,7 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
}
// Now we're allowed to set the new quota.
quota_manager()->SetPersistentHostQuota(
- net::GetHostOrSpecFromURL(params_.origin_url), params_.requested_size,
+ net::GetHostOrSpecFromURL(origin_url_), requested_size_,
base::Bind(&self_type::DidSetHostQuota, weak_factory_.GetWeakPtr()));
}
@@ -210,70 +219,71 @@ class QuotaDispatcherHost::RequestQuotaDispatcher
if (!dispatcher_host())
return;
DCHECK(dispatcher_host());
- if (status != storage::kQuotaStatusOk) {
- dispatcher_host()->Send(new QuotaMsg_DidFail(request_id(), status));
- } else {
- dispatcher_host()->Send(new QuotaMsg_DidGrantStorageQuota(
- request_id(), usage, granted_quota));
- }
+ std::move(callback_).Run(status, usage, granted_quota);
Completed();
}
- StorageQuotaParams params_;
+ const int64_t render_frame_id_;
+ const GURL origin_url_;
+ const storage::StorageType storage_type_;
+ const uint64_t requested_size_;
+ mojom::QuotaDispatcherHost::RequestStorageQuotaCallback callback_;
+
int64_t current_usage_;
int64_t current_quota_;
int64_t requested_quota_;
base::WeakPtrFactory<self_type> weak_factory_;
};
+// static
+void QuotaDispatcherHost::Create(
+ int process_id,
+ QuotaManager* quota_manager,
+ scoped_refptr<QuotaPermissionContext> permission_context,
+ mojom::QuotaDispatcherHostRequest request) {
+ mojo::MakeStrongBinding(
+ base::MakeUnique<QuotaDispatcherHost>(process_id, quota_manager,
+ std::move(permission_context)),
+ std::move(request));
+}
+
QuotaDispatcherHost::QuotaDispatcherHost(
int process_id,
QuotaManager* quota_manager,
- QuotaPermissionContext* permission_context)
- : BrowserMessageFilter(QuotaMsgStart),
- process_id_(process_id),
+ scoped_refptr<QuotaPermissionContext> permission_context)
+ : process_id_(process_id),
quota_manager_(quota_manager),
permission_context_(permission_context),
- weak_factory_(this) {
-}
-
-bool QuotaDispatcherHost::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(QuotaDispatcherHost, message)
- IPC_MESSAGE_HANDLER(QuotaHostMsg_QueryStorageUsageAndQuota,
- OnQueryStorageUsageAndQuota)
- IPC_MESSAGE_HANDLER(QuotaHostMsg_RequestStorageQuota,
- OnRequestStorageQuota)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
+ weak_factory_(this) {}
-QuotaDispatcherHost::~QuotaDispatcherHost() {}
-
-void QuotaDispatcherHost::OnQueryStorageUsageAndQuota(
- int request_id,
- const GURL& origin,
- StorageType type) {
+void QuotaDispatcherHost::QueryStorageUsageAndQuota(
+ const GURL& origin_url,
+ storage::StorageType storage_type,
+ QueryStorageUsageAndQuotaCallback callback) {
QueryUsageAndQuotaDispatcher* dispatcher = new QueryUsageAndQuotaDispatcher(
- weak_factory_.GetWeakPtr(), request_id);
- dispatcher->QueryStorageUsageAndQuota(origin, type);
+ weak_factory_.GetWeakPtr(), std::move(callback));
+ dispatcher->QueryStorageUsageAndQuota(origin_url, storage_type);
}
-void QuotaDispatcherHost::OnRequestStorageQuota(
- const StorageQuotaParams& params) {
- if (params.storage_type != storage::kStorageTypeTemporary &&
- params.storage_type != storage::kStorageTypePersistent) {
+void QuotaDispatcherHost::RequestStorageQuota(
+ int64_t render_frame_id,
+ const GURL& origin_url,
+ storage::StorageType storage_type,
+ uint64_t requested_size,
+ mojom::QuotaDispatcherHost::RequestStorageQuotaCallback callback) {
+ if (storage_type != storage::kStorageTypeTemporary &&
+ storage_type != storage::kStorageTypePersistent) {
// Unsupported storage types.
- Send(new QuotaMsg_DidFail(params.request_id,
- storage::kQuotaErrorNotSupported));
+ std::move(callback).Run(storage::kQuotaErrorNotSupported, 0, 0);
return;
}
- RequestQuotaDispatcher* dispatcher =
- new RequestQuotaDispatcher(weak_factory_.GetWeakPtr(),
- params);
+ RequestQuotaDispatcher* dispatcher = new RequestQuotaDispatcher(
+ weak_factory_.GetWeakPtr(), render_frame_id, origin_url, storage_type,
+ requested_size, std::move(callback));
dispatcher->Start();
}
+QuotaDispatcherHost::~QuotaDispatcherHost() = default;
+
} // namespace content
diff --git a/chromium/content/browser/quota_dispatcher_host.h b/chromium/content/browser/quota_dispatcher_host.h
index 8aebb6e044d..40677a25ce9 100644
--- a/chromium/content/browser/quota_dispatcher_host.h
+++ b/chromium/content/browser/quota_dispatcher_host.h
@@ -7,45 +7,47 @@
#include "base/containers/id_map.h"
#include "base/macros.h"
+#include "content/common/quota_dispatcher_host.mojom.h"
#include "content/public/browser/browser_message_filter.h"
-#include "storage/common/quota/quota_types.h"
class GURL;
-namespace IPC {
-class Message;
-}
-
namespace storage {
class QuotaManager;
}
namespace content {
class QuotaPermissionContext;
-struct StorageQuotaParams;
-class QuotaDispatcherHost : public BrowserMessageFilter {
+class QuotaDispatcherHost : public mojom::QuotaDispatcherHost {
public:
+ static void Create(int process_id,
+ storage::QuotaManager* quota_manager,
+ scoped_refptr<QuotaPermissionContext> permission_context,
+ mojom::QuotaDispatcherHostRequest request);
+
QuotaDispatcherHost(int process_id,
storage::QuotaManager* quota_manager,
- QuotaPermissionContext* permission_context);
+ scoped_refptr<QuotaPermissionContext> permission_context);
- // BrowserMessageFilter:
- bool OnMessageReceived(const IPC::Message& message) override;
-
- protected:
~QuotaDispatcherHost() override;
+ // content::mojom::QuotaDispatcherHost:
+ void QueryStorageUsageAndQuota(
+ const GURL& origin_url,
+ storage::StorageType storage_type,
+ QueryStorageUsageAndQuotaCallback callback) override;
+ void RequestStorageQuota(int64_t render_frame_id,
+ const GURL& origin_url,
+ storage::StorageType storage_type,
+ uint64_t requested_size,
+ RequestStorageQuotaCallback callback) override;
+
private:
class RequestDispatcher;
class QueryUsageAndQuotaDispatcher;
class RequestQuotaDispatcher;
- void OnQueryStorageUsageAndQuota(int request_id,
- const GURL& origin_url,
- storage::StorageType type);
- void OnRequestStorageQuota(const StorageQuotaParams& params);
-
// The ID of this process.
int process_id_;
diff --git a/chromium/content/browser/renderer_host/OWNERS b/chromium/content/browser/renderer_host/OWNERS
index 5dac3697072..f353520c33e 100644
--- a/chromium/content/browser/renderer_host/OWNERS
+++ b/chromium/content/browser/renderer_host/OWNERS
@@ -14,9 +14,6 @@ asvitkine@chromium.org
kbr@chromium.org
ccameron@chromium.org
-# for *android*
-aelias@chromium.org
-
# For touch/gesture specific changes
rjkroege@chromium.org
sadrul@chromium.org
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 8bc4ebd0d77..3ed8b18dfab 100644
--- a/chromium/content/browser/renderer_host/browser_compositor_view_mac.h
+++ b/chromium/content/browser/renderer_host/browser_compositor_view_mac.h
@@ -29,6 +29,7 @@ class BrowserCompositorMacClient {
virtual SkColor BrowserCompositorMacGetGutterColor(SkColor color) const = 0;
virtual void BrowserCompositorMacOnBeginFrame() = 0;
virtual viz::LocalSurfaceId GetLocalSurfaceId() const = 0;
+ virtual void OnFrameTokenChanged(uint32_t frame_token) = 0;
};
// This class owns a DelegatedFrameHost, and will dynamically attach and
@@ -111,6 +112,7 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient {
override;
void OnBeginFrame() override;
bool IsAutoResizeEnabled() const override;
+ void OnFrameTokenChanged(uint32_t frame_token) override;
// Returns nullptr if no compositor is attached.
ui::Compositor* CompositorForTesting() const;
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 04ca86589a1..00169dea145 100644
--- a/chromium/content/browser/renderer_host/browser_compositor_view_mac.mm
+++ b/chromium/content/browser/renderer_host/browser_compositor_view_mac.mm
@@ -91,6 +91,7 @@ class RecyclableCompositorMac : public ui::CompositorObserver {
base::TimeTicks start_time) override {}
void OnCompositingEnded(ui::Compositor* compositor) override {}
void OnCompositingLockStateChanged(ui::Compositor* compositor) override {}
+ void OnCompositingChildResizing(ui::Compositor* compositor) override {}
void OnCompositingShuttingDown(ui::Compositor* compositor) override {}
std::unique_ptr<ui::AcceleratedWidgetMac> accelerated_widget_mac_;
@@ -185,7 +186,8 @@ BrowserCompositorMac::BrowserCompositorMac(
root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
// TODO(fsamuel): Plumb surface synchronization settings.
delegated_frame_host_.reset(new DelegatedFrameHost(
- frame_sink_id, this, false /* enable_surface_synchronization */));
+ frame_sink_id, this, false /* enable_surface_synchronization */,
+ false /* enable_viz */));
SetRenderWidgetHostIsHidden(render_widget_host_is_hidden);
SetNSViewAttachedToWindow(ns_view_attached_to_window);
@@ -308,7 +310,7 @@ void BrowserCompositorMac::SubmitCompositorFrame(
pixel_size);
}
delegated_frame_host_->SubmitCompositorFrame(local_surface_id,
- std::move(frame));
+ std::move(frame), nullptr);
}
void BrowserCompositorMac::OnDidNotProduceFrame(const viz::BeginFrameAck& ack) {
@@ -467,6 +469,10 @@ bool BrowserCompositorMac::IsAutoResizeEnabled() const {
return false;
}
+void BrowserCompositorMac::OnFrameTokenChanged(uint32_t frame_token) {
+ client_->OnFrameTokenChanged(frame_token);
+}
+
ui::Compositor* BrowserCompositorMac::CompositorForTesting() const {
if (recyclable_compositor_)
return recyclable_compositor_->compositor();
diff --git a/chromium/content/browser/renderer_host/clipboard_host_impl.cc b/chromium/content/browser/renderer_host/clipboard_host_impl.cc
new file mode 100644
index 00000000000..cadcf99b7fc
--- /dev/null
+++ b/chromium/content/browser/renderer_host/clipboard_host_impl.cc
@@ -0,0 +1,303 @@
+// 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/browser/renderer_host/clipboard_host_impl.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/pickle.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
+#include "content/browser/blob_storage/chrome_blob_storage_context.h"
+#include "content/public/browser/blob_handle.h"
+#include "content/public/browser/browser_context.h"
+#include "ipc/ipc_message_macros.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"
+#include "ui/base/clipboard/custom_data_helper.h"
+#include "ui/base/clipboard/scoped_clipboard_writer.h"
+#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/geometry/size.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+void ReleaseSharedMemoryPixels(void* addr, void* context) {
+ MojoResult result = MojoUnmapBuffer(context);
+ DCHECK_EQ(MOJO_RESULT_OK, result);
+}
+
+// No-op helper for delayed cleanup of BlobHandles generated by reading
+// clipboard images.
+void CleanupReadImageBlob(std::unique_ptr<content::BlobHandle>) {}
+
+} // namespace
+
+ClipboardHostImpl::ClipboardHostImpl(
+ scoped_refptr<ChromeBlobStorageContext> blob_storage_context)
+ : clipboard_(ui::Clipboard::GetForCurrentThread()),
+ blob_storage_context_(std::move(blob_storage_context)),
+ clipboard_writer_(
+ new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+}
+
+void ClipboardHostImpl::Create(
+ scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
+ mojom::ClipboardHostRequest request) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ mojo::MakeStrongBinding(
+ base::WrapUnique<ClipboardHostImpl>(
+ new ClipboardHostImpl(std::move(blob_storage_context))),
+ std::move(request));
+}
+
+ClipboardHostImpl::~ClipboardHostImpl() {
+ clipboard_writer_->Reset();
+}
+
+void ClipboardHostImpl::GetSequenceNumber(ui::ClipboardType type,
+ GetSequenceNumberCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ std::move(callback).Run(clipboard_->GetSequenceNumber(type));
+}
+
+void ClipboardHostImpl::ReadAvailableTypes(
+ ui::ClipboardType type,
+ ReadAvailableTypesCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ std::vector<base::string16> types;
+ bool contains_filenames;
+ clipboard_->ReadAvailableTypes(type, &types, &contains_filenames);
+ std::move(callback).Run(types, contains_filenames);
+}
+
+void ClipboardHostImpl::IsFormatAvailable(content::ClipboardFormat format,
+ ui::ClipboardType type,
+ IsFormatAvailableCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ bool result = false;
+ switch (format) {
+ case CLIPBOARD_FORMAT_PLAINTEXT:
+ result = clipboard_->IsFormatAvailable(
+ ui::Clipboard::GetPlainTextWFormatType(), type) ||
+ clipboard_->IsFormatAvailable(
+ ui::Clipboard::GetPlainTextFormatType(), type);
+ break;
+ case CLIPBOARD_FORMAT_HTML:
+ result = clipboard_->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(),
+ type);
+ break;
+ case CLIPBOARD_FORMAT_SMART_PASTE:
+ result = clipboard_->IsFormatAvailable(
+ ui::Clipboard::GetWebKitSmartPasteFormatType(), type);
+ break;
+ case CLIPBOARD_FORMAT_BOOKMARK:
+#if defined(OS_WIN) || defined(OS_MACOSX)
+ result = clipboard_->IsFormatAvailable(ui::Clipboard::GetUrlWFormatType(),
+ type);
+#else
+ result = false;
+#endif
+ break;
+ }
+ std::move(callback).Run(result);
+}
+
+void ClipboardHostImpl::ReadText(ui::ClipboardType type,
+ ReadTextCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ base::string16 result;
+ if (clipboard_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
+ type)) {
+ clipboard_->ReadText(type, &result);
+ } else if (clipboard_->IsFormatAvailable(
+ ui::Clipboard::GetPlainTextFormatType(), type)) {
+ std::string ascii;
+ clipboard_->ReadAsciiText(type, &ascii);
+ result = base::ASCIIToUTF16(ascii);
+ }
+ std::move(callback).Run(result);
+}
+
+void ClipboardHostImpl::ReadHtml(ui::ClipboardType type,
+ ReadHtmlCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ base::string16 markup;
+ std::string src_url_str;
+ uint32_t fragment_start = 0;
+ uint32_t fragment_end = 0;
+ clipboard_->ReadHTML(type, &markup, &src_url_str, &fragment_start,
+ &fragment_end);
+ std::move(callback).Run(std::move(markup), GURL(src_url_str), fragment_start,
+ fragment_end);
+}
+
+void ClipboardHostImpl::ReadRtf(ui::ClipboardType type,
+ ReadRtfCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ std::string result;
+ clipboard_->ReadRTF(type, &result);
+ std::move(callback).Run(result);
+}
+
+void ClipboardHostImpl::ReadImage(ui::ClipboardType type,
+ ReadImageCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ SkBitmap bitmap = clipboard_->ReadImage(type);
+
+ base::PostTaskWithTraits(
+ FROM_HERE,
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
+ base::BindOnce(&ClipboardHostImpl::ReadAndEncodeImage,
+ base::Unretained(this), bitmap, std::move(callback)));
+}
+
+void ClipboardHostImpl::ReadAndEncodeImage(const SkBitmap& bitmap,
+ ReadImageCallback callback) {
+ if (!bitmap.isNull()) {
+ std::vector<uint8_t> png_data;
+ if (gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, &png_data)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&ClipboardHostImpl::OnReadAndEncodeImageFinished,
+ base::Unretained(this), std::move(png_data),
+ std::move(callback)));
+ return;
+ }
+ }
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::BindOnce(
+ [](ReadImageCallback callback) {
+ std::move(callback).Run(std::string(),
+ std::string(), -1);
+ },
+ std::move(callback)));
+}
+
+void ClipboardHostImpl::OnReadAndEncodeImageFinished(
+ std::vector<uint8_t> png_data,
+ ReadImageCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (png_data.size() < std::numeric_limits<uint32_t>::max()) {
+ std::unique_ptr<content::BlobHandle> blob_handle =
+ blob_storage_context_->CreateMemoryBackedBlob(
+ reinterpret_cast<char*>(png_data.data()), png_data.size(), "");
+ if (blob_handle) {
+ std::move(callback).Run(blob_handle->GetUUID(),
+ ui::Clipboard::kMimeTypePNG,
+ static_cast<int64_t>(png_data.size()));
+ // Give the renderer a minute to pick up a reference to the blob before
+ // giving up.
+ // TODO(dmurph): There should be a better way of transferring ownership of
+ // a blob from the browser to the renderer, rather than relying on this
+ // timeout to clean up eventually. See https://crbug.com/604800.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&CleanupReadImageBlob, base::Passed(&blob_handle)),
+ base::TimeDelta::FromMinutes(1));
+ return;
+ }
+ }
+ std::move(callback).Run(std::string(), std::string(), -1);
+}
+
+void ClipboardHostImpl::ReadCustomData(ui::ClipboardType clipboard_type,
+ const base::string16& type,
+ ReadCustomDataCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ base::string16 result;
+ clipboard_->ReadCustomData(clipboard_type, type, &result);
+ std::move(callback).Run(result);
+}
+
+void ClipboardHostImpl::WriteText(ui::ClipboardType clipboard_type,
+ const base::string16& text) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ clipboard_writer_->WriteText(text);
+}
+
+void ClipboardHostImpl::WriteHtml(ui::ClipboardType clipboard_type,
+ const base::string16& markup,
+ const GURL& url) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ clipboard_writer_->WriteHTML(markup, url.spec());
+}
+
+void ClipboardHostImpl::WriteSmartPasteMarker(
+ ui::ClipboardType clipboard_type) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ clipboard_writer_->WriteWebSmartPaste();
+}
+
+void ClipboardHostImpl::WriteCustomData(
+ ui::ClipboardType type,
+ const std::unordered_map<base::string16, base::string16>& data) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ base::Pickle pickle;
+ ui::WriteCustomDataToPickle(data, &pickle);
+ clipboard_writer_->WritePickledData(
+ pickle, ui::Clipboard::GetWebCustomDataFormatType());
+}
+
+void ClipboardHostImpl::WriteBookmark(ui::ClipboardType clipboard_type,
+ const std::string& url,
+ const base::string16& title) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ clipboard_writer_->WriteBookmark(title, url);
+}
+
+void ClipboardHostImpl::WriteImage(
+ ui::ClipboardType type,
+ const gfx::Size& size,
+ mojo::ScopedSharedBufferHandle shared_buffer_handle) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ SkBitmap bitmap;
+ // Let Skia do some sanity checking for (no negative widths/heights, no
+ // overflows while calculating bytes per row, etc).
+ if (!bitmap.setInfo(
+ SkImageInfo::MakeN32Premul(size.width(), size.height()))) {
+ return;
+ }
+
+ auto mapped = shared_buffer_handle->Map(bitmap.computeByteSize());
+ if (!mapped) {
+ return;
+ }
+
+ if (!bitmap.installPixels(bitmap.info(), mapped.get(), bitmap.rowBytes(),
+ &ReleaseSharedMemoryPixels, mapped.get())) {
+ return;
+ }
+
+ // On success, SkBitmap now owns the SharedMemory.
+ mapped.release();
+ clipboard_writer_->WriteImage(bitmap);
+}
+
+void ClipboardHostImpl::CommitWrite(ui::ClipboardType clipboard_type) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ clipboard_writer_.reset(
+ new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE));
+}
+
+#if !defined(OS_MACOSX)
+void ClipboardHostImpl::WriteStringToFindPboard(const base::string16& text) {
+ mojo::ReportBadMessage("Unexpected call to WriteStringToFindPboard.");
+}
+#endif
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/clipboard_host_impl.h b/chromium/content/browser/renderer_host/clipboard_host_impl.h
new file mode 100644
index 00000000000..8887586bf34
--- /dev/null
+++ b/chromium/content/browser/renderer_host/clipboard_host_impl.h
@@ -0,0 +1,98 @@
+// 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_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_
+#define CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/shared_memory.h"
+#include "build/build_config.h"
+#include "content/common/clipboard.mojom.h"
+#include "content/common/clipboard_format.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/browser_associated_interface.h"
+#include "content/public/browser/browser_message_filter.h"
+#include "ui/base/clipboard/clipboard.h"
+
+class GURL;
+
+namespace gfx {
+class Size;
+}
+
+namespace ui {
+class ScopedClipboardWriter;
+} // namespace ui
+
+namespace content {
+
+class ChromeBlobStorageContext;
+class ClipboardHostImplTest;
+
+class CONTENT_EXPORT ClipboardHostImpl : public mojom::ClipboardHost {
+ public:
+ ~ClipboardHostImpl() override;
+
+ static void Create(
+ scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
+ mojom::ClipboardHostRequest request);
+
+ private:
+ friend class ClipboardHostImplTest;
+
+ explicit ClipboardHostImpl(
+ scoped_refptr<ChromeBlobStorageContext> blob_storage_context);
+
+ void ReadAndEncodeImage(const SkBitmap& bitmap, ReadImageCallback callback);
+ void OnReadAndEncodeImageFinished(std::vector<uint8_t> png_data,
+ ReadImageCallback callback);
+
+ // content::mojom::ClipboardHost
+ void GetSequenceNumber(ui::ClipboardType type,
+ GetSequenceNumberCallback callback) override;
+ void IsFormatAvailable(content::ClipboardFormat format,
+ ui::ClipboardType type,
+ IsFormatAvailableCallback callback) override;
+ void ReadAvailableTypes(ui::ClipboardType type,
+ ReadAvailableTypesCallback callback) override;
+ void ReadText(ui::ClipboardType type, ReadTextCallback callback) override;
+ void ReadHtml(ui::ClipboardType type, ReadHtmlCallback callback) override;
+ void ReadRtf(ui::ClipboardType type, ReadRtfCallback callback) override;
+ void ReadImage(ui::ClipboardType type, ReadImageCallback callback) override;
+ void ReadCustomData(ui::ClipboardType clipboard_type,
+ const base::string16& type,
+ ReadCustomDataCallback callback) override;
+ void WriteText(ui::ClipboardType type, const base::string16& text) override;
+ void WriteHtml(ui::ClipboardType type,
+ const base::string16& markup,
+ const GURL& url) override;
+ void WriteSmartPasteMarker(ui::ClipboardType type) override;
+ void WriteCustomData(
+ ui::ClipboardType type,
+ const std::unordered_map<base::string16, base::string16>& data) override;
+ void WriteBookmark(ui::ClipboardType type,
+ const std::string& url,
+ const base::string16& title) override;
+ void WriteImage(ui::ClipboardType type,
+ const gfx::Size& size_in_pixels,
+ mojo::ScopedSharedBufferHandle shared_buffer_handle) override;
+ void CommitWrite(ui::ClipboardType type) override;
+ void WriteStringToFindPboard(const base::string16& text) override;
+
+ ui::Clipboard* clipboard_; // Not owned
+ scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
+ std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_
diff --git a/chromium/content/browser/renderer_host/clipboard_message_filter_mac.mm b/chromium/content/browser/renderer_host/clipboard_host_impl_mac.mm
index 18a908a2e73..b140c8d1d7b 100644
--- a/chromium/content/browser/renderer_host/clipboard_message_filter_mac.mm
+++ b/chromium/content/browser/renderer_host/clipboard_host_impl_mac.mm
@@ -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/browser/renderer_host/clipboard_message_filter.h"
+#include "content/browser/renderer_host/clipboard_host_impl.h"
#import <Cocoa/Cocoa.h>
#include <stddef.h>
@@ -21,36 +21,15 @@ namespace {
// The number of utf16 code units that will be written to the find pasteboard,
// longer texts are silently ignored. This is to prevent that a compromised
// renderer can write unlimited amounts of data into the find pasteboard.
-static const size_t kMaxFindPboardStringLength = 4096;
-
-class WriteFindPboardWrapper {
- public:
- explicit WriteFindPboardWrapper(NSString* text)
- : text_([text retain]) {}
-
- void Run() {
- [[FindPasteboard sharedInstance] setFindText:text_];
- }
-
- private:
- base::scoped_nsobject<NSString> text_;
-
- DISALLOW_COPY_AND_ASSIGN(WriteFindPboardWrapper);
-};
+static constexpr size_t kMaxFindPboardStringLength = 4096;
} // namespace
-// Called on the IO thread.
-void ClipboardMessageFilter::OnFindPboardWriteString(
- const base::string16& text) {
+void ClipboardHostImpl::WriteStringToFindPboard(const base::string16& text) {
if (text.length() <= kMaxFindPboardStringLength) {
NSString* nsText = base::SysUTF16ToNSString(text);
if (nsText) {
- // FindPasteboard must be used on the UI thread.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, base::Bind(
- &WriteFindPboardWrapper::Run,
- base::Owned(new WriteFindPboardWrapper(nsText))));
+ [[FindPasteboard sharedInstance] setFindText:nsText];
}
}
}
diff --git a/chromium/content/browser/renderer_host/clipboard_message_filter_unittest.cc b/chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc
index 976ebdba400..618b97cfca3 100644
--- a/chromium/content/browser/renderer_host/clipboard_message_filter_unittest.cc
+++ b/chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/renderer_host/clipboard_message_filter.h"
+#include "content/browser/renderer_host/clipboard_host_impl.h"
#include <stddef.h>
#include <stdint.h>
@@ -13,6 +13,7 @@
#include "base/run_loop.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "mojo/public/cpp/system/platform_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/test/test_clipboard.h"
@@ -20,53 +21,26 @@
namespace content {
-class ClipboardMessageFilterTest : public ::testing::Test {
+class ClipboardHostImplTest : public ::testing::Test {
protected:
- ClipboardMessageFilterTest()
- : filter_(new ClipboardMessageFilter(nullptr)),
- clipboard_(ui::TestClipboard::CreateForCurrentThread()) {
- filter_->set_peer_process_for_testing(base::Process::Current());
- }
+ ClipboardHostImplTest()
+ : host_(new ClipboardHostImpl(nullptr)),
+ clipboard_(ui::TestClipboard::CreateForCurrentThread()) {}
- ~ClipboardMessageFilterTest() override {
+ ~ClipboardHostImplTest() override {
ui::Clipboard::DestroyClipboardForCurrentThread();
}
- std::unique_ptr<base::SharedMemory> CreateAndMapReadOnlySharedMemory(
- size_t size) {
- std::unique_ptr<base::SharedMemory> m = CreateReadOnlySharedMemory(size);
- if (!m->Map(size))
- return nullptr;
- return m;
- }
-
- std::unique_ptr<base::SharedMemory> CreateReadOnlySharedMemory(size_t size) {
- std::unique_ptr<base::SharedMemory> m(new base::SharedMemory());
- base::SharedMemoryCreateOptions options;
- options.size = size;
- options.share_read_only = true;
- if (!m->Create(options))
- return nullptr;
- return m;
- }
-
void CallWriteImage(const gfx::Size& size,
- base::SharedMemory* shared_memory) {
- base::SharedMemoryHandle handle = shared_memory->GetReadOnlyHandle();
- shared_memory->Unmap();
- shared_memory->Close();
- ASSERT_TRUE(handle.IsValid());
- CallWriteImageDirectly(size, handle);
- }
-
- // Prefer to use CallWriteImage() in tests.
- void CallWriteImageDirectly(const gfx::Size& size,
- base::SharedMemoryHandle handle) {
- filter_->OnWriteImage(ui::CLIPBOARD_TYPE_COPY_PASTE, size, handle);
+ mojo::ScopedSharedBufferHandle shared_memory,
+ size_t shared_memory_size) {
+ host_->WriteImage(
+ ui::CLIPBOARD_TYPE_COPY_PASTE, size,
+ shared_memory->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY));
}
void CallCommitWrite() {
- filter_->OnCommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ host_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
base::RunLoop().RunUntilIdle();
}
@@ -74,24 +48,27 @@ class ClipboardMessageFilterTest : public ::testing::Test {
private:
const TestBrowserThreadBundle thread_bundle_;
- const scoped_refptr<ClipboardMessageFilter> filter_;
+ const std::unique_ptr<ClipboardHostImpl> host_;
ui::Clipboard* const clipboard_;
};
// Test that it actually works.
-TEST_F(ClipboardMessageFilterTest, SimpleImage) {
+TEST_F(ClipboardHostImplTest, SimpleImage) {
static const uint32_t bitmap_data[] = {
- 0x33333333, 0xdddddddd, 0xeeeeeeee, 0x00000000,
- 0x88888888, 0x66666666, 0x55555555, 0xbbbbbbbb,
- 0x44444444, 0xaaaaaaaa, 0x99999999, 0x77777777,
+ 0x33333333, 0xdddddddd, 0xeeeeeeee, 0x00000000, 0x88888888, 0x66666666,
+ 0x55555555, 0xbbbbbbbb, 0x44444444, 0xaaaaaaaa, 0x99999999, 0x77777777,
0xffffffff, 0x11111111, 0x22222222, 0xcccccccc,
};
- std::unique_ptr<base::SharedMemory> shared_memory =
- CreateAndMapReadOnlySharedMemory(sizeof(bitmap_data));
- memcpy(shared_memory->memory(), bitmap_data, sizeof(bitmap_data));
+ mojo::ScopedSharedBufferHandle shared_memory =
+ mojo::SharedBufferHandle::Create(sizeof(bitmap_data));
+ mojo::ScopedSharedBufferMapping mapping =
+ shared_memory->Map(sizeof(bitmap_data));
- CallWriteImage(gfx::Size(4, 4), shared_memory.get());
+ memcpy(mapping.get(), bitmap_data, sizeof(bitmap_data));
+
+ CallWriteImage(gfx::Size(4, 4), std::move(shared_memory),
+ sizeof(bitmap_data));
uint64_t sequence_number =
clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE);
CallCommitWrite();
@@ -110,11 +87,14 @@ TEST_F(ClipboardMessageFilterTest, SimpleImage) {
}
// Test with a size that would overflow a naive 32-bit row bytes calculation.
-TEST_F(ClipboardMessageFilterTest, ImageSizeOverflows32BitRowBytes) {
- std::unique_ptr<base::SharedMemory> shared_memory =
- CreateReadOnlySharedMemory(0x20000000);
+TEST_F(ClipboardHostImplTest, ImageSizeOverflows32BitRowBytes) {
+ mojo::ScopedSharedBufferHandle shared_memory =
+ mojo::SharedBufferHandle::Create(0x20000000);
+
+ mojo::ScopedSharedBufferMapping mapping = shared_memory->Map(0x20000000);
- CallWriteImage(gfx::Size(0x20000000, 1), shared_memory.get());
+ CallWriteImage(gfx::Size(0x20000000, 1), std::move(shared_memory),
+ 0x20000000);
uint64_t sequence_number =
clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE);
CallCommitWrite();
@@ -123,8 +103,9 @@ TEST_F(ClipboardMessageFilterTest, ImageSizeOverflows32BitRowBytes) {
clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE));
}
-TEST_F(ClipboardMessageFilterTest, InvalidSharedMemoryHandle) {
- CallWriteImageDirectly(gfx::Size(5, 5), base::SharedMemoryHandle());
+TEST_F(ClipboardHostImplTest, InvalidSharedMemoryHandle) {
+ mojo::ScopedSharedBufferHandle shared_memory;
+ CallWriteImage(gfx::Size(5, 5), std::move(shared_memory), 0);
uint64_t sequence_number =
clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE);
CallCommitWrite();
diff --git a/chromium/content/browser/renderer_host/clipboard_message_filter.cc b/chromium/content/browser/renderer_host/clipboard_message_filter.cc
deleted file mode 100644
index d12029e809e..00000000000
--- a/chromium/content/browser/renderer_host/clipboard_message_filter.cc
+++ /dev/null
@@ -1,328 +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/browser/renderer_host/clipboard_message_filter.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/location.h"
-#include "base/macros.h"
-#include "base/pickle.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/task_scheduler/post_task.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "build/build_config.h"
-#include "content/browser/blob_storage/chrome_blob_storage_context.h"
-#include "content/common/clipboard_messages.h"
-#include "content/public/browser/blob_handle.h"
-#include "content/public/browser/browser_context.h"
-#include "ipc/ipc_message_macros.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/base/clipboard/clipboard.h"
-#include "ui/base/clipboard/custom_data_helper.h"
-#include "ui/base/clipboard/scoped_clipboard_writer.h"
-#include "ui/gfx/codec/png_codec.h"
-#include "ui/gfx/geometry/size.h"
-#include "url/gurl.h"
-
-namespace content {
-
-namespace {
-
-void ReleaseSharedMemoryPixels(void* addr, void* context) {
- delete reinterpret_cast<base::SharedMemory*>(context);
-}
-
-// No-op helper for delayed cleanup of BlobHandles generated by reading
-// clipboard images.
-void CleanupReadImageBlob(std::unique_ptr<content::BlobHandle>) {}
-
-} // namespace
-
-ClipboardMessageFilter::ClipboardMessageFilter(
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context)
- : BrowserMessageFilter(ClipboardMsgStart),
- blob_storage_context_(std::move(blob_storage_context)),
- clipboard_writer_(
- new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)) {}
-
-void ClipboardMessageFilter::OverrideThreadForMessage(
- const IPC::Message& message, BrowserThread::ID* thread) {
- // Clipboard writes should always occur on the UI thread due the restrictions
- // of various platform APIs. In general, the clipboard is not thread-safe, so
- // all clipboard calls should be serviced from the UI thread.
- //
- // Windows needs clipboard reads to be serviced from the IO thread because
- // these are sync IPCs which can result in deadlocks with NPAPI plugins if
- // serviced from the UI thread. Note that Windows clipboard calls ARE
- // thread-safe so it is ok for reads and writes to be serviced from different
- // threads.
-#if !defined(OS_WIN)
- if (IPC_MESSAGE_CLASS(message) == ClipboardMsgStart)
- *thread = BrowserThread::UI;
-#endif
-}
-
-bool ClipboardMessageFilter::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(ClipboardMessageFilter, message)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_GetSequenceNumber, OnGetSequenceNumber)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_IsFormatAvailable, OnIsFormatAvailable)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_Clear, OnClear)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadAvailableTypes,
- OnReadAvailableTypes)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadText, OnReadText)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadHTML, OnReadHTML)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadRTF, OnReadRTF)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(ClipboardHostMsg_ReadImage, OnReadImage)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadCustomData, OnReadCustomData)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteText, OnWriteText)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteHTML, OnWriteHTML)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteSmartPasteMarker,
- OnWriteSmartPasteMarker)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteCustomData, OnWriteCustomData)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteBookmark, OnWriteBookmark)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_WriteImage, OnWriteImage)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_CommitWrite, OnCommitWrite);
-#if defined(OS_MACOSX)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_FindPboardWriteStringAsync,
- OnFindPboardWriteString)
-#endif
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-ClipboardMessageFilter::~ClipboardMessageFilter() {
- clipboard_writer_->Reset();
-}
-
-void ClipboardMessageFilter::OnGetSequenceNumber(ui::ClipboardType type,
- uint64_t* sequence_number) {
- *sequence_number = GetClipboard()->GetSequenceNumber(type);
-}
-
-void ClipboardMessageFilter::OnReadAvailableTypes(
- ui::ClipboardType type,
- std::vector<base::string16>* types,
- bool* contains_filenames) {
- GetClipboard()->ReadAvailableTypes(type, types, contains_filenames);
-}
-
-void ClipboardMessageFilter::OnIsFormatAvailable(ClipboardFormat format,
- ui::ClipboardType type,
- bool* result) {
- switch (format) {
- case CLIPBOARD_FORMAT_PLAINTEXT:
- *result = GetClipboard()->IsFormatAvailable(
- ui::Clipboard::GetPlainTextWFormatType(), type) ||
- GetClipboard()->IsFormatAvailable(
- ui::Clipboard::GetPlainTextFormatType(), type);
- break;
- case CLIPBOARD_FORMAT_HTML:
- *result = GetClipboard()->IsFormatAvailable(
- ui::Clipboard::GetHtmlFormatType(), type);
- break;
- case CLIPBOARD_FORMAT_SMART_PASTE:
- *result = GetClipboard()->IsFormatAvailable(
- ui::Clipboard::GetWebKitSmartPasteFormatType(), type);
- break;
- case CLIPBOARD_FORMAT_BOOKMARK:
-#if defined(OS_WIN) || defined(OS_MACOSX)
- *result = GetClipboard()->IsFormatAvailable(
- ui::Clipboard::GetUrlWFormatType(), type);
-#else
- *result = false;
-#endif
- break;
- }
-}
-
-void ClipboardMessageFilter::OnClear(ui::ClipboardType type) {
- GetClipboard()->Clear(type);
-}
-
-void ClipboardMessageFilter::OnReadText(ui::ClipboardType type,
- base::string16* result) {
- if (GetClipboard()->IsFormatAvailable(
- ui::Clipboard::GetPlainTextWFormatType(), type)) {
- GetClipboard()->ReadText(type, result);
- } else if (GetClipboard()->IsFormatAvailable(
- ui::Clipboard::GetPlainTextFormatType(), type)) {
- std::string ascii;
- GetClipboard()->ReadAsciiText(type, &ascii);
- *result = base::ASCIIToUTF16(ascii);
- } else {
- result->clear();
- }
-}
-
-void ClipboardMessageFilter::OnReadHTML(ui::ClipboardType type,
- base::string16* markup,
- GURL* url,
- uint32_t* fragment_start,
- uint32_t* fragment_end) {
- std::string src_url_str;
- GetClipboard()->ReadHTML(type, markup, &src_url_str, fragment_start,
- fragment_end);
- *url = GURL(src_url_str);
-}
-
-void ClipboardMessageFilter::OnReadRTF(ui::ClipboardType type,
- std::string* result) {
- GetClipboard()->ReadRTF(type, result);
-}
-
-void ClipboardMessageFilter::OnReadImage(ui::ClipboardType type,
- IPC::Message* reply_msg) {
- SkBitmap bitmap = GetClipboard()->ReadImage(type);
-
- base::PostTaskWithTraits(
- FROM_HERE,
- {base::MayBlock(), base::TaskPriority::BACKGROUND,
- base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
- base::BindOnce(&ClipboardMessageFilter::ReadAndEncodeImage, this, bitmap,
- reply_msg));
-}
-
-void ClipboardMessageFilter::ReadAndEncodeImage(const SkBitmap& bitmap,
- IPC::Message* reply_msg) {
- if (!bitmap.isNull()) {
- std::unique_ptr<std::vector<uint8_t>> png_data(new std::vector<uint8_t>);
- if (gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, png_data.get())) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&ClipboardMessageFilter::OnReadAndEncodeImageFinished,
- this, base::Passed(&png_data), reply_msg));
- return;
- }
- }
- ClipboardHostMsg_ReadImage::WriteReplyParams(reply_msg, std::string(),
- std::string(), -1);
- Send(reply_msg);
-}
-
-void ClipboardMessageFilter::OnReadAndEncodeImageFinished(
- std::unique_ptr<std::vector<uint8_t>> png_data,
- IPC::Message* reply_msg) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (png_data->size() < std::numeric_limits<uint32_t>::max()) {
- std::unique_ptr<content::BlobHandle> blob_handle =
- blob_storage_context_->CreateMemoryBackedBlob(
- reinterpret_cast<char*>(png_data->data()), png_data->size());
- if (blob_handle) {
- ClipboardHostMsg_ReadImage::WriteReplyParams(
- reply_msg, blob_handle->GetUUID(), ui::Clipboard::kMimeTypePNG,
- static_cast<int64_t>(png_data->size()));
- Send(reply_msg);
- // Give the renderer a minute to pick up a reference to the blob before
- // giving up.
- // TODO(dmurph): There should be a better way of transferring ownership of
- // a blob from the browser to the renderer, rather than relying on this
- // timeout to clean up eventually. See https://crbug.com/604800.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&CleanupReadImageBlob, base::Passed(&blob_handle)),
- base::TimeDelta::FromMinutes(1));
- return;
- }
- }
- ClipboardHostMsg_ReadImage::WriteReplyParams(reply_msg, std::string(),
- std::string(), -1);
- Send(reply_msg);
-}
-
-void ClipboardMessageFilter::OnReadCustomData(ui::ClipboardType clipboard_type,
- const base::string16& type,
- base::string16* result) {
- GetClipboard()->ReadCustomData(clipboard_type, type, result);
-}
-
-void ClipboardMessageFilter::OnWriteText(ui::ClipboardType clipboard_type,
- const base::string16& text) {
- clipboard_writer_->WriteText(text);
-}
-
-void ClipboardMessageFilter::OnWriteHTML(ui::ClipboardType clipboard_type,
- const base::string16& markup,
- const GURL& url) {
- clipboard_writer_->WriteHTML(markup, url.spec());
-}
-
-void ClipboardMessageFilter::OnWriteSmartPasteMarker(
- ui::ClipboardType clipboard_type) {
- clipboard_writer_->WriteWebSmartPaste();
-}
-
-void ClipboardMessageFilter::OnWriteCustomData(
- ui::ClipboardType clipboard_type,
- const std::map<base::string16, base::string16>& data) {
- base::Pickle pickle;
- ui::WriteCustomDataToPickle(data, &pickle);
- clipboard_writer_->WritePickledData(
- pickle, ui::Clipboard::GetWebCustomDataFormatType());
-}
-
-void ClipboardMessageFilter::OnWriteBookmark(ui::ClipboardType clipboard_type,
- const std::string& url,
- const base::string16& title) {
- clipboard_writer_->WriteBookmark(title, url);
-}
-
-void ClipboardMessageFilter::OnWriteImage(ui::ClipboardType clipboard_type,
- const gfx::Size& size,
- base::SharedMemoryHandle handle) {
- if (!base::SharedMemory::IsHandleValid(handle)) {
- return;
- }
-
- std::unique_ptr<base::SharedMemory> bitmap_buffer(
- new base::SharedMemory(handle, true));
-
- SkBitmap bitmap;
- // Let Skia do some sanity checking for (no negative widths/heights, no
- // overflows while calculating bytes per row, etc).
- if (!bitmap.setInfo(
- SkImageInfo::MakeN32Premul(size.width(), size.height()))) {
- return;
- }
-
- if (!bitmap_buffer->Map(bitmap.computeByteSize()))
- return;
-
- if (!bitmap.installPixels(bitmap.info(), bitmap_buffer->memory(),
- bitmap.rowBytes(), &ReleaseSharedMemoryPixels,
- bitmap_buffer.get()))
- return;
-
- // On success, SkBitmap now owns the SharedMemory.
- ignore_result(bitmap_buffer.release());
- clipboard_writer_->WriteImage(bitmap);
-}
-
-void ClipboardMessageFilter::OnCommitWrite(ui::ClipboardType clipboard_type) {
-#if defined(OS_WIN)
- // On non-Windows platforms, all clipboard IPCs are handled on the UI thread.
- // However, Windows handles the clipboard IPCs on the IO thread to prevent
- // deadlocks. Clipboard writes must still occur on the UI thread because the
- // clipboard object from the IO thread cannot create windows so it cannot be
- // the "owner" of the clipboard's contents. See http://crbug.com/5823.
- BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE,
- clipboard_writer_.release());
-#endif
- clipboard_writer_.reset(
- new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE));
-}
-
-// static
-ui::Clipboard* ClipboardMessageFilter::GetClipboard() {
- // We have a static instance of the clipboard service for use by all message
- // filters. This instance lives for the life of the browser processes.
- static ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
- return clipboard;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/renderer_host/clipboard_message_filter.h b/chromium/content/browser/renderer_host/clipboard_message_filter.h
deleted file mode 100644
index e74d9aeb4ae..00000000000
--- a/chromium/content/browser/renderer_host/clipboard_message_filter.h
+++ /dev/null
@@ -1,113 +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_BROWSER_RENDERER_HOST_CLIPBOARD_MESSAGE_FILTER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_MESSAGE_FILTER_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/shared_memory.h"
-#include "build/build_config.h"
-#include "content/common/clipboard_format.h"
-#include "content/common/content_export.h"
-#include "content/public/browser/browser_message_filter.h"
-#include "ui/base/clipboard/clipboard.h"
-
-class GURL;
-
-namespace gfx {
-class Size;
-}
-
-namespace ui {
-class ScopedClipboardWriter;
-} // namespace ui
-
-namespace content {
-
-class ChromeBlobStorageContext;
-class ClipboardMessageFilterTest;
-
-class CONTENT_EXPORT ClipboardMessageFilter : public BrowserMessageFilter {
- public:
- explicit ClipboardMessageFilter(
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context);
-
- void OverrideThreadForMessage(const IPC::Message& message,
- BrowserThread::ID* thread) override;
- bool OnMessageReceived(const IPC::Message& message) override;
-
- private:
- friend class ClipboardMessageFilterTest;
-
- ~ClipboardMessageFilter() override;
-
- void OnGetSequenceNumber(const ui::ClipboardType type,
- uint64_t* sequence_number);
- void OnIsFormatAvailable(ClipboardFormat format,
- ui::ClipboardType type,
- bool* result);
- void OnClear(ui::ClipboardType type);
- void OnReadAvailableTypes(ui::ClipboardType type,
- std::vector<base::string16>* types,
- bool* contains_filenames);
- void OnReadText(ui::ClipboardType type, base::string16* result);
- void OnReadHTML(ui::ClipboardType type,
- base::string16* markup,
- GURL* url,
- uint32_t* fragment_start,
- uint32_t* fragment_end);
- void OnReadRTF(ui::ClipboardType type, std::string* result);
- void OnReadImage(ui::ClipboardType type, IPC::Message* reply_msg);
- void ReadAndEncodeImage(const SkBitmap& bitmap, IPC::Message* reply_msg);
- void OnReadAndEncodeImageFinished(
- std::unique_ptr<std::vector<uint8_t>> png_data,
- IPC::Message* reply_msg);
- void OnReadCustomData(ui::ClipboardType clipboard_type,
- const base::string16& type,
- base::string16* result);
- void OnReadData(const ui::Clipboard::FormatType& format,
- std::string* data);
-
- void OnWriteText(ui::ClipboardType clipboard_type,
- const base::string16& text);
- void OnWriteHTML(ui::ClipboardType clipboard_type,
- const base::string16& markup,
- const GURL& url);
- void OnWriteSmartPasteMarker(ui::ClipboardType clipboard_type);
- void OnWriteCustomData(ui::ClipboardType clipboard_type,
- const std::map<base::string16, base::string16>& data);
- void OnWriteBookmark(ui::ClipboardType clipboard_type,
- const std::string& url,
- const base::string16& title);
- void OnWriteImage(ui::ClipboardType clipboard_type,
- const gfx::Size& size,
- base::SharedMemoryHandle handle);
- void OnCommitWrite(ui::ClipboardType clipboard_type);
-
-#if defined(OS_MACOSX)
- void OnFindPboardWriteString(const base::string16& text);
-#endif
-
- // We have our own clipboard because we want to access the clipboard on the
- // IO thread instead of forwarding (possibly synchronous) messages to the UI
- // thread. This instance of the clipboard should be accessed only on the IO
- // thread.
- static ui::Clipboard* GetClipboard();
-
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
- std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_;
-
- DISALLOW_COPY_AND_ASSIGN(ClipboardMessageFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_MESSAGE_FILTER_H_
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.cc b/chromium/content/browser/renderer_host/compositor_impl_android.cc
index dc6723d2413..23b66fe5d02 100644
--- a/chromium/content/browser/renderer_host/compositor_impl_android.cc
+++ b/chromium/content/browser/renderer_host/compositor_impl_android.cc
@@ -47,7 +47,6 @@
#include "components/viz/service/display/output_surface.h"
#include "components/viz/service/display/output_surface_client.h"
#include "components/viz/service/display/output_surface_frame.h"
-#include "components/viz/service/display/texture_mailbox_deleter.h"
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
@@ -60,7 +59,6 @@
#include "content/public/browser/android/compositor.h"
#include "content/public/browser/android/compositor_client.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/ipc/client/command_buffer_proxy_impl.h"
@@ -224,6 +222,8 @@ gpu::gles2::ContextCreationAttribHelper GetCompositorContextAttributes(
attributes.blue_size = 5;
}
+ attributes.enable_swap_timestamps_if_supported = true;
+
return attributes;
}
@@ -242,8 +242,8 @@ void CreateContextProviderAfterGpuChannelEstablished(
constexpr bool automatic_flushes = false;
constexpr bool support_locking = false;
- scoped_refptr<ui::ContextProviderCommandBuffer> context_provider =
- new ui::ContextProviderCommandBuffer(
+ auto context_provider =
+ base::MakeRefCounted<ui::ContextProviderCommandBuffer>(
std::move(gpu_channel_host), stream_id, stream_priority, handle,
GURL(std::string("chrome://gpu/Compositor::CreateContextProvider")),
automatic_flushes, support_locking, shared_memory_limits, attributes,
@@ -252,7 +252,9 @@ void CreateContextProviderAfterGpuChannelEstablished(
callback.Run(std::move(context_provider));
}
-class AndroidOutputSurface : public viz::OutputSurface {
+class AndroidOutputSurface
+ : public viz::OutputSurface,
+ public viz::OutputSurface::LatencyInfoCache::Client {
public:
AndroidOutputSurface(
scoped_refptr<ui::ContextProviderCommandBuffer> context_provider,
@@ -261,6 +263,7 @@ class AndroidOutputSurface : public viz::OutputSurface {
swap_buffers_callback_(std::move(swap_buffers_callback)),
overlay_candidate_validator_(
new viz::CompositorOverlayCandidateValidatorAndroid()),
+ latency_info_cache_(this),
weak_ptr_factory_(this) {
capabilities_.max_frames_pending = kMaxDisplaySwapBuffers;
}
@@ -268,7 +271,9 @@ class AndroidOutputSurface : public viz::OutputSurface {
~AndroidOutputSurface() override = default;
void SwapBuffers(viz::OutputSurfaceFrame frame) override {
- GetCommandBufferProxy()->AddLatencyInfo(frame.latency_info);
+ if (latency_info_cache_.WillSwap(std::move(frame.latency_info)))
+ GetCommandBufferProxy()->SetSnapshotRequested();
+
if (frame.sub_buffer_rect) {
DCHECK(frame.sub_buffer_rect->IsEmpty());
context_provider_->ContextSupport()->CommitOverlayPlanes();
@@ -277,6 +282,12 @@ class AndroidOutputSurface : public viz::OutputSurface {
}
}
+ // OutputSurface::LatencyInfoCache::Client implementation.
+ void LatencyInfoCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info) override {
+ RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(latency_info);
+ }
+
void BindToClient(viz::OutputSurfaceClient* client) override {
DCHECK(client);
DCHECK(!client_);
@@ -339,18 +350,19 @@ class AndroidOutputSurface : public viz::OutputSurface {
}
void OnSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info,
- gfx::SwapResult result,
+ const gfx::SwapResponse& response,
const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) {
- RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(latency_info);
- client_->DidReceiveSwapBuffersAck();
+ client_->DidReceiveSwapBuffersAck(response.swap_id);
swap_buffers_callback_.Run();
+ latency_info_cache_.OnSwapBuffersCompleted(response);
}
private:
viz::OutputSurfaceClient* client_ = nullptr;
base::Closure swap_buffers_callback_;
std::unique_ptr<viz::OverlayCandidateValidator> overlay_candidate_validator_;
+ LatencyInfoCache latency_info_cache_;
+
base::WeakPtrFactory<AndroidOutputSurface> weak_ptr_factory_;
};
@@ -471,7 +483,6 @@ CompositorImpl::CompositorImpl(CompositorClient* client,
root_window_(root_window),
needs_animate_(false),
pending_frames_(0U),
- num_successive_context_creation_failures_(0),
layer_tree_frame_sink_request_pending_(false),
weak_factory_(this) {
GetHostFrameSinkManager()->RegisterFrameSinkId(frame_sink_id_, this);
@@ -489,9 +500,14 @@ CompositorImpl::CompositorImpl(CompositorClient* client,
root_window->AttachCompositor(this);
CreateLayerTreeHost();
resource_manager_.Init(host_->GetUIResourceManager());
+
+ // Listen to display density change events and update painted device scale
+ // factor accordingly.
+ display::Screen::GetScreen()->AddObserver(this);
}
CompositorImpl::~CompositorImpl() {
+ display::Screen::GetScreen()->RemoveObserver(this);
root_window_->DetachCompositor();
root_window_->SetLayer(nullptr);
// Clean-up any surface references.
@@ -555,6 +571,11 @@ void CompositorImpl::SetSurface(jobject surface) {
}
}
+void CompositorImpl::SetBackgroundColor(int color) {
+ DCHECK(host_);
+ host_->set_background_color(color);
+}
+
void CompositorImpl::CreateLayerTreeHost() {
DCHECK(!host_);
@@ -584,6 +605,7 @@ void CompositorImpl::CreateLayerTreeHost() {
host_->SetFrameSinkId(frame_sink_id_);
host_->SetViewportSize(size_);
host_->SetDeviceScaleFactor(1);
+ host_->SetPaintedDeviceScaleFactor(root_window_->GetDipScale());
if (needs_animate_)
host_->SetNeedsAnimate();
@@ -628,6 +650,10 @@ void CompositorImpl::SetWindowBounds(const gfx::Size& size) {
root_window_->GetLayer()->SetBounds(size);
}
+void CompositorImpl::SetDeferCommits(bool defer_commits) {
+ host_->SetDeferCommits(defer_commits);
+}
+
void CompositorImpl::SetRequiresAlphaChannel(bool flag) {
requires_alpha_channel_ = flag;
}
@@ -683,25 +709,6 @@ void CompositorImpl::HandlePendingLayerTreeFrameSinkRequest() {
return;
#endif
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableTimeoutsForProfiling)) {
-#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
- defined(SYZYASAN) || defined(CYGPROFILE_INSTRUMENTATION)
- const int64_t kGpuChannelTimeoutInSeconds = 40;
-#else
- // The GPU watchdog timeout is 15 seconds (1.5x the kGpuTimeout value due to
- // logic in GpuWatchdogThread). Make this slightly longer to give the GPU a
- // chance to crash itself before crashing the browser.
- const int64_t kGpuChannelTimeoutInSeconds = 20;
-#endif
-
- // Start the timer first, if the result comes synchronously, we want it to
- // stop in the callback.
- establish_gpu_channel_timeout_.Start(
- FROM_HERE, base::TimeDelta::FromSeconds(kGpuChannelTimeoutInSeconds),
- this, &CompositorImpl::OnGpuChannelTimeout);
- }
-
DCHECK(surface_handle_ != gpu::kNullSurfaceHandle);
BrowserMainLoop::GetInstance()
->gpu_channel_establish_factory()
@@ -709,10 +716,6 @@ void CompositorImpl::HandlePendingLayerTreeFrameSinkRequest() {
weak_factory_.GetWeakPtr()));
}
-void CompositorImpl::OnGpuChannelTimeout() {
- LOG(FATAL) << "Timed out waiting for GPU channel.";
-}
-
#if BUILDFLAG(ENABLE_VULKAN)
void CompositorImpl::CreateVulkanOutputSurface() {
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -725,7 +728,7 @@ void CompositorImpl::CreateVulkanOutputSurface() {
return;
// TODO(crbug.com/582558): Need to match GL and implement DidSwapBuffers.
- auto vulkan_surface = base::MakeUnique<VulkanOutputSurface>(
+ auto vulkan_surface = std::make_unique<VulkanOutputSurface>(
vulkan_context_provider, base::ThreadTaskRunnerHandle::Get());
if (!vulkan_surface->Initialize(window_))
return;
@@ -737,8 +740,6 @@ void CompositorImpl::CreateVulkanOutputSurface() {
void CompositorImpl::OnGpuChannelEstablished(
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
- establish_gpu_channel_timeout_.Stop();
-
// 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.
@@ -767,8 +768,8 @@ void CompositorImpl::OnGpuChannelEstablished(
.color_space();
ui::ContextProviderCommandBuffer* shared_context = nullptr;
- scoped_refptr<ui::ContextProviderCommandBuffer> context_provider =
- new ui::ContextProviderCommandBuffer(
+ auto context_provider =
+ base::MakeRefCounted<ui::ContextProviderCommandBuffer>(
std::move(gpu_channel_host), stream_id, stream_priority,
surface_handle_,
GURL(std::string("chrome://gpu/CompositorImpl::") +
@@ -779,16 +780,16 @@ void CompositorImpl::OnGpuChannelEstablished(
requires_alpha_channel_),
shared_context,
ui::command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT);
- if (!context_provider->BindToCurrentThread()) {
- LOG(ERROR) << "Failed to init viz::ContextProvider for compositor.";
- LOG_IF(FATAL, ++num_successive_context_creation_failures_ >= 2)
- << "Too many context creation failures. Giving up... ";
+ auto result = context_provider->BindToCurrentThread();
+ LOG_IF(FATAL, result == gpu::ContextResult::kFatalFailure)
+ << "Fatal error making Gpu context";
+ if (result != gpu::ContextResult::kSuccess) {
HandlePendingLayerTreeFrameSinkRequest();
return;
}
// Unretained is safe this owns viz::Display which owns OutputSurface.
- auto display_output_surface = base::MakeUnique<AndroidOutputSurface>(
+ auto display_output_surface = std::make_unique<AndroidOutputSurface>(
context_provider,
base::Bind(&CompositorImpl::DidSwapBuffers, base::Unretained(this)));
InitializeDisplay(std::move(display_output_surface), nullptr,
@@ -802,7 +803,6 @@ void CompositorImpl::InitializeDisplay(
DCHECK(layer_tree_frame_sink_request_pending_);
pending_frames_ = 0;
- num_successive_context_creation_failures_ = 0;
if (context_provider) {
gpu_capabilities_ = context_provider->ContextCapabilities();
@@ -811,9 +811,10 @@ void CompositorImpl::InitializeDisplay(
}
viz::FrameSinkManagerImpl* manager = GetFrameSinkManager();
- auto* task_runner = base::ThreadTaskRunnerHandle::Get().get();
- auto scheduler = base::MakeUnique<viz::DisplayScheduler>(
- root_window_->GetBeginFrameSource(), task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ base::ThreadTaskRunnerHandle::Get();
+ auto scheduler = std::make_unique<viz::DisplayScheduler>(
+ root_window_->GetBeginFrameSource(), task_runner.get(),
display_output_surface->capabilities().max_frames_pending);
viz::RendererSettings renderer_settings;
@@ -822,18 +823,21 @@ void CompositorImpl::InitializeDisplay(
auto* gpu_memory_buffer_manager = BrowserMainLoop::GetInstance()
->gpu_channel_establish_factory()
->GetGpuMemoryBufferManager();
- display_ = base::MakeUnique<viz::Display>(
+
+ // Don't re-register BeginFrameSource on context loss.
+ const bool should_register_begin_frame_source = !display_;
+
+ display_ = std::make_unique<viz::Display>(
viz::ServerSharedBitmapManager::current(), gpu_memory_buffer_manager,
renderer_settings, frame_sink_id_, std::move(display_output_surface),
- std::move(scheduler),
- base::MakeUnique<viz::TextureMailboxDeleter>(task_runner));
+ std::move(scheduler), std::move(task_runner));
auto layer_tree_frame_sink =
vulkan_context_provider
- ? base::MakeUnique<viz::DirectLayerTreeFrameSink>(
+ ? std::make_unique<viz::DirectLayerTreeFrameSink>(
frame_sink_id_, GetHostFrameSinkManager(), manager,
display_.get(), vulkan_context_provider)
- : base::MakeUnique<viz::DirectLayerTreeFrameSink>(
+ : std::make_unique<viz::DirectLayerTreeFrameSink>(
frame_sink_id_, GetHostFrameSinkManager(), manager,
display_.get(), context_provider,
nullptr /* worker_context_provider */,
@@ -843,8 +847,10 @@ void CompositorImpl::InitializeDisplay(
display_->SetVisible(true);
display_->Resize(size_);
display_->SetColorSpace(display_color_space_, display_color_space_);
- GetFrameSinkManager()->RegisterBeginFrameSource(
- root_window_->GetBeginFrameSource(), frame_sink_id_);
+ if (should_register_begin_frame_source) {
+ GetFrameSinkManager()->RegisterBeginFrameSource(
+ root_window_->GetBeginFrameSource(), frame_sink_id_);
+ }
host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
}
@@ -937,6 +943,17 @@ void CompositorImpl::OnFirstSurfaceActivation(
// surface should be set here.
}
+void CompositorImpl::OnDisplayMetricsChanged(const display::Display& display,
+ uint32_t changed_metrics) {
+ if (changed_metrics & display::DisplayObserver::DisplayMetric::
+ DISPLAY_METRIC_DEVICE_SCALE_FACTOR &&
+ display.id() == display::Screen::GetScreen()
+ ->GetDisplayNearestWindow(root_window_)
+ .id()) {
+ host_->SetPaintedDeviceScaleFactor(root_window_->GetDipScale());
+ }
+}
+
bool CompositorImpl::HavePendingReadbacks() {
return !readback_layer_tree_->children().empty();
}
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.h b/chromium/content/browser/renderer_host/compositor_impl_android.h
index 96ed03e63c8..80fabcb1357 100644
--- a/chromium/content/browser/renderer_host/compositor_impl_android.h
+++ b/chromium/content/browser/renderer_host/compositor_impl_android.h
@@ -14,7 +14,6 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
-#include "base/timer/timer.h"
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
@@ -29,6 +28,7 @@
#include "ui/android/resources/resource_manager_impl.h"
#include "ui/android/resources/ui_resource_provider.h"
#include "ui/android/window_android_compositor.h"
+#include "ui/display/display_observer.h"
struct ANativeWindow;
@@ -59,7 +59,8 @@ class CONTENT_EXPORT CompositorImpl
public cc::LayerTreeHostSingleThreadClient,
public ui::UIResourceProvider,
public ui::WindowAndroidCompositor,
- public viz::HostFrameSinkClient {
+ public viz::HostFrameSinkClient,
+ public display::DisplayObserver {
public:
CompositorImpl(CompositorClient* client, gfx::NativeWindow root_window);
~CompositorImpl() override;
@@ -79,7 +80,9 @@ class CONTENT_EXPORT CompositorImpl
// Compositor implementation.
void SetRootLayer(scoped_refptr<cc::Layer> root) override;
void SetSurface(jobject surface) override;
+ void SetBackgroundColor(int color) override;
void SetWindowBounds(const gfx::Size& size) override;
+ void SetDeferCommits(bool defer_commits) override;
void SetRequiresAlphaChannel(bool flag) override;
void SetNeedsComposite() override;
ui::UIResourceProvider& GetUIResourceProvider() override;
@@ -124,6 +127,11 @@ class CONTENT_EXPORT CompositorImpl
// viz::HostFrameSinkClient implementation.
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
+ void OnFrameTokenChanged(uint32_t frame_token) override {}
+
+ // display::DisplayObserver implementation.
+ void OnDisplayMetricsChanged(const display::Display& display,
+ uint32_t changed_metrics) override;
void SetVisible(bool visible);
void CreateLayerTreeHost();
@@ -135,7 +143,6 @@ class CONTENT_EXPORT CompositorImpl
#endif
void OnGpuChannelEstablished(
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host);
- void OnGpuChannelTimeout();
void InitializeDisplay(
std::unique_ptr<viz::OutputSurface> display_output_surface,
scoped_refptr<viz::VulkanContextProvider> vulkan_context_provider,
@@ -178,10 +185,6 @@ class CONTENT_EXPORT CompositorImpl
// the GPU thread.
unsigned int pending_frames_;
- size_t num_successive_context_creation_failures_;
-
- base::OneShotTimer establish_gpu_channel_timeout_;
-
// Whether there is a LayerTreeFrameSink request pending from the current
// |host_|. Becomes |true| if RequestNewLayerTreeFrameSink is called, and
// |false| if |host_| is deleted or we succeed in creating *and* initializing
diff --git a/chromium/content/browser/renderer_host/compositor_resize_lock.cc b/chromium/content/browser/renderer_host/compositor_resize_lock.cc
index 4c3e34cced8..7336dba0aa4 100644
--- a/chromium/content/browser/renderer_host/compositor_resize_lock.cc
+++ b/chromium/content/browser/renderer_host/compositor_resize_lock.cc
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/compositor_resize_lock.h"
+#include "base/metrics/histogram_macros.h"
#include "base/trace_event/trace_event.h"
#include "content/public/browser/browser_thread.h"
#include "ui/compositor/compositor.h"
@@ -12,7 +13,9 @@ namespace content {
CompositorResizeLock::CompositorResizeLock(CompositorResizeLockClient* client,
const gfx::Size& new_size)
- : client_(client), expected_size_(new_size) {
+ : client_(client),
+ expected_size_(new_size),
+ acquisition_time_(base::TimeTicks::Now()) {
TRACE_EVENT_ASYNC_BEGIN2("ui", "CompositorResizeLock", this, "width",
expected_size().width(), "height",
expected_size().height());
@@ -26,6 +29,11 @@ CompositorResizeLock::~CompositorResizeLock() {
TRACE_EVENT_ASYNC_END2("ui", "CompositorResizeLock", this, "width",
expected_size().width(), "height",
expected_size().height());
+
+ UMA_HISTOGRAM_TIMES("UI.CompositorResizeLock.Duration",
+ base::TimeTicks::Now() - acquisition_time_);
+
+ UMA_HISTOGRAM_BOOLEAN("UI.CompositorResizeLock.TimedOut", timed_out_);
}
bool CompositorResizeLock::Lock() {
diff --git a/chromium/content/browser/renderer_host/compositor_resize_lock.h b/chromium/content/browser/renderer_host/compositor_resize_lock.h
index eab4c0b955e..23036898b9f 100644
--- a/chromium/content/browser/renderer_host/compositor_resize_lock.h
+++ b/chromium/content/browser/renderer_host/compositor_resize_lock.h
@@ -58,6 +58,7 @@ class CONTENT_EXPORT CompositorResizeLock : public ui::CompositorLockClient {
std::unique_ptr<ui::CompositorLock> compositor_lock_;
bool unlocked_ = false;
bool timed_out_ = false;
+ const base::TimeTicks acquisition_time_;
DISALLOW_COPY_AND_ASSIGN(CompositorResizeLock);
};
diff --git a/chromium/content/browser/renderer_host/cursor_manager_unittest.cc b/chromium/content/browser/renderer_host/cursor_manager_unittest.cc
index 86ed91c4bc9..5eb79bc7e88 100644
--- a/chromium/content/browser/renderer_host/cursor_manager_unittest.cc
+++ b/chromium/content/browser/renderer_host/cursor_manager_unittest.cc
@@ -53,7 +53,7 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
int32_t routing_id) {
mojom::WidgetPtr widget;
std::unique_ptr<MockWidgetImpl> widget_impl =
- base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
return new MockRenderWidgetHost(delegate, process, routing_id,
std::move(widget_impl), std::move(widget));
diff --git a/chromium/content/browser/renderer_host/delegated_frame_host.cc b/chromium/content/browser/renderer_host/delegated_frame_host.cc
index 60da0849fe7..e29dac1d5ac 100644
--- a/chromium/content/browser/renderer_host/delegated_frame_host.cc
+++ b/chromium/content/browser/renderer_host/delegated_frame_host.cc
@@ -17,8 +17,8 @@
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/gl_helper.h"
#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/texture_mailbox.h"
#include "components/viz/common/resources/single_release_callback.h"
+#include "components/viz/common/surfaces/stub_surface_reference_factory.h"
#include "components/viz/common/switches.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
@@ -30,6 +30,8 @@
#include "content/browser/renderer_host/compositor_resize_lock.h"
#include "content/browser/renderer_host/render_widget_host_view_frame_subscriber.h"
#include "content/public/common/content_switches.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/sync_token.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "skia/ext/image_operations.h"
@@ -45,15 +47,15 @@ namespace content {
DelegatedFrameHost::DelegatedFrameHost(const viz::FrameSinkId& frame_sink_id,
DelegatedFrameHostClient* client,
- bool enable_surface_synchronization)
+ bool enable_surface_synchronization,
+ bool enable_viz)
: frame_sink_id_(frame_sink_id),
client_(client),
enable_surface_synchronization_(enable_surface_synchronization),
- compositor_(nullptr),
- tick_clock_(new base::DefaultTickClock()),
- skipped_frames_(false),
+ enable_viz_(enable_viz),
+ tick_clock_(base::DefaultTickClock::GetInstance()),
background_color_(SK_ColorRED),
- frame_evictor_(new viz::FrameEvictor(this)),
+ frame_evictor_(std::make_unique<viz::FrameEvictor>(this)),
weak_ptr_factory_(this) {
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
factory->GetContextFactory()->AddObserver(this);
@@ -67,6 +69,20 @@ DelegatedFrameHost::DelegatedFrameHost(const viz::FrameSinkId& frame_sink_id,
CreateCompositorFrameSinkSupport();
}
+DelegatedFrameHost::~DelegatedFrameHost() {
+ DCHECK(!compositor_);
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+ factory->GetContextFactory()->RemoveObserver(this);
+
+ ResetCompositorFrameSinkSupport();
+
+ viz::HostFrameSinkManager* host_frame_sink_manager =
+ factory->GetContextFactoryPrivate()->GetHostFrameSinkManager();
+ host_frame_sink_manager->InvalidateFrameSinkId(frame_sink_id_);
+
+ DCHECK(!vsync_manager_.get());
+}
+
void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) {
frame_evictor_->SetVisible(true);
@@ -86,7 +102,7 @@ bool DelegatedFrameHost::HasSavedFrame() {
void DelegatedFrameHost::WasHidden() {
frame_evictor_->SetVisible(false);
- released_front_lock_ = NULL;
+ released_front_lock_ = nullptr;
}
void DelegatedFrameHost::MaybeCreateResizeLock() {
@@ -183,28 +199,28 @@ viz::FrameSinkId DelegatedFrameHost::GetFrameSinkId() {
viz::SurfaceId DelegatedFrameHost::SurfaceIdAtPoint(
viz::SurfaceHittestDelegate* delegate,
- const gfx::Point& point,
- gfx::Point* transformed_point) {
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point) {
*transformed_point = point;
viz::SurfaceId surface_id(frame_sink_id_, local_surface_id_);
- if (!surface_id.is_valid())
+ if (!surface_id.is_valid() || enable_viz_)
return surface_id;
viz::SurfaceHittest hittest(delegate,
GetFrameSinkManager()->surface_manager());
gfx::Transform target_transform;
- viz::SurfaceId target_local_surface_id =
- hittest.GetTargetSurfaceAtPoint(surface_id, point, &target_transform);
+ viz::SurfaceId target_local_surface_id = hittest.GetTargetSurfaceAtPoint(
+ surface_id, gfx::ToFlooredPoint(point), &target_transform);
if (target_local_surface_id.is_valid())
target_transform.TransformPoint(transformed_point);
return target_local_surface_id;
}
bool DelegatedFrameHost::TransformPointToLocalCoordSpace(
- const gfx::Point& point,
+ const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
viz::SurfaceId surface_id(frame_sink_id_, local_surface_id_);
- if (!surface_id.is_valid())
+ if (!surface_id.is_valid() || enable_viz_)
return false;
*transformed_point = point;
if (original_surface == surface_id)
@@ -217,9 +233,9 @@ bool DelegatedFrameHost::TransformPointToLocalCoordSpace(
}
bool DelegatedFrameHost::TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
if (!has_primary_surface_)
return false;
@@ -229,11 +245,21 @@ bool DelegatedFrameHost::TransformPointToCoordSpaceForView(
}
void DelegatedFrameHost::SetNeedsBeginFrames(bool needs_begin_frames) {
+ if (enable_viz_) {
+ NOTIMPLEMENTED();
+ return;
+ }
+
needs_begin_frame_ = needs_begin_frames;
support_->SetNeedsBeginFrame(needs_begin_frames);
}
void DelegatedFrameHost::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
+ if (enable_viz_) {
+ NOTIMPLEMENTED();
+ return;
+ }
+
DCHECK(!ack.has_damage);
support_->DidNotProduceFrame(ack);
}
@@ -250,8 +276,9 @@ bool DelegatedFrameHost::ShouldSkipFrame(const gfx::Size& size_in_dip) {
return size_in_dip != resize_lock_->expected_size();
}
-void DelegatedFrameHost::WillDrawSurface(const viz::LocalSurfaceId& id,
- const gfx::Rect& damage_rect) {
+void DelegatedFrameHost::OnAggregatedSurfaceDamage(
+ const viz::LocalSurfaceId& id,
+ const gfx::Rect& damage_rect) {
if (id != local_surface_id_)
return;
AttemptFrameSubscriberCapture(damage_rect);
@@ -265,21 +292,18 @@ void DelegatedFrameHost::WasResized() {
}
if (enable_surface_synchronization_) {
- ui::Layer* layer = client_->DelegatedFrameHostGetLayer();
- gfx::Size desired_size_in_pixels =
- gfx::ConvertSizeToPixel(layer->device_scale_factor(),
- client_->DelegatedFrameHostDesiredSizeInDIP());
+ current_frame_size_in_dip_ = client_->DelegatedFrameHostDesiredSizeInDIP();
viz::SurfaceId surface_id(frame_sink_id_, client_->GetLocalSurfaceId());
- viz::SurfaceInfo surface_info(surface_id, layer->device_scale_factor(),
- desired_size_in_pixels);
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
- viz::FrameSinkManagerImpl* manager =
- factory->GetContextFactoryPrivate()->GetFrameSinkManager();
client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface(
- surface_info, manager->surface_manager()->reference_factory());
+ surface_id, current_frame_size_in_dip_, GetSurfaceReferenceFactory());
has_primary_surface_ = true;
frame_evictor_->SwappedFrame(client_->DelegatedFrameHostIsVisible());
+ if (compositor_)
+ compositor_->OnChildResizing();
+ // Input throttling and guttering are handled differently when surface
+ // synchronization is enabled so exit early here.
+ return;
}
// If |create_resize_lock_after_commit_| is true, we're waiting to recreate
@@ -397,10 +421,9 @@ void DelegatedFrameHost::AttemptFrameSubscriberCapture(
// screenshots) since those copy requests do not specify |frame_subscriber()|
// as a source.
request->set_source(frame_subscriber()->GetSourceIdForCopyRequest());
- if (subscriber_texture.get()) {
- request->SetTextureMailbox(viz::TextureMailbox(
- subscriber_texture->mailbox(), subscriber_texture->sync_token(),
- subscriber_texture->target()));
+ if (subscriber_texture) {
+ request->SetMailbox(subscriber_texture->mailbox(),
+ subscriber_texture->sync_token());
}
// To avoid unnecessary browser composites, try to go directly to the Surface
@@ -422,7 +445,8 @@ void DelegatedFrameHost::DidCreateNewRendererCompositorFrameSink(
void DelegatedFrameHost::SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) {
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) {
#if defined(OS_CHROMEOS)
DCHECK(!resize_lock_ || !client_->IsAutoResizeEnabled());
#endif
@@ -437,11 +461,6 @@ void DelegatedFrameHost::SubmitCompositorFrame(
gfx::Size frame_size_in_dip =
gfx::ConvertSizeToDIP(frame_device_scale_factor, frame_size);
- gfx::Rect damage_rect = root_pass->damage_rect;
- damage_rect.Intersect(gfx::Rect(frame_size));
- gfx::Rect damage_rect_in_dip =
- gfx::ConvertRectToDIP(frame_device_scale_factor, damage_rect);
-
if (ShouldSkipFrame(frame_size_in_dip)) {
std::vector<viz::ReturnedResource> resources =
viz::TransferableResource::ReturnResources(frame.resource_list);
@@ -466,12 +485,10 @@ void DelegatedFrameHost::SubmitCompositorFrame(
if (skipped_frames_) {
skipped_frames_ = false;
- damage_rect = gfx::Rect(frame_size);
- damage_rect_in_dip = gfx::Rect(frame_size_in_dip);
// Give the same damage rect to the compositor.
viz::RenderPass* root_pass = frame.render_pass_list.back().get();
- root_pass->damage_rect = damage_rect;
+ root_pass->damage_rect = gfx::Rect(frame_size);
}
background_color_ = frame.metadata.root_background_color;
@@ -487,22 +504,14 @@ void DelegatedFrameHost::SubmitCompositorFrame(
// If surface synchronization is off, then OnFirstSurfaceActivation will be
// called in the same call stack.
- // TODO(kenrb): Supply HitTestRegionList data here as described in
- // crbug.com/750755.
- bool result = support_->SubmitCompositorFrame(local_surface_id,
- std::move(frame), nullptr);
+ bool result = support_->SubmitCompositorFrame(
+ local_surface_id, std::move(frame), std::move(hit_test_region_list));
DCHECK(result);
DCHECK(enable_surface_synchronization_ || has_primary_surface_);
}
- // TODO(fsamuel): This is used to detect video. We need to develop an
- // alternative mechanism to detect video in a frame for Viz.
if (!enable_surface_synchronization_) {
- if (!damage_rect_in_dip.IsEmpty()) {
- client_->DelegatedFrameHostGetLayer()->OnDelegatedFrameDamage(
- damage_rect_in_dip);
- }
if (has_primary_surface_)
frame_evictor_->SwappedFrame(client_->DelegatedFrameHostIsVisible());
// Note: the frame may have been evicted immediately.
@@ -523,6 +532,20 @@ void DelegatedFrameHost::DidReceiveCompositorFrameAck(
renderer_compositor_frame_sink_->DidReceiveCompositorFrameAck(resources);
}
+void DelegatedFrameHost::DidPresentCompositorFrame(uint32_t presentation_token,
+ base::TimeTicks time,
+ base::TimeDelta refresh,
+ uint32_t flags) {
+ renderer_compositor_frame_sink_->DidPresentCompositorFrame(
+ presentation_token, time, refresh, flags);
+}
+
+void DelegatedFrameHost::DidDiscardCompositorFrame(
+ uint32_t presentation_token) {
+ renderer_compositor_frame_sink_->DidDiscardCompositorFrame(
+ presentation_token);
+}
+
void DelegatedFrameHost::ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) {
renderer_compositor_frame_sink_->ReclaimResources(resources);
@@ -535,12 +558,12 @@ void DelegatedFrameHost::OnBeginFramePausedChanged(bool paused) {
void DelegatedFrameHost::OnFirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
+ gfx::Size frame_size_in_dip = gfx::ConvertSizeToDIP(
+ surface_info.device_scale_factor(), surface_info.size_in_pixels());
+
if (!enable_surface_synchronization_) {
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
- viz::FrameSinkManagerImpl* manager =
- factory->GetContextFactoryPrivate()->GetFrameSinkManager();
client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface(
- surface_info, manager->surface_manager()->reference_factory());
+ surface_info.id(), frame_size_in_dip, GetSurfaceReferenceFactory());
has_primary_surface_ = true;
}
@@ -549,18 +572,25 @@ void DelegatedFrameHost::OnFirstSurfaceActivation(
if (!has_primary_surface_)
return;
- client_->DelegatedFrameHostGetLayer()->SetFallbackSurface(surface_info);
+ client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
+ surface_info.id());
local_surface_id_ = surface_info.id().local_surface_id();
- released_front_lock_ = NULL;
- gfx::Size frame_size_in_dip = gfx::ConvertSizeToDIP(
- surface_info.device_scale_factor(), surface_info.size_in_pixels());
+ // Surface synchronization deals with resizes in WasResized().
+ if (enable_surface_synchronization_)
+ return;
+
+ released_front_lock_ = nullptr;
current_frame_size_in_dip_ = frame_size_in_dip;
CheckResizeLock();
UpdateGutters();
}
+void DelegatedFrameHost::OnFrameTokenChanged(uint32_t frame_token) {
+ client_->OnFrameTokenChanged(frame_token);
+}
+
void DelegatedFrameHost::OnBeginFrame(const viz::BeginFrameArgs& args) {
if (renderer_compositor_frame_sink_)
renderer_compositor_frame_sink_->OnBeginFrame(args);
@@ -568,6 +598,11 @@ void DelegatedFrameHost::OnBeginFrame(const viz::BeginFrameArgs& args) {
}
void DelegatedFrameHost::EvictDelegatedFrame() {
+ if (enable_viz_) {
+ NOTIMPLEMENTED();
+ return;
+ }
+
if (!has_primary_surface_)
return;
client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent();
@@ -670,6 +705,8 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo(
return;
}
+ DCHECK_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE);
+
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
viz::GLHelper* gl_helper = factory->GetGLHelper();
if (!gl_helper)
@@ -677,14 +714,10 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo(
if (subscriber_texture.get() && !subscriber_texture->texture_id())
return;
- viz::TextureMailbox texture_mailbox;
- std::unique_ptr<viz::SingleReleaseCallback> release_callback;
- if (auto* mailbox = result->GetTextureMailbox()) {
- texture_mailbox = *mailbox;
- release_callback = result->TakeTextureOwnership();
- }
- if (!texture_mailbox.IsTexture())
- return;
+ gpu::Mailbox mailbox = result->GetTextureResult()->mailbox;
+ gpu::SyncToken sync_token = result->GetTextureResult()->sync_token;
+ std::unique_ptr<viz::SingleReleaseCallback> release_callback =
+ result->TakeTextureOwnership();
if (!dfh->yuv_readback_pipeline_) {
dfh->yuv_readback_pipeline_ =
@@ -721,7 +754,8 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo(
<< region_in_frame.size().ToString();
std::unique_ptr<viz::GLHelper::ScalerInterface> scaler =
- gl_helper->CreateScaler(quality, scale_from, scale_to, false, false);
+ gl_helper->CreateScaler(quality, scale_from, scale_to, false, false,
+ false);
DCHECK(scaler); // Arguments to CreateScaler() should never be invalid.
yuv_readback_pipeline->SetScaler(std::move(scaler));
}
@@ -734,8 +768,7 @@ void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo(
video_frame, dfh->AsWeakPtr(), base::Bind(callback, region_in_frame),
subscriber_texture, base::Passed(&release_callback));
yuv_readback_pipeline->ReadbackYUV(
- texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(),
- gfx::Rect(region_in_frame.size()),
+ mailbox, sync_token, result->size(), gfx::Rect(region_in_frame.size()),
video_frame->stride(media::VideoFrame::kYPlane),
video_frame->data(media::VideoFrame::kYPlane),
video_frame->stride(media::VideoFrame::kUPlane),
@@ -794,6 +827,9 @@ void DelegatedFrameHost::OnCompositingLockStateChanged(
}
}
+void DelegatedFrameHost::OnCompositingChildResizing(
+ ui::Compositor* compositor) {}
+
void DelegatedFrameHost::OnCompositingShuttingDown(ui::Compositor* compositor) {
DCHECK_EQ(compositor, compositor_);
ResetCompositor();
@@ -818,20 +854,6 @@ void DelegatedFrameHost::OnLostResources() {
////////////////////////////////////////////////////////////////////////////////
// DelegatedFrameHost, private:
-DelegatedFrameHost::~DelegatedFrameHost() {
- DCHECK(!compositor_);
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
- factory->GetContextFactory()->RemoveObserver(this);
-
- ResetCompositorFrameSinkSupport();
-
- viz::HostFrameSinkManager* host_frame_sink_manager =
- factory->GetContextFactoryPrivate()->GetHostFrameSinkManager();
- host_frame_sink_manager->InvalidateFrameSinkId(frame_sink_id_);
-
- DCHECK(!vsync_manager_.get());
-}
-
void DelegatedFrameHost::SetCompositor(ui::Compositor* compositor) {
DCHECK(!compositor_);
if (!compositor)
@@ -886,6 +908,9 @@ void DelegatedFrameHost::UnlockResources() {
}
void DelegatedFrameHost::CreateCompositorFrameSinkSupport() {
+ if (enable_viz_)
+ return;
+
DCHECK(!support_);
constexpr bool is_root = false;
constexpr bool needs_sync_points = true;
@@ -894,8 +919,9 @@ void DelegatedFrameHost::CreateCompositorFrameSinkSupport() {
->GetHostFrameSinkManager()
->CreateCompositorFrameSinkSupport(this, frame_sink_id_,
is_root, needs_sync_points);
- support_->SetWillDrawSurfaceCallback(base::BindRepeating(
- &DelegatedFrameHost::WillDrawSurface, weak_ptr_factory_.GetWeakPtr()));
+ support_->SetAggregatedDamageCallback(
+ base::BindRepeating(&DelegatedFrameHost::OnAggregatedSurfaceDamage,
+ weak_ptr_factory_.GetWeakPtr()));
if (compositor_)
compositor_->AddFrameSink(frame_sink_id_);
if (needs_begin_frame_)
@@ -910,4 +936,12 @@ void DelegatedFrameHost::ResetCompositorFrameSinkSupport() {
support_.reset();
}
+scoped_refptr<viz::SurfaceReferenceFactory>
+DelegatedFrameHost::GetSurfaceReferenceFactory() {
+ if (enable_viz_)
+ return base::MakeRefCounted<viz::StubSurfaceReferenceFactory>();
+
+ return GetFrameSinkManager()->surface_manager()->reference_factory();
+}
+
} // 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 5231b3e7aee..6766d00cecc 100644
--- a/chromium/content/browser/renderer_host/delegated_frame_host.h
+++ b/chromium/content/browser/renderer_host/delegated_frame_host.h
@@ -24,6 +24,7 @@
#include "content/common/content_export.h"
#include "content/public/browser/render_process_host.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 "ui/compositor/compositor.h"
#include "ui/compositor/compositor_observer.h"
#include "ui/compositor/compositor_vsync_manager.h"
@@ -72,6 +73,7 @@ class CONTENT_EXPORT DelegatedFrameHostClient {
virtual void OnBeginFrame() = 0;
virtual bool IsAutoResizeEnabled() const = 0;
+ virtual void OnFrameTokenChanged(uint32_t frame_token) = 0;
};
// The DelegatedFrameHost is used to host all of the RenderWidgetHostView state
@@ -89,7 +91,8 @@ class CONTENT_EXPORT DelegatedFrameHost
public:
DelegatedFrameHost(const viz::FrameSinkId& frame_sink_id,
DelegatedFrameHostClient* client,
- bool enable_surface_synchronization);
+ bool enable_surface_synchronization,
+ bool enable_viz);
~DelegatedFrameHost() override;
// ui::CompositorObserver implementation.
@@ -98,6 +101,7 @@ class CONTENT_EXPORT DelegatedFrameHost
base::TimeTicks start_time) override;
void OnCompositingEnded(ui::Compositor* compositor) override;
void OnCompositingLockStateChanged(ui::Compositor* compositor) override;
+ void OnCompositingChildResizing(ui::Compositor* compositor) override;
void OnCompositingShuttingDown(ui::Compositor* compositor) override;
// ui::CompositorVSyncManager::Observer implementation.
@@ -113,6 +117,11 @@ class CONTENT_EXPORT DelegatedFrameHost
// viz::mojom::CompositorFrameSinkClient implementation.
void DidReceiveCompositorFrameAck(
const std::vector<viz::ReturnedResource>& resources) override;
+ void DidPresentCompositorFrame(uint32_t presentation_token,
+ base::TimeTicks time,
+ base::TimeDelta refresh,
+ uint32_t flags) override;
+ void DidDiscardCompositorFrame(uint32_t presentation_token) override;
void OnBeginFrame(const viz::BeginFrameArgs& args) override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
@@ -120,13 +129,16 @@ class CONTENT_EXPORT DelegatedFrameHost
// viz::HostFrameSinkClient implementation.
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
+ void OnFrameTokenChanged(uint32_t frame_token) override;
// Public interface exposed to RenderWidgetHostView.
void DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink);
- void SubmitCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame);
+ void SubmitCompositorFrame(
+ const viz::LocalSurfaceId& local_surface_id,
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list);
void ClearDelegatedFrame();
void WasHidden();
void WasShown(const ui::LatencyInfo& latency_info);
@@ -155,25 +167,25 @@ class CONTENT_EXPORT DelegatedFrameHost
// Returns a null SurfaceId if this DelegatedFrameHost has not yet created
// a compositor Surface.
viz::SurfaceId SurfaceIdAtPoint(viz::SurfaceHittestDelegate* delegate,
- const gfx::Point& point,
- gfx::Point* transformed_point);
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point);
// Given the SurfaceID of a Surface that is contained within this class'
// Surface, find the relative transform between the Surfaces and apply it
// to a point. Returns false if a Surface has not yet been created or if
// |original_surface| is not embedded within our current Surface.
- bool TransformPointToLocalCoordSpace(const gfx::Point& point,
+ bool TransformPointToLocalCoordSpace(const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point);
+ gfx::PointF* transformed_point);
// Given a RenderWidgetHostViewBase that renders to a Surface that is
// contained within this class' Surface, find the relative transform between
// the Surfaces and apply it to a point. Returns false if a Surface has not
// yet been created or if |target_view| is not a descendant RWHV from our
// client.
- bool TransformPointToCoordSpaceForView(const gfx::Point& point,
+ bool TransformPointToCoordSpaceForView(const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point);
+ gfx::PointF* transformed_point);
void SetNeedsBeginFrames(bool needs_begin_frames);
void DidNotProduceFrame(const viz::BeginFrameAck& ack);
@@ -182,6 +194,9 @@ class CONTENT_EXPORT DelegatedFrameHost
viz::SurfaceId SurfaceIdForTesting() const {
return viz::SurfaceId(frame_sink_id_, local_surface_id_);
}
+ viz::CompositorFrameSinkSupport* GetCompositorFrameSinkSupportForTesting() {
+ return support_.get();
+ }
bool HasPrimarySurfaceForTesting() const { return has_primary_surface_; }
@@ -197,6 +212,10 @@ class CONTENT_EXPORT DelegatedFrameHost
request_copy_of_output_callback_for_testing_ = callback;
}
+ gfx::Size CurrentFrameSizeInDipForTesting() const {
+ return current_frame_size_in_dip_;
+ }
+
private:
friend class DelegatedFrameHostClient;
friend class RenderWidgetHostViewAuraCopyRequestTest;
@@ -214,10 +233,10 @@ class CONTENT_EXPORT DelegatedFrameHost
bool ShouldSkipFrame(const gfx::Size& size_in_dip);
- // Called when surface is being scheduled for a draw. This is provided as a
- // callback to |support_|.
- void WillDrawSurface(const viz::LocalSurfaceId& id,
- const gfx::Rect& damage_rect);
+ // Called when the renderer's surface or something that it embeds has damage.
+ // Usually when there is damage we should give a copy to |frame_subscriber_|.
+ void OnAggregatedSurfaceDamage(const viz::LocalSurfaceId& id,
+ const gfx::Rect& aggregated_damage_rect);
// Lazily grab a resize lock if the aura window size doesn't match the current
// frame size, to give time to the renderer.
@@ -259,11 +278,16 @@ class CONTENT_EXPORT DelegatedFrameHost
void CreateCompositorFrameSinkSupport();
void ResetCompositorFrameSinkSupport();
+ // Returns SurfaceReferenceFactory instance. If |enable_viz| is true then it
+ // will be a stub factory, otherwise it will be the real factory.
+ scoped_refptr<viz::SurfaceReferenceFactory> GetSurfaceReferenceFactory();
+
const viz::FrameSinkId frame_sink_id_;
viz::LocalSurfaceId local_surface_id_;
DelegatedFrameHostClient* const client_;
const bool enable_surface_synchronization_;
- ui::Compositor* compositor_;
+ const bool enable_viz_;
+ ui::Compositor* compositor_ = nullptr;
// The vsync manager we are observing for changes, if any.
scoped_refptr<ui::CompositorVSyncManager> vsync_manager_;
@@ -274,11 +298,11 @@ class CONTENT_EXPORT DelegatedFrameHost
base::TimeDelta vsync_interval_;
// Overridable tick clock used for testing functions using current time.
- std::unique_ptr<base::TickClock> tick_clock_;
+ base::TickClock* tick_clock_;
// True after a delegated frame has been skipped, until a frame is not
// skipped.
- bool skipped_frames_;
+ bool skipped_frames_ = false;
std::vector<ui::LatencyInfo> skipped_latency_info_list_;
std::unique_ptr<ui::Layer> right_gutter_;
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 e68b18a083c..61cd6f86f2f 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
@@ -70,7 +70,7 @@ DelegatedFrameHostClientAura::DelegatedFrameHostCreateResizeLock() {
host->dispatcher()->HoldPointerMoves();
gfx::Size desired_size = render_widget_host_view_->window_->bounds().size();
- return base::MakeUnique<CompositorResizeLock>(this, desired_size);
+ return std::make_unique<CompositorResizeLock>(this, desired_size);
}
viz::LocalSurfaceId DelegatedFrameHostClientAura::GetLocalSurfaceId() const {
@@ -85,6 +85,10 @@ bool DelegatedFrameHostClientAura::IsAutoResizeEnabled() const {
return render_widget_host_view_->host_->auto_resize_enabled();
}
+void DelegatedFrameHostClientAura::OnFrameTokenChanged(uint32_t frame_token) {
+ render_widget_host_view_->OnFrameTokenChangedForView(frame_token);
+}
+
std::unique_ptr<ui::CompositorLock>
DelegatedFrameHostClientAura::GetCompositorLock(
ui::CompositorLockClient* client) {
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 c4490452572..37a79d174d6 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
@@ -39,6 +39,7 @@ class CONTENT_EXPORT DelegatedFrameHostClientAura
viz::LocalSurfaceId GetLocalSurfaceId() const override;
void OnBeginFrame() override;
bool IsAutoResizeEnabled() const override;
+ void OnFrameTokenChanged(uint32_t frame_token) override;
// CompositorResizeLockClient implementation.
std::unique_ptr<ui::CompositorLock> GetCompositorLock(
diff --git a/chromium/content/browser/renderer_host/dip_util.cc b/chromium/content/browser/renderer_host/dip_util.cc
index 3d20622eaaa..465ffa888aa 100644
--- a/chromium/content/browser/renderer_host/dip_util.cc
+++ b/chromium/content/browser/renderer_host/dip_util.cc
@@ -17,7 +17,8 @@
namespace content {
float GetScaleFactorForView(const RenderWidgetHostView* view) {
- return ui::GetScaleFactorForNativeView(view ? view->GetNativeView() : NULL);
+ return ui::GetScaleFactorForNativeView(view ? view->GetNativeView()
+ : nullptr);
}
gfx::Point ConvertViewPointToDIP(const RenderWidgetHostView* view,
diff --git a/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc b/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
index ce525f84383..cbe75f9080f 100644
--- a/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
+++ b/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
@@ -395,7 +395,7 @@ void DWriteFontProxyMessageFilter::OnMapCharacters(
return;
}
mswr::ComPtr<IDWriteTextAnalysisSource> analysis_source;
- if (FAILED(mswr::MakeAndInitialize<gfx::win::TextAnalysisSource>(
+ if (FAILED(gfx::win::TextAnalysisSource::Create(
&analysis_source, text, locale_name, number_substitution.Get(),
static_cast<DWRITE_READING_DIRECTION>(reading_direction)))) {
DCHECK(false);
diff --git a/chromium/content/browser/renderer_host/file_utilities_host_impl.cc b/chromium/content/browser/renderer_host/file_utilities_host_impl.cc
index d9a01b1c208..e3b08f3083b 100644
--- a/chromium/content/browser/renderer_host/file_utilities_host_impl.cc
+++ b/chromium/content/browser/renderer_host/file_utilities_host_impl.cc
@@ -21,7 +21,7 @@ FileUtilitiesHostImpl::~FileUtilitiesHostImpl() = default;
void FileUtilitiesHostImpl::Create(
int process_id,
content::mojom::FileUtilitiesHostRequest request) {
- mojo::MakeStrongBinding(base::MakeUnique<FileUtilitiesHostImpl>(process_id),
+ mojo::MakeStrongBinding(std::make_unique<FileUtilitiesHostImpl>(process_id),
std::move(request));
}
diff --git a/chromium/content/browser/renderer_host/font_utils_linux.cc b/chromium/content/browser/renderer_host/font_utils_linux.cc
index f32f6a1b886..e5fd81a17d8 100644
--- a/chromium/content/browser/renderer_host/font_utils_linux.cc
+++ b/chromium/content/browser/renderer_host/font_utils_linux.cc
@@ -160,11 +160,11 @@ int MatchFontFaceWithFallback(const std::string& face,
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
FcPatternAddLangSet(pattern, FC_LANG, langset);
FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
- FcConfigSubstitute(NULL, pattern, FcMatchPattern);
+ FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
FcResult result;
- FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result);
+ FcFontSet* font_set = FcFontSort(nullptr, pattern, 0, nullptr, &result);
int font_fd = -1;
int good_enough_index = -1;
bool good_enough_index_set = false;
diff --git a/chromium/content/browser/renderer_host/frame_connector_delegate.cc b/chromium/content/browser/renderer_host/frame_connector_delegate.cc
index bc3509406c9..1db1b20c2a3 100644
--- a/chromium/content/browser/renderer_host/frame_connector_delegate.cc
+++ b/chromium/content/browser/renderer_host/frame_connector_delegate.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/frame_connector_delegate.h"
+#include "content/common/content_switches_internal.h"
+
namespace content {
RenderWidgetHostViewBase*
@@ -16,29 +18,25 @@ FrameConnectorDelegate::GetRootRenderWidgetHostView() {
return nullptr;
}
-gfx::Rect FrameConnectorDelegate::ChildFrameRect() {
- return gfx::Rect();
-}
-
-gfx::Point FrameConnectorDelegate::TransformPointToRootCoordSpace(
- const gfx::Point& point,
+gfx::PointF FrameConnectorDelegate::TransformPointToRootCoordSpace(
+ const gfx::PointF& point,
const viz::SurfaceId& surface_id) {
- return gfx::Point();
+ return gfx::PointF();
}
bool FrameConnectorDelegate::TransformPointToLocalCoordSpace(
- const gfx::Point& point,
+ const gfx::PointF& point,
const viz::SurfaceId& original_surface,
const viz::SurfaceId& local_surface_id,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
return false;
}
bool FrameConnectorDelegate::TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
const viz::SurfaceId& local_surface_id,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
return false;
}
@@ -58,4 +56,28 @@ bool FrameConnectorDelegate::IsHidden() const {
return false;
}
+bool FrameConnectorDelegate::IsThrottled() const {
+ return false;
+}
+
+bool FrameConnectorDelegate::IsSubtreeThrottled() const {
+ return false;
+}
+
+void FrameConnectorDelegate::SetRect(const gfx::Rect& frame_rect) {
+ if (use_zoom_for_device_scale_factor_) {
+ frame_rect_in_pixels_ = frame_rect;
+ frame_rect_in_dip_ = gfx::ScaleToEnclosingRect(
+ frame_rect, 1.f / screen_info_.device_scale_factor);
+ } else {
+ frame_rect_in_dip_ = frame_rect;
+ frame_rect_in_pixels_ =
+ gfx::ScaleToEnclosingRect(frame_rect, screen_info_.device_scale_factor);
+ }
+}
+
+FrameConnectorDelegate::FrameConnectorDelegate(
+ bool use_zoom_for_device_scale_factor)
+ : use_zoom_for_device_scale_factor_(use_zoom_for_device_scale_factor) {}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/frame_connector_delegate.h b/chromium/content/browser/renderer_host/frame_connector_delegate.h
index 1bc46440140..03562e8f0d4 100644
--- a/chromium/content/browser/renderer_host/frame_connector_delegate.h
+++ b/chromium/content/browser/renderer_host/frame_connector_delegate.h
@@ -8,7 +8,8 @@
#include "components/viz/common/surfaces/local_surface_id.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
+#include "content/public/common/screen_info.h"
#include "ui/gfx/geometry/rect.h"
#if defined(USE_AURA)
@@ -66,9 +67,13 @@ class CONTENT_EXPORT FrameConnectorDelegate {
virtual void SetChildFrameSurface(const viz::SurfaceInfo& surface_info,
const viz::SurfaceSequence& sequence) {}
- // Return the rect that the RenderWidgetHostViewChildFrame's content will
- // render into.
- virtual gfx::Rect ChildFrameRect();
+ // Return the rect in DIP that the RenderWidgetHostViewChildFrame's content
+ // will render into.
+ const gfx::Rect& frame_rect_in_dip() { return frame_rect_in_dip_; }
+
+ // Return the rect in pixels that the RenderWidgetHostViewChildFrame's content
+ // will render into.
+ const gfx::Rect& frame_rect_in_pixels() { return frame_rect_in_pixels_; }
// Request that the platform change the mouse cursor when the mouse is
// positioned over this view's content.
@@ -77,8 +82,8 @@ class CONTENT_EXPORT FrameConnectorDelegate {
// Given a point in the current view's coordinate space, return the same
// point transformed into the coordinate space of the top-level view's
// coordinate space.
- virtual gfx::Point TransformPointToRootCoordSpace(
- const gfx::Point& point,
+ virtual gfx::PointF TransformPointToRootCoordSpace(
+ const gfx::PointF& point,
const viz::SurfaceId& surface_id);
// Given a point in the coordinate space of a different Surface, transform
@@ -90,20 +95,20 @@ class CONTENT_EXPORT FrameConnectorDelegate {
// be in sibling surfaces, they must first be converted to the root
// surface's coordinate space.
virtual bool TransformPointToLocalCoordSpace(
- const gfx::Point& point,
+ const gfx::PointF& point,
const viz::SurfaceId& original_surface,
const viz::SurfaceId& local_surface_id,
- gfx::Point* transformed_point);
+ gfx::PointF* transformed_point);
// Transform a point into the coordinate space of the root
// RenderWidgetHostView, for the current view's coordinate space.
// Returns false if |target_view| and |view_| do not have the same root
// RenderWidgetHostView.
virtual bool TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
const viz::SurfaceId& local_surface_id,
- gfx::Point* transformed_point);
+ gfx::PointF* transformed_point);
// Pass acked touch events to the root view for gesture processing.
virtual void ForwardProcessAckedTouchEvent(
@@ -139,6 +144,14 @@ class CONTENT_EXPORT FrameConnectorDelegate {
return local_surface_id_;
}
+ // Returns the ScreenInfo propagated from the parent to be used by this
+ // child frame.
+ const ScreenInfo& screen_info() const { return screen_info_; }
+
+ void SetScreenInfoForTesting(const ScreenInfo& screen_info) {
+ screen_info_ = screen_info;
+ }
+
// Determines whether the current view's content is inert, either because
// an HTMLDialogElement is being modally displayed in a higher-level frame,
// or because the inert attribute has been specified.
@@ -150,10 +163,19 @@ class CONTENT_EXPORT FrameConnectorDelegate {
// RenderWidgetHostView::Hide() is called on the current view.
virtual bool IsHidden() const;
+ // Determines whether the child frame should be render throttled, which
+ // happens when the entire rect is offscreen.
+ virtual bool IsThrottled() const;
+ virtual bool IsSubtreeThrottled() const;
+
// Called by RenderWidgetHostViewChildFrame to update the visibility of any
// nested child RWHVCFs inside it.
virtual void SetVisibilityForChildViews(bool visible) const {}
+ // Called to resize the child renderer. |frame_rect| is in pixels if
+ // zoom-for-dsf is enabled, and in DIP if not.
+ virtual void SetRect(const gfx::Rect& frame_rect);
+
#if defined(USE_AURA)
// Embeds a WindowTreeClient in the parent. This results in the parent
// creating a window in the ui server so that this can render to the screen.
@@ -161,14 +183,26 @@ class CONTENT_EXPORT FrameConnectorDelegate {
ui::mojom::WindowTreeClientPtr window_tree_client) {}
#endif
+ // Called by RenderWidgetHostViewChildFrame when the child frame has resized
+ // to |new_size| because auto-resize is enabled.
+ virtual void ResizeDueToAutoResize(const gfx::Size& new_size,
+ uint64_t sequence_number) {}
+
protected:
+ explicit FrameConnectorDelegate(bool use_zoom_for_device_scale_factor);
+
virtual ~FrameConnectorDelegate() {}
// This is here rather than in the implementation class so that
// ViewportIntersection() can return a reference.
gfx::Rect viewport_intersection_rect_;
+ ScreenInfo screen_info_;
+ gfx::Rect frame_rect_in_dip_;
+ gfx::Rect frame_rect_in_pixels_;
viz::LocalSurfaceId local_surface_id_;
+
+ const bool use_zoom_for_device_scale_factor_;
};
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/OWNERS b/chromium/content/browser/renderer_host/input/OWNERS
index cf2b318416b..86bfa17ec3d 100644
--- a/chromium/content/browser/renderer_host/input/OWNERS
+++ b/chromium/content/browser/renderer_host/input/OWNERS
@@ -1,4 +1,3 @@
-aelias@chromium.org
dtapuska@chromium.org
tdresser@chromium.org
diff --git a/chromium/content/browser/renderer_host/input/composited_scrolling_browsertest.cc b/chromium/content/browser/renderer_host/input/composited_scrolling_browsertest.cc
index 0d433e46fa0..6df2743a2f8 100644
--- a/chromium/content/browser/renderer_host/input/composited_scrolling_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/composited_scrolling_browsertest.cc
@@ -83,7 +83,7 @@ class CompositedScrollingBrowserTest : public ContentBrowserTest {
NavigateToURL(shell(), data_url);
RenderWidgetHostImpl* host = GetWidgetHost();
- FrameWatcher frame_watcher(shell()->web_contents());
+ MainThreadFrameObserver observer(host);
host->GetView()->SetSize(gfx::Size(400, 400));
base::string16 ready_title(base::ASCIIToUTF16("ready"));
@@ -94,7 +94,7 @@ class CompositedScrollingBrowserTest : public ContentBrowserTest {
// otherwise the injection of the synthetic gestures may get
// dropped because of MainThread/Impl thread sync of touch event
// regions.
- frame_watcher.WaitFrames(1);
+ observer.Wait();
}
// ContentBrowserTest:
@@ -136,7 +136,7 @@ class CompositedScrollingBrowserTest : public ContentBrowserTest {
// Runs until we get the OnSyntheticGestureCompleted callback
runner_->Run();
- runner_ = NULL;
+ runner_ = nullptr;
return GetScrollTop();
}
diff --git a/chromium/content/browser/renderer_host/input/gesture_event_queue.cc b/chromium/content/browser/renderer_host/input/gesture_event_queue.cc
index 309e75c764d..20443213c44 100644
--- a/chromium/content/browser/renderer_host/input/gesture_event_queue.cc
+++ b/chromium/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -75,6 +75,8 @@ bool GestureEventQueue::ShouldForwardForBounceReduction(
return true;
switch (gesture_event.event.GetType()) {
case WebInputEvent::kGestureScrollUpdate:
+ if (fling_in_progress_)
+ return false;
if (!scrolling_in_progress_) {
debounce_deferring_timer_.Start(
FROM_HERE,
@@ -165,7 +167,8 @@ bool GestureEventQueue::OnScrollBegin(
return false;
}
-void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result,
+void GestureEventQueue::ProcessGestureAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result,
WebInputEvent::Type type,
const ui::LatencyInfo& latency) {
TRACE_EVENT0("input", "GestureEventQueue::ProcessGestureAck");
@@ -176,7 +179,7 @@ void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result,
}
if (!allow_multiple_inflight_events_) {
- LegacyProcessGestureAck(ack_result, type, latency);
+ LegacyProcessGestureAck(ack_source, ack_result, type, latency);
return;
}
@@ -187,7 +190,7 @@ void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result,
continue;
if (outstanding_event.event.GetType() == type) {
outstanding_event.latency.AddNewLatencyFrom(latency);
- outstanding_event.set_ack_state(ack_result);
+ outstanding_event.set_ack_info(ack_source, ack_result);
break;
}
}
@@ -207,19 +210,20 @@ void GestureEventQueue::AckCompletedEvents() {
break;
GestureEventWithLatencyInfoAndAckState event = *iter;
coalesced_gesture_events_.erase(iter);
- AckGestureEventToClient(event, event.ack_state());
+ AckGestureEventToClient(event, event.ack_source(), event.ack_state());
}
}
void GestureEventQueue::AckGestureEventToClient(
const GestureEventWithLatencyInfo& event_with_latency,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
DCHECK(allow_multiple_inflight_events_);
// Ack'ing an event may enqueue additional gesture events. By ack'ing the
// event before the forwarding of queued events below, such additional events
// can be coalesced with existing queued events prior to dispatch.
- client_->OnGestureEventAck(event_with_latency, ack_result);
+ client_->OnGestureEventAck(event_with_latency, ack_source, ack_result);
const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
if (event_with_latency.event.GetType() ==
@@ -230,6 +234,7 @@ void GestureEventQueue::AckGestureEventToClient(
}
void GestureEventQueue::LegacyProcessGestureAck(
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
WebInputEvent::Type type,
const ui::LatencyInfo& latency) {
@@ -254,7 +259,7 @@ void GestureEventQueue::LegacyProcessGestureAck(
// Ack'ing an event may enqueue additional gesture events. By ack'ing the
// event before the forwarding of queued events below, such additional events
// can be coalesced with existing queued events prior to dispatch.
- client_->OnGestureEventAck(event_with_latency, ack_result);
+ client_->OnGestureEventAck(event_with_latency, ack_source, ack_result);
const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
if (type == WebInputEvent::kGestureFlingCancel) {
diff --git a/chromium/content/browser/renderer_host/input/gesture_event_queue.h b/chromium/content/browser/renderer_host/input/gesture_event_queue.h
index 5ad67df9a0b..a6bf36a5094 100644
--- a/chromium/content/browser/renderer_host/input/gesture_event_queue.h
+++ b/chromium/content/browser/renderer_host/input/gesture_event_queue.h
@@ -15,7 +15,8 @@
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/browser/renderer_host/input/fling_controller.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
namespace content {
@@ -31,9 +32,9 @@ class CONTENT_EXPORT GestureEventQueueClient {
virtual void SendGestureEventImmediately(
const GestureEventWithLatencyInfo& event) = 0;
- virtual void OnGestureEventAck(
- const GestureEventWithLatencyInfo& event,
- InputEventAckState ack_result) = 0;
+ virtual void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
+ InputEventAckState ack_result) = 0;
};
// Maintains WebGestureEvents in a queue before forwarding them to the renderer
@@ -83,7 +84,8 @@ class CONTENT_EXPORT GestureEventQueue {
// Indicates that the caller has received an acknowledgement from the renderer
// with state |ack_result| and event |type|. May send events if the queue is
// not empty.
- void ProcessGestureAck(InputEventAckState ack_result,
+ void ProcessGestureAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result,
blink::WebInputEvent::Type type,
const ui::LatencyInfo& latency);
@@ -119,9 +121,14 @@ class CONTENT_EXPORT GestureEventQueue {
public:
GestureEventWithLatencyInfoAndAckState(const GestureEventWithLatencyInfo&);
InputEventAckState ack_state() const { return ack_state_; }
- void set_ack_state(InputEventAckState state) { ack_state_ = state; }
+ void set_ack_info(InputEventAckSource source, InputEventAckState state) {
+ ack_source_ = source;
+ ack_state_ = state;
+ }
+ InputEventAckSource ack_source() const { return ack_source_; }
private:
+ InputEventAckSource ack_source_ = InputEventAckSource::UNKNOWN;
InputEventAckState ack_state_ = INPUT_EVENT_ACK_STATE_UNKNOWN;
};
@@ -150,11 +157,13 @@ class CONTENT_EXPORT GestureEventQueue {
// Will preserve the FIFO order as events originally arrived.
void AckCompletedEvents();
void AckGestureEventToClient(const GestureEventWithLatencyInfo&,
+ InputEventAckSource,
InputEventAckState);
// Used when |allow_multiple_inflight_events_| is false. Will only send next
// event after receiving ACK for the previous one.
- void LegacyProcessGestureAck(InputEventAckState,
+ void LegacyProcessGestureAck(InputEventAckSource,
+ InputEventAckState,
blink::WebInputEvent::Type,
const ui::LatencyInfo&);
diff --git a/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc b/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
index 69d03e62ae7..78c5ba6fd44 100644
--- a/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
@@ -21,8 +21,8 @@
#include "base/time/time.h"
#include "content/browser/renderer_host/input/input_router_config_helper.h"
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
+#include "content/public/common/input_event_ack_state.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "ui/events/blink/blink_features.h"
@@ -90,6 +90,7 @@ class GestureEventQueueTest : public testing::Test,
}
void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override {
++acked_gesture_event_count_;
last_acked_event_ = event.event;
@@ -147,7 +148,8 @@ class GestureEventQueueTest : public testing::Test,
void SendInputEventACK(WebInputEvent::Type type,
InputEventAckState ack) {
- queue()->ProcessGestureAck(ack, type, ui::LatencyInfo());
+ queue()->ProcessGestureAck(InputEventAckSource::COMPOSITOR_THREAD, ack,
+ type, ui::LatencyInfo());
}
void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
@@ -1174,20 +1176,19 @@ TEST_F(GestureEventQueueTest, DebounceEndsWithFlingStartEvent) {
SimulateGestureEvent(WebInputEvent::kGestureScrollUpdate,
blink::kWebGestureDeviceTouchpad);
EXPECT_EQ(0U, GetAndResetSentGestureEventCount());
- EXPECT_EQ(5U, GestureEventQueueSize());
+ EXPECT_EQ(4U, GestureEventQueueSize());
EXPECT_EQ(0U, GestureEventDebouncingQueueSize());
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchpad);
EXPECT_EQ(0U, GetAndResetSentGestureEventCount());
EXPECT_EQ(5U, GestureEventQueueSize());
- EXPECT_EQ(1U, GestureEventDebouncingQueueSize());
+ EXPECT_EQ(0U, GestureEventDebouncingQueueSize());
// Verify that the coalescing queue contains the correct events.
WebInputEvent::Type expected[] = {
WebInputEvent::kGestureScrollUpdate, WebInputEvent::kGestureScrollEnd,
- WebInputEvent::kGestureFlingStart, WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kGestureScrollUpdate};
+ WebInputEvent::kGestureFlingStart, WebInputEvent::kGestureScrollBegin};
for (unsigned i = 0; i < sizeof(expected) / sizeof(WebInputEvent::Type);
i++) {
diff --git a/chromium/content/browser/renderer_host/input/input_disposition_handler.h b/chromium/content/browser/renderer_host/input/input_disposition_handler.h
index eb7d7e0c891..efc6d557f6e 100644
--- a/chromium/content/browser/renderer_host/input/input_disposition_handler.h
+++ b/chromium/content/browser/renderer_host/input/input_disposition_handler.h
@@ -6,8 +6,9 @@
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_DISPOSITION_HANDLER_H_
#include "content/browser/renderer_host/event_with_latency_info.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/public/browser/native_web_keyboard_event.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
namespace content {
@@ -20,14 +21,19 @@ class CONTENT_EXPORT InputDispositionHandler {
// Called upon event ack receipt from the renderer.
virtual void OnKeyboardEventAck(
const NativeWebKeyboardEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) = 0;
virtual void OnMouseEventAck(const MouseEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) = 0;
virtual void OnWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) = 0;
virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) = 0;
virtual void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) = 0;
enum UnexpectedEventAckType {
diff --git a/chromium/content/browser/renderer_host/input/input_router.h b/chromium/content/browser/renderer_host/input/input_router.h
index 07d8fe72c86..68a549339ac 100644
--- a/chromium/content/browser/renderer_host/input/input_router.h
+++ b/chromium/content/browser/renderer_host/input/input_router.h
@@ -9,9 +9,9 @@
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
#include "content/browser/renderer_host/input/touch_event_queue.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/common/widget.mojom.h"
#include "content/public/browser/native_web_keyboard_event.h"
+#include "content/public/common/input_event_ack_state.h"
#include "ipc/ipc_listener.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
@@ -64,7 +64,8 @@ class InputRouter : public IPC::Listener {
virtual void SetForceEnableZoom(bool enabled) = 0;
// Associate this InputRouter with a remote host channel.
- virtual void BindHost(mojom::WidgetInputHandlerHostRequest request) = 0;
+ virtual void BindHost(mojom::WidgetInputHandlerHostRequest request,
+ bool frame_handler) = 0;
};
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/input_router_client.h b/chromium/content/browser/renderer_host/input/input_router_client.h
index d7f018afbe6..41afa6e7db6 100644
--- a/chromium/content/browser/renderer_host/input/input_router_client.h
+++ b/chromium/content/browser/renderer_host/input/input_router_client.h
@@ -8,9 +8,9 @@
#include "cc/input/touch_action.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_source.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/public/browser/native_web_keyboard_event.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
namespace ui {
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 57653f071c9..2f3ded52b79 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl.cc
+++ b/chromium/content/browser/renderer_host/input/input_router_impl.cc
@@ -16,13 +16,11 @@
#include "content/browser/renderer_host/input/gesture_event_queue.h"
#include "content/browser/renderer_host/input/input_disposition_handler.h"
#include "content/browser/renderer_host/input/input_router_client.h"
-#include "content/browser/renderer_host/input/legacy_touch_event_queue.h"
#include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
#include "content/browser/renderer_host/input/touch_event_queue.h"
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
#include "content/common/content_constants_internal.h"
#include "content/common/edit_command.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/common/input/input_handler.mojom.h"
#include "content/common/input/web_touch_event_traits.h"
#include "content/common/input_messages.h"
@@ -31,6 +29,7 @@
#include "content/public/browser/notification_types.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/input_event_ack_state.h"
#include "ipc/ipc_sender.h"
#include "ui/events/blink/blink_event_util.h"
#include "ui/events/blink/web_input_event_traits.h"
@@ -51,29 +50,6 @@ using ui::WebInputEventTraits;
namespace content {
namespace {
-const char* GetEventAckName(InputEventAckState ack_result) {
- switch (ack_result) {
- case INPUT_EVENT_ACK_STATE_UNKNOWN:
- return "UNKNOWN";
- case INPUT_EVENT_ACK_STATE_CONSUMED:
- return "CONSUMED";
- case INPUT_EVENT_ACK_STATE_NOT_CONSUMED:
- return "NOT_CONSUMED";
- case INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE:
- return "CONSUMED_SHOULD_BUBBLE";
- case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS:
- return "NO_CONSUMER_EXISTS";
- case INPUT_EVENT_ACK_STATE_IGNORED:
- return "IGNORED";
- case INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING:
- return "SET_NON_BLOCKING";
- case INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING:
- return "SET_NON_BLOCKING_DUE_TO_FLING";
- }
- DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.";
- return "";
-}
-
bool WasHandled(InputEventAckState state) {
switch (state) {
case INPUT_EVENT_ACK_STATE_CONSUMED:
@@ -105,22 +81,16 @@ InputRouterImpl::InputRouterImpl(InputRouterImplClient* client,
touch_scroll_started_sent_(false),
wheel_scroll_latching_enabled_(base::FeatureList::IsEnabled(
features::kTouchpadAndWheelScrollLatching)),
- raf_aligned_touch_enabled_(
- base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents)),
wheel_event_queue_(this, wheel_scroll_latching_enabled_),
gesture_event_queue_(this, this, config.gesture_config),
device_scale_factor_(1.f),
host_binding_(this),
+ frame_host_binding_(this),
weak_ptr_factory_(this) {
weak_this_ = weak_ptr_factory_.GetWeakPtr();
- if (raf_aligned_touch_enabled_) {
- touch_event_queue_.reset(
- new PassthroughTouchEventQueue(this, config.touch_config));
- } else {
- touch_event_queue_.reset(
- new LegacyTouchEventQueue(this, config.touch_config));
- }
+ touch_event_queue_.reset(
+ new PassthroughTouchEventQueue(this, config.touch_config));
DCHECK(client);
DCHECK(disposition_handler);
@@ -222,9 +192,15 @@ cc::TouchAction InputRouterImpl::AllowedTouchAction() {
return touch_action_filter_.allowed_touch_action();
}
-void InputRouterImpl::BindHost(mojom::WidgetInputHandlerHostRequest request) {
- host_binding_.Close();
- host_binding_.Bind(std::move(request));
+void InputRouterImpl::BindHost(mojom::WidgetInputHandlerHostRequest request,
+ bool frame_handler) {
+ if (frame_handler) {
+ frame_host_binding_.Close();
+ frame_host_binding_.Bind(std::move(request));
+ } else {
+ host_binding_.Close();
+ host_binding_.Bind(std::move(request));
+ }
}
void InputRouterImpl::CancelTouchTimeout() {
@@ -323,6 +299,7 @@ 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.
@@ -331,7 +308,7 @@ void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event,
touch_action_filter_.ResetTouchAction();
UpdateTouchAckTimeoutEnabled();
}
- disposition_handler_->OnTouchEventAck(event, ack_result);
+ disposition_handler_->OnTouchEventAck(event, ack_source, ack_result);
// Reset the touch action at the end of a touch-action sequence.
if (WebTouchEventTraits::IsTouchSequenceEnd(event.event)) {
@@ -361,9 +338,10 @@ void InputRouterImpl::SendGestureEventImmediately(
void InputRouterImpl::OnGestureEventAck(
const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
touch_event_queue_->OnGestureEventAck(event, ack_result);
- disposition_handler_->OnGestureEventAck(event, ack_result);
+ disposition_handler_->OnGestureEventAck(event, ack_source, ack_result);
}
void InputRouterImpl::SendMouseWheelEventImmediately(
@@ -376,8 +354,10 @@ void InputRouterImpl::SendMouseWheelEventImmediately(
void InputRouterImpl::OnMouseWheelEventAck(
const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
+
InputEventAckState ack_result) {
- disposition_handler_->OnWheelEventAck(event, ack_result);
+ disposition_handler_->OnWheelEventAck(event, ack_source, ack_result);
}
void InputRouterImpl::ForwardGestureEventWithLatencyInfo(
@@ -409,11 +389,10 @@ void InputRouterImpl::FilterAndSendWebInputEvent(
return;
}
- std::unique_ptr<InputEvent> event = base::MakeUnique<InputEvent>(
+ std::unique_ptr<InputEvent> event = std::make_unique<InputEvent>(
ScaleEvent(input_event, device_scale_factor_), latency_info);
if (WebInputEventTraits::ShouldBlockEventStream(
- input_event, raf_aligned_touch_enabled_,
- wheel_scroll_latching_enabled_)) {
+ input_event, wheel_scroll_latching_enabled_)) {
client_->IncrementInFlightEventCount(input_event.GetType());
client_->GetWidgetInputHandler()->DispatchEvent(std::move(event),
std::move(callback));
@@ -435,12 +414,12 @@ void InputRouterImpl::KeyboardEventHandled(
const base::Optional<cc::TouchAction>& touch_action) {
TRACE_EVENT2("input", "InputRouterImpl::KeboardEventHandled", "type",
WebInputEvent::GetName(event.event.GetType()), "ack",
- GetEventAckName(state));
+ InputEventAckStateToString(state));
if (source != InputEventAckSource::BROWSER)
client_->DecrementInFlightEventCount(source);
event.latency.AddNewLatencyFrom(latency);
- disposition_handler_->OnKeyboardEventAck(event, state);
+ disposition_handler_->OnKeyboardEventAck(event, source, state);
// WARNING: This InputRouterImpl can be deallocated at this point
// (i.e. in the case of Ctrl+W, where the call to
@@ -457,12 +436,12 @@ void InputRouterImpl::MouseEventHandled(
const base::Optional<cc::TouchAction>& touch_action) {
TRACE_EVENT2("input", "InputRouterImpl::MouseEventHandled", "type",
WebInputEvent::GetName(event.event.GetType()), "ack",
- GetEventAckName(state));
+ InputEventAckStateToString(state));
if (source != InputEventAckSource::BROWSER)
client_->DecrementInFlightEventCount(source);
event.latency.AddNewLatencyFrom(latency);
- disposition_handler_->OnMouseEventAck(event, state);
+ disposition_handler_->OnMouseEventAck(event, source, state);
}
void InputRouterImpl::TouchEventHandled(
@@ -474,7 +453,7 @@ void InputRouterImpl::TouchEventHandled(
const base::Optional<cc::TouchAction>& touch_action) {
TRACE_EVENT2("input", "InputRouterImpl::TouchEventHandled", "type",
WebInputEvent::GetName(touch_event.event.GetType()), "ack",
- GetEventAckName(state));
+ InputEventAckStateToString(state));
if (source != InputEventAckSource::BROWSER)
client_->DecrementInFlightEventCount(source);
touch_event.latency.AddNewLatencyFrom(latency);
@@ -486,7 +465,7 @@ void InputRouterImpl::TouchEventHandled(
OnSetTouchAction(touch_action.value());
// |touch_event_queue_| will forward to OnTouchEventAck when appropriate.
- touch_event_queue_->ProcessTouchAck(state, latency,
+ touch_event_queue_->ProcessTouchAck(source, state, latency,
touch_event.event.unique_touch_event_id);
}
@@ -499,7 +478,7 @@ void InputRouterImpl::GestureEventHandled(
const base::Optional<cc::TouchAction>& touch_action) {
TRACE_EVENT2("input", "InputRouterImpl::GestureEventHandled", "type",
WebInputEvent::GetName(gesture_event.event.GetType()), "ack",
- GetEventAckName(state));
+ InputEventAckStateToString(state));
if (source != InputEventAckSource::BROWSER)
client_->DecrementInFlightEventCount(source);
if (gesture_event.event.GetType() ==
@@ -515,8 +494,8 @@ void InputRouterImpl::GestureEventHandled(
}
// |gesture_event_queue_| will forward to OnGestureEventAck when appropriate.
- gesture_event_queue_.ProcessGestureAck(state, gesture_event.event.GetType(),
- latency);
+ gesture_event_queue_.ProcessGestureAck(
+ source, state, gesture_event.event.GetType(), latency);
}
void InputRouterImpl::MouseWheelEventHandled(
@@ -528,7 +507,7 @@ void InputRouterImpl::MouseWheelEventHandled(
const base::Optional<cc::TouchAction>& touch_action) {
TRACE_EVENT2("input", "InputRouterImpl::MouseWheelEventHandled", "type",
WebInputEvent::GetName(event.event.GetType()), "ack",
- GetEventAckName(state));
+ InputEventAckStateToString(state));
if (source != InputEventAckSource::BROWSER)
client_->DecrementInFlightEventCount(source);
event.latency.AddNewLatencyFrom(latency);
@@ -536,7 +515,7 @@ void InputRouterImpl::MouseWheelEventHandled(
if (overscroll)
DidOverscroll(overscroll.value());
- wheel_event_queue_.ProcessMouseWheelAck(state, event.latency);
+ wheel_event_queue_.ProcessMouseWheelAck(source, state, event.latency);
}
void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) {
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 0cff7da7ec3..1b196976716 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl.h
+++ b/chromium/content/browser/renderer_host/input/input_router_impl.h
@@ -22,11 +22,11 @@
#include "content/browser/renderer_host/input/touch_action_filter.h"
#include "content/browser/renderer_host/input/touch_event_queue.h"
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
-#include "content/common/input/input_event_ack_source.h"
#include "content/common/input/input_event_stream_validator.h"
#include "content/common/input/input_handler.mojom.h"
#include "content/common/widget.mojom.h"
#include "content/public/browser/native_web_keyboard_event.h"
+#include "content/public/common/input_event_ack_source.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace ui {
@@ -76,7 +76,8 @@ class CONTENT_EXPORT InputRouterImpl
void SetFrameTreeNodeId(int frame_tree_node_id) override;
void SetForceEnableZoom(bool enabled) override;
cc::TouchAction AllowedTouchAction() override;
- void BindHost(mojom::WidgetInputHandlerHostRequest request) override;
+ void BindHost(mojom::WidgetInputHandlerHostRequest request,
+ bool frame_handler) override;
// InputHandlerHost impl
void CancelTouchTimeout() override;
@@ -107,6 +108,7 @@ class CONTENT_EXPORT InputRouterImpl
void SendTouchEventImmediately(
const TouchEventWithLatencyInfo& touch_event) override;
void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnFilteringTouchEvent(const blink::WebTouchEvent& touch_event) override;
@@ -114,12 +116,14 @@ class CONTENT_EXPORT InputRouterImpl
void SendGestureEventImmediately(
const GestureEventWithLatencyInfo& gesture_event) override;
void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
// MouseWheelEventQueueClient
void SendMouseWheelEventImmediately(
const MouseWheelEventWithLatencyInfo& touch_event) override;
void OnMouseWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void ForwardGestureEventWithLatencyInfo(
const blink::WebGestureEvent& gesture_event,
@@ -191,7 +195,6 @@ class CONTENT_EXPORT InputRouterImpl
bool touch_scroll_started_sent_;
bool wheel_scroll_latching_enabled_;
- bool raf_aligned_touch_enabled_;
MouseWheelEventQueue wheel_event_queue_;
std::unique_ptr<TouchEventQueue> touch_event_queue_;
GestureEventQueue gesture_event_queue_;
@@ -204,8 +207,14 @@ class CONTENT_EXPORT InputRouterImpl
// Last touch position relative to screen. Used to compute movementX/Y.
base::flat_map<int, gfx::Point> global_touch_position_;
+ // The host binding associated with the widget input handler from
+ // the widget.
mojo::Binding<mojom::WidgetInputHandlerHost> host_binding_;
+ // The host binding associated with the widget input handler from
+ // the frame.
+ mojo::Binding<mojom::WidgetInputHandlerHost> frame_host_binding_;
+
base::WeakPtr<InputRouterImpl> weak_this_;
base::WeakPtrFactory<InputRouterImpl> weak_ptr_factory_;
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 5bf522ac351..b56b681f501 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
@@ -29,7 +29,6 @@
#include "content/browser/renderer_host/input/input_router_client.h"
#include "content/browser/renderer_host/input/mock_input_disposition_handler.h"
#include "content/browser/renderer_host/input/mock_input_router_client.h"
-#include "content/browser/renderer_host/input/mock_widget_input_handler.h"
#include "content/common/content_constants_internal.h"
#include "content/common/edit_command.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
@@ -39,6 +38,7 @@
#include "content/public/common/content_switches.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
+#include "content/test/mock_widget_input_handler.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/blink_features.h"
@@ -68,12 +68,11 @@ namespace {
bool ShouldBlockEventStream(const blink::WebInputEvent& event) {
return ui::WebInputEventTraits::ShouldBlockEventStream(
event,
- base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents),
base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching));
}
WebInputEvent& GetEventWithType(WebInputEvent::Type type) {
- WebInputEvent* event = NULL;
+ WebInputEvent* event = nullptr;
if (WebInputEvent::IsMouseEventType(type)) {
static WebMouseEvent mouse;
event = &mouse;
@@ -95,22 +94,6 @@ WebInputEvent& GetEventWithType(WebInputEvent::Type type) {
return *event;
}
-void CallCallback(mojom::WidgetInputHandler::DispatchEventCallback callback,
- InputEventAckState state) {
- std::move(callback).Run(InputEventAckSource::COMPOSITOR_THREAD,
- ui::LatencyInfo(), state, base::nullopt,
- base::nullopt);
-}
-
-void CallCallbackWithTouchAction(
- mojom::WidgetInputHandler::DispatchEventCallback callback,
- InputEventAckState state,
- cc::TouchAction touch_action) {
- std::move(callback).Run(InputEventAckSource::COMPOSITOR_THREAD,
- ui::LatencyInfo(), state, base::nullopt,
- touch_action);
-}
-
enum WheelScrollingMode {
kWheelScrollingModeNone,
kWheelScrollLatching,
@@ -133,9 +116,8 @@ class MockInputRouterImplClient : public InputRouterImplClient {
void OnImeCancelComposition() override {}
- std::vector<MockWidgetInputHandler::DispatchedEvent>
- GetAndResetDispatchedEvents() {
- return widget_input_handler_.GetAndResetDispatchedEvents();
+ MockWidgetInputHandler::MessageVector GetAndResetDispatchedMessages() {
+ return widget_input_handler_.GetAndResetDispatchedMessages();
}
InputEventAckState FilterInputEvent(
@@ -217,43 +199,22 @@ class MockInputRouterImplClient : public InputRouterImplClient {
class InputRouterImplTest : public testing::Test {
public:
InputRouterImplTest(
- bool raf_aligned_touch = true,
WheelScrollingMode wheel_scrolling_mode = kWheelScrollLatching)
: wheel_scroll_latching_enabled_(wheel_scrolling_mode !=
kWheelScrollingModeNone),
scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::UI) {
- if (raf_aligned_touch && wheel_scrolling_mode == kAsyncWheelEvents) {
- feature_list_.InitWithFeatures({features::kRafAlignedTouchInputEvents,
- features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents},
- {});
- } else if (raf_aligned_touch &&
- wheel_scrolling_mode == kWheelScrollLatching) {
- feature_list_.InitWithFeatures(
- {features::kRafAlignedTouchInputEvents,
- features::kTouchpadAndWheelScrollLatching},
- {features::kAsyncWheelEvents});
- } else if (raf_aligned_touch &&
- wheel_scrolling_mode == kWheelScrollingModeNone) {
- feature_list_.InitWithFeatures({features::kRafAlignedTouchInputEvents},
- {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents});
- } else if (!raf_aligned_touch &&
- wheel_scrolling_mode == kAsyncWheelEvents) {
+ if (wheel_scrolling_mode == kAsyncWheelEvents) {
feature_list_.InitWithFeatures({features::kTouchpadAndWheelScrollLatching,
features::kAsyncWheelEvents},
- {features::kRafAlignedTouchInputEvents});
- } else if (!raf_aligned_touch &&
- wheel_scrolling_mode == kWheelScrollLatching) {
+ {});
+ } else if (wheel_scrolling_mode == kWheelScrollLatching) {
feature_list_.InitWithFeatures(
{features::kTouchpadAndWheelScrollLatching},
- {features::kRafAlignedTouchInputEvents, features::kAsyncWheelEvents});
- } else { // !raf_aligned_touch && wheel_scroll_latching ==
- // kWheelScrollingModeNone.
+ {features::kAsyncWheelEvents});
+ } else if (wheel_scrolling_mode == kWheelScrollingModeNone) {
feature_list_.InitWithFeatures({},
- {features::kRafAlignedTouchInputEvents,
- features::kTouchpadAndWheelScrollLatching,
+ {features::kTouchpadAndWheelScrollLatching,
features::kAsyncWheelEvents});
}
@@ -264,7 +225,7 @@ class InputRouterImplTest : public testing::Test {
~InputRouterImplTest() override {}
protected:
- using DispatchedEvents = std::vector<MockWidgetInputHandler::DispatchedEvent>;
+ using DispatchedMessages = MockWidgetInputHandler::MessageVector;
// testing::Test
void SetUp() override {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
@@ -451,8 +412,8 @@ class InputRouterImplTest : public testing::Test {
unique_touch_event_id, ack_result);
}
- DispatchedEvents GetAndResetDispatchedEvents() {
- return client_->GetAndResetDispatchedEvents();
+ DispatchedMessages GetAndResetDispatchedMessages() {
+ return client_->GetAndResetDispatchedMessages();
}
static void RunTasksAndWait(base::TimeDelta delay) {
@@ -477,23 +438,17 @@ class InputRouterImplTest : public testing::Test {
base::test::ScopedFeatureList feature_list_;
};
-class InputRouterImplRafAlignedTouchDisabledTest : public InputRouterImplTest {
- public:
- InputRouterImplRafAlignedTouchDisabledTest()
- : InputRouterImplTest(false, kWheelScrollingModeNone) {}
-};
-
class InputRouterImplWheelScrollLatchingDisabledTest
: public InputRouterImplTest {
public:
InputRouterImplWheelScrollLatchingDisabledTest()
- : InputRouterImplTest(true, kWheelScrollingModeNone) {}
+ : InputRouterImplTest(kWheelScrollingModeNone) {}
};
class InputRouterImplAsyncWheelEventEnabledTest : public InputRouterImplTest {
public:
InputRouterImplAsyncWheelEventEnabledTest()
- : InputRouterImplTest(true, kAsyncWheelEvents) {}
+ : InputRouterImplTest(kAsyncWheelEvents) {}
};
TEST_F(InputRouterImplTest, HandledInputEvent) {
@@ -503,8 +458,8 @@ TEST_F(InputRouterImplTest, HandledInputEvent) {
SimulateKeyboardEvent(WebInputEvent::kRawKeyDown);
// Make sure no input event is sent to the renderer.
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(0u, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0u, dispatched_messages.size());
// OnKeyboardEventAck should be triggered without actual ack.
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
@@ -517,8 +472,8 @@ TEST_F(InputRouterImplTest, ClientCanceledKeyboardEvent) {
SimulateKeyboardEvent(WebInputEvent::kRawKeyDown);
// Make sure no input event is sent to the renderer.
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(0u, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0u, dispatched_messages.size());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
// Simulate a keyboard event that should be dropped.
@@ -526,8 +481,8 @@ TEST_F(InputRouterImplTest, ClientCanceledKeyboardEvent) {
SimulateKeyboardEvent(WebInputEvent::kRawKeyDown);
// Make sure no input event is sent to the renderer, and no ack is sent.
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(0u, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0u, dispatched_messages.size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
}
@@ -538,10 +493,11 @@ TEST_F(InputRouterImplTest, HandleKeyEventsWeSent) {
SimulateKeyboardEvent(WebInputEvent::kRawKeyDown);
// Make sure we sent the input event to the renderer.
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(WebInputEvent::kRawKeyDown,
disposition_handler_->acked_keyboard_event().GetType());
@@ -569,120 +525,88 @@ TEST_F(InputRouterImplTest, CoalescesWheelEvents) {
SimulateWheelEventWithPhase(WebMouseWheelEvent::kPhaseEnded); // enqueued
// Check that only the first event was sent.
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
ASSERT_EQ(WebInputEvent::kMouseWheel,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->Event()->web_event->GetType());
const WebMouseWheelEvent* wheel_event =
static_cast<const WebMouseWheelEvent*>(
- dispatched_events.at(0).event_->web_event.get());
+ dispatched_messages[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(0, wheel_event->delta_x);
EXPECT_EQ(-5, wheel_event->delta_y);
// Check that the ACK sends the second message immediately.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// The coalesced events can queue up a delayed ack
// so that additional input events can be processed before
// we turn off coalescing.
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
ASSERT_EQ(WebInputEvent::kMouseWheel,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->Event()->web_event->GetType());
wheel_event = static_cast<const WebMouseWheelEvent*>(
- dispatched_events.at(0).event_->web_event.get());
+ dispatched_messages[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(8, wheel_event->delta_x);
EXPECT_EQ(-10 + -6, wheel_event->delta_y); // coalesced
// Ack the second event (which had the third coalesced into it).
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
ASSERT_EQ(WebInputEvent::kMouseWheel,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->Event()->web_event->GetType());
wheel_event = static_cast<const WebMouseWheelEvent*>(
- dispatched_events.at(0).event_->web_event.get());
+ dispatched_messages[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(9, wheel_event->delta_x);
EXPECT_EQ(-7, wheel_event->delta_y);
// Ack the fourth event.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
ASSERT_EQ(WebInputEvent::kMouseWheel,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->Event()->web_event->GetType());
wheel_event = static_cast<const WebMouseWheelEvent*>(
- dispatched_events.at(0).event_->web_event.get());
+ dispatched_messages[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(0, wheel_event->delta_x);
EXPECT_EQ(-10, wheel_event->delta_y);
// Ack the fifth event.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
ASSERT_EQ(WebInputEvent::kMouseWheel,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->Event()->web_event->GetType());
wheel_event = static_cast<const WebMouseWheelEvent*>(
- dispatched_events.at(0).event_->web_event.get());
+ dispatched_messages[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(0, wheel_event->delta_x);
EXPECT_EQ(0, wheel_event->delta_y);
EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase);
// After the final ack, the queue should be empty.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(0u, dispatched_events.size());
-}
-
-// Tests that touch-events are queued properly.
-TEST_F(InputRouterImplRafAlignedTouchDisabledTest, TouchEventQueue) {
- OnHasTouchEventHandlers(true);
-
- PressTouchPoint(1, 1);
- SendTouchEvent();
- EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
- EXPECT_FALSE(TouchEventQueueEmpty());
-
- // The second touch should not be sent since one is already in queue.
- MoveTouchPoint(0, 5, 5);
- SendTouchEvent();
- EXPECT_FALSE(client_->GetAndResetFilterEventCalled());
- EXPECT_EQ(0u, GetAndResetDispatchedEvents().size());
- EXPECT_FALSE(TouchEventQueueEmpty());
-
- // Receive an ACK for the first touch-event.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_FALSE(TouchEventQueueEmpty());
- EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(WebInputEvent::kTouchStart,
- disposition_handler_->acked_touch_event().event.GetType());
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
-
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_TRUE(TouchEventQueueEmpty());
- EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(WebInputEvent::kTouchMove,
- disposition_handler_->acked_touch_event().event.GetType());
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0u, dispatched_messages.size());
}
// Tests that touch-events are sent properly.
@@ -692,34 +616,34 @@ TEST_F(InputRouterImplTest, TouchEventQueue) {
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
- DispatchedEvents touch_start_event = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_start_event.size());
+ DispatchedMessages touch_start_event = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_start_event.size());
+ ASSERT_TRUE(touch_start_event[0]->ToEvent());
EXPECT_FALSE(TouchEventQueueEmpty());
// The second touch should be sent right away.
MoveTouchPoint(0, 5, 5);
SendTouchEvent();
- DispatchedEvents touch_move_event = GetAndResetDispatchedEvents();
+ DispatchedMessages touch_move_event = GetAndResetDispatchedMessages();
EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
- EXPECT_EQ(1U, touch_move_event.size());
+ ASSERT_EQ(1U, touch_move_event.size());
+ ASSERT_TRUE(touch_move_event[0]->ToEvent());
EXPECT_FALSE(TouchEventQueueEmpty());
// Receive an ACK for the first touch-event.
- CallCallback(std::move(touch_start_event.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ touch_start_event[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_FALSE(TouchEventQueueEmpty());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(WebInputEvent::kTouchStart,
disposition_handler_->acked_touch_event().event.GetType());
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
- CallCallback(std::move(touch_move_event.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ touch_move_event[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_TRUE(TouchEventQueueEmpty());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(WebInputEvent::kTouchMove,
disposition_handler_->acked_touch_event().event.GetType());
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
}
// Tests that the touch-queue is emptied after a page stops listening for touch
@@ -727,7 +651,7 @@ TEST_F(InputRouterImplTest, TouchEventQueue) {
TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
OnHasTouchEventHandlers(true);
EXPECT_TRUE(client_->has_touch_handler());
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
EXPECT_TRUE(TouchEventQueueEmpty());
// Send a touch-press event.
@@ -736,21 +660,22 @@ TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
MoveTouchPoint(0, 2, 2);
MoveTouchPoint(0, 3, 3);
EXPECT_FALSE(TouchEventQueueEmpty());
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
// The page stops listening for touch-events. Note that flushing is deferred
// until the outstanding ack is received.
OnHasTouchEventHandlers(false);
EXPECT_FALSE(client_->has_touch_handler());
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
EXPECT_FALSE(TouchEventQueueEmpty());
// After the ack, the touch-event queue should be empty, and none of the
// flushed touch-events should have been sent to the renderer.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
EXPECT_TRUE(TouchEventQueueEmpty());
}
@@ -764,27 +689,31 @@ TEST_F(InputRouterImplTest, UnhandledWheelEvent) {
WebMouseWheelEvent::kPhaseChanged);
// Check that only the first event was sent.
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
// Indicate that the wheel event was unhandled.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- dispatched_events = GetAndResetDispatchedEvents();
+ dispatched_messages = GetAndResetDispatchedMessages();
// GestureEventQueue allows multiple in-flight events, so there should be a
// ScrollBegin, ScrollUpdate, and MouseWheel sent.
- EXPECT_EQ(3U, dispatched_events.size());
+ ASSERT_EQ(3U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[1]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[2]->ToEvent());
ASSERT_EQ(WebInputEvent::kGestureScrollBegin,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->Event()->web_event->GetType());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(1).event_->web_event->GetType());
+ dispatched_messages[1]->ToEvent()->Event()->web_event->GetType());
ASSERT_EQ(WebInputEvent::kMouseWheel,
- dispatched_events.at(2).event_->web_event->GetType());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[2]->ToEvent()->Event()->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// Check that the ack for ScrollBegin, MouseWheel were
// processed.
@@ -792,27 +721,28 @@ TEST_F(InputRouterImplTest, UnhandledWheelEvent) {
EXPECT_EQ(disposition_handler_->acked_wheel_event().delta_y, -5);
// Ack the gesture scroll update event.
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[1]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
// Ack the mouse wheel event.
- CallCallback(std::move(dispatched_events.at(2).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_messages[2]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->Event()->web_event->GetType());
// Check that the correct unhandled wheel event was received.
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
disposition_handler_->acked_wheel_event_state());
EXPECT_EQ(disposition_handler_->acked_wheel_event().delta_y, -10);
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// Check that the ack for ScrollUpdate were processed.
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
@@ -827,67 +757,75 @@ TEST_F(InputRouterImplWheelScrollLatchingDisabledTest, UnhandledWheelEvent) {
WebMouseWheelEvent::kPhaseChanged);
// Check that only the first event was sent.
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
// Indicate that the wheel event was unhandled.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- dispatched_events = GetAndResetDispatchedEvents();
+ dispatched_messages = GetAndResetDispatchedMessages();
// Check that the ack for MouseWheel and GestureScrollBegin was processed.
EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(disposition_handler_->acked_wheel_event().delta_y, -5);
// There should be a ScrollBegin, ScrollUpdate, ScrollEnd and MouseWheel sent.
- EXPECT_EQ(4U, dispatched_events.size());
+ ASSERT_EQ(4U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[1]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[2]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[3]->ToEvent());
ASSERT_EQ(WebInputEvent::kGestureScrollBegin,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->Event()->web_event->GetType());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(1).event_->web_event->GetType());
+ dispatched_messages[1]->ToEvent()->Event()->web_event->GetType());
ASSERT_EQ(WebInputEvent::kGestureScrollEnd,
- dispatched_events.at(2).event_->web_event->GetType());
+ dispatched_messages[2]->ToEvent()->Event()->web_event->GetType());
ASSERT_EQ(WebInputEvent::kMouseWheel,
- dispatched_events.at(3).event_->web_event->GetType());
+ dispatched_messages[3]->ToEvent()->Event()->web_event->GetType());
// Ack the ScrollUpdate
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[1]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// Check that the ack for ScrollUpdate and ScrollEnd was processed.
EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
// The GestureScrollEnd should have already been processed.
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
// Ack the MouseWheel.
- CallCallback(std::move(dispatched_events.at(3).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_messages[3]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
// Check that the ack for MouseWheel and GestureScrollBegin was processed.
EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
// There should be a ScrollBegin, ScrollUpdate and ScrollEnd sent.
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(3U, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(3U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[1]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[2]->ToEvent());
ASSERT_EQ(WebInputEvent::kGestureScrollBegin,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->Event()->web_event->GetType());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(1).event_->web_event->GetType());
+ dispatched_messages[1]->ToEvent()->Event()->web_event->GetType());
ASSERT_EQ(WebInputEvent::kGestureScrollEnd,
- dispatched_events.at(2).event_->web_event->GetType());
+ dispatched_messages[2]->ToEvent()->Event()->web_event->GetType());
// Check that the correct unhandled wheel event was received.
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
disposition_handler_->acked_wheel_event_state());
EXPECT_EQ(disposition_handler_->acked_wheel_event().delta_y, -10);
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[1]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// The GestureScrollEnd should have already been processed.
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
// Check that the ack for the ScrollUpdate and ScrollEnd were processed.
EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
@@ -901,29 +839,34 @@ TEST_F(InputRouterImplAsyncWheelEventEnabledTest, UnhandledWheelEvent) {
WebMouseWheelEvent::kPhaseChanged);
// Check that only the first event was sent.
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
// Indicate that the wheel event was unhandled.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
// There should be a ScrollBegin, ScrollUpdate, second MouseWheel, and second
// ScrollUpdate sent.
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(4U, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(4U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[1]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[2]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[3]->ToEvent());
ASSERT_EQ(WebInputEvent::kGestureScrollBegin,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_messages[0]->ToEvent()->Event()->web_event->GetType());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(1).event_->web_event->GetType());
+ dispatched_messages[1]->ToEvent()->Event()->web_event->GetType());
ASSERT_EQ(WebInputEvent::kMouseWheel,
- dispatched_events.at(2).event_->web_event->GetType());
+ dispatched_messages[2]->ToEvent()->Event()->web_event->GetType());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(3).event_->web_event->GetType());
+ dispatched_messages[3]->ToEvent()->Event()->web_event->GetType());
// Indicate that the GestureScrollBegin event was consumed.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// Check that the ack for the first MouseWheel, ScrollBegin, and the second
// MouseWheel were processed.
@@ -936,8 +879,8 @@ TEST_F(InputRouterImplAsyncWheelEventEnabledTest, UnhandledWheelEvent) {
disposition_handler_->acked_wheel_event_state());
// Ack the first gesture scroll update.
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[1]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// Check that the ack for the first ScrollUpdate were processed.
EXPECT_EQ(
@@ -946,8 +889,8 @@ TEST_F(InputRouterImplAsyncWheelEventEnabledTest, UnhandledWheelEvent) {
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
// Ack the second gesture scroll update.
- CallCallback(std::move(dispatched_events.at(3).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[3]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// Check that the ack for the second ScrollUpdate were processed.
EXPECT_EQ(
@@ -969,23 +912,25 @@ TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
// Precede the TouchCancel with an appropriate TouchStart;
PressTouchPoint(1, 1);
SendTouchEvent();
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
ASSERT_EQ(1U, disposition_handler_->GetAndResetAckCount());
ASSERT_EQ(0, client_->in_flight_event_count());
// The TouchCancel has no callback.
CancelTouchPoint(0);
SendTouchEvent();
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
EXPECT_FALSE(HasPendingEvents());
- EXPECT_FALSE(dispatched_events.at(0).callback_);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_FALSE(dispatched_messages[0]->ToEvent()->HasCallback());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_FALSE(HasPendingEvents());
}
@@ -1011,22 +956,23 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAck) {
WebInputEvent::Type type = eventTypes[i];
if (ShouldBlockEventStream(GetEventWithType(type))) {
SimulateGestureEvent(type, blink::kWebGestureDeviceTouchscreen);
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
if (type == WebInputEvent::kGestureScrollUpdate)
- EXPECT_EQ(2U, dispatched_events.size());
+ EXPECT_EQ(2U, dispatched_messages.size());
else
- EXPECT_EQ(1U, dispatched_events.size());
+ EXPECT_EQ(1U, dispatched_messages.size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
EXPECT_TRUE(HasPendingEvents());
+ ASSERT_TRUE(
+ dispatched_messages[dispatched_messages.size() - 1]->ToEvent());
- CallCallback(
- std::move(
- dispatched_events.at(dispatched_events.size() - 1).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_messages[dispatched_messages.size() - 1]
+ ->ToEvent()
+ ->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
EXPECT_FALSE(HasPendingEvents());
@@ -1034,7 +980,7 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAck) {
}
SimulateGestureEvent(type, blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
EXPECT_FALSE(HasPendingEvents());
@@ -1049,16 +995,17 @@ TEST_F(InputRouterImplTest, MouseTypesIgnoringAck) {
WebInputEvent::Type type = static_cast<WebInputEvent::Type>(i);
SimulateMouseEvent(type, 0, 0);
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
if (ShouldBlockEventStream(GetEventWithType(type))) {
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
} else {
@@ -1099,18 +1046,19 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
SimulateGestureEvent(WebInputEvent::kGestureScrollUpdate,
blink::kWebGestureDeviceTouchscreen);
- dispatched_events = GetAndResetDispatchedEvents();
+ dispatched_messages = GetAndResetDispatchedMessages();
// Should have sent |kTouchScrollStarted| and |kGestureScrollUpdate|.
- EXPECT_EQ(2U, dispatched_events.size());
+ EXPECT_EQ(2U, dispatched_messages.size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
@@ -1118,7 +1066,7 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
SimulateGestureEvent(WebInputEvent::kGestureTapDown,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
@@ -1126,14 +1074,14 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
SimulateGestureEvent(WebInputEvent::kGestureScrollUpdate,
blink::kWebGestureDeviceTouchscreen);
- DispatchedEvents temp_dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, temp_dispatched_events.size());
- dispatched_events.emplace_back(std::move(temp_dispatched_events.at(0)));
+ DispatchedMessages temp_dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, temp_dispatched_messages.size());
+ dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
SimulateGestureEvent(WebInputEvent::kGestureShowPress,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(2, client_->in_flight_event_count());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
@@ -1141,9 +1089,9 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
SimulateGestureEvent(WebInputEvent::kGestureScrollUpdate,
blink::kWebGestureDeviceTouchscreen);
- temp_dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, temp_dispatched_events.size());
- dispatched_events.emplace_back(std::move(temp_dispatched_events.at(0)));
+ temp_dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, temp_dispatched_messages.size());
+ dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(3, client_->in_flight_event_count());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
@@ -1151,7 +1099,7 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
SimulateGestureEvent(WebInputEvent::kGestureTapCancel,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(3, client_->in_flight_event_count());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
@@ -1160,21 +1108,25 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
// Now ack each ack-respecting event. Should see in-flight event count
// decreasing and additional acks coming back.
// Ack the first GestureScrollUpdate, note that |at(0)| is TouchScrollStarted.
- EXPECT_EQ(4U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ ASSERT_EQ(4U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[1]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[2]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[3]->ToEvent());
+ dispatched_messages[1]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(2, client_->in_flight_event_count());
// Ack the second GestureScrollUpdate
- CallCallback(std::move(dispatched_events.at(2).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_messages[2]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
// Ack the last GestureScrollUpdate
- CallCallback(std::move(dispatched_events.at(3).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_messages[3]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
}
@@ -1184,16 +1136,16 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, dispatched_messages.size());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
// GesturePinchBegin ignores its ack.
SimulateGestureEvent(WebInputEvent::kGesturePinchBegin,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
// GesturePinchUpdate waits for an ack.
@@ -1201,8 +1153,8 @@ TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
// to the renderer (in contrast to the TrackpadPinchUpdate test).
SimulateGestureEvent(WebInputEvent::kGesturePinchUpdate,
blink::kWebGestureDeviceTouchscreen);
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, dispatched_messages.size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
EXPECT_EQ(WebInputEvent::kGesturePinchUpdate,
@@ -1213,7 +1165,7 @@ TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
// in-flight events.
SimulateGestureEvent(WebInputEvent::kGestureShowPress,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
EXPECT_EQ(WebInputEvent::kGesturePinchUpdate,
@@ -1221,16 +1173,16 @@ TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
SimulateGestureEvent(WebInputEvent::kGestureShowPress,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
EXPECT_EQ(WebInputEvent::kGesturePinchUpdate,
client_->last_in_flight_event_type());
// Ack the GesturePinchUpdate to release two GestureShowPress ack.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(3U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
}
@@ -1247,25 +1199,26 @@ TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
RunTasksAndWait(base::TimeDelta::FromMilliseconds(kDesktopTimeoutMs + 1));
// The timed-out event should have been ack'ed.
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
// Ack'ing the timed-out event should fire a TouchCancel.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
// The remainder of the touch sequence should be dropped.
ReleaseTouchPoint(0);
SendTouchEvent();
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
ASSERT_TRUE(TouchEventTimeoutEnabled());
// A mobile-optimized site should use the mobile timeout. For this test that
@@ -1280,30 +1233,35 @@ TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
SendTouchEvent();
- DispatchedEvents touch_press_event2 = GetAndResetDispatchedEvents();
+ DispatchedMessages touch_press_event2 = GetAndResetDispatchedMessages();
EXPECT_EQ(1U, touch_press_event2.size());
EXPECT_TRUE(TouchEventTimeoutEnabled());
ReleaseTouchPoint(0);
SendTouchEvent();
- DispatchedEvents touch_release_event2 = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_release_event2.size());
- CallCallback(std::move(touch_press_event2.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- CallCallback(std::move(touch_release_event2.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ DispatchedMessages touch_release_event2 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_release_event2.size());
+ ASSERT_TRUE(touch_release_event2[0]->ToEvent());
+ touch_press_event2[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ touch_release_event2[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
PressTouchPoint(1, 1);
SendTouchEvent();
- DispatchedEvents touch_press_event3 = GetAndResetDispatchedEvents();
+ DispatchedMessages touch_press_event3 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, touch_press_event3.size());
+ ASSERT_TRUE(touch_press_event3[0]->ToEvent());
CancelTouchTimeout();
EXPECT_FALSE(TouchEventTimeoutEnabled());
ReleaseTouchPoint(0);
SendTouchEvent();
- DispatchedEvents touch_release_event3 = GetAndResetDispatchedEvents();
- CallCallback(std::move(touch_press_event3.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- CallCallback(std::move(touch_release_event3.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ DispatchedMessages touch_release_event3 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, touch_release_event3.size());
+ ASSERT_TRUE(touch_release_event3[0]->ToEvent());
+ touch_press_event3[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ touch_release_event3[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// As the touch-action is reset by a new touch sequence, the timeout behavior
// should be restored.
@@ -1325,47 +1283,49 @@ TEST_F(InputRouterImplTest,
// Start a touch sequence.
PressTouchPoint(1, 1);
SendTouchEvent();
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
// kTouchActionNone should disable the timeout.
CancelTouchTimeout();
- CallCallbackWithTouchAction(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED,
- cc::kTouchActionNone);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ InputEventAckSource::COMPOSITOR_THREAD, ui::LatencyInfo(),
+ INPUT_EVENT_ACK_STATE_CONSUMED, base::nullopt, cc::kTouchActionNone);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_FALSE(TouchEventTimeoutEnabled());
MoveTouchPoint(0, 1, 2);
SendTouchEvent();
- dispatched_events = GetAndResetDispatchedEvents();
+ dispatched_messages = GetAndResetDispatchedMessages();
EXPECT_FALSE(TouchEventTimeoutEnabled());
- EXPECT_EQ(1U, dispatched_events.size());
+ EXPECT_EQ(1U, dispatched_messages.size());
// Delay the move ack. The timeout should not fire.
RunTasksAndWait(base::TimeDelta::FromMilliseconds(kDesktopTimeoutMs + 1));
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
// End the touch sequence.
ReleaseTouchPoint(0);
SendTouchEvent();
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, dispatched_messages.size());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_TRUE(TouchEventTimeoutEnabled());
disposition_handler_->GetAndResetAckCount();
- GetAndResetDispatchedEvents();
+ GetAndResetDispatchedMessages();
// Start another touch sequence. This should restore the touch timeout.
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_TRUE(TouchEventTimeoutEnabled());
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, dispatched_messages.size());
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
// Wait for the touch ack timeout to fire.
@@ -1381,69 +1341,72 @@ TEST_F(InputRouterImplTest, TouchActionResetBeforeEventReachesRenderer) {
// Sequence 1.
PressTouchPoint(1, 1);
SendTouchEvent();
- DispatchedEvents touch_press_event1 = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_press_event1.size());
+ DispatchedMessages touch_press_event1 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_press_event1.size());
+ ASSERT_TRUE(touch_press_event1[0]->ToEvent());
CancelTouchTimeout();
MoveTouchPoint(0, 50, 50);
SendTouchEvent();
- DispatchedEvents touch_move_event1 = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_move_event1.size());
+ DispatchedMessages touch_move_event1 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_move_event1.size());
+ ASSERT_TRUE(touch_move_event1[0]->ToEvent());
ReleaseTouchPoint(0);
SendTouchEvent();
- DispatchedEvents touch_release_event1 = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_release_event1.size());
+ DispatchedMessages touch_release_event1 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_release_event1.size());
+ ASSERT_TRUE(touch_release_event1[0]->ToEvent());
// Sequence 2.
PressTouchPoint(1, 1);
SendTouchEvent();
- DispatchedEvents touch_press_event2 = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_press_event2.size());
+ DispatchedMessages touch_press_event2 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_press_event2.size());
+ ASSERT_TRUE(touch_press_event2[0]->ToEvent());
MoveTouchPoint(0, 50, 50);
SendTouchEvent();
- DispatchedEvents touch_move_event2 = GetAndResetDispatchedEvents();
+ DispatchedMessages touch_move_event2 = GetAndResetDispatchedMessages();
EXPECT_EQ(1U, touch_move_event2.size());
ReleaseTouchPoint(0);
SendTouchEvent();
- DispatchedEvents touch_release_event2 = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_release_event2.size());
+ DispatchedMessages touch_release_event2 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_release_event2.size());
+ ASSERT_TRUE(touch_release_event2[0]->ToEvent());
- CallCallbackWithTouchAction(std::move(touch_press_event1.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED,
- cc::kTouchActionNone);
- CallCallback(std::move(touch_move_event1.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ touch_press_event1[0]->ToEvent()->CallCallback(
+ InputEventAckSource::COMPOSITOR_THREAD, ui::LatencyInfo(),
+ INPUT_EVENT_ACK_STATE_CONSUMED, base::nullopt, cc::kTouchActionNone);
+ touch_move_event1[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Ensure touch action is still none, as the next touch start hasn't been
// acked yet. ScrollBegin and ScrollEnd don't require acks.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
// This allows the next touch sequence to start.
- CallCallback(std::move(touch_release_event1.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ touch_release_event1[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// Ensure touch action has been set to auto, as a new touch sequence has
// started.
- CallCallback(std::move(touch_press_event2.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- CallCallback(std::move(touch_move_event2.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ touch_press_event2[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ touch_move_event2[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- DispatchedEvents gesture_scroll_begin = GetAndResetDispatchedEvents();
+ DispatchedMessages gesture_scroll_begin = GetAndResetDispatchedMessages();
EXPECT_EQ(1U, gesture_scroll_begin.size());
- CallCallback(std::move(gesture_scroll_begin.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ gesture_scroll_begin[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
- CallCallback(std::move(touch_release_event2.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
+ touch_release_event2[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
}
// Test that TouchActionFilter::ResetTouchAction is called when a new touch
@@ -1454,60 +1417,64 @@ TEST_F(InputRouterImplTest, TouchActionResetWhenTouchHasNoConsumer) {
// Sequence 1.
PressTouchPoint(1, 1);
SendTouchEvent();
- DispatchedEvents touch_press_event1 = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_press_event1.size());
+ DispatchedMessages touch_press_event1 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_press_event1.size());
+ ASSERT_TRUE(touch_press_event1[0]->ToEvent());
MoveTouchPoint(0, 50, 50);
SendTouchEvent();
- DispatchedEvents touch_move_event1 = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_move_event1.size());
+ DispatchedMessages touch_move_event1 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_move_event1.size());
+ ASSERT_TRUE(touch_move_event1[0]->ToEvent());
CancelTouchTimeout();
- CallCallbackWithTouchAction(std::move(touch_press_event1.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED,
- cc::kTouchActionNone);
- CallCallback(std::move(touch_move_event1.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ touch_press_event1[0]->ToEvent()->CallCallback(
+ InputEventAckSource::COMPOSITOR_THREAD, ui::LatencyInfo(),
+ INPUT_EVENT_ACK_STATE_CONSUMED, base::nullopt, cc::kTouchActionNone);
+ touch_move_event1[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
ReleaseTouchPoint(0);
SendTouchEvent();
- DispatchedEvents touch_release_event1 = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_move_event1.size());
+ DispatchedMessages touch_release_event1 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_release_event1.size());
+ ASSERT_TRUE(touch_release_event1[0]->ToEvent());
// Sequence 2
PressTouchPoint(1, 1);
SendTouchEvent();
- DispatchedEvents touch_press_event2 = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, touch_press_event2.size());
+ DispatchedMessages touch_press_event2 = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, touch_press_event2.size());
+ ASSERT_TRUE(touch_press_event2[0]->ToEvent());
MoveTouchPoint(0, 50, 50);
SendTouchEvent();
ReleaseTouchPoint(0);
SendTouchEvent();
- EXPECT_EQ(2U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(2U, GetAndResetDispatchedMessages().size());
// Ensure we have touch-action:none. ScrollBegin and ScrollEnd don't require
// acks.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
- CallCallback(std::move(touch_release_event1.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- CallCallback(std::move(touch_press_event2.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ touch_release_event1[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ touch_press_event2[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
// Ensure touch action has been set to auto, as the touch had no consumer.
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
}
// Test that TouchActionFilter::ResetTouchAction is called when the touch
@@ -1522,26 +1489,29 @@ TEST_F(InputRouterImplTest, TouchActionResetWhenTouchHandlerRemoved) {
CancelTouchTimeout();
ReleaseTouchPoint(0);
SendTouchEvent();
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(3U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(3U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[1]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[2]->ToEvent());
// Ensure we have touch-action:none, suppressing scroll events.
- CallCallbackWithTouchAction(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED,
- cc::kTouchActionNone);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ InputEventAckSource::COMPOSITOR_THREAD, ui::LatencyInfo(),
+ INPUT_EVENT_ACK_STATE_CONSUMED, base::nullopt, cc::kTouchActionNone);
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
+ dispatched_messages[1]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
- CallCallback(std::move(dispatched_events.at(2).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_messages[2]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
// Sequence without a touch handler. Note that in this case, the view may not
// necessarily forward touches to the router (as no touch handler exists).
@@ -1551,13 +1521,14 @@ TEST_F(InputRouterImplTest, TouchActionResetWhenTouchHandlerRemoved) {
// removed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
}
// Tests that async touch-moves are ack'd from the browser side.
@@ -1567,31 +1538,33 @@ TEST_F(InputRouterImplTest, AsyncTouchMoveAckedImmediately) {
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
EXPECT_FALSE(TouchEventQueueEmpty());
// Receive an ACK for the first touch-event.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
SimulateGestureEvent(WebInputEvent::kGestureScrollUpdate,
blink::kWebGestureDeviceTouchscreen);
EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(2U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(2U, GetAndResetDispatchedMessages().size());
// Now send an async move.
MoveTouchPoint(0, 5, 5);
SendTouchEvent();
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
}
// Test that the double tap gesture depends on the touch action of the first
@@ -1603,12 +1576,12 @@ TEST_F(InputRouterImplTest, DoubleTapGestureDependsOnFirstTap) {
PressTouchPoint(1, 1);
SendTouchEvent();
CancelTouchTimeout();
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallbackWithTouchAction(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED,
- cc::kTouchActionNone);
-
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ InputEventAckSource::COMPOSITOR_THREAD, ui::LatencyInfo(),
+ INPUT_EVENT_ACK_STATE_CONSUMED, base::nullopt, cc::kTouchActionNone);
ReleaseTouchPoint(0);
SendTouchEvent();
@@ -1624,125 +1597,52 @@ TEST_F(InputRouterImplTest, DoubleTapGestureDependsOnFirstTap) {
// none.
SimulateGestureEvent(WebInputEvent::kGestureTapUnconfirmed,
blink::kWebGestureDeviceTouchscreen);
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(4U, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(4U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[1]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[2]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[3]->ToEvent());
// This test will become invalid if GestureTap stops requiring an ack.
ASSERT_TRUE(
ShouldBlockEventStream(GetEventWithType(WebInputEvent::kGestureTap)));
EXPECT_EQ(3, client_->in_flight_event_count());
- CallCallback(std::move(dispatched_events.at(3).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(2, client_->in_flight_event_count());
-
- // This tap gesture is dropped, since the GestureTapUnconfirmed was turned
- // into a tap.
- SimulateGestureEvent(WebInputEvent::kGestureTap,
- blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
-
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
-
- // Second Tap.
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
- SimulateGestureEvent(WebInputEvent::kGestureTapDown,
- blink::kWebGestureDeviceTouchscreen);
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
-
- // Although the touch-action is now auto, the double tap still won't be
- // dispatched, because the first tap occured when the touch-action was none.
- SimulateGestureEvent(WebInputEvent::kGestureDoubleTap,
- blink::kWebGestureDeviceTouchscreen);
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- // This test will become invalid if GestureDoubleTap stops requiring an ack.
- ASSERT_TRUE(ShouldBlockEventStream(
- GetEventWithType(WebInputEvent::kGestureDoubleTap)));
- EXPECT_EQ(1, client_->in_flight_event_count());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0, client_->in_flight_event_count());
-}
-
-// Test that the double tap gesture depends on the touch action of the first
-// tap.
-TEST_F(InputRouterImplRafAlignedTouchDisabledTest,
- DoubleTapGestureDependsOnFirstTap) {
- OnHasTouchEventHandlers(true);
-
- // Sequence 1.
- PressTouchPoint(1, 1);
- SendTouchEvent();
- CancelTouchTimeout();
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallbackWithTouchAction(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED,
- cc::kTouchActionNone);
-
- ReleaseTouchPoint(0);
- SendTouchEvent();
-
- // Sequence 2
- PressTouchPoint(1, 1);
- SendTouchEvent();
-
- // First tap.
- SimulateGestureEvent(WebInputEvent::kGestureTapDown,
- blink::kWebGestureDeviceTouchscreen);
-
- // The GestureTapUnconfirmed is converted into a tap, as the touch action is
- // none.
- SimulateGestureEvent(WebInputEvent::kGestureTapUnconfirmed,
- blink::kWebGestureDeviceTouchscreen);
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(3U, dispatched_events.size());
- // This test will become invalid if GestureTap stops requiring an ack.
- ASSERT_TRUE(
- ShouldBlockEventStream(GetEventWithType(WebInputEvent::kGestureTap)));
+ dispatched_messages[3]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(2, client_->in_flight_event_count());
- CallCallback(std::move(dispatched_events.at(2).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(1, client_->in_flight_event_count());
// This tap gesture is dropped, since the GestureTapUnconfirmed was turned
// into a tap.
SimulateGestureEvent(WebInputEvent::kGestureTap,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, GetAndResetDispatchedEvents().size());
-
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- ASSERT_EQ(WebInputEvent::kTouchStart,
- dispatched_events.at(0).event_->web_event->GetType());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[1]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
// Second Tap.
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
SimulateGestureEvent(WebInputEvent::kGestureTapDown,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetAndResetDispatchedEvents().size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, dispatched_messages.size());
// Although the touch-action is now auto, the double tap still won't be
// dispatched, because the first tap occured when the touch-action was none.
SimulateGestureEvent(WebInputEvent::kGestureDoubleTap,
blink::kWebGestureDeviceTouchscreen);
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, dispatched_messages.size());
// This test will become invalid if GestureDoubleTap stops requiring an ack.
ASSERT_TRUE(ShouldBlockEventStream(
GetEventWithType(WebInputEvent::kGestureDoubleTap)));
- EXPECT_EQ(1, client_->in_flight_event_count());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ ASSERT_EQ(1, client_->in_flight_event_count());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0, client_->in_flight_event_count());
}
@@ -1756,10 +1656,11 @@ TEST_F(InputRouterImplTest, TouchpadPinchUpdate) {
blink::kWebGestureDeviceTouchpad);
// Verify we actually sent a special wheel event to the renderer.
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
const WebInputEvent* input_event =
- dispatched_events.at(0).event_->web_event.get();
+ dispatched_messages[0]->ToEvent()->Event()->web_event.get();
ASSERT_EQ(WebInputEvent::kGesturePinchUpdate, input_event->GetType());
const WebGestureEvent* gesture_event =
static_cast<const WebGestureEvent*>(input_event);
@@ -1768,8 +1669,8 @@ TEST_F(InputRouterImplTest, TouchpadPinchUpdate) {
EXPECT_EQ(20, gesture_event->global_x);
EXPECT_EQ(25, gesture_event->global_y);
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
// Check that the correct unhandled pinch event was received.
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
@@ -1785,14 +1686,15 @@ TEST_F(InputRouterImplTest, TouchpadPinchUpdate) {
// Second a second pinch event.
SimulateGesturePinchUpdateEvent(0.3f, 20, 25, 0,
blink::kWebGestureDeviceTouchpad);
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- input_event = dispatched_events.at(0).event_->web_event.get();
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ input_event = dispatched_messages[0]->ToEvent()->Event()->web_event.get();
ASSERT_EQ(WebInputEvent::kGesturePinchUpdate, input_event->GetType());
gesture_event = static_cast<const WebGestureEvent*>(input_event);
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
// Check that the correct HANDLED pinch event was received.
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
@@ -1811,72 +1713,78 @@ TEST_F(InputRouterImplTest, TouchpadPinchAndScrollUpdate) {
blink::kWebGestureDeviceTouchpad);
SimulateGestureEvent(WebInputEvent::kGestureScrollUpdate,
blink::kWebGestureDeviceTouchpad);
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(2U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(2U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ ASSERT_TRUE(dispatched_messages[1]->ToEvent());
EXPECT_EQ(2, client_->in_flight_event_count());
// Subsequent scroll and pinch events will also be sent immediately.
SimulateGesturePinchUpdateEvent(1.5f, 20, 25, 0,
blink::kWebGestureDeviceTouchpad);
- DispatchedEvents temp_dispatched_events = GetAndResetDispatchedEvents();
- ASSERT_EQ(1U, temp_dispatched_events.size());
- dispatched_events.emplace_back(std::move(temp_dispatched_events.at(0)));
+ DispatchedMessages temp_dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, temp_dispatched_messages.size());
+ ASSERT_TRUE(temp_dispatched_messages[0]->ToEvent());
+ dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
EXPECT_EQ(3, client_->in_flight_event_count());
SimulateGestureScrollUpdateEvent(1.5f, 1.5f, 0,
blink::kWebGestureDeviceTouchpad);
- temp_dispatched_events = GetAndResetDispatchedEvents();
- ASSERT_EQ(1U, temp_dispatched_events.size());
- dispatched_events.emplace_back(std::move(temp_dispatched_events.at(0)));
+ temp_dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, temp_dispatched_messages.size());
+ ASSERT_TRUE(temp_dispatched_messages[0]->ToEvent());
+ dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
EXPECT_EQ(4, client_->in_flight_event_count());
SimulateGesturePinchUpdateEvent(1.5f, 20, 25, 0,
blink::kWebGestureDeviceTouchpad);
- temp_dispatched_events = GetAndResetDispatchedEvents();
- ASSERT_EQ(1U, temp_dispatched_events.size());
- dispatched_events.emplace_back(std::move(temp_dispatched_events.at(0)));
+ temp_dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, temp_dispatched_messages.size());
+ ASSERT_TRUE(temp_dispatched_messages[0]->ToEvent());
+ dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
EXPECT_EQ(5, client_->in_flight_event_count());
SimulateGestureScrollUpdateEvent(0.f, 1.5f, 0,
blink::kWebGestureDeviceTouchpad);
- temp_dispatched_events = GetAndResetDispatchedEvents();
- ASSERT_EQ(1U, temp_dispatched_events.size());
- dispatched_events.emplace_back(std::move(temp_dispatched_events.at(0)));
+ temp_dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, temp_dispatched_messages.size());
+ ASSERT_TRUE(temp_dispatched_messages[0]->ToEvent());
+ dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
EXPECT_EQ(6, client_->in_flight_event_count());
// Ack'ing events should decrease in-flight event count.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(5, client_->in_flight_event_count());
// Ack the second scroll.
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[1]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(4, client_->in_flight_event_count());
// Ack the pinch event.
- CallCallback(std::move(dispatched_events.at(2).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[2]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(3, client_->in_flight_event_count());
// Ack the scroll event.
- CallCallback(std::move(dispatched_events.at(3).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[3]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(2, client_->in_flight_event_count());
// Ack the pinch event.
- CallCallback(std::move(dispatched_events.at(4).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[4]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
// Ack the scroll event.
- CallCallback(std::move(dispatched_events.at(5).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_messages[5]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
}
@@ -1906,13 +1814,14 @@ void InputRouterImplTest::OverscrollDispatch() {
SimulateWheelEventPossiblyIncludingPhase(!wheel_scroll_latching_enabled_, 0,
0, 3, 0, 0, false,
WebMouseWheelEvent::kPhaseBegan);
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
- std::move(dispatched_events.at(0).callback_)
- .Run(InputEventAckSource::COMPOSITOR_THREAD, ui::LatencyInfo(),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
- DidOverscrollParams(wheel_overscroll), base::nullopt);
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ InputEventAckSource::COMPOSITOR_THREAD, ui::LatencyInfo(),
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED, DidOverscrollParams(wheel_overscroll),
+ base::nullopt);
client_overscroll = client_->GetAndResetOverscroll();
EXPECT_EQ(wheel_overscroll.accumulated_overscroll,
@@ -1951,32 +1860,35 @@ TEST_F(InputRouterImplTest, TouchValidationPassesWithFilteredInputEvents) {
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
SendTouchEvent();
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
PressTouchPoint(1, 1);
SendTouchEvent();
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
// This event will be filtered out, since no consumer exists.
ReleaseTouchPoint(1);
SendTouchEvent();
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(0U, dispatched_events.size());
+ dispatched_messages = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, dispatched_messages.size());
// If the validator didn't see the filtered out release event, it will crash
// now, upon seeing a press for a touch which it believes to be still pressed.
PressTouchPoint(1, 1);
SendTouchEvent();
- dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
}
TEST_F(InputRouterImplTest, TouchActionInCallback) {
@@ -1985,11 +1897,12 @@ TEST_F(InputRouterImplTest, TouchActionInCallback) {
// Send a touchstart
PressTouchPoint(1, 1);
SendTouchEvent();
- DispatchedEvents dispatched_events = GetAndResetDispatchedEvents();
- EXPECT_EQ(1U, dispatched_events.size());
- CallCallbackWithTouchAction(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED,
- cc::TouchAction::kTouchActionNone);
+ DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
+ ASSERT_EQ(1U, dispatched_messages.size());
+ ASSERT_TRUE(dispatched_messages[0]->ToEvent());
+ dispatched_messages[0]->ToEvent()->CallCallback(
+ InputEventAckSource::COMPOSITOR_THREAD, ui::LatencyInfo(),
+ INPUT_EVENT_ACK_STATE_CONSUMED, base::nullopt, cc::kTouchActionNone);
ASSERT_EQ(1U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(cc::TouchAction::kTouchActionNone,
input_router_->AllowedTouchAction());
@@ -2008,10 +1921,10 @@ class InputRouterImplScaleEventTest : public InputRouterImplTest {
template <typename T>
const T* GetSentWebInputEvent() {
- EXPECT_EQ(1u, dispatched_events_.size());
+ EXPECT_EQ(1u, dispatched_messages_.size());
return static_cast<const T*>(
- dispatched_events_.at(0).event_->web_event.get());
+ dispatched_messages_[0]->ToEvent()->Event()->web_event.get());
}
template <typename T>
@@ -2019,12 +1932,12 @@ class InputRouterImplScaleEventTest : public InputRouterImplTest {
return static_cast<const T*>(client_->last_filter_event());
}
- void UpdateDispatchedEvents() {
- dispatched_events_ = GetAndResetDispatchedEvents();
+ void UpdateDispatchedMessages() {
+ dispatched_messages_ = GetAndResetDispatchedMessages();
}
protected:
- DispatchedEvents dispatched_events_;
+ DispatchedMessages dispatched_messages_;
private:
DISALLOW_COPY_AND_ASSIGN(InputRouterImplScaleEventTest);
@@ -2038,7 +1951,7 @@ class InputRouterImplScaleMouseEventTest
void RunMouseEventTest(const std::string& name, WebInputEvent::Type type) {
SCOPED_TRACE(name);
SimulateMouseEvent(type, 10, 10);
- UpdateDispatchedEvents();
+ UpdateDispatchedMessages();
const WebMouseEvent* sent_event = GetSentWebInputEvent<WebMouseEvent>();
EXPECT_EQ(20, sent_event->PositionInWidget().x);
EXPECT_EQ(20, sent_event->PositionInWidget().y);
@@ -2064,7 +1977,7 @@ TEST_F(InputRouterImplScaleMouseEventTest, ScaleMouseEventTest) {
TEST_F(InputRouterImplScaleEventTest, ScaleMouseWheelEventTest) {
SimulateWheelEventWithPhase(5, 5, 10, 10, 0, false,
WebMouseWheelEvent::kPhaseBegan);
- UpdateDispatchedEvents();
+ UpdateDispatchedMessages();
const WebMouseWheelEvent* sent_event =
GetSentWebInputEvent<WebMouseWheelEvent>();
@@ -2138,22 +2051,22 @@ class InputRouterImplScaleTouchEventTest
void FlushTouchEvent(WebInputEvent::Type type) {
SendTouchEvent();
- UpdateDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events_.size());
- if (dispatched_events_.at(0).callback_) {
- CallCallback(std::move(dispatched_events_.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- }
+ UpdateDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_messages_.size());
+ ASSERT_TRUE(dispatched_messages_[0]->ToEvent());
+ dispatched_messages_[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
ASSERT_TRUE(TouchEventQueueEmpty());
}
void ReleaseTouchPointAndAck(int index) {
ReleaseTouchPoint(index);
SendTouchEvent();
- UpdateDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events_.size());
- CallCallback(std::move(dispatched_events_.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ UpdateDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_messages_.size());
+ ASSERT_TRUE(dispatched_messages_[0]->ToEvent());
+ dispatched_messages_[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
}
private:
@@ -2262,12 +2175,11 @@ class InputRouterImplScaleGestureEventTest
}
void FlushGestureEvent(WebInputEvent::Type type) {
- UpdateDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events_.size());
- if (dispatched_events_.at(0).callback_) {
- CallCallback(std::move(dispatched_events_.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- }
+ UpdateDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_messages_.size());
+ ASSERT_TRUE(dispatched_messages_[0]->ToEvent());
+ dispatched_messages_[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_CONSUMED);
}
void TestLocationInSentEvent(const WebGestureEvent* sent_event,
diff --git a/chromium/content/browser/renderer_host/input/legacy_input_router_impl.cc b/chromium/content/browser/renderer_host/input/legacy_input_router_impl.cc
index b2c41a67584..aac5baa0a73 100644
--- a/chromium/content/browser/renderer_host/input/legacy_input_router_impl.cc
+++ b/chromium/content/browser/renderer_host/input/legacy_input_router_impl.cc
@@ -16,13 +16,11 @@
#include "content/browser/renderer_host/input/gesture_event_queue.h"
#include "content/browser/renderer_host/input/input_disposition_handler.h"
#include "content/browser/renderer_host/input/input_router_client.h"
-#include "content/browser/renderer_host/input/legacy_touch_event_queue.h"
#include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
#include "content/browser/renderer_host/input/touch_event_queue.h"
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
#include "content/common/content_constants_internal.h"
#include "content/common/edit_command.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/common/input/web_touch_event_traits.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
@@ -30,6 +28,7 @@
#include "content/public/browser/notification_types.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/input_event_ack_state.h"
#include "ipc/ipc_sender.h"
#include "ui/events/blink/blink_event_util.h"
#include "ui/events/blink/web_input_event_traits.h"
@@ -47,32 +46,6 @@ using blink::WebTouchEvent;
using ui::WebInputEventTraits;
namespace content {
-namespace {
-
-const char* GetEventAckName(InputEventAckState ack_result) {
- switch (ack_result) {
- case INPUT_EVENT_ACK_STATE_UNKNOWN:
- return "UNKNOWN";
- case INPUT_EVENT_ACK_STATE_CONSUMED:
- return "CONSUMED";
- case INPUT_EVENT_ACK_STATE_NOT_CONSUMED:
- return "NOT_CONSUMED";
- case INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE:
- return "CONSUMED_SHOULD_BUBBLE";
- case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS:
- return "NO_CONSUMER_EXISTS";
- case INPUT_EVENT_ACK_STATE_IGNORED:
- return "IGNORED";
- case INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING:
- return "SET_NON_BLOCKING";
- case INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING:
- return "SET_NON_BLOCKING_DUE_TO_FLING";
- }
- DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.";
- return "";
-}
-
-} // namespace
LegacyInputRouterImpl::LegacyInputRouterImpl(
IPC::Sender* sender,
@@ -87,23 +60,15 @@ LegacyInputRouterImpl::LegacyInputRouterImpl(
frame_tree_node_id_(-1),
select_message_pending_(false),
move_caret_pending_(false),
- current_ack_source_(ACK_SOURCE_NONE),
active_renderer_fling_count_(0),
touch_scroll_started_sent_(false),
wheel_scroll_latching_enabled_(base::FeatureList::IsEnabled(
features::kTouchpadAndWheelScrollLatching)),
wheel_event_queue_(this, wheel_scroll_latching_enabled_),
gesture_event_queue_(this, this, config.gesture_config),
- device_scale_factor_(1.f),
- raf_aligned_touch_enabled_(
- base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents)) {
- if (raf_aligned_touch_enabled_) {
- touch_event_queue_.reset(
- new PassthroughTouchEventQueue(this, config.touch_config));
- } else {
- touch_event_queue_.reset(
- new LegacyTouchEventQueue(this, config.touch_config));
- }
+ device_scale_factor_(1.f) {
+ touch_event_queue_.reset(
+ new PassthroughTouchEventQueue(this, config.touch_config));
DCHECK(sender);
DCHECK(client);
@@ -238,7 +203,8 @@ void LegacyInputRouterImpl::SetDeviceScaleFactor(float device_scale_factor) {
}
void LegacyInputRouterImpl::BindHost(
- mojom::WidgetInputHandlerHostRequest request) {
+ mojom::WidgetInputHandlerHostRequest request,
+ bool frame_handler) {
NOTREACHED();
}
@@ -265,6 +231,7 @@ bool LegacyInputRouterImpl::OnMessageReceived(const IPC::Message& message) {
void LegacyInputRouterImpl::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.
@@ -273,7 +240,7 @@ void LegacyInputRouterImpl::OnTouchEventAck(
touch_action_filter_.ResetTouchAction();
UpdateTouchAckTimeoutEnabled();
}
- disposition_handler_->OnTouchEventAck(event, ack_result);
+ disposition_handler_->OnTouchEventAck(event, ack_source, ack_result);
// Reset the touch action at the end of a touch-action sequence.
if (WebTouchEventTraits::IsTouchSequenceEnd(event.event)) {
@@ -296,9 +263,10 @@ void LegacyInputRouterImpl::OnFilteringTouchEvent(
void LegacyInputRouterImpl::OnGestureEventAck(
const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
touch_event_queue_->OnGestureEventAck(event, ack_result);
- disposition_handler_->OnGestureEventAck(event, ack_result);
+ disposition_handler_->OnGestureEventAck(event, ack_source, ack_result);
}
void LegacyInputRouterImpl::ForwardGestureEventWithLatencyInfo(
@@ -314,8 +282,9 @@ void LegacyInputRouterImpl::SendMouseWheelEventImmediately(
void LegacyInputRouterImpl::OnMouseWheelEventAck(
const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
- disposition_handler_->OnWheelEventAck(event, ack_result);
+ disposition_handler_->OnWheelEventAck(event, ack_source, ack_result);
}
bool LegacyInputRouterImpl::SendSelectMessage(
@@ -378,7 +347,7 @@ void LegacyInputRouterImpl::OfferToHandlers(
return;
bool should_block = WebInputEventTraits::ShouldBlockEventStream(
- input_event, raf_aligned_touch_enabled_, wheel_scroll_latching_enabled_);
+ input_event, wheel_scroll_latching_enabled_);
OfferToRenderer(input_event, latency_info,
should_block
? InputEventDispatchType::DISPATCH_TYPE_BLOCKING
@@ -387,9 +356,9 @@ void LegacyInputRouterImpl::OfferToHandlers(
// Generate a synthetic ack if the event was sent so it doesn't block.
if (!should_block) {
ProcessInputEventAck(
- input_event.GetType(), INPUT_EVENT_ACK_STATE_IGNORED, latency_info,
- WebInputEventTraits::GetUniqueTouchEventId(input_event),
- IGNORING_DISPOSITION);
+ input_event.GetType(), InputEventAckSource::BROWSER,
+ INPUT_EVENT_ACK_STATE_IGNORED, latency_info,
+ WebInputEventTraits::GetUniqueTouchEventId(input_event));
}
}
@@ -404,8 +373,9 @@ bool LegacyInputRouterImpl::OfferToClient(const WebInputEvent& input_event,
case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS:
// Send the ACK and early exit.
ProcessInputEventAck(
- input_event.GetType(), filter_ack, latency_info,
- WebInputEventTraits::GetUniqueTouchEventId(input_event), CLIENT);
+ input_event.GetType(), InputEventAckSource::BROWSER, filter_ack,
+ latency_info,
+ WebInputEventTraits::GetUniqueTouchEventId(input_event));
// WARNING: |this| may be deleted at this point.
consumed = true;
break;
@@ -459,8 +429,8 @@ void LegacyInputRouterImpl::OnInputEventAck(const InputEventAck& ack) {
if (ack.touch_action.has_value())
OnSetTouchAction(ack.touch_action.value());
- ProcessInputEventAck(ack.type, ack.state, ack.latency,
- ack.unique_touch_event_id, RENDERER);
+ ProcessInputEventAck(ack.type, ack.source, ack.state, ack.latency,
+ ack.unique_touch_event_id);
}
void LegacyInputRouterImpl::OnDidOverscroll(
@@ -535,34 +505,30 @@ void LegacyInputRouterImpl::OnDidStopFlinging() {
void LegacyInputRouterImpl::ProcessInputEventAck(
WebInputEvent::Type event_type,
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency_info,
- uint32_t unique_touch_event_id,
- AckSource ack_source) {
+ uint32_t unique_touch_event_id) {
TRACE_EVENT2("input", "LegacyInputRouterImpl::ProcessInputEventAck", "type",
WebInputEvent::GetName(event_type), "ack",
- GetEventAckName(ack_result));
+ InputEventAckStateToString(ack_result));
- // Note: The keyboard ack must be treated carefully, as it may result in
- // synchronous destruction of |this|. Handling immediately guards against
- // future references to |this|, as with |auto_reset_current_ack_source| below.
if (WebInputEvent::IsKeyboardEventType(event_type)) {
- ProcessKeyboardAck(event_type, ack_result, latency_info);
+ // Note: The keyboard ack must be treated carefully, as it may result in
+ // synchronous destruction of |this|. Handling immediately guards against
+ // future references to |this|.
+ ProcessKeyboardAck(event_type, ack_source, ack_result, latency_info);
// WARNING: |this| may be deleted at this point.
return;
- }
-
- base::AutoReset<AckSource> auto_reset_current_ack_source(&current_ack_source_,
- ack_source);
-
- if (WebInputEvent::IsMouseEventType(event_type)) {
- ProcessMouseAck(event_type, ack_result, latency_info);
+ } else if (WebInputEvent::IsMouseEventType(event_type)) {
+ ProcessMouseAck(event_type, ack_source, ack_result, latency_info);
} else if (event_type == WebInputEvent::kMouseWheel) {
- ProcessWheelAck(ack_result, latency_info);
+ ProcessWheelAck(ack_source, ack_result, latency_info);
} else if (WebInputEvent::IsTouchEventType(event_type)) {
- ProcessTouchAck(ack_result, latency_info, unique_touch_event_id);
+ ProcessTouchAck(ack_source, ack_result, latency_info,
+ unique_touch_event_id);
} else if (WebInputEvent::IsGestureEventType(event_type)) {
- ProcessGestureAck(event_type, ack_result, latency_info);
+ ProcessGestureAck(event_type, ack_source, ack_result, latency_info);
} else if (event_type != WebInputEvent::kUndefined) {
disposition_handler_->OnUnexpectedEventAck(
InputDispositionHandler::BAD_ACK_MESSAGE);
@@ -570,6 +536,7 @@ void LegacyInputRouterImpl::ProcessInputEventAck(
}
void LegacyInputRouterImpl::ProcessKeyboardAck(blink::WebInputEvent::Type type,
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency) {
if (key_queue_.empty()) {
@@ -586,7 +553,8 @@ void LegacyInputRouterImpl::ProcessKeyboardAck(blink::WebInputEvent::Type type,
front_item.latency.AddNewLatencyFrom(latency);
key_queue_.pop_front();
- disposition_handler_->OnKeyboardEventAck(front_item, ack_result);
+ disposition_handler_->OnKeyboardEventAck(front_item, ack_source,
+ ack_result);
// WARNING: This LegacyInputRouterImpl can be deallocated at this point
// (i.e. in the case of Ctrl+W, where the call to
// HandleKeyboardEvent destroys this LegacyInputRouterImpl).
@@ -595,6 +563,7 @@ void LegacyInputRouterImpl::ProcessKeyboardAck(blink::WebInputEvent::Type type,
}
void LegacyInputRouterImpl::ProcessMouseAck(blink::WebInputEvent::Type type,
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency) {
if (mouse_event_queue_.empty()) {
@@ -604,16 +573,18 @@ void LegacyInputRouterImpl::ProcessMouseAck(blink::WebInputEvent::Type type,
MouseEventWithLatencyInfo front_item = mouse_event_queue_.front();
front_item.latency.AddNewLatencyFrom(latency);
mouse_event_queue_.pop_front();
- disposition_handler_->OnMouseEventAck(front_item, ack_result);
+ disposition_handler_->OnMouseEventAck(front_item, ack_source, ack_result);
}
}
-void LegacyInputRouterImpl::ProcessWheelAck(InputEventAckState ack_result,
+void LegacyInputRouterImpl::ProcessWheelAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result,
const ui::LatencyInfo& latency) {
- wheel_event_queue_.ProcessMouseWheelAck(ack_result, latency);
+ wheel_event_queue_.ProcessMouseWheelAck(ack_source, ack_result, latency);
}
void LegacyInputRouterImpl::ProcessGestureAck(WebInputEvent::Type type,
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency) {
if (type == blink::WebInputEvent::kGestureFlingStart &&
@@ -622,14 +593,15 @@ void LegacyInputRouterImpl::ProcessGestureAck(WebInputEvent::Type type,
}
// |gesture_event_queue_| will forward to OnGestureEventAck when appropriate.
- gesture_event_queue_.ProcessGestureAck(ack_result, type, latency);
+ gesture_event_queue_.ProcessGestureAck(ack_source, ack_result, type, latency);
}
-void LegacyInputRouterImpl::ProcessTouchAck(InputEventAckState ack_result,
+void LegacyInputRouterImpl::ProcessTouchAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result,
const ui::LatencyInfo& latency,
uint32_t unique_touch_event_id) {
// |touch_event_queue_| will forward to OnTouchEventAck when appropriate.
- touch_event_queue_->ProcessTouchAck(ack_result, latency,
+ touch_event_queue_->ProcessTouchAck(ack_source, ack_result, latency,
unique_touch_event_id);
}
diff --git a/chromium/content/browser/renderer_host/input/legacy_input_router_impl.h b/chromium/content/browser/renderer_host/input/legacy_input_router_impl.h
index bfed77ad6b3..be84b53d598 100644
--- a/chromium/content/browser/renderer_host/input/legacy_input_router_impl.h
+++ b/chromium/content/browser/renderer_host/input/legacy_input_router_impl.h
@@ -72,7 +72,8 @@ class CONTENT_EXPORT LegacyInputRouterImpl
void NotifySiteIsMobileOptimized(bool is_mobile_optimized) override;
bool HasPendingEvents() const override;
void SetDeviceScaleFactor(float device_scale_factor) override;
- void BindHost(mojom::WidgetInputHandlerHostRequest request) override;
+ void BindHost(mojom::WidgetInputHandlerHostRequest request,
+ bool frame_handler) override;
// IPC::Listener
bool OnMessageReceived(const IPC::Message& message) override;
@@ -103,6 +104,7 @@ class CONTENT_EXPORT LegacyInputRouterImpl
void SendTouchEventImmediately(
const TouchEventWithLatencyInfo& touch_event) override;
void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnFilteringTouchEvent(const blink::WebTouchEvent& touch_event) override;
@@ -110,12 +112,14 @@ class CONTENT_EXPORT LegacyInputRouterImpl
void SendGestureEventImmediately(
const GestureEventWithLatencyInfo& gesture_event) override;
void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
// MouseWheelEventQueueClient
void SendMouseWheelEventImmediately(
const MouseWheelEventWithLatencyInfo& touch_event) override;
void OnMouseWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void ForwardGestureEventWithLatencyInfo(
const blink::WebGestureEvent& gesture_event,
@@ -157,41 +161,43 @@ class CONTENT_EXPORT LegacyInputRouterImpl
InputEventAckState ack_result);
void OnDidStopFlinging();
- // Indicates the source of an ack provided to |ProcessInputEventAck()|.
- // The source is tracked by |current_ack_source_|, which aids in ack routing.
- enum AckSource { RENDERER, CLIENT, IGNORING_DISPOSITION, ACK_SOURCE_NONE };
// Note: This function may result in |this| being deleted, and as such
// should be the last method called in any internal chain of event handling.
void ProcessInputEventAck(blink::WebInputEvent::Type event_type,
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency_info,
- uint32_t unique_touch_event_id,
- AckSource ack_source);
+ uint32_t unique_touch_event_id);
// Dispatches the ack'ed event to |ack_handler_|.
void ProcessKeyboardAck(blink::WebInputEvent::Type type,
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency);
// Forwards a valid |next_mouse_move_| if |type| is MouseMove.
void ProcessMouseAck(blink::WebInputEvent::Type type,
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency);
// Dispatches the ack'ed event to |ack_handler_|, forwarding queued events
// from |coalesced_mouse_wheel_events_|.
- void ProcessWheelAck(InputEventAckState ack_result,
+ void ProcessWheelAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result,
const ui::LatencyInfo& latency);
// Forwards the event ack to |gesture_event_queue|, potentially triggering
// dispatch of queued gesture events.
void ProcessGestureAck(blink::WebInputEvent::Type type,
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
const ui::LatencyInfo& latency);
// Forwards the event ack to |touch_event_queue_|, potentially triggering
// dispatch of queued touch events, or the creation of gesture events.
- void ProcessTouchAck(InputEventAckState ack_result,
+ void ProcessTouchAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result,
const ui::LatencyInfo& latency,
uint32_t unique_touch_event_id);
@@ -233,10 +239,6 @@ class CONTENT_EXPORT LegacyInputRouterImpl
using KeyQueue = base::circular_deque<NativeWebKeyboardEventWithLatencyInfo>;
KeyQueue key_queue_;
- // The source of the ack within the scope of |ProcessInputEventAck()|.
- // Defaults to ACK_SOURCE_NONE.
- AckSource current_ack_source_;
-
// Whether there are any active flings in the renderer. As the fling
// end notification is asynchronous, we use a count rather than a boolean
// to avoid races in bookkeeping when starting a new fling.
@@ -256,7 +258,6 @@ class CONTENT_EXPORT LegacyInputRouterImpl
InputEventStreamValidator output_stream_validator_;
float device_scale_factor_;
- bool raf_aligned_touch_enabled_;
// Last touch position relative to screen. Used to compute movementX/Y.
std::map<int, gfx::Point> global_touch_position_;
diff --git a/chromium/content/browser/renderer_host/input/legacy_input_router_impl_perftest.cc b/chromium/content/browser/renderer_host/input/legacy_input_router_impl_perftest.cc
index ec9557bfe40..5b495fb05cc 100644
--- a/chromium/content/browser/renderer_host/input/legacy_input_router_impl_perftest.cc
+++ b/chromium/content/browser/renderer_host/input/legacy_input_router_impl_perftest.cc
@@ -40,22 +40,27 @@ class NullInputDispositionHandler : public InputDispositionHandler {
// InputDispositionHandler
void OnKeyboardEventAck(const NativeWebKeyboardEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override {
++ack_count_;
}
void OnMouseEventAck(const MouseEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override {
++ack_count_;
}
void OnWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override {
++ack_count_;
}
void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override {
++ack_count_;
}
void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override {
++ack_count_;
}
@@ -209,7 +214,6 @@ class InputEventTimer {
bool ShouldBlockEventStream(const blink::WebInputEvent& event) {
return ui::WebInputEventTraits::ShouldBlockEventStream(
event,
- base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents),
base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching));
}
diff --git a/chromium/content/browser/renderer_host/input/legacy_input_router_impl_unittest.cc b/chromium/content/browser/renderer_host/input/legacy_input_router_impl_unittest.cc
index d50cedebc39..a85f9fe3ee8 100644
--- a/chromium/content/browser/renderer_host/input/legacy_input_router_impl_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/legacy_input_router_impl_unittest.cc
@@ -67,7 +67,6 @@ namespace {
bool ShouldBlockEventStream(const blink::WebInputEvent& event) {
return ui::WebInputEventTraits::ShouldBlockEventStream(
event,
- base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents),
base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching));
}
@@ -76,12 +75,12 @@ const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
const char* data;
int data_length;
if (!iter.ReadData(&data, &data_length))
- return NULL;
+ return nullptr;
return reinterpret_cast<const WebInputEvent*>(data);
}
WebInputEvent& GetEventWithType(WebInputEvent::Type type) {
- WebInputEvent* event = NULL;
+ WebInputEvent* event = nullptr;
if (WebInputEvent::IsMouseEventType(type)) {
static WebMouseEvent mouse;
event = &mouse;
@@ -133,43 +132,22 @@ enum WheelScrollingMode {
class LegacyInputRouterImplTest : public testing::Test {
public:
LegacyInputRouterImplTest(
- bool raf_aligned_touch = true,
WheelScrollingMode wheel_scrolling_mode = kWheelScrollLatching)
: wheel_scroll_latching_enabled_(wheel_scrolling_mode !=
kWheelScrollingModeNone),
scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::UI) {
- if (raf_aligned_touch && wheel_scrolling_mode == kAsyncWheelEvents) {
- feature_list_.InitWithFeatures({features::kRafAlignedTouchInputEvents,
- features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents},
- {});
- } else if (raf_aligned_touch &&
- wheel_scrolling_mode == kWheelScrollLatching) {
- feature_list_.InitWithFeatures(
- {features::kRafAlignedTouchInputEvents,
- features::kTouchpadAndWheelScrollLatching},
- {features::kAsyncWheelEvents});
- } else if (raf_aligned_touch &&
- wheel_scrolling_mode == kWheelScrollingModeNone) {
- feature_list_.InitWithFeatures({features::kRafAlignedTouchInputEvents},
- {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents});
- } else if (!raf_aligned_touch &&
- wheel_scrolling_mode == kAsyncWheelEvents) {
+ if (wheel_scrolling_mode == kAsyncWheelEvents) {
feature_list_.InitWithFeatures({features::kTouchpadAndWheelScrollLatching,
features::kAsyncWheelEvents},
- {features::kRafAlignedTouchInputEvents});
- } else if (!raf_aligned_touch &&
- wheel_scrolling_mode == kWheelScrollLatching) {
+ {});
+ } else if (wheel_scrolling_mode == kWheelScrollLatching) {
feature_list_.InitWithFeatures(
{features::kTouchpadAndWheelScrollLatching},
- {features::kRafAlignedTouchInputEvents, features::kAsyncWheelEvents});
- } else { // !raf_aligned_touch && wheel_scroll_latching ==
- // kWheelScrollingModeNone.
+ {features::kAsyncWheelEvents});
+ } else if (wheel_scrolling_mode == kWheelScrollingModeNone) {
feature_list_.InitWithFeatures({},
- {features::kRafAlignedTouchInputEvents,
- features::kTouchpadAndWheelScrollLatching,
+ {features::kTouchpadAndWheelScrollLatching,
features::kAsyncWheelEvents});
}
@@ -429,25 +407,18 @@ class LegacyInputRouterImplTest : public testing::Test {
std::unique_ptr<TestBrowserContext> browser_context_;
};
-class LegacyInputRouterImplRafAlignedTouchDisabledTest
- : public LegacyInputRouterImplTest {
- public:
- LegacyInputRouterImplRafAlignedTouchDisabledTest()
- : LegacyInputRouterImplTest(false, kWheelScrollingModeNone) {}
-};
-
class LegacyInputRouterImplWheelScrollLatchingDisabledTest
: public LegacyInputRouterImplTest {
public:
LegacyInputRouterImplWheelScrollLatchingDisabledTest()
- : LegacyInputRouterImplTest(true, kWheelScrollingModeNone) {}
+ : LegacyInputRouterImplTest(kWheelScrollingModeNone) {}
};
class LegacyInputRouterImplAsyncWheelEventEnabledTest
: public LegacyInputRouterImplTest {
public:
LegacyInputRouterImplAsyncWheelEventEnabledTest()
- : LegacyInputRouterImplTest(true, kAsyncWheelEvents) {}
+ : LegacyInputRouterImplTest(kAsyncWheelEvents) {}
};
TEST_F(LegacyInputRouterImplTest, CoalescesRangeSelection) {
@@ -856,41 +827,6 @@ TEST_F(LegacyInputRouterImplTest, CoalescesWheelEvents) {
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
}
-// Tests that touch-events are queued properly.
-TEST_F(LegacyInputRouterImplRafAlignedTouchDisabledTest, TouchEventQueue) {
- OnHasTouchEventHandlers(true);
-
- PressTouchPoint(1, 1);
- uint32_t touch_press_event_id = SendTouchEvent();
- EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
- EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
- EXPECT_FALSE(TouchEventQueueEmpty());
-
- // The second touch should not be sent since one is already in queue.
- MoveTouchPoint(0, 5, 5);
- uint32_t touch_move_event_id = SendTouchEvent();
- EXPECT_FALSE(client_->GetAndResetFilterEventCalled());
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
- EXPECT_FALSE(TouchEventQueueEmpty());
-
- // Receive an ACK for the first touch-event.
- SendTouchEventACK(WebInputEvent::kTouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
- touch_press_event_id);
- EXPECT_FALSE(TouchEventQueueEmpty());
- EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(WebInputEvent::kTouchStart,
- disposition_handler_->acked_touch_event().event.GetType());
- EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
-
- SendTouchEventACK(WebInputEvent::kTouchMove, INPUT_EVENT_ACK_STATE_CONSUMED,
- touch_move_event_id);
- EXPECT_TRUE(TouchEventQueueEmpty());
- EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(WebInputEvent::kTouchMove,
- disposition_handler_->acked_touch_event().event.GetType());
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
-}
-
// Tests that touch-events are sent properly.
TEST_F(LegacyInputRouterImplTest, TouchEventQueue) {
OnHasTouchEventHandlers(true);
@@ -1718,74 +1654,6 @@ TEST_F(LegacyInputRouterImplTest, DoubleTapGestureDependsOnFirstTap) {
EXPECT_EQ(0, client_->in_flight_event_count());
}
-// Test that the double tap gesture depends on the touch action of the first
-// tap.
-TEST_F(LegacyInputRouterImplRafAlignedTouchDisabledTest,
- DoubleTapGestureDependsOnFirstTap) {
- OnHasTouchEventHandlers(true);
-
- // Sequence 1.
- PressTouchPoint(1, 1);
- uint32_t touch_press_event_id1 = SendTouchEvent();
- OnSetTouchAction(cc::kTouchActionNone);
- SendTouchEventACK(WebInputEvent::kTouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
- touch_press_event_id1);
-
- ReleaseTouchPoint(0);
- uint32_t touch_release_event_id = SendTouchEvent();
-
- // Sequence 2
- PressTouchPoint(1, 1);
- uint32_t touch_press_event_id2 = SendTouchEvent();
-
- // First tap.
- EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
- SimulateGestureEvent(WebInputEvent::kGestureTapDown,
- blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
-
- // The GestureTapUnconfirmed is converted into a tap, as the touch action is
- // none.
- SimulateGestureEvent(WebInputEvent::kGestureTapUnconfirmed,
- blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
- // This test will become invalid if GestureTap stops requiring an ack.
- ASSERT_TRUE(
- ShouldBlockEventStream(GetEventWithType(WebInputEvent::kGestureTap)));
- EXPECT_EQ(2, client_->in_flight_event_count());
- SendInputEventACK(WebInputEvent::kGestureTap, INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1, client_->in_flight_event_count());
-
- // This tap gesture is dropped, since the GestureTapUnconfirmed was turned
- // into a tap.
- SimulateGestureEvent(WebInputEvent::kGestureTap,
- blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
-
- SendTouchEventACK(WebInputEvent::kTouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED,
- touch_release_event_id);
- SendTouchEventACK(WebInputEvent::kTouchStart,
- INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
- touch_press_event_id2);
-
- // Second Tap.
- EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
- SimulateGestureEvent(WebInputEvent::kGestureTapDown,
- blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
-
- // Although the touch-action is now auto, the double tap still won't be
- // dispatched, because the first tap occured when the touch-action was none.
- SimulateGestureEvent(WebInputEvent::kGestureDoubleTap,
- blink::kWebGestureDeviceTouchscreen);
- // This test will become invalid if GestureDoubleTap stops requiring an ack.
- ASSERT_TRUE(ShouldBlockEventStream(
- GetEventWithType(WebInputEvent::kGestureDoubleTap)));
- EXPECT_EQ(1, client_->in_flight_event_count());
- SendInputEventACK(WebInputEvent::kGestureTap, INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0, client_->in_flight_event_count());
-}
-
// Test that GesturePinchUpdate is handled specially for trackpad
TEST_F(LegacyInputRouterImplTest, TouchpadPinchUpdate) {
// GesturePinchUpdate for trackpad sends synthetic wheel events.
diff --git a/chromium/content/browser/renderer_host/input/legacy_ipc_widget_input_handler.cc b/chromium/content/browser/renderer_host/input/legacy_ipc_widget_input_handler.cc
index e68cd6c3253..79f49e0e4d8 100644
--- a/chromium/content/browser/renderer_host/input/legacy_ipc_widget_input_handler.cc
+++ b/chromium/content/browser/renderer_host/input/legacy_ipc_widget_input_handler.cc
@@ -37,7 +37,7 @@ LegacyIPCWidgetInputHandler::LegacyIPCWidgetInputHandler(
LegacyIPCWidgetInputHandler::~LegacyIPCWidgetInputHandler() {}
void LegacyIPCWidgetInputHandler::SetFocus(bool focused) {
- SendInput(base::MakeUnique<InputMsg_SetFocus>(input_router_->routing_id(),
+ SendInput(std::make_unique<InputMsg_SetFocus>(input_router_->routing_id(),
focused));
}
@@ -45,12 +45,12 @@ void LegacyIPCWidgetInputHandler::MouseCaptureLost() {}
void LegacyIPCWidgetInputHandler::SetEditCommandsForNextKeyEvent(
const std::vector<EditCommand>& commands) {
- SendInput(base::MakeUnique<InputMsg_SetEditCommandsForNextKeyEvent>(
+ SendInput(std::make_unique<InputMsg_SetEditCommandsForNextKeyEvent>(
input_router_->routing_id(), commands));
}
void LegacyIPCWidgetInputHandler::CursorVisibilityChanged(bool visible) {
- SendInput(base::MakeUnique<InputMsg_CursorVisibilityChange>(
+ SendInput(std::make_unique<InputMsg_CursorVisibilityChange>(
input_router_->routing_id(), visible));
}
@@ -62,7 +62,7 @@ void LegacyIPCWidgetInputHandler::ImeSetComposition(
int32_t end) {
std::vector<blink::WebImeTextSpan> ime_text_spans =
ConvertToBlinkImeTextSpan(ui_ime_text_spans);
- SendInput(base::MakeUnique<InputMsg_ImeSetComposition>(
+ SendInput(std::make_unique<InputMsg_ImeSetComposition>(
input_router_->routing_id(), text, ime_text_spans, range, start, end));
}
@@ -73,18 +73,18 @@ void LegacyIPCWidgetInputHandler::ImeCommitText(
int32_t relative_cursor_position) {
std::vector<blink::WebImeTextSpan> ime_text_spans =
ConvertToBlinkImeTextSpan(ui_ime_text_spans);
- SendInput(base::MakeUnique<InputMsg_ImeCommitText>(
+ SendInput(std::make_unique<InputMsg_ImeCommitText>(
input_router_->routing_id(), text, ime_text_spans, range,
relative_cursor_position));
}
void LegacyIPCWidgetInputHandler::ImeFinishComposingText(bool keep_selection) {
- SendInput(base::MakeUnique<InputMsg_ImeFinishComposingText>(
+ SendInput(std::make_unique<InputMsg_ImeFinishComposingText>(
input_router_->routing_id(), keep_selection));
}
void LegacyIPCWidgetInputHandler::RequestTextInputStateUpdate() {
#if defined(OS_ANDROID)
- SendInput(base::MakeUnique<InputMsg_RequestTextInputStateUpdate>(
+ SendInput(std::make_unique<InputMsg_RequestTextInputStateUpdate>(
input_router_->routing_id()));
#endif
}
@@ -92,7 +92,7 @@ void LegacyIPCWidgetInputHandler::RequestTextInputStateUpdate() {
void LegacyIPCWidgetInputHandler::RequestCompositionUpdates(
bool immediate_request,
bool monitor_request) {
- SendInput(base::MakeUnique<InputMsg_RequestCompositionUpdates>(
+ SendInput(std::make_unique<InputMsg_RequestCompositionUpdates>(
input_router_->routing_id(), immediate_request, monitor_request));
}
diff --git a/chromium/content/browser/renderer_host/input/legacy_touch_event_queue.cc b/chromium/content/browser/renderer_host/input/legacy_touch_event_queue.cc
deleted file mode 100644
index 79e27c4f086..00000000000
--- a/chromium/content/browser/renderer_host/input/legacy_touch_event_queue.cc
+++ /dev/null
@@ -1,652 +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/input/legacy_touch_event_queue.h"
-
-#include <utility>
-
-#include "base/auto_reset.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/trace_event/trace_event.h"
-#include "content/browser/renderer_host/input/touch_timeout_handler.h"
-#include "content/common/input/web_touch_event_traits.h"
-#include "ui/events/base_event_utils.h"
-#include "ui/gfx/geometry/point_f.h"
-
-using blink::WebInputEvent;
-using blink::WebTouchEvent;
-using blink::WebTouchPoint;
-using ui::LatencyInfo;
-
-namespace content {
-namespace {
-
-// Time interval at which touchmove events will be forwarded to the client while
-// scrolling is active and possible.
-const double kAsyncTouchMoveIntervalSec = .2;
-
-// Compare all properties of touch points to determine the state.
-bool HasPointChanged(const WebTouchPoint& point_1,
- const WebTouchPoint& point_2) {
- DCHECK_EQ(point_1.id, point_2.id);
- if (point_1.PositionInScreen() != point_2.PositionInScreen() ||
- point_1.PositionInWidget() != point_2.PositionInWidget() ||
- point_1.radius_x != point_2.radius_x ||
- point_1.radius_y != point_2.radius_y ||
- point_1.rotation_angle != point_2.rotation_angle ||
- point_1.force != point_2.force || point_1.tilt_x != point_2.tilt_x ||
- point_1.tilt_y != point_2.tilt_y) {
- return true;
- }
- return false;
-}
-
-} // namespace
-
-// This class represents a single coalesced touch event. However, it also keeps
-// track of all the original touch-events that were coalesced into a single
-// event. The coalesced event is forwarded to the renderer, while the original
-// touch-events are sent to the Client (on ACK for the coalesced event) so that
-// the Client receives the event with their original timestamp.
-class CoalescedWebTouchEvent {
- public:
- CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event,
- bool suppress_client_ack)
- : coalesced_event_(event), suppress_client_ack_(suppress_client_ack) {
- TRACE_EVENT_ASYNC_BEGIN0("input", "LegacyTouchEventQueue::QueueEvent",
- this);
- }
-
- ~CoalescedWebTouchEvent() {
- TRACE_EVENT_ASYNC_END0("input", "LegacyTouchEventQueue::QueueEvent", this);
- }
-
- // Coalesces the event with the existing event if possible. Returns whether
- // the event was coalesced.
- bool CoalesceEventIfPossible(
- const TouchEventWithLatencyInfo& event_with_latency) {
- if (suppress_client_ack_)
- return false;
-
- if (!coalesced_event_.CanCoalesceWith(event_with_latency))
- return false;
-
- // Addition of the first event to |uncoaleseced_events_to_ack_| is deferred
- // until the first coalesced event, optimizing the (common) case where the
- // event is not coalesced at all.
- if (uncoaleseced_events_to_ack_.empty())
- uncoaleseced_events_to_ack_.push_back(coalesced_event_);
-
- TRACE_EVENT_INSTANT0("input", "LegacyTouchEventQueue::MoveCoalesced",
- TRACE_EVENT_SCOPE_THREAD);
- coalesced_event_.CoalesceWith(event_with_latency);
- uncoaleseced_events_to_ack_.push_back(event_with_latency);
- DCHECK_GE(uncoaleseced_events_to_ack_.size(), 2U);
- return true;
- }
-
- void DispatchAckToClient(InputEventAckState ack_result,
- const ui::LatencyInfo* optional_latency_info,
- TouchEventQueueClient* client) {
- DCHECK(client);
- if (suppress_client_ack_)
- return;
-
- if (uncoaleseced_events_to_ack_.empty()) {
- if (optional_latency_info)
- coalesced_event_.latency.AddNewLatencyFrom(*optional_latency_info);
- client->OnTouchEventAck(coalesced_event_, ack_result);
- return;
- }
-
- DCHECK_GE(uncoaleseced_events_to_ack_.size(), 2U);
- for (WebTouchEventWithLatencyList::iterator
- iter = uncoaleseced_events_to_ack_.begin(),
- end = uncoaleseced_events_to_ack_.end();
- iter != end; ++iter) {
- if (optional_latency_info)
- iter->latency.AddNewLatencyFrom(*optional_latency_info);
- client->OnTouchEventAck(*iter, ack_result);
- }
- }
-
- const TouchEventWithLatencyInfo& coalesced_event() const {
- return coalesced_event_;
- }
-
- private:
- // This is the event that is forwarded to the renderer.
- TouchEventWithLatencyInfo coalesced_event_;
-
- // This is the list of the original events that were coalesced, each requiring
- // future ack dispatch to the client.
- // Note that this will be empty if no coalescing has occurred.
- typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
- WebTouchEventWithLatencyList uncoaleseced_events_to_ack_;
-
- bool suppress_client_ack_;
-
- DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent);
-};
-
-LegacyTouchEventQueue::LegacyTouchEventQueue(TouchEventQueueClient* client,
- const Config& config)
- : client_(client),
- dispatching_touch_ack_(false),
- dispatching_touch_(false),
- has_handlers_(true),
- has_handler_for_current_sequence_(false),
- drop_remaining_touches_in_sequence_(false),
- send_touch_events_async_(false),
- last_sent_touch_timestamp_sec_(0) {
- if (config.touch_ack_timeout_supported) {
- timeout_handler_.reset(
- new TouchTimeoutHandler(this, config.desktop_touch_ack_timeout_delay,
- config.mobile_touch_ack_timeout_delay));
- }
-}
-
-LegacyTouchEventQueue::~LegacyTouchEventQueue() {}
-
-void LegacyTouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
- TRACE_EVENT0("input", "LegacyTouchEventQueue::QueueEvent");
-
- // If the queueing of |event| was triggered by an ack dispatch, defer
- // processing the event until the dispatch has finished.
- if (touch_queue_.empty() && !dispatching_touch_ack_) {
- // Optimization of the case without touch handlers. Removing this path
- // yields identical results, but this avoids unnecessary allocations.
- PreFilterResult filter_result = FilterBeforeForwarding(event.event);
- if (filter_result != FORWARD_TO_RENDERER) {
- client_->OnFilteringTouchEvent(event.event);
- client_->OnTouchEventAck(event,
- filter_result == ACK_WITH_NO_CONSUMER_EXISTS
- ? INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS
- : INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- return;
- }
-
- // There is no touch event in the queue. Forward it to the renderer
- // immediately.
- touch_queue_.push_back(
- base::MakeUnique<CoalescedWebTouchEvent>(event, false));
- ForwardNextEventToRenderer();
- return;
- }
-
- // If the last queued touch-event was a touch-move, and the current event is
- // also a touch-move, then the events can be coalesced into a single event.
- if (touch_queue_.size() > 1) {
- CoalescedWebTouchEvent* last_event = touch_queue_.back().get();
- if (last_event->CoalesceEventIfPossible(event))
- return;
- }
- touch_queue_.push_back(
- base::MakeUnique<CoalescedWebTouchEvent>(event, false));
-}
-
-void LegacyTouchEventQueue::PrependTouchScrollNotification() {
- TRACE_EVENT0("input",
- "LegacyTouchEventQueue::PrependTouchScrollNotification");
-
- // The queue should have an in-flight event when this method is called because
- // this method is triggered by InputRouterImpl::SendGestureEvent, which is
- // triggered by LegacyTouchEventQueue::AckTouchEventToClient, which has just
- // received an ack for the in-flight event. We leave the head of the queue
- // untouched since it is the in-flight event.
- //
- // However, for the (integration) tests in RenderWidgetHostTest that trigger
- // this method indirectly, they push the TouchScrollStarted event into
- // TouchEventQueue without any way to dispatch it. Below we added a check for
- // non-empty queue to keep those tests as-is w/o exposing internals of this
- // class all the way up.
- if (!touch_queue_.empty()) {
- TouchEventWithLatencyInfo touch(
- WebInputEvent::kTouchScrollStarted, WebInputEvent::kNoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()), LatencyInfo());
- touch.event.dispatch_type = WebInputEvent::kEventNonBlocking;
-
- auto it = touch_queue_.begin();
- DCHECK(it != touch_queue_.end());
- touch_queue_.insert(++it,
- base::MakeUnique<CoalescedWebTouchEvent>(touch, false));
- }
-}
-
-void LegacyTouchEventQueue::ProcessTouchAck(
- InputEventAckState ack_result,
- const LatencyInfo& latency_info,
- const uint32_t unique_touch_event_id) {
- TRACE_EVENT0("input", "LegacyTouchEventQueue::ProcessTouchAck");
-
- // We receive an ack for async touchmove from render.
- if (!ack_pending_async_touchmove_ids_.empty() &&
- ack_pending_async_touchmove_ids_.front() == unique_touch_event_id) {
- // Remove the first touchmove from the ack_pending_async_touchmove queue.
- ack_pending_async_touchmove_ids_.pop_front();
- // Send the next pending async touch move once we receive all acks back.
- if (pending_async_touchmove_ && ack_pending_async_touchmove_ids_.empty()) {
- DCHECK(touch_queue_.empty());
-
- // Dispatch the next pending async touch move when time expires.
- if (pending_async_touchmove_->event.TimeStampSeconds() >=
- last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec) {
- FlushPendingAsyncTouchmove();
- }
- }
- return;
- }
-
- DCHECK(!dispatching_touch_ack_);
- dispatching_touch_ = false;
-
- if (timeout_handler_ &&
- timeout_handler_->ConfirmTouchEvent(unique_touch_event_id, ack_result))
- return;
-
- if (touch_queue_.empty())
- return;
-
- // We don't care about the ordering of the acks vs the ordering of the
- // dispatched events because we can receive the ack for event B before the ack
- // for event A even though A was sent before B. This seems to be happening
- // when, for example, A is acked from renderer but B isn't, so the ack for B
- // is synthesized "locally" in InputRouter.
- //
- // TODO(crbug.com/600773): Bring the id checks back when dispatch triggering
- // is sane.
-
- PopTouchEventToClient(ack_result, latency_info);
- TryForwardNextEventToRenderer();
-}
-
-void LegacyTouchEventQueue::TryForwardNextEventToRenderer() {
- DCHECK(!dispatching_touch_ack_);
- // If there are queued touch events, then try to forward them to the renderer
- // immediately, or ACK the events back to the client if appropriate.
- while (!touch_queue_.empty()) {
- const WebTouchEvent& event = touch_queue_.front()->coalesced_event().event;
- PreFilterResult filter_result = FilterBeforeForwarding(event);
- if (filter_result != FORWARD_TO_RENDERER)
- client_->OnFilteringTouchEvent(event);
- switch (filter_result) {
- case ACK_WITH_NO_CONSUMER_EXISTS:
- PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- break;
- case ACK_WITH_NOT_CONSUMED:
- PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- break;
- case FORWARD_TO_RENDERER:
- ForwardNextEventToRenderer();
- return;
- }
- }
-}
-
-void LegacyTouchEventQueue::ForwardNextEventToRenderer() {
- TRACE_EVENT0("input", "LegacyTouchEventQueue::ForwardNextEventToRenderer");
-
- DCHECK(!empty());
- DCHECK(!dispatching_touch_);
- TouchEventWithLatencyInfo touch = touch_queue_.front()->coalesced_event();
-
- if (send_touch_events_async_ &&
- touch.event.GetType() == WebInputEvent::kTouchMove) {
- // Throttling touchmove's in a continuous touchmove stream while scrolling
- // reduces the risk of jank. However, it's still important that the web
- // application be sent touches at key points in the gesture stream,
- // e.g., when the application slop region is exceeded or touchmove
- // coalescing fails because of different modifiers.
- bool send_touchmove_now = size() > 1;
- send_touchmove_now |= pending_async_touchmove_ &&
- !pending_async_touchmove_->CanCoalesceWith(touch);
- send_touchmove_now |=
- ack_pending_async_touchmove_ids_.empty() &&
- (touch.event.TimeStampSeconds() >=
- last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec);
-
- if (!send_touchmove_now) {
- if (!pending_async_touchmove_) {
- pending_async_touchmove_.reset(new TouchEventWithLatencyInfo(touch));
- } else {
- DCHECK(pending_async_touchmove_->CanCoalesceWith(touch));
- pending_async_touchmove_->CoalesceWith(touch);
- }
- DCHECK_EQ(1U, size());
- PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- // It's possible (though unlikely) that ack'ing the current touch will
- // trigger the queueing of another touch event (e.g., a touchcancel). As
- // forwarding of the queued event will be deferred while the ack is being
- // dispatched (see |OnTouchEvent()|), try forwarding it now.
- TryForwardNextEventToRenderer();
- return;
- }
- }
-
- last_sent_touch_timestamp_sec_ = touch.event.TimeStampSeconds();
-
- // Flush any pending async touch move. If it can be combined with the current
- // (touchmove) event, great, otherwise send it immediately but separately. Its
- // ack will trigger forwarding of the original |touch| event.
- if (pending_async_touchmove_) {
- if (pending_async_touchmove_->CanCoalesceWith(touch)) {
- pending_async_touchmove_->CoalesceWith(touch);
- pending_async_touchmove_->event.dispatch_type =
- send_touch_events_async_ ? WebInputEvent::kEventNonBlocking
- : WebInputEvent::kBlocking;
- touch = *pending_async_touchmove_;
- pending_async_touchmove_.reset();
- } else {
- FlushPendingAsyncTouchmove();
- return;
- }
- }
-
- // Note: Touchstart events are marked cancelable to allow transitions between
- // platform scrolling and JS pinching. Touchend events, however, remain
- // uncancelable, mitigating the risk of jank when transitioning to a fling.
- if (send_touch_events_async_ &&
- touch.event.GetType() != WebInputEvent::kTouchStart)
- touch.event.dispatch_type = WebInputEvent::kEventNonBlocking;
-
- SendTouchEventImmediately(&touch);
-}
-
-void LegacyTouchEventQueue::FlushPendingAsyncTouchmove() {
- DCHECK(!dispatching_touch_);
- std::unique_ptr<TouchEventWithLatencyInfo> touch =
- std::move(pending_async_touchmove_);
- touch->event.dispatch_type = WebInputEvent::kEventNonBlocking;
- touch_queue_.push_front(
- base::MakeUnique<CoalescedWebTouchEvent>(*touch, true));
- SendTouchEventImmediately(touch.get());
-}
-
-void LegacyTouchEventQueue::OnGestureScrollEvent(
- const GestureEventWithLatencyInfo& gesture_event) {
- if (gesture_event.event.GetType() ==
- blink::WebInputEvent::kGestureScrollBegin) {
- pending_async_touchmove_.reset();
-
- return;
- }
-
- if (gesture_event.event.GetType() ==
- blink::WebInputEvent::kGestureScrollUpdate &&
- gesture_event.event.resending_plugin_id == -1) {
- send_touch_events_async_ = true;
- }
-}
-
-void LegacyTouchEventQueue::OnGestureEventAck(
- const GestureEventWithLatencyInfo& event,
- InputEventAckState ack_result) {
- // Throttle sending touchmove events as long as the scroll events are handled.
- // Note that there's no guarantee that this ACK is for the most recent
- // gesture event (or even part of the current sequence). Worst case, the
- // delay in updating the absorption state will result in minor UI glitches.
- // A valid |pending_async_touchmove_| will be flushed when the next event is
- // forwarded. Scroll updates that are being resent from a GuestView are
- // ignored.
- if (event.event.GetType() == blink::WebInputEvent::kGestureScrollUpdate &&
- event.event.resending_plugin_id == -1) {
- send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
- }
-}
-
-void LegacyTouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) {
- DCHECK(!dispatching_touch_ack_);
- DCHECK(!dispatching_touch_);
- has_handlers_ = has_handlers;
-}
-
-bool LegacyTouchEventQueue::IsPendingAckTouchStart() const {
- DCHECK(!dispatching_touch_ack_);
- if (touch_queue_.empty())
- return false;
-
- const blink::WebTouchEvent& event =
- touch_queue_.front()->coalesced_event().event;
- return (event.GetType() == WebInputEvent::kTouchStart);
-}
-
-void LegacyTouchEventQueue::SetAckTimeoutEnabled(bool enabled) {
- if (timeout_handler_)
- timeout_handler_->SetEnabled(enabled);
-}
-
-void LegacyTouchEventQueue::SetIsMobileOptimizedSite(
- bool mobile_optimized_site) {
- if (timeout_handler_)
- timeout_handler_->SetUseMobileTimeout(mobile_optimized_site);
-}
-
-bool LegacyTouchEventQueue::IsAckTimeoutEnabled() const {
- return timeout_handler_ && timeout_handler_->IsEnabled();
-}
-
-bool LegacyTouchEventQueue::Empty() const {
- return touch_queue_.empty();
-}
-
-bool LegacyTouchEventQueue::HasPendingAsyncTouchMoveForTesting() const {
- return !!pending_async_touchmove_;
-}
-
-bool LegacyTouchEventQueue::IsTimeoutRunningForTesting() const {
- return timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning();
-}
-
-const TouchEventWithLatencyInfo&
-LegacyTouchEventQueue::GetLatestEventForTesting() const {
- return touch_queue_.back()->coalesced_event();
-}
-
-void LegacyTouchEventQueue::FlushQueue() {
- DCHECK(!dispatching_touch_ack_);
- DCHECK(!dispatching_touch_);
- pending_async_touchmove_.reset();
- drop_remaining_touches_in_sequence_ = true;
- while (!touch_queue_.empty())
- PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
-}
-
-void LegacyTouchEventQueue::PopTouchEventToClient(
- InputEventAckState ack_result) {
- AckTouchEventToClient(ack_result, nullptr);
-}
-
-void LegacyTouchEventQueue::PopTouchEventToClient(
- InputEventAckState ack_result,
- const LatencyInfo& renderer_latency_info) {
- AckTouchEventToClient(ack_result, &renderer_latency_info);
-}
-
-void LegacyTouchEventQueue::AckTouchEventToClient(
- InputEventAckState ack_result,
- const ui::LatencyInfo* optional_latency_info) {
- DCHECK(!dispatching_touch_ack_);
- if (touch_queue_.empty()) {
- NOTREACHED() << "Too many acks";
- return;
- }
- std::unique_ptr<CoalescedWebTouchEvent> acked_event =
- std::move(touch_queue_.front());
- DCHECK(acked_event);
-
- UpdateTouchConsumerStates(acked_event->coalesced_event().event, ack_result);
-
- // Note that acking the touch-event may result in multiple gestures being sent
- // to the renderer, or touch-events being queued.
- base::AutoReset<bool> dispatching_touch_ack(&dispatching_touch_ack_, true);
-
- // Skip ack for TouchScrollStarted since it was synthesized within the queue.
- if (acked_event->coalesced_event().event.GetType() !=
- WebInputEvent::kTouchScrollStarted) {
- acked_event->DispatchAckToClient(ack_result, optional_latency_info,
- client_);
- }
-
- touch_queue_.pop_front();
-}
-
-void LegacyTouchEventQueue::SendTouchCancelEventForTouchEvent(
- const TouchEventWithLatencyInfo& event_to_cancel) {
- TouchEventWithLatencyInfo event = event_to_cancel;
- WebTouchEventTraits::ResetTypeAndTouchStates(
- WebInputEvent::kTouchCancel,
- // TODO(rbyers): Shouldn't we use a fresh timestamp?
- event.event.TimeStampSeconds(), &event.event);
- SendTouchEventImmediately(&event);
-}
-
-void LegacyTouchEventQueue::SendTouchEventImmediately(
- TouchEventWithLatencyInfo* touch) {
- // TODO(crbug.com/600773): Hack to avoid cyclic reentry to this method.
- if (dispatching_touch_)
- return;
-
- if (touch->event.GetType() == WebInputEvent::kTouchStart)
- touch->event.touch_start_or_first_touch_move = true;
-
- // For touchmove events, compare touch points position from current event
- // to last sent event and update touch points state.
- if (touch->event.GetType() == WebInputEvent::kTouchMove) {
- CHECK(last_sent_touchevent_);
- if (last_sent_touchevent_->GetType() == WebInputEvent::kTouchStart)
- touch->event.touch_start_or_first_touch_move = true;
- for (unsigned int i = 0; i < last_sent_touchevent_->touches_length; ++i) {
- const WebTouchPoint& last_touch_point = last_sent_touchevent_->touches[i];
- // Touches with same id may not have same index in Touches array.
- for (unsigned int j = 0; j < touch->event.touches_length; ++j) {
- const WebTouchPoint& current_touchmove_point = touch->event.touches[j];
- if (current_touchmove_point.id != last_touch_point.id)
- continue;
-
- if (!HasPointChanged(last_touch_point, current_touchmove_point))
- touch->event.touches[j].state = WebTouchPoint::kStateStationary;
-
- break;
- }
- }
- }
-
- if (touch->event.GetType() != WebInputEvent::kTouchScrollStarted) {
- if (last_sent_touchevent_)
- *last_sent_touchevent_ = touch->event;
- else
- last_sent_touchevent_.reset(new WebTouchEvent(touch->event));
- }
-
- base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true);
-
- client_->SendTouchEventImmediately(*touch);
-
- // A synchronous ack will reset |dispatching_touch_|, in which case the touch
- // timeout should not be started and the count also should not be increased.
- if (dispatching_touch_) {
- if (touch->event.GetType() == WebInputEvent::kTouchMove &&
- touch->event.dispatch_type != WebInputEvent::kBlocking) {
- // When we send out a uncancelable touch move, we increase the count and
- // we do not process input event ack any more, we will just ack to client
- // and wait for the ack from render. Also we will remove it from the front
- // of the queue.
- ack_pending_async_touchmove_ids_.push_back(
- touch->event.unique_touch_event_id);
- dispatching_touch_ = false;
- PopTouchEventToClient(INPUT_EVENT_ACK_STATE_IGNORED);
- TryForwardNextEventToRenderer();
- return;
- }
-
- if (timeout_handler_)
- timeout_handler_->StartIfNecessary(*touch);
- }
-}
-
-LegacyTouchEventQueue::PreFilterResult
-LegacyTouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) {
- if (event.GetType() == WebInputEvent::kTouchScrollStarted)
- return FORWARD_TO_RENDERER;
-
- if (WebTouchEventTraits::IsTouchSequenceStart(event)) {
- has_handler_for_current_sequence_ = false;
- send_touch_events_async_ = false;
- pending_async_touchmove_.reset();
- last_sent_touchevent_.reset();
-
- drop_remaining_touches_in_sequence_ = false;
- if (!has_handlers_) {
- drop_remaining_touches_in_sequence_ = true;
- return ACK_WITH_NO_CONSUMER_EXISTS;
- }
- }
-
- if (timeout_handler_ && timeout_handler_->FilterEvent(event))
- return ACK_WITH_NO_CONSUMER_EXISTS;
-
- if (drop_remaining_touches_in_sequence_ &&
- event.GetType() != WebInputEvent::kTouchCancel) {
- return ACK_WITH_NO_CONSUMER_EXISTS;
- }
-
- if (event.GetType() == WebInputEvent::kTouchStart) {
- return (has_handlers_ || has_handler_for_current_sequence_)
- ? FORWARD_TO_RENDERER
- : ACK_WITH_NO_CONSUMER_EXISTS;
- }
-
- if (has_handler_for_current_sequence_) {
- // Only forward a touch if it has a non-stationary pointer that is active
- // in the current touch sequence.
- for (size_t i = 0; i < event.touches_length; ++i) {
- const WebTouchPoint& point = event.touches[i];
- if (point.state == WebTouchPoint::kStateStationary)
- continue;
-
- // |last_sent_touchevent_| will be non-null as long as there is an
- // active touch sequence being forwarded to the renderer.
- if (!last_sent_touchevent_)
- continue;
-
- for (size_t j = 0; j < last_sent_touchevent_->touches_length; ++j) {
- if (point.id != last_sent_touchevent_->touches[j].id)
- continue;
-
- if (event.GetType() != WebInputEvent::kTouchMove)
- return FORWARD_TO_RENDERER;
-
- // All pointers in TouchMove events may have state as StateMoved,
- // even though none of the pointers have not changed in real.
- // Forward these events when at least one pointer has changed.
- if (HasPointChanged(last_sent_touchevent_->touches[j], point))
- return FORWARD_TO_RENDERER;
-
- // This is a TouchMove event for which we have yet to find a
- // non-stationary pointer. Continue checking the next pointers
- // in the |event|.
- break;
- }
- }
- }
-
- return ACK_WITH_NO_CONSUMER_EXISTS;
-}
-
-void LegacyTouchEventQueue::UpdateTouchConsumerStates(
- const WebTouchEvent& event,
- InputEventAckState ack_result) {
- if (event.GetType() == WebInputEvent::kTouchStart) {
- if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
- send_touch_events_async_ = false;
- has_handler_for_current_sequence_ |=
- ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
- } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) {
- has_handler_for_current_sequence_ = false;
- }
-}
-
-} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/legacy_touch_event_queue.h b/chromium/content/browser/renderer_host/input/legacy_touch_event_queue.h
deleted file mode 100644
index f18b8140845..00000000000
--- a/chromium/content/browser/renderer_host/input/legacy_touch_event_queue.h
+++ /dev/null
@@ -1,210 +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_INPUT_LEGACY_TOUCH_EVENT_QUEUE_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_LEGACY_TOUCH_EVENT_QUEUE_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <list>
-#include <memory>
-
-#include "base/containers/circular_deque.h"
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "content/browser/renderer_host/event_with_latency_info.h"
-#include "content/browser/renderer_host/input/touch_event_queue.h"
-#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
-#include "third_party/WebKit/public/platform/WebInputEvent.h"
-#include "ui/gfx/geometry/point_f.h"
-
-namespace content {
-
-class CoalescedWebTouchEvent;
-class TouchTimeoutHandler;
-
-// A queue for throttling and coalescing touch-events.
-class CONTENT_EXPORT LegacyTouchEventQueue : public TouchEventQueue {
- public:
- // The |client| must outlive the LegacyTouchEventQueue.
- LegacyTouchEventQueue(TouchEventQueueClient* client, const Config& config);
-
- ~LegacyTouchEventQueue() override;
-
- // Adds an event to the queue. The event may be coalesced with previously
- // queued events (e.g. consecutive touch-move events can be coalesced into a
- // single touch-move event). The event may also be immediately forwarded to
- // the renderer (e.g. when there are no other queued touch event).
- void QueueEvent(const TouchEventWithLatencyInfo& event) override;
-
- // Insert a TouchScrollStarted event in the queue ahead of all not-in-flight
- // events.
- void PrependTouchScrollNotification() override;
-
- // Notifies the queue that a touch-event has been processed by the renderer.
- // At this point, if the ack is for async touchmove, remove the uncancelable
- // touchmove from the front of the queue and decide if it should dispatch the
- // next pending async touch move event, otherwise the queue may send one or
- // more gesture events and/or additional queued touch-events to the renderer.
- void ProcessTouchAck(InputEventAckState ack_result,
- const ui::LatencyInfo& latency_info,
- const uint32_t unique_touch_event_id) override;
-
- // When GestureScrollBegin is received, we send a touch cancel to renderer,
- // route all the following touch events directly to client, and ignore the
- // ack for the touch cancel. When Gesture{ScrollEnd,FlingStart} is received,
- // resume the normal flow of sending touch events to the renderer.
- void OnGestureScrollEvent(
- const GestureEventWithLatencyInfo& gesture_event) override;
-
- void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
- InputEventAckState ack_result) override;
-
- // Notifies the queue whether the renderer has at least one touch handler.
- void OnHasTouchEventHandlers(bool has_handlers) override;
-
- // Returns whether the currently pending touch event (waiting ACK) is for
- // a touch start event.
- bool IsPendingAckTouchStart() const override;
-
- // Sets whether a delayed touch ack will cancel and flush the current
- // touch sequence. Note that, if the timeout was previously disabled, enabling
- // it will take effect only for the following touch sequence.
- void SetAckTimeoutEnabled(bool enabled) override;
-
- // Sets whether the current site has a mobile friendly viewport. This
- // determines which ack timeout delay will be used for *future* touch events.
- // The default assumption is that the site is *not* mobile-optimized.
- void SetIsMobileOptimizedSite(bool mobile_optimized_site) override;
-
- // Whether ack timeout behavior is supported and enabled for the current site.
- bool IsAckTimeoutEnabled() const override;
-
- bool Empty() const override;
-
- bool empty() const WARN_UNUSED_RESULT { return Empty(); }
-
- size_t size() const { return touch_queue_.size(); }
-
- bool has_handlers() const { return has_handlers_; }
-
- size_t uncancelable_touch_moves_pending_ack_count() const {
- return ack_pending_async_touchmove_ids_.size();
- }
-
- private:
- friend class LegacyTouchEventQueueTest;
-
- bool HasPendingAsyncTouchMoveForTesting() const;
- bool IsTimeoutRunningForTesting() const;
- const TouchEventWithLatencyInfo& GetLatestEventForTesting() const;
-
- // Empties the queue of touch events. This may result in any number of gesture
- // events being sent to the renderer.
- void FlushQueue() override;
-
- // Walks the queue, checking each event with |FilterBeforeForwarding()|.
- // If allowed, forwards the touch event and stops processing further events.
- // Otherwise, acks the event with |INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS|.
- void TryForwardNextEventToRenderer();
-
- // Forwards the event at the head of the queue to the renderer.
- void ForwardNextEventToRenderer();
-
- // Pops the touch-event from the head of the queue and acks it to the client.
- void PopTouchEventToClient(InputEventAckState ack_result);
-
- // Pops the touch-event from the top of the queue and acks it to the client,
- // updating the event with |renderer_latency_info|.
- void PopTouchEventToClient(InputEventAckState ack_result,
- const ui::LatencyInfo& renderer_latency_info);
-
- // Ack all coalesced events at the head of the queue to the client with
- // |ack_result|, updating the acked events with |optional_latency_info| if it
- // exists, and popping the head of the queue.
- void AckTouchEventToClient(InputEventAckState ack_result,
- const ui::LatencyInfo* optional_latency_info);
-
- // Dispatch a touch cancel event for the |event_to_cancel|.
- void SendTouchCancelEventForTouchEvent(
- const TouchEventWithLatencyInfo& event_to_cancel) override;
-
- // Dispatch |touch| to the client. Before dispatching, updates pointer
- // states in touchmove events for pointers that have not changed position.
- void SendTouchEventImmediately(TouchEventWithLatencyInfo* touch);
-
- enum PreFilterResult {
- ACK_WITH_NO_CONSUMER_EXISTS,
- ACK_WITH_NOT_CONSUMED,
- FORWARD_TO_RENDERER,
- };
- // Filter touches prior to forwarding to the renderer, e.g., if the renderer
- // has no touch handler.
- PreFilterResult FilterBeforeForwarding(const blink::WebTouchEvent& event);
- void ForwardToRenderer(const TouchEventWithLatencyInfo& event);
- void UpdateTouchConsumerStates(const blink::WebTouchEvent& event,
- InputEventAckState ack_result) override;
- void FlushPendingAsyncTouchmove();
-
- // Handles touch event forwarding and ack'ed event dispatch.
- TouchEventQueueClient* client_;
-
- std::list<std::unique_ptr<CoalescedWebTouchEvent>> touch_queue_;
-
- // Used to defer touch forwarding when ack dispatch triggers |QueueEvent()|.
- // True within the scope of |AckTouchEventToClient()|.
- bool dispatching_touch_ack_;
-
- // Used to prevent touch timeout scheduling and increase the count for async
- // touchmove if we receive a synchronous ack after forwarding a touch event
- // to the client.
- bool dispatching_touch_;
-
- // Whether the renderer has at least one touch handler.
- bool has_handlers_;
-
- // Whether any pointer in the touch sequence reported having a consumer.
- bool has_handler_for_current_sequence_;
-
- // Whether to allow any remaining touches for the current sequence. Note that
- // this is a stricter condition than an empty |touch_consumer_states_|, as it
- // also prevents forwarding of touchstart events for new pointers in the
- // current sequence. This is only used when the event is synthetically
- // cancelled after a touch timeout.
- bool drop_remaining_touches_in_sequence_;
-
- // Optional handler for timed-out touch event acks.
- std::unique_ptr<TouchTimeoutHandler> timeout_handler_;
-
- // Whether touch events should remain buffered and dispatched asynchronously
- // while a scroll sequence is active. In this mode, touchmove's are throttled
- // and ack'ed immediately, but remain buffered in |pending_async_touchmove_|
- // until a sufficient time period has elapsed since the last sent touch event.
- // For details see the design doc at http://goo.gl/lVyJAa.
- bool send_touch_events_async_;
- std::unique_ptr<TouchEventWithLatencyInfo> pending_async_touchmove_;
-
- // For uncancelable touch moves, not only we send a fake ack, but also a real
- // ack from render, which we use to decide when to send the next async
- // touchmove. This can help avoid the touch event queue keep growing when
- // render handles touchmove slow. We use a queue
- // ack_pending_async_touchmove_ids to store the recent dispatched
- // uncancelable touchmoves which are still waiting for their acks back from
- // render. We do not put them back to the front the touch_event_queue any
- // more.
- base::circular_deque<uint32_t> ack_pending_async_touchmove_ids_;
-
- double last_sent_touch_timestamp_sec_;
-
- // Event is saved to compare pointer positions for new touchmove events.
- std::unique_ptr<blink::WebTouchEvent> last_sent_touchevent_;
-
- DISALLOW_COPY_AND_ASSIGN(LegacyTouchEventQueue);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_LEGACY_TOUCH_EVENT_QUEUE_H_
diff --git a/chromium/content/browser/renderer_host/input/legacy_touch_event_queue_unittest.cc b/chromium/content/browser/renderer_host/input/legacy_touch_event_queue_unittest.cc
deleted file mode 100644
index 08bf421f265..00000000000
--- a/chromium/content/browser/renderer_host/input/legacy_touch_event_queue_unittest.cc
+++ /dev/null
@@ -1,2680 +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/input/legacy_touch_event_queue.h"
-
-#include <stddef.h>
-
-#include <memory>
-#include <utility>
-
-#include "base/containers/circular_deque.h"
-#include "base/location.h"
-#include "base/logging.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 "content/browser/renderer_host/input/timeout_monitor.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"
-#include "third_party/WebKit/public/platform/WebInputEvent.h"
-#include "ui/events/base_event_utils.h"
-
-using blink::WebGestureEvent;
-using blink::WebInputEvent;
-using blink::WebTouchEvent;
-using blink::WebTouchPoint;
-
-namespace content {
-namespace {
-
-const double kMinSecondsBetweenThrottledTouchmoves = 0.2;
-const float kSlopLengthDips = 10;
-const float kHalfSlopLengthDips = kSlopLengthDips / 2;
-
-base::TimeDelta DefaultTouchTimeoutDelay() {
- return base::TimeDelta::FromMilliseconds(1);
-}
-} // namespace
-
-class LegacyTouchEventQueueTest : public testing::Test,
- public TouchEventQueueClient {
- public:
- LegacyTouchEventQueueTest()
- : scoped_task_environment_(
- base::test::ScopedTaskEnvironment::MainThreadType::UI),
- acked_event_count_(0),
- last_acked_event_state_(INPUT_EVENT_ACK_STATE_UNKNOWN),
- slop_length_dips_(0) {}
-
- ~LegacyTouchEventQueueTest() override {}
-
- // testing::Test
- void SetUp() override {
- ResetQueueWithConfig(TouchEventQueue::Config());
- sent_events_ids_.clear();
- }
-
- void TearDown() override { queue_.reset(); }
-
- // TouchEventQueueClient
- void SendTouchEventImmediately(
- const TouchEventWithLatencyInfo& event) override {
- sent_events_.push_back(event.event);
- sent_events_ids_.push_back(event.event.unique_touch_event_id);
- if (sync_ack_result_) {
- auto sync_ack_result = std::move(sync_ack_result_);
- SendTouchEventAck(*sync_ack_result);
- }
- }
-
- void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
- InputEventAckState ack_result) override {
- ++acked_event_count_;
- last_acked_event_ = event.event;
- last_acked_event_state_ = ack_result;
- if (followup_touch_event_) {
- std::unique_ptr<WebTouchEvent> followup_touch_event =
- std::move(followup_touch_event_);
- SendTouchEvent(*followup_touch_event);
- }
- if (followup_gesture_event_) {
- std::unique_ptr<WebGestureEvent> followup_gesture_event =
- std::move(followup_gesture_event_);
- queue_->OnGestureScrollEvent(GestureEventWithLatencyInfo(
- *followup_gesture_event, ui::LatencyInfo()));
- }
- }
-
- void OnFilteringTouchEvent(const blink::WebTouchEvent& touch_event) override {
- }
-
- protected:
- void SetUpForTouchMoveSlopTesting(double slop_length_dips) {
- slop_length_dips_ = slop_length_dips;
- }
-
- void SetUpForTimeoutTesting(base::TimeDelta desktop_timeout_delay,
- base::TimeDelta mobile_timeout_delay) {
- TouchEventQueue::Config config;
- config.desktop_touch_ack_timeout_delay = desktop_timeout_delay;
- config.mobile_touch_ack_timeout_delay = mobile_timeout_delay;
- config.touch_ack_timeout_supported = true;
- ResetQueueWithConfig(config);
- }
-
- void SetUpForTimeoutTesting() {
- SetUpForTimeoutTesting(DefaultTouchTimeoutDelay(),
- DefaultTouchTimeoutDelay());
- }
-
- void SendTouchEvent(WebTouchEvent event) {
- if (slop_length_dips_) {
- event.moved_beyond_slop_region = false;
- if (WebTouchEventTraits::IsTouchSequenceStart(event))
- anchor_ = event.touches[0].PositionInWidget();
- if (event.GetType() == WebInputEvent::kTouchMove) {
- gfx::Vector2dF delta = anchor_ - event.touches[0].PositionInWidget();
- if (delta.LengthSquared() > slop_length_dips_ * slop_length_dips_)
- event.moved_beyond_slop_region = true;
- }
- } else {
- event.moved_beyond_slop_region =
- event.GetType() == WebInputEvent::kTouchMove;
- }
- queue_->QueueEvent(TouchEventWithLatencyInfo(event, ui::LatencyInfo()));
- }
-
- void SendGestureEvent(WebInputEvent::Type type) {
- WebGestureEvent event(type, WebInputEvent::kNoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- queue_->OnGestureScrollEvent(
- GestureEventWithLatencyInfo(event, ui::LatencyInfo()));
- }
-
- void SendTouchEventAck(InputEventAckState ack_result) {
- DCHECK(!sent_events_ids_.empty());
- queue_->ProcessTouchAck(ack_result, ui::LatencyInfo(),
- sent_events_ids_.front());
- sent_events_ids_.pop_front();
- }
-
- void SendTouchEventAckWithID(InputEventAckState ack_result,
- int unique_event_id) {
- queue_->ProcessTouchAck(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());
- }
-
- void SendGestureEventAck(WebInputEvent::Type type,
- InputEventAckState ack_result) {
- GestureEventWithLatencyInfo event(
- type, blink::WebInputEvent::kNoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()), ui::LatencyInfo());
- queue_->OnGestureEventAck(event, ack_result);
- }
-
- void SetFollowupEvent(const WebTouchEvent& event) {
- followup_touch_event_.reset(new WebTouchEvent(event));
- }
-
- void SetFollowupEvent(const WebGestureEvent& event) {
- followup_gesture_event_.reset(new WebGestureEvent(event));
- }
-
- void SetSyncAckResult(InputEventAckState sync_ack_result) {
- sync_ack_result_.reset(new InputEventAckState(sync_ack_result));
- }
-
- void PressTouchPoint(float x, float y) {
- touch_event_.PressPoint(x, y);
- SendTouchEvent();
- }
-
- void MoveTouchPoint(int index, float x, float y) {
- touch_event_.MovePoint(index, x, y);
- SendTouchEvent();
- }
-
- void MoveTouchPoints(int index0,
- float x0,
- float y0,
- int index1,
- float x1,
- float y1) {
- touch_event_.MovePoint(index0, x0, y0);
- touch_event_.MovePoint(index1, x1, y1);
- SendTouchEvent();
- }
-
- void ChangeTouchPointRadius(int index, float radius_x, float radius_y) {
- CHECK_GE(index, 0);
- CHECK_LT(index, touch_event_.kTouchesLengthCap);
- WebTouchPoint& point = touch_event_.touches[index];
- point.radius_x = radius_x;
- point.radius_y = radius_y;
- touch_event_.touches[index].state = WebTouchPoint::kStateMoved;
- touch_event_.moved_beyond_slop_region = true;
- WebTouchEventTraits::ResetType(WebInputEvent::kTouchMove,
- touch_event_.TimeStampSeconds(),
- &touch_event_);
- SendTouchEvent();
- }
-
- void ChangeTouchPointRotationAngle(int index, float rotation_angle) {
- CHECK_GE(index, 0);
- CHECK_LT(index, touch_event_.kTouchesLengthCap);
- WebTouchPoint& point = touch_event_.touches[index];
- point.rotation_angle = rotation_angle;
- touch_event_.touches[index].state = WebTouchPoint::kStateMoved;
- touch_event_.moved_beyond_slop_region = true;
- WebTouchEventTraits::ResetType(WebInputEvent::kTouchMove,
- touch_event_.TimeStampSeconds(),
- &touch_event_);
- SendTouchEvent();
- }
-
- void ChangeTouchPointForce(int index, float force) {
- CHECK_GE(index, 0);
- CHECK_LT(index, touch_event_.kTouchesLengthCap);
- WebTouchPoint& point = touch_event_.touches[index];
- point.force = force;
- touch_event_.touches[index].state = WebTouchPoint::kStateMoved;
- touch_event_.moved_beyond_slop_region = true;
- WebTouchEventTraits::ResetType(WebInputEvent::kTouchMove,
- touch_event_.TimeStampSeconds(),
- &touch_event_);
- SendTouchEvent();
- }
-
- void ReleaseTouchPoint(int index) {
- touch_event_.ReleasePoint(index);
- SendTouchEvent();
- }
-
- void CancelTouchPoint(int index) {
- touch_event_.CancelPoint(index);
- SendTouchEvent();
- }
-
- void PrependTouchScrollNotification() {
- queue_->PrependTouchScrollNotification();
- }
-
- void AdvanceTouchTime(double seconds) {
- touch_event_.SetTimeStampSeconds(touch_event_.TimeStampSeconds() + seconds);
- }
-
- void ResetTouchEvent() { touch_event_ = SyntheticWebTouchEvent(); }
-
- size_t GetAndResetAckedEventCount() {
- size_t count = acked_event_count_;
- acked_event_count_ = 0;
- return count;
- }
-
- size_t GetAndResetSentEventCount() {
- size_t count = sent_events_.size();
- sent_events_.clear();
- return count;
- }
-
- bool IsPendingAckTouchStart() const {
- return queue_->IsPendingAckTouchStart();
- }
-
- void OnHasTouchEventHandlers(bool has_handlers) {
- queue_->OnHasTouchEventHandlers(has_handlers);
- }
-
- void SetAckTimeoutDisabled() { queue_->SetAckTimeoutEnabled(false); }
-
- void SetIsMobileOptimizedSite(bool is_mobile_optimized) {
- queue_->SetIsMobileOptimizedSite(is_mobile_optimized);
- }
-
- bool IsTimeoutRunning() const { return queue_->IsTimeoutRunningForTesting(); }
-
- bool HasPendingAsyncTouchMove() const {
- return queue_->HasPendingAsyncTouchMoveForTesting();
- }
-
- size_t queued_event_count() const { return queue_->size(); }
-
- const WebTouchEvent& latest_event() const {
- return queue_->GetLatestEventForTesting().event;
- }
-
- const WebTouchEvent& acked_event() const { return last_acked_event_; }
-
- const WebTouchEvent& sent_event() const {
- DCHECK(!sent_events_.empty());
- return sent_events_.back();
- }
-
- const std::vector<WebTouchEvent>& all_sent_events() const {
- return sent_events_;
- }
-
- InputEventAckState acked_event_state() const {
- return last_acked_event_state_;
- }
-
- static void RunTasksAndWait(base::TimeDelta delay) {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), delay);
- base::RunLoop().Run();
- }
-
- size_t uncancelable_touch_moves_pending_ack_count() const {
- return queue_->uncancelable_touch_moves_pending_ack_count();
- }
-
- int GetUniqueTouchEventID() { return sent_events_ids_.back(); }
-
- private:
- void SendTouchEvent() {
- SendTouchEvent(touch_event_);
- touch_event_.ResetPoints();
- }
-
- void ResetQueueWithConfig(const TouchEventQueue::Config& config) {
- queue_.reset(new LegacyTouchEventQueue(this, config));
- queue_->OnHasTouchEventHandlers(true);
- }
-
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- std::unique_ptr<LegacyTouchEventQueue> queue_;
- size_t acked_event_count_;
- WebTouchEvent last_acked_event_;
- std::vector<WebTouchEvent> sent_events_;
- InputEventAckState last_acked_event_state_;
- SyntheticWebTouchEvent touch_event_;
- std::unique_ptr<WebTouchEvent> followup_touch_event_;
- std::unique_ptr<WebGestureEvent> followup_gesture_event_;
- std::unique_ptr<InputEventAckState> sync_ack_result_;
- double slop_length_dips_;
- gfx::PointF anchor_;
- base::circular_deque<int> sent_events_ids_;
-};
-
-// Tests that touch-events are queued properly.
-TEST_F(LegacyTouchEventQueueTest, Basic) {
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // The second touch should not be sent since one is already in queue.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Receive an ACK for the first touch-event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::kTouchStart, acked_event().GetType());
- EXPECT_EQ(WebInputEvent::kBlocking, acked_event().dispatch_type);
-
- // Receive an ACK for the second touch-event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::kTouchMove, acked_event().GetType());
- EXPECT_EQ(WebInputEvent::kBlocking, acked_event().dispatch_type);
-}
-
-// Tests that touch-events with multiple points are queued properly.
-TEST_F(LegacyTouchEventQueueTest, BasicMultiTouch) {
- const size_t kPointerCount = 10;
- for (float i = 0; i < kPointerCount; ++i)
- PressTouchPoint(i, i);
-
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(kPointerCount, queued_event_count());
-
- for (int i = 0; i < static_cast<int>(kPointerCount); ++i)
- MoveTouchPoint(i, 1.f + i, 2.f + i);
-
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- // All moves should coalesce.
- EXPECT_EQ(kPointerCount + 1, queued_event_count());
-
- for (int i = 0; i < static_cast<int>(kPointerCount); ++i)
- ReleaseTouchPoint(kPointerCount - 1 - i);
-
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(kPointerCount * 2 + 1, queued_event_count());
-
- // Ack all presses.
- for (size_t i = 0; i < kPointerCount; ++i)
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(kPointerCount, GetAndResetAckedEventCount());
- EXPECT_EQ(kPointerCount, GetAndResetSentEventCount());
-
- // Ack the coalesced move.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(kPointerCount, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Ack all releases.
- for (size_t i = 0; i < kPointerCount; ++i)
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(kPointerCount, GetAndResetAckedEventCount());
- EXPECT_EQ(kPointerCount - 1, GetAndResetSentEventCount());
-}
-
-// Tests that the touch-queue continues delivering events for an active touch
-// sequence after all handlers are removed.
-TEST_F(LegacyTouchEventQueueTest,
- TouchesForwardedIfHandlerRemovedDuringSequence) {
- OnHasTouchEventHandlers(true);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Send a touch-press event.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Signal that all touch handlers have been removed.
- OnHasTouchEventHandlers(false);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Process the ack for the sent touch, ensuring that it is honored (despite
- // the touch handler having been removed).
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
-
- // Try forwarding a new pointer. It should be forwarded as usual.
- PressTouchPoint(2, 2);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- // Further events for any pointer should be forwarded, even for pointers that
- // reported no consumer.
- MoveTouchPoint(1, 3, 3);
- ReleaseTouchPoint(1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Events for the first pointer, that had a handler, should be forwarded.
- MoveTouchPoint(0, 4, 4);
- ReleaseTouchPoint(0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
-}
-
-// Tests that addition of a touch handler during a touch sequence will not cause
-// the remaining sequence to be forwarded.
-TEST_F(LegacyTouchEventQueueTest, ActiveSequenceNotForwardedWhenHandlersAdded) {
- OnHasTouchEventHandlers(false);
-
- // Send a touch-press event while there is no handler.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- OnHasTouchEventHandlers(true);
-
- // The remaining touch sequence should not be forwarded.
- MoveTouchPoint(0, 5, 5);
- ReleaseTouchPoint(0);
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- // A new touch sequence should resume forwarding.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-}
-
-// Tests that removal of a touch handler during a touch sequence will prevent
-// the remaining sequence from being forwarded, even if another touch handler is
-// registered during the same touch sequence.
-TEST_F(LegacyTouchEventQueueTest, ActiveSequenceDroppedWhenHandlersRemoved) {
- // Send a touch-press event.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Queue a touch-move event.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Unregister all touch handlers.
- OnHasTouchEventHandlers(false);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- // Repeated registration/unregstration of handlers should have no effect as
- // we're still awaiting the ack arrival.
- OnHasTouchEventHandlers(true);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(2U, queued_event_count());
- OnHasTouchEventHandlers(false);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- // The ack should be flush the queue.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- // Events should be dropped while there is no touch handler.
- MoveTouchPoint(0, 10, 10);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Simulate touch handler registration in the middle of a touch sequence.
- OnHasTouchEventHandlers(true);
-
- // The touch end for the interrupted sequence should be dropped.
- ReleaseTouchPoint(0);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // A new touch sequence should be forwarded properly.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-}
-
-// Tests that removal/addition of a touch handler without any intervening
-// touch activity has no affect on touch forwarding.
-TEST_F(LegacyTouchEventQueueTest,
- ActiveSequenceUnaffectedByRepeatedHandlerRemovalAndAddition) {
- // Send a touch-press event.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Simulate the case where the touchstart handler removes itself, and adds a
- // touchmove handler.
- OnHasTouchEventHandlers(false);
- OnHasTouchEventHandlers(true);
-
- // Queue a touch-move event.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // The ack should trigger forwarding of the touchmove, as if no touch
- // handler registration changes have occurred.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
-}
-
-// Tests that touch-events are coalesced properly in the queue.
-TEST_F(LegacyTouchEventQueueTest, Coalesce) {
- // Send a touch-press event.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Send a few touch-move events, followed by a touch-release event. All the
- // touch-move events should be coalesced into a single event.
- for (float i = 5; i < 15; ++i)
- MoveTouchPoint(0, i, i);
-
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- ReleaseTouchPoint(0);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(3U, queued_event_count());
-
- // ACK the press. Coalesced touch-move events should be sent.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::kTouchStart, acked_event().GetType());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
-
- // ACK the moves.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(10U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::kTouchMove, acked_event().GetType());
-
- // ACK the release.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::kTouchEnd, acked_event().GetType());
-}
-
-// Tests that an event that has already been sent but hasn't been ack'ed yet
-// doesn't get coalesced with newer events.
-TEST_F(LegacyTouchEventQueueTest, SentTouchEventDoesNotCoalesce) {
- // Send a touch-press event.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Send a few touch-move events, followed by a touch-release event. All the
- // touch-move events should be coalesced into a single event.
- for (float i = 5; i < 15; ++i)
- MoveTouchPoint(0, i, i);
-
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // The coalesced touch-move event has been sent to the renderer. Any new
- // touch-move event should not be coalesced with the sent event.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
-
- MoveTouchPoint(0, 7, 7);
- EXPECT_EQ(2U, queued_event_count());
-}
-
-// Tests that coalescing works correctly for multi-touch events.
-TEST_F(LegacyTouchEventQueueTest, MultiTouch) {
- // Press the first finger.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Move the finger.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
-
- // Now press a second finger.
- PressTouchPoint(2, 2);
- EXPECT_EQ(3U, queued_event_count());
-
- // Move both fingers.
- MoveTouchPoints(0, 10, 10, 1, 20, 20);
- MoveTouchPoint(1, 20, 20);
- EXPECT_EQ(4U, queued_event_count());
-
- // Move only one finger now.
- MoveTouchPoint(0, 15, 15);
- EXPECT_EQ(4U, queued_event_count());
-
- // Move the other finger.
- MoveTouchPoint(1, 25, 25);
- EXPECT_EQ(4U, queued_event_count());
-
- // Make sure both fingers are marked as having been moved in the coalesced
- // event.
- const WebTouchEvent& event = latest_event();
- EXPECT_EQ(WebTouchPoint::kStateMoved, event.touches[0].state);
- EXPECT_EQ(WebTouchPoint::kStateMoved, event.touches[1].state);
-}
-
-// Tests that the touch-event queue is robust to redundant acks.
-TEST_F(LegacyTouchEventQueueTest, SpuriousAcksIgnored) {
- // Trigger a spurious ack.
- SendTouchEventAckWithID(INPUT_EVENT_ACK_STATE_CONSUMED, 0);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Send and ack a touch press.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- // Trigger a spurious ack.
- SendTouchEventAckWithID(INPUT_EVENT_ACK_STATE_CONSUMED, 3);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that touch-move events are not sent to the renderer if the preceding
-// touch-press event did not have a consumer (and consequently, did not hit the
-// main thread in the renderer). Also tests that all queued/coalesced touch
-// events are flushed immediately when the ACK for the touch-press comes back
-// with NO_CONSUMER status.
-TEST_F(LegacyTouchEventQueueTest, NoConsumer) {
- // The first touch-press should reach the renderer.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // The second touch should not be sent since one is already in queue.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- // Receive an ACK for the first touch-event. This should release the queued
- // touch-event, but it should not be sent to the renderer.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::kTouchMove, acked_event().GetType());
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Send a release event. This should not reach the renderer.
- ReleaseTouchPoint(0);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(WebInputEvent::kTouchEnd, acked_event().GetType());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Send a press-event, followed by move and release events, and another press
- // event, before the ACK for the first press event comes back. All of the
- // events should be queued first. After the NO_CONSUMER ack for the first
- // touch-press, all events upto the second touch-press should be flushed.
- PressTouchPoint(10, 10);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- MoveTouchPoint(0, 5, 5);
- MoveTouchPoint(0, 6, 5);
- ReleaseTouchPoint(0);
-
- PressTouchPoint(6, 5);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- // The queue should hold the first sent touch-press event, the coalesced
- // touch-move event, the touch-end event and the second touch-press event.
- EXPECT_EQ(4U, queued_event_count());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(WebInputEvent::kTouchEnd, acked_event().GetType());
- EXPECT_EQ(4U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // ACK the second press event as NO_CONSUMER too.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(WebInputEvent::kTouchStart, acked_event().GetType());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- // Send a second press event. Even though the first touch press had
- // NO_CONSUMER, this press event should reach the renderer.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::kTouchStart, acked_event().GetType());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-TEST_F(LegacyTouchEventQueueTest, ConsumerIgnoreMultiFinger) {
- // Interleave three pointer press, move and release events.
- PressTouchPoint(1, 1);
- MoveTouchPoint(0, 5, 5);
- PressTouchPoint(10, 10);
- MoveTouchPoint(1, 15, 15);
- PressTouchPoint(20, 20);
- MoveTouchPoint(2, 25, 25);
- ReleaseTouchPoint(2);
- MoveTouchPoint(1, 20, 20);
- ReleaseTouchPoint(1);
- MoveTouchPoint(0, 10, 10);
- ReleaseTouchPoint(0);
-
- // Since the first touch-press is still pending ACK, no other event should
- // have been sent to the renderer.
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(11U, queued_event_count());
-
- // ACK the first press as CONSUMED. This should cause the first touch-move of
- // the first touch-point to be dispatched.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(10U, queued_event_count());
-
- // ACK the first move as CONSUMED.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(9U, queued_event_count());
-
- // ACK the second press as NO_CONSUMER_EXISTS. The second pointer's touchmove
- // should still be forwarded, despite lacking a direct consumer.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(8U, queued_event_count());
-
- // ACK the coalesced move as NOT_CONSUMED.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(7U, queued_event_count());
-
- // All remaining touch events should be forwarded, even if the third pointer
- // press also reports no consumer.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(6U, queued_event_count());
-
- while (queued_event_count())
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- EXPECT_EQ(6U, GetAndResetSentEventCount());
-}
-
-// Tests that touch-event's enqueued via a touch ack are properly handled.
-TEST_F(LegacyTouchEventQueueTest, AckWithFollowupEvents) {
- // Queue a touch down.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Create a touch event that will be queued synchronously by a touch ack.
- // Note, this will be triggered by all subsequent touch acks.
- WebTouchEvent followup_event(
- WebInputEvent::kTouchMove, WebInputEvent::kNoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- followup_event.touches_length = 1;
- followup_event.touches[0].id = 0;
- followup_event.touches[0].state = WebTouchPoint::kStateMoved;
- SetFollowupEvent(followup_event);
-
- // Receive an ACK for the press. This should cause the followup touch-move to
- // be sent to the renderer.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
- EXPECT_EQ(WebInputEvent::kTouchStart, acked_event().GetType());
-
- // Queue another event.
- MoveTouchPoint(0, 2, 2);
- EXPECT_EQ(2U, queued_event_count());
-
- // Receive an ACK for the touch-move followup event. This should cause the
- // subsequent touch move event be sent to the renderer.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that touch-events can be synchronously ack'ed.
-TEST_F(LegacyTouchEventQueueTest, SynchronousAcks) {
- // TouchStart
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- PressTouchPoint(1, 1);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchMove
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- MoveTouchPoint(0, 2, 2);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchEnd
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- ReleaseTouchPoint(0);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchCancel (first inserting a TouchStart so the TouchCancel will be sent)
- PressTouchPoint(1, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- CancelTouchPoint(0);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that followup events triggered by an immediate ack from
-// TouchEventQueue::QueueEvent() are properly handled.
-TEST_F(LegacyTouchEventQueueTest, ImmediateAckWithFollowupEvents) {
- // Create a touch event that will be queued synchronously by a touch ack.
- WebTouchEvent followup_event(
- WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- followup_event.touches_length = 1;
- followup_event.touches[0].id = 1;
- followup_event.touches[0].state = WebTouchPoint::kStatePressed;
- SetFollowupEvent(followup_event);
-
- // Now, enqueue a stationary touch that will not be forwarded. This should be
- // immediately ack'ed with "NO_CONSUMER_EXISTS". The followup event should
- // then be enqueued and immediately sent to the renderer.
- WebTouchEvent stationary_event(
- WebInputEvent::kTouchMove, WebInputEvent::kNoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- ;
- stationary_event.touches_length = 1;
- stationary_event.touches[0].id = 1;
- stationary_event.touches[0].state = WebTouchPoint::kStateStationary;
- SendTouchEvent(stationary_event);
-
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state());
- EXPECT_EQ(WebInputEvent::kTouchMove, acked_event().GetType());
-}
-
-// Tests basic TouchEvent forwarding suppression.
-TEST_F(LegacyTouchEventQueueTest, NoTouchBasic) {
- // Disable TouchEvent forwarding.
- OnHasTouchEventHandlers(false);
- PressTouchPoint(30, 5);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchMove should not be sent to renderer.
- MoveTouchPoint(0, 65, 10);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchEnd should not be sent to renderer.
- ReleaseTouchPoint(0);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Enable TouchEvent forwarding.
- OnHasTouchEventHandlers(true);
-
- PressTouchPoint(80, 10);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 80, 20);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- ReleaseTouchPoint(0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that IsTouchStartPendingAck works correctly.
-TEST_F(LegacyTouchEventQueueTest, PendingStart) {
- EXPECT_FALSE(IsPendingAckTouchStart());
-
- // Send the touchstart for one point (#1).
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_TRUE(IsPendingAckTouchStart());
-
- // Send a touchmove for that point (#2).
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_TRUE(IsPendingAckTouchStart());
-
- // Ack the touchstart (#1).
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_FALSE(IsPendingAckTouchStart());
-
- // Send a touchstart for another point (#3).
- PressTouchPoint(10, 10);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_FALSE(IsPendingAckTouchStart());
-
- // Ack the touchmove (#2).
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_TRUE(IsPendingAckTouchStart());
-
- // Send a touchstart for a third point (#4).
- PressTouchPoint(15, 15);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_TRUE(IsPendingAckTouchStart());
-
- // Ack the touchstart for the second point (#3).
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_TRUE(IsPendingAckTouchStart());
-
- // Ack the touchstart for the third point (#4).
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_FALSE(IsPendingAckTouchStart());
-}
-
-// Tests that the touch timeout is started when sending certain touch types.
-TEST_F(LegacyTouchEventQueueTest, TouchTimeoutTypes) {
- SetUpForTimeoutTesting();
-
- // Sending a TouchStart will start the timeout.
- PressTouchPoint(0, 1);
- EXPECT_TRUE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
-
- // A TouchMove should start the timeout.
- MoveTouchPoint(0, 5, 5);
- EXPECT_TRUE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
-
- // A TouchEnd should not start the timeout.
- ReleaseTouchPoint(0);
- EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
-
- // A TouchCancel should not start the timeout.
- PressTouchPoint(0, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ASSERT_FALSE(IsTimeoutRunning());
- CancelTouchPoint(0);
- EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
-}
-
-// Tests that a delayed TouchEvent ack will trigger a TouchCancel timeout,
-// disabling touch forwarding until the next TouchStart is received after
-// the timeout events are ack'ed.
-TEST_F(LegacyTouchEventQueueTest, TouchTimeoutBasic) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- GetAndResetSentEventCount();
- GetAndResetAckedEventCount();
- PressTouchPoint(0, 1);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_TRUE(IsTimeoutRunning());
-
- // Delay the ack.
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
-
- // The timeout should have fired, synthetically ack'ing the timed-out event.
- // TouchEvent forwarding is disabled until the ack is received for the
- // timed-out event and the future cancel event.
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Ack'ing the original event should trigger a cancel event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(WebInputEvent::kTouchCancel, sent_event().GetType());
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Touch events should not be forwarded until we receive the cancel acks.
- MoveTouchPoint(0, 1, 1);
- ASSERT_EQ(0U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- ReleaseTouchPoint(0);
- ASSERT_EQ(0U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- // The synthetic TouchCancel ack should not reach the client, but should
- // resume touch forwarding.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Subsequent events should be handled normally.
- PressTouchPoint(0, 1);
- EXPECT_EQ(WebInputEvent::kTouchStart, sent_event().GetType());
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that the timeout is never started if the renderer consumes
-// a TouchEvent from the current touch sequence.
-TEST_F(LegacyTouchEventQueueTest, NoTouchTimeoutIfRendererIsConsumingGesture) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- ASSERT_TRUE(IsTimeoutRunning());
-
- // Mark the event as consumed. This should prevent the timeout from
- // being activated on subsequent TouchEvents in this gesture.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
-
- // A TouchMove should not start the timeout.
- MoveTouchPoint(0, 5, 5);
- EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // A secondary TouchStart should not start the timeout.
- PressTouchPoint(1, 0);
- EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // A TouchEnd should not start the timeout.
- ReleaseTouchPoint(1);
- EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // A TouchCancel should not start the timeout.
- CancelTouchPoint(0);
- EXPECT_FALSE(IsTimeoutRunning());
-}
-
-// Tests that the timeout is never started if the renderer consumes
-// a TouchEvent from the current touch sequence.
-TEST_F(LegacyTouchEventQueueTest, NoTouchTimeoutIfDisabledAfterTouchStart) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- ASSERT_TRUE(IsTimeoutRunning());
-
- // Send the ack immediately. The timeout should not have fired.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now explicitly disable the timeout.
- SetAckTimeoutDisabled();
- EXPECT_FALSE(IsTimeoutRunning());
-
- // A TouchMove should not start or trigger the timeout.
- MoveTouchPoint(0, 5, 5);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that the timeout is never started if the ack is synchronous.
-TEST_F(LegacyTouchEventQueueTest, NoTouchTimeoutIfAckIsSynchronous) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- ASSERT_FALSE(IsTimeoutRunning());
- PressTouchPoint(0, 1);
- EXPECT_FALSE(IsTimeoutRunning());
-}
-
-// Tests that the timeout does not fire if explicitly disabled while an event
-// is in-flight.
-TEST_F(LegacyTouchEventQueueTest, NoTouchTimeoutIfDisabledWhileTimerIsActive) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- ASSERT_TRUE(IsTimeoutRunning());
-
- // Verify that disabling the timeout also turns off the timer.
- SetAckTimeoutDisabled();
- EXPECT_FALSE(IsTimeoutRunning());
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that the timeout does not fire if the delay is zero.
-TEST_F(LegacyTouchEventQueueTest, NoTouchTimeoutIfTimeoutDelayIsZero) {
- SetUpForTimeoutTesting(base::TimeDelta(), base::TimeDelta());
-
- // As the delay is zero, timeout behavior should be disabled.
- PressTouchPoint(0, 1);
- EXPECT_FALSE(IsTimeoutRunning());
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that timeout delays for mobile sites take effect when appropriate.
-TEST_F(LegacyTouchEventQueueTest, TouchTimeoutConfiguredForMobile) {
- base::TimeDelta desktop_delay = DefaultTouchTimeoutDelay();
- base::TimeDelta mobile_delay = base::TimeDelta();
- SetUpForTimeoutTesting(desktop_delay, mobile_delay);
-
- // The desktop delay is non-zero, allowing timeout behavior.
- SetIsMobileOptimizedSite(false);
-
- PressTouchPoint(0, 1);
- ASSERT_TRUE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- ReleaseTouchPoint(0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
- ASSERT_FALSE(IsTimeoutRunning());
-
- // The mobile delay is zero, preventing timeout behavior.
- SetIsMobileOptimizedSite(true);
-
- PressTouchPoint(0, 1);
- EXPECT_FALSE(IsTimeoutRunning());
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that a TouchCancel timeout plays nice when the timed out touch stream
-// turns into a scroll gesture sequence.
-TEST_F(LegacyTouchEventQueueTest, TouchTimeoutWithFollowupGesture) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- EXPECT_TRUE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // The cancelled sequence may turn into a scroll gesture.
- WebGestureEvent followup_scroll(
- WebInputEvent::kGestureScrollBegin, WebInputEvent::kNoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- SetFollowupEvent(followup_scroll);
-
- // Delay the ack.
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
-
- // The timeout should have fired, disabling touch forwarding until both acks
- // are received, acking the timed out event.
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Ack the original event, triggering a TouchCancel.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Ack the cancel event. Normally, this would resume touch forwarding,
- // but we're still within a scroll gesture so it remains disabled.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Try to forward touch events for the current sequence.
- GetAndResetSentEventCount();
- GetAndResetAckedEventCount();
- MoveTouchPoint(0, 1, 1);
- ReleaseTouchPoint(0);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
-
- // Now end the scroll sequence, resuming touch handling.
- SendGestureEvent(blink::WebInputEvent::kGestureScrollEnd);
- PressTouchPoint(0, 1);
- EXPECT_TRUE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that a TouchCancel timeout plays nice when the timed out touch stream
-// turns into a scroll gesture sequence, but the original event acks are
-// significantly delayed.
-TEST_F(LegacyTouchEventQueueTest,
- TouchTimeoutWithFollowupGestureAndDelayedAck) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- EXPECT_TRUE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // The cancelled sequence may turn into a scroll gesture.
- WebGestureEvent followup_scroll(
- WebInputEvent::kGestureScrollBegin, WebInputEvent::kNoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- SetFollowupEvent(followup_scroll);
-
- // Delay the ack.
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
-
- // The timeout should have fired, disabling touch forwarding until both acks
- // are received and acking the timed out event.
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Try to forward a touch event.
- GetAndResetSentEventCount();
- GetAndResetAckedEventCount();
- MoveTouchPoint(0, 1, 1);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now end the scroll sequence. Events will not be forwarded until the two
- // outstanding touch acks are received.
- SendGestureEvent(blink::WebInputEvent::kGestureScrollEnd);
- MoveTouchPoint(0, 2, 2);
- ReleaseTouchPoint(0);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
-
- // Ack the original event, triggering a cancel.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Ack the cancel event, resuming touch forwarding.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- PressTouchPoint(0, 1);
- EXPECT_TRUE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-}
-
-// Tests that a delayed TouchEvent ack will not trigger a TouchCancel timeout if
-// the timed-out event had no consumer.
-TEST_F(LegacyTouchEventQueueTest, NoCancelOnTouchTimeoutWithoutConsumer) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_TRUE(IsTimeoutRunning());
-
- // Delay the ack.
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
-
- // The timeout should have fired, synthetically ack'ing the timed out event.
- // TouchEvent forwarding is disabled until the original ack is received.
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Touch events should not be forwarded until we receive the original ack.
- MoveTouchPoint(0, 1, 1);
- ReleaseTouchPoint(0);
- ASSERT_EQ(0U, GetAndResetSentEventCount());
- ASSERT_EQ(2U, GetAndResetAckedEventCount());
-
- // Ack'ing the original event should not trigger a cancel event, as the
- // TouchStart had no consumer. However, it should re-enable touch forwarding.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Subsequent events should be handled normally.
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that TouchMove's movedBeyondSlopRegion is set to false if within the
-// boundary-inclusive slop region for an unconsumed TouchStart.
-TEST_F(LegacyTouchEventQueueTest, TouchMovedBeyondSlopRegionCheck) {
- SetUpForTouchMoveSlopTesting(kSlopLengthDips);
-
- // Queue a TouchStart.
- PressTouchPoint(0, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchMove's movedBeyondSlopRegion within the slop region is set to false.
- MoveTouchPoint(0, 0, kHalfSlopLengthDips);
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(acked_event().moved_beyond_slop_region);
-
- MoveTouchPoint(0, kHalfSlopLengthDips, 0);
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(acked_event().moved_beyond_slop_region);
-
- MoveTouchPoint(0, -kHalfSlopLengthDips, 0);
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(acked_event().moved_beyond_slop_region);
-
- MoveTouchPoint(0, -kSlopLengthDips, 0);
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(acked_event().moved_beyond_slop_region);
-
- MoveTouchPoint(0, 0, kSlopLengthDips);
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(acked_event().moved_beyond_slop_region);
-
- // When a TouchMove exceeds the (Euclidean) distance, the TouchMove's
- // movedBeyondSlopRegion is set to true.
- const float kFortyFiveDegreeSlopLengthXY =
- kSlopLengthDips * std::sqrt(2.f) / 2;
- MoveTouchPoint(0, kFortyFiveDegreeSlopLengthXY + .2f,
- kFortyFiveDegreeSlopLengthXY + .2f);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_TRUE(acked_event().moved_beyond_slop_region);
-}
-
-// Tests that even very small TouchMove's movedBeyondSlopRegion is set to true
-// when the slop region's dimension is 0.
-TEST_F(LegacyTouchEventQueueTest,
- MovedBeyondSlopRegionAlwaysTrueIfDimensionZero) {
- // Queue a TouchStart.
- PressTouchPoint(0, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- // Small TouchMove's movedBeyondSlopRegion is set to true.
- MoveTouchPoint(0, 0.001f, 0.001f);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_TRUE(acked_event().moved_beyond_slop_region);
-}
-
-// Tests that secondary touch points can be forwarded even if the primary touch
-// point had no consumer.
-TEST_F(LegacyTouchEventQueueTest,
- SecondaryTouchForwardedAfterPrimaryHadNoConsumer) {
- // Queue a TouchStart.
- PressTouchPoint(0, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- // Events should not be forwarded, as the point had no consumer.
- MoveTouchPoint(0, 0, 15);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Simulate a secondary pointer press.
- PressTouchPoint(20, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchMove with a secondary pointer should not be suppressed.
- MoveTouchPoint(1, 25, 0);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that secondary touch points can be forwarded after scrolling begins
-// while first touch point has no consumer.
-TEST_F(LegacyTouchEventQueueTest, NoForwardingAfterScrollWithNoTouchConsumers) {
- // Queue a TouchStart.
- PressTouchPoint(0, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- MoveTouchPoint(0, 20, 5);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state());
-
- // The secondary pointer press should be forwarded.
- PressTouchPoint(20, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchMove with a secondary pointer should also be forwarded.
- MoveTouchPoint(1, 25, 0);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-TEST_F(LegacyTouchEventQueueTest, AsyncTouch) {
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- for (int i = 0; i < 3; ++i) {
- SendGestureEventAck(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- MoveTouchPoint(0, 10, 5 + i);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Consuming a scroll event will throttle subsequent touchmoves.
- SendGestureEventAck(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- MoveTouchPoint(0, 10, 7 + i);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- }
-}
-
-// Ensure that touchmove's are appropriately throttled during a typical
-// scroll sequences that transitions between scrolls consumed and unconsumed.
-TEST_F(LegacyTouchEventQueueTest, AsyncTouchThrottledAfterScroll) {
- // Process a TouchStart
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now send the first touch move and associated GestureScrollBegin.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- SendGestureEventAck(WebInputEvent::kGestureScrollBegin,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // Send the second touch move and associated GestureScrollUpdate, but don't
- // ACK the gesture event yet.
- MoveTouchPoint(0, 0, 50);
- followup_scroll.SetType(WebInputEvent::kGestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now queue a second touchmove and verify it's not (yet) dispatched.
- MoveTouchPoint(0, 0, 100);
- SetFollowupEvent(followup_scroll);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Queuing the final touchend should flush the pending async touchmove. In
- // this case, we will first dispatch an async touchmove and then a touchend.
- // For the async touchmove, we will not send ack again.
- ReleaseTouchPoint(0);
- followup_scroll.SetType(WebInputEvent::kGestureScrollEnd);
- SetFollowupEvent(followup_scroll);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_EQ(WebInputEvent::kTouchMove, all_sent_events()[0].GetType());
- EXPECT_NE(WebInputEvent::kBlocking, all_sent_events()[0].dispatch_type);
- EXPECT_EQ(WebInputEvent::kTouchEnd, all_sent_events()[1].GetType());
- EXPECT_NE(WebInputEvent::kBlocking, all_sent_events()[1].dispatch_type);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Ack the touchend.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now mark the scrolls as not consumed (which would cause future touchmoves
- // in the active sequence to be sent if there was one).
- SendGestureEventAck(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendGestureEventAck(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // Start a new touch sequence and verify that throttling has been reset.
- // Touch moves after the start of scrolling will again be throttled.
- PressTouchPoint(0, 0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- MoveTouchPoint(0, 0, 5);
- followup_scroll.SetType(WebInputEvent::kGestureScrollBegin);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 6);
- followup_scroll.SetType(WebInputEvent::kGestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Subsequent touchmove's should be deferred.
- MoveTouchPoint(0, 0, 25);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, uncancelable_touch_moves_pending_ack_count());
-
- // The pending touchmove should be flushed with the the new touchmove if
- // sufficient time has passed and ack to the client.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 15);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Non-touchmove events should always flush any pending touchmove events. In
- // this case, we will first dispatch an async touchmove and then a
- // touchstart. For the async touchmove, we will not send ack again.
- MoveTouchPoint(0, 0, 25);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- PressTouchPoint(30, 30);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_EQ(WebInputEvent::kTouchMove, all_sent_events()[0].GetType());
- EXPECT_NE(WebInputEvent::kBlocking, all_sent_events()[0].dispatch_type);
- EXPECT_EQ(WebInputEvent::kTouchStart, all_sent_events()[1].GetType());
- EXPECT_EQ(WebInputEvent::kBlocking, all_sent_events()[1].dispatch_type);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Ack the touchstart.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Send a secondary touchmove.
- MoveTouchPoint(1, 0, 25);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // An unconsumed scroll should resume synchronous touch handling.
- SendGestureEventAck(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // The pending touchmove should be coalesced with the next (now synchronous)
- // touchmove.
- MoveTouchPoint(0, 0, 26);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(WebInputEvent::kTouchMove, sent_event().GetType());
- EXPECT_EQ(WebTouchPoint::kStateMoved, sent_event().touches[0].state);
- EXPECT_EQ(WebTouchPoint::kStateMoved, sent_event().touches[1].state);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Subsequent touches will queue until the preceding, synchronous touches are
- // ack'ed.
- ReleaseTouchPoint(1);
- EXPECT_EQ(2U, queued_event_count());
- ReleaseTouchPoint(0);
- EXPECT_EQ(3U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(WebInputEvent::kTouchEnd, sent_event().GetType());
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(WebInputEvent::kTouchEnd, sent_event().GetType());
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-TEST_F(LegacyTouchEventQueueTest, AsyncTouchFlushedByTouchEnd) {
- PressTouchPoint(0, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Initiate async touchmove dispatch after the start of a scroll sequence.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- followup_scroll.SetType(WebInputEvent::kGestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now queue a second touchmove and verify it's not (yet) dispatched.
- MoveTouchPoint(0, 0, 100);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Return the touch sequence to the original touchstart position. Note that
- // this (0, 0) touchmove will coalesce with the previous (0, 100) touchmove.
- MoveTouchPoint(0, 0, 0);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Queuing the final touchend should flush the pending, async touchmove. In
- // this case, we will first dispatch an async touchmove and then a touchend.
- // For the async touchmove, we will not send ack again.
- ReleaseTouchPoint(0);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_EQ(WebInputEvent::kTouchMove, all_sent_events()[0].GetType());
- EXPECT_NE(WebInputEvent::kBlocking, all_sent_events()[0].dispatch_type);
- EXPECT_EQ(0, all_sent_events()[0].touches[0].PositionInWidget().x);
- EXPECT_EQ(0, all_sent_events()[0].touches[0].PositionInWidget().y);
- EXPECT_EQ(WebInputEvent::kTouchEnd, all_sent_events()[1].GetType());
- EXPECT_NE(WebInputEvent::kBlocking, all_sent_events()[1].dispatch_type);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Ensure that async touch dispatch and touch ack timeout interactions work
-// appropriately.
-TEST_F(LegacyTouchEventQueueTest, AsyncTouchWithAckTimeout) {
- SetUpForTimeoutTesting();
-
- // The touchstart should start the timeout.
- PressTouchPoint(0, 0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_TRUE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(IsTimeoutRunning());
-
- // The start of a scroll gesture should trigger async touch event dispatch.
- MoveTouchPoint(0, 1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_TRUE(IsTimeoutRunning());
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- SendGestureEventAck(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // An async touch should fire after the throttling interval has expired, but
- // it should not start the touch ack timeout.
- MoveTouchPoint(0, 5, 5);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 5, 5);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // An unconsumed scroll event will resume synchronous touchmoves, which are
- // subject to the ack timeout.
- SendGestureEventAck(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- MoveTouchPoint(0, 20, 5);
- EXPECT_TRUE(IsTimeoutRunning());
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // The timeout should fire, disabling touch forwarding until both acks are
- // received and acking the timed out event.
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Ack'ing the original event should trigger a cancel event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Subsequent touchmove's should not be forwarded, even as the scroll gesture
- // goes from unconsumed to consumed.
- SendGestureEventAck(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- MoveTouchPoint(0, 20, 5);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- SendGestureEventAck(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- MoveTouchPoint(0, 25, 5);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-}
-
-// Ensure that if the touch ack for an async touchmove triggers a follow-up
-// touch event, that follow-up touch will be forwarded appropriately.
-TEST_F(LegacyTouchEventQueueTest, AsyncTouchWithTouchCancelAfterAck) {
- PressTouchPoint(0, 0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // The start of a scroll gesture should trigger async touch event dispatch.
- MoveTouchPoint(0, 1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- SendGestureEvent(WebInputEvent::kGestureScrollUpdate);
-
- // The async touchmove should be ack'ed immediately, but not forwarded.
- // However, because the ack triggers a touchcancel, both the pending touch and
- // the queued touchcancel should be flushed.
- WebTouchEvent followup_cancel(WebInputEvent::kTouchCancel,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- followup_cancel.touches_length = 1;
- followup_cancel.touches[0].state = WebTouchPoint::kStateCancelled;
- SetFollowupEvent(followup_cancel);
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_EQ(WebInputEvent::kTouchMove, all_sent_events()[0].GetType());
- EXPECT_NE(WebInputEvent::kBlocking, all_sent_events()[0].dispatch_type);
- EXPECT_EQ(WebInputEvent::kTouchCancel, all_sent_events()[1].GetType());
- EXPECT_NE(WebInputEvent::kBlocking, all_sent_events()[1].dispatch_type);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- // Sending the ack is because the async touchmove is not ready for
- // dispatching send the ack immediately.
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::kTouchMove, acked_event().GetType());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::kTouchCancel, acked_event().GetType());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-}
-
-// Ensure that the async touch is fully reset if the touch sequence restarts
-// without properly terminating.
-TEST_F(LegacyTouchEventQueueTest, AsyncTouchWithHardTouchStartReset) {
- PressTouchPoint(0, 0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Trigger async touchmove dispatch.
- MoveTouchPoint(0, 1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
- SendGestureEvent(WebInputEvent::kGestureScrollUpdate);
-
- // The async touchmove should be immediately ack'ed but delivery is deferred.
- MoveTouchPoint(0, 2, 2);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::kTouchMove, acked_event().GetType());
-
- // The queue should be robust to hard touch restarts with a new touch
- // sequence. In this case, the deferred async touch should not be flushed
- // by the new touch sequence.
- SendGestureEvent(WebInputEvent::kGestureScrollEnd);
- ResetTouchEvent();
-
- PressTouchPoint(0, 0);
- EXPECT_EQ(WebInputEvent::kTouchStart, sent_event().GetType());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Ensure that even when the interval expires, we still need to wait for the
-// ack sent back from render to send the next async touchmove once the scroll
-// starts.
-TEST_F(LegacyTouchEventQueueTest, SendNextThrottledAsyncTouchMoveAfterAck) {
- // Process a TouchStart
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Initiate async touchmove dispatch after the start of a scroll sequence.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- followup_scroll.SetType(WebInputEvent::kGestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // We set the next touch event time to be after the throttled interval.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- // Dispatch the touch move event when sufficient time has passed.
- MoveTouchPoint(0, 0, 40);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- // When we dispatch an async touchmove, we do not put it back to the queue
- // any more and we will ack to client right away.
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-
- // Do not dispatch the event until throttledTouchmoves intervals expires and
- // receive an ack from render.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 50);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-
- // Send pending_async_touch_move_ when we receive an ack back from render,
- // but we will not send an ack for pending_async_touch_move_ becasue it is
- // been acked before.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-}
-
-// Ensure that even when we receive the ack from render, we still need to wait
-// for the interval expires to send the next async touchmove once the scroll
-// starts.
-TEST_F(LegacyTouchEventQueueTest, SendNextAsyncTouchMoveAfterAckAndTimeExpire) {
- // Process a TouchStart
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Initiate async touchmove dispatch after the start of a scroll sequence.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- followup_scroll.SetType(WebInputEvent::kGestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Dispatch the touch move event when sufficient time has passed.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 40);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- // When we dispatch an async touchmove, we do not put it back to the queue
- // any more and we will ack to client right away.
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-
- // We receive an ack back from render but the time interval is not expired,
- // so we do not dispatch the touch move event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, uncancelable_touch_moves_pending_ack_count());
- MoveTouchPoint(0, 0, 50);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Dispatch the touch move when sufficient time has passed.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 50);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(WebInputEvent::kTouchMove, sent_event().GetType());
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-}
-
-TEST_F(LegacyTouchEventQueueTest, AsyncTouchFlushedByNonTouchMove) {
- // Process a TouchStart
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Initiate async touchmove dispatch after the start of a scroll sequence.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- followup_scroll.SetType(WebInputEvent::kGestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Dispatch the touch move when sufficient time has passed.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 40);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- // When we dispatch an async touchmove, we do not put it back to the queue
- // any more and we will ack to client right away.
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-
- for (int i = 0; i < 3; ++i) {
- // We throttle the touchmoves, put it in the pending_async_touch_move_,
- // do not dispatch it.
- MoveTouchPoint(0, 10 + 10 * i, 10 + 10 * i);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(static_cast<size_t>(i + 1),
- uncancelable_touch_moves_pending_ack_count());
-
- // Send touchstart will flush pending_async_touch_move_, and increase the
- // count. In this case, we will first dispatch an async touchmove and
- // then a touchstart. For the async touchmove, we will not send ack again.
- PressTouchPoint(30, 30);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_EQ(WebInputEvent::kTouchMove, all_sent_events()[0].GetType());
- EXPECT_NE(WebInputEvent::kBlocking, all_sent_events()[0].dispatch_type);
- EXPECT_EQ(10 + 10 * i,
- all_sent_events()[0].touches[0].PositionInWidget().x);
- EXPECT_EQ(10 + 10 * i,
- all_sent_events()[0].touches[0].PositionInWidget().y);
- EXPECT_EQ(static_cast<size_t>(i + 2),
- uncancelable_touch_moves_pending_ack_count());
- EXPECT_EQ(WebInputEvent::kTouchStart, all_sent_events()[1].GetType());
- EXPECT_EQ(WebInputEvent::kBlocking, all_sent_events()[1].dispatch_type);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- SendTouchEventAckWithID(INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
- GetUniqueTouchEventID());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- }
-
- EXPECT_EQ(4U, uncancelable_touch_moves_pending_ack_count());
-
- // When we receive an ack from render we decrease the count.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(3U, uncancelable_touch_moves_pending_ack_count());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_FALSE(HasPendingAsyncTouchMove());
-
- // Do not dispatch the next uncancelable touchmove when we have not received
- // all the acks back from render.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 20, 30);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(3U, uncancelable_touch_moves_pending_ack_count());
-
- // Once we receive the ack from render, we do not dispatch the
- // pending_async_touchmove_ until the count is 0.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(2U, uncancelable_touch_moves_pending_ack_count());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_TRUE(HasPendingAsyncTouchMove());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // When we receive this ack from render, and the count is 0, so we can
- // dispatch the pending_async_touchmove_.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::kTouchMove, sent_event().GetType());
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Ensure that even when we receive the ack from render, we still need to wait
-// for the interval expires to send the next async touchmove once the scroll
-// starts.
-TEST_F(LegacyTouchEventQueueTest, DoNotIncreaseIfClientConsumeAsyncTouchMove) {
- // Process a TouchStart
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Initiate async touchmove dispatch after the start of a scroll sequence.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollBegin,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- followup_scroll.SetType(WebInputEvent::kGestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Dispatch the touch move event when sufficient time has passed.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 40);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- // When we dispatch an async touchmove, we do not put it back to the queue
- // any more and we will ack to client right away.
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-
- // We receive an ack back from render but the time interval is not expired,
- // so we do not dispatch the touch move event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, uncancelable_touch_moves_pending_ack_count());
- MoveTouchPoint(0, 0, 50);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Dispatch the touch move when sufficient time has passed. Becasue the event
- // is consumed by client already, we would not increase the count and ack to
- // client again.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- MoveTouchPoint(0, 0, 50);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(WebInputEvent::kTouchMove, sent_event().GetType());
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, uncancelable_touch_moves_pending_ack_count());
-}
-
-TEST_F(LegacyTouchEventQueueTest, TouchAbsorptionWithConsumedFirstMove) {
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 20, 5);
- SendGestureEvent(blink::WebInputEvent::kGestureScrollBegin);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(2U, GetAndResetSentEventCount());
-
- // Even if the first touchmove event was consumed, subsequent unconsumed
- // touchmove events should trigger scrolling.
- MoveTouchPoint(0, 60, 5);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- MoveTouchPoint(0, 20, 5);
- WebGestureEvent followup_scroll(WebInputEvent::kGestureScrollUpdate,
- WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendGestureEventAck(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Touch move event is throttled.
- MoveTouchPoint(0, 60, 5);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-}
-
-TEST_F(LegacyTouchEventQueueTest, TouchStartCancelableDuringScroll) {
- // Queue a touchstart and touchmove that go unconsumed, transitioning to an
- // active scroll sequence.
- PressTouchPoint(0, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- MoveTouchPoint(0, 20, 5);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- SendGestureEvent(blink::WebInputEvent::kGestureScrollBegin);
- SendGestureEvent(blink::WebInputEvent::kGestureScrollUpdate);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- // Even though scrolling has begun, touchstart events should be cancelable,
- // allowing, for example, customized pinch processing.
- PressTouchPoint(10, 11);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- // As the touch start was consumed, touchmoves should no longer be throttled.
- MoveTouchPoint(1, 11, 11);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- // With throttling disabled, touchend and touchmove events should also be
- // cancelable.
- MoveTouchPoint(1, 12, 12);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ReleaseTouchPoint(1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- // If subsequent touchmoves aren't consumed, the generated scroll events
- // will restore async touch dispatch.
- MoveTouchPoint(0, 25, 5);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendGestureEvent(blink::WebInputEvent::kGestureScrollUpdate);
- EXPECT_EQ(WebInputEvent::kBlocking, sent_event().dispatch_type);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 30, 5);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- // The touchend will be uncancelable during an active scroll sequence.
- ReleaseTouchPoint(0);
- EXPECT_NE(WebInputEvent::kBlocking, sent_event().dispatch_type);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-}
-
-TEST_F(LegacyTouchEventQueueTest, UnseenTouchPointerIdsNotForwarded) {
- SyntheticWebTouchEvent event;
- event.PressPoint(0, 0);
- SendTouchEvent(event);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Give the touchmove a previously unseen pointer id; it should not be sent.
- int press_id = event.touches[0].id;
- event.MovePoint(0, 1, 1);
- event.touches[0].id = 7;
- SendTouchEvent(event);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Give the touchmove a valid id; it should be sent.
- event.touches[0].id = press_id;
- SendTouchEvent(event);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Do the same for release.
- event.ReleasePoint(0);
- event.touches[0].id = 11;
- SendTouchEvent(event);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Give the touchmove a valid id; it should be sent.
- event.touches[0].id = press_id;
- SendTouchEvent(event);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that touch points states are correct in TouchMove events.
-TEST_F(LegacyTouchEventQueueTest, PointerStatesInTouchMove) {
- PressTouchPoint(1, 1);
- PressTouchPoint(2, 2);
- PressTouchPoint(3, 3);
- PressTouchPoint(4, 4);
- EXPECT_EQ(4U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Receive ACK for the first three touch-events.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
-
- // Test current touches state before sending TouchMoves.
- const WebTouchEvent& event1 = sent_event();
- EXPECT_EQ(WebInputEvent::kTouchStart, event1.GetType());
- EXPECT_EQ(WebTouchPoint::kStateStationary, event1.touches[0].state);
- EXPECT_EQ(WebTouchPoint::kStateStationary, event1.touches[1].state);
- EXPECT_EQ(WebTouchPoint::kStateStationary, event1.touches[2].state);
- EXPECT_EQ(WebTouchPoint::kStatePressed, event1.touches[3].state);
-
- // Move x-position for 1st touch, y-position for 2nd touch
- // and do not move other touches.
- MoveTouchPoints(0, 1.1f, 1.f, 1, 2.f, 20.001f);
- MoveTouchPoints(2, 3.f, 3.f, 3, 4.f, 4.f);
- EXPECT_EQ(2U, queued_event_count());
-
- // Receive an ACK for the last TouchPress event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // 1st TouchMove is sent. Test for touches state.
- const WebTouchEvent& event2 = sent_event();
- EXPECT_EQ(WebInputEvent::kTouchMove, event2.GetType());
- EXPECT_EQ(WebTouchPoint::kStateMoved, event2.touches[0].state);
- EXPECT_EQ(WebTouchPoint::kStateMoved, event2.touches[1].state);
- EXPECT_EQ(WebTouchPoint::kStateStationary, event2.touches[2].state);
- EXPECT_EQ(WebTouchPoint::kStateStationary, event2.touches[3].state);
-
- // Move only 4th touch but not others.
- MoveTouchPoints(0, 1.1f, 1.f, 1, 2.f, 20.001f);
- MoveTouchPoints(2, 3.f, 3.f, 3, 4.1f, 4.1f);
-
- // Receive an ACK for previous (1st) TouchMove.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // 2nd TouchMove is sent. Test for touches state.
- const WebTouchEvent& event3 = sent_event();
- EXPECT_EQ(WebInputEvent::kTouchMove, event3.GetType());
- EXPECT_EQ(WebTouchPoint::kStateStationary, event3.touches[0].state);
- EXPECT_EQ(WebTouchPoint::kStateStationary, event3.touches[1].state);
- EXPECT_EQ(WebTouchPoint::kStateStationary, event3.touches[2].state);
- EXPECT_EQ(WebTouchPoint::kStateMoved, event3.touches[3].state);
-}
-
-// Tests that touch point state is correct in TouchMove events
-// when point properties other than position changed.
-TEST_F(LegacyTouchEventQueueTest, PointerStatesWhenOtherThanPositionChanged) {
- PressTouchPoint(1, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // Default initial radiusX/Y is (1.f, 1.f).
- // Default initial rotationAngle is 1.f.
- // Default initial force is 1.f.
-
- // Change touch point radius only.
- ChangeTouchPointRadius(0, 1.5f, 1.f);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // TouchMove is sent. Test for pointer state.
- const WebTouchEvent& event1 = sent_event();
- EXPECT_EQ(WebInputEvent::kTouchMove, event1.GetType());
- EXPECT_EQ(WebTouchPoint::kStateMoved, event1.touches[0].state);
-
- // Change touch point force.
- ChangeTouchPointForce(0, 0.9f);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // TouchMove is sent. Test for pointer state.
- const WebTouchEvent& event2 = sent_event();
- EXPECT_EQ(WebInputEvent::kTouchMove, event2.GetType());
- EXPECT_EQ(WebTouchPoint::kStateMoved, event2.touches[0].state);
-
- // Change touch point rotationAngle.
- ChangeTouchPointRotationAngle(0, 1.1f);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // TouchMove is sent. Test for pointer state.
- const WebTouchEvent& event3 = sent_event();
- EXPECT_EQ(WebInputEvent::kTouchMove, event3.GetType());
- EXPECT_EQ(WebTouchPoint::kStateMoved, event3.touches[0].state);
-
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(4U, GetAndResetSentEventCount());
- EXPECT_EQ(4U, GetAndResetAckedEventCount());
-}
-
-// Tests that TouchMoves are filtered when none of the points are changed.
-TEST_F(LegacyTouchEventQueueTest, FilterTouchMovesWhenNoPointerChanged) {
- PressTouchPoint(1, 1);
- PressTouchPoint(2, 2);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
-
- // Move 1st touch point.
- MoveTouchPoint(0, 10, 10);
- EXPECT_EQ(1U, queued_event_count());
-
- // TouchMove should be allowed and test for touches state.
- const WebTouchEvent& event1 = sent_event();
- EXPECT_EQ(WebInputEvent::kTouchMove, event1.GetType());
- EXPECT_EQ(WebTouchPoint::kStateMoved, event1.touches[0].state);
- EXPECT_EQ(WebTouchPoint::kStateStationary, event1.touches[1].state);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Do not really move any touch points, but use previous values.
- MoveTouchPoint(0, 10, 10);
- ChangeTouchPointRadius(1, 1, 1);
- MoveTouchPoint(1, 2, 2);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Receive an ACK for 1st TouchMove.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // Tries to forward TouchMove but should be filtered
- // when none of the touch points have changed.
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(4U, GetAndResetAckedEventCount());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state());
-
- // Move 2nd touch point.
- MoveTouchPoint(1, 3, 3);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
-
- // TouchMove should be allowed and test for touches state.
- const WebTouchEvent& event2 = sent_event();
- EXPECT_EQ(WebInputEvent::kTouchMove, event2.GetType());
- EXPECT_EQ(WebTouchPoint::kStateStationary, event2.touches[0].state);
- EXPECT_EQ(WebTouchPoint::kStateMoved, event2.touches[1].state);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that touch-scroll-notification is not pushed into an empty queue.
-TEST_F(LegacyTouchEventQueueTest, TouchScrollNotificationOrder_EmptyQueue) {
- PrependTouchScrollNotification();
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-}
-
-// Tests touch-scroll-notification firing order when the event is placed at the
-// end of touch queue because of a pending ack for the head of the queue.
-TEST_F(LegacyTouchEventQueueTest, TouchScrollNotificationOrder_EndOfQueue) {
- PressTouchPoint(1, 1);
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Send the touch-scroll-notification when 3 events are in the queue.
- PrependTouchScrollNotification();
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- // Receive an ACK for the touchstart.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::kTouchStart, acked_event().GetType());
- EXPECT_EQ(1U, queued_event_count());
-
- // Receive an ACK for the touch-scroll-notification.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_IGNORED);
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- EXPECT_EQ(WebInputEvent::kTouchStart, all_sent_events()[0].GetType());
- EXPECT_EQ(WebInputEvent::kTouchScrollStarted, all_sent_events()[1].GetType());
- EXPECT_EQ(2U, GetAndResetSentEventCount());
-}
-
-// Tests touch-scroll-notification firing order when the event is placed in the
-// 2nd position in the touch queue between two events.
-TEST_F(LegacyTouchEventQueueTest, TouchScrollNotificationOrder_SecondPosition) {
- PressTouchPoint(1, 1);
- MoveTouchPoint(0, 5, 5);
- ReleaseTouchPoint(0);
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(3U, queued_event_count());
-
- // Send the touch-scroll-notification when 3 events are in the queue.
- PrependTouchScrollNotification();
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(4U, queued_event_count());
-
- // Receive an ACK for the touchstart.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::kTouchStart, acked_event().GetType());
- EXPECT_EQ(3U, queued_event_count());
-
- // Receive an ACK for the touch-scroll-notification.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_IGNORED);
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- // Receive an ACK for the touchmove.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::kTouchMove, acked_event().GetType());
- EXPECT_EQ(1U, queued_event_count());
-
- // Receive an ACK for the touchend.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::kTouchEnd, acked_event().GetType());
- EXPECT_EQ(0U, queued_event_count());
-
- EXPECT_EQ(WebInputEvent::kTouchStart, all_sent_events()[0].GetType());
- EXPECT_EQ(WebInputEvent::kTouchScrollStarted, all_sent_events()[1].GetType());
- EXPECT_EQ(WebInputEvent::kTouchMove, all_sent_events()[2].GetType());
- EXPECT_EQ(WebInputEvent::kTouchEnd, all_sent_events()[3].GetType());
- EXPECT_EQ(4U, GetAndResetSentEventCount());
-}
-
-// Tests that if touchStartOrFirstTouchMove is correctly set up for touch
-// events.
-TEST_F(LegacyTouchEventQueueTest, TouchStartOrFirstTouchMove) {
- PressTouchPoint(1, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::kTouchStart, sent_event().GetType());
- EXPECT_TRUE(sent_event().touch_start_or_first_touch_move);
-
- MoveTouchPoint(0, 5, 5);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::kTouchMove, sent_event().GetType());
- EXPECT_TRUE(sent_event().touch_start_or_first_touch_move);
-
- MoveTouchPoint(0, 15, 15);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::kTouchMove, sent_event().GetType());
- EXPECT_FALSE(sent_event().touch_start_or_first_touch_move);
-
- ReleaseTouchPoint(0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::kTouchEnd, sent_event().GetType());
- EXPECT_FALSE(sent_event().touch_start_or_first_touch_move);
-}
-
-} // namespace content
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 3d1c3821935..150bb71dd65 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
@@ -112,8 +112,8 @@ class MainThreadEventQueueBrowserTest : public ContentBrowserTest {
// event as ExecuteScript is synchronous.
SimulateMouseClick(shell()->web_contents(), 0,
blink::WebPointerProperties::Button::kLeft);
- scoped_refptr<InputMsgWatcher> input_msg_watcher(
- new InputMsgWatcher(GetWidgetHost(), blink::WebInputEvent::kMouseMove));
+ auto input_msg_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kMouseMove);
GetWidgetHost()->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(
blink::WebInputEvent::kMouseMove, 10, 10, 0));
GetWidgetHost()->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(
@@ -154,8 +154,8 @@ class MainThreadEventQueueBrowserTest : public ContentBrowserTest {
// event as ExecuteScript is synchronous.
SimulateMouseClick(shell()->web_contents(), 0,
blink::WebPointerProperties::Button::kLeft);
- scoped_refptr<InputMsgWatcher> input_msg_watcher(
- new InputMsgWatcher(GetWidgetHost(), blink::WebInputEvent::kTouchMove));
+ auto input_msg_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kTouchMove);
for (const auto& event : kEvents)
GetWidgetHost()->ForwardEmulatedTouchEvent(event);
diff --git a/chromium/content/browser/renderer_host/input/mock_input_disposition_handler.cc b/chromium/content/browser/renderer_host/input/mock_input_disposition_handler.cc
index 17e700190aa..134e281707d 100644
--- a/chromium/content/browser/renderer_host/input/mock_input_disposition_handler.cc
+++ b/chromium/content/browser/renderer_host/input/mock_input_disposition_handler.cc
@@ -18,7 +18,7 @@ using blink::WebTouchPoint;
namespace content {
MockInputDispositionHandler::MockInputDispositionHandler()
- : input_router_(NULL),
+ : input_router_(nullptr),
ack_count_(0),
unexpected_event_ack_called_(false),
ack_event_type_(WebInputEvent::kUndefined),
@@ -28,6 +28,7 @@ MockInputDispositionHandler::~MockInputDispositionHandler() {}
void MockInputDispositionHandler::OnKeyboardEventAck(
const NativeWebKeyboardEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
VLOG(1) << __FUNCTION__ << " called!";
acked_key_event_.reset(new NativeWebKeyboardEvent(event.event));
@@ -36,6 +37,7 @@ void MockInputDispositionHandler::OnKeyboardEventAck(
void MockInputDispositionHandler::OnMouseEventAck(
const MouseEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
VLOG(1) << __FUNCTION__ << " called!";
acked_mouse_event_ = event.event;
@@ -44,6 +46,7 @@ void MockInputDispositionHandler::OnMouseEventAck(
void MockInputDispositionHandler::OnWheelEventAck(
const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
VLOG(1) << __FUNCTION__ << " called!";
acked_wheel_event_ = event.event;
@@ -53,6 +56,7 @@ void MockInputDispositionHandler::OnWheelEventAck(
void MockInputDispositionHandler::OnTouchEventAck(
const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
VLOG(1) << __FUNCTION__ << " called!";
acked_touch_event_ = event;
@@ -65,6 +69,7 @@ void MockInputDispositionHandler::OnTouchEventAck(
void MockInputDispositionHandler::OnGestureEventAck(
const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
VLOG(1) << __FUNCTION__ << " called!";
acked_gesture_event_ = event.event;
diff --git a/chromium/content/browser/renderer_host/input/mock_input_disposition_handler.h b/chromium/content/browser/renderer_host/input/mock_input_disposition_handler.h
index 56ed6f57a28..4db0674d99a 100644
--- a/chromium/content/browser/renderer_host/input/mock_input_disposition_handler.h
+++ b/chromium/content/browser/renderer_host/input/mock_input_disposition_handler.h
@@ -23,14 +23,19 @@ class MockInputDispositionHandler : public InputDispositionHandler {
// InputDispositionHandler
void OnKeyboardEventAck(const NativeWebKeyboardEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnMouseEventAck(const MouseEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnUnexpectedEventAck(UnexpectedEventAckType type) override;
diff --git a/chromium/content/browser/renderer_host/input/mock_input_router_client.cc b/chromium/content/browser/renderer_host/input/mock_input_router_client.cc
index 95f5cdb2486..a46a9304a32 100644
--- a/chromium/content/browser/renderer_host/input/mock_input_router_client.cc
+++ b/chromium/content/browser/renderer_host/input/mock_input_router_client.cc
@@ -19,7 +19,7 @@ using blink::WebTouchPoint;
namespace content {
MockInputRouterClient::MockInputRouterClient()
- : input_router_(NULL),
+ : input_router_(nullptr),
in_flight_event_count_(0),
has_touch_handler_(false),
filter_state_(INPUT_EVENT_ACK_STATE_NOT_CONSUMED),
diff --git a/chromium/content/browser/renderer_host/input/mock_widget_input_handler.cc b/chromium/content/browser/renderer_host/input/mock_widget_input_handler.cc
deleted file mode 100644
index 79b0e4f2bae..00000000000
--- a/chromium/content/browser/renderer_host/input/mock_widget_input_handler.cc
+++ /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.
-
-#include "content/browser/renderer_host/input/mock_widget_input_handler.h"
-
-#include "content/browser/renderer_host/input/input_router.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::TimeDelta;
-using blink::WebGestureEvent;
-using blink::WebInputEvent;
-using blink::WebMouseEvent;
-using blink::WebMouseWheelEvent;
-using blink::WebTouchEvent;
-using blink::WebTouchPoint;
-
-namespace content {
-
-MockWidgetInputHandler::MockWidgetInputHandler() {}
-
-MockWidgetInputHandler::~MockWidgetInputHandler() {}
-
-void MockWidgetInputHandler::SetFocus(bool focused) {}
-
-void MockWidgetInputHandler::MouseCaptureLost() {}
-
-void MockWidgetInputHandler::SetEditCommandsForNextKeyEvent(
- const std::vector<content::EditCommand>& commands) {
- edit_commands_ = commands;
-}
-
-void MockWidgetInputHandler::CursorVisibilityChanged(bool visible) {}
-
-void MockWidgetInputHandler::ImeSetComposition(
- const base::string16& text,
- const std::vector<ui::ImeTextSpan>& ime_text_spans,
- const gfx::Range& range,
- int32_t start,
- int32_t end) {}
-
-void MockWidgetInputHandler::ImeCommitText(
- const base::string16& text,
- const std::vector<ui::ImeTextSpan>& ime_text_spans,
- const gfx::Range& range,
- int32_t relative_cursor_position) {}
-
-void MockWidgetInputHandler::ImeFinishComposingText(bool keep_selection) {}
-
-void MockWidgetInputHandler::RequestTextInputStateUpdate() {}
-
-void MockWidgetInputHandler::RequestCompositionUpdates(bool immediate_request,
- bool monitor_request) {}
-
-void MockWidgetInputHandler::DispatchEvent(
- std::unique_ptr<content::InputEvent> event,
- DispatchEventCallback callback) {
- dispatched_events_.emplace_back(
- DispatchedEvent(std::move(event), std::move(callback)));
-}
-
-void MockWidgetInputHandler::DispatchNonBlockingEvent(
- std::unique_ptr<content::InputEvent> event) {
- dispatched_events_.emplace_back(
- DispatchedEvent(std::move(event), DispatchEventCallback()));
-}
-
-std::vector<MockWidgetInputHandler::DispatchedEvent>
-MockWidgetInputHandler::GetAndResetDispatchedEvents() {
- std::vector<DispatchedEvent> dispatched_events;
- dispatched_events_.swap(dispatched_events);
- return dispatched_events;
-}
-
-std::vector<content::EditCommand>
-MockWidgetInputHandler::GetAndResetEditCommands() {
- std::vector<content::EditCommand> edit_commands;
- edit_commands_.swap(edit_commands);
- return edit_commands;
-}
-
-MockWidgetInputHandler::DispatchedEvent::DispatchedEvent(
- DispatchedEvent&& other)
- : event_(std::move(other.event_)), callback_(std::move(other.callback_)) {}
-
-MockWidgetInputHandler::DispatchedEvent::DispatchedEvent(
- std::unique_ptr<content::InputEvent> event,
- DispatchEventCallback callback)
- : event_(std::move(event)), callback_(std::move(callback)) {}
-
-MockWidgetInputHandler::DispatchedEvent::~DispatchedEvent() {}
-
-} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/mock_widget_input_handler.h b/chromium/content/browser/renderer_host/input/mock_widget_input_handler.h
deleted file mode 100644
index de206904713..00000000000
--- a/chromium/content/browser/renderer_host/input/mock_widget_input_handler.h
+++ /dev/null
@@ -1,68 +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_BROWSER_RENDERER_HOST_INPUT_MOCK_WIDGET_INPUT_HANDLER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_MOCK_WIDGET_INPUT_HANDLER_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <utility>
-
-#include "content/common/input/input_handler.mojom.h"
-
-namespace content {
-
-class MockWidgetInputHandler : public mojom::WidgetInputHandler {
- public:
- MockWidgetInputHandler();
- ~MockWidgetInputHandler() override;
-
- class DispatchedEvent {
- public:
- DispatchedEvent(DispatchedEvent&& other);
-
- DispatchedEvent(std::unique_ptr<content::InputEvent> event,
- DispatchEventCallback callback);
- ~DispatchedEvent();
- std::unique_ptr<content::InputEvent> event_;
- DispatchEventCallback callback_;
- };
-
- // mojom::WidgetInputHandler override.
- void SetFocus(bool focused) override;
- void MouseCaptureLost() override;
- void SetEditCommandsForNextKeyEvent(
- const std::vector<content::EditCommand>& commands) override;
- void CursorVisibilityChanged(bool visible) override;
- void ImeSetComposition(const base::string16& text,
- const std::vector<ui::ImeTextSpan>& ime_text_spans,
- const gfx::Range& range,
- int32_t start,
- int32_t end) override;
- void ImeCommitText(const base::string16& text,
- const std::vector<ui::ImeTextSpan>& ime_text_spans,
- const gfx::Range& range,
- int32_t relative_cursor_position) override;
- void ImeFinishComposingText(bool keep_selection) override;
- void RequestTextInputStateUpdate() override;
- void RequestCompositionUpdates(bool immediate_request,
- bool monitor_request) override;
-
- void DispatchEvent(std::unique_ptr<content::InputEvent> event,
- DispatchEventCallback callback) override;
- void DispatchNonBlockingEvent(
- std::unique_ptr<content::InputEvent> event) override;
-
- std::vector<DispatchedEvent> GetAndResetDispatchedEvents();
- std::vector<content::EditCommand> GetAndResetEditCommands();
-
- private:
- std::vector<DispatchedEvent> dispatched_events_;
- std::vector<content::EditCommand> edit_commands_;
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_MOCK_INPUT_ACK_HANDLER_H_
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 0754dbd6ff7..b6234b6e00c 100644
--- a/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc
@@ -15,14 +15,15 @@
#include "content/browser/renderer_host/input/synthetic_gesture.h"
#include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
+#include "content/browser/renderer_host/input/synthetic_smooth_move_gesture.h"
#include "content/browser/renderer_host/input/synthetic_tap_gesture.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/input/synthetic_gesture_params.h"
-#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/tracing_controller.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"
@@ -30,7 +31,7 @@
namespace {
-const char kMouseUpDownDataURL[] =
+const char kDataURL[] =
"data:text/html;charset=utf-8,"
"<!DOCTYPE html>"
"<html>"
@@ -38,6 +39,14 @@ const char kMouseUpDownDataURL[] =
"<title>Mouse event trace events reported.</title>"
"<script src=\"../../resources/testharness.js\"></script>"
"<script src=\"../../resources/testharnessreport.js\"></script>"
+ "<script>"
+ " let i=0;"
+ " document.addEventListener('mousemove', () => {"
+ " var end = performance.now() + 20;"
+ " while(performance.now() < end);"
+ " document.body.style.backgroundColor = 'rgb(' + (i++) + ',0,0)'"
+ " });"
+ "</script>"
"<style>"
"body {"
" height:3000px;"
@@ -81,7 +90,7 @@ class MouseLatencyBrowserTest : public ContentBrowserTest {
protected:
void LoadURL() {
- const GURL data_url(kMouseUpDownDataURL);
+ const GURL data_url(kDataURL);
NavigateToURL(shell(), data_url);
RenderWidgetHostImpl* host = GetWidgetHost();
@@ -103,7 +112,30 @@ class MouseLatencyBrowserTest : public ContentBrowserTest {
base::Unretained(this)));
// Runs until we get the OnSyntheticGestureCompleted callback
- runner_ = base::MakeUnique<base::RunLoop>();
+ runner_ = std::make_unique<base::RunLoop>();
+ runner_->Run();
+ }
+
+ // Generate mouse events drag from |position|.
+ void DoSyncCoalescedMoves(const gfx::PointF position,
+ const gfx::Vector2dF& delta1,
+ const gfx::Vector2dF& delta2) {
+ SyntheticSmoothMoveGestureParams params;
+ params.input_type = SyntheticSmoothMoveGestureParams::MOUSE_DRAG_INPUT;
+ params.start_point.SetPoint(position.x(), position.y());
+ params.distances.push_back(delta1);
+ params.distances.push_back(delta2);
+
+ std::unique_ptr<SyntheticSmoothMoveGesture> gesture(
+ new SyntheticSmoothMoveGesture(params));
+
+ GetWidgetHost()->QueueSyntheticGesture(
+ std::move(gesture),
+ base::BindOnce(&MouseLatencyBrowserTest::OnSyntheticGestureCompleted,
+ base::Unretained(this)));
+
+ // Runs until we get the OnSyntheticGestureCompleted callback
+ runner_ = std::make_unique<base::RunLoop>();
runner_->Run();
}
@@ -121,6 +153,7 @@ class MouseLatencyBrowserTest : public ContentBrowserTest {
base::RunLoop run_loop;
ASSERT_TRUE(TracingController::GetInstance()->StartTracing(
trace_config, run_loop.QuitClosure()));
+ run_loop.Run();
}
const base::Value& StopTracing() {
@@ -132,7 +165,7 @@ class MouseLatencyBrowserTest : public ContentBrowserTest {
// Runs until we get the OnTraceDataCollected callback, which populates
// trace_data_;
- runner_ = base::MakeUnique<base::RunLoop>();
+ runner_ = std::make_unique<base::RunLoop>();
runner_->Run();
return trace_data_;
}
@@ -149,8 +182,7 @@ class MouseLatencyBrowserTest : public ContentBrowserTest {
// MouseDown events in the case where no swap is generated.
// Disabled on Android because we don't support synthetic mouse input on
// Android (crbug.com/723618).
-// Flaky on Mac10.10 (crbug.com/774169).
-#if defined(OS_ANDROID) || defined(OS_MACOSX)
+#if defined(OS_ANDROID)
#define MAYBE_MouseDownAndUpRecordedWithoutSwap \
DISABLED_MouseDownAndUpRecordedWithoutSwap
#else
@@ -161,8 +193,12 @@ IN_PROC_BROWSER_TEST_F(MouseLatencyBrowserTest,
MAYBE_MouseDownAndUpRecordedWithoutSwap) {
LoadURL();
+ auto filter = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kMouseUp);
StartTracing();
DoSyncClick(gfx::PointF(100, 100));
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED,
+ filter->GetAckStateWaitIfNecessary());
const base::Value& trace_data = StopTracing();
const base::DictionaryValue* trace_data_dict;
@@ -193,4 +229,61 @@ IN_PROC_BROWSER_TEST_F(MouseLatencyBrowserTest,
"InputLatency::MouseUp", "InputLatency::MouseUp"));
}
+// Ensures that LatencyInfo async slices are reported correctly for MouseMove
+// events in the case where events are coalesced. (crbug.com/771165).
+// Disabled on Android because we don't support synthetic mouse input on Android
+// (crbug.com/723618).
+#if defined(OS_ANDROID)
+#define MAYBE_CoalescedMouseMovesCorrectlyTerminated \
+ DISABLED_CoalescedMouseMovesCorrectlyTerminated
+#else
+// Test fails/flakes on multiple platforms. https://crbug.com/789096
+#define MAYBE_CoalescedMouseMovesCorrectlyTerminated \
+ DISABLED_CoalescedMouseMovesCorrectlyTerminated
+#endif
+IN_PROC_BROWSER_TEST_F(MouseLatencyBrowserTest,
+ MAYBE_CoalescedMouseMovesCorrectlyTerminated) {
+ LoadURL();
+
+ auto filter = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kMouseUp);
+ StartTracing();
+ DoSyncCoalescedMoves(gfx::PointF(100, 100), gfx::Vector2dF(150, 150),
+ gfx::Vector2dF(250, 250));
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED,
+ filter->GetAckStateWaitIfNecessary());
+ content::MainThreadFrameObserver observer(GetWidgetHost());
+ observer.Wait();
+ const base::Value& trace_data = StopTracing();
+
+ const base::DictionaryValue* trace_data_dict;
+ trace_data.GetAsDictionary(&trace_data_dict);
+ ASSERT_TRUE(trace_data.GetAsDictionary(&trace_data_dict));
+
+ const base::ListValue* traceEvents;
+ ASSERT_TRUE(trace_data_dict->GetList("traceEvents", &traceEvents));
+
+ std::map<std::string, int> trace_ids;
+
+ for (size_t i = 0; i < traceEvents->GetSize(); ++i) {
+ const base::DictionaryValue* traceEvent;
+ ASSERT_TRUE(traceEvents->GetDictionary(i, &traceEvent));
+
+ std::string name;
+ ASSERT_TRUE(traceEvent->GetString("name", &name));
+
+ if (name != "InputLatency::MouseMove")
+ continue;
+
+ std::string id;
+ if (traceEvent->GetString("id", &id))
+ ++trace_ids[id];
+ }
+
+ for (auto i : trace_ids) {
+ // Each trace id should show up once for the begin, and once for the end.
+ EXPECT_EQ(2, i.second);
+ }
+}
+
} // namespace content
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 dd89c6c2229..7bbde1df888 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
@@ -39,11 +39,13 @@ class QueuedWebMouseWheelEvent : public MouseWheelEventWithLatencyInfo {
MouseWheelEventQueue::MouseWheelEventQueue(MouseWheelEventQueueClient* client,
bool enable_scroll_latching)
: client_(client),
- needs_scroll_begin_(true),
- needs_scroll_end_(false),
+ needs_scroll_begin_when_scroll_latching_disabled_(true),
+ needs_scroll_end_when_scroll_latching_disabled_(false),
+ scroll_in_progress_(false),
enable_scroll_latching_(enable_scroll_latching),
enable_async_wheel_events_(
- base::FeatureList::IsEnabled(features::kAsyncWheelEvents)),
+ base::FeatureList::IsEnabled(features::kAsyncWheelEvents) &&
+ enable_scroll_latching),
send_wheel_events_async_(false),
scrolling_device_(blink::kWebGestureDeviceUninitialized) {
DCHECK(client);
@@ -68,12 +70,13 @@ void MouseWheelEventQueue::QueueEvent(
}
}
- wheel_queue_.push_back(base::MakeUnique<QueuedWebMouseWheelEvent>(event));
+ wheel_queue_.push_back(std::make_unique<QueuedWebMouseWheelEvent>(event));
TryForwardNextEventToRenderer();
LOCAL_HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", wheel_queue_.size());
}
void MouseWheelEventQueue::ProcessMouseWheelAck(
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
const LatencyInfo& latency_info) {
TRACE_EVENT0("input", "MouseWheelEventQueue::ProcessMouseWheelAck");
@@ -81,7 +84,8 @@ void MouseWheelEventQueue::ProcessMouseWheelAck(
return;
event_sent_for_gesture_ack_->latency.AddNewLatencyFrom(latency_info);
- client_->OnMouseWheelEventAck(*event_sent_for_gesture_ack_, ack_result);
+ client_->OnMouseWheelEventAck(*event_sent_for_gesture_ack_, ack_source,
+ ack_result);
// If event wasn't consumed then generate a gesture scroll for it.
if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED &&
@@ -178,20 +182,25 @@ void MouseWheelEventQueue::ProcessMouseWheelAck(
bool needs_update = scroll_update.data.scroll_update.delta_x != 0 ||
scroll_update.data.scroll_update.delta_y != 0;
+ // For every GSU event record whether it is latched or not.
+ if (needs_update)
+ RecordLatchingUmaMetric(scroll_in_progress_);
+
if (enable_scroll_latching_) {
+ bool synthetic = event_sent_for_gesture_ack_->event.has_synthetic_phase;
if (event_sent_for_gesture_ack_->event.phase ==
blink::WebMouseWheelEvent::kPhaseBegan) {
// Wheel event with phaseBegan must have non-zero deltas.
DCHECK(needs_update);
send_wheel_events_async_ = true;
- SendScrollBegin(scroll_update, false);
+ SendScrollBegin(scroll_update, synthetic);
}
if (needs_update) {
// It is possible that the wheel event with phaseBegan is consumed and
// no GSB is sent.
- if (needs_scroll_begin_)
- SendScrollBegin(scroll_update, false);
+ if (!scroll_in_progress_)
+ SendScrollBegin(scroll_update, synthetic);
ui::LatencyInfo latency = ui::LatencyInfo(ui::SourceEventType::WHEEL);
latency.AddLatencyNumber(
ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, 0,
@@ -199,10 +208,10 @@ void MouseWheelEventQueue::ProcessMouseWheelAck(
client_->ForwardGestureEventWithLatencyInfo(scroll_update, latency);
}
- if (current_phase_ended && needs_scroll_end_) {
+ if (current_phase_ended && scroll_in_progress_) {
// Send GSE when scroll latching is enabled, GSB is sent, and no fling
// is going to happen next.
- SendScrollEnd(scroll_update, false);
+ SendScrollEnd(scroll_update, synthetic);
}
} else { // !enable_scroll_latching_
@@ -211,10 +220,11 @@ void MouseWheelEventQueue::ProcessMouseWheelAck(
// because the events generated will be a GSB (non-synthetic) and GSE
// (non-synthetic). This situation arises when OSX generates double
// phase end information.
- bool empty_sequence =
- !needs_update && needs_scroll_begin_ && current_phase_ended;
+ bool empty_sequence = !needs_update &&
+ needs_scroll_begin_when_scroll_latching_disabled_ &&
+ current_phase_ended;
if (needs_update || !empty_sequence) {
- if (needs_scroll_begin_) {
+ if (needs_scroll_begin_when_scroll_latching_disabled_) {
// If no GSB has been sent, it will be a non-synthetic GSB.
SendScrollBegin(scroll_update, false);
} else if (has_phase_info) {
@@ -263,10 +273,8 @@ void MouseWheelEventQueue::OnGestureScrollEvent(
gesture_event.event.GetType() ==
blink::WebInputEvent::kGestureFlingStart)) {
scrolling_device_ = blink::kWebGestureDeviceUninitialized;
- if (enable_scroll_latching_) {
- needs_scroll_begin_ = true;
- needs_scroll_end_ = false;
- }
+ if (enable_scroll_latching_)
+ scroll_in_progress_ = false;
}
}
@@ -298,7 +306,12 @@ void MouseWheelEventQueue::TryForwardNextEventToRenderer() {
void MouseWheelEventQueue::SendScrollEnd(WebGestureEvent update_event,
bool synthetic) {
- DCHECK((synthetic && !needs_scroll_end_) || needs_scroll_end_);
+ DCHECK(enable_scroll_latching_ ||
+ (synthetic && !needs_scroll_end_when_scroll_latching_disabled_) ||
+ needs_scroll_end_when_scroll_latching_disabled_);
+
+ DCHECK(scroll_in_progress_);
+ scroll_in_progress_ = false;
WebGestureEvent scroll_end(update_event);
scroll_end.SetTimeStampSeconds(
@@ -312,8 +325,8 @@ void MouseWheelEventQueue::SendScrollEnd(WebGestureEvent update_event,
update_event.data.scroll_update.delta_units;
if (!synthetic) {
- needs_scroll_begin_ = true;
- needs_scroll_end_ = false;
+ needs_scroll_begin_when_scroll_latching_disabled_ = true;
+ needs_scroll_end_when_scroll_latching_disabled_ = false;
}
client_->ForwardGestureEventWithLatencyInfo(
scroll_end, ui::LatencyInfo(ui::SourceEventType::WHEEL));
@@ -322,7 +335,12 @@ void MouseWheelEventQueue::SendScrollEnd(WebGestureEvent update_event,
void MouseWheelEventQueue::SendScrollBegin(
const WebGestureEvent& gesture_update,
bool synthetic) {
- DCHECK((synthetic && !needs_scroll_begin_) || needs_scroll_begin_);
+ DCHECK(enable_scroll_latching_ ||
+ (synthetic && !needs_scroll_begin_when_scroll_latching_disabled_) ||
+ needs_scroll_begin_when_scroll_latching_disabled_);
+
+ DCHECK(!scroll_in_progress_);
+ scroll_in_progress_ = true;
WebGestureEvent scroll_begin(gesture_update);
scroll_begin.SetType(WebInputEvent::kGestureScrollBegin);
@@ -337,10 +355,14 @@ void MouseWheelEventQueue::SendScrollBegin(
scroll_begin.data.scroll_begin.delta_hint_units =
gesture_update.data.scroll_update.delta_units;
- needs_scroll_begin_ = false;
- needs_scroll_end_ = true;
+ needs_scroll_begin_when_scroll_latching_disabled_ = false;
+ needs_scroll_end_when_scroll_latching_disabled_ = true;
client_->ForwardGestureEventWithLatencyInfo(
scroll_begin, ui::LatencyInfo(ui::SourceEventType::WHEEL));
}
+void MouseWheelEventQueue::RecordLatchingUmaMetric(bool latched) {
+ UMA_HISTOGRAM_BOOLEAN("WheelScrolling.WasLatched", latched);
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.h b/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.h
index ba90b5ed9cd..a724bb7661c 100644
--- a/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.h
+++ b/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.h
@@ -11,7 +11,8 @@
#include "base/time/time.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
namespace content {
@@ -30,6 +31,7 @@ class CONTENT_EXPORT MouseWheelEventQueueClient {
const blink::WebGestureEvent& event,
const ui::LatencyInfo& latency_info) = 0;
virtual void OnMouseWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) = 0;
};
@@ -54,7 +56,8 @@ class CONTENT_EXPORT MouseWheelEventQueue {
// Notifies the queue that a mouse wheel event has been processed by the
// renderer.
- void ProcessMouseWheelAck(InputEventAckState ack_result,
+ void ProcessMouseWheelAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result,
const ui::LatencyInfo& latency_info);
// When GestureScrollBegin is received, and it is a different source
@@ -77,6 +80,7 @@ class CONTENT_EXPORT MouseWheelEventQueue {
void SendScrollEnd(blink::WebGestureEvent update_event, bool synthetic);
void SendScrollBegin(const blink::WebGestureEvent& gesture_update,
bool synthetic);
+ void RecordLatchingUmaMetric(bool latched);
MouseWheelEventQueueClient* client_;
@@ -84,11 +88,16 @@ class CONTENT_EXPORT MouseWheelEventQueue {
std::unique_ptr<QueuedWebMouseWheelEvent> event_sent_for_gesture_ack_;
// True if a non-synthetic GSB needs to be sent before a GSU is sent.
- bool needs_scroll_begin_;
+ // This variable is used only when scroll latching is disabled.
+ bool needs_scroll_begin_when_scroll_latching_disabled_;
// True if a non-synthetic GSE needs to be sent because a non-synthetic
// GSB has been sent in the past.
- bool needs_scroll_end_;
+ // This variable is used only when scroll latching is disabled.
+ bool needs_scroll_end_when_scroll_latching_disabled_;
+
+ // True when a GSB is sent and its corresponding GSE is not sent.
+ bool scroll_in_progress_;
// True if the touchpad and wheel scroll latching flag is enabled.
bool enable_scroll_latching_;
diff --git a/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc b/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc
index c65b4dc9709..9db17edb664 100644
--- a/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc
@@ -13,6 +13,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -197,6 +198,7 @@ class MouseWheelEventQueueTest
}
void OnMouseWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override {
++acked_event_count_;
last_acked_event_ = event.event;
@@ -236,7 +238,8 @@ class MouseWheelEventQueueTest
}
void SendMouseWheelEventAck(InputEventAckState ack_result) {
- queue_->ProcessMouseWheelAck(ack_result, ui::LatencyInfo());
+ queue_->ProcessMouseWheelAck(InputEventAckSource::COMPOSITOR_THREAD,
+ ack_result, ui::LatencyInfo());
}
void SendMouseWheel(float x,
@@ -810,6 +813,30 @@ TEST_P(MouseWheelEventQueueTest, WheelScrollLatching) {
EXPECT_EQ(1U, GetAndResetSentEventCount());
}
+TEST_P(MouseWheelEventQueueTest, WheelScrollingWasLatchedHistogramCheck) {
+ base::HistogramTester histogram_tester;
+ const char latching_histogram_name[] = "WheelScrolling.WasLatched";
+
+ SendMouseWheelPossiblyIncludingPhase(
+ !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
+ kWheelScrollGlobalX, kWheelScrollGlobalY, 1, 1, 0, false,
+ WebMouseWheelEvent::kPhaseBegan, WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ histogram_tester.ExpectBucketCount(latching_histogram_name, 0, 1);
+
+ SendMouseWheelPossiblyIncludingPhase(
+ !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
+ kWheelScrollGlobalX, kWheelScrollGlobalY, 1, 1, 0, false,
+ WebMouseWheelEvent::kPhaseChanged, WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ if (scroll_latching_enabled_) {
+ histogram_tester.ExpectBucketCount(latching_histogram_name, 0, 1);
+ histogram_tester.ExpectBucketCount(latching_histogram_name, 1, 1);
+ } else {
+ histogram_tester.ExpectBucketCount(latching_histogram_name, 0, 2);
+ }
+}
+
INSTANTIATE_TEST_CASE_P(MouseWheelEventQueueTests,
MouseWheelEventQueueTest,
testing::Values(kWheelScrollingModeNone,
diff --git a/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc b/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc
index 1fc5861f670..9e9e4c75f95 100644
--- a/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc
+++ b/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc
@@ -13,11 +13,14 @@ namespace content {
MouseWheelPhaseHandler::MouseWheelPhaseHandler(
RenderWidgetHostImpl* const host,
RenderWidgetHostViewBase* const host_view)
- : host_(RenderWidgetHostImpl::From(host)), host_view_(host_view) {}
+ : host_(RenderWidgetHostImpl::From(host)),
+ host_view_(host_view),
+ scroll_phase_state_(SCROLL_STATE_UNKNOWN) {}
void MouseWheelPhaseHandler::AddPhaseIfNeededAndScheduleEndEvent(
blink::WebMouseWheelEvent& mouse_wheel_event,
bool should_route_event) {
+
bool has_phase =
mouse_wheel_event.phase != blink::WebMouseWheelEvent::kPhaseNone ||
mouse_wheel_event.momentum_phase != blink::WebMouseWheelEvent::kPhaseNone;
@@ -25,7 +28,7 @@ void MouseWheelPhaseHandler::AddPhaseIfNeededAndScheduleEndEvent(
if (mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseEnded) {
// Don't send the wheel end event immediately, start a timer instead to
// see whether momentum phase of the scrolling starts or not.
- ScheduleMouseWheelEndDispatching(mouse_wheel_event, should_route_event);
+ ScheduleMouseWheelEndDispatching(should_route_event);
} else if (mouse_wheel_event.phase ==
blink::WebMouseWheelEvent::kPhaseBegan) {
// A new scrolling sequence has started, send the pending wheel end
@@ -39,18 +42,35 @@ void MouseWheelPhaseHandler::AddPhaseIfNeededAndScheduleEndEvent(
IgnorePendingWheelEndEvent();
}
} else { // !has_phase
- if (!mouse_wheel_end_dispatch_timer_.IsRunning()) {
- mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
- ScheduleMouseWheelEndDispatching(mouse_wheel_event, should_route_event);
- } else { // mouse_wheel_end_dispatch_timer_.IsRunning()
- bool non_zero_delta =
- mouse_wheel_event.delta_x || mouse_wheel_event.delta_y;
- mouse_wheel_event.phase =
- non_zero_delta ? blink::WebMouseWheelEvent::kPhaseChanged
- : blink::WebMouseWheelEvent::kPhaseStationary;
- mouse_wheel_end_dispatch_timer_.Reset();
+ switch (scroll_phase_state_) {
+ case SCROLL_STATE_UNKNOWN: {
+ mouse_wheel_event.has_synthetic_phase = true;
+ if (!mouse_wheel_end_dispatch_timer_.IsRunning()) {
+ mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
+ ScheduleMouseWheelEndDispatching(should_route_event);
+ } else { // mouse_wheel_end_dispatch_timer_.IsRunning()
+ bool non_zero_delta =
+ mouse_wheel_event.delta_x || mouse_wheel_event.delta_y;
+ mouse_wheel_event.phase =
+ non_zero_delta ? blink::WebMouseWheelEvent::kPhaseChanged
+ : blink::WebMouseWheelEvent::kPhaseStationary;
+ mouse_wheel_end_dispatch_timer_.Reset();
+ }
+ break;
+ }
+ case SCROLL_MAY_BEGIN:
+ mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
+ scroll_phase_state_ = SCROLL_IN_PROGRESS;
+ break;
+ case SCROLL_IN_PROGRESS:
+ mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseChanged;
+ break;
+ default:
+ NOTREACHED();
}
}
+
+ last_mouse_wheel_event_ = mouse_wheel_event;
}
void MouseWheelPhaseHandler::DispatchPendingWheelEndEvent() {
@@ -66,40 +86,56 @@ void MouseWheelPhaseHandler::IgnorePendingWheelEndEvent() {
mouse_wheel_end_dispatch_timer_.Stop();
}
+void MouseWheelPhaseHandler::ResetScrollSequence() {
+ scroll_phase_state_ = SCROLL_STATE_UNKNOWN;
+}
+
+void MouseWheelPhaseHandler::SendWheelEndIfNeeded() {
+ if (scroll_phase_state_ == SCROLL_IN_PROGRESS) {
+ DCHECK(host_);
+ bool should_route_event =
+ host_->delegate() && host_->delegate()->GetInputEventRouter();
+ SendSyntheticWheelEventWithPhaseEnded(should_route_event);
+ }
+
+ ResetScrollSequence();
+}
+
+void MouseWheelPhaseHandler::ScrollingMayBegin() {
+ scroll_phase_state_ = SCROLL_MAY_BEGIN;
+}
+
void MouseWheelPhaseHandler::SendSyntheticWheelEventWithPhaseEnded(
- blink::WebMouseWheelEvent last_mouse_wheel_event,
bool should_route_event) {
DCHECK(host_view_->wheel_scroll_latching_enabled());
- blink::WebMouseWheelEvent mouse_wheel_event = last_mouse_wheel_event;
- mouse_wheel_event.SetTimeStampSeconds(
+ last_mouse_wheel_event_.SetTimeStampSeconds(
ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- mouse_wheel_event.delta_x = 0;
- mouse_wheel_event.delta_y = 0;
- mouse_wheel_event.wheel_ticks_x = 0;
- mouse_wheel_event.wheel_ticks_y = 0;
- mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
- mouse_wheel_event.dispatch_type =
+ last_mouse_wheel_event_.delta_x = 0;
+ last_mouse_wheel_event_.delta_y = 0;
+ last_mouse_wheel_event_.wheel_ticks_x = 0;
+ last_mouse_wheel_event_.wheel_ticks_y = 0;
+ last_mouse_wheel_event_.phase = blink::WebMouseWheelEvent::kPhaseEnded;
+ last_mouse_wheel_event_.dispatch_type =
blink::WebInputEvent::DispatchType::kEventNonBlocking;
if (should_route_event) {
host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(
- host_view_, &mouse_wheel_event,
+ host_view_, &last_mouse_wheel_event_,
ui::LatencyInfo(ui::SourceEventType::WHEEL));
} else {
host_view_->ProcessMouseWheelEvent(
- mouse_wheel_event, ui::LatencyInfo(ui::SourceEventType::WHEEL));
+ last_mouse_wheel_event_, ui::LatencyInfo(ui::SourceEventType::WHEEL));
}
}
void MouseWheelPhaseHandler::ScheduleMouseWheelEndDispatching(
- blink::WebMouseWheelEvent wheel_event,
bool should_route_event) {
mouse_wheel_end_dispatch_timer_.Start(
FROM_HERE,
base::TimeDelta::FromMilliseconds(
kDefaultMouseWheelLatchingTransactionMs),
base::Bind(&MouseWheelPhaseHandler::SendSyntheticWheelEventWithPhaseEnded,
- base::Unretained(this), wheel_event, should_route_event));
+ base::Unretained(this), should_route_event));
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.h b/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.h
index aa4a20e4942..1399bed5fe4 100644
--- a/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.h
+++ b/chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.h
@@ -7,6 +7,7 @@
#include "base/timer/timer.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
+#include "third_party/WebKit/public/platform/WebMouseWheelEvent.h"
namespace content {
class RenderWidgetHostImpl;
@@ -16,6 +17,18 @@ class RenderWidgetHostViewBase;
// phase = |kPhaseEnded| will be sent after the last wheel event.
const int64_t kDefaultMouseWheelLatchingTransactionMs = 100;
+// On ChromeOS wheel events don't have phase information; However, whenever the
+// user puts down or lifts their fingers a GFC or GFS is received.
+enum ScrollPhaseState {
+ // Scrolling with normal mouse wheels doesn't give any information about the
+ // state of scrolling.
+ SCROLL_STATE_UNKNOWN = 0,
+ // Shows that the user has put their fingers down and a scroll may start.
+ SCROLL_MAY_BEGIN,
+ // Scrolling has started and the user hasn't lift their fingers, yet.
+ SCROLL_IN_PROGRESS,
+};
+
class MouseWheelPhaseHandler {
public:
MouseWheelPhaseHandler(RenderWidgetHostImpl* const host,
@@ -27,20 +40,24 @@ class MouseWheelPhaseHandler {
bool should_route_event);
void DispatchPendingWheelEndEvent();
void IgnorePendingWheelEndEvent();
+ void ResetScrollSequence();
+ void SendWheelEndIfNeeded();
+ void ScrollingMayBegin();
+
bool HasPendingWheelEndEvent() const {
return mouse_wheel_end_dispatch_timer_.IsRunning();
}
private:
void SendSyntheticWheelEventWithPhaseEnded(
- blink::WebMouseWheelEvent last_mouse_wheel_event,
bool should_route_event);
- void ScheduleMouseWheelEndDispatching(blink::WebMouseWheelEvent wheel_event,
- bool should_route_event);
+ void ScheduleMouseWheelEndDispatching(bool should_route_event);
RenderWidgetHostImpl* const host_;
RenderWidgetHostViewBase* const host_view_;
base::OneShotTimer mouse_wheel_end_dispatch_timer_;
+ blink::WebMouseWheelEvent last_mouse_wheel_event_;
+ ScrollPhaseState scroll_phase_state_;
DISALLOW_COPY_AND_ASSIGN(MouseWheelPhaseHandler);
};
diff --git a/chromium/content/browser/renderer_host/input/non_blocking_event_browsertest.cc b/chromium/content/browser/renderer_host/input/non_blocking_event_browsertest.cc
index 52edfbb38f2..c8c34484d9c 100644
--- a/chromium/content/browser/renderer_host/input/non_blocking_event_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/non_blocking_event_browsertest.cc
@@ -128,8 +128,8 @@ class NonBlockingEventBrowserTest : public ContentBrowserTest {
EXPECT_EQ(kWebsiteHeight, scrollHeight);
FrameWatcher frame_watcher(shell()->web_contents());
- scoped_refptr<InputMsgWatcher> input_msg_watcher(new InputMsgWatcher(
- GetWidgetHost(), blink::WebInputEvent::kMouseWheel));
+ auto input_msg_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kMouseWheel);
blink::WebMouseWheelEvent wheel_event =
SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, -53, 0, true);
diff --git a/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.cc b/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.cc
index 329290e7d12..c80d26db707 100644
--- a/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.cc
+++ b/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.cc
@@ -92,7 +92,7 @@ void PassthroughTouchEventQueue::QueueEvent(
? INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS
: INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
TouchEventWithLatencyInfoAndAckState event_with_ack_state = event;
- event_with_ack_state.set_ack_state(ack_state);
+ event_with_ack_state.set_ack_info(InputEventAckSource::BROWSER, ack_state);
outstanding_touches_.insert(event_with_ack_state);
AckCompletedEvents();
return;
@@ -113,6 +113,7 @@ void PassthroughTouchEventQueue::PrependTouchScrollNotification() {
}
void PassthroughTouchEventQueue::ProcessTouchAck(
+ InputEventAckSource ack_source,
InputEventAckState ack_result,
const LatencyInfo& latency_info,
const uint32_t unique_touch_event_id) {
@@ -134,7 +135,7 @@ void PassthroughTouchEventQueue::ProcessTouchAck(
TouchEventWithLatencyInfoAndAckState event = *touch_event_iter;
touch_event_iter = outstanding_touches_.erase(touch_event_iter);
event.latency.AddNewLatencyFrom(latency_info);
- event.set_ack_state(ack_result);
+ event.set_ack_info(ack_source, ack_result);
outstanding_touches_.insert(touch_event_iter, event);
AckCompletedEvents();
@@ -200,8 +201,9 @@ void PassthroughTouchEventQueue::FlushQueue() {
TouchEventWithLatencyInfoAndAckState event = *iter;
outstanding_touches_.erase(iter);
if (event.ack_state() == INPUT_EVENT_ACK_STATE_UNKNOWN)
- event.set_ack_state(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- AckTouchEventToClient(event, event.ack_state());
+ event.set_ack_info(InputEventAckSource::BROWSER,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ AckTouchEventToClient(event, event.ack_source(), event.ack_state());
}
}
@@ -217,18 +219,19 @@ void PassthroughTouchEventQueue::AckCompletedEvents() {
break;
TouchEventWithLatencyInfoAndAckState event = *iter;
outstanding_touches_.erase(iter);
- AckTouchEventToClient(event, event.ack_state());
+ AckTouchEventToClient(event, event.ack_source(), event.ack_state());
}
}
void PassthroughTouchEventQueue::AckTouchEventToClient(
const TouchEventWithLatencyInfo& acked_event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
UpdateTouchConsumerStates(acked_event.event, ack_result);
// Skip ack for TouchScrollStarted since it was synthesized within the queue.
if (acked_event.event.GetType() != WebInputEvent::kTouchScrollStarted) {
- client_->OnTouchEventAck(acked_event, ack_result);
+ client_->OnTouchEventAck(acked_event, ack_source, ack_result);
}
}
diff --git a/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.h b/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.h
index cae55abf245..d89c373c669 100644
--- a/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.h
+++ b/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue.h
@@ -33,7 +33,8 @@ class CONTENT_EXPORT PassthroughTouchEventQueue : public TouchEventQueue {
void PrependTouchScrollNotification() override;
- void ProcessTouchAck(InputEventAckState ack_result,
+ void ProcessTouchAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result,
const ui::LatencyInfo& latency_info,
const uint32_t unique_touch_event_id) override;
void OnGestureScrollEvent(
@@ -72,9 +73,14 @@ class CONTENT_EXPORT PassthroughTouchEventQueue : public TouchEventQueue {
TouchEventWithLatencyInfoAndAckState(const TouchEventWithLatencyInfo&);
bool operator<(const TouchEventWithLatencyInfoAndAckState&) const;
InputEventAckState ack_state() const { return ack_state_; }
- void set_ack_state(InputEventAckState state) { ack_state_ = state; }
+ InputEventAckSource ack_source() const { return ack_source_; }
+ void set_ack_info(InputEventAckSource source, InputEventAckState state) {
+ ack_source_ = source;
+ ack_state_ = state;
+ }
private:
+ InputEventAckSource ack_source_;
InputEventAckState ack_state_;
};
@@ -88,6 +94,7 @@ class CONTENT_EXPORT PassthroughTouchEventQueue : public TouchEventQueue {
PreFilterResult FilterBeforeForwarding(const blink::WebTouchEvent& event);
void AckTouchEventToClient(const TouchEventWithLatencyInfo& acked_event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result);
void SendTouchEventImmediately(TouchEventWithLatencyInfo* touch,
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 dc29a530184..93cf482a60e 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
@@ -74,6 +74,7 @@ class PassthroughTouchEventQueueTest : public testing::Test,
}
void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override {
++acked_event_count_;
if (followup_touch_event_) {
@@ -139,21 +140,22 @@ class PassthroughTouchEventQueueTest : public testing::Test,
void SendTouchEventAck(InputEventAckState ack_result) {
DCHECK(!sent_events_ids_.empty());
- queue_->ProcessTouchAck(ack_result, ui::LatencyInfo(),
- sent_events_ids_.front());
+ queue_->ProcessTouchAck(InputEventAckSource::COMPOSITOR_THREAD, ack_result,
+ ui::LatencyInfo(), sent_events_ids_.front());
sent_events_ids_.pop_front();
}
void SendTouchEventAckLast(InputEventAckState ack_result) {
DCHECK(!sent_events_ids_.empty());
- queue_->ProcessTouchAck(ack_result, ui::LatencyInfo(),
- sent_events_ids_.back());
+ queue_->ProcessTouchAck(InputEventAckSource::COMPOSITOR_THREAD, ack_result,
+ ui::LatencyInfo(), sent_events_ids_.back());
sent_events_ids_.pop_back();
}
void SendTouchEventAckWithID(InputEventAckState ack_result,
int unique_event_id) {
- queue_->ProcessTouchAck(ack_result, ui::LatencyInfo(), 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());
diff --git a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
index e521794e416..c007c998615 100644
--- a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
+++ b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
@@ -9,14 +9,12 @@
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/rand_util.h"
#include "build/build_config.h"
#include "components/rappor/public/rappor_utils.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
-#include "services/metrics/public/cpp/ukm_entry_builder.h"
#include "ui/events/blink/web_input_event_traits.h"
#include "ui/latency/latency_histogram_macros.h"
@@ -30,7 +28,10 @@ using ui::LatencyInfo;
namespace content {
namespace {
-constexpr int kSamplingInterval = 10;
+ukm::SourceId GenerateUkmSourceId() {
+ ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
+ return ukm_recorder ? ukm_recorder->GetNewSourceID() : ukm::kInvalidSourceId;
+}
std::string WebInputEventTypeToInputModalityString(WebInputEvent::Type type) {
if (type == blink::WebInputEvent::kMouseWheel) {
@@ -142,21 +143,15 @@ void RecordEQTAccuracy(base::TimeDelta queueing_time,
} // namespace
RenderWidgetHostLatencyTracker::RenderWidgetHostLatencyTracker(
- bool metric_sampling)
- : ukm_source_id_(-1),
+ bool metric_sampling,
+ RenderWidgetHostDelegate* delegate)
+ : LatencyTracker(metric_sampling, GenerateUkmSourceId()),
last_event_id_(0),
latency_component_id_(0),
- device_scale_factor_(1),
has_seen_first_gesture_scroll_update_(false),
active_multi_finger_gesture_(false),
touch_start_default_prevented_(false),
- metric_sampling_(metric_sampling),
- metric_sampling_events_since_last_sample_(-1),
- render_widget_host_delegate_(nullptr) {
- if (metric_sampling)
- metric_sampling_events_since_last_sample_ =
- base::RandUint64() % kSamplingInterval;
-}
+ render_widget_host_delegate_(delegate) {}
RenderWidgetHostLatencyTracker::~RenderWidgetHostLatencyTracker() {}
@@ -183,11 +178,13 @@ void RenderWidgetHostLatencyTracker::ComputeInputLatencyHistograms(
return;
}
+ // The event will have gone through OnInputEvent(). So the BEGIN_RWH component
+ // should always be available here.
LatencyInfo::LatencyComponent rwh_component;
- if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- latency_component_id, &rwh_component)) {
- return;
- }
+ bool found_component =
+ latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
+ latency_component_id, &rwh_component);
+ DCHECK(found_component);
DCHECK_EQ(rwh_component.event_count, 1u);
bool multi_finger_touch_gesture =
@@ -197,18 +194,25 @@ void RenderWidgetHostLatencyTracker::ComputeInputLatencyHistograms(
if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0,
&ui_component)) {
DCHECK_EQ(ui_component.event_count, 1u);
+ CONFIRM_EVENT_TIMES_EXIST(ui_component, rwh_component);
base::TimeDelta ui_delta =
rwh_component.last_event_time - ui_component.first_event_time;
if (latency.source_event_type() == ui::SourceEventType::WHEEL) {
- UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.WheelUI",
- ui_delta.InMicroseconds(), 1, 20000, 100);
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.Latency.Browser.WheelUI",
+ std::max(static_cast<int64_t>(0), ui_delta.InMicroseconds()), 1,
+ 20000, 100);
} else if (latency.source_event_type() == ui::SourceEventType::TOUCH) {
- UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.TouchUI",
- ui_delta.InMicroseconds(), 1, 20000, 100);
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.Latency.Browser.TouchUI",
+ std::max(static_cast<int64_t>(0), ui_delta.InMicroseconds()), 1,
+ 20000, 100);
} else if (latency.source_event_type() == ui::SourceEventType::KEY_PRESS) {
- UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.KeyPressUI",
- ui_delta.InMicroseconds(), 1, 20000, 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.Latency.Browser.KeyPressUI",
+ std::max(static_cast<int64_t>(0), ui_delta.InMicroseconds()), 1,
+ 20000, 50);
} else {
// We should only report these histograms for wheel, touch and keyboard.
NOTREACHED();
@@ -272,8 +276,13 @@ void RenderWidgetHostLatencyTracker::OnInputEvent(
DCHECK(latency);
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- static uint64_t global_trace_id = 0;
- latency->set_trace_id(++global_trace_id);
+ OnEventStart(latency);
+ if (!set_url_for_ukm_ && render_widget_host_delegate_ &&
+ ukm_source_id() != ukm::kInvalidSourceId) {
+ render_widget_host_delegate_->UpdateUrlForUkmSource(ukm::UkmRecorder::Get(),
+ ukm_source_id());
+ set_url_for_ukm_ = true;
+ }
if (event.GetType() == WebInputEvent::kTouchStart) {
const WebTouchEvent& touch_event =
@@ -287,14 +296,16 @@ void RenderWidgetHostLatencyTracker::OnInputEvent(
event.GetType() == WebInputEvent::kRawKeyDown);
}
- if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- latency_component_id_, NULL)) {
- return;
- }
+ // This is the only place to add the BEGIN_RWH component. So this component
+ // should not already be present in the latency info.
+ bool found_component =
+ latency->FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
+ latency_component_id_, nullptr);
+ DCHECK(!found_component);
if (event.TimeStampSeconds() &&
!latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0,
- NULL)) {
+ nullptr)) {
base::TimeTicks timestamp_now = base::TimeTicks::Now();
base::TimeTicks timestamp_original =
base::TimeTicks() +
@@ -365,8 +376,9 @@ void RenderWidgetHostLatencyTracker::OnInputEventAck(
latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0);
// If this event couldn't have caused a gesture event, and it didn't trigger
- // rendering, we're done processing it.
- if (!rendering_scheduled) {
+ // rendering, we're done processing it. If the event got coalesced then
+ // terminate it as well.
+ if (!rendering_scheduled || latency->coalesced()) {
latency->AddLatencyNumber(
ui::INPUT_EVENT_LATENCY_TERMINATED_NO_SWAP_COMPONENT, 0, 0);
}
@@ -383,16 +395,11 @@ void RenderWidgetHostLatencyTracker::OnSwapCompositorFrame(
}
}
-void RenderWidgetHostLatencyTracker::SetDelegate(
- RenderWidgetHostDelegate* delegate) {
- render_widget_host_delegate_ = delegate;
-}
-
void RenderWidgetHostLatencyTracker::ReportRapporScrollLatency(
const std::string& name,
const LatencyInfo::LatencyComponent& start_component,
const LatencyInfo::LatencyComponent& end_component) {
- CONFIRM_VALID_TIMING(start_component, end_component)
+ CONFIRM_EVENT_TIMES_EXIST(start_component, end_component)
rappor::RapporService* rappor_service =
GetContentClient()->browser()->GetRapporService();
if (rappor_service && render_widget_host_delegate_) {
@@ -401,48 +408,12 @@ void RenderWidgetHostLatencyTracker::ReportRapporScrollLatency(
render_widget_host_delegate_->AddDomainInfoToRapporSample(sample.get());
sample->SetUInt64Field(
"Latency",
- (end_component.last_event_time - start_component.first_event_time)
- .InMicroseconds(),
+ std::max(static_cast<int64_t>(0), (end_component.last_event_time -
+ start_component.first_event_time)
+ .InMicroseconds()),
rappor::NO_NOISE);
rappor_service->RecordSample(name, std::move(sample));
}
}
-ukm::SourceId RenderWidgetHostLatencyTracker::GetUkmSourceId() {
- ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
- if (ukm_recorder && ukm_source_id_ == -1 && render_widget_host_delegate_) {
- ukm_source_id_ = ukm_recorder->GetNewSourceID();
- render_widget_host_delegate_->UpdateUrlForUkmSource(ukm_recorder,
- ukm_source_id_);
- }
- return ukm_source_id_;
-}
-
-void RenderWidgetHostLatencyTracker::ReportUkmScrollLatency(
- const std::string& event_name,
- const std::string& metric_name,
- const LatencyInfo::LatencyComponent& start_component,
- const LatencyInfo::LatencyComponent& end_component) {
- CONFIRM_VALID_TIMING(start_component, end_component)
-
- // Only report a subset of this metric as the volume is too high.
- if (event_name == "Event.ScrollUpdate.Touch") {
- metric_sampling_events_since_last_sample_++;
- metric_sampling_events_since_last_sample_ %= kSamplingInterval;
- if (metric_sampling_ && metric_sampling_events_since_last_sample_)
- return;
- }
-
- ukm::SourceId ukm_source_id = GetUkmSourceId();
- ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
-
- if (ukm_source_id == -1 || !ukm_recorder)
- return;
-
- std::unique_ptr<ukm::UkmEntryBuilder> builder =
- ukm_recorder->GetEntryBuilder(ukm_source_id, event_name.c_str());
- builder->AddMetric(metric_name.c_str(), (end_component.last_event_time -
- start_component.first_event_time)
- .InMicroseconds());
-}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h
index 4e5d5c56b97..017f13c3ede 100644
--- a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h
+++ b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h
@@ -12,8 +12,7 @@
#include "base/macros.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
-#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "content/public/common/input_event_ack_state.h"
#include "ui/latency/latency_info.h"
#include "ui/latency/latency_tracker.h"
@@ -26,8 +25,9 @@ class RenderWidgetHostDelegate;
class CONTENT_EXPORT RenderWidgetHostLatencyTracker
: public ui::LatencyTracker {
public:
- explicit RenderWidgetHostLatencyTracker(bool metric_sampling);
- ~RenderWidgetHostLatencyTracker();
+ RenderWidgetHostLatencyTracker(bool metric_sampling,
+ RenderWidgetHostDelegate* delegate);
+ virtual ~RenderWidgetHostLatencyTracker();
// Associates the latency tracker with a given route and process.
// Called once after the RenderWidgetHost is fully initialized.
@@ -57,41 +57,23 @@ class CONTENT_EXPORT RenderWidgetHostLatencyTracker
// update from the renderer.
void OnSwapCompositorFrame(std::vector<ui::LatencyInfo>* latencies);
- // WebInputEvent coordinates are in DPIs, while LatencyInfo expects
- // coordinates in device pixels.
- void set_device_scale_factor(float device_scale_factor) {
- device_scale_factor_ = device_scale_factor;
- }
+ void reset_delegate() { render_widget_host_delegate_ = nullptr; }
// Returns the ID that uniquely describes this component to the latency
// subsystem.
int64_t latency_component_id() const { return latency_component_id_; }
- // A delegate is used to get the url to be stored in Rappor Sample.
- // If delegate is null no Rappor sample will be reported.
- void SetDelegate(RenderWidgetHostDelegate*);
-
private:
- ukm::SourceId GetUkmSourceId();
-
// ui::LatencyTracker:
void ReportRapporScrollLatency(
const std::string& name,
const ui::LatencyInfo::LatencyComponent& start_component,
const ui::LatencyInfo::LatencyComponent& end_component) override;
- // ui::LatencyTracker:
- void ReportUkmScrollLatency(
- const std::string& event_name,
- const std::string& metric_name,
- const ui::LatencyInfo::LatencyComponent& start_component,
- const ui::LatencyInfo::LatencyComponent& end_component) override;
-
- ukm::SourceId ukm_source_id_;
int64_t last_event_id_;
int64_t latency_component_id_;
- float device_scale_factor_;
bool has_seen_first_gesture_scroll_update_;
+ bool set_url_for_ukm_ = false;
// Whether the current stream of touch events includes more than one active
// touch point. This is set in OnInputEvent, and cleared in OnInputEventAck.
bool active_multi_finger_gesture_;
@@ -99,12 +81,6 @@ class CONTENT_EXPORT RenderWidgetHostLatencyTracker
// default action prevented. Only valid for single finger gestures.
bool touch_start_default_prevented_;
- // Whether the sampling is needed for high volume metrics. This will be off
- // when we are in unit tests. This is a temporary field so we can come up with
- // a more permanent solution for crbug.com/739169.
- bool metric_sampling_;
- int metric_sampling_events_since_last_sample_;
-
RenderWidgetHostDelegate* render_widget_host_delegate_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostLatencyTracker);
diff --git a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc
index 459fac321db..5bf751e4b5d 100644
--- a/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc
@@ -5,7 +5,6 @@
#include "content/browser/renderer_host/input/render_widget_host_latency_tracker.h"
#include "base/metrics/metrics_hashes.h"
#include "base/test/histogram_tester.h"
-#include "components/metrics/proto/ukm/entry.pb.h"
#include "components/rappor/public/rappor_utils.h"
#include "components/rappor/test_rappor_service.h"
#include "components/ukm/test_ukm_recorder.h"
@@ -97,9 +96,7 @@ class RenderWidgetHostLatencyTrackerTestBrowserClient
class RenderWidgetHostLatencyTrackerTest
: public RenderViewHostImplTestHarness {
public:
- RenderWidgetHostLatencyTrackerTest()
- : tracker_(false), old_browser_client_(NULL) {
- tracker_.Initialize(kTestRoutingId, kTestProcessId);
+ RenderWidgetHostLatencyTrackerTest() : old_browser_client_(nullptr) {
ResetHistograms();
}
@@ -146,43 +143,18 @@ class RenderWidgetHostLatencyTrackerTest
}
}
- ::testing::AssertionResult AssertUkmReported(const char* event_name,
- const char* metric_name) {
+ void ExpectUkmReported(const char* event_name,
+ const char* metric_name,
+ size_t expected_count) {
const ukm::TestUkmRecorder* ukm_recoder =
test_browser_client_.GetTestUkmRecorder();
- size_t actual_event_count = 0;
- for (size_t i = 0; i < ukm_recoder->entries_count(); ++i) {
- const ukm::mojom::UkmEntry* entry = ukm_recoder->GetEntry(i);
- if (entry->event_hash != base::HashMetricName(event_name))
- continue;
-
- const ukm::UkmSource* source =
- ukm_recoder->GetSourceForSourceId(entry->source_id);
- if (!source)
- return ::testing::AssertionFailure() << "Source should not be null";
-
- if (actual_event_count >= 1)
- break;
-
- if (GURL(kUrl) != source->url())
- return ::testing::AssertionFailure() << "Incorrect URL is reported.";
-
- actual_event_count++;
- if (entry->metrics.size() != 1)
- return ::testing::AssertionFailure()
- << event_name << " entry expected only 1 metric but got "
- << entry->metrics.size();
-
- if (entry->metrics[0]->metric_hash != base::HashMetricName(metric_name))
- return ::testing::AssertionFailure()
- << "Expected a metric named " << metric_name;
+ auto entries = ukm_recoder->GetEntriesByName(event_name);
+ EXPECT_EQ(expected_count, entries.size());
+ for (const auto* const entry : entries) {
+ ukm_recoder->ExpectEntrySourceHasUrl(entry, GURL(kUrl));
+ EXPECT_TRUE(ukm_recoder->EntryHasMetric(entry, metric_name));
}
- if (actual_event_count != 1)
- return ::testing::AssertionFailure()
- << event_name << " expected " << 1 << " entry but got "
- << actual_event_count;
- return ::testing::AssertionSuccess();
}
::testing::AssertionResult HistogramSizeEq(const char* histogram_name,
@@ -198,7 +170,7 @@ class RenderWidgetHostLatencyTrackerTest
}
}
- RenderWidgetHostLatencyTracker* tracker() { return &tracker_; }
+ RenderWidgetHostLatencyTracker* tracker() { return tracker_.get(); }
void ResetHistograms() {
histogram_tester_.reset(new base::HistogramTester());
}
@@ -210,7 +182,9 @@ class RenderWidgetHostLatencyTrackerTest
void SetUp() override {
RenderViewHostImplTestHarness::SetUp();
old_browser_client_ = SetBrowserClientForTesting(&test_browser_client_);
- tracker_.SetDelegate(contents());
+ tracker_ =
+ std::make_unique<RenderWidgetHostLatencyTracker>(false, contents());
+ tracker_->Initialize(kTestRoutingId, kTestProcessId);
}
void TearDown() override {
@@ -224,11 +198,68 @@ class RenderWidgetHostLatencyTrackerTest
const int kTestRoutingId = 3;
const int kTestProcessId = 1;
std::unique_ptr<base::HistogramTester> histogram_tester_;
- RenderWidgetHostLatencyTracker tracker_;
+ std::unique_ptr<RenderWidgetHostLatencyTracker> tracker_;
RenderWidgetHostLatencyTrackerTestBrowserClient test_browser_client_;
ContentBrowserClient* old_browser_client_;
};
+TEST_F(RenderWidgetHostLatencyTrackerTest, TestValidEventTiming) {
+ base::TimeTicks now = base::TimeTicks::Now();
+
+ ui::LatencyInfo latency_info;
+ latency_info.set_trace_id(kTraceEventId);
+ latency_info.set_source_event_type(ui::SourceEventType::WHEEL);
+
+ latency_info.AddLatencyNumberWithTimestamp(
+ ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, 0, 0,
+ now + base::TimeDelta::FromMilliseconds(60), 1);
+
+ latency_info.AddLatencyNumberWithTimestamp(
+ ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, 0, 0,
+ now + base::TimeDelta::FromMilliseconds(50), 1);
+
+ latency_info.AddLatencyNumberWithTimestamp(
+ ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, 0, 0,
+ now + base::TimeDelta::FromMilliseconds(40), 1);
+
+ latency_info.AddLatencyNumberWithTimestamp(
+ ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, 0, 0,
+ now + base::TimeDelta::FromMilliseconds(30), 1);
+
+ latency_info.AddLatencyNumberWithTimestamp(
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
+ tracker()->latency_component_id(), 0,
+ now + base::TimeDelta::FromMilliseconds(20), 1);
+
+ latency_info.AddLatencyNumberWithTimestamp(
+ ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0,
+ now + base::TimeDelta::FromMilliseconds(10), 1);
+
+ latency_info.AddLatencyNumberWithTimestamp(
+ ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0, now, 1);
+
+ tracker()->OnGpuSwapBuffersCompleted(latency_info);
+
+ // When last_event_time of the end_component is less than the first_event_time
+ // of the start_component, zero is recorded instead of a negative value.
+ histogram_tester().ExpectUniqueSample(
+ "Event.Latency.ScrollBegin.Wheel.TimeToScrollUpdateSwapBegin2", 0, 1);
+ histogram_tester().ExpectUniqueSample(
+ "Event.Latency.Scroll.Wheel.TimeToScrollUpdateSwapBegin2", 0, 1);
+ histogram_tester().ExpectUniqueSample(
+ "Event.Latency.ScrollBegin.Wheel.TimeToHandled2_Impl", 0, 1);
+ histogram_tester().ExpectUniqueSample(
+ "Event.Latency.Scroll.Wheel.TimeToHandled2_Impl", 0, 1);
+ histogram_tester().ExpectUniqueSample(
+ "Event.Latency.ScrollBegin.Wheel.HandledToRendererSwap2_Impl", 0, 1);
+ histogram_tester().ExpectUniqueSample(
+ "Event.Latency.ScrollBegin.Wheel.RendererSwapToBrowserNotified2", 0, 1);
+ histogram_tester().ExpectUniqueSample(
+ "Event.Latency.ScrollBegin.Wheel.BrowserNotifiedToBeforeGpuSwap2", 0, 1);
+ histogram_tester().ExpectUniqueSample(
+ "Event.Latency.ScrollBegin.Wheel.GpuSwap2", 0, 1);
+}
+
TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToFirstScrollHistograms) {
const GURL url(kUrl);
size_t total_ukm_entry_count = 0;
@@ -258,14 +289,18 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToFirstScrollHistograms) {
// UKM metrics.
total_ukm_entry_count++;
- EXPECT_TRUE(AssertUkmReported("Event.ScrollBegin.Wheel",
- "TimeToScrollUpdateSwapBegin"));
+ ExpectUkmReported("Event.ScrollBegin.Wheel",
+ "TimeToScrollUpdateSwapBegin", total_ukm_entry_count);
// Rappor metrics.
EXPECT_TRUE(
RapporSampleAssert("Event.Latency.ScrollUpdate.Touch."
"TimeToScrollUpdateSwapBegin2",
0));
EXPECT_TRUE(
+ RapporSampleAssert("Event.Latency.ScrollUpdate.Wheel."
+ "TimeToScrollUpdateSwapBegin2",
+ 0));
+ EXPECT_TRUE(
RapporSampleAssert("Event.Latency.ScrollBegin.Touch."
"TimeToScrollUpdateSwapBegin2",
0));
@@ -285,11 +320,25 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToFirstScrollHistograms) {
"TimeToScrollUpdateSwapBegin2",
1));
EXPECT_TRUE(
+ HistogramSizeEq("Event.Latency.Scroll.Wheel."
+ "TimeToScrollUpdateSwapBegin2",
+ 1));
+ EXPECT_TRUE(
+ HistogramSizeEq("Event.Latency.ScrollUpdate.Wheel."
+ "TimeToScrollUpdateSwapBegin2",
+ 0));
+ EXPECT_TRUE(
HistogramSizeEq("Event.Latency.ScrollBegin.Wheel.TimeToHandled2_Main",
rendering_on_main ? 1 : 0));
EXPECT_TRUE(
HistogramSizeEq("Event.Latency.ScrollBegin.Wheel.TimeToHandled2_Impl",
rendering_on_main ? 0 : 1));
+ EXPECT_TRUE(
+ HistogramSizeEq("Event.Latency.Scroll.Wheel.TimeToHandled2_Main",
+ rendering_on_main ? 1 : 0));
+ EXPECT_TRUE(
+ HistogramSizeEq("Event.Latency.Scroll.Wheel.TimeToHandled2_Impl",
+ rendering_on_main ? 0 : 1));
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollBegin.Wheel.HandledToRendererSwap2_Main",
rendering_on_main ? 1 : 0));
@@ -323,16 +372,14 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToFirstScrollHistograms) {
0));
EXPECT_TRUE(
HistogramSizeEq("Event.Latency.ScrollUpdate.Wheel.GpuSwap2", 0));
-
- ukm::TestUkmRecorder* test_ukm_recorder =
- test_browser_client_.GetTestUkmRecorder();
- EXPECT_EQ(1U, test_ukm_recorder->sources_count());
- EXPECT_EQ(total_ukm_entry_count, test_ukm_recorder->entries_count());
}
}
}
TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToScrollHistograms) {
+ const GURL url(kUrl);
+ size_t total_ukm_entry_count = 0;
+ contents()->NavigateAndCommit(url);
for (bool rendering_on_main : {false, true}) {
ResetHistograms();
{
@@ -355,6 +402,32 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToScrollHistograms) {
tracker()->OnInputEventAck(wheel, &wheel_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
tracker()->OnGpuSwapBuffersCompleted(wheel_latency);
+
+ // UKM metrics.
+ total_ukm_entry_count++;
+ ExpectUkmReported("Event.ScrollUpdate.Wheel",
+ "TimeToScrollUpdateSwapBegin", total_ukm_entry_count);
+ // Rappor metrics.
+ EXPECT_TRUE(
+ RapporSampleAssert("Event.Latency.ScrollUpdate.Touch."
+ "TimeToScrollUpdateSwapBegin2",
+ 0));
+ EXPECT_TRUE(
+ RapporSampleAssert("Event.Latency.ScrollUpdate.Wheel."
+ "TimeToScrollUpdateSwapBegin2",
+ 2));
+ EXPECT_TRUE(
+ RapporSampleAssert("Event.Latency.ScrollBegin.Touch."
+ "TimeToScrollUpdateSwapBegin2",
+ 0));
+ EXPECT_TRUE(
+ RapporSampleAssert("Event.Latency.ScrollBegin.Wheel."
+ "TimeToScrollUpdateSwapBegin2",
+ 0));
+ EXPECT_EQ(2,
+ test_browser_client_.getTestRapporService()->GetReportsCount());
+
+ // UMA histograms.
EXPECT_TRUE(HistogramSizeEq("Event.Latency.Browser.WheelUI", 1));
EXPECT_TRUE(HistogramSizeEq("Event.Latency.Browser.WheelAcked", 1));
@@ -362,6 +435,15 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToScrollHistograms) {
HistogramSizeEq("Event.Latency.ScrollBegin.Wheel."
"TimeToScrollUpdateSwapBegin2",
0));
+ EXPECT_TRUE(
+ HistogramSizeEq("Event.Latency.Scroll.Wheel."
+ "TimeToScrollUpdateSwapBegin2",
+ 1));
+ EXPECT_TRUE(
+ HistogramSizeEq("Event.Latency.ScrollUpdate.Wheel."
+ "TimeToScrollUpdateSwapBegin2",
+ 1));
+
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollBegin.Wheel.TimeToHandled2_Main", 0));
EXPECT_TRUE(HistogramSizeEq(
@@ -387,6 +469,12 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToScrollHistograms) {
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollUpdate.Wheel.TimeToHandled2_Impl",
rendering_on_main ? 0 : 1));
+ EXPECT_TRUE(
+ HistogramSizeEq("Event.Latency.Scroll.Wheel.TimeToHandled2_Main",
+ rendering_on_main ? 1 : 0));
+ EXPECT_TRUE(
+ HistogramSizeEq("Event.Latency.Scroll.Wheel.TimeToHandled2_Impl",
+ rendering_on_main ? 0 : 1));
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollUpdate.Wheel.HandledToRendererSwap2_Main",
rendering_on_main ? 1 : 0));
@@ -456,14 +544,18 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToFirstScrollHistograms) {
// UKM metrics.
total_ukm_entry_count++;
- EXPECT_TRUE(AssertUkmReported("Event.ScrollBegin.Touch",
- "TimeToScrollUpdateSwapBegin"));
+ ExpectUkmReported("Event.ScrollBegin.Touch", "TimeToScrollUpdateSwapBegin",
+ total_ukm_entry_count);
// Rappor metrics.
EXPECT_TRUE(
RapporSampleAssert("Event.Latency.ScrollUpdate.Touch."
"TimeToScrollUpdateSwapBegin2",
0));
EXPECT_TRUE(
+ RapporSampleAssert("Event.Latency.ScrollUpdate.Wheel."
+ "TimeToScrollUpdateSwapBegin2",
+ 0));
+ EXPECT_TRUE(
RapporSampleAssert("Event.Latency.ScrollBegin.Touch."
"TimeToScrollUpdateSwapBegin2",
2));
@@ -477,10 +569,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToFirstScrollHistograms) {
// UMA histograms.
EXPECT_TRUE(HistogramSizeEq("Event.Latency.Browser.TouchUI", 1));
EXPECT_TRUE(HistogramSizeEq("Event.Latency.Browser.TouchAcked", 1));
- EXPECT_TRUE(
- HistogramSizeEq("Event.Latency.TouchToFirstScrollUpdateSwapBegin", 1));
- EXPECT_TRUE(
- HistogramSizeEq("Event.Latency.TouchToScrollUpdateSwapBegin", 1));
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollBegin.Touch.TimeToScrollUpdateSwapBegin2", 1));
@@ -523,11 +611,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToFirstScrollHistograms) {
"Event.Latency.ScrollUpdate.Touch.BrowserNotifiedToBeforeGpuSwap2", 0));
EXPECT_TRUE(
HistogramSizeEq("Event.Latency.ScrollUpdate.Touch.GpuSwap2", 0));
-
- ukm::TestUkmRecorder* test_ukm_recorder =
- test_browser_client_.GetTestUkmRecorder();
- EXPECT_EQ(1U, test_ukm_recorder->sources_count());
- EXPECT_EQ(total_ukm_entry_count, test_ukm_recorder->entries_count());
}
}
@@ -584,8 +667,8 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToScrollHistograms) {
// UKM metrics.
total_ukm_entry_count++;
- EXPECT_TRUE(AssertUkmReported("Event.ScrollUpdate.Touch",
- "TimeToScrollUpdateSwapBegin"));
+ ExpectUkmReported("Event.ScrollUpdate.Touch", "TimeToScrollUpdateSwapBegin",
+ total_ukm_entry_count);
// Rappor metrics.
EXPECT_TRUE(
@@ -593,6 +676,10 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToScrollHistograms) {
"TimeToScrollUpdateSwapBegin2",
2));
EXPECT_TRUE(
+ RapporSampleAssert("Event.Latency.ScrollUpdate.Wheel."
+ "TimeToScrollUpdateSwapBegin2",
+ 0));
+ EXPECT_TRUE(
RapporSampleAssert("Event.Latency.ScrollBegin.Touch."
"TimeToScrollUpdateSwapBegin2",
0));
@@ -645,11 +732,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToScrollHistograms) {
"Event.Latency.ScrollUpdate.Touch.BrowserNotifiedToBeforeGpuSwap2", 1));
EXPECT_TRUE(
HistogramSizeEq("Event.Latency.ScrollUpdate.Touch.GpuSwap2", 1));
-
- ukm::TestUkmRecorder* test_ukm_recorder =
- test_browser_client_.GetTestUkmRecorder();
- EXPECT_EQ(1U, test_ukm_recorder->sources_count());
- EXPECT_EQ(total_ukm_entry_count, test_ukm_recorder->entries_count());
}
}
@@ -696,7 +778,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest,
EXPECT_TRUE(touch_latency.FindLatency(
ui::INPUT_EVENT_LATENCY_TERMINATED_NO_SWAP_COMPONENT, 0, nullptr));
EXPECT_TRUE(touch_latency.terminated());
- tracker()->OnGpuSwapBuffersCompleted(touch_latency);
}
{
@@ -731,9 +812,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest,
EXPECT_TRUE(HistogramSizeEq("Event.Latency.Browser.WheelAcked", 1));
EXPECT_TRUE(HistogramSizeEq("Event.Latency.Browser.TouchAcked", 1));
EXPECT_TRUE(
- HistogramSizeEq("Event.Latency.TouchToFirstScrollUpdateSwapBegin", 1));
- EXPECT_TRUE(HistogramSizeEq("Event.Latency.TouchToScrollUpdateSwapBegin", 1));
- EXPECT_TRUE(
HistogramSizeEq("Event.Latency.ScrollUpdate.TouchToHandled_Main", 0));
EXPECT_TRUE(
HistogramSizeEq("Event.Latency.ScrollUpdate.TouchToHandled_Impl", 0));
@@ -1076,6 +1154,8 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, KeyUILatency) {
base::TimeDelta::FromMicroseconds(event_timestamps_microseconds[0]),
1);
+ // Add the BEGIN_RWH component explicitly here with a timestamp, instead of
+ // calling tracker()->OnInputEvent().
latency_info.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
tracker()->latency_component_id(), 0,
@@ -1083,7 +1163,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, KeyUILatency) {
base::TimeDelta::FromMicroseconds(event_timestamps_microseconds[1]),
1);
- tracker()->OnInputEvent(event, &latency_info);
tracker()->OnInputEventAck(event, &latency_info,
InputEventAckState::INPUT_EVENT_ACK_STATE_UNKNOWN);
EXPECT_THAT(
@@ -1104,6 +1183,8 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, KeyAckedLatency) {
latency_info.set_trace_id(kTraceEventId);
latency_info.set_source_event_type(ui::SourceEventType::KEY_PRESS);
+ // Add the BEGIN_RWH component explicitly here with a timestamp, instead of
+ // calling tracker()->OnInputEvent().
latency_info.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
tracker()->latency_component_id(), 0,
@@ -1111,13 +1192,14 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, KeyAckedLatency) {
base::TimeDelta::FromMicroseconds(event_timestamps_microseconds[0]),
1);
+ // Add the ACK_RWH component explicitly here with a timestamp, instead of
+ // calling tracker()->OnInputEventAck().
latency_info.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0,
base::TimeTicks() +
base::TimeDelta::FromMicroseconds(event_timestamps_microseconds[1]),
1);
- tracker()->OnInputEvent(event, &latency_info);
// Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck
// overwriting components.
tracker()->ComputeInputLatencyHistograms(
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 ce05435dcf8..0add2629f5d 100644
--- a/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc
@@ -68,7 +68,7 @@ class ScrollLatencyBrowserTest : public ContentBrowserTest {
void WaitAFrame() {
while (!GetWidgetHost()->ScheduleComposite())
GiveItSomeTime();
- frame_watcher_.WaitFrames(1);
+ frame_observer_->Wait();
}
protected:
@@ -79,10 +79,12 @@ class ScrollLatencyBrowserTest : public ContentBrowserTest {
RenderWidgetHostImpl* host = GetWidgetHost();
host->GetView()->SetSize(gfx::Size(400, 400));
- frame_watcher_.Observe(shell()->web_contents());
+ frame_observer_ = base::MakeUnique<MainThreadFrameObserver>(
+ shell()->web_contents()->GetRenderViewHost()->GetWidget());
// Wait a frame to make sure the page has renderered.
WaitAFrame();
+ frame_observer_.reset();
}
// Generate a single wheel tick, scrolling by |distance|. This will perform a
@@ -108,7 +110,7 @@ class ScrollLatencyBrowserTest : public ContentBrowserTest {
private:
base::MessageLoop loop_;
base::RunLoop runner_;
- FrameWatcher frame_watcher_;
+ std::unique_ptr<MainThreadFrameObserver> frame_observer_;
DISALLOW_COPY_AND_ASSIGN(ScrollLatencyBrowserTest);
};
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 32f1544ad17..23d1c4068a5 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
@@ -53,6 +53,7 @@ const int kPointerAssumedStoppedTimeMs = 43;
const float kTouchSlopInDips = 7.0f;
const float kMinScalingSpanInDips = 27.5f;
const int kTouchPointersLength = 16;
+const int kMouseWheelTickMultiplier = 0;
enum TouchGestureType { TOUCH_SCROLL, TOUCH_DRAG };
@@ -151,6 +152,10 @@ class MockSyntheticGestureTarget : public SyntheticGestureTarget {
float GetTouchSlopInDips() const override { return kTouchSlopInDips; }
+ int GetMouseWheelMinimumGranularity() const override {
+ return kMouseWheelTickMultiplier;
+ }
+
float GetMinScalingSpanInDips() const override {
return kMinScalingSpanInDips;
}
@@ -688,7 +693,7 @@ class SyntheticGestureControllerTestBase {
template<typename MockGestureTarget>
void CreateControllerAndTarget() {
target_ = new MockGestureTarget();
- controller_ = base::MakeUnique<SyntheticGestureController>(
+ controller_ = std::make_unique<SyntheticGestureController>(
&delegate_, std::unique_ptr<SyntheticGestureTarget>(target_));
}
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_target.h
index c364fad992f..e58c511faf8 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target.h
@@ -42,6 +42,11 @@ class CONTENT_EXPORT SyntheticGestureTarget {
// Returns the minimum number of DIPs two touch pointers have to be apart
// to perform a pinch-zoom.
virtual float GetMinScalingSpanInDips() const = 0;
+
+ // If mouse wheels can only specify the number of ticks of some static
+ // multiplier constant, this method returns that constant (in DIPs). If mouse
+ // wheels can specify an arbitrary delta this returns 0.
+ virtual int GetMouseWheelMinimumGranularity() const = 0;
};
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
index 7a64bdf6632..316737ef097 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
@@ -5,6 +5,8 @@
#include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
#include "base/trace_event/trace_event.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "jni/SyntheticGestureTarget_jni.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/WebKit/public/platform/WebMouseEvent.h"
@@ -50,10 +52,17 @@ void SyntheticGestureTargetAndroid::TouchSetScrollDeltas(int x,
int dy) {
TRACE_EVENT0("input", "SyntheticGestureTargetAndroid::TouchSetScrollDeltas");
JNIEnv* env = base::android::AttachCurrentThread();
- float scale_factor = view_->GetDipScale();
- Java_SyntheticGestureTarget_setScrollDeltas(
- env, java_ref_, x * scale_factor, y * scale_factor, dx * scale_factor,
- dy * scale_factor);
+
+ // Android motion events work by passing the number of wheel ticks and pixels
+ // per tick so the deltas should be passed in as number of ticks.
+ int wheel_ticks_multiplier =
+ render_widget_host()->GetView()->GetMouseWheelMinimumGranularity();
+ if (wheel_ticks_multiplier) {
+ dx /= wheel_ticks_multiplier;
+ dy /= wheel_ticks_multiplier;
+ }
+
+ Java_SyntheticGestureTarget_setScrollDeltas(env, java_ref_, x, y, dx, dy);
}
void SyntheticGestureTargetAndroid::TouchInject(MotionEventAction action,
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
index a2c6b302fa1..680b676cbe8 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
@@ -124,6 +124,10 @@ float SyntheticGestureTargetBase::GetMinScalingSpanInDips() const {
return 0.0f;
}
+int SyntheticGestureTargetBase::GetMouseWheelMinimumGranularity() const {
+ return host_->GetView()->GetMouseWheelMinimumGranularity();
+}
+
bool SyntheticGestureTargetBase::PointIsWithinContents(int x, int y) const {
gfx::Rect bounds = host_->GetView()->GetViewBounds();
bounds -= bounds.OffsetFromOrigin(); // Translate the bounds to (0,0).
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.h
index 1e4096c8f24..223644c74c8 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.h
@@ -52,6 +52,8 @@ class SyntheticGestureTargetBase : public SyntheticGestureTarget {
float GetMinScalingSpanInDips() const override;
+ int GetMouseWheelMinimumGranularity() const override;
+
protected:
RenderWidgetHostImpl* render_widget_host() const { return host_; }
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 cb244a653fb..aeaae359c62 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
@@ -80,6 +80,11 @@ class MockSyntheticPointerActionTarget : public SyntheticGestureTarget {
return 0.0f;
}
+ int GetMouseWheelMinimumGranularity() const override {
+ NOTIMPLEMENTED();
+ return 0.0f;
+ }
+
WebInputEvent::Type type() const { return type_; }
protected:
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer_driver.cc b/chromium/content/browser/renderer_host/input/synthetic_pointer_driver.cc
index cadf8896ceb..0189ef1bc6e 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_pointer_driver.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_pointer_driver.cc
@@ -19,11 +19,11 @@ std::unique_ptr<SyntheticPointerDriver> SyntheticPointerDriver::Create(
SyntheticGestureParams::GestureSourceType gesture_source_type) {
switch (gesture_source_type) {
case SyntheticGestureParams::TOUCH_INPUT:
- return base::MakeUnique<SyntheticTouchDriver>();
+ return std::make_unique<SyntheticTouchDriver>();
case SyntheticGestureParams::MOUSE_INPUT:
- return base::MakeUnique<SyntheticMouseDriver>();
+ return std::make_unique<SyntheticMouseDriver>();
case SyntheticGestureParams::PEN_INPUT:
- return base::MakeUnique<SyntheticPenDriver>();
+ return std::make_unique<SyntheticPenDriver>();
case SyntheticGestureParams::DEFAULT_INPUT:
return std::unique_ptr<SyntheticPointerDriver>();
}
diff --git a/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc
index fd2fe41e11e..bcf71cb0b92 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc
@@ -157,13 +157,30 @@ void SyntheticSmoothMoveGesture::ForwardMouseWheelInputEvents(
gfx::Vector2dF delta = GetPositionDeltaAtTime(event_timestamp) -
current_move_segment_total_delta_;
- blink::WebMouseWheelEvent::Phase phase =
- needs_scroll_begin_ ? blink::WebMouseWheelEvent::kPhaseBegan
- : blink::WebMouseWheelEvent::kPhaseChanged;
- DCHECK(delta.x() || delta.y());
- ForwardMouseWheelEvent(target, delta, phase, event_timestamp);
- current_move_segment_total_delta_ += delta;
- needs_scroll_begin_ = false;
+ // Android MotionEvents that carry mouse wheel ticks and the tick
+ // granularity. Since it's not easy to change this granularity, it means
+ // we can only scroll in terms of number of these ticks. Note also: if
+ // the delta is smaller than one tick size we wont send an event or
+ // accumulate it in current_move_segment_total_delta_ so that we don't
+ // consider that delta applied. If we did, slow scrolls would be entirely
+ // lost since we'd send 0 ticks in each event but assume delta was
+ // applied.
+ int pixels_per_wheel_tick = target->GetMouseWheelMinimumGranularity();
+ if (pixels_per_wheel_tick) {
+ int wheel_ticks_x = static_cast<int>(delta.x() / pixels_per_wheel_tick);
+ int wheel_ticks_y = static_cast<int>(delta.y() / pixels_per_wheel_tick);
+ delta = gfx::Vector2dF(wheel_ticks_x * pixels_per_wheel_tick,
+ wheel_ticks_y * pixels_per_wheel_tick);
+ }
+
+ if (delta.x() || delta.y()) {
+ blink::WebMouseWheelEvent::Phase phase =
+ needs_scroll_begin_ ? blink::WebMouseWheelEvent::kPhaseBegan
+ : blink::WebMouseWheelEvent::kPhaseChanged;
+ ForwardMouseWheelEvent(target, delta, phase, event_timestamp);
+ current_move_segment_total_delta_ += delta;
+ needs_scroll_begin_ = false;
+ }
if (FinishedCurrentMoveSegment(event_timestamp)) {
if (!IsLastMoveSegment()) {
@@ -298,6 +315,9 @@ gfx::Vector2dF SyntheticSmoothMoveGesture::GetPositionDeltaAtTime(
const base::TimeTicks& timestamp) const {
// Make sure the final delta is correct. Using the computation below can lead
// to issues with floating point precision.
+ // TODO(bokan): This comment makes it sound like we have pixel perfect
+ // precision. In fact, gestures can accumulate a significant amount of
+ // error (e.g. due to snapping to physical pixels on each event).
if (FinishedCurrentMoveSegment(timestamp))
return params_.distances[current_move_segment_];
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 32613466688..c16cb1a0eaf 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -156,7 +156,7 @@ class TouchActionBrowserTest : public ContentBrowserTest {
// Runs until we get the OnSyntheticGestureCompleted callback
runner_->Run();
- runner_ = NULL;
+ runner_ = nullptr;
// Expect that the compositor scrolled at least one pixel while the
// main thread was in a busy loop.
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 d1b94179777..e645b3334e2 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
@@ -2,10 +2,10 @@
// 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/event_with_latency_info.h"
#include "content/browser/renderer_host/input/touch_action_filter.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
+#include "content/public/common/input_event_ack_state.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
diff --git a/chromium/content/browser/renderer_host/input/touch_emulator.h b/chromium/content/browser/renderer_host/input/touch_emulator.h
index c501cef8b94..e46d0b8866c 100644
--- a/chromium/content/browser/renderer_host/input/touch_emulator.h
+++ b/chromium/content/browser/renderer_host/input/touch_emulator.h
@@ -12,7 +12,7 @@
#include "base/macros.h"
#include "content/browser/renderer_host/input/touch_emulator_client.h"
#include "content/common/cursors/webcursor.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
#include "third_party/WebKit/public/platform/WebTouchEvent.h"
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
#include "ui/events/gesture_detection/gesture_provider_config_helper.h"
diff --git a/chromium/content/browser/renderer_host/input/touch_event_queue.h b/chromium/content/browser/renderer_host/input/touch_event_queue.h
index c1c4115fa85..a6a15a85148 100644
--- a/chromium/content/browser/renderer_host/input/touch_event_queue.h
+++ b/chromium/content/browser/renderer_host/input/touch_event_queue.h
@@ -12,7 +12,8 @@
#include "base/time/time.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
namespace content {
@@ -25,9 +26,9 @@ class CONTENT_EXPORT TouchEventQueueClient {
virtual void SendTouchEventImmediately(
const TouchEventWithLatencyInfo& event) = 0;
- virtual void OnTouchEventAck(
- const TouchEventWithLatencyInfo& event,
- InputEventAckState ack_result) = 0;
+ virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
+ InputEventAckState ack_result) = 0;
virtual void OnFilteringTouchEvent(
const blink::WebTouchEvent& touch_event) = 0;
@@ -76,7 +77,8 @@ class CONTENT_EXPORT TouchEventQueue {
// touchmove from the front of the queue and decide if it should dispatch the
// next pending async touch move event, otherwise the queue may send one or
// more gesture events and/or additional queued touch-events to the renderer.
- virtual void ProcessTouchAck(InputEventAckState ack_result,
+ virtual void ProcessTouchAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result,
const ui::LatencyInfo& latency_info,
const uint32_t unique_touch_event_id) = 0;
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 e76bf32cea1..206e524e2ab 100644
--- a/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc
@@ -98,8 +98,8 @@ class TouchInputBrowserTest : public ContentBrowserTest {
shell()->web_contents()->GetRenderViewHost()->GetWidget());
}
- scoped_refptr<InputMsgWatcher> AddFilter(blink::WebInputEvent::Type type) {
- return new InputMsgWatcher(GetWidgetHost(), type);
+ std::unique_ptr<InputMsgWatcher> AddFilter(blink::WebInputEvent::Type type) {
+ return std::make_unique<InputMsgWatcher>(GetWidgetHost(), type);
}
protected:
@@ -139,7 +139,7 @@ IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchNoHandler) {
// A press on |first| should be acked with NO_CONSUMER_EXISTS since there is
// no touch-handler on it.
touch.PressPoint(25, 25);
- scoped_refptr<InputMsgWatcher> filter = AddFilter(WebInputEvent::kTouchStart);
+ auto filter = AddFilter(WebInputEvent::kTouchStart);
SendTouchEvent(&touch);
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, filter->WaitForAck());
@@ -163,7 +163,7 @@ IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchHandlerNoConsume) {
// Press on |second| should be acked with NOT_CONSUMED since there is a
// touch-handler on |second|, but it doesn't consume the event.
touch.PressPoint(125, 25);
- scoped_refptr<InputMsgWatcher> filter = AddFilter(WebInputEvent::kTouchStart);
+ auto filter = AddFilter(WebInputEvent::kTouchStart);
SendTouchEvent(&touch);
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter->WaitForAck());
@@ -186,7 +186,7 @@ IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchHandlerConsume) {
// Press on |third| should be acked with CONSUMED since the touch-handler on
// |third| consimes the event.
touch.PressPoint(25, 125);
- scoped_refptr<InputMsgWatcher> filter = AddFilter(WebInputEvent::kTouchStart);
+ auto filter = AddFilter(WebInputEvent::kTouchStart);
SendTouchEvent(&touch);
EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter->WaitForAck());
@@ -212,7 +212,7 @@ IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_MultiPointTouchPress) {
// Press on |first|, which sould be acked with NO_CONSUMER_EXISTS. Then press
// on |third|. That point should be acked with CONSUMED.
touch.PressPoint(25, 25);
- scoped_refptr<InputMsgWatcher> filter = AddFilter(WebInputEvent::kTouchStart);
+ auto filter = AddFilter(WebInputEvent::kTouchStart);
SendTouchEvent(&touch);
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, filter->WaitForAck());
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 915c5f8f80b..7f319cbd362 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
@@ -505,8 +505,8 @@ IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAuraSiteIsolationTest,
ui::TouchSelectionControllerTestApi selection_controller_test_api(
selection_controller);
- scoped_refptr<FrameRectChangedMessageFilter> filter =
- new FrameRectChangedMessageFilter();
+ scoped_refptr<UpdateResizeParamsMessageFilter> filter =
+ new UpdateResizeParamsMessageFilter();
root->current_frame_host()->GetProcess()->AddFilter(filter.get());
// Find the location of some text to select.
@@ -587,7 +587,7 @@ IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAuraSiteIsolationTest,
EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
// Make sure we wait for the scroll to actually happen.
- filter->Wait();
+ filter->WaitForRect();
// End scrolling: touch handles should re-appear.
ui::GestureEventDetails scroll_end_details(ui::ET_GESTURE_SCROLL_END);
@@ -848,7 +848,7 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest,
const int window_width = rwhva->GetNativeView()->bounds().width();
const float overscroll_threshold =
- GetOverscrollConfig(OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN);
+ GetOverscrollConfig(OverscrollConfig::THRESHOLD_START_TOUCHSCREEN);
const float scroll_amount = window_width * overscroll_threshold + 1;
event_x += scroll_amount;
ui::GestureEventDetails scroll_update_details(ui::ET_GESTURE_SCROLL_UPDATE,
diff --git a/chromium/content/browser/renderer_host/input/touch_timeout_handler.h b/chromium/content/browser/renderer_host/input/touch_timeout_handler.h
index 1556ff363b4..d8684db8be0 100644
--- a/chromium/content/browser/renderer_host/input/touch_timeout_handler.h
+++ b/chromium/content/browser/renderer_host/input/touch_timeout_handler.h
@@ -12,7 +12,7 @@
#include "base/time/time.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/browser/renderer_host/input/timeout_monitor.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
namespace content {
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_android.cc b/chromium/content/browser/renderer_host/input/web_input_event_builders_android.cc
index a76386d30cf..a8547dbc35c 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_android.cc
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_android.cc
@@ -8,7 +8,7 @@
#include "base/logging.h"
#include "ui/events/android/key_event_utils.h"
-#include "ui/events/android/motion_event_android.h"
+#include "ui/events/base_event_utils.h"
#include "ui/events/blink/blink_event_util.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/dom/dom_code.h"
@@ -111,24 +111,20 @@ WebKeyboardEvent WebKeyboardEventBuilder::Build(
return result;
}
-WebMouseEvent WebMouseEventBuilder::Build(WebInputEvent::Type type,
- double time_sec,
- int window_x,
- int window_y,
- int modifiers,
- int click_count,
- int pointer_id,
- float pressure,
- float orientation_rad,
- float tilt_x,
- float tilt_y,
- int action_button,
- int tool_type) {
+WebMouseEvent WebMouseEventBuilder::Build(
+ const ui::MotionEventAndroid& motion_event,
+ WebInputEvent::Type type,
+ int click_count,
+ int action_button) {
DCHECK(WebInputEvent::IsMouseEventType(type));
- WebMouseEvent result(type, ui::EventFlagsToWebEventModifiers(modifiers),
- time_sec);
+ int modifiers = motion_event.GetFlags();
+ WebMouseEvent result(
+ type, ui::EventFlagsToWebEventModifiers(modifiers),
+ ui::EventTimeStampToSeconds(motion_event.GetEventTime()));
+
+ result.SetPositionInWidget(motion_event.GetX(0), motion_event.GetY(0));
+ result.SetPositionInScreen(motion_event.GetRawX(0), motion_event.GetRawY(0));
- result.SetPositionInWidget(window_x, window_y);
result.click_count = click_count;
int button = action_button;
@@ -145,28 +141,27 @@ WebMouseEvent WebMouseEventBuilder::Build(WebInputEvent::Type type,
button = 0;
}
- ui::SetWebPointerPropertiesFromMotionEventData(result, pointer_id, pressure,
- orientation_rad, tilt_x,
- tilt_y, button, tool_type);
+ ui::SetWebPointerPropertiesFromMotionEventData(
+ result, motion_event.GetPointerId(0), motion_event.GetPressure(0),
+ motion_event.GetOrientation(0), motion_event.GetTiltX(0),
+ motion_event.GetTiltY(0), button, motion_event.GetToolType(0));
return result;
}
-WebMouseWheelEvent WebMouseWheelEventBuilder::Build(float ticks_x,
- float ticks_y,
- float tick_multiplier,
- double time_sec,
- int window_x,
- int window_y) {
+WebMouseWheelEvent WebMouseWheelEventBuilder::Build(
+ const ui::MotionEventAndroid& motion_event) {
WebMouseWheelEvent result(WebInputEvent::kMouseWheel,
- WebInputEvent::kNoModifiers, time_sec);
- result.SetPositionInWidget(window_x, window_y);
+ WebInputEvent::kNoModifiers,
+ motion_event.time_sec());
+ result.SetPositionInWidget(motion_event.GetX(0), motion_event.GetY(0));
+ result.SetPositionInScreen(motion_event.GetRawX(0), motion_event.GetRawY(0));
result.button = WebMouseEvent::Button::kNoButton;
result.has_precise_scrolling_deltas = true;
- result.delta_x = ticks_x * tick_multiplier;
- result.delta_y = ticks_y * tick_multiplier;
- result.wheel_ticks_x = ticks_x;
- result.wheel_ticks_y = ticks_y;
+ result.delta_x = motion_event.ticks_x() * motion_event.GetTickMultiplier();
+ result.delta_y = motion_event.ticks_y() * motion_event.GetTickMultiplier();
+ result.wheel_ticks_x = motion_event.ticks_x();
+ result.wheel_ticks_y = motion_event.ticks_y();
return result;
}
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_android.h b/chromium/content/browser/renderer_host/input/web_input_event_builders_android.h
index 4c45a8bb5dc..ce475e34b47 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_android.h
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_android.h
@@ -13,34 +13,22 @@
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/WebKit/public/platform/WebKeyboardEvent.h"
#include "third_party/WebKit/public/platform/WebMouseWheelEvent.h"
+#include "ui/events/android/motion_event_android.h"
namespace content {
-class WebMouseEventBuilder {
+class CONTENT_EXPORT WebMouseEventBuilder {
public:
- static blink::WebMouseEvent Build(blink::WebInputEvent::Type type,
- double time_sec,
- int window_x,
- int window_y,
- int modifiers,
+ static blink::WebMouseEvent Build(const ui::MotionEventAndroid& motion_event,
+ blink::WebInputEvent::Type type,
int click_count,
- int pointer_id,
- float pressure,
- float orientation_rad,
- float tilt_x,
- float tilt_y,
- int action_button,
- int tool_type);
+ int action_button);
};
class WebMouseWheelEventBuilder {
public:
- static blink::WebMouseWheelEvent Build(float ticks_x,
- float ticks_y,
- float tick_multiplier,
- double time_sec,
- int window_x,
- int window_y);
+ static blink::WebMouseWheelEvent Build(
+ const ui::MotionEventAndroid& motion_event);
};
class CONTENT_EXPORT WebKeyboardEventBuilder {
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc b/chromium/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc
index d7c5d01bfa5..a9388c9fbbf 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_android_unittest.cc
@@ -20,6 +20,7 @@
using base::android::AttachCurrentThread;
using base::android::ScopedJavaLocalRef;
using blink::WebKeyboardEvent;
+using blink::WebMouseEvent;
namespace {
@@ -194,3 +195,29 @@ TEST(WebInputEventBuilderAndroidTest, CutCopyPasteKey) {
EXPECT_EQ(entry.key, web_event.dom_key);
}
}
+
+TEST(WebInputEventBuilderAndroidTest, WebMouseEventCoordinates) {
+ ui::MotionEventAndroid::Pointer p0(1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, 0.2f,
+ ui::MotionEvent::TOOL_TYPE_MOUSE);
+ const float raw_offset_x = 11.f;
+ const float raw_offset_y = 22.f;
+ const float kPixToDip = 0.5f;
+
+ ui::MotionEventAndroid motion_event(
+ AttachCurrentThread(), nullptr, kPixToDip, 0.f, 0.f, 0.f, 0,
+ AMOTION_EVENT_ACTION_DOWN, 1, 0, -1, 0, 1, AMETA_ALT_ON, raw_offset_x,
+ raw_offset_y, false, &p0, nullptr);
+
+ WebMouseEvent web_event = content::WebMouseEventBuilder::Build(
+ motion_event, blink::WebInputEvent::kMouseDown, 1,
+ ui::MotionEvent::BUTTON_PRIMARY);
+ EXPECT_EQ(web_event.PositionInWidget().x, p0.pos_x_pixels * kPixToDip);
+ EXPECT_EQ(web_event.PositionInWidget().y, p0.pos_y_pixels * kPixToDip);
+ EXPECT_EQ(web_event.PositionInScreen().x,
+ (p0.pos_x_pixels + raw_offset_x) * kPixToDip);
+ EXPECT_EQ(web_event.PositionInScreen().y,
+ (p0.pos_y_pixels + raw_offset_y) * kPixToDip);
+ EXPECT_EQ(web_event.button, blink::WebPointerProperties::Button::kLeft);
+}
+
+// TODO(crbug.com/781404): Add more tests for WebMouseEventBuilder
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm b/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm
index e665a62230d..eca937f8469 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm
@@ -551,6 +551,13 @@ blink::WebGestureEvent WebGestureEventBuilder::Build(NSEvent* event,
// and end NSEvents come in. Leave them undefined. The caller will need
// to specify them when the gesture is differentiated.
break;
+ case NSEventTypeScrollWheel:
+ // When building against the 10.11 SDK or later, and running on macOS
+ // 10.11+, Cocoa no longer sends separate Begin/End gestures for scroll
+ // events. However, it's convenient to use the same path as the older
+ // OSes, to avoid logic duplication. We just need to support building a
+ // dummy WebGestureEvent.
+ break;
default:
NOTIMPLEMENTED();
}
diff --git a/chromium/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc b/chromium/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc
index 69797f51ed0..f4492c7f768 100644
--- a/chromium/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc
@@ -25,7 +25,7 @@ namespace {
void GiveItSomeTime() {
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMilliseconds(10));
+ FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMilliseconds(20));
run_loop.Run();
}
@@ -121,6 +121,12 @@ class WheelScrollLatchingBrowserTest : public ContentBrowserTest {
shell(), "domAutomationController.send(" + script + ")", &value));
return value;
}
+ std::string ExecuteScriptAndExtractString(const std::string& script) {
+ std::string value = "";
+ EXPECT_TRUE(content::ExecuteScriptAndExtractString(
+ shell(), "domAutomationController.send(" + script + ")", &value));
+ return value;
+ }
void EnableWheelScrollLatching() {
feature_list_.InitFromCommandLine(
features::kTouchpadAndWheelScrollLatching.name, "");
@@ -135,9 +141,11 @@ class WheelScrollLatchingBrowserTest : public ContentBrowserTest {
EXPECT_EQ(0, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
- FrameWatcher frame_watcher(shell()->web_contents());
- scoped_refptr<InputMsgWatcher> input_msg_watcher(new InputMsgWatcher(
- GetWidgetHost(), blink::WebInputEvent::kMouseWheel));
+ MainThreadFrameObserver frame_observer(
+ shell()->web_contents()->GetRenderViewHost()->GetWidget());
+
+ auto input_msg_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kMouseWheel);
float scrollable_div_top =
ExecuteScriptAndExtractInt("scrollableDiv.getBoundingClientRect().top");
@@ -163,7 +171,7 @@ class WheelScrollLatchingBrowserTest : public ContentBrowserTest {
while (ExecuteScriptAndExtractInt("document.scrollingElement.scrollTop") <
-delta_y) {
- frame_watcher.WaitFrames(1);
+ frame_observer.Wait();
}
EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDiv.scrollTop"));
@@ -181,7 +189,7 @@ class WheelScrollLatchingBrowserTest : public ContentBrowserTest {
if (wheel_scroll_latching_enabled_) {
while (ExecuteScriptAndExtractInt("document.scrollingElement.scrollTop") <
-2 * delta_y) {
- frame_watcher.WaitFrames(1);
+ frame_observer.Wait();
}
EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDiv.scrollTop"));
@@ -190,7 +198,7 @@ class WheelScrollLatchingBrowserTest : public ContentBrowserTest {
ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
} else { // !wheel_scroll_latching_enabled_
while (ExecuteScriptAndExtractInt("scrollableDiv.scrollTop") < -delta_y)
- frame_watcher.WaitFrames(1);
+ frame_observer.Wait();
EXPECT_EQ(1, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
EXPECT_EQ(1,
@@ -232,4 +240,131 @@ IN_PROC_BROWSER_TEST_F(WheelScrollLatchingDisabledBrowserTest,
WheelEventTargetTest();
}
+// Tests that wheel events are retargeted if their target gets deleted in the
+// middle of scrolling.
+IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest,
+ WheelEventRetargetWhenTargetRemoved) {
+ LoadURL();
+ EXPECT_EQ(0, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
+ EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
+
+ auto update_msg_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kGestureScrollUpdate);
+
+ float scrollable_div_top =
+ ExecuteScriptAndExtractInt("scrollableDiv.getBoundingClientRect().top");
+ float x = (ExecuteScriptAndExtractInt(
+ "scrollableDiv.getBoundingClientRect().left") +
+ ExecuteScriptAndExtractInt(
+ "scrollableDiv.getBoundingClientRect().right")) /
+ 2;
+ float y = 1.1 * scrollable_div_top;
+ float delta_x = 0;
+ float delta_y = -0.6 * scrollable_div_top;
+ blink::WebMouseWheelEvent wheel_event =
+ SyntheticWebMouseWheelEventBuilder::Build(x, y, x, y, delta_x, delta_y, 0,
+ true);
+ wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
+ GetRouter()->RouteMouseWheelEvent(GetRootView(), &wheel_event,
+ ui::LatencyInfo());
+
+ // Runs until we get the UpdateMsgAck callback.
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, update_msg_watcher->WaitForAck());
+
+ EXPECT_EQ(0,
+ ExecuteScriptAndExtractInt("document.scrollingElement.scrollTop"));
+ EXPECT_EQ(0, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
+ EXPECT_EQ(1, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
+
+ // Remove the scrollableDiv which is the current target for wheel events.
+ EXPECT_TRUE(ExecuteScript(
+ shell(), "scrollableDiv.parentNode.removeChild(scrollableDiv)"));
+
+ wheel_event.phase = blink::WebMouseWheelEvent::kPhaseChanged;
+ GetRouter()->RouteMouseWheelEvent(GetRootView(), &wheel_event,
+ ui::LatencyInfo());
+
+ // Runs until we get the UpdateMsgAck callbacks.
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, update_msg_watcher->WaitForAck());
+
+ // Wait for the document event listenr to handle the second wheel event.
+ while (ExecuteScriptAndExtractInt("documentWheelEventCounter") != 1) {
+ GiveItSomeTime();
+ }
+
+ EXPECT_EQ(1, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
+}
+
+// crbug.com/777258 Flaky on Android.
+#if defined(OS_ANDROID)
+#define MAYBE_WheelScrollingRelatchWhenLatchedScrollerRemoved \
+ DISABLED_WheelScrollingRelatchWhenLatchedScrollerRemoved
+#else
+#define MAYBE_WheelScrollingRelatchWhenLatchedScrollerRemoved \
+ WheelScrollingRelatchWhenLatchedScrollerRemoved
+#endif
+IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest,
+ MAYBE_WheelScrollingRelatchWhenLatchedScrollerRemoved) {
+ LoadURL();
+ EXPECT_EQ(ExecuteScriptAndExtractInt("document.scrollingElement.scrollTop"),
+ 0);
+ EXPECT_EQ(ExecuteScriptAndExtractInt("scrollableDiv.scrollTop"), 0);
+ float x = (ExecuteScriptAndExtractInt(
+ "scrollableDiv.getBoundingClientRect().left") +
+ ExecuteScriptAndExtractInt(
+ "scrollableDiv.getBoundingClientRect().right")) /
+ 2;
+ float y =
+ (ExecuteScriptAndExtractInt("scrollableDiv.getBoundingClientRect().top") +
+ ExecuteScriptAndExtractInt(
+ "scrollableDiv.getBoundingClientRect().bottom")) /
+ 2;
+#if defined(OS_CHROMEOS)
+ bool precise = true;
+#else
+ bool precise = false;
+#endif
+ // Send a GSB event to start scrolling the scrollableDiv.
+ blink::WebGestureEvent gesture_scroll_begin(
+ blink::WebGestureEvent::kGestureScrollBegin,
+ blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::kTimeStampForTesting);
+ gesture_scroll_begin.source_device = blink::kWebGestureDeviceTouchpad;
+ gesture_scroll_begin.data.scroll_begin.delta_hint_units =
+ precise ? blink::WebGestureEvent::ScrollUnits::kPrecisePixels
+ : blink::WebGestureEvent::ScrollUnits::kPixels;
+ gesture_scroll_begin.data.scroll_begin.delta_x_hint = 0.f;
+ gesture_scroll_begin.data.scroll_begin.delta_y_hint = -20.f;
+ gesture_scroll_begin.x = x;
+ gesture_scroll_begin.y = y;
+ gesture_scroll_begin.global_x = x;
+ gesture_scroll_begin.global_y = y;
+ GetRootView()->ProcessGestureEvent(gesture_scroll_begin, ui::LatencyInfo());
+
+ // Send the first GSU event.
+ blink::WebGestureEvent gesture_scroll_update(gesture_scroll_begin);
+ gesture_scroll_update.SetType(blink::WebGestureEvent::kGestureScrollUpdate);
+ gesture_scroll_update.data.scroll_update.delta_units =
+ precise ? blink::WebGestureEvent::ScrollUnits::kPrecisePixels
+ : blink::WebGestureEvent::ScrollUnits::kPixels;
+ gesture_scroll_update.data.scroll_update.delta_x = 0.f;
+ gesture_scroll_update.data.scroll_update.delta_y = -20.f;
+ GetRootView()->ProcessGestureEvent(gesture_scroll_update, ui::LatencyInfo());
+
+ // Wait for the scrollableDiv to scroll.
+ while (ExecuteScriptAndExtractInt("scrollableDiv.scrollTop") < 20)
+ GiveItSomeTime();
+
+ // Remove the scrollableDiv which is the current scroller and send the second
+ // GSU.
+ EXPECT_TRUE(ExecuteScript(
+ shell(), "scrollableDiv.parentNode.removeChild(scrollableDiv)"));
+ GiveItSomeTime();
+ GetRootView()->ProcessGestureEvent(gesture_scroll_update, ui::LatencyInfo());
+ while (ExecuteScriptAndExtractInt("document.scrollingElement.scrollTop") <
+ 20) {
+ GiveItSomeTime();
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc
index 74d9147cf66..d6f1334a4ee 100644
--- a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc
+++ b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.cc
@@ -194,7 +194,7 @@ LRESULT LegacyRenderWidgetHostHWND::OnGetObject(UINT message,
if (!manager || !manager->GetRoot())
return static_cast<LRESULT>(0L);
- base::win::ScopedComPtr<IAccessible> root(
+ Microsoft::WRL::ComPtr<IAccessible> root(
ToBrowserAccessibilityWin(manager->GetRoot())->GetCOM());
return LresultFromObject(IID_IAccessible, w_param,
static_cast<IAccessible*>(root.Detach()));
@@ -202,7 +202,7 @@ LRESULT LegacyRenderWidgetHostHWND::OnGetObject(UINT message,
if (static_cast<DWORD>(OBJID_CARET) == obj_id && host_->HasFocus()) {
DCHECK(ax_system_caret_);
- base::win::ScopedComPtr<IAccessible> ax_system_caret_accessible =
+ Microsoft::WRL::ComPtr<IAccessible> ax_system_caret_accessible =
ax_system_caret_->GetCaret();
return LresultFromObject(IID_IAccessible, w_param,
ax_system_caret_accessible.Detach());
diff --git a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h
index 8cb8b832e31..853e0344927 100644
--- a/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h
+++ b/chromium/content/browser/renderer_host/legacy_render_widget_host_win.h
@@ -9,11 +9,11 @@
#include <atlcrack.h>
#include <atlwin.h>
#include <oleacc.h>
+#include <wrl/client.h>
#include <memory>
#include "base/macros.h"
-#include "base/win/scoped_comptr.h"
#include "content/common/content_export.h"
#include "ui/gfx/geometry/rect.h"
@@ -157,7 +157,7 @@ class CONTENT_EXPORT LegacyRenderWidgetHostHWND
LRESULT OnSize(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnWindowPosChanged(UINT message, WPARAM w_param, LPARAM l_param);
- base::win::ScopedComPtr<IAccessible> window_accessible_;
+ Microsoft::WRL::ComPtr<IAccessible> window_accessible_;
// Set to true if we turned on mouse tracking.
bool mouse_tracking_enabled_;
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
new file mode 100644
index 00000000000..29db631bd1d
--- /dev/null
+++ b/chromium/content/browser/renderer_host/media/audio_input_delegate_impl.cc
@@ -0,0 +1,290 @@
+// Copyright 2017 The Chromium Authors. 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/media/audio_input_delegate_impl.h"
+
+#include <utility>
+
+#include "base/command_line.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/stringprintf.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/audio_input_sync_writer.h"
+#include "content/browser/renderer_host/media/media_stream_manager.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"
+#include "media/audio/audio_input_controller.h"
+#include "media/audio/audio_logging.h"
+#include "media/audio/audio_manager.h"
+#include "media/base/media_switches.h"
+#include "media/base/user_input_monitor.h"
+
+namespace content {
+
+namespace {
+
+void NotifyProcessHostStreamAdded(int render_process_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ auto* process_host = RenderProcessHost::FromID(render_process_id);
+ if (process_host)
+ process_host->OnMediaStreamAdded();
+}
+
+void NotifyProcessHostStreamRemoved(int render_process_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ auto* process_host = RenderProcessHost::FromID(render_process_id);
+ if (process_host)
+ process_host->OnMediaStreamRemoved();
+}
+
+// Safe to call from any thread.
+void LogMessage(int stream_id, base::StringPiece message) {
+ const std::string out_message =
+ base::StringPrintf("[stream_id=%d] %.*s", stream_id,
+ static_cast<int>(message.size()), message.data());
+ content::MediaStreamManager::SendMessageToNativeLog(out_message);
+ DVLOG(1) << out_message;
+}
+
+} // namespace
+
+class AudioInputDelegateImpl::ControllerEventHandler
+ : public media::AudioInputController::EventHandler {
+ public:
+ ControllerEventHandler(int stream_id,
+ base::WeakPtr<AudioInputDelegateImpl> weak_delegate)
+ : stream_id_(stream_id), weak_delegate_(std::move(weak_delegate)) {}
+
+ void OnCreated(bool initially_muted) override {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&AudioInputDelegateImpl::SendCreatedNotification,
+ weak_delegate_, initially_muted));
+ }
+
+ void OnError(media::AudioInputController::ErrorCode error_code) override {
+ // To ensure that the error is logged even during the destruction sequence,
+ // we log it here.
+ LogMessage(stream_id_,
+ base::StringPrintf("AIC reports error_code=%d", error_code));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&AudioInputDelegateImpl::OnError, weak_delegate_));
+ }
+
+ void OnLog(base::StringPiece message) override {
+ LogMessage(stream_id_, message);
+ }
+
+ 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));
+ }
+
+ private:
+ const int stream_id_;
+
+ // Bound to the IO thread.
+ const base::WeakPtr<AudioInputDelegateImpl> weak_delegate_;
+};
+
+std::unique_ptr<media::AudioInputDelegate> AudioInputDelegateImpl::Create(
+ EventHandler* subscriber,
+ media::AudioManager* audio_manager,
+ AudioMirroringManager* mirroring_manager,
+ media::UserInputMonitor* user_input_monitor,
+ AudioInputDeviceManager* audio_input_device_manager,
+ std::unique_ptr<media::AudioLog> audio_log,
+ AudioInputDeviceManager::KeyboardMicRegistration keyboard_mic_registration,
+ uint32_t shared_memory_count,
+ int stream_id,
+ int session_id,
+ int render_process_id,
+ int render_frame_id,
+ bool automatic_gain_control,
+ const media::AudioParameters& audio_parameters) {
+ // Check if we have the permission to open the device and which device to use.
+ const MediaStreamDevice* device =
+ audio_input_device_manager->GetOpenedDeviceById(session_id);
+ if (!device) {
+ LogMessage(stream_id, "Permission for stream not granted.");
+ DLOG(WARNING) << "No permission has been granted to input stream with "
+ << "session_id=" << session_id;
+ return nullptr;
+ }
+
+ media::AudioParameters possibly_modified_parameters = audio_parameters;
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseFakeDeviceForMediaStream)) {
+ possibly_modified_parameters.set_format(media::AudioParameters::AUDIO_FAKE);
+ }
+
+ auto foreign_socket = std::make_unique<base::CancelableSyncSocket>();
+
+ std::unique_ptr<AudioInputSyncWriter> writer = AudioInputSyncWriter::Create(
+ shared_memory_count, possibly_modified_parameters, foreign_socket.get());
+
+ if (!writer) {
+ LogMessage(stream_id, "Failed to set up sync writer.");
+ return nullptr;
+ }
+
+ LogMessage(
+ stream_id,
+ base::StringPrintf("OnCreateStream(render_frame_id=%d, session_id=%d): "
+ "device_name=%s, AGC=%d",
+ render_frame_id, session_id, device->name.c_str(),
+ automatic_gain_control));
+
+ return base::WrapUnique(new AudioInputDelegateImpl(
+ subscriber, audio_manager, mirroring_manager, user_input_monitor,
+ possibly_modified_parameters, std::move(writer),
+ std::move(foreign_socket), std::move(audio_log),
+ std::move(keyboard_mic_registration),
+ stream_id, render_process_id, render_frame_id, automatic_gain_control,
+ device));
+}
+
+AudioInputDelegateImpl::AudioInputDelegateImpl(
+ EventHandler* subscriber,
+ media::AudioManager* audio_manager,
+ AudioMirroringManager* mirroring_manager,
+ media::UserInputMonitor* user_input_monitor,
+ const media::AudioParameters& audio_parameters,
+ std::unique_ptr<AudioInputSyncWriter> writer,
+ std::unique_ptr<base::CancelableSyncSocket> foreign_socket,
+ std::unique_ptr<media::AudioLog> audio_log,
+ AudioInputDeviceManager::KeyboardMicRegistration keyboard_mic_registration,
+ int stream_id,
+ int render_process_id,
+ int render_frame_id,
+ bool automatic_gain_control,
+ const MediaStreamDevice* device)
+ : subscriber_(subscriber),
+ controller_event_handler_(),
+ writer_(std::move(writer)),
+ foreign_socket_(std::move(foreign_socket)),
+ audio_log_(std::move(audio_log)),
+ controller_(),
+ keyboard_mic_registration_(std::move(keyboard_mic_registration)),
+ stream_id_(stream_id),
+ render_process_id_(render_process_id),
+ weak_factory_(this) {
+ // Prevent process backgrounding while audio input is active:
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&NotifyProcessHostStreamAdded, render_process_id_));
+
+ controller_event_handler_ = std::make_unique<ControllerEventHandler>(
+ stream_id_, weak_factory_.GetWeakPtr());
+
+ const std::string& device_id = device->id;
+
+ if (WebContentsMediaCaptureId::Parse(device_id, nullptr)) {
+ // For MEDIA_DESKTOP_AUDIO_CAPTURE, the source is selected from picker
+ // window, we do not mute the source audio.
+ // For MEDIA_TAB_AUDIO_CAPTURE, the probable use case is Cast, we mute
+ // the source audio.
+ // TODO(qiangchen): Analyze audio constraints to make a duplicating or
+ // diverting decision. It would give web developer more flexibility.
+ controller_ = media::AudioInputController::CreateForStream(
+ audio_manager->GetTaskRunner(), controller_event_handler_.get(),
+ WebContentsAudioInputStream::Create(
+ device_id, audio_parameters, audio_manager->GetWorkerTaskRunner(),
+ mirroring_manager),
+ writer_.get(), user_input_monitor);
+ DCHECK(controller_);
+ // Only count for captures from desktop media picker dialog.
+ if (device->type == MEDIA_DESKTOP_AUDIO_CAPTURE)
+ IncrementDesktopCaptureCounter(TAB_AUDIO_CAPTURER_CREATED);
+ } else {
+ controller_ = media::AudioInputController::Create(
+ audio_manager, controller_event_handler_.get(), writer_.get(),
+ user_input_monitor, audio_parameters, device_id,
+ automatic_gain_control);
+
+ // Only count for captures from desktop media picker dialog and system loop
+ // back audio.
+ if (device->type == MEDIA_DESKTOP_AUDIO_CAPTURE &&
+ (device_id == media::AudioDeviceDescription::kLoopbackInputDeviceId ||
+ device_id ==
+ media::AudioDeviceDescription::kLoopbackWithMuteDeviceId)) {
+ IncrementDesktopCaptureCounter(SYSTEM_LOOPBACK_AUDIO_CAPTURER_CREATED);
+ }
+ }
+ DCHECK(controller_);
+
+ audio_log_->OnCreated(stream_id, audio_parameters, device_id);
+ MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry(
+ stream_id, render_process_id_, render_frame_id, audio_log_.get());
+}
+
+AudioInputDelegateImpl::~AudioInputDelegateImpl() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ audio_log_->OnClosed(stream_id_);
+ LogMessage(stream_id_, "Closing stream");
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&NotifyProcessHostStreamRemoved, render_process_id_));
+
+ // We pass |controller_event_handler_| and |writer_| in here to make sure they
+ // stay alive until |controller_| has finished closing.
+ controller_->Close(base::BindOnce(
+ [](int stream_id, std::unique_ptr<ControllerEventHandler>,
+ std::unique_ptr<AudioInputSyncWriter>) {
+ LogMessage(stream_id, "Stream is now closed");
+ },
+ stream_id_, std::move(controller_event_handler_), std::move(writer_)));
+}
+
+int AudioInputDelegateImpl::GetStreamId() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ return stream_id_;
+}
+
+void AudioInputDelegateImpl::OnRecordStream() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ LogMessage(stream_id_, "OnRecordStream");
+ controller_->Record();
+ audio_log_->OnStarted(stream_id_);
+}
+
+void AudioInputDelegateImpl::OnSetVolume(double volume) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_GE(volume, 0);
+ DCHECK_LE(volume, 1);
+ controller_->SetVolume(volume);
+ audio_log_->OnSetVolume(stream_id_, volume);
+}
+
+void AudioInputDelegateImpl::SendCreatedNotification(bool initially_muted) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(foreign_socket_);
+ subscriber_->OnStreamCreated(stream_id_, writer_->shared_memory(),
+ std::move(foreign_socket_), initially_muted);
+}
+
+void AudioInputDelegateImpl::OnMuted(bool is_muted) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ subscriber_->OnMuted(stream_id_, is_muted);
+}
+
+void AudioInputDelegateImpl::OnError() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ audio_log_->OnError(stream_id_);
+ subscriber_->OnStreamError(stream_id_);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/audio_input_delegate_impl.h b/chromium/content/browser/renderer_host/media/audio_input_delegate_impl.h
new file mode 100644
index 00000000000..14d302319c7
--- /dev/null
+++ b/chromium/content/browser/renderer_host/media/audio_input_delegate_impl.h
@@ -0,0 +1,107 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_DELEGATE_IMPL_H_
+#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_DELEGATE_IMPL_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/renderer_host/media/audio_input_device_manager.h"
+#include "content/common/content_export.h"
+#include "media/audio/audio_input_delegate.h"
+
+namespace media {
+class AudioLog;
+class AudioManager;
+class AudioInputController;
+class AudioParameters;
+class UserInputMonitor;
+} // namespace media
+
+namespace content {
+
+class AudioInputSyncWriter;
+class AudioInputDeviceManager;
+class AudioMirroringManager;
+struct MediaStreamDevice;
+
+// This class is operated on the IO thread.
+class CONTENT_EXPORT AudioInputDelegateImpl : public media::AudioInputDelegate {
+ public:
+ class ControllerEventHandler;
+
+ ~AudioInputDelegateImpl() override;
+
+ static std::unique_ptr<media::AudioInputDelegate> Create(
+ EventHandler* subscriber,
+ media::AudioManager* audio_manager,
+ AudioMirroringManager* mirroring_manager,
+ media::UserInputMonitor* user_input_monitor,
+ AudioInputDeviceManager* audio_input_device_manager,
+ std::unique_ptr<media::AudioLog> audio_log,
+ AudioInputDeviceManager::KeyboardMicRegistration
+ keyboard_mic_registration,
+ uint32_t shared_memory_count,
+ int stream_id,
+ int session_id,
+ int render_process_id,
+ int render_frame_id,
+ bool automatic_gain_control,
+ const media::AudioParameters& audio_parameters);
+
+ // AudioInputDelegate implementation.
+ int GetStreamId() override;
+ void OnRecordStream() override;
+ void OnSetVolume(double volume) override;
+
+ private:
+ AudioInputDelegateImpl(
+ EventHandler* subscriber,
+ media::AudioManager* audio_manager,
+ AudioMirroringManager* mirroring_manager,
+ media::UserInputMonitor* user_input_monitor,
+ const media::AudioParameters& audio_parameters,
+ std::unique_ptr<AudioInputSyncWriter> writer,
+ std::unique_ptr<base::CancelableSyncSocket> foreign_socket,
+ std::unique_ptr<media::AudioLog> audio_log,
+ AudioInputDeviceManager::KeyboardMicRegistration
+ keyboard_mic_registration,
+ int stream_id,
+ int render_process_id,
+ int render_frame_id,
+ bool automatic_gain_control,
+ const MediaStreamDevice* device);
+
+ void SendCreatedNotification(bool initially_muted);
+ void OnMuted(bool is_muted);
+ void OnError();
+
+ SEQUENCE_CHECKER(sequence_checker_);
+
+ // This is the event handler |this| sends notifications to.
+ EventHandler* const subscriber_;
+
+ // |controller_event_handler_| proxies events from controller to |this|.
+ // |controller_event_handler_| and |writer_| outlive |this|, see the
+ // destructor for details.
+ std::unique_ptr<ControllerEventHandler> controller_event_handler_;
+ std::unique_ptr<AudioInputSyncWriter> writer_;
+ std::unique_ptr<base::CancelableSyncSocket> foreign_socket_;
+ const std::unique_ptr<media::AudioLog> audio_log_;
+ scoped_refptr<media::AudioInputController> controller_;
+ const AudioInputDeviceManager::KeyboardMicRegistration
+ keyboard_mic_registration_;
+ const int stream_id_;
+ const int render_process_id_;
+ base::WeakPtrFactory<AudioInputDelegateImpl> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioInputDelegateImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_DELEGATE_IMPL_H_
diff --git a/chromium/content/browser/renderer_host/media/audio_input_delegate_impl_unittest.cc b/chromium/content/browser/renderer_host/media/audio_input_delegate_impl_unittest.cc
new file mode 100644
index 00000000000..86128044a16
--- /dev/null
+++ b/chromium/content/browser/renderer_host/media/audio_input_delegate_impl_unittest.cc
@@ -0,0 +1,345 @@
+// 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/renderer_host/media/audio_input_delegate_impl.h"
+
+#include <stdint.h>
+
+#include <limits>
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/optional.h"
+#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "base/sync_socket.h"
+#include "build/build_config.h"
+#include "content/browser/media/capture/audio_mirroring_manager.h"
+#include "content/browser/media/media_internals.h"
+#include "content/browser/renderer_host/media/audio_sync_reader.h"
+#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/media_observer.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "media/audio/audio_output_controller.h"
+#include "media/audio/audio_system_impl.h"
+#include "media/audio/fake_audio_input_stream.h"
+#include "media/audio/mock_audio_manager.h"
+#include "media/audio/test_audio_thread.h"
+#include "media/base/bind_to_current_loop.h"
+#include "media/base/gmock_callback_support.h"
+#include "media/base/media_switches.h"
+#include "media/base/user_input_monitor.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::Mock;
+using ::testing::InSequence;
+using ::testing::DoubleEq;
+using ::testing::AtLeast;
+using ::testing::NotNull;
+using ::testing::StrictMock;
+using ::testing::NiceMock;
+using ::testing::Return;
+
+namespace content {
+
+namespace {
+
+const int kRenderProcessId = 1;
+const int kRenderFrameId = 5;
+const int kStreamId = 50;
+const uint32_t kDefaultSharedMemoryCount = 10;
+const double kNewVolume = 0.618;
+const double kVolumeScale = 2.71828;
+const bool kDoEnableAGC = true;
+const bool kDoNotEnableAGC = false;
+const char* kDefaultDeviceId = "default";
+const char* kDefaultDeviceName = "default";
+
+media::AudioParameters ValidAudioParameters() {
+ return media::AudioParameters::UnavailableDeviceParams();
+}
+
+class MockEventHandler : public media::AudioInputDelegate::EventHandler {
+ public:
+ void OnStreamCreated(int stream_id,
+ const base::SharedMemory*,
+ std::unique_ptr<base::CancelableSyncSocket>,
+ bool initially_muted) override {
+ MockOnStreamCreated(stream_id, initially_muted);
+ }
+
+ MOCK_METHOD2(MockOnStreamCreated, void(int, bool));
+ MOCK_METHOD2(OnMuted, void(int, bool));
+ MOCK_METHOD1(OnStreamError, void(int));
+};
+
+class MockUserInputMonitor : public media::UserInputMonitor {
+ public:
+ MockUserInputMonitor() {}
+
+ size_t GetKeyPressCount() const { return 0; }
+
+ MOCK_METHOD0(StartKeyboardMonitoring, void());
+ MOCK_METHOD0(StopKeyboardMonitoring, void());
+};
+
+media::AudioOutputStream* ExpectNoOutputStreamCreation(
+ const media::AudioParameters&,
+ const std::string&) {
+ CHECK(false);
+ return nullptr;
+}
+
+media::AudioInputStream* ExpectNoInputStreamCreation(
+ const media::AudioParameters&,
+ const std::string&) {
+ CHECK(false);
+ return nullptr;
+}
+
+class MockAudioInputStream : public media::AudioInputStream {
+ public:
+ MockAudioInputStream() {}
+ ~MockAudioInputStream() override {}
+
+ MOCK_METHOD0(Open, bool());
+ MOCK_METHOD1(Start, void(AudioInputCallback*));
+ MOCK_METHOD0(Stop, void());
+ MOCK_METHOD0(Close, void());
+ MOCK_METHOD0(GetMaxVolume, double());
+ MOCK_METHOD1(SetVolume, void(double));
+ MOCK_METHOD0(GetVolume, double());
+ MOCK_METHOD1(SetAutomaticGainControl, bool(bool));
+ MOCK_METHOD0(GetAutomaticGainControl, bool());
+ MOCK_METHOD0(IsMuted, bool());
+};
+
+media::AudioInputStream* MakeInputStreamCallback(
+ media::AudioInputStream* stream,
+ bool* created,
+ const media::AudioParameters&,
+ const std::string&) {
+ CHECK(!*created);
+ *created = true;
+ return stream;
+}
+
+} // namespace
+
+// These tests are single-threaded.
+// In the real life we have AudioManager living on separate thread (or on the UI
+// thread on Mac), but AudioInputDelegate interacts with it on the IO thread via
+// AudioInputController, so we don't care much about AudioManager threading and
+// can use the main thread to run it. AudioInputDelegate lives on the IO thread,
+// it only posts notifications to the UI thread. MediaStreamManager lives on the
+// UI thread, but AID interacts with it on the IO thread, so we can have the IO
+// thread as a main thread for tests
+class AudioInputDelegateTest : public testing::Test {
+ public:
+ AudioInputDelegateTest()
+ : thread_bundle_(base::in_place),
+ audio_manager_(std::make_unique<media::TestAudioThread>()),
+ audio_system_(&audio_manager_),
+ media_stream_manager_(&audio_system_, audio_manager_.GetTaskRunner()) {
+ audio_manager_.SetMakeInputStreamCB(
+ base::BindRepeating(&ExpectNoInputStreamCreation));
+ audio_manager_.SetMakeOutputStreamCB(
+ base::BindRepeating(&ExpectNoOutputStreamCreation));
+ }
+
+ ~AudioInputDelegateTest() {
+ audio_manager_.Shutdown();
+
+ // MediaStreamManager expects to outlive the IO thread.
+ thread_bundle_.reset();
+ }
+
+ protected:
+ // Streams must be opened with AudioInputDeviceManager before
+ // AudioInputDelegateImpl will allow them to be used.
+ int MakeDeviceAvailable(const std::string& device_id,
+ const std::string& name) {
+ int session_id = media_stream_manager_.audio_input_device_manager()->Open(
+ MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, device_id, name));
+ base::RunLoop().RunUntilIdle();
+ return session_id;
+ }
+
+ std::unique_ptr<media::AudioInputDelegate> CreateDelegate(
+ uint32_t shared_memory_count,
+ int session_id,
+ bool enable_agc) {
+ return AudioInputDelegateImpl::Create(
+ &event_handler_, &audio_manager_, AudioMirroringManager::GetInstance(),
+ &user_input_monitor_,
+ media_stream_manager_.audio_input_device_manager(),
+ MediaInternals::GetInstance()->CreateAudioLog(
+ media::AudioLogFactory::AudioComponent::AUDIO_INPUT_CONTROLLER),
+ AudioInputDeviceManager::KeyboardMicRegistration(),
+ shared_memory_count, kStreamId, session_id, kRenderProcessId,
+ kRenderFrameId, enable_agc, ValidAudioParameters());
+ }
+
+ base::Optional<TestBrowserThreadBundle> thread_bundle_;
+ media::MockAudioManager audio_manager_;
+ media::AudioSystemImpl audio_system_;
+ MediaStreamManager media_stream_manager_;
+ NiceMock<MockUserInputMonitor> user_input_monitor_;
+ StrictMock<MockEventHandler> event_handler_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AudioInputDelegateTest);
+};
+
+TEST_F(AudioInputDelegateTest,
+ CreateWithoutAuthorization_FailsDelegateCreation) {
+ EXPECT_EQ(CreateDelegate(kDefaultSharedMemoryCount, 0, kDoNotEnableAGC),
+ nullptr);
+
+ // Ensure |event_handler_| didn't get any notifications.
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(AudioInputDelegateTest,
+ CreateWithTooManySegments_FailsDelegateCreation) {
+ int session_id = MakeDeviceAvailable(kDefaultDeviceId, kDefaultDeviceName);
+
+ EXPECT_EQ(CreateDelegate(std::numeric_limits<uint32_t>::max(), session_id,
+ kDoNotEnableAGC),
+ nullptr);
+
+ // Ensure |event_handler_| didn't get any notifications. Also verifies that
+ // no AudioManager stream is created.
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(AudioInputDelegateTest, CreateWebContentsCaptureStream) {
+ int session_id = MakeDeviceAvailable(
+ base::StringPrintf("web-contents-media-stream://%d:%d", kRenderProcessId,
+ kRenderFrameId),
+ "Web contents stream");
+ EXPECT_NE(
+ CreateDelegate(kDefaultSharedMemoryCount, session_id, kDoNotEnableAGC),
+ nullptr);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(AudioInputDelegateTest, CreateOrdinaryCaptureStream) {
+ int session_id = MakeDeviceAvailable(kDefaultDeviceId, kDefaultDeviceName);
+
+ auto delegate =
+ CreateDelegate(kDefaultSharedMemoryCount, session_id, kDoNotEnableAGC);
+ EXPECT_NE(delegate, nullptr);
+
+ StrictMock<MockAudioInputStream> stream;
+ EXPECT_CALL(stream, Open()).WillOnce(Return(true));
+ EXPECT_CALL(stream, SetAutomaticGainControl(false))
+
+ .WillOnce(Return(true));
+ EXPECT_CALL(stream, IsMuted()).WillOnce(Return(false));
+ EXPECT_CALL(event_handler_, MockOnStreamCreated(kStreamId, false));
+ bool created = false;
+ audio_manager_.SetMakeInputStreamCB(
+ base::BindRepeating(&MakeInputStreamCallback, &stream, &created));
+
+ base::RunLoop().RunUntilIdle();
+ delegate.reset();
+ EXPECT_CALL(stream, Close());
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(AudioInputDelegateTest, CreateOrdinaryStreamWithAGC_AGCPropagates) {
+ int session_id = MakeDeviceAvailable(kDefaultDeviceId, kDefaultDeviceName);
+
+ auto delegate =
+ CreateDelegate(kDefaultSharedMemoryCount, session_id, kDoEnableAGC);
+ EXPECT_NE(delegate, nullptr);
+
+ StrictMock<MockAudioInputStream> stream;
+ EXPECT_CALL(stream, Open()).WillOnce(Return(true));
+ EXPECT_CALL(stream, SetAutomaticGainControl(true))
+
+ .WillOnce(Return(true));
+ EXPECT_CALL(stream, IsMuted()).WillOnce(Return(false));
+ EXPECT_CALL(event_handler_, MockOnStreamCreated(kStreamId, false));
+ bool created = false;
+ audio_manager_.SetMakeInputStreamCB(
+ base::BindRepeating(&MakeInputStreamCallback, &stream, &created));
+
+ base::RunLoop().RunUntilIdle();
+ delegate.reset();
+ EXPECT_CALL(stream, Close());
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(AudioInputDelegateTest, Record) {
+ int session_id = MakeDeviceAvailable(kDefaultDeviceId, kDefaultDeviceName);
+
+ auto delegate =
+ CreateDelegate(kDefaultSharedMemoryCount, session_id, kDoNotEnableAGC);
+ EXPECT_NE(delegate, nullptr);
+
+ StrictMock<MockAudioInputStream> stream;
+ EXPECT_CALL(stream, Open()).WillOnce(Return(true));
+ EXPECT_CALL(stream, SetAutomaticGainControl(false))
+
+ .WillOnce(Return(true));
+ EXPECT_CALL(stream, IsMuted()).WillOnce(Return(false));
+ EXPECT_CALL(event_handler_, MockOnStreamCreated(kStreamId, false));
+ bool created = false;
+ audio_manager_.SetMakeInputStreamCB(
+ base::BindRepeating(&MakeInputStreamCallback, &stream, &created));
+
+ base::RunLoop().RunUntilIdle();
+
+ delegate->OnRecordStream();
+ EXPECT_CALL(stream, Start(NotNull()));
+ base::RunLoop().RunUntilIdle();
+
+ delegate.reset();
+ EXPECT_CALL(stream, Stop());
+ EXPECT_CALL(stream, Close());
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(AudioInputDelegateTest, SetVolume) {
+ int session_id = MakeDeviceAvailable(kDefaultDeviceId, kDefaultDeviceName);
+
+ auto delegate =
+ CreateDelegate(kDefaultSharedMemoryCount, session_id, kDoNotEnableAGC);
+ EXPECT_NE(delegate, nullptr);
+
+ StrictMock<MockAudioInputStream> stream;
+ EXPECT_CALL(stream, Open()).WillOnce(Return(true));
+ EXPECT_CALL(stream, SetAutomaticGainControl(false))
+
+ .WillOnce(Return(true));
+ EXPECT_CALL(stream, IsMuted()).WillOnce(Return(false));
+ EXPECT_CALL(event_handler_, MockOnStreamCreated(kStreamId, false));
+ bool created = false;
+ audio_manager_.SetMakeInputStreamCB(
+ base::BindRepeating(&MakeInputStreamCallback, &stream, &created));
+
+ base::RunLoop().RunUntilIdle();
+
+ delegate->OnSetVolume(kNewVolume);
+
+ // Note: The AudioInputController is supposed to access the max volume of the
+ // stream and map [0, 1] to [0, max_volume].
+ EXPECT_CALL(stream, GetMaxVolume()).WillOnce(Return(kVolumeScale));
+ EXPECT_CALL(stream, SetVolume(DoubleEq(kNewVolume * kVolumeScale)));
+ base::RunLoop().RunUntilIdle();
+
+ delegate.reset();
+ EXPECT_CALL(stream, Close());
+ base::RunLoop().RunUntilIdle();
+}
+
+} // namespace content
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 0bf8206b3f6..1259826036f 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
@@ -132,9 +132,6 @@ void AudioInputDeviceManager::Close(int session_id) {
}
#if defined(OS_CHROMEOS)
-AudioInputDeviceManager::KeyboardMicRegistration::KeyboardMicRegistration()
- : shared_registration_count_(nullptr) {}
-
AudioInputDeviceManager::KeyboardMicRegistration::KeyboardMicRegistration(
KeyboardMicRegistration&& other)
: shared_registration_count_(other.shared_registration_count_) {
@@ -142,15 +139,6 @@ AudioInputDeviceManager::KeyboardMicRegistration::KeyboardMicRegistration(
other.shared_registration_count_ = nullptr;
}
-AudioInputDeviceManager::KeyboardMicRegistration&
-AudioInputDeviceManager::KeyboardMicRegistration::operator=(
- KeyboardMicRegistration&& other) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DeregisterIfNeeded();
- shared_registration_count_ = other.shared_registration_count_;
- return *this;
-}
-
AudioInputDeviceManager::KeyboardMicRegistration::~KeyboardMicRegistration() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DeregisterIfNeeded();
diff --git a/chromium/content/browser/renderer_host/media/audio_input_device_manager.h b/chromium/content/browser/renderer_host/media/audio_input_device_manager.h
index 54e344166a3..d8db44f8b9f 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_device_manager.h
+++ b/chromium/content/browser/renderer_host/media/audio_input_device_manager.h
@@ -52,15 +52,15 @@ class CONTENT_EXPORT AudioInputDeviceManager : public MediaStreamProvider {
int Open(const MediaStreamDevice& device) override;
void Close(int session_id) override;
-#if defined(OS_CHROMEOS)
- // Owns a keyboard mic stream registration.
+ // Owns a keyboard mic stream registration. Dummy implementation on platforms
+ // other than Chrome OS.
class KeyboardMicRegistration {
public:
+#if defined(OS_CHROMEOS)
// No registration.
- KeyboardMicRegistration();
+ KeyboardMicRegistration() = default;
KeyboardMicRegistration(KeyboardMicRegistration&& other);
- KeyboardMicRegistration& operator=(KeyboardMicRegistration&& other);
~KeyboardMicRegistration();
@@ -75,9 +75,11 @@ class CONTENT_EXPORT AudioInputDeviceManager : public MediaStreamProvider {
// a member of the AudioInputDeviceManager, which lives as long as the IO
// thread, so the pointer will be valid for the lifetime of the
// registration.
- int* shared_registration_count_;
+ int* shared_registration_count_ = nullptr;
+#endif
};
+#if defined(OS_CHROMEOS)
// Registers that a stream using keyboard mic has been opened or closed.
// Keeps count of how many such streams are open and activates and
// inactivates the keyboard mic accordingly. The (in)activation is done on the
diff --git a/chromium/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc b/chromium/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
index 0d5a5cf87b7..6d9c4616075 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
@@ -66,7 +66,7 @@ class MAYBE_AudioInputDeviceManagerTest : public testing::Test {
// AudioInputDeviceManager accesses AudioSystem from IO thread, so it never
// runs on the same thread with it, even on Mac.
audio_manager_ = media::AudioManager::CreateForTesting(
- base::MakeUnique<media::AudioThreadImpl>());
+ std::make_unique<media::AudioThreadImpl>());
// Flush the message loop to ensure proper initialization of AudioManager.
base::RunLoop().RunUntilIdle();
diff --git a/chromium/content/browser/renderer_host/media/audio_input_renderer_host.cc b/chromium/content/browser/renderer_host/media/audio_input_renderer_host.cc
index 03e99adde9b..2575cf05fe9 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_renderer_host.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -7,41 +7,22 @@
#include <utility>
#include "base/bind.h"
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/files/file.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/histogram_macros.h"
-#include "base/numerics/safe_math.h"
-#include "base/process/process.h"
-#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/sync_socket.h"
#include "build/build_config.h"
#include "content/browser/bad_message.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_delegate_impl.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
-#include "content/browser/renderer_host/media/audio_input_sync_writer.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
-#include "content/browser/webrtc/webrtc_internals.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/web_contents_media_capture_id.h"
-#include "media/audio/audio_device_description.h"
-#include "media/base/audio_bus.h"
-#include "media/base/media_switches.h"
-#include "media/media_features.h"
+#include "media/audio/audio_manager.h"
namespace content {
namespace {
-#if BUILDFLAG(ENABLE_WEBRTC)
-const base::FilePath::CharType kDebugRecordingFileNameAddition[] =
- FILE_PATH_LITERAL("source_input");
-#endif
-
void LogMessage(int stream_id, const std::string& msg, bool add_prefix) {
std::ostringstream oss;
oss << "[stream_id=" << stream_id << "] ";
@@ -53,52 +34,8 @@ void LogMessage(int stream_id, const std::string& msg, bool add_prefix) {
DVLOG(1) << message;
}
-void NotifyProcessHostStreamAdded(int render_process_id) {
- auto* process_host = RenderProcessHost::FromID(render_process_id);
- if (process_host)
- process_host->OnMediaStreamAdded();
-}
-
-void NotifyProcessHostStreamRemoved(int render_process_id) {
- auto* process_host = RenderProcessHost::FromID(render_process_id);
- if (process_host)
- process_host->OnMediaStreamRemoved();
-}
-
} // namespace
-struct AudioInputRendererHost::AudioEntry {
- AudioEntry();
- ~AudioEntry();
-
- // The AudioInputController that manages the audio input stream.
- scoped_refptr<media::AudioInputController> controller;
-
- // The audio input stream ID in the RenderFrame.
- int stream_id;
-
- // The synchronous writer to be used by the controller. We have the
- // ownership of the writer.
- std::unique_ptr<AudioInputSyncWriter> writer;
-
- // The socket, paired with |writer|s socket, which should be used on the
- // remote end.
- base::CancelableSyncSocket foreign_socket;
-
- // Set to true after we called Close() for the controller.
- bool pending_close;
-
-#if defined(OS_CHROMEOS)
- AudioInputDeviceManager::KeyboardMicRegistration keyboard_mic_registration;
-#endif
-};
-
-AudioInputRendererHost::AudioEntry::AudioEntry()
- : stream_id(0), pending_close(false) {}
-
-AudioInputRendererHost::AudioEntry::~AudioEntry() {
-}
-
AudioInputRendererHost::AudioInputRendererHost(
int render_process_id,
media::AudioManager* audio_manager,
@@ -107,7 +44,6 @@ AudioInputRendererHost::AudioInputRendererHost(
media::UserInputMonitor* user_input_monitor)
: BrowserMessageFilter(AudioMsgStart),
render_process_id_(render_process_id),
- renderer_pid_(0),
audio_manager_(audio_manager),
media_stream_manager_(media_stream_manager),
audio_mirroring_manager_(audio_mirroring_manager),
@@ -117,92 +53,35 @@ AudioInputRendererHost::AudioInputRendererHost(
AudioInputRendererHost::~AudioInputRendererHost() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(audio_entries_.empty());
-}
-
-#if BUILDFLAG(ENABLE_WEBRTC)
-void AudioInputRendererHost::EnableDebugRecording(const base::FilePath& file) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (audio_entries_.empty())
- return;
- base::FilePath file_with_extensions =
- GetDebugRecordingFilePathWithExtensions(file);
- for (const auto& entry : audio_entries_)
- EnableDebugRecordingForId(file_with_extensions, entry.first);
-}
-
-void AudioInputRendererHost::DisableDebugRecording() {
- for (const auto& entry : audio_entries_) {
- entry.second->controller->DisableDebugRecording();
- }
+ DCHECK(delegates_.empty());
}
-#endif // ENABLE_WEBRTC
void AudioInputRendererHost::OnChannelClosing() {
- // Since the IPC sender is gone, close all requested audio streams.
- DeleteEntries();
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // Since the IPC sender is gone, close all audio streams.
+ delegates_.clear();
}
void AudioInputRendererHost::OnDestruct() const {
BrowserThread::DeleteOnIOThread::Destruct(this);
}
-void AudioInputRendererHost::OnCreated(media::AudioInputController* controller,
- bool initially_muted) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AudioInputRendererHost::DoCompleteCreation, this,
- base::RetainedRef(controller), initially_muted));
-}
-
-void AudioInputRendererHost::OnError(media::AudioInputController* controller,
- media::AudioInputController::ErrorCode error_code) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AudioInputRendererHost::DoHandleError, this,
- base::RetainedRef(controller), error_code));
-}
-
-void AudioInputRendererHost::OnLog(media::AudioInputController* controller,
- const std::string& message) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AudioInputRendererHost::DoLog, this,
- base::RetainedRef(controller), message));
-}
-
-void AudioInputRendererHost::OnMuted(media::AudioInputController* controller,
- bool is_muted) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AudioInputRendererHost::DoNotifyMutedState, this,
- base::RetainedRef(controller), is_muted));
-}
-
-void AudioInputRendererHost::set_renderer_pid(int32_t renderer_pid) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- renderer_pid_ = renderer_pid;
-}
-
-void AudioInputRendererHost::DoCompleteCreation(
- media::AudioInputController* controller,
+void AudioInputRendererHost::OnStreamCreated(
+ int stream_id,
+ const base::SharedMemory* shared_memory,
+ std::unique_ptr<base::CancelableSyncSocket> socket,
bool initially_muted) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- AudioEntry* entry = LookupByController(controller);
- DCHECK(entry);
- AudioInputSyncWriter* writer = entry->writer.get();
- DCHECK(writer);
DCHECK(PeerHandle());
// Once the audio stream is created then complete the creation process by
// mapping shared memory and sharing with the renderer process.
base::SharedMemoryHandle foreign_memory_handle =
- writer->shared_memory()->handle().Duplicate();
+ shared_memory->handle().Duplicate();
if (!foreign_memory_handle.IsValid()) {
// If we failed to map and share the shared memory then close the audio
// stream and send an error message.
- DeleteEntryOnError(entry, MEMORY_SHARING_FAILED);
+ DeleteDelegateOnError(stream_id, MEMORY_SHARING_FAILED);
return;
}
@@ -210,67 +89,36 @@ void AudioInputRendererHost::DoCompleteCreation(
// If we failed to prepare the sync socket for the renderer then we fail
// the construction of audio input stream.
- if (!entry->foreign_socket.PrepareTransitDescriptor(
- PeerHandle(), &socket_transit_descriptor)) {
+ if (!socket->PrepareTransitDescriptor(PeerHandle(),
+ &socket_transit_descriptor)) {
foreign_memory_handle.Close();
- DeleteEntryOnError(entry, SYNC_SOCKET_ERROR);
+ DeleteDelegateOnError(stream_id, SYNC_SOCKET_ERROR);
return;
}
- LogMessage(entry->stream_id,
+ LogMessage(stream_id,
base::StringPrintf("DoCompleteCreation: IPC channel and stream "
- "are now open (initially %s",
- initially_muted ? "muted" : "not muted"),
+ "are now open (initially%s muted)",
+ initially_muted ? "" : " not"),
true);
- Send(new AudioInputMsg_NotifyStreamCreated(
- entry->stream_id, foreign_memory_handle, socket_transit_descriptor,
- initially_muted));
-
- // Free the foreign socket on here since it isn't needed anymore in this
- // process.
- entry->foreign_socket.Close();
+ Send(new AudioInputMsg_NotifyStreamCreated(stream_id, foreign_memory_handle,
+ socket_transit_descriptor,
+ initially_muted));
}
-void AudioInputRendererHost::DoHandleError(
- media::AudioInputController* controller,
- media::AudioInputController::ErrorCode error_code) {
+void AudioInputRendererHost::OnStreamError(int stream_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- AudioEntry* entry = LookupByController(controller);
- DCHECK(entry);
-
- std::ostringstream oss;
- oss << "AIC reports error_code=" << error_code;
- LogMessage(entry->stream_id, oss.str(), false);
-
- audio_log_->OnError(entry->stream_id);
- DeleteEntryOnError(entry, AUDIO_INPUT_CONTROLLER_ERROR);
+ DeleteDelegateOnError(stream_id, AUDIO_INPUT_CONTROLLER_ERROR);
}
-void AudioInputRendererHost::DoLog(media::AudioInputController* controller,
- const std::string& message) {
+void AudioInputRendererHost::OnMuted(int stream_id, bool is_muted) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- AudioEntry* entry = LookupByController(controller);
- DCHECK(entry);
-
- // Add stream ID and current audio level reported by AIC to native log.
- LogMessage(entry->stream_id, message, false);
-}
-
-void AudioInputRendererHost::DoNotifyMutedState(
- media::AudioInputController* controller,
- bool is_muted) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- AudioEntry* entry = LookupByController(controller);
- DCHECK(entry);
- LogMessage(entry->stream_id,
- base::StringPrintf("OnMuted: State changed to: %s",
- (is_muted ? "muted" : "not muted")),
- true);
- Send(new AudioInputMsg_NotifyStreamMuted(entry->stream_id, is_muted));
+ Send(new AudioInputMsg_NotifyStreamMuted(stream_id, is_muted));
}
bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(AudioInputRendererHost, message)
IPC_MESSAGE_HANDLER(AudioInputHostMsg_CreateStream, OnCreateStream)
@@ -297,25 +145,20 @@ void AudioInputRendererHost::OnCreateStream(
->RegisterKeyboardMicStream(
base::BindOnce(&AudioInputRendererHost::DoCreateStream, this,
stream_id, render_frame_id, session_id, config));
- } else {
- DoCreateStream(stream_id, render_frame_id, session_id, config,
- AudioInputDeviceManager::KeyboardMicRegistration());
+ return;
}
-#else
- DoCreateStream(stream_id, render_frame_id, session_id, config);
#endif
+ DoCreateStream(stream_id, render_frame_id, session_id, config,
+ AudioInputDeviceManager::KeyboardMicRegistration());
}
void AudioInputRendererHost::DoCreateStream(
int stream_id,
int render_frame_id,
int session_id,
- const AudioInputHostMsg_CreateStream_Config& config
-#if defined(OS_CHROMEOS)
- ,
- AudioInputDeviceManager::KeyboardMicRegistration keyboard_mic_registration
-#endif
- ) {
+ const AudioInputHostMsg_CreateStream_Config& config,
+ AudioInputDeviceManager::KeyboardMicRegistration
+ keyboard_mic_registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_GT(render_frame_id, 0);
@@ -326,132 +169,44 @@ void AudioInputRendererHost::DoCreateStream(
return;
}
- // Check if we have the permission to open the device and which device to use.
- const MediaStreamDevice* device =
- media_stream_manager_->audio_input_device_manager()->GetOpenedDeviceById(
- session_id);
- if (!device) {
- SendErrorMessage(stream_id, PERMISSION_DENIED);
- DLOG(WARNING) << "No permission has been granted to input stream with "
- << "session_id=" << session_id;
- return;
- }
-
- const MediaStreamType& type = device->type;
- const std::string& device_id = device->id;
- const std::string& device_name = device->name;
- media::AudioParameters audio_params(config.params);
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kUseFakeDeviceForMediaStream)) {
- audio_params.set_format(media::AudioParameters::AUDIO_FAKE);
- }
-
- std::ostringstream oss;
- oss << "[stream_id=" << stream_id << "] "
- << "AIRH::OnCreateStream(render_frame_id=" << render_frame_id
- << ", session_id=" << session_id << ")"
- << ": device_name=" << device_name;
-
- // Create a new AudioEntry structure.
- std::unique_ptr<AudioEntry> entry = base::MakeUnique<AudioEntry>();
-
- entry->writer = AudioInputSyncWriter::Create(
- config.shared_memory_count, audio_params, &entry->foreign_socket);
-
- if (!entry->writer) {
- SendErrorMessage(stream_id, SYNC_WRITER_INIT_FAILED);
- return;
- }
+ std::unique_ptr<media::AudioInputDelegate> delegate =
+ AudioInputDelegateImpl::Create(
+ this, audio_manager_, audio_mirroring_manager_, user_input_monitor_,
+ media_stream_manager_->audio_input_device_manager(),
+ MediaInternals::GetInstance()->CreateAudioLog(
+ media::AudioLogFactory::AUDIO_INPUT_CONTROLLER),
+ std::move(keyboard_mic_registration),
+ config.shared_memory_count, stream_id, session_id, render_process_id_,
+ render_frame_id, config.automatic_gain_control, config.params);
- if (WebContentsMediaCaptureId::Parse(device_id, nullptr)) {
- // For MEDIA_DESKTOP_AUDIO_CAPTURE, the source is selected from picker
- // window, we do not mute the source audio.
- // For MEDIA_TAB_AUDIO_CAPTURE, the probable use case is Cast, we mute
- // the source audio.
- // TODO(qiangchen): Analyze audio constraints to make a duplicating or
- // diverting decision. It would give web developer more flexibility.
- entry->controller = media::AudioInputController::CreateForStream(
- audio_manager_->GetTaskRunner(), this,
- WebContentsAudioInputStream::Create(
- device_id, audio_params, audio_manager_->GetWorkerTaskRunner(),
- audio_mirroring_manager_),
- entry->writer.get(), user_input_monitor_,
- audio_params);
- // Only count for captures from desktop media picker dialog.
- if (entry->controller.get() && type == MEDIA_DESKTOP_AUDIO_CAPTURE)
- IncrementDesktopCaptureCounter(TAB_AUDIO_CAPTURER_CREATED);
- } else {
- entry->controller = media::AudioInputController::Create(
- audio_manager_, this, entry->writer.get(), user_input_monitor_,
- audio_params, device_id, config.automatic_gain_control);
- oss << ", AGC=" << config.automatic_gain_control;
-
- // Only count for captures from desktop media picker dialog and system loop
- // back audio.
- if (entry->controller.get() && type == MEDIA_DESKTOP_AUDIO_CAPTURE &&
- (device_id == media::AudioDeviceDescription::kLoopbackInputDeviceId ||
- device_id ==
- media::AudioDeviceDescription::kLoopbackWithMuteDeviceId)) {
- IncrementDesktopCaptureCounter(SYSTEM_LOOPBACK_AUDIO_CAPTURER_CREATED);
- }
- }
+ if (!delegate) {
+ // Error was logged by AudioInputDelegateImpl::Create.
+ Send(new AudioInputMsg_NotifyStreamError(stream_id));
- if (!entry->controller.get()) {
- SendErrorMessage(stream_id, STREAM_CREATE_ERROR);
return;
}
-#if defined(OS_CHROMEOS)
- entry->keyboard_mic_registration = std::move(keyboard_mic_registration);
-#endif
-
- const std::string log_message = oss.str();
- MediaStreamManager::SendMessageToNativeLog(log_message);
- DVLOG(1) << log_message;
-
- // Since the controller was created successfully, create an entry and add it
- // to the map.
- entry->stream_id = stream_id;
- audio_entries_.insert(std::make_pair(stream_id, entry.release()));
- audio_log_->OnCreated(stream_id, audio_params, device_id);
- MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry(
- stream_id, render_process_id_, render_frame_id, audio_log_.get());
-
- // Prevent process backgrounding while audio input is active:
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&NotifyProcessHostStreamAdded, render_process_id_));
-
-#if BUILDFLAG(ENABLE_WEBRTC)
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&AudioInputRendererHost::MaybeEnableDebugRecordingForId,
- this, stream_id));
-#endif
+ delegates_.emplace(stream_id, std::move(delegate));
}
void AudioInputRendererHost::OnRecordStream(int stream_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
LogMessage(stream_id, "OnRecordStream", true);
- AudioEntry* entry = LookupById(stream_id);
- if (!entry) {
+ media::AudioInputDelegate* delegate = LookupById(stream_id);
+ if (!delegate) {
SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY);
return;
}
- entry->controller->Record();
- audio_log_->OnStarted(stream_id);
+ delegate->OnRecordStream();
}
void AudioInputRendererHost::OnCloseStream(int stream_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
LogMessage(stream_id, "OnCloseStream", true);
- AudioEntry* entry = LookupById(stream_id);
-
- if (entry)
- CloseAndDeleteStream(entry);
+ delegates_.erase(stream_id);
}
void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) {
@@ -463,18 +218,18 @@ void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) {
return;
}
- AudioEntry* entry = LookupById(stream_id);
- if (!entry) {
+ media::AudioInputDelegate* delegate = LookupById(stream_id);
+ if (!delegate) {
SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY);
return;
}
- entry->controller->SetVolume(volume);
- audio_log_->OnSetVolume(stream_id, volume);
+ delegate->OnSetVolume(volume);
}
void AudioInputRendererHost::SendErrorMessage(
int stream_id, ErrorCode error_code) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::string err_msg =
base::StringPrintf("SendErrorMessage(error_code=%d)", error_code);
LogMessage(stream_id, err_msg, true);
@@ -482,127 +237,20 @@ void AudioInputRendererHost::SendErrorMessage(
Send(new AudioInputMsg_NotifyStreamError(stream_id));
}
-void AudioInputRendererHost::DeleteEntries() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- for (AudioEntryMap::iterator i = audio_entries_.begin();
- i != audio_entries_.end(); ++i) {
- CloseAndDeleteStream(i->second);
- }
-}
-
-void AudioInputRendererHost::CloseAndDeleteStream(AudioEntry* entry) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (!entry->pending_close) {
- LogMessage(entry->stream_id, "CloseAndDeleteStream", true);
- entry->controller->Close(
- base::BindOnce(&AudioInputRendererHost::DeleteEntry, this, entry));
- entry->pending_close = true;
- audio_log_->OnClosed(entry->stream_id);
-
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&NotifyProcessHostStreamRemoved, render_process_id_));
- }
-}
-
-void AudioInputRendererHost::DeleteEntry(AudioEntry* entry) {
+void AudioInputRendererHost::DeleteDelegateOnError(int stream_id,
+ ErrorCode error_code) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- LogMessage(entry->stream_id, "DeleteEntry: stream is now closed", true);
-
- // Delete the entry when this method goes out of scope.
- std::unique_ptr<AudioEntry> entry_deleter(entry);
-
- // Erase the entry from the map.
- audio_entries_.erase(entry->stream_id);
+ SendErrorMessage(stream_id, error_code);
+ delegates_.erase(stream_id);
}
-void AudioInputRendererHost::DeleteEntryOnError(AudioEntry* entry,
- ErrorCode error_code) {
+media::AudioInputDelegate* AudioInputRendererHost::LookupById(int stream_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // Sends the error message first before we close the stream because
- // |entry| is destroyed in DeleteEntry().
- SendErrorMessage(entry->stream_id, error_code);
- CloseAndDeleteStream(entry);
-}
-
-AudioInputRendererHost::AudioEntry* AudioInputRendererHost::LookupById(
- int stream_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- AudioEntryMap::iterator i = audio_entries_.find(stream_id);
- if (i != audio_entries_.end())
- return i->second;
- return nullptr;
-}
-
-AudioInputRendererHost::AudioEntry* AudioInputRendererHost::LookupByController(
- media::AudioInputController* controller) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- // Iterate the map of entries.
- // TODO(hclam): Implement a faster look up method.
- for (AudioEntryMap::iterator i = audio_entries_.begin();
- i != audio_entries_.end(); ++i) {
- if (controller == i->second->controller.get())
- return i->second;
- }
+ AudioInputDelegateMap::iterator i = delegates_.find(stream_id);
+ if (i != delegates_.end())
+ return i->second.get();
return nullptr;
}
-#if BUILDFLAG(ENABLE_WEBRTC)
-void AudioInputRendererHost::MaybeEnableDebugRecordingForId(int stream_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (WebRTCInternals::GetInstance()->IsAudioDebugRecordingsEnabled()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &AudioInputRendererHost::
- AddExtensionsToPathAndEnableDebugRecordingForId,
- this,
- WebRTCInternals::GetInstance()->GetAudioDebugRecordingsFilePath(),
- stream_id));
- }
-}
-
-#if defined(OS_WIN)
-#define IntToStringType base::IntToString16
-#else
-#define IntToStringType base::IntToString
-#endif
-
-base::FilePath AudioInputRendererHost::GetDebugRecordingFilePathWithExtensions(
- const base::FilePath& file) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // We expect |renderer_pid_| to be set.
- DCHECK_GT(renderer_pid_, 0);
- return file.AddExtension(IntToStringType(renderer_pid_))
- .AddExtension(kDebugRecordingFileNameAddition);
-}
-
-void AudioInputRendererHost::EnableDebugRecordingForId(
- const base::FilePath& file_name,
- int stream_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- AudioEntry* entry = LookupById(stream_id);
- if (!entry)
- return;
- entry->controller->EnableDebugRecording(
- file_name.AddExtension(IntToStringType(stream_id)));
-}
-
-#undef IntToStringType
-
-void AudioInputRendererHost::AddExtensionsToPathAndEnableDebugRecordingForId(
- const base::FilePath& file,
- int stream_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- EnableDebugRecordingForId(GetDebugRecordingFilePathWithExtensions(file),
- stream_id);
-}
-
-#endif // BUILDFLAG(ENABLE_WEBRTC)
-
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/audio_input_renderer_host.h b/chromium/content/browser/renderer_host/media/audio_input_renderer_host.h
index 083a0b2c2e8..5ace30e9864 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_renderer_host.h
+++ b/chromium/content/browser/renderer_host/media/audio_input_renderer_host.h
@@ -34,11 +34,7 @@
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/common/media/audio_messages.h"
#include "content/public/browser/browser_message_filter.h"
-#include "media/audio/audio_input_controller.h"
-
-namespace base {
-class FilePath;
-}
+#include "media/audio/audio_input_delegate.h"
namespace media {
class AudioManager;
@@ -52,15 +48,18 @@ class MediaStreamManager;
class CONTENT_EXPORT AudioInputRendererHost
: public BrowserMessageFilter,
- public media::AudioInputController::EventHandler {
+ public media::AudioInputDelegate::EventHandler {
public:
// Error codes to make native logging more clear. These error codes are added
// to generic error strings to provide a higher degree of details.
// Changing these values can lead to problems when matching native debug
// logs with the actual cause of error.
enum ErrorCode {
- // An unspecified error occured.
- UNKNOWN_ERROR = 0,
+ // Note: usage of many of these codes have been replaced with textual log
+ // messages.
+
+ // An unspecified error occured. Not used.
+ // UNKNOWN_ERROR = 0,
// Failed to look up audio intry for the provided stream id.
INVALID_AUDIO_ENTRY = 1,
@@ -72,14 +71,16 @@ class CONTENT_EXPORT AudioInputRendererHost
PERMISSION_DENIED = 3,
// Failed to create shared memory.
- // Obsolete, merged with SYNC_WRITER_INIT_FAILED.
+ // Obsolete.
// SHARED_MEMORY_CREATE_FAILED = 4
// Failed to initialize the AudioInputSyncWriter instance.
- SYNC_WRITER_INIT_FAILED = 5,
+ // Obsolete.
+ // SYNC_WRITER_INIT_FAILED = 5,
// Failed to create native audio input stream.
- STREAM_CREATE_ERROR = 6,
+ // Obsolete.
+ // STREAM_CREATE_ERROR = 6,
// Failed to map and share the shared memory.
MEMORY_SHARING_FAILED = 7,
@@ -92,36 +93,25 @@ class CONTENT_EXPORT AudioInputRendererHost
};
// Called from UI thread from the owner of this object.
- // |user_input_monitor| is used for typing detection and can be NULL.
+ // |user_input_monitor| is used for typing detection and can be null.
AudioInputRendererHost(int render_process_id,
media::AudioManager* audio_manager,
MediaStreamManager* media_stream_manager,
AudioMirroringManager* audio_mirroring_manager,
media::UserInputMonitor* user_input_monitor);
-#if BUILDFLAG(ENABLE_WEBRTC)
- // Enable and disable debug recording of input on all audio entries.
- void EnableDebugRecording(const base::FilePath& file);
- void DisableDebugRecording();
-#endif
-
// BrowserMessageFilter implementation.
void OnChannelClosing() override;
void OnDestruct() const override;
bool OnMessageReceived(const IPC::Message& message) override;
- // AudioInputController::EventHandler implementation.
- void OnCreated(media::AudioInputController* controller,
- bool initially_muted) override;
- void OnError(media::AudioInputController* controller,
- media::AudioInputController::ErrorCode error_code) override;
- void OnLog(media::AudioInputController* controller,
- const std::string& message) override;
- void OnMuted(media::AudioInputController* controller, bool is_muted) override;
-
- // Sets the PID renderer. This is used for constructing the debug recording
- // filename.
- void set_renderer_pid(int32_t renderer_pid);
+ // AudioInputDelegate::EventHandler implementation.
+ void OnStreamCreated(int stream_id,
+ const base::SharedMemory* shared_memory,
+ std::unique_ptr<base::CancelableSyncSocket> socket,
+ bool initially_muted) override;
+ void OnStreamError(int stream_id) override;
+ void OnMuted(int stream_id, bool is_muted) override;
protected:
~AudioInputRendererHost() override;
@@ -130,8 +120,9 @@ class CONTENT_EXPORT AudioInputRendererHost
friend class BrowserThread;
friend class base::DeleteHelper<AudioInputRendererHost>;
- struct AudioEntry;
- typedef std::map<int, AudioEntry*> AudioEntryMap;
+ // Holds the stream_id -> delegate mapping.
+ using AudioInputDelegateMap =
+ base::flat_map<int, std::unique_ptr<media::AudioInputDelegate>>;
// Methods called on IO thread ----------------------------------------------
@@ -154,12 +145,8 @@ class CONTENT_EXPORT AudioInputRendererHost
int stream_id,
int render_frame_id,
int session_id,
- const AudioInputHostMsg_CreateStream_Config& config
-#if defined(OS_CHROMEOS)
- ,
- AudioInputDeviceManager::KeyboardMicRegistration registration
-#endif
- );
+ const AudioInputHostMsg_CreateStream_Config& config,
+ AudioInputDeviceManager::KeyboardMicRegistration registration);
// Record the audio input stream referenced by |stream_id|.
void OnRecordStream(int stream_id);
@@ -173,79 +160,29 @@ class CONTENT_EXPORT AudioInputRendererHost
// Complete the process of creating an audio input stream. This will set up
// the shared memory or shared socket in low latency mode and send the
// NotifyStreamCreated message to the peer.
- void DoCompleteCreation(media::AudioInputController* controller,
- bool initially_muted);
-
- // Send a state change message to the renderer.
- void DoSendRecordingMessage(media::AudioInputController* controller);
+ void DoCompleteCreation(int stream_id, bool initially_muted);
// Handle error coming from audio stream.
- void DoHandleError(media::AudioInputController* controller,
- media::AudioInputController::ErrorCode error_code);
+ void DoHandleError(int stream_id);
// Log audio level of captured audio stream.
- void DoLog(media::AudioInputController* controller,
- const std::string& message);
+ void DoLog(int stream_id, const std::string& message);
// Notify renderer of a change to a stream's muted state.
- void DoNotifyMutedState(media::AudioInputController* controller,
- bool is_muted);
+ void DoNotifyMutedState(int stream_id, bool is_muted);
// Send an error message to the renderer.
void SendErrorMessage(int stream_id, ErrorCode error_code);
- // Delete all audio entries and all audio streams.
- void DeleteEntries();
-
- // Closes the stream. The stream is then deleted in DeleteEntry() after it
- // is closed.
- void CloseAndDeleteStream(AudioEntry* entry);
-
- // Delete an audio entry and close the related audio stream.
- void DeleteEntry(AudioEntry* entry);
-
- // Delete audio entry and close the related audio input stream.
- void DeleteEntryOnError(AudioEntry* entry, ErrorCode error_code);
+ void DeleteDelegateOnError(int stream_id, ErrorCode error_code);
- // A helper method to look up a AudioEntry identified by |stream_id|.
- // Returns NULL if not found.
- AudioEntry* LookupById(int stream_id);
-
- // Search for a AudioEntry having the reference to |controller|.
- // This method is used to look up an AudioEntry after a controller
- // event is received.
- AudioEntry* LookupByController(media::AudioInputController* controller);
-
-#if BUILDFLAG(ENABLE_WEBRTC)
- // TODO(grunell): Move debug recording handling to AudioManager.
- void MaybeEnableDebugRecordingForId(int stream_id);
-
- base::FilePath GetDebugRecordingFilePathWithExtensions(
- const base::FilePath& file);
-
- void EnableDebugRecordingForId(const base::FilePath& file, int stream_id);
-
- // Calls GetDebugRecordingFilePathWithExtensions() and
- // EnableDebugRecordingForId().
- void AddExtensionsToPathAndEnableDebugRecordingForId(
- const base::FilePath& file,
- int stream_id);
-
- void DoEnableDebugRecording(int stream_id, base::File file);
- void DoDisableDebugRecording(int stream_id);
-
- // Delete the debug writer used for debug recordings for |stream_id|.
- void DeleteDebugWriter(int stream_id);
-#endif
+ // A helper method to look up a AudioInputDelegate identified by |stream_id|.
+ // Returns null if not found.
+ media::AudioInputDelegate* LookupById(int stream_id);
// ID of the RenderProcessHost that owns this instance.
const int render_process_id_;
- // PID of the render process connected to the RenderProcessHost that owns this
- // instance.
- int32_t renderer_pid_;
-
- // Used to create an AudioInputController.
media::AudioManager* audio_manager_;
// Used to access to AudioInputDeviceManager.
@@ -254,7 +191,7 @@ class CONTENT_EXPORT AudioInputRendererHost
AudioMirroringManager* audio_mirroring_manager_;
// A map of stream IDs to audio sources.
- AudioEntryMap audio_entries_;
+ AudioInputDelegateMap delegates_;
// Raw pointer of the UserInputMonitor.
media::UserInputMonitor* const user_input_monitor_;
diff --git a/chromium/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc b/chromium/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
index d10f2b29bdc..b28fea1ca11 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
@@ -25,6 +25,7 @@
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "media/audio/audio_device_description.h"
+#include "media/audio/audio_input_controller.h"
#include "media/audio/audio_system_impl.h"
#include "media/audio/fake_audio_log_factory.h"
#include "media/audio/fake_audio_manager.h"
@@ -51,20 +52,13 @@ namespace {
const int kStreamId = 100;
const int kRenderProcessId = 42;
-const int kRendererPid = 21718;
const int kRenderFrameId = 31415;
const int kSharedMemoryCount = 11;
+const double kNewVolume = 0.618;
const char kSecurityOrigin[] = "http://localhost";
-#if BUILDFLAG(ENABLE_WEBRTC)
-#if defined(OS_WIN)
-const wchar_t kBaseFileName[] = L"some_file_name";
-#else
-const char kBaseFileName[] = "some_file_name";
-#endif // defined(OS_WIN)
-#endif // BUILDFLAG(ENABLE_WEBRTC)
url::Origin SecurityOrigin() {
- return url::Origin(GURL(kSecurityOrigin));
+ return url::Origin::Create(GURL(kSecurityOrigin));
}
AudioInputHostMsg_CreateStream_Config DefaultConfig() {
@@ -93,7 +87,6 @@ class AudioInputRendererHostWithInterception : public AudioInputRendererHost {
public:
AudioInputRendererHostWithInterception(
int render_process_id,
- int32_t renderer_pid,
media::AudioManager* audio_manager,
MediaStreamManager* media_stream_manager,
AudioMirroringManager* audio_mirroring_manager,
@@ -106,7 +99,6 @@ class AudioInputRendererHostWithInterception : public AudioInputRendererHost {
user_input_monitor),
renderer_(renderer) {
set_peer_process_for_testing(base::Process::Current());
- set_renderer_pid(renderer_pid);
}
protected:
@@ -175,17 +167,11 @@ class MockAudioInputController : public AudioInputController {
GetTaskRunnerForTesting()->PostTask(
FROM_HERE,
base::BindOnce(&AudioInputController::EventHandler::OnCreated,
- base::Unretained(event_handler), base::Unretained(this),
- false));
- ON_CALL(*this, EnableDebugRecording(_))
- .WillByDefault(SaveArg<0>(&file_name));
+ base::Unretained(event_handler), false));
}
EventHandler* handler() { return GetHandlerForTesting(); }
- // File name that we pretend to do a debug recording to, if any.
- base::FilePath debug_file_name() { return file_name; }
-
void Close(base::OnceClosure cl) override {
DidClose();
// Hop to audio manager thread before calling task, since this is the real
@@ -196,8 +182,6 @@ class MockAudioInputController : public AudioInputController {
MOCK_METHOD0(Record, void());
MOCK_METHOD1(SetVolume, void(double));
- MOCK_METHOD1(EnableDebugRecording, void(const base::FilePath&));
- MOCK_METHOD0(DisableDebugRecording, void());
MOCK_METHOD0(DidClose, void());
@@ -209,9 +193,6 @@ class MockAudioInputController : public AudioInputController {
protected:
~MockAudioInputController() override = default;
-
- private:
- base::FilePath file_name;
};
class MockControllerFactory : public AudioInputController::Factory {
@@ -270,7 +251,7 @@ class AudioInputRendererHostTest : public testing::Test {
media_stream_manager_ = std::make_unique<MediaStreamManager>(
audio_system_.get(), audio_manager_->GetTaskRunner());
airh_ = new AudioInputRendererHostWithInterception(
- kRenderProcessId, kRendererPid, media::AudioManager::Get(),
+ kRenderProcessId, media::AudioManager::Get(),
media_stream_manager_.get(), AudioMirroringManager::GetInstance(),
nullptr, &renderer_);
}
@@ -342,7 +323,7 @@ TEST_F(AudioInputRendererHostTest, CreateWithDefaultDevice) {
EXPECT_CALL(*controller_factory_.controller(0), DidClose());
}
-// If authorization hasn't been granted, only reply with and error and do
+// If authorization hasn't been granted, only reply with an error and do
// nothing else.
TEST_F(AudioInputRendererHostTest, CreateWithoutAuthorization_Error) {
EXPECT_CALL(renderer_, NotifyStreamError(kStreamId));
@@ -401,11 +382,11 @@ TEST_F(AudioInputRendererHostTest, CreateSetVolumeRecordClose) {
kStreamId, kRenderFrameId, session_id, DefaultConfig()));
base::RunLoop().RunUntilIdle();
- EXPECT_CALL(*controller_factory_.controller(0), SetVolume(0.5));
+ EXPECT_CALL(*controller_factory_.controller(0), SetVolume(kNewVolume));
EXPECT_CALL(*controller_factory_.controller(0), Record());
EXPECT_CALL(*controller_factory_.controller(0), DidClose());
- airh_->OnMessageReceived(AudioInputHostMsg_SetVolume(kStreamId, 0.5));
+ airh_->OnMessageReceived(AudioInputHostMsg_SetVolume(kStreamId, kNewVolume));
airh_->OnMessageReceived(AudioInputHostMsg_RecordStream(kStreamId));
airh_->OnMessageReceived(AudioInputHostMsg_CloseStream(kStreamId));
@@ -472,8 +453,7 @@ TEST_F(AudioInputRendererHostTest, CreateTwice_Error) {
}
// Checks that when two streams are created, messages are routed to the correct
-// stream. Also checks that when enabling debug recording, the streams get
-// different file names.
+// stream.
TEST_F(AudioInputRendererHostTest, TwoStreams) {
int session_id =
Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId);
@@ -488,20 +468,13 @@ TEST_F(AudioInputRendererHostTest, TwoStreams) {
kStreamId + 1, kRenderFrameId, session_id, DefaultConfig()));
base::RunLoop().RunUntilIdle();
-#if BUILDFLAG(ENABLE_WEBRTC)
- EXPECT_CALL(*controller_factory_.controller(0), EnableDebugRecording(_));
- EXPECT_CALL(*controller_factory_.controller(1), EnableDebugRecording(_));
-
- airh_->EnableDebugRecording(base::FilePath(kBaseFileName));
+ EXPECT_CALL(*controller_factory_.controller(0), Record());
+ airh_->OnMessageReceived(AudioInputHostMsg_RecordStream(kStreamId));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_CALL(*controller_factory_.controller(1), SetVolume(kNewVolume));
+ airh_->OnMessageReceived(
+ AudioInputHostMsg_SetVolume(kStreamId + 1, kNewVolume));
base::RunLoop().RunUntilIdle();
-
- EXPECT_NE(controller_factory_.controller(0)->debug_file_name(),
- controller_factory_.controller(1)->debug_file_name());
- EXPECT_CALL(*controller_factory_.controller(0), DisableDebugRecording());
- EXPECT_CALL(*controller_factory_.controller(1), DisableDebugRecording());
-
- airh_->DisableDebugRecording();
-#endif // ENABLE_WEBRTC
EXPECT_CALL(*controller_factory_.controller(0), DidClose());
EXPECT_CALL(*controller_factory_.controller(1), DidClose());
@@ -524,7 +497,7 @@ TEST_F(AudioInputRendererHostTest, Error_ClosesController) {
EXPECT_CALL(renderer_, NotifyStreamError(kStreamId));
controller_factory_.controller(0)->handler()->OnError(
- controller_factory_.controller(0), AudioInputController::UNKNOWN_ERROR);
+ AudioInputController::UNKNOWN_ERROR);
// Check Close expectation before the destructor.
base::RunLoop().RunUntilIdle();
diff --git a/chromium/content/browser/renderer_host/media/audio_input_sync_writer.cc b/chromium/content/browser/renderer_host/media/audio_input_sync_writer.cc
index 401f6717a92..18314cbcb5c 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_sync_writer.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_sync_writer.cc
@@ -145,19 +145,19 @@ std::unique_ptr<AudioInputSyncWriter> AudioInputSyncWriter::Create(
media::ComputeAudioInputBufferSizeChecked(params,
shared_memory_segment_count);
- auto shared_memory = base::MakeUnique<base::SharedMemory>();
+ auto shared_memory = std::make_unique<base::SharedMemory>();
if (!requested_memory_size.IsValid() ||
!shared_memory->CreateAndMapAnonymous(
requested_memory_size.ValueOrDie())) {
return nullptr;
}
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
if (!base::CancelableSyncSocket::CreatePair(socket.get(), foreign_socket)) {
return nullptr;
}
- return base::MakeUnique<AudioInputSyncWriter>(
+ return std::make_unique<AudioInputSyncWriter>(
std::move(shared_memory), std::move(socket), shared_memory_segment_count,
params);
}
@@ -176,7 +176,7 @@ void AudioInputSyncWriter::Write(const AudioBus* data,
// writing. We verify that each buffer index is in sequence.
size_t number_of_indices_available = socket_->Peek() / sizeof(uint32_t);
if (number_of_indices_available > 0) {
- auto indices = base::MakeUnique<uint32_t[]>(number_of_indices_available);
+ auto indices = std::make_unique<uint32_t[]>(number_of_indices_available);
size_t bytes_received = socket_->Receive(
&indices[0],
number_of_indices_available * sizeof(indices[0]));
@@ -268,7 +268,7 @@ bool AudioInputSyncWriter::PushDataToFifo(const AudioBus* data,
// We use |write_error_count_| for capping number of log messages.
// |write_error_count_| also includes socket Send() errors, but those should
// be rare.
- if (write_error_count_ <= 50) {
+ if (write_error_count_ <= 50 && write_error_count_ % 10 == 0) {
const std::string error_message = "AISW: No room in fifo.";
LOG(WARNING) << error_message;
AddToNativeLog(error_message);
diff --git a/chromium/content/browser/renderer_host/media/audio_input_sync_writer.h b/chromium/content/browser/renderer_host/media/audio_input_sync_writer.h
index a019918a7dc..117ba515de3 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_sync_writer.h
+++ b/chromium/content/browser/renderer_host/media/audio_input_sync_writer.h
@@ -27,6 +27,10 @@
#include "base/file_descriptor_posix.h"
#endif
+namespace base {
+class SharedMemory;
+}
+
namespace content {
// A AudioInputController::SyncWriter implementation using SyncSocket. This
diff --git a/chromium/content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc b/chromium/content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc
index 314c80d9955..f534f817480 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc
@@ -125,12 +125,12 @@ class AudioInputSyncWriterTest : public testing::Test {
const uint32_t data_size =
media::ComputeAudioInputBufferSize(audio_params, kSegments);
- auto shared_memory = base::MakeUnique<base::SharedMemory>();
+ auto shared_memory = std::make_unique<base::SharedMemory>();
EXPECT_TRUE(shared_memory->CreateAndMapAnonymous(data_size));
- auto socket = base::MakeUnique<MockCancelableSyncSocket>(kSegments);
+ auto socket = std::make_unique<MockCancelableSyncSocket>(kSegments);
socket_ = socket.get();
- writer_ = base::MakeUnique<AudioInputSyncWriterUnderTest>(
+ writer_ = std::make_unique<AudioInputSyncWriterUnderTest>(
std::move(shared_memory), std::move(socket), kSegments, audio_params);
audio_bus_ = AudioBus::Create(audio_params);
}
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 6953638fd28..f8ed5a8763e 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
@@ -4,8 +4,11 @@
#include "content/browser/renderer_host/media/audio_output_authorization_handler.h"
+#include "base/bind.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
#include "base/task_runner_util.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_thread.h"
#include "content/public/browser/media_device_id.h"
@@ -18,65 +21,50 @@ namespace content {
namespace {
-// Returns (by callback) the Origin for the frame and whether it may request
-// nondefault audio devices.
+// Returns (by callback) the Media Device salt and the Origin for the frame and
+// whether it may request nondefault audio devices.
void CheckAccessOnUIThread(
int render_process_id,
int render_frame_id,
bool override_permissions,
bool permissions_override_value,
- base::OnceCallback<void(const url::Origin&, bool)> cb) {
+ base::OnceCallback<void(std::string, const url::Origin&, bool)> cb) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RenderFrameHost* frame =
- RenderFrameHost::FromID(render_process_id, render_frame_id);
- if (!frame) {
- std::move(cb).Run(url::Origin(), false);
- return;
- }
- auto origin = frame->GetLastCommittedOrigin();
+ const auto& salt_and_origin =
+ GetMediaDeviceSaltAndOrigin(render_process_id, render_frame_id);
+ std::string salt = salt_and_origin.first;
+ const url::Origin& origin = salt_and_origin.second;
if (!MediaStreamManager::IsOriginAllowed(render_process_id, origin)) {
// In this case, it's likely a navigation has occurred while processing this
// request.
- std::move(cb).Run(url::Origin(), false);
+ std::move(cb).Run(std::string(), url::Origin(), false);
return;
}
// Check that MediaStream device permissions have been granted for
// nondefault devices.
if (override_permissions) {
- std::move(cb).Run(origin, permissions_override_value);
+ std::move(cb).Run(std::move(salt), origin, permissions_override_value);
return;
}
std::move(cb).Run(
- origin,
+ std::move(salt), origin,
MediaDevicesPermissionChecker().CheckPermissionOnUIThread(
MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, render_process_id, render_frame_id));
}
-url::Origin GetOriginOnUIThread(int render_process_id, int render_frame_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RenderFrameHost* frame =
- RenderFrameHost::FromID(render_process_id, render_frame_id);
- if (!frame)
- return url::Origin();
-
- return frame->GetLastCommittedOrigin();
-}
-
} // namespace
AudioOutputAuthorizationHandler::AudioOutputAuthorizationHandler(
media::AudioSystem* audio_system,
MediaStreamManager* media_stream_manager,
- int render_process_id,
- const std::string& salt)
+ int render_process_id)
: audio_system_(audio_system),
media_stream_manager_(media_stream_manager),
render_process_id_(render_process_id),
- salt_(salt),
weak_factory_(this) {
DCHECK(media_stream_manager_);
}
@@ -120,7 +108,7 @@ void AudioOutputAuthorizationHandler::RequestDeviceAuthorization(
// for hashing the device id before sending it back to the renderer.
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(&GetOriginOnUIThread, render_process_id_,
+ base::BindOnce(&GetMediaDeviceSaltAndOrigin, render_process_id_,
render_frame_id),
base::BindOnce(&AudioOutputAuthorizationHandler::HashDeviceId,
weak_factory_.GetWeakPtr(), std::move(cb),
@@ -155,13 +143,21 @@ void AudioOutputAuthorizationHandler::OverridePermissionsForTesting(
permissions_override_value_ = override_value;
}
+void AudioOutputAuthorizationHandler::UMALogDeviceAuthorizationTime(
+ base::TimeTicks auth_start_time) {
+ UMA_HISTOGRAM_CUSTOM_TIMES("Media.Audio.OutputDeviceAuthorizationTime",
+ base::TimeTicks::Now() - auth_start_time,
+ base::TimeDelta::FromMilliseconds(1),
+ base::TimeDelta::FromMilliseconds(5000), 50);
+}
+
void AudioOutputAuthorizationHandler::HashDeviceId(
AuthorizationCompletedCallback cb,
const std::string& raw_device_id,
const media::AudioParameters& params,
- const url::Origin& origin) const {
- std::string hashed_device_id =
- GetHMACForMediaDeviceID(salt_, origin, raw_device_id);
+ const std::pair<std::string, url::Origin>& salt_and_origin) const {
+ std::string hashed_device_id = GetHMACForMediaDeviceID(
+ salt_and_origin.first, salt_and_origin.second, raw_device_id);
DeviceParametersReceived(std::move(cb), hashed_device_id, raw_device_id,
params);
}
@@ -169,6 +165,7 @@ void AudioOutputAuthorizationHandler::HashDeviceId(
void AudioOutputAuthorizationHandler::AccessChecked(
AuthorizationCompletedCallback cb,
const std::string& device_id,
+ std::string salt,
const url::Origin& security_origin,
bool has_access) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -186,19 +183,20 @@ void AudioOutputAuthorizationHandler::AccessChecked(
devices_to_enumerate,
base::Bind(&AudioOutputAuthorizationHandler::TranslateDeviceID,
weak_factory_.GetWeakPtr(), base::Passed(&cb), device_id,
- security_origin));
+ std::move(salt), security_origin));
}
void AudioOutputAuthorizationHandler::TranslateDeviceID(
AuthorizationCompletedCallback cb,
const std::string& device_id,
+ const std::string& salt,
const url::Origin& security_origin,
const MediaDeviceEnumeration& enumeration) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!media::AudioDeviceDescription::IsDefaultDevice(device_id));
for (const MediaDeviceInfo& device_info :
enumeration[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT]) {
- if (DoesMediaDeviceIDMatchHMAC(salt_, security_origin, device_id,
+ if (DoesMediaDeviceIDMatchHMAC(salt, security_origin, device_id,
device_info.device_id)) {
GetDeviceParameters(std::move(cb), device_info.device_id);
return;
diff --git a/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.h b/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.h
index 553fbe76ef5..a5dcf25806c 100644
--- a/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.h
+++ b/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.h
@@ -11,6 +11,7 @@
#include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
#include "content/browser/media/media_devices_permission_checker.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "media/audio/audio_device_description.h"
@@ -45,8 +46,7 @@ class CONTENT_EXPORT AudioOutputAuthorizationHandler {
AudioOutputAuthorizationHandler(media::AudioSystem* audio_system,
MediaStreamManager* media_stream_manager,
- int render_process_id_,
- const std::string& salt);
+ int render_process_id_);
~AudioOutputAuthorizationHandler();
@@ -63,19 +63,24 @@ class CONTENT_EXPORT AudioOutputAuthorizationHandler {
// always return |override_value|.
void OverridePermissionsForTesting(bool override_value);
+ static void UMALogDeviceAuthorizationTime(base::TimeTicks auth_start_time);
+
private:
- void HashDeviceId(AuthorizationCompletedCallback cb,
- const std::string& raw_device_id,
- const media::AudioParameters& params,
- const url::Origin& origin) const;
+ void HashDeviceId(
+ AuthorizationCompletedCallback cb,
+ const std::string& raw_device_id,
+ const media::AudioParameters& params,
+ const std::pair<std::string, url::Origin>& salt_and_origin) const;
void AccessChecked(AuthorizationCompletedCallback cb,
const std::string& device_id,
+ std::string salt,
const url::Origin& security_origin,
bool has_access) const;
void TranslateDeviceID(AuthorizationCompletedCallback cb,
const std::string& device_id,
+ const std::string& salt,
const url::Origin& security_origin,
const MediaDeviceEnumeration& enumeration) const;
@@ -91,7 +96,6 @@ class CONTENT_EXPORT AudioOutputAuthorizationHandler {
media::AudioSystem* const audio_system_;
MediaStreamManager* const media_stream_manager_;
const int render_process_id_;
- const std::string salt_;
bool override_permissions_ = false;
bool permissions_override_value_ = false;
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 cf520a5ccfa..2e43aca4166 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
@@ -40,13 +40,12 @@ const char kSecurityOriginString[] = "http://localhost";
const char kDefaultDeviceId[] = "default";
const char kEmptyDeviceId[] = "";
const char kInvalidDeviceId[] = "invalid-device-id";
-const char kSalt[] = "salt";
using MockAuthorizationCallback = base::MockCallback<
AudioOutputAuthorizationHandler::AuthorizationCompletedCallback>;
url::Origin SecurityOrigin() {
- return url::Origin(GURL(kSecurityOriginString));
+ return url::Origin::Create(GURL(kSecurityOriginString));
}
// TestBrowserContext has a URLRequestContextGetter which uses a NullTaskRunner.
@@ -60,6 +59,7 @@ class TestBrowserContextWithRealURLRequestContextGetter
base::MakeRefCounted<net::TrivialURLRequestContextGetter>(
&context_,
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ salt_ = TestBrowserContext::GetMediaDeviceIDSalt();
}
~TestBrowserContextWithRealURLRequestContextGetter() override {}
@@ -70,9 +70,14 @@ class TestBrowserContextWithRealURLRequestContextGetter
return request_context_.get();
}
+ std::string GetMediaDeviceIDSalt() override { return salt_; }
+
+ void set_media_device_id_salt(std::string salt) { salt_ = std::move(salt); }
+
private:
net::TestURLRequestContext context_;
scoped_refptr<net::URLRequestContextGetter> request_context_;
+ std::string salt_;
};
} // namespace
@@ -196,7 +201,7 @@ TEST_F(AudioOutputAuthorizationHandlerTest, AuthorizeDefaultDevice_Ok) {
.Times(1);
std::unique_ptr<AudioOutputAuthorizationHandler> handler =
std::make_unique<AudioOutputAuthorizationHandler>(
- GetAudioSystem(), GetMediaStreamManager(), process()->GetID(), kSalt);
+ GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -218,7 +223,7 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
.Times(1);
std::unique_ptr<AudioOutputAuthorizationHandler> handler =
std::make_unique<AudioOutputAuthorizationHandler>(
- GetAudioSystem(), GetMediaStreamManager(), process()->GetID(), kSalt);
+ GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -236,12 +241,13 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
AuthorizeNondefaultDeviceIdWithoutPermission_NotAuthorized) {
std::string raw_nondefault_id = GetRawNondefaultId();
std::string hashed_id = MediaStreamManager::GetHMACForMediaDeviceID(
- kSalt, SecurityOrigin(), raw_nondefault_id);
+ browser_context()->GetMediaDeviceIDSalt(), SecurityOrigin(),
+ raw_nondefault_id);
MockAuthorizationCallback listener;
std::unique_ptr<AudioOutputAuthorizationHandler> handler =
std::make_unique<AudioOutputAuthorizationHandler>(
- GetAudioSystem(), GetMediaStreamManager(), process()->GetID(), kSalt);
+ GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
@@ -269,11 +275,12 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
AuthorizeNondefaultDeviceIdWithPermission_Ok) {
std::string raw_nondefault_id = GetRawNondefaultId();
std::string hashed_id = MediaStreamManager::GetHMACForMediaDeviceID(
- kSalt, SecurityOrigin(), raw_nondefault_id);
+ browser_context()->GetMediaDeviceIDSalt(), SecurityOrigin(),
+ raw_nondefault_id);
MockAuthorizationCallback listener;
std::unique_ptr<AudioOutputAuthorizationHandler> handler =
std::make_unique<AudioOutputAuthorizationHandler>(
- GetAudioSystem(), GetMediaStreamManager(), process()->GetID(), kSalt);
+ GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
@@ -300,7 +307,7 @@ TEST_F(AudioOutputAuthorizationHandlerTest, AuthorizeInvalidDeviceId_NotFound) {
MockAuthorizationCallback listener;
std::unique_ptr<AudioOutputAuthorizationHandler> handler =
std::make_unique<AudioOutputAuthorizationHandler>(
- GetAudioSystem(), GetMediaStreamManager(), process()->GetID(), kSalt);
+ GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
EXPECT_CALL(listener, Run(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, _,
std::string(), std::string()))
@@ -327,14 +334,14 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
// Note that other urls may also fail the permissions check, e.g. when a
// navigation is done during stream creation.
GURL url("about:blank");
- url::Origin origin(url);
+ url::Origin origin = url::Origin::Create(url);
std::string raw_nondefault_id = GetRawNondefaultId();
std::string hashed_id = MediaStreamManager::GetHMACForMediaDeviceID(
- kSalt, origin, raw_nondefault_id);
+ browser_context()->GetMediaDeviceIDSalt(), origin, raw_nondefault_id);
MockAuthorizationCallback listener;
std::unique_ptr<AudioOutputAuthorizationHandler> handler =
std::make_unique<AudioOutputAuthorizationHandler>(
- GetAudioSystem(), GetMediaStreamManager(), process()->GetID(), kSalt);
+ GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
NavigateAndCommit(url);
EXPECT_CALL(listener, Run(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED, _,
@@ -359,7 +366,7 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
MockAuthorizationCallback listener;
std::unique_ptr<AudioOutputAuthorizationHandler> handler =
std::make_unique<AudioOutputAuthorizationHandler>(
- GetAudioSystem(), GetMediaStreamManager(), process()->GetID(), kSalt);
+ GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
EXPECT_CALL(listener, Run(media::OUTPUT_DEVICE_STATUS_OK, _, kDefaultDeviceId,
std::string()))
@@ -377,4 +384,50 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
SyncWithAllThreads();
}
+TEST_F(AudioOutputAuthorizationHandlerTest,
+ AuthorizeNondefaultDeviceIdAfterSaltChange_NotFound) {
+ std::string raw_nondefault_id = GetRawNondefaultId();
+ std::string hashed_id = MediaStreamManager::GetHMACForMediaDeviceID(
+ browser_context()->GetMediaDeviceIDSalt(), SecurityOrigin(),
+ raw_nondefault_id);
+ MockAuthorizationCallback listener;
+ std::unique_ptr<AudioOutputAuthorizationHandler> handler =
+ std::make_unique<AudioOutputAuthorizationHandler>(
+ GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ 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::BindOnce(
+ &AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
+ base::Unretained(handler.get()), main_rfh()->GetRoutingID(), 0,
+ hashed_id, listener.Get()));
+ SyncWithAllThreads();
+
+ // Reset the salt and expect authorization of the device ID hashed with
+ // the old salt to fail.
+ auto* context =
+ static_cast<TestBrowserContextWithRealURLRequestContextGetter*>(
+ browser_context());
+ 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::BindOnce(
+ &AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
+ base::Unretained(handler.get()), main_rfh()->GetRoutingID(), 0,
+ hashed_id, listener.Get()));
+
+ SyncWithAllThreads();
+ BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, handler.release());
+ SyncWithAllThreads();
+}
+
} // namespace content
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 8ce981d7c1f..43d7083a0e8 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
@@ -8,6 +8,8 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/stringprintf.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"
@@ -34,7 +36,7 @@ class AudioOutputDelegateImpl::ControllerEventHandler
void OnControllerPlaying() override;
void OnControllerPaused() override;
void OnControllerError() override;
- void OnLog(const std::string& message) override;
+ void OnLog(base::StringPiece message) override;
base::WeakPtr<AudioOutputDelegateImpl> delegate_;
const int stream_id_; // Retained separately for logging.
@@ -73,10 +75,10 @@ void AudioOutputDelegateImpl::ControllerEventHandler::OnControllerError() {
}
void AudioOutputDelegateImpl::ControllerEventHandler::OnLog(
- const std::string& message) {
- std::ostringstream oss;
- oss << "[stream_id=" << stream_id_ << "] " << message;
- const std::string out_message = oss.str();
+ base::StringPiece message) {
+ const std::string out_message =
+ base::StringPrintf("[stream_id=%d] %.*s", stream_id_,
+ static_cast<int>(message.size()), message.data());
content::MediaStreamManager::SendMessageToNativeLog(out_message);
DVLOG(1) << out_message;
}
@@ -92,12 +94,12 @@ std::unique_ptr<media::AudioOutputDelegate> AudioOutputDelegateImpl::Create(
int render_process_id,
const media::AudioParameters& params,
const std::string& output_device_id) {
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(params, socket.get());
if (!reader)
return nullptr;
- return base::MakeUnique<AudioOutputDelegateImpl>(
+ return std::make_unique<AudioOutputDelegateImpl>(
std::move(reader), std::move(socket), handler, audio_manager,
std::move(audio_log), mirroring_manager, media_observer, stream_id,
render_frame_id, render_process_id, params, output_device_id);
@@ -134,7 +136,7 @@ AudioOutputDelegateImpl::AudioOutputDelegateImpl(
// Since the event handler never directly calls functions on |this| but rather
// posts them to the IO thread, passing a pointer from the constructor is
// safe.
- controller_event_handler_ = base::MakeUnique<ControllerEventHandler>(
+ controller_event_handler_ = std::make_unique<ControllerEventHandler>(
weak_factory_.GetWeakPtr(), stream_id_);
controller_ = media::AudioOutputController::Create(
audio_manager, controller_event_handler_.get(), params, output_device_id,
@@ -178,7 +180,7 @@ AudioOutputDelegateImpl::~AudioOutputDelegateImpl() {
base::Passed(&reader_), controller_));
}
-int AudioOutputDelegateImpl::GetStreamId() const {
+int AudioOutputDelegateImpl::GetStreamId() {
return stream_id_;
}
diff --git a/chromium/content/browser/renderer_host/media/audio_output_delegate_impl.h b/chromium/content/browser/renderer_host/media/audio_output_delegate_impl.h
index 5f1e6129d1c..cb56e2b06cf 100644
--- a/chromium/content/browser/renderer_host/media/audio_output_delegate_impl.h
+++ b/chromium/content/browser/renderer_host/media/audio_output_delegate_impl.h
@@ -62,7 +62,7 @@ class CONTENT_EXPORT AudioOutputDelegateImpl
~AudioOutputDelegateImpl() override;
// AudioOutputDelegate implementation.
- int GetStreamId() const override;
+ int GetStreamId() override;
void OnPlayStream() override;
void OnPauseStream() override;
void OnSetVolume(double volume) override;
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 eb5bad0c92e..f7ebc9588f3 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
@@ -115,11 +115,11 @@ class AudioOutputDelegateTest : public testing::Test {
// AudioOutputDelegate mainly interacts with the IO and audio threads,
// but interacts with UI for bad messages, so using these threads should
// approximate the real conditions of AudioOutputDelegate well.
- thread_bundle_ = base::MakeUnique<TestBrowserThreadBundle>(
+ thread_bundle_ = std::make_unique<TestBrowserThreadBundle>(
TestBrowserThreadBundle::Options::REAL_IO_THREAD);
audio_manager_.reset(new media::FakeAudioManager(
- base::MakeUnique<media::AudioThreadImpl>(), &log_factory_));
+ std::make_unique<media::AudioThreadImpl>(), &log_factory_));
}
~AudioOutputDelegateTest() { audio_manager_->Shutdown(); }
@@ -132,7 +132,7 @@ class AudioOutputDelegateTest : public testing::Test {
AddDiverter(kRenderProcessId, kRenderFrameId, NotNull()));
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
@@ -158,7 +158,7 @@ class AudioOutputDelegateTest : public testing::Test {
AddDiverter(kRenderProcessId, kRenderFrameId, NotNull()));
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
@@ -186,7 +186,7 @@ class AudioOutputDelegateTest : public testing::Test {
AddDiverter(kRenderProcessId, kRenderFrameId, NotNull()));
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
@@ -214,7 +214,7 @@ class AudioOutputDelegateTest : public testing::Test {
AddDiverter(kRenderProcessId, kRenderFrameId, NotNull()));
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
@@ -244,7 +244,7 @@ class AudioOutputDelegateTest : public testing::Test {
AddDiverter(kRenderProcessId, kRenderFrameId, NotNull()));
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
@@ -274,7 +274,7 @@ class AudioOutputDelegateTest : public testing::Test {
DummyAudioOutputStream stream;
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
@@ -303,7 +303,7 @@ class AudioOutputDelegateTest : public testing::Test {
DummyAudioOutputStream stream;
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
@@ -335,7 +335,7 @@ class AudioOutputDelegateTest : public testing::Test {
DummyAudioOutputStream stream;
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
@@ -372,9 +372,9 @@ class AudioOutputDelegateTest : public testing::Test {
AddDiverter(kRenderProcessId, kRenderFrameId, NotNull()));
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
- auto delegate = base::MakeUnique<AudioOutputDelegateImpl>(
+ auto delegate = std::make_unique<AudioOutputDelegateImpl>(
std::move(reader), std::move(socket), &event_handler_,
audio_manager_.get(),
log_factory_.CreateAudioLog(
@@ -402,7 +402,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
@@ -425,7 +425,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
@@ -452,7 +452,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
{
- auto socket = base::MakeUnique<base::CancelableSyncSocket>();
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
auto reader = AudioSyncReader::Create(Params(), socket.get());
AudioOutputDelegateImpl delegate(
std::move(reader), std::move(socket), &event_handler_,
diff --git a/chromium/content/browser/renderer_host/media/audio_renderer_host.cc b/chromium/content/browser/renderer_host/media/audio_renderer_host.cc
index 5e3b88f365b..43f72f27161 100644
--- a/chromium/content/browser/renderer_host/media/audio_renderer_host.cc
+++ b/chromium/content/browser/renderer_host/media/audio_renderer_host.cc
@@ -16,6 +16,7 @@
#include "content/browser/media/capture/audio_mirroring_manager.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/audio_output_authorization_handler.h"
#include "content/browser/renderer_host/media/audio_output_delegate_impl.h"
#include "content/browser/renderer_host/media/audio_sync_reader.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
@@ -35,13 +36,6 @@ namespace content {
namespace {
-void UMALogDeviceAuthorizationTime(base::TimeTicks auth_start_time) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Media.Audio.OutputDeviceAuthorizationTime",
- base::TimeTicks::Now() - auth_start_time,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMilliseconds(5000), 50);
-}
-
// Check that the routing ID references a valid RenderFrameHost, and run
// |callback| on the IO thread with true if the ID is valid.
void ValidateRenderFrameId(int render_process_id,
@@ -63,18 +57,15 @@ AudioRendererHost::AudioRendererHost(int render_process_id,
media::AudioManager* audio_manager,
media::AudioSystem* audio_system,
AudioMirroringManager* mirroring_manager,
- MediaStreamManager* media_stream_manager,
- const std::string& salt)
+ MediaStreamManager* media_stream_manager)
: BrowserMessageFilter(AudioMsgStart),
render_process_id_(render_process_id),
audio_manager_(audio_manager),
mirroring_manager_(mirroring_manager),
media_stream_manager_(media_stream_manager),
- salt_(salt),
authorization_handler_(audio_system,
media_stream_manager,
- render_process_id_,
- salt) {
+ render_process_id_) {
DCHECK(audio_manager_);
}
@@ -201,7 +192,8 @@ void AudioRendererHost::AuthorizationCompleted(
const std::string& device_id_for_renderer) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- UMALogDeviceAuthorizationTime(auth_start_time);
+ AudioOutputAuthorizationHandler::UMALogDeviceAuthorizationTime(
+ auth_start_time);
auto auth_data = authorizations_.find(stream_id);
if (auth_data == authorizations_.end())
diff --git a/chromium/content/browser/renderer_host/media/audio_renderer_host.h b/chromium/content/browser/renderer_host/media/audio_renderer_host.h
index 853d3c61d8a..a8e7a855c71 100644
--- a/chromium/content/browser/renderer_host/media/audio_renderer_host.h
+++ b/chromium/content/browser/renderer_host/media/audio_renderer_host.h
@@ -77,8 +77,7 @@ class CONTENT_EXPORT AudioRendererHost
media::AudioManager* audio_manager,
media::AudioSystem* audio_system,
AudioMirroringManager* mirroring_manager,
- MediaStreamManager* media_stream_manager,
- const std::string& salt);
+ MediaStreamManager* media_stream_manager);
// BrowserMessageFilter implementation.
void OnChannelClosing() override;
@@ -195,9 +194,6 @@ class CONTENT_EXPORT AudioRendererHost
// A list of the current open streams.
AudioOutputDelegateVector delegates_;
- // Salt required to translate renderer device IDs to raw device unique IDs
- std::string salt_;
-
// Map of device authorizations for streams that are not yet created
// The key is the stream ID, and the value is a pair. The pair's first element
// is a bool that is true if the authorization process completes successfully.
diff --git a/chromium/content/browser/renderer_host/media/audio_renderer_host_unittest.cc b/chromium/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
index 91580eb25c9..068b0374d78 100644
--- a/chromium/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
@@ -19,6 +19,7 @@
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/common/media/audio_messages.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/media_device_id.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/mock_render_process_host.h"
@@ -45,7 +46,6 @@ namespace {
const int kStreamId = 50;
const char kSecurityOrigin[] = "http://localhost";
const char kDefaultDeviceId[] = "";
-const char kSalt[] = "salt";
const char kBadDeviceId[] =
"badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad1";
const char kInvalidDeviceId[] = "invalid-device-id";
@@ -68,7 +68,7 @@ class MockAudioMirroringManager : public AudioMirroringManager {
class FakeAudioManagerWithAssociations : public media::FakeAudioManager {
public:
explicit FakeAudioManagerWithAssociations(media::AudioLogFactory* factory)
- : FakeAudioManager(base::MakeUnique<media::TestAudioThread>(), factory) {}
+ : FakeAudioManager(std::make_unique<media::TestAudioThread>(), factory) {}
void CreateDeviceAssociation(const std::string& input_device_id,
const std::string& output_device_id) {
@@ -99,17 +99,14 @@ class MockAudioRendererHost : public AudioRendererHost {
media::AudioManager* audio_manager,
media::AudioSystem* audio_system,
AudioMirroringManager* mirroring_manager,
- MediaStreamManager* media_stream_manager,
- const std::string& salt)
+ MediaStreamManager* media_stream_manager)
: AudioRendererHost(render_process_id,
audio_manager,
audio_system,
mirroring_manager,
- media_stream_manager,
- salt),
+ media_stream_manager),
shared_memory_length_(0),
- auth_run_loop_(auth_run_loop) {
- }
+ auth_run_loop_(auth_run_loop) {}
// A list of mock methods.
MOCK_METHOD4(OnDeviceAuthorized,
@@ -208,16 +205,15 @@ class AudioRendererHostTest : public RenderViewHostTestHarness {
RenderViewHostTestHarness::SetUp();
audio_manager_ =
- base::MakeUnique<FakeAudioManagerWithAssociations>(&log_factory_);
+ std::make_unique<FakeAudioManagerWithAssociations>(&log_factory_);
audio_system_ =
std::make_unique<media::AudioSystemImpl>(audio_manager_.get());
- media_stream_manager_ = base::MakeUnique<MediaStreamManager>(
+ media_stream_manager_ = std::make_unique<MediaStreamManager>(
audio_system_.get(), audio_manager_->GetTaskRunner());
- auth_run_loop_ = base::MakeUnique<base::RunLoop>();
+ auth_run_loop_ = std::make_unique<base::RunLoop>();
host_ = base::MakeRefCounted<MockAudioRendererHost>(
auth_run_loop_.get(), process()->GetID(), audio_manager_.get(),
- audio_system_.get(), &mirroring_manager_, media_stream_manager_.get(),
- kSalt);
+ audio_system_.get(), &mirroring_manager_, media_stream_manager_.get());
// Simulate IPC channel connected.
host_->set_peer_process_for_testing(base::Process::Current());
@@ -296,7 +292,8 @@ class AudioRendererHostTest : public RenderViewHostTestHarness {
}
void Create() {
- Create(kDefaultDeviceId, url::Origin(GURL(kSecurityOrigin)), true, true);
+ Create(kDefaultDeviceId, url::Origin::Create(GURL(kSecurityOrigin)), true,
+ true);
}
void Create(const std::string& device_id,
@@ -307,16 +304,18 @@ class AudioRendererHostTest : public RenderViewHostTestHarness {
device_id == kDefaultDeviceId ||
device_id ==
MediaStreamManager::GetHMACForMediaDeviceID(
- kSalt, url::Origin(GURL(kSecurityOrigin)),
+ browser_context()->GetMediaDeviceIDSalt(),
+ url::Origin::Create(GURL(kSecurityOrigin)),
GetNondefaultIdExpectedToPassPermissionsCheck())
? media::OUTPUT_DEVICE_STATUS_OK
: device_id == kBadDeviceId
? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED
: media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND;
- if (expect_onauthorized)
+ if (expect_onauthorized) {
EXPECT_CALL(*host_.get(),
OnDeviceAuthorized(kStreamId, expected_device_status, _, _));
+ }
if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) {
EXPECT_CALL(*host_.get(), WasNotifiedOfCreation(kStreamId));
@@ -352,7 +351,7 @@ class AudioRendererHostTest : public RenderViewHostTestHarness {
}
void CreateWithoutWaitingForAuth(const std::string& device_id) {
- Create(device_id, url::Origin(GURL(kSecurityOrigin)), false, false);
+ Create(device_id, url::Origin::Create(GURL(kSecurityOrigin)), false, false);
}
void CreateWithInvalidRenderFrameId() {
@@ -381,7 +380,8 @@ class AudioRendererHostTest : public RenderViewHostTestHarness {
std::string output_id = GetNondefaultIdExpectedToPassPermissionsCheck();
std::string input_id = GetNondefaultInputId();
std::string hashed_output_id = MediaStreamManager::GetHMACForMediaDeviceID(
- kSalt, url::Origin(GURL(kSecurityOrigin)), output_id);
+ browser_context()->GetMediaDeviceIDSalt(),
+ url::Origin::Create(GURL(kSecurityOrigin)), output_id);
// Set up association between input and output so that the output
// device gets selected when using session id:
audio_manager_->CreateDeviceAssociation(input_id, output_id);
@@ -549,12 +549,12 @@ TEST_F(AudioRendererHostTest, SimulateErrorAndClose) {
}
TEST_F(AudioRendererHostTest, CreateUnifiedStreamAndClose) {
- CreateUnifiedStream(url::Origin(GURL(kSecurityOrigin)));
+ CreateUnifiedStream(url::Origin::Create(GURL(kSecurityOrigin)));
Close();
}
TEST_F(AudioRendererHostTest, CreateUnauthorizedDevice) {
- Create(kBadDeviceId, url::Origin(GURL(kSecurityOrigin)), true, true);
+ Create(kBadDeviceId, url::Origin::Create(GURL(kSecurityOrigin)), true, true);
Close();
}
@@ -562,8 +562,9 @@ TEST_F(AudioRendererHostTest, CreateAuthorizedDevice) {
OverrideDevicePermissions(true);
std::string id = GetNondefaultIdExpectedToPassPermissionsCheck();
std::string hashed_id = MediaStreamManager::GetHMACForMediaDeviceID(
- kSalt, url::Origin(GURL(kSecurityOrigin)), id);
- Create(hashed_id, url::Origin(GURL(kSecurityOrigin)), true, true);
+ browser_context()->GetMediaDeviceIDSalt(),
+ url::Origin::Create(GURL(kSecurityOrigin)), id);
+ Create(hashed_id, url::Origin::Create(GURL(kSecurityOrigin)), true, true);
Close();
}
@@ -574,7 +575,8 @@ TEST_F(AudioRendererHostTest, CreateDeviceWithAuthorizationPendingIsError) {
}
TEST_F(AudioRendererHostTest, CreateInvalidDevice) {
- Create(kInvalidDeviceId, url::Origin(GURL(kSecurityOrigin)), true, true);
+ Create(kInvalidDeviceId, url::Origin::Create(GURL(kSecurityOrigin)), true,
+ true);
Close();
}
diff --git a/chromium/content/browser/renderer_host/media/audio_sync_reader.cc b/chromium/content/browser/renderer_host/media/audio_sync_reader.cc
index fad2322e59c..91d1f3e3f81 100644
--- a/chromium/content/browser/renderer_host/media/audio_sync_reader.cc
+++ b/chromium/content/browser/renderer_host/media/audio_sync_reader.cc
@@ -14,6 +14,7 @@
#include "base/memory/ptr_util.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/histogram_macros.h"
+#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
@@ -54,6 +55,10 @@ AudioSyncReader::AudioSyncReader(
switches::kMuteAudio)),
had_socket_error_(false),
socket_(std::move(socket)),
+ // Validated for reasonable size in Create.
+ output_bus_buffer_size_(
+ AudioBus::CalculateMemorySize(params.channels(),
+ params.frames_per_buffer())),
renderer_callback_count_(0),
renderer_missed_callback_count_(0),
trailing_renderer_missed_callback_count_(0),
@@ -131,7 +136,7 @@ std::unique_ptr<AudioSyncReader> AudioSyncReader::Create(
!base::CancelableSyncSocket::CreatePair(socket.get(), foreign_socket)) {
return nullptr;
}
- return base::MakeUnique<AudioSyncReader>(params, std::move(shared_memory),
+ return std::make_unique<AudioSyncReader>(params, std::move(shared_memory),
std::move(socket));
}
@@ -185,7 +190,8 @@ void AudioSyncReader::Read(AudioBus* dest) {
if (!WaitUntilDataIsReady()) {
++trailing_renderer_missed_callback_count_;
++renderer_missed_callback_count_;
- if (renderer_missed_callback_count_ <= 100) {
+ if (renderer_missed_callback_count_ <= 100 &&
+ renderer_missed_callback_count_ % 10 == 0) {
LOG(WARNING) << "AudioSyncReader::Read timed out, audio glitch count="
<< renderer_missed_callback_count_;
if (renderer_missed_callback_count_ == 100)
@@ -208,8 +214,17 @@ void AudioSyncReader::Read(AudioBus* dest) {
// For bitstream formats, we need the real data size and PCM frame count.
AudioOutputBuffer* buffer =
reinterpret_cast<AudioOutputBuffer*>(shared_memory_->memory());
- output_bus_->SetBitstreamDataSize(buffer->params.bitstream_data_size);
- output_bus_->SetBitstreamFrames(buffer->params.bitstream_frames);
+ uint32_t data_size = buffer->params.bitstream_data_size;
+ uint32_t bitstream_frames = buffer->params.bitstream_frames;
+ // |bitstream_frames| is cast to int below, so it must fit.
+ if (data_size > output_bus_buffer_size_ ||
+ !base::IsValueInRangeForNumericType<int>(bitstream_frames)) {
+ // Received data doesn't fit in the buffer, shouldn't happen.
+ dest->Zero();
+ return;
+ }
+ output_bus_->SetBitstreamDataSize(data_size);
+ output_bus_->SetBitstreamFrames(bitstream_frames);
}
output_bus_->CopyTo(dest);
}
diff --git a/chromium/content/browser/renderer_host/media/audio_sync_reader.h b/chromium/content/browser/renderer_host/media/audio_sync_reader.h
index cdf55d7db52..16715be39b3 100644
--- a/chromium/content/browser/renderer_host/media/audio_sync_reader.h
+++ b/chromium/content/browser/renderer_host/media/audio_sync_reader.h
@@ -79,6 +79,8 @@ class CONTENT_EXPORT AudioSyncReader
// Socket for transmitting audio data.
std::unique_ptr<base::CancelableSyncSocket> socket_;
+ const uint32_t output_bus_buffer_size_;
+
// Shared memory wrapper used for transferring audio data to Read() callers.
std::unique_ptr<media::AudioBus> output_bus_;
diff --git a/chromium/content/browser/renderer_host/media/audio_sync_reader_unittest.cc b/chromium/content/browser/renderer_host/media/audio_sync_reader_unittest.cc
new file mode 100644
index 00000000000..f9605d13128
--- /dev/null
+++ b/chromium/content/browser/renderer_host/media/audio_sync_reader_unittest.cc
@@ -0,0 +1,108 @@
+// Copyright 2017 The Chromium Authors. 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/media/audio_sync_reader.h"
+
+#include <limits>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+#include "base/memory/shared_memory.h"
+#include "base/sync_socket.h"
+#include "base/time/time.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "media/base/audio_bus.h"
+#include "media/base/audio_parameters.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::TestWithParam;
+
+namespace content {
+
+static_assert(
+ std::is_unsigned<decltype(
+ media::AudioOutputBufferParameters::bitstream_data_size)>::value,
+ "If |bitstream_data_size| is ever made signed, add tests for negative "
+ "buffer sizes.");
+enum OverflowTestCase {
+ kZero,
+ kNoOverflow,
+ kOverflowByOne,
+ kOverflowByOneThousand,
+ kOverflowByMax
+};
+
+static const OverflowTestCase overflow_test_case_values[]{
+ kZero, kNoOverflow, kOverflowByOne, kOverflowByOneThousand, kOverflowByMax};
+
+class AudioSyncReaderBitstreamTest : public TestWithParam<OverflowTestCase> {
+ public:
+ AudioSyncReaderBitstreamTest() {}
+ ~AudioSyncReaderBitstreamTest() override {}
+
+ private:
+ TestBrowserThreadBundle threads;
+};
+
+TEST_P(AudioSyncReaderBitstreamTest, BitstreamBufferOverflow_DoesNotWriteOOB) {
+ const int kSampleRate = 44100;
+ const int kBitsPerSample = 32;
+ const int kFramesPerBuffer = 1;
+ media::AudioParameters params(media::AudioParameters::AUDIO_BITSTREAM_AC3,
+ media::CHANNEL_LAYOUT_STEREO, kSampleRate,
+ kBitsPerSample, kFramesPerBuffer);
+
+ auto socket = std::make_unique<base::CancelableSyncSocket>();
+ std::unique_ptr<media::AudioBus> output_bus = media::AudioBus::Create(params);
+ std::unique_ptr<AudioSyncReader> reader =
+ AudioSyncReader::Create(params, socket.get());
+ const base::SharedMemory* shmem = reader->shared_memory();
+ media::AudioOutputBuffer* buffer =
+ reinterpret_cast<media::AudioOutputBuffer*>(shmem->memory());
+ reader->RequestMoreData(base::TimeDelta(), base::TimeTicks(), 0);
+
+ uint32_t signal;
+ EXPECT_EQ(socket->Receive(&signal, sizeof(signal)), sizeof(signal));
+
+ // So far, this is an ordinary stream.
+ // Now |reader| expects data to be writted to the shared memory. The renderer
+ // says how much data was written.
+ switch (GetParam()) {
+ case kZero:
+ buffer->params.bitstream_data_size = 0;
+ break;
+ case kNoOverflow:
+ buffer->params.bitstream_data_size =
+ shmem->mapped_size() - sizeof(media::AudioOutputBufferParameters);
+ break;
+ case kOverflowByOne:
+ buffer->params.bitstream_data_size =
+ shmem->mapped_size() - sizeof(media::AudioOutputBufferParameters) + 1;
+ break;
+ case kOverflowByOneThousand:
+ buffer->params.bitstream_data_size =
+ shmem->mapped_size() - sizeof(media::AudioOutputBufferParameters) +
+ 1000;
+ break;
+ case kOverflowByMax:
+ buffer->params.bitstream_data_size = std::numeric_limits<decltype(
+ buffer->params.bitstream_data_size)>::max();
+ break;
+ }
+
+ ++signal;
+ EXPECT_EQ(socket->Send(&signal, sizeof(signal)), sizeof(signal));
+
+ // The purpose of the test is to ensure this call doesn't result in undefined
+ // behavior, which should be verified by sanitizers.
+ reader->Read(output_bus.get());
+}
+
+INSTANTIATE_TEST_CASE_P(AudioSyncReaderTest,
+ AudioSyncReaderBitstreamTest,
+ ::testing::ValuesIn(overflow_test_case_values));
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc b/chromium/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc
new file mode 100644
index 00000000000..285bd24eb39
--- /dev/null
+++ b/chromium/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc
@@ -0,0 +1,92 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/media/fake_video_capture_device_launcher.h"
+#include "media/capture/video/video_capture_buffer_pool_impl.h"
+#include "media/capture/video/video_capture_buffer_tracker_factory_impl.h"
+#include "media/capture/video/video_capture_device_client.h"
+#include "media/capture/video/video_capture_jpeg_decoder.h"
+#include "media/capture/video/video_frame_receiver_on_task_runner.h"
+
+namespace {
+
+static const int kMaxBufferCount = 3;
+
+class FakeLaunchedVideoCaptureDevice
+ : public content::LaunchedVideoCaptureDevice {
+ public:
+ FakeLaunchedVideoCaptureDevice(
+ std::unique_ptr<media::VideoCaptureDevice> device)
+ : device_(std::move(device)) {}
+
+ void GetPhotoState(media::VideoCaptureDevice::GetPhotoStateCallback callback)
+ const override {
+ device_->GetPhotoState(std::move(callback));
+ }
+ void SetPhotoOptions(
+ media::mojom::PhotoSettingsPtr settings,
+ media::VideoCaptureDevice::SetPhotoOptionsCallback callback) override {
+ device_->SetPhotoOptions(std::move(settings), std::move(callback));
+ }
+ void TakePhoto(
+ media::VideoCaptureDevice::TakePhotoCallback callback) override {
+ device_->TakePhoto(std::move(callback));
+ }
+ void MaybeSuspendDevice() override { device_->MaybeSuspend(); }
+ void ResumeDevice() override { device_->Resume(); }
+ void RequestRefreshFrame() override { device_->RequestRefreshFrame(); }
+ void SetDesktopCaptureWindowIdAsync(gfx::NativeViewId window_id,
+ base::OnceClosure done_cb) override {
+ // Do nothing.
+ }
+ void OnUtilizationReport(int frame_feedback_id, double utilization) override {
+ device_->OnUtilizationReport(frame_feedback_id, utilization);
+ }
+
+ private:
+ std::unique_ptr<media::VideoCaptureDevice> device_;
+};
+
+} // anonymous namespace
+
+namespace content {
+
+FakeVideoCaptureDeviceLauncher::FakeVideoCaptureDeviceLauncher(
+ media::VideoCaptureSystem* system)
+ : system_(system) {
+ DCHECK(system_);
+}
+
+FakeVideoCaptureDeviceLauncher::~FakeVideoCaptureDeviceLauncher() = default;
+
+void FakeVideoCaptureDeviceLauncher::LaunchDeviceAsync(
+ const std::string& device_id,
+ content::MediaStreamType stream_type,
+ const media::VideoCaptureParams& params,
+ base::WeakPtr<media::VideoFrameReceiver> receiver,
+ base::OnceClosure connection_lost_cb,
+ Callbacks* callbacks,
+ base::OnceClosure done_cb) {
+ auto device = system_->CreateDevice(device_id);
+ auto empty_jpeg_decoder_factory_cb = base::BindRepeating(
+ []() { return std::unique_ptr<media::VideoCaptureJpegDecoder>(); });
+ scoped_refptr<media::VideoCaptureBufferPool> buffer_pool(
+ new media::VideoCaptureBufferPoolImpl(
+ base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(),
+ kMaxBufferCount));
+ auto device_client = base::MakeUnique<media::VideoCaptureDeviceClient>(
+ base::MakeUnique<media::VideoFrameReceiverOnTaskRunner>(
+ receiver, base::ThreadTaskRunnerHandle::Get()),
+ std::move(buffer_pool), empty_jpeg_decoder_factory_cb);
+ device->AllocateAndStart(params, std::move(device_client));
+ auto launched_device =
+ base::MakeUnique<FakeLaunchedVideoCaptureDevice>(std::move(device));
+ callbacks->OnDeviceLaunched(std::move(launched_device));
+}
+
+void FakeVideoCaptureDeviceLauncher::AbortLaunch() {
+ // Do nothing.
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/fake_video_capture_device_launcher.h b/chromium/content/browser/renderer_host/media/fake_video_capture_device_launcher.h
new file mode 100644
index 00000000000..09a93598adb
--- /dev/null
+++ b/chromium/content/browser/renderer_host/media/fake_video_capture_device_launcher.h
@@ -0,0 +1,34 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_FAKE_VIDEO_CAPTURE_DEVICE_LAUNCHER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_FAKE_VIDEO_CAPTURE_DEVICE_LAUNCHER_H_
+
+#include "content/browser/renderer_host/media/video_capture_provider.h"
+#include "media/capture/video/video_capture_system.h"
+
+namespace content {
+
+class FakeVideoCaptureDeviceLauncher
+ : public content::VideoCaptureDeviceLauncher {
+ public:
+ FakeVideoCaptureDeviceLauncher(media::VideoCaptureSystem* system);
+ ~FakeVideoCaptureDeviceLauncher() override;
+
+ void LaunchDeviceAsync(const std::string& device_id,
+ content::MediaStreamType stream_type,
+ const media::VideoCaptureParams& params,
+ base::WeakPtr<media::VideoFrameReceiver> receiver,
+ base::OnceClosure connection_lost_cb,
+ Callbacks* callbacks,
+ base::OnceClosure done_cb) override;
+ void AbortLaunch() override;
+
+ private:
+ media::VideoCaptureSystem* system_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_FAKE_VIDEO_CAPTURE_DEVICE_LAUNCHER_H_
diff --git a/chromium/content/browser/renderer_host/media/fake_video_capture_provider.cc b/chromium/content/browser/renderer_host/media/fake_video_capture_provider.cc
new file mode 100644
index 00000000000..75ff75515ad
--- /dev/null
+++ b/chromium/content/browser/renderer_host/media/fake_video_capture_provider.cc
@@ -0,0 +1,26 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/media/fake_video_capture_provider.h"
+#include "content/browser/renderer_host/media/fake_video_capture_device_launcher.h"
+#include "media/capture/video/fake_video_capture_device_factory.h"
+
+namespace content {
+
+FakeVideoCaptureProvider::FakeVideoCaptureProvider()
+ : system_(base::MakeUnique<media::FakeVideoCaptureDeviceFactory>()) {}
+
+FakeVideoCaptureProvider::~FakeVideoCaptureProvider() = default;
+
+void FakeVideoCaptureProvider::GetDeviceInfosAsync(
+ GetDeviceInfosCallback result_callback) {
+ system_.GetDeviceInfosAsync(std::move(result_callback));
+}
+
+std::unique_ptr<VideoCaptureDeviceLauncher>
+FakeVideoCaptureProvider::CreateDeviceLauncher() {
+ return base::MakeUnique<FakeVideoCaptureDeviceLauncher>(&system_);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/fake_video_capture_provider.h b/chromium/content/browser/renderer_host/media/fake_video_capture_provider.h
new file mode 100644
index 00000000000..02ac54fff07
--- /dev/null
+++ b/chromium/content/browser/renderer_host/media/fake_video_capture_provider.h
@@ -0,0 +1,30 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_FAKE_VIDEO_CAPTURE_PROVIDER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_FAKE_VIDEO_CAPTURE_PROVIDER_H_
+
+#include "content/browser/renderer_host/media/video_capture_provider.h"
+#include "media/capture/video/video_capture_system_impl.h"
+
+namespace content {
+
+// Implementation of VideoCaptureProvider that produces fake devices
+// generating test frames.
+class FakeVideoCaptureProvider : public VideoCaptureProvider {
+ public:
+ FakeVideoCaptureProvider();
+ ~FakeVideoCaptureProvider() override;
+
+ // VideoCaptureProvider implementation.
+ void GetDeviceInfosAsync(GetDeviceInfosCallback result_callback) override;
+ std::unique_ptr<VideoCaptureDeviceLauncher> CreateDeviceLauncher() override;
+
+ private:
+ media::VideoCaptureSystemImpl system_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_FAKE_VIDEO_CAPTURE_PROVIDER_H_
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 e0d8bfc1f71..bf13ae0269a 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
@@ -37,7 +37,7 @@ namespace {
std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb,
base::Callback<void(const std::string&)> send_log_message_cb) {
- return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(
+ return std::make_unique<content::VideoCaptureGpuJpegDecoder>(
std::move(decode_done_cb), std::move(send_log_message_cb));
}
@@ -157,11 +157,11 @@ InProcessVideoCaptureDeviceLauncher::CreateDeviceClient(
scoped_refptr<media::VideoCaptureBufferPool> buffer_pool =
new media::VideoCaptureBufferPoolImpl(
- base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(),
+ std::make_unique<media::VideoCaptureBufferTrackerFactoryImpl>(),
buffer_pool_max_buffer_count);
- return base::MakeUnique<media::VideoCaptureDeviceClient>(
- base::MakeUnique<media::VideoFrameReceiverOnTaskRunner>(
+ return std::make_unique<media::VideoCaptureDeviceClient>(
+ std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
receiver, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)),
std::move(buffer_pool),
base::Bind(&CreateGpuJpegDecoder,
@@ -193,7 +193,7 @@ void InProcessVideoCaptureDeviceLauncher::OnDeviceStarted(
}
}
- auto launched_device = base::MakeUnique<InProcessLaunchedVideoCaptureDevice>(
+ auto launched_device = std::make_unique<InProcessLaunchedVideoCaptureDevice>(
std::move(device), device_task_runner_);
switch (state_copy) {
@@ -284,7 +284,7 @@ void InProcessVideoCaptureDeviceLauncher::DoStartDesktopCaptureOnDeviceThread(
#endif
} else {
#if defined(OS_ANDROID)
- video_capture_device = base::MakeUnique<ScreenCaptureDeviceAndroid>();
+ video_capture_device = std::make_unique<ScreenCaptureDeviceAndroid>();
#else
#if defined(USE_AURA)
video_capture_device = DesktopCaptureDeviceAura::Create(desktop_id);
diff --git a/chromium/content/browser/renderer_host/media/in_process_video_capture_provider.cc b/chromium/content/browser/renderer_host/media/in_process_video_capture_provider.cc
index e5a4df65252..de6549f0036 100644
--- a/chromium/content/browser/renderer_host/media/in_process_video_capture_provider.cc
+++ b/chromium/content/browser/renderer_host/media/in_process_video_capture_provider.cc
@@ -27,7 +27,7 @@ std::unique_ptr<VideoCaptureProvider>
InProcessVideoCaptureProvider::CreateInstanceForNonDeviceCapture(
scoped_refptr<base::SingleThreadTaskRunner> device_task_runner,
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb) {
- return base::MakeUnique<InProcessVideoCaptureProvider>(
+ return std::make_unique<InProcessVideoCaptureProvider>(
nullptr, std::move(device_task_runner), std::move(emit_log_message_cb));
}
@@ -37,7 +37,7 @@ InProcessVideoCaptureProvider::CreateInstance(
std::unique_ptr<media::VideoCaptureSystem> video_capture_system,
scoped_refptr<base::SingleThreadTaskRunner> device_task_runner,
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb) {
- return base::MakeUnique<InProcessVideoCaptureProvider>(
+ return std::make_unique<InProcessVideoCaptureProvider>(
std::move(video_capture_system), std::move(device_task_runner),
std::move(emit_log_message_cb));
}
@@ -67,7 +67,7 @@ void InProcessVideoCaptureProvider::GetDeviceInfosAsync(
std::unique_ptr<VideoCaptureDeviceLauncher>
InProcessVideoCaptureProvider::CreateDeviceLauncher() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return base::MakeUnique<InProcessVideoCaptureDeviceLauncher>(
+ return std::make_unique<InProcessVideoCaptureDeviceLauncher>(
device_task_runner_, video_capture_system_.get());
}
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 6af84b14f97..b32c70d7522 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
@@ -7,14 +7,12 @@
#include <stddef.h>
#include <algorithm>
-#include <utility>
-#include <vector>
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
+#include "base/task_runner_util.h"
#include "content/browser/bad_message.h"
-#include "content/browser/media/media_devices_util.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/common/media/media_devices.h"
@@ -45,17 +43,6 @@ struct {
// Frame rates for sources with no support for capability enumeration.
const int kFallbackVideoFrameRates[] = {30, 60};
-url::Origin GetOrigin(int process_id,
- int frame_id,
- const url::Origin& origin_for_testing) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!origin_for_testing.unique())
- return origin_for_testing;
-
- RenderFrameHost* frame_host = RenderFrameHost::FromID(process_id, frame_id);
- return frame_host ? frame_host->GetLastCommittedOrigin() : url::Origin();
-}
-
MediaDeviceInfo TranslateDeviceInfo(bool has_permission,
const std::string& device_id_salt,
const std::string& group_id_salt,
@@ -86,31 +73,31 @@ MediaDeviceInfoArray TranslateMediaDeviceInfoArray(
return result;
}
-::mojom::FacingMode ToFacingMode(media::VideoFacingMode facing_mode) {
+blink::mojom::FacingMode ToFacingMode(media::VideoFacingMode facing_mode) {
switch (facing_mode) {
case media::MEDIA_VIDEO_FACING_NONE:
- return ::mojom::FacingMode::NONE;
+ return blink::mojom::FacingMode::NONE;
case media::MEDIA_VIDEO_FACING_USER:
- return ::mojom::FacingMode::USER;
+ return blink::mojom::FacingMode::USER;
case media::MEDIA_VIDEO_FACING_ENVIRONMENT:
- return ::mojom::FacingMode::ENVIRONMENT;
+ return blink::mojom::FacingMode::ENVIRONMENT;
default:
NOTREACHED();
- return ::mojom::FacingMode::NONE;
+ return blink::mojom::FacingMode::NONE;
}
}
-std::vector<::mojom::AudioInputDeviceCapabilitiesPtr>
+std::vector<blink::mojom::AudioInputDeviceCapabilitiesPtr>
ToVectorAudioInputDeviceCapabilitiesPtr(
- const std::vector<::mojom::AudioInputDeviceCapabilities>&
+ const std::vector<blink::mojom::AudioInputDeviceCapabilities>&
capabilities_vector,
const url::Origin& security_origin,
const std::string& salt) {
- std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> result;
+ std::vector<blink::mojom::AudioInputDeviceCapabilitiesPtr> result;
result.reserve(capabilities_vector.size());
for (auto& capabilities : capabilities_vector) {
- ::mojom::AudioInputDeviceCapabilitiesPtr capabilities_ptr =
- ::mojom::AudioInputDeviceCapabilities::New();
+ blink::mojom::AudioInputDeviceCapabilitiesPtr capabilities_ptr =
+ blink::mojom::AudioInputDeviceCapabilities::New();
capabilities_ptr->device_id =
GetHMACForMediaDeviceID(salt, security_origin, capabilities.device_id);
capabilities_ptr->parameters = capabilities.parameters;
@@ -125,28 +112,27 @@ ToVectorAudioInputDeviceCapabilitiesPtr(
void MediaDevicesDispatcherHost::Create(
int render_process_id,
int render_frame_id,
- const std::string& device_id_salt,
MediaStreamManager* media_stream_manager,
- ::mojom::MediaDevicesDispatcherHostRequest request) {
+ blink::mojom::MediaDevicesDispatcherHostRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- mojo::MakeStrongBinding(base::MakeUnique<MediaDevicesDispatcherHost>(
- render_process_id, render_frame_id,
- device_id_salt, media_stream_manager),
- std::move(request));
+ mojo::MakeStrongBinding(
+ std::make_unique<MediaDevicesDispatcherHost>(
+ render_process_id, render_frame_id, media_stream_manager),
+ std::move(request));
}
MediaDevicesDispatcherHost::MediaDevicesDispatcherHost(
int render_process_id,
int render_frame_id,
- const std::string& device_id_salt,
MediaStreamManager* media_stream_manager)
: render_process_id_(render_process_id),
render_frame_id_(render_frame_id),
- device_id_salt_(device_id_salt),
- group_id_salt_(BrowserContext::CreateRandomMediaDeviceIDSalt()),
+ group_id_salt_base_(BrowserContext::CreateRandomMediaDeviceIDSalt()),
media_stream_manager_(media_stream_manager),
- permission_checker_(base::MakeUnique<MediaDevicesPermissionChecker>()),
+ permission_checker_(std::make_unique<MediaDevicesPermissionChecker>()),
num_pending_audio_input_parameters_(0),
+ salt_and_origin_callback_(
+ base::BindRepeating(&GetMediaDeviceSaltAndOrigin)),
weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
@@ -187,9 +173,9 @@ void MediaDevicesDispatcherHost::EnumerateDevices(
base::PostTaskAndReplyWithResult(
BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
- base::Bind(GetOrigin, render_process_id_, render_frame_id_,
- security_origin_for_testing_),
- base::Bind(
+ base::BindOnce(salt_and_origin_callback_, render_process_id_,
+ render_frame_id_),
+ base::BindOnce(
&MediaDevicesDispatcherHost::CheckPermissionsForEnumerateDevices,
weak_factory_.GetWeakPtr(), devices_to_enumerate,
base::Passed(&client_callback)));
@@ -200,10 +186,11 @@ void MediaDevicesDispatcherHost::GetVideoInputCapabilities(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::PostTaskAndReplyWithResult(
BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
- base::Bind(GetOrigin, render_process_id_, render_frame_id_,
- security_origin_for_testing_),
- base::Bind(&MediaDevicesDispatcherHost::GetDefaultVideoInputDeviceID,
- weak_factory_.GetWeakPtr(), base::Passed(&client_callback)));
+ base::BindOnce(salt_and_origin_callback_, render_process_id_,
+ render_frame_id_),
+ base::BindOnce(&MediaDevicesDispatcherHost::GetDefaultVideoInputDeviceID,
+ weak_factory_.GetWeakPtr(),
+ base::Passed(&client_callback)));
}
void MediaDevicesDispatcherHost::GetAllVideoInputDeviceFormats(
@@ -226,10 +213,11 @@ void MediaDevicesDispatcherHost::GetAudioInputCapabilities(
GetAudioInputCapabilitiesCallback client_callback) {
base::PostTaskAndReplyWithResult(
BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
- base::Bind(GetOrigin, render_process_id_, render_frame_id_,
- security_origin_for_testing_),
- base::Bind(&MediaDevicesDispatcherHost::GetDefaultAudioInputDeviceID,
- weak_factory_.GetWeakPtr(), base::Passed(&client_callback)));
+ base::BindOnce(salt_and_origin_callback_, render_process_id_,
+ render_frame_id_),
+ base::BindOnce(&MediaDevicesDispatcherHost::GetDefaultAudioInputDeviceID,
+ weak_factory_.GetWeakPtr(),
+ base::Passed(&client_callback)));
}
void MediaDevicesDispatcherHost::SubscribeDeviceChangeNotifications(
@@ -293,8 +281,7 @@ void MediaDevicesDispatcherHost::NotifyDeviceChangeOnUIThread(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(IsValidMediaDeviceType(type));
- ::mojom::MediaDevicesListenerPtr media_devices_listener;
- url::Origin security_origin;
+ blink::mojom::MediaDevicesListenerPtr media_devices_listener;
if (device_change_listener_) {
media_devices_listener = std::move(device_change_listener_);
} else {
@@ -307,17 +294,18 @@ void MediaDevicesDispatcherHost::NotifyDeviceChangeOnUIThread(
mojo::MakeRequest(&media_devices_listener));
if (!media_devices_listener)
return;
-
- security_origin = render_frame_host->GetLastCommittedOrigin();
}
+ const auto& salt_and_origin =
+ salt_and_origin_callback_.Run(render_process_id_, render_frame_id_);
+ std::string group_id_salt = ComputeGroupIDSalt(salt_and_origin.first);
for (uint32_t subscription_id : subscriptions) {
bool has_permission = permission_checker_->CheckPermissionOnUIThread(
type, render_process_id_, render_frame_id_);
media_devices_listener->OnDevicesChanged(
type, subscription_id,
- TranslateMediaDeviceInfoArray(has_permission, device_id_salt_,
- group_id_salt_, security_origin,
+ TranslateMediaDeviceInfoArray(has_permission, salt_and_origin.first,
+ group_id_salt, salt_and_origin.second,
device_infos));
}
}
@@ -330,32 +318,28 @@ void MediaDevicesDispatcherHost::SetPermissionChecker(
}
void MediaDevicesDispatcherHost::SetDeviceChangeListenerForTesting(
- ::mojom::MediaDevicesListenerPtr listener) {
+ blink::mojom::MediaDevicesListenerPtr listener) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
device_change_listener_ = std::move(listener);
}
-void MediaDevicesDispatcherHost::SetSecurityOriginForTesting(
- const url::Origin& origin) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- security_origin_for_testing_ = origin;
-}
-
void MediaDevicesDispatcherHost::CheckPermissionsForEnumerateDevices(
const MediaDevicesManager::BoolDeviceTypes& requested_types,
EnumerateDevicesCallback client_callback,
- const url::Origin& security_origin) {
+ const std::pair<std::string, url::Origin>& salt_and_origin) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
permission_checker_->CheckPermissions(
requested_types, render_process_id_, render_frame_id_,
base::BindOnce(&MediaDevicesDispatcherHost::DoEnumerateDevices,
weak_factory_.GetWeakPtr(), requested_types,
- base::Passed(&client_callback), security_origin));
+ base::Passed(&client_callback), salt_and_origin.first,
+ salt_and_origin.second));
}
void MediaDevicesDispatcherHost::DoEnumerateDevices(
const MediaDevicesManager::BoolDeviceTypes& requested_types,
EnumerateDevicesCallback client_callback,
+ std::string device_id_salt,
const url::Origin& security_origin,
const MediaDevicesManager::BoolDeviceTypes& has_permissions) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -363,17 +347,19 @@ void MediaDevicesDispatcherHost::DoEnumerateDevices(
requested_types,
base::Bind(&MediaDevicesDispatcherHost::DevicesEnumerated,
weak_factory_.GetWeakPtr(), requested_types,
- base::Passed(&client_callback), security_origin,
- has_permissions));
+ base::Passed(&client_callback), std::move(device_id_salt),
+ security_origin, has_permissions));
}
void MediaDevicesDispatcherHost::DevicesEnumerated(
const MediaDevicesManager::BoolDeviceTypes& requested_types,
EnumerateDevicesCallback client_callback,
+ const std::string& device_id_salt,
const url::Origin& security_origin,
const MediaDevicesManager::BoolDeviceTypes& has_permissions,
const MediaDeviceEnumeration& enumeration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ std::string group_id_salt = ComputeGroupIDSalt(device_id_salt);
std::vector<std::vector<MediaDeviceInfo>> result(NUM_MEDIA_DEVICE_TYPES);
for (size_t i = 0; i < NUM_MEDIA_DEVICE_TYPES; ++i) {
if (!requested_types[i])
@@ -381,7 +367,7 @@ void MediaDevicesDispatcherHost::DevicesEnumerated(
for (const auto& device_info : enumeration[i]) {
result[i].push_back(TranslateDeviceInfo(has_permissions[i],
- device_id_salt_, group_id_salt_,
+ device_id_salt, group_id_salt,
security_origin, device_info));
}
}
@@ -390,39 +376,42 @@ void MediaDevicesDispatcherHost::DevicesEnumerated(
void MediaDevicesDispatcherHost::GetDefaultVideoInputDeviceID(
GetVideoInputCapabilitiesCallback client_callback,
- const url::Origin& security_origin) {
+ const std::pair<std::string, url::Origin>& salt_and_origin) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
GetDefaultMediaDeviceID(
MEDIA_DEVICE_TYPE_VIDEO_INPUT, render_process_id_, render_frame_id_,
base::Bind(&MediaDevicesDispatcherHost::GotDefaultVideoInputDeviceID,
weak_factory_.GetWeakPtr(), base::Passed(&client_callback),
- security_origin));
+ salt_and_origin.first, salt_and_origin.second));
}
void MediaDevicesDispatcherHost::GotDefaultVideoInputDeviceID(
GetVideoInputCapabilitiesCallback client_callback,
+ std::string device_id_salt,
const url::Origin& security_origin,
const std::string& default_device_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
media_stream_manager_->video_capture_manager()->EnumerateDevices(
base::Bind(&MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities,
weak_factory_.GetWeakPtr(), base::Passed(&client_callback),
- security_origin, default_device_id));
+ std::move(device_id_salt), security_origin,
+ std::move(default_device_id)));
}
void MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities(
GetVideoInputCapabilitiesCallback client_callback,
+ const std::string& device_id_salt,
const url::Origin& security_origin,
const std::string& default_device_id,
const media::VideoCaptureDeviceDescriptors& device_descriptors) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- std::vector<::mojom::VideoInputDeviceCapabilitiesPtr>
+ std::vector<blink::mojom::VideoInputDeviceCapabilitiesPtr>
video_input_capabilities;
for (const auto& descriptor : device_descriptors) {
std::string hmac_device_id = GetHMACForMediaDeviceID(
- device_id_salt_, security_origin, descriptor.device_id);
- ::mojom::VideoInputDeviceCapabilitiesPtr capabilities =
- ::mojom::VideoInputDeviceCapabilities::New();
+ device_id_salt, security_origin, descriptor.device_id);
+ blink::mojom::VideoInputDeviceCapabilitiesPtr capabilities =
+ blink::mojom::VideoInputDeviceCapabilities::New();
capabilities->device_id = std::move(hmac_device_id);
capabilities->formats =
GetVideoInputFormats(descriptor.device_id, true /* try_in_use_first */);
@@ -433,9 +422,9 @@ void MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities(
// TODO(guidou): Remove this code once the |facing| field is supported
// on Android. See http://crbug.com/672856.
if (descriptor.GetNameAndModel().find("front") != std::string::npos)
- capabilities->facing_mode = ::mojom::FacingMode::USER;
+ capabilities->facing_mode = blink::mojom::FacingMode::USER;
else if (descriptor.GetNameAndModel().find("back") != std::string::npos)
- capabilities->facing_mode = ::mojom::FacingMode::ENVIRONMENT;
+ capabilities->facing_mode = blink::mojom::FacingMode::ENVIRONMENT;
#endif
if (descriptor.device_id == default_device_id) {
video_input_capabilities.insert(video_input_capabilities.begin(),
@@ -455,34 +444,36 @@ void MediaDevicesDispatcherHost::GetVideoInputDeviceFormats(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::PostTaskAndReplyWithResult(
BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
- base::Bind(GetOrigin, render_process_id_, render_frame_id_,
- security_origin_for_testing_),
- base::Bind(&MediaDevicesDispatcherHost::EnumerateVideoDevicesForFormats,
- weak_factory_.GetWeakPtr(), base::Passed(&client_callback),
- device_id, try_in_use_first));
+ base::BindOnce(salt_and_origin_callback_, render_process_id_,
+ render_frame_id_),
+ base::BindOnce(
+ &MediaDevicesDispatcherHost::EnumerateVideoDevicesForFormats,
+ weak_factory_.GetWeakPtr(), base::Passed(&client_callback), device_id,
+ try_in_use_first));
}
void MediaDevicesDispatcherHost::EnumerateVideoDevicesForFormats(
GetVideoInputDeviceFormatsCallback client_callback,
const std::string& device_id,
bool try_in_use_first,
- const url::Origin& security_origin) {
+ const std::pair<std::string, url::Origin>& 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, security_origin));
+ try_in_use_first, salt_and_origin.first, salt_and_origin.second));
}
void MediaDevicesDispatcherHost::FinalizeGetVideoInputDeviceFormats(
GetVideoInputDeviceFormatsCallback client_callback,
const std::string& device_id,
bool try_in_use_first,
+ const std::string& device_id_salt,
const url::Origin& security_origin,
const media::VideoCaptureDeviceDescriptors& device_descriptors) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
for (const auto& descriptor : device_descriptors) {
- if (DoesMediaDeviceIDMatchHMAC(device_id_salt_, security_origin, device_id,
+ if (DoesMediaDeviceIDMatchHMAC(device_id_salt, security_origin, device_id,
descriptor.device_id)) {
std::move(client_callback)
.Run(GetVideoInputFormats(descriptor.device_id, try_in_use_first));
@@ -533,16 +524,18 @@ media::VideoCaptureFormats MediaDevicesDispatcherHost::GetVideoInputFormats(
}
struct MediaDevicesDispatcherHost::AudioInputCapabilitiesRequest {
+ std::string device_id_salt;
url::Origin security_origin;
GetAudioInputCapabilitiesCallback client_callback;
};
void MediaDevicesDispatcherHost::GetDefaultAudioInputDeviceID(
GetAudioInputCapabilitiesCallback client_callback,
- const url::Origin& security_origin) {
+ const std::pair<std::string, url::Origin>& salt_and_origin) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
pending_audio_input_capabilities_requests_.push_back(
- AudioInputCapabilitiesRequest{security_origin,
+ AudioInputCapabilitiesRequest{salt_and_origin.first,
+ salt_and_origin.second,
std::move(client_callback)});
if (pending_audio_input_capabilities_requests_.size() > 1U)
return;
@@ -575,7 +568,7 @@ void MediaDevicesDispatcherHost::GotAudioInputEnumeration(
DCHECK(current_audio_input_capabilities_.empty());
DCHECK_EQ(num_pending_audio_input_parameters_, 0U);
for (const auto& device_info : enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT]) {
- ::mojom::AudioInputDeviceCapabilities capabilities(
+ blink::mojom::AudioInputDeviceCapabilities capabilities(
device_info.device_id,
media::AudioParameters::UnavailableDeviceParams());
if (device_info.device_id == default_device_id)
@@ -626,11 +619,16 @@ void MediaDevicesDispatcherHost::FinalizeGetAudioInputCapabilities() {
std::move(request.client_callback)
.Run(ToVectorAudioInputDeviceCapabilitiesPtr(
current_audio_input_capabilities_, request.security_origin,
- device_id_salt_));
+ request.device_id_salt));
}
current_audio_input_capabilities_.clear();
pending_audio_input_capabilities_requests_.clear();
}
+std::string MediaDevicesDispatcherHost::ComputeGroupIDSalt(
+ const std::string& device_id_salt) {
+ return group_id_salt_base_ + device_id_salt;
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.h b/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.h
index 1340981ed9d..ea28d7e0cce 100644
--- a/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.h
+++ b/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.h
@@ -7,39 +7,39 @@
#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include "base/macros.h"
#include "content/browser/media/media_devices_permission_checker.h"
+#include "content/browser/media/media_devices_util.h"
#include "content/browser/renderer_host/media/media_devices_manager.h"
#include "content/common/content_export.h"
-#include "content/common/media/media_devices.mojom.h"
#include "media/capture/video/video_capture_device_descriptor.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
#include "url/origin.h"
-using ::mojom::MediaDeviceType;
+using blink::mojom::MediaDeviceType;
namespace content {
class MediaStreamManager;
class CONTENT_EXPORT MediaDevicesDispatcherHost
- : public ::mojom::MediaDevicesDispatcherHost,
+ : public blink::mojom::MediaDevicesDispatcherHost,
public MediaDeviceChangeSubscriber {
public:
MediaDevicesDispatcherHost(int render_process_id,
int render_frame_id,
- const std::string& device_id_salt,
MediaStreamManager* media_stream_manager);
~MediaDevicesDispatcherHost() override;
static void Create(int render_process_id,
int render_frame_id,
- const std::string& device_id_salt,
MediaStreamManager* media_stream_manager,
- ::mojom::MediaDevicesDispatcherHostRequest request);
+ blink::mojom::MediaDevicesDispatcherHostRequest request);
- // ::mojom::MediaDevicesDispatcherHost implementation.
+ // blink::mojom::MediaDevicesDispatcherHost implementation.
void EnumerateDevices(bool request_audio_input,
bool request_video_input,
bool request_audio_output,
@@ -67,9 +67,12 @@ class CONTENT_EXPORT MediaDevicesDispatcherHost
std::unique_ptr<MediaDevicesPermissionChecker> permission_checker);
void SetDeviceChangeListenerForTesting(
- ::mojom::MediaDevicesListenerPtr listener);
+ blink::mojom::MediaDevicesListenerPtr listener);
- void SetSecurityOriginForTesting(const url::Origin& origin);
+ void set_salt_and_origin_callback_for_testing(
+ MediaDeviceSaltAndOriginCallback callback) {
+ salt_and_origin_callback_ = std::move(callback);
+ }
private:
using GetVideoInputDeviceFormatsCallback =
@@ -78,39 +81,43 @@ class CONTENT_EXPORT MediaDevicesDispatcherHost
void CheckPermissionsForEnumerateDevices(
const MediaDevicesManager::BoolDeviceTypes& requested_types,
EnumerateDevicesCallback client_callback,
- const url::Origin& security_origin);
+ const std::pair<std::string, url::Origin>& salt_and_origin);
void DoEnumerateDevices(
const MediaDevicesManager::BoolDeviceTypes& requested_types,
EnumerateDevicesCallback client_callback,
+ std::string device_id_salt,
const url::Origin& security_origin,
const MediaDevicesManager::BoolDeviceTypes& has_permissions);
void DevicesEnumerated(
const MediaDevicesManager::BoolDeviceTypes& requested_types,
EnumerateDevicesCallback client_callback,
+ const std::string& device_id_salt,
const url::Origin& security_origin,
const MediaDevicesManager::BoolDeviceTypes& has_permissions,
const MediaDeviceEnumeration& enumeration);
void GetDefaultVideoInputDeviceID(
GetVideoInputCapabilitiesCallback client_callback,
- const url::Origin& security_origin);
+ const std::pair<std::string, url::Origin>& salt_and_origin);
void GotDefaultVideoInputDeviceID(
GetVideoInputCapabilitiesCallback client_callback,
+ std::string device_id_salt,
const url::Origin& security_origin,
const std::string& default_device_id);
void FinalizeGetVideoInputCapabilities(
GetVideoInputCapabilitiesCallback client_callback,
+ const std::string& device_id_salt,
const url::Origin& security_origin,
const std::string& default_device_id,
const media::VideoCaptureDeviceDescriptors& device_descriptors);
void GetDefaultAudioInputDeviceID(
GetAudioInputCapabilitiesCallback client_callback,
- const url::Origin& security_origin);
+ const std::pair<std::string, url::Origin>& salt_and_origin);
void GotDefaultAudioInputDeviceID(const std::string& default_device_id);
@@ -131,11 +138,12 @@ class CONTENT_EXPORT MediaDevicesDispatcherHost
GetVideoInputDeviceFormatsCallback client_callback,
const std::string& device_id,
bool try_in_use_first,
- const url::Origin& security_origin);
+ const std::pair<std::string, url::Origin>& salt_and_origin);
void FinalizeGetVideoInputDeviceFormats(
GetVideoInputDeviceFormatsCallback client_callback,
const std::string& device_id,
bool try_in_use_first,
+ const std::string& device_id_salt,
const url::Origin& security_origin,
const media::VideoCaptureDeviceDescriptors& device_descriptors);
@@ -150,11 +158,16 @@ class CONTENT_EXPORT MediaDevicesDispatcherHost
MediaDeviceType type,
const MediaDeviceInfoArray& device_infos);
+ std::string ComputeGroupIDSalt(const std::string& device_id_salt);
+
// The following const fields can be accessed on any thread.
const int render_process_id_;
const int render_frame_id_;
- const std::string device_id_salt_;
- const std::string group_id_salt_;
+ // This value is combined with the device ID salt to produce a salt for group
+ // IDs that, unlike the device ID salt, is not persistent across browsing
+ // sessions, but like the device ID salt, is reset when the user clears
+ // browsing data.
+ const std::string group_id_salt_base_;
// The following fields can only be accessed on the IO thread.
MediaStreamManager* media_stream_manager_;
@@ -162,17 +175,19 @@ class CONTENT_EXPORT MediaDevicesDispatcherHost
std::vector<uint32_t> device_change_subscriptions_[NUM_MEDIA_DEVICE_TYPES];
// This field can only be accessed on the UI thread.
- ::mojom::MediaDevicesListenerPtr device_change_listener_;
- url::Origin security_origin_for_testing_;
+ blink::mojom::MediaDevicesListenerPtr device_change_listener_;
struct AudioInputCapabilitiesRequest;
// Queued requests for audio-input capabilities.
std::vector<AudioInputCapabilitiesRequest>
pending_audio_input_capabilities_requests_;
size_t num_pending_audio_input_parameters_;
- std::vector<::mojom::AudioInputDeviceCapabilities>
+ std::vector<blink::mojom::AudioInputDeviceCapabilities>
current_audio_input_capabilities_;
+ // Callback used to obtain the current device ID salt and security origin.
+ MediaDeviceSaltAndOriginCallback salt_and_origin_callback_;
+
base::WeakPtrFactory<MediaDevicesDispatcherHost> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MediaDevicesDispatcherHost);
diff --git a/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc b/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
index e036c632ee2..4e32865964f 100644
--- a/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
@@ -15,13 +15,13 @@
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
+#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/renderer_host/media/in_process_video_capture_provider.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
-#include "content/public/browser/browser_context.h"
#include "content/public/browser/media_device_id.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -52,7 +52,9 @@ const char kNormalVideoDeviceID[] = "/dev/video0";
const char kNoFormatsVideoDeviceID[] = "/dev/video1";
const char kZeroResolutionVideoDeviceID[] = "/dev/video2";
const char* const kDefaultVideoDeviceID = kZeroResolutionVideoDeviceID;
-const char kDefaultAudioDeviceID[] = "fake_audio_input_2";
+const char kUserDefaultAudioInputDeviceID[] = "fake_audio_input_2";
+const char kSystemDefaultAudioInputLabel[] = "Fake Audio Input 1";
+const char kSystemDefaultAudioOutputLabel[] = "Fake Audio Output 1";
const auto kIgnoreLogMessageCB = base::BindRepeating([](const std::string&) {});
@@ -63,21 +65,21 @@ void PhysicalDevicesEnumerated(base::Closure quit_closure,
quit_closure.Run();
}
-class MockMediaDevicesListener : public ::mojom::MediaDevicesListener {
+class MockMediaDevicesListener : public blink::mojom::MediaDevicesListener {
public:
MockMediaDevicesListener() : binding_(this) {}
MOCK_METHOD3(OnDevicesChanged,
void(MediaDeviceType, uint32_t, const MediaDeviceInfoArray&));
- ::mojom::MediaDevicesListenerPtr CreateInterfacePtrAndBind() {
- ::mojom::MediaDevicesListenerPtr listener;
+ blink::mojom::MediaDevicesListenerPtr CreateInterfacePtrAndBind() {
+ blink::mojom::MediaDevicesListenerPtr listener;
binding_.Bind(mojo::MakeRequest(&listener));
return listener;
}
private:
- mojo::Binding<::mojom::MediaDevicesListener> binding_;
+ mojo::Binding<blink::mojom::MediaDevicesListener> binding_;
};
} // namespace
@@ -86,13 +88,15 @@ class MediaDevicesDispatcherHostTest : public testing::TestWithParam<GURL> {
public:
MediaDevicesDispatcherHostTest()
: thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
- origin_(GetParam()) {
+ browser_context_(new TestBrowserContext()),
+ origin_(url::Origin::Create(GetParam())) {
// Make sure we use fake devices to avoid long delays.
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kUseFakeDeviceForMediaStream,
base::StringPrintf("video-input-default-id=%s, "
"audio-input-default-id=%s",
- kDefaultVideoDeviceID, kDefaultAudioDeviceID));
+ kDefaultVideoDeviceID,
+ kUserDefaultAudioInputDeviceID));
audio_manager_ = std::make_unique<media::MockAudioManager>(
std::make_unique<media::TestAudioThread>());
audio_system_ =
@@ -112,9 +116,10 @@ class MediaDevicesDispatcherHostTest : public testing::TestWithParam<GURL> {
audio_system_.get(), audio_manager_->GetTaskRunner(),
std::move(video_capture_provider));
host_ = std::make_unique<MediaDevicesDispatcherHost>(
- kProcessId, kRenderId, browser_context_.GetMediaDeviceIDSalt(),
- media_stream_manager_.get());
- host_->SetSecurityOriginForTesting(origin_);
+ kProcessId, kRenderId, media_stream_manager_.get());
+ host_->set_salt_and_origin_callback_for_testing(
+ base::Bind(&MediaDevicesDispatcherHostTest::GetSaltAndOrigin,
+ base::Unretained(this)));
}
~MediaDevicesDispatcherHostTest() override { audio_manager_->Shutdown(); }
@@ -165,10 +170,10 @@ class MediaDevicesDispatcherHostTest : public testing::TestWithParam<GURL> {
MOCK_METHOD0(MockAvailableVideoInputDeviceFormatsCallback, void());
void VideoInputCapabilitiesCallback(
- std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> capabilities) {
+ std::vector<blink::mojom::VideoInputDeviceCapabilitiesPtr> capabilities) {
MockVideoInputCapabilitiesCallback();
std::string expected_first_device_id =
- GetHMACForMediaDeviceID(browser_context_.GetMediaDeviceIDSalt(),
+ GetHMACForMediaDeviceID(browser_context_->GetMediaDeviceIDSalt(),
origin_, kDefaultVideoDeviceID);
EXPECT_EQ(kNumFakeVideoDevices, capabilities.size());
EXPECT_EQ(expected_first_device_id, capabilities[0]->device_id);
@@ -184,20 +189,20 @@ class MediaDevicesDispatcherHostTest : public testing::TestWithParam<GURL> {
}
void VideoInputCapabilitiesUniqueOriginCallback(
- std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> capabilities) {
+ std::vector<blink::mojom::VideoInputDeviceCapabilitiesPtr> capabilities) {
MockVideoInputCapabilitiesCallback();
EXPECT_EQ(0U, capabilities.size());
}
void AudioInputCapabilitiesCallback(
- std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> capabilities) {
+ std::vector<blink::mojom::AudioInputDeviceCapabilitiesPtr> capabilities) {
MockAudioInputCapabilitiesCallback();
// MediaDevicesManager always returns 3 fake audio input devices.
const size_t kNumExpectedEntries = 3;
EXPECT_EQ(kNumExpectedEntries, capabilities.size());
std::string expected_first_device_id =
- GetHMACForMediaDeviceID(browser_context_.GetMediaDeviceIDSalt(),
- origin_, kDefaultAudioDeviceID);
+ GetHMACForMediaDeviceID(browser_context_->GetMediaDeviceIDSalt(),
+ origin_, kUserDefaultAudioInputDeviceID);
EXPECT_EQ(expected_first_device_id, capabilities[0]->device_id);
for (const auto& capability : capabilities)
EXPECT_TRUE(capability->parameters.IsValid());
@@ -239,7 +244,7 @@ class MediaDevicesDispatcherHostTest : public testing::TestWithParam<GURL> {
bool enumerate_video_input,
bool enumerate_audio_output,
bool permission_override_value = true) {
- host_->SetPermissionChecker(base::MakeUnique<MediaDevicesPermissionChecker>(
+ host_->SetPermissionChecker(std::make_unique<MediaDevicesPermissionChecker>(
permission_override_value));
base::RunLoop run_loop;
host_->EnumerateDevices(
@@ -289,7 +294,7 @@ class MediaDevicesDispatcherHostTest : public testing::TestWithParam<GURL> {
bool found_match = false;
for (const auto& raw_device_info : physical_devices_[i]) {
if (DoesMediaDeviceIDMatchHMAC(
- browser_context_.GetMediaDeviceIDSalt(), origin,
+ browser_context_->GetMediaDeviceIDSalt(), origin,
device_info.device_id, raw_device_info.device_id)) {
EXPECT_FALSE(found_match);
found_match = true;
@@ -303,8 +308,15 @@ class MediaDevicesDispatcherHostTest : public testing::TestWithParam<GURL> {
}
// Returns true if all devices have labels, false otherwise.
- bool DoesContainLabels(const MediaDeviceInfoArray& device_infos) {
+ bool DoesContainLabels(
+ const MediaDeviceInfoArray& device_infos,
+ const std::string& system_default_label = std::string()) {
for (const auto& device_info : device_infos) {
+ if (media::AudioDeviceDescription::IsDefaultDevice(
+ device_info.device_id)) {
+ EXPECT_TRUE(base::EndsWith(device_info.label, system_default_label,
+ base::CompareCase::SENSITIVE));
+ }
if (device_info.label.empty())
return false;
}
@@ -313,8 +325,13 @@ class MediaDevicesDispatcherHostTest : public testing::TestWithParam<GURL> {
// Returns true if all devices have labels, false otherwise.
bool DoesContainLabels(const std::vector<MediaDeviceInfoArray>& enumeration) {
- for (const auto& device_infos : enumeration) {
- if (!DoesContainLabels(device_infos))
+ for (int i = 0; i < NUM_MEDIA_DEVICE_TYPES; i++) {
+ std::string default_label;
+ if (i == MEDIA_DEVICE_TYPE_AUDIO_INPUT)
+ default_label = kSystemDefaultAudioInputLabel;
+ else if (i == MEDIA_DEVICE_TYPE_AUDIO_OUTPUT)
+ default_label = kSystemDefaultAudioOutputLabel;
+ if (!DoesContainLabels(enumeration[i], default_label))
return false;
}
return true;
@@ -368,6 +385,11 @@ class MediaDevicesDispatcherHostTest : public testing::TestWithParam<GURL> {
}
}
+ std::pair<std::string, url::Origin> GetSaltAndOrigin(int /* process_id */,
+ int /* frame_id */) {
+ return std::make_pair(browser_context_->GetMediaDeviceIDSalt(), origin_);
+ }
+
// The order of these members is important on teardown:
// MediaDevicesDispatcherHost expects to be destroyed on the IO thread while
// MediaStreamManager expects to be destroyed after the IO thread has been
@@ -379,7 +401,7 @@ class MediaDevicesDispatcherHostTest : public testing::TestWithParam<GURL> {
std::unique_ptr<media::AudioManager> audio_manager_;
std::unique_ptr<media::AudioSystem> audio_system_;
media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
- content::TestBrowserContext browser_context_;
+ std::unique_ptr<TestBrowserContext> browser_context_;
MediaDeviceEnumeration physical_devices_;
url::Origin origin_;
@@ -459,7 +481,7 @@ TEST_P(MediaDevicesDispatcherHostTest, GetAllVideoInputDeviceFormats) {
EXPECT_CALL(*this, MockAllVideoInputDeviceFormatsCallback())
.WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
host_->GetAllVideoInputDeviceFormats(
- GetHMACForMediaDeviceID(browser_context_.GetMediaDeviceIDSalt(), origin_,
+ GetHMACForMediaDeviceID(browser_context_->GetMediaDeviceIDSalt(), origin_,
kDefaultVideoDeviceID),
base::BindOnce(
&MediaDevicesDispatcherHostTest::AllVideoInputDeviceFormatsCallback,
@@ -472,7 +494,7 @@ TEST_P(MediaDevicesDispatcherHostTest, GetAvailableVideoInputDeviceFormats) {
EXPECT_CALL(*this, MockAvailableVideoInputDeviceFormatsCallback())
.WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
host_->GetAvailableVideoInputDeviceFormats(
- GetHMACForMediaDeviceID(browser_context_.GetMediaDeviceIDSalt(), origin_,
+ GetHMACForMediaDeviceID(browser_context_->GetMediaDeviceIDSalt(), origin_,
kNormalVideoDeviceID),
base::BindOnce(&MediaDevicesDispatcherHostTest::
AvailableVideoInputDeviceFormatsCallback,
@@ -480,6 +502,36 @@ TEST_P(MediaDevicesDispatcherHostTest, GetAvailableVideoInputDeviceFormats) {
run_loop.Run();
}
+TEST_P(MediaDevicesDispatcherHostTest, Salt) {
+ EnumerateDevicesAndWaitForResult(true, true, true);
+ auto devices = enumerated_devices_;
+ EnumerateDevicesAndWaitForResult(true, true, true);
+ // Expect two enumerations with the same salt to produce the same device IDs
+ EXPECT_EQ(devices.size(), enumerated_devices_.size());
+ for (size_t i = 0; i < enumerated_devices_.size(); ++i) {
+ EXPECT_EQ(devices[i].size(), enumerated_devices_[i].size());
+ for (size_t j = 0; j < devices[i].size(); ++j)
+ EXPECT_EQ(devices[i][j].device_id, enumerated_devices_[i][j].device_id);
+ }
+
+ // Reset the salt and expect different device IDs in a new enumeration, except
+ // for default audio devices, which are always hashed to the same constant.
+ browser_context_ = std::make_unique<TestBrowserContext>();
+ EnumerateDevicesAndWaitForResult(true, true, true);
+ EXPECT_EQ(devices.size(), enumerated_devices_.size());
+ for (size_t i = 0; i < enumerated_devices_.size(); ++i) {
+ EXPECT_EQ(devices[i].size(), enumerated_devices_[i].size());
+ for (size_t j = 0; j < devices[i].size(); ++j) {
+ if (media::AudioDeviceDescription::IsDefaultDevice(
+ devices[i][j].device_id)) {
+ EXPECT_EQ(devices[i][j].device_id, enumerated_devices_[i][j].device_id);
+ } else {
+ EXPECT_NE(devices[i][j].device_id, enumerated_devices_[i][j].device_id);
+ }
+ }
+ }
+}
+
INSTANTIATE_TEST_CASE_P(,
MediaDevicesDispatcherHostTest,
testing::Values(GURL(), GURL("https://test.com")));
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 5426c18a971..50435cd25ec 100644
--- a/chromium/content/browser/renderer_host/media/media_devices_manager.cc
+++ b/chromium/content/browser/renderer_host/media/media_devices_manager.cc
@@ -49,23 +49,23 @@ std::string GetLogMessageString(MediaDeviceType device_type,
return output_string;
}
-MediaDeviceInfoArray GetFakeAudioDevices(bool is_input) {
- MediaDeviceInfoArray result;
+media::AudioDeviceDescriptions GetFakeAudioDevices(bool is_input) {
+ media::AudioDeviceDescriptions result;
if (is_input) {
- result.emplace_back(media::AudioDeviceDescription::kDefaultDeviceId,
- "Fake Default Audio Input",
- "fake_group_audio_input_default");
- result.emplace_back("fake_audio_input_1", "Fake Audio Input 1",
- "fake_group_audio_input_1");
- result.emplace_back("fake_audio_input_2", "Fake Audio Input 2",
+ result.emplace_back("Fake Default Audio Input",
+ media::AudioDeviceDescription::kDefaultDeviceId,
+ "fake_group_audio_1");
+ result.emplace_back("Fake Audio Input 1", "fake_audio_input_1",
+ "fake_group_audio_1");
+ result.emplace_back("Fake Audio Input 2", "fake_audio_input_2",
"fake_group_audio_input_2");
} else {
- result.emplace_back(media::AudioDeviceDescription::kDefaultDeviceId,
- "Fake Default Audio Output",
- "fake_group_audio_output_default");
- result.emplace_back("fake_audio_output_1", "Fake Audio Output 1",
- "fake_group_audio_output_1");
- result.emplace_back("fake_audio_output_2", "Fake Audio Output 2",
+ result.emplace_back("Fake Default Audio Output",
+ media::AudioDeviceDescription::kDefaultDeviceId,
+ "fake_group_audio_1");
+ result.emplace_back("Fake Audio Output 1", "fake_audio_output_1",
+ "fake_group_audio_1");
+ result.emplace_back("Fake Audio Output 2", "fake_audio_output_2",
"fake_group_audio_output_2");
}
@@ -240,10 +240,12 @@ void MediaDevicesManager::StartMonitoring() {
monitoring_started_ = true;
base::SystemMonitor::Get()->AddDevicesChangedObserver(this);
- for (size_t i = 0; i < NUM_MEDIA_DEVICE_TYPES; ++i) {
- DCHECK(cache_policies_[i] != CachePolicy::SYSTEM_MONITOR);
- SetCachePolicy(static_cast<MediaDeviceType>(i),
- CachePolicy::SYSTEM_MONITOR);
+ if (base::FeatureList::IsEnabled(features::kMediaDevicesSystemMonitorCache)) {
+ for (size_t i = 0; i < NUM_MEDIA_DEVICE_TYPES; ++i) {
+ DCHECK(cache_policies_[i] != CachePolicy::SYSTEM_MONITOR);
+ SetCachePolicy(static_cast<MediaDeviceType>(i),
+ CachePolicy::SYSTEM_MONITOR);
+ }
}
#if defined(OS_MACOSX)
@@ -337,7 +339,7 @@ void MediaDevicesManager::EnumerateAudioDevices(bool is_input) {
is_input ? MEDIA_DEVICE_TYPE_AUDIO_INPUT : MEDIA_DEVICE_TYPE_AUDIO_OUTPUT;
if (use_fake_devices_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&MediaDevicesManager::DevicesEnumerated,
+ FROM_HERE, base::BindOnce(&MediaDevicesManager::AudioDevicesEnumerated,
weak_factory_.GetWeakPtr(), type,
GetFakeAudioDevices(is_input)));
return;
@@ -363,10 +365,56 @@ void MediaDevicesManager::AudioDevicesEnumerated(
media::AudioDeviceDescriptions device_descriptions) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ auto it_default_device =
+ std::find_if(device_descriptions.begin(), device_descriptions.end(),
+ [](const media::AudioDeviceDescription& description) {
+ return media::AudioDeviceDescription::IsDefaultDevice(
+ description.unique_id);
+ });
+
+ auto it_real_default_device = device_descriptions.end();
+ if (it_default_device != device_descriptions.end()) {
+ // Find the real device that maps to the default device by finding
+ // coincidence in the group ID.
+ // This approach works only when the following is true:
+ // * group ID is properly supported so that the default device has the
+ // same group ID as some real device.
+ // * For input devices, the default device has an associated output device.
+ // * There is only one device with the same group ID of the default device.
+ // TODO(guidou): Get the real ID of the default input device from
+ // media::AudioSystem when the functionality becomes available.
+ // http://crbug.com/788758
+ for (auto it = device_descriptions.begin(); it != device_descriptions.end();
+ ++it) {
+ if (it->group_id == it_default_device->group_id &&
+ !media::AudioDeviceDescription::IsDefaultDevice(it->unique_id)) {
+ if (it_real_default_device != device_descriptions.end()) {
+ // If there is more than one real device with the same group ID as the
+ // default device, the exact mapping cannot be found.
+ it_real_default_device = device_descriptions.end();
+ break;
+ } else {
+ it_real_default_device = it;
+ }
+ }
+ }
+ }
+
MediaDeviceInfoArray snapshot;
for (const media::AudioDeviceDescription& description : device_descriptions) {
- snapshot.emplace_back(description);
+ if (it_real_default_device != device_descriptions.end() &&
+ media::AudioDeviceDescription::IsDefaultDevice(description.unique_id)) {
+ // TODO(guidou): Make the concatenation of the default and real device
+ // labels in a properly localized manner. http://crbug.com/788767
+ snapshot.emplace_back(
+ description.unique_id,
+ description.device_name + " - " + it_real_default_device->device_name,
+ description.group_id);
+ } else {
+ snapshot.emplace_back(description);
+ }
}
+
DevicesEnumerated(type, snapshot);
}
diff --git a/chromium/content/browser/renderer_host/media/media_devices_manager_unittest.cc b/chromium/content/browser/renderer_host/media/media_devices_manager_unittest.cc
index 7cb7e30a310..f3a858d4005 100644
--- a/chromium/content/browser/renderer_host/media/media_devices_manager_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/media_devices_manager_unittest.cc
@@ -44,7 +44,7 @@ const auto kIgnoreLogMessageCB = base::BindRepeating([](const std::string&) {});
class MockAudioManager : public media::FakeAudioManager {
public:
MockAudioManager()
- : FakeAudioManager(base::MakeUnique<media::TestAudioThread>(),
+ : FakeAudioManager(std::make_unique<media::TestAudioThread>(),
&fake_audio_log_factory_),
num_output_devices_(2),
num_input_devices_(2) {}
@@ -58,8 +58,8 @@ class MockAudioManager : public media::FakeAudioManager {
DCHECK(device_names->empty());
for (size_t i = 0; i < num_input_devices_; i++) {
device_names->push_back(media::AudioDeviceName(
- std::string("fake_device_name_") + base::SizeTToString(i),
- std::string("fake_device_id_") + base::SizeTToString(i)));
+ std::string("fake_device_name_") + base::NumberToString(i),
+ std::string("fake_device_id_") + base::NumberToString(i)));
}
MockGetAudioInputDeviceNames(device_names);
}
@@ -69,8 +69,8 @@ class MockAudioManager : public media::FakeAudioManager {
DCHECK(device_names->empty());
for (size_t i = 0; i < num_output_devices_; i++) {
device_names->push_back(media::AudioDeviceName(
- std::string("fake_device_name_") + base::SizeTToString(i),
- std::string("fake_device_id_") + base::SizeTToString(i)));
+ std::string("fake_device_name_") + base::NumberToString(i),
+ std::string("fake_device_id_") + base::NumberToString(i)));
}
MockGetAudioOutputDeviceNames(device_names);
}
@@ -147,12 +147,12 @@ class MediaDevicesManagerTest : public ::testing::Test {
audio_system_ =
std::make_unique<media::AudioSystemImpl>(audio_manager_.get());
auto video_capture_device_factory =
- base::MakeUnique<MockVideoCaptureDeviceFactory>();
+ std::make_unique<MockVideoCaptureDeviceFactory>();
video_capture_device_factory_ = video_capture_device_factory.get();
- auto video_capture_system = base::MakeUnique<media::VideoCaptureSystemImpl>(
+ auto video_capture_system = std::make_unique<media::VideoCaptureSystemImpl>(
std::move(video_capture_device_factory));
auto video_capture_provider =
- base::MakeUnique<InProcessVideoCaptureProvider>(
+ std::make_unique<InProcessVideoCaptureProvider>(
std::move(video_capture_system),
base::ThreadTaskRunnerHandle::Get(), kIgnoreLogMessageCB);
video_capture_manager_ = new VideoCaptureManager(
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 1849b12ea9e..a5698a9e23c 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,6 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
+#include "base/task_runner_util.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
@@ -17,10 +18,10 @@ namespace content {
namespace {
-void BindMediaStreamDispatcherRequest(
+void BindMediaStreamDeviceObserverRequest(
int render_process_id,
int render_frame_id,
- mojom::MediaStreamDispatcherRequest request) {
+ mojom::MediaStreamDeviceObserverRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderFrameHost* render_frame_host =
@@ -33,11 +34,11 @@ void BindMediaStreamDispatcherRequest(
MediaStreamDispatcherHost::MediaStreamDispatcherHost(
int render_process_id,
- const std::string& salt,
MediaStreamManager* media_stream_manager)
: render_process_id_(render_process_id),
- salt_(salt),
media_stream_manager_(media_stream_manager),
+ salt_and_origin_callback_(
+ base::BindRepeating(&GetMediaDeviceSaltAndOrigin)),
weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -60,81 +61,46 @@ void MediaStreamDispatcherHost::BindRequest(
bindings_.AddBinding(this, std::move(request));
}
-void MediaStreamDispatcherHost::StreamGenerated(
+void MediaStreamDispatcherHost::OnDeviceStopped(
int render_frame_id,
- int page_request_id,
const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) {
- DVLOG(1) << __func__ << " label= " << label;
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- GetMediaStreamDispatcherForFrame(render_frame_id)
- ->OnStreamGenerated(page_request_id, label, audio_devices, video_devices);
-}
-
-void MediaStreamDispatcherHost::StreamGenerationFailed(
- int render_frame_id,
- int page_request_id,
- MediaStreamRequestResult result) {
- DVLOG(1) << __func__ << " page_request_id=" << page_request_id
- << " result=" << result;
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- GetMediaStreamDispatcherForFrame(render_frame_id)
- ->OnStreamGenerationFailed(page_request_id, result);
-}
-
-void MediaStreamDispatcherHost::DeviceStopped(int render_frame_id,
- const std::string& label,
- const MediaStreamDevice& device) {
+ const MediaStreamDevice& device) {
DVLOG(1) << __func__ << " label=" << label << " type=" << device.type
<< " device_id=" << device.id;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- GetMediaStreamDispatcherForFrame(render_frame_id)
+ GetMediaStreamDeviceObserverForFrame(render_frame_id)
->OnDeviceStopped(label, device);
}
-void MediaStreamDispatcherHost::DeviceOpened(int render_frame_id,
- int page_request_id,
- const std::string& label,
- const MediaStreamDevice& device) {
- DVLOG(1) << __func__ << " page_request_id=" << page_request_id;
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- GetMediaStreamDispatcherForFrame(render_frame_id)
- ->OnDeviceOpened(page_request_id, label, device);
-}
-
-mojom::MediaStreamDispatcher*
-MediaStreamDispatcherHost::GetMediaStreamDispatcherForFrame(
+mojom::MediaStreamDeviceObserver*
+MediaStreamDispatcherHost::GetMediaStreamDeviceObserverForFrame(
int render_frame_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- auto it = dispatchers_.find(render_frame_id);
- if (it != dispatchers_.end())
+ auto it = observers_.find(render_frame_id);
+ if (it != observers_.end())
return it->second.get();
- mojom::MediaStreamDispatcherPtr dispatcher;
- auto dispatcher_request = mojo::MakeRequest(&dispatcher);
- dispatcher.set_connection_error_handler(base::BindOnce(
- &MediaStreamDispatcherHost::OnMediaStreamDispatcherConnectionError,
+ mojom::MediaStreamDeviceObserverPtr observer;
+ auto dispatcher_request = mojo::MakeRequest(&observer);
+ observer.set_connection_error_handler(base::BindOnce(
+ &MediaStreamDispatcherHost::OnMediaStreamDeviceObserverConnectionError,
weak_factory_.GetWeakPtr(), render_frame_id));
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(&BindMediaStreamDispatcherRequest, render_process_id_,
+ base::BindOnce(&BindMediaStreamDeviceObserverRequest, render_process_id_,
render_frame_id, std::move(dispatcher_request)));
- dispatchers_[render_frame_id] = std::move(dispatcher);
+ observers_[render_frame_id] = std::move(observer);
- return dispatchers_[render_frame_id].get();
+ return observers_[render_frame_id].get();
}
-void MediaStreamDispatcherHost::OnMediaStreamDispatcherConnectionError(
+void MediaStreamDispatcherHost::OnMediaStreamDeviceObserverConnectionError(
int render_frame_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- dispatchers_.erase(render_frame_id);
+ observers_.erase(render_frame_id);
}
void MediaStreamDispatcherHost::CancelAllRequests() {
@@ -144,43 +110,55 @@ void MediaStreamDispatcherHost::CancelAllRequests() {
media_stream_manager_->CancelAllRequests(render_process_id_);
}
-void MediaStreamDispatcherHost::DeviceOpenFailed(int render_frame_id,
- int page_request_id) {
- DVLOG(1) << __func__ << " page_request_id=" << page_request_id;
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- GetMediaStreamDispatcherForFrame(render_frame_id)
- ->OnDeviceOpenFailed(page_request_id);
-}
-
void MediaStreamDispatcherHost::GenerateStream(
int32_t render_frame_id,
int32_t page_request_id,
const StreamControls& controls,
- const url::Origin& security_origin,
- bool user_gesture) {
+ bool user_gesture,
+ GenerateStreamCallback callback) {
DVLOG(1) << __func__ << " render_frame_id=" << render_frame_id
<< " page_request_id=" << page_request_id
<< " audio=" << controls.audio.requested
<< " video=" << controls.video.requested
- << " security_origin=" << security_origin
<< " user_gesture=" << user_gesture;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ base::PostTaskAndReplyWithResult(
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
+ base::BindOnce(salt_and_origin_callback_, render_process_id_,
+ render_frame_id),
+ base::BindOnce(&MediaStreamDispatcherHost::DoGenerateStream,
+ weak_factory_.GetWeakPtr(), render_frame_id,
+ page_request_id, controls, user_gesture,
+ base::Passed(&callback)));
+}
+
+void MediaStreamDispatcherHost::DoGenerateStream(
+ int32_t render_frame_id,
+ int32_t page_request_id,
+ const StreamControls& controls,
+ bool user_gesture,
+ GenerateStreamCallback callback,
+ const std::pair<std::string, url::Origin>& salt_and_origin) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!MediaStreamManager::IsOriginAllowed(render_process_id_,
- security_origin)) {
- StreamGenerationFailed(render_frame_id, page_request_id,
- MEDIA_DEVICE_INVALID_SECURITY_ORIGIN_DEPRECATED);
+ salt_and_origin.second)) {
+ std::move(callback).Run(MEDIA_DEVICE_INVALID_SECURITY_ORIGIN_DEPRECATED,
+ std::string(), MediaStreamDevices(),
+ MediaStreamDevices());
return;
}
media_stream_manager_->GenerateStream(
- weak_factory_.GetWeakPtr(), render_process_id_, render_frame_id, salt_,
- page_request_id, controls, security_origin, user_gesture);
+ render_process_id_, render_frame_id, salt_and_origin.first,
+ page_request_id, controls, salt_and_origin.second, user_gesture,
+ std::move(callback),
+ base::BindRepeating(&MediaStreamDispatcherHost::OnDeviceStopped,
+ weak_factory_.GetWeakPtr()));
}
-void MediaStreamDispatcherHost::CancelGenerateStream(int render_frame_id,
- int page_request_id) {
+void MediaStreamDispatcherHost::CancelRequest(int render_frame_id,
+ int page_request_id) {
DVLOG(1) << __func__ << " render_frame_id=" << render_frame_id
<< " page_request_id=" << page_request_id;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -203,22 +181,43 @@ void MediaStreamDispatcherHost::OpenDevice(int32_t render_frame_id,
int32_t page_request_id,
const std::string& device_id,
MediaStreamType type,
- const url::Origin& security_origin) {
+ OpenDeviceCallback callback) {
DVLOG(1) << __func__ << " render_frame_id=" << render_frame_id
<< " page_request_id=" << page_request_id
- << " device_id=" << device_id << " type=" << type
- << " security_origin=" << security_origin;
+ << " device_id=" << device_id << " type=" << type;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ base::PostTaskAndReplyWithResult(
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
+ base::BindOnce(salt_and_origin_callback_, render_process_id_,
+ render_frame_id),
+ base::BindOnce(&MediaStreamDispatcherHost::DoOpenDevice,
+ weak_factory_.GetWeakPtr(), render_frame_id,
+ page_request_id, device_id, type,
+ base::Passed(&callback)));
+}
+
+void MediaStreamDispatcherHost::DoOpenDevice(
+ int32_t render_frame_id,
+ int32_t page_request_id,
+ const std::string& device_id,
+ MediaStreamType type,
+ OpenDeviceCallback callback,
+ const std::pair<std::string, url::Origin>& salt_and_origin) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!MediaStreamManager::IsOriginAllowed(render_process_id_,
- security_origin)) {
- DeviceOpenFailed(render_frame_id, page_request_id);
+ salt_and_origin.second)) {
+ std::move(callback).Run(false /* success */, std::string(),
+ MediaStreamDevice());
return;
}
media_stream_manager_->OpenDevice(
- weak_factory_.GetWeakPtr(), render_process_id_, render_frame_id, salt_,
- page_request_id, device_id, type, security_origin);
+ render_process_id_, render_frame_id, salt_and_origin.first,
+ page_request_id, device_id, type, salt_and_origin.second,
+ std::move(callback),
+ base::BindRepeating(&MediaStreamDispatcherHost::OnDeviceStopped,
+ weak_factory_.GetWeakPtr()));
}
void MediaStreamDispatcherHost::CloseDevice(const std::string& label) {
@@ -239,7 +238,7 @@ void MediaStreamDispatcherHost::SetCapturingLinkSecured(int32_t session_id,
type, is_secure);
}
-void MediaStreamDispatcherHost::StreamStarted(const std::string& label) {
+void MediaStreamDispatcherHost::OnStreamStarted(const std::string& label) {
DVLOG(1) << __func__ << " label= " << label;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.h b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.h
index 9ff0b19bd6f..a515ce5a184 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.h
+++ b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.h
@@ -7,10 +7,11 @@
#include <map>
#include <string>
+#include <utility>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "content/browser/renderer_host/media/media_stream_requester.h"
+#include "content/browser/media/media_devices_util.h"
#include "content/common/content_export.h"
#include "content/common/media/media_stream.mojom.h"
#include "content/common/media/media_stream_controls.h"
@@ -28,74 +29,75 @@ class MediaStreamManager;
// MediaStreamImpl. There is one MediaStreamDispatcherHost per
// RenderProcessHost, the former owned by the latter.
class CONTENT_EXPORT MediaStreamDispatcherHost
- : public mojom::MediaStreamDispatcherHost,
- public MediaStreamRequester {
+ : public mojom::MediaStreamDispatcherHost {
public:
MediaStreamDispatcherHost(int render_process_id,
- const std::string& salt,
MediaStreamManager* media_stream_manager);
~MediaStreamDispatcherHost() override;
void BindRequest(mojom::MediaStreamDispatcherHostRequest request);
- // MediaStreamRequester implementation.
- void StreamGenerated(int render_frame_id,
- int page_request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) override;
- void StreamGenerationFailed(int render_frame_id,
- int page_request_id,
- MediaStreamRequestResult result) override;
- void DeviceStopped(int render_frame_id,
- const std::string& label,
- const MediaStreamDevice& device) override;
- void DeviceOpened(int render_frame_id,
- int page_request_id,
- const std::string& label,
- const MediaStreamDevice& device) override;
-
- void SetMediaStreamDispatcherForTesting(
+ void set_salt_and_origin_callback_for_testing(
+ MediaDeviceSaltAndOriginCallback callback) {
+ salt_and_origin_callback_ = std::move(callback);
+ }
+ void SetMediaStreamDeviceObserverForTesting(
int render_frame_id,
- mojom::MediaStreamDispatcherPtr dispatcher) {
- dispatchers_[render_frame_id] = std::move(dispatcher);
+ mojom::MediaStreamDeviceObserverPtr observer) {
+ observers_[render_frame_id] = std::move(observer);
}
private:
friend class MockMediaStreamDispatcherHost;
- mojom::MediaStreamDispatcher* GetMediaStreamDispatcherForFrame(
+ mojom::MediaStreamDeviceObserver* GetMediaStreamDeviceObserverForFrame(
int render_frame_id);
- void OnMediaStreamDispatcherConnectionError(int render_frame_id);
+ void OnMediaStreamDeviceObserverConnectionError(int render_frame_id);
void CancelAllRequests();
- void DeviceOpenFailed(int render_frame_id, int page_request_id);
// mojom::MediaStreamDispatcherHost implementation
void GenerateStream(int32_t render_frame_id,
int32_t request_id,
const StreamControls& controls,
- const url::Origin& security_origin,
- bool user_gesture) override;
- void CancelGenerateStream(int32_t render_frame_id,
- int32_t request_id) override;
+ bool user_gesture,
+ GenerateStreamCallback callback) override;
+ void CancelRequest(int32_t render_frame_id, int32_t request_id) override;
void StopStreamDevice(int32_t render_frame_id,
const std::string& device_id) override;
void OpenDevice(int32_t render_frame_id,
int32_t request_id,
const std::string& device_id,
MediaStreamType type,
- const url::Origin& security_origin) override;
+ OpenDeviceCallback callback) override;
void CloseDevice(const std::string& label) override;
void SetCapturingLinkSecured(int32_t session_id,
MediaStreamType type,
bool is_secure) override;
- void StreamStarted(const std::string& label) override;
+ void OnStreamStarted(const std::string& label) override;
+
+ void DoGenerateStream(
+ int32_t render_frame_id,
+ int32_t request_id,
+ const StreamControls& controls,
+ bool user_gesture,
+ GenerateStreamCallback callback,
+ const std::pair<std::string, url::Origin>& salt_and_origin);
+ void DoOpenDevice(int32_t render_frame_id,
+ int32_t request_id,
+ const std::string& device_id,
+ MediaStreamType type,
+ OpenDeviceCallback callback,
+ const std::pair<std::string, url::Origin>& salt_and_origin);
+
+ void OnDeviceStopped(int render_frame_id,
+ const std::string& label,
+ const MediaStreamDevice& device);
const int render_process_id_;
- std::string salt_;
MediaStreamManager* media_stream_manager_;
- std::map<int, mojom::MediaStreamDispatcherPtr> dispatchers_;
+ std::map<int, mojom::MediaStreamDeviceObserverPtr> observers_;
mojo::BindingSet<mojom::MediaStreamDispatcherHost> bindings_;
+ MediaDeviceSaltAndOriginCallback salt_and_origin_callback_;
base::WeakPtrFactory<MediaStreamDispatcherHost> weak_factory_;
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 8aaecd85ffd..345390ecff0 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
@@ -8,6 +8,7 @@
#include <memory>
#include <string>
#include <utility>
+#include <vector>
#include "base/bind.h"
#include "base/callback_helpers.h"
@@ -76,13 +77,12 @@ void AudioInputDevicesEnumerated(base::Closure quit_closure,
} // anonymous namespace
class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
- public mojom::MediaStreamDispatcher {
+ public mojom::MediaStreamDeviceObserver {
public:
MockMediaStreamDispatcherHost(
- const std::string& salt,
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
MediaStreamManager* manager)
- : MediaStreamDispatcherHost(kProcessId, salt, manager),
+ : MediaStreamDispatcherHost(kProcessId, manager),
task_runner_(task_runner) {}
~MockMediaStreamDispatcherHost() override {}
@@ -94,16 +94,18 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
MOCK_METHOD2(OnStreamGenerationFailure,
void(int request_id, MediaStreamRequestResult result));
MOCK_METHOD0(OnDeviceStopSuccess, void());
+ MOCK_METHOD0(OnDeviceOpenSuccess, void());
// Accessor to private functions.
void OnGenerateStream(int render_frame_id,
int page_request_id,
const StreamControls& controls,
- const url::Origin& security_origin,
const base::Closure& quit_closure) {
quit_closures_.push(quit_closure);
- MediaStreamDispatcherHost::GenerateStream(render_frame_id, page_request_id,
- controls, security_origin, false);
+ MediaStreamDispatcherHost::GenerateStream(
+ render_frame_id, page_request_id, controls, false,
+ base::BindOnce(&MockMediaStreamDispatcherHost::OnStreamGenerated,
+ base::Unretained(this), page_request_id));
}
void OnStopStreamDevice(int render_frame_id,
@@ -115,47 +117,28 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
int page_request_id,
const std::string& device_id,
MediaStreamType type,
- const url::Origin& security_origin,
const base::Closure& quit_closure) {
quit_closures_.push(quit_closure);
- MediaStreamDispatcherHost::OpenDevice(render_frame_id, page_request_id,
- device_id, type, security_origin);
+ MediaStreamDispatcherHost::OpenDevice(
+ render_frame_id, page_request_id, device_id, type,
+ base::BindOnce(&MockMediaStreamDispatcherHost::OnDeviceOpened,
+ base::Unretained(this)));
}
- void OnStreamStarted(const std::string label) {
- MediaStreamDispatcherHost::StreamStarted(label);
+ void OnStreamStarted(const std::string& label) {
+ MediaStreamDispatcherHost::OnStreamStarted(label);
}
- // mojom::MediaStreamDispatcher implementation.
- void OnStreamGenerated(int32_t request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) override {
- OnStreamGeneratedInternal(request_id, label, audio_devices, video_devices);
- }
-
- void OnStreamGenerationFailed(int32_t request_id,
- MediaStreamRequestResult result) override {
- OnStreamGenerationFailedInternal(request_id, result);
- }
-
- void OnDeviceOpened(int32_t request_id,
- const std::string& label,
- const MediaStreamDevice& device) override {
- OnDeviceOpenedInternal(request_id, label, device);
- }
-
- void OnDeviceOpenFailed(int32_t request_id) override {}
-
+ // mojom::MediaStreamDeviceObserver implementation.
void OnDeviceStopped(const std::string& label,
const MediaStreamDevice& device) override {
OnDeviceStoppedInternal(label, device);
}
- mojom::MediaStreamDispatcherPtr CreateInterfacePtrAndBind() {
- mojom::MediaStreamDispatcherPtr dispatcher;
- bindings_.AddBinding(this, mojo::MakeRequest(&dispatcher));
- return dispatcher;
+ mojom::MediaStreamDeviceObserverPtr CreateInterfacePtrAndBind() {
+ mojom::MediaStreamDeviceObserverPtr observer;
+ bindings_.AddBinding(this, mojo::MakeRequest(&observer));
+ return observer;
}
std::string label_;
@@ -165,10 +148,16 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
private:
// These handler methods do minimal things and delegate to the mock methods.
- void OnStreamGeneratedInternal(int request_id,
- std::string label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) {
+ void OnStreamGenerated(int request_id,
+ MediaStreamRequestResult result,
+ const std::string& label,
+ const MediaStreamDevices& audio_devices,
+ const MediaStreamDevices& video_devices) {
+ if (result != MEDIA_DEVICE_OK) {
+ OnStreamGenerationFailed(request_id, result);
+ return;
+ }
+
OnStreamGenerationSuccess(request_id, audio_devices.size(),
video_devices.size());
// Simulate the stream started event back to host for UI testing.
@@ -184,8 +173,8 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
video_devices_ = video_devices;
}
- void OnStreamGenerationFailedInternal(int request_id,
- MediaStreamRequestResult result) {
+ void OnStreamGenerationFailed(int request_id,
+ MediaStreamRequestResult result) {
OnStreamGenerationFailure(request_id, result);
if (!quit_closures_.empty()) {
base::Closure quit_closure = quit_closures_.front();
@@ -206,17 +195,20 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
OnDeviceStopSuccess();
}
- void OnDeviceOpenedInternal(int request_id,
- const std::string& label,
- const MediaStreamDevice& device) {
+ void OnDeviceOpened(bool success,
+ const std::string& label,
+ const MediaStreamDevice& device) {
base::Closure quit_closure = quit_closures_.front();
quit_closures_.pop();
task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
- label_ = label;
- opened_device_ = device;
+ if (success) {
+ label_ = label;
+ opened_device_ = device;
+ OnDeviceOpenSuccess();
+ }
}
- mojo::BindingSet<mojom::MediaStreamDispatcher> bindings_;
+ mojo::BindingSet<mojom::MediaStreamDeviceObserver> bindings_;
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::queue<base::Closure> quit_closures_;
};
@@ -239,11 +231,12 @@ class MediaStreamDispatcherHostTest : public testing::Test {
public:
MediaStreamDispatcherHostTest()
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- origin_(GURL("https://test.com")) {
+ origin_(url::Origin::Create(GURL("https://test.com"))) {
audio_manager_ = std::make_unique<media::MockAudioManager>(
std::make_unique<media::TestAudioThread>());
audio_system_ =
std::make_unique<media::AudioSystemImpl>(audio_manager_.get());
+ browser_context_ = std::make_unique<TestBrowserContext>();
// Make sure we use fake devices to avoid long delays.
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kUseFakeDeviceForMediaStream);
@@ -256,11 +249,14 @@ class MediaStreamDispatcherHostTest : public testing::Test {
std::move(mock_video_capture_provider));
host_ = std::make_unique<MockMediaStreamDispatcherHost>(
- browser_context_.GetMediaDeviceIDSalt(),
base::ThreadTaskRunnerHandle::Get(), media_stream_manager_.get());
- mojom::MediaStreamDispatcherPtr dispatcher =
+ host_->set_salt_and_origin_callback_for_testing(
+ base::BindRepeating(&MediaStreamDispatcherHostTest::GetSaltAndOrigin,
+ base::Unretained(this)));
+ mojom::MediaStreamDeviceObserverPtr observer =
host_->CreateInterfacePtrAndBind();
- host_->SetMediaStreamDispatcherForTesting(kRenderId, std::move(dispatcher));
+ host_->SetMediaStreamDeviceObserverForTesting(kRenderId,
+ std::move(observer));
#if defined(OS_CHROMEOS)
chromeos::CrasAudioHandler::InitializeForTesting();
@@ -342,7 +338,7 @@ class MediaStreamDispatcherHostTest : public testing::Test {
EXPECT_CALL(*host_, OnStreamGenerationSuccess(page_request_id,
expected_audio_array_size,
expected_video_array_size));
- host_->OnGenerateStream(render_frame_id, page_request_id, controls, origin_,
+ host_->OnGenerateStream(render_frame_id, page_request_id, controls,
run_loop.QuitClosure());
run_loop.Run();
EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
@@ -360,22 +356,34 @@ class MediaStreamDispatcherHostTest : public testing::Test {
EXPECT_CALL(*host_,
OnStreamGenerationFailure(page_request_id, expected_result));
host_->OnGenerateStream(render_frame_id, page_request_id, controls,
- origin_, run_loop.QuitClosure());
+ run_loop.QuitClosure());
run_loop.Run();
}
void OpenVideoDeviceAndWaitForResult(int render_frame_id,
int page_request_id,
const std::string& device_id) {
+ EXPECT_CALL(*host_, OnDeviceOpenSuccess());
base::RunLoop run_loop;
host_->OnOpenDevice(render_frame_id, page_request_id, device_id,
- MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
- run_loop.QuitClosure());
+ MEDIA_DEVICE_VIDEO_CAPTURE, run_loop.QuitClosure());
run_loop.Run();
EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
}
+ void OpenVideoDeviceAndWaitForFailure(int render_frame_id,
+ int page_request_id,
+ const std::string& device_id) {
+ EXPECT_CALL(*host_, OnDeviceOpenSuccess()).Times(0);
+ base::RunLoop run_loop;
+ host_->OnOpenDevice(render_frame_id, page_request_id, device_id,
+ MEDIA_DEVICE_VIDEO_CAPTURE, run_loop.QuitClosure());
+ run_loop.Run();
+ EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
+ EXPECT_FALSE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
+ }
+
bool DoesContainRawIds(const MediaStreamDevices& devices) {
for (size_t i = 0; i < devices.size(); ++i) {
if (devices[i].id != media::AudioDeviceDescription::kDefaultDeviceId &&
@@ -401,7 +409,7 @@ class MediaStreamDispatcherHostTest : public testing::Test {
media::AudioDeviceDescriptions::const_iterator audio_it =
audio_device_descriptions_.begin();
for (; audio_it != audio_device_descriptions_.end(); ++audio_it) {
- if (DoesMediaDeviceIDMatchHMAC(browser_context_.GetMediaDeviceIDSalt(),
+ if (DoesMediaDeviceIDMatchHMAC(browser_context_->GetMediaDeviceIDSalt(),
origin, devices[i].id,
audio_it->unique_id)) {
EXPECT_FALSE(found_match);
@@ -409,7 +417,7 @@ class MediaStreamDispatcherHostTest : public testing::Test {
}
}
for (const std::string& device_id : stub_video_device_ids_) {
- if (DoesMediaDeviceIDMatchHMAC(browser_context_.GetMediaDeviceIDSalt(),
+ if (DoesMediaDeviceIDMatchHMAC(browser_context_->GetMediaDeviceIDSalt(),
origin, devices[i].id, device_id)) {
EXPECT_FALSE(found_match);
found_match = true;
@@ -421,12 +429,17 @@ class MediaStreamDispatcherHostTest : public testing::Test {
return true;
}
+ std::pair<std::string, url::Origin> GetSaltAndOrigin(int /* process_id */,
+ int /* frame_id */) {
+ return std::make_pair(browser_context_->GetMediaDeviceIDSalt(), origin_);
+ }
+
std::unique_ptr<MockMediaStreamDispatcherHost> host_;
std::unique_ptr<MediaStreamManager> media_stream_manager_;
TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<media::AudioManager> audio_manager_;
std::unique_ptr<media::AudioSystem> audio_system_;
- TestBrowserContext browser_context_;
+ std::unique_ptr<TestBrowserContext> browser_context_;
media::AudioDeviceDescriptions audio_device_descriptions_;
std::vector<std::string> stub_video_device_ids_;
url::Origin origin_;
@@ -477,7 +490,7 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithDepthVideo) {
// We specify to generate both audio and video stream.
StreamControls controls(true, true);
std::string source_id = GetHMACForMediaDeviceID(
- browser_context_.GetMediaDeviceIDSalt(), origin_, kDepthVideoDeviceId);
+ browser_context_->GetMediaDeviceIDSalt(), origin_, kDepthVideoDeviceId);
// |source_id| corresponds to the depth device. As we can generate only one
// video stream using GenerateStreamAndWaitForResult, we use
// controls.video.source_id to specify that the stream is depth video.
@@ -559,7 +572,6 @@ TEST_F(MediaStreamDispatcherHostTest,
EXPECT_NE(label1, label2);
}
-
// This test generates two streams with video only using two separate render
// frame ids. The same device id but different session ids are expected.
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
@@ -577,10 +589,10 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
const int session_id1 = host_->video_devices_.front().session_id;
// Generate second stream from another render frame.
- mojom::MediaStreamDispatcherPtr dispatcher =
+ mojom::MediaStreamDeviceObserverPtr observer =
host_->CreateInterfacePtrAndBind();
- host_->SetMediaStreamDispatcherForTesting(kRenderId + 1,
- std::move(dispatcher));
+ host_->SetMediaStreamDeviceObserverForTesting(kRenderId + 1,
+ std::move(observer));
GenerateStreamAndWaitForResult(kRenderId + 1, kPageRequestId + 1, controls);
// Check the latest generated stream.
@@ -611,9 +623,9 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
}
base::RunLoop run_loop1;
base::RunLoop run_loop2;
- host_->OnGenerateStream(kRenderId, kPageRequestId, controls, origin_,
+ host_->OnGenerateStream(kRenderId, kPageRequestId, controls,
run_loop1.QuitClosure());
- host_->OnGenerateStream(kRenderId, kPageRequestId + 1, controls, origin_,
+ host_->OnGenerateStream(kRenderId, kPageRequestId + 1, controls,
run_loop2.QuitClosure());
run_loop1.Run();
@@ -630,7 +642,7 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithSourceId) {
audio_device_descriptions_.begin();
for (; audio_it != audio_device_descriptions_.end(); ++audio_it) {
std::string source_id = GetHMACForMediaDeviceID(
- browser_context_.GetMediaDeviceIDSalt(), origin_, audio_it->unique_id);
+ browser_context_->GetMediaDeviceIDSalt(), origin_, audio_it->unique_id);
ASSERT_FALSE(source_id.empty());
StreamControls controls(true, true);
controls.audio.device_id = source_id;
@@ -642,7 +654,7 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithSourceId) {
for (const std::string& device_id : stub_video_device_ids_) {
std::string source_id = GetHMACForMediaDeviceID(
- browser_context_.GetMediaDeviceIDSalt(), origin_, device_id);
+ browser_context_->GetMediaDeviceIDSalt(), origin_, device_id);
ASSERT_FALSE(source_id.empty());
StreamControls controls(true, true);
controls.video.device_id = source_id;
@@ -750,7 +762,7 @@ TEST_F(MediaStreamDispatcherHostTest,
EXPECT_CALL(*host_, OnStreamGenerationSuccess(kPageRequestId + 1, 0, 1));
base::RunLoop run_loop1;
- host_->OnGenerateStream(kRenderId, kPageRequestId + 1, controls, origin_,
+ host_->OnGenerateStream(kRenderId, kPageRequestId + 1, controls,
run_loop1.QuitClosure());
// Stop the video stream device from stream 1 while waiting for the
@@ -769,7 +781,7 @@ TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreams) {
// Create multiple GenerateStream requests.
size_t streams = 5;
for (size_t i = 1; i <= streams; ++i) {
- host_->OnGenerateStream(kRenderId, kPageRequestId + i, controls, origin_,
+ host_->OnGenerateStream(kRenderId, kPageRequestId + i, controls,
run_loop.QuitClosure());
}
@@ -817,7 +829,7 @@ TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
base::RunLoop().RunUntilIdle();
}
-// Test that the dispatcher is notified if a video device that is in use is
+// Test that the observer is notified if a video device that is in use is
// being unplugged.
TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
StreamControls controls(true, true);
@@ -837,4 +849,36 @@ TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
run_loop.Run();
}
+// Test that changing the salt invalidates device IDs. Attempts to open an
+// invalid device ID result in failure.
+TEST_F(MediaStreamDispatcherHostTest, Salt) {
+ SetupFakeUI(true);
+ StreamControls controls(false, true);
+
+ // Generate first stream.
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, controls);
+ EXPECT_EQ(host_->audio_devices_.size(), 0u);
+ EXPECT_EQ(host_->video_devices_.size(), 1u);
+ const std::string label1 = host_->label_;
+ const std::string device_id1 = host_->video_devices_.front().id;
+ const int session_id1 = host_->video_devices_.front().session_id;
+
+ // Generate second stream.
+ OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
+ const std::string device_id2 = host_->opened_device_.id;
+ const int session_id2 = host_->opened_device_.session_id;
+ const std::string label2 = host_->label_;
+ EXPECT_EQ(device_id1, device_id2);
+ EXPECT_NE(session_id1, session_id2);
+ EXPECT_NE(label1, label2);
+
+ // Reset salt and try to generate third stream with the invalidated device ID.
+ browser_context_ = std::make_unique<TestBrowserContext>();
+ EXPECT_CALL(*host_, OnDeviceOpenSuccess()).Times(0);
+ OpenVideoDeviceAndWaitForFailure(kRenderId, kPageRequestId, device_id1);
+ // Last open device ID and session are from the second stream.
+ EXPECT_EQ(session_id2, host_->opened_device_.session_id);
+ EXPECT_EQ(device_id2, host_->opened_device_.id);
+}
+
}; // namespace content
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 0eff1c52bf2..d086c41ebf7 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_manager.cc
@@ -32,7 +32,6 @@
#include "content/browser/renderer_host/media/in_process_video_capture_provider.h"
#include "content/browser/renderer_host/media/media_capture_devices_impl.h"
#include "content/browser/renderer_host/media/media_devices_manager.h"
-#include "content/browser/renderer_host/media/media_stream_requester.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_manager.h"
@@ -106,12 +105,12 @@ void ParseStreamType(const StreamControls& controls,
if (!controls.audio.stream_source.empty()) {
// This is tab or screen capture.
if (controls.audio.stream_source == kMediaStreamSourceTab) {
- *audio_type = content::MEDIA_TAB_AUDIO_CAPTURE;
+ *audio_type = MEDIA_TAB_AUDIO_CAPTURE;
} else if (controls.audio.stream_source == kMediaStreamSourceSystem) {
- *audio_type = content::MEDIA_DESKTOP_AUDIO_CAPTURE;
+ *audio_type = MEDIA_DESKTOP_AUDIO_CAPTURE;
} else if (audio_support_flag_for_desktop_share &&
controls.audio.stream_source == kMediaStreamSourceDesktop) {
- *audio_type = content::MEDIA_DESKTOP_AUDIO_CAPTURE;
+ *audio_type = MEDIA_DESKTOP_AUDIO_CAPTURE;
}
} else {
// This is normal audio device capture.
@@ -122,11 +121,11 @@ void ParseStreamType(const StreamControls& controls,
if (!controls.video.stream_source.empty()) {
// This is tab or screen capture.
if (controls.video.stream_source == kMediaStreamSourceTab) {
- *video_type = content::MEDIA_TAB_VIDEO_CAPTURE;
+ *video_type = MEDIA_TAB_VIDEO_CAPTURE;
} else if (controls.video.stream_source == kMediaStreamSourceScreen) {
- *video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE;
+ *video_type = MEDIA_DESKTOP_VIDEO_CAPTURE;
} else if (controls.video.stream_source == kMediaStreamSourceDesktop) {
- *video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE;
+ *video_type = MEDIA_DESKTOP_VIDEO_CAPTURE;
}
} else {
// This is normal video device capture.
@@ -228,15 +227,16 @@ void SendVideoCaptureLogMessage(const std::string& message) {
// statements in MediaStreamManager.
class MediaStreamManager::DeviceRequest {
public:
- DeviceRequest(int requesting_process_id,
- int requesting_frame_id,
- int page_request_id,
- const url::Origin& security_origin,
- bool user_gesture,
- MediaStreamRequestType request_type,
- const StreamControls& controls,
- const std::string& salt,
- base::WeakPtr<MediaStreamRequester> requester = nullptr)
+ DeviceRequest(
+ int requesting_process_id,
+ int requesting_frame_id,
+ int page_request_id,
+ const url::Origin& security_origin,
+ bool user_gesture,
+ MediaStreamRequestType request_type,
+ const StreamControls& controls,
+ const std::string& salt,
+ DeviceStoppedCallback device_stopped_cb = DeviceStoppedCallback())
: requesting_process_id(requesting_process_id),
requesting_frame_id(requesting_frame_id),
page_request_id(page_request_id),
@@ -245,14 +245,14 @@ class MediaStreamManager::DeviceRequest {
request_type(request_type),
controls(controls),
salt(salt),
- requester(std::move(requester)),
+ device_stopped_cb(std::move(device_stopped_cb)),
state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED),
audio_type_(MEDIA_NO_SERVICE),
video_type_(MEDIA_NO_SERVICE),
target_process_id_(-1),
target_frame_id_(-1) {}
- ~DeviceRequest() {}
+ ~DeviceRequest() { RunMojoCallbacks(); }
void SetAudioType(MediaStreamType audio_type) {
DCHECK(IsAudioInputMediaType(audio_type) ||
@@ -337,6 +337,19 @@ class MediaStreamManager::DeviceRequest {
video_type_, is_secure);
}
+ void RunMojoCallbacks() {
+ if (generate_stream_cb) {
+ std::move(generate_stream_cb)
+ .Run(MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN, std::string(),
+ MediaStreamDevices(), MediaStreamDevices());
+ }
+
+ if (open_device_cb) {
+ std::move(open_device_cb)
+ .Run(false /* success */, std::string(), MediaStreamDevice());
+ }
+ }
+
// The render process id that requested this stream to be generated and that
// will receive a handle to the MediaStream. This may be different from
// MediaStreamRequest::render_process_id which in the tab capture case
@@ -362,14 +375,18 @@ class MediaStreamManager::DeviceRequest {
const std::string salt;
- base::WeakPtr<MediaStreamRequester> requester;
-
MediaStreamDevices devices;
// Callback to the requester which audio/video devices have been selected.
// It can be null if the requester has no interest to know the result.
// Currently it is only used by |DEVICE_ACCESS| type.
- MediaStreamManager::MediaRequestResponseCallback callback;
+ MediaAccessRequestCallback media_access_request_cb;
+
+ GenerateStreamCallback generate_stream_cb;
+
+ OpenDeviceCallback open_device_cb;
+
+ DeviceStoppedCallback device_stopped_cb;
std::unique_ptr<MediaStreamUIProxy> ui_proxy;
@@ -416,7 +433,6 @@ MediaStreamManager::MediaStreamManager(
video_capture_thread_("VideoCaptureThread"),
#endif
fake_ui_factory_() {
-
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseFakeUIForMediaStream)) {
fake_ui_factory_ = base::Bind([] {
@@ -438,8 +454,8 @@ MediaStreamManager::MediaStreamManager(
device_task_runner = video_capture_thread_.task_runner();
#endif
if (base::FeatureList::IsEnabled(video_capture::kMojoVideoCapture)) {
- video_capture_provider = base::MakeUnique<VideoCaptureProviderSwitcher>(
- base::MakeUnique<ServiceVideoCaptureProvider>(
+ video_capture_provider = std::make_unique<VideoCaptureProviderSwitcher>(
+ std::make_unique<ServiceVideoCaptureProvider>(
base::BindRepeating(&SendVideoCaptureLogMessage)),
InProcessVideoCaptureProvider::CreateInstanceForNonDeviceCapture(
std::move(device_task_runner),
@@ -448,7 +464,7 @@ MediaStreamManager::MediaStreamManager(
video_capture::uma::LogVideoCaptureServiceEvent(
video_capture::uma::BROWSER_USING_LEGACY_CAPTURE);
video_capture_provider = InProcessVideoCaptureProvider::CreateInstance(
- base::MakeUnique<media::VideoCaptureSystemImpl>(
+ std::make_unique<media::VideoCaptureSystemImpl>(
media::VideoCaptureDeviceFactory::CreateFactory(
BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
BrowserGpuMemoryBufferManager::current())),
@@ -521,7 +537,7 @@ std::string MediaStreamManager::MakeMediaAccessRequest(
int page_request_id,
const StreamControls& controls,
const url::Origin& security_origin,
- MediaRequestResponseCallback callback) {
+ MediaAccessRequestCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DeviceRequest* request = new DeviceRequest(
@@ -531,7 +547,7 @@ std::string MediaStreamManager::MakeMediaAccessRequest(
const std::string& label = AddRequest(request);
- request->callback = std::move(callback);
+ request->media_access_request_cb = std::move(callback);
// Post a task and handle the request asynchronously. The reason is that the
// requester won't have a label for the request until this function returns
// and thus can not handle a response. Using base::Unretained is safe since
@@ -544,25 +560,28 @@ std::string MediaStreamManager::MakeMediaAccessRequest(
}
void MediaStreamManager::GenerateStream(
- base::WeakPtr<MediaStreamRequester> requester,
int render_process_id,
int render_frame_id,
const std::string& salt,
int page_request_id,
const StreamControls& controls,
const url::Origin& security_origin,
- bool user_gesture) {
+ bool user_gesture,
+ GenerateStreamCallback generate_stream_cb,
+ DeviceStoppedCallback device_stopped_cb) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DVLOG(1) << "GenerateStream()";
DeviceRequest* request =
new DeviceRequest(render_process_id, render_frame_id, page_request_id,
security_origin, user_gesture, MEDIA_GENERATE_STREAM,
- controls, salt, std::move(requester));
+ controls, salt, std::move(device_stopped_cb));
const std::string& label = AddRequest(request);
- if (!generate_stream_test_callback_.is_null()) {
+ request->generate_stream_cb = std::move(generate_stream_cb);
+
+ if (generate_stream_test_callback_) {
// The test callback is responsible to verify whether the |controls| is
// as expected. Then we need to finish getUserMedia and let Javascript
// access the result.
@@ -737,15 +756,15 @@ void MediaStreamManager::CloseDevice(MediaStreamType type, int session_id) {
}
}
-void MediaStreamManager::OpenDevice(
- base::WeakPtr<MediaStreamRequester> requester,
- int render_process_id,
- int render_frame_id,
- const std::string& salt,
- int page_request_id,
- const std::string& device_id,
- MediaStreamType type,
- const url::Origin& security_origin) {
+void MediaStreamManager::OpenDevice(int render_process_id,
+ int render_frame_id,
+ const std::string& salt,
+ int page_request_id,
+ const std::string& device_id,
+ MediaStreamType type,
+ const url::Origin& security_origin,
+ OpenDeviceCallback open_device_cb,
+ DeviceStoppedCallback device_stopped_cb) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
type == MEDIA_DEVICE_VIDEO_CAPTURE);
@@ -763,9 +782,12 @@ void MediaStreamManager::OpenDevice(
DeviceRequest* request = new DeviceRequest(
render_process_id, render_frame_id, page_request_id, security_origin,
false, // user gesture
- MEDIA_OPEN_DEVICE_PEPPER_ONLY, controls, salt, std::move(requester));
+ MEDIA_OPEN_DEVICE_PEPPER_ONLY, controls, salt,
+ std::move(device_stopped_cb));
const std::string& label = AddRequest(request);
+
+ request->open_device_cb = std::move(open_device_cb);
// Post a task and handle the request asynchronously. The reason is that the
// requester won't have a label for the request until this function returns
// and thus can not handle a response. Using base::Unretained is safe since
@@ -818,10 +840,9 @@ void MediaStreamManager::StopRemovedDevice(
request->salt, request->security_origin, media_device_info.device_id);
if (device.id == source_id && device.type == stream_type) {
session_ids.push_back(device.session_id);
- if (labeled_request.second->requester) {
- labeled_request.second->requester->DeviceStopped(
- labeled_request.second->requesting_frame_id,
- labeled_request.first, device);
+ if (request->device_stopped_cb) {
+ request->device_stopped_cb.Run(request->requesting_frame_id,
+ labeled_request.first, device);
}
}
}
@@ -915,7 +936,7 @@ std::string MediaStreamManager::AddRequest(DeviceRequest* request) {
std::string unique_label;
do {
unique_label = RandomLabel();
- } while (FindRequest(unique_label) != NULL);
+ } while (FindRequest(unique_label) != nullptr);
requests_.push_back(std::make_pair(unique_label, request));
@@ -928,7 +949,7 @@ MediaStreamManager::FindRequest(const std::string& label) const {
if (labeled_request.first == label)
return labeled_request.second;
}
- return NULL;
+ return nullptr;
}
void MediaStreamManager::DeleteRequest(const std::string& label) {
@@ -1105,7 +1126,7 @@ bool MediaStreamManager::SetupTabCaptureRequest(DeviceRequest* request) {
}
// Customize controls for a WebContents based capture.
- content::WebContentsMediaCaptureId web_id;
+ WebContentsMediaCaptureId web_id;
bool has_valid_device_id =
WebContentsMediaCaptureId::Parse(capture_device_id, &web_id);
if (!has_valid_device_id ||
@@ -1210,6 +1231,7 @@ void MediaStreamManager::FinalizeGenerateStream(const std::string& label,
DeviceRequest* request) {
DVLOG(1) << "FinalizeGenerateStream label " << label;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(request->generate_stream_cb);
// Partition the array of devices into audio vs video.
MediaStreamDevices audio_devices, video_devices;
@@ -1222,30 +1244,39 @@ void MediaStreamManager::FinalizeGenerateStream(const std::string& label,
NOTREACHED();
}
- if (request->requester) {
- request->requester->StreamGenerated(request->requesting_frame_id,
- request->page_request_id, label,
- audio_devices, video_devices);
- }
+ std::move(request->generate_stream_cb)
+ .Run(MEDIA_DEVICE_OK, label, audio_devices, video_devices);
}
void MediaStreamManager::FinalizeRequestFailed(
const std::string& label,
DeviceRequest* request,
- content::MediaStreamRequestResult result) {
+ MediaStreamRequestResult result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (request->requester) {
- request->requester->StreamGenerationFailed(
- request->requesting_frame_id,
- request->page_request_id,
- result);
- }
-
- if (request->request_type == MEDIA_DEVICE_ACCESS &&
- !request->callback.is_null()) {
- std::move(request->callback)
- .Run(MediaStreamDevices(), std::move(request->ui_proxy));
+ switch (request->request_type) {
+ case MEDIA_GENERATE_STREAM: {
+ DCHECK(request->generate_stream_cb);
+ std::move(request->generate_stream_cb)
+ .Run(result, std::string(), MediaStreamDevices(),
+ MediaStreamDevices());
+ break;
+ }
+ case MEDIA_OPEN_DEVICE_PEPPER_ONLY: {
+ DCHECK(request->open_device_cb);
+ std::move(request->open_device_cb)
+ .Run(false /* success */, std::string(), MediaStreamDevice());
+ break;
+ }
+ case MEDIA_DEVICE_ACCESS: {
+ DCHECK(request->media_access_request_cb);
+ std::move(request->media_access_request_cb)
+ .Run(MediaStreamDevices(), std::move(request->ui_proxy));
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
}
DeleteRequest(label);
@@ -1254,20 +1285,19 @@ void MediaStreamManager::FinalizeRequestFailed(
void MediaStreamManager::FinalizeOpenDevice(const std::string& label,
DeviceRequest* request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(request->open_device_cb);
- if (request->requester) {
- request->requester->DeviceOpened(request->requesting_frame_id,
- request->page_request_id, label,
- request->devices.front());
- }
+ std::move(request->open_device_cb)
+ .Run(true /* success */, label, request->devices.front());
}
void MediaStreamManager::FinalizeMediaAccessRequest(
const std::string& label,
DeviceRequest* request,
const MediaStreamDevices& devices) {
- if (!request->callback.is_null())
- std::move(request->callback).Run(devices, std::move(request->ui_proxy));
+ DCHECK(request->media_access_request_cb);
+ std::move(request->media_access_request_cb)
+ .Run(devices, std::move(request->ui_proxy));
// Delete the request since it is done.
DeleteRequest(label);
@@ -1333,7 +1363,7 @@ void MediaStreamManager::Opened(MediaStreamType stream_type,
// Store the native audio parameters in the device struct.
// TODO(xians): Handle the tab capture sample rate/channel layout
// in AudioInputDeviceManager::Open().
- if (device.type != content::MEDIA_TAB_AUDIO_CAPTURE) {
+ if (device.type != MEDIA_TAB_AUDIO_CAPTURE) {
const MediaStreamDevice* opened_device =
audio_input_device_manager_->GetOpenedDeviceById(
device.session_id);
@@ -1439,20 +1469,30 @@ void MediaStreamManager::UseFakeUIFactoryForTests(
fake_ui_factory_ = fake_ui_factory;
}
+// static
void MediaStreamManager::RegisterNativeLogCallback(
int renderer_host_id,
const base::Callback<void(const std::string&)>& callback) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&MediaStreamManager::DoNativeLogCallbackRegistration,
- base::Unretained(this), renderer_host_id, callback));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ MediaStreamManager* msm = g_media_stream_manager_tls_ptr.Pointer()->Get();
+ if (!msm) {
+ DLOG(ERROR) << "No MediaStreamManager on the IO thread.";
+ return;
+ }
+
+ msm->DoNativeLogCallbackRegistration(renderer_host_id, callback);
}
+// static
void MediaStreamManager::UnregisterNativeLogCallback(int renderer_host_id) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&MediaStreamManager::DoNativeLogCallbackUnregistration,
- base::Unretained(this), renderer_host_id));
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ MediaStreamManager* msm = g_media_stream_manager_tls_ptr.Pointer()->Get();
+ if (!msm) {
+ DLOG(ERROR) << "No MediaStreamManager on the IO thread.";
+ return;
+ }
+
+ msm->DoNativeLogCallbackUnregistration(renderer_host_id);
}
void MediaStreamManager::AddLogMessageOnIOThread(const std::string& message) {
@@ -1465,7 +1505,7 @@ void MediaStreamManager::HandleAccessRequestResponse(
const std::string& label,
const media::AudioParameters& output_parameters,
const MediaStreamDevices& devices,
- content::MediaStreamRequestResult result) {
+ MediaStreamRequestResult result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DVLOG(1) << "HandleAccessRequestResponse("
<< ", {label = " << label << "})";
@@ -1494,16 +1534,16 @@ void MediaStreamManager::HandleAccessRequestResponse(
for (const MediaStreamDevice& media_stream_device : devices) {
MediaStreamDevice device = media_stream_device;
- if (device.type == content::MEDIA_TAB_VIDEO_CAPTURE ||
- device.type == content::MEDIA_TAB_AUDIO_CAPTURE) {
+ if (device.type == MEDIA_TAB_VIDEO_CAPTURE ||
+ device.type == MEDIA_TAB_AUDIO_CAPTURE) {
device.id = request->tab_capture_device_id;
}
// Initialize the sample_rate and channel_layout here since for audio
// mirroring, we don't go through EnumerateDevices where these are usually
// initialized.
- if (device.type == content::MEDIA_TAB_AUDIO_CAPTURE ||
- device.type == content::MEDIA_DESKTOP_AUDIO_CAPTURE) {
+ if (device.type == MEDIA_TAB_AUDIO_CAPTURE ||
+ device.type == MEDIA_DESKTOP_AUDIO_CAPTURE) {
int sample_rate = output_parameters.sample_rate();
// If we weren't able to get the native sampling rate or the sample_rate
// is outside the valid range for input devices set reasonable defaults.
@@ -1571,10 +1611,10 @@ void MediaStreamManager::StopMediaStreamFromBrowser(const std::string& label) {
return;
// Notify renderers that the devices in the stream will be stopped.
- if (request->requester) {
+ if (request->device_stopped_cb) {
for (const MediaStreamDevice& device : request->devices) {
- request->requester->DeviceStopped(request->requesting_frame_id, label,
- device);
+ request->device_stopped_cb.Run(request->requesting_frame_id, label,
+ device);
}
}
@@ -1584,7 +1624,6 @@ void MediaStreamManager::StopMediaStreamFromBrowser(const std::string& label) {
void MediaStreamManager::WillDestroyCurrentMessageLoop() {
DVLOG(3) << "MediaStreamManager::WillDestroyCurrentMessageLoop()";
DCHECK(CalledOnIOThread());
- DCHECK(requests_.empty());
if (media_devices_manager_)
media_devices_manager_->StopMonitoring();
if (video_capture_manager_)
@@ -1596,6 +1635,7 @@ void MediaStreamManager::WillDestroyCurrentMessageLoop() {
video_capture_manager_ = nullptr;
media_devices_manager_ = nullptr;
g_media_stream_manager_tls_ptr.Pointer()->Set(nullptr);
+ requests_.clear();
}
void MediaStreamManager::NotifyDevicesChanged(
@@ -1750,7 +1790,7 @@ bool MediaStreamManager::IsOriginAllowed(int render_process_id,
void MediaStreamManager::SetCapturingLinkSecured(int render_process_id,
int session_id,
- content::MediaStreamType type,
+ MediaStreamType type,
bool is_secure) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
for (LabeledDeviceRequest& labeled_request : requests_) {
diff --git a/chromium/content/browser/renderer_host/media/media_stream_manager.h b/chromium/content/browser/renderer_host/media/media_stream_manager.h
index bbec41920a1..dcc045f2d00 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_manager.h
+++ b/chromium/content/browser/renderer_host/media/media_stream_manager.h
@@ -15,7 +15,7 @@
// users to select which devices to use and send callback to
// MediaStreamManager with the result.
// 5. MediaStreamManager will call the proper media device manager to open the
-// device and let the MediaStreamRequester know it has been done.
+// device and run the corresponding callback with result.
// If either user or test harness selects --use-fake-device-for-media-stream,
// a fake video device or devices are used instead of real ones.
@@ -33,6 +33,7 @@
#include <utility>
#include <vector>
+#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -61,27 +62,42 @@ namespace content {
class AudioInputDeviceManager;
class FakeMediaStreamUIProxy;
-class MediaStreamRequester;
class MediaStreamUIProxy;
class VideoCaptureManager;
class VideoCaptureProvider;
// MediaStreamManager is used to generate and close new media devices, not to
// start the media flow. The classes requesting new media streams are answered
-// using MediaStreamRequester.
+// using callbacks.
class CONTENT_EXPORT MediaStreamManager
: public MediaStreamProviderListener,
public base::MessageLoop::DestructionObserver,
public base::PowerObserver {
public:
- // Callback to deliver the result of a media request.
- typedef base::OnceCallback<void(const MediaStreamDevices& devices,
- std::unique_ptr<MediaStreamUIProxy> ui)>
- MediaRequestResponseCallback;
+ // Callback to deliver the result of a media access request.
+ using MediaAccessRequestCallback =
+ base::OnceCallback<void(const MediaStreamDevices& devices,
+ std::unique_ptr<MediaStreamUIProxy> ui)>;
+
+ using GenerateStreamCallback =
+ base::OnceCallback<void(MediaStreamRequestResult result,
+ const std::string& label,
+ const MediaStreamDevices& audio_devices,
+ const MediaStreamDevices& video_devices)>;
+
+ using OpenDeviceCallback =
+ base::OnceCallback<void(bool success,
+ const std::string& label,
+ const MediaStreamDevice& device)>;
+
+ using DeviceStoppedCallback =
+ base::RepeatingCallback<void(int render_frame_id,
+ const std::string& label,
+ const MediaStreamDevice& device)>;
// Callback for testing.
- typedef base::Callback<bool(const StreamControls&)>
- GenerateStreamTestCallback;
+ using GenerateStreamTestCallback =
+ base::Callback<bool(const StreamControls&)>;
// Adds |message| to native logs for outstanding device requests, for use by
// render processes hosts whose corresponding render processes are requesting
@@ -134,20 +150,22 @@ class CONTENT_EXPORT MediaStreamManager
int page_request_id,
const StreamControls& controls,
const url::Origin& security_origin,
- MediaRequestResponseCallback callback);
+ MediaAccessRequestCallback callback);
// GenerateStream opens new media devices according to |components|. It
// creates a new request which is identified by a unique string that's
// returned to the caller. |render_process_id| and |render_frame_id| are used
- // to determine where the infobar will appear to the user.
- void GenerateStream(base::WeakPtr<MediaStreamRequester> requester,
- int render_process_id,
+ // to determine where the infobar will appear to the user. |device_stopped_cb|
+ // is set to receive device stopped notifications.
+ void GenerateStream(int render_process_id,
int render_frame_id,
const std::string& salt,
int page_request_id,
const StreamControls& controls,
const url::Origin& security_origin,
- bool user_gesture);
+ bool user_gesture,
+ GenerateStreamCallback generate_stream_cb,
+ DeviceStoppedCallback device_stopped_cb);
void CancelRequest(int render_process_id,
int render_frame_id,
@@ -165,17 +183,19 @@ class CONTENT_EXPORT MediaStreamManager
int render_frame_id,
const std::string& device_id);
- // Open a device identified by |device_id|. |type| must be either
+ // Open a device identified by |device_id|. |type| must be either
// MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE.
- // The request is identified using string returned to the caller.
- void OpenDevice(base::WeakPtr<MediaStreamRequester> requester,
- int render_process_id,
+ // |device_stopped_cb| is set to receive device stopped notifications. The
+ // request is identified using string returned to the caller.
+ void OpenDevice(int render_process_id,
int render_frame_id,
const std::string& salt,
int page_request_id,
const std::string& device_id,
MediaStreamType type,
- const url::Origin& security_origin);
+ const url::Origin& security_origin,
+ OpenDeviceCallback open_device_cb,
+ DeviceStoppedCallback device_stopped_cb);
// Finds and returns the device id corresponding to the given
// |source_id|. Returns true if there was a raw device id that matched the
@@ -231,12 +251,11 @@ class CONTENT_EXPORT MediaStreamManager
fake_ui_factory);
// Register and unregister a new callback for receiving native log entries.
- // The registered callback will be invoked on the IO thread.
- // The registration and unregistration will be done asynchronously so it is
- // not guaranteed that when the call returns the operation has completed.
- void RegisterNativeLogCallback(int renderer_host_id,
+ // Called on the IO thread.
+ static void RegisterNativeLogCallback(
+ int renderer_host_id,
const base::Callback<void(const std::string&)>& callback);
- void UnregisterNativeLogCallback(int renderer_host_id);
+ static void UnregisterNativeLogCallback(int renderer_host_id);
// Generates a hash of a device's unique ID usable by one
// particular security origin.
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 9e9511080e5..db870f3f963 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
@@ -83,8 +83,8 @@ class MockAudioManager : public AudioManagerPlatform {
for (size_t i = 0; i < num_input_devices_; i++) {
device_names->push_back(media::AudioDeviceName(
- std::string("fake_device_name_") + base::SizeTToString(i),
- std::string("fake_device_id_") + base::SizeTToString(i)));
+ std::string("fake_device_name_") + base::NumberToString(i),
+ std::string("fake_device_id_") + base::NumberToString(i)));
}
}
@@ -98,8 +98,8 @@ class MockAudioManager : public AudioManagerPlatform {
for (size_t i = 0; i < num_output_devices_; i++) {
device_names->push_back(media::AudioDeviceName(
- std::string("fake_device_name_") + base::SizeTToString(i),
- std::string("fake_device_id_") + base::SizeTToString(i)));
+ std::string("fake_device_name_") + base::NumberToString(i),
+ std::string("fake_device_id_") + base::NumberToString(i)));
}
}
@@ -160,7 +160,7 @@ class MediaStreamManagerTest : public ::testing::Test {
const int render_frame_id = 1;
const int page_request_id = 1;
const url::Origin security_origin;
- MediaStreamManager::MediaRequestResponseCallback callback =
+ MediaStreamManager::MediaAccessRequestCallback callback =
base::BindOnce(&MediaStreamManagerTest::ResponseCallback,
base::Unretained(this), index);
StreamControls controls(true, true);
@@ -207,7 +207,7 @@ TEST_F(MediaStreamManagerTest, MakeMultipleRequests) {
int page_request_id = 2;
url::Origin security_origin;
StreamControls controls(true, true);
- MediaStreamManager::MediaRequestResponseCallback callback = base::BindOnce(
+ MediaStreamManager::MediaAccessRequestCallback callback = base::BindOnce(
&MediaStreamManagerTest::ResponseCallback, base::Unretained(this), 1);
std::string label2 = media_stream_manager_->MakeMediaAccessRequest(
render_process_id, render_frame_id, page_request_id, controls,
@@ -233,7 +233,7 @@ TEST_F(MediaStreamManagerTest, MakeAndCancelMultipleRequests) {
}
TEST_F(MediaStreamManagerTest, DeviceID) {
- url::Origin security_origin(GURL("http://localhost"));
+ url::Origin security_origin = url::Origin::Create(GURL("http://localhost"));
const std::string unique_default_id(
media::AudioDeviceDescription::kDefaultDeviceId);
const std::string hashed_default_id =
diff --git a/chromium/content/browser/renderer_host/media/media_stream_requester.h b/chromium/content/browser/renderer_host/media/media_stream_requester.h
deleted file mode 100644
index ab27463658a..00000000000
--- a/chromium/content/browser/renderer_host/media/media_stream_requester.h
+++ /dev/null
@@ -1,49 +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_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_REQUESTER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_REQUESTER_H_
-
-#include <string>
-
-#include "content/common/content_export.h"
-#include "content/public/common/media_stream_request.h"
-
-namespace content {
-
-// MediaStreamRequester must be implemented by the class requesting a new media
-// stream to be opened. MediaStreamManager will use this interface to signal
-// success and error for a request.
-class CONTENT_EXPORT MediaStreamRequester {
- public:
- // Called as a reply of a successful call to GenerateStream.
- virtual void StreamGenerated(int render_frame_id,
- int page_request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) = 0;
- // Called if GenerateStream failed.
- virtual void StreamGenerationFailed(int render_frame_id,
- int page_request_id,
- MediaStreamRequestResult result) = 0;
- // Called if a device has been stopped by a user from UI or the device
- // has become unavailable. |render_frame_id| is the render frame that
- // requested the device and |label| is the label of the request.
- virtual void DeviceStopped(int render_frame_id,
- const std::string& label,
- const MediaStreamDevice& device) = 0;
- // Called as a reply of a successful call to OpenDevice.
- virtual void DeviceOpened(int render_frame_id,
- int page_request_id,
- const std::string& label,
- const MediaStreamDevice& device) = 0;
-
- protected:
- virtual ~MediaStreamRequester() {
- }
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_REQUESTER_H_
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 e6afeb38779..0e4fff2feeb 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
@@ -16,7 +16,7 @@
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "media/capture/video/fake_video_capture_device.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicyFeature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -24,7 +24,7 @@ namespace content {
bool IsFeatureEnabled(RenderFrameHost* rfh,
bool tests_use_fake_render_frame_hosts,
- blink::WebFeaturePolicyFeature feature) {
+ blink::FeaturePolicyFeature feature) {
if (!base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions))
return true;
@@ -45,13 +45,13 @@ void SetAndCheckAncestorFlag(MediaStreamRequest* request) {
RenderFrameHostImpl::FromID(request->render_process_id,
request->render_frame_id);
- if (rfh == NULL) {
+ if (rfh == nullptr) {
// RenderFrame destroyed before the request is handled?
return;
}
FrameTreeNode* node = rfh->frame_tree_node();
- while (node->parent() != NULL) {
+ while (node->parent() != nullptr) {
if (!node->HasSameOrigin(*node->parent())) {
request->all_ancestors_have_same_origin = false;
return;
@@ -152,13 +152,13 @@ void MediaStreamUIProxy::Core::ProcessAccessRequestResponse(
for (const MediaStreamDevice& device : devices) {
if (device.type == MEDIA_DEVICE_AUDIO_CAPTURE &&
!IsFeatureEnabled(host, tests_use_fake_render_frame_hosts_,
- blink::WebFeaturePolicyFeature::kMicrophone)) {
+ blink::FeaturePolicyFeature::kMicrophone)) {
continue;
}
if (device.type == MEDIA_DEVICE_VIDEO_CAPTURE &&
!IsFeatureEnabled(host, tests_use_fake_render_frame_hosts_,
- blink::WebFeaturePolicyFeature::kCamera)) {
+ blink::FeaturePolicyFeature::kCamera)) {
continue;
}
@@ -189,12 +189,12 @@ RenderFrameHostDelegate* MediaStreamUIProxy::Core::GetRenderFrameHostDelegate(
return test_render_delegate_;
RenderFrameHostImpl* host =
RenderFrameHostImpl::FromID(render_process_id, render_frame_id);
- return host ? host->delegate() : NULL;
+ return host ? host->delegate() : nullptr;
}
// static
std::unique_ptr<MediaStreamUIProxy> MediaStreamUIProxy::Create() {
- return std::unique_ptr<MediaStreamUIProxy>(new MediaStreamUIProxy(NULL));
+ return std::unique_ptr<MediaStreamUIProxy>(new MediaStreamUIProxy(nullptr));
}
// static
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 6408784e9b8..4e3e6eb19fa 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
@@ -277,7 +277,7 @@ class MediaStreamUIProxyFeaturePolicyTest
// The header policy should only be set once on page load, so we refresh the
// page to simulate that.
void RefreshPageAndSetHeaderPolicy(RenderFrameHost* rfh,
- blink::WebFeaturePolicyFeature feature,
+ blink::FeaturePolicyFeature feature,
bool enabled) {
NavigateAndCommit(rfh->GetLastCommittedURL());
std::vector<url::Origin> whitelist;
@@ -306,7 +306,7 @@ class MediaStreamUIProxyFeaturePolicyTest
std::unique_ptr<MediaStreamRequest> CreateRequest(RenderFrameHost* rfh,
MediaStreamType mic_type,
MediaStreamType cam_type) {
- return base::MakeUnique<MediaStreamRequest>(
+ return std::make_unique<MediaStreamRequest>(
rfh->GetProcess()->GetID(), rfh->GetRoutingID(), 0,
rfh->GetLastCommittedURL(), false, MEDIA_GENERATE_STREAM, std::string(),
std::string(), mic_type, cam_type, false);
@@ -387,7 +387,7 @@ TEST_F(MediaStreamUIProxyFeaturePolicyTest, FeaturePolicy) {
// Mic disabled.
RefreshPageAndSetHeaderPolicy(main_rfh(),
- blink::WebFeaturePolicyFeature::kMicrophone,
+ blink::FeaturePolicyFeature::kMicrophone,
/*enabled=*/false);
GetResultForRequest(CreateRequest(main_rfh(), MEDIA_DEVICE_AUDIO_CAPTURE,
MEDIA_DEVICE_VIDEO_CAPTURE),
@@ -398,7 +398,7 @@ TEST_F(MediaStreamUIProxyFeaturePolicyTest, FeaturePolicy) {
// Camera disabled.
RefreshPageAndSetHeaderPolicy(main_rfh(),
- blink::WebFeaturePolicyFeature::kCamera,
+ blink::FeaturePolicyFeature::kCamera,
/*enabled=*/false);
GetResultForRequest(CreateRequest(main_rfh(), MEDIA_DEVICE_AUDIO_CAPTURE,
MEDIA_DEVICE_VIDEO_CAPTURE),
@@ -409,7 +409,7 @@ TEST_F(MediaStreamUIProxyFeaturePolicyTest, FeaturePolicy) {
// Camera disabled resulting in no devices being returned.
RefreshPageAndSetHeaderPolicy(main_rfh(),
- blink::WebFeaturePolicyFeature::kCamera,
+ blink::FeaturePolicyFeature::kCamera,
/*enabled=*/false);
GetResultForRequest(
CreateRequest(main_rfh(), MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE),
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 1054a2836a3..f9754abb969 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
@@ -6,8 +6,8 @@
#include <utility>
-#include "base/metrics/histogram_macros.h"
#include "base/task_runner_util.h"
+#include "content/browser/renderer_host/media/audio_output_authorization_handler.h"
#include "content/browser/renderer_host/media/renderer_audio_output_stream_factory_context.h"
#include "content/public/browser/render_frame_host.h"
#include "media/base/audio_parameters.h"
@@ -16,17 +16,6 @@
namespace content {
-namespace {
-
-void UMALogDeviceAuthorizationTime(base::TimeTicks auth_start_time) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Media.Audio.OutputDeviceAuthorizationTime",
- base::TimeTicks::Now() - auth_start_time,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMilliseconds(5000), 50);
-}
-
-} // namespace
-
// static
std::unique_ptr<RenderFrameAudioOutputStreamFactoryHandle,
BrowserThread::DeleteOnIOThread>
@@ -117,7 +106,8 @@ void RenderFrameAudioOutputStreamFactory::AuthorizationCompleted(
const std::string& raw_device_id,
const std::string& device_id_for_renderer) {
DCHECK(thread_checker_.CalledOnValidThread());
- UMALogDeviceAuthorizationTime(auth_start_time);
+ AudioOutputAuthorizationHandler::UMALogDeviceAuthorizationTime(
+ auth_start_time);
if (status != media::OUTPUT_DEVICE_STATUS_OK) {
std::move(callback).Run(media::OutputDeviceStatus(status),
@@ -129,7 +119,7 @@ void RenderFrameAudioOutputStreamFactory::AuthorizationCompleted(
// Since |context_| outlives |this| and |this| outlives |stream_providers_|,
// unretained is safe.
stream_providers_.insert(
- base::MakeUnique<media::MojoAudioOutputStreamProvider>(
+ std::make_unique<media::MojoAudioOutputStreamProvider>(
std::move(request),
base::BindOnce(
&RendererAudioOutputStreamFactoryContext::CreateDelegate,
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 5c9a99047e0..8d9cafb2ae0 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
@@ -75,7 +75,7 @@ class MockAudioOutputDelegate : public media::AudioOutputDelegate {
std::move(on_destruction_).Run();
}
- MOCK_CONST_METHOD0(GetStreamId, int());
+ MOCK_METHOD0(GetStreamId, int());
MOCK_METHOD0(OnPlayStream, void());
MOCK_METHOD0(OnPauseStream, void());
MOCK_METHOD1(OnSetVolume, void(double));
@@ -144,9 +144,9 @@ class MockContext : public RendererAudioOutputStreamFactoryContext {
AudioOutputStreamFactoryPtr CreateFactory() {
DCHECK(!factory_);
AudioOutputStreamFactoryPtr ret;
- factory_ = base::MakeUnique<RenderFrameAudioOutputStreamFactory>(
+ factory_ = std::make_unique<RenderFrameAudioOutputStreamFactory>(
kRenderFrameId, this);
- factory_binding_ = base::MakeUnique<
+ factory_binding_ = std::make_unique<
mojo::Binding<mojom::RendererAudioOutputStreamFactory>>(
factory_.get(), mojo::MakeRequest(&ret));
return ret;
@@ -211,9 +211,9 @@ TEST(RenderFrameAudioOutputStreamFactoryTest, CreateStream) {
mojo::Binding<AudioOutputStreamClient> client_binding(
&client, mojo::MakeRequest(&client_ptr));
media::AudioOutputDelegate::EventHandler* event_handler = nullptr;
- auto factory_context = base::MakeUnique<MockContext>(true);
+ auto factory_context = std::make_unique<MockContext>(true);
factory_context->PrepareDelegateForCreation(
- base::MakeUnique<MockAudioOutputDelegate>(), &event_handler);
+ std::make_unique<MockAudioOutputDelegate>(), &event_handler);
AudioOutputStreamFactoryPtr factory_ptr = factory_context->CreateFactory();
media::OutputDeviceStatus status;
@@ -238,8 +238,8 @@ TEST(RenderFrameAudioOutputStreamFactoryTest, CreateStream) {
base::SharedMemory shared_memory;
ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(100));
- auto local = base::MakeUnique<base::CancelableSyncSocket>();
- auto remote = base::MakeUnique<base::CancelableSyncSocket>();
+ auto local = std::make_unique<base::CancelableSyncSocket>();
+ auto remote = std::make_unique<base::CancelableSyncSocket>();
ASSERT_TRUE(
base::CancelableSyncSocket::CreatePair(local.get(), remote.get()));
event_handler->OnStreamCreated(kStreamId, &shared_memory, std::move(remote));
@@ -252,7 +252,7 @@ TEST(RenderFrameAudioOutputStreamFactoryTest, CreateStream) {
TEST(RenderFrameAudioOutputStreamFactoryTest, NotAuthorized_Denied) {
content::TestBrowserThreadBundle thread_bundle;
AudioOutputStreamProviderPtr output_provider;
- auto factory_context = base::MakeUnique<MockContext>(false);
+ auto factory_context = std::make_unique<MockContext>(false);
AudioOutputStreamFactoryPtr factory_ptr = factory_context->CreateFactory();
media::OutputDeviceStatus status;
@@ -277,9 +277,9 @@ TEST(RenderFrameAudioOutputStreamFactoryTest, ConnectionError_DeletesStream) {
&client, mojo::MakeRequest(&client_ptr));
bool delegate_is_destructed = false;
media::AudioOutputDelegate::EventHandler* event_handler = nullptr;
- auto factory_context = base::MakeUnique<MockContext>(true);
+ auto factory_context = std::make_unique<MockContext>(true);
factory_context->PrepareDelegateForCreation(
- base::MakeUnique<MockAudioOutputDelegate>(
+ std::make_unique<MockAudioOutputDelegate>(
base::BindOnce([](bool* destructed) { *destructed = true; },
&delegate_is_destructed)),
&event_handler);
@@ -314,9 +314,9 @@ TEST(RenderFrameAudioOutputStreamFactoryTest, DelegateError_DeletesStream) {
&client, mojo::MakeRequest(&client_ptr));
bool delegate_is_destructed = false;
media::AudioOutputDelegate::EventHandler* event_handler = nullptr;
- auto factory_context = base::MakeUnique<MockContext>(true);
+ auto factory_context = std::make_unique<MockContext>(true);
factory_context->PrepareDelegateForCreation(
- base::MakeUnique<MockAudioOutputDelegate>(
+ std::make_unique<MockAudioOutputDelegate>(
base::BindOnce([](bool* destructed) { *destructed = true; },
&delegate_is_destructed)),
&event_handler);
@@ -360,7 +360,7 @@ TEST(RenderFrameAudioOutputStreamFactoryTest, OutOfRangeSessionId_BadMessage) {
TestBrowserThreadBundle thread_bundle;
AudioOutputStreamProviderPtr output_provider;
- auto factory_context = base::MakeUnique<MockContext>(true);
+ auto factory_context = std::make_unique<MockContext>(true);
auto factory_ptr = factory_context->CreateFactory();
int64_t session_id = std::numeric_limits<int>::max();
diff --git a/chromium/content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.cc b/chromium/content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.cc
index 485228fb10f..6f1960fd309 100644
--- a/chromium/content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.cc
+++ b/chromium/content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.cc
@@ -23,16 +23,13 @@ RendererAudioOutputStreamFactoryContextImpl::
int render_process_id,
media::AudioSystem* audio_system,
media::AudioManager* audio_manager,
- MediaStreamManager* media_stream_manager,
- const std::string& salt)
- : salt_(salt),
- audio_system_(audio_system),
+ MediaStreamManager* media_stream_manager)
+ : audio_system_(audio_system),
audio_manager_(audio_manager),
media_stream_manager_(media_stream_manager),
authorization_handler_(audio_system_,
media_stream_manager_,
- render_process_id,
- salt_),
+ render_process_id),
render_process_id_(render_process_id) {}
RendererAudioOutputStreamFactoryContextImpl::
diff --git a/chromium/content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.h b/chromium/content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.h
index 583c7e945cd..12bf8a3838f 100644
--- a/chromium/content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.h
+++ b/chromium/content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.h
@@ -47,8 +47,7 @@ class CONTENT_EXPORT RendererAudioOutputStreamFactoryContextImpl
int render_process_id,
media::AudioSystem* audio_system,
media::AudioManager* audio_manager,
- MediaStreamManager* media_stream_manager,
- const std::string& salt);
+ MediaStreamManager* media_stream_manager);
~RendererAudioOutputStreamFactoryContextImpl() override;
@@ -72,7 +71,6 @@ class CONTENT_EXPORT RendererAudioOutputStreamFactoryContextImpl
private:
// Used for hashing the device_id.
- const std::string salt_;
media::AudioSystem* const audio_system_;
media::AudioManager* const audio_manager_;
MediaStreamManager* const media_stream_manager_;
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 0c6a2289654..9dfb2d35fb0 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
@@ -22,8 +22,8 @@ void ConcludeLaunchDeviceWithSuccess(
VideoCaptureDeviceLauncher::Callbacks* callbacks,
base::OnceClosure done_cb) {
auto receiver_adapter =
- base::MakeUnique<video_capture::ReceiverMediaToMojoAdapter>(
- base::MakeUnique<media::VideoFrameReceiverOnTaskRunner>(
+ std::make_unique<video_capture::ReceiverMediaToMojoAdapter>(
+ std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
std::move(receiver),
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
video_capture::mojom::ReceiverPtr receiver_proxy;
@@ -31,7 +31,7 @@ void ConcludeLaunchDeviceWithSuccess(
std::move(receiver_adapter), mojo::MakeRequest(&receiver_proxy));
device->Start(params, std::move(receiver_proxy));
callbacks->OnDeviceLaunched(
- base::MakeUnique<ServiceLaunchedVideoCaptureDevice>(
+ std::make_unique<ServiceLaunchedVideoCaptureDevice>(
std::move(device), std::move(connection_lost_cb)));
base::ResetAndReturn(&done_cb).Run();
}
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 0a6bae1d3c8..f808ebb3fd7 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
@@ -37,11 +37,23 @@ class MockDeviceFactory : public video_capture::mojom::DeviceFactory {
DoGetDeviceInfos(callback);
}
+ void AddVirtualDevice(const media::VideoCaptureDeviceInfo& device_info,
+ video_capture::mojom::ProducerPtr producer,
+ video_capture::mojom::VirtualDeviceRequest
+ virtual_device_request) override {
+ DoAddVirtualDevice(device_info, producer.get(), &virtual_device_request);
+ }
+
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::VirtualDeviceRequest* virtual_device_request));
};
class MockVideoCaptureDeviceLauncherCallbacks
@@ -66,9 +78,9 @@ class ServiceVideoCaptureDeviceLauncherTest : public testing::Test {
protected:
void SetUp() override {
factory_binding_ =
- base::MakeUnique<mojo::Binding<video_capture::mojom::DeviceFactory>>(
+ std::make_unique<mojo::Binding<video_capture::mojom::DeviceFactory>>(
&mock_device_factory_, mojo::MakeRequest(&device_factory_));
- launcher_ = base::MakeUnique<ServiceVideoCaptureDeviceLauncher>(
+ launcher_ = std::make_unique<ServiceVideoCaptureDeviceLauncher>(
connect_to_device_factory_cb_.Get());
launcher_has_connected_to_device_factory_ = false;
launcher_has_released_device_factory_ = false;
@@ -77,7 +89,7 @@ class ServiceVideoCaptureDeviceLauncherTest : public testing::Test {
.WillByDefault(Invoke(
[this](std::unique_ptr<VideoCaptureFactoryDelegate>* out_factory) {
launcher_has_connected_to_device_factory_ = true;
- *out_factory = base::MakeUnique<VideoCaptureFactoryDelegate>(
+ *out_factory = std::make_unique<VideoCaptureFactoryDelegate>(
&device_factory_, release_connection_cb_.Get());
}));
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 df1404744ba..b837db09e2d 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
@@ -42,7 +42,7 @@ namespace content {
ServiceVideoCaptureProvider::ServiceVideoCaptureProvider(
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb)
- : ServiceVideoCaptureProvider(base::MakeUnique<ServiceConnectorImpl>(),
+ : ServiceVideoCaptureProvider(std::make_unique<ServiceConnectorImpl>(),
std::move(emit_log_message_cb)) {}
ServiceVideoCaptureProvider::ServiceVideoCaptureProvider(
@@ -79,7 +79,7 @@ void ServiceVideoCaptureProvider::GetDeviceInfosAsync(
std::unique_ptr<VideoCaptureDeviceLauncher>
ServiceVideoCaptureProvider::CreateDeviceLauncher() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return base::MakeUnique<ServiceVideoCaptureDeviceLauncher>(
+ return std::make_unique<ServiceVideoCaptureDeviceLauncher>(
base::BindRepeating(&ServiceVideoCaptureProvider::ConnectToDeviceFactory,
weak_ptr_factory_.GetWeakPtr()));
}
@@ -90,7 +90,7 @@ void ServiceVideoCaptureProvider::ConnectToDeviceFactory(
IncreaseUsageCount();
LazyConnectToService();
launcher_has_connected_to_device_factory_ = true;
- *out_factory = base::MakeUnique<VideoCaptureFactoryDelegate>(
+ *out_factory = std::make_unique<VideoCaptureFactoryDelegate>(
&device_factory_,
base::BindOnce(&ServiceVideoCaptureProvider::DecreaseUsageCount,
weak_ptr_factory_.GetWeakPtr()));
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 c5347f15a7a..1197fcb2350 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
@@ -58,12 +58,23 @@ class MockDeviceFactory : public video_capture::mojom::DeviceFactory {
CreateDeviceCallback callback) override {
DoCreateDevice(device_id, &device_request, callback);
}
+ void AddVirtualDevice(const media::VideoCaptureDeviceInfo& device_info,
+ video_capture::mojom::ProducerPtr producer,
+ video_capture::mojom::VirtualDeviceRequest
+ virtual_device_request) override {
+ DoAddVirtualDevice(device_info, producer.get(), &virtual_device_request);
+ }
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::VirtualDeviceRequest* virtual_device_request));
};
class MockVideoCaptureDeviceLauncherCallbacks
@@ -89,9 +100,9 @@ class ServiceVideoCaptureProviderTest : public testing::Test {
protected:
void SetUp() override {
- auto mock_service_connector = base::MakeUnique<MockServiceConnector>();
+ auto mock_service_connector = std::make_unique<MockServiceConnector>();
mock_service_connector_ = mock_service_connector.get();
- provider_ = base::MakeUnique<ServiceVideoCaptureProvider>(
+ provider_ = std::make_unique<ServiceVideoCaptureProvider>(
std::move(mock_service_connector), kIgnoreLogMessageCB);
ON_CALL(*mock_service_connector_, BindFactoryProvider(_))
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 8ca0ad0af59..cc5ff45d09e 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc
@@ -4,6 +4,7 @@
#include "base/command_line.h"
#include "base/run_loop.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"
@@ -110,7 +111,15 @@ class VideoCaptureBrowserTest : public ContentBrowserTest,
ExerciseAcceleratedJpegDecoding,
UseMojoService>> {
public:
- VideoCaptureBrowserTest() { params_ = TestParams(GetParam()); }
+ VideoCaptureBrowserTest() {
+ params_ = TestParams(GetParam());
+ if (params_.use_mojo_service) {
+ scoped_feature_list_.InitAndEnableFeature(
+ video_capture::kMojoVideoCapture);
+ }
+ }
+
+ ~VideoCaptureBrowserTest() override {}
void SetUpAndStartCaptureDeviceOnIOThread(base::Closure continuation) {
video_capture_manager_ = media_stream_manager_->video_capture_manager();
@@ -158,10 +167,6 @@ class VideoCaptureBrowserTest : public ContentBrowserTest,
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisableAcceleratedMjpegDecode);
}
- if (params_.use_mojo_service) {
- base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
- switches::kEnableFeatures, video_capture::kMojoVideoCapture.name);
- }
}
// This cannot be part of an override of SetUp(), because at the time when
@@ -204,6 +209,8 @@ class VideoCaptureBrowserTest : public ContentBrowserTest,
}
protected:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
TestParams params_;
MediaStreamManager* media_stream_manager_ = nullptr;
VideoCaptureManager* video_capture_manager_ = nullptr;
@@ -212,6 +219,9 @@ class VideoCaptureBrowserTest : public ContentBrowserTest,
MockMediaStreamProviderListener mock_stream_provider_listener_;
MockVideoCaptureControllerEventHandler mock_controller_event_handler_;
base::WeakPtr<VideoCaptureController> controller_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VideoCaptureBrowserTest);
};
IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, StartAndImmediatelyStop) {
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 110a071006b..3b324aae45b 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
@@ -72,7 +72,7 @@ class VideoCaptureBufferPoolTest
VideoCaptureBufferPoolTest()
: expected_dropped_id_(0),
pool_(new media::VideoCaptureBufferPoolImpl(
- base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(),
+ std::make_unique<media::VideoCaptureBufferTrackerFactoryImpl>(),
kTestBufferPoolSize)) {}
void ExpectDroppedId(int expected_dropped_id) {
@@ -276,7 +276,7 @@ TEST_P(VideoCaptureBufferPoolTest, BufferPool) {
// the lifetime of the underlying memory.
buffer3.reset();
ASSERT_EQ(2.0 / kTestBufferPoolSize, pool_->GetBufferPoolUtilization());
- pool_ = NULL;
+ pool_ = nullptr;
// Touch the memory.
if (buffer2->data() != nullptr)
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 e9fb72a2656..97dcb2edf94 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_controller.cc
@@ -235,7 +235,7 @@ void VideoCaptureController::AddClient(
event_handler->OnStarted(id);
std::unique_ptr<ControllerClient> client =
- base::MakeUnique<ControllerClient>(id, event_handler, session_id, params);
+ std::make_unique<ControllerClient>(id, event_handler, session_id, params);
// If we already have gotten frame_info from the device, repeat it to the new
// client.
if (state_ != VIDEO_CAPTURE_STATE_ERROR) {
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 fd9e24fb4ca..3ef19257ca1 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
@@ -47,7 +47,7 @@ namespace content {
std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb) {
- return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(
+ return std::make_unique<content::VideoCaptureGpuJpegDecoder>(
std::move(decode_done_cb), base::Bind([](const std::string&) {}));
}
@@ -138,14 +138,14 @@ class VideoCaptureControllerTest
const MediaStreamType arbitrary_stream_type =
content::MEDIA_DEVICE_VIDEO_CAPTURE;
const media::VideoCaptureParams arbitrary_params;
- auto device_launcher = base::MakeUnique<MockVideoCaptureDeviceLauncher>();
+ auto device_launcher = std::make_unique<MockVideoCaptureDeviceLauncher>();
controller_ = new VideoCaptureController(
arbitrary_device_id, arbitrary_stream_type, arbitrary_params,
std::move(device_launcher),
base::BindRepeating([](const std::string&) {}));
InitializeNewDeviceClientAndBufferPoolInstances();
auto mock_launched_device =
- base::MakeUnique<MockLaunchedVideoCaptureDevice>();
+ std::make_unique<MockLaunchedVideoCaptureDevice>();
mock_launched_device_ = mock_launched_device.get();
controller_->OnDeviceLaunched(std::move(mock_launched_device));
client_a_.reset(
@@ -158,10 +158,10 @@ class VideoCaptureControllerTest
void InitializeNewDeviceClientAndBufferPoolInstances() {
buffer_pool_ = new media::VideoCaptureBufferPoolImpl(
- base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(),
+ std::make_unique<media::VideoCaptureBufferTrackerFactoryImpl>(),
kPoolSize);
device_client_.reset(new media::VideoCaptureDeviceClient(
- base::MakeUnique<media::VideoFrameReceiverOnTaskRunner>(
+ std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
controller_->GetWeakPtrForIOThread(),
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)),
buffer_pool_,
diff --git a/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc b/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
index 34afec23bfe..f351ccfd153 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
@@ -10,8 +10,8 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
-#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
+#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
@@ -19,11 +19,11 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
-#include "gpu/ipc/client/gpu_channel_host.h"
+#include "media/base/bind_to_current_loop.h"
#include "media/base/media_switches.h"
#include "media/base/video_frame.h"
-#include "media/gpu/ipc/client/gpu_jpeg_decode_accelerator_host.h"
#include "mojo/public/cpp/system/platform_handle.h"
+#include "services/ui/public/cpp/gpu/gpu.h"
namespace content {
@@ -35,18 +35,26 @@ VideoCaptureGpuJpegDecoder::VideoCaptureGpuJpegDecoder(
has_received_decoded_frame_(false),
next_bitstream_buffer_id_(0),
in_buffer_id_(media::JpegDecodeAccelerator::kInvalidBitstreamBufferId),
- decoder_status_(INIT_PENDING) {}
+ decoder_status_(INIT_PENDING),
+ weak_ptr_factory_(this) {}
VideoCaptureGpuJpegDecoder::~VideoCaptureGpuJpegDecoder() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // |decoder_| guarantees no more JpegDecodeAccelerator::Client callbacks
- // on IO thread after deletion.
- decoder_.reset();
-
- // |gpu_channel_host_| should outlive |decoder_|, so |gpu_channel_host_|
- // must be released after |decoder_| has been destroyed.
- gpu_channel_host_ = nullptr;
+ // |this| was set as |decoder_|'s client. |decoder_| has to be deleted before
+ // this destructor returns to ensure that it doesn't call back into its
+ // client. Hence, we wait here while we delete |decoder_| on the IO thread.
+ if (decoder_) {
+ base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ // base::Unretained is safe because |this| will be valid until |event|
+ // is signaled.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&VideoCaptureGpuJpegDecoder::DestroyDecoderOnIOThread,
+ base::Unretained(this), &event));
+ event.Wait();
+ }
}
void VideoCaptureGpuJpegDecoder::Initialize() {
@@ -70,11 +78,10 @@ void VideoCaptureGpuJpegDecoder::Initialize() {
return;
}
- const scoped_refptr<base::SingleThreadTaskRunner> current_task_runner(
- base::ThreadTaskRunnerHandle::Get());
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&EstablishGpuChannelOnUIThread,
- current_task_runner, AsWeakPtr()));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&RequestGPUInfoOnIOThread, base::ThreadTaskRunnerHandle::Get(),
+ weak_ptr_factory_.GetWeakPtr()));
}
VideoCaptureGpuJpegDecoder::STATUS VideoCaptureGpuJpegDecoder::GetStatus()
@@ -180,7 +187,12 @@ void VideoCaptureGpuJpegDecoder::DecodeCapturedData(
base::Passed(&out_buffer.access_permission),
base::Passed(&out_frame_info));
}
- decoder_->Decode(in_buffer, std::move(out_frame));
+
+ // base::Unretained is safe because |decoder_| is deleted on the IO thread.
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&media::JpegDecodeAccelerator::Decode,
+ base::Unretained(decoder_.get()),
+ in_buffer, std::move(out_frame)));
}
void VideoCaptureGpuJpegDecoder::VideoFrameReady(int32_t bitstream_buffer_id) {
@@ -247,61 +259,59 @@ void VideoCaptureGpuJpegDecoder::DidReceiveGPUInfoOnIOThread(
base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this,
const gpu::GPUInfo& gpu_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // TODO(c.padhi): Implement this, see http://crbug.com/699255.
- NOTIMPLEMENTED();
-}
-
-// static
-void VideoCaptureGpuJpegDecoder::EstablishGpuChannelOnUIThread(
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserMainLoop::GetInstance()
- ->gpu_channel_establish_factory()
- ->EstablishGpuChannel(base::Bind(
- &VideoCaptureGpuJpegDecoder::GpuChannelEstablishedOnUIThread,
- task_runner, weak_this));
-}
+ media::mojom::JpegDecodeAcceleratorPtr remote_decoder;
-// static
-void VideoCaptureGpuJpegDecoder::GpuChannelEstablishedOnUIThread(
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this,
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (gpu_info.jpeg_decode_accelerator_supported) {
+ GpuProcessHost* host =
+ GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false);
+ if (host) {
+ host->gpu_service()->CreateJpegDecodeAccelerator(
+ mojo::MakeRequest(&remote_decoder));
+ }
+ }
task_runner->PostTask(
FROM_HERE,
- base::BindOnce(&VideoCaptureGpuJpegDecoder::FinishInitialization,
- weak_this, std::move(gpu_channel_host)));
+ base::Bind(&VideoCaptureGpuJpegDecoder::FinishInitialization, weak_this,
+ base::Passed(remote_decoder.PassInterface())));
}
void VideoCaptureGpuJpegDecoder::FinishInitialization(
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
+ media::mojom::JpegDecodeAcceleratorPtrInfo unbound_remote_decoder) {
TRACE_EVENT0("gpu", "VideoCaptureGpuJpegDecoder::FinishInitialization");
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (unbound_remote_decoder.is_valid()) {
+ base::AutoLock lock(lock_);
+ decoder_ = base::MakeUnique<media::MojoJpegDecodeAccelerator>(
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ std::move(unbound_remote_decoder));
+
+ // base::Unretained is safe because |decoder_| is deleted on the IO thread.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&media::JpegDecodeAccelerator::InitializeAsync,
+ base::Unretained(decoder_.get()), this,
+ media::BindToCurrentLoop(base::Bind(
+ &VideoCaptureGpuJpegDecoder::OnInitializationDone,
+ weak_ptr_factory_.GetWeakPtr()))));
+ } else {
+ OnInitializationDone(false);
+ }
+}
+
+void VideoCaptureGpuJpegDecoder::OnInitializationDone(bool success) {
+ TRACE_EVENT0("gpu", "VideoCaptureGpuJpegDecoder::OnInitializationDone");
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
base::AutoLock lock(lock_);
- if (!gpu_channel_host) {
- LOG(ERROR) << "Failed to establish GPU channel for JPEG decoder";
- } else if (gpu_channel_host->gpu_info().jpeg_decode_accelerator_supported) {
- gpu_channel_host_ = std::move(gpu_channel_host);
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
-
- int32_t route_id = gpu_channel_host_->GenerateRouteID();
- std::unique_ptr<media::GpuJpegDecodeAcceleratorHost> decoder(
- new media::GpuJpegDecodeAcceleratorHost(gpu_channel_host_.get(),
- route_id, io_task_runner));
- if (decoder->Initialize(this)) {
- gpu_channel_host_->AddRouteWithTaskRunner(
- route_id, decoder->GetReceiver(), io_task_runner);
- decoder_ = std::move(decoder);
- } else {
- DLOG(ERROR) << "Failed to initialize JPEG decoder";
- }
+ if (!success) {
+ BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, decoder_.release());
+ DLOG(ERROR) << "Failed to initialize JPEG decoder";
}
- decoder_status_ = decoder_ ? INIT_PASSED : FAILED;
+
+ decoder_status_ = success ? INIT_PASSED : FAILED;
RecordInitDecodeUMA_Locked();
}
@@ -315,4 +325,11 @@ void VideoCaptureGpuJpegDecoder::RecordInitDecodeUMA_Locked() {
decoder_status_ == INIT_PASSED);
}
+void VideoCaptureGpuJpegDecoder::DestroyDecoderOnIOThread(
+ base::WaitableEvent* event) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ decoder_.reset();
+ event->Signal();
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h b/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h
index 3d0201d51f8..bf089ba6e83 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h
+++ b/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h
@@ -13,18 +13,15 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread.h"
#include "content/common/content_export.h"
#include "gpu/config/gpu_info.h"
#include "media/capture/video/video_capture_jpeg_decoder.h"
-#include "media/video/jpeg_decode_accelerator.h"
+#include "media/mojo/clients/mojo_jpeg_decode_accelerator.h"
-namespace gpu {
-class GpuChannelHost;
+namespace base {
+class WaitableEvent;
}
namespace content {
@@ -38,10 +35,9 @@ namespace content {
// the IO thread.
class CONTENT_EXPORT VideoCaptureGpuJpegDecoder
: public media::VideoCaptureJpegDecoder,
- public media::JpegDecodeAccelerator::Client,
- public base::SupportsWeakPtr<VideoCaptureGpuJpegDecoder> {
+ public media::JpegDecodeAccelerator::Client {
public:
- // |decode_done_cb| is called on the IO thread when decode succeed. This can
+ // |decode_done_cb| is called on the IO thread when decode succeeds. This can
// be on any thread. |decode_done_cb| is never called after
// VideoCaptureGpuJpegDecoder is destroyed.
VideoCaptureGpuJpegDecoder(
@@ -76,18 +72,9 @@ class CONTENT_EXPORT VideoCaptureGpuJpegDecoder
base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this,
const gpu::GPUInfo& gpu_info);
- // Initialization helper, to establish GPU channel.
- static void EstablishGpuChannelOnUIThread(
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this);
-
- static void GpuChannelEstablishedOnUIThread(
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this,
- scoped_refptr<gpu::GpuChannelHost> established_channel_host);
-
void FinishInitialization(
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host);
+ media::mojom::JpegDecodeAcceleratorPtrInfo unbound_remote_decoder);
+ void OnInitializationDone(bool success);
// Returns true if the decoding of last frame is not finished yet.
bool IsDecoding_Locked() const;
@@ -95,7 +82,7 @@ class CONTENT_EXPORT VideoCaptureGpuJpegDecoder
// Records |decoder_status_| to histogram.
void RecordInitDecodeUMA_Locked();
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host_;
+ void DestroyDecoderOnIOThread(base::WaitableEvent* event);
// The underlying JPEG decode accelerator.
std::unique_ptr<media::JpegDecodeAccelerator> decoder_;
@@ -126,6 +113,8 @@ class CONTENT_EXPORT VideoCaptureGpuJpegDecoder
SEQUENCE_CHECKER(sequence_checker_);
+ base::WeakPtrFactory<VideoCaptureGpuJpegDecoder> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(VideoCaptureGpuJpegDecoder);
};
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 da26a5c4694..d437d3c1dfa 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_host.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_host.cc
@@ -81,7 +81,7 @@ void VideoCaptureHost::Create(int render_process_id,
mojom::VideoCaptureHostRequest request) {
DVLOG(1) << __func__;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- mojo::MakeStrongBinding(base::MakeUnique<VideoCaptureHost>(
+ mojo::MakeStrongBinding(std::make_unique<VideoCaptureHost>(
render_process_id, media_stream_manager),
std::move(request));
}
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 582b3881bc5..7e0186adfef 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
@@ -106,7 +106,7 @@ class WrappedDeviceFactory : public media::FakeVideoCaptureDeviceFactory {
std::unique_ptr<media::VideoCaptureDevice> CreateDevice(
const media::VideoCaptureDeviceDescriptor& device_descriptor) final {
- return base::MakeUnique<WrappedDevice>(
+ return std::make_unique<WrappedDevice>(
FakeVideoCaptureDeviceFactory::CreateDevice(device_descriptor), this);
}
@@ -201,12 +201,12 @@ class VideoCaptureManagerTest : public testing::Test {
void SetUp() override {
listener_.reset(new MockMediaStreamProviderListener());
auto video_capture_device_factory =
- base::MakeUnique<WrappedDeviceFactory>();
+ std::make_unique<WrappedDeviceFactory>();
video_capture_device_factory_ = video_capture_device_factory.get();
- auto video_capture_system = base::MakeUnique<media::VideoCaptureSystemImpl>(
+ auto video_capture_system = std::make_unique<media::VideoCaptureSystemImpl>(
std::move(video_capture_device_factory));
auto video_capture_provider =
- base::MakeUnique<InProcessVideoCaptureProvider>(
+ std::make_unique<InProcessVideoCaptureProvider>(
std::move(video_capture_system),
base::ThreadTaskRunnerHandle::Get(), kIgnoreLogMessageCB);
vcm_ =
diff --git a/chromium/content/browser/renderer_host/media/video_capture_provider_switcher.cc b/chromium/content/browser/renderer_host/media/video_capture_provider_switcher.cc
index 26e91d9b0e8..d1b8b74f9f8 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_provider_switcher.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_provider_switcher.cc
@@ -77,7 +77,7 @@ void VideoCaptureProviderSwitcher::GetDeviceInfosAsync(
std::unique_ptr<VideoCaptureDeviceLauncher>
VideoCaptureProviderSwitcher::CreateDeviceLauncher() {
- return base::MakeUnique<VideoCaptureDeviceLauncherSwitcher>(
+ return std::make_unique<VideoCaptureDeviceLauncherSwitcher>(
media_device_capture_provider_->CreateDeviceLauncher(),
other_types_capture_provider_->CreateDeviceLauncher());
}
diff --git a/chromium/content/browser/renderer_host/media/video_capture_unittest.cc b/chromium/content/browser/renderer_host/media/video_capture_unittest.cc
index 65540b1a47a..7759d7330ae 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_unittest.cc
@@ -19,8 +19,9 @@
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
+#include "content/browser/renderer_host/media/fake_video_capture_provider.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
-#include "content/browser/renderer_host/media/media_stream_requester.h"
+#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "content/browser/renderer_host/media/video_capture_host.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/common/media/media_devices.h"
@@ -71,38 +72,6 @@ void VideoInputDevicesEnumerated(base::Closure quit_closure,
// video_capture_host. This is an arbitrary value.
static const int kDeviceId = 555;
-class MockMediaStreamRequester
- : public MediaStreamRequester,
- public base::SupportsWeakPtr<MockMediaStreamRequester> {
- public:
- MockMediaStreamRequester() {}
- virtual ~MockMediaStreamRequester() {}
-
- // MediaStreamRequester implementation.
- MOCK_METHOD5(StreamGenerated,
- void(int render_frame_id,
- int page_request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices));
- MOCK_METHOD3(StreamGenerationFailed,
- void(int render_frame_id,
- int page_request_id,
- content::MediaStreamRequestResult result));
- MOCK_METHOD3(DeviceStopped,
- void(int render_frame_id,
- const std::string& label,
- const MediaStreamDevice& device));
- MOCK_METHOD4(DeviceOpened,
- void(int render_frame_id,
- int page_request_id,
- const std::string& label,
- const MediaStreamDevice& device));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockMediaStreamRequester);
-};
-
ACTION_P2(ExitMessageLoop, task_runner, quit_closure) {
task_runner->PostTask(FROM_HERE, quit_closure);
}
@@ -127,12 +96,11 @@ class VideoCaptureTest : public testing::Test,
void SetUp() override {
SetBrowserClientForTesting(&browser_client_);
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kUseFakeDeviceForMediaStream);
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kUseFakeUIForMediaStream);
- media_stream_manager_ = base::MakeUnique<MediaStreamManager>(
- audio_system_.get(), audio_manager_->GetTaskRunner());
+ media_stream_manager_ = std::make_unique<MediaStreamManager>(
+ audio_system_.get(), audio_manager_->GetTaskRunner(),
+ base::MakeUnique<FakeVideoCaptureProvider>());
+ media_stream_manager_->UseFakeUIFactoryForTests(
+ base::Bind(&VideoCaptureTest::CreateFakeUI, base::Unretained(this)));
// Create a Host and connect it to a simulated IPC channel.
host_.reset(new VideoCaptureHost(0 /* render_process_id */,
@@ -156,7 +124,8 @@ class VideoCaptureTest : public testing::Test,
const int render_process_id = 1;
const int render_frame_id = 1;
const int page_request_id = 1;
- const url::Origin security_origin(GURL("http://test.com"));
+ const url::Origin security_origin =
+ url::Origin::Create(GURL("http://test.com"));
ASSERT_TRUE(opened_device_label_.empty());
@@ -178,23 +147,17 @@ class VideoCaptureTest : public testing::Test,
// Open the first device.
{
base::RunLoop run_loop;
- MediaStreamDevice opened_device;
media_stream_manager_->OpenDevice(
- stream_requester_.AsWeakPtr(), render_process_id, render_frame_id,
+ render_process_id, render_frame_id,
browser_context_.GetMediaDeviceIDSalt(), page_request_id,
video_devices[0].device_id, MEDIA_DEVICE_VIDEO_CAPTURE,
- security_origin);
- EXPECT_CALL(stream_requester_,
- DeviceOpened(render_frame_id, page_request_id, _, _))
- .Times(1)
- .WillOnce(DoAll(ExitMessageLoop(task_runner_, run_loop.QuitClosure()),
- SaveArg<2>(&opened_device_label_),
- SaveArg<3>(&opened_device)));
+ security_origin,
+ base::BindOnce(&VideoCaptureTest::OnDeviceOpened,
+ base::Unretained(this), run_loop.QuitClosure()),
+ MediaStreamManager::DeviceStoppedCallback());
run_loop.Run();
- Mock::VerifyAndClearExpectations(&stream_requester_);
- ASSERT_NE(MediaStreamDevice::kNoId, opened_device.session_id);
- opened_session_id_ = opened_device.session_id;
}
+ ASSERT_NE(MediaStreamDevice::kNoId, opened_session_id_);
}
void CloseSession() {
@@ -310,9 +273,24 @@ class VideoCaptureTest : public testing::Test,
}
private:
+ std::unique_ptr<FakeMediaStreamUIProxy> CreateFakeUI() {
+ return std::make_unique<FakeMediaStreamUIProxy>(
+ /*tests_use_fake_render_frame_hosts=*/true);
+ }
+
+ void OnDeviceOpened(base::Closure quit_closure,
+ bool success,
+ const std::string& label,
+ const MediaStreamDevice& opened_device) {
+ if (success) {
+ opened_device_label_ = label;
+ opened_session_id_ = opened_device.session_id;
+ }
+ quit_closure.Run();
+ }
+
// |media_stream_manager_| needs to outlive |thread_bundle_| because it is a
// MessageLoop::DestructionObserver.
- StrictMock<MockMediaStreamRequester> stream_requester_;
std::unique_ptr<MediaStreamManager> media_stream_manager_;
const content::TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<media::AudioManager> audio_manager_;
diff --git a/chromium/content/browser/renderer_host/offscreen_canvas_provider_impl.cc b/chromium/content/browser/renderer_host/offscreen_canvas_provider_impl.cc
index 279340bc2e5..6169a95d3e3 100644
--- a/chromium/content/browser/renderer_host/offscreen_canvas_provider_impl.cc
+++ b/chromium/content/browser/renderer_host/offscreen_canvas_provider_impl.cc
@@ -41,7 +41,7 @@ void OffscreenCanvasProviderImpl::CreateOffscreenCanvasSurface(
&OffscreenCanvasProviderImpl::DestroyOffscreenCanvasSurface,
base::Unretained(this), frame_sink_id);
- canvas_map_[frame_sink_id] = base::MakeUnique<OffscreenCanvasSurfaceImpl>(
+ canvas_map_[frame_sink_id] = std::make_unique<OffscreenCanvasSurfaceImpl>(
host_frame_sink_manager_, parent_frame_sink_id, frame_sink_id,
std::move(client), std::move(request), std::move(destroy_callback));
}
diff --git a/chromium/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc b/chromium/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc
index dce298183f0..fdc8db66281 100644
--- a/chromium/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc
+++ b/chromium/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc
@@ -12,8 +12,11 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "components/viz/common/quads/compositor_frame.h"
+#include "components/viz/host/host_frame_sink_manager.h"
+#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
+#include "components/viz/test/fake_host_frame_sink_client.h"
+#include "components/viz/test/mock_compositor_frame_sink_client.h"
#include "content/browser/compositor/surface_utils.h"
-#include "content/browser/compositor/test/no_transport_image_transport_factory.h"
#include "content/browser/renderer_host/offscreen_canvas_surface_impl.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -65,33 +68,6 @@ class StubOffscreenCanvasSurfaceClient
DISALLOW_COPY_AND_ASSIGN(StubOffscreenCanvasSurfaceClient);
};
-// Stub CompositorFrameSinkClient that does nothing.
-class StubCompositorFrameSinkClient
- : public viz::mojom::CompositorFrameSinkClient {
- public:
- StubCompositorFrameSinkClient() : binding_(this) {}
- ~StubCompositorFrameSinkClient() override {}
-
- viz::mojom::CompositorFrameSinkClientPtr GetInterfacePtr() {
- viz::mojom::CompositorFrameSinkClientPtr client;
- binding_.Bind(mojo::MakeRequest(&client));
- return client;
- }
-
- private:
- // viz::mojom::CompositorFrameSinkClient:
- void DidReceiveCompositorFrameAck(
- const std::vector<viz::ReturnedResource>& resources) override {}
- void OnBeginFrame(const viz::BeginFrameArgs& begin_frame_args) override {}
- void OnBeginFramePausedChanged(bool paused) override {}
- void ReclaimResources(
- const std::vector<viz::ReturnedResource>& resources) override {}
-
- mojo::Binding<viz::mojom::CompositorFrameSinkClient> binding_;
-
- DISALLOW_COPY_AND_ASSIGN(StubCompositorFrameSinkClient);
-};
-
// Create a CompositorFrame suitable to send over IPC.
viz::CompositorFrame MakeCompositorFrame() {
viz::CompositorFrame frame;
@@ -146,33 +122,30 @@ class OffscreenCanvasProviderImplTest : public testing::Test {
protected:
void SetUp() override {
-#if !defined(OS_ANDROID)
- ImageTransportFactory::SetFactory(
- std::make_unique<NoTransportImageTransportFactory>());
-#endif
- host_frame_sink_manager_ = base::MakeUnique<viz::HostFrameSinkManager>();
+ host_frame_sink_manager_ = std::make_unique<viz::HostFrameSinkManager>();
// The FrameSinkManagerImpl implementation is in-process here for tests.
- frame_sink_manager_ = base::MakeUnique<viz::FrameSinkManagerImpl>();
+ frame_sink_manager_ = std::make_unique<viz::FrameSinkManagerImpl>();
surface_utils::ConnectWithLocalFrameSinkManager(
host_frame_sink_manager_.get(), frame_sink_manager_.get());
- provider_ = base::MakeUnique<OffscreenCanvasProviderImpl>(
+ provider_ = std::make_unique<OffscreenCanvasProviderImpl>(
host_frame_sink_manager_.get(), kRendererClientId);
+
+ host_frame_sink_manager_->RegisterFrameSinkId(kFrameSinkParent,
+ &host_frame_sink_client_);
}
void TearDown() override {
provider_.reset();
frame_sink_manager_.reset();
host_frame_sink_manager_.reset();
-#if !defined(OS_ANDROID)
- ImageTransportFactory::Terminate();
-#endif
}
private:
// A MessageLoop is required for mojo bindings which are used to
// connect to graphics services.
base::MessageLoop message_loop_;
+ viz::FakeHostFrameSinkClient host_frame_sink_client_;
std::unique_ptr<viz::HostFrameSinkManager> host_frame_sink_manager_;
std::unique_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_;
std::unique_ptr<OffscreenCanvasProviderImpl> provider_;
@@ -199,9 +172,9 @@ TEST_F(OffscreenCanvasProviderImplTest,
// Mimic connection from the renderer main or worker thread to browser.
viz::mojom::CompositorFrameSinkPtr compositor_frame_sink;
- StubCompositorFrameSinkClient compositor_frame_sink_client;
+ viz::MockCompositorFrameSinkClient compositor_frame_sink_client;
provider()->CreateCompositorFrameSink(
- kFrameSinkA, compositor_frame_sink_client.GetInterfacePtr(),
+ kFrameSinkA, compositor_frame_sink_client.BindInterfacePtr(),
mojo::MakeRequest(&compositor_frame_sink));
// Renderer submits a CompositorFrame with |local_id|.
@@ -282,11 +255,11 @@ TEST_F(OffscreenCanvasProviderImplTest, ProviderClosesConnections) {
TEST_F(OffscreenCanvasProviderImplTest, ClientConnectionWrongOrder) {
// Mimic connection from the renderer main or worker thread.
viz::mojom::CompositorFrameSinkPtr compositor_frame_sink;
- StubCompositorFrameSinkClient compositor_frame_sink_client;
+ viz::MockCompositorFrameSinkClient compositor_frame_sink_client;
// Try to connect CompositorFrameSink without first making
// OffscreenCanvasSurface connection. This should fail.
provider()->CreateCompositorFrameSink(
- kFrameSinkA, compositor_frame_sink_client.GetInterfacePtr(),
+ kFrameSinkA, compositor_frame_sink_client.BindInterfacePtr(),
mojo::MakeRequest(&compositor_frame_sink));
// Observe connection errors on |compositor_frame_sink|.
diff --git a/chromium/content/browser/renderer_host/offscreen_canvas_surface_impl.cc b/chromium/content/browser/renderer_host/offscreen_canvas_surface_impl.cc
index a60a65ad832..ad3a74465d8 100644
--- a/chromium/content/browser/renderer_host/offscreen_canvas_surface_impl.cc
+++ b/chromium/content/browser/renderer_host/offscreen_canvas_surface_impl.cc
@@ -71,6 +71,11 @@ void OffscreenCanvasSurfaceImpl::OnFirstSurfaceActivation(
client_->OnFirstSurfaceActivation(surface_info);
}
+void OffscreenCanvasSurfaceImpl::OnFrameTokenChanged(uint32_t frame_token) {
+ // TODO(yiyix, fsamuel): To complete plumbing of frame tokens for offscreen
+ // canvas
+}
+
void OffscreenCanvasSurfaceImpl::Require(const viz::SurfaceId& surface_id,
const viz::SurfaceSequence& sequence) {
auto* surface_manager = GetFrameSinkManager()->surface_manager();
diff --git a/chromium/content/browser/renderer_host/offscreen_canvas_surface_impl.h b/chromium/content/browser/renderer_host/offscreen_canvas_surface_impl.h
index 93e5be1a399..b906ed61d18 100644
--- a/chromium/content/browser/renderer_host/offscreen_canvas_surface_impl.h
+++ b/chromium/content/browser/renderer_host/offscreen_canvas_surface_impl.h
@@ -54,6 +54,7 @@ class CONTENT_EXPORT OffscreenCanvasSurfaceImpl
// viz::HostFrameSinkClient implementation.
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
+ void OnFrameTokenChanged(uint32_t frame_token) override;
// blink::mojom::OffscreenCanvasSurface implementation.
void Require(const viz::SurfaceId& surface_id,
diff --git a/chromium/content/browser/renderer_host/overscroll_configuration.cc b/chromium/content/browser/renderer_host/overscroll_configuration.cc
index 80f975bcdd2..b7544655380 100644
--- a/chromium/content/browser/renderer_host/overscroll_configuration.cc
+++ b/chromium/content/browser/renderer_host/overscroll_configuration.cc
@@ -11,26 +11,25 @@
namespace {
-const float kHorizThresholdComplete = 0.25f;
-const float kVertThresholdComplete = 0.20f;
+const float kThresholdCompleteTouchpad = 0.3f;
+const float kThresholdCompleteTouchscreen = 0.25f;
-const float kHorizThresholdStartTouchscreen = 50.f;
-const float kHorizThresholdStartTouchpad = 50.f;
-const float kVertThresholdStart = 50.f;
+const float kThresholdStartTouchpad = 60.f;
+const float kThresholdStartTouchscreen = 50.f;
-float GetHorizontalStartThresholdMultiplier() {
+float GetStartThresholdMultiplier() {
base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
if (!cmd->HasSwitch(switches::kOverscrollStartThreshold))
return 1.f;
+
std::string string_value =
cmd->GetSwitchValueASCII(switches::kOverscrollStartThreshold);
int percentage;
- if (base::StringToInt(string_value, &percentage) && percentage > 0) {
+ if (base::StringToInt(string_value, &percentage) && percentage > 0)
return percentage / 100.f;
- }
DLOG(WARNING) << "Failed to parse switch "
- << switches::kOverscrollStartThreshold << ": " << string_value;
+ << switches::kOverscrollStartThreshold << ": " << string_value;
return 1.f;
}
@@ -40,31 +39,24 @@ namespace content {
float GetOverscrollConfig(OverscrollConfig config) {
switch (config) {
- case OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE:
- return kHorizThresholdComplete;
-
- case OVERSCROLL_CONFIG_VERT_THRESHOLD_COMPLETE:
- return kVertThresholdComplete;
-
- case OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN:
- static const float horiz_threshold_start_touchscreen =
- GetHorizontalStartThresholdMultiplier() *
- kHorizThresholdStartTouchscreen;
- return horiz_threshold_start_touchscreen;
+ case OverscrollConfig::THRESHOLD_COMPLETE_TOUCHPAD:
+ return kThresholdCompleteTouchpad;
- case OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHPAD:
- static const float horiz_threshold_start_touchpad =
- GetHorizontalStartThresholdMultiplier() *
- kHorizThresholdStartTouchpad;
- return horiz_threshold_start_touchpad;
+ case OverscrollConfig::THRESHOLD_COMPLETE_TOUCHSCREEN:
+ return kThresholdCompleteTouchscreen;
- case OVERSCROLL_CONFIG_VERT_THRESHOLD_START:
- return kVertThresholdStart;
+ case OverscrollConfig::THRESHOLD_START_TOUCHPAD:
+ static const float threshold_start_touchpad =
+ GetStartThresholdMultiplier() * kThresholdStartTouchpad;
+ return threshold_start_touchpad;
- case OVERSCROLL_CONFIG_NONE:
- NOTREACHED();
+ case OverscrollConfig::THRESHOLD_START_TOUCHSCREEN:
+ static const float threshold_start_touchscreen =
+ GetStartThresholdMultiplier() * kThresholdStartTouchscreen;
+ return threshold_start_touchscreen;
}
+ NOTREACHED();
return -1.f;
}
diff --git a/chromium/content/browser/renderer_host/overscroll_controller.cc b/chromium/content/browser/renderer_host/overscroll_controller.cc
index ba933016227..3d9b66f0069 100644
--- a/chromium/content/browser/renderer_host/overscroll_controller.cc
+++ b/chromium/content/browser/renderer_host/overscroll_controller.cc
@@ -12,8 +12,6 @@
#include "content/public/browser/overscroll_configuration.h"
#include "content/public/common/content_switches.h"
-using blink::WebInputEvent;
-
namespace content {
namespace {
@@ -185,6 +183,7 @@ bool OverscrollController::DispatchEventCompletesAction (
const blink::WebInputEvent& event) const {
if (overscroll_mode_ == OVERSCROLL_NONE)
return false;
+ DCHECK_NE(OverscrollSource::NONE, overscroll_source_);
// Complete the overscroll gesture if there was a mouse move or a scroll-end
// after the threshold.
@@ -197,7 +196,8 @@ bool OverscrollController::DispatchEventCompletesAction (
// from the touchpad since it is sent based on a timeout not
// when the user has stopped interacting.
if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd &&
- IsGestureEventFromTouchpad(event)) {
+ overscroll_source_ == OverscrollSource::TOUCHPAD) {
+ DCHECK(IsGestureEventFromTouchpad(event));
return false;
}
@@ -234,16 +234,15 @@ bool OverscrollController::DispatchEventCompletesAction (
if (size.IsEmpty())
return false;
- float ratio, threshold;
- if (overscroll_mode_ == OVERSCROLL_WEST ||
- overscroll_mode_ == OVERSCROLL_EAST) {
- ratio = fabs(overscroll_delta_x_) / size.width();
- threshold = GetOverscrollConfig(OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE);
- } else {
- ratio = fabs(overscroll_delta_y_) / size.height();
- threshold = GetOverscrollConfig(OVERSCROLL_CONFIG_VERT_THRESHOLD_COMPLETE);
- }
-
+ const float delta =
+ overscroll_mode_ == OVERSCROLL_WEST || overscroll_mode_ == OVERSCROLL_EAST
+ ? overscroll_delta_x_
+ : overscroll_delta_y_;
+ const float ratio = fabs(delta) / std::max(size.width(), size.height());
+ const float threshold = GetOverscrollConfig(
+ overscroll_source_ == OverscrollSource::TOUCHPAD
+ ? OverscrollConfig::THRESHOLD_COMPLETE_TOUCHPAD
+ : OverscrollConfig::THRESHOLD_COMPLETE_TOUCHSCREEN);
return ratio >= threshold;
}
@@ -352,13 +351,11 @@ bool OverscrollController::ProcessOverscroll(float delta_x,
overscroll_delta_y_ += delta_y;
}
- const float horiz_threshold = GetOverscrollConfig(
- is_touchpad ? OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHPAD
- : OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN);
- const float vert_threshold =
- GetOverscrollConfig(OVERSCROLL_CONFIG_VERT_THRESHOLD_START);
- if (fabs(overscroll_delta_x_) <= horiz_threshold &&
- fabs(overscroll_delta_y_) <= vert_threshold) {
+ const float start_threshold = GetOverscrollConfig(
+ is_touchpad ? OverscrollConfig::THRESHOLD_START_TOUCHPAD
+ : OverscrollConfig::THRESHOLD_START_TOUCHSCREEN);
+ if (fabs(overscroll_delta_x_) <= start_threshold &&
+ fabs(overscroll_delta_y_) <= start_threshold) {
SetOverscrollMode(OVERSCROLL_NONE, OverscrollSource::NONE);
return true;
}
@@ -371,12 +368,12 @@ bool OverscrollController::ProcessOverscroll(float delta_x,
case OVERSCROLL_WEST:
case OVERSCROLL_EAST:
overscroll_delta_x_ = ClampAbsoluteValue(
- overscroll_delta_x_, cap.value() + horiz_threshold);
+ overscroll_delta_x_, cap.value() + start_threshold);
break;
case OVERSCROLL_NORTH:
case OVERSCROLL_SOUTH:
overscroll_delta_y_ = ClampAbsoluteValue(
- overscroll_delta_y_, cap.value() + vert_threshold);
+ overscroll_delta_y_, cap.value() + start_threshold);
break;
case OVERSCROLL_NONE:
break;
@@ -389,10 +386,10 @@ bool OverscrollController::ProcessOverscroll(float delta_x,
// to make sure that subsequent scroll events go through to the page first.
OverscrollMode new_mode = OVERSCROLL_NONE;
const float kMinRatio = 2.5;
- if (fabs(overscroll_delta_x_) > horiz_threshold &&
+ if (fabs(overscroll_delta_x_) > start_threshold &&
fabs(overscroll_delta_x_) > fabs(overscroll_delta_y_) * kMinRatio)
new_mode = overscroll_delta_x_ > 0.f ? OVERSCROLL_EAST : OVERSCROLL_WEST;
- else if (fabs(overscroll_delta_y_) > vert_threshold &&
+ else if (fabs(overscroll_delta_y_) > start_threshold &&
fabs(overscroll_delta_y_) > fabs(overscroll_delta_x_) * kMinRatio)
new_mode = overscroll_delta_y_ > 0.f ? OVERSCROLL_SOUTH : OVERSCROLL_NORTH;
@@ -418,21 +415,21 @@ bool OverscrollController::ProcessOverscroll(float delta_x,
// Do not include the threshold amount when sending the deltas to the
// delegate.
float delegate_delta_x = overscroll_delta_x_;
- if (fabs(delegate_delta_x) > horiz_threshold) {
+ if (fabs(delegate_delta_x) > start_threshold) {
if (delegate_delta_x < 0)
- delegate_delta_x += horiz_threshold;
+ delegate_delta_x += start_threshold;
else
- delegate_delta_x -= horiz_threshold;
+ delegate_delta_x -= start_threshold;
} else {
delegate_delta_x = 0.f;
}
float delegate_delta_y = overscroll_delta_y_;
- if (fabs(delegate_delta_y) > vert_threshold) {
+ if (fabs(delegate_delta_y) > start_threshold) {
if (delegate_delta_y < 0)
- delegate_delta_y += vert_threshold;
+ delegate_delta_y += start_threshold;
else
- delegate_delta_y -= vert_threshold;
+ delegate_delta_y -= start_threshold;
} else {
delegate_delta_y = 0.f;
}
diff --git a/chromium/content/browser/renderer_host/overscroll_controller.h b/chromium/content/browser/renderer_host/overscroll_controller.h
index 9adf12aafd6..46bc8784a31 100644
--- a/chromium/content/browser/renderer_host/overscroll_controller.h
+++ b/chromium/content/browser/renderer_host/overscroll_controller.h
@@ -37,13 +37,13 @@ enum class OverscrollSource {
// overscroll gesture. This controller receives the events that are dispatched
// to the renderer, and the ACKs of events, and updates the overscroll gesture
// status accordingly.
-class OverscrollController {
+class CONTENT_EXPORT OverscrollController {
public:
// Exported for testing.
// TODO(mcnee): Tests needing CONTENT_EXPORT are BrowserPlugin specific.
// Remove after removing BrowserPlugin (crbug.com/533069).
- CONTENT_EXPORT OverscrollController();
- CONTENT_EXPORT virtual ~OverscrollController();
+ OverscrollController();
+ virtual ~OverscrollController();
// This must be called when dispatching any event from the
// RenderWidgetHostView so that the state of the overscroll gesture can be
@@ -56,9 +56,8 @@ class OverscrollController {
// Virtual and exported for testing.
// TODO(mcnee): Tests needing CONTENT_EXPORT and virtual are BrowserPlugin
// specific. Remove after removing BrowserPlugin (crbug.com/533069).
- CONTENT_EXPORT virtual void ReceivedEventACK(
- const blink::WebInputEvent& event,
- bool processed);
+ virtual void ReceivedEventACK(const blink::WebInputEvent& event,
+ bool processed);
OverscrollMode overscroll_mode() const { return overscroll_mode_; }
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 a06a26558aa..12b342e87ac 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
@@ -131,7 +131,7 @@ void P2PSocketDispatcherHost::OnChannelClosing() {
dns_requests_.clear();
if (monitoring_networks_) {
- net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
+ net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
monitoring_networks_ = false;
}
}
@@ -159,7 +159,10 @@ bool P2PSocketDispatcherHost::OnMessageReceived(const IPC::Message& message) {
return handled;
}
-void P2PSocketDispatcherHost::OnIPAddressChanged() {
+void P2PSocketDispatcherHost::OnNetworkChanged(
+ net::NetworkChangeNotifier::ConnectionType type) {
+ if (type == net::NetworkChangeNotifier::CONNECTION_NONE)
+ return;
// Notify the renderer about changes to list of network interfaces.
network_list_task_runner_->PostTask(
FROM_HERE,
@@ -200,7 +203,7 @@ P2PSocketDispatcherHost::~P2PSocketDispatcherHost() {
DCHECK(dns_requests_.empty());
if (monitoring_networks_)
- net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
+ net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
}
P2PSocketHost* P2PSocketDispatcherHost::LookupSocket(int socket_id) {
@@ -210,7 +213,7 @@ P2PSocketHost* P2PSocketDispatcherHost::LookupSocket(int socket_id) {
void P2PSocketDispatcherHost::OnStartNetworkNotifications() {
if (!monitoring_networks_) {
- net::NetworkChangeNotifier::AddIPAddressObserver(this);
+ net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
monitoring_networks_ = true;
}
@@ -221,14 +224,14 @@ void P2PSocketDispatcherHost::OnStartNetworkNotifications() {
void P2PSocketDispatcherHost::OnStopNetworkNotifications() {
if (monitoring_networks_) {
- net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
+ net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
monitoring_networks_ = false;
}
}
void P2PSocketDispatcherHost::OnGetHostAddress(const std::string& host_name,
int32_t request_id) {
- std::unique_ptr<DnsRequest> request = base::MakeUnique<DnsRequest>(
+ std::unique_ptr<DnsRequest> request = std::make_unique<DnsRequest>(
request_id, resource_context_->GetHostResolver());
DnsRequest* request_ptr = request.get();
dns_requests_.insert(std::move(request));
diff --git a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h
index be6b2d78e6d..e3f2e310790 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h
+++ b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h
@@ -39,7 +39,7 @@ class ResourceContext;
class P2PSocketDispatcherHost
: public content::BrowserMessageFilter,
- public net::NetworkChangeNotifier::IPAddressObserver {
+ public net::NetworkChangeNotifier::NetworkChangeObserver {
public:
P2PSocketDispatcherHost(content::ResourceContext* resource_context,
net::URLRequestContextGetter* url_context);
@@ -49,9 +49,9 @@ class P2PSocketDispatcherHost
void OnDestruct() const override;
bool OnMessageReceived(const IPC::Message& message) override;
- // net::NetworkChangeNotifier::IPAddressObserver interface.
- void OnIPAddressChanged() override;
-
+ // net::NetworkChangeNotifier::NetworkChangeObserver interface.
+ void OnNetworkChanged(
+ net::NetworkChangeNotifier::ConnectionType type) override;
// Starts the RTP packet header dumping. Must be called on the IO thread.
void StartRtpDump(
bool incoming,
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc b/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc
index 9f536022f69..6cac40664c7 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc
@@ -29,11 +29,11 @@ namespace {
typedef uint16_t PacketLength;
const int kPacketHeaderSize = sizeof(PacketLength);
-const int kReadBufferSize = 4096;
+const int kTcpReadBufferSize = 4096;
const int kPacketLengthOffset = 2;
const int kTurnChannelDataHeaderSize = 4;
-const int kRecvSocketBufferSize = 128 * 1024;
-const int kSendSocketBufferSize = 128 * 1024;
+const int kTcpRecvSocketBufferSize = 128 * 1024;
+const int kTcpSendSocketBufferSize = 128 * 1024;
bool IsTlsClientSocket(content::P2PSocketType type) {
return (type == content::P2P_SOCKET_STUN_TLS_CLIENT ||
@@ -245,14 +245,14 @@ void P2PSocketHostTcpBase::ProcessTlsSslConnectDone(int status) {
void P2PSocketHostTcpBase::OnOpen() {
state_ = STATE_OPEN;
// Setting socket send and receive buffer size.
- if (net::OK != socket_->SetReceiveBufferSize(kRecvSocketBufferSize)) {
+ if (net::OK != socket_->SetReceiveBufferSize(kTcpRecvSocketBufferSize)) {
LOG(WARNING) << "Failed to set socket receive buffer size to "
- << kRecvSocketBufferSize;
+ << kTcpRecvSocketBufferSize;
}
- if (net::OK != socket_->SetSendBufferSize(kSendSocketBufferSize)) {
+ if (net::OK != socket_->SetSendBufferSize(kTcpSendSocketBufferSize)) {
LOG(WARNING) << "Failed to set socket send buffer size to "
- << kSendSocketBufferSize;
+ << kTcpSendSocketBufferSize;
}
if (!DoSendSocketCreateMsg())
@@ -312,13 +312,13 @@ void P2PSocketHostTcpBase::DoRead() {
do {
if (!read_buffer_.get()) {
read_buffer_ = new net::GrowableIOBuffer();
- read_buffer_->SetCapacity(kReadBufferSize);
- } else if (read_buffer_->RemainingCapacity() < kReadBufferSize) {
- // Make sure that we always have at least kReadBufferSize of
+ read_buffer_->SetCapacity(kTcpReadBufferSize);
+ } else if (read_buffer_->RemainingCapacity() < kTcpReadBufferSize) {
+ // Make sure that we always have at least kTcpReadBufferSize of
// remaining capacity in the read buffer. Normally all packets
- // are smaller than kReadBufferSize, so this is not really
+ // are smaller than kTcpReadBufferSize, so this is not really
// required.
- read_buffer_->SetCapacity(read_buffer_->capacity() + kReadBufferSize -
+ read_buffer_->SetCapacity(read_buffer_->capacity() + kTcpReadBufferSize -
read_buffer_->RemainingCapacity());
}
result = socket_->Read(
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_udp.cc b/chromium/content/browser/renderer_host/p2p/socket_host_udp.cc
index 3094699d7b7..7b484dd52d0 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_udp.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_udp.cc
@@ -26,9 +26,9 @@
namespace {
// UDP packets cannot be bigger than 64k.
-const int kReadBufferSize = 65536;
+const int kUdpReadBufferSize = 65536;
// Socket receive buffer size.
-const int kRecvSocketBufferSize = 65536; // 64K
+const int kUdpRecvSocketBufferSize = 65536; // 64K
// Defines set of transient errors. These errors are ignored when we get them
// from sendto() or recvfrom() calls.
@@ -175,9 +175,9 @@ bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address,
}
// Setting recv socket buffer size.
- if (socket_->SetReceiveBufferSize(kRecvSocketBufferSize) != net::OK) {
+ if (socket_->SetReceiveBufferSize(kUdpRecvSocketBufferSize) != net::OK) {
LOG(WARNING) << "Failed to set socket receive buffer size to "
- << kRecvSocketBufferSize;
+ << kUdpRecvSocketBufferSize;
}
net::IPEndPoint address;
@@ -198,7 +198,7 @@ bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address,
message_sender_->Send(new P2PMsg_OnSocketCreated(
id_, address, remote_address.ip_address));
- recv_buffer_ = new net::IOBuffer(kReadBufferSize);
+ recv_buffer_ = new net::IOBuffer(kUdpReadBufferSize);
DoRead();
return true;
@@ -218,9 +218,7 @@ void P2PSocketHostUdp::DoRead() {
int result;
do {
result = socket_->RecvFrom(
- recv_buffer_.get(),
- kReadBufferSize,
- &recv_address_,
+ recv_buffer_.get(), kUdpReadBufferSize, &recv_address_,
base::Bind(&P2PSocketHostUdp::OnRecv, base::Unretained(this)));
if (result == net::ERR_IO_PENDING)
return;
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc b/chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
index 4df3558ebd3..924bf66ec5a 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
@@ -194,7 +194,7 @@ std::unique_ptr<net::DatagramServerSocket> CreateFakeDatagramServerSocket(
base::circular_deque<FakeDatagramServerSocket::UDPPacket>* sent_packets,
std::vector<uint16_t>* used_ports,
net::NetLog* net_log) {
- return base::MakeUnique<FakeDatagramServerSocket>(sent_packets, used_ports);
+ return std::make_unique<FakeDatagramServerSocket>(sent_packets, used_ports);
}
} // namespace
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 36c26f84eb0..851a223707d 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
@@ -154,7 +154,7 @@ void BrowserPpapiHostImpl::AddInstance(
// See http://crbug.com/733548.
if (instance_map_.find(instance) == instance_map_.end()) {
instance_map_[instance] =
- base::MakeUnique<InstanceData>(renderer_instance_data);
+ std::make_unique<InstanceData>(renderer_instance_data);
} else {
NOTREACHED();
}
@@ -235,8 +235,8 @@ bool BrowserPpapiHostImpl::HostMessageFilter::OnMessageReceived(
void BrowserPpapiHostImpl::HostMessageFilter::OnHostDestroyed() {
DCHECK(ppapi_host_);
- ppapi_host_ = NULL;
- browser_ppapi_host_impl_ = NULL;
+ ppapi_host_ = nullptr;
+ browser_ppapi_host_impl_ = nullptr;
}
BrowserPpapiHostImpl::HostMessageFilter::~HostMessageFilter() {}
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 3b38831a9a9..f0cd482cf3d 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
@@ -167,7 +167,7 @@ ContentBrowserPepperHostFactory::CreateResourceHost(
case PpapiHostMsg_VpnProvider_Create::ID: {
scoped_refptr<PepperVpnProviderMessageFilter> vpn_provider(
new PepperVpnProviderMessageFilter(host_, instance));
- return base::MakeUnique<ppapi::host::MessageFilterHost>(
+ return std::make_unique<ppapi::host::MessageFilterHost>(
host_->GetPpapiHost(), instance, resource, std::move(vpn_provider));
}
#endif
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_ref_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_file_ref_host.cc
index 6a1d9affe23..8af8c58045c 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_file_ref_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_file_ref_host.cc
@@ -45,7 +45,7 @@ PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost* host,
ResourceHost* fs_resource_host =
host->GetPpapiHost()->GetResourceHost(file_system);
- if (fs_resource_host == NULL) {
+ if (fs_resource_host == nullptr) {
DLOG(ERROR) << "Couldn't find FileSystem host: " << resource
<< " path: " << path;
return;
@@ -211,7 +211,7 @@ int32_t PepperFileRefHost::OnRename(ppapi::host::HostMessageContext* context,
if (!resource_host)
return PP_ERROR_BADRESOURCE;
- PepperFileRefHost* file_ref_host = NULL;
+ PepperFileRefHost* file_ref_host = nullptr;
if (resource_host->IsFileRefHost())
file_ref_host = static_cast<PepperFileRefHost*>(resource_host);
if (!file_ref_host)
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 d827ac0fd60..76a102ad2a2 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
@@ -40,10 +40,10 @@ scoped_refptr<storage::FileSystemContext> GetFileSystemContextFromRenderId(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHost* host = RenderProcessHost::FromID(render_process_id);
if (!host)
- return NULL;
+ return nullptr;
StoragePartition* storage_partition = host->GetStoragePartition();
if (!storage_partition)
- return NULL;
+ return nullptr;
return storage_partition->GetFileSystemContext();
}
@@ -58,7 +58,7 @@ PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host,
type_(type),
called_open_(false),
opened_(false),
- file_system_context_(NULL),
+ file_system_context_(nullptr),
reserved_quota_(0),
reserving_quota_(false),
weak_factory_(this) {}
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 f5c86d89bde..a7eb91795c4 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
@@ -104,7 +104,7 @@ PepperHostResolverMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& message) {
if (message.type() == PpapiHostMsg_HostResolver_Resolve::ID)
return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
- return NULL;
+ return nullptr;
}
int32_t PepperHostResolverMessageFilter::OnResourceMessageReceived(
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc b/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
index db1ace000c1..ab1c3fc3d50 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
@@ -80,7 +80,7 @@ base::FilePath PepperInternalFileRefBackend::GetExternalFilePath() const {
scoped_refptr<storage::FileSystemContext>
PepperInternalFileRefBackend::GetFileSystemContext() const {
if (!fs_host_.get())
- return NULL;
+ return nullptr;
return fs_host_->GetFileSystemContext();
}
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 6ad7bffb3f3..8a426aa3c76 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
@@ -28,7 +28,7 @@ PepperNetworkProxyHost::PepperNetworkProxyHost(BrowserPpapiHostImpl* host,
PP_Instance instance,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
- proxy_service_(NULL),
+ proxy_service_(nullptr),
is_allowed_(false),
waiting_for_ui_thread_data_(true),
weak_factory_(this) {
@@ -139,7 +139,7 @@ void PepperNetworkProxyHost::TryToSendUnsentRequests() {
} else {
// Everything looks valid, so try to resolve the proxy.
net::ProxyInfo* proxy_info = new net::ProxyInfo;
- net::ProxyService::PacRequest* pending_request = NULL;
+ net::ProxyService::PacRequest* pending_request = nullptr;
base::Callback<void(int)> callback =
base::Bind(&PepperNetworkProxyHost::OnResolveProxyCompleted,
weak_factory_.GetWeakPtr(),
@@ -147,7 +147,7 @@ void PepperNetworkProxyHost::TryToSendUnsentRequests() {
base::Owned(proxy_info));
int result = proxy_service_->ResolveProxy(
request.url, std::string(), proxy_info, callback, &pending_request,
- NULL, net::NetLogWithSource());
+ nullptr, net::NetLogWithSource());
pending_requests_.push(pending_request);
// If it was handled synchronously, we must run the callback now;
// proxy_service_ won't run it for us in this case.
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 f18aa82ecec..94d7951abf7 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
@@ -51,7 +51,7 @@ PP_Rect PrintAreaToPPPrintArea(const gfx::Rect& print_area,
class PrintingContextDelegate : public printing::PrintingContext::Delegate {
public:
// PrintingContext::Delegate methods.
- gfx::NativeView GetParentView() override { return NULL; }
+ gfx::NativeView GetParentView() override { return nullptr; }
std::string GetAppLocale() override {
return GetContentClient()->browser()->GetApplicationLocale();
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.cc b/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.cc
index be3dccde25a..af880f7b0dc 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_renderer_connection.cc
@@ -30,7 +30,7 @@ namespace content {
namespace {
-const uint32_t kFilteredMessageClasses[] = {
+const uint32_t kPepperFilteredMessageClasses[] = {
PpapiMsgStart, FrameMsgStart,
};
@@ -94,8 +94,8 @@ PendingHostCreator::~PendingHostCreator() {
} // namespace
PepperRendererConnection::PepperRendererConnection(int render_process_id)
- : BrowserMessageFilter(kFilteredMessageClasses,
- arraysize(kFilteredMessageClasses)),
+ : BrowserMessageFilter(kPepperFilteredMessageClasses,
+ arraysize(kPepperFilteredMessageClasses)),
render_process_id_(render_process_id) {
// Only give the renderer permission for stable APIs.
in_process_host_.reset(new BrowserPpapiHostImpl(this,
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.cc b/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.cc
index b766a7f5c51..d1bf34b4c6b 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_socket_utils.cc
@@ -81,36 +81,36 @@ bool GetCertificateFields(const net::X509Certificate& cert,
ppapi::PPB_X509Certificate_Fields* fields) {
const net::CertPrincipal& issuer = cert.issuer();
fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_COMMON_NAME,
- base::MakeUnique<base::Value>(issuer.common_name));
+ std::make_unique<base::Value>(issuer.common_name));
fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_LOCALITY_NAME,
- base::MakeUnique<base::Value>(issuer.locality_name));
+ std::make_unique<base::Value>(issuer.locality_name));
fields->SetField(
PP_X509CERTIFICATE_PRIVATE_ISSUER_STATE_OR_PROVINCE_NAME,
- base::MakeUnique<base::Value>(issuer.state_or_province_name));
+ std::make_unique<base::Value>(issuer.state_or_province_name));
fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_COUNTRY_NAME,
- base::MakeUnique<base::Value>(issuer.country_name));
+ std::make_unique<base::Value>(issuer.country_name));
fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_ORGANIZATION_NAME,
- base::MakeUnique<base::Value>(
+ std::make_unique<base::Value>(
base::JoinString(issuer.organization_names, "\n")));
fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_ORGANIZATION_UNIT_NAME,
- base::MakeUnique<base::Value>(
+ std::make_unique<base::Value>(
base::JoinString(issuer.organization_unit_names, "\n")));
const net::CertPrincipal& subject = cert.subject();
fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_COMMON_NAME,
- base::MakeUnique<base::Value>(subject.common_name));
+ std::make_unique<base::Value>(subject.common_name));
fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_LOCALITY_NAME,
- base::MakeUnique<base::Value>(subject.locality_name));
+ std::make_unique<base::Value>(subject.locality_name));
fields->SetField(
PP_X509CERTIFICATE_PRIVATE_SUBJECT_STATE_OR_PROVINCE_NAME,
- base::MakeUnique<base::Value>(subject.state_or_province_name));
+ std::make_unique<base::Value>(subject.state_or_province_name));
fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_COUNTRY_NAME,
- base::MakeUnique<base::Value>(subject.country_name));
+ std::make_unique<base::Value>(subject.country_name));
fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_ORGANIZATION_NAME,
- base::MakeUnique<base::Value>(
+ std::make_unique<base::Value>(
base::JoinString(subject.organization_names, "\n")));
fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_ORGANIZATION_UNIT_NAME,
- base::MakeUnique<base::Value>(base::JoinString(
+ std::make_unique<base::Value>(base::JoinString(
subject.organization_unit_names, "\n")));
const std::string& serial_number = cert.serial_number();
@@ -119,10 +119,10 @@ bool GetCertificateFields(const net::X509Certificate& cert,
serial_number.length()));
fields->SetField(
PP_X509CERTIFICATE_PRIVATE_VALIDITY_NOT_BEFORE,
- base::MakeUnique<base::Value>(cert.valid_start().ToDoubleT()));
+ std::make_unique<base::Value>(cert.valid_start().ToDoubleT()));
fields->SetField(
PP_X509CERTIFICATE_PRIVATE_VALIDITY_NOT_AFTER,
- base::MakeUnique<base::Value>(cert.valid_expiry().ToDoubleT()));
+ std::make_unique<base::Value>(cert.valid_expiry().ToDoubleT()));
std::string der;
net::X509Certificate::GetDEREncoded(cert.os_cert_handle(), &der);
fields->SetField(
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 abb4407b458..3a8cb7c6cd0 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
@@ -87,7 +87,7 @@ PepperTCPServerSocketMessageFilter::OverrideTaskRunnerForMessage(
case PpapiHostMsg_TCPServerSocket_StopListening::ID:
return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
}
- return NULL;
+ return nullptr;
}
int32_t PepperTCPServerSocketMessageFilter::OnResourceMessageReceived(
@@ -181,7 +181,7 @@ void PepperTCPServerSocketMessageFilter::DoListen(
state_ = STATE_LISTEN_IN_PROGRESS;
- socket_.reset(new net::TCPSocket(NULL, NULL, net::NetLogSource()));
+ socket_.reset(new net::TCPSocket(nullptr, nullptr, net::NetLogSource()));
int net_result = net::OK;
do {
net::IPEndPoint ip_end_point(net::IPAddress(address), port);
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 10be37c8976..e70df7a41b5 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
@@ -77,7 +77,7 @@ PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter(
rcvbuf_size_(0),
sndbuf_size_(0),
address_index_(0),
- socket_(new net::TCPSocket(NULL, NULL, net::NetLogSource())),
+ socket_(new net::TCPSocket(nullptr, nullptr, net::NetLogSource())),
ssl_context_helper_(host->ssl_context_helper()),
pending_accept_(false),
pending_read_on_unthrottle_(false),
@@ -105,7 +105,7 @@ PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter(
render_process_id_(0),
render_frame_id_(0),
host_(host),
- factory_(NULL),
+ factory_(nullptr),
instance_(instance),
state_(TCPSocketState::CONNECTED),
end_of_file_reached_(false),
@@ -166,7 +166,7 @@ PepperTCPSocketMessageFilter::OverrideTaskRunnerForMessage(
case PpapiHostMsg_TCPSocket_SetOption::ID:
return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
}
- return NULL;
+ return nullptr;
}
int32_t PepperTCPSocketMessageFilter::OnResourceMessageReceived(
@@ -222,11 +222,9 @@ int32_t PepperTCPSocketMessageFilter::OnMsgBind(
return PP_ERROR_NOACCESS;
}
- if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_,
- false /* private_api */,
- NULL,
- render_process_id_,
- render_frame_id_)) {
+ if (!pepper_socket_utils::CanUseSocketAPIs(
+ external_plugin_, false /* private_api */, nullptr,
+ render_process_id_, render_frame_id_)) {
return PP_ERROR_NOACCESS;
}
@@ -848,7 +846,7 @@ void PepperTCPSocketMessageFilter::OnConnectCompleted(
// 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(NULL, NULL, net::NetLogSource()));
+ socket_.reset(new net::TCPSocket(nullptr, nullptr, net::NetLogSource()));
if (address_index_ + 1 < address_list_.size()) {
DCHECK_EQ(version_, ppapi::TCP_SOCKET_VERSION_PRIVATE);
@@ -900,7 +898,7 @@ void PepperTCPSocketMessageFilter::OnReadCompleted(
} else {
SendReadError(context, NetErrorToPepperError(net_result));
}
- read_buffer_ = NULL;
+ read_buffer_ = nullptr;
}
void PepperTCPSocketMessageFilter::OnWriteCompleted(
@@ -925,8 +923,8 @@ void PepperTCPSocketMessageFilter::OnWriteCompleted(
else
SendWriteReply(context, NetErrorToPepperError(net_result));
- write_buffer_ = NULL;
- write_buffer_base_ = NULL;
+ write_buffer_ = nullptr;
+ write_buffer_base_ = nullptr;
}
void PepperTCPSocketMessageFilter::OnListenCompleted(
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_host.cc
index 0df16ef2cf2..036149f4af4 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_host.cc
@@ -50,7 +50,7 @@ PepperTrueTypeFontHost::~PepperTrueTypeFontHost() {
// long blocking operations.
font_->AddRef();
PepperTrueTypeFont* raw_font = font_.get();
- font_ = NULL;
+ font_ = nullptr;
task_runner_->ReleaseSoon(FROM_HERE, raw_font);
}
}
@@ -124,7 +124,7 @@ void PepperTrueTypeFontHost::OnInitializeComplete(
initialize_completed_ = true;
// Release the font if there was an error, so future calls will fail.
if (result != PP_OK)
- font_ = NULL;
+ font_ = nullptr;
host()->SendUnsolicitedReply(
pp_resource(), PpapiPluginMsg_TrueTypeFont_CreateReply(*desc, result));
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc
index 9b37b39efba..464dcbd4767 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc
@@ -138,7 +138,7 @@ int32_t PepperTrueTypeFontLinux::GetTable(uint32_t table_tag,
size_t table_size = 0;
// Tags are byte swapped on Linux.
table_tag = base::ByteSwap(table_tag);
- if (!GetFontTable(fd_.get(), table_tag, offset, NULL, &table_size))
+ if (!GetFontTable(fd_.get(), table_tag, offset, nullptr, &table_size))
return PP_ERROR_FAILED;
// Only retrieve as much as the caller requested.
table_size = std::min(table_size, static_cast<size_t>(max_data_length));
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_pango.cc b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_pango.cc
index cd1a5e579dc..05bd58ea43a 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_pango.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_pango.cc
@@ -15,7 +15,7 @@ namespace content {
void GetFontFamilies_SlowBlocking(std::vector<std::string>* font_families) {
PangoFontMap* font_map = ::pango_cairo_font_map_get_default();
- PangoFontFamily** families = NULL;
+ PangoFontFamily** families = nullptr;
int num_families = 0;
::pango_font_map_list_families(font_map, &families, &num_families);
@@ -28,14 +28,14 @@ void GetFontsInFamily_SlowBlocking(
const std::string& family,
std::vector<ppapi::proxy::SerializedTrueTypeFontDesc>* fonts_in_family) {
PangoFontMap* font_map = ::pango_cairo_font_map_get_default();
- PangoFontFamily** font_families = NULL;
+ PangoFontFamily** font_families = nullptr;
int num_families = 0;
::pango_font_map_list_families(font_map, &font_families, &num_families);
for (int i = 0; i < num_families; ++i) {
PangoFontFamily* font_family = font_families[i];
if (family.compare(::pango_font_family_get_name(font_family)) == 0) {
- PangoFontFace** font_faces = NULL;
+ PangoFontFace** font_faces = nullptr;
int num_faces = 0;
::pango_font_family_list_faces(font_family, &font_faces, &num_faces);
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 249de778836..ed3a9daea66 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
@@ -115,7 +115,7 @@ PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage(
case PpapiHostMsg_UDPSocket_LeaveGroup::ID:
return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
}
- return NULL;
+ return nullptr;
}
int32_t PepperUDPSocketMessageFilter::OnResourceMessageReceived(
@@ -401,7 +401,7 @@ void PepperUDPSocketMessageFilter::DoBind(
std::unique_ptr<net::UDPSocket> socket(
new net::UDPSocket(net::DatagramSocket::DEFAULT_BIND,
- net::RandIntCallback(), NULL, net::NetLogSource()));
+ net::RandIntCallback(), nullptr, net::NetLogSource()));
net::IPAddressBytes address;
uint16_t port;
@@ -660,7 +660,7 @@ void PepperUDPSocketMessageFilter::OnRecvFromCompleted(int net_result) {
SendRecvFromError(pp_result);
}
- recvfrom_buffer_ = NULL;
+ recvfrom_buffer_ = nullptr;
DCHECK_GT(remaining_recv_slots_, 0u);
remaining_recv_slots_--;
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 8799b033036..5327e8d97bc 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
@@ -210,16 +210,16 @@ int32_t PepperVpnProviderMessageFilter::DoBind(
!recv_buffer->CreateAndMapAnonymous(kBufferSize))
return PP_ERROR_NOMEMORY;
- send_packet_buffer_ = base::MakeUnique<ppapi::VpnProviderSharedBuffer>(
+ send_packet_buffer_ = std::make_unique<ppapi::VpnProviderSharedBuffer>(
kMaxBufferedPackets, kMaxPacketSize, std::move(send_buffer));
- recv_packet_buffer_ = base::MakeUnique<ppapi::VpnProviderSharedBuffer>(
+ recv_packet_buffer_ = std::make_unique<ppapi::VpnProviderSharedBuffer>(
kMaxBufferedPackets, kMaxPacketSize, std::move(recv_buffer));
}
vpn_service_proxy_->Bind(
document_url_.host(), configuration_id_, configuration_name_,
success_callback, failure_callback,
- base::MakeUnique<PepperVpnProviderResourceHostProxyImpl>(
+ std::make_unique<PepperVpnProviderResourceHostProxyImpl>(
weak_factory_.GetWeakPtr()));
return PP_OK_COMPLETIONPENDING;
diff --git a/chromium/content/browser/renderer_host/render_message_filter.cc b/chromium/content/browser/renderer_host/render_message_filter.cc
index 24f6dfbe179..4fc430437c7 100644
--- a/chromium/content/browser/renderer_host/render_message_filter.cc
+++ b/chromium/content/browser/renderer_host/render_message_filter.cc
@@ -21,6 +21,7 @@
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
+#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"
@@ -40,11 +41,8 @@
#include "content/browser/renderer_host/render_widget_helper.h"
#include "content/browser/resource_context_impl.h"
#include "content/common/cache_storage/cache_storage_types.h"
-#include "content/common/child_process_host_impl.h"
-#include "content/common/child_process_messages.h"
#include "content/common/content_constants_internal.h"
#include "content/common/render_message_filter.mojom.h"
-#include "content/common/render_process_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_context.h"
@@ -80,17 +78,18 @@
#include "content/common/mac/font_loader.h"
#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
#endif
-
#if defined(OS_LINUX)
#include "base/linux_util.h"
#include "base/threading/platform_thread.h"
#endif
+using blink::mojom::CacheStorageError;
+
namespace content {
namespace {
-const uint32_t kFilteredMessageClasses[] = {
- ChildProcessMsgStart, RenderProcessMsgStart, ViewMsgStart,
+const uint32_t kRenderFilteredMessageClasses[] = {
+ ChildProcessMsgStart, ViewMsgStart,
};
#if defined(OS_MACOSX)
@@ -110,9 +109,8 @@ void ResizeHelperPostMsgToUIThread(int render_process_id,
}
#endif
-void NoOpCacheStorageErrorCallback(
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- CacheStorageError error) {}
+void NoOpCacheStorageErrorCallback(CacheStorageCacheHandle cache_handle,
+ CacheStorageError error) {}
} // namespace
@@ -124,8 +122,8 @@ RenderMessageFilter::RenderMessageFilter(
MediaInternals* media_internals,
DOMStorageContextWrapper* dom_storage_context,
CacheStorageContextImpl* cache_storage_context)
- : BrowserMessageFilter(kFilteredMessageClasses,
- arraysize(kFilteredMessageClasses)),
+ : BrowserMessageFilter(kRenderFilteredMessageClasses,
+ arraysize(kRenderFilteredMessageClasses)),
BrowserAssociatedInterface<mojom::RenderMessageFilter>(this, this),
resource_dispatcher_host_(ResourceDispatcherHostImpl::Get()),
request_context_(request_context),
@@ -157,20 +155,6 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
ViewHostMsg_ResizeOrRepaint_ACK,
ResizeHelperPostMsgToUIThread(render_process_id_, message))
#endif
- IPC_MESSAGE_HANDLER_DELAY_REPLY(ChildProcessHostMsg_HasGpuProcess,
- OnHasGpuProcess)
-#if defined(OS_LINUX)
- IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SetThreadPriority,
- OnSetThreadPriority)
-#endif
- IPC_MESSAGE_HANDLER(RenderProcessHostMsg_DidGenerateCacheableMetadata,
- OnCacheableMetadataAvailable)
- IPC_MESSAGE_HANDLER(
- RenderProcessHostMsg_DidGenerateCacheableMetadataInCacheStorage,
- OnCacheableMetadataAvailableForCacheStorage)
-#if defined(OS_MACOSX)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(RenderProcessHostMsg_LoadFont, OnLoadFont)
-#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvents, OnMediaLogEvents)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -214,25 +198,16 @@ void RenderMessageFilter::CreateFullscreenWidget(
std::move(callback).Run(route_id);
}
+void RenderMessageFilter::LoadFont(const base::string16& font_name,
+ float font_point_size,
+ LoadFontCallback callback) {
#if defined(OS_MACOSX)
-
-void RenderMessageFilter::OnLoadFont(const FontDescriptor& font,
- IPC::Message* reply_msg) {
- FontLoader::LoadFont(
- font,
- base::BindOnce(&RenderMessageFilter::SendLoadFontReply, this, reply_msg));
-}
-
-void RenderMessageFilter::SendLoadFontReply(IPC::Message* reply,
- uint32_t data_size,
- base::SharedMemoryHandle handle,
- uint32_t font_id) {
- RenderProcessHostMsg_LoadFont::WriteReplyParams(reply, data_size, handle,
- font_id);
- Send(reply);
-}
-
+ FontLoader::LoadFont(font_name, font_point_size, std::move(callback));
+#else
+ // TODO(https://crbug.com/676224): remove this reporting.
+ mojo::ReportBadMessage("LoadFont is OS_MACOSX only.");
#endif // defined(OS_MACOSX)
+}
#if defined(OS_LINUX)
void RenderMessageFilter::SetThreadPriorityOnFileThread(
@@ -253,23 +228,33 @@ void RenderMessageFilter::SetThreadPriorityOnFileThread(
base::PlatformThread::SetThreadPriority(peer_tid, priority);
}
+#endif
-void RenderMessageFilter::OnSetThreadPriority(base::PlatformThreadId ns_tid,
- base::ThreadPriority priority) {
+void RenderMessageFilter::SetThreadPriority(int32_t ns_tid,
+ base::ThreadPriority priority) {
+#if defined(OS_LINUX)
constexpr base::TaskTraits kTraits = {
base::MayBlock(), base::TaskPriority::USER_BLOCKING,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
base::PostTaskWithTraits(
FROM_HERE, kTraits,
base::BindOnce(&RenderMessageFilter::SetThreadPriorityOnFileThread, this,
- ns_tid, priority));
-}
+ static_cast<base::PlatformThreadId>(ns_tid), priority));
+#else
+ mojo::ReportBadMessage("SetThreadPriority is only supported on OS_LINUX");
#endif
+}
-void RenderMessageFilter::OnCacheableMetadataAvailable(
+void RenderMessageFilter::DidGenerateCacheableMetadata(
const GURL& url,
base::Time expected_response_time,
- const std::vector<char>& data) {
+ const std::vector<uint8_t>& data) {
+ if (!url.SchemeIsHTTPOrHTTPS()) {
+ bad_message::ReceivedBadMessage(
+ this, bad_message::RMF_BAD_URL_CACHEABLE_METADATA);
+ return;
+ }
+
net::HttpCache* cache = request_context_->GetURLRequestContext()->
http_transaction_factory()->GetCache();
if (!cache)
@@ -288,10 +273,10 @@ void RenderMessageFilter::OnCacheableMetadataAvailable(
data.size());
}
-void RenderMessageFilter::OnCacheableMetadataAvailableForCacheStorage(
+void RenderMessageFilter::DidGenerateCacheableMetadataInCacheStorage(
const GURL& url,
base::Time expected_response_time,
- const std::vector<char>& data,
+ 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()));
@@ -310,13 +295,11 @@ void RenderMessageFilter::OnCacheStorageOpenCallback(
base::Time expected_response_time,
scoped_refptr<net::IOBuffer> buf,
int buf_len,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheStorageError error) {
- if (error != CACHE_STORAGE_OK || !cache_handle || !cache_handle->value())
- return;
- CacheStorageCache* cache = cache_handle->value();
- if (!cache)
+ if (error != CacheStorageError::kSuccess || !cache_handle.value())
return;
+ CacheStorageCache* cache = cache_handle.value();
cache->WriteSideData(base::BindOnce(&NoOpCacheStorageErrorCallback,
base::Passed(std::move(cache_handle))),
url, expected_response_time, buf, buf_len);
@@ -331,18 +314,8 @@ void RenderMessageFilter::OnMediaLogEvents(
media_internals_->OnMediaEvents(render_process_id_, events);
}
-void RenderMessageFilter::OnHasGpuProcess(IPC::Message* reply_ptr) {
- std::unique_ptr<IPC::Message> reply(reply_ptr);
- GpuProcessHost::GetHasGpuProcess(
- base::Bind(&RenderMessageFilter::GetHasGpuProcessCallback,
- weak_ptr_factory_.GetWeakPtr(), base::Passed(&reply)));
-}
-
-void RenderMessageFilter::GetHasGpuProcessCallback(
- std::unique_ptr<IPC::Message> reply,
- bool has_gpu) {
- ChildProcessHostMsg_HasGpuProcess::WriteReplyParams(reply.get(), has_gpu);
- Send(reply.release());
+void RenderMessageFilter::HasGpuProcess(HasGpuProcessCallback callback) {
+ GpuProcessHost::GetHasGpuProcess(std::move(callback));
}
} // 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 d0e7c36a50e..0a42a5e14b6 100644
--- a/chromium/content/browser/renderer_host/render_message_filter.h
+++ b/chromium/content/browser/renderer_host/render_message_filter.h
@@ -14,7 +14,6 @@
#include "base/files/file_path.h"
#include "base/macros.h"
-#include "base/memory/shared_memory.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner_helpers.h"
#include "base/strings/string16.h"
@@ -26,6 +25,7 @@
#include "content/public/browser/browser_message_filter.h"
#include "gpu/config/gpu_info.h"
#include "ipc/message_filter.h"
+#include "third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h"
#include "third_party/WebKit/public/web/WebPopupType.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -37,7 +37,6 @@
#endif
class GURL;
-struct FontDescriptor;
namespace media {
struct MediaLogEvent;
@@ -95,15 +94,6 @@ class CONTENT_EXPORT RenderMessageFilter
void OnGetProcessMemorySizes(size_t* private_bytes, size_t* shared_bytes);
-#if defined(OS_MACOSX)
- // Messages for OOP font loading.
- void OnLoadFont(const FontDescriptor& font, IPC::Message* reply_msg);
- void SendLoadFontReply(IPC::Message* reply,
- uint32_t data_size,
- base::SharedMemoryHandle handle,
- uint32_t font_id);
-#endif
-
// mojom::RenderMessageFilter:
void GenerateRoutingID(GenerateRoutingIDCallback routing_id) override;
void CreateNewWidget(int32_t opener_id,
@@ -113,37 +103,36 @@ class CONTENT_EXPORT RenderMessageFilter
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 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;
+ void SetThreadPriority(int32_t ns_tid,
+ base::ThreadPriority priority) override;
+ // Messages for OOP font loading. Only used for MACOSX.
+ void LoadFont(const base::string16& font_to_load,
+ float font_point_size,
+ LoadFontCallback callback) override;
- // Message handlers called on the browser IO thread:
- void OnHasGpuProcess(IPC::Message* reply);
- // Helper callbacks for the message handlers.
- void GetHasGpuProcessCallback(std::unique_ptr<IPC::Message> reply,
- bool has_gpu);
void OnResolveProxy(const GURL& url, IPC::Message* reply_msg);
#if defined(OS_LINUX)
void SetThreadPriorityOnFileThread(base::PlatformThreadId ns_tid,
base::ThreadPriority priority);
- void OnSetThreadPriority(base::PlatformThreadId ns_tid,
- base::ThreadPriority priority);
#endif
- void OnCacheableMetadataAvailable(const GURL& url,
- base::Time expected_response_time,
- const std::vector<char>& data);
- void OnCacheableMetadataAvailableForCacheStorage(
- const GURL& url,
- base::Time expected_response_time,
- const std::vector<char>& data,
- const url::Origin& cache_storage_origin,
- const std::string& cache_storage_cache_name);
- void OnCacheStorageOpenCallback(
- const GURL& url,
- base::Time expected_response_time,
- scoped_refptr<net::IOBuffer> buf,
- int buf_len,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- CacheStorageError error);
+ 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;
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 30249244add..936b44a0992 100644
--- a/chromium/content/browser/renderer_host/render_process_host_browsertest.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_browsertest.cc
@@ -9,8 +9,8 @@
#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/common/child_process_messages.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_observer.h"
@@ -58,14 +58,14 @@ std::unique_ptr<net::test_server::HttpResponse> HandleBeacon(
const net::test_server::HttpRequest& request) {
if (request.relative_url != "/beacon")
return nullptr;
- return base::MakeUnique<net::test_server::BasicHttpResponse>();
+ return std::make_unique<net::test_server::BasicHttpResponse>();
}
std::unique_ptr<net::test_server::HttpResponse> HandleHungBeacon(
const net::test_server::HttpRequest& request) {
if (request.relative_url != "/beacon")
return nullptr;
- return base::MakeUnique<net::test_server::HungResponse>();
+ return std::make_unique<net::test_server::HungResponse>();
}
class RenderProcessHostTest : public ContentBrowserTest,
@@ -137,6 +137,19 @@ class NonSpareRendererContentBrowserClient : public TestContentBrowserClient {
}
};
+class RenderProcessHostWithKeepAliveOptionEnabledTest
+ : public RenderProcessHostTest {
+ public:
+ void SetUp() override {
+ feature_list_.InitAndEnableFeature(
+ features::kKeepAliveRendererForKeepaliveRequests);
+ RenderProcessHostTest::SetUp();
+ }
+
+ private:
+ base::test::ScopedFeatureList feature_list_;
+};
+
// Sometimes the renderer process's ShutdownRequest (corresponding to the
// ViewMsg_WasSwappedOut from a previous navigation) doesn't arrive until after
// the browser process decides to re-use the renderer for a new purpose. This
@@ -153,11 +166,13 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
host_destructions_ = 0;
process_exits_ = 0;
+
rph->AddObserver(this);
- ChildProcessHostMsg_ShutdownRequest msg;
- rph->OnMessageReceived(msg);
- // If the RPH sends a mistaken ChildProcessMsg_Shutdown, the renderer process
+ static_cast<mojom::RendererHost*>(static_cast<RenderProcessHostImpl*>(rph))
+ ->ShutdownRequest();
+
+ // If the RPH sends a mistaken ProcessShutdown, the renderer process
// will take some time to die. Wait for a second tab to load in order to give
// that time to happen.
NavigateToURL(CreateBrowser(), test_url);
@@ -474,7 +489,8 @@ class MediaStopObserver : public WebContentsObserver {
void MediaStoppedPlaying(
const WebContentsObserver::MediaPlayerInfo& media_info,
- const WebContentsObserver::MediaPlayerId& id) override {
+ const WebContentsObserver::MediaPlayerId& id,
+ WebContentsObserver::MediaStoppedReason reason) override {
quit_closure_.Run();
}
@@ -706,23 +722,24 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
rph->RemoveObserver(this);
}
-IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, KeepAliveRendererProcess) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeatureWithParameters(
- features::kKeepAliveRendererForKeepaliveRequests,
- {std::make_pair("timeout_in_sec", "30")});
-
+IN_PROC_BROWSER_TEST_F(RenderProcessHostWithKeepAliveOptionEnabledTest,
+ KeepAliveRendererProcess) {
embedded_test_server()->RegisterRequestHandler(
base::BindRepeating(HandleBeacon));
ASSERT_TRUE(embedded_test_server()->Start());
- RenderProcessHostImpl* rph = static_cast<RenderProcessHostImpl*>(
- shell()->web_contents()->GetMainFrame()->GetProcess());
+
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/send-beacon.html"));
+
+ RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
+ shell()->web_contents()->GetMainFrame());
+ RenderProcessHostImpl* rph =
+ static_cast<RenderProcessHostImpl*>(rfh->GetProcess());
host_destructions_ = 0;
process_exits_ = 0;
rph->AddObserver(this);
+ rfh->SetKeepAliveTimeoutForTesting(base::TimeDelta::FromSeconds(30));
- NavigateToURL(shell(), embedded_test_server()->GetURL("/send-beacon.html"));
base::TimeTicks start = base::TimeTicks::Now();
NavigateToURL(shell(), GURL("data:text/html,<p>hello</p>"));
@@ -733,23 +750,53 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, KeepAliveRendererProcess) {
rph->RemoveObserver(this);
}
-IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, KeepAliveRendererProcess_Hung) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeatureWithParameters(
- features::kKeepAliveRendererForKeepaliveRequests,
- {std::make_pair("timeout_in_sec", "1")});
+IN_PROC_BROWSER_TEST_F(RenderProcessHostWithKeepAliveOptionEnabledTest,
+ KeepAliveRendererProcess_Hung) {
+ embedded_test_server()->RegisterRequestHandler(
+ base::BindRepeating(HandleHungBeacon));
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/send-beacon.html"));
+
+ RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
+ shell()->web_contents()->GetMainFrame());
+ RenderProcessHostImpl* rph =
+ static_cast<RenderProcessHostImpl*>(rfh->GetProcess());
+ host_destructions_ = 0;
+ process_exits_ = 0;
+ rph->AddObserver(this);
+ rfh->SetKeepAliveTimeoutForTesting(base::TimeDelta::FromSeconds(1));
+
+ base::TimeTicks start = base::TimeTicks::Now();
+ NavigateToURL(shell(), GURL("data:text/html,<p>hello</p>"));
+
+ WaitUntilProcessExits(1);
+
+ EXPECT_GE(base::TimeTicks::Now() - start, base::TimeDelta::FromSeconds(1));
+ if (!host_destructions_)
+ rph->RemoveObserver(this);
+}
+
+IN_PROC_BROWSER_TEST_F(RenderProcessHostWithKeepAliveOptionEnabledTest,
+ FetchKeepAliveRendererProcess_Hung) {
embedded_test_server()->RegisterRequestHandler(
base::BindRepeating(HandleHungBeacon));
ASSERT_TRUE(embedded_test_server()->Start());
- RenderProcessHostImpl* rph = static_cast<RenderProcessHostImpl*>(
- shell()->web_contents()->GetMainFrame()->GetProcess());
+
+ NavigateToURL(shell(),
+ embedded_test_server()->GetURL("/fetch-keepalive.html"));
+
+ RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
+ shell()->web_contents()->GetMainFrame());
+ RenderProcessHostImpl* rph =
+ static_cast<RenderProcessHostImpl*>(rfh->GetProcess());
host_destructions_ = 0;
process_exits_ = 0;
rph->AddObserver(this);
+ rfh->SetKeepAliveTimeoutForTesting(base::TimeDelta::FromSeconds(1));
- NavigateToURL(shell(), embedded_test_server()->GetURL("/send-beacon.html"));
base::TimeTicks start = base::TimeTicks::Now();
NavigateToURL(shell(), GURL("data:text/html,<p>hello</p>"));
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 a8dfd6c0c83..28a84469516 100644
--- a/chromium/content/browser/renderer_host/render_process_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_impl.cc
@@ -33,9 +33,11 @@
#include "base/memory/shared_memory.h"
#include "base/memory/shared_memory_handle.h"
#include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/persistent_histogram_allocator.h"
#include "base/metrics/persistent_memory_allocator.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/metrics/user_metrics.h"
#include "base/process/process_handle.h"
#include "base/rand_util.h"
@@ -46,9 +48,11 @@
#include "base/supports_user_data.h"
#include "base/synchronization/lock.h"
#include "base/sys_info.h"
+#include "base/task_scheduler/post_task.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
@@ -87,7 +91,6 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/gpu/shader_cache_factory.h"
#include "content/browser/histogram_controller.h"
-#include "content/browser/histogram_message_filter.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
#include "content/browser/loader/resource_message_filter.h"
@@ -98,19 +101,20 @@
#include "content/browser/media/midi_host.h"
#include "content/browser/memory/memory_coordinator_impl.h"
#include "content/browser/mime_registry_impl.h"
+#include "content/browser/mus_util.h"
#include "content/browser/net/reporting_service_proxy.h"
#include "content/browser/notifications/notification_message_filter.h"
-#include "content/browser/notifications/platform_notification_context_impl.h"
#include "content/browser/payments/payment_manager.h"
#include "content/browser/permissions/permission_service_context.h"
#include "content/browser/permissions/permission_service_impl.h"
#include "content/browser/push_messaging/push_messaging_manager.h"
#include "content/browser/quota_dispatcher_host.h"
-#include "content/browser/renderer_host/clipboard_message_filter.h"
+#include "content/browser/renderer_host/clipboard_host_impl.h"
#include "content/browser/renderer_host/file_utilities_host_impl.h"
#include "content/browser/renderer_host/media/audio_input_renderer_host.h"
#include "content/browser/renderer_host/media/audio_renderer_host.h"
#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
+#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/peer_connection_tracker_host.h"
#include "content/browser/renderer_host/media/video_capture_host.h"
#include "content/browser/renderer_host/offscreen_canvas_provider_impl.h"
@@ -135,11 +139,10 @@
#include "content/browser/websockets/websocket_manager.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/common/child_process_host_impl.h"
-#include "content/common/child_process_messages.h"
#include "content/common/content_switches_internal.h"
#include "content/common/frame_messages.h"
#include "content/common/in_process_child_thread_params.h"
-#include "content/common/render_process_messages.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "content/common/resource_messages.h"
#include "content/common/service_manager/child_connection.h"
#include "content/common/service_manager/service_manager_connection_impl.h"
@@ -150,12 +153,12 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
+#include "content/public/browser/quota_permission_context.h"
#include "content/public/browser/render_process_host_factory.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/browser/resource_context.h"
-#include "content/public/browser/worker_service.h"
#include "content/public/common/bind_interface_helpers.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/connection_filter.h"
@@ -170,6 +173,7 @@
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/common/url_constants.h"
+#include "device/gamepad/gamepad_haptics_manager.h"
#include "device/gamepad/gamepad_monitor.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gpu_switches.h"
@@ -180,6 +184,7 @@
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_mojo.h"
#include "ipc/ipc_logging.h"
+#include "media/audio/audio_manager.h"
#include "media/base/media_switches.h"
#include "media/media_features.h"
#include "media/mojo/services/video_decode_perf_history.h"
@@ -191,22 +196,20 @@
#include "ppapi/features/features.h"
#include "services/device/public/interfaces/battery_monitor.mojom.h"
#include "services/device/public/interfaces/constants.mojom.h"
+#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
-#include "services/resource_coordinator/public/cpp/resource_coordinator_interface.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"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "services/service_manager/runner/common/client_util.h"
#include "services/service_manager/runner/common/switches.h"
-#include "services/shape_detection/public/interfaces/barcodedetection.mojom.h"
-#include "services/shape_detection/public/interfaces/constants.mojom.h"
-#include "services/shape_detection/public/interfaces/facedetection_provider.mojom.h"
-#include "services/shape_detection/public/interfaces/textdetection.mojom.h"
+#include "services/service_manager/sandbox/switches.h"
#include "storage/browser/fileapi/sandbox_file_system_backend.h"
#include "third_party/WebKit/public/public_features.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/ui_base_switches.h"
+#include "ui/base/ui_base_switches_util.h"
#include "ui/display/display_switches.h"
#include "ui/gl/gl_switches.h"
#include "ui/gl/gpu_switching_manager.h"
@@ -218,13 +221,16 @@
#include "media/audio/android/audio_manager_android.h"
#endif
+#if !defined(OS_ANDROID)
+#include "content/browser/compositor/image_transport_factory.h"
+#endif
+
#if defined(OS_WIN)
#include "base/win/scoped_com_initializer.h"
#include "base/win/windows_version.h"
#include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h"
-#include "content/common/font_cache_dispatcher_win.h"
-#include "content/common/sandbox_win.h"
#include "sandbox/win/src/sandbox_policy.h"
+#include "services/service_manager/sandbox/win/sandbox_win.h"
#include "ui/display/win/dpi.h"
#endif
@@ -250,6 +256,7 @@
#include "content/browser/renderer_host/p2p/socket_dispatcher_host.h"
#include "content/browser/webrtc/webrtc_internals.h"
#include "content/common/media/aec_dump_messages.h"
+#include "content/public/browser/webrtc_log.h"
#endif
#if BUILDFLAG(USE_MINIKIN_HYPHENATION)
@@ -360,7 +367,7 @@ class SiteProcessMap : public base::SupportsUserData::Data {
SiteToProcessMap::iterator i = map_.find(site);
if (i != map_.end())
return i->second;
- return NULL;
+ return nullptr;
}
void RemoveProcess(RenderProcessHost* host) {
@@ -408,13 +415,13 @@ class RendererSandboxedProcessLauncherDelegate
#if defined(OS_WIN)
bool PreSpawnTarget(sandbox::TargetPolicy* policy) override {
- AddBaseHandleClosePolicy(policy);
+ service_manager::SandboxWin::AddBaseHandleClosePolicy(policy);
const base::string16& sid =
GetContentClient()->browser()->GetAppContainerSidForSandboxType(
GetSandboxType());
if (!sid.empty())
- AddAppContainerPolicy(policy, sid.c_str());
+ service_manager::SandboxWin::AddAppContainerPolicy(policy, sid.c_str());
return GetContentClient()->browser()->PreSpawnRenderer(policy);
}
@@ -685,9 +692,9 @@ void CreateMemoryCoordinatorHandle(
std::move(request));
}
-void CreateResourceCoordinatorProcessInterface(
+void CreateProcessResourceCoordinator(
RenderProcessHostImpl* render_process_host,
- resource_coordinator::mojom::CoordinationUnitRequest request) {
+ resource_coordinator::mojom::ProcessCoordinationUnitRequest request) {
render_process_host->GetProcessResourceCoordinator()->AddBinding(
std::move(request));
}
@@ -830,7 +837,8 @@ class SiteProcessCountTracker : public base::SupportsUserData::Data,
// |site_url|, for example if it was reused by a navigation to a
// different site, and |site_url| requires a dedicated process. Do not
// allow such hosts to be reused. See https://crbug.com/780661.
- if (!RenderProcessHostImpl::IsSuitableHost(
+ if (!host->MayReuseHost() ||
+ !RenderProcessHostImpl::IsSuitableHost(
host, host->GetBrowserContext(), site_url))
continue;
@@ -995,6 +1003,15 @@ class UnmatchedServiceWorkerProcessTracker
RenderProcessHost* host = FindFreshestProcessForSite(site_url);
if (!host)
return nullptr;
+
+ // It's possible that |host| is currently unsuitable for hosting
+ // |site_url|, for example if it was used for a ServiceWorker for a
+ // nonexistent extension URL. See https://crbug.com/782349 and
+ // https://crbug.com/780661.
+ if (!host->MayReuseHost() || !RenderProcessHostImpl::IsSuitableHost(
+ host, host->GetBrowserContext(), site_url))
+ return nullptr;
+
site_process_set_.erase(SiteProcessIDPair(site_url, host->GetID()));
if (!HasProcess(host))
host->RemoveObserver(this);
@@ -1338,6 +1355,9 @@ RenderProcessHostImpl::RenderProcessHostImpl(
AddObserver(indexed_db_factory_.get());
InitializeChannelProxy();
+
+ if (!switches::IsMusHostingViz())
+ gpu_client_.reset(new GpuClient(GetID()));
}
// static
@@ -1432,6 +1452,9 @@ bool RenderProcessHostImpl::Init() {
if (renderer_path.empty())
return false;
+ if (gpu_client_)
+ gpu_client_->PreEstablishGpuChannel();
+
sent_render_process_ready_ = false;
// We may reach Init() during process death notification (e.g.
@@ -1511,7 +1534,7 @@ bool RenderProcessHostImpl::Init() {
// Build command line for renderer. We call AppendRendererCommandLine()
// first so the process type argument will appear first.
std::unique_ptr<base::CommandLine> cmd_line =
- base::MakeUnique<base::CommandLine>(renderer_path);
+ std::make_unique<base::CommandLine>(renderer_path);
if (!renderer_prefix.empty())
cmd_line->PrependWrapper(renderer_prefix);
AppendRendererCommandLine(cmd_line.get());
@@ -1520,7 +1543,7 @@ bool RenderProcessHostImpl::Init() {
// As long as there's no renderer prefix, we can use the zygote process
// at this stage.
child_process_launcher_.reset(new ChildProcessLauncher(
- base::MakeUnique<RendererSandboxedProcessLauncherDelegate>(),
+ std::make_unique<RendererSandboxedProcessLauncherDelegate>(),
std::move(cmd_line), GetID(), this,
std::move(broker_client_invitation_),
base::Bind(&RenderProcessHostImpl::OnMojoError, id_)));
@@ -1569,7 +1592,7 @@ void RenderProcessHostImpl::InitializeChannelProxy() {
// Establish a ServiceManager connection for the new render service instance.
broker_client_invitation_ =
- base::MakeUnique<mojo::edk::OutgoingBrokerClientInvitation>();
+ std::make_unique<mojo::edk::OutgoingBrokerClientInvitation>();
service_manager::Identity child_identity(
mojom::kRendererServiceName,
BrowserContext::GetServiceUserIdFor(GetBrowserContext()),
@@ -1585,8 +1608,11 @@ void RenderProcessHostImpl::InitializeChannelProxy() {
mojo::MessagePipe pipe;
BindInterface(IPC::mojom::ChannelBootstrap::Name_, std::move(pipe.handle1));
std::unique_ptr<IPC::ChannelFactory> channel_factory =
- IPC::ChannelMojo::CreateServerFactory(std::move(pipe.handle0),
- io_task_runner);
+ IPC::ChannelMojo::CreateServerFactory(
+ std::move(pipe.handle0), io_task_runner,
+ base::ThreadTaskRunnerHandle::Get());
+
+ content::BindInterface(this, &child_control_interface_);
ResetChannelProxy();
@@ -1596,12 +1622,14 @@ void RenderProcessHostImpl::InitializeChannelProxy() {
// See crbug.com/526842 for details.
#if defined(OS_ANDROID)
if (GetContentClient()->UsingSynchronousCompositing()) {
- channel_ = IPC::SyncChannel::Create(
- this, io_task_runner.get(), &never_signaled_);
+ channel_ = IPC::SyncChannel::Create(this, io_task_runner.get(),
+ base::ThreadTaskRunnerHandle::Get(),
+ &never_signaled_);
}
#endif // OS_ANDROID
if (!channel_)
- channel_.reset(new IPC::ChannelProxy(this, io_task_runner.get()));
+ channel_.reset(new IPC::ChannelProxy(this, io_task_runner.get(),
+ base::ThreadTaskRunnerHandle::Get()));
channel_->Init(std::move(channel_factory), true /* create_pipe_now */);
// Note that Channel send is effectively paused and unpaused at various points
@@ -1693,26 +1721,21 @@ void RenderProcessHostImpl::CreateMessageFilters() {
BrowserMainLoop::GetInstance()->audio_manager();
MediaStreamManager* media_stream_manager =
BrowserMainLoop::GetInstance()->media_stream_manager();
- // The AudioInputRendererHost needs to be available for
- // lookup, so it's stashed in a member variable.
- audio_input_renderer_host_ = new AudioInputRendererHost(
+ AddFilter(new AudioInputRendererHost(
GetID(), audio_manager, media_stream_manager,
AudioMirroringManager::GetInstance(),
- BrowserMainLoop::GetInstance()->user_input_monitor());
- AddFilter(audio_input_renderer_host_.get());
+ BrowserMainLoop::GetInstance()->user_input_monitor()));
if (!RendererAudioOutputStreamFactoryContextImpl::UseMojoFactories()) {
AddFilter(base::MakeRefCounted<AudioRendererHost>(
GetID(), audio_manager,
BrowserMainLoop::GetInstance()->audio_system(),
- AudioMirroringManager::GetInstance(), media_stream_manager,
- browser_context->GetMediaDeviceIDSalt())
+ AudioMirroringManager::GetInstance(), media_stream_manager)
.get());
}
AddFilter(
new MidiHost(GetID(), BrowserMainLoop::GetInstance()->midi_service()));
AddFilter(new AppCacheDispatcherHost(
storage_partition_impl_->GetAppCacheService(), GetID()));
- AddFilter(new ClipboardMessageFilter(blob_storage_context));
AddFilter(new DOMStorageMessageFilter(
storage_partition_impl_->GetDOMStorageContext()));
@@ -1738,12 +1761,6 @@ void RenderProcessHostImpl::CreateMessageFilters() {
AddFilter(new TextInputClientMessageFilter());
#elif defined(OS_WIN)
AddFilter(new DWriteFontProxyMessageFilter());
-
- // The FontCacheDispatcher is required only when we're using GDI rendering.
- // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
- // GDI fonts (http://crbug.com/383227), even when using DirectWrite. This
- // should eventually be if (!ShouldUseDirectWrite()) guarded.
- channel_->AddFilter(new FontCacheDispatcher());
#endif
scoped_refptr<CacheStorageDispatcherHost> cache_storage_filter =
@@ -1765,9 +1782,6 @@ void RenderProcessHostImpl::CreateMessageFilters() {
AddFilter(new TraceMessageFilter(GetID()));
AddFilter(new ResolveProxyMsgHelper(request_context.get()));
- AddFilter(new QuotaDispatcherHost(
- GetID(), storage_partition_impl_->GetQuotaManager(),
- GetContentClient()->browser()->CreateQuotaPermissionContext()));
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context(
static_cast<ServiceWorkerContextWrapper*>(
@@ -1777,7 +1791,6 @@ void RenderProcessHostImpl::CreateMessageFilters() {
resource_context, service_worker_context, browser_context);
AddFilter(notification_message_filter_.get());
- AddFilter(new HistogramMessageFilter());
#if defined(OS_ANDROID)
synchronous_compositor_filter_ =
new SynchronousCompositorBrowserFilter(GetID());
@@ -1786,42 +1799,18 @@ void RenderProcessHostImpl::CreateMessageFilters() {
}
void RenderProcessHostImpl::RegisterMojoInterfaces() {
- auto registry = base::MakeUnique<service_manager::BinderRegistry>();
+ auto registry = std::make_unique<service_manager::BinderRegistry>();
channel_->AddAssociatedInterfaceForIOThread(
base::Bind(&IndexedDBDispatcherHost::AddBinding,
base::Unretained(indexed_db_factory_.get())));
AddUIThreadInterface(
- registry.get(),
- base::Bind(&ForwardRequest<shape_detection::mojom::BarcodeDetection>,
- shape_detection::mojom::kServiceName));
- AddUIThreadInterface(
- registry.get(),
- base::Bind(&ForwardRequest<shape_detection::mojom::FaceDetectionProvider>,
- shape_detection::mojom::kServiceName));
- AddUIThreadInterface(
- registry.get(),
- base::Bind(&ForwardRequest<shape_detection::mojom::TextDetection>,
- shape_detection::mojom::kServiceName));
-
- AddUIThreadInterface(
registry.get(), base::Bind(&ForwardRequest<device::mojom::BatteryMonitor>,
device::mojom::kServiceName));
AddUIThreadInterface(
registry.get(),
- base::Bind(&PermissionServiceContext::CreateService,
- base::Unretained(permission_service_context_.get())));
-
- AddUIThreadInterface(
- registry.get(),
- base::Bind(
- &PaymentAppContextImpl::CreatePaymentManager,
- base::Unretained(storage_partition_impl_->GetPaymentAppContext())));
-
- AddUIThreadInterface(
- registry.get(),
base::Bind(&RenderProcessHostImpl::CreateOffscreenCanvasProvider,
base::Unretained(this)));
@@ -1831,6 +1820,11 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
AddUIThreadInterface(
registry.get(),
+ base::Bind(&RenderProcessHostImpl::BindCompositingModeReporter,
+ base::Unretained(this)));
+
+ AddUIThreadInterface(
+ registry.get(),
base::Bind(&RenderProcessHostImpl::BindSharedBitmapAllocationNotifier,
base::Unretained(this)));
@@ -1841,12 +1835,6 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
storage_partition_impl_->GetBackgroundSyncContext())));
AddUIThreadInterface(
registry.get(),
- base::Bind(&PlatformNotificationContextImpl::CreateService,
- base::Unretained(
- storage_partition_impl_->GetPlatformNotificationContext()),
- GetID()));
- AddUIThreadInterface(
- registry.get(),
base::Bind(&RenderProcessHostImpl::CreateStoragePartitionService,
base::Unretained(this)));
AddUIThreadInterface(
@@ -1859,11 +1847,26 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
registry.get(), base::Bind(&CreateMemoryCoordinatorHandle, GetID()));
}
if (resource_coordinator::IsResourceCoordinatorEnabled()) {
- AddUIThreadInterface(registry.get(),
- base::Bind(&CreateResourceCoordinatorProcessInterface,
- base::Unretained(this)));
+ AddUIThreadInterface(
+ registry.get(),
+ base::Bind(&CreateProcessResourceCoordinator, base::Unretained(this)));
}
+ BrowserContext* browser_context = GetBrowserContext();
+ scoped_refptr<ChromeBlobStorageContext> blob_storage_context =
+ ChromeBlobStorageContext::GetFor(browser_context);
+
+ AddUIThreadInterface(
+ registry.get(),
+ base::Bind(&ClipboardHostImpl::Create, std::move(blob_storage_context)));
+
+ media::VideoDecodePerfHistory* video_perf_history =
+ GetBrowserContext()->GetVideoDecodePerfHistory();
+ AddUIThreadInterface(
+ registry.get(),
+ base::BindRepeating(&media::VideoDecodePerfHistory::BindRequest,
+ base::Unretained(video_perf_history)));
+
registry->AddInterface(
base::Bind(&MimeRegistryImpl::Create),
base::CreateSequencedTaskRunnerWithTraits(
@@ -1874,6 +1877,8 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
hyphenation::HyphenationImpl::GetTaskRunner());
#endif
+ registry->AddInterface(base::Bind(&device::GamepadHapticsManager::Create));
+
registry->AddInterface(base::Bind(&device::GamepadMonitor::Create));
registry->AddInterface(
@@ -1885,8 +1890,12 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
base::WrapRefCounted(
storage_partition_impl_->GetBackgroundFetchContext())));
- registry->AddInterface(base::Bind(&RenderProcessHostImpl::CreateMusGpuRequest,
- base::Unretained(this)));
+ if (gpu_client_) {
+ // |gpu_client_| outlives the registry, because its destruction is posted to
+ // IO thread from the destructor of |this|.
+ registry->AddInterface(
+ base::Bind(&GpuClient::Add, base::Unretained(gpu_client_.get())));
+ }
registry->AddInterface(
base::Bind(
@@ -1906,36 +1915,34 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
{base::MayBlock(), base::TaskPriority::USER_VISIBLE}));
#if BUILDFLAG(ENABLE_WEBRTC)
- registry->AddInterface(base::Bind(
- &RenderProcessHostImpl::CreateMediaStreamDispatcherHost,
- base::Unretained(this), GetBrowserContext()->GetMediaDeviceIDSalt(),
- media_stream_manager));
+ registry->AddInterface(
+ base::Bind(&RenderProcessHostImpl::CreateMediaStreamDispatcherHost,
+ base::Unretained(this), media_stream_manager));
#endif
registry->AddInterface(
base::Bind(&metrics::CreateSingleSampleMetricsProvider));
+ registry->AddInterface(base::Bind(
+ QuotaDispatcherHost::Create, GetID(),
+ base::RetainedRef(storage_partition_impl_->GetQuotaManager()),
+ base::WrapRefCounted(
+ GetContentClient()->browser()->CreateQuotaPermissionContext())));
+
registry->AddInterface(
base::Bind(&CreateReportingServiceProxy, storage_partition_impl_));
- // This is to support usage of WebSockets in cases in which there is no
- // associated RenderFrame (e.g., Shared Workers).
- AddUIThreadInterface(registry.get(),
- base::Bind(&WebSocketManager::CreateWebSocket, GetID(),
- MSG_ROUTING_NONE));
-
AddUIThreadInterface(registry.get(), base::Bind(&FieldTrialRecorder::Create));
associated_interfaces_.reset(new AssociatedInterfaceRegistryImpl());
GetContentClient()->browser()->ExposeInterfacesToRenderer(
registry.get(), associated_interfaces_.get(), this);
- static_cast<AssociatedInterfaceRegistry*>(associated_interfaces_.get())
- ->AddInterface(base::Bind(&RenderProcessHostImpl::BindRouteProvider,
- base::Unretained(this)));
-
- AddUIThreadInterface(registry.get(),
- base::Bind(&RenderProcessHostImpl::CreateRendererHost,
- base::Unretained(this)));
+ blink::AssociatedInterfaceRegistry* associated_registry =
+ associated_interfaces_.get();
+ associated_registry->AddInterface(base::Bind(
+ &RenderProcessHostImpl::BindRouteProvider, base::Unretained(this)));
+ associated_registry->AddInterface(base::Bind(
+ &RenderProcessHostImpl::CreateRendererHost, base::Unretained(this)));
if (base::FeatureList::IsEnabled(features::kNetworkService)) {
AddUIThreadInterface(
@@ -1950,9 +1957,6 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
storage_partition_impl_->GetBlobRegistry(), GetID()));
}
- registry->AddInterface(
- base::Bind(&media::VideoDecodePerfHistory::BindRequest));
-
ServiceManagerConnection* service_manager_connection =
BrowserContext::GetServiceManagerConnectionFor(browser_context_);
std::unique_ptr<ConnectionFilterImpl> connection_filter(
@@ -1998,20 +2002,13 @@ void RenderProcessHostImpl::GetBlobURLLoaderFactory(
std::move(request));
}
-void RenderProcessHostImpl::CreateMusGpuRequest(ui::mojom::GpuRequest request) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!gpu_client_)
- gpu_client_.reset(new GpuClient(GetID()));
- gpu_client_->Add(std::move(request));
-}
-
void RenderProcessHostImpl::CreateOffscreenCanvasProvider(
blink::mojom::OffscreenCanvasProviderRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!offscreen_canvas_provider_) {
// The client id gets converted to a uint32_t in FrameSinkId.
uint32_t renderer_client_id = base::checked_cast<uint32_t>(id_);
- offscreen_canvas_provider_ = base::MakeUnique<OffscreenCanvasProviderImpl>(
+ offscreen_canvas_provider_ = std::make_unique<OffscreenCanvasProviderImpl>(
GetHostFrameSinkManager(), renderer_client_id);
}
offscreen_canvas_provider_->Add(std::move(request));
@@ -2022,6 +2019,12 @@ void RenderProcessHostImpl::BindFrameSinkProvider(
frame_sink_provider_.Bind(std::move(request));
}
+void RenderProcessHostImpl::BindCompositingModeReporter(
+ viz::mojom::CompositingModeReporterRequest request) {
+ BrowserMainLoop::GetInstance()->GetCompositingModeReporter(
+ std::move(request));
+}
+
void RenderProcessHostImpl::BindSharedBitmapAllocationNotifier(
viz::mojom::SharedBitmapAllocationNotifierRequest request) {
shared_bitmap_allocation_notifier_impl_.Bind(std::move(request));
@@ -2041,7 +2044,7 @@ void RenderProcessHostImpl::CreateStoragePartitionService(
}
void RenderProcessHostImpl::CreateRendererHost(
- mojom::RendererHostRequest request) {
+ mojom::RendererHostAssociatedRequest request) {
renderer_host_binding_.Bind(std::move(request));
}
@@ -2121,32 +2124,29 @@ bool RenderProcessHostImpl::IsKeepAliveRefCountDisabled() {
}
void RenderProcessHostImpl::PurgeAndSuspend() {
- Send(new ChildProcessMsg_PurgeAndSuspend());
+ GetRendererInterface()->ProcessPurgeAndSuspend();
}
-void RenderProcessHostImpl::Resume() {
- Send(new ChildProcessMsg_Resume());
-}
+void RenderProcessHostImpl::Resume() {}
mojom::Renderer* RenderProcessHostImpl::GetRendererInterface() {
return renderer_interface_.get();
}
-resource_coordinator::ResourceCoordinatorInterface*
+resource_coordinator::ProcessResourceCoordinator*
RenderProcessHostImpl::GetProcessResourceCoordinator() {
if (process_resource_coordinator_)
return process_resource_coordinator_.get();
if (!resource_coordinator::IsResourceCoordinatorEnabled()) {
process_resource_coordinator_ =
- base::MakeUnique<resource_coordinator::ResourceCoordinatorInterface>(
- nullptr, resource_coordinator::CoordinationUnitType::kProcess);
+ std::make_unique<resource_coordinator::ProcessResourceCoordinator>(
+ nullptr);
} else {
auto* connection = ServiceManagerConnection::GetForProcess();
process_resource_coordinator_ =
- base::MakeUnique<resource_coordinator::ResourceCoordinatorInterface>(
- connection ? connection->GetConnector() : nullptr,
- resource_coordinator::CoordinationUnitType::kProcess);
+ std::make_unique<resource_coordinator::ProcessResourceCoordinator>(
+ connection ? connection->GetConnector() : nullptr);
}
return process_resource_coordinator_.get();
}
@@ -2288,10 +2288,9 @@ RenderProcessHostImpl::GetRendererAudioOutputStreamFactoryContext() {
BrowserMainLoop::GetInstance()->media_stream_manager();
media::AudioSystem* audio_system =
BrowserMainLoop::GetInstance()->audio_system();
- std::string salt = GetBrowserContext()->GetMediaDeviceIDSalt();
audio_output_stream_factory_context_.reset(
new RendererAudioOutputStreamFactoryContextImpl(
- GetID(), audio_system, audio_manager, media_stream_manager, salt));
+ GetID(), audio_system, audio_manager, media_stream_manager));
}
return audio_output_stream_factory_context_.get();
}
@@ -2497,7 +2496,7 @@ void RenderProcessHostImpl::AppendRendererCommandLine(
#if defined(OS_WIN)
command_line->AppendSwitchASCII(
switches::kDeviceScaleFactor,
- base::DoubleToString(display::win::GetDPIScale()));
+ base::NumberToString(display::win::GetDPIScale()));
#endif
AppendCompositorCommandLineFlags(command_line);
@@ -2515,6 +2514,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
// with any associated values) if present in the browser command line.
static const char* const kSwitchNames[] = {
service_manager::switches::kDisableInProcessStackTraces,
+ service_manager::switches::kDisableSeccompFilterSandbox,
switches::kAgcStartupMinVolume,
switches::kAecRefinedAdaptiveFilter,
switches::kAllowLoopbackInPeerConnection,
@@ -2536,7 +2536,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisableDistanceFieldText,
switches::kDisableFileSystem,
switches::kDisableGestureRequirementForPresentation,
- switches::kDisableGpuCompositing,
switches::kDisableGpuMemoryBufferVideoFrames,
switches::kDisableGpuVsync,
switches::kDisableLowResTiling,
@@ -2553,7 +2552,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisablePinch,
switches::kDisableRGBA4444Textures,
switches::kDisableRTCSmoothnessAlgorithm,
- switches::kDisableSeccompFilterSandbox,
switches::kDisableSharedWorkers,
switches::kDisableSkiaRuntimeOpts,
switches::kDisableSmoothScrolling,
@@ -2613,8 +2611,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kFullMemoryCrashReport,
switches::kIgnoreAutoplayRestrictionsForTests,
switches::kIPCConnectionTimeout,
- switches::kIsolateOrigins,
- switches::kIsRunningInMash,
switches::kJavaScriptFlags,
switches::kLoggingLevel,
switches::kMainFrameResizesAreOrientationChanges,
@@ -2630,7 +2626,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kPassiveListenersDefault,
switches::kPpapiInProcess,
switches::kReducedReferrerGranularity,
- switches::kReduceSecurityForTesting,
switches::kRegisterPepperPlugins,
switches::kRendererStartupDialog,
switches::kRootLayerScrolls,
@@ -2649,7 +2644,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kUseGpuInTests,
switches::kUseMobileUserAgent,
switches::kV,
- switches::kV8CacheStrategiesForCacheStorage,
switches::kVideoThreads,
switches::kVideoUnderflowThresholdMs,
switches::kVModule,
@@ -2694,6 +2688,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisallowNonExactResourceReuse,
#if defined(OS_ANDROID)
switches::kDisableMediaSessionAPI,
+ switches::kMadviseRandomExecutableCode,
switches::kRendererWaitForJavaDebugger,
#endif
#if defined(OS_MACOSX)
@@ -2701,7 +2696,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kEnableSandboxLogging,
#endif
#if defined(OS_WIN)
- switches::kDisableWin32kLockDown,
+ service_manager::switches::kDisableWin32kLockDown,
switches::kEnableWin7WebRtcHWH264Decoding,
switches::kTrySupportedChannelLayouts,
switches::kTraceExportEventsToETW,
@@ -2709,13 +2704,13 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
#if defined(USE_OZONE)
switches::kOzonePlatform,
#endif
-#if defined(OS_CHROMEOS)
- switches::kDisableVaapiAcceleratedVideoEncode,
-#endif
#if defined(ENABLE_IPC_FUZZER)
switches::kIpcDumpDirectory,
switches::kIpcFuzzerTestcase,
#endif
+#if BUILDFLAG(ENABLE_MUS)
+ switches::kMus,
+#endif
};
renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
arraysize(kSwitchNames));
@@ -2749,6 +2744,18 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
renderer_cmd->AppendSwitch(switches::kDisableDatabases);
}
+#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+ // 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,
+ // but the renderer will hear about the correct state eventually. This
+ // optimizes the common case to avoid wasted work.
+ // Note: There is no ImageTransportFactory with Mus, but there is also no
+ // software compositing on ChromeOS where Mus is used, so no need to check
+ // this state and forward it.
+ if (ImageTransportFactory::GetInstance()->IsGpuCompositingDisabled())
+ renderer_cmd->AppendSwitch(switches::kDisableGpuCompositing);
+#endif
+
// Add kWaitForDebugger to let renderer process wait for a debugger.
if (browser_cmd.HasSwitch(switches::kWaitForDebuggerChildren)) {
// Look to pass-on the kWaitForDebugger flag.
@@ -2805,7 +2812,9 @@ bool RenderProcessHostImpl::Shutdown(int exit_code, bool wait) {
bool RenderProcessHostImpl::FastShutdownIfPossible(size_t page_count,
bool skip_unload_handlers) {
- if (page_count && GetActiveViewCount() != page_count)
+ // Do not shut down the process if there are active or pending views other
+ // than the ones we're shutting down.
+ if (page_count && page_count != (GetActiveViewCount() + pending_views_))
return false;
if (run_renderer_in_process())
@@ -2877,10 +2886,6 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
if (msg.routing_id() == MSG_ROUTING_CONTROL) {
// Dispatch control messages.
IPC_BEGIN_MESSAGE_MAP(RenderProcessHostImpl, msg)
- IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
- OnShutdownRequest)
- IPC_MESSAGE_HANDLER(RenderProcessHostMsg_SuddenTerminationChanged,
- SuddenTerminationChanged)
IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
OnUserMetricsRecordAction)
IPC_MESSAGE_HANDLER(ViewHostMsg_Close_ACK, OnCloseACK)
@@ -2889,6 +2894,7 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
OnRegisterAecDumpConsumer)
IPC_MESSAGE_HANDLER(AecDumpMsg_UnregisterAecDumpConsumer,
OnUnregisterAecDumpConsumer)
+ IPC_MESSAGE_HANDLER(AudioProcessingMsg_Aec3Enabled, OnAec3Enabled)
#endif
// Adding single handlers for your service here is fine, but once your
// service needs more than one handler, please extract them into a new
@@ -2936,17 +2942,9 @@ void RenderProcessHostImpl::OnChannelConnected(int32_t peer_pid) {
}
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
- Send(new ChildProcessMsg_SetIPCLoggingEnabled(
- IPC::Logging::GetInstance()->Enabled()));
+ child_control_interface_->SetIPCLoggingEnabled(
+ IPC::Logging::GetInstance()->Enabled());
#endif
-
- // Inform AudioInputRendererHost about the new render process PID.
- // AudioInputRendererHost is reference counted, so its lifetime is
- // guaranteed during the lifetime of the closure.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AudioInputRendererHost::set_renderer_pid,
- audio_input_renderer_host_, peer_pid));
}
void RenderProcessHostImpl::OnChannelError() {
@@ -3027,8 +3025,11 @@ void RenderProcessHostImpl::Cleanup() {
return;
#if BUILDFLAG(ENABLE_WEBRTC)
- if (is_initialized_)
- ClearWebRtcLogMessageCallback();
+ if (is_initialized_) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&WebRtcLog::ClearLogMessageCallback, GetID()));
+ }
#endif
if (!keep_alive_start_time_.is_null()) {
@@ -3152,19 +3153,8 @@ void RenderProcessHostImpl::EnableAudioDebugRecordings(
// Enable AEC dump for each registered consumer.
base::FilePath file_with_extensions = GetAecDumpFilePathWithExtensions(file);
- for (std::vector<int>::iterator it = aec_dump_consumers_.begin();
- it != aec_dump_consumers_.end(); ++it) {
- EnableAecDumpForId(file_with_extensions, *it);
- }
-
- // Enable mic input recording. AudioInputRendererHost is reference counted, so
- // its lifetime is guaranteed during the lifetime of the closure.
- if (audio_input_renderer_host_) {
- // Not null if RenderProcessHostImpl::Init has already been called.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AudioInputRendererHost::EnableDebugRecording,
- audio_input_renderer_host_, file));
+ for (int id : aec_dump_consumers_) {
+ EnableAecDumpForId(file_with_extensions, id);
}
}
@@ -3178,16 +3168,6 @@ void RenderProcessHostImpl::DisableAudioDebugRecordings() {
FROM_HERE, base::BindOnce(&base::DoNothing),
base::BindOnce(&RenderProcessHostImpl::SendDisableAecDumpToRenderer,
weak_factory_.GetWeakPtr()));
-
- // AudioInputRendererHost is reference counted, so it's lifetime is
- // guaranteed during the lifetime of the closure.
- if (audio_input_renderer_host_) {
- // Not null if RenderProcessHostImpl::Init has already been called.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AudioInputRendererHost::DisableDebugRecording,
- audio_input_renderer_host_));
- }
}
bool RenderProcessHostImpl::StartWebRTCEventLog(
@@ -3199,36 +3179,22 @@ bool RenderProcessHostImpl::StopWebRTCEventLog() {
return webrtc_eventlog_host_.StopWebRTCEventLog();
}
-void RenderProcessHostImpl::SetEchoCanceller3(bool enable) {
+void RenderProcessHostImpl::SetEchoCanceller3(
+ bool enable,
+ base::OnceCallback<void(bool, const std::string&)> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // TODO(hlundin) Implement a test to verify that the setting works both with
- // aec_dump_consumers already registered, and with those registered in the
- // future. crbug.com/740104
- override_aec3_ = enable;
+ DCHECK(!callback.is_null());
- // Piggybacking on AEC dumps.
- // TODO(hlundin): Change name for aec_dump_consumers_;
- // http://crbug.com/709919.
- for (std::vector<int>::iterator it = aec_dump_consumers_.begin();
- it != aec_dump_consumers_.end(); ++it) {
- Send(new AudioProcessingMsg_EnableAec3(*it, enable));
+ 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"));
+ return;
}
-}
-void RenderProcessHostImpl::SetWebRtcLogMessageCallback(
- base::Callback<void(const std::string&)> callback) {
-#if BUILDFLAG(ENABLE_WEBRTC)
- BrowserMainLoop::GetInstance()->media_stream_manager()->
- RegisterNativeLogCallback(GetID(), callback);
-#endif
-}
-
-void RenderProcessHostImpl::ClearWebRtcLogMessageCallback() {
-#if BUILDFLAG(ENABLE_WEBRTC)
- BrowserMainLoop::GetInstance()
- ->media_stream_manager()
- ->UnregisterNativeLogCallback(GetID());
-#endif
+ aec3_set_callback_ = std::move(callback);
+ Send(new AudioProcessingMsg_EnableAec3(enable));
}
RenderProcessHostImpl::WebRtcStopRtpDumpCallback
@@ -3251,7 +3217,7 @@ RenderProcessHostImpl::StartRtpDump(
}
return stop_rtp_dump_callback_;
}
-#endif
+#endif // BUILDFLAG(ENABLE_WEBRTC)
IPC::ChannelProxy* RenderProcessHostImpl::GetChannel() {
return channel_.get();
@@ -3356,8 +3322,9 @@ bool RenderProcessHostImpl::IsSuitableHost(RenderProcessHost* host,
ChildProcessSecurityPolicyImpl::CheckOriginLockResult::NO_LOCK) {
// If the process is already dedicated to a site, only allow the destination
// URL to reuse this process if the URL has the same site.
- return lock_state == ChildProcessSecurityPolicyImpl::CheckOriginLockResult::
- HAS_EQUAL_LOCK;
+ if (lock_state !=
+ ChildProcessSecurityPolicyImpl::CheckOriginLockResult::HAS_EQUAL_LOCK)
+ return false;
} else if (!host->IsUnused() && SiteInstanceImpl::ShouldLockToOrigin(
browser_context, host, site_url)) {
// Otherwise, if this process has been used to host any other content, it
@@ -3414,6 +3381,19 @@ RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
}
// static
+RenderProcessHost* RenderProcessHost::FromRendererIdentity(
+ const service_manager::Identity& identity) {
+ for (content::RenderProcessHost::iterator i(
+ content::RenderProcessHost::AllHostsIterator());
+ !i.IsAtEnd(); i.Advance()) {
+ content::RenderProcessHost* process = i.GetCurrentValue();
+ if (process->GetChildIdentity() == identity)
+ return process;
+ }
+ return nullptr;
+}
+
+// static
bool RenderProcessHost::ShouldTryToUseExistingProcessHost(
BrowserContext* browser_context,
const GURL& url) {
@@ -3461,7 +3441,7 @@ RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
return suitable_renderers[random_index];
}
- return NULL;
+ return nullptr;
}
// static
@@ -3509,7 +3489,7 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSite(
RecordAction(
base::UserMetricsAction("BindingsMismatch_GetProcessHostPerSite"));
map->RemoveProcess(host);
- host = NULL;
+ host = nullptr;
}
return host;
@@ -3584,6 +3564,22 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSiteInstance(
render_process_host = GetExistingProcessHost(browser_context, site_url);
}
+ // If we found a process to reuse, sanity check that it is suitable for
+ // hosting |site_url|. For example, if |site_url| requires a dedicated
+ // process, we should never pick a process used by, or locked to, a different
+ // site.
+ if (render_process_host &&
+ !RenderProcessHostImpl::IsSuitableHost(render_process_host,
+ browser_context, site_url)) {
+ ChildProcessSecurityPolicyImpl* policy =
+ ChildProcessSecurityPolicyImpl::GetInstance();
+ base::debug::SetCrashKeyValue("requested_site_url", site_url.spec());
+ base::debug::SetCrashKeyValue(
+ "killed_process_origin_lock",
+ policy->GetOriginLock(render_process_host->GetID()).spec());
+ CHECK(false) << "Unsuitable process reused for site " << site_url;
+ }
+
// Otherwise, use the spare RenderProcessHost or create a new one.
if (!render_process_host) {
// Pass a null StoragePartition. Tests with TestBrowserContext using a
@@ -3729,6 +3725,8 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead,
if (renderer_host_binding_.is_bound())
renderer_host_binding_.Unbind();
+ compositing_mode_reporter_.reset();
+
shared_bitmap_allocation_notifier_impl_.ChildDied();
HistogramController::GetInstance()->NotifyChildDied<RenderProcessHost>(this);
@@ -3770,19 +3768,25 @@ void RenderProcessHostImpl::ReleaseOnCloseACK(
holder->Hold(sessions, view_route_id);
}
-void RenderProcessHostImpl::OnShutdownRequest() {
+void RenderProcessHostImpl::ShutdownRequest() {
+ // Notify any contents that the renderer might shut down.
+ for (auto& observer : observers_) {
+ observer.RenderProcessShutdownRequested(this);
+ }
+
// Don't shut down if there are active RenderViews, or if there are pending
// RenderViews being swapped back in.
// In single process mode, we never shutdown the renderer.
- if (pending_views_ || run_renderer_in_process() || GetActiveViewCount() > 0)
+ if (pending_views_ || run_renderer_in_process() || GetActiveViewCount() > 0) {
return;
+ }
// Notify any contents that might have swapped out renderers from this
// process. They should not attempt to swap them back in.
- for (auto& observer : observers_)
+ for (auto& observer : observers_) {
observer.RenderProcessWillExit(this);
-
- Send(new ChildProcessMsg_Shutdown());
+ }
+ child_control_interface_->ProcessShutdown();
}
void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) {
@@ -3842,8 +3846,9 @@ void RenderProcessHostImpl::UpdateProcessPriority() {
// Notify the child process of background state. Note
// |priority_.boost_for_pending_views| state is not sent to renderer simply
// due to lack of need.
- if (should_background_changed)
- Send(new ChildProcessMsg_SetProcessBackgrounded(priority.background));
+ if (should_background_changed) {
+ GetRendererInterface()->SetProcessBackgrounded(priority.background);
+ }
}
void RenderProcessHostImpl::OnProcessLaunched() {
@@ -3922,9 +3927,8 @@ void RenderProcessHostImpl::OnProcessLaunched() {
observer.RenderProcessReady(this);
}
- GetProcessResourceCoordinator()->SetProperty(
- resource_coordinator::mojom::PropertyType::kPID,
- base::GetProcId(GetHandle()));
+ GetProcessResourceCoordinator()->SetLaunchTime(base::Time::Now());
+ GetProcessResourceCoordinator()->SetPID(base::GetProcId(GetHandle()));
#if BUILDFLAG(ENABLE_WEBRTC)
if (WebRTCInternals::GetInstance()->IsAudioDebugRecordingsEnabled()) {
@@ -4033,13 +4037,12 @@ RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSite(
#if BUILDFLAG(ENABLE_WEBRTC)
void RenderProcessHostImpl::CreateMediaStreamDispatcherHost(
- const std::string& salt,
MediaStreamManager* media_stream_manager,
mojom::MediaStreamDispatcherHostRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!media_stream_dispatcher_host_) {
media_stream_dispatcher_host_.reset(
- new MediaStreamDispatcherHost(GetID(), salt, media_stream_manager));
+ new MediaStreamDispatcherHost(GetID(), media_stream_manager));
}
media_stream_dispatcher_host_->BindRequest(std::move(request));
}
@@ -4068,20 +4071,14 @@ void RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread(int id) {
WebRTCInternals::GetInstance()->GetAudioDebugRecordingsFilePath());
EnableAecDumpForId(file_with_extensions, id);
}
- if (override_aec3_) {
- Send(new AudioProcessingMsg_EnableAec3(id, *override_aec3_));
- }
}
void RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread(int id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- for (std::vector<int>::iterator it = aec_dump_consumers_.begin();
- it != aec_dump_consumers_.end(); ++it) {
- if (*it == id) {
- aec_dump_consumers_.erase(it);
- break;
- }
- }
+ auto it =
+ std::find(aec_dump_consumers_.begin(), aec_dump_consumers_.end(), id);
+ if (it != aec_dump_consumers_.end())
+ aec_dump_consumers_.erase(it);
}
void RenderProcessHostImpl::EnableAecDumpForId(const base::FilePath& file,
@@ -4121,6 +4118,15 @@ base::SequencedTaskRunner& RenderProcessHostImpl::GetAecDumpFileTaskRunner() {
}
return *audio_debug_recordings_file_task_runner_;
}
+
+void RenderProcessHostImpl::OnAec3Enabled() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // The callback should be set unless the message from the renderer is
+ // spurious.
+ if (!aec3_set_callback_.is_null())
+ std::move(aec3_set_callback_).Run(true, std::string());
+}
#endif // BUILDFLAG(ENABLE_WEBRTC)
void RenderProcessHostImpl::RecomputeAndUpdateWebKitPreferences() {
@@ -4151,4 +4157,27 @@ RenderProcessHostImpl::GetSharedBitmapAllocationNotifier() {
return &shared_bitmap_allocation_notifier_impl_;
}
+void RenderProcessHostImpl::GetBrowserHistogram(
+ const std::string& name,
+ BrowserHistogramCallback callback) {
+ // Security: Only allow access to browser histograms when running in the
+ // context of a test.
+ bool using_stats_collection_controller =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kStatsCollectionController);
+ if (!using_stats_collection_controller) {
+ std::move(callback).Run(std::string());
+ return;
+ }
+ base::HistogramBase* histogram =
+ base::StatisticsRecorder::FindHistogram(name);
+ std::string histogram_json;
+ if (!histogram) {
+ histogram_json = "{}";
+ } else {
+ histogram->WriteJSON(&histogram_json, base::JSON_VERBOSITY_LEVEL_FULL);
+ }
+ std::move(callback).Run(histogram_json);
+}
+
} // namespace content
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 dd7df59cb5c..b5528d49e67 100644
--- a/chromium/content/browser/renderer_host/render_process_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_process_host_impl.h
@@ -30,6 +30,7 @@
#include "content/browser/webrtc/webrtc_eventlog_host.h"
#include "content/common/associated_interface_registry_impl.h"
#include "content/common/associated_interfaces.mojom.h"
+#include "content/common/child_control.mojom.h"
#include "content/common/content_export.h"
#include "content/common/indexed_db/indexed_db.mojom.h"
#include "content/common/media/media_stream.mojom.h"
@@ -50,6 +51,7 @@
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/interfaces/service.mojom.h"
#include "services/ui/public/interfaces/gpu.mojom.h"
+#include "services/viz/public/interfaces/compositing/compositing_mode_watcher.mojom.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gl/gpu_switching_observer.h"
@@ -65,16 +67,11 @@ class SharedPersistentMemoryAllocator;
}
namespace content {
-class AudioInputRendererHost;
class ChildConnection;
class GpuClient;
class IndexedDBDispatcherHost;
class InProcessChildThreadParams;
class NotificationMessageFilter;
-#if BUILDFLAG(ENABLE_WEBRTC)
-class MediaStreamDispatcherHost;
-class P2PSocketDispatcherHost;
-#endif
class PermissionServiceContext;
class PeerConnectionTrackerHost;
class PushMessagingManager;
@@ -89,6 +86,11 @@ class SiteInstanceImpl;
class StoragePartition;
class StoragePartitionImpl;
+#if BUILDFLAG(ENABLE_WEBRTC)
+class MediaStreamDispatcherHost;
+class P2PSocketDispatcherHost;
+#endif
+
typedef base::Thread* (*RendererMainThreadFactoryFunction)(
const InProcessChildThreadParams& params);
@@ -191,10 +193,9 @@ class CONTENT_EXPORT RenderProcessHostImpl
void DisableAudioDebugRecordings() override;
bool StartWebRTCEventLog(const base::FilePath& file_path) override;
bool StopWebRTCEventLog() override;
- void SetEchoCanceller3(bool enable) override;
- void SetWebRtcLogMessageCallback(
- base::Callback<void(const std::string&)> callback) override;
- void ClearWebRtcLogMessageCallback() override;
+ void SetEchoCanceller3(
+ bool enable,
+ base::OnceCallback<void(bool, const std::string&)> callback) override;
WebRtcStopRtpDumpCallback StartRtpDump(
bool incoming,
bool outgoing,
@@ -215,7 +216,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
void PurgeAndSuspend() override;
void Resume() override;
mojom::Renderer* GetRendererInterface() override;
- resource_coordinator::ResourceCoordinatorInterface*
+ resource_coordinator::ProcessResourceCoordinator*
GetProcessResourceCoordinator() override;
void SetIsNeverSuitableForReuse() override;
@@ -387,6 +388,10 @@ class CONTENT_EXPORT RenderProcessHostImpl
// globally-used spare RenderProcessHost at any time.
static RenderProcessHost* GetSpareRenderProcessHostForTesting();
+ PermissionServiceContext& permission_service_context() {
+ return *permission_service_context_;
+ }
+
protected:
// A proxy for our IPC::Channel that lives on the IO thread.
std::unique_ptr<IPC::ChannelProxy> channel_;
@@ -446,23 +451,28 @@ class CONTENT_EXPORT RenderProcessHostImpl
// mojom::RendererHost
void GetBlobURLLoaderFactory(mojom::URLLoaderFactoryRequest request) override;
+ using BrowserHistogramCallback =
+ mojom::RendererHost::GetBrowserHistogramCallback;
+ void GetBrowserHistogram(const std::string& name,
+ BrowserHistogramCallback callback) override;
+ void SuddenTerminationChanged(bool enabled) override;
+ void ShutdownRequest() override;
void BindRouteProvider(mojom::RouteProviderAssociatedRequest request);
- void CreateMusGpuRequest(ui::mojom::GpuRequest request);
void CreateOffscreenCanvasProvider(
blink::mojom::OffscreenCanvasProviderRequest request);
void BindFrameSinkProvider(mojom::FrameSinkProviderRequest request);
+ void BindCompositingModeReporter(
+ viz::mojom::CompositingModeReporterRequest request);
void BindSharedBitmapAllocationNotifier(
viz::mojom::SharedBitmapAllocationNotifierRequest request);
void CreateStoragePartitionService(
mojom::StoragePartitionServiceRequest request);
- void CreateRendererHost(mojom::RendererHostRequest request);
+ void CreateRendererHost(mojom::RendererHostAssociatedRequest request);
void CreateURLLoaderFactory(mojom::URLLoaderFactoryRequest request);
// Control message handlers.
- void OnShutdownRequest();
- void SuddenTerminationChanged(bool enabled);
void OnUserMetricsRecordAction(const std::string& action);
void OnCloseACK(int old_route_id);
@@ -508,7 +518,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
#if BUILDFLAG(ENABLE_WEBRTC)
void CreateMediaStreamDispatcherHost(
- const std::string& salt,
MediaStreamManager* media_stream_manager,
mojom::MediaStreamDispatcherHostRequest request);
void OnRegisterAecDumpConsumer(int id);
@@ -522,6 +531,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
void SendDisableAecDumpToRenderer();
base::FilePath GetAecDumpFilePathWithExtensions(const base::FilePath& file);
base::SequencedTaskRunner& GetAecDumpFileTaskRunner();
+ void OnAec3Enabled();
#endif
static void OnMojoError(int render_process_id, const std::string& error);
@@ -695,14 +705,12 @@ class CONTENT_EXPORT RenderProcessHostImpl
BrowserThread::DeleteOnIOThread>
audio_output_stream_factory_context_;
- scoped_refptr<AudioInputRendererHost> audio_input_renderer_host_;
-
#if BUILDFLAG(ENABLE_WEBRTC)
scoped_refptr<P2PSocketDispatcherHost> p2p_socket_dispatcher_host_;
// Must be accessed on UI thread.
std::vector<int> aec_dump_consumers_;
- base::Optional<bool> override_aec3_;
+ base::OnceCallback<void(bool, const std::string&)> aec3_set_callback_;
WebRtcStopRtpDumpCallback stop_rtp_dump_callback_;
@@ -753,15 +761,16 @@ class CONTENT_EXPORT RenderProcessHostImpl
std::unique_ptr<OffscreenCanvasProviderImpl> offscreen_canvas_provider_;
+ mojom::ChildControlPtr child_control_interface_;
mojom::RouteProviderAssociatedPtr remote_route_provider_;
mojom::RendererAssociatedPtr renderer_interface_;
- mojo::Binding<mojom::RendererHost> renderer_host_binding_;
+ mojo::AssociatedBinding<mojom::RendererHost> renderer_host_binding_;
// Tracks active audio and video streams within the render process; used to
// determine if if a process should be backgrounded.
int media_stream_count_ = 0;
- std::unique_ptr<resource_coordinator::ResourceCoordinatorInterface>
+ std::unique_ptr<resource_coordinator::ProcessResourceCoordinator>
process_resource_coordinator_;
// A WeakPtrFactory which is reset every time Cleanup() runs. Used to vend
@@ -770,6 +779,8 @@ class CONTENT_EXPORT RenderProcessHostImpl
instance_weak_factory_;
FrameSinkProviderImpl frame_sink_provider_;
+ std::unique_ptr<mojo::Binding<viz::mojom::CompositingModeReporter>>
+ compositing_mode_reporter_;
viz::SharedBitmapAllocationNotifierImpl
shared_bitmap_allocation_notifier_impl_;
diff --git a/chromium/content/browser/renderer_host/render_process_host_unittest.cc b/chromium/content/browser/renderer_host/render_process_host_unittest.cc
index 01e3171e028..a6ecd7ae3a6 100644
--- a/chromium/content/browser/renderer_host/render_process_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_unittest.cc
@@ -12,6 +12,7 @@
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "content/common/frame_messages.h"
+#include "content/common/frame_owner_properties.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/browser_side_navigation_policy.h"
@@ -24,7 +25,7 @@
#include "content/test/test_render_frame_host.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "third_party/WebKit/common/frame_policy.h"
namespace content {
@@ -66,7 +67,7 @@ TEST_F(RenderProcessHostUnitTest, RendererProcessLimit) {
ASSERT_NE(0u, kMaxRendererProcessCount);
std::vector<std::unique_ptr<MockRenderProcessHost>> hosts;
for (size_t i = 0; i < kMaxRendererProcessCount; ++i) {
- hosts.push_back(base::MakeUnique<MockRenderProcessHost>(browser_context()));
+ hosts.push_back(std::make_unique<MockRenderProcessHost>(browser_context()));
}
// Verify that the renderer sharing will happen.
@@ -77,7 +78,7 @@ TEST_F(RenderProcessHostUnitTest, RendererProcessLimit) {
#endif
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
-TEST_F(RenderProcessHostUnitTest, NoRendererProcessLimitOnAndroid) {
+TEST_F(RenderProcessHostUnitTest, NoRendererProcessLimitOnAndroidOrChromeOS) {
// Disable any overrides.
RenderProcessHostImpl::SetMaxRendererProcessCount(0);
@@ -85,7 +86,7 @@ TEST_F(RenderProcessHostUnitTest, NoRendererProcessLimitOnAndroid) {
ASSERT_NE(0u, kMaxRendererProcessCount);
std::vector<std::unique_ptr<MockRenderProcessHost>> hosts;
for (size_t i = 0; i < kMaxRendererProcessCount; ++i) {
- hosts.push_back(base::MakeUnique<MockRenderProcessHost>(browser_context()));
+ hosts.push_back(std::make_unique<MockRenderProcessHost>(browser_context()));
}
// Verify that the renderer sharing still won't happen.
@@ -129,9 +130,10 @@ TEST_F(RenderProcessHostUnitTest, ReuseCommittedSite) {
// return the process of the subframe RFH.
std::string unique_name("uniqueName0");
main_test_rfh()->OnCreateChildFrame(
- process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument,
- std::string(), unique_name, base::UnguessableToken::Create(),
- blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(),
+ process()->GetNextRoutingID(),
+ TestRenderFrameHost::CreateStubInterfaceProviderRequest(),
+ blink::WebTreeScopeType::kDocument, std::string(), unique_name, false,
+ base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>(
contents()->GetFrameTree()->root()->child_at(0)->current_frame_host());
@@ -213,6 +215,50 @@ TEST_F(RenderProcessHostUnitTest, ReuseUnmatchedServiceWorkerProcess) {
EXPECT_NE(sw_host2, site_instance3->GetProcess());
}
+class UnsuitableHostContentBrowserClient : public ContentBrowserClient {
+ public:
+ UnsuitableHostContentBrowserClient() {}
+ ~UnsuitableHostContentBrowserClient() override {}
+
+ private:
+ bool IsSuitableHost(RenderProcessHost* process_host,
+ const GURL& site_url) override {
+ return false;
+ }
+};
+
+// Check that an unmatched ServiceWorker process is not reused when it's not a
+// suitable host for the destination URL. See https://crbug.com/782349.
+TEST_F(RenderProcessHostUnitTest,
+ DontReuseUnsuitableUnmatchedServiceWorkerProcess) {
+ const GURL kUrl("https://foo.com");
+
+ // Gets a RenderProcessHost for an unmatched service worker.
+ scoped_refptr<SiteInstanceImpl> sw_site_instance =
+ SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
+ sw_site_instance->set_is_for_service_worker();
+ RenderProcessHost* sw_host = sw_site_instance->GetProcess();
+
+ // Simulate a situation where |sw_host| won't be considered suitable for
+ // future navigations to |kUrl|. In https://crbug.com/782349, this happened
+ // when |kUrl| corresponded to a nonexistent extension, but
+ // chrome-extension:// URLs can't be tested inside content/. Instead,
+ // install a ContentBrowserClient which will return false when IsSuitableHost
+ // is consulted.
+ UnsuitableHostContentBrowserClient modified_client;
+ ContentBrowserClient* regular_client =
+ SetBrowserClientForTesting(&modified_client);
+
+ // Now, getting a RenderProcessHost for a navigation to the same site should
+ // not reuse the unmatched service worker's process (i.e., |sw_host|), as
+ // it's unsuitable.
+ scoped_refptr<SiteInstanceImpl> site_instance =
+ SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
+ EXPECT_NE(sw_host, site_instance->GetProcess());
+
+ SetBrowserClientForTesting(regular_client);
+}
+
TEST_F(RenderProcessHostUnitTest, ReuseServiceWorkerProcessForServiceWorker) {
const GURL kUrl("https://foo.com");
@@ -359,18 +405,26 @@ TEST_F(RenderProcessHostUnitTest, DoNotReuseError) {
// Navigate back and simulate an error. Getting a RenderProcessHost with the
// REUSE_PENDING_OR_COMMITTED_SITE policy should return a new process.
- web_contents()->GetController().GoBack();
- TestRenderFrameHost* pending_rfh = contents()->GetPendingMainFrame();
- if (!IsBrowserSideNavigationEnabled())
- pending_rfh->SimulateNavigationStart(kUrl1);
- pending_rfh->SimulateNavigationError(kUrl1, net::ERR_TIMED_OUT);
- pending_rfh->SimulateNavigationErrorPageCommit();
+ NavigationSimulator::GoBackAndFail(contents(), net::ERR_TIMED_OUT);
site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl1);
site_instance->set_process_reuse_policy(
SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE);
EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess());
}
+// Tests that RenderProcessHost will not consider reusing a process that is
+// marked as never suitable for reuse, according to MayReuseHost().
+TEST_F(RenderProcessHostUnitTest, DoNotReuseHostThatIsNeverSuitableForReuse) {
+ const GURL kUrl("http://foo.com");
+ NavigateAndCommit(kUrl);
+ main_test_rfh()->GetProcess()->SetIsNeverSuitableForReuse();
+ scoped_refptr<SiteInstanceImpl> site_instance =
+ SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
+ site_instance->set_process_reuse_policy(
+ SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE);
+ EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess());
+}
+
// Tests that RenderProcessHost reuse considers navigations correctly.
TEST_F(RenderProcessHostUnitTest, ReuseNavigationProcess) {
// This is only applicable to PlzNavigate.
@@ -595,26 +649,6 @@ TEST_F(RenderProcessHostUnitTest,
EXPECT_EQ(speculative_process_host_id, site_instance->GetProcess()->GetID());
}
-class EffectiveURLContentBrowserClient : public ContentBrowserClient {
- public:
- EffectiveURLContentBrowserClient(const GURL& url_to_modify,
- const GURL& url_to_return)
- : url_to_modify_(url_to_modify), url_to_return_(url_to_return) {}
- ~EffectiveURLContentBrowserClient() override {}
-
- private:
- GURL GetEffectiveURL(BrowserContext* browser_context,
- const GURL& url,
- bool is_isolated_origin) override {
- if (url == url_to_modify_)
- return url_to_return_;
- return url;
- }
-
- GURL url_to_modify_;
- GURL url_to_return_;
-};
-
// Tests that RenderProcessHost reuse works correctly even if the site URL of a
// URL changes.
TEST_F(RenderProcessHostUnitTest, ReuseSiteURLChanges) {
@@ -867,7 +901,7 @@ class SpareRenderProcessHostUnitTest : public RenderViewHostImplTestHarness {
void SetUp() override {
SetRenderProcessHostFactory(&rph_factory_);
RenderViewHostImplTestHarness::SetUp();
- SetContents(NULL); // Start with no renderers.
+ SetContents(nullptr); // Start with no renderers.
while (!rph_factory_.GetProcesses()->empty()) {
rph_factory_.Remove(rph_factory_.GetProcesses()->back().get());
}
diff --git a/chromium/content/browser/renderer_host/render_view_host_delegate.cc b/chromium/content/browser/renderer_host/render_view_host_delegate.cc
index 6f563658efd..6ceb1543e01 100644
--- a/chromium/content/browser/renderer_host/render_view_host_delegate.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_delegate.cc
@@ -10,7 +10,7 @@
namespace content {
RenderViewHostDelegateView* RenderViewHostDelegate::GetDelegateView() {
- return NULL;
+ return nullptr;
}
bool RenderViewHostDelegate::OnMessageReceived(
@@ -20,12 +20,12 @@ bool RenderViewHostDelegate::OnMessageReceived(
}
WebContents* RenderViewHostDelegate::GetAsWebContents() {
- return NULL;
+ return nullptr;
}
SessionStorageNamespace* RenderViewHostDelegate::GetSessionStorageNamespace(
SiteInstance* instance) {
- return NULL;
+ return nullptr;
}
SessionStorageNamespaceMap
@@ -34,7 +34,7 @@ RenderViewHostDelegate::GetSessionStorageNamespaceMap() {
}
FrameTree* RenderViewHostDelegate::GetFrameTree() {
- return NULL;
+ return nullptr;
}
double RenderViewHostDelegate::GetPendingPageZoomLevel() {
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 36d6c4886f2..9b01a0dd1e0 100644
--- a/chromium/content/browser/renderer_host/render_view_host_delegate.h
+++ b/chromium/content/browser/renderer_host/render_view_host_delegate.h
@@ -96,9 +96,6 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// The page is trying to move the RenderView's representation in the client.
virtual void RequestMove(const gfx::Rect& new_bounds) {}
- // The pending page load was canceled.
- virtual void DidCancelLoading() {}
-
// The RenderView's main frame document element is ready. This happens when
// the document has finished parsing.
virtual void DocumentAvailableInMainFrame(RenderViewHost* render_view_host) {}
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 1261d1d4112..fa8f1daeada 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
@@ -13,4 +13,16 @@ content::RenderViewHostDelegateView::GetOverscrollRefreshHandler() const {
}
#endif
+int RenderViewHostDelegateView::GetTopControlsHeight() const {
+ return 0;
+}
+
+int RenderViewHostDelegateView::GetBottomControlsHeight() const {
+ return 0;
+}
+
+bool RenderViewHostDelegateView::DoBrowserControlsShrinkBlinkSize() const {
+ return false;
+}
+
} // namespace content
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 71ca5d275e3..4578feccfa6 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
@@ -69,6 +69,15 @@ class CONTENT_EXPORT RenderViewHostDelegateView {
// retrieved by doing a Shift-Tab.
virtual void TakeFocus(bool reverse) {}
+ // Returns the height of the top controls in DIP.
+ virtual int GetTopControlsHeight() const;
+
+ // 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;
+
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
// Shows a popup menu with the specified items.
// This method should call RenderFrameHost::DidSelectPopupMenuItem[s]() or
diff --git a/chromium/content/browser/renderer_host/render_view_host_factory.cc b/chromium/content/browser/renderer_host/render_view_host_factory.cc
index 831b6c7e8ca..c6b6cf1e873 100644
--- a/chromium/content/browser/renderer_host/render_view_host_factory.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_factory.cc
@@ -50,7 +50,7 @@ RenderViewHost* RenderViewHostFactory::Create(
}
return new RenderViewHostImpl(
instance,
- base::MakeUnique<RenderWidgetHostImpl>(
+ std::make_unique<RenderWidgetHostImpl>(
widget_delegate, instance->GetProcess(), routing_id, nullptr, hidden),
delegate, main_frame_routing_id, swapped_out,
true /* has_initialized_audio_host */);
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 0c73c1a37c3..bf19ad4f46e 100644
--- a/chromium/content/browser/renderer_host/render_view_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_impl.cc
@@ -83,6 +83,7 @@
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/device_form_factor.h"
#include "ui/base/touch/touch_device.h"
+#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/display/display_switches.h"
#include "ui/gfx/animation/animation.h"
@@ -307,6 +308,8 @@ bool RenderViewHostImpl::CreateRenderView(
RenderFrameHostImpl* main_rfh = RenderFrameHostImpl::FromID(
GetProcess()->GetID(), main_frame_routing_id_);
DCHECK(main_rfh);
+ main_rfh->BindInterfaceProviderRequest(
+ mojo::MakeRequest(&params->main_frame_interface_provider));
RenderWidgetHostImpl* main_rwh = main_rfh->GetRenderWidgetHost();
params->main_frame_widget_routing_id = main_rwh->GetRoutingID();
}
@@ -388,20 +391,16 @@ WebPreferences RenderViewHostImpl::ComputeWebkitPrefs() {
!command_line.HasSwitch(switches::kDisablePepper3d);
prefs.flash_3d_enabled =
- GpuProcessHost::gpu_enabled() &&
!command_line.HasSwitch(switches::kDisableFlash3d);
prefs.flash_stage3d_enabled =
- GpuProcessHost::gpu_enabled() &&
!command_line.HasSwitch(switches::kDisableFlashStage3d);
prefs.flash_stage3d_baseline_enabled =
- GpuProcessHost::gpu_enabled() &&
!command_line.HasSwitch(switches::kDisableFlashStage3d);
prefs.allow_file_access_from_file_urls =
command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
prefs.accelerated_2d_canvas_enabled =
- GpuProcessHost::gpu_enabled() &&
!command_line.HasSwitch(switches::kDisableAccelerated2dCanvas);
prefs.antialiased_2d_canvas_disabled =
command_line.HasSwitch(switches::kDisable2dCanvasAntialiasing);
@@ -937,12 +936,20 @@ void RenderViewHostImpl::DisableAutoResize(const gfx::Size& new_size) {
void RenderViewHostImpl::ExecuteMediaPlayerActionAtLocation(
const gfx::Point& location, const blink::WebMediaPlayerAction& action) {
+ // TODO(wjmaclean): See if coordinate transforms need to be done for OOPIFs
+ // and guest views. https://crbug.com/776807
Send(new ViewMsg_MediaPlayerActionAt(GetRoutingID(), location, action));
}
void RenderViewHostImpl::ExecutePluginActionAtLocation(
const gfx::Point& location, const blink::WebPluginAction& action) {
- Send(new ViewMsg_PluginActionAt(GetRoutingID(), location, action));
+ // TODO(wjmaclean): See if this needs to be done for OOPIFs as well.
+ // https://crbug.com/776807
+ gfx::PointF local_location_f =
+ GetWidget()->GetView()->TransformRootPointToViewCoordSpace(
+ gfx::PointF(location.x(), location.y()));
+ gfx::Point local_location(local_location_f.x(), local_location_f.y());
+ Send(new ViewMsg_PluginActionAt(GetRoutingID(), local_location, action));
}
void RenderViewHostImpl::NotifyMoveOrResizeStarted() {
diff --git a/chromium/content/browser/renderer_host/render_view_host_unittest.cc b/chromium/content/browser/renderer_host/render_view_host_unittest.cc
index 132ed24e33a..56d2d7c0c2f 100644
--- a/chromium/content/browser/renderer_host/render_view_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_unittest.cc
@@ -47,7 +47,7 @@ class RenderViewHostTestBrowserClient : public TestContentBrowserClient {
class RenderViewHostTest : public RenderViewHostImplTestHarness {
public:
- RenderViewHostTest() : old_browser_client_(NULL) {}
+ RenderViewHostTest() : old_browser_client_(nullptr) {}
~RenderViewHostTest() override {}
void SetUp() override {
@@ -83,7 +83,7 @@ TEST_F(RenderViewHostTest, CreateFullscreenWidget) {
mojom::WidgetPtr widget;
std::unique_ptr<MockWidgetImpl> widget_impl =
- base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
test_rvh()->CreateNewFullscreenWidget(routing_id, std::move(widget));
}
@@ -161,8 +161,8 @@ TEST_F(RenderViewHostTest, StartDragging) {
TEST_F(RenderViewHostTest, DragEnteredFileURLsStillBlocked) {
DropData dropped_data;
- gfx::Point client_point;
- gfx::Point screen_point;
+ gfx::PointF client_point;
+ gfx::PointF screen_point;
// We use "//foo/bar" path (rather than "/foo/bar") since dragged paths are
// expected to be absolute on any platforms.
base::FilePath highlighted_file_path(FILE_PATH_LITERAL("//tmp/foo.html"));
diff --git a/chromium/content/browser/renderer_host/render_widget_helper.cc b/chromium/content/browser/renderer_host/render_widget_helper.cc
index 98bc9bbd13a..6a7e9eef132 100644
--- a/chromium/content/browser/renderer_host/render_widget_helper.cc
+++ b/chromium/content/browser/renderer_host/render_widget_helper.cc
@@ -32,9 +32,7 @@ void AddWidgetHelper(int render_process_id,
} // namespace
RenderWidgetHelper::RenderWidgetHelper()
- : render_process_id_(-1),
- resource_dispatcher_host_(NULL) {
-}
+ : render_process_id_(-1), resource_dispatcher_host_(nullptr) {}
RenderWidgetHelper::~RenderWidgetHelper() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
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 9a97fd29dd9..9dbc1afad1e 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_delegate.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -31,12 +31,12 @@ bool RenderWidgetHostDelegate::PreHandleGestureEvent(
BrowserAccessibilityManager*
RenderWidgetHostDelegate::GetRootBrowserAccessibilityManager() {
- return NULL;
+ return nullptr;
}
BrowserAccessibilityManager*
RenderWidgetHostDelegate::GetOrCreateRootBrowserAccessibilityManager() {
- return NULL;
+ return nullptr;
}
// If a delegate does not override this, the RenderWidgetHostView will
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 3083f04a020..7b0d5cabbdc 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_delegate.h
@@ -75,16 +75,14 @@ class CONTENT_EXPORT RenderWidgetHostDelegate {
// The contents auto-resized and the container should match it.
virtual void ResizeDueToAutoResize(RenderWidgetHostImpl* render_widget_host,
- const gfx::Size& new_size) {}
+ const gfx::Size& new_size,
+ uint64_t sequence_number) {}
// The screen info has changed.
virtual void ScreenInfoChanged() {}
- // Sets the device scale factor for frames associated with this WebContents.
- virtual void UpdateDeviceScaleFactor(double device_scale_factor) {}
-
// Retrieve screen information.
- virtual void GetScreenInfo(ScreenInfo* web_screen_info);
+ virtual void GetScreenInfo(ScreenInfo* screen_info);
// Callback to give the browser a chance to handle the specified keyboard
// event before sending it to the renderer. See enum for details on return
diff --git a/chromium/content/browser/renderer_host/render_widget_host_factory.cc b/chromium/content/browser/renderer_host/render_widget_host_factory.cc
new file mode 100644
index 00000000000..2a0c4f1bf2d
--- /dev/null
+++ b/chromium/content/browser/renderer_host/render_widget_host_factory.cc
@@ -0,0 +1,42 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/render_widget_host_factory.h"
+
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+
+namespace content {
+
+// static
+RenderWidgetHostFactory* RenderWidgetHostFactory::factory_ = nullptr;
+
+// static
+RenderWidgetHostImpl* RenderWidgetHostFactory::Create(
+ RenderWidgetHostDelegate* delegate,
+ RenderProcessHost* process,
+ int32_t routing_id,
+ mojom::WidgetPtr widget_interface,
+ bool hidden) {
+ if (factory_) {
+ return factory_->CreateRenderWidgetHost(
+ delegate, process, routing_id, std::move(widget_interface), hidden);
+ }
+ return new RenderWidgetHostImpl(delegate, process, routing_id,
+ std::move(widget_interface), hidden);
+}
+
+// static
+void RenderWidgetHostFactory::RegisterFactory(
+ RenderWidgetHostFactory* factory) {
+ DCHECK(!factory_) << "Can't register two factories at once.";
+ factory_ = factory;
+}
+
+// static
+void RenderWidgetHostFactory::UnregisterFactory() {
+ DCHECK(factory_) << "No factory to unregister.";
+ factory_ = nullptr;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_widget_host_factory.h b/chromium/content/browser/renderer_host/render_widget_host_factory.h
new file mode 100644
index 00000000000..c691954c6a3
--- /dev/null
+++ b/chromium/content/browser/renderer_host/render_widget_host_factory.h
@@ -0,0 +1,69 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_FACTORY_H_
+#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_FACTORY_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "content/common/widget.mojom.h"
+
+namespace content {
+class RenderProcessHost;
+class RenderWidgetHostDelegate;
+class RenderWidgetHostImpl;
+
+// A factory for creating RenderWidgetHostImpls. There is a global factory
+// function that can be installed for the purposes of testing to provide a
+// specialized RenderWidgetHostImpl class.
+class RenderWidgetHostFactory {
+ public:
+ // Creates a RenderWidgetHostImpl using the currently registered factory, or
+ // the default one if no factory is registered. Ownership of the returned
+ // pointer will be passed to the caller.
+ static RenderWidgetHostImpl* Create(RenderWidgetHostDelegate* delegate,
+ RenderProcessHost* process,
+ int32_t routing_id,
+ mojom::WidgetPtr widget_interface,
+ bool hidden);
+
+ // Returns true if there is currently a globally-registered factory.
+ static bool has_factory() { return !!factory_; }
+
+ protected:
+ RenderWidgetHostFactory() {}
+ virtual ~RenderWidgetHostFactory() {}
+
+ // You can derive from this class and specify an implementation for this
+ // function to create a different kind of RenderWidgetHostImpl for testing.
+ virtual RenderWidgetHostImpl* CreateRenderWidgetHost(
+ RenderWidgetHostDelegate* delegate,
+ RenderProcessHost* process,
+ int32_t routing_id,
+ mojom::WidgetPtr widget_interface,
+ bool hidden) = 0;
+
+ // Registers your factory to be called when new RenderWidgetHostImpls are
+ // created. We have only one global factory, so there must be no factory
+ // registered before the call. This class does NOT take ownership of the
+ // pointer.
+ CONTENT_EXPORT static void RegisterFactory(RenderWidgetHostFactory* factory);
+
+ // Unregister the previously registered factory. With no factory registered,
+ // the default RenderWidgetHostImpls will be created.
+ CONTENT_EXPORT static void UnregisterFactory();
+
+ private:
+ // The current globally registered factory. This is NULL when we should
+ // create the default RenderWidgetHostImpls.
+ CONTENT_EXPORT static RenderWidgetHostFactory* factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostFactory);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_FACTORY_H_
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 24b9880966d..078e4527115 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
@@ -30,14 +30,17 @@
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
+#include "components/viz/common/features.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/switches.h"
+#include "components/viz/host/host_frame_sink_manager.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.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_guest.h"
#include "content/browser/child_process_security_policy_impl.h"
+#include "content/browser/compositor/surface_utils.h"
#include "content/browser/fileapi/browser_file_system_helper.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/renderer_host/dip_util.h"
@@ -160,7 +163,7 @@ class RenderWidgetHostIteratorImpl : public RenderWidgetHostIterator {
// RenderWidgetHostIterator:
RenderWidgetHost* GetNextHost() override {
- RenderWidgetHost* host = NULL;
+ RenderWidgetHost* host = nullptr;
while (current_index_ < hosts_.size() && !host) {
RenderWidgetHostID id = hosts_[current_index_];
host = RenderWidgetHost::FromID(id.first, id.second);
@@ -344,7 +347,7 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
is_last_unlocked_by_target_(false),
has_touch_handler_(false),
is_in_touchpad_gesture_fling_(false),
- latency_tracker_(true),
+ latency_tracker_(true, delegate_),
next_browser_snapshot_id_(1),
owned_by_render_frame_host_(false),
is_focused_(false),
@@ -360,7 +363,6 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
weak_factory_(this) {
CHECK(delegate_);
CHECK_NE(MSG_ROUTING_NONE, routing_id_);
- latency_tracker_.SetDelegate(delegate_);
DCHECK(base::TaskScheduler::GetInstance())
<< "Ref. Prerequisite section of post_task.h";
@@ -390,14 +392,18 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
weak_factory_.GetWeakPtr())));
}
- new_content_rendering_timeout_.reset(new TimeoutMonitor(
- base::Bind(&RenderWidgetHostImpl::ClearDisplayedGraphics,
- weak_factory_.GetWeakPtr())));
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableNewContentRenderingTimeout)) {
+ new_content_rendering_timeout_.reset(new TimeoutMonitor(
+ base::Bind(&RenderWidgetHostImpl::ClearDisplayedGraphics,
+ weak_factory_.GetWeakPtr())));
+ }
+
+ enable_surface_synchronization_ = features::IsSurfaceSynchronizationEnabled();
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
- enable_surface_synchronization_ =
- command_line.HasSwitch(switches::kEnableSurfaceSynchronization);
+ enable_viz_ = command_line.HasSwitch(switches::kEnableViz);
delegate_->RenderWidgetCreated(this);
}
@@ -704,9 +710,8 @@ void RenderWidgetHostImpl::WasShown(const ui::LatencyInfo& latency_info) {
// 2. WasResized -> do nothing as resize_ack_pending_ is true
// 3. WasHidden
// 4. OnResizeOrRepaintACK from (1) processed. Does NOT invoke WasResized as
- // view
- // is hidden. Now renderer/browser out of sync with what they think size
- // is.
+ // view is hidden. Now renderer/browser out of sync with what they think
+ // size is.
// By invoking WasResized the renderer is updated as necessary. WasResized
// does nothing if the sizes are already in sync.
//
@@ -801,10 +806,14 @@ void RenderWidgetHostImpl::SetInitialRenderSizeParams(
const ResizeParams& resize_params) {
resize_ack_pending_ = resize_params.needs_resize_ack;
- old_resize_params_ = base::MakeUnique<ResizeParams>(resize_params);
+ old_resize_params_ = std::make_unique<ResizeParams>(resize_params);
}
void RenderWidgetHostImpl::WasResized() {
+ WasResized(false);
+}
+
+void RenderWidgetHostImpl::WasResized(bool scroll_focused_node_into_view) {
// Skip if the |delegate_| has already been detached because
// it's web contents is being deleted.
if (resize_ack_pending_ || !process_->HasConnection() || !view_ ||
@@ -815,6 +824,7 @@ void RenderWidgetHostImpl::WasResized() {
std::unique_ptr<ResizeParams> params(new ResizeParams);
if (!GetResizeParams(params.get()))
return;
+ params->scroll_focused_node_into_view = scroll_focused_node_into_view;
bool width_changed =
!old_resize_params_ ||
@@ -912,7 +922,7 @@ void RenderWidgetHostImpl::ViewDestroyed() {
// TODO(evanm): tracking this may no longer be necessary;
// eliminate this function if so.
- SetView(NULL);
+ SetView(nullptr);
}
#if defined(OS_MACOSX)
@@ -1062,6 +1072,10 @@ void RenderWidgetHostImpl::RestartHangMonitorTimeoutIfNecessary() {
}
}
+bool RenderWidgetHostImpl::IsCurrentlyUnresponsive() const {
+ return is_unresponsive_;
+}
+
void RenderWidgetHostImpl::StopHangMonitorTimeout() {
LogHangMonitorUnresponsive();
hang_start_time_ = TimeTicks();
@@ -1080,6 +1094,10 @@ void RenderWidgetHostImpl::LogHangMonitorUnresponsive() {
void RenderWidgetHostImpl::StartNewContentRenderingTimeout(
uint32_t next_source_id) {
current_content_source_id_ = next_source_id;
+
+ if (!new_content_rendering_timeout_)
+ return;
+
// It is possible for a compositor frame to arrive before the browser is
// notified about the page being committed, in which case no timer is
// necessary.
@@ -1376,7 +1394,7 @@ void RenderWidgetHostImpl::QueueSyntheticGesture(
base::OnceCallback<void(SyntheticGesture::Result)> on_complete) {
if (!synthetic_gesture_controller_ && view_) {
synthetic_gesture_controller_ =
- base::MakeUnique<SyntheticGestureController>(
+ std::make_unique<SyntheticGestureController>(
this, view_->CreateSyntheticGestureTarget());
}
if (synthetic_gesture_controller_) {
@@ -1454,22 +1472,23 @@ void RenderWidgetHostImpl::RemoveInputEventObserver(
void RenderWidgetHostImpl::GetScreenInfo(ScreenInfo* result) {
TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::GetScreenInfo");
- if (delegate_)
+ if (view_) {
+ view_->GetScreenInfo(result);
+ } else {
+ DCHECK(delegate_);
delegate_->GetScreenInfo(result);
- else
- NOTREACHED();
+ }
// TODO(sievers): find a way to make this done another way so the method
// can be const.
- latency_tracker_.set_device_scale_factor(result->device_scale_factor);
if (IsUseZoomForDSFEnabled())
input_router_->SetDeviceScaleFactor(result->device_scale_factor);
}
void RenderWidgetHostImpl::DragTargetDragEnter(
const DropData& drop_data,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
WebDragOperationsMask operations_allowed,
int key_modifiers) {
DragTargetDragEnterWithMetaData(DropDataToMetaData(drop_data), client_pt,
@@ -1478,8 +1497,8 @@ void RenderWidgetHostImpl::DragTargetDragEnter(
void RenderWidgetHostImpl::DragTargetDragEnterWithMetaData(
const std::vector<DropData::Metadata>& metadata,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
WebDragOperationsMask operations_allowed,
int key_modifiers) {
Send(new DragMsg_TargetDragEnter(GetRoutingID(), metadata, client_pt,
@@ -1488,22 +1507,23 @@ void RenderWidgetHostImpl::DragTargetDragEnterWithMetaData(
}
void RenderWidgetHostImpl::DragTargetDragOver(
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
WebDragOperationsMask operations_allowed,
int key_modifiers) {
Send(new DragMsg_TargetDragOver(GetRoutingID(), client_pt, screen_pt,
operations_allowed, key_modifiers));
}
-void RenderWidgetHostImpl::DragTargetDragLeave(const gfx::Point& client_point,
- const gfx::Point& screen_point) {
+void RenderWidgetHostImpl::DragTargetDragLeave(
+ const gfx::PointF& client_point,
+ const gfx::PointF& screen_point) {
Send(new DragMsg_TargetDragLeave(GetRoutingID(), client_point, screen_point));
}
void RenderWidgetHostImpl::DragTargetDrop(const DropData& drop_data,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
int key_modifiers) {
DropData drop_data_with_permissions(drop_data);
GrantFileAccessFromDropData(&drop_data_with_permissions);
@@ -1512,8 +1532,8 @@ void RenderWidgetHostImpl::DragTargetDrop(const DropData& drop_data,
}
void RenderWidgetHostImpl::DragSourceEndedAt(
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
blink::WebDragOperation operation) {
Send(new DragMsg_SourceEnded(GetRoutingID(),
client_pt,
@@ -1754,8 +1774,6 @@ void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status,
// event. (In particular, the above call to view_->RenderProcessGone will
// destroy the aura window, which may dispatch a synthetic mouse move.)
SetupInputRouter();
- associated_widget_input_handler_ = nullptr;
- widget_input_handler_ = nullptr;
synthetic_gesture_controller_.reset();
last_received_frame_token_ = 0;
@@ -2038,14 +2056,15 @@ void RenderWidgetHostImpl::OnResizeOrRepaintACK(
DidCompleteResizeOrRepaint(params, paint_start);
+ last_auto_resize_request_number_ = params.sequence_number;
+
if (auto_resize_enabled_) {
bool post_callback = new_auto_size_.IsEmpty();
new_auto_size_ = params.view_size;
if (post_callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&RenderWidgetHostImpl::DelayedAutoResized,
- weak_factory_.GetWeakPtr(), params.sequence_number));
+ FROM_HERE, base::BindOnce(&RenderWidgetHostImpl::DelayedAutoResized,
+ weak_factory_.GetWeakPtr()));
}
}
@@ -2211,7 +2230,7 @@ void RenderWidgetHostImpl::OnShowDisambiguationPopup(
// It is assumed that the disambiguation popup will make a copy of the
// provided zoomed image, so we delete this one.
- zoomed_bitmap.setPixels(0);
+ zoomed_bitmap.setPixels(nullptr);
Send(new ViewMsg_ReleaseDisambiguationPopupBitmap(GetRoutingID(), id));
}
@@ -2315,11 +2334,12 @@ void RenderWidgetHostImpl::DispatchInputEventWithLatencyInfo(
}
void RenderWidgetHostImpl::OnKeyboardEventAck(
- const NativeWebKeyboardEventWithLatencyInfo& event,
- InputEventAckState ack_result) {
+ const NativeWebKeyboardEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
+ InputEventAckState ack_result) {
latency_tracker_.OnInputEventAck(event.event, &event.latency, ack_result);
for (auto& input_event_observer : input_event_observers_)
- input_event_observer.OnInputEventAck(event.event);
+ input_event_observer.OnInputEventAck(ack_source, ack_result, event.event);
const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
@@ -2337,20 +2357,24 @@ void RenderWidgetHostImpl::OnKeyboardEventAck(
void RenderWidgetHostImpl::OnMouseEventAck(
const MouseEventWithLatencyInfo& mouse_event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
latency_tracker_.OnInputEventAck(mouse_event.event, &mouse_event.latency,
ack_result);
for (auto& input_event_observer : input_event_observers_)
- input_event_observer.OnInputEventAck(mouse_event.event);
+ input_event_observer.OnInputEventAck(ack_source, ack_result,
+ mouse_event.event);
}
void RenderWidgetHostImpl::OnWheelEventAck(
const MouseWheelEventWithLatencyInfo& wheel_event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
latency_tracker_.OnInputEventAck(wheel_event.event, &wheel_event.latency,
ack_result);
for (auto& input_event_observer : input_event_observers_)
- input_event_observer.OnInputEventAck(wheel_event.event);
+ input_event_observer.OnInputEventAck(ack_source, ack_result,
+ wheel_event.event);
if (!is_hidden() && view_) {
if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED &&
@@ -2363,10 +2387,11 @@ void RenderWidgetHostImpl::OnWheelEventAck(
void RenderWidgetHostImpl::OnGestureEventAck(
const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
latency_tracker_.OnInputEventAck(event.event, &event.latency, ack_result);
for (auto& input_event_observer : input_event_observers_)
- input_event_observer.OnInputEventAck(event.event);
+ input_event_observer.OnInputEventAck(ack_source, ack_result, event.event);
if (view_)
view_->GestureEventAck(event.event, ack_result);
@@ -2374,10 +2399,11 @@ void RenderWidgetHostImpl::OnGestureEventAck(
void RenderWidgetHostImpl::OnTouchEventAck(
const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) {
latency_tracker_.OnInputEventAck(event.event, &event.latency, ack_result);
for (auto& input_event_observer : input_event_observers_)
- input_event_observer.OnInputEventAck(event.event);
+ input_event_observer.OnInputEventAck(ack_source, ack_result, event.event);
if (touch_emulator_ &&
touch_emulator_->HandleTouchEventAck(event.event, ack_result)) {
@@ -2426,7 +2452,7 @@ bool RenderWidgetHostImpl::GotResponseToLockMouseRequest(bool allowed) {
return true;
}
-void RenderWidgetHostImpl::DelayedAutoResized(uint64_t sequence_number) {
+void RenderWidgetHostImpl::DelayedAutoResized() {
gfx::Size new_size = new_auto_size_;
// Clear the new_auto_size_ since the empty value is used as a flag to
// indicate that no callback is in progress (i.e. without this line
@@ -2435,21 +2461,32 @@ void RenderWidgetHostImpl::DelayedAutoResized(uint64_t sequence_number) {
if (!auto_resize_enabled_)
return;
- if (delegate_)
- delegate_->ResizeDueToAutoResize(this, new_size);
+ if (delegate_) {
+ delegate_->ResizeDueToAutoResize(this, new_size,
+ last_auto_resize_request_number_);
+ }
+}
+
+void RenderWidgetHostImpl::DetachDelegate() {
+ delegate_ = nullptr;
+ latency_tracker_.reset_delegate();
+}
+
+void RenderWidgetHostImpl::DidAllocateLocalSurfaceIdForAutoResize(
+ uint64_t sequence_number) {
+ if (!view_ || last_auto_resize_request_number_ != sequence_number)
+ return;
viz::LocalSurfaceId local_surface_id(view_->GetLocalSurfaceId());
if (local_surface_id.is_valid()) {
+ ScreenInfo screen_info;
+ GetScreenInfo(&screen_info);
Send(new ViewMsg_SetLocalSurfaceIdForAutoResize(
- routing_id_, sequence_number, local_surface_id));
+ routing_id_, sequence_number, min_size_for_auto_resize_,
+ max_size_for_auto_resize_, screen_info, local_surface_id));
}
}
-void RenderWidgetHostImpl::DetachDelegate() {
- delegate_ = NULL;
- latency_tracker_.SetDelegate(nullptr);
-}
-
void RenderWidgetHostImpl::DidReceiveRendererFrame() {
view_->DidReceiveRendererFrame();
}
@@ -2521,7 +2558,7 @@ void RenderWidgetHostImpl::OnSnapshotFromSurfaceReceived(
}
void RenderWidgetHostImpl::OnSnapshotReceived(int snapshot_id,
- const gfx::Image& image) {
+ 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();
@@ -2566,13 +2603,13 @@ void RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(
BrowserAccessibilityManager*
RenderWidgetHostImpl::GetRootBrowserAccessibilityManager() {
- return delegate_ ? delegate_->GetRootBrowserAccessibilityManager() : NULL;
+ return delegate_ ? delegate_->GetRootBrowserAccessibilityManager() : nullptr;
}
BrowserAccessibilityManager*
RenderWidgetHostImpl::GetOrCreateRootBrowserAccessibilityManager() {
- return delegate_ ?
- delegate_->GetOrCreateRootBrowserAccessibilityManager() : NULL;
+ return delegate_ ? delegate_->GetOrCreateRootBrowserAccessibilityManager()
+ : nullptr;
}
void RenderWidgetHostImpl::GrantFileAccessFromDropData(DropData* drop_data) {
@@ -2595,6 +2632,16 @@ void RenderWidgetHostImpl::RequestCompositionUpdates(bool immediate_request,
void RenderWidgetHostImpl::RequestCompositorFrameSink(
viz::mojom::CompositorFrameSinkRequest request,
viz::mojom::CompositorFrameSinkClientPtr client) {
+ if (enable_viz_) {
+ // TODO(kylechar): Find out why renderer is requesting a CompositorFrameSink
+ // with no view.
+ if (view_) {
+ GetHostFrameSinkManager()->CreateCompositorFrameSink(
+ view_->GetFrameSinkId(), std::move(request), std::move(client));
+ }
+ return;
+ }
+
if (compositor_frame_sink_binding_.is_bound())
compositor_frame_sink_binding_.Close();
compositor_frame_sink_binding_.Bind(
@@ -2620,7 +2667,7 @@ void RenderWidgetHostImpl::SubmitCompositorFrame(
uint64_t submit_time) {
// TODO(gklassen): Route hit-test data to appropriate HitTestAggregator.
TRACE_EVENT_FLOW_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "SubmitCompositorFrame", local_surface_id.local_id());
+ "SubmitCompositorFrame", local_surface_id.parent_id());
bool tracing_enabled;
TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
&tracing_enabled);
@@ -2669,7 +2716,6 @@ void RenderWidgetHostImpl::SubmitCompositorFrame(
last_surface_properties_ = new_surface_properties;
last_received_content_source_id_ = frame.metadata.content_source_id;
- uint32_t frame_token = frame.metadata.frame_token;
// |has_damage| is not transmitted.
frame.metadata.begin_frame_ack.has_damage = true;
@@ -2690,9 +2736,14 @@ void RenderWidgetHostImpl::SubmitCompositorFrame(
// compositor frame can arrive before the navigation commit message that
// updates that value.
if (view_ && frame.metadata.content_source_id >= current_content_source_id_) {
- view_->SubmitCompositorFrame(local_surface_id, std::move(frame));
+ view_->SubmitCompositorFrame(local_surface_id, std::move(frame),
+ std::move(hit_test_region_list));
view_->DidReceiveRendererFrame();
} else {
+ 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);
@@ -2700,16 +2751,14 @@ 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_ &&
+ if (new_content_rendering_timeout_ &&
+ last_received_content_source_id_ >= current_content_source_id_ &&
new_content_rendering_timeout_->IsRunning()) {
new_content_rendering_timeout_->Stop();
}
if (delegate_)
delegate_->DidReceiveCompositorFrame();
-
- if (frame_token)
- DidProcessFrame(frame_token);
}
void RenderWidgetHostImpl::DidProcessFrame(uint32_t frame_token) {
@@ -2755,8 +2804,8 @@ device::mojom::WakeLock* RenderWidgetHostImpl::GetWakeLock() {
connector->BindInterface(device::mojom::kServiceName,
mojo::MakeRequest(&wake_lock_provider));
wake_lock_provider->GetWakeLockWithoutContext(
- device::mojom::WakeLockType::PreventDisplaySleep,
- device::mojom::WakeLockReason::ReasonOther, "GetSnapshot",
+ device::mojom::WakeLockType::kPreventDisplaySleep,
+ device::mojom::WakeLockReason::kOther, "GetSnapshot",
std::move(request));
}
}
@@ -2782,6 +2831,11 @@ void RenderWidgetHostImpl::DidAllocateSharedBitmap(uint32_t sequence_number) {
}
void RenderWidgetHostImpl::SetupInputRouter() {
+ in_flight_event_count_ = 0;
+ StopHangMonitorTimeout();
+ associated_widget_input_handler_ = nullptr;
+ widget_input_handler_ = nullptr;
+
if (base::FeatureList::IsEnabled(features::kMojoInputMessages)) {
input_router_.reset(
new InputRouterImpl(this, this, GetInputRouterConfigForPlatform()));
@@ -2791,14 +2845,19 @@ void RenderWidgetHostImpl::SetupInputRouter() {
// widget shutdown, so we present an UnboundWidgetInputHandler had
// DLOGS the message calls.
legacy_widget_input_handler_ =
- base::MakeUnique<UnboundWidgetInputHandler>();
+ std::make_unique<UnboundWidgetInputHandler>();
} else {
input_router_.reset(new LegacyInputRouterImpl(
process_, this, this, routing_id_, GetInputRouterConfigForPlatform()));
legacy_widget_input_handler_ =
- base::MakeUnique<LegacyIPCWidgetInputHandler>(
+ std::make_unique<LegacyIPCWidgetInputHandler>(
static_cast<LegacyInputRouterImpl*>(input_router_.get()));
}
+
+ if (IsUseZoomForDSFEnabled()) {
+ input_router_->SetDeviceScaleFactor(
+ view_.get() ? content::GetScaleFactorForView(view_.get()) : 1.0f);
+ }
}
void RenderWidgetHostImpl::SetForceEnableZoom(bool enabled) {
@@ -2806,20 +2865,26 @@ void RenderWidgetHostImpl::SetForceEnableZoom(bool enabled) {
}
void RenderWidgetHostImpl::SetWidgetInputHandler(
- mojom::WidgetInputHandlerAssociatedPtr widget_input_handler) {
- associated_widget_input_handler_ = std::move(widget_input_handler);
+ mojom::WidgetInputHandlerAssociatedPtr widget_input_handler,
+ mojom::WidgetInputHandlerHostRequest host_request) {
+ if (base::FeatureList::IsEnabled(features::kMojoInputMessages)) {
+ associated_widget_input_handler_ = std::move(widget_input_handler);
+ input_router_->BindHost(std::move(host_request), true);
+ }
}
void RenderWidgetHostImpl::SetWidget(mojom::WidgetPtr widget) {
if (widget && base::FeatureList::IsEnabled(features::kMojoInputMessages)) {
- widget_input_handler_.reset();
+ // If we have a bound handler ensure that we destroy the old input router.
+ if (widget_input_handler_.get())
+ SetupInputRouter();
mojom::WidgetInputHandlerHostPtr host;
mojom::WidgetInputHandlerHostRequest host_request =
mojo::MakeRequest(&host);
widget->SetupWidgetInputHandler(mojo::MakeRequest(&widget_input_handler_),
std::move(host));
- input_router_->BindHost(std::move(host_request));
+ input_router_->BindHost(std::move(host_request), false);
}
}
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 14abab21c65..13ac701aa57 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h
@@ -40,12 +40,12 @@
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/common/drag_event_source_info.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/common/input/input_handler.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"
#include "content/public/common/page_zoom.h"
#include "content/public/common/url_constants.h"
#include "ipc/ipc_listener.h"
@@ -175,6 +175,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
RenderWidgetHostViewBase* GetView() const override;
bool IsLoading() const override;
void RestartHangMonitorTimeoutIfNecessary() override;
+ bool IsCurrentlyUnresponsive() const override;
void SetIgnoreInputEvents(bool ignore_input_events) override;
void WasResized() override;
void AddKeyPressEventCallback(const KeyPressEventCallback& callback) override;
@@ -190,30 +191,30 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// |drop_data| must have been filtered. The embedder should call
// FilterDropData before passing the drop data to RWHI.
void DragTargetDragEnter(const DropData& drop_data,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
blink::WebDragOperationsMask operations_allowed,
int key_modifiers) override;
void DragTargetDragEnterWithMetaData(
const std::vector<DropData::Metadata>& metadata,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
blink::WebDragOperationsMask operations_allowed,
int key_modifiers) override;
- void DragTargetDragOver(const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ void DragTargetDragOver(const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
blink::WebDragOperationsMask operations_allowed,
int key_modifiers) override;
- void DragTargetDragLeave(const gfx::Point& client_point,
- const gfx::Point& screen_point) override;
+ void DragTargetDragLeave(const gfx::PointF& client_point,
+ const gfx::PointF& screen_point) override;
// |drop_data| must have been filtered. The embedder should call
// FilterDropData before passing the drop data to RWHI.
void DragTargetDrop(const DropData& drop_data,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
int key_modifiers) override;
- void DragSourceEndedAt(const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ void DragSourceEndedAt(const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
blink::WebDragOperation operation) override;
void DragSourceSystemDragEnded() override;
void FilterDropData(DropData* drop_data) override;
@@ -499,6 +500,10 @@ class CONTENT_EXPORT RenderWidgetHostImpl
return max_size_for_auto_resize_;
}
+ // Called to notify the RenderWidget that a viz::LocalSurfaceId was allocated
+ // for the auto-resize request specified by |sequence_number|.
+ void DidAllocateLocalSurfaceIdForAutoResize(uint64_t sequence_number);
+
void DidReceiveRendererFrame();
// Returns the ID that uniquely describes this component to the latency
@@ -542,6 +547,10 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// request to create a new RenderWidget.
void SetInitialRenderSizeParams(const ResizeParams& resize_params);
+ // The RenderWidget was resized and whether the focused node should be
+ // scrolled into view.
+ void WasResized(bool scroll_focused_node_into_view);
+
// Called when we receive a notification indicating that the renderer process
// is gone. This will reset our state so that our state will be consistent if
// a new renderer is created.
@@ -587,6 +596,10 @@ class CONTENT_EXPORT RenderWidgetHostImpl
return last_frame_metadata_;
}
+ uint64_t last_auto_resize_request_number() const {
+ return last_auto_resize_request_number_;
+ }
+
bool HasGestureStopped() override;
// viz::mojom::CompositorFrameSink implementation.
@@ -607,7 +620,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// interface calls processed on the FrameInputHandler to be processed in order
// with the interface calls processed on the WidgetInputHandler.
void SetWidgetInputHandler(
- mojom::WidgetInputHandlerAssociatedPtr widget_input_handler);
+ mojom::WidgetInputHandlerAssociatedPtr widget_input_handler,
+ mojom::WidgetInputHandlerHostRequest host_request);
void SetWidget(mojom::WidgetPtr widget);
// InputRouterImplClient overrides.
@@ -645,6 +659,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
StopAndStartHangMonitorTimeout);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest,
ShorterDelayHangMonitorTimeout);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, AutoResizeWithScale);
FRIEND_TEST_ALL_PREFIXES(DevToolsManagerTest,
NoUnresponsiveDialogInInspectedContents);
friend class MockRenderWidgetHost;
@@ -732,20 +747,25 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// InputAckHandler
void OnKeyboardEventAck(const NativeWebKeyboardEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnMouseEventAck(const MouseEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override;
void OnUnexpectedEventAck(UnexpectedEventAckType type) override;
// Called when there is a new auto resize (using a post to avoid a stack
// which may get in recursive loops).
- void DelayedAutoResized(uint64_t sequence_number);
+ void DelayedAutoResized();
void WindowSnapshotReachedScreen(int snapshot_id);
@@ -754,7 +774,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
const SkBitmap& bitmap,
ReadbackResponse response);
- void OnSnapshotReceived(int snapshot_id, const gfx::Image& image);
+ void OnSnapshotReceived(int snapshot_id, gfx::Image image);
// 1. Grants permissions to URL (if any)
// 2. Grants permissions to filenames
@@ -848,6 +868,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// The maximum size for the render widget if auto-resize is enabled.
gfx::Size max_size_for_auto_resize_;
+ uint64_t last_auto_resize_request_number_ = 0ul;
+
bool waiting_for_screen_rects_ack_;
gfx::Rect last_view_screen_rect_;
gfx::Rect last_window_screen_rect_;
@@ -1028,6 +1050,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
} saved_frame_;
bool enable_surface_synchronization_ = false;
+ bool enable_viz_ = false;
// If the |associated_widget_input_handler_| is set it should always be
// used to ensure in order delivery of related messages that may occur
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 b9c1a57c331..49d64e8cc4d 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
@@ -132,7 +132,7 @@ RenderWidgetHostInputEventRouter::HittestDelegate::HittestDelegate(
bool RenderWidgetHostInputEventRouter::HittestDelegate::RejectHitTarget(
const viz::SurfaceDrawQuad* surface_quad,
const gfx::Point& point_in_quad_space) {
- auto it = hittest_data_.find(surface_quad->surface_id);
+ auto it = hittest_data_.find(surface_quad->primary_surface_id);
if (it != hittest_data_.end() && it->second.ignored_for_hittest)
return true;
return false;
@@ -141,7 +141,7 @@ bool RenderWidgetHostInputEventRouter::HittestDelegate::RejectHitTarget(
bool RenderWidgetHostInputEventRouter::HittestDelegate::AcceptHitTarget(
const viz::SurfaceDrawQuad* surface_quad,
const gfx::Point& point_in_quad_space) {
- auto it = hittest_data_.find(surface_quad->surface_id);
+ auto it = hittest_data_.find(surface_quad->primary_surface_id);
if (it != hittest_data_.end() && !it->second.ignored_for_hittest)
return true;
return false;
@@ -164,6 +164,17 @@ RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget(
RenderWidgetHostViewBase* root_view,
const gfx::Point& point,
gfx::Point* transformed_point) {
+ gfx::PointF temp_point(*transformed_point);
+ RenderWidgetHostViewBase* view =
+ FindEventTarget(root_view, gfx::PointF(point), &temp_point);
+ *transformed_point = gfx::ToFlooredPoint(temp_point);
+ return view;
+}
+
+RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget(
+ RenderWidgetHostViewBase* root_view,
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point) {
// Short circuit if owner_map has only one RenderWidgetHostView, no need for
// hit testing.
if (owner_map_.size() <= 1) {
@@ -181,6 +192,7 @@ RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget(
// single process with only one RenderWidgetHost.
viz::FrameSinkId frame_sink_id =
root_view->FrameSinkIdAtPoint(&delegate, point, transformed_point);
+
const FrameSinkIdOwnerMap::iterator iter = owner_map_.find(frame_sink_id);
// If the point hit a Surface whose namspace is no longer in the map, then
// it likely means the RenderWidgetHostView has been destroyed but its
@@ -196,7 +208,7 @@ void RenderWidgetHostInputEventRouter::RouteMouseEvent(
blink::WebMouseEvent* event,
const ui::LatencyInfo& latency) {
RenderWidgetHostViewBase* target = nullptr;
- gfx::Point transformed_point;
+ gfx::PointF transformed_point;
// When the mouse is locked, directly route the events to the widget that
// holds the lock and return.
@@ -206,9 +218,7 @@ void RenderWidgetHostInputEventRouter::RouteMouseEvent(
->GetMouseLockWidget()
->GetView();
if (!root_view->TransformPointToCoordSpaceForView(
- gfx::Point(event->PositionInWidget().x,
- event->PositionInWidget().y),
- target, &transformed_point))
+ event->PositionInWidget(), target, &transformed_point))
return;
event->SetPositionInWidget(transformed_point.x(), transformed_point.y());
@@ -227,17 +237,13 @@ void RenderWidgetHostInputEventRouter::RouteMouseEvent(
event->GetModifiers() & mouse_button_modifiers)) {
target = mouse_capture_target_.target;
if (!root_view->TransformPointToCoordSpaceForView(
- gfx::Point(event->PositionInWidget().x,
- event->PositionInWidget().y),
- target, &transformed_point))
+ event->PositionInWidget(), target, &transformed_point))
return;
if (event->GetType() == blink::WebInputEvent::kMouseUp)
mouse_capture_target_.target = nullptr;
} else {
- target = FindEventTarget(
- root_view,
- gfx::Point(event->PositionInWidget().x, event->PositionInWidget().y),
- &transformed_point);
+ target = FindEventTarget(root_view, event->PositionInWidget(),
+ &transformed_point);
}
// RenderWidgetHostViewGuest does not properly handle direct routing of mouse
@@ -259,11 +265,9 @@ void RenderWidgetHostInputEventRouter::RouteMouseEvent(
if (owner_view != root_view) {
// This happens when the view is embedded inside a cross-process frame
// (i.e., owner view is a RenderWidgetHostViewChildFrame).
- gfx::Point owner_point;
+ gfx::PointF owner_point;
if (!root_view->TransformPointToCoordSpaceForView(
- gfx::Point(event->PositionInWidget().x,
- event->PositionInWidget().y),
- owner_view, &owner_point)) {
+ event->PositionInWidget(), owner_view, &owner_point)) {
return;
}
event->SetPositionInWidget(owner_point.x(), owner_point.y());
@@ -299,7 +303,7 @@ void RenderWidgetHostInputEventRouter::RouteMouseWheelEvent(
blink::WebMouseWheelEvent* event,
const ui::LatencyInfo& latency) {
RenderWidgetHostViewBase* target = nullptr;
- gfx::Point transformed_point;
+ gfx::PointF transformed_point;
if (root_view->IsMouseLocked()) {
target = RenderWidgetHostImpl::From(root_view->GetRenderWidgetHost())
@@ -307,9 +311,7 @@ void RenderWidgetHostInputEventRouter::RouteMouseWheelEvent(
->GetMouseLockWidget()
->GetView();
if (!root_view->TransformPointToCoordSpaceForView(
- gfx::Point(event->PositionInWidget().x,
- event->PositionInWidget().y),
- target, &transformed_point)) {
+ event->PositionInWidget(), target, &transformed_point)) {
root_view->WheelEventAck(*event,
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
return;
@@ -317,19 +319,14 @@ void RenderWidgetHostInputEventRouter::RouteMouseWheelEvent(
} else if (root_view->wheel_scroll_latching_enabled()) {
if (event->phase == blink::WebMouseWheelEvent::kPhaseBegan) {
wheel_target_.target = FindEventTarget(
- root_view,
- gfx::Point(event->PositionInWidget().x, event->PositionInWidget().y),
- &transformed_point);
+ root_view, event->PositionInWidget(), &transformed_point);
wheel_target_.delta =
- transformed_point -
- gfx::Point(event->PositionInWidget().x, event->PositionInWidget().y);
+ gfx::ToFlooredVector2d(transformed_point - event->PositionInWidget());
target = wheel_target_.target;
} else {
if (wheel_target_.target) {
target = wheel_target_.target;
- transformed_point = gfx::Point(event->PositionInWidget().x,
- event->PositionInWidget().y) +
- wheel_target_.delta;
+ transformed_point = event->PositionInWidget() + wheel_target_.delta;
} else if ((event->phase == blink::WebMouseWheelEvent::kPhaseEnded ||
event->momentum_phase ==
blink::WebMouseWheelEvent::kPhaseEnded) &&
@@ -348,11 +345,9 @@ void RenderWidgetHostInputEventRouter::RouteMouseWheelEvent(
}
} else { // !root_view->IsMouseLocked() &&
- // !root_view->wheel_scroll_latching_enabled()
- target = FindEventTarget(
- root_view,
- gfx::Point(event->PositionInWidget().x, event->PositionInWidget().y),
- &transformed_point);
+ // !root_view->wheel_scroll_latching_enabled()
+ target = FindEventTarget(root_view, event->PositionInWidget(),
+ &transformed_point);
}
if (!target) {
@@ -418,10 +413,10 @@ unsigned CountChangedTouchPoints(const blink::WebTouchEvent& event) {
// We'll only ever call this method for TouchStart, TouchEnd
// and TounchCancel events, so mark the rest as not-reached.
NOTREACHED();
- }
- for (unsigned i = 0; i < event.touches_length; ++i) {
- if (event.touches[i].state == required_state)
- ++changed_count;
+ }
+ for (unsigned i = 0; i < event.touches_length; ++i) {
+ if (event.touches[i].state == required_state)
+ ++changed_count;
}
DCHECK(event.GetType() == blink::WebInputEvent::kTouchCancel ||
@@ -605,7 +600,7 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents(
exited_views.pop_back();
}
- gfx::Point transformed_point;
+ gfx::PointF transformed_point;
// Send MouseLeaves.
for (auto* view : exited_views) {
blink::WebMouseEvent mouse_leave(*event);
@@ -614,11 +609,9 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents(
// new compositor surface. The SurfaceID for that might not have
// propagated to its embedding surface, which makes it impossible to
// compute the transformation for it
- if (!root_view->TransformPointToCoordSpaceForView(
- gfx::Point(event->PositionInWidget().x,
- event->PositionInWidget().y),
- view, &transformed_point))
- transformed_point = gfx::Point();
+ if (!root_view->TransformPointToCoordSpaceForView(event->PositionInWidget(),
+ view, &transformed_point))
+ transformed_point = gfx::PointF();
mouse_leave.SetPositionInWidget(transformed_point.x(),
transformed_point.y());
view->ProcessMouseEvent(mouse_leave, ui::LatencyInfo());
@@ -629,10 +622,8 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents(
blink::WebMouseEvent mouse_move(*event);
mouse_move.SetType(blink::WebInputEvent::kMouseMove);
if (!root_view->TransformPointToCoordSpaceForView(
- gfx::Point(event->PositionInWidget().x,
- event->PositionInWidget().y),
- common_ancestor, &transformed_point))
- transformed_point = gfx::Point();
+ event->PositionInWidget(), common_ancestor, &transformed_point))
+ transformed_point = gfx::PointF();
mouse_move.SetPositionInWidget(transformed_point.x(),
transformed_point.y());
common_ancestor->ProcessMouseEvent(mouse_move, ui::LatencyInfo());
@@ -644,11 +635,9 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents(
continue;
blink::WebMouseEvent mouse_enter(*event);
mouse_enter.SetType(blink::WebInputEvent::kMouseMove);
- if (!root_view->TransformPointToCoordSpaceForView(
- gfx::Point(event->PositionInWidget().x,
- event->PositionInWidget().y),
- view, &transformed_point))
- transformed_point = gfx::Point();
+ if (!root_view->TransformPointToCoordSpaceForView(event->PositionInWidget(),
+ view, &transformed_point))
+ transformed_point = gfx::PointF();
mouse_enter.SetPositionInWidget(transformed_point.x(),
transformed_point.y());
view->ProcessMouseEvent(mouse_enter, ui::LatencyInfo());
@@ -893,8 +882,8 @@ void RenderWidgetHostInputEventRouter::OnHittestData(
RenderWidgetHostImpl*
RenderWidgetHostInputEventRouter::GetRenderWidgetHostAtPoint(
RenderWidgetHostViewBase* root_view,
- const gfx::Point& point,
- gfx::Point* transformed_point) {
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point) {
if (!root_view)
return nullptr;
return RenderWidgetHostImpl::From(
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 b796d1deca1..951b63dd02e 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
@@ -18,7 +18,7 @@
#include "components/viz/service/surfaces/surface_hittest_delegate.h"
#include "content/browser/renderer_host/render_widget_host_view_base_observer.h"
#include "content/common/content_export.h"
-#include "ui/gfx/geometry/vector2d.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
struct FrameHostMsg_HittestData_Params;
@@ -31,6 +31,7 @@ class WebTouchEvent;
namespace gfx {
class Point;
+class PointF;
}
namespace ui {
@@ -93,8 +94,8 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
// will return nullptr and will not modify |transformed_point|.
RenderWidgetHostImpl* GetRenderWidgetHostAtPoint(
RenderWidgetHostViewBase* root_view,
- const gfx::Point& point,
- gfx::Point* transformed_point);
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point);
std::vector<RenderWidgetHostView*> GetRenderWidgetHostViewsForTests() const;
@@ -134,6 +135,10 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
const gfx::Point& point,
gfx::Point* transformed_point);
+ RenderWidgetHostViewBase* FindEventTarget(RenderWidgetHostViewBase* root_view,
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point);
+
void RouteTouchscreenGestureEvent(RenderWidgetHostViewBase* root_view,
blink::WebGestureEvent* event,
const ui::LatencyInfo& latency);
diff --git a/chromium/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
index 035728454c5..e08df123aad 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
@@ -60,8 +60,8 @@ class MockRootRenderWidgetHostView : public MockRenderWidgetHostView {
~MockRootRenderWidgetHostView() override {}
viz::FrameSinkId FrameSinkIdAtPoint(viz::SurfaceHittestDelegate*,
- const gfx::Point&,
- gfx::Point*) override {
+ const gfx::PointF&,
+ gfx::PointF*) override {
return frame_sink_id_map_[current_hittest_result_];
}
@@ -85,28 +85,28 @@ class RenderWidgetHostInputEventRouterTest : public testing::Test {
protected:
// testing::Test:
void SetUp() override {
- browser_context_ = base::MakeUnique<TestBrowserContext>();
+ browser_context_ = std::make_unique<TestBrowserContext>();
process_host1_ =
- base::MakeUnique<MockRenderProcessHost>(browser_context_.get());
+ std::make_unique<MockRenderProcessHost>(browser_context_.get());
process_host2_ =
- base::MakeUnique<MockRenderProcessHost>(browser_context_.get());
+ std::make_unique<MockRenderProcessHost>(browser_context_.get());
mojom::WidgetPtr widget1;
widget_impl1_ =
- base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget1));
- widget_host1_ = base::MakeUnique<RenderWidgetHostImpl>(
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget1));
+ widget_host1_ = std::make_unique<RenderWidgetHostImpl>(
&delegate_, process_host1_.get(), process_host1_->GetNextRoutingID(),
std::move(widget1), false);
mojom::WidgetPtr widget2;
widget_impl2_ =
- base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget2));
- widget_host2_ = base::MakeUnique<RenderWidgetHostImpl>(
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget2));
+ widget_host2_ = std::make_unique<RenderWidgetHostImpl>(
&delegate_, process_host2_.get(), process_host2_->GetNextRoutingID(),
std::move(widget2), false);
- view_root_ = base::MakeUnique<MockRootRenderWidgetHostView>(
+ view_root_ = std::make_unique<MockRootRenderWidgetHostView>(
widget_host1_.get(), frame_sink_id_map_);
view_other_ =
- base::MakeUnique<MockRenderWidgetHostView>(widget_host2_.get());
+ std::make_unique<MockRenderWidgetHostView>(widget_host2_.get());
// Set up the RWHIER's FrameSinkId to RWHV map so that we can control the
// result of RWHIER's hittesting.
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 6e4b19b92ab..57954972a5b 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -19,9 +19,9 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
+#include "components/viz/test/begin_frame_args_test.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/renderer_host/input/legacy_input_router_impl.h"
-#include "content/browser/renderer_host/input/mock_widget_input_handler.h"
#include "content/browser/renderer_host/input/touch_emulator.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
@@ -39,6 +39,7 @@
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/fake_renderer_compositor_frame_sink.h"
#include "content/test/mock_widget_impl.h"
+#include "content/test/mock_widget_input_handler.h"
#include "content/test/test_render_view_host.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -119,7 +120,8 @@ class MockInputRouter : public InputRouter {
void SetFrameTreeNodeId(int frameTreeNodeId) override {}
cc::TouchAction AllowedTouchAction() override { return cc::kTouchActionAuto; }
void SetForceEnableZoom(bool enabled) override {}
- void BindHost(mojom::WidgetInputHandlerHostRequest request) override {}
+ void BindHost(mojom::WidgetInputHandlerHostRequest request,
+ bool frame_handler) override {}
// IPC::Listener
bool OnMessageReceived(const IPC::Message& message) override {
@@ -157,10 +159,11 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
using RenderWidgetHostImpl::queued_messages_;
void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
InputEventAckState ack_result) override {
// Sniff touch acks.
acked_touch_event_type_ = event.event.GetType();
- RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
+ RenderWidgetHostImpl::OnTouchEventAck(event, ack_source, ack_result);
}
void reset_new_content_rendering_timeout_fired() {
@@ -180,7 +183,7 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
input_router_.reset(new LegacyInputRouterImpl(
process_, this, this, routing_id_, InputRouter::Config()));
legacy_widget_input_handler_ =
- base::MakeUnique<LegacyIPCWidgetInputHandler>(
+ std::make_unique<LegacyIPCWidgetInputHandler>(
static_cast<LegacyInputRouterImpl*>(input_router_.get()));
}
}
@@ -207,7 +210,7 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
int32_t routing_id) {
mojom::WidgetPtr widget;
std::unique_ptr<MockWidgetImpl> widget_impl =
- base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
return new MockRenderWidgetHost(delegate, process, routing_id,
std::move(widget_impl), std::move(widget));
@@ -341,6 +344,10 @@ class TestView : public TestRenderWidgetHostView {
use_fake_physical_backing_size_ = false;
}
+ const viz::BeginFrameAck& last_did_not_produce_frame_ack() {
+ return last_did_not_produce_frame_ack_;
+ }
+
// RenderWidgetHostView override.
gfx::Rect GetViewBounds() const override { return bounds_; }
float GetTopControlsHeight() const override { return top_controls_height_; }
@@ -369,6 +376,9 @@ class TestView : public TestRenderWidgetHostView {
return mock_physical_backing_size_;
return TestRenderWidgetHostView::GetPhysicalBackingSize();
}
+ void OnDidNotProduceFrame(const viz::BeginFrameAck& ack) override {
+ last_did_not_produce_frame_ack_ = ack;
+ }
protected:
WebMouseWheelEvent unhandled_wheel_event_;
@@ -382,6 +392,7 @@ class TestView : public TestRenderWidgetHostView {
InputEventAckState ack_result_;
float top_controls_height_;
float bottom_controls_height_;
+ viz::BeginFrameAck last_did_not_produce_frame_ack_;
private:
DISALLOW_COPY_AND_ASSIGN(TestView);
@@ -549,7 +560,7 @@ class RenderWidgetHostTest : public testing::Test {
RenderWidgetHostTest(
UseMojoInputMessages input_messages_mode = UseMojoInputMessages::kEnabled,
WheelScrollingMode wheel_scrolling_mode = kWheelScrollLatching)
- : process_(NULL),
+ : process_(nullptr),
handle_key_press_event_(false),
handle_mouse_event_(false),
simulated_event_time_delta_seconds_(0),
@@ -565,18 +576,15 @@ class RenderWidgetHostTest : public testing::Test {
switch (wheel_scrolling_mode) {
case kWheelScrollingModeNone:
- features.push_back(features::kRafAlignedTouchInputEvents.name);
disabled_features.push_back(
features::kTouchpadAndWheelScrollLatching.name);
disabled_features.push_back(features::kAsyncWheelEvents.name);
break;
case kWheelScrollLatching:
- features.push_back(features::kRafAlignedTouchInputEvents.name);
features.push_back(features::kTouchpadAndWheelScrollLatching.name);
disabled_features.push_back(features::kAsyncWheelEvents.name);
break;
case kAsyncWheelEvents:
- features.push_back(features::kRafAlignedTouchInputEvents.name);
features.push_back(features::kTouchpadAndWheelScrollLatching.name);
features.push_back(features::kAsyncWheelEvents.name);
break;
@@ -634,7 +642,7 @@ class RenderWidgetHostTest : public testing::Test {
viz::mojom::CompositorFrameSinkClientRequest client_request =
mojo::MakeRequest(&renderer_compositor_frame_sink_ptr_);
renderer_compositor_frame_sink_ =
- base::MakeUnique<FakeRendererCompositorFrameSink>(
+ std::make_unique<FakeRendererCompositorFrameSink>(
std::move(sink), std::move(client_request));
host_->RequestCompositorFrameSink(
std::move(sink_request),
@@ -645,7 +653,7 @@ class RenderWidgetHostTest : public testing::Test {
view_.reset();
host_.reset();
delegate_.reset();
- process_ = NULL;
+ process_ = nullptr;
browser_context_.reset();
#if defined(USE_AURA)
@@ -827,7 +835,7 @@ class RenderWidgetHostTest : public testing::Test {
const char* data;
int data_length;
if (!iter.ReadData(&data, &data_length))
- return NULL;
+ return nullptr;
return reinterpret_cast<const WebInputEvent*>(data);
}
@@ -910,13 +918,6 @@ class RenderWidgetHostWithSourceTest
public testing::WithParamInterface<WebGestureDevice> {};
#endif // GTEST_HAS_PARAM_TEST
-void CallCallback(mojom::WidgetInputHandler::DispatchEventCallback callback,
- InputEventAckState state) {
- std::move(callback).Run(InputEventAckSource::COMPOSITOR_THREAD,
- ui::LatencyInfo(), state, base::nullopt,
- base::nullopt);
-}
-
} // namespace
// -----------------------------------------------------------------------------
@@ -1097,7 +1098,7 @@ TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
// Simulate a renderer crash before the update message. Ensure all the
// resize ack logic is cleared. Must clear the view first so it doesn't get
// deleted.
- host_->SetView(NULL);
+ host_->SetView(nullptr);
host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
EXPECT_FALSE(host_->resize_ack_pending_);
EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
@@ -1113,9 +1114,10 @@ TEST_F(RenderWidgetHostTest, Background) {
std::unique_ptr<RenderWidgetHostViewBase> view;
#if defined(USE_AURA)
view.reset(new RenderWidgetHostViewAura(
- host_.get(), false, false /* enable_surface_synchronization */));
+ host_.get(), false, false /* enable_surface_synchronization */,
+ false /* is_mus_browser_plugin_guest */));
// TODO(derat): Call this on all platforms: http://crbug.com/102450.
- view->InitAsChild(NULL);
+ view->InitAsChild(nullptr);
#elif defined(OS_ANDROID)
view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
#endif
@@ -1135,7 +1137,7 @@ TEST_F(RenderWidgetHostTest, Background) {
ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
EXPECT_FALSE(std::get<0>(sent_background));
- host_->SetView(NULL);
+ host_->SetView(nullptr);
static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
}
#endif
@@ -1189,13 +1191,13 @@ TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
SimulateKeyboardEvent(WebInputEvent::kRawKeyDown);
// Make sure we sent the input event to the renderer.
- std::vector<MockWidgetInputHandler::DispatchedEvent> dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ MockWidgetInputHandler::MessageVector dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
// Send the simulated response from the renderer back.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_FALSE(delegate_->unhandled_keyboard_event_called());
}
@@ -1224,17 +1226,14 @@ TEST_F(RenderWidgetHostTest, SendEditCommandsBeforeKeyEvent) {
SimulateKeyboardEventWithCommands(WebInputEvent::kRawKeyDown);
// Make sure we sent commands and key event to the renderer.
- std::vector<content::EditCommand> edit_commands =
- host_->mock_widget_input_handler_.GetAndResetEditCommands();
- EXPECT_EQ(1u, edit_commands.size());
-
- std::vector<MockWidgetInputHandler::DispatchedEvent> dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ MockWidgetInputHandler::MessageVector dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(2u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEditCommand());
+ ASSERT_TRUE(dispatched_events[1]->ToEvent());
// Send the simulated response from the renderer back.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
}
TEST_F(RenderWidgetHostMojoInputDisabledTest, PreHandleRawKeyDownEvent) {
@@ -1297,8 +1296,8 @@ TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
delegate_->prehandle_keyboard_event_type());
// Make sure the commands and key event are not sent to the renderer.
- std::vector<MockWidgetInputHandler::DispatchedEvent> dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ MockWidgetInputHandler::MessageVector dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
EXPECT_EQ(0u, dispatched_events.size());
// The browser won't pre-handle a Char event.
@@ -1309,7 +1308,7 @@ TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
// Make sure the Char event is suppressed.
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
EXPECT_EQ(0u, dispatched_events.size());
// Forward the KeyUp event.
@@ -1317,20 +1316,21 @@ TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
// Make sure the KeyUp event is suppressed.
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
EXPECT_EQ(0u, dispatched_events.size());
// Simulate a new RawKeyDown event.
SimulateKeyboardEvent(WebInputEvent::kRawKeyDown);
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kRawKeyDown,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
// Send the simulated response from the renderer back.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_TRUE(delegate_->unhandled_keyboard_event_called());
EXPECT_EQ(WebInputEvent::kRawKeyDown,
@@ -1403,15 +1403,16 @@ TEST_F(RenderWidgetHostTest, RawKeyDownShortcutEvent) {
delegate_->prehandle_keyboard_event_type());
// Make sure the RawKeyDown event is sent to the renderer.
- std::vector<MockWidgetInputHandler::DispatchedEvent> dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ MockWidgetInputHandler::MessageVector dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kRawKeyDown,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
// Send the simulated response from the renderer back.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(WebInputEvent::kRawKeyDown,
delegate_->unhandled_keyboard_event_type());
@@ -1424,14 +1425,15 @@ TEST_F(RenderWidgetHostTest, RawKeyDownShortcutEvent) {
// The Char event is not suppressed; the renderer will ignore it
// if the preceding RawKeyDown shortcut goes unhandled.
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kChar,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
// Send the simulated response from the renderer back.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(WebInputEvent::kChar, delegate_->unhandled_keyboard_event_type());
// Forward the KeyUp event.
@@ -1439,14 +1441,15 @@ TEST_F(RenderWidgetHostTest, RawKeyDownShortcutEvent) {
// Make sure only KeyUp was sent to the renderer.
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kKeyUp,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
// Send the simulated response from the renderer back.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(WebInputEvent::kKeyUp, delegate_->unhandled_keyboard_event_type());
}
@@ -1482,15 +1485,16 @@ void RenderWidgetHostTest::UnhandledWheelEvent() {
SimulateWheelEventPossiblyIncludingPhase(-5, 0, 0, true,
WebMouseWheelEvent::kPhaseBegan);
- std::vector<MockWidgetInputHandler::DispatchedEvent> dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ MockWidgetInputHandler::MessageVector dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kMouseWheel,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
// Send the simulated response from the renderer back.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_TRUE(delegate_->handle_wheel_event_called());
EXPECT_EQ(1, view_->unhandled_wheel_event_count());
@@ -1547,15 +1551,16 @@ void RenderWidgetHostTest::HandleWheelEvent() {
SimulateWheelEventPossiblyIncludingPhase(-5, 0, 0, true,
WebMouseWheelEvent::kPhaseBegan);
- std::vector<MockWidgetInputHandler::DispatchedEvent> dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ MockWidgetInputHandler::MessageVector dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kMouseWheel,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
// Send the simulated response from the renderer back.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
// ensure the wheel event handler was invoked
EXPECT_TRUE(delegate_->handle_wheel_event_called());
@@ -1593,15 +1598,16 @@ TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
SimulateGestureEvent(WebInputEvent::kGestureTwoFingerTap,
blink::kWebGestureDeviceTouchscreen);
- std::vector<MockWidgetInputHandler::DispatchedEvent> dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ MockWidgetInputHandler::MessageVector dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kGestureTwoFingerTap,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
// Send the simulated response from the renderer back.
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ dispatched_events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(WebInputEvent::kGestureTwoFingerTap, view_->gesture_event_type());
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, view_->ack_result());
@@ -1806,6 +1812,9 @@ TEST_F(RenderWidgetHostTest, SwapCompositorFrameWithBadSourceId) {
0);
EXPECT_FALSE(
static_cast<TestView*>(host_->GetView())->did_swap_compositor_frame());
+ EXPECT_EQ(viz::BeginFrameAck(0, 1, false),
+ static_cast<TestView*>(host_->GetView())
+ ->last_did_not_produce_frame_ack());
static_cast<TestView*>(host_->GetView())->reset_did_swap_compositor_frame();
}
@@ -1998,175 +2007,181 @@ TEST_F(RenderWidgetHostTest, TouchEmulator) {
view_->Show();
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 10, 0, false);
- std::vector<MockWidgetInputHandler::DispatchedEvent> dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ MockWidgetInputHandler::MessageVector dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
EXPECT_EQ(0u, dispatched_events.size());
// Mouse press becomes touch start which in turn becomes tap.
SimulateMouseEvent(WebInputEvent::kMouseDown, 10, 10, 0, true);
EXPECT_EQ(WebInputEvent::kTouchStart, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kGestureTapDown,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
// Mouse drag generates touch move, cancels tap and starts scroll.
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 30, 0, true);
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(4u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(4u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
+ ASSERT_TRUE(dispatched_events[1]->ToEvent());
+ ASSERT_TRUE(dispatched_events[2]->ToEvent());
+ ASSERT_TRUE(dispatched_events[3]->ToEvent());
EXPECT_EQ(WebInputEvent::kGestureTapCancel,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kGestureScrollBegin,
- dispatched_events.at(1).event_->web_event->GetType());
+ dispatched_events[1]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kTouchScrollStarted,
- dispatched_events.at(2).event_->web_event->GetType());
+ dispatched_events[2]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(3).event_->web_event->GetType());
- if (dispatched_events.at(1).callback_) {
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- }
+ dispatched_events[3]->ToEvent()->Event()->web_event->GetType());
+ dispatched_events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(WebInputEvent::kTouchMove, host_->acked_touch_event_type());
EXPECT_EQ(
0u,
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents().size());
- CallCallback(std::move(dispatched_events.at(3).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages().size());
+ dispatched_events[3]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Mouse drag with shift becomes pinch.
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 40,
WebInputEvent::kShiftKey, true);
EXPECT_EQ(WebInputEvent::kTouchMove, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kGesturePinchBegin,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 50,
WebInputEvent::kShiftKey, true);
EXPECT_EQ(WebInputEvent::kTouchMove, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kGesturePinchUpdate,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Mouse drag without shift becomes scroll again.
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 60, 0, true);
EXPECT_EQ(WebInputEvent::kTouchMove, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(2u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(2u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
+ ASSERT_TRUE(dispatched_events[1]->ToEvent());
EXPECT_EQ(WebInputEvent::kGesturePinchEnd,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(1).event_->web_event->GetType());
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_events[1]->ToEvent()->Event()->web_event->GetType());
+ dispatched_events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 70, 0, true);
EXPECT_EQ(WebInputEvent::kTouchMove, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(0).event_->web_event->GetType());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
+ dispatched_events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateMouseEvent(WebInputEvent::kMouseUp, 10, 70, 0, true);
EXPECT_EQ(WebInputEvent::kTouchEnd, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kGestureScrollEnd,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
// Mouse move does nothing.
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 80, 0, false);
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
EXPECT_EQ(0u, dispatched_events.size());
// Another mouse down continues scroll.
SimulateMouseEvent(WebInputEvent::kMouseDown, 10, 80, 0, true);
EXPECT_EQ(WebInputEvent::kTouchStart, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kGestureTapDown,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 100, 0, true);
EXPECT_EQ(WebInputEvent::kTouchMove, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(4u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(4u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
+ ASSERT_TRUE(dispatched_events[1]->ToEvent());
+ ASSERT_TRUE(dispatched_events[2]->ToEvent());
+ ASSERT_TRUE(dispatched_events[3]->ToEvent());
EXPECT_EQ(WebInputEvent::kGestureTapCancel,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kGestureScrollBegin,
- dispatched_events.at(1).event_->web_event->GetType());
+ dispatched_events[1]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kTouchScrollStarted,
- dispatched_events.at(2).event_->web_event->GetType());
+ dispatched_events[2]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(3).event_->web_event->GetType());
- if (dispatched_events.at(1).callback_) {
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- }
+ dispatched_events[3]->ToEvent()->Event()->web_event->GetType());
+ dispatched_events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(
0u,
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents().size());
- CallCallback(std::move(dispatched_events.at(3).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages().size());
+ dispatched_events[3]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Another pinch.
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 110,
WebInputEvent::kShiftKey, true);
EXPECT_EQ(WebInputEvent::kTouchMove, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
EXPECT_EQ(1u, dispatched_events.size());
EXPECT_EQ(WebInputEvent::kGesturePinchBegin,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 120,
WebInputEvent::kShiftKey, true);
EXPECT_EQ(WebInputEvent::kTouchMove, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
EXPECT_EQ(1u, dispatched_events.size());
EXPECT_EQ(WebInputEvent::kGesturePinchUpdate,
- dispatched_events.at(0).event_->web_event->GetType());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
+ dispatched_events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Turn off emulation during a pinch.
host_->GetTouchEmulator()->Disable();
EXPECT_EQ(WebInputEvent::kTouchCancel, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(2u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(2u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
+ ASSERT_TRUE(dispatched_events[1]->ToEvent());
EXPECT_EQ(WebInputEvent::kGesturePinchEnd,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kGestureScrollEnd,
- dispatched_events.at(1).event_->web_event->GetType());
+ dispatched_events[1]->ToEvent()->Event()->web_event->GetType());
// Mouse event should pass untouched.
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 10,
WebInputEvent::kShiftKey, true);
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kMouseMove,
- dispatched_events.at(0).event_->web_event->GetType());
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
+ dispatched_events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Turn on emulation.
host_->GetTouchEmulator()->Enable(
@@ -2177,44 +2192,46 @@ TEST_F(RenderWidgetHostTest, TouchEmulator) {
SimulateMouseEvent(WebInputEvent::kMouseDown, 10, 10, 0, true);
EXPECT_EQ(WebInputEvent::kTouchStart, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kGestureTapDown,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
// Scroll.
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 30, 0, true);
EXPECT_EQ(WebInputEvent::kTouchMove, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(4u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(4u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
+ ASSERT_TRUE(dispatched_events[1]->ToEvent());
+ ASSERT_TRUE(dispatched_events[2]->ToEvent());
+ ASSERT_TRUE(dispatched_events[3]->ToEvent());
EXPECT_EQ(WebInputEvent::kGestureTapCancel,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kGestureScrollBegin,
- dispatched_events.at(1).event_->web_event->GetType());
+ dispatched_events[1]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kTouchScrollStarted,
- dispatched_events.at(2).event_->web_event->GetType());
+ dispatched_events[2]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(3).event_->web_event->GetType());
- if (dispatched_events.at(1).callback_) {
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- }
+ dispatched_events[3]->ToEvent()->Event()->web_event->GetType());
+ dispatched_events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(
0u,
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents().size());
- CallCallback(std::move(dispatched_events.at(3).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages().size());
+ dispatched_events[3]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Turn off emulation during a scroll.
host_->GetTouchEmulator()->Disable();
EXPECT_EQ(WebInputEvent::kTouchCancel, host_->acked_touch_event_type());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
- EXPECT_EQ(1u, dispatched_events.size());
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
EXPECT_EQ(WebInputEvent::kGestureScrollEnd,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
}
TEST_F(RenderWidgetHostTest, IgnoreInputEvent) {
@@ -2345,7 +2362,7 @@ void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process,
EXPECT_TRUE(event->GetType() == expected_type);
EXPECT_TRUE(latency_info.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, component_id, NULL));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, component_id, nullptr));
process->sink().ClearMessages();
}
@@ -2373,7 +2390,7 @@ void CheckLatencyInfoComponentInGestureScrollUpdate(
EXPECT_TRUE(event->GetType() == WebInputEvent::kGestureScrollUpdate);
EXPECT_TRUE(latency_info.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, component_id, NULL));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, component_id, nullptr));
process->sink().ClearMessages();
}
@@ -2452,33 +2469,35 @@ TEST_F(RenderWidgetHostAsyncWheelEventsEnabledMojoInputDisabledTest,
}
void CheckLatencyInfoComponentInMessage(
- std::vector<MockWidgetInputHandler::DispatchedEvent>& dispatched_events,
+ MockWidgetInputHandler::MessageVector& dispatched_events,
int64_t component_id,
WebInputEvent::Type expected_type) {
- EXPECT_EQ(1u, dispatched_events.size());
- EXPECT_TRUE(dispatched_events.at(0).event_->web_event->GetType() ==
+ ASSERT_EQ(1u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
+
+ EXPECT_TRUE(dispatched_events[0]->ToEvent()->Event()->web_event->GetType() ==
expected_type);
- EXPECT_TRUE(dispatched_events.at(0).event_->latency_info.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, component_id, NULL));
- if (dispatched_events.at(0).callback_) {
- CallCallback(std::move(dispatched_events.at(0).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
- }
+ EXPECT_TRUE(
+ dispatched_events[0]->ToEvent()->Event()->latency_info.FindLatency(
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, component_id, nullptr));
+ dispatched_events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
}
void CheckLatencyInfoComponentInGestureScrollUpdate(
- std::vector<MockWidgetInputHandler::DispatchedEvent>& dispatched_events,
+ MockWidgetInputHandler::MessageVector& dispatched_events,
int64_t component_id) {
- EXPECT_EQ(2u, dispatched_events.size());
+ ASSERT_EQ(2u, dispatched_events.size());
+ ASSERT_TRUE(dispatched_events[0]->ToEvent());
+ ASSERT_TRUE(dispatched_events[1]->ToEvent());
EXPECT_EQ(WebInputEvent::kTouchScrollStarted,
- dispatched_events.at(0).event_->web_event->GetType());
+ dispatched_events[0]->ToEvent()->Event()->web_event->GetType());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_events.at(1).event_->web_event->GetType());
- EXPECT_TRUE(dispatched_events.at(1).event_->latency_info.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, component_id, NULL));
- CallCallback(std::move(dispatched_events.at(1).callback_),
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_events[1]->ToEvent()->Event()->web_event->GetType());
+ EXPECT_TRUE(
+ dispatched_events[1]->ToEvent()->Event()->latency_info.FindLatency(
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, component_id, nullptr));
+ dispatched_events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
}
// Tests that after input event passes through RWHI through ForwardXXXEvent()
@@ -2491,8 +2510,8 @@ void RenderWidgetHostTest::InputEventRWHLatencyComponent() {
// Tests RWHI::ForwardWheelEvent().
SimulateWheelEventPossiblyIncludingPhase(-5, 0, 0, true,
WebMouseWheelEvent::kPhaseBegan);
- std::vector<MockWidgetInputHandler::DispatchedEvent> dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ MockWidgetInputHandler::MessageVector dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
WebInputEvent::kMouseWheel);
@@ -2500,14 +2519,14 @@ void RenderWidgetHostTest::InputEventRWHLatencyComponent() {
SimulateWheelEventWithLatencyInfoAndPossiblyPhase(
-5, 0, 0, true, ui::LatencyInfo(), WebMouseWheelEvent::kPhaseChanged);
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
WebInputEvent::kMouseWheel);
// Tests RWHI::ForwardMouseEvent().
SimulateMouseEvent(WebInputEvent::kMouseMove);
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
WebInputEvent::kMouseMove);
@@ -2515,7 +2534,7 @@ void RenderWidgetHostTest::InputEventRWHLatencyComponent() {
SimulateMouseEventWithLatencyInfo(WebInputEvent::kMouseMove,
ui::LatencyInfo());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
WebInputEvent::kMouseMove);
@@ -2523,7 +2542,7 @@ void RenderWidgetHostTest::InputEventRWHLatencyComponent() {
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
WebInputEvent::kGestureScrollBegin);
@@ -2532,7 +2551,7 @@ void RenderWidgetHostTest::InputEventRWHLatencyComponent() {
blink::kWebGestureDeviceTouchscreen,
ui::LatencyInfo());
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
CheckLatencyInfoComponentInGestureScrollUpdate(dispatched_events,
GetLatencyComponentId());
@@ -2540,7 +2559,7 @@ void RenderWidgetHostTest::InputEventRWHLatencyComponent() {
PressTouchPoint(0, 1);
SendTouchEvent();
dispatched_events =
- host_->mock_widget_input_handler_.GetAndResetDispatchedEvents();
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
WebInputEvent::kTouchStart);
}
@@ -2882,6 +2901,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_RendererCrash) {
host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
EXPECT_EQ(0u, host_->queued_messages_.size());
EXPECT_EQ(0u, host_->processed_frame_messages_count());
+ host_->SetView(view_.get());
host_->Init();
host_->OnMessageReceived(
@@ -2896,4 +2916,16 @@ TEST_F(RenderWidgetHostTest, FrameToken_RendererCrash) {
EXPECT_EQ(1u, host_->processed_frame_messages_count());
}
+TEST_F(RenderWidgetHostTest, InflightEventCountResetsAfterRebind) {
+ // Simulate a keyboard event.
+ SimulateKeyboardEvent(WebInputEvent::kRawKeyDown);
+
+ EXPECT_EQ(1u, host_->in_flight_event_count());
+ mojom::WidgetPtr widget;
+ std::unique_ptr<MockWidgetImpl> widget_impl =
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ host_->SetWidget(std::move(widget));
+ EXPECT_EQ(0u, host_->in_flight_event_count());
+}
+
} // namespace content
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 f0b5e5c4a33..696c6d76bad 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
@@ -30,6 +30,7 @@
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/common/gl_helper.h"
+#include "components/viz/common/gpu/context_lost_observer.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/resources/single_release_callback.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
@@ -89,8 +90,9 @@
#include "ui/android/window_android_compositor.h"
#include "ui/base/layout.h"
#include "ui/base/ui_base_types.h"
+#include "ui/events/android/gesture_event_android.h"
+#include "ui/events/android/gesture_event_type.h"
#include "ui/events/android/motion_event_android.h"
-#include "ui/events/base_event_utils.h"
#include "ui/events/blink/blink_event_util.h"
#include "ui/events/blink/did_overscroll_params.h"
#include "ui/events/blink/web_input_event_traits.h"
@@ -133,10 +135,12 @@ class PendingReadbackLock : public base::RefCounted<PendingReadbackLock> {
using base::android::ApplicationState;
using base::android::ApplicationStatusListener;
-class GLHelperHolder {
+class GLHelperHolder : public viz::ContextLostObserver {
public:
static GLHelperHolder* Create();
+ ~GLHelperHolder() override;
+
viz::GLHelper* gl_helper() { return gl_helper_.get(); }
bool IsLost() {
if (!gl_helper_)
@@ -148,10 +152,13 @@ class GLHelperHolder {
private:
GLHelperHolder();
+
void Initialize();
- void OnContextLost();
void OnApplicationStatusChanged(ApplicationState new_state);
+ // viz::ContextLostObserver implementation.
+ void OnContextLost() override;
+
scoped_refptr<ui::ContextProviderCommandBuffer> provider_;
std::unique_ptr<viz::GLHelper> gl_helper_;
@@ -170,6 +177,11 @@ GLHelperHolder::GLHelperHolder()
(ApplicationStatusListener::GetState() ==
base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES)) {}
+GLHelperHolder::~GLHelperHolder() {
+ if (provider_)
+ provider_->RemoveObserver(this);
+}
+
GLHelperHolder* GLHelperHolder::Create() {
GLHelperHolder* holder = new GLHelperHolder;
holder->Initialize();
@@ -219,14 +231,14 @@ void GLHelperHolder::Initialize() {
gpu::kNullSurfaceHandle, url, automatic_flushes, support_locking, limits,
attributes, nullptr,
ui::command_buffer_metrics::BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT);
- if (!provider_->BindToCurrentThread())
+ auto result = provider_->BindToCurrentThread();
+ if (result != gpu::ContextResult::kSuccess)
return;
provider_->ContextGL()->TraceBeginCHROMIUM(
"gpu_toplevel",
base::StringPrintf("CmdBufferImageTransportFactory-%p", provider_.get())
.c_str());
- provider_->SetLostContextCallback(
- base::Bind(&GLHelperHolder::OnContextLost, base::Unretained(this)));
+ provider_->AddObserver(this);
gl_helper_.reset(
new viz::GLHelper(provider_->ContextGL(), provider_->ContextSupport()));
@@ -238,6 +250,8 @@ void GLHelperHolder::Initialize() {
void GLHelperHolder::ReleaseIfPossible() {
if (!has_running_or_paused_activities_ && !g_pending_readback_lock) {
gl_helper_.reset();
+ if (provider_)
+ provider_->RemoveObserver(this);
provider_ = nullptr;
// Make sure this will get recreated on next use.
DCHECK(IsLost());
@@ -335,7 +349,7 @@ std::unique_ptr<ui::TouchSelectionController> CreateSelectionController(
config.enable_longpress_drag_selection =
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableLongpressDragSelection);
- return base::MakeUnique<ui::TouchSelectionController>(client, config);
+ return std::make_unique<ui::TouchSelectionController>(client, config);
}
gfx::RectF GetSelectionRect(const ui::TouchSelectionController& controller) {
@@ -365,15 +379,12 @@ void PrepareTextureCopyOutputResult(
"RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult");
if (result->IsEmpty())
return;
+ DCHECK_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE);
- viz::TextureMailbox texture_mailbox;
- std::unique_ptr<viz::SingleReleaseCallback> release_callback;
- if (auto* mailbox = result->GetTextureMailbox()) {
- texture_mailbox = *mailbox;
- release_callback = result->TakeTextureOwnership();
- }
- if (!texture_mailbox.IsTexture())
- return;
+ gpu::Mailbox mailbox = result->GetTextureResult()->mailbox;
+ gpu::SyncToken sync_token = result->GetTextureResult()->sync_token;
+ std::unique_ptr<viz::SingleReleaseCallback> release_callback =
+ result->TakeTextureOwnership();
viz::GLHelper* gl_helper = GetPostReadbackGLHelper();
if (!gl_helper)
@@ -402,8 +413,8 @@ void PrepareTextureCopyOutputResult(
ignore_result(scoped_callback_runner.Release());
gl_helper->CropScaleReadbackAndCleanMailbox(
- texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(),
- output_size_in_pixel, pixels, color_type,
+ mailbox, sync_token, result->size(), output_size_in_pixel, pixels,
+ color_type,
base::Bind(&CopyFromCompositingSurfaceFinished, callback,
base::Passed(&release_callback), base::Passed(&bitmap),
start_time, readback_lock),
@@ -472,6 +483,9 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
observing_root_window_(false),
prev_top_shown_pix_(0.f),
prev_bottom_shown_pix_(0.f),
+ page_scale_(1.f),
+ min_page_scale_(1.f),
+ max_page_scale_(1.f),
mouse_wheel_phase_handler_(widget_host, this),
weak_ptr_factory_(this) {
// Set the layer which will hold the content layer for this view. The content
@@ -495,7 +509,7 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
host_->SetView(this);
touch_selection_controller_client_manager_ =
- base::MakeUnique<TouchSelectionControllerClientManagerAndroid>(this);
+ std::make_unique<TouchSelectionControllerClientManagerAndroid>(this);
SetContentViewCore(content_view_core);
CreateOverscrollControllerIfPossible();
@@ -667,12 +681,6 @@ void RenderWidgetHostViewAndroid::OnShowUnhandledTapUIIfNeeded(int x_dip,
int y_dip) {
if (!selection_popup_controller_ || !content_view_core_)
return;
- // Validate the coordinates are within the viewport.
- // TODO(jinsukkim): Get viewport size from ViewAndroid.
- gfx::Size viewport_size = content_view_core_->GetViewportSizeDip();
- if (x_dip < 0 || x_dip > viewport_size.width() ||
- y_dip < 0 || y_dip > viewport_size.height())
- return;
selection_popup_controller_->OnShowUnhandledTapUIIfNeeded(
x_dip, y_dip, view_.GetDipScale());
}
@@ -690,7 +698,7 @@ gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
if (!content_view_core_)
return default_bounds_;
- gfx::Size size(content_view_core_->GetViewSize());
+ gfx::Size size(view_.GetSize());
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableOSKOverscroll)) {
size.Enlarge(0, view_.GetSystemWindowInsetBottom() / view_.GetDipScale());
@@ -703,7 +711,7 @@ gfx::Size RenderWidgetHostViewAndroid::GetVisibleViewportSize() const {
if (!content_view_core_)
return default_bounds_.size();
- return content_view_core_->GetViewSize();
+ return view_.GetSize();
}
gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
@@ -719,26 +727,42 @@ gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
}
bool RenderWidgetHostViewAndroid::DoBrowserControlsShrinkBlinkSize() const {
- // Whether or not Blink's viewport size should be shrunk by the height of the
- // URL-bar.
- return content_view_core_ &&
- content_view_core_->DoBrowserControlsShrinkBlinkSize();
+ RenderWidgetHostDelegate* delegate = host_->delegate();
+ if (!delegate)
+ return false;
+
+ RenderViewHostDelegateView* delegate_view = delegate->GetDelegateView();
+ return delegate_view ? delegate_view->DoBrowserControlsShrinkBlinkSize()
+ : false;
}
float RenderWidgetHostViewAndroid::GetTopControlsHeight() const {
- if (!content_view_core_)
- return default_bounds_.x();
+ RenderWidgetHostDelegate* delegate = host_->delegate();
+ if (!delegate)
+ return 0.f;
- // The height of the browser controls.
- return content_view_core_->GetTopControlsHeightDip();
+ RenderViewHostDelegateView* delegate_view = delegate->GetDelegateView();
+ return delegate_view ? delegate_view->GetTopControlsHeight() : 0.f;
}
float RenderWidgetHostViewAndroid::GetBottomControlsHeight() const {
- if (!content_view_core_)
+ RenderWidgetHostDelegate* delegate = host_->delegate();
+ if (!delegate)
return 0.f;
- // The height of the browser controls.
- return content_view_core_->GetBottomControlsHeightDip();
+ RenderViewHostDelegateView* delegate_view = delegate->GetDelegateView();
+ return delegate_view ? delegate_view->GetBottomControlsHeight() : 0.f;
+}
+
+int RenderWidgetHostViewAndroid::GetMouseWheelMinimumGranularity() const {
+ if (!content_view_core_)
+ return 0;
+
+ // On Android, mouse wheel MotionEvents specify the number of ticks and how
+ // many pixels each tick scrolls. This multiplier is specified by device
+ // metrics (See RenderCoordinates::mWheelScrollFactor) so the minimum
+ // granularity will be the size of this tick multiplier.
+ return content_view_core_->GetMouseWheelMinimumGranularity();
}
void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
@@ -847,8 +871,8 @@ viz::SurfaceId RenderWidgetHostViewAndroid::SurfaceIdForTesting() const {
viz::FrameSinkId RenderWidgetHostViewAndroid::FrameSinkIdAtPoint(
viz::SurfaceHittestDelegate* delegate,
- const gfx::Point& point,
- gfx::Point* transformed_point) {
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point) {
if (!delegated_frame_host_)
return viz::FrameSinkId();
@@ -856,15 +880,15 @@ viz::FrameSinkId RenderWidgetHostViewAndroid::FrameSinkIdAtPoint(
DCHECK_GT(scale_factor, 0);
// The surface hittest happens in device pixels, so we need to convert the
// |point| from DIPs to pixels before hittesting.
- gfx::Point point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point);
+ gfx::PointF point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point);
viz::SurfaceId surface_id = delegated_frame_host_->SurfaceId();
if (surface_id.is_valid()) {
viz::SurfaceHittest hittest(delegate,
GetFrameSinkManager()->surface_manager());
gfx::Transform target_transform;
- surface_id = hittest.GetTargetSurfaceAtPoint(surface_id, point_in_pixels,
- &target_transform);
+ surface_id = hittest.GetTargetSurfaceAtPoint(
+ surface_id, gfx::ToFlooredPoint(point_in_pixels), &target_transform);
*transformed_point = point_in_pixels;
if (surface_id.is_valid())
target_transform.TransformPoint(transformed_point);
@@ -904,9 +928,9 @@ void RenderWidgetHostViewAndroid::ProcessGestureEvent(
}
bool RenderWidgetHostViewAndroid::TransformPointToLocalCoordSpace(
- const gfx::Point& point,
+ const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
if (!delegated_frame_host_)
return false;
@@ -914,7 +938,7 @@ bool RenderWidgetHostViewAndroid::TransformPointToLocalCoordSpace(
DCHECK_GT(scale_factor, 0);
// Transformations use physical pixels rather than DIP, so conversion
// is necessary.
- gfx::Point point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point);
+ gfx::PointF point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point);
viz::SurfaceId surface_id = delegated_frame_host_->SurfaceId();
if (!surface_id.is_valid())
@@ -935,9 +959,9 @@ bool RenderWidgetHostViewAndroid::TransformPointToLocalCoordSpace(
}
bool RenderWidgetHostViewAndroid::TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
if (target_view == this || !delegated_frame_host_) {
*transformed_point = point;
return true;
@@ -959,6 +983,24 @@ RenderWidgetHostViewAndroid::GetWeakPtrAndroid() {
return weak_ptr_factory_.GetWeakPtr();
}
+bool RenderWidgetHostViewAndroid::OnGestureEvent(
+ const ui::GestureEventAndroid& event) {
+ std::unique_ptr<blink::WebGestureEvent> web_event;
+ if (event.delta() < 0.f) {
+ // Negative delta indicates zoom reset.
+ float delta = min_page_scale_ / page_scale_;
+ web_event = ui::CreateWebGestureEventFromGestureEventAndroid(
+ ui::GestureEventAndroid(event.type(), event.location(),
+ event.screen_location(), event.time(), delta));
+ } else {
+ web_event = ui::CreateWebGestureEventFromGestureEventAndroid(event);
+ }
+ if (!web_event)
+ return false;
+ SendGestureEvent(*web_event);
+ return true;
+}
+
bool RenderWidgetHostViewAndroid::OnTouchEvent(
const ui::MotionEventAndroid& event) {
RecordToolTypeForActionDown(event);
@@ -996,6 +1038,9 @@ bool RenderWidgetHostViewAndroid::OnTouchEvent(
blink::WebTouchEvent web_event = ui::CreateWebTouchEventFromMotionEvent(
event, result.moved_beyond_slop_region);
+ if (web_event.GetType() == blink::WebInputEvent::kUndefined)
+ return false;
+
ui::LatencyInfo latency_info(ui::SourceEventType::TOUCH);
latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0);
if (host_->delegate()->GetInputEventRouter()) {
@@ -1205,6 +1250,10 @@ void RenderWidgetHostViewAndroid::ReclaimResources(
SendReclaimCompositorResources(false /* is_swap_ack */);
}
+void RenderWidgetHostViewAndroid::OnFrameTokenChanged(uint32_t frame_token) {
+ OnFrameTokenChangedForView(frame_token);
+}
+
void RenderWidgetHostViewAndroid::DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
if (!delegated_frame_host_) {
@@ -1239,7 +1288,8 @@ void RenderWidgetHostViewAndroid::EvictFrameIfNecessary() {
void RenderWidgetHostViewAndroid::SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) {
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) {
if (!delegated_frame_host_) {
DCHECK(!using_browser_compositor_);
return;
@@ -1482,11 +1532,16 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
bool is_mobile_optimized = IsMobileOptimizedFrame(frame_metadata);
gesture_provider_.SetDoubleTapSupportForPageEnabled(!is_mobile_optimized);
- float dip_scale = IsUseZoomForDSFEnabled() ? 1.f : view_.GetDipScale();
- float top_controls_pix = frame_metadata.top_controls_height * dip_scale;
+ float dip_scale = view_.GetDipScale();
+ float to_pix = IsUseZoomForDSFEnabled() ? 1.f : dip_scale;
+ float top_controls_pix = frame_metadata.top_controls_height * to_pix;
+ // |top_content_offset| is its CSS pixels * DSF if --use-zoom-for-dsf is
+ // enabled. Otherwise, it is in CSS pixels.
+ // Note that the height of browser control is not affected by page scale
+ // factor. Thus, |top_content_offset| in CSS pixels is also in DIP pixels.
float top_content_offset = frame_metadata.top_controls_height *
frame_metadata.top_controls_shown_ratio;
- float top_shown_pix = top_content_offset * dip_scale;
+ float top_shown_pix = top_content_offset * to_pix;
if (ime_adapter_android_)
ime_adapter_android_->UpdateFrameInfo(frame_metadata.selection.start,
@@ -1522,8 +1577,12 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
UpdateBackgroundColor(is_transparent ? SK_ColorTRANSPARENT
: frame_metadata.root_background_color);
- view_.UpdateFrameInfo({frame_metadata.scrollable_viewport_size,
- frame_metadata.page_scale_factor, top_content_offset});
+ // ViewAndroid::content_offset() must be in CSS scale
+ float top_content_offset_css = IsUseZoomForDSFEnabled()
+ ? top_content_offset / dip_scale
+ : top_content_offset;
+ view_.UpdateFrameInfo(
+ {frame_metadata.scrollable_viewport_size, top_content_offset});
bool top_changed = !FloatEquals(top_shown_pix, prev_top_shown_pix_);
if (top_changed) {
@@ -1532,7 +1591,7 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
prev_top_shown_pix_ = top_shown_pix;
}
- float bottom_controls_pix = frame_metadata.bottom_controls_height * dip_scale;
+ float bottom_controls_pix = frame_metadata.bottom_controls_height * to_pix;
float bottom_shown_pix =
bottom_controls_pix * frame_metadata.bottom_controls_shown_ratio;
bool bottom_changed = !FloatEquals(bottom_shown_pix, prev_bottom_shown_pix_);
@@ -1542,13 +1601,17 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
prev_bottom_shown_pix_ = bottom_shown_pix;
}
- // All offsets and sizes are in CSS pixels.
+ page_scale_ = frame_metadata.page_scale_factor;
+ min_page_scale_ = frame_metadata.min_page_scale_factor;
+ max_page_scale_ = frame_metadata.max_page_scale_factor;
+
+ // All offsets and sizes except |top_shown_pix| are in CSS pixels.
content_view_core_->UpdateFrameInfo(
frame_metadata.root_scroll_offset, frame_metadata.page_scale_factor,
- gfx::Vector2dF(frame_metadata.min_page_scale_factor,
- frame_metadata.max_page_scale_factor),
- frame_metadata.root_layer_size, frame_metadata.scrollable_viewport_size,
- top_content_offset, top_shown_pix, top_changed, is_mobile_optimized);
+ frame_metadata.min_page_scale_factor,
+ frame_metadata.max_page_scale_factor, frame_metadata.root_layer_size,
+ frame_metadata.scrollable_viewport_size, top_content_offset_css,
+ top_shown_pix, top_changed, is_mobile_optimized);
EvictFrameIfNecessary();
}
@@ -1856,9 +1919,11 @@ void RenderWidgetHostViewAndroid::SendMouseEvent(
blink::WebInputEvent::Type webMouseEventType =
ui::ToWebMouseEventType(motion_event.GetAction());
+ if (webMouseEventType == blink::WebInputEvent::kUndefined)
+ return;
+
if (webMouseEventType == blink::WebInputEvent::kMouseDown)
- UpdateLeftClickCount(action_button, motion_event.GetX(0),
- motion_event.GetY(0));
+ UpdateMouseState(action_button, motion_event.GetX(0), motion_event.GetY(0));
int click_count = 0;
@@ -1869,12 +1934,7 @@ void RenderWidgetHostViewAndroid::SendMouseEvent(
: 1;
blink::WebMouseEvent mouse_event = WebMouseEventBuilder::Build(
- webMouseEventType,
- ui::EventTimeStampToSeconds(motion_event.GetEventTime()),
- motion_event.GetX(0), motion_event.GetY(0), motion_event.GetFlags(),
- click_count, motion_event.GetPointerId(0), motion_event.GetPressure(0),
- motion_event.GetOrientation(0), motion_event.GetTiltX(0),
- motion_event.GetTiltY(0), action_button, motion_event.GetToolType(0));
+ motion_event, webMouseEventType, click_count, action_button);
if (!host_ || !host_->delegate())
return;
@@ -1887,9 +1947,9 @@ void RenderWidgetHostViewAndroid::SendMouseEvent(
}
}
-void RenderWidgetHostViewAndroid::UpdateLeftClickCount(int action_button,
- float mousedown_x,
- float mousedown_y) {
+void RenderWidgetHostViewAndroid::UpdateMouseState(int action_button,
+ float mousedown_x,
+ float mousedown_y) {
if (action_button != ui::MotionEventAndroid::BUTTON_PRIMARY) {
// Reset state if middle or right button was pressed.
left_click_count_ = 0;
@@ -1938,8 +1998,10 @@ void RenderWidgetHostViewAndroid::SendGestureEvent(
if (overscroll_controller_)
overscroll_controller_->Enable();
- if (!host_ || !host_->delegate())
+ if (!host_ || !host_->delegate() ||
+ event.GetType() == blink::WebInputEvent::kUndefined) {
return;
+ }
// We let the touch selection controller see gesture events here, since they
// may be routed and not make it to FilterInputEvent().
@@ -2090,13 +2152,6 @@ void RenderWidgetHostViewAndroid::SetContentViewCore(
if (content_view_core != content_view_core_) {
touch_selection_controller_.reset();
RunAckCallbacks();
- // TODO(yusufo) : Get rid of the below conditions and have a better handling
- // for resizing after crbug.com/628302 is handled.
- bool is_size_initialized = !content_view_core
- || content_view_core->GetViewportSizeDip().width() != 0
- || content_view_core->GetViewportSizeDip().height() != 0;
- if (content_view_core_ || is_size_initialized)
- resize = true;
if (content_view_core_) {
view_.RemoveObserver(this);
view_.RemoveFromParent();
@@ -2108,6 +2163,13 @@ void RenderWidgetHostViewAndroid::SetContentViewCore(
parent_view->AddChild(&view_);
parent_view->GetLayer()->AddChild(view_.GetLayer());
}
+ // TODO(yusufo) : Get rid of the below conditions and have a better handling
+ // for resizing after crbug.com/628302 is handled.
+ bool is_size_initialized = !content_view_core ||
+ view_.GetSize().width() != 0 ||
+ view_.GetSize().height() != 0;
+ if (content_view_core_ || is_size_initialized)
+ resize = true;
content_view_core_ = content_view_core;
}
@@ -2157,9 +2219,7 @@ bool RenderWidgetHostViewAndroid::OnMouseEvent(
bool RenderWidgetHostViewAndroid::OnMouseWheelEvent(
const ui::MotionEventAndroid& event) {
- SendMouseWheelEvent(WebMouseWheelEventBuilder::Build(
- event.ticks_x(), event.ticks_y(), event.GetTickMultiplier(),
- event.time_sec(), event.GetX(0), event.GetY(0)));
+ SendMouseWheelEvent(WebMouseWheelEventBuilder::Build(event));
return true;
}
@@ -2406,13 +2466,13 @@ void RenderWidgetHostViewAndroid::CreateOverscrollControllerIfPossible() {
if (!compositor)
return;
- overscroll_controller_ = base::MakeUnique<OverscrollControllerAndroid>(
+ overscroll_controller_ = std::make_unique<OverscrollControllerAndroid>(
overscroll_refresh_handler, compositor, view_.GetDipScale());
}
void RenderWidgetHostViewAndroid::SetOverscrollControllerForTesting(
ui::OverscrollRefreshHandler* overscroll_refresh_handler) {
- overscroll_controller_ = base::MakeUnique<OverscrollControllerAndroid>(
+ overscroll_controller_ = std::make_unique<OverscrollControllerAndroid>(
overscroll_refresh_handler, view_.GetWindowAndroid()->GetCompositor(),
view_.GetDipScale());
}
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 a552a90c2d6..67dbc3fb30c 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
@@ -128,6 +128,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
bool DoBrowserControlsShrinkBlinkSize() const override;
float GetTopControlsHeight() const override;
float GetBottomControlsHeight() const override;
+ int GetMouseWheelMinimumGranularity() const override;
void UpdateCursor(const WebCursor& cursor) override;
void SetIsLoading(bool is_loading) override;
void FocusedNodeChanged(bool is_editable_node,
@@ -155,8 +156,10 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink)
override;
- void SubmitCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) override;
+ void SubmitCompositorFrame(
+ const viz::LocalSurfaceId& local_surface_id,
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) override;
void OnDidNotProduceFrame(const viz::BeginFrameAck& ack) override;
void ClearCompositorFrame() override;
void SetIsInVR(bool is_in_vr) override;
@@ -171,8 +174,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void SetNeedsBeginFrames(bool needs_begin_frames) override;
viz::FrameSinkId GetFrameSinkId() override;
viz::FrameSinkId FrameSinkIdAtPoint(viz::SurfaceHittestDelegate* delegate,
- const gfx::Point& point,
- gfx::Point* transformed_point) override;
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point) override;
void ProcessMouseEvent(const blink::WebMouseEvent& event,
const ui::LatencyInfo& latency) override;
void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event,
@@ -181,13 +184,13 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
const ui::LatencyInfo& latency) override;
void ProcessGestureEvent(const blink::WebGestureEvent& event,
const ui::LatencyInfo& latency) override;
- bool TransformPointToLocalCoordSpace(const gfx::Point& point,
+ bool TransformPointToLocalCoordSpace(const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point) override;
+ gfx::PointF* transformed_point) override;
bool TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point) override;
+ gfx::PointF* transformed_point) override;
TouchSelectionControllerClientManager*
GetTouchSelectionControllerClientManager() override;
@@ -195,6 +198,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
bool OnTouchEvent(const ui::MotionEventAndroid& m) override;
bool OnMouseEvent(const ui::MotionEventAndroid& m) override;
bool OnMouseWheelEvent(const ui::MotionEventAndroid& event) override;
+ bool OnGestureEvent(const ui::GestureEventAndroid& event) override;
void OnPhysicalBackingSizeChanged() override;
// ui::ViewAndroidObserver implementation:
@@ -238,6 +242,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void DidReceiveCompositorFrameAck() override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
+ void OnFrameTokenChanged(uint32_t frame_token) override;
// viz::BeginFrameObserver implementation.
void OnBeginFrame(const viz::BeginFrameArgs& args) override;
@@ -378,9 +383,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void CreateOverscrollControllerIfPossible();
- void UpdateLeftClickCount(int action_button,
- float mousedown_x,
- float mouse_down_y);
+ void UpdateMouseState(int action_button,
+ float mousedown_x,
+ float mouse_down_y);
WebContentsAccessibilityAndroid* GetWebContentsAccessibilityAndroid() const;
@@ -472,6 +477,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
float prev_top_shown_pix_;
float prev_bottom_shown_pix_;
+ float page_scale_;
+ float min_page_scale_;
+ float max_page_scale_;
base::TimeTicks prev_mousedown_timestamp_;
gfx::Point prev_mousedown_point_;
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 9bcef0992e7..2662e67f7ee 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
@@ -23,7 +23,7 @@
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/common/gl_helper.h"
-#include "components/viz/common/quads/texture_mailbox.h"
+#include "components/viz/common/switches.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/bad_message.h"
@@ -31,6 +31,7 @@
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/gpu/compositor_util.h"
+#include "content/browser/mus_util.h"
#include "content/browser/renderer_host/cursor_manager.h"
#include "content/browser/renderer_host/delegated_frame_host_client_aura.h"
#include "content/browser/renderer_host/dip_util.h"
@@ -59,6 +60,7 @@
#include "gpu/ipc/common/gpu_messages.h"
#include "media/base/video_frame.h"
#include "services/service_manager/public/cpp/interface_provider.h"
+#include "services/ui/common/switches.h"
#include "services/ui/public/interfaces/window_manager_constants.mojom.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebImeTextSpan.h"
@@ -80,6 +82,7 @@
#include "ui/base/hit_test.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ui_base_switches.h"
+#include "ui/base/ui_base_switches_util.h"
#include "ui/base/ui_base_types.h"
#include "ui/compositor/compositor_vsync_manager.h"
#include "ui/compositor/dip_util.h"
@@ -359,7 +362,8 @@ class RenderWidgetHostViewAura::WindowAncestorObserver
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) override {
+ const gfx::Rect& new_bounds,
+ ui::PropertyChangeReason reason) override {
DCHECK(ancestors_.find(window) != ancestors_.end());
if (new_bounds.origin() != old_bounds.origin())
view_->HandleParentBoundsChanged();
@@ -378,9 +382,6 @@ class RenderWidgetHostViewAura::WindowAncestorObserver
DISALLOW_COPY_AND_ASSIGN(WindowAncestorObserver);
};
-bool IsMus() {
- return aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS;
-}
////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, public:
@@ -388,9 +389,11 @@ bool IsMus() {
RenderWidgetHostViewAura::RenderWidgetHostViewAura(
RenderWidgetHost* host,
bool is_guest_view_hack,
- bool enable_surface_synchronization)
+ bool enable_surface_synchronization,
+ bool is_mus_browser_plugin_guest)
: host_(RenderWidgetHostImpl::From(host)),
enable_surface_synchronization_(enable_surface_synchronization),
+ is_mus_browser_plugin_guest_(is_mus_browser_plugin_guest),
window_(nullptr),
in_shutdown_(false),
in_bounds_changed_(false),
@@ -411,8 +414,9 @@ 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_(IsMus() ? viz::FrameSinkId()
- : host_->AllocateFrameSinkId(is_guest_view_hack_)),
+ frame_sink_id_(switches::IsMusHostingViz()
+ ? viz::FrameSinkId()
+ : host_->AllocateFrameSinkId(is_guest_view_hack_)),
weak_ptr_factory_(this) {
if (!is_guest_view_hack_)
host_->SetView(this);
@@ -443,8 +447,10 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(
////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, RenderWidgetHostView implementation:
-void RenderWidgetHostViewAura::InitAsChild(
- gfx::NativeView parent_view) {
+void RenderWidgetHostViewAura::InitAsChild(gfx::NativeView parent_view) {
+ if (is_mus_browser_plugin_guest_)
+ return;
+
CreateDelegatedFrameHostClient();
CreateAuraWindow(aura::client::WINDOW_TYPE_CONTROL);
@@ -458,6 +464,8 @@ void RenderWidgetHostViewAura::InitAsChild(
void RenderWidgetHostViewAura::InitAsPopup(
RenderWidgetHostView* parent_host_view,
const gfx::Rect& bounds_in_screen) {
+ // Popups never have |is_mus_browser_plugin_guest_| set to true.
+ DCHECK(!is_mus_browser_plugin_guest_);
CreateDelegatedFrameHostClient();
popup_parent_host_view_ =
@@ -477,7 +485,7 @@ void RenderWidgetHostViewAura::InitAsPopup(
transient_window_client->RemoveTransientChild(
popup_parent_host_view_->window_, old_child->window_);
}
- old_child->popup_parent_host_view_ = NULL;
+ old_child->popup_parent_host_view_ = nullptr;
}
popup_parent_host_view_->SetPopupChild(this);
CreateAuraWindow(aura::client::WINDOW_TYPE_MENU);
@@ -506,12 +514,15 @@ void RenderWidgetHostViewAura::InitAsPopup(
void RenderWidgetHostViewAura::InitAsFullscreen(
RenderWidgetHostView* reference_host_view) {
+ // Webview Fullscreen doesn't go through InitAsFullscreen(), so
+ // |is_mus_browser_plugin_guest_| is always false.
+ DCHECK(!is_mus_browser_plugin_guest_);
is_fullscreen_ = true;
CreateDelegatedFrameHostClient();
CreateAuraWindow(aura::client::WINDOW_TYPE_NORMAL);
window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
- aura::Window* parent = NULL;
+ aura::Window* parent = nullptr;
gfx::Rect bounds;
if (reference_host_view) {
aura::Window* reference_window =
@@ -534,16 +545,23 @@ RenderWidgetHost* RenderWidgetHostViewAura::GetRenderWidgetHost() const {
}
void RenderWidgetHostViewAura::Show() {
+ if (is_mus_browser_plugin_guest_)
+ return;
+
window_->Show();
WasUnOccluded();
}
void RenderWidgetHostViewAura::Hide() {
+ if (is_mus_browser_plugin_guest_)
+ return;
+
window_->Hide();
WasOccluded();
}
void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
+ DCHECK(!is_mus_browser_plugin_guest_);
// For a SetSize operation, we don't care what coordinate system the origin
// of the window is in, it's only important to make sure that the origin
// remains constant after the operation.
@@ -551,6 +569,7 @@ void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
}
void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) {
+ DCHECK(!is_mus_browser_plugin_guest_);
gfx::Point relative_origin(rect.origin());
// RenderWidgetHostViewAura::SetBounds() takes screen coordinates, but
@@ -573,6 +592,7 @@ gfx::Vector2dF RenderWidgetHostViewAura::GetLastScrollOffset() const {
}
gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const {
+ DCHECK(!is_mus_browser_plugin_guest_);
return window_;
}
@@ -595,12 +615,12 @@ gfx::NativeViewAccessible RenderWidgetHostViewAura::GetNativeViewAccessible() {
#elif defined(USE_X11)
BrowserAccessibilityManager* manager =
host_->GetOrCreateRootBrowserAccessibilityManager();
- if (manager)
- return ToBrowserAccessibilityAuraLinux(manager->GetRoot())->GetAtkObject();
+ if (manager && manager->GetRoot())
+ return manager->GetRoot()->GetNativeViewAccessible();
#endif
NOTIMPLEMENTED();
- return static_cast<gfx::NativeViewAccessible>(NULL);
+ return static_cast<gfx::NativeViewAccessible>(nullptr);
}
ui::TextInputClient* RenderWidgetHostViewAura::GetTextInputClient() {
@@ -616,7 +636,7 @@ void RenderWidgetHostViewAura::OnBeginFrame() {
UpdateNeedsBeginFramesInternal();
}
-RenderFrameHostImpl* RenderWidgetHostViewAura::GetFocusedFrame() {
+RenderFrameHostImpl* RenderWidgetHostViewAura::GetFocusedFrame() const {
RenderViewHost* rvh = RenderViewHost::From(host_);
if (!rvh)
return nullptr;
@@ -772,7 +792,7 @@ gfx::Size RenderWidgetHostViewAura::GetVisibleViewportSize() const {
void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) {
if (insets != insets_) {
insets_ = insets;
- host_->WasResized();
+ host_->WasResized(!insets_.IsEmpty());
}
}
@@ -786,8 +806,9 @@ void RenderWidgetHostViewAura::FocusedNodeTouched(
if (editable && host_->GetView() && host_->delegate()) {
keyboard_observer_.reset(new WinScreenKeyboardObserver(
this, location_dips_screen, device_scale_factor_, window_));
- virtual_keyboard_requested_ =
- osk_display_manager->DisplayVirtualKeyboard(keyboard_observer_.get());
+ if (!osk_display_manager->DisplayVirtualKeyboard(keyboard_observer_.get()))
+ keyboard_observer_.reset(nullptr);
+ virtual_keyboard_requested_ = keyboard_observer_.get();
} else {
virtual_keyboard_requested_ = false;
osk_display_manager->DismissVirtualKeyboard();
@@ -847,6 +868,18 @@ void RenderWidgetHostViewAura::SetTooltipText(
}
}
+void RenderWidgetHostViewAura::UpdateScreenInfo(gfx::NativeView view) {
+ RenderWidgetHostViewBase::UpdateScreenInfo(view);
+ if (!host_->auto_resize_enabled())
+ return;
+
+ window_->AllocateLocalSurfaceId();
+ host_->DidAllocateLocalSurfaceIdForAutoResize(
+ host_->last_auto_resize_request_number());
+ if (delegated_frame_host_)
+ delegated_frame_host_->WasResized();
+}
+
gfx::Size RenderWidgetHostViewAura::GetRequestedRendererSize() const {
return delegated_frame_host_
? delegated_frame_host_->GetRequestedRendererSize()
@@ -919,7 +952,9 @@ void RenderWidgetHostViewAura::DidCreateNewRendererCompositorFrameSink(
void RenderWidgetHostViewAura::SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) {
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) {
+ DCHECK(delegated_frame_host_);
TRACE_EVENT0("content", "RenderWidgetHostViewAura::OnSwapCompositorFrame");
// Override the background color to the current compositor background.
@@ -929,10 +964,18 @@ void RenderWidgetHostViewAura::SubmitCompositorFrame(
UpdateBackgroundColorFromRenderer(frame.metadata.root_background_color);
last_scroll_offset_ = frame.metadata.root_scroll_offset;
- if (delegated_frame_host_) {
- delegated_frame_host_->SubmitCompositorFrame(local_surface_id,
- std::move(frame));
+ if (IsUseZoomForDSFEnabled()) {
+ // With zoom-for-DSF Blink pixel coordinates are used and zoom is used to
+ // adjusts for the device scale factor. That's why last_scroll_offset_
+ // needs to be scaled to view coordinates.
+ // Without zoom-for-DSF the values are already in view coordinates.
+ last_scroll_offset_.Scale(1.0f / current_device_scale_factor_);
}
+
+ delegated_frame_host_->SubmitCompositorFrame(
+ local_surface_id, std::move(frame), std::move(hit_test_region_list));
+ if (window_)
+ window_->set_embed_frame_sink_id(frame_sink_id_);
if (frame.metadata.selection.start != selection_start_ ||
frame.metadata.selection.end != selection_end_) {
selection_start_ = frame.metadata.selection.start;
@@ -1134,7 +1177,7 @@ InputEventAckState RenderWidgetHostViewAura::FilterChildGestureEvent(
BrowserAccessibilityManager*
RenderWidgetHostViewAura::CreateBrowserAccessibilityManager(
BrowserAccessibilityDelegate* delegate, bool for_root_frame) {
- BrowserAccessibilityManager* manager = NULL;
+ BrowserAccessibilityManager* manager = nullptr;
#if defined(OS_WIN)
manager = new BrowserAccessibilityManagerWin(
BrowserAccessibilityManagerWin::GetEmptyDocument(), delegate);
@@ -1160,7 +1203,7 @@ RenderWidgetHostViewAura::AccessibilityGetNativeViewAccessible() {
if (legacy_render_widget_host_HWND_)
return legacy_render_widget_host_HWND_->window_accessible();
#endif
- return NULL;
+ return nullptr;
}
void RenderWidgetHostViewAura::SetMainFrameAXTreeID(
@@ -1453,6 +1496,10 @@ bool RenderWidgetHostViewAura::IsTextEditCommandEnabled(
void RenderWidgetHostViewAura::SetTextEditCommandForNextKeyEvent(
ui::TextEditCommand command) {}
+const std::string& RenderWidgetHostViewAura::GetClientSourceInfo() const {
+ return GetFocusedFrame()->GetLastCommittedURL().spec();
+}
+
////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, display::DisplayObserver implementation:
@@ -1534,10 +1581,9 @@ void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
if (!window_->GetRootWindow())
return;
- RenderWidgetHostImpl* host =
- RenderWidgetHostImpl::From(GetRenderWidgetHost());
- if (host && host->delegate())
- host->delegate()->UpdateDeviceScaleFactor(new_device_scale_factor);
+ host_->WasResized();
+ if (delegated_frame_host_)
+ delegated_frame_host_->WasResized();
device_scale_factor_ = new_device_scale_factor;
const display::Display display =
@@ -1612,8 +1658,8 @@ void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
viz::FrameSinkId RenderWidgetHostViewAura::FrameSinkIdAtPoint(
viz::SurfaceHittestDelegate* delegate,
- const gfx::Point& point,
- gfx::Point* transformed_point) {
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point) {
DCHECK(device_scale_factor_ != 0.0f);
// TODO: this shouldn't be used with aura-mus, so that the null check so
@@ -1625,7 +1671,7 @@ viz::FrameSinkId RenderWidgetHostViewAura::FrameSinkIdAtPoint(
// The surface hittest happens in device pixels, so we need to convert the
// |point| from DIPs to pixels before hittesting.
- gfx::Point point_in_pixels =
+ gfx::PointF point_in_pixels =
gfx::ConvertPointToPixel(device_scale_factor_, point);
viz::SurfaceId id = delegated_frame_host_->SurfaceIdAtPoint(
delegate, point_in_pixels, transformed_point);
@@ -1633,7 +1679,7 @@ viz::FrameSinkId RenderWidgetHostViewAura::FrameSinkIdAtPoint(
gfx::ConvertPointToDIP(device_scale_factor_, *transformed_point);
// It is possible that the renderer has not yet produced a surface, in which
- // case we return our current namespace.
+ // case we return our current FrameSinkId.
if (!id.is_valid())
return GetFrameSinkId();
return id.frame_sink_id();
@@ -1664,12 +1710,12 @@ void RenderWidgetHostViewAura::ProcessGestureEvent(
}
bool RenderWidgetHostViewAura::TransformPointToLocalCoordSpace(
- const gfx::Point& point,
+ const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
// Transformations use physical pixels rather than DIP, so conversion
// is necessary.
- gfx::Point point_in_pixels =
+ gfx::PointF point_in_pixels =
gfx::ConvertPointToPixel(device_scale_factor_, point);
// TODO: this shouldn't be used with aura-mus, so that the null check so
// go away and become a DCHECK.
@@ -1683,9 +1729,9 @@ bool RenderWidgetHostViewAura::TransformPointToLocalCoordSpace(
}
bool RenderWidgetHostViewAura::TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
if (target_view == this || !delegated_frame_host_) {
*transformed_point = point;
return true;
@@ -1701,6 +1747,10 @@ bool RenderWidgetHostViewAura::TransformPointToCoordSpaceForView(
void RenderWidgetHostViewAura::FocusedNodeChanged(
bool editable,
const gfx::Rect& node_bounds_in_screen) {
+ if (GetInputMethod())
+ GetInputMethod()->CancelComposition(this);
+ has_composition_text_ = false;
+
#if defined(OS_WIN)
if (!editable && virtual_keyboard_requested_) {
virtual_keyboard_requested_ = false;
@@ -1714,9 +1764,9 @@ void RenderWidgetHostViewAura::FocusedNodeChanged(
void RenderWidgetHostViewAura::ScheduleEmbed(
ui::mojom::WindowTreeClientPtr client,
base::OnceCallback<void(const base::UnguessableToken&)> callback) {
- DCHECK(IsMus());
- aura::WindowPortMus::Get(window_)->ScheduleEmbed(std::move(client),
- std::move(callback));
+ DCHECK(IsUsingMus());
+ aura::Env::GetInstance()->ScheduleEmbed(std::move(client),
+ std::move(callback));
}
void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
@@ -1861,7 +1911,7 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
if (window_->GetHost())
window_->GetHost()->RemoveObserver(this);
UnlockMouse();
- wm::SetTooltipText(window_, NULL);
+ wm::SetTooltipText(window_, nullptr);
display::Screen::GetScreen()->RemoveObserver(this);
// This call is usually no-op since |this| object is already removed from
@@ -1870,14 +1920,14 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
DetachFromInputMethod();
}
if (popup_parent_host_view_) {
- DCHECK(popup_parent_host_view_->popup_child_host_view_ == NULL ||
+ DCHECK(popup_parent_host_view_->popup_child_host_view_ == nullptr ||
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_ == NULL ||
+ DCHECK(popup_child_host_view_->popup_parent_host_view_ == nullptr ||
popup_child_host_view_->popup_parent_host_view_ == this);
- popup_child_host_view_->popup_parent_host_view_ = NULL;
+ popup_child_host_view_->popup_parent_host_view_ = nullptr;
}
event_filter_for_popup_exit_.reset();
@@ -1894,6 +1944,7 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
DCHECK(!window_);
+ DCHECK(!is_mus_browser_plugin_guest_);
window_ = new aura::Window(this);
window_->SetName("RenderWidgetHostViewAura");
window_->SetProperty(aura::client::kEmbedType,
@@ -1910,28 +1961,35 @@ void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
window_->Init(ui::LAYER_SOLID_COLOR);
window_->layer()->SetColor(background_color_);
- if (!IsMus())
+ if (!IsUsingMus())
return;
// Embed the renderer into the Window.
+ // Use kEmbedFlagEmbedderControlsVisibility so that the renderer can't change
+ // the visibility of |window_|.
aura::WindowPortMus::Get(window_)->Embed(
GetWindowTreeClientFromRenderer(),
- ui::mojom::kEmbedFlagEmbedderInterceptsEvents,
+ ui::mojom::kEmbedFlagEmbedderInterceptsEvents |
+ ui::mojom::kEmbedFlagEmbedderControlsVisibility,
base::Bind(&EmbedCallback));
}
void RenderWidgetHostViewAura::CreateDelegatedFrameHostClient() {
- if (IsMus())
+ if (!frame_sink_id_.is_valid())
return;
// Tests may set |delegated_frame_host_client_|.
if (!delegated_frame_host_client_) {
delegated_frame_host_client_ =
- base::MakeUnique<DelegatedFrameHostClientAura>(this);
+ std::make_unique<DelegatedFrameHostClientAura>(this);
}
- delegated_frame_host_ = base::MakeUnique<DelegatedFrameHost>(
+
+ const bool enable_viz =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableViz);
+ delegated_frame_host_ = std::make_unique<DelegatedFrameHost>(
frame_sink_id_, delegated_frame_host_client_.get(),
- enable_surface_synchronization_);
+ enable_surface_synchronization_, enable_viz);
+
if (renderer_compositor_frame_sink_) {
delegated_frame_host_->DidCreateNewRendererCompositorFrameSink(
renderer_compositor_frame_sink_);
@@ -1947,6 +2005,9 @@ void RenderWidgetHostViewAura::CreateDelegatedFrameHostClient() {
}
void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
+ if (is_mus_browser_plugin_guest_)
+ return;
+
if (host_->GetProcess()->FastShutdownStarted())
return;
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 a23a9a396ba..9a52485b28c 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
@@ -94,9 +94,11 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
//
// TODO(lazyboy): Remove |is_guest_view_hack| once BrowserPlugin has migrated
// to use RWHVChildFrame (http://crbug.com/330264).
+ // |is_mus_browser_plugin_guest| can be removed at the same time.
RenderWidgetHostViewAura(RenderWidgetHost* host,
bool is_guest_view_hack,
- bool enable_surface_synchronization);
+ bool enable_surface_synchronization,
+ bool is_mus_browser_plugin_guest);
// RenderWidgetHostView implementation.
void InitAsChild(gfx::NativeView parent_view) override;
@@ -138,6 +140,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
int error_code) override;
void Destroy() override;
void SetTooltipText(const base::string16& tooltip_text) override;
+ void UpdateScreenInfo(gfx::NativeView view) override;
gfx::Size GetRequestedRendererSize() const override;
bool IsSurfaceAvailableForCopy() const override;
void CopyFromSurface(const gfx::Rect& src_rect,
@@ -175,8 +178,10 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
void DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink)
override;
- void SubmitCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) override;
+ void SubmitCompositorFrame(
+ const viz::LocalSurfaceId& local_surface_id,
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) override;
void OnDidNotProduceFrame(const viz::BeginFrameAck& ack) override;
void ClearCompositorFrame() override;
void DidStopFlinging() override;
@@ -184,8 +189,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
viz::FrameSinkId GetFrameSinkId() override;
viz::LocalSurfaceId GetLocalSurfaceId() const override;
viz::FrameSinkId FrameSinkIdAtPoint(viz::SurfaceHittestDelegate* delegate,
- const gfx::Point& point,
- gfx::Point* transformed_point) override;
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point) override;
void ProcessMouseEvent(const blink::WebMouseEvent& event,
const ui::LatencyInfo& latency) override;
void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event,
@@ -194,13 +199,13 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
const ui::LatencyInfo& latency) override;
void ProcessGestureEvent(const blink::WebGestureEvent& event,
const ui::LatencyInfo& latency) override;
- bool TransformPointToLocalCoordSpace(const gfx::Point& point,
+ bool TransformPointToLocalCoordSpace(const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point) override;
+ gfx::PointF* transformed_point) override;
bool TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point) override;
+ gfx::PointF* transformed_point) override;
void FocusedNodeChanged(bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) override;
@@ -237,6 +242,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
void EnsureCaretNotInRect(const gfx::Rect& rect) override;
bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override;
void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override;
+ const std::string& GetClientSourceInfo() const override;
// Overridden from display::DisplayObserver:
void OnDisplayAdded(const display::Display& new_display) override;
@@ -332,7 +338,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
void ForwardKeyboardEventWithLatencyInfo(const NativeWebKeyboardEvent& event,
const ui::LatencyInfo& latency,
bool* update_event) override;
- RenderFrameHostImpl* GetFocusedFrame();
+ RenderFrameHostImpl* GetFocusedFrame() const;
bool NeedsMouseCapture() override;
void SetTooltipsEnabled(bool enable) override;
void ShowContextMenu(const ContextMenuParams& params) override;
@@ -365,6 +371,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
PopupRetainsCaptureAfterMouseRelease);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, SetCompositionText);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, FocusedNodeChanged);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, TouchEventState);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
TouchEventPositionsArentRounded);
@@ -395,10 +402,14 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
ForwardsBeginFrameAcks);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
VirtualKeyboardFocusEnsureCaretInRect);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
+ HitTestRegionListSubmitted);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
CompositorFrameSinkChange);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
SurfaceChanges);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
+ DeviceScaleFactorChanges);
FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, PopupMenuTest);
FRIEND_TEST_ALL_PREFIXES(WebContentsViewAuraTest,
WebContentsViewReparent);
@@ -489,9 +500,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
// and to notify the |event_handler_|.
void SetPopupChild(RenderWidgetHostViewAura* popup_child_host_view);
- // Forwards a mouse event to this view's parent window delegate.
- void ForwardMouseEventToParent(ui::MouseEvent* event);
-
// Tells DelegatedFrameHost whether we need to receive BeginFrames.
void UpdateNeedsBeginFramesInternal();
@@ -504,6 +512,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
const bool enable_surface_synchronization_;
+ const bool is_mus_browser_plugin_guest_;
+
+ // NOTE: this is null if |is_mus_browser_plugin_guest_| is true.
aura::Window* window_;
std::unique_ptr<DelegatedFrameHostClient> delegated_frame_host_client_;
@@ -603,8 +614,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
gfx::Insets insets_;
- std::vector<ui::LatencyInfo> software_latency_info_;
-
std::unique_ptr<wm::ScopedTooltipDisabler> tooltip_disabler_;
// True when this view acts as a platform view hack for a
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 e13c1f5f82c..6b141cd82e5 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
@@ -30,11 +30,14 @@
#include "components/viz/common/quads/compositor_frame_metadata.h"
#include "components/viz/common/surfaces/local_surface_id_allocator.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
+#include "components/viz/service/hit_test/hit_test_manager.h"
#include "components/viz/service/surfaces/surface.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_external_begin_frame_source.h"
#include "components/viz/test/fake_surface_observer.h"
+#include "content/browser/browser_main_loop.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/compositor/test/no_transport_image_transport_factory.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h"
@@ -86,6 +89,7 @@
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_observer.h"
#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/ime/input_method.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/ui_base_types.h"
#include "ui/compositor/compositor.h"
@@ -132,10 +136,41 @@ void InstallDelegatedFrameHostClient(
namespace {
+constexpr uint64_t kFrameIndexStart =
+ viz::CompositorFrameSinkSupport::kFrameIndexStart;
+
const viz::LocalSurfaceId kArbitraryLocalSurfaceId(
1,
base::UnguessableToken::Deserialize(2, 3));
+std::string GetMessageNames(
+ const MockWidgetInputHandler::MessageVector& events) {
+ std::vector<std::string> result;
+ for (auto& event : events)
+ result.push_back(event->name());
+ return base::JoinString(result, " ");
+}
+
+uint64_t FrameIndexForView(RenderWidgetHostViewAura* view) {
+ return ImageTransportFactory::GetInstance()
+ ->GetContextFactoryPrivate()
+ ->GetFrameSinkManager()
+ ->surface_manager()
+ ->GetSurfaceForId(view->SurfaceIdForTesting())
+ ->GetActiveFrameIndex();
+}
+
+const gfx::Rect& DamageRectForView(RenderWidgetHostViewAura* view) {
+ return ImageTransportFactory::GetInstance()
+ ->GetContextFactoryPrivate()
+ ->GetFrameSinkManager()
+ ->surface_manager()
+ ->GetSurfaceForId(view->SurfaceIdForTesting())
+ ->GetActiveFrame()
+ .render_pass_list.back()
+ ->damage_rect;
+}
+
class TestOverscrollDelegate : public OverscrollControllerDelegate {
public:
explicit TestOverscrollDelegate(RenderWidgetHostView* view)
@@ -232,9 +267,44 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
}
double get_last_device_scale_factor() { return last_device_scale_factor_; }
- void UpdateDeviceScaleFactor(double device_scale_factor) override {
- last_device_scale_factor_ = device_scale_factor;
+ void ResizeDueToAutoResize(RenderWidgetHostImpl* render_widget_host,
+ const gfx::Size& new_size,
+ uint64_t sequence_number) override {
+ RenderWidgetHostViewBase* rwhv = rwh_->GetView();
+ if (rwhv)
+ rwhv->ResizeDueToAutoResize(new_size, sequence_number);
+ }
+ void ScreenInfoChanged() override {
+ display::Screen* screen = display::Screen::GetScreen();
+ const display::Display display = screen->GetPrimaryDisplay();
+ last_device_scale_factor_ = display.device_scale_factor();
+ }
+
+ void GetScreenInfo(ScreenInfo* result) override {
+ display::Screen* screen = display::Screen::GetScreen();
+ const display::Display display = screen->GetPrimaryDisplay();
+ result->rect = display.bounds();
+ result->available_rect = display.work_area();
+ result->depth = display.color_depth();
+ result->depth_per_component = display.depth_per_component();
+ result->is_monochrome = display.is_monochrome();
+ result->device_scale_factor = display.device_scale_factor();
+ result->color_space = display.color_space();
+
+ // The Display rotation and the ScreenInfo orientation are not the same
+ // angle. The former is the physical display rotation while the later is the
+ // rotation required by the content to be shown properly on the screen, in
+ // other words, relative to the physical display.
+ result->orientation_angle = display.RotationAsDegree();
+ if (result->orientation_angle == 90)
+ result->orientation_angle = 270;
+ else if (result->orientation_angle == 270)
+ result->orientation_angle = 90;
+
+ result->orientation_type =
+ RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display);
}
+
void set_pre_handle_keyboard_event_result(
KeyboardEventProcessingResult result) {
pre_handle_keyboard_event_result_ = result;
@@ -403,7 +473,7 @@ class FakeDelegatedFrameHostClientAura : public DelegatedFrameHostClientAura,
std::unique_ptr<ui::CompositorLock> GetCompositorLock(
ui::CompositorLockClient* client) override {
resize_locked_ = compositor_locked_ = true;
- return base::MakeUnique<ui::CompositorLock>(nullptr,
+ return std::make_unique<ui::CompositorLock>(nullptr,
weak_ptr_factory_.GetWeakPtr());
}
// CompositorResizeLockClient implemention. Overrides from
@@ -433,7 +503,8 @@ class FakeRenderWidgetHostViewAura : public RenderWidgetHostViewAura {
bool enable_surface_synchronization)
: RenderWidgetHostViewAura(widget,
is_guest_view_hack,
- enable_surface_synchronization),
+ enable_surface_synchronization,
+ false /* is_mus_browser_plugin_guest */),
delegated_frame_host_client_(
new FakeDelegatedFrameHostClientAura(this)) {
InstallDelegatedFrameHostClient(
@@ -450,7 +521,7 @@ class FakeRenderWidgetHostViewAura : public RenderWidgetHostViewAura {
viz::mojom::CompositorFrameSinkClientRequest client_request =
mojo::MakeRequest(&renderer_compositor_frame_sink_ptr_);
renderer_compositor_frame_sink_ =
- base::MakeUnique<FakeRendererCompositorFrameSink>(
+ std::make_unique<FakeRendererCompositorFrameSink>(
std::move(sink), std::move(client_request));
DidCreateNewRendererCompositorFrameSink(
renderer_compositor_frame_sink_ptr_.get());
@@ -473,13 +544,12 @@ class FakeRenderWidgetHostViewAura : public RenderWidgetHostViewAura {
void InterceptCopyOfOutput(std::unique_ptr<viz::CopyOutputRequest> request) {
last_copy_request_ = std::move(request);
- if (last_copy_request_->has_texture_mailbox()) {
+ if (last_copy_request_->has_mailbox()) {
// Give the resulting texture a size.
viz::GLHelper* gl_helper =
ImageTransportFactory::GetInstance()->GetGLHelper();
GLuint texture = gl_helper->ConsumeMailboxToTexture(
- last_copy_request_->texture_mailbox().mailbox(),
- last_copy_request_->texture_mailbox().sync_token());
+ last_copy_request_->mailbox(), last_copy_request_->sync_token());
gl_helper->ResizeTexture(texture, window()->bounds().size());
gl_helper->DeleteTexture(texture);
}
@@ -557,11 +627,6 @@ class FullscreenLayoutManager : public aura::LayoutManager {
DISALLOW_COPY_AND_ASSIGN(FullscreenLayoutManager);
};
-class MockWindowObserver : public aura::WindowObserver {
- public:
- MOCK_METHOD2(OnDelegatedFrameDamage, void(aura::Window*, const gfx::Rect&));
-};
-
class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
public:
~MockRenderWidgetHostImpl() override {}
@@ -591,7 +656,7 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
int32_t routing_id) {
mojom::WidgetPtr widget;
std::unique_ptr<MockWidgetImpl> widget_impl =
- base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
return new MockRenderWidgetHostImpl(delegate, process, routing_id,
std::move(widget_impl),
@@ -599,6 +664,10 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
}
ui::LatencyInfo lastWheelOrTouchEventLatencyInfo;
+ MockWidgetInputHandler* input_handler() {
+ return widget_impl_->input_handler();
+ }
+
private:
MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
RenderProcessHost* process,
@@ -617,15 +686,6 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
std::unique_ptr<MockWidgetImpl> widget_impl_;
};
-const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
- base::PickleIterator iter(message);
- const char* data;
- int data_length;
- if (!iter.ReadData(&data, &data_length))
- return nullptr;
- return reinterpret_cast<const WebInputEvent*>(data);
-}
-
enum WheelScrollingMode {
kWheelScrollingModeNone,
kWheelScrollLatching,
@@ -648,6 +708,7 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
}
void SetUpEnvironment(bool enable_surface_synchronization) {
+ mojo_feature_list_.InitAndEnableFeature(features::kMojoInputMessages);
ImageTransportFactory::SetFactory(
std::make_unique<NoTransportImageTransportFactory>());
aura_test_helper_.reset(new aura::test::AuraTestHelper());
@@ -667,8 +728,10 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
parent_host_ = MockRenderWidgetHostImpl::Create(delegates_.back().get(),
process_host_, routing_id);
delegates_.back()->set_widget_host(parent_host_);
+ const bool is_mus_browser_plugin_guest = false;
parent_view_ = new RenderWidgetHostViewAura(
- parent_host_, is_guest_view_hack_, enable_surface_synchronization);
+ parent_host_, is_guest_view_hack_, enable_surface_synchronization,
+ is_mus_browser_plugin_guest);
parent_view_->InitAsChild(nullptr);
aura::client::ParentWindowWithContext(parent_view_->GetNativeView(),
aura_test_helper_->root_window(),
@@ -682,6 +745,7 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
widget_host_->Init();
view_ = new FakeRenderWidgetHostViewAura(widget_host_, is_guest_view_hack_,
enable_surface_synchronization);
+ base::RunLoop().RunUntilIdle();
}
void TearDownEnvironment() {
@@ -736,69 +800,19 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
FrameEvictionManager::GetInstance()->OnMemoryPressure(level);
}
- void SendInputEventACK(WebInputEvent::Type type,
- InputEventAckState ack_result) {
- DCHECK(!WebInputEvent::IsTouchEventType(type));
- InputEventAck ack(InputEventAckSource::COMPOSITOR_THREAD, type, ack_result);
- InputHostMsg_HandleInputEvent_ACK response(0, ack);
- widget_host_->OnMessageReceived(response);
- }
-
- void SendTouchEventACK(WebInputEvent::Type type,
- InputEventAckState ack_result,
- uint32_t event_id) {
- DCHECK(WebInputEvent::IsTouchEventType(type));
- InputEventAck ack(InputEventAckSource::COMPOSITOR_THREAD, type, ack_result,
- event_id);
- InputHostMsg_HandleInputEvent_ACK response(0, ack);
- widget_host_->OnMessageReceived(response);
+ MockWidgetInputHandler::MessageVector GetAndResetDispatchedMessages() {
+ return widget_host_->input_handler()->GetAndResetDispatchedMessages();
}
- std::string GetInputMessageTypes() {
- return content::GetInputMessageTypes(process_host_);
- }
-
- size_t GetSentMessageCountAndResetSink() {
- size_t count = sink_->message_count();
- sink_->ClearMessages();
- return count;
- }
-
- void AckLastSentInputEventIfNecessary(InputEventAckState ack_result) {
- if (!sink_->message_count())
- return;
-
- InputMsg_HandleInputEvent::Param params;
- if (!InputMsg_HandleInputEvent::Read(
- sink_->GetMessageAt(sink_->message_count() - 1), &params)) {
- return;
- }
-
- InputEventDispatchType dispatch_type = std::get<3>(params);
- if (dispatch_type == InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING)
- return;
-
- const blink::WebInputEvent* event = std::get<0>(params);
- SendTouchEventACK(event->GetType(), ack_result,
- WebInputEventTraits::GetUniqueTouchEventId(*event));
+ void SendNotConsumedAcks(MockWidgetInputHandler::MessageVector& events) {
+ events.clear();
}
const ui::MotionEventAura& pointer_state() { return view_->pointer_state(); }
- void EnableRafAlignedTouchInput() {
- feature_list_.InitFromCommandLine(
- features::kRafAlignedTouchInputEvents.name, "");
- }
-
- void DisableRafAlignedTouchInput() {
- feature_list_.InitFromCommandLine(
- "", features::kRafAlignedTouchInputEvents.name);
- }
-
void EnableWheelScrollLatching() {
feature_list_.InitFromCommandLine(
- features::kTouchpadAndWheelScrollLatching.name,
- features::kMojoInputMessages.name);
+ features::kTouchpadAndWheelScrollLatching.name, "");
}
void DisableWheelScrollLatching() {
@@ -807,39 +821,18 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
}
void SetFeatureList(
- bool raf_aligned_touch,
WheelScrollingMode wheel_scrolling_mode = kWheelScrollLatching) {
- if (raf_aligned_touch && wheel_scrolling_mode == kAsyncWheelEvents) {
- feature_list_.InitWithFeatures({features::kRafAlignedTouchInputEvents,
- features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents},
- {});
- } else if (raf_aligned_touch &&
- wheel_scrolling_mode == kWheelScrollLatching) {
- feature_list_.InitWithFeatures(
- {features::kRafAlignedTouchInputEvents,
- features::kTouchpadAndWheelScrollLatching},
- {features::kAsyncWheelEvents});
- } else if (raf_aligned_touch &&
- wheel_scrolling_mode == kWheelScrollingModeNone) {
- feature_list_.InitWithFeatures({features::kRafAlignedTouchInputEvents},
- {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents});
- } else if (!raf_aligned_touch &&
- wheel_scrolling_mode == kAsyncWheelEvents) {
+ if (wheel_scrolling_mode == kAsyncWheelEvents) {
feature_list_.InitWithFeatures({features::kTouchpadAndWheelScrollLatching,
features::kAsyncWheelEvents},
- {features::kRafAlignedTouchInputEvents});
- } else if (!raf_aligned_touch &&
- wheel_scrolling_mode == kWheelScrollLatching) {
+ {});
+ } else if (wheel_scrolling_mode == kWheelScrollLatching) {
feature_list_.InitWithFeatures(
{features::kTouchpadAndWheelScrollLatching},
- {features::kRafAlignedTouchInputEvents, features::kAsyncWheelEvents});
- } else { // !raf_aligned_touch && wheel_scroll_latching ==
- // kWheelScrollingModeNone.
+ {features::kAsyncWheelEvents});
+ } else if (wheel_scrolling_mode == kWheelScrollingModeNone) {
feature_list_.InitWithFeatures({},
- {features::kRafAlignedTouchInputEvents,
- features::kTouchpadAndWheelScrollLatching,
+ {features::kTouchpadAndWheelScrollLatching,
features::kAsyncWheelEvents});
}
@@ -906,6 +899,7 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
FakeRenderWidgetHostViewAura* view_;
IPC::TestSink* sink_;
+ base::test::ScopedFeatureList mojo_feature_list_;
base::test::ScopedFeatureList vsync_feature_list_;
base::test::ScopedFeatureList feature_list_;
@@ -915,15 +909,6 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraTest);
};
-class RenderWidgetHostViewAuraRafAlignedTouchEnabledTest
- : public RenderWidgetHostViewAuraTest {
- public:
- void SetUp() override {
- EnableRafAlignedTouchInput();
- RenderWidgetHostViewAuraTest::SetUp();
- }
-};
-
class RenderWidgetHostViewAuraSurfaceSynchronizationTest
: public RenderWidgetHostViewAuraTest {
void SetUp() override {
@@ -931,15 +916,6 @@ class RenderWidgetHostViewAuraSurfaceSynchronizationTest
}
};
-class RenderWidgetHostViewAuraRafAlignedTouchDisabledTest
- : public RenderWidgetHostViewAuraTest {
- public:
- void SetUp() override {
- DisableRafAlignedTouchInput();
- RenderWidgetHostViewAuraTest::SetUp();
- }
-};
-
class RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest
: public RenderWidgetHostViewAuraTest {
public:
@@ -1005,13 +981,45 @@ class RenderWidgetHostViewAuraOverscrollTest
// We explicitly invoke SetUp to allow gesture debounce customization.
void SetUp() override {}
- void SendScrollBeginAckIfNeeded(InputEventAckState ack_result) {
+ void SendScrollUpdateAck(MockWidgetInputHandler::MessageVector& messages,
+ InputEventAckState ack_result) {
+ for (size_t i = 0; i < messages.size(); ++i) {
+ MockWidgetInputHandler::DispatchedEventMessage* event =
+ messages[i]->ToEvent();
+ if (event &&
+ event->Event()->web_event->GetType() ==
+ WebInputEvent::kGestureScrollUpdate &&
+ event->HasCallback()) {
+ event->CallCallback(ack_result);
+ return;
+ }
+ }
+ EXPECT_TRUE(false);
+ }
+
+ void SendScrollBeginAckIfNeeded(
+ MockWidgetInputHandler::MessageVector& messages,
+ InputEventAckState ack_result) {
if (wheel_scroll_latching_enabled_) {
- // GSB events are blocking, send the ack.
- SendInputEventACK(WebInputEvent::kGestureScrollBegin, ack_result);
+ for (size_t i = 0; i < messages.size(); ++i) {
+ MockWidgetInputHandler::DispatchedEventMessage* event =
+ messages[i]->ToEvent();
+ // GSB events are blocking, send the ack.
+ if (event && event->Event()->web_event->GetType() ==
+ WebInputEvent::kGestureScrollBegin) {
+ event->CallCallback(ack_result);
+ return;
+ }
+ }
}
}
+ void SendScrollBeginAckIfNeeded(InputEventAckState ack_result) {
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ SendScrollBeginAckIfNeeded(events, ack_result);
+ }
+
protected:
void SetUpOverscrollEnvironmentWithDebounce(int debounce_interval_in_ms) {
SetUpOverscrollEnvironmentImpl(debounce_interval_in_ms);
@@ -1020,7 +1028,7 @@ class RenderWidgetHostViewAuraOverscrollTest
void SetUpOverscrollEnvironment() { SetUpOverscrollEnvironmentImpl(0); }
void SetUpOverscrollEnvironmentImpl(int debounce_interval_in_ms) {
- SetFeatureList(true, wheel_scrolling_mode_);
+ SetFeatureList(wheel_scrolling_mode_);
ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
debounce_interval_in_ms);
@@ -1040,17 +1048,20 @@ class RenderWidgetHostViewAuraOverscrollTest
// TODO(jdduke): Simulate ui::Events, injecting through the view.
void SimulateMouseEvent(WebInputEvent::Type type) {
widget_host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type));
+ base::RunLoop().RunUntilIdle();
}
void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type,
const ui::LatencyInfo& ui_latency) {
widget_host_->ForwardMouseEventWithLatencyInfo(
SyntheticWebMouseEventBuilder::Build(type), ui_latency);
+ base::RunLoop().RunUntilIdle();
}
void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
widget_host_->ForwardWheelEvent(SyntheticWebMouseWheelEventBuilder::Build(
0, 0, dX, dY, modifiers, precise));
+ base::RunLoop().RunUntilIdle();
}
void SimulateWheelEventWithPhase(float dX,
@@ -1062,6 +1073,7 @@ class RenderWidgetHostViewAuraOverscrollTest
0, 0, dX, dY, modifiers, precise);
wheel_event.phase = phase;
widget_host_->ForwardWheelEvent(wheel_event);
+ base::RunLoop().RunUntilIdle();
}
void SimulateWheelEventPossiblyIncludingPhase(
@@ -1085,6 +1097,7 @@ class RenderWidgetHostViewAuraOverscrollTest
SyntheticWebMouseWheelEventBuilder::Build(0, 0, dX, dY, modifiers,
precise),
ui_latency);
+ base::RunLoop().RunUntilIdle();
}
void SimulateMouseMove(int x, int y, int modifiers) {
@@ -1101,22 +1114,26 @@ class RenderWidgetHostViewAuraOverscrollTest
if (pressed)
event.button = WebMouseEvent::Button::kLeft;
widget_host_->ForwardMouseEvent(event);
+ base::RunLoop().RunUntilIdle();
}
void SimulateWheelEventWithPhase(WebMouseWheelEvent::Phase phase) {
widget_host_->ForwardWheelEvent(
SyntheticWebMouseWheelEventBuilder::Build(phase));
+ base::RunLoop().RunUntilIdle();
}
// Inject provided synthetic WebGestureEvent instance.
void SimulateGestureEventCore(const WebGestureEvent& gesture_event) {
widget_host_->ForwardGestureEvent(gesture_event);
+ base::RunLoop().RunUntilIdle();
}
void SimulateGestureEventCoreWithLatencyInfo(
const WebGestureEvent& gesture_event,
const ui::LatencyInfo& ui_latency) {
widget_host_->ForwardGestureEventWithLatencyInfo(gesture_event, ui_latency);
+ base::RunLoop().RunUntilIdle();
}
// Inject simple synthetic WebGestureEvent instances.
@@ -1196,6 +1213,7 @@ class RenderWidgetHostViewAuraOverscrollTest
widget_host_->ForwardTouchEventWithLatencyInfo(touch_event_,
ui::LatencyInfo());
touch_event_.ResetPoints();
+ base::RunLoop().RunUntilIdle();
return touch_event_id;
}
@@ -1211,26 +1229,34 @@ class RenderWidgetHostViewAuraOverscrollTest
touch_event_.ReleasePoint(index);
}
- void ExpectGestureScrollEndForWheelScrolling(bool is_last) {
+ MockWidgetInputHandler::MessageVector ExpectGestureScrollEndForWheelScrolling(
+ bool is_last) {
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
if (!wheel_scroll_latching_enabled_) {
// Already handled in |ExpectGestureScrollEventsAfterMouseWheelACK()|.
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
- return;
+ EXPECT_EQ(0U, events.size());
+ return events;
}
if (is_last) {
// Scroll latching will have one GestureScrollEnd at the end.
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
+ return events;
}
// No GestureScrollEnd during the scroll.
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ EXPECT_EQ(0U, events.size());
+ return events;
}
- void ExpectGestureScrollEventsAfterMouseWheelACK(
+ MockWidgetInputHandler::MessageVector
+ ExpectGestureScrollEventsAfterMouseWheelACK(
bool is_first_ack,
size_t enqueued_wheel_event_count) {
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
std::string expected_events;
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- ASSERT_TRUE(wheel_scroll_latching_enabled_);
+ EXPECT_TRUE(wheel_scroll_latching_enabled_);
// If the ack for the first sent event is not consumed,
// MouseWheelEventQueue(MWEQ) sends the rest of the wheel events in the
// current scrolling sequence as non-blocking events. Since MWEQ
@@ -1245,7 +1271,7 @@ class RenderWidgetHostViewAuraOverscrollTest
for (size_t i = 0; i < enqueued_wheel_event_count; ++i)
expected_events += "MouseWheel GestureScrollUpdate ";
} else if (wheel_scrolling_mode_ == kWheelScrollLatching) {
- ASSERT_TRUE(wheel_scroll_latching_enabled_);
+ EXPECT_TRUE(wheel_scroll_latching_enabled_);
// Since the MWEQ must wait for ack of the sent event before sending the
// next queued event, when wheel events are blocking only one queued
// event will be sent regardless of the number of the queued wheel
@@ -1270,45 +1296,51 @@ class RenderWidgetHostViewAuraOverscrollTest
}
EXPECT_EQ(base::TrimWhitespaceASCII(expected_events, base::TRIM_TRAILING),
- GetInputMessageTypes());
+ GetMessageNames(events));
+ return events;
}
- void ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(
+ MockWidgetInputHandler::MessageVector
+ ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(
bool wheel_was_queued) {
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
size_t gesture_scroll_update_index;
- InputMsg_HandleInputEvent::Param params;
if (wheel_was_queued) {
// The queued wheel event is already sent.
gesture_scroll_update_index = 0;
} else {
// The first sent must be the wheel event and the second one must be
// GestureScrollUpdate since the ack for the wheel event is non-blocking.
- if (InputMsg_HandleInputEvent::Read(sink_->GetMessageAt(0), &params)) {
- EXPECT_EQ(WebInputEvent::kMouseWheel, (std::get<0>(params))->GetType());
- }
+ EXPECT_TRUE(events[0]->ToEvent());
+ EXPECT_EQ(WebInputEvent::kMouseWheel,
+ events[0]->ToEvent()->Event()->web_event->GetType());
gesture_scroll_update_index = 1;
}
- if (InputMsg_HandleInputEvent::Read(
- sink_->GetMessageAt(gesture_scroll_update_index), &params)) {
- EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
- (std::get<0>(params))->GetType());
- }
- EXPECT_EQ(gesture_scroll_update_index + 1,
- GetSentMessageCountAndResetSink());
+ EXPECT_EQ(gesture_scroll_update_index + 1, events.size());
+ EXPECT_TRUE(events[gesture_scroll_update_index]->ToEvent());
+ EXPECT_EQ(WebInputEvent::kGestureScrollUpdate,
+ events[gesture_scroll_update_index]
+ ->ToEvent()
+ ->Event()
+ ->web_event->GetType());
+ return events;
}
void ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling() {
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
// Wheel event ack either:
// - does not generate a gesture scroll update (async wheel event); or
// - generates a gesture scroll update that is consumed by the overscroll
// controller to prevent content scroll (non-async wheel event).
if (wheel_scroll_latching_enabled_) {
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ EXPECT_EQ(0U, events.size());
} else {
// Wheel event ack generates a gesture scroll begin, a gesture scroll
// update, and a gesture scroll end; of which the gesture scroll update is
// consumed by the overscroll controller to prevent content scroll.
- EXPECT_EQ("GestureScrollBegin GestureScrollEnd", GetInputMessageTypes());
+ EXPECT_EQ("GestureScrollBegin GestureScrollEnd", GetMessageNames(events));
}
}
@@ -1637,41 +1669,39 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCompositionText) {
// Caret is at the end. (This emulates Japanese MSIME 2007 and later)
composition_text.selection = gfx::Range(4);
- sink_->ClearMessages();
view_->SetCompositionText(composition_text);
EXPECT_TRUE(view_->has_composition_text_);
- {
- const IPC::Message* msg =
- sink_->GetFirstMessageMatching(InputMsg_ImeSetComposition::ID);
- ASSERT_TRUE(msg != nullptr);
-
- InputMsg_ImeSetComposition::Param params;
- InputMsg_ImeSetComposition::Read(msg, &params);
- // composition text
- EXPECT_EQ(composition_text.text, std::get<0>(params));
- // ime spans
- ASSERT_EQ(ime_text_spans.size(), std::get<1>(params).size());
- for (size_t i = 0; i < ime_text_spans.size(); ++i) {
- EXPECT_EQ(ime_text_spans[i].start_offset,
- std::get<1>(params)[i].start_offset);
- EXPECT_EQ(ime_text_spans[i].end_offset,
- std::get<1>(params)[i].end_offset);
- EXPECT_EQ(ime_text_spans[i].underline_color,
- std::get<1>(params)[i].underline_color);
- EXPECT_EQ(ime_text_spans[i].thick, std::get<1>(params)[i].thick);
- EXPECT_EQ(ime_text_spans[i].background_color,
- std::get<1>(params)[i].background_color);
- }
- EXPECT_EQ(gfx::Range::InvalidRange(), std::get<2>(params));
- // highlighted range
- EXPECT_EQ(4, std::get<3>(params)) << "Should be the same to the caret pos";
- EXPECT_EQ(4, std::get<4>(params)) << "Should be the same to the caret pos";
- }
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("SetComposition", GetMessageNames(events));
+
+ MockWidgetInputHandler::DispatchedIMEMessage* ime_message =
+ events[0]->ToIME();
+ EXPECT_TRUE(ime_message);
+ EXPECT_TRUE(ime_message->Matches(composition_text.text, ime_text_spans,
+ gfx::Range::InvalidRange(), 4, 4));
view_->ImeCancelComposition();
EXPECT_FALSE(view_->has_composition_text_);
}
+// Checks that we reset has_composition_text_ to false upon when the focused
+// node is changed.
+TEST_F(RenderWidgetHostViewAuraTest, FocusedNodeChanged) {
+ view_->InitAsChild(nullptr);
+ view_->Show();
+ ActivateViewForTextInputManager(view_, ui::TEXT_INPUT_TYPE_TEXT);
+
+ ui::CompositionText composition_text;
+ composition_text.text = base::ASCIIToUTF16("hello");
+ view_->SetCompositionText(composition_text);
+ EXPECT_TRUE(view_->has_composition_text_);
+
+ view_->FocusedNodeChanged(true, gfx::Rect());
+ EXPECT_FALSE(view_->has_composition_text_);
+}
+
// Checks that sequence of IME-composition-event and mouse-event when mouse
// clicking to cancel the composition.
TEST_F(RenderWidgetHostViewAuraTest, FinishCompositionByMouse) {
@@ -1696,22 +1726,20 @@ TEST_F(RenderWidgetHostViewAuraTest, FinishCompositionByMouse) {
view_->SetCompositionText(composition_text);
EXPECT_TRUE(view_->has_composition_text_);
- sink_->ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("SetComposition", GetMessageNames(GetAndResetDispatchedMessages()));
// Simulates the mouse press.
ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
0);
view_->OnMouseEvent(&mouse_event);
+ base::RunLoop().RunUntilIdle();
EXPECT_FALSE(view_->has_composition_text_);
- ASSERT_EQ(2U, sink_->message_count());
-
- // Verify mouse event happens after the finish composing text event.
- EXPECT_EQ(InputMsg_ImeFinishComposingText::ID,
- sink_->GetMessageAt(0)->type());
- EXPECT_EQ(InputMsg_HandleInputEvent::ID, sink_->GetMessageAt(1)->type());
+ EXPECT_EQ("FinishComposingText MouseDown",
+ GetMessageNames(GetAndResetDispatchedMessages()));
}
// Checks that WasOcculded/WasUnOccluded notifies RenderWidgetHostImpl.
@@ -1752,10 +1780,9 @@ TEST_F(RenderWidgetHostViewAuraTest, WasOccluded) {
}
// Checks that touch-event state is maintained correctly.
-TEST_F(RenderWidgetHostViewAuraRafAlignedTouchDisabledTest, TouchEventState) {
+TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
view_->InitAsChild(nullptr);
view_->Show();
- GetSentMessageCountAndResetSink();
// Start with no touch-event handler in the renderer.
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
@@ -1773,105 +1800,25 @@ TEST_F(RenderWidgetHostViewAuraRafAlignedTouchDisabledTest, TouchEventState) {
// The touch events should get forwarded from the view, but they should not
// reach the renderer.
view_->OnTouchEvent(&press);
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
- EXPECT_TRUE(press.synchronous_handling_disabled());
- EXPECT_EQ(ui::MotionEvent::ACTION_DOWN, pointer_state().GetAction());
-
- view_->OnTouchEvent(&move);
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
- EXPECT_TRUE(press.synchronous_handling_disabled());
- EXPECT_EQ(ui::MotionEvent::ACTION_MOVE, pointer_state().GetAction());
- EXPECT_EQ(1U, pointer_state().GetPointerCount());
-
- view_->OnTouchEvent(&release);
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
- EXPECT_TRUE(press.synchronous_handling_disabled());
- EXPECT_EQ(0U, pointer_state().GetPointerCount());
-
- // Now install some touch-event handlers and do the same steps. The touch
- // events should now be consumed. However, the touch-event state should be
- // updated as before.
- widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
-
- view_->OnTouchEvent(&press);
- EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
- EXPECT_TRUE(press.synchronous_handling_disabled());
- EXPECT_EQ(ui::MotionEvent::ACTION_DOWN, pointer_state().GetAction());
- EXPECT_EQ(1U, pointer_state().GetPointerCount());
-
- view_->OnTouchEvent(&move);
- EXPECT_TRUE(move.synchronous_handling_disabled());
- EXPECT_EQ(ui::MotionEvent::ACTION_MOVE, pointer_state().GetAction());
- EXPECT_EQ(1U, pointer_state().GetPointerCount());
- view_->OnTouchEvent(&release);
- EXPECT_TRUE(release.synchronous_handling_disabled());
- EXPECT_EQ(0U, pointer_state().GetPointerCount());
-
- // Now start a touch event, and remove the event-handlers before the release.
- view_->OnTouchEvent(&press);
- EXPECT_TRUE(press.synchronous_handling_disabled());
- EXPECT_EQ(ui::MotionEvent::ACTION_DOWN, pointer_state().GetAction());
- EXPECT_EQ(1U, pointer_state().GetPointerCount());
-
- widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
-
- // Ack'ing the outstanding event should flush the pending touch queue.
- InputEventAck ack(
- InputEventAckSource::COMPOSITOR_THREAD, blink::WebInputEvent::kTouchStart,
- INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, press.unique_event_id());
- widget_host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
-
- ui::TouchEvent move2(
- ui::ET_TOUCH_MOVED, gfx::Point(20, 20), base::TimeTicks::Now(),
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
- view_->OnTouchEvent(&move2);
- EXPECT_TRUE(press.synchronous_handling_disabled());
- EXPECT_EQ(ui::MotionEvent::ACTION_MOVE, pointer_state().GetAction());
- EXPECT_EQ(1U, pointer_state().GetPointerCount());
-
- ui::TouchEvent release2(
- ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), base::TimeTicks::Now(),
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
- view_->OnTouchEvent(&release2);
- EXPECT_TRUE(press.synchronous_handling_disabled());
- EXPECT_EQ(0U, pointer_state().GetPointerCount());
-}
-
-// Checks that touch-event state is maintained correctly.
-TEST_F(RenderWidgetHostViewAuraRafAlignedTouchEnabledTest, TouchEventState) {
- view_->InitAsChild(nullptr);
- view_->Show();
- GetSentMessageCountAndResetSink();
-
- // Start with no touch-event handler in the renderer.
- widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
-
- ui::TouchEvent press(
- ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), ui::EventTimeForNow(),
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
- ui::TouchEvent move(
- ui::ET_TOUCH_MOVED, gfx::Point(20, 20), ui::EventTimeForNow(),
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
- ui::TouchEvent release(
- ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), ui::EventTimeForNow(),
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
-
- // The touch events should get forwarded from the view, but they should not
- // reach the renderer.
- view_->OnTouchEvent(&press);
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(ui::MotionEvent::ACTION_DOWN, pointer_state().GetAction());
view_->OnTouchEvent(&move);
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(ui::MotionEvent::ACTION_MOVE, pointer_state().GetAction());
EXPECT_EQ(1U, pointer_state().GetPointerCount());
view_->OnTouchEvent(&release);
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(0U, pointer_state().GetPointerCount());
@@ -1881,12 +1828,15 @@ TEST_F(RenderWidgetHostViewAuraRafAlignedTouchEnabledTest, TouchEventState) {
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
view_->OnTouchEvent(&press);
- EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, events.size());
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(ui::MotionEvent::ACTION_DOWN, pointer_state().GetAction());
EXPECT_EQ(1U, pointer_state().GetPointerCount());
view_->OnTouchEvent(&move);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(move.synchronous_handling_disabled());
EXPECT_EQ(ui::MotionEvent::ACTION_MOVE, pointer_state().GetAction());
EXPECT_EQ(1U, pointer_state().GetPointerCount());
@@ -1896,10 +1846,12 @@ TEST_F(RenderWidgetHostViewAuraRafAlignedTouchEnabledTest, TouchEventState) {
// Now start a touch event, and remove the event-handlers before the release.
view_->OnTouchEvent(&press);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(ui::MotionEvent::ACTION_DOWN, pointer_state().GetAction());
EXPECT_EQ(1U, pointer_state().GetPointerCount());
- EXPECT_EQ(3U, GetSentMessageCountAndResetSink());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(3U, events.size());
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
@@ -1909,12 +1861,14 @@ TEST_F(RenderWidgetHostViewAuraRafAlignedTouchEnabledTest, TouchEventState) {
InputEventAckSource::COMPOSITOR_THREAD, blink::WebInputEvent::kTouchStart,
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, press.unique_event_id());
widget_host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
ui::TouchEvent move2(
ui::ET_TOUCH_MOVED, gfx::Point(20, 20), base::TimeTicks::Now(),
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
view_->OnTouchEvent(&move2);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(ui::MotionEvent::ACTION_MOVE, pointer_state().GetAction());
EXPECT_EQ(1U, pointer_state().GetPointerCount());
@@ -1923,9 +1877,11 @@ TEST_F(RenderWidgetHostViewAuraRafAlignedTouchEnabledTest, TouchEventState) {
ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), base::TimeTicks::Now(),
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
view_->OnTouchEvent(&release2);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(0U, pointer_state().GetPointerCount());
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
}
TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
@@ -1937,52 +1893,52 @@ TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
ui::MouseWheelEvent event(gfx::Vector2d(0, 5), gfx::Point(2, 2),
gfx::Point(2, 2), ui::EventTimeForNow(), 0, 0);
view_->OnMouseEvent(&event);
- const WebInputEvent* input_event =
- GetInputEventFromMessage(*sink_->GetMessageAt(0));
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+
+ EXPECT_TRUE(events[0]->ToEvent());
const WebMouseWheelEvent* wheel_event =
- static_cast<const WebMouseWheelEvent*>(input_event);
+ static_cast<const WebMouseWheelEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
- SendInputEventACK(blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(1));
- const WebGestureEvent* gesture_event =
- static_cast<const WebGestureEvent*>(input_event);
+ events = GetAndResetDispatchedMessages();
+ const WebGestureEvent* gesture_event = static_cast<const WebGestureEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebInputEvent::kGestureScrollBegin, gesture_event->GetType());
- SendInputEventACK(WebInputEvent::kGestureScrollBegin,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_TRUE(gesture_event->data.scroll_begin.synthetic);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(2));
- gesture_event = static_cast<const WebGestureEvent*>(input_event);
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, gesture_event->GetType());
EXPECT_EQ(0U, gesture_event->data.scroll_update.delta_x);
EXPECT_EQ(5U, gesture_event->data.scroll_update.delta_y);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- sink_->ClearMessages();
+ events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Send a ui::ScrollEvent instead of ui::MouseWheel event, the timer based
// phase info doesn't diffrentiate between the two types of events.
ui::ScrollEvent scroll1(ui::ET_SCROLL, gfx::Point(2, 2),
ui::EventTimeForNow(), 0, 0, 2, 0, 2, 2);
view_->OnScrollEvent(&scroll1);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0));
- wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ wheel_event = static_cast<const WebMouseWheelEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
base::TimeTicks wheel_event_timestamp =
ui::EventTimeStampFromSeconds(wheel_event->TimeStampSeconds());
EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, wheel_event->phase);
- SendInputEventACK(blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(1));
- gesture_event = static_cast<const WebGestureEvent*>(input_event);
+ events = GetAndResetDispatchedMessages();
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, gesture_event->GetType());
EXPECT_EQ(0U, gesture_event->data.scroll_update.delta_x);
EXPECT_EQ(2U, gesture_event->data.scroll_update.delta_y);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
-
- sink_->ClearMessages();
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Let the MouseWheelPhaseHandler::mouse_wheel_end_dispatch_timer_ fire. A
// synthetic wheel event with zero deltas and kPhaseEnded will be sent.
@@ -1992,9 +1948,10 @@ TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
kDefaultMouseWheelLatchingTransactionMs));
base::RunLoop().Run();
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0));
+ events = GetAndResetDispatchedMessages();
const WebMouseWheelEvent* wheel_end_event =
- static_cast<const WebMouseWheelEvent*>(input_event);
+ static_cast<const WebMouseWheelEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_end_event->phase);
EXPECT_EQ(0U, wheel_end_event->delta_x);
EXPECT_EQ(0U, wheel_end_event->delta_y);
@@ -2002,84 +1959,111 @@ TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
EXPECT_EQ(0U, wheel_end_event->wheel_ticks_y);
EXPECT_GT(ui::EventTimeStampFromSeconds(wheel_end_event->TimeStampSeconds()),
wheel_event_timestamp);
- SendInputEventACK(blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(1));
- gesture_event = static_cast<const WebGestureEvent*>(input_event);
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebInputEvent::kGestureScrollEnd, gesture_event->GetType());
- sink_->ClearMessages();
+ EXPECT_TRUE(gesture_event->data.scroll_end.synthetic);
}
-// Tests that a gesture fling start with touchpad source stops the
-// RenderWidgetHostViewEventHandler::mouse_wheel_phase_timer_ and no synthetic
-// wheel event will be sent.
+// Tests that a gesture fling start with touchpad source resets wheel phase
+// state.
TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
- TouchpadFlingStartStopsWheelPhaseTimer) {
+ TouchpadFlingStartResetsWheelPhaseState) {
+ // When the user puts their fingers down a GFC is receieved.
+ ui::ScrollEvent fling_cancel(ui::ET_SCROLL_FLING_CANCEL, gfx::Point(2, 2),
+ ui::EventTimeForNow(), 0, 0, 0, 0, 0, 2);
+ view_->OnScrollEvent(&fling_cancel);
+
+ // Scrolling starts.
ui::ScrollEvent scroll0(ui::ET_SCROLL, gfx::Point(2, 2),
ui::EventTimeForNow(), 0, 0, 5, 0, 5, 2);
view_->OnScrollEvent(&scroll0);
- const WebInputEvent* input_event =
- GetInputEventFromMessage(*sink_->GetMessageAt(0));
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+
const WebMouseWheelEvent* wheel_event =
- static_cast<const WebMouseWheelEvent*>(input_event);
+ static_cast<const WebMouseWheelEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
- SendInputEventACK(blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(1));
- const WebGestureEvent* gesture_event =
- static_cast<const WebGestureEvent*>(input_event);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));
+ const WebGestureEvent* gesture_event = static_cast<const WebGestureEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebInputEvent::kGestureScrollBegin, gesture_event->GetType());
- SendInputEventACK(WebInputEvent::kGestureScrollBegin,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(2));
- gesture_event = static_cast<const WebGestureEvent*>(input_event);
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, gesture_event->GetType());
EXPECT_EQ(0U, gesture_event->data.scroll_update.delta_x);
EXPECT_EQ(5U, gesture_event->data.scroll_update.delta_y);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- sink_->ClearMessages();
+ events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+
+ // Wait for some time and resume scrolling. The second scroll will latch since
+ // the user hasn't lifted their fingers, yet.
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ base::TimeDelta::FromMilliseconds(
+ 2 * kDefaultMouseWheelLatchingTransactionMs));
+ run_loop.Run();
+ ui::ScrollEvent scroll1(ui::ET_SCROLL, gfx::Point(2, 2),
+ ui::EventTimeForNow(), 0, 0, 15, 0, 15, 2);
+ view_->OnScrollEvent(&scroll1);
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, events.size());
+ wheel_event = static_cast<const WebMouseWheelEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
+ EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, wheel_event->phase);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollUpdate", GetMessageNames(events));
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
+ EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, gesture_event->GetType());
+ EXPECT_EQ(0U, gesture_event->data.scroll_update.delta_x);
+ EXPECT_EQ(15U, gesture_event->data.scroll_update.delta_y);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+ // A GFS is received showing that the user has lifted their fingers. This will
+ // reset the scroll state of the wheel phase handler.
ui::ScrollEvent fling_start(ui::ET_SCROLL_FLING_START, gfx::Point(2, 2),
ui::EventTimeForNow(), 0, 0, 10, 0, 10, 2);
view_->OnScrollEvent(&fling_start);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0));
- gesture_event = static_cast<const WebGestureEvent*>(input_event);
- EXPECT_EQ(WebInputEvent::kGestureFlingStart, gesture_event->GetType());
- SendInputEventACK(WebInputEvent::kGestureFlingStart,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- sink_->ClearMessages();
-
- // Let the MouseWheelPhaseHandler::mouse_wheel_end_dispatch_timer_ fire. No
- // synthetic wheel event will be sent since the timer has stopped.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
- base::TimeDelta::FromMilliseconds(
- kDefaultMouseWheelLatchingTransactionMs));
- base::RunLoop().Run();
+ base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0U, sink_->message_count());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureFlingStart", GetMessageNames(events));
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
+ EXPECT_EQ(WebInputEvent::kGestureFlingStart, gesture_event->GetType());
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendNotConsumedAcks(events);
// Handling the next ui::ET_SCROLL event will send a fling cancellation and a
// mouse wheel with kPhaseBegan.
- ui::ScrollEvent scroll1(ui::ET_SCROLL, gfx::Point(2, 2),
+ ui::ScrollEvent scroll2(ui::ET_SCROLL, gfx::Point(2, 2),
ui::EventTimeForNow(), 0, 0, 15, 0, 15, 2);
- view_->OnScrollEvent(&scroll1);
- EXPECT_EQ(2U, sink_->message_count());
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0));
- gesture_event = static_cast<const WebGestureEvent*>(input_event);
+ view_->OnScrollEvent(&scroll2);
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(2U, events.size());
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebInputEvent::kGestureFlingCancel, gesture_event->GetType());
- SendInputEventACK(WebInputEvent::kGestureFlingCancel,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(1));
- wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+ wheel_event = static_cast<const WebMouseWheelEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
- sink_->ClearMessages();
}
TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
@@ -2087,52 +2071,54 @@ TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
ui::ScrollEvent scroll0(ui::ET_SCROLL, gfx::Point(2, 2),
ui::EventTimeForNow(), 0, 0, 5, 0, 5, 2);
view_->OnScrollEvent(&scroll0);
- const WebInputEvent* input_event =
- GetInputEventFromMessage(*sink_->GetMessageAt(0));
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
const WebMouseWheelEvent* wheel_event =
- static_cast<const WebMouseWheelEvent*>(input_event);
+ static_cast<const WebMouseWheelEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
- SendInputEventACK(blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(1));
- const WebGestureEvent* gesture_event =
- static_cast<const WebGestureEvent*>(input_event);
- EXPECT_EQ(WebInputEvent::kGestureScrollBegin, gesture_event->GetType());
- SendInputEventACK(WebInputEvent::kGestureScrollBegin,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));
+ const WebGestureEvent* gesture_event = static_cast<const WebGestureEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(2));
- gesture_event = static_cast<const WebGestureEvent*>(input_event);
- EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, gesture_event->GetType());
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(0U, gesture_event->data.scroll_update.delta_x);
EXPECT_EQ(5U, gesture_event->data.scroll_update.delta_y);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- sink_->ClearMessages();
+ events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
ui::GestureEventDetails event_details(ui::ET_GESTURE_SCROLL_BEGIN);
event_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
ui::GestureEvent scroll_begin(2, 2, 0, ui::EventTimeForNow(), event_details);
view_->OnGestureEvent(&scroll_begin);
- EXPECT_EQ(3U, sink_->message_count());
+ base::RunLoop().RunUntilIdle();
+
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel GestureScrollEnd GestureScrollBegin",
+ GetMessageNames(events));
+ EXPECT_EQ(3U, events.size());
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0));
- wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+ wheel_event = static_cast<const WebMouseWheelEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase);
EXPECT_EQ(0U, wheel_event->delta_x);
EXPECT_EQ(0U, wheel_event->delta_y);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(1));
- gesture_event = static_cast<const WebGestureEvent*>(input_event);
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebInputEvent::kGestureScrollEnd, gesture_event->GetType());
EXPECT_EQ(blink::kWebGestureDeviceTouchpad, gesture_event->source_device);
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(2));
- gesture_event = static_cast<const WebGestureEvent*>(input_event);
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[2]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebInputEvent::kGestureScrollBegin, gesture_event->GetType());
EXPECT_EQ(blink::kWebGestureDeviceTouchscreen, gesture_event->source_device);
- sink_->ClearMessages();
}
// Checks that touch-event state is maintained correctly for multiple touch
@@ -2141,15 +2127,18 @@ TEST_F(RenderWidgetHostViewAuraTest, MultiTouchPointsStates) {
view_->InitAsFullscreen(parent_view_);
view_->Show();
view_->UseFakeDispatcher();
- GetSentMessageCountAndResetSink();
ui::TouchEvent press0(
ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), ui::EventTimeForNow(),
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
view_->OnTouchEvent(&press0);
- SendTouchEventACK(blink::WebInputEvent::kTouchStart,
- INPUT_EVENT_ACK_STATE_CONSUMED, press0.unique_event_id());
+ base::RunLoop().RunUntilIdle();
+
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("SetFocus TouchStart", GetMessageNames(events));
+ events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(ui::MotionEvent::ACTION_DOWN, pointer_state().GetAction());
EXPECT_EQ(1U, pointer_state().GetPointerCount());
EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
@@ -2159,8 +2148,10 @@ TEST_F(RenderWidgetHostViewAuraTest, MultiTouchPointsStates) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
view_->OnTouchEvent(&move0);
- SendTouchEventACK(blink::WebInputEvent::kTouchMove,
- INPUT_EVENT_ACK_STATE_CONSUMED, move0.unique_event_id());
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchMove", GetMessageNames(events));
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(ui::MotionEvent::ACTION_MOVE, pointer_state().GetAction());
EXPECT_EQ(1U, pointer_state().GetPointerCount());
EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
@@ -2172,8 +2163,10 @@ TEST_F(RenderWidgetHostViewAuraTest, MultiTouchPointsStates) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
view_->OnTouchEvent(&press1);
- SendTouchEventACK(blink::WebInputEvent::kTouchStart,
- INPUT_EVENT_ACK_STATE_CONSUMED, press1.unique_event_id());
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchStart", GetMessageNames(events));
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(ui::MotionEvent::ACTION_POINTER_DOWN, pointer_state().GetAction());
EXPECT_EQ(1, pointer_state().GetActionIndex());
EXPECT_EQ(2U, pointer_state().GetPointerCount());
@@ -2186,8 +2179,10 @@ TEST_F(RenderWidgetHostViewAuraTest, MultiTouchPointsStates) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
view_->OnTouchEvent(&move1);
- SendTouchEventACK(blink::WebInputEvent::kTouchMove,
- INPUT_EVENT_ACK_STATE_CONSUMED, move1.unique_event_id());
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchMove", GetMessageNames(events));
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(ui::MotionEvent::ACTION_MOVE, pointer_state().GetAction());
EXPECT_EQ(2U, pointer_state().GetPointerCount());
EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
@@ -2199,8 +2194,10 @@ TEST_F(RenderWidgetHostViewAuraTest, MultiTouchPointsStates) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
view_->OnTouchEvent(&move2);
- SendTouchEventACK(blink::WebInputEvent::kTouchMove,
- INPUT_EVENT_ACK_STATE_CONSUMED, move2.unique_event_id());
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchMove", GetMessageNames(events));
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(ui::MotionEvent::ACTION_MOVE, pointer_state().GetAction());
EXPECT_EQ(2U, pointer_state().GetPointerCount());
EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
@@ -2212,6 +2209,9 @@ TEST_F(RenderWidgetHostViewAuraTest, MultiTouchPointsStates) {
// For the touchcancel, only the state of the current touch point is
// StateCancelled, the state of the other touch point is StateStationary.
view_->OnTouchEvent(&cancel0);
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchCancel", GetMessageNames(events));
EXPECT_EQ(1U, pointer_state().GetPointerCount());
EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
@@ -2220,6 +2220,9 @@ TEST_F(RenderWidgetHostViewAuraTest, MultiTouchPointsStates) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
view_->OnTouchEvent(&cancel1);
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchCancel", GetMessageNames(events));
EXPECT_EQ(1U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
EXPECT_EQ(0U, pointer_state().GetPointerCount());
}
@@ -2313,6 +2316,56 @@ TEST_F(RenderWidgetHostViewAuraTest, PhysicalBackingSizeWithScale) {
EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString());
}
+// This test verifies that in AutoResize mode a new
+// ViewMsg_SetLocalSurfaceIdForAutoResize message is sent when ScreenInfo
+// changes and that message contains the latest ScreenInfo.
+TEST_F(RenderWidgetHostViewAuraTest, AutoResizeWithScale) {
+ view_->InitAsChild(nullptr);
+ aura::client::ParentWindowWithContext(
+ view_->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(),
+ gfx::Rect());
+ sink_->ClearMessages();
+ widget_host_->SetAutoResize(true, gfx::Size(50, 50), gfx::Size(100, 100));
+ ViewHostMsg_ResizeOrRepaint_ACK_Params params;
+ params.view_size = gfx::Size(75, 75);
+ params.sequence_number = 1;
+ widget_host_->OnResizeOrRepaintACK(params);
+
+ // RenderWidgetHostImpl has delayed auto-resize processing. Yield here to
+ // let it complete.
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
+ run_loop.Run();
+
+ EXPECT_EQ(1u, sink_->message_count());
+ {
+ const IPC::Message* msg = sink_->GetMessageAt(0);
+ EXPECT_EQ(ViewMsg_SetLocalSurfaceIdForAutoResize::ID, msg->type());
+ ViewMsg_SetLocalSurfaceIdForAutoResize::Param params;
+ ViewMsg_SetLocalSurfaceIdForAutoResize::Read(msg, &params);
+ EXPECT_EQ(1u, std::get<0>(params)); // sequence_number
+ EXPECT_EQ("50x50", std::get<1>(params).ToString());
+ EXPECT_EQ("100x100", std::get<2>(params).ToString());
+ EXPECT_EQ(1, std::get<3>(params).device_scale_factor);
+ }
+
+ sink_->ClearMessages();
+ aura_test_helper_->test_screen()->SetDeviceScaleFactor(2.0f);
+
+ EXPECT_EQ(2u, sink_->message_count());
+ {
+ const IPC::Message* msg = sink_->GetMessageAt(1);
+ EXPECT_EQ(ViewMsg_SetLocalSurfaceIdForAutoResize::ID, msg->type());
+ ViewMsg_SetLocalSurfaceIdForAutoResize::Param params;
+ ViewMsg_SetLocalSurfaceIdForAutoResize::Read(msg, &params);
+ EXPECT_EQ(1u, std::get<0>(params)); // sequence_number
+ EXPECT_EQ("50x50", std::get<1>(params).ToString());
+ EXPECT_EQ("100x100", std::get<2>(params).ToString());
+ EXPECT_EQ(2, std::get<3>(params).device_scale_factor);
+ }
+}
+
// Checks that InputMsg_CursorVisibilityChange IPC messages are dispatched
// to the renderer at the correct times.
TEST_F(RenderWidgetHostViewAuraTest, CursorVisibilityChange) {
@@ -2330,68 +2383,69 @@ TEST_F(RenderWidgetHostViewAuraTest, CursorVisibilityChange) {
// Expect a message the first time the cursor is shown.
view_->Show();
- sink_->ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ GetAndResetDispatchedMessages();
cursor_client.ShowCursor();
- EXPECT_EQ(1u, sink_->message_count());
- EXPECT_TRUE(sink_->GetUniqueMessageMatching(
- InputMsg_CursorVisibilityChange::ID));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("CursorVisibilityChanged",
+ GetMessageNames(GetAndResetDispatchedMessages()));
// No message expected if the renderer already knows the cursor is visible.
- sink_->ClearMessages();
cursor_client.ShowCursor();
- EXPECT_EQ(0u, sink_->message_count());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0u, GetAndResetDispatchedMessages().size());
// Hiding the cursor should send a message.
- sink_->ClearMessages();
cursor_client.HideCursor();
- EXPECT_EQ(1u, sink_->message_count());
- EXPECT_TRUE(sink_->GetUniqueMessageMatching(
- InputMsg_CursorVisibilityChange::ID));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("CursorVisibilityChanged",
+ GetMessageNames(GetAndResetDispatchedMessages()));
// No message expected if the renderer already knows the cursor is invisible.
- sink_->ClearMessages();
cursor_client.HideCursor();
- EXPECT_EQ(0u, sink_->message_count());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0u, GetAndResetDispatchedMessages().size());
// No messages should be sent while the view is invisible.
view_->Hide();
- sink_->ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ GetAndResetDispatchedMessages();
cursor_client.ShowCursor();
- EXPECT_EQ(0u, sink_->message_count());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0u, GetAndResetDispatchedMessages().size());
cursor_client.HideCursor();
- EXPECT_EQ(0u, sink_->message_count());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0u, GetAndResetDispatchedMessages().size());
// Show the view. Since the cursor was invisible when the view was hidden,
// no message should be sent.
- sink_->ClearMessages();
view_->Show();
- EXPECT_FALSE(sink_->GetUniqueMessageMatching(
- InputMsg_CursorVisibilityChange::ID));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0u, GetAndResetDispatchedMessages().size());
// No message expected if the renderer already knows the cursor is invisible.
- sink_->ClearMessages();
cursor_client.HideCursor();
- EXPECT_EQ(0u, sink_->message_count());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0u, GetAndResetDispatchedMessages().size());
// Showing the cursor should send a message.
- sink_->ClearMessages();
cursor_client.ShowCursor();
- EXPECT_EQ(1u, sink_->message_count());
- EXPECT_TRUE(sink_->GetUniqueMessageMatching(
- InputMsg_CursorVisibilityChange::ID));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("CursorVisibilityChanged",
+ GetMessageNames(GetAndResetDispatchedMessages()));
// No messages should be sent while the view is invisible.
view_->Hide();
- sink_->ClearMessages();
cursor_client.HideCursor();
- EXPECT_EQ(0u, sink_->message_count());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0u, GetAndResetDispatchedMessages().size());
// Show the view. Since the cursor was visible when the view was hidden,
// a message is expected to be sent.
- sink_->ClearMessages();
view_->Show();
- EXPECT_TRUE(sink_->GetUniqueMessageMatching(
- InputMsg_CursorVisibilityChange::ID));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("CursorVisibilityChanged",
+ GetMessageNames(GetAndResetDispatchedMessages()));
cursor_client.RemoveObserver(view_);
}
@@ -2512,7 +2566,8 @@ TEST_F(RenderWidgetHostViewAuraTest, TwoOutputSurfaces) {
viz::TransferableResource resource;
resource.id = 1;
frame.resource_list.push_back(resource);
- view_->SubmitCompositorFrame(kArbitraryLocalSurfaceId, std::move(frame));
+ view_->SubmitCompositorFrame(kArbitraryLocalSurfaceId, std::move(frame),
+ nullptr);
EXPECT_EQ(0u, sink_->message_count());
// Signal that a new RendererCompositorFrameSink was created by the renderer.
@@ -2521,7 +2576,8 @@ TEST_F(RenderWidgetHostViewAuraTest, TwoOutputSurfaces) {
// Submit another frame. The resources for the previous frame belong to the
// old RendererCompositorFrameSink and should not be returned.
view_->SubmitCompositorFrame(local_surface_id_allocator_.GenerateId(),
- MakeDelegatedFrame(1.f, view_size, view_rect));
+ MakeDelegatedFrame(1.f, view_size, view_rect),
+ nullptr);
EXPECT_EQ(0u, sink_->message_count());
// Report that the surface is drawn to trigger an ACK.
@@ -2562,7 +2618,8 @@ TEST_F(RenderWidgetHostViewAuraTest, DISABLED_FullscreenResize) {
view_->SubmitCompositorFrame(
kArbitraryLocalSurfaceId,
MakeDelegatedFrame(1.f, std::get<0>(params).new_size,
- gfx::Rect(std::get<0>(params).new_size)));
+ gfx::Rect(std::get<0>(params).new_size)),
+ nullptr);
ui::DrawWaiterForTest::WaitForCommit(
root_window->GetHost()->compositor());
}
@@ -2586,44 +2643,13 @@ TEST_F(RenderWidgetHostViewAuraTest, DISABLED_FullscreenResize) {
view_->SubmitCompositorFrame(
kArbitraryLocalSurfaceId,
MakeDelegatedFrame(1.f, std::get<0>(params).new_size,
- gfx::Rect(std::get<0>(params).new_size)));
+ gfx::Rect(std::get<0>(params).new_size)),
+ nullptr);
ui::DrawWaiterForTest::WaitForCommit(
root_window->GetHost()->compositor());
}
}
-// Swapping a frame should notify the window.
-TEST_F(RenderWidgetHostViewAuraTest, SwapNotifiesWindow) {
- gfx::Size view_size(100, 100);
- gfx::Rect view_rect(view_size);
-
- view_->InitAsChild(nullptr);
- aura::client::ParentWindowWithContext(
- view_->GetNativeView(),
- parent_view_->GetNativeView()->GetRootWindow(),
- gfx::Rect());
- view_->SetSize(view_size);
- view_->Show();
-
- MockWindowObserver observer;
- view_->window_->AddObserver(&observer);
-
- // Delegated renderer path
- EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
- view_->SubmitCompositorFrame(kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, view_size, view_rect));
- testing::Mock::VerifyAndClearExpectations(&observer);
-
- EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_,
- gfx::Rect(5, 5, 5, 5)));
- view_->SubmitCompositorFrame(
- kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, view_size, gfx::Rect(5, 5, 5, 5)));
- testing::Mock::VerifyAndClearExpectations(&observer);
-
- view_->window_->RemoveObserver(&observer);
-}
-
// If the view size is larger than the compositor frame then extra layers
// should be created to fill the gap.
TEST_F(RenderWidgetHostViewAuraTest, DelegatedFrameGutter) {
@@ -2645,7 +2671,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DelegatedFrameGutter) {
viz::CompositorFrame frame =
MakeDelegatedFrame(1.f, small_size, gfx::Rect(small_size));
frame.metadata.root_background_color = SK_ColorRED;
- view_->SubmitCompositorFrame(small_id, std::move(frame));
+ view_->SubmitCompositorFrame(small_id, std::move(frame), nullptr);
ui::Layer* parent_layer = view_->GetNativeView()->layer();
@@ -2666,7 +2692,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DelegatedFrameGutter) {
EXPECT_EQ(SK_ColorBLACK, parent_layer->children()[0]->background_color());
frame = MakeDelegatedFrame(1.f, medium_size, gfx::Rect(medium_size));
- view_->SubmitCompositorFrame(medium_id, std::move(frame));
+ view_->SubmitCompositorFrame(medium_id, std::move(frame), nullptr);
EXPECT_EQ(0u, parent_layer->children().size());
view_->SetSize(large_size);
@@ -2678,7 +2704,9 @@ TEST_F(RenderWidgetHostViewAuraTest, DelegatedFrameGutter) {
ASSERT_EQ(0u, parent_layer->children().size());
}
-TEST_F(RenderWidgetHostViewAuraTest, Resize) {
+// Resizing is disabled due to flakiness. Commit might come before
+// DrawWaiterForTest looks for compositor frame. crbug.com/759653
+TEST_F(RenderWidgetHostViewAuraTest, DISABLED_Resize) {
gfx::Size size1(100, 100);
gfx::Size size2(200, 200);
gfx::Size size3(300, 300);
@@ -2693,7 +2721,7 @@ TEST_F(RenderWidgetHostViewAuraTest, Resize) {
view_->Show();
view_->SetSize(size1);
view_->SubmitCompositorFrame(
- id1, MakeDelegatedFrame(1.f, size1, gfx::Rect(size1)));
+ id1, MakeDelegatedFrame(1.f, size1, gfx::Rect(size1)), nullptr);
ui::DrawWaiterForTest::WaitForCommit(
root_window->GetHost()->compositor());
ViewHostMsg_ResizeOrRepaint_ACK_Params update_params;
@@ -2732,7 +2760,7 @@ TEST_F(RenderWidgetHostViewAuraTest, Resize) {
// message.
view_->renderer_compositor_frame_sink_->Reset();
view_->SubmitCompositorFrame(
- id3, MakeDelegatedFrame(1.f, size3, gfx::Rect(size3)));
+ id3, MakeDelegatedFrame(1.f, size3, gfx::Rect(size3)), nullptr);
view_->renderer_compositor_frame_sink_->Flush();
// Expect the frame ack;
EXPECT_TRUE(view_->renderer_compositor_frame_sink_->did_receive_ack());
@@ -2742,7 +2770,7 @@ TEST_F(RenderWidgetHostViewAuraTest, Resize) {
// produce a Resize message after the commit.
view_->renderer_compositor_frame_sink_->Reset();
view_->SubmitCompositorFrame(
- id2, MakeDelegatedFrame(1.f, size2, gfx::Rect(size2)));
+ id2, MakeDelegatedFrame(1.f, size2, gfx::Rect(size2)), nullptr);
view_->renderer_compositor_frame_sink_->Flush();
viz::SurfaceId surface_id = view_->surface_id();
if (!surface_id.is_valid()) {
@@ -2763,18 +2791,6 @@ TEST_F(RenderWidgetHostViewAuraTest, Resize) {
for (uint32_t i = 0; i < sink_->message_count(); ++i) {
const IPC::Message* msg = sink_->GetMessageAt(i);
switch (msg->type()) {
- case InputMsg_HandleInputEvent::ID: {
- // On some platforms, the call to view_->Show() causes a posted task to
- // call
- // ui::WindowEventDispatcher::SynthesizeMouseMoveAfterChangeToWindow,
- // which the above WaitForCommit may cause to be picked up. Be robust
- // to this extra IPC coming in.
- InputMsg_HandleInputEvent::Param params;
- InputMsg_HandleInputEvent::Read(msg, &params);
- const blink::WebInputEvent* event = std::get<0>(params);
- EXPECT_EQ(blink::WebInputEvent::kMouseMove, event->GetType());
- break;
- }
case ViewMsg_Resize::ID: {
EXPECT_FALSE(has_resize);
ViewMsg_Resize::Param params;
@@ -2799,7 +2815,8 @@ TEST_F(RenderWidgetHostViewAuraTest, Resize) {
TEST_F(RenderWidgetHostViewAuraTest, SkippedDelegatedFrames) {
gfx::Rect view_rect(100, 100);
gfx::Size frame_size = view_rect.size();
- viz::LocalSurfaceId local_surface_id = kArbitraryLocalSurfaceId;
+ viz::LocalSurfaceId local_surface_id =
+ local_surface_id_allocator_.GenerateId();
view_->InitAsChild(nullptr);
aura::client::ParentWindowWithContext(
@@ -2808,23 +2825,21 @@ TEST_F(RenderWidgetHostViewAuraTest, SkippedDelegatedFrames) {
gfx::Rect());
view_->SetSize(view_rect.size());
- MockWindowObserver observer;
- view_->window_->AddObserver(&observer);
-
// A full frame of damage.
- EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
view_->SubmitCompositorFrame(local_surface_id,
- MakeDelegatedFrame(1.f, frame_size, view_rect));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
+ EXPECT_EQ(kFrameIndexStart + 1u, FrameIndexForView(view_));
+ EXPECT_EQ(view_rect, DamageRectForView(view_));
view_->RunOnCompositingDidCommit();
// A partial damage frame.
gfx::Rect partial_view_rect(30, 30, 20, 20);
- EXPECT_CALL(observer,
- OnDelegatedFrameDamage(view_->window_, partial_view_rect));
view_->SubmitCompositorFrame(
- local_surface_id, MakeDelegatedFrame(1.f, frame_size, partial_view_rect));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ local_surface_id, MakeDelegatedFrame(1.f, frame_size, partial_view_rect),
+ nullptr);
+ EXPECT_EQ(kFrameIndexStart + 2u, FrameIndexForView(view_));
+ EXPECT_EQ(partial_view_rect, DamageRectForView(view_));
view_->RunOnCompositingDidCommit();
EXPECT_FALSE(view_->resize_locked());
@@ -2838,19 +2853,17 @@ TEST_F(RenderWidgetHostViewAuraTest, SkippedDelegatedFrames) {
// This frame is dropped.
gfx::Rect dropped_damage_rect_1(10, 20, 30, 40);
- EXPECT_CALL(observer, OnDelegatedFrameDamage(_, _)).Times(0);
view_->SubmitCompositorFrame(
local_surface_id,
- MakeDelegatedFrame(1.f, frame_size, dropped_damage_rect_1));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, dropped_damage_rect_1), nullptr);
+ EXPECT_EQ(kFrameIndexStart + 2u, FrameIndexForView(view_));
view_->RunOnCompositingDidCommit();
gfx::Rect dropped_damage_rect_2(40, 50, 10, 20);
- EXPECT_CALL(observer, OnDelegatedFrameDamage(_, _)).Times(0);
view_->SubmitCompositorFrame(
local_surface_id,
- MakeDelegatedFrame(1.f, frame_size, dropped_damage_rect_2));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, dropped_damage_rect_2), nullptr);
+ EXPECT_EQ(kFrameIndexStart + 2u, FrameIndexForView(view_));
view_->RunOnCompositingDidCommit();
EXPECT_TRUE(view_->resize_locked());
@@ -2861,25 +2874,25 @@ TEST_F(RenderWidgetHostViewAuraTest, SkippedDelegatedFrames) {
local_surface_id = local_surface_id_allocator_.GenerateId();
gfx::Rect new_damage_rect(5, 6, 10, 10);
- EXPECT_CALL(observer,
- OnDelegatedFrameDamage(view_->window_, view_rect));
view_->SubmitCompositorFrame(
- local_surface_id, MakeDelegatedFrame(1.f, frame_size, new_damage_rect));
+ local_surface_id, MakeDelegatedFrame(1.f, frame_size, new_damage_rect),
+ nullptr);
// The swap unlocks the compositor.
EXPECT_TRUE(view_->resize_locked());
EXPECT_FALSE(view_->compositor_locked());
- testing::Mock::VerifyAndClearExpectations(&observer);
+ EXPECT_EQ(kFrameIndexStart + 3u, FrameIndexForView(view_));
+ EXPECT_EQ(view_rect, DamageRectForView(view_));
// The UI commit unlocks for further resize.
view_->RunOnCompositingDidCommit();
EXPECT_FALSE(view_->resize_locked());
EXPECT_FALSE(view_->compositor_locked());
// A partial damage frame, this should not be dropped.
- EXPECT_CALL(observer,
- OnDelegatedFrameDamage(view_->window_, partial_view_rect));
view_->SubmitCompositorFrame(
- local_surface_id, MakeDelegatedFrame(1.f, frame_size, partial_view_rect));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ local_surface_id, MakeDelegatedFrame(1.f, frame_size, partial_view_rect),
+ nullptr);
+ EXPECT_EQ(kFrameIndexStart + 4u, FrameIndexForView(view_));
+ EXPECT_EQ(partial_view_rect, DamageRectForView(view_));
view_->RunOnCompositingDidCommit();
EXPECT_FALSE(view_->resize_locked());
EXPECT_FALSE(view_->compositor_locked());
@@ -2900,24 +2913,24 @@ TEST_F(RenderWidgetHostViewAuraTest, SkippedDelegatedFrames) {
EXPECT_TRUE(view_->compositor_locked());
// This frame should not be dropped.
- EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
view_->SubmitCompositorFrame(local_surface_id,
- MakeDelegatedFrame(1.f, frame_size, view_rect));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
+ EXPECT_EQ(kFrameIndexStart + 5u, FrameIndexForView(view_));
+ EXPECT_EQ(view_rect, DamageRectForView(view_));
EXPECT_TRUE(view_->resize_locked());
EXPECT_FALSE(view_->compositor_locked());
view_->RunOnCompositingDidCommit();
EXPECT_FALSE(view_->resize_locked());
EXPECT_FALSE(view_->compositor_locked());
-
- view_->window_->RemoveObserver(&observer);
}
// If resize races with a renderer frame, we should lock for the right size.
TEST_F(RenderWidgetHostViewAuraTest, ResizeAfterReceivingFrame) {
gfx::Rect view_rect(100, 100);
gfx::Size frame_size = view_rect.size();
- viz::LocalSurfaceId local_surface_id = kArbitraryLocalSurfaceId;
+ viz::LocalSurfaceId local_surface_id =
+ local_surface_id_allocator_.GenerateId();
view_->InitAsChild(nullptr);
aura::client::ParentWindowWithContext(
@@ -2925,23 +2938,19 @@ TEST_F(RenderWidgetHostViewAuraTest, ResizeAfterReceivingFrame) {
gfx::Rect());
view_->SetSize(view_rect.size());
- MockWindowObserver observer;
- view_->window_->AddObserver(&observer);
-
// A frame of initial size.
- EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
view_->SubmitCompositorFrame(
local_surface_id,
- MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)), nullptr);
+ EXPECT_EQ(kFrameIndexStart + 1, FrameIndexForView(view_));
+ EXPECT_EQ(view_rect, DamageRectForView(view_));
view_->RunOnCompositingDidCommit();
// A frame of initial size arrives, but we don't commit in the UI yet.
- EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, _));
view_->SubmitCompositorFrame(
local_surface_id,
- MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)), nullptr);
+ EXPECT_EQ(kFrameIndexStart + 2, FrameIndexForView(view_));
EXPECT_FALSE(view_->resize_locked());
EXPECT_FALSE(view_->compositor_locked());
@@ -2952,11 +2961,10 @@ TEST_F(RenderWidgetHostViewAuraTest, ResizeAfterReceivingFrame) {
EXPECT_TRUE(view_->resize_locked());
EXPECT_TRUE(view_->compositor_locked());
- EXPECT_CALL(observer, OnDelegatedFrameDamage(_, _)).Times(0);
view_->SubmitCompositorFrame(
local_surface_id,
- MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)), nullptr);
+ EXPECT_EQ(kFrameIndexStart + 2, FrameIndexForView(view_));
// If the CompositorLock times out in the meantime, a commit would happen.
// Verify that if a commit occurs, the lock remains and we reject frames
@@ -2967,31 +2975,27 @@ TEST_F(RenderWidgetHostViewAuraTest, ResizeAfterReceivingFrame) {
// In this case we lied about it and the CompositorLock is still active.
EXPECT_TRUE(view_->compositor_locked());
- EXPECT_CALL(observer, OnDelegatedFrameDamage(_, _)).Times(0);
view_->SubmitCompositorFrame(
local_surface_id,
- MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)), nullptr);
+ EXPECT_EQ(kFrameIndexStart + 2, FrameIndexForView(view_));
// A frame arrives of the new size, which will be accepted.
frame_size = view_rect.size();
local_surface_id = local_surface_id_allocator_.GenerateId();
- EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, _));
view_->SubmitCompositorFrame(
local_surface_id,
- MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)));
+ MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)), nullptr);
// Receiving the frame unlocks the compositor so it can commit.
EXPECT_TRUE(view_->resize_locked());
EXPECT_FALSE(view_->compositor_locked());
- testing::Mock::VerifyAndClearExpectations(&observer);
+ EXPECT_EQ(kFrameIndexStart + 3, FrameIndexForView(view_));
// When the frame of the correct size is committed, the CompositorResizeLock
// is released.
view_->RunOnCompositingDidCommit();
EXPECT_FALSE(view_->resize_locked());
EXPECT_FALSE(view_->compositor_locked());
-
- view_->window_->RemoveObserver(&observer);
}
// When the DelegatedFrameHost does not have a frame from the renderer, it has
@@ -3017,7 +3021,7 @@ TEST_F(RenderWidgetHostViewAuraTest, MissingFramesDontLock) {
// DelegatedFrameHost, at which point locking becomes feasible if resized.
view_->SubmitCompositorFrame(
kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)));
+ MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)), nullptr);
view_->RunOnCompositingDidCommit();
EXPECT_FALSE(view_->resize_locked());
@@ -3054,24 +3058,23 @@ TEST_F(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange) {
gfx::Rect());
view_->SetSize(view_rect.size());
- MockWindowObserver observer;
- view_->window_->AddObserver(&observer);
-
// Swap a frame.
- EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
view_->SubmitCompositorFrame(kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, frame_size, view_rect));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
+ EXPECT_EQ(kFrameIndexStart + 1, FrameIndexForView(view_));
+ EXPECT_EQ(view_rect, DamageRectForView(view_));
view_->RunOnCompositingDidCommit();
// Signal that a new RendererCompositorFrameSink was created.
view_->CreateNewRendererCompositorFrameSink();
// Submit a frame from the new RendererCompositorFrameSink.
- EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
view_->SubmitCompositorFrame(local_surface_id_allocator_.GenerateId(),
- MakeDelegatedFrame(1.f, frame_size, view_rect));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
+ EXPECT_EQ(kFrameIndexStart + 1, FrameIndexForView(view_));
+ EXPECT_EQ(view_rect, DamageRectForView(view_));
view_->RunOnCompositingDidCommit();
// Signal that a new RendererCompositorFrameSink was created.
@@ -3080,21 +3083,21 @@ TEST_F(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange) {
// Submit a frame from the new RendererCompositorFrameSink.
view_->SubmitCompositorFrame(
local_surface_id_allocator_.GenerateId(),
- MakeDelegatedFrame(1.f, gfx::Size(), gfx::Rect()));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, gfx::Size(), gfx::Rect()), nullptr);
+ EXPECT_EQ(kFrameIndexStart + 1, FrameIndexForView(view_));
+ EXPECT_EQ(view_rect, DamageRectForView(view_));
view_->RunOnCompositingDidCommit();
// Signal that a new RendererCompositorFrameSink was created.
view_->CreateNewRendererCompositorFrameSink();
// Swap another frame, with a different surface id.
- EXPECT_CALL(observer, OnDelegatedFrameDamage(view_->window_, view_rect));
view_->SubmitCompositorFrame(local_surface_id_allocator_.GenerateId(),
- MakeDelegatedFrame(1.f, frame_size, view_rect));
- testing::Mock::VerifyAndClearExpectations(&observer);
+ MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
+ EXPECT_EQ(kFrameIndexStart + 1, FrameIndexForView(view_));
+ EXPECT_EQ(view_rect, DamageRectForView(view_));
view_->RunOnCompositingDidCommit();
-
- view_->window_->RemoveObserver(&observer);
}
// This test verifies that the primary SurfaceInfo is populated on resize and
@@ -3108,28 +3111,56 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest, SurfaceChanges) {
// Prevent the DelegatedFrameHost from skipping frames.
view_->DisableResizeLock();
EXPECT_FALSE(view_->HasPrimarySurface());
+ ASSERT_TRUE(view_->delegated_frame_host_);
view_->SetSize(gfx::Size(300, 300));
ASSERT_TRUE(view_->HasPrimarySurface());
+ EXPECT_EQ(gfx::Size(300, 300), view_->window_->layer()->size());
+ EXPECT_FALSE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid());
EXPECT_EQ(gfx::Size(300, 300),
- view_->window_->layer()->GetPrimarySurfaceInfo()->size_in_pixels());
- EXPECT_FALSE(view_->window_->layer()->GetFallbackSurfaceInfo()->is_valid());
+ view_->delegated_frame_host_->CurrentFrameSizeInDipForTesting());
// Resizing should update the primary SurfaceInfo.
view_->SetSize(gfx::Size(400, 400));
+ EXPECT_EQ(gfx::Size(400, 400), view_->window_->layer()->size());
+ EXPECT_FALSE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid());
EXPECT_EQ(gfx::Size(400, 400),
- view_->window_->layer()->GetPrimarySurfaceInfo()->size_in_pixels());
- EXPECT_FALSE(view_->window_->layer()->GetFallbackSurfaceInfo()->is_valid());
+ view_->delegated_frame_host_->CurrentFrameSizeInDipForTesting());
// Submitting a CompositorFrame should update the fallback SurfaceInfo
view_->SubmitCompositorFrame(
kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, gfx::Size(400, 400), gfx::Rect(400, 400)));
- EXPECT_EQ(gfx::Size(400, 400),
- view_->window_->layer()->GetPrimarySurfaceInfo()->size_in_pixels());
- EXPECT_EQ(
- gfx::Size(400, 400),
- view_->window_->layer()->GetFallbackSurfaceInfo()->size_in_pixels());
+ MakeDelegatedFrame(1.f, gfx::Size(400, 400), gfx::Rect(400, 400)),
+ nullptr);
+ EXPECT_EQ(gfx::Size(400, 400), view_->window_->layer()->size());
+}
+
+// This test verifies that the primary SurfaceInfo is updated on device scale
+// factor changes.
+TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
+ DeviceScaleFactorChanges) {
+ view_->InitAsChild(nullptr);
+ aura::client::ParentWindowWithContext(
+ view_->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(),
+ gfx::Rect());
+
+ // Prevent the DelegatedFrameHost from skipping frames.
+ view_->DisableResizeLock();
+ EXPECT_FALSE(view_->HasPrimarySurface());
+
+ view_->SetSize(gfx::Size(300, 300));
+ ASSERT_TRUE(view_->HasPrimarySurface());
+ EXPECT_EQ(gfx::Size(300, 300), view_->window_->layer()->size());
+ viz::SurfaceId initial_surface_id =
+ *view_->window_->layer()->GetPrimarySurfaceId();
+ EXPECT_FALSE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid());
+
+ // Resizing should update the primary SurfaceInfo.
+ aura_test_helper_->test_screen()->SetDeviceScaleFactor(2.0f);
+ viz::SurfaceId new_surface_id =
+ *view_->window_->layer()->GetPrimarySurfaceId();
+ EXPECT_NE(new_surface_id, initial_surface_id);
+ EXPECT_EQ(gfx::Size(300, 300), view_->window_->layer()->bounds().size());
}
// This test verifies that changing the CompositorFrameSink (and thus evicting
@@ -3147,7 +3178,8 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
// Swap a frame.
view_->SubmitCompositorFrame(kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, frame_size, view_rect));
+ MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
view_->RunOnCompositingDidCommit();
// Signal that a new RendererCompositorFrameSink was created.
@@ -3155,7 +3187,8 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
// Submit a frame from the new RendererCompositorFrameSink.
view_->SubmitCompositorFrame(local_surface_id_allocator_.GenerateId(),
- MakeDelegatedFrame(1.f, frame_size, view_rect));
+ MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
view_->RunOnCompositingDidCommit();
}
@@ -3310,7 +3343,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
views[i]->Show();
views[i]->SubmitCompositorFrame(
kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, frame_size, view_rect));
+ MakeDelegatedFrame(1.f, frame_size, view_rect), nullptr);
EXPECT_TRUE(views[i]->HasPrimarySurface());
views[i]->Hide();
}
@@ -3331,7 +3364,8 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
// Swap a frame on it, it should evict the next LRU [1].
views[0]->SubmitCompositorFrame(
- kArbitraryLocalSurfaceId, MakeDelegatedFrame(1.f, frame_size, view_rect));
+ kArbitraryLocalSurfaceId, MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
EXPECT_TRUE(views[0]->HasPrimarySurface());
EXPECT_FALSE(views[1]->HasPrimarySurface());
// Now that [0] got a frame, it shouldn't be waiting any more.
@@ -3341,7 +3375,8 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
// LRU renderer is [1], still hidden. Swap a frame on it, it should evict
// the next LRU [2].
views[1]->SubmitCompositorFrame(
- kArbitraryLocalSurfaceId, MakeDelegatedFrame(1.f, frame_size, view_rect));
+ kArbitraryLocalSurfaceId, MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
EXPECT_TRUE(views[0]->HasPrimarySurface());
EXPECT_TRUE(views[1]->HasPrimarySurface());
EXPECT_FALSE(views[2]->HasPrimarySurface());
@@ -3359,7 +3394,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
views[i]->released_front_lock_active());
views[i]->SubmitCompositorFrame(
kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, frame_size, view_rect));
+ MakeDelegatedFrame(1.f, frame_size, view_rect), nullptr);
// Now everyone has a frame.
EXPECT_FALSE(views[i]->released_front_lock_active());
EXPECT_TRUE(views[i]->HasPrimarySurface());
@@ -3368,7 +3403,8 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
// Swap a frame on [0], it should be evicted immediately.
views[0]->SubmitCompositorFrame(
- kArbitraryLocalSurfaceId, MakeDelegatedFrame(1.f, frame_size, view_rect));
+ kArbitraryLocalSurfaceId, MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
EXPECT_FALSE(views[0]->HasPrimarySurface());
// Make [0] visible, and swap a frame on it. Nothing should be evicted
@@ -3377,7 +3413,8 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
// We don't have a frame, wait.
EXPECT_TRUE(views[0]->released_front_lock_active());
views[0]->SubmitCompositorFrame(
- kArbitraryLocalSurfaceId, MakeDelegatedFrame(1.f, frame_size, view_rect));
+ kArbitraryLocalSurfaceId, MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
EXPECT_FALSE(views[0]->released_front_lock_active());
for (size_t i = 0; i < renderer_count; ++i)
EXPECT_TRUE(views[i]->HasPrimarySurface());
@@ -3404,7 +3441,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
views[1]->Show();
EXPECT_TRUE(views[1]->released_front_lock_active());
views[1]->SubmitCompositorFrame(
- id2, MakeDelegatedFrame(1.f, size2, gfx::Rect(size2)));
+ id2, MakeDelegatedFrame(1.f, size2, gfx::Rect(size2)), nullptr);
EXPECT_FALSE(views[1]->released_front_lock_active());
for (size_t i = 0; i < renderer_count; ++i) {
@@ -3452,7 +3489,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
views[i]->Show();
views[i]->SubmitCompositorFrame(
i ? local_surface_id_allocator_.GenerateId() : kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, frame_size, view_rect));
+ MakeDelegatedFrame(1.f, frame_size, view_rect), nullptr);
EXPECT_TRUE(views[i]->HasPrimarySurface());
}
@@ -3463,7 +3500,8 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
// If we lock [0] before hiding it, then [0] should not be evicted.
views[0]->Show();
views[0]->SubmitCompositorFrame(
- kArbitraryLocalSurfaceId, MakeDelegatedFrame(1.f, frame_size, view_rect));
+ kArbitraryLocalSurfaceId, MakeDelegatedFrame(1.f, frame_size, view_rect),
+ nullptr);
EXPECT_TRUE(views[0]->HasPrimarySurface());
views[0]->GetDelegatedFrameHost()->LockResources();
views[0]->Hide();
@@ -3525,7 +3563,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithMemoryPressure) {
views[i]->Show();
views[i]->SubmitCompositorFrame(
kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, frame_size, view_rect));
+ MakeDelegatedFrame(1.f, frame_size, view_rect), nullptr);
EXPECT_TRUE(views[i]->HasPrimarySurface());
}
@@ -3601,14 +3639,14 @@ TEST_F(RenderWidgetHostViewAuraTest, ForwardsBeginFrameAcks) {
surface_manager->AddObserver(&observer);
view_->SetNeedsBeginFrames(true);
- uint32_t source_id = 10;
+ constexpr uint64_t source_id = 10;
{
// Ack from CompositorFrame is forwarded.
viz::BeginFrameAck ack(source_id, 5, true);
viz::CompositorFrame frame = MakeDelegatedFrame(1.f, frame_size, view_rect);
frame.metadata.begin_frame_ack = ack;
- view_->SubmitCompositorFrame(local_surface_id, std::move(frame));
+ view_->SubmitCompositorFrame(local_surface_id, std::move(frame), nullptr);
view_->RunOnCompositingDidCommit();
EXPECT_EQ(ack, observer.last_ack());
}
@@ -3631,7 +3669,6 @@ class RenderWidgetHostViewAuraCopyRequestTest
: callback_count_(0),
result_(false),
frame_subscriber_(nullptr),
- tick_clock_(nullptr),
view_rect_(100, 100) {}
void CallbackMethod(bool result) {
@@ -3670,19 +3707,17 @@ class RenderWidgetHostViewAuraCopyRequestTest
}
void InstallFakeTickClock() {
- // Create a fake tick clock and transfer ownership to the frame host.
- tick_clock_ = new base::SimpleTestTickClock();
- view_->GetDelegatedFrameHost()->tick_clock_ = base::WrapUnique(tick_clock_);
+ view_->GetDelegatedFrameHost()->tick_clock_ = &tick_clock_;
}
void SubmitCompositorFrame() {
view_->SubmitCompositorFrame(
kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, view_rect_.size(), view_rect_));
+ MakeDelegatedFrame(1.f, view_rect_.size(), view_rect_), nullptr);
viz::SurfaceId surface_id =
view_->GetDelegatedFrameHost()->SurfaceIdForTesting();
if (surface_id.is_valid())
- view_->GetDelegatedFrameHost()->WillDrawSurface(
+ view_->GetDelegatedFrameHost()->OnAggregatedSurfaceDamage(
surface_id.local_surface_id(), view_rect_);
ASSERT_TRUE(view_->last_copy_request_);
}
@@ -3691,7 +3726,8 @@ class RenderWidgetHostViewAuraCopyRequestTest
std::unique_ptr<viz::CopyOutputRequest> request =
std::move(view_->last_copy_request_);
request->SendResult(std::make_unique<viz::CopyOutputTextureResult>(
- view_rect_, request->texture_mailbox(),
+ view_rect_, request->mailbox(), request->sync_token(),
+ gfx::ColorSpace(),
viz::SingleReleaseCallback::Create(
base::Bind([](const gpu::SyncToken&, bool) {}))));
RunLoopUntilCallback();
@@ -3723,7 +3759,7 @@ class RenderWidgetHostViewAuraCopyRequestTest
int callback_count_;
bool result_;
FakeFrameSubscriber* frame_subscriber_; // Owned by |view_|.
- base::SimpleTestTickClock* tick_clock_; // Owned by DelegatedFrameHost.
+ base::SimpleTestTickClock tick_clock_;
const gfx::Rect view_rect_;
private:
@@ -3788,7 +3824,7 @@ TEST_F(RenderWidgetHostViewAuraCopyRequestTest, DestroyedAfterCopyRequest) {
SubmitCompositorFrame();
EXPECT_EQ(0, callback_count_);
EXPECT_TRUE(view_->last_copy_request_);
- EXPECT_TRUE(view_->last_copy_request_->has_texture_mailbox());
+ EXPECT_TRUE(view_->last_copy_request_->has_mailbox());
// Notify DelegatedFrameHost that the copy requests were moved to the
// compositor thread by calling OnCompositingDidCommit().
@@ -3828,13 +3864,13 @@ TEST_F(RenderWidgetHostViewAuraCopyRequestTest, PresentTime) {
// Verify our initial state.
EXPECT_EQ(base::TimeTicks(), frame_subscriber_->last_present_time());
- EXPECT_EQ(base::TimeTicks(), tick_clock_->NowTicks());
+ EXPECT_EQ(base::TimeTicks(), tick_clock_.NowTicks());
// Start our fake clock from a non-zero, but not an even multiple of the
// interval, value to differentiate it from our initialization state.
const base::TimeDelta kDefaultInterval =
viz::BeginFrameArgs::DefaultInterval();
- tick_clock_->Advance(kDefaultInterval / 3);
+ tick_clock_.Advance(kDefaultInterval / 3);
// Swap the first frame without any vsync information.
ASSERT_EQ(base::TimeTicks(), vsync_timebase());
@@ -3843,7 +3879,7 @@ TEST_F(RenderWidgetHostViewAuraCopyRequestTest, PresentTime) {
// During this first call, there is no known vsync information, so while the
// callback should succeed the present time is effectively just current time.
SubmitCompositorFrameAndRelease();
- EXPECT_EQ(tick_clock_->NowTicks(), frame_subscriber_->last_present_time());
+ EXPECT_EQ(tick_clock_.NowTicks(), frame_subscriber_->last_present_time());
// Now initialize the vsync parameters with a null timebase, but a known vsync
// interval; which should give us slightly better frame time estimates.
@@ -3860,7 +3896,7 @@ TEST_F(RenderWidgetHostViewAuraCopyRequestTest, PresentTime) {
// Now initialize the vsync parameters with a valid timebase and a known vsync
// interval; which should give us the best frame time estimates.
- const base::TimeTicks kBaseTime = tick_clock_->NowTicks();
+ const base::TimeTicks kBaseTime = tick_clock_.NowTicks();
OnUpdateVSyncParameters(kBaseTime, kDefaultInterval);
ASSERT_EQ(kBaseTime, vsync_timebase());
ASSERT_EQ(kDefaultInterval, vsync_interval());
@@ -3870,7 +3906,7 @@ TEST_F(RenderWidgetHostViewAuraCopyRequestTest, PresentTime) {
// the vsync timebase. Advance time by a non integer number of intervals to
// verify.
const double kElapsedIntervals = 2.5;
- tick_clock_->Advance(kDefaultInterval * kElapsedIntervals);
+ tick_clock_.Advance(kDefaultInterval * kElapsedIntervals);
SubmitCompositorFrameAndRelease();
EXPECT_EQ(kBaseTime + kDefaultInterval * std::ceil(kElapsedIntervals),
frame_subscriber_->last_present_time());
@@ -3932,23 +3968,22 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventPositionsArentRounded) {
void RenderWidgetHostViewAuraOverscrollTest::WheelNotPreciseScrollEvent() {
SetUpOverscrollEnvironment();
- // Simulate wheel events.
+ // Simulate wheel event. Does not cross start threshold.
SimulateWheelEventPossiblyIncludingPhase(
-5, 0, 0, false, WebMouseWheelEvent::kPhaseBegan); // sent directly
+ // Simulate wheel event. Crosses start threshold.
SimulateWheelEventPossiblyIncludingPhase(
- -60, 1, 0, false, WebMouseWheelEvent::kPhaseChanged); // enqueued
+ -70, 1, 0, false, WebMouseWheelEvent::kPhaseChanged); // enqueued
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
// Receive ACK the first wheel event as not processed.
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(true, 1);
-
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(true, 1);
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
@@ -3956,21 +3991,20 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelNotPreciseScrollEvent() {
if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
ExpectGestureScrollEndForWheelScrolling(false);
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
}
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- EXPECT_EQ("MouseWheel GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
} else if (wheel_scroll_latching_enabled_) {
SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
ExpectGestureScrollEndForWheelScrolling(true);
} else {
ExpectGestureScrollEndForWheelScrolling(true);
@@ -3995,17 +4029,18 @@ TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
void RenderWidgetHostViewAuraOverscrollTest::WheelScrollEventOverscrolls() {
SetUpOverscrollEnvironment();
- // Simulate wheel events.
+ // Simulate wheel events. Do not cross start threshold.
SimulateWheelEventPossiblyIncludingPhase(
-5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
SimulateWheelEventPossiblyIncludingPhase(
- -1, 1, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
+ -10, 1, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
SimulateWheelEventPossiblyIncludingPhase(
-10, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
SimulateWheelEventPossiblyIncludingPhase(
-15, -1, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
+ // Simulate wheel events. Cross start threshold.
SimulateWheelEventPossiblyIncludingPhase(
-30, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
@@ -4014,16 +4049,14 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollEventOverscrolls() {
WebMouseWheelEvent::kPhaseChanged); // enqueued, different modifiers
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
// Receive ACK the first wheel event as not processed.
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(true, 2);
-
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(true, 2);
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
@@ -4037,34 +4070,30 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollEventOverscrolls() {
// instead of being sent to the renderer. So the result will be an
// overscroll back navigation, and no ScrollUpdate event will be sent to the
// renderer.
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 1);
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 1);
}
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ExpectGestureScrollEndForWheelScrolling(false);
-
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHPAD, overscroll_source());
EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode());
- EXPECT_EQ(-81.f, overscroll_delta_x());
- EXPECT_EQ(-31.f, overscroll_delegate()->delta_x());
+ EXPECT_EQ(-90.f, overscroll_delta_x());
+ EXPECT_EQ(-30.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ(0U, sink_->message_count());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
// Send a mouse-move event. This should cancel the overscroll navigation.
SimulateMouseMove(5, 10, 0);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ(1U, sink_->message_count());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseMove", GetMessageNames(events));
}
TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollEventOverscrolls) {
WheelScrollEventOverscrolls();
@@ -4084,17 +4113,18 @@ void RenderWidgetHostViewAuraOverscrollTest::
WheelScrollConsumedDoNotHorizOverscroll() {
SetUpOverscrollEnvironment();
- // Simulate wheel events.
+ // Simulate wheel events. Do not cross start threshold.
SimulateWheelEventPossiblyIncludingPhase(
-5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
SimulateWheelEventPossiblyIncludingPhase(
- -1, -1, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
+ -10, -1, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
SimulateWheelEventPossiblyIncludingPhase(
-10, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
SimulateWheelEventPossiblyIncludingPhase(
-15, -1, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
+ // Simulate wheel events. Cross start threshold.
SimulateWheelEventPossiblyIncludingPhase(
-30, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
@@ -4102,31 +4132,30 @@ void RenderWidgetHostViewAuraOverscrollTest::
-20, 6, 1, true,
WebMouseWheelEvent::kPhaseChanged); // enqueued, different modifiers
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
// Receive ACK the first wheel event as processed.
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(true, 2);
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(true, 2);
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_CONSUMED);
ExpectGestureScrollEndForWheelScrolling(false);
// Receive ACK for the second (coalesced) event as not processed. This
// should not initiate overscroll, since the beginning of the scroll has
// been consumed. The queued event with different modifiers should be sent
// to the renderer.
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 1);
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 1);
}
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
@@ -4134,30 +4163,27 @@ void RenderWidgetHostViewAuraOverscrollTest::
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
// The GSU events are coalesced. This is the ack for the coalesced event.
// Since it is the first GSU, the ack should be consumed.
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_CONSUMED);
} else {
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEndForWheelScrolling(false);
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = ExpectGestureScrollEndForWheelScrolling(false);
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
+ SendNotConsumedAcks(events);
}
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- EXPECT_EQ("MouseWheel GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
} else if (wheel_scroll_latching_enabled_) {
SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEndForWheelScrolling(true);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEndForWheelScrolling(true);
} else {
- ExpectGestureScrollEndForWheelScrolling(true);
+ events = ExpectGestureScrollEndForWheelScrolling(true);
}
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
@@ -4183,14 +4209,16 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() {
// initiate an overscroll gesture since it doesn't cross the threshold yet.
SimulateWheelEventPossiblyIncludingPhase(10, 0, 0, true,
WebMouseWheelEvent::kPhaseBegan);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(true, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(true, 0);
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendNotConsumedAcks(events);
+
ExpectGestureScrollEndForWheelScrolling(false);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -4201,16 +4229,14 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() {
SimulateWheelEventPossiblyIncludingPhase(10, 0, 0, true,
WebMouseWheelEvent::kPhaseChanged);
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
+ events = ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
} else {
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
}
-
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ExpectGestureScrollEndForWheelScrolling(false);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -4218,35 +4244,34 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() {
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// Scroll some more to initiate an overscroll.
- SimulateWheelEventPossiblyIncludingPhase(40, 0, 0, true,
+ SimulateWheelEventPossiblyIncludingPhase(50, 0, 0, true,
WebMouseWheelEvent::kPhaseChanged);
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
+ events = ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
} else {
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
}
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ExpectGestureScrollEndForWheelScrolling(false);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHPAD, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
- EXPECT_EQ(60.f, overscroll_delta_x());
+ EXPECT_EQ(70.f, overscroll_delta_x());
EXPECT_EQ(10.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
// Scroll in the reverse direction enough to abort the overscroll.
SimulateWheelEventPossiblyIncludingPhase(-20, 0, 0, true,
WebMouseWheelEvent::kPhaseChanged);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
}
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -4257,10 +4282,10 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() {
SimulateWheelEventPossiblyIncludingPhase(-20, 0, 0, true,
WebMouseWheelEvent::kPhaseChanged);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
}
@@ -4271,30 +4296,32 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() {
// Continue to scroll in the reverse direction enough to initiate overscroll
// in that direction. However, overscroll should not be initiated as the
// overscroll mode is locked to east mode.
- SimulateWheelEventPossiblyIncludingPhase(-55, 0, 0, true,
+ SimulateWheelEventPossiblyIncludingPhase(-65, 0, 0, true,
WebMouseWheelEvent::kPhaseChanged);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
}
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- EXPECT_EQ("MouseWheel GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
} else if (wheel_scroll_latching_enabled_) {
SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
}
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ(-95.f, overscroll_delta_x());
+ EXPECT_EQ(-105.f, overscroll_delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
}
@@ -4317,14 +4344,14 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollEventsOverscrollWithFling() {
// initiate an overscroll gesture since it doesn't cross the threshold yet.
SimulateWheelEventPossiblyIncludingPhase(10, 0, 0, true,
WebMouseWheelEvent::kPhaseBegan);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(true, 0);
-
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(true, 0);
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+
+ SendNotConsumedAcks(events);
ExpectGestureScrollEndForWheelScrolling(false);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -4337,53 +4364,54 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollEventsOverscrollWithFling() {
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
} else {
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
}
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- sink_->ClearMessages();
// Scroll some more to initiate an overscroll.
- SimulateWheelEventPossiblyIncludingPhase(30, 0, 0, true,
+ SimulateWheelEventPossiblyIncludingPhase(40, 0, 0, true,
WebMouseWheelEvent::kPhaseChanged);
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
} else {
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
}
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
ExpectGestureScrollEndForWheelScrolling(false);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHPAD, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
- EXPECT_EQ(60.f, overscroll_delta_x());
+ EXPECT_EQ(70.f, overscroll_delta_x());
EXPECT_EQ(10.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
// Send a fling start, but with a small velocity, so that the overscroll is
// aborted. The fling should proceed to the renderer, through the gesture
// event filter.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureFlingStartEvent(0.f, 0.1f, blink::kWebGestureDeviceTouchpad);
+ events = GetAndResetDispatchedMessages();
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
- EXPECT_EQ("GestureScrollBegin GestureFlingStart", GetInputMessageTypes());
+ EXPECT_EQ("GestureFlingStart", GetMessageNames(events));
}
TEST_F(RenderWidgetHostViewAuraOverscrollTest,
ScrollEventsOverscrollWithFling) {
@@ -4408,14 +4436,14 @@ void RenderWidgetHostViewAuraOverscrollTest::
// initiate an overscroll gesture since it doesn't cross the threshold yet.
SimulateWheelEventPossiblyIncludingPhase(10, 0, 0, true,
WebMouseWheelEvent::kPhaseBegan);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(true, 0);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(true, 0);
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendNotConsumedAcks(events);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ExpectGestureScrollEndForWheelScrolling(false);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -4428,14 +4456,12 @@ void RenderWidgetHostViewAuraOverscrollTest::
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
} else {
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
}
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ExpectGestureScrollEndForWheelScrolling(false);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -4443,41 +4469,44 @@ void RenderWidgetHostViewAuraOverscrollTest::
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// Scroll some more to initiate an overscroll.
- SimulateWheelEventPossiblyIncludingPhase(30, 0, 0, true,
+ SimulateWheelEventPossiblyIncludingPhase(40, 0, 0, true,
WebMouseWheelEvent::kPhaseChanged);
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
} else {
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
}
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
ExpectGestureScrollEndForWheelScrolling(false);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHPAD, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
- EXPECT_EQ(60.f, overscroll_delta_x());
+ EXPECT_EQ(70.f, overscroll_delta_x());
EXPECT_EQ(10.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
// Send a fling start, but with a small velocity, so that the overscroll is
// aborted. The fling should proceed to the renderer, through the gesture
// event filter.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureFlingStartEvent(10.f, 0.f, blink::kWebGestureDeviceTouchpad);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
- EXPECT_EQ("GestureScrollBegin GestureFlingStart", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureFlingStart", GetMessageNames(events));
}
TEST_F(RenderWidgetHostViewAuraOverscrollTest,
ScrollEventsOverscrollWithZeroFling) {
@@ -4503,20 +4532,23 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, ReverseFlingCancelsOverscroll) {
// overscroll navigation.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureScrollUpdateEvent(300, -5, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin TouchScrollStarted GestureScrollUpdate",
+ GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
- sink_->ClearMessages();
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ(1U, sink_->message_count());
}
{
@@ -4527,19 +4559,22 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, ReverseFlingCancelsOverscroll) {
overscroll_delegate()->Reset();
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureScrollUpdateEvent(-300, -5, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin TouchScrollStarted GestureScrollUpdate",
+ GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode());
- sink_->ClearMessages();
SimulateGestureFlingStartEvent(100, 0, blink::kWebGestureDeviceTouchscreen);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureFlingStart", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ(1U, sink_->message_count());
}
}
@@ -4551,17 +4586,20 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, GestureScrollOverscrolls) {
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
// Send another gesture event and ACK as not being processed. This should
// initiate the navigation gesture.
SimulateGestureScrollUpdateEvent(55, -5, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetMessageNames(events));
+ events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
@@ -4569,12 +4607,13 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, GestureScrollOverscrolls) {
EXPECT_EQ(-5.f, overscroll_delta_y());
EXPECT_EQ(5.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetInputMessageTypes());
// Send another gesture update event. This event should be consumed by the
// controller, and not be forwarded to the renderer. The gesture-event filter
// should not also receive this event.
SimulateGestureScrollUpdateEvent(10, -5, 0);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
@@ -4582,17 +4621,17 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, GestureScrollOverscrolls) {
EXPECT_EQ(-10.f, overscroll_delta_y());
EXPECT_EQ(15.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ(0U, sink_->message_count());
// Now send a scroll end. This should cancel the overscroll gesture, and send
// the event to the renderer. The gesture-event filter should receive this
// event.
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
}
// Tests that when a cap is set for overscroll delta, extra overscroll delta is
@@ -4604,16 +4643,19 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDeltaCap) {
overscroll_delegate()->set_delta_cap(50);
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
// Scroll enough to initiate the overscrolling.
SimulateGestureScrollUpdateEvent(55, -5, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetMessageNames(events));
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
@@ -4621,10 +4663,11 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDeltaCap) {
EXPECT_EQ(-5.f, overscroll_delta_y());
EXPECT_EQ(5.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetInputMessageTypes());
// Scroll beyond overscroll cap. Overscroll delta should not surpass the cap.
SimulateGestureScrollUpdateEvent(75, -5, 0);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
@@ -4632,11 +4675,12 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDeltaCap) {
EXPECT_EQ(-10.f, overscroll_delta_y());
EXPECT_EQ(50.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ(0U, sink_->message_count());
// Scroll back a bit. Since the extra scroll after cap in previous step is
// ignored, scrolling back should immediately reduce overscroll delta.
SimulateGestureScrollUpdateEvent(-10, -5, 0);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
@@ -4644,15 +4688,15 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDeltaCap) {
EXPECT_EQ(-15.f, overscroll_delta_y());
EXPECT_EQ(40.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ(0U, sink_->message_count());
// End overscrolling.
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
}
// Tests that if the page is scrolled because of a scroll-gesture, then that
@@ -4664,25 +4708,27 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureScrollUpdateEvent(10, 0, 0);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin TouchScrollStarted GestureScrollUpdate",
+ GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
// Start scrolling on content. ACK both events as being processed.
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- sink_->ClearMessages();
// Send another gesture event and ACK as not being processed. This should
// not initiate overscroll because the beginning of the scroll event did
// scroll some content on the page. Since there was no overscroll, the event
// should reach the renderer.
SimulateGestureScrollUpdateEvent(55, 0, 0);
- EXPECT_EQ("GestureScrollUpdate", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollUpdate", GetMessageNames(events));
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
}
@@ -4696,66 +4742,72 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
// Start scrolling. Receive ACK as it being processed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
// Send update events.
SimulateGestureScrollUpdateEvent(25, 0, 0);
- EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetMessageNames(events));
// Quickly end and restart the scroll gesture. These two events should get
// discarded.
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, sink_->message_count());
+ MockWidgetInputHandler::MessageVector second_scroll_update_events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, second_scroll_update_events.size());
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, sink_->message_count());
+ second_scroll_update_events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, second_scroll_update_events.size());
// Send another update event. This should be sent right away.
SimulateGestureScrollUpdateEvent(30, 0, 0);
- EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetInputMessageTypes());
+ second_scroll_update_events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate",
+ GetMessageNames(second_scroll_update_events));
// Receive an ACK for the first scroll-update event as not being processed.
// This will contribute to the overscroll gesture, but not enough for the
// overscroll controller to start consuming gesture events.
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// The second GSU was already sent.
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ MockWidgetInputHandler::MessageVector third_scroll_update_events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, third_scroll_update_events.size());
// Send another update event. This should be forwarded immediately since
// GestureEventQueue allows multiple in-flight events.
SimulateGestureScrollUpdateEvent(10, 0, 0);
- EXPECT_EQ("GestureScrollUpdate", GetInputMessageTypes());
+ third_scroll_update_events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollUpdate", GetMessageNames(third_scroll_update_events));
// Receive an ACK for the second scroll-update event as not being processed.
// This will now initiate an overscroll.
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(second_scroll_update_events);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
EXPECT_EQ(55.f, overscroll_delta_x());
EXPECT_EQ(5.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ(0U, sink_->message_count());
// Receive an ACK for the last scroll-update event as not being processed.
// This will be consumed by the overscroll controller.
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(third_scroll_update_events);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
EXPECT_EQ(65.f, overscroll_delta_x());
EXPECT_EQ(15.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ(0U, sink_->message_count());
}
// Tests that the gesture debounce timer plays nice with the overscroll
@@ -4767,21 +4819,23 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
// Start scrolling. Receive ACK as it being processed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
// Send update events.
SimulateGestureScrollUpdateEvent(55, 0, 0);
- EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetMessageNames(events));
// Send an end event. This should get in the debounce queue.
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, sink_->message_count());
+ EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
// Receive ACK for the scroll-update event.
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
@@ -4803,7 +4857,8 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
}
// Tests that when touch-events are dispatched to the renderer, the overscroll
@@ -4811,20 +4866,20 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
SetUpOverscrollEnvironmentWithDebounce(10);
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
- sink_->ClearMessages();
// The test sends an intermingled sequence of touch and gesture events.
PressTouchPoint(0, 1);
- uint32_t touch_press_event_id1 = SendTouchEvent();
- SendTouchEventACK(WebInputEvent::kTouchStart,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED, touch_press_event_id1);
- EXPECT_EQ("TouchStart", GetInputMessageTypes());
+ SendTouchEvent();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchStart", GetMessageNames(events));
+ SendNotConsumedAcks(events);
MoveTouchPoint(0, 20, 5);
- uint32_t touch_move_event_id1 = SendTouchEvent();
- SendTouchEventACK(WebInputEvent::kTouchMove,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED, touch_move_event_id1);
- EXPECT_EQ("TouchMove", GetInputMessageTypes());
+ SendTouchEvent();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchMove", GetMessageNames(events));
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
@@ -4832,12 +4887,13 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
SimulateGestureScrollUpdateEvent(20, 0, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetInputMessageTypes());
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetMessageNames(events));
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
@@ -4847,19 +4903,20 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
// not require an ack (having been marked uncancelable).
MoveTouchPoint(0, 65, 10);
SendTouchEvent();
- AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ("TouchMove", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchMove", GetMessageNames(events));
+ SendNotConsumedAcks(events);
SimulateGestureScrollUpdateEvent(45, 0, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollUpdate", GetMessageNames(events));
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
EXPECT_EQ(65.f, overscroll_delta_x());
EXPECT_EQ(15.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- EXPECT_EQ("GestureScrollUpdate", GetInputMessageTypes());
// Send another touch event. The page should get the touch-move event, even
// though overscroll has started.
@@ -4871,11 +4928,13 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
EXPECT_EQ(65.f, overscroll_delta_x());
EXPECT_EQ(15.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ("TouchMove", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchMove", GetMessageNames(events));
+ SendNotConsumedAcks(events);
SimulateGestureScrollUpdateEvent(-10, 0, 0);
- EXPECT_EQ(0U, sink_->message_count());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
@@ -4885,11 +4944,13 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
PressTouchPoint(255, 5);
SendTouchEvent();
- AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ("TouchStart", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchStart", GetMessageNames(events));
+ SendNotConsumedAcks(events);
SimulateGestureScrollUpdateEvent(200, 0, 0);
- EXPECT_EQ(0U, sink_->message_count());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
@@ -4901,12 +4962,14 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
// touch handlers.
ReleaseTouchPoint(1);
SendTouchEvent();
- AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ("TouchEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchEnd", GetMessageNames(events));
+ SendNotConsumedAcks(events);
ReleaseTouchPoint(0);
SendTouchEvent();
- AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ("TouchEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchEnd", GetMessageNames(events));
+ SendNotConsumedAcks(events);
SimulateGestureEvent(blink::WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
@@ -4914,7 +4977,8 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
base::TimeDelta::FromMilliseconds(10));
base::RunLoop().Run();
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
@@ -4927,13 +4991,14 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
TouchGestureEndDispatchedAfterOverscrollComplete) {
SetUpOverscrollEnvironmentWithDebounce(10);
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
- sink_->ClearMessages();
// Start scrolling. Receive ACK as it being processed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
// The scroll begin event will have received a synthetic ack from the input
// router.
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -4942,13 +5007,13 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
// Send update events.
SimulateGestureScrollUpdateEvent(55, -5, 0);
- EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
EXPECT_EQ(0U, sink_->message_count());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
@@ -4960,7 +5025,8 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
// Send end event.
SimulateGestureEvent(blink::WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, sink_->message_count());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
base::TimeDelta::FromMilliseconds(10));
@@ -4969,27 +5035,29 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
// Start scrolling. Receive ACK as it being processed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// Send update events.
SimulateGestureScrollUpdateEvent(235, -5, 0);
- EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, sink_->message_count());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
@@ -5000,7 +5068,8 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
// Send end event.
SimulateGestureEvent(blink::WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ(0U, sink_->message_count());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
base::TimeDelta::FromMilliseconds(10));
@@ -5009,7 +5078,8 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
}
TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDirectionChange) {
@@ -5018,32 +5088,36 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDirectionChange) {
// Start scrolling. Receive ACK as it being processed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
// Send update events and receive ack as not consumed.
SimulateGestureScrollUpdateEvent(125, -5, 0);
- EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetInputMessageTypes());
-
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetMessageNames(events));
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
- EXPECT_EQ(0U, sink_->message_count());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
// Send another update event, but in the reverse direction. Although the
// overscroll controller is not triggering gesture-nav, it will consume the
// ScrollUpdate event to prevent content scroll.
SimulateGestureScrollUpdateEvent(-260, 0, 0);
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
// Although the overscroll mode has been reset, the next scroll update events
// should be consumed by the overscroll controller to prevent content scroll.
SimulateGestureScrollUpdateEvent(-20, 0, 0);
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
}
@@ -5054,12 +5128,14 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
// Send GSU to trigger overscroll.
SimulateGestureScrollUpdateEvent(300, -5, 0);
@@ -5068,8 +5144,10 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
blink::kWebGestureDeviceTouchscreen);
// Now ACK the GSU. Should see a completed overscroll.
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate GestureScrollEnd",
+ GetMessageNames(events));
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
@@ -5082,12 +5160,15 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SimulateGestureScrollUpdateEvent(30, -5, 0);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin TouchScrollStarted GestureScrollUpdate",
+ GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
// Send the first GSU which shouldn't trigger overscroll.
- SimulateGestureScrollUpdateEvent(30, -5, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
EXPECT_EQ(0U, overscroll_delegate()->historical_modes().size());
@@ -5098,9 +5179,11 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollUpdate GestureScrollEnd", GetMessageNames(events));
+
// Now ACK the second GSU, should see overscroll being triggered and cleared.
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
EXPECT_EQ(2U, overscroll_delegate()->historical_modes().size());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->historical_modes().at(0));
@@ -5114,14 +5197,16 @@ void RenderWidgetHostViewAuraOverscrollTest::
// Send wheel event and receive ack as not consumed.
SimulateWheelEventPossiblyIncludingPhase(125, -5, 0, true,
WebMouseWheelEvent::kPhaseBegan);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(true, 0);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ // Receive ACK the first wheel event as not processed.
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ if (events.size() > 1)
+ events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(true, 0);
+ SendNotConsumedAcks(events);
ExpectGestureScrollEndForWheelScrolling(false);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
@@ -5134,10 +5219,10 @@ void RenderWidgetHostViewAuraOverscrollTest::
SimulateWheelEventPossiblyIncludingPhase(-260, 0, 0, true,
WebMouseWheelEvent::kPhaseChanged);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
}
@@ -5152,11 +5237,10 @@ void RenderWidgetHostViewAuraOverscrollTest::
SimulateWheelEventPossiblyIncludingPhase(-20, 0, 0, true,
WebMouseWheelEvent::kPhaseChanged);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
+ SendNotConsumedAcks(events);
ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
}
@@ -5181,9 +5265,9 @@ void RenderWidgetHostViewAuraOverscrollTest::OverscrollMouseMoveCompletion() {
SetUpOverscrollEnvironment();
SimulateWheelEventPossiblyIncludingPhase(
- 5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
+ -5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
SimulateWheelEventPossiblyIncludingPhase(
- -1, 0, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
+ -10, 0, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
SimulateWheelEventPossiblyIncludingPhase(
-10, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
@@ -5194,19 +5278,16 @@ void RenderWidgetHostViewAuraOverscrollTest::OverscrollMouseMoveCompletion() {
-30, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
// Receive ACK the first wheel event as not processed.
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(true, 1);
-
- // Ack the first GSU, shouldn't be able to trigger overscroll.
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(true, 1);
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
@@ -5214,15 +5295,13 @@ void RenderWidgetHostViewAuraOverscrollTest::OverscrollMouseMoveCompletion() {
if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
ExpectGestureScrollEndForWheelScrolling(false);
+ SendNotConsumedAcks(events);
// Receive ACK for the second (coalesced) event as not processed. This will
// start an overcroll gesture.
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
}
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
ExpectGestureScrollEndForWheelScrolling(false);
EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
@@ -5233,56 +5312,55 @@ void RenderWidgetHostViewAuraOverscrollTest::OverscrollMouseMoveCompletion() {
// (since the amount overscrolled is not above the threshold), and so the
// mouse-move should reach the renderer.
SimulateMouseMove(5, 10, 0);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseMove", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ("MouseMove", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseMove,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
// Moving the mouse more should continue to send the events to the renderer.
SimulateMouseMove(5, 10, 0);
- SendInputEventACK(WebInputEvent::kMouseMove,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ("MouseMove", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseMove", GetMessageNames(events));
+ SendNotConsumedAcks(events);
// Now try with gestures.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureScrollUpdateEvent(300, -5, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchScrollStarted GestureScrollUpdate", GetMessageNames(events));
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
- sink_->ClearMessages();
// Overscroll gesture is in progress. Send a mouse-move now. This should
// complete the gesture (because the amount overscrolled is above the
// threshold).
SimulateMouseMove(5, 10, 0);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseMove", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ("MouseMove", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseMove,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
+ events = GetAndResetDispatchedMessages();
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
// Move mouse some more. The mouse-move events should reach the renderer.
SimulateMouseMove(5, 10, 0);
- EXPECT_EQ("MouseMove", GetInputMessageTypes());
-
- SendInputEventACK(WebInputEvent::kMouseMove,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseMove", GetMessageNames(events));
}
TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollMouseMoveCompletion) {
OverscrollMouseMoveCompletion();
@@ -5314,51 +5392,51 @@ void RenderWidgetHostViewAuraOverscrollTest::
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
-
- // The first wheel event is consumed. Dispatches the queued wheel event.
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(true, 1);
-
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+
+ // The first wheel event is not consumed. Dispatches the queued wheel event.
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(true, 1);
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_TRUE(ScrollStateIsContentScrolling());
if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
ExpectGestureScrollEndForWheelScrolling(false);
- // The second wheel event is consumed.
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
+ // The second wheel event is not consumed.
+ SendNotConsumedAcks(events);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
+ }
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_CONSUMED);
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- EXPECT_EQ("MouseWheel GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
} else if (wheel_scroll_latching_enabled_) {
SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEndForWheelScrolling(true);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEndForWheelScrolling(true);
} else {
- ExpectGestureScrollEndForWheelScrolling(true);
+ events = ExpectGestureScrollEndForWheelScrolling(true);
}
EXPECT_TRUE(ScrollStateIsContentScrolling());
+ SendNotConsumedAcks(events);
// Touchpad scroll can end with a zero-velocity fling which is not dispatched,
// but it should still reset the overscroll controller state.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureFlingStartEvent(0.f, 0.f, blink::kWebGestureDeviceTouchpad);
EXPECT_TRUE(ScrollStateIsUnknown());
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
// Dropped flings should neither propagate *nor* indicate that they were
// consumed and have triggered a fling animation (as tracked by the router).
@@ -5366,7 +5444,8 @@ void RenderWidgetHostViewAuraOverscrollTest::
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
SimulateWheelEventPossiblyIncludingPhase(
-5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
@@ -5377,41 +5456,37 @@ void RenderWidgetHostViewAuraOverscrollTest::
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
EXPECT_TRUE(ScrollStateIsUnknown());
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
// The first wheel scroll did not scroll content. Overscroll should not start
// yet, since enough hasn't been scrolled.
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(true, 1);
SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(true, 1);
-
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_TRUE(ScrollStateIsUnknown());
if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- ExpectGestureScrollEndForWheelScrolling(false);
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
+ events = ExpectGestureScrollEndForWheelScrolling(false);
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
}
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- EXPECT_EQ("MouseWheel GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
} else if (wheel_scroll_latching_enabled_) {
SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- EXPECT_EQ("MouseWheel", GetInputMessageTypes());
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ExpectGestureScrollEndForWheelScrolling(true);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = ExpectGestureScrollEndForWheelScrolling(true);
} else {
- ExpectGestureScrollEndForWheelScrolling(true);
+ events = ExpectGestureScrollEndForWheelScrolling(true);
}
EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHPAD, overscroll_source());
@@ -5421,13 +5496,18 @@ void RenderWidgetHostViewAuraOverscrollTest::
EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode());
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin", GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureFlingStartEvent(0.f, 0.f, blink::kWebGestureDeviceTouchpad);
+ SendNotConsumedAcks(events);
+ events = GetAndResetDispatchedMessages();
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_TRUE(ScrollStateIsUnknown());
- EXPECT_EQ("GestureScrollBegin", GetInputMessageTypes());
EXPECT_FALSE(parent_host_->input_router()->HasPendingEvents());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0u, events.size());
}
TEST_F(RenderWidgetHostViewAuraOverscrollTest,
OverscrollStateResetsAfterScroll) {
@@ -5449,15 +5529,16 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollResetsOnBlur) {
// the host.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureScrollUpdateEvent(300, -5, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin TouchScrollStarted GestureScrollUpdate",
+ GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
- EXPECT_EQ("GestureScrollBegin TouchScrollStarted GestureScrollUpdate",
- GetInputMessageTypes());
view_->OnWindowFocused(nullptr, view_->GetNativeView());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -5466,20 +5547,23 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollResetsOnBlur) {
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
EXPECT_EQ(0.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
- sink_->ClearMessages();
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
- EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes());
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("SetFocus GestureScrollEnd", GetMessageNames(events));
// Start a scroll gesture again. This should correctly start the overscroll
// after the threshold.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureScrollUpdateEvent(300, -5, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureScrollBegin TouchScrollStarted GestureScrollUpdate",
+ GetMessageNames(events));
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHSCREEN, overscroll_source());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode());
@@ -5487,12 +5571,10 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollResetsOnBlur) {
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
+ events = GetAndResetDispatchedMessages();
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
- EXPECT_EQ(
- "GestureScrollBegin TouchScrollStarted GestureScrollUpdate "
- "GestureScrollEnd",
- GetInputMessageTypes());
+ EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
}
#if defined(OS_CHROMEOS)
@@ -5554,7 +5636,6 @@ TEST_F(RenderWidgetHostViewAuraTest,
InvalidEventsHaveSyncHandlingDisabled) {
view_->InitAsChild(nullptr);
view_->Show();
- GetSentMessageCountAndResetSink();
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
@@ -5569,14 +5650,19 @@ TEST_F(RenderWidgetHostViewAuraTest,
// Valid press is handled asynchronously.
view_->OnTouchEvent(&press);
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(press.synchronous_handling_disabled());
- EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
- AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ(1U, events.size());
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Invalid move is handled synchronously, but is consumed. It should not
// be forwarded to the renderer.
view_->OnTouchEvent(&invalid_move);
- EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
EXPECT_FALSE(invalid_move.synchronous_handling_disabled());
EXPECT_TRUE(invalid_move.stopped_propagation());
}
@@ -5625,43 +5711,45 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) {
ui::MouseWheelEvent event(gfx::Vector2d(1, 1), gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), ui::EF_CONTROL_DOWN, 0);
view_->OnMouseEvent(&event);
+ base::RunLoop().RunUntilIdle();
- const WebInputEvent* input_event =
- GetInputEventFromMessage(*sink_->GetMessageAt(0));
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
const WebMouseWheelEvent* wheel_event =
- static_cast<const WebMouseWheelEvent*>(input_event);
+ static_cast<const WebMouseWheelEvent*>(
+ 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));
- sink_->ClearMessages();
// Ack'ing the outstanding event should flush the pending event queue.
- SendInputEventACK(blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Simulates the mouse wheel event with no modifier applied.
event = ui::MouseWheelEvent(gfx::Vector2d(1, 1), gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), ui::EF_NONE, 0);
view_->OnMouseEvent(&event);
+ base::RunLoop().RunUntilIdle();
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0));
- wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+ events = GetAndResetDispatchedMessages();
+ wheel_event = static_cast<const WebMouseWheelEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
// Check if scroll is caused when no modifier is applied to the
// mouse wheel event.
EXPECT_TRUE(WebInputEventTraits::CanCauseScroll(*wheel_event));
- sink_->ClearMessages();
- SendInputEventACK(blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_CONSUMED);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Simulates the scroll event with ctrl modifier applied.
ui::ScrollEvent scroll(ui::ET_SCROLL, gfx::Point(2, 2), ui::EventTimeForNow(),
ui::EF_CONTROL_DOWN, 0, 5, 0, 5, 2);
view_->OnScrollEvent(&scroll);
+ base::RunLoop().RunUntilIdle();
- input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0));
- wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+ events = GetAndResetDispatchedMessages();
+ wheel_event = static_cast<const WebMouseWheelEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
// Check if scroll is caused when ctrl-touchpad-scroll is generated
// from scroll event.
EXPECT_TRUE(WebInputEventTraits::CanCauseScroll(*wheel_event));
@@ -5679,15 +5767,20 @@ TEST_F(RenderWidgetHostViewAuraTest, CorrectNumberOfAcksAreDispatched) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
view_->OnTouchEvent(&press1);
- SendTouchEventACK(blink::WebInputEvent::kTouchStart,
- INPUT_EVENT_ACK_STATE_CONSUMED, press1.unique_event_id());
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("SetFocus TouchStart", GetMessageNames(events));
+ events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
ui::TouchEvent press2(
ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), ui::EventTimeForNow(),
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
view_->OnTouchEvent(&press2);
- SendTouchEventACK(blink::WebInputEvent::kTouchStart,
- INPUT_EVENT_ACK_STATE_CONSUMED, press2.unique_event_id());
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(1u, events.size());
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(2U, view_->dispatcher_->GetAndResetProcessedTouchEventCount());
}
@@ -5700,11 +5793,13 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollDeltasResetOnEnd() {
// Wheel event scroll ending with mouse move.
SimulateWheelEventPossiblyIncludingPhase(
-30, -10, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = GetAndResetDispatchedMessages();
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(-30.f, overscroll_delta_x());
@@ -5717,16 +5812,16 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollDeltasResetOnEnd() {
// device.
SimulateWheelEventPossiblyIncludingPhase(0, 0, 0, true,
WebMouseWheelEvent::kPhaseEnded);
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ SendNotConsumedAcks(events);
// Scroll gesture.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateGestureScrollUpdateEvent(-30, -5, 0);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(-30.f, overscroll_delta_x());
@@ -5735,25 +5830,33 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollDeltasResetOnEnd() {
blink::kWebGestureDeviceTouchscreen);
EXPECT_EQ(0.f, overscroll_delta_x());
EXPECT_EQ(0.f, overscroll_delta_y());
+ events = GetAndResetDispatchedMessages();
+ SendNotConsumedAcks(events);
// Wheel event scroll ending with a fling. This is the first wheel event after
// touchscreen scrolling ends so it will have phase = kPhaseBegan.
SimulateWheelEventPossiblyIncludingPhase(5, 0, 0, true,
WebMouseWheelEvent::kPhaseBegan);
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ // ACK the MouseWheel event
+ events = GetAndResetDispatchedMessages();
+ SendNotConsumedAcks(events);
+
+ events = GetAndResetDispatchedMessages();
+ SendScrollBeginAckIfNeeded(events, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
SimulateWheelEventPossiblyIncludingPhase(10, -5, 0, true,
WebMouseWheelEvent::kPhaseChanged);
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendInputEventACK(WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
+ } else {
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ SendNotConsumedAcks(events);
+ events = GetAndResetDispatchedMessages();
}
- SendInputEventACK(WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(15.f, overscroll_delta_x());
@@ -5827,24 +5930,56 @@ TEST_F(RenderWidgetHostViewAuraTest, GestureTapFromStylusHasPointerType) {
ui::test::EventGenerator generator(root, root->bounds().CenterPoint());
// Simulate touch press and release to generate a GestureTap.
- sink_->ClearMessages();
generator.EnterPenPointerMode();
generator.PressTouch();
- AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
generator.ReleaseTouch();
- AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("SetFocus TouchStart TouchEnd", GetMessageNames(events));
+ SendNotConsumedAcks(events);
// GestureTap event should have correct pointer type.
- EXPECT_EQ(5U, sink_->message_count());
- const WebInputEvent* input_event = GetInputEventFromMessage(
- *sink_->GetMessageAt(sink_->message_count() - 1));
- EXPECT_EQ(WebInputEvent::kGestureTap, input_event->GetType());
- const WebGestureEvent* geture_event =
- static_cast<const WebGestureEvent*>(input_event);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("GestureTapDown GestureShowPress GestureTap",
+ GetMessageNames(events));
+ const WebGestureEvent* gesture_event = static_cast<const WebGestureEvent*>(
+ events[2]->ToEvent()->Event()->web_event.get());
+ EXPECT_EQ(WebInputEvent::kGestureTap, gesture_event->GetType());
EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
- geture_event->primary_pointer_type);
+ gesture_event->primary_pointer_type);
+}
- sink_->ClearMessages();
+// Verify that a hit test region list that was provided to the view in a
+// SubmitCompositorFrame becomes the active hit test region in the
+// viz::HitTestManager.
+TEST_F(RenderWidgetHostViewAuraTest, HitTestRegionListSubmitted) {
+ gfx::Rect view_rect(0, 0, 100, 100);
+ gfx::Size frame_size = view_rect.size();
+
+ view_->InitAsChild(nullptr);
+ aura::client::ParentWindowWithContext(
+ view_->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(),
+ gfx::Rect());
+ view_->SetSize(view_rect.size());
+
+ viz::SurfaceId surface_id(view_->GetFrameSinkId(), kArbitraryLocalSurfaceId);
+
+ auto hit_test_region_list = viz::mojom::HitTestRegionList::New();
+ hit_test_region_list->flags = viz::mojom::kHitTestMine;
+ hit_test_region_list->bounds.SetRect(0, 0, 100, 100);
+ view_->SubmitCompositorFrame(kArbitraryLocalSurfaceId,
+ MakeDelegatedFrame(1.f, frame_size, view_rect),
+ std::move(hit_test_region_list));
+
+ const viz::mojom::HitTestRegionList* active_hit_test_region_list =
+ view_->GetDelegatedFrameHost()
+ ->GetCompositorFrameSinkSupportForTesting()
+ ->frame_sink_manager()
+ ->hit_test_manager()
+ ->GetActiveHitTestRegionList(surface_id);
+ EXPECT_EQ(active_hit_test_region_list->flags, viz::mojom::kHitTestMine);
+ EXPECT_EQ(active_hit_test_region_list->bounds, view_rect);
}
// This class provides functionality to test a RenderWidgetHostViewAura
@@ -5866,7 +6001,8 @@ class RenderWidgetHostViewAuraWithViewHarnessTest
// This instance is destroyed in the TearDown method below.
view_ = new RenderWidgetHostViewAura(
contents()->GetRenderViewHost()->GetWidget(), false,
- false /* enable_surface_synchronization */);
+ false /* enable_surface_synchronization */,
+ false /* is_mus_browser_plugin_guest */);
}
void TearDown() override {
@@ -6013,13 +6149,22 @@ class InputMethodAuraTestBase : public RenderWidgetHostViewAuraTest {
RenderWidgetHostViewAuraTest::SetUp();
InitializeAura();
- view_for_first_process_ = CreateViewForProcess(tab_process());
+ widget_host_for_first_process_ =
+ CreateRenderWidgetHostForProcess(tab_process());
+ view_for_first_process_ =
+ CreateViewForProcess(widget_host_for_first_process_);
second_process_host_ = CreateNewProcessHost();
- view_for_second_process_ = CreateViewForProcess(second_process_host_);
+ widget_host_for_second_process_ =
+ CreateRenderWidgetHostForProcess(second_process_host_);
+ view_for_second_process_ =
+ CreateViewForProcess(widget_host_for_second_process_);
third_process_host_ = CreateNewProcessHost();
- view_for_third_process_ = CreateViewForProcess(third_process_host_);
+ widget_host_for_third_process_ =
+ CreateRenderWidgetHostForProcess(third_process_host_);
+ view_for_third_process_ =
+ CreateViewForProcess(widget_host_for_third_process_);
views_.insert(views_.begin(),
{tab_view(), view_for_first_process_,
@@ -6027,25 +6172,23 @@ class InputMethodAuraTestBase : public RenderWidgetHostViewAuraTest {
processes_.insert(processes_.begin(),
{tab_process(), tab_process(), second_process_host_,
third_process_host_});
+ widget_hosts_.insert(
+ widget_hosts_.begin(),
+ {tab_widget_host(), widget_host_for_first_process_,
+ widget_host_for_second_process_, widget_host_for_third_process_});
active_view_sequence_.insert(active_view_sequence_.begin(),
{0, 1, 2, 1, 1, 3, 0, 3, 1});
}
void TearDown() override {
- RenderWidgetHost* widget_for_first_process =
- view_for_first_process_->GetRenderWidgetHost();
view_for_first_process_->Destroy();
- delete widget_for_first_process;
+ delete widget_host_for_first_process_;
- RenderWidgetHost* widget_for_second_process =
- view_for_second_process_->GetRenderWidgetHost();
view_for_second_process_->Destroy();
- delete widget_for_second_process;
+ delete widget_host_for_second_process_;
- RenderWidgetHost* widget_for_third_process =
- view_for_third_process_->GetRenderWidgetHost();
view_for_third_process_->Destroy();
- delete widget_for_third_process;
+ delete widget_host_for_third_process_;
RenderWidgetHostViewAuraTest::TearDown();
}
@@ -6071,8 +6214,7 @@ class InputMethodAuraTestBase : public RenderWidgetHostViewAuraTest {
}
TestRenderWidgetHostView* CreateViewForProcess(
- MockRenderProcessHost* process_host) {
- RenderWidgetHostImpl* host = CreateRenderWidgetHostForProcess(process_host);
+ MockRenderWidgetHostImpl* host) {
TestRenderWidgetHostView* view = new TestRenderWidgetHostView(host);
host->SetView(view);
return view;
@@ -6089,8 +6231,11 @@ class InputMethodAuraTestBase : public RenderWidgetHostViewAuraTest {
RenderWidgetHostViewAura* tab_view() const { return view_; }
+ MockRenderWidgetHostImpl* tab_widget_host() const { return widget_host_; }
+
std::vector<RenderWidgetHostViewBase*> views_;
std::vector<MockRenderProcessHost*> processes_;
+ std::vector<MockRenderWidgetHostImpl*> widget_hosts_;
// A sequence of indices in [0, 3] which determines the index of a RWHV in
// |views_|. This sequence is used in the tests to sequentially make a RWHV
// active for a subsequent IME result method call.
@@ -6104,10 +6249,13 @@ class InputMethodAuraTestBase : public RenderWidgetHostViewAuraTest {
view_->Show();
}
+ MockRenderWidgetHostImpl* widget_host_for_first_process_;
TestRenderWidgetHostView* view_for_first_process_;
MockRenderProcessHost* second_process_host_;
+ MockRenderWidgetHostImpl* widget_host_for_second_process_;
TestRenderWidgetHostView* view_for_second_process_;
MockRenderProcessHost* third_process_host_;
+ MockRenderWidgetHostImpl* widget_host_for_third_process_;
TestRenderWidgetHostView* view_for_third_process_;
DISALLOW_COPY_AND_ASSIGN(InputMethodAuraTestBase);
@@ -6145,8 +6293,12 @@ TEST_F(InputMethodResultAuraTest, SetCompositionText) {
base::Unretained(text_input_client()), ui::CompositionText());
for (auto index : active_view_sequence_) {
ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT);
- EXPECT_TRUE(!!RunAndReturnIPCSent(ime_call, processes_[index],
- InputMsg_ImeSetComposition::ID));
+ ime_call.Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("SetComposition",
+ GetMessageNames(widget_hosts_[index]
+ ->input_handler()
+ ->GetAndResetDispatchedMessages()));
}
}
@@ -6158,8 +6310,12 @@ TEST_F(InputMethodResultAuraTest, ConfirmCompositionText) {
for (auto index : active_view_sequence_) {
ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT);
SetHasCompositionTextToTrue();
- EXPECT_TRUE(!!RunAndReturnIPCSent(ime_call, processes_[index],
- InputMsg_ImeFinishComposingText::ID));
+ ime_call.Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("SetComposition FinishComposingText",
+ GetMessageNames(widget_hosts_[index]
+ ->input_handler()
+ ->GetAndResetDispatchedMessages()));
}
}
@@ -6171,8 +6327,12 @@ TEST_F(InputMethodResultAuraTest, ClearCompositionText) {
for (auto index : active_view_sequence_) {
ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT);
SetHasCompositionTextToTrue();
- EXPECT_TRUE(!!RunAndReturnIPCSent(ime_call, processes_[index],
- InputMsg_ImeSetComposition::ID));
+ ime_call.Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("SetComposition SetComposition",
+ GetMessageNames(widget_hosts_[index]
+ ->input_handler()
+ ->GetAndResetDispatchedMessages()));
}
}
@@ -6184,8 +6344,12 @@ TEST_F(InputMethodResultAuraTest, FinishComposingText) {
for (auto index : active_view_sequence_) {
ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT);
SetHasCompositionTextToTrue();
- EXPECT_TRUE(!!RunAndReturnIPCSent(ime_call, processes_[index],
- InputMsg_ImeFinishComposingText::ID));
+ ime_call.Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("SetComposition FinishComposingText",
+ GetMessageNames(widget_hosts_[index]
+ ->input_handler()
+ ->GetAndResetDispatchedMessages()));
}
}
@@ -6196,8 +6360,12 @@ TEST_F(InputMethodResultAuraTest, CommitText) {
base::UTF8ToUTF16("hello"));
for (auto index : active_view_sequence_) {
ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT);
- EXPECT_TRUE(!!RunAndReturnIPCSent(ime_call, processes_[index],
- InputMsg_ImeCommitText::ID));
+ ime_call.Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("CommitText",
+ GetMessageNames(widget_hosts_[index]
+ ->input_handler()
+ ->GetAndResetDispatchedMessages()));
}
}
@@ -6210,9 +6378,12 @@ TEST_F(InputMethodResultAuraTest, FinishImeCompositionSession) {
for (auto index : active_view_sequence_) {
ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT);
SetHasCompositionTextToTrue();
- EXPECT_TRUE(!!RunAndReturnIPCSent(ime_finish_session_call,
- processes_[index],
- InputMsg_ImeFinishComposingText::ID));
+ ime_finish_session_call.Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ("SetComposition FinishComposingText",
+ GetMessageNames(widget_hosts_[index]
+ ->input_handler()
+ ->GetAndResetDispatchedMessages()));
}
}
@@ -6412,4 +6583,17 @@ TEST_F(InputMethodStateAuraTest, ImeCancelCompositionForAllViews) {
}
}
+// This test verifies that when the focused node is changed,
+// RenderWidgetHostViewAura will tell InputMethodAuraLinux to cancel the current
+// composition.
+TEST_F(InputMethodStateAuraTest, ImeFocusedNodeChanged) {
+ ActivateViewForTextInputManager(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
+ // There is no composition in the beginning.
+ EXPECT_FALSE(has_composition_text());
+ SetHasCompositionTextToTrue();
+ tab_view()->FocusedNodeChanged(true, gfx::Rect());
+ // The composition must have been canceled.
+ EXPECT_FALSE(has_composition_text());
+}
+
} // namespace content
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 964578b4d17..34248e7b2ef 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
@@ -23,6 +23,7 @@
#include "ui/base/layout.h"
#include "ui/base/ui_base_types.h"
#include "ui/display/screen.h"
+#include "ui/events/event.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/size_f.h"
@@ -121,6 +122,13 @@ float RenderWidgetHostViewBase::GetBottomControlsHeight() const {
return 0.f;
}
+int RenderWidgetHostViewBase::GetMouseWheelMinimumGranularity() const {
+ // Most platforms can specify the floating-point delta in the wheel event so
+ // they don't have a minimum granularity. Android is currently the only
+ // platform that overrides this.
+ return 0;
+}
+
void RenderWidgetHostViewBase::SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) {
@@ -134,7 +142,7 @@ gfx::Size RenderWidgetHostViewBase::GetRequestedRendererSize() const {
ui::TextInputClient* RenderWidgetHostViewBase::GetTextInputClient() {
NOTREACHED();
- return NULL;
+ return nullptr;
}
void RenderWidgetHostViewBase::SetIsInVR(bool is_in_vr) {
@@ -210,11 +218,11 @@ BrowserAccessibilityManager*
RenderWidgetHostViewBase::CreateBrowserAccessibilityManager(
BrowserAccessibilityDelegate* delegate, bool for_root_frame) {
NOTREACHED();
- return NULL;
+ return nullptr;
}
void RenderWidgetHostViewBase::AccessibilityShowMenu(const gfx::Point& point) {
- RenderWidgetHostImpl* impl = NULL;
+ RenderWidgetHostImpl* impl = nullptr;
if (GetRenderWidgetHost())
impl = RenderWidgetHostImpl::From(GetRenderWidgetHost());
@@ -234,11 +242,11 @@ gfx::AcceleratedWidget
gfx::NativeViewAccessible
RenderWidgetHostViewBase::AccessibilityGetNativeViewAccessible() {
- return NULL;
+ return nullptr;
}
void RenderWidgetHostViewBase::UpdateScreenInfo(gfx::NativeView view) {
- RenderWidgetHostImpl* impl = NULL;
+ RenderWidgetHostImpl* impl = nullptr;
if (GetRenderWidgetHost())
impl = RenderWidgetHostImpl::From(GetRenderWidgetHost());
@@ -273,6 +281,13 @@ void RenderWidgetHostViewBase::DidUnregisterFromTextInputManager(
text_input_manager_ = nullptr;
}
+void RenderWidgetHostViewBase::ResizeDueToAutoResize(const gfx::Size& new_size,
+ uint64_t sequence_number) {
+ RenderWidgetHostImpl* host =
+ RenderWidgetHostImpl::From(GetRenderWidgetHost());
+ host->DidAllocateLocalSurfaceIdForAutoResize(sequence_number);
+}
+
base::WeakPtr<RenderWidgetHostViewBase> RenderWidgetHostViewBase::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
@@ -301,6 +316,16 @@ void RenderWidgetHostViewBase::FocusedNodeTouched(
DVLOG(1) << "FocusedNodeTouched: " << editable;
}
+void RenderWidgetHostViewBase::GetScreenInfo(ScreenInfo* screen_info) {
+ RenderWidgetHostImpl* host =
+ RenderWidgetHostImpl::From(GetRenderWidgetHost());
+ if (!host || !host->delegate()) {
+ *screen_info = ScreenInfo();
+ return;
+ }
+ host->delegate()->GetScreenInfo(screen_info);
+}
+
uint32_t RenderWidgetHostViewBase::RendererFrameNumber() {
return renderer_frame_number_;
}
@@ -393,6 +418,14 @@ ScreenOrientationValues RenderWidgetHostViewBase::GetOrientationTypeForDesktop(
void RenderWidgetHostViewBase::OnDidNavigateMainFrameToNewPage() {
}
+void RenderWidgetHostViewBase::OnFrameTokenChangedForView(
+ uint32_t frame_token) {
+ RenderWidgetHostImpl* host =
+ RenderWidgetHostImpl::From(GetRenderWidgetHost());
+ if (host)
+ host->DidProcessFrame(frame_token);
+}
+
viz::FrameSinkId RenderWidgetHostViewBase::GetFrameSinkId() {
return viz::FrameSinkId();
}
@@ -403,35 +436,34 @@ viz::LocalSurfaceId RenderWidgetHostViewBase::GetLocalSurfaceId() const {
viz::FrameSinkId RenderWidgetHostViewBase::FrameSinkIdAtPoint(
viz::SurfaceHittestDelegate* delegate,
- const gfx::Point& point,
- gfx::Point* transformed_point) {
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point) {
NOTREACHED();
return viz::FrameSinkId();
}
-gfx::Point RenderWidgetHostViewBase::TransformPointToRootCoordSpace(
- const gfx::Point& point) {
+gfx::PointF RenderWidgetHostViewBase::TransformPointToRootCoordSpaceF(
+ const gfx::PointF& point) {
return point;
}
-gfx::PointF RenderWidgetHostViewBase::TransformPointToRootCoordSpaceF(
+gfx::PointF RenderWidgetHostViewBase::TransformRootPointToViewCoordSpace(
const gfx::PointF& point) {
- return gfx::PointF(TransformPointToRootCoordSpace(
- gfx::ToRoundedPoint(point)));
+ return point;
}
bool RenderWidgetHostViewBase::TransformPointToLocalCoordSpace(
- const gfx::Point& point,
+ const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
*transformed_point = point;
return true;
}
bool RenderWidgetHostViewBase::TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
NOTREACHED();
return true;
}
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 1764ea8c31c..aac5858b18d 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
@@ -22,11 +22,12 @@
#include "components/viz/common/surfaces/surface_id.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
#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 "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/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationType.h"
#include "third_party/WebKit/public/web/WebPopupType.h"
#include "third_party/WebKit/public/web/WebTextDirection.h"
@@ -128,14 +129,16 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
void EndFrameSubscription() override;
void FocusedNodeTouched(const gfx::Point& location_dips_screen,
bool editable) override;
+ void GetScreenInfo(ScreenInfo* screen_info) override;
TouchSelectionControllerClientManager*
GetTouchSelectionControllerClientManager() override;
// This only needs to be overridden by RenderWidgetHostViewBase subclasses
// that handle content embedded within other RenderWidgetHostViews.
- gfx::Point TransformPointToRootCoordSpace(const gfx::Point& point) override;
gfx::PointF TransformPointToRootCoordSpaceF(
const gfx::PointF& point) override;
+ gfx::PointF TransformRootPointToViewCoordSpace(
+ const gfx::PointF& point) override;
// IPC::Listener implementation:
bool OnMessageReceived(const IPC::Message& msg) override;
@@ -153,7 +156,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
void DidReceiveRendererFrame();
// Notification that a resize or move session ended on the native widget.
- void UpdateScreenInfo(gfx::NativeView view);
+ virtual void UpdateScreenInfo(gfx::NativeView view);
// Tells if the display property (work area/scale factor) has
// changed since the last time.
@@ -165,6 +168,11 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
// to nullptr.
void DidUnregisterFromTextInputManager(TextInputManager* text_input_manager);
+ // Informs the view that the renderer has resized to |new_size| because auto-
+ // resize is enabled.
+ virtual void ResizeDueToAutoResize(const gfx::Size& new_size,
+ uint64_t sequence_number);
+
base::WeakPtr<RenderWidgetHostViewBase> GetWeakPtr();
//----------------------------------------------------------------------------
@@ -192,6 +200,11 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
// The height of the bottom bar.
virtual float GetBottomControlsHeight() const;
+ // If mouse wheels can only specify the number of ticks of some static
+ // multiplier constant, this method returns that constant (in DIPs). If mouse
+ // wheels can specify an arbitrary delta this returns 0.
+ virtual int GetMouseWheelMinimumGranularity() const;
+
// Called prior to forwarding input event messages to the renderer, giving
// the view a chance to perform in-process event filtering or processing.
// Return values of |NOT_CONSUMED| or |UNKNOWN| will result in |input_event|
@@ -241,9 +254,16 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
viz::mojom::CompositorFrameSinkClient*
renderer_compositor_frame_sink) = 0;
+ // This is called by the RenderWidgetHostImpl to provide a new compositor
+ // frame that was received from the renderer process. if Viz service hit
+ // testing is enabled then a HitTestRegionList provides hit test data
+ // that is used for routing input events.
+ // TODO(kenrb): When Viz service is enabled on all platforms,
+ // |hit_test_region_list| should stop being an optional argument.
virtual void SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) = 0;
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) = 0;
virtual void OnDidNotProduceFrame(const viz::BeginFrameAck& ack) {}
@@ -279,8 +299,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
// been identified by hit testing mouse, touch or gesture events).
virtual viz::FrameSinkId FrameSinkIdAtPoint(
viz::SurfaceHittestDelegate* delegate,
- const gfx::Point& point,
- gfx::Point* transformed_point);
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point);
virtual void ProcessKeyboardEvent(const NativeWebKeyboardEvent& event,
const ui::LatencyInfo& latency) {}
virtual void ProcessMouseEvent(const blink::WebMouseEvent& event,
@@ -304,16 +324,16 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
// between sibling surfaces, the point must be transformed to the root's
// coordinate space as an intermediate step.
virtual bool TransformPointToLocalCoordSpace(
- const gfx::Point& point,
+ const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point);
+ gfx::PointF* transformed_point);
// Transform a point that is in the coordinate space for the current
// RenderWidgetHostView to the coordinate space of the target_view.
virtual bool TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point);
+ gfx::PointF* transformed_point);
// TODO(kenrb, wjmaclean): This is a temporary subclass identifier for
// RenderWidgetHostViewGuests that is needed for special treatment during
@@ -432,6 +452,9 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
// changes.
virtual void SetShowingContextMenu(bool showing) {}
+ // Process swap messages sent before |frame_token| in RenderWidgetHostImpl.
+ void OnFrameTokenChangedForView(uint32_t frame_token);
+
// Add and remove observers for lifetime event notifications. The order in
// which notifications are sent to observers is undefined. Clients must be
// sure to remove the observer before they go away.
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index bfc63fc0661..7e978f05363 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -17,7 +17,6 @@
#include "build/build_config.h"
#include "cc/paint/skia_paint_canvas.h"
#include "content/browser/gpu/compositor_util.h"
-#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
@@ -37,7 +36,7 @@
#include "content/shell/browser/shell.h"
#include "content/test/did_commit_provisional_load_interceptor.h"
#include "media/base/video_frame.h"
-#include "media/renderers/skcanvas_video_renderer.h"
+#include "media/renderers/paint_canvas_video_renderer.h"
#include "net/base/filename_util.h"
#include "net/dns/mock_host_resolver.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -158,7 +157,7 @@ class RenderWidgetHostViewBrowserTest : public ContentBrowserTest {
// Copy one frame using the CopyFromSurface API.
void RunBasicCopyFromSurfaceTest() {
- SET_UP_SURFACE_OR_PASS_TEST(NULL);
+ SET_UP_SURFACE_OR_PASS_TEST(nullptr);
// Repeatedly call CopyFromBackingStore() since, on some platforms (e.g.,
// Windows), the operation will fail until the first "present" has been
@@ -274,7 +273,10 @@ IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTestBase,
EXPECT_TRUE(WaitForLoadStop(web_contents));
EXPECT_EQ(web_contents->GetMainFrame()->GetProcess(),
new_web_contents->GetMainFrame()->GetProcess());
- FrameWatcher(web_contents).WaitFrames(5);
+ MainThreadFrameObserver observer(
+ web_contents->GetRenderViewHost()->GetWidget());
+ for (int i = 0; i < 5; ++i)
+ observer.Wait();
}
enum CompositingMode {
@@ -303,7 +305,7 @@ class CompositingRenderWidgetHostViewBrowserTest
bool SetUpSourceSurface(const char* wait_message) override {
content::DOMMessageQueue message_queue;
NavigateToURL(shell(), TestUrl());
- if (wait_message != NULL) {
+ if (wait_message != nullptr) {
std::string result(wait_message);
if (!message_queue.WaitForMessage(&result)) {
EXPECT_TRUE(false) << "WaitForMessage " << result << " failed.";
@@ -369,7 +371,7 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
// when the RenderWidgetHostView is deleting in the middle of an async copy.
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
CopyFromSurface_CallbackDespiteDelete) {
- SET_UP_SURFACE_OR_PASS_TEST(NULL);
+ SET_UP_SURFACE_OR_PASS_TEST(nullptr);
base::RunLoop run_loop;
GetRenderWidgetHostView()->CopyFromSurface(
@@ -387,7 +389,7 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
// async copy.
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
CopyFromSurfaceToVideoFrame_CallbackDespiteDelete) {
- SET_UP_SURFACE_OR_PASS_TEST(NULL);
+ SET_UP_SURFACE_OR_PASS_TEST(nullptr);
base::RunLoop run_loop;
scoped_refptr<media::VideoFrame> dest =
@@ -406,7 +408,7 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
// until at least one DeliverFrameCallback has been invoked.
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
FrameSubscriberTest) {
- SET_UP_SURFACE_OR_PASS_TEST(NULL);
+ SET_UP_SURFACE_OR_PASS_TEST(nullptr);
RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
base::RunLoop run_loop;
@@ -424,7 +426,7 @@ IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
}
IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest, CopyTwice) {
- SET_UP_SURFACE_OR_PASS_TEST(NULL);
+ SET_UP_SURFACE_OR_PASS_TEST(nullptr);
RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
base::RunLoop run_loop;
@@ -565,7 +567,7 @@ class CompositingRenderWidgetHostViewBrowserTestTabCapture
return;
}
- media::SkCanvasVideoRenderer video_renderer;
+ media::PaintCanvasVideoRenderer video_renderer;
SkBitmap bitmap;
bitmap.allocN32Pixels(video_frame->visible_rect().width(),
@@ -677,14 +679,11 @@ class CompositingRenderWidgetHostViewBrowserTestTabCapture
run_loop.QuitClosure());
rwhv->CopyFromSurfaceToVideoFrame(copy_rect, video_frame, callback);
} else {
- if (!content::GpuDataManager::GetInstance()
- ->CanUseGpuBrowserCompositor()) {
- // Skia rendering can cause color differences, particularly in the
- // middle two columns.
- SetAllowableError(2);
- SetExcludeRect(gfx::Rect(output_size.width() / 2 - 1, 0, 2,
- output_size.height()));
- }
+ // Skia rendering can cause color differences, particularly in the
+ // middle two columns.
+ SetAllowableError(2);
+ SetExcludeRect(
+ gfx::Rect(output_size.width() / 2 - 1, 0, 2, output_size.height()));
const ReadbackRequestCallback callback =
base::Bind(&CompositingRenderWidgetHostViewBrowserTestTabCapture::
@@ -988,6 +987,80 @@ IN_PROC_BROWSER_TEST_P(
video_frame);
}
+class CompositingRenderWidgetHostViewBrowserTestHiDPI
+ : public CompositingRenderWidgetHostViewBrowserTest {
+ public:
+ CompositingRenderWidgetHostViewBrowserTestHiDPI() {}
+
+ protected:
+ void SetUpCommandLine(base::CommandLine* cmd) override {
+ CompositingRenderWidgetHostViewBrowserTest::SetUpCommandLine(cmd);
+ cmd->AppendSwitchASCII(switches::kForceDeviceScaleFactor,
+ base::StringPrintf("%f", scale()));
+ }
+
+ GURL TestUrl() override { return GURL(test_url_); }
+
+ void SetTestUrl(const std::string& url) { test_url_ = url; }
+
+ bool ShouldContinueAfterTestURLLoad() {
+ // Short-circuit a pass for platforms where setting up high-DPI fails.
+ const float actual_scale_factor =
+ GetScaleFactorForView(GetRenderWidgetHostView());
+ if (actual_scale_factor != scale()) {
+ LOG(WARNING) << "Blindly passing this test; unable to force device scale "
+ << "factor: seems to be " << actual_scale_factor
+ << " but expected " << scale();
+ return false;
+ }
+ VLOG(1)
+ << ("Successfully forced device scale factor. Moving forward with "
+ "this test! :-)");
+ return true;
+ }
+
+ static float scale() { return 2.0f; }
+
+ private:
+ std::string test_url_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompositingRenderWidgetHostViewBrowserTestHiDPI);
+};
+
+IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestHiDPI,
+ ScrollOffset) {
+ const int kContentHeight = 2000;
+ const int kScrollAmount = 100;
+
+ SetTestUrl(
+ base::StringPrintf("data:text/html,<!doctype html>"
+ "<div class='box'></div>"
+ "<style>"
+ "body { padding: 0; margin: 0; }"
+ ".box { position: absolute;"
+ " background: #0ff;"
+ " width: 100%%;"
+ " height: %dpx;"
+ "}"
+ "</style>"
+ "<script>"
+ " addEventListener(\"scroll\", function() {"
+ " domAutomationController.send(\"DONE\"); });"
+ " window.scrollTo(0, %d);"
+ "</script>",
+ kContentHeight, kScrollAmount));
+
+ SET_UP_SURFACE_OR_PASS_TEST("\"DONE\"");
+ if (!ShouldContinueAfterTestURLLoad())
+ return;
+
+ RenderWidgetHostViewBase* rwhv = GetRenderWidgetHostView();
+ gfx::Vector2dF scroll_offset = rwhv->GetLastScrollOffset();
+
+ EXPECT_EQ(scroll_offset.x(), 0);
+ EXPECT_EQ(scroll_offset.y(), kScrollAmount);
+}
+
#if defined(OS_CHROMEOS)
// On ChromeOS there is no software compositing.
static const auto kTestCompositingModes = testing::Values(GL_COMPOSITING);
@@ -1006,6 +1079,9 @@ INSTANTIATE_TEST_CASE_P(
GLAndSoftwareCompositing,
CompositingRenderWidgetHostViewBrowserTestTabCaptureHighDPI,
kTestCompositingModes);
+INSTANTIATE_TEST_CASE_P(GLAndSoftwareCompositing,
+ CompositingRenderWidgetHostViewBrowserTestHiDPI,
+ kTestCompositingModes);
#endif // !defined(OS_ANDROID)
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 47f0f1a361c..eaa06d40261 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
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/command_line.h"
#include "base/debug/dump_without_crashing.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
@@ -16,6 +17,7 @@
#include "build/build_config.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
+#include "components/viz/common/switches.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
@@ -25,6 +27,7 @@
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/gpu/compositor_util.h"
+#include "content/browser/mus_util.h"
#include "content/browser/renderer_host/frame_connector_delegate.h"
#include "content/browser/renderer_host/input/touch_selection_controller_client_child_frame.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -50,17 +53,6 @@
#endif
namespace content {
-namespace {
-
-bool IsUsingMus() {
-#if defined(USE_AURA)
- return aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS;
-#else
- return false;
-#endif
-}
-
-} // namespace
// static
RenderWidgetHostViewChildFrame* RenderWidgetHostViewChildFrame::Create(
@@ -80,10 +72,16 @@ RenderWidgetHostViewChildFrame::RenderWidgetHostViewChildFrame(
next_surface_sequence_(1u),
current_surface_scale_factor_(1.f),
frame_connector_(nullptr),
+ enable_viz_(base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableViz)),
background_color_(SK_ColorWHITE),
scroll_bubbling_state_(NO_ACTIVE_GESTURE_SCROLL),
weak_factory_(this) {
- if (!IsUsingMus()) {
+ if (IsUsingMus()) {
+ // 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();
+ } else {
GetHostFrameSinkManager()->RegisterFrameSinkId(frame_sink_id_, this);
#if DCHECK_IS_ON()
GetHostFrameSinkManager()->SetFrameSinkDebugLabel(
@@ -158,20 +156,17 @@ void RenderWidgetHostViewChildFrame::SetFrameConnectorDelegate(
SetParentFrameSinkId(parent_view->GetFrameSinkId());
}
+ current_device_scale_factor_ =
+ frame_connector_->screen_info().device_scale_factor;
+
auto* root_view = frame_connector_->GetRootRenderWidgetHostView();
if (root_view) {
- // Make sure we're not using the zero-valued default for
- // current_device_scale_factor_.
- current_device_scale_factor_ = root_view->current_device_scale_factor();
- if (current_device_scale_factor_ == 0.f)
- current_device_scale_factor_ = 1.f;
-
auto* manager = root_view->GetTouchSelectionControllerClientManager();
if (manager) {
// We have managers in Aura and Android, as well as outside of content/.
// There is no manager for Mac OS.
selection_controller_client_ =
- base::MakeUnique<TouchSelectionControllerClientChildFrame>(this,
+ std::make_unique<TouchSelectionControllerClientChildFrame>(this,
manager);
manager->AddObserver(this);
}
@@ -185,6 +180,14 @@ void RenderWidgetHostViewChildFrame::SetFrameConnectorDelegate(
#endif
}
+#if defined(USE_AURA)
+void RenderWidgetHostViewChildFrame::SetFrameSinkId(
+ const viz::FrameSinkId& frame_sink_id) {
+ if (IsUsingMus())
+ frame_sink_id_ = frame_sink_id;
+}
+#endif // defined(USE_AURA)
+
void RenderWidgetHostViewChildFrame::OnManagerWillDestroy(
TouchSelectionControllerClientManager* manager) {
// We get the manager via the observer callback instead of through the
@@ -256,7 +259,7 @@ bool RenderWidgetHostViewChildFrame::IsShowing() {
gfx::Rect RenderWidgetHostViewChildFrame::GetViewBounds() const {
gfx::Rect rect;
if (frame_connector_) {
- rect = frame_connector_->ChildFrameRect();
+ rect = frame_connector_->frame_rect_in_dip();
RenderWidgetHostView* parent_view =
frame_connector_->GetParentRenderWidgetHostView();
@@ -329,14 +332,9 @@ SkColor RenderWidgetHostViewChildFrame::background_color() const {
}
gfx::Size RenderWidgetHostViewChildFrame::GetPhysicalBackingSize() const {
- gfx::Size size;
- if (frame_connector_) {
- content::ScreenInfo screen_info;
- host_->GetScreenInfo(&screen_info);
- size = gfx::ScaleToCeiledSize(frame_connector_->ChildFrameRect().size(),
- screen_info.device_scale_factor);
- }
- return size;
+ if (frame_connector_)
+ return frame_connector_->frame_rect_in_pixels().size();
+ return gfx::Size();
}
void RenderWidgetHostViewChildFrame::InitAsPopup(
@@ -440,6 +438,14 @@ void RenderWidgetHostViewChildFrame::SetIsInert() {
}
}
+void RenderWidgetHostViewChildFrame::UpdateRenderThrottlingStatus() {
+ if (host_ && frame_connector_) {
+ host_->Send(new ViewMsg_UpdateRenderThrottlingStatus(
+ host_->GetRoutingID(), frame_connector_->IsThrottled(),
+ frame_connector_->IsSubtreeThrottled()));
+ }
+}
+
void RenderWidgetHostViewChildFrame::GestureEventAck(
const blink::WebGestureEvent& event,
InputEventAckState ack_result) {
@@ -451,6 +457,15 @@ void RenderWidgetHostViewChildFrame::GestureEventAck(
if (!frame_connector_)
return;
if (wheel_scroll_latching_enabled()) {
+ if ((event.GetType() == blink::WebInputEvent::kGestureScrollBegin) &&
+ should_bubble) {
+ DCHECK(!is_scroll_sequence_bubbling_);
+ is_scroll_sequence_bubbling_ = true;
+ } else if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
+ event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
+ is_scroll_sequence_bubbling_ = false;
+ }
+
// GestureScrollBegin is a blocking event; It is forwarded for bubbling if
// its ack is not consumed. For the rest of the scroll events
// (GestureScrollUpdate, GestureScrollEnd, GestureFlingStart) the
@@ -503,6 +518,17 @@ void RenderWidgetHostViewChildFrame::DidReceiveCompositorFrameAck(
renderer_compositor_frame_sink_->DidReceiveCompositorFrameAck(resources);
}
+void RenderWidgetHostViewChildFrame::DidPresentCompositorFrame(
+ uint32_t presentation_token,
+ base::TimeTicks time,
+ base::TimeDelta refresh,
+ uint32_t flags) {
+ NOTIMPLEMENTED();
+}
+void RenderWidgetHostViewChildFrame::DidDiscardCompositorFrame(
+ uint32_t presentation_token) {
+ NOTIMPLEMENTED();
+}
void RenderWidgetHostViewChildFrame::DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
ResetCompositorFrameSinkSupport();
@@ -535,14 +561,13 @@ void RenderWidgetHostViewChildFrame::SetParentFrameSinkId(
void RenderWidgetHostViewChildFrame::ProcessCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) {
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) {
current_surface_size_ = frame.size_in_pixels();
current_surface_scale_factor_ = frame.device_scale_factor();
- // TODO(kenrb): Supply HitTestRegionList data here as described in
- // crbug.com/750755.
- bool result = support_->SubmitCompositorFrame(local_surface_id,
- std::move(frame), nullptr);
+ bool result = support_->SubmitCompositorFrame(
+ local_surface_id, std::move(frame), std::move(hit_test_region_list));
DCHECK(result);
has_frame_ = true;
@@ -586,17 +611,21 @@ void RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedderImpl(
void RenderWidgetHostViewChildFrame::SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) {
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) {
+ DCHECK(!enable_viz_);
TRACE_EVENT0("content",
"RenderWidgetHostViewChildFrame::OnSwapCompositorFrame");
last_scroll_offset_ = frame.metadata.root_scroll_offset;
if (!frame_connector_)
return;
- ProcessCompositorFrame(local_surface_id, std::move(frame));
+ ProcessCompositorFrame(local_surface_id, std::move(frame),
+ std::move(hit_test_region_list));
}
void RenderWidgetHostViewChildFrame::OnDidNotProduceFrame(
const viz::BeginFrameAck& ack) {
+ DCHECK(!enable_viz_);
support_->DidNotProduceFrame(ack);
}
@@ -702,11 +731,33 @@ void RenderWidgetHostViewChildFrame::ProcessTouchEvent(
void RenderWidgetHostViewChildFrame::ProcessGestureEvent(
const blink::WebGestureEvent& event,
const ui::LatencyInfo& latency) {
+ if (wheel_scroll_latching_enabled() && is_scroll_sequence_bubbling_ &&
+ (event.GetType() == blink::WebInputEvent::kGestureFlingStart) &&
+ frame_connector_) {
+ // For GestureFlingStarts, we send a GestureScrollEnd to the child in order
+ // to conclude the scrolling sequence but without allowing the child to
+ // actually fling if the child attempts to consume scroll.
+ // We bubble the fling to the target intended to consume it.
+ frame_connector_->BubbleScrollEvent(event);
+
+ blink::WebGestureEvent scroll_end(event);
+ scroll_end.SetType(blink::WebInputEvent::kGestureScrollEnd);
+ scroll_end.data.scroll_end.inertial_phase =
+ blink::WebGestureEvent::kUnknownMomentumPhase;
+ scroll_end.data.scroll_end.delta_units =
+ blink::WebGestureEvent::kPrecisePixels;
+ // Since we've just bubbled the fling, the |frame_connector_| knows that
+ // the sequence has ended, so it will just drop this synthesised GSE when
+ // we get the ack.
+ host_->ForwardGestureEvent(scroll_end);
+ return;
+ }
+
host_->ForwardGestureEventWithLatencyInfo(event, latency);
}
-gfx::Point RenderWidgetHostViewChildFrame::TransformPointToRootCoordSpace(
- const gfx::Point& point) {
+gfx::PointF RenderWidgetHostViewChildFrame::TransformPointToRootCoordSpaceF(
+ const gfx::PointF& point) {
if (!frame_connector_ || !last_received_local_surface_id_.is_valid())
return point;
@@ -715,9 +766,9 @@ gfx::Point RenderWidgetHostViewChildFrame::TransformPointToRootCoordSpace(
}
bool RenderWidgetHostViewChildFrame::TransformPointToLocalCoordSpace(
- const gfx::Point& point,
+ const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
*transformed_point = point;
if (!frame_connector_ || !last_received_local_surface_id_.is_valid())
return false;
@@ -729,9 +780,9 @@ bool RenderWidgetHostViewChildFrame::TransformPointToLocalCoordSpace(
}
bool RenderWidgetHostViewChildFrame::TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
if (!frame_connector_ || !last_received_local_surface_id_.is_valid())
return false;
@@ -762,6 +813,7 @@ void RenderWidgetHostViewChildFrame::WillSendScreenRects() {
if (frame_connector_) {
UpdateViewportIntersection(frame_connector_->ViewportIntersection());
SetIsInert();
+ UpdateRenderThrottlingStatus();
}
}
@@ -806,7 +858,7 @@ void RenderWidgetHostViewChildFrame::CopyFromSurface(
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.
- RegisterFrameSwappedCallback(base::MakeUnique<base::Closure>(base::Bind(
+ RegisterFrameSwappedCallback(std::make_unique<base::Closure>(base::Bind(
&RenderWidgetHostViewChildFrame::SubmitSurfaceCopyRequest, AsWeakPtr(),
src_rect, output_size, callback, preferred_color_type)));
return;
@@ -863,6 +915,10 @@ void RenderWidgetHostViewChildFrame::OnFirstSurfaceActivation(
SendSurfaceInfoToEmbedderImpl(surface_info, sequence);
}
+void RenderWidgetHostViewChildFrame::OnFrameTokenChanged(uint32_t frame_token) {
+ OnFrameTokenChangedForView(frame_token);
+}
+
void RenderWidgetHostViewChildFrame::SetNeedsBeginFrames(
bool needs_begin_frames) {
if (support_)
@@ -891,6 +947,20 @@ InputEventAckState RenderWidgetHostViewChildFrame::FilterInputEvent(
}
}
+ if (wheel_scroll_latching_enabled() && is_scroll_sequence_bubbling_ &&
+ (input_event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) &&
+ frame_connector_) {
+ // If we're bubbling, then to preserve latching behaviour, the child should
+ // not consume this event. If the child has added its viewport to the scroll
+ // chain, then any GSU events we send to the renderer could be consumed,
+ // even though we intend for them to be bubbled. So we immediately bubble
+ // any scroll updates without giving the child a chance to consume them.
+ // If the child has not added its viewport to the scroll chain, then we
+ // know that it will not attempt to consume the rest of the scroll
+ // sequence.
+ return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
+ }
+
// Allow the root RWHV a chance to consume the child's GestureScrollUpdates
// in case the root needs to prevent the child from scrolling. For example,
// if the root has started an overscroll gesture, it needs to process the
@@ -928,6 +998,18 @@ RenderWidgetHostViewChildFrame::CreateBrowserAccessibilityManager(
BrowserAccessibilityManager::GetEmptyDocument(), delegate);
}
+void RenderWidgetHostViewChildFrame::GetScreenInfo(ScreenInfo* screen_info) {
+ if (frame_connector_)
+ *screen_info = frame_connector_->screen_info();
+}
+
+void RenderWidgetHostViewChildFrame::ResizeDueToAutoResize(
+ const gfx::Size& new_size,
+ uint64_t sequence_number) {
+ if (frame_connector_)
+ frame_connector_->ResizeDueToAutoResize(new_size, sequence_number);
+}
+
void RenderWidgetHostViewChildFrame::ClearCompositorSurfaceIfNecessary() {
if (!support_)
return;
@@ -944,7 +1026,7 @@ viz::SurfaceId RenderWidgetHostViewChildFrame::SurfaceIdForTesting() const {
}
void RenderWidgetHostViewChildFrame::CreateCompositorFrameSinkSupport() {
- if (IsUsingMus())
+ if (IsUsingMus() || enable_viz_)
return;
DCHECK(!support_);
@@ -1010,6 +1092,12 @@ gfx::Point RenderWidgetHostViewChildFrame::GetViewOriginInRoot() const {
return gfx::Point();
}
+RenderWidgetHostViewBase*
+RenderWidgetHostViewChildFrame::GetRootRenderWidgetHostView() const {
+ return frame_connector_ ? frame_connector_->GetRootRenderWidgetHostView()
+ : nullptr;
+}
+
bool RenderWidgetHostViewChildFrame::CanBecomeVisible() {
if (!frame_connector_)
return true;
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.h b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.h
index b0617bb1fdb..743ca2b13ed 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.h
@@ -25,9 +25,9 @@
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/public/browser/readback_types.h"
#include "content/public/browser/touch_selection_controller_client_manager.h"
+#include "content/public/common/input_event_ack_state.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
@@ -63,6 +63,12 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void SetFrameConnectorDelegate(FrameConnectorDelegate* frame_connector);
+#if defined(USE_AURA)
+ // When the viz::FrameSinkId for this child frame is created and registered
+ // remotely, it can be set here.
+ void SetFrameSinkId(const viz::FrameSinkId& frame_sink_id);
+#endif // defined(USE_AURA)
+
// This functions registers single-use callbacks that want to be notified when
// the next frame is swapped. The callback is triggered by
// ProcessCompositorFrame, which is the appropriate time to request pixel
@@ -118,8 +124,10 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink)
override;
- void SubmitCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) override;
+ void SubmitCompositorFrame(
+ const viz::LocalSurfaceId& local_surface_id,
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) override;
void OnDidNotProduceFrame(const viz::BeginFrameAck& ack) override;
// Since the URL of content rendered by this class is not displayed in
// the URL bar, this method does not need an implementation.
@@ -142,14 +150,15 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
const ui::LatencyInfo& latency) override;
void ProcessGestureEvent(const blink::WebGestureEvent& event,
const ui::LatencyInfo& latency) override;
- gfx::Point TransformPointToRootCoordSpace(const gfx::Point& point) override;
- bool TransformPointToLocalCoordSpace(const gfx::Point& point,
+ gfx::PointF TransformPointToRootCoordSpaceF(
+ const gfx::PointF& point) override;
+ bool TransformPointToLocalCoordSpace(const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point) override;
+ gfx::PointF* transformed_point) override;
bool TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point) override;
+ gfx::PointF* transformed_point) override;
bool IsRenderWidgetHostViewChildFrame() override;
@@ -173,10 +182,18 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
BrowserAccessibilityManager* CreateBrowserAccessibilityManager(
BrowserAccessibilityDelegate* delegate,
bool for_root_frame) override;
+ void GetScreenInfo(ScreenInfo* screen_info) override;
+ void ResizeDueToAutoResize(const gfx::Size& new_size,
+ uint64_t sequence_number) override;
// viz::mojom::CompositorFrameSinkClient implementation.
void DidReceiveCompositorFrameAck(
const std::vector<viz::ReturnedResource>& resources) override;
+ void DidPresentCompositorFrame(uint32_t presentation_token,
+ base::TimeTicks time,
+ base::TimeDelta refresh,
+ uint32_t flags) override;
+ void DidDiscardCompositorFrame(uint32_t presentation_token) override;
void OnBeginFrame(const viz::BeginFrameArgs& args) override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
@@ -184,6 +201,7 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
// viz::HostFrameSinkClient implementation.
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
+ void OnFrameTokenChanged(uint32_t frame_token) override;
// Exposed for tests.
bool IsChildFrameForTesting() const override;
@@ -207,6 +225,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void SetIsInert();
+ void UpdateRenderThrottlingStatus();
+
bool has_frame() { return has_frame_; }
ui::TextInputType GetTextInputType() const;
@@ -215,6 +235,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
// of the root RenderWidgetHostView.
gfx::Point GetViewOriginInRoot() const;
+ RenderWidgetHostViewBase* GetRootRenderWidgetHostView() const;
+
protected:
friend class RenderWidgetHostView;
friend class RenderWidgetHostViewChildFrameTest;
@@ -229,8 +251,10 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
// parent was already set then it also unregisters hierarchy.
void SetParentFrameSinkId(const viz::FrameSinkId& parent_frame_sink_id);
- void ProcessCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame);
+ void ProcessCompositorFrame(
+ const viz::LocalSurfaceId& local_surface_id,
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list);
void SendSurfaceInfoToEmbedder();
@@ -301,6 +325,7 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
// The surface client ID of the parent RenderWidgetHostView. 0 if none.
viz::FrameSinkId parent_frame_sink_id_;
+ const bool enable_viz_;
bool has_frame_ = false;
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink_ =
nullptr;
@@ -311,6 +336,9 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
std::unique_ptr<TouchSelectionControllerClientChildFrame>
selection_controller_client_;
+ // True if there is currently a scroll sequence being bubbled to our parent.
+ bool is_scroll_sequence_bubbling_ = false;
+
// Used to prevent bubbling of subsequent GestureScrollUpdates in a scroll
// gesture if the child consumed the first GSU.
// TODO(mcnee): This is only needed for |!wheel_scroll_latching_enabled()|
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 43f3075b3f1..9fa1e492f6a 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
@@ -7,6 +7,8 @@
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/common/surfaces/surface_sequence.h"
#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/mus_util.h"
+#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
@@ -46,9 +48,41 @@ class RenderWidgetHostViewChildFrameTest : public ContentBrowserTest {
EXPECT_EQ(expected_screen_width_, width);
}
+ // Tests that the FrameSinkId of each child frame has been updated by the
+ // RenderFrameProxy.
+ void CheckFrameSinkId(RenderFrameHost* render_frame_host) {
+ RenderWidgetHostViewBase* child_view =
+ static_cast<RenderFrameHostImpl*>(render_frame_host)
+ ->GetRenderWidgetHost()
+ ->GetView();
+ // Only interested in updated FrameSinkIds on child frames.
+ if (!child_view || !child_view->IsRenderWidgetHostViewChildFrame())
+ return;
+
+ // Ensure that the received viz::FrameSinkId was correctly set on the child
+ // frame.
+ viz::FrameSinkId actual_frame_sink_id_ = child_view->GetFrameSinkId();
+ EXPECT_EQ(expected_frame_sink_id_, actual_frame_sink_id_);
+
+ // The viz::FrameSinkID will be replaced while the test blocks for
+ // navigation. It should differ from the information stored in the child's
+ // RenderWidgetHost.
+ EXPECT_NE(base::checked_cast<uint32_t>(
+ child_view->GetRenderWidgetHost()->GetProcess()->GetID()),
+ actual_frame_sink_id_.client_id());
+ EXPECT_NE(base::checked_cast<uint32_t>(
+ child_view->GetRenderWidgetHost()->GetRoutingID()),
+ actual_frame_sink_id_.sink_id());
+ }
+
+ void set_expected_frame_sink_id(viz::FrameSinkId frame_sink_id) {
+ expected_frame_sink_id_ = frame_sink_id;
+ }
+
void set_expected_screen_width(int width) { expected_screen_width_ = width; }
private:
+ viz::FrameSinkId expected_frame_sink_id_;
int expected_screen_width_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewChildFrameTest);
@@ -118,6 +152,40 @@ IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest,
EXPECT_EQ(gfx::Size(75, 75), rwhv->GetVisibleViewportSize());
}
+// Tests that while in mus, the child frame receives an updated FrameSinkId
+// representing the frame sink used by the RenderFrameProxy
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest, ChildFrameSinkId) {
+ // Only in mus do we expect a RenderFrameProxy to provide the FrameSinkId.
+ if (!IsUsingMus())
+ return;
+
+ GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
+ NavigateToURL(shell(), main_url);
+
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ scoped_refptr<UpdateResizeParamsMessageFilter> message_filter(
+ new UpdateResizeParamsMessageFilter());
+ root->current_frame_host()->GetProcess()->AddFilter(message_filter.get());
+
+ // Load cross-site page into iframe.
+ GURL cross_site_url(
+ embedded_test_server()->GetURL("foo.com", "/title2.html"));
+ // The child frame is created during this blocking call, on the UI thread.
+ // This is racing the IPC we are testing for, which arrives on the IO thread.
+ // Due to this we cannot get the pre-IPC value of the viz::FrameSinkId.
+ NavigateFrameToURL(root->child_at(0), cross_site_url);
+
+ // Ensure that the IPC providing the new viz::FrameSinkId. If it does not then
+ // this test will timeout.
+ set_expected_frame_sink_id(message_filter->GetOrWaitForId());
+
+ shell()->web_contents()->ForEachFrame(
+ base::Bind(&RenderWidgetHostViewChildFrameTest::CheckFrameSinkId,
+ base::Unretained(this)));
+}
+
// A class to filter RequireSequence and SatisfySequence messages sent from
// an embedding renderer for its child's Surfaces.
class SurfaceRefMessageFilter : public BrowserMessageFilter {
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 b1c69c430f9..f619f98fbf3 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
@@ -50,7 +50,8 @@ const viz::LocalSurfaceId kArbitraryLocalSurfaceId(
class MockFrameConnectorDelegate : public FrameConnectorDelegate {
public:
- MockFrameConnectorDelegate() : FrameConnectorDelegate() {}
+ MockFrameConnectorDelegate(bool use_zoom_for_device_scale_factor)
+ : FrameConnectorDelegate(use_zoom_for_device_scale_factor) {}
~MockFrameConnectorDelegate() override {}
void SetChildFrameSurface(const viz::SurfaceInfo& surface_info,
@@ -82,6 +83,10 @@ class RenderWidgetHostViewChildFrameTest : public testing::Test {
base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
void SetUp() override {
+ SetUpEnvironment(false /* use_zoom_for_device_scale_factor */);
+ }
+
+ void SetUpEnvironment(bool use_zoom_for_device_scale_factor) {
browser_context_.reset(new TestBrowserContext);
// ImageTransportFactory doesn't exist on Android.
@@ -94,12 +99,13 @@ class RenderWidgetHostViewChildFrameTest : public testing::Test {
new MockRenderProcessHost(browser_context_.get());
int32_t routing_id = process_host->GetNextRoutingID();
mojom::WidgetPtr widget;
- widget_impl_ = base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ widget_impl_ = std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
widget_host_ = new RenderWidgetHostImpl(
&delegate_, process_host, routing_id, std::move(widget), false);
view_ = RenderWidgetHostViewChildFrame::Create(widget_host_);
- test_frame_connector_ = new MockFrameConnectorDelegate();
+ test_frame_connector_ =
+ new MockFrameConnectorDelegate(use_zoom_for_device_scale_factor);
view_->SetFrameConnectorDelegate(test_frame_connector_);
viz::mojom::CompositorFrameSinkPtr sink;
@@ -108,7 +114,7 @@ class RenderWidgetHostViewChildFrameTest : public testing::Test {
viz::mojom::CompositorFrameSinkClientRequest client_request =
mojo::MakeRequest(&renderer_compositor_frame_sink_ptr_);
renderer_compositor_frame_sink_ =
- base::MakeUnique<FakeRendererCompositorFrameSink>(
+ std::make_unique<FakeRendererCompositorFrameSink>(
std::move(sink), std::move(client_request));
view_->DidCreateNewRendererCompositorFrameSink(
renderer_compositor_frame_sink_ptr_.get());
@@ -204,7 +210,7 @@ TEST_F(RenderWidgetHostViewChildFrameTest, SwapCompositorFrame) {
view_->SubmitCompositorFrame(
local_surface_id,
- CreateDelegatedFrame(scale_factor, view_size, view_rect));
+ CreateDelegatedFrame(scale_factor, view_size, view_rect), nullptr);
viz::SurfaceId id = GetSurfaceId();
if (id.is_valid()) {
@@ -236,7 +242,7 @@ TEST_F(RenderWidgetHostViewChildFrameTest, FrameEviction) {
// Submit a frame.
view_->SubmitCompositorFrame(
kArbitraryLocalSurfaceId,
- CreateDelegatedFrame(scale_factor, view_size, view_rect));
+ CreateDelegatedFrame(scale_factor, view_size, view_rect), nullptr);
EXPECT_EQ(kArbitraryLocalSurfaceId, GetLocalSurfaceId());
EXPECT_TRUE(view_->has_frame());
@@ -250,7 +256,7 @@ TEST_F(RenderWidgetHostViewChildFrameTest, FrameEviction) {
// usable.
view_->SubmitCompositorFrame(
kArbitraryLocalSurfaceId,
- CreateDelegatedFrame(scale_factor, view_size, view_rect));
+ CreateDelegatedFrame(scale_factor, view_size, view_rect), nullptr);
EXPECT_EQ(kArbitraryLocalSurfaceId, GetLocalSurfaceId());
EXPECT_TRUE(view_->has_frame());
}
@@ -299,6 +305,19 @@ class RenderWidgetHostViewChildFrameScrollLatchingDisabledTest
RenderWidgetHostViewChildFrameScrollLatchingDisabledTest);
};
+class RenderWidgetHostViewChildFrameZoomForDSFTest
+ : public RenderWidgetHostViewChildFrameTest {
+ public:
+ RenderWidgetHostViewChildFrameZoomForDSFTest() {}
+
+ void SetUp() override {
+ SetUpEnvironment(true /* use_zoom_for_device_scale_factor */);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewChildFrameZoomForDSFTest);
+};
+
// Test that when a child scrolls and then stops consuming once it hits the
// extent, we don't bubble the subsequent unconsumed GestureScrollUpdates
// in the same gesture.
@@ -319,4 +338,20 @@ TEST_F(RenderWidgetHostViewChildFrameScrollLatchingDisabledTest,
EXPECT_FALSE(test_frame_connector_->seen_bubbled_gsu_);
}
+// Tests that moving the child around does not affect the physical backing size.
+TEST_F(RenderWidgetHostViewChildFrameZoomForDSFTest, PhysicalBackingSize) {
+ ScreenInfo screen_info;
+ screen_info.device_scale_factor = 2.0f;
+ test_frame_connector_->SetScreenInfoForTesting(screen_info);
+
+ gfx::Size frame_size_in_pixels(1276, 410);
+ gfx::Rect frame_rect_in_pixels(frame_size_in_pixels);
+ test_frame_connector_->SetRect(frame_rect_in_pixels);
+ EXPECT_EQ(frame_size_in_pixels, view_->GetPhysicalBackingSize());
+
+ frame_rect_in_pixels.set_origin(gfx::Point(230, 263));
+ test_frame_connector_->SetRect(frame_rect_in_pixels);
+ EXPECT_EQ(frame_size_in_pixels, view_->GetPhysicalBackingSize());
+}
+
} // namespace content
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 02614b2e7ef..aada073d739 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
@@ -55,7 +55,7 @@ BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) {
if (::IsWindowVisible(window)) {
const HWND owner = ::GetWindow(window, GW_OWNER);
if (toplevel_hwnd == owner) {
- ::PostMessage(window, WM_CANCELMODE, 0, 0);
+ ::PostMessageW(window, WM_CANCELMODE, 0, 0);
}
}
@@ -63,15 +63,15 @@ BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) {
}
#endif // defined(OS_WIN)
-gfx::Point GetScreenLocationFromEvent(const ui::LocatedEvent& event) {
+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();
+ return event.root_location_f();
- gfx::Point screen_location(event.root_location());
+ gfx::PointF screen_location(event.root_location_f());
spc->ConvertPointToScreen(root, &screen_location);
return screen_location;
}
@@ -200,8 +200,7 @@ bool RenderWidgetHostViewEventHandler::LockMouse() {
}
if (ShouldMoveToCenter()) {
- synthetic_move_sent_ = true;
- window_->MoveCursorTo(gfx::Rect(window_->bounds().size()).CenterPoint());
+ MoveCursorToCenter();
}
delegate_->SetTooltipsEnabled(false);
return true;
@@ -229,7 +228,7 @@ void RenderWidgetHostViewEventHandler::UnlockMouse() {
// not what sites expect. The delta is computed in the
// ModifyEventMovementAndCoords function.
global_mouse_position_ = unlocked_global_mouse_position_;
- window_->MoveCursorTo(unlocked_mouse_position_);
+ window_->MoveCursorTo(gfx::ToFlooredPoint(unlocked_mouse_position_));
aura::client::CursorClient* cursor_client =
aura::client::GetCursorClient(root_window);
@@ -445,9 +444,12 @@ void RenderWidgetHostViewEventHandler::OnScrollEvent(ui::ScrollEvent* event) {
}
if (event->type() == ui::ET_SCROLL_FLING_START) {
RecordAction(base::UserMetricsAction("TrackpadScrollFling"));
- // Ignore the pending wheel end event to avoid sending a wheel event with
- // kPhaseEnded before a GFS.
- mouse_wheel_phase_handler_.IgnorePendingWheelEndEvent();
+ // The user has lifted their fingers.
+ mouse_wheel_phase_handler_.ResetScrollSequence();
+ } else if (event->type() == ui::ET_SCROLL_FLING_CANCEL) {
+ // The user has put their fingers down.
+ DCHECK_EQ(blink::kWebGestureDeviceTouchpad, gesture_event.source_device);
+ mouse_wheel_phase_handler_.ScrollingMayBegin();
}
}
@@ -546,11 +548,13 @@ void RenderWidgetHostViewEventHandler::OnGestureEvent(ui::GestureEvent* event) {
// wheel based send a synthetic wheel event with kPhaseEnded to cancel
// the current scroll.
mouse_wheel_phase_handler_.DispatchPendingWheelEndEvent();
+ mouse_wheel_phase_handler_.SendWheelEndIfNeeded();
} else if (event->type() == ui::ET_GESTURE_SCROLL_END) {
// Make sure that the next wheel event will have phase = |kPhaseBegan|.
// This is for maintaining the correct phase info when some of the wheel
// events get ignored while a touchscreen scroll is going on.
mouse_wheel_phase_handler_.IgnorePendingWheelEndEvent();
+ mouse_wheel_phase_handler_.ResetScrollSequence();
} else if (event->type() == ui::ET_SCROLL_FLING_START) {
RecordAction(base::UserMetricsAction("TouchscreenScrollFling"));
}
@@ -740,8 +744,7 @@ void RenderWidgetHostViewEventHandler::HandleMouseEventWhileLocked(
// needs to be moved back to the center.
if (event->flags() & ui::EF_IS_NON_CLIENT) {
// TODO(jonross): ideally this would not be done for mus (crbug.com/621412)
- synthetic_move_sent_ = true;
- window_->MoveCursorTo(center);
+ MoveCursorToCenter();
return;
}
@@ -780,10 +783,8 @@ void RenderWidgetHostViewEventHandler::HandleMouseEventWhileLocked(
synthetic_move_sent_ = false;
} else {
// Check if the mouse has reached the border and needs to be centered.
- if (ShouldMoveToCenter()) {
- synthetic_move_sent_ = true;
- window_->MoveCursorTo(center);
- }
+ if (ShouldMoveToCenter())
+ MoveCursorToCenter();
bool is_selection_popup = NeedsInputGrab(popup_child_host_view_);
// Forward event to renderer.
if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) &&
@@ -819,8 +820,10 @@ void RenderWidgetHostViewEventHandler::ModifyEventMovementAndCoords(
// We do not measure movement as the delta from cursor to center because
// we may receive more mouse movement events before our warp has taken
// effect.
- event->movement_x = event->PositionInScreen().x - global_mouse_position_.x();
- event->movement_y = event->PositionInScreen().y - global_mouse_position_.y();
+ event->movement_x = gfx::ToFlooredInt(event->PositionInScreen().x -
+ global_mouse_position_.x());
+ event->movement_y = gfx::ToFlooredInt(event->PositionInScreen().y -
+ global_mouse_position_.y());
global_mouse_position_.SetPoint(event->PositionInScreen().x,
event->PositionInScreen().y);
@@ -840,6 +843,21 @@ void RenderWidgetHostViewEventHandler::ModifyEventMovementAndCoords(
}
}
+void RenderWidgetHostViewEventHandler::MoveCursorToCenter() {
+#if defined(OS_WIN)
+ // TODO(crbug.com/781182): Set the global position when move cursor to center.
+ // This is a workaround for a bug from Windows update 16299, and should be remove
+ // once the bug is fixed in OS.
+ gfx::PointF center_in_screen(window_->GetBoundsInScreen().CenterPoint());
+ global_mouse_position_ = center_in_screen;
+#else
+ synthetic_move_sent_ = true;
+#endif
+
+ gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint());
+ window_->MoveCursorTo(center);
+}
+
void RenderWidgetHostViewEventHandler::SetKeyboardFocus() {
#if defined(OS_WIN)
if (window_ && window_->delegate()->CanFocus()) {
@@ -861,8 +879,8 @@ void RenderWidgetHostViewEventHandler::SetKeyboardFocus() {
bool RenderWidgetHostViewEventHandler::ShouldMoveToCenter() {
gfx::Rect rect = window_->bounds();
rect = delegate_->ConvertRectToScreen(rect);
- int border_x = rect.width() * kMouseLockBorderPercentage / 100;
- int border_y = rect.height() * kMouseLockBorderPercentage / 100;
+ float border_x = rect.width() * kMouseLockBorderPercentage / 100.0;
+ float border_y = rect.height() * kMouseLockBorderPercentage / 100.0;
return global_mouse_position_.x() < rect.x() + border_x ||
global_mouse_position_.x() > rect.right() - border_x ||
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 b5449d502d4..073b4916914 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
@@ -176,6 +176,9 @@ class CONTENT_EXPORT RenderWidgetHostViewEventHandler
void ModifyEventMovementAndCoords(const ui::MouseEvent& ui_mouse_event,
blink::WebMouseEvent* event);
+ // This method moves cursor to window center for pointer lock.
+ void MoveCursorToCenter();
+
// Helper function to set keyboard focus to the main window.
void SetKeyboardFocus();
@@ -225,11 +228,11 @@ class CONTENT_EXPORT RenderWidgetHostViewEventHandler
// While the mouse is locked, they store the last known position just as mouse
// lock was entered.
// Relative to the upper-left corner of the view.
- gfx::Point unlocked_mouse_position_;
+ gfx::PointF unlocked_mouse_position_;
// Relative to the upper-left corner of the screen.
- gfx::Point unlocked_global_mouse_position_;
+ gfx::PointF unlocked_global_mouse_position_;
// Last cursor position relative to screen. Used to compute movementX/Y.
- gfx::Point global_mouse_position_;
+ gfx::PointF global_mouse_position_;
// In mouse locked mode, we synthetically move the mouse cursor to the center
// of the window when it reaches the window borders to avoid it going outside.
// This flag is used to differentiate between these synthetic mouse move
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 7bed8419992..7620d73675d 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
@@ -313,6 +313,7 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
int error_code) override;
void Destroy() override;
void SetTooltipText(const base::string16& tooltip_text) override;
+ void UpdateScreenInfo(gfx::NativeView view) override;
bool IsSurfaceAvailableForCopy() const override;
void CopyFromSurface(const gfx::Rect& src_rect,
const gfx::Size& output_size,
@@ -331,8 +332,10 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
void DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink)
override;
- void SubmitCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) override;
+ void SubmitCompositorFrame(
+ const viz::LocalSurfaceId& local_surface_id,
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) override;
void OnDidNotProduceFrame(const viz::BeginFrameAck& ack) override;
void ClearCompositorFrame() override;
BrowserAccessibilityManager* CreateBrowserAccessibilityManager(
@@ -348,13 +351,15 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
void GestureEventAck(const blink::WebGestureEvent& event,
InputEventAckState ack_result) override;
+ void DidOverscroll(const ui::DidOverscrollParams& params) override;
+
std::unique_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget()
override;
viz::FrameSinkId GetFrameSinkId() override;
viz::FrameSinkId FrameSinkIdAtPoint(viz::SurfaceHittestDelegate* delegate,
- const gfx::Point& point,
- gfx::Point* transformed_point) override;
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point) override;
// Returns true when we can do SurfaceHitTesting for the event type.
bool ShouldRouteEvent(const blink::WebInputEvent& event) const;
// This method checks |event| to see if a GesturePinch event can be routed
@@ -373,13 +378,13 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
const ui::LatencyInfo& latency) override;
void ProcessGestureEvent(const blink::WebGestureEvent& event,
const ui::LatencyInfo& latency) override;
- bool TransformPointToLocalCoordSpace(const gfx::Point& point,
+ bool TransformPointToLocalCoordSpace(const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point) override;
+ gfx::PointF* transformed_point) override;
bool TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point) override;
+ gfx::PointF* transformed_point) override;
// TextInputManager::Observer implementation.
void OnUpdateTextInputStateCalled(TextInputManager* text_input_manager,
@@ -493,6 +498,7 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
SkColor BrowserCompositorMacGetGutterColor(SkColor color) const override;
void BrowserCompositorMacOnBeginFrame() override;
viz::LocalSurfaceId GetLocalSurfaceId() const override;
+ void OnFrameTokenChanged(uint32_t frame_token) override;
// AcceleratedWidgetMacNSView implementation.
NSView* AcceleratedWidgetGetNSView() const override;
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 d60210d735b..7671defd7a2 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
@@ -158,6 +158,7 @@ RenderWidgetHostView* GetRenderWidgetHostViewToUse(
consumed:(BOOL)consumed;
- (void)processedGestureScrollEvent:(const blink::WebGestureEvent&)event
consumed:(BOOL)consumed;
+- (void)processedOverscroll:(const ui::DidOverscrollParams&)params;
- (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv;
- (void)windowDidChangeBackingProperties:(NSNotification*)notification;
- (void)windowChangedGlobalFrame:(NSNotification*)notification;
@@ -404,6 +405,10 @@ viz::LocalSurfaceId RenderWidgetHostViewMac::GetLocalSurfaceId() const {
return local_surface_id_;
}
+void RenderWidgetHostViewMac::OnFrameTokenChanged(uint32_t frame_token) {
+ OnFrameTokenChangedForView(frame_token);
+}
+
////////////////////////////////////////////////////////////////////////////////
// AcceleratedWidgetMacNSView, public:
@@ -1109,6 +1114,18 @@ void RenderWidgetHostViewMac::SetTooltipText(
}
}
+void RenderWidgetHostViewMac::UpdateScreenInfo(gfx::NativeView view) {
+ RenderWidgetHostViewBase::UpdateScreenInfo(view);
+
+ if (!render_widget_host_ || !render_widget_host_->auto_resize_enabled())
+ return;
+
+ local_surface_id_ = local_surface_id_allocator_.GenerateId();
+ render_widget_host_->DidAllocateLocalSurfaceIdForAutoResize(
+ render_widget_host_->last_auto_resize_request_number());
+ browser_compositor_->GetDelegatedFrameHost()->WasResized();
+}
+
bool RenderWidgetHostViewMac::SupportsSpeech() const {
return [NSApp respondsToSelector:@selector(speakString:)] &&
[NSApp respondsToSelector:@selector(stopSpeaking:)];
@@ -1420,6 +1437,8 @@ bool RenderWidgetHostViewMac::HasAcceleratedSurface(
void RenderWidgetHostViewMac::FocusedNodeChanged(
bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) {
+ [cocoa_view_ cancelComposition];
+
// If the Mac Zoom feature is enabled, update it with the bounds of the
// current focused node so that it can ensure that it's scrolled into view.
// Don't do anything if it's an editable node, as this will be handled by
@@ -1438,7 +1457,8 @@ void RenderWidgetHostViewMac::DidCreateNewRendererCompositorFrameSink(
void RenderWidgetHostViewMac::SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) {
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) {
TRACE_EVENT0("browser", "RenderWidgetHostViewMac::OnSwapCompositorFrame");
last_frame_root_background_color_ = frame.metadata.root_background_color;
@@ -1516,6 +1536,11 @@ void RenderWidgetHostViewMac::GestureEventAck(
}
}
+void RenderWidgetHostViewMac::DidOverscroll(
+ const ui::DidOverscrollParams& params) {
+ [cocoa_view_ processedOverscroll:params];
+}
+
std::unique_ptr<SyntheticGestureTarget>
RenderWidgetHostViewMac::CreateSyntheticGestureTarget() {
RenderWidgetHostImpl* host =
@@ -1530,12 +1555,12 @@ viz::FrameSinkId RenderWidgetHostViewMac::GetFrameSinkId() {
viz::FrameSinkId RenderWidgetHostViewMac::FrameSinkIdAtPoint(
viz::SurfaceHittestDelegate* delegate,
- const gfx::Point& point,
- gfx::Point* transformed_point) {
+ const gfx::PointF& point,
+ gfx::PointF* transformed_point) {
// The surface hittest happens in device pixels, so we need to convert the
// |point| from DIPs to pixels before hittesting.
float scale_factor = ui::GetScaleFactorForNativeView(cocoa_view_);
- gfx::Point point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point);
+ gfx::PointF point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point);
viz::SurfaceId id =
browser_compositor_->GetDelegatedFrameHost()->SurfaceIdAtPoint(
delegate, point_in_pixels, transformed_point);
@@ -1596,13 +1621,13 @@ void RenderWidgetHostViewMac::ProcessGestureEvent(
}
bool RenderWidgetHostViewMac::TransformPointToLocalCoordSpace(
- const gfx::Point& point,
+ const gfx::PointF& point,
const viz::SurfaceId& original_surface,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
// Transformations use physical pixels rather than DIP, so conversion
// is necessary.
float scale_factor = ui::GetScaleFactorForNativeView(cocoa_view_);
- gfx::Point point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point);
+ gfx::PointF point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point);
if (!browser_compositor_->GetDelegatedFrameHost()
->TransformPointToLocalCoordSpace(point_in_pixels, original_surface,
transformed_point))
@@ -1612,9 +1637,9 @@ bool RenderWidgetHostViewMac::TransformPointToLocalCoordSpace(
}
bool RenderWidgetHostViewMac::TransformPointToCoordSpaceForView(
- const gfx::Point& point,
+ const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
- gfx::Point* transformed_point) {
+ gfx::PointF* transformed_point) {
if (target_view == this) {
*transformed_point = point;
return true;
@@ -1773,8 +1798,13 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
}
RenderWidgetHostImpl* host =
RenderWidgetHostImpl::From(GetRenderWidgetHost());
- if (host && host->delegate())
- host->delegate()->UpdateDeviceScaleFactor(display.device_scale_factor());
+ if (host) {
+ if (host->auto_resize_enabled()) {
+ host->DidAllocateLocalSurfaceIdForAutoResize(
+ host->last_auto_resize_request_number());
+ }
+ host->WasResized();
+ }
}
UpdateBackingStoreProperties();
@@ -1830,6 +1860,14 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
[[self window] makeFirstResponder:nil];
[NSApp updateWindows];
+ // Debug key to check if the current input context still holds onto the view.
+ NSTextInputContext* currentContext = [NSTextInputContext currentInputContext];
+ base::debug::ScopedCrashKey textInputContextCrashKey(
+ "text-input-context-client",
+ currentContext && [currentContext client] == self
+ ? "text input still held on"
+ : "text input no longer held on");
+
[super dealloc];
}
@@ -1861,6 +1899,10 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
consumed:consumed];
}
+- (void)processedOverscroll:(const ui::DidOverscrollParams&)params {
+ [responderDelegate_ rendererHandledOverscrollEvent:params];
+}
+
- (BOOL)respondsToSelector:(SEL)selector {
// Trickiness: this doesn't mean "does this object's superclass respond to
// this selector" but rather "does the -respondsToSelector impl from the
@@ -2325,12 +2367,15 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
NativeWebKeyboardEvent fakeEvent = event;
fakeEvent.SetType(blink::WebInputEvent::kKeyUp);
fakeEvent.skip_in_browser = true;
- widgetHost->ForwardKeyboardEventWithLatencyInfo(fakeEvent, latency_info);
+ ui::LatencyInfo fake_event_latency_info = latency_info;
+ fake_event_latency_info.set_source_event_type(ui::SourceEventType::OTHER);
+ widgetHost->ForwardKeyboardEventWithLatencyInfo(fakeEvent,
+ fake_event_latency_info);
// Not checking |renderWidgetHostView_->render_widget_host_| here because
// a key event with |skip_in_browser| == true won't be handled by browser,
// thus it won't destroy the widget.
- widgetHost->ForwardKeyboardEventWithCommands(event, latency_info,
+ widgetHost->ForwardKeyboardEventWithCommands(event, fake_event_latency_info,
&editCommands_);
// Calling ForwardKeyboardEventWithCommands() could have destroyed the
@@ -2554,8 +2599,8 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
}
- (void)showLookUpDictionaryOverlayAtPoint:(NSPoint)point {
- gfx::Point rootPoint(point.x, NSHeight([self frame]) - point.y);
- gfx::Point transformedPoint;
+ gfx::PointF rootPoint(point.x, NSHeight([self frame]) - point.y);
+ gfx::PointF transformedPoint;
if (!renderWidgetHostView_->render_widget_host_ ||
!renderWidgetHostView_->render_widget_host_->delegate() ||
!renderWidgetHostView_->render_widget_host_->delegate()
@@ -2573,7 +2618,7 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
int32_t targetWidgetProcessId = widgetHost->GetProcess()->GetID();
int32_t targetWidgetRoutingId = widgetHost->GetRoutingID();
TextInputClientMac::GetInstance()->GetStringAtPoint(
- widgetHost, transformedPoint,
+ widgetHost, gfx::ToFlooredPoint(transformedPoint),
^(NSAttributedString* string, NSPoint baselinePoint) {
if (!content::RenderWidgetHost::FromID(targetWidgetProcessId,
targetWidgetRoutingId)) {
@@ -3181,8 +3226,8 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
->GetInputEventRouter())
return NSNotFound;
- gfx::Point rootPoint(thePoint.x, thePoint.y);
- gfx::Point transformedPoint;
+ gfx::PointF rootPoint(thePoint.x, thePoint.y);
+ gfx::PointF transformedPoint;
RenderWidgetHostImpl* widgetHost =
renderWidgetHostView_->render_widget_host_->delegate()
->GetInputEventRouter()
@@ -3193,7 +3238,7 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
NSUInteger index =
TextInputClientMac::GetInstance()->GetCharacterIndexAtPoint(
- widgetHost, transformedPoint);
+ widgetHost, gfx::ToFlooredPoint(transformedPoint));
return index;
}
@@ -3618,7 +3663,8 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
// NSWindow's invalidateCursorRectsForView: resets cursor rects but does not
// update the cursor instantly. The cursor is updated when the mouse moves.
// Update the cursor by setting the current cursor if not hidden.
- if (!cursorHidden_)
+ WebContents* web_contents = renderWidgetHostView_->GetWebContents();
+ if (!cursorHidden_ && web_contents && !web_contents->IsShowingContextMenu())
[currentCursor_ set];
}
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm
index 72cbc1c2f99..02b3c10a70d 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm
@@ -174,6 +174,8 @@ NSString* RenderWidgetHostViewMacEditCommandHelper::CommandNameForSelector(
return @"MovePageUp";
if (selector == @selector(pageUpAndModifySelection:))
return @"MovePageUpAndModifySelection";
+ if (selector == @selector(showGuessPanel:))
+ return @"ToggleSpellPanel";
// Remove the trailing colon.
NSString* selector_str = NSStringFromSelector(selector);
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 167a2f756f2..b575cb19a7a 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
@@ -143,7 +143,7 @@ TEST_F(RenderWidgetHostViewMacEditCommandHelperWithTaskEnvTest,
int32_t routing_id = process_host->GetNextRoutingID();
mojom::WidgetPtr widget;
std::unique_ptr<MockWidgetImpl> widget_impl =
- base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
RenderWidgetHostImpl* render_widget = new RenderWidgetHostImpl(
&delegate, process_host, routing_id, std::move(widget), false);
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 1f63302262c..955d69758ea 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
@@ -114,6 +114,8 @@
- (void)touchesEndedWithEvent:(NSEvent*)event {}
- (void)beginGestureWithEvent:(NSEvent*)event {}
- (void)endGestureWithEvent:(NSEvent*)event {}
+- (void)rendererHandledOverscrollEvent:(const ui::DidOverscrollParams&)params {
+}
@end
@@ -121,23 +123,26 @@ namespace content {
namespace {
-blink::WebPointerProperties::PointerType GetInputMessagePointerTypes(
- MockRenderProcessHost* process) {
- blink::WebPointerProperties::PointerType pointer_type;
- DCHECK_LE(process->sink().message_count(), 1U);
- for (size_t i = 0; i < process->sink().message_count(); ++i) {
- const IPC::Message* message = process->sink().GetMessageAt(i);
- EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
- InputMsg_HandleInputEvent::Param params;
- EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
- const blink::WebInputEvent* event = std::get<0>(params);
- if (blink::WebInputEvent::IsMouseEventType(event->GetType())) {
- pointer_type =
- static_cast<const blink::WebMouseEvent*>(event)->pointer_type;
+std::string GetMessageNames(
+ const MockWidgetInputHandler::MessageVector& events) {
+ std::vector<std::string> result;
+ for (auto& event : events)
+ result.push_back(event->name());
+ return base::JoinString(result, " ");
}
- }
- process->sink().ClearMessages();
- return pointer_type;
+
+ blink::WebPointerProperties::PointerType GetPointerType(
+ const MockWidgetInputHandler::MessageVector& events) {
+ EXPECT_EQ(events.size(), 1U);
+ MockWidgetInputHandler::DispatchedEventMessage* event =
+ events[0]->ToEvent();
+ if (event && blink::WebInputEvent::IsMouseEventType(
+ event->Event()->web_event->GetType())) {
+ return static_cast<const blink::WebMouseEvent*>(
+ event->Event()->web_event.get())
+ ->pointer_type;
+ }
+ return blink::WebPointerProperties::PointerType::kUnknown;
}
NSEvent* MockTabletEventWithParams(CGEventType type,
@@ -243,13 +248,20 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
int32_t routing_id) {
mojom::WidgetPtr widget;
std::unique_ptr<MockWidgetImpl> widget_impl =
- base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
return new MockRenderWidgetHostImpl(delegate, process, routing_id,
std::move(widget_impl),
std::move(widget));
}
+ MockWidgetInputHandler* input_handler() {
+ return widget_impl_->input_handler();
+ }
+ MockWidgetInputHandler::MessageVector GetAndResetDispatchedMessages() {
+ return input_handler()->GetAndResetDispatchedMessages();
+ }
+
private:
MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
RenderProcessHost* process,
@@ -264,8 +276,18 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
widget_impl_(std::move(widget_impl)) {
set_renderer_initialized(true);
lastWheelEventLatencyInfo = ui::LatencyInfo();
+
+ ON_CALL(*this, Focus())
+ .WillByDefault(
+ testing::Invoke(this, &MockRenderWidgetHostImpl::FocusImpl));
+ ON_CALL(*this, Blur())
+ .WillByDefault(
+ testing::Invoke(this, &MockRenderWidgetHostImpl::BlurImpl));
}
+ void FocusImpl() { RenderWidgetHostImpl::Focus(); }
+ void BlurImpl() { RenderWidgetHostImpl::Blur(); }
+
std::unique_ptr<MockWidgetImpl> widget_impl_;
DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHostImpl);
@@ -327,6 +349,10 @@ NSEvent* MockScrollWheelEventWithPhase(SEL mockPhaseSelector, int32_t delta) {
return event;
}
+NSEvent* MockScrollWheelEventWithoutPhase(int32_t delta) {
+ return MockScrollWheelEventWithPhase(@selector(phaseNone), delta);
+}
+
NSEvent* MockScrollWheelEventWithMomentumPhase(SEL mockPhaseSelector,
int32_t delta) {
// Create a dummy event with phaseNone. This is for resetting the phase info
@@ -361,6 +387,7 @@ class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
else
DisableWheelScrollLatching();
+ mojo_feature_list_.InitAndEnableFeature(features::kMojoInputMessages);
vsync_feature_list_.InitAndEnableFeature(
features::kVsyncAlignedInputEvents);
}
@@ -379,6 +406,7 @@ class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
RenderWidgetHostImpl::From(rvh()->GetWidget())->SetView(rwhv_mac_);
rwhv_cocoa_.reset([rwhv_mac_->cocoa_view() retain]);
+ base::RunLoop().RunUntilIdle();
}
void TearDown() override {
@@ -439,6 +467,7 @@ class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
RenderWidgetHostView* old_rwhv_;
+ base::test::ScopedFeatureList mojo_feature_list_;
base::test::ScopedFeatureList vsync_feature_list_;
base::test::ScopedFeatureList feature_list_;
@@ -565,16 +594,21 @@ TEST_F(RenderWidgetHostViewMacTest, FilterNonPrintableCharacter) {
MockRenderWidgetHostImpl* host =
MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
+ base::RunLoop().RunUntilIdle();
// Simulate ctrl+F12, will produce a private use character but shouldn't
// fire keypress event
- process_host->sink().ClearMessages();
- EXPECT_EQ(0U, process_host->sink().message_count());
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
+
+ EXPECT_EQ(0U, events.size());
[view->cocoa_view() keyEvent:
cocoa_test_event_utils::KeyEventWithKeyCode(
0x7B, 0xF70F, NSKeyDown, NSControlKeyMask)];
- EXPECT_EQ(1U, process_host->sink().message_count());
- EXPECT_EQ("RawKeyDown", GetInputMessageTypes(process_host));
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+
+ EXPECT_EQ("RawKeyDown", GetMessageNames(events));
// Simulate ctrl+delete, will produce a private use character but shouldn't
// fire keypress event
@@ -583,17 +617,17 @@ TEST_F(RenderWidgetHostViewMacTest, FilterNonPrintableCharacter) {
[view->cocoa_view() keyEvent:
cocoa_test_event_utils::KeyEventWithKeyCode(
0x2E, 0xF728, NSKeyDown, NSControlKeyMask)];
- EXPECT_EQ(1U, process_host->sink().message_count());
- EXPECT_EQ("RawKeyDown", GetInputMessageTypes(process_host));
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+ EXPECT_EQ("RawKeyDown", GetMessageNames(events));
// Simulate a printable char, should generate keypress event
- process_host->sink().ClearMessages();
- EXPECT_EQ(0U, process_host->sink().message_count());
[view->cocoa_view() keyEvent:
cocoa_test_event_utils::KeyEventWithKeyCode(
0x58, 'x', NSKeyDown, NSControlKeyMask)];
- EXPECT_EQ(2U, process_host->sink().message_count());
- EXPECT_EQ("RawKeyDown Char", GetInputMessageTypes(process_host));
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+ EXPECT_EQ("RawKeyDown Char", GetMessageNames(events));
// Clean up.
host->ShutdownAndDestroyWidget(true);
@@ -611,14 +645,13 @@ TEST_F(RenderWidgetHostViewMacTest, InvalidKeyCode) {
MockRenderWidgetHostImpl* host =
MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
-
+ base::RunLoop().RunUntilIdle();
// Simulate "Convert" key on JIS PC keyboard, will generate a |NSFlagsChanged|
// NSEvent with |keyCode| == 0xFF.
- process_host->sink().ClearMessages();
- EXPECT_EQ(0U, process_host->sink().message_count());
[view->cocoa_view() keyEvent:cocoa_test_event_utils::KeyEventWithKeyCode(
0xFF, 0, NSFlagsChanged, 0)];
- EXPECT_EQ(0U, process_host->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0U, host->GetAndResetDispatchedMessages().size());
// Clean up.
host->ShutdownAndDestroyWidget(true);
@@ -1100,37 +1133,33 @@ void RenderWidgetHostViewMacTest::ScrollWheelEndEventDelivery() {
MockRenderWidgetHostImpl* host =
MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
- process_host->sink().ClearMessages();
// Send an initial wheel event with NSEventPhaseBegan to the view.
NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 0);
[view->cocoa_view() scrollWheel:event1];
- ASSERT_EQ(1U, process_host->sink().message_count());
// Flush and clear other messages (e.g. begin frames) the RWHVMac also sends.
base::RunLoop().RunUntilIdle();
- process_host->sink().ClearMessages();
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
// Send an ACK for the first wheel event, so that the queue will be flushed.
- InputEventAck ack(InputEventAckSource::COMPOSITOR_THREAD,
- blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- std::unique_ptr<IPC::Message> response(
- new InputHostMsg_HandleInputEvent_ACK(0, ack));
- host->OnMessageReceived(*response);
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Post the NSEventPhaseEnded wheel event to NSApp and check whether the
// render view receives it.
NSEvent* event2 = MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
[NSApp postEvent:event2 atStart:NO];
base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
if (scroll_latching_) {
// The wheel event with phaseEnded won't be sent to the render view
// immediately, instead the mouse_wheel_phase_handler will wait for 100ms
// to see if a wheel event with momentumPhase began arrives or not.
- ASSERT_EQ(0U, process_host->sink().message_count());
+ ASSERT_EQ(0U, events.size());
} else {
- ASSERT_EQ(1U, process_host->sink().message_count());
+ ASSERT_EQ(1U, events.size());
}
// Clean up.
@@ -1153,7 +1182,7 @@ TEST_F(RenderWidgetHostViewMacTest, PointerEventWithEraserType) {
MockRenderWidgetHostImpl* host =
MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
- process_host->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
// Send a NSEvent of NSTabletProximity type which has a device type of eraser.
NSEvent* event = MockTabletEventWithParams(kCGEventTabletProximity, true,
@@ -1161,15 +1190,17 @@ TEST_F(RenderWidgetHostViewMacTest, PointerEventWithEraserType) {
[view->cocoa_view() tabletEvent:event];
// Flush and clear other messages (e.g. begin frames) the RWHVMac also sends.
base::RunLoop().RunUntilIdle();
- process_host->sink().ClearMessages();
event =
MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft,
kCGEventMouseSubtypeTabletPoint);
[view->cocoa_view() mouseEvent:event];
- ASSERT_EQ(1U, process_host->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseLeave", GetMessageNames(events));
EXPECT_EQ(blink::WebPointerProperties::PointerType::kEraser,
- GetInputMessagePointerTypes(process_host));
+ GetPointerType(events));
// Clean up.
host->ShutdownAndDestroyWidget(true);
@@ -1196,15 +1227,17 @@ TEST_F(RenderWidgetHostViewMacTest, PointerEventWithPenType) {
[view->cocoa_view() tabletEvent:event];
// Flush and clear other messages (e.g. begin frames) the RWHVMac also sends.
base::RunLoop().RunUntilIdle();
- process_host->sink().ClearMessages();
event =
MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft,
kCGEventMouseSubtypeTabletPoint);
[view->cocoa_view() mouseEvent:event];
- ASSERT_EQ(1U, process_host->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseLeave", GetMessageNames(events));
EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
- GetInputMessagePointerTypes(process_host));
+ GetPointerType(events));
// Clean up.
host->ShutdownAndDestroyWidget(true);
@@ -1230,9 +1263,12 @@ TEST_F(RenderWidgetHostViewMacTest, PointerEventWithMouseType) {
MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft,
kCGEventMouseSubtypeDefault);
[view->cocoa_view() mouseEvent:event];
- ASSERT_EQ(1U, process_host->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseLeave", GetMessageNames(events));
EXPECT_EQ(blink::WebPointerProperties::PointerType::kMouse,
- GetInputMessagePointerTypes(process_host));
+ GetPointerType(events));
// Clean up.
host->ShutdownAndDestroyWidget(true);
@@ -1252,7 +1288,7 @@ void RenderWidgetHostViewMacTest::
MockRenderWidgetHostImpl* host =
MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
- process_host->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
// Add a delegate to the view.
base::scoped_nsobject<MockRenderWidgetHostViewMacDelegate> view_delegate(
@@ -1262,42 +1298,30 @@ void RenderWidgetHostViewMacTest::
// Send an initial wheel event for scrolling by 3 lines.
NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
[view->cocoa_view() scrollWheel:event1];
- ASSERT_EQ(1U, process_host->sink().message_count());
- process_host->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
+
+ ASSERT_EQ("MouseWheel", GetMessageNames(events));
// Indicate that the wheel event was unhandled.
- InputEventAck unhandled_ack(InputEventAckSource::COMPOSITOR_THREAD,
- blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- std::unique_ptr<IPC::Message> response1(
- new InputHostMsg_HandleInputEvent_ACK(0, unhandled_ack));
- host->OnMessageReceived(*response1);
+ events.clear();
+
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
if (scroll_latching_) {
// GestureEventQueue allows multiple in-flight events.
ASSERT_EQ("GestureScrollBegin GestureScrollUpdate",
- GetInputMessageTypes(process_host));
- // Send GSB ack.
- InputEventAck unhandled_scroll_ack(
- InputEventAckSource::COMPOSITOR_THREAD,
- blink::WebInputEvent::kGestureScrollBegin,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- std::unique_ptr<IPC::Message> scroll_response1(
- new InputHostMsg_HandleInputEvent_ACK(0, unhandled_scroll_ack));
- host->OnMessageReceived(*scroll_response1);
+ GetMessageNames(events));
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
} else {
// GestureEventQueue allows multiple in-flight events.
ASSERT_EQ("GestureScrollBegin GestureScrollUpdate GestureScrollEnd",
- GetInputMessageTypes(process_host));
+ GetMessageNames(events));
}
- process_host->sink().ClearMessages();
-
- InputEventAck unhandled_scroll_ack(InputEventAckSource::COMPOSITOR_THREAD,
- blink::WebInputEvent::kGestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- std::unique_ptr<IPC::Message> scroll_response1(
- new InputHostMsg_HandleInputEvent_ACK(0, unhandled_scroll_ack));
- host->OnMessageReceived(*scroll_response1);
+ events.clear();
// Check that the view delegate got an unhandled wheel event.
ASSERT_EQ(YES, view_delegate.get().unhandledWheelEventReceived);
@@ -1306,12 +1330,11 @@ void RenderWidgetHostViewMacTest::
// Send another wheel event, this time for scrolling by 0 lines (empty event).
NSEvent* event2 = MockScrollWheelEventWithPhase(@selector(phaseChanged), 0);
[view->cocoa_view() scrollWheel:event2];
- ASSERT_EQ("MouseWheel", GetInputMessageTypes(process_host));
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseWheel", GetMessageNames(events));
- // Indicate that the wheel event was also unhandled.
- std::unique_ptr<IPC::Message> response2(
- new InputHostMsg_HandleInputEvent_ACK(0, unhandled_ack));
- host->OnMessageReceived(*response2);
+ events.clear();
// Check that the view delegate ignored the empty unhandled wheel event.
ASSERT_EQ(NO, view_delegate.get().unhandledWheelEventReceived);
@@ -1445,6 +1468,59 @@ TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
ScrollWheelEndEventDelivery();
}
+// Scrolling with a mouse wheel device on Mac won't give phase information.
+// MouseWheelPhaseHandler adds timer based phase information to wheel events
+// generated from this type of devices.
+TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
+ TimerBasedPhaseInfo) {
+ // Initialize the view associated with a MockRenderWidgetHostImpl, rather than
+ // the MockRenderProcessHost that is set up by the test harness which mocks
+ // out |OnMessageReceived()|.
+ TestBrowserContext browser_context;
+ MockRenderProcessHost* process_host =
+ new MockRenderProcessHost(&browser_context);
+ process_host->Init();
+ MockRenderWidgetHostDelegate delegate;
+ int32_t routing_id = process_host->GetNextRoutingID();
+ MockRenderWidgetHostImpl* host =
+ MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
+ RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
+ base::RunLoop().RunUntilIdle();
+
+ // Send a wheel event without phase information for scrolling by 3 lines.
+ NSEvent* wheelEvent = MockScrollWheelEventWithoutPhase(3);
+ [view->cocoa_view() scrollWheel:wheelEvent];
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseWheel", GetMessageNames(events));
+
+ events.clear();
+ events = host->GetAndResetDispatchedMessages();
+ // Both GSB and GSU will be sent since GestureEventQueue allows multiple
+ // in-flight events.
+ ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));
+ ASSERT_TRUE(static_cast<const blink::WebGestureEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get())
+ ->data.scroll_begin.synthetic);
+ events.clear();
+
+ // Wait for the mouse_wheel_end_dispatch_timer_ to expire, the pending wheel
+ // event gets dispatched.
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ base::TimeDelta::FromMilliseconds(100));
+ run_loop.Run();
+
+ events = host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
+ ASSERT_TRUE(static_cast<const blink::WebGestureEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get())
+ ->data.scroll_end.synthetic);
+ host->ShutdownAndDestroyWidget(true);
+}
+
// When wheel scroll latching is enabled, wheel end events are not sent
// immediately, instead we start a timer to see if momentum phase of the scroll
// starts or not.
@@ -1462,26 +1538,22 @@ TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
MockRenderWidgetHostImpl* host =
MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
- process_host->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
// Send an initial wheel event for scrolling by 3 lines.
NSEvent* wheelEvent1 =
MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
[view->cocoa_view() scrollWheel:wheelEvent1];
- ASSERT_EQ(1U, process_host->sink().message_count());
- process_host->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseWheel", GetMessageNames(events));
- // Indicate that the wheel event was unhandled.
- InputEventAck unhandled_ack(InputEventAckSource::COMPOSITOR_THREAD,
- blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- std::unique_ptr<IPC::Message> response1(
- new InputHostMsg_HandleInputEvent_ACK(0, unhandled_ack));
- host->OnMessageReceived(*response1);
+ events.clear();
+ events = host->GetAndResetDispatchedMessages();
// Both GSB and GSU will be sent since GestureEventQueue allows multiple
// in-flight events.
- ASSERT_EQ("GestureScrollBegin GestureScrollUpdate",
- GetInputMessageTypes(process_host));
+ ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));
// Send a wheel event with phaseEnded. When wheel scroll latching is enabled
// the event will be dropped and the mouse_wheel_end_dispatch_timer_ will
@@ -1489,9 +1561,10 @@ TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
NSEvent* wheelEvent2 =
MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
[view->cocoa_view() scrollWheel:wheelEvent2];
- ASSERT_EQ(0U, process_host->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+ ASSERT_EQ(0U, events.size());
DCHECK(view->HasPendingWheelEndEventForTesting());
- process_host->sink().ClearMessages();
host->ShutdownAndDestroyWidget(true);
@@ -1521,26 +1594,23 @@ TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
MockRenderWidgetHostImpl* host =
MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
- process_host->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
// Send an initial wheel event for scrolling by 3 lines.
NSEvent* wheelEvent1 =
MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
[view->cocoa_view() scrollWheel:wheelEvent1];
- ASSERT_EQ(1U, process_host->sink().message_count());
- process_host->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseWheel", GetMessageNames(events));
// Indicate that the wheel event was unhandled.
- InputEventAck unhandled_ack(InputEventAckSource::COMPOSITOR_THREAD,
- blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- std::unique_ptr<IPC::Message> response1(
- new InputHostMsg_HandleInputEvent_ACK(0, unhandled_ack));
- host->OnMessageReceived(*response1);
+ events.clear();
+ events = host->GetAndResetDispatchedMessages();
// Both GSB and GSU will be sent since GestureEventQueue allows multiple
// in-flight events.
- ASSERT_EQ("GestureScrollBegin GestureScrollUpdate",
- GetInputMessageTypes(process_host));
+ ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));
// Send a wheel event with phaseEnded. When wheel scroll latching is enabled
// the event will be dropped and the mouse_wheel_end_dispatch_timer_ will
@@ -1548,9 +1618,10 @@ TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
NSEvent* wheelEvent2 =
MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
[view->cocoa_view() scrollWheel:wheelEvent2];
- ASSERT_EQ(0U, process_host->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+ ASSERT_EQ(0U, events.size());
DCHECK(view->HasPendingWheelEndEventForTesting());
- process_host->sink().ClearMessages();
// Send a wheel event with momentum phase started, this should stop the wheel
// end dispatch timer.
@@ -1558,9 +1629,10 @@ TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
MockScrollWheelEventWithMomentumPhase(@selector(phaseBegan), 3);
ASSERT_TRUE(wheelEvent3);
[view->cocoa_view() scrollWheel:wheelEvent3];
- ASSERT_EQ(1U, process_host->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseWheel", GetMessageNames(events));
DCHECK(!view->HasPendingWheelEndEventForTesting());
- process_host->sink().ClearMessages();
host->ShutdownAndDestroyWidget(true);
}
@@ -1579,26 +1651,23 @@ TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
MockRenderWidgetHostImpl* host =
MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
- process_host->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
// Send an initial wheel event for scrolling by 3 lines.
NSEvent* wheelEvent1 =
MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
[view->cocoa_view() scrollWheel:wheelEvent1];
- ASSERT_EQ(1U, process_host->sink().message_count());
- process_host->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseWheel", GetMessageNames(events));
// Indicate that the wheel event was unhandled.
- InputEventAck unhandled_ack(InputEventAckSource::COMPOSITOR_THREAD,
- blink::WebInputEvent::kMouseWheel,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- std::unique_ptr<IPC::Message> response1(
- new InputHostMsg_HandleInputEvent_ACK(0, unhandled_ack));
- host->OnMessageReceived(*response1);
+ events.clear();
// Both GSB and GSU will be sent since GestureEventQueue allows multiple
// in-flight events.
- ASSERT_EQ("GestureScrollBegin GestureScrollUpdate",
- GetInputMessageTypes(process_host));
+ events = host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));
// Send a wheel event with phaseEnded. When wheel scroll latching is enabled
// the event will be dropped and the mouse_wheel_end_dispatch_timer_ will
@@ -1606,9 +1675,10 @@ TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
NSEvent* wheelEvent2 =
MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
[view->cocoa_view() scrollWheel:wheelEvent2];
- ASSERT_EQ(0U, process_host->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+ ASSERT_EQ(0U, events.size());
DCHECK(view->HasPendingWheelEndEventForTesting());
- process_host->sink().ClearMessages();
// Send a wheel event with phase started, this should stop the wheel end
// dispatch timer and dispatch the pending wheel end event for the previous
@@ -1617,10 +1687,10 @@ TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
ASSERT_TRUE(wheelEvent3);
[view->cocoa_view() scrollWheel:wheelEvent3];
- ASSERT_EQ("MouseWheel GestureScrollEnd MouseWheel",
- GetInputMessageTypes(process_host));
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events));
DCHECK(!view->HasPendingWheelEndEventForTesting());
- process_host->sink().ClearMessages();
host->ShutdownAndDestroyWidget(true);
}
@@ -1643,7 +1713,7 @@ class RenderWidgetHostViewMacPinchTest : public RenderWidgetHostViewMacTest {
delegate_.get(), process_host_.get(), routing_id));
view_ = new RenderWidgetHostViewMac(host_.get(), false);
cocoa_view_.reset([view_->cocoa_view() retain]);
- process_host_->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
}
void TearDown() override {
@@ -1656,31 +1726,15 @@ class RenderWidgetHostViewMacPinchTest : public RenderWidgetHostViewMacTest {
RenderWidgetHostViewMacTest::TearDown();
}
- bool ZoomDisabledForPinchUpdateMessage() {
- const IPC::Message* message = nullptr;
- // The first message may be a PinchBegin. Go for the second message if
- // there are two.
- switch (process_host_->sink().message_count()) {
- case 1:
- message = process_host_->sink().GetMessageAt(0);
- break;
- case 2:
- message = process_host_->sink().GetMessageAt(1);
- break;
- default:
- NOTREACHED();
- break;
- }
- DCHECK(message);
- std::tuple<IPC::WebInputEventPointer,
- std::vector<IPC::WebInputEventPointer>, ui::LatencyInfo,
- InputEventDispatchType>
- data;
- InputMsg_HandleInputEvent::Read(message, &data);
- IPC::WebInputEventPointer ipc_event = std::get<0>(data);
- const blink::WebGestureEvent* gesture_event =
- static_cast<const blink::WebGestureEvent*>(ipc_event);
- return gesture_event->data.pinch_update.zoom_disabled;
+ bool ZoomDisabledForPinchUpdateMessage(
+ const MockWidgetInputHandler::MessageVector& events) {
+ MockWidgetInputHandler::DispatchedEventMessage* event =
+ events[events.size() - 1]->ToEvent();
+ EXPECT_TRUE(event);
+
+ return static_cast<const blink::WebGestureEvent*>(
+ event->Event()->web_event.get())
+ ->data.pinch_update.zoom_disabled;
}
bool ShouldSendGestureEvents() {
@@ -1719,13 +1773,6 @@ class RenderWidgetHostViewMacPinchTest : public RenderWidgetHostViewMacTest {
};
TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
- // We'll use this IPC message to ack events.
- InputEventAck ack(InputEventAckSource::COMPOSITOR_THREAD,
- blink::WebInputEvent::kGesturePinchUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- std::unique_ptr<IPC::Message> response(
- new InputHostMsg_HandleInputEvent_ACK(0, ack));
-
// Do a gesture that crosses the threshold.
{
NSEvent* pinchUpdateEvents[3] = {
@@ -1735,33 +1782,38 @@ TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
};
SendBeginEvent();
- EXPECT_EQ(0U, process_host_->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host_->GetAndResetDispatchedMessages();
+
+ EXPECT_EQ(0U, events.size());
// No zoom is sent for the first update event.
[cocoa_view_ magnifyWithEvent:pinchUpdateEvents[0]];
- host_->OnMessageReceived(*response);
- EXPECT_EQ(2U, process_host_->sink().message_count());
- EXPECT_TRUE(ZoomDisabledForPinchUpdateMessage());
- process_host_->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("GesturePinchBegin GesturePinchUpdate", GetMessageNames(events));
+ EXPECT_TRUE(ZoomDisabledForPinchUpdateMessage(events));
// The second update event crosses the threshold of 0.4, and so zoom is no
// longer disabled.
[cocoa_view_ magnifyWithEvent:pinchUpdateEvents[1]];
- EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage());
- host_->OnMessageReceived(*response);
- EXPECT_EQ(1U, process_host_->sink().message_count());
- process_host_->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("GesturePinchUpdate", GetMessageNames(events));
+ EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage(events));
// The third update still has zoom enabled.
[cocoa_view_ magnifyWithEvent:pinchUpdateEvents[2]];
- EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage());
- host_->OnMessageReceived(*response);
- EXPECT_EQ(1U, process_host_->sink().message_count());
- process_host_->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("GesturePinchUpdate", GetMessageNames(events));
+ EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage(events));
SendEndEvent();
- EXPECT_EQ(1U, process_host_->sink().message_count());
- process_host_->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("GesturePinchEnd", GetMessageNames(events));
}
// Do a gesture that doesn't cross the threshold, but happens when we're not
@@ -1772,18 +1824,22 @@ TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
view_->page_at_minimum_scale_ = false;
SendBeginEvent();
- EXPECT_EQ(0U, process_host_->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
// Expect that a zoom happen because the time threshold has not passed.
[cocoa_view_ magnifyWithEvent:pinchUpdateEvent];
- EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage());
- host_->OnMessageReceived(*response);
- EXPECT_EQ(2U, process_host_->sink().message_count());
- process_host_->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("GesturePinchBegin GesturePinchUpdate", GetMessageNames(events));
+ EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage(events));
SendEndEvent();
- EXPECT_EQ(1U, process_host_->sink().message_count());
- process_host_->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("GesturePinchEnd", GetMessageNames(events));
}
// Do a gesture again, after the page scale is no longer at one, and ensure
@@ -1794,7 +1850,10 @@ TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
view_->page_at_minimum_scale_ = true;
SendBeginEvent();
- EXPECT_EQ(0U, process_host_->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
// Get back to zoom one right after the begin event. This should still keep
// the thresholding in place (it is latched at the begin event).
@@ -1802,14 +1861,15 @@ TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
// Expect that zoom be disabled because the time threshold has passed.
[cocoa_view_ magnifyWithEvent:pinchUpdateEvent];
- EXPECT_EQ(2U, process_host_->sink().message_count());
- EXPECT_TRUE(ZoomDisabledForPinchUpdateMessage());
- host_->OnMessageReceived(*response);
- process_host_->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("GesturePinchBegin GesturePinchUpdate", GetMessageNames(events));
+ EXPECT_TRUE(ZoomDisabledForPinchUpdateMessage(events));
SendEndEvent();
- EXPECT_EQ(1U, process_host_->sink().message_count());
- process_host_->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("GesturePinchEnd", GetMessageNames(events));
}
}
@@ -1871,20 +1931,24 @@ class InputMethodMacTest : public RenderWidgetHostViewMacTest {
void SetUp() override {
RenderWidgetHostViewMacTest::SetUp();
+ process_host_ = new MockRenderProcessHost(&browser_context_);
+ process_host_->Init();
+ widget_ = MockRenderWidgetHostImpl::Create(
+ &delegate_, process_host_, process_host_->GetNextRoutingID());
+ view_ = new RenderWidgetHostViewMac(widget_, false);
// Initializing a child frame's view.
- child_process_host_ = new MockRenderProcessHost(&browser_context_);
- RenderWidgetHostDelegate* rwh_delegate =
- RenderWidgetHostImpl::From(rvh()->GetWidget())->delegate();
+ child_process_host_ = new MockRenderProcessHost(&child_browser_context_);
+ child_process_host_->Init();
child_widget_ = MockRenderWidgetHostImpl::Create(
- rwh_delegate, child_process_host_,
+ &delegate_, child_process_host_,
child_process_host_->GetNextRoutingID());
child_view_ = new TestRenderWidgetHostView(child_widget_);
- text_input_manager_ = rwh_delegate->GetTextInputManager();
- tab_widget_ = RenderWidgetHostImpl::From(rvh()->GetWidget());
+ base::RunLoop().RunUntilIdle();
}
void TearDown() override {
+ widget_->ShutdownAndDestroyWidget(true);
child_widget_->ShutdownAndDestroyWidget(true);
RenderWidgetHostViewMacTest::TearDown();
@@ -1899,19 +1963,26 @@ class InputMethodMacTest : public RenderWidgetHostViewMacTest {
IPC::TestSink& tab_sink() { return process()->sink(); }
IPC::TestSink& child_sink() { return child_process_host_->sink(); }
- TextInputManager* text_input_manager() { return text_input_manager_; }
- RenderWidgetHostViewBase* tab_view() { return rwhv_mac_; }
- RenderWidgetHostImpl* tab_widget() { return tab_widget_; }
+ TextInputManager* text_input_manager() {
+ return delegate_.GetTextInputManager();
+ }
+ RenderWidgetHostViewBase* tab_view() { return view_; }
+ RenderWidgetHostImpl* tab_widget() { return widget_; }
+ RenderWidgetHostViewCocoa* tab_cocoa_view() { return view_->cocoa_view(); }
protected:
+ MockRenderProcessHost* process_host_;
+ MockRenderWidgetHostImpl* widget_;
+ MockRenderWidgetHostDelegate delegate_;
+ RenderWidgetHostViewMac* view_;
+
MockRenderProcessHost* child_process_host_;
- RenderWidgetHostImpl* child_widget_;
+ MockRenderWidgetHostImpl* child_widget_;
TestRenderWidgetHostView* child_view_;
private:
TestBrowserContext browser_context_;
- TextInputManager* text_input_manager_;
- RenderWidgetHostImpl* tab_widget_;
+ TestBrowserContext child_browser_context_;
DISALLOW_COPY_AND_ASSIGN(InputMethodMacTest);
};
@@ -1925,18 +1996,19 @@ TEST_F(InputMethodMacTest, UnmarkText) {
// tests as well). We should observe an IPC being sent to the |child_widget_|.
SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
- child_sink().ClearMessages();
- [rwhv_cocoa_ unmarkText];
- EXPECT_TRUE(!!child_sink().GetFirstMessageMatching(
- InputMsg_ImeFinishComposingText::ID));
+ [tab_cocoa_view() unmarkText];
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ child_widget_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("FinishComposingText", GetMessageNames(events));
// Repeat the same steps for the tab's view .
SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
- tab_sink().ClearMessages();
- [rwhv_cocoa_ unmarkText];
- EXPECT_TRUE(!!tab_sink().GetFirstMessageMatching(
- InputMsg_ImeFinishComposingText::ID));
+ [tab_cocoa_view() unmarkText];
+ base::RunLoop().RunUntilIdle();
+ events = widget_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("FinishComposingText", GetMessageNames(events));
}
// This test makes sure that calling setMarkedText on the cocoa view will lead
@@ -1952,22 +2024,23 @@ TEST_F(InputMethodMacTest, SetMarkedText) {
// should observe an IPC being sent to the |child_widget_|.
SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
- child_sink().ClearMessages();
- [rwhv_cocoa_ setMarkedText:text
- selectedRange:selectedRange
- replacementRange:replacementRange];
- EXPECT_TRUE(
- !!child_sink().GetFirstMessageMatching(InputMsg_ImeSetComposition::ID));
+ [tab_cocoa_view() setMarkedText:text
+ selectedRange:selectedRange
+ replacementRange:replacementRange];
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ child_widget_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("SetComposition", GetMessageNames(events));
// Repeat the same steps for the tab's view.
SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
- tab_sink().ClearMessages();
- [rwhv_cocoa_ setMarkedText:text
- selectedRange:selectedRange
- replacementRange:replacementRange];
- EXPECT_TRUE(
- !!tab_sink().GetFirstMessageMatching(InputMsg_ImeSetComposition::ID));
+ [tab_cocoa_view() setMarkedText:text
+ selectedRange:selectedRange
+ replacementRange:replacementRange];
+ base::RunLoop().RunUntilIdle();
+ events = widget_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("SetComposition", GetMessageNames(events));
}
// This test verifies that calling insertText on the cocoa view will lead to a
@@ -1982,16 +2055,19 @@ TEST_F(InputMethodMacTest, InsertText) {
// should observe an IPC being sent to the |child_widget_|.
SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
- child_sink().ClearMessages();
- [rwhv_cocoa_ insertText:text replacementRange:replacementRange];
- EXPECT_TRUE(
- !!child_sink().GetFirstMessageMatching(InputMsg_ImeCommitText::ID));
+ [tab_cocoa_view() insertText:text replacementRange:replacementRange];
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ child_widget_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("CommitText", GetMessageNames(events));
// Repeat the same steps for the tab's view.
SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
- [rwhv_cocoa_ insertText:text replacementRange:replacementRange];
- EXPECT_TRUE(!!tab_sink().GetFirstMessageMatching(InputMsg_ImeCommitText::ID));
+ [tab_cocoa_view() insertText:text replacementRange:replacementRange];
+ base::RunLoop().RunUntilIdle();
+ events = widget_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("CommitText", GetMessageNames(events));
}
// This test makes sure that calling finishComposingText on the cocoa view will
@@ -2007,28 +2083,29 @@ TEST_F(InputMethodMacTest, FinishComposingText) {
// an IPC being sent to the |child_widget_|.
SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
- child_sink().ClearMessages();
// In order to finish composing text, we must first have some marked text. So,
// we will first call setMarkedText on cocoa view. This would lead to a set
// composition IPC in the sink, but it doesn't matter since we will be looking
// for a finish composing text IPC for this test.
- [rwhv_cocoa_ setMarkedText:text
- selectedRange:selectedRange
- replacementRange:replacementRange];
- [rwhv_cocoa_ finishComposingText];
- EXPECT_TRUE(!!child_sink().GetFirstMessageMatching(
- InputMsg_ImeFinishComposingText::ID));
+ [tab_cocoa_view() setMarkedText:text
+ selectedRange:selectedRange
+ replacementRange:replacementRange];
+ [tab_cocoa_view() finishComposingText];
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ child_widget_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("SetComposition FinishComposingText", GetMessageNames(events));
// Repeat the same steps for the tab's view.
SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
- tab_sink().ClearMessages();
- [rwhv_cocoa_ setMarkedText:text
- selectedRange:selectedRange
- replacementRange:replacementRange];
- [rwhv_cocoa_ finishComposingText];
- EXPECT_TRUE(!!tab_sink().GetFirstMessageMatching(
- InputMsg_ImeFinishComposingText::ID));
+ [tab_cocoa_view() setMarkedText:text
+ selectedRange:selectedRange
+ replacementRange:replacementRange];
+ [tab_cocoa_view() finishComposingText];
+ base::RunLoop().RunUntilIdle();
+ events = widget_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("SetComposition FinishComposingText", GetMessageNames(events));
}
// This test creates a test view to mimic a child frame's view and verifies that
@@ -2042,20 +2119,37 @@ TEST_F(InputMethodMacTest, ImeCancelCompositionForAllViews) {
NSRange replacementRange = NSMakeRange(0, 1);
// Make Cocoa view assume there is marked text.
- [rwhv_cocoa_ setMarkedText:text
- selectedRange:selectedRange
- replacementRange:replacementRange];
- EXPECT_TRUE([rwhv_cocoa_ hasMarkedText]);
+ [tab_cocoa_view() setMarkedText:text
+ selectedRange:selectedRange
+ replacementRange:replacementRange];
+ EXPECT_TRUE([tab_cocoa_view() hasMarkedText]);
child_view_->ImeCancelComposition();
- EXPECT_FALSE([rwhv_cocoa_ hasMarkedText]);
+ EXPECT_FALSE([tab_cocoa_view() hasMarkedText]);
// Repeat for the tab's view.
- [rwhv_cocoa_ setMarkedText:text
- selectedRange:selectedRange
- replacementRange:replacementRange];
- EXPECT_TRUE([rwhv_cocoa_ hasMarkedText]);
- rwhv_mac_->ImeCancelComposition();
- EXPECT_FALSE([rwhv_cocoa_ hasMarkedText]);
+ [tab_cocoa_view() setMarkedText:text
+ selectedRange:selectedRange
+ replacementRange:replacementRange];
+ EXPECT_TRUE([tab_cocoa_view() hasMarkedText]);
+ tab_view()->ImeCancelComposition();
+ EXPECT_FALSE([tab_cocoa_view() hasMarkedText]);
+}
+
+// This test verifies that calling FocusedNodeChanged() on
+// RenderWidgetHostViewMac calls cancelComposition on the Cocoa view.
+TEST_F(InputMethodMacTest, FocusedNodeChanged) {
+ // Some values for the call to setMarkedText.
+ base::scoped_nsobject<NSString> text(
+ [[NSString alloc] initWithString:@"sample text"]);
+ NSRange selectedRange = NSMakeRange(0, 1);
+ NSRange replacementRange = NSMakeRange(0, 1);
+
+ [tab_cocoa_view() setMarkedText:text
+ selectedRange:selectedRange
+ replacementRange:replacementRange];
+ EXPECT_TRUE([tab_cocoa_view() hasMarkedText]);
+ tab_view()->FocusedNodeChanged(true, gfx::Rect());
+ EXPECT_FALSE([tab_cocoa_view() hasMarkedText]);
}
// This test verifies that when a RenderWidgetHostView changes its
@@ -2069,102 +2163,102 @@ TEST_F(InputMethodMacTest, MonitorCompositionRangeForActiveWidget) {
// be asked to start monitoring composition info.
base::scoped_nsobject<CocoaTestHelperWindow> window(
[[CocoaTestHelperWindow alloc] init]);
- [[window contentView] addSubview:rwhv_cocoa_];
- [window makeFirstResponder:rwhv_cocoa_];
- EXPECT_TRUE(rwhv_mac_->HasFocus());
+ [[window contentView] addSubview:tab_cocoa_view()];
+ [window makeFirstResponder:tab_cocoa_view()];
+ EXPECT_TRUE(view_->HasFocus());
TextInputState state;
state.type = ui::TEXT_INPUT_TYPE_TEXT;
- tab_sink().ClearMessages();
// Make the tab's widget active.
- rwhv_mac_->TextInputStateChanged(state);
+ view_->TextInputStateChanged(state);
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ widget_->GetAndResetDispatchedMessages();
// The tab's widget must have received an IPC regarding composition updates.
- const IPC::Message* composition_request_msg_for_tab =
- tab_sink().GetUniqueMessageMatching(
- InputMsg_RequestCompositionUpdates::ID);
- EXPECT_TRUE(composition_request_msg_for_tab);
+ EXPECT_EQ("SetFocus RequestCompositionUpdates", GetMessageNames(events));
// The message should ask for monitoring updates, but no immediate update.
- InputMsg_RequestCompositionUpdates::Param tab_msg_params;
- InputMsg_RequestCompositionUpdates::Read(composition_request_msg_for_tab,
- &tab_msg_params);
- bool is_tab_msg_for_immediate_request = std::get<0>(tab_msg_params);
- bool is_tab_msg_for_monitor_request = std::get<1>(tab_msg_params);
- EXPECT_FALSE(is_tab_msg_for_immediate_request);
- EXPECT_TRUE(is_tab_msg_for_monitor_request);
- tab_sink().ClearMessages();
- child_sink().ClearMessages();
+ MockWidgetInputHandler::DispatchedRequestCompositionUpdatesMessage* message =
+ events.at(1)->ToRequestCompositionUpdates();
+ EXPECT_FALSE(message->immediate_request());
+ EXPECT_TRUE(message->monitor_request());
// Now make the child view active.
child_view_->TextInputStateChanged(state);
// The tab should receive another IPC for composition updates.
- composition_request_msg_for_tab = tab_sink().GetUniqueMessageMatching(
- InputMsg_RequestCompositionUpdates::ID);
- EXPECT_TRUE(composition_request_msg_for_tab);
-
+ base::RunLoop().RunUntilIdle();
+ events = widget_->GetAndResetDispatchedMessages();
+ // The tab's widget must have received an IPC regarding composition updates.
+ EXPECT_EQ("RequestCompositionUpdates", GetMessageNames(events));
// This time, the tab should have been asked to stop monitoring (and no
// immediate updates).
- InputMsg_RequestCompositionUpdates::Read(composition_request_msg_for_tab,
- &tab_msg_params);
- is_tab_msg_for_immediate_request = std::get<0>(tab_msg_params);
- is_tab_msg_for_monitor_request = std::get<1>(tab_msg_params);
- EXPECT_FALSE(is_tab_msg_for_immediate_request);
- EXPECT_FALSE(is_tab_msg_for_monitor_request);
- tab_sink().ClearMessages();
+ message = events.at(0)->ToRequestCompositionUpdates();
+ EXPECT_FALSE(message->immediate_request());
+ EXPECT_FALSE(message->monitor_request());
// The child too must have received an IPC for composition updates.
- const IPC::Message* composition_request_msg_for_child =
- child_sink().GetUniqueMessageMatching(
- InputMsg_RequestCompositionUpdates::ID);
- EXPECT_TRUE(composition_request_msg_for_child);
+ events = child_widget_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("RequestCompositionUpdates", GetMessageNames(events));
// Verify that the message is asking for monitoring to start; but no immediate
// updates.
- InputMsg_RequestCompositionUpdates::Param child_msg_params;
- InputMsg_RequestCompositionUpdates::Read(composition_request_msg_for_child,
- &child_msg_params);
- bool is_child_msg_for_immediate_request = std::get<0>(child_msg_params);
- bool is_child_msg_for_monitor_request = std::get<1>(child_msg_params);
- EXPECT_FALSE(is_child_msg_for_immediate_request);
- EXPECT_TRUE(is_child_msg_for_monitor_request);
- child_sink().ClearMessages();
+ message = events.at(0)->ToRequestCompositionUpdates();
+ EXPECT_FALSE(message->immediate_request());
+ EXPECT_TRUE(message->monitor_request());
// Make the tab view active again.
- rwhv_mac_->TextInputStateChanged(state);
+ view_->TextInputStateChanged(state);
+
+ base::RunLoop().RunUntilIdle();
+ events = child_widget_->GetAndResetDispatchedMessages();
// Verify that the child received another IPC for composition updates.
- composition_request_msg_for_child = child_sink().GetUniqueMessageMatching(
- InputMsg_RequestCompositionUpdates::ID);
- EXPECT_TRUE(composition_request_msg_for_child);
+ EXPECT_EQ("RequestCompositionUpdates", GetMessageNames(events));
// Verify that this IPC is asking for no monitoring or immediate updates.
- InputMsg_RequestCompositionUpdates::Read(composition_request_msg_for_child,
- &child_msg_params);
- is_child_msg_for_immediate_request = std::get<0>(child_msg_params);
- is_child_msg_for_monitor_request = std::get<1>(child_msg_params);
- EXPECT_FALSE(is_child_msg_for_immediate_request);
- EXPECT_FALSE(is_child_msg_for_monitor_request);
+ message = events.at(0)->ToRequestCompositionUpdates();
+ EXPECT_FALSE(message->immediate_request());
+ EXPECT_FALSE(message->monitor_request());
}
// Ensure RenderWidgetHostViewMac claims hotkeys when AppKit spams the UI with
// -performKeyEquivalent:, but only when the window is key.
TEST_F(RenderWidgetHostViewMacTest, ForwardKeyEquivalentsOnlyIfKey) {
+ MockRenderWidgetHostDelegate delegate;
+ TestBrowserContext browser_context;
+
+ MockRenderProcessHost* process_host =
+ new MockRenderProcessHost(&browser_context);
+ process_host->Init();
+
+ int32_t routing_id = process_host->GetNextRoutingID();
+ // Owned by its |cocoa_view()|.
+ MockRenderWidgetHostImpl* host =
+ MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
+ RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
+
+ EXPECT_CALL(*host, Focus()).Times(2);
+ EXPECT_CALL(*host, Blur());
+
// This test needs an NSWindow. |rwhv_cocoa_| isn't in one, but going
// fullscreen conveniently puts it in one.
- EXPECT_FALSE([rwhv_cocoa_ window]);
- rwhv_mac_->InitAsFullscreen(nullptr);
- NSWindow* window = [rwhv_cocoa_ window];
+ EXPECT_FALSE([view->cocoa_view() window]);
+ view->InitAsFullscreen(nullptr);
+ NSWindow* window = [view->cocoa_view() window];
EXPECT_TRUE(window);
-
- MockRenderProcessHost* process_host = test_rvh()->GetProcess();
- process_host->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host->GetAndResetDispatchedMessages();
ui::test::ScopedFakeNSWindowFocus key_window_faker;
EXPECT_FALSE([window isKeyWindow]);
- EXPECT_EQ(0U, process_host->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+
+ EXPECT_EQ(0U, events.size());
// Cmd+x.
NSEvent* key_down =
@@ -2175,20 +2269,27 @@ TEST_F(RenderWidgetHostViewMacTest, ForwardKeyEquivalentsOnlyIfKey) {
// other parts of the UI to handle it, but in the test they should all say
// "NO" as well.
EXPECT_FALSE([window performKeyEquivalent:key_down]);
- EXPECT_EQ(0U, process_host->sink().message_count());
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
// Make key and send again. Event should be seen.
[window makeKeyWindow];
EXPECT_TRUE([window isKeyWindow]);
- process_host->sink().ClearMessages(); // Ignore the focus messages.
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
// -performKeyEquivalent: now returns YES to prevent further propagation, and
// the event is sent to the renderer.
EXPECT_TRUE([window performKeyEquivalent:key_down]);
- EXPECT_EQ(2U, process_host->sink().message_count());
- EXPECT_EQ("RawKeyDown Char", GetInputMessageTypes(process_host));
+ base::RunLoop().RunUntilIdle();
+ events = host->GetAndResetDispatchedMessages();
+ EXPECT_EQ("RawKeyDown Char", GetMessageNames(events));
- rwhv_mac_->release_pepper_fullscreen_window_for_testing();
+ view->release_pepper_fullscreen_window_for_testing();
+
+ // Clean up.
+ host->ShutdownAndDestroyWidget(true);
}
TEST_F(RenderWidgetHostViewMacTest, ClearCompositorFrame) {
diff --git a/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm b/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm
index b742d3672f7..3f9607c42c3 100644
--- a/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm
+++ b/chromium/content/browser/renderer_host/text_input_client_mac_unittest.mm
@@ -61,7 +61,7 @@ class TextInputClientMacTest : public testing::Test {
int32_t routing_id = rph->GetNextRoutingID();
mojom::WidgetPtr widget;
mock_widget_impl_ =
- base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
widget_.reset(new RenderWidgetHostImpl(&delegate_, rph, routing_id,
std::move(widget), false));
diff --git a/chromium/content/browser/renderer_host/ui_events_helper.cc b/chromium/content/browser/renderer_host/ui_events_helper.cc
index 9bfc3bbf55d..5e4c6f96377 100644
--- a/chromium/content/browser/renderer_host/ui_events_helper.cc
+++ b/chromium/content/browser/renderer_host/ui_events_helper.cc
@@ -77,7 +77,7 @@ bool MakeUITouchEventsFromWebTouchEvents(
location = point.PositionInWidget();
else
location = point.PositionInScreen();
- auto uievent = base::MakeUnique<ui::TouchEvent>(
+ 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),
diff --git a/chromium/content/browser/renderer_host/ui_events_helper.h b/chromium/content/browser/renderer_host/ui_events_helper.h
index 2123a2a26fd..147c7d0b0c5 100644
--- a/chromium/content/browser/renderer_host/ui_events_helper.h
+++ b/chromium/content/browser/renderer_host/ui_events_helper.h
@@ -10,7 +10,7 @@
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
namespace ui {
class TouchEvent;
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 266d25a8963..2ab649e4956 100644
--- a/chromium/content/browser/renderer_host/web_database_host_impl.cc
+++ b/chromium/content/browser/renderer_host/web_database_host_impl.cc
@@ -69,10 +69,10 @@ WebDatabaseHostImpl::~WebDatabaseHostImpl() {
void WebDatabaseHostImpl::Create(
int process_id,
scoped_refptr<storage::DatabaseTracker> db_tracker,
- content::mojom::WebDatabaseHostRequest request) {
+ blink::mojom::WebDatabaseHostRequest request) {
DCHECK(db_tracker->task_runner()->RunsTasksInCurrentSequence());
mojo::MakeStrongBinding(
- base::MakeUnique<WebDatabaseHostImpl>(process_id, std::move(db_tracker)),
+ std::make_unique<WebDatabaseHostImpl>(process_id, std::move(db_tracker)),
std::move(request));
}
@@ -337,7 +337,7 @@ void WebDatabaseHostImpl::OnDatabaseSizeChanged(
}
GetWebDatabase().UpdateSize(
- url::Origin(storage::GetOriginFromIdentifier(origin_identifier)),
+ url::Origin::Create(storage::GetOriginFromIdentifier(origin_identifier)),
database_name, database_size);
}
@@ -347,11 +347,11 @@ void WebDatabaseHostImpl::OnDatabaseScheduledForDeletion(
DCHECK(db_tracker_->task_runner()->RunsTasksInCurrentSequence());
GetWebDatabase().CloseImmediately(
- url::Origin(storage::GetOriginFromIdentifier(origin_identifier)),
+ url::Origin::Create(storage::GetOriginFromIdentifier(origin_identifier)),
database_name);
}
-content::mojom::WebDatabase& WebDatabaseHostImpl::GetWebDatabase() {
+blink::mojom::WebDatabase& WebDatabaseHostImpl::GetWebDatabase() {
DCHECK(db_tracker_->task_runner()->RunsTasksInCurrentSequence());
if (!database_provider_) {
// The interface binding needs to occur on the UI thread, as we can
@@ -359,7 +359,7 @@ content::mojom::WebDatabase& WebDatabaseHostImpl::GetWebDatabase() {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(
- [](int process_id, content::mojom::WebDatabaseRequest request) {
+ [](int process_id, blink::mojom::WebDatabaseRequest request) {
RenderProcessHost* host = RenderProcessHost::FromID(process_id);
if (host) {
content::BindInterface(host, std::move(request));
diff --git a/chromium/content/browser/renderer_host/web_database_host_impl.h b/chromium/content/browser/renderer_host/web_database_host_impl.h
index c3da45de77f..aa4d6874bcd 100644
--- a/chromium/content/browser/renderer_host/web_database_host_impl.h
+++ b/chromium/content/browser/renderer_host/web_database_host_impl.h
@@ -8,10 +8,10 @@
#include <string>
#include "base/strings/string16.h"
-#include "content/common/web_database.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "storage/browser/database/database_tracker.h"
#include "storage/common/quota/quota_types.h"
+#include "third_party/WebKit/public/platform/modules/webdatabase/web_database.mojom.h"
namespace url {
class Origin;
@@ -19,7 +19,7 @@ class Origin;
namespace content {
-class WebDatabaseHostImpl : public content::mojom::WebDatabaseHost,
+class WebDatabaseHostImpl : public blink::mojom::WebDatabaseHost,
public storage::DatabaseTracker::Observer {
public:
WebDatabaseHostImpl(int proess_id,
@@ -28,10 +28,10 @@ class WebDatabaseHostImpl : public content::mojom::WebDatabaseHost,
static void Create(int process_id,
scoped_refptr<storage::DatabaseTracker> db_tracker,
- content::mojom::WebDatabaseHostRequest request);
+ blink::mojom::WebDatabaseHostRequest request);
private:
- // content::mojom::WebDatabaseHost:
+ // blink::mojom::WebDatabaseHost:
void OpenFile(const base::string16& vfs_file_name,
int32_t desired_flags,
OpenFileCallback callback) override;
@@ -84,7 +84,7 @@ class WebDatabaseHostImpl : public content::mojom::WebDatabaseHost,
// Helper function to get the mojo interface for the WebDatabase on the
// render process. Creates the WebDatabase connection if it does not already
// exist.
- content::mojom::WebDatabase& GetWebDatabase();
+ blink::mojom::WebDatabase& GetWebDatabase();
// Our render process host ID, used to bind to the correct render process.
const int process_id_;
@@ -97,7 +97,7 @@ class WebDatabaseHostImpl : public content::mojom::WebDatabaseHost,
storage::DatabaseConnections database_connections_;
// Interface to the render process WebDatabase.
- content::mojom::WebDatabasePtr database_provider_;
+ blink::mojom::WebDatabasePtr database_provider_;
// The database tracker for the current browser context.
const scoped_refptr<storage::DatabaseTracker> db_tracker_;
diff --git a/chromium/content/browser/renderer_interface_binders.cc b/chromium/content/browser/renderer_interface_binders.cc
new file mode 100644
index 00000000000..082e5c990dc
--- /dev/null
+++ b/chromium/content/browser/renderer_interface_binders.cc
@@ -0,0 +1,163 @@
+// Copyright 2017 The Chromium Authors. 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_interface_binders.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "content/browser/background_fetch/background_fetch_service_impl.h"
+#include "content/browser/dedicated_worker/dedicated_worker_host.h"
+#include "content/browser/notifications/platform_notification_context_impl.h"
+#include "content/browser/payments/payment_manager.h"
+#include "content/browser/permissions/permission_service_context.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/browser/websockets/websocket_manager.h"
+#include "content/public/browser/browser_context.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 "services/device/public/interfaces/constants.mojom.h"
+#include "services/device/public/interfaces/vibration_manager.mojom.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/shape_detection/public/interfaces/barcodedetection.mojom.h"
+#include "services/shape_detection/public/interfaces/constants.mojom.h"
+#include "services/shape_detection/public/interfaces/facedetection_provider.mojom.h"
+#include "services/shape_detection/public/interfaces/textdetection.mojom.h"
+#include "third_party/WebKit/public/platform/modules/notifications/notification_service.mojom.h"
+#include "url/origin.h"
+
+namespace content {
+namespace {
+
+// A holder for a parameterized BinderRegistry for content-layer interfaces
+// exposed to web workers.
+class RendererInterfaceBinders {
+ public:
+ RendererInterfaceBinders() { InitializeParameterizedBinderRegistry(); }
+
+ // Bind an interface request |interface_pipe| for |interface_name| received
+ // from a web worker with origin |origin| hosted in the renderer |host|.
+ void BindInterface(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe,
+ RenderProcessHost* host,
+ const url::Origin& origin) {
+ if (parameterized_binder_registry_.TryBindInterface(
+ interface_name, &interface_pipe, host, origin)) {
+ return;
+ }
+
+ GetContentClient()->browser()->BindInterfaceRequestFromWorker(
+ host, origin, interface_name, std::move(interface_pipe));
+ }
+
+ // Try binding an interface request |interface_pipe| for |interface_name|
+ // received from |frame|.
+ bool TryBindInterface(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle* interface_pipe,
+ RenderFrameHost* frame) {
+ return parameterized_binder_registry_.TryBindInterface(
+ interface_name, interface_pipe, frame->GetProcess(),
+ frame->GetLastCommittedOrigin());
+ }
+
+ private:
+ void InitializeParameterizedBinderRegistry();
+
+ service_manager::BinderRegistryWithArgs<RenderProcessHost*,
+ const url::Origin&>
+ parameterized_binder_registry_;
+};
+
+// Forwards service requests to Service Manager since the renderer cannot launch
+// out-of-process services on is own.
+template <typename Interface>
+void ForwardServiceRequest(const char* service_name,
+ mojo::InterfaceRequest<Interface> request,
+ RenderProcessHost* host,
+ const url::Origin& origin) {
+ auto* connector = BrowserContext::GetConnectorFor(host->GetBrowserContext());
+ connector->BindInterface(service_name, std::move(request));
+}
+
+// Register renderer-exposed interfaces. Each registered interface binder is
+// exposed to all renderer-hosted execution context types (document/frame,
+// dedicated worker, shared worker and service worker) where the appropriate
+// capability spec in the content_browser manifest includes the interface. For
+// interface requests from frames, binders registered on the frame itself
+// override binders registered here.
+void RendererInterfaceBinders::InitializeParameterizedBinderRegistry() {
+ parameterized_binder_registry_.AddInterface(base::Bind(
+ &ForwardServiceRequest<shape_detection::mojom::BarcodeDetection>,
+ shape_detection::mojom::kServiceName));
+ parameterized_binder_registry_.AddInterface(base::Bind(
+ &ForwardServiceRequest<shape_detection::mojom::FaceDetectionProvider>,
+ shape_detection::mojom::kServiceName));
+ parameterized_binder_registry_.AddInterface(
+ base::Bind(&ForwardServiceRequest<shape_detection::mojom::TextDetection>,
+ shape_detection::mojom::kServiceName));
+ parameterized_binder_registry_.AddInterface(
+ base::Bind(&ForwardServiceRequest<device::mojom::VibrationManager>,
+ device::mojom::kServiceName));
+ parameterized_binder_registry_.AddInterface(
+ base::Bind([](blink::mojom::WebSocketRequest request,
+ RenderProcessHost* host, const url::Origin& origin) {
+ WebSocketManager::CreateWebSocket(host->GetID(), MSG_ROUTING_NONE,
+ std::move(request));
+ }));
+ parameterized_binder_registry_.AddInterface(
+ base::Bind([](payments::mojom::PaymentManagerRequest request,
+ RenderProcessHost* host, const url::Origin& origin) {
+ static_cast<StoragePartitionImpl*>(host->GetStoragePartition())
+ ->GetPaymentAppContext()
+ ->CreatePaymentManager(std::move(request));
+ }));
+ parameterized_binder_registry_.AddInterface(
+ base::Bind([](blink::mojom::PermissionServiceRequest request,
+ RenderProcessHost* host, const url::Origin& origin) {
+ static_cast<RenderProcessHostImpl*>(host)
+ ->permission_service_context()
+ .CreateService(std::move(request));
+ }));
+ parameterized_binder_registry_.AddInterface(
+ base::Bind(&CreateDedicatedWorkerHostFactory));
+ parameterized_binder_registry_.AddInterface(
+ base::Bind([](blink::mojom::NotificationServiceRequest request,
+ RenderProcessHost* host, const url::Origin& origin) {
+ static_cast<StoragePartitionImpl*>(host->GetStoragePartition())
+ ->GetPlatformNotificationContext()
+ ->CreateService(host->GetID(), origin, std::move(request));
+ }));
+}
+
+RendererInterfaceBinders& GetRendererInterfaceBinders() {
+ CR_DEFINE_STATIC_LOCAL(RendererInterfaceBinders, binders, ());
+ return binders;
+}
+
+} // namespace
+
+void BindWorkerInterface(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe,
+ RenderProcessHost* host,
+ const url::Origin& origin) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ GetRendererInterfaceBinders().BindInterface(
+ interface_name, std::move(interface_pipe), host, origin);
+}
+
+bool TryBindFrameInterface(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle* interface_pipe,
+ RenderFrameHost* frame) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ return GetRendererInterfaceBinders().TryBindInterface(interface_name,
+ interface_pipe, frame);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_interface_binders.h b/chromium/content/browser/renderer_interface_binders.h
new file mode 100644
index 00000000000..eca39508512
--- /dev/null
+++ b/chromium/content/browser/renderer_interface_binders.h
@@ -0,0 +1,35 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_INTERFACE_BINDERS_H_
+#define CONTENT_BROWSER_RENDERER_INTERFACE_BINDERS_H_
+
+#include <string>
+
+#include "mojo/public/cpp/system/message_pipe.h"
+
+namespace url {
+class Origin;
+}
+
+namespace content {
+class RenderFrameHost;
+class RenderProcessHost;
+
+// Bind an interface request |interface_pipe| for |interface_name| received from
+// a web worker with origin |origin| hosted in the renderer |host|.
+void BindWorkerInterface(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe,
+ RenderProcessHost* host,
+ const url::Origin& origin);
+
+// Try binding an interface request |interface_pipe| for |interface_name|
+// received from |frame|.
+bool TryBindFrameInterface(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle* interface_pipe,
+ RenderFrameHost* frame);
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_INTERFACE_BINDERS_H_
diff --git a/chromium/content/browser/resolve_proxy_msg_helper.cc b/chromium/content/browser/resolve_proxy_msg_helper.cc
index a546ec22d3b..ee9681862f2 100644
--- a/chromium/content/browser/resolve_proxy_msg_helper.cc
+++ b/chromium/content/browser/resolve_proxy_msg_helper.cc
@@ -19,8 +19,7 @@ ResolveProxyMsgHelper::ResolveProxyMsgHelper(
net::URLRequestContextGetter* getter)
: BrowserMessageFilter(ViewMsgStart),
context_getter_(getter),
- proxy_service_(NULL) {
-}
+ proxy_service_(nullptr) {}
ResolveProxyMsgHelper::ResolveProxyMsgHelper(net::ProxyService* proxy_service)
: BrowserMessageFilter(ViewMsgStart),
@@ -83,11 +82,11 @@ void ResolveProxyMsgHelper::StartPendingRequest() {
PendingRequest& req = pending_requests_.front();
// Verify the request wasn't started yet.
- DCHECK(NULL == req.pac_req);
+ DCHECK(nullptr == req.pac_req);
if (context_getter_.get()) {
proxy_service_ = context_getter_->GetURLRequestContext()->proxy_service();
- context_getter_ = NULL;
+ context_getter_ = nullptr;
}
// Start the request.
@@ -95,7 +94,7 @@ void ResolveProxyMsgHelper::StartPendingRequest() {
req.url, std::string(), &proxy_info_,
base::Bind(&ResolveProxyMsgHelper::OnResolveProxyCompleted,
base::Unretained(this)),
- &req.pac_req, NULL, net::NetLogWithSource());
+ &req.pac_req, nullptr, net::NetLogWithSource());
// Completed synchronously.
if (result != net::ERR_IO_PENDING)
diff --git a/chromium/content/browser/resolve_proxy_msg_helper_unittest.cc b/chromium/content/browser/resolve_proxy_msg_helper_unittest.cc
index 1afc709404d..9a6ae8141ab 100644
--- a/chromium/content/browser/resolve_proxy_msg_helper_unittest.cc
+++ b/chromium/content/browser/resolve_proxy_msg_helper_unittest.cc
@@ -65,7 +65,7 @@ class ResolveProxyMsgHelperTest : public testing::Test, public IPC::Listener {
service_(
new net::ProxyService(base::WrapUnique(new MockProxyConfigService),
base::WrapUnique(resolver_factory_),
- NULL)),
+ nullptr)),
helper_(new TestResolveProxyMsgHelper(service_.get(), this)) {
test_sink_.AddFilter(this);
}
@@ -251,13 +251,13 @@ TEST_F(ResolveProxyMsgHelperTest, CancelPendingRequests) {
// Delete the underlying ResolveProxyMsgHelper -- this should cancel all
// the requests which are outstanding.
- helper_ = NULL;
+ helper_ = nullptr;
// The pending requests sent to the proxy resolver should have been cancelled.
EXPECT_EQ(0u, resolver_.pending_jobs().size());
- EXPECT_TRUE(pending_result() == NULL);
+ EXPECT_TRUE(pending_result() == nullptr);
// It should also be the case that msg1, msg2, msg3 were deleted by the
// cancellation. (Else will show up as a leak in Valgrind).
diff --git a/chromium/content/browser/resource_context_impl.cc b/chromium/content/browser/resource_context_impl.cc
index 141a0830533..895a9367b85 100644
--- a/chromium/content/browser/resource_context_impl.cc
+++ b/chromium/content/browser/resource_context_impl.cc
@@ -22,7 +22,6 @@ using base::UserDataAdapter;
namespace content {
// Key names on ResourceContext.
-const char kBlobStorageContextKeyName[] = "content_blob_storage_context";
const char kStreamContextKeyName[] = "content_stream_context";
const char kURLDataManagerBackendKeyName[] = "url_data_manager_backend";
@@ -52,7 +51,7 @@ URLDataManagerBackend* GetURLDataManagerForResourceContext(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context->GetUserData(kURLDataManagerBackendKeyName)) {
context->SetUserData(kURLDataManagerBackendKeyName,
- base::MakeUnique<URLDataManagerBackend>());
+ std::make_unique<URLDataManagerBackend>());
}
return static_cast<URLDataManagerBackend*>(
context->GetUserData(kURLDataManagerBackendKeyName));
@@ -63,11 +62,11 @@ void InitializeResourceContext(BrowserContext* browser_context) {
resource_context->SetUserData(
kBlobStorageContextKeyName,
- base::MakeUnique<UserDataAdapter<ChromeBlobStorageContext>>(
+ std::make_unique<UserDataAdapter<ChromeBlobStorageContext>>(
ChromeBlobStorageContext::GetFor(browser_context)));
resource_context->SetUserData(
- kStreamContextKeyName, base::MakeUnique<UserDataAdapter<StreamContext>>(
+ kStreamContextKeyName, std::make_unique<UserDataAdapter<StreamContext>>(
StreamContext::GetFor(browser_context)));
resource_context->DetachFromSequence();
diff --git a/chromium/content/browser/resources/accessibility/accessibility.html b/chromium/content/browser/resources/accessibility/accessibility.html
index 8e30acb7f63..80e7b7a665b 100644
--- a/chromium/content/browser/resources/accessibility/accessibility.html
+++ b/chromium/content/browser/resources/accessibility/accessibility.html
@@ -135,6 +135,11 @@ found in the LICENSE file.
<a is="action-link" role="button" id="toggle_internal" aria-labelledby="internal"></a>
</div>
-->
+ <h2>Chrome Native UI:</h2>
+ <div id="native_ui">
+ <a is="action-link" tabindex="0" role="button" id="showNativeUI">show accessibility tree</a>
+ </div>
+
<h2>Pages:</h2>
<div id="pages" class="list"></div>
<script src="chrome://resources/js/i18n_template.js"></script>
diff --git a/chromium/content/browser/resources/accessibility/accessibility.js b/chromium/content/browser/resources/accessibility/accessibility.js
index 4750364882f..979aa311c22 100644
--- a/chromium/content/browser/resources/accessibility/accessibility.js
+++ b/chromium/content/browser/resources/accessibility/accessibility.js
@@ -44,8 +44,8 @@ cr.define('accessibility', function() {
document.location.reload();
}
- function requestAccessibilityTree(data, element) {
- chrome.send('requestAccessibilityTree',
+ function requestWebContentsTree(data, element) {
+ chrome.send('requestWebContentsTree',
[String(data.processId), String(data.routeId)]);
}
@@ -66,6 +66,11 @@ cr.define('accessibility', function() {
for (var i = 0; i < list.length; i++) {
addToPagesList(list[i]);
}
+
+ var showNativeUI = $('showNativeUI');
+ showNativeUI.addEventListener('click', function() {
+ chrome.send('requestNativeUITree', []);
+ });
}
function bindCheckbox(name, value) {
@@ -190,7 +195,7 @@ cr.define('accessibility', function() {
link.textContent = 'show accessibility tree';
link.id = row.id + ':showTree';
link.addEventListener('click',
- requestAccessibilityTree.bind(this, data, link));
+ requestWebContentsTree.bind(this, data, link));
return link;
}
@@ -228,6 +233,7 @@ cr.define('accessibility', function() {
return errorMessageElement;
}
+ // Called from C++
function showTree(data) {
var id = data.processId + '.' + data.routeId;
var row = $(id);
@@ -238,6 +244,16 @@ cr.define('accessibility', function() {
formatRow(row, data);
}
+ // Called from C++
+ function showNativeUITree(data) {
+ var treeElement = document.querySelector('#native_ui pre');
+ if (!treeElement) {
+ var treeElement = document.createElement('pre');
+ $('native_ui').appendChild(treeElement);
+ }
+ treeElement.textContent = data.tree;
+ }
+
function createAccessibilityTreeElement(data) {
var treeElement = document.createElement('pre');
var tree = data.tree;
@@ -245,9 +261,11 @@ cr.define('accessibility', function() {
return treeElement;
}
+ // These are the functions we export so they can be called from C++.
return {
initialize: initialize,
- showTree: showTree
+ showTree: showTree,
+ showNativeUITree: showNativeUITree
};
});
diff --git a/chromium/content/browser/resources/gpu/browser_bridge_tests.js b/chromium/content/browser/resources/gpu/browser_bridge_tests.js
index 6a3a375bc64..41cf325b8d6 100644
--- a/chromium/content/browser/resources/gpu/browser_bridge_tests.js
+++ b/chromium/content/browser/resources/gpu/browser_bridge_tests.js
@@ -255,7 +255,6 @@ var glValueArray = ['GL_ARB_compatibility',
}
},
clientInfo: {
- blacklist_version: '1.10',
command_line: commandLineStr,
version: 'Chrome/12.0.729.0',
},
diff --git a/chromium/content/browser/resources/gpu/info_view.html b/chromium/content/browser/resources/gpu/info_view.html
index ad1dc509aa8..3b114594bb0 100644
--- a/chromium/content/browser/resources/gpu/info_view.html
+++ b/chromium/content/browser/resources/gpu/info_view.html
@@ -55,6 +55,11 @@ found in the LICENSE file.
<div id="display-info"></div>
</div>
+ <div>
+ <h3>Video Acceleration Information</h3>
+ <div id="video-acceleration-info"></div>
+ </div>
+
<div class="diagnostics">
<h3>Diagnostics</h3>
<div class="diagnostics-loading">... loading ...</div>
diff --git a/chromium/content/browser/resources/gpu/info_view.js b/chromium/content/browser/resources/gpu/info_view.js
index 6e888096654..0a75199d824 100644
--- a/chromium/content/browser/resources/gpu/info_view.js
+++ b/chromium/content/browser/resources/gpu/info_view.js
@@ -34,6 +34,11 @@ cr.define('gpu', function() {
* Updates the view based on its currently known data
*/
refresh: function(data) {
+ function createSourcePermalink(revisionIdentifier, filepath) {
+ return 'https://chromium.googlesource.com/chromium/src/+/' +
+ revisionIdentifier + '/' + filepath;
+ }
+
// Client info
if (browserBridge.clientInfo) {
var clientInfo = browserBridge.clientInfo;
@@ -52,12 +57,14 @@ cr.define('gpu', function() {
value: clientInfo.operating_system
},
{
- description: 'Software rendering list version',
- value: clientInfo.blacklist_version
+ description: 'Software rendering list URL',
+ value: createSourcePermalink(clientInfo.revision_identifier,
+ 'gpu/config/software_rendering_list.json')
},
{
- description: 'Driver bug list version',
- value: clientInfo.driver_bug_list_version
+ description: 'Driver bug list URL',
+ value: createSourcePermalink(clientInfo.revision_identifier,
+ 'gpu/config/gpu_driver_bug_list.json')
},
{
description: 'ANGLE commit id',
@@ -86,8 +93,6 @@ cr.define('gpu', function() {
'flash_stage3d_baseline': 'Flash Stage3D Baseline profile',
'texture_sharing': 'Texture Sharing',
'video_decode': 'Video Decode',
- 'video_encode': 'Video Encode',
- 'panel_fitting': 'Panel Fitting',
'rasterization': 'Rasterization',
'multiple_raster_threads': 'Multiple Raster Threads',
'native_gpu_memory_buffers': 'Native GpuMemoryBuffers',
@@ -237,6 +242,13 @@ cr.define('gpu', function() {
else
this.setTable_('display-info', []);
+ if (gpuInfo.videoAcceleratorsInfo) {
+ this.setTable_(
+ 'video-acceleration-info', gpuInfo.videoAcceleratorsInfo);
+ } else {
+ this.setTable_('video-acceleration-info', []);
+ }
+
if (gpuInfo.diagnostics) {
diagnosticsDiv.hidden = false;
diagnosticsLoadingDiv.hidden = true;
diff --git a/chromium/content/browser/resources/media/dump_creator.js b/chromium/content/browser/resources/media/dump_creator.js
index 88f2c65263c..c70fe205670 100644
--- a/chromium/content/browser/resources/media/dump_creator.js
+++ b/chromium/content/browser/resources/media/dump_creator.js
@@ -47,10 +47,10 @@ var DumpCreator = (function() {
' suffixes will be added:</p>' +
'<p><div>&lt;base filename&gt;.&lt;render process ID&gt;' +
'.aec_dump.&lt;AEC dump recording ID&gt;</div>' +
- '<div>&lt;base filename&gt;.&lt;render process ID&gt;' +
- '.source_input.&lt;stream ID&gt;.wav</div>' +
- '<div>&lt;base filename&gt;.output' +
- '.&lt;output stream recording ID&gt;.wav</div></p>' +
+ '<div>&lt;base filename&gt;.input.&lt;stream recording ID&gt;.wav' +
+ '</div><div>' +
+ '&lt;base filename&gt;.output.&lt;stream recording ID&gt;.wav' +
+ '</div></p>' +
'<p class=audio-diagnostic-dumps-info>It is recommended to choose a' +
' new base filename each time the feature is enabled to avoid ending' +
' up with partially overwritten or unusable audio files.</p>' +
diff --git a/chromium/content/browser/sandbox_ipc_linux.cc b/chromium/content/browser/sandbox_ipc_linux.cc
index 0851477f24c..182d7b44bdb 100644
--- a/chromium/content/browser/sandbox_ipc_linux.cc
+++ b/chromium/content/browser/sandbox_ipc_linux.cc
@@ -23,8 +23,8 @@
#include "base/strings/string_number_conversions.h"
#include "content/browser/renderer_host/font_utils_linux.h"
#include "content/common/font_config_ipc_linux.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
#include "content/public/common/content_switches.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#include "skia/ext/skia_utils_base.h"
#include "third_party/skia/include/ports/SkFontConfigInterface.h"
#include "ui/gfx/font.h"
@@ -178,15 +178,19 @@ void SandboxIPCHandler::HandleRequestFromChild(int fd) {
HandleFontMatchRequest(fd, iter, fds);
} else if (kind == FontConfigIPC::METHOD_OPEN) {
HandleFontOpenRequest(fd, iter, fds);
- } else if (kind == LinuxSandbox::METHOD_GET_FALLBACK_FONT_FOR_CHAR) {
+ } else if (kind ==
+ service_manager::SandboxLinux::METHOD_GET_FALLBACK_FONT_FOR_CHAR) {
HandleGetFallbackFontForChar(fd, iter, fds);
- } else if (kind == LinuxSandbox::METHOD_LOCALTIME) {
+ } else if (kind == service_manager::SandboxLinux::METHOD_LOCALTIME) {
HandleLocaltime(fd, iter, fds);
- } else if (kind == LinuxSandbox::METHOD_GET_STYLE_FOR_STRIKE) {
+ } else if (kind ==
+ service_manager::SandboxLinux::METHOD_GET_STYLE_FOR_STRIKE) {
HandleGetStyleForStrike(fd, iter, fds);
- } else if (kind == LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT) {
+ } else if (kind ==
+ service_manager::SandboxLinux::METHOD_MAKE_SHARED_MEMORY_SEGMENT) {
HandleMakeSharedMemorySegment(fd, iter, fds);
- } else if (kind == LinuxSandbox::METHOD_MATCH_WITH_FALLBACK) {
+ } else if (kind ==
+ service_manager::SandboxLinux::METHOD_MATCH_WITH_FALLBACK) {
HandleMatchWithFallback(fd, iter, fds);
}
}
diff --git a/chromium/content/browser/sandbox_parameters_mac.mm b/chromium/content/browser/sandbox_parameters_mac.mm
index f3cb8fda1d3..007aee37d63 100644
--- a/chromium/content/browser/sandbox_parameters_mac.mm
+++ b/chromium/content/browser/sandbox_parameters_mac.mm
@@ -48,45 +48,45 @@ void SetupRendererSandboxParameters(sandbox::SeatbeltExecClient* client) {
command_line->HasSwitch(switches::kEnableSandboxLogging);
CHECK(client->SetBooleanParameter(
- service_manager::Sandbox::kSandboxEnableLogging, enable_logging));
+ service_manager::SandboxMac::kSandboxEnableLogging, enable_logging));
CHECK(client->SetBooleanParameter(
- service_manager::Sandbox::kSandboxDisableDenialLogging, !enable_logging));
+ service_manager::SandboxMac::kSandboxDisableDenialLogging,
+ !enable_logging));
std::string homedir =
- service_manager::Sandbox::GetCanonicalSandboxPath(base::GetHomeDir())
- .value();
- CHECK(client->SetParameter(service_manager::Sandbox::kSandboxHomedirAsLiteral,
- homedir));
+ service_manager::SandboxMac::GetCanonicalPath(base::GetHomeDir()).value();
+ CHECK(client->SetParameter(
+ service_manager::SandboxMac::kSandboxHomedirAsLiteral, homedir));
- CHECK(client->SetParameter(service_manager::Sandbox::kSandboxOSVersion,
+ CHECK(client->SetParameter(service_manager::SandboxMac::kSandboxOSVersion,
GetOSVersion()));
- std::string bundle_path = service_manager::Sandbox::GetCanonicalSandboxPath(
- base::mac::MainBundlePath())
- .value();
- CHECK(client->SetParameter(service_manager::Sandbox::kSandboxBundlePath,
+ std::string bundle_path =
+ service_manager::SandboxMac::GetCanonicalPath(base::mac::MainBundlePath())
+ .value();
+ CHECK(client->SetParameter(service_manager::SandboxMac::kSandboxBundlePath,
bundle_path));
NSBundle* bundle = base::mac::OuterBundle();
std::string bundle_id = base::SysNSStringToUTF8([bundle bundleIdentifier]);
- CHECK(client->SetParameter(service_manager::Sandbox::kSandboxChromeBundleId,
- bundle_id));
+ CHECK(client->SetParameter(
+ service_manager::SandboxMac::kSandboxChromeBundleId, bundle_id));
- CHECK(client->SetParameter(service_manager::Sandbox::kSandboxBrowserPID,
+ CHECK(client->SetParameter(service_manager::SandboxMac::kSandboxBrowserPID,
std::to_string(getpid())));
std::string logging_path =
GetContentClient()->browser()->GetLoggingFileName(*command_line).value();
CHECK(client->SetParameter(
- service_manager::Sandbox::kSandboxLoggingPathAsLiteral, logging_path));
+ service_manager::SandboxMac::kSandboxLoggingPathAsLiteral, logging_path));
#if defined(COMPONENT_BUILD)
// For component builds, allow access to one directory level higher, where
// the dylibs live.
base::FilePath component_path = base::mac::MainBundlePath().Append("..");
std::string component_path_canonical =
- service_manager::Sandbox::GetCanonicalSandboxPath(component_path).value();
- CHECK(client->SetParameter(service_manager::Sandbox::kSandboxComponentPath,
+ service_manager::SandboxMac::GetCanonicalPath(component_path).value();
+ CHECK(client->SetParameter(service_manager::SandboxMac::kSandboxComponentPath,
component_path_canonical));
#endif
}
diff --git a/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc b/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc
index 507ed0637b3..a461bd21af7 100644
--- a/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc
+++ b/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc
@@ -42,7 +42,7 @@ class ScreenOrientationBrowserTest : public ContentBrowserTest {
}
protected:
- void SendFakeScreenOrientation(unsigned angle, const std::string& strType) {
+ void SendFakeScreenOrientation(unsigned angle, const std::string& str_type) {
RenderWidgetHost* main_frame_rwh =
web_contents()->GetMainFrame()->GetRenderWidgetHost();
ScreenInfo screen_info;
@@ -50,13 +50,13 @@ class ScreenOrientationBrowserTest : public ContentBrowserTest {
screen_info.orientation_angle = angle;
ScreenOrientationValues type = SCREEN_ORIENTATION_VALUES_DEFAULT;
- if (strType == "portrait-primary") {
+ if (str_type == "portrait-primary") {
type = SCREEN_ORIENTATION_VALUES_PORTRAIT_PRIMARY;
- } else if (strType == "portrait-secondary") {
+ } else if (str_type == "portrait-secondary") {
type = SCREEN_ORIENTATION_VALUES_PORTRAIT_SECONDARY;
- } else if (strType == "landscape-primary") {
+ } else if (str_type == "landscape-primary") {
type = SCREEN_ORIENTATION_VALUES_LANDSCAPE_PRIMARY;
- } else if (strType == "landscape-secondary") {
+ } else if (str_type == "landscape-secondary") {
type = SCREEN_ORIENTATION_VALUES_LANDSCAPE_SECONDARY;
}
ASSERT_NE(SCREEN_ORIENTATION_VALUES_DEFAULT, type);
@@ -64,8 +64,8 @@ class ScreenOrientationBrowserTest : public ContentBrowserTest {
ResizeParams params;
params.screen_info = screen_info;
- params.new_size = gfx::Size(0, 0);
- params.physical_backing_size = gfx::Size(300, 300);
+ params.new_size = main_frame_rwh->GetView()->GetViewBounds().size();
+ params.physical_backing_size = params.new_size;
params.top_controls_height = 0.f;
params.browser_controls_shrink_blink_size = false;
params.is_fullscreen_granted = false;
@@ -93,12 +93,6 @@ class ScreenOrientationBrowserTest : public ContentBrowserTest {
// involved in the FrameTree.
web_contents()->GetFrameTree()->root()->render_manager()->SendPageMessage(
new PageMsg_UpdateScreenInfo(MSG_ROUTING_NONE, screen_info), nullptr);
-
- // 3. When the top-level frame gets the ViewMsg_Resize, it'll dispatch a
- // FrameHostMsg_FrameRectsChanged IPC that causes the remote subframes to
- // receive the ViewMsg_Resize from the browser.
- for (auto* rwh : rwhs)
- rwh->Send(new ViewMsg_Resize(rwh->GetRoutingID(), params));
}
int GetOrientationAngle() {
diff --git a/chromium/content/browser/security_exploit_browsertest.cc b/chromium/content/browser/security_exploit_browsertest.cc
index b2616a67904..503162b3a7a 100644
--- a/chromium/content/browser/security_exploit_browsertest.cc
+++ b/chromium/content/browser/security_exploit_browsertest.cc
@@ -99,7 +99,7 @@ RenderFrameHostImpl* PrepareToDuplicateHosts(Shell* shell,
wc->GetFrameTree()->root()->navigator()->RequestOpenURL(
wc->GetFrameTree()->root()->current_frame_host(), extension_url, false,
nullptr, std::string(), Referrer(), WindowOpenDisposition::CURRENT_TAB,
- false, false, true, blink::WebTriggeringEventInfo::kFromTrustedEvent);
+ false, true, blink::WebTriggeringEventInfo::kFromTrustedEvent);
// Since the navigation above requires a cross-process swap, there will be a
// speculative/pending RenderFrameHost. Ensure it exists and is in a different
@@ -124,7 +124,7 @@ ResourceRequest CreateXHRRequest(const char* url) {
request.referrer_policy = blink::kWebReferrerPolicyDefault;
request.request_initiator = url::Origin();
request.load_flags = 0;
- request.origin_pid = 0;
+ request.plugin_child_id = -1;
request.resource_type = RESOURCE_TYPE_XHR;
request.request_context = 0;
request.appcache_host_id = kAppCacheNoHostId;
@@ -276,7 +276,8 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
mojom::CreateNewWindowParamsPtr params = mojom::CreateNewWindowParams::New();
params->target_url = GURL("about:blank");
pending_rfh->CreateNewWindow(
- std::move(params), base::BindOnce([](mojom::CreateNewWindowReplyPtr) {}));
+ std::move(params), base::BindOnce([](mojom::CreateNewWindowStatus,
+ mojom::CreateNewWindowReplyPtr) {}));
// If the above operation doesn't cause a crash, the test has succeeded!
}
@@ -299,7 +300,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
mojom::WidgetPtr widget;
std::unique_ptr<MockWidgetImpl> widget_impl =
- base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+ std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));
// Since this test executes on the UI thread and hopping threads might cause
// different timing in the test, let's simulate a CreateNewWidget call coming
@@ -381,7 +382,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
InterstitialPage* interstitial_page =
shell()->web_contents()->GetInterstitialPage();
- ASSERT_TRUE(interstitial_page != NULL);
+ ASSERT_TRUE(interstitial_page != nullptr);
ASSERT_TRUE(shell()->web_contents()->ShowingInterstitialPage());
ASSERT_TRUE(interstitial_page->GetDelegateForTesting() == interstitial);
@@ -549,7 +550,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, MismatchedOriginOnCommit) {
// Create commit params with different origins in params.url and
// params.origin.
std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params =
- base::MakeUnique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
+ std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
params->nav_entry_id = 0;
params->did_create_new_entry = false;
params->url = url;
@@ -559,7 +560,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, MismatchedOriginOnCommit) {
params->was_within_same_document = false;
params->method = "GET";
params->page_state = PageState::CreateFromURL(url);
- params->origin = url::Origin(GURL("http://bar.com/"));
+ params->origin = url::Origin::Create(GURL("http://bar.com/"));
static_cast<mojom::FrameHost*>(root->current_frame_host())
->DidCommitProvisionalLoad(std::move(params));
@@ -667,7 +668,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, PageStateToWrongEntry) {
// put a PageState on the cross-site iframe's FrameNavigationEntry. Forge a
// data URL within the PageState that differs from child1_url.
std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params =
- base::MakeUnique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
+ std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
params->nav_entry_id = nav_entry_id;
params->did_create_new_entry = false;
params->url = GURL("about:blank");
@@ -677,7 +678,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, PageStateToWrongEntry) {
params->was_within_same_document = false;
params->method = "GET";
params->page_state = PageState::CreateFromURL(GURL("data:text/html,foo"));
- params->origin = url::Origin(GURL("about:blank"));
+ params->origin = url::Origin::Create(GURL("about:blank"));
static_cast<mojom::FrameHost*>(child0_0->current_frame_host())
->DidCommitProvisionalLoad(std::move(params));
diff --git a/chromium/content/browser/service_manager/common_browser_interfaces.cc b/chromium/content/browser/service_manager/common_browser_interfaces.cc
index 695663408c7..a9be22bcd5c 100644
--- a/chromium/content/browser/service_manager/common_browser_interfaces.cc
+++ b/chromium/content/browser/service_manager/common_browser_interfaces.cc
@@ -11,6 +11,7 @@
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/task_runner.h"
+#include "build/build_config.h"
#include "components/discardable_memory/service/discardable_shared_memory_manager.h"
#include "content/browser/browser_main_loop.h"
#include "content/public/common/connection_filter.h"
@@ -19,6 +20,10 @@
#include "mojo/public/cpp/bindings/interface_request.h"
#include "services/service_manager/public/cpp/binder_registry.h"
+#if defined(OS_WIN)
+#include "content/common/font_cache_dispatcher_win.h"
+#endif
+
namespace content {
namespace {
@@ -28,7 +33,9 @@ class ConnectionFilterImpl : public ConnectionFilter {
ConnectionFilterImpl()
: main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
RegisterMainThreadInterface(base::Bind(&device::GeolocationConfig::Create));
-
+#if defined(OS_WIN)
+ registry_.AddInterface(base::Bind(&FontCacheDispatcher::Create));
+#endif
auto* browser_main_loop = BrowserMainLoop::GetInstance();
if (browser_main_loop) {
auto* manager = browser_main_loop->discardable_shared_memory_manager();
@@ -83,7 +90,7 @@ class ConnectionFilterImpl : public ConnectionFilter {
} // namespace
void RegisterCommonBrowserInterfaces(ServiceManagerConnection* connection) {
- connection->AddConnectionFilter(base::MakeUnique<ConnectionFilterImpl>());
+ connection->AddConnectionFilter(std::make_unique<ConnectionFilterImpl>());
}
} // namespace content
diff --git a/chromium/content/browser/service_manager/service_manager_context.cc b/chromium/content/browser/service_manager/service_manager_context.cc
index 41f605f134b..fb85ee019a2 100644
--- a/chromium/content/browser/service_manager/service_manager_context.cc
+++ b/chromium/content/browser/service_manager/service_manager_context.cc
@@ -15,13 +15,16 @@
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/process/process_handle.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "build/build_config.h"
+#include "content/browser/browser_main_loop.h"
#include "content/browser/child_process_launcher.h"
#include "content/browser/gpu/gpu_process_host.h"
+#include "content/browser/mus_util.h"
#include "content/browser/service_manager/common_browser_interfaces.h"
#include "content/browser/utility_process_host_impl.h"
#include "content/browser/wake_lock/wake_lock_context_host.h"
@@ -62,6 +65,9 @@
#include "services/shape_detection/public/interfaces/constants.mojom.h"
#include "services/video_capture/public/cpp/constants.h"
#include "services/video_capture/public/interfaces/constants.mojom.h"
+#include "services/viz/public/interfaces/constants.mojom.h"
+#include "ui/base/ui_base_switches_util.h"
+#include "ui/base/ui_features.h"
#if defined(OS_ANDROID)
#include "base/android/jni_android.h"
@@ -73,6 +79,18 @@
#include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h"
#endif
+#if defined(USE_AURA)
+#include "ui/aura/env.h"
+#endif
+
+#if BUILDFLAG(ENABLE_MUS)
+#include "components/discardable_memory/service/discardable_shared_memory_manager.h"
+#include "content/public/browser/discardable_shared_memory_manager.h"
+#include "services/ui/common/image_cursors_set.h"
+#include "services/ui/public/interfaces/constants.mojom.h"
+#include "services/ui/service.h"
+#endif
+
namespace content {
namespace {
@@ -96,7 +114,7 @@ void StartServiceInUtilityProcess(
UtilityProcessHostImpl* process_host =
new UtilityProcessHostImpl(nullptr, nullptr);
#if defined(OS_WIN)
- if (sandbox_type == service_manager::SANDBOX_TYPE_PPAPI)
+ if (sandbox_type == service_manager::SANDBOX_TYPE_PDF_COMPOSITOR)
process_host->AddFilter(new DWriteFontProxyMessageFilter());
#endif
process_host->SetName(process_name);
@@ -211,17 +229,56 @@ class NullServiceProcessLauncherFactory
void GetGeolocationRequestContextFromContentClient(
base::OnceCallback<void(scoped_refptr<net::URLRequestContextGetter>)>
callback) {
- // TODO(amoylan): Confirm whether either of the following can be replaced with
- // DCHECKs owing to lifetime guarantees on ContentClient or
- // ContentBrowserClient:
- if (GetContentClient() && GetContentClient()->browser()) {
- GetContentClient()->browser()->GetGeolocationRequestContext(
- std::move(callback));
- } else {
- std::move(callback).Run(
- scoped_refptr<net::URLRequestContextGetter>(nullptr));
- }
+ GetContentClient()->browser()->GetGeolocationRequestContext(
+ std::move(callback));
+}
+
+bool ShouldEnableVizService() {
+#if defined(USE_AURA)
+ // aura::Env can be null in tests.
+ return aura::Env::GetInstanceDontCreate() &&
+ aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS;
+#else
+ return false;
+#endif
+}
+
+#if BUILDFLAG(ENABLE_MUS)
+std::unique_ptr<service_manager::Service> CreateEmbeddedUIService(
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+ base::WeakPtr<ui::ImageCursorsSet> image_cursors_set_weak_ptr,
+ discardable_memory::DiscardableSharedMemoryManager* memory_manager) {
+ ui::Service::InProcessConfig config;
+ config.resource_runner = task_runner;
+ config.image_cursors_set_weak_ptr = image_cursors_set_weak_ptr;
+ config.memory_manager = memory_manager;
+ config.should_host_viz = switches::IsMusHostingViz();
+ return base::MakeUnique<ui::Service>(&config);
+}
+
+void RegisterUIServiceInProcessIfNecessary(
+ ServiceManagerConnection* connection) {
+ // Some tests don't create BrowserMainLoop.
+ if (!BrowserMainLoop::GetInstance())
+ return;
+ // Do not embed the UI service when running in mash.
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch("mash"))
+ return;
+ // Do not embed the UI service if not running with --mus.
+ if (!IsUsingMus())
+ return;
+
+ service_manager::EmbeddedServiceInfo info;
+ info.factory = base::Bind(
+ &CreateEmbeddedUIService, base::ThreadTaskRunnerHandle::Get(),
+ BrowserMainLoop::GetInstance()->image_cursors_set()->GetWeakPtr(),
+ GetDiscardableSharedMemoryManager());
+ info.use_own_thread = true;
+ info.message_loop_type = base::MessageLoop::TYPE_UI;
+ info.thread_priority = base::ThreadPriority::DISPLAY;
+ connection->AddEmbeddedService(ui::mojom::kServiceName, info);
}
+#endif
} // namespace
@@ -259,8 +316,8 @@ class ServiceManagerContext::InProcessServiceManagerContext
std::unique_ptr<BuiltinManifestProvider> manifest_provider,
service_manager::mojom::ServicePtrInfo packaged_services_service_info) {
manifest_provider_ = std::move(manifest_provider);
- service_manager_ = base::MakeUnique<service_manager::ServiceManager>(
- base::MakeUnique<NullServiceProcessLauncherFactory>(), nullptr,
+ service_manager_ = std::make_unique<service_manager::ServiceManager>(
+ std::make_unique<NullServiceProcessLauncherFactory>(), nullptr,
manifest_provider_.get());
service_manager::mojom::ServicePtr packaged_services_service;
@@ -269,6 +326,24 @@ class ServiceManagerContext::InProcessServiceManagerContext
service_manager::Identity(mojom::kPackagedServicesServiceName,
service_manager::mojom::kRootUserID),
std::move(packaged_services_service), nullptr);
+ service_manager_->SetInstanceQuitCallback(
+ base::Bind(&OnInstanceQuitOnIOThread));
+ }
+
+ static void OnInstanceQuitOnIOThread(const service_manager::Identity& id) {
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)
+ ->PostTask(FROM_HERE, base::BindOnce(&OnInstanceQuit, id));
+ }
+
+ static void OnInstanceQuit(const service_manager::Identity& id) {
+ if (GetContentClient()->browser()->ShouldTerminateOnServiceQuit(id)) {
+ // Don't LOG(FATAL) because we don't want a browser crash report.
+ LOG(ERROR) << "Terminating because service '" << id.name()
+ << "' quit unexpectedly.";
+ // Skip shutdown to reduce the risk that other code in the browser will
+ // respond to the service pipe closing.
+ exit(1);
+ }
}
void ShutDownOnIOThread() {
@@ -292,7 +367,7 @@ ServiceManagerContext::ServiceManagerContext() {
service_manager::GetServiceRequestFromCommandLine(invitation.get());
} else {
std::unique_ptr<BuiltinManifestProvider> manifest_provider =
- base::MakeUnique<BuiltinManifestProvider>();
+ std::make_unique<BuiltinManifestProvider>();
static const struct ManifestInfo {
const char* name;
@@ -357,17 +432,21 @@ ServiceManagerContext::ServiceManagerContext() {
java_nfc_delegate.Reset(Java_ContentNfcDelegate_create(env));
DCHECK(!java_nfc_delegate.is_null());
- // See the comments on wake_lock_context_host.h and ContentNfcDelegate.java
- // respectively for comments on those parameters.
- device_info.factory =
- base::Bind(&device::CreateDeviceService, device_blocking_task_runner,
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
- base::Bind(&WakeLockContextHost::GetNativeViewForContext),
- std::move(java_nfc_delegate));
+ // See the comments on wake_lock_context_host.h, content_browser_client.h and
+ // ContentNfcDelegate.java respectively for comments on those parameters.
+ device_info.factory = base::Bind(
+ &device::CreateDeviceService, device_blocking_task_runner,
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ base::Bind(&WakeLockContextHost::GetNativeViewForContext),
+ base::Bind(&ContentBrowserClient::OverrideSystemLocationProvider,
+ base::Unretained(GetContentClient()->browser())),
+ std::move(java_nfc_delegate));
#else
- device_info.factory =
- base::Bind(&device::CreateDeviceService, device_blocking_task_runner,
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ device_info.factory = base::Bind(
+ &device::CreateDeviceService, device_blocking_task_runner,
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ base::Bind(&ContentBrowserClient::OverrideSystemLocationProvider,
+ base::Unretained(GetContentClient()->browser())));
#endif
device_info.task_runner = base::ThreadTaskRunnerHandle::Get();
packaged_services_connection_->AddEmbeddedService(device::mojom::kServiceName,
@@ -397,6 +476,10 @@ ServiceManagerContext::ServiceManagerContext() {
entry.second);
}
+#if BUILDFLAG(ENABLE_MUS)
+ RegisterUIServiceInProcessIfNecessary(packaged_services_connection_.get());
+#endif
+
// This is safe to assign directly from any thread, because
// ServiceManagerContext must be constructed before anyone can call
// GetConnectorForIOThread().
@@ -431,6 +514,11 @@ ServiceManagerContext::ServiceManagerContext() {
base::ASCIIToUTF16("Content Decryption Module Service");
#endif
+ if (ShouldEnableVizService()) {
+ out_of_process_services[viz::mojom::kVizServiceName] =
+ base::ASCIIToUTF16("Visuals Service");
+ }
+
for (const auto& service : out_of_process_services) {
packaged_services_connection_->AddServiceRequestHandler(
service.first, base::Bind(&QueryAndStartServiceInUtilityProcess,
diff --git a/chromium/content/browser/service_manager/service_manager_context_browsertest.cc b/chromium/content/browser/service_manager/service_manager_context_browsertest.cc
new file mode 100644
index 00000000000..742e55a4a54
--- /dev/null
+++ b/chromium/content/browser/service_manager/service_manager_context_browsertest.cc
@@ -0,0 +1,78 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/command_line.h"
+#include "base/process/launch.h"
+#include "base/run_loop.h"
+#include "base/test/launcher/test_launcher.h"
+#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
+#include "content/public/common/service_manager_connection.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/test_launcher.h"
+#include "content/shell/browser/shell_content_browser_client.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/test/echo/public/interfaces/echo.mojom.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::HasSubstr;
+using testing::Not;
+
+namespace content {
+namespace {
+
+bool ShouldTerminateOnServiceQuit(const service_manager::Identity& id) {
+ return id.name() == echo::mojom::kServiceName;
+}
+
+} // namespace
+
+using ServiceManagerContextTest = ContentBrowserTest;
+
+// "MANUAL" tests only run when kRunManualTestsFlag is set.
+IN_PROC_BROWSER_TEST_F(ServiceManagerContextTest,
+ MANUAL_TerminateOnServiceQuit) {
+ ShellContentBrowserClient::Get()
+ ->set_should_terminate_on_service_quit_callback(
+ base::Bind(&ShouldTerminateOnServiceQuit));
+
+ // Launch a test service.
+ echo::mojom::EchoPtr echo_ptr;
+ content::ServiceManagerConnection::GetForProcess()
+ ->GetConnector()
+ ->BindInterface(echo::mojom::kServiceName, &echo_ptr);
+
+ base::RunLoop loop;
+ // Terminate the service. Browser should exit in response with an error.
+ echo_ptr->Quit();
+ loop.Run();
+}
+
+// Verifies that if an important service quits then the browser exits.
+IN_PROC_BROWSER_TEST_F(ServiceManagerContextTest, TerminateOnServiceQuit) {
+ // Run the above test and collect the test output.
+ base::CommandLine new_test =
+ base::CommandLine(base::CommandLine::ForCurrentProcess()->GetProgram());
+ new_test.AppendSwitchASCII(
+ base::kGTestFilterFlag,
+ "ServiceManagerContextTest.MANUAL_TerminateOnServiceQuit");
+ new_test.AppendSwitch(kRunManualTestsFlag);
+ new_test.AppendSwitch(kSingleProcessTestsFlag);
+
+ base::ScopedAllowBlockingForTesting allow;
+ std::string output;
+ base::GetAppOutputAndError(new_test, &output);
+
+#if !defined(OS_ANDROID)
+ // The test output contains the failure message.
+ // TODO(jamescook): The |output| is always empty on Android. I suspect the
+ // test runner does logs collection after the program has exited.
+ EXPECT_THAT(output, HasSubstr("Terminating because service 'echo' quit"));
+#endif
+}
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/OWNERS b/chromium/content/browser/service_worker/OWNERS
index 86badc51868..c028a7d7cc6 100644
--- a/chromium/content/browser/service_worker/OWNERS
+++ b/chromium/content/browser/service_worker/OWNERS
@@ -3,9 +3,9 @@
# This file also covers ownership of the following:
# //chrome/browser/chrome_service_worker_browsertest.cc
# //content/browser/resources/service_worker/
-# //content/child/service_worker/
# //content/common/service_worker/
# //content/renderer/service_worker/
+# //third_party/WebKit/common/service_worker/
# //third_party/WebKit/public/web/modules/serviceworker/
# //third_party/WebKit/public/platform/modules/serviceworker/
# //third_party/WebKit/Source/modules/serviceworkers/
diff --git a/chromium/content/browser/service_worker/browser_side_controller_service_worker.cc b/chromium/content/browser/service_worker/browser_side_controller_service_worker.cc
deleted file mode 100644
index cdd82eebf39..00000000000
--- a/chromium/content/browser/service_worker/browser_side_controller_service_worker.cc
+++ /dev/null
@@ -1,237 +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/browser/service_worker/browser_side_controller_service_worker.h"
-
-#include "base/callback.h"
-#include "content/browser/service_worker/service_worker_version.h"
-#include "content/common/service_worker/service_worker_utils.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-
-namespace content {
-
-// BrowserSideControllerServiceWorker::ResponseCallback ----------------
-
-// ResponseCallback is owned by the callback that is passed to
-// ServiceWorkerVersion::StartRequest*(), and held in pending_requests_
-// until FinishRequest() is called.
-//
-// This forwards callbacks to the controllee-side's ResponseCallback
-// (|forwarding_callback|, implemented by ServiceWorkerSubresourceLoader),
-// which is the original initiator of the FetchEvent for subresource fetch:
-//
-// SubresourceLoader <-> ControllerServiceWorker <-> EventDispatcher
-// (controllee) [browser-process] (controller)
-//
-// (Eventually SubresourceLoader should directly dispatch events to
-// the controller's ControllerServiceWorker)
-class BrowserSideControllerServiceWorker::ResponseCallback
- : public mojom::ServiceWorkerFetchResponseCallback {
- public:
- // |forwarding_callback| is implemented by the controllee's SubresourceLoader.
- ResponseCallback(
- mojom::ServiceWorkerFetchResponseCallbackRequest request,
- mojom::ServiceWorkerFetchResponseCallbackPtr forwarding_callback,
- ServiceWorkerVersion* version)
- : binding_(this, std::move(request)),
- forwarding_callback_(std::move(forwarding_callback)),
- version_(version) {}
- ~ResponseCallback() override { DCHECK(fetch_event_id_.has_value()); }
-
- void set_fetch_event_id(int id) {
- DCHECK(!fetch_event_id_);
- fetch_event_id_ = id;
- }
-
- // Implements mojom::ServiceWorkerFetchResponseCallback.
- void OnResponse(const ServiceWorkerResponse& response,
- base::Time dispatch_event_time) override {
- // Calling FinishRequest will destroy |this|, so save the callback now.
- auto callback = std::move(forwarding_callback_);
- if (!version_->FinishRequest(fetch_event_id_.value(),
- true /* was_handled */, dispatch_event_time)) {
- NOTREACHED() << "Should only receive one reply per event";
- }
- callback->OnResponse(response, dispatch_event_time);
- }
- void OnResponseBlob(const ServiceWorkerResponse& response,
- storage::mojom::BlobPtr body_as_blob,
- base::Time dispatch_event_time) override {
- // Calling FinishRequest will destroy |this|, so save the callback now.
- auto callback = std::move(forwarding_callback_);
- if (!version_->FinishRequest(fetch_event_id_.value(),
- true /* was_handled */, dispatch_event_time)) {
- NOTREACHED() << "Should only receive one reply per event";
- }
- callback->OnResponseBlob(response, std::move(body_as_blob),
- dispatch_event_time);
- }
- void OnResponseStream(
- const ServiceWorkerResponse& response,
- blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- base::Time dispatch_event_time) override {
- // Calling FinishRequest will destroy |this|, so save the callback now.
- auto callback = std::move(forwarding_callback_);
- if (!version_->FinishRequest(fetch_event_id_.value(),
- true /* was_handled */, dispatch_event_time)) {
- NOTREACHED() << "Should only receive one reply per event";
- }
- callback->OnResponseStream(response, std::move(body_as_stream),
- dispatch_event_time);
- }
- void OnFallback(base::Time dispatch_event_time) override {
- // Calling FinishRequest will destroy |this|, so save the callback now.
- auto callback = std::move(forwarding_callback_);
- if (!version_->FinishRequest(fetch_event_id_.value(),
- false /* was_handled */,
- dispatch_event_time)) {
- NOTREACHED() << "Should only receive one reply per event";
- }
- callback->OnFallback(dispatch_event_time);
- }
-
- private:
- mojo::Binding<mojom::ServiceWorkerFetchResponseCallback> binding_;
- mojom::ServiceWorkerFetchResponseCallbackPtr forwarding_callback_;
- ServiceWorkerVersion* version_; // Owns |this| via pending_requests_.
- // Must be set to a non-nullopt value before the corresponding mojo
- // handle is passed to the other end (i.e. before any of OnResponse*
- // is called).
- base::Optional<int> fetch_event_id_;
- DISALLOW_COPY_AND_ASSIGN(ResponseCallback);
-};
-
-// BrowserSideControllerServiceWorker ----------------------------------
-
-BrowserSideControllerServiceWorker::BrowserSideControllerServiceWorker(
- ServiceWorkerVersion* receiver_version)
- : receiver_version_(receiver_version), weak_factory_(this) {
- DCHECK(receiver_version_);
-}
-
-BrowserSideControllerServiceWorker::~BrowserSideControllerServiceWorker() {
- for (base::IDMap<std::unique_ptr<DispatchFetchEventCallback>>::iterator iter(
- &fetch_event_callbacks_);
- !iter.IsAtEnd(); iter.Advance()) {
- std::move(*iter.GetCurrentValue())
- .Run(blink::mojom::ServiceWorkerEventStatus::ABORTED, base::Time());
- }
-}
-
-void BrowserSideControllerServiceWorker::AddBinding(
- mojom::ControllerServiceWorkerRequest request) {
- binding_.AddBinding(this, std::move(request));
-}
-
-void BrowserSideControllerServiceWorker::DispatchFetchEvent(
- const ServiceWorkerFetchRequest& request,
- mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- DispatchFetchEventCallback callback) {
- DVLOG(1) << "FetchEvent [" << request.url.spec();
- const int internal_fetch_event_id = fetch_event_callbacks_.Add(
- std::make_unique<DispatchFetchEventCallback>(std::move(callback)));
-
- if (receiver_version_->running_status() == EmbeddedWorkerStatus::RUNNING) {
- DispatchFetchEventInternal(internal_fetch_event_id, request,
- std::move(response_callback));
- return;
- }
-
- // TODO(kinuko): Support ForeignFetch if it turns out that we need it.
- DCHECK_NE(ServiceWorkerFetchType::FOREIGN_FETCH, request.fetch_type);
- // Only subresource requests should come here (as the other end of pipe for
- // this event dispatcher is passed to the renderer's SubresourceLoader).
- DCHECK_EQ(REQUEST_CONTEXT_FRAME_TYPE_NONE, request.frame_type);
-
- receiver_version_->RunAfterStartWorker(
- ServiceWorkerMetrics::EventType::FETCH_SUB_RESOURCE,
- base::BindOnce(
- &BrowserSideControllerServiceWorker::DispatchFetchEventInternal,
- weak_factory_.GetWeakPtr(), internal_fetch_event_id, request,
- std::move(response_callback)),
- base::BindOnce(
- &BrowserSideControllerServiceWorker::DidFailToStartWorker,
- weak_factory_.GetWeakPtr(),
- base::BindOnce(
- &BrowserSideControllerServiceWorker::DidFailToDispatchFetch,
- weak_factory_.GetWeakPtr(), internal_fetch_event_id, nullptr)));
-}
-
-void BrowserSideControllerServiceWorker::DispatchFetchEventInternal(
- int internal_fetch_event_id,
- const ServiceWorkerFetchRequest& request,
- mojom::ServiceWorkerFetchResponseCallbackPtr internal_response_callback) {
- mojom::ServiceWorkerFetchResponseCallbackPtr mojo_response_callback_ptr;
- auto response_callback = base::MakeUnique<ResponseCallback>(
- mojo::MakeRequest(&mojo_response_callback_ptr),
- std::move(internal_response_callback), receiver_version_);
- ResponseCallback* response_callback_rawptr = response_callback.get();
-
- // TODO(kinuko): No timeout support for now; support timeout.
- int fetch_event_id = receiver_version_->StartRequest(
- ServiceWorkerMetrics::EventType::FETCH_SUB_RESOURCE,
- base::BindOnce(
- &BrowserSideControllerServiceWorker::DidFailToDispatchFetch,
- weak_factory_.GetWeakPtr(), internal_fetch_event_id,
- std::move(response_callback)));
- int event_finish_id = receiver_version_->StartRequest(
- ServiceWorkerMetrics::EventType::FETCH_WAITUNTIL,
- // NoOp as the same error callback should be handled by the other
- // StartRequest above.
- base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
-
- response_callback_rawptr->set_fetch_event_id(fetch_event_id);
-
- receiver_version_->event_dispatcher()->DispatchFetchEvent(
- fetch_event_id, request, nullptr /* preload_handle */,
- std::move(mojo_response_callback_ptr),
- base::BindOnce(&BrowserSideControllerServiceWorker::DidDispatchFetchEvent,
- weak_factory_.GetWeakPtr(), internal_fetch_event_id,
- event_finish_id));
-}
-
-void BrowserSideControllerServiceWorker::DidFailToStartWorker(
- StatusCallback callback,
- ServiceWorkerStatusCode status) {
- // TODO(kinuko): Should log the failures.
- DCHECK_NE(SERVICE_WORKER_OK, status);
- std::move(callback).Run(status);
-}
-
-void BrowserSideControllerServiceWorker::DidFailToDispatchFetch(
- int internal_fetch_event_id,
- std::unique_ptr<ResponseCallback> response_callback,
- ServiceWorkerStatusCode status) {
- // TODO(kinuko): Should log the failures.
- DCHECK_NE(SERVICE_WORKER_OK, status);
- CompleteDispatchFetchEvent(internal_fetch_event_id,
- blink::mojom::ServiceWorkerEventStatus::ABORTED,
- base::Time());
-}
-
-void BrowserSideControllerServiceWorker::DidDispatchFetchEvent(
- int internal_fetch_event_id,
- int event_finish_id,
- blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time) {
- receiver_version_->FinishRequest(
- event_finish_id,
- status != blink::mojom::ServiceWorkerEventStatus::ABORTED,
- dispatch_event_time);
- CompleteDispatchFetchEvent(internal_fetch_event_id, status,
- dispatch_event_time);
-}
-
-void BrowserSideControllerServiceWorker::CompleteDispatchFetchEvent(
- int internal_fetch_event_id,
- blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time) {
- DVLOG(1) << "CompleteFetch [" << internal_fetch_event_id
- << "] status:" << status;
- auto* found = fetch_event_callbacks_.Lookup(internal_fetch_event_id);
- std::move(*found).Run(status, dispatch_event_time);
- fetch_event_callbacks_.Remove(internal_fetch_event_id);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/service_worker/browser_side_controller_service_worker.h b/chromium/content/browser/service_worker/browser_side_controller_service_worker.h
deleted file mode 100644
index e6499a39784..00000000000
--- a/chromium/content/browser/service_worker/browser_side_controller_service_worker.h
+++ /dev/null
@@ -1,79 +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_BROWSER_SERVICE_WORKER_BROWSER_SIDE_CONTROLLER_SERVICE_WORKER_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_BROWSER_SIDE_CONTROLLER_SERVICE_WORKER_H_
-
-#include "base/containers/id_map.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "content/browser/service_worker/service_worker_metrics.h"
-#include "content/common/service_worker/controller_service_worker.mojom.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
-
-namespace content {
-
-class ServiceWorkerVersion;
-
-// S13nServiceWorker:
-// BrowserSideControllerServiceWorker is the browser-side implementation of
-// mojom::ControllerServiceWorker, that forwards Fetch events to a
-// ServiceWorkerVersion, and is called by controllees from their renderer
-// processes.
-// This class should be soon migrated to the renderer-process where the
-// controller service worker lives.
-class BrowserSideControllerServiceWorker
- : public mojom::ControllerServiceWorker {
- public:
- explicit BrowserSideControllerServiceWorker(
- ServiceWorkerVersion* receiver_version);
- ~BrowserSideControllerServiceWorker() override;
-
- void AddBinding(mojom::ControllerServiceWorkerRequest request);
-
- // mojom::ControllerServiceWorker:
- void DispatchFetchEvent(
- const ServiceWorkerFetchRequest& request,
- mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- DispatchFetchEventCallback callback) override;
-
- private:
- class ResponseCallback;
- using StatusCallback = base::OnceCallback<void(ServiceWorkerStatusCode)>;
-
- void DispatchFetchEventInternal(
- int internal_fetch_event_id,
- const ServiceWorkerFetchRequest& request,
- mojom::ServiceWorkerFetchResponseCallbackPtr response_callback);
- void DidFailToStartWorker(StatusCallback callback,
- ServiceWorkerStatusCode status);
- void DidFailToDispatchFetch(int internal_fetch_event_id,
- std::unique_ptr<ResponseCallback> callback,
- ServiceWorkerStatusCode status);
- void DidDispatchFetchEvent(int internal_fetch_event_id,
- int event_finish_id,
- blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time);
- void CompleteDispatchFetchEvent(int internal_fetch_event_id,
- blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time);
-
- // Connected by the controllees.
- mojo::BindingSet<mojom::ControllerServiceWorker> binding_;
-
- // Not owned; |this| should go away before the version goes away.
- ServiceWorkerVersion* receiver_version_;
-
- base::IDMap<std::unique_ptr<DispatchFetchEventCallback>>
- fetch_event_callbacks_;
-
- base::WeakPtrFactory<BrowserSideControllerServiceWorker> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(BrowserSideControllerServiceWorker);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_SERVICE_WORKER_BROWSER_SIDE_CONTROLLER_SERVICE_WORKER_H_
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance.cc b/chromium/content/browser/service_worker/embedded_worker_instance.cc
index 01506aa6e72..a2162a0cc63 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_instance.cc
@@ -23,6 +23,7 @@
#include "content/common/service_worker/embedded_worker_settings.h"
#include "content/common/service_worker/embedded_worker_start_params.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_process_host.h"
@@ -30,6 +31,7 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_message.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
#include "url/gurl.h"
@@ -92,7 +94,7 @@ void SetupOnUIThread(
SetupProcessCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto process_info =
- base::MakeUnique<ServiceWorkerProcessManager::AllocatedProcessInfo>();
+ std::make_unique<ServiceWorkerProcessManager::AllocatedProcessInfo>();
std::unique_ptr<EmbeddedWorkerInstance::DevToolsProxy> devtools_proxy;
if (!process_manager) {
BrowserThread::PostTask(
@@ -135,12 +137,12 @@ void SetupOnUIThread(
process_id, routing_id,
ServiceWorkerDevToolsManager::ServiceWorkerIdentifier(
context, weak_context, params->service_worker_version_id,
- params->script_url, params->scope),
+ params->script_url, params->scope, params->devtools_worker_token),
params->is_installed);
params->worker_devtools_agent_route_id = routing_id;
// Create DevToolsProxy here to ensure that the WorkerCreated() call is
// balanced by DevToolsProxy's destructor calling WorkerDestroyed().
- devtools_proxy = base::MakeUnique<EmbeddedWorkerInstance::DevToolsProxy>(
+ devtools_proxy = std::make_unique<EmbeddedWorkerInstance::DevToolsProxy>(
process_id, routing_id);
// Set EmbeddedWorkerSettings for content settings only readable from the UI
@@ -415,7 +417,7 @@ class EmbeddedWorkerInstance::StartTask {
// Notify the instance that a process is allocated.
state_ = ProcessAllocationState::ALLOCATED;
instance_->OnProcessAllocated(
- base::MakeUnique<WorkerProcessHandle>(instance_->context_,
+ std::make_unique<WorkerProcessHandle>(instance_->context_,
instance_->embedded_worker_id(),
process_info->process_id),
start_situation);
@@ -476,7 +478,10 @@ void EmbeddedWorkerInstance::Start(
std::unique_ptr<EmbeddedWorkerStartParams> params,
ProviderInfoGetter provider_info_getter,
mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo
+ service_worker_host_ptr_info,
StatusCallback callback) {
restart_count_++;
if (!context_) {
@@ -487,7 +492,8 @@ void EmbeddedWorkerInstance::Start(
DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, status_);
DCHECK(!params->pause_after_download || !params->is_installed);
- DCHECK_NE(kInvalidServiceWorkerVersionId, params->service_worker_version_id);
+ DCHECK_NE(blink::mojom::kInvalidServiceWorkerVersionId,
+ params->service_worker_version_id);
step_time_ = base::TimeTicks::Now();
status_ = EmbeddedWorkerStatus::STARTING;
@@ -501,6 +507,7 @@ void EmbeddedWorkerInstance::Start(
params->embedded_worker_id = embedded_worker_id_;
params->worker_devtools_agent_route_id = MSG_ROUTING_NONE;
params->wait_for_debugger = false;
+ params->devtools_worker_token = devtools_worker_token_;
params->settings.v8_cache_options = GetV8CacheOptions();
mojom::EmbeddedWorkerInstanceClientAssociatedRequest request =
@@ -508,8 +515,10 @@ void EmbeddedWorkerInstance::Start(
client_.set_connection_error_handler(
base::BindOnce(&EmbeddedWorkerInstance::Detach, base::Unretained(this)));
pending_dispatcher_request_ = std::move(dispatcher_request);
+ pending_controller_request_ = std::move(controller_request);
pending_installed_scripts_info_ = std::move(installed_scripts_info);
-
+ pending_service_worker_host_ptr_info_ =
+ std::move(service_worker_host_ptr_info);
inflight_start_task_.reset(
new StartTask(this, params->script_url, std::move(request)));
inflight_start_task_->Start(std::move(params), std::move(callback));
@@ -539,7 +548,7 @@ void EmbeddedWorkerInstance::Stop() {
observer.OnStopping();
}
-void EmbeddedWorkerInstance::StopIfIdle() {
+void EmbeddedWorkerInstance::StopIfNotAttachedToDevTools() {
if (devtools_attached_) {
if (devtools_proxy_) {
// Check ShouldNotifyWorkerStopIgnored not to show the same message
@@ -555,7 +564,7 @@ void EmbeddedWorkerInstance::StopIfIdle() {
Stop();
}
-ServiceWorkerStatusCode EmbeddedWorkerInstance::SendMessage(
+ServiceWorkerStatusCode EmbeddedWorkerInstance::SendIpcMessage(
const IPC::Message& message) {
DCHECK_NE(kInvalidEmbeddedWorkerThreadId, thread_id_);
if (status_ != EmbeddedWorkerStatus::RUNNING &&
@@ -578,9 +587,11 @@ void EmbeddedWorkerInstance::ResumeAfterDownload() {
EmbeddedWorkerInstance::EmbeddedWorkerInstance(
base::WeakPtr<ServiceWorkerContextCore> context,
+ ServiceWorkerVersion* owner_version,
int embedded_worker_id)
: context_(context),
registry_(context->embedded_worker_registry()),
+ owner_version_(owner_version),
embedded_worker_id_(embedded_worker_id),
status_(EmbeddedWorkerStatus::STOPPED),
starting_phase_(NOT_STARTING),
@@ -588,6 +599,7 @@ EmbeddedWorkerInstance::EmbeddedWorkerInstance(
thread_id_(kInvalidEmbeddedWorkerThreadId),
instance_host_binding_(this),
devtools_attached_(false),
+ devtools_worker_token_(base::UnguessableToken::Create()),
network_accessed_for_script_(false),
weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -638,13 +650,15 @@ ServiceWorkerStatusCode EmbeddedWorkerInstance::SendStartWorker(
return SERVICE_WORKER_ERROR_IPC_FAILED;
}
DCHECK(pending_dispatcher_request_.is_pending());
+ DCHECK(pending_controller_request_.is_pending());
+ DCHECK(pending_service_worker_host_ptr_info_.is_valid());
DCHECK(!instance_host_binding_.is_bound());
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo host_ptr_info;
instance_host_binding_.Bind(mojo::MakeRequest(&host_ptr_info));
blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy_ptr_info;
- content_settings_ = base::MakeUnique<ServiceWorkerContentSettingsProxyImpl>(
+ content_settings_ = std::make_unique<ServiceWorkerContentSettingsProxyImpl>(
params->script_url, context_,
mojo::MakeRequest(&content_settings_proxy_ptr_info));
@@ -653,7 +667,9 @@ ServiceWorkerStatusCode EmbeddedWorkerInstance::SendStartWorker(
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
std::move(provider_info_getter_).Run(process_id());
client_->StartWorker(*params, std::move(pending_dispatcher_request_),
+ std::move(pending_controller_request_),
std::move(pending_installed_scripts_info_),
+ std::move(pending_service_worker_host_ptr_info_),
std::move(host_ptr_info), std::move(provider_info),
std::move(content_settings_proxy_ptr_info));
registry_->BindWorkerToProcess(process_id(), embedded_worker_id());
@@ -676,6 +692,27 @@ void EmbeddedWorkerInstance::OnStartWorkerMessageSent(
observer.OnStartWorkerMessageSent();
}
+void EmbeddedWorkerInstance::RequestTermination() {
+ if (!ServiceWorkerUtils::IsServicificationEnabled()) {
+ mojo::ReportBadMessage(
+ "Invalid termination request: RequestTermination() was called but "
+ "S13nServiceWorker is not enabled");
+ return;
+ }
+
+ if (status() != EmbeddedWorkerStatus::RUNNING &&
+ status() != EmbeddedWorkerStatus::STOPPING) {
+ mojo::ReportBadMessage(
+ "Invalid termination request: Termination should be requested during "
+ "running or stopping");
+ return;
+ }
+
+ if (status() == EmbeddedWorkerStatus::STOPPING)
+ return;
+ owner_version_->StopWorkerIfIdle();
+}
+
void EmbeddedWorkerInstance::OnReadyForInspection() {
if (devtools_proxy_)
devtools_proxy_->NotifyWorkerReadyForInspection();
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance.h b/chromium/content/browser/service_worker/embedded_worker_instance.h
index ab558bdc6f6..908f6ebca98 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance.h
+++ b/chromium/content/browser/service_worker/embedded_worker_instance.h
@@ -20,20 +20,18 @@
#include "base/observer_list.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
+#include "base/unguessable_token.h"
#include "content/browser/service_worker/embedded_worker_status.h"
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/common/content_export.h"
+#include "content/common/service_worker/controller_service_worker.mojom.h"
#include "content/common/service_worker/embedded_worker.mojom.h"
#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker.mojom.h"
#include "url/gurl.h"
-// Windows headers will redefine SendMessage.
-#ifdef SendMessage
-#undef SendMessage
-#endif
-
namespace IPC {
class Message;
}
@@ -44,6 +42,7 @@ class EmbeddedWorkerRegistry;
struct EmbeddedWorkerStartParams;
class ServiceWorkerContentSettingsProxyImpl;
class ServiceWorkerContextCore;
+class ServiceWorkerVersion;
// This gives an interface to control one EmbeddedWorker instance, which
// may be 'in-waiting' or running in one of the child processes added by
@@ -136,7 +135,10 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
void Start(std::unique_ptr<EmbeddedWorkerStartParams> params,
ProviderInfoGetter provider_info_getter,
mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo
+ service_worker_host_ptr_info,
StatusCallback callback);
// Stops the worker. It is invalid to call this when the worker is not in
@@ -152,12 +154,12 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
// Stops the worker if the worker is not being debugged (i.e. devtools is
// not attached). This method is called by a stop-worker timer to kill
// idle workers.
- void StopIfIdle();
+ void StopIfNotAttachedToDevTools();
// Sends |message| to the embedded worker running in the child process.
// It is invalid to call this while the worker is not in STARTING or RUNNING
// status.
- ServiceWorkerStatusCode SendMessage(const IPC::Message& message);
+ ServiceWorkerStatusCode SendIpcMessage(const IPC::Message& message);
// Resumes the worker if it paused after download.
void ResumeAfterDownload();
@@ -236,6 +238,7 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
// Constructor is called via EmbeddedWorkerRegistry::CreateWorker().
// This instance holds a ref of |registry|.
EmbeddedWorkerInstance(base::WeakPtr<ServiceWorkerContextCore> context,
+ ServiceWorkerVersion* owner_version,
int embedded_worker_id);
// Called back from StartTask after a process is allocated on the UI thread.
@@ -257,6 +260,7 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
// Implements mojom::EmbeddedWorkerInstanceHost.
// These functions all run on the IO thread.
+ void RequestTermination() override;
void OnReadyForInspection() override;
void OnScriptLoaded() override;
// Notifies the corresponding provider host that the thread has started and is
@@ -299,6 +303,7 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
base::WeakPtr<ServiceWorkerContextCore> context_;
scoped_refptr<EmbeddedWorkerRegistry> registry_;
+ ServiceWorkerVersion* owner_version_;
// Unique within an EmbeddedWorkerRegistry.
const int embedded_worker_id_;
@@ -317,15 +322,18 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
// Binding for EmbeddedWorkerInstanceHost, runs on IO thread.
mojo::AssociatedBinding<EmbeddedWorkerInstanceHost> instance_host_binding_;
- // |pending_dispatcher_request_| and |pending_installed_scripts_info_| are
- // parameters of the StartWorker message. These are called "pending" because
- // they are not used directly by this class and are just transferred to the
- // renderer in SendStartWorker().
- // TODO(shimazu): Remove |pending_dispatcher_request_| and
- // |pending_installed_scripts_info_| when EmbeddedWorkerStartParams is
+ // |pending_dispatcher_request_|, |pending_controller_request_|,
+ // |pending_installed_scripts_info_|, and
+ // |pending_service_worker_host_ptr_info_| are parameters of the StartWorker
+ // message. These are called "pending" because they are not used directly by
+ // this class and are just transferred to the renderer in SendStartWorker().
+ // TODO(shimazu): Remove these when EmbeddedWorkerStartParams is
// changed to a mojo struct and we put them in EmbeddedWorkerStartParams.
mojom::ServiceWorkerEventDispatcherRequest pending_dispatcher_request_;
+ mojom::ControllerServiceWorkerRequest pending_controller_request_;
mojom::ServiceWorkerInstalledScriptsInfoPtr pending_installed_scripts_info_;
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo
+ pending_service_worker_host_ptr_info_;
// This is set at Start and used on SendStartWorker.
ProviderInfoGetter provider_info_getter_;
@@ -333,6 +341,9 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
// Whether devtools is attached or not.
bool devtools_attached_;
+ // Unique token identifying this worker for DevTools.
+ base::UnguessableToken devtools_worker_token_;
+
// True if the script load request accessed the network. If the script was
// served from HTTPCache or ServiceWorkerDatabase this value is false.
bool network_accessed_for_script_;
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 75906b8ccba..b12a01cc60f 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -18,7 +18,9 @@
#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"
+#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
+#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/service_worker/embedded_worker.mojom.h"
#include "content/common/service_worker/embedded_worker_messages.h"
#include "content/common/service_worker/embedded_worker_start_params.h"
@@ -30,6 +32,7 @@
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
namespace content {
@@ -61,8 +64,17 @@ class ProviderHostEndpoints : public mojom::ServiceWorkerContainerHost {
blink::mojom::ServiceWorkerRegistrationObjectInfo::New();
provider_info->registration->options =
blink::mojom::ServiceWorkerRegistrationOptions::New();
+ registration_object_host_request_ =
+ mojo::MakeRequest(&(provider_info->registration->host_ptr_info));
+ provider_info->registration->installing =
+ blink::mojom::ServiceWorkerObjectInfo::New();
+ provider_info->registration->waiting =
+ blink::mojom::ServiceWorkerObjectInfo::New();
+ provider_info->registration->active =
+ blink::mojom::ServiceWorkerObjectInfo::New();
binding_.Bind(mojo::MakeRequest(&provider_info->host_ptr_info));
provider_info->client_request = mojo::MakeRequest(&client_);
+ mojo::MakeRequest(&provider_info->interface_provider);
return provider_info;
}
@@ -88,9 +100,15 @@ class ProviderHostEndpoints : public mojom::ServiceWorkerContainerHost {
mojom::ControllerServiceWorkerRequest request) override {
NOTIMPLEMENTED();
}
+ void CloneForWorker(
+ mojom::ServiceWorkerContainerHostRequest request) override {
+ NOTIMPLEMENTED();
+ }
mojom::ServiceWorkerContainerAssociatedPtr client_;
mojo::AssociatedBinding<mojom::ServiceWorkerContainerHost> binding_;
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedRequest
+ registration_object_host_request_;
DISALLOW_COPY_AND_ASSIGN(ProviderHostEndpoints);
};
@@ -141,6 +159,27 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
void TearDown() override { helper_.reset(); }
+ using RegistrationAndVersionPair =
+ std::pair<scoped_refptr<ServiceWorkerRegistration>,
+ scoped_refptr<ServiceWorkerVersion>>;
+
+ RegistrationAndVersionPair PrepareRegistrationAndVersion(
+ const GURL& scope,
+ const GURL& script_url) {
+ base::RunLoop loop;
+ if (!context()->storage()->LazyInitializeForTest(loop.QuitClosure())) {
+ loop.Run();
+ }
+ RegistrationAndVersionPair pair;
+ pair.first = base::MakeRefCounted<ServiceWorkerRegistration>(
+ blink::mojom::ServiceWorkerRegistrationOptions(scope),
+ context()->storage()->NewRegistrationId(), context()->AsWeakPtr());
+ pair.second = base::MakeRefCounted<ServiceWorkerVersion>(
+ pair.first.get(), script_url, context()->storage()->NewVersionId(),
+ context()->AsWeakPtr());
+ return pair;
+ }
+
ServiceWorkerStatusCode StartWorker(EmbeddedWorkerInstance* worker,
int id, const GURL& pattern,
const GURL& url) {
@@ -150,7 +189,8 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
CreateStartParams(id, pattern, url);
worker->Start(
std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
- GetInstalledScriptsInfoPtr(),
+ CreateController(), GetInstalledScriptsInfoPtr(),
+ GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
run_loop.Run();
return status;
@@ -159,7 +199,7 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
std::unique_ptr<EmbeddedWorkerStartParams>
CreateStartParams(int version_id, const GURL& scope, const GURL& script_url) {
std::unique_ptr<EmbeddedWorkerStartParams> params =
- base::MakeUnique<EmbeddedWorkerStartParams>();
+ std::make_unique<EmbeddedWorkerStartParams>();
params->service_worker_version_id = version_id;
params->scope = scope;
params->script_url = script_url;
@@ -171,7 +211,7 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr CreateProviderInfo(
int /* process_id */) {
provider_host_endpoints_.emplace_back(
- base::MakeUnique<ProviderHostEndpoints>());
+ std::make_unique<ProviderHostEndpoints>());
return provider_host_endpoints_.back()->CreateProviderInfoPtr();
}
@@ -185,6 +225,11 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
return mojo::MakeRequest(&dispatchers_.back());
}
+ mojom::ControllerServiceWorkerRequest CreateController() {
+ controllers_.emplace_back();
+ return mojo::MakeRequest(&controllers_.back());
+ }
+
void SetWorkerStatus(EmbeddedWorkerInstance* worker,
EmbeddedWorkerStatus status) {
worker->status_ = status;
@@ -201,9 +246,18 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
auto info = mojom::ServiceWorkerInstalledScriptsInfo::New();
info->manager_request =
mojo::MakeRequest(&installed_scripts_managers_.back());
+ installed_scripts_manager_host_requests_.push_back(
+ mojo::MakeRequest(&info->manager_host_ptr));
return info;
}
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo
+ GetServiceWorkerHostPtrInfo() {
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo ptr_info;
+ service_worker_host_requests_.push_back(mojo::MakeRequest(&ptr_info));
+ return ptr_info;
+ }
+
ServiceWorkerContextCore* context() { return helper_->context(); }
EmbeddedWorkerRegistry* embedded_worker_registry() {
@@ -221,8 +275,13 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
// Mojo endpoints.
std::vector<mojom::ServiceWorkerEventDispatcherPtr> dispatchers_;
+ std::vector<mojom::ControllerServiceWorkerPtr> controllers_;
std::vector<mojom::ServiceWorkerInstalledScriptsManagerPtr>
installed_scripts_managers_;
+ std::vector<mojom::ServiceWorkerInstalledScriptsManagerHostRequest>
+ installed_scripts_manager_host_requests_;
+ std::vector<blink::mojom::ServiceWorkerHostAssociatedRequest>
+ service_worker_host_requests_;
std::vector<std::unique_ptr<ProviderHostEndpoints>> provider_host_endpoints_;
TestBrowserThreadBundle thread_bundle_;
@@ -246,9 +305,12 @@ class StalledInStartWorkerHelper : public EmbeddedWorkerTestHelper {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info)
override {
if (force_stall_in_start_) {
// Prepare for OnStopWorker().
@@ -258,8 +320,10 @@ class StalledInStartWorkerHelper : public EmbeddedWorkerTestHelper {
}
EmbeddedWorkerTestHelper::OnStartWorker(
embedded_worker_id, service_worker_version_id, scope, script_url,
- pause_after_download, std::move(request), std::move(instance_host),
- std::move(provider_info));
+ pause_after_download, std::move(dispatcher_request),
+ std::move(controller_request), std::move(service_worker_host),
+ std::move(instance_host), std::move(provider_info),
+ std::move(installed_scripts_info));
}
void OnStopWorker(int embedded_worker_id) override {
@@ -285,15 +349,16 @@ class StalledInStartWorkerHelper : public EmbeddedWorkerTestHelper {
};
TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
+ const GURL pattern("http://example.com/");
+ const GURL url("http://example.com/worker.js");
+
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(pattern, url);
+ const int64_t service_worker_version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
worker->AddListener(this);
- const int64_t service_worker_version_id = 55L;
- const GURL pattern("http://example.com/");
- const GURL url("http://example.com/worker.js");
-
// Simulate adding one process to the pattern.
helper_->SimulateAddProcessToPattern(pattern,
helper_->mock_render_process_id());
@@ -305,7 +370,8 @@ TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
CreateStartParams(service_worker_version_id, pattern, url);
worker->Start(
std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
- GetInstalledScriptsInfoPtr(),
+ CreateController(), GetInstalledScriptsInfoPtr(),
+ GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
run_loop.Run();
@@ -336,14 +402,15 @@ TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
// Test that a worker that failed twice will use a new render process
// on the next attempt.
TEST_F(EmbeddedWorkerInstanceTest, ForceNewProcess) {
- std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
- EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
-
- const int64_t service_worker_version_id = 55L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(pattern, url);
+ const int64_t service_worker_version_id = pair.second->version_id();
+ std::unique_ptr<EmbeddedWorkerInstance> worker =
+ embedded_worker_registry()->CreateWorker(pair.second.get());
+ EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
+
// Simulate adding one process to the pattern.
helper_->SimulateAddProcessToPattern(pattern,
helper_->mock_render_process_id());
@@ -363,7 +430,8 @@ TEST_F(EmbeddedWorkerInstanceTest, ForceNewProcess) {
CreateStartParams(service_worker_version_id, pattern, url);
worker->Start(
std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
- GetInstalledScriptsInfoPtr(),
+ CreateController(), GetInstalledScriptsInfoPtr(),
+ GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
run_loop.Run();
EXPECT_EQ(SERVICE_WORKER_OK, status);
@@ -389,7 +457,8 @@ TEST_F(EmbeddedWorkerInstanceTest, ForceNewProcess) {
CreateStartParams(service_worker_version_id, pattern, url);
worker->Start(
std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
- GetInstalledScriptsInfoPtr(),
+ CreateController(), GetInstalledScriptsInfoPtr(),
+ GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
run_loop.Run();
@@ -404,24 +473,25 @@ TEST_F(EmbeddedWorkerInstanceTest, ForceNewProcess) {
}
TEST_F(EmbeddedWorkerInstanceTest, StopWhenDevToolsAttached) {
- std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
- EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
-
- const int64_t service_worker_version_id = 55L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(pattern, url);
+ const int64_t service_worker_version_id = pair.second->version_id();
+ std::unique_ptr<EmbeddedWorkerInstance> worker =
+ embedded_worker_registry()->CreateWorker(pair.second.get());
+ EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
+
// Simulate adding one process to the pattern.
helper_->SimulateAddProcessToPattern(pattern,
helper_->mock_render_process_id());
- // Start the worker and then call StopIfIdle().
+ // Start the worker and then call StopIfNotAttachedToDevTools().
EXPECT_EQ(SERVICE_WORKER_OK,
StartWorker(worker.get(), service_worker_version_id, pattern, url));
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
EXPECT_EQ(helper_->mock_render_process_id(), worker->process_id());
- worker->StopIfIdle();
+ worker->StopIfNotAttachedToDevTools();
EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, worker->status());
base::RunLoop().RunUntilIdle();
@@ -435,7 +505,7 @@ TEST_F(EmbeddedWorkerInstanceTest, StopWhenDevToolsAttached) {
StartWorker(worker.get(), service_worker_version_id, pattern, url));
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
EXPECT_EQ(helper_->mock_render_process_id(), worker->process_id());
- worker->StopIfIdle();
+ worker->StopIfNotAttachedToDevTools();
base::RunLoop().RunUntilIdle();
// The worker must not be stopped this time.
@@ -451,15 +521,20 @@ TEST_F(EmbeddedWorkerInstanceTest, StopWhenDevToolsAttached) {
// Test that the removal of a worker from the registry doesn't remove
// other workers in the same process.
TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) {
+ const GURL pattern("http://example.com/");
+ const GURL url("http://example.com/worker.js");
+
+ RegistrationAndVersionPair pair1 =
+ PrepareRegistrationAndVersion(pattern, url);
std::unique_ptr<EmbeddedWorkerInstance> worker1 =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair1.second.get());
+ RegistrationAndVersionPair pair2 =
+ PrepareRegistrationAndVersion(pattern, url);
std::unique_ptr<EmbeddedWorkerInstance> worker2 =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair2.second.get());
- const int64_t version_id1 = 55L;
- const int64_t version_id2 = 56L;
- const GURL pattern("http://example.com/");
- const GURL url("http://example.com/worker.js");
+ const int64_t version_id1 = pair1.second->version_id();
+ const int64_t version_id2 = pair2.second->version_id();
int process_id = helper_->mock_render_process_id();
helper_->SimulateAddProcessToPattern(pattern, process_id);
@@ -471,7 +546,8 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) {
CreateStartParams(version_id1, pattern, url);
worker1->Start(
std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
- GetInstalledScriptsInfoPtr(),
+ CreateController(), GetInstalledScriptsInfoPtr(),
+ GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
run_loop.Run();
EXPECT_EQ(SERVICE_WORKER_OK, status);
@@ -485,7 +561,8 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) {
CreateStartParams(version_id2, pattern, url);
worker2->Start(
std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
- GetInstalledScriptsInfoPtr(),
+ CreateController(), GetInstalledScriptsInfoPtr(),
+ GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
run_loop.Run();
EXPECT_EQ(SERVICE_WORKER_OK, status);
@@ -510,12 +587,13 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) {
}
TEST_F(EmbeddedWorkerInstanceTest, DetachDuringProcessAllocation) {
- const int64_t version_id = 55L;
const GURL scope("http://example.com/");
const GURL url("http://example.com/worker.js");
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
+ const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
worker->AddListener(this);
// Run the start worker sequence and detach during process allocation.
@@ -523,7 +601,8 @@ TEST_F(EmbeddedWorkerInstanceTest, DetachDuringProcessAllocation) {
std::unique_ptr<EmbeddedWorkerStartParams> params =
CreateStartParams(version_id, scope, url);
worker->Start(std::move(params), CreateProviderInfoGetter(),
- CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+ CreateEventDispatcher(), CreateController(),
+ GetInstalledScriptsInfoPtr(), GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status,
base::BindOnce(&base::DoNothing)));
worker->Detach();
@@ -543,13 +622,14 @@ TEST_F(EmbeddedWorkerInstanceTest, DetachDuringProcessAllocation) {
}
TEST_F(EmbeddedWorkerInstanceTest, DetachAfterSendingStartWorkerMessage) {
- const int64_t version_id = 55L;
const GURL scope("http://example.com/");
const GURL url("http://example.com/worker.js");
helper_.reset(new StalledInStartWorkerHelper());
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
+ const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
worker->AddListener(this);
// Run the start worker sequence until a start worker message is sent.
@@ -557,7 +637,8 @@ TEST_F(EmbeddedWorkerInstanceTest, DetachAfterSendingStartWorkerMessage) {
std::unique_ptr<EmbeddedWorkerStartParams> params =
CreateStartParams(version_id, scope, url);
worker->Start(std::move(params), CreateProviderInfoGetter(),
- CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+ CreateEventDispatcher(), CreateController(),
+ GetInstalledScriptsInfoPtr(), GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status,
base::BindOnce(&base::DoNothing)));
base::RunLoop().RunUntilIdle();
@@ -584,12 +665,13 @@ TEST_F(EmbeddedWorkerInstanceTest, DetachAfterSendingStartWorkerMessage) {
}
TEST_F(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) {
- const int64_t version_id = 55L;
const GURL scope("http://example.com/");
const GURL url("http://example.com/worker.js");
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
+ const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
worker->AddListener(this);
// Stop the start worker sequence before a process is allocated.
@@ -598,7 +680,8 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) {
std::unique_ptr<EmbeddedWorkerStartParams> params =
CreateStartParams(version_id, scope, url);
worker->Start(std::move(params), CreateProviderInfoGetter(),
- CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+ CreateEventDispatcher(), CreateController(),
+ GetInstalledScriptsInfoPtr(), GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status,
base::BindOnce(&base::DoNothing)));
worker->Stop();
@@ -623,7 +706,8 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) {
params = CreateStartParams(version_id, scope, url);
worker->Start(
std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
- GetInstalledScriptsInfoPtr(),
+ CreateController(), GetInstalledScriptsInfoPtr(),
+ GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status, run_loop->QuitClosure()));
run_loop->Run();
@@ -655,17 +739,18 @@ class DontReceiveResumeAfterDownloadInstanceClient
};
TEST_F(EmbeddedWorkerInstanceTest, StopDuringPausedAfterDownload) {
- const int64_t version_id = 55L;
const GURL scope("http://example.com/");
const GURL url("http://example.com/worker.js");
bool was_resume_after_download_called = false;
helper_->RegisterMockInstanceClient(
- base::MakeUnique<DontReceiveResumeAfterDownloadInstanceClient>(
+ std::make_unique<DontReceiveResumeAfterDownloadInstanceClient>(
helper_->AsWeakPtr(), &was_resume_after_download_called));
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
+ const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
worker->AddListener(this);
// Run the start worker sequence until pause after download.
@@ -675,7 +760,8 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringPausedAfterDownload) {
CreateStartParams(version_id, scope, url);
params->pause_after_download = true;
worker->Start(std::move(params), CreateProviderInfoGetter(),
- CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+ CreateEventDispatcher(), CreateController(),
+ GetInstalledScriptsInfoPtr(), GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status,
base::BindOnce(&base::DoNothing)));
base::RunLoop().RunUntilIdle();
@@ -692,13 +778,14 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringPausedAfterDownload) {
}
TEST_F(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) {
- const int64_t version_id = 55L;
const GURL scope("http://example.com/");
const GURL url("http://example.com/worker.js");
helper_.reset(new StalledInStartWorkerHelper);
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
+ const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
worker->AddListener(this);
// Run the start worker sequence until a start worker message is sent.
@@ -706,7 +793,8 @@ TEST_F(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) {
std::unique_ptr<EmbeddedWorkerStartParams> params =
CreateStartParams(version_id, scope, url);
worker->Start(std::move(params), CreateProviderInfoGetter(),
- CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+ CreateEventDispatcher(), CreateController(),
+ GetInstalledScriptsInfoPtr(), GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status,
base::BindOnce(&base::DoNothing)));
base::RunLoop().RunUntilIdle();
@@ -741,7 +829,8 @@ TEST_F(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) {
params = CreateStartParams(version_id, scope, url);
worker->Start(
std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
- GetInstalledScriptsInfoPtr(),
+ CreateController(), GetInstalledScriptsInfoPtr(),
+ GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status, run_loop->QuitClosure()));
run_loop->Run();
@@ -757,11 +846,13 @@ TEST_F(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) {
}
TEST_F(EmbeddedWorkerInstanceTest, Detach) {
- const int64_t version_id = 55L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
+
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(pattern, url);
+ const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
helper_->SimulateAddProcessToPattern(pattern,
helper_->mock_render_process_id());
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
@@ -773,7 +864,8 @@ TEST_F(EmbeddedWorkerInstanceTest, Detach) {
CreateStartParams(version_id, pattern, url);
worker->Start(
std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
- GetInstalledScriptsInfoPtr(),
+ CreateController(), GetInstalledScriptsInfoPtr(),
+ GetServiceWorkerHostPtrInfo(),
base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
run_loop.Run();
@@ -791,15 +883,16 @@ TEST_F(EmbeddedWorkerInstanceTest, Detach) {
// Test for when sending the start IPC failed.
TEST_F(EmbeddedWorkerInstanceTest, FailToSendStartIPC) {
- const int64_t version_id = 55L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
// Let StartWorker fail; mojo IPC fails to connect to a remote interface.
helper_->RegisterMockInstanceClient(nullptr);
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(pattern, url);
+ const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
helper_->SimulateAddProcessToPattern(pattern,
helper_->mock_render_process_id());
worker->AddListener(this);
@@ -808,7 +901,8 @@ TEST_F(EmbeddedWorkerInstanceTest, FailToSendStartIPC) {
std::unique_ptr<EmbeddedWorkerStartParams> params =
CreateStartParams(version_id, pattern, url);
worker->Start(std::move(params), CreateProviderInfoGetter(),
- CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+ CreateEventDispatcher(), CreateController(),
+ GetInstalledScriptsInfoPtr(), GetServiceWorkerHostPtrInfo(),
base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
base::RunLoop().RunUntilIdle();
@@ -831,7 +925,9 @@ class FailEmbeddedWorkerInstanceClientImpl
private:
void StartWorker(const EmbeddedWorkerStartParams&,
mojom::ServiceWorkerEventDispatcherRequest,
+ mojom::ControllerServiceWorkerRequest,
mojom::ServiceWorkerInstalledScriptsInfoPtr /* unused */,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr,
blink::mojom::WorkerContentSettingsProxyPtr
@@ -841,18 +937,19 @@ class FailEmbeddedWorkerInstanceClientImpl
};
TEST_F(EmbeddedWorkerInstanceTest, RemoveRemoteInterface) {
- const int64_t version_id = 55L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
// Let StartWorker fail; binding is discarded in the middle of IPC
helper_->RegisterMockInstanceClient(
- base::MakeUnique<FailEmbeddedWorkerInstanceClientImpl>(
+ std::make_unique<FailEmbeddedWorkerInstanceClientImpl>(
helper_->AsWeakPtr()));
ASSERT_EQ(mock_instance_clients()->size(), 1UL);
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(pattern, url);
+ const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
helper_->SimulateAddProcessToPattern(pattern,
helper_->mock_render_process_id());
worker->AddListener(this);
@@ -861,7 +958,8 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveRemoteInterface) {
std::unique_ptr<EmbeddedWorkerStartParams> params =
CreateStartParams(version_id, pattern, url);
worker->Start(std::move(params), CreateProviderInfoGetter(),
- CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+ CreateEventDispatcher(), CreateController(),
+ GetInstalledScriptsInfoPtr(), GetServiceWorkerHostPtrInfo(),
base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
base::RunLoop().RunUntilIdle();
@@ -896,17 +994,18 @@ class StoreMessageInstanceClient
};
TEST_F(EmbeddedWorkerInstanceTest, AddMessageToConsole) {
- const int64_t version_id = 55L;
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
std::unique_ptr<StoreMessageInstanceClient> instance_client =
- base::MakeUnique<StoreMessageInstanceClient>(helper_->AsWeakPtr());
+ std::make_unique<StoreMessageInstanceClient>(helper_->AsWeakPtr());
StoreMessageInstanceClient* instance_client_rawptr = instance_client.get();
helper_->RegisterMockInstanceClient(std::move(instance_client));
ASSERT_EQ(mock_instance_clients()->size(), 1UL);
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(pattern, url);
+ const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
helper_->SimulateAddProcessToPattern(pattern,
helper_->mock_render_process_id());
worker->AddListener(this);
@@ -918,7 +1017,8 @@ TEST_F(EmbeddedWorkerInstanceTest, AddMessageToConsole) {
std::unique_ptr<EmbeddedWorkerStartParams> params =
CreateStartParams(version_id, pattern, url);
worker->Start(std::move(params), CreateProviderInfoGetter(),
- CreateEventDispatcher(), GetInstalledScriptsInfoPtr(),
+ CreateEventDispatcher(), CreateController(),
+ GetInstalledScriptsInfoPtr(), GetServiceWorkerHostPtrInfo(),
base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
worker->AddMessageToConsole(test_message.first, test_message.second);
base::RunLoop().RunUntilIdle();
@@ -947,10 +1047,14 @@ TEST_F(EmbeddedWorkerInstanceTest, AddMessageToConsole) {
// Test that SendStartWorker checks if dispatcher host exists.
TEST_F(EmbeddedWorkerInstanceTest, NoDispatcherHost) {
+ const GURL scope("http://example.com/");
+ const GURL url("http://example.com/worker.js");
+
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
std::unique_ptr<EmbeddedWorkerInstance> worker =
- embedded_worker_registry()->CreateWorker();
+ embedded_worker_registry()->CreateWorker(pair.second.get());
SetWorkerStatus(worker.get(), EmbeddedWorkerStatus::STARTING);
- auto params = base::MakeUnique<EmbeddedWorkerStartParams>();
+ auto params = std::make_unique<EmbeddedWorkerStartParams>();
ServiceWorkerStatusCode result =
SimulateSendStartWorker(worker.get(), std::move(params));
EXPECT_EQ(SERVICE_WORKER_ERROR_IPC_FAILED, result);
diff --git a/chromium/content/browser/service_worker/embedded_worker_registry.cc b/chromium/content/browser/service_worker/embedded_worker_registry.cc
index cedc3228f7e..d5a9faf207a 100644
--- a/chromium/content/browser/service_worker/embedded_worker_registry.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_registry.cc
@@ -36,9 +36,10 @@ scoped_refptr<EmbeddedWorkerRegistry> EmbeddedWorkerRegistry::Create(
return registry;
}
-std::unique_ptr<EmbeddedWorkerInstance> EmbeddedWorkerRegistry::CreateWorker() {
- std::unique_ptr<EmbeddedWorkerInstance> worker(
- new EmbeddedWorkerInstance(context_, next_embedded_worker_id_));
+std::unique_ptr<EmbeddedWorkerInstance> EmbeddedWorkerRegistry::CreateWorker(
+ ServiceWorkerVersion* owner_version) {
+ std::unique_ptr<EmbeddedWorkerInstance> worker(new EmbeddedWorkerInstance(
+ context_, owner_version, next_embedded_worker_id_));
worker_map_[next_embedded_worker_id_++] = worker.get();
return worker;
}
diff --git a/chromium/content/browser/service_worker/embedded_worker_registry.h b/chromium/content/browser/service_worker/embedded_worker_registry.h
index 4ff60bc386e..7626c42b0fc 100644
--- a/chromium/content/browser/service_worker/embedded_worker_registry.h
+++ b/chromium/content/browser/service_worker/embedded_worker_registry.h
@@ -27,6 +27,7 @@ namespace content {
class EmbeddedWorkerInstance;
class ServiceWorkerContextCore;
+class ServiceWorkerVersion;
// Acts as a thin stub between MessageFilter and each EmbeddedWorkerInstance,
// which sends/receives messages to/from each EmbeddedWorker in child process.
@@ -37,7 +38,7 @@ class CONTENT_EXPORT EmbeddedWorkerRegistry
: public base::RefCounted<EmbeddedWorkerRegistry> {
public:
static scoped_refptr<EmbeddedWorkerRegistry> Create(
- const base::WeakPtr<ServiceWorkerContextCore>& contxet);
+ const base::WeakPtr<ServiceWorkerContextCore>& context);
// Used for DeleteAndStartOver. Creates a new registry which takes over
// |next_embedded_worker_id_| and |process_sender_map_| from |old_registry|.
@@ -49,7 +50,8 @@ class CONTENT_EXPORT EmbeddedWorkerRegistry
// Creates and removes a new worker instance entry for bookkeeping.
// This doesn't actually start or stop the worker.
- std::unique_ptr<EmbeddedWorkerInstance> CreateWorker();
+ std::unique_ptr<EmbeddedWorkerInstance> CreateWorker(
+ ServiceWorkerVersion* owner_version);
// Stop all running workers, even if they're handling events.
void Shutdown();
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 84b1c746fe2..9bebc036567 100644
--- a/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -65,6 +65,27 @@ class MockServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost {
DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerDispatcherHost);
};
+void OnFetchEventCommon(
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
+ finish_callback) {
+ response_callback->OnResponse(
+ ServiceWorkerResponse(
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
+ network::mojom::FetchResponseType::kDefault,
+ std::make_unique<ServiceWorkerHeaderMap>(), std::string(), 0,
+ nullptr /* blob */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time(),
+ false /* is_in_cache_storage */,
+ std::string() /* cache_storage_cache_name */,
+ std::make_unique<
+ ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
+ base::Time::Now());
+ std::move(finish_callback)
+ .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
+ base::Time::Now());
+}
+
} // namespace
EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::
@@ -78,7 +99,9 @@ EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::
void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StartWorker(
const EmbeddedWorkerStartParams& params,
mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy) {
@@ -92,9 +115,10 @@ void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StartWorker(
ASSERT_TRUE(worker);
EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
- helper_->OnStartWorkerStub(params, std::move(dispatcher_request),
- std::move(instance_host),
- std::move(provider_info));
+ helper_->OnStartWorkerStub(
+ params, std::move(dispatcher_request), std::move(controller_request),
+ std::move(service_worker_host), std::move(instance_host),
+ std::move(provider_info), std::move(installed_scripts_info));
}
void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StopWorker() {
@@ -134,7 +158,7 @@ void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::Bind(
ASSERT_GE(clients->size(), next_client_index);
if (clients->size() == next_client_index) {
clients->push_back(
- base::MakeUnique<MockEmbeddedWorkerInstanceClient>(helper));
+ std::make_unique<MockEmbeddedWorkerInstanceClient>(helper));
}
std::unique_ptr<MockEmbeddedWorkerInstanceClient>& client =
@@ -151,7 +175,7 @@ class EmbeddedWorkerTestHelper::MockServiceWorkerEventDispatcher
int thread_id,
mojom::ServiceWorkerEventDispatcherRequest request) {
mojo::MakeStrongBinding(
- base::MakeUnique<MockServiceWorkerEventDispatcher>(helper, thread_id),
+ std::make_unique<MockServiceWorkerEventDispatcher>(helper, thread_id),
std::move(request));
}
@@ -163,11 +187,10 @@ class EmbeddedWorkerTestHelper::MockServiceWorkerEventDispatcher
~MockServiceWorkerEventDispatcher() override {}
void DispatchInstallEvent(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client,
DispatchInstallEventCallback callback) override {
if (!helper_)
return;
- helper_->OnInstallEventStub(std::move(client), std::move(callback));
+ helper_->OnInstallEventStub(std::move(callback));
}
void DispatchActivateEvent(DispatchActivateEventCallback callback) override {
@@ -215,19 +238,30 @@ class EmbeddedWorkerTestHelper::MockServiceWorkerEventDispatcher
std::move(callback));
}
- void DispatchFetchEvent(
- int fetch_event_id,
+ void DispatchLegacyFetchEvent(
const ServiceWorkerFetchRequest& request,
mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) override {
if (!helper_)
return;
- helper_->OnFetchEventStub(
- thread_id_, fetch_event_id, request, std::move(preload_handle),
+ helper_->OnLegacyFetchEventStub(
+ thread_id_, request, std::move(preload_handle),
std::move(response_callback), std::move(callback));
}
+ void DispatchFetchEvent(
+ const ResourceRequest& request,
+ mojom::FetchEventPreloadHandlePtr preload_handle,
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ DispatchFetchEventCallback callback) override {
+ if (!helper_)
+ return;
+ helper_->OnFetchEventStub(thread_id_, request, std::move(preload_handle),
+ std::move(response_callback),
+ std::move(callback));
+ }
+
void DispatchNotificationClickEvent(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
@@ -362,6 +396,8 @@ class EmbeddedWorkerTestHelper::MockRendererInterface : public mojom::Renderer {
NOTREACHED();
}
void PurgePluginListCache(bool reload_pages) override { NOTREACHED(); }
+ void SetProcessBackgrounded(bool backgrounded) override { NOTREACHED(); }
+ void ProcessPurgeAndSuspend() override { NOTREACHED(); }
base::WeakPtr<EmbeddedWorkerTestHelper> helper_;
mojo::AssociatedBindingSet<mojom::Renderer> bindings_;
@@ -374,11 +410,11 @@ EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
const base::FilePath& user_data_directory,
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter)
- : browser_context_(base::MakeUnique<TestBrowserContext>()),
+ : browser_context_(std::make_unique<TestBrowserContext>()),
render_process_host_(
- base::MakeUnique<MockRenderProcessHost>(browser_context_.get())),
+ std::make_unique<MockRenderProcessHost>(browser_context_.get())),
new_render_process_host_(
- base::MakeUnique<MockRenderProcessHost>(browser_context_.get())),
+ std::make_unique<MockRenderProcessHost>(browser_context_.get())),
wrapper_(base::MakeRefCounted<ServiceWorkerContextWrapper>(
browser_context_.get())),
mock_instance_clients_next_index_(0),
@@ -405,19 +441,21 @@ EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
// Install a mocked mojom::Renderer interface to catch requests to
// establish Mojo connection for EWInstanceClient.
mock_renderer_interface_ =
- base::MakeUnique<MockRendererInterface>(AsWeakPtr());
+ std::make_unique<MockRendererInterface>(AsWeakPtr());
auto renderer_interface_ptr =
- base::MakeUnique<mojom::RendererAssociatedPtr>();
+ std::make_unique<mojom::RendererAssociatedPtr>();
mock_renderer_interface_->AddBinding(
- mojo::MakeIsolatedRequest(renderer_interface_ptr.get()));
+ mojo::MakeRequestAssociatedWithDedicatedPipe(
+ renderer_interface_ptr.get()));
render_process_host_->OverrideRendererInterfaceForTesting(
std::move(renderer_interface_ptr));
auto new_renderer_interface_ptr =
- base::MakeUnique<mojom::RendererAssociatedPtr>();
+ std::make_unique<mojom::RendererAssociatedPtr>();
mock_renderer_interface_->AddBinding(
- mojo::MakeIsolatedRequest(new_renderer_interface_ptr.get()));
+ mojo::MakeRequestAssociatedWithDedicatedPipe(
+ new_renderer_interface_ptr.get()));
new_render_process_host_->OverrideRendererInterfaceForTesting(
std::move(new_renderer_interface_ptr));
}
@@ -478,7 +516,7 @@ ServiceWorkerContextCore* EmbeddedWorkerTestHelper::context() {
void EmbeddedWorkerTestHelper::ShutdownContext() {
wrapper_->Shutdown();
- wrapper_ = NULL;
+ wrapper_ = nullptr;
}
ServiceWorkerDispatcherHost*
@@ -504,24 +542,36 @@ void EmbeddedWorkerTestHelper::OnStartWorker(
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info) {
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
ASSERT_TRUE(worker);
MockServiceWorkerEventDispatcher::Create(AsWeakPtr(), worker->thread_id(),
- std::move(request));
-
+ std::move(dispatcher_request));
embedded_worker_id_service_worker_version_id_map_[embedded_worker_id] =
service_worker_version_id;
embedded_worker_id_instance_host_ptr_map_[embedded_worker_id].Bind(
std::move(instance_host));
+ embedded_worker_id_installed_scripts_info_map_[embedded_worker_id] =
+ std::move(installed_scripts_info);
ServiceWorkerRemoteProviderEndpoint* provider_endpoint =
&embedded_worker_id_remote_provider_map_[embedded_worker_id];
provider_endpoint->BindWithProviderInfo(std::move(provider_info));
SimulateWorkerReadyForInspection(embedded_worker_id);
- SimulateWorkerScriptCached(embedded_worker_id);
+ SimulateWorkerScriptCached(
+ embedded_worker_id,
+ base::BindOnce(&EmbeddedWorkerTestHelper::DidSimulateWorkerScriptCached,
+ AsWeakPtr(), embedded_worker_id, pause_after_download));
+}
+
+void EmbeddedWorkerTestHelper::DidSimulateWorkerScriptCached(
+ int embedded_worker_id,
+ bool pause_after_download) {
SimulateWorkerScriptLoaded(embedded_worker_id);
if (!pause_after_download)
OnResumeAfterDownload(embedded_worker_id);
@@ -591,7 +641,6 @@ void EmbeddedWorkerTestHelper::OnExtendableMessageEvent(
}
void EmbeddedWorkerTestHelper::OnInstallEvent(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client,
mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
callback) {
dispatched_events()->push_back(Event::Install);
@@ -601,26 +650,22 @@ void EmbeddedWorkerTestHelper::OnInstallEvent(
void EmbeddedWorkerTestHelper::OnFetchEvent(
int /* embedded_worker_id */,
- int /* fetch_event_id */,
+ const ResourceRequest& /* request */,
+ mojom::FetchEventPreloadHandlePtr /* preload_handle */,
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
+ finish_callback) {
+ OnFetchEventCommon(std::move(response_callback), std::move(finish_callback));
+}
+
+void EmbeddedWorkerTestHelper::OnLegacyFetchEvent(
+ int /* embedded_worker_id */,
const ServiceWorkerFetchRequest& /* request */,
mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
finish_callback) {
- response_callback->OnResponse(
- ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
- network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), std::string(), 0,
- nullptr /* blob */, blink::kWebServiceWorkerResponseErrorUnknown,
- base::Time(), false /* is_in_cache_storage */,
- std::string() /* cache_storage_cache_name */,
- base::MakeUnique<
- ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
- base::Time::Now());
- std::move(finish_callback)
- .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ OnFetchEventCommon(std::move(response_callback), std::move(finish_callback));
}
void EmbeddedWorkerTestHelper::OnPushEvent(
@@ -701,23 +746,30 @@ void EmbeddedWorkerTestHelper::SimulateWorkerReadyForInspection(
}
void EmbeddedWorkerTestHelper::SimulateWorkerScriptCached(
- int embedded_worker_id) {
+ int embedded_worker_id,
+ base::OnceClosure callback) {
int64_t version_id =
embedded_worker_id_service_worker_version_id_map_[embedded_worker_id];
ServiceWorkerVersion* version = context()->GetLiveVersion(version_id);
- if (!version)
+ if (!version) {
+ std::move(callback).Run();
return;
+ }
if (!version->script_cache_map()->size()) {
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
// Add a dummy ResourceRecord for the main script to the script cache map of
- // the ServiceWorkerVersion. We use embedded_worker_id for resource_id to
- // avoid ID collision.
- records.push_back(ServiceWorkerDatabase::ResourceRecord(
- embedded_worker_id, version->script_url(), 100));
+ // the ServiceWorkerVersion.
+ records.push_back(WriteToDiskCacheAsync(
+ context()->storage(), version->script_url(),
+ context()->storage()->NewResourceId(), {} /* headers */, "I'm a body",
+ "I'm a meta data", std::move(callback)));
version->script_cache_map()->SetResources(records);
}
if (!version->GetMainScriptHttpResponseInfo())
version->SetMainScriptHttpResponseInfo(CreateHttpResponseInfo());
+ // Call |callback| if |version| already has ResourceRecords.
+ if (!callback.is_null())
+ std::move(callback).Run();
}
void EmbeddedWorkerTestHelper::SimulateWorkerScriptLoaded(
@@ -778,21 +830,25 @@ void EmbeddedWorkerTestHelper::SimulateSend(IPC::Message* message) {
void EmbeddedWorkerTestHelper::OnStartWorkerStub(
const EmbeddedWorkerStartParams& params,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info) {
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info) {
EmbeddedWorkerInstance* worker =
registry()->GetWorker(params.embedded_worker_id);
ASSERT_TRUE(worker);
EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(&EmbeddedWorkerTestHelper::OnStartWorker, AsWeakPtr(),
- params.embedded_worker_id,
- params.service_worker_version_id, params.scope,
- params.script_url, params.pause_after_download,
- base::Passed(&request), base::Passed(&instance_host),
- base::Passed(&provider_info)));
+ base::BindOnce(
+ &EmbeddedWorkerTestHelper::OnStartWorker, AsWeakPtr(),
+ params.embedded_worker_id, params.service_worker_version_id,
+ params.scope, params.script_url, params.pause_after_download,
+ std::move(dispatcher_request), std::move(controller_request),
+ std::move(service_worker_host), std::move(instance_host),
+ std::move(provider_info), std::move(installed_scripts_info)));
}
void EmbeddedWorkerTestHelper::OnResumeAfterDownloadStub(
@@ -887,19 +943,16 @@ void EmbeddedWorkerTestHelper::OnExtendableMessageEventStub(
}
void EmbeddedWorkerTestHelper::OnInstallEventStub(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client,
mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&EmbeddedWorkerTestHelper::OnInstallEvent, AsWeakPtr(),
- base::Passed(&client), base::Passed(&callback)));
+ FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnInstallEvent,
+ AsWeakPtr(), std::move(callback)));
}
void EmbeddedWorkerTestHelper::OnFetchEventStub(
int thread_id,
- int fetch_event_id,
- const ServiceWorkerFetchRequest& request,
+ const ResourceRequest& request,
mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
@@ -907,10 +960,24 @@ void EmbeddedWorkerTestHelper::OnFetchEventStub(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnFetchEvent, AsWeakPtr(),
- thread_id_embedded_worker_id_map_[thread_id],
- fetch_event_id, request, base::Passed(&preload_handle),
- base::Passed(&response_callback),
- base::Passed(&finish_callback)));
+ thread_id_embedded_worker_id_map_[thread_id], request,
+ std::move(preload_handle), std::move(response_callback),
+ std::move(finish_callback)));
+}
+
+void EmbeddedWorkerTestHelper::OnLegacyFetchEventStub(
+ int thread_id,
+ const ServiceWorkerFetchRequest& request,
+ mojom::FetchEventPreloadHandlePtr preload_handle,
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
+ finish_callback) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&EmbeddedWorkerTestHelper::OnLegacyFetchEvent, AsWeakPtr(),
+ thread_id_embedded_worker_id_map_[thread_id], request,
+ std::move(preload_handle), std::move(response_callback),
+ std::move(finish_callback)));
}
void EmbeddedWorkerTestHelper::OnNotificationClickEventStub(
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 3982d5cb141..a54fddf486c 100644
--- a/chromium/content/browser/service_worker/embedded_worker_test_helper.h
+++ b/chromium/content/browser/service_worker/embedded_worker_test_helper.h
@@ -27,6 +27,7 @@
#include "ipc/ipc_test_sink.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "net/http/http_response_info.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker.mojom.h"
#include "url/gurl.h"
class GURL;
@@ -81,7 +82,9 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
void StartWorker(
const EmbeddedWorkerStartParams& params,
mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy)
@@ -189,9 +192,12 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info);
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info);
virtual void OnResumeAfterDownload(int embedded_worker_id);
// StopWorker IPC handler routed through MockEmbeddedWorkerInstanceClient.
// This calls SimulateWorkerStopped() by default.
@@ -227,12 +233,17 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
mojom::ServiceWorkerEventDispatcher::
DispatchExtendableMessageEventCallback callback);
virtual void OnInstallEvent(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client,
mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
callback);
virtual void OnFetchEvent(
int embedded_worker_id,
- int fetch_event_id,
+ const ResourceRequest& request,
+ mojom::FetchEventPreloadHandlePtr preload_handle,
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
+ finish_callback);
+ virtual void OnLegacyFetchEvent(
+ int embedded_worker_id,
const ServiceWorkerFetchRequest& request,
mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
@@ -268,10 +279,10 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
mojom::ServiceWorkerEventDispatcher::DispatchPaymentRequestEventCallback
callback);
- // These functions simulate sending an EmbeddedHostMsg message through the
- // legacy IPC system to the browser.
+ // These functions simulate making Mojo calls to the browser.
void SimulateWorkerReadyForInspection(int embedded_worker_id);
- void SimulateWorkerScriptCached(int embedded_worker_id);
+ void SimulateWorkerScriptCached(int embedded_worker_id,
+ base::OnceClosure callback);
void SimulateWorkerScriptLoaded(int embedded_worker_id);
void SimulateWorkerThreadStarted(int thread_id, int embedded_worker_id);
void SimulateWorkerScriptEvaluated(int embedded_worker_id, bool success);
@@ -285,11 +296,17 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
class MockServiceWorkerEventDispatcher;
class MockRendererInterface;
+ void DidSimulateWorkerScriptCached(int embedded_worker_id,
+ bool pause_after_download);
+
void OnStartWorkerStub(
const EmbeddedWorkerStartParams& params,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info);
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info);
void OnResumeAfterDownloadStub(int embedded_worker_id);
void OnStopWorkerStub(int embedded_worker_id);
void OnMessageToWorkerStub(int thread_id,
@@ -323,17 +340,22 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
mojom::ServiceWorkerEventDispatcher::
DispatchExtendableMessageEventCallback callback);
void OnInstallEventStub(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client,
mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
callback);
- void OnFetchEventStub(
+ void OnLegacyFetchEventStub(
int thread_id,
- int fetch_event_id,
const ServiceWorkerFetchRequest& request,
mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
finish_callback);
+ void OnFetchEventStub(
+ int thread_id,
+ const ResourceRequest& request,
+ mojom::FetchEventPreloadHandlePtr preload_handle,
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
+ finish_callback);
void OnNotificationClickEventStub(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
@@ -394,6 +416,9 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
embedded_worker_id_instance_host_ptr_map_;
std::map<int /* embedded_worker_id */, ServiceWorkerRemoteProviderEndpoint>
embedded_worker_id_remote_provider_map_;
+ std::map<int /* embedded_worker_id */,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr>
+ embedded_worker_id_installed_scripts_info_map_;
std::vector<Event> events_;
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter_;
@@ -407,7 +432,7 @@ template <typename MockType, typename... Args>
MockType* EmbeddedWorkerTestHelper::CreateAndRegisterMockInstanceClient(
Args&&... args) {
std::unique_ptr<MockType> mock =
- base::MakeUnique<MockType>(std::forward<Args>(args)...);
+ std::make_unique<MockType>(std::forward<Args>(args)...);
MockType* mock_rawptr = mock.get();
RegisterMockInstanceClient(std::move(mock));
return mock_rawptr;
diff --git a/chromium/content/browser/service_worker/foreign_fetch_request_handler.cc b/chromium/content/browser/service_worker/foreign_fetch_request_handler.cc
deleted file mode 100644
index da36f683986..00000000000
--- a/chromium/content/browser/service_worker/foreign_fetch_request_handler.cc
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/service_worker/foreign_fetch_request_handler.h"
-
-#include <string>
-#include <utility>
-
-#include "base/command_line.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/stl_util.h"
-#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_response_info.h"
-#include "content/browser/service_worker/service_worker_url_request_job.h"
-#include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/resource_request_info.h"
-#include "content/public/common/content_client.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/origin_trial_policy.h"
-#include "content/public/common/resource_request_body.h"
-#include "content/public/common/service_worker_modes.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_interceptor.h"
-#include "storage/browser/blob/blob_storage_context.h"
-
-namespace content {
-
-namespace {
-
-int kUserDataKey; // Only address is used.
-
-class ForeignFetchRequestInterceptor : public net::URLRequestInterceptor {
- public:
- explicit ForeignFetchRequestInterceptor(ResourceContext* resource_context)
- : resource_context_(resource_context) {}
- ~ForeignFetchRequestInterceptor() override {}
- net::URLRequestJob* MaybeInterceptRequest(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate) const override {
- ForeignFetchRequestHandler* handler =
- ForeignFetchRequestHandler::GetHandler(request);
- if (!handler)
- return nullptr;
- return handler->MaybeCreateJob(request, network_delegate,
- resource_context_);
- }
-
- private:
- ResourceContext* resource_context_;
- DISALLOW_COPY_AND_ASSIGN(ForeignFetchRequestInterceptor);
-};
-
-} // namespace
-
-bool ForeignFetchRequestHandler::IsForeignFetchEnabled() {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableExperimentalWebPlatformFeatures)) {
- return true;
- }
- OriginTrialPolicy* origin_trial_policy =
- GetContentClient()->GetOriginTrialPolicy();
- return origin_trial_policy &&
- !origin_trial_policy->IsFeatureDisabled("ForeignFetch");
-}
-
-void ForeignFetchRequestHandler::InitializeHandler(
- net::URLRequest* request,
- ServiceWorkerContextWrapper* context_wrapper,
- storage::BlobStorageContext* blob_storage_context,
- int process_id,
- int provider_id,
- ServiceWorkerMode service_worker_mode,
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
- FetchRedirectMode redirect_mode,
- const std::string& integrity,
- ResourceType resource_type,
- RequestContextType request_context_type,
- RequestContextFrameType frame_type,
- scoped_refptr<ResourceRequestBody> body,
- bool initiated_in_secure_context) {
- if (!IsForeignFetchEnabled())
- return;
-
- if (!context_wrapper || !context_wrapper->context() ||
- provider_id == kInvalidServiceWorkerProviderId) {
- return;
- }
-
- if (service_worker_mode == ServiceWorkerMode::NONE)
- return;
-
- if (!initiated_in_secure_context)
- return;
-
- // ServiceWorkerUtils::IsMainResource doesn't consider all worker types to
- // be main resources. This code shouldn't handle any main resource requests
- // though, so explicitly exclude the extra worker types.
- if (ServiceWorkerUtils::IsMainResourceType(resource_type) ||
- resource_type == RESOURCE_TYPE_WORKER ||
- resource_type == RESOURCE_TYPE_SERVICE_WORKER)
- return;
-
- if (request->initiator().has_value() &&
- request->initiator()->IsSameOriginWith(url::Origin(request->url()))) {
- return;
- }
-
- ServiceWorkerProviderHost* provider_host =
- context_wrapper->context()->GetProviderHost(process_id, provider_id);
- if (!provider_host || !provider_host->IsContextAlive())
- return;
-
- base::Optional<base::TimeDelta> timeout;
- if (provider_host->IsHostToRunningServiceWorker()) {
- timeout = base::make_optional(
- provider_host->running_hosted_version()->remaining_timeout());
- }
-
- if (!context_wrapper->OriginHasForeignFetchRegistrations(
- request->url().GetOrigin())) {
- return;
- }
-
- // Any more precise checks to see if the request should be intercepted are
- // asynchronous, so just create our handler in all cases.
- std::unique_ptr<ForeignFetchRequestHandler> handler =
- base::WrapUnique(new ForeignFetchRequestHandler(
- context_wrapper, blob_storage_context->AsWeakPtr(), request_mode,
- credentials_mode, redirect_mode, integrity, resource_type,
- request_context_type, frame_type, body, timeout));
- request->SetUserData(&kUserDataKey, std::move(handler));
-}
-
-ForeignFetchRequestHandler* ForeignFetchRequestHandler::GetHandler(
- net::URLRequest* request) {
- return static_cast<ForeignFetchRequestHandler*>(
- request->GetUserData(&kUserDataKey));
-}
-
-std::unique_ptr<net::URLRequestInterceptor>
-ForeignFetchRequestHandler::CreateInterceptor(
- ResourceContext* resource_context) {
- return std::unique_ptr<net::URLRequestInterceptor>(
- new ForeignFetchRequestInterceptor(resource_context));
-}
-
-ForeignFetchRequestHandler::~ForeignFetchRequestHandler() {}
-
-net::URLRequestJob* ForeignFetchRequestHandler::MaybeCreateJob(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- ResourceContext* resource_context) {
- ClearJob();
- ServiceWorkerResponseInfo::ResetDataForRequest(request);
-
- if (!context_) {
- // We can't do anything other than to fall back to network.
- job_.reset();
- return nullptr;
- }
-
- // This may get called multiple times for original and redirect requests:
- // A. original request case: use_network_ is false, no previous location info.
- // B. redirect or restarted request case:
- // a) use_network_ is false if the previous location was forwarded to SW.
- // b) use_network_ is false if the previous location was fallback.
- // c) use_network_ is true if additional restart was required to fall back.
-
- // Fall back to network. (Case B-c)
- if (use_network_) {
- // TODO(mek): Determine if redirects should be able to be intercepted by
- // other foreign fetch service workers.
- return nullptr;
- }
-
- // It's for original request (A) or redirect case (B-a or B-b).
- DCHECK(!job_.get() || job_->ShouldForwardToServiceWorker());
-
- ServiceWorkerURLRequestJob* job = new ServiceWorkerURLRequestJob(
- request, network_delegate, std::string(), blob_storage_context_,
- resource_context, request_mode_, credentials_mode_, redirect_mode_,
- integrity_, resource_type_, request_context_type_, frame_type_, body_,
- ServiceWorkerFetchType::FOREIGN_FETCH, timeout_, this);
- job_ = job->GetWeakPtr();
- resource_context_ = resource_context;
-
- context_->FindReadyRegistrationForDocument(
- request->url(),
- base::Bind(&ForeignFetchRequestHandler::DidFindRegistration,
- weak_factory_.GetWeakPtr(), job_));
-
- return job_.get();
-}
-
-ForeignFetchRequestHandler::ForeignFetchRequestHandler(
- ServiceWorkerContextWrapper* context,
- base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
- FetchRedirectMode redirect_mode,
- const std::string& integrity,
- ResourceType resource_type,
- RequestContextType request_context_type,
- RequestContextFrameType frame_type,
- scoped_refptr<ResourceRequestBody> body,
- const base::Optional<base::TimeDelta>& timeout)
- : context_(context),
- blob_storage_context_(blob_storage_context),
- resource_type_(resource_type),
- request_mode_(request_mode),
- credentials_mode_(credentials_mode),
- redirect_mode_(redirect_mode),
- integrity_(integrity),
- request_context_type_(request_context_type),
- frame_type_(frame_type),
- body_(body),
- timeout_(timeout),
- weak_factory_(this) {}
-
-void ForeignFetchRequestHandler::DidFindRegistration(
- const base::WeakPtr<ServiceWorkerURLRequestJob>& job,
- ServiceWorkerStatusCode status,
- scoped_refptr<ServiceWorkerRegistration> registration) {
- if (!job || job.get() != job_.get()) {
- // No more job to handle, or job changed somehow, so just return.
- return;
- }
-
- if (status != SERVICE_WORKER_OK || !job->request()) {
- job->FallbackToNetwork();
- return;
- }
-
- ServiceWorkerVersion* active_version = registration->active_version();
- DCHECK(active_version);
-
- const GURL& request_url = job->request()->url();
- bool scope_matches = false;
- for (const GURL& scope : active_version->foreign_fetch_scopes()) {
- if (ServiceWorkerUtils::ScopeMatches(scope, request_url)) {
- scope_matches = true;
- break;
- }
- }
-
- const url::Origin& request_origin = job->request()->initiator().value();
- bool origin_matches = active_version->foreign_fetch_origins().empty();
- for (const url::Origin& origin : active_version->foreign_fetch_origins()) {
- if (request_origin.IsSameOriginWith(origin))
- origin_matches = true;
- }
-
- if (!scope_matches || !origin_matches) {
- job->FallbackToNetwork();
- return;
- }
-
- if (!IsForeignFetchEnabled() && !CheckOriginTrialToken(active_version)) {
- job->FallbackToNetwork();
- return;
- }
-
- auto* request_info = ResourceRequestInfo::ForRequest(job->request());
- base::Callback<WebContents*(void)> web_contents_getter;
- if (request_info)
- web_contents_getter = request_info->GetWebContentsGetterForRequest();
-
- if (!GetContentClient()->browser()->AllowServiceWorker(
- registration->pattern(), job->request()->site_for_cookies(),
- resource_context_, web_contents_getter)) {
- job->FallbackToNetwork();
- return;
- }
-
- target_worker_ = active_version;
- job->ForwardToServiceWorker();
-}
-
-void ForeignFetchRequestHandler::OnPrepareToRestart() {
- use_network_ = true;
- ClearJob();
-}
-
-ServiceWorkerVersion* ForeignFetchRequestHandler::GetServiceWorkerVersion(
- ServiceWorkerMetrics::URLRequestJobResult* result) {
- // TODO(mek): Figure out what should happen if the active worker changes or
- // gets uninstalled before this point is reached.
- if (!target_worker_) {
- *result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_NO_ACTIVE_VERSION;
- return nullptr;
- }
- return target_worker_.get();
-}
-
-void ForeignFetchRequestHandler::ClearJob() {
- job_.reset();
- target_worker_ = nullptr;
- resource_context_ = nullptr;
-}
-
-// static
-bool ForeignFetchRequestHandler::CheckOriginTrialToken(
- const ServiceWorkerVersion* const active_version) {
- // The worker entry in the database was written by old version Chrome (< M56)
- // and the main script was not loaded yet. In this case, we can't check the
- // origin trial token.
- if (!active_version->origin_trial_tokens())
- return true;
- const auto& token_map = *active_version->origin_trial_tokens();
- return base::ContainsKey(token_map, "ForeignFetch");
-}
-
-} // namespace content
diff --git a/chromium/content/browser/service_worker/foreign_fetch_request_handler.h b/chromium/content/browser/service_worker/foreign_fetch_request_handler.h
deleted file mode 100644
index 11986ee5cd9..00000000000
--- a/chromium/content/browser/service_worker/foreign_fetch_request_handler.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_SERVICE_WORKER_FOREIGN_FETCH_REQUEST_HANDLER_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_FOREIGN_FETCH_REQUEST_HANDLER_H_
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
-#include "base/supports_user_data.h"
-#include "base/time/time.h"
-#include "content/browser/service_worker/service_worker_url_request_job.h"
-#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
-#include "content/public/common/request_context_frame_type.h"
-#include "content/public/common/request_context_type.h"
-#include "content/public/common/resource_type.h"
-#include "content/public/common/service_worker_modes.h"
-#include "net/url_request/url_request_job_factory.h"
-
-namespace net {
-class NetworkDelegate;
-class URLRequest;
-class URLRequestInterceptor;
-}
-
-namespace storage {
-class BlobStorageContext;
-}
-
-namespace content {
-
-class ResourceContext;
-class ResourceRequestBody;
-class ServiceWorkerContextWrapper;
-class ServiceWorkerRegistration;
-
-// Class for routing network requests to ServiceWorkers for foreign fetch
-// events. Created one per URLRequest and attached to each request.
-// TODO(mek): Does this need something similar to ServiceWorkerRequestHandler's
-// GetExtraResponseInfo method?
-class CONTENT_EXPORT ForeignFetchRequestHandler
- : public base::SupportsUserData::Data,
- public ServiceWorkerURLRequestJob::Delegate {
- public:
- // Returns true if Foreign Fetch is enabled. Foreign Fetch is considered to be
- // enabled if an OriginTrialPolicy exists, and that policy doesn't disable the
- // feature. When the policy does disable the feature, that can be overridden
- // with the experimental web platform features command line flag.
- static bool IsForeignFetchEnabled();
-
- // Attaches a newly created handler if the given |request| needs to
- // be handled by a foreign fetch handling ServiceWorker.
- static void InitializeHandler(
- net::URLRequest* request,
- ServiceWorkerContextWrapper* context_wrapper,
- storage::BlobStorageContext* blob_storage_context,
- int process_id,
- int provider_id,
- ServiceWorkerMode service_worker_mode,
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
- FetchRedirectMode redirect_mode,
- const std::string& integrity,
- ResourceType resource_type,
- RequestContextType request_context_type,
- RequestContextFrameType frame_type,
- scoped_refptr<ResourceRequestBody> body,
- bool initiated_in_secure_context);
-
- // Returns the handler attached to |request|. This may return null
- // if no handler is attached.
- static ForeignFetchRequestHandler* GetHandler(net::URLRequest* request);
-
- // Creates a protocol interceptor for foreign fetch.
- static std::unique_ptr<net::URLRequestInterceptor> CreateInterceptor(
- ResourceContext* resource_context);
-
- ~ForeignFetchRequestHandler() override;
-
- // Called via custom URLRequestJobFactory.
- net::URLRequestJob* MaybeCreateJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- ResourceContext* resource_context);
-
- private:
- friend class ForeignFetchRequestHandlerTest;
-
- ForeignFetchRequestHandler(
- ServiceWorkerContextWrapper* context,
- base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
- FetchRedirectMode redirect_mode,
- const std::string& integrity,
- ResourceType resource_type,
- RequestContextType request_context_type,
- RequestContextFrameType frame_type,
- scoped_refptr<ResourceRequestBody> body,
- const base::Optional<base::TimeDelta>& timeout);
-
- // Called when a ServiceWorkerRegistration has (or hasn't) been found for the
- // request being handled.
- void DidFindRegistration(
- const base::WeakPtr<ServiceWorkerURLRequestJob>& job,
- ServiceWorkerStatusCode status,
- scoped_refptr<ServiceWorkerRegistration> registration);
-
- // ServiceWorkerURLRequestJob::Delegate implementation:
- void OnPrepareToRestart() override;
- ServiceWorkerVersion* GetServiceWorkerVersion(
- ServiceWorkerMetrics::URLRequestJobResult* result) override;
-
- // Sets |job_| to nullptr, and clears all extra response info associated with
- // that job.
- void ClearJob();
-
- // Returns true if the version doesn't have origin_trial_tokens entry (this
- // happens if the existing worker's entry in the database was written by old
- // version (< M56) Chrome), or the version has valid Origin Trial token.
- static bool CheckOriginTrialToken(
- const ServiceWorkerVersion* const active_version);
-
- scoped_refptr<ServiceWorkerContextWrapper> context_;
- base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
- ResourceType resource_type_;
- FetchRequestMode request_mode_;
- FetchCredentialsMode credentials_mode_;
- FetchRedirectMode redirect_mode_;
- std::string integrity_;
- RequestContextType request_context_type_;
- RequestContextFrameType frame_type_;
- scoped_refptr<ResourceRequestBody> body_;
- ResourceContext* resource_context_;
- base::Optional<base::TimeDelta> timeout_;
-
- base::WeakPtr<ServiceWorkerURLRequestJob> job_;
- scoped_refptr<ServiceWorkerVersion> target_worker_;
-
- // True if the next time this request is started, the response should be
- // delivered from the network, bypassing the ServiceWorker.
- bool use_network_ = false;
-
- base::WeakPtrFactory<ForeignFetchRequestHandler> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ForeignFetchRequestHandler);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_SERVICE_WORKER_FOREIGN_FETCH_REQUEST_HANDLER_H_
diff --git a/chromium/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc b/chromium/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
deleted file mode 100644
index cad3616d908..00000000000
--- a/chromium/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
+++ /dev/null
@@ -1,406 +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/service_worker/foreign_fetch_request_handler.h"
-
-#include "base/bind_helpers.h"
-#include "base/memory/ptr_util.h"
-#include "base/run_loop.h"
-#include "base/test/simple_test_clock.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "content/browser/browser_thread_impl.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_registration.h"
-#include "content/browser/service_worker/service_worker_test_utils.h"
-#include "content/browser/service_worker/service_worker_version.h"
-#include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/common/content_client.h"
-#include "content/public/common/origin_trial_policy.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/test/test_content_browser_client.h"
-#include "net/http/http_response_info.h"
-#include "net/test/cert_test_util.h"
-#include "net/test/test_data_directory.h"
-#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_test_util.h"
-#include "storage/browser/blob/blob_storage_context.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-
-namespace content {
-
-namespace {
-
-// This is a sample public key for testing the API. The corresponding private
-// key (use this to generate new samples for this test file) is:
-//
-// 0x83, 0x67, 0xf4, 0xcd, 0x2a, 0x1f, 0x0e, 0x04, 0x0d, 0x43, 0x13,
-// 0x4c, 0x67, 0xc4, 0xf4, 0x28, 0xc9, 0x90, 0x15, 0x02, 0xe2, 0xba,
-// 0xfd, 0xbb, 0xfa, 0xbc, 0x92, 0x76, 0x8a, 0x2c, 0x4b, 0xc7, 0x75,
-// 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2, 0x9a,
-// 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f, 0x64,
-// 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0
-const uint8_t kTestPublicKey[] = {
- 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2,
- 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f,
- 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0,
-};
-
-int kMockProviderId = 1;
-
-const char* kValidUrl = "https://valid.example.com/foo/bar";
-
-// This timestamp is set to a time after the expiry timestamp of the expired
-// tokens in this test, but before the expiry timestamp of the valid ones.
-double kNowTimestamp = 1500000000;
-
-} // namespace
-
-class ForeignFetchRequestHandlerTest : public testing::Test {
- public:
- ForeignFetchRequestHandlerTest()
- : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {
- SetContentClient(&test_content_client_);
- SetBrowserClientForTesting(&test_content_browser_client_);
- }
- ~ForeignFetchRequestHandlerTest() override {}
-
- void SetUp() override {
- const GURL kScope("https://valid.example.com/scope/");
- const GURL kResource1("https://valid.example.com/scope/sw.js");
- const int64_t kRegistrationId = 0;
- const int64_t kVersionId = 0;
- helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
-
- // Create a registration for the worker which has foreign fetch event
- // handler.
- registration_ = new ServiceWorkerRegistration(
- blink::mojom::ServiceWorkerRegistrationOptions(kScope), kRegistrationId,
- context()->AsWeakPtr());
- version_ = new ServiceWorkerVersion(registration_.get(), kResource1,
- kVersionId, context()->AsWeakPtr());
- version_->set_foreign_fetch_scopes({kScope});
-
- // Fix the time for testing to kNowTimestamp
- std::unique_ptr<base::SimpleTestClock> clock =
- base::MakeUnique<base::SimpleTestClock>();
- clock->SetNow(base::Time::FromDoubleT(kNowTimestamp));
- version_->SetClockForTesting(std::move(clock));
-
- context()->storage()->LazyInitializeForTest(
- base::BindOnce(&base::DoNothing));
- base::RunLoop().RunUntilIdle();
-
- // Persist the registration data.
- std::vector<ServiceWorkerDatabase::ResourceRecord> records;
- records.push_back(
- ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100));
- version_->script_cache_map()->SetResources(records);
- version_->set_fetch_handler_existence(
- ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
- version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
- registration_->SetActiveVersion(version_);
- context()->storage()->StoreRegistration(
- registration_.get(), version_.get(),
- base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
- base::RunLoop().RunUntilIdle();
- }
-
- void TearDown() override {
- version_ = nullptr;
- registration_ = nullptr;
- helper_.reset();
- base::RunLoop().RunUntilIdle();
- }
-
- protected:
- ServiceWorkerContextCore* context() const { return helper_->context(); }
- ServiceWorkerContextWrapper* context_wrapper() const {
- return helper_->context_wrapper();
- }
- ServiceWorkerProviderHost* provider_host() const {
- return provider_host_.get();
- }
-
- bool CheckOriginTrialToken(const ServiceWorkerVersion* const version) const {
- return ForeignFetchRequestHandler::CheckOriginTrialToken(version);
- }
-
- base::Optional<base::TimeDelta> timeout_for_request(
- ForeignFetchRequestHandler* handler) {
- return handler->timeout_;
- }
-
- ServiceWorkerVersion* version() const { return version_.get(); }
-
- static std::unique_ptr<net::HttpResponseInfo> CreateTestHttpResponseInfo() {
- std::unique_ptr<net::HttpResponseInfo> http_info(
- base::MakeUnique<net::HttpResponseInfo>());
- http_info->ssl_info.cert =
- net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
- DCHECK(http_info->ssl_info.is_valid());
- http_info->ssl_info.security_bits = 0x100;
- // SSL3 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
- http_info->ssl_info.connection_status = 0x300039;
- http_info->headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
- return http_info;
- }
-
- ForeignFetchRequestHandler* InitializeHandler(const std::string& url,
- ResourceType resource_type,
- const char* initiator) {
- request_ = url_request_context_.CreateRequest(
- GURL(url), net::DEFAULT_PRIORITY, &url_request_delegate_,
- TRAFFIC_ANNOTATION_FOR_TESTS);
- if (initiator)
- request_->set_initiator(url::Origin(GURL(initiator)));
- ForeignFetchRequestHandler::InitializeHandler(
- request_.get(), context_wrapper(), &blob_storage_context_,
- helper_->mock_render_process_id(), provider_host()->provider_id(),
- ServiceWorkerMode::ALL, FETCH_REQUEST_MODE_CORS,
- FETCH_CREDENTIALS_MODE_OMIT, FetchRedirectMode::FOLLOW_MODE,
- std::string() /* integrity */, resource_type,
- REQUEST_CONTEXT_TYPE_FETCH, REQUEST_CONTEXT_FRAME_TYPE_NONE, nullptr,
- true /* initiated_in_secure_context */);
-
- return ForeignFetchRequestHandler::GetHandler(request_.get());
- }
-
- void CreateWindowTypeProviderHost() {
- remote_endpoints_.emplace_back();
- std::unique_ptr<ServiceWorkerProviderHost> host =
- CreateProviderHostForWindow(
- helper_->mock_render_process_id(), kMockProviderId,
- true /* is_parent_frame_secure */, helper_->context()->AsWeakPtr(),
- &remote_endpoints_.back());
- EXPECT_FALSE(
- context()->GetProviderHost(host->process_id(), host->provider_id()));
- host->SetDocumentUrl(GURL("https://host/scope/"));
- provider_host_ = host->AsWeakPtr();
- context()->AddProviderHost(std::move(host));
- }
-
- void CreateServiceWorkerTypeProviderHost() {
- // Create another worker whose requests will be intercepted by the foreign
- // fetch event handler.
- scoped_refptr<ServiceWorkerRegistration> registration =
- new ServiceWorkerRegistration(
- blink::mojom::ServiceWorkerRegistrationOptions(
- GURL("https://host/scope")),
- 1L, context()->AsWeakPtr());
- scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
- registration.get(), GURL("https://host/script.js"), 1L,
- context()->AsWeakPtr());
-
- std::vector<ServiceWorkerDatabase::ResourceRecord> records;
- records.push_back(
- ServiceWorkerDatabase::ResourceRecord(10, version->script_url(), 100));
- version->script_cache_map()->SetResources(records);
- version->set_fetch_handler_existence(
- ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
- version->SetStatus(ServiceWorkerVersion::ACTIVATED);
- registration->SetActiveVersion(version);
- context()->storage()->StoreRegistration(
- registration.get(), version.get(),
- base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
- base::RunLoop().RunUntilIdle();
-
- remote_endpoints_.emplace_back();
- std::unique_ptr<ServiceWorkerProviderHost> host =
- CreateProviderHostForServiceWorkerContext(
- helper_->mock_render_process_id(),
- true /* is_parent_frame_secure */, version.get(),
- helper_->context()->AsWeakPtr(), &remote_endpoints_.back());
- EXPECT_FALSE(
- context()->GetProviderHost(host->process_id(), host->provider_id()));
- provider_host_ = host->AsWeakPtr();
- context()->AddProviderHost(std::move(host));
- }
-
- private:
- class TestContentClient : public ContentClient {
- public:
- // ContentRendererClient methods
- OriginTrialPolicy* GetOriginTrialPolicy() override {
- return &origin_trial_policy_;
- }
-
- private:
- class TestOriginTrialPolicy : public OriginTrialPolicy {
- public:
- base::StringPiece GetPublicKey() const override {
- return base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey),
- arraysize(kTestPublicKey));
- }
- };
-
- TestOriginTrialPolicy origin_trial_policy_;
- };
-
- scoped_refptr<ServiceWorkerRegistration> registration_;
- scoped_refptr<ServiceWorkerVersion> version_;
- TestContentClient test_content_client_;
- TestContentBrowserClient test_content_browser_client_;
- std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
- TestBrowserThreadBundle browser_thread_bundle_;
-
- net::URLRequestContext url_request_context_;
- net::TestDelegate url_request_delegate_;
- base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
- storage::BlobStorageContext blob_storage_context_;
- std::unique_ptr<net::URLRequest> request_;
- std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_;
-
- DISALLOW_COPY_AND_ASSIGN(ForeignFetchRequestHandlerTest);
-};
-
-TEST_F(ForeignFetchRequestHandlerTest, CheckOriginTrialToken_NoToken) {
- CreateWindowTypeProviderHost();
- EXPECT_TRUE(CheckOriginTrialToken(version()));
- std::unique_ptr<net::HttpResponseInfo> http_info(
- CreateTestHttpResponseInfo());
- version()->SetMainScriptHttpResponseInfo(*http_info);
- EXPECT_FALSE(CheckOriginTrialToken(version()));
-}
-
-TEST_F(ForeignFetchRequestHandlerTest, CheckOriginTrialToken_ValidToken) {
- CreateWindowTypeProviderHost();
- EXPECT_TRUE(CheckOriginTrialToken(version()));
- std::unique_ptr<net::HttpResponseInfo> http_info(
- CreateTestHttpResponseInfo());
- const std::string kOriginTrial("Origin-Trial: ");
- // Token for ForeignFetch which expires 2033-05-18.
- // generate_token.py valid.example.com ForeignFetch
- // --expire-timestamp=2000000000
- // TODO(horo): Generate this sample token during the build.
- const std::string kFeatureToken(
- "AsDmvl17hoVfq9G6OT0VEhX28Nnl0VnbGZJoG6XFzosIamNfxNJ28m40PRA3PtFv3BfOlRe1"
- "5bLrEZhtICdDnwwAAABceyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5leGFtcGxlLmNvbTo0"
- "NDMiLCAiZmVhdHVyZSI6ICJGb3JlaWduRmV0Y2giLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0"
- "=");
- http_info->headers->AddHeader(kOriginTrial + kFeatureToken);
- version()->SetMainScriptHttpResponseInfo(*http_info);
- EXPECT_TRUE(CheckOriginTrialToken(version()));
-}
-
-TEST_F(ForeignFetchRequestHandlerTest, CheckOriginTrialToken_InvalidToken) {
- CreateWindowTypeProviderHost();
- EXPECT_TRUE(CheckOriginTrialToken(version()));
- std::unique_ptr<net::HttpResponseInfo> http_info(
- CreateTestHttpResponseInfo());
- const std::string kOriginTrial("Origin-Trial: ");
- // Token for FooBar which expires 2033-05-18.
- // generate_token.py valid.example.com FooBar
- // --expire-timestamp=2000000000
- // TODO(horo): Generate this sample token during the build.
- const std::string kFeatureToken(
- "AqwtRpuoLdc6MKSFH8TbzoLFvLouL8VXTv6OJIqQvRtJBynRMbAbFwjUlcwMuj4pXUBbquBj"
- "zj/w/d1H/ZsOcQIAAABWeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5leGFtcGxlLmNvbTo0"
- "NDMiLCAiZmVhdHVyZSI6ICJGb29CYXIiLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0=");
- http_info->headers->AddHeader(kOriginTrial + kFeatureToken);
- version()->SetMainScriptHttpResponseInfo(*http_info);
- EXPECT_FALSE(CheckOriginTrialToken(version()));
-}
-
-TEST_F(ForeignFetchRequestHandlerTest, CheckOriginTrialToken_ExpiredToken) {
- CreateWindowTypeProviderHost();
- EXPECT_TRUE(CheckOriginTrialToken(version()));
- std::unique_ptr<net::HttpResponseInfo> http_info(
- CreateTestHttpResponseInfo());
- const std::string kOriginTrial("Origin-Trial: ");
- // Token for ForeignFetch which expired 2001-09-09.
- // generate_token.py valid.example.com ForeignFetch
- // --expire-timestamp=1000000000
- const std::string kFeatureToken(
- "AgBgj4Zhwzn85LJw7rzh4ZFRFqp49+9Es2SrCwZdDcoqtqQEjbvui4SKLn6GqMpr4DynGfJh"
- "tIy9dpOuK8PVTwkAAABceyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5leGFtcGxlLmNvbTo0"
- "NDMiLCAiZmVhdHVyZSI6ICJGb3JlaWduRmV0Y2giLCAiZXhwaXJ5IjogMTAwMDAwMDAwMH0"
- "=");
- http_info->headers->AddHeader(kOriginTrial + kFeatureToken);
- version()->SetMainScriptHttpResponseInfo(*http_info);
- EXPECT_FALSE(CheckOriginTrialToken(version()));
-}
-
-TEST_F(ForeignFetchRequestHandlerTest, InitializeHandler_Success) {
- CreateWindowTypeProviderHost();
- EXPECT_TRUE(InitializeHandler(kValidUrl, RESOURCE_TYPE_IMAGE,
- nullptr /* initiator */));
-}
-
-TEST_F(ForeignFetchRequestHandlerTest, InitializeHandler_WrongResourceType) {
- CreateWindowTypeProviderHost();
- EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_MAIN_FRAME,
- nullptr /* initiator */));
- EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_SUB_FRAME,
- nullptr /* initiator */));
- EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_WORKER,
- nullptr /* initiator */));
- EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_SHARED_WORKER,
- nullptr /* initiator */));
- EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_SERVICE_WORKER,
- nullptr /* initiator */));
-}
-
-TEST_F(ForeignFetchRequestHandlerTest, InitializeHandler_SameOriginRequest) {
- CreateWindowTypeProviderHost();
- EXPECT_FALSE(InitializeHandler(kValidUrl, RESOURCE_TYPE_IMAGE,
- kValidUrl /* initiator */));
-}
-
-TEST_F(ForeignFetchRequestHandlerTest, InitializeHandler_NoRegisteredHandlers) {
- CreateWindowTypeProviderHost();
- EXPECT_FALSE(InitializeHandler("https://invalid.example.com/foo",
- RESOURCE_TYPE_IMAGE, nullptr /* initiator */));
-}
-
-TEST_F(ForeignFetchRequestHandlerTest,
- InitializeHandler_TimeoutBehaviorForWindow) {
- CreateWindowTypeProviderHost();
- ForeignFetchRequestHandler* handler =
- InitializeHandler("https://valid.example.com/foo", RESOURCE_TYPE_IMAGE,
- nullptr /* initiator */);
- ASSERT_TRUE(handler);
-
- EXPECT_EQ(base::nullopt, timeout_for_request(handler));
-}
-
-TEST_F(ForeignFetchRequestHandlerTest,
- InitializeHandler_TimeoutBehaviorForServiceWorker) {
- CreateServiceWorkerTypeProviderHost();
- ServiceWorkerVersion* version = provider_host()->running_hosted_version();
- std::unique_ptr<net::HttpResponseInfo> http_info(
- CreateTestHttpResponseInfo());
- version->SetMainScriptHttpResponseInfo(*http_info);
-
- // Set mock clock on version to check timeout behavior.
- base::SimpleTestTickClock* tick_clock = new base::SimpleTestTickClock();
- tick_clock->SetNowTicks(base::TimeTicks::Now());
- version->SetTickClockForTesting(base::WrapUnique(tick_clock));
-
- // Make sure worker has a non-zero timeout.
- version->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
- base::RunLoop().RunUntilIdle();
- version->StartRequestWithCustomTimeout(
- ServiceWorkerMetrics::EventType::ACTIVATE,
- base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback),
- base::TimeDelta::FromSeconds(10), ServiceWorkerVersion::KILL_ON_TIMEOUT);
-
- // Advance clock by a couple seconds.
- tick_clock->Advance(base::TimeDelta::FromSeconds(4));
- base::TimeDelta remaining_time = version->remaining_timeout();
- EXPECT_EQ(base::TimeDelta::FromSeconds(6), remaining_time);
-
- // Make sure new request only gets remaining timeout.
- ForeignFetchRequestHandler* handler =
- InitializeHandler("https://valid.example.com/foo", RESOURCE_TYPE_IMAGE,
- nullptr /* initiator */);
- ASSERT_TRUE(handler);
- ASSERT_TRUE(timeout_for_request(handler).has_value());
- EXPECT_EQ(remaining_time, timeout_for_request(handler).value());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/service_worker/link_header_support.cc b/chromium/content/browser/service_worker/link_header_support.cc
deleted file mode 100644
index aebedfbc042..00000000000
--- a/chromium/content/browser/service_worker/link_header_support.cc
+++ /dev/null
@@ -1,178 +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/service_worker/link_header_support.h"
-
-#include "base/command_line.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/time/time.h"
-#include "components/link_header_util/link_header_util.h"
-#include "content/browser/loader/resource_message_filter.h"
-#include "content/browser/loader/resource_request_info_impl.h"
-#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_request_handler.h"
-#include "content/common/origin_trials/trial_policy_impl.h"
-#include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/common/browser_side_navigation_policy.h"
-#include "content/public/common/content_client.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/origin_util.h"
-#include "net/http/http_util.h"
-#include "net/url_request/url_request.h"
-#include "third_party/WebKit/common/origin_trials/trial_token_validator.h"
-
-namespace content {
-
-namespace {
-
-void RegisterServiceWorkerFinished(int64_t trace_id, bool result) {
- TRACE_EVENT_ASYNC_END1("ServiceWorker",
- "LinkHeaderResourceThrottle::HandleServiceWorkerLink",
- trace_id, "Success", result);
-}
-
-void HandleServiceWorkerLink(
- net::URLRequest* request,
- const std::string& url,
- const std::unordered_map<std::string, base::Optional<std::string>>& params,
- const blink::TrialTokenValidator& validator,
- ServiceWorkerContextWrapper* service_worker_context_for_testing) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableExperimentalWebPlatformFeatures) &&
- !validator.RequestEnablesFeature(request, "ForeignFetch",
- base::Time::Now())) {
- // TODO(mek): Log attempt to use without having correct token?
- return;
- }
-
- if (ContainsKey(params, "anchor"))
- return;
-
- ResourceRequestInfoImpl* request_info =
- ResourceRequestInfoImpl::ForRequest(request);
- ServiceWorkerContext* service_worker_context =
- service_worker_context_for_testing
- ? service_worker_context_for_testing
- : request_info->requester_info()->service_worker_context();
-
- if (!service_worker_context)
- return;
-
- ServiceWorkerProviderHost* provider_host =
- ServiceWorkerRequestHandler::GetProviderHost(request);
-
- // If fetched from a service worker, make sure fetching service worker is
- // controlling at least one client to prevent a service worker from spawning
- // new service workers in the background.
- if (provider_host && provider_host->IsHostToRunningServiceWorker()) {
- if (!provider_host->running_hosted_version()->HasControllee())
- return;
- }
-
- if (ServiceWorkerUtils::IsMainResourceType(request_info->GetResourceType())) {
- // In case of navigations, make sure the navigation will actually result in
- // a secure context.
- if (!provider_host || !provider_host->IsContextSecureForServiceWorker())
- return;
- } else {
- // If this is not a navigation, make sure the request was initiated from a
- // secure context.
- if (!request_info->initiated_in_secure_context())
- return;
- }
-
- // TODO(mek): support for a serviceworker link on a request that wouldn't ever
- // be able to be intercepted by a serviceworker isn't very useful, so this
- // should share logic with ServiceWorkerRequestHandler and
- // ForeignFetchRequestHandler to limit the requests for which serviceworker
- // links are processed.
-
- GURL context_url = request->url();
- GURL script_url = context_url.Resolve(url);
- auto scope_param = params.find("scope");
- GURL scope_url = scope_param == params.end()
- ? script_url.Resolve("./")
- : context_url.Resolve(scope_param->second.value_or(""));
-
- if (!context_url.is_valid() || !script_url.is_valid() ||
- !scope_url.is_valid())
- return;
- if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(
- {context_url, scope_url, script_url})) {
- return;
- }
- std::string error;
- if (ServiceWorkerUtils::ContainsDisallowedCharacter(scope_url, script_url,
- &error))
- return;
-
- if (!GetContentClient()->browser()->AllowServiceWorker(
- scope_url, request->site_for_cookies(), request_info->GetContext(),
- request_info->GetWebContentsGetterForRequest()))
- return;
-
- static int64_t trace_id = 0;
- TRACE_EVENT_ASYNC_BEGIN2(
- "ServiceWorker", "LinkHeaderResourceThrottle::HandleServiceWorkerLink",
- ++trace_id, "Pattern", scope_url.spec(), "Script URL", script_url.spec());
- service_worker_context->RegisterServiceWorker(
- scope_url, script_url,
- base::Bind(&RegisterServiceWorkerFinished, trace_id));
-}
-
-void ProcessLinkHeaderValueForRequest(
- net::URLRequest* request,
- std::string::const_iterator value_begin,
- std::string::const_iterator value_end,
- ServiceWorkerContextWrapper* service_worker_context_for_testing) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- std::string url;
- std::unordered_map<std::string, base::Optional<std::string>> params;
- if (!link_header_util::ParseLinkHeaderValue(value_begin, value_end, &url,
- &params))
- return;
-
- auto rel_param = params.find("rel");
- if (rel_param == params.end() || !rel_param->second)
- return;
-
- const auto validator = base::MakeUnique<blink::TrialTokenValidator>(
- base::MakeUnique<TrialPolicyImpl>());
- for (const auto& rel : base::SplitStringPiece(rel_param->second.value(),
- HTTP_LWS, base::TRIM_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY)) {
- if (base::EqualsCaseInsensitiveASCII(rel, "serviceworker"))
- HandleServiceWorkerLink(request, url, params, *validator,
- service_worker_context_for_testing);
- }
-}
-
-} // namespace
-
-void ProcessRequestForLinkHeaders(net::URLRequest* request) {
- std::string link_header;
- request->GetResponseHeaderByName("link", &link_header);
- if (link_header.empty())
- return;
-
- ProcessLinkHeaderForRequest(request, link_header);
-}
-
-void ProcessLinkHeaderForRequest(
- net::URLRequest* request,
- const std::string& link_header,
- ServiceWorkerContextWrapper* service_worker_context_for_testing) {
- for (const auto& value : link_header_util::SplitLinkHeader(link_header)) {
- ProcessLinkHeaderValueForRequest(request, value.first, value.second,
- service_worker_context_for_testing);
- }
-}
-
-} // namespace content
diff --git a/chromium/content/browser/service_worker/link_header_support.h b/chromium/content/browser/service_worker/link_header_support.h
deleted file mode 100644
index b57dfbfb273..00000000000
--- a/chromium/content/browser/service_worker/link_header_support.h
+++ /dev/null
@@ -1,38 +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_SERVICE_WORKER_LINK_HEADER_SUPPORT_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_LINK_HEADER_SUPPORT_H_
-
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-
-namespace net {
-class URLRequest;
-}
-
-namespace content {
-class ServiceWorkerContextWrapper;
-
-void ProcessRequestForLinkHeaders(net::URLRequest* request);
-
-CONTENT_EXPORT void ProcessLinkHeaderForRequest(
- net::URLRequest* request,
- const std::string& link_header,
- ServiceWorkerContextWrapper* service_worker_context_for_testing = nullptr);
-
-CONTENT_EXPORT void SplitLinkHeaderForTesting(const std::string& header,
- std::vector<std::string>* values);
-CONTENT_EXPORT bool ParseLinkHeaderValueForTesting(
- const std::string& link,
- std::string* url,
- std::unordered_map<std::string, std::string>* params);
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_SERVICE_WORKER_LINK_HEADER_SUPPORT_H_
diff --git a/chromium/content/browser/service_worker/link_header_support_unittest.cc b/chromium/content/browser/service_worker/link_header_support_unittest.cc
deleted file mode 100644
index 76ab69daaf4..00000000000
--- a/chromium/content/browser/service_worker/link_header_support_unittest.cc
+++ /dev/null
@@ -1,451 +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/service_worker/link_header_support.h"
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/run_loop.h"
-#include "content/browser/loader/resource_request_info_impl.h"
-#include "content/browser/service_worker/embedded_worker_test_helper.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_request_handler.h"
-#include "content/browser/service_worker/service_worker_test_utils.h"
-#include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/previews_state.h"
-#include "content/public/test/mock_resource_context.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "net/http/http_response_headers.h"
-#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
-#include "net/url_request/url_request_test_job.h"
-#include "net/url_request/url_request_test_util.h"
-#include "storage/browser/blob/blob_storage_context.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-
-namespace content {
-
-namespace {
-
-const int kMockProviderId = 1;
-
-void SaveFoundRegistrationsCallback(
- ServiceWorkerStatusCode expected_status,
- bool* called,
- std::vector<ServiceWorkerRegistrationInfo>* registrations,
- ServiceWorkerStatusCode status,
- const std::vector<ServiceWorkerRegistrationInfo>& result) {
- EXPECT_EQ(expected_status, status);
- *called = true;
- *registrations = result;
-}
-
-ServiceWorkerContextWrapper::GetRegistrationsInfosCallback
-SaveFoundRegistrations(
- ServiceWorkerStatusCode expected_status,
- bool* called,
- std::vector<ServiceWorkerRegistrationInfo>* registrations) {
- *called = false;
- return base::Bind(&SaveFoundRegistrationsCallback, expected_status, called,
- registrations);
-}
-
-} // namespace
-
-class LinkHeaderServiceWorkerTest : public ::testing::Test {
- public:
- LinkHeaderServiceWorkerTest()
- : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- resource_context_(&request_context_) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableExperimentalWebPlatformFeatures);
- }
- ~LinkHeaderServiceWorkerTest() override {}
-
- void SetUp() override {
- helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
- }
-
- void TearDown() override { helper_.reset(); }
-
- ServiceWorkerContextCore* context() { return helper_->context(); }
- ServiceWorkerContextWrapper* context_wrapper() {
- return helper_->context_wrapper();
- }
- ServiceWorkerProviderHost* provider_host() { return provider_host_.get(); }
- int render_process_id() const { return helper_->mock_render_process_id(); }
-
- void CreateDocumentProviderHost() {
- // An empty host.
- remote_endpoints_.emplace_back();
- std::unique_ptr<ServiceWorkerProviderHost> host =
- CreateProviderHostForWindow(render_process_id(), kMockProviderId,
- true /* is_parent_frame_secure */,
- context()->AsWeakPtr(),
- &remote_endpoints_.back());
- provider_host_ = host->AsWeakPtr();
- EXPECT_FALSE(
- context()->GetProviderHost(host->process_id(), host->provider_id()));
- context()->AddProviderHost(std::move(host));
- }
-
- void CreateInsecureDocumentProviderHost() {
- // An empty host.
- remote_endpoints_.emplace_back();
- std::unique_ptr<ServiceWorkerProviderHost> host =
- CreateProviderHostForWindow(render_process_id(), kMockProviderId,
- false /* is_parent_frame_secure */,
- context()->AsWeakPtr(),
- &remote_endpoints_.back());
- provider_host_ = host->AsWeakPtr();
- EXPECT_FALSE(
- context()->GetProviderHost(host->process_id(), host->provider_id()));
- context()->AddProviderHost(std::move(host));
- }
-
- void CreateServiceWorkerProviderHost() {
- scoped_refptr<ServiceWorkerRegistration> registration =
- new ServiceWorkerRegistration(
- blink::mojom::ServiceWorkerRegistrationOptions(
- GURL("https://host/scope")),
- 1L, context()->AsWeakPtr());
- scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
- registration.get(), GURL("https://host/script.js"), 1L,
- context()->AsWeakPtr());
-
- remote_endpoints_.emplace_back();
- std::unique_ptr<ServiceWorkerProviderHost> host =
- CreateProviderHostForServiceWorkerContext(
- render_process_id(), true /* is_parent_frame_secure */,
- version.get(), context()->AsWeakPtr(), &remote_endpoints_.back());
- provider_host_ = host->AsWeakPtr();
- EXPECT_FALSE(
- context()->GetProviderHost(host->process_id(), host->provider_id()));
- context()->AddProviderHost(std::move(host));
- }
-
- std::unique_ptr<net::URLRequest> CreateRequest(const GURL& request_url,
- ResourceType resource_type,
- int provider_id) {
- std::unique_ptr<net::URLRequest> request = request_context_.CreateRequest(
- request_url, net::DEFAULT_PRIORITY, &request_delegate_,
- TRAFFIC_ANNOTATION_FOR_TESTS);
- ResourceRequestInfo::AllocateForTesting(
- request.get(), resource_type, &resource_context_,
- -1 /* render_process_id */, -1 /* render_view_id */,
- -1 /* render_frame_id */, resource_type == RESOURCE_TYPE_MAIN_FRAME,
- true /* allow_download */, true /* is_async */,
- PREVIEWS_OFF /* previews_state */);
- ResourceRequestInfoImpl::ForRequest(request.get())
- ->set_initiated_in_secure_context_for_testing(true);
-
- ServiceWorkerRequestHandler::InitializeHandler(
- request.get(), context_wrapper(), &blob_storage_context_,
- render_process_id(), provider_id, false /* skip_service_worker */,
- FETCH_REQUEST_MODE_NO_CORS, FETCH_CREDENTIALS_MODE_OMIT,
- FetchRedirectMode::FOLLOW_MODE, std::string() /* integrity */,
- resource_type, REQUEST_CONTEXT_TYPE_HYPERLINK,
- REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL, nullptr);
-
- return request;
- }
-
- std::unique_ptr<net::URLRequest> CreateSubresourceRequest(
- const GURL& request_url,
- int provider_id) {
- return CreateRequest(request_url, RESOURCE_TYPE_SCRIPT, provider_id);
- }
-
- std::vector<ServiceWorkerRegistrationInfo> GetRegistrations() {
- bool called;
- std::vector<ServiceWorkerRegistrationInfo> registrations;
- context_wrapper()->GetAllRegistrations(
- SaveFoundRegistrations(SERVICE_WORKER_OK, &called, &registrations));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(called);
- return registrations;
- }
-
- protected:
- TestBrowserThreadBundle thread_bundle_;
- std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
- net::TestURLRequestContext request_context_;
- net::TestDelegate request_delegate_;
- MockResourceContext resource_context_;
- base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
- storage::BlobStorageContext blob_storage_context_;
- std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_;
-};
-
-TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_Basic) {
- CreateDocumentProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foo/bar/"),
- provider_host()->provider_id())
- .get(),
- "<../foo.js>; rel=serviceworker", context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(1u, registrations.size());
- EXPECT_EQ(GURL("https://example.com/foo/"), registrations[0].pattern);
- EXPECT_EQ(GURL("https://example.com/foo/foo.js"),
- registrations[0].active_version.script_url);
-}
-
-TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_ScopeWithFragment) {
- CreateDocumentProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foo/bar/"),
- provider_host()->provider_id())
- .get(),
- "<../bar.js>; rel=serviceworker; scope=\"scope#ref\"", context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(1u, registrations.size());
- EXPECT_EQ(GURL("https://example.com/foo/bar/scope"),
- registrations[0].pattern);
- EXPECT_EQ(GURL("https://example.com/foo/bar.js"),
- registrations[0].active_version.script_url);
-}
-
-TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_ScopeAbsoluteUrl) {
- CreateDocumentProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foo/bar/"),
- provider_host()->provider_id())
- .get(),
- "<bar.js>; rel=serviceworker; "
- "scope=\"https://example.com:443/foo/bar/scope\"",
- context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(1u, registrations.size());
- EXPECT_EQ(GURL("https://example.com/foo/bar/scope"),
- registrations[0].pattern);
- EXPECT_EQ(GURL("https://example.com/foo/bar/bar.js"),
- registrations[0].active_version.script_url);
-}
-
-TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_ScopeDifferentOrigin) {
- CreateDocumentProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foobar/"),
- provider_host()->provider_id())
- .get(),
- "<bar.js>; rel=serviceworker; scope=\"https://google.com/scope\"",
- context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(0u, registrations.size());
-}
-
-TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_ScopeUrlEncodedSlash) {
- CreateDocumentProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foobar/"),
- provider_host()->provider_id())
- .get(),
- "<bar.js>; rel=serviceworker; scope=\"./foo%2Fbar\"", context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(0u, registrations.size());
-}
-
-TEST_F(LinkHeaderServiceWorkerTest,
- InstallServiceWorker_ScriptUrlEncodedSlash) {
- CreateDocumentProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foobar/"),
- provider_host()->provider_id())
- .get(),
- "<foo%2Fbar.js>; rel=serviceworker", context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(0u, registrations.size());
-}
-
-TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_ScriptAbsoluteUrl) {
- CreateDocumentProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foobar/"),
- provider_host()->provider_id())
- .get(),
- "<https://example.com/bar.js>; rel=serviceworker; scope=foo",
- context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(1u, registrations.size());
- EXPECT_EQ(GURL("https://example.com/foobar/foo"), registrations[0].pattern);
- EXPECT_EQ(GURL("https://example.com/bar.js"),
- registrations[0].active_version.script_url);
-}
-
-TEST_F(LinkHeaderServiceWorkerTest,
- InstallServiceWorker_ScriptDifferentOrigin) {
- CreateDocumentProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foobar/"),
- provider_host()->provider_id())
- .get(),
- "<https://google.com/bar.js>; rel=serviceworker; scope=foo",
- context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(0u, registrations.size());
-}
-
-TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_MultipleWorkers) {
- CreateDocumentProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foobar/"),
- provider_host()->provider_id())
- .get(),
- "<bar.js>; rel=serviceworker; scope=foo, <baz.js>; "
- "rel=serviceworker; scope=scope",
- context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(2u, registrations.size());
- EXPECT_EQ(GURL("https://example.com/foobar/foo"), registrations[0].pattern);
- EXPECT_EQ(GURL("https://example.com/foobar/bar.js"),
- registrations[0].active_version.script_url);
- EXPECT_EQ(GURL("https://example.com/foobar/scope"), registrations[1].pattern);
- EXPECT_EQ(GURL("https://example.com/foobar/baz.js"),
- registrations[1].active_version.script_url);
-}
-
-TEST_F(LinkHeaderServiceWorkerTest,
- InstallServiceWorker_ValidAndInvalidValues) {
- CreateDocumentProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foobar/"),
- provider_host()->provider_id())
- .get(),
- "<https://google.com/bar.js>; rel=serviceworker; scope=foo, <baz.js>; "
- "rel=serviceworker; scope=scope",
- context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(1u, registrations.size());
- EXPECT_EQ(GURL("https://example.com/foobar/scope"), registrations[0].pattern);
- EXPECT_EQ(GURL("https://example.com/foobar/baz.js"),
- registrations[0].active_version.script_url);
-}
-
-TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_InsecureContext) {
- CreateDocumentProviderHost();
- std::unique_ptr<net::URLRequest> request = CreateSubresourceRequest(
- GURL("https://example.com/foo/bar/"), provider_host()->provider_id());
- ResourceRequestInfoImpl::ForRequest(request.get())
- ->set_initiated_in_secure_context_for_testing(false);
- ProcessLinkHeaderForRequest(request.get(), "<../foo.js>; rel=serviceworker",
- context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(0u, registrations.size());
-}
-
-TEST_F(LinkHeaderServiceWorkerTest,
- InstallServiceWorker_NavigationFromInsecureContextToSecureContext) {
- CreateDocumentProviderHost();
- std::unique_ptr<net::URLRequest> request =
- CreateRequest(GURL("https://example.com/foo/bar/"),
- RESOURCE_TYPE_MAIN_FRAME, provider_host()->provider_id());
- ResourceRequestInfoImpl::ForRequest(request.get())
- ->set_initiated_in_secure_context_for_testing(false);
-
- provider_host()->SetDocumentUrl(GURL("https://example.com/foo/bar/"));
-
- ProcessLinkHeaderForRequest(request.get(), "<../foo.js>; rel=serviceworker",
- context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(1u, registrations.size());
- EXPECT_EQ(GURL("https://example.com/foo/"), registrations[0].pattern);
- EXPECT_EQ(GURL("https://example.com/foo/foo.js"),
- registrations[0].active_version.script_url);
-}
-
-TEST_F(LinkHeaderServiceWorkerTest,
- InstallServiceWorker_NavigationToInsecureContext) {
- CreateDocumentProviderHost();
- provider_host()->SetDocumentUrl(GURL("http://example.com/foo/bar/"));
- ProcessLinkHeaderForRequest(
- CreateRequest(GURL("http://example.com/foo/bar/"),
- RESOURCE_TYPE_MAIN_FRAME, provider_host()->provider_id())
- .get(),
- "<../foo.js>; rel=serviceworker", context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(0u, registrations.size());
-}
-
-TEST_F(LinkHeaderServiceWorkerTest,
- InstallServiceWorker_NavigationToInsecureHttpsContext) {
- CreateInsecureDocumentProviderHost();
- provider_host()->SetDocumentUrl(GURL("https://example.com/foo/bar/"));
- ProcessLinkHeaderForRequest(
- CreateRequest(GURL("https://example.com/foo/bar/"),
- RESOURCE_TYPE_MAIN_FRAME, provider_host()->provider_id())
- .get(),
- "<../foo.js>; rel=serviceworker", context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(0u, registrations.size());
-}
-
-TEST_F(LinkHeaderServiceWorkerTest,
- InstallServiceWorker_FromWorkerWithoutControllees) {
- CreateServiceWorkerProviderHost();
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foo/bar/"),
- provider_host()->provider_id())
- .get(),
- "<../foo.js>; rel=serviceworker", context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(0u, registrations.size());
-}
-
-TEST_F(LinkHeaderServiceWorkerTest,
- InstallServiceWorker_FromWorkerWithControllees) {
- CreateServiceWorkerProviderHost();
-
- remote_endpoints_.emplace_back();
- std::unique_ptr<ServiceWorkerProviderHost> controllee =
- CreateProviderHostForWindow(render_process_id(), kMockProviderId,
- true /* is_parent_frame_secure */,
- context()->AsWeakPtr(),
- &remote_endpoints_.back());
- provider_host()->running_hosted_version()->AddControllee(controllee.get());
-
- ProcessLinkHeaderForRequest(
- CreateSubresourceRequest(GURL("https://example.com/foo/bar/"),
- provider_host()->provider_id())
- .get(),
- "<../foo.js>; rel=serviceworker", context_wrapper());
- base::RunLoop().RunUntilIdle();
-
- std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
- ASSERT_EQ(1u, registrations.size());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_blob_reader.cc b/chromium/content/browser/service_worker/service_worker_blob_reader.cc
index 527b2b29786..842cb46e035 100644
--- a/chromium/content/browser/service_worker/service_worker_blob_reader.cc
+++ b/chromium/content/browser/service_worker/service_worker_blob_reader.cc
@@ -51,8 +51,9 @@ void ServiceWorkerBlobReader::OnSSLCertificateError(
NOTREACHED();
}
-void ServiceWorkerBlobReader::OnResponseStarted(net::URLRequest* request) {
- // TODO(falken): This should check request->status() per URLRequest::Delegate
+void ServiceWorkerBlobReader::OnResponseStarted(net::URLRequest* request,
+ int net_error) {
+ // TODO(falken): This should check net_error per URLRequest::Delegate
// contract.
// TODO(falken): Add Content-Length, Content-Type if they were not provided in
// the ServiceWorkerResponse.
diff --git a/chromium/content/browser/service_worker/service_worker_blob_reader.h b/chromium/content/browser/service_worker/service_worker_blob_reader.h
index 3a2e21d9ab3..4021657a3ce 100644
--- a/chromium/content/browser/service_worker/service_worker_blob_reader.h
+++ b/chromium/content/browser/service_worker/service_worker_blob_reader.h
@@ -45,7 +45,7 @@ class ServiceWorkerBlobReader : public net::URLRequest::Delegate {
void OnSSLCertificateError(net::URLRequest* request,
const net::SSLInfo& ssl_info,
bool fatal) override;
- void OnResponseStarted(net::URLRequest* request) override;
+ void OnResponseStarted(net::URLRequest* request, int net_error) override;
void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
private:
diff --git a/chromium/content/browser/service_worker/service_worker_browsertest.cc b/chromium/content/browser/service_worker/service_worker_browsertest.cc
index 81182e8871b..7a4f1be88f6 100644
--- a/chromium/content/browser/service_worker/service_worker_browsertest.cc
+++ b/chromium/content/browser/service_worker/service_worker_browsertest.cc
@@ -48,6 +48,7 @@
#include "content/common/service_worker/service_worker_messages.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
@@ -86,15 +87,21 @@
#include "storage/browser/blob/blob_reader.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+using blink::mojom::CacheStorageError;
+
namespace content {
namespace {
+// V8ScriptRunner::setCacheTimeStamp() stores 12 byte data (tag + timestamp).
+const int kV8CacheTimeStampDataSize = sizeof(unsigned) + sizeof(double);
+
struct FetchResult {
ServiceWorkerStatusCode status;
- ServiceWorkerFetchEventResult result;
+ ServiceWorkerFetchDispatcher::FetchEventResult result;
ServiceWorkerResponse response;
std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
};
@@ -138,8 +145,8 @@ void ReceivePrepareResult(bool* is_prepared) {
*is_prepared = true;
}
-base::Closure CreatePrepareReceiver(bool* is_prepared) {
- return base::Bind(&ReceivePrepareResult, is_prepared);
+base::OnceClosure CreatePrepareReceiver(bool* is_prepared) {
+ return base::BindOnce(&ReceivePrepareResult, is_prepared);
}
void ReceiveFindRegistrationStatus(
@@ -241,7 +248,7 @@ std::unique_ptr<net::test_server::HttpResponse>
VerifySaveDataHeaderNotInRequest(const net::test_server::HttpRequest& request) {
auto it = request.headers.find("Save-Data");
EXPECT_EQ(request.headers.end(), it);
- return base::MakeUnique<net::test_server::BasicHttpResponse>();
+ return std::make_unique<net::test_server::BasicHttpResponse>();
}
std::unique_ptr<net::test_server::HttpResponse>
@@ -332,13 +339,13 @@ void CountScriptResources(
int version_id;
size_t index = infos.size() - 1;
if (infos[index].installing_version.version_id !=
- kInvalidServiceWorkerVersionId)
+ blink::mojom::kInvalidServiceWorkerVersionId)
version_id = infos[index].installing_version.version_id;
else if (infos[index].waiting_version.version_id !=
- kInvalidServiceWorkerVersionId)
+ blink::mojom::kInvalidServiceWorkerVersionId)
version_id = infos[1].waiting_version.version_id;
else if (infos[index].active_version.version_id !=
- kInvalidServiceWorkerVersionId)
+ blink::mojom::kInvalidServiceWorkerVersionId)
version_id = infos[index].active_version.version_id;
else
return;
@@ -446,7 +453,7 @@ class ServiceWorkerBrowserTest : public ContentBrowserTest {
void TearDownOnMainThread() override {
RunOnIOThread(
base::Bind(&self::TearDownOnIOThread, base::Unretained(this)));
- wrapper_ = NULL;
+ wrapper_ = nullptr;
}
// Starts the test server and navigates the renderer to an empty page. Call
@@ -576,8 +583,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
~ServiceWorkerVersionBrowserTest() override {}
void TearDownOnIOThread() override {
- registration_ = NULL;
- version_ = NULL;
+ registration_ = nullptr;
+ version_ = nullptr;
remote_endpoints_.clear();
}
@@ -619,7 +626,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
}
void FetchOnRegisteredWorker(
- ServiceWorkerFetchEventResult* result,
+ ServiceWorkerFetchDispatcher::FetchEventResult* result,
ServiceWorkerResponse* response,
std::unique_ptr<storage::BlobDataHandle>* blob_data_handle) {
blob_context_ = ChromeBlobStorageContext::GetFor(
@@ -800,10 +807,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
int request_id =
version_->StartRequest(ServiceWorkerMetrics::EventType::INSTALL,
CreateReceiver(BrowserThread::UI, done, result));
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo ptr_info;
- mojo::MakeRequest(&ptr_info);
version_->event_dispatcher()->DispatchInstallEvent(
- std::move(ptr_info),
base::BindOnce(&self::ReceiveInstallEventOnIOThread,
base::Unretained(this), done, result, request_id));
}
@@ -865,16 +869,30 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
bool* prepare_result,
FetchResult* result) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
- std::unique_ptr<ServiceWorkerFetchRequest> request(
- new ServiceWorkerFetchRequest(
- embedded_test_server()->GetURL("/service_worker/empty.html"), "GET",
- ServiceWorkerHeaderMap(), Referrer(), false));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
- fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
- std::move(request), version_.get(), RESOURCE_TYPE_MAIN_FRAME,
- base::nullopt, net::NetLogWithSource(),
- CreatePrepareReceiver(prepare_result),
- CreateResponseReceiver(done, blob_context_.get(), result)));
+ GURL url = embedded_test_server()->GetURL("/service_worker/empty.html");
+ ResourceType resource_type = RESOURCE_TYPE_MAIN_FRAME;
+ base::OnceClosure prepare_callback = CreatePrepareReceiver(prepare_result);
+ ServiceWorkerFetchDispatcher::FetchCallback fetch_callback =
+ CreateResponseReceiver(done, blob_context_.get(), result);
+ if (ServiceWorkerUtils::IsServicificationEnabled()) {
+ auto request = std::make_unique<ResourceRequest>();
+ request->url = url;
+ request->method = "GET";
+ request->resource_type = resource_type;
+ fetch_dispatcher_ = std::make_unique<ServiceWorkerFetchDispatcher>(
+ std::move(request), version_, base::nullopt /* timeout */,
+ net::NetLogWithSource(), std::move(prepare_callback),
+ std::move(fetch_callback));
+ } else {
+ auto legacy_request = std::make_unique<ServiceWorkerFetchRequest>(
+ url, "GET", ServiceWorkerHeaderMap(), Referrer(),
+ false /* is_reload */);
+ fetch_dispatcher_ = std::make_unique<ServiceWorkerFetchDispatcher>(
+ std::move(legacy_request), version_, resource_type,
+ base::nullopt /* timeout */, net::NetLogWithSource(),
+ std::move(prepare_callback), std::move(fetch_callback));
+ }
fetch_dispatcher_->Run();
}
@@ -886,11 +904,11 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
ChromeBlobStorageContext* blob_context,
FetchResult* out_result,
ServiceWorkerStatusCode actual_status,
- ServiceWorkerFetchEventResult actual_result,
+ ServiceWorkerFetchDispatcher::FetchEventResult actual_result,
const ServiceWorkerResponse& actual_response,
blink::mojom::ServiceWorkerStreamHandlePtr /* stream */,
- storage::mojom::BlobPtr /* blob */,
- const scoped_refptr<ServiceWorkerVersion>& worker) {
+ blink::mojom::BlobPtr /* blob */,
+ scoped_refptr<ServiceWorkerVersion> worker) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
ASSERT_TRUE(fetch_dispatcher_);
fetch_dispatcher_.reset();
@@ -910,9 +928,9 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
const base::Closure& quit,
ChromeBlobStorageContext* blob_context,
FetchResult* result) {
- return base::Bind(&self::ReceiveFetchResultOnIOThread,
- base::Unretained(this), quit,
- base::RetainedRef(blob_context), result);
+ return base::BindOnce(&self::ReceiveFetchResultOnIOThread,
+ base::Unretained(this), quit,
+ base::RetainedRef(blob_context), result);
}
void StopOnIOThread(const base::Closure& done) {
@@ -1224,14 +1242,15 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutWorkerInEvent) {
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_Response) {
StartServerAndNavigateToSetup();
- ServiceWorkerFetchEventResult result;
+ ServiceWorkerFetchDispatcher::FetchEventResult result;
ServiceWorkerResponse response;
std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
InstallTestHelper("/service_worker/fetch_event.js", SERVICE_WORKER_OK);
ActivateTestHelper("/service_worker/fetch_event.js", SERVICE_WORKER_OK);
FetchOnRegisteredWorker(&result, &response, &blob_data_handle);
- ASSERT_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, result);
+ ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
+ result);
EXPECT_EQ(301, response.status_code);
EXPECT_EQ("Moved Permanently", response.status_text);
ServiceWorkerHeaderMap expected_headers;
@@ -1249,7 +1268,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_Response) {
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
FetchEvent_ResponseViaCache) {
StartServerAndNavigateToSetup();
- ServiceWorkerFetchEventResult result;
+ ServiceWorkerFetchDispatcher::FetchEventResult result;
ServiceWorkerResponse response1;
ServiceWorkerResponse response2;
std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
@@ -1260,7 +1279,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
SERVICE_WORKER_OK);
FetchOnRegisteredWorker(&result, &response1, &blob_data_handle);
- ASSERT_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, result);
+ ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
+ result);
EXPECT_EQ(200, response1.status_code);
EXPECT_EQ("OK", response1.status_text);
EXPECT_TRUE(response1.response_time >= start_time);
@@ -1268,7 +1288,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
EXPECT_EQ(std::string(), response2.cache_storage_cache_name);
FetchOnRegisteredWorker(&result, &response2, &blob_data_handle);
- ASSERT_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, result);
+ ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
+ result);
EXPECT_EQ(200, response2.status_code);
EXPECT_EQ("OK", response2.status_text);
EXPECT_EQ(response1.response_time, response2.response_time);
@@ -1279,7 +1300,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
FetchEvent_respondWithRejection) {
StartServerAndNavigateToSetup();
- ServiceWorkerFetchEventResult result;
+ ServiceWorkerFetchDispatcher::FetchEventResult result;
ServiceWorkerResponse response;
std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
InstallTestHelper("/service_worker/fetch_event_rejected.js",
@@ -1305,7 +1326,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
base::Unretained(version_->embedded_worker()),
&console_listener));
- ASSERT_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, result);
+ ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
+ result);
EXPECT_EQ(0, response.status_code);
ASSERT_FALSE(blob_data_handle);
@@ -1337,11 +1359,16 @@ class MockContentBrowserClient : public TestContentBrowserClient {
class ServiceWorkerVersionOffMainThreadFetchTest
: public ServiceWorkerVersionBrowserTest {
public:
- ~ServiceWorkerVersionOffMainThreadFetchTest() override {}
- void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitchASCII(switches::kEnableFeatures,
- features::kOffMainThreadFetch.name);
+ ServiceWorkerVersionOffMainThreadFetchTest() {
+ scoped_feature_list_.InitAndEnableFeature(features::kOffMainThreadFetch);
}
+
+ ~ServiceWorkerVersionOffMainThreadFetchTest() override {}
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionOffMainThreadFetchTest);
};
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchWithSaveData) {
@@ -1352,6 +1379,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchWithSaveData) {
content_browser_client.set_data_saver_enabled(true);
ContentBrowserClient* old_client =
SetBrowserClientForTesting(&content_browser_client);
+ shell()->web_contents()->GetRenderViewHost()->OnWebkitPreferencesChanged();
InstallTestHelper("/service_worker/fetch_in_install.js", SERVICE_WORKER_OK);
SetBrowserClientForTesting(old_client);
}
@@ -1365,6 +1393,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionOffMainThreadFetchTest,
content_browser_client.set_data_saver_enabled(true);
ContentBrowserClient* old_client =
SetBrowserClientForTesting(&content_browser_client);
+ shell()->web_contents()->GetRenderViewHost()->OnWebkitPreferencesChanged();
InstallTestHelper("/service_worker/fetch_in_install.js", SERVICE_WORKER_OK);
SetBrowserClientForTesting(old_client);
}
@@ -1378,6 +1407,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
content_browser_client.set_data_saver_enabled(true);
ContentBrowserClient* old_client =
SetBrowserClientForTesting(&content_browser_client);
+ shell()->web_contents()->GetRenderViewHost()->OnWebkitPreferencesChanged();
InstallTestHelper("/service_worker/generated_sw.js", SERVICE_WORKER_OK);
SetBrowserClientForTesting(old_client);
}
@@ -1684,7 +1714,7 @@ class ServiceWorkerNavigationPreloadTest : public ServiceWorkerBrowserTest {
if (request.relative_url.substr(0, query_position) != relative_url)
return std::unique_ptr<net::test_server::HttpResponse>();
std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
- base::MakeUnique<net::test_server::BasicHttpResponse>());
+ std::make_unique<net::test_server::BasicHttpResponse>());
http_response->set_code(net::HTTP_OK);
http_response->set_content(content);
http_response->set_content_type(content_type);
@@ -1698,7 +1728,7 @@ class ServiceWorkerNavigationPreloadTest : public ServiceWorkerBrowserTest {
const size_t query_position = request.relative_url.find('?');
if (request.relative_url.substr(0, query_position) != relative_url)
return std::unique_ptr<net::test_server::HttpResponse>();
- return base::MakeUnique<CustomResponse>(response);
+ return std::make_unique<CustomResponse>(response);
}
std::unique_ptr<net::test_server::HttpResponse> KeepSearchRedirectHandler(
@@ -2586,12 +2616,15 @@ class ServiceWorkerVersionBrowserV8CacheTest
protected:
// ServiceWorkerVersion::Listener overrides
- void OnCachedMetadataUpdated(ServiceWorkerVersion* version) override {
+ void OnCachedMetadataUpdated(ServiceWorkerVersion* version,
+ size_t size) override {
+ metadata_size_ = size;
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
cache_updated_closure_);
}
base::Closure cache_updated_closure_;
+ size_t metadata_size_ = 0;
};
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest, Restart) {
@@ -2599,21 +2632,96 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest, Restart) {
RunOnIOThread(base::Bind(&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(SERVICE_WORKER_OK);
+ // Wait for the metadata to be stored. This run loop should finish when
+ // OnCachedMetadataUpdated() is called.
+ cached_metadata_run_loop.Run();
+ }
+
+ // Time stamp data must be stored to the storage.
+ 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(SERVICE_WORKER_OK);
+ // Wait for the matadata to be stored. This run loop should finish when
+ // OnCachedMetadataUpdated() is called.
+ cached_metadata_run_loop.Run();
+ }
+
+ // The V8 code cache should be stored to the storage. It must have size
+ // greater than 12 bytes.
+ EXPECT_GT(static_cast<int>(metadata_size_), kV8CacheTimeStampDataSize);
+
+ // Stop the worker.
+ StopWorker();
+}
+
+class ServiceWorkerVersionBrowserV8FullCodeCacheTest
+ : public ServiceWorkerVersionBrowserTest,
+ public ServiceWorkerVersion::Listener {
+ public:
+ using self = ServiceWorkerVersionBrowserV8FullCodeCacheTest;
+ ServiceWorkerVersionBrowserV8FullCodeCacheTest() {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kServiceWorkerScriptFullCodeCache);
+ }
+ ~ServiceWorkerVersionBrowserV8FullCodeCacheTest() override {
+ if (version_)
+ version_->RemoveListener(this);
+ }
+ void SetUpRegistrationAndListenerOnIOThread(const std::string& worker_url) {
+ SetUpRegistrationOnIOThread(worker_url);
+ version_->AddListener(this);
+ }
+
+ protected:
+ // ServiceWorkerVersion::Listener overrides
+ void OnCachedMetadataUpdated(ServiceWorkerVersion* version,
+ size_t size) override {
+ metadata_size_ = size;
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ cache_updated_closure_);
+ }
+
+ base::Closure cache_updated_closure_;
+ size_t metadata_size_ = 0;
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8FullCodeCacheTest,
+ FullCode) {
+ StartServerAndNavigateToSetup();
+ RunOnIOThread(base::Bind(&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(SERVICE_WORKER_OK);
- // Wait for the matadata is stored. This run loop should finish when
+ // Wait for the metadata to be stored. This run loop should finish when
// OnCachedMetadataUpdated() is called.
cached_metadata_run_loop.Run();
- // Stop the worker.
- StopWorker();
- // Restart the worker.
- StartWorker(SERVICE_WORKER_OK);
+ // The V8 code cache should be stored to the storage. It must have size
+ // greater than 12 bytes.
+ EXPECT_GT(static_cast<int>(metadata_size_), kV8CacheTimeStampDataSize);
+
// Stop the worker.
StopWorker();
}
@@ -2664,16 +2772,15 @@ class CacheStorageSideDataSizeChecker
continuation));
}
- void OnCacheStorageOpenCallback(
- int* result,
- const base::Closure& continuation,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
- CacheStorageError error) {
- ASSERT_EQ(CACHE_STORAGE_OK, error);
+ void OnCacheStorageOpenCallback(int* result,
+ const base::Closure& continuation,
+ CacheStorageCacheHandle cache_handle,
+ CacheStorageError error) {
+ ASSERT_EQ(CacheStorageError::kSuccess, error);
std::unique_ptr<ServiceWorkerFetchRequest> scoped_request(
new ServiceWorkerFetchRequest());
scoped_request->url = url_;
- CacheStorageCache* cache = cache_handle->value();
+ CacheStorageCache* cache = cache_handle.value();
cache->Match(
std::move(scoped_request), CacheStorageCacheQueryParams(),
base::BindOnce(&self::OnCacheStorageCacheMatchCallback, this, result,
@@ -2683,13 +2790,13 @@ class CacheStorageSideDataSizeChecker
void OnCacheStorageCacheMatchCallback(
int* result,
const base::Closure& continuation,
- std::unique_ptr<CacheStorageCacheHandle> cache_handle,
+ CacheStorageCacheHandle cache_handle,
CacheStorageError error,
std::unique_ptr<ServiceWorkerResponse> response,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle) {
- ASSERT_EQ(CACHE_STORAGE_OK, error);
+ ASSERT_EQ(CacheStorageError::kSuccess, error);
blob_data_handle_ = std::move(blob_data_handle);
- blob_reader_ = blob_data_handle_->CreateReader(file_system_context_);
+ blob_reader_ = blob_data_handle_->CreateReader();
const storage::BlobReader::Status status = blob_reader_->CalculateSize(
base::Bind(&self::OnBlobReaderCalculateSizeCallback, this, result,
continuation));
@@ -2737,10 +2844,11 @@ class CacheStorageSideDataSizeChecker
DISALLOW_COPY_AND_ASSIGN(CacheStorageSideDataSizeChecker);
};
-class ServiceWorkerV8CacheStrategiesTest : public ServiceWorkerBrowserTest {
+class ServiceWorkerV8CodeCacheForCacheStorageTest
+ : public ServiceWorkerBrowserTest {
public:
- ServiceWorkerV8CacheStrategiesTest() {}
- ~ServiceWorkerV8CacheStrategiesTest() override {}
+ ServiceWorkerV8CodeCacheForCacheStorageTest() = default;
+ ~ServiceWorkerV8CodeCacheForCacheStorageTest() override = default;
void SetUpOnMainThread() override {
ServiceWorkerBrowserTest::SetUpOnMainThread();
@@ -2748,61 +2856,6 @@ class ServiceWorkerV8CacheStrategiesTest : public ServiceWorkerBrowserTest {
}
protected:
- void CheckStrategyIsNone() {
- RegisterAndActivateServiceWorker();
-
- NavigateToTestPage();
- WaitUntilSideDataSizeIs(0);
-
- NavigateToTestPage();
- WaitUntilSideDataSizeIs(0);
-
- NavigateToTestPage();
- WaitUntilSideDataSizeIs(0);
- }
-
- void CheckStrategyIsNormal() {
- RegisterAndActivateServiceWorker();
-
- NavigateToTestPage();
- // fetch_event_response_via_cache.js returns |cloned_response| for the first
- // load. So the V8 code cache should not be stored to the CacheStorage.
- WaitUntilSideDataSizeIs(0);
-
- NavigateToTestPage();
- // V8ScriptRunner::setCacheTimeStamp() stores 12 byte data (tag +
- // timestamp).
- WaitUntilSideDataSizeIs(kV8CacheTimeStampDataSize);
-
- NavigateToTestPage();
- // The V8 code cache must be stored to the CacheStorage which must be bigger
- // than 12 byte.
- WaitUntilSideDataSizeIsBiggerThan(kV8CacheTimeStampDataSize);
- }
-
- void CheckStrategyIsAggressive() {
- RegisterAndActivateServiceWorker();
-
- NavigateToTestPage();
- // fetch_event_response_via_cache.js returns |cloned_response| for the first
- // load. So the V8 code cache should not be stored to the CacheStorage.
- WaitUntilSideDataSizeIs(0);
-
- NavigateToTestPage();
- // The V8 code cache must be stored to the CacheStorage which must be bigger
- // than 12 byte.
- WaitUntilSideDataSizeIsBiggerThan(kV8CacheTimeStampDataSize);
-
- NavigateToTestPage();
- WaitUntilSideDataSizeIsBiggerThan(kV8CacheTimeStampDataSize);
- }
-
- private:
- static const char kPageUrl[];
- static const char kWorkerUrl[];
- static const char kScriptUrl[];
- static const int kV8CacheTimeStampDataSize;
-
void RegisterAndActivateServiceWorker() {
scoped_refptr<WorkerActivatedObserver> observer =
new WorkerActivatedObserver(wrapper());
@@ -2822,16 +2875,6 @@ class ServiceWorkerV8CacheStrategiesTest : public ServiceWorkerBrowserTest {
EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
}
- int GetSideDataSize() {
- StoragePartition* partition = BrowserContext::GetDefaultStoragePartition(
- shell()->web_contents()->GetBrowserContext());
- return CacheStorageSideDataSizeChecker::GetSize(
- static_cast<CacheStorageContextImpl*>(
- partition->GetCacheStorageContext()),
- partition->GetFileSystemContext(), embedded_test_server()->base_url(),
- std::string("cache_name"), embedded_test_server()->GetURL(kScriptUrl));
- }
-
void WaitUntilSideDataSizeIs(int expected_size) {
while (true) {
if (GetSideDataSize() == expected_size)
@@ -2846,80 +2889,71 @@ class ServiceWorkerV8CacheStrategiesTest : public ServiceWorkerBrowserTest {
}
}
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerV8CacheStrategiesTest);
+ private:
+ static const char kPageUrl[];
+ static const char kWorkerUrl[];
+ static const char kScriptUrl[];
+
+ int GetSideDataSize() {
+ StoragePartition* partition = BrowserContext::GetDefaultStoragePartition(
+ shell()->web_contents()->GetBrowserContext());
+ return CacheStorageSideDataSizeChecker::GetSize(
+ static_cast<CacheStorageContextImpl*>(
+ partition->GetCacheStorageContext()),
+ partition->GetFileSystemContext(), embedded_test_server()->base_url(),
+ std::string("cache_name"), embedded_test_server()->GetURL(kScriptUrl));
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerV8CodeCacheForCacheStorageTest);
};
-const char ServiceWorkerV8CacheStrategiesTest::kPageUrl[] =
+const char ServiceWorkerV8CodeCacheForCacheStorageTest::kPageUrl[] =
"/service_worker/v8_cache_test.html";
-const char ServiceWorkerV8CacheStrategiesTest::kWorkerUrl[] =
+const char ServiceWorkerV8CodeCacheForCacheStorageTest::kWorkerUrl[] =
"/service_worker/fetch_event_response_via_cache.js";
-const char ServiceWorkerV8CacheStrategiesTest::kScriptUrl[] =
+const char ServiceWorkerV8CodeCacheForCacheStorageTest::kScriptUrl[] =
"/service_worker/v8_cache_test.js";
-// V8ScriptRunner::setCacheTimeStamp() stores 12 byte data (tag + timestamp).
-const int ServiceWorkerV8CacheStrategiesTest::kV8CacheTimeStampDataSize =
- sizeof(unsigned) + sizeof(double);
-IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CacheStrategiesTest,
+IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CodeCacheForCacheStorageTest,
V8CacheOnCacheStorage) {
- // The strategy is "aggressive" on default.
- CheckStrategyIsAggressive();
-}
+ RegisterAndActivateServiceWorker();
-class ServiceWorkerV8CacheStrategiesNoneTest
- : public ServiceWorkerV8CacheStrategiesTest {
- public:
- ServiceWorkerV8CacheStrategiesNoneTest() {}
- ~ServiceWorkerV8CacheStrategiesNoneTest() override {}
- void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitchASCII(switches::kV8CacheStrategiesForCacheStorage,
- "none");
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerV8CacheStrategiesNoneTest);
-};
+ // First load: fetch_event_response_via_cache.js returns |cloned_response|.
+ // The V8 code cache should not be stored in CacheStorage.
+ NavigateToTestPage();
+ WaitUntilSideDataSizeIs(0);
-IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CacheStrategiesNoneTest,
- V8CacheOnCacheStorage) {
- CheckStrategyIsNone();
+ // Second load: The V8 code cache should be stored in CacheStorage. It must
+ // have size greater than 12 bytes.
+ NavigateToTestPage();
+ WaitUntilSideDataSizeIsBiggerThan(kV8CacheTimeStampDataSize);
}
-class ServiceWorkerV8CacheStrategiesNormalTest
- : public ServiceWorkerV8CacheStrategiesTest {
+class ServiceWorkerV8CodeCacheForCacheStorageNoneTest
+ : public ServiceWorkerV8CodeCacheForCacheStorageTest {
public:
- ServiceWorkerV8CacheStrategiesNormalTest() {}
- ~ServiceWorkerV8CacheStrategiesNormalTest() override {}
+ ServiceWorkerV8CodeCacheForCacheStorageNoneTest() {}
+ ~ServiceWorkerV8CodeCacheForCacheStorageNoneTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitchASCII(switches::kV8CacheStrategiesForCacheStorage,
- "normal");
+ command_line->AppendSwitchASCII(switches::kV8CacheOptions, "none");
}
private:
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerV8CacheStrategiesNormalTest);
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerV8CodeCacheForCacheStorageNoneTest);
};
-IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CacheStrategiesNormalTest,
+IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CodeCacheForCacheStorageNoneTest,
V8CacheOnCacheStorage) {
- CheckStrategyIsNormal();
-}
+ RegisterAndActivateServiceWorker();
-class ServiceWorkerV8CacheStrategiesAggressiveTest
- : public ServiceWorkerV8CacheStrategiesTest {
- public:
- ServiceWorkerV8CacheStrategiesAggressiveTest() {}
- ~ServiceWorkerV8CacheStrategiesAggressiveTest() override {}
- void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitchASCII(switches::kV8CacheStrategiesForCacheStorage,
- "aggressive");
- }
+ // First load.
+ NavigateToTestPage();
+ WaitUntilSideDataSizeIs(0);
- private:
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerV8CacheStrategiesAggressiveTest);
-};
-
-IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CacheStrategiesAggressiveTest,
- V8CacheOnCacheStorage) {
- CheckStrategyIsAggressive();
+ // Second load: The V8 code cache must not be stored even after the second
+ // load when --v8-cache-options=none is set.
+ NavigateToTestPage();
+ WaitUntilSideDataSizeIs(0);
}
// ServiceWorkerDisableWebSecurityTests check the behavior when the web security
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 ab849450fc1..fe35ed66883 100644
--- a/chromium/content/browser/service_worker/service_worker_client_utils.cc
+++ b/chromium/content/browser/service_worker/service_worker_client_utils.cc
@@ -31,6 +31,8 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/child_process_host.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
+#include "third_party/WebKit/common/service_worker/service_worker_client.mojom.h"
#include "url/gurl.h"
namespace content {
@@ -125,7 +127,7 @@ ServiceWorkerClientInfo GetWindowClientInfoOnUI(
render_frame_host->GetParent() ? REQUEST_CONTEXT_FRAME_TYPE_NESTED
: REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
render_frame_host->frame_tree_node()->last_focus_time(), create_time,
- blink::kWebServiceWorkerClientTypeWindow);
+ blink::mojom::ServiceWorkerClientType::kWindow);
}
ServiceWorkerClientInfo FocusOnUI(int render_process_id,
@@ -299,7 +301,7 @@ void AddWindowClient(
std::vector<std::tuple<int, int, base::TimeTicks, std::string>>*
client_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (host->client_type() != blink::kWebServiceWorkerClientTypeWindow)
+ if (host->client_type() != blink::mojom::ServiceWorkerClientType::kWindow)
return;
client_info->push_back(std::make_tuple(host->process_id(), host->frame_id(),
host->create_time(),
@@ -310,15 +312,15 @@ void AddNonWindowClient(ServiceWorkerProviderHost* host,
const ServiceWorkerClientQueryOptions& options,
ServiceWorkerClients* clients) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- blink::WebServiceWorkerClientType host_client_type = host->client_type();
- if (host_client_type == blink::kWebServiceWorkerClientTypeWindow)
+ blink::mojom::ServiceWorkerClientType host_client_type = host->client_type();
+ if (host_client_type == blink::mojom::ServiceWorkerClientType::kWindow)
return;
- if (options.client_type != blink::kWebServiceWorkerClientTypeAll &&
+ if (options.client_type != blink::mojom::ServiceWorkerClientType::kAll &&
options.client_type != host_client_type)
return;
ServiceWorkerClientInfo client_info(
- host->client_uuid(), blink::kWebPageVisibilityStateHidden,
+ host->client_uuid(), blink::mojom::PageVisibilityState::kHidden,
false, // is_focused
host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE, base::TimeTicks(),
host->create_time(), host_client_type);
@@ -362,12 +364,12 @@ struct ServiceWorkerClientInfoSort {
bool operator()(const ServiceWorkerClientInfo& a,
const ServiceWorkerClientInfo& b) const {
// Clients for windows should be appeared earlier.
- if (a.client_type == blink::kWebServiceWorkerClientTypeWindow &&
- b.client_type != blink::kWebServiceWorkerClientTypeWindow) {
+ if (a.client_type == blink::mojom::ServiceWorkerClientType::kWindow &&
+ b.client_type != blink::mojom::ServiceWorkerClientType::kWindow) {
return true;
}
- if (a.client_type != blink::kWebServiceWorkerClientTypeWindow &&
- b.client_type == blink::kWebServiceWorkerClientTypeWindow) {
+ if (a.client_type != blink::mojom::ServiceWorkerClientType::kWindow &&
+ b.client_type == blink::mojom::ServiceWorkerClientType::kWindow) {
return false;
}
@@ -412,7 +414,7 @@ void DidGetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
const ClientsCallback& callback,
std::unique_ptr<ServiceWorkerClients> clients) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (options.client_type == blink::kWebServiceWorkerClientTypeAll) {
+ if (options.client_type == blink::mojom::ServiceWorkerClientType::kAll) {
GetNonWindowClients(controller, options, callback, std::move(clients));
return;
}
@@ -424,8 +426,9 @@ void GetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
const ClientsCallback& callback,
std::unique_ptr<ServiceWorkerClients> clients) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(options.client_type == blink::kWebServiceWorkerClientTypeWindow ||
- options.client_type == blink::kWebServiceWorkerClientTypeAll);
+ DCHECK(options.client_type ==
+ blink::mojom::ServiceWorkerClientType::kWindow ||
+ options.client_type == blink::mojom::ServiceWorkerClientType::kAll);
std::vector<std::tuple<int, int, base::TimeTicks, std::string>> clients_info;
if (!options.include_uncontrolled) {
@@ -457,7 +460,7 @@ void GetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
void FocusWindowClient(ServiceWorkerProviderHost* provider_host,
const ClientCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_EQ(blink::kWebServiceWorkerClientTypeWindow,
+ DCHECK_EQ(blink::mojom::ServiceWorkerClientType::kWindow,
provider_host->client_type());
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::UI, FROM_HERE,
@@ -500,13 +503,13 @@ void GetClient(ServiceWorkerProviderHost* provider_host,
const ClientCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- blink::WebServiceWorkerClientType client_type = provider_host->client_type();
- DCHECK(client_type == blink::kWebServiceWorkerClientTypeWindow ||
- client_type == blink::kWebServiceWorkerClientTypeWorker ||
- client_type == blink::kWebServiceWorkerClientTypeSharedWorker)
+ blink::mojom::ServiceWorkerClientType client_type =
+ provider_host->client_type();
+ DCHECK(client_type == blink::mojom::ServiceWorkerClientType::kWindow ||
+ client_type == blink::mojom::ServiceWorkerClientType::kSharedWorker)
<< client_type;
- if (client_type == blink::kWebServiceWorkerClientTypeWindow) {
+ if (client_type == blink::mojom::ServiceWorkerClientType::kWindow) {
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::UI, FROM_HERE,
base::Bind(&GetWindowClientInfoOnUI, provider_host->process_id(),
@@ -517,7 +520,7 @@ void GetClient(ServiceWorkerProviderHost* provider_host,
}
ServiceWorkerClientInfo client_info(
- provider_host->client_uuid(), blink::kWebPageVisibilityStateHidden,
+ provider_host->client_uuid(), blink::mojom::PageVisibilityState::kHidden,
false, // is_focused
provider_host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE,
base::TimeTicks(), provider_host->create_time(),
@@ -531,15 +534,15 @@ void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
const ClientsCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- auto clients = base::MakeUnique<ServiceWorkerClients>();
+ auto clients = std::make_unique<ServiceWorkerClients>();
if (!controller->HasControllee() && !options.include_uncontrolled) {
DidGetClients(callback, std::move(clients));
return;
}
// For Window clients we want to query the info on the UI thread first.
- if (options.client_type == blink::kWebServiceWorkerClientTypeWindow ||
- options.client_type == blink::kWebServiceWorkerClientTypeAll) {
+ if (options.client_type == blink::mojom::ServiceWorkerClientType::kWindow ||
+ options.client_type == blink::mojom::ServiceWorkerClientType::kAll) {
GetWindowClients(controller, options, callback, std::move(clients));
return;
}
diff --git a/chromium/content/browser/service_worker/service_worker_consts.cc b/chromium/content/browser/service_worker/service_worker_consts.cc
new file mode 100644
index 00000000000..0a6663fa0c5
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_consts.cc
@@ -0,0 +1,52 @@
+// Copyright 2017 The Chromium Authors. 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_consts.h"
+
+namespace content {
+
+const char ServiceWorkerConsts::kBadMessageFromNonWindow[] =
+ "The request message should not come from a non-window client.";
+
+const char ServiceWorkerConsts::kBadMessageGetRegistrationForReadyDuplicated[] =
+ "There's already a completed or ongoing request to get the ready "
+ "registration.";
+
+const char ServiceWorkerConsts::kBadMessageImproperOrigins[] =
+ "Origins are not matching, or some cannot access service worker.";
+
+const char ServiceWorkerConsts::kBadMessageInvalidURL[] =
+ "Some URLs are invalid.";
+
+const char ServiceWorkerConsts::kBadNavigationPreloadHeaderValue[] =
+ "The navigation preload header value is invalid.";
+
+const char ServiceWorkerConsts::kDatabaseErrorMessage[] =
+ "Failed to access storage.";
+
+const char ServiceWorkerConsts::kEnableNavigationPreloadErrorPrefix[] =
+ "Failed to enable or disable navigation preload: ";
+
+const char ServiceWorkerConsts::kGetNavigationPreloadStateErrorPrefix[] =
+ "Failed to get navigation preload state: ";
+
+const char ServiceWorkerConsts::kInvalidStateErrorMessage[] =
+ "The object is in an invalid state.";
+
+const char ServiceWorkerConsts::kNoActiveWorkerErrorMessage[] =
+ "The registration does not have an active worker.";
+
+const char ServiceWorkerConsts::kNoDocumentURLErrorMessage[] =
+ "No URL is associated with the caller's document.";
+
+const char ServiceWorkerConsts::kSetNavigationPreloadHeaderErrorPrefix[] =
+ "Failed to set navigation preload header: ";
+
+const char ServiceWorkerConsts::kShutdownErrorMessage[] =
+ "The Service Worker system has shutdown.";
+
+const char ServiceWorkerConsts::kUserDeniedPermissionMessage[] =
+ "The user denied permission to use Service Worker.";
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_consts.h b/chromium/content/browser/service_worker/service_worker_consts.h
new file mode 100644
index 00000000000..d119a472c79
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_consts.h
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONSTS_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONSTS_H_
+
+namespace content {
+
+struct ServiceWorkerConsts {
+ static const char kBadMessageFromNonWindow[];
+ static const char kBadMessageGetRegistrationForReadyDuplicated[];
+ static const char kBadMessageImproperOrigins[];
+ static const char kBadMessageInvalidURL[];
+ static const char kBadNavigationPreloadHeaderValue[];
+ static const char kDatabaseErrorMessage[];
+ static const char kEnableNavigationPreloadErrorPrefix[];
+ static const char kGetNavigationPreloadStateErrorPrefix[];
+ static const char kInvalidStateErrorMessage[];
+ static const char kNoActiveWorkerErrorMessage[];
+ static const char kNoDocumentURLErrorMessage[];
+ static const char kSetNavigationPreloadHeaderErrorPrefix[];
+ static const char kShutdownErrorMessage[];
+ static const char kUserDeniedPermissionMessage[];
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONSTS_H_
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 b8ac5b41c3b..2934d52f2c7 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
@@ -16,7 +16,7 @@ ServiceWorkerContentSettingsProxyImpl::ServiceWorkerContentSettingsProxyImpl(
const GURL& script_url,
base::WeakPtr<ServiceWorkerContextCore> context,
blink::mojom::WorkerContentSettingsProxyRequest request)
- : origin_(script_url),
+ : origin_(url::Origin::Create(script_url)),
context_(context),
binding_(this, std::move(request)) {}
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 18138b8885f..c717e64b18c 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_core.cc
@@ -39,6 +39,7 @@
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "storage/browser/quota/quota_manager_proxy.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
#include "url/gurl.h"
@@ -66,22 +67,23 @@ void CheckFetchHandlerOfInstalledServiceWorker(
: ServiceWorkerCapability::SERVICE_WORKER_NO_FETCH_HANDLER);
}
-void SuccessCollectorCallback(const base::Closure& done_closure,
+void SuccessCollectorCallback(base::OnceClosure done_closure,
bool* overall_success,
ServiceWorkerStatusCode status) {
if (status != ServiceWorkerStatusCode::SERVICE_WORKER_OK) {
*overall_success = false;
}
- done_closure.Run();
+ std::move(done_closure).Run();
}
void SuccessReportingCallback(
const bool* success,
- const ServiceWorkerContextCore::UnregistrationCallback& callback) {
+ base::OnceCallback<void(ServiceWorkerStatusCode)> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
bool result = *success;
- callback.Run(result ? ServiceWorkerStatusCode::SERVICE_WORKER_OK
- : ServiceWorkerStatusCode::SERVICE_WORKER_ERROR_FAILED);
+ std::move(callback).Run(
+ result ? ServiceWorkerStatusCode::SERVICE_WORKER_OK
+ : ServiceWorkerStatusCode::SERVICE_WORKER_ERROR_FAILED);
}
bool IsSameOriginClientProviderHost(const GURL& origin,
@@ -93,7 +95,7 @@ bool IsSameOriginClientProviderHost(const GURL& origin,
bool IsSameOriginWindowProviderHost(const GURL& origin,
ServiceWorkerProviderHost* host) {
return host->provider_type() ==
- ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_FOR_WINDOW &&
+ blink::mojom::ServiceWorkerProviderType::kForWindow &&
host->document_url().GetOrigin() == origin;
}
@@ -163,6 +165,35 @@ class ClearAllServiceWorkersHelper
DISALLOW_COPY_AND_ASSIGN(ClearAllServiceWorkersHelper);
};
+class RegistrationDeletionListener
+ : public ServiceWorkerRegistration::Listener {
+ public:
+ // Wait until a |registration| is deleted and call |callback|.
+ static void WaitForDeletion(
+ scoped_refptr<ServiceWorkerRegistration> registration,
+ base::OnceClosure callback) {
+ DCHECK(!registration->is_deleted());
+ registration->AddListener(
+ new RegistrationDeletionListener(registration, std::move(callback)));
+ }
+
+ void OnRegistrationDeleted(ServiceWorkerRegistration* registration) override {
+ registration->RemoveListener(this);
+ std::move(callback_).Run();
+ delete this;
+ }
+
+ private:
+ RegistrationDeletionListener(
+ scoped_refptr<ServiceWorkerRegistration> registration,
+ base::OnceClosure callback)
+ : registration_(std::move(registration)),
+ callback_(std::move(callback)) {}
+ virtual ~RegistrationDeletionListener() = default;
+
+ scoped_refptr<ServiceWorkerRegistration> registration_;
+ base::OnceClosure callback_;
+};
} // namespace
const base::FilePath::CharType
@@ -244,12 +275,11 @@ ServiceWorkerContextCore::ServiceWorkerContextCore(
observer_list,
ServiceWorkerContextWrapper* wrapper)
: wrapper_(wrapper),
- providers_(base::MakeUnique<ProcessToProviderMap>()),
- provider_by_uuid_(base::MakeUnique<ProviderByClientUUIDMap>()),
+ providers_(std::make_unique<ProcessToProviderMap>()),
+ provider_by_uuid_(std::make_unique<ProviderByClientUUIDMap>()),
loader_factory_getter_(url_loader_factory_getter),
force_update_on_page_load_(false),
next_handle_id_(0),
- next_registration_handle_id_(0),
was_service_worker_registered_(false),
observer_list_(observer_list),
weak_factory_(this) {
@@ -270,7 +300,6 @@ ServiceWorkerContextCore::ServiceWorkerContextCore(
providers_(old_context->providers_.release()),
provider_by_uuid_(old_context->provider_by_uuid_.release()),
next_handle_id_(old_context->next_handle_id_),
- next_registration_handle_id_(old_context->next_registration_handle_id_),
was_service_worker_registered_(
old_context->was_service_worker_registered_),
observer_list_(old_context->observer_list_),
@@ -312,6 +341,12 @@ ServiceWorkerDispatcherHost* ServiceWorkerContextCore::GetDispatcherHost(
void ServiceWorkerContextCore::RemoveDispatcherHost(int process_id) {
// Temporary CHECK for debugging https://crbug.com/750267.
CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // TODO(falken) Try to remove this call. It should be unnecessary because
+ // provider hosts remove themselves when their Mojo connection to the renderer
+ // is destroyed. But if we don't remove the hosts immediately here, collisions
+ // of <process_id, provider_id> can occur if a new dispatcher host is
+ // created for a reused RenderProcessHost. https://crbug.com/736203
+ RemoveAllProviderHostsForProcess(process_id);
dispatcher_hosts_.erase(process_id);
}
@@ -323,7 +358,7 @@ void ServiceWorkerContextCore::AddProviderHost(
int provider_id = host->provider_id();
ProviderMap* map = GetProviderMapForProcess(process_id);
if (!map) {
- providers_->AddWithID(base::MakeUnique<ProviderMap>(), process_id);
+ providers_->AddWithID(std::make_unique<ProviderMap>(), process_id);
map = GetProviderMapForProcess(process_id);
}
map->AddWithID(std::move(host), provider_id);
@@ -468,38 +503,44 @@ void ServiceWorkerContextCore::UnregisterServiceWorker(
callback));
}
-void ServiceWorkerContextCore::UnregisterServiceWorkers(
+void ServiceWorkerContextCore::DeleteForOrigin(
const GURL& origin,
- const UnregistrationCallback& callback) {
+ base::OnceCallback<void(ServiceWorkerStatusCode)> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- storage()->GetAllRegistrationsInfos(base::Bind(
- &ServiceWorkerContextCore::DidGetAllRegistrationsForUnregisterForOrigin,
- AsWeakPtr(), callback, origin));
+ storage()->GetRegistrationsForOrigin(
+ origin,
+ AdaptCallbackForRepeating(base::BindOnce(
+ &ServiceWorkerContextCore::DidGetRegistrationsForDeleteForOrigin,
+ AsWeakPtr(), std::move(callback))));
}
-void ServiceWorkerContextCore::DidGetAllRegistrationsForUnregisterForOrigin(
- const UnregistrationCallback& result,
- const GURL& origin,
+void ServiceWorkerContextCore::DidGetRegistrationsForDeleteForOrigin(
+ base::OnceCallback<void(ServiceWorkerStatusCode)> callback,
ServiceWorkerStatusCode status,
- const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
+ const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
+ registrations) {
if (status != SERVICE_WORKER_OK) {
- result.Run(status);
+ std::move(callback).Run(status);
return;
}
- std::set<GURL> scopes;
- for (const auto& registration_info : registrations) {
- if (origin == registration_info.pattern.GetOrigin()) {
- scopes.insert(registration_info.pattern);
- }
- }
bool* overall_success = new bool(true);
- base::Closure barrier = base::BarrierClosure(
- scopes.size(), base::BindOnce(&SuccessReportingCallback,
- base::Owned(overall_success), result));
-
- for (const GURL& scope : scopes) {
+ // The barrier must be executed twice for each registration: once for
+ // unregistration and once for deletion.
+ base::RepeatingClosure barrier = base::BarrierClosure(
+ 2 * registrations.size(),
+ base::BindOnce(&SuccessReportingCallback, base::Owned(overall_success),
+ std::move(callback)));
+ for (const auto& registration : registrations) {
+ DCHECK(registration);
+ if (!registration->is_deleted()) {
+ RegistrationDeletionListener::WaitForDeletion(registration, barrier);
+ } else {
+ barrier.Run();
+ }
UnregisterServiceWorker(
- scope, base::Bind(&SuccessCollectorCallback, barrier, overall_success));
+ registration->pattern(),
+ AdaptCallbackForRepeating(base::BindOnce(&SuccessCollectorCallback,
+ barrier, overall_success)));
}
}
@@ -673,10 +714,6 @@ int ServiceWorkerContextCore::GetNewServiceWorkerHandleId() {
return next_handle_id_++;
}
-int ServiceWorkerContextCore::GetNewRegistrationHandleId() {
- return next_registration_handle_id_++;
-}
-
void ServiceWorkerContextCore::ScheduleDeleteAndStartOver() const {
storage_->Disable();
base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/chromium/content/browser/service_worker/service_worker_context_core.h b/chromium/content/browser/service_worker/service_worker_context_core.h
index 194f7c4b9fe..6d2db80fb11 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core.h
+++ b/chromium/content/browser/service_worker/service_worker_context_core.h
@@ -181,7 +181,8 @@ class CONTENT_EXPORT ServiceWorkerContextCore
const GURL& origin);
// Runs the callback with true if there is a ProviderHost for |origin| of type
- // SERVICE_WORKER_PROVIDER_FOR_WINDOW which is a main (top-level) frame.
+ // blink::mojom::ServiceWorkerProviderType::kForWindow which is a main
+ // (top-level) frame.
void HasMainFrameProviderHost(const GURL& origin,
const BoolCallback& callback) const;
@@ -204,11 +205,12 @@ class CONTENT_EXPORT ServiceWorkerContextCore
void UnregisterServiceWorker(const GURL& pattern,
const UnregistrationCallback& callback);
- // Callback is called issued after all unregistrations occur. The Status
- // is populated as SERVICE_WORKER_OK if all succeed, or SERVICE_WORKER_FAILED
+ // Callback is called after all deletions occured. The status code is
+ // SERVICE_WORKER_OK if all succeed, or SERVICE_WORKER_FAILED
// if any did not succeed.
- void UnregisterServiceWorkers(const GURL& origin,
- const UnregistrationCallback& callback);
+ void DeleteForOrigin(
+ const GURL& origin,
+ base::OnceCallback<void(ServiceWorkerStatusCode)> callback);
// Updates the service worker. If |force_bypass_cache| is true or 24 hours
// have passed since the last update, bypasses the browser cache.
@@ -265,7 +267,6 @@ class CONTENT_EXPORT ServiceWorkerContextCore
// Returns new context-local unique ID.
int GetNewServiceWorkerHandleId();
- int GetNewRegistrationHandleId();
void ScheduleDeleteAndStartOver() const;
@@ -336,11 +337,11 @@ class CONTENT_EXPORT ServiceWorkerContextCore
int64_t registration_id,
ServiceWorkerStatusCode status);
- void DidGetAllRegistrationsForUnregisterForOrigin(
- const UnregistrationCallback& result,
- const GURL& origin,
+ void DidGetRegistrationsForDeleteForOrigin(
+ base::OnceCallback<void(ServiceWorkerStatusCode)> callback,
ServiceWorkerStatusCode status,
- const std::vector<ServiceWorkerRegistrationInfo>& registrations);
+ const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
+ registrations);
void DidFindRegistrationForCheckHasServiceWorker(
const GURL& other_url,
@@ -378,7 +379,6 @@ class CONTENT_EXPORT ServiceWorkerContextCore
bool force_update_on_page_load_;
int next_handle_id_;
- int next_registration_handle_id_;
// Set in RegisterServiceWorker(), cleared in ClearAllServiceWorkersForTest().
// This is used to avoid unnecessary disk read operation in tests. This value
// is false if Chrome was relaunched after service workers were registered.
diff --git a/chromium/content/browser/service_worker/service_worker_context_core_observer.h b/chromium/content/browser/service_worker/service_worker_context_core_observer.h
index e8bf1086848..44e788b8f1e 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core_observer.h
+++ b/chromium/content/browser/service_worker/service_worker_context_core_observer.h
@@ -12,6 +12,7 @@
#include "base/time/time.h"
#include "content/browser/service_worker/service_worker_info.h"
#include "content/browser/service_worker/service_worker_version.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
#include "url/gurl.h"
namespace content {
@@ -85,7 +86,7 @@ class ServiceWorkerContextCoreObserver {
int process_id,
int route_id,
const base::Callback<WebContents*(void)>& web_contents_getter,
- ServiceWorkerProviderType type) {}
+ blink::mojom::ServiceWorkerProviderType type) {}
virtual void OnControlleeRemoved(int64_t version_id,
const std::string& uuid) {}
virtual void OnRegistrationStored(int64_t registration_id,
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 a5c1436753e..11c63c40884 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
@@ -109,7 +109,7 @@ class ServiceWorkerContextRequestHandlerTest : public testing::Test {
// Creates a ServiceWorkerContextHandler directly.
std::unique_ptr<ServiceWorkerContextRequestHandler> CreateHandler(
ResourceType resource_type) {
- return base::MakeUnique<ServiceWorkerContextRequestHandler>(
+ return std::make_unique<ServiceWorkerContextRequestHandler>(
context()->AsWeakPtr(), provider_host_,
base::WeakPtr<storage::BlobStorageContext>(), resource_type);
}
@@ -121,9 +121,11 @@ class ServiceWorkerContextRequestHandlerTest : public testing::Test {
ServiceWorkerRequestHandler::InitializeHandler(
request, helper_->context_wrapper(), &blob_storage_context_,
helper_->mock_render_process_id(), provider_host_->provider_id(),
- false /* skip_service_worker */, FETCH_REQUEST_MODE_NO_CORS,
- FETCH_CREDENTIALS_MODE_OMIT, FetchRedirectMode::FOLLOW_MODE,
- std::string() /* integrity */, RESOURCE_TYPE_SERVICE_WORKER,
+ false /* skip_service_worker */,
+ network::mojom::FetchRequestMode::kNoCORS,
+ network::mojom::FetchCredentialsMode::kOmit,
+ FetchRedirectMode::FOLLOW_MODE, std::string() /* integrity */,
+ false /* keepalive */, RESOURCE_TYPE_SERVICE_WORKER,
REQUEST_CONTEXT_TYPE_SERVICE_WORKER, REQUEST_CONTEXT_FRAME_TYPE_NONE,
nullptr);
}
@@ -254,9 +256,10 @@ TEST_F(ServiceWorkerContextRequestHandlerTest,
ServiceWorkerRequestHandler::InitializeHandler(
request.get(), helper_->context_wrapper(), &blob_storage_context_,
helper_->mock_render_process_id(), provider_host_->provider_id(),
- true /* skip_service_worker */, FETCH_REQUEST_MODE_NO_CORS,
- FETCH_CREDENTIALS_MODE_OMIT, FetchRedirectMode::FOLLOW_MODE,
- std::string() /* integrity */, RESOURCE_TYPE_SERVICE_WORKER,
+ true /* skip_service_worker */, network::mojom::FetchRequestMode::kNoCORS,
+ network::mojom::FetchCredentialsMode::kOmit,
+ FetchRedirectMode::FOLLOW_MODE, std::string() /* integrity */,
+ false /* keepalive */, RESOURCE_TYPE_SERVICE_WORKER,
REQUEST_CONTEXT_TYPE_SERVICE_WORKER, REQUEST_CONTEXT_FRAME_TYPE_NONE,
nullptr);
// Verify a ServiceWorkerRequestHandler was created.
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 8105156cb8d..00986969fbe 100644
--- a/chromium/content/browser/service_worker/service_worker_context_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_unittest.cc
@@ -90,7 +90,6 @@ class RejectInstallTestHelper : public EmbeddedWorkerTestHelper {
RejectInstallTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
void OnInstallEvent(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client,
mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
callback) override {
dispatched_events()->push_back(Event::Install);
@@ -184,15 +183,18 @@ class RecordableEmbeddedWorkerInstanceClient
protected:
void StartWorker(
const EmbeddedWorkerStartParams& params,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
mojom::ServiceWorkerInstalledScriptsInfoPtr scripts_info,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy)
override {
events_.push_back(Message::StartWorker);
EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StartWorker(
- params, std::move(request), std::move(scripts_info),
+ params, std::move(dispatcher_request), std::move(controller_request),
+ std::move(scripts_info), std::move(service_worker_host),
std::move(instance_host), std::move(provider_info),
std::move(content_settings_proxy));
}
@@ -409,19 +411,33 @@ TEST_F(ServiceWorkerContextTest, UnregisterMultiple) {
GURL("http://www.example.com/service_worker.js"),
blink::mojom::ServiceWorkerRegistrationOptions(origin1_p1), nullptr,
MakeRegisteredCallback(&called, &registration_id1));
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ called = false;
context()->RegisterServiceWorker(
GURL("http://www.example.com/service_worker2.js"),
blink::mojom::ServiceWorkerRegistrationOptions(origin1_p2), nullptr,
MakeRegisteredCallback(&called, &registration_id2));
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ called = false;
context()->RegisterServiceWorker(
GURL("http://www.example.com:8080/service_worker3.js"),
blink::mojom::ServiceWorkerRegistrationOptions(origin2_p1), nullptr,
MakeRegisteredCallback(&called, &registration_id3));
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ called = false;
context()->RegisterServiceWorker(
GURL("http://www.other.com/service_worker4.js"),
blink::mojom::ServiceWorkerRegistrationOptions(origin3_p1), nullptr,
MakeRegisteredCallback(&called, &registration_id4));
-
ASSERT_FALSE(called);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(called);
@@ -436,8 +452,8 @@ TEST_F(ServiceWorkerContextTest, UnregisterMultiple) {
registration_id4);
called = false;
- context()->UnregisterServiceWorkers(origin1_p1.GetOrigin(),
- MakeUnregisteredCallback(&called));
+ context()->DeleteForOrigin(origin1_p1.GetOrigin(),
+ MakeUnregisteredCallback(&called));
ASSERT_FALSE(called);
base::RunLoop().RunUntilIdle();
@@ -489,11 +505,11 @@ TEST_F(ServiceWorkerContextTest, UnregisterMultiple) {
EXPECT_EQ(origin3_p1, notifications_[3].pattern);
EXPECT_EQ(registration_id4, notifications_[3].registration_id);
EXPECT_EQ(REGISTRATION_DELETED, notifications_[4].type);
- EXPECT_EQ(origin1_p2, notifications_[4].pattern);
- EXPECT_EQ(registration_id2, notifications_[4].registration_id);
+ EXPECT_EQ(origin1_p1, notifications_[4].pattern);
+ EXPECT_EQ(registration_id1, notifications_[4].registration_id);
EXPECT_EQ(REGISTRATION_DELETED, notifications_[5].type);
- EXPECT_EQ(origin1_p1, notifications_[5].pattern);
- EXPECT_EQ(registration_id1, notifications_[5].registration_id);
+ EXPECT_EQ(origin1_p2, notifications_[5].pattern);
+ EXPECT_EQ(registration_id2, notifications_[5].registration_id);
}
// Make sure registering a new script shares an existing registration.
@@ -725,10 +741,9 @@ TEST_P(ServiceWorkerContextRecoveryTest, DeleteAndStartOver) {
true /* expect_active */));
content::RunAllTasksUntilIdle();
- // Next handle ids should be 1 (the next call should return 2) because
+ // Next handle id should be 1 (the next call should return 2) because
// registered worker should have taken ID 0.
EXPECT_EQ(1, context()->GetNewServiceWorkerHandleId());
- EXPECT_EQ(1, context()->GetNewRegistrationHandleId());
context()->ScheduleDeleteAndStartOver();
@@ -769,10 +784,9 @@ TEST_P(ServiceWorkerContextRecoveryTest, DeleteAndStartOver) {
true /* expect_active */));
content::RunAllTasksUntilIdle();
- // The new context should take over next handle ids. ID 2 should have been
+ // The new context should take over next handle id. ID 2 should have been
// taken by the running registration, so the following method calls return 3.
EXPECT_EQ(3, context()->GetNewServiceWorkerHandleId());
- EXPECT_EQ(3, context()->GetNewRegistrationHandleId());
ASSERT_EQ(3u, notifications_.size());
EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
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 8a03b13468b..e2210fade1c 100644
--- a/chromium/content/browser/service_worker/service_worker_context_watcher.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_watcher.cc
@@ -11,9 +11,9 @@
#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/common/service_worker/service_worker_types.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/console_message_level.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
#include "url/gurl.h"
@@ -82,13 +82,13 @@ void ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread(
StoreVersionInfo(version);
std::unique_ptr<std::vector<ServiceWorkerRegistrationInfo>> registrations =
- base::MakeUnique<std::vector<ServiceWorkerRegistrationInfo>>();
+ std::make_unique<std::vector<ServiceWorkerRegistrationInfo>>();
registrations->reserve(registration_info_map.size());
for (const auto& registration_id_info_pair : registration_info_map)
registrations->push_back(*registration_id_info_pair.second);
std::unique_ptr<std::vector<ServiceWorkerVersionInfo>> versions =
- base::MakeUnique<std::vector<ServiceWorkerVersionInfo>>();
+ std::make_unique<std::vector<ServiceWorkerVersionInfo>>();
versions->reserve(version_info_map_.size());
for (auto version_it = version_info_map_.begin();
@@ -130,7 +130,7 @@ void ServiceWorkerContextWatcher::StoreRegistrationInfo(
blink::mojom::kInvalidServiceWorkerRegistrationId)
return;
(*info_map)[registration_info.registration_id] =
- base::MakeUnique<ServiceWorkerRegistrationInfo>(registration_info);
+ std::make_unique<ServiceWorkerRegistrationInfo>(registration_info);
StoreVersionInfo(registration_info.active_version);
StoreVersionInfo(registration_info.waiting_version);
StoreVersionInfo(registration_info.installing_version);
@@ -139,10 +139,10 @@ void ServiceWorkerContextWatcher::StoreRegistrationInfo(
void ServiceWorkerContextWatcher::StoreVersionInfo(
const ServiceWorkerVersionInfo& version_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (version_info.version_id == kInvalidServiceWorkerVersionId)
+ if (version_info.version_id == blink::mojom::kInvalidServiceWorkerVersionId)
return;
version_info_map_[version_info.version_id] =
- base::MakeUnique<ServiceWorkerVersionInfo>(version_info);
+ std::make_unique<ServiceWorkerVersionInfo>(version_info);
}
void ServiceWorkerContextWatcher::SendRegistrationInfo(
@@ -151,7 +151,7 @@ void ServiceWorkerContextWatcher::SendRegistrationInfo(
ServiceWorkerRegistrationInfo::DeleteFlag delete_flag) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::unique_ptr<std::vector<ServiceWorkerRegistrationInfo>> registrations =
- base::MakeUnique<std::vector<ServiceWorkerRegistrationInfo>>();
+ std::make_unique<std::vector<ServiceWorkerRegistrationInfo>>();
ServiceWorkerRegistration* registration =
context_->GetLiveRegistration(registration_id);
if (registration) {
@@ -171,7 +171,7 @@ void ServiceWorkerContextWatcher::SendVersionInfo(
const ServiceWorkerVersionInfo& version_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::unique_ptr<std::vector<ServiceWorkerVersionInfo>> versions =
- base::MakeUnique<std::vector<ServiceWorkerVersionInfo>>();
+ std::make_unique<std::vector<ServiceWorkerVersionInfo>>();
versions->push_back(version_info);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
@@ -225,7 +225,7 @@ void ServiceWorkerContextWatcher::OnNewLiveVersion(
}
std::unique_ptr<ServiceWorkerVersionInfo> version =
- base::MakeUnique<ServiceWorkerVersionInfo>(version_info);
+ std::make_unique<ServiceWorkerVersionInfo>(version_info);
SendVersionInfo(*version);
if (!IsStoppedAndRedundant(*version))
version_info_map_[version_id] = std::move(version);
@@ -310,7 +310,7 @@ void ServiceWorkerContextWatcher::OnErrorReported(int64_t version_id,
BrowserThread::UI, FROM_HERE,
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerErrorReportedCallback, this,
- registration_id, version_id, base::MakeUnique<ErrorInfo>(info)));
+ registration_id, version_id, std::make_unique<ErrorInfo>(info)));
}
void ServiceWorkerContextWatcher::OnReportConsoleMessage(
@@ -331,7 +331,7 @@ void ServiceWorkerContextWatcher::OnReportConsoleMessage(
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerErrorReportedCallback, this,
registration_id, version_id,
- base::MakeUnique<ErrorInfo>(message.message, message.line_number, -1,
+ std::make_unique<ErrorInfo>(message.message, message.line_number, -1,
message.source_url)));
}
@@ -341,7 +341,7 @@ void ServiceWorkerContextWatcher::OnControlleeAdded(
int process_id,
int route_id,
const base::Callback<WebContents*(void)>& web_contents_getter,
- ServiceWorkerProviderType type) {
+ blink::mojom::ServiceWorkerProviderType type) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
auto it = version_info_map_.find(version_id);
if (it == version_info_map_.end())
diff --git a/chromium/content/browser/service_worker/service_worker_context_watcher.h b/chromium/content/browser/service_worker/service_worker_context_watcher.h
index 10847d4a1f5..3d3f008bfde 100644
--- a/chromium/content/browser/service_worker/service_worker_context_watcher.h
+++ b/chromium/content/browser/service_worker/service_worker_context_watcher.h
@@ -14,6 +14,7 @@
#include "content/browser/service_worker/service_worker_context_core_observer.h"
#include "content/browser/service_worker/service_worker_info.h"
#include "content/common/content_export.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
namespace content {
@@ -108,7 +109,7 @@ class CONTENT_EXPORT ServiceWorkerContextWatcher
int process_id,
int route_id,
const base::Callback<WebContents*(void)>& web_contents_getter,
- ServiceWorkerProviderType type) override;
+ blink::mojom::ServiceWorkerProviderType type) override;
void OnControlleeRemoved(int64_t version_id,
const std::string& uuid) override;
void OnRegistrationStored(int64_t registration_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 573911f9e6f..51aa2b3893b 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -43,10 +43,6 @@ typedef std::set<std::string> HeaderNameSet;
base::LazyInstance<HeaderNameSet>::DestructorAtExit g_excluded_header_name_set =
LAZY_INSTANCE_INITIALIZER;
-void RunSoon(const base::Closure& closure) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure);
-}
-
void WorkerStarted(const ServiceWorkerContextWrapper::StatusCallback& callback,
ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -369,9 +365,9 @@ void ServiceWorkerContextWrapper::DeleteForOrigin(const GURL& origin,
base::BindOnce(std::move(callback), false));
return;
}
- context()->UnregisterServiceWorkers(
- origin.GetOrigin(), base::Bind(&StatusCodeToBoolCallbackAdapter,
- base::Passed(std::move(callback))));
+ context()->DeleteForOrigin(
+ origin.GetOrigin(),
+ base::BindOnce(&StatusCodeToBoolCallbackAdapter, std::move(callback)));
}
void ServiceWorkerContextWrapper::CheckHasServiceWorker(
@@ -560,7 +556,9 @@ void ServiceWorkerContextWrapper::FindReadyRegistrationForPattern(
const FindRegistrationCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT, nullptr));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(callback, SERVICE_WORKER_ERROR_ABORT, nullptr));
return;
}
context_core_->storage()->FindRegistrationForPattern(
@@ -604,7 +602,9 @@ void ServiceWorkerContextWrapper::GetAllRegistrations(
const GetRegistrationsInfosCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT,
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(callback, SERVICE_WORKER_ERROR_ABORT,
std::vector<ServiceWorkerRegistrationInfo>()));
return;
}
@@ -617,8 +617,9 @@ void ServiceWorkerContextWrapper::GetRegistrationUserData(
const GetUserDataCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- RunSoon(base::Bind(callback, std::vector<std::string>(),
- SERVICE_WORKER_ERROR_ABORT));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(callback, std::vector<std::string>(),
+ SERVICE_WORKER_ERROR_ABORT));
return;
}
context_core_->storage()->GetUserData(registration_id, keys, callback);
@@ -630,14 +631,31 @@ void ServiceWorkerContextWrapper::GetRegistrationUserDataByKeyPrefix(
const GetUserDataCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- RunSoon(base::Bind(callback, std::vector<std::string>(),
- SERVICE_WORKER_ERROR_ABORT));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(callback, std::vector<std::string>(),
+ SERVICE_WORKER_ERROR_ABORT));
return;
}
context_core_->storage()->GetUserDataByKeyPrefix(registration_id, key_prefix,
callback);
}
+void ServiceWorkerContextWrapper::GetRegistrationUserKeysAndDataByKeyPrefix(
+ int64_t registration_id,
+ const std::string& key_prefix,
+ const GetUserKeysAndDataCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (!context_core_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(callback, base::flat_map<std::string, std::string>(),
+ SERVICE_WORKER_ERROR_ABORT));
+ return;
+ }
+ context_core_->storage()->GetUserKeysAndDataByKeyPrefix(registration_id,
+ key_prefix, callback);
+}
+
void ServiceWorkerContextWrapper::StoreRegistrationUserData(
int64_t registration_id,
const GURL& origin,
@@ -645,7 +663,8 @@ void ServiceWorkerContextWrapper::StoreRegistrationUserData(
const StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(callback, SERVICE_WORKER_ERROR_ABORT));
return;
}
context_core_->storage()->StoreUserData(registration_id, origin.GetOrigin(),
@@ -658,7 +677,8 @@ void ServiceWorkerContextWrapper::ClearRegistrationUserData(
const StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(callback, SERVICE_WORKER_ERROR_ABORT));
return;
}
context_core_->storage()->ClearUserData(registration_id, keys, callback);
@@ -670,7 +690,8 @@ void ServiceWorkerContextWrapper::ClearRegistrationUserDataByKeyPrefixes(
const StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(callback, SERVICE_WORKER_ERROR_ABORT));
return;
}
context_core_->storage()->ClearUserDataByKeyPrefixes(registration_id,
@@ -682,7 +703,9 @@ void ServiceWorkerContextWrapper::GetUserDataForAllRegistrations(
const GetUserDataForAllRegistrationsCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- RunSoon(base::Bind(callback, std::vector<std::pair<int64_t, std::string>>(),
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(callback, std::vector<std::pair<int64_t, std::string>>(),
SERVICE_WORKER_ERROR_ABORT));
return;
}
@@ -694,7 +717,9 @@ void ServiceWorkerContextWrapper::GetUserDataForAllRegistrationsByKeyPrefix(
const GetUserDataForAllRegistrationsCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- RunSoon(base::Bind(callback, std::vector<std::pair<int64_t, std::string>>(),
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(callback, std::vector<std::pair<int64_t, std::string>>(),
SERVICE_WORKER_ERROR_ABORT));
return;
}
@@ -777,14 +802,6 @@ void ServiceWorkerContextWrapper::RemoveObserver(
core_observer_list_->RemoveObserver(observer);
}
-bool ServiceWorkerContextWrapper::OriginHasForeignFetchRegistrations(
- const GURL& origin) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!context_core_)
- return false;
- return context_core_->storage()->OriginHasForeignFetchRegistrations(origin);
-}
-
ServiceWorkerContextWrapper::~ServiceWorkerContextWrapper() {
// Explicitly remove this object as an observer to avoid use-after-frees in
// tests where this object is not guaranteed to outlive the
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 c22f938843b..93bc750df57 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper.h
@@ -55,6 +55,8 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
using GetRegistrationsInfosCallback =
ServiceWorkerStorage::GetRegistrationsInfosCallback;
using GetUserDataCallback = ServiceWorkerStorage::GetUserDataCallback;
+ using GetUserKeysAndDataCallback =
+ ServiceWorkerStorage::GetUserKeysAndDataCallback;
using GetUserDataForAllRegistrationsCallback =
ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback;
@@ -215,6 +217,10 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
void GetRegistrationUserDataByKeyPrefix(int64_t registration_id,
const std::string& key_prefix,
const GetUserDataCallback& callback);
+ void GetRegistrationUserKeysAndDataByKeyPrefix(
+ int64_t registration_id,
+ const std::string& key_prefix,
+ const GetUserKeysAndDataCallback& callback);
void StoreRegistrationUserData(
int64_t registration_id,
const GURL& origin,
@@ -249,16 +255,12 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
bool is_incognito() const { return is_incognito_; }
- // Must be called from the IO thread.
- bool OriginHasForeignFetchRegistrations(const GURL& origin);
-
private:
friend class BackgroundSyncManagerTest;
friend class base::RefCountedThreadSafe<ServiceWorkerContextWrapper>;
friend class EmbeddedWorkerTestHelper;
friend class EmbeddedWorkerBrowserTest;
friend class FakeServiceWorkerContextWrapper;
- friend class ForeignFetchRequestHandler;
friend class ServiceWorkerDispatcherHost;
friend class ServiceWorkerInternalsUI;
friend class ServiceWorkerNavigationHandleCore;
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 4dc9742e856..162f9a1e4d1 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
@@ -81,10 +81,11 @@ ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
base::WeakPtr<ServiceWorkerContextCore> context,
base::WeakPtr<ServiceWorkerProviderHost> provider_host,
base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
+ network::mojom::FetchRequestMode request_mode,
+ network::mojom::FetchCredentialsMode credentials_mode,
FetchRedirectMode redirect_mode,
const std::string& integrity,
+ bool keepalive,
ResourceType resource_type,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
@@ -100,6 +101,7 @@ ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
credentials_mode_(credentials_mode),
redirect_mode_(redirect_mode),
integrity_(integrity),
+ keepalive_(keepalive),
request_context_type_(request_context_type),
frame_type_(frame_type),
body_(body),
@@ -131,7 +133,7 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
if (!context_ || !provider_host_) {
// We can't do anything other than to fall back to network.
- return NULL;
+ return nullptr;
}
// This may get called multiple times for original and redirect requests:
@@ -148,7 +150,7 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
// requests.
if (is_main_resource_load_)
use_network_ = false;
- return NULL;
+ return nullptr;
}
#if BUILDFLAG(ENABLE_OFFLINE_PAGES)
@@ -163,10 +165,10 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
new ServiceWorkerURLRequestJob(
request, network_delegate, provider_host_->client_uuid(),
blob_storage_context_, resource_context, request_mode_,
- credentials_mode_, redirect_mode_, integrity_, resource_type_,
- request_context_type_, frame_type_, body_,
+ credentials_mode_, redirect_mode_, integrity_, keepalive_,
+ resource_type_, request_context_type_, frame_type_, body_,
ServiceWorkerFetchType::FETCH, base::nullopt, this));
- url_job_ = base::MakeUnique<ServiceWorkerURLJobWrapper>(job->GetWeakPtr());
+ url_job_ = std::make_unique<ServiceWorkerURLJobWrapper>(job->GetWeakPtr());
resource_context_ = resource_context;
@@ -219,8 +221,8 @@ void ServiceWorkerControlleeRequestHandler::MaybeCreateLoader(
}
#endif // BUILDFLAG(ENABLE_OFFLINE_PAGES)
- url_job_ = base::MakeUnique<ServiceWorkerURLJobWrapper>(
- base::MakeUnique<ServiceWorkerURLLoaderJob>(
+ url_job_ = std::make_unique<ServiceWorkerURLJobWrapper>(
+ std::make_unique<ServiceWorkerURLLoaderJob>(
std::move(callback), this, resource_request,
base::WrapRefCounted(context_->loader_factory_getter()),
blob_storage_context_));
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 6877783a583..3b7febad4a9 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
@@ -21,6 +21,7 @@
#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "content/public/common/service_worker_modes.h"
+#include "services/network/public/interfaces/fetch_api.mojom.h"
#include "url/gurl.h"
namespace net {
@@ -46,10 +47,11 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
base::WeakPtr<ServiceWorkerContextCore> context,
base::WeakPtr<ServiceWorkerProviderHost> provider_host,
base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
+ network::mojom::FetchRequestMode request_mode,
+ network::mojom::FetchCredentialsMode credentials_mode,
FetchRedirectMode redirect_mode,
const std::string& integrity,
+ bool keepalive,
ResourceType resource_type,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
@@ -65,9 +67,9 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
net::NetworkDelegate* network_delegate,
ResourceContext* resource_context) override;
- // Used only for IsServicificationEnabled (PlzNavigate and
- // --enable-network-service) cases.
- // This will replace MaybeCreateJob() once NetworkService is enabled.
+ // S13nServiceWorker:
+ // MaybeCreateLoader replaces MaybeCreateJob() when S13nServiceWorker is
+ // enabled.
// This could get called multiple times during the lifetime in redirect
// cases. (In fallback-to-network cases we basically forward the request
// to the request to the next request handler)
@@ -123,10 +125,11 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
const bool is_main_resource_load_;
const bool is_main_frame_load_;
std::unique_ptr<ServiceWorkerURLJobWrapper> url_job_;
- FetchRequestMode request_mode_;
- FetchCredentialsMode credentials_mode_;
+ network::mojom::FetchRequestMode request_mode_;
+ network::mojom::FetchCredentialsMode credentials_mode_;
FetchRedirectMode redirect_mode_;
std::string integrity_;
+ const bool keepalive_;
RequestContextType request_context_type_;
RequestContextFrameType frame_type_;
scoped_refptr<ResourceRequestBody> body_;
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 2bd21965b46..0ac643641bd 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
@@ -53,7 +53,8 @@ class ServiceWorkerControlleeRequestHandlerTest : public testing::Test {
ServiceWorkerControlleeRequestHandlerTest* test,
const GURL& url,
ResourceType type,
- FetchRequestMode fetch_type = FETCH_REQUEST_MODE_NO_CORS)
+ network::mojom::FetchRequestMode fetch_type =
+ network::mojom::FetchRequestMode::kNoCORS)
: test_(test),
request_(test->url_request_context_.CreateRequest(
url,
@@ -65,9 +66,10 @@ class ServiceWorkerControlleeRequestHandlerTest : public testing::Test {
test->provider_host_,
base::WeakPtr<storage::BlobStorageContext>(),
fetch_type,
- FETCH_CREDENTIALS_MODE_OMIT,
+ network::mojom::FetchCredentialsMode::kOmit,
FetchRedirectMode::FOLLOW_MODE,
std::string() /* integrity */,
+ false /* keepalive */,
type,
REQUEST_CONTEXT_TYPE_HYPERLINK,
REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
@@ -110,9 +112,15 @@ class ServiceWorkerControlleeRequestHandlerTest : public testing::Test {
version_ = new ServiceWorkerVersion(
registration_.get(), script_url_, 1L, context()->AsWeakPtr());
+ context()->storage()->LazyInitializeForTest(
+ base::BindOnce(&base::DoNothing));
+ base::RunLoop().RunUntilIdle();
+
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
- records.push_back(
- ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100));
+ records.push_back(WriteToDiskCacheSync(
+ context()->storage(), version_->script_url(),
+ context()->storage()->NewResourceId(), {} /* headers */, "I'm a body",
+ "I'm a meta data"));
version_->script_cache_map()->SetResources(records);
version_->SetMainScriptHttpResponseInfo(
EmbeddedWorkerTestHelper::CreateHttpResponseInfo());
@@ -126,15 +134,11 @@ class ServiceWorkerControlleeRequestHandlerTest : public testing::Test {
&remote_endpoints_.back());
provider_host_ = host->AsWeakPtr();
context()->AddProviderHost(std::move(host));
-
- context()->storage()->LazyInitializeForTest(
- base::BindOnce(&base::DoNothing));
- base::RunLoop().RunUntilIdle();
}
void TearDown() override {
- version_ = NULL;
- registration_ = NULL;
+ version_ = nullptr;
+ registration_ = nullptr;
helper_.reset();
}
@@ -273,8 +277,8 @@ TEST_F(ServiceWorkerControlleeRequestHandlerTest, DeletedProviderHost) {
version_.get(),
base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
base::RunLoop().RunUntilIdle();
- version_ = NULL;
- registration_ = NULL;
+ version_ = nullptr;
+ registration_ = nullptr;
// Conduct a main resource load.
ServiceWorkerRequestTestResources test_resources(
@@ -371,7 +375,7 @@ TEST_F(ServiceWorkerControlleeRequestHandlerTest, FallbackWithNoFetchHandler) {
// CORS request should be returned to renderer for CORS checking.
ServiceWorkerRequestTestResources sub_test_resources_cors(
this, GURL("https://host/scope/doc/subresource"), RESOURCE_TYPE_SCRIPT,
- FETCH_REQUEST_MODE_CORS);
+ network::mojom::FetchRequestMode::kCORS);
ServiceWorkerURLRequestJob* sub_cors_job =
sub_test_resources_cors.MaybeCreateJob();
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 b26f614e036..3f652293b8d 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
@@ -34,10 +34,11 @@ class MockServiceWorkerURLRequestJob : public ServiceWorkerURLRequestJob {
"",
nullptr,
nullptr,
- FETCH_REQUEST_MODE_NO_CORS,
- FETCH_CREDENTIALS_MODE_OMIT,
+ network::mojom::FetchRequestMode::kNoCORS,
+ network::mojom::FetchCredentialsMode::kOmit,
FetchRedirectMode::FOLLOW_MODE,
std::string() /* integrity */,
+ false /* keepalive */,
RESOURCE_TYPE_MAIN_FRAME,
REQUEST_CONTEXT_TYPE_HYPERLINK,
REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
@@ -77,9 +78,9 @@ class ServiceWorkerDataPipeReaderTest
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
- helper_ = base::MakeUnique<EmbeddedWorkerTestHelper>(base::FilePath());
+ helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath());
mock_url_request_job_ =
- base::MakeUnique<MockServiceWorkerURLRequestJob>(this);
+ std::make_unique<MockServiceWorkerURLRequestJob>(this);
blink::mojom::ServiceWorkerRegistrationOptions options(
GURL("https://example.com/"));
registration_ = new ServiceWorkerRegistration(
@@ -102,7 +103,7 @@ class ServiceWorkerDataPipeReaderTest
blink::mojom::ServiceWorkerStreamHandle::New();
stream_handle->stream = std::move(data_pipe->consumer_handle);
stream_handle->callback_request = mojo::MakeRequest(stream_callback);
- return base::MakeUnique<ServiceWorkerDataPipeReader>(
+ return std::make_unique<ServiceWorkerDataPipeReader>(
mock_url_request_job_.get(), version_, std::move(stream_handle));
}
diff --git a/chromium/content/browser/service_worker/service_worker_database.cc b/chromium/content/browser/service_worker/service_worker_database.cc
index 6ae138490b6..5fe29835d1d 100644
--- a/chromium/content/browser/service_worker/service_worker_database.cc
+++ b/chromium/content/browser/service_worker/service_worker_database.cc
@@ -4,8 +4,6 @@
#include "content/browser/service_worker/service_worker_database.h"
-#include <utility>
-
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/location.h"
@@ -19,6 +17,7 @@
#include "content/browser/service_worker/service_worker_database.pb.h"
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/leveldb_chrome.h"
@@ -77,30 +76,30 @@
// key: "REGID_TO_ORIGIN:" + <int64_t 'registration_id'>
// value: <GURL 'origin'>
//
-// OBSOLETE: http://crbug.com/539713
+// OBSOLETE: https://crbug.com/539713
// key: "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED"
// value: <empty>
// - This entry represents that the diskcache uses the Simple backend and
// does not have to do diskcache migration (http://crbug.com/487482).
//
-// OBSOLETE: http://crbug.com/539713
+// OBSOLETE: https://crbug.com/539713
// key: "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED"
// value: <empty>
// - This entry represents that the old BlockFile diskcache was deleted
// after diskcache migration (http://crbug.com/487482).
//
+// OBSOLETE: https://crbug.com/788604
// key: "INITDATA_FOREIGN_FETCH_ORIGIN:" + <GURL 'origin'>
// value: <empty>
namespace content {
-namespace {
+namespace service_worker_internals {
const char kDatabaseVersionKey[] = "INITDATA_DB_VERSION";
const char kNextRegIdKey[] = "INITDATA_NEXT_REGISTRATION_ID";
const char kNextResIdKey[] = "INITDATA_NEXT_RESOURCE_ID";
const char kNextVerIdKey[] = "INITDATA_NEXT_VERSION_ID";
const char kUniqueOriginKey[] = "INITDATA_UNIQUE_ORIGIN:";
-const char kForeignFetchOriginKey[] = "INITDATA_FOREIGN_FETCH_ORIGIN:";
const char kRegKeyPrefix[] = "REG:";
const char kRegUserDataKeyPrefix[] = "REG_USER_DATA:";
@@ -114,6 +113,10 @@ const char kPurgeableResIdKeyPrefix[] = "PRES:";
const int64_t kCurrentSchemaVersion = 2;
+} // namespace service_worker_internals
+
+namespace {
+
class ServiceWorkerEnv : public leveldb_env::ChromiumEnv {
public:
ServiceWorkerEnv() : ChromiumEnv("LevelDBEnv.ServiceWorker") {}
@@ -133,8 +136,9 @@ bool RemovePrefix(const std::string& str,
}
std::string CreateRegistrationKeyPrefix(const GURL& origin) {
- return base::StringPrintf("%s%s%c", kRegKeyPrefix,
- origin.GetOrigin().spec().c_str(), kKeySeparator);
+ return base::StringPrintf("%s%s%c", service_worker_internals::kRegKeyPrefix,
+ origin.GetOrigin().spec().c_str(),
+ service_worker_internals::kKeySeparator);
}
std::string CreateRegistrationKey(int64_t registration_id, const GURL& origin) {
@@ -143,10 +147,9 @@ std::string CreateRegistrationKey(int64_t registration_id, const GURL& origin) {
}
std::string CreateResourceRecordKeyPrefix(int64_t version_id) {
- return base::StringPrintf("%s%s%c",
- kResKeyPrefix,
+ return base::StringPrintf("%s%s%c", service_worker_internals::kResKeyPrefix,
base::Int64ToString(version_id).c_str(),
- kKeySeparator);
+ service_worker_internals::kKeySeparator);
}
std::string CreateResourceRecordKey(int64_t version_id, int64_t resource_id) {
@@ -155,12 +158,7 @@ std::string CreateResourceRecordKey(int64_t version_id, int64_t resource_id) {
}
std::string CreateUniqueOriginKey(const GURL& origin) {
- return base::StringPrintf("%s%s", kUniqueOriginKey,
- origin.GetOrigin().spec().c_str());
-}
-
-std::string CreateForeignFetchOriginKey(const GURL& origin) {
- return base::StringPrintf("%s%s", kForeignFetchOriginKey,
+ return base::StringPrintf("%s%s", service_worker_internals::kUniqueOriginKey,
origin.GetOrigin().spec().c_str());
}
@@ -171,9 +169,9 @@ std::string CreateResourceIdKey(const char* key_prefix, int64_t resource_id) {
std::string CreateUserDataKeyPrefix(int64_t registration_id) {
return base::StringPrintf("%s%s%c",
- kRegUserDataKeyPrefix,
+ service_worker_internals::kRegUserDataKeyPrefix,
base::Int64ToString(registration_id).c_str(),
- kKeySeparator);
+ service_worker_internals::kKeySeparator);
}
std::string CreateUserDataKey(int64_t registration_id,
@@ -182,8 +180,9 @@ std::string CreateUserDataKey(int64_t registration_id,
}
std::string CreateHasUserDataKeyPrefix(const std::string& user_data_name) {
- return base::StringPrintf("%s%s%c", kRegHasUserDataKeyPrefix,
- user_data_name.c_str(), kKeySeparator);
+ return base::StringPrintf(
+ "%s%s%c", service_worker_internals::kRegHasUserDataKeyPrefix,
+ user_data_name.c_str(), service_worker_internals::kKeySeparator);
}
std::string CreateHasUserDataKey(int64_t registration_id,
@@ -193,7 +192,8 @@ std::string CreateHasUserDataKey(int64_t registration_id,
}
std::string CreateRegistrationIdToOriginKey(int64_t registration_id) {
- return base::StringPrintf("%s%s", kRegIdToOriginKeyPrefix,
+ return base::StringPrintf("%s%s",
+ service_worker_internals::kRegIdToOriginKeyPrefix,
base::Int64ToString(registration_id).c_str());
}
@@ -206,13 +206,10 @@ void PutUniqueOriginToBatch(const GURL& origin,
void PutPurgeableResourceIdToBatch(int64_t resource_id,
leveldb::WriteBatch* batch) {
// Value should be empty.
- batch->Put(CreateResourceIdKey(kPurgeableResIdKeyPrefix, resource_id), "");
-}
-
-void PutForeignFetchOriginToBatch(const GURL& origin,
- leveldb::WriteBatch* batch) {
- // Value should be empty.
- batch->Put(CreateForeignFetchOriginKey(origin), "");
+ batch->Put(
+ CreateResourceIdKey(service_worker_internals::kPurgeableResIdKeyPrefix,
+ resource_id),
+ "");
}
ServiceWorkerDatabase::Status ParseId(const std::string& serialized,
@@ -225,7 +222,7 @@ ServiceWorkerDatabase::Status ParseId(const std::string& serialized,
return ServiceWorkerDatabase::STATUS_OK;
}
-ServiceWorkerDatabase::Status LevelDBStatusToStatus(
+ServiceWorkerDatabase::Status LevelDBStatusToServiceWorkerDBStatus(
const leveldb::Status& status) {
if (status.ok())
return ServiceWorkerDatabase::STATUS_OK;
@@ -276,7 +273,7 @@ const char* ServiceWorkerDatabase::StatusToString(
ServiceWorkerDatabase::RegistrationData::RegistrationData()
: registration_id(blink::mojom::kInvalidServiceWorkerRegistrationId),
- version_id(kInvalidServiceWorkerVersionId),
+ version_id(blink::mojom::kInvalidServiceWorkerVersionId),
is_active(false),
has_fetch_handler(false),
resources_total_size_bytes(0) {}
@@ -320,13 +317,16 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetNextAvailableIds(
if (status != STATUS_OK)
return status;
- status = ReadNextAvailableId(kNextRegIdKey, &next_avail_registration_id_);
+ status = ReadNextAvailableId(service_worker_internals::kNextRegIdKey,
+ &next_avail_registration_id_);
if (status != STATUS_OK)
return status;
- status = ReadNextAvailableId(kNextVerIdKey, &next_avail_version_id_);
+ status = ReadNextAvailableId(service_worker_internals::kNextVerIdKey,
+ &next_avail_version_id_);
if (status != STATUS_OK)
return status;
- status = ReadNextAvailableId(kNextResIdKey, &next_avail_resource_id_);
+ status = ReadNextAvailableId(service_worker_internals::kNextResIdKey,
+ &next_avail_resource_id_);
if (status != STATUS_OK)
return status;
@@ -350,56 +350,17 @@ ServiceWorkerDatabase::GetOriginsWithRegistrations(std::set<GURL>* origins) {
{
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
- for (itr->Seek(kUniqueOriginKey); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
+ for (itr->Seek(service_worker_internals::kUniqueOriginKey); itr->Valid();
+ itr->Next()) {
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK) {
origins->clear();
break;
}
std::string origin_str;
- if (!RemovePrefix(itr->key().ToString(), kUniqueOriginKey, &origin_str))
- break;
-
- GURL origin(origin_str);
- if (!origin.is_valid()) {
- status = STATUS_ERROR_CORRUPTED;
- origins->clear();
- break;
- }
-
- origins->insert(origin);
- }
- }
-
- HandleReadResult(FROM_HERE, status);
- return status;
-}
-
-ServiceWorkerDatabase::Status
-ServiceWorkerDatabase::GetOriginsWithForeignFetchRegistrations(
- std::set<GURL>* origins) {
- DCHECK(sequence_checker_.CalledOnValidSequence());
- DCHECK(origins->empty());
-
- Status status = LazyOpen(false);
- if (IsNewOrNonexistentDatabase(status))
- return STATUS_OK;
- if (status != STATUS_OK)
- return status;
-
- {
- std::unique_ptr<leveldb::Iterator> itr(
- db_->NewIterator(leveldb::ReadOptions()));
- for (itr->Seek(kForeignFetchOriginKey); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
- if (status != STATUS_OK) {
- origins->clear();
- break;
- }
-
- std::string origin_str;
- if (!RemovePrefix(itr->key().ToString(), kForeignFetchOriginKey,
+ if (!RemovePrefix(itr->key().ToString(),
+ service_worker_internals::kUniqueOriginKey,
&origin_str))
break;
@@ -436,7 +397,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetRegistrationsForOrigin(
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK) {
registrations->clear();
if (opt_resources_list)
@@ -444,7 +405,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetRegistrationsForOrigin(
break;
}
- if (!RemovePrefix(itr->key().ToString(), prefix, NULL))
+ if (!RemovePrefix(itr->key().ToString(), prefix, nullptr))
break;
RegistrationData registration;
@@ -488,14 +449,16 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetAllRegistrations(
{
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
- for (itr->Seek(kRegKeyPrefix); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
+ for (itr->Seek(service_worker_internals::kRegKeyPrefix); itr->Valid();
+ itr->Next()) {
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK) {
registrations->clear();
break;
}
- if (!RemovePrefix(itr->key().ToString(), kRegKeyPrefix, NULL))
+ if (!RemovePrefix(itr->key().ToString(),
+ service_worker_internals::kRegKeyPrefix, nullptr))
break;
RegistrationData registration;
@@ -557,7 +520,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadRegistrationOrigin(
return status;
std::string value;
- status = LevelDBStatusToStatus(
+ status = LevelDBStatusToServiceWorkerDBStatus(
db_->Get(leveldb::ReadOptions(),
CreateRegistrationIdToOriginKey(registration_id), &value));
if (status != STATUS_OK) {
@@ -587,7 +550,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
DCHECK(old_registration);
DCHECK(!resources.empty());
Status status = LazyOpen(true);
- old_registration->version_id = kInvalidServiceWorkerVersionId;
+ old_registration->version_id = blink::mojom::kInvalidServiceWorkerVersionId;
if (status != STATUS_OK)
return status;
@@ -597,9 +560,6 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch);
- if (!registration.foreign_fetch_scopes.empty())
- PutForeignFetchOriginToBatch(registration.scope.GetOrigin(), &batch);
-
DCHECK_EQ(AccumulateResourceSizeInBytes(resources),
registration.resources_total_size_bytes)
<< "The total size in the registration must match the cumulative "
@@ -625,10 +585,11 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
// Delete a resource from the uncommitted list.
batch.Delete(CreateResourceIdKey(
- kUncommittedResIdKeyPrefix, itr->resource_id));
+ service_worker_internals::kUncommittedResIdKeyPrefix,
+ itr->resource_id));
// Delete from the purgeable list in case this version was once deleted.
- batch.Delete(
- CreateResourceIdKey(kPurgeableResIdKeyPrefix, itr->resource_id));
+ batch.Delete(CreateResourceIdKey(
+ service_worker_internals::kPurgeableResIdKeyPrefix, itr->resource_id));
}
// Retrieve a previous version to sweep purgeable resources.
@@ -652,31 +613,6 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
DCHECK(base::STLSetIntersection<std::set<int64_t>>(pushed_resources,
deleted_resources)
.empty());
-
- // If old registration had foreign fetch scopes, but new registration
- // doesn't, the origin might have to be removed from the list of origins
- // with foreign fetch scopes.
- // TODO(mek): Like the similar check in DeleteRegistration, ideally this
- // could be done more efficiently.
- if (!old_registration->foreign_fetch_scopes.empty() &&
- registration.foreign_fetch_scopes.empty()) {
- std::vector<RegistrationData> registrations;
- status = GetRegistrationsForOrigin(registration.scope.GetOrigin(),
- &registrations, nullptr);
- if (status != STATUS_OK)
- return status;
- bool remaining_ff_scopes = false;
- for (const auto& existing_reg : registrations) {
- if (existing_reg.registration_id != registration.registration_id &&
- !existing_reg.foreign_fetch_scopes.empty()) {
- remaining_ff_scopes = true;
- break;
- }
- }
- if (!remaining_ff_scopes)
- batch.Delete(
- CreateForeignFetchOriginKey(registration.scope.GetOrigin()));
- }
}
return WriteBatch(&batch);
@@ -788,7 +724,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteRegistration(
std::vector<int64_t>* newly_purgeable_resources) {
DCHECK(sequence_checker_.CalledOnValidSequence());
DCHECK(deleted_version);
- deleted_version->version_id = kInvalidServiceWorkerVersionId;
+ deleted_version->version_id = blink::mojom::kInvalidServiceWorkerVersionId;
Status status = LazyOpen(false);
if (IsNewOrNonexistentDatabase(status))
return STATUS_OK;
@@ -812,19 +748,6 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteRegistration(
batch.Delete(CreateUniqueOriginKey(origin));
}
- // Remove |origin| from foreign fetch origins if a registration specified by
- // |registration_id| is the only one with foreign fetch scopes for |origin|.
- bool remaining_ff_scopes = false;
- for (const auto& registration : registrations) {
- if (registration.registration_id != registration_id &&
- !registration.foreign_fetch_scopes.empty()) {
- remaining_ff_scopes = true;
- break;
- }
- }
- if (!remaining_ff_scopes)
- batch.Delete(CreateForeignFetchOriginKey(origin));
-
// Delete a registration specified by |registration_id|.
batch.Delete(CreateRegistrationKey(registration_id, origin));
batch.Delete(CreateRegistrationIdToOriginKey(registration_id));
@@ -867,7 +790,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadUserData(
for (size_t i = 0; i < user_data_names.size(); i++) {
const std::string key =
CreateUserDataKey(registration_id, user_data_names[i]);
- status = LevelDBStatusToStatus(
+ status = LevelDBStatusToServiceWorkerDBStatus(
db_->Get(leveldb::ReadOptions(), key, &(*user_data_values)[i]));
if (status != STATUS_OK) {
user_data_values->clear();
@@ -899,7 +822,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadUserDataByKeyPrefix(
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK) {
user_data_values->clear();
break;
@@ -909,7 +832,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadUserDataByKeyPrefix(
break;
std::string user_data_value;
- status = LevelDBStatusToStatus(
+ status = LevelDBStatusToServiceWorkerDBStatus(
db_->Get(leveldb::ReadOptions(), itr->key(), &user_data_value));
if (status != STATUS_OK) {
user_data_values->clear();
@@ -924,6 +847,57 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadUserDataByKeyPrefix(
return status;
}
+ServiceWorkerDatabase::Status
+ServiceWorkerDatabase::ReadUserKeysAndDataByKeyPrefix(
+ int64_t registration_id,
+ const std::string& user_data_name_prefix,
+ base::flat_map<std::string, std::string>* user_data_map) {
+ DCHECK(sequence_checker_.CalledOnValidSequence());
+ DCHECK_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, registration_id);
+ DCHECK(user_data_map);
+
+ Status status = LazyOpen(false);
+ if (IsNewOrNonexistentDatabase(status))
+ return STATUS_ERROR_NOT_FOUND;
+ if (status != STATUS_OK)
+ return status;
+
+ std::string prefix =
+ CreateUserDataKey(registration_id, user_data_name_prefix);
+ {
+ std::unique_ptr<leveldb::Iterator> itr(
+ db_->NewIterator(leveldb::ReadOptions()));
+ for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
+ if (status != STATUS_OK) {
+ user_data_map->clear();
+ break;
+ }
+
+ if (!itr->key().starts_with(prefix))
+ break;
+
+ std::string user_data_value;
+ status = LevelDBStatusToServiceWorkerDBStatus(
+ db_->Get(leveldb::ReadOptions(), itr->key(), &user_data_value));
+ if (status != STATUS_OK) {
+ user_data_map->clear();
+ break;
+ }
+
+ leveldb::Slice s = itr->key();
+ s.remove_prefix(prefix.size());
+ // Always insert at the end of the map as they're retrieved presorted from
+ // the database.
+ user_data_map->insert(user_data_map->end(),
+ {s.ToString(), user_data_value});
+ }
+ }
+
+ HandleReadResult(FROM_HERE, status);
+ return status;
+}
+
ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteUserData(
int64_t registration_id,
const GURL& origin,
@@ -1003,7 +977,7 @@ ServiceWorkerDatabase::DeleteUserDataByKeyPrefixes(
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(key_prefix); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK)
return status;
@@ -1047,7 +1021,7 @@ ServiceWorkerDatabase::ReadUserDataForAllRegistrations(
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(key_prefix); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK) {
user_data->clear();
break;
@@ -1067,7 +1041,7 @@ ServiceWorkerDatabase::ReadUserDataForAllRegistrations(
}
std::string value;
- status = LevelDBStatusToStatus(
+ status = LevelDBStatusToServiceWorkerDBStatus(
db_->Get(leveldb::ReadOptions(),
CreateUserDataKey(registration_id, user_data_name), &value));
if (status != STATUS_OK) {
@@ -1095,12 +1069,13 @@ ServiceWorkerDatabase::ReadUserDataForAllRegistrationsByKeyPrefix(
if (status != STATUS_OK)
return status;
- std::string key_prefix = kRegHasUserDataKeyPrefix + user_data_name_prefix;
+ std::string key_prefix = service_worker_internals::kRegHasUserDataKeyPrefix +
+ user_data_name_prefix;
{
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(key_prefix); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK) {
user_data->clear();
break;
@@ -1110,13 +1085,15 @@ ServiceWorkerDatabase::ReadUserDataForAllRegistrationsByKeyPrefix(
break;
std::string user_data_name_with_id;
- if (!RemovePrefix(itr->key().ToString(), kRegHasUserDataKeyPrefix,
+ if (!RemovePrefix(itr->key().ToString(),
+ service_worker_internals::kRegHasUserDataKeyPrefix,
&user_data_name_with_id)) {
break;
}
std::vector<std::string> parts = base::SplitString(
- user_data_name_with_id, base::StringPrintf("%c", kKeySeparator),
+ user_data_name_with_id,
+ base::StringPrintf("%c", service_worker_internals::kKeySeparator),
base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
if (parts.size() != 2) {
status = STATUS_ERROR_CORRUPTED;
@@ -1132,7 +1109,7 @@ ServiceWorkerDatabase::ReadUserDataForAllRegistrationsByKeyPrefix(
}
std::string value;
- status = LevelDBStatusToStatus(
+ status = LevelDBStatusToServiceWorkerDBStatus(
db_->Get(leveldb::ReadOptions(),
CreateUserDataKey(registration_id, parts[0]), &value));
if (status != STATUS_OK) {
@@ -1149,15 +1126,16 @@ ServiceWorkerDatabase::ReadUserDataForAllRegistrationsByKeyPrefix(
ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetUncommittedResourceIds(
std::set<int64_t>* ids) {
- return ReadResourceIds(kUncommittedResIdKeyPrefix, ids);
+ return ReadResourceIds(service_worker_internals::kUncommittedResIdKeyPrefix,
+ ids);
}
ServiceWorkerDatabase::Status
ServiceWorkerDatabase::WriteUncommittedResourceIds(
const std::set<int64_t>& ids) {
leveldb::WriteBatch batch;
- Status status =
- WriteResourceIdsInBatch(kUncommittedResIdKeyPrefix, ids, &batch);
+ Status status = WriteResourceIdsInBatch(
+ service_worker_internals::kUncommittedResIdKeyPrefix, ids, &batch);
if (status != STATUS_OK)
return status;
return WriteBatch(&batch);
@@ -1165,14 +1143,15 @@ ServiceWorkerDatabase::WriteUncommittedResourceIds(
ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetPurgeableResourceIds(
std::set<int64_t>* ids) {
- return ReadResourceIds(kPurgeableResIdKeyPrefix, ids);
+ return ReadResourceIds(service_worker_internals::kPurgeableResIdKeyPrefix,
+ ids);
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ClearPurgeableResourceIds(
const std::set<int64_t>& ids) {
leveldb::WriteBatch batch;
- Status status =
- DeleteResourceIdsInBatch(kPurgeableResIdKeyPrefix, ids, &batch);
+ Status status = DeleteResourceIdsInBatch(
+ service_worker_internals::kPurgeableResIdKeyPrefix, ids, &batch);
if (status != STATUS_OK)
return status;
return WriteBatch(&batch);
@@ -1183,10 +1162,11 @@ ServiceWorkerDatabase::PurgeUncommittedResourceIds(
const std::set<int64_t>& ids) {
leveldb::WriteBatch batch;
Status status = DeleteResourceIdsInBatch(
- kUncommittedResIdKeyPrefix, ids, &batch);
+ service_worker_internals::kUncommittedResIdKeyPrefix, ids, &batch);
if (status != STATUS_OK)
return status;
- status = WriteResourceIdsInBatch(kPurgeableResIdKeyPrefix, ids, &batch);
+ status = WriteResourceIdsInBatch(
+ service_worker_internals::kPurgeableResIdKeyPrefix, ids, &batch);
if (status != STATUS_OK)
return status;
return WriteBatch(&batch);
@@ -1210,9 +1190,6 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteAllDataForOrigins(
// Delete from the unique origin list.
batch.Delete(CreateUniqueOriginKey(origin));
- // Delete from the foreign fetch origin list.
- batch.Delete(CreateForeignFetchOriginKey(origin));
-
std::vector<RegistrationData> registrations;
status = GetRegistrationsForOrigin(origin, &registrations, nullptr);
if (status != STATUS_OK)
@@ -1283,7 +1260,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::LazyOpen(
options.env = g_service_worker_env.Pointer();
}
- Status status = LevelDBStatusToStatus(
+ Status status = LevelDBStatusToServiceWorkerDBStatus(
leveldb_env::OpenDB(options, path_.AsUTF8Unsafe(), &db_));
HandleOpenResult(FROM_HERE, status);
if (status != STATUS_OK) {
@@ -1308,7 +1285,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::LazyOpen(
Disable(FROM_HERE, status);
return status;
case 2:
- DCHECK_EQ(db_version, kCurrentSchemaVersion);
+ DCHECK_EQ(db_version, service_worker_internals::kCurrentSchemaVersion);
state_ = INITIALIZED;
return STATUS_OK;
default:
@@ -1334,7 +1311,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadNextAvailableId(
DCHECK(next_avail_id);
std::string value;
- Status status = LevelDBStatusToStatus(
+ Status status = LevelDBStatusToServiceWorkerDBStatus(
db_->Get(leveldb::ReadOptions(), id_key, &value));
if (status == STATUS_ERROR_NOT_FOUND) {
// Nobody has gotten the next resource id for |id_key|.
@@ -1359,7 +1336,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadRegistrationData(
const std::string key = CreateRegistrationKey(registration_id, origin);
std::string value;
- Status status = LevelDBStatusToStatus(
+ Status status = LevelDBStatusToServiceWorkerDBStatus(
db_->Get(leveldb::ReadOptions(), key, &value));
if (status != STATUS_OK) {
HandleReadResult(
@@ -1411,26 +1388,6 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ParseRegistrationData(
out->last_update_check =
base::Time::FromInternalValue(data.last_update_check_time());
out->resources_total_size_bytes = data.resources_total_size_bytes();
- for (int i = 0; i < data.foreign_fetch_scope_size(); ++i) {
- GURL sub_scope_url(data.foreign_fetch_scope(i));
- if (!sub_scope_url.is_valid() ||
- !ServiceWorkerUtils::ScopeMatches(scope_url, sub_scope_url)) {
- DLOG(ERROR) << "Foreign fetch scope '" << data.foreign_fetch_scope(i)
- << "' is not valid or does not match Scope URL '" << scope_url
- << "'.";
- return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
- }
- out->foreign_fetch_scopes.push_back(sub_scope_url);
- }
- for (int i = 0; i < data.foreign_fetch_origin_size(); ++i) {
- url::Origin parsed_origin(GURL(data.foreign_fetch_origin(i)));
- if (parsed_origin.unique()) {
- DLOG(ERROR) << "Foreign fetch origin '" << data.foreign_fetch_origin(i)
- << "' is not valid.";
- return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
- }
- out->foreign_fetch_origins.push_back(parsed_origin);
- }
if (data.has_origin_trial_tokens()) {
const ServiceWorkerOriginTrialInfo& info = data.origin_trial_tokens();
blink::TrialTokenValidator::FeatureToTokensMap origin_trial_tokens;
@@ -1475,15 +1432,6 @@ void ServiceWorkerDatabase::WriteRegistrationDataInBatch(
data.set_last_update_check_time(
registration.last_update_check.ToInternalValue());
data.set_resources_total_size_bytes(registration.resources_total_size_bytes);
- for (const GURL& url : registration.foreign_fetch_scopes) {
- DCHECK(ServiceWorkerUtils::ScopeMatches(registration.scope, url))
- << "Foreign fetch scope '" << url
- << "' does not match service worker scope '" << registration.scope
- << "'.";
- data.add_foreign_fetch_scope(url.spec());
- }
- for (const url::Origin& origin : registration.foreign_fetch_origins)
- data.add_foreign_fetch_origin(origin.Serialize());
if (registration.origin_trial_tokens) {
ServiceWorkerOriginTrialInfo* info = data.mutable_origin_trial_tokens();
for (const auto& feature : *registration.origin_trial_tokens) {
@@ -1521,13 +1469,13 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceRecords(
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
- Status status = LevelDBStatusToStatus(itr->status());
+ Status status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK) {
resources->clear();
break;
}
- if (!RemovePrefix(itr->key().ToString(), prefix, NULL))
+ if (!RemovePrefix(itr->key().ToString(), prefix, nullptr))
break;
ResourceRecord resource;
@@ -1622,7 +1570,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceRecords(
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK)
break;
@@ -1667,7 +1615,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceIds(
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(id_key_prefix); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK) {
ids->clear();
break;
@@ -1746,7 +1694,7 @@ ServiceWorkerDatabase::DeleteUserDataForRegistration(
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
- status = LevelDBStatusToStatus(itr->status());
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != STATUS_OK)
break;
@@ -1766,8 +1714,9 @@ ServiceWorkerDatabase::DeleteUserDataForRegistration(
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadDatabaseVersion(
int64_t* db_version) {
std::string value;
- Status status = LevelDBStatusToStatus(
- db_->Get(leveldb::ReadOptions(), kDatabaseVersionKey, &value));
+ Status status = LevelDBStatusToServiceWorkerDBStatus(
+ db_->Get(leveldb::ReadOptions(),
+ service_worker_internals::kDatabaseVersionKey, &value));
if (status == STATUS_ERROR_NOT_FOUND) {
// The database hasn't been initialized yet.
*db_version = 0;
@@ -1782,7 +1731,8 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadDatabaseVersion(
const int kFirstValidVersion = 1;
if (!base::StringToInt64(value, db_version) ||
- *db_version < kFirstValidVersion || kCurrentSchemaVersion < *db_version) {
+ *db_version < kFirstValidVersion ||
+ service_worker_internals::kCurrentSchemaVersion < *db_version) {
status = STATUS_ERROR_CORRUPTED;
HandleReadResult(FROM_HERE, status);
return status;
@@ -1800,11 +1750,13 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteBatch(
if (state_ == UNINITIALIZED) {
// Write database default values.
- batch->Put(kDatabaseVersionKey, base::Int64ToString(kCurrentSchemaVersion));
+ batch->Put(
+ service_worker_internals::kDatabaseVersionKey,
+ base::Int64ToString(service_worker_internals::kCurrentSchemaVersion));
state_ = INITIALIZED;
}
- Status status = LevelDBStatusToStatus(
+ Status status = LevelDBStatusToServiceWorkerDBStatus(
db_->Write(leveldb::WriteOptions(), batch));
HandleWriteResult(FROM_HERE, status);
return status;
@@ -1816,7 +1768,8 @@ void ServiceWorkerDatabase::BumpNextRegistrationIdIfNeeded(
DCHECK(batch);
if (next_avail_registration_id_ <= used_id) {
next_avail_registration_id_ = used_id + 1;
- batch->Put(kNextRegIdKey, base::Int64ToString(next_avail_registration_id_));
+ batch->Put(service_worker_internals::kNextRegIdKey,
+ base::Int64ToString(next_avail_registration_id_));
}
}
@@ -1826,7 +1779,8 @@ void ServiceWorkerDatabase::BumpNextResourceIdIfNeeded(
DCHECK(batch);
if (next_avail_resource_id_ <= used_id) {
next_avail_resource_id_ = used_id + 1;
- batch->Put(kNextResIdKey, base::Int64ToString(next_avail_resource_id_));
+ batch->Put(service_worker_internals::kNextResIdKey,
+ base::Int64ToString(next_avail_resource_id_));
}
}
@@ -1836,12 +1790,13 @@ void ServiceWorkerDatabase::BumpNextVersionIdIfNeeded(
DCHECK(batch);
if (next_avail_version_id_ <= used_id) {
next_avail_version_id_ = used_id + 1;
- batch->Put(kNextVerIdKey, base::Int64ToString(next_avail_version_id_));
+ batch->Put(service_worker_internals::kNextVerIdKey,
+ base::Int64ToString(next_avail_version_id_));
}
}
bool ServiceWorkerDatabase::IsOpen() {
- return db_ != NULL;
+ return db_ != nullptr;
}
void ServiceWorkerDatabase::Disable(const base::Location& from_here,
diff --git a/chromium/content/browser/service_worker/service_worker_database.h b/chromium/content/browser/service_worker/service_worker_database.h
index 0c55d1da319..d20005c0227 100644
--- a/chromium/content/browser/service_worker/service_worker_database.h
+++ b/chromium/content/browser/service_worker/service_worker_database.h
@@ -13,6 +13,7 @@
#include <utility>
#include <vector>
+#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -75,11 +76,9 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
bool is_active;
bool has_fetch_handler;
base::Time last_update_check;
- std::vector<GURL> foreign_fetch_scopes;
- std::vector<url::Origin> foreign_fetch_origins;
base::Optional<blink::TrialTokenValidator::FeatureToTokensMap>
origin_trial_tokens;
- NavigationPreloadState navigation_preload_state;
+ blink::mojom::NavigationPreloadState navigation_preload_state;
std::set<uint32_t> used_features;
// Not populated until ServiceWorkerStorage::StoreRegistration is called.
@@ -114,11 +113,6 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
// Otherwise, returns an error.
Status GetOriginsWithRegistrations(std::set<GURL>* origins);
- // Reads origins that have one or more than one registration with at least one
- // foreign fetch scope registered. Returns OK if they are successfully read or
- // not found. Otherwise returns an error.
- Status GetOriginsWithForeignFetchRegistrations(std::set<GURL>* origins);
-
// Reads registrations for |origin| from the database. Returns OK if they are
// successfully read or not found. Otherwise, returns an error.
Status GetRegistrationsForOrigin(
@@ -193,19 +187,28 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
std::vector<int64_t>* newly_purgeable_resources);
// Reads user data for |registration_id| and |user_data_names| from the
- // database. Returns OK only if all keys are found; otherwise NOT_FOUND, and
- // |user_data_values| will be empty.
+ // database and writes them to |user_data_values|. Returns OK only if all keys
+ // are found; otherwise NOT_FOUND, and |user_data_values| will be empty.
Status ReadUserData(int64_t registration_id,
const std::vector<std::string>& user_data_names,
std::vector<std::string>* user_data_values);
// Reads user data for |registration_id| and |user_data_name_prefix| from the
- // database. Returns OK only if keys matched to |user_data_name_prefix| are
- // found; otherwise NOT_FOUND, and |user_data_values| will be empty.
+ // database and writes them to |user_data_values|. Returns OK if they are
+ // successfully read or not found.
Status ReadUserDataByKeyPrefix(int64_t registration_id,
const std::string& user_data_name_prefix,
std::vector<std::string>* user_data_values);
+ // Reads user keys and associated data for |registration_id| and
+ // |user_data_name_prefix| from the database and writes them to
+ // |user_data_map|. The map keys are stripped of |user_data_name_prefix|.
+ // Returns OK if they are successfully read or not found.
+ Status ReadUserKeysAndDataByKeyPrefix(
+ int64_t registration_id,
+ const std::string& user_data_name_prefix,
+ base::flat_map<std::string, std::string>* user_data_map);
+
// Writes |name_value_pairs| into the database. Returns NOT_FOUND if the
// registration specified by |registration_id| does not exist in the database.
Status WriteUserData(
diff --git a/chromium/content/browser/service_worker/service_worker_database.proto b/chromium/content/browser/service_worker/service_worker_database.proto
index 892001d00c0..32c628cbbb0 100644
--- a/chromium/content/browser/service_worker/service_worker_database.proto
+++ b/chromium/content/browser/service_worker/service_worker_database.proto
@@ -40,8 +40,8 @@ message ServiceWorkerRegistrationData {
optional uint64 resources_total_size_bytes = 8;
- repeated string foreign_fetch_scope = 9;
- repeated string foreign_fetch_origin = 10;
+ // repeated string foreign_fetch_scope = 9; // obsolete
+ // repeated string foreign_fetch_origin = 10; // obsolete
// If the registration data was created by old Chrome (< M56),
// |origin_trial_tokens| is not set. In this case, we have to start the
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 3d700cdf7fd..4fd4cb619d3 100644
--- a/chromium/content/browser/service_worker/service_worker_database_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_database_unittest.cc
@@ -16,7 +16,9 @@
#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 "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
#include "url/origin.h"
@@ -25,6 +27,9 @@ namespace content {
namespace {
+using ::testing::ElementsAreArray;
+using ::testing::IsEmpty;
+
typedef ServiceWorkerDatabase::RegistrationData RegistrationData;
typedef ServiceWorkerDatabase::ResourceRecord Resource;
@@ -71,8 +76,6 @@ void VerifyRegistrationData(const RegistrationData& expected,
EXPECT_EQ(expected.last_update_check, actual.last_update_check);
EXPECT_EQ(expected.resources_total_size_bytes,
actual.resources_total_size_bytes);
- EXPECT_EQ(expected.foreign_fetch_scopes, actual.foreign_fetch_scopes);
- EXPECT_EQ(expected.foreign_fetch_origins, actual.foreign_fetch_origins);
EXPECT_EQ(expected.used_features, actual.used_features);
}
@@ -624,7 +627,6 @@ TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
data.script = URL(origin, "/resource1");
data.version_id = 200;
data.resources_total_size_bytes = 10939 + 200;
- data.foreign_fetch_scopes.push_back(URL(origin, "/foo/bar"));
data.used_features = {124, 901, 1019};
std::vector<Resource> resources;
@@ -650,7 +652,8 @@ TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteRegistration(
data, resources, &deleted_version, &newly_purgeable_resources));
- EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
+ deleted_version.version_id);
EXPECT_TRUE(newly_purgeable_resources.empty());
// Make sure that the registration and resource records are stored.
@@ -726,7 +729,8 @@ TEST(ServiceWorkerDatabaseTest, DeleteNonExistentRegistration) {
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->WriteRegistration(
data, resources, &deleted_version, &newly_purgeable_resources));
- EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
+ deleted_version.version_id);
EXPECT_TRUE(newly_purgeable_resources.empty());
// Delete from an origin that has a registration.
@@ -737,7 +741,8 @@ TEST(ServiceWorkerDatabaseTest, DeleteNonExistentRegistration) {
origin,
&deleted_version,
&newly_purgeable_resources));
- EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
+ deleted_version.version_id);
EXPECT_TRUE(newly_purgeable_resources.empty());
// Delete from an origin that has no registration.
@@ -748,7 +753,8 @@ TEST(ServiceWorkerDatabaseTest, DeleteNonExistentRegistration) {
GURL("http://example.net"),
&deleted_version,
&newly_purgeable_resources));
- EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
+ deleted_version.version_id);
EXPECT_TRUE(newly_purgeable_resources.empty());
}
@@ -762,9 +768,6 @@ TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
data.script = URL(origin, "/resource1");
data.version_id = 200;
data.resources_total_size_bytes = 10 + 11;
- data.foreign_fetch_scopes.push_back(URL(origin, "/foo"));
- data.foreign_fetch_origins.push_back(
- url::Origin(GURL("https://chromium.org")));
data.used_features = {124, 901, 1019};
std::vector<Resource> resources1;
@@ -779,7 +782,8 @@ TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
ServiceWorkerDatabase::STATUS_OK,
database->WriteRegistration(
data, resources1, &deleted_version, &newly_purgeable_resources));
- EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
+ deleted_version.version_id);
EXPECT_TRUE(newly_purgeable_resources.empty());
// Make sure that the registration and resource records are stored.
@@ -795,9 +799,6 @@ TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
updated_data.script = URL(origin, "/resource3");
updated_data.version_id = data.version_id + 1;
updated_data.resources_total_size_bytes = 12 + 13;
- updated_data.foreign_fetch_scopes.clear();
- updated_data.foreign_fetch_origins.push_back(
- url::Origin(GURL("https://example.com")));
updated_data.used_features = {109, 421, 9101};
std::vector<Resource> resources2;
resources2.push_back(CreateResource(3, URL(origin, "/resource3"), 12));
@@ -957,7 +958,8 @@ TEST(ServiceWorkerDatabaseTest, Registration_UninitializedDatabase) {
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->DeleteRegistration(
100, origin, &deleted_version, &newly_purgeable_resources));
- EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
+ deleted_version.version_id);
EXPECT_TRUE(newly_purgeable_resources.empty());
// Actually create a new database, but not initialized yet.
@@ -978,7 +980,8 @@ TEST(ServiceWorkerDatabaseTest, Registration_UninitializedDatabase) {
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->DeleteRegistration(
100, origin, &deleted_version, &newly_purgeable_resources));
- EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
+ deleted_version.version_id);
EXPECT_TRUE(newly_purgeable_resources.empty());
}
@@ -1175,6 +1178,102 @@ TEST(ServiceWorkerDatabaseTest,
EXPECT_EQ("value3", user_data_list[4].second);
}
+TEST(ServiceWorkerDatabaseTest, ReadUserDataByKeyPrefix) {
+ std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
+ const GURL kOrigin("http://example.com");
+
+ // Add a registration.
+ RegistrationData data;
+ data.registration_id = 100;
+ data.scope = URL(kOrigin, "/foo");
+ data.script = URL(kOrigin, "/script.js");
+ data.version_id = 200;
+ data.resources_total_size_bytes = 100;
+ std::vector<Resource> resources;
+ resources.push_back(CreateResource(1, data.script, 100));
+ ServiceWorkerDatabase::RegistrationData deleted_version;
+ std::vector<int64_t> newly_purgeable_resources;
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(data, resources, &deleted_version,
+ &newly_purgeable_resources));
+
+ // Write user data associated with the registration.
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteUserData(data.registration_id, kOrigin,
+ {{"key_prefix:key1", "value_c1"},
+ {"key_prefix:key2", "value_c2"},
+ {"other_key_prefix:k1", "value_d1"},
+ {"other_key_prefix:k2", "value_d2"}}));
+
+ std::vector<std::string> user_data;
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->ReadUserDataByKeyPrefix(data.registration_id,
+ "bogus_prefix:", &user_data));
+ EXPECT_THAT(user_data, IsEmpty());
+
+ user_data.clear();
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->ReadUserDataByKeyPrefix(data.registration_id,
+ "key_prefix:", &user_data));
+ EXPECT_THAT(user_data, ElementsAreArray({"value_c1", "value_c2"}));
+
+ user_data.clear();
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->ReadUserDataByKeyPrefix(data.registration_id,
+ "other_key_prefix:", &user_data));
+ EXPECT_THAT(user_data, ElementsAreArray({"value_d1", "value_d2"}));
+}
+
+TEST(ServiceWorkerDatabaseTest, ReadUserKeysAndDataByKeyPrefix) {
+ std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
+ const GURL kOrigin("http://example.com");
+
+ // Add a registration.
+ RegistrationData data;
+ data.registration_id = 100;
+ data.scope = URL(kOrigin, "/foo");
+ data.script = URL(kOrigin, "/script.js");
+ data.version_id = 200;
+ data.resources_total_size_bytes = 100;
+ std::vector<Resource> resources;
+ resources.push_back(CreateResource(1, data.script, 100));
+ ServiceWorkerDatabase::RegistrationData deleted_version;
+ std::vector<int64_t> newly_purgeable_resources;
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(data, resources, &deleted_version,
+ &newly_purgeable_resources));
+
+ // Write user data associated with the registration.
+ ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteUserData(data.registration_id, kOrigin,
+ {{"key_prefix:key1", "value_c1"},
+ {"key_prefix:key2", "value_c2"},
+ {"other_key_prefix:k1", "value_d1"},
+ {"other_key_prefix:k2", "value_d2"}}));
+
+ base::flat_map<std::string, std::string> user_data_map;
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->ReadUserKeysAndDataByKeyPrefix(
+ data.registration_id, "bogus_prefix:", &user_data_map));
+ EXPECT_THAT(user_data_map, IsEmpty());
+
+ user_data_map.clear();
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->ReadUserKeysAndDataByKeyPrefix(
+ data.registration_id, "key_prefix:", &user_data_map));
+ EXPECT_THAT(user_data_map,
+ ElementsAreArray(std::vector<std::pair<std::string, std::string>>{
+ {"key1", "value_c1"}, {"key2", "value_c2"}}));
+
+ user_data_map.clear();
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->ReadUserKeysAndDataByKeyPrefix(
+ data.registration_id, "other_key_prefix:", &user_data_map));
+ EXPECT_THAT(user_data_map,
+ ElementsAreArray(std::vector<std::pair<std::string, std::string>>{
+ {"k1", "value_d1"}, {"k2", "value_d2"}}));
+}
+
TEST(ServiceWorkerDatabaseTest, UserData_DeleteUserDataByKeyPrefixes) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
const GURL kOrigin("http://example.com");
@@ -1676,7 +1775,6 @@ TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
data1.script = URL(origin1, "/resource1");
data1.version_id = 100;
data1.resources_total_size_bytes = 2013 + 512;
- data1.foreign_fetch_scopes.push_back(URL(origin1, "/foo/ff"));
std::vector<Resource> resources1;
resources1.push_back(CreateResource(1, URL(origin1, "/resource1"), 2013));
@@ -1720,7 +1818,6 @@ TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
data3.script = URL(origin2, "/resource5");
data3.version_id = 102;
data3.resources_total_size_bytes = 6 + 7;
- data3.foreign_fetch_scopes.push_back(URL(origin2, "/hoge/ff"));
std::vector<Resource> resources3;
resources3.push_back(CreateResource(5, URL(origin2, "/resource5"), 6));
@@ -1749,13 +1846,6 @@ TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
EXPECT_EQ(1u, unique_origins.size());
EXPECT_TRUE(base::ContainsKey(unique_origins, origin2));
- // |origin1| should be removed from the foreign fetch origin list.
- unique_origins.clear();
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->GetOriginsWithForeignFetchRegistrations(&unique_origins));
- EXPECT_EQ(1u, unique_origins.size());
- EXPECT_TRUE(base::ContainsKey(unique_origins, origin2));
-
// The registrations for |origin1| should be removed.
std::vector<RegistrationData> registrations;
EXPECT_EQ(
@@ -1830,142 +1920,6 @@ TEST(ServiceWorkerDatabaseTest, DestroyDatabase) {
ASSERT_FALSE(base::DirectoryExists(database_dir.GetPath()));
}
-TEST(ServiceWorkerDatabaseTest, GetOriginsWithForeignFetchRegistrations) {
- std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
-
- std::set<GURL> origins;
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->GetOriginsWithForeignFetchRegistrations(&origins));
- EXPECT_TRUE(origins.empty());
-
- ServiceWorkerDatabase::RegistrationData deleted_version;
- std::vector<int64_t> newly_purgeable_resources;
-
- GURL origin1("http://example.com");
- RegistrationData data1;
- data1.registration_id = 123;
- data1.scope = URL(origin1, "/foo");
- data1.script = URL(origin1, "/script1.js");
- data1.version_id = 456;
- data1.resources_total_size_bytes = 100;
- data1.foreign_fetch_scopes.push_back(URL(origin1, "/foo/bar"));
- std::vector<Resource> resources1;
- resources1.push_back(CreateResource(1, data1.script, 100));
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WriteRegistration(data1, resources1, &deleted_version,
- &newly_purgeable_resources));
-
- GURL origin2("https://www.example.com");
- RegistrationData data2;
- data2.registration_id = 234;
- data2.scope = URL(origin2, "/bar");
- data2.script = URL(origin2, "/script2.js");
- data2.version_id = 567;
- data2.resources_total_size_bytes = 200;
- std::vector<Resource> resources2;
- resources2.push_back(CreateResource(2, data2.script, 200));
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WriteRegistration(data2, resources2, &deleted_version,
- &newly_purgeable_resources));
-
- GURL origin3("https://example.org");
- RegistrationData data3;
- data3.registration_id = 345;
- data3.scope = URL(origin3, "/hoge");
- data3.script = URL(origin3, "/script3.js");
- data3.version_id = 678;
- data3.resources_total_size_bytes = 300;
- data3.foreign_fetch_scopes.push_back(URL(origin3, "/hoge/foo"));
- std::vector<Resource> resources3;
- resources3.push_back(CreateResource(3, data3.script, 300));
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WriteRegistration(data3, resources3, &deleted_version,
- &newly_purgeable_resources));
-
- // |origin3| has three registrations.
- RegistrationData data4;
- data4.registration_id = 456;
- data4.scope = URL(origin3, "/fuga");
- data4.script = URL(origin3, "/script4.js");
- data4.version_id = 789;
- data4.resources_total_size_bytes = 400;
- data4.foreign_fetch_scopes.push_back(URL(origin3, "/fuga/bar"));
- std::vector<Resource> resources4;
- resources4.push_back(CreateResource(4, data4.script, 400));
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WriteRegistration(data4, resources4, &deleted_version,
- &newly_purgeable_resources));
-
- RegistrationData data5;
- data5.registration_id = 567;
- data5.scope = URL(origin3, "/bla");
- data5.script = URL(origin3, "/script5.js");
- data5.version_id = 890;
- data5.resources_total_size_bytes = 500;
- std::vector<Resource> resources5;
- resources5.push_back(CreateResource(5, data5.script, 500));
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WriteRegistration(data5, resources5, &deleted_version,
- &newly_purgeable_resources));
-
- origins.clear();
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->GetOriginsWithForeignFetchRegistrations(&origins));
- EXPECT_EQ(2U, origins.size());
- EXPECT_TRUE(base::ContainsKey(origins, origin1));
- EXPECT_TRUE(base::ContainsKey(origins, origin3));
-
- // |origin3| has another registration, so should not remove it from the
- // foreign fetch origin list.
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->DeleteRegistration(data4.registration_id, origin3,
- &deleted_version,
- &newly_purgeable_resources));
- EXPECT_EQ(data4.registration_id, deleted_version.registration_id);
-
- origins.clear();
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->GetOriginsWithForeignFetchRegistrations(&origins));
- EXPECT_EQ(2U, origins.size());
- EXPECT_TRUE(base::ContainsKey(origins, origin1));
- EXPECT_TRUE(base::ContainsKey(origins, origin3));
-
- // |origin3| should be removed from the foreign fetch origin list, since its
- // only remaining registration doesn't have foreign fetch scopes.
- ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->DeleteRegistration(data3.registration_id, origin3,
- &deleted_version,
- &newly_purgeable_resources));
- EXPECT_EQ(data3.registration_id, deleted_version.registration_id);
-
- origins.clear();
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->GetOriginsWithForeignFetchRegistrations(&origins));
- EXPECT_EQ(1U, origins.size());
- EXPECT_TRUE(base::ContainsKey(origins, origin1));
-
- // |origin1| should be removed from the foreign fetch origin list, since we
- // replace its registration with one without scopes.
- RegistrationData updated_data1 = data1;
- updated_data1.version_id++;
- updated_data1.resources_total_size_bytes = 12 + 13;
- updated_data1.foreign_fetch_scopes.clear();
- std::vector<Resource> updated_resources1;
- updated_resources1.push_back(
- CreateResource(13, URL(origin1, "/resource3"), 12));
- updated_resources1.push_back(
- CreateResource(14, URL(origin1, "/resource4"), 13));
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->WriteRegistration(updated_data1, updated_resources1,
- &deleted_version,
- &newly_purgeable_resources));
-
- origins.clear();
- EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->GetOriginsWithForeignFetchRegistrations(&origins));
- EXPECT_EQ(0U, origins.size());
-}
-
TEST(ServiceWorkerDatabaseTest, Corruption_NoMainResource) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
ServiceWorkerDatabase::RegistrationData deleted_version;
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 18db95e867f..a4e5b723869 100644
--- a/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -22,11 +22,9 @@
#include "content/browser/service_worker/service_worker_handle.h"
#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/browser/service_worker/service_worker_registration_handle.h"
#include "content/common/service_worker/embedded_worker_messages.h"
#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
#include "content/common/service_worker/service_worker_messages.h"
-#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
@@ -36,9 +34,11 @@
#include "content/public/common/content_client.h"
#include "content/public/common/origin_util.h"
#include "ipc/ipc_message_macros.h"
-#include "net/http/http_util.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
+#include "third_party/WebKit/public/platform/web_feature.mojom.h"
#include "url/gurl.h"
using blink::MessagePortChannel;
@@ -48,45 +48,17 @@ namespace content {
namespace {
-const char kNoDocumentURLErrorMessage[] =
- "No URL is associated with the caller's document.";
-const char kShutdownErrorMessage[] =
- "The Service Worker system has shutdown.";
-const char kUserDeniedPermissionMessage[] =
- "The user denied permission to use Service Worker.";
-const char kInvalidStateErrorMessage[] = "The object is in an invalid state.";
-const char kEnableNavigationPreloadErrorPrefix[] =
- "Failed to enable or disable navigation preload: ";
-const char kGetNavigationPreloadStateErrorPrefix[] =
- "Failed to get navigation preload state: ";
-const char kSetNavigationPreloadHeaderErrorPrefix[] =
- "Failed to set navigation preload header: ";
-const char kNoActiveWorkerErrorMessage[] =
- "The registration does not have an active worker.";
-const char kDatabaseErrorMessage[] = "Failed to access storage.";
-
-const uint32_t kFilteredMessageClasses[] = {
+const uint32_t kServiceWorkerFilteredMessageClasses[] = {
ServiceWorkerMsgStart, EmbeddedWorkerMsgStart,
};
-void RunSoon(const base::Closure& callback) {
- if (!callback.is_null())
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
-}
-
-WebContents* GetWebContents(int render_process_id, int render_frame_id) {
- RenderFrameHost* rfh =
- RenderFrameHost::FromID(render_process_id, render_frame_id);
- return WebContents::FromRenderFrameHost(rfh);
-}
-
} // namespace
ServiceWorkerDispatcherHost::ServiceWorkerDispatcherHost(
int render_process_id,
ResourceContext* resource_context)
- : BrowserMessageFilter(kFilteredMessageClasses,
- arraysize(kFilteredMessageClasses)),
+ : BrowserMessageFilter(kServiceWorkerFilteredMessageClasses,
+ arraysize(kServiceWorkerFilteredMessageClasses)),
BrowserAssociatedInterface<mojom::ServiceWorkerDispatcherHost>(this,
this),
render_process_id_(render_process_id),
@@ -160,10 +132,6 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcherHost, message)
- IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_UpdateServiceWorker,
- OnUpdateServiceWorker)
- IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_UnregisterServiceWorker,
- OnUnregisterServiceWorker)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker,
OnPostMessageToWorker)
IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_CountFeature, OnCountFeature)
@@ -172,12 +140,6 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived(
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount,
OnDecrementServiceWorkerRefCount)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_TerminateWorker, OnTerminateWorker)
- IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_EnableNavigationPreload,
- OnEnableNavigationPreload)
- IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetNavigationPreloadState,
- OnGetNavigationPreloadState)
- IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetNavigationPreloadHeader,
- OnSetNavigationPreloadHeader)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -208,17 +170,6 @@ void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle(
handles_.AddWithID(std::move(handle), handle_id);
}
-void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle(
- ServiceWorkerRegistrationHandle* handle) {
- int handle_id = handle->handle_id();
- registration_handles_.AddWithID(base::WrapUnique(handle), handle_id);
-}
-
-void ServiceWorkerDispatcherHost::UnregisterServiceWorkerRegistrationHandle(
- int handle_id) {
- registration_handles_.Remove(handle_id);
-}
-
ServiceWorkerHandle* ServiceWorkerDispatcherHost::FindServiceWorkerHandle(
int provider_id,
int64_t version_id) {
@@ -236,400 +187,11 @@ ServiceWorkerHandle* ServiceWorkerDispatcherHost::FindServiceWorkerHandle(
return nullptr;
}
-blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
-ServiceWorkerDispatcherHost::CreateRegistrationObjectInfo(
- base::WeakPtr<ServiceWorkerProviderHost> provider_host,
- ServiceWorkerRegistration* registration) {
- DCHECK(provider_host);
- ServiceWorkerRegistrationHandle* existing_handle =
- FindRegistrationHandle(provider_host->provider_id(), registration->id());
- if (existing_handle) {
- return existing_handle->CreateObjectInfo();
- }
- // ServiceWorkerRegistrationHandle ctor will register itself into
- // |registration_handles_|.
- auto* new_handle = new ServiceWorkerRegistrationHandle(
- GetContext()->AsWeakPtr(), this, provider_host, registration);
- return new_handle->CreateObjectInfo();
-}
-
base::WeakPtr<ServiceWorkerDispatcherHost>
ServiceWorkerDispatcherHost::AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
-void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(
- int thread_id,
- int request_id,
- int provider_id,
- int64_t registration_id) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerDispatcherHost::OnUpdateServiceWorker");
- ProviderStatus provider_status;
- ServiceWorkerProviderHost* provider_host =
- GetProviderHostForRequest(&provider_status, provider_id);
- switch (provider_status) {
- case ProviderStatus::NO_CONTEXT: // fallthrough
- case ProviderStatus::DEAD_HOST:
- Send(new ServiceWorkerMsg_ServiceWorkerUpdateError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kAbort,
- base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) +
- base::ASCIIToUTF16(kShutdownErrorMessage)));
- return;
- case ProviderStatus::NO_HOST:
- bad_message::ReceivedBadMessage(this, bad_message::SWDH_UPDATE_NO_HOST);
- return;
- case ProviderStatus::NO_URL:
- Send(new ServiceWorkerMsg_ServiceWorkerUpdateError(
- thread_id, request_id,
- blink::mojom::ServiceWorkerErrorType::kSecurity,
- base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) +
- base::ASCIIToUTF16(kNoDocumentURLErrorMessage)));
- return;
- case ProviderStatus::OK:
- break;
- }
-
- ServiceWorkerRegistration* registration =
- GetContext()->GetLiveRegistration(registration_id);
- if (!registration) {
- // |registration| must be alive because a renderer retains a registration
- // reference at this point.
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_UPDATE_BAD_REGISTRATION_ID);
- return;
- }
-
- std::vector<GURL> urls = {provider_host->document_url(),
- registration->pattern()};
- if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) {
- bad_message::ReceivedBadMessage(this, bad_message::SWDH_UPDATE_CANNOT);
- return;
- }
-
- if (!GetContentClient()->browser()->AllowServiceWorker(
- registration->pattern(), provider_host->topmost_frame_url(),
- resource_context_, base::Bind(&GetWebContents, render_process_id_,
- provider_host->frame_id()))) {
- Send(new ServiceWorkerMsg_ServiceWorkerUpdateError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kDisabled,
- base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) +
- base::ASCIIToUTF16(kUserDeniedPermissionMessage)));
- return;
- }
-
- if (!registration->GetNewestVersion()) {
- // This can happen if update() is called during initial script evaluation.
- // Abort the following steps according to the spec.
- Send(new ServiceWorkerMsg_ServiceWorkerUpdateError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kState,
- base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) +
- base::ASCIIToUTF16(kInvalidStateErrorMessage)));
- return;
- }
-
- TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
- "ServiceWorkerDispatcherHost::UpdateServiceWorker",
- request_id, "Scope", registration->pattern().spec());
- GetContext()->UpdateServiceWorker(
- registration, false /* force_bypass_cache */,
- false /* skip_script_comparison */, provider_host,
- base::Bind(&ServiceWorkerDispatcherHost::UpdateComplete, this, thread_id,
- provider_id, request_id));
-}
-
-void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
- int thread_id,
- int request_id,
- int provider_id,
- int64_t registration_id) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker");
- ProviderStatus provider_status;
- ServiceWorkerProviderHost* provider_host =
- GetProviderHostForRequest(&provider_status, provider_id);
- switch (provider_status) {
- case ProviderStatus::NO_CONTEXT: // fallthrough
- case ProviderStatus::DEAD_HOST:
- Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kAbort,
- base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) +
- base::ASCIIToUTF16(kShutdownErrorMessage)));
- return;
- case ProviderStatus::NO_HOST:
- bad_message::ReceivedBadMessage(this,
- bad_message::SWDH_UNREGISTER_NO_HOST);
- return;
- case ProviderStatus::NO_URL:
- Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
- thread_id, request_id,
- blink::mojom::ServiceWorkerErrorType::kSecurity,
- base::ASCIIToUTF16(kServiceWorkerUnregisterErrorPrefix) +
- base::ASCIIToUTF16(kNoDocumentURLErrorMessage)));
- return;
- case ProviderStatus::OK:
- break;
- }
-
- ServiceWorkerRegistration* registration =
- GetContext()->GetLiveRegistration(registration_id);
- if (!registration) {
- // |registration| must be alive because a renderer retains a registration
- // reference at this point.
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_UNREGISTER_BAD_REGISTRATION_ID);
- return;
- }
-
- std::vector<GURL> urls = {provider_host->document_url(),
- registration->pattern()};
- if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) {
- bad_message::ReceivedBadMessage(this, bad_message::SWDH_UNREGISTER_CANNOT);
- return;
- }
-
- if (!GetContentClient()->browser()->AllowServiceWorker(
- registration->pattern(), provider_host->topmost_frame_url(),
- resource_context_, base::Bind(&GetWebContents, render_process_id_,
- provider_host->frame_id()))) {
- Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kDisabled,
- base::ASCIIToUTF16(kUserDeniedPermissionMessage)));
- return;
- }
-
- TRACE_EVENT_ASYNC_BEGIN1(
- "ServiceWorker", "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
- request_id, "Scope", registration->pattern().spec());
- GetContext()->UnregisterServiceWorker(
- registration->pattern(),
- base::Bind(&ServiceWorkerDispatcherHost::UnregistrationComplete, this,
- thread_id, request_id));
-}
-
-void ServiceWorkerDispatcherHost::OnEnableNavigationPreload(
- int thread_id,
- int request_id,
- int provider_id,
- int64_t registration_id,
- bool enable) {
- ProviderStatus provider_status;
- ServiceWorkerProviderHost* provider_host =
- GetProviderHostForRequest(&provider_status, provider_id);
- switch (provider_status) {
- case ProviderStatus::NO_CONTEXT: // fallthrough
- case ProviderStatus::DEAD_HOST:
- Send(new ServiceWorkerMsg_EnableNavigationPreloadError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kAbort,
- std::string(kEnableNavigationPreloadErrorPrefix) +
- std::string(kShutdownErrorMessage)));
- return;
- case ProviderStatus::NO_HOST:
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_ENABLE_NAVIGATION_PRELOAD_NO_HOST);
- return;
- case ProviderStatus::NO_URL:
- Send(new ServiceWorkerMsg_EnableNavigationPreloadError(
- thread_id, request_id,
- blink::mojom::ServiceWorkerErrorType::kSecurity,
- std::string(kEnableNavigationPreloadErrorPrefix) +
- std::string(kNoDocumentURLErrorMessage)));
- return;
- case ProviderStatus::OK:
- break;
- }
-
- ServiceWorkerRegistration* registration =
- GetContext()->GetLiveRegistration(registration_id);
- if (!registration) {
- // |registration| must be alive because a renderer retains a registration
- // reference at this point.
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_ENABLE_NAVIGATION_PRELOAD_BAD_REGISTRATION_ID);
- return;
- }
- if (!registration->active_version()) {
- Send(new ServiceWorkerMsg_EnableNavigationPreloadError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kState,
- std::string(kEnableNavigationPreloadErrorPrefix) +
- std::string(kNoActiveWorkerErrorMessage)));
- return;
- }
-
- std::vector<GURL> urls = {provider_host->document_url(),
- registration->pattern()};
- if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) {
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_ENABLE_NAVIGATION_PRELOAD_INVALID_ORIGIN);
- return;
- }
-
- if (!GetContentClient()->browser()->AllowServiceWorker(
- registration->pattern(), provider_host->topmost_frame_url(),
- resource_context_, base::Bind(&GetWebContents, render_process_id_,
- provider_host->frame_id()))) {
- Send(new ServiceWorkerMsg_EnableNavigationPreloadError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kDisabled,
- std::string(kEnableNavigationPreloadErrorPrefix) +
- std::string(kUserDeniedPermissionMessage)));
- return;
- }
-
- GetContext()->storage()->UpdateNavigationPreloadEnabled(
- registration->id(), registration->pattern().GetOrigin(), enable,
- base::Bind(
- &ServiceWorkerDispatcherHost::DidUpdateNavigationPreloadEnabled, this,
- thread_id, request_id, registration->id(), enable));
-}
-
-void ServiceWorkerDispatcherHost::OnGetNavigationPreloadState(
- int thread_id,
- int request_id,
- int provider_id,
- int64_t registration_id) {
- ProviderStatus provider_status;
- ServiceWorkerProviderHost* provider_host =
- GetProviderHostForRequest(&provider_status, provider_id);
- switch (provider_status) {
- case ProviderStatus::NO_CONTEXT: // fallthrough
- case ProviderStatus::DEAD_HOST:
- Send(new ServiceWorkerMsg_GetNavigationPreloadStateError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kAbort,
- std::string(kGetNavigationPreloadStateErrorPrefix) +
- std::string(kShutdownErrorMessage)));
- return;
- case ProviderStatus::NO_HOST:
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_GET_NAVIGATION_PRELOAD_STATE_NO_HOST);
- return;
- case ProviderStatus::NO_URL:
- Send(new ServiceWorkerMsg_GetNavigationPreloadStateError(
- thread_id, request_id,
- blink::mojom::ServiceWorkerErrorType::kSecurity,
- std::string(kGetNavigationPreloadStateErrorPrefix) +
- std::string(kNoDocumentURLErrorMessage)));
- return;
- case ProviderStatus::OK:
- break;
- }
-
- ServiceWorkerRegistration* registration =
- GetContext()->GetLiveRegistration(registration_id);
- if (!registration) {
- // |registration| must be alive because a renderer retains a registration
- // reference at this point.
- bad_message::ReceivedBadMessage(
- this,
- bad_message::SWDH_GET_NAVIGATION_PRELOAD_STATE_BAD_REGISTRATION_ID);
- return;
- }
-
- std::vector<GURL> urls = {provider_host->document_url(),
- registration->pattern()};
- if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) {
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_GET_NAVIGATION_PRELOAD_STATE_INVALID_ORIGIN);
- return;
- }
-
- if (!GetContentClient()->browser()->AllowServiceWorker(
- registration->pattern(), provider_host->topmost_frame_url(),
- resource_context_, base::Bind(&GetWebContents, render_process_id_,
- provider_host->frame_id()))) {
- Send(new ServiceWorkerMsg_GetNavigationPreloadStateError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kDisabled,
- std::string(kGetNavigationPreloadStateErrorPrefix) +
- std::string(kUserDeniedPermissionMessage)));
- return;
- }
-
- Send(new ServiceWorkerMsg_DidGetNavigationPreloadState(
- thread_id, request_id, registration->navigation_preload_state()));
-}
-
-void ServiceWorkerDispatcherHost::OnSetNavigationPreloadHeader(
- int thread_id,
- int request_id,
- int provider_id,
- int64_t registration_id,
- const std::string& value) {
- ProviderStatus provider_status;
- ServiceWorkerProviderHost* provider_host =
- GetProviderHostForRequest(&provider_status, provider_id);
- switch (provider_status) {
- case ProviderStatus::NO_CONTEXT: // fallthrough
- case ProviderStatus::DEAD_HOST:
- Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kAbort,
- std::string(kSetNavigationPreloadHeaderErrorPrefix) +
- std::string(kShutdownErrorMessage)));
- return;
- case ProviderStatus::NO_HOST:
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_NO_HOST);
- return;
- case ProviderStatus::NO_URL:
- Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError(
- thread_id, request_id,
- blink::mojom::ServiceWorkerErrorType::kSecurity,
- std::string(kSetNavigationPreloadHeaderErrorPrefix) +
- std::string(kNoDocumentURLErrorMessage)));
- return;
- case ProviderStatus::OK:
- break;
- }
-
- ServiceWorkerRegistration* registration =
- GetContext()->GetLiveRegistration(registration_id);
- if (!registration) {
- // |registration| must be alive because a renderer retains a registration
- // reference at this point.
- bad_message::ReceivedBadMessage(
- this,
- bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_BAD_REGISTRATION_ID);
- return;
- }
- if (!registration->active_version()) {
- Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kState,
- std::string(kSetNavigationPreloadHeaderErrorPrefix) +
- std::string(kNoActiveWorkerErrorMessage)));
- return;
- }
-
- std::vector<GURL> urls = {provider_host->document_url(),
- registration->pattern()};
- if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) {
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_INVALID_ORIGIN);
- return;
- }
-
- // TODO(falken): Ideally this would match Blink's isValidHTTPHeaderValue.
- // Chrome's check is less restrictive: it allows non-latin1 characters.
- if (!net::HttpUtil::IsValidHeaderValue(value)) {
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_SET_NAVIGATION_PRELOAD_HEADER_BAD_VALUE);
- return;
- }
-
- if (!GetContentClient()->browser()->AllowServiceWorker(
- registration->pattern(), provider_host->topmost_frame_url(),
- resource_context_, base::Bind(&GetWebContents, render_process_id_,
- provider_host->frame_id()))) {
- Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kDisabled,
- std::string(kSetNavigationPreloadHeaderErrorPrefix) +
- std::string(kUserDeniedPermissionMessage)));
- return;
- }
-
- GetContext()->storage()->UpdateNavigationPreloadHeader(
- registration->id(), registration->pattern().GetOrigin(), value,
- base::Bind(&ServiceWorkerDispatcherHost::DidUpdateNavigationPreloadHeader,
- this, thread_id, request_id, registration->id(), value));
-}
-
void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
int handle_id,
int provider_id,
@@ -669,9 +231,8 @@ void ServiceWorkerDispatcherHost::DispatchExtendableMessageEvent(
ServiceWorkerProviderHost* sender_provider_host,
const StatusCallback& callback) {
switch (sender_provider_host->provider_type()) {
- case SERVICE_WORKER_PROVIDER_FOR_WINDOW:
- case SERVICE_WORKER_PROVIDER_FOR_WORKER:
- case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER:
+ case blink::mojom::ServiceWorkerProviderType::kForWindow:
+ case blink::mojom::ServiceWorkerProviderType::kForSharedWorker:
service_worker_client_utils::GetClient(
sender_provider_host,
base::Bind(&ServiceWorkerDispatcherHost::
@@ -680,21 +241,26 @@ void ServiceWorkerDispatcherHost::DispatchExtendableMessageEvent(
this, worker, message, source_origin, sent_message_ports,
base::nullopt, callback));
break;
- case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: {
+ case blink::mojom::ServiceWorkerProviderType::kForServiceWorker: {
// Clamp timeout to the sending worker's remaining timeout, to prevent
// postMessage from keeping workers alive forever.
base::TimeDelta timeout =
sender_provider_host->running_hosted_version()->remaining_timeout();
- RunSoon(base::Bind(
- &ServiceWorkerDispatcherHost::DispatchExtendableMessageEventInternal<
- ServiceWorkerObjectInfo>,
- this, worker, message, source_origin, sent_message_ports,
- base::make_optional(timeout), callback,
+ blink::mojom::ServiceWorkerObjectInfoPtr worker_info =
sender_provider_host->GetOrCreateServiceWorkerHandle(
- sender_provider_host->running_hosted_version())));
+ sender_provider_host->running_hosted_version());
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ServiceWorkerDispatcherHost::
+ DispatchExtendableMessageEventInternal<
+ blink::mojom::ServiceWorkerObjectInfo>,
+ this, worker, message, source_origin,
+ sent_message_ports, base::make_optional(timeout),
+ callback, *worker_info));
break;
}
- case SERVICE_WORKER_PROVIDER_UNKNOWN:
+ case blink::mojom::ServiceWorkerProviderType::kUnknown:
default:
NOTREACHED() << sender_provider_host->provider_type();
break;
@@ -732,7 +298,7 @@ void ServiceWorkerDispatcherHost::OnProviderCreated(
}
// Otherwise, completed the initialization of the pre-created host.
- if (info.type != SERVICE_WORKER_PROVIDER_FOR_WINDOW) {
+ if (info.type != blink::mojom::ServiceWorkerProviderType::kForWindow) {
bad_message::ReceivedBadMessage(
this, bad_message::SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_NOT_WINDOW);
return;
@@ -741,9 +307,10 @@ void ServiceWorkerDispatcherHost::OnProviderCreated(
std::move(info), AsWeakPtr());
GetContext()->AddProviderHost(std::move(provider_host));
} else {
- // Provider host for controller should be pre-created on StartWorker in
- // ServiceWorkerVersion.
- if (info.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) {
+ // Provider hosts for service workers should be pre-created in StartWorker
+ // in ServiceWorkerVersion.
+ if (info.type ==
+ blink::mojom::ServiceWorkerProviderType::kForServiceWorker) {
bad_message::ReceivedBadMessage(
this, bad_message::SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_CONTROLLER);
return;
@@ -768,7 +335,7 @@ void ServiceWorkerDispatcherHost::DispatchExtendableMessageEventInternal(
const base::Optional<base::TimeDelta>& timeout,
const StatusCallback& callback,
const SourceInfo& source_info) {
- if (!source_info.IsValid()) {
+ if (!IsValidSourceInfo(source_info)) {
DidFailToDispatchExtendableMessageEvent<SourceInfo>(
sent_message_ports, source_info, callback, SERVICE_WORKER_ERROR_FAILED);
return;
@@ -839,11 +406,22 @@ void ServiceWorkerDispatcherHost::DidFailToDispatchExtendableMessageEvent(
const SourceInfo& source_info,
const StatusCallback& callback,
ServiceWorkerStatusCode status) {
- if (source_info.IsValid())
+ if (IsValidSourceInfo(source_info))
ReleaseSourceInfo(source_info);
callback.Run(status);
}
+bool ServiceWorkerDispatcherHost::IsValidSourceInfo(
+ const ServiceWorkerClientInfo& source_info) {
+ return source_info.IsValid();
+}
+
+bool ServiceWorkerDispatcherHost::IsValidSourceInfo(
+ const blink::mojom::ServiceWorkerObjectInfo& source_info) {
+ return source_info.handle_id != blink::mojom::kInvalidServiceWorkerHandleId &&
+ source_info.version_id != blink::mojom::kInvalidServiceWorkerVersionId;
+}
+
void ServiceWorkerDispatcherHost::ReleaseSourceInfo(
const ServiceWorkerClientInfo& source_info) {
// ServiceWorkerClientInfo is just a snapshot of the client. There is no need
@@ -851,7 +429,7 @@ void ServiceWorkerDispatcherHost::ReleaseSourceInfo(
}
void ServiceWorkerDispatcherHost::ReleaseSourceInfo(
- const ServiceWorkerObjectInfo& source_info) {
+ const blink::mojom::ServiceWorkerObjectInfo& source_info) {
ServiceWorkerHandle* handle = handles_.Lookup(source_info.handle_id);
DCHECK(handle);
handle->DecrementRefCount();
@@ -859,67 +437,6 @@ void ServiceWorkerDispatcherHost::ReleaseSourceInfo(
handles_.Remove(source_info.handle_id);
}
-ServiceWorkerRegistrationHandle*
-ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id,
- int64_t registration_id) {
- for (RegistrationHandleMap::iterator iter(&registration_handles_);
- !iter.IsAtEnd(); iter.Advance()) {
- ServiceWorkerRegistrationHandle* handle = iter.GetCurrentValue();
- if (handle->provider_id() == provider_id &&
- handle->registration()->id() == registration_id) {
- return handle;
- }
- }
- return nullptr;
-}
-
-void ServiceWorkerDispatcherHost::GetRegistrationObjectInfoAndVersionAttributes(
- base::WeakPtr<ServiceWorkerProviderHost> provider_host,
- ServiceWorkerRegistration* registration,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr* out_info,
- ServiceWorkerVersionAttributes* out_attrs) {
- *out_info = CreateRegistrationObjectInfo(provider_host, registration);
-
- out_attrs->installing = provider_host->GetOrCreateServiceWorkerHandle(
- registration->installing_version());
- out_attrs->waiting = provider_host->GetOrCreateServiceWorkerHandle(
- registration->waiting_version());
- out_attrs->active = provider_host->GetOrCreateServiceWorkerHandle(
- registration->active_version());
-}
-
-void ServiceWorkerDispatcherHost::UpdateComplete(
- int thread_id,
- int provider_id,
- int request_id,
- ServiceWorkerStatusCode status,
- const std::string& status_message,
- int64_t registration_id) {
- TRACE_EVENT_ASYNC_END2(
- "ServiceWorker", "ServiceWorkerDispatcherHost::UpdateServiceWorker",
- request_id, "Status", status, "Registration ID", registration_id);
- if (!GetContext())
- return;
-
- ServiceWorkerProviderHost* provider_host =
- GetContext()->GetProviderHost(render_process_id_, provider_id);
- if (!provider_host)
- return; // The provider has already been destroyed.
-
- if (status != SERVICE_WORKER_OK) {
- base::string16 error_message;
- blink::mojom::ServiceWorkerErrorType error_type;
- GetServiceWorkerRegistrationStatusResponse(status, status_message,
- &error_type, &error_message);
- Send(new ServiceWorkerMsg_ServiceWorkerUpdateError(
- thread_id, request_id, error_type,
- base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + error_message));
- return;
- }
-
- Send(new ServiceWorkerMsg_ServiceWorkerUpdated(thread_id, request_id));
-}
-
void ServiceWorkerDispatcherHost::OnCountFeature(int64_t version_id,
uint32_t feature) {
if (!GetContext())
@@ -927,6 +444,14 @@ void ServiceWorkerDispatcherHost::OnCountFeature(int64_t version_id,
ServiceWorkerVersion* version = GetContext()->GetLiveVersion(version_id);
if (!version)
return;
+ if (feature >=
+ static_cast<uint32_t>(blink::mojom::WebFeature::kNumberOfFeatures)) {
+ // We don't use BadMessageReceived here since this IPC will be converted to
+ // a Mojo method call soon, which will validate inputs for us.
+ // TODO(xiaofeng.zhang): Convert the OnCountFeature IPC into a Mojo method
+ // call.
+ return;
+ }
version->CountFeature(feature);
}
@@ -958,30 +483,6 @@ void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(
handles_.Remove(handle_id);
}
-void ServiceWorkerDispatcherHost::UnregistrationComplete(
- int thread_id,
- int request_id,
- ServiceWorkerStatusCode status) {
- TRACE_EVENT_ASYNC_END1("ServiceWorker",
- "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
- request_id, "Status", status);
- if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
- base::string16 error_message;
- blink::mojom::ServiceWorkerErrorType error_type;
- GetServiceWorkerRegistrationStatusResponse(status, std::string(),
- &error_type, &error_message);
- Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
- thread_id, request_id, error_type,
- base::ASCIIToUTF16(kServiceWorkerUnregisterErrorPrefix) +
- error_message));
- return;
- }
- const bool is_success = (status == SERVICE_WORKER_OK);
- Send(new ServiceWorkerMsg_ServiceWorkerUnregistered(thread_id,
- request_id,
- is_success));
-}
-
ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() {
// Temporary CHECK for debugging https://crbug.com/736203.
CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -990,81 +491,6 @@ ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() {
return context_wrapper_->context();
}
-ServiceWorkerProviderHost*
-ServiceWorkerDispatcherHost::GetProviderHostForRequest(ProviderStatus* status,
- int provider_id) {
- if (!GetContext()) {
- *status = ProviderStatus::NO_CONTEXT;
- return nullptr;
- }
-
- ServiceWorkerProviderHost* provider_host =
- GetContext()->GetProviderHost(render_process_id_, provider_id);
- if (!provider_host) {
- *status = ProviderStatus::NO_HOST;
- return nullptr;
- }
-
- if (!provider_host->IsContextAlive()) {
- *status = ProviderStatus::DEAD_HOST;
- return nullptr;
- }
-
- // TODO(falken): This check can be removed once crbug.com/439697 is fixed.
- if (provider_host->document_url().is_empty()) {
- *status = ProviderStatus::NO_URL;
- return nullptr;
- }
-
- *status = ProviderStatus::OK;
- return provider_host;
-}
-
-void ServiceWorkerDispatcherHost::DidUpdateNavigationPreloadEnabled(
- int thread_id,
- int request_id,
- int registration_id,
- bool enable,
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
- Send(new ServiceWorkerMsg_EnableNavigationPreloadError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kUnknown,
- std::string(kEnableNavigationPreloadErrorPrefix) +
- std::string(kDatabaseErrorMessage)));
- return;
- }
- if (!GetContext())
- return;
- ServiceWorkerRegistration* registration =
- GetContext()->GetLiveRegistration(registration_id);
- if (registration)
- registration->EnableNavigationPreload(enable);
- Send(new ServiceWorkerMsg_DidEnableNavigationPreload(thread_id, request_id));
-}
-
-void ServiceWorkerDispatcherHost::DidUpdateNavigationPreloadHeader(
- int thread_id,
- int request_id,
- int registration_id,
- const std::string& value,
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
- Send(new ServiceWorkerMsg_SetNavigationPreloadHeaderError(
- thread_id, request_id, blink::mojom::ServiceWorkerErrorType::kUnknown,
- std::string(kSetNavigationPreloadHeaderErrorPrefix) +
- std::string(kDatabaseErrorMessage)));
- return;
- }
- if (!GetContext())
- return;
- ServiceWorkerRegistration* registration =
- GetContext()->GetLiveRegistration(registration_id);
- if (registration)
- registration->SetNavigationPreloadHeader(value);
- Send(new ServiceWorkerMsg_DidSetNavigationPreloadHeader(thread_id,
- request_id));
-}
-
void ServiceWorkerDispatcherHost::OnTerminateWorker(int handle_id) {
ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
if (!handle) {
diff --git a/chromium/content/browser/service_worker/service_worker_dispatcher_host.h b/chromium/content/browser/service_worker/service_worker_dispatcher_host.h
index 93574ae022a..ce3d794e66f 100644
--- a/chromium/content/browser/service_worker/service_worker_dispatcher_host.h
+++ b/chromium/content/browser/service_worker/service_worker_dispatcher_host.h
@@ -38,11 +38,7 @@ class ServiceWorkerContextCore;
class ServiceWorkerContextWrapper;
class ServiceWorkerHandle;
class ServiceWorkerProviderHost;
-class ServiceWorkerRegistration;
-class ServiceWorkerRegistrationHandle;
class ServiceWorkerVersion;
-struct ServiceWorkerObjectInfo;
-struct ServiceWorkerVersionAttributes;
// ServiceWorkerDispatcherHost is the browser-side endpoint for several IPC
// messages for service workers. There is a 1:1 correspondence between
@@ -91,34 +87,13 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost
// be destroyed.
bool Send(IPC::Message* message) override;
- // Following methods are virtual only for testing.
+ // This method is virtual only for testing.
virtual void RegisterServiceWorkerHandle(
std::unique_ptr<ServiceWorkerHandle> handle);
- virtual void RegisterServiceWorkerRegistrationHandle(
- ServiceWorkerRegistrationHandle* handle);
- virtual void UnregisterServiceWorkerRegistrationHandle(int handle_id);
ServiceWorkerHandle* FindServiceWorkerHandle(int provider_id,
int64_t version_id);
- // Gets or creates the registration and version handles appropriate for
- // representing |registration| inside of |provider_host|. Sets |out_info| and
- // |out_attrs| accordingly for these handles.
- void GetRegistrationObjectInfoAndVersionAttributes(
- base::WeakPtr<ServiceWorkerProviderHost> provider_host,
- ServiceWorkerRegistration* registration,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr* out_info,
- ServiceWorkerVersionAttributes* out_attrs);
-
- // Returns an object info representing |registration|. The object info holds a
- // Mojo connection to the ServiceWorkerRegistrationHandle for the
- // |registration| to ensure the handle stays alive while the object info is
- // alive. A new handle is created if one does not already exist.
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
- CreateRegistrationObjectInfo(
- base::WeakPtr<ServiceWorkerProviderHost> provider_host,
- ServiceWorkerRegistration* registration);
-
ResourceContext* resource_context() { return resource_context_; }
base::WeakPtr<ServiceWorkerDispatcherHost> AsWeakPtr();
@@ -147,28 +122,6 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost
void OnProviderCreated(ServiceWorkerProviderHostInfo info) override;
// IPC Message handlers
- void OnUpdateServiceWorker(int thread_id,
- int request_id,
- int provider_id,
- int64_t registration_id);
- void OnUnregisterServiceWorker(int thread_id,
- int request_id,
- int provider_id,
- int64_t registration_id);
- void OnEnableNavigationPreload(int thread_id,
- int request_id,
- int provider_id,
- int64_t registration_id,
- bool enable);
- void OnGetNavigationPreloadState(int thread_id,
- int request_id,
- int provider_id,
- int64_t registration_id);
- void OnSetNavigationPreloadHeader(int thread_id,
- int request_id,
- int provider_id,
- int64_t registration_id,
- const std::string& value);
void OnCountFeature(int64_t version_id, uint32_t feature);
void OnIncrementServiceWorkerRefCount(int handle_id);
void OnDecrementServiceWorkerRefCount(int handle_id);
@@ -211,42 +164,14 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost
const SourceInfo& source_info,
const StatusCallback& callback,
ServiceWorkerStatusCode status);
+ bool IsValidSourceInfo(const ServiceWorkerClientInfo& source_info);
+ bool IsValidSourceInfo(
+ const blink::mojom::ServiceWorkerObjectInfo& source_info);
void ReleaseSourceInfo(const ServiceWorkerClientInfo& source_info);
- void ReleaseSourceInfo(const ServiceWorkerObjectInfo& source_info);
-
- ServiceWorkerRegistrationHandle* FindRegistrationHandle(
- int provider_id,
- int64_t registration_id);
-
- // Callbacks from ServiceWorkerContextCore
- void UpdateComplete(int thread_id,
- int provider_id,
- int request_id,
- ServiceWorkerStatusCode status,
- const std::string& status_message,
- int64_t registration_id);
- void UnregistrationComplete(int thread_id,
- int request_id,
- ServiceWorkerStatusCode status);
+ void ReleaseSourceInfo(
+ const blink::mojom::ServiceWorkerObjectInfo& source_info);
ServiceWorkerContextCore* GetContext();
- // Returns the provider host with id equal to |provider_id|, or nullptr
- // if the provider host could not be found or is not appropriate for
- // initiating a request such as register/unregister/update.
- ServiceWorkerProviderHost* GetProviderHostForRequest(
- ProviderStatus* out_status,
- int provider_id);
-
- void DidUpdateNavigationPreloadEnabled(int thread_id,
- int request_id,
- int registration_id,
- bool enable,
- ServiceWorkerStatusCode status);
- void DidUpdateNavigationPreloadHeader(int thread_id,
- int request_id,
- int registration_id,
- const std::string& value,
- ServiceWorkerStatusCode status);
const int render_process_id_;
ResourceContext* resource_context_;
@@ -257,10 +182,6 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost
base::IDMap<std::unique_ptr<ServiceWorkerHandle>> handles_;
- using RegistrationHandleMap =
- base::IDMap<std::unique_ptr<ServiceWorkerRegistrationHandle>>;
- RegistrationHandleMap registration_handles_;
-
bool channel_ready_; // True after BrowserMessageFilter::sender_ != NULL.
std::vector<std::unique_ptr<IPC::Message>> pending_messages_;
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 b9cf2c1647b..6e30afaa06d 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
@@ -26,15 +26,14 @@
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/common/service_worker/embedded_worker_messages.h"
#include "content/common/service_worker/service_worker_messages.h"
-#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/mock_resource_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/test/test_content_browser_client.h"
-#include "mojo/edk/embedder/embedder.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
using blink::MessagePortChannel;
@@ -66,8 +65,9 @@ RemoteProviderInfo SetupProviderHostInfoPtrs(
RemoteProviderInfo remote_info;
mojom::ServiceWorkerContainerAssociatedPtr browser_side_client_ptr;
remote_info.client_request =
- mojo::MakeIsolatedRequest(&browser_side_client_ptr);
- host_info->host_request = mojo::MakeIsolatedRequest(&remote_info.host_ptr);
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&browser_side_client_ptr);
+ host_info->host_request =
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&remote_info.host_ptr);
host_info->client_ptr_info = browser_side_client_ptr.PassInterface();
EXPECT_TRUE(host_info->host_request.is_pending());
EXPECT_TRUE(host_info->client_ptr_info.is_valid());
@@ -83,7 +83,7 @@ std::unique_ptr<ServiceWorkerNavigationHandleCore> CreateNavigationHandleCore(
BrowserThread::UI, FROM_HERE,
base::Bind(
[](ServiceWorkerContextWrapper* wrapper) {
- return base::MakeUnique<ServiceWorkerNavigationHandleCore>(nullptr,
+ return std::make_unique<ServiceWorkerNavigationHandleCore>(nullptr,
wrapper);
},
base::RetainedRef(context_wrapper)),
@@ -133,9 +133,12 @@ class FailToStartWorkerTestHelper : public EmbeddedWorkerTestHelper {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info)
override {
mojom::EmbeddedWorkerInstanceHostAssociatedPtr instance_host_ptr;
instance_host_ptr.Bind(std::move(instance_host));
@@ -150,14 +153,10 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override {
- Initialize(base::MakeUnique<EmbeddedWorkerTestHelper>(base::FilePath()));
- mojo::edk::SetDefaultProcessErrorCallback(base::Bind(
- &ServiceWorkerDispatcherHostTest::OnMojoError, base::Unretained(this)));
+ Initialize(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
}
void TearDown() override {
- mojo::edk::SetDefaultProcessErrorCallback(
- mojo::edk::ProcessErrorCallback());
version_ = nullptr;
registration_ = nullptr;
helper_.reset();
@@ -208,7 +207,7 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
EXPECT_EQ(SERVICE_WORKER_OK, status);
}
- void SendProviderCreated(ServiceWorkerProviderType type,
+ void SendProviderCreated(blink::mojom::ServiceWorkerProviderType type,
const GURL& pattern) {
const int64_t kProviderId = 99;
ServiceWorkerProviderHostInfo info(kProviderId, MSG_ROUTING_NONE, type,
@@ -235,115 +234,6 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
context()->AddProviderHost(std::move(host));
}
- void SendRegister(mojom::ServiceWorkerContainerHost* container_host,
- GURL pattern,
- GURL worker_url) {
- auto options = blink::mojom::ServiceWorkerRegistrationOptions::New(pattern);
- container_host->Register(
- worker_url, std::move(options),
- base::BindOnce([](blink::mojom::ServiceWorkerErrorType error,
- const base::Optional<std::string>& error_msg,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
- registration,
- const base::Optional<ServiceWorkerVersionAttributes>&
- attributes) {}));
- base::RunLoop().RunUntilIdle();
- }
-
- void Register(mojom::ServiceWorkerContainerHost* container_host,
- GURL pattern,
- GURL worker_url,
- blink::mojom::ServiceWorkerErrorType expected) {
- blink::mojom::ServiceWorkerErrorType error;
- auto options = blink::mojom::ServiceWorkerRegistrationOptions::New(pattern);
- container_host->Register(
- worker_url, std::move(options),
- base::BindOnce([](blink::mojom::ServiceWorkerErrorType* out_error,
- blink::mojom::ServiceWorkerErrorType error,
- const base::Optional<std::string>& error_msg,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
- registration,
- const base::Optional<ServiceWorkerVersionAttributes>&
- attributes) { *out_error = error; },
- &error));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(expected, error);
- }
-
- void SendUnregister(int64_t provider_id, int64_t registration_id) {
- dispatcher_host_->OnMessageReceived(
- ServiceWorkerHostMsg_UnregisterServiceWorker(-1, -1, provider_id,
- registration_id));
- base::RunLoop().RunUntilIdle();
- }
-
- void Unregister(int64_t provider_id,
- int64_t registration_id,
- uint32_t expected_message) {
- SendUnregister(provider_id, registration_id);
- EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching(
- expected_message));
- dispatcher_host_->ipc_sink()->ClearMessages();
- }
-
- void SendGetRegistration(mojom::ServiceWorkerContainerHost* container_host,
- GURL document_url) {
- container_host->GetRegistration(
- document_url,
- base::BindOnce([](blink::mojom::ServiceWorkerErrorType error,
- const base::Optional<std::string>& error_msg,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
- registration,
- const base::Optional<ServiceWorkerVersionAttributes>&
- attributes) {}));
- base::RunLoop().RunUntilIdle();
- }
-
- void GetRegistration(mojom::ServiceWorkerContainerHost* container_host,
- GURL document_url,
- blink::mojom::ServiceWorkerErrorType expected) {
- blink::mojom::ServiceWorkerErrorType error;
- container_host->GetRegistration(
- document_url,
- base::BindOnce([](blink::mojom::ServiceWorkerErrorType* out_error,
- blink::mojom::ServiceWorkerErrorType error,
- const base::Optional<std::string>& error_msg,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
- registration,
- const base::Optional<ServiceWorkerVersionAttributes>&
- attributes) { *out_error = error; },
- &error));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(expected, error);
- }
-
- void SendGetRegistrations(mojom::ServiceWorkerContainerHost* container_host) {
- container_host->GetRegistrations(base::BindOnce(
- [](blink::mojom::ServiceWorkerErrorType error,
- const base::Optional<std::string>& error_msg,
- base::Optional<std::vector<
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr>> infos,
- const base::Optional<std::vector<ServiceWorkerVersionAttributes>>&
- attrs) {}));
- base::RunLoop().RunUntilIdle();
- }
-
- void GetRegistrations(mojom::ServiceWorkerContainerHost* container_host,
- blink::mojom::ServiceWorkerErrorType expected) {
- blink::mojom::ServiceWorkerErrorType error;
- container_host->GetRegistrations(base::BindOnce(
- [](blink::mojom::ServiceWorkerErrorType* out_error,
- blink::mojom::ServiceWorkerErrorType error,
- const base::Optional<std::string>& error_msg,
- base::Optional<std::vector<
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr>> infos,
- const base::Optional<std::vector<ServiceWorkerVersionAttributes>>&
- attrs) { *out_error = error; },
- &error));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(expected, error);
- }
-
void DispatchExtendableMessageEvent(
scoped_refptr<ServiceWorkerVersion> worker,
const base::string16& message,
@@ -356,13 +246,6 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
sender_provider_host, callback);
}
- std::unique_ptr<ServiceWorkerProviderHost> CreateServiceWorkerProviderHost(
- int provider_id) {
- return CreateProviderHostWithDispatcherHost(
- helper_->mock_render_process_id(), provider_id, context()->AsWeakPtr(),
- kRenderFrameId, dispatcher_host_.get(), &remote_endpoint_);
- }
-
ServiceWorkerRemoteProviderEndpoint PrepareServiceWorkerProviderHost(
int provider_id,
const GURL& document_url) {
@@ -377,10 +260,8 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
return remote_endpoint;
}
- void OnMojoError(const std::string& error) { bad_messages_.push_back(error); }
-
- std::vector<std::string> bad_messages_;
TestBrowserThreadBundle browser_thread_bundle_;
+ base::SimpleTestTickClock tick_clock_;
content::MockResourceContext resource_context_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host_;
@@ -390,254 +271,6 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
ServiceWorkerRemoteProviderEndpoint remote_endpoint_;
};
-class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient {
- public:
- ServiceWorkerTestContentBrowserClient() {}
- bool AllowServiceWorker(
- const GURL& scope,
- const GURL& first_party,
- content::ResourceContext* context,
- const base::Callback<WebContents*(void)>& wc_getter) override {
- return false;
- }
-};
-
-TEST_F(ServiceWorkerDispatcherHostTest,
- Register_ContentSettingsDisallowsServiceWorker) {
- ServiceWorkerTestContentBrowserClient test_browser_client;
- ContentBrowserClient* old_browser_client =
- SetBrowserClientForTesting(&test_browser_client);
-
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com/foo"));
-
- Register(remote_endpoint.host_ptr()->get(), GURL("https://www.example.com/"),
- GURL("https://www.example.com/bar"),
- blink::mojom::ServiceWorkerErrorType::kDisabled);
- GetRegistration(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/"),
- blink::mojom::ServiceWorkerErrorType::kDisabled);
- GetRegistrations(remote_endpoint.host_ptr()->get(),
- blink::mojom::ServiceWorkerErrorType::kDisabled);
-
- // Add a registration into a live registration map so that Unregister() can
- // find it.
- const int64_t kRegistrationId = 999; // Dummy value
- scoped_refptr<ServiceWorkerRegistration> registration(
- new ServiceWorkerRegistration(
- blink::mojom::ServiceWorkerRegistrationOptions(
- GURL("https://www.example.com/")),
- kRegistrationId, context()->AsWeakPtr()));
- Unregister(kProviderId, kRegistrationId,
- ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID);
-
- SetBrowserClientForTesting(old_browser_client);
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, Register_HTTPS) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com/foo"));
-
- Register(remote_endpoint.host_ptr()->get(), GURL("https://www.example.com/"),
- GURL("https://www.example.com/bar"),
- blink::mojom::ServiceWorkerErrorType::kNone);
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, Register_NonSecureTransportLocalhost) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("http://127.0.0.3:81/foo"));
-
- Register(remote_endpoint.host_ptr()->get(), GURL("http://127.0.0.3:81/bar"),
- GURL("http://127.0.0.3:81/baz"),
- blink::mojom::ServiceWorkerErrorType::kNone);
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, Register_InvalidScopeShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com/foo"));
-
- ASSERT_TRUE(bad_messages_.empty());
- SendRegister(remote_endpoint.host_ptr()->get(), GURL(""),
- GURL("https://www.example.com/bar/hoge.js"));
- EXPECT_EQ(1u, bad_messages_.size());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, Register_InvalidScriptShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com/foo"));
-
- ASSERT_TRUE(bad_messages_.empty());
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/bar/"), GURL(""));
- EXPECT_EQ(1u, bad_messages_.size());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, Register_NonSecureOriginShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("http://www.example.com/foo"));
-
- ASSERT_TRUE(bad_messages_.empty());
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("http://www.example.com/"),
- GURL("http://www.example.com/bar"));
- EXPECT_EQ(1u, bad_messages_.size());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, Register_CrossOriginShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com/foo"));
-
- ASSERT_TRUE(bad_messages_.empty());
- // Script has a different host
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/"),
- GURL("https://foo.example.com/bar"));
- EXPECT_EQ(1u, bad_messages_.size());
-
- // Scope has a different host
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://foo.example.com/"),
- GURL("https://www.example.com/bar"));
- EXPECT_EQ(2u, bad_messages_.size());
-
- // Script has a different port
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/"),
- GURL("https://www.example.com:8080/bar"));
- EXPECT_EQ(3u, bad_messages_.size());
-
- // Scope has a different transport
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("wss://www.example.com/"),
- GURL("https://www.example.com/bar"));
- EXPECT_EQ(4u, bad_messages_.size());
-
- // Script and scope have a different host but match each other
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://foo.example.com/"),
- GURL("https://foo.example.com/bar"));
- EXPECT_EQ(5u, bad_messages_.size());
-
- // Script and scope URLs are invalid
- SendRegister(remote_endpoint.host_ptr()->get(), GURL(), GURL("h@ttps://@"));
- EXPECT_EQ(6u, bad_messages_.size());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, Register_BadCharactersShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com"));
-
- ASSERT_TRUE(bad_messages_.empty());
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/%2f"),
- GURL("https://www.example.com/"));
- EXPECT_EQ(1u, bad_messages_.size());
-
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/%2F"),
- GURL("https://www.example.com/"));
- EXPECT_EQ(2u, bad_messages_.size());
-
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/"),
- GURL("https://www.example.com/%2f"));
- EXPECT_EQ(3u, bad_messages_.size());
-
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/%5c"),
- GURL("https://www.example.com/"));
- EXPECT_EQ(4u, bad_messages_.size());
-
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/"),
- GURL("https://www.example.com/%5c"));
- EXPECT_EQ(5u, bad_messages_.size());
-
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/"),
- GURL("https://www.example.com/%5C"));
- EXPECT_EQ(6u, bad_messages_.size());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, Register_FileSystemDocumentShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(
- kProviderId, GURL("filesystem:https://www.example.com/temporary/a"));
-
- ASSERT_TRUE(bad_messages_.empty());
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("filesystem:https://www.example.com/temporary/"),
- GURL("https://www.example.com/temporary/bar"));
- EXPECT_EQ(1u, bad_messages_.size());
-
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/temporary/"),
- GURL("filesystem:https://www.example.com/temporary/bar"));
- EXPECT_EQ(2u, bad_messages_.size());
-
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("filesystem:https://www.example.com/temporary/"),
- GURL("filesystem:https://www.example.com/temporary/bar"));
- EXPECT_EQ(3u, bad_messages_.size());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest,
- Register_FileSystemScriptOrScopeShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(
- kProviderId, GURL("https://www.example.com/temporary/"));
-
- ASSERT_TRUE(bad_messages_.empty());
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("filesystem:https://www.example.com/temporary/"),
- GURL("https://www.example.com/temporary/bar"));
- EXPECT_EQ(1u, bad_messages_.size());
-
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/temporary/"),
- GURL("filesystem:https://www.example.com/temporary/bar"));
- EXPECT_EQ(2u, bad_messages_.size());
-
- SendRegister(remote_endpoint.host_ptr()->get(),
- GURL("filesystem:https://www.example.com/temporary/"),
- GURL("filesystem:https://www.example.com/temporary/bar"));
- EXPECT_EQ(3u, bad_messages_.size());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, EarlyContextDeletion) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com/foo"));
-
- helper_->ShutdownContext();
-
- // Let the shutdown reach the simulated IO thread.
- base::RunLoop().RunUntilIdle();
-
- // Because ServiceWorkerContextCore owns ServiceWorkerProviderHost, our
- // ServiceWorkerProviderHost instance has destroyed.
- EXPECT_TRUE(remote_endpoint.host_ptr()->encountered_error());
-}
-
TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) {
// |kProviderId| must be -2 when PlzNavigate is enabled to match the
// pre-created provider host. Otherwise |kProviderId| is just a dummy value.
@@ -645,15 +278,18 @@ TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) {
int process_id = helper_->mock_render_process_id();
// Setup ServiceWorkerProviderHostInfo.
- ServiceWorkerProviderHostInfo host_info_1(kProviderId, 1 /* route_id */,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- true /* is_parent_frame_secure */);
- ServiceWorkerProviderHostInfo host_info_2(kProviderId, 1 /* route_id */,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- true /* is_parent_frame_secure */);
- ServiceWorkerProviderHostInfo host_info_3(kProviderId, 1 /* route_id */,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- true /* is_parent_frame_secure */);
+ ServiceWorkerProviderHostInfo host_info_1(
+ kProviderId, 1 /* route_id */,
+ blink::mojom::ServiceWorkerProviderType::kForWindow,
+ true /* is_parent_frame_secure */);
+ ServiceWorkerProviderHostInfo host_info_2(
+ kProviderId, 1 /* route_id */,
+ blink::mojom::ServiceWorkerProviderType::kForWindow,
+ true /* is_parent_frame_secure */);
+ ServiceWorkerProviderHostInfo host_info_3(
+ kProviderId, 1 /* route_id */,
+ blink::mojom::ServiceWorkerProviderType::kForWindow,
+ true /* is_parent_frame_secure */);
RemoteProviderInfo remote_info_1 = SetupProviderHostInfoPtrs(&host_info_1);
RemoteProviderInfo remote_info_2 = SetupProviderHostInfoPtrs(&host_info_2);
RemoteProviderInfo remote_info_3 = SetupProviderHostInfoPtrs(&host_info_3);
@@ -696,87 +332,13 @@ TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) {
base::Callback<WebContents*(void)>()));
}
- // Deletion of the dispatcher_host should cause provider hosts for
- // that process to have a null dispatcher host.
+ // Deletion of the dispatcher_host should cause providers for that
+ // process to get deleted as well.
dispatcher_host_->OnProviderCreated(std::move(host_info_3));
- ServiceWorkerProviderHost* host =
- context()->GetProviderHost(process_id, kProviderId);
- EXPECT_TRUE(host->dispatcher_host());
+ EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId));
EXPECT_TRUE(dispatcher_host_->HasOneRef());
dispatcher_host_ = nullptr;
- host = context()->GetProviderHost(process_id, kProviderId);
- ASSERT_TRUE(host);
- EXPECT_FALSE(host->dispatcher_host());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_SameOrigin) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com/foo"));
-
- GetRegistration(remote_endpoint.host_ptr()->get(),
- GURL("https://www.example.com/"),
- blink::mojom::ServiceWorkerErrorType::kNone);
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_CrossOriginShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com/foo"));
-
- ASSERT_TRUE(bad_messages_.empty());
- SendGetRegistration(remote_endpoint.host_ptr()->get(),
- GURL("https://foo.example.com/"));
- EXPECT_EQ(1u, bad_messages_.size());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest,
- GetRegistration_InvalidScopeShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com/foo"));
-
- ASSERT_TRUE(bad_messages_.empty());
- SendGetRegistration(remote_endpoint.host_ptr()->get(), GURL(""));
- EXPECT_EQ(1u, bad_messages_.size());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest,
- GetRegistration_NonSecureOriginShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("http://www.example.com/foo"));
-
- ASSERT_TRUE(bad_messages_.empty());
- SendGetRegistration(remote_endpoint.host_ptr()->get(),
- GURL("http://www.example.com/"));
- EXPECT_EQ(1u, bad_messages_.size());
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest, GetRegistrations_SecureOrigin) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("https://www.example.com/foo"));
-
- GetRegistrations(remote_endpoint.host_ptr()->get(),
- blink::mojom::ServiceWorkerErrorType::kNone);
-}
-
-TEST_F(ServiceWorkerDispatcherHostTest,
- GetRegistrations_NonSecureOriginShouldFail) {
- const int64_t kProviderId = 99; // Dummy value
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
- PrepareServiceWorkerProviderHost(kProviderId,
- GURL("http://www.example.com/foo"));
-
- ASSERT_TRUE(bad_messages_.empty());
- SendGetRegistrations(remote_endpoint.host_ptr()->get());
- EXPECT_EQ(1u, bad_messages_.size());
+ EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId));
}
TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
@@ -784,7 +346,8 @@ TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
GURL script_url = GURL("http://www.example.com/service_worker.js");
int process_id = helper_->mock_render_process_id();
- SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_WINDOW, pattern);
+ SendProviderCreated(blink::mojom::ServiceWorkerProviderType::kForWindow,
+ pattern);
SetUpRegistration(pattern, script_url);
int64_t provider_id = provider_host_->provider_id();
@@ -804,13 +367,8 @@ TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
// Simulate the render process crashing.
dispatcher_host_->OnFilterRemoved();
- // The provider host still exists, since it will clean itself up when its Mojo
- // connection to the renderer breaks. But it should no longer be using the
- // dispatcher host.
- ServiceWorkerProviderHost* host =
- context()->GetProviderHost(process_id, provider_id);
- ASSERT_TRUE(host);
- EXPECT_FALSE(host->dispatcher_host());
+ // The dispatcher host should have removed the provider host.
+ EXPECT_FALSE(context()->GetProviderHost(process_id, provider_id));
// The EmbeddedWorkerInstance should still think it is running, since it will
// clean itself up when its Mojo connection to the renderer breaks.
@@ -824,10 +382,13 @@ TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
helper_.get()));
new_dispatcher_host->Init(context_wrapper());
- // To show the new dispatcher can operate, simulate provider creation.
- ServiceWorkerProviderHostInfo host_info(provider_id + 1, MSG_ROUTING_NONE,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- true /* is_parent_frame_secure */);
+ // To show the new dispatcher can operate, simulate provider creation. Since
+ // the old dispatcher cleaned up the old provider host, the new one won't
+ // complain.
+ ServiceWorkerProviderHostInfo host_info(
+ provider_id, MSG_ROUTING_NONE,
+ blink::mojom::ServiceWorkerProviderType::kForWindow,
+ true /* is_parent_frame_secure */);
ServiceWorkerRemoteProviderEndpoint remote_endpoint;
remote_endpoint.BindWithProviderHostInfo(&host_info);
new_dispatcher_host->OnProviderCreated(std::move(host_info));
@@ -853,9 +414,8 @@ TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent) {
const int ref_count = sender_worker_handle->ref_count();
// Set mock clock on version_ to check timeout behavior.
- base::SimpleTestTickClock* tick_clock = new base::SimpleTestTickClock();
- tick_clock->SetNowTicks(base::TimeTicks::Now());
- version_->SetTickClockForTesting(base::WrapUnique(tick_clock));
+ tick_clock_.SetNowTicks(base::TimeTicks::Now());
+ version_->SetTickClockForTesting(&tick_clock_);
// Make sure worker has a non-zero timeout.
bool called = false;
@@ -871,7 +431,7 @@ TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent) {
base::TimeDelta::FromSeconds(10), ServiceWorkerVersion::KILL_ON_TIMEOUT);
// Advance clock by a couple seconds.
- tick_clock->Advance(base::TimeDelta::FromSeconds(4));
+ tick_clock_.Advance(base::TimeDelta::FromSeconds(4));
base::TimeDelta remaining_time = version_->remaining_timeout();
EXPECT_EQ(base::TimeDelta::FromSeconds(6), remaining_time);
@@ -881,8 +441,9 @@ TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent) {
called = false;
status = SERVICE_WORKER_ERROR_MAX_VALUE;
DispatchExtendableMessageEvent(
- version_, base::string16(), url::Origin(version_->scope().GetOrigin()),
- ports, provider_host_, base::Bind(&SaveStatusCallback, &called, &status));
+ version_, base::string16(),
+ url::Origin::Create(version_->scope().GetOrigin()), ports, provider_host_,
+ base::Bind(&SaveStatusCallback, &called, &status));
EXPECT_EQ(ref_count + 1, sender_worker_handle->ref_count());
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
@@ -899,7 +460,8 @@ TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent_Fail) {
GURL script_url = GURL("http://www.example.com/service_worker.js");
Initialize(base::WrapUnique(new FailToStartWorkerTestHelper));
- SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_WORKER, pattern);
+ SendProviderCreated(blink::mojom::ServiceWorkerProviderType::kForSharedWorker,
+ pattern);
SetUpRegistration(pattern, script_url);
// Try to dispatch ExtendableMessageEvent. This should fail to start the
@@ -909,8 +471,9 @@ TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent_Fail) {
bool called = false;
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
DispatchExtendableMessageEvent(
- version_, base::string16(), url::Origin(version_->scope().GetOrigin()),
- ports, provider_host_, base::Bind(&SaveStatusCallback, &called, &status));
+ version_, base::string16(),
+ url::Origin::Create(version_->scope().GetOrigin()), ports, provider_host_,
+ base::Bind(&SaveStatusCallback, &called, &status));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status);
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 f7712a55e4f..1f8f966e67d 100644
--- a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -6,6 +6,7 @@
#include <string>
#include <utility>
+#include <vector>
#include "base/bind.h"
#include "base/containers/queue.h"
@@ -116,12 +117,12 @@ void NotifyNavigationPreloadResponseReceivedOnUI(
}
void NotifyNavigationPreloadCompletedOnUI(
- const ResourceRequestCompletionStatus& completion_status,
+ const network::URLLoaderCompletionStatus& status,
const std::pair<int, int>& worker_id,
const std::string& request_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (ServiceWorkerDevToolsAgentHost* agent_host = GetAgentHost(worker_id))
- agent_host->NavigationPreloadCompleted(request_id, completion_status);
+ agent_host->NavigationPreloadCompleted(request_id, status);
}
// DelegatingURLLoaderClient is the URLLoaderClient for the navigation preload
@@ -144,7 +145,7 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
~DelegatingURLLoaderClient() override {
if (!completed_) {
// Let the service worker know that the request has been canceled.
- ResourceRequestCompletionStatus status;
+ network::URLLoaderCompletionStatus status;
status.error_code = net::ERR_ABORTED;
client_->OnComplete(status);
AddDevToolsCallback(
@@ -152,10 +153,10 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
}
}
- void MayBeReportToDevTools(WorkerId worker_id, int fetch_event_id) {
+ void MaybeReportToDevTools(WorkerId worker_id, int fetch_event_id) {
worker_id_ = worker_id;
devtools_request_id_ = base::StringPrintf("preload-%d", fetch_event_id);
- MayBeRunDevToolsCallbacks();
+ MaybeRunDevToolsCallbacks();
}
void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {
@@ -192,7 +193,7 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
client_->OnReceiveRedirect(redirect_info, head);
AddDevToolsCallback(
base::Bind(&NotifyNavigationPreloadResponseReceivedOnUI, url_, head));
- ResourceRequestCompletionStatus status;
+ network::URLLoaderCompletionStatus status;
AddDevToolsCallback(
base::Bind(&NotifyNavigationPreloadCompletedOnUI, status));
}
@@ -200,14 +201,13 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
mojo::ScopedDataPipeConsumerHandle body) override {
client_->OnStartLoadingResponseBody(std::move(body));
}
- void OnComplete(
- const ResourceRequestCompletionStatus& completion_status) override {
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override {
if (completed_)
return;
completed_ = true;
- client_->OnComplete(completion_status);
+ client_->OnComplete(status);
AddDevToolsCallback(
- base::Bind(&NotifyNavigationPreloadCompletedOnUI, completion_status));
+ base::Bind(&NotifyNavigationPreloadCompletedOnUI, status));
}
void Bind(mojom::URLLoaderClientPtr* ptr_info) {
@@ -215,7 +215,7 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
}
private:
- void MayBeRunDevToolsCallbacks() {
+ void MaybeRunDevToolsCallbacks() {
if (!worker_id_)
return;
while (!devtools_callbacks.empty()) {
@@ -229,7 +229,7 @@ class DelegatingURLLoaderClient final : public mojom::URLLoaderClient {
void AddDevToolsCallback(
base::Callback<void(const WorkerId&, const std::string&)> callback) {
devtools_callbacks.push(callback);
- MayBeRunDevToolsCallbacks();
+ MaybeRunDevToolsCallbacks();
}
mojo::Binding<mojom::URLLoaderClient> binding_;
@@ -273,12 +273,13 @@ std::unique_ptr<base::Value> NetLogServiceWorkerStatusCallback(
std::unique_ptr<base::Value> NetLogFetchEventCallback(
ServiceWorkerStatusCode status,
- ServiceWorkerFetchEventResult result,
+ ServiceWorkerFetchDispatcher::FetchEventResult result,
net::NetLogCaptureMode) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
dict->SetString("status", ServiceWorkerStatusToString(status));
- dict->SetBoolean("has_response",
- result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE);
+ dict->SetBoolean(
+ "has_response",
+ result == ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse);
return std::move(dict);
}
@@ -289,13 +290,6 @@ void EndNetLogEventWithServiceWorkerStatus(const net::NetLogWithSource& net_log,
base::Bind(&NetLogServiceWorkerStatusCallback, status));
}
-ServiceWorkerMetrics::EventType FetchTypeToWaitUntilEventType(
- ServiceWorkerFetchType type) {
- if (type == ServiceWorkerFetchType::FOREIGN_FETCH)
- return ServiceWorkerMetrics::EventType::FOREIGN_FETCH_WAITUNTIL;
- return ServiceWorkerMetrics::EventType::FETCH_WAITUNTIL;
-}
-
const net::NetworkTrafficAnnotationTag kNavigationPreloadTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("service_worker_navigation_preload",
R"(
@@ -367,16 +361,22 @@ class ServiceWorkerFetchDispatcher::ResponseCallback
base::Time dispatch_event_time) override {
HandleResponse(fetch_dispatcher_, version_, fetch_event_id_, response,
nullptr /* body_as_stream */, nullptr /* body_as_blob */,
- SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
- dispatch_event_time);
+ FetchEventResult::kGotResponse, dispatch_event_time);
}
void OnResponseBlob(const ServiceWorkerResponse& response,
- storage::mojom::BlobPtr body_as_blob,
+ blink::mojom::BlobPtr body_as_blob,
base::Time dispatch_event_time) override {
HandleResponse(fetch_dispatcher_, version_, fetch_event_id_, response,
nullptr /* body_as_stream */, std::move(body_as_blob),
- SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
- dispatch_event_time);
+ FetchEventResult::kGotResponse, dispatch_event_time);
+ }
+ void OnResponseLegacyBlob(const ServiceWorkerResponse& response,
+ base::Time dispatch_event_time,
+ OnResponseLegacyBlobCallback callback) override {
+ HandleResponse(fetch_dispatcher_, version_, fetch_event_id_, response,
+ nullptr /* body_as_stream */, nullptr /* body_as_blob */,
+ FetchEventResult::kGotResponse, dispatch_event_time);
+ std::move(callback).Run();
}
void OnResponseStream(
const ServiceWorkerResponse& response,
@@ -384,14 +384,13 @@ class ServiceWorkerFetchDispatcher::ResponseCallback
base::Time dispatch_event_time) override {
HandleResponse(fetch_dispatcher_, version_, fetch_event_id_, response,
std::move(body_as_stream), nullptr /* body_as_blob */,
- SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
- dispatch_event_time);
+ FetchEventResult::kGotResponse, dispatch_event_time);
}
void OnFallback(base::Time dispatch_event_time) override {
- HandleResponse(
- fetch_dispatcher_, version_, fetch_event_id_, ServiceWorkerResponse(),
- nullptr /* body_as_stream */, nullptr /* body_as_blob */,
- SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, dispatch_event_time);
+ HandleResponse(fetch_dispatcher_, version_, fetch_event_id_,
+ ServiceWorkerResponse(), nullptr /* body_as_stream */,
+ nullptr /* body_as_blob */,
+ FetchEventResult::kShouldFallback, dispatch_event_time);
}
private:
@@ -403,13 +402,12 @@ class ServiceWorkerFetchDispatcher::ResponseCallback
base::Optional<int> fetch_event_id,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob,
- ServiceWorkerFetchEventResult fetch_result,
+ blink::mojom::BlobPtr body_as_blob,
+ FetchEventResult fetch_result,
base::Time dispatch_event_time) {
- if (!version->FinishRequest(
- fetch_event_id.value(),
- fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
- dispatch_event_time))
+ if (!version->FinishRequest(fetch_event_id.value(),
+ fetch_result == FetchEventResult::kGotResponse,
+ dispatch_event_time))
NOTREACHED() << "Should only receive one reply per event";
// |fetch_dispatcher| is null if the URLRequest was killed.
if (!fetch_dispatcher)
@@ -443,9 +441,9 @@ class ServiceWorkerFetchDispatcher::URLLoaderAssets
url_loader_(std::move(url_loader)),
url_loader_client_(std::move(url_loader_client)) {}
- void MayBeReportToDevTools(std::pair<int, int> worker_id,
+ void MaybeReportToDevTools(std::pair<int, int> worker_id,
int fetch_event_id) {
- url_loader_client_->MayBeReportToDevTools(worker_id, fetch_event_id);
+ url_loader_client_->MaybeReportToDevTools(worker_id, fetch_event_id);
}
private:
@@ -459,20 +457,44 @@ class ServiceWorkerFetchDispatcher::URLLoaderAssets
DISALLOW_COPY_AND_ASSIGN(URLLoaderAssets);
};
+// S13nServiceWorker
ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher(
- std::unique_ptr<ServiceWorkerFetchRequest> request,
- ServiceWorkerVersion* version,
- ResourceType resource_type,
+ std::unique_ptr<ResourceRequest> request,
+ scoped_refptr<ServiceWorkerVersion> version,
const base::Optional<base::TimeDelta>& timeout,
const net::NetLogWithSource& net_log,
- const base::Closure& prepare_callback,
- const FetchCallback& fetch_callback)
- : version_(version),
+ base::OnceClosure prepare_callback,
+ FetchCallback fetch_callback)
+ : request_(std::move(request)),
+ version_(std::move(version)),
+ resource_type_(request_->resource_type),
net_log_(net_log),
- prepare_callback_(prepare_callback),
- fetch_callback_(fetch_callback),
- request_(std::move(request)),
+ prepare_callback_(std::move(prepare_callback)),
+ fetch_callback_(std::move(fetch_callback)),
+ timeout_(timeout),
+ did_complete_(false),
+ weak_factory_(this) {
+ net_log_.BeginEvent(net::NetLogEventType::SERVICE_WORKER_DISPATCH_FETCH_EVENT,
+ net::NetLog::StringCallback(
+ "event_type", ServiceWorkerMetrics::EventTypeToString(
+ GetEventType())));
+}
+
+// Non-S13nServiceWorker
+ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher(
+ std::unique_ptr<ServiceWorkerFetchRequest> legacy_request,
+ scoped_refptr<ServiceWorkerVersion> version,
+ ResourceType resource_type,
+ const base::Optional<base::TimeDelta>& timeout,
+ const net::NetLogWithSource& net_log,
+ base::OnceClosure prepare_callback,
+ FetchCallback fetch_callback)
+ : legacy_request_(std::move(legacy_request)),
+ version_(std::move(version)),
resource_type_(resource_type),
+ net_log_(net_log),
+ prepare_callback_(std::move(prepare_callback)),
+ fetch_callback_(std::move(fetch_callback)),
timeout_(timeout),
did_complete_(false),
weak_factory_(this) {
@@ -547,17 +569,20 @@ void ServiceWorkerFetchDispatcher::DidFailToStartWorker(
void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status())
<< "Worker stopped too soon after it was started.";
- DCHECK(!prepare_callback_.is_null());
- base::Closure prepare_callback = prepare_callback_;
- prepare_callback.Run();
-
- mojom::ServiceWorkerFetchResponseCallbackPtr mojo_response_callback_ptr;
- auto response_callback = base::MakeUnique<ResponseCallback>(
- mojo::MakeRequest(&mojo_response_callback_ptr),
- weak_factory_.GetWeakPtr(), version_.get());
- ResponseCallback* response_callback_rawptr = response_callback.get();
+ // Run callback to say that the fetch event will be dispatched.
+ DCHECK(prepare_callback_);
+ std::move(prepare_callback_).Run();
net_log_.BeginEvent(net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT);
+
+ // Set up for receiving the response.
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_ptr;
+ auto response_callback = std::make_unique<ResponseCallback>(
+ mojo::MakeRequest(&response_callback_ptr), weak_factory_.GetWeakPtr(),
+ version_.get());
+ ResponseCallback* response_callback_rawptr = response_callback.get();
+
+ // Set up the fetch event.
int fetch_event_id;
int event_finish_id;
if (timeout_) {
@@ -568,7 +593,7 @@ void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
std::move(response_callback)),
*timeout_, ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
event_finish_id = version_->StartRequestWithCustomTimeout(
- FetchTypeToWaitUntilEventType(request_->fetch_type),
+ ServiceWorkerMetrics::EventType::FETCH_WAITUNTIL,
base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback), *timeout_,
ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
} else {
@@ -578,30 +603,43 @@ void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
weak_factory_.GetWeakPtr(),
std::move(response_callback)));
event_finish_id = version_->StartRequest(
- FetchTypeToWaitUntilEventType(request_->fetch_type),
+ ServiceWorkerMetrics::EventType::FETCH_WAITUNTIL,
base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
}
-
response_callback_rawptr->set_fetch_event_id(fetch_event_id);
+ // Report navigation preload to DevTools if needed.
if (url_loader_assets_) {
- url_loader_assets_->MayBeReportToDevTools(
+ url_loader_assets_->MaybeReportToDevTools(
std::make_pair(
version_->embedded_worker()->process_id(),
version_->embedded_worker()->worker_devtools_agent_route_id()),
fetch_event_id);
}
+ // Dispatch the fetch event.
// |event_dispatcher| is owned by |version_|. So it is safe to pass the
// unretained raw pointer of |version_| to OnFetchEventFinished callback.
// Pass |url_loader_assets_| to the callback to keep the URL loader related
// assets alive while the FetchEvent is ongoing in the service worker.
- version_->event_dispatcher()->DispatchFetchEvent(
- fetch_event_id, *request_, std::move(preload_handle_),
- std::move(mojo_response_callback_ptr),
- base::BindOnce(&ServiceWorkerFetchDispatcher::OnFetchEventFinished,
- base::Unretained(version_.get()), event_finish_id,
- url_loader_assets_));
+ if (ServiceWorkerUtils::IsServicificationEnabled()) {
+ DCHECK(request_);
+ DCHECK(!legacy_request_);
+ version_->event_dispatcher()->DispatchFetchEvent(
+ *request_, std::move(preload_handle_), std::move(response_callback_ptr),
+ base::BindOnce(&ServiceWorkerFetchDispatcher::OnFetchEventFinished,
+ base::Unretained(version_.get()), event_finish_id,
+ url_loader_assets_));
+ } else {
+ DCHECK(!request_);
+ DCHECK(legacy_request_);
+ version_->event_dispatcher()->DispatchLegacyFetchEvent(
+ *legacy_request_, std::move(preload_handle_),
+ std::move(response_callback_ptr),
+ base::BindOnce(&ServiceWorkerFetchDispatcher::OnFetchEventFinished,
+ base::Unretained(version_.get()), event_finish_id,
+ url_loader_assets_));
+ }
}
void ServiceWorkerFetchDispatcher::DidFailToDispatch(
@@ -614,17 +652,16 @@ void ServiceWorkerFetchDispatcher::DidFailToDispatch(
void ServiceWorkerFetchDispatcher::DidFail(ServiceWorkerStatusCode status) {
DCHECK_NE(SERVICE_WORKER_OK, status);
- Complete(status, SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
- ServiceWorkerResponse(), nullptr /* body_as_stream */,
- nullptr /* body_as_blob */);
+ Complete(status, FetchEventResult::kShouldFallback, ServiceWorkerResponse(),
+ nullptr /* body_as_stream */, nullptr /* body_as_blob */);
}
void ServiceWorkerFetchDispatcher::DidFinish(
int request_id,
- ServiceWorkerFetchEventResult fetch_result,
+ FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob) {
+ blink::mojom::BlobPtr body_as_blob) {
net_log_.EndEvent(net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT);
Complete(SERVICE_WORKER_OK, fetch_result, response, std::move(body_as_stream),
std::move(body_as_blob));
@@ -632,21 +669,20 @@ void ServiceWorkerFetchDispatcher::DidFinish(
void ServiceWorkerFetchDispatcher::Complete(
ServiceWorkerStatusCode status,
- ServiceWorkerFetchEventResult fetch_result,
+ FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob) {
- DCHECK(!fetch_callback_.is_null());
+ blink::mojom::BlobPtr body_as_blob) {
+ DCHECK(fetch_callback_);
did_complete_ = true;
net_log_.EndEvent(
net::NetLogEventType::SERVICE_WORKER_DISPATCH_FETCH_EVENT,
base::Bind(&NetLogFetchEventCallback, status, fetch_result));
- FetchCallback fetch_callback = fetch_callback_;
- scoped_refptr<ServiceWorkerVersion> version = version_;
- fetch_callback.Run(status, fetch_result, response, std::move(body_as_stream),
- std::move(body_as_blob), version);
+ std::move(fetch_callback_)
+ .Run(status, fetch_result, response, std::move(body_as_stream),
+ std::move(body_as_blob), version_);
}
bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
@@ -659,7 +695,7 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
if (!version_->navigation_preload_state().enabled)
return false;
// TODO(horo): Currently NavigationPreload doesn't support request body.
- if (!request_->blob_uuid.empty())
+ if (!legacy_request_->blob_uuid.empty())
return false;
ResourceRequestInfoImpl* original_info =
@@ -685,9 +721,10 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
request.method = original_request->method();
request.url = original_request->url();
// TODO(horo): Set site_for_cookies to support Same-site Cookies.
- request.request_initiator = original_request->initiator().has_value()
- ? original_request->initiator()
- : url::Origin(original_request->url());
+ request.request_initiator =
+ original_request->initiator().has_value()
+ ? original_request->initiator()
+ : url::Origin::Create(original_request->url());
request.referrer = GURL(original_request->referrer());
request.referrer_policy = original_info->GetReferrerPolicy();
request.visibility_state = original_info->GetVisibilityState();
@@ -718,7 +755,7 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
mojom::URLLoaderClientPtr url_loader_client_ptr;
preload_handle_->url_loader_client_request =
mojo::MakeRequest(&url_loader_client_ptr);
- auto url_loader_client = base::MakeUnique<DelegatingURLLoaderClient>(
+ auto url_loader_client = std::make_unique<DelegatingURLLoaderClient>(
std::move(url_loader_client_ptr), std::move(on_response), request);
mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass;
url_loader_client->Bind(&url_loader_client_ptr_to_pass);
@@ -733,7 +770,8 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
auto url_loader = std::make_unique<DelegatingURLLoader>(
std::move(url_loader_associated_ptr));
- preload_handle_->url_loader = url_loader->CreateInterfacePtrAndBind();
+ preload_handle_->url_loader =
+ url_loader->CreateInterfacePtrAndBind().PassInterface();
url_loader_assets_ = base::MakeRefCounted<URLLoaderAssets>(
std::move(url_loader_factory), std::move(url_loader),
std::move(url_loader_client));
@@ -752,7 +790,7 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreloadWithURLLoader(
if (!version_->navigation_preload_state().enabled)
return false;
// TODO(horo): Currently NavigationPreload doesn't support request body.
- if (!request_->blob_uuid.empty())
+ if (request_->request_body)
return false;
ResourceRequest resource_request(original_request);
@@ -779,7 +817,7 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreloadWithURLLoader(
mojom::URLLoaderClientPtr url_loader_client_ptr;
preload_handle_->url_loader_client_request =
mojo::MakeRequest(&url_loader_client_ptr);
- auto url_loader_client = base::MakeUnique<DelegatingURLLoaderClient>(
+ auto url_loader_client = std::make_unique<DelegatingURLLoaderClient>(
std::move(url_loader_client_ptr), std::move(on_response),
resource_request);
@@ -788,7 +826,7 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreloadWithURLLoader(
mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass;
url_loader_client->Bind(&url_loader_client_ptr_to_pass);
mojom::URLLoaderPtr url_loader_associated_ptr;
- url_loader_factory_getter->GetNetworkFactory()->get()->CreateLoaderAndStart(
+ url_loader_factory_getter->GetNetworkFactory()->CreateLoaderAndStart(
mojo::MakeRequest(&url_loader_associated_ptr), -1 /* routing_id? */,
-1 /* request_id? */, mojom::kURLLoadOptionNone, resource_request,
std::move(url_loader_client_ptr_to_pass),
@@ -799,7 +837,8 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreloadWithURLLoader(
// DelegatingURLLoaderClient.
auto url_loader = std::make_unique<DelegatingURLLoader>(
std::move(url_loader_associated_ptr));
- preload_handle_->url_loader = url_loader->CreateInterfacePtrAndBind();
+ preload_handle_->url_loader =
+ url_loader->CreateInterfacePtrAndBind().PassInterface();
DCHECK(!url_loader_assets_);
// Unlike the non-S13N code path, we don't own the URLLoaderFactory being used
@@ -812,10 +851,14 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreloadWithURLLoader(
return true;
}
+ServiceWorkerFetchType ServiceWorkerFetchDispatcher::GetFetchType() const {
+ if (ServiceWorkerUtils::IsServicificationEnabled())
+ return ServiceWorkerFetchType::FETCH;
+ return legacy_request_->fetch_type;
+}
+
ServiceWorkerMetrics::EventType ServiceWorkerFetchDispatcher::GetEventType()
const {
- if (request_->fetch_type == ServiceWorkerFetchType::FOREIGN_FETCH)
- return ServiceWorkerMetrics::EventType::FOREIGN_FETCH;
return ResourceTypeToEventType(resource_type_);
}
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 32c136c53ce..0cd984b8846 100644
--- a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
+++ b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -23,7 +23,7 @@
#include "content/public/common/url_loader_factory.mojom.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/log/net_log_with_source.h"
-#include "storage/public/interfaces/blobs.mojom.h"
+#include "third_party/WebKit/common/blob/blob.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
namespace net {
@@ -38,22 +38,38 @@ class URLLoaderFactoryGetter;
// A helper class to dispatch fetch event to a service worker.
class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
public:
+ // Indicates how the service worker handled a fetch event.
+ enum class FetchEventResult {
+ // Browser should fallback to native fetch.
+ kShouldFallback,
+ // Service worker provided a ServiceWorkerResponse.
+ kGotResponse
+ };
+
using FetchCallback =
- base::Callback<void(ServiceWorkerStatusCode,
- ServiceWorkerFetchEventResult,
- const ServiceWorkerResponse&,
- blink::mojom::ServiceWorkerStreamHandlePtr,
- storage::mojom::BlobPtr,
- const scoped_refptr<ServiceWorkerVersion>&)>;
+ base::OnceCallback<void(ServiceWorkerStatusCode,
+ FetchEventResult,
+ const ServiceWorkerResponse&,
+ blink::mojom::ServiceWorkerStreamHandlePtr,
+ blink::mojom::BlobPtr,
+ scoped_refptr<ServiceWorkerVersion>)>;
+ // S13nServiceWorker
+ ServiceWorkerFetchDispatcher(std::unique_ptr<ResourceRequest> request,
+ scoped_refptr<ServiceWorkerVersion> version,
+ const base::Optional<base::TimeDelta>& timeout,
+ const net::NetLogWithSource& net_log,
+ base::OnceClosure prepare_callback,
+ FetchCallback fetch_callback);
+ // Non-S13nServiceWorker
ServiceWorkerFetchDispatcher(
std::unique_ptr<ServiceWorkerFetchRequest> request,
- ServiceWorkerVersion* version,
+ scoped_refptr<ServiceWorkerVersion> version,
ResourceType resource_type,
const base::Optional<base::TimeDelta>& timeout,
const net::NetLogWithSource& net_log,
- const base::Closure& prepare_callback,
- const FetchCallback& fetch_callback);
+ base::OnceClosure prepare_callback,
+ FetchCallback fetch_callback);
~ServiceWorkerFetchDispatcher();
// If appropriate, starts the navigation preload request and creates
@@ -87,15 +103,15 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
ServiceWorkerStatusCode status);
void DidFail(ServiceWorkerStatusCode status);
void DidFinish(int request_id,
- ServiceWorkerFetchEventResult fetch_result,
+ FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob);
+ blink::mojom::BlobPtr body_as_blob);
void Complete(ServiceWorkerStatusCode status,
- ServiceWorkerFetchEventResult fetch_result,
+ FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob);
+ blink::mojom::BlobPtr body_as_blob);
static void OnFetchEventFinished(
ServiceWorkerVersion* version,
@@ -104,14 +120,19 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
blink::mojom::ServiceWorkerEventStatus status,
base::Time dispatch_event_time);
+ ServiceWorkerFetchType GetFetchType() const;
ServiceWorkerMetrics::EventType GetEventType() const;
+ // S13nServiceWorker
+ std::unique_ptr<ResourceRequest> request_;
+ // Non-S13nServiceWorker
+ std::unique_ptr<ServiceWorkerFetchRequest> legacy_request_;
+
scoped_refptr<ServiceWorkerVersion> version_;
+ ResourceType resource_type_;
net::NetLogWithSource net_log_;
- base::Closure prepare_callback_;
+ base::OnceClosure prepare_callback_;
FetchCallback fetch_callback_;
- std::unique_ptr<ServiceWorkerFetchRequest> request_;
- ResourceType resource_type_;
base::Optional<base::TimeDelta> timeout_;
bool did_complete_;
diff --git a/chromium/content/browser/service_worker/service_worker_handle.cc b/chromium/content/browser/service_worker/service_worker_handle.cc
index a88f4f71896..b54e3a14dec 100644
--- a/chromium/content/browser/service_worker/service_worker_handle.cc
+++ b/chromium/content/browser/service_worker/service_worker_handle.cc
@@ -52,13 +52,14 @@ void ServiceWorkerHandle::OnVersionStateChanged(ServiceWorkerVersion* version) {
mojo::ConvertTo<blink::mojom::ServiceWorkerState>(version->status()));
}
-ServiceWorkerObjectInfo ServiceWorkerHandle::GetObjectInfo() {
- ServiceWorkerObjectInfo info;
- info.handle_id = handle_id_;
- info.url = version_->script_url();
- info.state =
+blink::mojom::ServiceWorkerObjectInfoPtr
+ServiceWorkerHandle::CreateObjectInfo() {
+ auto info = blink::mojom::ServiceWorkerObjectInfo::New();
+ info->handle_id = handle_id_;
+ info->url = version_->script_url();
+ info->state =
mojo::ConvertTo<blink::mojom::ServiceWorkerState>(version_->status());
- info.version_id = version_->version_id();
+ info->version_id = version_->version_id();
return info;
}
diff --git a/chromium/content/browser/service_worker/service_worker_handle.h b/chromium/content/browser/service_worker/service_worker_handle.h
index fd2697b6cfb..0a397105f9b 100644
--- a/chromium/content/browser/service_worker/service_worker_handle.h
+++ b/chromium/content/browser/service_worker/service_worker_handle.h
@@ -45,7 +45,7 @@ class CONTENT_EXPORT ServiceWorkerHandle
// ServiceWorkerVersion::Listener overrides.
void OnVersionStateChanged(ServiceWorkerVersion* version) override;
- ServiceWorkerObjectInfo GetObjectInfo();
+ blink::mojom::ServiceWorkerObjectInfoPtr CreateObjectInfo();
int provider_id() const { return provider_id_; }
int handle_id() const { return handle_id_; }
diff --git a/chromium/content/browser/service_worker/service_worker_handle_unittest.cc b/chromium/content/browser/service_worker/service_worker_handle_unittest.cc
index f5c8f17907b..b31187658d2 100644
--- a/chromium/content/browser/service_worker/service_worker_handle_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_handle_unittest.cc
@@ -35,7 +35,7 @@ const int kRenderFrameId = 44; // A dummy ID for testing.
void VerifyStateChangedMessage(int expected_handle_id,
blink::mojom::ServiceWorkerState expected_state,
const IPC::Message* message) {
- ASSERT_TRUE(message != NULL);
+ ASSERT_TRUE(message != nullptr);
ServiceWorkerMsg_ServiceWorkerStateChanged::Param param;
ASSERT_TRUE(ServiceWorkerMsg_ServiceWorkerStateChanged::Read(
message, &param));
@@ -118,9 +118,9 @@ class ServiceWorkerHandleTest : public testing::Test {
}
void TearDown() override {
- dispatcher_host_ = NULL;
- registration_ = NULL;
- version_ = NULL;
+ dispatcher_host_ = nullptr;
+ registration_ = nullptr;
+ version_ = nullptr;
provider_host_.reset();
helper_.reset();
}
diff --git a/chromium/content/browser/service_worker/service_worker_info.cc b/chromium/content/browser/service_worker/service_worker_info.cc
index a3f28da8224..0bf9e3547b4 100644
--- a/chromium/content/browser/service_worker/service_worker_info.cc
+++ b/chromium/content/browser/service_worker/service_worker_info.cc
@@ -9,6 +9,7 @@
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/child_process_host.h"
#include "ipc/ipc_message.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
namespace content {
@@ -17,13 +18,13 @@ ServiceWorkerVersionInfo::ClientInfo::ClientInfo()
: ClientInfo(ChildProcessHost::kInvalidUniqueID,
MSG_ROUTING_NONE,
base::Callback<WebContents*(void)>(),
- SERVICE_WORKER_PROVIDER_UNKNOWN) {}
+ blink::mojom::ServiceWorkerProviderType::kUnknown) {}
ServiceWorkerVersionInfo::ClientInfo::ClientInfo(
int process_id,
int route_id,
const base::Callback<WebContents*(void)>& web_contents_getter,
- ServiceWorkerProviderType type)
+ blink::mojom::ServiceWorkerProviderType type)
: process_id(process_id),
route_id(route_id),
web_contents_getter(web_contents_getter),
@@ -41,7 +42,7 @@ ServiceWorkerVersionInfo::ServiceWorkerVersionInfo()
fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN),
registration_id(blink::mojom::kInvalidServiceWorkerRegistrationId),
- version_id(kInvalidServiceWorkerVersionId),
+ version_id(blink::mojom::kInvalidServiceWorkerVersionId),
process_id(ChildProcessHost::kInvalidUniqueID),
thread_id(kInvalidEmbeddedWorkerThreadId),
devtools_agent_route_id(MSG_ROUTING_NONE) {}
diff --git a/chromium/content/browser/service_worker/service_worker_info.h b/chromium/content/browser/service_worker/service_worker_info.h
index 6145c27cf9c..2e81a1a8b18 100644
--- a/chromium/content/browser/service_worker/service_worker_info.h
+++ b/chromium/content/browser/service_worker/service_worker_info.h
@@ -14,6 +14,7 @@
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
#include "url/gurl.h"
namespace content {
@@ -28,14 +29,14 @@ struct CONTENT_EXPORT ServiceWorkerVersionInfo {
ClientInfo(int process_id,
int route_id,
const base::Callback<WebContents*(void)>& web_contents_getter,
- ServiceWorkerProviderType type);
+ blink::mojom::ServiceWorkerProviderType type);
ClientInfo(const ClientInfo& other);
~ClientInfo();
int process_id;
int route_id;
// |web_contents_getter| is only set for PlzNavigate.
base::Callback<WebContents*(void)> web_contents_getter;
- ServiceWorkerProviderType type;
+ blink::mojom::ServiceWorkerProviderType type;
};
ServiceWorkerVersionInfo();
@@ -55,7 +56,7 @@ struct CONTENT_EXPORT ServiceWorkerVersionInfo {
EmbeddedWorkerStatus running_status;
ServiceWorkerVersion::Status status;
ServiceWorkerVersion::FetchHandlerExistence fetch_handler_existence;
- NavigationPreloadState navigation_preload_state;
+ blink::mojom::NavigationPreloadState navigation_preload_state;
GURL script_url;
int64_t registration_id;
int64_t version_id;
diff --git a/chromium/content/browser/service_worker/service_worker_installed_scripts_sender.cc b/chromium/content/browser/service_worker/service_worker_installed_scripts_sender.cc
index 5e14a4ca52b..9594dacb670 100644
--- a/chromium/content/browser/service_worker/service_worker_installed_scripts_sender.cc
+++ b/chromium/content/browser/service_worker/service_worker_installed_scripts_sender.cc
@@ -133,7 +133,7 @@ class ServiceWorkerInstalledScriptsSender::Sender {
CompleteSendIfNeeded(FinishedReason::kCreateDataPipeError);
return;
}
- meta_data_sender_ = base::MakeUnique<MetaDataSender>(
+ meta_data_sender_ = std::make_unique<MetaDataSender>(
http_info->http_info->metadata, std::move(meta_data_producer));
meta_data_sender_->Start(
base::BindOnce(&Sender::OnMetaDataSent, AsWeakPtr()));
@@ -246,13 +246,14 @@ class ServiceWorkerInstalledScriptsSender::Sender {
// |this| will be removed by |owner_| as a result. Errors are notified
// immediately, but when the transfer has been succeeded, it's notified when
// sending both of body and meta data is finished.
- void CompleteSendIfNeeded(FinishedReason status) {
- if (status != FinishedReason::kSuccess) {
- owner_->OnAbortSendingScript(status);
+ void CompleteSendIfNeeded(FinishedReason reason) {
+ if (reason != FinishedReason::kSuccess) {
+ owner_->OnFinishSendingScript(reason);
return;
}
+
if (WasMetadataWritten() && WasBodyWritten())
- owner_->OnFinishSendingScript();
+ owner_->OnFinishSendingScript(reason);
}
bool WasMetadataWritten() const { return !meta_data_sender_; }
@@ -285,8 +286,10 @@ ServiceWorkerInstalledScriptsSender::ServiceWorkerInstalledScriptsSender(
main_script_url_(owner_->script_url()),
main_script_id_(
owner_->script_cache_map()->LookupResourceId(main_script_url_)),
+ sent_main_script_(false),
+ binding_(this),
state_(State::kNotStarted),
- finished_reason_(FinishedReason::kNotFinished) {
+ last_finished_reason_(FinishedReason::kNotFinished) {
DCHECK(ServiceWorkerVersion::IsInstalled(owner_->status()));
DCHECK_NE(kInvalidServiceWorkerResourceId, main_script_id_);
}
@@ -304,7 +307,7 @@ ServiceWorkerInstalledScriptsSender::CreateInfoAndBind() {
installed_urls.emplace_back(resource.url);
if (resource.url == main_script_url_)
continue;
- imported_scripts_.emplace(resource.resource_id, resource.url);
+ pending_scripts_.emplace(resource.resource_id, resource.url);
}
DCHECK(!installed_urls.empty())
<< "At least the main script should be installed.";
@@ -312,32 +315,31 @@ ServiceWorkerInstalledScriptsSender::CreateInfoAndBind() {
auto info = mojom::ServiceWorkerInstalledScriptsInfo::New();
info->manager_request = mojo::MakeRequest(&manager_);
info->installed_urls = std::move(installed_urls);
+ binding_.Bind(mojo::MakeRequest(&info->manager_host_ptr));
return info;
}
-bool ServiceWorkerInstalledScriptsSender::IsFinished() const {
- return state_ == State::kFinished;
-}
-
void ServiceWorkerInstalledScriptsSender::Start() {
DCHECK_EQ(State::kNotStarted, state_);
DCHECK_NE(kInvalidServiceWorkerResourceId, main_script_id_);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker",
"ServiceWorkerInstalledScriptsSender", this,
"main_script_url", main_script_url_.spec());
- UpdateState(State::kSendingMainScript);
- StartSendingScript(main_script_id_);
+ StartSendingScript(main_script_id_, main_script_url_);
}
void ServiceWorkerInstalledScriptsSender::StartSendingScript(
- int64_t resource_id) {
+ int64_t resource_id,
+ const GURL& script_url) {
DCHECK(!running_sender_);
- DCHECK(state_ == State::kSendingMainScript ||
- state_ == State::kSendingImportedScript);
+ DCHECK(current_sending_url_.is_empty());
+ state_ = State::kSendingScripts;
+ current_sending_url_ = script_url;
+
auto reader = owner_->context()->storage()->CreateResponseReader(resource_id);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker", "SendingScript", this,
- "script_url", CurrentSendingURL().spec());
- running_sender_ = base::MakeUnique<Sender>(std::move(reader), this);
+ "script_url", current_sending_url_.spec());
+ running_sender_ = std::make_unique<Sender>(std::move(reader), this);
running_sender_->Start();
}
@@ -349,13 +351,12 @@ void ServiceWorkerInstalledScriptsSender::SendScriptInfoToRenderer(
mojo::ScopedDataPipeConsumerHandle meta_data_handle,
uint64_t meta_data_size) {
DCHECK(running_sender_);
- DCHECK(state_ == State::kSendingMainScript ||
- state_ == State::kSendingImportedScript);
+ DCHECK_EQ(State::kSendingScripts, state_);
TRACE_EVENT_NESTABLE_ASYNC_INSTANT2(
"ServiceWorker", "SendScriptInfoToRenderer", this, "body_size", body_size,
"meta_data_size", meta_data_size);
auto script_info = mojom::ServiceWorkerScriptInfo::New();
- script_info->script_url = CurrentSendingURL();
+ script_info->script_url = current_sending_url_;
script_info->headers = std::move(headers);
script_info->encoding = std::move(encoding);
script_info->body = std::move(body_handle);
@@ -368,51 +369,55 @@ void ServiceWorkerInstalledScriptsSender::SendScriptInfoToRenderer(
void ServiceWorkerInstalledScriptsSender::OnHttpInfoRead(
scoped_refptr<HttpResponseInfoIOBuffer> http_info) {
DCHECK(running_sender_);
- DCHECK(state_ == State::kSendingMainScript ||
- state_ == State::kSendingImportedScript);
- if (state_ == State::kSendingMainScript)
+ DCHECK_EQ(State::kSendingScripts, state_);
+ if (IsSendingMainScript())
owner_->SetMainScriptHttpResponseInfo(*http_info->http_info);
}
-void ServiceWorkerInstalledScriptsSender::OnFinishSendingScript() {
+void ServiceWorkerInstalledScriptsSender::OnFinishSendingScript(
+ FinishedReason reason) {
DCHECK(running_sender_);
- DCHECK(state_ == State::kSendingMainScript ||
- state_ == State::kSendingImportedScript);
+ DCHECK_EQ(State::kSendingScripts, state_);
TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "SendingScript", this);
running_sender_.reset();
- if (state_ == State::kSendingMainScript) {
- // Imported scripts are served after the main script.
- imported_script_iter_ = imported_scripts_.begin();
- UpdateState(State::kSendingImportedScript);
- } else {
- ++imported_script_iter_;
+ current_sending_url_ = GURL();
+
+ if (IsSendingMainScript())
+ sent_main_script_ = true;
+
+ if (reason != FinishedReason::kSuccess) {
+ Abort(reason);
+ return;
}
- if (imported_script_iter_ == imported_scripts_.end()) {
- // All scripts have been sent to the renderer.
- // ServiceWorkerInstalledScriptsSender's work is done now.
- DCHECK_EQ(State::kSendingImportedScript, state_);
- DCHECK(!IsFinished());
- Finish(FinishedReason::kSuccess);
+
+ if (pending_scripts_.empty()) {
+ UpdateFinishedReasonAndBecomeIdle(FinishedReason::kSuccess);
TRACE_EVENT_NESTABLE_ASYNC_END0(
"ServiceWorker", "ServiceWorkerInstalledScriptsSender", this);
return;
}
+
// Start sending the next script.
- StartSendingScript(imported_script_iter_->first);
+ int64_t next_id = pending_scripts_.front().first;
+ GURL next_url = pending_scripts_.front().second;
+ pending_scripts_.pop();
+ StartSendingScript(next_id, next_url);
}
-void ServiceWorkerInstalledScriptsSender::OnAbortSendingScript(
- FinishedReason reason) {
- DCHECK(running_sender_);
- DCHECK(state_ == State::kSendingMainScript ||
- state_ == State::kSendingImportedScript);
+void ServiceWorkerInstalledScriptsSender::Abort(FinishedReason reason) {
+ DCHECK_EQ(State::kSendingScripts, state_);
DCHECK_NE(FinishedReason::kSuccess, reason);
- DCHECK(!IsFinished());
TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker",
"ServiceWorkerInstalledScriptsSender", this,
"FinishedReason", static_cast<int>(reason));
- running_sender_.reset();
- Finish(reason);
+
+ // Remove all pending scripts.
+ // Note that base::queue doesn't have clear(), and also base::STLClearObject
+ // is not applicable for base::queue since it doesn't have reserve().
+ base::queue<std::pair<int64_t, GURL>> empty;
+ pending_scripts_.swap(empty);
+
+ UpdateFinishedReasonAndBecomeIdle(reason);
switch (reason) {
case FinishedReason::kNotFinished:
@@ -438,40 +443,52 @@ void ServiceWorkerInstalledScriptsSender::OnAbortSendingScript(
// failure means the renderer gets killed, and the error handler of
// EmbeddedWorkerInstance is invoked soon.
manager_.reset();
+ binding_.Close();
return;
}
}
-const GURL& ServiceWorkerInstalledScriptsSender::CurrentSendingURL() {
- if (state_ == State::kSendingMainScript)
- return main_script_url_;
- return imported_script_iter_->second;
+void ServiceWorkerInstalledScriptsSender::UpdateFinishedReasonAndBecomeIdle(
+ FinishedReason reason) {
+ DCHECK_EQ(State::kSendingScripts, state_);
+ DCHECK_NE(FinishedReason::kNotFinished, reason);
+ DCHECK(current_sending_url_.is_empty());
+ state_ = State::kIdle;
+ last_finished_reason_ = reason;
}
-void ServiceWorkerInstalledScriptsSender::UpdateState(State state) {
- DCHECK_NE(State::kFinished, state) << "Use Finish() for state kFinished.";
+void ServiceWorkerInstalledScriptsSender::RequestInstalledScript(
+ const GURL& script_url) {
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerInstalledScriptsSender::RequestInstalledScript",
+ "script_url", script_url.spec());
+ int64_t resource_id =
+ owner_->script_cache_map()->LookupResourceId(script_url);
- switch (state_) {
- case State::kNotStarted:
- DCHECK_EQ(State::kSendingMainScript, state);
- state_ = state;
- return;
- case State::kSendingMainScript:
- DCHECK_EQ(State::kSendingImportedScript, state);
- state_ = state;
- return;
- case State::kSendingImportedScript:
- case State::kFinished:
- NOTREACHED();
- return;
+ if (resource_id == kInvalidServiceWorkerResourceId) {
+ mojo::ReportBadMessage("Requested script was not installed.");
+ return;
}
+
+ if (state_ == State::kSendingScripts) {
+ // The sender is now sending other scripts. Push the requested script into
+ // the waiting queue.
+ pending_scripts_.emplace(resource_id, script_url);
+ return;
+ }
+
+ DCHECK_EQ(State::kIdle, state_);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker",
+ "ServiceWorkerInstalledScriptsSender", this,
+ "main_script_url", main_script_url_.spec());
+ StartSendingScript(resource_id, script_url);
}
-void ServiceWorkerInstalledScriptsSender::Finish(FinishedReason reason) {
- DCHECK_NE(State::kFinished, state_);
- DCHECK_NE(FinishedReason::kNotFinished, reason);
- state_ = State::kFinished;
- finished_reason_ = reason;
+bool ServiceWorkerInstalledScriptsSender::IsSendingMainScript() const {
+ // |current_sending_url_| could match |main_script_url_| even though
+ // |sent_main_script_| is false if calling importScripts for the main
+ // script.
+ return !sent_main_script_ && current_sending_url_ == main_script_url_;
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_installed_scripts_sender.h b/chromium/content/browser/service_worker/service_worker_installed_scripts_sender.h
index 37d8e7da359..0d031b31090 100644
--- a/chromium/content/browser/service_worker/service_worker_installed_scripts_sender.h
+++ b/chromium/content/browser/service_worker/service_worker_installed_scripts_sender.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_INSTALLED_SCRIPTS_SENDER_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_INSTALLED_SCRIPTS_SENDER_H_
+#include "base/containers/queue.h"
#include "content/common/service_worker/service_worker_installed_scripts_manager.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
namespace content {
@@ -16,7 +18,18 @@ class ServiceWorkerVersion;
// scripts from ServiceWorkerStorage to the renderer through Mojo data pipes.
// ServiceWorkerInstalledScriptsSender is owned by ServiceWorkerVersion. It is
// created for worker startup and lives as long as the worker is running.
-class CONTENT_EXPORT ServiceWorkerInstalledScriptsSender {
+//
+// SWInstalledScriptsSender has three phases.
+// 1. The sender sends all installed scripts to the renderer without any
+// requests from the renderer. This initial phase is called "streaming".
+// |state_| is kSendingScripts. When all installed scripts are sent, moves to
+// the phase 2.
+// 2. The sender is idle. |state_| is kIdle. If the renderer calls
+// RequestInstalledScript, moves to the phase 3.
+// 3. The sender sends requested scripts. |state_| is kSendingScripts. When all
+// the requested scripts are sent, returns to the phase 2.
+class CONTENT_EXPORT ServiceWorkerInstalledScriptsSender
+ : public mojom::ServiceWorkerInstalledScriptsManagerHost {
public:
// Do not change the order. This is used for UMA.
enum class FinishedReason {
@@ -34,7 +47,7 @@ class CONTENT_EXPORT ServiceWorkerInstalledScriptsSender {
// |owner| must be an installed service worker.
explicit ServiceWorkerInstalledScriptsSender(ServiceWorkerVersion* owner);
- ~ServiceWorkerInstalledScriptsSender();
+ ~ServiceWorkerInstalledScriptsSender() override;
// Creates a Mojo struct (mojom::ServiceWorkerInstalledScriptsInfo) and sets
// it with the information to create WebServiceWorkerInstalledScriptsManager
@@ -44,20 +57,28 @@ class CONTENT_EXPORT ServiceWorkerInstalledScriptsSender {
// Starts sending installed scripts to the worker.
void Start();
- bool IsFinished() const;
- FinishedReason finished_reason() const { return finished_reason_; }
+ // Returns the reason for the last time the sender entered the idle state. If
+ // this sender has never reached the idle state, returns kNotFinished.
+ FinishedReason last_finished_reason() const { return last_finished_reason_; }
private:
class Sender;
enum class State {
kNotStarted,
- kSendingMainScript,
- kSendingImportedScript,
- kFinished,
+ kSendingScripts,
+ kIdle,
};
- void StartSendingScript(int64_t resource_id);
+ void StartSendingScript(int64_t resource_id, const GURL& script_url);
+
+ // Stops all tasks even if pending scripts exist and disconnects the pipe to
+ // the renderer. Also, if |reason| indicates failure to read the installed
+ // script from the disk cache (kNoHTTPInfoError or kResponseReaderError), then
+ // |owner_| is doomed via ServiceWorkerRegistration::DeleteVersion().
+ void Abort(FinishedReason reason);
+
+ void UpdateFinishedReasonAndBecomeIdle(FinishedReason reason);
// Called from |running_sender_|.
void SendScriptInfoToRenderer(
@@ -68,24 +89,27 @@ class CONTENT_EXPORT ServiceWorkerInstalledScriptsSender {
mojo::ScopedDataPipeConsumerHandle meta_data_handle,
uint64_t meta_data_size);
void OnHttpInfoRead(scoped_refptr<HttpResponseInfoIOBuffer> http_info);
- void OnFinishSendingScript();
- void OnAbortSendingScript(FinishedReason reason);
+ void OnFinishSendingScript(FinishedReason reason);
- const GURL& CurrentSendingURL();
+ // Implements mojom::ServiceWorkerInstalledScriptsManagerHost.
+ void RequestInstalledScript(const GURL& script_url) override;
- void UpdateState(State state);
- void Finish(FinishedReason reason);
+ bool IsSendingMainScript() const;
ServiceWorkerVersion* owner_;
const GURL main_script_url_;
const int64_t main_script_id_;
+ bool sent_main_script_;
+ mojo::Binding<mojom::ServiceWorkerInstalledScriptsManagerHost> binding_;
mojom::ServiceWorkerInstalledScriptsManagerPtr manager_;
std::unique_ptr<Sender> running_sender_;
+
State state_;
- FinishedReason finished_reason_;
- std::map<int64_t /* resource_id */, GURL> imported_scripts_;
- std::map<int64_t /* resource_id */, GURL>::iterator imported_script_iter_;
+ FinishedReason last_finished_reason_;
+
+ GURL current_sending_url_;
+ base::queue<std::pair<int64_t /* resource_id */, GURL>> pending_scripts_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerInstalledScriptsSender);
};
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 06d6d1ec245..13428415d88 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
@@ -11,6 +11,7 @@
#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/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/io_buffer.h"
@@ -22,55 +23,6 @@ namespace content {
namespace {
-void WriteBodyToDiskCache(
- ServiceWorkerResponseWriter* writer,
- const std::vector<std::pair<std::string, std::string>>& headers,
- const std::string& body) {
- std::unique_ptr<net::HttpResponseInfo> info =
- base::MakeUnique<net::HttpResponseInfo>();
- info->request_time = base::Time::Now();
- info->response_time = base::Time::Now();
- info->headers =
- base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.0 200 OK\0\0");
- for (const auto& header : headers)
- info->headers->AddHeader(header.first + ": " + header.second);
-
- scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
- base::MakeRefCounted<HttpResponseInfoIOBuffer>(info.release());
- info_buffer->response_data_size = body.size();
- {
- net::TestCompletionCallback cb;
- writer->WriteInfo(info_buffer.get(), cb.callback());
- int rv = cb.WaitForResult();
- EXPECT_GE(rv, 0);
- }
-
- scoped_refptr<net::IOBuffer> body_buffer =
- base::MakeRefCounted<net::StringIOBuffer>(body);
- {
- net::TestCompletionCallback cb;
- writer->WriteData(body_buffer.get(), body.size(), cb.callback());
- int rv = cb.WaitForResult();
- EXPECT_EQ(body.size(), static_cast<size_t>(rv));
- }
-}
-
-void WriteMetaDataToDiskCache(ServiceWorkerResponseMetadataWriter* writer,
- const std::string& meta_data) {
- scoped_refptr<net::IOBuffer> meta_data_buffer =
- base::MakeRefCounted<net::StringIOBuffer>(meta_data);
- base::RunLoop loop;
- writer->WriteMetadata(
- meta_data_buffer.get(), meta_data.size(),
- base::Bind(
- [](base::Closure closure, int expected, int result) {
- EXPECT_EQ(expected, result);
- closure.Run();
- },
- loop.QuitClosure(), meta_data.size()));
- loop.Run();
-}
-
void ReadDataPipeInternal(mojo::DataPipeConsumerHandle handle,
std::string* result,
base::OnceClosure quit_closure) {
@@ -138,12 +90,8 @@ class ExpectedScriptInfo {
ServiceWorkerDatabase::ResourceRecord WriteToDiskCache(
ServiceWorkerStorage* storage) const {
- auto body_writer = storage->CreateResponseWriter(resource_id_);
- WriteBodyToDiskCache(body_writer.get(), headers_, body_);
- auto metadata_writer = storage->CreateResponseMetadataWriter(resource_id_);
- WriteMetaDataToDiskCache(metadata_writer.get(), meta_data_);
- return ServiceWorkerDatabase::ResourceRecord(resource_id_, script_url_,
- body_.size());
+ return ::content::WriteToDiskCacheSync(storage, script_url_, resource_id_,
+ headers_, body_, meta_data_);
}
void CheckIfIdentical(
@@ -183,12 +131,9 @@ class ExpectedScriptInfo {
class MockServiceWorkerInstalledScriptsManager
: public mojom::ServiceWorkerInstalledScriptsManager {
public:
- MockServiceWorkerInstalledScriptsManager(
- std::vector<GURL> installed_urls,
+ explicit MockServiceWorkerInstalledScriptsManager(
mojom::ServiceWorkerInstalledScriptsManagerRequest request)
- : binding_(this, std::move(request)),
- installed_urls_(std::move(installed_urls)),
- next_url_(installed_urls_.begin()) {}
+ : binding_(this, std::move(request)) {}
mojom::ServiceWorkerScriptInfoPtr WaitUntilTransferInstalledScript() {
EXPECT_TRUE(incoming_script_info_.is_null());
@@ -204,19 +149,13 @@ class MockServiceWorkerInstalledScriptsManager
mojom::ServiceWorkerScriptInfoPtr script_info) override {
EXPECT_TRUE(incoming_script_info_.is_null());
EXPECT_TRUE(transfer_installed_script_waiter_);
- EXPECT_EQ(*next_url_, script_info->script_url);
incoming_script_info_ = std::move(script_info);
- if (transfer_installed_script_waiter_)
- std::move(transfer_installed_script_waiter_).Run();
- ++next_url_;
+ ASSERT_TRUE(transfer_installed_script_waiter_);
+ std::move(transfer_installed_script_waiter_).Run();
}
private:
mojo::Binding<mojom::ServiceWorkerInstalledScriptsManager> binding_;
- // This is in the order to be served.
- const std::vector<GURL> installed_urls_;
- std::vector<GURL>::const_iterator next_url_;
-
base::OnceClosure transfer_installed_script_waiter_;
mojom::ServiceWorkerScriptInfoPtr incoming_script_info_;
@@ -230,7 +169,7 @@ class ServiceWorkerInstalledScriptsSenderTest : public testing::Test {
protected:
void SetUp() override {
- helper_ = base::MakeUnique<EmbeddedWorkerTestHelper>(base::FilePath());
+ helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath());
context()->storage()->LazyInitializeForTest(
base::BindOnce(&base::DoNothing));
@@ -314,7 +253,7 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, SendScripts) {
}
auto sender =
- base::MakeUnique<ServiceWorkerInstalledScriptsSender>(version());
+ std::make_unique<ServiceWorkerInstalledScriptsSender>(version());
std::unique_ptr<MockServiceWorkerInstalledScriptsManager> renderer_manager;
{
@@ -327,27 +266,24 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, SendScripts) {
EXPECT_TRUE(base::ContainsKey(kExpectedScriptInfoMap, url));
EXPECT_TRUE(scripts_info->manager_request.is_pending());
renderer_manager =
- base::MakeUnique<MockServiceWorkerInstalledScriptsManager>(
- std::move(scripts_info->installed_urls),
+ std::make_unique<MockServiceWorkerInstalledScriptsManager>(
std::move(scripts_info->manager_request));
}
ASSERT_TRUE(renderer_manager);
sender->Start();
- while (kExpectedScriptInfoMap.size() > 0) {
- EXPECT_FALSE(sender->IsFinished());
- EXPECT_EQ(SenderFinishedReason::kNotFinished, sender->finished_reason());
+ // Stream the installed scripts once.
+ for (const auto& expected_script : kExpectedScriptInfoMap) {
+ const ExpectedScriptInfo& info = expected_script.second;
+ EXPECT_EQ(SenderFinishedReason::kNotFinished,
+ sender->last_finished_reason());
auto script_info = renderer_manager->WaitUntilTransferInstalledScript();
- EXPECT_TRUE(
- base::ContainsKey(kExpectedScriptInfoMap, script_info->script_url));
- const auto& info = kExpectedScriptInfoMap.at(script_info->script_url);
+ EXPECT_EQ(info.script_url(), script_info->script_url);
info.CheckIfIdentical(script_info);
- kExpectedScriptInfoMap.erase(script_info->script_url);
}
- EXPECT_TRUE(sender->IsFinished());
- EXPECT_EQ(SenderFinishedReason::kSuccess, sender->finished_reason());
+ EXPECT_EQ(SenderFinishedReason::kSuccess, sender->last_finished_reason());
}
TEST_F(ServiceWorkerInstalledScriptsSenderTest, FailedToSendBody) {
@@ -374,7 +310,7 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, FailedToSendBody) {
}
auto sender =
- base::MakeUnique<ServiceWorkerInstalledScriptsSender>(version());
+ std::make_unique<ServiceWorkerInstalledScriptsSender>(version());
std::unique_ptr<MockServiceWorkerInstalledScriptsManager> renderer_manager;
{
@@ -387,15 +323,13 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, FailedToSendBody) {
EXPECT_TRUE(base::ContainsKey(kExpectedScriptInfoMap, url));
EXPECT_TRUE(scripts_info->manager_request.is_pending());
renderer_manager =
- base::MakeUnique<MockServiceWorkerInstalledScriptsManager>(
- std::move(scripts_info->installed_urls),
+ std::make_unique<MockServiceWorkerInstalledScriptsManager>(
std::move(scripts_info->manager_request));
}
ASSERT_TRUE(renderer_manager);
sender->Start();
- EXPECT_FALSE(sender->IsFinished());
- EXPECT_EQ(SenderFinishedReason::kNotFinished, sender->finished_reason());
+ EXPECT_EQ(SenderFinishedReason::kNotFinished, sender->last_finished_reason());
{
// Reset a data pipe during sending the body.
@@ -408,8 +342,8 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, FailedToSendBody) {
base::RunLoop().RunUntilIdle();
}
- EXPECT_TRUE(sender->IsFinished());
- EXPECT_EQ(SenderFinishedReason::kConnectionError, sender->finished_reason());
+ EXPECT_EQ(SenderFinishedReason::kConnectionError,
+ sender->last_finished_reason());
}
TEST_F(ServiceWorkerInstalledScriptsSenderTest, FailedToSendMetaData) {
@@ -436,7 +370,7 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, FailedToSendMetaData) {
}
auto sender =
- base::MakeUnique<ServiceWorkerInstalledScriptsSender>(version());
+ std::make_unique<ServiceWorkerInstalledScriptsSender>(version());
std::unique_ptr<MockServiceWorkerInstalledScriptsManager> renderer_manager;
{
@@ -449,15 +383,13 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, FailedToSendMetaData) {
EXPECT_TRUE(base::ContainsKey(kExpectedScriptInfoMap, url));
EXPECT_TRUE(scripts_info->manager_request.is_pending());
renderer_manager =
- base::MakeUnique<MockServiceWorkerInstalledScriptsManager>(
- std::move(scripts_info->installed_urls),
+ std::make_unique<MockServiceWorkerInstalledScriptsManager>(
std::move(scripts_info->manager_request));
}
ASSERT_TRUE(renderer_manager);
sender->Start();
- EXPECT_FALSE(sender->IsFinished());
- EXPECT_EQ(SenderFinishedReason::kNotFinished, sender->finished_reason());
+ EXPECT_EQ(SenderFinishedReason::kNotFinished, sender->last_finished_reason());
{
// Reset a data pipe during sending the meta data.
@@ -470,9 +402,8 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, FailedToSendMetaData) {
base::RunLoop().RunUntilIdle();
}
- EXPECT_TRUE(sender->IsFinished());
EXPECT_EQ(SenderFinishedReason::kMetaDataSenderError,
- sender->finished_reason());
+ sender->last_finished_reason());
}
TEST_F(ServiceWorkerInstalledScriptsSenderTest, Histograms) {
@@ -510,7 +441,7 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, Histograms) {
}
auto sender =
- base::MakeUnique<ServiceWorkerInstalledScriptsSender>(version());
+ std::make_unique<ServiceWorkerInstalledScriptsSender>(version());
std::unique_ptr<MockServiceWorkerInstalledScriptsManager> renderer_manager;
{
@@ -523,8 +454,7 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, Histograms) {
EXPECT_TRUE(base::ContainsKey(kExpectedScriptInfoMap, url));
EXPECT_TRUE(scripts_info->manager_request.is_pending());
renderer_manager =
- base::MakeUnique<MockServiceWorkerInstalledScriptsManager>(
- std::move(scripts_info->installed_urls),
+ std::make_unique<MockServiceWorkerInstalledScriptsManager>(
std::move(scripts_info->manager_request));
}
ASSERT_TRUE(renderer_manager);
@@ -532,19 +462,17 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, Histograms) {
base::HistogramTester histogram_tester;
sender->Start();
- while (kExpectedScriptInfoMap.size() > 0) {
- EXPECT_FALSE(sender->IsFinished());
- EXPECT_EQ(SenderFinishedReason::kNotFinished, sender->finished_reason());
+ // Stream the installed scripts once.
+ for (const auto& expected_script : kExpectedScriptInfoMap) {
+ const ExpectedScriptInfo& info = expected_script.second;
+ EXPECT_EQ(SenderFinishedReason::kNotFinished,
+ sender->last_finished_reason());
auto script_info = renderer_manager->WaitUntilTransferInstalledScript();
- EXPECT_TRUE(
- base::ContainsKey(kExpectedScriptInfoMap, script_info->script_url));
- const auto& info = kExpectedScriptInfoMap.at(script_info->script_url);
+ EXPECT_EQ(info.script_url(), script_info->script_url);
info.CheckIfIdentical(script_info);
- kExpectedScriptInfoMap.erase(script_info->script_url);
}
- EXPECT_TRUE(sender->IsFinished());
- EXPECT_EQ(SenderFinishedReason::kSuccess, sender->finished_reason());
+ EXPECT_EQ(SenderFinishedReason::kSuccess, sender->last_finished_reason());
// The histogram should be recorded when reading the script.
// The count should be four: reading the response body of a main script and an
@@ -554,4 +482,177 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, Histograms) {
ServiceWorkerMetrics::ReadResponseResult::READ_OK, 4);
}
+TEST_F(ServiceWorkerInstalledScriptsSenderTest, RequestScriptBeforeStreaming) {
+ const GURL kMainScriptURL = version()->script_url();
+ std::map<GURL, ExpectedScriptInfo> kExpectedScriptInfoMap = {
+ {kMainScriptURL,
+ {1,
+ kMainScriptURL,
+ {{"Content-Length", "35"},
+ {"Content-Type", "text/javascript; charset=utf-8"},
+ {"TestHeader", "BlahBlah"}},
+ "utf-8",
+ "I'm script body for the main script",
+ "I'm meta data for the main script"}},
+ {GURL("https://example.com/imported1"),
+ {2,
+ GURL("https://example.com/imported1"),
+ {{"Content-Length", "22"},
+ {"Content-Type", "text/javascript; charset=euc-jp"},
+ {"TestHeader", "BlahBlah"}},
+ "euc-jp",
+ "I'm imported script 1!",
+ "I'm the meta data for imported script 1!"}},
+ {GURL("https://example.com/imported2"),
+ {3,
+ GURL("https://example.com/imported2"),
+ {{"Content-Length", "0"},
+ {"Content-Type", "text/javascript; charset=shift_jis"},
+ {"TestHeader", "BlahBlah"}},
+ "shift_jis",
+ "",
+ ""}},
+ };
+
+ {
+ std::vector<ServiceWorkerDatabase::ResourceRecord> records;
+ for (const auto& info : kExpectedScriptInfoMap)
+ records.push_back(info.second.WriteToDiskCache(context()->storage()));
+ version()->script_cache_map()->SetResources(records);
+ }
+
+ auto sender =
+ std::make_unique<ServiceWorkerInstalledScriptsSender>(version());
+
+ std::unique_ptr<MockServiceWorkerInstalledScriptsManager> renderer_manager;
+ mojom::ServiceWorkerInstalledScriptsManagerHostPtr manager_host_ptr;
+ {
+ mojom::ServiceWorkerInstalledScriptsInfoPtr scripts_info =
+ sender->CreateInfoAndBind();
+ ASSERT_TRUE(scripts_info);
+ ASSERT_EQ(kExpectedScriptInfoMap.size(),
+ scripts_info->installed_urls.size());
+ for (const auto& url : scripts_info->installed_urls)
+ EXPECT_TRUE(base::ContainsKey(kExpectedScriptInfoMap, url));
+ EXPECT_TRUE(scripts_info->manager_request.is_pending());
+ renderer_manager =
+ std::make_unique<MockServiceWorkerInstalledScriptsManager>(
+ std::move(scripts_info->manager_request));
+ manager_host_ptr.Bind(std::move(scripts_info->manager_host_ptr));
+ }
+ ASSERT_TRUE(renderer_manager);
+
+ sender->Start();
+
+ // Request the main script again before receiving the other scripts. It'll be
+ // handled after all of script transfer.
+ manager_host_ptr->RequestInstalledScript(kMainScriptURL);
+
+ // Stream the installed scripts once.
+ for (const auto& expected_script : kExpectedScriptInfoMap) {
+ const ExpectedScriptInfo& info = expected_script.second;
+ EXPECT_EQ(SenderFinishedReason::kNotFinished,
+ sender->last_finished_reason());
+ auto script_info = renderer_manager->WaitUntilTransferInstalledScript();
+ EXPECT_EQ(info.script_url(), script_info->script_url);
+ info.CheckIfIdentical(script_info);
+ }
+ EXPECT_EQ(SenderFinishedReason::kNotFinished, sender->last_finished_reason());
+
+ // Handle requested installed scripts.
+ {
+ const ExpectedScriptInfo& info = kExpectedScriptInfoMap.at(kMainScriptURL);
+ auto script_info = renderer_manager->WaitUntilTransferInstalledScript();
+ EXPECT_EQ(info.script_url(), script_info->script_url);
+ info.CheckIfIdentical(script_info);
+ }
+ EXPECT_EQ(SenderFinishedReason::kSuccess, sender->last_finished_reason());
+}
+
+TEST_F(ServiceWorkerInstalledScriptsSenderTest, RequestScriptAfterStreaming) {
+ const GURL kMainScriptURL = version()->script_url();
+ std::map<GURL, ExpectedScriptInfo> kExpectedScriptInfoMap = {
+ {kMainScriptURL,
+ {1,
+ kMainScriptURL,
+ {{"Content-Length", "35"},
+ {"Content-Type", "text/javascript; charset=utf-8"},
+ {"TestHeader", "BlahBlah"}},
+ "utf-8",
+ "I'm script body for the main script",
+ "I'm meta data for the main script"}},
+ {GURL("https://example.com/imported1"),
+ {2,
+ GURL("https://example.com/imported1"),
+ {{"Content-Length", "22"},
+ {"Content-Type", "text/javascript; charset=euc-jp"},
+ {"TestHeader", "BlahBlah"}},
+ "euc-jp",
+ "I'm imported script 1!",
+ "I'm the meta data for imported script 1!"}},
+ {GURL("https://example.com/imported2"),
+ {3,
+ GURL("https://example.com/imported2"),
+ {{"Content-Length", "0"},
+ {"Content-Type", "text/javascript; charset=shift_jis"},
+ {"TestHeader", "BlahBlah"}},
+ "shift_jis",
+ "",
+ ""}},
+ };
+
+ {
+ std::vector<ServiceWorkerDatabase::ResourceRecord> records;
+ for (const auto& info : kExpectedScriptInfoMap)
+ records.push_back(info.second.WriteToDiskCache(context()->storage()));
+ version()->script_cache_map()->SetResources(records);
+ }
+
+ auto sender =
+ std::make_unique<ServiceWorkerInstalledScriptsSender>(version());
+
+ std::unique_ptr<MockServiceWorkerInstalledScriptsManager> renderer_manager;
+ mojom::ServiceWorkerInstalledScriptsManagerHostPtr manager_host_ptr;
+ {
+ mojom::ServiceWorkerInstalledScriptsInfoPtr scripts_info =
+ sender->CreateInfoAndBind();
+ ASSERT_TRUE(scripts_info);
+ ASSERT_EQ(kExpectedScriptInfoMap.size(),
+ scripts_info->installed_urls.size());
+ for (const auto& url : scripts_info->installed_urls)
+ EXPECT_TRUE(base::ContainsKey(kExpectedScriptInfoMap, url));
+ EXPECT_TRUE(scripts_info->manager_request.is_pending());
+ renderer_manager =
+ std::make_unique<MockServiceWorkerInstalledScriptsManager>(
+ std::move(scripts_info->manager_request));
+ manager_host_ptr.Bind(std::move(scripts_info->manager_host_ptr));
+ }
+ ASSERT_TRUE(renderer_manager);
+
+ sender->Start();
+
+ // Stream the installed scripts once.
+ for (const auto& expected_script : kExpectedScriptInfoMap) {
+ const ExpectedScriptInfo& info = expected_script.second;
+ EXPECT_EQ(SenderFinishedReason::kNotFinished,
+ sender->last_finished_reason());
+ auto script_info = renderer_manager->WaitUntilTransferInstalledScript();
+ EXPECT_EQ(info.script_url(), script_info->script_url);
+ info.CheckIfIdentical(script_info);
+ }
+ EXPECT_EQ(SenderFinishedReason::kSuccess, sender->last_finished_reason());
+
+ // Request the main script again before receiving the other scripts.
+ manager_host_ptr->RequestInstalledScript(kMainScriptURL);
+
+ // Handle requested installed scripts.
+ {
+ const ExpectedScriptInfo& info = kExpectedScriptInfoMap.at(kMainScriptURL);
+ auto script_info = renderer_manager->WaitUntilTransferInstalledScript();
+ EXPECT_EQ(info.script_url(), script_info->script_url);
+ info.CheckIfIdentical(script_info);
+ }
+ EXPECT_EQ(SenderFinishedReason::kSuccess, sender->last_finished_reason());
+}
+
} // namespace content
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 77da353fe8d..f20e5b9164a 100644
--- a/chromium/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/chromium/content/browser/service_worker/service_worker_internals_ui.cc
@@ -33,6 +33,7 @@
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/url_constants.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
using base::DictionaryValue;
using base::ListValue;
@@ -154,27 +155,27 @@ void UpdateVersionInfo(const ServiceWorkerVersionInfo& version,
std::unique_ptr<ListValue> GetRegistrationListValue(
const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
- auto result = base::MakeUnique<ListValue>();
+ auto result = std::make_unique<ListValue>();
for (std::vector<ServiceWorkerRegistrationInfo>::const_iterator it =
registrations.begin();
it != registrations.end();
++it) {
const ServiceWorkerRegistrationInfo& registration = *it;
- auto registration_info = base::MakeUnique<DictionaryValue>();
+ auto registration_info = std::make_unique<DictionaryValue>();
registration_info->SetString("scope", registration.pattern.spec());
registration_info->SetString(
"registration_id", base::Int64ToString(registration.registration_id));
if (registration.active_version.version_id !=
- kInvalidServiceWorkerVersionId) {
- auto active_info = base::MakeUnique<DictionaryValue>();
+ blink::mojom::kInvalidServiceWorkerVersionId) {
+ auto active_info = std::make_unique<DictionaryValue>();
UpdateVersionInfo(registration.active_version, active_info.get());
registration_info->Set("active", std::move(active_info));
}
if (registration.waiting_version.version_id !=
- kInvalidServiceWorkerVersionId) {
- auto waiting_info = base::MakeUnique<DictionaryValue>();
+ blink::mojom::kInvalidServiceWorkerVersionId) {
+ auto waiting_info = std::make_unique<DictionaryValue>();
UpdateVersionInfo(registration.waiting_version, waiting_info.get());
registration_info->Set("waiting", std::move(waiting_info));
}
@@ -186,12 +187,12 @@ std::unique_ptr<ListValue> GetRegistrationListValue(
std::unique_ptr<ListValue> GetVersionListValue(
const std::vector<ServiceWorkerVersionInfo>& versions) {
- auto result = base::MakeUnique<ListValue>();
+ auto result = std::make_unique<ListValue>();
for (std::vector<ServiceWorkerVersionInfo>::const_iterator it =
versions.begin();
it != versions.end();
++it) {
- auto info = base::MakeUnique<DictionaryValue>();
+ auto info = std::make_unique<DictionaryValue>();
UpdateVersionInfo(*it, info.get());
result->Append(std::move(info));
}
@@ -233,8 +234,8 @@ void DidGetRegistrations(
args.push_back(GetRegistrationListValue(live_registrations));
args.push_back(GetVersionListValue(live_versions));
args.push_back(GetRegistrationListValue(stored_registrations));
- args.push_back(base::MakeUnique<Value>(partition_id));
- args.push_back(base::MakeUnique<Value>(context_path.value()));
+ args.push_back(std::make_unique<Value>(partition_id));
+ args.push_back(std::make_unique<Value>(context_path.value()));
internals->web_ui()->CallJavascriptFunctionUnsafe(
"serviceworker.onPartitionData", ConvertToRawPtrVector(args));
}
@@ -268,11 +269,11 @@ class ServiceWorkerInternalsUI::PartitionObserver
const ErrorInfo& info) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::vector<std::unique_ptr<const Value>> args;
- args.push_back(base::MakeUnique<Value>(partition_id_));
- args.push_back(base::MakeUnique<Value>(base::Int64ToString(version_id)));
- args.push_back(base::MakeUnique<Value>(process_id));
- args.push_back(base::MakeUnique<Value>(thread_id));
- auto value = base::MakeUnique<DictionaryValue>();
+ args.push_back(std::make_unique<Value>(partition_id_));
+ args.push_back(std::make_unique<Value>(base::Int64ToString(version_id)));
+ args.push_back(std::make_unique<Value>(process_id));
+ args.push_back(std::make_unique<Value>(thread_id));
+ auto value = std::make_unique<DictionaryValue>();
value->SetString("message", info.error_message);
value->SetInteger("lineNumber", info.line_number);
value->SetInteger("columnNumber", info.column_number);
@@ -287,11 +288,11 @@ class ServiceWorkerInternalsUI::PartitionObserver
const ConsoleMessage& message) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::vector<std::unique_ptr<const Value>> args;
- args.push_back(base::MakeUnique<Value>(partition_id_));
- args.push_back(base::MakeUnique<Value>(base::Int64ToString(version_id)));
- args.push_back(base::MakeUnique<Value>(process_id));
- args.push_back(base::MakeUnique<Value>(thread_id));
- auto value = base::MakeUnique<DictionaryValue>();
+ args.push_back(std::make_unique<Value>(partition_id_));
+ args.push_back(std::make_unique<Value>(base::Int64ToString(version_id)));
+ args.push_back(std::make_unique<Value>(process_id));
+ args.push_back(std::make_unique<Value>(thread_id));
+ auto value = std::make_unique<DictionaryValue>();
value->SetInteger("sourceIdentifier", message.source_identifier);
value->SetInteger("message_level", message.message_level);
value->SetString("message", message.message);
@@ -418,7 +419,7 @@ void ServiceWorkerInternalsUI::AddContextFromStoragePartition(
} else {
partition_id = next_partition_id_++;
auto new_observer =
- base::MakeUnique<PartitionObserver>(partition_id, web_ui());
+ std::make_unique<PartitionObserver>(partition_id, web_ui());
context->AddObserver(new_observer.get());
observers_[reinterpret_cast<uintptr_t>(partition)] =
std::move(new_observer);
@@ -461,7 +462,7 @@ bool ServiceWorkerInternalsUI::GetServiceWorkerContext(
scoped_refptr<ServiceWorkerContextWrapper>* context) const {
BrowserContext* browser_context =
web_ui()->GetWebContents()->GetBrowserContext();
- StoragePartition* result_partition(NULL);
+ StoragePartition* result_partition(nullptr);
BrowserContext::StoragePartitionCallback find_context_cb =
base::Bind(&ServiceWorkerInternalsUI::FindContext,
base::Unretained(this),
@@ -478,7 +479,7 @@ bool ServiceWorkerInternalsUI::GetServiceWorkerContext(
void ServiceWorkerInternalsUI::StopWorker(const ListValue* args) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
int callback_id;
- const DictionaryValue* cmd_args = NULL;
+ const DictionaryValue* cmd_args = nullptr;
int partition_id;
scoped_refptr<ServiceWorkerContextWrapper> context;
std::string version_id_string;
@@ -500,7 +501,7 @@ void ServiceWorkerInternalsUI::StopWorker(const ListValue* args) {
void ServiceWorkerInternalsUI::InspectWorker(const ListValue* args) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
int callback_id;
- const DictionaryValue* cmd_args = NULL;
+ const DictionaryValue* cmd_args = nullptr;
int process_host_id = 0;
int devtools_agent_route_id = 0;
if (!args->GetInteger(0, &callback_id) ||
@@ -529,7 +530,7 @@ void ServiceWorkerInternalsUI::Unregister(const ListValue* args) {
int callback_id;
int partition_id;
std::string scope_string;
- const DictionaryValue* cmd_args = NULL;
+ const DictionaryValue* cmd_args = nullptr;
scoped_refptr<ServiceWorkerContextWrapper> context;
if (!args->GetInteger(0, &callback_id) ||
!args->GetDictionary(1, &cmd_args) ||
@@ -549,7 +550,7 @@ void ServiceWorkerInternalsUI::StartWorker(const ListValue* args) {
int callback_id;
int partition_id;
std::string scope_string;
- const DictionaryValue* cmd_args = NULL;
+ const DictionaryValue* cmd_args = nullptr;
scoped_refptr<ServiceWorkerContextWrapper> context;
if (!args->GetInteger(0, &callback_id) ||
!args->GetDictionary(1, &cmd_args) ||
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 f80422a0ff3..d264b6ce204 100644
--- a/chromium/content/browser/service_worker/service_worker_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_job_unittest.cc
@@ -24,7 +24,7 @@
#include "content/browser/service_worker/service_worker_handle.h"
#include "content/browser/service_worker/service_worker_job_coordinator.h"
#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/browser/service_worker/service_worker_registration_handle.h"
+#include "content/browser/service_worker/service_worker_registration_object_host.h"
#include "content/browser/service_worker/service_worker_registration_status.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/common/service_worker/embedded_worker_messages.h"
@@ -38,7 +38,9 @@
#include "net/base/test_completion_callback.h"
#include "net/http/http_response_headers.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
using net::IOBuffer;
@@ -50,8 +52,7 @@ namespace content {
namespace {
-// A dispatcher host that holds on to all registered ServiceWorkerHandles and
-// ServiceWorkerRegistrationHandles.
+// A dispatcher host that holds on to all registered ServiceWorkerHandles.
class KeepHandlesDispatcherHost : public ServiceWorkerDispatcherHost {
public:
KeepHandlesDispatcherHost(int render_process_id,
@@ -61,40 +62,19 @@ class KeepHandlesDispatcherHost : public ServiceWorkerDispatcherHost {
std::unique_ptr<ServiceWorkerHandle> handle) override {
handles_.push_back(std::move(handle));
}
- void RegisterServiceWorkerRegistrationHandle(
- ServiceWorkerRegistrationHandle* handle) override {
- registration_handles_.push_back(base::WrapUnique(handle));
- }
- void UnregisterServiceWorkerRegistrationHandle(int handle_id) override {
- auto iter = registration_handles_.begin();
- for (; iter != registration_handles_.end(); ++iter) {
- if ((*iter)->handle_id() == handle_id)
- break;
- }
- ASSERT_NE(registration_handles_.end(), iter);
- registration_handles_.erase(iter);
- }
- void RemoveHandles() {
+ void Clear() {
handles_.clear();
- registration_handles_.clear();
}
const std::vector<std::unique_ptr<ServiceWorkerHandle>>& handles() {
return handles_;
}
- const std::vector<std::unique_ptr<ServiceWorkerRegistrationHandle>>&
- registration_handles() {
- return registration_handles_;
- }
-
private:
~KeepHandlesDispatcherHost() override {}
std::vector<std::unique_ptr<ServiceWorkerHandle>> handles_;
- std::vector<std::unique_ptr<ServiceWorkerRegistrationHandle>>
- registration_handles_;
DISALLOW_COPY_AND_ASSIGN(KeepHandlesDispatcherHost);
};
@@ -161,25 +141,6 @@ ServiceWorkerUnregisterJob::UnregistrationCallback SaveUnregistration(
return base::Bind(&SaveUnregistrationCallback, expected_status, called);
}
-// This is for the test of mojom::ServiceWorkerInstallEventMethods.
-void RegisterForeignFetchScopes(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client) {
- GURL valid_scope_1("http://www.example.com/test/subscope");
- GURL valid_scope_2("http://www.example.com/test/othersubscope");
- std::vector<GURL> valid_scopes;
- valid_scopes.push_back(valid_scope_1);
- valid_scopes.push_back(valid_scope_2);
-
- std::vector<url::Origin> all_origins;
- url::Origin valid_origin(GURL("https://chromium.org/"));
- std::vector<url::Origin> valid_origin_list(1, valid_origin);
-
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtr install_event_methods;
- install_event_methods.Bind(std::move(client));
- install_event_methods->RegisterForeignFetchScopes(valid_scopes,
- valid_origin_list);
-}
-
} // namespace
class ServiceWorkerJobTest : public testing::Test {
@@ -355,54 +316,27 @@ TEST_F(ServiceWorkerJobTest, DifferentMatchDifferentRegistration) {
ASSERT_NE(registration1, registration2);
}
-class RegisterForeignFetchTestHelper : public EmbeddedWorkerTestHelper {
- public:
- RegisterForeignFetchTestHelper()
- : EmbeddedWorkerTestHelper(base::FilePath()) {}
-
- void OnInstallEvent(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client,
- mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
- callback) override {
- RegisterForeignFetchScopes(std::move(client));
- dispatched_events()->push_back(Event::Install);
- std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- true /* has_fetch_handler */, base::Time::Now());
- }
-};
-
// Make sure basic registration is working.
TEST_F(ServiceWorkerJobTest, Register) {
- helper_.reset(new RegisterForeignFetchTestHelper);
-
scoped_refptr<ServiceWorkerRegistration> registration =
RunRegisterJob(GURL("http://www.example.com/"),
GURL("http://www.example.com/service_worker.js"));
- ASSERT_NE(scoped_refptr<ServiceWorkerRegistration>(nullptr), registration);
+ EXPECT_TRUE(registration);
EXPECT_EQ(EmbeddedWorkerTestHelper::Event::Install,
helper_->dispatched_events()->at(0));
EXPECT_EQ(EmbeddedWorkerTestHelper::Event::Activate,
helper_->dispatched_events()->at(1));
-
- GURL valid_scope_1("http://www.example.com/test/subscope");
- GURL valid_scope_2("http://www.example.com/test/othersubscope");
- url::Origin valid_origin(GURL("https://chromium.org/"));
-
- ServiceWorkerVersion* version_ = registration->active_version();
- EXPECT_EQ(2u, version_->foreign_fetch_scopes_.size());
- EXPECT_EQ(valid_scope_1, version_->foreign_fetch_scopes_[0]);
- EXPECT_EQ(valid_scope_2, version_->foreign_fetch_scopes_[1]);
- EXPECT_EQ(1u, version_->foreign_fetch_origins_.size());
- EXPECT_EQ(valid_origin, version_->foreign_fetch_origins_[0]);
}
// Make sure registrations are cleaned up when they are unregistered.
TEST_F(ServiceWorkerJobTest, Unregister) {
GURL pattern("http://www.example.com/");
- // During registration, handles will be created for hosting the worker's
- // context. KeepHandlesDispatcherHost will store the handles.
+ // During registration, service worker handles will be created to host the
+ // {installing,waiting,active} service worker objects for
+ // ServiceWorkerGlobalScope#registration. KeepHandlesDispatcherHost will store
+ // the handles.
scoped_refptr<KeepHandlesDispatcherHost> dispatcher_host =
base::MakeRefCounted<KeepHandlesDispatcherHost>(
helper_->mock_render_process_id(),
@@ -414,22 +348,29 @@ TEST_F(ServiceWorkerJobTest, Unregister) {
scoped_refptr<ServiceWorkerRegistration> registration =
RunRegisterJob(pattern, GURL("http://www.example.com/service_worker.js"));
- EXPECT_EQ(1UL, dispatcher_host->registration_handles().size());
+ // During the above registration, a service worker registration object host
+ // for ServiceWorkerGlobalScope#registration has been created/added into
+ // |provider_host|.
+ ServiceWorkerProviderHost* provider_host =
+ registration->active_version()->provider_host();
+ ASSERT_NE(nullptr, provider_host);
+ EXPECT_EQ(1UL, provider_host->registration_object_hosts_.size());
EXPECT_EQ(3UL, dispatcher_host->handles().size());
RunUnregisterJob(pattern);
- // Remove the handles. The only reference to the registration object should be
- // |registration|.
- dispatcher_host->RemoveHandles();
- EXPECT_EQ(0UL, dispatcher_host->registration_handles().size());
+ // Clear all service worker handles.
+ dispatcher_host->Clear();
EXPECT_EQ(0UL, dispatcher_host->handles().size());
- ASSERT_TRUE(registration->HasOneRef());
+ // The service worker registration object host has been destroyed together
+ // with |provider_host| by the above unregistration. Then the only reference
+ // to the registration should be |registration|.
+ EXPECT_TRUE(registration->HasOneRef());
registration = FindRegistrationForPattern(pattern,
SERVICE_WORKER_ERROR_NOT_FOUND);
- ASSERT_EQ(scoped_refptr<ServiceWorkerRegistration>(nullptr), registration);
+ EXPECT_FALSE(registration);
}
TEST_F(ServiceWorkerJobTest, Unregister_NothingRegistered) {
@@ -483,10 +424,19 @@ TEST_F(ServiceWorkerJobTest, RegisterDuplicateScript) {
scoped_refptr<ServiceWorkerRegistration> old_registration =
RunRegisterJob(pattern, script_url);
- // Ensure that the registration's handle doesn't have the reference.
- EXPECT_EQ(1UL, dispatcher_host->registration_handles().size());
- dispatcher_host->RemoveHandles();
- EXPECT_EQ(0UL, dispatcher_host->registration_handles().size());
+ // During the above registration, a service worker registration object host
+ // for ServiceWorkerGlobalScope#registration has been created/added into
+ // |provider_host|.
+ ServiceWorkerProviderHost* provider_host =
+ old_registration->active_version()->provider_host();
+ ASSERT_NE(nullptr, provider_host);
+
+ // Clear all service worker handles.
+ dispatcher_host->Clear();
+ // Ensure that the registration's object host doesn't have the reference.
+ EXPECT_EQ(1UL, provider_host->registration_object_hosts_.size());
+ provider_host->registration_object_hosts_.clear();
+ EXPECT_EQ(0UL, provider_host->registration_object_hosts_.size());
ASSERT_TRUE(old_registration->HasOneRef());
scoped_refptr<ServiceWorkerRegistration> old_registration_by_pattern =
@@ -517,9 +467,12 @@ class FailToStartWorkerTestHelper : public EmbeddedWorkerTestHelper {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info)
override {
mojom::EmbeddedWorkerInstanceHostAssociatedPtr instance_host_ptr;
instance_host_ptr.Bind(std::move(instance_host));
@@ -977,9 +930,12 @@ class UpdateJobTestHelper
const GURL& scope,
const GURL& script,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info)
override {
const std::string kMockScriptBody = "mock_script";
const uint64_t kMockScriptSize = 19284;
@@ -1037,7 +993,9 @@ class UpdateJobTestHelper
started_workers_.insert(embedded_worker_id);
EmbeddedWorkerTestHelper::OnStartWorker(
embedded_worker_id, version_id, scope, script, pause_after_download,
- std::move(request), std::move(instance_host), std::move(provider_info));
+ std::move(dispatcher_request), std::move(controller_request),
+ std::move(service_worker_host), std::move(instance_host),
+ std::move(provider_info), std::move(installed_scripts_info));
}
void OnStopWorker(int embedded_worker_id) override {
@@ -1110,9 +1068,12 @@ class EvictIncumbentVersionHelper : public UpdateJobTestHelper {
const GURL& scope,
const GURL& script,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info)
override {
ServiceWorkerVersion* version = context()->GetLiveVersion(version_id);
ServiceWorkerRegistration* registration =
@@ -1127,7 +1088,9 @@ class EvictIncumbentVersionHelper : public UpdateJobTestHelper {
}
UpdateJobTestHelper::OnStartWorker(
embedded_worker_id, version_id, scope, script, pause_after_download,
- std::move(request), std::move(instance_host), std::move(provider_info));
+ std::move(dispatcher_request), std::move(controller_request),
+ std::move(service_worker_host), std::move(instance_host),
+ std::move(provider_info), std::move(installed_scripts_info));
}
void OnRegistrationFailed(ServiceWorkerRegistration* registration) override {
@@ -1254,33 +1217,33 @@ TEST_F(ServiceWorkerJobTest, Update_NewVersion) {
EXPECT_FALSE(entry.mask.waiting_changed());
EXPECT_FALSE(entry.mask.active_changed());
EXPECT_NE(entry.info.installing_version.version_id,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
EXPECT_EQ(entry.info.waiting_version.version_id,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
EXPECT_NE(entry.info.active_version.version_id,
- kInvalidServiceWorkerVersionId);
+ 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,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
EXPECT_NE(entry.info.waiting_version.version_id,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
EXPECT_NE(entry.info.active_version.version_id,
- kInvalidServiceWorkerVersionId);
+ 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,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
EXPECT_EQ(entry.info.waiting_version.version_id,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
EXPECT_NE(entry.info.active_version.version_id,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
// expected version state transitions:
// new.installing, new.installed,
@@ -1618,7 +1581,6 @@ class EventCallbackHelper : public EmbeddedWorkerTestHelper {
blink::mojom::ServiceWorkerEventStatus::COMPLETED) {}
void OnInstallEvent(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client,
mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
callback) override {
if (!install_callback_.is_null())
@@ -1805,8 +1767,10 @@ class CheckPauseAfterDownloadEmbeddedWorkerInstanceClient
protected:
void StartWorker(
const EmbeddedWorkerStartParams& params,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
mojom::ServiceWorkerInstalledScriptsInfoPtr scripts_info,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy)
@@ -1815,7 +1779,8 @@ class CheckPauseAfterDownloadEmbeddedWorkerInstanceClient
EXPECT_EQ(next_pause_after_download_.value(), params.pause_after_download);
num_of_startworker_++;
EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StartWorker(
- params, std::move(request), std::move(scripts_info),
+ params, std::move(dispatcher_request), std::move(controller_request),
+ std::move(scripts_info), std::move(service_worker_host),
std::move(instance_host), std::move(provider_info),
std::move(content_settings_proxy));
}
diff --git a/chromium/content/browser/service_worker/service_worker_lifetime_tracker.cc b/chromium/content/browser/service_worker/service_worker_lifetime_tracker.cc
index 4691bddfce4..6a6d28cf062 100644
--- a/chromium/content/browser/service_worker/service_worker_lifetime_tracker.cc
+++ b/chromium/content/browser/service_worker/service_worker_lifetime_tracker.cc
@@ -12,12 +12,11 @@
namespace content {
ServiceWorkerLifetimeTracker::ServiceWorkerLifetimeTracker()
- : ServiceWorkerLifetimeTracker(base::MakeUnique<base::DefaultTickClock>()) {
-}
+ : ServiceWorkerLifetimeTracker(base::DefaultTickClock::GetInstance()) {}
ServiceWorkerLifetimeTracker::ServiceWorkerLifetimeTracker(
- std::unique_ptr<base::TickClock> tick_clock)
- : tick_clock_(std::move(tick_clock)) {}
+ base::TickClock* tick_clock)
+ : tick_clock_(tick_clock) {}
ServiceWorkerLifetimeTracker::~ServiceWorkerLifetimeTracker() = default;
diff --git a/chromium/content/browser/service_worker/service_worker_lifetime_tracker.h b/chromium/content/browser/service_worker/service_worker_lifetime_tracker.h
index b9cb2bcba40..12b0eb16c23 100644
--- a/chromium/content/browser/service_worker/service_worker_lifetime_tracker.h
+++ b/chromium/content/browser/service_worker/service_worker_lifetime_tracker.h
@@ -22,8 +22,7 @@ namespace content {
class CONTENT_EXPORT ServiceWorkerLifetimeTracker {
public:
ServiceWorkerLifetimeTracker();
- explicit ServiceWorkerLifetimeTracker(
- std::unique_ptr<base::TickClock> tick_clock);
+ explicit ServiceWorkerLifetimeTracker(base::TickClock* tick_clock);
virtual ~ServiceWorkerLifetimeTracker();
// Called when the worker started running.
@@ -39,7 +38,7 @@ class CONTENT_EXPORT ServiceWorkerLifetimeTracker {
void RecordHistograms();
- std::unique_ptr<base::TickClock> tick_clock_;
+ base::TickClock* tick_clock_;
std::map<int64_t /* embedded_worker_id */, base::TimeTicks /* start_time */>
running_workers_;
diff --git a/chromium/content/browser/service_worker/service_worker_lifetime_tracker_unittest.cc b/chromium/content/browser/service_worker/service_worker_lifetime_tracker_unittest.cc
index 7575482650e..9b42bdbfa73 100644
--- a/chromium/content/browser/service_worker/service_worker_lifetime_tracker_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_lifetime_tracker_unittest.cc
@@ -14,16 +14,13 @@ namespace content {
class ServiceWorkerLifetimeTrackerTest : public testing::Test {
public:
- ServiceWorkerLifetimeTrackerTest()
- : tick_clock_(new base::SimpleTestTickClock()),
- tracker_(base::WrapUnique(tick_clock_)) {}
+ ServiceWorkerLifetimeTrackerTest() : tracker_(&tick_clock_) {}
- base::SimpleTestTickClock* tick_clock() { return tick_clock_; }
+ base::SimpleTestTickClock* tick_clock() { return &tick_clock_; }
ServiceWorkerLifetimeTracker* tracker() { return &tracker_; }
private:
- // Not owned.
- base::SimpleTestTickClock* tick_clock_;
+ base::SimpleTestTickClock tick_clock_;
ServiceWorkerLifetimeTracker tracker_;
};
diff --git a/chromium/content/browser/service_worker/service_worker_metrics.cc b/chromium/content/browser/service_worker/service_worker_metrics.cc
index 66a71373906..1cd81ef3cdd 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics.cc
+++ b/chromium/content/browser/service_worker/service_worker_metrics.cc
@@ -15,6 +15,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
+#include "net/url_request/url_request.h"
namespace content {
@@ -474,12 +475,13 @@ void ServiceWorkerMetrics::CountControlledPageLoad(
"ServiceWorker.MainFramePageLoad.CoreTransition",
static_cast<int>(ui::PageTransitionStripQualifier(page_transition)),
static_cast<int>(ui::PAGE_TRANSITION_LAST_CORE) + 1);
- // Currently the max number of HTTP redirects is 20 which is defined as
- // kMaxRedirects in net/url_request/url_request.cc. So the max number of the
- // chain length is 21.
+ // Currently the max number of HTTP redirects is 20 as defined in
+ // net::URLRequest::kMaxRedirects in
+ // net/url_request/url_request.h. So the max number of the chain
+ // length is 21.
UMA_HISTOGRAM_EXACT_LINEAR(
"ServiceWorker.MainFramePageLoad.RedirectChainLength",
- redirect_chain_length, 21);
+ redirect_chain_length, net::URLRequest::kMaxRedirects + 1);
}
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
@@ -780,21 +782,23 @@ void ServiceWorkerMetrics::RecordURLRequestJobResult(
void ServiceWorkerMetrics::RecordStatusZeroResponseError(
bool is_main_resource,
- blink::WebServiceWorkerResponseError error) {
+ blink::mojom::ServiceWorkerResponseError error) {
if (is_main_resource) {
UMA_HISTOGRAM_ENUMERATION(
"ServiceWorker.URLRequestJob.MainResource.StatusZeroError", error,
- blink::kWebServiceWorkerResponseErrorLast + 1);
+ static_cast<int>(blink::mojom::ServiceWorkerResponseError::kLast) + 1);
} else {
UMA_HISTOGRAM_ENUMERATION(
"ServiceWorker.URLRequestJob.Subresource.StatusZeroError", error,
- blink::kWebServiceWorkerResponseErrorLast + 1);
+ static_cast<int>(blink::mojom::ServiceWorkerResponseError::kLast) + 1);
}
}
-void ServiceWorkerMetrics::RecordFallbackedRequestMode(FetchRequestMode mode) {
- UMA_HISTOGRAM_ENUMERATION("ServiceWorker.URLRequestJob.FallbackedRequestMode",
- mode, FETCH_REQUEST_MODE_LAST + 1);
+void ServiceWorkerMetrics::RecordFallbackedRequestMode(
+ network::mojom::FetchRequestMode mode) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "ServiceWorker.URLRequestJob.FallbackedRequestMode", mode,
+ static_cast<int>(network::mojom::FetchRequestMode::kLast) + 1);
}
void ServiceWorkerMetrics::RecordProcessCreated(bool is_new_process) {
diff --git a/chromium/content/browser/service_worker/service_worker_metrics.h b/chromium/content/browser/service_worker/service_worker_metrics.h
index e4ab5bd78c5..80d21e7833b 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics.h
+++ b/chromium/content/browser/service_worker/service_worker_metrics.h
@@ -18,7 +18,7 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/common/service_worker_modes.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponseError.h"
+#include "services/network/public/interfaces/fetch_api.mojom.h"
#include "ui/base/page_transition_types.h"
class GURL;
@@ -333,10 +333,11 @@ class ServiceWorkerMetrics {
// status zero to a fetch request.
static void RecordStatusZeroResponseError(
bool is_main_resource,
- blink::WebServiceWorkerResponseError error);
+ blink::mojom::ServiceWorkerResponseError error);
// Records the mode of request that was fallbacked to the network.
- static void RecordFallbackedRequestMode(FetchRequestMode mode);
+ static void RecordFallbackedRequestMode(
+ network::mojom::FetchRequestMode mode);
// Called at the beginning of each ServiceWorkerVersion::Dispatch*Event
// function. Records the time elapsed since idle (generally the time since the
diff --git a/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc b/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc
index 01dca660bbe..52c632673d8 100644
--- a/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc
@@ -43,7 +43,7 @@ class ServiceWorkerProcessManagerTest : public testing::Test {
}
std::unique_ptr<MockRenderProcessHost> CreateRenderProcessHost() {
- return base::MakeUnique<MockRenderProcessHost>(browser_context_.get());
+ return std::make_unique<MockRenderProcessHost>(browser_context_.get());
}
protected:
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 aa52f1b82b3..ca80f936236 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_provider_host.cc
@@ -13,22 +13,26 @@
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "content/browser/bad_message.h"
-#include "content/browser/service_worker/browser_side_controller_service_worker.h"
+#include "content/browser/interface_provider_filtering.h"
+#include "content/browser/renderer_interface_binders.h"
#include "content/browser/service_worker/embedded_worker_status.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_context_request_handler.h"
#include "content/browser/service_worker/service_worker_controllee_request_handler.h"
#include "content/browser/service_worker/service_worker_dispatcher_host.h"
#include "content/browser/service_worker/service_worker_handle.h"
-#include "content/browser/service_worker/service_worker_registration_handle.h"
+#include "content/browser/service_worker/service_worker_registration_object_host.h"
#include "content/browser/service_worker/service_worker_script_url_loader_factory.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_impl.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.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/web_contents.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/child_process_host.h"
@@ -38,27 +42,15 @@
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "net/base/url_util.h"
#include "storage/browser/blob/blob_storage_context.h"
+#include "third_party/WebKit/common/message_port/message_port_channel.h"
+#include "third_party/WebKit/common/service_worker/service_worker_client.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
namespace content {
namespace {
-const char kNoDocumentURLErrorMessage[] =
- "No URL is associated with the caller's document.";
-const char kShutdownErrorMessage[] = "The Service Worker system has shutdown.";
-const char kUserDeniedPermissionMessage[] =
- "The user denied permission to use Service Worker.";
-
-const char kBadMessageInvalidURL[] = "Some URLs are invalid.";
-const char kBadMessageInproperOrigins[] =
- "Origins are not matching, or some cannot access service worker.";
-const char kBadMessageFromNonWindow[] =
- "The request message should not come from a non-window client.";
-const char kBadMessageGetRegistrationForReadyDuplicated[] =
- "There's already a completed or ongoing request to get the ready "
- "registration.";
-
// Provider host for navigation with PlzNavigate or when service worker's
// context is created on the browser side. This function provides the next
// ServiceWorkerProviderHost ID for them, starts at -2 and keeps going down.
@@ -97,6 +89,19 @@ class ServiceWorkerURLTrackingRequestHandler
return nullptr;
}
+ void MaybeCreateLoader(const ResourceRequest& resource_request,
+ ResourceContext*,
+ LoaderCallback callback) override {
+ // |provider_host_| may have been deleted when the request is resumed.
+ if (!provider_host_)
+ return;
+ const GURL stripped_url = net::SimplifyUrlForRequest(resource_request.url);
+ provider_host_->SetDocumentUrl(stripped_url);
+ provider_host_->SetTopmostFrameUrl(resource_request.site_for_cookies);
+ // Fall back to network.
+ std::move(callback).Run(StartLoaderCallback());
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerURLTrackingRequestHandler);
};
@@ -118,10 +123,17 @@ void RemoveProviderHost(base::WeakPtr<ServiceWorkerContextCore> context,
context->RemoveProviderHost(process_id, provider_id);
}
-WebContents* GetWebContents(int render_process_id, int render_frame_id) {
- RenderFrameHost* rfh =
- RenderFrameHost::FromID(render_process_id, render_frame_id);
- return WebContents::FromRenderFrameHost(rfh);
+void GetInterfaceImpl(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe,
+ const url::Origin& origin,
+ int process_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ auto* process = RenderProcessHost::FromID(process_id);
+ if (!process)
+ return;
+
+ BindWorkerInterface(interface_name, std::move(interface_pipe), process,
+ origin);
}
} // anonymous namespace
@@ -137,7 +149,8 @@ ServiceWorkerProviderHost::PreCreateNavigationHost(
ChildProcessHost::kInvalidUniqueID,
ServiceWorkerProviderHostInfo(
NextBrowserProvidedProviderId(), MSG_ROUTING_NONE,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW, are_ancestors_secure),
+ blink::mojom::ServiceWorkerProviderType::kForWindow,
+ are_ancestors_secure),
context, nullptr /* dispatcher_host */));
host->web_contents_getter_ = web_contents_getter;
return host;
@@ -149,10 +162,10 @@ ServiceWorkerProviderHost::PreCreateForController(
base::WeakPtr<ServiceWorkerContextCore> context) {
auto host = base::WrapUnique(new ServiceWorkerProviderHost(
ChildProcessHost::kInvalidUniqueID,
- ServiceWorkerProviderHostInfo(NextBrowserProvidedProviderId(),
- MSG_ROUTING_NONE,
- SERVICE_WORKER_PROVIDER_FOR_CONTROLLER,
- true /* is_parent_frame_secure */),
+ ServiceWorkerProviderHostInfo(
+ NextBrowserProvidedProviderId(), MSG_ROUTING_NONE,
+ blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
+ true /* is_parent_frame_secure */),
std::move(context), nullptr));
return host;
}
@@ -180,10 +193,12 @@ ServiceWorkerProviderHost::ServiceWorkerProviderHost(
context_(context),
dispatcher_host_(dispatcher_host),
allow_association_(true),
- binding_(this) {
- DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type);
+ binding_(this),
+ interface_provider_binding_(this) {
+ DCHECK_NE(blink::mojom::ServiceWorkerProviderType::kUnknown, info_.type);
- if (info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) {
+ if (info_.type ==
+ blink::mojom::ServiceWorkerProviderType::kForServiceWorker) {
// Actual |render_process_id| will be set after choosing a process for the
// controller, and |render_thread id| will be set when the service worker
// context gets started.
@@ -198,11 +213,12 @@ ServiceWorkerProviderHost::ServiceWorkerProviderHost(
context_->RegisterProviderHostByClientID(client_uuid_, this);
// |client_| and |binding_| will be bound on CompleteNavigationInitialized
- // (PlzNavigate) or on CompleteStartWorkerPreparation (providers for
- // controller).
+ // (providers for clients created during PlzNavigate) or on
+ // CompleteStartWorkerPreparation (providers for service workers).
if (!info_.client_ptr_info.is_valid() && !info_.host_request.is_pending()) {
DCHECK(IsBrowserSideNavigationEnabled() ||
- info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER);
+ info_.type ==
+ blink::mojom::ServiceWorkerProviderType::kForServiceWorker);
return;
}
@@ -231,7 +247,7 @@ ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
}
int ServiceWorkerProviderHost::frame_id() const {
- if (info_.type == SERVICE_WORKER_PROVIDER_FOR_WINDOW)
+ if (info_.type == blink::mojom::ServiceWorkerProviderType::kForWindow)
return info_.route_id;
return MSG_ROUTING_NONE;
}
@@ -319,52 +335,44 @@ void ServiceWorkerProviderHost::SetControllerVersionAttribute(
scoped_refptr<ServiceWorkerVersion> previous_version = controller_;
controller_ = version;
- // This will drop the message pipes to the client pages as well.
- controller_service_worker_.reset();
-
- if (version) {
+ if (version)
version->AddControllee(this);
- controller_service_worker_ =
- base::MakeUnique<BrowserSideControllerServiceWorker>(version);
- }
+
if (previous_version.get())
previous_version->RemoveControllee(this);
- // SetController message should be sent only for controllees.
+ // SetController message should be sent only for clients.
DCHECK(IsProviderForClient());
SendSetControllerServiceWorker(version, notify_controllerchange);
}
bool ServiceWorkerProviderHost::IsProviderForClient() const {
switch (info_.type) {
- case SERVICE_WORKER_PROVIDER_FOR_WINDOW:
- case SERVICE_WORKER_PROVIDER_FOR_WORKER:
- case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER:
+ case blink::mojom::ServiceWorkerProviderType::kForWindow:
+ case blink::mojom::ServiceWorkerProviderType::kForSharedWorker:
return true;
- case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER:
+ case blink::mojom::ServiceWorkerProviderType::kForServiceWorker:
return false;
- case SERVICE_WORKER_PROVIDER_UNKNOWN:
+ case blink::mojom::ServiceWorkerProviderType::kUnknown:
NOTREACHED() << info_.type;
}
NOTREACHED() << info_.type;
return false;
}
-blink::WebServiceWorkerClientType ServiceWorkerProviderHost::client_type()
+blink::mojom::ServiceWorkerClientType ServiceWorkerProviderHost::client_type()
const {
switch (info_.type) {
- case SERVICE_WORKER_PROVIDER_FOR_WINDOW:
- return blink::kWebServiceWorkerClientTypeWindow;
- case SERVICE_WORKER_PROVIDER_FOR_WORKER:
- return blink::kWebServiceWorkerClientTypeWorker;
- case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER:
- return blink::kWebServiceWorkerClientTypeSharedWorker;
- case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER:
- case SERVICE_WORKER_PROVIDER_UNKNOWN:
+ case blink::mojom::ServiceWorkerProviderType::kForWindow:
+ return blink::mojom::ServiceWorkerClientType::kWindow;
+ case blink::mojom::ServiceWorkerProviderType::kForSharedWorker:
+ return blink::mojom::ServiceWorkerClientType::kSharedWorker;
+ case blink::mojom::ServiceWorkerProviderType::kForServiceWorker:
+ case blink::mojom::ServiceWorkerProviderType::kUnknown:
NOTREACHED() << info_.type;
}
NOTREACHED() << info_.type;
- return blink::kWebServiceWorkerClientTypeWindow;
+ return blink::mojom::ServiceWorkerClientType::kWindow;
}
void ServiceWorkerProviderHost::AssociateRegistration(
@@ -426,16 +434,30 @@ ServiceWorkerProviderHost::MatchRegistration() const {
return nullptr;
}
+void ServiceWorkerProviderHost::RemoveServiceWorkerRegistrationObjectHost(
+ int64_t registration_id) {
+ DCHECK(base::ContainsKey(registration_object_hosts_, registration_id));
+ registration_object_hosts_.erase(registration_id);
+}
+
+bool ServiceWorkerProviderHost::AllowServiceWorker(const GURL& scope) {
+ return GetContentClient()->browser()->AllowServiceWorker(
+ scope, topmost_frame_url(), dispatcher_host_->resource_context(),
+ base::Bind(&WebContentsImpl::FromRenderFrameHostID, render_process_id_,
+ frame_id()));
+}
+
void ServiceWorkerProviderHost::NotifyControllerLost() {
SetControllerVersionAttribute(nullptr, true /* notify_controllerchange */);
}
std::unique_ptr<ServiceWorkerRequestHandler>
ServiceWorkerProviderHost::CreateRequestHandler(
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
+ network::mojom::FetchRequestMode request_mode,
+ network::mojom::FetchCredentialsMode credentials_mode,
FetchRedirectMode redirect_mode,
const std::string& integrity,
+ bool keepalive,
ResourceType resource_type,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
@@ -459,40 +481,40 @@ ServiceWorkerProviderHost::CreateRequestHandler(
if (skip_service_worker) {
if (!ServiceWorkerUtils::IsMainResourceType(resource_type))
return std::unique_ptr<ServiceWorkerRequestHandler>();
- return base::MakeUnique<ServiceWorkerURLTrackingRequestHandler>(
+ return std::make_unique<ServiceWorkerURLTrackingRequestHandler>(
context_, AsWeakPtr(), blob_storage_context, resource_type);
}
if (IsHostToRunningServiceWorker()) {
- return base::MakeUnique<ServiceWorkerContextRequestHandler>(
+ return std::make_unique<ServiceWorkerContextRequestHandler>(
context_, AsWeakPtr(), blob_storage_context, resource_type);
}
if (ServiceWorkerUtils::IsMainResourceType(resource_type) || controller()) {
- return base::MakeUnique<ServiceWorkerControlleeRequestHandler>(
+ return std::make_unique<ServiceWorkerControlleeRequestHandler>(
context_, AsWeakPtr(), blob_storage_context, request_mode,
- credentials_mode, redirect_mode, integrity, resource_type,
+ credentials_mode, redirect_mode, integrity, keepalive, resource_type,
request_context_type, frame_type, body);
}
return std::unique_ptr<ServiceWorkerRequestHandler>();
}
-ServiceWorkerObjectInfo
+blink::mojom::ServiceWorkerObjectInfoPtr
ServiceWorkerProviderHost::GetOrCreateServiceWorkerHandle(
ServiceWorkerVersion* version) {
DCHECK(dispatcher_host_);
if (!context_ || !version)
- return ServiceWorkerObjectInfo();
+ return blink::mojom::ServiceWorkerObjectInfo::New();
ServiceWorkerHandle* handle = dispatcher_host_->FindServiceWorkerHandle(
provider_id(), version->version_id());
if (handle) {
handle->IncrementRefCount();
- return handle->GetObjectInfo();
+ return handle->CreateObjectInfo();
}
std::unique_ptr<ServiceWorkerHandle> new_handle(
ServiceWorkerHandle::Create(context_, AsWeakPtr(), version));
handle = new_handle.get();
dispatcher_host_->RegisterServiceWorkerHandle(std::move(new_handle));
- return handle->GetObjectInfo();
+ return handle->CreateObjectInfo();
}
bool ServiceWorkerProviderHost::CanAssociateRegistration(
@@ -510,26 +532,27 @@ void ServiceWorkerProviderHost::PostMessageToClient(
ServiceWorkerVersion* version,
const base::string16& message,
const std::vector<blink::MessagePortChannel>& sent_message_ports) {
+ DCHECK(IsProviderForClient());
if (!dispatcher_host_)
return;
- ServiceWorkerMsg_MessageToDocument_Params params;
- params.thread_id = kDocumentMainThreadId;
- params.provider_id = provider_id();
- params.service_worker_info = GetOrCreateServiceWorkerHandle(version);
- params.message = message;
- params.message_ports = sent_message_ports;
- Send(new ServiceWorkerMsg_MessageToDocument(params));
+ auto message_pipes =
+ blink::MessagePortChannel::ReleaseHandles(sent_message_ports);
+ container_->PostMessageToClient(GetOrCreateServiceWorkerHandle(version),
+ message, std::move(message_pipes));
}
void ServiceWorkerProviderHost::CountFeature(uint32_t feature) {
if (!dispatcher_host_)
return;
-
- // CountFeature message should be sent only for controllees.
+ // CountFeature message should be sent only for clients.
DCHECK(IsProviderForClient());
- Send(new ServiceWorkerMsg_CountFeature(render_thread_id_, provider_id(),
- feature));
+ DCHECK_LT(feature,
+ static_cast<uint32_t>(blink::mojom::WebFeature::kNumberOfFeatures));
+
+ blink::mojom::WebFeature web_feature =
+ static_cast<blink::mojom::WebFeature>(feature);
+ container_->CountFeature(web_feature);
}
void ServiceWorkerProviderHost::AddScopedProcessReferenceToPattern(
@@ -557,7 +580,14 @@ ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() {
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_);
DCHECK_NE(MSG_ROUTING_NONE, info_.route_id);
DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
- DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type);
+ DCHECK_NE(blink::mojom::ServiceWorkerProviderType::kUnknown, info_.type);
+
+ // Clear the controller from the renderer-side provider, since no one knows
+ // what's going to happen until after cross-site transfer finishes.
+ if (controller_) {
+ SendSetControllerServiceWorker(nullptr,
+ false /* notify_controllerchange */);
+ }
std::unique_ptr<ServiceWorkerProviderHost> provisional_host =
base::WrapUnique(new ServiceWorkerProviderHost(
@@ -571,13 +601,6 @@ ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() {
RemoveAllMatchingRegistrations();
- // Clear the controller from the renderer-side provider, since no one knows
- // what's going to happen until after cross-site transfer finishes.
- if (controller_) {
- SendSetControllerServiceWorker(nullptr,
- false /* notify_controllerchange */);
- }
-
render_process_id_ = ChildProcessHost::kInvalidUniqueID;
render_thread_id_ = kInvalidEmbeddedWorkerThreadId;
dispatcher_host_ = nullptr;
@@ -627,7 +650,7 @@ void ServiceWorkerProviderHost::CompleteNavigationInitialized(
base::WeakPtr<ServiceWorkerDispatcherHost> dispatcher_host) {
CHECK(IsBrowserSideNavigationEnabled());
DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_);
- DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, info_.type);
+ DCHECK_EQ(blink::mojom::ServiceWorkerProviderType::kForWindow, info_.type);
DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id);
@@ -667,7 +690,8 @@ ServiceWorkerProviderHost::CompleteStartWorkerPreparation(
DCHECK(context_);
DCHECK_EQ(kInvalidEmbeddedWorkerThreadId, render_thread_id_);
DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_);
- DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, provider_type());
+ DCHECK_EQ(blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
+ provider_type());
DCHECK(!running_hosted_version_);
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id);
@@ -685,23 +709,19 @@ ServiceWorkerProviderHost::CompleteStartWorkerPreparation(
ServiceWorkerRegistration* registration = context_->GetLiveRegistration(
running_hosted_version()->registration_id());
DCHECK(registration);
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- dispatcher_host->GetRegistrationObjectInfoAndVersionAttributes(
- AsWeakPtr(), registration, &info, &attrs);
// Initialize provider_info.
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
mojom::ServiceWorkerProviderInfoForStartWorker::New();
provider_info->provider_id = provider_id();
- provider_info->attributes = std::move(attrs);
- provider_info->registration = std::move(info);
+ provider_info->registration = CreateServiceWorkerRegistrationObjectInfo(
+ scoped_refptr<ServiceWorkerRegistration>(registration));
provider_info->client_request = mojo::MakeRequest(&container_);
mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory_ptr_info;
if (ServiceWorkerUtils::IsServicificationEnabled()) {
mojo::MakeStrongAssociatedBinding(
- base::MakeUnique<ServiceWorkerScriptURLLoaderFactory>(
+ std::make_unique<ServiceWorkerScriptURLLoaderFactory>(
context_, AsWeakPtr(), context_->loader_factory_getter()),
mojo::MakeRequest(&script_loader_factory_ptr_info));
provider_info->script_loader_factory_ptr_info =
@@ -712,6 +732,10 @@ ServiceWorkerProviderHost::CompleteStartWorkerPreparation(
binding_.set_connection_error_handler(
base::BindOnce(&RemoveProviderHost, context_, process_id, provider_id()));
+ interface_provider_binding_.Bind(FilterRendererExposedInterfaces(
+ mojom::kNavigation_ServiceWorkerSpec, process_id,
+ mojo::MakeRequest(&provider_info->interface_provider)));
+
// Set the document URL to the script url in order to allow
// register/unregister/getRegistration on ServiceWorkerGlobalScope.
SetDocumentUrl(running_hosted_version()->script_url());
@@ -719,55 +743,6 @@ ServiceWorkerProviderHost::CompleteStartWorkerPreparation(
return provider_info;
}
-void ServiceWorkerProviderHost::SendUpdateFoundMessage(
- int registration_handle_id) {
- if (!dispatcher_host_)
- return;
-
- if (!IsReadyToSendMessages()) {
- queued_events_.push_back(
- base::Bind(&ServiceWorkerProviderHost::SendUpdateFoundMessage,
- AsWeakPtr(), registration_handle_id));
- return;
- }
-
- Send(new ServiceWorkerMsg_UpdateFound(
- render_thread_id_, registration_handle_id));
-}
-
-void ServiceWorkerProviderHost::SendSetVersionAttributesMessage(
- int registration_handle_id,
- ChangedVersionAttributesMask changed_mask,
- ServiceWorkerVersion* installing_version,
- ServiceWorkerVersion* waiting_version,
- ServiceWorkerVersion* active_version) {
- if (!dispatcher_host_)
- return;
- if (!changed_mask.changed())
- return;
-
- if (!IsReadyToSendMessages()) {
- queued_events_.push_back(base::Bind(
- &ServiceWorkerProviderHost::SendSetVersionAttributesMessage,
- AsWeakPtr(), registration_handle_id, changed_mask,
- base::RetainedRef(installing_version),
- base::RetainedRef(waiting_version), base::RetainedRef(active_version)));
- return;
- }
-
- ServiceWorkerVersionAttributes attrs;
- if (changed_mask.installing_changed())
- attrs.installing = GetOrCreateServiceWorkerHandle(installing_version);
- if (changed_mask.waiting_changed())
- attrs.waiting = GetOrCreateServiceWorkerHandle(waiting_version);
- if (changed_mask.active_changed())
- attrs.active = GetOrCreateServiceWorkerHandle(active_version);
-
- Send(new ServiceWorkerMsg_SetVersionAttributes(
- render_thread_id_, registration_handle_id, changed_mask.changed(),
- attrs));
-}
-
void ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage(
int worker_handle_id,
blink::mojom::ServiceWorkerState state) {
@@ -848,11 +823,9 @@ void ServiceWorkerProviderHost::ReturnRegistrationForReadyIfNeeded() {
return;
}
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- dispatcher_host_->GetRegistrationObjectInfoAndVersionAttributes(
- AsWeakPtr(), registration, &info, &attrs);
- std::move(*get_ready_callback_).Run(std::move(info), attrs);
+ std::move(*get_ready_callback_)
+ .Run(CreateServiceWorkerRegistrationObjectInfo(
+ scoped_refptr<ServiceWorkerRegistration>(registration)));
}
bool ServiceWorkerProviderHost::IsReadyToSendMessages() const {
@@ -881,33 +854,25 @@ void ServiceWorkerProviderHost::SendSetControllerServiceWorker(
DCHECK_EQ(controller_.get(), version);
}
- ServiceWorkerMsg_SetControllerServiceWorker_Params params;
- params.thread_id = render_thread_id_;
- params.provider_id = provider_id();
- params.object_info = GetOrCreateServiceWorkerHandle(version);
- params.should_notify_controllerchange = notify_controllerchange;
- if (version)
- params.used_features = version->used_features();
- Send(new ServiceWorkerMsg_SetControllerServiceWorker(params));
+ std::vector<blink::mojom::WebFeature> used_features;
+ if (version) {
+ for (const uint32_t feature : version->used_features()) {
+ DCHECK_LT(feature, static_cast<uint32_t>(
+ blink::mojom::WebFeature::kNumberOfFeatures));
+ used_features.push_back(static_cast<blink::mojom::WebFeature>(feature));
+ }
+ }
+ container_->SetController(GetOrCreateServiceWorkerHandle(version),
+ used_features, notify_controllerchange);
}
void ServiceWorkerProviderHost::Register(
const GURL& script_url,
blink::mojom::ServiceWorkerRegistrationOptionsPtr options,
RegisterCallback callback) {
- if (!dispatcher_host_ || !IsContextAlive()) {
- std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kAbort,
- std::string(kServiceWorkerRegisterErrorPrefix) +
- std::string(kShutdownErrorMessage),
- nullptr, base::nullopt);
- return;
- }
- // TODO(falken): This check can be removed once crbug.com/439697 is fixed.
- if (document_url().is_empty()) {
- std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kSecurity,
- std::string(kServiceWorkerRegisterErrorPrefix) +
- std::string(kNoDocumentURLErrorMessage),
- nullptr, base::nullopt);
+ if (!CanServeContainerHostMethods(&callback, options->scope,
+ kServiceWorkerRegisterErrorPrefix,
+ nullptr)) {
return;
}
@@ -917,18 +882,7 @@ void ServiceWorkerProviderHost::Register(
// ReportBadMessage() will kill the renderer process, but Mojo complains if
// the callback is not run. Just run it with nonsense arguments.
std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kUnknown,
- std::string(), nullptr, base::nullopt);
- return;
- }
-
- if (!GetContentClient()->browser()->AllowServiceWorker(
- options->scope, topmost_frame_url(),
- dispatcher_host_->resource_context(),
- base::Bind(&GetWebContents, render_process_id_, frame_id()))) {
- std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kDisabled,
- std::string(kServiceWorkerRegisterErrorPrefix) +
- std::string(kUserDeniedPermissionMessage),
- nullptr, base::nullopt);
+ std::string(), nullptr);
return;
}
@@ -953,10 +907,11 @@ void ServiceWorkerProviderHost::RegistrationComplete(
trace_id, "Status", status, "Registration ID",
registration_id);
if (!dispatcher_host_ || !IsContextAlive()) {
- std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kAbort,
- std::string(kServiceWorkerRegisterErrorPrefix) +
- std::string(kShutdownErrorMessage),
- nullptr, base::nullopt);
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kAbort,
+ std::string(kServiceWorkerRegisterErrorPrefix) +
+ std::string(ServiceWorkerConsts::kShutdownErrorMessage),
+ nullptr);
return;
}
@@ -965,9 +920,8 @@ void ServiceWorkerProviderHost::RegistrationComplete(
blink::mojom::ServiceWorkerErrorType error_type;
GetServiceWorkerErrorTypeForRegistration(status, status_message,
&error_type, &error_message);
- std::move(callback).Run(error_type,
- kServiceWorkerRegisterErrorPrefix + error_message,
- nullptr, base::nullopt);
+ std::move(callback).Run(
+ error_type, kServiceWorkerRegisterErrorPrefix + error_message, nullptr);
return;
}
@@ -977,33 +931,18 @@ void ServiceWorkerProviderHost::RegistrationComplete(
// this function being called, while the registration is live.
DCHECK(registration);
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- dispatcher_host_->GetRegistrationObjectInfoAndVersionAttributes(
- AsWeakPtr(), registration, &info, &attrs);
-
- std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
- base::nullopt, std::move(info), attrs);
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kNone, base::nullopt,
+ CreateServiceWorkerRegistrationObjectInfo(
+ scoped_refptr<ServiceWorkerRegistration>(registration)));
}
void ServiceWorkerProviderHost::GetRegistration(
const GURL& client_url,
GetRegistrationCallback callback) {
- if (!dispatcher_host_ || !IsContextAlive()) {
- std::move(callback).Run(
- blink::mojom::ServiceWorkerErrorType::kAbort,
- std::string(kServiceWorkerGetRegistrationErrorPrefix) +
- std::string(kShutdownErrorMessage),
- nullptr, base::nullopt);
- return;
- }
- // TODO(falken): This check can be removed once crbug.com/439697 is fixed.
- if (document_url().is_empty()) {
- std::move(callback).Run(
- blink::mojom::ServiceWorkerErrorType::kSecurity,
- std::string(kServiceWorkerGetRegistrationErrorPrefix) +
- std::string(kNoDocumentURLErrorMessage),
- nullptr, base::nullopt);
+ if (!CanServeContainerHostMethods(&callback, document_url(),
+ kServiceWorkerGetRegistrationErrorPrefix,
+ nullptr)) {
return;
}
@@ -1013,19 +952,7 @@ void ServiceWorkerProviderHost::GetRegistration(
// ReportBadMessage() will kill the renderer process, but Mojo complains if
// the callback is not run. Just run it with nonsense arguments.
std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kUnknown,
- std::string(), nullptr, base::nullopt);
- return;
- }
-
- if (!GetContentClient()->browser()->AllowServiceWorker(
- document_url(), topmost_frame_url(),
- dispatcher_host_->resource_context(),
- base::Bind(&GetWebContents, render_process_id_, frame_id()))) {
- std::move(callback).Run(
- blink::mojom::ServiceWorkerErrorType::kDisabled,
- std::string(kServiceWorkerGetRegistrationErrorPrefix) +
- std::string(kUserDeniedPermissionMessage),
- nullptr, base::nullopt);
+ std::string(), nullptr);
return;
}
@@ -1041,21 +968,9 @@ void ServiceWorkerProviderHost::GetRegistration(
void ServiceWorkerProviderHost::GetRegistrations(
GetRegistrationsCallback callback) {
- if (!dispatcher_host_ || !IsContextAlive()) {
- std::move(callback).Run(
- blink::mojom::ServiceWorkerErrorType::kAbort,
- std::string(kServiceWorkerGetRegistrationsErrorPrefix) +
- std::string(kShutdownErrorMessage),
- base::nullopt, base::nullopt);
- return;
- }
- // TODO(falken): This check can be removed once crbug.com/439697 is fixed.
- if (document_url().is_empty()) {
- std::move(callback).Run(
- blink::mojom::ServiceWorkerErrorType::kSecurity,
- std::string(kServiceWorkerGetRegistrationsErrorPrefix) +
- std::string(kNoDocumentURLErrorMessage),
- base::nullopt, base::nullopt);
+ if (!CanServeContainerHostMethods(&callback, document_url(),
+ kServiceWorkerGetRegistrationsErrorPrefix,
+ base::nullopt)) {
return;
}
@@ -1065,19 +980,7 @@ void ServiceWorkerProviderHost::GetRegistrations(
// ReportBadMessage() will kill the renderer process, but Mojo complains if
// the callback is not run. Just run it with nonsense arguments.
std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kUnknown,
- std::string(), base::nullopt, base::nullopt);
- return;
- }
-
- if (!GetContentClient()->browser()->AllowServiceWorker(
- document_url(), topmost_frame_url(),
- dispatcher_host_->resource_context(),
- base::Bind(&GetWebContents, render_process_id_, frame_id()))) {
- std::move(callback).Run(
- blink::mojom::ServiceWorkerErrorType::kDisabled,
- std::string(kServiceWorkerGetRegistrationsErrorPrefix) +
- std::string(kUserDeniedPermissionMessage),
- base::nullopt, base::nullopt);
+ std::string(), base::nullopt);
return;
}
@@ -1105,8 +1008,8 @@ void ServiceWorkerProviderHost::GetRegistrationComplete(
std::move(callback).Run(
blink::mojom::ServiceWorkerErrorType::kAbort,
std::string(kServiceWorkerGetRegistrationErrorPrefix) +
- std::string(kShutdownErrorMessage),
- nullptr, base::nullopt);
+ std::string(ServiceWorkerConsts::kShutdownErrorMessage),
+ nullptr);
return;
}
@@ -1117,23 +1020,17 @@ void ServiceWorkerProviderHost::GetRegistrationComplete(
&error_message);
std::move(callback).Run(
error_type, kServiceWorkerGetRegistrationErrorPrefix + error_message,
- nullptr, base::nullopt);
+ nullptr);
return;
}
- auto info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New();
- info->options = blink::mojom::ServiceWorkerRegistrationOptions::New();
- ServiceWorkerVersionAttributes attrs;
- if (status == SERVICE_WORKER_OK) {
- DCHECK(registration.get());
- if (!registration->is_uninstalling()) {
- dispatcher_host_->GetRegistrationObjectInfoAndVersionAttributes(
- AsWeakPtr(), registration.get(), &info, &attrs);
- }
- }
+ DCHECK(status != SERVICE_WORKER_OK || registration);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
+ if (status == SERVICE_WORKER_OK && !registration->is_uninstalling())
+ info = CreateServiceWorkerRegistrationObjectInfo(std::move(registration));
std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
- base::nullopt, std::move(info), attrs);
+ base::nullopt, std::move(info));
}
void ServiceWorkerProviderHost::GetRegistrationsComplete(
@@ -1149,8 +1046,8 @@ void ServiceWorkerProviderHost::GetRegistrationsComplete(
std::move(callback).Run(
blink::mojom::ServiceWorkerErrorType::kAbort,
std::string(kServiceWorkerGetRegistrationsErrorPrefix) +
- std::string(kShutdownErrorMessage),
- base::nullopt, base::nullopt);
+ std::string(ServiceWorkerConsts::kShutdownErrorMessage),
+ base::nullopt);
return;
}
@@ -1161,29 +1058,23 @@ void ServiceWorkerProviderHost::GetRegistrationsComplete(
&error_message);
std::move(callback).Run(
error_type, kServiceWorkerGetRegistrationsErrorPrefix + error_message,
- base::nullopt, base::nullopt);
+ base::nullopt);
return;
}
std::vector<blink::mojom::ServiceWorkerRegistrationObjectInfoPtr>
object_infos;
- std::vector<ServiceWorkerVersionAttributes> version_attrs;
for (const auto& registration : registrations) {
DCHECK(registration.get());
if (!registration->is_uninstalling()) {
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr object_info;
- ServiceWorkerVersionAttributes version_attr;
- dispatcher_host_->GetRegistrationObjectInfoAndVersionAttributes(
- AsWeakPtr(), registration.get(), &object_info, &version_attr);
- object_infos.push_back(std::move(object_info));
- version_attrs.push_back(version_attr);
+ object_infos.push_back(
+ CreateServiceWorkerRegistrationObjectInfo(std::move(registration)));
}
}
std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
- base::nullopt, std::move(object_infos),
- version_attrs);
+ base::nullopt, std::move(object_infos));
}
void ServiceWorkerProviderHost::GetRegistrationForReady(
@@ -1193,7 +1084,7 @@ void ServiceWorkerProviderHost::GetRegistrationForReady(
mojo::ReportBadMessage(error_message);
// ReportBadMessage() will kill the renderer process, but Mojo complains if
// the callback is not run. Just run it with nonsense arguments.
- std::move(callback).Run(nullptr, base::nullopt);
+ std::move(callback).Run(nullptr);
return;
}
@@ -1202,34 +1093,41 @@ void ServiceWorkerProviderHost::GetRegistrationForReady(
this);
DCHECK(!get_ready_callback_);
get_ready_callback_ =
- base::MakeUnique<GetRegistrationForReadyCallback>(std::move(callback));
+ std::make_unique<GetRegistrationForReadyCallback>(std::move(callback));
ReturnRegistrationForReadyIfNeeded();
}
void ServiceWorkerProviderHost::GetControllerServiceWorker(
mojom::ControllerServiceWorkerRequest controller_request) {
// TODO(kinuko): Log the reasons we drop the request.
- if (!dispatcher_host_ || !IsContextAlive() || !controller_service_worker_)
+ if (!dispatcher_host_ || !IsContextAlive() || !controller_)
return;
- // TODO(kinuko): Call version_->StartWorker() here and pass the
- // controller_request to the ServiceWorker.
- // (Note that this could get called multiple times before the service
- // worker is started)
+ // TODO(kinuko): Call version_->StartWorker() here if the service
+ // is stopped. Currently it should be starting or running at this point.
DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
- controller_service_worker_->AddBinding(std::move(controller_request));
+ DCHECK(controller_->running_status() == EmbeddedWorkerStatus::STARTING ||
+ controller_->running_status() == EmbeddedWorkerStatus::RUNNING);
+ controller_->controller()->Clone(std::move(controller_request));
+}
+
+void ServiceWorkerProviderHost::CloneForWorker(
+ mojom::ServiceWorkerContainerHostRequest container_host_request) {
+ DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ bindings_for_worker_threads_.AddBinding(this,
+ std::move(container_host_request));
}
bool ServiceWorkerProviderHost::IsValidRegisterMessage(
const GURL& script_url,
const blink::mojom::ServiceWorkerRegistrationOptions& options,
std::string* out_error) const {
- if (client_type() != blink::kWebServiceWorkerClientTypeWindow) {
- *out_error = kBadMessageFromNonWindow;
+ if (client_type() != blink::mojom::ServiceWorkerClientType::kWindow) {
+ *out_error = ServiceWorkerConsts::kBadMessageFromNonWindow;
return false;
}
if (!options.scope.is_valid() || !script_url.is_valid()) {
- *out_error = kBadMessageInvalidURL;
+ *out_error = ServiceWorkerConsts::kBadMessageInvalidURL;
return false;
}
if (ServiceWorkerUtils::ContainsDisallowedCharacter(options.scope, script_url,
@@ -1238,7 +1136,7 @@ bool ServiceWorkerProviderHost::IsValidRegisterMessage(
}
std::vector<GURL> urls = {document_url(), options.scope, script_url};
if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) {
- *out_error = kBadMessageInproperOrigins;
+ *out_error = ServiceWorkerConsts::kBadMessageImproperOrigins;
return false;
}
@@ -1248,17 +1146,17 @@ bool ServiceWorkerProviderHost::IsValidRegisterMessage(
bool ServiceWorkerProviderHost::IsValidGetRegistrationMessage(
const GURL& client_url,
std::string* out_error) const {
- if (client_type() != blink::kWebServiceWorkerClientTypeWindow) {
- *out_error = kBadMessageFromNonWindow;
+ if (client_type() != blink::mojom::ServiceWorkerClientType::kWindow) {
+ *out_error = ServiceWorkerConsts::kBadMessageFromNonWindow;
return false;
}
if (!client_url.is_valid()) {
- *out_error = kBadMessageInvalidURL;
+ *out_error = ServiceWorkerConsts::kBadMessageInvalidURL;
return false;
}
std::vector<GURL> urls = {document_url(), client_url};
if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) {
- *out_error = kBadMessageInproperOrigins;
+ *out_error = ServiceWorkerConsts::kBadMessageImproperOrigins;
return false;
}
@@ -1267,12 +1165,12 @@ bool ServiceWorkerProviderHost::IsValidGetRegistrationMessage(
bool ServiceWorkerProviderHost::IsValidGetRegistrationsMessage(
std::string* out_error) const {
- if (client_type() != blink::kWebServiceWorkerClientTypeWindow) {
- *out_error = kBadMessageFromNonWindow;
+ if (client_type() != blink::mojom::ServiceWorkerClientType::kWindow) {
+ *out_error = ServiceWorkerConsts::kBadMessageFromNonWindow;
return false;
}
if (!OriginCanAccessServiceWorkers(document_url())) {
- *out_error = kBadMessageInproperOrigins;
+ *out_error = ServiceWorkerConsts::kBadMessageImproperOrigins;
return false;
}
@@ -1281,13 +1179,79 @@ bool ServiceWorkerProviderHost::IsValidGetRegistrationsMessage(
bool ServiceWorkerProviderHost::IsValidGetRegistrationForReadyMessage(
std::string* out_error) const {
- if (client_type() != blink::kWebServiceWorkerClientTypeWindow) {
- *out_error = kBadMessageFromNonWindow;
+ if (client_type() != blink::mojom::ServiceWorkerClientType::kWindow) {
+ *out_error = ServiceWorkerConsts::kBadMessageFromNonWindow;
return false;
}
if (get_ready_callback_) {
- *out_error = kBadMessageGetRegistrationForReadyDuplicated;
+ *out_error =
+ ServiceWorkerConsts::kBadMessageGetRegistrationForReadyDuplicated;
+ return false;
+ }
+
+ return true;
+}
+
+void ServiceWorkerProviderHost::GetInterface(
+ const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_NE(kDocumentMainThreadId, render_thread_id_);
+ DCHECK(IsHostToRunningServiceWorker());
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(
+ &GetInterfaceImpl, interface_name, std::move(interface_pipe),
+ running_hosted_version_->script_origin(), render_process_id_));
+}
+
+blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
+ServiceWorkerProviderHost::CreateServiceWorkerRegistrationObjectInfo(
+ scoped_refptr<ServiceWorkerRegistration> registration) {
+ int64_t registration_id = registration->id();
+ auto existing_host = registration_object_hosts_.find(registration_id);
+ if (existing_host != registration_object_hosts_.end()) {
+ return existing_host->second->CreateObjectInfo();
+ }
+ registration_object_hosts_[registration_id] =
+ std::make_unique<ServiceWorkerRegistrationObjectHost>(
+ context_, this, std::move(registration));
+ return registration_object_hosts_[registration_id]->CreateObjectInfo();
+}
+
+template <typename CallbackType, typename... Args>
+bool ServiceWorkerProviderHost::CanServeContainerHostMethods(
+ CallbackType* callback,
+ const GURL& scope,
+ const char* error_prefix,
+ Args... args) {
+ if (!dispatcher_host_ || !IsContextAlive()) {
+ std::move(*callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kAbort,
+ std::string(error_prefix) +
+ std::string(ServiceWorkerConsts::kShutdownErrorMessage),
+ args...);
+ return false;
+ }
+
+ // TODO(falken): This check can be removed once crbug.com/439697 is fixed.
+ // (Also see crbug.com/776408)
+ if (document_url().is_empty()) {
+ std::move(*callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kSecurity,
+ std::string(error_prefix) +
+ std::string(ServiceWorkerConsts::kNoDocumentURLErrorMessage),
+ args...);
+ return false;
+ }
+
+ if (!AllowServiceWorker(scope)) {
+ std::move(*callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kDisabled,
+ std::string(error_prefix) +
+ std::string(ServiceWorkerConsts::kUserDeniedPermissionMessage),
+ args...);
return false;
}
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 16287a32192..f4c69d0da54 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host.h
+++ b/chromium/content/browser/service_worker/service_worker_provider_host.h
@@ -29,6 +29,10 @@
#include "content/public/common/resource_type.h"
#include "content/public/common/service_worker_modes.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "services/network/public/interfaces/fetch_api.mojom.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
namespace blink {
@@ -44,15 +48,15 @@ namespace content {
class ResourceRequestBody;
class ServiceWorkerContextCore;
class ServiceWorkerDispatcherHost;
+class ServiceWorkerRegistrationObjectHost;
class ServiceWorkerRequestHandler;
class ServiceWorkerVersion;
-class BrowserSideControllerServiceWorker;
class WebContents;
// This class is the browser-process representation of a service worker
// provider. There are two general types of providers: 1) those for a client
-// (windows, dedicated workers, or shared workers), and 2) those for hosting a
-// running service worker.
+// (windows or shared workers), and 2) those for hosting a running service
+// worker.
//
// For client providers, there is a provider per document or a worker and the
// lifetime of this object is tied to the lifetime of its document or the worker
@@ -82,7 +86,8 @@ class WebContents;
class CONTENT_EXPORT ServiceWorkerProviderHost
: public ServiceWorkerRegistration::Listener,
public base::SupportsWeakPtr<ServiceWorkerProviderHost>,
- public mojom::ServiceWorkerContainerHost {
+ public mojom::ServiceWorkerContainerHost,
+ public service_manager::mojom::InterfaceProvider {
public:
using WebContentsGetter = base::Callback<WebContents*(void)>;
@@ -187,9 +192,9 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// The running version, if any, that this provider is providing resource
// loads for.
ServiceWorkerVersion* running_hosted_version() const {
- // Only providers for controllers can host a running version.
DCHECK(!running_hosted_version_ ||
- info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER);
+ info_.type ==
+ blink::mojom::ServiceWorkerProviderType::kForServiceWorker);
return running_hosted_version_.get();
}
@@ -202,9 +207,11 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
void SetTopmostFrameUrl(const GURL& url);
const GURL& topmost_frame_url() const { return topmost_frame_url_; }
- ServiceWorkerProviderType provider_type() const { return info_.type; }
+ blink::mojom::ServiceWorkerProviderType provider_type() const {
+ return info_.type;
+ }
bool IsProviderForClient() const;
- blink::WebServiceWorkerClientType client_type() const;
+ blink::mojom::ServiceWorkerClientType client_type() const;
// For service worker clients. Associates to |registration| to listen for its
// version change events and sets the controller. If |notify_controllerchange|
@@ -216,13 +223,14 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// listening to it.
void DisassociateRegistration();
- // Returns a handler for a request, the handler may return nullptr if
- // the request doesn't require special handling.
+ // Returns a handler for a request. May return nullptr if the request doesn't
+ // require special handling.
std::unique_ptr<ServiceWorkerRequestHandler> CreateRequestHandler(
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
+ network::mojom::FetchRequestMode request_mode,
+ network::mojom::FetchCredentialsMode credentials_mode,
FetchRedirectMode redirect_mode,
const std::string& integrity,
+ bool keepalive,
ResourceType resource_type,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
@@ -233,9 +241,9 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// Used to get a ServiceWorkerObjectInfo to send to the renderer. Finds an
// existing ServiceWorkerHandle, and increments its reference count, or else
// creates a new one (initialized to ref count 1). Returns the
- // ServiceWorkerInfo from the handle. The renderer is expected to use
+ // ServiceWorkerObjectInfo from the handle. The renderer is expected to use
// ServiceWorkerHandleReference::Adopt to balance out the ref count.
- ServiceWorkerObjectInfo GetOrCreateServiceWorkerHandle(
+ blink::mojom::ServiceWorkerObjectInfoPtr GetOrCreateServiceWorkerHandle(
ServiceWorkerVersion* version);
// Returns true if |registration| can be associated with this provider.
@@ -281,11 +289,12 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
ServiceWorkerProviderHostInfo info,
base::WeakPtr<ServiceWorkerDispatcherHost> dispatcher_host);
- // Completes initialization of provider hosts for controllers and returns the
- // value to create ServiceWorkerNetworkProvider on the renderer which will be
- // connected to this instance.
- // This instance will keep the reference to |hosted_version|, so please be
- // careful not to create a reference cycle.
+ // Completes initialization of this provider host (which is for hosting a
+ // service worker). It is called once a renderer process has been found to
+ // host the worker. Returns the info needed for creating a
+ // ServiceWorkerNetworkProvider on the renderer which will be connected to
+ // this instance. This instance will keep the reference to |hosted_version|,
+ // so please be careful not to create a reference cycle.
mojom::ServiceWorkerProviderInfoForStartWorkerPtr
CompleteStartWorkerPreparation(
int process_id,
@@ -293,14 +302,6 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// Sends event messages to the renderer. Events for the worker are queued up
// until the worker thread id is known via SetReadyToSendMessagesToWorker().
- void SendUpdateFoundMessage(
- int registration_handle_id);
- void SendSetVersionAttributesMessage(
- int registration_handle_id,
- ChangedVersionAttributesMask changed_mask,
- ServiceWorkerVersion* installing_version,
- ServiceWorkerVersion* waiting_version,
- ServiceWorkerVersion* active_version);
void SendServiceWorkerStateChangedMessage(
int worker_handle_id,
blink::mojom::ServiceWorkerState state);
@@ -315,13 +316,22 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// for current document.
ServiceWorkerRegistration* MatchRegistration() const;
+ // Removes the ServiceWorkerRegistrationObjectHost corresponding to
+ // |registration_id|.
+ void RemoveServiceWorkerRegistrationObjectHost(int64_t registration_id);
+
+ // Calls ContentBrowserClient::AllowServiceWorker(). Returns true if content
+ // settings allows service workers to run at |scope|. If this provider is for
+ // a window client, the check involves the topmost frame url as well as
+ // |scope|, and may display tab-level UI.
+ bool AllowServiceWorker(const GURL& scope);
+
// Called when our controller has been terminated and doomed due to an
// exceptional condition like it could no longer be read from the script
// cache.
void NotifyControllerLost();
private:
- friend class ForeignFetchRequestHandlerTest;
friend class LinkHeaderServiceWorkerTest;
friend class ServiceWorkerProviderHostTest;
friend class ServiceWorkerWriteToCacheJobTest;
@@ -340,6 +350,10 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDispatcherHostTest,
DispatchExtendableMessageEvent_Fail);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProviderHostTest, ContextSecurity);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerJobTest, Unregister);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerJobTest, RegisterDuplicateScript);
+ FRIEND_TEST_ALL_PREFIXES(BackgroundSyncManagerTest,
+ RegisterWithoutLiveSWRegistration);
ServiceWorkerProviderHost(
int process_id,
@@ -401,6 +415,8 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
GetRegistrationForReadyCallback callback) override;
void GetControllerServiceWorker(
mojom::ControllerServiceWorkerRequest controller_request) override;
+ void CloneForWorker(
+ mojom::ServiceWorkerContainerHostRequest container_host_request) override;
// Callback for ServiceWorkerContextCore::RegisterServiceWorker().
void RegistrationComplete(RegisterCallback callback,
@@ -431,6 +447,32 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
bool IsValidGetRegistrationsMessage(std::string* out_error) const;
bool IsValidGetRegistrationForReadyMessage(std::string* out_error) const;
+ // service_manager::mojom::InterfaceProvider:
+ // For provider hosts that are hosting a running service worker.
+ void GetInterface(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) override;
+
+ // Returns an object info representing |registration|. The object info holds a
+ // Mojo connection to the ServiceWorkerRegistrationObjectHost for the
+ // |registration| to ensure the host stays alive while the object info is
+ // alive. A new ServiceWorkerRegistrationObjectHost instance is created if one
+ // can not be found in |registration_object_hosts_|.
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
+ CreateServiceWorkerRegistrationObjectInfo(
+ scoped_refptr<ServiceWorkerRegistration> registration);
+
+ // Perform common checks that need to run before ContainerHost methods that
+ // come from a child process are handled.
+ // |scope| is checked if it is allowed to run a service worker.
+ // Returns true if all checks have passed.
+ // If anything looks wrong |callback| will run with an error
+ // message prefixed by |error_prefix| and |args|, and false is returned.
+ template <typename CallbackType, typename... Args>
+ bool CanServeContainerHostMethods(CallbackType* callback,
+ const GURL& scope,
+ const char* error_prefix,
+ Args... args);
+
const std::string client_uuid_;
const base::TimeTicks create_time_;
int render_process_id_;
@@ -463,6 +505,14 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// false.
ServiceWorkerRegistrationMap matching_registrations_;
+ // Contains all ServiceWorkerRegistrationObjectHost instances corresponding to
+ // the service worker registration JavaScript objects for the hosted execution
+ // context (service worker global scope or service worker client) in the
+ // renderer process.
+ std::map<int64_t /* registration_id */,
+ std::unique_ptr<ServiceWorkerRegistrationObjectHost>>
+ registration_object_hosts_;
+
// The ready() promise is only allowed to be created once.
// |get_ready_callback_| has three states:
// 1. |get_ready_callback_| is null when ready() has not yet been called.
@@ -471,21 +521,19 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// 3. |*get_ready_callback_| is a null OnceCallback after the callback has
// been run.
std::unique_ptr<GetRegistrationForReadyCallback> get_ready_callback_;
- scoped_refptr<ServiceWorkerVersion> controller_;
- std::unique_ptr<BrowserSideControllerServiceWorker>
- controller_service_worker_;
+ scoped_refptr<ServiceWorkerVersion> controller_;
scoped_refptr<ServiceWorkerVersion> running_hosted_version_;
base::WeakPtr<ServiceWorkerContextCore> context_;
- // |dispatcher_host_| can be null in several cases:
+ // |dispatcher_host_| is expected to outlive |this| because it destroys
+ // |this| upon destruction. However, it may be null in several cases:
// 1) In some tests.
// 2) PlzNavigate and service worker startup pre-create a
// ServiceWorkerProviderHost instance before there is a renderer assigned to
// it. The dispatcher host is set once the instance starts hosting a
// renderer.
// 3) During cross-site transfer.
- // 4) The dispatcher host can be destructed/removed before the provider host.
base::WeakPtr<ServiceWorkerDispatcherHost> dispatcher_host_;
bool allow_association_;
@@ -501,8 +549,24 @@ 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_;
+
std::vector<base::Closure> queued_events_;
+ // For provider hosts that are hosting a running service worker.
+ mojo::Binding<service_manager::mojom::InterfaceProvider>
+ interface_provider_binding_;
+
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderHost);
};
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 5c1fe628c68..ef789a8971d 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
@@ -28,24 +28,15 @@
#include "content/public/test/test_utils.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
+#include "mojo/edk/embedder/embedder.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
namespace content {
namespace {
-// Sets the document URL for |host| and associates it with |registration|.
-// A dumb version of
-// ServiceWorkerControlleeRequestHandler::PrepareForMainResource().
-void SimulateServiceWorkerControlleeRequestHandler(
- ServiceWorkerProviderHost* host,
- ServiceWorkerRegistration* registration) {
- host->SetDocumentUrl(GURL("https://www.example.com/page"));
- host->AssociateRegistration(registration,
- false /* notify_controllerchange */);
-}
-
const char kServiceWorkerScheme[] = "i-can-use-service-worker";
class ServiceWorkerTestContentClient : public TestContentClient {
@@ -55,6 +46,18 @@ class ServiceWorkerTestContentClient : public TestContentClient {
}
};
+class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient {
+ public:
+ ServiceWorkerTestContentBrowserClient() {}
+ bool AllowServiceWorker(
+ const GURL& scope,
+ const GURL& first_party,
+ content::ResourceContext* context,
+ const base::Callback<WebContents*(void)>& wc_getter) override {
+ return false;
+ }
+};
+
} // namespace
class ServiceWorkerProviderHostTest : public testing::Test {
@@ -70,6 +73,8 @@ class ServiceWorkerProviderHostTest : public testing::Test {
old_content_browser_client_ =
SetBrowserClientForTesting(&test_content_browser_client_);
ResetSchemesAndOriginsWhitelist();
+ mojo::edk::SetDefaultProcessErrorCallback(base::Bind(
+ &ServiceWorkerProviderHostTest::OnMojoError, base::Unretained(this)));
helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
context_ = helper_->context();
@@ -96,36 +101,24 @@ class ServiceWorkerProviderHostTest : public testing::Test {
SetBrowserClientForTesting(old_content_browser_client_);
// Reset cached security schemes so we don't affect other tests.
ResetSchemesAndOriginsWhitelist();
+ mojo::edk::SetDefaultProcessErrorCallback(
+ mojo::edk::ProcessErrorCallback());
}
bool PatternHasProcessToRun(const GURL& pattern) const {
return context_->process_manager()->PatternHasProcessToRun(pattern);
}
+ ServiceWorkerRemoteProviderEndpoint PrepareServiceWorkerProviderHost(
+ const GURL& document_url) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ CreateProviderHostInternal(document_url, &remote_endpoint);
+ return remote_endpoint;
+ }
+
ServiceWorkerProviderHost* CreateProviderHost(const GURL& document_url) {
remote_endpoints_.emplace_back();
- std::unique_ptr<ServiceWorkerProviderHost> host;
- if (IsBrowserSideNavigationEnabled()) {
- host = ServiceWorkerProviderHost::PreCreateNavigationHost(
- helper_->context()->AsWeakPtr(), true,
- base::Callback<WebContents*(void)>());
- ServiceWorkerProviderHostInfo info(host->provider_id(), 1 /* route_id */,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- true /* is_parent_frame_secure */);
- remote_endpoints_.back().BindWithProviderHostInfo(&info);
- host->CompleteNavigationInitialized(helper_->mock_render_process_id(),
- std::move(info), nullptr);
- } else {
- host = CreateProviderHostForWindow(
- helper_->mock_render_process_id(), next_renderer_provided_id_++,
- true /* is_parent_frame_secure */, helper_->context()->AsWeakPtr(),
- &remote_endpoints_.back());
- }
-
- ServiceWorkerProviderHost* host_raw = host.get();
- host->SetDocumentUrl(document_url);
- context_->AddProviderHost(std::move(host));
- return host_raw;
+ return CreateProviderHostInternal(document_url, &remote_endpoints_.back());
}
ServiceWorkerProviderHost* CreateProviderHostWithInsecureParentFrame(
@@ -142,6 +135,70 @@ class ServiceWorkerProviderHostTest : public testing::Test {
return host_raw;
}
+ blink::mojom::ServiceWorkerErrorType Register(
+ mojom::ServiceWorkerContainerHost* container_host,
+ GURL pattern,
+ GURL worker_url) {
+ blink::mojom::ServiceWorkerErrorType error =
+ blink::mojom::ServiceWorkerErrorType::kUnknown;
+ auto options = blink::mojom::ServiceWorkerRegistrationOptions::New(pattern);
+ container_host->Register(
+ worker_url, std::move(options),
+ base::BindOnce([](blink::mojom::ServiceWorkerErrorType* out_error,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg,
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
+ registration) { *out_error = error; },
+ &error));
+ base::RunLoop().RunUntilIdle();
+ return error;
+ }
+
+ blink::mojom::ServiceWorkerErrorType GetRegistration(
+ mojom::ServiceWorkerContainerHost* container_host,
+ GURL document_url,
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr* out_info =
+ nullptr) {
+ blink::mojom::ServiceWorkerErrorType error =
+ blink::mojom::ServiceWorkerErrorType::kUnknown;
+ container_host->GetRegistration(
+ document_url,
+ base::BindOnce(
+ [](blink::mojom::ServiceWorkerErrorType* out_error,
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr* out_info,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg,
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
+ registration) {
+ *out_error = error;
+ if (out_info)
+ *out_info = std::move(registration);
+ },
+ &error, out_info));
+ base::RunLoop().RunUntilIdle();
+ return error;
+ }
+
+ blink::mojom::ServiceWorkerErrorType GetRegistrations(
+ mojom::ServiceWorkerContainerHost* container_host) {
+ blink::mojom::ServiceWorkerErrorType error =
+ blink::mojom::ServiceWorkerErrorType::kUnknown;
+ container_host->GetRegistrations(base::BindOnce(
+ [](blink::mojom::ServiceWorkerErrorType* out_error,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg,
+ base::Optional<std::vector<
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr>> infos) {
+ *out_error = error;
+ },
+ &error));
+ base::RunLoop().RunUntilIdle();
+ return error;
+ }
+
+ void OnMojoError(const std::string& error) { bad_messages_.push_back(error); }
+
+ std::vector<std::string> bad_messages_;
TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
ServiceWorkerContextCore* context_;
@@ -156,6 +213,39 @@ class ServiceWorkerProviderHostTest : public testing::Test {
std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_;
private:
+ ServiceWorkerProviderHost* CreateProviderHostInternal(
+ const GURL& document_url,
+ ServiceWorkerRemoteProviderEndpoint* remote_endpoint) {
+ std::unique_ptr<ServiceWorkerProviderHost> host;
+ if (IsBrowserSideNavigationEnabled()) {
+ host = ServiceWorkerProviderHost::PreCreateNavigationHost(
+ helper_->context()->AsWeakPtr(), true,
+ base::Callback<WebContents*(void)>());
+ ServiceWorkerProviderHostInfo info(
+ host->provider_id(), 1 /* route_id */,
+ blink::mojom::ServiceWorkerProviderType::kForWindow,
+ true /* is_parent_frame_secure */);
+ remote_endpoint->BindWithProviderHostInfo(&info);
+ host->CompleteNavigationInitialized(
+ helper_->mock_render_process_id(), std::move(info),
+ helper_
+ ->GetDispatcherHostForProcess(helper_->mock_render_process_id())
+ ->AsWeakPtr());
+ } else {
+ host = CreateProviderHostWithDispatcherHost(
+ helper_->mock_render_process_id(), next_renderer_provided_id_++,
+ helper_->context()->AsWeakPtr(), 1 /* route_id */,
+ helper_->GetDispatcherHostForProcess(
+ helper_->mock_render_process_id()),
+ remote_endpoint);
+ }
+
+ ServiceWorkerProviderHost* host_raw = host.get();
+ host->SetDocumentUrl(document_url);
+ context_->AddProviderHost(std::move(host));
+ return host_raw;
+ }
+
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderHostTest);
};
@@ -313,7 +403,8 @@ TEST_F(ServiceWorkerProviderHostTest, CrossSiteTransfer) {
const int process_id = provider_host->process_id();
const int provider_id = provider_host->provider_id();
const int frame_id = provider_host->frame_id();
- const ServiceWorkerProviderType type = provider_host->provider_type();
+ const blink::mojom::ServiceWorkerProviderType type =
+ provider_host->provider_type();
const bool is_parent_frame_secure = provider_host->is_parent_frame_secure();
const ServiceWorkerDispatcherHost* dispatcher_host =
provider_host->dispatcher_host();
@@ -333,7 +424,8 @@ TEST_F(ServiceWorkerProviderHostTest, CrossSiteTransfer) {
EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, provider_host->process_id());
EXPECT_EQ(kInvalidServiceWorkerProviderId, provider_host->provider_id());
EXPECT_EQ(MSG_ROUTING_NONE, provider_host->frame_id());
- EXPECT_EQ(SERVICE_WORKER_PROVIDER_UNKNOWN, provider_host->provider_type());
+ EXPECT_EQ(blink::mojom::ServiceWorkerProviderType::kUnknown,
+ provider_host->provider_type());
EXPECT_FALSE(provider_host->is_parent_frame_secure());
EXPECT_EQ(nullptr, provider_host->dispatcher_host());
@@ -350,9 +442,10 @@ TEST_F(ServiceWorkerProviderHostTest, CrossSiteTransfer) {
EXPECT_EQ(kInvalidServiceWorkerProviderId, provisional_host->provider_id());
EXPECT_EQ(MSG_ROUTING_NONE, provisional_host->frame_id());
- EXPECT_EQ(SERVICE_WORKER_PROVIDER_UNKNOWN, provisional_host->provider_type());
+ EXPECT_EQ(blink::mojom::ServiceWorkerProviderType::kUnknown,
+ provisional_host->provider_type());
EXPECT_FALSE(provisional_host->is_parent_frame_secure());
- EXPECT_EQ(nullptr, provisional_host->dispatcher_host());
+ EXPECT_EQ(dispatcher_host, provisional_host->dispatcher_host());
EXPECT_EQ(1u, registration->listeners().count(provider_host));
}
@@ -372,6 +465,32 @@ TEST_F(ServiceWorkerProviderHostTest, RemoveProvider) {
EXPECT_FALSE(context_->GetProviderHost(process_id, provider_id));
}
+class MockServiceWorkerContainer : public mojom::ServiceWorkerContainer {
+ public:
+ explicit MockServiceWorkerContainer(
+ mojom::ServiceWorkerContainerAssociatedRequest request)
+ : binding_(this, std::move(request)) {}
+
+ ~MockServiceWorkerContainer() override = default;
+
+ void SetController(blink::mojom::ServiceWorkerObjectInfoPtr controller,
+ const std::vector<blink::mojom::WebFeature>& used_features,
+ bool should_notify_controllerchange) override {
+ was_set_controller_called_ = true;
+ }
+ void PostMessageToClient(
+ blink::mojom::ServiceWorkerObjectInfoPtr controller,
+ const base::string16& message,
+ std::vector<mojo::ScopedMessagePipeHandle> message_pipes) override {}
+ void CountFeature(blink::mojom::WebFeature feature) override {}
+
+ bool was_set_controller_called() const { return was_set_controller_called_; }
+
+ private:
+ bool was_set_controller_called_ = false;
+ mojo::AssociatedBinding<mojom::ServiceWorkerContainer> binding_;
+};
+
TEST_F(ServiceWorkerProviderHostTest, Controller) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableBrowserSideNavigation);
@@ -380,32 +499,37 @@ TEST_F(ServiceWorkerProviderHostTest, Controller) {
ServiceWorkerProviderHost::PreCreateNavigationHost(
helper_->context()->AsWeakPtr(), true /* are_ancestors_secure */,
base::Callback<WebContents*(void)>());
- ServiceWorkerProviderHostInfo info(host->provider_id(), 1 /* route_id */,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- true /* is_parent_frame_secure */);
+ ServiceWorkerProviderHostInfo info(
+ host->provider_id(), 1 /* route_id */,
+ blink::mojom::ServiceWorkerProviderType::kForWindow,
+ true /* is_parent_frame_secure */);
remote_endpoints_.emplace_back();
remote_endpoints_.back().BindWithProviderHostInfo(&info);
+ auto container = std::make_unique<MockServiceWorkerContainer>(
+ std::move(*remote_endpoints_.back().client_request()));
// 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());
registration1_->SetActiveVersion(version);
- SimulateServiceWorkerControlleeRequestHandler(host.get(),
- registration1_.get());
// Finish the navigation.
+ host->SetDocumentUrl(GURL("https://www.example.com/page"));
host->CompleteNavigationInitialized(
helper_->mock_render_process_id(), std::move(info),
helper_->GetDispatcherHostForProcess(helper_->mock_render_process_id())
->AsWeakPtr());
+ host->AssociateRegistration(registration1_.get(),
+ false /* notify_controllerchange */);
+ base::RunLoop().RunUntilIdle();
+
// The page should be controlled since there was an active version at the
// time navigation started. The SetController IPC should have been sent.
EXPECT_TRUE(host->active_version());
EXPECT_EQ(host->active_version(), host->controller());
- EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
- ServiceWorkerMsg_SetControllerServiceWorker::ID));
+ EXPECT_TRUE(container->was_set_controller_called());
}
TEST_F(ServiceWorkerProviderHostTest, ActiveIsNotController) {
@@ -416,36 +540,315 @@ TEST_F(ServiceWorkerProviderHostTest, ActiveIsNotController) {
ServiceWorkerProviderHost::PreCreateNavigationHost(
helper_->context()->AsWeakPtr(), true /* are_ancestors_secure */,
base::Callback<WebContents*(void)>());
- ServiceWorkerProviderHostInfo info(host->provider_id(), 1 /* route_id */,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- true /* is_parent_frame_secure */);
+ ServiceWorkerProviderHostInfo info(
+ host->provider_id(), 1 /* route_id */,
+ blink::mojom::ServiceWorkerProviderType::kForWindow,
+ true /* is_parent_frame_secure */);
remote_endpoints_.emplace_back();
remote_endpoints_.back().BindWithProviderHostInfo(&info);
+ auto container = std::make_unique<MockServiceWorkerContainer>(
+ std::move(*remote_endpoints_.back().client_request()));
- // Associate it with an installing registration then start the navigation.
+ // 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());
registration1_->SetInstallingVersion(version);
- SimulateServiceWorkerControlleeRequestHandler(host.get(),
- registration1_.get());
- // Promote the worker to active while navigation is still happening.
- registration1_->SetActiveVersion(version);
// Finish the navigation.
+ host->SetDocumentUrl(GURL("https://www.example.com/page"));
host->CompleteNavigationInitialized(
helper_->mock_render_process_id(), std::move(info),
helper_->GetDispatcherHostForProcess(helper_->mock_render_process_id())
->AsWeakPtr());
+ host->AssociateRegistration(registration1_.get(),
+ false /* notify_controllerchange */);
+ // Promote the worker to active while navigation is still happening.
+ registration1_->SetActiveVersion(version);
+ base::RunLoop().RunUntilIdle();
+
// The page should not be controlled since there was no active version at the
// time navigation started. Furthermore, no SetController IPC should have been
// sent.
EXPECT_TRUE(host->active_version());
EXPECT_FALSE(host->controller());
- EXPECT_EQ(nullptr, helper_->ipc_sink()->GetFirstMessageMatching(
- ServiceWorkerMsg_SetControllerServiceWorker::ID));
+ EXPECT_FALSE(container->was_set_controller_called());
+}
+
+TEST_F(ServiceWorkerProviderHostTest,
+ Register_ContentSettingsDisallowsServiceWorker) {
+ ServiceWorkerTestContentBrowserClient test_browser_client;
+ ContentBrowserClient* old_browser_client =
+ SetBrowserClientForTesting(&test_browser_client);
+
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kDisabled,
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("https://www.example.com/"),
+ GURL("https://www.example.com/bar")));
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kDisabled,
+ GetRegistration(remote_endpoint.host_ptr()->get(),
+ GURL("https://www.example.com/")));
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kDisabled,
+ GetRegistrations(remote_endpoint.host_ptr()->get()));
+
+ SetBrowserClientForTesting(old_browser_client);
+}
+
+TEST_F(ServiceWorkerProviderHostTest, Register_HTTPS) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("https://www.example.com/"),
+ GURL("https://www.example.com/bar")));
+}
+
+TEST_F(ServiceWorkerProviderHostTest, Register_NonSecureTransportLocalhost) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("http://127.0.0.3:81/foo"));
+
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("http://127.0.0.3:81/bar"),
+ GURL("http://127.0.0.3:81/baz")));
+}
+
+TEST_F(ServiceWorkerProviderHostTest, Register_InvalidScopeShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ Register(remote_endpoint.host_ptr()->get(), GURL(""),
+ GURL("https://www.example.com/bar/hoge.js"));
+ EXPECT_EQ(1u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerProviderHostTest, Register_InvalidScriptShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("https://www.example.com/bar/"), GURL(""));
+ EXPECT_EQ(1u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerProviderHostTest, Register_NonSecureOriginShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("http://www.example.com/foo"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ Register(remote_endpoint.host_ptr()->get(), GURL("http://www.example.com/"),
+ GURL("http://www.example.com/bar"));
+ EXPECT_EQ(1u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerProviderHostTest, Register_CrossOriginShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ // Script has a different host
+ Register(remote_endpoint.host_ptr()->get(), GURL("https://www.example.com/"),
+ GURL("https://foo.example.com/bar"));
+ EXPECT_EQ(1u, bad_messages_.size());
+
+ // Scope has a different host
+ Register(remote_endpoint.host_ptr()->get(), GURL("https://foo.example.com/"),
+ GURL("https://www.example.com/bar"));
+ EXPECT_EQ(2u, bad_messages_.size());
+
+ // Script has a different port
+ Register(remote_endpoint.host_ptr()->get(), GURL("https://www.example.com/"),
+ GURL("https://www.example.com:8080/bar"));
+ EXPECT_EQ(3u, bad_messages_.size());
+
+ // Scope has a different transport
+ Register(remote_endpoint.host_ptr()->get(), GURL("wss://www.example.com/"),
+ GURL("https://www.example.com/bar"));
+ EXPECT_EQ(4u, bad_messages_.size());
+
+ // Script and scope have a different host but match each other
+ Register(remote_endpoint.host_ptr()->get(), GURL("https://foo.example.com/"),
+ GURL("https://foo.example.com/bar"));
+ EXPECT_EQ(5u, bad_messages_.size());
+
+ // Script and scope URLs are invalid
+ Register(remote_endpoint.host_ptr()->get(), GURL(), GURL("h@ttps://@"));
+ EXPECT_EQ(6u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerProviderHostTest, Register_BadCharactersShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("https://www.example.com/%2f"),
+ GURL("https://www.example.com/"));
+ EXPECT_EQ(1u, bad_messages_.size());
+
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("https://www.example.com/%2F"),
+ GURL("https://www.example.com/"));
+ EXPECT_EQ(2u, bad_messages_.size());
+
+ Register(remote_endpoint.host_ptr()->get(), GURL("https://www.example.com/"),
+ GURL("https://www.example.com/%2f"));
+ EXPECT_EQ(3u, bad_messages_.size());
+
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("https://www.example.com/%5c"),
+ GURL("https://www.example.com/"));
+ EXPECT_EQ(4u, bad_messages_.size());
+
+ Register(remote_endpoint.host_ptr()->get(), GURL("https://www.example.com/"),
+ GURL("https://www.example.com/%5c"));
+ EXPECT_EQ(5u, bad_messages_.size());
+
+ Register(remote_endpoint.host_ptr()->get(), GURL("https://www.example.com/"),
+ GURL("https://www.example.com/%5C"));
+ EXPECT_EQ(6u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerProviderHostTest, Register_FileSystemDocumentShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(
+ GURL("filesystem:https://www.example.com/temporary/a"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("filesystem:https://www.example.com/temporary/"),
+ GURL("https://www.example.com/temporary/bar"));
+ EXPECT_EQ(1u, bad_messages_.size());
+
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("https://www.example.com/temporary/"),
+ GURL("filesystem:https://www.example.com/temporary/bar"));
+ EXPECT_EQ(2u, bad_messages_.size());
+
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("filesystem:https://www.example.com/temporary/"),
+ GURL("filesystem:https://www.example.com/temporary/bar"));
+ EXPECT_EQ(3u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerProviderHostTest,
+ Register_FileSystemScriptOrScopeShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(
+ GURL("https://www.example.com/temporary/"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("filesystem:https://www.example.com/temporary/"),
+ GURL("https://www.example.com/temporary/bar"));
+ EXPECT_EQ(1u, bad_messages_.size());
+
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("https://www.example.com/temporary/"),
+ GURL("filesystem:https://www.example.com/temporary/bar"));
+ EXPECT_EQ(2u, bad_messages_.size());
+
+ Register(remote_endpoint.host_ptr()->get(),
+ GURL("filesystem:https://www.example.com/temporary/"),
+ GURL("filesystem:https://www.example.com/temporary/bar"));
+ EXPECT_EQ(3u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerProviderHostTest, EarlyContextDeletion) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ helper_->ShutdownContext();
+
+ // Let the shutdown reach the simulated IO thread.
+ base::RunLoop().RunUntilIdle();
+
+ // Because ServiceWorkerContextCore owns ServiceWorkerProviderHost, our
+ // ServiceWorkerProviderHost instance has destroyed.
+ EXPECT_TRUE(remote_endpoint.host_ptr()->encountered_error());
+}
+
+TEST_F(ServiceWorkerProviderHostTest, GetRegistration_Success) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ const GURL kScope("https://www.example.com/");
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
+ Register(remote_endpoint.host_ptr()->get(), kScope,
+ GURL("https://www.example.com/sw.js")));
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
+ GetRegistration(remote_endpoint.host_ptr()->get(), kScope, &info));
+ ASSERT_TRUE(info);
+ EXPECT_EQ(kScope, info->options->scope);
+}
+
+TEST_F(ServiceWorkerProviderHostTest,
+ GetRegistration_NotFoundShouldReturnNull) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
+ GetRegistration(remote_endpoint.host_ptr()->get(),
+ GURL("https://www.example.com/"), &info));
+ EXPECT_FALSE(info);
+}
+
+TEST_F(ServiceWorkerProviderHostTest, GetRegistration_CrossOriginShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ GetRegistration(remote_endpoint.host_ptr()->get(),
+ GURL("https://foo.example.com/"));
+ EXPECT_EQ(1u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerProviderHostTest, GetRegistration_InvalidScopeShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ GetRegistration(remote_endpoint.host_ptr()->get(), GURL(""));
+ EXPECT_EQ(1u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerProviderHostTest,
+ GetRegistration_NonSecureOriginShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("http://www.example.com/foo"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ GetRegistration(remote_endpoint.host_ptr()->get(),
+ GURL("http://www.example.com/"));
+ EXPECT_EQ(1u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerProviderHostTest, GetRegistrations_SecureOrigin) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
+
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
+ GetRegistrations(remote_endpoint.host_ptr()->get()));
+}
+
+TEST_F(ServiceWorkerProviderHostTest,
+ GetRegistrations_NonSecureOriginShouldFail) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareServiceWorkerProviderHost(GURL("http://www.example.com/foo"));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ GetRegistrations(remote_endpoint.host_ptr()->get());
+ EXPECT_EQ(1u, bad_messages_.size());
}
} // namespace content
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 7cdd7042011..7b8bfd6868d 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
@@ -199,7 +199,7 @@ TEST_F(ServiceWorkerReadFromCacheJobTest, ReadMainScript) {
net::DEFAULT_PRIORITY, &delegate_,
TRAFFIC_ANNOTATION_FOR_TESTS);
test_job_interceptor_->set_main_intercept_job(
- base::MakeUnique<ServiceWorkerReadFromCacheJob>(
+ std::make_unique<ServiceWorkerReadFromCacheJob>(
request.get(), nullptr /* NetworkDelegate */,
RESOURCE_TYPE_SERVICE_WORKER, context()->AsWeakPtr(), version_,
main_script_.resource_id));
@@ -218,7 +218,7 @@ TEST_F(ServiceWorkerReadFromCacheJobTest, ReadImportedScript) {
net::DEFAULT_PRIORITY, &delegate_,
TRAFFIC_ANNOTATION_FOR_TESTS);
test_job_interceptor_->set_main_intercept_job(
- base::MakeUnique<ServiceWorkerReadFromCacheJob>(
+ std::make_unique<ServiceWorkerReadFromCacheJob>(
request.get(), nullptr /* NetworkDelegate */, RESOURCE_TYPE_SCRIPT,
context()->AsWeakPtr(), version_, imported_script_.resource_id));
StartAndWaitForRequest(request.get());
@@ -249,7 +249,7 @@ TEST_F(ServiceWorkerReadFromCacheJobTest, ResourceNotFound) {
TRAFFIC_ANNOTATION_FOR_TESTS);
const int64_t kNonexistentResourceId = 100;
test_job_interceptor_->set_main_intercept_job(
- base::MakeUnique<ServiceWorkerReadFromCacheJob>(
+ std::make_unique<ServiceWorkerReadFromCacheJob>(
request.get(), nullptr /* NetworkDelegate */,
RESOURCE_TYPE_SERVICE_WORKER, context()->AsWeakPtr(), version_,
kNonexistentResourceId));
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 132745efcb0..2a0c3114574 100644
--- a/chromium/content/browser/service_worker/service_worker_register_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_register_job.cc
@@ -25,46 +25,10 @@
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "net/base/net_errors.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
namespace content {
-namespace {
-
-class InstallEventMethodsReceiver
- : public mojom::ServiceWorkerInstallEventMethods {
- public:
- InstallEventMethodsReceiver(ServiceWorkerVersion* version)
- : version_(version), install_methods_binding_(this) {}
- ~InstallEventMethodsReceiver() override {}
-
- void BindInterface(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo* ptr_info) {
- install_methods_binding_.Bind(mojo::MakeRequest(ptr_info));
- }
-
- // Implements mojom::ServiceWorkerInstallEventMethod.
- void RegisterForeignFetchScopes(
- const std::vector<GURL>& sub_scopes,
- const std::vector<url::Origin>& origins) override {
- DCHECK(version_);
- version_->RegisterForeignFetchScopes(sub_scopes, origins);
- }
-
- private:
- ServiceWorkerVersion* version_;
-
- mojo::AssociatedBinding<mojom::ServiceWorkerInstallEventMethods>
- install_methods_binding_;
-
- DISALLOW_COPY_AND_ASSIGN(InstallEventMethodsReceiver);
-};
-
-void RunSoon(const base::Closure& closure) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure);
-}
-
-} // namespace
-
typedef ServiceWorkerRegisterJobBase::RegistrationJobType RegistrationJobType;
ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
@@ -118,7 +82,9 @@ void ServiceWorkerRegisterJob::AddCallback(
provider_host->AddScopedProcessReferenceToPattern(pattern_);
return;
}
- RunSoon(base::Bind(callback, promise_resolved_status_,
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(callback, promise_resolved_status_,
promise_resolved_status_message_,
base::RetainedRef(promise_resolved_registration_)));
}
@@ -146,7 +112,8 @@ void ServiceWorkerRegisterJob::StartImpl() {
scoped_refptr<ServiceWorkerRegistration> registration =
context_->storage()->GetUninstallingRegistration(pattern_);
if (registration.get())
- RunSoon(base::Bind(next_step, SERVICE_WORKER_OK, registration));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(next_step, SERVICE_WORKER_OK, registration));
else
context_->storage()->FindRegistrationForPattern(pattern_, next_step);
}
@@ -373,7 +340,7 @@ void ServiceWorkerRegisterJob::UpdateAndContinue() {
context_->storage()->NotifyInstallingRegistration(registration());
int64_t version_id = context_->storage()->NewVersionId();
- if (version_id == kInvalidServiceWorkerVersionId) {
+ if (version_id == blink::mojom::kInvalidServiceWorkerVersionId) {
Complete(SERVICE_WORKER_ERROR_ABORT);
return;
}
@@ -465,24 +432,16 @@ void ServiceWorkerRegisterJob::DispatchInstallEvent() {
base::Bind(&ServiceWorkerRegisterJob::OnInstallFailed,
weak_factory_.GetWeakPtr()));
- std::unique_ptr<InstallEventMethodsReceiver> install_methods_receiver =
- base::MakeUnique<InstallEventMethodsReceiver>(new_version());
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo ptr_info;
- install_methods_receiver->BindInterface(&ptr_info);
new_version()->event_dispatcher()->DispatchInstallEvent(
- std::move(ptr_info),
base::BindOnce(&ServiceWorkerRegisterJob::OnInstallFinished,
- weak_factory_.GetWeakPtr(), request_id,
- base::Passed(&install_methods_receiver)));
+ weak_factory_.GetWeakPtr(), request_id));
}
void ServiceWorkerRegisterJob::OnInstallFinished(
int request_id,
- std::unique_ptr<InstallEventMethodsReceiver> install_methods_receiver,
blink::mojom::ServiceWorkerEventStatus event_status,
bool has_fetch_handler,
base::Time dispatch_event_time) {
- install_methods_receiver.reset();
bool succeeded =
event_status == blink::mojom::ServiceWorkerEventStatus::COMPLETED;
new_version()->FinishRequest(request_id, succeeded, dispatch_event_time);
@@ -493,9 +452,6 @@ void ServiceWorkerRegisterJob::OnInstallFinished(
}
ServiceWorkerMetrics::RecordInstallEventStatus(SERVICE_WORKER_OK);
- ServiceWorkerMetrics::RecordForeignFetchRegistrationCount(
- new_version()->foreign_fetch_scopes().size(),
- new_version()->foreign_fetch_origins().size());
SetPhase(STORE);
DCHECK(!registration()->last_update_check().is_null());
@@ -599,7 +555,7 @@ void ServiceWorkerRegisterJob::CompleteInternal(
}
}
if (!is_promise_resolved_)
- ResolvePromise(status, status_message, NULL);
+ ResolvePromise(status, status_message, nullptr);
}
DCHECK(callbacks_.empty());
if (registration()) {
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 1524a64c770..22b493908de 100644
--- a/chromium/content/browser/service_worker/service_worker_register_job.h
+++ b/chromium/content/browser/service_worker/service_worker_register_job.h
@@ -21,10 +21,6 @@
namespace content {
-namespace {
-class InstallEventMethodsReceiver;
-} // namespace
-
// Handles the initial registration of a Service Worker and the
// subsequent update of existing registrations.
//
@@ -128,7 +124,6 @@ class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase,
void DispatchInstallEvent();
void OnInstallFinished(
int request_id,
- std::unique_ptr<InstallEventMethodsReceiver> install_event_methods,
blink::mojom::ServiceWorkerEventStatus event_status,
bool has_fetch_handler,
base::Time dispatch_event_time);
diff --git a/chromium/content/browser/service_worker/service_worker_registration.cc b/chromium/content/browser/service_worker/service_worker_registration.cc
index 6f55751d6d1..80eb7c76a59 100644
--- a/chromium/content/browser/service_worker/service_worker_registration.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration.cc
@@ -178,15 +178,15 @@ void ServiceWorkerRegistration::UnsetVersionInternal(
ChangedVersionAttributesMask* mask) {
DCHECK(version);
if (installing_version_.get() == version) {
- installing_version_ = NULL;
+ installing_version_ = nullptr;
mask->add(ChangedVersionAttributesMask::INSTALLING_VERSION);
} else if (waiting_version_.get() == version) {
- waiting_version_ = NULL;
+ waiting_version_ = nullptr;
should_activate_when_ready_ = false;
mask->add(ChangedVersionAttributesMask::WAITING_VERSION);
} else if (active_version_.get() == version) {
active_version_->RemoveListener(this);
- active_version_ = NULL;
+ active_version_ = nullptr;
mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION);
}
}
@@ -229,9 +229,9 @@ void ServiceWorkerRegistration::ClearWhenReady() {
context_->storage()->NotifyUninstallingRegistration(this);
context_->storage()->DeleteRegistration(
- id(),
- pattern().GetOrigin(),
- base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+ id(), pattern().GetOrigin(),
+ AdaptCallbackForRepeating(
+ base::BindOnce(&ServiceWorkerRegistration::OnDeleteFinished, this)));
if (!active_version() || !active_version()->HasControllee())
Clear();
@@ -512,8 +512,8 @@ void ServiceWorkerRegistration::OnActivateEventFinished(
void ServiceWorkerRegistration::OnDeleteFinished(
ServiceWorkerStatusCode status) {
- // Intentionally empty completion callback, used to prevent
- // |this| from being deleted until the storage method completes.
+ for (auto& listener : listeners_)
+ listener.OnRegistrationDeleted(this);
}
void ServiceWorkerRegistration::Clear() {
diff --git a/chromium/content/browser/service_worker/service_worker_registration.h b/chromium/content/browser/service_worker/service_worker_registration.h
index 32f2df80039..fea1bf1b778 100644
--- a/chromium/content/browser/service_worker/service_worker_registration.h
+++ b/chromium/content/browser/service_worker/service_worker_registration.h
@@ -28,7 +28,7 @@ struct ServiceWorkerRegistrationInfo;
// Represents the core of a service worker registration object. Other
// registration derivatives (WebServiceWorkerRegistration etc) ultimately refer
-// to this class. This is refcounted via ServiceWorkerRegistrationHandle to
+// to this class. This is refcounted via ServiceWorkerRegistrationObjectHost to
// facilitate multiple controllees being associated with the same registration.
class CONTENT_EXPORT ServiceWorkerRegistration
: public base::RefCounted<ServiceWorkerRegistration>,
@@ -46,6 +46,8 @@ class CONTENT_EXPORT ServiceWorkerRegistration
ServiceWorkerRegistration* registration) {}
virtual void OnRegistrationFinishedUninstalling(
ServiceWorkerRegistration* registration) {}
+ virtual void OnRegistrationDeleted(
+ ServiceWorkerRegistration* registration) {}
virtual void OnUpdateFound(
ServiceWorkerRegistration* registration) {}
virtual void OnSkippedWaiting(ServiceWorkerRegistration* registation) {}
@@ -97,7 +99,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
return active_version() || waiting_version();
}
- const NavigationPreloadState& navigation_preload_state() const {
+ const blink::mojom::NavigationPreloadState navigation_preload_state() const {
return navigation_preload_state_;
}
@@ -205,7 +207,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
bool is_uninstalling_;
bool is_uninstalled_;
bool should_activate_when_ready_;
- NavigationPreloadState navigation_preload_state_;
+ blink::mojom::NavigationPreloadState navigation_preload_state_;
base::Time last_update_check_;
int64_t resources_total_size_bytes_;
diff --git a/chromium/content/browser/service_worker/service_worker_registration_handle.cc b/chromium/content/browser/service_worker/service_worker_registration_handle.cc
deleted file mode 100644
index dffa2a7c6eb..00000000000
--- a/chromium/content/browser/service_worker/service_worker_registration_handle.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/service_worker/service_worker_registration_handle.h"
-
-#include "content/browser/service_worker/service_worker_context_core.h"
-#include "content/browser/service_worker/service_worker_dispatcher_host.h"
-#include "content/browser/service_worker/service_worker_handle.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
-#include "content/common/service_worker/service_worker_messages.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/common/service_worker_modes.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-
-namespace content {
-
-ServiceWorkerRegistrationHandle::ServiceWorkerRegistrationHandle(
- base::WeakPtr<ServiceWorkerContextCore> context,
- ServiceWorkerDispatcherHost* dispatcher_host,
- base::WeakPtr<ServiceWorkerProviderHost> provider_host,
- ServiceWorkerRegistration* registration)
- : dispatcher_host_(dispatcher_host),
- provider_host_(provider_host),
- provider_id_(provider_host ? provider_host->provider_id()
- : kInvalidServiceWorkerProviderId),
- handle_id_(context
- ? context->GetNewRegistrationHandleId()
- : blink::mojom::kInvalidServiceWorkerRegistrationHandleId),
- registration_(registration) {
- DCHECK(registration_.get());
- registration_->AddListener(this);
- bindings_.set_connection_error_handler(
- base::Bind(&ServiceWorkerRegistrationHandle::OnConnectionError,
- base::Unretained(this)));
-
- dispatcher_host_->RegisterServiceWorkerRegistrationHandle(this);
-}
-
-ServiceWorkerRegistrationHandle::~ServiceWorkerRegistrationHandle() {
- DCHECK(registration_.get());
- registration_->RemoveListener(this);
-}
-
-blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
-ServiceWorkerRegistrationHandle::CreateObjectInfo() {
- auto info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New();
- info->handle_id = handle_id_;
- info->options = blink::mojom::ServiceWorkerRegistrationOptions::New(
- registration_->pattern());
- info->registration_id = registration_->id();
- bindings_.AddBinding(this, mojo::MakeRequest(&info->host_ptr_info));
- return info;
-}
-
-void ServiceWorkerRegistrationHandle::OnVersionAttributesChanged(
- ServiceWorkerRegistration* registration,
- ChangedVersionAttributesMask changed_mask,
- const ServiceWorkerRegistrationInfo& info) {
- DCHECK_EQ(registration->id(), registration_->id());
- SetVersionAttributes(changed_mask,
- registration->installing_version(),
- registration->waiting_version(),
- registration->active_version());
-}
-
-void ServiceWorkerRegistrationHandle::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);
-}
-
-void ServiceWorkerRegistrationHandle::OnUpdateFound(
- ServiceWorkerRegistration* registration) {
- if (!provider_host_)
- return; // Could be nullptr in some tests.
- provider_host_->SendUpdateFoundMessage(handle_id_);
-}
-
-void ServiceWorkerRegistrationHandle::SetVersionAttributes(
- ChangedVersionAttributesMask changed_mask,
- ServiceWorkerVersion* installing_version,
- ServiceWorkerVersion* waiting_version,
- ServiceWorkerVersion* active_version) {
- if (!provider_host_)
- return; // Could be nullptr in some tests.
- provider_host_->SendSetVersionAttributesMessage(handle_id_,
- changed_mask,
- installing_version,
- waiting_version,
- active_version);
-}
-
-void ServiceWorkerRegistrationHandle::OnConnectionError() {
- // If there are still bindings, |this| is still being used.
- if (!bindings_.empty())
- return;
- // Will destroy |this|.
- dispatcher_host_->UnregisterServiceWorkerRegistrationHandle(handle_id_);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_registration_handle.h b/chromium/content/browser/service_worker/service_worker_registration_handle.h
deleted file mode 100644
index b3fa835057c..00000000000
--- a/chromium/content/browser/service_worker/service_worker_registration_handle.h
+++ /dev/null
@@ -1,91 +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_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/browser/service_worker/service_worker_version.h"
-#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "mojo/public/cpp/bindings/associated_binding_set.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-
-namespace content {
-
-class ServiceWorkerContextCore;
-class ServiceWorkerDispatcherHost;
-class ServiceWorkerVersion;
-
-// TODO(leonhsl): Merge this class into ServiceWorkerRegistration.
-
-// ServiceWorkerRegistrationHandle has a 1:1 correspondence to
-// WebServiceWorkerRegistration in the renderer process.
-// WebServiceWorkerRegistration owns ServiceWorkerRegistrationHandle via an
-// associated interface pointer to
-// blink::mojom::ServiceWorkerRegistrationObjectHost.
-//
-// Has a reference to the corresponding ServiceWorkerRegistration in order to
-// ensure that the registration is alive while this handle is around.
-class CONTENT_EXPORT ServiceWorkerRegistrationHandle
- : public blink::mojom::ServiceWorkerRegistrationObjectHost,
- public ServiceWorkerRegistration::Listener {
- public:
- ServiceWorkerRegistrationHandle(
- base::WeakPtr<ServiceWorkerContextCore> context,
- ServiceWorkerDispatcherHost* dispatcher_host,
- base::WeakPtr<ServiceWorkerProviderHost> provider_host,
- ServiceWorkerRegistration* registration);
- ~ServiceWorkerRegistrationHandle() override;
-
- // Establishes a new mojo connection into |bindings_|.
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr CreateObjectInfo();
-
- int provider_id() const { return provider_id_; }
- int handle_id() const { return handle_id_; }
-
- ServiceWorkerRegistration* registration() { return registration_.get(); }
-
- private:
- // ServiceWorkerRegistration::Listener overrides.
- void OnVersionAttributesChanged(
- ServiceWorkerRegistration* registration,
- ChangedVersionAttributesMask changed_mask,
- const ServiceWorkerRegistrationInfo& info) override;
- void OnRegistrationFailed(ServiceWorkerRegistration* registration) override;
- void OnUpdateFound(ServiceWorkerRegistration* registration) override;
-
- // 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 OnConnectionError();
-
- // |dispatcher_host_| is valid throughout lifetime of |this| because it owns
- // |this|.
- ServiceWorkerDispatcherHost* dispatcher_host_;
- base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
- const int provider_id_;
- const int handle_id_;
- mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerRegistrationObjectHost>
- bindings_;
-
- // This handle is the primary owner of this registration.
- scoped_refptr<ServiceWorkerRegistration> registration_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegistrationHandle);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_H_
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
new file mode 100644
index 00000000000..5f2606af383
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_registration_object_host.cc
@@ -0,0 +1,346 @@
+// 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/browser/service_worker/service_worker_registration_object_host.h"
+
+#include "base/memory/ptr_util.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_handle.h"
+#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/common/service_worker_modes.h"
+#include "net/http/http_util.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+
+namespace content {
+
+ServiceWorkerRegistrationObjectHost::ServiceWorkerRegistrationObjectHost(
+ base::WeakPtr<ServiceWorkerContextCore> context,
+ ServiceWorkerProviderHost* provider_host,
+ scoped_refptr<ServiceWorkerRegistration> registration)
+ : provider_host_(provider_host),
+ context_(context),
+ registration_(registration),
+ weak_ptr_factory_(this) {
+ DCHECK(registration_.get());
+ DCHECK(provider_host_);
+ registration_->AddListener(this);
+ bindings_.set_connection_error_handler(
+ base::Bind(&ServiceWorkerRegistrationObjectHost::OnConnectionError,
+ base::Unretained(this)));
+}
+
+ServiceWorkerRegistrationObjectHost::~ServiceWorkerRegistrationObjectHost() {
+ DCHECK(registration_.get());
+ registration_->RemoveListener(this);
+}
+
+blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
+ServiceWorkerRegistrationObjectHost::CreateObjectInfo() {
+ auto info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New();
+ info->options = blink::mojom::ServiceWorkerRegistrationOptions::New(
+ registration_->pattern());
+ info->registration_id = registration_->id();
+ bindings_.AddBinding(this, mojo::MakeRequest(&info->host_ptr_info));
+ if (!remote_registration_)
+ info->request = mojo::MakeRequest(&remote_registration_);
+
+ info->installing = provider_host_->GetOrCreateServiceWorkerHandle(
+ registration_->installing_version());
+ info->waiting = provider_host_->GetOrCreateServiceWorkerHandle(
+ registration_->waiting_version());
+ info->active = provider_host_->GetOrCreateServiceWorkerHandle(
+ registration_->active_version());
+ return info;
+}
+
+void ServiceWorkerRegistrationObjectHost::OnVersionAttributesChanged(
+ ServiceWorkerRegistration* registration,
+ ChangedVersionAttributesMask changed_mask,
+ const ServiceWorkerRegistrationInfo& info) {
+ DCHECK_EQ(registration->id(), registration_->id());
+ SetVersionAttributes(changed_mask, registration->installing_version(),
+ registration->waiting_version(),
+ registration->active_version());
+}
+
+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);
+}
+
+void ServiceWorkerRegistrationObjectHost::OnUpdateFound(
+ ServiceWorkerRegistration* registration) {
+ DCHECK(remote_registration_);
+ remote_registration_->UpdateFound();
+}
+
+void ServiceWorkerRegistrationObjectHost::Update(UpdateCallback callback) {
+ if (!CanServeRegistrationObjectHostMethods(&callback,
+ kServiceWorkerUpdateErrorPrefix)) {
+ return;
+ }
+
+ if (!registration_->GetNewestVersion()) {
+ // This can happen if update() is called during initial script evaluation.
+ // Abort the following steps according to the spec.
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kState,
+ std::string(kServiceWorkerUpdateErrorPrefix) +
+ std::string(ServiceWorkerConsts::kInvalidStateErrorMessage));
+ return;
+ }
+
+ context_->UpdateServiceWorker(
+ registration_.get(), false /* force_bypass_cache */,
+ false /* skip_script_comparison */, provider_host_,
+ base::AdaptCallbackForRepeating(
+ base::BindOnce(&ServiceWorkerRegistrationObjectHost::UpdateComplete,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback))));
+}
+
+void ServiceWorkerRegistrationObjectHost::Unregister(
+ UnregisterCallback callback) {
+ if (!CanServeRegistrationObjectHostMethods(
+ &callback, kServiceWorkerUnregisterErrorPrefix)) {
+ return;
+ }
+
+ context_->UnregisterServiceWorker(
+ registration_->pattern(),
+ base::AdaptCallbackForRepeating(base::BindOnce(
+ &ServiceWorkerRegistrationObjectHost::UnregistrationComplete,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback))));
+}
+
+void ServiceWorkerRegistrationObjectHost::EnableNavigationPreload(
+ bool enable,
+ EnableNavigationPreloadCallback callback) {
+ if (!CanServeRegistrationObjectHostMethods(
+ &callback,
+ ServiceWorkerConsts::kEnableNavigationPreloadErrorPrefix)) {
+ return;
+ }
+
+ if (!registration_->active_version()) {
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kState,
+ std::string(ServiceWorkerConsts::kEnableNavigationPreloadErrorPrefix) +
+ std::string(ServiceWorkerConsts::kNoActiveWorkerErrorMessage));
+ return;
+ }
+
+ context_->storage()->UpdateNavigationPreloadEnabled(
+ registration_->id(), registration_->pattern().GetOrigin(), enable,
+ base::AdaptCallbackForRepeating(base::BindOnce(
+ &ServiceWorkerRegistrationObjectHost::
+ DidUpdateNavigationPreloadEnabled,
+ weak_ptr_factory_.GetWeakPtr(), enable, std::move(callback))));
+}
+
+void ServiceWorkerRegistrationObjectHost::GetNavigationPreloadState(
+ GetNavigationPreloadStateCallback callback) {
+ if (!CanServeRegistrationObjectHostMethods(
+ &callback, ServiceWorkerConsts::kGetNavigationPreloadStateErrorPrefix,
+ nullptr)) {
+ return;
+ }
+
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt,
+ registration_->navigation_preload_state().Clone());
+}
+
+void ServiceWorkerRegistrationObjectHost::SetNavigationPreloadHeader(
+ const std::string& value,
+ SetNavigationPreloadHeaderCallback callback) {
+ if (!CanServeRegistrationObjectHostMethods(
+ &callback,
+ ServiceWorkerConsts::kSetNavigationPreloadHeaderErrorPrefix)) {
+ return;
+ }
+
+ if (!registration_->active_version()) {
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kState,
+ std::string(
+ ServiceWorkerConsts::kSetNavigationPreloadHeaderErrorPrefix) +
+ std::string(ServiceWorkerConsts::kNoActiveWorkerErrorMessage));
+ return;
+ }
+
+ // TODO(falken): Ideally this would match Blink's isValidHTTPHeaderValue.
+ // Chrome's check is less restrictive: it allows non-latin1 characters.
+ if (!net::HttpUtil::IsValidHeaderValue(value)) {
+ bindings_.ReportBadMessage(
+ ServiceWorkerConsts::kBadNavigationPreloadHeaderValue);
+ return;
+ }
+
+ context_->storage()->UpdateNavigationPreloadHeader(
+ registration_->id(), registration_->pattern().GetOrigin(), value,
+ base::AdaptCallbackForRepeating(base::BindOnce(
+ &ServiceWorkerRegistrationObjectHost::
+ DidUpdateNavigationPreloadHeader,
+ weak_ptr_factory_.GetWeakPtr(), value, std::move(callback))));
+}
+
+void ServiceWorkerRegistrationObjectHost::UpdateComplete(
+ UpdateCallback callback,
+ ServiceWorkerStatusCode status,
+ const std::string& status_message,
+ int64_t registration_id) {
+ if (status != SERVICE_WORKER_OK) {
+ std::string error_message;
+ blink::mojom::ServiceWorkerErrorType error_type;
+ GetServiceWorkerErrorTypeForRegistration(status, status_message,
+ &error_type, &error_message);
+ std::move(callback).Run(error_type,
+ kServiceWorkerUpdateErrorPrefix + error_message);
+ return;
+ }
+
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+}
+
+void ServiceWorkerRegistrationObjectHost::UnregistrationComplete(
+ UnregisterCallback callback,
+ ServiceWorkerStatusCode status) {
+ if (status != SERVICE_WORKER_OK) {
+ std::string error_message;
+ blink::mojom::ServiceWorkerErrorType error_type;
+ GetServiceWorkerErrorTypeForRegistration(status, std::string(), &error_type,
+ &error_message);
+ std::move(callback).Run(
+ error_type, kServiceWorkerUnregisterErrorPrefix + error_message);
+ return;
+ }
+
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+}
+
+void ServiceWorkerRegistrationObjectHost::DidUpdateNavigationPreloadEnabled(
+ bool enable,
+ EnableNavigationPreloadCallback callback,
+ ServiceWorkerStatusCode status) {
+ if (status != SERVICE_WORKER_OK) {
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kUnknown,
+ std::string(ServiceWorkerConsts::kEnableNavigationPreloadErrorPrefix) +
+ std::string(ServiceWorkerConsts::kDatabaseErrorMessage));
+ return;
+ }
+
+ if (registration_)
+ registration_->EnableNavigationPreload(enable);
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+}
+
+void ServiceWorkerRegistrationObjectHost::DidUpdateNavigationPreloadHeader(
+ const std::string& value,
+ SetNavigationPreloadHeaderCallback callback,
+ ServiceWorkerStatusCode status) {
+ if (status != SERVICE_WORKER_OK) {
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kUnknown,
+ std::string(
+ ServiceWorkerConsts::kSetNavigationPreloadHeaderErrorPrefix) +
+ std::string(ServiceWorkerConsts::kDatabaseErrorMessage));
+ return;
+ }
+
+ if (registration_)
+ registration_->SetNavigationPreloadHeader(value);
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+}
+
+void ServiceWorkerRegistrationObjectHost::SetVersionAttributes(
+ ChangedVersionAttributesMask changed_mask,
+ ServiceWorkerVersion* installing_version,
+ ServiceWorkerVersion* waiting_version,
+ ServiceWorkerVersion* active_version) {
+ if (!changed_mask.changed())
+ return;
+
+ blink::mojom::ServiceWorkerObjectInfoPtr installing;
+ blink::mojom::ServiceWorkerObjectInfoPtr waiting;
+ blink::mojom::ServiceWorkerObjectInfoPtr active;
+ if (changed_mask.installing_changed()) {
+ installing =
+ provider_host_->GetOrCreateServiceWorkerHandle(installing_version);
+ }
+ if (changed_mask.waiting_changed())
+ waiting = provider_host_->GetOrCreateServiceWorkerHandle(waiting_version);
+ if (changed_mask.active_changed())
+ active = provider_host_->GetOrCreateServiceWorkerHandle(active_version);
+ DCHECK(remote_registration_);
+ remote_registration_->SetVersionAttributes(
+ changed_mask.changed(), std::move(installing), std::move(waiting),
+ std::move(active));
+}
+
+void ServiceWorkerRegistrationObjectHost::OnConnectionError() {
+ // If there are still bindings, |this| is still being used.
+ if (!bindings_.empty())
+ return;
+ // Will destroy |this|.
+ provider_host_->RemoveServiceWorkerRegistrationObjectHost(
+ registration()->id());
+}
+
+template <typename CallbackType, typename... Args>
+bool ServiceWorkerRegistrationObjectHost::CanServeRegistrationObjectHostMethods(
+ CallbackType* callback,
+ const char* error_prefix,
+ Args... args) {
+ if (!context_) {
+ std::move(*callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kAbort,
+ std::string(error_prefix) +
+ std::string(ServiceWorkerConsts::kShutdownErrorMessage),
+ args...);
+ return false;
+ }
+
+ // TODO(falken): This check can be removed once crbug.com/439697 is fixed.
+ // (Also see crbug.com/776408)
+ if (provider_host_->document_url().is_empty()) {
+ std::move(*callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kSecurity,
+ std::string(error_prefix) +
+ std::string(ServiceWorkerConsts::kNoDocumentURLErrorMessage),
+ args...);
+ return false;
+ }
+
+ std::vector<GURL> urls = {provider_host_->document_url(),
+ registration_->pattern()};
+ if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) {
+ bindings_.ReportBadMessage(ServiceWorkerConsts::kBadMessageImproperOrigins);
+ return false;
+ }
+
+ if (!provider_host_->AllowServiceWorker(registration_->pattern())) {
+ std::move(*callback).Run(
+ blink::mojom::ServiceWorkerErrorType::kDisabled,
+ std::string(error_prefix) +
+ std::string(ServiceWorkerConsts::kUserDeniedPermissionMessage),
+ args...);
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace content
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
new file mode 100644
index 00000000000..be87d38caa5
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_registration_object_host.h
@@ -0,0 +1,130 @@
+// 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_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_OBJECT_HOST_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_OBJECT_HOST_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/common/content_export.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "mojo/public/cpp/bindings/associated_binding_set.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+
+namespace content {
+
+class ServiceWorkerContextCore;
+class ServiceWorkerVersion;
+
+// ServiceWorkerRegistrationObjectHost has a 1:1 correspondence to
+// WebServiceWorkerRegistration in the renderer process.
+// The host stays alive while the WebServiceWorkerRegistration is alive, and
+// also initiates destruction of the WebServiceWorkerRegistration once detected
+// that it's no longer needed. See the class documentation in
+// WebServiceWorkerRegistrationImpl for details.
+//
+// Has a reference to the corresponding ServiceWorkerRegistration in order to
+// ensure that the registration is alive while this object host is around.
+class CONTENT_EXPORT ServiceWorkerRegistrationObjectHost
+ : public blink::mojom::ServiceWorkerRegistrationObjectHost,
+ public ServiceWorkerRegistration::Listener {
+ public:
+ ServiceWorkerRegistrationObjectHost(
+ base::WeakPtr<ServiceWorkerContextCore> context,
+ ServiceWorkerProviderHost* provider_host,
+ scoped_refptr<ServiceWorkerRegistration> registration);
+ ~ServiceWorkerRegistrationObjectHost() override;
+
+ // Establishes a new mojo connection into |bindings_|.
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr CreateObjectInfo();
+
+ ServiceWorkerRegistration* registration() { return registration_.get(); }
+
+ private:
+ // ServiceWorkerRegistration::Listener overrides.
+ void OnVersionAttributesChanged(
+ ServiceWorkerRegistration* registration,
+ ChangedVersionAttributesMask changed_mask,
+ const ServiceWorkerRegistrationInfo& info) override;
+ void OnRegistrationFailed(ServiceWorkerRegistration* registration) override;
+ void OnUpdateFound(ServiceWorkerRegistration* registration) override;
+
+ // Implements blink::mojom::ServiceWorkerRegistrationObjectHost.
+ void Update(UpdateCallback callback) override;
+ void Unregister(UnregisterCallback callback) override;
+ void EnableNavigationPreload(
+ bool enable,
+ EnableNavigationPreloadCallback callback) override;
+ void GetNavigationPreloadState(
+ GetNavigationPreloadStateCallback callback) override;
+ void SetNavigationPreloadHeader(
+ const std::string& value,
+ SetNavigationPreloadHeaderCallback callback) override;
+
+ // Called back from ServiceWorkerContextCore when an update is complete.
+ void UpdateComplete(UpdateCallback callback,
+ ServiceWorkerStatusCode status,
+ const std::string& status_message,
+ int64_t registration_id);
+ // Called back from ServiceWorkerContextCore when the unregistration is
+ // complete.
+ void UnregistrationComplete(UnregisterCallback callback,
+ ServiceWorkerStatusCode status);
+ // Called back from ServiceWorkerStorage when setting navigation preload is
+ // complete.
+ void DidUpdateNavigationPreloadEnabled(
+ bool enable,
+ EnableNavigationPreloadCallback callback,
+ ServiceWorkerStatusCode status);
+ // Called back from ServiceWorkerStorage when setting navigation preload
+ // header is complete.
+ void DidUpdateNavigationPreloadHeader(
+ const std::string& value,
+ SetNavigationPreloadHeaderCallback callback,
+ ServiceWorkerStatusCode status);
+
+ // 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 OnConnectionError();
+
+ // Perform common checks that need to run before RegistrationObjectHost
+ // methods that come from a child process are handled. Returns true if all
+ // checks have passed. If anything looks wrong |callback| will run with an
+ // error message prefixed by |error_prefix| and |args|, and false is returned.
+ template <typename CallbackType, typename... Args>
+ bool CanServeRegistrationObjectHostMethods(CallbackType* callback,
+ const char* error_prefix,
+ Args... args);
+
+ // |provider_host_| is valid throughout lifetime of |this| because it owns
+ // |this|.
+ ServiceWorkerProviderHost* provider_host_;
+ base::WeakPtr<ServiceWorkerContextCore> context_;
+ mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerRegistrationObjectHost>
+ bindings_;
+ // Mojo connection to the content::WebServiceWorkerRegistrationImpl in the
+ // renderer, which corresponds to the ServiceWorkerRegistration JavaScript
+ // object.
+ blink::mojom::ServiceWorkerRegistrationObjectAssociatedPtr
+ remote_registration_;
+
+ scoped_refptr<ServiceWorkerRegistration> registration_;
+
+ base::WeakPtrFactory<ServiceWorkerRegistrationObjectHost> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegistrationObjectHost);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_OBJECT_HOST_H_
diff --git a/chromium/content/browser/service_worker/service_worker_registration_status.cc b/chromium/content/browser/service_worker/service_worker_registration_status.cc
index 0031b75483d..e0472e919a3 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_status.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration_status.cc
@@ -14,69 +14,6 @@ namespace content {
using blink::WebServiceWorkerError;
-void GetServiceWorkerRegistrationStatusResponse(
- ServiceWorkerStatusCode status,
- const std::string& status_message,
- blink::mojom::ServiceWorkerErrorType* error_type,
- base::string16* message) {
- *error_type = blink::mojom::ServiceWorkerErrorType::kUnknown;
- if (!status_message.empty())
- *message = base::UTF8ToUTF16(status_message);
- else
- *message = base::ASCIIToUTF16(ServiceWorkerStatusToString(status));
- switch (status) {
- case SERVICE_WORKER_OK:
- NOTREACHED() << "Calling this when status == OK is not allowed";
- return;
-
- case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
- case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
- case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
- case SERVICE_WORKER_ERROR_REDUNDANT:
- case SERVICE_WORKER_ERROR_DISALLOWED:
- *error_type = blink::mojom::ServiceWorkerErrorType::kInstall;
- return;
-
- case SERVICE_WORKER_ERROR_NOT_FOUND:
- *error_type = blink::mojom::ServiceWorkerErrorType::kNotFound;
- return;
-
- case SERVICE_WORKER_ERROR_NETWORK:
- *error_type = blink::mojom::ServiceWorkerErrorType::kNetwork;
- return;
-
- case SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED:
- *error_type = blink::mojom::ServiceWorkerErrorType::kScriptEvaluateFailed;
- return;
-
- case SERVICE_WORKER_ERROR_SECURITY:
- *error_type = blink::mojom::ServiceWorkerErrorType::kSecurity;
- return;
-
- case SERVICE_WORKER_ERROR_TIMEOUT:
- *error_type = blink::mojom::ServiceWorkerErrorType::kTimeout;
- return;
-
- case SERVICE_WORKER_ERROR_ABORT:
- *error_type = blink::mojom::ServiceWorkerErrorType::kAbort;
- return;
-
- case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
- case SERVICE_WORKER_ERROR_IPC_FAILED:
- case SERVICE_WORKER_ERROR_FAILED:
- case SERVICE_WORKER_ERROR_EXISTS:
- case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
- case SERVICE_WORKER_ERROR_STATE:
- case SERVICE_WORKER_ERROR_DISK_CACHE:
- case SERVICE_WORKER_ERROR_MAX_VALUE:
- // Unexpected, or should have bailed out before calling this, or we don't
- // have a corresponding blink error code yet.
- break; // Fall through to NOTREACHED().
- }
- NOTREACHED() << "Got unexpected error code: "
- << status << " " << ServiceWorkerStatusToString(status);
-}
-
void GetServiceWorkerErrorTypeForRegistration(
ServiceWorkerStatusCode status,
const std::string& status_message,
diff --git a/chromium/content/browser/service_worker/service_worker_registration_status.h b/chromium/content/browser/service_worker/service_worker_registration_status.h
index fe584a5c87a..37c1815b4d9 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_status.h
+++ b/chromium/content/browser/service_worker/service_worker_registration_status.h
@@ -11,17 +11,6 @@
namespace content {
-// TODO(leonhsl): Eliminate this function once all its users changed to use
-// GetServiceWorkerErrorTypeForRegistration() which gets out a std::string
-// |message| rather than a base::string16. The legacy IPC used base::string16 as
-// an old WebKit convention. This should only be called for errors, where status
-// != OK.
-void GetServiceWorkerRegistrationStatusResponse(
- ServiceWorkerStatusCode status,
- const std::string& status_message,
- blink::mojom::ServiceWorkerErrorType* error_type,
- base::string16* message);
-
// This should only be called for errors, where status != OK.
void GetServiceWorkerErrorTypeForRegistration(
ServiceWorkerStatusCode status,
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 6304a37d77b..2dc47b92007 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <utility>
+#include "base/callback_helpers.h"
#include "base/compiler_specific.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
@@ -18,12 +19,16 @@
#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_dispatcher_host.h"
-#include "content/browser/service_worker/service_worker_registration_handle.h"
+#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_registration_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/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/test/test_content_browser_client.h"
+#include "mojo/edk/embedder/embedder.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
#include "url/gurl.h"
@@ -43,6 +48,75 @@ int CreateInflightRequest(ServiceWorkerVersion* version) {
base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
}
+static void SaveStatusCallback(bool* called,
+ ServiceWorkerStatusCode* out,
+ ServiceWorkerStatusCode status) {
+ *called = true;
+ *out = status;
+}
+
+class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient {
+ public:
+ bool AllowServiceWorker(
+ const GURL& scope,
+ const GURL& first_party,
+ content::ResourceContext* context,
+ const base::Callback<WebContents*(void)>& wc_getter) override {
+ return false;
+ }
+};
+
+class MockServiceWorkerRegistrationObject
+ : public blink::mojom::ServiceWorkerRegistrationObject {
+ public:
+ explicit MockServiceWorkerRegistrationObject(
+ blink::mojom::ServiceWorkerRegistrationObjectAssociatedRequest request)
+ : binding_(this) {
+ binding_.Bind(std::move(request));
+ }
+ ~MockServiceWorkerRegistrationObject() override = default;
+
+ int update_found_called_count() const { return update_found_called_count_; };
+ int set_version_attributes_called_count() const {
+ return set_version_attributes_called_count_;
+ };
+ int changed_mask() const { return changed_mask_; }
+ const blink::mojom::ServiceWorkerObjectInfoPtr& installing() const {
+ return installing_;
+ }
+ const blink::mojom::ServiceWorkerObjectInfoPtr& waiting() const {
+ return waiting_;
+ }
+ const blink::mojom::ServiceWorkerObjectInfoPtr& active() const {
+ return active_;
+ }
+
+ private:
+ // Implements blink::mojom::ServiceWorkerRegistrationObject.
+ void SetVersionAttributes(
+ int changed_mask,
+ blink::mojom::ServiceWorkerObjectInfoPtr installing,
+ blink::mojom::ServiceWorkerObjectInfoPtr waiting,
+ blink::mojom::ServiceWorkerObjectInfoPtr active) override {
+ set_version_attributes_called_count_++;
+ changed_mask_ = changed_mask;
+ installing_ = std::move(installing);
+ waiting_ = std::move(waiting);
+ active_ = std::move(active);
+ }
+ void UpdateFound() override { update_found_called_count_++; }
+
+ int update_found_called_count_ = 0;
+ int set_version_attributes_called_count_ = 0;
+ int changed_mask_ = 0;
+ blink::mojom::ServiceWorkerObjectInfoPtr installing_;
+ blink::mojom::ServiceWorkerObjectInfoPtr waiting_;
+ blink::mojom::ServiceWorkerObjectInfoPtr active_;
+
+ mojo::AssociatedBinding<blink::mojom::ServiceWorkerRegistrationObject>
+ binding_;
+};
+
} // namespace
class ServiceWorkerRegistrationTest : public testing::Test {
@@ -93,7 +167,7 @@ class ServiceWorkerRegistrationTest : public testing::Test {
}
void Reset() {
- observed_registration_ = NULL;
+ observed_registration_ = nullptr;
observed_changed_mask_ = ChangedVersionAttributesMask();
observed_info_ = ServiceWorkerRegistrationInfo();
}
@@ -113,16 +187,18 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
const GURL kScript("http://www.example.not/service_worker.js");
int64_t kRegistrationId = 1L;
scoped_refptr<ServiceWorkerRegistration> registration =
- new ServiceWorkerRegistration(
+ base::MakeRefCounted<ServiceWorkerRegistration>(
blink::mojom::ServiceWorkerRegistrationOptions(kScope),
kRegistrationId, context()->AsWeakPtr());
const int64_t version_1_id = 1L;
const int64_t version_2_id = 2L;
- scoped_refptr<ServiceWorkerVersion> version_1 = new ServiceWorkerVersion(
- registration.get(), kScript, version_1_id, context()->AsWeakPtr());
- scoped_refptr<ServiceWorkerVersion> version_2 = new ServiceWorkerVersion(
- registration.get(), kScript, version_2_id, context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> version_1 =
+ base::MakeRefCounted<ServiceWorkerVersion>(
+ registration.get(), kScript, version_1_id, context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> version_2 =
+ base::MakeRefCounted<ServiceWorkerVersion>(
+ registration.get(), kScript, version_2_id, context()->AsWeakPtr());
RegistrationListener listener;
registration->AddListener(&listener);
@@ -136,9 +212,9 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
EXPECT_EQ(kScript, listener.observed_info_.active_version.script_url);
EXPECT_EQ(listener.observed_info_.installing_version.version_id,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
EXPECT_EQ(listener.observed_info_.waiting_version.version_id,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
listener.Reset();
registration->SetInstallingVersion(version_2);
@@ -150,7 +226,7 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
EXPECT_EQ(version_2_id,
listener.observed_info_.installing_version.version_id);
EXPECT_EQ(listener.observed_info_.waiting_version.version_id,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
listener.Reset();
registration->SetWaitingVersion(version_2);
@@ -162,7 +238,7 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
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,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
listener.Reset();
registration->UnsetVersion(version_2.get());
@@ -172,9 +248,9 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
listener.observed_changed_mask_.changed());
EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
EXPECT_EQ(listener.observed_info_.waiting_version.version_id,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
EXPECT_EQ(listener.observed_info_.installing_version.version_id,
- kInvalidServiceWorkerVersionId);
+ blink::mojom::kInvalidServiceWorkerVersionId);
}
TEST_F(ServiceWorkerRegistrationTest, FailedRegistrationNoCrash) {
@@ -186,14 +262,25 @@ TEST_F(ServiceWorkerRegistrationTest, FailedRegistrationNoCrash) {
auto dispatcher_host = base::MakeRefCounted<ServiceWorkerDispatcherHost>(
helper_->mock_render_process_id(),
helper_->browser_context()->GetResourceContext());
- // ServiceWorkerRegistrationHandle ctor will make |handle| be owned by
- // |dispatcher_host|.
- auto* handle = new ServiceWorkerRegistrationHandle(
- context()->AsWeakPtr(), dispatcher_host.get(),
- base::WeakPtr<ServiceWorkerProviderHost>(), registration.get());
- ALLOW_UNUSED_LOCAL(handle);
+ // Prepare a ServiceWorkerProviderHost.
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ std::unique_ptr<ServiceWorkerProviderHost> provider_host =
+ CreateProviderHostWithDispatcherHost(
+ helper_->mock_render_process_id(), 1 /* dummy provider_id */,
+ context()->AsWeakPtr(), 1 /* route_id */, dispatcher_host.get(),
+ &remote_endpoint);
+ auto registration_object_host =
+ std::make_unique<ServiceWorkerRegistrationObjectHost>(
+ context()->AsWeakPtr(), provider_host.get(), registration);
+ // To enable the caller end point
+ // |registration_object_host->remote_registration_| to make calls safely with
+ // no need to pass |object_info_->request| through a message pipe endpoint.
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr object_info =
+ registration_object_host->CreateObjectInfo();
+ mojo::AssociateWithDisconnectedPipe(object_info->request.PassHandle());
+
registration->NotifyRegistrationFailed();
- // Don't crash when handle gets destructed.
+ // Don't crash when |registration_object_host| gets destructed.
}
TEST_F(ServiceWorkerRegistrationTest, NavigationPreload) {
@@ -201,19 +288,21 @@ TEST_F(ServiceWorkerRegistrationTest, NavigationPreload) {
const GURL kScript("https://www.example.not/service_worker.js");
// Setup.
scoped_refptr<ServiceWorkerRegistration> registration =
- new ServiceWorkerRegistration(
+ base::MakeRefCounted<ServiceWorkerRegistration>(
blink::mojom::ServiceWorkerRegistrationOptions(kScope),
storage()->NewRegistrationId(), context()->AsWeakPtr());
- scoped_refptr<ServiceWorkerVersion> version_1 = new ServiceWorkerVersion(
- registration.get(), kScript, storage()->NewVersionId(),
- context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> version_1 =
+ base::MakeRefCounted<ServiceWorkerVersion>(registration.get(), kScript,
+ 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 = new ServiceWorkerVersion(
- registration.get(), kScript, storage()->NewVersionId(),
- context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> version_2 =
+ base::MakeRefCounted<ServiceWorkerVersion>(registration.get(), kScript,
+ storage()->NewVersionId(),
+ context()->AsWeakPtr());
version_2->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
registration->SetWaitingVersion(version_2);
@@ -245,24 +334,27 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
const GURL kScope("https://www.example.not/");
const GURL kScript("https://www.example.not/service_worker.js");
- registration_ = new ServiceWorkerRegistration(
+ registration_ = base::MakeRefCounted<ServiceWorkerRegistration>(
blink::mojom::ServiceWorkerRegistrationOptions(kScope),
storage()->NewRegistrationId(), context()->AsWeakPtr());
// Create an active version.
- scoped_refptr<ServiceWorkerVersion> version_1 = new ServiceWorkerVersion(
- registration_.get(), kScript, storage()->NewVersionId(),
- context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> version_1 =
+ base::MakeRefCounted<ServiceWorkerVersion>(registration_.get(), kScript,
+ storage()->NewVersionId(),
+ context()->AsWeakPtr());
version_1->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
registration_->SetActiveVersion(version_1);
version_1->SetStatus(ServiceWorkerVersion::ACTIVATED);
// Store the registration.
- std::vector<ServiceWorkerDatabase::ResourceRecord> records;
- records.push_back(ServiceWorkerDatabase::ResourceRecord(
- 10, version_1->script_url(), 100));
- version_1->script_cache_map()->SetResources(records);
+ std::vector<ServiceWorkerDatabase::ResourceRecord> records_1;
+ records_1.push_back(WriteToDiskCacheSync(
+ helper_->context()->storage(), version_1->script_url(),
+ helper_->context()->storage()->NewResourceId(), {} /* headers */,
+ "I'm the body", "I'm the meta data"));
+ version_1->script_cache_map()->SetResources(records_1);
version_1->SetMainScriptHttpResponseInfo(
EmbeddedWorkerTestHelper::CreateHttpResponseInfo());
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
@@ -285,9 +377,18 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
inflight_request_id_ = CreateInflightRequest(version_1.get());
// Create a waiting version.
- scoped_refptr<ServiceWorkerVersion> version_2 = new ServiceWorkerVersion(
- registration_.get(), kScript, storage()->NewVersionId(),
- context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> version_2 =
+ base::MakeRefCounted<ServiceWorkerVersion>(registration_.get(), kScript,
+ storage()->NewVersionId(),
+ context()->AsWeakPtr());
+ std::vector<ServiceWorkerDatabase::ResourceRecord> records_2;
+ records_2.push_back(WriteToDiskCacheSync(
+ helper_->context()->storage(), version_2->script_url(),
+ helper_->context()->storage()->NewResourceId(), {} /* headers */,
+ "I'm the body", "I'm the meta data"));
+ version_2->script_cache_map()->SetResources(records_2);
+ version_2->SetMainScriptHttpResponseInfo(
+ EmbeddedWorkerTestHelper::CreateHttpResponseInfo());
version_2->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
registration_->SetWaitingVersion(version_2);
@@ -407,9 +508,9 @@ TEST_F(ServiceWorkerActivationTest, SkipWaitingWithInflightRequest) {
TEST_F(ServiceWorkerActivationTest, TimeSinceSkipWaiting_Installing) {
scoped_refptr<ServiceWorkerRegistration> reg = registration();
scoped_refptr<ServiceWorkerVersion> version = reg->waiting_version();
- base::SimpleTestTickClock* clock = new base::SimpleTestTickClock();
- clock->SetNowTicks(base::TimeTicks::Now());
- version->SetTickClockForTesting(base::WrapUnique(clock));
+ base::SimpleTestTickClock clock;
+ clock.SetNowTicks(base::TimeTicks::Now());
+ version->SetTickClockForTesting(&clock);
// Reset version to the installing phase.
reg->UnsetVersion(version.get());
@@ -419,14 +520,14 @@ TEST_F(ServiceWorkerActivationTest, TimeSinceSkipWaiting_Installing) {
// since the version is not yet installed.
SimulateSkipWaiting(version.get(), 77 /* dummy request_id */);
base::RunLoop().RunUntilIdle();
- clock->Advance(base::TimeDelta::FromSeconds(11));
+ clock.Advance(base::TimeDelta::FromSeconds(11));
EXPECT_EQ(base::TimeDelta(), version->TimeSinceSkipWaiting());
// Install the version. Now the skip waiting time starts ticking.
version->SetStatus(ServiceWorkerVersion::INSTALLED);
reg->SetWaitingVersion(version);
base::RunLoop().RunUntilIdle();
- clock->Advance(base::TimeDelta::FromSeconds(33));
+ clock.Advance(base::TimeDelta::FromSeconds(33));
EXPECT_EQ(base::TimeDelta::FromSeconds(33), version->TimeSinceSkipWaiting());
// Call skipWaiting() again. It doesn't reset the time.
@@ -440,12 +541,12 @@ TEST_F(ServiceWorkerActivationTest, LameDuckTime_SkipWaiting) {
scoped_refptr<ServiceWorkerRegistration> reg = registration();
scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
- base::SimpleTestTickClock* clock_1 = new base::SimpleTestTickClock();
- base::SimpleTestTickClock* clock_2 = new base::SimpleTestTickClock();
- clock_1->SetNowTicks(base::TimeTicks::Now());
- clock_2->SetNowTicks(clock_1->NowTicks());
- version_1->SetTickClockForTesting(base::WrapUnique(clock_1));
- version_2->SetTickClockForTesting(base::WrapUnique(clock_2));
+ base::SimpleTestTickClock clock_1;
+ base::SimpleTestTickClock clock_2;
+ clock_1.SetNowTicks(base::TimeTicks::Now());
+ clock_2.SetNowTicks(clock_1.NowTicks());
+ version_1->SetTickClockForTesting(&clock_1);
+ version_2->SetTickClockForTesting(&clock_2);
// Set skip waiting flag. Since there is still an in-flight request,
// activation should not happen. But the lame duck timer should start.
@@ -456,7 +557,7 @@ TEST_F(ServiceWorkerActivationTest, LameDuckTime_SkipWaiting) {
EXPECT_TRUE(IsLameDuckTimerRunning());
// Move forward by lame duck time.
- clock_2->Advance(kMaxLameDuckTime + base::TimeDelta::FromSeconds(1));
+ clock_2.Advance(kMaxLameDuckTime + base::TimeDelta::FromSeconds(1));
// Activation should happen by the lame duck timer.
RunLameDuckTimer();
@@ -470,12 +571,12 @@ TEST_F(ServiceWorkerActivationTest, LameDuckTime_NoControllee) {
scoped_refptr<ServiceWorkerRegistration> reg = registration();
scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
- base::SimpleTestTickClock* clock_1 = new base::SimpleTestTickClock();
- base::SimpleTestTickClock* clock_2 = new base::SimpleTestTickClock();
- clock_1->SetNowTicks(base::TimeTicks::Now());
- clock_2->SetNowTicks(clock_1->NowTicks());
- version_1->SetTickClockForTesting(base::WrapUnique(clock_1));
- version_2->SetTickClockForTesting(base::WrapUnique(clock_2));
+ base::SimpleTestTickClock clock_1;
+ base::SimpleTestTickClock clock_2;
+ clock_1.SetNowTicks(base::TimeTicks::Now());
+ clock_2.SetNowTicks(clock_1.NowTicks());
+ version_1->SetTickClockForTesting(&clock_1);
+ version_2->SetTickClockForTesting(&clock_2);
// Remove the controllee. Since there is still an in-flight request,
// activation should not happen. But the lame duck timer should start.
@@ -487,7 +588,7 @@ TEST_F(ServiceWorkerActivationTest, LameDuckTime_NoControllee) {
// Move clock forward by a little bit.
constexpr base::TimeDelta kLittleBit = base::TimeDelta::FromMinutes(1);
- clock_1->Advance(kLittleBit);
+ clock_1.Advance(kLittleBit);
// Add a controllee again to reset the lame duck period.
version_1->AddControllee(controllee());
@@ -500,8 +601,8 @@ TEST_F(ServiceWorkerActivationTest, LameDuckTime_NoControllee) {
EXPECT_TRUE(IsLameDuckTimerRunning());
// Move clock forward to the next lame duck timer tick.
- clock_1->Advance(kMaxLameDuckTime - kLittleBit +
- base::TimeDelta::FromSeconds(1));
+ clock_1.Advance(kMaxLameDuckTime - kLittleBit +
+ base::TimeDelta::FromSeconds(1));
// Run the lame duck timer. Activation should not yet happen
// since the lame duck period has not expired.
@@ -511,7 +612,7 @@ TEST_F(ServiceWorkerActivationTest, LameDuckTime_NoControllee) {
EXPECT_TRUE(IsLameDuckTimerRunning());
// Continue on to the next lame duck timer tick.
- clock_1->Advance(kMaxLameDuckTime + base::TimeDelta::FromSeconds(1));
+ clock_1.Advance(kMaxLameDuckTime + base::TimeDelta::FromSeconds(1));
// Activation should happen by the lame duck timer.
RunLameDuckTimer();
@@ -520,4 +621,435 @@ TEST_F(ServiceWorkerActivationTest, LameDuckTime_NoControllee) {
EXPECT_FALSE(IsLameDuckTimerRunning());
}
+// Sets up a registration with a ServiceWorkerRegistrationObjectHost to hold it.
+class ServiceWorkerRegistrationObjectHostTest
+ : public ServiceWorkerRegistrationTest {
+ protected:
+ void SetUp() override {
+ ServiceWorkerRegistrationTest::SetUp();
+ mojo::edk::SetDefaultProcessErrorCallback(base::AdaptCallbackForRepeating(
+ base::BindOnce(&ServiceWorkerRegistrationObjectHostTest::OnMojoError,
+ base::Unretained(this))));
+ }
+
+ void TearDown() override {
+ mojo::edk::SetDefaultProcessErrorCallback(
+ mojo::edk::ProcessErrorCallback());
+ ServiceWorkerRegistrationTest::TearDown();
+ }
+
+ blink::mojom::ServiceWorkerErrorType CallUpdate(
+ blink::mojom::ServiceWorkerRegistrationObjectHost* registration_host) {
+ blink::mojom::ServiceWorkerErrorType error =
+ blink::mojom::ServiceWorkerErrorType::kUnknown;
+ registration_host->Update(base::BindOnce(
+ [](blink::mojom::ServiceWorkerErrorType* out_error,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg) {
+ *out_error = error;
+ },
+ &error));
+ base::RunLoop().RunUntilIdle();
+ return error;
+ }
+
+ blink::mojom::ServiceWorkerErrorType CallUnregister(
+ blink::mojom::ServiceWorkerRegistrationObjectHost* registration_host) {
+ blink::mojom::ServiceWorkerErrorType error =
+ blink::mojom::ServiceWorkerErrorType::kUnknown;
+ registration_host->Unregister(base::BindOnce(
+ [](blink::mojom::ServiceWorkerErrorType* out_error,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg) {
+ *out_error = error;
+ },
+ &error));
+ base::RunLoop().RunUntilIdle();
+ return error;
+ }
+
+ ServiceWorkerStatusCode FindRegistrationInStorage(int64_t registration_id,
+ const GURL& scope) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ storage()->FindRegistrationForId(
+ registration_id, scope,
+ base::AdaptCallbackForRepeating(base::BindOnce(
+ [](ServiceWorkerStatusCode* out_status,
+ ServiceWorkerStatusCode status,
+ scoped_refptr<ServiceWorkerRegistration> registration) {
+ *out_status = status;
+ },
+ &status)));
+ return status;
+ }
+
+ int64_t SetUpRegistration(const GURL& scope, const GURL& script_url) {
+ storage()->LazyInitializeForTest(base::BindOnce(&base::DoNothing));
+ base::RunLoop().RunUntilIdle();
+
+ // Prepare ServiceWorkerRegistration.
+ scoped_refptr<ServiceWorkerRegistration> registration =
+ base::MakeRefCounted<ServiceWorkerRegistration>(
+ blink::mojom::ServiceWorkerRegistrationOptions(scope),
+ storage()->NewRegistrationId(), context()->AsWeakPtr());
+ // Prepare ServiceWorkerVersion.
+ scoped_refptr<ServiceWorkerVersion> version =
+ base::MakeRefCounted<ServiceWorkerVersion>(
+ registration.get(), script_url, storage()->NewVersionId(),
+ context()->AsWeakPtr());
+ std::vector<ServiceWorkerDatabase::ResourceRecord> records;
+ records.push_back(WriteToDiskCacheSync(
+ storage(), version->script_url(), storage()->NewResourceId(),
+ {} /* headers */, "I'm the body", "I'm the meta data"));
+ version->script_cache_map()->SetResources(records);
+ version->SetMainScriptHttpResponseInfo(
+ EmbeddedWorkerTestHelper::CreateHttpResponseInfo());
+ version->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version->SetStatus(ServiceWorkerVersion::INSTALLING);
+ // Make the registration findable via storage functions.
+ bool called = false;
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ storage()->StoreRegistration(registration.get(), version.get(),
+ base::AdaptCallbackForRepeating(base::BindOnce(
+ &SaveStatusCallback, &called, &status)));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+
+ return registration->id();
+ }
+
+ ServiceWorkerRemoteProviderEndpoint PrepareProviderHost(
+ int64_t provider_id,
+ const GURL& document_url) {
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ std::unique_ptr<ServiceWorkerProviderHost> host =
+ CreateProviderHostWithDispatcherHost(
+ helper_->mock_render_process_id(), provider_id,
+ context()->AsWeakPtr(), 1 /* route_id */, dispatcher_host(),
+ &remote_endpoint);
+ host->SetDocumentUrl(document_url);
+ context()->AddProviderHost(std::move(host));
+ return remote_endpoint;
+ }
+
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
+ GetRegistrationFromRemote(mojom::ServiceWorkerContainerHost* container_host,
+ const GURL& url) {
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info;
+ container_host->GetRegistration(
+ url, base::BindOnce(
+ [](blink::mojom::ServiceWorkerRegistrationObjectInfoPtr*
+ out_registration_info,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg,
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
+ registration) {
+ ASSERT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
+ error);
+ *out_registration_info = std::move(registration);
+ },
+ &registration_info));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(registration_info->host_ptr_info.is_valid());
+ return registration_info;
+ }
+
+ ServiceWorkerDispatcherHost* dispatcher_host() {
+ return helper_->GetDispatcherHostForProcess(
+ helper_->mock_render_process_id());
+ }
+
+ void OnMojoError(const std::string& error) { bad_messages_.push_back(error); }
+
+ std::vector<std::string> bad_messages_;
+};
+
+TEST_F(ServiceWorkerRegistrationObjectHostTest, BreakConnection_Destroy) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
+ const int64_t kProviderId = 99; // Dummy value
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareProviderHost(kProviderId, kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr
+ registration_host_ptr;
+ registration_host_ptr.Bind(std::move(info->host_ptr_info));
+
+ EXPECT_NE(nullptr, context()->GetLiveRegistration(registration_id));
+ registration_host_ptr.reset();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(nullptr, context()->GetLiveRegistration(registration_id));
+}
+
+TEST_F(ServiceWorkerRegistrationObjectHostTest, Update_Success) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ SetUpRegistration(kScope, kScriptUrl);
+ const int64_t kProviderId = 99; // Dummy value
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareProviderHost(kProviderId, kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr
+ registration_host_ptr;
+
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope);
+ registration_host_ptr.Bind(std::move(info->host_ptr_info));
+ // Ignore the messages to the registration object, otherwise the callbacks
+ // issued from |registration_host_ptr| may wait for receiving the messages to
+ // |info->request|.
+ info->request = nullptr;
+
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
+ CallUpdate(registration_host_ptr.get()));
+}
+
+TEST_F(ServiceWorkerRegistrationObjectHostTest, Update_CrossOriginShouldFail) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ SetUpRegistration(kScope, kScriptUrl);
+ const int64_t kProviderId = 99; // Dummy value
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareProviderHost(kProviderId, kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr
+ registration_host_ptr;
+ registration_host_ptr.Bind(std::move(info->host_ptr_info));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ context()
+ ->GetProviderHost(helper_->mock_render_process_id(), kProviderId)
+ ->SetDocumentUrl(GURL("https://does.not.exist/"));
+ CallUpdate(registration_host_ptr.get());
+ EXPECT_EQ(1u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerRegistrationObjectHostTest,
+ Update_ContentSettingsDisallowsServiceWorker) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ SetUpRegistration(kScope, kScriptUrl);
+ const int64_t kProviderId = 99; // Dummy value
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareProviderHost(kProviderId, kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr
+ registration_host_ptr;
+ registration_host_ptr.Bind(std::move(info->host_ptr_info));
+
+ ServiceWorkerTestContentBrowserClient test_browser_client;
+ ContentBrowserClient* old_browser_client =
+ SetBrowserClientForTesting(&test_browser_client);
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kDisabled,
+ CallUpdate(registration_host_ptr.get()));
+ SetBrowserClientForTesting(old_browser_client);
+}
+
+TEST_F(ServiceWorkerRegistrationObjectHostTest, Unregister_Success) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
+ const int64_t kProviderId = 99; // Dummy value
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareProviderHost(kProviderId, kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr
+ registration_host_ptr;
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope);
+ registration_host_ptr.Bind(std::move(info->host_ptr_info));
+ // Ignore the messages to the registration object, otherwise the callbacks
+ // issued from |registration_host_ptr| may wait for receiving the messages to
+ // |info->request|.
+ info->request = nullptr;
+
+ EXPECT_EQ(SERVICE_WORKER_OK,
+ FindRegistrationInStorage(registration_id, kScope));
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
+ CallUnregister(registration_host_ptr.get()));
+
+ EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ FindRegistrationInStorage(registration_id, kScope));
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNotFound,
+ CallUnregister(registration_host_ptr.get()));
+}
+
+TEST_F(ServiceWorkerRegistrationObjectHostTest,
+ Unregister_CrossOriginShouldFail) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ SetUpRegistration(kScope, kScriptUrl);
+ const int64_t kProviderId = 99; // Dummy value
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareProviderHost(kProviderId, kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr
+ registration_host_ptr;
+ registration_host_ptr.Bind(std::move(info->host_ptr_info));
+
+ ASSERT_TRUE(bad_messages_.empty());
+ context()
+ ->GetProviderHost(helper_->mock_render_process_id(), kProviderId)
+ ->SetDocumentUrl(GURL("https://does.not.exist/"));
+ CallUnregister(registration_host_ptr.get());
+ EXPECT_EQ(1u, bad_messages_.size());
+}
+
+TEST_F(ServiceWorkerRegistrationObjectHostTest,
+ Unregister_ContentSettingsDisallowsServiceWorker) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ SetUpRegistration(kScope, kScriptUrl);
+ const int64_t kProviderId = 99; // Dummy value
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareProviderHost(kProviderId, kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr
+ registration_host_ptr;
+ registration_host_ptr.Bind(std::move(info->host_ptr_info));
+
+ ServiceWorkerTestContentBrowserClient test_browser_client;
+ ContentBrowserClient* old_browser_client =
+ SetBrowserClientForTesting(&test_browser_client);
+ EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kDisabled,
+ CallUnregister(registration_host_ptr.get()));
+ SetBrowserClientForTesting(old_browser_client);
+}
+
+TEST_F(ServiceWorkerRegistrationObjectHostTest, SetVersionAttributes) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
+ const int64_t kProviderId = 99; // Dummy value
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareProviderHost(kProviderId, kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope);
+ EXPECT_EQ(registration_id, info->registration_id);
+ EXPECT_TRUE(info->request.is_pending());
+ auto mock_registration_object =
+ std::make_unique<MockServiceWorkerRegistrationObject>(
+ std::move(info->request));
+
+ ServiceWorkerRegistration* registration =
+ context()->GetLiveRegistration(registration_id);
+ ASSERT_NE(nullptr, registration);
+ const int64_t version_1_id = 1L;
+ const int64_t version_2_id = 2L;
+ scoped_refptr<ServiceWorkerVersion> version_1 =
+ base::MakeRefCounted<ServiceWorkerVersion>(
+ registration, kScriptUrl, version_1_id, context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> version_2 =
+ base::MakeRefCounted<ServiceWorkerVersion>(
+ registration, kScriptUrl, 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);
+ }
+
+ // 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);
+ }
+
+ // 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_TRUE(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);
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
+ mock_registration_object->installing()->version_id);
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerHandleId,
+ mock_registration_object->installing()->handle_id);
+ }
+
+ // 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_TRUE(mock_registration_object->waiting());
+ EXPECT_FALSE(mask.active_changed());
+ EXPECT_FALSE(mock_registration_object->active());
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
+ mock_registration_object->waiting()->version_id);
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerHandleId,
+ mock_registration_object->waiting()->handle_id);
+ }
+}
+
+TEST_F(ServiceWorkerRegistrationObjectHostTest, UpdateFound) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
+ const int64_t kProviderId = 99; // Dummy value
+ ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ PrepareProviderHost(kProviderId, kScope);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), kScope);
+ EXPECT_EQ(registration_id, info->registration_id);
+ EXPECT_TRUE(info->request.is_pending());
+ auto mock_registration_object =
+ std::make_unique<MockServiceWorkerRegistrationObject>(
+ std::move(info->request));
+
+ ServiceWorkerRegistration* registration =
+ context()->GetLiveRegistration(registration_id);
+ ASSERT_NE(nullptr, registration);
+ EXPECT_EQ(0, mock_registration_object->update_found_called_count());
+ registration->NotifyUpdateFound();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, mock_registration_object->update_found_called_count());
+}
+
} // namespace content
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 50948a4ca04..9c6dd7438bb 100644
--- a/chromium/content/browser/service_worker/service_worker_request_handler.cc
+++ b/chromium/content/browser/service_worker/service_worker_request_handler.cc
@@ -36,8 +36,6 @@ namespace content {
namespace {
-int kUserDataKey; // Key value is not important.
-
class ServiceWorkerRequestInterceptor
: public net::URLRequestInterceptor {
public:
@@ -50,7 +48,7 @@ class ServiceWorkerRequestInterceptor
ServiceWorkerRequestHandler* handler =
ServiceWorkerRequestHandler::GetHandler(request);
if (!handler)
- return NULL;
+ return nullptr;
return handler->MaybeCreateJob(
request, network_delegate, resource_context_);
}
@@ -62,7 +60,11 @@ class ServiceWorkerRequestInterceptor
} // namespace
-// PlzNavigate
+// static
+int ServiceWorkerRequestHandler::user_data_key_;
+
+// PlzNavigate:
+// static
void ServiceWorkerRequestHandler::InitializeForNavigation(
net::URLRequest* request,
ServiceWorkerNavigationHandleCore* navigation_handle_core,
@@ -101,12 +103,14 @@ void ServiceWorkerRequestHandler::InitializeForNavigation(
std::unique_ptr<ServiceWorkerRequestHandler> handler(
provider_host->CreateRequestHandler(
- FETCH_REQUEST_MODE_NAVIGATE, FETCH_CREDENTIALS_MODE_INCLUDE,
+ network::mojom::FetchRequestMode::kNavigate,
+ network::mojom::FetchCredentialsMode::kInclude,
FetchRedirectMode::MANUAL_MODE, std::string() /* integrity */,
- resource_type, request_context_type, frame_type,
- blob_storage_context->AsWeakPtr(), body, skip_service_worker));
+ false /* keepalive */, resource_type, request_context_type,
+ frame_type, blob_storage_context->AsWeakPtr(), body,
+ skip_service_worker));
if (handler)
- request->SetUserData(&kUserDataKey, std::move(handler));
+ request->SetUserData(&user_data_key_, std::move(handler));
// Transfer ownership to the ServiceWorkerNavigationHandleCore.
// In the case of a successful navigation, the SWProviderHost will be
@@ -116,7 +120,7 @@ void ServiceWorkerRequestHandler::InitializeForNavigation(
navigation_handle_core->DidPreCreateProviderHost(std::move(provider_host));
}
-// PlzNavigate and --enable-network-service.
+// S13nServiceWorker:
// static
std::unique_ptr<URLLoaderRequestHandler>
ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
@@ -131,8 +135,7 @@ ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
bool is_parent_frame_secure,
scoped_refptr<ResourceRequestBody> body,
const base::Callback<WebContents*(void)>& web_contents_getter) {
- DCHECK(IsBrowserSideNavigationEnabled() &&
- base::FeatureList::IsEnabled(features::kNetworkService));
+ DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
DCHECK(navigation_handle_core);
// Create the handler even for insecure HTTP since it's used in the
@@ -155,10 +158,12 @@ ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
std::unique_ptr<ServiceWorkerRequestHandler> handler(
provider_host->CreateRequestHandler(
- FETCH_REQUEST_MODE_NAVIGATE, FETCH_CREDENTIALS_MODE_INCLUDE,
+ network::mojom::FetchRequestMode::kNavigate,
+ network::mojom::FetchCredentialsMode::kInclude,
FetchRedirectMode::MANUAL_MODE, std::string() /* integrity */,
- resource_type, request_context_type, frame_type,
- blob_storage_context->AsWeakPtr(), body, skip_service_worker));
+ false /* keepalive */, resource_type, request_context_type,
+ frame_type, blob_storage_context->AsWeakPtr(), body,
+ skip_service_worker));
// Transfer ownership to the ServiceWorkerNavigationHandleCore.
// In the case of a successful navigation, the SWProviderHost will be
@@ -170,6 +175,7 @@ ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
return base::WrapUnique<URLLoaderRequestHandler>(handler.release());
}
+// static
void ServiceWorkerRequestHandler::InitializeHandler(
net::URLRequest* request,
ServiceWorkerContextWrapper* context_wrapper,
@@ -177,10 +183,11 @@ void ServiceWorkerRequestHandler::InitializeHandler(
int process_id,
int provider_id,
bool skip_service_worker,
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
+ network::mojom::FetchRequestMode request_mode,
+ network::mojom::FetchCredentialsMode credentials_mode,
FetchRedirectMode redirect_mode,
const std::string& integrity,
+ bool keepalive,
ResourceType resource_type,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
@@ -204,19 +211,21 @@ void ServiceWorkerRequestHandler::InitializeHandler(
std::unique_ptr<ServiceWorkerRequestHandler> handler(
provider_host->CreateRequestHandler(
- request_mode, credentials_mode, redirect_mode, integrity,
+ request_mode, credentials_mode, redirect_mode, integrity, keepalive,
resource_type, request_context_type, frame_type,
blob_storage_context->AsWeakPtr(), body, skip_service_worker));
if (handler)
- request->SetUserData(&kUserDataKey, std::move(handler));
+ request->SetUserData(&user_data_key_, std::move(handler));
}
+// static
ServiceWorkerRequestHandler* ServiceWorkerRequestHandler::GetHandler(
const net::URLRequest* request) {
return static_cast<ServiceWorkerRequestHandler*>(
- request->GetUserData(&kUserDataKey));
+ request->GetUserData(&user_data_key_));
}
+// static
std::unique_ptr<net::URLRequestInterceptor>
ServiceWorkerRequestHandler::CreateInterceptor(
ResourceContext* resource_context) {
@@ -224,6 +233,7 @@ ServiceWorkerRequestHandler::CreateInterceptor(
new ServiceWorkerRequestInterceptor(resource_context));
}
+// static
bool ServiceWorkerRequestHandler::IsControlledByServiceWorker(
const net::URLRequest* request) {
ServiceWorkerRequestHandler* handler = GetHandler(request);
@@ -233,6 +243,7 @@ bool ServiceWorkerRequestHandler::IsControlledByServiceWorker(
handler->provider_host_->running_hosted_version();
}
+// static
ServiceWorkerProviderHost* ServiceWorkerRequestHandler::GetProviderHost(
const net::URLRequest* request) {
ServiceWorkerRequestHandler* handler = GetHandler(request);
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 2190178cc30..51d257228f3 100644
--- a/chromium/content/browser/service_worker/service_worker_request_handler.h
+++ b/chromium/content/browser/service_worker/service_worker_request_handler.h
@@ -21,6 +21,7 @@
#include "content/public/common/resource_type.h"
#include "content/public/common/service_worker_modes.h"
#include "net/url_request/url_request_job_factory.h"
+#include "services/network/public/interfaces/fetch_api.mojom.h"
namespace net {
class NetworkDelegate;
@@ -63,7 +64,7 @@ class CONTENT_EXPORT ServiceWorkerRequestHandler
scoped_refptr<ResourceRequestBody> body,
const base::Callback<WebContents*(void)>& web_contents_getter);
- // PlzNavigate and --enable-network-service.
+ // S13nServiceWorker:
// Same as InitializeForNavigation() but instead of attaching to a URLRequest,
// just creates a URLLoaderRequestHandler and returns it.
static std::unique_ptr<URLLoaderRequestHandler>
@@ -93,10 +94,11 @@ class CONTENT_EXPORT ServiceWorkerRequestHandler
int process_id,
int provider_id,
bool skip_service_worker,
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
+ network::mojom::FetchRequestMode request_mode,
+ network::mojom::FetchCredentialsMode credentials_mode,
FetchRedirectMode redirect_mode,
const std::string& integrity,
+ bool keepalive,
ResourceType resource_type,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
@@ -163,6 +165,8 @@ class CONTENT_EXPORT ServiceWorkerRequestHandler
int old_process_id_;
int old_provider_id_;
+ static int user_data_key_; // Only address is used.
+
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRequestHandler);
};
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 da0fc2055c0..0dba4b23927 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
@@ -76,9 +76,10 @@ class ServiceWorkerRequestHandlerTest : public testing::Test {
ServiceWorkerRequestHandler::InitializeHandler(
request, context_wrapper(), &blob_storage_context_,
helper_->mock_render_process_id(), kMockProviderId, skip_service_worker,
- FETCH_REQUEST_MODE_NO_CORS, FETCH_CREDENTIALS_MODE_OMIT,
+ network::mojom::FetchRequestMode::kNoCORS,
+ network::mojom::FetchCredentialsMode::kOmit,
FetchRedirectMode::FOLLOW_MODE, std::string() /* integrity */,
- resource_type, REQUEST_CONTEXT_TYPE_HYPERLINK,
+ false /* keepalive */, resource_type, REQUEST_CONTEXT_TYPE_HYPERLINK,
REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL, nullptr);
}
diff --git a/chromium/content/browser/service_worker/service_worker_response_info.cc b/chromium/content/browser/service_worker/service_worker_response_info.cc
index 028e30dada0..814ffd7c89c 100644
--- a/chromium/content/browser/service_worker/service_worker_response_info.cc
+++ b/chromium/content/browser/service_worker/service_worker_response_info.cc
@@ -10,21 +10,18 @@
namespace content {
-namespace {
-
-int kUserDataKey; // Only address is used, value is not important.
-
-} // namespace
+// static
+int ServiceWorkerResponseInfo::user_data_key_;
// static
ServiceWorkerResponseInfo* ServiceWorkerResponseInfo::ForRequest(
net::URLRequest* request,
bool create) {
ServiceWorkerResponseInfo* info = static_cast<ServiceWorkerResponseInfo*>(
- request->GetUserData(&kUserDataKey));
+ request->GetUserData(&user_data_key_));
if (!info && create) {
info = new ServiceWorkerResponseInfo();
- request->SetUserData(&kUserDataKey, base::WrapUnique(info));
+ request->SetUserData(&user_data_key_, base::WrapUnique(info));
}
return info;
}
@@ -42,7 +39,6 @@ void ServiceWorkerResponseInfo::GetExtraResponseInfo(
ResourceResponseInfo* response_info) const {
response_info->was_fetched_via_service_worker =
was_fetched_via_service_worker_;
- response_info->was_fetched_via_foreign_fetch = was_fetched_via_foreign_fetch_;
response_info->was_fallback_required_by_service_worker =
was_fallback_required_;
response_info->url_list_via_service_worker = url_list_via_service_worker_;
@@ -77,7 +73,6 @@ void ServiceWorkerResponseInfo::OnPrepareToRestart(
void ServiceWorkerResponseInfo::OnStartCompleted(
bool was_fetched_via_service_worker,
- bool was_fetched_via_foreign_fetch,
bool was_fallback_required,
const std::vector<GURL>& url_list_via_service_worker,
network::mojom::FetchResponseType response_type_via_service_worker,
@@ -88,7 +83,6 @@ void ServiceWorkerResponseInfo::OnStartCompleted(
const ServiceWorkerHeaderList& cors_exposed_header_names,
bool did_navigation_preload) {
was_fetched_via_service_worker_ = was_fetched_via_service_worker;
- was_fetched_via_foreign_fetch_ = was_fetched_via_foreign_fetch;
was_fallback_required_ = was_fallback_required;
url_list_via_service_worker_ = url_list_via_service_worker;
response_type_via_service_worker_ = response_type_via_service_worker;
@@ -107,7 +101,6 @@ void ServiceWorkerResponseInfo::OnStartCompleted(
void ServiceWorkerResponseInfo::ResetData() {
was_fetched_via_service_worker_ = false;
- was_fetched_via_foreign_fetch_ = false;
was_fallback_required_ = false;
url_list_via_service_worker_.clear();
response_type_via_service_worker_ =
diff --git a/chromium/content/browser/service_worker/service_worker_response_info.h b/chromium/content/browser/service_worker/service_worker_response_info.h
index ab759f1cef3..6dc1f0b7ab0 100644
--- a/chromium/content/browser/service_worker/service_worker_response_info.h
+++ b/chromium/content/browser/service_worker/service_worker_response_info.h
@@ -36,7 +36,6 @@ class CONTENT_EXPORT ServiceWorkerResponseInfo
bool did_navigation_preload);
void OnStartCompleted(
bool was_fetched_via_service_worker,
- bool was_fetched_via_foreign_fetch,
bool was_fallback_required,
const std::vector<GURL>& url_list_via_service_worker,
network::mojom::FetchResponseType response_type_via_service_worker,
@@ -97,7 +96,6 @@ class CONTENT_EXPORT ServiceWorkerResponseInfo
ServiceWorkerResponseInfo();
bool was_fetched_via_service_worker_ = false;
- bool was_fetched_via_foreign_fetch_ = false;
bool was_fallback_required_ = false;
std::vector<GURL> url_list_via_service_worker_;
network::mojom::FetchResponseType response_type_via_service_worker_ =
@@ -108,6 +106,8 @@ class CONTENT_EXPORT ServiceWorkerResponseInfo
std::string response_cache_storage_cache_name_;
ServiceWorkerHeaderList cors_exposed_header_names_;
bool did_navigation_preload_ = false;
+
+ static int user_data_key_; // Only address is used.
};
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_response_type.h b/chromium/content/browser/service_worker/service_worker_response_type.h
index c8e15b9a58f..0d37b880f04 100644
--- a/chromium/content/browser/service_worker/service_worker_response_type.h
+++ b/chromium/content/browser/service_worker/service_worker_response_type.h
@@ -8,7 +8,7 @@
namespace content {
// Response handling type, used in URL {request,loader} jobs.
-enum ServiceWorkerResponseType {
+enum class ServiceWorkerResponseType {
NOT_DETERMINED,
FAIL_DUE_TO_LOST_CONTROLLER,
FALLBACK_TO_NETWORK,
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 ac1ad78a270..c843ab379f0 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
@@ -90,7 +90,7 @@ void ServiceWorkerScriptCacheMap::SetResources(
void ServiceWorkerScriptCacheMap::WriteMetadata(
const GURL& url,
- const std::vector<char>& data,
+ const std::vector<uint8_t>& data,
const net::CompletionCallback& callback) {
ResourceMap::iterator found = resource_map_.find(url);
if (found == resource_map_.end() ||
@@ -114,7 +114,7 @@ void ServiceWorkerScriptCacheMap::WriteMetadata(
void ServiceWorkerScriptCacheMap::ClearMetadata(
const GURL& url,
const net::CompletionCallback& callback) {
- WriteMetadata(url, std::vector<char>(), callback);
+ WriteMetadata(url, std::vector<uint8_t>(), callback);
}
void ServiceWorkerScriptCacheMap::OnMetadataWritten(
diff --git a/chromium/content/browser/service_worker/service_worker_script_cache_map.h b/chromium/content/browser/service_worker/service_worker_script_cache_map.h
index 709b3a88694..5617ff4e2a0 100644
--- a/chromium/content/browser/service_worker/service_worker_script_cache_map.h
+++ b/chromium/content/browser/service_worker/service_worker_script_cache_map.h
@@ -50,7 +50,7 @@ class CONTENT_EXPORT ServiceWorkerScriptCacheMap {
// Writes the metadata of the existing script.
void WriteMetadata(const GURL& url,
- const std::vector<char>& data,
+ const std::vector<uint8_t>& data,
const net::CompletionCallback& callback);
// Clears the metadata of the existing script.
void ClearMetadata(const GURL& url, const net::CompletionCallback& callback);
diff --git a/chromium/content/browser/service_worker/service_worker_script_url_loader.cc b/chromium/content/browser/service_worker/service_worker_script_url_loader.cc
index 7cf1aea2572..2a38721493a 100644
--- a/chromium/content/browser/service_worker/service_worker_script_url_loader.cc
+++ b/chromium/content/browser/service_worker/service_worker_script_url_loader.cc
@@ -6,6 +6,7 @@
#include <memory>
#include "base/numerics/safe_conversions.h"
+#include "components/network_session_configurator/common/network_switches.h"
#include "content/browser/appcache/appcache_response.h"
#include "content/browser/service_worker/service_worker_cache_writer.h"
#include "content/browser/service_worker/service_worker_context_core.h"
@@ -95,7 +96,7 @@ ServiceWorkerScriptURLLoader::ServiceWorkerScriptURLLoader(
mojom::URLLoaderClientPtr network_client;
network_client_binding_.Bind(mojo::MakeRequest(&network_client));
- loader_factory_getter->GetNetworkFactory()->get()->CreateLoaderAndStart(
+ loader_factory_getter->GetNetworkFactory()->CreateLoaderAndStart(
mojo::MakeRequest(&network_loader_), routing_id, request_id, options,
resource_request, std::move(network_client), traffic_annotation);
}
@@ -128,7 +129,7 @@ void ServiceWorkerScriptURLLoader::OnReceiveResponse(
const base::Optional<net::SSLInfo>& ssl_info,
mojom::DownloadedTempFilePtr downloaded_file) {
if (!version_->context() || version_->is_redundant()) {
- CommitCompleted(ResourceRequestCompletionStatus(net::ERR_FAILED));
+ CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED));
return;
}
@@ -152,19 +153,19 @@ void ServiceWorkerScriptURLLoader::OnReceiveResponse(
// Non-2XX HTTP status code is handled as an error.
// TODO(nhiroki): Show an error message equivalent to kBadHTTPResponseError
// in service_worker_write_to_cache_job.cc.
- CommitCompleted(ResourceRequestCompletionStatus(net::ERR_INVALID_RESPONSE));
+ CommitCompleted(
+ network::URLLoaderCompletionStatus(net::ERR_INVALID_RESPONSE));
return;
}
// Check the certificate error.
- // TODO(nhiroki): Ignore the certificate error when the
- // --ignore-certificate-errors flag etc are specified.
- // See ShouldIgnoreSSLError() in service_worker_write_to_cache_job.cc.
- if (net::IsCertStatusError(response_head.cert_status)) {
+ if (net::IsCertStatusError(response_head.cert_status) &&
+ !base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kIgnoreCertificateErrors)) {
// TODO(nhiroki): Show an error message equivalent to kSSLError in
// service_worker_write_to_cache_job.cc.
- CommitCompleted(
- ResourceRequestCompletionStatus(net::ERR_INSECURE_RESPONSE));
+ CommitCompleted(network::URLLoaderCompletionStatus(
+ net::MapCertStatusToNetError(response_head.cert_status)));
return;
}
@@ -173,7 +174,7 @@ void ServiceWorkerScriptURLLoader::OnReceiveResponse(
// TODO(nhiroki): Show an error message equivalent to kNoMIMEError or
// kBadMIMEError in service_worker_write_to_cache_job.cc.
CommitCompleted(
- ResourceRequestCompletionStatus(net::ERR_INSECURE_RESPONSE));
+ network::URLLoaderCompletionStatus(net::ERR_INSECURE_RESPONSE));
return;
}
@@ -189,7 +190,7 @@ void ServiceWorkerScriptURLLoader::OnReceiveResponse(
has_header ? &service_worker_allowed : nullptr, &error_message)) {
// TODO(nhiroki): Report |error_message|.
CommitCompleted(
- ResourceRequestCompletionStatus(net::ERR_INSECURE_RESPONSE));
+ network::URLLoaderCompletionStatus(net::ERR_INSECURE_RESPONSE));
return;
}
@@ -205,7 +206,7 @@ void ServiceWorkerScriptURLLoader::OnReceiveResponse(
void ServiceWorkerScriptURLLoader::OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
- const ResourceResponseHead& respoinse_head) {
+ const ResourceResponseHead& response_head) {
// Resource requests for service worker scripts should not follow redirects.
//
// Step 7.5: "Set request's redirect mode to "error"."
@@ -213,7 +214,7 @@ void ServiceWorkerScriptURLLoader::OnReceiveRedirect(
//
// TODO(nhiroki): Show an error message equivalent to kRedirectError in
// service_worker_write_to_cache_job.cc.
- CommitCompleted(ResourceRequestCompletionStatus(net::ERR_UNSAFE_REDIRECT));
+ CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_UNSAFE_REDIRECT));
}
void ServiceWorkerScriptURLLoader::OnDataDownloaded(int64_t data_len,
@@ -245,7 +246,7 @@ void ServiceWorkerScriptURLLoader::OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle client_consumer;
if (mojo::CreateDataPipe(nullptr, &client_producer_, &client_consumer) !=
MOJO_RESULT_OK) {
- CommitCompleted(ResourceRequestCompletionStatus(net::ERR_FAILED));
+ CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED));
return;
}
@@ -257,7 +258,7 @@ void ServiceWorkerScriptURLLoader::OnStartLoadingResponseBody(
}
void ServiceWorkerScriptURLLoader::OnComplete(
- const ResourceRequestCompletionStatus& status) {
+ const network::URLLoaderCompletionStatus& status) {
if (status.error_code != net::OK) {
CommitCompleted(status);
return;
@@ -274,7 +275,7 @@ void ServiceWorkerScriptURLLoader::OnComplete(
// storage.
return;
case State::kWroteData:
- CommitCompleted(ResourceRequestCompletionStatus(net::OK));
+ CommitCompleted(network::URLLoaderCompletionStatus(net::OK));
return;
}
NOTREACHED() << static_cast<int>(state_);
@@ -323,7 +324,7 @@ void ServiceWorkerScriptURLLoader::WriteHeaders(
void ServiceWorkerScriptURLLoader::OnWriteHeadersComplete(net::Error error) {
DCHECK_NE(net::ERR_IO_PENDING, error);
if (error != net::OK) {
- CommitCompleted(ResourceRequestCompletionStatus(error));
+ CommitCompleted(network::URLLoaderCompletionStatus(error));
return;
}
AdvanceState(State::kWroteHeaders);
@@ -366,7 +367,7 @@ void ServiceWorkerScriptURLLoader::OnNetworkDataAvailable(MojoResult) {
// notified via OnComplete().
AdvanceState(State::kWroteData);
if (network_load_completed_)
- CommitCompleted(ResourceRequestCompletionStatus(net::OK));
+ CommitCompleted(network::URLLoaderCompletionStatus(net::OK));
return;
case MOJO_RESULT_SHOULD_WAIT:
network_watcher_.ArmOrNotify();
@@ -390,7 +391,7 @@ void ServiceWorkerScriptURLLoader::WriteData(
case MOJO_RESULT_OK:
break;
case MOJO_RESULT_FAILED_PRECONDITION:
- CommitCompleted(ResourceRequestCompletionStatus(net::ERR_FAILED));
+ CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED));
return;
case MOJO_RESULT_SHOULD_WAIT:
// No data was written to |client_producer_| because the pipe was full.
@@ -426,7 +427,7 @@ void ServiceWorkerScriptURLLoader::OnWriteDataComplete(
net::Error error) {
DCHECK_NE(net::ERR_IO_PENDING, error);
if (error != net::OK) {
- CommitCompleted(ResourceRequestCompletionStatus(error));
+ CommitCompleted(network::URLLoaderCompletionStatus(error));
return;
}
DCHECK(pending_buffer);
@@ -437,7 +438,7 @@ void ServiceWorkerScriptURLLoader::OnWriteDataComplete(
}
void ServiceWorkerScriptURLLoader::CommitCompleted(
- const ResourceRequestCompletionStatus& status) {
+ const network::URLLoaderCompletionStatus& status) {
AdvanceState(State::kCompleted);
net::Error error_code = static_cast<net::Error>(status.error_code);
int bytes_written = -1;
diff --git a/chromium/content/browser/service_worker/service_worker_script_url_loader.h b/chromium/content/browser/service_worker/service_worker_script_url_loader.h
index 9c707840842..f7b9c601b7f 100644
--- a/chromium/content/browser/service_worker/service_worker_script_url_loader.h
+++ b/chromium/content/browser/service_worker/service_worker_script_url_loader.h
@@ -80,7 +80,7 @@ class CONTENT_EXPORT ServiceWorkerScriptURLLoader
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- void OnComplete(const ResourceRequestCompletionStatus& status) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
// Buffer size for reading script data from network.
const static uint32_t kReadBufferSize;
@@ -117,7 +117,7 @@ class CONTENT_EXPORT ServiceWorkerScriptURLLoader
// This is the last method that is called on this class. Notifies the final
// result to |client_| and clears all mojo connections etc.
- void CommitCompleted(const ResourceRequestCompletionStatus& status);
+ void CommitCompleted(const network::URLLoaderCompletionStatus& status);
const GURL request_url_;
diff --git a/chromium/content/browser/service_worker/service_worker_script_url_loader_factory.cc b/chromium/content/browser/service_worker/service_worker_script_url_loader_factory.cc
index d2ffd407d39..4d9ec57f508 100644
--- a/chromium/content/browser/service_worker/service_worker_script_url_loader_factory.cc
+++ b/chromium/content/browser/service_worker/service_worker_script_url_loader_factory.cc
@@ -43,14 +43,13 @@ void ServiceWorkerScriptURLLoaderFactory::CreateLoaderAndStart(
// associated message pipes.
// TODO(kinuko): Record the reason like what we do with netlog in
// ServiceWorkerContextRequestHandler.
- (*loader_factory_getter_->GetNetworkFactory())
- ->CreateLoaderAndStart(std::move(request), routing_id, request_id,
- options, resource_request, std::move(client),
- traffic_annotation);
+ loader_factory_getter_->GetNetworkFactory()->CreateLoaderAndStart(
+ std::move(request), routing_id, request_id, options, resource_request,
+ std::move(client), traffic_annotation);
return;
}
mojo::MakeStrongBinding(
- base::MakeUnique<ServiceWorkerScriptURLLoader>(
+ std::make_unique<ServiceWorkerScriptURLLoader>(
routing_id, request_id, options, resource_request, std::move(client),
provider_host_->running_hosted_version(), loader_factory_getter_,
traffic_annotation),
diff --git a/chromium/content/browser/service_worker/service_worker_script_url_loader_unittest.cc b/chromium/content/browser/service_worker/service_worker_script_url_loader_unittest.cc
index c7080d7c82f..f5aa2206340 100644
--- a/chromium/content/browser/service_worker/service_worker_script_url_loader_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_script_url_loader_unittest.cc
@@ -12,7 +12,6 @@
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/url_loader_factory_getter.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "content/public/common/url_loader_factory.mojom.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_url_loader_client.h"
@@ -23,6 +22,7 @@
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
namespace content {
@@ -90,17 +90,16 @@ class MockNetworkURLLoaderFactory final : public mojom::URLLoaderFactory {
ResourceResponseHead response_head;
response_head.headers = info.headers;
response_head.headers->GetMimeType(&response_head.mime_type);
- base::Optional<net::SSLInfo> ssl_info;
if (response.has_certificate_error) {
- ssl_info.emplace();
- ssl_info->cert_status = net::CERT_STATUS_DATE_INVALID;
+ response_head.cert_status = net::CERT_STATUS_DATE_INVALID;
}
if (response_head.headers->response_code() == 307) {
client->OnReceiveRedirect(net::RedirectInfo(), response_head);
return;
}
- client->OnReceiveResponse(response_head, ssl_info, nullptr);
+ client->OnReceiveResponse(response_head, base::nullopt /* ssl_info */,
+ nullptr /* downloaded_file */);
// Pass the response body to the client.
uint32_t bytes_written = response.body.size();
@@ -110,7 +109,7 @@ class MockNetworkURLLoaderFactory final : public mojom::URLLoaderFactory {
ASSERT_EQ(MOJO_RESULT_OK, result);
client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
- ResourceRequestCompletionStatus status;
+ network::URLLoaderCompletionStatus status;
status.error_code = net::OK;
client->OnComplete(status);
}
@@ -149,11 +148,10 @@ class ServiceWorkerScriptURLLoaderTest : public testing::Test {
// Initialize URLLoaderFactory.
mojom::URLLoaderFactoryPtr test_loader_factory;
- mojo::MakeStrongBinding(
- std::make_unique<MockNetworkURLLoaderFactory>(mock_server_.get()),
- MakeRequest(&test_loader_factory));
+ mock_url_loader_factory_ =
+ std::make_unique<MockNetworkURLLoaderFactory>(mock_server_.get());
helper_->url_loader_factory_getter()->SetNetworkFactoryForTesting(
- std::move(test_loader_factory));
+ mock_url_loader_factory_.get());
}
void InitializeStorage() {
@@ -252,6 +250,7 @@ class ServiceWorkerScriptURLLoaderTest : public testing::Test {
protected:
TestBrowserThreadBundle thread_bundle_;
+ std::unique_ptr<MockNetworkURLLoaderFactory> mock_url_loader_factory_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
scoped_refptr<ServiceWorkerRegistration> registration_;
@@ -383,7 +382,7 @@ TEST_F(ServiceWorkerScriptURLLoaderTest, Error_CertificateError) {
// The request should be failed because of the response with the certificate
// error.
- EXPECT_EQ(net::ERR_INSECURE_RESPONSE, client_.completion_status().error_code);
+ EXPECT_EQ(net::ERR_CERT_DATE_INVALID, client_.completion_status().error_code);
EXPECT_FALSE(client_.has_received_response());
// The response shouldn't be stored in the storage.
diff --git a/chromium/content/browser/service_worker/service_worker_storage.cc b/chromium/content/browser/service_worker/service_worker_storage.cc
index bf25534b47e..538048ab6a3 100644
--- a/chromium/content/browser/service_worker/service_worker_storage.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage.cc
@@ -5,7 +5,6 @@
#include "content/browser/service_worker/service_worker_storage.h"
#include <stddef.h>
-#include <memory>
#include <utility>
#include "base/bind_helpers.h"
@@ -29,7 +28,9 @@
#include "net/base/net_errors.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/quota/special_storage_policy.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+#include "third_party/WebKit/public/platform/web_feature.mojom.h"
using std::swap;
@@ -71,8 +72,8 @@ const base::FilePath::CharType kDatabaseName[] =
const base::FilePath::CharType kDiskCacheName[] =
FILE_PATH_LITERAL("ScriptCache");
-const int kMaxMemDiskCacheSize = 10 * 1024 * 1024;
-const int kMaxDiskCacheSize = 250 * 1024 * 1024;
+const int kMaxServiceWorkerStorageMemDiskCacheSize = 10 * 1024 * 1024;
+const int kMaxServiceWorkerStorageDiskCacheSize = 250 * 1024 * 1024;
ServiceWorkerStatusCode DatabaseStatusToStatusCode(
ServiceWorkerDatabase::Status status) {
@@ -98,7 +99,7 @@ void DidUpdateNavigationPreloadState(
ServiceWorkerStorage::InitialData::InitialData()
: next_registration_id(blink::mojom::kInvalidServiceWorkerRegistrationId),
- next_version_id(kInvalidServiceWorkerVersionId),
+ next_version_id(blink::mojom::kInvalidServiceWorkerVersionId),
next_resource_id(kInvalidServiceWorkerResourceId) {}
ServiceWorkerStorage::InitialData::~InitialData() {
@@ -399,8 +400,6 @@ void ServiceWorkerStorage::StoreRegistration(
data.version_id = version->version_id();
data.last_update_check = registration->last_update_check();
data.is_active = (version == registration->active_version());
- data.foreign_fetch_scopes = version->foreign_fetch_scopes();
- data.foreign_fetch_origins = version->foreign_fetch_origins();
if (version->origin_trial_tokens())
data.origin_trial_tokens = *version->origin_trial_tokens();
data.navigation_preload_state = registration->navigation_preload_state();
@@ -704,6 +703,40 @@ void ServiceWorkerStorage::GetUserDataByKeyPrefix(
weak_factory_.GetWeakPtr(), callback)));
}
+void ServiceWorkerStorage::GetUserKeysAndDataByKeyPrefix(
+ int64_t registration_id,
+ const std::string& key_prefix,
+ const GetUserKeysAndDataCallback& callback) {
+ if (!LazyInitialize(base::BindOnce(
+ &ServiceWorkerStorage::GetUserKeysAndDataByKeyPrefix,
+ weak_factory_.GetWeakPtr(), registration_id, key_prefix, callback))) {
+ if (state_ != INITIALIZING) {
+ RunSoon(
+ FROM_HERE,
+ base::BindOnce(callback, base::flat_map<std::string, std::string>(),
+ SERVICE_WORKER_ERROR_ABORT));
+ }
+ return;
+ }
+ DCHECK_EQ(INITIALIZED, state_);
+
+ if (registration_id == blink::mojom::kInvalidServiceWorkerRegistrationId ||
+ key_prefix.empty()) {
+ RunSoon(FROM_HERE,
+ base::BindOnce(callback, base::flat_map<std::string, std::string>(),
+ SERVICE_WORKER_ERROR_FAILED));
+ return;
+ }
+
+ database_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ServiceWorkerStorage::GetUserKeysAndDataByKeyPrefixInDB,
+ database_.get(), base::ThreadTaskRunnerHandle::Get(),
+ registration_id, key_prefix,
+ base::Bind(&ServiceWorkerStorage::DidGetUserKeysAndData,
+ weak_factory_.GetWeakPtr(), callback)));
+}
+
void ServiceWorkerStorage::ClearUserData(int64_t registration_id,
const std::vector<std::string>& keys,
const StatusCallback& callback) {
@@ -847,12 +880,6 @@ void ServiceWorkerStorage::GetUserDataForAllRegistrationsByKeyPrefix(
weak_factory_.GetWeakPtr(), callback)));
}
-bool ServiceWorkerStorage::OriginHasForeignFetchRegistrations(
- const GURL& origin) {
- return !IsDisabled() &&
- foreign_fetch_origins_.find(origin) != foreign_fetch_origins_.end();
-}
-
void ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) {
Disable();
@@ -888,7 +915,7 @@ int64_t ServiceWorkerStorage::NewRegistrationId() {
int64_t ServiceWorkerStorage::NewVersionId() {
if (state_ == DISABLED)
- return kInvalidServiceWorkerVersionId;
+ return blink::mojom::kInvalidServiceWorkerVersionId;
DCHECK_EQ(INITIALIZED, state_);
return next_version_id_++;
}
@@ -958,7 +985,7 @@ ServiceWorkerStorage::ServiceWorkerStorage(
storage::QuotaManagerProxy* quota_manager_proxy,
storage::SpecialStoragePolicy* special_storage_policy)
: next_registration_id_(blink::mojom::kInvalidServiceWorkerRegistrationId),
- next_version_id_(kInvalidServiceWorkerVersionId),
+ next_version_id_(blink::mojom::kInvalidServiceWorkerVersionId),
next_resource_id_(kInvalidServiceWorkerResourceId),
state_(UNINITIALIZED),
expecting_done_with_disk_on_disable_(false),
@@ -1023,7 +1050,6 @@ void ServiceWorkerStorage::DidReadInitialData(
next_version_id_ = data->next_version_id;
next_resource_id_ = data->next_resource_id;
registered_origins_.swap(data->origins);
- foreign_fetch_origins_.swap(data->foreign_fetch_origins);
state_ = INITIALIZED;
ServiceWorkerMetrics::RecordRegisteredOriginCount(
registered_origins_.size());
@@ -1269,8 +1295,6 @@ void ServiceWorkerStorage::DidStoreRegistration(
return;
}
registered_origins_.insert(origin);
- if (!new_version.foreign_fetch_scopes.empty())
- foreign_fetch_origins_.insert(origin);
scoped_refptr<ServiceWorkerRegistration> registration =
context_->GetLiveRegistration(new_version.registration_id);
@@ -1324,11 +1348,8 @@ void ServiceWorkerStorage::DidDeleteRegistration(
storage::StorageType::kStorageTypeTemporary,
-deleted_version.resources_total_size_bytes);
}
- if (origin_state == OriginState::DELETE_FROM_ALL)
+ if (origin_state == OriginState::kDelete)
registered_origins_.erase(params.origin);
- if (origin_state == OriginState::DELETE_FROM_ALL ||
- origin_state == OriginState::DELETE_FROM_FOREIGN_FETCH)
- foreign_fetch_origins_.erase(params.origin);
params.callback.Run(SERVICE_WORKER_OK);
if (!context_->GetLiveVersion(deleted_version.version_id))
@@ -1375,6 +1396,17 @@ void ServiceWorkerStorage::DidGetUserData(
callback.Run(data, DatabaseStatusToStatusCode(status));
}
+void ServiceWorkerStorage::DidGetUserKeysAndData(
+ const GetUserKeysAndDataCallback& callback,
+ const base::flat_map<std::string, std::string>& data_map,
+ ServiceWorkerDatabase::Status status) {
+ if (status != ServiceWorkerDatabase::STATUS_OK &&
+ status != ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
+ ScheduleDeleteAndStartOver();
+ }
+ callback.Run(data_map, DatabaseStatusToStatusCode(status));
+}
+
void ServiceWorkerStorage::DidDeleteUserData(
const StatusCallback& callback,
ServiceWorkerDatabase::Status status) {
@@ -1422,11 +1454,25 @@ ServiceWorkerStorage::GetOrCreateRegistration(
version->SetStatus(data.is_active ?
ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED);
version->script_cache_map()->SetResources(resources);
- version->set_foreign_fetch_scopes(data.foreign_fetch_scopes);
- version->set_foreign_fetch_origins(data.foreign_fetch_origins);
if (data.origin_trial_tokens)
version->SetValidOriginTrialTokens(*data.origin_trial_tokens);
- version->set_used_features(data.used_features);
+
+ // Some features may be outside the valid range of features, if the data on
+ // disk was written by a later version of Chrome than currently running
+ // (crbug.com/758419).
+ // TODO(falken): Maybe Chrome should have a generic mechanism to detect
+ // profile downgrade and just abort? Or we could just crash here, but that
+ // seems extreme and difficult for a user to escape.
+ std::set<uint32_t> used_features = data.used_features;
+ for (auto it = used_features.begin(); it != used_features.end();) {
+ if (*it >=
+ static_cast<uint32_t>(blink::mojom::WebFeature::kNumberOfFeatures)) {
+ it = used_features.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ version->set_used_features(used_features);
}
if (version->status() == ServiceWorkerVersion::ACTIVATED)
@@ -1488,8 +1534,8 @@ ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() {
base::FilePath path = GetDiskCachePath();
if (path.empty()) {
- int rv = disk_cache_->InitWithMemBackend(kMaxMemDiskCacheSize,
- net::CompletionCallback());
+ int rv = disk_cache_->InitWithMemBackend(
+ kMaxServiceWorkerStorageMemDiskCacheSize, net::CompletionCallback());
DCHECK_EQ(net::OK, rv);
return disk_cache_.get();
}
@@ -1502,7 +1548,7 @@ void ServiceWorkerStorage::InitializeDiskCache() {
disk_cache_->set_is_waiting_to_initialize(false);
expecting_done_with_disk_on_disable_ = true;
int rv = disk_cache_->InitWithDiskBackend(
- GetDiskCachePath(), kMaxDiskCacheSize, false,
+ GetDiskCachePath(), kMaxServiceWorkerStorageDiskCacheSize, false,
base::BindOnce(&ServiceWorkerStorage::DiskCacheImplDoneWithDisk,
weak_factory_.GetWeakPtr()),
base::Bind(&ServiceWorkerStorage::OnDiskCacheInitialized,
@@ -1686,8 +1732,6 @@ void ServiceWorkerStorage::ReadInitialDataFromDB(
return;
}
- status = database->GetOriginsWithForeignFetchRegistrations(
- &data->foreign_fetch_origins);
original_task_runner->PostTask(
FROM_HERE,
base::BindOnce(callback, base::Passed(std::move(data)), status));
@@ -1707,9 +1751,8 @@ void ServiceWorkerStorage::DeleteRegistrationFromDB(
registration_id, origin, &deleted_version, &newly_purgeable_resources);
if (status != ServiceWorkerDatabase::STATUS_OK) {
original_task_runner->PostTask(
- FROM_HERE,
- base::BindOnce(callback, OriginState::KEEP_ALL, deleted_version,
- std::vector<int64_t>(), status));
+ FROM_HERE, base::BindOnce(callback, OriginState::kKeep, deleted_version,
+ std::vector<int64_t>(), status));
return;
}
@@ -1719,24 +1762,13 @@ void ServiceWorkerStorage::DeleteRegistrationFromDB(
status = database->GetRegistrationsForOrigin(origin, &registrations, nullptr);
if (status != ServiceWorkerDatabase::STATUS_OK) {
original_task_runner->PostTask(
- FROM_HERE,
- base::BindOnce(callback, OriginState::KEEP_ALL, deleted_version,
- std::vector<int64_t>(), status));
+ FROM_HERE, base::BindOnce(callback, OriginState::kKeep, deleted_version,
+ std::vector<int64_t>(), status));
return;
}
- OriginState origin_state = registrations.empty()
- ? OriginState::DELETE_FROM_ALL
- : OriginState::DELETE_FROM_FOREIGN_FETCH;
-
- // TODO(mek): Add convenient method to ServiceWorkerDatabase to check the
- // foreign fetch scope origin list.
- for (const auto& registration : registrations) {
- if (!registration.foreign_fetch_scopes.empty()) {
- origin_state = OriginState::KEEP_ALL;
- break;
- }
- }
+ OriginState origin_state =
+ registrations.empty() ? OriginState::kDelete : OriginState::kKeep;
original_task_runner->PostTask(
FROM_HERE, base::BindOnce(callback, origin_state, deleted_version,
newly_purgeable_resources, status));
@@ -1889,6 +1921,20 @@ void ServiceWorkerStorage::GetUserDataByKeyPrefixInDB(
base::BindOnce(callback, values, status));
}
+void ServiceWorkerStorage::GetUserKeysAndDataByKeyPrefixInDB(
+ ServiceWorkerDatabase* database,
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+ int64_t registration_id,
+ const std::string& key_prefix,
+ const GetUserKeysAndDataInDBCallback& callback) {
+ base::flat_map<std::string, std::string> data_map;
+ ServiceWorkerDatabase::Status status =
+ database->ReadUserKeysAndDataByKeyPrefix(registration_id, key_prefix,
+ &data_map);
+ original_task_runner->PostTask(FROM_HERE,
+ base::BindOnce(callback, data_map, status));
+}
+
void ServiceWorkerStorage::GetUserDataForAllRegistrationsInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
diff --git a/chromium/content/browser/service_worker/service_worker_storage.h b/chromium/content/browser/service_worker/service_worker_storage.h
index 39c0cf30845..50b5b8e7154 100644
--- a/chromium/content/browser/service_worker/service_worker_storage.h
+++ b/chromium/content/browser/service_worker/service_worker_storage.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <utility>
@@ -15,6 +16,7 @@
#include "base/bind.h"
#include "base/containers/circular_deque.h"
+#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -71,6 +73,9 @@ class CONTENT_EXPORT ServiceWorkerStorage
using GetUserDataCallback =
base::Callback<void(const std::vector<std::string>& data,
ServiceWorkerStatusCode status)>;
+ using GetUserKeysAndDataCallback = base::Callback<void(
+ const base::flat_map<std::string, std::string>& data_map,
+ ServiceWorkerStatusCode status)>;
typedef base::Callback<void(
const std::vector<std::pair<int64_t, std::string>>& user_data,
ServiceWorkerStatusCode status)> GetUserDataForAllRegistrationsCallback;
@@ -178,14 +183,23 @@ class CONTENT_EXPORT ServiceWorkerStorage
// Provide a storage mechanism to read/write arbitrary data associated with
// a registration. Each registration has its own key namespace.
- // GetUserData/GetUserDataByKeyPrefix responds OK only if all keys are found;
- // otherwise NOT_FOUND, and the callback's data will be empty.
+ // GetUserData responds OK only if all keys are found; otherwise NOT_FOUND,
+ // and the callback's data will be empty.
void GetUserData(int64_t registration_id,
const std::vector<std::string>& keys,
const GetUserDataCallback& callback);
+ // GetUserDataByKeyPrefix responds OK with a vector containing data rows that
+ // had matching keys assuming the database was read successfully.
void GetUserDataByKeyPrefix(int64_t registration_id,
const std::string& key_prefix,
const GetUserDataCallback& callback);
+ // GetUserKeysAndDataByKeyPrefix responds OK with a flat_map containing
+ // matching keys and their data assuming the database was read successfully.
+ // The map keys have |key_prefix| stripped from them.
+ void GetUserKeysAndDataByKeyPrefix(
+ int64_t registration_id,
+ const std::string& key_prefix,
+ const GetUserKeysAndDataCallback& callback);
// Stored data is deleted when the associated registraton is deleted.
void StoreUserData(
@@ -213,10 +227,6 @@ class CONTENT_EXPORT ServiceWorkerStorage
const std::string& key_prefix,
const GetUserDataForAllRegistrationsCallback& callback);
- // Returns true if any service workers at |origin| have registered for foreign
- // fetch.
- bool OriginHasForeignFetchRegistrations(const GURL& origin);
-
// Deletes the storage and starts over.
void DeleteAndStartOver(const StatusCallback& callback);
@@ -270,7 +280,6 @@ class CONTENT_EXPORT ServiceWorkerStorage
int64_t next_version_id;
int64_t next_resource_id;
std::set<GURL> origins;
- std::set<GURL> foreign_fetch_origins;
InitialData();
~InitialData();
@@ -288,13 +297,10 @@ class CONTENT_EXPORT ServiceWorkerStorage
};
enum class OriginState {
- // Other registrations with foreign fetch scopes exist for the origin.
- KEEP_ALL,
- // Other registrations exist at this origin, but none of them have foreign
- // fetch scopes.
- DELETE_FROM_FOREIGN_FETCH,
- // No other registrations exist at this origin.
- DELETE_FROM_ALL
+ // Registrations may exist at this origin. It cannot be deleted.
+ kKeep,
+ // No registrations exist at this origin. It can be deleted.
+ kDelete
};
typedef std::vector<ServiceWorkerDatabase::RegistrationData> RegistrationList;
@@ -319,6 +325,9 @@ class CONTENT_EXPORT ServiceWorkerStorage
const ServiceWorkerDatabase::RegistrationData& data,
const ResourceList& resources,
ServiceWorkerDatabase::Status status)> FindInDBCallback;
+ using GetUserKeysAndDataInDBCallback = base::Callback<void(
+ const base::flat_map<std::string, std::string>& data_map,
+ ServiceWorkerDatabase::Status)>;
typedef base::Callback<void(const std::vector<std::string>& data,
ServiceWorkerDatabase::Status)>
GetUserDataInDBCallback;
@@ -395,9 +404,12 @@ class CONTENT_EXPORT ServiceWorkerStorage
void DidGetUserData(const GetUserDataCallback& callback,
const std::vector<std::string>& data,
ServiceWorkerDatabase::Status status);
- void DidDeleteUserData(
- const StatusCallback& callback,
+ void DidGetUserKeysAndData(
+ const GetUserKeysAndDataCallback& callback,
+ const base::flat_map<std::string, std::string>& map,
ServiceWorkerDatabase::Status status);
+ void DidDeleteUserData(const StatusCallback& callback,
+ ServiceWorkerDatabase::Status status);
void DidGetUserDataForAllRegistrations(
const GetUserDataForAllRegistrationsCallback& callback,
const std::vector<std::pair<int64_t, std::string>>& user_data,
@@ -492,6 +504,12 @@ class CONTENT_EXPORT ServiceWorkerStorage
int64_t registration_id,
const std::string& key_prefix,
const GetUserDataInDBCallback& callback);
+ static void GetUserKeysAndDataByKeyPrefixInDB(
+ ServiceWorkerDatabase* database,
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+ int64_t registration_id,
+ const std::string& key_prefix,
+ const GetUserKeysAndDataInDBCallback& callback);
static void GetUserDataForAllRegistrationsInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
@@ -525,7 +543,6 @@ class CONTENT_EXPORT ServiceWorkerStorage
// Origins having registations.
std::set<GURL> registered_origins_;
- std::set<GURL> foreign_fetch_origins_;
// Pending database tasks waiting for initialization.
std::vector<base::OnceClosure> pending_tasks_;
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 b8362924385..ec74e853dd0 100644
--- a/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -40,6 +40,7 @@
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
using net::IOBuffer;
@@ -269,7 +270,7 @@ int WriteResponseMetadata(ServiceWorkerStorage* storage,
int WriteMetadata(ServiceWorkerVersion* version,
const GURL& url,
const std::string& metadata) {
- const std::vector<char> data(metadata.begin(), metadata.end());
+ const std::vector<uint8_t> data(metadata.begin(), metadata.end());
EXPECT_TRUE(version);
TestCompletionCallback cb;
version->script_cache_map()->WriteMetadata(url, data, cb.callback());
@@ -678,13 +679,11 @@ TEST_F(ServiceWorkerStorageTest, DisabledStorage) {
EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
GetUserDataForAllRegistrations(kUserDataKey, &data_list_out));
- EXPECT_FALSE(
- storage()->OriginHasForeignFetchRegistrations(kScope.GetOrigin()));
-
// Next available ids should be invalid.
EXPECT_EQ(blink::mojom::kInvalidServiceWorkerRegistrationId,
storage()->NewRegistrationId());
- EXPECT_EQ(kInvalidServiceWorkerVersionId, storage()->NewVersionId());
+ EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
+ storage()->NewVersionId());
EXPECT_EQ(kInvalidServiceWorkerResourceId, storage()->NewRegistrationId());
}
@@ -697,8 +696,6 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
const int64_t kResource2Size = 51;
const int64_t kRegistrationId = 0;
const int64_t kVersionId = 0;
- const GURL kForeignFetchScope("http://www.test.not/scope/ff/");
- const url::Origin kForeignFetchOrigin(GURL("https://example.com/"));
const base::Time kToday = base::Time::Now();
const base::Time kYesterday = kToday - base::TimeDelta::FromDays(1);
std::set<uint32_t> used_features = {124, 901, 1019};
@@ -734,10 +731,6 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
live_version->SetStatus(ServiceWorkerVersion::INSTALLED);
live_version->script_cache_map()->SetResources(resources);
- live_version->set_foreign_fetch_scopes(
- std::vector<GURL>(1, kForeignFetchScope));
- live_version->set_foreign_fetch_origins(
- std::vector<url::Origin>(1, kForeignFetchOrigin));
live_version->set_used_features(used_features);
live_registration->SetWaitingVersion(live_version);
live_registration->set_last_update_check(kYesterday);
@@ -754,13 +747,13 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
found_registration->resources_total_size_bytes());
EXPECT_EQ(used_features,
found_registration->waiting_version()->used_features());
- found_registration = NULL;
+ found_registration = nullptr;
// But FindRegistrationForPattern is always async.
EXPECT_EQ(SERVICE_WORKER_OK,
FindRegistrationForPattern(kScope, &found_registration));
EXPECT_EQ(live_registration, found_registration);
- found_registration = NULL;
+ found_registration = nullptr;
// Can be found by id too.
EXPECT_EQ(SERVICE_WORKER_OK,
@@ -769,7 +762,7 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
ASSERT_TRUE(found_registration.get());
EXPECT_EQ(kRegistrationId, found_registration->id());
EXPECT_EQ(live_registration, found_registration);
- found_registration = NULL;
+ found_registration = nullptr;
// Can be found by just the id too.
EXPECT_EQ(SERVICE_WORKER_OK,
@@ -777,10 +770,10 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
ASSERT_TRUE(found_registration.get());
EXPECT_EQ(kRegistrationId, found_registration->id());
EXPECT_EQ(live_registration, found_registration);
- found_registration = NULL;
+ found_registration = nullptr;
// Drop the live registration, but keep the version live.
- live_registration = NULL;
+ live_registration = nullptr;
// Now FindRegistrationForDocument should be async.
EXPECT_EQ(SERVICE_WORKER_OK,
@@ -814,10 +807,10 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
&registrations_for_origin));
EXPECT_TRUE(registrations_for_origin.empty());
- found_registration = NULL;
+ found_registration = nullptr;
// Drop the live version too.
- live_version = NULL;
+ live_version = nullptr;
// And FindRegistrationForPattern is always async.
EXPECT_EQ(SERVICE_WORKER_OK,
@@ -830,27 +823,18 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
EXPECT_EQ(kYesterday, found_registration->last_update_check());
EXPECT_EQ(ServiceWorkerVersion::INSTALLED,
found_registration->waiting_version()->status());
- EXPECT_EQ(
- 1u, found_registration->waiting_version()->foreign_fetch_scopes().size());
- EXPECT_EQ(kForeignFetchScope,
- found_registration->waiting_version()->foreign_fetch_scopes()[0]);
- EXPECT_EQ(
- 1u,
- found_registration->waiting_version()->foreign_fetch_origins().size());
- EXPECT_EQ(kForeignFetchOrigin,
- found_registration->waiting_version()->foreign_fetch_origins()[0]);
// Update to active and update the last check time.
scoped_refptr<ServiceWorkerVersion> temp_version =
found_registration->waiting_version();
temp_version->SetStatus(ServiceWorkerVersion::ACTIVATED);
found_registration->SetActiveVersion(temp_version);
- temp_version = NULL;
+ temp_version = nullptr;
EXPECT_EQ(SERVICE_WORKER_OK, UpdateToActiveState(found_registration));
found_registration->set_last_update_check(kToday);
UpdateLastUpdateCheckTime(found_registration.get());
- found_registration = NULL;
+ found_registration = nullptr;
// Trying to update a unstored registration to active should fail.
scoped_refptr<ServiceWorkerRegistration> unstored_registration =
@@ -859,7 +843,7 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
kRegistrationId + 1, context()->AsWeakPtr());
EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
UpdateToActiveState(unstored_registration));
- unstored_registration = NULL;
+ unstored_registration = nullptr;
// The Find methods should return a registration with an active version
// and the expected update time.
@@ -955,22 +939,22 @@ TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) {
FindRegistrationForId(
kRegistrationId, kScope.GetOrigin(), &found_registration));
EXPECT_EQ(live_registration, found_registration);
- found_registration = NULL;
+ found_registration = nullptr;
EXPECT_EQ(SERVICE_WORKER_OK,
FindRegistrationForIdOnly(kRegistrationId, &found_registration));
EXPECT_EQ(live_registration, found_registration);
- found_registration = NULL;
+ found_registration = nullptr;
EXPECT_EQ(SERVICE_WORKER_OK,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
EXPECT_EQ(live_registration, found_registration);
- found_registration = NULL;
+ found_registration = nullptr;
EXPECT_EQ(SERVICE_WORKER_OK,
FindRegistrationForPattern(kScope, &found_registration));
EXPECT_EQ(live_registration, found_registration);
- found_registration = NULL;
+ found_registration = nullptr;
EXPECT_EQ(SERVICE_WORKER_OK, GetAllRegistrationsInfos(&all_registrations));
EXPECT_EQ(1u, all_registrations.size());
@@ -989,8 +973,8 @@ TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) {
EXPECT_TRUE(registrations_for_origin.empty());
// Notify storage of installation no longer happening.
- storage()->NotifyDoneInstallingRegistration(
- live_registration.get(), NULL, SERVICE_WORKER_OK);
+ storage()->NotifyDoneInstallingRegistration(live_registration.get(), nullptr,
+ SERVICE_WORKER_OK);
// Once again, should not be findable.
EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
@@ -1364,8 +1348,8 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) {
ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
std::set<int64_t> verify_ids;
- registration_->SetWaitingVersion(NULL);
- registration_ = NULL;
+ registration_->SetWaitingVersion(nullptr);
+ registration_ = nullptr;
// Deleting the registration should result in the resources being added to the
// purgeable list and then doomed in the disk cache and removed from that
@@ -1475,7 +1459,7 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_ActiveVersion) {
TEST_F(ServiceWorkerResourceStorageDiskTest, CleanupOnRestart) {
// Promote the worker to active and add a controllee.
registration_->SetActiveVersion(registration_->waiting_version());
- registration_->SetWaitingVersion(NULL);
+ registration_->SetWaitingVersion(nullptr);
storage()->UpdateToActiveState(
registration_.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
ServiceWorkerRemoteProviderEndpoint remote_endpoint;
@@ -1722,7 +1706,7 @@ TEST_F(ServiceWorkerStorageTest, FindRegistration_LongestScopeMatch) {
EXPECT_EQ(SERVICE_WORKER_OK,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
EXPECT_EQ(live_registration2, found_registration);
- found_registration = NULL;
+ found_registration = nullptr;
// Store registrations.
EXPECT_EQ(SERVICE_WORKER_OK,
@@ -1736,12 +1720,12 @@ TEST_F(ServiceWorkerStorageTest, FindRegistration_LongestScopeMatch) {
live_registration3->waiting_version()));
// Notify storage of installations no longer happening.
- storage()->NotifyDoneInstallingRegistration(
- live_registration1.get(), NULL, SERVICE_WORKER_OK);
- storage()->NotifyDoneInstallingRegistration(
- live_registration2.get(), NULL, SERVICE_WORKER_OK);
- storage()->NotifyDoneInstallingRegistration(
- live_registration3.get(), NULL, SERVICE_WORKER_OK);
+ storage()->NotifyDoneInstallingRegistration(live_registration1.get(), nullptr,
+ SERVICE_WORKER_OK);
+ storage()->NotifyDoneInstallingRegistration(live_registration2.get(), nullptr,
+ SERVICE_WORKER_OK);
+ storage()->NotifyDoneInstallingRegistration(live_registration3.get(), nullptr,
+ SERVICE_WORKER_OK);
// Find a registration among installed ones.
EXPECT_EQ(SERVICE_WORKER_OK,
@@ -1759,83 +1743,6 @@ class ServiceWorkerStorageDiskTest : public ServiceWorkerStorageTest {
}
};
-TEST_F(ServiceWorkerStorageDiskTest, OriginHasForeignFetchRegistrations) {
- LazyInitialize();
-
- // Registration 1 for http://www.example.com
- const GURL kScope1("http://www.example.com/scope/");
- const GURL kScript1("http://www.example.com/script1.js");
- scoped_refptr<ServiceWorkerRegistration> live_registration1 =
- CreateLiveRegistrationAndVersion(kScope1, kScript1);
- const int64_t kRegistrationId1 = live_registration1->id();
- ServiceWorkerVersion* live_version1 = live_registration1->waiting_version();
- live_version1->set_foreign_fetch_scopes(std::vector<GURL>(1, kScope1));
-
- // Registration 2 for http://www.example.com
- const GURL kScope2("http://www.example.com/scope/foo");
- const GURL kScript2("http://www.example.com/script2.js");
- scoped_refptr<ServiceWorkerRegistration> live_registration2 =
- CreateLiveRegistrationAndVersion(kScope2, kScript2);
- const int64_t kRegistrationId2 = live_registration2->id();
- ServiceWorkerVersion* live_version2 = live_registration2->waiting_version();
- live_version2->set_foreign_fetch_scopes(std::vector<GURL>(1, kScope2));
-
- // Registration for http://www.test.com
- const GURL kScope3("http://www.test.com/scope/foobar");
- const GURL kScript3("http://www.test.com/script3.js");
- scoped_refptr<ServiceWorkerRegistration> live_registration3 =
- CreateLiveRegistrationAndVersion(kScope3, kScript3);
- ServiceWorkerVersion* live_version3 = live_registration3->waiting_version();
-
- // Neither origin should have registrations before they are stored.
- const GURL kOrigin1 = kScope1.GetOrigin();
- const GURL kOrigin2 = kScope3.GetOrigin();
- EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin1));
- EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin2));
-
- // Store all registrations.
- EXPECT_EQ(SERVICE_WORKER_OK,
- StoreRegistration(live_registration1, live_version1));
- EXPECT_EQ(SERVICE_WORKER_OK,
- StoreRegistration(live_registration2, live_version2));
- EXPECT_EQ(SERVICE_WORKER_OK,
- StoreRegistration(live_registration3, live_version3));
-
- // Now first origin should have foreign fetch registrations, second doesn't.
- EXPECT_TRUE(storage()->OriginHasForeignFetchRegistrations(kOrigin1));
- EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin2));
-
- // Remove one registration at first origin.
- EXPECT_EQ(SERVICE_WORKER_OK,
- DeleteRegistration(kRegistrationId1, kScope1.GetOrigin()));
-
- // First origin should still have a registration left.
- EXPECT_TRUE(storage()->OriginHasForeignFetchRegistrations(kOrigin1));
- EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin2));
-
- // Simulate browser shutdown and restart.
- live_registration1 = nullptr;
- live_version1 = nullptr;
- live_registration2 = nullptr;
- live_version2 = nullptr;
- live_registration3 = nullptr;
- live_version3 = nullptr;
- InitializeTestHelper();
- LazyInitialize();
-
- // First origin should still have a registration left.
- EXPECT_TRUE(storage()->OriginHasForeignFetchRegistrations(kOrigin1));
- EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin2));
-
- // Remove other registration at first origin.
- EXPECT_EQ(SERVICE_WORKER_OK,
- DeleteRegistration(kRegistrationId2, kScope2.GetOrigin()));
-
- // No foreign fetch registrations remain.
- EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin1));
- EXPECT_FALSE(storage()->OriginHasForeignFetchRegistrations(kOrigin2));
-}
-
TEST_F(ServiceWorkerStorageTest, OriginTrialsAbsentEntryAndEmptyEntry) {
const GURL origin1("http://www1.example.com");
const GURL scope1("http://www1.example.com/foo/");
@@ -2033,12 +1940,12 @@ TEST_F(ServiceWorkerStorageTest, AbsentNavigationPreloadState) {
scoped_refptr<ServiceWorkerRegistration> found_registration;
EXPECT_EQ(SERVICE_WORKER_OK,
FindRegistrationForDocument(scope1, &found_registration));
- const NavigationPreloadState& registration_state =
+ const blink::mojom::NavigationPreloadState& registration_state =
found_registration->navigation_preload_state();
EXPECT_FALSE(registration_state.enabled);
EXPECT_EQ("true", registration_state.header);
ASSERT_TRUE(found_registration->active_version());
- const NavigationPreloadState& state =
+ const blink::mojom::NavigationPreloadState& state =
found_registration->active_version()->navigation_preload_state();
EXPECT_FALSE(state.enabled);
EXPECT_EQ("true", state.header);
@@ -2119,12 +2026,12 @@ TEST_F(ServiceWorkerStorageDiskTest, DisabledNavigationPreloadState) {
scoped_refptr<ServiceWorkerRegistration> found_registration;
EXPECT_EQ(SERVICE_WORKER_OK,
FindRegistrationForDocument(kScope, &found_registration));
- const NavigationPreloadState& registration_state =
+ const blink::mojom::NavigationPreloadState& registration_state =
found_registration->navigation_preload_state();
EXPECT_FALSE(registration_state.enabled);
EXPECT_EQ("true", registration_state.header);
ASSERT_TRUE(found_registration->active_version());
- const NavigationPreloadState& state =
+ const blink::mojom::NavigationPreloadState& state =
found_registration->active_version()->navigation_preload_state();
EXPECT_FALSE(state.enabled);
EXPECT_EQ("true", state.header);
@@ -2156,12 +2063,12 @@ TEST_F(ServiceWorkerStorageDiskTest, EnabledNavigationPreloadState) {
scoped_refptr<ServiceWorkerRegistration> found_registration;
EXPECT_EQ(SERVICE_WORKER_OK,
FindRegistrationForDocument(kScope, &found_registration));
- const NavigationPreloadState& registration_state =
+ const blink::mojom::NavigationPreloadState& registration_state =
found_registration->navigation_preload_state();
EXPECT_TRUE(registration_state.enabled);
EXPECT_EQ(kHeaderValue, registration_state.header);
ASSERT_TRUE(found_registration->active_version());
- const NavigationPreloadState& state =
+ const blink::mojom::NavigationPreloadState& state =
found_registration->active_version()->navigation_preload_state();
EXPECT_TRUE(state.enabled);
EXPECT_EQ(kHeaderValue, state.header);
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 a69a338e7cc..4d05a4374ad 100644
--- a/chromium/content/browser/service_worker/service_worker_test_utils.cc
+++ b/chromium/content/browser/service_worker/service_worker_test_utils.cc
@@ -4,15 +4,83 @@
#include "content/browser/service_worker/service_worker_test_utils.h"
+#include <memory>
#include <utility>
+#include "base/barrier_closure.h"
+#include "base/run_loop.h"
+#include "base/time/time.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_database.h"
+#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/service_worker/service_worker_dispatcher_host.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/browser/service_worker/service_worker_storage.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/public/common/child_process_host.h"
+#include "net/base/io_buffer.h"
+#include "net/base/test_completion_callback.h"
+#include "net/http/http_response_info.h"
namespace content {
+namespace {
+
+void OnWriteBodyInfoToDiskCache(
+ std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ const std::string& body,
+ base::OnceClosure callback,
+ int result) {
+ EXPECT_GE(result, 0);
+ scoped_refptr<net::IOBuffer> body_buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(body);
+ ServiceWorkerResponseWriter* writer_rawptr = writer.get();
+ writer_rawptr->WriteData(
+ body_buffer.get(), body.size(),
+ base::BindOnce(
+ [](std::unique_ptr<ServiceWorkerResponseWriter> /* unused */,
+ base::OnceClosure callback, int expected, int result) {
+ EXPECT_EQ(expected, result);
+ std::move(callback).Run();
+ },
+ std::move(writer), std::move(callback), body.size()));
+}
+
+void WriteBodyToDiskCache(std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ std::unique_ptr<net::HttpResponseInfo> info,
+ const std::string& body,
+ base::OnceClosure callback) {
+ scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
+ base::MakeRefCounted<HttpResponseInfoIOBuffer>(info.release());
+ info_buffer->response_data_size = body.size();
+ ServiceWorkerResponseWriter* writer_rawptr = writer.get();
+ writer_rawptr->WriteInfo(
+ info_buffer.get(),
+ base::BindOnce(&OnWriteBodyInfoToDiskCache, std::move(writer), body,
+ std::move(callback)));
+}
+
+void WriteMetaDataToDiskCache(
+ std::unique_ptr<ServiceWorkerResponseMetadataWriter> writer,
+ const std::string& meta_data,
+ base::OnceClosure callback) {
+ scoped_refptr<net::IOBuffer> meta_data_buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(meta_data);
+ ServiceWorkerResponseMetadataWriter* writer_rawptr = writer.get();
+ writer_rawptr->WriteMetadata(
+ meta_data_buffer.get(), meta_data.size(),
+ base::Bind(
+ [](std::unique_ptr<ServiceWorkerResponseMetadataWriter> /* unused */,
+ base::OnceClosure callback, int expected, int result) {
+ EXPECT_EQ(expected, result);
+ std::move(callback).Run();
+ },
+ base::Passed(&writer), base::Passed(&callback), meta_data.size()));
+}
+
+} // namespace
+
ServiceWorkerRemoteProviderEndpoint::ServiceWorkerRemoteProviderEndpoint() {}
ServiceWorkerRemoteProviderEndpoint::ServiceWorkerRemoteProviderEndpoint(
ServiceWorkerRemoteProviderEndpoint&& other)
@@ -24,9 +92,9 @@ ServiceWorkerRemoteProviderEndpoint::~ServiceWorkerRemoteProviderEndpoint() {}
void ServiceWorkerRemoteProviderEndpoint::BindWithProviderHostInfo(
content::ServiceWorkerProviderHostInfo* info) {
mojom::ServiceWorkerContainerAssociatedPtr client_ptr;
- client_request_ = mojo::MakeIsolatedRequest(&client_ptr);
+ client_request_ = mojo::MakeRequestAssociatedWithDedicatedPipe(&client_ptr);
info->client_ptr_info = client_ptr.PassInterface();
- info->host_request = mojo::MakeIsolatedRequest(&host_ptr_);
+ info->host_request = mojo::MakeRequestAssociatedWithDedicatedPipe(&host_ptr_);
}
void ServiceWorkerRemoteProviderEndpoint::BindWithProviderInfo(
@@ -34,6 +102,10 @@ void ServiceWorkerRemoteProviderEndpoint::BindWithProviderInfo(
client_request_ = std::move(info->client_request);
host_ptr_.Bind(std::move(info->host_ptr_info));
registration_object_info_ = std::move(info->registration);
+ // To enable the caller end point to make calls safely with no need to pass
+ // |registration_object_info_->request| through a message pipe endpoint.
+ mojo::AssociateWithDisconnectedPipe(
+ registration_object_info_->request.PassHandle());
}
std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostForWindow(
@@ -42,9 +114,10 @@ std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostForWindow(
bool is_parent_frame_secure,
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerRemoteProviderEndpoint* output_endpoint) {
- ServiceWorkerProviderHostInfo info(provider_id, 1 /* route_id */,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- is_parent_frame_secure);
+ ServiceWorkerProviderHostInfo info(
+ provider_id, 1 /* route_id */,
+ blink::mojom::ServiceWorkerProviderType::kForWindow,
+ is_parent_frame_secure);
output_endpoint->BindWithProviderHostInfo(&info);
return ServiceWorkerProviderHost::Create(process_id, std::move(info),
std::move(context), nullptr);
@@ -59,7 +132,8 @@ CreateProviderHostForServiceWorkerContext(
ServiceWorkerRemoteProviderEndpoint* output_endpoint) {
ServiceWorkerProviderHostInfo info(
kInvalidServiceWorkerProviderId, MSG_ROUTING_NONE,
- SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, is_parent_frame_secure);
+ blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
+ is_parent_frame_secure);
std::unique_ptr<ServiceWorkerProviderHost> host =
ServiceWorkerProviderHost::PreCreateForController(std::move(context));
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
@@ -75,12 +149,85 @@ std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostWithDispatcherHost(
int route_id,
ServiceWorkerDispatcherHost* dispatcher_host,
ServiceWorkerRemoteProviderEndpoint* output_endpoint) {
- ServiceWorkerProviderHostInfo info(provider_id, route_id,
- SERVICE_WORKER_PROVIDER_FOR_WINDOW, true);
+ ServiceWorkerProviderHostInfo info(
+ provider_id, route_id,
+ blink::mojom::ServiceWorkerProviderType::kForWindow, true);
output_endpoint->BindWithProviderHostInfo(&info);
return ServiceWorkerProviderHost::Create(process_id, std::move(info),
std::move(context),
dispatcher_host->AsWeakPtr());
}
+ServiceWorkerDatabase::ResourceRecord WriteToDiskCacheSync(
+ ServiceWorkerStorage* storage,
+ const GURL& script_url,
+ int64_t resource_id,
+ const std::vector<std::pair<std::string, std::string>>& headers,
+ const std::string& body,
+ const std::string& meta_data) {
+ base::RunLoop loop;
+ ServiceWorkerDatabase::ResourceRecord record =
+ WriteToDiskCacheAsync(storage, script_url, resource_id, headers, body,
+ meta_data, loop.QuitClosure());
+ loop.Run();
+ return record;
+}
+
+ServiceWorkerDatabase::ResourceRecord
+WriteToDiskCacheWithCustomResponseInfoSync(
+ ServiceWorkerStorage* storage,
+ const GURL& script_url,
+ int64_t resource_id,
+ std::unique_ptr<net::HttpResponseInfo> http_info,
+ const std::string& body,
+ const std::string& meta_data) {
+ base::RunLoop loop;
+ ServiceWorkerDatabase::ResourceRecord record =
+ WriteToDiskCacheWithCustomResponseInfoAsync(
+ storage, script_url, resource_id, std::move(http_info), body,
+ meta_data, loop.QuitClosure());
+ loop.Run();
+ return record;
+}
+
+ServiceWorkerDatabase::ResourceRecord WriteToDiskCacheAsync(
+ ServiceWorkerStorage* storage,
+ const GURL& script_url,
+ int64_t resource_id,
+ const std::vector<std::pair<std::string, std::string>>& headers,
+ const std::string& body,
+ const std::string& meta_data,
+ base::OnceClosure callback) {
+ std::unique_ptr<net::HttpResponseInfo> info =
+ std::make_unique<net::HttpResponseInfo>();
+ info->request_time = base::Time::Now();
+ info->response_time = base::Time::Now();
+ info->headers =
+ base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.0 200 OK\0\0");
+ for (const auto& header : headers)
+ info->headers->AddHeader(header.first + ": " + header.second);
+ return WriteToDiskCacheWithCustomResponseInfoAsync(
+ storage, script_url, resource_id, std::move(info), body, meta_data,
+ std::move(callback));
+}
+
+ServiceWorkerDatabase::ResourceRecord
+WriteToDiskCacheWithCustomResponseInfoAsync(
+ ServiceWorkerStorage* storage,
+ const GURL& script_url,
+ int64_t resource_id,
+ std::unique_ptr<net::HttpResponseInfo> http_info,
+ const std::string& body,
+ const std::string& meta_data,
+ base::OnceClosure callback) {
+ base::RepeatingClosure barrier = base::BarrierClosure(2, std::move(callback));
+ auto body_writer = storage->CreateResponseWriter(resource_id);
+ WriteBodyToDiskCache(std::move(body_writer), std::move(http_info), body,
+ barrier);
+ auto metadata_writer = storage->CreateResponseMetadataWriter(resource_id);
+ WriteMetaDataToDiskCache(std::move(metadata_writer), meta_data, barrier);
+ return ServiceWorkerDatabase::ResourceRecord(resource_id, script_url,
+ body.size());
+}
+
} // 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 377da430ccf..eb67a8428cb 100644
--- a/chromium/content/browser/service_worker/service_worker_test_utils.h
+++ b/chromium/content/browser/service_worker/service_worker_test_utils.h
@@ -11,17 +11,26 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/memory/weak_ptr.h"
+#include "content/browser/service_worker/service_worker_database.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+namespace net {
+
+class HttpResponseInfo;
+
+} // namespace net
+
namespace content {
class ServiceWorkerContextCore;
class ServiceWorkerDispatcherHost;
class ServiceWorkerProviderHost;
+class ServiceWorkerRegistration;
+class ServiceWorkerStorage;
class ServiceWorkerVersion;
struct ServiceWorkerProviderHostInfo;
@@ -108,6 +117,59 @@ std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostWithDispatcherHost(
ServiceWorkerDispatcherHost* dispatcher_host,
ServiceWorkerRemoteProviderEndpoint* output_endpoint);
+// Writes the script down to |storage| synchronously. This should not be used in
+// base::RunLoop since base::RunLoop is used internally to wait for completing
+// all of tasks. If it's in another base::RunLoop, consider to use
+// WriteToDiskCacheAsync().
+ServiceWorkerDatabase::ResourceRecord WriteToDiskCacheSync(
+ ServiceWorkerStorage* storage,
+ const GURL& script_url,
+ int64_t resource_id,
+ const std::vector<std::pair<std::string, std::string>>& headers,
+ const std::string& body,
+ const std::string& meta_data);
+
+// Writes the script with custom net::HttpResponseInfo down to |storage|
+// synchronously. This should not be used in base::RunLoop since base::RunLoop
+// is used internally to wait for completing all of tasks. If it's in another
+// base::RunLoop, consider to use WriteToDiskCacheWithCustomResponseInfoAsync().
+ServiceWorkerDatabase::ResourceRecord
+WriteToDiskCacheWithCustomResponseInfoSync(
+ ServiceWorkerStorage* storage,
+ const GURL& script_url,
+ int64_t resource_id,
+ std::unique_ptr<net::HttpResponseInfo> http_info,
+ const std::string& body,
+ const std::string& meta_data);
+
+// Writes the script down to |storage| asynchronously. When completing tasks,
+// |callback| will be called. You must wait for |callback| instead of
+// base::RunUntilIdle because wiriting to the storage might happen on another
+// thread and base::RunLoop could get idle before writes has not finished yet.
+ServiceWorkerDatabase::ResourceRecord WriteToDiskCacheAsync(
+ ServiceWorkerStorage* storage,
+ const GURL& script_url,
+ int64_t resource_id,
+ const std::vector<std::pair<std::string, std::string>>& headers,
+ const std::string& body,
+ const std::string& meta_data,
+ base::OnceClosure callback);
+
+// Writes the script with custom net::HttpResponseInfo down to |storage|
+// asynchronously. When completing tasks, |callback| will be called. You must
+// wait for |callback| instead of base::RunUntilIdle because wiriting to the
+// storage might happen on another thread and base::RunLoop could get idle
+// before writes has not finished yet.
+ServiceWorkerDatabase::ResourceRecord
+WriteToDiskCacheWithCustomResponseInfoAsync(
+ ServiceWorkerStorage* storage,
+ const GURL& script_url,
+ int64_t resource_id,
+ std::unique_ptr<net::HttpResponseInfo> http_info,
+ const std::string& body,
+ const std::string& meta_data,
+ base::OnceClosure callback);
+
} // namespace content
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_TEST_UTILS_H_
diff --git a/chromium/content/browser/service_worker/service_worker_url_loader_job.cc b/chromium/content/browser/service_worker/service_worker_url_loader_job.cc
index ed6fde6b71b..5c359193425 100644
--- a/chromium/content/browser/service_worker/service_worker_url_loader_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_url_loader_job.cc
@@ -4,10 +4,10 @@
#include "content/browser/service_worker/service_worker_url_loader_job.h"
-#include "base/guid.h"
+#include <utility>
+
#include "base/optional.h"
#include "content/browser/blob_storage/blob_url_loader_factory.h"
-#include "content/browser/service_worker/service_worker_fetch_dispatcher.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"
@@ -16,7 +16,7 @@
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
-#include "storage/browser/blob/blob_data_builder.h"
+#include "services/network/public/interfaces/fetch_api.mojom.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_impl.h"
#include "storage/browser/blob/blob_reader.h"
@@ -24,38 +24,6 @@
namespace content {
-namespace {
-
-base::Optional<net::RedirectInfo> ComputeRedirectInfo(
- const ResourceRequest& original_request,
- const ResourceResponseHead& response_head,
- bool token_binding_negotiated) {
- std::string new_location;
- if (!response_head.headers->IsRedirect(&new_location))
- return base::nullopt;
-
- std::string referrer_string;
- net::URLRequest::ReferrerPolicy referrer_policy;
- Referrer::ComputeReferrerInfo(
- &referrer_string, &referrer_policy,
- Referrer(original_request.referrer, original_request.referrer_policy));
-
- // If the request is a MAIN_FRAME request, the first-party URL gets
- // updated on redirects.
- const net::URLRequest::FirstPartyURLPolicy first_party_url_policy =
- original_request.resource_type == RESOURCE_TYPE_MAIN_FRAME
- ? net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT
- : net::URLRequest::NEVER_CHANGE_FIRST_PARTY_URL;
- return net::RedirectInfo::ComputeRedirectInfo(
- original_request.method, original_request.url,
- original_request.site_for_cookies, first_party_url_policy,
- referrer_policy, referrer_string, response_head.headers.get(),
- response_head.headers->response_code(),
- original_request.url.Resolve(new_location), token_binding_negotiated);
-}
-
-} // namespace
-
// This class waits for completion of a stream response from the service worker.
// It calls ServiceWorkerURLLoader::CommitComplete() upon completion of the
// response.
@@ -107,8 +75,11 @@ ServiceWorkerURLLoaderJob::ServiceWorkerURLLoaderJob(
blob_client_binding_(this),
binding_(this),
weak_factory_(this) {
- DCHECK_EQ(FETCH_REQUEST_MODE_NAVIGATE, resource_request_.fetch_request_mode);
- DCHECK_EQ(FETCH_CREDENTIALS_MODE_INCLUDE,
+ DCHECK(
+ ServiceWorkerUtils::IsMainResourceType(resource_request.resource_type));
+ DCHECK_EQ(network::mojom::FetchRequestMode::kNavigate,
+ resource_request_.fetch_request_mode);
+ DCHECK_EQ(network::mojom::FetchCredentialsMode::kInclude,
resource_request_.fetch_credentials_mode);
DCHECK_EQ(FetchRedirectMode::MANUAL_MODE,
resource_request_.fetch_redirect_mode);
@@ -119,7 +90,7 @@ ServiceWorkerURLLoaderJob::ServiceWorkerURLLoaderJob(
ServiceWorkerURLLoaderJob::~ServiceWorkerURLLoaderJob() {}
void ServiceWorkerURLLoaderJob::FallbackToNetwork() {
- response_type_ = FALLBACK_TO_NETWORK;
+ response_type_ = ResponseType::FALLBACK_TO_NETWORK;
// 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.
@@ -134,12 +105,12 @@ void ServiceWorkerURLLoaderJob::FallbackToNetworkOrRenderer() {
}
void ServiceWorkerURLLoaderJob::ForwardToServiceWorker() {
- response_type_ = FORWARD_TO_SERVICE_WORKER;
+ response_type_ = ResponseType::FORWARD_TO_SERVICE_WORKER;
StartRequest();
}
bool ServiceWorkerURLLoaderJob::ShouldFallbackToNetwork() {
- return response_type_ == FALLBACK_TO_NETWORK;
+ return response_type_ == ResponseType::FALLBACK_TO_NETWORK;
}
ui::PageTransition ServiceWorkerURLLoaderJob::GetPageTransition() {
@@ -164,7 +135,7 @@ void ServiceWorkerURLLoaderJob::Cancel() {
stream_waiter_.reset();
url_loader_client_->OnComplete(
- ResourceRequestCompletionStatus(net::ERR_ABORTED));
+ network::URLLoaderCompletionStatus(net::ERR_ABORTED));
url_loader_client_.reset();
}
@@ -173,7 +144,7 @@ bool ServiceWorkerURLLoaderJob::WasCanceled() const {
}
void ServiceWorkerURLLoaderJob::StartRequest() {
- DCHECK_EQ(FORWARD_TO_SERVICE_WORKER, response_type_);
+ DCHECK_EQ(ResponseType::FORWARD_TO_SERVICE_WORKER, response_type_);
DCHECK_EQ(Status::kNotStarted, status_);
status_ = Status::kStarted;
@@ -186,25 +157,17 @@ void ServiceWorkerURLLoaderJob::StartRequest() {
return;
}
- // Create the URL request to pass to the fetch event.
- std::unique_ptr<ServiceWorkerFetchRequest> fetch_request =
- ServiceWorkerLoaderHelpers::CreateFetchRequest(resource_request_);
- // TODO(emim): We should create an error when no blob_storage_context_, but
- // for consistency with StartResponse(), just ignore for now.
- if (resource_request_.request_body.get() && blob_storage_context_) {
- DCHECK(features::IsMojoBlobsEnabled());
- fetch_request->blob = CreateRequestBodyBlob();
- }
// Dispatch the fetch event.
fetch_dispatcher_ = std::make_unique<ServiceWorkerFetchDispatcher>(
- std::move(fetch_request), active_worker, resource_request_.resource_type,
- base::nullopt, net::NetLogWithSource() /* TODO(scottmg): net log? */,
- base::Bind(&ServiceWorkerURLLoaderJob::DidPrepareFetchEvent,
- weak_factory_.GetWeakPtr(),
- base::WrapRefCounted(active_worker)),
- base::Bind(&ServiceWorkerURLLoaderJob::DidDispatchFetchEvent,
- weak_factory_.GetWeakPtr()));
+ std::make_unique<ResourceRequest>(resource_request_), active_worker,
+ base::nullopt /* timeout */,
+ net::NetLogWithSource() /* TODO(scottmg): net log? */,
+ base::BindOnce(&ServiceWorkerURLLoaderJob::DidPrepareFetchEvent,
+ weak_factory_.GetWeakPtr(),
+ base::WrapRefCounted(active_worker)),
+ base::BindOnce(&ServiceWorkerURLLoaderJob::DidDispatchFetchEvent,
+ weak_factory_.GetWeakPtr()));
did_navigation_preload_ =
fetch_dispatcher_->MaybeStartNavigationPreloadWithURLLoader(
resource_request_, url_loader_factory_getter_.get(),
@@ -215,24 +178,6 @@ void ServiceWorkerURLLoaderJob::StartRequest() {
fetch_dispatcher_->Run();
}
-scoped_refptr<storage::BlobHandle>
-ServiceWorkerURLLoaderJob::CreateRequestBodyBlob() {
- storage::BlobDataBuilder blob_builder(base::GenerateGUID());
- // TODO(emim): Resolve file sizes before calling AppendIPCDataElement().
- for (const auto& element : (*resource_request_.request_body->elements())) {
- blob_builder.AppendIPCDataElement(element);
- }
-
- std::unique_ptr<storage::BlobDataHandle> request_body_blob_data_handle =
- blob_storage_context_->AddFinishedBlob(&blob_builder);
- // TODO(emim): Return a network error when the blob is broken.
- CHECK(!request_body_blob_data_handle->IsBroken());
- storage::mojom::BlobPtr blob_ptr;
- storage::BlobImpl::Create(std::move(request_body_blob_data_handle),
- MakeRequest(&blob_ptr));
- return base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr));
-}
-
void ServiceWorkerURLLoaderJob::CommitResponseHeaders() {
DCHECK_EQ(Status::kStarted, status_);
DCHECK(url_loader_client_.is_bound());
@@ -249,7 +194,8 @@ void ServiceWorkerURLLoaderJob::CommitCompleted(int error_code) {
// |stream_waiter_| calls this when done.
stream_waiter_.reset();
- url_loader_client_->OnComplete(ResourceRequestCompletionStatus(error_code));
+ url_loader_client_->OnComplete(
+ network::URLLoaderCompletionStatus(error_code));
}
void ServiceWorkerURLLoaderJob::ReturnNetworkError() {
@@ -267,11 +213,11 @@ void ServiceWorkerURLLoaderJob::DidPrepareFetchEvent(
void ServiceWorkerURLLoaderJob::DidDispatchFetchEvent(
ServiceWorkerStatusCode status,
- ServiceWorkerFetchEventResult fetch_result,
+ ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob,
- const scoped_refptr<ServiceWorkerVersion>& version) {
+ blink::mojom::BlobPtr body_as_blob,
+ scoped_refptr<ServiceWorkerVersion> version) {
ServiceWorkerMetrics::URLRequestJobResult result =
ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
if (!delegate_->RequestStillValid(&result)) {
@@ -285,13 +231,15 @@ void ServiceWorkerURLLoaderJob::DidDispatchFetchEvent(
return;
}
- if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) {
+ if (fetch_result ==
+ ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback) {
// TODO(kinuko): Check if this needs to fallback to the renderer.
FallbackToNetwork();
return;
}
- DCHECK_EQ(fetch_result, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE);
+ DCHECK_EQ(fetch_result,
+ ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse);
// A response with status code 0 is Blink telling us to respond with
// network error.
@@ -306,10 +254,8 @@ void ServiceWorkerURLLoaderJob::DidDispatchFetchEvent(
// ServiceWorker, we have to check the security level of the responses.
const net::HttpResponseInfo* main_script_http_info =
version->GetMainScriptHttpResponseInfo();
- // TODO(kinuko)
- // Fix this here.
- if (main_script_http_info)
- ssl_info_ = main_script_http_info->ssl_info;
+ DCHECK(main_script_http_info);
+ ssl_info_ = main_script_http_info->ssl_info;
std::move(loader_callback_)
.Run(base::BindOnce(&ServiceWorkerURLLoaderJob::StartResponse,
@@ -321,7 +267,7 @@ void ServiceWorkerURLLoaderJob::StartResponse(
const ServiceWorkerResponse& response,
scoped_refptr<ServiceWorkerVersion> version,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob,
+ blink::mojom::BlobPtr body_as_blob,
mojom::URLLoaderRequest request,
mojom::URLLoaderClientPtr client) {
DCHECK(!binding_.is_bound());
@@ -343,11 +289,14 @@ void ServiceWorkerURLLoaderJob::StartResponse(
// Handle a redirect response. ComputeRedirectInfo returns non-null redirect
// info if the given response is a redirect.
base::Optional<net::RedirectInfo> redirect_info =
- ComputeRedirectInfo(resource_request_, response_head_,
- ssl_info_ && ssl_info_->token_binding_negotiated);
+ ServiceWorkerLoaderHelpers::ComputeRedirectInfo(
+ resource_request_, response_head_,
+ ssl_info_ && ssl_info_->token_binding_negotiated);
if (redirect_info) {
response_head_.encoded_data_length = 0;
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;
return;
}
@@ -376,7 +325,7 @@ void ServiceWorkerURLLoaderJob::StartResponse(
blob_client_binding_.Bind(mojo::MakeRequest(&client));
BlobURLLoaderFactory::CreateLoaderAndStart(
std::move(request), resource_request_, std::move(client),
- std::move(blob_data_handle), nullptr /* file_system_context */);
+ std::move(blob_data_handle));
return;
}
@@ -462,7 +411,7 @@ void ServiceWorkerURLLoaderJob::OnStartLoadingResponseBody(
}
void ServiceWorkerURLLoaderJob::OnComplete(
- const ResourceRequestCompletionStatus& status) {
+ const network::URLLoaderCompletionStatus& status) {
DCHECK_EQ(Status::kSentHeader, status_);
DCHECK(url_loader_client_.is_bound());
status_ = Status::kCompleted;
diff --git a/chromium/content/browser/service_worker/service_worker_url_loader_job.h b/chromium/content/browser/service_worker/service_worker_url_loader_job.h
index 18a5f5c95d6..84553df3fb6 100644
--- a/chromium/content/browser/service_worker/service_worker_url_loader_job.h
+++ b/chromium/content/browser/service_worker/service_worker_url_loader_job.h
@@ -5,9 +5,13 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_URL_LOADER_JOB_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_URL_LOADER_JOB_H_
+#include <memory>
+#include <vector>
+
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/loader/url_loader_request_handler.h"
+#include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_response_type.h"
#include "content/browser/service_worker/service_worker_url_job_wrapper.h"
@@ -29,19 +33,19 @@ class BlobStorageContext;
namespace content {
-class ServiceWorkerFetchDispatcher;
struct ServiceWorkerResponse;
class ServiceWorkerVersion;
+// S13nServiceWorker:
// ServiceWorkerURLLoaderJob works similar to ServiceWorkerURLRequestJob
-// but with mojom::URLLoader instead of URLRequest, and used only when
-// --enable-network-service and PlzNavigate is enabled.
+// but with mojom::URLLoader instead of URLRequest.
// This also works as a URLLoaderClient for BlobURLLoader while reading
// the blob content returned by SW.
class CONTENT_EXPORT ServiceWorkerURLLoaderJob : public mojom::URLLoader,
public mojom::URLLoaderClient {
public:
using Delegate = ServiceWorkerURLJobWrapper::Delegate;
+ using ResponseType = ServiceWorkerResponseType;
// Created by ServiceWorkerControlleeRequestHandler::MaybeCreateLoader
// when starting to load a page for navigation.
@@ -94,15 +98,14 @@ class CONTENT_EXPORT ServiceWorkerURLLoaderJob : public mojom::URLLoader,
// For FORWARD_TO_SERVICE_WORKER case.
void StartRequest();
- scoped_refptr<storage::BlobHandle> CreateRequestBodyBlob();
void DidPrepareFetchEvent(scoped_refptr<ServiceWorkerVersion> version);
void DidDispatchFetchEvent(
ServiceWorkerStatusCode status,
- ServiceWorkerFetchEventResult fetch_result,
+ ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob,
- const scoped_refptr<ServiceWorkerVersion>& version);
+ blink::mojom::BlobPtr body_as_blob,
+ scoped_refptr<ServiceWorkerVersion> version);
// Used as the StartLoaderCallback passed to |loader_callback_| when the
// service worker provided a response. Returns the response to |client|.
@@ -111,7 +114,7 @@ class CONTENT_EXPORT ServiceWorkerURLLoaderJob : public mojom::URLLoader,
void StartResponse(const ServiceWorkerResponse& response,
scoped_refptr<ServiceWorkerVersion> version,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob,
+ blink::mojom::BlobPtr body_as_blob,
mojom::URLLoaderRequest request,
mojom::URLLoaderClientPtr client);
@@ -152,9 +155,9 @@ class CONTENT_EXPORT ServiceWorkerURLLoaderJob : public mojom::URLLoader,
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- void OnComplete(const ResourceRequestCompletionStatus& status) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
- ServiceWorkerResponseType response_type_ = NOT_DETERMINED;
+ ResponseType response_type_ = ResponseType::NOT_DETERMINED;
LoaderCallback loader_callback_;
Delegate* delegate_;
diff --git a/chromium/content/browser/service_worker/service_worker_url_loader_job_unittest.cc b/chromium/content/browser/service_worker/service_worker_url_loader_job_unittest.cc
index 840cc7b3f96..3768f17f242 100644
--- a/chromium/content/browser/service_worker/service_worker_url_loader_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_url_loader_job_unittest.cc
@@ -10,8 +10,10 @@
#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_registration.h"
+#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/common/content_features.h"
#include "content/public/common/resource_response.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -27,7 +29,6 @@
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_impl.h"
#include "storage/browser/blob/blob_storage_context.h"
-#include "storage/public/interfaces/blobs.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
@@ -92,7 +93,7 @@ class NavigationPreloadLoaderClient final : public mojom::URLLoaderClient {
// We could call OnResponseStream() here, but for simplicity, don't do
// anything until OnComplete().
}
- void OnComplete(const ResourceRequestCompletionStatus& status) override {
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override {
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
auto stream_handle = blink::mojom::ServiceWorkerStreamHandle::New();
stream_handle->callback_request = mojo::MakeRequest(&stream_callback);
@@ -102,17 +103,17 @@ class NavigationPreloadLoaderClient final : public mojom::URLLoaderClient {
// FetchEvent#respondWith.
response_callback_->OnResponseStream(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(
+ std::make_unique<std::vector<GURL>>(
response_head_.url_list_via_service_worker),
response_head_.headers->response_code(),
response_head_.headers->GetStatusText(),
response_head_.response_type_via_service_worker,
- base::MakeUnique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
+ std::make_unique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
0 /* blob_size */, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown, base::Time(),
+ blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time(),
false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
std::move(stream_handle), base::Time::Now());
std::move(finish_callback_)
@@ -182,7 +183,7 @@ class MockNetworkURLLoaderFactory final : public mojom::URLLoaderFactory {
MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
- ResourceRequestCompletionStatus status;
+ network::URLLoaderCompletionStatus status;
status.error_code = net::OK;
client->OnComplete(status);
}
@@ -201,11 +202,8 @@ class Helper : public EmbeddedWorkerTestHelper {
: EmbeddedWorkerTestHelper(
base::FilePath(),
base::MakeRefCounted<URLLoaderFactoryGetter>()) {
- mojom::URLLoaderFactoryPtr mock_loader_factory;
- mojo::MakeStrongBinding(base::MakeUnique<MockNetworkURLLoaderFactory>(),
- MakeRequest(&mock_loader_factory));
url_loader_factory_getter()->SetNetworkFactoryForTesting(
- std::move(mock_loader_factory));
+ &mock_url_loader_factory_);
}
~Helper() override = default;
@@ -270,44 +268,46 @@ class Helper : public EmbeddedWorkerTestHelper {
}
void ReadRequestBody(std::string* out_string) {
- ASSERT_TRUE(request_body_blob_);
-
- mojo::DataPipe pipe;
- (*request_body_blob_)->ReadAll(std::move(pipe.producer_handle), nullptr);
- base::RunLoop().RunUntilIdle();
-
- EXPECT_TRUE(mojo::common::BlockingCopyToString(
- std::move(pipe.consumer_handle), out_string));
+ ASSERT_TRUE(request_body_);
+ const std::vector<ResourceRequestBody::Element>* elements =
+ request_body_->elements();
+ // So far this test expects a single bytes element.
+ ASSERT_EQ(1u, elements->size());
+ const ResourceRequestBody::Element& element = elements->front();
+ ASSERT_EQ(ResourceRequestBody::Element::TYPE_BYTES, element.type());
+ *out_string = std::string(element.bytes(), element.length());
}
protected:
void OnFetchEvent(
int embedded_worker_id,
- int fetch_event_id,
- const ServiceWorkerFetchRequest& request,
+ const ResourceRequest& request,
mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
finish_callback) override {
- request_body_blob_ = request.blob;
+ // Basic checks on DispatchFetchEvent parameters.
+ EXPECT_TRUE(ServiceWorkerUtils::IsMainResourceType(request.resource_type));
+
+ request_body_ = request.request_body;
+
switch (response_mode_) {
case ResponseMode::kDefault:
EmbeddedWorkerTestHelper::OnFetchEvent(
- embedded_worker_id, fetch_event_id, request,
- std::move(preload_handle), std::move(response_callback),
- std::move(finish_callback));
+ embedded_worker_id, request, std::move(preload_handle),
+ std::move(response_callback), std::move(finish_callback));
return;
case ResponseMode::kBlob:
response_callback->OnResponse(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), blob_uuid_,
+ std::make_unique<ServiceWorkerHeaderMap>(), blob_uuid_,
blob_size_, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown, base::Time(),
- false /* response_is_in_cache_storage */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown,
+ base::Time(), false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
base::Time::Now());
std::move(finish_callback)
@@ -317,14 +317,14 @@ class Helper : public EmbeddedWorkerTestHelper {
case ResponseMode::kStream:
response_callback->OnResponseStream(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
+ std::make_unique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
0 /* blob_size */, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown, base::Time(),
- false /* response_is_in_cache_storage */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown,
+ base::Time(), false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
std::move(stream_handle_), base::Time::Now());
std::move(finish_callback)
@@ -340,15 +340,15 @@ class Helper : public EmbeddedWorkerTestHelper {
case ResponseMode::kErrorResponse:
response_callback->OnResponse(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 0 /* status_code */,
+ std::make_unique<std::vector<GURL>>(), 0 /* status_code */,
"" /* status_text */,
network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
+ std::make_unique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
0 /* blob_size */, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorPromiseRejected,
+ blink::mojom::ServiceWorkerResponseError::kPromiseRejected,
base::Time(), false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
base::Time::Now());
std::move(finish_callback)
@@ -381,30 +381,30 @@ class Helper : public EmbeddedWorkerTestHelper {
finish_callback_ = std::move(finish_callback);
response_callback->OnResponse(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
+ std::make_unique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
0 /* blob_size */, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown, base::Time(),
- false /* response_is_in_cache_storage */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown,
+ base::Time(), false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
base::Time::Now());
// Now the caller must call FinishWaitUntil() to finish the event.
return;
case ResponseMode::kRedirect:
- auto headers = base::MakeUnique<ServiceWorkerHeaderMap>();
+ auto headers = std::make_unique<ServiceWorkerHeaderMap>();
(*headers)["location"] = redirected_url_.spec();
response_callback->OnResponse(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 301, "Moved Permanently",
+ std::make_unique<std::vector<GURL>>(), 301, "Moved Permanently",
network::mojom::FetchResponseType::kDefault, std::move(headers),
"" /* blob_uuid */, 0 /* blob_size */, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown, base::Time(),
- false /* response_is_in_cache_storage */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown,
+ base::Time(), false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
base::Time::Now());
std::move(finish_callback)
@@ -429,7 +429,7 @@ class Helper : public EmbeddedWorkerTestHelper {
};
ResponseMode response_mode_ = ResponseMode::kDefault;
- scoped_refptr<storage::BlobHandle> request_body_blob_;
+ scoped_refptr<ResourceRequestBody> request_body_;
// For ResponseMode::kBlob.
std::string blob_uuid_;
@@ -445,6 +445,8 @@ class Helper : public EmbeddedWorkerTestHelper {
// For ResponseMode::kRedirect.
GURL redirected_url_;
+ MockNetworkURLLoaderFactory mock_url_loader_factory_;
+
DISALLOW_COPY_AND_ASSIGN(Helper);
};
@@ -473,16 +475,16 @@ std::unique_ptr<ResourceResponseHead> CreateResponseInfoFromServiceWorker() {
// responding as if a service worker is running in the renderer.
//
// ServiceWorkerURLLoaderJobTest is also a ServiceWorkerURLLoaderJob::Delegate.
-// In production code, ServiceWorkerControlleeRequestHandler is the Delegate
-// (for non-"foreign fetch" request interceptions). So this class also basically
-// mocks that part of ServiceWorkerControlleeRequestHandler.
+// In production code, ServiceWorkerControlleeRequestHandler is the Delegate. So
+// this class also basically mocks that part of
+// ServiceWorkerControlleeRequestHandler.
class ServiceWorkerURLLoaderJobTest
: public testing::Test,
public ServiceWorkerURLLoaderJob::Delegate {
public:
ServiceWorkerURLLoaderJobTest()
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- helper_(base::MakeUnique<Helper>()) {}
+ helper_(std::make_unique<Helper>()) {}
~ServiceWorkerURLLoaderJobTest() override = default;
void SetUp() override {
@@ -499,8 +501,9 @@ class ServiceWorkerURLLoaderJobTest
registration_.get(), GURL("https://example.com/service_worker.js"),
storage()->NewVersionId(), helper_->context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
- records.push_back(ServiceWorkerDatabase::ResourceRecord(
- storage()->NewResourceId(), version_->script_url(), 100));
+ records.push_back(WriteToDiskCacheSync(
+ storage(), version_->script_url(), storage()->NewResourceId(),
+ {} /* headers */, "I'm the body", "I'm the meta data"));
version_->script_cache_map()->SetResources(records);
version_->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
@@ -536,7 +539,7 @@ class ServiceWorkerURLLoaderJobTest
// Start a ServiceWorkerURLLoaderJob. It should return a
// StartLoaderCallback.
StartLoaderCallback callback;
- job_ = base::MakeUnique<ServiceWorkerURLLoaderJob>(
+ job_ = std::make_unique<ServiceWorkerURLLoaderJob>(
base::BindOnce(&ReceiveStartLoaderCallback, &callback), this, *request,
base::WrapRefCounted<URLLoaderFactoryGetter>(
helper_->context()->loader_factory_getter()),
@@ -575,11 +578,12 @@ class ServiceWorkerURLLoaderJobTest
std::unique_ptr<ResourceRequest> CreateRequest() {
std::unique_ptr<ResourceRequest> request =
- base::MakeUnique<ResourceRequest>();
+ std::make_unique<ResourceRequest>();
request->url = GURL("https://www.example.com/");
request->method = "GET";
- request->fetch_request_mode = FETCH_REQUEST_MODE_NAVIGATE;
- request->fetch_credentials_mode = FETCH_CREDENTIALS_MODE_INCLUDE;
+ request->fetch_request_mode = network::mojom::FetchRequestMode::kNavigate;
+ request->fetch_credentials_mode =
+ network::mojom::FetchCredentialsMode::kInclude;
request->fetch_redirect_mode = FetchRedirectMode::MANUAL_MODE;
return request;
}
@@ -641,12 +645,13 @@ TEST_F(ServiceWorkerURLLoaderJobTest, NoActiveWorker) {
// Test that the request body is passed to the fetch event.
TEST_F(ServiceWorkerURLLoaderJobTest, RequestBody) {
- const std::string kData = "BlobRequest";
+ const std::string kData = "hi this is the request body";
// Create a request with a body.
auto request_body = base::MakeRefCounted<ResourceRequestBody>();
request_body->AppendBytes(kData.c_str(), kData.length());
std::unique_ptr<ResourceRequest> request = CreateRequest();
+ request->method = "POST";
request->request_body = request_body;
// This test doesn't use the response to the fetch event, so just have the
@@ -664,7 +669,7 @@ TEST_F(ServiceWorkerURLLoaderJobTest, RequestBody) {
TEST_F(ServiceWorkerURLLoaderJobTest, BlobResponse) {
// Construct the blob to respond with.
const std::string kResponseBody = "Here is sample text for the blob.";
- auto blob_data = base::MakeUnique<storage::BlobDataBuilder>("blob-id:myblob");
+ auto blob_data = std::make_unique<storage::BlobDataBuilder>("blob-id:myblob");
blob_data->AppendData(kResponseBody);
std::unique_ptr<storage::BlobDataHandle> blob_handle =
blob_context_.AddFinishedBlob(blob_data.get());
@@ -889,12 +894,13 @@ TEST_F(ServiceWorkerURLLoaderJobTest, FallbackToNetwork) {
ResourceRequest request;
request.url = GURL("https://www.example.com/");
request.method = "GET";
- request.fetch_request_mode = FETCH_REQUEST_MODE_NAVIGATE;
- request.fetch_credentials_mode = FETCH_CREDENTIALS_MODE_INCLUDE;
+ request.fetch_request_mode = network::mojom::FetchRequestMode::kNavigate;
+ request.fetch_credentials_mode =
+ network::mojom::FetchCredentialsMode::kInclude;
request.fetch_redirect_mode = FetchRedirectMode::MANUAL_MODE;
StartLoaderCallback callback;
- auto job = base::MakeUnique<ServiceWorkerURLLoaderJob>(
+ auto job = std::make_unique<ServiceWorkerURLLoaderJob>(
base::BindOnce(&ReceiveStartLoaderCallback, &callback), this, request,
base::WrapRefCounted<URLLoaderFactoryGetter>(
helper_->context()->loader_factory_getter()),
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 bd0e323fccc..90bb2dacd81 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
@@ -27,7 +27,6 @@
#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/service_worker_blob_reader.h"
#include "content/browser/service_worker/service_worker_data_pipe_reader.h"
-#include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_response_info.h"
#include "content/common/service_worker/service_worker_types.h"
@@ -58,8 +57,9 @@ namespace content {
namespace {
net::URLRequestStatus ServiceWorkerResponseErrorToNetStatus(
- blink::WebServiceWorkerResponseError error) {
- if (error == blink::kWebServiceWorkerResponseErrorDataPipeCreationFailed) {
+ blink::mojom::ServiceWorkerResponseError error) {
+ if (error ==
+ blink::mojom::ServiceWorkerResponseError::kDataPipeCreationFailed) {
return net::URLRequestStatus::FromError(net::ERR_INSUFFICIENT_RESOURCES);
}
@@ -321,10 +321,11 @@ ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
const std::string& client_id,
base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
const ResourceContext* resource_context,
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
+ network::mojom::FetchRequestMode request_mode,
+ network::mojom::FetchCredentialsMode credentials_mode,
FetchRedirectMode redirect_mode,
const std::string& integrity,
+ bool keepalive,
ResourceType resource_type,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
@@ -334,7 +335,7 @@ ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
Delegate* delegate)
: net::URLRequestJob(request, network_delegate),
delegate_(delegate),
- response_type_(NOT_DETERMINED),
+ response_type_(ResponseType::NOT_DETERMINED),
is_started_(false),
fetch_response_type_(network::mojom::FetchResponseType::kDefault),
client_id_(client_id),
@@ -344,6 +345,7 @@ ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
credentials_mode_(credentials_mode),
redirect_mode_(redirect_mode),
integrity_(integrity),
+ keepalive_(keepalive),
resource_type_(resource_type),
request_context_type_(request_context_type),
frame_type_(frame_type),
@@ -371,32 +373,31 @@ ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() {
}
void ServiceWorkerURLRequestJob::FallbackToNetwork() {
- DCHECK_EQ(NOT_DETERMINED, response_type_);
+ DCHECK_EQ(ResponseType::NOT_DETERMINED, response_type_);
DCHECK(!IsFallbackToRendererNeeded());
- response_type_ = FALLBACK_TO_NETWORK;
+ response_type_ = ResponseType::FALLBACK_TO_NETWORK;
MaybeStartRequest();
}
void ServiceWorkerURLRequestJob::FallbackToNetworkOrRenderer() {
- DCHECK_EQ(NOT_DETERMINED, response_type_);
- DCHECK_NE(ServiceWorkerFetchType::FOREIGN_FETCH, fetch_type_);
+ DCHECK_EQ(ResponseType::NOT_DETERMINED, response_type_);
if (IsFallbackToRendererNeeded()) {
- response_type_ = FALLBACK_TO_RENDERER;
+ response_type_ = ResponseType::FALLBACK_TO_RENDERER;
} else {
- response_type_ = FALLBACK_TO_NETWORK;
+ response_type_ = ResponseType::FALLBACK_TO_NETWORK;
}
MaybeStartRequest();
}
void ServiceWorkerURLRequestJob::ForwardToServiceWorker() {
- DCHECK_EQ(NOT_DETERMINED, response_type_);
- response_type_ = FORWARD_TO_SERVICE_WORKER;
+ DCHECK_EQ(ResponseType::NOT_DETERMINED, response_type_);
+ response_type_ = ResponseType::FORWARD_TO_SERVICE_WORKER;
MaybeStartRequest();
}
void ServiceWorkerURLRequestJob::FailDueToLostController() {
- DCHECK_EQ(NOT_DETERMINED, response_type_);
- response_type_ = FAIL_DUE_TO_LOST_CONTROLLER;
+ DCHECK_EQ(ResponseType::NOT_DETERMINED, response_type_);
+ response_type_ = ResponseType::FAIL_DUE_TO_LOST_CONTROLLER;
MaybeStartRequest();
}
@@ -507,7 +508,7 @@ const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const {
}
void ServiceWorkerURLRequestJob::MaybeStartRequest() {
- if (is_started_ && response_type_ != NOT_DETERMINED) {
+ if (is_started_ && response_type_ != ResponseType::NOT_DETERMINED) {
// Start asynchronously.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&ServiceWorkerURLRequestJob::StartRequest,
@@ -520,25 +521,25 @@ void ServiceWorkerURLRequestJob::StartRequest() {
net::NetLogEventType::SERVICE_WORKER_START_REQUEST);
switch (response_type_) {
- case NOT_DETERMINED:
+ case ResponseType::NOT_DETERMINED:
NOTREACHED();
return;
- case FAIL_DUE_TO_LOST_CONTROLLER:
+ case ResponseType::FAIL_DUE_TO_LOST_CONTROLLER:
request()->net_log().AddEvent(
net::NetLogEventType::SERVICE_WORKER_ERROR_NO_ACTIVE_VERSION);
NotifyStartError(net::URLRequestStatus::FromError(net::ERR_FAILED));
return;
- case FALLBACK_TO_NETWORK:
+ case ResponseType::FALLBACK_TO_NETWORK:
FinalizeFallbackToNetwork();
return;
- case FALLBACK_TO_RENDERER:
+ case ResponseType::FALLBACK_TO_RENDERER:
FinalizeFallbackToRenderer();
return;
- case FORWARD_TO_SERVICE_WORKER:
+ case ResponseType::FORWARD_TO_SERVICE_WORKER:
if (HasRequestBody()) {
DCHECK(!file_size_resolver_);
file_size_resolver_.reset(new FileSizeResolver(this));
@@ -561,8 +562,7 @@ ServiceWorkerURLRequestJob::CreateFetchRequest() {
uint64_t blob_size = 0;
if (HasRequestBody())
CreateRequestBodyBlob(&blob_uuid, &blob_size);
- std::unique_ptr<ServiceWorkerFetchRequest> request(
- new ServiceWorkerFetchRequest());
+ auto request = std::make_unique<ServiceWorkerFetchRequest>();
request->mode = request_mode_;
request->is_main_resource_load = IsMainResourceLoad();
request->request_context_type = request_context_type_;
@@ -579,8 +579,11 @@ ServiceWorkerURLRequestJob::CreateFetchRequest() {
request->blob_size = blob_size;
request->blob = request_body_blob_handle_;
request->credentials_mode = credentials_mode_;
+ request->cache_mode = ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(
+ request_->load_flags());
request->redirect_mode = redirect_mode_;
request->integrity = integrity_;
+ request->keepalive = keepalive_;
request->client_id = client_id_;
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
if (info) {
@@ -604,7 +607,7 @@ void ServiceWorkerURLRequestJob::CreateRequestBodyBlob(std::string* blob_uuid,
DCHECK(HasRequestBody());
storage::BlobDataBuilder blob_builder(base::GenerateGUID());
for (const ResourceRequestBody::Element& element : (*body_->elements())) {
- blob_builder.AppendIPCDataElement(element);
+ blob_builder.AppendIPCDataElement(element, nullptr); // TODO
}
request_body_blob_data_handle_ =
@@ -613,8 +616,8 @@ void ServiceWorkerURLRequestJob::CreateRequestBodyBlob(std::string* blob_uuid,
*blob_size = request_body_blob_data_handle_->size();
if (features::IsMojoBlobsEnabled()) {
- storage::mojom::BlobPtr blob_ptr;
- storage::BlobImpl::Create(base::MakeUnique<storage::BlobDataHandle>(
+ blink::mojom::BlobPtr blob_ptr;
+ storage::BlobImpl::Create(std::make_unique<storage::BlobDataHandle>(
*request_body_blob_data_handle_),
MakeRequest(&blob_ptr));
request_body_blob_handle_ =
@@ -677,11 +680,11 @@ void ServiceWorkerURLRequestJob::DidPrepareFetchEvent(
void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
ServiceWorkerStatusCode status,
- ServiceWorkerFetchEventResult fetch_result,
+ ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob,
- const scoped_refptr<ServiceWorkerVersion>& version) {
+ blink::mojom::BlobPtr body_as_blob,
+ scoped_refptr<ServiceWorkerVersion> version) {
// Do not clear |fetch_dispatcher_| if it has dispatched a navigation preload
// request to keep the mojom::URLLoader related objects in it, because the
// preload response might still need to be streamed even after calling
@@ -711,7 +714,8 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
return;
}
- if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) {
+ if (fetch_result ==
+ ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback) {
ServiceWorkerMetrics::RecordFallbackedRequestMode(request_mode_);
if (IsFallbackToRendererNeeded()) {
FinalizeFallbackToRenderer();
@@ -722,7 +726,8 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
}
// We should have a response now.
- DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result);
+ DCHECK_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
+ fetch_result);
// A response with status code 0 is Blink telling us to respond with network
// error.
@@ -837,21 +842,18 @@ void ServiceWorkerURLRequestJob::FinalizeFallbackToNetwork() {
// intercept.
if (ShouldRecordResult())
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_RESPONSE);
- response_type_ = FALLBACK_TO_NETWORK;
+ response_type_ = ResponseType::FALLBACK_TO_NETWORK;
NotifyRestartRequired();
return;
}
void ServiceWorkerURLRequestJob::FinalizeFallbackToRenderer() {
- // TODO(mek): http://crbug.com/604084 Figure out what to do about CORS
- // preflight and fallbacks for foreign fetch events.
- DCHECK_NE(fetch_type_, ServiceWorkerFetchType::FOREIGN_FETCH);
fall_back_required_ = true;
if (ShouldRecordResult())
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_FOR_CORS);
CreateResponseHeader(400, "Service Worker Fallback Required",
ServiceWorkerHeaderMap());
- response_type_ = FALLBACK_TO_RENDERER;
+ response_type_ = ResponseType::FALLBACK_TO_RENDERER;
CommitResponseHeader();
}
@@ -861,17 +863,13 @@ bool ServiceWorkerURLRequestJob::IsFallbackToRendererNeeded() const {
// document, we can't simply fallback to the network in the browser process.
// It is because the CORS preflight logic is implemented in the renderer. So
// we return a fall_back_required response to the renderer.
- // If fetch_type is |FOREIGN_FETCH| any required CORS checks will have already
- // been done in the renderer (and if a preflight was necesary the request
- // would never have reached foreign fetch), so such requests can always
- // fallback to the network directly.
return !IsMainResourceLoad() &&
- fetch_type_ != ServiceWorkerFetchType::FOREIGN_FETCH &&
- (request_mode_ == FETCH_REQUEST_MODE_CORS ||
- request_mode_ == FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT) &&
+ (request_mode_ == network::mojom::FetchRequestMode::kCORS ||
+ request_mode_ ==
+ network::mojom::FetchRequestMode::kCORSWithForcedPreflight) &&
(!request()->initiator().has_value() ||
!request()->initiator()->IsSameOriginWith(
- url::Origin(request()->url())));
+ url::Origin::Create(request()->url())));
}
void ServiceWorkerURLRequestJob::SetResponseBodyType(ResponseBodyType type) {
@@ -882,11 +880,11 @@ void ServiceWorkerURLRequestJob::SetResponseBodyType(ResponseBodyType type) {
bool ServiceWorkerURLRequestJob::ShouldRecordResult() {
return !did_record_result_ && is_started_ &&
- response_type_ == FORWARD_TO_SERVICE_WORKER;
+ response_type_ == ResponseType::FORWARD_TO_SERVICE_WORKER;
}
void ServiceWorkerURLRequestJob::RecordStatusZeroResponseError(
- blink::WebServiceWorkerResponseError error) {
+ blink::mojom::ServiceWorkerResponseError error) {
// It violates style guidelines to handle a NOTREACHED() failure but if there
// is a bug don't let it corrupt UMA results by double-counting.
if (!ShouldRecordResult()) {
@@ -919,16 +917,15 @@ void ServiceWorkerURLRequestJob::NotifyRestartRequired() {
void ServiceWorkerURLRequestJob::OnStartCompleted() const {
switch (response_type_) {
- case NOT_DETERMINED:
+ case ResponseType::NOT_DETERMINED:
NOTREACHED();
return;
- case FAIL_DUE_TO_LOST_CONTROLLER:
- case FALLBACK_TO_NETWORK:
+ case ResponseType::FAIL_DUE_TO_LOST_CONTROLLER:
+ case ResponseType::FALLBACK_TO_NETWORK:
// Indicate that the service worker did not respond to the request.
ServiceWorkerResponseInfo::ForRequest(request_, true)
->OnStartCompleted(
false /* was_fetched_via_service_worker */,
- false /* was_fetched_via_foreign_fetch */,
false /* was_fallback_required */,
std::vector<GURL>() /* url_list_via_service_worker */,
network::mojom::FetchResponseType::kDefault,
@@ -939,15 +936,14 @@ void ServiceWorkerURLRequestJob::OnStartCompleted() const {
ServiceWorkerHeaderList() /* cors_exposed_header_names */,
did_navigation_preload_);
break;
- case FALLBACK_TO_RENDERER:
- case FORWARD_TO_SERVICE_WORKER:
+ case ResponseType::FALLBACK_TO_RENDERER:
+ case ResponseType::FORWARD_TO_SERVICE_WORKER:
// Indicate that the service worker responded to the request, which is
// considered true if "fallback to renderer" was required since the
// renderer expects that.
ServiceWorkerResponseInfo::ForRequest(request_, true)
->OnStartCompleted(
true /* was_fetched_via_service_worker */,
- fetch_type_ == ServiceWorkerFetchType::FOREIGN_FETCH,
fall_back_required_, response_url_list_, fetch_response_type_,
worker_start_time_, worker_ready_time_,
response_is_in_cache_storage_, response_cache_storage_cache_name_,
@@ -994,16 +990,16 @@ void ServiceWorkerURLRequestJob::RequestBodyFileSizesResolved(bool success) {
initial_worker_status_ = active_worker->running_status();
DCHECK(!fetch_dispatcher_);
- fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
- CreateFetchRequest(), active_worker, resource_type_, timeout_,
- request()->net_log(),
- base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
- weak_factory_.GetWeakPtr(),
- base::WrapRefCounted(active_worker)),
- base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
- weak_factory_.GetWeakPtr())));
+ fetch_dispatcher_ = std::make_unique<ServiceWorkerFetchDispatcher>(
+ CreateFetchRequest(), base::WrapRefCounted(active_worker), resource_type_,
+ timeout_, request()->net_log(),
+ base::BindOnce(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
+ weak_factory_.GetWeakPtr(),
+ base::WrapRefCounted(active_worker)),
+ base::BindOnce(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
+ weak_factory_.GetWeakPtr()));
worker_start_time_ = base::TimeTicks::Now();
- nav_preload_metrics_ = base::MakeUnique<NavigationPreloadMetrics>(this);
+ nav_preload_metrics_ = std::make_unique<NavigationPreloadMetrics>(this);
if (simulate_navigation_preload_for_test_) {
did_navigation_preload_ = true;
} else {
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 a3b1ad33afd..93cc1bfbc86 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
@@ -18,6 +18,7 @@
#include "base/optional.h"
#include "base/time/time.h"
#include "content/browser/service_worker/embedded_worker_status.h"
+#include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_response_type.h"
#include "content/browser/service_worker/service_worker_url_job_wrapper.h"
@@ -53,12 +54,12 @@ class ResourceContext;
class ResourceRequestBody;
class ServiceWorkerBlobReader;
class ServiceWorkerDataPipeReader;
-class ServiceWorkerFetchDispatcher;
class ServiceWorkerVersion;
class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
public:
using Delegate = ServiceWorkerURLJobWrapper::Delegate;
+ using ResponseType = ServiceWorkerResponseType;
ServiceWorkerURLRequestJob(
net::URLRequest* request,
@@ -66,10 +67,11 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
const std::string& client_id,
base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
const ResourceContext* resource_context,
- FetchRequestMode request_mode,
- FetchCredentialsMode credentials_mode,
+ network::mojom::FetchRequestMode request_mode,
+ network::mojom::FetchCredentialsMode credentials_mode,
FetchRedirectMode redirect_mode,
const std::string& integrity,
+ bool keepalive,
ResourceType resource_type,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
@@ -96,11 +98,9 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
// When an in-flight request possibly needs CORS check, use
// FallbackToNetworkOrRenderer. This method will decide whether the request
// can directly go to the network or should fallback to a renderer to send
- // CORS preflight. You can use FallbackToNetwork only when, like main resource
- // or foreign fetch cases, it's apparent that the request should go to the
- // network directly.
- // TODO(shimazu): Update the comment when what should we do at foreign fetch
- // fallback is determined: crbug.com/604084
+ // CORS preflight. You can use FallbackToNetwork only when it's apparent that
+ // the request can go to the network directly (e.g., main resource requests or
+ // same-origin requests).
void FallbackToNetwork();
void FallbackToNetworkOrRenderer();
void ForwardToServiceWorker();
@@ -110,10 +110,10 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
void FailDueToLostController();
bool ShouldFallbackToNetwork() const {
- return response_type_ == FALLBACK_TO_NETWORK;
+ return response_type_ == ResponseType::FALLBACK_TO_NETWORK;
}
bool ShouldForwardToServiceWorker() const {
- return response_type_ == FORWARD_TO_SERVICE_WORKER;
+ return response_type_ == ResponseType::FORWARD_TO_SERVICE_WORKER;
}
// net::URLRequestJob overrides:
@@ -175,11 +175,11 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
void DidPrepareFetchEvent(scoped_refptr<ServiceWorkerVersion> version);
void DidDispatchFetchEvent(
ServiceWorkerStatusCode status,
- ServiceWorkerFetchEventResult fetch_result,
+ ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- storage::mojom::BlobPtr body_as_blob,
- const scoped_refptr<ServiceWorkerVersion>& version);
+ blink::mojom::BlobPtr body_as_blob,
+ scoped_refptr<ServiceWorkerVersion> version);
void SetResponse(const ServiceWorkerResponse& response);
// Populates |http_response_headers_|.
@@ -211,7 +211,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
void SetResponseBodyType(ResponseBodyType type);
bool ShouldRecordResult();
void RecordStatusZeroResponseError(
- blink::WebServiceWorkerResponseError error);
+ blink::mojom::ServiceWorkerResponseError error);
const net::HttpResponseInfo* http_info() const;
@@ -276,7 +276,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
std::unique_ptr<NavigationPreloadMetrics> nav_preload_metrics_;
- ServiceWorkerResponseType response_type_;
+ ResponseType response_type_;
// True if URLRequestJob::Start() has been called.
bool is_started_;
@@ -298,10 +298,11 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
std::unique_ptr<ServiceWorkerBlobReader> blob_reader_;
std::unique_ptr<ServiceWorkerDataPipeReader> data_pipe_reader_;
- FetchRequestMode request_mode_;
- FetchCredentialsMode credentials_mode_;
+ network::mojom::FetchRequestMode request_mode_;
+ network::mojom::FetchCredentialsMode credentials_mode_;
FetchRedirectMode redirect_mode_;
std::string integrity_;
+ const bool keepalive_;
const ResourceType resource_type_;
RequestContextType request_context_type_;
RequestContextFrameType frame_type_;
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 900bb54a7fa..f84479472e5 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
@@ -34,6 +34,7 @@
#include "content/common/service_worker/service_worker_messages.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
+#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_frame_type.h"
@@ -62,6 +63,7 @@
#include "storage/browser/blob/blob_url_request_job_factory.h"
#include "storage/common/blob_storage/blob_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
@@ -118,10 +120,12 @@ class MockProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
job_ = new ServiceWorkerURLRequestJob(
request, network_delegate, provider_host_->client_uuid(),
- blob_storage_context_, resource_context_, FETCH_REQUEST_MODE_NO_CORS,
- FETCH_CREDENTIALS_MODE_OMIT, FetchRedirectMode::FOLLOW_MODE,
- std::string() /* integrity */, resource_type_,
- REQUEST_CONTEXT_TYPE_HYPERLINK, REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
+ blob_storage_context_, resource_context_,
+ network::mojom::FetchRequestMode::kNoCORS,
+ network::mojom::FetchCredentialsMode::kOmit,
+ FetchRedirectMode::FOLLOW_MODE, std::string() /* integrity */,
+ false /* keepalive */, resource_type_, REQUEST_CONTEXT_TYPE_HYPERLINK,
+ REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
scoped_refptr<ResourceRequestBody>(), ServiceWorkerFetchType::FETCH,
custom_timeout_, delegate_);
if (simulate_navigation_preload_) {
@@ -147,12 +151,11 @@ class MockProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
// the memory.
std::unique_ptr<storage::BlobProtocolHandler> CreateMockBlobProtocolHandler(
storage::BlobStorageContext* blob_storage_context) {
- return base::MakeUnique<storage::BlobProtocolHandler>(blob_storage_context,
- nullptr);
+ return std::make_unique<storage::BlobProtocolHandler>(blob_storage_context);
}
std::unique_ptr<ServiceWorkerHeaderMap> MakeHeaders() {
- auto headers = base::MakeUnique<ServiceWorkerHeaderMap>();
+ auto headers = std::make_unique<ServiceWorkerHeaderMap>();
(*headers)["Pineapple"] = "Pen";
(*headers)["Foo"] = "Bar";
(*headers)["Set-Cookie"] = "CookieCookieCookie";
@@ -206,6 +209,19 @@ class ServiceWorkerURLRequestJobTest
void SetUpWithHelper(std::unique_ptr<EmbeddedWorkerTestHelper> helper) {
helper_ = std::move(helper);
+ helper_->context()->storage()->LazyInitializeForTest(
+ base::BindOnce(&base::DoNothing));
+ base::RunLoop().RunUntilIdle();
+
+ // Prepare HTTP response info for the version.
+ auto http_info = std::make_unique<net::HttpResponseInfo>();
+ http_info->ssl_info.cert =
+ net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
+ EXPECT_TRUE(http_info->ssl_info.is_valid());
+ http_info->ssl_info.security_bits = 0x100;
+ // SSL3 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ http_info->ssl_info.connection_status = 0x300039;
+ http_info->headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
// Create a registration and service worker version.
registration_ = new ServiceWorkerRegistration(
@@ -215,17 +231,20 @@ class ServiceWorkerURLRequestJobTest
version_ = new ServiceWorkerVersion(
registration_.get(), GURL("https://example.com/service_worker.js"), 1L,
helper_->context()->AsWeakPtr());
+ // If script streaming is not enabled, SetMainScriptHttpResponseInfo()
+ // should be called manually since |http_info| which is stored in disk cache
+ // won't be read during SWVersion::StartWorker() in tests.
+ if (!ServiceWorkerUtils::IsScriptStreamingEnabled())
+ version_->SetMainScriptHttpResponseInfo(*http_info);
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
- records.push_back(
- ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100));
+ records.push_back(WriteToDiskCacheWithCustomResponseInfoSync(
+ helper_->context()->storage(), version_->script_url(), 10,
+ std::move(http_info), "I'm the body", "I'm the meta data"));
version_->script_cache_map()->SetResources(records);
version_->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
// Make the registration findable via storage functions.
- helper_->context()->storage()->LazyInitializeForTest(
- base::BindOnce(&base::DoNothing));
- base::RunLoop().RunUntilIdle();
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
helper_->context()->storage()->StoreRegistration(
registration_.get(),
@@ -234,17 +253,6 @@ class ServiceWorkerURLRequestJobTest
base::RunLoop().RunUntilIdle();
ASSERT_EQ(SERVICE_WORKER_OK, status);
- // Set HTTP response info on the version.
- net::HttpResponseInfo http_info;
- http_info.ssl_info.cert =
- net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
- EXPECT_TRUE(http_info.ssl_info.is_valid());
- http_info.ssl_info.security_bits = 0x100;
- // SSL3 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
- http_info.ssl_info.connection_status = 0x300039;
- http_info.headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
- version_->SetMainScriptHttpResponseInfo(http_info);
-
// Create a controlled client.
std::unique_ptr<ServiceWorkerProviderHost> provider_host =
CreateProviderHostForWindow(
@@ -373,7 +381,7 @@ class ServiceWorkerURLRequestJobTest
ResourceRequestInfo::AllocateForTesting(
request_.get(), resource_type, browser_context_->GetResourceContext(),
-1, -1, -1, resource_type == RESOURCE_TYPE_MAIN_FRAME, true, true,
- PREVIEWS_OFF);
+ PREVIEWS_OFF, nullptr);
request_->set_method("GET");
request_->Start();
@@ -413,6 +421,7 @@ class ServiceWorkerURLRequestJobTest
// ---------------------------------------------------------------------------
TestBrowserThreadBundle thread_bundle_;
+ base::SimpleTestTickClock tick_clock_;
std::unique_ptr<TestBrowserContext> browser_context_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
@@ -438,7 +447,7 @@ class ServiceWorkerURLRequestJobTest
};
TEST_F(ServiceWorkerURLRequestJobTest, Simple) {
- SetUpWithHelper(base::MakeUnique<EmbeddedWorkerTestHelper>(base::FilePath()));
+ SetUpWithHelper(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
TestRequest(200, "OK", std::string(), true /* expect_valid_ssl */);
@@ -473,19 +482,22 @@ class DelayHelper : public EmbeddedWorkerTestHelper {
EmbeddedWorkerTestHelper::OnStartWorker(
embedded_worker_id_, service_worker_version_id_, scope_, script_url_,
pause_after_download_, std::move(start_worker_request_),
- std::move(start_worker_instance_host_), std::move(provider_info_));
+ std::move(controller_request_), std::move(service_worker_host_),
+ std::move(start_worker_instance_host_), std::move(provider_info_),
+ std::move(installed_scripts_info_));
}
void Respond() {
response_callback_->OnResponse(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), std::string(), 0,
- nullptr /* blob */, blink::kWebServiceWorkerResponseErrorUnknown,
- base::Time(), false /* response_is_in_cache_storage */,
+ std::make_unique<ServiceWorkerHeaderMap>(), std::string(), 0,
+ nullptr /* blob */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time(),
+ false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
base::Time::Now());
std::move(finish_callback_)
@@ -500,30 +512,34 @@ class DelayHelper : public EmbeddedWorkerTestHelper {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info)
override {
embedded_worker_id_ = embedded_worker_id;
service_worker_version_id_ = service_worker_version_id;
scope_ = scope;
script_url_ = script_url;
pause_after_download_ = pause_after_download;
- start_worker_request_ = std::move(request);
+ start_worker_request_ = std::move(dispatcher_request);
+ controller_request_ = std::move(controller_request);
+ service_worker_host_ = std::move(service_worker_host);
start_worker_instance_host_ = std::move(instance_host);
provider_info_ = std::move(provider_info);
+ installed_scripts_info_ = std::move(installed_scripts_info);
}
- void OnFetchEvent(
+ void OnLegacyFetchEvent(
int embedded_worker_id,
- int fetch_event_id,
const ServiceWorkerFetchRequest& /* request */,
mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
finish_callback) override {
embedded_worker_id_ = embedded_worker_id;
- fetch_event_id_ = fetch_event_id;
response_callback_ = std::move(response_callback);
finish_callback_ = std::move(finish_callback);
preload_handle_ = std::move(preload_handle);
@@ -535,11 +551,13 @@ class DelayHelper : public EmbeddedWorkerTestHelper {
GURL script_url_;
bool pause_after_download_;
mojom::ServiceWorkerEventDispatcherRequest start_worker_request_;
+ mojom::ControllerServiceWorkerRequest controller_request_;
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host_;
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
start_worker_instance_host_;
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info_;
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info_;
int embedded_worker_id_ = 0;
- int fetch_event_id_ = 0;
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_;
mojom::FetchEventPreloadHandlePtr preload_handle_;
mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
@@ -550,7 +568,7 @@ class DelayHelper : public EmbeddedWorkerTestHelper {
TEST_F(ServiceWorkerURLRequestJobTest,
NavPreloadMetrics_WorkerAlreadyStarted_MainFrame) {
- SetUpWithHelper(base::MakeUnique<DelayHelper>(this));
+ SetUpWithHelper(std::make_unique<DelayHelper>(this));
DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());
// Start the worker before the navigation.
@@ -584,7 +602,7 @@ TEST_F(ServiceWorkerURLRequestJobTest,
TEST_F(ServiceWorkerURLRequestJobTest,
NavPreloadMetrics_WorkerFirst_MainFrame) {
- SetUpWithHelper(base::MakeUnique<DelayHelper>(this));
+ SetUpWithHelper(std::make_unique<DelayHelper>(this));
DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());
base::HistogramTester histogram_tester;
@@ -611,7 +629,7 @@ TEST_F(ServiceWorkerURLRequestJobTest,
TEST_F(ServiceWorkerURLRequestJobTest,
NavPreloadMetrics_NavPreloadFirst_MainFrame) {
- SetUpWithHelper(base::MakeUnique<DelayHelper>(this));
+ SetUpWithHelper(std::make_unique<DelayHelper>(this));
DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());
base::HistogramTester histogram_tester;
@@ -637,7 +655,7 @@ TEST_F(ServiceWorkerURLRequestJobTest,
}
TEST_F(ServiceWorkerURLRequestJobTest, NavPreloadMetrics_WorkerFirst_SubFrame) {
- SetUpWithHelper(base::MakeUnique<DelayHelper>(this));
+ SetUpWithHelper(std::make_unique<DelayHelper>(this));
DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());
base::HistogramTester histogram_tester;
@@ -663,7 +681,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, NavPreloadMetrics_WorkerFirst_SubFrame) {
TEST_F(ServiceWorkerURLRequestJobTest,
NavPreloadMetrics_NavPreloadFirst_SubFrame) {
- SetUpWithHelper(base::MakeUnique<DelayHelper>(this));
+ SetUpWithHelper(std::make_unique<DelayHelper>(this));
DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());
base::HistogramTester histogram_tester;
@@ -688,16 +706,13 @@ TEST_F(ServiceWorkerURLRequestJobTest,
}
TEST_F(ServiceWorkerURLRequestJobTest, CustomTimeout) {
- SetUpWithHelper(base::MakeUnique<EmbeddedWorkerTestHelper>(base::FilePath()));
+ SetUpWithHelper(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
// Set mock clock on version_ to check timeout behavior.
- {
- auto tick_clock = base::MakeUnique<base::SimpleTestTickClock>();
- tick_clock->SetNowTicks(base::TimeTicks::Now());
- version_->SetTickClockForTesting(std::move(tick_clock));
- }
+ tick_clock_.SetNowTicks(base::TimeTicks::Now());
+ version_->SetTickClockForTesting(&tick_clock_);
protocol_handler_->set_custom_timeout(base::TimeDelta::FromSeconds(5));
TestRequest(200, "OK", std::string(), true /* expect_valid_ssl */);
@@ -710,9 +725,8 @@ class ProviderDeleteHelper : public EmbeddedWorkerTestHelper {
~ProviderDeleteHelper() override {}
protected:
- void OnFetchEvent(
+ void OnLegacyFetchEvent(
int /* embedded_worker_id */,
- int /* fetch_event_id */,
const ServiceWorkerFetchRequest& /* request */,
mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
@@ -721,13 +735,14 @@ class ProviderDeleteHelper : public EmbeddedWorkerTestHelper {
context()->RemoveProviderHost(mock_render_process_id(), kProviderID);
response_callback->OnResponse(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), std::string(), 0,
- nullptr /* blob */, blink::kWebServiceWorkerResponseErrorUnknown,
- base::Time(), false /* response_is_in_cache_storage */,
+ std::make_unique<ServiceWorkerHeaderMap>(), std::string(), 0,
+ nullptr /* blob */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time(),
+ false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
base::Time::Now());
std::move(finish_callback)
@@ -742,9 +757,7 @@ class ProviderDeleteHelper : public EmbeddedWorkerTestHelper {
// Shouldn't crash if the ProviderHost is deleted prior to completion of the
// fetch event.
TEST_F(ServiceWorkerURLRequestJobTest, DeletedProviderHostOnFetchEvent) {
- SetUpWithHelper(base::MakeUnique<ProviderDeleteHelper>());
-
- version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ SetUpWithHelper(std::make_unique<ProviderDeleteHelper>());
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
TestRequest(500, "Service Worker Response Error", std::string(),
@@ -764,7 +777,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, DeletedProviderHostOnFetchEvent) {
}
TEST_F(ServiceWorkerURLRequestJobTest, DeletedProviderHostBeforeFetchEvent) {
- SetUpWithHelper(base::MakeUnique<EmbeddedWorkerTestHelper>(base::FilePath()));
+ SetUpWithHelper(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
request_ = url_request_context_.CreateRequest(
@@ -802,9 +815,8 @@ class BlobResponder : public EmbeddedWorkerTestHelper {
~BlobResponder() override = default;
protected:
- void OnFetchEvent(
+ void OnLegacyFetchEvent(
int /* embedded_worker_id */,
- int /* fetch_event_id */,
const ServiceWorkerFetchRequest& /* request */,
mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
@@ -812,13 +824,13 @@ class BlobResponder : public EmbeddedWorkerTestHelper {
finish_callback) override {
response_callback->OnResponse(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
network::mojom::FetchResponseType::kDefault, MakeHeaders(),
blob_uuid_, blob_size_, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown, base::Time(),
+ blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time(),
false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
base::Time::Now());
std::move(finish_callback)
@@ -842,14 +854,14 @@ TEST_F(ServiceWorkerURLRequestJobTest, BlobResponse) {
std::string expected_response;
expected_response.reserve((sizeof(kTestData) - 1) * 1024);
- auto blob_data = base::MakeUnique<storage::BlobDataBuilder>("blob-id:myblob");
+ auto blob_data = std::make_unique<storage::BlobDataBuilder>("blob-id:myblob");
for (int i = 0; i < 1024; ++i) {
blob_data->AppendData(kTestData);
expected_response += kTestData;
}
std::unique_ptr<storage::BlobDataHandle> blob_handle =
blob_storage_context->context()->AddFinishedBlob(blob_data.get());
- SetUpWithHelper(base::MakeUnique<BlobResponder>(blob_handle->uuid(),
+ SetUpWithHelper(std::make_unique<BlobResponder>(blob_handle->uuid(),
expected_response.size()));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -871,7 +883,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, BlobResponse) {
TEST_F(ServiceWorkerURLRequestJobTest, NonExistentBlobUUIDResponse) {
SetUpWithHelper(
- base::MakeUnique<BlobResponder>("blob-id:nothing-is-here", 0));
+ std::make_unique<BlobResponder>("blob-id:nothing-is-here", 0));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
TestRequest(500, "Service Worker Response Error", std::string(),
true /* expect_valid_ssl */);
@@ -904,9 +916,8 @@ class StreamResponder : public EmbeddedWorkerTestHelper {
~StreamResponder() override {}
protected:
- void OnFetchEvent(
+ void OnLegacyFetchEvent(
int /* embedded_worker_id */,
- int /* fetch_event_id */,
const ServiceWorkerFetchRequest& /* request */,
mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
@@ -915,12 +926,13 @@ class StreamResponder : public EmbeddedWorkerTestHelper {
ASSERT_FALSE(stream_handle_.is_null());
response_callback->OnResponseStream(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
network::mojom::FetchResponseType::kDefault, MakeHeaders(), "", 0,
- nullptr /* blob */, blink::kWebServiceWorkerResponseErrorUnknown,
- base::Time(), false /* response_is_in_cache_storage */,
+ nullptr /* blob */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time(),
+ false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
std::move(stream_handle_), base::Time::Now());
std::move(finish_callback)
@@ -938,7 +950,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse) {
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
mojo::DataPipe data_pipe;
SetUpWithHelper(
- base::MakeUnique<StreamResponder>(mojo::MakeRequest(&stream_callback),
+ std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
std::move(data_pipe.consumer_handle)));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -991,7 +1003,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_ConsecutiveRead) {
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
mojo::DataPipe data_pipe;
SetUpWithHelper(
- base::MakeUnique<StreamResponder>(mojo::MakeRequest(&stream_callback),
+ std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
std::move(data_pipe.consumer_handle)));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1041,7 +1053,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponseAndCancel) {
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
mojo::DataPipe data_pipe;
SetUpWithHelper(
- base::MakeUnique<StreamResponder>(mojo::MakeRequest(&stream_callback),
+ std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
std::move(data_pipe.consumer_handle)));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1094,7 +1106,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_Abort) {
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
mojo::DataPipe data_pipe;
SetUpWithHelper(
- base::MakeUnique<StreamResponder>(mojo::MakeRequest(&stream_callback),
+ std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
std::move(data_pipe.consumer_handle)));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1148,7 +1160,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_AbortBeforeData) {
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
mojo::DataPipe data_pipe;
SetUpWithHelper(
- base::MakeUnique<StreamResponder>(mojo::MakeRequest(&stream_callback),
+ std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
std::move(data_pipe.consumer_handle)));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1202,7 +1214,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_AbortAfterData) {
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
mojo::DataPipe data_pipe;
SetUpWithHelper(
- base::MakeUnique<StreamResponder>(mojo::MakeRequest(&stream_callback),
+ std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
std::move(data_pipe.consumer_handle)));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1240,7 +1252,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, StreamResponse_ConsecutiveReadAndAbort) {
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
mojo::DataPipe data_pipe;
SetUpWithHelper(
- base::MakeUnique<StreamResponder>(mojo::MakeRequest(&stream_callback),
+ std::make_unique<StreamResponder>(mojo::MakeRequest(&stream_callback),
std::move(data_pipe.consumer_handle)));
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1294,9 +1306,8 @@ class FailFetchHelper : public EmbeddedWorkerTestHelper {
~FailFetchHelper() override {}
protected:
- void OnFetchEvent(
+ void OnLegacyFetchEvent(
int embedded_worker_id,
- int /* fetch_event_id */,
const ServiceWorkerFetchRequest& /* request */,
mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr /* response_callback */,
@@ -1313,7 +1324,7 @@ class FailFetchHelper : public EmbeddedWorkerTestHelper {
};
TEST_F(ServiceWorkerURLRequestJobTest, FailFetchDispatch) {
- SetUpWithHelper(base::MakeUnique<FailFetchHelper>());
+ SetUpWithHelper(std::make_unique<FailFetchHelper>());
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
request_ = url_request_context_.CreateRequest(
@@ -1342,7 +1353,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, FailFetchDispatch) {
}
TEST_F(ServiceWorkerURLRequestJobTest, FailToActivate_MainResource) {
- SetUpWithHelper(base::MakeUnique<EmbeddedWorkerTestHelper>(base::FilePath()));
+ SetUpWithHelper(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
RunFailToActivateTest(RESOURCE_TYPE_MAIN_FRAME);
// The load should fail and we should have fallen back to network because
@@ -1359,7 +1370,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, FailToActivate_MainResource) {
}
TEST_F(ServiceWorkerURLRequestJobTest, FailToActivate_Subresource) {
- SetUpWithHelper(base::MakeUnique<EmbeddedWorkerTestHelper>(base::FilePath()));
+ SetUpWithHelper(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
RunFailToActivateTest(RESOURCE_TYPE_IMAGE);
// The load should fail and we should not fall back to network because
@@ -1388,9 +1399,8 @@ class EarlyResponseHelper : public EmbeddedWorkerTestHelper {
}
protected:
- void OnFetchEvent(
+ void OnLegacyFetchEvent(
int /* embedded_worker_id */,
- int /* fetch_event_id */,
const ServiceWorkerFetchRequest& /* request */,
mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
@@ -1399,13 +1409,14 @@ class EarlyResponseHelper : public EmbeddedWorkerTestHelper {
finish_callback_ = std::move(finish_callback);
response_callback->OnResponse(
ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), std::string(), 0,
- nullptr /* blob */, blink::kWebServiceWorkerResponseErrorUnknown,
- base::Time(), false /* response_is_in_cache_storage */,
+ std::make_unique<ServiceWorkerHeaderMap>(), std::string(), 0,
+ nullptr /* blob */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time(),
+ false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
+ std::make_unique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
base::Time::Now());
}
@@ -1419,7 +1430,7 @@ class EarlyResponseHelper : public EmbeddedWorkerTestHelper {
// This simulates the case when a response is returned and the fetch event is
// still in flight.
TEST_F(ServiceWorkerURLRequestJobTest, EarlyResponse) {
- SetUpWithHelper(base::MakeUnique<EarlyResponseHelper>());
+ SetUpWithHelper(std::make_unique<EarlyResponseHelper>());
EarlyResponseHelper* helper =
static_cast<EarlyResponseHelper*>(helper_.get());
@@ -1448,7 +1459,7 @@ TEST_F(ServiceWorkerURLRequestJobTest, EarlyResponse) {
// Test cancelling the URLRequest while the fetch event is in flight.
TEST_F(ServiceWorkerURLRequestJobTest, CancelRequest) {
- SetUpWithHelper(base::MakeUnique<DelayHelper>(this));
+ SetUpWithHelper(std::make_unique<DelayHelper>(this));
DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());
// Start the URL request. The job will be waiting for the
diff --git a/chromium/content/browser/service_worker/service_worker_version.cc b/chromium/content/browser/service_worker/service_worker_version.cc
index 6ac6413ba67..4afa86ae0d8 100644
--- a/chromium/content/browser/service_worker/service_worker_version.cc
+++ b/chromium/content/browser/service_worker/service_worker_version.cc
@@ -46,7 +46,9 @@
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "third_party/WebKit/common/origin_trials/trial_token_validator.h"
+#include "third_party/WebKit/common/service_worker/service_worker_client.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
namespace content {
@@ -119,7 +121,7 @@ void RunTaskAfterStartWorker(base::WeakPtr<ServiceWorkerVersion> version,
std::move(task).Run();
}
-void KillEmbeddedWorkerProcess(int process_id, ResultCode code) {
+void KillEmbeddedWorkerProcess(int process_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHost* render_process_host =
RenderProcessHost::FromID(process_id);
@@ -282,22 +284,23 @@ ServiceWorkerVersion::ServiceWorkerVersion(
: version_id_(version_id),
registration_id_(registration->id()),
script_url_(script_url),
+ script_origin_(url::Origin::Create(script_url_)),
scope_(registration->pattern()),
fetch_handler_existence_(FetchHandlerExistence::UNKNOWN),
site_for_uma_(ServiceWorkerMetrics::SiteFromURL(scope_)),
+ binding_(this),
context_(context),
script_cache_map_(this, context),
- tick_clock_(base::MakeUnique<base::DefaultTickClock>()),
- clock_(base::MakeUnique<base::DefaultClock>()),
+ tick_clock_(base::DefaultTickClock::GetInstance()),
+ clock_(base::DefaultClock::GetInstance()),
ping_controller_(new PingController(this)),
- validator_(base::MakeUnique<blink::TrialTokenValidator>(
- base::MakeUnique<TrialPolicyImpl>())),
+ validator_(TrialPolicyImpl::CreateValidatorForPolicy()),
weak_factory_(this) {
- DCHECK_NE(kInvalidServiceWorkerVersionId, version_id);
+ DCHECK_NE(blink::mojom::kInvalidServiceWorkerVersionId, version_id);
DCHECK(context_);
DCHECK(registration);
DCHECK(script_url_.is_valid());
- embedded_worker_ = context_->embedded_worker_registry()->CreateWorker();
+ embedded_worker_ = context_->embedded_worker_registry()->CreateWorker(this);
embedded_worker_->AddListener(this);
context_->AddLiveVersion(this);
}
@@ -325,7 +328,7 @@ ServiceWorkerVersion::~ServiceWorkerVersion() {
}
void ServiceWorkerVersion::SetNavigationPreloadState(
- const NavigationPreloadState& state) {
+ const blink::mojom::NavigationPreloadState& state) {
navigation_preload_state_ = state;
}
@@ -363,7 +366,7 @@ void ServiceWorkerVersion::SetStatus(Status status) {
// Resolve skip waiting promises.
ClearTick(&skip_waiting_time_);
for (int request_id : pending_skip_waiting_requests_) {
- embedded_worker_->SendMessage(
+ embedded_worker_->SendIpcMessage(
ServiceWorkerMsg_DidSkipWaiting(request_id));
}
pending_skip_waiting_requests_.clear();
@@ -572,16 +575,23 @@ int ServiceWorkerVersion::StartRequestWithCustomTimeout(
<< "Event of type " << static_cast<int>(event_type)
<< " can only be dispatched to an active worker: " << status();
- int request_id = pending_requests_.Add(
- base::MakeUnique<PendingRequest>(std::move(error_callback), clock_->Now(),
- tick_clock_->NowTicks(), event_type));
+ auto request =
+ std::make_unique<PendingRequest>(std::move(error_callback), clock_->Now(),
+ tick_clock_->NowTicks(), event_type);
+ PendingRequest* request_rawptr = request.get();
+ int request_id = pending_requests_.Add(std::move(request));
TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker", "ServiceWorkerVersion::Request",
- pending_requests_.Lookup(request_id), "Request id",
- request_id, "Event type",
+ request_rawptr, "Request id", request_id,
+ "Event type",
ServiceWorkerMetrics::EventTypeToString(event_type));
+
base::TimeTicks expiration_time = tick_clock_->NowTicks() + timeout;
- timeout_queue_.push(
- RequestInfo(request_id, event_type, expiration_time, timeout_behavior));
+ bool is_inserted = false;
+ std::set<RequestInfo>::iterator iter;
+ std::tie(iter, is_inserted) = request_timeouts_.emplace(
+ request_id, event_type, expiration_time, timeout_behavior);
+ DCHECK(is_inserted);
+ request_rawptr->timeout_iter = iter;
if (expiration_time > max_request_expiration_time_)
max_request_expiration_time_ = expiration_time;
return request_id;
@@ -623,6 +633,7 @@ bool ServiceWorkerVersion::FinishRequest(int request_id,
RestartTick(&idle_time_);
TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
request, "Handled", was_handled);
+ request_timeouts_.erase(request->timeout_iter);
pending_requests_.Remove(request_id);
if (!HasWork()) {
for (auto& observer : listeners_)
@@ -670,9 +681,9 @@ void ServiceWorkerVersion::RunAfterStartWorker(
std::move(task).Run();
return;
}
- StartWorker(purpose, base::AdaptCallbackForRepeating(base::BindOnce(
+ StartWorker(purpose, base::BindOnce(
&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
- std::move(error_callback), std::move(task))));
+ std::move(error_callback), std::move(task)));
}
void ServiceWorkerVersion::AddControllee(
@@ -773,8 +784,8 @@ void ServiceWorkerVersion::Doom() {
void ServiceWorkerVersion::SetValidOriginTrialTokens(
const blink::TrialTokenValidator::FeatureToTokensMap& tokens) {
- origin_trial_tokens_ =
- validator_->GetValidTokens(url::Origin(scope()), tokens, clock_->Now());
+ origin_trial_tokens_ = validator_->GetValidTokens(
+ url::Origin::Create(scope()), tokens, clock_->Now());
}
void ServiceWorkerVersion::SetDevToolsAttached(bool attached) {
@@ -826,7 +837,7 @@ void ServiceWorkerVersion::SetMainScriptHttpResponseInfo(
// wasn't set in the entry.
if (!origin_trial_tokens_) {
origin_trial_tokens_ = validator_->GetValidTokensFromHeaders(
- url::Origin(scope()), http_info.headers.get(), clock_->Now());
+ url::Origin::Create(scope()), http_info.headers.get(), clock_->Now());
}
for (auto& observer : listeners_)
@@ -837,14 +848,12 @@ void ServiceWorkerVersion::SimulatePingTimeoutForTesting() {
ping_controller_->SimulateTimeoutForTesting();
}
-void ServiceWorkerVersion::SetTickClockForTesting(
- std::unique_ptr<base::TickClock> tick_clock) {
- tick_clock_ = std::move(tick_clock);
+void ServiceWorkerVersion::SetTickClockForTesting(base::TickClock* tick_clock) {
+ tick_clock_ = tick_clock;
}
-void ServiceWorkerVersion::SetClockForTesting(
- std::unique_ptr<base::Clock> clock) {
- clock_ = std::move(clock);
+void ServiceWorkerVersion::SetClockForTesting(base::Clock* clock) {
+ clock_ = clock;
}
const net::HttpResponseInfo*
@@ -865,9 +874,11 @@ ServiceWorkerVersion::RequestInfo::RequestInfo(
ServiceWorkerVersion::RequestInfo::~RequestInfo() {
}
-bool ServiceWorkerVersion::RequestInfo::operator>(
+bool ServiceWorkerVersion::RequestInfo::operator<(
const RequestInfo& other) const {
- return expiration > other.expiration;
+ if (expiration == other.expiration)
+ return id < other.id;
+ return expiration < other.expiration;
}
ServiceWorkerVersion::PendingRequest::PendingRequest(
@@ -988,10 +999,6 @@ bool ServiceWorkerVersion::OnMessageReceived(const IPC::Message& message) {
OnGetClients)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenNewTab, OnOpenNewTab)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenNewPopup, OnOpenNewPopup)
- IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetCachedMetadata,
- OnSetCachedMetadata)
- IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClearCachedMetadata,
- OnClearCachedMetadata)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToClient,
OnPostMessageToClient)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient,
@@ -1014,6 +1021,47 @@ void ServiceWorkerVersion::OnStartSentAndScriptEvaluated(
}
}
+void ServiceWorkerVersion::SetCachedMetadata(const GURL& url,
+ const std::vector<uint8_t>& data) {
+ int64_t callback_id = tick_clock_->NowTicks().ToInternalValue();
+ TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
+ "ServiceWorkerVersion::SetCachedMetadata",
+ callback_id, "URL", url.spec());
+ script_cache_map_.WriteMetadata(
+ url, data,
+ base::Bind(&ServiceWorkerVersion::OnSetCachedMetadataFinished,
+ weak_factory_.GetWeakPtr(), callback_id, data.size()));
+}
+
+void ServiceWorkerVersion::ClearCachedMetadata(const GURL& url) {
+ int64_t callback_id = tick_clock_->NowTicks().ToInternalValue();
+ TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
+ "ServiceWorkerVersion::ClearCachedMetadata",
+ callback_id, "URL", url.spec());
+ script_cache_map_.ClearMetadata(
+ url, base::Bind(&ServiceWorkerVersion::OnClearCachedMetadataFinished,
+ weak_factory_.GetWeakPtr(), callback_id));
+}
+
+void ServiceWorkerVersion::OnSetCachedMetadataFinished(int64_t callback_id,
+ size_t size,
+ int result) {
+ TRACE_EVENT_ASYNC_END1("ServiceWorker",
+ "ServiceWorkerVersion::SetCachedMetadata", callback_id,
+ "result", result);
+ for (auto& listener : listeners_)
+ listener.OnCachedMetadataUpdated(this, size);
+}
+
+void ServiceWorkerVersion::OnClearCachedMetadataFinished(int64_t callback_id,
+ int result) {
+ TRACE_EVENT_ASYNC_END1("ServiceWorker",
+ "ServiceWorkerVersion::ClearCachedMetadata",
+ callback_id, "result", result);
+ for (auto& listener : listeners_)
+ listener.OnCachedMetadataUpdated(this, 0);
+}
+
void ServiceWorkerVersion::OnGetClient(int request_id,
const std::string& client_uuid) {
if (!context_)
@@ -1037,8 +1085,10 @@ void ServiceWorkerVersion::OnGetClientFinished(
int request_id,
const ServiceWorkerClientInfo& client_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::OnGetClient",
- request_id, "client_type", client_info.client_type);
+ TRACE_EVENT_ASYNC_END1(
+ "ServiceWorker", "ServiceWorkerVersion::OnGetClient", request_id,
+ "client_type",
+ ServiceWorkerUtils::ClientTypeToString(client_info.client_type));
// When Clients.get() is called on the script evaluation phase, the running
// status can be STARTING here.
@@ -1047,7 +1097,7 @@ void ServiceWorkerVersion::OnGetClientFinished(
return;
}
- embedded_worker_->SendMessage(
+ embedded_worker_->SendIpcMessage(
ServiceWorkerMsg_DidGetClient(request_id, client_info));
}
@@ -1056,8 +1106,9 @@ void ServiceWorkerVersion::OnGetClients(
const ServiceWorkerClientQueryOptions& options) {
TRACE_EVENT_ASYNC_BEGIN2(
"ServiceWorker", "ServiceWorkerVersion::OnGetClients", request_id,
- "client_type", options.client_type, "include_uncontrolled",
- options.include_uncontrolled);
+ "client_type",
+ ServiceWorkerUtils::ClientTypeToString(options.client_type),
+ "include_uncontrolled", options.include_uncontrolled);
service_worker_client_utils::GetClients(
weak_factory_.GetWeakPtr(), options,
base::Bind(&ServiceWorkerVersion::OnGetClientsFinished,
@@ -1078,7 +1129,7 @@ void ServiceWorkerVersion::OnGetClientsFinished(
return;
}
- embedded_worker_->SendMessage(
+ embedded_worker_->SendIpcMessage(
ServiceWorkerMsg_DidGetClients(request_id, *clients));
}
@@ -1141,8 +1192,7 @@ void ServiceWorkerVersion::OnOpenWindow(int request_id,
DVLOG(1) << "Received unexpected invalid URL from renderer process.";
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(&KillEmbeddedWorkerProcess,
- embedded_worker_->process_id(),
- RESULT_CODE_KILLED_BAD_MESSAGE));
+ embedded_worker_->process_id()));
return;
}
@@ -1157,7 +1207,7 @@ void ServiceWorkerVersion::OnOpenWindow(int request_id,
// filtered out by Blink.
if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL(
embedded_worker_->process_id(), url)) {
- embedded_worker_->SendMessage(ServiceWorkerMsg_OpenWindowError(
+ embedded_worker_->SendIpcMessage(ServiceWorkerMsg_OpenWindowError(
request_id, url.spec() + " cannot be opened."));
return;
}
@@ -1178,54 +1228,15 @@ void ServiceWorkerVersion::OnOpenWindowFinished(
return;
if (status != SERVICE_WORKER_OK) {
- embedded_worker_->SendMessage(ServiceWorkerMsg_OpenWindowError(
+ embedded_worker_->SendIpcMessage(ServiceWorkerMsg_OpenWindowError(
request_id, "Something went wrong while trying to open the window."));
return;
}
- embedded_worker_->SendMessage(
+ embedded_worker_->SendIpcMessage(
ServiceWorkerMsg_OpenWindowResponse(request_id, client_info));
}
-void ServiceWorkerVersion::OnSetCachedMetadata(const GURL& url,
- const std::vector<char>& data) {
- int64_t callback_id = tick_clock_->NowTicks().ToInternalValue();
- TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
- "ServiceWorkerVersion::OnSetCachedMetadata",
- callback_id, "URL", url.spec());
- script_cache_map_.WriteMetadata(
- url, data, base::Bind(&ServiceWorkerVersion::OnSetCachedMetadataFinished,
- weak_factory_.GetWeakPtr(), callback_id));
-}
-
-void ServiceWorkerVersion::OnSetCachedMetadataFinished(int64_t callback_id,
- int result) {
- TRACE_EVENT_ASYNC_END1("ServiceWorker",
- "ServiceWorkerVersion::OnSetCachedMetadata",
- callback_id, "result", result);
- for (auto& observer : listeners_)
- observer.OnCachedMetadataUpdated(this);
-}
-
-void ServiceWorkerVersion::OnClearCachedMetadata(const GURL& url) {
- int64_t callback_id = tick_clock_->NowTicks().ToInternalValue();
- TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
- "ServiceWorkerVersion::OnClearCachedMetadata",
- callback_id, "URL", url.spec());
- script_cache_map_.ClearMetadata(
- url, base::Bind(&ServiceWorkerVersion::OnClearCachedMetadataFinished,
- weak_factory_.GetWeakPtr(), callback_id));
-}
-
-void ServiceWorkerVersion::OnClearCachedMetadataFinished(int64_t callback_id,
- int result) {
- TRACE_EVENT_ASYNC_END1("ServiceWorker",
- "ServiceWorkerVersion::OnClearCachedMetadata",
- callback_id, "result", result);
- for (auto& observer : listeners_)
- observer.OnCachedMetadataUpdated(this);
-}
-
void ServiceWorkerVersion::OnPostMessageToClient(
const std::string& client_uuid,
const base::string16& message,
@@ -1269,7 +1280,7 @@ void ServiceWorkerVersion::OnFocusClient(int request_id,
return;
}
if (provider_host->client_type() !=
- blink::kWebServiceWorkerClientTypeWindow) {
+ blink::mojom::ServiceWorkerClientType::kWindow) {
// focus() should be called only for WindowClient. This may happen due to
// bad message.
return;
@@ -1288,7 +1299,7 @@ void ServiceWorkerVersion::OnFocusClientFinished(
if (running_status() != EmbeddedWorkerStatus::RUNNING)
return;
- embedded_worker_->SendMessage(
+ embedded_worker_->SendIpcMessage(
ServiceWorkerMsg_FocusClientResponse(request_id, client_info));
}
@@ -1305,8 +1316,7 @@ void ServiceWorkerVersion::OnNavigateClient(int request_id,
DVLOG(1) << "Received unexpected invalid URL/UUID from renderer process.";
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(&KillEmbeddedWorkerProcess,
- embedded_worker_->process_id(),
- RESULT_CODE_KILLED_BAD_MESSAGE));
+ embedded_worker_->process_id()));
return;
}
@@ -1316,7 +1326,7 @@ void ServiceWorkerVersion::OnNavigateClient(int request_id,
// filtered out by Blink.
if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL(
embedded_worker_->process_id(), url)) {
- embedded_worker_->SendMessage(
+ embedded_worker_->SendIpcMessage(
ServiceWorkerMsg_NavigateClientError(request_id, url));
return;
}
@@ -1324,7 +1334,7 @@ void ServiceWorkerVersion::OnNavigateClient(int request_id,
ServiceWorkerProviderHost* provider_host =
context_->GetProviderHostByClientID(client_uuid);
if (!provider_host || provider_host->active_version() != this) {
- embedded_worker_->SendMessage(
+ embedded_worker_->SendIpcMessage(
ServiceWorkerMsg_NavigateClientError(request_id, url));
return;
}
@@ -1345,12 +1355,12 @@ void ServiceWorkerVersion::OnNavigateClientFinished(
return;
if (status != SERVICE_WORKER_OK) {
- embedded_worker_->SendMessage(
+ embedded_worker_->SendIpcMessage(
ServiceWorkerMsg_NavigateClientError(request_id, GURL()));
return;
}
- embedded_worker_->SendMessage(
+ embedded_worker_->SendIpcMessage(
ServiceWorkerMsg_NavigateClientResponse(request_id, client_info));
}
@@ -1365,7 +1375,8 @@ void ServiceWorkerVersion::OnSkipWaiting(int request_id) {
// activation. In that case, it's a slight spec violation to not resolve now,
// but we'll eventually resolve the promise in SetStatus().
if (status_ != INSTALLED) {
- embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id));
+ embedded_worker_->SendIpcMessage(
+ ServiceWorkerMsg_DidSkipWaiting(request_id));
return;
}
@@ -1384,7 +1395,7 @@ void ServiceWorkerVersion::OnSkipWaiting(int request_id) {
void ServiceWorkerVersion::OnClaimClients(int request_id) {
if (status_ != ACTIVATING && status_ != ACTIVATED) {
- embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError(
+ embedded_worker_->SendIpcMessage(ServiceWorkerMsg_ClaimClientsError(
request_id, blink::mojom::ServiceWorkerErrorType::kState,
base::ASCIIToUTF16(kClaimClientsStateErrorMesage)));
return;
@@ -1393,13 +1404,13 @@ void ServiceWorkerVersion::OnClaimClients(int request_id) {
if (ServiceWorkerRegistration* registration =
context_->GetLiveRegistration(registration_id_)) {
registration->ClaimClients();
- embedded_worker_->SendMessage(
+ embedded_worker_->SendIpcMessage(
ServiceWorkerMsg_DidClaimClients(request_id));
return;
}
}
- embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError(
+ embedded_worker_->SendIpcMessage(ServiceWorkerMsg_ClaimClientsError(
request_id, blink::mojom::ServiceWorkerErrorType::kAbort,
base::ASCIIToUTF16(kClaimClientsShutdownErrorMesage)));
}
@@ -1408,40 +1419,6 @@ void ServiceWorkerVersion::OnPongFromWorker() {
ping_controller_->OnPongReceived();
}
-void ServiceWorkerVersion::RegisterForeignFetchScopes(
- const std::vector<GURL>& sub_scopes,
- const std::vector<url::Origin>& origins) {
- DCHECK(status() == INSTALLING || status() == REDUNDANT) << status();
- // Renderer should have already verified all these urls are inside the
- // worker's scope, but verify again here on the browser process side.
- GURL origin = scope_.GetOrigin();
- std::string scope_path = scope_.path();
- for (const GURL& url : sub_scopes) {
- if (!url.is_valid() || url.GetOrigin() != origin ||
- !base::StartsWith(url.path(), scope_path,
- base::CompareCase::SENSITIVE)) {
- DVLOG(1) << "Received unexpected invalid URL from renderer process.";
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&KillEmbeddedWorkerProcess,
- embedded_worker_->process_id(),
- RESULT_CODE_KILLED_BAD_MESSAGE));
- return;
- }
- }
- for (const url::Origin& url : origins) {
- if (url.unique()) {
- DVLOG(1) << "Received unexpected unique origin from renderer process.";
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&KillEmbeddedWorkerProcess,
- embedded_worker_->process_id(),
- RESULT_CODE_KILLED_BAD_MESSAGE));
- return;
- }
- }
- set_foreign_fetch_scopes(sub_scopes);
- set_foreign_fetch_origins(origins);
-}
-
void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
ServiceWorkerMetrics::EventType purpose,
Status prestart_status,
@@ -1518,12 +1495,14 @@ void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
void ServiceWorkerVersion::StartWorkerInternal() {
DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, running_status());
+ DCHECK(pending_requests_.IsEmpty());
+ DCHECK(request_timeouts_.empty());
DCHECK(start_worker_first_purpose_);
if (!ServiceWorkerMetrics::ShouldExcludeSiteFromHistogram(site_for_uma_)) {
DCHECK(!event_recorder_);
event_recorder_ =
- base::MakeUnique<ServiceWorkerMetrics::ScopedEventRecorder>(
+ std::make_unique<ServiceWorkerMetrics::ScopedEventRecorder>(
start_worker_first_purpose_.value());
}
// We don't clear |start_worker_first_purpose_| here but clear in
@@ -1536,7 +1515,7 @@ void ServiceWorkerVersion::StartWorkerInternal() {
ServiceWorkerProviderHost::PreCreateForController(context());
provider_host_ = pending_provider_host->AsWeakPtr();
- auto params = base::MakeUnique<EmbeddedWorkerStartParams>();
+ auto params = std::make_unique<EmbeddedWorkerStartParams>();
params->service_worker_version_id = version_id_;
params->scope = scope_;
params->script_url = script_url_;
@@ -1548,7 +1527,7 @@ void ServiceWorkerVersion::StartWorkerInternal() {
!pause_after_download_) {
DCHECK(!installed_scripts_sender_);
installed_scripts_sender_ =
- base::MakeUnique<ServiceWorkerInstalledScriptsSender>(this);
+ std::make_unique<ServiceWorkerInstalledScriptsSender>(this);
installed_scripts_info = installed_scripts_sender_->CreateInfoAndBind();
installed_scripts_sender_->Start();
}
@@ -1558,13 +1537,19 @@ void ServiceWorkerVersion::StartWorkerInternal() {
CHECK(event_dispatcher_.is_bound());
CHECK(event_dispatcher_request.is_pending());
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host_ptr_info;
+ binding_.Close();
+ binding_.Bind(mojo::MakeRequest(&service_worker_host_ptr_info));
+
embedded_worker_->Start(
std::move(params),
// Unretained is used here because the callback will be owned by
// |embedded_worker_| whose owner is |this|.
base::BindOnce(&CompleteProviderHostPreparation, base::Unretained(this),
std::move(pending_provider_host), context()),
- mojo::MakeRequest(&event_dispatcher_), std::move(installed_scripts_info),
+ mojo::MakeRequest(&event_dispatcher_),
+ mojo::MakeRequest(&controller_ptr_), std::move(installed_scripts_info),
+ std::move(service_worker_host_ptr_info),
base::BindOnce(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated,
weak_factory_.GetWeakPtr()));
event_dispatcher_.set_connection_error_handler(base::BindOnce(
@@ -1615,9 +1600,10 @@ void ServiceWorkerVersion::SetTimeoutTimerInterval(base::TimeDelta interval) {
}
void ServiceWorkerVersion::OnTimeoutTimer() {
- DCHECK(running_status() == EmbeddedWorkerStatus::STARTING ||
- running_status() == EmbeddedWorkerStatus::RUNNING ||
- running_status() == EmbeddedWorkerStatus::STOPPING)
+ // TODO(horo): This CHECK is for debugging crbug.com/759938.
+ CHECK(running_status() == EmbeddedWorkerStatus::STARTING ||
+ running_status() == EmbeddedWorkerStatus::RUNNING ||
+ running_status() == EmbeddedWorkerStatus::STOPPING)
<< static_cast<int>(running_status());
if (!context_)
@@ -1642,7 +1628,7 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
scoped_refptr<ServiceWorkerVersion> protect_this(this);
embedded_worker_->RemoveListener(this);
embedded_worker_->Detach();
- embedded_worker_ = context_->embedded_worker_registry()->CreateWorker();
+ embedded_worker_ = context_->embedded_worker_registry()->CreateWorker(this);
embedded_worker_->AddListener(this);
// Call OnStoppedInternal to fail callbacks and possibly restart.
@@ -1675,8 +1661,9 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
// Requests have not finished before their expiration.
bool stop_for_timeout = false;
- while (!timeout_queue_.empty()) {
- RequestInfo info = timeout_queue_.top();
+ auto timeout_iter = request_timeouts_.begin();
+ while (timeout_iter != request_timeouts_.end()) {
+ const RequestInfo& info = *timeout_iter;
if (!RequestExpired(info.expiration))
break;
if (MaybeTimeOutRequest(info)) {
@@ -1684,7 +1671,7 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
stop_for_timeout || info.timeout_behavior == KILL_ON_TIMEOUT;
ServiceWorkerMetrics::RecordEventTimeout(info.event_type);
}
- timeout_queue_.pop();
+ timeout_iter = request_timeouts_.erase(timeout_iter);
}
if (stop_for_timeout && running_status() != EmbeddedWorkerStatus::STOPPING)
embedded_worker_->Stop();
@@ -1695,7 +1682,10 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
return;
// The worker has been idle for longer than a certain period.
- if (GetTickDuration(idle_time_) > kIdleWorkerTimeout) {
+ // S13nServiceWorker: The idle timer is implemented on the renderer, so we can
+ // skip this check.
+ if (!ServiceWorkerUtils::IsServicificationEnabled() &&
+ GetTickDuration(idle_time_) > kIdleWorkerTimeout) {
StopWorkerIfIdle();
return;
}
@@ -1705,8 +1695,9 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
}
void ServiceWorkerVersion::PingWorker() {
- DCHECK(running_status() == EmbeddedWorkerStatus::STARTING ||
- running_status() == EmbeddedWorkerStatus::RUNNING);
+ // TODO(horo): This CHECK is for debugging crbug.com/759938.
+ CHECK(running_status() == EmbeddedWorkerStatus::STARTING ||
+ running_status() == EmbeddedWorkerStatus::RUNNING);
// base::Unretained here is safe because event_dispatcher is owned by |this|.
event_dispatcher()->Ping(base::BindOnce(
&ServiceWorkerVersion::OnPongFromWorker, base::Unretained(this)));
@@ -1722,15 +1713,18 @@ void ServiceWorkerVersion::OnPingTimeout() {
}
void ServiceWorkerVersion::StopWorkerIfIdle() {
- if (HasWork() && !ping_controller_->IsTimedOut())
- return;
if (running_status() == EmbeddedWorkerStatus::STOPPED ||
running_status() == EmbeddedWorkerStatus::STOPPING ||
!stop_callbacks_.empty()) {
return;
}
- embedded_worker_->StopIfIdle();
+ // 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() && HasWork())
+ return;
+ embedded_worker_->StopIfNotAttachedToDevTools();
}
bool ServiceWorkerVersion::HasWork() const {
@@ -1757,7 +1751,7 @@ void ServiceWorkerVersion::RecordStartWorkerResult(
if (installed_scripts_sender_) {
ServiceWorkerMetrics::RecordInstalledScriptsSenderStatus(
- installed_scripts_sender_->finished_reason());
+ installed_scripts_sender_->last_finished_reason());
}
ServiceWorkerMetrics::RecordStartWorkerStatus(status, purpose,
IsInstalled(prestart_status));
@@ -1807,14 +1801,18 @@ bool ServiceWorkerVersion::MaybeTimeOutRequest(const RequestInfo& info) {
void ServiceWorkerVersion::SetAllRequestExpirations(
const base::TimeTicks& expiration) {
- RequestInfoPriorityQueue new_requests;
- while (!timeout_queue_.empty()) {
- RequestInfo info = timeout_queue_.top();
- info.expiration = expiration;
- new_requests.push(info);
- timeout_queue_.pop();
+ std::set<RequestInfo> new_timeouts;
+ for (const auto& info : request_timeouts_) {
+ bool is_inserted = false;
+ std::set<RequestInfo>::iterator iter;
+ std::tie(iter, is_inserted) = new_timeouts.emplace(
+ info.id, info.event_type, expiration, info.timeout_behavior);
+ DCHECK(is_inserted);
+ PendingRequest* request = pending_requests_.Lookup(info.id);
+ DCHECK(request);
+ request->timeout_iter = iter;
}
- timeout_queue_ = new_requests;
+ request_timeouts_.swap(new_timeouts);
}
ServiceWorkerStatusCode ServiceWorkerVersion::DeduceStartWorkerFailureReason(
@@ -1828,6 +1826,8 @@ ServiceWorkerStatusCode ServiceWorkerVersion::DeduceStartWorkerFailureReason(
const net::URLRequestStatus& main_script_status =
script_cache_map()->main_script_status();
if (main_script_status.status() != net::URLRequestStatus::SUCCESS) {
+ if (net::IsCertificateError(main_script_status.error()))
+ return SERVICE_WORKER_ERROR_SECURITY;
switch (main_script_status.error()) {
case net::ERR_INSECURE_RESPONSE:
case net::ERR_UNSAFE_REDIRECT:
@@ -1933,9 +1933,12 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) {
iter.Advance();
}
pending_requests_.Clear();
+ request_timeouts_.clear();
external_request_uuid_to_request_id_.clear();
event_dispatcher_.reset();
+ controller_ptr_.reset();
installed_scripts_sender_.reset();
+ binding_.Close();
for (auto& observer : listeners_)
observer.OnRunningStateChanged(this);
diff --git a/chromium/content/browser/service_worker/service_worker_version.h b/chromium/content/browser/service_worker/service_worker_version.h
index 139da206ace..6ca616bb271 100644
--- a/chromium/content/browser/service_worker/service_worker_version.h
+++ b/chromium/content/browser/service_worker/service_worker_version.h
@@ -10,7 +10,6 @@
#include <functional>
#include <map>
#include <memory>
-#include <queue>
#include <set>
#include <string>
#include <utility>
@@ -35,6 +34,7 @@
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_script_cache_map.h"
#include "content/common/content_export.h"
+#include "content/common/service_worker/controller_service_worker.mojom.h"
#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
@@ -42,6 +42,7 @@
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/WebKit/common/origin_trials/trial_token_validator.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
#include "ui/base/mojo/window_open_disposition.mojom.h"
#include "url/gurl.h"
@@ -69,8 +70,11 @@ struct ServiceWorkerVersionInfo;
// more than one ServiceWorkerVersion "running" at a time, but only
// one of them is activated. This class connects the actual script with a
// running worker.
+//
+// Unless otherwise noted, all methods of this class run on the IO thread.
class CONTENT_EXPORT ServiceWorkerVersion
- : public base::RefCounted<ServiceWorkerVersion>,
+ : public blink::mojom::ServiceWorkerHost,
+ public base::RefCounted<ServiceWorkerVersion>,
public EmbeddedWorkerInstance::Listener {
public:
// TODO(crbug.com/755477): LegacyStatusCallback which does not use
@@ -131,7 +135,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
}
virtual void OnNoControllees(ServiceWorkerVersion* version) {}
virtual void OnNoWork(ServiceWorkerVersion* version) {}
- virtual void OnCachedMetadataUpdated(ServiceWorkerVersion* version) {}
+ virtual void OnCachedMetadataUpdated(ServiceWorkerVersion* version,
+ size_t size) {}
protected:
virtual ~Listener() {}
@@ -145,6 +150,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
int64_t version_id() const { return version_id_; }
int64_t registration_id() const { return registration_id_; }
const GURL& script_url() const { return script_url_; }
+ const url::Origin& script_origin() const { return script_origin_; }
const GURL& scope() const { return scope_; }
EmbeddedWorkerStatus running_status() const {
return embedded_worker_->status();
@@ -161,20 +167,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
// This also updates |site_for_uma_| when it was Site::OTHER.
void set_fetch_handler_existence(FetchHandlerExistence existence);
- const std::vector<GURL>& foreign_fetch_scopes() const {
- return foreign_fetch_scopes_;
- }
- void set_foreign_fetch_scopes(const std::vector<GURL>& scopes) {
- foreign_fetch_scopes_ = scopes;
- }
-
- const std::vector<url::Origin>& foreign_fetch_origins() const {
- return foreign_fetch_origins_;
- }
- void set_foreign_fetch_origins(const std::vector<url::Origin>& origins) {
- foreign_fetch_origins_ = origins;
- }
-
base::TimeDelta TimeSinceNoControllees() const {
return GetTickDuration(no_controllees_time_);
}
@@ -184,7 +176,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
}
// Meaningful only if this version is active.
- const NavigationPreloadState& navigation_preload_state() const {
+ const blink::mojom::NavigationPreloadState& navigation_preload_state() const {
DCHECK(status_ == ACTIVATING || status_ == ACTIVATED) << status_;
return navigation_preload_state_;
}
@@ -192,7 +184,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
// ServiceWorkerRegistration::EnableNavigationPreload or
// ServiceWorkerRegistration::SetNavigationPreloadHeader instead of this
// function.
- void SetNavigationPreloadState(const NavigationPreloadState& state);
+ void SetNavigationPreloadState(
+ const blink::mojom::NavigationPreloadState& state);
ServiceWorkerMetrics::Site site_for_uma() const { return site_for_uma_; }
@@ -214,6 +207,10 @@ 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.
+ void StopWorkerIfIdle();
+
// Skips waiting and forces this version to become activated.
void SkipWaitingFromDevTools();
@@ -275,9 +272,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
bool was_handled,
base::Time dispatch_event_time);
- void RegisterForeignFetchScopes(const std::vector<GURL>& sub_scopes,
- const std::vector<url::Origin>& origins);
-
// Finishes an external request that was started by StartExternalRequest().
// Returns false if there was an error finishing the request: e.g. the request
// was not found or the worker already terminated.
@@ -295,6 +289,13 @@ class CONTENT_EXPORT ServiceWorkerVersion
return event_dispatcher_.get();
}
+ // This must be called when the worker is running.
+ // Returns the 'controller' interface of this worker.
+ mojom::ControllerServiceWorker* controller() {
+ DCHECK(controller_ptr_.is_bound());
+ return controller_ptr_.get();
+ }
+
// Adds and removes |provider_host| as a controllee of this ServiceWorker.
void AddControllee(ServiceWorkerProviderHost* provider_host);
void RemoveControllee(ServiceWorkerProviderHost* provider_host);
@@ -388,10 +389,10 @@ class CONTENT_EXPORT ServiceWorkerVersion
void SimulatePingTimeoutForTesting();
// Used to allow tests to change time for testing.
- void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
+ void SetTickClockForTesting(base::TickClock* tick_clock);
// Used to allow tests to change wall clock for testing.
- void SetClockForTesting(std::unique_ptr<base::Clock> clock);
+ void SetClockForTesting(base::Clock* clock);
// Returns true if the service worker has work to do: it has pending
// requests, in-progress streaming URLRequestJobs, or pending start callbacks.
@@ -446,11 +447,10 @@ class CONTENT_EXPORT ServiceWorkerVersion
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerStallInStoppingTest, DetachThenRestart);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerStallInStoppingTest,
DetachThenRestartNoCrash);
- FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest,
- RegisterForeignFetchScopes);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestNowTimeout);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestNowTimeoutKill);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestCustomizedTimeout);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RestartWorker);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, MixedRequestTimeouts);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, EarlyResponse);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, CancelRequest);
@@ -463,11 +463,13 @@ class CONTENT_EXPORT ServiceWorkerVersion
const base::TimeTicks& expiration,
TimeoutBehavior timeout_behavior);
~RequestInfo();
- bool operator>(const RequestInfo& other) const;
- int id;
- ServiceWorkerMetrics::EventType event_type;
- base::TimeTicks expiration;
- TimeoutBehavior timeout_behavior;
+ // Compares |expiration|, or |id| if |expiration| is the same.
+ bool operator<(const RequestInfo& other) const;
+
+ const int id;
+ const ServiceWorkerMetrics::EventType event_type;
+ const base::TimeTicks expiration;
+ const TimeoutBehavior timeout_behavior;
};
struct PendingRequest {
@@ -481,50 +483,11 @@ class CONTENT_EXPORT ServiceWorkerVersion
base::Time start_time;
base::TimeTicks start_time_ticks;
ServiceWorkerMetrics::EventType event_type;
+ // Points to this request's entry in |request_timeouts_|.
+ std::set<RequestInfo>::iterator timeout_iter;
};
using ServiceWorkerClients = std::vector<ServiceWorkerClientInfo>;
- using RequestInfoPriorityQueue =
- std::priority_queue<RequestInfo,
- std::vector<RequestInfo>,
- std::greater<RequestInfo>>;
-
- // EmbeddedWorkerInstance Listener implementation which calls a callback
- // on receiving a particular IPC message. ResponseMessage is the type of
- // the IPC message to listen for, while CallbackType should be a callback
- // with same arguments as the IPC message.
- // Additionally only calls the callback for messages with a specific request
- // id, which must be the first argument of the IPC message.
- template <typename ResponseMessage,
- typename CallbackType,
- typename Signature = typename CallbackType::RunType>
- class EventResponseHandler;
-
- template <typename ResponseMessage, typename CallbackType, typename... Args>
- class EventResponseHandler<ResponseMessage, CallbackType, void(Args...)>
- : public EmbeddedWorkerInstance::Listener {
- public:
- EventResponseHandler(const base::WeakPtr<EmbeddedWorkerInstance>& worker,
- int request_id,
- const CallbackType& callback)
- : worker_(worker), request_id_(request_id), callback_(callback) {
- worker_->AddListener(this);
- }
- ~EventResponseHandler() override {
- if (worker_)
- worker_->RemoveListener(this);
- }
- bool OnMessageReceived(const IPC::Message& message) override;
-
- private:
- void RunCallback(Args... args) {
- callback_.Run(std::forward<Args>(args)...);
- }
-
- base::WeakPtr<EmbeddedWorkerInstance> const worker_;
- const int request_id_;
- const CallbackType callback_;
- };
// The timeout timer interval.
static constexpr base::TimeDelta kTimeoutTimerDelay =
@@ -567,6 +530,16 @@ class CONTENT_EXPORT ServiceWorkerVersion
void OnStartSentAndScriptEvaluated(ServiceWorkerStatusCode status);
+ // Implements blink::mojom::ServiceWorkerHost.
+ void SetCachedMetadata(const GURL& url,
+ const std::vector<uint8_t>& data) override;
+ void ClearCachedMetadata(const GURL& url) override;
+
+ void OnSetCachedMetadataFinished(int64_t callback_id,
+ size_t size,
+ int result);
+ void OnClearCachedMetadataFinished(int64_t callback_id, int result);
+
// Message handlers.
// This corresponds to the spec's get(id) steps.
@@ -589,11 +562,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
ServiceWorkerStatusCode status,
const ServiceWorkerClientInfo& client_info);
- void OnSetCachedMetadata(const GURL& url, const std::vector<char>& data);
- void OnSetCachedMetadataFinished(int64_t callback_id, int result);
- void OnClearCachedMetadata(const GURL& url);
- void OnClearCachedMetadataFinished(int64_t callback_id, int result);
-
void OnPostMessageToClient(
const std::string& client_uuid,
const base::string16& message,
@@ -647,10 +615,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
void PingWorker();
void OnPingTimeout();
- // Stops the worker if it is idle (has no in-flight requests) or timed out
- // ping.
- void StopWorkerIfIdle();
-
// RecordStartWorkerResult is added as a start callback by StartTimeoutTimer
// and records metrics about startup.
void RecordStartWorkerResult(ServiceWorkerMetrics::EventType purpose,
@@ -689,15 +653,14 @@ class CONTENT_EXPORT ServiceWorkerVersion
const int64_t version_id_;
const int64_t registration_id_;
const GURL script_url_;
+ const url::Origin script_origin_;
const GURL scope_;
- std::vector<GURL> foreign_fetch_scopes_;
- std::vector<url::Origin> foreign_fetch_origins_;
FetchHandlerExistence fetch_handler_existence_;
// The source of truth for navigation preload state is the
// ServiceWorkerRegistration. |navigation_preload_state_| is essentially a
// cached value because it must be looked up quickly and a live registration
// doesn't necessarily exist whenever there is a live version.
- NavigationPreloadState navigation_preload_state_;
+ blink::mojom::NavigationPreloadState navigation_preload_state_;
ServiceWorkerMetrics::Site site_for_uma_;
Status status_ = NEW;
@@ -710,6 +673,12 @@ class CONTENT_EXPORT ServiceWorkerVersion
// fetch, sync, etc. events.
base::IDMap<std::unique_ptr<PendingRequest>> pending_requests_;
+ // Keeps track of in-flight requests for timeout purposes. Requests are sorted
+ // by their expiration time (soonest to expire at the beginning of the
+ // set). The timeout timer periodically checks |request_timeouts_| for entries
+ // that should time out.
+ std::set<RequestInfo> request_timeouts_;
+
// Container for pending external requests for this service worker.
// (key, value): (request uuid, request id).
using RequestUUIDToRequestIDMap = std::map<std::string, int>;
@@ -717,10 +686,13 @@ class CONTENT_EXPORT ServiceWorkerVersion
// Connected to ServiceWorkerContextClient while the worker is running.
mojom::ServiceWorkerEventDispatcherPtr event_dispatcher_;
+ mojom::ControllerServiceWorkerPtr controller_ptr_;
std::unique_ptr<ServiceWorkerInstalledScriptsSender>
installed_scripts_sender_;
+ mojo::AssociatedBinding<blink::mojom::ServiceWorkerHost> binding_;
+
// The number of fetch event responses that the service worker is streaming to
// the browser process. We try to not stop the service worker while there is
// an ongoing response.
@@ -757,13 +729,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
// expiration times of finished requests.
base::TimeTicks max_request_expiration_time_;
- // Keeps track of requests for timeout purposes. Requests are sorted by
- // their expiration time (soonest to expire on top of the priority queue). The
- // timeout timer periodically checks |timeout_queue_| for entries that should
- // time out or have already been fulfilled (i.e., removed from
- // |pending_requests_|).
- RequestInfoPriorityQueue timeout_queue_;
-
bool skip_waiting_ = false;
bool skip_recording_startup_time_ = false;
bool force_bypass_cache_for_scripts_ = false;
@@ -785,10 +750,10 @@ class CONTENT_EXPORT ServiceWorkerVersion
ServiceWorkerStatusCode start_worker_status_ = SERVICE_WORKER_OK;
// The clock used to vend tick time.
- std::unique_ptr<base::TickClock> tick_clock_;
+ base::TickClock* tick_clock_;
// The clock used for actual (wall clock) time
- std::unique_ptr<base::Clock> clock_;
+ base::Clock* clock_;
std::unique_ptr<PingController> ping_controller_;
@@ -815,31 +780,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersion);
};
-template <typename ResponseMessage, typename CallbackType, typename... Args>
-bool ServiceWorkerVersion::EventResponseHandler<
- ResponseMessage,
- CallbackType,
- void(Args...)>::OnMessageReceived(const IPC::Message& message) {
- if (message.type() != ResponseMessage::ID)
- return false;
- int received_request_id;
- bool result = base::PickleIterator(message).ReadInt(&received_request_id);
- if (!result || received_request_id != request_id_)
- return false;
-
- CallbackType protect(callback_);
- // Essentially same code as what IPC_MESSAGE_FORWARD expands to.
- void* param = nullptr;
- if (!ResponseMessage::Dispatch(&message, this, this, param,
- &EventResponseHandler::RunCallback))
- message.set_dispatch_error();
-
- // At this point |this| can have been deleted, so don't do anything other
- // than returning.
-
- return true;
-}
-
} // namespace content
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_VERSION_H_
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 678dbd4f925..c913cb99c02 100644
--- a/chromium/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_version_unittest.cc
@@ -5,6 +5,7 @@
#include "content/browser/service_worker/service_worker_version.h"
#include <stdint.h>
+#include <memory>
#include <tuple>
#include <utility>
@@ -28,13 +29,17 @@
#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/WebKit/public/platform/modules/serviceworker/service_worker.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
// IPC messages for testing ---------------------------------------------------
+#undef IPC_IPC_MESSAGE_MACROS_H_
+#undef IPC_MESSAGE_EXTRA
#define IPC_MESSAGE_IMPL
#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_message_templates_impl.h"
#define IPC_MESSAGE_START TestMsgStart
@@ -65,11 +70,52 @@ class MessageReceiver : public EmbeddedWorkerTestHelper {
new TestMsg_TestEventResult(embedded_worker_id, request_id, reply));
}
+ void SimulateSetCachedMetadata(int embedded_worker_id,
+ const GURL& url,
+ const std::vector<uint8_t>& data) {
+ ASSERT_TRUE(service_worker_host_map_[embedded_worker_id]);
+ service_worker_host_map_[embedded_worker_id]->SetCachedMetadata(url, data);
+ }
+
+ void SimulateClearCachedMetadata(int embedded_worker_id, const GURL& url) {
+ ASSERT_TRUE(service_worker_host_map_[embedded_worker_id]);
+ service_worker_host_map_[embedded_worker_id]->ClearCachedMetadata(url);
+ }
+
+ protected:
+ void OnStartWorker(
+ int embedded_worker_id,
+ int64_t service_worker_version_id,
+ const GURL& scope,
+ const GURL& script_url,
+ bool pause_after_download,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
+ mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info)
+ override {
+ service_worker_host_map_[embedded_worker_id].Bind(
+ std::move(service_worker_host));
+ EmbeddedWorkerTestHelper::OnStartWorker(
+ embedded_worker_id, service_worker_version_id, scope, script_url,
+ pause_after_download, std::move(dispatcher_request),
+ std::move(controller_request), nullptr /* service_worker_host */,
+ std::move(instance_host), std::move(provider_info),
+ std::move(installed_scripts_info));
+ }
+
private:
void OnMessage() {
// Do nothing.
}
+ std::map<
+ int /* embedded_worker_id */,
+ blink::mojom::ServiceWorkerHostAssociatedPtr /* service_worker_host */>
+ service_worker_host_map_;
+
DISALLOW_COPY_AND_ASSIGN(MessageReceiver);
};
@@ -148,6 +194,16 @@ class TestServiceImpl : public mojom::TestService {
TestServiceImpl() {}
};
+void StartWorker(ServiceWorkerVersion* version,
+ ServiceWorkerMetrics::EventType purpose) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ version->StartWorker(purpose, CreateReceiverOnCurrentThread(&status));
+ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version->running_status());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version->running_status());
+}
+
} // namespace
class ServiceWorkerVersionTest : public testing::Test {
@@ -161,6 +217,16 @@ class ServiceWorkerVersionTest : public testing::Test {
EmbeddedWorkerStatus last_status;
};
+ struct CachedMetadataUpdateListener : public ServiceWorkerVersion::Listener {
+ CachedMetadataUpdateListener() = default;
+ ~CachedMetadataUpdateListener() override = default;
+ void OnCachedMetadataUpdated(ServiceWorkerVersion* version,
+ size_t size) override {
+ ++updated_count;
+ }
+ int updated_count = 0;
+ };
+
ServiceWorkerVersionTest()
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
@@ -180,9 +246,11 @@ class ServiceWorkerVersionTest : public testing::Test {
GURL("https://www.example.com/test/service_worker.js"),
helper_->context()->storage()->NewVersionId(),
helper_->context()->AsWeakPtr());
+ EXPECT_EQ(url::Origin::Create(pattern_), version_->script_origin());
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
- records.push_back(
- ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100));
+ records.push_back(WriteToDiskCacheSync(
+ helper_->context()->storage(), version_->script_url(), 10,
+ {} /* headers */, "I'm a body", "I'm a meta data"));
version_->script_cache_map()->SetResources(records);
version_->SetMainScriptHttpResponseInfo(
EmbeddedWorkerTestHelper::CreateHttpResponseInfo());
@@ -206,12 +274,12 @@ class ServiceWorkerVersionTest : public testing::Test {
}
virtual std::unique_ptr<MessageReceiver> GetMessageReceiver() {
- return base::MakeUnique<MessageReceiver>();
+ return std::make_unique<MessageReceiver>();
}
void TearDown() override {
- version_ = 0;
- registration_ = 0;
+ version_ = nullptr;
+ registration_ = nullptr;
helper_.reset();
}
@@ -220,10 +288,9 @@ class ServiceWorkerVersionTest : public testing::Test {
SERVICE_WORKER_ERROR_MAX_VALUE; // dummy value
// Make sure worker is running.
- scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner);
- version_->RunAfterStartWorker(event_type, runner->QuitClosure(),
+ version_->RunAfterStartWorker(event_type, base::Bind(&base::DoNothing),
CreateReceiverOnCurrentThread(&status));
- runner->Run();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
@@ -239,10 +306,8 @@ class ServiceWorkerVersionTest : public testing::Test {
EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
}
- base::SimpleTestTickClock* SetTickClockForTesting() {
- base::SimpleTestTickClock* tick_clock = new base::SimpleTestTickClock();
- version_->SetTickClockForTesting(base::WrapUnique(tick_clock));
- return tick_clock;
+ void SetTickClockForTesting(base::SimpleTestTickClock* tick_clock) {
+ version_->SetTickClockForTesting(tick_clock);
}
TestBrowserThreadBundle thread_bundle_;
@@ -268,9 +333,12 @@ class MessageReceiverDisallowStart : public MessageReceiver {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest request,
+ mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
+ mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info)
override {
switch (mode_) {
case StartMode::STALL:
@@ -278,20 +346,26 @@ class MessageReceiverDisallowStart : public MessageReceiver {
instance_host_ptr_map_[embedded_worker_id].Bind(
std::move(instance_host));
// Just keep the connection alive.
- event_dispatcher_request_map_[embedded_worker_id] = std::move(request);
+ event_dispatcher_request_map_[embedded_worker_id] =
+ std::move(dispatcher_request);
+ controller_request_map_[embedded_worker_id] =
+ std::move(controller_request);
break;
case StartMode::FAIL:
ASSERT_EQ(current_mock_instance_index_ + 1,
mock_instance_clients()->size());
// Remove the connection by peer
mock_instance_clients()->at(current_mock_instance_index_).reset();
- std::move(request);
+ std::move(dispatcher_request);
+ std::move(controller_request);
break;
case StartMode::SUCCEED:
MessageReceiver::OnStartWorker(
embedded_worker_id, service_worker_version_id, scope, script_url,
- pause_after_download, std::move(request), std::move(instance_host),
- std::move(provider_info));
+ pause_after_download, std::move(dispatcher_request),
+ std::move(controller_request), std::move(service_worker_host),
+ std::move(instance_host), std::move(provider_info),
+ std::move(installed_scripts_info));
break;
}
current_mock_instance_index_++;
@@ -319,6 +393,8 @@ class MessageReceiverDisallowStart : public MessageReceiver {
std::map<int /* embedded_worker_id */,
mojom::ServiceWorkerEventDispatcherRequest>
event_dispatcher_request_map_;
+ std::map<int /* embedded_worker_id */, mojom::ControllerServiceWorkerRequest>
+ controller_request_map_;
DISALLOW_COPY_AND_ASSIGN(MessageReceiverDisallowStart);
};
@@ -333,7 +409,7 @@ class ServiceWorkerFailToStartTest : public ServiceWorkerVersionTest {
}
std::unique_ptr<MessageReceiver> GetMessageReceiver() override {
- return base::MakeUnique<MessageReceiverDisallowStart>();
+ return std::make_unique<MessageReceiverDisallowStart>();
}
private:
@@ -379,7 +455,7 @@ class ServiceWorkerStallInStoppingTest : public ServiceWorkerVersionTest {
ServiceWorkerStallInStoppingTest() : ServiceWorkerVersionTest() {}
std::unique_ptr<MessageReceiver> GetMessageReceiver() override {
- return base::MakeUnique<MessageReceiverDisallowStop>();
+ return std::make_unique<MessageReceiverDisallowStop>();
}
private:
@@ -479,15 +555,11 @@ TEST_F(ServiceWorkerVersionTest, DispatchEventToStoppedWorker) {
TEST_F(ServiceWorkerVersionTest, StartUnregisteredButStillLiveWorker) {
// Start the worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
- version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- CreateReceiverOnCurrentThread(&status));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
// Delete the registration.
- status = SERVICE_WORKER_ERROR_FAILED;
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
helper_->context()->storage()->DeleteRegistration(
registration_->id(), registration_->pattern().GetOrigin(),
CreateReceiverOnCurrentThread(&status));
@@ -513,13 +585,7 @@ TEST_F(ServiceWorkerVersionTest, StartUnregisteredButStillLiveWorker) {
TEST_F(ServiceWorkerVersionTest, ReceiveMessageFromWorker) {
// Start worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
- version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- CreateReceiverOnCurrentThread(&status));
- EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
MessageReceiverFromWorker receiver(version_->embedded_worker());
@@ -628,11 +694,7 @@ TEST_F(ServiceWorkerVersionTest, IdleTimeout) {
EXPECT_FALSE(version_->timeout_timer_.IsRunning());
// Verify the timer is running after the worker is started.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
- version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- CreateReceiverOnCurrentThread(&status));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
EXPECT_FALSE(version_->idle_time_.is_null());
@@ -644,11 +706,7 @@ TEST_F(ServiceWorkerVersionTest, IdleTimeout) {
version_->StopWorker(base::BindOnce(&VerifyCalled, &has_stopped));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(has_stopped);
- status = SERVICE_WORKER_ERROR_FAILED;
- version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- CreateReceiverOnCurrentThread(&status));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
EXPECT_LT(idle_time, version_->idle_time_);
@@ -673,6 +731,7 @@ TEST_F(ServiceWorkerVersionTest, IdleTimeout) {
// Starting and finishing a request resets the idle time.
version_->idle_time_ -= kOneSecond;
idle_time = version_->idle_time_;
+ ServiceWorkerStatusCode status = SERVICE_WORKER_OK;
int request_id =
version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC,
CreateReceiverOnCurrentThread(&status));
@@ -716,13 +775,7 @@ TEST_F(ServiceWorkerVersionTest, SetDevToolsAttached) {
TEST_F(ServiceWorkerVersionTest, StoppingBeforeDestruct) {
RunningStateListener listener;
version_->AddListener(&listener);
-
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
- version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- CreateReceiverOnCurrentThread(&status));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, listener.last_status);
// Destruct |version_| by releasing all references, including the provider
@@ -838,6 +891,61 @@ TEST_F(ServiceWorkerVersionTest, StaleUpdate_DoNotDeferTimer) {
EXPECT_EQ(run_time, version_->update_timer_.desired_run_time());
}
+TEST_F(ServiceWorkerVersionTest, UpdateCachedMetadata) {
+ CachedMetadataUpdateListener listener;
+ version_->AddListener(&listener);
+ ASSERT_EQ(0, listener.updated_count);
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
+
+ // Simulate requesting SetCachedMetadata from the service worker global scope.
+ std::vector<uint8_t> data{1, 2, 3};
+ helper_->SimulateSetCachedMetadata(
+ version_->embedded_worker()->embedded_worker_id(), version_->script_url(),
+ data);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, listener.updated_count);
+
+ // Simulate requesting ClearCachedMetadata from the service worker global
+ // scope.
+ helper_->SimulateClearCachedMetadata(
+ version_->embedded_worker()->embedded_worker_id(),
+ version_->script_url());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(2, listener.updated_count);
+ version_->RemoveListener(&listener);
+}
+
+TEST_F(ServiceWorkerVersionTest, RestartWorker) {
+ StartWorker(version_.get(),
+ ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+
+ ServiceWorkerStatusCode event_status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ version_->StartRequest(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
+ CreateReceiverOnCurrentThread(&event_status));
+
+ // Restart the worker. The inflight event should have been failed.
+ bool has_stopped = false;
+ version_->StopWorker(base::BindOnce(&VerifyCalled, &has_stopped));
+ EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status());
+ ServiceWorkerStatusCode start_status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+ CreateReceiverOnCurrentThread(&start_status));
+ base::RunLoop().RunUntilIdle();
+
+ // All inflight events should have been aborted.
+ EXPECT_EQ(event_status, SERVICE_WORKER_ERROR_FAILED);
+ // The worker should have been stopped.
+ EXPECT_TRUE(has_stopped);
+ // The worker should have been successfully re-started after stopped.
+ EXPECT_EQ(SERVICE_WORKER_OK, start_status);
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+
+ // SetAllRequestExpirations() after restarting should not crash since all
+ // events should have been removed at this point: crbug.com/791451.
+ version_->SetAllRequestExpirations(base::TimeTicks());
+}
+
class MessageReceiverControlEvents : public MessageReceiver {
public:
MessageReceiverControlEvents() : MessageReceiver() {}
@@ -882,7 +990,7 @@ class ServiceWorkerRequestTimeoutTest : public ServiceWorkerVersionTest {
ServiceWorkerRequestTimeoutTest() : ServiceWorkerVersionTest() {}
std::unique_ptr<MessageReceiver> GetMessageReceiver() override {
- return base::MakeUnique<MessageReceiverControlEvents>();
+ return std::make_unique<MessageReceiverControlEvents>();
}
bool has_extendable_message_event_callback() {
@@ -909,11 +1017,8 @@ TEST_F(ServiceWorkerRequestTimeoutTest, RequestTimeout) {
ServiceWorkerStatusCode error_status =
SERVICE_WORKER_ERROR_NETWORK; // dummy value
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-
- version_->StartWorker(
- ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
- base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
- base::RunLoop().RunUntilIdle();
+ StartWorker(version_.get(),
+ ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
// Create a request.
int request_id =
@@ -966,11 +1071,7 @@ TEST_F(ServiceWorkerRequestTimeoutTest, RequestTimeout) {
TEST_F(ServiceWorkerVersionTest, RequestNowTimeout) {
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-
- version_->StartWorker(
- ServiceWorkerMetrics::EventType::SYNC,
- base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
- base::RunLoop().RunUntilIdle();
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::SYNC);
// Create a request that should expire Now().
int request_id = version_->StartRequestWithCustomTimeout(
@@ -994,11 +1095,7 @@ TEST_F(ServiceWorkerVersionTest, RequestNowTimeout) {
TEST_F(ServiceWorkerVersionTest, RequestNowTimeoutKill) {
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-
- version_->StartWorker(
- ServiceWorkerMetrics::EventType::SYNC,
- base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
- base::RunLoop().RunUntilIdle();
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::SYNC);
// Create a request that should expire Now().
int request_id = version_->StartRequestWithCustomTimeout(
@@ -1025,13 +1122,10 @@ TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) {
ServiceWorkerStatusCode second_status =
SERVICE_WORKER_ERROR_MAX_VALUE; // dummy value
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::SYNC);
- version_->StartWorker(
- ServiceWorkerMetrics::EventType::SYNC,
- base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
- base::RunLoop().RunUntilIdle();
-
- base::SimpleTestTickClock* tick_clock = SetTickClockForTesting();
+ base::SimpleTestTickClock tick_clock;
+ SetTickClockForTesting(&tick_clock);
// Create two requests. One which times out in 10 seconds, one in 20 seconds.
int timeout_seconds = 10;
@@ -1056,7 +1150,7 @@ TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) {
EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, second_status);
// Now advance time until the second task timeout should expire.
- tick_clock->Advance(base::TimeDelta::FromSeconds(timeout_seconds + 1));
+ tick_clock.Advance(base::TimeDelta::FromSeconds(timeout_seconds + 1));
version_->timeout_timer_.user_task().Run();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, first_status);
@@ -1066,7 +1160,7 @@ TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) {
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
// Now advance time until both tasks should be expired.
- tick_clock->Advance(base::TimeDelta::FromSeconds(timeout_seconds + 1));
+ tick_clock.Advance(base::TimeDelta::FromSeconds(timeout_seconds + 1));
version_->timeout_timer_.user_task().Run();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, first_status);
@@ -1088,11 +1182,8 @@ TEST_F(ServiceWorkerVersionTest, MixedRequestTimeouts) {
ServiceWorkerStatusCode fetch_status =
SERVICE_WORKER_ERROR_NETWORK; // dummy value
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-
- version_->StartWorker(
- ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
- base::BindOnce(&ServiceWorkerUtils::NoOpStatusCallback));
- base::RunLoop().RunUntilIdle();
+ StartWorker(version_.get(),
+ ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
// Create a fetch request that should expire sometime later.
int fetch_request_id =
@@ -1181,12 +1272,7 @@ TEST_F(ServiceWorkerFailToStartTest, Timeout) {
// sticky error state.
TEST_F(ServiceWorkerStallInStoppingTest, DetachThenStart) {
// Start a worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
- version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- CreateReceiverOnCurrentThread(&status));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
// Try to stop the worker.
bool has_stopped = false;
@@ -1209,12 +1295,7 @@ TEST_F(ServiceWorkerStallInStoppingTest, DetachThenStart) {
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
// Try to start the worker again. It should work.
- status = SERVICE_WORKER_ERROR_FAILED;
- version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- CreateReceiverOnCurrentThread(&status));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
// The timeout interval should be reset to normal.
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
@@ -1226,12 +1307,7 @@ TEST_F(ServiceWorkerStallInStoppingTest, DetachThenStart) {
// request queued up will timeout and restart.
TEST_F(ServiceWorkerStallInStoppingTest, DetachThenRestart) {
// Start a worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
- version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- CreateReceiverOnCurrentThread(&status));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
// Try to stop the worker.
bool has_stopped = false;
@@ -1254,92 +1330,11 @@ TEST_F(ServiceWorkerStallInStoppingTest, DetachThenRestart) {
EXPECT_EQ(SERVICE_WORKER_OK, start_status);
}
-TEST_F(ServiceWorkerVersionTest, RegisterForeignFetchScopes) {
- version_->SetStatus(ServiceWorkerVersion::INSTALLING);
- // Start a worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
- version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- CreateReceiverOnCurrentThread(&status));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
- EXPECT_EQ(0, helper_->mock_render_process_host()->bad_msg_count());
-
- GURL valid_scope_1("https://www.example.com/test/subscope");
- GURL valid_scope_2("https://www.example.com/test/othersubscope");
- std::vector<GURL> valid_scopes;
- valid_scopes.push_back(valid_scope_1);
- valid_scopes.push_back(valid_scope_2);
-
- std::vector<url::Origin> all_origins;
- url::Origin valid_origin(GURL("https://chromium.org/"));
- std::vector<url::Origin> valid_origin_list(1, valid_origin);
-
- // Invalid subscope, should kill worker (but in tests will only increase bad
- // message count).
- version_->RegisterForeignFetchScopes(std::vector<GURL>(1, GURL()),
- valid_origin_list);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1, helper_->mock_render_process_host()->bad_msg_count());
- EXPECT_EQ(0u, version_->foreign_fetch_scopes_.size());
- EXPECT_EQ(0u, version_->foreign_fetch_origins_.size());
-
- // Subscope outside the scope of the worker.
- version_->RegisterForeignFetchScopes(
- std::vector<GURL>(1, GURL("https://www.example.com/wrong")),
- valid_origin_list);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2, helper_->mock_render_process_host()->bad_msg_count());
- EXPECT_EQ(0u, version_->foreign_fetch_scopes_.size());
- EXPECT_EQ(0u, version_->foreign_fetch_origins_.size());
-
- // Subscope on wrong origin.
- version_->RegisterForeignFetchScopes(
- std::vector<GURL>(1, GURL("https://example.com/test/")),
- valid_origin_list);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(3, helper_->mock_render_process_host()->bad_msg_count());
- EXPECT_EQ(0u, version_->foreign_fetch_scopes_.size());
- EXPECT_EQ(0u, version_->foreign_fetch_origins_.size());
-
- // Invalid origin.
- version_->RegisterForeignFetchScopes(
- valid_scopes, std::vector<url::Origin>(1, url::Origin()));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(4, helper_->mock_render_process_host()->bad_msg_count());
- EXPECT_EQ(0u, version_->foreign_fetch_scopes_.size());
- EXPECT_EQ(0u, version_->foreign_fetch_origins_.size());
-
- // Valid subscope, no origins.
- version_->RegisterForeignFetchScopes(std::vector<GURL>(1, valid_scope_1),
- all_origins);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(4, helper_->mock_render_process_host()->bad_msg_count());
- EXPECT_EQ(1u, version_->foreign_fetch_scopes_.size());
- EXPECT_EQ(valid_scope_1, version_->foreign_fetch_scopes_[0]);
- EXPECT_EQ(0u, version_->foreign_fetch_origins_.size());
-
- // Valid subscope, explicit origins.
- version_->RegisterForeignFetchScopes(valid_scopes, valid_origin_list);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(4, helper_->mock_render_process_host()->bad_msg_count());
- EXPECT_EQ(2u, version_->foreign_fetch_scopes_.size());
- EXPECT_EQ(valid_scope_1, version_->foreign_fetch_scopes_[0]);
- EXPECT_EQ(valid_scope_2, version_->foreign_fetch_scopes_[1]);
- EXPECT_EQ(1u, version_->foreign_fetch_origins_.size());
- EXPECT_EQ(valid_origin, version_->foreign_fetch_origins_[0]);
-}
-
TEST_F(ServiceWorkerVersionTest, RendererCrashDuringEvent) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
-
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
- version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
- CreateReceiverOnCurrentThread(&status));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+ StartWorker(version_.get(), ServiceWorkerMetrics::EventType::SYNC);
+ ServiceWorkerStatusCode status = SERVICE_WORKER_OK;
int request_id =
version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC,
CreateReceiverOnCurrentThread(&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 277a0f7284f..fbe92a8ff93 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
@@ -120,7 +120,7 @@ void ServiceWorkerWriteToCacheJob::StartAsync() {
copy_reader =
context_->storage()->CreateResponseReader(incumbent_resource_id_);
}
- cache_writer_ = base::MakeUnique<ServiceWorkerCacheWriter>(
+ cache_writer_ = std::make_unique<ServiceWorkerCacheWriter>(
std::move(compare_reader), std::move(copy_reader),
context_->storage()->CreateResponseWriter(resource_id_));
@@ -237,7 +237,7 @@ void ServiceWorkerWriteToCacheJob::InitNetRequest(
net_request_->set_initiator(request()->initiator());
net_request_->SetReferrer(request()->referrer());
net_request_->SetUserData(URLRequestServiceWorkerData::kUserDataKey,
- base::MakeUnique<URLRequestServiceWorkerData>());
+ std::make_unique<URLRequestServiceWorkerData>());
if (extra_load_flags)
net_request_->SetLoadFlags(net_request_->load_flags() | extra_load_flags);
@@ -303,10 +303,13 @@ void ServiceWorkerWriteToCacheJob::OnSSLCertificateError(
DCHECK_EQ(net_request_.get(), request);
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerWriteToCacheJob::OnSSLCertificateError");
- if (ShouldIgnoreSSLError(request))
+ if (ShouldIgnoreSSLError(request)) {
request->ContinueDespiteLastError();
- else
- NotifyStartErrorHelper(net::ERR_INSECURE_RESPONSE, kSSLError);
+ } else {
+ NotifyStartErrorHelper(
+ net::Error(net::MapCertStatusToNetError(ssl_info.cert_status)),
+ kSSLError);
+ }
}
void ServiceWorkerWriteToCacheJob::OnResponseStarted(net::URLRequest* request,
@@ -331,7 +334,9 @@ void ServiceWorkerWriteToCacheJob::OnResponseStarted(net::URLRequest* request,
// So we check cert_status here.
if (net::IsCertStatusError(request->ssl_info().cert_status) &&
!ShouldIgnoreSSLError(request)) {
- NotifyStartErrorHelper(net::ERR_INSECURE_RESPONSE, kSSLError);
+ NotifyStartErrorHelper(net::Error(net::MapCertStatusToNetError(
+ request->ssl_info().cert_status)),
+ kSSLError);
return;
}
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 f7d575ea613..928b61f9f51 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
@@ -317,9 +317,10 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
TRAFFIC_ANNOTATION_FOR_TESTS);
ServiceWorkerRequestHandler::InitializeHandler(
request_.get(), context_wrapper(), &blob_storage_context_, process_id,
- provider_id, false, FETCH_REQUEST_MODE_NO_CORS,
- FETCH_CREDENTIALS_MODE_OMIT, FetchRedirectMode::FOLLOW_MODE,
- std::string() /* integrity */, RESOURCE_TYPE_SERVICE_WORKER,
+ provider_id, false, network::mojom::FetchRequestMode::kNoCORS,
+ network::mojom::FetchCredentialsMode::kOmit,
+ FetchRedirectMode::FOLLOW_MODE, std::string() /* integrity */,
+ false /* keepalive */, RESOURCE_TYPE_SERVICE_WORKER,
REQUEST_CONTEXT_TYPE_SERVICE_WORKER, REQUEST_CONTEXT_FRAME_TYPE_NONE,
scoped_refptr<ResourceRequestBody>());
}
@@ -472,7 +473,7 @@ TEST_F(ServiceWorkerWriteToCacheJobTest, SSLCertificateError) {
request_->Start();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
- EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
+ EXPECT_EQ(net::ERR_CERT_DATE_INVALID, request_->status().error());
EXPECT_EQ(kInvalidServiceWorkerResourceId,
version_->script_cache_map()->LookupResourceId(script_url_));
}
@@ -507,7 +508,7 @@ TEST_F(ServiceWorkerWriteToCacheLocalhostTest, SSLCertificateError) {
request_->Start();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
- EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
+ EXPECT_EQ(net::ERR_CERT_DATE_INVALID, request_->status().error());
EXPECT_EQ(kInvalidServiceWorkerResourceId,
version_->script_cache_map()->LookupResourceId(script_url_));
}
@@ -533,7 +534,7 @@ TEST_F(ServiceWorkerWriteToCacheLocalhostTest, CertStatusError) {
request_->Start();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
- EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
+ EXPECT_EQ(net::ERR_CERT_DATE_INVALID, request_->status().error());
EXPECT_EQ(kInvalidServiceWorkerResourceId,
version_->script_cache_map()->LookupResourceId(script_url_));
}
@@ -544,7 +545,7 @@ TEST_F(ServiceWorkerWriteToCacheJobTest, CertStatusError) {
request_->Start();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
- EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
+ EXPECT_EQ(net::ERR_CERT_DATE_INVALID, request_->status().error());
EXPECT_EQ(kInvalidServiceWorkerResourceId,
version_->script_cache_map()->LookupResourceId(script_url_));
}
diff --git a/chromium/content/browser/shareable_file_reference_unittest.cc b/chromium/content/browser/shareable_file_reference_unittest.cc
index 2d6fbd6bd0a..5003f6c6e68 100644
--- a/chromium/content/browser/shareable_file_reference_unittest.cc
+++ b/chromium/content/browser/shareable_file_reference_unittest.cc
@@ -46,13 +46,13 @@ TEST(ShareableFileReferenceTest, TestReferences) {
EXPECT_EQ(reference1.get(), reference2.get());
// Drop the first reference, the file and reference should still be there.
- reference1 = NULL;
+ reference1 = nullptr;
EXPECT_TRUE(ShareableFileReference::Get(file).get());
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(base::PathExists(file));
// Drop the second reference, the file and reference should get deleted.
- reference2 = NULL;
+ reference2 = nullptr;
EXPECT_FALSE(ShareableFileReference::Get(file).get());
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(base::PathExists(file));
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 c7db23aa939..4fb7fcdb85c 100644
--- a/chromium/content/browser/shared_worker/shared_worker_connector_impl.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_connector_impl.cc
@@ -70,10 +70,12 @@ void SharedWorkerConnectorImpl::Connect(
mojom::SharedWorkerClientPtr client,
blink::mojom::SharedWorkerCreationContextType creation_context_type,
mojo::ScopedMessagePipeHandle message_port) {
- SharedWorkerServiceImpl::GetInstance()->ConnectToWorker(
- process_id_, frame_id_, std::move(info), std::move(client),
- creation_context_type, blink::MessagePortChannel(std::move(message_port)),
- resource_context_, WorkerStoragePartitionId(worker_storage_partition_));
+ static_cast<SharedWorkerServiceImpl*>(SharedWorkerService::GetInstance())
+ ->ConnectToWorker(process_id_, frame_id_, std::move(info),
+ std::move(client), creation_context_type,
+ blink::MessagePortChannel(std::move(message_port)),
+ resource_context_,
+ WorkerStoragePartitionId(worker_storage_partition_));
}
} // 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 99c2f61aafe..ba7feb60615 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
@@ -16,7 +16,9 @@ SharedWorkerContentSettingsProxyImpl::SharedWorkerContentSettingsProxyImpl(
const GURL& script_url,
SharedWorkerHost* owner,
blink::mojom::WorkerContentSettingsProxyRequest request)
- : origin_(script_url), owner_(owner), binding_(this, std::move(request)) {}
+ : origin_(url::Origin::Create(script_url)),
+ owner_(owner),
+ binding_(this, std::move(request)) {}
SharedWorkerContentSettingsProxyImpl::~SharedWorkerContentSettingsProxyImpl() =
default;
diff --git a/chromium/content/browser/shared_worker/shared_worker_host.cc b/chromium/content/browser/shared_worker/shared_worker_host.cc
index 3b6034911d9..6b098619b57 100644
--- a/chromium/content/browser/shared_worker/shared_worker_host.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_host.cc
@@ -8,6 +8,8 @@
#include "base/metrics/histogram_macros.h"
#include "content/browser/devtools/shared_worker_devtools_manager.h"
+#include "content/browser/interface_provider_filtering.h"
+#include "content/browser/renderer_interface_binders.h"
#include "content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h"
#include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/shared_worker_service_impl.h"
@@ -60,6 +62,7 @@ SharedWorkerHost::SharedWorkerHost(
route_id_(route_id),
next_connection_request_id_(1),
creation_time_(base::TimeTicks::Now()),
+ interface_provider_binding_(this),
weak_factory_(this) {
DCHECK(instance_);
}
@@ -82,14 +85,20 @@ void SharedWorkerHost::Start(mojom::SharedWorkerFactoryPtr factory,
mojom::SharedWorkerHostPtr host;
binding_.Bind(mojo::MakeRequest(&host));
+ service_manager::mojom::InterfaceProviderPtr interface_provider;
+ interface_provider_binding_.Bind(FilterRendererExposedInterfaces(
+ mojom::kNavigation_SharedWorkerSpec, process_id_,
+ mojo::MakeRequest(&interface_provider)));
+
mojom::SharedWorkerInfoPtr info(mojom::SharedWorkerInfo::New(
instance_->url(), instance_->name(), instance_->content_security_policy(),
instance_->content_security_policy_type(),
- instance_->creation_address_space(), instance_->data_saver_enabled()));
+ instance_->creation_address_space()));
- factory->CreateSharedWorker(std::move(info), pause_on_start, route_id_,
- std::move(content_settings), std::move(host),
- mojo::MakeRequest(&worker_));
+ factory->CreateSharedWorker(
+ std::move(info), pause_on_start, instance_->devtools_worker_token(),
+ route_id_, std::move(content_settings), std::move(host),
+ mojo::MakeRequest(&worker_), std::move(interface_provider));
// Monitor the lifetime of the worker.
worker_.set_connection_error_handler(base::BindOnce(
@@ -242,7 +251,21 @@ void SharedWorkerHost::OnClientConnectionLost() {
void SharedWorkerHost::OnWorkerConnectionLost() {
// This will destroy |this| resulting in client's observing their mojo
// connection being dropped.
- SharedWorkerServiceImpl::GetInstance()->DestroyHost(process_id_, route_id_);
+ static_cast<SharedWorkerServiceImpl*>(SharedWorkerService::GetInstance())
+ ->DestroyHost(process_id_, route_id_);
+}
+
+void SharedWorkerHost::GetInterface(
+ const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ auto* process = RenderProcessHost::FromID(process_id_);
+ if (!process)
+ return;
+
+ BindWorkerInterface(interface_name, std::move(interface_pipe), process,
+ url::Origin::Create(instance()->url()));
}
} // namespace content
diff --git a/chromium/content/browser/shared_worker/shared_worker_host.h b/chromium/content/browser/shared_worker/shared_worker_host.h
index 781563e5098..47f5ce9a03f 100644
--- a/chromium/content/browser/shared_worker/shared_worker_host.h
+++ b/chromium/content/browser/shared_worker/shared_worker_host.h
@@ -20,6 +20,7 @@
#include "content/common/shared_worker/shared_worker_factory.mojom.h"
#include "content/common/shared_worker/shared_worker_host.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
class GURL;
@@ -36,7 +37,8 @@ class SharedWorkerInstance;
// the browser <-> worker communication channel. This is owned by
// SharedWorkerServiceImpl and destructed when a worker context or worker's
// message filter is closed.
-class SharedWorkerHost : public mojom::SharedWorkerHost {
+class SharedWorkerHost : public mojom::SharedWorkerHost,
+ public service_manager::mojom::InterfaceProvider {
public:
SharedWorkerHost(std::unique_ptr<SharedWorkerInstance> instance,
int process_id,
@@ -99,6 +101,10 @@ class SharedWorkerHost : public mojom::SharedWorkerHost {
void OnClientConnectionLost();
void OnWorkerConnectionLost();
+ // service_manager::mojom::InterfaceProvider:
+ void GetInterface(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) override;
+
mojo::Binding<mojom::SharedWorkerHost> binding_;
std::unique_ptr<SharedWorkerInstance> instance_;
ClientList clients_;
@@ -116,6 +122,10 @@ class SharedWorkerHost : public mojom::SharedWorkerHost {
std::set<blink::mojom::WebFeature> used_features_;
std::unique_ptr<SharedWorkerContentSettingsProxyImpl> content_settings_;
+
+ mojo::Binding<service_manager::mojom::InterfaceProvider>
+ interface_provider_binding_;
+
base::WeakPtrFactory<SharedWorkerHost> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SharedWorkerHost);
diff --git a/chromium/content/browser/shared_worker/shared_worker_instance.cc b/chromium/content/browser/shared_worker/shared_worker_instance.cc
index 41a81c23fed..be023a1fdfe 100644
--- a/chromium/content/browser/shared_worker/shared_worker_instance.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_instance.cc
@@ -11,42 +11,43 @@ namespace content {
SharedWorkerInstance::SharedWorkerInstance(
const GURL& url,
const std::string& name,
+ const url::Origin& constructor_origin,
const std::string& content_security_policy,
blink::WebContentSecurityPolicyType security_policy_type,
blink::WebAddressSpace creation_address_space,
ResourceContext* resource_context,
const WorkerStoragePartitionId& partition_id,
blink::mojom::SharedWorkerCreationContextType creation_context_type,
- bool data_saver_enabled)
+ const base::UnguessableToken& devtools_worker_token)
: url_(url),
name_(name),
+ constructor_origin_(constructor_origin),
content_security_policy_(content_security_policy),
content_security_policy_type_(security_policy_type),
creation_address_space_(creation_address_space),
resource_context_(resource_context),
partition_id_(partition_id),
creation_context_type_(creation_context_type),
- data_saver_enabled_(data_saver_enabled) {
+ devtools_worker_token_(devtools_worker_token) {
DCHECK(resource_context_);
+ DCHECK(!devtools_worker_token_.is_empty());
}
-SharedWorkerInstance::SharedWorkerInstance(const SharedWorkerInstance& other)
- : url_(other.url_),
- name_(other.name_),
- content_security_policy_(other.content_security_policy_),
- content_security_policy_type_(other.content_security_policy_type_),
- creation_address_space_(other.creation_address_space_),
- resource_context_(other.resource_context_),
- partition_id_(other.partition_id_),
- creation_context_type_(other.creation_context_type_),
- data_saver_enabled_(other.data_saver_enabled_) {}
+SharedWorkerInstance::SharedWorkerInstance(const SharedWorkerInstance& other) =
+ default;
-SharedWorkerInstance::~SharedWorkerInstance() {}
+SharedWorkerInstance::~SharedWorkerInstance() = default;
-bool SharedWorkerInstance::Matches(const GURL& match_url,
- const std::string& match_name,
+bool SharedWorkerInstance::Matches(const GURL& url,
+ const std::string& name,
+ const url::Origin& constructor_origin,
const WorkerStoragePartitionId& partition_id,
ResourceContext* resource_context) const {
+ // |url| and |constructor_origin| should be in the same origin, or |url|
+ // should be a data: URL.
+ DCHECK(url::Origin::Create(url).IsSameOriginWith(constructor_origin) ||
+ url.SchemeIs(url::kDataScheme));
+
// ResourceContext equivalence is being used as a proxy to ensure we only
// matched shared workers within the same BrowserContext.
if (resource_context_ != resource_context)
@@ -57,19 +58,20 @@ bool SharedWorkerInstance::Matches(const GURL& match_url,
if (!partition_id_.Equals(partition_id))
return false;
- if (url_.GetOrigin() != match_url.GetOrigin())
- return false;
-
- if (name_ != match_name || url_ != match_url)
+ // Step 11.2: "If there exists a SharedWorkerGlobalScope object whose closing
+ // flag is false, constructor origin is same origin with outside settings's
+ // origin, constructor url equals urlRecord, and name equals the value of
+ // options's name member, then set worker global scope to that
+ // SharedWorkerGlobalScope object."
+ if (!constructor_origin_.IsSameOriginWith(constructor_origin) ||
+ url_ != url || name_ != name)
return false;
return true;
}
bool SharedWorkerInstance::Matches(const SharedWorkerInstance& other) const {
- return Matches(other.url(),
- other.name(),
- other.partition_id(),
- other.resource_context());
+ return Matches(other.url(), other.name(), other.constructor_origin(),
+ other.partition_id(), other.resource_context());
}
} // namespace content
diff --git a/chromium/content/browser/shared_worker/shared_worker_instance.h b/chromium/content/browser/shared_worker/shared_worker_instance.h
index eef29d1b866..f064cb511a8 100644
--- a/chromium/content/browser/shared_worker/shared_worker_instance.h
+++ b/chromium/content/browser/shared_worker/shared_worker_instance.h
@@ -7,12 +7,14 @@
#include <string>
+#include "base/unguessable_token.h"
#include "content/browser/shared_worker/worker_storage_partition.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/WebAddressSpace.h"
#include "third_party/WebKit/public/platform/WebContentSecurityPolicy.h"
#include "third_party/WebKit/public/web/shared_worker_creation_context_type.mojom.h"
#include "url/gurl.h"
+#include "url/origin.h"
namespace content {
class ResourceContext;
@@ -24,24 +26,24 @@ class CONTENT_EXPORT SharedWorkerInstance {
SharedWorkerInstance(
const GURL& url,
const std::string& name,
+ const url::Origin& constructor_origin,
const std::string& content_security_policy,
blink::WebContentSecurityPolicyType content_security_policy_type,
blink::WebAddressSpace creation_address_space,
ResourceContext* resource_context,
const WorkerStoragePartitionId& partition_id,
blink::mojom::SharedWorkerCreationContextType creation_context_type,
- bool data_saver_enabled);
+ const base::UnguessableToken& devtools_worker_token);
SharedWorkerInstance(const SharedWorkerInstance& other);
~SharedWorkerInstance();
- // Checks if this SharedWorkerInstance matches the passed url/name params
- // based on the algorithm in the WebWorkers spec - an instance matches if the
- // origins of the URLs match, and:
- // a) the names are non-empty and equal.
- // -or-
- // b) the names are both empty, and the urls are equal.
+ // Checks if this SharedWorkerInstance matches the passed url, name, and
+ // constructor origin params according to the SharedWorker constructor steps
+ // in the HTML spec:
+ // https://html.spec.whatwg.org/multipage/workers.html#shared-workers-and-the-sharedworker-interface
bool Matches(const GURL& url,
const std::string& name,
+ const url::Origin& constructor_origin,
const WorkerStoragePartitionId& partition,
ResourceContext* resource_context) const;
bool Matches(const SharedWorkerInstance& other) const;
@@ -49,6 +51,7 @@ class CONTENT_EXPORT SharedWorkerInstance {
// Accessors.
const GURL& url() const { return url_; }
const std::string name() const { return name_; }
+ const url::Origin& constructor_origin() const { return constructor_origin_; }
const std::string content_security_policy() const {
return content_security_policy_;
}
@@ -65,18 +68,26 @@ class CONTENT_EXPORT SharedWorkerInstance {
blink::mojom::SharedWorkerCreationContextType creation_context_type() const {
return creation_context_type_;
}
- bool data_saver_enabled() const { return data_saver_enabled_; }
+ const base::UnguessableToken& devtools_worker_token() const {
+ return devtools_worker_token_;
+ }
private:
const GURL url_;
const std::string name_;
+
+ // The origin of the document that created this shared worker instance. Used
+ // for security checks. See Matches() for details.
+ // https://html.spec.whatwg.org/multipage/workers.html#concept-sharedworkerglobalscope-constructor-origin
+ const url::Origin constructor_origin_;
+
const std::string content_security_policy_;
const blink::WebContentSecurityPolicyType content_security_policy_type_;
const blink::WebAddressSpace creation_address_space_;
ResourceContext* const resource_context_;
const WorkerStoragePartitionId partition_id_;
const blink::mojom::SharedWorkerCreationContextType creation_context_type_;
- const bool data_saver_enabled_;
+ const base::UnguessableToken devtools_worker_token_;
};
} // namespace content
diff --git a/chromium/content/browser/shared_worker/shared_worker_instance_unittest.cc b/chromium/content/browser/shared_worker/shared_worker_instance_unittest.cc
index ff9759ffc12..0845739ba88 100644
--- a/chromium/content/browser/shared_worker/shared_worker_instance_unittest.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_instance_unittest.cc
@@ -33,10 +33,28 @@ class SharedWorkerInstanceTest : public testing::Test {
nullptr /* service_worker_context */)),
partition_id_(*partition_.get()) {}
+ SharedWorkerInstance CreateInstance(const GURL& script_url,
+ const std::string& name,
+ const url::Origin& constructor_origin) {
+ return SharedWorkerInstance(
+ script_url, name, constructor_origin, std::string(),
+ blink::kWebContentSecurityPolicyTypeReport,
+ blink::kWebAddressSpacePublic, browser_context_->GetResourceContext(),
+ partition_id_,
+ blink::mojom::SharedWorkerCreationContextType::kNonsecure,
+ base::UnguessableToken::Create());
+ }
+
bool Matches(const SharedWorkerInstance& instance,
const std::string& url,
const base::StringPiece& name) {
- return instance.Matches(GURL(url), name.as_string(), partition_id_,
+ url::Origin constructor_origin;
+ if (GURL(url).SchemeIs(url::kDataScheme))
+ constructor_origin = url::Origin::Create(GURL("http://example.com/"));
+ else
+ constructor_origin = url::Origin::Create(GURL(url));
+ return instance.Matches(GURL(url), name.as_string(), constructor_origin,
+ partition_id_,
browser_context_->GetResourceContext());
}
@@ -50,12 +68,15 @@ class SharedWorkerInstanceTest : public testing::Test {
};
TEST_F(SharedWorkerInstanceTest, MatchesTest) {
- SharedWorkerInstance instance1(
- GURL("http://example.com/w.js"), std::string(), std::string(),
- blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic,
- browser_context_->GetResourceContext(), partition_id_,
- blink::mojom::SharedWorkerCreationContextType::kNonsecure,
- false /* data_saver_enabled */);
+ const std::string kDataURL("data:text/javascript;base64,Ly8gSGVsbG8h");
+
+ // SharedWorker that doesn't have a name option.
+ GURL script_url1("http://example.com/w.js");
+ std::string name1("");
+ url::Origin constructor_origin1 = url::Origin::Create(script_url1);
+ SharedWorkerInstance instance1 =
+ CreateInstance(script_url1, name1, constructor_origin1);
+
EXPECT_TRUE(Matches(instance1, "http://example.com/w.js", ""));
EXPECT_FALSE(Matches(instance1, "http://example.com/w2.js", ""));
EXPECT_FALSE(Matches(instance1, "http://example.net/w.js", ""));
@@ -64,13 +85,16 @@ TEST_F(SharedWorkerInstanceTest, MatchesTest) {
EXPECT_FALSE(Matches(instance1, "http://example.com/w2.js", "name"));
EXPECT_FALSE(Matches(instance1, "http://example.net/w.js", "name"));
EXPECT_FALSE(Matches(instance1, "http://example.net/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance1, kDataURL, ""));
+ EXPECT_FALSE(Matches(instance1, kDataURL, "name"));
+
+ // SharedWorker that has a name option.
+ GURL script_url2("http://example.com/w.js");
+ std::string name2("name");
+ url::Origin constructor_origin2 = url::Origin::Create(script_url2);
+ SharedWorkerInstance instance2 =
+ CreateInstance(script_url2, name2, constructor_origin2);
- SharedWorkerInstance instance2(
- GURL("http://example.com/w.js"), "name", std::string(),
- blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic,
- browser_context_->GetResourceContext(), partition_id_,
- blink::mojom::SharedWorkerCreationContextType::kNonsecure,
- false /* data_saver_enabled */);
EXPECT_FALSE(Matches(instance2, "http://example.com/w.js", ""));
EXPECT_FALSE(Matches(instance2, "http://example.com/w2.js", ""));
EXPECT_FALSE(Matches(instance2, "http://example.net/w.js", ""));
@@ -83,17 +107,126 @@ TEST_F(SharedWorkerInstanceTest, MatchesTest) {
EXPECT_FALSE(Matches(instance2, "http://example.com/w2.js", "name2"));
EXPECT_FALSE(Matches(instance2, "http://example.net/w.js", "name2"));
EXPECT_FALSE(Matches(instance2, "http://example.net/w2.js", "name2"));
+ EXPECT_FALSE(Matches(instance2, kDataURL, ""));
+ EXPECT_FALSE(Matches(instance2, kDataURL, "name"));
+}
+
+TEST_F(SharedWorkerInstanceTest, MatchesTest_DataURLWorker) {
+ const std::string kDataURL("data:text/javascript;base64,Ly8gSGVsbG8h");
+
+ // SharedWorker created from a data: URL without a name option.
+ GURL script_url1(kDataURL);
+ std::string name1("");
+ url::Origin constructor_origin1 =
+ url::Origin::Create(GURL("http://example.com/"));
+ SharedWorkerInstance instance1 =
+ CreateInstance(script_url1, name1, constructor_origin1);
+
+ EXPECT_FALSE(Matches(instance1, "http://example.com/w.js", ""));
+ EXPECT_FALSE(Matches(instance1, "http://example.com/w2.js", ""));
+ EXPECT_FALSE(Matches(instance1, "http://example.net/w.js", ""));
+ EXPECT_FALSE(Matches(instance1, "http://example.net/w2.js", ""));
+ EXPECT_FALSE(Matches(instance1, "http://example.com/w.js", "name"));
+ EXPECT_FALSE(Matches(instance1, "http://example.com/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance1, "http://example.net/w.js", "name"));
+ EXPECT_FALSE(Matches(instance1, "http://example.net/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance1, "http://example.com/w.js", "name2"));
+ EXPECT_FALSE(Matches(instance1, "http://example.com/w2.js", "name2"));
+ EXPECT_FALSE(Matches(instance1, "http://example.net/w.js", "name2"));
+ EXPECT_FALSE(Matches(instance1, "http://example.net/w2.js", "name2"));
+ // This should match because the instance has the same data: URL, name, and
+ // constructor origin.
+ EXPECT_TRUE(Matches(instance1, kDataURL, ""));
+ EXPECT_FALSE(Matches(instance1, kDataURL, "name"));
+
+ // SharedWorker created from a data: URL with a name option.
+ GURL script_url2(kDataURL);
+ std::string name2("name");
+ url::Origin constructor_origin2 =
+ url::Origin::Create(GURL("http://example.com/"));
+ SharedWorkerInstance instance2 =
+ CreateInstance(script_url2, name2, constructor_origin2);
+
+ EXPECT_FALSE(Matches(instance2, "http://example.com/w.js", ""));
+ EXPECT_FALSE(Matches(instance2, "http://example.com/w2.js", ""));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w.js", ""));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w2.js", ""));
+ EXPECT_FALSE(Matches(instance2, "http://example.com/w.js", "name"));
+ EXPECT_FALSE(Matches(instance2, "http://example.com/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w.js", "name"));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance2, "http://example.com/w.js", "name2"));
+ EXPECT_FALSE(Matches(instance2, "http://example.com/w2.js", "name2"));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w.js", "name2"));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w2.js", "name2"));
+ EXPECT_FALSE(Matches(instance2, kDataURL, ""));
+ // This should match because the instance has the same data: URL, name, and
+ // constructor origin.
+ EXPECT_TRUE(Matches(instance2, kDataURL, "name"));
+
+ // SharedWorker created from a data: URL on a remote origin (i.e., example.net
+ // opposed to example.com) without a name option.
+ GURL script_url3(kDataURL);
+ std::string name3("");
+ url::Origin constructor_origin3 =
+ url::Origin::Create(GURL("http://example.net/"));
+ SharedWorkerInstance instance3 =
+ CreateInstance(script_url3, name3, constructor_origin3);
+
+ EXPECT_FALSE(Matches(instance3, "http://example.com/w.js", ""));
+ EXPECT_FALSE(Matches(instance3, "http://example.com/w2.js", ""));
+ EXPECT_FALSE(Matches(instance3, "http://example.net/w.js", ""));
+ EXPECT_FALSE(Matches(instance3, "http://example.net/w2.js", ""));
+ EXPECT_FALSE(Matches(instance3, "http://example.com/w.js", "name"));
+ EXPECT_FALSE(Matches(instance3, "http://example.com/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance3, "http://example.net/w.js", "name"));
+ EXPECT_FALSE(Matches(instance3, "http://example.net/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance3, "http://example.com/w.js", "name2"));
+ EXPECT_FALSE(Matches(instance3, "http://example.com/w2.js", "name2"));
+ EXPECT_FALSE(Matches(instance3, "http://example.net/w.js", "name2"));
+ EXPECT_FALSE(Matches(instance3, "http://example.net/w2.js", "name2"));
+ // This should not match because the instance has a different constructor
+ // origin.
+ EXPECT_FALSE(Matches(instance3, kDataURL, ""));
+ EXPECT_FALSE(Matches(instance3, kDataURL, "name"));
+
+ // SharedWorker created from a data: URL on a remote origin (i.e., example.net
+ // opposed to example.com) with a name option.
+ GURL script_url4(kDataURL);
+ std::string name4("");
+ url::Origin constructor_origin4 =
+ url::Origin::Create(GURL("http://example.net/"));
+ SharedWorkerInstance instance4 =
+ CreateInstance(script_url4, name4, constructor_origin4);
+
+ EXPECT_FALSE(Matches(instance4, "http://example.com/w.js", ""));
+ EXPECT_FALSE(Matches(instance4, "http://example.com/w2.js", ""));
+ EXPECT_FALSE(Matches(instance4, "http://example.net/w.js", ""));
+ EXPECT_FALSE(Matches(instance4, "http://example.net/w2.js", ""));
+ EXPECT_FALSE(Matches(instance4, "http://example.com/w.js", "name"));
+ EXPECT_FALSE(Matches(instance4, "http://example.com/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance4, "http://example.net/w.js", "name"));
+ EXPECT_FALSE(Matches(instance4, "http://example.net/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance4, "http://example.com/w.js", "name2"));
+ EXPECT_FALSE(Matches(instance4, "http://example.com/w2.js", "name2"));
+ EXPECT_FALSE(Matches(instance4, "http://example.net/w.js", "name2"));
+ EXPECT_FALSE(Matches(instance4, "http://example.net/w2.js", "name2"));
+ EXPECT_FALSE(Matches(instance4, kDataURL, ""));
+ // This should not match because the instance has a different constructor
+ // origin.
+ EXPECT_FALSE(Matches(instance4, kDataURL, "name"));
}
TEST_F(SharedWorkerInstanceTest, AddressSpace) {
for (int i = 0; i < static_cast<int>(blink::kWebAddressSpaceLast); i++) {
SharedWorkerInstance instance(
- GURL("http://example.com/w.js"), "name", std::string(),
+ GURL("http://example.com/w.js"), "name",
+ url::Origin::Create(GURL("http://example.com/")), std::string(),
blink::kWebContentSecurityPolicyTypeReport,
static_cast<blink::WebAddressSpace>(i),
browser_context_->GetResourceContext(), partition_id_,
blink::mojom::SharedWorkerCreationContextType::kNonsecure,
- false /* data_saver_enabled */);
+ base::UnguessableToken::Create());
EXPECT_EQ(static_cast<blink::WebAddressSpace>(i),
instance.creation_address_space());
}
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 b698edb4962..ecf29e7851d 100644
--- a/chromium/content/browser/shared_worker/shared_worker_service_impl.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -16,12 +16,17 @@
#include "content/browser/devtools/shared_worker_devtools_manager.h"
#include "content/browser/shared_worker/shared_worker_host.h"
#include "content/browser/shared_worker/shared_worker_instance.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/shared_worker/shared_worker_client.mojom.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/worker_service_observer.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/common/bind_interface_helpers.h"
#include "third_party/WebKit/common/message_port/message_port_channel.h"
+#include "url/origin.h"
namespace content {
namespace {
@@ -33,11 +38,8 @@ bool IsShuttingDown(RenderProcessHost* host) {
} // namespace
-WorkerService* WorkerService::GetInstance() {
- return SharedWorkerServiceImpl::GetInstance();
-}
-
-SharedWorkerServiceImpl* SharedWorkerServiceImpl::GetInstance() {
+// static
+SharedWorkerService* SharedWorkerService::GetInstance() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// OK to just leak the instance.
// TODO(darin): Consider hanging instances off of StoragePartitionImpl.
@@ -53,10 +55,40 @@ SharedWorkerServiceImpl::~SharedWorkerServiceImpl() {}
void SharedWorkerServiceImpl::ResetForTesting() {
worker_hosts_.clear();
- observers_.Clear();
}
-bool SharedWorkerServiceImpl::TerminateWorker(int process_id, int route_id) {
+bool SharedWorkerServiceImpl::TerminateWorker(
+ const GURL& url,
+ const std::string& name,
+ const url::Origin& constructor_origin,
+ StoragePartition* storage_partition,
+ ResourceContext* resource_context) {
+ StoragePartitionImpl* storage_partition_impl =
+ static_cast<StoragePartitionImpl*>(storage_partition);
+ WorkerStoragePartitionId partition_id(WorkerStoragePartition(
+ storage_partition_impl->GetURLRequestContext(),
+ storage_partition_impl->GetMediaURLRequestContext(),
+ storage_partition_impl->GetAppCacheService(),
+ storage_partition_impl->GetQuotaManager(),
+ storage_partition_impl->GetFileSystemContext(),
+ storage_partition_impl->GetDatabaseTracker(),
+ storage_partition_impl->GetIndexedDBContext(),
+ storage_partition_impl->GetServiceWorkerContext()));
+
+ for (const auto& iter : worker_hosts_) {
+ SharedWorkerHost* host = iter.second.get();
+ if (host->IsAvailable() &&
+ host->instance()->Matches(url, name, constructor_origin, partition_id,
+ resource_context)) {
+ host->TerminateWorker();
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SharedWorkerServiceImpl::TerminateWorkerById(int process_id,
+ int route_id) {
SharedWorkerHost* host = FindSharedWorkerHost(process_id, route_id);
if (!host || !host->instance())
return false;
@@ -80,34 +112,6 @@ void SharedWorkerServiceImpl::TerminateAllWorkersForTesting(
}
}
-std::vector<WorkerService::WorkerInfo> SharedWorkerServiceImpl::GetWorkers() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- std::vector<WorkerService::WorkerInfo> results;
- for (const auto& iter : worker_hosts_) {
- SharedWorkerHost* host = iter.second.get();
- const SharedWorkerInstance* instance = host->instance();
- if (instance) {
- WorkerService::WorkerInfo info;
- info.url = instance->url();
- info.name = instance->name();
- info.route_id = host->route_id();
- info.process_id = host->process_id();
- results.push_back(info);
- }
- }
- return results;
-}
-
-void SharedWorkerServiceImpl::AddObserver(WorkerServiceObserver* observer) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- observers_.AddObserver(observer);
-}
-
-void SharedWorkerServiceImpl::RemoveObserver(WorkerServiceObserver* observer) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- observers_.RemoveObserver(observer);
-}
-
void SharedWorkerServiceImpl::ConnectToWorker(
int process_id,
int frame_id,
@@ -119,14 +123,42 @@ void SharedWorkerServiceImpl::ConnectToWorker(
const WorkerStoragePartitionId& partition_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RenderFrameHostImpl* render_frame_host =
+ RenderFrameHostImpl::FromID(process_id, frame_id);
+ if (!render_frame_host) {
+ // TODO(nhiroki): Support the case where the requester is a worker (i.e.,
+ // nested worker) (https://crbug.com/31666).
+ client->OnScriptLoadFailed();
+ return;
+ }
+
+ RenderFrameHost* main_frame =
+ render_frame_host->frame_tree_node()->frame_tree()->GetMainFrame();
+ if (!GetContentClient()->browser()->AllowSharedWorker(
+ info->url, main_frame->GetLastCommittedURL(), info->name,
+ render_frame_host->GetLastCommittedOrigin(),
+ WebContentsImpl::FromRenderFrameHostID(process_id, frame_id)
+ ->GetBrowserContext(),
+ process_id, frame_id)) {
+ client->OnScriptLoadFailed();
+ return;
+ }
+
auto instance = std::make_unique<SharedWorkerInstance>(
- info->url, info->name, info->content_security_policy,
- info->content_security_policy_type, info->creation_address_space,
- resource_context, partition_id, creation_context_type,
- info->data_saver_enabled);
+ info->url, info->name, render_frame_host->GetLastCommittedOrigin(),
+ info->content_security_policy, info->content_security_policy_type,
+ info->creation_address_space, resource_context, partition_id,
+ creation_context_type, base::UnguessableToken::Create());
SharedWorkerHost* host = FindAvailableSharedWorkerHost(*instance);
if (host) {
+ // Non-secure contexts cannot connect to secure workers, and secure contexts
+ // cannot connect to non-secure workers:
+ if (host->instance()->creation_context_type() != creation_context_type) {
+ client->OnScriptLoadFailed();
+ return;
+ }
+
// The process may be shutting down, in which case we will try to create a
// new shared worker instead.
if (!IsShuttingDown(RenderProcessHost::FromID(host->process_id()))) {
@@ -147,9 +179,6 @@ void SharedWorkerServiceImpl::ConnectToWorker(
void SharedWorkerServiceImpl::DestroyHost(int process_id, int route_id) {
worker_hosts_.erase(WorkerID(process_id, route_id));
- for (auto& observer : observers_)
- observer.WorkerDestroyed(process_id, route_id);
-
// Complete the call to TerminateAllWorkersForTesting if no more workers.
if (worker_hosts_.empty() && terminate_all_workers_callback_)
std::move(terminate_all_workers_callback_).Run();
@@ -200,9 +229,6 @@ void SharedWorkerServiceImpl::CreateWorker(
const std::string name = host->instance()->name();
worker_hosts_[WorkerID(worker_process_id, worker_route_id)] = std::move(host);
-
- for (auto& observer : observers_)
- observer.WorkerCreated(url, name, worker_process_id, worker_route_id);
}
SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(int process_id,
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 756fab620e3..ce7d66dbf81 100644
--- a/chromium/content/browser/shared_worker/shared_worker_service_impl.h
+++ b/chromium/content/browser/shared_worker/shared_worker_service_impl.h
@@ -14,13 +14,10 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/singleton.h"
-#include "base/observer_list.h"
#include "content/browser/shared_worker/shared_worker_host.h"
#include "content/common/shared_worker/shared_worker_connector.mojom.h"
#include "content/common/shared_worker/shared_worker_factory.mojom.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/worker_service.h"
+#include "content/public/browser/shared_worker_service.h"
namespace blink {
class MessagePortChannel;
@@ -30,23 +27,22 @@ namespace content {
class SharedWorkerInstance;
class SharedWorkerHost;
+class StoragePartition;
class ResourceContext;
-class WorkerServiceObserver;
class WorkerStoragePartitionId;
-// The implementation of WorkerService. We try to place workers in an existing
-// renderer process when possible.
-class CONTENT_EXPORT SharedWorkerServiceImpl : public WorkerService {
+class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
public:
- // Returns the SharedWorkerServiceImpl singleton.
- static SharedWorkerServiceImpl* GetInstance();
+ // SharedWorkerService implementation.
+ bool TerminateWorker(const GURL& url,
+ const std::string& name,
+ const url::Origin& constructor_origin,
+ StoragePartition* storage_partition,
+ ResourceContext* resource_context) override;
- // WorkerService implementation:
- bool TerminateWorker(int process_id, int route_id) override;
- void TerminateAllWorkersForTesting(base::OnceClosure callback) override;
- std::vector<WorkerInfo> GetWorkers() override;
- void AddObserver(WorkerServiceObserver* observer) override;
- void RemoveObserver(WorkerServiceObserver* observer) override;
+ // Terminates the given worker. Returns true if the process was found.
+ bool TerminateWorkerById(int process_id, int route_id);
+ void TerminateAllWorkersForTesting(base::OnceClosure callback);
// Creates the worker if necessary or connects to an already existing worker.
void ConnectToWorker(
@@ -64,6 +60,7 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public WorkerService {
private:
friend struct base::DefaultSingletonTraits<SharedWorkerServiceImpl>;
friend class SharedWorkerServiceImplTest;
+ friend class SharedWorkerService;
using WorkerID = std::pair<int /* process_id */, int /* route_id */>;
using WorkerHostMap = std::map<WorkerID, std::unique_ptr<SharedWorkerHost>>;
@@ -85,7 +82,6 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public WorkerService {
const SharedWorkerInstance& instance);
WorkerHostMap worker_hosts_;
- base::ObserverList<WorkerServiceObserver> observers_;
base::OnceClosure terminate_all_workers_callback_;
DISALLOW_COPY_AND_ASSIGN(SharedWorkerServiceImpl);
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 0644ff6189b..b78a6c99e25 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
@@ -21,11 +21,14 @@
#include "base/synchronization/lock.h"
#include "content/browser/shared_worker/shared_worker_connector_impl.h"
#include "content/browser/shared_worker/worker_storage_partition.h"
+#include "content/browser/site_instance_impl.h"
#include "content/public/browser/storage_partition.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_utils.h"
+#include "content/test/test_render_frame_host.h"
+#include "content/test/test_render_view_host.h"
+#include "content/test/test_web_contents.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/common/message_port/message_port_channel.h"
@@ -34,7 +37,7 @@ using blink::MessagePortChannel;
namespace content {
-class SharedWorkerServiceImplTest : public testing::Test {
+class SharedWorkerServiceImplTest : public RenderViewHostImplTestHarness {
public:
mojom::SharedWorkerConnectorPtr MakeSharedWorkerConnector(
RenderProcessHost* process_host,
@@ -65,18 +68,17 @@ class SharedWorkerServiceImplTest : public testing::Test {
mojom::SharedWorkerFactoryRequest(std::move(handle)));
}
- std::unique_ptr<MockRenderProcessHost> MakeMockRenderProcessHost() {
- auto host = std::make_unique<MockRenderProcessHost>(browser_context_.get());
- host->OverrideBinderForTesting(
- mojom::SharedWorkerFactory::Name_,
- base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
- return host;
+ std::unique_ptr<TestWebContents> CreateWebContents(const GURL& url) {
+ std::unique_ptr<TestWebContents> web_contents(TestWebContents::Create(
+ browser_context_.get(),
+ SiteInstanceImpl::Create(browser_context_.get())));
+ web_contents->NavigateAndCommit(url);
+ return web_contents;
}
protected:
SharedWorkerServiceImplTest()
- : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- browser_context_(new TestBrowserContext()),
+ : browser_context_(new TestBrowserContext()),
partition_(new WorkerStoragePartition(
BrowserContext::GetDefaultStoragePartition(browser_context_.get())
->GetURLRequestContext(),
@@ -86,20 +88,28 @@ class SharedWorkerServiceImplTest : public testing::Test {
nullptr /* filesystem_context */,
nullptr /* database_tracker */,
nullptr /* indexed_db_context */,
- nullptr /* service_worker_context */)) {
+ nullptr /* service_worker_context */)) {}
+
+ void SetUp() override {
+ RenderViewHostImplTestHarness::SetUp();
+ render_process_host_factory_ =
+ std::make_unique<MockRenderProcessHostFactory>();
+ RenderProcessHostImpl::set_render_process_host_factory(
+ render_process_host_factory_.get());
}
- void SetUp() override {}
-
void TearDown() override {
- SharedWorkerServiceImpl::GetInstance()->ResetForTesting();
+ static_cast<SharedWorkerServiceImpl*>(SharedWorkerService::GetInstance())
+ ->ResetForTesting();
+ browser_context_.reset();
+ RenderViewHostImplTestHarness::TearDown();
}
- TestBrowserThreadBundle browser_thread_bundle_;
std::unique_ptr<TestBrowserContext> browser_context_;
std::unique_ptr<WorkerStoragePartition> partition_;
static std::queue<mojom::SharedWorkerFactoryRequest>
s_factory_request_received_;
+ std::unique_ptr<MockRenderProcessHostFactory> render_process_host_factory_;
private:
DISALLOW_COPY_AND_ASSIGN(SharedWorkerServiceImplTest);
@@ -111,8 +121,6 @@ std::queue<mojom::SharedWorkerFactoryRequest>
namespace {
-static const int kRenderFrameRouteIDs[] = {300, 301, 302};
-
template <typename T>
static bool CheckEquality(const T& expected, const T& actual) {
EXPECT_EQ(expected, actual);
@@ -126,7 +134,7 @@ std::vector<uint8_t> StringPieceToVector(base::StringPiece s) {
void BlockingReadFromMessagePort(MessagePortChannel port,
std::vector<uint8_t>* message) {
base::RunLoop run_loop;
- port.SetCallback(run_loop.QuitClosure());
+ port.SetCallback(run_loop.QuitClosure(), base::ThreadTaskRunnerHandle::Get());
run_loop.Run();
std::vector<MessagePortChannel> should_be_empty;
@@ -198,6 +206,8 @@ class MockSharedWorkerFactory : public mojom::SharedWorkerFactory {
if (!CheckEquality(expected_content_security_policy_type,
create_params->info->content_security_policy_type))
return false;
+ if (!create_params->interface_provider)
+ return false;
*host = std::move(create_params->host);
*request = std::move(create_params->request);
return true;
@@ -208,10 +218,13 @@ class MockSharedWorkerFactory : public mojom::SharedWorkerFactory {
void CreateSharedWorker(
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
+ const base::UnguessableToken& devtools_worker_token,
int32_t route_id,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::SharedWorkerHostPtr host,
- mojom::SharedWorkerRequest request) override {
+ mojom::SharedWorkerRequest request,
+ service_manager::mojom::InterfaceProviderPtr interface_provider)
+ override {
CHECK(!create_params_);
create_params_ = std::make_unique<CreateParams>();
create_params_->info = std::move(info);
@@ -220,6 +233,7 @@ class MockSharedWorkerFactory : public mojom::SharedWorkerFactory {
create_params_->content_settings = std::move(content_settings);
create_params_->host = std::move(host);
create_params_->request = std::move(request);
+ create_params_->interface_provider = std::move(interface_provider);
}
struct CreateParams {
@@ -229,6 +243,7 @@ class MockSharedWorkerFactory : public mojom::SharedWorkerFactory {
blink::mojom::WorkerContentSettingsProxyPtr content_settings;
mojom::SharedWorkerHostPtr host;
mojom::SharedWorkerRequest request;
+ service_manager::mojom::InterfaceProviderPtr interface_provider;
};
mojo::Binding<mojom::SharedWorkerFactory> binding_;
@@ -308,10 +323,10 @@ void ConnectToSharedWorker(mojom::SharedWorkerConnectorPtr connector,
const std::string& name,
MockSharedWorkerClient* client,
MessagePortChannel* local_port) {
- mojom::SharedWorkerInfoPtr info(mojom::SharedWorkerInfo::New(
- GURL(url), name, std::string(),
- blink::kWebContentSecurityPolicyTypeReport, blink::kWebAddressSpacePublic,
- false /* data_saver_enabled */));
+ mojom::SharedWorkerInfoPtr info(
+ mojom::SharedWorkerInfo::New(GURL(url), name, std::string(),
+ blink::kWebContentSecurityPolicyTypeReport,
+ blink::kWebAddressSpacePublic));
mojo::MessagePipe message_pipe;
*local_port = MessagePortChannel(std::move(message_pipe.handle0));
@@ -327,14 +342,20 @@ void ConnectToSharedWorker(mojom::SharedWorkerConnectorPtr connector,
} // namespace
TEST_F(SharedWorkerServiceImplTest, BasicTest) {
- std::unique_ptr<MockRenderProcessHost> renderer_host(
- MakeMockRenderProcessHost());
- MockSharedWorkerClient client;
+ std::unique_ptr<TestWebContents> web_contents =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host = web_contents->GetMainFrame();
+ MockRenderProcessHost* renderer_host = render_frame_host->GetProcess();
+ renderer_host->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+ MockSharedWorkerClient client;
MessagePortChannel local_port;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host.get(), kRenderFrameRouteIDs[0]),
- "http://example.com/w.js", "name", &client, &local_port);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host, render_frame_host->GetRoutingID()),
+ "http://example.com/w.js", "name", &client,
+ &local_port);
RunAllPendingInMessageLoop();
@@ -396,14 +417,20 @@ TEST_F(SharedWorkerServiceImplTest, BasicTest) {
TEST_F(SharedWorkerServiceImplTest, TwoRendererTest) {
// The first renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host0(
- MakeMockRenderProcessHost());
- MockSharedWorkerClient client0;
+ std::unique_ptr<TestWebContents> web_contents0 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
+ MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
+ renderer_host0->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+ MockSharedWorkerClient client0;
MessagePortChannel local_port0;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host0.get(), kRenderFrameRouteIDs[0]),
- "http://example.com/w.js", "name", &client0, &local_port0);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host0, render_frame_host0->GetRoutingID()),
+ "http://example.com/w.js", "name", &client0,
+ &local_port0);
RunAllPendingInMessageLoop();
@@ -458,14 +485,20 @@ TEST_F(SharedWorkerServiceImplTest, TwoRendererTest) {
EXPECT_EQ(1u, renderer_host0->GetKeepAliveRefCount());
// The second renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host1(
- MakeMockRenderProcessHost());
- MockSharedWorkerClient client1;
+ std::unique_ptr<TestWebContents> web_contents1 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
+ MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
+ renderer_host1->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+ MockSharedWorkerClient client1;
MessagePortChannel local_port1;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host1.get(), kRenderFrameRouteIDs[1]),
- "http://example.com/w.js", "name", &client1, &local_port1);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host1, render_frame_host1->GetRoutingID()),
+ "http://example.com/w.js", "name", &client1,
+ &local_port1);
RunAllPendingInMessageLoop();
@@ -506,9 +539,6 @@ TEST_F(SharedWorkerServiceImplTest, TwoRendererTest) {
RunAllPendingInMessageLoop();
EXPECT_TRUE(client0.CheckReceivedOnFeatureUsed(feature3));
EXPECT_TRUE(client1.CheckReceivedOnFeatureUsed(feature3));
-
- renderer_host1.reset();
- renderer_host0.reset();
}
TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase) {
@@ -516,19 +546,30 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase) {
const char kName[] = "name";
// The first renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host0(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents0 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
+ MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
+ renderer_host0->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+
// The second renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host1(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents1 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
+ MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
+ renderer_host1->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
// First client, creates worker.
MockSharedWorkerClient client0;
MessagePortChannel local_port0;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host0.get(), kRenderFrameRouteIDs[0]),
- kURL, kName, &client0, &local_port0);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host0, render_frame_host0->GetRoutingID()),
+ kURL, kName, &client0, &local_port0);
RunAllPendingInMessageLoop();
mojom::SharedWorkerFactoryRequest factory_request;
@@ -551,9 +592,9 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase) {
MockSharedWorkerClient client1;
MessagePortChannel local_port1;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host1.get(), kRenderFrameRouteIDs[1]),
- kURL, kName, &client1, &local_port1);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host1, render_frame_host1->GetRoutingID()),
+ kURL, kName, &client1, &local_port1);
RunAllPendingInMessageLoop();
EXPECT_TRUE(CheckNotReceivedFactoryRequest());
@@ -576,19 +617,30 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase_URLMismatch) {
const char kName[] = "name";
// The first renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host0(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents0 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
+ MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
+ renderer_host0->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+
// The second renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host1(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents1 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
+ MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
+ renderer_host1->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
// First client, creates worker.
MockSharedWorkerClient client0;
MessagePortChannel local_port0;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host0.get(), kRenderFrameRouteIDs[0]),
- kURL0, kName, &client0, &local_port0);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host0, render_frame_host0->GetRoutingID()),
+ kURL0, kName, &client0, &local_port0);
RunAllPendingInMessageLoop();
mojom::SharedWorkerFactoryRequest factory_request0;
@@ -611,9 +663,9 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase_URLMismatch) {
MockSharedWorkerClient client1;
MessagePortChannel local_port1;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host1.get(), kRenderFrameRouteIDs[1]),
- kURL1, kName, &client1, &local_port1);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host1, render_frame_host1->GetRoutingID()),
+ kURL1, kName, &client1, &local_port1);
RunAllPendingInMessageLoop();
mojom::SharedWorkerFactoryRequest factory_request1;
@@ -648,19 +700,30 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase_NameMismatch) {
const char kName1[] = "name1";
// The first renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host0(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents0 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
+ MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
+ renderer_host0->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+
// The second renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host1(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents1 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
+ MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
+ renderer_host1->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
// First client, creates worker.
MockSharedWorkerClient client0;
MessagePortChannel local_port0;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host0.get(), kRenderFrameRouteIDs[0]),
- kURL, kName0, &client0, &local_port0);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host0, render_frame_host0->GetRoutingID()),
+ kURL, kName0, &client0, &local_port0);
RunAllPendingInMessageLoop();
mojom::SharedWorkerFactoryRequest factory_request0;
@@ -683,9 +746,9 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase_NameMismatch) {
MockSharedWorkerClient client1;
MessagePortChannel local_port1;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host1.get(), kRenderFrameRouteIDs[1]),
- kURL, kName1, &client1, &local_port1);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host1, render_frame_host1->GetRoutingID()),
+ kURL, kName1, &client1, &local_port1);
RunAllPendingInMessageLoop();
mojom::SharedWorkerFactoryRequest factory_request1;
@@ -719,25 +782,36 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_PendingCase) {
const char kName[] = "name";
// The first renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host0(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents0 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
+ MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
+ renderer_host0->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+
// The second renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host1(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents1 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
+ MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
+ renderer_host1->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
// First client and second client are created before the worker starts.
MockSharedWorkerClient client0;
MessagePortChannel local_port0;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host0.get(), kRenderFrameRouteIDs[0]),
- kURL, kName, &client0, &local_port0);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host0, render_frame_host0->GetRoutingID()),
+ kURL, kName, &client0, &local_port0);
MockSharedWorkerClient client1;
MessagePortChannel local_port1;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host1.get(), kRenderFrameRouteIDs[1]),
- kURL, kName, &client1, &local_port1);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host1, render_frame_host1->GetRoutingID()),
+ kURL, kName, &client1, &local_port1);
RunAllPendingInMessageLoop();
@@ -781,25 +855,36 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_PendingCase_URLMismatch) {
const char kName[] = "name";
// The first renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host0(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents0 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
+ MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
+ renderer_host0->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+
// The second renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host1(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents1 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
+ MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
+ renderer_host1->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
// First client and second client are created before the workers start.
MockSharedWorkerClient client0;
MessagePortChannel local_port0;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host0.get(), kRenderFrameRouteIDs[0]),
- kURL0, kName, &client0, &local_port0);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host0, render_frame_host0->GetRoutingID()),
+ kURL0, kName, &client0, &local_port0);
MockSharedWorkerClient client1;
MessagePortChannel local_port1;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host1.get(), kRenderFrameRouteIDs[1]),
- kURL1, kName, &client1, &local_port1);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host1, render_frame_host1->GetRoutingID()),
+ kURL1, kName, &client1, &local_port1);
RunAllPendingInMessageLoop();
@@ -857,25 +942,36 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_PendingCase_NameMismatch) {
const char kName1[] = "name1";
// The first renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host0(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents0 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
+ MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
+ renderer_host0->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+
// The second renderer host.
- std::unique_ptr<MockRenderProcessHost> renderer_host1(
- MakeMockRenderProcessHost());
+ std::unique_ptr<TestWebContents> web_contents1 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
+ MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
+ renderer_host1->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
// First client and second client are created before the workers start.
MockSharedWorkerClient client0;
MessagePortChannel local_port0;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host0.get(), kRenderFrameRouteIDs[0]),
- kURL, kName0, &client0, &local_port0);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host0, render_frame_host0->GetRoutingID()),
+ kURL, kName0, &client0, &local_port0);
MockSharedWorkerClient client1;
MessagePortChannel local_port1;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host1.get(), kRenderFrameRouteIDs[1]),
- kURL, kName1, &client1, &local_port1);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host1, render_frame_host1->GetRoutingID()),
+ kURL, kName1, &client1, &local_port1);
RunAllPendingInMessageLoop();
@@ -932,18 +1028,36 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest) {
const char kName[] = "name";
// Create three renderer hosts.
- std::unique_ptr<MockRenderProcessHost> renderer_host0(
- MakeMockRenderProcessHost());
- std::unique_ptr<MockRenderProcessHost> renderer_host1(
- MakeMockRenderProcessHost());
- std::unique_ptr<MockRenderProcessHost> renderer_host2(
- MakeMockRenderProcessHost());
+
+ std::unique_ptr<TestWebContents> web_contents0 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
+ MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
+ renderer_host0->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+
+ std::unique_ptr<TestWebContents> web_contents1 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
+ MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
+ renderer_host1->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+
+ std::unique_ptr<TestWebContents> web_contents2 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host2 = web_contents2->GetMainFrame();
+ MockRenderProcessHost* renderer_host2 = render_frame_host2->GetProcess();
+ renderer_host2->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
MockSharedWorkerClient client0;
MessagePortChannel local_port0;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host0.get(), kRenderFrameRouteIDs[0]),
- kURL, kName, &client0, &local_port0);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host0, render_frame_host0->GetRoutingID()),
+ kURL, kName, &client0, &local_port0);
RunAllPendingInMessageLoop();
@@ -968,14 +1082,16 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest) {
client0.CheckReceivedOnCreated();
// Kill this process, which should make worker0 unavailable.
+ web_contents0.reset();
renderer_host0->FastShutdownIfPossible(0, true);
+ ASSERT_TRUE(renderer_host0->FastShutdownStarted());
// Start a new client, attemping to connect to the same worker.
MockSharedWorkerClient client1;
MessagePortChannel local_port1;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host1.get(), kRenderFrameRouteIDs[1]),
- kURL, kName, &client1, &local_port1);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host1, render_frame_host1->GetRoutingID()),
+ kURL, kName, &client1, &local_port1);
RunAllPendingInMessageLoop();
@@ -1003,9 +1119,9 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest) {
// Start another client to confirm that it can connect to the same worker.
MockSharedWorkerClient client2;
MessagePortChannel local_port2;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host2.get(), kRenderFrameRouteIDs[2]),
- kURL, kName, &client2, &local_port2);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host2, render_frame_host2->GetRoutingID()),
+ kURL, kName, &client2, &local_port2);
RunAllPendingInMessageLoop();
@@ -1020,18 +1136,36 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest2) {
const char kName[] = "name";
// Create three renderer hosts.
- std::unique_ptr<MockRenderProcessHost> renderer_host0(
- MakeMockRenderProcessHost());
- std::unique_ptr<MockRenderProcessHost> renderer_host1(
- MakeMockRenderProcessHost());
- std::unique_ptr<MockRenderProcessHost> renderer_host2(
- MakeMockRenderProcessHost());
+
+ std::unique_ptr<TestWebContents> web_contents0 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
+ MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
+ renderer_host0->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+
+ std::unique_ptr<TestWebContents> web_contents1 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
+ MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
+ renderer_host1->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
+
+ std::unique_ptr<TestWebContents> web_contents2 =
+ CreateWebContents(GURL("http://example.com/"));
+ TestRenderFrameHost* render_frame_host2 = web_contents2->GetMainFrame();
+ MockRenderProcessHost* renderer_host2 = render_frame_host2->GetProcess();
+ renderer_host2->OverrideBinderForTesting(
+ mojom::SharedWorkerFactory::Name_,
+ base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));
MockSharedWorkerClient client0;
MessagePortChannel local_port0;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host0.get(), kRenderFrameRouteIDs[0]),
- kURL, kName, &client0, &local_port0);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host0, render_frame_host0->GetRoutingID()),
+ kURL, kName, &client0, &local_port0);
// Kill this process, which should make worker0 unavailable.
renderer_host0->FastShutdownIfPossible(0, true);
@@ -1039,9 +1173,9 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest2) {
// Start a new client, attemping to connect to the same worker.
MockSharedWorkerClient client1;
MessagePortChannel local_port1;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host1.get(), kRenderFrameRouteIDs[1]),
- kURL, kName, &client1, &local_port1);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host1, render_frame_host1->GetRoutingID()),
+ kURL, kName, &client1, &local_port1);
RunAllPendingInMessageLoop();
@@ -1070,9 +1204,9 @@ TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest2) {
// Start another client to confirm that it can connect to the same worker.
MockSharedWorkerClient client2;
MessagePortChannel local_port2;
- ConnectToSharedWorker(
- MakeSharedWorkerConnector(renderer_host2.get(), kRenderFrameRouteIDs[2]),
- kURL, kName, &client2, &local_port2);
+ ConnectToSharedWorker(MakeSharedWorkerConnector(
+ renderer_host2, render_frame_host2->GetRoutingID()),
+ kURL, kName, &client2, &local_port2);
RunAllPendingInMessageLoop();
diff --git a/chromium/content/browser/shared_worker/worker_browsertest.cc b/chromium/content/browser/shared_worker/worker_browsertest.cc
index 8f439df1870..386c91fa4df 100644
--- a/chromium/content/browser/shared_worker/worker_browsertest.cc
+++ b/chromium/content/browser/shared_worker/worker_browsertest.cc
@@ -3,20 +3,19 @@
// found in the LICENSE file.
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_info.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/client_certificate_delegate.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/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
@@ -111,16 +110,20 @@ class WorkerTest : public ContentBrowserTest {
class WorkerFetchTest : public testing::WithParamInterface<bool>,
public WorkerTest {
public:
- ~WorkerFetchTest() override {}
- void SetUpCommandLine(base::CommandLine* command_line) override {
+ WorkerFetchTest() {
if (GetParam()) {
- command_line->AppendSwitchASCII(switches::kEnableFeatures,
- features::kOffMainThreadFetch.name);
+ scoped_feature_list_.InitAndEnableFeature(features::kOffMainThreadFetch);
} else {
- command_line->AppendSwitchASCII(switches::kDisableFeatures,
- features::kOffMainThreadFetch.name);
+ scoped_feature_list_.InitAndDisableFeature(features::kOffMainThreadFetch);
}
}
+
+ ~WorkerFetchTest() override {}
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(WorkerFetchTest);
};
IN_PROC_BROWSER_TEST_F(WorkerTest, SingleWorker) {
diff --git a/chromium/content/browser/site_instance_impl.cc b/chromium/content/browser/site_instance_impl.cc
index 68f9dbe8532..0801a629c98 100644
--- a/chromium/content/browser/site_instance_impl.cc
+++ b/chromium/content/browser/site_instance_impl.cc
@@ -5,6 +5,7 @@
#include "content/browser/site_instance_impl.h"
#include "base/command_line.h"
+#include "base/debug/crash_logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "content/browser/browsing_instance.h"
@@ -19,6 +20,7 @@
#include "content/public/browser/web_ui_controller_factory.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/url_utils.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
namespace content {
@@ -49,12 +51,14 @@ SiteInstanceImpl::~SiteInstanceImpl() {
browsing_instance_->UnregisterSiteInstance(this);
}
+// static
scoped_refptr<SiteInstanceImpl> SiteInstanceImpl::Create(
BrowserContext* browser_context) {
return base::WrapRefCounted(
new SiteInstanceImpl(new BrowsingInstance(browser_context)));
}
+// static
scoped_refptr<SiteInstanceImpl> SiteInstanceImpl::CreateForURL(
BrowserContext* browser_context,
const GURL& url) {
@@ -64,12 +68,24 @@ scoped_refptr<SiteInstanceImpl> SiteInstanceImpl::CreateForURL(
return instance->GetSiteInstanceForURL(url);
}
+// static
+bool SiteInstanceImpl::ShouldAssignSiteForURL(const GURL& url) {
+ // about:blank should not "use up" a new SiteInstance. The SiteInstance can
+ // still be used for a normal web site.
+ if (url == url::kAboutBlankURL)
+ return false;
+
+ // The embedder will then have the opportunity to determine if the URL
+ // should "use up" the SiteInstance.
+ return GetContentClient()->browser()->ShouldAssignSiteForURL(url);
+}
+
int32_t SiteInstanceImpl::GetId() {
return id_;
}
bool SiteInstanceImpl::HasProcess() const {
- if (process_ != NULL)
+ if (process_ != nullptr)
return true;
// If we would use process-per-site for this site, also check if there is an
@@ -149,6 +165,7 @@ void SiteInstanceImpl::SetSite(const GURL& url) {
has_site_ = true;
BrowserContext* browser_context = browsing_instance_->browser_context();
site_ = GetSiteForURL(browser_context, url);
+ original_url_ = url;
// Now that we have a site, register it with the BrowsingInstance. This
// ensures that we won't create another SiteInstance for this site within
@@ -292,13 +309,30 @@ scoped_refptr<SiteInstance> SiteInstance::CreateForURL(
}
// static
+bool SiteInstance::ShouldAssignSiteForURL(const GURL& url) {
+ return SiteInstanceImpl::ShouldAssignSiteForURL(url);
+}
+
+// static
bool SiteInstance::IsSameWebSite(BrowserContext* browser_context,
const GURL& real_src_url,
const GURL& real_dest_url) {
- GURL src_url = SiteInstanceImpl::GetEffectiveURL(browser_context,
- real_src_url);
- GURL dest_url = SiteInstanceImpl::GetEffectiveURL(browser_context,
- real_dest_url);
+ return SiteInstanceImpl::IsSameWebSite(browser_context, real_src_url,
+ real_dest_url, true);
+}
+
+bool SiteInstanceImpl::IsSameWebSite(BrowserContext* browser_context,
+ const GURL& real_src_url,
+ const GURL& real_dest_url,
+ bool should_compare_effective_urls) {
+ GURL src_url =
+ should_compare_effective_urls
+ ? SiteInstanceImpl::GetEffectiveURL(browser_context, real_src_url)
+ : real_src_url;
+ GURL dest_url =
+ should_compare_effective_urls
+ ? SiteInstanceImpl::GetEffectiveURL(browser_context, real_dest_url)
+ : real_dest_url;
// We infer web site boundaries based on the registered domain name of the
// top-level page and the scheme. We do not pay attention to the port if
@@ -321,8 +355,8 @@ bool SiteInstance::IsSameWebSite(BrowserContext* browser_context,
if (dest_url == blank_page)
return true;
- url::Origin src_origin(src_url);
- url::Origin dest_origin(dest_url);
+ url::Origin src_origin = url::Origin::Create(src_url);
+ url::Origin dest_origin = url::Origin::Create(dest_url);
// If the schemes differ, they aren't part of the same site.
if (src_origin.scheme() != dest_origin.scheme())
@@ -361,7 +395,7 @@ GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context,
return real_url;
GURL url = SiteInstanceImpl::GetEffectiveURL(browser_context, real_url);
- url::Origin origin(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
@@ -370,7 +404,7 @@ GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context,
// origin lookup.
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
url::Origin isolated_origin;
- if (policy->GetMatchingIsolatedOrigin(url::Origin(url),
+ if (policy->GetMatchingIsolatedOrigin(url::Origin::Create(url),
&isolated_origin)) {
return isolated_origin.GetURL();
}
@@ -400,10 +434,13 @@ GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context,
// static
GURL SiteInstanceImpl::GetEffectiveURL(BrowserContext* browser_context,
const GURL& url) {
- auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
- bool is_isolated_origin = policy->IsIsolatedOrigin(url::Origin(url));
- return GetContentClient()->browser()->GetEffectiveURL(browser_context, url,
- is_isolated_origin);
+ return GetContentClient()->browser()->GetEffectiveURL(browser_context, url);
+}
+
+// static
+bool SiteInstanceImpl::HasEffectiveURL(BrowserContext* browser_context,
+ const GURL& url) {
+ return GetEffectiveURL(browser_context, url) != url;
}
// static
@@ -417,7 +454,7 @@ bool SiteInstanceImpl::DoesSiteRequireDedicatedProcess(
// Always require a dedicated process for isolated origins.
GURL site_url = GetSiteForURL(browser_context, url);
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
- if (policy->IsIsolatedOrigin(url::Origin(site_url)))
+ if (policy->IsIsolatedOrigin(url::Origin::Create(site_url)))
return true;
// Let the content embedder enable site isolation for specific URLs. Use the
@@ -470,18 +507,6 @@ bool SiteInstanceImpl::ShouldLockToOrigin(BrowserContext* browser_context,
return true;
}
-// static
-bool SiteInstanceImpl::ShouldAssignSiteForURL(const GURL& url) {
- // about:blank should not "use up" a new SiteInstance. The SiteInstance can
- // still be used for a normal web site.
- if (url == url::kAboutBlankURL)
- return false;
-
- // The embedder will then have the opportunity to determine if the URL
- // should "use up" the SiteInstance.
- return GetContentClient()->browser()->ShouldAssignSiteForURL(url);
-}
-
void SiteInstanceImpl::RenderProcessHostDestroyed(RenderProcessHost* host) {
DCHECK_EQ(process_, host);
process_->RemoveObserver(this);
@@ -538,6 +563,10 @@ void SiteInstanceImpl::LockToOriginIfNeeded() {
HAS_WRONG_LOCK:
// We should never attempt to reassign a different origin lock to a
// process.
+ base::debug::SetCrashKeyValue("requested_site_url", site_.spec());
+ base::debug::SetCrashKeyValue(
+ "killed_process_origin_lock",
+ policy->GetOriginLock(process_->GetID()).spec());
CHECK(false) << "Trying to lock a process to " << site_
<< " but the process is already locked to "
<< policy->GetOriginLock(process_->GetID());
@@ -554,6 +583,10 @@ void SiteInstanceImpl::LockToOriginIfNeeded() {
// If the site that we've just committed doesn't require a dedicated
// process, make sure we aren't putting it in a process for a site that
// does.
+ base::debug::SetCrashKeyValue("requested_site_url", site_.spec());
+ base::debug::SetCrashKeyValue(
+ "killed_process_origin_lock",
+ policy->GetOriginLock(process_->GetID()).spec());
CHECK_EQ(lock_state,
ChildProcessSecurityPolicyImpl::CheckOriginLockResult::NO_LOCK)
<< "Trying to commit non-isolated site " << site_
diff --git a/chromium/content/browser/site_instance_impl.h b/chromium/content/browser/site_instance_impl.h
index cb74dfaf877..7548752f7d8 100644
--- a/chromium/content/browser/site_instance_impl.h
+++ b/chromium/content/browser/site_instance_impl.h
@@ -37,6 +37,16 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
static scoped_refptr<SiteInstanceImpl> CreateForURL(
BrowserContext* browser_context,
const GURL& url);
+ static bool ShouldAssignSiteForURL(const GURL& url);
+
+ // See SiteInstance::IsSameWebSite.
+ // This version allows comparing URLs without converting them to effective
+ // URLs first, which is useful for avoiding OOPIFs when otherwise same-site
+ // URLs may look cross-site via their effective URLs.
+ static bool IsSameWebSite(content::BrowserContext* browser_context,
+ const GURL& src_url,
+ const GURL& dest_url,
+ bool should_compare_effective_urls);
// SiteInstance interface overrides.
int32_t GetId() override;
@@ -96,6 +106,15 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
void set_is_for_service_worker() { is_for_service_worker_ = true; }
bool is_for_service_worker() const { return is_for_service_worker_; }
+ // Returns the URL which was used to set the |site_| for this SiteInstance.
+ // May be empty if this SiteInstance does not have a |site_|.
+ const GURL& original_url() { return original_url_; }
+
+ // True if |url| resolves to an effective URL that is different from |url|.
+ // See GetEffectiveURL(). This will be true for hosted apps as well as NTP
+ // URLs.
+ static bool HasEffectiveURL(BrowserContext* browser_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
@@ -176,10 +195,6 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
RenderProcessHost* host,
GURL site_url);
- // Determine if a URL should "use up" a site. URLs such as about:blank or
- // chrome-native:// leave the site unassigned.
- static bool ShouldAssignSiteForURL(const GURL& url);
-
private:
friend class BrowsingInstance;
friend class SiteInstanceTestBrowserClient;
@@ -232,6 +247,9 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
// Whether SetSite has been called.
bool has_site_;
+ // The URL which was used to set the |site_| for this SiteInstance.
+ GURL original_url_;
+
// The ProcessReusePolicy to use when creating a RenderProcessHost for this
// SiteInstance.
ProcessReusePolicy process_reuse_policy_;
diff --git a/chromium/content/browser/site_instance_impl_unittest.cc b/chromium/content/browser/site_instance_impl_unittest.cc
index c523ca9a06b..efcc82fe751 100644
--- a/chromium/content/browser/site_instance_impl_unittest.cc
+++ b/chromium/content/browser/site_instance_impl_unittest.cc
@@ -601,7 +601,7 @@ TEST_F(SiteInstanceTest, ProcessSharingByType) {
std::vector<std::unique_ptr<MockRenderProcessHost>> hosts;
for (size_t i = 0; i < kMaxRendererProcessCount; ++i)
hosts.push_back(
- base::MakeUnique<MockRenderProcessHost>(browser_context.get()));
+ std::make_unique<MockRenderProcessHost>(browser_context.get()));
// Create some extension instances and make sure they share a process.
scoped_refptr<SiteInstanceImpl> extension1_instance(
@@ -894,22 +894,23 @@ TEST_F(SiteInstanceTest, IsolatedOrigins) {
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
- EXPECT_FALSE(policy->IsIsolatedOrigin(url::Origin(isolated_foo_url)));
+ EXPECT_FALSE(policy->IsIsolatedOrigin(url::Origin::Create(isolated_foo_url)));
EXPECT_TRUE(SiteInstance::IsSameWebSite(nullptr, foo_url, isolated_foo_url));
- policy->AddIsolatedOrigins({url::Origin(isolated_foo_url)});
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(isolated_foo_url)));
- EXPECT_FALSE(policy->IsIsolatedOrigin(url::Origin(foo_url)));
- EXPECT_FALSE(policy->IsIsolatedOrigin(url::Origin(GURL("http://foo.com"))));
+ policy->AddIsolatedOrigins({url::Origin::Create(isolated_foo_url)});
+ EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin::Create(isolated_foo_url)));
+ EXPECT_FALSE(policy->IsIsolatedOrigin(url::Origin::Create(foo_url)));
EXPECT_FALSE(
- policy->IsIsolatedOrigin(url::Origin(GURL("http://www.bar.com"))));
- EXPECT_FALSE(
- policy->IsIsolatedOrigin(url::Origin(GURL("https://isolated.foo.com"))));
+ policy->IsIsolatedOrigin(url::Origin::Create(GURL("http://foo.com"))));
+ EXPECT_FALSE(policy->IsIsolatedOrigin(
+ url::Origin::Create(GURL("http://www.bar.com"))));
EXPECT_FALSE(policy->IsIsolatedOrigin(
- url::Origin(GURL("http://isolated.foo.com:12345"))));
+ url::Origin::Create(GURL("https://isolated.foo.com"))));
+ EXPECT_FALSE(policy->IsIsolatedOrigin(
+ url::Origin::Create(GURL("http://isolated.foo.com:12345"))));
- policy->AddIsolatedOrigins({url::Origin(isolated_bar_url)});
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(isolated_bar_url)));
+ policy->AddIsolatedOrigins({url::Origin::Create(isolated_bar_url)});
+ EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin::Create(isolated_bar_url)));
// IsSameWebSite should compare origins rather than sites if either URL is an
// isolated origin.
@@ -951,8 +952,8 @@ TEST_F(SiteInstanceTest, IsolatedOrigins) {
nullptr, isolated_filesystem_foo_url));
// Cleanup.
- policy->RemoveIsolatedOriginForTesting(url::Origin(isolated_foo_url));
- policy->RemoveIsolatedOriginForTesting(url::Origin(isolated_bar_url));
+ policy->RemoveIsolatedOriginForTesting(url::Origin::Create(isolated_foo_url));
+ policy->RemoveIsolatedOriginForTesting(url::Origin::Create(isolated_bar_url));
}
// Check that only valid isolated origins are allowed to be registered.
@@ -961,36 +962,36 @@ TEST_F(SiteInstanceTest, IsValidIsolatedOrigin) {
// unique origins.
EXPECT_FALSE(IsolatedOriginUtil::IsValidIsolatedOrigin(url::Origin()));
EXPECT_FALSE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL("invalid.url"))));
+ url::Origin::Create(GURL("invalid.url"))));
// IP addresses are ok.
EXPECT_TRUE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL("http://127.0.0.1"))));
+ url::Origin::Create(GURL("http://127.0.0.1"))));
// Hosts without a valid registry-controlled domain are disallowed. This
// includes hosts that are themselves a registry-controlled domain.
EXPECT_FALSE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL("http://.com/"))));
+ url::Origin::Create(GURL("http://.com/"))));
EXPECT_FALSE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL("http://.com./"))));
+ url::Origin::Create(GURL("http://.com./"))));
EXPECT_FALSE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL("http://foo/"))));
+ url::Origin::Create(GURL("http://foo/"))));
EXPECT_FALSE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL("http://co.uk/"))));
+ url::Origin::Create(GURL("http://co.uk/"))));
EXPECT_TRUE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL("http://foo.bar.baz/"))));
+ url::Origin::Create(GURL("http://foo.bar.baz/"))));
// Scheme must be HTTP or HTTPS.
EXPECT_FALSE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL(kChromeUIScheme + std::string("://gpu")))));
+ url::Origin::Create(GURL(kChromeUIScheme + std::string("://gpu")))));
EXPECT_TRUE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL("http://a.com"))));
+ url::Origin::Create(GURL("http://a.com"))));
EXPECT_TRUE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL("https://b.co.uk"))));
+ url::Origin::Create(GURL("https://b.co.uk"))));
// Trailing dot is disallowed.
EXPECT_FALSE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin(GURL("http://a.com."))));
+ url::Origin::Create(GURL("http://a.com."))));
}
TEST_F(SiteInstanceTest, SubdomainOnIsolatedSite) {
@@ -998,23 +999,23 @@ TEST_F(SiteInstanceTest, SubdomainOnIsolatedSite) {
GURL foo_isolated_url("http://foo.isolated.com");
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
- policy->AddIsolatedOrigins({url::Origin(isolated_url)});
+ policy->AddIsolatedOrigins({url::Origin::Create(isolated_url)});
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(isolated_url)));
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(foo_isolated_url)));
- EXPECT_FALSE(
- policy->IsIsolatedOrigin(url::Origin(GURL("http://unisolated.com"))));
- EXPECT_FALSE(
- policy->IsIsolatedOrigin(url::Origin(GURL("http://isolated.foo.com"))));
+ EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin::Create(isolated_url)));
+ EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin::Create(foo_isolated_url)));
+ EXPECT_FALSE(policy->IsIsolatedOrigin(
+ url::Origin::Create(GURL("http://unisolated.com"))));
+ EXPECT_FALSE(policy->IsIsolatedOrigin(
+ url::Origin::Create(GURL("http://isolated.foo.com"))));
// Wrong scheme.
- EXPECT_FALSE(
- policy->IsIsolatedOrigin(url::Origin(GURL("https://foo.isolated.com"))));
+ EXPECT_FALSE(policy->IsIsolatedOrigin(
+ url::Origin::Create(GURL("https://foo.isolated.com"))));
// Appending a trailing dot to a URL should not bypass process isolation.
- EXPECT_TRUE(
- policy->IsIsolatedOrigin(url::Origin(GURL("http://isolated.com."))));
- EXPECT_TRUE(
- policy->IsIsolatedOrigin(url::Origin(GURL("http://foo.isolated.com."))));
+ EXPECT_TRUE(policy->IsIsolatedOrigin(
+ url::Origin::Create(GURL("http://isolated.com."))));
+ EXPECT_TRUE(policy->IsIsolatedOrigin(
+ url::Origin::Create(GURL("http://foo.isolated.com."))));
// A new SiteInstance created for a subdomain on an isolated origin
// should use the isolated origin's host and not its own host as the site
@@ -1032,13 +1033,13 @@ TEST_F(SiteInstanceTest, SubdomainOnIsolatedSite) {
// Don't try to match subdomains on IP addresses.
GURL isolated_ip("http://127.0.0.1");
- policy->AddIsolatedOrigins({url::Origin(isolated_ip)});
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(isolated_ip)));
- EXPECT_FALSE(
- policy->IsIsolatedOrigin(url::Origin(GURL("http://42.127.0.0.1"))));
+ policy->AddIsolatedOrigins({url::Origin::Create(isolated_ip)});
+ EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin::Create(isolated_ip)));
+ EXPECT_FALSE(policy->IsIsolatedOrigin(
+ url::Origin::Create(GURL("http://42.127.0.0.1"))));
// Cleanup.
- policy->RemoveIsolatedOriginForTesting(url::Origin(isolated_url));
+ policy->RemoveIsolatedOriginForTesting(url::Origin::Create(isolated_url));
}
TEST_F(SiteInstanceTest, SubdomainOnIsolatedOrigin) {
@@ -1048,12 +1049,14 @@ TEST_F(SiteInstanceTest, SubdomainOnIsolatedOrigin) {
GURL baz_isolated_foo_url("http://baz.isolated.foo.com");
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
- policy->AddIsolatedOrigins({url::Origin(isolated_foo_url)});
+ policy->AddIsolatedOrigins({url::Origin::Create(isolated_foo_url)});
- EXPECT_FALSE(policy->IsIsolatedOrigin(url::Origin(foo_url)));
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(isolated_foo_url)));
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(bar_isolated_foo_url)));
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(baz_isolated_foo_url)));
+ EXPECT_FALSE(policy->IsIsolatedOrigin(url::Origin::Create(foo_url)));
+ EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin::Create(isolated_foo_url)));
+ EXPECT_TRUE(
+ policy->IsIsolatedOrigin(url::Origin::Create(bar_isolated_foo_url)));
+ EXPECT_TRUE(
+ policy->IsIsolatedOrigin(url::Origin::Create(baz_isolated_foo_url)));
EXPECT_EQ(foo_url, SiteInstance::GetSiteForURL(nullptr, foo_url));
EXPECT_EQ(isolated_foo_url,
@@ -1090,7 +1093,7 @@ TEST_F(SiteInstanceTest, SubdomainOnIsolatedOrigin) {
bar_isolated_foo_url));
// Cleanup.
- policy->RemoveIsolatedOriginForTesting(url::Origin(isolated_foo_url));
+ policy->RemoveIsolatedOriginForTesting(url::Origin::Create(isolated_foo_url));
}
TEST_F(SiteInstanceTest, MultipleIsolatedOriginsWithCommonSite) {
@@ -1100,13 +1103,14 @@ TEST_F(SiteInstanceTest, MultipleIsolatedOriginsWithCommonSite) {
GURL qux_baz_bar_foo_url("http://qux.baz.bar.foo.com");
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
- policy->AddIsolatedOrigins({url::Origin(foo_url)});
- policy->AddIsolatedOrigins({url::Origin(baz_bar_foo_url)});
+ policy->AddIsolatedOrigins(
+ {url::Origin::Create(foo_url), url::Origin::Create(baz_bar_foo_url)});
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(foo_url)));
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(bar_foo_url)));
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(baz_bar_foo_url)));
- EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin(qux_baz_bar_foo_url)));
+ EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin::Create(foo_url)));
+ EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin::Create(bar_foo_url)));
+ EXPECT_TRUE(policy->IsIsolatedOrigin(url::Origin::Create(baz_bar_foo_url)));
+ EXPECT_TRUE(
+ policy->IsIsolatedOrigin(url::Origin::Create(qux_baz_bar_foo_url)));
EXPECT_EQ(foo_url, SiteInstance::GetSiteForURL(nullptr, foo_url));
EXPECT_EQ(foo_url, SiteInstance::GetSiteForURL(nullptr, bar_foo_url));
@@ -1138,8 +1142,54 @@ TEST_F(SiteInstanceTest, MultipleIsolatedOriginsWithCommonSite) {
qux_baz_bar_foo_url));
// Cleanup.
- policy->RemoveIsolatedOriginForTesting(url::Origin(foo_url));
- policy->RemoveIsolatedOriginForTesting(url::Origin(baz_bar_foo_url));
+ policy->RemoveIsolatedOriginForTesting(url::Origin::Create(foo_url));
+ policy->RemoveIsolatedOriginForTesting(url::Origin::Create(baz_bar_foo_url));
+}
+
+// Check that new SiteInstances correctly preserve the full URL that was used
+// to initialize their site URL.
+TEST_F(SiteInstanceTest, OriginalURL) {
+ GURL original_url("https://foo.com/");
+ GURL app_url("https://app.com/");
+ EffectiveURLContentBrowserClient modified_client(original_url, app_url);
+ ContentBrowserClient* regular_client =
+ SetBrowserClientForTesting(&modified_client);
+ std::unique_ptr<TestBrowserContext> browser_context(new TestBrowserContext());
+
+ // New SiteInstance in a new BrowsingInstance with a predetermined URL.
+ {
+ scoped_refptr<SiteInstanceImpl> site_instance =
+ SiteInstanceImpl::CreateForURL(browser_context.get(), original_url);
+ EXPECT_EQ(app_url, site_instance->GetSiteURL());
+ EXPECT_EQ(original_url, site_instance->original_url());
+ }
+
+ // New related SiteInstance from an existing SiteInstance with a
+ // predetermined URL.
+ {
+ scoped_refptr<SiteInstanceImpl> bar_site_instance =
+ SiteInstanceImpl::CreateForURL(browser_context.get(),
+ GURL("https://bar.com/"));
+ scoped_refptr<SiteInstance> site_instance =
+ bar_site_instance->GetRelatedSiteInstance(original_url);
+ EXPECT_EQ(app_url, site_instance->GetSiteURL());
+ EXPECT_EQ(
+ original_url,
+ static_cast<SiteInstanceImpl*>(site_instance.get())->original_url());
+ }
+
+ // New SiteInstance with a lazily assigned site URL.
+ {
+ scoped_refptr<SiteInstanceImpl> site_instance =
+ SiteInstanceImpl::Create(browser_context.get());
+ EXPECT_FALSE(site_instance->HasSite());
+ EXPECT_TRUE(site_instance->original_url().is_empty());
+ site_instance->SetSite(original_url);
+ EXPECT_EQ(app_url, site_instance->GetSiteURL());
+ EXPECT_EQ(original_url, site_instance->original_url());
+ }
+
+ SetBrowserClientForTesting(regular_client);
}
} // namespace content
diff --git a/chromium/content/browser/site_per_process_browsertest.cc b/chromium/content/browser/site_per_process_browsertest.cc
index faee0e7a4d8..5ab401a805a 100644
--- a/chromium/content/browser/site_per_process_browsertest.cc
+++ b/chromium/content/browser/site_per_process_browsertest.cc
@@ -19,6 +19,7 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/feature_list.h"
+#include "base/json/json_reader.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
@@ -26,6 +27,8 @@
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/pattern.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_timeouts.h"
@@ -54,7 +57,6 @@
#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/child_process_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/input/synthetic_tap_gesture_params.h"
#include "content/common/input_messages.h"
@@ -79,6 +81,7 @@
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
+#include "content/shell/common/shell_switches.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "content/test/mock_overscroll_observer.h"
#include "ipc/constants.mojom.h"
@@ -91,10 +94,10 @@
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
+#include "third_party/WebKit/common/sandbox_flags.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
#include "ui/display/display_switches.h"
#include "ui/display/screen.h"
#include "ui/events/base_event_utils.h"
@@ -102,6 +105,7 @@
#include "ui/events/event_utils.h"
#include "ui/events/gesture_detection/gesture_configuration.h"
#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/rect.h"
#include "ui/latency/latency_info.h"
#include "ui/native_theme/native_theme_features.h"
@@ -620,6 +624,25 @@ class TestInterstitialDelegate : public InterstitialPageDelegate {
std::string GetHTMLContents() override { return "<p>Interstitial</p>"; }
};
+#if defined(USE_AURA) || defined(OS_ANDROID)
+bool ConvertJSONToPoint(const std::string& str, gfx::PointF* point) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(str);
+ if (!value)
+ return false;
+ base::DictionaryValue* root;
+ if (!value->GetAsDictionary(&root))
+ return false;
+ double x, y;
+ if (!root->GetDouble("x", &x))
+ return false;
+ if (!root->GetDouble("y", &y))
+ return false;
+ point->set_x(x);
+ point->set_y(y);
+ return true;
+}
+#endif // defined(USE_AURA) || defined (OS_ANDROID)
+
} // namespace
//
@@ -736,21 +759,20 @@ class SitePerProcessFeaturePolicyBrowserTest
"FeaturePolicy,FeaturePolicyExperimentalFeatures");
}
- ParsedFeaturePolicyHeader CreateFPHeader(
- blink::WebFeaturePolicyFeature feature,
- const std::vector<GURL>& origins) {
- ParsedFeaturePolicyHeader result(1);
+ blink::ParsedFeaturePolicy CreateFPHeader(blink::FeaturePolicyFeature feature,
+ const std::vector<GURL>& origins) {
+ blink::ParsedFeaturePolicy result(1);
result[0].feature = feature;
result[0].matches_all_origins = false;
DCHECK(!origins.empty());
for (const GURL& origin : origins)
- result[0].origins.push_back(url::Origin(origin));
+ result[0].origins.push_back(url::Origin::Create(origin));
return result;
}
- ParsedFeaturePolicyHeader CreateFPHeaderMatchesAll(
- blink::WebFeaturePolicyFeature feature) {
- ParsedFeaturePolicyHeader result(1);
+ blink::ParsedFeaturePolicy CreateFPHeaderMatchesAll(
+ blink::FeaturePolicyFeature feature) {
+ blink::ParsedFeaturePolicy result(1);
result[0].feature = feature;
result[0].matches_all_origins = true;
return result;
@@ -967,43 +989,6 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, TitleAfterCrossSiteIframe) {
EXPECT_EQ(expected_title, entry->GetTitle());
}
-// Class to detect incoming GestureScrollEnd acks for bubbling tests.
-class InputEventAckWaiter
- : public content::RenderWidgetHost::InputEventObserver {
- public:
- explicit InputEventAckWaiter(blink::WebInputEvent::Type ack_type_waiting_for)
- : message_loop_runner_(new content::MessageLoopRunner),
- ack_type_waiting_for_(ack_type_waiting_for),
- desired_ack_type_received_(false) {}
- ~InputEventAckWaiter() override {}
-
- void OnInputEventAck(const blink::WebInputEvent& event) override {
- if (event.GetType() == ack_type_waiting_for_) {
- desired_ack_type_received_ = true;
- if (message_loop_runner_->loop_running())
- message_loop_runner_->Quit();
- }
- }
-
- void Wait() {
- if (!desired_ack_type_received_) {
- message_loop_runner_->Run();
- }
- }
-
- void Reset() {
- desired_ack_type_received_ = false;
- message_loop_runner_ = new content::MessageLoopRunner;
- }
-
- private:
- scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
- blink::WebInputEvent::Type ack_type_waiting_for_;
- bool desired_ack_type_received_;
-
- DISALLOW_COPY_AND_ASSIGN(InputEventAckWaiter);
-};
-
// Test that the view bounds for an out-of-process iframe are set and updated
// correctly, including accounting for local frame offsets in the parent and
// scroll positions.
@@ -1048,8 +1033,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ViewBoundsInNestedFrameTest) {
// relative offset of its direct parent within the root frame.
gfx::Rect bounds = rwhv_nested->GetViewBounds();
- scoped_refptr<FrameRectChangedMessageFilter> filter =
- new FrameRectChangedMessageFilter();
+ scoped_refptr<UpdateResizeParamsMessageFilter> filter =
+ new UpdateResizeParamsMessageFilter();
root->current_frame_host()->GetProcess()->AddFilter(filter.get());
// Scroll the parent frame downward to verify that the child rect gets updated
@@ -1068,7 +1053,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ViewBoundsInNestedFrameTest) {
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
rwhv_root->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- filter->Wait();
+ filter->WaitForRect();
// The precise amount of scroll for the first view position update is not
// deterministic, so this simply verifies that the OOPIF moved from its
@@ -1090,6 +1075,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
->GetFrameTree()
->root();
ASSERT_EQ(1U, root->child_count());
+ RenderWidgetHost* root_rwh =
+ root->current_frame_host()->GetRenderWidgetHost();
FrameTreeNode* child_iframe_node = root->child_at(0);
@@ -1099,21 +1086,15 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
RenderWidgetHostViewBase* child_rwhv =
static_cast<RenderWidgetHostViewBase*>(child_rwh->GetView());
- std::unique_ptr<InputEventAckWaiter> gesture_fling_start_ack_observer =
- base::MakeUnique<InputEventAckWaiter>(
- blink::WebInputEvent::kGestureFlingStart);
- if (child_rwhv->wheel_scroll_latching_enabled()) {
- // If wheel scroll latching is enabled, the fling start won't bubble since
- // its corresponding GSB hasn't bubbled.
- child_rwh->AddInputEventObserver(gesture_fling_start_ack_observer.get());
- } else {
- root->current_frame_host()->GetRenderWidgetHost()->AddInputEventObserver(
- gesture_fling_start_ack_observer.get());
- }
+ // If wheel scroll latching is enabled, the fling start won't bubble since
+ // its corresponding GSB hasn't bubbled.
+ InputEventAckWaiter gesture_fling_start_ack_observer(
+ (child_rwhv->wheel_scroll_latching_enabled() ? child_rwh : root_rwh),
+ blink::WebInputEvent::kGestureFlingStart);
WaitForChildFrameSurfaceReady(child_iframe_node->current_frame_host());
- gesture_fling_start_ack_observer->Reset();
+ gesture_fling_start_ack_observer.Reset();
// Send a GSB, GSU, GFS sequence and verify that the GFS bubbles.
blink::WebGestureEvent gesture_scroll_begin(
blink::WebGestureEvent::kGestureScrollBegin,
@@ -1152,8 +1133,161 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// We now wait for the fling start event to be acked by the parent
// frame. If the test fails, then the test times out.
- gesture_fling_start_ack_observer->Wait();
+ gesture_fling_start_ack_observer.Wait();
+}
+
+// Restrict to Aura to we can use routable MouseWheel event via
+// RenderWidgetHostViewAura::OnScrollEvent().
+#if defined(USE_AURA)
+class SitePerProcessInternalsBrowserTest : public SitePerProcessBrowserTest {
+ public:
+ SitePerProcessInternalsBrowserTest() {}
+
+ protected:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ SitePerProcessBrowserTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitch(switches::kExposeInternalsForTesting);
+ // Needed to guarantee the scrollable div we're testing with is not given
+ // its own compositing layer.
+ command_line->AppendSwitch(switches::kDisablePreferCompositingToLCDText);
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(SitePerProcessInternalsBrowserTest,
+ ScrollNestedLocalNonFastScrollableDiv) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ // It is safe to obtain the root frame tree node here, as it doesn't change.
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ ASSERT_EQ(1U, root->child_count());
+
+ FrameTreeNode* parent_iframe_node = root->child_at(0);
+
+ GURL site_url(embedded_test_server()->GetURL(
+ "b.com", "/tall_page_with_local_iframe.html"));
+ NavigateFrameToURL(parent_iframe_node, site_url);
+
+ FrameTreeNode* nested_iframe_node = parent_iframe_node->child_at(0);
+ WaitForChildFrameSurfaceReady(nested_iframe_node->current_frame_host());
+
+ 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 = http://b.com/",
+ DepictFrameTree(root));
+
+ const char* get_element_location_script_fmt =
+ "var rect = "
+ "document.getElementById('%s').getBoundingClientRect();\n"
+ "var point = {\n"
+ " x: rect.left,\n"
+ " y: rect.top\n"
+ "};\n"
+ "window.domAutomationController.send(JSON.stringify(point));";
+
+ // Since the nested local b-frame shares the RenderWidgetHostViewChildFrame
+ // with the parent frame, we need to query element offsets in both documents
+ // before converting to root space coordinates for the wheel event.
+ std::string str;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ nested_iframe_node->current_frame_host(),
+ base::StringPrintf(get_element_location_script_fmt, "scrollable_div"),
+ &str));
+ gfx::PointF nested_point_f;
+ ConvertJSONToPoint(str, &nested_point_f);
+
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ parent_iframe_node->current_frame_host(),
+ base::StringPrintf(get_element_location_script_fmt, "nested_frame"),
+ &str));
+ gfx::PointF parent_offset_f;
+ ConvertJSONToPoint(str, &parent_offset_f);
+
+ // Compute location for wheel event.
+ gfx::PointF point_f(parent_offset_f.x() + nested_point_f.x() + 5.f,
+ parent_offset_f.y() + nested_point_f.y() + 5.f);
+
+ RenderWidgetHostViewChildFrame* rwhv_nested =
+ static_cast<RenderWidgetHostViewChildFrame*>(
+ nested_iframe_node->current_frame_host()
+ ->GetRenderWidgetHost()
+ ->GetView());
+ point_f = rwhv_nested->TransformPointToRootCoordSpaceF(point_f);
+
+ RenderWidgetHostViewAura* rwhv_root = static_cast<RenderWidgetHostViewAura*>(
+ root->current_frame_host()->GetRenderWidgetHost()->GetView());
+
+ gfx::PointF nested_in_parent;
+ rwhv_root->TransformPointToCoordSpaceForView(
+ point_f,
+ parent_iframe_node->current_frame_host()
+ ->GetRenderWidgetHost()
+ ->GetView(),
+ &nested_in_parent);
+
+ // Get original scroll position.
+ int div_scroll_top_start;
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ nested_iframe_node->current_frame_host(),
+ "window.domAutomationController.send("
+ "document.getElementById('scrollable_div').scrollTop);",
+ &div_scroll_top_start));
+ EXPECT_EQ(0, div_scroll_top_start);
+
+ // Wait until renderer's compositor thread is synced. Otherwise the event
+ // handler won't be installed when the event arrives.
+ MainThreadFrameObserver observer(rwhv_root->GetRenderWidgetHost());
+ observer.Wait();
+ {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ // tiny_timeout() is too small to run without flakes, but
+ // action_timeout() is 100 times bigger, which is overkill. We use a
+ // custom delay here to achieve a balance.
+ base::TimeDelta::FromMilliseconds(1000));
+ run_loop.Run();
+ }
+
+ // Send a wheel to scroll the div.
+ gfx::Point location(point_f.x(), point_f.y());
+ ui::ScrollEvent scroll_event(ui::ET_SCROLL, location, ui::EventTimeForNow(),
+ 0, 0, -ui::MouseWheelEvent::kWheelDelta, 0,
+ ui::MouseWheelEvent::kWheelDelta,
+ 2); // This must be '2' or it gets silently
+ // dropped.
+ rwhv_root->OnScrollEvent(&scroll_event);
+
+ InputEventAckWaiter ack_observer(
+ parent_iframe_node->current_frame_host()->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureScrollUpdate);
+ ack_observer.Wait();
+
+ // Check compositor layers.
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ nested_iframe_node->current_frame_host(),
+ "window.domAutomationController.send("
+ "window.internals.layerTreeAsText(document));",
+ &str));
+ // We expect the nested OOPIF to not have any compositor layers.
+ EXPECT_EQ(std::string(), str);
+
+ // Verify the div scrolled.
+ int div_scroll_top = div_scroll_top_start;
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ nested_iframe_node->current_frame_host(),
+ "window.domAutomationController.send("
+ "document.getElementById('scrollable_div').scrollTop);",
+ &div_scroll_top));
+ EXPECT_NE(div_scroll_top_start, div_scroll_top);
}
+#endif // defined(USE_AURA)
// Test that scrolling a nested out-of-process iframe bubbles unused scroll
// delta to a parent frame.
@@ -1173,20 +1307,17 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
FrameTreeNode* parent_iframe_node = root->child_at(0);
// This test uses the position of the nested iframe within the parent iframe
- // to infer the scroll position of the parent. FrameRectChangedMessageFilter
+ // to infer the scroll position of the parent. UpdateResizeParamsMessageFilter
// catches updates to the position in order to avoid busy waiting.
// It gets created early to catch the initial rects from the navigation.
- scoped_refptr<FrameRectChangedMessageFilter> filter =
- new FrameRectChangedMessageFilter();
+ scoped_refptr<UpdateResizeParamsMessageFilter> filter =
+ new UpdateResizeParamsMessageFilter();
parent_iframe_node->current_frame_host()->GetProcess()->AddFilter(
filter.get());
- std::unique_ptr<InputEventAckWaiter> ack_observer =
- base::MakeUnique<InputEventAckWaiter>(
- blink::WebInputEvent::kGestureScrollEnd);
- parent_iframe_node->current_frame_host()
- ->GetRenderWidgetHost()
- ->AddInputEventObserver(ack_observer.get());
+ InputEventAckWaiter ack_observer(
+ parent_iframe_node->current_frame_host()->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureScrollEnd);
GURL site_url(embedded_test_server()->GetURL(
"b.com", "/frame_tree/page_with_positioned_frame.html"));
@@ -1222,10 +1353,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
WaitForChildFrameSurfaceReady(nested_iframe_node->current_frame_host());
// Save the original offset as a point of reference.
- filter->Wait();
+ filter->WaitForRect();
gfx::Rect update_rect = filter->last_rect();
int initial_y = update_rect.y();
- filter->Reset();
+ filter->ResetRectRunLoop();
// Scroll the parent frame downward.
blink::WebMouseWheelEvent scroll_event(
@@ -1254,11 +1385,11 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
}
// Ensure that the view position is propagated to the child properly.
- filter->Wait();
+ filter->WaitForRect();
update_rect = filter->last_rect();
EXPECT_LT(update_rect.y(), initial_y);
- filter->Reset();
- ack_observer->Reset();
+ filter->ResetRectRunLoop();
+ ack_observer.Reset();
// Now scroll the nested frame upward, which should bubble to the parent.
// The upscroll exceeds the amount that the frame was initially scrolled
@@ -1268,7 +1399,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- filter->Wait();
+ filter->WaitForRect();
// This loop isn't great, but it accounts for the possibility of multiple
// incremental updates happening as a result of the scroll animation.
// A failure condition of this test is that the loop might not terminate
@@ -1296,7 +1427,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
}
- filter->Reset();
+ filter->ResetRectRunLoop();
// Once we've sent a wheel to the nested iframe that we expect to turn into
// a bubbling scroll, we need to delay to make sure the GestureScrollBegin
// from this new scroll doesn't hit the RenderWidgetHostImpl before the
@@ -1304,7 +1435,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
// This timing only seems to be needed for CrOS, but we'll enable it on
// all platforms just to lessen the possibility of tests being flakey
// on non-CrOS platforms.
- ack_observer->Wait();
+ ack_observer.Wait();
// Scroll the parent down again in order to test scroll bubbling from
// gestures.
@@ -1326,8 +1457,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
}
// Ensure ensuing offset change is received, and then reset the filter.
- filter->Wait();
- filter->Reset();
+ filter->WaitForRect();
+ filter->ResetRectRunLoop();
// Scroll down the nested iframe via gesture. This requires 3 separate input
// events.
@@ -1342,17 +1473,29 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
gesture_event.data.scroll_begin.delta_y_hint = 6.0f;
rwhv_nested->GetRenderWidgetHost()->ForwardGestureEvent(gesture_event);
- gesture_event.SetType(blink::WebGestureEvent::kGestureScrollUpdate);
+ gesture_event =
+ blink::WebGestureEvent(blink::WebGestureEvent::kGestureScrollUpdate,
+ blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::kTimeStampForTesting);
+ gesture_event.source_device = blink::kWebGestureDeviceTouchpad;
+ gesture_event.x = 1;
+ gesture_event.y = 1;
gesture_event.data.scroll_update.delta_x = 0.0f;
gesture_event.data.scroll_update.delta_y = 6.0f;
gesture_event.data.scroll_update.velocity_x = 0;
gesture_event.data.scroll_update.velocity_y = 0;
rwhv_nested->GetRenderWidgetHost()->ForwardGestureEvent(gesture_event);
- gesture_event.SetType(blink::WebGestureEvent::kGestureScrollEnd);
+ gesture_event =
+ blink::WebGestureEvent(blink::WebGestureEvent::kGestureScrollEnd,
+ blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::kTimeStampForTesting);
+ gesture_event.source_device = blink::kWebGestureDeviceTouchpad;
+ gesture_event.x = 1;
+ gesture_event.y = 1;
rwhv_nested->GetRenderWidgetHost()->ForwardGestureEvent(gesture_event);
- filter->Wait();
+ filter->WaitForRect();
update_rect = filter->last_rect();
// As above, if this loop does not terminate then it indicates an issue
// with scroll bubbling.
@@ -1366,7 +1509,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
// Test that when the child frame absorbs all of the scroll delta, it does
// not propagate to the parent (see https://crbug.com/621624).
- filter->Reset();
+ filter->ResetRectRunLoop();
scroll_event.delta_y = -5.0f;
scroll_event.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
@@ -1416,17 +1559,12 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
WaitForChildFrameSurfaceReady(iframe_node->current_frame_host());
- std::unique_ptr<InputEventAckWaiter> scroll_begin_observer =
- base::MakeUnique<InputEventAckWaiter>(
- blink::WebInputEvent::kGestureScrollBegin);
- root->current_frame_host()->GetRenderWidgetHost()->AddInputEventObserver(
- scroll_begin_observer.get());
-
- std::unique_ptr<InputEventAckWaiter> scroll_end_observer =
- base::MakeUnique<InputEventAckWaiter>(
- blink::WebInputEvent::kGestureScrollEnd);
- root->current_frame_host()->GetRenderWidgetHost()->AddInputEventObserver(
- scroll_end_observer.get());
+ InputEventAckWaiter scroll_begin_observer(
+ root->current_frame_host()->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureScrollBegin);
+ InputEventAckWaiter scroll_end_observer(
+ root->current_frame_host()->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureScrollEnd);
// Scroll the iframe upward, scroll events get bubbled up to the root.
blink::WebMouseWheelEvent scroll_event(
@@ -1444,7 +1582,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
scroll_event.has_precise_scrolling_deltas = true;
router->RouteMouseWheelEvent(root_view, &scroll_event, ui::LatencyInfo());
- scroll_begin_observer->Wait();
+ scroll_begin_observer.Wait();
// Now destroy the child_rwhv, scroll bubbling stops and a GSE gets sent to
// the root_view.
@@ -1460,7 +1598,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
blink::WebInputEvent::DispatchType::kEventNonBlocking;
router->RouteMouseWheelEvent(root_view, &scroll_event, ui::LatencyInfo());
- scroll_end_observer->Wait();
+ scroll_end_observer.Wait();
}
class ScrollObserver : public RenderWidgetHost::InputEventObserver {
@@ -1538,21 +1676,19 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
WaitForChildFrameSurfaceReady(nested_iframe_node->current_frame_host());
- std::unique_ptr<InputEventAckWaiter> ack_observer =
- base::MakeUnique<InputEventAckWaiter>(
- blink::WebInputEvent::kGestureScrollBegin);
- root->current_frame_host()->GetRenderWidgetHost()->AddInputEventObserver(
- ack_observer.get());
+ InputEventAckWaiter ack_observer(
+ root->current_frame_host()->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureScrollBegin);
std::unique_ptr<ScrollObserver> scroll_observer;
if (root_view->wheel_scroll_latching_enabled()) {
// All GSU events will be wrapped between a single GSB-GSE pair. The
// expected delta value is equal to summation of all scroll update deltas.
- scroll_observer = base::MakeUnique<ScrollObserver>(0, 15);
+ scroll_observer = std::make_unique<ScrollObserver>(0, 15);
} else {
// Each GSU will be wrapped betweeen its own GSB-GSE pair. The expected
// delta value is the delta of the first GSU event.
- scroll_observer = base::MakeUnique<ScrollObserver>(0, 5);
+ scroll_observer = std::make_unique<ScrollObserver>(0, 5);
}
root->current_frame_host()->GetRenderWidgetHost()->AddInputEventObserver(
scroll_observer.get());
@@ -1574,7 +1710,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
scroll_event.has_precise_scrolling_deltas = true;
rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- ack_observer->Wait();
+ ack_observer.Wait();
// When wheel scroll latching is disabled, each wheel event will have its own
// complete scroll seqeunce.
@@ -1603,6 +1739,128 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
}
}
+// This test verifies that scrolling an element to view works across OOPIFs.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollElementIntoView) {
+ GURL url_domain_a(
+ embedded_test_server()->GetURL("a.com", "/iframe_out_of_view.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), url_domain_a));
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+
+ GURL url_domain_b(
+ embedded_test_server()->GetURL("b.com", "/iframe_out_of_view.html"));
+ NavigateFrameToURL(root->child_at(0), url_domain_b);
+
+ GURL url_domain_c(embedded_test_server()->GetURL("c.com", "/title1.html"));
+ NavigateFrameToURL(root->child_at(0)->child_at(0), url_domain_c);
+
+ RenderFrameHostImpl* main_frame = root->current_frame_host();
+ RenderFrameHostImpl* child_frame_b = root->child_at(0)->current_frame_host();
+ RenderFrameHostImpl* child_frame_c =
+ root->child_at(0)->child_at(0)->current_frame_host();
+ RenderWidgetHostView *main_frame_rwhv = main_frame->GetView(),
+ *child_frame_b_rwhv = child_frame_b->GetView(),
+ *child_frame_c_rwhv = child_frame_c->GetView();
+
+ // Wait until <iframe> 'b' is not visible (in main frame).
+ while (main_frame_rwhv->GetViewBounds().Intersects(
+ child_frame_b_rwhv->GetViewBounds())) {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
+ run_loop.Run();
+ }
+
+ // Sanity check: <iframe> 'c' should not be visible either.
+ EXPECT_FALSE(main_frame_rwhv->GetViewBounds().Intersects(
+ child_frame_c_rwhv->GetViewBounds()));
+
+ // Scroll the inner most frame's body into view.
+ EXPECT_TRUE(ExecuteScript(child_frame_c, "document.body.scrollIntoView();"));
+
+ // Wait until <iframe> 'c' is in view bounds of parent frame and therefore
+ // visible.
+ while (!main_frame_rwhv->GetViewBounds().Intersects(
+ child_frame_c_rwhv->GetViewBounds())) {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
+ run_loop.Run();
+ }
+
+ // Sanity check: <iframe> 'b' should also be visible inside parent frame.
+ EXPECT_TRUE(main_frame_rwhv->GetViewBounds().Intersects(
+ child_frame_b_rwhv->GetViewBounds()));
+
+ // Sanity check: <iframe> 'c' should be visible inside <iframe> 'b'.
+ EXPECT_TRUE(child_frame_b_rwhv->GetViewBounds().Intersects(
+ child_frame_c_rwhv->GetViewBounds()));
+}
+
+// This test verifies that Scrolling a focused editable element into view works
+// when the element is inside an OOPIF.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ ScrollFocusedEditableElementIntoView) {
+ GURL main_frame_url(
+ embedded_test_server()->GetURL("a.com", "/iframe_out_of_view.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_frame_url));
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+
+ GURL child_frame_url(
+ embedded_test_server()->GetURL("b.com", "/page_with_input_field.html"));
+ NavigateFrameToURL(root->child_at(0), child_frame_url);
+
+ RenderFrameHostImpl* main_frame = root->current_frame_host();
+ RenderFrameHostImpl* child_frame = root->child_at(0)->current_frame_host();
+
+ // Focus the input field.
+ std::string result;
+ ASSERT_TRUE(
+ ExecuteScriptAndExtractString(child_frame, "focusInputField()", &result));
+ ASSERT_EQ(result, "input-focus");
+
+ // Wait and verify that before scrolling the child <iframe> is not visible.
+ while (main_frame->GetView()->GetViewBounds().Intersects(
+ child_frame->GetView()->GetViewBounds())) {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
+ run_loop.Run();
+ }
+
+ child_frame->GetFrameInputHandler()->ScrollFocusedEditableNodeIntoRect(
+ gfx::Rect());
+
+ // Wait until the child frame is visible.
+ while (!root->current_frame_host()->GetView()->GetViewBounds().Intersects(
+ child_frame->GetView()->GetViewBounds())) {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
+ run_loop.Run();
+ }
+
+ // Verify that the bounding box of the <input> is visible inside the main
+ // frame.
+ ASSERT_TRUE(ExecuteScriptAndExtractString(
+ child_frame,
+ " var rect = document.querySelector('input').getBoundingClientRect();"
+ "domAutomationController.send(rect.x + ',' + rect.y + ','"
+ "+ rect.width + ',' + rect.height);",
+ &result));
+ std::vector<std::string> tokens = base::SplitString(
+ result, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ ASSERT_EQ(4U, tokens.size());
+ double x, y, width, height;
+ ASSERT_TRUE(base::StringToDouble(tokens[0], &x));
+ ASSERT_TRUE(base::StringToDouble(tokens[1], &y));
+ ASSERT_TRUE(base::StringToDouble(tokens[2], &width));
+ ASSERT_TRUE(base::StringToDouble(tokens[3], &height));
+ gfx::Rect test_rect(static_cast<int>(x), static_cast<int>(y),
+ static_cast<int>(width), static_cast<int>(height));
+ test_rect += child_frame->GetView()->GetViewBounds().OffsetFromOrigin();
+ EXPECT_TRUE(main_frame->GetView()->GetViewBounds().Intersects(test_rect));
+}
+
#if defined(USE_AURA) || defined(OS_ANDROID)
// When unconsumed scrolls in a child bubble to the root and start an
@@ -1659,12 +1917,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
const gfx::Rect root_bounds = rwhv_root->GetViewBounds();
const gfx::Rect child_bounds = rwhv_child->GetViewBounds();
const float page_scale_factor = GetPageScaleFactor(shell());
- const gfx::Point point_in_child(
- gfx::ToCeiledInt((child_bounds.x() - root_bounds.x() + 10) *
- page_scale_factor),
- gfx::ToCeiledInt((child_bounds.y() - root_bounds.y() + 10) *
- page_scale_factor));
- gfx::Point dont_care;
+ const gfx::PointF point_in_child(
+ (child_bounds.x() - root_bounds.x() + 10) * page_scale_factor,
+ (child_bounds.y() - root_bounds.y() + 10) * page_scale_factor);
+ gfx::PointF dont_care;
ASSERT_EQ(rwhv_child->GetRenderWidgetHost(),
router->GetRenderWidgetHostAtPoint(rwhv_root, point_in_child,
&dont_care));
@@ -1695,7 +1951,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
static_cast<RenderWidgetHostViewAura*>(rwhv_root);
std::unique_ptr<MockOverscrollControllerDelegateAura>
mock_overscroll_delegate =
- base::MakeUnique<MockOverscrollControllerDelegateAura>(rwhva);
+ std::make_unique<MockOverscrollControllerDelegateAura>(rwhva);
rwhva->overscroll_controller()->set_delegate(mock_overscroll_delegate.get());
MockOverscrollObserver* mock_overscroll_observer =
mock_overscroll_delegate.get();
@@ -1703,29 +1959,23 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
RenderWidgetHostViewAndroid* rwhv_android =
static_cast<RenderWidgetHostViewAndroid*>(rwhv_root);
std::unique_ptr<MockOverscrollRefreshHandlerAndroid> mock_overscroll_handler =
- base::MakeUnique<MockOverscrollRefreshHandlerAndroid>();
+ std::make_unique<MockOverscrollRefreshHandlerAndroid>();
rwhv_android->SetOverscrollControllerForTesting(
mock_overscroll_handler.get());
MockOverscrollObserver* mock_overscroll_observer =
mock_overscroll_handler.get();
#endif // defined(USE_AURA)
- std::unique_ptr<InputEventAckWaiter> gesture_begin_observer_child =
- base::MakeUnique<InputEventAckWaiter>(
- blink::WebInputEvent::kGestureScrollBegin);
- child_node->current_frame_host()
- ->GetRenderWidgetHost()
- ->AddInputEventObserver(gesture_begin_observer_child.get());
- std::unique_ptr<InputEventAckWaiter> gesture_end_observer_child =
- base::MakeUnique<InputEventAckWaiter>(
- blink::WebInputEvent::kGestureScrollEnd);
- child_node->current_frame_host()
- ->GetRenderWidgetHost()
- ->AddInputEventObserver(gesture_end_observer_child.get());
+ InputEventAckWaiter gesture_begin_observer_child(
+ child_node->current_frame_host()->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureScrollBegin);
+ InputEventAckWaiter gesture_end_observer_child(
+ child_node->current_frame_host()->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureScrollEnd);
#if defined(USE_AURA)
const float overscroll_threshold =
- GetOverscrollConfig(OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN);
+ GetOverscrollConfig(OverscrollConfig::THRESHOLD_START_TOUCHSCREEN);
#elif defined(OS_ANDROID)
const float overscroll_threshold = 0.f;
#endif
@@ -1755,7 +2005,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
ui::LatencyInfo(ui::SourceEventType::TOUCH));
// Make sure the child is indeed receiving the gesture stream.
- gesture_begin_observer_child->Wait();
+ gesture_begin_observer_child.Wait();
blink::WebGestureEvent gesture_scroll_update(
blink::WebGestureEvent::kGestureScrollUpdate,
@@ -1813,7 +2063,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Ensure that the method of providing the child's scroll events to the root
// does not leave the child in an invalid state.
- gesture_end_observer_child->Wait();
+ gesture_end_observer_child.Wait();
}
#endif // defined(USE_AURA) || defined(OS_ANDROID)
@@ -2854,7 +3104,7 @@ namespace {
class FailingURLLoaderImpl : public mojom::URLLoader {
public:
explicit FailingURLLoaderImpl(mojom::URLLoaderClientPtr client) {
- ResourceRequestCompletionStatus status;
+ network::URLLoaderCompletionStatus status;
status.error_code = net::ERR_NOT_IMPLEMENTED;
client->OnComplete(status);
}
@@ -2907,16 +3157,14 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ProcessTransferAfterError) {
GURL url_b = embedded_test_server()->GetURL("b.com", "/title3.html");
bool network_service =
base::FeatureList::IsEnabled(features::kNetworkService);
- mojom::URLLoaderFactoryPtr failing_factory;
- mojo::MakeStrongBinding(base::MakeUnique<FailingLoadFactory>(),
- mojo::MakeRequest(&failing_factory));
+ FailingLoadFactory failing_factory;
StoragePartitionImpl* storage_partition = nullptr;
if (network_service) {
storage_partition = static_cast<StoragePartitionImpl*>(
BrowserContext::GetDefaultStoragePartition(
shell()->web_contents()->GetBrowserContext()));
storage_partition->url_loader_factory_getter()->SetNetworkFactoryForTesting(
- std::move(failing_factory));
+ &failing_factory);
} else {
host_resolver()->ClearRules();
}
@@ -3623,7 +3871,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// It is safe to obtain the root frame tree node here, as it doesn't change.
FrameTreeNode* root = web_contents()->GetFrameTree()->root();
- EXPECT_TRUE(root->child_at(1) != NULL);
+ EXPECT_TRUE(root->child_at(1) != nullptr);
EXPECT_EQ(2U, root->child_at(1)->child_count());
{
@@ -3654,7 +3902,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// navigating frame to still be present. The reason is that we don't run the
// message loop, so no IPCs that alter the frame tree can be processed.
FrameTreeNode* child = root->child_at(1);
- SiteInstance* site = NULL;
+ SiteInstance* site = nullptr;
bool browser_side_navigation = IsBrowserSideNavigationEnabled();
std::string cross_site_rfh_type =
browser_side_navigation ? "speculative" : "pending";
@@ -4184,13 +4432,13 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DynamicSandboxFlags) {
// Both frames should not be sandboxed to start with.
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(0)->pending_sandbox_flags());
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(0)->effective_sandbox_flags());
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(1)->pending_sandbox_flags());
+ root->child_at(1)->pending_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(1)->effective_sandbox_flags());
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
// Dynamically update sandbox flags for the first frame.
EXPECT_TRUE(ExecuteScript(
@@ -4198,17 +4446,18 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DynamicSandboxFlags) {
"document.querySelector('iframe').sandbox='allow-scripts';"));
// Check that updated sandbox flags are propagated to browser process.
- // The new flags should be reflected in pending_sandbox_flags(), while
- // effective_sandbox_flags() should still reflect the old flags, because
- // sandbox flag updates take place only after navigations. "allow-scripts"
- // resets both SandboxFlags::Scripts and SandboxFlags::AutomaticFeatures bits
- // per blink::parseSandboxPolicy().
+ // The new flags should be reflected in pending_frame_policy().sandbox_flags,
+ // while effective_frame_policy().sandbox_flags should still reflect the old
+ // flags, because sandbox flag updates take place only after navigations.
+ // "allow-scripts" resets both SandboxFlags::Scripts and
+ // SandboxFlags::AutomaticFeatures bits per blink::parseSandboxPolicy().
blink::WebSandboxFlags expected_flags =
blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
~blink::WebSandboxFlags::kAutomaticFeatures;
- EXPECT_EQ(expected_flags, root->child_at(0)->pending_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(0)->effective_sandbox_flags());
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
// Navigate the first frame to a page on the same site. The new sandbox
// flags should take effect.
@@ -4232,8 +4481,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DynamicSandboxFlags) {
// Confirm that the browser process has updated the frame's current sandbox
// flags.
- EXPECT_EQ(expected_flags, root->child_at(0)->pending_sandbox_flags());
- EXPECT_EQ(expected_flags, root->child_at(0)->effective_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
// Opening a popup in the now-sandboxed frame should fail.
bool success = false;
@@ -4276,8 +4527,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DynamicSandboxFlags) {
EXPECT_EQ(1u, Shell::windows().size());
// Child of a sandboxed frame should also be sandboxed on the browser side.
- EXPECT_EQ(expected_flags,
- root->child_at(0)->child_at(0)->effective_sandbox_flags());
+ EXPECT_EQ(
+ expected_flags,
+ root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
}
// Check that dynamic updates to iframe sandbox flags are propagated correctly.
@@ -4309,9 +4561,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
blink::WebSandboxFlags expected_flags =
blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
~blink::WebSandboxFlags::kAutomaticFeatures;
- EXPECT_EQ(expected_flags, root->child_at(1)->pending_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(1)->pending_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(1)->effective_sandbox_flags());
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
// Navigate the second subframe to a page on bar.com. This will trigger a
// remote-to-local frame swap in bar.com's process.
@@ -4322,8 +4575,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
ASSERT_EQ(1U, root->child_at(1)->child_count());
// Confirm that the browser process has updated the current sandbox flags.
- EXPECT_EQ(expected_flags, root->child_at(1)->pending_sandbox_flags());
- EXPECT_EQ(expected_flags, root->child_at(1)->effective_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(1)->pending_frame_policy().sandbox_flags);
+ EXPECT_EQ(expected_flags,
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
// Opening a popup in the sandboxed second frame should fail.
bool success = false;
@@ -4366,26 +4621,27 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// The frame should not be sandboxed to start with.
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(0)->pending_sandbox_flags());
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(0)->effective_sandbox_flags());
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
// Dynamically update the frame's sandbox flags.
EXPECT_TRUE(ExecuteScript(
shell(), "document.querySelector('iframe').sandbox='allow-scripts';"));
// Check that updated sandbox flags are propagated to browser process.
- // The new flags should be set in pending_sandbox_flags(), while
- // effective_sandbox_flags() should still reflect the old flags, because
- // sandbox flag updates take place only after navigations. "allow-scripts"
- // resets both SandboxFlags::Scripts and SandboxFlags::AutomaticFeatures bits
- // per blink::parseSandboxPolicy().
+ // The new flags should be set in pending_frame_policy().sandbox_flags, while
+ // effective_frame_policy().sandbox_flags should still reflect the old flags,
+ // because sandbox flag updates take place only after navigations.
+ // "allow-scripts" resets both SandboxFlags::Scripts and
+ // SandboxFlags::AutomaticFeatures bits per blink::parseSandboxPolicy().
blink::WebSandboxFlags expected_flags =
blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
~blink::WebSandboxFlags::kAutomaticFeatures;
- EXPECT_EQ(expected_flags, root->child_at(0)->pending_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(0)->effective_sandbox_flags());
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
// Perform a renderer-initiated same-site navigation in the first frame. The
// new sandbox flags should take effect.
@@ -4398,8 +4654,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Confirm that the browser process has updated the frame's current sandbox
// flags.
- EXPECT_EQ(expected_flags, root->child_at(0)->pending_sandbox_flags());
- EXPECT_EQ(expected_flags, root->child_at(0)->effective_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
// Opening a popup in the now-sandboxed frame should fail.
bool success = false;
@@ -4490,11 +4748,13 @@ IN_PROC_BROWSER_TEST_F(
blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
~blink::WebSandboxFlags::kAutomaticFeatures &
~blink::WebSandboxFlags::kOrigin;
- EXPECT_EQ(expected_flags, root->child_at(1)->effective_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
// The child of the sandboxed frame should've inherited sandbox flags, so it
// should not be able to create popups.
- EXPECT_EQ(expected_flags, bottom_child->effective_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ bottom_child->effective_frame_policy().sandbox_flags);
bool success = false;
EXPECT_TRUE(ExecuteScriptAndExtractBool(
bottom_child,
@@ -5915,6 +6175,52 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SubframeWindowFocus) {
EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
}
+// Check that when a subframe has focus, and another subframe navigates
+// cross-site to a new renderer process, this doesn't reset the focused frame
+// to the main frame. See https://crbug.com/802156.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ SubframeFocusNotLostWhenAnotherFrameNavigatesCrossSite) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(a,a)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+ FrameTreeNode* child1 = root->child_at(0);
+ FrameTreeNode* child2 = root->child_at(1);
+
+ // The main frame should be focused to start with.
+ EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+
+ // Add an <input> element to the first subframe.
+ ExecuteScriptAsync(
+ child1, "document.body.appendChild(document.createElement('input'))");
+
+ // Focus the first subframe using window.focus().
+ FrameFocusedObserver focus_observer(child1->current_frame_host());
+ ExecuteScriptAsync(root, "frames[0].focus()");
+ focus_observer.Wait();
+ EXPECT_EQ(child1, root->frame_tree()->GetFocusedFrame());
+
+ // Give focus to the <input> element in the first subframe.
+ ExecuteScriptAsync(child1, "document.querySelector('input').focus()");
+
+ // Now, navigate second subframe cross-site. Ensure that this won't change
+ // the focused frame.
+ GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
+ NavigateFrameToURL(child2, b_url);
+ // This is needed because the incorrect focused frame change as in
+ // https://crbug.com/802156 requires an additional post-commit IPC roundtrip.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(child1, root->frame_tree()->GetFocusedFrame());
+
+ // The <input> in first subframe should still be the activeElement.
+ std::string activeTag;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ child1, "domAutomationController.send(document.activeElement.tagName)",
+ &activeTag));
+ EXPECT_EQ("input", base::ToLowerASCII(activeTag));
+}
+
// There are no cursors on Android.
#if !defined(OS_ANDROID)
class CursorMessageFilter : public content::BrowserMessageFilter {
@@ -6138,7 +6444,9 @@ class SitePerProcessMouseWheelBrowserTest : public SitePerProcessBrowserTest {
// cancellable.
EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
EXPECT_EQ("\"wheel: 2\"", reply);
- if (base::FeatureList::IsEnabled(features::kAsyncWheelEvents)) {
+ if (base::FeatureList::IsEnabled(features::kAsyncWheelEvents) &&
+ base::FeatureList::IsEnabled(
+ features::kTouchpadAndWheelScrollLatching)) {
EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
EXPECT_EQ("\"scroll: 2\"", reply);
}
@@ -6366,7 +6674,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Wait until renderer's compositor thread is synced.
{
auto observer =
- base::MakeUnique<MainThreadFrameObserver>(render_widget_host);
+ std::make_unique<MainThreadFrameObserver>(render_widget_host);
observer->Wait();
}
@@ -6380,7 +6688,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
rwhv->OnTouchEvent(&touch_event);
{
auto observer =
- base::MakeUnique<MainThreadFrameObserver>(render_widget_host);
+ std::make_unique<MainThreadFrameObserver>(render_widget_host);
observer->Wait();
}
@@ -7491,6 +7799,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
{
mojom::CreateFrameParamsPtr params = mojom::CreateFrameParams::New();
params->routing_id = frame_routing_id;
+ mojo::MakeRequest(&params->interface_provider);
params->proxy_routing_id = proxy_routing_id;
params->opener_routing_id = IPC::mojom::kRoutingIdNone;
params->parent_routing_id =
@@ -7558,6 +7867,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ParentDetachRemoteChild) {
{
mojom::CreateFrameParamsPtr params = mojom::CreateFrameParams::New();
params->routing_id = frame_routing_id;
+ mojo::MakeRequest(&params->interface_provider);
params->proxy_routing_id = IPC::mojom::kRoutingIdNone;
params->opener_routing_id = IPC::mojom::kRoutingIdNone;
params->parent_routing_id = parent_routing_id;
@@ -7735,7 +8045,7 @@ class ChildFrameCompositorFrameSwapCounter {
private:
void RegisterCallback() {
- view_->RegisterFrameSwappedCallback(base::MakeUnique<base::Closure>(
+ view_->RegisterFrameSwappedCallback(std::make_unique<base::Closure>(
base::Bind(&ChildFrameCompositorFrameSwapCounter::OnFrameSwapped,
weak_factory_.GetWeakPtr())));
}
@@ -7955,9 +8265,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SandboxFlagsInheritance) {
blink::WebSandboxFlags expected_flags =
blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
~blink::WebSandboxFlags::kAutomaticFeatures;
- EXPECT_EQ(expected_flags, root->child_at(0)->pending_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(0)->effective_sandbox_flags());
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
// Navigate child frame so that the sandbox flags take effect. Use a page
// with three levels of frames and make sure all frames properly inherit
@@ -7973,9 +8284,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SandboxFlagsInheritance) {
FrameTreeNode* b_child = root->child_at(0);
FrameTreeNode* c_child = b_child->child_at(0);
FrameTreeNode* d_child = c_child->child_at(0);
- EXPECT_EQ(expected_flags, b_child->effective_sandbox_flags());
- EXPECT_EQ(expected_flags, c_child->effective_sandbox_flags());
- EXPECT_EQ(expected_flags, d_child->effective_sandbox_flags());
+ EXPECT_EQ(expected_flags, b_child->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(expected_flags, c_child->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(expected_flags, d_child->effective_frame_policy().sandbox_flags);
// Check whether each frame is sandboxed on the renderer side, by seeing if
// each frame's origin is unique ("null").
@@ -8007,8 +8318,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
~blink::WebSandboxFlags::kAutomaticFeatures;
FrameTreeNode* child = root->child_at(0);
- EXPECT_EQ(expected_flags, child->pending_sandbox_flags());
- EXPECT_EQ(blink::WebSandboxFlags::kNone, child->effective_sandbox_flags());
+ EXPECT_EQ(expected_flags, child->pending_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ child->effective_frame_policy().sandbox_flags);
// Add a new grandchild frame and navigate it cross-site.
RenderFrameHostCreatedObserver frame_observer(shell()->web_contents(), 1);
@@ -8024,9 +8336,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Since the update flags haven't yet taken effect in its parent, this
// grandchild frame should not be sandboxed.
- EXPECT_EQ(blink::WebSandboxFlags::kNone, grandchild->pending_sandbox_flags());
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- grandchild->effective_sandbox_flags());
+ grandchild->pending_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ grandchild->effective_frame_policy().sandbox_flags);
// Check that the grandchild frame isn't sandboxed on the renderer side. If
// sandboxed, its origin would be unique ("null").
@@ -8057,14 +8370,16 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
~blink::WebSandboxFlags::kAutomaticFeatures &
~blink::WebSandboxFlags::kPopups;
- EXPECT_EQ(expected_flags, root->child_at(0)->pending_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
// Navigate child frame cross-site. The sandbox flags should take effect.
GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
TestFrameNavigationObserver frame_observer(root->child_at(0));
NavigateFrameToURL(root->child_at(0), frame_url);
frame_observer.Wait();
- EXPECT_EQ(expected_flags, root->child_at(0)->effective_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
// Verify that they've also taken effect on the renderer side. The sandboxed
// frame's origin should be unique.
@@ -8082,7 +8397,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Check that the sandbox flags for new popup are correct in the browser
// process.
- EXPECT_EQ(expected_flags, foo_root->effective_sandbox_flags());
+ 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));
@@ -8100,7 +8415,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_sandbox_flags());
+ EXPECT_EQ(expected_flags, foo_root->effective_frame_policy().sandbox_flags);
EXPECT_EQ("null", GetDocumentOrigin(foo_root));
// Navigate the popup back to b.com. The popup should perform a
@@ -8116,7 +8431,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_sandbox_flags());
+ EXPECT_EQ(expected_flags, foo_root->effective_frame_policy().sandbox_flags);
EXPECT_EQ("null", GetDocumentOrigin(foo_root));
}
@@ -8147,14 +8462,16 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
~blink::WebSandboxFlags::kAutomaticFeatures &
~blink::WebSandboxFlags::kPopups &
~blink::WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts;
- EXPECT_EQ(expected_flags, root->child_at(0)->pending_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
// Navigate child frame cross-site. The sandbox flags should take effect.
GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
TestFrameNavigationObserver frame_observer(root->child_at(0));
NavigateFrameToURL(root->child_at(0), frame_url);
frame_observer.Wait();
- EXPECT_EQ(expected_flags, root->child_at(0)->effective_sandbox_flags());
+ EXPECT_EQ(expected_flags,
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
// Open a cross-site popup named "foo" from the child frame.
GURL b_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
@@ -8168,7 +8485,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Check that the sandbox flags for new popup are correct in the browser
// process. They should not have been inherited.
- EXPECT_EQ(blink::WebSandboxFlags::kNone, foo_root->effective_sandbox_flags());
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ foo_root->effective_frame_policy().sandbox_flags);
// The popup's origin should match |b_url|, since it's not sandboxed.
std::string popup_origin;
@@ -8464,7 +8782,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
EXPECT_EQ(c_url.GetOrigin().spec(),
root->child_at(0)->current_origin().Serialize() + "/");
EXPECT_EQ(blink::WebSandboxFlags::kNone,
- root->child_at(0)->effective_sandbox_flags());
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
}
}
@@ -8798,34 +9116,21 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
EXPECT_FALSE(rvh->is_swapped_out_);
}
-// Helper class to wait for a ChildProcessHostMsg_ShutdownRequest message to
-// arrive.
-class ShutdownRequestMessageFilter : public BrowserMessageFilter {
+// Helper class to wait for a ShutdownRequest message to arrive, in response to
+// which RenderProcessWillExit is called on observers by RenderProcessHost.
+class ShutdownObserver : public RenderProcessHostObserver {
public:
- ShutdownRequestMessageFilter()
- : BrowserMessageFilter(ChildProcessMsgStart),
- message_loop_runner_(new MessageLoopRunner) {}
+ ShutdownObserver() : message_loop_runner_(new MessageLoopRunner) {}
- bool OnMessageReceived(const IPC::Message& message) override {
- if (message.type() == ChildProcessHostMsg_ShutdownRequest::ID) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::BindOnce(&ShutdownRequestMessageFilter::OnShutdownRequest,
- this));
- }
- return false;
+ void RenderProcessShutdownRequested(RenderProcessHost* host) override {
+ message_loop_runner_->Quit();
}
- void OnShutdownRequest() { message_loop_runner_->Quit(); }
-
void Wait() { message_loop_runner_->Run(); }
private:
- ~ShutdownRequestMessageFilter() override {}
-
scoped_refptr<MessageLoopRunner> message_loop_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(ShutdownRequestMessageFilter);
+ DISALLOW_COPY_AND_ASSIGN(ShutdownObserver);
};
// Test for https://crbug.com/568836. From an A-embed-B page, navigate the
@@ -8864,15 +9169,15 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Navigate the subframe away from b.com. Since this is the last active
// frame in the b.com process, this causes the RenderWidget and RenderView to
// be closed. If this succeeds without crashing, the renderer will release
- // the process and send a ChildProcessHostMsg_ShutdownRequest to the browser
+ // the process and send a ShutdownRequest to the browser
// process to ask whether it's ok to terminate. Thus, wait for this message
// to ensure that the RenderView and widget were closed without crashing.
- scoped_refptr<ShutdownRequestMessageFilter> filter =
- new ShutdownRequestMessageFilter();
- subframe_process->AddFilter(filter.get());
+ ShutdownObserver shutdown_observer;
+ subframe_process->AddObserver(&shutdown_observer);
NavigateFrameToURL(root->child_at(0),
embedded_test_server()->GetURL("a.com", "/title1.html"));
- filter->Wait();
+ shutdown_observer.Wait();
+ subframe_process->RemoveObserver(&shutdown_observer);
// TODO(alexmos): Navigating the subframe back to b.com at this point would
// trigger the race in https://crbug.com/535246, where the browser process
@@ -10287,14 +10592,14 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
EXPECT_TRUE(NavigateToURL(shell(), start_url));
FrameTreeNode* root = web_contents()->GetFrameTree()->root();
- EXPECT_EQ(CreateFPHeader(blink::WebFeaturePolicyFeature::kVibrate,
+ EXPECT_EQ(CreateFPHeader(blink::FeaturePolicyFeature::kVibrate,
{start_url.GetOrigin()}),
root->current_replication_state().feature_policy_header);
// When the main frame navigates to a page with a new policy, it should
// overwrite the old one.
EXPECT_TRUE(NavigateToURL(shell(), first_nav_url));
- EXPECT_EQ(CreateFPHeaderMatchesAll(blink::WebFeaturePolicyFeature::kVibrate),
+ EXPECT_EQ(CreateFPHeaderMatchesAll(blink::FeaturePolicyFeature::kVibrate),
root->current_replication_state().feature_policy_header);
// When the main frame navigates to a page without a policy, the replicated
@@ -10314,14 +10619,14 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
EXPECT_TRUE(NavigateToURL(shell(), start_url));
FrameTreeNode* root = web_contents()->GetFrameTree()->root();
- EXPECT_EQ(CreateFPHeader(blink::WebFeaturePolicyFeature::kVibrate,
+ EXPECT_EQ(CreateFPHeader(blink::FeaturePolicyFeature::kVibrate,
{start_url.GetOrigin()}),
root->current_replication_state().feature_policy_header);
// When the main frame navigates to a page with a new policy, it should
// overwrite the old one.
EXPECT_TRUE(NavigateToURL(shell(), first_nav_url));
- EXPECT_EQ(CreateFPHeaderMatchesAll(blink::WebFeaturePolicyFeature::kVibrate),
+ EXPECT_EQ(CreateFPHeaderMatchesAll(blink::FeaturePolicyFeature::kVibrate),
root->current_replication_state().feature_policy_header);
// When the main frame navigates to a page without a policy, the replicated
@@ -10343,19 +10648,19 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root = web_contents()->GetFrameTree()->root();
- EXPECT_EQ(CreateFPHeader(blink::WebFeaturePolicyFeature::kVibrate,
+ EXPECT_EQ(CreateFPHeader(blink::FeaturePolicyFeature::kVibrate,
{main_url.GetOrigin(), GURL("http://example.com/")}),
root->current_replication_state().feature_policy_header);
EXPECT_EQ(1UL, root->child_count());
EXPECT_EQ(
- CreateFPHeader(blink::WebFeaturePolicyFeature::kVibrate,
+ CreateFPHeader(blink::FeaturePolicyFeature::kVibrate,
{main_url.GetOrigin()}),
root->child_at(0)->current_replication_state().feature_policy_header);
// Navigate the iframe cross-site.
NavigateFrameToURL(root->child_at(0), first_nav_url);
EXPECT_EQ(
- CreateFPHeaderMatchesAll(blink::WebFeaturePolicyFeature::kVibrate),
+ CreateFPHeaderMatchesAll(blink::FeaturePolicyFeature::kVibrate),
root->child_at(0)->current_replication_state().feature_policy_header);
// Navigate the iframe to another location, this one with no policy header
@@ -10367,7 +10672,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
// Navigate the iframe back to a page with a policy
NavigateFrameToURL(root->child_at(0), first_nav_url);
EXPECT_EQ(
- CreateFPHeaderMatchesAll(blink::WebFeaturePolicyFeature::kVibrate),
+ CreateFPHeaderMatchesAll(blink::FeaturePolicyFeature::kVibrate),
root->child_at(0)->current_replication_state().feature_policy_header);
}
@@ -10552,11 +10857,15 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
FrameTreeNode* root = web_contents()->GetFrameTree()->root();
- EXPECT_EQ(0UL, root->effective_container_policy().size());
- EXPECT_EQ(0UL, root->child_at(0)->effective_container_policy().size());
- EXPECT_EQ(0UL, root->child_at(1)->effective_container_policy().size());
- EXPECT_EQ(2UL, root->child_at(2)->effective_container_policy().size());
- EXPECT_EQ(2UL, root->child_at(3)->effective_container_policy().size());
+ EXPECT_EQ(0UL, root->effective_frame_policy().container_policy.size());
+ EXPECT_EQ(
+ 0UL, root->child_at(0)->effective_frame_policy().container_policy.size());
+ EXPECT_EQ(
+ 0UL, root->child_at(1)->effective_frame_policy().container_policy.size());
+ EXPECT_EQ(
+ 2UL, root->child_at(2)->effective_frame_policy().container_policy.size());
+ EXPECT_EQ(
+ 2UL, root->child_at(3)->effective_frame_policy().container_policy.size());
}
// Test dynamic updates to iframe "allow" attribute are propagated correctly.
@@ -10569,18 +10878,22 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
FrameTreeNode* root = web_contents()->GetFrameTree()->root();
- EXPECT_EQ(2UL, root->child_at(2)->effective_container_policy().size());
+ EXPECT_EQ(
+ 2UL, root->child_at(2)->effective_frame_policy().container_policy.size());
// Removing the "allow" attribute; pending policy should update, but effective
// policy remains unchanged.
EXPECT_TRUE(ExecuteScript(
root, "document.getElementById('child-2').setAttribute('allow','')"));
- EXPECT_EQ(2UL, root->child_at(2)->effective_container_policy().size());
- EXPECT_EQ(0UL, root->child_at(2)->pending_container_policy_.size());
+ EXPECT_EQ(
+ 2UL, root->child_at(2)->effective_frame_policy().container_policy.size());
+ EXPECT_EQ(0UL,
+ root->child_at(2)->pending_frame_policy().container_policy.size());
// Navigate the frame; pending policy should be committed.
NavigateFrameToURL(root->child_at(2), nav_url);
- EXPECT_EQ(0UL, root->child_at(2)->effective_container_policy().size());
+ EXPECT_EQ(
+ 0UL, root->child_at(2)->effective_frame_policy().container_policy.size());
}
// Check that out-of-process frames correctly calculate the container policy in
@@ -10648,8 +10961,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
// Validate that the effective container policy contains a single non-unique
// origin.
- const ParsedFeaturePolicyHeader initial_effective_policy =
- root->child_at(2)->effective_container_policy();
+ 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());
@@ -10657,10 +10970,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
// contain a unique origin, but effective policy should remain unchanged.
EXPECT_TRUE(ExecuteScript(
root, "document.getElementById('child-2').setAttribute('sandbox','')"));
- const ParsedFeaturePolicyHeader updated_effective_policy =
- root->child_at(2)->effective_container_policy();
- const ParsedFeaturePolicyHeader updated_pending_policy =
- root->child_at(2)->pending_container_policy_;
+ const blink::ParsedFeaturePolicy updated_effective_policy =
+ root->child_at(2)->effective_frame_policy().container_policy;
+ 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_EQ(1UL, updated_pending_policy[0].origins.size());
@@ -10668,8 +10981,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
// Navigate the frame; pending policy should now be committed.
NavigateFrameToURL(root->child_at(2), nav_url);
- const ParsedFeaturePolicyHeader final_effective_policy =
- root->child_at(2)->effective_container_policy();
+ const blink::ParsedFeaturePolicy final_effective_policy =
+ root->child_at(2)->effective_frame_policy().container_policy;
EXPECT_EQ(1UL, final_effective_policy[0].origins.size());
EXPECT_TRUE(final_effective_policy[0].origins[0].unique());
}
@@ -10681,7 +10994,7 @@ class RequestDelayingSitePerProcessBrowserTest
: public SitePerProcessBrowserTest {
public:
RequestDelayingSitePerProcessBrowserTest()
- : test_server_(base::MakeUnique<net::EmbeddedTestServer>()) {}
+ : test_server_(std::make_unique<net::EmbeddedTestServer>()) {}
// Must be called after any calls to SetDelayedRequestsForPath.
void SetUpEmbeddedTestServer() {
@@ -10729,7 +11042,7 @@ class RequestDelayingSitePerProcessBrowserTest
// send an empty response.
if (it->second > 0) {
--it->second;
- return base::MakeUnique<DelayedResponse>(this);
+ return std::make_unique<DelayedResponse>(this);
}
MaybeStartRequests();
return std::unique_ptr<net::test_server::BasicHttpResponse>();
@@ -11087,6 +11400,72 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, PostTargetSubFrame) {
EXPECT_EQ("my_token=my_value\n", body);
}
+// Tests that POST method and body is not lost when an OOPIF submits a form
+// that targets the main frame. See https://crbug.com/806215.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ PostTargetsMainFrameFromOOPIF) {
+ // Navigate to a page with an OOPIF.
+ GURL main_url(
+ embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+
+ // The main frame and the subframe live on different processes.
+ EXPECT_EQ(1u, root->child_count());
+ EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
+ root->child_at(0)->current_frame_host()->GetSiteInstance());
+
+ // Make a form submission from the subframe and target its parent frame.
+ GURL form_url(embedded_test_server()->GetURL("/echoall"));
+ TestNavigationObserver form_post_observer(web_contents());
+ EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), R"(
+ var form = document.createElement('form');
+
+ // POST form submission to /echoall.
+ form.setAttribute("method", "POST");
+ form.setAttribute("action", ")" + form_url.spec() + R"(");
+
+ // Target the parent.
+ form.setAttribute("target", "_parent");
+
+ // Add some POST data: "my_token=my_value";
+ var input = document.createElement("input");
+ input.setAttribute("type", "hidden");
+ input.setAttribute("name", "my_token");
+ input.setAttribute("value", "my_value");
+ form.appendChild(input);
+
+ // Submit the form.
+ document.body.appendChild(form);
+ form.submit();
+ )"));
+ form_post_observer.Wait();
+
+ // Verify that the FrameNavigationEntry's method is POST.
+ NavigationEntryImpl* entry = static_cast<NavigationEntryImpl*>(
+ web_contents()->GetController().GetLastCommittedEntry());
+ EXPECT_EQ("POST", entry->root_node()->frame_entry->method());
+
+ // Verify that POST body was correctly passed to the server and ended up in
+ // the body of the page.
+ std::string body;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(root, R"(
+ var body = document.getElementsByTagName('pre')[0].innerText;
+ window.domAutomationController.send(body);)", &body));
+ EXPECT_EQ("my_token=my_value\n", body);
+
+ // Reload the main frame and ensure the POST body is preserved. This checks
+ // that the POST body was saved in the FrameNavigationEntry.
+ web_contents()->GetController().Reload(ReloadType::NORMAL,
+ false /* check_for_repost */);
+ EXPECT_TRUE(WaitForLoadStop(web_contents()));
+ body = "";
+ EXPECT_TRUE(ExecuteScriptAndExtractString(root, R"(
+ var body = document.getElementsByTagName('pre')[0].innerText;
+ window.domAutomationController.send(body);)", &body));
+ EXPECT_EQ("my_token=my_value\n", body);
+}
+
// Verify that a remote-to-local main frame navigation doesn't overwrite
// the previous history entry. See https://crbug.com/725716.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
@@ -11870,27 +12249,6 @@ class TouchSelectionControllerClientTestWrapper
DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerClientTestWrapper);
};
-namespace {
-
-bool ConvertJSONToPoint(const std::string& str, gfx::PointF* point) {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(str);
- if (!value)
- return false;
- base::DictionaryValue* root;
- if (!value->GetAsDictionary(&root))
- return false;
- double x, y;
- if (!root->GetDouble("x", &x))
- return false;
- if (!root->GetDouble("y", &y))
- return false;
- point->set_x(x);
- point->set_y(y);
- return true;
-}
-
-} // namespace
-
IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAndroidSiteIsolationTest,
BasicSelectionIsolatedIframe) {
GURL test_url(embedded_test_server()->GetURL(
@@ -12026,4 +12384,414 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAndroidSiteIsolationTest,
#endif // defined(OS_ANDROID)
+// Verify that sandbox flags specified by a CSP header are properly inherited by
+// child frames, but are removed when the frame navigates.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ ActiveSandboxFlagsMaintainedAcrossNavigation) {
+ GURL main_url(
+ embedded_test_server()->GetURL("a.com", "/sandbox_main_frame_csp.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());
+
+ EXPECT_EQ(
+ " Site A\n"
+ " +--Site A\n"
+ "Where A = http://a.com/",
+ DepictFrameTree(root));
+
+ FrameTreeNode* child_node = root->child_at(0);
+
+ EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
+ child_node->current_frame_host()->GetSiteInstance());
+
+ // Main page is served with a CSP header applying sandbox flags allow-popups,
+ // allow-pointer-lock and allow-scripts.
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->pending_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->active_sandbox_flags());
+
+ // Child frame has iframe sandbox flags allow-popups, allow-scripts, and
+ // allow-orientation-lock. It should receive the intersection of those with
+ // the parent sandbox flags: allow-popups and allow-scripts.
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
+
+ // Document in child frame is served with a CSP header giving sandbox flags
+ // allow-scripts, allow-popups and allow-pointer-lock. The final effective
+ // flags should only include allow-scripts and allow-popups.
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->active_sandbox_flags());
+
+ // Navigate the child frame to a new page. This should clear any CSP-applied
+ // sandbox flags.
+ GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
+ NavigateFrameToURL(root->child_at(0), frame_url);
+
+ EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
+ child_node->current_frame_host()->GetSiteInstance());
+
+ // Navigating should reset the sandbox flags to the frame owner flags:
+ // allow-popups and allow-scripts.
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->active_sandbox_flags());
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->pending_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->effective_frame_policy().sandbox_flags);
+}
+
+// Test that after an RFH is swapped out, its old sandbox flags remain active.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ ActiveSandboxFlagsRetainedAfterSwapOut) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/sandboxed_main_frame_script.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 = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ RenderFrameHostImpl* rfh =
+ static_cast<WebContentsImpl*>(shell()->web_contents())->GetMainFrame();
+
+ // Check sandbox flags on RFH before navigating away.
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ rfh->active_sandbox_flags());
+
+ // Set up a slow unload handler to force the RFH to linger in the swapped
+ // out but not-yet-deleted state.
+ EXPECT_TRUE(
+ ExecuteScript(rfh, "window.onunload=function(e){ while(1); };\n"));
+
+ rfh->DisableSwapOutTimerForTesting();
+ RenderFrameDeletedObserver rfh_observer(rfh);
+
+ // Navigate to a page with no sandbox, but wait for commit, not for the actual
+ // load to finish.
+ TestFrameNavigationObserver commit_observer(root);
+ shell()->LoadURL(
+ GURL(embedded_test_server()->GetURL("b.com", "/title1.html")));
+ commit_observer.WaitForCommit();
+
+ // The previous RFH should still be pending deletion, as we wait for either
+ // the SwapOut ACK or a timeout.
+ ASSERT_TRUE(rfh->IsRenderFrameLive());
+ ASSERT_FALSE(rfh->is_active());
+ ASSERT_FALSE(rfh_observer.deleted());
+
+ // Check sandbox flags on old RFH -- they should be unchanged.
+ EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ rfh->active_sandbox_flags());
+
+ // The FrameTreeNode should have flags which represent the new state.
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->effective_frame_policy().sandbox_flags);
+}
+
+// Verify that when CSP-set sandbox flags on a page change due to navigation,
+// the new flags are propagated to proxies in other SiteInstances.
+//
+// A A A A
+// \ \ \ \ .
+// B -> B* -> B* -> B*
+// / \ / \ / \ .
+// B B A B C B
+//
+// (B* has CSP-set sandbox flags)
+// The test checks sandbox flags for the proxy added in step 2, by checking
+// whether the grandchild frames navigated to in step 3 and 4 see the correct
+// sandbox flags.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ ActiveSandboxFlagsCorrectInProxies) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "foo.com", "/cross_site_iframe_factory.html?foo(bar)"));
+ 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();
+ TestNavigationObserver observer(shell()->web_contents());
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " +--Site B ------- proxies for A\n"
+ "Where A = http://foo.com/\n"
+ " B = http://bar.com/",
+ DepictFrameTree(root));
+
+ // Navigate the child to a CSP-sandboxed page on the same origin as it is
+ // currently. This should update the flags in its proxies as well.
+ NavigateFrameToURL(
+ root->child_at(0),
+ embedded_test_server()->GetURL("bar.com", "/csp_sandboxed_frame.html"));
+
+ 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://foo.com/\n"
+ " B = http://bar.com/",
+ DepictFrameTree(root));
+
+ // Now navigate the first grandchild to a page on the same origin as the main
+ // frame. It should still be sandboxed, as it should get its flags from its
+ // (remote) parent.
+ NavigateFrameToURL(root->child_at(0)->child_at(0),
+ embedded_test_server()->GetURL("foo.com", "/title1.html"));
+
+ 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://foo.com/\n"
+ " B = http://bar.com/",
+ DepictFrameTree(root));
+
+ // The child of the sandboxed frame should've inherited sandbox flags, so it
+ // should not be able to create popups.
+ EXPECT_EQ(
+ blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(
+ root->child_at(0)->child_at(0)->active_sandbox_flags(),
+ root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
+ bool success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ root->child_at(0)->child_at(0),
+ "window.domAutomationController.send("
+ " !window.open('data:text/html,dataurl'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_EQ(1u, Shell::windows().size());
+
+ // Finally, navigate the grandchild frame to a new origin, creating a new site
+ // instance. Again, the new document should be sandboxed, as it should get its
+ // flags from its (remote) parent in B.
+ NavigateFrameToURL(root->child_at(0)->child_at(0),
+ embedded_test_server()->GetURL("baz.com", "/title1.html"));
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B C\n"
+ " +--Site B ------- proxies for A C\n"
+ " |--Site C -- proxies for A B\n"
+ " +--Site B -- proxies for A C\n"
+ "Where A = http://foo.com/\n"
+ " B = http://bar.com/\n"
+ " C = http://baz.com/",
+ DepictFrameTree(root));
+
+ // The child of the sandboxed frame should've inherited sandbox flags, so it
+ // should not be able to create popups.
+ EXPECT_EQ(
+ blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(
+ root->child_at(0)->child_at(0)->active_sandbox_flags(),
+ root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
+ success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ root->child_at(0)->child_at(0),
+ "window.domAutomationController.send("
+ " !window.open('data:text/html,dataurl'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_EQ(1u, Shell::windows().size());
+}
+
+// Verify that when the sandbox iframe attribute changes on a page which also
+// has CSP-set sandbox flags, that the correct combination of flags is set in
+// the sandboxed page after navigation.
+//
+// A A A A
+// \ \ \ \ .
+// B -> B* -> B* -> (change sandbox attr) -> B*
+// / \ / \ / \ .
+// B B A B A' B
+//
+// (B* has CSP-set sandbox flags)
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ ActiveSandboxFlagsCorrectAfterUpdate) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "foo.com", "/cross_site_iframe_factory.html?foo(bar)"));
+ 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();
+ TestNavigationObserver observer(shell()->web_contents());
+
+ // Navigate the child to a CSP-sandboxed page on the same origin as it is
+ // currently. This should update the flags in its proxies as well.
+ NavigateFrameToURL(
+ root->child_at(0),
+ embedded_test_server()->GetURL("bar.com", "/csp_sandboxed_frame.html"));
+
+ // Now navigate the first grandchild to a page on the same origin as the main
+ // frame. It should still be sandboxed, as it should get its flags from its
+ // (remote) parent.
+ NavigateFrameToURL(root->child_at(0)->child_at(0),
+ embedded_test_server()->GetURL("foo.com", "/title1.html"));
+
+ // The child of the sandboxed frame should've inherited sandbox flags, so it
+ // should not be able to create popups.
+ EXPECT_EQ(
+ blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(
+ root->child_at(0)->child_at(0)->active_sandbox_flags(),
+ root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
+ bool success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ root->child_at(0)->child_at(0),
+ "window.domAutomationController.send("
+ " !window.open('data:text/html,dataurl'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_EQ(1u, Shell::windows().size());
+
+ // Update the sandbox attribute in the child frame. This should be overridden
+ // by the CSP-set sandbox on this frame: The grandchild should *not* receive
+ // an allowance for popups after it is navigated.
+ EXPECT_TRUE(ExecuteScript(root->child_at(0),
+ "document.querySelector('iframe').sandbox = "
+ " 'allow-scripts allow-popups';"));
+ // Finally, navigate the grandchild frame to another page on the top-level
+ // origin; the active sandbox flags should still come from the it's parent's
+ // CSP and the frame owner attributes.
+ NavigateFrameToURL(root->child_at(0)->child_at(0),
+ embedded_test_server()->GetURL("foo.com", "/title2.html"));
+ EXPECT_EQ(
+ blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(
+ root->child_at(0)->child_at(0)->active_sandbox_flags(),
+ root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
+ success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ root->child_at(0)->child_at(0),
+ "window.domAutomationController.send("
+ " !window.open('data:text/html,dataurl'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_EQ(1u, Shell::windows().size());
+}
+
+// Verify that when the sandbox iframe attribute is removed from a page which
+// also has CSP-set sandbox flags, that the flags are cleared in the browser
+// and renderers (including proxies) after navigation to a page without CSP-set
+// flags.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ ActiveSandboxFlagsCorrectWhenCleared) {
+ GURL main_url(
+ embedded_test_server()->GetURL("foo.com", "/sandboxed_frames_csp.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();
+ TestNavigationObserver observer(shell()->web_contents());
+
+ // The second child has both iframe-attribute sandbox flags and CSP-set flags.
+ // Verify that it the flags are combined correctly in the frame tree.
+ EXPECT_EQ(blink::WebSandboxFlags::kAll &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kOrientationLock &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(1)->active_sandbox_flags());
+
+ NavigateFrameToURL(
+ root->child_at(1),
+ embedded_test_server()->GetURL("bar.com", "/sandboxed_child_frame.html"));
+ EXPECT_EQ(blink::WebSandboxFlags::kAll &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kOrientationLock &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kAll &
+ ~blink::WebSandboxFlags::kPointerLock &
+ ~blink::WebSandboxFlags::kScripts &
+ ~blink::WebSandboxFlags::kAutomaticFeatures,
+ root->child_at(1)->active_sandbox_flags());
+
+ // Remove the sandbox attribute from the child frame.
+ EXPECT_TRUE(ExecuteScript(root,
+ "document.querySelectorAll('iframe')[1]"
+ ".removeAttribute('sandbox');"));
+ // Finally, navigate that child frame to another page on the same origin with
+ // no CSP-set sandbox. Its sandbox flags should be completely cleared, and
+ // should be cleared in the proxy in the main frame's renderer as well.
+ // We can check that the flags were properly cleared by nesting another frame
+ // under the child, and ensuring that *it* saw no sandbox flags in the
+ // browser, or in the RemoteSecurityContext in the main frame's renderer.
+ NavigateFrameToURL(
+ root->child_at(1),
+ embedded_test_server()->GetURL(
+ "bar.com", "/cross_site_iframe_factory.html?bar(foo)"));
+
+ // Check the sandbox flags on the child frame in the browser process.
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->child_at(1)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(blink::WebSandboxFlags::kNone,
+ root->child_at(1)->active_sandbox_flags());
+
+ // Check the sandbox flags on the grandchid frame in the browser process.
+ EXPECT_EQ(
+ blink::WebSandboxFlags::kNone,
+ root->child_at(1)->child_at(0)->effective_frame_policy().sandbox_flags);
+ EXPECT_EQ(
+ root->child_at(1)->child_at(0)->active_sandbox_flags(),
+ root->child_at(1)->child_at(0)->effective_frame_policy().sandbox_flags);
+
+ // Check the sandbox flags in the grandchild frame's renderer by attempting
+ // to open a popup. This should succeed.
+ bool success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ root->child_at(1)->child_at(0),
+ "window.domAutomationController.send("
+ " !!window.open('data:text/html,dataurl'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_EQ(2u, Shell::windows().size());
+}
+
} // namespace content
diff --git a/chromium/content/browser/site_per_process_mac_browsertest.mm b/chromium/content/browser/site_per_process_mac_browsertest.mm
index a807770ae9b..54388fe36da 100644
--- a/chromium/content/browser/site_per_process_mac_browsertest.mm
+++ b/chromium/content/browser/site_per_process_mac_browsertest.mm
@@ -9,6 +9,7 @@
#include "base/mac/mac_util.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/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -66,54 +67,6 @@ class TextInputClientMacHelper {
DISALLOW_COPY_AND_ASSIGN(TextInputClientMacHelper);
};
-// Class to detect incoming gesture event acks for scrolling tests.
-class InputEventAckWaiter
- : public content::RenderWidgetHost::InputEventObserver {
- public:
- InputEventAckWaiter(blink::WebInputEvent::Type ack_type_waiting_for)
- : message_loop_runner_(new content::MessageLoopRunner),
- ack_type_waiting_for_(ack_type_waiting_for),
- desired_ack_type_received_(false) {}
- ~InputEventAckWaiter() override {}
-
- void OnInputEventAck(const blink::WebInputEvent& event) override {
- if (event.GetType() != ack_type_waiting_for_)
- return;
-
- // Ignore synthetic GestureScrollBegin/Ends.
- if ((event.GetType() == blink::WebInputEvent::kGestureScrollBegin &&
- static_cast<const blink::WebGestureEvent&>(event)
- .data.scroll_begin.synthetic) ||
- (event.GetType() == blink::WebInputEvent::kGestureScrollEnd &&
- static_cast<const blink::WebGestureEvent&>(event)
- .data.scroll_end.synthetic)) {
- return;
- }
-
- desired_ack_type_received_ = true;
- if (message_loop_runner_->loop_running())
- message_loop_runner_->Quit();
- }
-
- void Wait() {
- if (!desired_ack_type_received_) {
- message_loop_runner_->Run();
- }
- }
-
- void Reset() {
- desired_ack_type_received_ = false;
- message_loop_runner_ = new content::MessageLoopRunner;
- }
-
- private:
- scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
- blink::WebInputEvent::Type ack_type_waiting_for_;
- bool desired_ack_type_received_;
-
- DISALLOW_COPY_AND_ASSIGN(InputEventAckWaiter);
-};
-
} // namespace
// Site per process browser tests inside content which are specific to Mac OSX
@@ -194,14 +147,20 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessMacBrowserTest,
RenderWidgetHost* child_rwh =
child_iframe_node->current_frame_host()->GetRenderWidgetHost();
- std::unique_ptr<InputEventAckWaiter> gesture_scroll_begin_ack_observer =
- base::MakeUnique<InputEventAckWaiter>(
- blink::WebInputEvent::kGestureScrollBegin);
- std::unique_ptr<InputEventAckWaiter> gesture_scroll_end_ack_observer =
- base::MakeUnique<InputEventAckWaiter>(
- blink::WebInputEvent::kGestureScrollEnd);
- child_rwh->AddInputEventObserver(gesture_scroll_begin_ack_observer.get());
- child_rwh->AddInputEventObserver(gesture_scroll_end_ack_observer.get());
+ InputEventAckWaiter gesture_scroll_begin_ack_observer(
+ child_rwh, base::BindRepeating([](InputEventAckSource, InputEventAckState,
+ const blink::WebInputEvent& event) {
+ return event.GetType() == blink::WebInputEvent::kGestureScrollBegin &&
+ !static_cast<const blink::WebGestureEvent&>(event)
+ .data.scroll_begin.synthetic;
+ }));
+ InputEventAckWaiter gesture_scroll_end_ack_observer(
+ child_rwh, base::BindRepeating([](InputEventAckSource, InputEventAckState,
+ const blink::WebInputEvent& event) {
+ return event.GetType() == blink::WebInputEvent::kGestureScrollEnd &&
+ !static_cast<const blink::WebGestureEvent&>(event)
+ .data.scroll_end.synthetic;
+ }));
RenderWidgetHostViewBase* child_rwhv =
static_cast<RenderWidgetHostViewBase*>(child_rwh->GetView());
@@ -223,7 +182,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessMacBrowserTest,
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
scroll_event.momentum_phase = blink::WebMouseWheelEvent::kPhaseNone;
child_rwhv->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- gesture_scroll_begin_ack_observer->Wait();
+ gesture_scroll_begin_ack_observer.Wait();
scroll_event.delta_y = -2.0f;
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseChanged;
@@ -240,9 +199,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessMacBrowserTest,
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
scroll_event.momentum_phase = blink::WebMouseWheelEvent::kPhaseNone;
child_rwhv->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- gesture_scroll_end_ack_observer->Wait();
- gesture_scroll_begin_ack_observer->Reset();
- gesture_scroll_end_ack_observer->Reset();
+ gesture_scroll_end_ack_observer.Wait();
+ gesture_scroll_begin_ack_observer.Reset();
+ gesture_scroll_end_ack_observer.Reset();
}
// We now go into a fling.
@@ -251,7 +210,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessMacBrowserTest,
scroll_event.momentum_phase = blink::WebMouseWheelEvent::kPhaseBegan;
child_rwhv->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
if (!child_rwhv->wheel_scroll_latching_enabled())
- gesture_scroll_begin_ack_observer->Wait();
+ gesture_scroll_begin_ack_observer.Wait();
scroll_event.delta_y = -2.0f;
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseNone;
@@ -263,7 +222,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessMacBrowserTest,
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseNone;
scroll_event.momentum_phase = blink::WebMouseWheelEvent::kPhaseEnded;
child_rwhv->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- gesture_scroll_end_ack_observer->Wait();
+ gesture_scroll_end_ack_observer.Wait();
}
namespace {
diff --git a/chromium/content/browser/snapshot_browsertest.cc b/chromium/content/browser/snapshot_browsertest.cc
index 4525fe4bc96..2145e19369f 100644
--- a/chromium/content/browser/snapshot_browsertest.cc
+++ b/chromium/content/browser/snapshot_browsertest.cc
@@ -12,6 +12,7 @@
#include "base/command_line.h"
#include "base/rand_util.h"
+#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -249,12 +250,22 @@ IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, SingleWindowTest) {
}
}
-// Seen to time out / fail on debug Mac; crbug.com/771119, crbug.com/774050.
-#if defined(NDEBUG) && !defined(OS_MACOSX)
-#define MAYBE_SyncMultiWindowTest SyncMultiWindowTest
-#else
+// Timing out either all the time, or infrequently, apparently because
+// they're too slow, on the following configurations:
+// Windows Debug
+// Linux Chromium OS ASAN LSAN Tests (1)
+// Linux TSAN Tests
+// See crbug.com/771119
+#if (defined(OS_WIN) && !defined(NDEBUG)) || \
+ (defined(OS_CHROMEOS) && defined(ADDRESS_SANITIZER)) || \
+ (defined(OS_LINUX) && defined(THREAD_SANITIZER))
#define MAYBE_SyncMultiWindowTest DISABLED_SyncMultiWindowTest
+#define MAYBE_AsyncMultiWindowTest DISABLED_AsyncMultiWindowTest
+#else
+#define MAYBE_SyncMultiWindowTest SyncMultiWindowTest
+#define MAYBE_AsyncMultiWindowTest AsyncMultiWindowTest
#endif
+
IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_SyncMultiWindowTest) {
SetupTestServer();
@@ -310,9 +321,7 @@ IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_SyncMultiWindowTest) {
}
}
-// Seen to time out / fail on Mac and Win bots; crbug.com/772379,
-// crbug.com/771119.
-IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, AsyncMultiWindowTest) {
+IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_AsyncMultiWindowTest) {
SetupTestServer();
for (int i = 0; i < 3; ++i) {
diff --git a/chromium/content/browser/speech/audio_encoder.cc b/chromium/content/browser/speech/audio_encoder.cc
index 950948bc46d..c036c2d5a13 100644
--- a/chromium/content/browser/speech/audio_encoder.cc
+++ b/chromium/content/browser/speech/audio_encoder.cc
@@ -55,8 +55,9 @@ void AudioEncoder::Encode(const AudioChunk& raw_audio) {
DCHECK_EQ(raw_audio.bytes_per_sample(), 2);
if (!is_encoder_initialized_) {
const FLAC__StreamEncoderInitStatus encoder_status =
- FLAC__stream_encoder_init_stream(encoder_, WriteCallback, NULL, NULL,
- NULL, &encoded_audio_buffer_);
+ FLAC__stream_encoder_init_stream(encoder_, WriteCallback, nullptr,
+ nullptr, nullptr,
+ &encoded_audio_buffer_);
DCHECK_EQ(encoder_status, FLAC__STREAM_ENCODER_INIT_STATUS_OK);
is_encoder_initialized_ = true;
}
diff --git a/chromium/content/browser/speech/chunked_byte_buffer.cc b/chromium/content/browser/speech/chunked_byte_buffer.cc
index 6a5a517fd04..ae219c75800 100644
--- a/chromium/content/browser/speech/chunked_byte_buffer.cc
+++ b/chromium/content/browser/speech/chunked_byte_buffer.cc
@@ -36,7 +36,7 @@ void ChunkedByteBuffer::Append(const uint8_t* start, size_t length) {
const uint8_t* next_data = start;
while (remaining_bytes > 0) {
- DCHECK(partial_chunk_ != NULL);
+ DCHECK(partial_chunk_ != nullptr);
size_t insert_length = 0;
bool header_completed = false;
bool content_completed = false;
diff --git a/chromium/content/browser/speech/chunked_byte_buffer_unittest.cc b/chromium/content/browser/speech/chunked_byte_buffer_unittest.cc
index d8a5cb27842..099d3113815 100644
--- a/chromium/content/browser/speech/chunked_byte_buffer_unittest.cc
+++ b/chromium/content/browser/speech/chunked_byte_buffer_unittest.cc
@@ -44,7 +44,7 @@ TEST(ChunkedByteBufferTest, BasicTest) {
// Remove and check chunk 1.
std::unique_ptr<ByteVector> chunk;
chunk = buffer.PopChunk();
- EXPECT_TRUE(chunk != NULL);
+ EXPECT_TRUE(chunk != nullptr);
EXPECT_EQ(4U, chunk->size());
EXPECT_EQ(0, std::char_traits<uint8_t>::compare(kChunks + 4, &(*chunk)[0],
chunk->size()));
@@ -53,7 +53,7 @@ TEST(ChunkedByteBufferTest, BasicTest) {
// Read and check chunk 2.
chunk = buffer.PopChunk();
- EXPECT_TRUE(chunk != NULL);
+ EXPECT_TRUE(chunk != nullptr);
EXPECT_EQ(2U, chunk->size());
EXPECT_EQ(0, std::char_traits<uint8_t>::compare(kChunks + 12, &(*chunk)[0],
chunk->size()));
@@ -66,7 +66,7 @@ TEST(ChunkedByteBufferTest, BasicTest) {
// Remove and check chunk 3.
chunk = buffer.PopChunk();
- EXPECT_TRUE(chunk != NULL);
+ EXPECT_TRUE(chunk != nullptr);
EXPECT_EQ(1U, chunk->size());
EXPECT_EQ((*chunk)[0], kChunks[18]);
EXPECT_EQ(0U, buffer.GetTotalLength());
diff --git a/chromium/content/browser/speech/endpointer/endpointer.cc b/chromium/content/browser/speech/endpointer/endpointer.cc
index 1758970ee11..2ad1992c2ae 100644
--- a/chromium/content/browser/speech/endpointer/endpointer.cc
+++ b/chromium/content/browser/speech/endpointer/endpointer.cc
@@ -7,9 +7,8 @@
#include "base/time/time.h"
#include "content/browser/speech/audio_buffer.h"
-using base::Time;
-
namespace {
+const int64_t kMicrosecondsPerSecond = base::Time::kMicrosecondsPerSecond;
const int kFrameRate = 50; // 1 frame = 20ms of audio.
}
@@ -26,13 +25,13 @@ Endpointer::Endpointer(int sample_rate)
frame_size_ = static_cast<int>(sample_rate / static_cast<float>(kFrameRate));
speech_input_minimum_length_us_ =
- static_cast<int64_t>(1.7 * Time::kMicrosecondsPerSecond);
+ static_cast<int64_t>(1.7 * kMicrosecondsPerSecond);
speech_input_complete_silence_length_us_ =
- static_cast<int64_t>(0.5 * Time::kMicrosecondsPerSecond);
+ static_cast<int64_t>(0.5 * kMicrosecondsPerSecond);
long_speech_input_complete_silence_length_us_ = -1;
long_speech_length_us_ = -1;
speech_input_possibly_complete_silence_length_us_ =
- 1 * Time::kMicrosecondsPerSecond;
+ 1 * kMicrosecondsPerSecond;
// Set the default configuration for Push To Talk mode.
EnergyEndpointerParams ep_config;
@@ -105,8 +104,8 @@ EpStatus Endpointer::ProcessAudio(const AudioChunk& raw_audio, float* rms_out) {
frame_size_,
rms_out);
sample_index += frame_size_;
- audio_frame_time_us_ += (frame_size_ * Time::kMicrosecondsPerSecond) /
- sample_rate_;
+ audio_frame_time_us_ +=
+ (frame_size_ * kMicrosecondsPerSecond) / sample_rate_;
// Get the status of the endpointer.
int64_t ep_time;
diff --git a/chromium/content/browser/speech/endpointer/endpointer_unittest.cc b/chromium/content/browser/speech/endpointer/endpointer_unittest.cc
index 53ec4d19afc..200c42ca0e1 100644
--- a/chromium/content/browser/speech/endpointer/endpointer_unittest.cc
+++ b/chromium/content/browser/speech/endpointer/endpointer_unittest.cc
@@ -80,7 +80,7 @@ class EnergyEndpointerFrameProcessor : public FrameProcessor {
EpStatus ProcessFrame(int64_t time,
int16_t* samples,
int frame_size) override {
- endpointer_->ProcessAudioFrame(time, samples, kFrameSize, NULL);
+ endpointer_->ProcessAudioFrame(time, samples, kFrameSize, nullptr);
int64_t ep_time;
return endpointer_->Status(&ep_time);
}
@@ -127,7 +127,7 @@ class EndpointerFrameProcessor : public FrameProcessor {
int frame_size) override {
scoped_refptr<AudioChunk> frame(
new AudioChunk(reinterpret_cast<uint8_t*>(samples), kFrameSize * 2, 2));
- endpointer_->ProcessAudio(*frame.get(), NULL);
+ endpointer_->ProcessAudio(*frame.get(), nullptr);
int64_t ep_time;
return endpointer_->Status(&ep_time);
}
diff --git a/chromium/content/browser/speech/speech_recognition_engine.cc b/chromium/content/browser/speech/speech_recognition_engine.cc
index 53919a718cd..e273b90874e 100644
--- a/chromium/content/browser/speech/speech_recognition_engine.cc
+++ b/chromium/content/browser/speech/speech_recognition_engine.cc
@@ -407,8 +407,8 @@ SpeechRecognitionEngine::ConnectBothStreams(const FSMEventArgs&) {
}
upstream_args.push_back("app=chromium");
for (const SpeechRecognitionGrammar& grammar : config_.grammars) {
- std::string grammar_value(
- base::DoubleToString(grammar.weight) + ":" + grammar.url);
+ std::string grammar_value(base::NumberToString(grammar.weight) + ":" +
+ grammar.url);
upstream_args.push_back(
"grammar=" + net::EscapeQueryParamValue(grammar_value, true));
}
diff --git a/chromium/content/browser/speech/speech_recognition_engine_unittest.cc b/chromium/content/browser/speech/speech_recognition_engine_unittest.cc
index 4ea8fc4aca8..fd880ae2d36 100644
--- a/chromium/content/browser/speech/speech_recognition_engine_unittest.cc
+++ b/chromium/content/browser/speech/speech_recognition_engine_unittest.cc
@@ -420,7 +420,7 @@ TEST_F(SpeechRecognitionEngineTest, SendPreamble) {
void SpeechRecognitionEngineTest::SetUp() {
engine_under_test_.reset(
- new SpeechRecognitionEngine(NULL /*URLRequestContextGetter*/));
+ new SpeechRecognitionEngine(nullptr /*URLRequestContextGetter*/));
engine_under_test_->set_delegate(this);
}
diff --git a/chromium/content/browser/speech/speech_recognition_manager_impl.cc b/chromium/content/browser/speech/speech_recognition_manager_impl.cc
index 9c6010c840e..03ef916e5ff 100644
--- a/chromium/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/chromium/content/browser/speech/speech_recognition_manager_impl.cc
@@ -82,7 +82,7 @@ SpeechRecognitionManagerImpl::~SpeechRecognitionManagerImpl() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(g_speech_recognition_manager_impl);
- g_speech_recognition_manager_impl = NULL;
+ g_speech_recognition_manager_impl = nullptr;
for (SessionsTable::iterator it = sessions_.begin(); it != sessions_.end();
++it) {
@@ -180,7 +180,8 @@ void SpeechRecognitionManagerImpl::RecognitionAllowedCallback(int session_id,
SpeechRecognitionSessionContext& context = session->context;
context.label = media_stream_manager_->MakeMediaAccessRequest(
context.render_process_id, context.render_frame_id, context.request_id,
- StreamControls(true, false), url::Origin(GURL(context.context_name)),
+ StreamControls(true, false),
+ url::Origin::Create(GURL(context.context_name)),
base::BindOnce(
&SpeechRecognitionManagerImpl::MediaRequestPermissionCallback,
weak_factory_.GetWeakPtr(), session_id));
@@ -587,7 +588,8 @@ void SpeechRecognitionManagerImpl::ResetCapturingSessionId(
}
void SpeechRecognitionManagerImpl::SessionDelete(Session* session) {
- DCHECK(session->recognizer.get() == NULL || !session->recognizer->IsActive());
+ DCHECK(session->recognizer.get() == nullptr ||
+ !session->recognizer->IsActive());
if (primary_session_id_ == session->id)
primary_session_id_ = kSessionIDInvalid;
if (!session->context.label.empty())
@@ -628,12 +630,12 @@ SpeechRecognitionEventListener* SpeechRecognitionManagerImpl::GetListener(
Session* session = GetSession(session_id);
if (session->listener_is_active && session->config.event_listener)
return session->config.event_listener.get();
- return NULL;
+ return nullptr;
}
SpeechRecognitionEventListener*
SpeechRecognitionManagerImpl::GetDelegateListener() const {
- return delegate_.get() ? delegate_->GetEventListener() : NULL;
+ return delegate_.get() ? delegate_->GetEventListener() : nullptr;
}
const SpeechRecognitionSessionConfig&
diff --git a/chromium/content/browser/speech/speech_recognition_manager_impl.h b/chromium/content/browser/speech/speech_recognition_manager_impl.h
index 7626cfeaa2b..e3e993130d0 100644
--- a/chromium/content/browser/speech/speech_recognition_manager_impl.h
+++ b/chromium/content/browser/speech/speech_recognition_manager_impl.h
@@ -12,7 +12,6 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
-#include "content/browser/renderer_host/media/media_stream_requester.h"
#include "content/public/browser/speech_recognition_event_listener.h"
#include "content/public/browser/speech_recognition_manager.h"
#include "content/public/browser/speech_recognition_session_config.h"
diff --git a/chromium/content/browser/speech/speech_recognizer_impl.cc b/chromium/content/browser/speech/speech_recognizer_impl.cc
index 3812dc9f40c..e09035b1e3b 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl.cc
@@ -259,8 +259,8 @@ bool SpeechRecognizerImpl::IsCapturingAudio() const {
DCHECK_CURRENTLY_ON(BrowserThread::IO); // See IsActive().
const bool is_capturing_audio = state_ >= STATE_STARTING &&
state_ <= STATE_RECOGNIZING;
- DCHECK((is_capturing_audio && (audio_controller_.get() != NULL)) ||
- (!is_capturing_audio && audio_controller_.get() == NULL));
+ DCHECK((is_capturing_audio && (audio_controller_.get() != nullptr)) ||
+ (!is_capturing_audio && audio_controller_.get() == nullptr));
return is_capturing_audio;
}
@@ -280,7 +280,7 @@ SpeechRecognizerImpl::~SpeechRecognizerImpl() {
}
// Invoked in the audio thread.
-void SpeechRecognizerImpl::OnError(AudioInputController* controller,
+void SpeechRecognizerImpl::OnError(
media::AudioInputController::ErrorCode error_code) {
FSMEventArgs event_args(EVENT_AUDIO_ERROR);
BrowserThread::PostTask(
@@ -364,7 +364,7 @@ void SpeechRecognizerImpl::DispatchEvent(const FSMEventArgs& event_args) {
scoped_refptr<SpeechRecognizerImpl> me(this);
if (event_args.event == EVENT_AUDIO_DATA) {
- DCHECK(event_args.audio_data.get() != NULL);
+ DCHECK(event_args.audio_data.get() != nullptr);
ProcessAudioPipeline(*event_args.audio_data.get());
}
@@ -548,7 +548,7 @@ void SpeechRecognizerImpl::ProcessAudioPipeline(const AudioChunk& raw_audio) {
UpdateSignalAndNoiseLevels(rms, clip_detected);
}
if (route_to_sr_engine) {
- DCHECK(recognition_engine_.get() != NULL);
+ DCHECK(recognition_engine_.get() != nullptr);
recognition_engine_->TakeAudioChunk(raw_audio);
}
}
@@ -564,7 +564,7 @@ void SpeechRecognizerImpl::OnDeviceInfo(
SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::PrepareRecognition(
const FSMEventArgs&) {
DCHECK(state_ == STATE_IDLE);
- DCHECK(recognition_engine_.get() != NULL);
+ DCHECK(recognition_engine_.get() != nullptr);
DCHECK(!IsCapturingAudio());
GetAudioSystem()->GetInputStreamParameters(
device_id_, base::BindOnce(&SpeechRecognizerImpl::OnDeviceInfo,
@@ -577,7 +577,7 @@ SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::PrepareRecognition(
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::StartRecording(const FSMEventArgs&) {
DCHECK(state_ == STATE_PREPARING);
- DCHECK(recognition_engine_.get() != NULL);
+ DCHECK(recognition_engine_.get() != nullptr);
DCHECK(!IsCapturingAudio());
DVLOG(1) << "SpeechRecognizerImpl starting audio capture.";
@@ -662,7 +662,7 @@ SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::StartRecognitionEngine(const FSMEventArgs& event_args) {
// This is the first audio packet captured, so the recognition engine is
// started and the delegate notified about the event.
- DCHECK(recognition_engine_.get() != NULL);
+ DCHECK(recognition_engine_.get() != nullptr);
recognition_engine_->StartRecognition();
listener()->OnAudioStart(session_id());
@@ -752,7 +752,7 @@ SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::Abort(
// The recognition engine is initialized only after STATE_STARTING.
if (state_ > STATE_STARTING) {
- DCHECK(recognition_engine_.get() != NULL);
+ DCHECK(recognition_engine_.get() != nullptr);
recognition_engine_->EndRecognition();
}
@@ -856,7 +856,7 @@ void SpeechRecognizerImpl::CloseAudioControllerAsynchronously() {
audio_controller_->Close(
base::BindOnce(&SpeechRecognizerImpl::OnAudioClosed, this,
base::RetainedRef(audio_controller_)));
- audio_controller_ = NULL; // The controller is still refcounted by Bind.
+ audio_controller_ = nullptr; // The controller is still refcounted by Bind.
audio_log_->OnClosed(0);
}
@@ -903,9 +903,8 @@ media::AudioManager* SpeechRecognizerImpl::GetAudioManager() {
SpeechRecognizerImpl::FSMEventArgs::FSMEventArgs(FSMEvent event_value)
: event(event_value),
- audio_data(NULL),
- engine_error(SPEECH_RECOGNITION_ERROR_NONE) {
-}
+ audio_data(nullptr),
+ engine_error(SPEECH_RECOGNITION_ERROR_NONE) {}
SpeechRecognizerImpl::FSMEventArgs::FSMEventArgs(const FSMEventArgs& other) =
default;
diff --git a/chromium/content/browser/speech/speech_recognizer_impl.h b/chromium/content/browser/speech/speech_recognizer_impl.h
index ef44f9b036d..b509fef7ef1 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl.h
+++ b/chromium/content/browser/speech/speech_recognizer_impl.h
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/strings/string_piece.h"
#include "content/browser/speech/endpointer/endpointer.h"
#include "content/browser/speech/speech_recognition_engine.h"
#include "content/browser/speech/speech_recognizer.h"
@@ -143,14 +144,10 @@ class CONTENT_EXPORT SpeechRecognizerImpl
void OnAudioClosed(media::AudioInputController*);
// AudioInputController::EventHandler methods.
- void OnCreated(media::AudioInputController* controller,
- bool initially_muted) override {}
- void OnError(media::AudioInputController* controller,
- media::AudioInputController::ErrorCode error_code) override;
- void OnLog(media::AudioInputController* controller,
- const std::string& message) override {}
- void OnMuted(media::AudioInputController* controller,
- bool is_muted) override {}
+ void OnCreated(bool initially_muted) override {}
+ void OnError(media::AudioInputController::ErrorCode error_code) override;
+ void OnLog(base::StringPiece) override {}
+ void OnMuted(bool is_muted) override {}
// AudioInputController::SyncWriter methods.
void Write(const media::AudioBus* data,
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc b/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
index 3dd2fb29aae..db08209880a 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
@@ -55,7 +55,7 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener,
volume_(-1.0f) {
// SpeechRecognizer takes ownership of sr_engine.
SpeechRecognitionEngine* sr_engine =
- new SpeechRecognitionEngine(NULL /* URLRequestContextGetter */);
+ new SpeechRecognitionEngine(nullptr /* URLRequestContextGetter */);
SpeechRecognitionEngine::Config config;
config.audio_num_bits_per_sample =
SpeechRecognizerImpl::kNumBitsPerAudioSample;
@@ -66,7 +66,7 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener,
const int kTestingSessionId = 1;
audio_manager_.reset(new media::MockAudioManager(
- base::MakeUnique<media::TestAudioThread>(true)));
+ std::make_unique<media::TestAudioThread>(true)));
audio_manager_->SetInputStreamParameters(
media::AudioParameters::UnavailableDeviceParams());
audio_system_ =
@@ -169,7 +169,7 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener,
}
void TearDown() override {
- AudioInputController::set_factory_for_testing(NULL);
+ AudioInputController::set_factory_for_testing(nullptr);
}
void CopyPacketToAudioBus() {
@@ -507,8 +507,7 @@ TEST_F(SpeechRecognizerImplTest, AudioControllerErrorNoData) {
TestAudioInputController* controller =
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
- controller->event_handler()->OnError(controller,
- AudioInputController::UNKNOWN_ERROR);
+ controller->event_handler()->OnError(AudioInputController::UNKNOWN_ERROR);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
@@ -529,8 +528,7 @@ TEST_F(SpeechRecognizerImplTest, AudioControllerErrorWithData) {
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
OnData(audio_bus_.get());
- controller->event_handler()->OnError(controller,
- AudioInputController::UNKNOWN_ERROR);
+ controller->event_handler()->OnError(AudioInputController::UNKNOWN_ERROR);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(url_fetcher_factory_.GetFetcherByID(0));
EXPECT_TRUE(recognition_started_);
diff --git a/chromium/content/browser/ssl/ssl_error_handler.cc b/chromium/content/browser/ssl/ssl_error_handler.cc
index b2b2de52032..6145e9b7673 100644
--- a/chromium/content/browser/ssl/ssl_error_handler.cc
+++ b/chromium/content/browser/ssl/ssl_error_handler.cc
@@ -41,11 +41,13 @@ void CompleteContinueRequest(
SSLErrorHandler::SSLErrorHandler(WebContents* web_contents,
const base::WeakPtr<Delegate>& delegate,
+ BrowserThread::ID delegate_thread,
ResourceType resource_type,
const GURL& url,
const net::SSLInfo& ssl_info,
bool fatal)
: delegate_(delegate),
+ delegate_thread_(delegate_thread),
request_url_(url),
resource_type_(resource_type),
ssl_info_(ssl_info),
@@ -53,12 +55,19 @@ SSLErrorHandler::SSLErrorHandler(WebContents* web_contents,
fatal_(fatal),
web_contents_(web_contents) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(delegate_thread == BrowserThread::UI ||
+ delegate_thread == BrowserThread::IO);
}
SSLErrorHandler::~SSLErrorHandler() {}
void SSLErrorHandler::CancelRequest() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (delegate_thread_ == BrowserThread::UI) {
+ if (delegate_)
+ delegate_->CancelSSLRequest(net::ERR_ABORTED, &ssl_info());
+ return;
+ }
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::BindOnce(&CompleteCancelRequest, delegate_,
ssl_info(), net::ERR_ABORTED));
@@ -66,14 +75,23 @@ void SSLErrorHandler::CancelRequest() {
void SSLErrorHandler::DenyRequest() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CompleteCancelRequest, delegate_, ssl_info(),
- net::ERR_INSECURE_RESPONSE));
+ if (delegate_thread_ == BrowserThread::UI) {
+ if (delegate_)
+ delegate_->CancelSSLRequest(cert_error_, &ssl_info());
+ return;
+ }
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&CompleteCancelRequest, delegate_,
+ ssl_info(), cert_error_));
}
void SSLErrorHandler::ContinueRequest() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (delegate_thread_ == BrowserThread::UI) {
+ if (delegate_)
+ delegate_->ContinueSSLRequest();
+ return;
+ }
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::BindOnce(&CompleteContinueRequest, delegate_));
}
diff --git a/chromium/content/browser/ssl/ssl_error_handler.h b/chromium/content/browser/ssl/ssl_error_handler.h
index 03a11eac80e..6cfe07c070f 100644
--- a/chromium/content/browser/ssl/ssl_error_handler.h
+++ b/chromium/content/browser/ssl/ssl_error_handler.h
@@ -11,6 +11,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/common/resource_type.h"
#include "net/ssl/ssl_info.h"
@@ -31,8 +32,8 @@ class WebContents;
// call exactly one of those methods exactly once.
class SSLErrorHandler {
public:
- // SSLErrorHandler's delegate lives on the IO thread, and thus these
- // delegate methods must be called on the IO thread only.
+ // SSLErrorHandler's delegate lives on the UI or IO thread based on the passed
+ // in |delegate_thread|. The methods will be called on that thread.
class CONTENT_EXPORT Delegate {
public:
// Called when SSLErrorHandler decides to cancel the request because of
@@ -49,6 +50,7 @@ class SSLErrorHandler {
SSLErrorHandler(WebContents* web_contents,
const base::WeakPtr<Delegate>& delegate,
+ BrowserThread::ID delegate_thread,
ResourceType resource_type,
const GURL& url,
const net::SSLInfo& ssl_info,
@@ -83,11 +85,12 @@ class SSLErrorHandler {
void DenyRequest();
private:
- // This must not be dereferenced on the UI thread. SSLErrorHandler
- // simply holds on to the reference to be passed back to the IO thread
- // to enact a decision about the error once one has been made.
+ // This is called on |delegate_thread_|.
base::WeakPtr<Delegate> delegate_;
+ // The thread that the delegate is called on.
+ BrowserThread::ID delegate_thread_;
+
// The URL for the request that generated the error.
const GURL request_url_;
diff --git a/chromium/content/browser/ssl/ssl_manager.cc b/chromium/content/browser/ssl/ssl_manager.cc
index d4f90426f97..1bc61f58899 100644
--- a/chromium/content/browser/ssl/ssl_manager.cc
+++ b/chromium/content/browser/ssl/ssl_manager.cc
@@ -36,13 +36,6 @@ namespace {
const char kSSLManagerKeyName[] = "content_ssl_manager";
-// Events for UMA. Do not reorder or change!
-enum SSLGoodCertSeenEvent {
- NO_PREVIOUS_EXCEPTION = 0,
- HAD_PREVIOUS_EXCEPTION = 1,
- SSL_GOOD_CERT_SEEN_EVENT_MAX = 2
-};
-
void OnAllowCertificateWithRecordDecision(
bool record_decision,
const base::Callback<void(bool, content::CertificateRequestResultType)>&
@@ -100,13 +93,15 @@ class SSLManagerSet : public base::SupportsUserData::Data {
void HandleSSLErrorOnUI(
const base::Callback<WebContents*(void)>& web_contents_getter,
const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
+ BrowserThread::ID delegate_thread,
const ResourceType resource_type,
const GURL& url,
const net::SSLInfo& ssl_info,
bool fatal) {
content::WebContents* web_contents = web_contents_getter.Run();
- std::unique_ptr<SSLErrorHandler> handler(new SSLErrorHandler(
- web_contents, delegate, resource_type, url, ssl_info, fatal));
+ std::unique_ptr<SSLErrorHandler> handler(
+ new SSLErrorHandler(web_contents, delegate, delegate_thread,
+ resource_type, url, ssl_info, fatal));
if (!web_contents) {
// Requests can fail to dispatch because they don't have a WebContents. See
@@ -145,12 +140,18 @@ void SSLManager::OnSSLCertificateError(
<< " url: " << url.spec()
<< " cert_status: " << std::hex << ssl_info.cert_status;
- // A certificate error occurred. Construct a SSLErrorHandler object
- // on the UI thread for processing.
+ if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ HandleSSLErrorOnUI(web_contents_getter, delegate, BrowserThread::UI,
+ resource_type, url, ssl_info, fatal);
+ return;
+ }
+
+ // 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::BindOnce(&HandleSSLErrorOnUI, web_contents_getter, delegate,
- resource_type, url, ssl_info, fatal));
+ BrowserThread::IO, resource_type, url, ssl_info, fatal));
}
// static
@@ -176,7 +177,7 @@ SSLManager::SSLManager(NavigationControllerImpl* controller)
SSLManagerSet* managers = static_cast<SSLManagerSet*>(
controller_->GetBrowserContext()->GetUserData(kSSLManagerKeyName));
if (!managers) {
- auto managers_owned = base::MakeUnique<SSLManagerSet>();
+ auto managers_owned = std::make_unique<SSLManagerSet>();
managers = managers_owned.get();
controller_->GetBrowserContext()->SetUserData(kSSLManagerKeyName,
std::move(managers_owned));
@@ -242,18 +243,6 @@ void SSLManager::DidDisplayContentWithCertErrors() {
}
}
-void SSLManager::DidShowPasswordInputOnHttp() {
- UpdateLastCommittedEntry(SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP, 0);
-}
-
-void SSLManager::DidHideAllPasswordInputsOnHttp() {
- UpdateLastCommittedEntry(0, SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP);
-}
-
-void SSLManager::DidShowCreditCardInputOnHttp() {
- UpdateLastCommittedEntry(SSLStatus::DISPLAYED_CREDIT_CARD_FIELD_ON_HTTP, 0);
-}
-
void SSLManager::DidRunMixedContent(const GURL& security_origin) {
NavigationEntryImpl* entry = controller_->GetLastCommittedEntry();
if (!entry)
@@ -317,7 +306,8 @@ void SSLManager::OnCertError(std::unique_ptr<SSLErrorHandler> handler) {
void SSLManager::DidStartResourceResponse(const GURL& url,
bool has_certificate,
- net::CertStatus ssl_cert_status) {
+ net::CertStatus ssl_cert_status,
+ ResourceType resource_type) {
if (has_certificate && url.SchemeIsCryptographic() &&
!net::IsCertStatusError(ssl_cert_status)) {
// If the scheme is https: or wss: *and* the security info for the
@@ -326,18 +316,16 @@ void SSLManager::DidStartResourceResponse(const GURL& url,
// have occurred. If the cert info has not been set, do nothing since it
// isn't known if the connection was actually a valid connection or if it
// had a cert error.
- SSLGoodCertSeenEvent event = NO_PREVIOUS_EXCEPTION;
if (ssl_host_state_delegate_ &&
ssl_host_state_delegate_->HasAllowException(url.host())) {
// If there's no certificate error, a good certificate has been seen, so
// clear out any exceptions that were made by the user for bad
// certificates. This intentionally does not apply to cached resources
// (see https://crbug.com/634553 for an explanation).
+ UMA_HISTOGRAM_BOOLEAN("interstitial.ssl.good_cert_seen_type_is_frame",
+ IsResourceTypeFrame(resource_type));
ssl_host_state_delegate_->RevokeUserAllowExceptions(url.host());
- event = HAD_PREVIOUS_EXCEPTION;
}
- UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.good_cert_seen", event,
- SSL_GOOD_CERT_SEEN_EVENT_MAX);
}
}
diff --git a/chromium/content/browser/ssl/ssl_manager.h b/chromium/content/browser/ssl/ssl_manager.h
index 240c172cd21..d4d846f78ca 100644
--- a/chromium/content/browser/ssl/ssl_manager.h
+++ b/chromium/content/browser/ssl/ssl_manager.h
@@ -14,6 +14,7 @@
#include "content/common/content_export.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/ssl_status.h"
+#include "content/public/common/resource_type.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_status_flags.h"
#include "url/gurl.h"
@@ -43,7 +44,8 @@ class CONTENT_EXPORT SSLManager {
// will adjust the security UI and either call |CancelSSLRequest| or
// |ContinueSSLRequest| of |delegate|.
//
- // Called on the IO thread.
+ // This can be called on the UI or IO thread. It will call |delegate| on the
+ // same thread.
static void OnSSLCertificateError(
const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
ResourceType resource_type,
@@ -74,7 +76,8 @@ class CONTENT_EXPORT SSLManager {
void DidCommitProvisionalLoad(const LoadCommittedDetails& details);
void DidStartResourceResponse(const GURL& url,
bool has_certificate,
- net::CertStatus ssl_cert_status);
+ net::CertStatus ssl_cert_status,
+ ResourceType resource_type);
// The following methods are called when a page includes insecure
// content. These methods update the SSLStatus on the NavigationEntry
@@ -84,9 +87,6 @@ class CONTENT_EXPORT SSLManager {
void DidDisplayMixedContent();
void DidContainInsecureFormAction();
void DidDisplayContentWithCertErrors();
- void DidShowPasswordInputOnHttp();
- void DidHideAllPasswordInputsOnHttp();
- void DidShowCreditCardInputOnHttp();
void DidRunMixedContent(const GURL& security_origin);
void DidRunContentWithCertErrors(const GURL& security_origin);
diff --git a/chromium/content/browser/ssl/ssl_manager_unittest.cc b/chromium/content/browser/ssl/ssl_manager_unittest.cc
deleted file mode 100644
index 0facd9ee99b..00000000000
--- a/chromium/content/browser/ssl/ssl_manager_unittest.cc
+++ /dev/null
@@ -1,107 +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/ssl/ssl_manager.h"
-
-#include "base/macros.h"
-#include "content/browser/site_instance_impl.h"
-#include "content/common/frame_messages.h"
-#include "content/public/browser/ssl_status.h"
-#include "content/public/browser/web_contents_delegate.h"
-#include "content/public/test/mock_render_process_host.h"
-#include "content/public/test/test_browser_context.h"
-#include "content/public/test/test_renderer_host.h"
-#include "content/test/test_web_contents.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-namespace {
-
-// A WebContentsDelegate that exposes the visible SSLStatus at the time
-// of the last VisibleSecurityStateChanged() call.
-class TestWebContentsDelegate : public WebContentsDelegate {
- public:
- TestWebContentsDelegate() : WebContentsDelegate() {}
- ~TestWebContentsDelegate() override {}
-
- const SSLStatus& last_ssl_state() { return last_ssl_state_; }
-
- // WebContentsDelegate:
- void VisibleSecurityStateChanged(WebContents* source) override {
- NavigationEntry* entry = source->GetController().GetVisibleEntry();
- EXPECT_TRUE(entry);
- last_ssl_state_ = entry->GetSSL();
- }
-
- private:
- SSLStatus last_ssl_state_;
- DISALLOW_COPY_AND_ASSIGN(TestWebContentsDelegate);
-};
-
-class SSLManagerTest : public RenderViewHostTestHarness {
- public:
- SSLManagerTest() : RenderViewHostTestHarness() {}
- ~SSLManagerTest() override {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(SSLManagerTest);
-};
-
-// Tests that VisibleSecurityStateChanged() is called when a password input
-// is shown on an HTTP page.
-TEST_F(SSLManagerTest, NotifyVisibleSSLStateChangeOnHttpPassword) {
- TestWebContentsDelegate delegate;
- web_contents()->SetDelegate(&delegate);
- SSLManager manager(
- static_cast<NavigationControllerImpl*>(&web_contents()->GetController()));
-
- NavigateAndCommit(GURL("http://example.test"));
- EXPECT_FALSE(delegate.last_ssl_state().content_status &
- SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP);
- web_contents()->OnPasswordInputShownOnHttp();
- EXPECT_TRUE(delegate.last_ssl_state().content_status &
- SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP);
-}
-
-// Tests that VisibleSecurityStateChanged() is called when a credit card input
-// is shown on an HTTP page.
-TEST_F(SSLManagerTest, NotifyVisibleSSLStateChangeOnHttpCreditCard) {
- TestWebContentsDelegate delegate;
- web_contents()->SetDelegate(&delegate);
- SSLManager manager(
- static_cast<NavigationControllerImpl*>(&web_contents()->GetController()));
-
- NavigateAndCommit(GURL("http://example.test"));
- EXPECT_FALSE(delegate.last_ssl_state().content_status &
- SSLStatus::DISPLAYED_CREDIT_CARD_FIELD_ON_HTTP);
- web_contents()->OnCreditCardInputShownOnHttp();
- EXPECT_TRUE(delegate.last_ssl_state().content_status &
- SSLStatus::DISPLAYED_CREDIT_CARD_FIELD_ON_HTTP);
-}
-
-// Tests that VisibleSecurityStateChanged() is called when password and
-// credit card inputs are shown on an HTTP page.
-TEST_F(SSLManagerTest, NotifyVisibleSSLStateChangeOnPasswordAndHttpCreditCard) {
- TestWebContentsDelegate delegate;
- web_contents()->SetDelegate(&delegate);
- SSLManager manager(
- static_cast<NavigationControllerImpl*>(&web_contents()->GetController()));
-
- NavigateAndCommit(GURL("http://example.test"));
- EXPECT_FALSE(delegate.last_ssl_state().content_status &
- SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP);
- EXPECT_FALSE(delegate.last_ssl_state().content_status &
- SSLStatus::DISPLAYED_CREDIT_CARD_FIELD_ON_HTTP);
- web_contents()->OnPasswordInputShownOnHttp();
- web_contents()->OnCreditCardInputShownOnHttp();
- EXPECT_TRUE(delegate.last_ssl_state().content_status &
- SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP);
- EXPECT_TRUE(delegate.last_ssl_state().content_status &
- SSLStatus::DISPLAYED_CREDIT_CARD_FIELD_ON_HTTP);
-}
-
-} // namespace
-
-} // namespace content
diff --git a/chromium/content/browser/storage_partition_impl.cc b/chromium/content/browser/storage_partition_impl.cc
index 011f314b4ab..3bc015e7887 100644
--- a/chromium/content/browser/storage_partition_impl.cc
+++ b/chromium/content/browser/storage_partition_impl.cc
@@ -261,7 +261,7 @@ class StoragePartitionImpl::NetworkContextOwner {
scoped_refptr<net::URLRequestContextGetter> context_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
context_getter_ = std::move(context_getter);
- network_context_ = base::MakeUnique<NetworkContext>(
+ network_context_ = std::make_unique<NetworkContext>(
std::move(network_context_request),
context_getter_->GetURLRequestContext());
}
@@ -357,10 +357,10 @@ struct StoragePartitionImpl::QuotaManagedDataDeletionHelper {
struct StoragePartitionImpl::DataDeletionHelper {
DataDeletionHelper(uint32_t remove_mask,
uint32_t quota_storage_remove_mask,
- const base::Closure& callback)
+ base::OnceClosure callback)
: remove_mask(remove_mask),
quota_storage_remove_mask(quota_storage_remove_mask),
- callback(callback),
+ callback(std::move(callback)),
task_count(0) {}
void IncrementTaskCountOnUI();
@@ -392,7 +392,7 @@ struct StoragePartitionImpl::DataDeletionHelper {
uint32_t quota_storage_remove_mask;
// Accessed on UI thread.
- const base::Closure callback;
+ base::OnceClosure callback;
// Accessed on UI thread.
int task_count;
};
@@ -552,8 +552,8 @@ std::unique_ptr<StoragePartitionImpl> StoragePartitionImpl::Create(
if (base::FeatureList::IsEnabled(features::kNetworkService)) {
BlobURLLoaderFactory::BlobContextGetter blob_getter =
base::BindOnce(&BlobStorageContextGetter, blob_context);
- partition->blob_url_loader_factory_ = BlobURLLoaderFactory::Create(
- std::move(blob_getter), partition->filesystem_context_);
+ partition->blob_url_loader_factory_ =
+ BlobURLLoaderFactory::Create(std::move(blob_getter));
partition->url_loader_factory_getter_ = new URLLoaderFactoryGetter();
partition->url_loader_factory_getter_->Initialize(partition.get());
@@ -592,7 +592,7 @@ mojom::NetworkContext* StoragePartitionImpl::GetNetworkContext() {
if (!network_context_) {
DCHECK(!base::FeatureList::IsEnabled(features::kNetworkService));
DCHECK(!network_context_owner_);
- network_context_owner_ = base::MakeUnique<NetworkContextOwner>();
+ network_context_owner_ = std::make_unique<NetworkContextOwner>();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&NetworkContextOwner::Initialize,
@@ -607,8 +607,7 @@ StoragePartitionImpl::GetURLLoaderFactoryForBrowserProcess() {
// Create the URLLoaderFactory as needed.
if (!url_loader_factory_for_browser_process_) {
GetNetworkContext()->CreateURLLoaderFactory(
- mojo::MakeRequest(&url_loader_factory_for_browser_process_),
- base::GetUniqueIdForProcess());
+ mojo::MakeRequest(&url_loader_factory_for_browser_process_), 0);
}
return url_loader_factory_for_browser_process_.get();
}
@@ -707,6 +706,20 @@ void StoragePartitionImpl::OpenLocalStorage(
dom_storage_context_->OpenLocalStorage(origin, std::move(request));
}
+void StoragePartitionImpl::OpenSessionStorage(
+ int64_t namespace_id,
+ const url::Origin& origin,
+ mojo::InterfaceRequest<mojom::LevelDBWrapper> request) {
+ int process_id = bindings_.dispatch_context();
+ if (!ChildProcessSecurityPolicy::GetInstance()->CanAccessDataForOrigin(
+ process_id, origin.GetURL())) {
+ bindings_.ReportBadMessage("Access denied for sessionStorage request");
+ return;
+ }
+ dom_storage_context_->OpenSessionStorage(namespace_id, origin,
+ std::move(request));
+}
+
void StoragePartitionImpl::ClearDataImpl(
uint32_t remove_mask,
uint32_t quota_storage_remove_mask,
@@ -716,11 +729,10 @@ void StoragePartitionImpl::ClearDataImpl(
net::URLRequestContextGetter* rq_context,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) {
+ base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DataDeletionHelper* helper = new DataDeletionHelper(remove_mask,
- quota_storage_remove_mask,
- callback);
+ DataDeletionHelper* helper = new DataDeletionHelper(
+ remove_mask, quota_storage_remove_mask, std::move(callback));
// |helper| deletes itself when done in
// DataDeletionHelper::DecrementTaskCountOnUI().
helper->ClearDataOnUIThread(
@@ -851,7 +863,7 @@ void StoragePartitionImpl::DataDeletionHelper::DecrementTaskCountOnUI() {
DCHECK_GT(task_count, 0);
--task_count;
if (!task_count) {
- callback.Run();
+ std::move(callback).Run();
delete this;
}
}
@@ -945,13 +957,12 @@ void StoragePartitionImpl::ClearDataForOrigin(
uint32_t remove_mask,
uint32_t quota_storage_remove_mask,
const GURL& storage_origin,
- net::URLRequestContextGetter* request_context_getter,
- const base::Closure& callback) {
+ net::URLRequestContextGetter* request_context_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
ClearDataImpl(remove_mask, quota_storage_remove_mask, storage_origin,
OriginMatcherFunction(), CookieMatcherFunction(),
request_context_getter, base::Time(), base::Time::Max(),
- callback);
+ base::Bind(&base::DoNothing));
}
void StoragePartitionImpl::ClearData(
@@ -961,10 +972,10 @@ void StoragePartitionImpl::ClearData(
const OriginMatcherFunction& origin_matcher,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) {
+ base::OnceClosure callback) {
ClearDataImpl(remove_mask, quota_storage_remove_mask, storage_origin,
origin_matcher, CookieMatcherFunction(), GetURLRequestContext(),
- begin, end, callback);
+ begin, end, std::move(callback));
}
void StoragePartitionImpl::ClearData(
@@ -974,24 +985,25 @@ void StoragePartitionImpl::ClearData(
const CookieMatcherFunction& cookie_matcher,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) {
+ base::OnceClosure callback) {
ClearDataImpl(remove_mask, quota_storage_remove_mask, GURL(), origin_matcher,
- cookie_matcher, GetURLRequestContext(), begin, end, callback);
+ cookie_matcher, GetURLRequestContext(), begin, end,
+ std::move(callback));
}
void StoragePartitionImpl::ClearHttpAndMediaCaches(
const base::Time begin,
const base::Time end,
const base::Callback<bool(const GURL&)>& url_matcher,
- const base::Closure& callback) {
+ base::OnceClosure callback) {
// StoragePartitionHttpCacheDataRemover deletes itself when it is done.
if (url_matcher.is_null()) {
StoragePartitionHttpCacheDataRemover::CreateForRange(this, begin, end)
- ->Remove(callback);
+ ->Remove(std::move(callback));
} else {
StoragePartitionHttpCacheDataRemover::CreateForURLsAndRange(
this, url_matcher, begin, end)
- ->Remove(callback);
+ ->Remove(std::move(callback));
}
}
@@ -1005,6 +1017,11 @@ void StoragePartitionImpl::ClearBluetoothAllowedDevicesMapForTesting() {
bluetooth_allowed_devices_map_->Clear();
}
+void StoragePartitionImpl::SetNetworkFactoryForTesting(
+ mojom::URLLoaderFactory* test_factory) {
+ url_loader_factory_getter_->SetNetworkFactoryForTesting(test_factory);
+}
+
BrowserContext* StoragePartitionImpl::browser_context() const {
return browser_context_;
}
diff --git a/chromium/content/browser/storage_partition_impl.h b/chromium/content/browser/storage_partition_impl.h
index 6e62286f3f0..54818f596e4 100644
--- a/chromium/content/browser/storage_partition_impl.h
+++ b/chromium/content/browser/storage_partition_impl.h
@@ -91,33 +91,34 @@ class CONTENT_EXPORT StoragePartitionImpl
ZoomLevelDelegate* GetZoomLevelDelegate() override;
#endif // !defined(OS_ANDROID)
PlatformNotificationContextImpl* GetPlatformNotificationContext() override;
- void ClearDataForOrigin(uint32_t remove_mask,
- uint32_t quota_storage_remove_mask,
- const GURL& storage_origin,
- net::URLRequestContextGetter* request_context_getter,
- const base::Closure& callback) override;
+ void ClearDataForOrigin(
+ uint32_t remove_mask,
+ uint32_t quota_storage_remove_mask,
+ const GURL& storage_origin,
+ net::URLRequestContextGetter* request_context_getter) override;
void ClearData(uint32_t remove_mask,
uint32_t quota_storage_remove_mask,
const GURL& storage_origin,
const OriginMatcherFunction& origin_matcher,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) override;
+ base::OnceClosure callback) override;
void ClearData(uint32_t remove_mask,
uint32_t quota_storage_remove_mask,
const OriginMatcherFunction& origin_matcher,
const CookieMatcherFunction& cookie_matcher,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) override;
+ base::OnceClosure callback) override;
void ClearHttpAndMediaCaches(
const base::Time begin,
const base::Time end,
const base::Callback<bool(const GURL&)>& url_matcher,
- const base::Closure& callback) override;
+ base::OnceClosure callback) override;
void Flush() override;
void ClearBluetoothAllowedDevicesMapForTesting() override;
-
+ void SetNetworkFactoryForTesting(
+ mojom::URLLoaderFactory* test_factory) override;
BackgroundFetchContext* GetBackgroundFetchContext();
BackgroundSyncContext* GetBackgroundSyncContext();
PaymentAppContextImpl* GetPaymentAppContext();
@@ -130,6 +131,10 @@ class CONTENT_EXPORT StoragePartitionImpl
void OpenLocalStorage(
const url::Origin& origin,
mojo::InterfaceRequest<mojom::LevelDBWrapper> request) override;
+ void OpenSessionStorage(
+ int64_t namespace_id,
+ const url::Origin& origin,
+ mojo::InterfaceRequest<mojom::LevelDBWrapper> request) override;
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter() {
return url_loader_factory_getter_;
@@ -213,7 +218,7 @@ class CONTENT_EXPORT StoragePartitionImpl
net::URLRequestContextGetter* rq_context,
const base::Time begin,
const base::Time end,
- const base::Closure& callback);
+ base::OnceClosure callback);
// Used by StoragePartitionImplMap.
//
diff --git a/chromium/content/browser/storage_partition_impl_map.cc b/chromium/content/browser/storage_partition_impl_map.cc
index c2ead6db1e6..972dcb3d022 100644
--- a/chromium/content/browser/storage_partition_impl_map.cc
+++ b/chromium/content/browser/storage_partition_impl_map.cc
@@ -30,7 +30,6 @@
#include "content/browser/fileapi/browser_file_system_helper.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/resource_context_impl.h"
-#include "content/browser/service_worker/foreign_fetch_request_handler.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/streams/stream.h"
@@ -64,11 +63,9 @@ namespace {
class BlobProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
public:
BlobProtocolHandler(ChromeBlobStorageContext* blob_storage_context,
- StreamContext* stream_context,
- storage::FileSystemContext* file_system_context)
+ StreamContext* stream_context)
: blob_storage_context_(blob_storage_context),
- stream_context_(stream_context),
- file_system_context_(file_system_context) {}
+ stream_context_(stream_context) {}
~BlobProtocolHandler() override {}
@@ -84,8 +81,8 @@ class BlobProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
// Construction is deferred because 'this' is constructed on
// the main thread but we want blob_protocol_handler_ constructed
// on the IO thread.
- blob_protocol_handler_.reset(new storage::BlobProtocolHandler(
- blob_storage_context_->context(), file_system_context_.get()));
+ blob_protocol_handler_.reset(
+ new storage::BlobProtocolHandler(blob_storage_context_->context()));
}
return blob_protocol_handler_->MaybeCreateJob(request, network_delegate);
}
@@ -93,7 +90,6 @@ class BlobProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
private:
const scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
const scoped_refptr<StreamContext> stream_context_;
- const scoped_refptr<storage::FileSystemContext> file_system_context_;
mutable std::unique_ptr<storage::BlobProtocolHandler> blob_protocol_handler_;
DISALLOW_COPY_AND_ASSIGN(BlobProtocolHandler);
};
@@ -408,9 +404,7 @@ StoragePartitionImpl* StoragePartitionImplMap::Get(
ProtocolHandlerMap protocol_handlers;
protocol_handlers[url::kBlobScheme] =
linked_ptr<net::URLRequestJobFactory::ProtocolHandler>(
- new BlobProtocolHandler(blob_storage_context,
- stream_context,
- partition->GetFileSystemContext()));
+ new BlobProtocolHandler(blob_storage_context, stream_context));
protocol_handlers[url::kFileSystemScheme] =
linked_ptr<net::URLRequestJobFactory::ProtocolHandler>(
CreateFileSystemProtocolHandler(partition_domain,
@@ -425,15 +419,10 @@ StoragePartitionImpl* StoragePartitionImplMap::Get(
URLRequestInterceptorScopedVector request_interceptors;
request_interceptors.push_back(
- base::MakeUnique<DevToolsURLRequestInterceptor>(browser_context_));
+ std::make_unique<DevToolsURLRequestInterceptor>(browser_context_));
request_interceptors.push_back(ServiceWorkerRequestHandler::CreateInterceptor(
browser_context_->GetResourceContext()));
- if (ForeignFetchRequestHandler::IsForeignFetchEnabled()) {
- request_interceptors.push_back(
- ForeignFetchRequestHandler::CreateInterceptor(
- browser_context_->GetResourceContext()));
- }
- request_interceptors.push_back(base::MakeUnique<AppCacheInterceptor>());
+ request_interceptors.push_back(std::make_unique<AppCacheInterceptor>());
// These calls must happen after StoragePartitionImpl::Create().
if (partition_domain.empty()) {
diff --git a/chromium/content/browser/storage_partition_impl_unittest.cc b/chromium/content/browser/storage_partition_impl_unittest.cc
index 03d64edc2e2..24ef1bf6cd7 100644
--- a/chromium/content/browser/storage_partition_impl_unittest.cc
+++ b/chromium/content/browser/storage_partition_impl_unittest.cc
@@ -23,7 +23,7 @@
#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/test/mock_leveldb_database.h"
+#include "content/test/fake_leveldb_database.h"
#include "net/base/test_completion_callback.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_store.h"
@@ -177,7 +177,7 @@ class RemoveCookieTester {
class RemoveLocalStorageTester {
public:
explicit RemoveLocalStorageTester(TestBrowserContext* profile)
- : dom_storage_context_(NULL),
+ : dom_storage_context_(nullptr),
mock_db_(&mock_data_),
db_binding_(&mock_db_) {
dom_storage_context_ =
@@ -201,7 +201,7 @@ class RemoveLocalStorageTester {
// stores data in the database.
leveldb::mojom::LevelDBDatabaseAssociatedPtr database_ptr;
leveldb::mojom::LevelDBDatabaseAssociatedRequest request =
- MakeIsolatedRequest(&database_ptr);
+ MakeRequestAssociatedWithDedicatedPipe(&database_ptr);
static_cast<DOMStorageContextWrapper*>(dom_storage_context_)
->SetLocalStorageDatabaseForTesting(std::move(database_ptr));
db_binding_.Bind(std::move(request));
@@ -211,21 +211,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(kOrigin1))] =
+ mock_data_[CreateMetaDataKey(url::Origin::Create(kOrigin1))] =
leveldb::StdStringToUint8Vector(data.SerializeAsString());
- mock_data_[CreateDataKey(url::Origin(kOrigin1))] = {};
+ mock_data_[CreateDataKey(url::Origin::Create(kOrigin1))] = {};
base::Time one_day_ago = now - base::TimeDelta::FromDays(1);
data.set_last_modified(one_day_ago.ToInternalValue());
- mock_data_[CreateMetaDataKey(url::Origin(kOrigin2))] =
+ mock_data_[CreateMetaDataKey(url::Origin::Create(kOrigin2))] =
leveldb::StdStringToUint8Vector(data.SerializeAsString());
- mock_data_[CreateDataKey(url::Origin(kOrigin2))] = {};
+ mock_data_[CreateDataKey(url::Origin::Create(kOrigin2))] = {};
base::Time sixty_days_ago = now - base::TimeDelta::FromDays(60);
data.set_last_modified(sixty_days_ago.ToInternalValue());
- mock_data_[CreateMetaDataKey(url::Origin(kOrigin3))] =
+ mock_data_[CreateMetaDataKey(url::Origin::Create(kOrigin3))] =
leveldb::StdStringToUint8Vector(data.SerializeAsString());
- mock_data_[CreateDataKey(url::Origin(kOrigin3))] = {};
+ mock_data_[CreateDataKey(url::Origin::Create(kOrigin3))] = {};
}
private:
@@ -266,7 +266,7 @@ class RemoveLocalStorageTester {
content::DOMStorageContext* dom_storage_context_;
std::map<std::vector<uint8_t>, std::vector<uint8_t>> mock_data_;
- MockLevelDBDatabase mock_db_;
+ FakeLevelDBDatabase mock_db_;
mojo::AssociatedBinding<leveldb::mojom::LevelDBDatabase> db_binding_;
std::vector<content::LocalStorageUsageInfo> infos_;
@@ -335,7 +335,7 @@ class RemovePluginPrivateDataTester {
filesystem_context_->GetAsyncFileUtil(
storage::kFileSystemTypePluginPrivate);
std::unique_ptr<storage::FileSystemOperationContext> operation_context =
- base::MakeUnique<storage::FileSystemOperationContext>(
+ std::make_unique<storage::FileSystemOperationContext>(
filesystem_context_);
async_file_util->CreateOrOpen(
std::move(operation_context), clearkey_file_,
@@ -381,7 +381,7 @@ class RemovePluginPrivateDataTester {
storage::AsyncFileUtil* file_util = filesystem_context_->GetAsyncFileUtil(
storage::kFileSystemTypePluginPrivate);
std::unique_ptr<storage::FileSystemOperationContext> operation_context =
- base::MakeUnique<storage::FileSystemOperationContext>(
+ std::make_unique<storage::FileSystemOperationContext>(
filesystem_context_);
operation_context->set_allowed_bytes_growth(
storage::QuotaManager::kNoLimit);
@@ -398,7 +398,7 @@ class RemovePluginPrivateDataTester {
storage::AsyncFileUtil* file_util = filesystem_context_->GetAsyncFileUtil(
storage::kFileSystemTypePluginPrivate);
std::unique_ptr<storage::FileSystemOperationContext> operation_context =
- base::MakeUnique<storage::FileSystemOperationContext>(
+ std::make_unique<storage::FileSystemOperationContext>(
filesystem_context_);
file_util->DeleteFile(
std::move(operation_context), file_url,
@@ -415,7 +415,7 @@ class RemovePluginPrivateDataTester {
storage::AsyncFileUtil* file_util = filesystem_context_->GetAsyncFileUtil(
storage::kFileSystemTypePluginPrivate);
std::unique_ptr<storage::FileSystemOperationContext> operation_context =
- base::MakeUnique<storage::FileSystemOperationContext>(
+ std::make_unique<storage::FileSystemOperationContext>(
filesystem_context_);
file_util->Touch(std::move(operation_context), file_url, time_stamp,
time_stamp,
@@ -664,7 +664,7 @@ class StoragePartitionShaderClearTest : public testing::Test {
}
~StoragePartitionShaderClearTest() override {
- cache_ = NULL;
+ cache_ = nullptr;
GetShaderCacheFactorySingleton()->RemoveCacheInfo(kDefaultClientId);
}
diff --git a/chromium/content/browser/streams/stream.cc b/chromium/content/browser/streams/stream.cc
index 7c0bc8a930a..5cb066a5ac3 100644
--- a/chromium/content/browser/streams/stream.cc
+++ b/chromium/content/browser/streams/stream.cc
@@ -10,6 +10,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "content/browser/streams/stream_handle_impl.h"
+#include "content/browser/streams/stream_metadata.h"
#include "content/browser/streams/stream_read_observer.h"
#include "content/browser/streams/stream_registry.h"
#include "content/browser/streams/stream_write_observer.h"
@@ -32,9 +33,9 @@ Stream::Stream(StreamRegistry* registry,
data_bytes_read_(0),
last_total_buffered_bytes_(0),
registry_(registry),
- read_observer_(NULL),
+ read_observer_(nullptr),
write_observer_(write_observer),
- stream_handle_(NULL),
+ stream_handle_(nullptr),
weak_ptr_factory_(this) {
CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get(), kDeferSizeThreshold,
@@ -61,12 +62,12 @@ bool Stream::SetReadObserver(StreamReadObserver* observer) {
void Stream::RemoveReadObserver(StreamReadObserver* observer) {
DCHECK(observer == read_observer_);
- read_observer_ = NULL;
+ read_observer_ = nullptr;
}
void Stream::RemoveWriteObserver(StreamWriteObserver* observer) {
DCHECK(observer == write_observer_);
- write_observer_ = NULL;
+ write_observer_ = nullptr;
}
void Stream::Abort() {
@@ -84,6 +85,24 @@ void Stream::Abort() {
base::BindOnce(&Stream::OnDataAvailable, weak_ptr_factory_.GetWeakPtr()));
}
+void Stream::OnResponseStarted(const net::HttpResponseInfo& response_info) {
+ DCHECK(!metadata_);
+ if (response_info.headers) {
+ metadata_.reset(new StreamMetadata(response_info));
+ return;
+ }
+ // Assume request wasn't backed by HTTP and produce fake "200 OK" response,
+ // as some consumers expect it for, say, data urls.
+ net::HttpResponseInfo fake_response_info = response_info;
+ fake_response_info.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
+ metadata_ = std::make_unique<StreamMetadata>(fake_response_info);
+}
+
+void Stream::UpdateNetworkStats(int64_t raw_body_bytes, int64_t total_bytes) {
+ metadata_->set_raw_body_bytes(raw_body_bytes);
+ metadata_->set_total_received_bytes(total_bytes);
+}
+
void Stream::AddData(scoped_refptr<net::IOBuffer> buffer, size_t size) {
if (!writer_.get())
return;
@@ -181,7 +200,7 @@ void Stream::CloseHandle() {
scoped_refptr<Stream> ref(this);
CHECK(stream_handle_);
- stream_handle_ = NULL;
+ stream_handle_ = nullptr;
registry_->UnregisterStream(url());
if (write_observer_)
write_observer_->OnClose(this);
@@ -203,7 +222,7 @@ void Stream::OnDataAvailable() {
}
void Stream::ClearBuffer() {
- data_ = NULL;
+ data_ = nullptr;
data_length_ = 0;
data_bytes_read_ = 0;
}
diff --git a/chromium/content/browser/streams/stream.h b/chromium/content/browser/streams/stream.h
index 44f9a8f53d8..c46963b9fe4 100644
--- a/chromium/content/browser/streams/stream.h
+++ b/chromium/content/browser/streams/stream.h
@@ -15,6 +15,7 @@
#include "url/gurl.h"
namespace net {
+class HttpResponseInfo;
class IOBuffer;
}
@@ -22,6 +23,7 @@ namespace content {
class StreamHandle;
class StreamHandleImpl;
+class StreamMetadata;
class StreamReadObserver;
class StreamRegistry;
class StreamWriteObserver;
@@ -64,6 +66,13 @@ class CONTENT_EXPORT Stream : public base::RefCountedThreadSafe<Stream> {
// |registry_| and make coming ReadRawData() calls return STREAM_ABORTED.
void Abort();
+ // Passes HTTP response information associated with the response body
+ // transferred through this.
+ void OnResponseStarted(const net::HttpResponseInfo& response_info);
+
+ // Updates actual counts of bytes transferred by the network.
+ void UpdateNetworkStats(int64_t raw_body_bytes, int64_t total_bytes);
+
// Adds the data in |buffer| to the stream. Takes ownership of |buffer|.
void AddData(scoped_refptr<net::IOBuffer> buffer, size_t size);
// Adds data of |size| at |data| to the stream. This method creates a copy
@@ -99,6 +108,8 @@ class CONTENT_EXPORT Stream : public base::RefCountedThreadSafe<Stream> {
return last_total_buffered_bytes_;
}
+ StreamMetadata* metadata() const { return metadata_.get(); }
+
private:
friend class base::RefCountedThreadSafe<Stream>;
@@ -135,6 +146,7 @@ class CONTENT_EXPORT Stream : public base::RefCountedThreadSafe<Stream> {
StreamWriteObserver* write_observer_;
StreamHandleImpl* stream_handle_;
+ std::unique_ptr<StreamMetadata> metadata_;
base::WeakPtrFactory<Stream> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(Stream);
diff --git a/chromium/content/browser/streams/stream_context.cc b/chromium/content/browser/streams/stream_context.cc
index b23d083c734..7aafca3aafc 100644
--- a/chromium/content/browser/streams/stream_context.cc
+++ b/chromium/content/browser/streams/stream_context.cc
@@ -27,7 +27,7 @@ StreamContext* StreamContext::GetFor(BrowserContext* context) {
scoped_refptr<StreamContext> stream = new StreamContext();
context->SetUserData(
kStreamContextKeyName,
- base::MakeUnique<UserDataAdapter<StreamContext>>(stream.get()));
+ std::make_unique<UserDataAdapter<StreamContext>>(stream.get()));
// Check first to avoid memory leak in unittests.
if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
BrowserThread::PostTask(
diff --git a/chromium/content/browser/streams/stream_metadata.h b/chromium/content/browser/streams/stream_metadata.h
new file mode 100644
index 00000000000..a53424acac6
--- /dev/null
+++ b/chromium/content/browser/streams/stream_metadata.h
@@ -0,0 +1,41 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_STREAMS_STREAM_METADATA_H_
+#define CONTENT_BROWSER_STREAMS_STREAM_METADATA_H_
+
+#include "base/macros.h"
+
+#include "net/http/http_response_info.h"
+
+namespace content {
+
+class StreamMetadata {
+ public:
+ explicit StreamMetadata(const net::HttpResponseInfo& response_info)
+ : total_received_bytes_(0),
+ raw_body_bytes_(0),
+ response_info_(response_info) {}
+
+ void set_total_received_bytes(int64_t bytes) {
+ total_received_bytes_ = bytes;
+ }
+ int64_t total_received_bytes() const { return total_received_bytes_; }
+
+ void set_raw_body_bytes(int64_t bytes) { raw_body_bytes_ = bytes; }
+ int64_t raw_body_bytes() const { return raw_body_bytes_; }
+
+ const net::HttpResponseInfo& response_info() const { return response_info_; }
+
+ private:
+ int64_t total_received_bytes_;
+ int64_t raw_body_bytes_;
+ net::HttpResponseInfo response_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(StreamMetadata);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_STREAMS_STREAM_METADATA_H_ \ No newline at end of file
diff --git a/chromium/content/browser/streams/stream_registry.cc b/chromium/content/browser/streams/stream_registry.cc
index b9cba5bc78f..ca6baee32f1 100644
--- a/chromium/content/browser/streams/stream_registry.cc
+++ b/chromium/content/browser/streams/stream_registry.cc
@@ -47,7 +47,7 @@ scoped_refptr<Stream> StreamRegistry::GetStream(const GURL& url) {
if (stream != streams_.end())
return stream->second;
- return NULL;
+ return nullptr;
}
bool StreamRegistry::CloneStream(const GURL& url, const GURL& src_url) {
diff --git a/chromium/content/browser/streams/stream_url_request_job.cc b/chromium/content/browser/streams/stream_url_request_job.cc
index 5c895f431dc..304b9a0fb00 100644
--- a/chromium/content/browser/streams/stream_url_request_job.cc
+++ b/chromium/content/browser/streams/stream_url_request_job.cc
@@ -9,6 +9,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/streams/stream.h"
+#include "content/browser/streams/stream_metadata.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_byte_range.h"
@@ -19,15 +20,14 @@
namespace content {
-StreamURLRequestJob::StreamURLRequestJob(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- scoped_refptr<Stream> stream)
+StreamURLRequestJob::StreamURLRequestJob(net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ scoped_refptr<Stream> stream)
: net::URLRangeRequestJob(request, network_delegate),
stream_(stream),
- headers_set_(false),
pending_buffer_size_(0),
total_bytes_read_(0),
+ raw_body_bytes_(0),
max_range_(0),
request_failed_(false),
error_code_(net::OK),
@@ -70,7 +70,7 @@ void StreamURLRequestJob::OnDataAvailable(Stream* stream) {
// Clear the buffers before notifying the read is complete, so that it is
// safe for the observer to read.
- pending_buffer_ = NULL;
+ pending_buffer_ = nullptr;
pending_buffer_size_ = 0;
if (result > 0)
@@ -110,6 +110,7 @@ int StreamURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
switch (stream_->ReadRawData(buf, to_read, &bytes_read)) {
case Stream::STREAM_HAS_DATA:
total_bytes_read_ += bytes_read;
+ raw_body_bytes_ = stream_->metadata()->raw_body_bytes();
return bytes_read;
case Stream::STREAM_COMPLETE:
return stream_->GetStatus();
@@ -126,32 +127,42 @@ int StreamURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
}
bool StreamURLRequestJob::GetMimeType(std::string* mime_type) const {
- if (!response_info_)
+ const StreamMetadata* metadata = stream_->metadata();
+ if (!metadata || !metadata->response_info().headers)
return false;
// TODO(zork): Support registered MIME types if needed.
- return response_info_->headers->GetMimeType(mime_type);
+ return metadata->response_info().headers->GetMimeType(mime_type);
}
void StreamURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
- if (response_info_)
- *info = *response_info_;
+ if (failed_response_info_) {
+ *info = *failed_response_info_;
+ return;
+ }
+ const StreamMetadata* metadata = stream_->metadata();
+ if (metadata)
+ *info = metadata->response_info();
}
int64_t StreamURLRequestJob::GetTotalReceivedBytes() const {
- int64_t total_received_bytes = 0;
- if (response_info_)
- total_received_bytes = response_info_->headers->raw_headers().size();
- if (stream_.get())
- total_received_bytes += total_bytes_read_;
- return total_received_bytes;
+ if (!stream_)
+ return 0;
+ const StreamMetadata* metadata = stream_->metadata();
+ if (!metadata)
+ return 0;
+ return metadata->total_received_bytes();
+}
+
+int64_t StreamURLRequestJob::prefilter_bytes_read() const {
+ return raw_body_bytes_;
}
void StreamURLRequestJob::DidStart() {
if (range_parse_result() == net::OK && ranges().size() > 0) {
// Only one range is supported, and it must start at the first byte.
if (ranges().size() > 1 || ranges()[0].first_byte_position() != 0) {
- NotifyFailure(net::ERR_METHOD_NOT_SUPPORTED);
+ NotifyMethodNotSupported();
return;
}
@@ -160,42 +171,17 @@ void StreamURLRequestJob::DidStart() {
// This class only supports GET requests.
if (request()->method() != "GET") {
- NotifyFailure(net::ERR_METHOD_NOT_SUPPORTED);
+ NotifyMethodNotSupported();
return;
}
-
- HeadersCompleted(net::HTTP_OK);
+ NotifyHeadersComplete();
}
-void StreamURLRequestJob::NotifyFailure(int error_code) {
+void StreamURLRequestJob::NotifyMethodNotSupported() {
+ const net::HttpStatusCode status_code = net::HTTP_METHOD_NOT_ALLOWED;
request_failed_ = true;
- error_code_ = error_code;
-
- // This method can only be called before headers are set.
- DCHECK(!headers_set_);
+ error_code_ = net::ERR_METHOD_NOT_SUPPORTED;
- // TODO(zork): Share these with BlobURLRequestJob.
- net::HttpStatusCode status_code = net::HTTP_INTERNAL_SERVER_ERROR;
- switch (error_code) {
- case net::ERR_ACCESS_DENIED:
- status_code = net::HTTP_FORBIDDEN;
- break;
- case net::ERR_FILE_NOT_FOUND:
- status_code = net::HTTP_NOT_FOUND;
- break;
- case net::ERR_METHOD_NOT_SUPPORTED:
- status_code = net::HTTP_METHOD_NOT_ALLOWED;
- break;
- case net::ERR_FAILED:
- break;
- default:
- DCHECK(false);
- break;
- }
- HeadersCompleted(status_code);
-}
-
-void StreamURLRequestJob::HeadersCompleted(net::HttpStatusCode status_code) {
std::string status("HTTP/1.1 ");
status.append(base::IntToString(status_code));
status.append(" ");
@@ -203,25 +189,15 @@ void StreamURLRequestJob::HeadersCompleted(net::HttpStatusCode status_code) {
status.append("\0\0", 2);
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
- if (status_code == net::HTTP_OK) {
- std::string content_type_header(net::HttpRequestHeaders::kContentType);
- content_type_header.append(": ");
- content_type_header.append("text/plain");
- headers->AddHeader(content_type_header);
- }
-
- response_info_.reset(new net::HttpResponseInfo());
- response_info_->headers = headers;
-
- headers_set_ = true;
-
+ failed_response_info_.reset(new net::HttpResponseInfo());
+ failed_response_info_->headers = headers;
NotifyHeadersComplete();
}
void StreamURLRequestJob::ClearStream() {
if (stream_.get()) {
stream_->RemoveReadObserver(this);
- stream_ = NULL;
+ stream_ = nullptr;
}
}
diff --git a/chromium/content/browser/streams/stream_url_request_job.h b/chromium/content/browser/streams/stream_url_request_job.h
index 2eafa5f94c5..170bdaf632c 100644
--- a/chromium/content/browser/streams/stream_url_request_job.h
+++ b/chromium/content/browser/streams/stream_url_request_job.h
@@ -34,26 +34,28 @@ class CONTENT_EXPORT StreamURLRequestJob
bool GetMimeType(std::string* mime_type) const override;
void GetResponseInfo(net::HttpResponseInfo* info) override;
int64_t GetTotalReceivedBytes() const override;
+ int64_t prefilter_bytes_read() const override;
protected:
~StreamURLRequestJob() override;
private:
void DidStart();
- void NotifyFailure(int);
- void HeadersCompleted(net::HttpStatusCode status_code);
+ void NotifyMethodNotSupported();
+ void UpdateNetworkBytesRead();
void ClearStream();
scoped_refptr<content::Stream> stream_;
- bool headers_set_;
scoped_refptr<net::IOBuffer> pending_buffer_;
int pending_buffer_size_;
- std::unique_ptr<net::HttpResponseInfo> response_info_;
// Total bytes received for this job.
int total_bytes_read_;
+ int64_t raw_body_bytes_;
+
int max_range_;
bool request_failed_;
+ std::unique_ptr<net::HttpResponseInfo> failed_response_info_;
int error_code_; // Only set if request_failed_.
base::WeakPtrFactory<StreamURLRequestJob> weak_factory_;
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 2301b0d2f40..c4f9e232136 100644
--- a/chromium/content/browser/streams/stream_url_request_job_unittest.cc
+++ b/chromium/content/browser/streams/stream_url_request_job_unittest.cc
@@ -9,6 +9,7 @@
#include "base/run_loop.h"
#include "base/test/test_simple_task_runner.h"
#include "content/browser/streams/stream.h"
+#include "content/browser/streams/stream_metadata.h"
#include "content/browser/streams/stream_registry.h"
#include "content/browser/streams/stream_write_observer.h"
#include "net/base/request_priority.h"
@@ -48,7 +49,7 @@ class StreamURLRequestJobTest : public testing::Test {
scoped_refptr<Stream> stream = registry_->GetStream(request->url());
if (stream.get())
return new StreamURLRequestJob(request, network_delegate, stream);
- return NULL;
+ return nullptr;
}
private:
@@ -61,7 +62,7 @@ class StreamURLRequestJobTest : public testing::Test {
registry_.reset(new StreamRegistry());
url_request_job_factory_.SetProtocolHandler(
- "blob", base::MakeUnique<MockProtocolHandler>(registry_.get()));
+ "blob", std::make_unique<MockProtocolHandler>(registry_.get()));
url_request_context_.set_job_factory(&url_request_job_factory_);
}
@@ -73,6 +74,12 @@ class StreamURLRequestJobTest : public testing::Test {
expected_response);
}
+ std::unique_ptr<net::HttpResponseInfo> BuildResponseInfo() {
+ auto response_info = std::make_unique<net::HttpResponseInfo>();
+ response_info->headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
+ return response_info;
+ }
+
void TestRequest(const std::string& method,
const GURL& url,
const net::HttpRequestHeaders& extra_headers,
@@ -111,7 +118,8 @@ class StreamURLRequestJobTest : public testing::Test {
TEST_F(StreamURLRequestJobTest, TestGetSimpleDataRequest) {
scoped_refptr<Stream> stream(
- new Stream(registry_.get(), NULL, kStreamURL));
+ new Stream(registry_.get(), nullptr, kStreamURL));
+ stream->OnResponseStarted(*BuildResponseInfo());
scoped_refptr<net::StringIOBuffer> buffer(
new net::StringIOBuffer(kTestData1));
@@ -124,7 +132,8 @@ TEST_F(StreamURLRequestJobTest, TestGetSimpleDataRequest) {
TEST_F(StreamURLRequestJobTest, TestGetLargeStreamRequest) {
scoped_refptr<Stream> stream(
- new Stream(registry_.get(), NULL, kStreamURL));
+ new Stream(registry_.get(), nullptr, kStreamURL));
+ stream->OnResponseStarted(*BuildResponseInfo());
std::string large_data;
large_data.reserve(kBufferSize * 5);
@@ -155,7 +164,8 @@ TEST_F(StreamURLRequestJobTest, TestGetNonExistentStreamRequest) {
TEST_F(StreamURLRequestJobTest, TestRangeDataRequest) {
scoped_refptr<Stream> stream(
- new Stream(registry_.get(), NULL, kStreamURL));
+ new Stream(registry_.get(), nullptr, kStreamURL));
+ stream->OnResponseStarted(*BuildResponseInfo());
scoped_refptr<net::StringIOBuffer> buffer(
new net::StringIOBuffer(kTestData2));
@@ -172,8 +182,8 @@ TEST_F(StreamURLRequestJobTest, TestRangeDataRequest) {
TEST_F(StreamURLRequestJobTest, TestInvalidRangeDataRequest) {
scoped_refptr<Stream> stream(
- new Stream(registry_.get(), NULL, kStreamURL));
-
+ new Stream(registry_.get(), nullptr, kStreamURL));
+ stream->OnResponseStarted(*BuildResponseInfo());
scoped_refptr<net::StringIOBuffer> buffer(
new net::StringIOBuffer(kTestData2));
diff --git a/chromium/content/browser/top_document_isolation_browsertest.cc b/chromium/content/browser/top_document_isolation_browsertest.cc
index be1fa6e4565..cedc2f9c64c 100644
--- a/chromium/content/browser/top_document_isolation_browsertest.cc
+++ b/chromium/content/browser/top_document_isolation_browsertest.cc
@@ -187,11 +187,11 @@ IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, NavigateToSubframeSite) {
NavigateToURL(shell(), ba_url);
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/",
+ " 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()));
}
diff --git a/chromium/content/browser/tracing/background_memory_tracing_observer.cc b/chromium/content/browser/tracing/background_memory_tracing_observer.cc
index 36f8f7b1d9e..f3dd9e3cd08 100644
--- a/chromium/content/browser/tracing/background_memory_tracing_observer.cc
+++ b/chromium/content/browser/tracing/background_memory_tracing_observer.cc
@@ -20,13 +20,6 @@ namespace {
const char kEnableHeapProfilerModeName[] = "enable_heap_profiler_mode";
const char kBackgroundModeName[] = "background";
const char kHeapProfilerCategoryFilter[] = "heap_profiler_category_filter";
-
-void GlobalDumpCallback(bool success, uint64_t guid) {
- // Disable heap profiling after capturing the first memory dump.
- MemoryDumpManager::GetInstance()->EnableHeapProfiling(
- base::trace_event::kHeapProfilingModeDisabled);
- TraceLog::GetInstance()->SetDisabled(TraceLog::FILTERING_MODE);
-}
} // namespace
// static
@@ -106,14 +99,12 @@ void BackgroundMemoryTracingObserver::OnTracingEnabled(
BackgroundTracingConfigImpl::CategoryPreset::BENCHMARK_MEMORY_LIGHT)
return;
- memory_instrumentation::MemoryInstrumentation::
- RequestGlobalDumpAndAppendToTraceCallback callback;
- if (heap_profiling_enabled_)
- callback = base::Bind(&GlobalDumpCallback);
memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDumpAndAppendToTrace(
base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED,
- base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND, callback);
+ base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND,
+ memory_instrumentation::MemoryInstrumentation::
+ RequestGlobalMemoryDumpAndAppendToTraceCallback());
}
} // namespace content
diff --git a/chromium/content/browser/tracing/background_memory_tracing_observer_unittest.cc b/chromium/content/browser/tracing/background_memory_tracing_observer_unittest.cc
index 20c1615e857..013da3852db 100644
--- a/chromium/content/browser/tracing/background_memory_tracing_observer_unittest.cc
+++ b/chromium/content/browser/tracing/background_memory_tracing_observer_unittest.cc
@@ -4,6 +4,7 @@
#include "content/browser/tracing/background_memory_tracing_observer.h"
+#include "base/allocator/features.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/message_loop/message_loop.h"
@@ -11,6 +12,7 @@
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/memory_dump_manager_test_utils.h"
#include "base/trace_event/trace_log.h"
+#include "build/build_config.h"
#include "content/browser/tracing/background_tracing_config_impl.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -28,7 +30,7 @@ std::unique_ptr<BackgroundTracingConfigImpl> ReadFromJSONString(
const std::string& json_text) {
std::unique_ptr<base::Value> json_value(base::JSONReader::Read(json_text));
- base::DictionaryValue* dict = NULL;
+ base::DictionaryValue* dict = nullptr;
if (json_value)
json_value->GetAsDictionary(&dict);
@@ -104,8 +106,6 @@ TEST_F(BackgroundMemoryTracingObserverTest, OnlyBackgroundDumpConfig) {
AllocationContextTracker::capture_mode());
}
-// TODO(ssid): Fix these tests to work with builds without allocator shim
-// (asan).
TEST_F(BackgroundMemoryTracingObserverTest, DISABLED_HeapProfilingConfig) {
auto* observer = BackgroundMemoryTracingObserver::GetInstance();
auto config = ReadFromJSONString(
@@ -119,8 +119,13 @@ TEST_F(BackgroundMemoryTracingObserverTest, DISABLED_HeapProfilingConfig) {
EXPECT_TRUE(observer->heap_profiling_enabled_for_testing());
observer->OnTracingEnabled(BackgroundTracingConfigImpl::BENCHMARK);
EXPECT_EQ(0u, TraceLog::GetInstance()->enabled_modes());
+#if BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL)
EXPECT_EQ(AllocationContextTracker::CaptureMode::PSEUDO_STACK,
AllocationContextTracker::capture_mode());
+#else
+ EXPECT_EQ(AllocationContextTracker::CaptureMode::DISABLED,
+ AllocationContextTracker::capture_mode());
+#endif
observer->OnScenarioAborted();
EXPECT_FALSE(observer->heap_profiling_enabled_for_testing());
@@ -129,8 +134,6 @@ TEST_F(BackgroundMemoryTracingObserverTest, DISABLED_HeapProfilingConfig) {
AllocationContextTracker::capture_mode());
}
-// TODO(ssid): Fix these tests to work with builds without allocator shim
-// (asan).
TEST_F(BackgroundMemoryTracingObserverTest, DISABLED_HeapProfilingWithFilters) {
auto* observer = BackgroundMemoryTracingObserver::GetInstance();
auto config = ReadFromJSONString(
@@ -143,6 +146,7 @@ TEST_F(BackgroundMemoryTracingObserverTest, DISABLED_HeapProfilingWithFilters) {
observer->OnScenarioActivated(config.get());
EXPECT_TRUE(observer->heap_profiling_enabled_for_testing());
observer->OnTracingEnabled(BackgroundTracingConfigImpl::BENCHMARK);
+#if BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL)
EXPECT_EQ(AllocationContextTracker::CaptureMode::PSEUDO_STACK,
AllocationContextTracker::capture_mode());
EXPECT_EQ(TraceLog::FILTERING_MODE, TraceLog::GetInstance()->enabled_modes());
@@ -156,6 +160,11 @@ TEST_F(BackgroundMemoryTracingObserverTest, DISABLED_HeapProfilingWithFilters) {
std::string filter_str;
base::JSONWriter::Write(filter_dict, &filter_str);
EXPECT_EQ(kExpectedConfig, filter_str);
+#else // BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL)
+ EXPECT_EQ(0u, TraceLog::GetInstance()->enabled_modes());
+ EXPECT_EQ(AllocationContextTracker::CaptureMode::DISABLED,
+ AllocationContextTracker::capture_mode());
+#endif // BUILDFLAG(USE_ALLOCATOR_SHIM) && !defined(OS_NACL)
observer->OnScenarioAborted();
EXPECT_FALSE(observer->heap_profiling_enabled_for_testing());
diff --git a/chromium/content/browser/tracing/background_tracing_config_unittest.cc b/chromium/content/browser/tracing/background_tracing_config_unittest.cc
index dadffb3a095..7124ddff9f0 100644
--- a/chromium/content/browser/tracing/background_tracing_config_unittest.cc
+++ b/chromium/content/browser/tracing/background_tracing_config_unittest.cc
@@ -29,7 +29,7 @@ std::unique_ptr<BackgroundTracingConfigImpl> ReadFromJSONString(
const std::string& json_text) {
std::unique_ptr<base::Value> json_value(base::JSONReader::Read(json_text));
- base::DictionaryValue* dict = NULL;
+ base::DictionaryValue* dict = nullptr;
if (json_value)
json_value->GetAsDictionary(&dict);
diff --git a/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc b/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
index 0c100aeb788..f364552e6fe 100644
--- a/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
+++ b/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
@@ -123,7 +123,7 @@ class BackgroundTracingManagerUploadConfigWrapper {
const size_t kOutputBufferLength = 10 * 1024 * 1024;
std::vector<char> output_str(kOutputBufferLength);
- z_stream stream = {0};
+ z_stream stream = {nullptr};
stream.avail_in = compressed_length;
stream.avail_out = kOutputBufferLength;
stream.next_in = (Bytef*)&file_contents->data()[0];
@@ -224,7 +224,7 @@ void SetupBackgroundTracingManager() {
void DisableScenarioWhenIdle() {
BackgroundTracingManager::GetInstance()->SetActiveScenario(
- NULL, BackgroundTracingManager::ReceiveCallback(),
+ nullptr, BackgroundTracingManager::ReceiveCallback(),
BackgroundTracingManager::NO_DATA_FILTERING);
}
diff --git a/chromium/content/browser/tracing/background_tracing_manager_impl.cc b/chromium/content/browser/tracing/background_tracing_manager_impl.cc
index b59b9bea623..578fb4133dc 100644
--- a/chromium/content/browser/tracing/background_tracing_manager_impl.cc
+++ b/chromium/content/browser/tracing/background_tracing_manager_impl.cc
@@ -552,9 +552,9 @@ BackgroundTracingManagerImpl::GenerateMetadataDict() {
if (!IsAllowedFinalization())
return nullptr;
- auto metadata_dict = base::MakeUnique<base::DictionaryValue>();
+ auto metadata_dict = std::make_unique<base::DictionaryValue>();
if (config_) {
- auto config_dict = base::MakeUnique<base::DictionaryValue>();
+ auto config_dict = std::make_unique<base::DictionaryValue>();
config_->IntoDict(config_dict.get());
metadata_dict->Set("config", std::move(config_dict));
}
diff --git a/chromium/content/browser/tracing/etw_tracing_agent_win.cc b/chromium/content/browser/tracing/etw_tracing_agent_win.cc
index 210a4d02a2b..f39b59d1f24 100644
--- a/chromium/content/browser/tracing/etw_tracing_agent_win.cc
+++ b/chromium/content/browser/tracing/etw_tracing_agent_win.cc
@@ -199,7 +199,7 @@ void EtwTracingAgent::AddSyncEventToBuffer() {
now_in_us.QuadPart = now.ToInternalValue();
// Add fields to the event.
- auto value = base::MakeUnique<base::DictionaryValue>();
+ auto value = std::make_unique<base::DictionaryValue>();
value->SetString("guid", "ClockSync");
value->SetString("walltime",
base::StringPrintf("%08lX%08lX", walltime_in_us.HighPart,
@@ -212,7 +212,7 @@ void EtwTracingAgent::AddSyncEventToBuffer() {
}
void EtwTracingAgent::AppendEventToBuffer(EVENT_TRACE* event) {
- auto value = base::MakeUnique<base::DictionaryValue>();
+ auto value = std::make_unique<base::DictionaryValue>();
// Add header fields to the event.
LARGE_INTEGER ts_us;
@@ -255,7 +255,7 @@ void EtwTracingAgent::TraceAndConsumeOnThread() {
void EtwTracingAgent::FlushOnThread() {
// Add the header information to the stream.
- auto header = base::MakeUnique<base::DictionaryValue>();
+ auto header = std::make_unique<base::DictionaryValue>();
header->SetString("name", "ETW");
// Release and pass the events buffer.
diff --git a/chromium/content/browser/tracing/memory_instrumentation_browsertest.cc b/chromium/content/browser/tracing/memory_instrumentation_browsertest.cc
index f9a38746f30..b935015bf63 100644
--- a/chromium/content/browser/tracing/memory_instrumentation_browsertest.cc
+++ b/chromium/content/browser/tracing/memory_instrumentation_browsertest.cc
@@ -83,7 +83,7 @@ IN_PROC_BROWSER_TEST_F(MemoryInstrumentationTest,
GlobalMemoryDumpPtr before_ptr = DoGlobalDump();
- std::unique_ptr<char[]> buffer = base::MakeUnique<char[]>(kAllocSize);
+ std::unique_ptr<char[]> buffer = std::make_unique<char[]>(kAllocSize);
memset(buffer.get(), 1, kAllocSize);
volatile char* x = static_cast<volatile char*>(buffer.get());
EXPECT_EQ(x[0] + x[kAllocSize - 1], 2);
diff --git a/chromium/content/browser/tracing/memory_tracing_browsertest.cc b/chromium/content/browser/tracing/memory_tracing_browsertest.cc
index b55e93e163a..3612d03ef92 100644
--- a/chromium/content/browser/tracing/memory_tracing_browsertest.cc
+++ b/chromium/content/browser/tracing/memory_tracing_browsertest.cc
@@ -76,10 +76,9 @@ class MemoryTracingTest : public ContentBrowserTest {
const MemoryDumpLevelOfDetail& level_of_detail,
const base::Closure& closure) {
uint32_t request_index = next_request_index_++;
- memory_instrumentation::MemoryInstrumentation::
- RequestGlobalDumpAndAppendToTraceCallback callback = base::Bind(
- &MemoryTracingTest::OnGlobalMemoryDumpDone, base::Unretained(this),
- base::ThreadTaskRunnerHandle::Get(), closure, request_index);
+ auto callback = base::Bind(
+ &MemoryTracingTest::OnGlobalMemoryDumpDone, base::Unretained(this),
+ base::ThreadTaskRunnerHandle::Get(), closure, request_index);
if (from_renderer_thread) {
PostTaskToInProcessRendererAndWait(base::Bind(
&memory_instrumentation::MemoryInstrumentation::
@@ -202,10 +201,17 @@ IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest,
DisableTracing();
}
+// https://crbug.com/788788
+#if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
+#define MAYBE_RendererInitiatedSingleDump DISABLED_RendererInitiatedSingleDump
+#else
+#define MAYBE_RendererInitiatedSingleDump RendererInitiatedSingleDump
+#endif // defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
+
// Checks that a memory dump initiated from a renderer thread ends up in a
// single dump even in single process mode.
IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest,
- RendererInitiatedSingleDump) {
+ MAYBE_RendererInitiatedSingleDump) {
Navigate(shell());
EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true));
@@ -218,7 +224,14 @@ IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest,
DisableTracing();
}
-IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest, ManyInterleavedDumps) {
+// https://crbug.com/788788
+#if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
+#define MAYBE_ManyInterleavedDumps DISABLED_ManyInterleavedDumps
+#else
+#define MAYBE_ManyInterleavedDumps ManyInterleavedDumps
+#endif // defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
+IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest,
+ MAYBE_ManyInterleavedDumps) {
Navigate(shell());
EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_))
diff --git a/chromium/content/browser/tracing/tracing_controller_browsertest.cc b/chromium/content/browser/tracing/tracing_controller_browsertest.cc
index 66e938e6ab0..a65ee7a8d15 100644
--- a/chromium/content/browser/tracing/tracing_controller_browsertest.cc
+++ b/chromium/content/browser/tracing/tracing_controller_browsertest.cc
@@ -269,7 +269,7 @@ class TracingControllerTest : public ContentBrowserTest {
scoped_refptr<TracingController::TraceDataEndpoint> trace_data_endpoint =
TracingController::CreateStringEndpoint(callback);
- metadata_ = base::MakeUnique<base::DictionaryValue>();
+ metadata_ = std::make_unique<base::DictionaryValue>();
metadata_->SetString("not-whitelisted", "this_not_found");
bool result = controller->StopTracing(trace_data_endpoint);
@@ -379,7 +379,7 @@ IN_PROC_BROWSER_TEST_F(TracingControllerTest, DisableRecordingStoresMetadata) {
TestStartAndStopTracingString();
// Check that a number of important keys exist in the metadata dictionary. The
// values are not checked to ensure the test is robust.
- EXPECT_TRUE(last_metadata() != NULL);
+ EXPECT_TRUE(last_metadata() != nullptr);
std::string network_type;
last_metadata()->GetString("network-type", &network_type);
EXPECT_TRUE(network_type.length() > 0);
@@ -405,7 +405,7 @@ IN_PROC_BROWSER_TEST_F(TracingControllerTest,
DISABLED_NotWhitelistedMetadataStripped) {
TestStartAndStopTracingStringWithFilter();
// Check that a number of important keys exist in the metadata dictionary.
- EXPECT_TRUE(last_metadata() != NULL);
+ EXPECT_TRUE(last_metadata() != nullptr);
std::string cpu_brand;
last_metadata()->GetString("cpu-brand", &cpu_brand);
EXPECT_TRUE(cpu_brand.length() > 0);
diff --git a/chromium/content/browser/tracing/tracing_controller_impl.cc b/chromium/content/browser/tracing/tracing_controller_impl.cc
index 180b1a6de49..1008cd71570 100644
--- a/chromium/content/browser/tracing/tracing_controller_impl.cc
+++ b/chromium/content/browser/tracing/tracing_controller_impl.cc
@@ -22,7 +22,6 @@
#include "base/values.h"
#include "build/build_config.h"
#include "content/browser/tracing/file_tracing_provider_impl.h"
-#include "content/browser/tracing/power_tracing_agent.h"
#include "content/browser/tracing/tracing_ui.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
@@ -108,8 +107,60 @@ std::string GetClockString() {
return std::string();
}
-std::unique_ptr<base::DictionaryValue> GenerateSystemMetadataDict() {
- auto metadata_dict = base::MakeUnique<base::DictionaryValue>();
+} // namespace
+
+TracingController* TracingController::GetInstance() {
+ return TracingControllerImpl::GetInstance();
+}
+
+TracingControllerImpl::TracingControllerImpl()
+ : delegate_(GetContentClient()->browser()->GetTracingDelegate()) {
+ DCHECK(!g_tracing_controller);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Deliberately leaked, like this class.
+ base::FileTracing::SetProvider(new FileTracingProviderImpl);
+ AddAgents();
+ g_tracing_controller = this;
+}
+
+TracingControllerImpl::~TracingControllerImpl() = default;
+
+void TracingControllerImpl::AddAgents() {
+ auto* connector =
+ content::ServiceManagerConnection::GetForProcess()->GetConnector();
+ connector->BindInterface(resource_coordinator::mojom::kServiceName,
+ &coordinator_);
+
+// Register tracing agents.
+#if defined(ENABLE_POWER_TRACING)
+ agents_.push_back(std::make_unique<PowerTracingAgent>(connector));
+#endif
+
+#if defined(OS_CHROMEOS)
+ agents_.push_back(std::make_unique<CrOSTracingAgent>(connector));
+ agents_.push_back(std::make_unique<ArcTracingAgentImpl>(connector));
+#elif defined(OS_WIN)
+ agents_.push_back(std::make_unique<EtwTracingAgent>(connector));
+#endif
+
+ auto chrome_agent =
+ std::make_unique<tracing::ChromeTraceEventAgent>(connector);
+ // For adding general CPU, network, OS, and other system information to the
+ // metadata.
+ chrome_agent->AddMetadataGeneratorFunction(base::BindRepeating(
+ &TracingControllerImpl::GenerateMetadataDict, base::Unretained(this)));
+ if (delegate_) {
+ chrome_agent->AddMetadataGeneratorFunction(
+ base::BindRepeating(&TracingDelegate::GenerateMetadataDict,
+ base::Unretained(delegate_.get())));
+ }
+ agents_.push_back(std::move(chrome_agent));
+}
+
+std::unique_ptr<base::DictionaryValue>
+TracingControllerImpl::GenerateMetadataDict() const {
+ auto metadata_dict = std::make_unique<base::DictionaryValue>();
+ metadata_dict->SetString("trace-config", trace_config_->ToString());
metadata_dict->SetString("network-type", GetNetworkTypeString());
metadata_dict->SetString("product-version", GetContentClient()->GetProduct());
@@ -146,13 +197,7 @@ std::unique_ptr<base::DictionaryValue> GenerateSystemMetadataDict() {
metadata_dict->SetInteger("physical-memory",
base::SysInfo::AmountOfPhysicalMemoryMB());
- std::string cpu_brand = cpu.cpu_brand();
- // Workaround for crbug.com/249713.
- // TODO(oysteine): Remove workaround when bug is fixed.
- size_t null_pos = cpu_brand.find('\0');
- if (null_pos != std::string::npos)
- cpu_brand.erase(null_pos);
- metadata_dict->SetString("cpu-brand", cpu_brand);
+ metadata_dict->SetString("cpu-brand", cpu.cpu_brand());
// GPU
gpu::GPUInfo gpu_info = content::GpuDataManager::GetInstance()->GetGPUInfo();
@@ -188,66 +233,24 @@ std::unique_ptr<base::DictionaryValue> GenerateSystemMetadataDict() {
ctime.hour, ctime.minute, ctime.second);
metadata_dict->SetString("trace-capture-datetime", time_string);
- return metadata_dict;
-}
-
-} // namespace
-
-TracingController* TracingController::GetInstance() {
- return TracingControllerImpl::GetInstance();
-}
-
-TracingControllerImpl::TracingControllerImpl()
- : delegate_(GetContentClient()->browser()->GetTracingDelegate()) {
- DCHECK(!g_tracing_controller);
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // Deliberately leaked, like this class.
- base::FileTracing::SetProvider(new FileTracingProviderImpl);
- AddAgents();
- g_tracing_controller = this;
-}
-
-TracingControllerImpl::~TracingControllerImpl() = default;
-
-void TracingControllerImpl::AddAgents() {
- auto* connector =
- content::ServiceManagerConnection::GetForProcess()->GetConnector();
- connector->BindInterface(resource_coordinator::mojom::kServiceName,
- &coordinator_);
-
-// Register tracing agents.
-#if defined(ENABLE_POWER_TRACING)
- agents_.push_back(base::MakeUnique<PowerTracingAgent>(connector));
-#endif
-
-#if defined(OS_CHROMEOS)
- agents_.push_back(base::MakeUnique<CrOSTracingAgent>(connector));
- agents_.push_back(base::MakeUnique<ArcTracingAgentImpl>(connector));
-#elif defined(OS_WIN)
- agents_.push_back(base::MakeUnique<EtwTracingAgent>(connector));
-#endif
+ // TODO(crbug.com/737049): The central controller doesn't know about
+ // metadata filters, so we temporarily filter here as the controller is
+ // what assembles the full trace data.
+ MetadataFilterPredicate metadata_filter;
+ if (trace_config_->IsArgumentFilterEnabled()) {
+ if (delegate_)
+ metadata_filter = delegate_->GetMetadataFilterPredicate();
+ }
- auto chrome_agent =
- base::MakeUnique<tracing::ChromeTraceEventAgent>(connector);
- // For adding general CPU, network, OS, and other system information to the
- // metadata.
- chrome_agent->AddMetadataGeneratorFunction(
- base::BindRepeating(&GenerateSystemMetadataDict));
- // For adding controller information to the metadata.
- chrome_agent->AddMetadataGeneratorFunction(base::BindRepeating(
- &TracingControllerImpl::GenerateMetadataDict, base::Unretained(this)));
- if (delegate_) {
- chrome_agent->AddMetadataGeneratorFunction(
- base::BindRepeating(&TracingDelegate::GenerateMetadataDict,
- base::Unretained(delegate_.get())));
+ if (!metadata_filter.is_null()) {
+ for (base::DictionaryValue::Iterator it(*metadata_dict); !it.IsAtEnd();
+ it.Advance()) {
+ if (!metadata_filter.Run(it.key())) {
+ metadata_dict->SetString(it.key(), "__stripped__");
+ }
+ }
}
- agents_.push_back(std::move(chrome_agent));
-}
-std::unique_ptr<base::DictionaryValue>
-TracingControllerImpl::GenerateMetadataDict() const {
- auto metadata_dict = base::MakeUnique<base::DictionaryValue>();
- metadata_dict->SetString("trace-config", trace_config_->ToString());
return metadata_dict;
}
@@ -280,8 +283,12 @@ bool TracingControllerImpl::StartTracing(
const base::trace_event::TraceConfig& trace_config,
const StartTracingDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // TODO(chiniforooshan): The actual value should be received by callback and
+ // this function should return void.
+ if (IsTracing())
+ return false;
trace_config_ =
- base::MakeUnique<base::trace_event::TraceConfig>(trace_config);
+ std::make_unique<base::trace_event::TraceConfig>(trace_config);
coordinator_->StartTracing(
trace_config.ToString(),
base::BindRepeating(
@@ -365,7 +372,7 @@ void TracingControllerImpl::OnDataAvailable(const void* data,
if (trace_data_endpoint_) {
const std::string chunk(static_cast<const char*>(data), num_bytes);
trace_data_endpoint_->ReceiveTraceChunk(
- base::MakeUnique<std::string>(chunk));
+ std::make_unique<std::string>(chunk));
}
}
@@ -374,6 +381,7 @@ void TracingControllerImpl::CompleteFlush() {
trace_data_endpoint_->ReceiveTraceFinalContents(
std::move(filtered_metadata_));
}
+ filtered_metadata_.reset(nullptr);
trace_data_endpoint_ = nullptr;
trace_config_ = nullptr;
}
@@ -396,12 +404,12 @@ void TracingControllerImpl::OnMetadataAvailable(
if (metadata_filter.is_null()) {
filtered_metadata_ = std::move(metadata);
} else {
- filtered_metadata_ = base::MakeUnique<base::DictionaryValue>();
+ filtered_metadata_ = std::make_unique<base::DictionaryValue>();
for (base::DictionaryValue::Iterator it(*metadata); !it.IsAtEnd();
it.Advance()) {
if (metadata_filter.Run(it.key())) {
filtered_metadata_->Set(
- it.key(), base::MakeUnique<base::Value>(it.value().Clone()));
+ it.key(), std::make_unique<base::Value>(it.value().Clone()));
} else {
filtered_metadata_->SetString(it.key(), "__stripped__");
}
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 0d4f1d66d12..586f096a446 100644
--- a/chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc
+++ b/chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc
@@ -63,7 +63,7 @@ class FileTraceDataEndpoint : public TracingController::TraceDataEndpoint {
const base::Closure& callback)
: file_path_(trace_file_path),
completion_callback_(callback),
- file_(NULL) {}
+ file_(nullptr) {}
void ReceiveTraceChunk(std::unique_ptr<std::string> chunk) override {
background_task_runner_->PostTask(
@@ -80,7 +80,7 @@ class FileTraceDataEndpoint : public TracingController::TraceDataEndpoint {
}
private:
- ~FileTraceDataEndpoint() override { DCHECK(file_ == NULL); }
+ ~FileTraceDataEndpoint() override { DCHECK(file_ == nullptr); }
void ReceiveTraceChunkOnBlockingThread(std::unique_ptr<std::string> chunk) {
if (!OpenFileIfNeededOnBlockingThread())
@@ -90,10 +90,10 @@ class FileTraceDataEndpoint : public TracingController::TraceDataEndpoint {
bool OpenFileIfNeededOnBlockingThread() {
base::AssertBlockingAllowed();
- if (file_ != NULL)
+ if (file_ != nullptr)
return true;
file_ = base::OpenFile(file_path_, "w");
- if (file_ == NULL) {
+ if (file_ == nullptr) {
LOG(ERROR) << "Failed to open " << file_path_.value();
return false;
}
@@ -103,7 +103,7 @@ class FileTraceDataEndpoint : public TracingController::TraceDataEndpoint {
void CloseOnBlockingThread() {
if (OpenFileIfNeededOnBlockingThread()) {
base::CloseFile(file_);
- file_ = NULL;
+ file_ = nullptr;
}
BrowserThread::PostTask(
@@ -162,7 +162,7 @@ class CompressedTraceDataEndpoint
already_tried_open_ = true;
stream_.reset(new z_stream);
- *stream_ = {0};
+ *stream_ = {nullptr};
stream_->zalloc = Z_NULL;
stream_->zfree = Z_NULL;
stream_->opaque = Z_NULL;
@@ -201,7 +201,7 @@ class CompressedTraceDataEndpoint
int bytes = kChunkSize - stream_->avail_out;
if (bytes) {
std::string compressed(buffer, bytes);
- endpoint_->ReceiveTraceChunk(base::MakeUnique<std::string>(compressed));
+ endpoint_->ReceiveTraceChunk(std::make_unique<std::string>(compressed));
}
} while (stream_->avail_out == 0);
}
diff --git a/chromium/content/browser/tracing/tracing_ui.cc b/chromium/content/browser/tracing/tracing_ui.cc
index 5df94bc8083..c30a376b71c 100644
--- a/chromium/content/browser/tracing/tracing_ui.cc
+++ b/chromium/content/browser/tracing/tracing_ui.cc
@@ -77,7 +77,7 @@ void OnRecordingEnabledAck(const WebUIDataSource::GotDataCallback& callback) {
void OnTraceBufferUsageResult(const WebUIDataSource::GotDataCallback& callback,
float percent_full,
size_t approximate_event_count) {
- std::string str = base::DoubleToString(percent_full);
+ std::string str = base::NumberToString(percent_full);
callback.Run(base::RefCountedString::TakeString(&str));
}
diff --git a/chromium/content/browser/url_loader_factory_getter.cc b/chromium/content/browser/url_loader_factory_getter.cc
index af030c20945..d0f06571d79 100644
--- a/chromium/content/browser/url_loader_factory_getter.cc
+++ b/chromium/content/browser/url_loader_factory_getter.cc
@@ -28,21 +28,20 @@ void URLLoaderFactoryGetter::Initialize(StoragePartitionImpl* partition) {
blob_factory.PassInterface()));
}
-mojom::URLLoaderFactoryPtr* URLLoaderFactoryGetter::GetNetworkFactory() {
+mojom::URLLoaderFactory* URLLoaderFactoryGetter::GetNetworkFactory() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return test_factory_.is_bound() ? &test_factory_ : &network_factory_;
+ return test_factory_ ? test_factory_ : network_factory_.get();
}
-mojom::URLLoaderFactoryPtr* URLLoaderFactoryGetter::GetBlobFactory() {
+mojom::URLLoaderFactory* URLLoaderFactoryGetter::GetBlobFactory() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return &blob_factory_;
+ return blob_factory_.get();
}
void URLLoaderFactoryGetter::SetNetworkFactoryForTesting(
- mojom::URLLoaderFactoryPtr test_factory) {
+ mojom::URLLoaderFactory* test_factory) {
if (content::BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- URLLoaderFactoryGetter::SetTestNetworkFactoryOnIOThread(
- test_factory.PassInterface());
+ URLLoaderFactoryGetter::SetTestNetworkFactoryOnIOThread(test_factory);
} else {
// Since the URLLoaderFactory pointers are bound on the IO thread, and this
// method is called on the UI thread, we are not able to unbind and return
@@ -51,7 +50,7 @@ void URLLoaderFactoryGetter::SetNetworkFactoryForTesting(
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&URLLoaderFactoryGetter::SetTestNetworkFactoryOnIOThread,
- this, test_factory.PassInterface()));
+ this, test_factory));
}
}
@@ -65,8 +64,9 @@ void URLLoaderFactoryGetter::InitializeOnIOThread(
}
void URLLoaderFactoryGetter::SetTestNetworkFactoryOnIOThread(
- mojom::URLLoaderFactoryPtrInfo test_factory) {
- test_factory_.Bind(std::move(test_factory));
+ mojom::URLLoaderFactory* test_factory) {
+ DCHECK(!test_factory_ || !test_factory);
+ test_factory_ = test_factory;
}
} // namespace content
diff --git a/chromium/content/browser/url_loader_factory_getter.h b/chromium/content/browser/url_loader_factory_getter.h
index cee9f47b060..79b6ce1806f 100644
--- a/chromium/content/browser/url_loader_factory_getter.h
+++ b/chromium/content/browser/url_loader_factory_getter.h
@@ -30,17 +30,22 @@ class URLLoaderFactoryGetter
// Called on the IO thread to get the URLLoaderFactory to the network service.
// The pointer shouldn't be cached.
- mojom::URLLoaderFactoryPtr* GetNetworkFactory();
+ mojom::URLLoaderFactory* GetNetworkFactory();
// Called on the IO thread to get the URLLoaderFactory to the blob service.
// The pointer shouldn't be cached.
- CONTENT_EXPORT mojom::URLLoaderFactoryPtr* GetBlobFactory();
+ CONTENT_EXPORT mojom::URLLoaderFactory* GetBlobFactory();
// Overrides the network URLLoaderFactory for subsequent requests. Passing a
// null pointer will restore the default behavior.
// This is called on the UI thread.
CONTENT_EXPORT void SetNetworkFactoryForTesting(
- mojom::URLLoaderFactoryPtr test_factory);
+ mojom::URLLoaderFactory* test_factory);
+
+ CONTENT_EXPORT mojom::URLLoaderFactoryPtr*
+ original_network_factory_for_testing() {
+ return &network_factory_;
+ }
private:
friend class base::DeleteHelper<URLLoaderFactoryGetter>;
@@ -49,13 +54,12 @@ class URLLoaderFactoryGetter
CONTENT_EXPORT ~URLLoaderFactoryGetter();
void InitializeOnIOThread(mojom::URLLoaderFactoryPtrInfo network_factory,
mojom::URLLoaderFactoryPtrInfo blob_factory);
- void SetTestNetworkFactoryOnIOThread(
- mojom::URLLoaderFactoryPtrInfo test_factory);
+ void SetTestNetworkFactoryOnIOThread(mojom::URLLoaderFactory* test_factory);
// Only accessed on IO thread.
mojom::URLLoaderFactoryPtr network_factory_;
mojom::URLLoaderFactoryPtr blob_factory_;
- mojom::URLLoaderFactoryPtr test_factory_;
+ mojom::URLLoaderFactory* test_factory_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryGetter);
};
diff --git a/chromium/content/browser/utility_process_host_impl.cc b/chromium/content/browser/utility_process_host_impl.cc
index f161b3e26f8..5a617e55ce8 100644
--- a/chromium/content/browser/utility_process_host_impl.cc
+++ b/chromium/content/browser/utility_process_host_impl.cc
@@ -34,6 +34,7 @@
#include "services/service_manager/public/cpp/interface_provider.h"
#include "services/service_manager/sandbox/sandbox_type.h"
#include "ui/base/ui_base_switches.h"
+#include "ui/gl/gl_switches.h"
#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
#include "content/public/browser/zygote_handle_linux.h"
@@ -52,29 +53,37 @@ class UtilitySandboxedProcessLauncherDelegate
public:
UtilitySandboxedProcessLauncherDelegate(
const base::FilePath& exposed_dir,
- bool launch_elevated,
service_manager::SandboxType sandbox_type,
const base::EnvironmentMap& env)
: exposed_dir_(exposed_dir),
-#if defined(OS_WIN)
- launch_elevated_(launch_elevated),
-#elif defined(OS_POSIX)
+#if defined(OS_POSIX)
env_(env),
-#endif // OS_WIN
+#endif
sandbox_type_(sandbox_type) {
- DCHECK(sandbox_type_ == service_manager::SANDBOX_TYPE_NO_SANDBOX ||
- sandbox_type_ == service_manager::SANDBOX_TYPE_UTILITY ||
- sandbox_type_ == service_manager::SANDBOX_TYPE_NETWORK ||
- sandbox_type_ == service_manager::SANDBOX_TYPE_CDM ||
- sandbox_type_ == service_manager::SANDBOX_TYPE_PDF_COMPOSITOR ||
- sandbox_type_ == service_manager::SANDBOX_TYPE_PROFILING ||
- sandbox_type_ == service_manager::SANDBOX_TYPE_PPAPI);
+#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 ||
+#endif
+ sandbox_type_ == service_manager::SANDBOX_TYPE_UTILITY ||
+ sandbox_type_ == service_manager::SANDBOX_TYPE_NETWORK ||
+ sandbox_type_ == service_manager::SANDBOX_TYPE_CDM ||
+ sandbox_type_ == service_manager::SANDBOX_TYPE_PDF_COMPOSITOR ||
+ sandbox_type_ == service_manager::SANDBOX_TYPE_PROFILING ||
+ sandbox_type_ == service_manager::SANDBOX_TYPE_PPAPI;
+ DCHECK(supported_sandbox_type);
+#endif // DCHECK_IS_ON()
}
~UtilitySandboxedProcessLauncherDelegate() override {}
#if defined(OS_WIN)
- bool ShouldLaunchElevated() override { return launch_elevated_; }
+ bool ShouldLaunchElevated() override {
+ return sandbox_type_ ==
+ service_manager::SANDBOX_TYPE_NO_SANDBOX_AND_ELEVATED_PRIVILEGES;
+ }
bool PreSpawnTarget(sandbox::TargetPolicy* policy) override {
if (exposed_dir_.empty())
@@ -99,6 +108,7 @@ class UtilitySandboxedProcessLauncherDelegate
#if !defined(OS_MACOSX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
ZygoteHandle GetZygote() override {
if (service_manager::IsUnsandboxedSandboxType(sandbox_type_) ||
+ sandbox_type_ == service_manager::SANDBOX_TYPE_NETWORK ||
!exposed_dir_.empty()) {
return nullptr;
}
@@ -115,15 +125,13 @@ class UtilitySandboxedProcessLauncherDelegate
private:
base::FilePath exposed_dir_;
-#if defined(OS_WIN)
- bool launch_elevated_;
-#elif defined(OS_POSIX)
+#if defined(OS_POSIX)
base::EnvironmentMap env_;
#endif // OS_WIN
service_manager::SandboxType sandbox_type_;
};
-UtilityMainThreadFactoryFunction g_utility_main_thread_factory = NULL;
+UtilityMainThreadFactoryFunction g_utility_main_thread_factory = nullptr;
UtilityProcessHost* UtilityProcessHost::Create(
const scoped_refptr<UtilityProcessHostClient>& client,
@@ -142,7 +150,6 @@ UtilityProcessHostImpl::UtilityProcessHostImpl(
: client_(client),
client_task_runner_(client_task_runner),
sandbox_type_(service_manager::SANDBOX_TYPE_UTILITY),
- run_elevated_(false),
#if defined(OS_LINUX)
child_flags_(ChildProcessHost::CHILD_ALLOW_SELF),
#else
@@ -180,13 +187,6 @@ void UtilityProcessHostImpl::SetSandboxType(
sandbox_type_ = sandbox_type;
}
-#if defined(OS_WIN)
-void UtilityProcessHostImpl::ElevatePrivileges() {
- sandbox_type_ = service_manager::SANDBOX_TYPE_NO_SANDBOX;
- run_elevated_ = true;
-}
-#endif
-
const ChildProcessData& UtilityProcessHostImpl::GetData() {
return process_->GetData();
}
@@ -251,7 +251,7 @@ bool UtilityProcessHostImpl::StartProcess() {
// As a workaround skip calling it here, since the executable name is
// not needed on Android anyway. See crbug.com/500854.
std::unique_ptr<base::CommandLine> cmd_line =
- base::MakeUnique<base::CommandLine>(base::CommandLine::NO_PROGRAM);
+ std::make_unique<base::CommandLine>(base::CommandLine::NO_PROGRAM);
#else
int child_flags = child_flags_;
@@ -270,7 +270,7 @@ bool UtilityProcessHostImpl::StartProcess() {
}
std::unique_ptr<base::CommandLine> cmd_line =
- base::MakeUnique<base::CommandLine>(exe_path);
+ std::make_unique<base::CommandLine>(exe_path);
#endif
cmd_line->AppendSwitchASCII(switches::kProcessType,
@@ -289,15 +289,28 @@ bool UtilityProcessHostImpl::StartProcess() {
// Browser command-line switches to propagate to the utility process.
static const char* const kSwitchNames[] = {
switches::kHostResolverRules,
+ switches::kIgnoreCertificateErrors,
+ switches::kIgnoreCertificateErrorsSPKIList,
switches::kLogNetLog,
switches::kNoSandbox,
+ switches::kOverrideUseSoftwareGLForTests,
switches::kProxyServer,
#if defined(OS_MACOSX)
switches::kEnableSandboxLogging,
#endif
+#if defined(USE_AURA)
+ switches::kMus,
+#endif
switches::kUseFakeDeviceForMediaStream,
switches::kUseFileForFakeVideoCapture,
+#if defined(OS_WIN)
+ switches::kForceMediaFoundationVideoCapture,
+#endif // defined(OS_WIN)
switches::kUtilityStartupDialog,
+ switches::kUseGL,
+#if defined(OS_ANDROID)
+ switches::kMadviseRandomExecutableCode,
+#endif
};
cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
arraysize(kSwitchNames));
@@ -317,20 +330,14 @@ bool UtilityProcessHostImpl::StartProcess() {
exposed_dir_);
}
-#if defined(OS_WIN)
- // Let the utility process know if it is intended to be elevated.
- if (run_elevated_)
- cmd_line->AppendSwitch(switches::kUtilityProcessRunningElevated);
-#endif
-
const bool is_service = service_identity_.has_value();
if (is_service) {
GetContentClient()->browser()->AdjustUtilityServiceProcessCommandLine(
*service_identity_, cmd_line.get());
}
- process_->Launch(base::MakeUnique<UtilitySandboxedProcessLauncherDelegate>(
- exposed_dir_, run_elevated_, sandbox_type_, env_),
+ process_->Launch(std::make_unique<UtilitySandboxedProcessLauncherDelegate>(
+ exposed_dir_, sandbox_type_, env_),
std::move(cmd_line), true);
}
diff --git a/chromium/content/browser/utility_process_host_impl.h b/chromium/content/browser/utility_process_host_impl.h
index 96d33522abc..8fef04637da 100644
--- a/chromium/content/browser/utility_process_host_impl.h
+++ b/chromium/content/browser/utility_process_host_impl.h
@@ -48,9 +48,6 @@ class CONTENT_EXPORT UtilityProcessHostImpl
bool Send(IPC::Message* message) override;
void SetExposedDir(const base::FilePath& dir) override;
void SetSandboxType(service_manager::SandboxType sandbox_type) override;
-#if defined(OS_WIN)
- void ElevatePrivileges() override;
-#endif
const ChildProcessData& GetData() override;
#if defined(OS_POSIX)
void SetEnv(const base::EnvironmentMap& env) override;
@@ -96,9 +93,6 @@ class CONTENT_EXPORT UtilityProcessHostImpl
// Launch the child process with switches that will setup this sandbox type.
service_manager::SandboxType sandbox_type_;
- // Whether to launch the child process with elevated privileges.
- bool run_elevated_;
-
// ChildProcessHost flags to use when starting the child process.
int child_flags_;
diff --git a/chromium/content/browser/utility_process_host_impl_browsertest.cc b/chromium/content/browser/utility_process_host_impl_browsertest.cc
index 06a18aa2834..280a37d80f0 100644
--- a/chromium/content/browser/utility_process_host_impl_browsertest.cc
+++ b/chromium/content/browser/utility_process_host_impl_browsertest.cc
@@ -33,7 +33,8 @@ class UtilityProcessHostImplBrowserTest : public ContentBrowserTest {
host->SetName(base::ASCIIToUTF16("TestProcess"));
#if defined(OS_WIN)
if (elevated)
- host->ElevatePrivileges();
+ host->SetSandboxType(service_manager::SandboxType::
+ SANDBOX_TYPE_NO_SANDBOX_AND_ELEVATED_PRIVILEGES);
#endif
EXPECT_TRUE(host->Start());
diff --git a/chromium/content/browser/web_contents/aura/OWNERS b/chromium/content/browser/web_contents/aura/OWNERS
index 6e8111fb817..8842bb9529e 100644
--- a/chromium/content/browser/web_contents/aura/OWNERS
+++ b/chromium/content/browser/web_contents/aura/OWNERS
@@ -1,2 +1,2 @@
-mfomitchev@chromium.org
+mohsen@chromium.org
sadrul@chromium.org
diff --git a/chromium/content/browser/web_contents/aura/gesture_nav_simple.cc b/chromium/content/browser/web_contents/aura/gesture_nav_simple.cc
index f2916091104..bfbbff76bd8 100644
--- a/chromium/content/browser/web_contents/aura/gesture_nav_simple.cc
+++ b/chromium/content/browser/web_contents/aura/gesture_nav_simple.cc
@@ -42,7 +42,7 @@ const int kArrowSize = 16;
const SkColor kArrowColor = gfx::kGoogleBlue500;
const float kArrowFullOpacity = 1.f;
const float kArrowInitialOpacity = .3f;
-const float kReloadArrowInitialRotation = -90.f;
+const float kReloadArrowInitialRotation = -180.f;
// The arrow opacity remains constant until progress reaches this threshold,
// then increases quickly as the progress increases beyond the threshold
@@ -110,8 +110,9 @@ NavigationDirection GetDirectionFromMode(OverscrollMode mode) {
return NavigationDirection::NONE;
}
-// Records UMA historgram and also user action for the cancelled overscroll.
-void RecordCancelled(NavigationDirection direction, OverscrollSource source) {
+// Records UMA histogram and also user action for the cancelled overscroll.
+void RecordGestureOverscrollCancelled(NavigationDirection direction,
+ OverscrollSource source) {
DCHECK_NE(direction, NavigationDirection::NONE);
DCHECK_NE(source, OverscrollSource::NONE);
UMA_HISTOGRAM_ENUMERATION("Overscroll.Cancelled3",
@@ -137,7 +138,6 @@ class Arrow : public ui::LayerDelegate {
private:
// ui::LayerDelegate:
void OnPaintLayer(const ui::PaintContext& context) override;
- void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override;
void OnDeviceScaleFactorChanged(float old_device_scale_factor,
float new_device_scale_factor) override;
@@ -184,8 +184,6 @@ void Arrow::OnPaintLayer(const ui::PaintContext& context) {
canvas->DrawImageInt(image, 0, 0);
}
-void Arrow::OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) {}
-
void Arrow::OnDeviceScaleFactorChanged(float old_device_scale_factor,
float new_device_scale_factor) {}
@@ -241,7 +239,6 @@ class Affordance : public ui::LayerDelegate, public gfx::AnimationDelegate {
// ui::LayerDelegate:
void OnPaintLayer(const ui::PaintContext& context) override;
- void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override;
void OnDeviceScaleFactorChanged(float old_device_scale_factor,
float new_device_scale_factor) override;
@@ -325,7 +322,7 @@ void Affordance::Abort() {
state_ = State::ABORTING;
- animation_ = base::MakeUnique<gfx::LinearAnimation>(
+ animation_ = std::make_unique<gfx::LinearAnimation>(
GetAffordanceProgress() * kAbortAnimationDuration,
gfx::LinearAnimation::kDefaultFrameRate, this);
animation_->Start();
@@ -337,7 +334,7 @@ void Affordance::Complete() {
state_ = State::COMPLETING;
- animation_ = base::MakeUnique<gfx::LinearAnimation>(
+ animation_ = std::make_unique<gfx::LinearAnimation>(
kRippleBurstAnimationDuration, gfx::LinearAnimation::kDefaultFrameRate,
this);
animation_->Start();
@@ -377,9 +374,14 @@ void Affordance::UpdatePaintedLayer() {
}
void Affordance::UpdateArrowLayer() {
- const float progress = std::min(1.f, GetAffordanceProgress());
+ const float progress = GetAffordanceProgress();
+ const float capped_progress = std::min(1.f, progress);
gfx::Transform transform;
if (mode_ == OVERSCROLL_SOUTH) {
+ // For pull-to-refresh, the arrow should rotate starting from
+ // |kReloadArrowInitialRotation| until it reaches 0 when |progress| reaches
+ // 1; i.e., activation threshold. The arrow will continue rotation after
+ // activation threshold.
gfx::Vector2dF offset(kArrowSize / 2.f, kArrowSize / 2.f);
transform.Translate(offset);
transform.Rotate(kReloadArrowInitialRotation * (1 - progress));
@@ -387,26 +389,24 @@ void Affordance::UpdateArrowLayer() {
} else {
// Calculate the offset for the arrow relative to its final position.
const float offset =
- (1 - progress) * (-kBackgroundRadius + kArrowSize / 2.f);
+ (1 - capped_progress) * (-kBackgroundRadius + kArrowSize / 2.f);
transform.Translate(
gfx::Vector2dF(mode_ == OVERSCROLL_EAST ? offset : -offset, 0));
}
arrow_.layer()->SetTransform(transform);
- if (mode_ != OVERSCROLL_SOUTH) {
- // The arrow opacity is fixed before progress reaches
- // kArrowOpacityProgressThreshold and after that increases linearly to 1;
- // essentially, making a quick bump at the end.
- float opacity = kArrowInitialOpacity;
- if (progress > kArrowOpacityProgressThreshold) {
- const float max_opacity_bump = kArrowFullOpacity - kArrowInitialOpacity;
- const float opacity_bump_ratio =
- std::min(1.f, (progress - kArrowOpacityProgressThreshold) /
- (1.f - kArrowOpacityProgressThreshold));
- opacity += opacity_bump_ratio * max_opacity_bump;
- }
- arrow_.layer()->SetOpacity(opacity);
+ // The arrow opacity is fixed before progress reaches
+ // kArrowOpacityProgressThreshold and after that increases linearly to 1;
+ // essentially, making a quick bump at the end.
+ float opacity = kArrowInitialOpacity;
+ if (capped_progress > kArrowOpacityProgressThreshold) {
+ const float max_opacity_bump = kArrowFullOpacity - kArrowInitialOpacity;
+ const float opacity_bump_ratio =
+ std::min(1.f, (capped_progress - kArrowOpacityProgressThreshold) /
+ (1.f - kArrowOpacityProgressThreshold));
+ opacity += opacity_bump_ratio * max_opacity_bump;
}
+ arrow_.layer()->SetOpacity(opacity);
}
void Affordance::UpdateLayers() {
@@ -505,8 +505,6 @@ void Affordance::OnPaintLayer(const ui::PaintContext& context) {
canvas->DrawCircle(center_point, kBackgroundRadius, bg_flags);
}
-void Affordance::OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) {}
-
void Affordance::OnDeviceScaleFactorChanged(float old_device_scale_factor,
float new_device_scale_factor) {}
@@ -592,7 +590,8 @@ void GestureNavSimple::OnOverscrollComplete(OverscrollMode overscroll_mode) {
else
RecordAction(base::UserMetricsAction("Overscroll_Navigated.Reload"));
} else {
- RecordCancelled(GetDirectionFromMode(overscroll_mode), overscroll_source);
+ RecordGestureOverscrollCancelled(GetDirectionFromMode(overscroll_mode),
+ overscroll_source);
}
}
@@ -610,7 +609,7 @@ void GestureNavSimple::OnOverscrollModeChange(OverscrollMode old_mode,
!ShouldReload(controller, mode_)) {
// If there is an overscroll in progress - record its cancellation.
if (affordance_ && !affordance_->IsFinishing()) {
- RecordCancelled(GetDirectionFromMode(old_mode), source_);
+ RecordGestureOverscrollCancelled(GetDirectionFromMode(old_mode), source_);
affordance_->Abort();
}
source_ = OverscrollSource::NONE;
@@ -625,26 +624,25 @@ void GestureNavSimple::OnOverscrollModeChange(OverscrollMode old_mode,
GetUmaNavigationType(GetDirectionFromMode(mode_), source_),
UmaNavigationType::NAVIGATION_TYPE_COUNT);
- bool is_vertical = mode_ == OVERSCROLL_SOUTH;
+ const bool is_touchpad = source == OverscrollSource::TOUCHPAD;
const float start_threshold = GetOverscrollConfig(
- is_vertical ? OVERSCROLL_CONFIG_VERT_THRESHOLD_START
- : source == OverscrollSource::TOUCHPAD
- ? OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHPAD
- : OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN);
- const int size =
- is_vertical ? GetDisplaySize().height() : GetDisplaySize().width();
+ is_touchpad ? OverscrollConfig::THRESHOLD_START_TOUCHPAD
+ : OverscrollConfig::THRESHOLD_START_TOUCHSCREEN);
+ const gfx::Size size = GetDisplaySize();
+ const int max_size = std::max(size.width(), size.height());
completion_threshold_ =
- size * GetOverscrollConfig(
- is_vertical ? OVERSCROLL_CONFIG_VERT_THRESHOLD_COMPLETE
- : OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE) -
+ max_size * GetOverscrollConfig(
+ is_touchpad
+ ? OverscrollConfig::THRESHOLD_COMPLETE_TOUCHPAD
+ : OverscrollConfig::THRESHOLD_COMPLETE_TOUCHSCREEN) -
start_threshold;
DCHECK_LE(0, completion_threshold_);
- max_delta_ = size - start_threshold;
+ max_delta_ = max_size - start_threshold;
DCHECK_LE(0, max_delta_);
aura::Window* window = web_contents_->GetNativeView();
- affordance_ = base::MakeUnique<Affordance>(
+ affordance_ = std::make_unique<Affordance>(
this, mode_, window->bounds(), max_delta_ / completion_threshold_);
// Adding the affordance as a child of the content window is not sufficient,
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 427784094dd..dd4de01dc30 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
+++ b/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
@@ -47,8 +47,9 @@ bool DoesEntryMatchURL(NavigationEntry* entry, const GURL& url) {
return false;
}
-// Records UMA historgram and also user action for the cancelled overscroll.
-void RecordCancelled(NavigationDirection direction, OverscrollSource source) {
+// Records UMA histogram and also user action for the cancelled overscroll.
+void RecordNavigationOverscrollCancelled(NavigationDirection direction,
+ OverscrollSource source) {
UMA_HISTOGRAM_ENUMERATION("Overscroll.Cancelled3",
GetUmaNavigationType(direction, source),
NAVIGATION_TYPE_COUNT);
@@ -61,8 +62,7 @@ void RecordCancelled(NavigationDirection direction, OverscrollSource source) {
} // namespace
// Responsible for fading out and deleting the layer of the overlay window.
-class OverlayDismissAnimator
- : public ui::LayerAnimationObserver {
+class OverlayDismissAnimator : public ui::ImplicitAnimationObserver {
public:
// Takes ownership of the layer.
explicit OverlayDismissAnimator(std::unique_ptr<ui::Layer> layer)
@@ -74,29 +74,17 @@ class OverlayDismissAnimator
// the object deletes itself along with the layer.
void Animate() {
DCHECK(layer_.get());
- ui::LayerAnimator* animator = layer_->GetAnimator();
// This makes SetOpacity() animate with default duration (which could be
// zero, e.g. when running tests).
- ui::ScopedLayerAnimationSettings settings(animator);
- animator->AddObserver(this);
+ ui::ScopedLayerAnimationSettings settings(layer_->GetAnimator());
+ settings.AddObserver(this);
layer_->SetOpacity(0);
}
- // Overridden from ui::LayerAnimationObserver
- void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
- delete this;
- }
-
- void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {
- delete this;
- }
-
- void OnLayerAnimationScheduled(
- ui::LayerAnimationSequence* sequence) override {}
+ // ui::ImplicitAnimationObserver:
+ void OnImplicitAnimationsCompleted() override { delete this; }
private:
- ~OverlayDismissAnimator() override {}
-
std::unique_ptr<ui::Layer> layer_;
DISALLOW_COPY_AND_ASSIGN(OverlayDismissAnimator);
@@ -233,7 +221,7 @@ void OverscrollNavigationOverlay::OnOverscrollCompleted(
DCHECK_NE(direction_, NavigationDirection::NONE);
aura::Window* main_window = GetMainWindow();
if (!main_window) {
- RecordCancelled(direction_, owa_->overscroll_source());
+ RecordNavigationOverscrollCancelled(direction_, owa_->overscroll_source());
return;
}
@@ -260,7 +248,7 @@ void OverscrollNavigationOverlay::OnOverscrollCompleted(
} else {
// We need to dismiss the overlay without navigating as soon as the
// overscroll finishes.
- RecordCancelled(direction_, owa_->overscroll_source());
+ RecordNavigationOverscrollCancelled(direction_, owa_->overscroll_source());
loading_complete_ = true;
}
@@ -281,7 +269,7 @@ void OverscrollNavigationOverlay::OnOverscrollCompleted(
}
void OverscrollNavigationOverlay::OnOverscrollCancelled() {
- RecordCancelled(direction_, owa_->overscroll_source());
+ RecordNavigationOverscrollCancelled(direction_, owa_->overscroll_source());
aura::Window* main_window = GetMainWindow();
if (!main_window)
return;
diff --git a/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc b/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
index 33306b7233a..044e12944cb 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
+++ b/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
@@ -496,9 +496,10 @@ TEST_F(OverscrollNavigationOverlayTest, OverlayWindowSwap) {
int overscroll_complete_distance =
root_window()->bounds().size().width() *
content::GetOverscrollConfig(
- content::OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE) +
+ content::OverscrollConfig::THRESHOLD_COMPLETE_TOUCHSCREEN) +
ui::GestureConfiguration::GetInstance()
- ->max_touch_move_in_pixels_for_click() + 1;
+ ->max_touch_move_in_pixels_for_click() +
+ 1;
// Start and complete a back navigation via a gesture.
ui::test::EventGenerator generator(root_window());
diff --git a/chromium/content/browser/web_contents/aura/overscroll_window_delegate.cc b/chromium/content/browser/web_contents/aura/overscroll_window_delegate.cc
index 5f910bc4d6c..075d966fda2 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_window_delegate.cc
+++ b/chromium/content/browser/web_contents/aura/overscroll_window_delegate.cc
@@ -21,12 +21,15 @@ OverscrollWindowDelegate::OverscrollWindowDelegate(
: delegate_(delegate),
overscroll_mode_(OVERSCROLL_NONE),
delta_x_(0.f),
- complete_threshold_ratio_(content::GetOverscrollConfig(
- content::OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE)),
+ complete_threshold_ratio_touchscreen_(content::GetOverscrollConfig(
+ content::OverscrollConfig::THRESHOLD_COMPLETE_TOUCHSCREEN)),
+ complete_threshold_ratio_touchpad_(content::GetOverscrollConfig(
+ content::OverscrollConfig::THRESHOLD_COMPLETE_TOUCHPAD)),
+ active_complete_threshold_ratio_(0.f),
start_threshold_touchscreen_(content::GetOverscrollConfig(
- content::OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN)),
+ content::OverscrollConfig::THRESHOLD_START_TOUCHSCREEN)),
start_threshold_touchpad_(content::GetOverscrollConfig(
- content::OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHPAD)),
+ content::OverscrollConfig::THRESHOLD_START_TOUCHPAD)),
active_start_threshold_(0.f) {
SetImage(image);
}
@@ -55,8 +58,10 @@ void OverscrollWindowDelegate::ResetOverscroll() {
void OverscrollWindowDelegate::CompleteOrResetOverscroll() {
if (overscroll_mode_ == OVERSCROLL_NONE)
return;
- float ratio = (fabs(delta_x_)) / delegate_->GetDisplaySize().width();
- if (ratio < complete_threshold_ratio_) {
+ gfx::Size display_size = delegate_->GetDisplaySize();
+ int max_size = std::max(display_size.width(), display_size.height());
+ float ratio = (fabs(delta_x_)) / max_size;
+ if (ratio < active_complete_threshold_ratio_) {
ResetOverscroll();
return;
}
@@ -94,6 +99,7 @@ void OverscrollWindowDelegate::OnMouseEvent(ui::MouseEvent* event) {
void OverscrollWindowDelegate::OnScrollEvent(ui::ScrollEvent* event) {
active_start_threshold_ = start_threshold_touchpad_;
+ active_complete_threshold_ratio_ = complete_threshold_ratio_touchpad_;
if (event->type() == ui::ET_SCROLL)
UpdateOverscroll(event->x_offset_ordinal(), OverscrollSource::TOUCHPAD);
else if (event->type() == ui::ET_SCROLL_FLING_START)
@@ -105,6 +111,7 @@ void OverscrollWindowDelegate::OnScrollEvent(ui::ScrollEvent* event) {
void OverscrollWindowDelegate::OnGestureEvent(ui::GestureEvent* event) {
active_start_threshold_ = start_threshold_touchscreen_;
+ active_complete_threshold_ratio_ = complete_threshold_ratio_touchscreen_;
switch (event->type()) {
case ui::ET_GESTURE_SCROLL_UPDATE:
UpdateOverscroll(event->details().scroll_x(),
diff --git a/chromium/content/browser/web_contents/aura/overscroll_window_delegate.h b/chromium/content/browser/web_contents/aura/overscroll_window_delegate.h
index f267b851277..7c8ca3333f5 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_window_delegate.h
+++ b/chromium/content/browser/web_contents/aura/overscroll_window_delegate.h
@@ -55,8 +55,14 @@ class CONTENT_EXPORT OverscrollWindowDelegate
// The latest delta_x scroll update.
float delta_x_;
- // The ratio of overscroll at which we consider the overscroll completed.
- const float complete_threshold_ratio_;
+ // The ratio of overscroll at which we consider the overscroll completed, for
+ // touchscreen or touchpad.
+ const float complete_threshold_ratio_touchscreen_;
+ const float complete_threshold_ratio_touchpad_;
+
+ // The ratio of overscroll at which we consider the overscroll completed for
+ // the current touch input.
+ float active_complete_threshold_ratio_;
// The threshold for starting the overscroll gesture, for touchscreen or
// touchpads.
diff --git a/chromium/content/browser/web_contents/aura/overscroll_window_delegate_unittest.cc b/chromium/content/browser/web_contents/aura/overscroll_window_delegate_unittest.cc
index 683a6cb1a3e..6058a7cd6c2 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_window_delegate_unittest.cc
+++ b/chromium/content/browser/web_contents/aura/overscroll_window_delegate_unittest.cc
@@ -30,9 +30,9 @@ class OverscrollWindowDelegateTest : public aura::test::AuraTestBase,
mode_changed_(false),
current_mode_(OVERSCROLL_NONE),
touch_start_threshold_(content::GetOverscrollConfig(
- content::OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN)),
+ OverscrollConfig::THRESHOLD_START_TOUCHSCREEN)),
touch_complete_threshold_(content::GetOverscrollConfig(
- content::OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE)) {}
+ OverscrollConfig::THRESHOLD_COMPLETE_TOUCHSCREEN)) {}
~OverscrollWindowDelegateTest() override {}
diff --git a/chromium/content/browser/web_contents/aura/shadow_layer_delegate.cc b/chromium/content/browser/web_contents/aura/shadow_layer_delegate.cc
index e6c92a30747..9e6119eb9d0 100644
--- a/chromium/content/browser/web_contents/aura/shadow_layer_delegate.cc
+++ b/chromium/content/browser/web_contents/aura/shadow_layer_delegate.cc
@@ -52,10 +52,6 @@ void ShadowLayerDelegate::OnPaintLayer(const ui::PaintContext& context) {
recorder.canvas()->DrawRect(paint_rect, flags);
}
-void ShadowLayerDelegate::OnDelegatedFrameDamage(
- const gfx::Rect& damage_rect_in_dip) {
-}
-
void ShadowLayerDelegate::OnDeviceScaleFactorChanged(
float old_device_scale_factor,
float new_device_scale_factor) {}
diff --git a/chromium/content/browser/web_contents/aura/shadow_layer_delegate.h b/chromium/content/browser/web_contents/aura/shadow_layer_delegate.h
index 6a84d2b7bf5..c93e990bd6f 100644
--- a/chromium/content/browser/web_contents/aura/shadow_layer_delegate.h
+++ b/chromium/content/browser/web_contents/aura/shadow_layer_delegate.h
@@ -31,7 +31,6 @@ class ShadowLayerDelegate : public ui::LayerDelegate {
private:
// Overridden from ui::LayerDelegate:
void OnPaintLayer(const ui::PaintContext& context) override;
- void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override;
void OnDeviceScaleFactorChanged(float old_device_scale_factor,
float new_device_scale_factor) override;
diff --git a/chromium/content/browser/web_contents/opened_by_dom_browsertest.cc b/chromium/content/browser/web_contents/opened_by_dom_browsertest.cc
index 0f506b50b41..9ef6e2ba389 100644
--- a/chromium/content/browser/web_contents/opened_by_dom_browsertest.cc
+++ b/chromium/content/browser/web_contents/opened_by_dom_browsertest.cc
@@ -74,7 +74,7 @@ class OpenedByDOMTest : public ContentBrowserTest {
Shell* OpenWindowFromJavaScript(Shell* shell, const GURL& url) {
// Wait for the popup to be created and for it to have navigated.
ShellAddedObserver new_shell_observer;
- TestNavigationObserver nav_observer(NULL);
+ TestNavigationObserver nav_observer(nullptr);
nav_observer.StartWatchingNewWebContents();
CHECK(ExecuteScript(
shell, base::StringPrintf("window.open('%s')", url.spec().c_str())));
diff --git a/chromium/content/browser/web_contents/web_contents_android.cc b/chromium/content/browser/web_contents/web_contents_android.cc
index e9f632c330f..074ad70caa0 100644
--- a/chromium/content/browser/web_contents/web_contents_android.cc
+++ b/chromium/content/browser/web_contents/web_contents_android.cc
@@ -84,7 +84,7 @@ void SmartClipCallback(const ScopedJavaGlobalRef<jobject>& callback,
Java_WebContentsImpl_onSmartClipDataExtracted(env, jtext, jhtml, callback);
}
-ScopedJavaLocalRef<jobject> CreateJavaAXSnapshot(
+ScopedJavaLocalRef<jobject> JNI_WebContentsImpl_CreateJavaAXSnapshot(
JNIEnv* env,
const ui::AXSnapshotNodeAndroid* node,
bool is_root) {
@@ -106,7 +106,8 @@ ScopedJavaLocalRef<jobject> CreateJavaAXSnapshot(
for (auto& child : node->children) {
Java_WebContentsImpl_addAccessibilityNodeAsChild(
- env, j_node, CreateJavaAXSnapshot(env, child.get(), false));
+ env, j_node,
+ JNI_WebContentsImpl_CreateJavaAXSnapshot(env, child.get(), false));
}
return j_node;
}
@@ -125,7 +126,7 @@ void AXTreeSnapshotCallback(const ScopedJavaGlobalRef<jobject>& callback,
auto snapshot = ui::AXSnapshotNodeAndroid::Create(
result, manager->ShouldExposePasswordText());
ScopedJavaLocalRef<jobject> j_root =
- CreateJavaAXSnapshot(env, snapshot.get(), true);
+ JNI_WebContentsImpl_CreateJavaAXSnapshot(env, snapshot.get(), true);
Java_WebContentsImpl_onAccessibilitySnapshot(env, j_root, callback);
}
@@ -148,9 +149,10 @@ WebContents* WebContents::FromJavaWebContents(
}
// static
-static void DestroyWebContents(JNIEnv* env,
- const JavaParamRef<jclass>& clazz,
- jlong jweb_contents_android_ptr) {
+static void JNI_WebContentsImpl_DestroyWebContents(
+ JNIEnv* env,
+ const JavaParamRef<jclass>& clazz,
+ jlong jweb_contents_android_ptr) {
WebContentsAndroid* web_contents_android =
reinterpret_cast<WebContentsAndroid*>(jweb_contents_android_ptr);
if (!web_contents_android)
@@ -164,9 +166,10 @@ static void DestroyWebContents(JNIEnv* env,
}
// static
-ScopedJavaLocalRef<jobject> FromNativePtr(JNIEnv* env,
- const JavaParamRef<jclass>& clazz,
- jlong web_contents_ptr) {
+ScopedJavaLocalRef<jobject> JNI_WebContentsImpl_FromNativePtr(
+ JNIEnv* env,
+ const JavaParamRef<jclass>& clazz,
+ jlong web_contents_ptr) {
WebContentsAndroid* web_contents_android =
reinterpret_cast<WebContentsAndroid*>(web_contents_ptr);
@@ -591,7 +594,7 @@ void WebContentsAndroid::SetOverscrollRefreshHandler(
WebContentsViewAndroid* view =
static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
view->SetOverscrollRefreshHandler(
- base::MakeUnique<ui::OverscrollRefreshHandler>(
+ std::make_unique<ui::OverscrollRefreshHandler>(
overscroll_refresh_handler));
}
diff --git a/chromium/content/browser/web_contents/web_contents_delegate_unittest.cc b/chromium/content/browser/web_contents/web_contents_delegate_unittest.cc
index 90358587c89..1845a660f90 100644
--- a/chromium/content/browser/web_contents/web_contents_delegate_unittest.cc
+++ b/chromium/content/browser/web_contents/web_contents_delegate_unittest.cc
@@ -26,8 +26,8 @@ TEST_F(WebContentsDelegateTest, UnregisterInDestructor) {
WebContents::Create(WebContents::CreateParams(browser_context()))));
std::unique_ptr<WebContentsImpl> contents_b(static_cast<WebContentsImpl*>(
WebContents::Create(WebContents::CreateParams(browser_context()))));
- EXPECT_EQ(NULL, contents_a->GetDelegate());
- EXPECT_EQ(NULL, contents_b->GetDelegate());
+ EXPECT_EQ(nullptr, contents_a->GetDelegate());
+ EXPECT_EQ(nullptr, contents_b->GetDelegate());
std::unique_ptr<MockWebContentsDelegate> delegate(
new MockWebContentsDelegate());
@@ -35,7 +35,7 @@ TEST_F(WebContentsDelegateTest, UnregisterInDestructor) {
// Setting a delegate should work correctly.
contents_a->SetDelegate(delegate.get());
EXPECT_EQ(delegate.get(), contents_a->GetDelegate());
- EXPECT_TRUE(contents_b->GetDelegate() == NULL);
+ EXPECT_TRUE(contents_b->GetDelegate() == nullptr);
// A delegate can be a delegate to multiple WebContentsImpl.
contents_b->SetDelegate(delegate.get());
@@ -48,18 +48,18 @@ TEST_F(WebContentsDelegateTest, UnregisterInDestructor) {
EXPECT_EQ(delegate.get(), contents_b->GetDelegate());
// Setting delegate to NULL should work correctly.
- contents_b->SetDelegate(NULL);
+ contents_b->SetDelegate(nullptr);
EXPECT_EQ(delegate.get(), contents_a->GetDelegate());
- EXPECT_TRUE(contents_b->GetDelegate() == NULL);
+ EXPECT_TRUE(contents_b->GetDelegate() == nullptr);
// Destroying the delegate while it is still the delegate for a
// WebContentsImpl should unregister it.
contents_b->SetDelegate(delegate.get());
EXPECT_EQ(delegate.get(), contents_a->GetDelegate());
EXPECT_EQ(delegate.get(), contents_b->GetDelegate());
- delegate.reset(NULL);
- EXPECT_TRUE(contents_a->GetDelegate() == NULL);
- EXPECT_TRUE(contents_b->GetDelegate() == NULL);
+ delegate.reset(nullptr);
+ EXPECT_TRUE(contents_a->GetDelegate() == nullptr);
+ EXPECT_TRUE(contents_b->GetDelegate() == nullptr);
// Destroy the WebContentses and run the message loop to prevent leaks.
contents_a.reset();
diff --git a/chromium/content/browser/web_contents/web_contents_impl.cc b/chromium/content/browser/web_contents/web_contents_impl.cc
index f985ea2bcea..c1ae2a91173 100644
--- a/chromium/content/browser/web_contents/web_contents_impl.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl.cc
@@ -105,6 +105,7 @@
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/browser/resource_request_details.h"
+#include "content/public/browser/restore_type.h"
#include "content/public/browser/security_style_explanations.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/browser/storage_partition.h"
@@ -116,11 +117,12 @@
#include "content/public/common/child_process_host.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/page_state.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/result_codes.h"
+#include "content/public/common/service_manager_connection.h"
#include "content/public/common/url_utils.h"
#include "content/public/common/web_preferences.h"
-#include "device/geolocation/geolocation_context.h"
#include "net/base/url_util.h"
#include "net/http/http_cache.h"
#include "net/http/http_transaction_factory.h"
@@ -128,11 +130,13 @@
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "ppapi/features/features.h"
+#include "services/device/public/interfaces/constants.mojom.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/WebKit/common/mime_util/mime_util.h"
+#include "third_party/WebKit/common/sandbox_flags.h"
#include "third_party/WebKit/public/platform/WebSecurityStyle.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/accessibility/ax_tree_combiner.h"
#include "ui/base/layout.h"
@@ -267,15 +271,13 @@ bool GetInnerWebContentsHelper(
return false;
}
-FrameTreeNode* FindOpener(const WebContents::CreateParams& params) {
- FrameTreeNode* opener_node = nullptr;
+RenderFrameHostImpl* FindOpenerRFH(const WebContents::CreateParams& params) {
+ RenderFrameHostImpl* opener_rfh = nullptr;
if (params.opener_render_frame_id != MSG_ROUTING_NONE) {
- RenderFrameHostImpl* opener_rfh = RenderFrameHostImpl::FromID(
- params.opener_render_process_id, params.opener_render_frame_id);
- if (opener_rfh)
- opener_node = opener_rfh->frame_tree_node();
+ opener_rfh = RenderFrameHostImpl::FromID(params.opener_render_process_id,
+ params.opener_render_frame_id);
}
- return opener_node;
+ return opener_rfh;
}
// Ensures that OnDialogClosed is only called once.
@@ -306,15 +308,18 @@ class CloseDialogCallbackWrapper
} // namespace
WebContents* WebContents::Create(const WebContents::CreateParams& params) {
- return WebContentsImpl::CreateWithOpener(params, FindOpener(params));
+ return WebContentsImpl::CreateWithOpener(params, FindOpenerRFH(params));
}
WebContents* WebContents::CreateWithSessionStorage(
const WebContents::CreateParams& params,
const SessionStorageNamespaceMap& session_storage_namespace_map) {
WebContentsImpl* new_contents = new WebContentsImpl(params.browser_context);
- new_contents->SetOpenerForNewContents(FindOpener(params),
- params.opener_suppressed);
+ RenderFrameHostImpl* opener_rfh = FindOpenerRFH(params);
+ FrameTreeNode* opener = nullptr;
+ if (opener_rfh)
+ opener = opener_rfh->frame_tree_node();
+ new_contents->SetOpenerForNewContents(opener, params.opener_suppressed);
for (SessionStorageNamespaceMap::const_iterator it =
session_storage_namespace_map.begin();
@@ -494,9 +499,9 @@ WebContentsImpl::WebContentsTreeNode::inner_web_contents() const {
// WebContentsImpl -------------------------------------------------------------
WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
- : delegate_(NULL),
+ : delegate_(nullptr),
controller_(this, browser_context),
- render_view_host_delegate_view_(NULL),
+ render_view_host_delegate_view_(nullptr),
created_with_opener_(false),
frame_tree_(new NavigatorImpl(&controller_, this),
this,
@@ -524,7 +529,7 @@ WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
is_being_destroyed_(false),
is_notifying_observers_(false),
notify_disconnection_(false),
- dialog_manager_(NULL),
+ dialog_manager_(nullptr),
is_showing_before_unload_dialog_(false),
last_active_time_(base::TimeTicks::Now()),
closed_by_user_gesture_(false),
@@ -537,7 +542,6 @@ WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
is_subframe_(false),
force_disable_overscroll_content_(false),
last_dialog_suppressed_(false),
- geolocation_context_(new device::GeolocationContext()),
accessibility_mode_(
BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()),
audio_stream_monitor_(this),
@@ -674,13 +678,16 @@ WebContentsImpl::~WebContentsImpl() {
for (auto& observer : observers_)
observer.ResetWebContents();
- SetDelegate(NULL);
+ SetDelegate(nullptr);
}
WebContentsImpl* WebContentsImpl::CreateWithOpener(
const WebContents::CreateParams& params,
- FrameTreeNode* opener) {
+ RenderFrameHostImpl* opener_rfh) {
TRACE_EVENT0("browser", "WebContentsImpl::CreateWithOpener");
+ FrameTreeNode* opener = nullptr;
+ if (opener_rfh)
+ opener = opener_rfh->frame_tree_node();
WebContentsImpl* new_contents = new WebContentsImpl(params.browser_context);
new_contents->SetOpenerForNewContents(opener, params.opener_suppressed);
@@ -691,15 +698,22 @@ WebContentsImpl* WebContentsImpl::CreateWithOpener(
// See https://html.spec.whatwg.org/#attr-iframe-sandbox.
FrameTreeNode* new_root = new_contents->GetFrameTree()->root();
if (opener) {
- blink::WebSandboxFlags opener_flags = opener->effective_sandbox_flags();
+ blink::WebSandboxFlags opener_flags = opener_rfh->active_sandbox_flags();
const blink::WebSandboxFlags inherit_flag =
blink::WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts;
if ((opener_flags & inherit_flag) == inherit_flag) {
- new_root->SetPendingSandboxFlags(opener_flags);
- new_root->CommitPendingFramePolicy();
+ // TODO(iclelland): Transfer correct container policy from opener as well.
+ // https://crbug.com/774620
+ new_root->SetPendingFramePolicy({opener_flags, {}});
}
}
+ // Apply starting sandbox flags.
+ blink::FramePolicy frame_policy(new_root->pending_frame_policy());
+ frame_policy.sandbox_flags |= params.starting_sandbox_flags;
+ new_root->SetPendingFramePolicy(frame_policy);
+ new_root->CommitPendingFramePolicy();
+
// This may be true even when opener is null, such as when opening blocked
// popups.
if (params.created_with_opener)
@@ -713,6 +727,7 @@ WebContentsImpl* WebContentsImpl::CreateWithOpener(
// bit to true.
new_contents->is_subframe_ = true;
}
+
new_contents->Init(params);
return new_contents;
}
@@ -792,12 +807,6 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHostImpl* render_view_host,
IPC_MESSAGE_HANDLER(ViewHostMsg_RequestPpapiBrokerPermission,
OnRequestPpapiBrokerPermission)
#endif
- IPC_MESSAGE_HANDLER(ViewHostMsg_ShowValidationMessage,
- OnShowValidationMessage)
- IPC_MESSAGE_HANDLER(ViewHostMsg_HideValidationMessage,
- OnHideValidationMessage)
- IPC_MESSAGE_HANDLER(ViewHostMsg_MoveValidationMessage,
- OnMoveValidationMessage)
#if defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(ViewHostMsg_OpenDateTimeDialog, OnOpenDateTimeDialog)
#endif
@@ -1008,8 +1017,6 @@ void WebContentsImpl::CancelActiveAndPendingDialogs() {
}
if (browser_plugin_embedder_)
browser_plugin_embedder_->CancelGuestDialogs();
- if (delegate_)
- delegate_->HideValidationMessage(this);
}
void WebContentsImpl::ClosePage() {
@@ -1059,10 +1066,17 @@ void WebContentsImpl::SetAccessibilityMode(ui::AXMode mode) {
for (FrameTreeNode* node : frame_tree_.Nodes()) {
UpdateAccessibilityModeOnFrame(node->current_frame_host());
+ // Also update accessibility mode on the pending RenderFrameHost for this
+ // FrameTreeNode, if one exists. speculative_frame_host() is used with
+ // PlzNavigate, and pending_frame_host() is used without it.
RenderFrameHost* pending_frame_host =
node->render_manager()->pending_frame_host();
if (pending_frame_host)
UpdateAccessibilityModeOnFrame(pending_frame_host);
+ RenderFrameHost* speculative_frame_host =
+ node->render_manager()->speculative_frame_host();
+ if (speculative_frame_host)
+ UpdateAccessibilityModeOnFrame(speculative_frame_host);
}
}
@@ -1168,11 +1182,6 @@ void WebContentsImpl::NotifyManifestUrlChanged(
observer.DidUpdateWebManifestURL(manifest_url);
}
-void WebContentsImpl::UpdateDeviceScaleFactor(double device_scale_factor) {
- SendPageMessage(
- new PageMsg_SetDeviceScaleFactor(MSG_ROUTING_NONE, device_scale_factor));
-}
-
void WebContentsImpl::GetScreenInfo(ScreenInfo* screen_info) {
if (GetView())
GetView()->GetScreenInfo(screen_info);
@@ -1202,7 +1211,7 @@ void WebContentsImpl::SetUserAgentOverride(const std::string& override) {
// Reload the page if a load is currently in progress to avoid having
// different parts of the page loaded using different user agents.
NavigationEntry* entry = controller_.GetVisibleEntry();
- if (IsLoading() && entry != NULL && entry->GetIsOverridingUserAgent())
+ if (IsLoading() && entry != nullptr && entry->GetIsOverridingUserAgent())
controller_.Reload(ReloadType::BYPASSING_CACHE, true);
for (auto& observer : observers_)
@@ -1466,8 +1475,10 @@ void WebContentsImpl::OnAudioStateChanged(bool is_audible) {
// Notification for UI updates in response to the changed audio state.
NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
+ was_ever_audible_ = was_ever_audible_ || is_audible;
+
if (delegate_)
- delegate_->OnAudioStateChanged(is_audible);
+ delegate_->OnAudioStateChanged(this, is_audible);
}
base::TimeTicks WebContentsImpl::GetLastActiveTime() const {
@@ -1688,8 +1699,11 @@ WebContents* WebContentsImpl::Clone() {
// before.
CreateParams create_params(GetBrowserContext(), GetSiteInstance());
create_params.initial_size = GetContainerBounds().size();
- WebContentsImpl* tc =
- CreateWithOpener(create_params, frame_tree_.root()->opener());
+ FrameTreeNode* opener = frame_tree_.root()->opener();
+ RenderFrameHostImpl* opener_rfh = nullptr;
+ if (opener)
+ opener_rfh = opener->current_frame_host();
+ WebContentsImpl* tc = CreateWithOpener(create_params, opener_rfh);
tc->GetController().CopyStateFrom(controller_, true);
for (auto& observer : observers_)
observer.DidCloneToNewWebContents(this, tc);
@@ -1778,12 +1792,11 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
} else {
view_.reset(CreateWebContentsView(this, delegate,
&render_view_host_delegate_view_));
- }
-
- if (browser_plugin_guest_ && !GuestMode::IsCrossProcessFrameGuest(this)) {
- view_.reset(new WebContentsViewGuest(this, browser_plugin_guest_.get(),
- std::move(view_),
- &render_view_host_delegate_view_));
+ if (browser_plugin_guest_) {
+ view_ = std::make_unique<WebContentsViewGuest>(
+ this, browser_plugin_guest_.get(), std::move(view_),
+ &render_view_host_delegate_view_);
+ }
}
CHECK(render_view_host_delegate_view_);
CHECK(view_.get());
@@ -1857,7 +1870,7 @@ void WebContentsImpl::OnWebContentsDestroyed(WebContentsImpl* web_contents) {
void WebContentsImpl::AddDestructionObserver(WebContentsImpl* web_contents) {
if (!ContainsKey(destruction_observers_, web_contents)) {
destruction_observers_[web_contents] =
- base::MakeUnique<DestructionObserver>(this, web_contents);
+ std::make_unique<DestructionObserver>(this, web_contents);
}
}
@@ -1967,21 +1980,10 @@ void WebContentsImpl::RenderWidgetWasResized(
GetScreenInfo(&screen_info);
SendPageMessage(new PageMsg_UpdateScreenInfo(MSG_ROUTING_NONE, screen_info));
- // Send resize message to subframes.
- for (RenderWidgetHostView* view : GetRenderWidgetHostViewsInTree()) {
- if (view != rfh->GetView())
- view->GetRenderWidgetHost()->WasResized();
- }
-
for (auto& observer : observers_)
observer.MainFrameWasResized(width_changed);
}
-void WebContentsImpl::ScreenInfoChanged() {
- if (browser_plugin_embedder_)
- browser_plugin_embedder_->ScreenInfoChanged();
-}
-
KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
const NativeWebKeyboardEvent& event) {
return delegate_ ? delegate_->PreHandleKeyboardEvent(this, event)
@@ -2347,7 +2349,7 @@ void WebContentsImpl::CreateNewWindow(
create_params.renderer_initiated_creation =
main_frame_route_id != MSG_ROUTING_NONE;
- WebContentsImpl* new_contents = NULL;
+ WebContentsImpl* new_contents = nullptr;
if (!is_guest) {
create_params.context = view_->GetNativeView();
create_params.initial_size = GetContainerBounds().size();
@@ -2548,7 +2550,7 @@ void WebContentsImpl::ShowCreatedWidget(int process_id,
if (!widget_host_view)
return;
- RenderWidgetHostView* view = NULL;
+ RenderWidgetHostView* view = nullptr;
if (GetOuterWebContents()) {
view = GetOuterWebContents()->GetRenderWidgetHostView();
} else {
@@ -2727,7 +2729,17 @@ RenderFrameHost* WebContentsImpl::GetGuestByInstanceID(
return guest->GetMainFrame();
}
-device::GeolocationContext* WebContentsImpl::GetGeolocationContext() {
+device::mojom::GeolocationContext* WebContentsImpl::GetGeolocationContext() {
+ if (geolocation_context_)
+ return geolocation_context_.get();
+
+ auto request = mojo::MakeRequest(&geolocation_context_);
+ if (!ServiceManagerConnection::GetForProcess())
+ return geolocation_context_.get();
+
+ service_manager::Connector* connector =
+ ServiceManagerConnection::GetForProcess()->GetConnector();
+ connector->BindInterface(device::mojom::kServiceName, std::move(request));
return geolocation_context_.get();
}
@@ -2747,8 +2759,8 @@ device::mojom::WakeLock* WebContentsImpl::GetRendererWakeLock() {
return nullptr;
}
wake_lock_context->GetWakeLock(
- device::mojom::WakeLockType::PreventDisplaySleep,
- device::mojom::WakeLockReason::ReasonOther, "Wake Lock API",
+ device::mojom::WakeLockType::kPreventDisplaySleep,
+ device::mojom::WakeLockReason::kOther, "Wake Lock API",
mojo::MakeRequest(&renderer_wake_lock_));
}
return renderer_wake_lock_.get();
@@ -2762,31 +2774,6 @@ void WebContentsImpl::GetNFC(device::mojom::NFCRequest request) {
}
#endif
-void WebContentsImpl::OnShowValidationMessage(
- RenderViewHostImpl* source,
- const gfx::Rect& anchor_in_root_view,
- const base::string16& main_text,
- const base::string16& sub_text) {
- // TODO(nick): Should we consider |source| here or pass it to the delegate?
- if (delegate_)
- delegate_->ShowValidationMessage(
- this, anchor_in_root_view, main_text, sub_text);
-}
-
-void WebContentsImpl::OnHideValidationMessage(RenderViewHostImpl* source) {
- // TODO(nick): Should we consider |source| here or pass it to the delegate?
- if (delegate_)
- delegate_->HideValidationMessage(this);
-}
-
-void WebContentsImpl::OnMoveValidationMessage(
- RenderViewHostImpl* source,
- const gfx::Rect& anchor_in_root_view) {
- // TODO(nick): Should we consider |source| here or pass it to the delegate?
- if (delegate_)
- delegate_->MoveValidationMessage(this, anchor_in_root_view);
-}
-
void WebContentsImpl::SetNotWaitingForResponse() {
if (waiting_for_response_ == false)
return;
@@ -2904,7 +2891,8 @@ void WebContentsImpl::UpdatePreferredSize(const gfx::Size& pref_size) {
void WebContentsImpl::ResizeDueToAutoResize(
RenderWidgetHostImpl* render_widget_host,
- const gfx::Size& new_size) {
+ const gfx::Size& new_size,
+ uint64_t sequence_number) {
if (render_widget_host != GetRenderViewHost()->GetWidget())
return;
@@ -2924,6 +2912,11 @@ void WebContentsImpl::ResizeDueToAutoResize(
if (delegate_)
delegate_->ResizeDueToAutoResize(this, new_size);
+
+ RenderWidgetHostViewBase* view =
+ static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView());
+ if (view)
+ view->ResizeDueToAutoResize(new_size, sequence_number);
}
gfx::Size WebContentsImpl::GetAutoResizeSize() {
@@ -2936,7 +2929,7 @@ void WebContentsImpl::ResetAutoResizeSize() {
WebContents* WebContentsImpl::OpenURL(const OpenURLParams& params) {
if (!delegate_)
- return NULL;
+ return nullptr;
WebContents* new_contents = delegate_->OpenURLFromTab(this, params);
@@ -3246,17 +3239,7 @@ void WebContentsImpl::RestoreFocus() {
}
void WebContentsImpl::FocusThroughTabTraversal(bool reverse) {
- if (ShowingInterstitialPage()) {
- interstitial_page_->FocusThroughTabTraversal(reverse);
- return;
- }
- RenderWidgetHostView* const fullscreen_view =
- GetFullscreenRenderWidgetHostView();
- if (fullscreen_view) {
- fullscreen_view->Focus();
- return;
- }
- GetRenderViewHost()->SetInitialFocus(reverse);
+ view_->FocusThroughTabTraversal(reverse);
}
bool WebContentsImpl::ShowingInterstitialPage() const {
@@ -3269,7 +3252,7 @@ void WebContentsImpl::AdjustPreviewsStateForNavigation(
delegate_->AdjustPreviewsStateForNavigation(previews_state);
}
-InterstitialPage* WebContentsImpl::GetInterstitialPage() const {
+InterstitialPageImpl* WebContentsImpl::GetInterstitialPage() const {
return interstitial_page_;
}
@@ -3362,7 +3345,7 @@ void WebContentsImpl::SaveFrameWithHeaders(const GURL& url,
"triggered by user request."
policy_exception_justification: "Not implemented."
})");
- auto params = base::MakeUnique<DownloadUrlParameters>(
+ auto params = std::make_unique<DownloadUrlParameters>(
url, frame_host->GetProcess()->GetID(),
frame_host->GetRenderViewHost()->GetRoutingID(),
frame_host->GetRoutingID(), storage_partition->GetURLRequestContext(),
@@ -3407,19 +3390,18 @@ void WebContentsImpl::Close() {
Close(GetRenderViewHost());
}
-void WebContentsImpl::DragSourceEndedAt(int client_x,
- int client_y,
- int screen_x,
- int screen_y,
+void WebContentsImpl::DragSourceEndedAt(float client_x,
+ float client_y,
+ float screen_x,
+ float screen_y,
blink::WebDragOperation operation,
RenderWidgetHost* source_rwh) {
if (browser_plugin_embedder_.get())
browser_plugin_embedder_->DragSourceEndedAt(
client_x, client_y, screen_x, screen_y, operation);
if (source_rwh) {
- source_rwh->DragSourceEndedAt(gfx::Point(client_x, client_y),
- gfx::Point(screen_x, screen_y),
- operation);
+ source_rwh->DragSourceEndedAt(gfx::PointF(client_x, client_y),
+ gfx::PointF(screen_x, screen_y), operation);
}
}
@@ -3444,18 +3426,13 @@ void WebContentsImpl::DidGetResourceResponseStart(
const ResourceRequestDetails& details) {
SetNotWaitingForResponse();
controller_.ssl_manager()->DidStartResourceResponse(
- details.url, details.has_certificate, details.ssl_cert_status);
+ details.url, details.has_certificate, details.ssl_cert_status,
+ details.resource_type);
for (auto& observer : observers_)
observer.DidGetResourceResponseStart(details);
}
-void WebContentsImpl::DidGetRedirectForResourceRequest(
- const ResourceRedirectDetails& details) {
- for (auto& observer : observers_)
- observer.DidGetRedirectForResourceRequest(details);
-}
-
void WebContentsImpl::NotifyWebContentsFocused(
RenderWidgetHost* render_widget_host) {
for (auto& observer : observers_)
@@ -3488,25 +3465,6 @@ bool WebContentsImpl::GetClosedByUserGesture() const {
return closed_by_user_gesture_;
}
-void WebContentsImpl::ViewSource() {
- if (!delegate_)
- return;
-
- NavigationEntry* entry = GetController().GetLastCommittedEntry();
- if (!entry)
- return;
-
- delegate_->ViewSourceForTab(this, entry->GetURL());
-}
-
-void WebContentsImpl::ViewFrameSource(const GURL& url,
- const PageState& page_state) {
- if (!delegate_)
- return;
-
- delegate_->ViewSourceForFrame(this, url, page_state);
-}
-
int WebContentsImpl::GetMinimumZoomPercent() const {
return minimum_zoom_percent_;
}
@@ -3549,7 +3507,7 @@ bool WebContentsImpl::GotResponseToLockMouseRequest(bool allowed) {
}
bool WebContentsImpl::HasOpener() const {
- return GetOpener() != NULL;
+ return GetOpener() != nullptr;
}
RenderFrameHostImpl* WebContentsImpl::GetOpener() const {
@@ -3558,7 +3516,7 @@ RenderFrameHostImpl* WebContentsImpl::GetOpener() const {
}
bool WebContentsImpl::HasOriginalOpener() const {
- return GetOriginalOpener() != NULL;
+ return GetOriginalOpener() != nullptr;
}
RenderFrameHostImpl* WebContentsImpl::GetOriginalOpener() const {
@@ -3651,6 +3609,10 @@ bool WebContentsImpl::WasRecentlyAudible() {
browser_plugin_embedder_->WereAnyGuestsRecentlyAudible());
}
+bool WebContentsImpl::WasEverAudible() {
+ return was_ever_audible_;
+}
+
void WebContentsImpl::GetManifest(const GetManifestCallback& callback) {
manifest_manager_host_->GetManifest(callback);
}
@@ -3754,6 +3716,11 @@ void WebContentsImpl::DidFinishNavigation(NavigationHandle* navigation_handle) {
manager->NavigationSucceeded();
}
}
+
+ if (navigation_handle->IsInMainFrame() &&
+ !navigation_handle->IsSameDocument()) {
+ was_ever_audible_ = false;
+ }
}
}
@@ -3956,6 +3923,83 @@ bool WebContentsImpl::ShouldAllowRunningInsecureContent(
web_contents, allowed_per_prefs, origin, resource_url);
}
+void WebContentsImpl::ViewSource(RenderFrameHostImpl* frame) {
+ DCHECK_EQ(this, WebContents::FromRenderFrameHost(frame));
+
+ // Don't do anything if there is no |delegate_| that could accept and show the
+ // new WebContents containing the view-source.
+ if (!delegate_)
+ return;
+
+ // Use the last committed entry, since the pending entry hasn't loaded yet and
+ // won't be copied into the cloned tab.
+ NavigationEntryImpl* last_committed_entry =
+ static_cast<NavigationEntryImpl*>(frame->frame_tree_node()
+ ->navigator()
+ ->GetController()
+ ->GetLastCommittedEntry());
+ if (!last_committed_entry)
+ return;
+
+ FrameNavigationEntry* frame_entry =
+ last_committed_entry->GetFrameEntry(frame->frame_tree_node());
+ if (!frame_entry)
+ return;
+
+ // Any new WebContents opened while this WebContents is in fullscreen can be
+ // used to confuse the user, so drop fullscreen.
+ if (IsFullscreenForCurrentTab())
+ ExitFullscreen(true);
+
+ // We intentionally don't share the SiteInstance with the original frame so
+ // that view source has a consistent process model and always ends up in a new
+ // process (https://crbug.com/699493).
+ scoped_refptr<SiteInstanceImpl> site_instance_for_view_source = nullptr;
+ // Referrer is not important, because view-source should not hit the network,
+ // but should be served from the cache instead.
+ Referrer referrer_for_view_source;
+ // Do not restore title, derive it from the url.
+ base::string16 title_for_view_source;
+ auto navigation_entry = std::make_unique<NavigationEntryImpl>(
+ site_instance_for_view_source, frame_entry->url(),
+ referrer_for_view_source, title_for_view_source, ui::PAGE_TRANSITION_LINK,
+ /* is_renderer_initiated = */ false);
+ navigation_entry->SetVirtualURL(GURL(content::kViewSourceScheme +
+ std::string(":") +
+ frame_entry->url().spec()));
+
+ // Do not restore scroller position.
+ // TODO(creis, lukasza, arthursonzogni): Do not reuse the original PageState,
+ // but start from a new one and only copy the needed data.
+ const PageState& new_page_state =
+ frame_entry->page_state().RemoveScrollOffset();
+
+ scoped_refptr<FrameNavigationEntry> new_frame_entry =
+ navigation_entry->root_node()->frame_entry;
+ new_frame_entry->set_method(frame_entry->method());
+ new_frame_entry->SetPageState(new_page_state);
+
+ // Create a new WebContents, which is used to display the source code.
+ WebContentsImpl* view_source_contents =
+ static_cast<WebContentsImpl*>(Create(CreateParams(GetBrowserContext())));
+
+ // Restore the previously created NavigationEntry.
+ std::vector<std::unique_ptr<NavigationEntry>> navigation_entries;
+ navigation_entries.push_back(std::move(navigation_entry));
+ view_source_contents->GetController().Restore(0, RestoreType::CURRENT_SESSION,
+ &navigation_entries);
+
+ // Add |view_source_contents| as a new tab.
+ gfx::Rect initial_rect;
+ constexpr bool kUserGesture = true;
+ bool ignored_was_blocked;
+ delegate_->AddNewContents(this, view_source_contents,
+ WindowOpenDisposition::NEW_FOREGROUND_TAB,
+ initial_rect, kUserGesture, &ignored_was_blocked);
+ // Note that the |delegate_| could have deleted |view_source_contents| during
+ // AddNewContents method call.
+}
+
#if defined(OS_ANDROID)
base::android::ScopedJavaLocalRef<jobject>
WebContentsImpl::GetJavaRenderFrameHostDelegate() {
@@ -4161,9 +4205,9 @@ void WebContentsImpl::OnOpenColorChooser(
int color_chooser_id,
SkColor color,
const std::vector<ColorSuggestion>& suggestions) {
- ColorChooser* new_color_chooser = delegate_ ?
- delegate_->OpenColorChooser(this, color, suggestions) :
- NULL;
+ ColorChooser* new_color_chooser =
+ delegate_ ? delegate_->OpenColorChooser(this, color, suggestions)
+ : nullptr;
if (!new_color_chooser)
return;
if (color_chooser_info_.get())
@@ -4294,18 +4338,6 @@ void WebContentsImpl::OnUpdateFaviconURL(
observer.DidUpdateFaviconURL(candidates);
}
-void WebContentsImpl::OnPasswordInputShownOnHttp() {
- controller_.ssl_manager()->DidShowPasswordInputOnHttp();
-}
-
-void WebContentsImpl::OnAllPasswordInputsHiddenOnHttp() {
- controller_.ssl_manager()->DidHideAllPasswordInputsOnHttp();
-}
-
-void WebContentsImpl::OnCreditCardInputShownOnHttp() {
- controller_.ssl_manager()->DidShowCreditCardInputOnHttp();
-}
-
void WebContentsImpl::SetIsOverlayContent(bool is_overlay_content) {
is_overlay_content_ = is_overlay_content;
}
@@ -4685,7 +4717,7 @@ void WebContentsImpl::RunBeforeUnloadConfirm(
if (dialog_manager_) {
dialog_manager_->RunBeforeUnloadDialog(
- this, is_reload,
+ this, render_frame_host, is_reload,
base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false));
}
}
@@ -5670,6 +5702,9 @@ void WebContentsImpl::OnDialogClosed(int render_process_id,
controller_.DiscardNonCommittedEntries();
}
+ // Update the URL display either way, to avoid showing a stale URL.
+ NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
+
for (auto& observer : observers_)
observer.BeforeUnloadDialogCancelled();
}
@@ -5759,12 +5794,12 @@ void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
}
std::unique_ptr<WebUIImpl> WebContentsImpl::CreateWebUI(const GURL& url) {
- std::unique_ptr<WebUIImpl> web_ui = base::MakeUnique<WebUIImpl>(this);
+ std::unique_ptr<WebUIImpl> web_ui = std::make_unique<WebUIImpl>(this);
WebUIController* controller =
WebUIControllerFactoryRegistry::GetInstance()
->CreateWebUIControllerForURL(web_ui.get(), url);
if (controller) {
- web_ui->AddMessageHandler(base::MakeUnique<GenericHandler>());
+ web_ui->AddMessageHandler(std::make_unique<GenericHandler>());
web_ui->SetController(controller);
return web_ui;
}
@@ -5886,12 +5921,13 @@ void WebContentsImpl::MediaStartedPlaying(
void WebContentsImpl::MediaStoppedPlaying(
const WebContentsObserver::MediaPlayerInfo& media_info,
- const WebContentsObserver::MediaPlayerId& id) {
+ const WebContentsObserver::MediaPlayerId& id,
+ WebContentsObserver::MediaStoppedReason reason) {
if (media_info.has_video)
currently_playing_video_count_--;
for (auto& observer : observers_)
- observer.MediaStoppedPlaying(media_info, id);
+ observer.MediaStoppedPlaying(media_info, id, reason);
}
void WebContentsImpl::MediaResized(
diff --git a/chromium/content/browser/web_contents/web_contents_impl.h b/chromium/content/browser/web_contents/web_contents_impl.h
index afd40fc8389..a8ac12f8beb 100644
--- a/chromium/content/browser/web_contents/web_contents_impl.h
+++ b/chromium/content/browser/web_contents/web_contents_impl.h
@@ -24,6 +24,7 @@
#include "build/build_config.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_controller_delegate.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigator_delegate.h"
@@ -46,6 +47,7 @@
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/resource_type.h"
#include "content/public/common/three_d_api_types.h"
+#include "device/geolocation/public/interfaces/geolocation_context.mojom.h"
#include "net/base/load_states.h"
#include "net/http/http_response_headers.h"
#include "ppapi/features/features.h"
@@ -98,7 +100,6 @@ struct ColorSuggestion;
struct FaviconURL;
struct LoadNotificationDetails;
struct MHTMLGenerationParams;
-struct ResourceRedirectDetails;
struct ResourceRequestDetails;
namespace mojom {
@@ -137,7 +138,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
static WebContentsImpl* CreateWithOpener(
const WebContents::CreateParams& params,
- FrameTreeNode* opener);
+ RenderFrameHostImpl* opener_rfh);
static std::vector<WebContentsImpl*> GetAllWebContents();
@@ -197,10 +198,10 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// Informs the render view host and the BrowserPluginEmbedder, if present, of
// a Drag Source End.
- void DragSourceEndedAt(int client_x,
- int client_y,
- int screen_x,
- int screen_y,
+ void DragSourceEndedAt(float client_x,
+ float client_y,
+ float screen_x,
+ float screen_y,
blink::WebDragOperation operation,
RenderWidgetHost* source_rwh);
@@ -214,10 +215,6 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void DidGetResourceResponseStart(
const ResourceRequestDetails& details);
- // A redirect was received while requesting a resource.
- void DidGetRedirectForResourceRequest(
- const ResourceRedirectDetails& details);
-
// Notify observers that the web contents has been focused.
void NotifyWebContentsFocused(RenderWidgetHost* render_widget_host);
@@ -406,7 +403,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void FocusThroughTabTraversal(bool reverse) override;
bool ShowingInterstitialPage() const override;
void AdjustPreviewsStateForNavigation(PreviewsState* previews_state) override;
- InterstitialPage* GetInterstitialPage() const override;
+ InterstitialPageImpl* GetInterstitialPage() const override;
bool IsSavable() override;
void OnSavePage() override;
bool SavePage(const base::FilePath& main_file,
@@ -426,8 +423,6 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void UserGestureDone() override;
void SetClosedByUserGesture(bool value) override;
bool GetClosedByUserGesture() const override;
- void ViewSource() override;
- void ViewFrameSource(const GURL& url, const PageState& page_state) override;
int GetMinimumZoomPercent() const override;
int GetMaximumZoomPercent() const override;
void SetPageScale(float page_scale_factor) override;
@@ -450,13 +445,11 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
const blink::WebFindOptions& options) override;
void StopFinding(StopFindAction action) override;
bool WasRecentlyAudible() override;
+ bool WasEverAudible() override;
void GetManifest(const GetManifestCallback& callback) override;
bool IsFullscreenForCurrentTab() const override;
void ExitFullscreen(bool will_cause_resize) override;
void ResumeLoadingCreatedWebContents() override;
- void OnPasswordInputShownOnHttp() override;
- void OnAllPasswordInputsHiddenOnHttp() override;
- void OnCreditCardInputShownOnHttp() override;
void SetIsOverlayContent(bool is_overlay_content) override;
bool IsFocusedElementEditable() override;
void ClearFocusedElement() override;
@@ -506,6 +499,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
IPC::Message* reply_msg) override;
void RunFileChooser(RenderFrameHost* render_frame_host,
const FileChooserParams& params) override;
+ void DidCancelLoading() override;
void DidAccessInitialDocument() override;
void DidChangeName(RenderFrameHost* render_frame_host,
const std::string& name) override;
@@ -527,7 +521,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
RenderFrameHost* GetGuestByInstanceID(
RenderFrameHost* render_frame_host,
int browser_plugin_instance_id) override;
- device::GeolocationContext* GetGeolocationContext() override;
+ device::mojom::GeolocationContext* GetGeolocationContext() override;
device::mojom::WakeLockContext* GetWakeLockContext() override;
device::mojom::WakeLock* GetRendererWakeLock() override;
#if defined(OS_ANDROID)
@@ -567,6 +561,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
bool allowed_per_prefs,
const url::Origin& origin,
const GURL& resource_url) override;
+ void ViewSource(RenderFrameHostImpl* frame) override;
#if defined(OS_ANDROID)
base::android::ScopedJavaLocalRef<jobject> GetJavaRenderFrameHostDelegate()
override;
@@ -589,7 +584,6 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
const GURL& url) override;
void Close(RenderViewHost* render_view_host) override;
void RequestMove(const gfx::Rect& new_bounds) override;
- void DidCancelLoading() override;
void DocumentAvailableInMainFrame(RenderViewHost* render_view_host) override;
void RouteCloseEvent(RenderViewHost* rvh) override;
bool DidAddMessageToConsole(int32_t level,
@@ -678,11 +672,10 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void RenderWidgetWasResized(RenderWidgetHostImpl* render_widget_host,
bool width_changed) override;
void ResizeDueToAutoResize(RenderWidgetHostImpl* render_widget_host,
- const gfx::Size& new_size) override;
+ const gfx::Size& new_size,
+ uint64_t sequence_number) override;
gfx::Size GetAutoResizeSize() override;
void ResetAutoResizeSize() override;
- void ScreenInfoChanged() override;
- void UpdateDeviceScaleFactor(double device_scale_factor) override;
void GetScreenInfo(ScreenInfo* screen_info) override;
KeyboardEventProcessingResult PreHandleKeyboardEvent(
const NativeWebKeyboardEvent& event) override;
@@ -844,7 +837,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
const WebContentsObserver::MediaPlayerId& id);
void MediaStoppedPlaying(
const WebContentsObserver::MediaPlayerInfo& media_info,
- const WebContentsObserver::MediaPlayerId& id);
+ const WebContentsObserver::MediaPlayerId& id,
+ WebContentsObserver::MediaStoppedReason reason);
// This will be called before playback is started, check
// GetCurrentlyPlayingVideoCount if you need this when playback starts.
void MediaResized(const gfx::Size& size,
@@ -943,6 +937,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
IframeBeforeUnloadParentHang);
FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
BeforeUnloadDialogRequiresGesture);
+ FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
+ CancelBeforeUnloadResetsURL);
FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest, JavaScriptDialogNotifications);
FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest, JavaScriptDialogInterop);
FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest, BeforeUnloadDialog);
@@ -1600,7 +1596,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// Whether the last JavaScript dialog shown was suppressed. Used for testing.
bool last_dialog_suppressed_;
- std::unique_ptr<device::GeolocationContext> geolocation_context_;
+ device::mojom::GeolocationContextPtr geolocation_context_;
std::unique_ptr<WakeLockContextHost> wake_lock_context_host_;
@@ -1675,6 +1671,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
bool has_persistent_video_ = false;
+ bool was_ever_audible_ = false;
+
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 259388aaff0..998bd419788 100644
--- a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -88,7 +88,7 @@ class LoadStopNotificationObserver : public WindowedNotificationObserver {
: WindowedNotificationObserver(NOTIFICATION_LOAD_STOP,
Source<NavigationController>(controller)),
session_index_(-1),
- controller_(NULL) {}
+ controller_(nullptr) {}
void Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) override {
@@ -420,7 +420,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
class RenderFrameCreatedObserver : public WebContentsObserver {
public:
explicit RenderFrameCreatedObserver(Shell* shell)
- : WebContentsObserver(shell->web_contents()), last_rfh_(NULL) {}
+ : WebContentsObserver(shell->web_contents()), last_rfh_(nullptr) {}
void RenderFrameCreated(RenderFrameHost* render_frame_host) override {
last_rfh_ = render_frame_host;
@@ -1128,6 +1128,7 @@ class TestWCDelegateForDialogsAndFullscreen : public JavaScriptDialogManager,
};
void RunBeforeUnloadDialog(WebContents* web_contents,
+ RenderFrameHost* render_frame_host,
bool is_reload,
DialogClosedCallback callback) override {
std::move(callback).Run(true, base::string16());
@@ -1626,82 +1627,6 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
wc->SetJavaScriptDialogManagerForTesting(nullptr);
}
-class FormBubbleDelegate : public WebContentsDelegate {
- public:
- FormBubbleDelegate() = default;
-
- void WaitUntilShown() {
- while (!is_visible_) {
- message_loop_runner_ = new MessageLoopRunner;
- message_loop_runner_->Run();
- }
- }
-
- void WaitUntilHidden() {
- while (is_visible_) {
- message_loop_runner_ = new MessageLoopRunner;
- message_loop_runner_->Run();
- }
- }
-
- private:
- void ShowValidationMessage(WebContents* web_contents,
- const gfx::Rect& anchor_in_root_view,
- const base::string16& main_text,
- const base::string16& sub_text) override {
- is_visible_ = true;
- if (message_loop_runner_)
- message_loop_runner_->Quit();
- }
-
- void HideValidationMessage(WebContents* web_contents) override {
- is_visible_ = false;
- if (message_loop_runner_)
- message_loop_runner_->Quit();
- }
-
- bool is_visible_ = false;
- scoped_refptr<MessageLoopRunner> message_loop_runner_;
-};
-
-// TODO(tkent): Remove this test when we remove the browser-side validation
-// bubble implementation. crbug.com/739091
-IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
- DISABLED_NavigationHidesFormValidationBubble) {
- ASSERT_TRUE(embedded_test_server()->Start());
- EXPECT_TRUE(NavigateToURL(
- shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
-
- // Start listening for requests to show or hide the form validation bubble.
- WebContentsImpl* web_contents =
- static_cast<WebContentsImpl*>(shell()->web_contents());
- FormBubbleDelegate bubble_delegate;
- web_contents->SetDelegate(&bubble_delegate);
-
- // Trigger a form validation bubble and verify that the bubble is shown.
- std::string script = R"(
- var input_field = document.createElement('input');
- input_field.required = true;
- var form = document.createElement('form');
- form.appendChild(input_field);
- document.body.appendChild(form);
-
- setTimeout(function() {
- input_field.setCustomValidity('Custom validity message');
- input_field.reportValidity();
- },
- 0);
- )";
- ASSERT_TRUE(ExecuteScript(web_contents, script));
- bubble_delegate.WaitUntilShown();
-
- // Navigate to another page and verify that the form validation bubble is
- // hidden.
- EXPECT_TRUE(NavigateToURL(
- shell(), embedded_test_server()->GetURL("b.com", "/title2.html")));
- bubble_delegate.WaitUntilHidden();
-}
-
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
FrameDetachInCopyDoesNotCrash) {
ASSERT_TRUE(embedded_test_server()->Start());
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 6e340ce8669..baf27d65d9d 100644
--- a/chromium/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -35,7 +35,6 @@
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_widget_host_view.h"
-#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/ssl_host_state_delegate.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents_delegate.h"
@@ -57,6 +56,7 @@
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/common/sandbox_flags.h"
#include "third_party/skia/include/core/SkColor.h"
#include "url/url_constants.h"
@@ -339,19 +339,9 @@ class FakeFullscreenDelegate : public WebContentsDelegate {
class FakeWebContentsDelegate : public WebContentsDelegate {
public:
- FakeWebContentsDelegate()
- : hide_validation_message_was_called_(false),
- loading_state_changed_was_called_(false) {}
+ FakeWebContentsDelegate() : loading_state_changed_was_called_(false) {}
~FakeWebContentsDelegate() override {}
- void HideValidationMessage(WebContents* web_contents) override {
- hide_validation_message_was_called_ = true;
- }
-
- bool hide_validation_message_was_called() const {
- return hide_validation_message_was_called_;
- }
-
void LoadingStateChanged(WebContents* source,
bool to_different_document) override {
loading_state_changed_was_called_ = true;
@@ -362,7 +352,6 @@ class FakeWebContentsDelegate : public WebContentsDelegate {
}
private:
- bool hide_validation_message_was_called_;
bool loading_state_changed_was_called_;
DISALLOW_COPY_AND_ASSIGN(FakeWebContentsDelegate);
@@ -1600,22 +1589,6 @@ TEST_F(WebContentsImplTest, HistoryNavigationExitsFullscreen) {
contents()->SetDelegate(nullptr);
}
-TEST_F(WebContentsImplTest, TerminateHidesValidationMessage) {
- FakeWebContentsDelegate fake_delegate;
- contents()->SetDelegate(&fake_delegate);
- EXPECT_FALSE(fake_delegate.hide_validation_message_was_called());
-
- // Initialize the RenderFrame and then simulate crashing the renderer
- // process.
- main_test_rfh()->InitializeRenderFrameIfNeeded();
- main_test_rfh()->GetProcess()->SimulateCrash();
-
- // Confirm HideValidationMessage was called.
- EXPECT_TRUE(fake_delegate.hide_validation_message_was_called());
-
- contents()->SetDelegate(nullptr);
-}
-
// Tests that fullscreen is exited throughout the object hierarchy on a renderer
// crash.
TEST_F(WebContentsImplTest, CrashExitsFullscreen) {
@@ -3514,8 +3487,8 @@ TEST_F(WebContentsImplTest, LoadResourceWithEmptySecurityInfo) {
ASSERT_TRUE(state_delegate);
state_delegate->AllowCert(test_url.host(), *cert.get(), 1);
EXPECT_TRUE(state_delegate->HasAllowException(test_url.host()));
- contents()->controller_.ssl_manager()->DidStartResourceResponse(test_url,
- false, 0);
+ contents()->controller_.ssl_manager()->DidStartResourceResponse(
+ test_url, false, 0, RESOURCE_TYPE_MAIN_FRAME);
EXPECT_TRUE(state_delegate->HasAllowException(test_url.host()));
@@ -3576,6 +3549,7 @@ class TestJavaScriptDialogManager : public JavaScriptDialogManager {
};
void RunBeforeUnloadDialog(WebContents* web_contents,
+ RenderFrameHost* render_frame_host,
bool is_reload,
DialogClosedCallback callback) override {}
@@ -3618,4 +3592,21 @@ TEST_F(WebContentsImplTest, ResetJavaScriptDialogOnUserNavigate) {
contents()->SetJavaScriptDialogManagerForTesting(nullptr);
}
+TEST_F(WebContentsImplTest, StartingSandboxFlags) {
+ WebContents::CreateParams params(browser_context());
+ const blink::WebSandboxFlags expected_flags =
+ blink::WebSandboxFlags::kPopups | blink::WebSandboxFlags::kModals |
+ blink::WebSandboxFlags::kTopNavigation;
+ params.starting_sandbox_flags = expected_flags;
+ WebContentsImpl* new_contents =
+ WebContentsImpl::CreateWithOpener(params, nullptr);
+ FrameTreeNode* root = new_contents->GetFrameTree()->root();
+ blink::WebSandboxFlags pending_flags =
+ root->pending_frame_policy().sandbox_flags;
+ EXPECT_EQ(pending_flags, expected_flags);
+ blink::WebSandboxFlags effective_flags =
+ root->effective_frame_policy().sandbox_flags;
+ EXPECT_EQ(effective_flags, expected_flags);
+}
+
} // namespace content
diff --git a/chromium/content/browser/web_contents/web_contents_user_data_unittest.cc b/chromium/content/browser/web_contents/web_contents_user_data_unittest.cc
index c7e908ab667..81b65023bd4 100644
--- a/chromium/content/browser/web_contents/web_contents_user_data_unittest.cc
+++ b/chromium/content/browser/web_contents/web_contents_user_data_unittest.cc
@@ -42,23 +42,23 @@ TEST_F(WebContentsUserDataTest, OneInstanceTwoAttachments) {
WebContents* contents = web_contents();
WebContentsAttachedClass1* class1 =
WebContentsAttachedClass1::FromWebContents(contents);
- ASSERT_EQ(NULL, class1);
+ ASSERT_EQ(nullptr, class1);
WebContentsAttachedClass2* class2 =
WebContentsAttachedClass2::FromWebContents(contents);
- ASSERT_EQ(NULL, class2);
+ ASSERT_EQ(nullptr, class2);
WebContentsAttachedClass1::CreateForWebContents(contents);
class1 = WebContentsAttachedClass1::FromWebContents(contents);
- ASSERT_TRUE(class1 != NULL);
+ ASSERT_TRUE(class1 != nullptr);
class2 = WebContentsAttachedClass2::FromWebContents(contents);
- ASSERT_EQ(NULL, class2);
+ ASSERT_EQ(nullptr, class2);
WebContentsAttachedClass2::CreateForWebContents(contents);
WebContentsAttachedClass1* class1again =
WebContentsAttachedClass1::FromWebContents(contents);
- ASSERT_TRUE(class1again != NULL);
+ ASSERT_TRUE(class1again != nullptr);
class2 = WebContentsAttachedClass2::FromWebContents(contents);
- ASSERT_TRUE(class2 != NULL);
+ ASSERT_TRUE(class2 != nullptr);
ASSERT_EQ(class1, class1again);
ASSERT_NE(static_cast<void*>(class1), static_cast<void*>(class2));
}
@@ -66,27 +66,27 @@ TEST_F(WebContentsUserDataTest, OneInstanceTwoAttachments) {
TEST_F(WebContentsUserDataTest, TwoInstancesOneAttachment) {
WebContents* contents1 = web_contents();
std::unique_ptr<WebContents> contents2(
- WebContentsTester::CreateTestWebContents(browser_context(), NULL));
+ WebContentsTester::CreateTestWebContents(browser_context(), nullptr));
WebContentsAttachedClass1* one_class =
WebContentsAttachedClass1::FromWebContents(contents1);
- ASSERT_EQ(NULL, one_class);
+ ASSERT_EQ(nullptr, one_class);
WebContentsAttachedClass1* two_class =
WebContentsAttachedClass1::FromWebContents(contents2.get());
- ASSERT_EQ(NULL, two_class);
+ ASSERT_EQ(nullptr, two_class);
WebContentsAttachedClass1::CreateForWebContents(contents1);
one_class = WebContentsAttachedClass1::FromWebContents(contents1);
- ASSERT_TRUE(one_class != NULL);
+ ASSERT_TRUE(one_class != nullptr);
two_class = WebContentsAttachedClass1::FromWebContents(contents2.get());
- ASSERT_EQ(NULL, two_class);
+ ASSERT_EQ(nullptr, two_class);
WebContentsAttachedClass1::CreateForWebContents(contents2.get());
WebContentsAttachedClass1* one_class_again =
WebContentsAttachedClass1::FromWebContents(contents1);
- ASSERT_TRUE(one_class_again != NULL);
+ ASSERT_TRUE(one_class_again != nullptr);
two_class = WebContentsAttachedClass1::FromWebContents(contents2.get());
- ASSERT_TRUE(two_class != NULL);
+ ASSERT_TRUE(two_class != nullptr);
ASSERT_EQ(one_class, one_class_again);
ASSERT_NE(one_class, two_class);
}
@@ -95,16 +95,16 @@ TEST_F(WebContentsUserDataTest, Idempotence) {
WebContents* contents = web_contents();
WebContentsAttachedClass1* clazz =
WebContentsAttachedClass1::FromWebContents(contents);
- ASSERT_EQ(NULL, clazz);
+ ASSERT_EQ(nullptr, clazz);
WebContentsAttachedClass1::CreateForWebContents(contents);
clazz = WebContentsAttachedClass1::FromWebContents(contents);
- ASSERT_TRUE(clazz != NULL);
+ ASSERT_TRUE(clazz != nullptr);
WebContentsAttachedClass1::CreateForWebContents(contents);
WebContentsAttachedClass1* class_again =
WebContentsAttachedClass1::FromWebContents(contents);
- ASSERT_TRUE(class_again != NULL);
+ ASSERT_TRUE(class_again != nullptr);
ASSERT_EQ(clazz, class_again);
}
diff --git a/chromium/content/browser/web_contents/web_contents_view.h b/chromium/content/browser/web_contents/web_contents_view.h
index e4401f85bf3..a38a936af6d 100644
--- a/chromium/content/browser/web_contents/web_contents_view.h
+++ b/chromium/content/browser/web_contents/web_contents_view.h
@@ -74,6 +74,11 @@ class WebContentsView {
// invoked, SetInitialFocus is invoked.
virtual void RestoreFocus() = 0;
+ // Focuses the first (last if |reverse| is true) element in the page.
+ // Invoked when this tab is getting the focus through tab traversal (|reverse|
+ // is true when using Shift-Tab).
+ virtual void FocusThroughTabTraversal(bool reverse) = 0;
+
// Returns the current drop data, if any.
virtual DropData* GetDropData() const = 0;
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 95f5ad6734d..b2102a103b2 100644
--- a/chromium/content/browser/web_contents/web_contents_view_android.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_android.cc
@@ -49,6 +49,22 @@ void DisplayToScreenInfo(const display::Display& display, ScreenInfo* results) {
results->is_monochrome = display.is_monochrome();
results->color_space = display.color_space();
}
+
+RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid(
+ WebContents* web_contents) {
+ RenderWidgetHostView* rwhv = NULL;
+ if (web_contents) {
+ rwhv = web_contents->GetRenderWidgetHostView();
+ if (web_contents->ShowingInterstitialPage()) {
+ rwhv = web_contents->GetInterstitialPage()
+ ->GetMainFrame()
+ ->GetRenderViewHost()
+ ->GetWidget()
+ ->GetView();
+ }
+ }
+ return static_cast<RenderWidgetHostViewAndroid*>(rwhv);
+}
}
// static
@@ -177,8 +193,7 @@ void WebContentsViewAndroid::GetScreenInfo(ScreenInfo* result) const {
}
void WebContentsViewAndroid::GetContainerBounds(gfx::Rect* out) const {
- *out = content_view_core_ ? gfx::Rect(content_view_core_->GetViewSize())
- : gfx::Rect();
+ *out = GetViewBounds();
}
void WebContentsViewAndroid::SetPageTitle(const base::string16& title) {
@@ -216,16 +231,27 @@ void WebContentsViewAndroid::RestoreFocus() {
NOTIMPLEMENTED();
}
+void WebContentsViewAndroid::FocusThroughTabTraversal(bool reverse) {
+ if (web_contents_->ShowingInterstitialPage()) {
+ web_contents_->GetInterstitialPage()->FocusThroughTabTraversal(reverse);
+ return;
+ }
+ content::RenderWidgetHostView* fullscreen_view =
+ web_contents_->GetFullscreenRenderWidgetHostView();
+ if (fullscreen_view) {
+ fullscreen_view->Focus();
+ return;
+ }
+ web_contents_->GetRenderViewHost()->SetInitialFocus(reverse);
+}
+
DropData* WebContentsViewAndroid::GetDropData() const {
NOTIMPLEMENTED();
return NULL;
}
gfx::Rect WebContentsViewAndroid::GetViewBounds() const {
- if (content_view_core_)
- return gfx::Rect(content_view_core_->GetViewSize());
-
- return gfx::Rect();
+ return gfx::Rect(view_.GetSize());
}
void WebContentsViewAndroid::CreateView(
@@ -363,11 +389,11 @@ bool WebContentsViewAndroid::OnDragEvent(const ui::DragEventAndroid& event) {
metadata.push_back(DropData::Metadata::CreateForMimeType(
DropData::Kind::STRING, mime_type));
}
- OnDragEntered(metadata, event.GetLocation(), event.GetScreenLocation());
+ OnDragEntered(metadata, event.location_f(), event.screen_location_f());
break;
}
case JNI_DragEvent::ACTION_DRAG_LOCATION:
- OnDragUpdated(event.GetLocation(), event.GetScreenLocation());
+ OnDragUpdated(event.location_f(), event.screen_location_f());
break;
case JNI_DragEvent::ACTION_DROP: {
DropData drop_data;
@@ -385,7 +411,7 @@ bool WebContentsViewAndroid::OnDragEvent(const ui::DragEventAndroid& event) {
}
}
- OnPerformDrop(&drop_data, event.GetLocation(), event.GetScreenLocation());
+ OnPerformDrop(&drop_data, event.location_f(), event.screen_location_f());
break;
}
case JNI_DragEvent::ACTION_DRAG_EXITED:
@@ -407,8 +433,8 @@ bool WebContentsViewAndroid::OnDragEvent(const ui::DragEventAndroid& event) {
void WebContentsViewAndroid::OnDragEntered(
const std::vector<DropData::Metadata>& metadata,
- const gfx::Point& location,
- const gfx::Point& screen_location) {
+ const gfx::PointF& location,
+ const gfx::PointF& screen_location) {
blink::WebDragOperationsMask allowed_ops =
static_cast<blink::WebDragOperationsMask>(blink::kWebDragOperationCopy |
blink::kWebDragOperationMove);
@@ -417,8 +443,8 @@ void WebContentsViewAndroid::OnDragEntered(
allowed_ops, 0);
}
-void WebContentsViewAndroid::OnDragUpdated(const gfx::Point& location,
- const gfx::Point& screen_location) {
+void WebContentsViewAndroid::OnDragUpdated(const gfx::PointF& location,
+ const gfx::PointF& screen_location) {
blink::WebDragOperationsMask allowed_ops =
static_cast<blink::WebDragOperationsMask>(blink::kWebDragOperationCopy |
blink::kWebDragOperationMove);
@@ -428,12 +454,12 @@ void WebContentsViewAndroid::OnDragUpdated(const gfx::Point& location,
void WebContentsViewAndroid::OnDragExited() {
web_contents_->GetRenderViewHost()->GetWidget()->DragTargetDragLeave(
- gfx::Point(), gfx::Point());
+ gfx::PointF(), gfx::PointF());
}
void WebContentsViewAndroid::OnPerformDrop(DropData* drop_data,
- const gfx::Point& location,
- const gfx::Point& screen_location) {
+ const gfx::PointF& location,
+ const gfx::PointF& screen_location) {
web_contents_->GetRenderViewHost()->GetWidget()->FilterDropData(drop_data);
web_contents_->GetRenderViewHost()->GetWidget()->DragTargetDrop(
*drop_data, location, screen_location, 0);
@@ -462,6 +488,21 @@ void WebContentsViewAndroid::TakeFocus(bool reverse) {
web_contents_->GetRenderWidgetHostView()->Focus();
}
+int WebContentsViewAndroid::GetTopControlsHeight() const {
+ auto* delegate = web_contents_->GetDelegate();
+ return delegate ? delegate->GetTopControlsHeight() : 0;
+}
+
+int WebContentsViewAndroid::GetBottomControlsHeight() const {
+ auto* delegate = web_contents_->GetDelegate();
+ return delegate ? delegate->GetBottomControlsHeight() : 0;
+}
+
+bool WebContentsViewAndroid::DoBrowserControlsShrinkBlinkSize() const {
+ auto* delegate = web_contents_->GetDelegate();
+ return delegate ? delegate->DoBrowserControlsShrinkBlinkSize() : false;
+}
+
bool WebContentsViewAndroid::OnTouchEvent(const ui::MotionEventAndroid& event) {
if (event.GetAction() == ui::MotionEventAndroid::ACTION_DOWN)
content_view_core_->OnTouchDown(event.GetJavaObject());
@@ -481,6 +522,14 @@ bool WebContentsViewAndroid::OnMouseEvent(const ui::MotionEventAndroid& event) {
return manager && manager->OnHoverEvent(event);
}
+void WebContentsViewAndroid::OnSizeChanged() {
+ auto* rwhv = ::content::GetRenderWidgetHostViewAndroid(web_contents_);
+ if (rwhv) {
+ web_contents_->SendScreenRects();
+ rwhv->WasResized();
+ }
+}
+
void WebContentsViewAndroid::OnPhysicalBackingSizeChanged() {
if (web_contents_->GetRenderWidgetHostView())
web_contents_->SendScreenRects();
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 26945c159ae..8963312926b 100644
--- a/chromium/content/browser/web_contents/web_contents_view_android.h
+++ b/chromium/content/browser/web_contents/web_contents_view_android.h
@@ -62,6 +62,7 @@ class WebContentsViewAndroid : public WebContentsView,
void SetInitialFocus() override;
void StoreFocus() override;
void RestoreFocus() override;
+ void FocusThroughTabTraversal(bool reverse) override;
DropData* GetDropData() const override;
gfx::Rect GetViewBounds() const override;
void CreateView(const gfx::Size& initial_size,
@@ -99,23 +100,27 @@ class WebContentsViewAndroid : public WebContentsView,
void GotFocus(RenderWidgetHostImpl* render_widget_host) override;
void LostFocus(RenderWidgetHostImpl* render_widget_host) override;
void TakeFocus(bool reverse) override;
+ int GetTopControlsHeight() const override;
+ int GetBottomControlsHeight() const override;
+ bool DoBrowserControlsShrinkBlinkSize() const override;
// ui::ViewClient implementation.
bool OnTouchEvent(const ui::MotionEventAndroid& event) override;
bool OnMouseEvent(const ui::MotionEventAndroid& event) override;
bool OnDragEvent(const ui::DragEventAndroid& event) override;
+ void OnSizeChanged() override;
void OnPhysicalBackingSizeChanged() override;
private:
void OnDragEntered(const std::vector<DropData::Metadata>& metadata,
- const gfx::Point& location,
- const gfx::Point& screen_location);
- void OnDragUpdated(const gfx::Point& location,
- const gfx::Point& screen_location);
+ const gfx::PointF& location,
+ const gfx::PointF& screen_location);
+ void OnDragUpdated(const gfx::PointF& location,
+ const gfx::PointF& screen_location);
void OnDragExited();
void OnPerformDrop(DropData* drop_data,
- const gfx::Point& location,
- const gfx::Point& screen_location);
+ const gfx::PointF& location,
+ const gfx::PointF& screen_location);
void OnDragEnded();
// The WebContents whose contents we display.
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 3395028a568..ee18b4dd66b 100644
--- a/chromium/content/browser/web_contents/web_contents_view_aura.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_aura.cc
@@ -15,11 +15,12 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
-#include "components/viz/common/switches.h"
+#include "components/viz/common/features.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/download/drag_download_util.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
+#include "content/browser/mus_util.h"
#include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/input/touch_selection_controller_client_aura.h"
#include "content/browser/renderer_host/overscroll_controller.h"
@@ -32,6 +33,7 @@
#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/guest_mode.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_source.h"
@@ -99,14 +101,14 @@ RenderWidgetHostViewAura* ToRenderWidgetHostViewAura(
RenderWidgetHostView* view) {
if (!view || (RenderViewHostFactory::has_factory() &&
!RenderViewHostFactory::is_real_render_view_host())) {
- return NULL; // Can't cast to RenderWidgetHostViewAura in unit tests.
+ return nullptr; // Can't cast to RenderWidgetHostViewAura in unit tests.
}
RenderViewHost* rvh = RenderViewHost::From(view->GetRenderWidgetHost());
WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
- rvh ? WebContents::FromRenderViewHost(rvh) : NULL);
+ rvh ? WebContents::FromRenderViewHost(rvh) : nullptr);
if (BrowserPluginGuest::IsGuest(web_contents))
- return NULL;
+ return nullptr;
return static_cast<RenderWidgetHostViewAura*>(view);
}
@@ -137,8 +139,8 @@ class WebDragSourceAura : public NotificationObserver {
if (dnd_client && dnd_client->IsDragDropInProgress())
dnd_client->DragCancel();
- window_ = NULL;
- contents_ = NULL;
+ window_ = nullptr;
+ contents_ = nullptr;
}
aura::Window* window() const { return window_; }
@@ -415,8 +417,7 @@ class WebContentsViewAura::WindowObserver
: public aura::WindowObserver, public aura::WindowTreeHostObserver {
public:
explicit WindowObserver(WebContentsViewAura* view)
- : view_(view),
- host_window_(NULL) {
+ : view_(view), host_window_(nullptr) {
view_->window_->AddObserver(this);
}
@@ -448,7 +449,8 @@ class WebContentsViewAura::WindowObserver
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) override {
+ const gfx::Rect& new_bounds,
+ ui::PropertyChangeReason reason) override {
if (window == host_window_ || window == view_->window_.get()) {
SendScreenRects();
if (old_bounds.origin() != new_bounds.origin()) {
@@ -463,7 +465,7 @@ class WebContentsViewAura::WindowObserver
void OnWindowDestroying(aura::Window* window) override {
if (window == host_window_) {
host_window_->RemoveObserver(this);
- host_window_ = NULL;
+ host_window_ = nullptr;
}
}
@@ -527,7 +529,9 @@ void WebContentsViewAura::InstallCreateHookForTests(
WebContentsViewAura::WebContentsViewAura(WebContentsImpl* web_contents,
WebContentsViewDelegate* delegate)
- : web_contents_(web_contents),
+ : is_mus_browser_plugin_guest_(
+ web_contents->GetBrowserPluginGuest() != nullptr && IsUsingMus()),
+ web_contents_(web_contents),
delegate_(delegate),
current_drag_op_(blink::kWebDragOperationNone),
drag_dest_delegate_(nullptr),
@@ -539,10 +543,7 @@ WebContentsViewAura::WebContentsViewAura(WebContentsImpl* web_contents,
completed_overscroll_gesture_(OVERSCROLL_NONE),
navigation_overlay_(nullptr),
init_rwhv_with_null_parent_for_testing_(false) {
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- enable_surface_synchronization_ =
- command_line.HasSwitch(switches::kEnableSurfaceSynchronization);
+ enable_surface_synchronization_ = features::IsSurfaceSynchronizationEnabled();
}
void WebContentsViewAura::SetDelegateForTesting(
@@ -584,8 +585,9 @@ void WebContentsViewAura::EndDrag(RenderWidgetHost* source_rwh,
return;
aura::Window* window = GetContentNativeView();
- gfx::Point screen_loc = display::Screen::GetScreen()->GetCursorScreenPoint();
- gfx::Point client_loc = screen_loc;
+ gfx::PointF screen_loc =
+ gfx::PointF(display::Screen::GetScreen()->GetCursorScreenPoint());
+ gfx::PointF client_loc = screen_loc;
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(window->GetRootWindow());
if (screen_position_client)
@@ -593,8 +595,8 @@ void WebContentsViewAura::EndDrag(RenderWidgetHost* source_rwh,
// |client_loc| and |screen_loc| are in the root coordinate space, for
// non-root RenderWidgetHosts they need to be transformed.
- gfx::Point transformed_point = client_loc;
- gfx::Point transformed_screen_point = screen_loc;
+ gfx::PointF transformed_point = client_loc;
+ gfx::PointF transformed_screen_point = screen_loc;
if (source_rwh && web_contents_->GetRenderWidgetHostView()) {
static_cast<RenderWidgetHostViewBase*>(
web_contents_->GetRenderWidgetHostView())
@@ -634,7 +636,7 @@ void WebContentsViewAura::InstallOverscrollControllerDelegate(
return;
}
view->overscroll_controller()->set_delegate(this);
- if (!navigation_overlay_) {
+ if (!navigation_overlay_ && !is_mus_browser_plugin_guest_) {
navigation_overlay_.reset(
new OverscrollNavigationOverlay(web_contents_, window_.get()));
}
@@ -680,17 +682,32 @@ bool WebContentsViewAura::IsValidDragTarget(
// WebContentsViewAura, WebContentsView implementation:
gfx::NativeView WebContentsViewAura::GetNativeView() const {
- return window_.get();
+ if (!is_mus_browser_plugin_guest_)
+ return window_.get();
+ DCHECK(web_contents_->GetOuterWebContents());
+ return web_contents_->GetOuterWebContents()->GetView()->GetNativeView();
}
gfx::NativeView WebContentsViewAura::GetContentNativeView() const {
- RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
- return rwhv ? rwhv->GetNativeView() : NULL;
+ if (!is_mus_browser_plugin_guest_) {
+ RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
+ return rwhv ? rwhv->GetNativeView() : nullptr;
+ }
+ DCHECK(web_contents_->GetOuterWebContents());
+ return web_contents_->GetOuterWebContents()
+ ->GetView()
+ ->GetContentNativeView();
}
gfx::NativeWindow WebContentsViewAura::GetTopLevelNativeWindow() const {
- gfx::NativeWindow window = window_->GetToplevelWindow();
- return window ? window : delegate_->GetNativeWindow();
+ if (!is_mus_browser_plugin_guest_) {
+ gfx::NativeWindow window = window_->GetToplevelWindow();
+ return window ? window : delegate_->GetNativeWindow();
+ }
+ DCHECK(web_contents_->GetOuterWebContents());
+ return web_contents_->GetOuterWebContents()
+ ->GetView()
+ ->GetTopLevelNativeWindow();
}
namespace {
@@ -708,7 +725,6 @@ void GetScreenInfoForWindow(ScreenInfo* results,
results->is_monochrome = display.is_monochrome();
results->device_scale_factor = display.device_scale_factor();
results->color_space = display.color_space();
- results->color_space.GetICCProfile(&results->icc_profile);
// The Display rotation and the ScreenInfo orientation are not the same
// angle. The former is the physical display rotation while the later is the
@@ -728,15 +744,15 @@ void GetScreenInfoForWindow(ScreenInfo* results,
// Static.
void WebContentsView::GetDefaultScreenInfo(ScreenInfo* results) {
- GetScreenInfoForWindow(results, NULL);
+ GetScreenInfoForWindow(results, nullptr);
}
void WebContentsViewAura::GetScreenInfo(ScreenInfo* screen_info) const {
- GetScreenInfoForWindow(screen_info, window_.get());
+ GetScreenInfoForWindow(screen_info, GetNativeView());
}
-void WebContentsViewAura::GetContainerBounds(gfx::Rect *out) const {
- *out = window_->GetBoundsInScreen();
+void WebContentsViewAura::GetContainerBounds(gfx::Rect* out) const {
+ *out = GetNativeView()->GetBoundsInScreen();
}
void WebContentsViewAura::SizeContents(const gfx::Size& size) {
@@ -752,12 +768,15 @@ void WebContentsViewAura::SizeContents(const gfx::Size& size) {
}
void WebContentsViewAura::Focus() {
+ if (delegate_)
+ delegate_->ResetStoredFocus();
+
if (web_contents_->GetInterstitialPage()) {
web_contents_->GetInterstitialPage()->Focus();
return;
}
- if (delegate_.get() && delegate_->Focus())
+ if (delegate_ && delegate_->Focus())
return;
RenderWidgetHostView* rwhv =
@@ -769,6 +788,9 @@ void WebContentsViewAura::Focus() {
}
void WebContentsViewAura::SetInitialFocus() {
+ if (delegate_)
+ delegate_->ResetStoredFocus();
+
if (web_contents_->FocusLocationBarByDefault())
web_contents_->SetFocusToLocationBar(false);
else
@@ -781,8 +803,26 @@ void WebContentsViewAura::StoreFocus() {
}
void WebContentsViewAura::RestoreFocus() {
+ if (delegate_ && delegate_->RestoreFocus())
+ return;
+ SetInitialFocus();
+}
+
+void WebContentsViewAura::FocusThroughTabTraversal(bool reverse) {
if (delegate_)
- delegate_->RestoreFocus();
+ delegate_->ResetStoredFocus();
+
+ if (web_contents_->ShowingInterstitialPage()) {
+ web_contents_->GetInterstitialPage()->FocusThroughTabTraversal(reverse);
+ return;
+ }
+ content::RenderWidgetHostView* fullscreen_view =
+ web_contents_->GetFullscreenRenderWidgetHostView();
+ if (fullscreen_view) {
+ fullscreen_view->Focus();
+ return;
+ }
+ web_contents_->GetRenderViewHost()->SetInitialFocus(reverse);
}
DropData* WebContentsViewAura::GetDropData() const {
@@ -790,20 +830,13 @@ DropData* WebContentsViewAura::GetDropData() const {
}
gfx::Rect WebContentsViewAura::GetViewBounds() const {
- return window_->GetBoundsInScreen();
+ return GetNativeView()->GetBoundsInScreen();
}
-////////////////////////////////////////////////////////////////////////////////
-// WebContentsViewAura, WebContentsView implementation:
-
-void WebContentsViewAura::CreateView(
- const gfx::Size& initial_size, gfx::NativeView context) {
- // NOTE: we ignore |initial_size| since in some cases it's wrong (such as
- // if the bookmark bar is not shown and you create a new tab). The right
- // value is set shortly after this, so its safe to ignore.
-
+void WebContentsViewAura::CreateAuraWindow(aura::Window* context) {
DCHECK(aura::Env::GetInstanceDontCreate());
- window_ = base::MakeUnique<aura::Window>(this);
+ DCHECK(!window_);
+ window_ = std::make_unique<aura::Window>(this);
window_->set_owned_by_parent(false);
window_->SetType(aura::client::WINDOW_TYPE_CONTROL);
window_->SetName("WebContentsViewAura");
@@ -831,6 +864,19 @@ void WebContentsViewAura::CreateView(
// 2) guests' window bounds are supposed to come from its embedder.
if (!BrowserPluginGuest::IsGuest(web_contents_))
window_observer_.reset(new WindowObserver(this));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WebContentsViewAura, WebContentsView implementation:
+
+void WebContentsViewAura::CreateView(const gfx::Size& initial_size,
+ gfx::NativeView context) {
+ // NOTE: we ignore |initial_size| since in some cases it's wrong (such as
+ // if the bookmark bar is not shown and you create a new tab). The right
+ // value is set shortly after this, so its safe to ignore.
+
+ if (!is_mus_browser_plugin_guest_)
+ CreateAuraWindow(context);
// delegate_->GetDragDestDelegate() creates a new delegate on every call.
// Hence, we save a reference to it locally. Similar model is used on other
@@ -857,7 +903,8 @@ RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
? g_create_render_widget_host_view(render_widget_host,
is_guest_view_hack)
: new RenderWidgetHostViewAura(render_widget_host, is_guest_view_hack,
- enable_surface_synchronization_);
+ enable_surface_synchronization_,
+ is_mus_browser_plugin_guest_);
view->InitAsChild(GetRenderWidgetHostViewParent());
RenderWidgetHostImpl* host_impl =
@@ -866,6 +913,9 @@ RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
if (!host_impl->is_hidden())
view->Show();
+ if (is_mus_browser_plugin_guest_)
+ return view;
+
// We listen to drag drop events in the newly created view's window.
aura::client::SetDragDropDelegate(view->GetNativeView(), this);
@@ -880,12 +930,17 @@ RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForPopupWidget(
RenderWidgetHost* render_widget_host) {
+ // Popups are not created as embedded windows in mus, so
+ // |is_mus_browser_plugin_guest| is always false for them.
+ const bool is_mus_browser_plugin_guest = false;
return new RenderWidgetHostViewAura(render_widget_host, false,
- enable_surface_synchronization_);
+ enable_surface_synchronization_,
+ is_mus_browser_plugin_guest);
}
void WebContentsViewAura::SetPageTitle(const base::string16& title) {
- window_->SetTitle(title);
+ if (!is_mus_browser_plugin_guest_)
+ window_->SetTitle(title);
}
void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) {
@@ -906,8 +961,14 @@ void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) {
if (!enabled) {
navigation_overlay_.reset();
} else if (!navigation_overlay_) {
- navigation_overlay_.reset(
- new OverscrollNavigationOverlay(web_contents_, window_.get()));
+ if (is_mus_browser_plugin_guest_) {
+ // |is_mus_browser_plugin_guest_| implies this WebContentsViewAura is
+ // held inside a WebContentsViewGuest, which does not forward this call.
+ NOTREACHED();
+ } else {
+ navigation_overlay_.reset(
+ new OverscrollNavigationOverlay(web_contents_, window_.get()));
+ }
}
}
@@ -1113,7 +1174,7 @@ bool WebContentsViewAura::CanFocus() {
// this window can handle key events.
RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
web_contents_->GetRenderWidgetHostView());
- if (view != NULL && !view->IsClosing())
+ if (view != nullptr && !view->IsClosing())
return true;
return false;
@@ -1179,11 +1240,11 @@ void WebContentsViewAura::OnMouseEvent(ui::MouseEvent* event) {
// WebContentsViewAura, aura::client::DragDropDelegate implementation:
void WebContentsViewAura::OnDragEntered(const ui::DropTargetEvent& event) {
- gfx::Point transformed_pt;
+ gfx::PointF transformed_pt;
RenderWidgetHostImpl* target_rwh =
web_contents_->GetInputEventRouter()->GetRenderWidgetHostAtPoint(
web_contents_->GetRenderViewHost()->GetWidget()->GetView(),
- event.location(), &transformed_pt);
+ event.location_f(), &transformed_pt);
if (!IsValidDragTarget(target_rwh))
return;
@@ -1201,14 +1262,14 @@ void WebContentsViewAura::OnDragEntered(const ui::DropTargetEvent& event) {
if (web_contents_->GetDelegate() &&
!web_contents_->GetDelegate()->CanDragEnter(
web_contents_, *current_drop_data_.get(), op)) {
- current_drop_data_.reset(NULL);
+ current_drop_data_.reset(nullptr);
return;
}
if (drag_dest_delegate_)
drag_dest_delegate_->DragInitialize(web_contents_);
- gfx::Point screen_pt = display::Screen::GetScreen()->GetCursorScreenPoint();
+ gfx::PointF screen_pt(display::Screen::GetScreen()->GetCursorScreenPoint());
current_rwh_for_drag_->DragTargetDragEnter(
*current_drop_data_, transformed_pt, screen_pt, op,
ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
@@ -1220,25 +1281,26 @@ void WebContentsViewAura::OnDragEntered(const ui::DropTargetEvent& event) {
}
int WebContentsViewAura::OnDragUpdated(const ui::DropTargetEvent& event) {
- gfx::Point transformed_pt;
+ gfx::PointF transformed_pt;
RenderWidgetHostImpl* target_rwh =
web_contents_->GetInputEventRouter()->GetRenderWidgetHostAtPoint(
web_contents_->GetRenderViewHost()->GetWidget()->GetView(),
- event.location(), &transformed_pt);
+ event.location_f(), &transformed_pt);
if (!IsValidDragTarget(target_rwh))
return ui::DragDropTypes::DRAG_NONE;
- gfx::Point screen_pt = event.root_location();
+ gfx::PointF screen_pt = event.root_location_f();
if (target_rwh != current_rwh_for_drag_.get()) {
if (current_rwh_for_drag_) {
- gfx::Point transformed_leave_point = event.location();
- gfx::Point transformed_screen_point = screen_pt;
+ gfx::PointF transformed_leave_point = event.location_f();
+ gfx::PointF transformed_screen_point = screen_pt;
static_cast<RenderWidgetHostViewBase*>(
web_contents_->GetRenderWidgetHostView())
->TransformPointToCoordSpaceForView(
- event.location(), static_cast<RenderWidgetHostViewBase*>(
- current_rwh_for_drag_->GetView()),
+ event.location_f(),
+ static_cast<RenderWidgetHostViewBase*>(
+ current_rwh_for_drag_->GetView()),
&transformed_leave_point);
static_cast<RenderWidgetHostViewBase*>(
web_contents_->GetRenderWidgetHostView())
@@ -1274,7 +1336,7 @@ void WebContentsViewAura::OnDragExited() {
}
if (current_rwh_for_drag_) {
- current_rwh_for_drag_->DragTargetDragLeave(gfx::Point(), gfx::Point());
+ current_rwh_for_drag_->DragTargetDragLeave(gfx::PointF(), gfx::PointF());
current_rwh_for_drag_.reset();
}
@@ -1285,16 +1347,16 @@ void WebContentsViewAura::OnDragExited() {
}
int WebContentsViewAura::OnPerformDrop(const ui::DropTargetEvent& event) {
- gfx::Point transformed_pt;
+ gfx::PointF transformed_pt;
RenderWidgetHostImpl* target_rwh =
web_contents_->GetInputEventRouter()->GetRenderWidgetHostAtPoint(
web_contents_->GetRenderViewHost()->GetWidget()->GetView(),
- event.location(), &transformed_pt);
+ event.location_f(), &transformed_pt);
if (!IsValidDragTarget(target_rwh))
return ui::DragDropTypes::DRAG_NONE;
- gfx::Point screen_pt = display::Screen::GetScreen()->GetCursorScreenPoint();
+ gfx::PointF screen_pt(display::Screen::GetScreen()->GetCursorScreenPoint());
if (target_rwh != current_rwh_for_drag_.get()) {
if (current_rwh_for_drag_)
current_rwh_for_drag_->DragTargetDragLeave(transformed_pt, screen_pt);
@@ -1306,7 +1368,7 @@ int WebContentsViewAura::OnPerformDrop(const ui::DropTargetEvent& event) {
target_rwh->DragTargetDrop(
*current_drop_data_, transformed_pt,
- display::Screen::GetScreen()->GetCursorScreenPoint(),
+ gfx::PointF(display::Screen::GetScreen()->GetCursorScreenPoint()),
ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
if (drag_dest_delegate_)
drag_dest_delegate_->OnDrop();
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 359032e6634..7b2078f53dc 100644
--- a/chromium/content/browser/web_contents/web_contents_view_aura.h
+++ b/chromium/content/browser/web_contents/web_contents_view_aura.h
@@ -99,6 +99,9 @@ class CONTENT_EXPORT WebContentsViewAura
// crbug.com/666858.
bool IsValidDragTarget(RenderWidgetHostImpl* target_rwh) const;
+ // Called from CreateView() to create |window_|.
+ void CreateAuraWindow(aura::Window* context);
+
// Overridden from WebContentsView:
gfx::NativeView GetNativeView() const override;
gfx::NativeView GetContentNativeView() const override;
@@ -110,6 +113,7 @@ class CONTENT_EXPORT WebContentsViewAura
void SetInitialFocus() override;
void StoreFocus() override;
void RestoreFocus() override;
+ void FocusThroughTabTraversal(bool reverse) override;
DropData* GetDropData() const override;
gfx::Rect GetViewBounds() const override;
void CreateView(const gfx::Size& initial_size,
@@ -195,8 +199,11 @@ class CONTENT_EXPORT WebContentsViewAura
FRIEND_TEST_ALL_PREFIXES(WebContentsViewAuraTest, EnableDisableOverscroll);
+ const bool is_mus_browser_plugin_guest_;
+
bool enable_surface_synchronization_ = false;
+ // NOTE: this is null when running in mus and |is_mus_browser_plugin_guest_|.
std::unique_ptr<aura::Window> window_;
std::unique_ptr<WindowObserver> window_observer_;
diff --git a/chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc b/chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc
index 14e57824f7e..c43c8de5c52 100644
--- a/chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc
@@ -70,16 +70,15 @@ class ScreenshotTracker : public NavigationEntryScreenshotManager {
public:
explicit ScreenshotTracker(NavigationControllerImpl* controller)
: NavigationEntryScreenshotManager(controller),
- screenshot_taken_for_(NULL),
- waiting_for_screenshots_(0) {
- }
+ screenshot_taken_for_(nullptr),
+ waiting_for_screenshots_(0) {}
~ScreenshotTracker() override {}
RenderViewHost* screenshot_taken_for() { return screenshot_taken_for_; }
void Reset() {
- screenshot_taken_for_ = NULL;
+ screenshot_taken_for_ = nullptr;
screenshot_set_.clear();
}
@@ -173,9 +172,7 @@ class InputEventMessageFilterWaitsForAcks : public BrowserMessageFilter {
class WebContentsViewAuraTest : public ContentBrowserTest {
public:
- WebContentsViewAuraTest()
- : screenshot_manager_(NULL) {
- }
+ WebContentsViewAuraTest() : screenshot_manager_(nullptr) {}
// Executes the javascript synchronously and makes sure the returned value is
// freed properly.
@@ -473,9 +470,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
gesture_scroll_update.data.scroll_update.delta_units =
blink::WebGestureEvent::ScrollUnits::kPrecisePixels;
gesture_scroll_update.data.scroll_update.delta_y = 0.f;
- float horiz_threshold =
- GetOverscrollConfig(OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN);
- gesture_scroll_update.data.scroll_update.delta_x = horiz_threshold + 1;
+ float start_threshold =
+ GetOverscrollConfig(OverscrollConfig::THRESHOLD_START_TOUCHSCREEN);
+ gesture_scroll_update.data.scroll_update.delta_x = start_threshold + 1;
GetRenderWidgetHost()->ForwardGestureEvent(gesture_scroll_update);
// Wait for the overscroll gesture to start and then allow some time for the
@@ -751,7 +748,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
WaitForLoadStop(web_contents);
screenshot_manager()->WaitUntilScreenshotIsReady();
- EXPECT_EQ(NULL, screenshot_manager()->screenshot_taken_for());
+ EXPECT_EQ(nullptr, screenshot_manager()->screenshot_taken_for());
}
// Tests that navigations resulting from reloads, history.replaceState,
@@ -797,7 +794,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
DISABLED_ContentWindowReparent) {
ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
- std::unique_ptr<aura::Window> window(new aura::Window(NULL));
+ std::unique_ptr<aura::Window> window(new aura::Window(nullptr));
window->Init(ui::LAYER_NOT_DRAWN);
WebContentsImpl* web_contents =
@@ -922,7 +919,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, HideContentOnParenHide) {
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, WebContentsViewReparent) {
ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/overscroll_navigation.html"));
- std::unique_ptr<aura::Window> window(new aura::Window(NULL));
+ std::unique_ptr<aura::Window> window(new aura::Window(nullptr));
window->Init(ui::LAYER_NOT_DRAWN);
RenderWidgetHostViewAura* rwhva =
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 e1aca335ede..e1db175c25c 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
@@ -60,10 +60,12 @@ void WebContentsViewChildFrame::GetScreenInfo(ScreenInfo* screen_info) const {
// to happen in RenderWidgetHostViewChildFrame, but it seems like the right
// thing to do. We should keep an eye on this in case the else-clause below
// causes problems.
- if (web_contents_->GetOuterWebContents())
- GetOuterView()->GetScreenInfo(screen_info);
- else
+ RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
+ if (!rwhv) {
WebContentsView::GetDefaultScreenInfo(screen_info);
+ return;
+ }
+ rwhv->GetScreenInfo(screen_info);
}
void WebContentsViewChildFrame::GetContainerBounds(gfx::Rect* out) const {
@@ -146,6 +148,10 @@ void WebContentsViewChildFrame::StoreFocus() {
NOTREACHED();
}
+void WebContentsViewChildFrame::FocusThroughTabTraversal(bool reverse) {
+ NOTREACHED();
+}
+
DropData* WebContentsViewChildFrame::GetDropData() const {
NOTREACHED();
return nullptr;
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 18d45eea524..ca3c586f9f8 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
@@ -34,6 +34,7 @@ class WebContentsViewChildFrame : public WebContentsView,
void SetInitialFocus() override;
void StoreFocus() override;
void RestoreFocus() override;
+ void FocusThroughTabTraversal(bool reverse) override;
DropData* GetDropData() const override;
gfx::Rect GetViewBounds() const override;
void CreateView(const gfx::Size& initial_size,
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 025686922ad..f1370d294ef 100644
--- a/chromium/content/browser/web_contents/web_contents_view_guest.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_guest.cc
@@ -12,6 +12,7 @@
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h"
+#include "content/browser/mus_util.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -55,7 +56,7 @@ gfx::NativeView WebContentsViewGuest::GetNativeView() const {
gfx::NativeView WebContentsViewGuest::GetContentNativeView() const {
RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
if (!rwhv)
- return NULL;
+ return nullptr;
return rwhv->GetNativeView();
}
@@ -77,14 +78,17 @@ 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.
- parent_view->GetNativeView()->AddChild(platform_view_->GetNativeView());
+ if (!IsUsingMus())
+ parent_view->GetNativeView()->AddChild(platform_view_->GetNativeView());
#endif // defined(USE_AURA)
}
void WebContentsViewGuest::OnGuestDetached(WebContentsView* old_parent_view) {
#if defined(USE_AURA)
- old_parent_view->GetNativeView()->RemoveChild(
- platform_view_->GetNativeView());
+ if (!IsUsingMus()) {
+ old_parent_view->GetNativeView()->RemoveChild(
+ platform_view_->GetNativeView());
+ }
#endif // defined(USE_AURA)
}
@@ -198,9 +202,13 @@ void WebContentsViewGuest::StoreFocus() {
platform_view_->StoreFocus();
}
+void WebContentsViewGuest::FocusThroughTabTraversal(bool reverse) {
+ platform_view_->FocusThroughTabTraversal(reverse);
+}
+
DropData* WebContentsViewGuest::GetDropData() const {
NOTIMPLEMENTED();
- return NULL;
+ return nullptr;
}
void WebContentsViewGuest::UpdateDragCursor(WebDragOperation operation) {
@@ -216,6 +224,7 @@ void WebContentsViewGuest::UpdateDragCursor(WebDragOperation operation) {
void WebContentsViewGuest::ShowContextMenu(RenderFrameHost* render_frame_host,
const ContextMenuParams& params) {
+ DCHECK(platform_view_delegate_view_);
platform_view_delegate_view_->ShowContextMenu(render_frame_host, params);
}
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 464ea8f780e..c04fe9bc23c 100644
--- a/chromium/content/browser/web_contents/web_contents_view_guest.h
+++ b/chromium/content/browser/web_contents/web_contents_view_guest.h
@@ -52,6 +52,7 @@ class WebContentsViewGuest : public WebContentsView,
void SetInitialFocus() override;
void StoreFocus() override;
void RestoreFocus() override;
+ void FocusThroughTabTraversal(bool reverse) override;
DropData* GetDropData() const override;
gfx::Rect GetViewBounds() const override;
void CreateView(const gfx::Size& initial_size,
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 12675d077c8..95ba5f05e4f 100644
--- a/chromium/content/browser/web_contents/web_contents_view_mac.h
+++ b/chromium/content/browser/web_contents/web_contents_view_mac.h
@@ -21,7 +21,6 @@
#include "ui/base/cocoa/base_view.h"
#include "ui/gfx/geometry/size.h"
-@class FocusTracker;
@class WebDragDest;
@class WebDragSource;
@@ -82,6 +81,7 @@ class WebContentsViewMac : public WebContentsView,
void SetInitialFocus() override;
void StoreFocus() override;
void RestoreFocus() override;
+ void FocusThroughTabTraversal(bool reverse) override;
DropData* GetDropData() const override;
gfx::Rect GetViewBounds() const override;
void SetAllowOtherViews(bool allow) override;
@@ -151,10 +151,6 @@ class WebContentsViewMac : public WebContentsView,
// The Cocoa NSView that lives in the view hierarchy.
base::scoped_nsobject<WebContentsViewCocoa> cocoa_view_;
- // Keeps track of which NSView has focus so we can restore the focus when
- // focus returns.
- base::scoped_nsobject<FocusTracker> focus_tracker_;
-
// Our optional delegate.
std::unique_ptr<WebContentsViewDelegate> delegate_;
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 abcbb302f41..2c5dd9e99e6 100644
--- a/chromium/content/browser/web_contents/web_contents_view_mac.mm
+++ b/chromium/content/browser/web_contents/web_contents_view_mac.mm
@@ -22,13 +22,13 @@
#import "content/browser/web_contents/web_drag_dest_mac.h"
#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/web_contents_delegate.h"
#include "content/public/browser/web_contents_view_delegate.h"
#include "content/public/common/content_switches.h"
#include "skia/ext/skia_utils_mac.h"
#import "third_party/mozilla/NSPasteboard+Utils.h"
#include "ui/base/clipboard/custom_data_helper.h"
-#import "ui/base/cocoa/focus_tracker.h"
#include "ui/base/dragdrop/cocoa_dnd_util.h"
#include "ui/display/screen.h"
#include "ui/gfx/image/image_skia_util_mac.h"
@@ -90,7 +90,7 @@ content::ScreenInfo GetNSViewScreenInfo(NSView* view) {
content::ScreenInfo results;
results.device_scale_factor = static_cast<int>(display.device_scale_factor());
results.color_space = display.color_space();
- results.color_space.GetICCProfile(&results.icc_profile);
+ results.icc_profile = gfx::ICCProfile::FromCacheMac(display.color_space());
results.depth = display.color_depth();
results.depth_per_component = display.depth_per_component();
results.is_monochrome = display.is_monochrome();
@@ -222,6 +222,9 @@ gfx::NativeView WebContentsViewMac::GetNativeViewForFocus() const {
}
void WebContentsViewMac::Focus() {
+ if (delegate())
+ delegate()->ResetStoredFocus();
+
gfx::NativeView native_view = GetNativeViewForFocus();
NSWindow* window = [native_view window];
[window makeFirstResponder:native_view];
@@ -231,6 +234,9 @@ void WebContentsViewMac::Focus() {
}
void WebContentsViewMac::SetInitialFocus() {
+ if (delegate())
+ delegate()->ResetStoredFocus();
+
if (web_contents_->FocusLocationBarByDefault())
web_contents_->SetFocusToLocationBar(false);
else
@@ -238,28 +244,37 @@ void WebContentsViewMac::SetInitialFocus() {
}
void WebContentsViewMac::StoreFocus() {
- gfx::NativeView native_view = GetNativeViewForFocus();
- // We're explicitly being asked to store focus, so don't worry if there's
- // already a view saved.
- focus_tracker_.reset(
- [[FocusTracker alloc] initWithWindow:[native_view window]]);
+ if (delegate())
+ delegate()->StoreFocus();
}
void WebContentsViewMac::RestoreFocus() {
- gfx::NativeView native_view = GetNativeViewForFocus();
- // TODO(avi): Could we be restoring a view that's no longer in the key view
- // chain?
- if (!(focus_tracker_.get() &&
- [focus_tracker_ restoreFocusInWindow:[native_view window]])) {
- // Fall back to the default focus behavior if we could not restore focus.
- // TODO(shess): If location-bar gets focus by default, this will
- // select-all in the field. If there was a specific selection in
- // the field when we navigated away from it, we should restore
- // that selection.
- SetInitialFocus();
- }
+ if (delegate() && delegate()->RestoreFocus())
+ return;
- focus_tracker_.reset(nil);
+ // Fall back to the default focus behavior if we could not restore focus.
+ // TODO(shess): If location-bar gets focus by default, this will
+ // select-all in the field. If there was a specific selection in
+ // the field when we navigated away from it, we should restore
+ // that selection.
+ SetInitialFocus();
+}
+
+void WebContentsViewMac::FocusThroughTabTraversal(bool reverse) {
+ if (delegate())
+ delegate()->ResetStoredFocus();
+
+ if (web_contents_->ShowingInterstitialPage()) {
+ web_contents_->GetInterstitialPage()->FocusThroughTabTraversal(reverse);
+ return;
+ }
+ content::RenderWidgetHostView* fullscreen_view =
+ web_contents_->GetFullscreenRenderWidgetHostView();
+ if (fullscreen_view) {
+ fullscreen_view->Focus();
+ return;
+ }
+ web_contents_->GetRenderViewHost()->SetInitialFocus(reverse);
}
DropData* WebContentsViewMac::GetDropData() const {
@@ -277,6 +292,14 @@ void WebContentsViewMac::GotFocus(RenderWidgetHostImpl* render_widget_host) {
// This is called when the renderer asks us to take focus back (i.e., it has
// iterated past the last focusable element on the page).
void WebContentsViewMac::TakeFocus(bool reverse) {
+ if (delegate())
+ delegate()->ResetStoredFocus();
+
+ if (web_contents_->GetDelegate() &&
+ web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse))
+ return;
+ if (delegate() && delegate()->TakeFocus(reverse))
+ return;
if (reverse) {
[[cocoa_view_ window] selectPreviousKeyView:cocoa_view_.get()];
} else {
diff --git a/chromium/content/browser/web_contents/web_drag_dest_mac.h b/chromium/content/browser/web_contents/web_drag_dest_mac.h
index da4427bca57..c81c2a89ab8 100644
--- a/chromium/content/browser/web_contents/web_drag_dest_mac.h
+++ b/chromium/content/browser/web_contents/web_drag_dest_mac.h
@@ -2,6 +2,9 @@
// 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_DRAG_DEST_MAC_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_DEST_MAC_H_
+
#import <Cocoa/Cocoa.h>
#include <memory>
@@ -10,7 +13,7 @@
#include "content/browser/loader/global_routing_id.h"
#include "content/common/content_export.h"
#include "content/public/common/drop_data.h"
-#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/point_f.h"
namespace content {
class RenderViewHost;
@@ -87,7 +90,7 @@ CONTENT_EXPORT
// Helper to call WebWidgetHostInputEventRouter::GetRenderWidgetHostAtPoint().
- (content::RenderWidgetHostImpl*)
GetRenderWidgetHostAtPoint:(const NSPoint&)viewPoint
- transformedPt:(gfx::Point*)transformedPt;
+ transformedPt:(gfx::PointF*)transformedPt;
// Sets |dragStartProcessID_| and |dragStartViewID_|.
- (void)setDragStartTrackersForProcess:(int)processID;
@@ -114,3 +117,5 @@ GetRenderWidgetHostAtPoint:(const NSPoint&)viewPoint
- (NSPoint)flipWindowPointToScreen:(const NSPoint&)windowPoint
view:(NSView*)view;
@end
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_DEST_MAC_H_
diff --git a/chromium/content/browser/web_contents/web_drag_dest_mac.mm b/chromium/content/browser/web_contents/web_drag_dest_mac.mm
index ff2c964a68d..35c4ee35242 100644
--- a/chromium/content/browser/web_contents/web_drag_dest_mac.mm
+++ b/chromium/content/browser/web_contents/web_drag_dest_mac.mm
@@ -143,7 +143,7 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
NSPoint windowPoint = [info draggingLocation];
NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view];
NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view];
- gfx::Point transformedPt;
+ gfx::PointF transformedPt;
if (!webContents_->GetRenderWidgetHostView()) {
// TODO(ekaramad, paulmeyer): Find a better way than toggling |canceled_|.
// This could happen when the renderer process for the top-level RWH crashes
@@ -192,7 +192,7 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
dropData_.swap(dropData);
currentRWHForDrag_->DragTargetDragEnter(
- *dropData_, transformedPt, gfx::Point(screenPoint.x, screenPoint.y),
+ *dropData_, transformedPt, gfx::PointF(screenPoint.x, screenPoint.y),
static_cast<WebDragOperationsMask>(mask), GetModifierFlags());
// We won't know the true operation (whether the drag is allowed) until we
@@ -216,7 +216,7 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
delegate_->OnDragLeave();
if (currentRWHForDrag_) {
- currentRWHForDrag_->DragTargetDragLeave(gfx::Point(), gfx::Point());
+ currentRWHForDrag_->DragTargetDragLeave(gfx::PointF(), gfx::PointF());
currentRWHForDrag_.reset();
}
dropData_.reset();
@@ -234,7 +234,7 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
NSPoint windowPoint = [info draggingLocation];
NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view];
NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view];
- gfx::Point transformedPt;
+ gfx::PointF transformedPt;
content::RenderWidgetHostImpl* targetRWH =
[self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt];
@@ -245,9 +245,9 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
// per drag, even without the drag ever leaving the window.
if (targetRWH != currentRWHForDrag_.get()) {
if (currentRWHForDrag_) {
- gfx::Point transformedLeavePoint = gfx::Point(viewPoint.x, viewPoint.y);
- gfx::Point transformedScreenPoint =
- gfx::Point(screenPoint.x, screenPoint.y);
+ gfx::PointF transformedLeavePoint = gfx::PointF(viewPoint.x, viewPoint.y);
+ gfx::PointF transformedScreenPoint =
+ gfx::PointF(screenPoint.x, screenPoint.y);
content::RenderWidgetHostViewBase* rootView =
static_cast<content::RenderWidgetHostViewBase*>(
webContents_->GetRenderWidgetHostView());
@@ -275,7 +275,7 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
NSDragOperation mask = [info draggingSourceOperationMask];
targetRWH->DragTargetDragOver(
- transformedPt, gfx::Point(screenPoint.x, screenPoint.y),
+ transformedPt, gfx::PointF(screenPoint.x, screenPoint.y),
static_cast<WebDragOperationsMask>(mask), GetModifierFlags());
if (delegate_)
@@ -291,7 +291,7 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
NSPoint windowPoint = [info draggingLocation];
NSPoint viewPoint = [self flipWindowPointToView:windowPoint view:view];
NSPoint screenPoint = [self flipWindowPointToScreen:windowPoint view:view];
- gfx::Point transformedPt;
+ gfx::PointF transformedPt;
content::RenderWidgetHostImpl* targetRWH =
[self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt];
@@ -301,7 +301,7 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
if (targetRWH != currentRWHForDrag_.get()) {
if (currentRWHForDrag_)
currentRWHForDrag_->DragTargetDragLeave(
- transformedPt, gfx::Point(screenPoint.x, screenPoint.y));
+ transformedPt, gfx::PointF(screenPoint.x, screenPoint.y));
[self draggingEntered:info view:view];
}
@@ -326,7 +326,7 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
currentRVH_ = NULL;
targetRWH->DragTargetDrop(*dropData_, transformedPt,
- gfx::Point(screenPoint.x, screenPoint.y),
+ gfx::PointF(screenPoint.x, screenPoint.y),
GetModifierFlags());
dropData_.reset();
@@ -336,10 +336,10 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
- (content::RenderWidgetHostImpl*)
GetRenderWidgetHostAtPoint:(const NSPoint&)viewPoint
- transformedPt:(gfx::Point*)transformedPt {
+ transformedPt:(gfx::PointF*)transformedPt {
return webContents_->GetInputEventRouter()->GetRenderWidgetHostAtPoint(
webContents_->GetRenderViewHost()->GetWidget()->GetView(),
- gfx::Point(viewPoint.x, viewPoint.y), transformedPt);
+ gfx::PointF(viewPoint.x, viewPoint.y), transformedPt);
}
- (void)setDragStartTrackersForProcess:(int)processID {
diff --git a/chromium/content/browser/web_contents/web_drag_source_mac.h b/chromium/content/browser/web_contents/web_drag_source_mac.h
index 0bc51eb9292..a488e75a251 100644
--- a/chromium/content/browser/web_contents/web_drag_source_mac.h
+++ b/chromium/content/browser/web_contents/web_drag_source_mac.h
@@ -2,6 +2,9 @@
// 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_DRAG_SOURCE_MAC_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_SOURCE_MAC_H_
+
#import <Cocoa/Cocoa.h>
#include <memory>
@@ -101,3 +104,5 @@ CONTENT_EXPORT
- (NSString*)dragPromisedFileTo:(NSString*)path;
@end
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_WEB_DRAG_SOURCE_MAC_H_
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 60d0b1a9068..d8dd5f43252 100644
--- a/chromium/content/browser/web_contents/web_drag_source_mac.mm
+++ b/chromium/content/browser/web_contents/web_drag_source_mac.mm
@@ -244,6 +244,12 @@ void PromiseWriterHelper(const DropData& drop_data,
contents_->SystemDragEnded(dragStartRWH_.get());
+ if (dragImage_) {
+ screenPoint.x += imageOffset_.x;
+ // Deal with Cocoa's flipped coordinate system.
+ screenPoint.y += [dragImage_.get() size].height - imageOffset_.y;
+ }
+
// Convert |screenPoint| to view coordinates and flip it.
NSPoint localPoint = NSZeroPoint;
if ([contentsView_ window])
@@ -262,8 +268,9 @@ void PromiseWriterHelper(const DropData& drop_data,
// |localPoint| and |screenPoint| are in the root coordinate space, for
// non-root RenderWidgetHosts they need to be transformed.
- gfx::Point transformedPoint = gfx::Point(localPoint.x, localPoint.y);
- gfx::Point transformedScreenPoint = gfx::Point(screenPoint.x, screenPoint.y);
+ gfx::PointF transformedPoint = gfx::PointF(localPoint.x, localPoint.y);
+ gfx::PointF transformedScreenPoint =
+ gfx::PointF(screenPoint.x, screenPoint.y);
if (dragStartRWH_ && contents_->GetRenderWidgetHostView()) {
content::RenderWidgetHostViewBase* contentsViewBase =
static_cast<content::RenderWidgetHostViewBase*>(
@@ -272,10 +279,10 @@ void PromiseWriterHelper(const DropData& drop_data,
static_cast<content::RenderWidgetHostViewBase*>(
dragStartRWH_->GetView());
contentsViewBase->TransformPointToCoordSpaceForView(
- gfx::Point(localPoint.x, localPoint.y), dragStartViewBase,
+ gfx::PointF(localPoint.x, localPoint.y), dragStartViewBase,
&transformedPoint);
contentsViewBase->TransformPointToCoordSpaceForView(
- gfx::Point(screenPoint.x, screenPoint.y), dragStartViewBase,
+ gfx::PointF(screenPoint.x, screenPoint.y), dragStartViewBase,
&transformedScreenPoint);
}
diff --git a/chromium/content/browser/web_contents_binding_set_browsertest.cc b/chromium/content/browser/web_contents_binding_set_browsertest.cc
index ba905185220..3d9ba3d2250 100644
--- a/chromium/content/browser/web_contents_binding_set_browsertest.cc
+++ b/chromium/content/browser/web_contents_binding_set_browsertest.cc
@@ -80,7 +80,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsBindingSetBrowserTest, OverrideForTesting) {
WebContentsBindingSet::GetForWebContents<
mojom::BrowserAssociatedInterfaceTestDriver>(web_contents)
->SetBinderForTesting(
- base::MakeUnique<TestInterfaceBinder>(run_loop.QuitClosure()));
+ std::make_unique<TestInterfaceBinder>(run_loop.QuitClosure()));
// Simulate an inbound request for the test interface. This should get routed
// to the overriding binder and allow the test to complete.
@@ -89,7 +89,8 @@ IN_PROC_BROWSER_TEST_F(WebContentsBindingSetBrowserTest, OverrideForTesting) {
->OnAssociatedInterfaceRequest(
web_contents->GetMainFrame(),
mojom::BrowserAssociatedInterfaceTestDriver::Name_,
- mojo::MakeIsolatedRequest(&override_client).PassHandle());
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&override_client)
+ .PassHandle());
run_loop.Run();
}
@@ -106,7 +107,8 @@ IN_PROC_BROWSER_TEST_F(WebContentsBindingSetBrowserTest, CloseOnFrameDeletion) {
->OnAssociatedInterfaceRequest(
web_contents->GetMainFrame(),
mojom::WebContentsFrameBindingSetTest::Name_,
- mojo::MakeIsolatedRequest(&override_client).PassHandle());
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&override_client)
+ .PassHandle());
base::RunLoop run_loop;
override_client.set_connection_error_handler(run_loop.QuitClosure());
diff --git a/chromium/content/browser/webauth/DEPS b/chromium/content/browser/webauth/DEPS
new file mode 100644
index 00000000000..8d0f2ca5aa4
--- /dev/null
+++ b/chromium/content/browser/webauth/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+device",
+]
diff --git a/chromium/content/browser/webauth/attestation_object.cc b/chromium/content/browser/webauth/attestation_object.cc
new file mode 100644
index 00000000000..12234091143
--- /dev/null
+++ b/chromium/content/browser/webauth/attestation_object.cc
@@ -0,0 +1,40 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/webauth/attestation_object.h"
+
+#include <utility>
+
+#include "content/browser/webauth/attestation_statement.h"
+#include "content/browser/webauth/cbor/cbor_writer.h"
+
+namespace content {
+
+namespace {
+constexpr char kAuthDataKey[] = "authData";
+constexpr char kFormatKey[] = "fmt";
+constexpr char kAttestationKey[] = "attStmt";
+} // namespace
+
+AttestationObject::AttestationObject(
+ std::unique_ptr<AuthenticatorData> data,
+ std::unique_ptr<AttestationStatement> statement)
+ : authenticator_data_(std::move(data)),
+ attestation_statement_(std::move(statement)) {}
+
+std::vector<uint8_t> AttestationObject::SerializeToCBOREncodedBytes() {
+ CBORValue::MapValue map;
+ map[kFormatKey] = CBORValue(attestation_statement_->format_name().c_str());
+ map[kAuthDataKey] = CBORValue(authenticator_data_->SerializeToByteArray());
+ map[kAttestationKey] = CBORValue(attestation_statement_->GetAsCBORMap());
+ auto cbor = CBORWriter::Write(CBORValue(map));
+ if (cbor.has_value()) {
+ return cbor.value();
+ }
+ return std::vector<uint8_t>();
+}
+
+AttestationObject::~AttestationObject() {}
+
+} // namespace content
diff --git a/chromium/content/browser/webauth/attestation_object.h b/chromium/content/browser/webauth/attestation_object.h
new file mode 100644
index 00000000000..5b1993dd28d
--- /dev/null
+++ b/chromium/content/browser/webauth/attestation_object.h
@@ -0,0 +1,43 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEBAUTH_ATTESTATION_OBJECT_H_
+#define CONTENT_BROWSER_WEBAUTH_ATTESTATION_OBJECT_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "content/browser/webauth/authenticator_data.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class AttestationStatement;
+
+// Object containing the authenticator-provided attestation every time
+// a credential is created, per
+// https://www.w3.org/TR/2017/WD-webauthn-20170505/#cred-attestation.
+class CONTENT_EXPORT AttestationObject {
+ public:
+ AttestationObject(std::unique_ptr<AuthenticatorData> data,
+ std::unique_ptr<AttestationStatement> statement);
+ virtual ~AttestationObject();
+
+ // Produces a CBOR-encoded byte-array in the following format:
+ // {"authData": authenticator data bytes,
+ // "fmt": attestation format name,
+ // "attStmt": attestation statement bytes }
+ std::vector<uint8_t> SerializeToCBOREncodedBytes();
+
+ private:
+ const std::unique_ptr<AuthenticatorData> authenticator_data_;
+ const std::unique_ptr<AttestationStatement> attestation_statement_;
+
+ DISALLOW_COPY_AND_ASSIGN(AttestationObject);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEBAUTH_ATTESTATION_OBJECT_H_
diff --git a/chromium/content/browser/webauth/attestation_statement.cc b/chromium/content/browser/webauth/attestation_statement.cc
new file mode 100644
index 00000000000..c677322fe68
--- /dev/null
+++ b/chromium/content/browser/webauth/attestation_statement.cc
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/webauth/attestation_statement.h"
+
+#include <string>
+#include <utility>
+
+namespace content {
+
+AttestationStatement::AttestationStatement(std::string format)
+ : format_(std::move(format)) {}
+
+AttestationStatement::~AttestationStatement() {}
+
+} // namespace content
diff --git a/chromium/content/browser/webauth/attestation_statement.h b/chromium/content/browser/webauth/attestation_statement.h
new file mode 100644
index 00000000000..6ba3720bb17
--- /dev/null
+++ b/chromium/content/browser/webauth/attestation_statement.h
@@ -0,0 +1,44 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEBAUTH_ATTESTATION_STATEMENT_H_
+#define CONTENT_BROWSER_WEBAUTH_ATTESTATION_STATEMENT_H_
+
+#include "base/macros.h"
+#include "content/browser/webauth/cbor/cbor_values.h"
+
+namespace content {
+
+// A signed data object containing statements about a credential itself and
+// the authenticator that created it.
+// Each attestation statement format is defined by the following attributes:
+// - The attestation statement format identifier.
+// - The set of attestation types supported by the format.
+// - The syntax of an attestation statement produced in this format.
+// https://www.w3.org/TR/2017/WD-webauthn-20170505/#cred-attestation.
+class AttestationStatement {
+ public:
+ virtual ~AttestationStatement();
+
+ // The CBOR map data to be added to the attestation object, structured
+ // in a way that is specified by its particular attestation format:
+ // https://www.w3.org/TR/2017/WD-webauthn-20170505/#defined-attestation-formats
+ // This is not a CBOR-encoded byte array, but the map that will be
+ // nested within another CBOR object and encoded then.
+ virtual CBORValue::MapValue GetAsCBORMap() = 0;
+
+ const std::string& format_name() { return format_; }
+
+ protected:
+ AttestationStatement(std::string format);
+
+ private:
+ const std::string format_;
+
+ DISALLOW_COPY_AND_ASSIGN(AttestationStatement);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEBAUTH_ATTESTATION_STATEMENT_H_
diff --git a/chromium/content/browser/webauth/attested_credential_data.cc b/chromium/content/browser/webauth/attested_credential_data.cc
new file mode 100644
index 00000000000..ba2d394c0ca
--- /dev/null
+++ b/chromium/content/browser/webauth/attested_credential_data.cc
@@ -0,0 +1,61 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/webauth/attested_credential_data.h"
+
+#include <utility>
+
+#include "base/numerics/safe_math.h"
+#include "content/browser/webauth/authenticator_utils.h"
+
+namespace content {
+
+// static
+std::unique_ptr<AttestedCredentialData>
+AttestedCredentialData::CreateFromU2fRegisterResponse(
+ const std::vector<uint8_t>& u2f_data,
+ std::vector<uint8_t> aaguid,
+ std::unique_ptr<PublicKey> public_key) {
+ // Extract the length of the credential (i.e. of the U2FResponse key
+ // handle). Length is big endian.
+ std::vector<uint8_t> credential_id_length(2, 0);
+ std::vector<uint8_t> extracted_length = authenticator_utils::Extract(
+ u2f_data, authenticator_utils::kU2fResponseLengthPos, 1);
+
+ // Note that U2F responses only use one byte for length.
+ credential_id_length[1] = extracted_length[0];
+
+ // Extract the credential id (i.e. key handle).
+ std::vector<uint8_t> credential_id = authenticator_utils::Extract(
+ u2f_data, authenticator_utils::kU2fResponseKeyHandleStartPos,
+ base::strict_cast<size_t>(credential_id_length[1]));
+
+ return std::make_unique<AttestedCredentialData>(
+ std::move(aaguid), std::move(credential_id_length),
+ std::move(credential_id), std::move(public_key));
+}
+
+AttestedCredentialData::AttestedCredentialData(
+ std::vector<uint8_t> aaguid,
+ std::vector<uint8_t> length,
+ std::vector<uint8_t> credential_id,
+ std::unique_ptr<PublicKey> public_key)
+ : aaguid_(std::move(aaguid)),
+ credential_id_length_(std::move(length)),
+ credential_id_(std::move(credential_id)),
+ public_key_(std::move(public_key)) {}
+
+std::vector<uint8_t> AttestedCredentialData::SerializeAsBytes() {
+ std::vector<uint8_t> attestation_data;
+ std::vector<uint8_t> cbor_encoded_key = public_key_->EncodeAsCBOR();
+ authenticator_utils::Append(&attestation_data, aaguid_);
+ authenticator_utils::Append(&attestation_data, credential_id_length_);
+ authenticator_utils::Append(&attestation_data, credential_id_);
+ authenticator_utils::Append(&attestation_data, cbor_encoded_key);
+ return attestation_data;
+}
+
+AttestedCredentialData::~AttestedCredentialData() {}
+
+} // namespace content
diff --git a/chromium/content/browser/webauth/attested_credential_data.h b/chromium/content/browser/webauth/attested_credential_data.h
new file mode 100644
index 00000000000..5ff2bd13fa4
--- /dev/null
+++ b/chromium/content/browser/webauth/attested_credential_data.h
@@ -0,0 +1,56 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEBAUTH_ATTESTED_CREDENTIAL_DATA_H_
+#define CONTENT_BROWSER_WEBAUTH_ATTESTED_CREDENTIAL_DATA_H_
+
+#include "content/browser/webauth/public_key.h"
+
+#include <stdint.h>
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// https://www.w3.org/TR/2017/WD-webauthn-20170505/#sec-attestation-data
+class CONTENT_EXPORT AttestedCredentialData {
+ public:
+ AttestedCredentialData(std::vector<uint8_t> aaguid,
+ std::vector<uint8_t> length,
+ std::vector<uint8_t> credential_id,
+ std::unique_ptr<PublicKey> public_key);
+ virtual ~AttestedCredentialData();
+
+ static std::unique_ptr<AttestedCredentialData> CreateFromU2fRegisterResponse(
+ const std::vector<uint8_t>& u2f_data,
+ std::vector<uint8_t> aaguid,
+ std::unique_ptr<PublicKey> public_key);
+
+ const std::vector<uint8_t>& credential_id() { return credential_id_; }
+
+ // Produces a byte array consisting of:
+ // * AAGUID (16 bytes)
+ // * Len (2 bytes)
+ // * Credential Id (Len bytes)
+ // * Credential Public Key.
+ std::vector<uint8_t> SerializeAsBytes();
+
+ private:
+ // The 16-byte AAGUID of the authenticator.
+ const std::vector<uint8_t> aaguid_;
+
+ // Big-endian length of the credential (i.e. key handle).
+ const std::vector<uint8_t> credential_id_length_;
+ const std::vector<uint8_t> credential_id_;
+ const std::unique_ptr<PublicKey> public_key_;
+
+ DISALLOW_COPY_AND_ASSIGN(AttestedCredentialData);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEBAUTH_ATTESTED_CREDENTIAL_DATA_H_
diff --git a/chromium/content/browser/webauth/authenticator_data.cc b/chromium/content/browser/webauth/authenticator_data.cc
new file mode 100644
index 00000000000..e9876570361
--- /dev/null
+++ b/chromium/content/browser/webauth/authenticator_data.cc
@@ -0,0 +1,63 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/webauth/authenticator_data.h"
+
+#include <utility>
+
+#include "base/json/json_reader.h"
+#include "base/values.h"
+#include "content/browser/webauth/attested_credential_data.h"
+#include "content/browser/webauth/authenticator_utils.h"
+#include "crypto/sha2.h"
+
+namespace content {
+
+// static
+std::unique_ptr<AuthenticatorData> AuthenticatorData::Create(
+ std::string client_data_json,
+ Flags flags,
+ std::vector<uint8_t> counter,
+ std::unique_ptr<AttestedCredentialData> data) {
+ base::DictionaryValue* client_data_dictionary;
+ std::unique_ptr<base::Value> client_data =
+ base::JSONReader::Read(client_data_json);
+ client_data->GetAsDictionary(&client_data_dictionary);
+ std::string relying_party_id =
+ client_data_dictionary->FindKey(authenticator_utils::kOriginKey)
+ ->GetString();
+
+ return std::make_unique<AuthenticatorData>(
+ std::move(relying_party_id), flags, std::move(counter), std::move(data));
+}
+
+AuthenticatorData::AuthenticatorData(
+ std::string relying_party_id,
+ Flags flags,
+ std::vector<uint8_t> counter,
+ std::unique_ptr<AttestedCredentialData> data)
+ : relying_party_id_(std::move(relying_party_id)),
+ flags_(flags),
+ counter_(std::move(counter)),
+ attested_data_(std::move(data)) {
+ CHECK_EQ(counter_.size(), 4u);
+}
+
+std::vector<uint8_t> AuthenticatorData::SerializeToByteArray() {
+ std::vector<uint8_t> authenticator_data;
+ std::vector<uint8_t> rp_id_hash(crypto::kSHA256Length);
+ crypto::SHA256HashString(relying_party_id_, rp_id_hash.data(),
+ rp_id_hash.size());
+ authenticator_utils::Append(&authenticator_data, rp_id_hash);
+ authenticator_data.insert(authenticator_data.end(), flags_);
+ authenticator_utils::Append(&authenticator_data, counter_);
+ std::vector<uint8_t> attestation_bytes = attested_data_->SerializeAsBytes();
+ authenticator_utils::Append(&authenticator_data, attestation_bytes);
+
+ return authenticator_data;
+}
+
+AuthenticatorData::~AuthenticatorData() {}
+
+} // namespace content
diff --git a/chromium/content/browser/webauth/authenticator_data.h b/chromium/content/browser/webauth/authenticator_data.h
new file mode 100644
index 00000000000..76c8b84f17d
--- /dev/null
+++ b/chromium/content/browser/webauth/authenticator_data.h
@@ -0,0 +1,70 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_DATA_H_
+#define CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_DATA_H_
+
+#include <stdint.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class AttestedCredentialData;
+
+// https://www.w3.org/TR/2017/WD-webauthn-20170505/#sec-authenticator-data.
+class CONTENT_EXPORT AuthenticatorData {
+ public:
+ enum class Flag : uint8_t {
+ TEST_OF_USER_PRESENCE = 1u << 0,
+ ATTESTATION = 1u << 6
+ };
+
+ using Flags = uint8_t;
+
+ AuthenticatorData(std::string relying_party_id,
+ Flags flags,
+ std::vector<uint8_t> counter,
+ std::unique_ptr<AttestedCredentialData> data);
+ virtual ~AuthenticatorData();
+
+ static std::unique_ptr<AuthenticatorData> Create(
+ std::string client_data_json,
+ Flags flags,
+ std::vector<uint8_t> counter,
+ std::unique_ptr<AttestedCredentialData> data);
+
+ // Produces a byte array consisting of:
+ // * hash(relying_party_id)
+ // * flags
+ // * counter
+ // * attestation_data.
+ std::vector<uint8_t> SerializeToByteArray();
+
+ private:
+ // RP ID associated with the credential
+ const std::string relying_party_id_;
+
+ // Flags (bit 0 is the least significant bit):
+ // [ED | AT | RFU | RFU | RFU | RFU | RFU | UP ]
+ // * Bit 0: Test of User Presence (TUP) result.
+ // * Bits 1-5: Reserved for future use (RFU).
+ // * Bit 6: Attestation data included (AT).
+ // * Bit 7: Extension data included (ED).
+ Flags flags_;
+
+ // Signature counter, 32-bit unsigned big-endian integer.
+ const std::vector<uint8_t> counter_;
+ const std::unique_ptr<AttestedCredentialData> attested_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(AuthenticatorData);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_DATA_H_
diff --git a/chromium/content/browser/webauth/authenticator_impl.cc b/chromium/content/browser/webauth/authenticator_impl.cc
index 2abf7244ca8..eb722981dc2 100644
--- a/chromium/content/browser/webauth/authenticator_impl.cc
+++ b/chromium/content/browser/webauth/authenticator_impl.cc
@@ -4,117 +4,188 @@
#include "content/browser/webauth/authenticator_impl.h"
-#include <memory>
+#include <utility>
-#include "base/json/json_writer.h"
-#include "base/memory/ptr_util.h"
+#include "base/logging.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 "crypto/sha2.h"
+#include "device/u2f/u2f_hid_discovery.h"
+#include "device/u2f/u2f_register.h"
+#include "device/u2f/u2f_request.h"
+#include "device/u2f/u2f_return_code.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/service_manager/public/cpp/connector.h"
namespace content {
namespace {
+constexpr int32_t kCoseEs256 = -7;
-constexpr char kMakeCredentialType[] = "navigator.id.makeCredential";
-
-// JSON key values
-constexpr char kTypeKey[] = "type";
-constexpr char kChallengeKey[] = "challenge";
-constexpr char kOriginKey[] = "origin";
-constexpr char kCidPubkeyKey[] = "cid_pubkey";
-
-} // namespace
+bool HasValidAlgorithm(
+ const std::vector<webauth::mojom::PublicKeyCredentialParametersPtr>&
+ parameters) {
+ for (const auto& params : parameters) {
+ if (params->algorithm_identifier == kCoseEs256)
+ return true;
+ }
+ return false;
+}
-// Serializes the |value| to a JSON string and returns the result.
-std::string SerializeValueToJson(const base::Value& value) {
- std::string json;
- base::JSONWriter::Write(value, &json);
- return json;
+webauth::mojom::PublicKeyCredentialInfoPtr CreatePublicKeyCredentialInfo(
+ std::unique_ptr<RegisterResponseData> response_data) {
+ auto credential_info = webauth::mojom::PublicKeyCredentialInfo::New();
+ credential_info->client_data_json = response_data->GetClientDataJSONBytes();
+ credential_info->raw_id = response_data->raw_id();
+ credential_info->id = response_data->GetId();
+ auto response = webauth::mojom::AuthenticatorResponse::New();
+ response->attestation_object =
+ response_data->GetCBOREncodedAttestationObject();
+ credential_info->response = std::move(response);
+ return credential_info;
}
+} // namespace
-// static
-void AuthenticatorImpl::Create(
- RenderFrameHost* render_frame_host,
- webauth::mojom::AuthenticatorRequest request) {
- auto authenticator_impl =
- base::WrapUnique(new AuthenticatorImpl(render_frame_host));
- mojo::MakeStrongBinding(std::move(authenticator_impl), std::move(request));
+AuthenticatorImpl::AuthenticatorImpl(RenderFrameHost* render_frame_host)
+ : render_frame_host_(render_frame_host), weak_factory_(this) {
+ DCHECK(render_frame_host_);
}
AuthenticatorImpl::~AuthenticatorImpl() {}
-AuthenticatorImpl::AuthenticatorImpl(RenderFrameHost* render_frame_host) {
- DCHECK(render_frame_host);
- caller_origin_ = render_frame_host->GetLastCommittedOrigin();
+void AuthenticatorImpl::Bind(webauth::mojom::AuthenticatorRequest request) {
+ bindings_.AddBinding(this, std::move(request));
}
-// mojom:Authenticator
+// mojom::Authenticator
void AuthenticatorImpl::MakeCredential(
- webauth::mojom::MakeCredentialOptionsPtr options,
+ webauth::mojom::MakePublicKeyCredentialOptionsPtr options,
MakeCredentialCallback callback) {
- std::string effective_domain;
- std::string relying_party_id;
- std::string client_data_json;
- base::DictionaryValue client_data;
+ // Ensure no other operations are in flight.
+ // TODO(kpaulhamus): Do this properly. http://crbug.com/785954.
+ if (u2f_request_) {
+ std::move(callback).Run(
+ webauth::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr);
+ return;
+ }
// Steps 6 & 7 of https://w3c.github.io/webauthn/#createCredential
// opaque origin
- if (caller_origin_.unique()) {
+ url::Origin caller_origin = render_frame_host_->GetLastCommittedOrigin();
+ if (caller_origin.unique()) {
std::move(callback).Run(
webauth::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr);
return;
}
- if (!options->relying_party->id) {
- relying_party_id = caller_origin_.Serialize();
- } else {
- effective_domain = caller_origin_.host();
-
- DCHECK(!effective_domain.empty());
+ std::string relying_party_id;
+ if (options->relying_party->id) {
// TODO(kpaulhamus): Check if relyingPartyId is a registrable domain
// suffix of and equal to effectiveDomain and set relyingPartyId
// appropriately.
+ // TODO(kpaulhamus): Add unit tests for domains. http://crbug.com/785950.
relying_party_id = *options->relying_party->id;
+ } else {
+ // Use the effective domain of the caller origin.
+ relying_party_id = caller_origin.host();
+ DCHECK(!relying_party_id.empty());
}
// Check that at least one of the cryptographic parameters is supported.
// Only ES256 is currently supported by U2F_V2.
- if (!HasValidAlgorithm(options->crypto_parameters)) {
+ if (!HasValidAlgorithm(options->public_key_parameters)) {
std::move(callback).Run(
webauth::mojom::AuthenticatorStatus::NOT_SUPPORTED_ERROR, nullptr);
return;
}
- client_data.SetString(kTypeKey, kMakeCredentialType);
- client_data.SetString(kChallengeKey,
- base::StringPiece(reinterpret_cast<const char*>(
- options->challenge.data()),
- options->challenge.size()));
- client_data.SetString(kOriginKey, relying_party_id);
- // Channel ID is optional, and missing if the browser doesn't support it.
- // It is present and set to the constant "unused" if the browser
- // supports Channel ID but is not using it to talk to the origin.
- // TODO(kpaulhamus): Fetch and add the Channel ID public key used to
- // communicate with the origin.
- client_data.SetString(kCidPubkeyKey, "unused");
-
- // SHA-256 hash the JSON data structure
- client_data_json = SerializeValueToJson(client_data);
- std::string client_data_hash = crypto::SHA256HashString(client_data_json);
-
- std::move(callback).Run(webauth::mojom::AuthenticatorStatus::NOT_IMPLEMENTED,
- nullptr);
+ std::unique_ptr<CollectedClientData> client_data =
+ CollectedClientData::Create(authenticator_utils::kCreateType,
+ caller_origin.Serialize(),
+ std::move(options->challenge));
+
+ // SHA-256 hash of the JSON data structure
+ std::vector<uint8_t> client_data_hash(crypto::kSHA256Length);
+ crypto::SHA256HashString(client_data->SerializeToJson(),
+ client_data_hash.data(), client_data_hash.size());
+
+ // The application parameter is the SHA-256 hash of the UTF-8 encoding of
+ // the application identity (i.e. relying_party_id) of the application
+ // requesting the registration.
+ std::vector<uint8_t> application_parameter(crypto::kSHA256Length);
+ crypto::SHA256HashString(relying_party_id, application_parameter.data(),
+ application_parameter.size());
+
+ auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback));
+
+ // Start the timer (step 16 - https://w3c.github.io/webauthn/#makeCredential).
+ timer_.Start(FROM_HERE, options->adjusted_timeout,
+ base::Bind(&AuthenticatorImpl::OnTimeout, base::Unretained(this),
+ copyable_callback));
+
+ service_manager::Connector* connector =
+ ServiceManagerConnection::GetForProcess()->GetConnector();
+
+ std::vector<std::unique_ptr<device::U2fDiscovery>> discoveries;
+ discoveries.push_back(std::make_unique<device::U2fHidDiscovery>(connector));
+
+ // Per fido-u2f-raw-message-formats:
+ // The challenge parameter is the SHA-256 hash of the Client Data,
+ // Among other things, the Client Data contains the challenge from the
+ // relying party (hence the name of the parameter).
+ device::U2fRegister::ResponseCallback response_callback = base::Bind(
+ &AuthenticatorImpl::OnDeviceResponse, weak_factory_.GetWeakPtr(),
+ copyable_callback, base::Passed(&client_data));
+
+ // Extract list of credentials to exclude.
+ std::vector<std::vector<uint8_t>> registered_keys;
+ for (const auto& credential : options->exclude_credentials) {
+ registered_keys.push_back(credential->id);
+ }
+
+ // TODO(kpaulhamus): Mock U2fRegister for unit tests. http://crbug.com/785955.
+ u2f_request_ = device::U2fRegister::TryRegistration(
+ registered_keys, client_data_hash, application_parameter,
+ std::move(discoveries), response_callback);
}
-bool AuthenticatorImpl::HasValidAlgorithm(
- const std::vector<webauth::mojom::PublicKeyCredentialParametersPtr>&
- parameters) {
- for (const auto& params : parameters) {
- if (params->algorithm_identifier == -7)
- return true;
+// Callback to handle the async response from a U2fDevice.
+// |data| is returned for both successful sign and register responses, whereas
+// |key_handle| is only returned for successful sign responses.
+void AuthenticatorImpl::OnDeviceResponse(
+ MakeCredentialCallback callback,
+ std::unique_ptr<CollectedClientData> client_data,
+ device::U2fReturnCode status_code,
+ const std::vector<uint8_t>& u2f_register_response,
+ const std::vector<uint8_t>& key_handle) {
+ timer_.Stop();
+
+ if (status_code == device::U2fReturnCode::SUCCESS) {
+ // TODO(kpaulhamus): Add fuzzers for the response parsers.
+ // http//crbug.com/785957.
+ std::unique_ptr<RegisterResponseData> response =
+ RegisterResponseData::CreateFromU2fRegisterResponse(
+ std::move(client_data), std::move(u2f_register_response));
+ std::move(callback).Run(webauth::mojom::AuthenticatorStatus::SUCCESS,
+ CreatePublicKeyCredentialInfo(std::move(response)));
+ } else if (status_code == device::U2fReturnCode::FAILURE ||
+ status_code == device::U2fReturnCode::INVALID_PARAMS) {
+ std::move(callback).Run(webauth::mojom::AuthenticatorStatus::UNKNOWN_ERROR,
+ nullptr);
}
- return false;
+
+ u2f_request_.reset();
}
+
+// TODO(kpaulhamus): Add unit test for this. http://crbug.com/785950.
+void AuthenticatorImpl::OnTimeout(
+ base::OnceCallback<void(webauth::mojom::AuthenticatorStatus,
+ webauth::mojom::PublicKeyCredentialInfoPtr)>
+ callback) {
+ u2f_request_.reset();
+ std::move(callback).Run(
+ webauth::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr);
+}
+
} // namespace content
diff --git a/chromium/content/browser/webauth/authenticator_impl.h b/chromium/content/browser/webauth/authenticator_impl.h
index 6f19c52570c..bf645f96d60 100644
--- a/chromium/content/browser/webauth/authenticator_impl.h
+++ b/chromium/content/browser/webauth/authenticator_impl.h
@@ -5,16 +5,27 @@
#ifndef CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_IMPL_H_
#define CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_IMPL_H_
+#include <stdint.h>
+#include <memory>
#include <vector>
-#include "base/cancelable_callback.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback_forward.h"
#include "base/macros.h"
+#include "base/timer/timer.h"
+#include "content/browser/webauth/register_response_data.h"
#include "content/common/content_export.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "third_party/WebKit/public/platform/modules/webauth/authenticator.mojom.h"
#include "url/origin.h"
+namespace device {
+class U2fRequest;
+enum class U2fReturnCode : uint8_t;
+} // namespace device
+
namespace content {
class RenderFrameHost;
@@ -22,28 +33,39 @@ class RenderFrameHost;
// Implementation of the public Authenticator interface.
class CONTENT_EXPORT AuthenticatorImpl : public webauth::mojom::Authenticator {
public:
- static void Create(RenderFrameHost* render_frame_host,
- webauth::mojom::AuthenticatorRequest request);
+ explicit AuthenticatorImpl(RenderFrameHost* render_frame_host);
~AuthenticatorImpl() override;
- void set_connection_error_handler(const base::Closure& error_handler) {
- connection_error_handler_ = error_handler;
- }
+ // Creates a binding between this object and |request|. Note that a
+ // AuthenticatorImpl instance can be bound to multiple requests (as happens in
+ // the case of simultaneous starting and finishing operations).
+ void Bind(webauth::mojom::AuthenticatorRequest request);
private:
- explicit AuthenticatorImpl(RenderFrameHost* render_frame_host);
-
// mojom:Authenticator
- void MakeCredential(webauth::mojom::MakeCredentialOptionsPtr options,
+ void MakeCredential(webauth::mojom::MakePublicKeyCredentialOptionsPtr options,
MakeCredentialCallback callback) override;
- bool HasValidAlgorithm(
- const std::vector<webauth::mojom::PublicKeyCredentialParametersPtr>&
- parameters);
+ // Callback to handle the async response from a U2fDevice.
+ void OnDeviceResponse(MakeCredentialCallback callback,
+ std::unique_ptr<CollectedClientData> client_data,
+ device::U2fReturnCode status_code,
+ const std::vector<uint8_t>& data,
+ const std::vector<uint8_t>& key_handle);
+
+ // Runs when timer expires and cancels all issued requests to a U2fDevice.
+ void OnTimeout(
+ base::OnceCallback<void(webauth::mojom::AuthenticatorStatus,
+ webauth::mojom::PublicKeyCredentialInfoPtr)>
+ callback);
+
+ // Owns pipes to this Authenticator from |render_frame_host_|.
+ mojo::BindingSet<webauth::mojom::Authenticator> bindings_;
+ std::unique_ptr<device::U2fRequest> u2f_request_;
+ base::OneShotTimer timer_;
+ RenderFrameHost* render_frame_host_;
+ base::WeakPtrFactory<AuthenticatorImpl> weak_factory_;
- base::Closure connection_error_handler_;
- base::CancelableClosure timeout_callback_;
- url::Origin caller_origin_;
DISALLOW_COPY_AND_ASSIGN(AuthenticatorImpl);
};
diff --git a/chromium/content/browser/webauth/authenticator_impl_unittest.cc b/chromium/content/browser/webauth/authenticator_impl_unittest.cc
index 655a6d00471..f9fc3eb0908 100644
--- a/chromium/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/chromium/content/browser/webauth/authenticator_impl_unittest.cc
@@ -4,11 +4,20 @@
#include "content/browser/webauth/authenticator_impl.h"
-#include <stdint.h>
#include <string>
-#include <vector>
+#include "base/base64url.h"
#include "base/run_loop.h"
+#include "base/test/gtest_util.h"
+#include "content/browser/webauth/attestation_object.h"
+#include "content/browser/webauth/attested_credential_data.h"
+#include "content/browser/webauth/authenticator_data.h"
+#include "content/browser/webauth/authenticator_utils.h"
+#include "content/browser/webauth/cbor/cbor_writer.h"
+#include "content/browser/webauth/collected_client_data.h"
+#include "content/browser/webauth/ec_public_key.h"
+#include "content/browser/webauth/fido_attestation_statement.h"
+#include "content/browser/webauth/register_response_data.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/navigation_simulator.h"
@@ -24,38 +33,346 @@ using ::testing::_;
using webauth::mojom::AuthenticatorPtr;
using webauth::mojom::AuthenticatorStatus;
-using webauth::mojom::MakeCredentialOptions;
-using webauth::mojom::MakeCredentialOptionsPtr;
-using webauth::mojom::PublicKeyCredentialEntity;
-using webauth::mojom::PublicKeyCredentialEntityPtr;
+using webauth::mojom::MakePublicKeyCredentialOptions;
+using webauth::mojom::MakePublicKeyCredentialOptionsPtr;
+using webauth::mojom::PublicKeyCredentialRpEntity;
+using webauth::mojom::PublicKeyCredentialRpEntityPtr;
+using webauth::mojom::PublicKeyCredentialUserEntity;
+using webauth::mojom::PublicKeyCredentialUserEntityPtr;
using webauth::mojom::PublicKeyCredentialInfoPtr;
using webauth::mojom::PublicKeyCredentialParameters;
using webauth::mojom::PublicKeyCredentialParametersPtr;
-const char* kOrigin1 = "https://google.com";
-
namespace {
-const int32_t algorithm_identifier = -7;
+constexpr char kTestOrigin1[] = "https://google.com";
+
+// Test data. CBOR test data can be built using the given diagnostic strings
+// and the utility at "http://cbor.me/".
+constexpr int32_t kCoseEs256 = -7;
+
+constexpr char kTestRelyingPartyId[] = "google.com";
+
+constexpr uint8_t kTestChallengeBytes[] = {
+ 0x68, 0x71, 0x34, 0x96, 0x82, 0x22, 0xEC, 0x17, 0x20, 0x2E, 0x42,
+ 0x50, 0x5F, 0x8E, 0xD2, 0xB1, 0x6A, 0xE2, 0x2F, 0x16, 0xBB, 0x05,
+ 0xB8, 0x8C, 0x25, 0xDB, 0x9E, 0x60, 0x26, 0x45, 0xF1, 0x41};
+
+constexpr char kTestClientDataJsonString[] =
+ "{\"challenge\":\"aHE0loIi7BcgLkJQX47SsWriLxa7BbiMJdueYCZF8UE\","
+ "\"hashAlgorithm\""
+ ":\"SHA-256\",\"origin\":\"google.com\",\"tokenBinding\":\"unused\","
+ "\"type\":\"webauthn.create\"}";
+
+constexpr uint8_t kTestCredentialRawIdBytes[] = {
+ 0x89, 0xAF, 0xB5, 0x24, 0x91, 0x1C, 0x40, 0x2B, 0x7F, 0x74, 0x59,
+ 0xC9, 0xF2, 0x21, 0xAF, 0xE6, 0xE5, 0x56, 0x65, 0x85, 0x04, 0xE8,
+ 0x5B, 0x49, 0x4D, 0x07, 0x55, 0x55, 0xF4, 0x6A, 0xBC, 0x44, 0x7B,
+ 0x15, 0xFC, 0x62, 0x61, 0x90, 0xA5, 0xFE, 0xEB, 0xE5, 0x9F, 0x5E,
+ 0xDC, 0x75, 0x32, 0x98, 0x6F, 0x44, 0x69, 0xD7, 0xF6, 0x13, 0xEB,
+ 0xAA, 0xEA, 0x33, 0xFB, 0xD5, 0x8E, 0xBF, 0xC6, 0x09};
+
+// CBOR-encoded EC public key.
+// Diagnostic notation:
+// {"x": h'F868CE3869605224CE1059C0047EF01B830F2AD93BE27A3211F44E894560E695',
+// "y": h'4E11538CABA2DF1CC1A6F250ED9F0C8B28B39DA44539DFABD46B589CD0E202E5',
+// "alg": "ES256"}
+constexpr uint8_t kTestECPublicKeyCBOR[] = {
+ // clang-format off
+ 0xA3, // map(3)
+ 0x61, // text(1)
+ 0x78, // "x"
+ 0x58, 0x20, // bytes(32)
+ 0xF8, 0x68, 0xCE, 0x38, 0x69, 0x60, 0x52, 0x24, 0xCE, 0x10, 0x59, 0xC0,
+ 0x04, 0x7E, 0xF0, 0x1B, 0x83, 0x0F, 0x2A, 0xD9, 0x3B, 0xE2, 0x7A, 0x32,
+ 0x11, 0xF4, 0x4E, 0x89, 0x45, 0x60, 0xE6, 0x95,
+ 0x61, // text(1)
+ 0x79, // "y"
+ 0x58, 0x20, // bytes(32)
+ 0x4E, 0x11, 0x53, 0x8C, 0xAB, 0xA2, 0xDF, 0x1C, 0xC1, 0xA6, 0xF2, 0x50,
+ 0xED, 0x9F, 0x0C, 0x8B, 0x28, 0xB3, 0x9D, 0xA4, 0x45, 0x39, 0xDF, 0xAB,
+ 0xD4, 0x6B, 0x58, 0x9C, 0xD0, 0xE2, 0x02, 0xE5,
+ 0x63, // text(3)
+ 0x61, 0x6C, 0x67, // "alg"
+ 0x65, // text(5)
+ 0x45, 0x53, 0x32, 0x35, 0x36, // "ES256"
+ // clang-format on
+};
+
+// U2F response blob produced by a U2F registration request. This example
+// data uses testClientDataJson and 'created' a key with testCredentialRawId
+// as its key handle and with the above x- and y- coordinates.
+constexpr uint8_t kTestU2fRegisterResponse[] = {
+ 0x05, 0x04, 0xF8, 0x68, 0xCE, 0x38, 0x69, 0x60, 0x52, 0x24, 0xCE, 0x10,
+ 0x59, 0xC0, 0x04, 0x7E, 0xF0, 0x1B, 0x83, 0x0F, 0x2A, 0xD9, 0x3B, 0xE2,
+ 0x7A, 0x32, 0x11, 0xF4, 0x4E, 0x89, 0x45, 0x60, 0xE6, 0x95, 0x4E, 0x11,
+ 0x53, 0x8C, 0xAB, 0xA2, 0xDF, 0x1C, 0xC1, 0xA6, 0xF2, 0x50, 0xED, 0x9F,
+ 0x0C, 0x8B, 0x28, 0xB3, 0x9D, 0xA4, 0x45, 0x39, 0xDF, 0xAB, 0xD4, 0x6B,
+ 0x58, 0x9C, 0xD0, 0xE2, 0x02, 0xE5, 0x40, 0x89, 0xAF, 0xB5, 0x24, 0x91,
+ 0x1C, 0x40, 0x2B, 0x7F, 0x74, 0x59, 0xC9, 0xF2, 0x21, 0xAF, 0xE6, 0xE5,
+ 0x56, 0x65, 0x85, 0x04, 0xE8, 0x5B, 0x49, 0x4D, 0x07, 0x55, 0x55, 0xF4,
+ 0x6A, 0xBC, 0x44, 0x7B, 0x15, 0xFC, 0x62, 0x61, 0x90, 0xA5, 0xFE, 0xEB,
+ 0xE5, 0x9F, 0x5E, 0xDC, 0x75, 0x32, 0x98, 0x6F, 0x44, 0x69, 0xD7, 0xF6,
+ 0x13, 0xEB, 0xAA, 0xEA, 0x33, 0xFB, 0xD5, 0x8E, 0xBF, 0xC6, 0x09, 0x30,
+ 0x82, 0x02, 0x4A, 0x30, 0x82, 0x01, 0x32, 0xA0, 0x03, 0x02, 0x01, 0x02,
+ 0x02, 0x04, 0x04, 0x6C, 0x88, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86,
+ 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x2E, 0x31,
+ 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x23, 0x59, 0x75,
+ 0x62, 0x69, 0x63, 0x6F, 0x20, 0x55, 0x32, 0x46, 0x20, 0x52, 0x6F, 0x6F,
+ 0x74, 0x20, 0x43, 0x41, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x20,
+ 0x34, 0x35, 0x37, 0x32, 0x30, 0x30, 0x36, 0x33, 0x31, 0x30, 0x20, 0x17,
+ 0x0D, 0x31, 0x34, 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x5A, 0x18, 0x0F, 0x32, 0x30, 0x35, 0x30, 0x30, 0x39, 0x30, 0x34,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x2C, 0x31, 0x2A, 0x30,
+ 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x21, 0x59, 0x75, 0x62, 0x69,
+ 0x63, 0x6F, 0x20, 0x55, 0x32, 0x46, 0x20, 0x45, 0x45, 0x20, 0x53, 0x65,
+ 0x72, 0x69, 0x61, 0x6C, 0x20, 0x32, 0x34, 0x39, 0x31, 0x38, 0x32, 0x33,
+ 0x32, 0x34, 0x37, 0x37, 0x30, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A,
+ 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE,
+ 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x3C, 0xCA, 0xB9, 0x2C,
+ 0xCB, 0x97, 0x28, 0x7E, 0xE8, 0xE6, 0x39, 0x43, 0x7E, 0x21, 0xFC, 0xD6,
+ 0xB6, 0xF1, 0x65, 0xB2, 0xD5, 0xA3, 0xF3, 0xDB, 0x13, 0x1D, 0x31, 0xC1,
+ 0x6B, 0x74, 0x2B, 0xB4, 0x76, 0xD8, 0xD1, 0xE9, 0x90, 0x80, 0xEB, 0x54,
+ 0x6C, 0x9B, 0xBD, 0xF5, 0x56, 0xE6, 0x21, 0x0F, 0xD4, 0x27, 0x85, 0x89,
+ 0x9E, 0x78, 0xCC, 0x58, 0x9E, 0xBE, 0x31, 0x0F, 0x6C, 0xDB, 0x9F, 0xF4,
+ 0xA3, 0x3B, 0x30, 0x39, 0x30, 0x22, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04,
+ 0x01, 0x82, 0xC4, 0x0A, 0x02, 0x04, 0x15, 0x31, 0x2E, 0x33, 0x2E, 0x36,
+ 0x2E, 0x31, 0x2E, 0x34, 0x2E, 0x31, 0x2E, 0x34, 0x31, 0x34, 0x38, 0x32,
+ 0x2E, 0x31, 0x2E, 0x32, 0x30, 0x13, 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04,
+ 0x01, 0x82, 0xE5, 0x1C, 0x02, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x04,
+ 0x30, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
+ 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9F, 0x9B, 0x05,
+ 0x22, 0x48, 0xBC, 0x4C, 0xF4, 0x2C, 0xC5, 0x99, 0x1F, 0xCA, 0xAB, 0xAC,
+ 0x9B, 0x65, 0x1B, 0xBE, 0x5B, 0xDC, 0xDC, 0x8E, 0xF0, 0xAD, 0x2C, 0x1C,
+ 0x1F, 0xFB, 0x36, 0xD1, 0x87, 0x15, 0xD4, 0x2E, 0x78, 0xB2, 0x49, 0x22,
+ 0x4F, 0x92, 0xC7, 0xE6, 0xE7, 0xA0, 0x5C, 0x49, 0xF0, 0xE7, 0xE4, 0xC8,
+ 0x81, 0xBF, 0x2E, 0x94, 0xF4, 0x5E, 0x4A, 0x21, 0x83, 0x3D, 0x74, 0x56,
+ 0x85, 0x1D, 0x0F, 0x6C, 0x14, 0x5A, 0x29, 0x54, 0x0C, 0x87, 0x4F, 0x30,
+ 0x92, 0xC9, 0x34, 0xB4, 0x3D, 0x22, 0x2B, 0x89, 0x62, 0xC0, 0xF4, 0x10,
+ 0xCE, 0xF1, 0xDB, 0x75, 0x89, 0x2A, 0xF1, 0x16, 0xB4, 0x4A, 0x96, 0xF5,
+ 0xD3, 0x5A, 0xDE, 0xA3, 0x82, 0x2F, 0xC7, 0x14, 0x6F, 0x60, 0x04, 0x38,
+ 0x5B, 0xCB, 0x69, 0xB6, 0x5C, 0x99, 0xE7, 0xEB, 0x69, 0x19, 0x78, 0x67,
+ 0x03, 0xC0, 0xD8, 0xCD, 0x41, 0xE8, 0xF7, 0x5C, 0xCA, 0x44, 0xAA, 0x8A,
+ 0xB7, 0x25, 0xAD, 0x8E, 0x79, 0x9F, 0xF3, 0xA8, 0x69, 0x6A, 0x6F, 0x1B,
+ 0x26, 0x56, 0xE6, 0x31, 0xB1, 0xE4, 0x01, 0x83, 0xC0, 0x8F, 0xDA, 0x53,
+ 0xFA, 0x4A, 0x8F, 0x85, 0xA0, 0x56, 0x93, 0x94, 0x4A, 0xE1, 0x79, 0xA1,
+ 0x33, 0x9D, 0x00, 0x2D, 0x15, 0xCA, 0xBD, 0x81, 0x00, 0x90, 0xEC, 0x72,
+ 0x2E, 0xF5, 0xDE, 0xF9, 0x96, 0x5A, 0x37, 0x1D, 0x41, 0x5D, 0x62, 0x4B,
+ 0x68, 0xA2, 0x70, 0x7C, 0xAD, 0x97, 0xBC, 0xDD, 0x17, 0x85, 0xAF, 0x97,
+ 0xE2, 0x58, 0xF3, 0x3D, 0xF5, 0x6A, 0x03, 0x1A, 0xA0, 0x35, 0x6D, 0x8E,
+ 0x8D, 0x5E, 0xBC, 0xAD, 0xC7, 0x4E, 0x07, 0x16, 0x36, 0xC6, 0xB1, 0x10,
+ 0xAC, 0xE5, 0xCC, 0x9B, 0x90, 0xDF, 0xEA, 0xCA, 0xE6, 0x40, 0xFF, 0x1B,
+ 0xB0, 0xF1, 0xFE, 0x5D, 0xB4, 0xEF, 0xF7, 0xA9, 0x5F, 0x06, 0x07, 0x33,
+ 0xF5, 0x30, 0x44, 0x02, 0x20, 0x08, 0xC3, 0xF8, 0xDB, 0x6E, 0x29, 0xFD,
+ 0x8B, 0x14, 0xD9, 0xDE, 0x1B, 0xD9, 0x8E, 0x84, 0x07, 0x2C, 0xB8, 0x13,
+ 0x38, 0x59, 0x89, 0xAA, 0x2C, 0xA2, 0x89, 0x39, 0x5E, 0x00, 0x09, 0xB8,
+ 0xB7, 0x02, 0x20, 0x26, 0x07, 0xB4, 0xF9, 0xAD, 0x05, 0xDE, 0x26, 0xF5,
+ 0x6F, 0x48, 0xB8, 0x25, 0x69, 0xEA, 0xD8, 0x23, 0x1A, 0x5A, 0x6C, 0x3A,
+ 0x14, 0x48, 0xDE, 0xAA, 0xAF, 0x15, 0xC0, 0xEF, 0x29, 0x63, 0x1A};
+
+// The attested credential data, excluding the CBOR public key bytes. Append
+// with kTestECPublicKeyCBOR to get the complete attestation data.
+constexpr uint8_t kTestAttestedCredentialDataPrefix[] = {
+ // clang-format off
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, // 16-byte aaguid
+ 0x00, 0x40, // 2-byte length
+ 0x89, 0xAF, 0xB5, 0x24, 0x91, 0x1C, 0x40, 0x2B, 0x7F, 0x74, 0x59, 0xC9,
+ 0xF2, 0x21, 0xAF, 0xE6, 0xE5, 0x56, 0x65, 0x85, 0x04, 0xE8, 0x5B, 0x49,
+ 0x4D, 0x07, 0x55, 0x55, 0xF4, 0x6A, 0xBC, 0x44, 0x7B, 0x15, 0xFC, 0x62,
+ 0x61, 0x90, 0xA5, 0xFE, 0xEB, 0xE5, 0x9F, 0x5E, 0xDC, 0x75, 0x32, 0x98,
+ 0x6F, 0x44, 0x69, 0xD7, 0xF6, 0x13, 0xEB, 0xAA, 0xEA, 0x33, 0xFB, 0xD5,
+ 0x8E, 0xBF, 0xC6, 0x09 //64-byte key handle
+ // clang-format on
+};
+
+// The authenticator data, excluding the attested credential data bytes. Append
+// with attested credential data to get the complete authenticator data.
+constexpr uint8_t kTestAuthenticatorDataPrefix[] = {
+ // clang-format off
+ // sha256 hash of kTestRelyingPartyId
+ 0xD4, 0xC9, 0xD9, 0x02, 0x73, 0x26, 0x27, 0x1A, 0x89, 0xCE, 0x51,
+ 0xFC, 0xAF, 0x32, 0x8E, 0xD6, 0x73, 0xF1, 0x7B, 0xE3, 0x34, 0x69,
+ 0xFF, 0x97, 0x9E, 0x8A, 0xB8, 0xDD, 0x50, 0x1E, 0x66, 0x4F,
+ 0x41, // flags (TUP and AT bits set)
+ 0x00, 0x00, 0x00, 0x00 //counter
+ // clang-format on
+};
+
+// The attestation statement, a CBOR-encoded byte array.
+// Diagnostic notation:
+// {"sig":
+// h'3044022008C3F8DB6E29FD8B14D9DE1BD98E84072CB813385989AA2CA289395E0009B8B70 \
+// 2202607B4F9AD05DE26F56F48B82569EAD8231A5A6C3A1448DEAAAF15C0EF29631A',
+// "x5c": [h'3082024A30820132A0030201020204046C8822300D06092A864886F70D01010B0 \
+// 500302E312C302A0603550403132359756269636F2055324620526F6F742043412053657269 \
+// 616C203435373230303633313020170D3134303830313030303030305A180F3230353030393 \
+// 0343030303030305A302C312A302806035504030C2159756269636F20553246204545205365 \
+// 7269616C203234393138323332343737303059301306072A8648CE3D020106082A8648CE3D0 \
+// 30107034200043CCAB92CCB97287EE8E639437E21FCD6B6F165B2D5A3F3DB131D31C16B742B \
+// B476D8D1E99080EB546C9BBDF556E6210FD42785899E78CC589EBE310F6CDB9FF4A33B30393 \
+// 02206092B0601040182C40A020415312E332E362E312E342E312E34313438322E312E323013 \
+// 060B2B0601040182E51C020101040403020430300D06092A864886F70D01010B05000382010 \
+// 1009F9B052248BC4CF42CC5991FCAABAC9B651BBE5BDCDC8EF0AD2C1C1FFB36D18715D42E78 \
+// B249224F92C7E6E7A05C49F0E7E4C881BF2E94F45E4A21833D7456851D0F6C145A29540C874 \
+// F3092C934B43D222B8962C0F410CEF1DB75892AF116B44A96F5D35ADEA3822FC7146F600438 \
+// 5BCB69B65C99E7EB6919786703C0D8CD41E8F75CCA44AA8AB725AD8E799FF3A8696A6F1B265 \
+// 6E631B1E40183C08FDA53FA4A8F85A05693944AE179A1339D002D15CABD810090EC722EF5DE \
+// F9965A371D415D624B68A2707CAD97BCDD1785AF97E258F33DF56A031AA0356D8E8D5EBCADC \
+// 74E071636C6B110ACE5CC9B90DFEACAE640FF1BB0F1FE5DB4EFF7A95F060733F5']}
+constexpr uint8_t kU2fAttestationStatementCBOR[] = {
+ // clang-format off
+ 0xA2, // map(2)
+ 0x63, // text(3)
+ 0x73, 0x69, 0x67, // "sig"
+ 0x58, 0x46, // bytes(70)
+ 0x30, 0x44, 0x02, 0x20, 0x08, 0xC3, 0xF8, 0xDB, 0x6E, 0x29, 0xFD, 0x8B,
+ 0x14, 0xD9, 0xDE, 0x1B, 0xD9, 0x8E, 0x84, 0x07, 0x2C, 0xB8, 0x13, 0x38,
+ 0x59, 0x89, 0xAA, 0x2C, 0xA2, 0x89, 0x39, 0x5E, 0x00, 0x09, 0xB8, 0xB7,
+ 0x02, 0x20, 0x26, 0x07, 0xB4, 0xF9, 0xAD, 0x05, 0xDE, 0x26, 0xF5, 0x6F,
+ 0x48, 0xB8, 0x25, 0x69, 0xEA, 0xD8, 0x23, 0x1A, 0x5A, 0x6C, 0x3A, 0x14,
+ 0x48, 0xDE, 0xAA, 0xAF, 0x15, 0xC0, 0xEF, 0x29, 0x63, 0x1A,
+ 0x63, // text(3)
+ 0x78, 0x35, 0x63, // "x5c"
+ 0x81, // array(1)
+ 0x59, 0x02, 0x4E, // bytes(590)
+ 0x30, 0x82, 0x02, 0x4A, 0x30, 0x82, 0x01, 0x32, 0xA0, 0x03, 0x02,
+ 0x01, 0x02, 0x02, 0x04, 0x04, 0x6C, 0x88, 0x22, 0x30, 0x0D, 0x06,
+ 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05,
+ 0x00, 0x30, 0x2E, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x23, 0x59, 0x75, 0x62, 0x69, 0x63, 0x6F, 0x20, 0x55,
+ 0x32, 0x46, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20,
+ 0x53, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x20, 0x34, 0x35, 0x37, 0x32,
+ 0x30, 0x30, 0x36, 0x33, 0x31, 0x30, 0x20, 0x17, 0x0D, 0x31, 0x34,
+ 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A,
+ 0x18, 0x0F, 0x32, 0x30, 0x35, 0x30, 0x30, 0x39, 0x30, 0x34, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x2C, 0x31, 0x2A, 0x30,
+ 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x21, 0x59, 0x75, 0x62,
+ 0x69, 0x63, 0x6F, 0x20, 0x55, 0x32, 0x46, 0x20, 0x45, 0x45, 0x20,
+ 0x53, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x20, 0x32, 0x34, 0x39, 0x31,
+ 0x38, 0x32, 0x33, 0x32, 0x34, 0x37, 0x37, 0x30, 0x30, 0x59, 0x30,
+ 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06,
+ 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42,
+ 0x00, 0x04, 0x3C, 0xCA, 0xB9, 0x2C, 0xCB, 0x97, 0x28, 0x7E, 0xE8,
+ 0xE6, 0x39, 0x43, 0x7E, 0x21, 0xFC, 0xD6, 0xB6, 0xF1, 0x65, 0xB2,
+ 0xD5, 0xA3, 0xF3, 0xDB, 0x13, 0x1D, 0x31, 0xC1, 0x6B, 0x74, 0x2B,
+ 0xB4, 0x76, 0xD8, 0xD1, 0xE9, 0x90, 0x80, 0xEB, 0x54, 0x6C, 0x9B,
+ 0xBD, 0xF5, 0x56, 0xE6, 0x21, 0x0F, 0xD4, 0x27, 0x85, 0x89, 0x9E,
+ 0x78, 0xCC, 0x58, 0x9E, 0xBE, 0x31, 0x0F, 0x6C, 0xDB, 0x9F, 0xF4,
+ 0xA3, 0x3B, 0x30, 0x39, 0x30, 0x22, 0x06, 0x09, 0x2B, 0x06, 0x01,
+ 0x04, 0x01, 0x82, 0xC4, 0x0A, 0x02, 0x04, 0x15, 0x31, 0x2E, 0x33,
+ 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E, 0x31, 0x2E, 0x34, 0x31,
+ 0x34, 0x38, 0x32, 0x2E, 0x31, 0x2E, 0x32, 0x30, 0x13, 0x06, 0x0B,
+ 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xE5, 0x1C, 0x02, 0x01, 0x01,
+ 0x04, 0x04, 0x03, 0x02, 0x04, 0x30, 0x30, 0x0D, 0x06, 0x09, 0x2A,
+ 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x01, 0x00, 0x9F, 0x9B, 0x05, 0x22, 0x48, 0xBC, 0x4C,
+ 0xF4, 0x2C, 0xC5, 0x99, 0x1F, 0xCA, 0xAB, 0xAC, 0x9B, 0x65, 0x1B,
+ 0xBE, 0x5B, 0xDC, 0xDC, 0x8E, 0xF0, 0xAD, 0x2C, 0x1C, 0x1F, 0xFB,
+ 0x36, 0xD1, 0x87, 0x15, 0xD4, 0x2E, 0x78, 0xB2, 0x49, 0x22, 0x4F,
+ 0x92, 0xC7, 0xE6, 0xE7, 0xA0, 0x5C, 0x49, 0xF0, 0xE7, 0xE4, 0xC8,
+ 0x81, 0xBF, 0x2E, 0x94, 0xF4, 0x5E, 0x4A, 0x21, 0x83, 0x3D, 0x74,
+ 0x56, 0x85, 0x1D, 0x0F, 0x6C, 0x14, 0x5A, 0x29, 0x54, 0x0C, 0x87,
+ 0x4F, 0x30, 0x92, 0xC9, 0x34, 0xB4, 0x3D, 0x22, 0x2B, 0x89, 0x62,
+ 0xC0, 0xF4, 0x10, 0xCE, 0xF1, 0xDB, 0x75, 0x89, 0x2A, 0xF1, 0x16,
+ 0xB4, 0x4A, 0x96, 0xF5, 0xD3, 0x5A, 0xDE, 0xA3, 0x82, 0x2F, 0xC7,
+ 0x14, 0x6F, 0x60, 0x04, 0x38, 0x5B, 0xCB, 0x69, 0xB6, 0x5C, 0x99,
+ 0xE7, 0xEB, 0x69, 0x19, 0x78, 0x67, 0x03, 0xC0, 0xD8, 0xCD, 0x41,
+ 0xE8, 0xF7, 0x5C, 0xCA, 0x44, 0xAA, 0x8A, 0xB7, 0x25, 0xAD, 0x8E,
+ 0x79, 0x9F, 0xF3, 0xA8, 0x69, 0x6A, 0x6F, 0x1B, 0x26, 0x56, 0xE6,
+ 0x31, 0xB1, 0xE4, 0x01, 0x83, 0xC0, 0x8F, 0xDA, 0x53, 0xFA, 0x4A,
+ 0x8F, 0x85, 0xA0, 0x56, 0x93, 0x94, 0x4A, 0xE1, 0x79, 0xA1, 0x33,
+ 0x9D, 0x00, 0x2D, 0x15, 0xCA, 0xBD, 0x81, 0x00, 0x90, 0xEC, 0x72,
+ 0x2E, 0xF5, 0xDE, 0xF9, 0x96, 0x5A, 0x37, 0x1D, 0x41, 0x5D, 0x62,
+ 0x4B, 0x68, 0xA2, 0x70, 0x7C, 0xAD, 0x97, 0xBC, 0xDD, 0x17, 0x85,
+ 0xAF, 0x97, 0xE2, 0x58, 0xF3, 0x3D, 0xF5, 0x6A, 0x03, 0x1A, 0xA0,
+ 0x35, 0x6D, 0x8E, 0x8D, 0x5E, 0xBC, 0xAD, 0xC7, 0x4E, 0x07, 0x16,
+ 0x36, 0xC6, 0xB1, 0x10, 0xAC, 0xE5, 0xCC, 0x9B, 0x90, 0xDF, 0xEA,
+ 0xCA, 0xE6, 0x40, 0xFF, 0x1B, 0xB0, 0xF1, 0xFE, 0x5D, 0xB4, 0xEF,
+ 0xF7, 0xA9, 0x5F, 0x06, 0x07, 0x33, 0xF5
+ // clang-format on
+};
+
+// Components of the CBOR needed to form an authenticator object.
+// Combined diagnostic notation:
+// {"fmt": "fido-u2f", "attStmt": {"sig": h'30...}, "authData": h'D4C9D9...'}
+constexpr uint8_t kFormatFidoU2fCBOR[] = {
+ // clang-format off
+ 0xA3, // map(3)
+ 0x63, // text(3)
+ 0x66, 0x6D, 0x74, // "fmt"
+ 0x68, // text(8)
+ 0x66, 0x69, 0x64, 0x6F, 0x2D, 0x75, 0x32, 0x66 // "fido-u2f"
+ // clang-format on
+};
+
+constexpr uint8_t kAttStmtCBOR[] = {
+ // clang-format off
+ 0x67, // text(7)
+ 0x61, 0x74, 0x74, 0x53, 0x74, 0x6D, 0x74 // "attStmt"
+ // clang-format on
+};
+
+constexpr uint8_t kAuthDataCBOR[] = {
+ // clang-format off
+ 0x68, // text(8)
+ 0x61, 0x75, 0x74, 0x68, 0x44, 0x61, 0x74, 0x61, // "authData"
+ 0x58, 0xCA //bytes(202). i.e.,the authenticator_data bytearray
+ // clang-format on
+};
+
+// Helpers.
+
+const std::vector<uint8_t>& GetTestECPublicKeyCBOR() {
+ static const std::vector<uint8_t> data(std::begin(kTestECPublicKeyCBOR),
+ std::end(kTestECPublicKeyCBOR));
+ return data;
+}
+
+const std::vector<uint8_t>& GetTestRegisterResponse() {
+ static const std::vector<uint8_t> data(std::begin(kTestU2fRegisterResponse),
+ std::end(kTestU2fRegisterResponse));
+ return data;
+}
-PublicKeyCredentialEntityPtr GetTestPublicKeyCredentialRPEntity() {
- auto entity = PublicKeyCredentialEntity::New();
+const std::vector<uint8_t>& GetTestCredentialRawIdBytes() {
+ static const std::vector<uint8_t> data(std::begin(kTestCredentialRawIdBytes),
+ std::end(kTestCredentialRawIdBytes));
+ return data;
+}
+
+const std::vector<uint8_t>& GetTestChallengeBytes() {
+ static const std::vector<uint8_t> data(std::begin(kTestChallengeBytes),
+ std::end(kTestChallengeBytes));
+ return data;
+}
+
+const std::vector<uint8_t>& GetU2fAttestationStatementCBOR() {
+ static const std::vector<uint8_t> data(
+ std::begin(kU2fAttestationStatementCBOR),
+ std::end(kU2fAttestationStatementCBOR));
+ return data;
+}
+
+PublicKeyCredentialRpEntityPtr GetTestPublicKeyCredentialRPEntity() {
+ auto entity = PublicKeyCredentialRpEntity::New();
entity->id = std::string("localhost");
entity->name = std::string("TestRP@example.com");
return entity;
}
-PublicKeyCredentialEntityPtr GetTestPublicKeyCredentialUserEntity() {
- auto entity = PublicKeyCredentialEntity::New();
+PublicKeyCredentialUserEntityPtr GetTestPublicKeyCredentialUserEntity() {
+ auto entity = PublicKeyCredentialUserEntity::New();
entity->display_name = std::string("User A. Name");
- entity->id = std::string("1098237235409872");
+ std::vector<uint8_t> id(32, 0x0A);
+ entity->id = id;
entity->name = std::string("username@example.com");
entity->icon = GURL("fakeurl2.png");
return entity;
}
std::vector<PublicKeyCredentialParametersPtr>
-GetTestPublicKeyCredentialParameters() {
+GetTestPublicKeyCredentialParameters(int32_t algorithm_identifier) {
std::vector<PublicKeyCredentialParametersPtr> parameters;
auto fake_parameter = PublicKeyCredentialParameters::New();
fake_parameter->type = webauth::mojom::PublicKeyCredentialType::PUBLIC_KEY;
@@ -64,17 +381,69 @@ GetTestPublicKeyCredentialParameters() {
return parameters;
}
-MakeCredentialOptionsPtr GetTestMakeCredentialOptions() {
- auto options = MakeCredentialOptions::New();
+MakePublicKeyCredentialOptionsPtr GetTestMakePublicKeyCredentialOptions() {
+ auto options = MakePublicKeyCredentialOptions::New();
std::vector<uint8_t> buffer(32, 0x0A);
options->relying_party = GetTestPublicKeyCredentialRPEntity();
options->user = GetTestPublicKeyCredentialUserEntity();
- options->crypto_parameters = GetTestPublicKeyCredentialParameters();
+ options->public_key_parameters =
+ GetTestPublicKeyCredentialParameters(kCoseEs256);
options->challenge = std::move(buffer);
options->adjusted_timeout = base::TimeDelta::FromMinutes(1);
return options;
}
+std::unique_ptr<CollectedClientData> GetTestClientData(std::string type) {
+ std::unique_ptr<CollectedClientData> client_data =
+ CollectedClientData::Create(type, kTestRelyingPartyId,
+ GetTestChallengeBytes());
+ return client_data;
+}
+
+std::vector<uint8_t> GetTestAttestedCredentialDataBytes() {
+ // Combine kTestAttestedCredentialDataPrefix and kTestECPublicKeyCBOR.
+ std::vector<uint8_t> test_attested_data(
+ std::begin(kTestAttestedCredentialDataPrefix),
+ std::end(kTestAttestedCredentialDataPrefix));
+ test_attested_data.insert(test_attested_data.end(),
+ std::begin(kTestECPublicKeyCBOR),
+ std::end(kTestECPublicKeyCBOR));
+ return test_attested_data;
+}
+
+std::vector<uint8_t> GetTestAuthenticatorDataBytes() {
+ // Build the test authenticator data.
+ std::vector<uint8_t> test_authenticator_data(
+ std::begin(kTestAuthenticatorDataPrefix),
+ std::end(kTestAuthenticatorDataPrefix));
+ std::vector<uint8_t> test_attested_data =
+ GetTestAttestedCredentialDataBytes();
+ test_authenticator_data.insert(test_authenticator_data.end(),
+ test_attested_data.begin(),
+ test_attested_data.end());
+ return test_authenticator_data;
+}
+
+std::vector<uint8_t> GetTestAttestationObjectBytes() {
+ std::vector<uint8_t> test_authenticator_object(std::begin(kFormatFidoU2fCBOR),
+ std::end(kFormatFidoU2fCBOR));
+ test_authenticator_object.insert(test_authenticator_object.end(),
+ std::begin(kAttStmtCBOR),
+ std::end(kAttStmtCBOR));
+ test_authenticator_object.insert(test_authenticator_object.end(),
+ std::begin(kU2fAttestationStatementCBOR),
+ std::end(kU2fAttestationStatementCBOR));
+ test_authenticator_object.insert(test_authenticator_object.end(),
+ std::begin(kAuthDataCBOR),
+ std::end(kAuthDataCBOR));
+ std::vector<uint8_t> test_authenticator_data =
+ GetTestAuthenticatorDataBytes();
+ test_authenticator_object.insert(test_authenticator_object.end(),
+ test_authenticator_data.begin(),
+ test_authenticator_data.end());
+ return test_authenticator_object;
+}
+
class AuthenticatorImplTest : public content::RenderViewHostTestHarness {
public:
AuthenticatorImplTest() {}
@@ -89,10 +458,14 @@ class AuthenticatorImplTest : public content::RenderViewHostTestHarness {
}
AuthenticatorPtr ConnectToAuthenticator() {
+ authenticator_impl_.reset(new AuthenticatorImpl(main_rfh()));
AuthenticatorPtr authenticator;
- AuthenticatorImpl::Create(main_rfh(), mojo::MakeRequest(&authenticator));
+ authenticator_impl_->Bind(mojo::MakeRequest(&authenticator));
return authenticator;
}
+
+ private:
+ std::unique_ptr<AuthenticatorImpl> authenticator_impl_;
};
class TestMakeCredentialCallback {
@@ -132,35 +505,159 @@ class TestMakeCredentialCallback {
} // namespace
-// Test that service returns NOT_IMPLEMENTED on a call to MakeCredential.
-TEST_F(AuthenticatorImplTest, MakeCredentialNotImplemented) {
- SimulateNavigation(GURL(kOrigin1));
+// Test that service returns NOT_ALLOWED_ERROR on a call to MakeCredential with
+// an opaque origin.
+TEST_F(AuthenticatorImplTest, MakeCredentialOpaqueOrigin) {
+ NavigateAndCommit(GURL("data:text/html,opaque"));
AuthenticatorPtr authenticator = ConnectToAuthenticator();
- MakeCredentialOptionsPtr options = GetTestMakeCredentialOptions();
+ MakePublicKeyCredentialOptionsPtr options =
+ GetTestMakePublicKeyCredentialOptions();
TestMakeCredentialCallback cb;
authenticator->MakeCredential(std::move(options), cb.callback());
std::pair<webauth::mojom::AuthenticatorStatus,
webauth::mojom::PublicKeyCredentialInfoPtr>& response =
cb.WaitForCallback();
- EXPECT_EQ(webauth::mojom::AuthenticatorStatus::NOT_IMPLEMENTED,
+ EXPECT_EQ(webauth::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR,
response.first);
}
-// Test that service returns NOT_ALLOWED_ERROR on a call to MakeCredential with
-// an opaque origin.
-TEST_F(AuthenticatorImplTest, MakeCredentialOpaqueOrigin) {
- NavigateAndCommit(GURL("data:text/html,opaque"));
+// Test that service returns NOT_SUPPORTED_ERROR if no parameters contain
+// a supported algorithm.
+TEST_F(AuthenticatorImplTest, MakeCredentialNoSupportedAlgorithm) {
+ SimulateNavigation(GURL(kTestOrigin1));
AuthenticatorPtr authenticator = ConnectToAuthenticator();
- MakeCredentialOptionsPtr options = GetTestMakeCredentialOptions();
+ MakePublicKeyCredentialOptionsPtr options =
+ GetTestMakePublicKeyCredentialOptions();
+ options->public_key_parameters = GetTestPublicKeyCredentialParameters(123);
TestMakeCredentialCallback cb;
authenticator->MakeCredential(std::move(options), cb.callback());
std::pair<webauth::mojom::AuthenticatorStatus,
webauth::mojom::PublicKeyCredentialInfoPtr>& response =
cb.WaitForCallback();
- EXPECT_EQ(webauth::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR,
+ EXPECT_EQ(webauth::mojom::AuthenticatorStatus::NOT_SUPPORTED_ERROR,
response.first);
}
+
+// Test that client data serializes to JSON properly.
+TEST_F(AuthenticatorImplTest, TestSerializedClientData) {
+ EXPECT_EQ(
+ kTestClientDataJsonString,
+ GetTestClientData(authenticator_utils::kCreateType)->SerializeToJson());
+}
+
+// Test that an EC public key serializes to CBOR properly.
+TEST_F(AuthenticatorImplTest, TestSerializedPublicKey) {
+ std::unique_ptr<ECPublicKey> public_key =
+ ECPublicKey::ExtractFromU2fRegistrationResponse(
+ authenticator_utils::kEs256, GetTestRegisterResponse());
+ EXPECT_EQ(GetTestECPublicKeyCBOR(), public_key->EncodeAsCBOR());
+}
+
+// Test that the attestation statement cbor map is constructed properly.
+TEST_F(AuthenticatorImplTest, TestU2fAttestationStatementCBOR) {
+ std::unique_ptr<FidoAttestationStatement> fido_attestation_statement =
+ FidoAttestationStatement::CreateFromU2fRegisterResponse(
+ GetTestRegisterResponse());
+ auto cbor =
+ CBORWriter::Write(CBORValue(fido_attestation_statement->GetAsCBORMap()));
+ ASSERT_TRUE(cbor.has_value());
+ EXPECT_EQ(GetU2fAttestationStatementCBOR(), cbor.value());
+}
+
+// Tests that well-formed attested credential data serializes properly.
+TEST_F(AuthenticatorImplTest, TestAttestedCredentialData) {
+ std::unique_ptr<ECPublicKey> public_key =
+ ECPublicKey::ExtractFromU2fRegistrationResponse(
+ authenticator_utils::kEs256, GetTestRegisterResponse());
+ std::unique_ptr<AttestedCredentialData> attested_data =
+ AttestedCredentialData::CreateFromU2fRegisterResponse(
+ GetTestRegisterResponse(), std::vector<uint8_t>(16, 0) /* aaguid */,
+ std::move(public_key));
+
+ EXPECT_EQ(GetTestAttestedCredentialDataBytes(),
+ attested_data->SerializeAsBytes());
+}
+
+// Tests that well-formed authenticator data serializes properly.
+TEST_F(AuthenticatorImplTest, TestAuthenticatorData) {
+ std::unique_ptr<ECPublicKey> public_key =
+ ECPublicKey::ExtractFromU2fRegistrationResponse(
+ authenticator_utils::kEs256, GetTestRegisterResponse());
+ std::unique_ptr<AttestedCredentialData> attested_data =
+ AttestedCredentialData::CreateFromU2fRegisterResponse(
+ GetTestRegisterResponse(), std::vector<uint8_t>(16, 0) /* aaguid */,
+ std::move(public_key));
+
+ AuthenticatorData::Flags flags =
+ static_cast<AuthenticatorData::Flags>(
+ AuthenticatorData::Flag::TEST_OF_USER_PRESENCE) |
+ static_cast<AuthenticatorData::Flags>(
+ AuthenticatorData::Flag::ATTESTATION);
+
+ std::unique_ptr<AuthenticatorData> authenticator_data =
+ AuthenticatorData::Create(
+ GetTestClientData(authenticator_utils::kCreateType)
+ ->SerializeToJson(),
+ flags, std::vector<uint8_t>(4, 0) /* counter */,
+ std::move(attested_data));
+
+ EXPECT_EQ(GetTestAuthenticatorDataBytes(),
+ authenticator_data->SerializeToByteArray());
+}
+
+// Tests that a U2F attestation object serializes properly.
+TEST_F(AuthenticatorImplTest, TestU2fAttestationObject) {
+ std::unique_ptr<ECPublicKey> public_key =
+ ECPublicKey::ExtractFromU2fRegistrationResponse(
+ authenticator_utils::kEs256, GetTestRegisterResponse());
+ std::unique_ptr<AttestedCredentialData> attested_data =
+ AttestedCredentialData::CreateFromU2fRegisterResponse(
+ GetTestRegisterResponse(), std::vector<uint8_t>(16, 0) /* aaguid */,
+ std::move(public_key));
+
+ AuthenticatorData::Flags flags =
+ static_cast<AuthenticatorData::Flags>(
+ AuthenticatorData::Flag::TEST_OF_USER_PRESENCE) |
+ static_cast<AuthenticatorData::Flags>(
+ AuthenticatorData::Flag::ATTESTATION);
+ std::unique_ptr<AuthenticatorData> authenticator_data =
+ AuthenticatorData::Create(
+ GetTestClientData(authenticator_utils::kCreateType)
+ ->SerializeToJson(),
+ flags, std::vector<uint8_t>(4, 0) /* counter */,
+ std::move(attested_data));
+
+ // Construct the attestation statement.
+ std::unique_ptr<FidoAttestationStatement> fido_attestation_statement =
+ FidoAttestationStatement::CreateFromU2fRegisterResponse(
+ GetTestRegisterResponse());
+
+ // Construct the attestation object.
+ auto attestation_object = std::make_unique<AttestationObject>(
+ std::move(authenticator_data), std::move(fido_attestation_statement));
+
+ EXPECT_EQ(GetTestAttestationObjectBytes(),
+ attestation_object->SerializeToCBOREncodedBytes());
+}
+
+// Test that a U2F register response is properly parsed.
+TEST_F(AuthenticatorImplTest, TestRegisterResponseData) {
+ std::unique_ptr<CollectedClientData> client_data =
+ GetTestClientData(authenticator_utils::kCreateType);
+ std::unique_ptr<RegisterResponseData> response =
+ RegisterResponseData::CreateFromU2fRegisterResponse(
+ std::move(client_data), GetTestRegisterResponse());
+
+ EXPECT_EQ(std::vector<uint8_t>(
+ kTestClientDataJsonString,
+ kTestClientDataJsonString + strlen(kTestClientDataJsonString)),
+ response->GetClientDataJSONBytes());
+ EXPECT_EQ(GetTestCredentialRawIdBytes(), response->raw_id());
+ EXPECT_EQ(GetTestAttestationObjectBytes(),
+ response->GetCBOREncodedAttestationObject());
+}
+
} // namespace content
diff --git a/chromium/content/browser/webauth/authenticator_utils.cc b/chromium/content/browser/webauth/authenticator_utils.cc
new file mode 100644
index 00000000000..6f7081f8323
--- /dev/null
+++ b/chromium/content/browser/webauth/authenticator_utils.cc
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/webauth/authenticator_utils.h"
+
+#include "base/logging.h"
+
+namespace content {
+namespace authenticator_utils {
+
+void Append(std::vector<uint8_t>* target,
+ const std::vector<uint8_t>& in_values) {
+ target->insert(target->end(), in_values.begin(), in_values.end());
+}
+
+std::vector<uint8_t> Extract(const std::vector<uint8_t>& source,
+ size_t pos,
+ size_t length) {
+ if (!(pos <= source.size() && length <= source.size() - pos)) {
+ return std::vector<uint8_t>();
+ }
+
+ return std::vector<uint8_t>(source.begin() + pos,
+ source.begin() + pos + length);
+}
+
+} // namespace authenticator_utils
+} // namespace content
diff --git a/chromium/content/browser/webauth/authenticator_utils.h b/chromium/content/browser/webauth/authenticator_utils.h
new file mode 100644
index 00000000000..3a2e963bb62
--- /dev/null
+++ b/chromium/content/browser/webauth/authenticator_utils.h
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. 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_WEBAUTH_AUTHENTICATOR_UTILS_H_
+#define CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_UTILS_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <vector>
+
+namespace content {
+namespace authenticator_utils {
+
+// JSON key values
+constexpr char kTypeKey[] = "type";
+constexpr char kChallengeKey[] = "challenge";
+constexpr char kOriginKey[] = "origin";
+constexpr char kHashAlgorithm[] = "hashAlgorithm";
+constexpr char kTokenBindingKey[] = "tokenBinding";
+
+// U2FResponse byte positions
+constexpr uint32_t kU2fResponseLengthPos = 66;
+constexpr uint32_t kU2fResponseKeyHandleStartPos = 67;
+
+constexpr char kEs256[] = "ES256";
+
+void Append(std::vector<uint8_t>* target,
+ const std::vector<uint8_t>& in_values);
+
+// Parses out a sub-vector after verifying no out-of-bound reads.
+std::vector<uint8_t> Extract(const std::vector<uint8_t>& source,
+ size_t pos,
+ size_t length);
+
+} // namespace authenticator_utils
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_UTILS_H_
diff --git a/chromium/content/browser/webauth/cbor/cbor_values.h b/chromium/content/browser/webauth/cbor/cbor_values.h
index 7f3d45b65a8..6fe9e143342 100644
--- a/chromium/content/browser/webauth/cbor/cbor_values.h
+++ b/chromium/content/browser/webauth/cbor/cbor_values.h
@@ -7,11 +7,12 @@
#include <stdint.h>
#include <string>
+#include <tuple>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/macros.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
#include "content/common/content_export.h"
namespace content {
@@ -23,9 +24,40 @@ namespace content {
// * Indefinite-length encodings.
class CONTENT_EXPORT CBORValue {
public:
+ struct CTAPLess {
+ // Comparison predicate to order keys in a dictionary as required by the
+ // Client-to-Authenticator Protocol (CTAP) spec 2.0.
+ //
+ // The sort order defined in CTAP is:
+ // • If the major types are different, the one with the lower value in
+ // numerical order sorts earlier. (Moot in this code because all keys
+ // are strings.)
+ // • If two keys have different lengths, the shorter one sorts earlier.
+ // • If two keys have the same length, the one with the lower value in
+ // (byte-wise) lexical order sorts earlier.
+ //
+ // See section 6 of https://fidoalliance.org/specs/fido-v2.0-rd-20170927/
+ // fido-client-to-authenticator-protocol-v2.0-rd-20170927.html.
+ //
+ // The sort order defined in
+ // https://tools.ietf.org/html/rfc7049#section-3.9 is similar to the CTAP
+ // order implemented here, but it sorts purely by serialised key and
+ // doesn't specify that major types are compared first. Thus the shortest
+ // key sorts first by the RFC rules (irrespective of the major type), but
+ // may not by CTAP rules.
+ bool operator()(const base::StringPiece& a,
+ const base::StringPiece& b) const {
+ const size_t a_size = a.size();
+ const size_t b_size = b.size();
+ return std::tie(a_size, a) < std::tie(b_size, b);
+ }
+
+ using is_transparent = void;
+ };
+
using BinaryValue = std::vector<uint8_t>;
using ArrayValue = std::vector<CBORValue>;
- using MapValue = base::flat_map<std::string, CBORValue>;
+ using MapValue = base::flat_map<std::string, CBORValue, CTAPLess>;
enum class Type {
NONE,
diff --git a/chromium/content/browser/webauth/cbor/cbor_writer.cc b/chromium/content/browser/webauth/cbor/cbor_writer.cc
index 666c7310d19..9ee55b21ff1 100644
--- a/chromium/content/browser/webauth/cbor/cbor_writer.cc
+++ b/chromium/content/browser/webauth/cbor/cbor_writer.cc
@@ -4,34 +4,59 @@
#include "content/browser/webauth/cbor/cbor_writer.h"
+#include <string>
+
#include "base/numerics/safe_conversions.h"
+#include "base/strings/string_piece.h"
namespace content {
+namespace {
+
+// Mask selecting the last 5 bits of the "initial byte" where
+// 'additional information is encoded.
+constexpr uint8_t kAdditionalInformationDataMask = 0x1F;
+// Indicates the integer is in the following byte.
+constexpr uint8_t kAdditionalInformation1Byte = 24u;
+// Indicates the integer is in the next 2 bytes.
+constexpr uint8_t kAdditionalInformation2Bytes = 25u;
+// Indicates the integer is in the next 4 bytes.
+constexpr uint8_t kAdditionalInformation4Bytes = 26u;
+// Indicates the integer is in the next 8 bytes.
+constexpr uint8_t kAdditionalInformation8Bytes = 27u;
+
+} // namespace
+
CBORWriter::~CBORWriter() {}
// static
-std::vector<uint8_t> CBORWriter::Write(const CBORValue& node) {
+base::Optional<std::vector<uint8_t>> CBORWriter::Write(
+ const CBORValue& node,
+ size_t max_nesting_level) {
std::vector<uint8_t> cbor;
CBORWriter writer(&cbor);
- writer.EncodeCBOR(node);
- return cbor;
+ if (writer.EncodeCBOR(node, base::checked_cast<int>(max_nesting_level)))
+ return cbor;
+ return base::nullopt;
}
CBORWriter::CBORWriter(std::vector<uint8_t>* cbor) : encoded_cbor_(cbor) {}
-void CBORWriter::EncodeCBOR(const CBORValue& node) {
+bool CBORWriter::EncodeCBOR(const CBORValue& node, int max_nesting_level) {
+ if (max_nesting_level < 0)
+ return false;
+
switch (node.type()) {
case CBORValue::Type::NONE: {
StartItem(CborMajorType::kByteString, 0);
- return;
+ return true;
}
// Represents unsigned integers.
case CBORValue::Type::UNSIGNED: {
uint64_t value = node.GetUnsigned();
StartItem(CborMajorType::kUnsigned, value);
- return;
+ return true;
}
// Represents a byte string.
@@ -41,7 +66,7 @@ void CBORWriter::EncodeCBOR(const CBORValue& node) {
base::strict_cast<uint64_t>(bytes.size()));
// Add the bytes.
encoded_cbor_->insert(encoded_cbor_->end(), bytes.begin(), bytes.end());
- return;
+ return true;
}
case CBORValue::Type::STRING: {
@@ -51,7 +76,7 @@ void CBORWriter::EncodeCBOR(const CBORValue& node) {
// Add the characters.
encoded_cbor_->insert(encoded_cbor_->end(), string.begin(), string.end());
- return;
+ return true;
}
// Represents an array.
@@ -59,33 +84,40 @@ void CBORWriter::EncodeCBOR(const CBORValue& node) {
const CBORValue::ArrayValue& array = node.GetArray();
StartItem(CborMajorType::kArray, array.size());
for (const auto& value : array) {
- EncodeCBOR(value);
+ if (!EncodeCBOR(value, max_nesting_level - 1))
+ return false;
}
- return;
+ return true;
}
// Represents a map.
case CBORValue::Type::MAP: {
const CBORValue::MapValue& map = node.GetMap();
StartItem(CborMajorType::kMap, map.size());
+
for (const auto& value : map) {
- EncodeCBOR(CBORValue(value.first));
- EncodeCBOR(value.second);
+ if (!EncodeCBOR(CBORValue(value.first), max_nesting_level - 1))
+ return false;
+ if (!EncodeCBOR(value.second, max_nesting_level - 1))
+ return false;
}
- return;
+ return true;
}
}
NOTREACHED();
- return;
+ return true;
}
void CBORWriter::StartItem(CborMajorType type, uint64_t size) {
- encoded_cbor_->push_back(base::checked_cast<uint8_t>(type) << 5);
+ encoded_cbor_->push_back(
+ base::checked_cast<uint8_t>(static_cast<unsigned>(type) << 5));
SetUint(size);
}
void CBORWriter::SetAdditionalInformation(uint8_t additional_information) {
DCHECK(!encoded_cbor_->empty());
+ DCHECK_EQ(additional_information & kAdditionalInformationDataMask,
+ additional_information);
encoded_cbor_->back() |=
(additional_information & kAdditionalInformationDataMask);
}
@@ -112,17 +144,17 @@ void CBORWriter::SetUint(uint64_t value) {
SetAdditionalInformation(kAdditionalInformation4Bytes);
shift = 3;
break;
- return;
case 8:
SetAdditionalInformation(kAdditionalInformation8Bytes);
shift = 7;
break;
+ default:
+ NOTREACHED();
+ break;
}
for (; shift >= 0; shift--) {
- encoded_cbor_->push_back(
- base::checked_cast<uint8_t>(0xFF & (value >> (shift * 8))));
+ encoded_cbor_->push_back(0xFF & (value >> (shift * 8)));
}
- return;
}
size_t CBORWriter::GetNumUintBytes(uint64_t value) {
diff --git a/chromium/content/browser/webauth/cbor/cbor_writer.h b/chromium/content/browser/webauth/cbor/cbor_writer.h
index 97edfd39844..b8f40b3f2d8 100644
--- a/chromium/content/browser/webauth/cbor/cbor_writer.h
+++ b/chromium/content/browser/webauth/cbor/cbor_writer.h
@@ -5,20 +5,18 @@
#ifndef CONTENT_BROWSER_WEBAUTH_CBOR_CBOR_WRITER_H_
#define CONTENT_BROWSER_WEBAUTH_CBOR_CBOR_WRITER_H_
+#include "content/browser/webauth/cbor/cbor_values.h"
+
#include <stdint.h>
-#include <string>
#include <vector>
-#include "base/numerics/safe_math.h"
-#include "base/strings/string_piece.h"
-#include "content/browser/webauth/cbor/cbor_values.h"
+#include "base/optional.h"
#include "content/common/content_export.h"
// A basic Concise Binary Object Representation (CBOR) encoder as defined by
-// https://tools.ietf.org/html/rfc7049.
-// This is a non-canonical, generic encoder that supplies well-formed
-// CBOR values but does not guarantee their validity (see
-// https://tools.ietf.org/html/rfc7049#section-3.2).
+// https://tools.ietf.org/html/rfc7049. This is a generic encoder that supplies
+// canonical, well-formed CBOR values but does not guarantee their validity
+// (see https://tools.ietf.org/html/rfc7049#section-3.2).
// Supported:
// * Major types:
// * 0: Unsigned integers, up to 64-bit.
@@ -32,6 +30,24 @@
// * Floating-point numbers.
// * Indefinite-length encodings.
// * Parsing.
+//
+// Requirements for canonical CBOR as suggested by RFC 7049 are:
+// 1) All major data types for the CBOR values must be as short as possible.
+// * Unsigned integer between 0 to 23 must be expressed in same byte as
+// the major type.
+// * 24 to 255 must be expressed only with an additional uint8_t.
+// * 256 to 65535 must be expressed only with an additional uint16_t.
+// * 65536 to 4294967295 must be expressed only with an additional
+// uint32_t. * The rules for expression of length in major types
+// 2 to 5 follow the above rule for integers.
+// 2) Keys in every map must be sorted (first by major type, then by key
+// length, then by value in byte-wise lexical order).
+// 3) Indefinite length items must be converted to definite length items.
+// 4) All maps must not have duplicate keys.
+//
+// Current implementation of CBORWriter encoder meets all the requirements of
+// canonical CBOR.
+
enum class CborMajorType {
kUnsigned = 0, // Unsigned integer.
kNegative = 1, // Negative integer. Unsupported by this implementation.
@@ -42,34 +58,31 @@ enum class CborMajorType {
};
namespace content {
-
namespace {
-// Mask selecting the last 5 bits of the "initial byte" where
-// 'additional information is encoded.
-constexpr uint8_t kAdditionalInformationDataMask = 0x1F;
-// Indicates the integer is in the following byte.
-constexpr uint8_t kAdditionalInformation1Byte = 24;
-// Indicates the integer is in the next 2 bytes.
-constexpr uint8_t kAdditionalInformation2Bytes = 25;
-// Indicates the integer is in the next 4 bytes.
-constexpr uint8_t kAdditionalInformation4Bytes = 26;
-// Indicates the integer is in the next 8 bytes.
-constexpr uint8_t kAdditionalInformation8Bytes = 27;
+// Default that should be sufficiently large for most use cases.
+constexpr size_t kDefaultMaxNestingDepth = 16;
} // namespace
class CONTENT_EXPORT CBORWriter {
public:
~CBORWriter();
- // Generates a CBOR byte string.
- static std::vector<uint8_t> Write(const CBORValue& node);
+ // Returns the CBOR byte string representation of |node|, unless its nesting
+ // depth is greater than |max_nesting_depth|, in which case an empty optional
+ // value is returned. The nesting depth of |node| is defined as the number of
+ // arrays/maps that has to be traversed to reach the most nested CBORValue
+ // contained in |node|. Primitive values and empty containers have nesting
+ // depths of 0.
+ static base::Optional<std::vector<uint8_t>> Write(
+ const CBORValue& node,
+ size_t max_nesting_level = kDefaultMaxNestingDepth);
private:
CBORWriter(std::vector<uint8_t>* cbor);
// Called recursively to build the CBOR bytestring. When completed,
// |encoded_cbor_| will contain the CBOR.
- void EncodeCBOR(const CBORValue& node);
+ bool EncodeCBOR(const CBORValue& node, int max_nesting_level);
// Encodes the type and size of the data being added.
void StartItem(CborMajorType type, uint64_t size);
diff --git a/chromium/content/browser/webauth/cbor/cbor_writer_unittest.cc b/chromium/content/browser/webauth/cbor/cbor_writer_unittest.cc
index 290f81e276c..a53d0625384 100644
--- a/chromium/content/browser/webauth/cbor/cbor_writer_unittest.cc
+++ b/chromium/content/browser/webauth/cbor/cbor_writer_unittest.cc
@@ -4,6 +4,9 @@
#include "content/browser/webauth/cbor/cbor_writer.h"
+#include <string>
+
+#include "base/strings/string_piece.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -33,8 +36,9 @@ TEST(CBORWriterTest, TestWriteUint) {
};
for (const UintTestCase& test_case : kUintTestCases) {
- std::vector<uint8_t> cbor = CBORWriter::Write(CBORValue(test_case.value));
- EXPECT_THAT(cbor, testing::ElementsAreArray(test_case.cbor));
+ auto cbor = CBORWriter::Write(CBORValue(test_case.value));
+ ASSERT_TRUE(cbor.has_value());
+ EXPECT_THAT(cbor.value(), testing::ElementsAreArray(test_case.cbor));
}
}
@@ -50,8 +54,9 @@ TEST(CBORWriterTest, TestWriteBytes) {
};
for (const BytesTestCase& test_case : kBytesTestCases) {
- std::vector<uint8_t> cbor = CBORWriter::Write(CBORValue(test_case.bytes));
- EXPECT_THAT(cbor, testing::ElementsAreArray(test_case.cbor));
+ auto cbor = CBORWriter::Write(CBORValue(test_case.bytes));
+ ASSERT_TRUE(cbor.has_value());
+ EXPECT_THAT(cbor.value(), testing::ElementsAreArray(test_case.cbor));
}
}
@@ -71,68 +76,231 @@ TEST(CBORWriterTest, TestWriteString) {
{"\xf0\x90\x85\x91", base::StringPiece("\x64\xf0\x90\x85\x91")}};
for (const StringTestCase& test_case : kStringTestCases) {
- std::vector<uint8_t> cbor = CBORWriter::Write(CBORValue(test_case.string));
- EXPECT_THAT(cbor, testing::ElementsAreArray(test_case.cbor));
+ auto cbor = CBORWriter::Write(CBORValue(test_case.string));
+ ASSERT_TRUE(cbor.has_value());
+ EXPECT_THAT(cbor.value(), testing::ElementsAreArray(test_case.cbor));
}
}
TEST(CBORWriterTest, TestWriteArray) {
static const uint8_t kArrayTestCaseCbor[] = {
- 0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
- 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19};
+ // clang-format off
+ 0x98, 0x19, // array of 25 elements
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
+ 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x18, 0x18, 0x19,
+ // clang-format on
+ };
std::vector<CBORValue> array;
for (int i = 1; i <= 25; i++) {
array.push_back(CBORValue(i));
}
- std::vector<uint8_t> cbor = CBORWriter::Write(CBORValue(array));
- EXPECT_THAT(cbor, testing::ElementsAreArray(kArrayTestCaseCbor,
- arraysize(kArrayTestCaseCbor)));
+ auto cbor = CBORWriter::Write(CBORValue(array));
+ ASSERT_TRUE(cbor.has_value());
+ EXPECT_THAT(cbor.value(),
+ testing::ElementsAreArray(kArrayTestCaseCbor,
+ arraysize(kArrayTestCaseCbor)));
}
TEST(CBORWriterTest, TestWriteMapWithMapValue) {
static const uint8_t kMapTestCaseCbor[] = {
- 0xa5, 0x61, 0x61, 0x61, 0x41, 0x61, 0x62, 0x61, 0x42, 0x61, 0x63,
- 0x61, 0x43, 0x61, 0x64, 0x61, 0x44, 0x61, 0x65, 0x61, 0x45};
+ // clang-format off
+ 0xa6, // map of 6 pairs:
+ 0x60, // ""
+ 0x61, 0x2e, // "."
+
+ 0x61, 0x62, // "b"
+ 0x61, 0x42, // "B"
+
+ 0x61, 0x63, // "c"
+ 0x61, 0x43, // "C"
+
+ 0x61, 0x64, // "d"
+ 0x61, 0x44, // "D"
+
+ 0x61, 0x65, // "e"
+ 0x61, 0x45, // "E"
+
+ 0x62, 0x61, 0x61, // "aa"
+ 0x62, 0x41, 0x41, // "AA"
+ // clang-format on
+ };
CBORValue::MapValue map;
- map["a"] = CBORValue("A");
- map["b"] = CBORValue("B");
- map["c"] = CBORValue("C");
+ // Shorter strings sort first in CTAP, thus the “aa” value should be
+ // serialised last in the map.
+ map["aa"] = CBORValue("AA");
map["d"] = CBORValue("D");
+ map["b"] = CBORValue("B");
map["e"] = CBORValue("E");
- std::vector<uint8_t> cbor = CBORWriter::Write(CBORValue(map));
- EXPECT_THAT(cbor, testing::ElementsAreArray(kMapTestCaseCbor,
- arraysize(kMapTestCaseCbor)));
+ map["c"] = CBORValue("C");
+ // The empty string is shorter than all others, so should appear first in the
+ // serialisation.
+ map[""] = CBORValue(".");
+ auto cbor = CBORWriter::Write(CBORValue(map));
+ ASSERT_TRUE(cbor.has_value());
+ EXPECT_THAT(cbor.value(), testing::ElementsAreArray(
+ kMapTestCaseCbor, arraysize(kMapTestCaseCbor)));
}
TEST(CBORWriterTest, TestWriteMapWithArray) {
- static const uint8_t kMapArrayTestCaseCbor[] = {0xa2, 0x61, 0x61, 0x01, 0x61,
- 0x62, 0x82, 0x02, 0x03};
+ static const uint8_t kMapArrayTestCaseCbor[] = {
+ // clang-format off
+ 0xa2, // map of 2 pairs
+ 0x61, 0x61, // "a"
+ 0x01,
+
+ 0x61, 0x62, // "b"
+ 0x82, // array with 2 elements
+ 0x02,
+ 0x03,
+ // clang-format on
+ };
CBORValue::MapValue map;
map["a"] = CBORValue(1);
CBORValue::ArrayValue array;
array.push_back(CBORValue(2));
array.push_back(CBORValue(3));
map["b"] = CBORValue(array);
- std::vector<uint8_t> cbor = CBORWriter::Write(CBORValue(map));
- EXPECT_THAT(cbor,
+ auto cbor = CBORWriter::Write(CBORValue(map));
+ ASSERT_TRUE(cbor.has_value());
+ EXPECT_THAT(cbor.value(),
testing::ElementsAreArray(kMapArrayTestCaseCbor,
arraysize(kMapArrayTestCaseCbor)));
}
TEST(CBORWriterTest, TestWriteNestedMap) {
- static const uint8_t kNestedMapTestCase[] = {0xa2, 0x61, 0x61, 0x01, 0x61,
- 0x62, 0xa2, 0x61, 0x63, 0x02,
- 0x61, 0x64, 0x03};
+ static const uint8_t kNestedMapTestCase[] = {
+ // clang-format off
+ 0xa2, // map of 2 pairs
+ 0x61, 0x61, // "a"
+ 0x01,
+
+ 0x61, 0x62, // "b"
+ 0xa2, // map of 2 pairs
+ 0x61, 0x63, // "c"
+ 0x02,
+
+ 0x61, 0x64, // "d"
+ 0x03,
+ // clang-format on
+ };
CBORValue::MapValue map;
map["a"] = CBORValue(1);
CBORValue::MapValue nested_map;
nested_map["c"] = CBORValue(2);
nested_map["d"] = CBORValue(3);
map["b"] = CBORValue(nested_map);
- std::vector<uint8_t> cbor = CBORWriter::Write(CBORValue(map));
- EXPECT_THAT(cbor, testing::ElementsAreArray(kNestedMapTestCase,
- arraysize(kNestedMapTestCase)));
+ auto cbor = CBORWriter::Write(CBORValue(map));
+ ASSERT_TRUE(cbor.has_value());
+ EXPECT_THAT(cbor.value(),
+ testing::ElementsAreArray(kNestedMapTestCase,
+ arraysize(kNestedMapTestCase)));
+}
+
+// For major type 0, 2, 3, empty CBOR array, and empty CBOR map, the nesting
+// depth is expected to be 0 since the CBOR decoder does not need to parse
+// any nested CBOR value elements.
+TEST(CBORWriterTest, TestWriteSingleLayer) {
+ const CBORValue simple_uint = CBORValue(1);
+ const CBORValue simple_string = CBORValue("a");
+ const std::vector<uint8_t> byte_data = {0x01, 0x02, 0x03, 0x04};
+ const CBORValue simple_bytestring = CBORValue(byte_data);
+ CBORValue::ArrayValue empty_cbor_array;
+ CBORValue::MapValue empty_cbor_map;
+ const CBORValue empty_array_value = CBORValue(empty_cbor_array);
+ const CBORValue empty_map_value = CBORValue(empty_cbor_map);
+ CBORValue::ArrayValue simple_array;
+ simple_array.push_back(CBORValue(2));
+ CBORValue::MapValue simple_map;
+ simple_map["b"] = CBORValue(3);
+ const CBORValue single_layer_cbor_map = CBORValue(simple_map);
+ const CBORValue single_layer_cbor_array = CBORValue(simple_array);
+
+ EXPECT_TRUE(CBORWriter::Write(simple_uint, 0).has_value());
+ EXPECT_TRUE(CBORWriter::Write(simple_string, 0).has_value());
+ EXPECT_TRUE(CBORWriter::Write(simple_bytestring, 0).has_value());
+
+ EXPECT_TRUE(CBORWriter::Write(empty_array_value, 0).has_value());
+ EXPECT_TRUE(CBORWriter::Write(empty_map_value, 0).has_value());
+
+ EXPECT_FALSE(CBORWriter::Write(single_layer_cbor_array, 0).has_value());
+ EXPECT_TRUE(CBORWriter::Write(single_layer_cbor_array, 1).has_value());
+
+ EXPECT_FALSE(CBORWriter::Write(single_layer_cbor_map, 0).has_value());
+ EXPECT_TRUE(CBORWriter::Write(single_layer_cbor_map, 1).has_value());
+}
+
+// Major type 5 nested CBOR map value with following structure.
+// {"a": 1,
+// "b": {"c": 2,
+// "d": 3}}
+TEST(CBORWriterTest, NestedMaps) {
+ CBORValue::MapValue cbor_map;
+ cbor_map["a"] = CBORValue(1);
+ CBORValue::MapValue nested_map;
+ nested_map["c"] = CBORValue(2);
+ nested_map["d"] = CBORValue(3);
+ cbor_map["b"] = CBORValue(nested_map);
+ EXPECT_TRUE(CBORWriter::Write(CBORValue(cbor_map), 2).has_value());
+ EXPECT_FALSE(CBORWriter::Write(CBORValue(cbor_map), 1).has_value());
+}
+
+// Testing Write() function for following CBOR structure with depth of 3.
+// [1,
+// 2,
+// 3,
+// {"a": 1,
+// "b": {"c": 2,
+// "d": 3}}]
+TEST(CBORWriterTest, UnbalancedNestedContainers) {
+ CBORValue::ArrayValue cbor_array;
+ CBORValue::MapValue cbor_map;
+ CBORValue::MapValue nested_map;
+
+ cbor_map["a"] = CBORValue(1);
+ nested_map["c"] = CBORValue(2);
+ nested_map["d"] = CBORValue(3);
+ cbor_map["b"] = CBORValue(nested_map);
+ cbor_array.push_back(CBORValue(1));
+ cbor_array.push_back(CBORValue(2));
+ cbor_array.push_back(CBORValue(3));
+ cbor_array.push_back(CBORValue(cbor_map));
+
+ EXPECT_TRUE(CBORWriter::Write(CBORValue(cbor_array), 3).has_value());
+ EXPECT_FALSE(CBORWriter::Write(CBORValue(cbor_array), 2).has_value());
+}
+
+// Testing Write() function for following CBOR structure.
+// {"a": 1,
+// "b": {"c": 2,
+// "d": 3
+// "h": { "e": 4,
+// "f": 5,
+// "g": [6, 7, [8]]}}}
+// Since above CBOR contains 5 nesting levels. Thus, Write() is expected to
+// return empty optional object when maximum nesting layer size is set to 4.
+TEST(CBORWriterTest, OverlyNestedCBOR) {
+ CBORValue::MapValue map;
+ CBORValue::MapValue nested_map;
+ CBORValue::MapValue inner_nested_map;
+ CBORValue::ArrayValue inner_array;
+ CBORValue::ArrayValue array;
+
+ map["a"] = CBORValue(1);
+ nested_map["c"] = CBORValue(2);
+ nested_map["d"] = CBORValue(3);
+ inner_nested_map["e"] = CBORValue(4);
+ inner_nested_map["f"] = CBORValue(5);
+ inner_array.push_back(CBORValue(6));
+ array.push_back(CBORValue(6));
+ array.push_back(CBORValue(7));
+ array.push_back(CBORValue(inner_array));
+ inner_nested_map["g"] = CBORValue(array);
+ nested_map["h"] = CBORValue(inner_nested_map);
+ map["b"] = CBORValue(nested_map);
+
+ EXPECT_TRUE(CBORWriter::Write(CBORValue(map), 5).has_value());
+ EXPECT_FALSE(CBORWriter::Write(CBORValue(map), 4).has_value());
}
} // namespace content
diff --git a/chromium/content/browser/webauth/collected_client_data.cc b/chromium/content/browser/webauth/collected_client_data.cc
new file mode 100644
index 00000000000..5f3a82af255
--- /dev/null
+++ b/chromium/content/browser/webauth/collected_client_data.cc
@@ -0,0 +1,71 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/webauth/collected_client_data.h"
+
+#include <utility>
+
+#include "base/base64url.h"
+#include "base/json/json_writer.h"
+#include "base/values.h"
+#include "content/browser/webauth/authenticator_utils.h"
+
+namespace content {
+
+// static
+std::unique_ptr<CollectedClientData> CollectedClientData::Create(
+ std::string type,
+ std::string relying_party_id,
+ std::vector<uint8_t> challenge) {
+ // The base64url encoding of options.challenge.
+ std::string encoded_challenge;
+ base::Base64UrlEncode(
+ base::StringPiece(reinterpret_cast<const char*>(challenge.data()),
+ challenge.size()),
+ base::Base64UrlEncodePolicy::OMIT_PADDING, &encoded_challenge);
+
+ // TokenBinding is present and set to the constant "unused" if the browser
+ // supports Token Binding, but is not using it to talk to the origin.
+ // TODO(kpaulhamus): Fetch and add the Token Binding ID public key used to
+ // communicate with the origin.
+ return std::make_unique<CollectedClientData>(
+ std::move(type), std::move(encoded_challenge),
+ std::move(relying_party_id), "SHA-256", "unused");
+}
+
+CollectedClientData::CollectedClientData(std::string type,
+ std::string base64_encoded_challenge,
+ std::string origin,
+ std::string hash_algorithm,
+ std::string token_binding_id)
+ : type_(std::move(type)),
+ base64_encoded_challenge_(std::move(base64_encoded_challenge)),
+ origin_(std::move(origin)),
+ hash_algorithm_(std::move(hash_algorithm)),
+ token_binding_id_(std::move(token_binding_id)) {}
+
+std::string CollectedClientData::SerializeToJson() {
+ base::DictionaryValue client_data;
+ client_data.SetString(authenticator_utils::kTypeKey, type_);
+ client_data.SetString(authenticator_utils::kChallengeKey,
+ base64_encoded_challenge_);
+
+ // The serialization of callerOrigin.
+ client_data.SetString(authenticator_utils::kOriginKey, origin_);
+
+ // The recognized algorithm name of the hash algorithm selected by the client
+ // for generating the hash of the serialized client data.
+ client_data.SetString(authenticator_utils::kHashAlgorithm, hash_algorithm_);
+
+ client_data.SetString(authenticator_utils::kTokenBindingKey,
+ token_binding_id_);
+
+ std::string json;
+ base::JSONWriter::Write(client_data, &json);
+ return json;
+}
+
+CollectedClientData::~CollectedClientData() {}
+
+} // namespace content
diff --git a/chromium/content/browser/webauth/collected_client_data.h b/chromium/content/browser/webauth/collected_client_data.h
new file mode 100644
index 00000000000..35d8f8e5b4b
--- /dev/null
+++ b/chromium/content/browser/webauth/collected_client_data.h
@@ -0,0 +1,56 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEBAUTH_COLLECTED_CLIENT_DATA_H_
+#define CONTENT_BROWSER_WEBAUTH_COLLECTED_CLIENT_DATA_H_
+
+#include <stdint.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+namespace authenticator_utils {
+constexpr char kCreateType[] = "webauthn.create";
+}
+
+// Represents the contextual bindings of both the Relying Party and the
+// client platform that is used in authenticator signatures.
+// https://www.w3.org/TR/2017/WD-webauthn-20170505/#dictdef-collectedclientdata
+class CONTENT_EXPORT CollectedClientData {
+ public:
+ CollectedClientData(std::string type_,
+ std::string base64_encoded_challenge_,
+ std::string origin,
+ std::string hash_algorithm,
+ std::string token_binding_id);
+ virtual ~CollectedClientData();
+
+ static std::unique_ptr<CollectedClientData> Create(
+ std::string type,
+ std::string relying_party_id,
+ std::vector<uint8_t> challenge);
+
+ // Builds a JSON-serialized string per step 13 of
+ // https://www.w3.org/TR/2017/WD-webauthn-20170505/#createCredential.
+ std::string SerializeToJson();
+
+ private:
+ const std::string type_;
+ const std::string base64_encoded_challenge_;
+ const std::string origin_;
+ const std::string hash_algorithm_;
+ const std::string token_binding_id_;
+ // TODO(kpaulhamus): Add extensions support. https://crbug/757502.
+
+ DISALLOW_COPY_AND_ASSIGN(CollectedClientData);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEBAUTH_COLLECTED_CLIENT_DATA_H_
diff --git a/chromium/content/browser/webauth/ec_public_key.cc b/chromium/content/browser/webauth/ec_public_key.cc
new file mode 100644
index 00000000000..65c910ed44f
--- /dev/null
+++ b/chromium/content/browser/webauth/ec_public_key.cc
@@ -0,0 +1,54 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/webauth/ec_public_key.h"
+
+#include <utility>
+
+#include "content/browser/webauth/authenticator_utils.h"
+#include "content/browser/webauth/cbor/cbor_writer.h"
+
+namespace content {
+
+// static
+std::unique_ptr<ECPublicKey> ECPublicKey::ExtractFromU2fRegistrationResponse(
+ std::string algorithm,
+ const std::vector<uint8_t>& u2f_data) {
+ // Extract the key, which is located after the first byte of the response
+ // (which is a reserved byte).
+ // The uncompressed form consists of 65 bytes:
+ // - a constant 0x04 prefix
+ // - the 32-byte x coordinate
+ // - the 32-byte y coordinate.
+ int start = 2; // Account for reserved byte and 0x04 prefix.
+ std::vector<uint8_t> x = authenticator_utils::Extract(u2f_data, start, 32);
+ std::vector<uint8_t> y =
+ authenticator_utils::Extract(u2f_data, start + 32, 32);
+ return std::make_unique<ECPublicKey>(std::move(algorithm), std::move(x),
+ std::move(y));
+}
+
+ECPublicKey::ECPublicKey(std::string algorithm,
+ std::vector<uint8_t> x,
+ std::vector<uint8_t> y)
+ : PublicKey(std::move(algorithm)),
+ x_coordinate_(std::move(x)),
+ y_coordinate_(std::move(y)) {
+ DCHECK_EQ(x_coordinate_.size(), 32u);
+ DCHECK_EQ(y_coordinate_.size(), 32u);
+}
+
+std::vector<uint8_t> ECPublicKey::EncodeAsCBOR() {
+ CBORValue::MapValue map;
+ map["alg"] = CBORValue(algorithm_.c_str());
+ map["x"] = CBORValue(x_coordinate_);
+ map["y"] = CBORValue(y_coordinate_);
+ auto cbor = CBORWriter::Write(CBORValue(map));
+ DCHECK(cbor.has_value());
+ return cbor.value();
+}
+
+ECPublicKey::~ECPublicKey() {}
+
+} // namespace content
diff --git a/chromium/content/browser/webauth/ec_public_key.h b/chromium/content/browser/webauth/ec_public_key.h
new file mode 100644
index 00000000000..45b1ffb5231
--- /dev/null
+++ b/chromium/content/browser/webauth/ec_public_key.h
@@ -0,0 +1,48 @@
+// Copyright 2017 The Chromium Authors. 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_WEBAUTH_EC_PUBLIC_KEY_H_
+#define CONTENT_BROWSER_WEBAUTH_EC_PUBLIC_KEY_H_
+
+#include <stdint.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "content/browser/webauth/public_key.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// An uncompressed ECPublicKey consisting of 64 bytes:
+// - the 32-byte x coordinate
+// - the 32-byte y coordinate.
+class CONTENT_EXPORT ECPublicKey : public PublicKey {
+ public:
+ ECPublicKey(std::string algorithm,
+ std::vector<uint8_t> x,
+ std::vector<uint8_t> y);
+
+ ~ECPublicKey() override;
+
+ static std::unique_ptr<ECPublicKey> ExtractFromU2fRegistrationResponse(
+ std::string algorithm,
+ const std::vector<uint8_t>& u2f_data);
+
+ // Produces a CBOR-encoded public key encoded in the following format:
+ // { alg: eccAlgName, x: biguint, y: biguint }
+ // where eccAlgName = "ES256" / "ES384" / "ES512"
+ std::vector<uint8_t> EncodeAsCBOR() override;
+
+ private:
+ const std::vector<uint8_t> x_coordinate_;
+ const std::vector<uint8_t> y_coordinate_;
+
+ DISALLOW_COPY_AND_ASSIGN(ECPublicKey);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEBAUTH_EC_PUBLIC_KEY_H_
diff --git a/chromium/content/browser/webauth/fido_attestation_statement.cc b/chromium/content/browser/webauth/fido_attestation_statement.cc
new file mode 100644
index 00000000000..f4f00d442b6
--- /dev/null
+++ b/chromium/content/browser/webauth/fido_attestation_statement.cc
@@ -0,0 +1,102 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/webauth/fido_attestation_statement.h"
+
+#include <utility>
+
+#include "base/numerics/safe_conversions.h"
+#include "content/browser/webauth/authenticator_utils.h"
+#include "content/browser/webauth/cbor/cbor_writer.h"
+
+namespace content {
+
+namespace {
+constexpr char kFidoFormatName[] = "fido-u2f";
+constexpr char kSignatureKey[] = "sig";
+constexpr char kX509CertKey[] = "x5c";
+} // namespace
+
+// static
+std::unique_ptr<FidoAttestationStatement>
+FidoAttestationStatement::CreateFromU2fRegisterResponse(
+ const std::vector<uint8_t>& u2f_data) {
+ std::vector<std::vector<uint8_t>> x509_certificates;
+ std::vector<uint8_t> x509_cert;
+
+ // Extract the length length of the credential (i.e. of U2FResponse key
+ // handle). Length is big endian and is located at position 66 in the data.
+ // Note that U2F responses only use one byte for length.
+ std::vector<uint8_t> id_length(2, 0);
+ CHECK_GE(u2f_data.size(), authenticator_utils::kU2fResponseLengthPos + 1);
+ id_length[1] = u2f_data[authenticator_utils::kU2fResponseLengthPos];
+ size_t id_end_byte = authenticator_utils::kU2fResponseKeyHandleStartPos +
+ ((base::strict_cast<uint32_t>(id_length[0]) << 8) |
+ (base::strict_cast<uint32_t>(id_length[1])));
+
+ // Parse x509 cert to get cert length (which is variable).
+ // TODO: Support responses with multiple certs.
+ int num_bytes = 0;
+ uint32_t cert_length = 0;
+ // The first x509 byte is a tag, so we skip it.
+ size_t first_length_byte =
+ base::strict_cast<size_t>(u2f_data[id_end_byte + 1]);
+
+ // If the first length byte is less than 127, it is the length. If it is
+ // greater than 128, it indicates the number of following bytes that encode
+ // the length.
+ if (first_length_byte > 127) {
+ num_bytes = first_length_byte - 128;
+
+ // x509 cert length, interpreted big-endian.
+ for (int i = 1; i <= num_bytes; i++) {
+ // Account for tag byte and length details byte.
+ cert_length |= base::checked_cast<uint32_t>(u2f_data[id_end_byte + 1 + i]
+ << ((num_bytes - i) * 8));
+ }
+ } else {
+ cert_length = first_length_byte;
+ }
+
+ size_t x509_length = 1 /* tag byte */ + 1 /* first length byte */
+ + num_bytes /* # bytes of length */ + cert_length;
+
+ authenticator_utils::Append(
+ &x509_cert,
+ authenticator_utils::Extract(u2f_data, id_end_byte, x509_length));
+ x509_certificates.push_back(x509_cert);
+
+ // The remaining bytes are the signature.
+ std::vector<uint8_t> signature;
+ size_t signature_start_byte = id_end_byte + x509_length;
+ authenticator_utils::Append(
+ &signature,
+ authenticator_utils::Extract(u2f_data, signature_start_byte,
+ u2f_data.size() - signature_start_byte));
+ return std::make_unique<FidoAttestationStatement>(signature,
+ x509_certificates);
+}
+
+FidoAttestationStatement::FidoAttestationStatement(
+ std::vector<uint8_t> signature,
+ std::vector<std::vector<uint8_t>> x509_certificates)
+ : AttestationStatement(kFidoFormatName),
+ signature_(std::move(signature)),
+ x509_certificates_(std::move(x509_certificates)) {}
+
+CBORValue::MapValue FidoAttestationStatement::GetAsCBORMap() {
+ CBORValue::MapValue attstmt_map;
+ attstmt_map[kSignatureKey] = CBORValue(signature_);
+
+ std::vector<CBORValue> array;
+ for (auto cert : x509_certificates_) {
+ array.push_back(CBORValue(cert));
+ }
+ attstmt_map[kX509CertKey] = CBORValue(array);
+ return attstmt_map;
+}
+
+FidoAttestationStatement::~FidoAttestationStatement() {}
+
+} // namespace content
diff --git a/chromium/content/browser/webauth/fido_attestation_statement.h b/chromium/content/browser/webauth/fido_attestation_statement.h
new file mode 100644
index 00000000000..bf1b34925c3
--- /dev/null
+++ b/chromium/content/browser/webauth/fido_attestation_statement.h
@@ -0,0 +1,43 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEBAUTH_FIDO_ATTESTATION_STATEMENT_H_
+#define CONTENT_BROWSER_WEBAUTH_FIDO_ATTESTATION_STATEMENT_H_
+
+#include <stdint.h>
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "content/browser/webauth/attestation_statement.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// https://www.w3.org/TR/2017/WD-webauthn-20170505/#fido-u2f-attestation
+class CONTENT_EXPORT FidoAttestationStatement : public AttestationStatement {
+ public:
+ FidoAttestationStatement(std::vector<uint8_t> signature,
+ std::vector<std::vector<uint8_t>> x509_certificates);
+ ~FidoAttestationStatement() override;
+
+ static std::unique_ptr<FidoAttestationStatement>
+ CreateFromU2fRegisterResponse(const std::vector<uint8_t>& u2f_data);
+
+ // AttestationStatement overrides
+
+ // Produces a map in the following format:
+ // { "x5c": [ x509_certs bytes ], "sig": signature bytes ] }
+ CBORValue::MapValue GetAsCBORMap() override;
+
+ private:
+ const std::vector<uint8_t> signature_;
+ const std::vector<std::vector<uint8_t>> x509_certificates_;
+
+ DISALLOW_COPY_AND_ASSIGN(FidoAttestationStatement);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEBAUTH_FIDO_ATTESTATION_STATEMENT_H_
diff --git a/chromium/content/browser/webauth/public_key.cc b/chromium/content/browser/webauth/public_key.cc
new file mode 100644
index 00000000000..10d0c7edd3a
--- /dev/null
+++ b/chromium/content/browser/webauth/public_key.cc
@@ -0,0 +1,18 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/webauth/public_key.h"
+
+#include <utility>
+
+#include "base/macros.h"
+
+namespace content {
+
+PublicKey::PublicKey(std::string algorithm)
+ : algorithm_(std::move(algorithm)) {}
+
+PublicKey::~PublicKey() {}
+
+} // namespace content
diff --git a/chromium/content/browser/webauth/public_key.h b/chromium/content/browser/webauth/public_key.h
new file mode 100644
index 00000000000..dc1ca2919f6
--- /dev/null
+++ b/chromium/content/browser/webauth/public_key.h
@@ -0,0 +1,35 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEBAUTH_PUBLIC_KEY_H_
+#define CONTENT_BROWSER_WEBAUTH_PUBLIC_KEY_H_
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+
+namespace content {
+
+// https://www.w3.org/TR/2017/WD-webauthn-20170505/#sec-attestation-data.
+class PublicKey {
+ public:
+ virtual ~PublicKey();
+
+ // The credential public key as a CBOR map according to a format
+ // defined per public key type.
+ virtual std::vector<uint8_t> EncodeAsCBOR() = 0;
+
+ protected:
+ PublicKey(const std::string algorithm);
+ const std::string algorithm_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PublicKey);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEBAUTH_PUBLIC_KEY_H_
diff --git a/chromium/content/browser/webauth/register_response_data.cc b/chromium/content/browser/webauth/register_response_data.cc
new file mode 100644
index 00000000000..73d4ca8f1f3
--- /dev/null
+++ b/chromium/content/browser/webauth/register_response_data.cc
@@ -0,0 +1,89 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/webauth/register_response_data.h"
+
+#include <utility>
+
+#include "content/browser/webauth/attested_credential_data.h"
+#include "content/browser/webauth/authenticator_utils.h"
+#include "content/browser/webauth/ec_public_key.h"
+#include "content/browser/webauth/fido_attestation_statement.h"
+
+namespace content {
+
+// static
+std::unique_ptr<RegisterResponseData>
+RegisterResponseData::CreateFromU2fRegisterResponse(
+ std::unique_ptr<CollectedClientData> client_data,
+ std::vector<uint8_t> u2f_data) {
+ std::unique_ptr<ECPublicKey> public_key =
+ ECPublicKey::ExtractFromU2fRegistrationResponse(
+ authenticator_utils::kEs256, u2f_data);
+
+ // Construct the attestation data.
+ // AAGUID is zeroed out for U2F responses.
+ std::vector<uint8_t> aaguid(16u, 0u);
+ std::unique_ptr<AttestedCredentialData> attested_data =
+ AttestedCredentialData::CreateFromU2fRegisterResponse(
+ u2f_data, std::move(aaguid), std::move(public_key));
+
+ // Extract the credential_id for packing into the reponse data.
+ std::vector<uint8_t> credential_id = attested_data->credential_id();
+
+ // Construct the authenticator data.
+ // The counter is zeroed out for Register requests.
+ std::vector<uint8_t> counter(4u, 0u);
+ AuthenticatorData::Flags flags =
+ static_cast<AuthenticatorData::Flags>(
+ AuthenticatorData::Flag::TEST_OF_USER_PRESENCE) |
+ static_cast<AuthenticatorData::Flags>(
+ AuthenticatorData::Flag::ATTESTATION);
+
+ std::unique_ptr<AuthenticatorData> authenticator_data =
+ AuthenticatorData::Create(client_data->SerializeToJson(), flags,
+ std::move(counter), std::move(attested_data));
+
+ // Construct the attestation statement.
+ std::unique_ptr<FidoAttestationStatement> fido_attestation_statement =
+ FidoAttestationStatement::CreateFromU2fRegisterResponse(u2f_data);
+
+ // Construct the attestation object.
+ auto attestation_object = std::make_unique<AttestationObject>(
+ std::move(authenticator_data), std::move(fido_attestation_statement));
+
+ return std::make_unique<RegisterResponseData>(std::move(client_data),
+ std::move(credential_id),
+ std::move(attestation_object));
+}
+
+RegisterResponseData::RegisterResponseData(
+ std::unique_ptr<CollectedClientData> client_data,
+ std::vector<uint8_t> credential_id,
+ std::unique_ptr<AttestationObject> object)
+ : client_data_(std::move(client_data)),
+ raw_id_(std::move(credential_id)),
+ attestation_object_(std::move(object)) {}
+
+std::vector<uint8_t> RegisterResponseData::GetClientDataJSONBytes() {
+ std::string client_data_json = client_data_->SerializeToJson();
+ return std::vector<uint8_t>(client_data_json.begin(), client_data_json.end());
+}
+
+std::vector<uint8_t> RegisterResponseData::GetCBOREncodedAttestationObject() {
+ return attestation_object_->SerializeToCBOREncodedBytes();
+}
+
+std::string RegisterResponseData::GetId() {
+ std::string id;
+ base::Base64UrlEncode(
+ base::StringPiece(reinterpret_cast<const char*>(raw_id_.data()),
+ raw_id_.size()),
+ base::Base64UrlEncodePolicy::OMIT_PADDING, &id);
+ return id;
+}
+
+RegisterResponseData::~RegisterResponseData() {}
+
+} // namespace content
diff --git a/chromium/content/browser/webauth/register_response_data.h b/chromium/content/browser/webauth/register_response_data.h
new file mode 100644
index 00000000000..29e9cc4089e
--- /dev/null
+++ b/chromium/content/browser/webauth/register_response_data.h
@@ -0,0 +1,52 @@
+// Copyright 2017 The Chromium Authors. 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_WEBAUTH_REGISTER_RESPONSE_DATA_H_
+#define CONTENT_BROWSER_WEBAUTH_REGISTER_RESPONSE_DATA_H_
+
+#include <stdint.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/base64url.h"
+#include "base/macros.h"
+#include "content/browser/webauth/attestation_object.h"
+#include "content/browser/webauth/collected_client_data.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// See figure 2:
+// https://fidoalliance.org/specs/fido-v2.0-rd-20170927/ \
+// fido-client-to-authenticator-protocol-v2.0-rd-20170927.html#using-the- \
+// ctap2-authenticatormakecredential-command-with-ctap1-u2f-authenticators
+class CONTENT_EXPORT RegisterResponseData {
+ public:
+ RegisterResponseData(std::unique_ptr<CollectedClientData> client_data,
+ std::vector<uint8_t> credential_id,
+ std::unique_ptr<AttestationObject> object);
+
+ static std::unique_ptr<RegisterResponseData> CreateFromU2fRegisterResponse(
+ std::unique_ptr<CollectedClientData> client_data,
+ std::vector<uint8_t> u2f_data);
+
+ virtual ~RegisterResponseData();
+
+ std::vector<uint8_t> GetClientDataJSONBytes();
+ std::string GetId();
+ std::vector<uint8_t> GetCBOREncodedAttestationObject();
+ const std::vector<uint8_t>& raw_id() { return raw_id_; }
+
+ private:
+ const std::unique_ptr<CollectedClientData> client_data_;
+ const std::vector<uint8_t> raw_id_;
+ const std::unique_ptr<AttestationObject> attestation_object_;
+
+ DISALLOW_COPY_AND_ASSIGN(RegisterResponseData);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEBAUTH_REGISTER_RESPONSE_DATA_H_
diff --git a/chromium/content/browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc b/chromium/content/browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc
index 82495dbd273..034b29d3b13 100644
--- a/chromium/content/browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc
@@ -4,6 +4,8 @@
#include <stdint.h>
+#include "base/files/file_enumerator.h"
+#include "base/files/file_path.h"
#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
@@ -25,14 +27,11 @@
namespace {
const int kExpectedConsumerId = 1;
-const int kExpectedInputStreamId = 1;
-const int kExpectedFirstOutputStreamId = 1;
const int kWaveHeaderSizeBytes = 44;
const base::FilePath::CharType kBaseFilename[] =
FILE_PATH_LITERAL("audio_debug");
-const base::FilePath::CharType kWaveExtension[] = FILE_PATH_LITERAL("wav");
// Get the ID for the render process host when there should only be one.
bool GetRenderProcessHostId(base::ProcessId* id) {
@@ -57,27 +56,24 @@ base::FilePath GetExpectedAecDumpFileName(const base::FilePath& base_file_path,
.AddExtension(IntToStringType(kExpectedConsumerId));
}
-// Get the expected input audio file name. The name will be
-// <temporary path>.<render process id>.source_input.<stream id>.wav, for
-// example "/tmp/.com.google.Chrome.Z6UC3P.12345.source_input.1.wav".
-base::FilePath GetExpectedInputAudioFileName(
- const base::FilePath& base_file_path,
- int render_process_id) {
- return base_file_path.AddExtension(IntToStringType(render_process_id))
- .AddExtension(FILE_PATH_LITERAL("source_input"))
- .AddExtension(IntToStringType(kExpectedInputStreamId))
- .AddExtension(kWaveExtension);
-}
-
-// Get the expected output audio file name. The name will be
-// <temporary path>.output.<running stream id>.wav, for example
-// "/tmp/.com.google.Chrome.Z6UC3P.output.1.wav".
-base::FilePath GetExpectedOutputAudioFileName(
- const base::FilePath& base_file_path,
- int id) {
- return base_file_path.AddExtension(FILE_PATH_LITERAL("output"))
- .AddExtension(IntToStringType(id))
- .AddExtension(kWaveExtension);
+// Get the file names of the recordings. The name will be
+// <temporary path>.<kind>.<running stream id>.wav, for example
+// "/tmp/.com.google.Chrome.Z6UC3P.output.1.wav". |kind| is output or input.
+std::vector<base::FilePath> GetRecordingFileNames(
+ base::FilePath::StringPieceType kind,
+ const base::FilePath& base_file_path) {
+ base::FilePath dir = base_file_path.DirName();
+ base::FilePath file = base_file_path.BaseName();
+ // Assumes single-character id.
+ base::FileEnumerator recording_files(
+ dir, /*recursive*/ false, base::FileEnumerator::FileType::FILES,
+ file.AddExtension(kind).AddExtension(FILE_PATH_LITERAL("?.wav")).value());
+ std::vector<base::FilePath> ret;
+ for (base::FilePath path = recording_files.Next(); !path.empty();
+ path = recording_files.Next()) {
+ ret.push_back(std::move(path));
+ }
+ return ret;
}
} // namespace
@@ -97,8 +93,9 @@ class WebRtcAudioDebugRecordingsBrowserTest
#if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
// Renderer crashes under Android ASAN: https://crbug.com/408496.
#define MAYBE_CallWithAudioDebugRecordings DISABLED_CallWithAudioDebugRecordings
-#elif defined(OS_ANDROID)
+#elif (defined(OS_ANDROID) || defined(OS_WIN))
// Renderer crashes on Android M. https://crbug.com/535728.
+// Flaky on Windows. https://crbug.com/783790
#define MAYBE_CallWithAudioDebugRecordings DISABLED_CallWithAudioDebugRecordings
#else
#define MAYBE_CallWithAudioDebugRecordings CallWithAudioDebugRecordings
@@ -132,7 +129,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
// This fakes the behavior of another open tab with webrtc-internals, and
// enabling audio debug recordings in that tab.
- WebRTCInternals::GetInstance()->FileSelected(base_file_path, -1, NULL);
+ WebRTCInternals::GetInstance()->FileSelected(base_file_path, -1, nullptr);
// Make a call.
GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
@@ -154,19 +151,20 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
EXPECT_TRUE(base::DeleteFile(file_path, false));
// Verify that the expected input audio file exists and contains some data.
- file_path = GetExpectedInputAudioFileName(base_file_path, render_process_id);
- EXPECT_TRUE(base::PathExists(file_path));
+ std::vector<base::FilePath> input_files =
+ GetRecordingFileNames(FILE_PATH_LITERAL("input"), base_file_path);
+ EXPECT_EQ(input_files.size(), 1u);
file_size = 0;
- EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
+ EXPECT_TRUE(base::GetFileSize(input_files[0], &file_size));
EXPECT_GT(file_size, kWaveHeaderSizeBytes);
- EXPECT_TRUE(base::DeleteFile(file_path, false));
+ EXPECT_TRUE(base::DeleteFile(input_files[0], false));
// Verify that the expected output audio files exists and contains some data.
// Two files are expected, one for each peer in the call.
- for (int i = 0; i < 2; ++i) {
- file_path = GetExpectedOutputAudioFileName(
- base_file_path, kExpectedFirstOutputStreamId + i);
- EXPECT_TRUE(base::PathExists(file_path));
+ std::vector<base::FilePath> output_files =
+ GetRecordingFileNames(FILE_PATH_LITERAL("output"), base_file_path);
+ EXPECT_EQ(output_files.size(), 2u);
+ for (const base::FilePath& file_path : output_files) {
file_size = 0;
EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
EXPECT_GT(file_size, kWaveHeaderSizeBytes);
@@ -216,7 +214,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
// This fakes the behavior of another open tab with webrtc-internals, and
// enabling audio debug recordings in that tab, then disabling it.
- WebRTCInternals::GetInstance()->FileSelected(base_file_path, -1, NULL);
+ WebRTCInternals::GetInstance()->FileSelected(base_file_path, -1, nullptr);
WebRTCInternals::GetInstance()->DisableAudioDebugRecordings();
// Make a call.
@@ -271,7 +269,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
// This fakes the behavior of another open tab with webrtc-internals, and
// enabling audio debug recordings in that tab.
- WebRTCInternals::GetInstance()->FileSelected(base_file_path, -1, NULL);
+ WebRTCInternals::GetInstance()->FileSelected(base_file_path, -1, nullptr);
// Make the calls.
GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
@@ -306,11 +304,13 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
EXPECT_GT(file_size, 0);
EXPECT_TRUE(base::DeleteFile(file_path, false));
+ }
- // Verify that the expected input audio file exists and contains some data.
- file_path =
- GetExpectedInputAudioFileName(base_file_path, render_process_id);
- EXPECT_TRUE(base::PathExists(file_path));
+ // Verify that the expected input audio files exist and contains some data.
+ std::vector<base::FilePath> input_files =
+ GetRecordingFileNames(FILE_PATH_LITERAL("input"), base_file_path);
+ EXPECT_EQ(input_files.size(), 2u);
+ for (const base::FilePath& file_path : input_files) {
file_size = 0;
EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
EXPECT_GT(file_size, kWaveHeaderSizeBytes);
@@ -320,10 +320,10 @@ IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
// Verify that the expected output audio files exists and contains some data.
// Four files are expected, one for each peer in each call. (Two calls * two
// peers.)
- for (int i = 0; i < 4; ++i) {
- file_path = GetExpectedOutputAudioFileName(
- base_file_path, kExpectedFirstOutputStreamId + i);
- EXPECT_TRUE(base::PathExists(file_path));
+ std::vector<base::FilePath> output_files =
+ GetRecordingFileNames(FILE_PATH_LITERAL("output"), base_file_path);
+ EXPECT_EQ(output_files.size(), 4u);
+ for (const base::FilePath& file_path : output_files) {
file_size = 0;
EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
EXPECT_GT(file_size, kWaveHeaderSizeBytes);
diff --git a/chromium/content/browser/webrtc/webrtc_browsertest.cc b/chromium/content/browser/webrtc/webrtc_browsertest.cc
index 02ea40d8b0e..68dda3929b1 100644
--- a/chromium/content/browser/webrtc/webrtc_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_browsertest.cc
@@ -53,6 +53,15 @@ class MAYBE_WebRtcBrowserTest : public WebRtcContentBrowserTestBase {
}
};
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, CanSetupAudioAndVideoCall) {
+ MakeTypicalPeerConnectionCall("call({video: true, audio: true});");
+}
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
+ CanSetupDefaultVideoCallWithOldGetUserMedia) {
+ MakeTypicalPeerConnectionCall("oldStyleCall();");
+}
+
// These tests will make a complete PeerConnection-based call and verify that
// video is playing for the call.
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
@@ -94,11 +103,6 @@ IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
MakeTypicalPeerConnectionCall(javascript);
}
-IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
- CanSetupAudioAndVideoCall) {
- MakeTypicalPeerConnectionCall("call({video: true, audio: true});");
-}
-
#if defined(OS_WIN) && !defined(NVALGRIND)
// Times out on Dr. Memory bots: https://crbug.com/545740
diff --git a/chromium/content/browser/webrtc/webrtc_capture_from_element_browsertest.cc b/chromium/content/browser/webrtc/webrtc_capture_from_element_browsertest.cc
index 2a5989cd101..bca86ebc788 100644
--- a/chromium/content/browser/webrtc/webrtc_capture_from_element_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_capture_from_element_browsertest.cc
@@ -7,6 +7,7 @@
#include "build/build_config.h"
#include "content/browser/webrtc/webrtc_content_browsertest_base.h"
#include "content/public/common/content_switches.h"
+#include "content/shell/common/shell_switches.h"
#include "media/base/media_switches.h"
#include "media/base/test_data_util.h"
#include "media/mojo/features.h"
@@ -70,6 +71,9 @@ class WebRtcCaptureFromElementBrowserTest
// Allow experimental canvas features.
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalCanvasFeatures);
+ // Allow window.internals for simulating context loss.
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kExposeInternalsForTesting);
}
private:
@@ -78,7 +82,7 @@ class WebRtcCaptureFromElementBrowserTest
IN_PROC_BROWSER_TEST_F(WebRtcCaptureFromElementBrowserTest,
VerifyCanvas2DCaptureColor) {
- MakeTypicalCall("testCanvas2DCaptureColors();",
+ MakeTypicalCall("testCanvas2DCaptureColors(true);",
kCanvasCaptureColorTestHtmlFile);
}
@@ -88,7 +92,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcCaptureFromElementBrowserTest,
// TODO(crbug.com/706009): Make this test pass on mac. Behavior is not buggy
// (verified manually) on mac, but for some reason this test fails on the mac
// bot.
- MakeTypicalCall("testCanvasWebGLCaptureColors();",
+ MakeTypicalCall("testCanvasWebGLCaptureColors(true);",
kCanvasCaptureColorTestHtmlFile);
#endif
}
@@ -143,6 +147,18 @@ IN_PROC_BROWSER_TEST_P(WebRtcCaptureFromElementBrowserTest,
kVideoAudioHtmlFile);
}
+IN_PROC_BROWSER_TEST_F(WebRtcCaptureFromElementBrowserTest,
+ CaptureFromCanvas2DHandlesContextLoss) {
+ MakeTypicalCall("testCanvas2DContextLoss(true);",
+ kCanvasCaptureColorTestHtmlFile);
+}
+
+IN_PROC_BROWSER_TEST_F(WebRtcCaptureFromElementBrowserTest,
+ CaptureFromOpaqueCanvas2DHandlesContextLoss) {
+ MakeTypicalCall("testCanvas2DContextLoss(false);",
+ kCanvasCaptureColorTestHtmlFile);
+}
+
INSTANTIATE_TEST_CASE_P(,
WebRtcCaptureFromElementBrowserTest,
testing::ValuesIn(kFileAndTypeParameters));
diff --git a/chromium/content/browser/webrtc/webrtc_eventlog_host.cc b/chromium/content/browser/webrtc/webrtc_eventlog_host.cc
index 14235fe97f8..42c0771b430 100644
--- a/chromium/content/browser/webrtc/webrtc_eventlog_host.cc
+++ b/chromium/content/browser/webrtc/webrtc_eventlog_host.cc
@@ -25,8 +25,6 @@
namespace content {
-int WebRTCEventLogHost::number_active_log_files_ = 0;
-
namespace {
// In addition to the limit to the number of files given below, the size of the
@@ -46,11 +44,11 @@ base::FilePath GetWebRtcEventLogPath(const base::FilePath& base_file,
}
// Opens a logfile to pass on to the renderer.
-IPC::PlatformFileForTransit CreateFileForProcess(
+IPC::PlatformFileForTransit CreateEventLogFileForChildProcess(
const base::FilePath& base_path,
int render_process_id,
int connection_id) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
base::FilePath file_path =
GetWebRtcEventLogPath(base_path, render_process_id, connection_id);
base::File event_log_file(
@@ -77,6 +75,9 @@ WebRTCEventLogHost::WebRTCEventLogHost(int render_process_id)
WebRTCEventLogHost::~WebRTCEventLogHost() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ for (int lid : active_peer_connection_local_ids_) {
+ RtcEventLogRemoved(lid);
+ }
}
void WebRTCEventLogHost::PeerConnectionAdded(int peer_connection_local_id) {
@@ -87,7 +88,7 @@ void WebRTCEventLogHost::PeerConnectionAdded(int peer_connection_local_id) {
active_peer_connection_local_ids_.end()) {
active_peer_connection_local_ids_.push_back(peer_connection_local_id);
if (rtc_event_logging_enabled_ &&
- number_active_log_files_ < kMaxNumberLogFiles) {
+ ActivePeerConnectionsWithLogFiles().size() < kMaxNumberLogFiles) {
StartEventLogForPeerConnection(peer_connection_local_id);
}
}
@@ -95,12 +96,13 @@ void WebRTCEventLogHost::PeerConnectionAdded(int peer_connection_local_id) {
void WebRTCEventLogHost::PeerConnectionRemoved(int peer_connection_local_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- const auto found = std::find(active_peer_connection_local_ids_.begin(),
- active_peer_connection_local_ids_.end(),
- peer_connection_local_id);
- if (found != active_peer_connection_local_ids_.end()) {
- active_peer_connection_local_ids_.erase(found);
+ const auto lid = std::find(active_peer_connection_local_ids_.begin(),
+ active_peer_connection_local_ids_.end(),
+ peer_connection_local_id);
+ if (lid != active_peer_connection_local_ids_.end()) {
+ active_peer_connection_local_ids_.erase(lid);
}
+ RtcEventLogRemoved(peer_connection_local_id);
}
bool WebRTCEventLogHost::StartWebRTCEventLog(const base::FilePath& file_path) {
@@ -116,15 +118,17 @@ bool WebRTCEventLogHost::StartWebRTCEventLog(const base::FilePath& file_path) {
bool WebRTCEventLogHost::StopWebRTCEventLog() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!rtc_event_logging_enabled_)
+ if (!rtc_event_logging_enabled_) {
+ DCHECK(ActivePeerConnectionsWithLogFiles().empty());
return false;
- number_active_log_files_ = 0;
+ }
rtc_event_logging_enabled_ = false;
RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_);
if (host) {
for (int local_id : active_peer_connection_local_ids_)
host->Send(new PeerConnectionTracker_StopEventLog(local_id));
}
+ ActivePeerConnectionsWithLogFiles().clear();
return true;
}
@@ -132,25 +136,34 @@ base::WeakPtr<WebRTCEventLogHost> WebRTCEventLogHost::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
-bool WebRTCEventLogHost::StartEventLogForPeerConnection(
+std::vector<WebRTCEventLogHost::PeerConnectionKey>&
+WebRTCEventLogHost::ActivePeerConnectionsWithLogFiles() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ CR_DEFINE_STATIC_LOCAL(std::vector<WebRTCEventLogHost::PeerConnectionKey>,
+ vector, ());
+ return vector;
+}
+
+void WebRTCEventLogHost::StartEventLogForPeerConnection(
int peer_connection_local_id) {
- if (number_active_log_files_ < kMaxNumberLogFiles) {
- ++number_active_log_files_;
+ if (ActivePeerConnectionsWithLogFiles().size() < kMaxNumberLogFiles) {
+ RtcEventLogAdded(peer_connection_local_id);
base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
- base::Bind(&CreateFileForProcess, base_file_path_, render_process_id_,
- peer_connection_local_id),
+ base::Bind(&CreateEventLogFileForChildProcess, base_file_path_,
+ render_process_id_, peer_connection_local_id),
base::Bind(&WebRTCEventLogHost::SendEventLogFileToRenderer,
weak_ptr_factory_.GetWeakPtr(), peer_connection_local_id));
}
- return true;
}
void WebRTCEventLogHost::SendEventLogFileToRenderer(
int peer_connection_local_id,
IPC::PlatformFileForTransit file_for_transit) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (file_for_transit == IPC::InvalidPlatformFileForTransit()) {
- --number_active_log_files_;
+ bool removed = RtcEventLogRemoved(peer_connection_local_id);
+ DCHECK(removed);
return;
}
RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id_);
@@ -158,9 +171,36 @@ void WebRTCEventLogHost::SendEventLogFileToRenderer(
rph->Send(new PeerConnectionTracker_StartEventLog(peer_connection_local_id,
file_for_transit));
} else {
- --number_active_log_files_;
+ bool removed = RtcEventLogRemoved(peer_connection_local_id);
+ DCHECK(removed);
IPC::PlatformFileForTransitToFile(file_for_transit).Close();
}
}
+void WebRTCEventLogHost::RtcEventLogAdded(int peer_connection_local_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ auto& active_peer_connections_with_log_files =
+ ActivePeerConnectionsWithLogFiles();
+ PeerConnectionKey pc_key = {render_process_id_, peer_connection_local_id};
+ DCHECK(std::find(active_peer_connections_with_log_files.begin(),
+ active_peer_connections_with_log_files.end(),
+ pc_key) == active_peer_connections_with_log_files.end());
+ active_peer_connections_with_log_files.push_back(pc_key);
+}
+
+bool WebRTCEventLogHost::RtcEventLogRemoved(int peer_connection_local_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ auto& active_peer_connections_with_log_files =
+ ActivePeerConnectionsWithLogFiles();
+ PeerConnectionKey pc_key = {render_process_id_, peer_connection_local_id};
+ const auto it =
+ std::find(active_peer_connections_with_log_files.begin(),
+ active_peer_connections_with_log_files.end(), pc_key);
+ if (it != active_peer_connections_with_log_files.end()) {
+ active_peer_connections_with_log_files.erase(it);
+ return true;
+ }
+ return false;
+}
+
} // namespace content
diff --git a/chromium/content/browser/webrtc/webrtc_eventlog_host.h b/chromium/content/browser/webrtc/webrtc_eventlog_host.h
index aa030fb94f9..ca08e207fc2 100644
--- a/chromium/content/browser/webrtc/webrtc_eventlog_host.h
+++ b/chromium/content/browser/webrtc/webrtc_eventlog_host.h
@@ -43,14 +43,31 @@ class CONTENT_EXPORT WebRTCEventLogHost {
base::WeakPtr<WebRTCEventLogHost> GetWeakPtr();
private:
+ // Tracks which peer connections have log files associated.
+ struct PeerConnectionKey {
+ bool operator==(const PeerConnectionKey& other) const {
+ return render_process_id == other.render_process_id &&
+ peer_connection_local_id == other.peer_connection_local_id;
+ }
+ int render_process_id;
+ int peer_connection_local_id;
+ };
+ static std::vector<PeerConnectionKey>& ActivePeerConnectionsWithLogFiles();
+
// Actually start the eventlog for a single PeerConnection using the path
// stored in base_file_path_.
- bool StartEventLogForPeerConnection(int peer_connection_local_id);
+ void StartEventLogForPeerConnection(int peer_connection_local_id);
// Send the platform file to the render process using an IPC message.
void SendEventLogFileToRenderer(int peer_connection_local_id,
IPC::PlatformFileForTransit file_for_transit);
+ // Management of |active_peer_connections_with_log_files_|, which tracks
+ // which PCs have associated log files.
+ // RtcEventLogRemoved() returns whether actual removal took place.
+ void RtcEventLogAdded(int peer_connection_local_id);
+ bool RtcEventLogRemoved(int peer_connection_local_id);
+
// The render process ID that this object is associated with.
const int render_process_id_;
@@ -61,9 +78,6 @@ class CONTENT_EXPORT WebRTCEventLogHost {
// The local identifiers of all the currently active PeerConnections.
std::vector<int> active_peer_connection_local_ids_;
- // Number of active log files that have been opened.
- static int number_active_log_files_;
-
// Track if the RTC event log is currently active.
bool rtc_event_logging_enabled_;
diff --git a/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
index c8510b51ff6..d262d20da88 100644
--- a/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -7,11 +7,7 @@
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/json/json_reader.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/strings/stringprintf.h"
-#include "base/test/trace_event_analyzer.h"
#include "base/threading/thread_restrictions.h"
-#include "base/trace_event/trace_event_impl.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/browser/browser_main_loop.h"
@@ -27,20 +23,14 @@
#include "media/audio/audio_manager.h"
#include "media/audio/fake_audio_input_stream.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "testing/perf/perf_test.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
#endif
-using trace_analyzer::TraceAnalyzer;
-using trace_analyzer::Query;
-using trace_analyzer::TraceEventVector;
-
namespace {
static const char kGetUserMediaAndStop[] = "getUserMediaAndStop";
-static const char kGetUserMediaAndGetStreamUp[] = "getUserMediaAndGetStreamUp";
static const char kGetUserMediaAndAnalyseAndStop[] =
"getUserMediaAndAnalyseAndStop";
static const char kGetUserMediaAndExpectFailure[] =
@@ -106,107 +96,12 @@ namespace content {
class WebRtcGetUserMediaBrowserTest : public WebRtcContentBrowserTestBase {
public:
- WebRtcGetUserMediaBrowserTest() : trace_log_(NULL) {
+ WebRtcGetUserMediaBrowserTest() {
// Automatically grant device permission.
AppendUseFakeUIForMediaStreamFlag();
}
~WebRtcGetUserMediaBrowserTest() override {}
- void StartTracing() {
- CHECK(trace_log_ == NULL) << "Can only can start tracing once";
- trace_log_ = base::trace_event::TraceLog::GetInstance();
- base::trace_event::TraceConfig trace_config(
- "video", base::trace_event::RECORD_UNTIL_FULL);
- trace_log_->SetEnabled(trace_config,
- base::trace_event::TraceLog::RECORDING_MODE);
- // Check that we are indeed recording.
- EXPECT_EQ(trace_log_->GetNumTracesRecorded(), 1);
- }
-
- void StopTracing() {
- CHECK(message_loop_runner_.get() == NULL)
- << "Calling StopTracing more than once";
-
- {
- base::ThreadRestrictions::ScopedAllowIO allow_thread_join_caused_by_test;
- trace_log_->SetDisabled();
- }
-
- message_loop_runner_ = new MessageLoopRunner;
- trace_log_->Flush(base::Bind(
- &WebRtcGetUserMediaBrowserTest::OnTraceDataCollected,
- base::Unretained(this)));
- message_loop_runner_->Run();
- }
-
- void OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& events_str_ptr,
- bool has_more_events) {
- CHECK(!has_more_events);
- recorded_trace_data_ = events_str_ptr;
- message_loop_runner_->Quit();
- }
-
- TraceAnalyzer* CreateTraceAnalyzer() {
- return TraceAnalyzer::Create("[" + recorded_trace_data_->data() + "]");
- }
-
- void RunGetUserMediaAndCollectMeasures(const int time_to_sample_secs,
- const std::string& measure_filter,
- const std::string& graph_name) {
- ASSERT_TRUE(embedded_test_server()->Start());
-
- GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
- NavigateToURL(shell(), url);
-
- // Put getUserMedia to work and let it run for a couple of seconds.
- DCHECK(time_to_sample_secs);
- ExecuteJavascriptAndWaitForOk(
- base::StringPrintf("%s({video: true}, 'myStreamName');",
- kGetUserMediaAndGetStreamUp));
-
- // Now the stream is up and running, start collecting traces.
- StartTracing();
-
- ExecuteJavascriptAndWaitForOk(
- base::StringPrintf("waitAndStopVideoTrack(window['myStreamName'], %d);",
- time_to_sample_secs));
-
- // Wait until the page title changes to "OK". Do not sleep() here since that
- // would stop both this code and the browser underneath.
- StopTracing();
-
- std::unique_ptr<TraceAnalyzer> analyzer(CreateTraceAnalyzer());
- analyzer->AssociateBeginEndEvents();
- trace_analyzer::TraceEventVector events;
- DCHECK(measure_filter.size());
- analyzer->FindEvents(
- Query::EventNameIs(measure_filter),
- &events);
- ASSERT_GT(events.size(), 0u)
- << "Could not collect any samples during test, this is bad";
-
- std::string duration_us;
- std::string interarrival_us;
- for (size_t i = 0; i != events.size(); ++i) {
- duration_us.append(
- base::StringPrintf("%d,", static_cast<int>(events[i]->duration)));
- }
-
- for (size_t i = 1; i < events.size(); ++i) {
- // The event |timestamp| comes in ns, divide to get us like |duration|.
- interarrival_us.append(base::StringPrintf("%d,",
- static_cast<int>((events[i]->timestamp - events[i - 1]->timestamp) /
- base::Time::kNanosecondsPerMicrosecond)));
- }
-
- perf_test::PrintResultList(
- graph_name, "", "sample_duration", duration_us, "us", true);
-
- perf_test::PrintResultList(
- graph_name, "", "interarrival_time", interarrival_us, "us", true);
- }
-
// Runs the JavaScript twoGetUserMedia with |constraints1| and |constraint2|.
void RunTwoGetTwoGetUserMediaWithDifferentContraints(
const std::string& constraints1,
@@ -238,7 +133,7 @@ class WebRtcGetUserMediaBrowserTest : public WebRtcContentBrowserTestBase {
devices_as_json, base::JSON_ALLOW_TRAILING_COMMAS, &error_code,
&error_message);
- ASSERT_TRUE(value.get() != NULL) << error_message;
+ ASSERT_TRUE(value.get() != nullptr) << error_message;
EXPECT_EQ(value->type(), base::Value::Type::LIST);
base::ListValue* values;
@@ -263,11 +158,6 @@ class WebRtcGetUserMediaBrowserTest : public WebRtcContentBrowserTestBase {
ASSERT_FALSE(audio_ids->empty());
ASSERT_FALSE(video_ids->empty());
}
-
- private:
- base::trace_event::TraceLog* trace_log_;
- scoped_refptr<base::RefCountedString> recorded_trace_data_;
- scoped_refptr<MessageLoopRunner> message_loop_runner_;
};
// These tests will all make a getUserMedia call with different constraints and
@@ -428,21 +318,21 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
// Test with invalid mandatory audio sourceID.
NavigateToURL(shell(), url);
- EXPECT_EQ("ConstraintNotSatisfiedError",
+ EXPECT_EQ("OverconstrainedError",
ExecuteJavascriptAndReturnResult(
GenerateGetUserMediaWithMandatorySourceID(
kGetUserMediaAndExpectFailure, "something invalid",
video_ids[0])));
// Test with invalid mandatory video sourceID.
- EXPECT_EQ("ConstraintNotSatisfiedError",
+ EXPECT_EQ("OverconstrainedError",
ExecuteJavascriptAndReturnResult(
GenerateGetUserMediaWithMandatorySourceID(
kGetUserMediaAndExpectFailure, audio_ids[0],
"something invalid")));
// Test with empty mandatory audio sourceID.
- EXPECT_EQ("ConstraintNotSatisfiedError",
+ EXPECT_EQ("OverconstrainedError",
ExecuteJavascriptAndReturnResult(
GenerateGetUserMediaWithMandatorySourceID(
kGetUserMediaAndExpectFailure, "", video_ids[0])));
@@ -545,16 +435,10 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
expected_result);
}
-// Test fails under MSan, http://crbug.com/445745
-#if defined(MEMORY_SANITIZER)
-#define MAYBE_TwoGetUserMediaAndVerifyFrameRate \
- DISABLED_TwoGetUserMediaAndVerifyFrameRate
-#else
-#define MAYBE_TwoGetUserMediaAndVerifyFrameRate \
- TwoGetUserMediaAndVerifyFrameRate
-#endif
+// Test fails under MSan, http://crbug.com/445745.
+// Flaky everywhere: https://crbug.com/789121.
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
- MAYBE_TwoGetUserMediaAndVerifyFrameRate) {
+ DISABLED_TwoGetUserMediaAndVerifyFrameRate) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
@@ -588,8 +472,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
large_value);
NavigateToURL(shell(), url);
- EXPECT_EQ("ConstraintNotSatisfiedError",
- ExecuteJavascriptAndReturnResult(call));
+ EXPECT_EQ("OverconstrainedError", ExecuteJavascriptAndReturnResult(call));
}
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
@@ -605,8 +488,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
const std::string call = base::StringPrintf(
"%s({video: false, audio: true});", kGetUserMediaAndExpectFailure);
- EXPECT_EQ("TrackStartError",
- ExecuteJavascriptAndReturnResult(call));
+ EXPECT_EQ("NotReadableError", ExecuteJavascriptAndReturnResult(call));
}
// This test makes two getUserMedia requests, one with impossible constraints
@@ -632,7 +514,7 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
GenerateGetUserMediaCall(kGetUserMediaAndAnalyseAndStop,
640, 640, 480, 480, 10, 30);
- ASSERT_EQ("ConstraintNotSatisfiedError",
+ ASSERT_EQ("OverconstrainedError",
ExecuteJavascriptAndReturnResult(gum_with_impossible_constraints));
ASSERT_EQ("w=640:h=480",
@@ -647,19 +529,6 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
TraceVideoCaptureControllerPerformanceDuringGetUserMedia
#endif
-// This test will make a simple getUserMedia page, verify that video is playing
-// in a simple local <video>, and for a couple of seconds, collect some
-// performance traces from VideoCaptureController colorspace conversion and
-// potential resizing.
-IN_PROC_BROWSER_TEST_F(
- WebRtcGetUserMediaBrowserTest,
- MAYBE_TraceVideoCaptureControllerPerformanceDuringGetUserMedia) {
- RunGetUserMediaAndCollectMeasures(
- 10,
- "VideoCaptureDeviceClient::OnIncomingCapturedData",
- "VideoCaptureDeviceClient");
-}
-
// This test calls getUserMedia and checks for aspect ratio behavior.
IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
TestGetUserMediaAspectRatio4To3) {
@@ -935,4 +804,12 @@ IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
ExecuteJavascriptAndWaitForOk("applyConstraintsNonDevice()");
}
+IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
+ ConcurrentGetUserMediaStop) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+ ExecuteJavascriptAndWaitForOk("concurrentGetUserMediaStop()");
+}
+
} // namespace content
diff --git a/chromium/content/browser/webrtc/webrtc_image_capture_browsertest.cc b/chromium/content/browser/webrtc/webrtc_image_capture_browsertest.cc
index 22b925ae4a5..1ca3828d8c6 100644
--- a/chromium/content/browser/webrtc/webrtc_image_capture_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_image_capture_browsertest.cc
@@ -3,6 +3,7 @@
// 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/webrtc/webrtc_webcam_browsertest.h"
#include "content/public/common/content_switches.h"
@@ -31,6 +32,16 @@ namespace content {
#define MAYBE_GetTrackCapabilities DISABLED_GetTrackCapabilities
#define MAYBE_GetTrackSettings DISABLED_GetTrackSettings
#define MAYBE_ManipulateZoom DISABLED_ManipulateZoom
+#elif defined(OS_ANDROID)
+// TODO(chfremer): Re-enable test on Android as soon as the cause for
+// https://crbug.com/793859 is understood and fixed.
+#define MAYBE_GetPhotoCapabilities GetPhotoCapabilities
+#define MAYBE_GetPhotoSettings GetPhotoSettings
+#define MAYBE_TakePhoto TakePhoto
+#define MAYBE_GrabFrame GrabFrame
+#define MAYBE_GetTrackCapabilities GetTrackCapabilities
+#define MAYBE_GetTrackSettings GetTrackSettings
+#define MAYBE_ManipulateZoom DISABLED_ManipulateZoom
#else
#define MAYBE_GetPhotoCapabilities GetPhotoCapabilities
#define MAYBE_GetPhotoSettings GetPhotoSettings
@@ -132,7 +143,13 @@ class WebRtcImageCaptureSucceedsBrowserTest
public testing::WithParamInterface<
std::tuple<TargetCamera, TargetVideoCaptureStack>> {
public:
- WebRtcImageCaptureSucceedsBrowserTest() = default;
+ WebRtcImageCaptureSucceedsBrowserTest() {
+ if (std::get<1>(GetParam()).use_video_capture_service) {
+ scoped_feature_list_.InitAndEnableFeature(
+ video_capture::kMojoVideoCapture);
+ }
+ }
+
~WebRtcImageCaptureSucceedsBrowserTest() override = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -144,10 +161,6 @@ class WebRtcImageCaptureSucceedsBrowserTest
ASSERT_TRUE(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseFakeDeviceForMediaStream));
}
- if (std::get<1>(GetParam()).use_video_capture_service) {
- base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
- switches::kEnableFeatures, video_capture::kMojoVideoCapture.name);
- }
}
bool RunImageCaptureTestCase(const std::string& command) override {
@@ -161,6 +174,11 @@ class WebRtcImageCaptureSucceedsBrowserTest
}
return WebRtcImageCaptureBrowserTestBase::RunImageCaptureTestCase(command);
}
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcImageCaptureSucceedsBrowserTest);
};
IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureSucceedsBrowserTest,
@@ -219,17 +237,27 @@ class WebRtcImageCaptureCustomConfigFakeDeviceBrowserTest
: public WebRtcImageCaptureBrowserTestBase,
public testing::WithParamInterface<TargetVideoCaptureStack> {
public:
+ WebRtcImageCaptureCustomConfigFakeDeviceBrowserTest() {
+ if (GetParam().use_video_capture_service) {
+ scoped_feature_list_.InitAndEnableFeature(
+ video_capture::kMojoVideoCapture);
+ }
+ }
+
+ ~WebRtcImageCaptureCustomConfigFakeDeviceBrowserTest() override {}
+
void SetUpCommandLine(base::CommandLine* command_line) override {
WebRtcImageCaptureBrowserTestBase::SetUpCommandLine(command_line);
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kUseFakeDeviceForMediaStream,
std::string("config=") + FakeDeviceConfigTraits::config());
- if (GetParam().use_video_capture_service) {
- base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
- switches::kEnableFeatures, video_capture::kMojoVideoCapture.name);
- }
}
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcImageCaptureCustomConfigFakeDeviceBrowserTest);
};
struct GetPhotoStateFailsConfigTraits {
diff --git a/chromium/content/browser/webrtc/webrtc_internals.cc b/chromium/content/browser/webrtc/webrtc_internals.cc
index 25acf073060..7ffa0ad65e8 100644
--- a/chromium/content/browser/webrtc/webrtc_internals.cc
+++ b/chromium/content/browser/webrtc/webrtc_internals.cc
@@ -45,9 +45,9 @@ base::LazyInstance<WebRTCInternals>::Leaky g_webrtc_internals =
// Makes sure that |dict| has a ListValue under path "log".
base::ListValue* EnsureLogList(base::DictionaryValue* dict) {
- base::ListValue* log = NULL;
+ base::ListValue* log = nullptr;
if (!dict->GetList("log", &log))
- log = dict->SetList("log", base::MakeUnique<base::ListValue>());
+ log = dict->SetList("log", std::make_unique<base::ListValue>());
return log;
}
@@ -87,9 +87,9 @@ WebRTCInternals::WebRTCInternals() : WebRTCInternals(500, true) {}
WebRTCInternals::WebRTCInternals(int aggregate_updates_ms,
bool should_block_power_saving)
- : audio_debug_recordings_(false),
+ : selection_type_(SelectionType::kAudioDebugRecordings),
+ audio_debug_recordings_(false),
event_log_recordings_(false),
- selecting_event_log_(false),
num_open_connections_(0),
should_block_power_saving_(should_block_power_saving),
aggregate_updates_ms_(aggregate_updates_ms),
@@ -165,7 +165,7 @@ void WebRTCInternals::OnRemovePeerConnection(ProcessId pid, int lid) {
base::DictionaryValue* dict = FindRecord(pid, lid, &index);
if (dict) {
MaybeClosePeerConnection(dict);
- peer_connection_data_.Remove(index, NULL);
+ peer_connection_data_.Remove(index, nullptr);
}
if (observers_.might_have_observers()) {
@@ -191,15 +191,15 @@ void WebRTCInternals::OnUpdatePeerConnection(
if (!observers_.might_have_observers())
return;
- auto log_entry = base::MakeUnique<base::DictionaryValue>();
+ auto log_entry = std::make_unique<base::DictionaryValue>();
double epoch_time = base::Time::Now().ToJsTime();
- string time = base::DoubleToString(epoch_time);
+ string time = base::NumberToString(epoch_time);
log_entry->SetString("time", time);
log_entry->SetString("type", type);
log_entry->SetString("value", value);
- auto update = base::MakeUnique<base::DictionaryValue>();
+ auto update = std::make_unique<base::DictionaryValue>();
update->SetInteger("pid", static_cast<int>(pid));
update->SetInteger("lid", lid);
update->MergeDictionary(log_entry.get());
@@ -215,7 +215,7 @@ void WebRTCInternals::OnAddStats(base::ProcessId pid, int lid,
if (!observers_.might_have_observers())
return;
- auto dict = base::MakeUnique<base::DictionaryValue>();
+ auto dict = std::make_unique<base::DictionaryValue>();
dict->SetInteger("pid", static_cast<int>(pid));
dict->SetInteger("lid", lid);
@@ -233,7 +233,7 @@ void WebRTCInternals::OnGetUserMedia(int rid,
const std::string& video_constraints) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- auto dict = base::MakeUnique<base::DictionaryValue>();
+ auto dict = std::make_unique<base::DictionaryValue>();
dict->SetInteger("rid", rid);
dict->SetInteger("pid", static_cast<int>(pid));
dict->SetString("origin", origin);
@@ -292,13 +292,14 @@ void WebRTCInternals::EnableAudioDebugRecordings(
#if defined(OS_ANDROID)
EnableAudioDebugRecordingsOnAllRenderProcessHosts();
#else
- selecting_event_log_ = false;
+ selection_type_ = SelectionType::kAudioDebugRecordings;
DCHECK(!select_file_dialog_);
select_file_dialog_ = ui::SelectFileDialog::Create(this, nullptr);
select_file_dialog_->SelectFile(
ui::SelectFileDialog::SELECT_SAVEAS_FILE, base::string16(),
- audio_debug_recordings_file_path_, NULL, 0, base::FilePath::StringType(),
- web_contents->GetTopLevelNativeWindow(), NULL);
+ audio_debug_recordings_file_path_, nullptr, 0,
+ base::FilePath::StringType(), web_contents->GetTopLevelNativeWindow(),
+ nullptr);
#endif
#endif
}
@@ -327,9 +328,8 @@ void WebRTCInternals::DisableAudioDebugRecordings() {
// this object, so it's safe to post unretained to the audio thread.
media::AudioManager* audio_manager = media::AudioManager::Get();
audio_manager->GetTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&media::AudioManager::DisableOutputDebugRecording,
- base::Unretained(audio_manager)));
+ FROM_HERE, base::BindOnce(&media::AudioManager::DisableDebugRecording,
+ base::Unretained(audio_manager)));
#endif
}
@@ -352,7 +352,7 @@ void WebRTCInternals::EnableEventLogRecordings(
#else
DCHECK(web_contents);
DCHECK(!select_file_dialog_);
- selecting_event_log_ = true;
+ selection_type_ = SelectionType::kRtcEventLogs;
select_file_dialog_ = ui::SelectFileDialog::Create(this, nullptr);
select_file_dialog_->SelectFile(
ui::SelectFileDialog::SELECT_SAVEAS_FILE, base::string16(),
@@ -415,12 +415,17 @@ void WebRTCInternals::FileSelected(const base::FilePath& path,
void* /*unused_params */) {
#if BUILDFLAG(ENABLE_WEBRTC)
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (selecting_event_log_) {
- event_log_recordings_file_path_ = path;
- EnableEventLogRecordingsOnAllRenderProcessHosts();
- } else {
- audio_debug_recordings_file_path_ = path;
- EnableAudioDebugRecordingsOnAllRenderProcessHosts();
+ switch (selection_type_) {
+ case SelectionType::kRtcEventLogs:
+ event_log_recordings_file_path_ = path;
+ EnableEventLogRecordingsOnAllRenderProcessHosts();
+ break;
+ case SelectionType::kAudioDebugRecordings:
+ audio_debug_recordings_file_path_ = path;
+ EnableAudioDebugRecordingsOnAllRenderProcessHosts();
+ break;
+ default:
+ NOTREACHED();
}
#endif
}
@@ -428,10 +433,15 @@ void WebRTCInternals::FileSelected(const base::FilePath& path,
void WebRTCInternals::FileSelectionCanceled(void* params) {
#if BUILDFLAG(ENABLE_WEBRTC)
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (selecting_event_log_) {
- SendUpdate("eventLogRecordingsFileSelectionCancelled", nullptr);
- } else {
- SendUpdate("audioDebugRecordingsFileSelectionCancelled", nullptr);
+ switch (selection_type_) {
+ case SelectionType::kRtcEventLogs:
+ SendUpdate("eventLogRecordingsFileSelectionCancelled", nullptr);
+ break;
+ case SelectionType::kAudioDebugRecordings:
+ SendUpdate("audioDebugRecordingsFileSelectionCancelled", nullptr);
+ break;
+ default:
+ NOTREACHED();
}
#endif
}
@@ -442,7 +452,7 @@ void WebRTCInternals::OnRendererExit(int render_process_id) {
// Iterates from the end of the list to remove the PeerConnections created
// by the exitting renderer.
for (int i = peer_connection_data_.GetSize() - 1; i >= 0; --i) {
- base::DictionaryValue* record = NULL;
+ base::DictionaryValue* record = nullptr;
peer_connection_data_.GetDictionary(i, &record);
int this_rid = 0;
@@ -461,7 +471,7 @@ void WebRTCInternals::OnRendererExit(int render_process_id) {
SendUpdate("removePeerConnection", std::move(update));
}
MaybeClosePeerConnection(record);
- peer_connection_data_.Remove(i, NULL);
+ peer_connection_data_.Remove(i, nullptr);
}
}
UpdateWakeLock();
@@ -470,14 +480,14 @@ void WebRTCInternals::OnRendererExit(int render_process_id) {
// Iterates from the end of the list to remove the getUserMedia requests
// created by the exiting renderer.
for (int i = get_user_media_requests_.GetSize() - 1; i >= 0; --i) {
- base::DictionaryValue* record = NULL;
+ base::DictionaryValue* record = nullptr;
get_user_media_requests_.GetDictionary(i, &record);
int this_rid = 0;
record->GetInteger("rid", &this_rid);
if (this_rid == render_process_id) {
- get_user_media_requests_.Remove(i, NULL);
+ get_user_media_requests_.Remove(i, nullptr);
found_any = true;
}
}
@@ -508,10 +518,9 @@ void WebRTCInternals::EnableAudioDebugRecordingsOnAllRenderProcessHosts() {
// this object, so it's safe to post unretained to the audio thread.
media::AudioManager* audio_manager = media::AudioManager::Get();
audio_manager->GetTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&media::AudioManager::EnableOutputDebugRecording,
- base::Unretained(audio_manager),
- audio_debug_recordings_file_path_));
+ FROM_HERE, base::BindOnce(&media::AudioManager::EnableDebugRecording,
+ base::Unretained(audio_manager),
+ audio_debug_recordings_file_path_));
}
void WebRTCInternals::EnableEventLogRecordingsOnAllRenderProcessHosts() {
@@ -569,8 +578,8 @@ device::mojom::WakeLock* WebRTCInternals::GetWakeLock() {
connector->BindInterface(device::mojom::kServiceName,
mojo::MakeRequest(&wake_lock_provider));
wake_lock_provider->GetWakeLockWithoutContext(
- device::mojom::WakeLockType::PreventAppSuspension,
- device::mojom::WakeLockReason::ReasonOther,
+ device::mojom::WakeLockType::kPreventAppSuspension,
+ device::mojom::WakeLockReason::kOther,
"WebRTC has active PeerConnections", std::move(request));
}
}
diff --git a/chromium/content/browser/webrtc/webrtc_internals.h b/chromium/content/browser/webrtc/webrtc_internals.h
index 708d5da9dc0..40c23c67051 100644
--- a/chromium/content/browser/webrtc/webrtc_internals.h
+++ b/chromium/content/browser/webrtc/webrtc_internals.h
@@ -208,6 +208,10 @@ class CONTENT_EXPORT WebRTCInternals : public RenderProcessHostObserver,
// For managing select file dialog.
scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
+ enum class SelectionType {
+ kRtcEventLogs,
+ kAudioDebugRecordings
+ } selection_type_;
// Diagnostic audio recording state.
bool audio_debug_recordings_;
@@ -215,7 +219,6 @@ class CONTENT_EXPORT WebRTCInternals : public RenderProcessHostObserver,
// Diagnostic event log recording state.
bool event_log_recordings_;
- bool selecting_event_log_;
base::FilePath event_log_recordings_file_path_;
// While |num_open_connections_| is greater than zero, request a wake lock
diff --git a/chromium/content/browser/webrtc/webrtc_internals_browsertest.cc b/chromium/content/browser/webrtc/webrtc_internals_browsertest.cc
index b3f0c1b4c2c..213d360a792 100644
--- a/chromium/content/browser/webrtc/webrtc_internals_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_internals_browsertest.cc
@@ -246,7 +246,7 @@ class MAYBE_WebRtcInternalsBrowserTest: public ContentBrowserTest {
EXPECT_EQ(requests.size(), list_request->GetSize());
for (size_t i = 0; i < requests.size(); ++i) {
- base::DictionaryValue* dict = NULL;
+ base::DictionaryValue* dict = nullptr;
ASSERT_TRUE(list_request->GetDictionary(i, &dict));
int pid, rid;
std::string origin, audio, video;
@@ -438,7 +438,7 @@ class MAYBE_WebRtcInternalsBrowserTest: public ContentBrowserTest {
int peer_connection_number,
int update_number,
int stats_number) {
- EXPECT_NE((base::Value*)NULL, dump);
+ EXPECT_NE((base::Value*)nullptr, dump);
EXPECT_EQ(base::Value::Type::DICTIONARY, dump->type());
base::DictionaryValue* dict_dump =
@@ -447,7 +447,7 @@ class MAYBE_WebRtcInternalsBrowserTest: public ContentBrowserTest {
base::DictionaryValue::Iterator it(*dict_dump);
for (; !it.IsAtEnd(); it.Advance()) {
- base::Value* value = NULL;
+ base::Value* value = nullptr;
dict_dump->Get(it.key(), &value);
EXPECT_EQ(base::Value::Type::DICTIONARY, value->type());
base::DictionaryValue* pc_dump =
@@ -476,17 +476,17 @@ class MAYBE_WebRtcInternalsBrowserTest: public ContentBrowserTest {
const string& report_type,
const string& report_id,
const StatsUnit& stats) {
- EXPECT_NE((base::Value*)NULL, dump);
+ EXPECT_NE((base::Value*)nullptr, dump);
EXPECT_EQ(base::Value::Type::DICTIONARY, dump->type());
base::DictionaryValue* dict_dump =
static_cast<base::DictionaryValue*>(dump);
- base::Value* value = NULL;
+ base::Value* value = nullptr;
dict_dump->Get(pc.getIdString(), &value);
base::DictionaryValue* pc_dump = static_cast<base::DictionaryValue*>(value);
// Verifies there is one data series per stats name.
- value = NULL;
+ value = nullptr;
pc_dump->Get("stats", &value);
EXPECT_EQ(base::Value::Type::DICTIONARY, value->type());
diff --git a/chromium/content/browser/webrtc/webrtc_internals_ui.cc b/chromium/content/browser/webrtc/webrtc_internals_ui.cc
index 027ab873e6a..6e26375c8ab 100644
--- a/chromium/content/browser/webrtc/webrtc_internals_ui.cc
+++ b/chromium/content/browser/webrtc/webrtc_internals_ui.cc
@@ -36,7 +36,7 @@ WebUIDataSource* CreateWebRTCInternalsHTMLSource() {
WebRTCInternalsUI::WebRTCInternalsUI(WebUI* web_ui)
: WebUIController(web_ui) {
- web_ui->AddMessageHandler(base::MakeUnique<WebRTCInternalsMessageHandler>());
+ web_ui->AddMessageHandler(std::make_unique<WebRTCInternalsMessageHandler>());
BrowserContext* browser_context =
web_ui->GetWebContents()->GetBrowserContext();
diff --git a/chromium/content/browser/webrtc/webrtc_internals_unittest.cc b/chromium/content/browser/webrtc/webrtc_internals_unittest.cc
index ef2c5028bda..d6f26c1aec8 100644
--- a/chromium/content/browser/webrtc/webrtc_internals_unittest.cc
+++ b/chromium/content/browser/webrtc/webrtc_internals_unittest.cc
@@ -110,7 +110,7 @@ class WebRtcInternalsTest : public testing::Test {
void VerifyList(const base::DictionaryValue* dict,
const std::string& key,
const base::ListValue& expected) {
- const base::ListValue* actual = NULL;
+ const base::ListValue* actual = nullptr;
EXPECT_TRUE(dict->GetList(key, &actual));
EXPECT_TRUE(expected.Equals(actual));
}
@@ -121,7 +121,7 @@ class WebRtcInternalsTest : public testing::Test {
const std::string& origin,
const std::string& audio,
const std::string& video) {
- base::DictionaryValue* dict = NULL;
+ base::DictionaryValue* dict = nullptr;
EXPECT_TRUE(actual_data->GetAsDictionary(&dict));
VerifyInt(dict, "rid", rid);
@@ -227,7 +227,7 @@ TEST_F(WebRtcInternalsTest, SendAddPeerConnectionUpdate) {
ASSERT_EQ("addPeerConnection", observer.command());
- base::DictionaryValue* dict = NULL;
+ base::DictionaryValue* dict = nullptr;
EXPECT_TRUE(observer.value()->GetAsDictionary(&dict));
VerifyInt(dict, "pid", 1);
@@ -253,7 +253,7 @@ TEST_F(WebRtcInternalsTest, SendRemovePeerConnectionUpdate) {
ASSERT_EQ("removePeerConnection", observer.command());
- base::DictionaryValue* dict = NULL;
+ base::DictionaryValue* dict = nullptr;
EXPECT_TRUE(observer.value()->GetAsDictionary(&dict));
VerifyInt(dict, "pid", 1);
@@ -278,7 +278,7 @@ TEST_F(WebRtcInternalsTest, SendUpdatePeerConnectionUpdate) {
ASSERT_EQ("updatePeerConnection", observer.command());
- base::DictionaryValue* dict = NULL;
+ base::DictionaryValue* dict = nullptr;
EXPECT_TRUE(observer.value()->GetAsDictionary(&dict));
VerifyInt(dict, "pid", 1);
@@ -358,11 +358,11 @@ TEST_F(WebRtcInternalsTest, SendAllUpdatesWithPeerConnectionUpdate) {
EXPECT_EQ("updateAllPeerConnections", observer.command());
ASSERT_TRUE(observer.value());
- base::ListValue* list = NULL;
+ base::ListValue* list = nullptr;
EXPECT_TRUE(observer.value()->GetAsList(&list));
EXPECT_EQ(1U, list->GetSize());
- base::DictionaryValue* dict = NULL;
+ base::DictionaryValue* dict = nullptr;
EXPECT_TRUE((*list->begin()).GetAsDictionary(&dict));
VerifyInt(dict, "rid", rid);
@@ -372,7 +372,7 @@ TEST_F(WebRtcInternalsTest, SendAllUpdatesWithPeerConnectionUpdate) {
VerifyString(dict, "rtcConfiguration", kRtcConfiguration);
VerifyString(dict, "constraints", kContraints);
- base::ListValue* log = NULL;
+ base::ListValue* log = nullptr;
ASSERT_TRUE(dict->GetList("log", &log));
EXPECT_EQ(1U, log->GetSize());
@@ -403,7 +403,7 @@ TEST_F(WebRtcInternalsTest, OnAddStats) {
EXPECT_EQ("addStats", observer.command());
ASSERT_TRUE(observer.value());
- base::DictionaryValue* dict = NULL;
+ base::DictionaryValue* dict = nullptr;
EXPECT_TRUE(observer.value()->GetAsDictionary(&dict));
VerifyInt(dict, "pid", pid);
diff --git a/chromium/content/browser/webrtc/webrtc_pause_play_browsertest.cc b/chromium/content/browser/webrtc/webrtc_pause_play_browsertest.cc
new file mode 100644
index 00000000000..a743dd9c0d6
--- /dev/null
+++ b/chromium/content/browser/webrtc/webrtc_pause_play_browsertest.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/threading/platform_thread.h"
+#include "build/build_config.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/webrtc/webrtc_content_browsertest_base.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+
+namespace content {
+
+namespace {
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
+ defined(SYZYASAN) || defined(MEMORY_SANITIZER)
+static const int kTestDurationSecs = 2;
+static const int kNumPeerConnections = 3;
+#else
+static const int kTestDurationSecs = 10;
+static const int kNumPeerConnections = 10;
+#endif
+} // namespace
+
+#if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
+// Renderer crashes under Android ASAN: https://crbug.com/408496.
+#define MAYBE_WebRtcPausePlayBrowserTest DISABLED_WebRtcPausePlayBrowserTest
+#else
+#define MAYBE_WebRtcPausePlayBrowserTest WebRtcPausePlayBrowserTest
+#endif
+
+class MAYBE_WebRtcPausePlayBrowserTest : public WebRtcContentBrowserTestBase {
+ public:
+ MAYBE_WebRtcPausePlayBrowserTest() {}
+ ~MAYBE_WebRtcPausePlayBrowserTest() override {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ WebRtcContentBrowserTestBase::SetUpCommandLine(command_line);
+ // Automatically grant device permission.
+ AppendUseFakeUIForMediaStreamFlag();
+ }
+
+ protected:
+ void MakeTypicalPeerConnectionCall(const std::string& javascript) {
+ MakeTypicalCall(javascript, "/media/peerconnection-pause-play.html");
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcPausePlayBrowserTest,
+ SurvivesPeerConnectionPausePlaying) {
+ // Args: runtimeSeconds, numPeerConnections, pausePlayIterationDelayMillis,
+ // elementType.
+ MakeTypicalPeerConnectionCall(
+ base::StringPrintf("runPausePlayTest(%d, %d, 100, 'video');",
+ kTestDurationSecs, kNumPeerConnections));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/webrtc/webrtc_video_capture_browsertest.cc b/chromium/content/browser/webrtc/webrtc_video_capture_browsertest.cc
index 884551c7dfb..6a9f123ae16 100644
--- a/chromium/content/browser/webrtc/webrtc_video_capture_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_video_capture_browsertest.cc
@@ -3,6 +3,7 @@
// 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/webrtc/webrtc_webcam_browsertest.h"
#include "content/public/browser/browser_child_process_host.h"
@@ -46,10 +47,14 @@ static const char kVerifyHasReceivedTrackEndedEvent[] =
// JavaScript level.
class WebRtcVideoCaptureBrowserTest : public ContentBrowserTest {
protected:
+ WebRtcVideoCaptureBrowserTest() {
+ scoped_feature_list_.InitAndEnableFeature(video_capture::kMojoVideoCapture);
+ }
+
+ ~WebRtcVideoCaptureBrowserTest() override {}
+
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
- command_line->AppendSwitchASCII(switches::kEnableFeatures,
- video_capture::kMojoVideoCapture.name);
command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kEnableBlinkFeatures, "GetUserMedia");
@@ -60,6 +65,11 @@ class WebRtcVideoCaptureBrowserTest : public ContentBrowserTest {
EnablePixelOutput();
ContentBrowserTest::SetUp();
}
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcVideoCaptureBrowserTest);
};
IN_PROC_BROWSER_TEST_F(WebRtcVideoCaptureBrowserTest,
diff --git a/chromium/content/browser/webui/i18n_source_stream.cc b/chromium/content/browser/webui/i18n_source_stream.cc
deleted file mode 100644
index c2120a8ed9a..00000000000
--- a/chromium/content/browser/webui/i18n_source_stream.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/webui/i18n_source_stream.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "base/logging.h"
-#include "base/strings/string_piece.h"
-#include "net/base/io_buffer.h"
-
-namespace content {
-
-I18nSourceStream::~I18nSourceStream() {}
-
-std::unique_ptr<I18nSourceStream> I18nSourceStream::Create(
- std::unique_ptr<SourceStream> upstream,
- SourceStream::SourceType type,
- const ui::TemplateReplacements* replacements) {
- DCHECK(replacements);
- std::unique_ptr<I18nSourceStream> source(
- new I18nSourceStream(std::move(upstream), type, replacements));
- return source;
-}
-
-I18nSourceStream::I18nSourceStream(std::unique_ptr<SourceStream> upstream,
- SourceStream::SourceType type,
- const ui::TemplateReplacements* replacements)
- : FilterSourceStream(type, std::move(upstream)),
- replacements_(replacements) {}
-
-std::string I18nSourceStream::GetTypeAsString() const {
- return "i18n";
-}
-
-int I18nSourceStream::FilterData(net::IOBuffer* output_buffer,
- int output_buffer_size,
- net::IOBuffer* input_buffer,
- int input_buffer_size,
- int* consumed_bytes,
- bool upstream_end_reached) {
- // |input_| is often empty (or it may have something from the prior call).
- input_.append(input_buffer->data(), input_buffer_size);
- *consumed_bytes = input_buffer_size;
-
- // The replacement tag starts with '$' and ends with '}'. The white-space
- // characters are an optimization that looks for characters that are invalid
- // within $i18n{} tags.
- size_t pos = input_.find_last_of("$} \t\r\n");
- std::string to_process;
- if (!upstream_end_reached && pos != std::string::npos && input_[pos] == '$') {
- // If there is a trailing '$' then split the |input_| at that point. Process
- // the first part; save the second part for the next call to FilterData().
- to_process.assign(input_, 0, pos);
- input_.erase(0, pos);
- } else {
- // There is no risk of a split key, process the whole input.
- to_process.swap(input_);
- }
-
- output_.append(ui::ReplaceTemplateExpressions(to_process, *replacements_));
- int bytes_out =
- std::min(output_.size(), static_cast<size_t>(output_buffer_size));
- output_.copy(output_buffer->data(), bytes_out);
- output_.erase(0, bytes_out);
- return bytes_out;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/webui/i18n_source_stream.h b/chromium/content/browser/webui/i18n_source_stream.h
deleted file mode 100644
index 64378c85f30..00000000000
--- a/chromium/content/browser/webui/i18n_source_stream.h
+++ /dev/null
@@ -1,61 +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_WEBUI_I18N_SOURCE_STREAM_H_
-#define CONTENT_BROWSER_WEBUI_I18N_SOURCE_STREAM_H_
-
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "net/filter/filter_source_stream.h"
-#include "ui/base/template_expressions.h"
-
-namespace content {
-
-class CONTENT_EXPORT I18nSourceStream : public net::FilterSourceStream {
- public:
- ~I18nSourceStream() override;
-
- // Factory function to create an I18nSourceStream.
- // |replacements| is a dictionary of i18n replacements.
- static std::unique_ptr<I18nSourceStream> Create(
- std::unique_ptr<SourceStream> previous,
- SourceStream::SourceType type,
- const ui::TemplateReplacements* replacements);
-
- private:
- I18nSourceStream(std::unique_ptr<SourceStream> previous,
- SourceStream::SourceType type,
- const ui::TemplateReplacements* replacements);
-
- // SourceStream implementation.
- std::string GetTypeAsString() const override;
- int FilterData(net::IOBuffer* output_buffer,
- int output_buffer_size,
- net::IOBuffer* input_buffer,
- int input_buffer_size,
- int* consumed_bytes,
- bool upstream_end_reached) override;
-
- // Keep split $i18n tags (wait for the whole tag). This is expected to vary
- // in size from 0 to a few KB and should never be larger than the input file
- // (in the worst case).
- std::string input_;
-
- // Keep excess that didn't fit in the output buffer. This is expected to vary
- // in size from 0 to a few KB and should never get much larger than the input
- // file (in the worst case).
- std::string output_;
-
- // A map of i18n replacement keys and translations.
- const ui::TemplateReplacements* replacements_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(I18nSourceStream);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_WEBUI_I18N_SOURCE_STREAM_H_
diff --git a/chromium/content/browser/webui/i18n_source_stream_unittest.cc b/chromium/content/browser/webui/i18n_source_stream_unittest.cc
deleted file mode 100644
index 8d96c9b67ee..00000000000
--- a/chromium/content/browser/webui/i18n_source_stream_unittest.cc
+++ /dev/null
@@ -1,265 +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 <utility>
-
-#include "content/browser/webui/i18n_source_stream.h"
-#include "net/base/io_buffer.h"
-#include "net/base/test_completion_callback.h"
-#include "net/filter/mock_source_stream.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-namespace {
-
-// This constant is rather arbitrary, though the offsets and other sizes must
-// be less than kBufferSize.
-const int kBufferSize = 256;
-
-const int kMinimumSize = 1;
-const int kSmallSize = 5; // Arbitrary small value > 1.
-const int kInOneReadSize = INT_MAX;
-
-struct I18nTest {
- constexpr I18nTest(const char* input, const char* expected_output)
- : input(input), expected_output(expected_output) {}
-
- const char* input;
- const char* expected_output;
-};
-
-constexpr I18nTest kTestEmpty = I18nTest("", "");
-
-constexpr I18nTest kTestNoReplacements =
- I18nTest("This text has no i18n replacements.",
- "This text has no i18n replacements.");
-
-constexpr I18nTest kTestTagAtEndOfLine =
- I18nTest("test with tag at end of line $",
- "test with tag at end of line $");
-
-constexpr I18nTest kTestOneReplacement = I18nTest("$i18n{alpha}", "apple");
-
-constexpr I18nTest kTestOneReplacementPlus =
- I18nTest("Extra text $i18n{alpha}.", "Extra text apple.");
-
-constexpr I18nTest kTestThreeReplacements =
- I18nTest("$i18n{alpha}^$i18n{beta}_$i18n{gamma}", "apple^banana_carrot");
-
-constexpr I18nTest kTestExtraBraces =
- I18nTest("($i18n{alpha})^_^_^_^_$i18n{beta}_beta_$i18n{gamma}}}}}}",
- "(apple)^_^_^_^_banana_beta_carrot}}}}}");
-
-// These tests with generic names are sequences that might catch an error in the
-// future, depending on how the code changes.
-constexpr I18nTest kTest1 =
- I18nTest(" } $($i18n{gamma})^_^_^_^_$i18n{alpha}_$i18n{gamma}$",
- " } $(carrot)^_^_^_^_apple_carrot$");
-
-constexpr I18nTest kTest2 =
- I18nTest("$i18n{alpha} gamma}{ ^_^_^_^_$abc{beta}:$i18n{gamma}z",
- "apple gamma}{ ^_^_^_^_$abc{beta}:carrotz");
-
-struct I18nTestParam {
- constexpr I18nTestParam(
- const I18nTest* test,
- int buf_size,
- int read_size,
- net::MockSourceStream::Mode read_mode = net::MockSourceStream::SYNC)
- : buffer_size(buf_size),
- read_size(read_size),
- mode(read_mode),
- test(test) {}
-
- const int buffer_size;
- const int read_size;
- const net::MockSourceStream::Mode mode;
- const I18nTest* test;
-};
-
-} // namespace
-
-class I18nSourceStreamTest : public ::testing::TestWithParam<I18nTestParam> {
- protected:
- I18nSourceStreamTest() : output_buffer_size_(GetParam().buffer_size) {}
-
- // Helpful function to initialize the test fixture.
- void Init() {
- output_buffer_ = new net::IOBuffer(output_buffer_size_);
- std::unique_ptr<net::MockSourceStream> source(new net::MockSourceStream());
- source_ = source.get();
-
- replacements_["alpha"] = "apple";
- replacements_["beta"] = "banana";
- replacements_["gamma"] = "carrot";
- stream_ = I18nSourceStream::Create(
- std::move(source), net::SourceStream::TYPE_NONE, &replacements_);
- }
-
- // If MockSourceStream::Mode is ASYNC, completes 1 read from |mock_stream| and
- // wait for |callback| to complete. If Mode is not ASYNC, does nothing and
- // returns |previous_result|.
- int CompleteReadIfAsync(int previous_result,
- net::TestCompletionCallback* callback,
- net::MockSourceStream* mock_stream) {
- if (GetParam().mode == net::MockSourceStream::ASYNC) {
- EXPECT_EQ(net::ERR_IO_PENDING, previous_result);
- mock_stream->CompleteNextRead();
- return callback->WaitForResult();
- }
- return previous_result;
- }
-
- net::IOBuffer* output_buffer() { return output_buffer_.get(); }
- char* output_data() { return output_buffer_->data(); }
- size_t output_buffer_size() { return output_buffer_size_; }
-
- net::MockSourceStream* source() { return source_; }
- I18nSourceStream* stream() { return stream_.get(); }
-
- void PushReadResults(const char* input, size_t chunk_size) {
- size_t written = 0;
- size_t source_size = strlen(GetParam().test->input);
- while (written != source_size) {
- size_t write_size = std::min(chunk_size, source_size - written);
- source()->AddReadResult(input + written, write_size, net::OK,
- GetParam().mode);
- written += write_size;
- }
- source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
- }
-
- // Reads from |stream_| until an error occurs or the EOF is reached.
- // When an error occurs, returns the net error code. When an EOF is reached,
- // returns the number of bytes read and appends data read to |output|.
- int ReadStream(std::string* output) {
- int bytes_read = 0;
- while (true) {
- net::TestCompletionCallback callback;
- int rv = stream_->Read(output_buffer(), output_buffer_size(),
- callback.callback());
- if (rv == net::ERR_IO_PENDING)
- rv = CompleteReadIfAsync(rv, &callback, source());
- if (rv == net::OK)
- break;
- if (rv < net::OK)
- return rv;
- EXPECT_GT(rv, net::OK);
- bytes_read += rv;
- output->append(output_data(), rv);
- }
- return bytes_read;
- }
-
- private:
- scoped_refptr<net::IOBuffer> output_buffer_;
- const int output_buffer_size_;
-
- net::MockSourceStream* source_;
- std::unique_ptr<I18nSourceStream> stream_;
-
- ui::TemplateReplacements replacements_;
-};
-
-INSTANTIATE_TEST_CASE_P(
- I18nSourceStreamTests,
- I18nSourceStreamTest,
- ::testing::Values(
- I18nTestParam(&kTest1, kBufferSize, kInOneReadSize),
- I18nTestParam(&kTest1, kBufferSize, kSmallSize),
- I18nTestParam(&kTest1, kMinimumSize, kMinimumSize),
- I18nTestParam(&kTest1, kMinimumSize, kSmallSize),
-
- I18nTestParam(&kTest2, kBufferSize, kInOneReadSize),
- I18nTestParam(&kTest2, kBufferSize, kSmallSize),
- I18nTestParam(&kTest2, kMinimumSize, kMinimumSize),
- I18nTestParam(&kTest2, kMinimumSize, kSmallSize),
-
- I18nTestParam(&kTestEmpty, kBufferSize, kInOneReadSize),
- I18nTestParam(&kTestEmpty, kBufferSize, kSmallSize),
- I18nTestParam(&kTestEmpty, kMinimumSize, kMinimumSize),
- I18nTestParam(&kTestEmpty, kMinimumSize, kSmallSize),
-
- I18nTestParam(&kTestExtraBraces, kBufferSize, kInOneReadSize),
- I18nTestParam(&kTestExtraBraces, kBufferSize, kSmallSize),
- I18nTestParam(&kTestExtraBraces, kMinimumSize, kMinimumSize),
- I18nTestParam(&kTestExtraBraces, kMinimumSize, kSmallSize),
-
- I18nTestParam(&kTestNoReplacements, kBufferSize, kInOneReadSize),
- I18nTestParam(&kTestNoReplacements, kBufferSize, kSmallSize),
- I18nTestParam(&kTestNoReplacements, kMinimumSize, kMinimumSize),
- I18nTestParam(&kTestNoReplacements, kMinimumSize, kSmallSize),
-
- I18nTestParam(&kTestOneReplacement, kBufferSize, kInOneReadSize),
- I18nTestParam(&kTestOneReplacement, kBufferSize, kSmallSize),
- I18nTestParam(&kTestOneReplacement, kMinimumSize, kMinimumSize),
- I18nTestParam(&kTestOneReplacement, kMinimumSize, kSmallSize),
-
- I18nTestParam(&kTestOneReplacementPlus, kBufferSize, kInOneReadSize),
- I18nTestParam(&kTestOneReplacementPlus, kBufferSize, kSmallSize),
- I18nTestParam(&kTestOneReplacementPlus, kMinimumSize, kMinimumSize),
- I18nTestParam(&kTestOneReplacementPlus, kMinimumSize, kSmallSize),
-
- I18nTestParam(&kTestTagAtEndOfLine, kBufferSize, kInOneReadSize),
- I18nTestParam(&kTestTagAtEndOfLine, kBufferSize, kSmallSize),
- I18nTestParam(&kTestTagAtEndOfLine, kMinimumSize, kMinimumSize),
- I18nTestParam(&kTestTagAtEndOfLine, kMinimumSize, kSmallSize),
-
- I18nTestParam(&kTestThreeReplacements, kBufferSize, kInOneReadSize),
- I18nTestParam(&kTestThreeReplacements, kBufferSize, kSmallSize),
- I18nTestParam(&kTestThreeReplacements, kMinimumSize, kMinimumSize),
- I18nTestParam(&kTestThreeReplacements, kMinimumSize, kSmallSize)));
-
-TEST_P(I18nSourceStreamTest, FilterTests) {
- Init();
- // Create the chain of read buffers.
- PushReadResults(GetParam().test->input, GetParam().read_size);
-
- // Process the buffers.
- std::string actual_output;
- int rv = ReadStream(&actual_output);
-
- // Check the results.
- std::string expected_output(GetParam().test->expected_output);
- EXPECT_EQ(expected_output.size(), static_cast<size_t>(rv));
- EXPECT_EQ(expected_output, actual_output);
- EXPECT_EQ("i18n", stream()->Description());
-}
-
-TEST_P(I18nSourceStreamTest, LargeFilterTests) {
- Init();
- std::string padding;
- // 251 and 599 are prime and avoid power-of-two repetition.
- int padding_modulus = 251;
- int pad_size = 599;
- padding.resize(pad_size);
- for (int i = 0; i < pad_size; ++i)
- padding[i] = i % padding_modulus;
-
- // Create the chain of read buffers.
- const int kPadCount = 128; // Arbitrary number of pads to add.
- for (int i = 0; i < kPadCount; ++i) {
- source()->AddReadResult(padding.c_str(), padding.size(), net::OK,
- GetParam().mode);
- }
- PushReadResults(GetParam().test->input, GetParam().read_size);
-
- // Process the buffers.
- std::string actual_output;
- int rv = ReadStream(&actual_output);
-
- // Check the results.
- size_t total_padding = kPadCount * padding.size();
- std::string expected_output(GetParam().test->expected_output);
- ASSERT_EQ(expected_output.size() + total_padding, static_cast<size_t>(rv));
- for (int i = 0; i < kPadCount; ++i) {
- EXPECT_EQ(actual_output.substr(i * padding.size(), padding.size()),
- padding);
- }
- EXPECT_EQ(expected_output, &actual_output[total_padding]);
- EXPECT_EQ("i18n", stream()->Description());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/webui/network_error_url_loader.cc b/chromium/content/browser/webui/network_error_url_loader.cc
index 9372a60756a..5771f7ad7a3 100644
--- a/chromium/content/browser/webui/network_error_url_loader.cc
+++ b/chromium/content/browser/webui/network_error_url_loader.cc
@@ -29,9 +29,9 @@ void StartNetworkErrorsURLLoader(const ResourceRequest& request,
}
}
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = net_error;
- client->OnComplete(request_complete_data);
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net_error;
+ client->OnComplete(status);
}
} // namespace content
diff --git a/chromium/content/browser/webui/shared_resources_data_source.cc b/chromium/content/browser/webui/shared_resources_data_source.cc
index 589c395687b..f1338cacabd 100644
--- a/chromium/content/browser/webui/shared_resources_data_source.cc
+++ b/chromium/content/browser/webui/shared_resources_data_source.cc
@@ -15,6 +15,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
+#include "mojo/public/js/grit/mojo_bindings_resources.h"
#include "ui/base/layout.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/resources/grit/webui_resources.h"
@@ -45,7 +46,7 @@ const struct {
const char* const path;
const int resource_id;
} kAdditionalResourceMapEntries[] = {
- {"js/mojo_bindings.js", IDR_WEBUI_MOJO_BINDINGS_JS},
+ {"js/mojo_bindings.js", IDR_MOJO_BINDINGS_JS},
};
void AddResource(const std::string& path,
@@ -199,7 +200,7 @@ SharedResourcesDataSource::GetAccessControlAllowOriginForOrigin(
}
bool SharedResourcesDataSource::IsGzipped(const std::string& path) const {
- return path == "js/mojo_bindings.js";
+ return webui::IsSharedResourceGzipped(path);
}
} // namespace content
diff --git a/chromium/content/browser/webui/url_data_manager.cc b/chromium/content/browser/webui/url_data_manager.cc
index f45d227fe94..bdfc5d93765 100644
--- a/chromium/content/browser/webui/url_data_manager.cc
+++ b/chromium/content/browser/webui/url_data_manager.cc
@@ -34,7 +34,7 @@ base::LazyInstance<base::Lock>::Leaky g_delete_lock = LAZY_INSTANCE_INITIALIZER;
URLDataManager* GetFromBrowserContext(BrowserContext* context) {
if (!context->GetUserData(kURLDataManagerKeyName)) {
context->SetUserData(kURLDataManagerKeyName,
- base::MakeUnique<URLDataManager>(context));
+ std::make_unique<URLDataManager>(context));
}
return static_cast<URLDataManager*>(
context->GetUserData(kURLDataManagerKeyName));
@@ -60,7 +60,7 @@ static void UpdateWebUIDataSourceOnIOThread(
} // namespace
// static
-URLDataManager::URLDataSources* URLDataManager::data_sources_ = NULL;
+URLDataManager::URLDataSources* URLDataManager::data_sources_ = nullptr;
URLDataManager::URLDataManager(BrowserContext* browser_context)
: browser_context_(browser_context) {
diff --git a/chromium/content/browser/webui/url_data_manager_backend.cc b/chromium/content/browser/webui/url_data_manager_backend.cc
index 66e52a35974..88de8668be5 100644
--- a/chromium/content/browser/webui/url_data_manager_backend.cc
+++ b/chromium/content/browser/webui/url_data_manager_backend.cc
@@ -30,7 +30,6 @@
#include "content/browser/net/view_blob_internals_job_factory.h"
#include "content/browser/net/view_http_cache_job_factory.h"
#include "content/browser/resource_context_impl.h"
-#include "content/browser/webui/i18n_source_stream.h"
#include "content/browser/webui/shared_resources_data_source.h"
#include "content/browser/webui/url_data_source_impl.h"
#include "content/browser/webui/web_ui_data_source_impl.h"
@@ -52,6 +51,7 @@
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory.h"
#include "ui/base/template_expressions.h"
+#include "ui/base/webui/i18n_source_stream.h"
#include "url/url_util.h"
namespace content {
@@ -251,7 +251,7 @@ std::unique_ptr<net::SourceStream> URLRequestChromeJob::SetUpSourceStream() {
}
if (replacements_) {
- source_stream = I18nSourceStream::Create(
+ source_stream = ui::I18nSourceStream::Create(
std::move(source_stream), net::SourceStream::TYPE_NONE, replacements_);
}
@@ -437,7 +437,7 @@ URLDataManagerBackend::CreateProtocolHandler(
ResourceContext* resource_context,
ChromeBlobStorageContext* blob_storage_context) {
DCHECK(resource_context);
- return base::MakeUnique<ChromeProtocolHandler>(resource_context,
+ return std::make_unique<ChromeProtocolHandler>(resource_context,
blob_storage_context);
}
diff --git a/chromium/content/browser/webui/web_ui_controller_factory_registry.cc b/chromium/content/browser/webui/web_ui_controller_factory_registry.cc
index b151e32a73a..dd0e955be8d 100644
--- a/chromium/content/browser/webui/web_ui_controller_factory_registry.cc
+++ b/chromium/content/browser/webui/web_ui_controller_factory_registry.cc
@@ -8,21 +8,24 @@
#include "base/lazy_instance.h"
#include "content/browser/frame_host/debug_urls.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/url_utils.h"
#include "url/gurl.h"
namespace content {
base::LazyInstance<std::vector<WebUIControllerFactory*>>::DestructorAtExit
- g_factories = LAZY_INSTANCE_INITIALIZER;
+ g_web_ui_controller_factories = LAZY_INSTANCE_INITIALIZER;
void WebUIControllerFactory::RegisterFactory(WebUIControllerFactory* factory) {
- g_factories.Pointer()->push_back(factory);
+ g_web_ui_controller_factories.Pointer()->push_back(factory);
}
void WebUIControllerFactory::UnregisterFactoryForTesting(
WebUIControllerFactory* factory) {
- std::vector<WebUIControllerFactory*>* factories = g_factories.Pointer();
+ std::vector<WebUIControllerFactory*>* factories =
+ g_web_ui_controller_factories.Pointer();
for (size_t i = 0; i < factories->size(); ++i) {
if ((*factories)[i] == factory) {
factories->erase(factories->begin() + i);
@@ -38,19 +41,21 @@ WebUIControllerFactoryRegistry* WebUIControllerFactoryRegistry::GetInstance() {
WebUIController* WebUIControllerFactoryRegistry::CreateWebUIControllerForURL(
WebUI* web_ui, const GURL& url) const {
- std::vector<WebUIControllerFactory*>* factories = g_factories.Pointer();
+ std::vector<WebUIControllerFactory*>* factories =
+ g_web_ui_controller_factories.Pointer();
for (size_t i = 0; i < factories->size(); ++i) {
WebUIController* controller = (*factories)[i]->CreateWebUIControllerForURL(
web_ui, url);
if (controller)
return controller;
}
- return NULL;
+ return nullptr;
}
WebUI::TypeID WebUIControllerFactoryRegistry::GetWebUIType(
BrowserContext* browser_context, const GURL& url) const {
- std::vector<WebUIControllerFactory*>* factories = g_factories.Pointer();
+ std::vector<WebUIControllerFactory*>* factories =
+ g_web_ui_controller_factories.Pointer();
for (size_t i = 0; i < factories->size(); ++i) {
WebUI::TypeID type = (*factories)[i]->GetWebUIType(browser_context, url);
if (type != WebUI::kNoWebUI)
@@ -61,7 +66,8 @@ WebUI::TypeID WebUIControllerFactoryRegistry::GetWebUIType(
bool WebUIControllerFactoryRegistry::UseWebUIForURL(
BrowserContext* browser_context, const GURL& url) const {
- std::vector<WebUIControllerFactory*>* factories = g_factories.Pointer();
+ std::vector<WebUIControllerFactory*>* factories =
+ g_web_ui_controller_factories.Pointer();
for (size_t i = 0; i < factories->size(); ++i) {
if ((*factories)[i]->UseWebUIForURL(browser_context, url))
return true;
@@ -71,7 +77,8 @@ bool WebUIControllerFactoryRegistry::UseWebUIForURL(
bool WebUIControllerFactoryRegistry::UseWebUIBindingsForURL(
BrowserContext* browser_context, const GURL& url) const {
- std::vector<WebUIControllerFactory*>* factories = g_factories.Pointer();
+ std::vector<WebUIControllerFactory*>* factories =
+ g_web_ui_controller_factories.Pointer();
for (size_t i = 0; i < factories->size(); ++i) {
if ((*factories)[i]->UseWebUIBindingsForURL(browser_context, url))
return true;
@@ -83,11 +90,15 @@ bool WebUIControllerFactoryRegistry::IsURLAcceptableForWebUI(
BrowserContext* browser_context,
const GURL& url) const {
return UseWebUIForURL(browser_context, url) ||
- // It's possible to load about:blank in a Web UI renderer.
- // See http://crbug.com/42547
- url.spec() == url::kAboutBlankURL ||
- // javascript: and debug URLs like chrome://kill are allowed.
- IsRendererDebugURL(url);
+ // It's possible to load about:blank in a Web UI renderer.
+ // See http://crbug.com/42547
+ url.spec() == url::kAboutBlankURL ||
+ // javascript: and debug URLs like chrome://kill are allowed.
+ IsRendererDebugURL(url) ||
+ // Temporarily allow the embedder to whitelist URLs allowed in WebUI
+ // until crbug.com/768526 is resolved.
+ GetContentClient()->browser()->IsURLAcceptableForWebUI(browser_context,
+ url);
}
WebUIControllerFactoryRegistry::WebUIControllerFactoryRegistry() {
diff --git a/chromium/content/browser/webui/web_ui_data_source_unittest.cc b/chromium/content/browser/webui/web_ui_data_source_unittest.cc
index 08695f0bf90..f2974ff7f75 100644
--- a/chromium/content/browser/webui/web_ui_data_source_unittest.cc
+++ b/chromium/content/browser/webui/web_ui_data_source_unittest.cc
@@ -35,7 +35,7 @@ class TestClient : public TestContentClient {
base::RefCountedMemory* GetDataResourceBytes(
int resource_id) const override {
- base::RefCountedStaticMemory* bytes = NULL;
+ base::RefCountedStaticMemory* bytes = nullptr;
if (resource_id == kDummyDefaultResourceId) {
bytes = new base::RefCountedStaticMemory(
kDummyDefaultResource, arraysize(kDummyDefaultResource));
diff --git a/chromium/content/browser/webui/web_ui_impl.cc b/chromium/content/browser/webui/web_ui_impl.cc
index 278ec150c6b..eabd4a4a8e6 100644
--- a/chromium/content/browser/webui/web_ui_impl.cc
+++ b/chromium/content/browser/webui/web_ui_impl.cc
@@ -56,7 +56,7 @@ class WebUIImpl::MainFrameNavigationObserver : public WebContentsObserver {
WebUIImpl* web_ui_;
};
-const WebUI::TypeID WebUI::kNoWebUI = NULL;
+const WebUI::TypeID WebUI::kNoWebUI = nullptr;
// static
base::string16 WebUI::GetJavascriptCall(
@@ -112,7 +112,9 @@ void WebUIImpl::OnWebUISend(RenderFrameHost* sender,
sender->GetProcess()->GetID()) ||
!WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
web_contents_->GetBrowserContext(), source_url)) {
- NOTREACHED() << "Blocked unauthorized use of WebUIBindings.";
+ bad_message::ReceivedBadMessage(
+ sender->GetProcess(),
+ bad_message::WEBUI_SEND_FROM_UNAUTHORIZED_PROCESS);
return;
}
diff --git a/chromium/content/browser/webui/web_ui_mojo_browsertest.cc b/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
index b54e78bfce3..5c8b8ce1aef 100644
--- a/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
+++ b/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -141,7 +141,7 @@ class PingTestWebUIController : public TestWebUIController,
void CreateHandler(mojom::BrowserTargetRequest request) {
browser_target_ =
- base::MakeUnique<BrowserTargetImpl>(run_loop_, std::move(request));
+ std::make_unique<BrowserTargetImpl>(run_loop_, std::move(request));
}
private:
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 579df51d808..8996f11d328 100644
--- a/chromium/content/browser/webui/web_ui_url_loader_factory.cc
+++ b/chromium/content/browser/webui/web_ui_url_loader_factory.cc
@@ -13,11 +13,12 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/string_piece.h"
#include "base/task_scheduler/post_task.h"
+#include "content/browser/bad_message.h"
#include "content/browser/blob_storage/blob_internals_url_loader.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
-#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/histogram_internals_url_loader.h"
+#include "content/browser/loader/global_routing_id.h"
#include "content/browser/resource_context_impl.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/webui/network_error_url_loader.h"
@@ -27,6 +28,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/network_service.mojom.h"
#include "content/public/common/url_constants.h"
#include "mojo/public/cpp/bindings/binding_set.h"
@@ -38,14 +40,15 @@ namespace content {
namespace {
class WebUIURLLoaderFactory;
-base::LazyInstance<std::map<int, std::unique_ptr<WebUIURLLoaderFactory>>>::Leaky
- g_factories = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<std::map<GlobalFrameRoutingId,
+ std::unique_ptr<WebUIURLLoaderFactory>>>::Leaky
+ g_web_ui_url_loader_factories = LAZY_INSTANCE_INITIALIZER;
void CallOnError(mojom::URLLoaderClientPtrInfo client_info, int error_code) {
mojom::URLLoaderClientPtr client;
client.Bind(std::move(client_info));
- ResourceRequestCompletionStatus status;
+ network::URLLoaderCompletionStatus status;
status.error_code = error_code;
client->OnComplete(status);
}
@@ -97,19 +100,19 @@ void ReadData(scoped_refptr<ResourceResponse> headers,
MojoResult result = data_pipe.producer_handle->BeginWriteData(
&buffer, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE);
CHECK_EQ(result, MOJO_RESULT_OK);
- CHECK_EQ(num_bytes, output_size);
+ CHECK_GE(num_bytes, output_size);
if (gzipped) {
- base::StringPiece output(static_cast<char*>(buffer), num_bytes);
+ base::StringPiece output(static_cast<char*>(buffer), output_size);
CHECK(compression::GzipUncompress(input, output));
} else {
memcpy(buffer, bytes->front(), output_size);
}
- result = data_pipe.producer_handle->EndWriteData(num_bytes);
+ result = data_pipe.producer_handle->EndWriteData(output_size);
CHECK_EQ(result, MOJO_RESULT_OK);
client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
- ResourceRequestCompletionStatus status(net::OK);
+ network::URLLoaderCompletionStatus status(net::OK);
status.encoded_data_length = output_size;
status.encoded_body_length = output_size;
client->OnComplete(status);
@@ -205,14 +208,12 @@ void StartURLLoader(const ResourceRequest& request,
}
class WebUIURLLoaderFactory : public mojom::URLLoaderFactory,
- public FrameTreeNode::Observer {
+ public WebContentsObserver {
public:
- WebUIURLLoaderFactory(FrameTreeNode* ftn)
- : frame_tree_node_id_(ftn->frame_tree_node_id()),
- storage_partition_(static_cast<StoragePartitionImpl*>(
- ftn->current_frame_host()->GetProcess()->GetStoragePartition())) {
- ftn->AddObserver(this);
- }
+ WebUIURLLoaderFactory(RenderFrameHost* rfh, const std::string& scheme)
+ : WebContentsObserver(WebContents::FromRenderFrameHost(rfh)),
+ render_frame_host_(rfh),
+ scheme_(scheme) {}
~WebUIURLLoaderFactory() override {}
@@ -232,8 +233,16 @@ class WebUIURLLoaderFactory : public mojom::URLLoaderFactory,
const net::MutableNetworkTrafficAnnotationTag&
traffic_annotation) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (request.url.scheme() != scheme_) {
+ ReceivedBadMessage(render_frame_host_->GetProcess(),
+ bad_message::WEBUI_BAD_SCHEME_ACCESS);
+ client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ return;
+ }
+
if (request.url.host_piece() == kChromeUINetworkViewCacheHost) {
- storage_partition_->GetNetworkContext()->HandleViewCacheRequest(
+ GetStoragePartition()->GetNetworkContext()->HandleViewCacheRequest(
request.url, std::move(client));
return;
}
@@ -244,7 +253,7 @@ class WebUIURLLoaderFactory : public mojom::URLLoaderFactory,
base::BindOnce(&StartBlobInternalsURLLoader, request,
client.PassInterface(),
base::Unretained(ChromeBlobStorageContext::GetFor(
- storage_partition_->browser_context()))));
+ GetStoragePartition()->browser_context()))));
return;
}
@@ -259,26 +268,41 @@ class WebUIURLLoaderFactory : public mojom::URLLoaderFactory,
return;
}
+ // We pass the FrameTreeNode ID to get to the WebContents because requests
+ // 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::BindOnce(
- &StartURLLoader, request, frame_tree_node_id_,
+ &StartURLLoader, request, render_frame_host_->GetFrameTreeNodeId(),
client.PassInterface(),
- storage_partition_->browser_context()->GetResourceContext()));
+ GetStoragePartition()->browser_context()->GetResourceContext()));
}
void Clone(mojom::URLLoaderFactoryRequest request) override {
loader_factory_bindings_.AddBinding(this, std::move(request));
}
- // FrameTreeNode::Observer implementation:
- void OnFrameTreeNodeDestroyed(FrameTreeNode* node) override {
- g_factories.Get().erase(frame_tree_node_id_);
+ // WebContentsObserver implementation:
+ void RenderFrameDeleted(RenderFrameHost* render_frame_host) override {
+ if (render_frame_host != render_frame_host_)
+ return;
+ g_web_ui_url_loader_factories.Get().erase(
+ GlobalFrameRoutingId(render_frame_host_->GetRoutingID(),
+ render_frame_host_->GetProcess()->GetID()));
}
+ const std::string& scheme() const { return scheme_; }
+
private:
- int frame_tree_node_id_;
- StoragePartitionImpl* storage_partition_;
+ StoragePartitionImpl* GetStoragePartition() {
+ return static_cast<StoragePartitionImpl*>(
+ render_frame_host_->GetProcess()->GetStoragePartition());
+ }
+
+ RenderFrameHost* render_frame_host_;
+ std::string scheme_;
mojo::BindingSet<mojom::URLLoaderFactory> loader_factory_bindings_;
DISALLOW_COPY_AND_ASSIGN(WebUIURLLoaderFactory);
@@ -286,11 +310,18 @@ class WebUIURLLoaderFactory : public mojom::URLLoaderFactory,
} // namespace
-mojom::URLLoaderFactoryPtr CreateWebUIURLLoader(FrameTreeNode* node) {
- int ftn_id = node->frame_tree_node_id();
- if (g_factories.Get()[ftn_id].get() == nullptr)
- g_factories.Get()[ftn_id] = base::MakeUnique<WebUIURLLoaderFactory>(node);
- return g_factories.Get()[ftn_id]->CreateBinding();
+mojom::URLLoaderFactoryPtr CreateWebUIURLLoader(
+ RenderFrameHost* render_frame_host,
+ const std::string& scheme) {
+ GlobalFrameRoutingId routing_id(render_frame_host->GetRoutingID(),
+ render_frame_host->GetProcess()->GetID());
+ if (g_web_ui_url_loader_factories.Get().find(routing_id) ==
+ g_web_ui_url_loader_factories.Get().end() ||
+ g_web_ui_url_loader_factories.Get()[routing_id]->scheme() != scheme) {
+ g_web_ui_url_loader_factories.Get()[routing_id] =
+ std::make_unique<WebUIURLLoaderFactory>(render_frame_host, scheme);
+ }
+ return g_web_ui_url_loader_factories.Get()[routing_id]->CreateBinding();
}
} // namespace content
diff --git a/chromium/content/browser/webui/web_ui_url_loader_factory.h b/chromium/content/browser/webui/web_ui_url_loader_factory.h
index 733e8e31a1c..cbb53849290 100644
--- a/chromium/content/browser/webui/web_ui_url_loader_factory.h
+++ b/chromium/content/browser/webui/web_ui_url_loader_factory.h
@@ -8,10 +8,15 @@
#include "content/public/common/url_loader_factory.mojom.h"
namespace content {
-class FrameTreeNode;
+class RenderFrameHost;
-// Creates a URLLoaderFactory interface pointer for serving WebUI requests.
-mojom::URLLoaderFactoryPtr CreateWebUIURLLoader(FrameTreeNode* node);
+// Creates a URLLoaderFactory interface pointer for serving WebUI requests to
+// the given |render_frame_host|. The factory will only create loaders for
+// requests with the same scheme as |scheme|. This is needed because there is
+// more than one scheme used for WebUI, and not all have WebUI bindings.
+mojom::URLLoaderFactoryPtr CreateWebUIURLLoader(
+ RenderFrameHost* render_frame_host,
+ const std::string& scheme);
} // namespace content
diff --git a/chromium/content/browser/zygote_host/zygote_communication_linux.cc b/chromium/content/browser/zygote_host/zygote_communication_linux.cc
index 7cd9c8b2655..5fb75af5b03 100644
--- a/chromium/content/browser/zygote_host/zygote_communication_linux.cc
+++ b/chromium/content/browser/zygote_host/zygote_communication_linux.cc
@@ -9,6 +9,7 @@
#include "base/base_switches.h"
#include "base/command_line.h"
+#include "base/i18n/unicodestring.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
@@ -24,6 +25,8 @@
#include "content/public/common/result_codes.h"
#include "media/base/media_switches.h"
#include "services/service_manager/embedder/switches.h"
+#include "services/service_manager/sandbox/switches.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
#include "ui/display/display_switches.h"
#include "ui/gfx/switches.h"
@@ -102,6 +105,12 @@ pid_t ZygoteCommunication::ForkRequest(
for (std::vector<std::string>::const_iterator i = argv.begin();
i != argv.end(); ++i)
pickle.WriteString(*i);
+ if (process_type == switches::kRendererProcess) {
+ std::unique_ptr<icu::TimeZone> timezone(icu::TimeZone::createDefault());
+ icu::UnicodeString timezone_id;
+ pickle.WriteString16(
+ base::i18n::UnicodeStringToString16(timezone->getID(timezone_id)));
+ }
// Fork requests contain one file descriptor for the PID oracle, and one
// more for each file descriptor mapping for the child process.
@@ -154,7 +163,7 @@ pid_t ZygoteCommunication::ForkRequest(
base::Pickle pid_pickle;
pid_pickle.WriteInt(kZygoteCommandForkRealPID);
pid_pickle.WriteInt(real_pid);
- if (!SendMessage(pid_pickle, NULL))
+ if (!SendMessage(pid_pickle, nullptr))
return base::kNullProcessHandle;
}
@@ -214,7 +223,7 @@ void ZygoteCommunication::EnsureProcessTerminated(pid_t process) {
pickle.WriteInt(kZygoteCommandReap);
pickle.WriteInt(process);
- if (!SendMessage(pickle, NULL))
+ if (!SendMessage(pickle, nullptr))
LOG(ERROR) << "Failed to send Reap message to zygote";
ZygoteChildDied(process);
}
@@ -251,10 +260,11 @@ void ZygoteCommunication::Init() {
// to the zygote/renderers.
// Should this list be obtained from browser_render_process_host.cc?
static const char* const kForwardSwitches[] = {
+ service_manager::switches::kAllowSandboxDebugging,
service_manager::switches::kDisableInProcessStackTraces,
- switches::kAllowSandboxDebugging, switches::kAndroidFontsPath,
- switches::kClearKeyCdmPathForTesting,
- switches::kDisableSeccompFilterSandbox, switches::kEnableHeapProfiling,
+ service_manager::switches::kDisableSeccompFilterSandbox,
+ switches::kAndroidFontsPath, switches::kClearKeyCdmPathForTesting,
+ switches::kEnableHeapProfiling,
switches::kEnableLogging, // Support, e.g., --enable-logging=stderr.
// Need to tell the zygote that it is headless so that we don't try to use
// the wrong type of main delegate.
@@ -274,7 +284,7 @@ void ZygoteCommunication::Init() {
base::Pickle pickle;
pickle.WriteInt(kZygoteCommandGetSandboxStatus);
- if (!SendMessage(pickle, NULL))
+ if (!SendMessage(pickle, nullptr))
LOG(FATAL) << "Cannot communicate with zygote";
init_ = true;
@@ -295,7 +305,7 @@ base::TerminationStatus ZygoteCommunication::GetTerminationStatus(
ssize_t len;
{
base::AutoLock lock(control_lock_);
- if (!SendMessage(pickle, NULL))
+ if (!SendMessage(pickle, nullptr))
LOG(ERROR) << "Failed to send GetTerminationStatus message to zygote";
len = ReadReply(buf, sizeof(buf));
}
diff --git a/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc b/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
index cf264bfa84d..680c08a8d60 100644
--- a/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
+++ b/chromium/content/browser/zygote_host/zygote_host_impl_linux.cc
@@ -15,13 +15,15 @@
#include "base/process/memory.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/sandbox_host_linux.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
#include "content/common/zygote_commands_linux.h"
+#include "content/public/common/common_sandbox_support_linux.h"
#include "content/public/common/content_switches.h"
#include "sandbox/linux/services/credentials.h"
#include "sandbox/linux/services/namespace_sandbox.h"
#include "sandbox/linux/suid/client/setuid_sandbox_host.h"
#include "sandbox/linux/suid/common/sandbox.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
+#include "services/service_manager/sandbox/switches.h"
namespace content {
@@ -110,7 +112,8 @@ void ZygoteHostImpl::Init(const base::CommandLine& command_line) {
"OOM scores.";
}
#endif
- } else if (!command_line.HasSwitch(switches::kDisableSetuidSandbox) &&
+ } else if (!command_line.HasSwitch(
+ service_manager::switches::kDisableSetuidSandbox) &&
!sandbox_binary_.empty()) {
use_suid_sandbox_ = true;
diff --git a/chromium/content/child/BUILD.gn b/chromium/content/child/BUILD.gn
index a92ef35093e..6a445da0316 100644
--- a/chromium/content/child/BUILD.gn
+++ b/chromium/content/child/BUILD.gn
@@ -32,43 +32,19 @@ target(link_target_type, "child") {
}
sources = [
- "appcache/appcache_backend_proxy.cc",
- "appcache/appcache_backend_proxy.h",
- "appcache/appcache_dispatcher.cc",
- "appcache/appcache_dispatcher.h",
- "appcache/appcache_frontend_impl.cc",
- "appcache/appcache_frontend_impl.h",
- "appcache/web_application_cache_host_impl.cc",
- "appcache/web_application_cache_host_impl.h",
"assert_matching_enums.cc",
- "background_sync/background_sync_type_converters.cc",
- "background_sync/background_sync_type_converters.h",
"blink_platform_impl.cc",
"blink_platform_impl.h",
- "blob_storage/blob_consolidation.cc",
- "blob_storage/blob_consolidation.h",
- "blob_storage/blob_message_filter.cc",
- "blob_storage/blob_message_filter.h",
- "blob_storage/blob_transport_controller.cc",
- "blob_storage/blob_transport_controller.h",
- "blob_storage/webblobregistry_impl.cc",
- "blob_storage/webblobregistry_impl.h",
"browser_font_resource_trusted.cc",
"browser_font_resource_trusted.h",
"child_histogram_fetcher_impl.cc",
"child_histogram_fetcher_impl.h",
- "child_message_filter.cc",
- "child_message_filter.h",
"child_process.cc",
"child_process.h",
"child_process_sandbox_support_impl_linux.cc",
"child_process_sandbox_support_impl_linux.h",
- "child_resource_message_filter.cc",
- "child_resource_message_filter.h",
"child_thread_impl.cc",
"child_thread_impl.h",
- "child_url_loader_factory_getter_impl.cc",
- "child_url_loader_factory_getter_impl.h",
"content_child_helpers.cc",
"content_child_helpers.h",
"dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc",
@@ -79,64 +55,14 @@ target(link_target_type, "child") {
"dwrite_font_proxy/dwrite_localized_strings_win.h",
"dwrite_font_proxy/font_fallback_win.cc",
"dwrite_font_proxy/font_fallback_win.h",
- "feature_policy/feature_policy_platform.cc",
- "feature_policy/feature_policy_platform.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",
"font_warmup_win.cc",
"font_warmup_win.h",
- "ftp_directory_listing_response_delegate.cc",
- "ftp_directory_listing_response_delegate.h",
"image_decoder.cc",
"image_decoder.h",
- "indexed_db/indexed_db_callbacks_impl.cc",
- "indexed_db/indexed_db_callbacks_impl.h",
- "indexed_db/indexed_db_database_callbacks_impl.cc",
- "indexed_db/indexed_db_database_callbacks_impl.h",
- "indexed_db/indexed_db_dispatcher.cc",
- "indexed_db/indexed_db_dispatcher.h",
- "indexed_db/indexed_db_key_builders.cc",
- "indexed_db/indexed_db_key_builders.h",
- "indexed_db/webidbcursor_impl.cc",
- "indexed_db/webidbcursor_impl.h",
- "indexed_db/webidbdatabase_impl.cc",
- "indexed_db/webidbdatabase_impl.h",
- "indexed_db/webidbfactory_impl.cc",
- "indexed_db/webidbfactory_impl.h",
- "loader/cors_url_loader.cc",
- "loader/cors_url_loader.h",
- "loader/cors_url_loader_factory.cc",
- "loader/cors_url_loader_factory.h",
"memory/child_memory_coordinator_impl.cc",
"memory/child_memory_coordinator_impl.h",
"memory/child_memory_coordinator_impl_android.cc",
"memory/child_memory_coordinator_impl_android.h",
- "notifications/notification_data_conversions.cc",
- "notifications/notification_data_conversions.h",
- "notifications/notification_dispatcher.cc",
- "notifications/notification_dispatcher.h",
- "notifications/notification_manager.cc",
- "notifications/notification_manager.h",
- "push_messaging/push_provider.cc",
- "push_messaging/push_provider.h",
- "quota_dispatcher.cc",
- "quota_dispatcher.h",
- "quota_message_filter.cc",
- "quota_message_filter.h",
- "request_extra_data.cc",
- "request_extra_data.h",
- "resource_dispatcher.cc",
- "resource_dispatcher.h",
- "resource_scheduling_filter.cc",
- "resource_scheduling_filter.h",
"runtime_features.cc",
"runtime_features.h",
"scoped_child_process_reference.cc",
@@ -144,73 +70,15 @@ target(link_target_type, "child") {
"scoped_web_callbacks.h",
"service_factory.cc",
"service_factory.h",
- "service_worker/controller_service_worker_connector.cc",
- "service_worker/controller_service_worker_connector.h",
- "service_worker/service_worker_dispatcher.cc",
- "service_worker/service_worker_dispatcher.h",
- "service_worker/service_worker_handle_reference.cc",
- "service_worker/service_worker_handle_reference.h",
- "service_worker/service_worker_message_filter.cc",
- "service_worker/service_worker_message_filter.h",
- "service_worker/service_worker_network_provider.cc",
- "service_worker/service_worker_network_provider.h",
- "service_worker/service_worker_provider_context.cc",
- "service_worker/service_worker_provider_context.h",
- "service_worker/service_worker_subresource_loader.cc",
- "service_worker/service_worker_subresource_loader.h",
- "service_worker/web_service_worker_impl.cc",
- "service_worker/web_service_worker_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",
- "service_worker/web_service_worker_registration_impl.h",
- "shared_memory_data_consumer_handle.cc",
- "shared_memory_data_consumer_handle.h",
- "shared_memory_received_data_factory.cc",
- "shared_memory_received_data_factory.h",
- "shared_worker_devtools_agent.cc",
- "shared_worker_devtools_agent.h",
- "site_isolation_stats_gatherer.cc",
- "site_isolation_stats_gatherer.h",
- "storage_util.cc",
- "storage_util.h",
- "sync_load_context.cc",
- "sync_load_context.h",
- "sync_load_response.cc",
- "sync_load_response.h",
"thread_safe_sender.cc",
"thread_safe_sender.h",
- "url_loader_client_impl.cc",
- "url_loader_client_impl.h",
- "url_response_body_consumer.cc",
- "url_response_body_consumer.h",
- "v8_value_converter_impl.cc",
- "v8_value_converter_impl.h",
- "web_data_consumer_handle_impl.cc",
- "web_data_consumer_handle_impl.h",
- "web_database_impl.cc",
- "web_database_impl.h",
- "web_database_observer_impl.cc",
- "web_database_observer_impl.h",
- "web_url_loader_impl.cc",
- "web_url_loader_impl.h",
- "web_url_request_util.cc",
- "web_url_request_util.h",
"webfallbackthemeengine_impl.cc",
"webfallbackthemeengine_impl.h",
- "webfileutilities_impl.cc",
- "webfileutilities_impl.h",
"webthemeengine_impl_android.cc",
"webthemeengine_impl_android.h",
"webthemeengine_impl_default.cc",
"webthemeengine_impl_default.h",
"webthemeengine_impl_mac.h",
- "weburlresponse_extradata_impl.cc",
- "weburlresponse_extradata_impl.h",
- "worker_thread_message_filter.cc",
- "worker_thread_message_filter.h",
- "worker_thread_registry.cc",
- "worker_thread_registry.h",
]
configs += [ "//build/config:precompiled_headers" ]
diff --git a/chromium/content/child/DEPS b/chromium/content/child/DEPS
index ed11f056f96..2e4293efebb 100644
--- a/chromium/content/child/DEPS
+++ b/chromium/content/child/DEPS
@@ -12,7 +12,6 @@ include_rules = [
"+services/device/public/interfaces",
"+services/resource_coordinator",
"+services/service_manager",
- "+storage/public/interfaces",
"+third_party/WebKit/common",
"+v8/include/v8.h"
]
diff --git a/chromium/content/child/OWNERS b/chromium/content/child/OWNERS
index 40e30002815..2029635600e 100644
--- a/chromium/content/child/OWNERS
+++ b/chromium/content/child/OWNERS
@@ -1,9 +1,8 @@
+haraken@chromium.org
+
# For Blink API usage
dglazkov@chromium.org
-# For resource loading
-yhirano@chromium.org
-
# AppCache
per-file appcache*=michaeln@chromium.org
diff --git a/chromium/content/child/blink_platform_impl.cc b/chromium/content/child/blink_platform_impl.cc
index ea99bcde1fa..c9cbd793db4 100644
--- a/chromium/content/child/blink_platform_impl.cc
+++ b/chromium/content/child/blink_platform_impl.cc
@@ -39,16 +39,8 @@
#include "content/app/strings/grit/content_strings.h"
#include "content/child/child_thread_impl.h"
#include "content/child/content_child_helpers.h"
-#include "content/child/feature_policy/feature_policy_platform.h"
-#include "content/child/notifications/notification_dispatcher.h"
-#include "content/child/notifications/notification_manager.h"
-#include "content/child/push_messaging/push_provider.h"
-#include "content/child/thread_safe_sender.h"
-#include "content/child/web_data_consumer_handle_impl.h"
-#include "content/child/web_url_loader_impl.h"
-#include "content/child/web_url_request_util.h"
-#include "content/child/worker_thread_registry.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
#include "net/base/net_errors.h"
@@ -71,7 +63,6 @@ using blink::WebString;
using blink::WebThemeEngine;
using blink::WebURL;
using blink::WebURLError;
-using blink::WebURLLoader;
namespace content {
@@ -187,8 +178,6 @@ static int ToMessageID(WebLocalizedString::Name name) {
return IDS_FORM_INPUT_ALT;
case WebLocalizedString::kMissingPluginText:
return IDS_PLUGIN_INITIALIZATION_ERROR;
- case WebLocalizedString::kMediaRemotingDisableText:
- return IDS_MEDIA_REMOTING_DISABLE_TEXT;
case WebLocalizedString::kMediaRemotingCastText:
return IDS_MEDIA_REMOTING_CAST_TEXT;
case WebLocalizedString::kMediaRemotingCastToUnknownDeviceText:
@@ -205,6 +194,8 @@ static int ToMessageID(WebLocalizedString::Name name) {
return IDS_FORM_OTHER_WEEK_LABEL;
case WebLocalizedString::kOverflowMenuCaptions:
return IDS_MEDIA_OVERFLOW_MENU_CLOSED_CAPTIONS;
+ case WebLocalizedString::kOverflowMenuCaptionsSubmenuTitle:
+ return IDS_MEDIA_OVERFLOW_MENU_CLOSED_CAPTIONS_SUBMENU_TITLE;
case WebLocalizedString::kOverflowMenuCast:
return IDS_MEDIA_OVERFLOW_MENU_CAST;
case WebLocalizedString::kOverflowMenuEnterFullscreen:
@@ -320,24 +311,14 @@ static int ToMessageID(WebLocalizedString::Name name) {
BlinkPlatformImpl::BlinkPlatformImpl()
: BlinkPlatformImpl(base::ThreadTaskRunnerHandle::IsSet()
? base::ThreadTaskRunnerHandle::Get()
- : nullptr) {
-}
+ : nullptr,
+ nullptr) {}
BlinkPlatformImpl::BlinkPlatformImpl(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
- : main_thread_task_runner_(main_thread_task_runner),
- compositor_thread_(nullptr) {
- InternalInit();
-}
-
-void BlinkPlatformImpl::InternalInit() {
- // ChildThread may not exist in some tests.
- if (ChildThreadImpl::current()) {
- thread_safe_sender_ = ChildThreadImpl::current()->thread_safe_sender();
- notification_dispatcher_ =
- ChildThreadImpl::current()->notification_dispatcher();
- }
-}
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner)
+ : 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) {
@@ -361,12 +342,6 @@ void BlinkPlatformImpl::UpdateWebThreadTLS(blink::WebThread* thread,
BlinkPlatformImpl::~BlinkPlatformImpl() {
}
-std::unique_ptr<blink::WebDataConsumerHandle>
-BlinkPlatformImpl::CreateDataConsumerHandle(
- mojo::ScopedDataPipeConsumerHandle handle) {
- return base::MakeUnique<WebDataConsumerHandleImpl>(std::move(handle));
-}
-
WebString BlinkPlatformImpl::UserAgent() {
return blink::WebString::FromUTF8(GetContentClient()->GetUserAgent());
}
@@ -397,13 +372,6 @@ std::unique_ptr<blink::WebThread> BlinkPlatformImpl::CreateWebAudioThread() {
return std::move(thread);
}
-void BlinkPlatformImpl::SetCompositorThread(
- blink::scheduler::WebThreadBase* compositor_thread) {
- compositor_thread_ = compositor_thread;
- if (compositor_thread_)
- WaitUntilWebThreadTLSUpdate(compositor_thread_);
-}
-
blink::WebThread* BlinkPlatformImpl::CurrentThread() {
return static_cast<blink::WebThread*>(current_thread_slot_.Get());
}
@@ -605,7 +573,8 @@ WebString BlinkPlatformImpl::QueryLocalizedString(WebLocalizedString::Name name,
if (message_id < 0)
return WebString();
return WebString::FromUTF16(base::ReplaceStringPlaceholders(
- GetContentClient()->GetLocalizedString(message_id), value.Utf16(), NULL));
+ GetContentClient()->GetLocalizedString(message_id), value.Utf16(),
+ nullptr));
}
WebString BlinkPlatformImpl::QueryLocalizedString(WebLocalizedString::Name name,
@@ -619,11 +588,11 @@ WebString BlinkPlatformImpl::QueryLocalizedString(WebLocalizedString::Name name,
values.push_back(value1.Utf16());
values.push_back(value2.Utf16());
return WebString::FromUTF16(base::ReplaceStringPlaceholders(
- GetContentClient()->GetLocalizedString(message_id), values, NULL));
+ GetContentClient()->GetLocalizedString(message_id), values, nullptr));
}
-blink::WebThread* BlinkPlatformImpl::CompositorThread() const {
- return compositor_thread_;
+bool BlinkPlatformImpl::IsRendererSideResourceSchedulerEnabled() const {
+ return base::FeatureList::IsEnabled(features::kRendererSideResourceScheduler);
}
std::unique_ptr<blink::WebGestureCurve>
@@ -637,14 +606,6 @@ BlinkPlatformImpl::CreateFlingAnimationCurve(
IsMainThread());
}
-void BlinkPlatformImpl::DidStartWorkerThread() {
- WorkerThreadRegistry::Instance()->DidStartCurrentWorkerThread();
-}
-
-void BlinkPlatformImpl::WillStopWorkerThread() {
- WorkerThreadRegistry::Instance()->WillStopCurrentWorkerThread();
-}
-
bool BlinkPlatformImpl::AllowScriptExtensionForServiceWorker(
const blink::WebURL& scriptUrl) {
return GetContentClient()->AllowScriptExtensionForServiceWorker(scriptUrl);
@@ -658,19 +619,6 @@ const char* BlinkPlatformImpl::GetBrowserServiceName() const {
return mojom::kBrowserServiceName;
}
-blink::WebNotificationManager* BlinkPlatformImpl::GetNotificationManager() {
- if (!thread_safe_sender_.get() || !notification_dispatcher_.get())
- return nullptr;
-
- return NotificationManager::ThreadSpecificInstance(
- thread_safe_sender_.get(),
- notification_dispatcher_.get());
-}
-
-blink::WebPushProvider* BlinkPlatformImpl::PushProvider() {
- return PushProvider::ThreadSpecificInstance(main_thread_task_runner_);
-}
-
blink::WebMediaCapabilitiesClient*
BlinkPlatformImpl::MediaCapabilitiesClient() {
return &media_capabilities_client_;
@@ -788,24 +736,9 @@ bool BlinkPlatformImpl::IsDomKeyForModifier(int dom_key) {
static_cast<ui::DomKey>(dom_key));
}
-std::unique_ptr<blink::WebFeaturePolicy> BlinkPlatformImpl::CreateFeaturePolicy(
- const blink::WebFeaturePolicy* parent_policy,
- const blink::WebParsedFeaturePolicy& container_policy,
- const blink::WebParsedFeaturePolicy& policy_header,
- const blink::WebSecurityOrigin& origin) {
- std::unique_ptr<FeaturePolicy> policy = FeaturePolicy::CreateFromParentPolicy(
- static_cast<const FeaturePolicy*>(parent_policy),
- FeaturePolicyHeaderFromWeb(container_policy), url::Origin(origin));
- policy->SetHeaderPolicy(FeaturePolicyHeaderFromWeb(policy_header));
- return std::move(policy);
-}
-
-std::unique_ptr<blink::WebFeaturePolicy>
-BlinkPlatformImpl::DuplicateFeaturePolicyWithOrigin(
- const blink::WebFeaturePolicy& policy,
- const blink::WebSecurityOrigin& new_origin) {
- return FeaturePolicy::CreateFromPolicyWithOrigin(
- static_cast<const FeaturePolicy&>(policy), url::Origin(new_origin));
+scoped_refptr<base::SingleThreadTaskRunner> BlinkPlatformImpl::GetIOTaskRunner()
+ const {
+ return io_thread_task_runner_;
}
} // namespace content
diff --git a/chromium/content/child/blink_platform_impl.h b/chromium/content/child/blink_platform_impl.h
index 41f7766ff1e..a70bae628c6 100644
--- a/chromium/content/child/blink_platform_impl.h
+++ b/chromium/content/child/blink_platform_impl.h
@@ -46,15 +46,14 @@ class WebThreadBase;
namespace content {
-class NotificationDispatcher;
-class ThreadSafeSender;
class WebCryptoImpl;
class CONTENT_EXPORT BlinkPlatformImpl : public blink::Platform {
public:
BlinkPlatformImpl();
explicit BlinkPlatformImpl(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner);
~BlinkPlatformImpl() override;
// Platform methods (partial implementation):
@@ -78,8 +77,6 @@ class CONTENT_EXPORT BlinkPlatformImpl : public blink::Platform {
size_t MaxDecodedImageBytes() override;
bool IsLowEndDevice() override;
uint32_t GetUniqueIdForProcess() override;
- std::unique_ptr<blink::WebDataConsumerHandle> CreateDataConsumerHandle(
- mojo::ScopedDataPipeConsumerHandle handle) override;
blink::WebString UserAgent() override;
std::unique_ptr<blink::WebThread> CreateThread(const char* name) override;
std::unique_ptr<blink::WebThread> CreateWebAudioThread() override;
@@ -99,19 +96,15 @@ class CONTENT_EXPORT BlinkPlatformImpl : public blink::Platform {
const blink::WebString& value1,
const blink::WebString& value2) override;
void SuddenTerminationChanged(bool enabled) override {}
- blink::WebThread* CompositorThread() const override;
+ bool IsRendererSideResourceSchedulerEnabled() const final;
std::unique_ptr<blink::WebGestureCurve> CreateFlingAnimationCurve(
blink::WebGestureDevice device_source,
const blink::WebFloatPoint& velocity,
const blink::WebSize& cumulative_scroll) override;
- void DidStartWorkerThread() override;
- void WillStopWorkerThread() override;
bool AllowScriptExtensionForServiceWorker(
const blink::WebURL& script_url) override;
blink::WebCrypto* Crypto() override;
const char* GetBrowserServiceName() const override;
- blink::WebNotificationManager* GetNotificationManager() override;
- blink::WebPushProvider* PushProvider() override;
blink::WebMediaCapabilitiesClient* MediaCapabilitiesClient() override;
blink::WebString DomCodeStringFromEnum(int dom_code) override;
@@ -120,38 +113,22 @@ class CONTENT_EXPORT BlinkPlatformImpl : public blink::Platform {
int DomKeyEnumFromString(const blink::WebString& key_string) override;
bool IsDomKeyForModifier(int dom_key) override;
- // 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);
+ void WaitUntilWebThreadTLSUpdate(blink::scheduler::WebThreadBase* thread);
- std::unique_ptr<blink::WebFeaturePolicy> CreateFeaturePolicy(
- const blink::WebFeaturePolicy* parentPolicy,
- const blink::WebParsedFeaturePolicy& containerPolicy,
- const blink::WebParsedFeaturePolicy& policyHeader,
- const blink::WebSecurityOrigin& origin) override;
- std::unique_ptr<blink::WebFeaturePolicy> DuplicateFeaturePolicyWithOrigin(
- const blink::WebFeaturePolicy& policy,
- const blink::WebSecurityOrigin& new_origin) override;
+ scoped_refptr<base::SingleThreadTaskRunner> GetIOTaskRunner() const override;
private:
- void InternalInit();
- void WaitUntilWebThreadTLSUpdate(blink::scheduler::WebThreadBase* thread);
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_;
WebFallbackThemeEngineImpl fallback_theme_engine_;
base::ThreadLocalStorage::Slot current_thread_slot_;
webcrypto::WebCryptoImpl web_crypto_;
media::WebMediaCapabilitiesClientImpl media_capabilities_client_;
-
- scoped_refptr<ThreadSafeSender> thread_safe_sender_;
- scoped_refptr<NotificationDispatcher> notification_dispatcher_;
-
- blink::scheduler::WebThreadBase* compositor_thread_;
};
} // namespace content
diff --git a/chromium/content/child/blink_platform_impl_unittest.cc b/chromium/content/child/blink_platform_impl_unittest.cc
index ca84ee2ff3f..f8ff8a22525 100644
--- a/chromium/content/child/blink_platform_impl_unittest.cc
+++ b/chromium/content/child/blink_platform_impl_unittest.cc
@@ -121,7 +121,7 @@ TEST(BlinkPlatformTest, CastWebSecurityOrigin) {
EXPECT_EQ(test.port, url_origin.port());
EXPECT_EQ(test.suborigin, url_origin.suborigin());
- web_origin = url::Origin(GURL(test.url));
+ web_origin = url::Origin::Create(GURL(test.url));
EXPECT_EQ(test.scheme, web_origin.Protocol().Utf8());
EXPECT_EQ(test.host, web_origin.Host().Utf8());
EXPECT_EQ(test.port, web_origin.EffectivePort());
@@ -140,7 +140,7 @@ TEST(BlinkPlatformTest, CastWebSecurityOrigin) {
EXPECT_TRUE(url_origin.unique());
EXPECT_EQ("", url_origin.suborigin());
- web_origin = url::Origin(GURL(""));
+ web_origin = url::Origin::Create(GURL(""));
EXPECT_TRUE(web_origin.IsUnique());
}
}
diff --git a/chromium/content/child/browser_font_resource_trusted.cc b/chromium/content/child/browser_font_resource_trusted.cc
index 7fd605bce36..64f59f578cb 100644
--- a/chromium/content/child/browser_font_resource_trusted.cc
+++ b/chromium/content/child/browser_font_resource_trusted.cc
@@ -62,8 +62,7 @@ base::string16 GetFontFromMap(const ScriptFontFamilyMap& map,
class TextRunCollection {
public:
explicit TextRunCollection(const PP_BrowserFont_Trusted_TextRun& run)
- : bidi_(NULL),
- num_runs_(0) {
+ : bidi_(nullptr), num_runs_(0) {
StringVar* text_string = StringVar::FromPPVar(run.text);
if (!text_string)
return; // Leave num_runs_ = 0 so we'll do nothing.
@@ -77,7 +76,8 @@ class TextRunCollection {
} else {
bidi_ = ubidi_open();
UErrorCode uerror = U_ZERO_ERROR;
- ubidi_setPara(bidi_, text_.data(), text_.size(), run.rtl, NULL, &uerror);
+ ubidi_setPara(bidi_, text_.data(), text_.size(), run.rtl, nullptr,
+ &uerror);
if (U_SUCCESS(uerror))
num_runs_ = ubidi_countRuns(bidi_, &uerror);
}
diff --git a/chromium/content/child/child_histogram_fetcher_impl.cc b/chromium/content/child/child_histogram_fetcher_impl.cc
index 31a6b2e9aa9..36dbd27bb6f 100644
--- a/chromium/content/child/child_histogram_fetcher_impl.cc
+++ b/chromium/content/child/child_histogram_fetcher_impl.cc
@@ -13,7 +13,6 @@
#include "base/metrics/persistent_histogram_allocator.h"
#include "base/single_thread_task_runner.h"
#include "content/child/child_process.h"
-#include "content/common/child_process_messages.h"
#include "ipc/ipc_sender.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/platform_handle.h"
@@ -26,7 +25,7 @@ ChildHistogramFetcherFactoryImpl::~ChildHistogramFetcherFactoryImpl() {}
void ChildHistogramFetcherFactoryImpl::Create(
content::mojom::ChildHistogramFetcherFactoryRequest request) {
- mojo::MakeStrongBinding(base::MakeUnique<ChildHistogramFetcherFactoryImpl>(),
+ mojo::MakeStrongBinding(std::make_unique<ChildHistogramFetcherFactoryImpl>(),
std::move(request));
}
@@ -51,7 +50,7 @@ void ChildHistogramFetcherFactoryImpl::CreateFetcher(
global_allocator->CreateTrackingHistograms(global_allocator->Name());
content::mojom::ChildHistogramFetcherPtr child_histogram_interface;
- mojo::MakeStrongBinding(base::MakeUnique<ChildHistogramFetcherImpl>(),
+ mojo::MakeStrongBinding(std::make_unique<ChildHistogramFetcherImpl>(),
std::move(request));
}
diff --git a/chromium/content/child/child_process.cc b/chromium/content/child/child_process.cc
index b28d6e878dc..9ab78bd0cfa 100644
--- a/chromium/content/child/child_process.cc
+++ b/chromium/content/child/child_process.cc
@@ -85,7 +85,7 @@ ChildProcess::~ChildProcess() {
}
}
- g_lazy_tls.Pointer()->Set(NULL);
+ g_lazy_tls.Pointer()->Set(nullptr);
io_thread_.Stop();
if (initialized_task_scheduler_) {
@@ -119,13 +119,6 @@ void ChildProcess::ReleaseProcess() {
main_thread_->OnProcessFinalRelease();
}
-#if defined(OS_LINUX)
-void ChildProcess::SetIOThreadPriority(
- base::ThreadPriority io_thread_priority) {
- main_thread_->SetThreadPriority(io_thread_.GetThreadId(), io_thread_priority);
-}
-#endif
-
ChildProcess* ChildProcess::current() {
return g_lazy_tls.Pointer()->Get();
}
diff --git a/chromium/content/child/child_process.h b/chromium/content/child/child_process.h
index 7b1426b2c6d..e80c6555e1e 100644
--- a/chromium/content/child/child_process.h
+++ b/chromium/content/child/child_process.h
@@ -58,6 +58,7 @@ class CONTENT_EXPORT ChildProcess {
base::SingleThreadTaskRunner* io_task_runner() {
return io_thread_.task_runner().get();
}
+ base::PlatformThreadId io_thread_id() { return io_thread_.GetThreadId(); }
// A global event object that is signalled when the main thread's message
// loop exits. This gives background threads a way to observe the main
@@ -79,10 +80,6 @@ class CONTENT_EXPORT ChildProcess {
void AddRefProcess();
void ReleaseProcess();
-#if defined(OS_LINUX)
- void SetIOThreadPriority(base::ThreadPriority io_thread_priority);
-#endif
-
// Getter for the one ChildProcess object for this process. Can only be called
// on the main thread.
static ChildProcess* current();
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 61f3b532307..533471928ae 100644
--- a/chromium/content/child/child_process_sandbox_support_impl_linux.cc
+++ b/chromium/content/child/child_process_sandbox_support_impl_linux.cc
@@ -15,7 +15,8 @@
#include "base/posix/unix_domain_socket.h"
#include "base/sys_byteorder.h"
#include "base/trace_event/trace_event.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
+#include "content/public/common/common_sandbox_support_linux.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/platform/linux/WebFallbackFont.h"
@@ -29,13 +30,14 @@ void GetFallbackFontForCharacter(int32_t character,
TRACE_EVENT0("sandbox_ipc", "GetFontFamilyForCharacter");
base::Pickle request;
- request.WriteInt(LinuxSandbox::METHOD_GET_FALLBACK_FONT_FOR_CHAR);
+ request.WriteInt(
+ service_manager::SandboxLinux::METHOD_GET_FALLBACK_FONT_FOR_CHAR);
request.WriteInt(character);
request.WriteString(preferred_locale);
uint8_t buf[512];
const ssize_t n = base::UnixDomainSocket::SendRecvMsg(
- GetSandboxFD(), buf, sizeof(buf), NULL, request);
+ GetSandboxFD(), buf, sizeof(buf), nullptr, request);
std::string family_name;
std::string filename;
@@ -78,7 +80,7 @@ void GetRenderStyleForStrike(const char* family,
return;
base::Pickle request;
- request.WriteInt(LinuxSandbox::METHOD_GET_STYLE_FOR_STRIKE);
+ request.WriteInt(service_manager::SandboxLinux::METHOD_GET_STYLE_FOR_STRIKE);
request.WriteString(family);
request.WriteBool(bold);
request.WriteBool(italic);
@@ -86,7 +88,7 @@ void GetRenderStyleForStrike(const char* family,
uint8_t buf[512];
const ssize_t n = base::UnixDomainSocket::SendRecvMsg(
- GetSandboxFD(), buf, sizeof(buf), NULL, request);
+ GetSandboxFD(), buf, sizeof(buf), nullptr, request);
if (n == -1)
return;
@@ -117,7 +119,7 @@ int MatchFontWithFallback(const std::string& face,
TRACE_EVENT0("sandbox_ipc", "MatchFontWithFallback");
base::Pickle request;
- request.WriteInt(LinuxSandbox::METHOD_MATCH_WITH_FALLBACK);
+ request.WriteInt(service_manager::SandboxLinux::METHOD_MATCH_WITH_FALLBACK);
request.WriteString(face);
request.WriteBool(bold);
request.WriteBool(italic);
diff --git a/chromium/content/child/child_thread_impl.cc b/chromium/content/child/child_thread_impl.cc
index 9bf12f83c10..f8ca6067850 100644
--- a/chromium/content/child/child_thread_impl.cc
+++ b/chromium/content/child/child_thread_impl.cc
@@ -38,16 +38,7 @@
#include "components/tracing/child/child_trace_message_filter.h"
#include "content/child/child_histogram_fetcher_impl.h"
#include "content/child/child_process.h"
-#include "content/child/child_resource_message_filter.h"
-#include "content/child/fileapi/file_system_dispatcher.h"
-#include "content/child/fileapi/webfilesystem_impl.h"
-#include "content/child/notifications/notification_dispatcher.h"
-#include "content/child/quota_dispatcher.h"
-#include "content/child/quota_message_filter.h"
-#include "content/child/resource_dispatcher.h"
-#include "content/child/service_worker/service_worker_message_filter.h"
#include "content/child/thread_safe_sender.h"
-#include "content/common/child_process_messages.h"
#include "content/common/field_trial_recorder.mojom.h"
#include "content/common/in_process_child_thread_params.h"
#include "content/public/common/connection_filter.h"
@@ -76,6 +67,7 @@
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "services/service_manager/runner/common/client_util.h"
+#include "services/service_manager/sandbox/sandbox_type.h"
#if defined(OS_POSIX)
#include "base/posix/global_descriptors.h"
@@ -348,6 +340,13 @@ ChildThreadImpl::Options::Builder::AddStartupFilter(
return *this;
}
+ChildThreadImpl::Options::Builder&
+ChildThreadImpl::Options::Builder::IPCTaskRunner(
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner) {
+ options_.ipc_task_runner = ipc_task_runner;
+ return *this;
+}
+
ChildThreadImpl::Options ChildThreadImpl::Options::Builder::Build() {
return options_;
}
@@ -388,6 +387,7 @@ ChildThreadImpl::ChildThreadImpl(const Options& options)
browser_process_io_runner_(options.browser_process_io_runner),
channel_connected_factory_(
new base::WeakPtrFactory<ChildThreadImpl>(this)),
+ ipc_task_runner_(options.ipc_task_runner),
weak_factory_(this) {
Init(options);
}
@@ -420,11 +420,13 @@ void ChildThreadImpl::ConnectChannel(
mojo::ScopedMessagePipeHandle handle =
mojo::MakeRequest(&bootstrap).PassMessagePipe();
service_manager_connection_->AddConnectionFilter(
- base::MakeUnique<ChannelBootstrapFilter>(bootstrap.PassInterface()));
+ std::make_unique<ChannelBootstrapFilter>(bootstrap.PassInterface()));
channel_->Init(
IPC::ChannelMojo::CreateClientFactory(
- std::move(handle), ChildProcess::current()->io_task_runner()),
+ std::move(handle), ChildProcess::current()->io_task_runner(),
+ ipc_task_runner_ ? ipc_task_runner_
+ : base::ThreadTaskRunnerHandle::Get()),
true /* create_pipe_now */);
}
@@ -439,9 +441,10 @@ void ChildThreadImpl::Init(const Options& options) {
IPC::Logging::GetInstance();
#endif
- channel_ =
- IPC::SyncChannel::Create(this, ChildProcess::current()->io_task_runner(),
- ChildProcess::current()->GetShutDownEvent());
+ channel_ = IPC::SyncChannel::Create(
+ this, ChildProcess::current()->io_task_runner(),
+ ipc_task_runner_ ? ipc_task_runner_ : base::ThreadTaskRunnerHandle::Get(),
+ ChildProcess::current()->GetShutDownEvent());
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
if (!IsInBrowserProcess())
IPC::Logging::GetInstance()->SetIPCSender(this);
@@ -477,43 +480,20 @@ void ChildThreadImpl::Init(const Options& options) {
thread_safe_sender_ = new ThreadSafeSender(
message_loop_->task_runner(), sync_message_filter_.get());
- resource_dispatcher_.reset(new ResourceDispatcher(
- this, message_loop()->task_runner()));
- file_system_dispatcher_.reset(new FileSystemDispatcher());
-
- resource_message_filter_ =
- new ChildResourceMessageFilter(resource_dispatcher());
-
- auto registry = base::MakeUnique<service_manager::BinderRegistry>();
+ auto registry = std::make_unique<service_manager::BinderRegistry>();
registry->AddInterface(base::Bind(&ChildHistogramFetcherFactoryImpl::Create),
GetIOTaskRunner());
+ registry->AddInterface(base::Bind(&ChildThreadImpl::OnChildControlRequest,
+ base::Unretained(this)),
+ base::ThreadTaskRunnerHandle::Get());
GetServiceManagerConnection()->AddConnectionFilter(
- base::MakeUnique<SimpleConnectionFilter>(std::move(registry)));
-
- service_worker_message_filter_ =
- new ServiceWorkerMessageFilter(thread_safe_sender_.get());
-
- quota_message_filter_ =
- new QuotaMessageFilter(thread_safe_sender_.get());
- quota_dispatcher_.reset(new QuotaDispatcher(thread_safe_sender_.get(),
- quota_message_filter_.get()));
- notification_dispatcher_ =
- new NotificationDispatcher(thread_safe_sender_.get());
+ std::make_unique<SimpleConnectionFilter>(std::move(registry)));
- channel_->AddFilter(resource_message_filter_.get());
- channel_->AddFilter(quota_message_filter_->GetFilter());
- channel_->AddFilter(notification_dispatcher_->GetFilter());
- channel_->AddFilter(service_worker_message_filter_->GetFilter());
+ InitTracing();
+ // In single process mode, browser-side tracing and memory will cover the
+ // whole process including renderers.
if (!IsInBrowserProcess()) {
- // In single process mode, browser-side tracing and memory will cover the
- // whole process including renderers.
- channel_->AddFilter(new tracing::ChildTraceMessageFilter(
- ChildProcess::current()->io_task_runner()));
-
- chrome_trace_event_agent_ =
- base::MakeUnique<tracing::ChromeTraceEventAgent>(GetConnector());
-
if (service_manager_connection_) {
std::string process_type_str =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
@@ -540,7 +520,7 @@ void ChildThreadImpl::Init(const Options& options) {
// not create the power monitor.
if (!base::PowerMonitor::Get() && service_manager_connection_) {
auto power_monitor_source =
- base::MakeUnique<device::PowerMonitorBroadcastSource>(
+ std::make_unique<device::PowerMonitorBroadcastSource>(
GetConnector(), GetIOTaskRunner());
power_monitor_.reset(
new base::PowerMonitor(std::move(power_monitor_source)));
@@ -609,6 +589,28 @@ void ChildThreadImpl::Init(const Options& options) {
#endif
}
+void ChildThreadImpl::InitTracing() {
+ // In single process mode, browser-side tracing and memory will cover the
+ // whole process including renderers.
+ if (IsInBrowserProcess())
+ return;
+
+ // Tracing adds too much overhead to the profiling service. The only
+ // way to determine if this is the profiling service is by checking the
+ // sandbox type.
+ service_manager::SandboxType sandbox_type =
+ service_manager::SandboxTypeFromCommandLine(
+ *base::CommandLine::ForCurrentProcess());
+ if (sandbox_type == service_manager::SANDBOX_TYPE_PROFILING)
+ return;
+
+ channel_->AddFilter(new tracing::ChildTraceMessageFilter(
+ ChildProcess::current()->io_task_runner()));
+
+ chrome_trace_event_agent_ =
+ std::make_unique<tracing::ChromeTraceEventAgent>(GetConnector());
+}
+
ChildThreadImpl::~ChildThreadImpl() {
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
IPC::Logging::GetInstance()->SetIPCSender(NULL);
@@ -625,15 +627,12 @@ 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(NULL);
+ g_lazy_tls.Pointer()->Set(nullptr);
}
void ChildThreadImpl::Shutdown() {
// Delete objects that hold references to blink so derived classes can
// safely shutdown blink in their Shutdown implementation.
- file_system_dispatcher_.reset();
- quota_dispatcher_.reset();
- WebFileSystemImpl::DeleteThreadSpecificInstance();
}
bool ChildThreadImpl::ShouldBeDestroyed() {
@@ -664,11 +663,19 @@ bool ChildThreadImpl::Send(IPC::Message* msg) {
#if defined(OS_WIN)
void ChildThreadImpl::PreCacheFont(const LOGFONT& log_font) {
- Send(new ChildProcessHostMsg_PreCacheFont(log_font));
+ GetFontCacheWin()->PreCacheFont(log_font);
}
void ChildThreadImpl::ReleaseCachedFonts() {
- Send(new ChildProcessHostMsg_ReleaseCachedFonts());
+ GetFontCacheWin()->ReleaseCachedFonts();
+}
+
+mojom::FontCacheWin* ChildThreadImpl::GetFontCacheWin() {
+ if (!font_cache_win_ptr_) {
+ GetConnector()->BindInterface(mojom::kBrowserServiceName,
+ &font_cache_win_ptr_);
+ }
+ return font_cache_win_ptr_.get();
}
#endif
@@ -718,41 +725,10 @@ std::unique_ptr<base::SharedMemory> ChildThreadImpl::AllocateSharedMemory(
return nullptr;
}
- return base::MakeUnique<base::SharedMemory>(shared_buf, false);
-}
-
-#if defined(OS_LINUX)
-void ChildThreadImpl::SetThreadPriority(base::PlatformThreadId id,
- base::ThreadPriority priority) {
- Send(new ChildProcessHostMsg_SetThreadPriority(id, priority));
+ return std::make_unique<base::SharedMemory>(shared_buf, false);
}
-#endif
bool ChildThreadImpl::OnMessageReceived(const IPC::Message& msg) {
- // Resource responses are sent to the resource dispatcher.
- if (resource_dispatcher_->OnMessageReceived(msg))
- return true;
- if (file_system_dispatcher_->OnMessageReceived(msg))
- return true;
-
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(ChildThreadImpl, msg)
- IPC_MESSAGE_HANDLER(ChildProcessMsg_Shutdown, OnShutdown)
-#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
- IPC_MESSAGE_HANDLER(ChildProcessMsg_SetIPCLoggingEnabled,
- OnSetIPCLoggingEnabled)
-#endif
- IPC_MESSAGE_HANDLER(ChildProcessMsg_SetProcessBackgrounded,
- OnProcessBackgrounded)
- IPC_MESSAGE_HANDLER(ChildProcessMsg_PurgeAndSuspend,
- OnProcessPurgeAndSuspend)
- IPC_MESSAGE_HANDLER(ChildProcessMsg_Resume, OnProcessResume)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- if (handled)
- return true;
-
if (msg.routing_id() == MSG_ROUTING_CONTROL)
return OnControlMessageReceived(msg);
@@ -783,31 +759,23 @@ bool ChildThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
return false;
}
-void ChildThreadImpl::OnProcessBackgrounded(bool backgrounded) {
- // Set timer slack to maximum on main thread when in background.
- base::TimerSlack timer_slack = base::TIMER_SLACK_NONE;
- if (backgrounded)
- timer_slack = base::TIMER_SLACK_MAXIMUM;
- base::MessageLoop::current()->SetTimerSlack(timer_slack);
-}
-
-void ChildThreadImpl::OnProcessPurgeAndSuspend() {
-}
-
-void ChildThreadImpl::OnProcessResume() {}
-
-void ChildThreadImpl::OnShutdown() {
+void ChildThreadImpl::ProcessShutdown() {
base::RunLoop::QuitCurrentWhenIdleDeprecated();
}
+void ChildThreadImpl::SetIPCLoggingEnabled(bool enable) {
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
-void ChildThreadImpl::OnSetIPCLoggingEnabled(bool enable) {
if (enable)
IPC::Logging::GetInstance()->Enable();
else
IPC::Logging::GetInstance()->Disable();
-}
#endif // IPC_MESSAGE_LOG_ENABLED
+}
+
+void ChildThreadImpl::OnChildControlRequest(
+ mojom::ChildControlRequest request) {
+ child_control_bindings_.AddBinding(this, std::move(request));
+}
ChildThreadImpl* ChildThreadImpl::current() {
return g_lazy_tls.Pointer()->Get();
@@ -827,13 +795,7 @@ void ChildThreadImpl::OnProcessFinalRelease() {
if (on_channel_error_called_)
return;
- // The child process shutdown sequence is a request response based mechanism,
- // where we send out an initial feeler request to the child process host
- // instance in the browser to verify if it's ok to shutdown the child process.
- // The browser then sends back a response if it's ok to shutdown. This avoids
- // race conditions if the process refcount is 0 but there's an IPC message
- // inflight that would addref it.
- Send(new ChildProcessHostMsg_ShutdownRequest);
+ ProcessShutdown();
}
void ChildThreadImpl::EnsureConnected() {
diff --git a/chromium/content/child/child_thread_impl.h b/chromium/content/child/child_thread_impl.h
index 4f534117381..54bf2504c07 100644
--- a/chromium/content/child/child_thread_impl.h
+++ b/chromium/content/child/child_thread_impl.h
@@ -20,6 +20,7 @@
#include "build/build_config.h"
#include "components/variations/child_process_field_trial_syncer.h"
#include "content/common/associated_interfaces.mojom.h"
+#include "content/common/child_control.mojom.h"
#include "content/common/content_export.h"
#include "content/public/child/child_thread.h"
#include "ipc/ipc.mojom.h"
@@ -30,6 +31,10 @@
#include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "services/resource_coordinator/public/cpp/tracing/chrome_trace_event_agent.h"
+#if defined(OS_WIN)
+#include "content/common/font_cache_win.mojom.h"
+#endif
+
namespace base {
class MessageLoop;
} // namespace base
@@ -49,14 +54,7 @@ class ScopedIPCSupport;
} // namespace mojo
namespace content {
-class ChildResourceMessageFilter;
-class FileSystemDispatcher;
class InProcessChildThreadParams;
-class NotificationDispatcher;
-class ServiceWorkerMessageFilter;
-class QuotaDispatcher;
-class QuotaMessageFilter;
-class ResourceDispatcher;
class ThreadSafeSender;
// The main thread of a child process derives from this class.
@@ -65,7 +63,8 @@ class CONTENT_EXPORT ChildThreadImpl
virtual public ChildThread,
private base::FieldTrialList::Observer,
public mojom::RouteProvider,
- public mojom::AssociatedInterfaceProvider {
+ public mojom::AssociatedInterfaceProvider,
+ public mojom::ChildControl {
public:
struct CONTENT_EXPORT Options;
@@ -115,27 +114,6 @@ class CONTENT_EXPORT ChildThreadImpl
static std::unique_ptr<base::SharedMemory> AllocateSharedMemory(
size_t buf_size);
-#if defined(OS_LINUX)
- void SetThreadPriority(base::PlatformThreadId id,
- base::ThreadPriority priority);
-#endif
-
- ResourceDispatcher* resource_dispatcher() const {
- return resource_dispatcher_.get();
- }
-
- FileSystemDispatcher* file_system_dispatcher() const {
- return file_system_dispatcher_.get();
- }
-
- QuotaDispatcher* quota_dispatcher() const {
- return quota_dispatcher_.get();
- }
-
- NotificationDispatcher* notification_dispatcher() const {
- return notification_dispatcher_.get();
- }
-
IPC::SyncMessageFilter* sync_message_filter() const {
return sync_message_filter_.get();
}
@@ -147,18 +125,6 @@ class CONTENT_EXPORT ChildThreadImpl
return thread_safe_sender_.get();
}
- ServiceWorkerMessageFilter* service_worker_message_filter() const {
- return service_worker_message_filter_.get();
- }
-
- QuotaMessageFilter* quota_message_filter() const {
- return quota_message_filter_.get();
- }
-
- ChildResourceMessageFilter* child_resource_message_filter() const {
- return resource_message_filter_.get();
- }
-
base::MessageLoop* message_loop() const { return message_loop_; }
// Returns the one child thread. Can only be called on the main thread.
@@ -174,7 +140,7 @@ class CONTENT_EXPORT ChildThreadImpl
friend class ChildProcess;
// Called when the process refcount is 0.
- void OnProcessFinalRelease();
+ virtual void OnProcessFinalRelease();
// Called by subclasses to manually start the ServiceManagerConnection. Must
// only be called if
@@ -182,11 +148,12 @@ class CONTENT_EXPORT ChildThreadImpl
// |false| on ChildThreadImpl construction.
void StartServiceManagerConnection();
- virtual bool OnControlMessageReceived(const IPC::Message& msg);
- virtual void OnProcessBackgrounded(bool backgrounded);
- virtual void OnProcessPurgeAndSuspend();
- virtual void OnProcessResume();
+ // mojom::ChildControl
+ void ProcessShutdown() override;
+ void SetIPCLoggingEnabled(bool enable) override;
+ void OnChildControlRequest(mojom::ChildControlRequest);
+ virtual bool OnControlMessageReceived(const IPC::Message& msg);
// IPC::Listener implementation:
bool OnMessageReceived(const IPC::Message& msg) override;
void OnAssociatedInterfaceRequest(
@@ -194,6 +161,7 @@ class CONTENT_EXPORT ChildThreadImpl
mojo::ScopedInterfaceEndpointHandle handle) override;
void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
+ bool on_channel_error_called() const { return on_channel_error_called_; }
bool IsInBrowserProcess() const;
@@ -213,15 +181,14 @@ class CONTENT_EXPORT ChildThreadImpl
void Init(const Options& options);
+ // Sets chrome_trace_event_agent_ if necessary.
+ void InitTracing();
+
// We create the channel first without connecting it so we can add filters
// prior to any messages being received, then connect it afterwards.
void ConnectChannel(mojo::edk::IncomingBrokerClientInvitation* invitation);
// IPC message handlers.
- void OnShutdown();
-#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
- void OnSetIPCLoggingEnabled(bool enable);
-#endif
void EnsureConnected();
@@ -235,13 +202,21 @@ class CONTENT_EXPORT ChildThreadImpl
const std::string& name,
mojom::AssociatedInterfaceAssociatedRequest request) override;
+#if defined(OS_WIN)
+ mojom::FontCacheWin* GetFontCacheWin();
+#endif
+
std::unique_ptr<mojo::edk::ScopedIPCSupport> mojo_ipc_support_;
std::unique_ptr<ServiceManagerConnection> service_manager_connection_;
+ mojo::BindingSet<mojom::ChildControl> child_control_bindings_;
mojo::AssociatedBinding<mojom::RouteProvider> route_provider_binding_;
mojo::AssociatedBindingSet<mojom::AssociatedInterfaceProvider, int32_t>
associated_interface_provider_bindings_;
mojom::RouteProviderAssociatedPtr remote_route_provider_;
+#if defined(OS_WIN)
+ mojom::FontCacheWinPtr font_cache_win_ptr_;
+#endif
std::unique_ptr<IPC::SyncChannel> channel_;
@@ -254,27 +229,12 @@ class CONTENT_EXPORT ChildThreadImpl
// ChildThreadImpl.
ChildThreadMessageRouter router_;
- // Handles resource loads for this process.
- std::unique_ptr<ResourceDispatcher> resource_dispatcher_;
-
// The OnChannelError() callback was invoked - the channel is dead, don't
// attempt to communicate.
bool on_channel_error_called_;
base::MessageLoop* message_loop_;
- std::unique_ptr<FileSystemDispatcher> file_system_dispatcher_;
-
- std::unique_ptr<QuotaDispatcher> quota_dispatcher_;
-
- scoped_refptr<ChildResourceMessageFilter> resource_message_filter_;
-
- scoped_refptr<ServiceWorkerMessageFilter> service_worker_message_filter_;
-
- scoped_refptr<QuotaMessageFilter> quota_message_filter_;
-
- scoped_refptr<NotificationDispatcher> notification_dispatcher_;
-
std::unique_ptr<base::PowerMonitor> power_monitor_;
scoped_refptr<base::SingleThreadTaskRunner> browser_process_io_runner_;
@@ -286,6 +246,8 @@ class CONTENT_EXPORT ChildThreadImpl
std::unique_ptr<base::WeakPtrFactory<ChildThreadImpl>>
channel_connected_factory_;
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
+
base::WeakPtrFactory<ChildThreadImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ChildThreadImpl);
@@ -303,6 +265,7 @@ struct ChildThreadImpl::Options {
std::vector<IPC::MessageFilter*> startup_filters;
mojo::edk::OutgoingBrokerClientInvitation* broker_client_invitation;
std::string in_process_service_request_token;
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner;
private:
Options();
@@ -316,6 +279,8 @@ class ChildThreadImpl::Options::Builder {
Builder& AutoStartServiceManagerConnection(bool auto_start);
Builder& ConnectToBrowser(bool connect_to_browser);
Builder& AddStartupFilter(IPC::MessageFilter* filter);
+ Builder& IPCTaskRunner(
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner);
Options Build();
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 741bd3646c7..123353a1e62 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
@@ -66,15 +66,14 @@ void InitializeDWriteFontProxy() {
sender = ChildThreadImpl::current()->thread_safe_sender();
if (!g_font_collection) {
- mswr::MakeAndInitialize<DWriteFontCollectionProxy>(&g_font_collection,
- factory.Get(), sender);
+ DWriteFontCollectionProxy::Create(&g_font_collection, factory.Get(),
+ sender);
}
mswr::ComPtr<IDWriteFactory2> factory2;
if (SUCCEEDED(factory.As(&factory2)) && factory2.Get()) {
- mswr::MakeAndInitialize<FontFallback>(&g_font_fallback,
- g_font_collection.Get(), sender);
+ FontFallback::Create(&g_font_fallback, g_font_collection.Get(), sender);
}
sk_sp<SkFontMgr> skia_font_manager = SkFontMgr_New_DirectWrite(
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 15dded63ec3..f23b7e20dd1 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
@@ -75,6 +75,13 @@ void LogFontProxyError(FontProxyError error) {
} // namespace
+HRESULT DWriteFontCollectionProxy::Create(DWriteFontCollectionProxy** proxy_out,
+ IDWriteFactory* dwrite_factory,
+ IPC::Sender* sender) {
+ return Microsoft::WRL::MakeAndInitialize<DWriteFontCollectionProxy>(
+ proxy_out, dwrite_factory, sender);
+}
+
DWriteFontCollectionProxy::DWriteFontCollectionProxy() = default;
DWriteFontCollectionProxy::~DWriteFontCollectionProxy() = default;
diff --git a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h
index 2346e5e1ecd..3d01477dca7 100644
--- a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h
+++ b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h
@@ -30,13 +30,21 @@ class DWriteFontFamilyProxy;
// into a custom font collection.
// This is needed because the sandbox interferes with DirectWrite's
// communication with the system font service.
-class CONTENT_EXPORT DWriteFontCollectionProxy
+class DWriteFontCollectionProxy
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
IDWriteFontCollection,
IDWriteFontCollectionLoader,
IDWriteFontFileLoader> {
public:
+ // Factory method to avoid exporting the class and all it derives from.
+ static CONTENT_EXPORT HRESULT Create(DWriteFontCollectionProxy** proxy_out,
+ IDWriteFactory* dwrite_factory,
+ IPC::Sender* sender);
+
+ // Use Create() to construct these objects. Direct calls to the constructor
+ // are an error - it is only public because a WRL helper function creates the
+ // objects.
DWriteFontCollectionProxy();
~DWriteFontCollectionProxy() override;
@@ -63,10 +71,10 @@ class CONTENT_EXPORT DWriteFontCollectionProxy
UINT32 font_file_reference_key_size,
IDWriteFontFileStream** font_file_stream) override;
- HRESULT STDMETHODCALLTYPE
+ CONTENT_EXPORT HRESULT STDMETHODCALLTYPE
RuntimeClassInitialize(IDWriteFactory* factory, IPC::Sender* sender_override);
- void Unregister();
+ CONTENT_EXPORT void Unregister();
bool LoadFamily(UINT32 family_index,
IDWriteFontCollection** containing_collection);
@@ -99,7 +107,7 @@ class CONTENT_EXPORT DWriteFontCollectionProxy
// stub, until something calls a method that requires actual font data. At that
// point this will load the font files into a custom collection and
// subsequently calls will be proxied to the resulting DirectWrite object.
-class CONTENT_EXPORT DWriteFontFamilyProxy
+class DWriteFontFamilyProxy
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
IDWriteFontFamily> {
@@ -151,7 +159,7 @@ class CONTENT_EXPORT DWriteFontFamilyProxy
// Implements the DirectWrite font file enumerator interface, backed by a list
// of font files.
-class CONTENT_EXPORT FontFileEnumerator
+class FontFileEnumerator
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
IDWriteFontFileEnumerator> {
@@ -181,7 +189,7 @@ class CONTENT_EXPORT FontFileEnumerator
// Implements the DirectWrite font file stream interface that maps the file to
// be loaded as a memory mapped file, and subsequently returns pointers into
// the mapped memory block.
-class CONTENT_EXPORT FontFileStream
+class FontFileStream
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
IDWriteFontFileStream> {
diff --git a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc
index 2fb66bab887..002b68387d7 100644
--- a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc
+++ b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc
@@ -29,8 +29,9 @@ class DWriteFontProxyUnitTest : public testing::Test {
DWriteFontProxyUnitTest() {
fake_collection_ = new FakeFontCollection();
SetupFonts(fake_collection_.get());
- mswr::MakeAndInitialize<DWriteFontCollectionProxy>(
- &collection_, factory.Get(), fake_collection_->GetTrackingSender());
+ DWriteFontCollectionProxy::Create(&collection_, factory.Get(),
+ fake_collection_->GetTrackingSender());
+ EXPECT_TRUE(collection_.Get());
}
~DWriteFontProxyUnitTest() override {
@@ -343,8 +344,8 @@ TEST_F(DWriteFontProxyUnitTest, TestCustomFontFiles) {
arial.AddFileHandle(IPC::TakePlatformFileForTransit(std::move(file)));
}
mswr::ComPtr<DWriteFontCollectionProxy> collection;
- mswr::MakeAndInitialize<DWriteFontCollectionProxy>(
- &collection, factory.Get(), fonts->GetTrackingSender());
+ DWriteFontCollectionProxy::Create(&collection, factory.Get(),
+ fonts->GetTrackingSender());
// Check that we can get the font family and match a font.
UINT32 index = UINT_MAX;
diff --git a/chromium/content/child/dwrite_font_proxy/font_fallback_win.cc b/chromium/content/child/dwrite_font_proxy/font_fallback_win.cc
index 4bf78d2804f..d8642401503 100644
--- a/chromium/content/child/dwrite_font_proxy/font_fallback_win.cc
+++ b/chromium/content/child/dwrite_font_proxy/font_fallback_win.cc
@@ -43,6 +43,13 @@ void LogFallbackResult(DirectWriteFontFallbackResult fallback_result) {
} // namespace
+HRESULT FontFallback::Create(FontFallback** font_fallback_out,
+ DWriteFontCollectionProxy* collection,
+ IPC::Sender* sender) {
+ return Microsoft::WRL::MakeAndInitialize<FontFallback>(font_fallback_out,
+ collection, sender);
+}
+
FontFallback::FontFallback() = default;
FontFallback::~FontFallback() = default;
diff --git a/chromium/content/child/dwrite_font_proxy/font_fallback_win.h b/chromium/content/child/dwrite_font_proxy/font_fallback_win.h
index 195941d8d75..3277482420f 100644
--- a/chromium/content/child/dwrite_font_proxy/font_fallback_win.h
+++ b/chromium/content/child/dwrite_font_proxy/font_fallback_win.h
@@ -20,11 +20,19 @@ namespace content {
// Implements an IDWriteFontFallback that uses IPC to proxy the fallback calls
// to the system fallback in the browser process.
-class CONTENT_EXPORT FontFallback
+class FontFallback
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
IDWriteFontFallback> {
public:
+ // Factory method to avoid exporting the class and all it derives from.
+ static CONTENT_EXPORT HRESULT Create(FontFallback** font_fallback_out,
+ DWriteFontCollectionProxy* collection,
+ IPC::Sender* sender);
+
+ // Use Create() to construct these objects. Direct calls to the constructor
+ // are an error - it is only public because a WRL helper function creates the
+ // objects.
FontFallback();
HRESULT STDMETHODCALLTYPE
diff --git a/chromium/content/child/dwrite_font_proxy/font_fallback_win_unittest.cc b/chromium/content/child/dwrite_font_proxy/font_fallback_win_unittest.cc
index 7bc539bc073..64b54ff6b77 100644
--- a/chromium/content/child/dwrite_font_proxy/font_fallback_win_unittest.cc
+++ b/chromium/content/child/dwrite_font_proxy/font_fallback_win_unittest.cc
@@ -44,8 +44,8 @@ class FontFallbackUnitTest : public testing::Test {
.AddFamilyName(L"en-us", L"Segoe UI Symbol")
.AddFilePath(segoe_path);
- mswr::MakeAndInitialize<DWriteFontCollectionProxy>(
- &collection_, factory_.Get(), fake_collection_->GetSender());
+ DWriteFontCollectionProxy::Create(&collection_, factory_.Get(),
+ fake_collection_->GetSender());
}
scoped_refptr<FakeFontCollection> fake_collection_;
@@ -56,17 +56,17 @@ class FontFallbackUnitTest : public testing::Test {
TEST_F(FontFallbackUnitTest, MapCharacters) {
mswr::ComPtr<FontFallback> fallback;
- mswr::MakeAndInitialize<FontFallback>(&fallback, collection_.Get(),
- fake_collection_->GetSender());
+ FontFallback::Create(&fallback, collection_.Get(),
+ fake_collection_->GetSender());
mswr::ComPtr<IDWriteFont> font;
UINT32 mapped_length = 0;
float scale = 0.0;
- mswr::ComPtr<gfx::win::TextAnalysisSource> text;
- mswr::MakeAndInitialize<gfx::win::TextAnalysisSource>(
- &text, L"hello", L"en-us", number_substitution_.Get(),
- DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
+ mswr::ComPtr<IDWriteTextAnalysisSource> text;
+ gfx::win::TextAnalysisSource::Create(&text, L"hello", L"en-us",
+ number_substitution_.Get(),
+ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
fallback->MapCharacters(text.Get(), 0, 5, nullptr, nullptr,
DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, &mapped_length, &font,
@@ -78,17 +78,17 @@ TEST_F(FontFallbackUnitTest, MapCharacters) {
TEST_F(FontFallbackUnitTest, DuplicateCallsShouldNotRepeatIPC) {
mswr::ComPtr<FontFallback> fallback;
- mswr::MakeAndInitialize<FontFallback>(&fallback, collection_.Get(),
- fake_collection_->GetTrackingSender());
+ FontFallback::Create(&fallback, collection_.Get(),
+ fake_collection_->GetTrackingSender());
mswr::ComPtr<IDWriteFont> font;
UINT32 mapped_length = 0;
float scale = 0.0;
- mswr::ComPtr<gfx::win::TextAnalysisSource> text;
- mswr::MakeAndInitialize<gfx::win::TextAnalysisSource>(
- &text, L"hello", L"en-us", number_substitution_.Get(),
- DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
+ mswr::ComPtr<IDWriteTextAnalysisSource> text;
+ gfx::win::TextAnalysisSource::Create(&text, L"hello", L"en-us",
+ number_substitution_.Get(),
+ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
fallback->MapCharacters(text.Get(), 0, 5, nullptr, nullptr,
DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, &mapped_length, &font,
@@ -105,17 +105,17 @@ TEST_F(FontFallbackUnitTest, DuplicateCallsShouldNotRepeatIPC) {
TEST_F(FontFallbackUnitTest, DifferentFamilyShouldNotReuseCache) {
mswr::ComPtr<FontFallback> fallback;
- mswr::MakeAndInitialize<FontFallback>(&fallback, collection_.Get(),
- fake_collection_->GetTrackingSender());
+ FontFallback::Create(&fallback, collection_.Get(),
+ fake_collection_->GetTrackingSender());
mswr::ComPtr<IDWriteFont> font;
UINT32 mapped_length = 0;
float scale = 0.0;
- mswr::ComPtr<gfx::win::TextAnalysisSource> text;
- mswr::MakeAndInitialize<gfx::win::TextAnalysisSource>(
- &text, L"hello", L"en-us", number_substitution_.Get(),
- DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
+ mswr::ComPtr<IDWriteTextAnalysisSource> text;
+ gfx::win::TextAnalysisSource::Create(&text, L"hello", L"en-us",
+ number_substitution_.Get(),
+ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
fallback->MapCharacters(text.Get(), 0, 5, nullptr, L"font1",
DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, &mapped_length, &font,
@@ -130,21 +130,21 @@ TEST_F(FontFallbackUnitTest, DifferentFamilyShouldNotReuseCache) {
TEST_F(FontFallbackUnitTest, CacheMissShouldRepeatIPC) {
mswr::ComPtr<FontFallback> fallback;
- mswr::MakeAndInitialize<FontFallback>(&fallback, collection_.Get(),
- fake_collection_->GetTrackingSender());
+ FontFallback::Create(&fallback, collection_.Get(),
+ fake_collection_->GetTrackingSender());
mswr::ComPtr<IDWriteFont> font;
UINT32 mapped_length = 0;
float scale = 0.0;
- mswr::ComPtr<gfx::win::TextAnalysisSource> text;
- mswr::MakeAndInitialize<gfx::win::TextAnalysisSource>(
- &text, L"hello", L"en-us", number_substitution_.Get(),
- DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
- mswr::ComPtr<gfx::win::TextAnalysisSource> unmappable_text;
- mswr::MakeAndInitialize<gfx::win::TextAnalysisSource>(
- &unmappable_text, L"\uffff", L"en-us", number_substitution_.Get(),
- DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
+ mswr::ComPtr<IDWriteTextAnalysisSource> text;
+ gfx::win::TextAnalysisSource::Create(&text, L"hello", L"en-us",
+ number_substitution_.Get(),
+ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
+ mswr::ComPtr<IDWriteTextAnalysisSource> unmappable_text;
+ gfx::win::TextAnalysisSource::Create(&unmappable_text, L"\uffff", L"en-us",
+ number_substitution_.Get(),
+ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
fallback->MapCharacters(text.Get(), 0, 5, nullptr, nullptr,
DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, &mapped_length, &font,
@@ -159,21 +159,21 @@ TEST_F(FontFallbackUnitTest, CacheMissShouldRepeatIPC) {
TEST_F(FontFallbackUnitTest, SurrogatePairCacheHit) {
mswr::ComPtr<FontFallback> fallback;
- mswr::MakeAndInitialize<FontFallback>(&fallback, collection_.Get(),
- fake_collection_->GetTrackingSender());
+ FontFallback::Create(&fallback, collection_.Get(),
+ fake_collection_->GetTrackingSender());
mswr::ComPtr<IDWriteFont> font;
UINT32 mapped_length = 0;
float scale = 0.0;
- mswr::ComPtr<gfx::win::TextAnalysisSource> text;
- mswr::MakeAndInitialize<gfx::win::TextAnalysisSource>(
- &text, L"hello", L"en-us", number_substitution_.Get(),
- DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
- mswr::ComPtr<gfx::win::TextAnalysisSource> surrogate_pair_text;
- mswr::MakeAndInitialize<gfx::win::TextAnalysisSource>(
- &surrogate_pair_text, L"\U0001d300", L"en-us", number_substitution_.Get(),
- DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
+ mswr::ComPtr<IDWriteTextAnalysisSource> text;
+ gfx::win::TextAnalysisSource::Create(&text, L"hello", L"en-us",
+ number_substitution_.Get(),
+ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
+ mswr::ComPtr<IDWriteTextAnalysisSource> surrogate_pair_text;
+ gfx::win::TextAnalysisSource::Create(&surrogate_pair_text, L"\U0001d300",
+ L"en-us", number_substitution_.Get(),
+ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
fallback->MapCharacters(text.Get(), 0, 5, nullptr, nullptr,
DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, &mapped_length, &font,
diff --git a/chromium/content/child/feature_policy/OWNERS b/chromium/content/child/feature_policy/OWNERS
deleted file mode 100644
index e17e569a80e..00000000000
--- a/chromium/content/child/feature_policy/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file://content/common/feature_policy/OWNERS
diff --git a/chromium/content/child/feature_policy/feature_policy_platform.cc b/chromium/content/child/feature_policy/feature_policy_platform.cc
deleted file mode 100644
index d0a90374d05..00000000000
--- a/chromium/content/child/feature_policy/feature_policy_platform.cc
+++ /dev/null
@@ -1,41 +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/child/feature_policy/feature_policy_platform.h"
-
-namespace content {
-
-ParsedFeaturePolicyHeader FeaturePolicyHeaderFromWeb(
- const blink::WebParsedFeaturePolicy& web_feature_policy_header) {
- ParsedFeaturePolicyHeader result;
- for (const blink::WebParsedFeaturePolicyDeclaration& web_declaration :
- web_feature_policy_header) {
- ParsedFeaturePolicyDeclaration declaration;
- declaration.feature = web_declaration.feature;
- declaration.matches_all_origins = web_declaration.matches_all_origins;
- for (const blink::WebSecurityOrigin& web_origin : web_declaration.origins)
- declaration.origins.push_back(web_origin);
- result.push_back(declaration);
- }
- return result;
-}
-
-blink::WebParsedFeaturePolicy FeaturePolicyHeaderToWeb(
- const ParsedFeaturePolicyHeader& feature_policy_header) {
- std::vector<blink::WebParsedFeaturePolicyDeclaration> result;
- for (const ParsedFeaturePolicyDeclaration& declaration :
- feature_policy_header) {
- blink::WebParsedFeaturePolicyDeclaration web_declaration;
- web_declaration.feature = declaration.feature;
- web_declaration.matches_all_origins = declaration.matches_all_origins;
- std::vector<blink::WebSecurityOrigin> web_origins;
- for (const url::Origin& origin : declaration.origins)
- web_origins.push_back(origin);
- web_declaration.origins = web_origins;
- result.push_back(web_declaration);
- }
- return result;
-}
-
-} // namespace content
diff --git a/chromium/content/child/feature_policy/feature_policy_platform.h b/chromium/content/child/feature_policy/feature_policy_platform.h
deleted file mode 100644
index 7eb36d84e72..00000000000
--- a/chromium/content/child/feature_policy/feature_policy_platform.h
+++ /dev/null
@@ -1,22 +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_CHILD_FEATURE_POLICY_FEATURE_POLICY_PLATFORM_H_
-#define CONTENT_CHILD_FEATURE_POLICY_FEATURE_POLICY_PLATFORM_H_
-
-#include "content/common/feature_policy/feature_policy.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
-
-namespace content {
-
-// Conversions between ParsedFeaturePolicyHeader and
-// WebParsedFeaturePolicy
-ParsedFeaturePolicyHeader FeaturePolicyHeaderFromWeb(
- const blink::WebParsedFeaturePolicy& web_feature_policy_header);
-blink::WebParsedFeaturePolicy FeaturePolicyHeaderToWeb(
- const ParsedFeaturePolicyHeader& feature_policy_header);
-
-} // namespace content
-
-#endif // CONTENT_CHILD_FEATURE_POLICY_FEATURE_POLICY_PLATFORM_H_
diff --git a/chromium/content/child/loader/cors_url_loader.cc b/chromium/content/child/loader/cors_url_loader.cc
deleted file mode 100644
index e661c122cbf..00000000000
--- a/chromium/content/child/loader/cors_url_loader.cc
+++ /dev/null
@@ -1,108 +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/child/loader/cors_url_loader.h"
-
-namespace content {
-
-// TODO(hintzed): At the moment this class simply forwards all calls to the
-// underlying network loader. Part of the effort to move CORS handling out of
-// Blink: http://crbug/736308.
-CORSURLLoader::CORSURLLoader(
- int32_t routing_id,
- int32_t request_id,
- uint32_t options,
- const ResourceRequest& resource_request,
- mojom::URLLoaderClientPtr client,
- const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
- mojom::URLLoaderFactory* network_loader_factory)
- : network_loader_factory_(network_loader_factory),
- network_client_binding_(this),
- forwarding_client_(std::move(client)) {
- DCHECK(network_loader_factory_);
-
- mojom::URLLoaderClientPtr network_client;
- network_client_binding_.Bind(mojo::MakeRequest(&network_client));
- // Binding |this| as an unretained pointer is safe because
- // |network_client_binding_| shares this object's lifetime.
- network_client_binding_.set_connection_error_handler(base::BindOnce(
- &CORSURLLoader::OnUpstreamConnectionError, base::Unretained(this)));
- network_loader_factory_->CreateLoaderAndStart(
- mojo::MakeRequest(&network_loader_), routing_id, request_id, options,
- resource_request, std::move(network_client), traffic_annotation);
-}
-
-CORSURLLoader::~CORSURLLoader() {}
-
-void CORSURLLoader::FollowRedirect() {
- network_loader_->FollowRedirect();
-}
-
-void CORSURLLoader::SetPriority(net::RequestPriority priority,
- int32_t intra_priority_value) {
- network_loader_->SetPriority(priority, intra_priority_value);
-}
-
-void CORSURLLoader::PauseReadingBodyFromNet() {
- network_loader_->PauseReadingBodyFromNet();
-}
-
-void CORSURLLoader::ResumeReadingBodyFromNet() {
- network_loader_->ResumeReadingBodyFromNet();
-}
-
-// mojom::URLLoaderClient for simply proxying network for now:
-void CORSURLLoader::OnReceiveResponse(
- const ResourceResponseHead& response_head,
- const base::Optional<net::SSLInfo>& ssl_info,
- mojom::DownloadedTempFilePtr downloaded_file) {
- forwarding_client_->OnReceiveResponse(response_head, ssl_info,
- std::move(downloaded_file));
-}
-
-void CORSURLLoader::OnReceiveRedirect(
- const net::RedirectInfo& redirect_info,
- const ResourceResponseHead& response_head) {
- forwarding_client_->OnReceiveRedirect(redirect_info, response_head);
-}
-
-void CORSURLLoader::OnDataDownloaded(int64_t data_len,
- int64_t encoded_data_len) {
- forwarding_client_->OnDataDownloaded(data_len, encoded_data_len);
-}
-
-void CORSURLLoader::OnUploadProgress(int64_t current_position,
- int64_t total_size,
- OnUploadProgressCallback ack_callback) {
- forwarding_client_->OnUploadProgress(current_position, total_size,
- std::move(ack_callback));
-}
-
-void CORSURLLoader::OnReceiveCachedMetadata(const std::vector<uint8_t>& data) {
- forwarding_client_->OnReceiveCachedMetadata(data);
-}
-
-void CORSURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
- forwarding_client_->OnTransferSizeUpdated(transfer_size_diff);
-}
-
-void CORSURLLoader::OnStartLoadingResponseBody(
- mojo::ScopedDataPipeConsumerHandle body) {
- forwarding_client_->OnStartLoadingResponseBody(std::move(body));
-}
-
-void CORSURLLoader::OnComplete(const ResourceRequestCompletionStatus& status) {
- forwarding_client_->OnComplete(status);
-}
-
-void CORSURLLoader::OnUpstreamConnectionError() {
- // |network_client_binding_| has experienced a connection error and will no
- // longer call any of the mojom::URLLoaderClient methods above. The client
- // pipe to the downstream client is closed to inform it of this failure. The
- // client should respond by closing its mojom::URLLoader pipe which will cause
- // this object to be destroyed.
- forwarding_client_.reset();
-}
-
-} // namespace content
diff --git a/chromium/content/child/push_messaging/OWNERS b/chromium/content/child/push_messaging/OWNERS
deleted file mode 100644
index 4898e44ea16..00000000000
--- a/chromium/content/child/push_messaging/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-file://content/browser/push_messaging/OWNERS
-
-# TEAM: platform-capabilities@chromium.org
-# COMPONENT: Blink>PushAPI
diff --git a/chromium/content/child/quota_message_filter.cc b/chromium/content/child/quota_message_filter.cc
deleted file mode 100644
index e196ebde151..00000000000
--- a/chromium/content/child/quota_message_filter.cc
+++ /dev/null
@@ -1,60 +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/child/quota_message_filter.h"
-
-#include "content/child/quota_dispatcher.h"
-#include "content/common/quota_messages.h"
-
-namespace content {
-
-QuotaMessageFilter::QuotaMessageFilter(ThreadSafeSender* thread_safe_sender)
- : WorkerThreadMessageFilter(thread_safe_sender), next_request_id_(0) {
-}
-
-QuotaMessageFilter::~QuotaMessageFilter() {}
-
-int QuotaMessageFilter::GenerateRequestID(int thread_id) {
- base::AutoLock lock(request_id_map_lock_);
- request_id_map_[next_request_id_] = thread_id;
- return next_request_id_++;
-}
-
-void QuotaMessageFilter::ClearThreadRequests(int thread_id) {
- base::AutoLock lock(request_id_map_lock_);
- for (RequestIdToThreadId::iterator iter = request_id_map_.begin();
- iter != request_id_map_.end();) {
- if (iter->second == thread_id)
- request_id_map_.erase(iter++);
- else
- iter++;
- }
-}
-
-bool QuotaMessageFilter::ShouldHandleMessage(const IPC::Message& msg) const {
- return IPC_MESSAGE_CLASS(msg) == QuotaMsgStart;
-}
-
-void QuotaMessageFilter::OnFilteredMessageReceived(const IPC::Message& msg) {
- QuotaDispatcher::ThreadSpecificInstance(thread_safe_sender(), this)
- ->OnMessageReceived(msg);
-}
-
-bool QuotaMessageFilter::GetWorkerThreadIdForMessage(const IPC::Message& msg,
- int* ipc_thread_id) {
- int request_id = -1;
- const bool success = base::PickleIterator(msg).ReadInt(&request_id);
- DCHECK(success);
-
- base::AutoLock lock(request_id_map_lock_);
- RequestIdToThreadId::iterator found = request_id_map_.find(request_id);
- if (found != request_id_map_.end()) {
- *ipc_thread_id = found->second;
- request_id_map_.erase(found);
- return true;
- }
- return false;
-}
-
-} // namespace content
diff --git a/chromium/content/child/quota_message_filter.h b/chromium/content/child/quota_message_filter.h
deleted file mode 100644
index cd2a11f7d66..00000000000
--- a/chromium/content/child/quota_message_filter.h
+++ /dev/null
@@ -1,49 +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_CHILD_QUOTA_MESSAGE_FILTER_H_
-#define CONTENT_CHILD_QUOTA_MESSAGE_FILTER_H_
-
-#include <map>
-
-#include "base/macros.h"
-#include "base/synchronization/lock.h"
-#include "content/child/worker_thread_message_filter.h"
-
-namespace content {
-
-class QuotaMessageFilter : public WorkerThreadMessageFilter {
- public:
- explicit QuotaMessageFilter(ThreadSafeSender* thread_safe_sender);
-
- // Generates a new request_id, registers { request_id, thread_id } map to
- // the message filter and returns the request_id.
- // This method can be called on any thread.
- int GenerateRequestID(int thread_id);
-
- // Clears all requests from the thread_id.
- void ClearThreadRequests(int thread_id);
-
- protected:
- ~QuotaMessageFilter() override;
-
- private:
- // WorkerThreadMessageFilter:
- bool ShouldHandleMessage(const IPC::Message& msg) const override;
- void OnFilteredMessageReceived(const IPC::Message& msg) override;
- bool GetWorkerThreadIdForMessage(const IPC::Message& msg,
- int* ipc_thread_id) override;
-
- typedef std::map<int, int> RequestIdToThreadId;
-
- base::Lock request_id_map_lock_;
- RequestIdToThreadId request_id_map_;
- int next_request_id_;
-
- DISALLOW_COPY_AND_ASSIGN(QuotaMessageFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_CHILD_QUOTA_MESSAGE_FILTER_H_
diff --git a/chromium/content/child/runtime_features.cc b/chromium/content/child/runtime_features.cc
index 59f1d793e36..28644e9a709 100644
--- a/chromium/content/child/runtime_features.cc
+++ b/chromium/content/child/runtime_features.cc
@@ -218,7 +218,7 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnableWebVR(true);
WebRuntimeFeatures::EnableWebVRExperimentalRendering(
- base::FeatureList::IsEnabled(features::kWebVRExperimentalRendering));
+ base::FeatureList::IsEnabled(features::kWebVrExperimentalRendering));
if (command_line.HasSwitch(switches::kDisablePresentationAPI))
WebRuntimeFeatures::EnablePresentationAPI(false);
@@ -230,6 +230,9 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
base::FeatureList::IsEnabled(features::kScrollAnchoring) ||
enableExperimentalWebPlatformFeatures);
+ WebRuntimeFeatures::EnableUserActivationV2(
+ base::FeatureList::IsEnabled(features::kUserActivationV2));
+
if (command_line.HasSwitch(switches::kEnableSlimmingPaintV175))
WebRuntimeFeatures::EnableFeatureFromString("SlimmingPaintV175", true);
if (command_line.HasSwitch(switches::kEnableSlimmingPaintV2))
@@ -285,9 +288,16 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnablePaymentRequest(
base::FeatureList::IsEnabled(features::kWebPayments));
+ if (base::FeatureList::IsEnabled(features::kServiceWorkerPaymentApps))
+ WebRuntimeFeatures::EnablePaymentApp(true);
+
WebRuntimeFeatures::EnableServiceWorkerScriptStreaming(
base::FeatureList::IsEnabled(features::kServiceWorkerScriptStreaming));
+ WebRuntimeFeatures::EnableServiceWorkerScriptFullCodeCache(
+ base::FeatureList::IsEnabled(
+ features::kServiceWorkerScriptFullCodeCache));
+
WebRuntimeFeatures::EnableOffMainThreadFetch(
base::FeatureList::IsEnabled(features::kOffMainThreadFetch));
@@ -309,8 +319,8 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (base::FeatureList::IsEnabled(features::kCompositorTouchAction))
WebRuntimeFeatures::EnableCompositorTouchAction(true);
- if (base::FeatureList::IsEnabled(features::kSkipCompositingSmallScrollers))
- WebRuntimeFeatures::EnableSkipCompositingSmallScrollers(true);
+ WebRuntimeFeatures::EnablePreventLayerSquashing(
+ base::FeatureList::IsEnabled(features::kEnablePreventLayerSquashing));
if (base::FeatureList::IsEnabled(features::kGenericSensor)) {
WebRuntimeFeatures::EnableGenericSensor(true);
@@ -322,6 +332,9 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
base::FeatureList::IsEnabled(features::kNetworkService))
WebRuntimeFeatures::EnableLoadingWithMojo(true);
+ if (base::FeatureList::IsEnabled(features::kNotificationsWithMojo))
+ WebRuntimeFeatures::EnableNotificationsWithMojo(true);
+
if (base::FeatureList::IsEnabled(features::kOutOfBlinkCORS))
WebRuntimeFeatures::EnableOutOfBlinkCORS(true);
@@ -355,9 +368,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
!enableExperimentalWebPlatformFeatures)
WebRuntimeFeatures::EnableWebAuth(false);
- WebRuntimeFeatures::EnableModuleScripts(
- base::FeatureList::IsEnabled(features::kModuleScripts));
-
WebRuntimeFeatures::EnableClientPlaceholdersForServerLoFi(
base::GetFieldTrialParamValue("PreviewsClientLoFi",
"replace_server_placeholders") == "true");
@@ -380,6 +390,9 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnableModuleScriptsDynamicImport(
base::FeatureList::IsEnabled(features::kModuleScriptsDynamicImport));
+ WebRuntimeFeatures::EnableModuleScriptsImportMetaUrl(
+ base::FeatureList::IsEnabled(features::kModuleScriptsImportMetaUrl));
+
WebRuntimeFeatures::EnableOverflowIconsForMediaControls(
base::FeatureList::IsEnabled(media::kOverflowIconsForMediaControls));
@@ -389,6 +402,13 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnableModernMediaControls(
base::FeatureList::IsEnabled(media::kUseModernMediaControls));
+ WebRuntimeFeatures::EnableWorkStealingInScriptRunner(
+ base::FeatureList::IsEnabled(features::kWorkStealingInScriptRunner));
+
+ WebRuntimeFeatures::EnableFeatureFromString(
+ "FeaturePolicyForPermissions",
+ base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions));
+
// Enable explicitly enabled features, and then disable explicitly disabled
// ones.
for (const std::string& feature :
@@ -402,6 +422,15 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (base::FeatureList::IsEnabled(features::kV8ContextSnapshot))
WebRuntimeFeatures::EnableV8ContextSnapshot(true);
+
+ if (base::FeatureList::IsEnabled(features::kStopLoadingInBackground))
+ WebRuntimeFeatures::EnableStopLoadingInBackgroundAndroid(true);
+
+ WebRuntimeFeatures::EnablePWAFullCodeCache(
+ base::FeatureList::IsEnabled(features::kPWAFullCodeCache));
+
+ WebRuntimeFeatures::EnableRequireCSSExtensionForFile(
+ base::FeatureList::IsEnabled(features::kRequireCSSExtensionForFile));
};
} // namespace content
diff --git a/chromium/content/child/service_worker/OWNERS b/chromium/content/child/service_worker/OWNERS
deleted file mode 100644
index 299b6b925b6..00000000000
--- a/chromium/content/child/service_worker/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-file://content/browser/service_worker/OWNERS
-
-# TEAM: worker-dev@chromium.org
-# COMPONENT: Blink>ServiceWorker
diff --git a/chromium/content/child/service_worker/service_worker_dispatcher.cc b/chromium/content/child/service_worker/service_worker_dispatcher.cc
deleted file mode 100644
index 093df6827bb..00000000000
--- a/chromium/content/child/service_worker/service_worker_dispatcher.cc
+++ /dev/null
@@ -1,619 +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/child/service_worker/service_worker_dispatcher.h"
-
-#include <stddef.h>
-#include <utility>
-
-#include "base/lazy_instance.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
-#include "base/threading/thread_local.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/trace_event/trace_event.h"
-#include "content/child/service_worker/service_worker_handle_reference.h"
-#include "content/child/service_worker/service_worker_provider_context.h"
-#include "content/child/service_worker/web_service_worker_impl.h"
-#include "content/child/service_worker/web_service_worker_registration_impl.h"
-#include "content/child/thread_safe_sender.h"
-#include "content/common/service_worker/service_worker_messages.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/common/content_constants.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebNavigationPreloadState.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-#include "url/url_constants.h"
-
-using blink::WebServiceWorkerError;
-using blink::WebServiceWorkerProvider;
-using base::ThreadLocalPointer;
-
-namespace content {
-
-namespace {
-
-base::LazyInstance<ThreadLocalPointer<void>>::Leaky g_dispatcher_tls =
- LAZY_INSTANCE_INITIALIZER;
-
-void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1);
-
-int CurrentWorkerId() {
- return WorkerThread::GetCurrentId();
-}
-
-} // namespace
-
-ServiceWorkerDispatcher::ServiceWorkerDispatcher(
- ThreadSafeSender* thread_safe_sender,
- base::SingleThreadTaskRunner* main_thread_task_runner)
- : thread_safe_sender_(thread_safe_sender),
- main_thread_task_runner_(main_thread_task_runner) {
- g_dispatcher_tls.Pointer()->Set(static_cast<void*>(this));
-}
-
-ServiceWorkerDispatcher::~ServiceWorkerDispatcher() {
- g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
-}
-
-void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) {
- bool handled = true;
-
- // When you add a new message handler, you should consider adding a similar
- // handler in ServiceWorkerMessageFilter to release references passed from
- // the browser process in case we fail to post task to the thread.
- IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUpdated, OnUpdated)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered,
- OnUnregistered)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidEnableNavigationPreload,
- OnDidEnableNavigationPreload)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetNavigationPreloadState,
- OnDidGetNavigationPreloadState)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidSetNavigationPreloadHeader,
- OnDidSetNavigationPreloadHeader)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUpdateError,
- OnUpdateError)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistrationError,
- OnUnregistrationError)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_EnableNavigationPreloadError,
- OnEnableNavigationPreloadError)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_GetNavigationPreloadStateError,
- OnGetNavigationPreloadStateError)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetNavigationPreloadHeaderError,
- OnSetNavigationPreloadHeaderError)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged,
- OnServiceWorkerStateChanged)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes,
- OnSetVersionAttributes)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_UpdateFound,
- OnUpdateFound)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker,
- OnSetControllerServiceWorker)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
- OnPostMessage)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CountFeature, OnCountFeature)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- DCHECK(handled) << "Unhandled message:" << msg.type();
-}
-
-void ServiceWorkerDispatcher::UpdateServiceWorker(
- int provider_id,
- int64_t registration_id,
- std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks) {
- DCHECK(callbacks);
- int request_id = pending_update_callbacks_.Add(std::move(callbacks));
- thread_safe_sender_->Send(new ServiceWorkerHostMsg_UpdateServiceWorker(
- CurrentWorkerId(), request_id, provider_id, registration_id));
-}
-
-void ServiceWorkerDispatcher::UnregisterServiceWorker(
- int provider_id,
- int64_t registration_id,
- std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks) {
- DCHECK(callbacks);
- int request_id = pending_unregistration_callbacks_.Add(std::move(callbacks));
- TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
- "ServiceWorkerDispatcher::UnregisterServiceWorker",
- request_id, "Registration ID", registration_id);
- thread_safe_sender_->Send(new ServiceWorkerHostMsg_UnregisterServiceWorker(
- CurrentWorkerId(), request_id, provider_id, registration_id));
-}
-
-void ServiceWorkerDispatcher::EnableNavigationPreload(
- int provider_id,
- int64_t registration_id,
- bool enable,
- std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks) {
- DCHECK(callbacks);
- int request_id =
- enable_navigation_preload_callbacks_.Add(std::move(callbacks));
- thread_safe_sender_->Send(new ServiceWorkerHostMsg_EnableNavigationPreload(
- CurrentWorkerId(), request_id, provider_id, registration_id, enable));
-}
-
-void ServiceWorkerDispatcher::GetNavigationPreloadState(
- int provider_id,
- int64_t registration_id,
- std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks) {
- DCHECK(callbacks);
- int request_id =
- get_navigation_preload_state_callbacks_.Add(std::move(callbacks));
- thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetNavigationPreloadState(
- CurrentWorkerId(), request_id, provider_id, registration_id));
-}
-
-void ServiceWorkerDispatcher::SetNavigationPreloadHeader(
- int provider_id,
- int64_t registration_id,
- const std::string& value,
- std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks) {
- DCHECK(callbacks);
- int request_id =
- set_navigation_preload_header_callbacks_.Add(std::move(callbacks));
- thread_safe_sender_->Send(new ServiceWorkerHostMsg_SetNavigationPreloadHeader(
- CurrentWorkerId(), request_id, provider_id, registration_id, value));
-}
-
-void ServiceWorkerDispatcher::AddProviderContext(
- ServiceWorkerProviderContext* provider_context) {
- DCHECK(provider_context);
- int provider_id = provider_context->provider_id();
- DCHECK(!base::ContainsKey(provider_contexts_, provider_id));
- provider_contexts_[provider_id] = provider_context;
-}
-
-void ServiceWorkerDispatcher::RemoveProviderContext(
- ServiceWorkerProviderContext* provider_context) {
- DCHECK(provider_context);
- DCHECK(
- base::ContainsKey(provider_contexts_, provider_context->provider_id()));
- provider_contexts_.erase(provider_context->provider_id());
-}
-
-void ServiceWorkerDispatcher::AddProviderClient(
- int provider_id,
- blink::WebServiceWorkerProviderClient* client) {
- DCHECK(client);
- DCHECK(!base::ContainsKey(provider_clients_, provider_id));
- provider_clients_[provider_id] = client;
-}
-
-void ServiceWorkerDispatcher::RemoveProviderClient(int provider_id) {
- // This could be possibly called multiple times to ensure termination.
- if (base::ContainsKey(provider_clients_, provider_id))
- provider_clients_.erase(provider_id);
-}
-
-ServiceWorkerDispatcher*
-ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
- ThreadSafeSender* thread_safe_sender,
- base::SingleThreadTaskRunner* main_thread_task_runner) {
- if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
- NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher.";
- g_dispatcher_tls.Pointer()->Set(NULL);
- }
- if (g_dispatcher_tls.Pointer()->Get())
- return static_cast<ServiceWorkerDispatcher*>(
- g_dispatcher_tls.Pointer()->Get());
-
- ServiceWorkerDispatcher* dispatcher =
- new ServiceWorkerDispatcher(thread_safe_sender, main_thread_task_runner);
- if (WorkerThread::GetCurrentId())
- WorkerThread::AddObserver(dispatcher);
- return dispatcher;
-}
-
-ServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() {
- if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted)
- return NULL;
- return static_cast<ServiceWorkerDispatcher*>(
- g_dispatcher_tls.Pointer()->Get());
-}
-
-void ServiceWorkerDispatcher::WillStopCurrentWorkerThread() {
- delete this;
-}
-
-scoped_refptr<WebServiceWorkerImpl>
-ServiceWorkerDispatcher::GetOrCreateServiceWorker(
- std::unique_ptr<ServiceWorkerHandleReference> handle_ref) {
- if (!handle_ref)
- return nullptr;
-
- WorkerObjectMap::iterator found =
- service_workers_.find(handle_ref->handle_id());
- if (found != service_workers_.end())
- return found->second;
-
- // WebServiceWorkerImpl constructor calls AddServiceWorker.
- return new WebServiceWorkerImpl(std::move(handle_ref),
- thread_safe_sender_.get());
-}
-
-scoped_refptr<WebServiceWorkerRegistrationImpl>
-ServiceWorkerDispatcher::GetOrCreateRegistration(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
- const ServiceWorkerVersionAttributes& attrs) {
- RegistrationObjectMap::iterator found = registrations_.find(info->handle_id);
- if (found != registrations_.end())
- return found->second;
-
- // WebServiceWorkerRegistrationImpl constructor calls
- // AddServiceWorkerRegistration to add itself into |registrations_|.
- auto registration =
- base::MakeRefCounted<WebServiceWorkerRegistrationImpl>(std::move(info));
-
- registration->SetInstalling(
- GetOrCreateServiceWorker(ServiceWorkerHandleReference::Create(
- attrs.installing, thread_safe_sender_.get())));
- registration->SetWaiting(
- GetOrCreateServiceWorker(ServiceWorkerHandleReference::Create(
- attrs.waiting, thread_safe_sender_.get())));
- registration->SetActive(
- GetOrCreateServiceWorker(ServiceWorkerHandleReference::Create(
- attrs.active, thread_safe_sender_.get())));
- return registration;
-}
-
-scoped_refptr<WebServiceWorkerRegistrationImpl>
-ServiceWorkerDispatcher::GetOrAdoptRegistration(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
- const ServiceWorkerVersionAttributes& attrs) {
- int32_t registration_handle_id = info->handle_id;
-
- std::unique_ptr<ServiceWorkerHandleReference> installing_ref =
- Adopt(attrs.installing);
- std::unique_ptr<ServiceWorkerHandleReference> waiting_ref =
- Adopt(attrs.waiting);
- std::unique_ptr<ServiceWorkerHandleReference> active_ref =
- Adopt(attrs.active);
-
- RegistrationObjectMap::iterator found =
- registrations_.find(registration_handle_id);
- if (found != registrations_.end())
- return found->second;
-
- // WebServiceWorkerRegistrationImpl constructor calls
- // AddServiceWorkerRegistration to add itself into |registrations_|.
- auto registration =
- base::MakeRefCounted<WebServiceWorkerRegistrationImpl>(std::move(info));
- registration->SetInstalling(
- GetOrCreateServiceWorker(std::move(installing_ref)));
- registration->SetWaiting(GetOrCreateServiceWorker(std::move(waiting_ref)));
- registration->SetActive(GetOrCreateServiceWorker(std::move(active_ref)));
- return registration;
-}
-
-void ServiceWorkerDispatcher::OnUpdated(int thread_id, int request_id) {
- TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
- "ServiceWorkerDispatcher::UpdateServiceWorker",
- request_id, "OnUpdated");
- TRACE_EVENT_ASYNC_END0("ServiceWorker",
- "ServiceWorkerDispatcher::UpdateServiceWorker",
- request_id);
- WebServiceWorkerUpdateCallbacks* callbacks =
- pending_update_callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- if (!callbacks)
- return;
-
- callbacks->OnSuccess();
- pending_update_callbacks_.Remove(request_id);
-}
-
-void ServiceWorkerDispatcher::OnUnregistered(int thread_id,
- int request_id,
- bool is_success) {
- TRACE_EVENT_ASYNC_STEP_INTO0(
- "ServiceWorker",
- "ServiceWorkerDispatcher::UnregisterServiceWorker",
- request_id,
- "OnUnregistered");
- TRACE_EVENT_ASYNC_END0("ServiceWorker",
- "ServiceWorkerDispatcher::UnregisterServiceWorker",
- request_id);
- WebServiceWorkerUnregistrationCallbacks* callbacks =
- pending_unregistration_callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- if (!callbacks)
- return;
- callbacks->OnSuccess(is_success);
- pending_unregistration_callbacks_.Remove(request_id);
-}
-
-void ServiceWorkerDispatcher::OnDidEnableNavigationPreload(int thread_id,
- int request_id) {
- WebEnableNavigationPreloadCallbacks* callbacks =
- enable_navigation_preload_callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- if (!callbacks)
- return;
- callbacks->OnSuccess();
- enable_navigation_preload_callbacks_.Remove(request_id);
-}
-
-void ServiceWorkerDispatcher::OnDidGetNavigationPreloadState(
- int thread_id,
- int request_id,
- const NavigationPreloadState& state) {
- WebGetNavigationPreloadStateCallbacks* callbacks =
- get_navigation_preload_state_callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- if (!callbacks)
- return;
- callbacks->OnSuccess(blink::WebNavigationPreloadState(
- state.enabled, blink::WebString::FromUTF8(state.header)));
- get_navigation_preload_state_callbacks_.Remove(request_id);
-}
-
-void ServiceWorkerDispatcher::OnDidSetNavigationPreloadHeader(int thread_id,
- int request_id) {
- WebSetNavigationPreloadHeaderCallbacks* callbacks =
- set_navigation_preload_header_callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- if (!callbacks)
- return;
- callbacks->OnSuccess();
- set_navigation_preload_header_callbacks_.Remove(request_id);
-}
-
-void ServiceWorkerDispatcher::OnUpdateError(
- int thread_id,
- int request_id,
- blink::mojom::ServiceWorkerErrorType error_type,
- const base::string16& message) {
- TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
- "ServiceWorkerDispatcher::UpdateServiceWorker",
- request_id, "OnUpdateError");
- TRACE_EVENT_ASYNC_END0("ServiceWorker",
- "ServiceWorkerDispatcher::UpdateServiceWorker",
- request_id);
- WebServiceWorkerUpdateCallbacks* callbacks =
- pending_update_callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- if (!callbacks)
- return;
-
- callbacks->OnError(
- WebServiceWorkerError(error_type, blink::WebString::FromUTF16(message)));
- pending_update_callbacks_.Remove(request_id);
-}
-
-void ServiceWorkerDispatcher::OnUnregistrationError(
- int thread_id,
- int request_id,
- blink::mojom::ServiceWorkerErrorType error_type,
- const base::string16& message) {
- TRACE_EVENT_ASYNC_STEP_INTO0(
- "ServiceWorker",
- "ServiceWorkerDispatcher::UnregisterServiceWorker",
- request_id,
- "OnUnregistrationError");
- TRACE_EVENT_ASYNC_END0("ServiceWorker",
- "ServiceWorkerDispatcher::UnregisterServiceWorker",
- request_id);
- WebServiceWorkerUnregistrationCallbacks* callbacks =
- pending_unregistration_callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- if (!callbacks)
- return;
-
- callbacks->OnError(
- WebServiceWorkerError(error_type, blink::WebString::FromUTF16(message)));
- pending_unregistration_callbacks_.Remove(request_id);
-}
-
-void ServiceWorkerDispatcher::OnEnableNavigationPreloadError(
- int thread_id,
- int request_id,
- blink::mojom::ServiceWorkerErrorType error_type,
- const std::string& message) {
- WebEnableNavigationPreloadCallbacks* callbacks =
- enable_navigation_preload_callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- if (!callbacks)
- return;
- callbacks->OnError(
- WebServiceWorkerError(error_type, blink::WebString::FromUTF8(message)));
- enable_navigation_preload_callbacks_.Remove(request_id);
-}
-
-void ServiceWorkerDispatcher::OnGetNavigationPreloadStateError(
- int thread_id,
- int request_id,
- blink::mojom::ServiceWorkerErrorType error_type,
- const std::string& message) {
- WebGetNavigationPreloadStateCallbacks* callbacks =
- get_navigation_preload_state_callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- if (!callbacks)
- return;
- callbacks->OnError(
- WebServiceWorkerError(error_type, blink::WebString::FromUTF8(message)));
- get_navigation_preload_state_callbacks_.Remove(request_id);
-}
-
-void ServiceWorkerDispatcher::OnSetNavigationPreloadHeaderError(
- int thread_id,
- int request_id,
- blink::mojom::ServiceWorkerErrorType error_type,
- const std::string& message) {
- WebSetNavigationPreloadHeaderCallbacks* callbacks =
- set_navigation_preload_header_callbacks_.Lookup(request_id);
- DCHECK(callbacks);
- if (!callbacks)
- return;
- callbacks->OnError(
- WebServiceWorkerError(error_type, blink::WebString::FromUTF8(message)));
- set_navigation_preload_header_callbacks_.Remove(request_id);
-}
-
-void ServiceWorkerDispatcher::OnServiceWorkerStateChanged(
- int thread_id,
- int handle_id,
- blink::mojom::ServiceWorkerState state) {
- TRACE_EVENT2("ServiceWorker",
- "ServiceWorkerDispatcher::OnServiceWorkerStateChanged",
- "Thread ID", thread_id,
- "State", static_cast<int>(state));
- WorkerObjectMap::iterator worker = service_workers_.find(handle_id);
- if (worker != service_workers_.end())
- worker->second->OnStateChanged(state);
-}
-
-void ServiceWorkerDispatcher::OnSetVersionAttributes(
- int thread_id,
- int registration_handle_id,
- int changed_mask,
- const ServiceWorkerVersionAttributes& attrs) {
- TRACE_EVENT1("ServiceWorker",
- "ServiceWorkerDispatcher::OnSetVersionAttributes",
- "Thread ID", thread_id);
-
- // Adopt the references sent from the browser process and pass it to the
- // registration if it exists.
- std::unique_ptr<ServiceWorkerHandleReference> installing =
- Adopt(attrs.installing);
- std::unique_ptr<ServiceWorkerHandleReference> waiting = Adopt(attrs.waiting);
- std::unique_ptr<ServiceWorkerHandleReference> active = Adopt(attrs.active);
-
- RegistrationObjectMap::iterator found =
- registrations_.find(registration_handle_id);
- if (found != registrations_.end()) {
- // Populate the version fields (eg. .installing) with worker objects.
- ChangedVersionAttributesMask mask(changed_mask);
- if (mask.installing_changed())
- found->second->SetInstalling(
- GetOrCreateServiceWorker(std::move(installing)));
- if (mask.waiting_changed())
- found->second->SetWaiting(GetOrCreateServiceWorker(std::move(waiting)));
- if (mask.active_changed())
- found->second->SetActive(GetOrCreateServiceWorker(std::move(active)));
- }
-}
-
-void ServiceWorkerDispatcher::OnUpdateFound(
- int thread_id,
- int registration_handle_id) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerDispatcher::OnUpdateFound");
- RegistrationObjectMap::iterator found =
- registrations_.find(registration_handle_id);
- if (found != registrations_.end())
- found->second->OnUpdateFound();
-}
-
-void ServiceWorkerDispatcher::OnSetControllerServiceWorker(
- const ServiceWorkerMsg_SetControllerServiceWorker_Params& params) {
- TRACE_EVENT2(
- "ServiceWorker", "ServiceWorkerDispatcher::OnSetControllerServiceWorker",
- "Thread ID", params.thread_id, "Provider ID", params.provider_id);
-
- // Adopt the reference sent from the browser process and pass it to the
- // provider context if it exists.
- std::unique_ptr<ServiceWorkerHandleReference> handle_ref =
- Adopt(params.object_info);
- ProviderContextMap::iterator provider =
- provider_contexts_.find(params.provider_id);
- if (provider != provider_contexts_.end()) {
- provider->second->SetController(std::move(handle_ref),
- params.used_features);
- }
-
- ProviderClientMap::iterator found =
- provider_clients_.find(params.provider_id);
- if (found != provider_clients_.end()) {
- // Sync the controllee's use counter with the service worker's one.
- for (uint32_t feature : params.used_features)
- found->second->CountFeature(feature);
-
- // Get the existing worker object or create a new one with a new reference
- // to populate the .controller field.
- scoped_refptr<WebServiceWorkerImpl> worker =
- GetOrCreateServiceWorker(ServiceWorkerHandleReference::Create(
- params.object_info, thread_safe_sender_.get()));
- found->second->SetController(WebServiceWorkerImpl::CreateHandle(worker),
- params.should_notify_controllerchange);
- // You must not access |found| after setController() because it may fire the
- // controllerchange event that may remove the provider client, for example,
- // by detaching an iframe.
- }
-}
-
-void ServiceWorkerDispatcher::OnPostMessage(
- const ServiceWorkerMsg_MessageToDocument_Params& params) {
- // Make sure we're on the main document thread. (That must be the only
- // thread we get this message)
- DCHECK_EQ(kDocumentMainThreadId, params.thread_id);
- TRACE_EVENT1("ServiceWorker", "ServiceWorkerDispatcher::OnPostMessage",
- "Thread ID", params.thread_id);
-
- // Adopt the reference sent from the browser process and get the corresponding
- // worker object.
- scoped_refptr<WebServiceWorkerImpl> worker =
- GetOrCreateServiceWorker(Adopt(params.service_worker_info));
-
- ProviderClientMap::iterator found =
- provider_clients_.find(params.provider_id);
- if (found == provider_clients_.end()) {
- // For now we do no queueing for messages sent to nonexistent / unattached
- // client.
- return;
- }
-
- found->second->DispatchMessageEvent(
- WebServiceWorkerImpl::CreateHandle(worker),
- blink::WebString::FromUTF16(params.message),
- std::move(params.message_ports));
-}
-
-void ServiceWorkerDispatcher::OnCountFeature(int thread_id,
- int provider_id,
- uint32_t feature) {
- ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
- if (provider != provider_contexts_.end()) {
- provider->second->CountFeature(feature);
- }
-
- ProviderClientMap::iterator found = provider_clients_.find(provider_id);
- if (found != provider_clients_.end())
- found->second->CountFeature(feature);
-}
-
-void ServiceWorkerDispatcher::AddServiceWorker(
- int handle_id, WebServiceWorkerImpl* worker) {
- DCHECK(!base::ContainsKey(service_workers_, handle_id));
- service_workers_[handle_id] = worker;
-}
-
-void ServiceWorkerDispatcher::RemoveServiceWorker(int handle_id) {
- DCHECK(base::ContainsKey(service_workers_, handle_id));
- service_workers_.erase(handle_id);
-}
-
-void ServiceWorkerDispatcher::AddServiceWorkerRegistration(
- int registration_handle_id,
- WebServiceWorkerRegistrationImpl* registration) {
- DCHECK(!base::ContainsKey(registrations_, registration_handle_id));
- registrations_[registration_handle_id] = registration;
-}
-
-void ServiceWorkerDispatcher::RemoveServiceWorkerRegistration(
- int registration_handle_id) {
- DCHECK(base::ContainsKey(registrations_, registration_handle_id));
- registrations_.erase(registration_handle_id);
-}
-
-std::unique_ptr<ServiceWorkerHandleReference> ServiceWorkerDispatcher::Adopt(
- const ServiceWorkerObjectInfo& info) {
- return ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
-}
-
-} // namespace content
diff --git a/chromium/content/child/service_worker/service_worker_dispatcher.h b/chromium/content/child/service_worker/service_worker_dispatcher.h
deleted file mode 100644
index a87c24ce3df..00000000000
--- a/chromium/content/child/service_worker/service_worker_dispatcher.h
+++ /dev/null
@@ -1,256 +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_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
-#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <set>
-#include <vector>
-
-#include "base/containers/id_map.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/strings/string16.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/child/worker_thread.h"
-#include "mojo/public/cpp/system/message_pipe.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProvider.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_state.mojom.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace IPC {
-class Message;
-}
-
-struct ServiceWorkerMsg_MessageToDocument_Params;
-struct ServiceWorkerMsg_SetControllerServiceWorker_Params;
-
-namespace content {
-
-class ServiceWorkerHandleReference;
-class ServiceWorkerProviderContext;
-class ThreadSafeSender;
-class WebServiceWorkerImpl;
-class WebServiceWorkerRegistrationImpl;
-struct ServiceWorkerObjectInfo;
-struct ServiceWorkerVersionAttributes;
-
-// This class manages communication with the browser process about
-// registration of the service worker, exposed to renderer and worker
-// scripts through methods like navigator.registerServiceWorker().
-class CONTENT_EXPORT ServiceWorkerDispatcher : public WorkerThread::Observer {
- public:
- typedef blink::WebServiceWorkerRegistration::WebServiceWorkerUpdateCallbacks
- WebServiceWorkerUpdateCallbacks;
- typedef blink::WebServiceWorkerRegistration::
- WebServiceWorkerUnregistrationCallbacks
- WebServiceWorkerUnregistrationCallbacks;
- using WebEnableNavigationPreloadCallbacks =
- blink::WebServiceWorkerRegistration::WebEnableNavigationPreloadCallbacks;
- using WebGetNavigationPreloadStateCallbacks = blink::
- WebServiceWorkerRegistration::WebGetNavigationPreloadStateCallbacks;
- using WebSetNavigationPreloadHeaderCallbacks = blink::
- WebServiceWorkerRegistration::WebSetNavigationPreloadHeaderCallbacks;
-
- ServiceWorkerDispatcher(
- ThreadSafeSender* thread_safe_sender,
- base::SingleThreadTaskRunner* main_thread_task_runner);
- ~ServiceWorkerDispatcher() override;
-
- void OnMessageReceived(const IPC::Message& msg);
-
- // Corresponds to ServiceWorkerRegistration.update().
- void UpdateServiceWorker(
- int provider_id,
- int64_t registration_id,
- std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks);
- // Corresponds to ServiceWorkerRegistration.unregister().
- void UnregisterServiceWorker(
- int provider_id,
- int64_t registration_id,
- std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks);
-
- // Corresponds to NavigationPreloadManager.enable/disable.
- void EnableNavigationPreload(
- int provider_id,
- int64_t registration_id,
- bool enable,
- std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks);
- // Corresponds to NavigationPreloadManager.getState.
- void GetNavigationPreloadState(
- int provider_id,
- int64_t registration_id,
- std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks);
- // Corresponds to NavigationPreloadManager.setHeaderValue.
- void SetNavigationPreloadHeader(
- int provider_id,
- int64_t registration_id,
- const std::string& value,
- std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks);
-
- // Called when a new provider context for a document is created. Usually
- // this happens when a new document is being loaded, and is called much
- // earlier than AddScriptClient.
- // (This is attached only to the document thread's ServiceWorkerDispatcher)
- void AddProviderContext(ServiceWorkerProviderContext* provider_context);
- void RemoveProviderContext(ServiceWorkerProviderContext* provider_context);
-
- // Called when navigator.serviceWorker is instantiated or detached
- // for a document whose provider can be identified by |provider_id|.
- void AddProviderClient(int provider_id,
- blink::WebServiceWorkerProviderClient* client);
- void RemoveProviderClient(int provider_id);
-
- // Returns the existing service worker or a newly created one with the given
- // handle reference. Returns nullptr if the given reference is invalid.
- scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorker(
- std::unique_ptr<ServiceWorkerHandleReference> handle_ref);
-
- // Returns the existing registration or a newly created one. When a new one is
- // created, increments interprocess references to the registration and its
- // versions via ServiceWorker(Registration)HandleReference.
- scoped_refptr<WebServiceWorkerRegistrationImpl> GetOrCreateRegistration(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
- const ServiceWorkerVersionAttributes& attrs);
-
- // Returns the existing registration or a newly created one. Always adopts
- // interprocess references to the registration and its versions via
- // ServiceWorker(Registration)HandleReference.
- scoped_refptr<WebServiceWorkerRegistrationImpl> GetOrAdoptRegistration(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
- const ServiceWorkerVersionAttributes& attrs);
-
- static ServiceWorkerDispatcher* GetOrCreateThreadSpecificInstance(
- ThreadSafeSender* thread_safe_sender,
- base::SingleThreadTaskRunner* main_thread_task_runner);
-
- // Unlike GetOrCreateThreadSpecificInstance() this doesn't create a new
- // instance if thread-local instance doesn't exist.
- static ServiceWorkerDispatcher* GetThreadSpecificInstance();
-
- base::SingleThreadTaskRunner* main_thread_task_runner() {
- return main_thread_task_runner_.get();
- }
-
- private:
- using UpdateCallbackMap =
- base::IDMap<std::unique_ptr<WebServiceWorkerUpdateCallbacks>>;
- using UnregistrationCallbackMap =
- base::IDMap<std::unique_ptr<WebServiceWorkerUnregistrationCallbacks>>;
- using EnableNavigationPreloadCallbackMap =
- base::IDMap<std::unique_ptr<WebEnableNavigationPreloadCallbacks>>;
- using GetNavigationPreloadStateCallbackMap =
- base::IDMap<std::unique_ptr<WebGetNavigationPreloadStateCallbacks>>;
- using SetNavigationPreloadHeaderCallbackMap =
- base::IDMap<std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks>>;
-
- using ProviderClientMap =
- std::map<int, blink::WebServiceWorkerProviderClient*>;
- using ProviderContextMap = std::map<int, ServiceWorkerProviderContext*>;
- using WorkerToProviderMap = std::map<int, ServiceWorkerProviderContext*>;
- using WorkerObjectMap = std::map<int, WebServiceWorkerImpl*>;
- using RegistrationObjectMap =
- std::map<int, WebServiceWorkerRegistrationImpl*>;
-
- friend class ServiceWorkerDispatcherTest;
- friend class WebServiceWorkerImpl;
- friend class WebServiceWorkerRegistrationImpl;
-
- // WorkerThread::Observer implementation.
- void WillStopCurrentWorkerThread() override;
-
- void OnUpdated(int thread_id, int request_id);
- void OnUnregistered(int thread_id,
- int request_id,
- bool is_success);
- void OnDidEnableNavigationPreload(int thread_id, int request_id);
- void OnDidGetNavigationPreloadState(int thread_id,
- int request_id,
- const NavigationPreloadState& state);
- void OnDidSetNavigationPreloadHeader(int thread_id, int request_id);
- void OnUpdateError(int thread_id,
- int request_id,
- blink::mojom::ServiceWorkerErrorType error_type,
- const base::string16& message);
- void OnUnregistrationError(int thread_id,
- int request_id,
- blink::mojom::ServiceWorkerErrorType error_type,
- const base::string16& message);
- void OnEnableNavigationPreloadError(
- int thread_id,
- int request_id,
- blink::mojom::ServiceWorkerErrorType error_type,
- const std::string& message);
- void OnGetNavigationPreloadStateError(
- int thread_id,
- int request_id,
- blink::mojom::ServiceWorkerErrorType error_type,
- const std::string& message);
- void OnSetNavigationPreloadHeaderError(
- int thread_id,
- int request_id,
- blink::mojom::ServiceWorkerErrorType error_type,
- const std::string& message);
- void OnServiceWorkerStateChanged(int thread_id,
- int handle_id,
- blink::mojom::ServiceWorkerState state);
- void OnSetVersionAttributes(int thread_id,
- int registration_handle_id,
- int changed_mask,
- const ServiceWorkerVersionAttributes& attributes);
- void OnUpdateFound(int thread_id,
- int registration_handle_id);
- void OnSetControllerServiceWorker(
- const ServiceWorkerMsg_SetControllerServiceWorker_Params& params);
- void OnPostMessage(const ServiceWorkerMsg_MessageToDocument_Params& params);
- void OnCountFeature(int thread_id, int provider_id, uint32_t feature);
-
- // Keeps map from handle_id to ServiceWorker object.
- void AddServiceWorker(int handle_id, WebServiceWorkerImpl* worker);
- void RemoveServiceWorker(int handle_id);
-
- // Keeps map from registration_handle_id to ServiceWorkerRegistration object.
- void AddServiceWorkerRegistration(
- int registration_handle_id,
- WebServiceWorkerRegistrationImpl* registration);
- void RemoveServiceWorkerRegistration(
- int registration_handle_id);
-
- // Assumes that the given object information retains an interprocess handle
- // reference passed from the browser process, and adopts it.
- std::unique_ptr<ServiceWorkerHandleReference> Adopt(
- const ServiceWorkerObjectInfo& info);
-
- UpdateCallbackMap pending_update_callbacks_;
- UnregistrationCallbackMap pending_unregistration_callbacks_;
- EnableNavigationPreloadCallbackMap enable_navigation_preload_callbacks_;
- GetNavigationPreloadStateCallbackMap get_navigation_preload_state_callbacks_;
- SetNavigationPreloadHeaderCallbackMap
- set_navigation_preload_header_callbacks_;
-
- ProviderClientMap provider_clients_;
- ProviderContextMap provider_contexts_;
-
- WorkerObjectMap service_workers_;
- RegistrationObjectMap registrations_;
-
- scoped_refptr<ThreadSafeSender> thread_safe_sender_;
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcher);
-};
-
-} // namespace content
-
-#endif // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
diff --git a/chromium/content/child/service_worker/service_worker_dispatcher_unittest.cc b/chromium/content/child/service_worker/service_worker_dispatcher_unittest.cc
deleted file mode 100644
index 6e329c3848b..00000000000
--- a/chromium/content/child/service_worker/service_worker_dispatcher_unittest.cc
+++ /dev/null
@@ -1,505 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/child/service_worker/service_worker_dispatcher.h"
-
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "content/child/service_worker/service_worker_handle_reference.h"
-#include "content/child/service_worker/service_worker_provider_context.h"
-#include "content/child/service_worker/web_service_worker_impl.h"
-#include "content/child/service_worker/web_service_worker_registration_impl.h"
-#include "content/child/thread_safe_sender.h"
-#include "content/common/service_worker/service_worker_container.mojom.h"
-#include "content/common/service_worker/service_worker_messages.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "ipc/ipc_sync_message_filter.h"
-#include "ipc/ipc_test_sink.h"
-#include "mojo/public/cpp/bindings/associated_binding_set.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-
-namespace content {
-
-namespace {
-
-class MockServiceWorkerRegistrationObjectHost
- : public blink::mojom::ServiceWorkerRegistrationObjectHost {
- public:
- MockServiceWorkerRegistrationObjectHost() = default;
- ~MockServiceWorkerRegistrationObjectHost() override = default;
-
- void AddBinding(
- blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedRequest
- request) {
- bindings_.AddBinding(this, std::move(request));
- }
-
- int GetBindingCount() const { return bindings_.size(); }
-
- private:
- mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerRegistrationObjectHost>
- bindings_;
-};
-
-class ServiceWorkerTestSender : public ThreadSafeSender {
- public:
- explicit ServiceWorkerTestSender(IPC::TestSink* ipc_sink)
- : ThreadSafeSender(nullptr, nullptr),
- ipc_sink_(ipc_sink) {}
-
- bool Send(IPC::Message* message) override {
- return ipc_sink_->Send(message);
- }
-
- private:
- ~ServiceWorkerTestSender() override {}
-
- IPC::TestSink* ipc_sink_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTestSender);
-};
-
-} // namespace
-
-class ServiceWorkerDispatcherTest : public testing::Test {
- public:
- ServiceWorkerDispatcherTest() {}
-
- void SetUp() override {
- sender_ = new ServiceWorkerTestSender(&ipc_sink_);
- dispatcher_.reset(new ServiceWorkerDispatcher(sender_.get(), nullptr));
- }
-
- void CreateObjectInfoAndVersionAttributes(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr* info,
- ServiceWorkerVersionAttributes* attrs) {
- *info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New();
- (*info)->handle_id = 10;
- (*info)->registration_id = 20;
- remote_registration_object_host_.AddBinding(
- mojo::MakeRequest(&(*info)->host_ptr_info));
-
- attrs->active.handle_id = 100;
- attrs->active.version_id = 200;
- attrs->waiting.handle_id = 101;
- attrs->waiting.version_id = 201;
- attrs->installing.handle_id = 102;
- attrs->installing.version_id = 202;
- }
-
- bool ContainsServiceWorker(int handle_id) {
- return ContainsKey(dispatcher_->service_workers_, handle_id);
- }
-
- bool ContainsRegistration(int registration_handle_id) {
- return ContainsKey(dispatcher_->registrations_, registration_handle_id);
- }
-
- void OnSetControllerServiceWorker(int thread_id,
- int provider_id,
- const ServiceWorkerObjectInfo& info,
- bool should_notify_controllerchange,
- const std::set<uint32_t>& used_features) {
- ServiceWorkerMsg_SetControllerServiceWorker_Params params;
- params.thread_id = thread_id;
- params.provider_id = provider_id;
- params.object_info = info;
- params.should_notify_controllerchange = should_notify_controllerchange;
- params.used_features = used_features;
- dispatcher_->OnSetControllerServiceWorker(params);
- }
-
- void OnPostMessage(const ServiceWorkerMsg_MessageToDocument_Params& params) {
- dispatcher_->OnPostMessage(params);
- }
-
- std::unique_ptr<ServiceWorkerHandleReference> Adopt(
- const ServiceWorkerObjectInfo& info) {
- return dispatcher_->Adopt(info);
- }
-
- ServiceWorkerDispatcher* dispatcher() { return dispatcher_.get(); }
- ThreadSafeSender* thread_safe_sender() { return sender_.get(); }
- IPC::TestSink* ipc_sink() { return &ipc_sink_; }
- const MockServiceWorkerRegistrationObjectHost&
- remote_registration_object_host() const {
- return remote_registration_object_host_;
- }
-
- private:
- base::MessageLoop message_loop_;
- IPC::TestSink ipc_sink_;
- std::unique_ptr<ServiceWorkerDispatcher> dispatcher_;
- scoped_refptr<ServiceWorkerTestSender> sender_;
- MockServiceWorkerRegistrationObjectHost remote_registration_object_host_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcherTest);
-};
-
-class MockWebServiceWorkerProviderClientImpl
- : public blink::WebServiceWorkerProviderClient {
- public:
- MockWebServiceWorkerProviderClientImpl(int provider_id,
- ServiceWorkerDispatcher* dispatcher)
- : provider_id_(provider_id), dispatcher_(dispatcher) {
- dispatcher_->AddProviderClient(provider_id, this);
- }
-
- ~MockWebServiceWorkerProviderClientImpl() override {
- dispatcher_->RemoveProviderClient(provider_id_);
- }
-
- void SetController(std::unique_ptr<blink::WebServiceWorker::Handle> handle,
- bool shouldNotifyControllerChange) override {
- // WebPassOwnPtr cannot be owned in Chromium, so drop the handle here.
- // The destruction releases ServiceWorkerHandleReference.
- is_set_controlled_called_ = true;
- }
-
- void DispatchMessageEvent(
- std::unique_ptr<blink::WebServiceWorker::Handle> handle,
- const blink::WebString& message,
- blink::WebVector<blink::MessagePortChannel> ports) override {
- // WebPassOwnPtr cannot be owned in Chromium, so drop the handle here.
- // The destruction releases ServiceWorkerHandleReference.
- is_dispatch_message_event_called_ = true;
- }
-
- void CountFeature(uint32_t feature) override {
- used_features_.insert(feature);
- }
-
- bool is_set_controlled_called() const { return is_set_controlled_called_; }
-
- bool is_dispatch_message_event_called() const {
- return is_dispatch_message_event_called_;
- }
-
- private:
- const int provider_id_;
- bool is_set_controlled_called_ = false;
- bool is_dispatch_message_event_called_ = false;
- ServiceWorkerDispatcher* dispatcher_;
- std::set<uint32_t> used_features_;
-};
-
-TEST_F(ServiceWorkerDispatcherTest, OnSetControllerServiceWorker) {
- const int kProviderId = 10;
- bool should_notify_controllerchange = true;
-
- // Assume that these objects are passed from the browser process and own
- // references to browser-side registration/worker representations.
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- CreateObjectInfoAndVersionAttributes(&info, &attrs);
-
- // (1) In the case there are no SWProviderContext and WebSWProviderClient for
- // the provider, the passed reference to the active worker should be adopted
- // but immediately released because there is no provider context to own it.
- OnSetControllerServiceWorker(kDocumentMainThreadId, kProviderId, attrs.active,
- should_notify_controllerchange,
- std::set<uint32_t>());
- ASSERT_EQ(1UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- ipc_sink()->ClearMessages();
-
- // (2) In the case there is no WebSWProviderClient but SWProviderContext for
- // the provider, the passed referecence should be adopted and owned by the
- // provider context.
- auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
- kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- nullptr /* provider_request */, nullptr /* host_ptr_info */, dispatcher(),
- nullptr /* loader_factory_getter */);
- ipc_sink()->ClearMessages();
- OnSetControllerServiceWorker(kDocumentMainThreadId, kProviderId, attrs.active,
- should_notify_controllerchange,
- std::set<uint32_t>());
- EXPECT_EQ(0UL, ipc_sink()->message_count());
-
- // Destruction of the provider context should release references to the
- // associated registration and the controller.
- provider_context = nullptr;
- ASSERT_EQ(1UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- ipc_sink()->ClearMessages();
-
- // (3) In the case there is no SWProviderContext but WebSWProviderClient for
- // the provider, the new reference should be created and owned by the provider
- // client (but the reference is immediately released due to limitation of the
- // mock provider client. See the comment on setController() of the mock).
- // In addition, the passed reference should be adopted but immediately
- // released because there is no provider context to own it.
- std::unique_ptr<MockWebServiceWorkerProviderClientImpl> provider_client(
- new MockWebServiceWorkerProviderClientImpl(kProviderId, dispatcher()));
- ASSERT_FALSE(provider_client->is_set_controlled_called());
- OnSetControllerServiceWorker(kDocumentMainThreadId, kProviderId, attrs.active,
- should_notify_controllerchange,
- std::set<uint32_t>());
- EXPECT_TRUE(provider_client->is_set_controlled_called());
- ASSERT_EQ(3UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(1)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(2)->type());
- provider_client.reset();
- ipc_sink()->ClearMessages();
-
- // (4) In the case there are both SWProviderContext and SWProviderClient for
- // the provider, the passed referecence should be adopted and owned by the
- // provider context. In addition, the new reference should be created for the
- // provider client and immediately released due to limitation of the mock
- // implementation.
- provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
- kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- nullptr /* provider_request */, nullptr /* host_ptr_info */, dispatcher(),
- nullptr /* loader_factory_getter */);
- provider_client.reset(
- new MockWebServiceWorkerProviderClientImpl(kProviderId, dispatcher()));
- ASSERT_FALSE(provider_client->is_set_controlled_called());
- ipc_sink()->ClearMessages();
- OnSetControllerServiceWorker(kDocumentMainThreadId, kProviderId, attrs.active,
- should_notify_controllerchange,
- std::set<uint32_t>());
- EXPECT_TRUE(provider_client->is_set_controlled_called());
- ASSERT_EQ(2UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(1)->type());
-}
-
-// Test that clearing the controller by sending a kInvalidServiceWorkerHandle
-// results in the provider context having a null controller.
-TEST_F(ServiceWorkerDispatcherTest, OnSetControllerServiceWorker_Null) {
- const int kProviderId = 10;
- bool should_notify_controllerchange = true;
-
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- CreateObjectInfoAndVersionAttributes(&info, &attrs);
-
- std::unique_ptr<MockWebServiceWorkerProviderClientImpl> provider_client(
- new MockWebServiceWorkerProviderClientImpl(kProviderId, dispatcher()));
- auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
- kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- nullptr /* provider_request */, nullptr /* host_ptr_info */, dispatcher(),
- nullptr /* loader_factory_getter */);
-
- // Set the controller to kInvalidServiceWorkerHandle.
- OnSetControllerServiceWorker(
- kDocumentMainThreadId, kProviderId, ServiceWorkerObjectInfo(),
- should_notify_controllerchange, std::set<uint32_t>());
-
- // Check that it became null.
- EXPECT_EQ(nullptr, provider_context->controller());
- EXPECT_TRUE(provider_client->is_set_controlled_called());
-}
-
-TEST_F(ServiceWorkerDispatcherTest, OnPostMessage) {
- const int kProviderId = 10;
-
- // Assume that these objects are passed from the browser process and own
- // references to browser-side registration/worker representations.
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- CreateObjectInfoAndVersionAttributes(&info, &attrs);
-
- ServiceWorkerMsg_MessageToDocument_Params params;
- params.thread_id = kDocumentMainThreadId;
- params.provider_id = kProviderId;
- params.service_worker_info = attrs.active;
-
- // The passed reference should be adopted but immediately released because
- // there is no provider client.
- OnPostMessage(params);
- ASSERT_EQ(1UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- ipc_sink()->ClearMessages();
-
- std::unique_ptr<MockWebServiceWorkerProviderClientImpl> provider_client(
- new MockWebServiceWorkerProviderClientImpl(kProviderId, dispatcher()));
- ASSERT_FALSE(provider_client->is_dispatch_message_event_called());
-
- // The passed reference should be owned by the provider client (but the
- // reference is immediately released due to limitation of the mock provider
- // client. See the comment on dispatchMessageEvent() of the mock).
- OnPostMessage(params);
- EXPECT_TRUE(provider_client->is_dispatch_message_event_called());
- ASSERT_EQ(1UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
-}
-
-TEST_F(ServiceWorkerDispatcherTest, GetServiceWorker) {
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- CreateObjectInfoAndVersionAttributes(&info, &attrs);
-
- // Should return a worker object newly created with the given reference.
- scoped_refptr<WebServiceWorkerImpl> worker(
- dispatcher()->GetOrCreateServiceWorker(Adopt(attrs.installing)));
- EXPECT_TRUE(worker);
- EXPECT_TRUE(ContainsServiceWorker(attrs.installing.handle_id));
- EXPECT_EQ(0UL, ipc_sink()->message_count());
-
- // Should return the same worker object and release the given reference.
- scoped_refptr<WebServiceWorkerImpl> existing_worker =
- dispatcher()->GetOrCreateServiceWorker(Adopt(attrs.installing));
- EXPECT_EQ(worker, existing_worker);
- ASSERT_EQ(1UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- ipc_sink()->ClearMessages();
-
- // Should return nullptr when a given object is invalid.
- scoped_refptr<WebServiceWorkerImpl> invalid_worker =
- dispatcher()->GetOrCreateServiceWorker(Adopt(ServiceWorkerObjectInfo()));
- EXPECT_FALSE(invalid_worker);
- EXPECT_EQ(0UL, ipc_sink()->message_count());
-}
-
-TEST_F(ServiceWorkerDispatcherTest, GetOrCreateRegistration) {
- scoped_refptr<WebServiceWorkerRegistrationImpl> registration1;
- scoped_refptr<WebServiceWorkerRegistrationImpl> registration2;
-
- {
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- CreateObjectInfoAndVersionAttributes(&info, &attrs);
- int64_t registration_id = info->registration_id;
- int32_t handle_id = info->handle_id;
- // The 1st ServiceWorkerRegistrationObjectHost Mojo connection has been
- // added.
- ASSERT_EQ(1, remote_registration_object_host().GetBindingCount());
-
- // Should return a registration object newly created with incrementing
- // the refcounts.
- registration1 =
- dispatcher()->GetOrCreateRegistration(std::move(info), attrs);
- EXPECT_TRUE(registration1);
- EXPECT_TRUE(ContainsRegistration(handle_id));
- EXPECT_EQ(registration_id, registration1->RegistrationId());
- EXPECT_EQ(1, remote_registration_object_host().GetBindingCount());
- ASSERT_EQ(3UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(1)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(2)->type());
- }
-
- ipc_sink()->ClearMessages();
-
- {
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- CreateObjectInfoAndVersionAttributes(&info, &attrs);
- // The 2nd Mojo connection has been added.
- ASSERT_EQ(2, remote_registration_object_host().GetBindingCount());
- // Should return the same registration object without incrementing the
- // refcounts.
- registration2 =
- dispatcher()->GetOrCreateRegistration(std::move(info), attrs);
- EXPECT_TRUE(registration2);
- EXPECT_EQ(registration1, registration2);
- // The 2nd Mojo connection has been dropped.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1, remote_registration_object_host().GetBindingCount());
- EXPECT_EQ(0UL, ipc_sink()->message_count());
- }
-
- ipc_sink()->ClearMessages();
-
- // The registration dtor decrements the refcounts.
- registration1 = nullptr;
- registration2 = nullptr;
- ASSERT_EQ(3UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(1)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(2)->type());
- // The 1st Mojo connection has been dropped.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0, remote_registration_object_host().GetBindingCount());
-}
-
-TEST_F(ServiceWorkerDispatcherTest, GetOrAdoptRegistration) {
- scoped_refptr<WebServiceWorkerRegistrationImpl> registration1;
- scoped_refptr<WebServiceWorkerRegistrationImpl> registration2;
-
- {
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- CreateObjectInfoAndVersionAttributes(&info, &attrs);
- int64_t registration_id = info->registration_id;
- int32_t handle_id = info->handle_id;
- // The 1st ServiceWorkerRegistrationObjectHost Mojo connection has been
- // added.
- ASSERT_EQ(1, remote_registration_object_host().GetBindingCount());
-
- // Should return a registration object newly created with adopting the
- // refcounts.
- registration1 =
- dispatcher()->GetOrAdoptRegistration(std::move(info), attrs);
- EXPECT_TRUE(registration1);
- EXPECT_TRUE(ContainsRegistration(handle_id));
- EXPECT_EQ(registration_id, registration1->RegistrationId());
- EXPECT_EQ(1, remote_registration_object_host().GetBindingCount());
- EXPECT_EQ(0UL, ipc_sink()->message_count());
- }
-
- ipc_sink()->ClearMessages();
-
- {
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- ServiceWorkerVersionAttributes attrs;
- CreateObjectInfoAndVersionAttributes(&info, &attrs);
- // The 2nd Mojo connection has been added.
- ASSERT_EQ(2, remote_registration_object_host().GetBindingCount());
- // Should return the same registration object without incrementing the
- // refcounts.
- registration2 =
- dispatcher()->GetOrAdoptRegistration(std::move(info), attrs);
- EXPECT_TRUE(registration2);
- EXPECT_EQ(registration1, registration2);
- // The 2nd Mojo connection has been dropped.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1, remote_registration_object_host().GetBindingCount());
- ASSERT_EQ(3UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(1)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(2)->type());
- }
-
- ipc_sink()->ClearMessages();
-
- // The registration dtor decrements the refcounts.
- registration1 = nullptr;
- registration2 = nullptr;
- ASSERT_EQ(3UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(1)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(2)->type());
- // The 1st Mojo connection has been dropped.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0, remote_registration_object_host().GetBindingCount());
-}
-
-} // namespace content
diff --git a/chromium/content/child/service_worker/service_worker_handle_reference.cc b/chromium/content/child/service_worker/service_worker_handle_reference.cc
deleted file mode 100644
index 5cd79ccfa3f..00000000000
--- a/chromium/content/child/service_worker/service_worker_handle_reference.cc
+++ /dev/null
@@ -1,52 +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/child/service_worker/service_worker_handle_reference.h"
-
-#include "base/memory/ptr_util.h"
-#include "content/child/thread_safe_sender.h"
-#include "content/common/service_worker/service_worker_messages.h"
-
-namespace content {
-
-std::unique_ptr<ServiceWorkerHandleReference>
-ServiceWorkerHandleReference::Create(const ServiceWorkerObjectInfo& info,
- ThreadSafeSender* sender) {
- DCHECK(sender);
- if (info.handle_id == kInvalidServiceWorkerHandleId)
- return nullptr;
- return base::WrapUnique(new ServiceWorkerHandleReference(info, sender, true));
-}
-
-std::unique_ptr<ServiceWorkerHandleReference>
-ServiceWorkerHandleReference::Adopt(const ServiceWorkerObjectInfo& info,
- ThreadSafeSender* sender) {
- DCHECK(sender);
- if (info.handle_id == kInvalidServiceWorkerHandleId)
- return nullptr;
- return base::WrapUnique(
- new ServiceWorkerHandleReference(info, sender, false));
-}
-
-ServiceWorkerHandleReference::ServiceWorkerHandleReference(
- const ServiceWorkerObjectInfo& info,
- ThreadSafeSender* sender,
- bool increment_ref_in_ctor)
- : info_(info),
- sender_(sender) {
- DCHECK_NE(info.handle_id, kInvalidServiceWorkerHandleId);
- if (increment_ref_in_ctor) {
- sender_->Send(
- new ServiceWorkerHostMsg_IncrementServiceWorkerRefCount(
- info_.handle_id));
- }
-}
-
-ServiceWorkerHandleReference::~ServiceWorkerHandleReference() {
- DCHECK_NE(info_.handle_id, kInvalidServiceWorkerHandleId);
- sender_->Send(
- new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount(info_.handle_id));
-}
-
-} // namespace content
diff --git a/chromium/content/child/service_worker/service_worker_message_filter.cc b/chromium/content/child/service_worker/service_worker_message_filter.cc
deleted file mode 100644
index a6861e4324d..00000000000
--- a/chromium/content/child/service_worker/service_worker_message_filter.cc
+++ /dev/null
@@ -1,97 +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/child/service_worker/service_worker_message_filter.h"
-
-#include <stddef.h>
-
-#include "content/child/service_worker/service_worker_dispatcher.h"
-#include "content/child/thread_safe_sender.h"
-#include "content/common/service_worker/service_worker_messages.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "ipc/ipc_message_macros.h"
-
-namespace content {
-
-namespace {
-
-// Sends a ServiceWorkerObjectDestroyed message to the browser so it can delete
-// the ServiceWorker handle.
-void SendServiceWorkerObjectDestroyed(
- ThreadSafeSender* sender,
- int handle_id) {
- if (handle_id == kInvalidServiceWorkerHandleId)
- return;
- sender->Send(
- new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount(handle_id));
-}
-
-} // namespace
-
-ServiceWorkerMessageFilter::ServiceWorkerMessageFilter(ThreadSafeSender* sender)
- : WorkerThreadMessageFilter(sender) {
-}
-
-ServiceWorkerMessageFilter::~ServiceWorkerMessageFilter() {}
-
-bool ServiceWorkerMessageFilter::ShouldHandleMessage(
- const IPC::Message& msg) const {
- return IPC_MESSAGE_CLASS(msg) == ServiceWorkerMsgStart;
-}
-
-void ServiceWorkerMessageFilter::OnFilteredMessageReceived(
- const IPC::Message& msg) {
- ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
- thread_safe_sender(), main_thread_task_runner())
- ->OnMessageReceived(msg);
-}
-
-bool ServiceWorkerMessageFilter::GetWorkerThreadIdForMessage(
- const IPC::Message& msg,
- int* ipc_thread_id) {
- return base::PickleIterator(msg).ReadInt(ipc_thread_id);
-}
-
-void ServiceWorkerMessageFilter::OnStaleMessageReceived(
- const IPC::Message& msg) {
- // Specifically handle some messages in case we failed to post task
- // to the thread (meaning that the context on the thread is now gone).
- IPC_BEGIN_MESSAGE_MAP(ServiceWorkerMessageFilter, msg)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes,
- OnStaleSetVersionAttributes)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker,
- OnStaleSetControllerServiceWorker)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
- OnStaleMessageToDocument)
- IPC_END_MESSAGE_MAP()
-}
-
-void ServiceWorkerMessageFilter::OnStaleSetVersionAttributes(
- int thread_id,
- int registration_handle_id,
- int changed_mask,
- const ServiceWorkerVersionAttributes& attrs) {
- SendServiceWorkerObjectDestroyed(thread_safe_sender(),
- attrs.installing.handle_id);
- SendServiceWorkerObjectDestroyed(thread_safe_sender(),
- attrs.waiting.handle_id);
- SendServiceWorkerObjectDestroyed(thread_safe_sender(),
- attrs.active.handle_id);
- // Don't have to decrement registration refcount because the sender of the
- // SetVersionAttributes message doesn't increment it.
-}
-
-void ServiceWorkerMessageFilter::OnStaleSetControllerServiceWorker(
- const ServiceWorkerMsg_SetControllerServiceWorker_Params& params) {
- SendServiceWorkerObjectDestroyed(thread_safe_sender(),
- params.object_info.handle_id);
-}
-
-void ServiceWorkerMessageFilter::OnStaleMessageToDocument(
- const ServiceWorkerMsg_MessageToDocument_Params& params) {
- SendServiceWorkerObjectDestroyed(thread_safe_sender(),
- params.service_worker_info.handle_id);
-}
-
-} // namespace content
diff --git a/chromium/content/child/service_worker/service_worker_message_filter.h b/chromium/content/child/service_worker/service_worker_message_filter.h
deleted file mode 100644
index 91947da627f..00000000000
--- a/chromium/content/child/service_worker/service_worker_message_filter.h
+++ /dev/null
@@ -1,56 +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_CHILD_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_
-#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_
-
-#include <set>
-#include <vector>
-
-#include "base/macros.h"
-#include "content/child/worker_thread_message_filter.h"
-#include "content/common/content_export.h"
-
-struct ServiceWorkerMsg_MessageToDocument_Params;
-struct ServiceWorkerMsg_SetControllerServiceWorker_Params;
-
-namespace content {
-
-struct ServiceWorkerVersionAttributes;
-
-class CONTENT_EXPORT ServiceWorkerMessageFilter
- : public WorkerThreadMessageFilter {
- public:
- explicit ServiceWorkerMessageFilter(ThreadSafeSender* thread_safe_sender);
-
- protected:
- ~ServiceWorkerMessageFilter() override;
-
- private:
- // WorkerThreadMessageFilter:
- bool ShouldHandleMessage(const IPC::Message& msg) const override;
- void OnFilteredMessageReceived(const IPC::Message& msg) override;
- bool GetWorkerThreadIdForMessage(const IPC::Message& msg,
- int* ipc_thread_id) override;
-
- // ChildMessageFilter:
- void OnStaleMessageReceived(const IPC::Message& msg) override;
-
- // Message handlers for stale messages.
- void OnStaleSetVersionAttributes(
- int thread_id,
- int registration_handle_id,
- int changed_mask,
- const ServiceWorkerVersionAttributes& attrs);
- void OnStaleSetControllerServiceWorker(
- const ServiceWorkerMsg_SetControllerServiceWorker_Params& params);
- void OnStaleMessageToDocument(
- const ServiceWorkerMsg_MessageToDocument_Params& params);
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerMessageFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_
diff --git a/chromium/content/child/service_worker/service_worker_provider_context.cc b/chromium/content/child/service_worker/service_worker_provider_context.cc
deleted file mode 100644
index 61d785d9ef1..00000000000
--- a/chromium/content/child/service_worker/service_worker_provider_context.cc
+++ /dev/null
@@ -1,274 +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/child/service_worker/service_worker_provider_context.h"
-
-#include <set>
-#include <utility>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/stl_util.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/child_thread_impl.h"
-#include "content/child/service_worker/controller_service_worker_connector.h"
-#include "content/child/service_worker/service_worker_dispatcher.h"
-#include "content/child/service_worker/service_worker_handle_reference.h"
-#include "content/child/service_worker/service_worker_subresource_loader.h"
-#include "content/child/thread_safe_sender.h"
-#include "content/child/worker_thread_registry.h"
-#include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
-#include "content/public/common/service_names.mojom.h"
-#include "content/public/common/url_loader_factory.mojom.h"
-#include "mojo/public/cpp/bindings/strong_associated_binding.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-
-namespace content {
-
-// Holds state for service worker clients.
-struct ServiceWorkerProviderContext::ControlleeState {
- explicit ControlleeState(
- scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter)
- : default_loader_factory_getter(
- std::move(default_loader_factory_getter)) {}
- ~ControlleeState() = default;
-
- std::unique_ptr<ServiceWorkerHandleReference> controller;
-
- // S13nServiceWorker:
- // Used to intercept requests from the controllee and dispatch them
- // as events to the controller ServiceWorker. This is reset when a new
- // controller is set.
- mojom::URLLoaderFactoryPtr subresource_loader_factory;
-
- // S13nServiceWorker:
- // Used when we create |subresource_loader_factory|.
- scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter;
-
- // Tracks feature usage for UseCounter.
- std::set<uint32_t> used_features;
-
- // Keeps ServiceWorkerWorkerClient pointers of dedicated or shared workers
- // which are associated with the ServiceWorkerProviderContext.
- // - If this ServiceWorkerProviderContext is for a Document, then
- // |worker_clients| contains all its dedicated workers.
- // - If this ServiceWorkerProviderContext is for a SharedWorker (technically
- // speaking, for its shadow page), then |worker_clients| has one element:
- // the shared worker.
- std::vector<mojom::ServiceWorkerWorkerClientPtr> worker_clients;
-
- // S13nServiceWorker
- // Used in |subresource_loader_factory| to get the connection to the
- // controller service worker. Kept here in order to call
- // OnContainerHostConnectionClosed when container_host_ for the
- // provider is reset.
- scoped_refptr<ControllerServiceWorkerConnector> controller_connector;
-};
-
-// Holds state for service worker execution contexts.
-struct ServiceWorkerProviderContext::ControllerState {
- ControllerState() = default;
- ~ControllerState() = default;
- // |registration->host_ptr_info| will be taken by
- // ServiceWorkerProviderContext::TakeRegistrationForServiceWorkerGlobalScope()
- // means after that |registration| will be in a half-way taken state.
- // TODO(leonhsl): To avoid the half-way taken state mentioned above, make
- // ServiceWorkerProviderContext::TakeRegistrationForServiceWorkerGlobalScope()
- // take/reset all information of |registration|, |installing|, |waiting| and
- // |active| all at once.
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration;
- std::unique_ptr<ServiceWorkerHandleReference> installing;
- std::unique_ptr<ServiceWorkerHandleReference> waiting;
- std::unique_ptr<ServiceWorkerHandleReference> active;
-};
-
-ServiceWorkerProviderContext::ServiceWorkerProviderContext(
- int provider_id,
- ServiceWorkerProviderType provider_type,
- mojom::ServiceWorkerContainerAssociatedRequest request,
- mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info,
- ServiceWorkerDispatcher* dispatcher,
- scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter)
- : provider_type_(provider_type),
- provider_id_(provider_id),
- main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
- binding_(this, std::move(request)) {
- container_host_.Bind(std::move(host_ptr_info));
- if (provider_type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) {
- controller_state_ = base::MakeUnique<ControllerState>();
- } else {
- controllee_state_ = base::MakeUnique<ControlleeState>(
- std::move(default_loader_factory_getter));
- }
-
- // |dispatcher| may be null in tests.
- // TODO(falken): Figure out how to make a dispatcher in tests.
- if (dispatcher)
- dispatcher->AddProviderContext(this);
-}
-
-ServiceWorkerProviderContext::~ServiceWorkerProviderContext() {
- if (ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetThreadSpecificInstance()) {
- // Remove this context from the dispatcher living on the main thread.
- dispatcher->RemoveProviderContext(this);
- }
-}
-
-void ServiceWorkerProviderContext::SetRegistrationForServiceWorkerGlobalScope(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration,
- std::unique_ptr<ServiceWorkerHandleReference> installing,
- std::unique_ptr<ServiceWorkerHandleReference> waiting,
- std::unique_ptr<ServiceWorkerHandleReference> active) {
- DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
- ControllerState* state = controller_state_.get();
- DCHECK(state);
- DCHECK(!state->registration);
- DCHECK(!state->installing && !state->waiting && !state->active);
- state->registration = std::move(registration);
- state->installing = std::move(installing);
- state->waiting = std::move(waiting);
- state->active = std::move(active);
-}
-
-void ServiceWorkerProviderContext::TakeRegistrationForServiceWorkerGlobalScope(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr* info,
- ServiceWorkerVersionAttributes* attrs) {
- DCHECK(!main_thread_task_runner_->RunsTasksInCurrentSequence());
- ControllerState* state = controller_state_.get();
- DCHECK(state);
- DCHECK(state->registration);
- DCHECK(state->registration->host_ptr_info.is_valid());
- *info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New(
- state->registration->registration_id, state->registration->handle_id,
- state->registration->options->Clone(),
- std::move(state->registration->host_ptr_info));
-
- if (state->installing)
- attrs->installing = state->installing->info();
- if (state->waiting)
- attrs->waiting = state->waiting->info();
- if (state->active)
- attrs->active = state->active->info();
-}
-
-void ServiceWorkerProviderContext::SetController(
- std::unique_ptr<ServiceWorkerHandleReference> controller,
- const std::set<uint32_t>& used_features) {
- DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
- ControlleeState* state = controllee_state_.get();
- DCHECK(state);
- DCHECK(!state->controller ||
- state->controller->handle_id() != kInvalidServiceWorkerHandleId);
-
- state->controller = std::move(controller);
- state->used_features = used_features;
-
- // Propagate the controller to workers related to this provider.
- if (state->controller) {
- for (const auto& worker : state->worker_clients) {
- // This is a Mojo interface call to the (dedicated or shared) worker
- // thread.
- worker->SetControllerServiceWorker(state->controller->version_id());
- }
- }
-
- // S13nServiceWorker
- // Set up the URL loader factory for sending URL requests to the controller.
- if (!ServiceWorkerUtils::IsServicificationEnabled() || !state->controller) {
- state->controller_connector = nullptr;
- state->subresource_loader_factory = nullptr;
- return;
- }
- storage::mojom::BlobRegistryPtr blob_registry_ptr;
- ChildThreadImpl::current()->GetConnector()->BindInterface(
- mojom::kBrowserServiceName, mojo::MakeRequest(&blob_registry_ptr));
- auto blob_registry = base::MakeRefCounted<
- base::RefCountedData<storage::mojom::BlobRegistryPtr>>(
- std::move(blob_registry_ptr));
- state->controller_connector =
- base::MakeRefCounted<ControllerServiceWorkerConnector>(
- container_host_.get());
- mojo::MakeStrongBinding(
- base::MakeUnique<ServiceWorkerSubresourceLoaderFactory>(
- state->controller_connector, state->default_loader_factory_getter,
- state->controller->url().GetOrigin(), std::move(blob_registry)),
- mojo::MakeRequest(&state->subresource_loader_factory));
-}
-
-ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() {
- DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
- DCHECK(controllee_state_);
- return controllee_state_->controller.get();
-}
-
-mojom::URLLoaderFactory*
-ServiceWorkerProviderContext::subresource_loader_factory() {
- DCHECK(controllee_state_);
- return controllee_state_->subresource_loader_factory.get();
-}
-
-mojom::ServiceWorkerContainerHost*
-ServiceWorkerProviderContext::container_host() const {
- DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, provider_type_);
- return container_host_.get();
-}
-
-void ServiceWorkerProviderContext::CountFeature(uint32_t feature) {
- // ServiceWorkerProviderContext keeps track of features in order to propagate
- // it to WebServiceWorkerProviderClient, which actually records the
- // UseCounter.
- DCHECK(controllee_state_);
- controllee_state_->used_features.insert(feature);
-}
-
-const std::set<uint32_t>& ServiceWorkerProviderContext::used_features() const {
- DCHECK(controllee_state_);
- return controllee_state_->used_features;
-}
-
-mojom::ServiceWorkerWorkerClientRequest
-ServiceWorkerProviderContext::CreateWorkerClientRequest() {
- DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
- DCHECK(controllee_state_);
- mojom::ServiceWorkerWorkerClientPtr client;
- mojom::ServiceWorkerWorkerClientRequest request = mojo::MakeRequest(&client);
- client.set_connection_error_handler(base::BindOnce(
- &ServiceWorkerProviderContext::UnregisterWorkerFetchContext,
- base::Unretained(this), client.get()));
- controllee_state_->worker_clients.push_back(std::move(client));
- return request;
-}
-
-void ServiceWorkerProviderContext::UnregisterWorkerFetchContext(
- mojom::ServiceWorkerWorkerClient* client) {
- DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
- DCHECK(controllee_state_);
- base::EraseIf(
- controllee_state_->worker_clients,
- [client](const mojom::ServiceWorkerWorkerClientPtr& client_ptr) {
- return client_ptr.get() == client;
- });
-}
-
-void ServiceWorkerProviderContext::OnNetworkProviderDestroyed() {
- container_host_.reset();
- if (controllee_state_ && controllee_state_->controller_connector)
- controllee_state_->controller_connector->OnContainerHostConnectionClosed();
-}
-
-void ServiceWorkerProviderContext::DestructOnMainThread() const {
- if (!main_thread_task_runner_->RunsTasksInCurrentSequence() &&
- main_thread_task_runner_->DeleteSoon(FROM_HERE, this)) {
- return;
- }
- delete this;
-}
-
-} // namespace content
diff --git a/chromium/content/child/service_worker/service_worker_provider_context_unittest.cc b/chromium/content/child/service_worker/service_worker_provider_context_unittest.cc
deleted file mode 100644
index 0adc051ce3c..00000000000
--- a/chromium/content/child/service_worker/service_worker_provider_context_unittest.cc
+++ /dev/null
@@ -1,155 +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/child/service_worker/service_worker_provider_context.h"
-
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "content/child/service_worker/service_worker_dispatcher.h"
-#include "content/child/service_worker/service_worker_handle_reference.h"
-#include "content/child/service_worker/service_worker_provider_context.h"
-#include "content/child/service_worker/web_service_worker_impl.h"
-#include "content/child/service_worker/web_service_worker_registration_impl.h"
-#include "content/child/thread_safe_sender.h"
-#include "content/common/service_worker/service_worker_container.mojom.h"
-#include "content/common/service_worker/service_worker_messages.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
-#include "content/public/common/url_loader_factory.mojom.h"
-#include "ipc/ipc_sync_message_filter.h"
-#include "ipc/ipc_test_sink.h"
-#include "mojo/public/cpp/bindings/associated_binding_set.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-
-namespace content {
-
-namespace {
-
-class MockServiceWorkerRegistrationObjectHost
- : public blink::mojom::ServiceWorkerRegistrationObjectHost {
- public:
- MockServiceWorkerRegistrationObjectHost() = default;
- ~MockServiceWorkerRegistrationObjectHost() override = default;
-
- void AddBinding(
- blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedRequest
- request) {
- bindings_.AddBinding(this, std::move(request));
- }
-
- int GetBindingCount() const { return bindings_.size(); }
-
- private:
- mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerRegistrationObjectHost>
- bindings_;
-};
-
-class ServiceWorkerTestSender : public ThreadSafeSender {
- public:
- explicit ServiceWorkerTestSender(IPC::TestSink* ipc_sink)
- : ThreadSafeSender(nullptr, nullptr), ipc_sink_(ipc_sink) {}
-
- bool Send(IPC::Message* message) override { return ipc_sink_->Send(message); }
-
- private:
- ~ServiceWorkerTestSender() override {}
-
- IPC::TestSink* ipc_sink_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTestSender);
-};
-
-} // namespace
-
-class ServiceWorkerProviderContextTest : public testing::Test {
- public:
- ServiceWorkerProviderContextTest() = default;
-
- void SetUp() override {
- sender_ = new ServiceWorkerTestSender(&ipc_sink_);
- dispatcher_.reset(new ServiceWorkerDispatcher(sender_.get(), nullptr));
- }
-
- void CreateObjectInfoAndVersionAttributes(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr* info,
- ServiceWorkerVersionAttributes* attrs) {
- *info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New();
- (*info)->handle_id = 10;
- (*info)->registration_id = 20;
- remote_registration_object_host_.AddBinding(
- mojo::MakeRequest(&(*info)->host_ptr_info));
-
- attrs->active.handle_id = 100;
- attrs->active.version_id = 200;
- attrs->waiting.handle_id = 101;
- attrs->waiting.version_id = 201;
- attrs->installing.handle_id = 102;
- attrs->installing.version_id = 202;
- }
-
- ThreadSafeSender* thread_safe_sender() { return sender_.get(); }
- IPC::TestSink* ipc_sink() { return &ipc_sink_; }
- ServiceWorkerDispatcher* dispatcher() { return dispatcher_.get(); }
- const MockServiceWorkerRegistrationObjectHost&
- remote_registration_object_host() const {
- return remote_registration_object_host_;
- }
-
- private:
- base::MessageLoop message_loop_;
- IPC::TestSink ipc_sink_;
- std::unique_ptr<ServiceWorkerDispatcher> dispatcher_;
- scoped_refptr<ServiceWorkerTestSender> sender_;
- MockServiceWorkerRegistrationObjectHost remote_registration_object_host_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderContextTest);
-};
-
-TEST_F(ServiceWorkerProviderContextTest, CreateForController) {
- // Assume that these objects are passed from the browser process and own
- // references to browser-side registration/worker representations.
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info;
- ServiceWorkerVersionAttributes version_attrs;
- CreateObjectInfoAndVersionAttributes(&registration_info, &version_attrs);
- // ServiceWorkerRegistrationObjectHost Mojo connection has been added.
- ASSERT_EQ(1, remote_registration_object_host().GetBindingCount());
- std::unique_ptr<ServiceWorkerHandleReference> installing =
- ServiceWorkerHandleReference::Adopt(version_attrs.installing,
- thread_safe_sender());
- std::unique_ptr<ServiceWorkerHandleReference> waiting =
- ServiceWorkerHandleReference::Adopt(version_attrs.waiting,
- thread_safe_sender());
- std::unique_ptr<ServiceWorkerHandleReference> active =
- ServiceWorkerHandleReference::Adopt(version_attrs.active,
- thread_safe_sender());
-
- // Set up ServiceWorkerProviderContext for ServiceWorkerGlobalScope.
- const int kProviderId = 10;
- auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
- kProviderId, SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, nullptr, nullptr,
- dispatcher(), nullptr /* loader_factory_getter */);
-
- // The passed references should be adopted and owned by the provider context.
- provider_context->SetRegistrationForServiceWorkerGlobalScope(
- std::move(registration_info), std::move(installing), std::move(waiting),
- std::move(active));
- EXPECT_EQ(0UL, ipc_sink()->message_count());
-
- // Destruction of the provider context should release references to the
- // associated registration and its versions.
- provider_context = nullptr;
- ASSERT_EQ(3UL, ipc_sink()->message_count());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(0)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(1)->type());
- EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
- ipc_sink()->GetMessageAt(2)->type());
- // ServiceWorkerRegistrationObjectHost Mojo connection got broken.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0, remote_registration_object_host().GetBindingCount());
-}
-
-} // namespace content
diff --git a/chromium/content/child/service_worker/service_worker_subresource_loader_unittest.cc b/chromium/content/child/service_worker/service_worker_subresource_loader_unittest.cc
deleted file mode 100644
index 34bc3202cc8..00000000000
--- a/chromium/content/child/service_worker/service_worker_subresource_loader_unittest.cc
+++ /dev/null
@@ -1,443 +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/child/service_worker/service_worker_subresource_loader.h"
-
-#include "base/run_loop.h"
-#include "base/test/scoped_feature_list.h"
-#include "content/child/child_url_loader_factory_getter_impl.h"
-#include "content/child/service_worker/controller_service_worker_connector.h"
-#include "content/common/service_worker/service_worker_container.mojom.h"
-#include "content/public/common/content_features.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/public/test/test_url_loader_client.h"
-#include "mojo/common/data_pipe_utils.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-#include "net/http/http_util.h"
-#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
-#include "storage/browser/blob/blob_data_builder.h"
-#include "storage/browser/blob/blob_data_handle.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-namespace {
-
-// This class need to set ChildURLLoaderFactoryGetter. CreateLoaderAndStart()
-// need to implement. todo(emim): Merge this and the one in
-// service_worker_url_loader_job_unittest.cc.
-class FakeNetworkURLLoaderFactory final : public mojom::URLLoaderFactory {
- public:
- FakeNetworkURLLoaderFactory() = default;
-
- // mojom::URLLoaderFactory implementation.
- void CreateLoaderAndStart(mojom::URLLoaderRequest request,
- int32_t routing_id,
- int32_t request_id,
- uint32_t options,
- const ResourceRequest& url_request,
- mojom::URLLoaderClientPtr client,
- const net::MutableNetworkTrafficAnnotationTag&
- traffic_annotation) override {
- std::string headers = "HTTP/1.1 200 OK\n\n";
- net::HttpResponseInfo info;
- info.headers = new net::HttpResponseHeaders(
- net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.length()));
- ResourceResponseHead response;
- response.headers = info.headers;
- response.headers->GetMimeType(&response.mime_type);
- client->OnReceiveResponse(response, base::nullopt, nullptr);
-
- std::string body = "this body came from the network";
- uint32_t bytes_written = body.size();
- mojo::DataPipe data_pipe;
- data_pipe.producer_handle->WriteData(body.data(), &bytes_written,
- MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
- client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
-
- ResourceRequestCompletionStatus status;
- status.error_code = net::OK;
- client->OnComplete(status);
- }
-
- void Clone(mojom::URLLoaderFactoryRequest factory) override { NOTREACHED(); }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FakeNetworkURLLoaderFactory);
-};
-
-class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
- public:
- FakeControllerServiceWorker() = default;
- ~FakeControllerServiceWorker() override = default;
-
- void AddBinding(mojom::ControllerServiceWorkerRequest request) {
- bindings_.AddBinding(this, std::move(request));
- }
-
- void CloseAllBindings() { bindings_.CloseAllBindings(); }
-
- // Tells this controller to respond to fetch events with network fallback.
- // i.e., simulate the service worker not calling respondWith().
- void RespondWithFallback() {
- response_mode_ = ResponseMode::kFallbackResponse;
- }
-
- // Tells this controller to respond to fetch events with the specified stream.
- void RespondWithStream(
- blink::mojom::ServiceWorkerStreamCallbackRequest callback_request,
- mojo::ScopedDataPipeConsumerHandle consumer_handle) {
- response_mode_ = ResponseMode::kStream;
- stream_handle_ = blink::mojom::ServiceWorkerStreamHandle::New();
- stream_handle_->callback_request = std::move(callback_request);
- stream_handle_->stream = std::move(consumer_handle);
- }
-
- // Tells this controller to respond to fetch events with a error response.
- void RespondWithError() { response_mode_ = ResponseMode::kErrorResponse; }
-
- // mojom::ControllerServiceWorker:
- void DispatchFetchEvent(
- const ServiceWorkerFetchRequest& request,
- mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- DispatchFetchEventCallback callback) override {
- fetch_event_count_++;
- fetch_event_request_ = request;
- switch (response_mode_) {
- case ResponseMode::kDefault:
- std::move(callback).Run(
- blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
- return;
- case ResponseMode::kStream:
- response_callback->OnResponseStream(
- ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 200, "OK",
- network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
- 0 /* blob_size */, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorUnknown, base::Time(),
- false /* response_is_in_cache_storage */,
- std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
- ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
- std::move(stream_handle_), base::Time::Now());
- std::move(callback).Run(
- blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
- return;
- case ResponseMode::kFallbackResponse:
- response_callback->OnFallback(base::Time::Now());
- std::move(callback).Run(
- blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
- return;
- case ResponseMode::kErrorResponse:
- response_callback->OnResponse(
- ServiceWorkerResponse(
- base::MakeUnique<std::vector<GURL>>(), 0 /* status_code */,
- "" /* status_text */,
- network::mojom::FetchResponseType::kDefault,
- base::MakeUnique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
- 0 /* blob_size */, nullptr /* blob */,
- blink::kWebServiceWorkerResponseErrorPromiseRejected,
- base::Time(), false /* response_is_in_cache_storage */,
- std::string() /* response_cache_storage_cache_name */,
- base::MakeUnique<
- ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
- base::Time::Now());
- std::move(callback).Run(
- blink::mojom::ServiceWorkerEventStatus::REJECTED,
- base::Time::Now());
- return;
- }
- NOTREACHED();
- }
-
- int fetch_event_count() const { return fetch_event_count_; }
- const ServiceWorkerFetchRequest& fetch_event_request() const {
- return fetch_event_request_;
- }
-
- private:
- enum class ResponseMode {
- kDefault,
- kStream,
- kFallbackResponse,
- kErrorResponse
- };
-
- ResponseMode response_mode_ = ResponseMode::kDefault;
-
- int fetch_event_count_ = 0;
- ServiceWorkerFetchRequest fetch_event_request_;
- mojo::BindingSet<mojom::ControllerServiceWorker> bindings_;
- // For ResponseMode::kStream.
- blink::mojom::ServiceWorkerStreamHandlePtr stream_handle_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeControllerServiceWorker);
-};
-
-class FakeServiceWorkerContainerHost
- : public mojom::ServiceWorkerContainerHost {
- public:
- explicit FakeServiceWorkerContainerHost(
- FakeControllerServiceWorker* fake_controller)
- : fake_controller_(fake_controller) {}
-
- ~FakeServiceWorkerContainerHost() override = default;
-
- int get_controller_service_worker_count() const {
- return get_controller_service_worker_count_;
- }
-
- private:
- // Implements mojom::ServiceWorkerContainerHost.
- void Register(const GURL& script_url,
- blink::mojom::ServiceWorkerRegistrationOptionsPtr options,
- RegisterCallback callback) override {
- NOTIMPLEMENTED();
- }
- void GetRegistration(const GURL& client_url,
- GetRegistrationCallback callback) override {
- NOTIMPLEMENTED();
- }
- void GetRegistrations(GetRegistrationsCallback callback) override {
- NOTIMPLEMENTED();
- }
- void GetRegistrationForReady(
- GetRegistrationForReadyCallback callback) override {
- NOTIMPLEMENTED();
- }
- void GetControllerServiceWorker(
- mojom::ControllerServiceWorkerRequest request) override {
- get_controller_service_worker_count_++;
- fake_controller_->AddBinding(std::move(request));
- }
-
- int get_controller_service_worker_count_ = 0;
- FakeControllerServiceWorker* fake_controller_;
- DISALLOW_COPY_AND_ASSIGN(FakeServiceWorkerContainerHost);
-};
-
-} // namespace
-
-
-class ServiceWorkerSubresourceLoaderTest : public ::testing::Test {
- protected:
- ServiceWorkerSubresourceLoaderTest()
- : fake_container_host_(&fake_controller_),
- url_loader_client_(base::MakeUnique<TestURLLoaderClient>()) {}
- ~ServiceWorkerSubresourceLoaderTest() override = default;
-
- void SetUp() override {
- feature_list_.InitAndEnableFeature(features::kNetworkService);
-
- mojom::URLLoaderFactoryPtr fake_loader_factory;
- mojo::MakeStrongBinding(base::MakeUnique<FakeNetworkURLLoaderFactory>(),
- MakeRequest(&fake_loader_factory));
- loader_factory_getter_ =
- base::MakeRefCounted<ChildURLLoaderFactoryGetterImpl>(
- std::move(fake_loader_factory), nullptr);
- controller_connector_ =
- base::MakeRefCounted<ControllerServiceWorkerConnector>(
- &fake_container_host_);
- }
-
- void TearDown() override {
- controller_connector_->OnContainerHostConnectionClosed();
- }
-
- void TestRequest(std::unique_ptr<ResourceRequest> request) {
- mojom::URLLoaderPtr url_loader;
-
- ServiceWorkerSubresourceLoaderFactory loader_factory(
- controller_connector_, loader_factory_getter_, request->url.GetOrigin(),
- base::MakeRefCounted<
- base::RefCountedData<storage::mojom::BlobRegistryPtr>>());
- loader_factory.CreateLoaderAndStart(
- mojo::MakeRequest(&url_loader), 0, 0, mojom::kURLLoadOptionNone,
- *request, url_loader_client_->CreateInterfacePtr(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- base::RunLoop().RunUntilIdle();
-
- EXPECT_EQ(request->url, fake_controller_.fetch_event_request().url);
- EXPECT_EQ(request->method, fake_controller_.fetch_event_request().method);
- }
-
- std::unique_ptr<ResourceRequest> CreateRequest(const GURL& url) {
- std::unique_ptr<ResourceRequest> request =
- base::MakeUnique<ResourceRequest>();
- request->url = url;
- request->method = "GET";
- return request;
- }
-
- TestBrowserThreadBundle thread_bundle_;
- scoped_refptr<ChildURLLoaderFactoryGetter> loader_factory_getter_;
-
- FakeServiceWorkerContainerHost fake_container_host_;
- FakeControllerServiceWorker fake_controller_;
- scoped_refptr<ControllerServiceWorkerConnector> controller_connector_;
- base::test::ScopedFeatureList feature_list_;
-
- std::unique_ptr<TestURLLoaderClient> url_loader_client_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSubresourceLoaderTest);
-};
-
-TEST_F(ServiceWorkerSubresourceLoaderTest, Basic) {
- TestRequest(CreateRequest(GURL("https://www.example.com/foo.html")));
- EXPECT_EQ(1, fake_controller_.fetch_event_count());
- EXPECT_EQ(1, fake_container_host_.get_controller_service_worker_count());
-}
-
-TEST_F(ServiceWorkerSubresourceLoaderTest, DropController) {
- TestRequest(CreateRequest(GURL("https://www.example.com/foo.html")));
- url_loader_client_->Unbind();
- EXPECT_EQ(1, fake_controller_.fetch_event_count());
- EXPECT_EQ(1, fake_container_host_.get_controller_service_worker_count());
- TestRequest(CreateRequest(GURL("https://www.example.com/foo2.html")));
- url_loader_client_->Unbind();
- EXPECT_EQ(2, fake_controller_.fetch_event_count());
- EXPECT_EQ(1, fake_container_host_.get_controller_service_worker_count());
-
- // Drop the connection to the ControllerServiceWorker.
- fake_controller_.CloseAllBindings();
- base::RunLoop().RunUntilIdle();
-
- // This should re-obtain the ControllerServiceWorker.
- TestRequest(CreateRequest(GURL("https://www.example.com/foo3.html")));
- EXPECT_EQ(3, fake_controller_.fetch_event_count());
- EXPECT_EQ(2, fake_container_host_.get_controller_service_worker_count());
-}
-
-TEST_F(ServiceWorkerSubresourceLoaderTest, StreamResponse) {
- // Construct the Stream to respond with.
- const char kResponseBody[] = "Here is sample text for the Stream.";
- blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
- mojo::DataPipe data_pipe;
- fake_controller_.RespondWithStream(mojo::MakeRequest(&stream_callback),
- std::move(data_pipe.consumer_handle));
-
- // Perform the request.
- TestRequest(CreateRequest(GURL("https://www.example.com/foo.html")));
-
- const ResourceResponseHead& info = url_loader_client_->response_head();
- EXPECT_EQ(200, info.headers->response_code());
- EXPECT_EQ(true, info.was_fetched_via_service_worker);
- EXPECT_EQ(false, info.was_fallback_required_by_service_worker);
- EXPECT_EQ(std::vector<GURL>(), info.url_list_via_service_worker);
- EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
- info.response_type_via_service_worker);
- EXPECT_EQ(false, info.is_in_cache_storage);
- EXPECT_EQ(std::string(), info.cache_storage_cache_name);
- EXPECT_EQ(false, info.did_service_worker_navigation_preload);
- EXPECT_NE(base::TimeTicks(), info.service_worker_start_time);
- EXPECT_NE(base::TimeTicks(), info.service_worker_ready_time);
-
- // Write the body stream.
- 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);
- stream_callback->OnCompleted();
- data_pipe.producer_handle.reset();
-
- url_loader_client_->RunUntilComplete();
- EXPECT_EQ(net::OK, url_loader_client_->completion_status().error_code);
-
- // Test the body.
- std::string response;
- EXPECT_TRUE(url_loader_client_->response_body().is_valid());
- EXPECT_TRUE(mojo::common::BlockingCopyToString(
- url_loader_client_->response_body_release(), &response));
- EXPECT_EQ(kResponseBody, response);
-}
-
-// Test when the service worker responds with network fallback.
-// i.e., does not call respondWith().
-TEST_F(ServiceWorkerSubresourceLoaderTest, FallbackResponse) {
- fake_controller_.RespondWithFallback();
-
- // Perform the request.
- TestRequest(CreateRequest(GURL("https://www.example.com/foo.html")));
- // TODO(emim): It should add some expression to check whether this actually
- // performed the fallback.
-}
-
-TEST_F(ServiceWorkerSubresourceLoaderTest, ErrorResponse) {
- fake_controller_.RespondWithError();
-
- // Perform the request.
- TestRequest(CreateRequest(GURL("https://www.example.com/foo.html")));
-
- EXPECT_EQ(net::ERR_FAILED,
- url_loader_client_->completion_status().error_code);
-}
-
-// Test when the service worker responds with network fallback to CORS request.
-TEST_F(ServiceWorkerSubresourceLoaderTest, CORSFallbackResponse) {
- fake_controller_.RespondWithFallback();
-
- struct TestCase {
- FetchRequestMode fetch_request_mode;
- base::Optional<url::Origin> request_initiator;
- bool expected_was_fallback_required_by_service_worker;
- };
- const TestCase kTests[] = {
- {FETCH_REQUEST_MODE_SAME_ORIGIN, base::Optional<url::Origin>(), false},
- {FETCH_REQUEST_MODE_NO_CORS, base::Optional<url::Origin>(), false},
- {FETCH_REQUEST_MODE_CORS, base::Optional<url::Origin>(), true},
- {FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT,
- base::Optional<url::Origin>(), true},
- {FETCH_REQUEST_MODE_NAVIGATE, base::Optional<url::Origin>(), false},
- {FETCH_REQUEST_MODE_SAME_ORIGIN,
- url::Origin(GURL("https://www.example.com/")), false},
- {FETCH_REQUEST_MODE_NO_CORS,
- url::Origin(GURL("https://www.example.com/")), false},
- {FETCH_REQUEST_MODE_CORS, url::Origin(GURL("https://www.example.com/")),
- false},
- {FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT,
- url::Origin(GURL("https://www.example.com/")), false},
- {FETCH_REQUEST_MODE_NAVIGATE,
- url::Origin(GURL("https://other.example.com/")), false},
- {FETCH_REQUEST_MODE_SAME_ORIGIN,
- url::Origin(GURL("https://other.example.com/")), false},
- {FETCH_REQUEST_MODE_NO_CORS,
- url::Origin(GURL("https://other.example.com/")), false},
- {FETCH_REQUEST_MODE_CORS, url::Origin(GURL("https://other.example.com/")),
- true},
- {FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT,
- url::Origin(GURL("https://other.example.com/")), true},
- {FETCH_REQUEST_MODE_NAVIGATE,
- url::Origin(GURL("https://other.example.com/")), false}};
-
- for (const auto& test : kTests) {
- SCOPED_TRACE(
- ::testing::Message()
- << "fetch_request_mode: " << static_cast<int>(test.fetch_request_mode)
- << " request_initiator: "
- << (test.request_initiator ? test.request_initiator->Serialize()
- : std::string("null")));
- std::unique_ptr<ResourceRequest> request =
- CreateRequest(GURL("https://www.example.com/foo.html"));
- request->fetch_request_mode = test.fetch_request_mode;
- request->request_initiator = test.request_initiator;
-
- // Perform the request.
- TestRequest(std::move(request));
-
- const ResourceResponseHead& info = url_loader_client_->response_head();
- EXPECT_EQ(test.expected_was_fallback_required_by_service_worker,
- info.was_fetched_via_service_worker);
- EXPECT_EQ(test.expected_was_fallback_required_by_service_worker,
- info.was_fallback_required_by_service_worker);
- url_loader_client_ = base::MakeUnique<TestURLLoaderClient>();
- }
-}
-
-// TODO(kinuko): Add more tests.
-
-} // namespace content
diff --git a/chromium/content/child/service_worker/web_service_worker_registration_impl.cc b/chromium/content/child/service_worker/web_service_worker_registration_impl.cc
deleted file mode 100644
index 83878bba1d2..00000000000
--- a/chromium/content/child/service_worker/web_service_worker_registration_impl.cc
+++ /dev/null
@@ -1,210 +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/child/service_worker/web_service_worker_registration_impl.h"
-
-#include <utility>
-
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "content/child/service_worker/service_worker_dispatcher.h"
-#include "content/child/service_worker/web_service_worker_impl.h"
-#include "content/child/service_worker/web_service_worker_provider_impl.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebNavigationPreloadState.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistrationProxy.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-
-namespace content {
-
-namespace {
-
-class HandleImpl : public blink::WebServiceWorkerRegistration::Handle {
- public:
- explicit HandleImpl(
- const scoped_refptr<WebServiceWorkerRegistrationImpl>& registration)
- : registration_(registration) {}
- ~HandleImpl() override {}
-
- blink::WebServiceWorkerRegistration* Registration() override {
- return registration_.get();
- }
-
- private:
- scoped_refptr<WebServiceWorkerRegistrationImpl> registration_;
-
- DISALLOW_COPY_AND_ASSIGN(HandleImpl);
-};
-
-} // namespace
-
-WebServiceWorkerRegistrationImpl::QueuedTask::QueuedTask(
- QueuedTaskType type,
- const scoped_refptr<WebServiceWorkerImpl>& worker)
- : type(type), worker(worker) {}
-
-WebServiceWorkerRegistrationImpl::QueuedTask::QueuedTask(
- const QueuedTask& other) = default;
-
-WebServiceWorkerRegistrationImpl::QueuedTask::~QueuedTask() {}
-
-WebServiceWorkerRegistrationImpl::WebServiceWorkerRegistrationImpl(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info)
- : info_(std::move(info)), proxy_(nullptr) {
- DCHECK(info_);
- DCHECK_NE(blink::mojom::kInvalidServiceWorkerRegistrationHandleId,
- info_->handle_id);
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetThreadSpecificInstance();
- DCHECK(dispatcher);
- dispatcher->AddServiceWorkerRegistration(info_->handle_id, this);
-}
-
-void WebServiceWorkerRegistrationImpl::SetInstalling(
- const scoped_refptr<WebServiceWorkerImpl>& service_worker) {
- if (proxy_)
- proxy_->SetInstalling(WebServiceWorkerImpl::CreateHandle(service_worker));
- else
- queued_tasks_.push_back(QueuedTask(INSTALLING, service_worker));
-}
-
-void WebServiceWorkerRegistrationImpl::SetWaiting(
- const scoped_refptr<WebServiceWorkerImpl>& service_worker) {
- if (proxy_)
- proxy_->SetWaiting(WebServiceWorkerImpl::CreateHandle(service_worker));
- else
- queued_tasks_.push_back(QueuedTask(WAITING, service_worker));
-}
-
-void WebServiceWorkerRegistrationImpl::SetActive(
- const scoped_refptr<WebServiceWorkerImpl>& service_worker) {
- if (proxy_)
- proxy_->SetActive(WebServiceWorkerImpl::CreateHandle(service_worker));
- else
- queued_tasks_.push_back(QueuedTask(ACTIVE, service_worker));
-}
-
-void WebServiceWorkerRegistrationImpl::OnUpdateFound() {
- if (proxy_)
- proxy_->DispatchUpdateFoundEvent();
- else
- queued_tasks_.push_back(QueuedTask(UPDATE_FOUND, nullptr));
-}
-
-void WebServiceWorkerRegistrationImpl::SetProxy(
- blink::WebServiceWorkerRegistrationProxy* proxy) {
- proxy_ = proxy;
- RunQueuedTasks();
-}
-
-void WebServiceWorkerRegistrationImpl::RunQueuedTasks() {
- DCHECK(proxy_);
- for (const QueuedTask& task : queued_tasks_) {
- if (task.type == INSTALLING)
- proxy_->SetInstalling(WebServiceWorkerImpl::CreateHandle(task.worker));
- else if (task.type == WAITING)
- proxy_->SetWaiting(WebServiceWorkerImpl::CreateHandle(task.worker));
- else if (task.type == ACTIVE)
- proxy_->SetActive(WebServiceWorkerImpl::CreateHandle(task.worker));
- else if (task.type == UPDATE_FOUND)
- proxy_->DispatchUpdateFoundEvent();
- }
- queued_tasks_.clear();
-}
-
-blink::WebServiceWorkerRegistrationProxy*
-WebServiceWorkerRegistrationImpl::Proxy() {
- return proxy_;
-}
-
-blink::WebURL WebServiceWorkerRegistrationImpl::Scope() const {
- return info_->options->scope;
-}
-
-void WebServiceWorkerRegistrationImpl::Update(
- blink::WebServiceWorkerProvider* provider,
- std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks) {
- WebServiceWorkerProviderImpl* provider_impl =
- static_cast<WebServiceWorkerProviderImpl*>(provider);
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetThreadSpecificInstance();
- DCHECK(dispatcher);
- dispatcher->UpdateServiceWorker(provider_impl->provider_id(),
- RegistrationId(), std::move(callbacks));
-}
-
-void WebServiceWorkerRegistrationImpl::Unregister(
- blink::WebServiceWorkerProvider* provider,
- std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks) {
- WebServiceWorkerProviderImpl* provider_impl =
- static_cast<WebServiceWorkerProviderImpl*>(provider);
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetThreadSpecificInstance();
- DCHECK(dispatcher);
- dispatcher->UnregisterServiceWorker(provider_impl->provider_id(),
- RegistrationId(), std::move(callbacks));
-}
-
-void WebServiceWorkerRegistrationImpl::EnableNavigationPreload(
- bool enable,
- blink::WebServiceWorkerProvider* provider,
- std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks) {
- WebServiceWorkerProviderImpl* provider_impl =
- static_cast<WebServiceWorkerProviderImpl*>(provider);
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetThreadSpecificInstance();
- DCHECK(dispatcher);
- dispatcher->EnableNavigationPreload(provider_impl->provider_id(),
- RegistrationId(), enable,
- std::move(callbacks));
-}
-
-void WebServiceWorkerRegistrationImpl::GetNavigationPreloadState(
- blink::WebServiceWorkerProvider* provider,
- std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks) {
- WebServiceWorkerProviderImpl* provider_impl =
- static_cast<WebServiceWorkerProviderImpl*>(provider);
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetThreadSpecificInstance();
- DCHECK(dispatcher);
- dispatcher->GetNavigationPreloadState(provider_impl->provider_id(),
- RegistrationId(), std::move(callbacks));
-}
-
-void WebServiceWorkerRegistrationImpl::SetNavigationPreloadHeader(
- const blink::WebString& value,
- blink::WebServiceWorkerProvider* provider,
- std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks) {
- WebServiceWorkerProviderImpl* provider_impl =
- static_cast<WebServiceWorkerProviderImpl*>(provider);
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetThreadSpecificInstance();
- DCHECK(dispatcher);
- dispatcher->SetNavigationPreloadHeader(provider_impl->provider_id(),
- RegistrationId(), value.Utf8(),
- std::move(callbacks));
-}
-
-int64_t WebServiceWorkerRegistrationImpl::RegistrationId() const {
- return info_->registration_id;
-}
-
-// static
-std::unique_ptr<blink::WebServiceWorkerRegistration::Handle>
-WebServiceWorkerRegistrationImpl::CreateHandle(
- const scoped_refptr<WebServiceWorkerRegistrationImpl>& registration) {
- if (!registration)
- return nullptr;
- return std::make_unique<HandleImpl>(registration);
-}
-
-WebServiceWorkerRegistrationImpl::~WebServiceWorkerRegistrationImpl() {
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetThreadSpecificInstance();
- if (dispatcher)
- dispatcher->RemoveServiceWorkerRegistration(info_->handle_id);
-}
-
-} // namespace content
diff --git a/chromium/content/child/service_worker/web_service_worker_registration_impl.h b/chromium/content/child/service_worker/web_service_worker_registration_impl.h
deleted file mode 100644
index a5eb5fe5db3..00000000000
--- a/chromium/content/child/service_worker/web_service_worker_registration_impl.h
+++ /dev/null
@@ -1,114 +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_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_REGISTRATION_IMPL_H_
-#define CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_REGISTRATION_IMPL_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "content/common/content_export.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
-
-namespace blink {
-class WebServiceWorkerRegistrationProxy;
-}
-
-namespace content {
-
-class WebServiceWorkerImpl;
-
-// Each instance corresponds to one ServiceWorkerRegistration object in JS
-// context, and is held by ServiceWorkerRegistration object in Blink's C++ layer
-// via WebServiceWorkerRegistration::Handle.
-//
-// Each instance holds one mojo connection of interface
-// blink::mojom::ServiceWorkerRegistrationObjectHost inside |info_|, so that
-// corresponding ServiceWorkerRegistrationHandle doesn't go away in the browser
-// process while the ServiceWorkerRegistration object is alive.
-class CONTENT_EXPORT WebServiceWorkerRegistrationImpl
- : public blink::WebServiceWorkerRegistration,
- public base::RefCounted<WebServiceWorkerRegistrationImpl> {
- public:
- explicit WebServiceWorkerRegistrationImpl(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info);
-
- void SetInstalling(const scoped_refptr<WebServiceWorkerImpl>& service_worker);
- void SetWaiting(const scoped_refptr<WebServiceWorkerImpl>& service_worker);
- void SetActive(const scoped_refptr<WebServiceWorkerImpl>& service_worker);
-
- void OnUpdateFound();
-
- // blink::WebServiceWorkerRegistration overrides.
- void SetProxy(blink::WebServiceWorkerRegistrationProxy* proxy) override;
- blink::WebServiceWorkerRegistrationProxy* Proxy() override;
- blink::WebURL Scope() const override;
- void Update(
- blink::WebServiceWorkerProvider* provider,
- std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks) override;
- void Unregister(blink::WebServiceWorkerProvider* provider,
- std::unique_ptr<WebServiceWorkerUnregistrationCallbacks>
- callbacks) override;
- void EnableNavigationPreload(
- bool enable,
- blink::WebServiceWorkerProvider* provider,
- std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks) override;
- void GetNavigationPreloadState(
- blink::WebServiceWorkerProvider* provider,
- std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks)
- override;
- void SetNavigationPreloadHeader(
- const blink::WebString& value,
- blink::WebServiceWorkerProvider* provider,
- std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks)
- override;
- int64_t RegistrationId() const override;
-
- using WebServiceWorkerRegistrationHandle =
- blink::WebServiceWorkerRegistration::Handle;
-
- // Creates WebServiceWorkerRegistrationHandle object that owns a reference to
- // the given WebServiceWorkerRegistrationImpl object.
- static std::unique_ptr<WebServiceWorkerRegistrationHandle> CreateHandle(
- const scoped_refptr<WebServiceWorkerRegistrationImpl>& registration);
-
- private:
- friend class base::RefCounted<WebServiceWorkerRegistrationImpl>;
- ~WebServiceWorkerRegistrationImpl() override;
-
- enum QueuedTaskType {
- INSTALLING,
- WAITING,
- ACTIVE,
- UPDATE_FOUND,
- };
-
- struct QueuedTask {
- QueuedTask(QueuedTaskType type,
- const scoped_refptr<WebServiceWorkerImpl>& worker);
- QueuedTask(const QueuedTask& other);
- ~QueuedTask();
- QueuedTaskType type;
- scoped_refptr<WebServiceWorkerImpl> worker;
- };
-
- void RunQueuedTasks();
-
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info_;
- blink::WebServiceWorkerRegistrationProxy* proxy_;
-
- std::vector<QueuedTask> queued_tasks_;
-
- DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerRegistrationImpl);
-};
-
-} // namespace content
-
-#endif // CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_REGISTRATION_IMPL_H_
diff --git a/chromium/content/child/web_database_impl.cc b/chromium/content/child/web_database_impl.cc
deleted file mode 100644
index 7830e321541..00000000000
--- a/chromium/content/child/web_database_impl.cc
+++ /dev/null
@@ -1,42 +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/child/web_database_impl.h"
-
-#include "mojo/public/cpp/bindings/strong_binding.h"
-#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebDatabase.h"
-#include "url/origin.h"
-
-using blink::WebSecurityOrigin;
-using blink::WebString;
-
-namespace content {
-
-WebDatabaseImpl::WebDatabaseImpl() = default;
-
-WebDatabaseImpl::~WebDatabaseImpl() = default;
-
-void WebDatabaseImpl::Create(content::mojom::WebDatabaseRequest request) {
- mojo::MakeStrongBinding(base::MakeUnique<WebDatabaseImpl>(),
- std::move(request));
-}
-
-void WebDatabaseImpl::UpdateSize(const url::Origin& origin,
- const base::string16& name,
- int64_t size) {
- DCHECK(!origin.unique());
- blink::WebDatabase::UpdateDatabaseSize(origin, WebString::FromUTF16(name),
- size);
-}
-
-void WebDatabaseImpl::CloseImmediately(const url::Origin& origin,
- const base::string16& name) {
- DCHECK(!origin.unique());
- blink::WebDatabase::CloseDatabaseImmediately(origin,
- WebString::FromUTF16(name));
-}
-
-} // namespace content
diff --git a/chromium/content/child/web_database_impl.h b/chromium/content/child/web_database_impl.h
deleted file mode 100644
index 66a92fbe700..00000000000
--- a/chromium/content/child/web_database_impl.h
+++ /dev/null
@@ -1,39 +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_CHILD_WEB_DATABASE_IMPL_H_
-#define CONTENT_CHILD_WEB_DATABASE_IMPL_H_
-
-#include <stdint.h>
-
-#include "base/strings/string16.h"
-#include "content/common/web_database.mojom.h"
-
-namespace url {
-class Origin;
-} // namespace url
-
-namespace content {
-
-// Receives database messages from the browser process and processes them on the
-// IO thread.
-class WebDatabaseImpl : public content::mojom::WebDatabase {
- public:
- WebDatabaseImpl();
- ~WebDatabaseImpl() override;
-
- static void Create(content::mojom::WebDatabaseRequest);
-
- private:
- // content::mojom::Database:
- void UpdateSize(const url::Origin& origin,
- const base::string16& name,
- int64_t size) override;
- void CloseImmediately(const url::Origin& origin,
- const base::string16& name) override;
-};
-
-} // namespace content
-
-#endif // CONTENT_CHILD_WEB_DATABASE_IMPL_H_
diff --git a/chromium/content/common/BUILD.gn b/chromium/content/common/BUILD.gn
index d607aae096c..33c85e6a96f 100644
--- a/chromium/content/common/BUILD.gn
+++ b/chromium/content/common/BUILD.gn
@@ -74,9 +74,7 @@ source_set("common") {
"cache_storage/cache_storage_types.h",
"child_process_host_impl.cc",
"child_process_host_impl.h",
- "child_process_messages.h",
"clipboard_format.h",
- "clipboard_messages.h",
"common_sandbox_support_linux.cc",
"content_constants_internal.cc",
"content_constants_internal.h",
@@ -114,18 +112,6 @@ source_set("common") {
"cursors/webcursor_mac.mm",
"cursors/webcursor_ozone.cc",
"date_time_suggestion.h",
- "devtools/devtools_network_conditions.cc",
- "devtools/devtools_network_conditions.h",
- "devtools/devtools_network_controller.cc",
- "devtools/devtools_network_controller.h",
- "devtools/devtools_network_interceptor.cc",
- "devtools/devtools_network_interceptor.h",
- "devtools/devtools_network_transaction.cc",
- "devtools/devtools_network_transaction.h",
- "devtools/devtools_network_transaction_factory.cc",
- "devtools/devtools_network_transaction_factory.h",
- "devtools/devtools_network_upload_data_stream.cc",
- "devtools/devtools_network_upload_data_stream.h",
"devtools_messages.h",
"dom_storage/dom_storage_map.cc",
"dom_storage/dom_storage_map.h",
@@ -138,8 +124,6 @@ source_set("common") {
"drag_traits.h",
"dwrite_font_proxy_messages.h",
"edit_command.h",
- "feature_policy/feature_policy.cc",
- "feature_policy/feature_policy.h",
"fileapi/file_system_messages.h",
"fileapi/webblob_messages.h",
"font_cache_dispatcher_win.cc",
@@ -182,8 +166,7 @@ source_set("common") {
"input/input_event.h",
"input/input_event_ack.cc",
"input/input_event_ack.h",
- "input/input_event_ack_source.h",
- "input/input_event_ack_state.h",
+ "input/input_event_ack_state.cc",
"input/input_event_dispatch_type.h",
"input/input_event_stream_validator.cc",
"input/input_event_stream_validator.h",
@@ -222,8 +205,6 @@ source_set("common") {
"loader_util.h",
"mac/attributed_string_coder.h",
"mac/attributed_string_coder.mm",
- "mac/font_descriptor.h",
- "mac/font_descriptor.mm",
"mac/font_loader.h",
"mac/font_loader.mm",
"media/aec_dump_messages.h",
@@ -247,6 +228,8 @@ source_set("common") {
"navigation_gesture.h",
"navigation_params.cc",
"navigation_params.h",
+ "navigation_subresource_loader_params.cc",
+ "navigation_subresource_loader_params.h",
"net/url_fetcher.cc",
"net/url_request_service_worker_data.cc",
"net/url_request_service_worker_data.h",
@@ -280,44 +263,15 @@ source_set("common") {
"quarantine/quarantine_linux.cc",
"quarantine/quarantine_mac.mm",
"quarantine/quarantine_win.cc",
- "quota_messages.h",
- "render_process_messages.h",
"render_widget_surface_properties.cc",
"render_widget_surface_properties.h",
"resize_params.cc",
"resize_params.h",
"resource_messages.cc",
"resource_messages.h",
+ "sandbox_init_linux.cc",
"sandbox_init_mac.cc",
- "sandbox_init_mac.h",
"sandbox_init_win.cc",
- "sandbox_linux/bpf_cdm_policy_linux.cc",
- "sandbox_linux/bpf_cdm_policy_linux.h",
- "sandbox_linux/bpf_cros_amd_gpu_policy_linux.cc",
- "sandbox_linux/bpf_cros_amd_gpu_policy_linux.h",
- "sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc",
- "sandbox_linux/bpf_cros_arm_gpu_policy_linux.h",
- "sandbox_linux/bpf_gpu_policy_linux.cc",
- "sandbox_linux/bpf_gpu_policy_linux.h",
- "sandbox_linux/bpf_pdf_compositor_policy_linux.cc",
- "sandbox_linux/bpf_pdf_compositor_policy_linux.h",
- "sandbox_linux/bpf_ppapi_policy_linux.cc",
- "sandbox_linux/bpf_ppapi_policy_linux.h",
- "sandbox_linux/bpf_renderer_policy_linux.cc",
- "sandbox_linux/bpf_renderer_policy_linux.h",
- "sandbox_linux/bpf_utility_policy_linux.cc",
- "sandbox_linux/bpf_utility_policy_linux.h",
- "sandbox_linux/sandbox_bpf_base_policy_linux.cc",
- "sandbox_linux/sandbox_bpf_base_policy_linux.h",
- "sandbox_linux/sandbox_debug_handling_linux.cc",
- "sandbox_linux/sandbox_debug_handling_linux.h",
- "sandbox_linux/sandbox_init_linux.cc",
- "sandbox_linux/sandbox_linux.cc",
- "sandbox_linux/sandbox_linux.h",
- "sandbox_linux/sandbox_seccomp_bpf_linux.cc",
- "sandbox_linux/sandbox_seccomp_bpf_linux.h",
- "sandbox_win.cc",
- "sandbox_win.h",
"savable_subframe.h",
"send_zygote_child_ping_linux.cc",
"service_manager/service_manager_connection_impl.cc",
@@ -353,6 +307,8 @@ source_set("common") {
"throttling_url_loader.h",
"unique_name_helper.cc",
"unique_name_helper.h",
+ "url_loader_factory_bundle.cc",
+ "url_loader_factory_bundle.h",
"url_request_struct_traits.cc",
"url_request_struct_traits.h",
"url_schemes.cc",
@@ -377,6 +333,7 @@ source_set("common") {
"//services/service_manager/sandbox",
"//third_party/WebKit/common:blink_common",
"//third_party/WebKit/public:blink_headers",
+ "//ui/accessibility",
]
deps = [
":features",
@@ -436,7 +393,6 @@ source_set("common") {
"//third_party/angle:angle_gpu_info_util",
"//third_party/boringssl",
"//third_party/icu",
- "//ui/accessibility",
"//ui/base",
"//ui/base/ime",
"//ui/display",
@@ -467,8 +423,8 @@ source_set("common") {
if (is_android && use_seccomp_bpf) {
set_sources_assignment_filter([])
sources += [
- "sandbox_linux/sandbox_bpf_base_policy_linux.cc",
- "sandbox_linux/sandbox_bpf_base_policy_linux.h",
+ "//services/service_manager/sandbox/linux/bpf_base_policy_linux.cc",
+ "//services/service_manager/sandbox/linux/bpf_base_policy_linux.h",
]
set_sources_assignment_filter(sources_assignment_filter)
}
@@ -546,8 +502,10 @@ source_set("common") {
}
if (!use_seccomp_bpf) {
- if (is_linux) {
+ if (is_linux && current_cpu != "s390x" && current_cpu != "ppc64") {
sources -= [
+ "sandbox_linux/bpf_base_policy_linux.cc",
+ "sandbox_linux/bpf_base_policy_linux.h",
"sandbox_linux/bpf_cros_amd_gpu_policy_linux.cc",
"sandbox_linux/bpf_cros_amd_gpu_policy_linux.h",
"sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc",
@@ -560,8 +518,6 @@ source_set("common") {
"sandbox_linux/bpf_renderer_policy_linux.h",
"sandbox_linux/bpf_utility_policy_linux.cc",
"sandbox_linux/bpf_utility_policy_linux.h",
- "sandbox_linux/sandbox_bpf_base_policy_linux.cc",
- "sandbox_linux/sandbox_bpf_base_policy_linux.h",
]
}
}
@@ -605,9 +561,13 @@ mojom("mojo_bindings") {
cpp_only = true
sources = [
+ "appcache.mojom",
"associated_interfaces.mojom",
"child.mojom",
+ "child_control.mojom",
"child_memory_coordinator.mojom",
+ "clipboard.mojom",
+ "devtools.mojom",
"field_trial_recorder.mojom",
"file_utilities.mojom",
"frame.mojom",
@@ -620,12 +580,13 @@ mojom("mojo_bindings") {
"input/input_injector.mojom",
"leveldb_wrapper.mojom",
"manifest_observer.mojom",
- "media/media_devices.mojom",
"media/media_stream.mojom",
"media/renderer_audio_output_stream_factory.mojom",
"memory_coordinator.mojom",
"native_types.mojom",
+ "page_state.mojom",
"push_messaging.mojom",
+ "quota_dispatcher_host.mojom",
"render_frame_message_filter.mojom",
"render_message_filter.mojom",
"render_widget_window_tree_client_factory.mojom",
@@ -639,7 +600,6 @@ mojom("mojo_bindings") {
"service_worker/service_worker_fetch_response_callback.mojom",
"service_worker/service_worker_installed_scripts_manager.mojom",
"service_worker/service_worker_provider.mojom",
- "service_worker/service_worker_types.mojom",
"shared_worker/shared_worker.mojom",
"shared_worker/shared_worker_client.mojom",
"shared_worker/shared_worker_connector.mojom",
@@ -647,11 +607,15 @@ mojom("mojo_bindings") {
"shared_worker/shared_worker_host.mojom",
"shared_worker/shared_worker_info.mojom",
"storage_partition_service.mojom",
+ "url_loader_factory_bundle.mojom",
"video_capture.mojom",
- "web_database.mojom",
"widget.mojom",
]
+ if (is_win) {
+ sources += [ "font_cache_win.mojom" ]
+ }
+
import_dirs = [ "//mojo/services" ]
public_deps = [
@@ -667,8 +631,9 @@ mojom("mojo_bindings") {
"//services/video_capture/public/interfaces",
"//services/viz/public/interfaces",
"//skia/public/interfaces",
- "//storage/public/interfaces",
+ "//storage/common:mojo_bindings",
"//third_party/WebKit/public:mojo_bindings",
+ "//ui/base/clipboard/mojom:mojo_bindings",
"//ui/base/mojo:mojo_bindings",
"//ui/gfx/geometry/mojo",
"//ui/gfx/mojo",
@@ -676,12 +641,6 @@ mojom("mojo_bindings") {
"//url/mojo:url_mojom_origin",
]
- # //storage/public/interfaces is configured to be exported
- # as STORAGE_COMMON, so override the dependencies to make it
- # depend via //storage/common.
- overridden_deps = [ "//storage/public/interfaces" ]
- component_deps = [ "//storage/common" ]
-
component_output_prefix = "content_common_mojo_bindings"
export_class_attribute = "CONTENT_EXPORT"
export_define = "CONTENT_IMPLEMENTATION=1"
diff --git a/chromium/content/common/DEPS b/chromium/content/common/DEPS
index 628a26dca0b..845cce99e9e 100644
--- a/chromium/content/common/DEPS
+++ b/chromium/content/common/DEPS
@@ -5,6 +5,7 @@ include_rules = [
"+components/viz/common",
"+components/payments",
"+device/base/synchronization",
+ "+services/network/public/cpp",
"+services/network/public/interfaces",
"+services/resource_coordinator/public/interfaces",
"+services/service_manager/public/cpp",
@@ -15,11 +16,12 @@ include_rules = [
# No inclusion of WebKit from the browser, other than strictly enum/POD,
# header-only types, and some selected common code.
"-third_party/WebKit",
+ "+third_party/WebKit/common/feature_policy/feature_policy.h",
+ "+third_party/WebKit/common/page/page_visibility_state.mojom.h",
"+third_party/WebKit/public/platform/WebAddressSpace.h",
"+third_party/WebKit/public/platform/WebContentSecurityPolicy.h",
"+third_party/WebKit/public/platform/WebDisplayMode.h",
"+third_party/WebKit/public/platform/WebDragOperation.h",
- "+third_party/WebKit/public/platform/WebFeaturePolicy.h",
"+third_party/WebKit/public/platform/WebFloatPoint.h",
"+third_party/WebKit/public/platform/WebFloatRect.h",
"+third_party/WebKit/public/platform/WebFocusType.h",
@@ -35,6 +37,7 @@ include_rules = [
"+third_party/WebKit/public/platform/WebOriginTrialTokenStatus.h",
"+third_party/WebKit/public/platform/WebPageVisibilityState.h",
"+third_party/WebKit/public/platform/WebReferrerPolicy.h",
+ "+third_party/WebKit/public/platform/WebRemoteScrollProperties.h",
"+third_party/WebKit/public/platform/WebScreenInfo.h",
"+third_party/WebKit/public/platform/WebScrollbarButtonsPlacement.h",
"+third_party/WebKit/public/platform/WebStorageArea.h",
@@ -43,6 +46,7 @@ include_rules = [
"+third_party/WebKit/public/platform/linux/WebFallbackFont.h",
"+third_party/WebKit/public/platform/mac/WebScrollbarTheme.h",
"+third_party/WebKit/public/platform/modules/bluetooth/web_bluetooth.mojom.h",
+ "+third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h",
"+third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionData.h",
"+third_party/WebKit/public/platform/modules/device_orientation/WebDeviceOrientationData.h",
"+third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom.h",
@@ -58,15 +62,15 @@ include_rules = [
"+third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h",
"+third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationType.h",
"+third_party/WebKit/public/platform/modules/payments/WebPaymentAppRequest.h",
- "+third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCacheError.h",
"+third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerClientType.h",
"+third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h",
- "+third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponseError.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/navigation_preload_state.mojom.h",
"+third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h",
"+third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h",
+ "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h",
"+third_party/WebKit/public/platform/modules/serviceworker/service_worker_state.mojom.h",
"+third_party/WebKit/public/platform/modules/serviceworker/service_worker_stream_handle.mojom.h",
- "+third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h",
"+third_party/WebKit/public/web/WebAXEnums.h",
"+third_party/WebKit/public/web/WebDeviceEmulationParams.h",
"+third_party/WebKit/public/web/WebDragStatus.h",
@@ -77,7 +81,6 @@ include_rules = [
"+third_party/WebKit/public/web/WebMediaPlayerAction.h",
"+third_party/WebKit/public/web/WebPluginAction.h",
"+third_party/WebKit/public/web/WebPopupType.h",
- "+third_party/WebKit/public/web/WebSandboxFlags.h",
"+third_party/WebKit/public/web/WebSharedWorkerCreationContextType.h",
"+third_party/WebKit/public/web/WebSharedWorkerCreationErrors.h",
"+third_party/WebKit/public/web/WebTextDirection.h",
diff --git a/chromium/content/common/OWNERS b/chromium/content/common/OWNERS
index db8fc708acd..05a264b6c24 100644
--- a/chromium/content/common/OWNERS
+++ b/chromium/content/common/OWNERS
@@ -5,8 +5,6 @@ jln@chromium.org
# For security review of Windows sandbox.
per-file sandbox_init_win.cc=set noparent
per-file sandbox_init_win.cc=file://sandbox/win/OWNERS
-per-file sandbox_win.*=set noparent
-per-file sandbox_win.*=file://sandbox/win/OWNERS
# Mac Sandbox.
per-file sandbox_init_mac.*=rsesek@chromium.org
diff --git a/chromium/content/common/accessibility_messages.h b/chromium/content/common/accessibility_messages.h
index dfa018a21f2..ff568ca39ae 100644
--- a/chromium/content/common/accessibility_messages.h
+++ b/chromium/content/common/accessibility_messages.h
@@ -203,9 +203,10 @@ IPC_MESSAGE_ROUTED1(
AccessibilityHostMsg_FindInPageResultParams)
// Sent in response to AccessibilityMsg_HitTest.
-IPC_MESSAGE_ROUTED3(AccessibilityHostMsg_ChildFrameHitTestResult,
+IPC_MESSAGE_ROUTED4(AccessibilityHostMsg_ChildFrameHitTestResult,
gfx::Point /* location tested */,
- int /* node id of result */,
+ int /* routing id of child frame */,
+ int /* browser plugin instance id of child frame */,
ui::AXEvent /* event to fire */)
// Sent in response to AccessibilityMsg_SnapshotTree. The callback id that was
diff --git a/chromium/content/common/android/OWNERS b/chromium/content/common/android/OWNERS
index acb7d4889f3..841d67d3261 100644
--- a/chromium/content/common/android/OWNERS
+++ b/chromium/content/common/android/OWNERS
@@ -1,4 +1,3 @@
-aelias@chromium.org
boliu@chromium.org
tedchoc@chromium.org
yfriedman@chromium.org
diff --git a/chromium/content/common/android/browser_side_navigation_policy_android.cc b/chromium/content/common/android/browser_side_navigation_policy_android.cc
index d2fe4a86fb0..a14dddd40f9 100644
--- a/chromium/content/common/android/browser_side_navigation_policy_android.cc
+++ b/chromium/content/common/android/browser_side_navigation_policy_android.cc
@@ -12,8 +12,9 @@ using base::android::JavaParamRef;
namespace content {
-jboolean IsBrowserSideNavigationEnabled(JNIEnv* env,
- const JavaParamRef<jclass>& clazz) {
+jboolean JNI_BrowserSideNavigationPolicy_IsBrowserSideNavigationEnabled(
+ JNIEnv* env,
+ const JavaParamRef<jclass>& clazz) {
return IsBrowserSideNavigationEnabled();
}
diff --git a/chromium/content/common/android/hash_set.h b/chromium/content/common/android/hash_set.h
index f2034f7ce80..af3260fc4fc 100644
--- a/chromium/content/common/android/hash_set.h
+++ b/chromium/content/common/android/hash_set.h
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#ifndef CONTENT_COMMON_ANDROID_HASH_SET_H_
+#define CONTENT_COMMON_ANDROID_HASH_SET_H_
+
#include <jni.h>
#include "base/android/scoped_java_ref.h"
@@ -20,3 +23,5 @@ void JNI_Java_HashSet_clear(JNIEnv* env,
const base::android::JavaRef<jobject>& hash_set);
} // namespace content
+
+#endif // CONTENT_COMMON_ANDROID_HASH_SET_H_
diff --git a/chromium/content/common/android/resource_request_body_android.cc b/chromium/content/common/android/resource_request_body_android.cc
index 50970499b65..ca7d105ebc5 100644
--- a/chromium/content/common/android/resource_request_body_android.cc
+++ b/chromium/content/common/android/resource_request_body_android.cc
@@ -22,8 +22,9 @@ namespace content {
namespace {
base::android::ScopedJavaLocalRef<jbyteArray>
-ConvertResourceRequestBodyToJavaArray(JNIEnv* env,
- const ResourceRequestBody& body) {
+JNI_ResourceRequestBody_ConvertResourceRequestBodyToJavaArray(
+ JNIEnv* env,
+ const ResourceRequestBody& body) {
std::string encoded = EncodeResourceRequestBody(body);
return base::android::ToJavaByteArray(
env, reinterpret_cast<const uint8_t*>(encoded.data()), encoded.size());
@@ -32,7 +33,7 @@ ConvertResourceRequestBodyToJavaArray(JNIEnv* env,
} // namespace
base::android::ScopedJavaLocalRef<jbyteArray>
-CreateResourceRequestBodyFromBytes(
+JNI_ResourceRequestBody_CreateResourceRequestBodyFromBytes(
JNIEnv* env,
const JavaParamRef<jclass>& clazz,
const JavaParamRef<jbyteArray>& j_post_data) {
@@ -46,7 +47,7 @@ CreateResourceRequestBodyFromBytes(
ResourceRequestBody::CreateFromBytes(
reinterpret_cast<const char*>(post_data.data()), post_data.size());
- return ConvertResourceRequestBodyToJavaArray(
+ return JNI_ResourceRequestBody_ConvertResourceRequestBodyToJavaArray(
env, static_cast<const ResourceRequestBody&>(*body));
}
@@ -60,7 +61,7 @@ ConvertResourceRequestBodyToJavaObject(
// TODO(lukasza): Avoid repeatedly copying the bytes.
// See also https://goo.gl/ITiLGI.
base::android::ScopedJavaLocalRef<jbyteArray> j_encoded =
- ConvertResourceRequestBodyToJavaArray(env, *body);
+ JNI_ResourceRequestBody_ConvertResourceRequestBodyToJavaArray(env, *body);
return Java_ResourceRequestBody_createFromEncodedNativeForm(env, j_encoded);
}
diff --git a/chromium/content/common/android/sync_compositor_messages.h b/chromium/content/common/android/sync_compositor_messages.h
index 2367f72b9f7..0beb97bb3b7 100644
--- a/chromium/content/common/android/sync_compositor_messages.h
+++ b/chromium/content/common/android/sync_compositor_messages.h
@@ -13,7 +13,7 @@
#include "components/viz/common/quads/compositor_frame.h"
#include "content/common/content_export.h"
#include "content/common/content_param_traits.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "ui/gfx/geometry/point.h"
diff --git a/chromium/content/common/appcache.mojom b/chromium/content/common/appcache.mojom
new file mode 100644
index 00000000000..ee9366b2dee
--- /dev/null
+++ b/chromium/content/common/appcache.mojom
@@ -0,0 +1,50 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+import "content/public/common/appcache_info.mojom";
+import "url/mojo/url.mojom";
+
+enum AppCacheEventID {
+ APPCACHE_CHECKING_EVENT,
+ APPCACHE_ERROR_EVENT,
+ APPCACHE_NO_UPDATE_EVENT,
+ APPCACHE_DOWNLOADING_EVENT,
+ APPCACHE_PROGRESS_EVENT,
+ APPCACHE_UPDATE_READY_EVENT,
+ APPCACHE_CACHED_EVENT,
+ APPCACHE_OBSOLETE_EVENT,
+};
+
+enum AppCacheErrorReason {
+ APPCACHE_MANIFEST_ERROR,
+ APPCACHE_SIGNATURE_ERROR,
+ APPCACHE_RESOURCE_ERROR,
+ APPCACHE_CHANGED_ERROR,
+ APPCACHE_ABORT_ERROR,
+ APPCACHE_QUOTA_ERROR,
+ APPCACHE_POLICY_ERROR,
+ APPCACHE_UNKNOWN_ERROR,
+};
+
+struct AppCacheResourceInfo {
+ url.mojom.Url url;
+ int64 size;
+ bool is_master;
+ bool is_manifest;
+ bool is_intercept;
+ bool is_fallback;
+ bool is_foreign;
+ bool is_explicit;
+ int64 response_id;
+};
+
+struct AppCacheErrorDetails {
+ string message;
+ AppCacheErrorReason reason = APPCACHE_UNKNOWN_ERROR;
+ url.mojom.Url url;
+ int32 status;
+ bool is_cross_origin;
+};
diff --git a/chromium/content/common/appcache_interfaces.cc b/chromium/content/common/appcache_interfaces.cc
index fea95e70241..11e24605124 100644
--- a/chromium/content/common/appcache_interfaces.cc
+++ b/chromium/content/common/appcache_interfaces.cc
@@ -17,88 +17,20 @@ namespace content {
const char kHttpGETMethod[] = "GET";
const char kHttpHEADMethod[] = "HEAD";
-const char kEnableExecutableHandlers[] = "enable-appcache-executable-handlers";
-
const base::FilePath::CharType kAppCacheDatabaseName[] =
FILE_PATH_LITERAL("Index");
-AppCacheInfo::AppCacheInfo()
- : cache_id(kAppCacheNoCacheId),
- group_id(0),
- status(APPCACHE_STATUS_UNCACHED),
- size(0),
- is_complete(false) {
-}
-
-AppCacheInfo::AppCacheInfo(const AppCacheInfo& other) = default;
-
-AppCacheInfo::~AppCacheInfo() {
-}
-
-AppCacheResourceInfo::AppCacheResourceInfo()
- : url(),
- size(0),
- is_master(false),
- is_manifest(false),
- is_intercept(false),
- is_fallback(false),
- is_foreign(false),
- is_explicit(false),
- response_id(kAppCacheNoResponseId) {
-}
-
-AppCacheResourceInfo::AppCacheResourceInfo(const AppCacheResourceInfo& other) =
- default;
-
-AppCacheResourceInfo::~AppCacheResourceInfo() {
-}
-
-AppCacheErrorDetails::AppCacheErrorDetails()
- : message(),
- reason(APPCACHE_UNKNOWN_ERROR),
- url(),
- status(0),
- is_cross_origin(false) {}
-
-AppCacheErrorDetails::AppCacheErrorDetails(
- std::string in_message,
- AppCacheErrorReason in_reason,
- GURL in_url,
- int in_status,
- bool in_is_cross_origin)
- : message(in_message),
- reason(in_reason),
- url(in_url),
- status(in_status),
- is_cross_origin(in_is_cross_origin) {}
-
-AppCacheErrorDetails::~AppCacheErrorDetails() {}
-
AppCacheNamespace::AppCacheNamespace()
- : type(APPCACHE_FALLBACK_NAMESPACE),
- is_pattern(false),
- is_executable(false) {
-}
-
-AppCacheNamespace::AppCacheNamespace(
- AppCacheNamespaceType type, const GURL& url, const GURL& target,
- bool is_pattern)
- : type(type),
- namespace_url(url),
- target_url(target),
- is_pattern(is_pattern),
- is_executable(false) {
-}
+ : type(APPCACHE_FALLBACK_NAMESPACE), is_pattern(false) {}
-AppCacheNamespace::AppCacheNamespace(
- AppCacheNamespaceType type, const GURL& url, const GURL& target,
- bool is_pattern, bool is_executable)
+AppCacheNamespace::AppCacheNamespace(AppCacheNamespaceType type,
+ const GURL& url,
+ const GURL& target,
+ bool is_pattern)
: type(type),
namespace_url(url),
target_url(target),
- is_pattern(is_pattern),
- is_executable(is_executable) {
-}
+ is_pattern(is_pattern) {}
AppCacheNamespace::~AppCacheNamespace() {
}
diff --git a/chromium/content/common/appcache_interfaces.h b/chromium/content/common/appcache_interfaces.h
index 74defd08c69..41ae467a079 100644
--- a/chromium/content/common/appcache_interfaces.h
+++ b/chromium/content/common/appcache_interfaces.h
@@ -10,6 +10,7 @@
#include <string>
#include "base/files/file_path.h"
+#include "content/common/appcache.mojom.h"
#include "content/public/common/appcache_info.h"
#include "mojo/public/cpp/system/message_pipe.h"
@@ -22,17 +23,10 @@ namespace content {
// Defines constants, types, and abstract classes used in the main
// process and in child processes.
-enum AppCacheEventID {
- APPCACHE_CHECKING_EVENT,
- APPCACHE_ERROR_EVENT,
- APPCACHE_NO_UPDATE_EVENT,
- APPCACHE_DOWNLOADING_EVENT,
- APPCACHE_PROGRESS_EVENT,
- APPCACHE_UPDATE_READY_EVENT,
- APPCACHE_CACHED_EVENT,
- APPCACHE_OBSOLETE_EVENT,
- APPCACHE_EVENT_ID_LAST = APPCACHE_OBSOLETE_EVENT
-};
+using mojom::AppCacheEventID;
+using mojom::AppCacheErrorReason;
+using mojom::AppCacheResourceInfo;
+using mojom::AppCacheErrorDetails;
// Temporarily renumber them in wierd way, to help remove LOG_TIP from WebKit
enum AppCacheLogLevel {
@@ -48,59 +42,12 @@ enum AppCacheNamespaceType {
APPCACHE_NETWORK_NAMESPACE
};
-enum AppCacheErrorReason {
- APPCACHE_MANIFEST_ERROR,
- APPCACHE_SIGNATURE_ERROR,
- APPCACHE_RESOURCE_ERROR,
- APPCACHE_CHANGED_ERROR,
- APPCACHE_ABORT_ERROR,
- APPCACHE_QUOTA_ERROR,
- APPCACHE_POLICY_ERROR,
- APPCACHE_UNKNOWN_ERROR,
- APPCACHE_ERROR_REASON_LAST = APPCACHE_UNKNOWN_ERROR
-};
-
-// Type to hold information about a single appcache resource.
-struct CONTENT_EXPORT AppCacheResourceInfo {
- AppCacheResourceInfo();
- AppCacheResourceInfo(const AppCacheResourceInfo& other);
- ~AppCacheResourceInfo();
-
- GURL url;
- int64_t size;
- bool is_master;
- bool is_manifest;
- bool is_intercept;
- bool is_fallback;
- bool is_foreign;
- bool is_explicit;
- int64_t response_id;
-};
-
-struct CONTENT_EXPORT AppCacheErrorDetails {
- AppCacheErrorDetails();
- AppCacheErrorDetails(std::string message,
- AppCacheErrorReason reason,
- GURL url,
- int status,
- bool is_cross_origin);
- ~AppCacheErrorDetails();
-
- std::string message;
- AppCacheErrorReason reason;
- GURL url;
- int status;
- bool is_cross_origin;
-};
-
typedef std::vector<AppCacheResourceInfo> AppCacheResourceInfoVector;
struct CONTENT_EXPORT AppCacheNamespace {
AppCacheNamespace(); // Type is APPCACHE_FALLBACK_NAMESPACE by default.
AppCacheNamespace(AppCacheNamespaceType type, const GURL& url,
const GURL& target, bool is_pattern);
- AppCacheNamespace(AppCacheNamespaceType type, const GURL& url,
- const GURL& target, bool is_pattern, bool is_executable);
~AppCacheNamespace();
bool IsMatch(const GURL& url) const;
@@ -109,7 +56,6 @@ struct CONTENT_EXPORT AppCacheNamespace {
GURL namespace_url;
GURL target_url;
bool is_pattern;
- bool is_executable;
};
typedef std::vector<AppCacheNamespace> AppCacheNamespaceVector;
@@ -153,10 +99,6 @@ class CONTENT_EXPORT AppCacheBackend {
const GURL& document_url,
const int64_t cache_document_was_loaded_from,
const GURL& manifest_url) = 0;
- virtual void SelectCacheForWorker(
- int host_id,
- int parent_process_id,
- int parent_host_id) = 0;
virtual void SelectCacheForSharedWorker(int host_id, int64_t appcache_id) = 0;
virtual void MarkAsForeignEntry(int host_id,
const GURL& document_url,
diff --git a/chromium/content/common/appcache_messages.h b/chromium/content/common/appcache_messages.h
index 38f6b48fcfb..94f6af97fee 100644
--- a/chromium/content/common/appcache_messages.h
+++ b/chromium/content/common/appcache_messages.h
@@ -16,11 +16,11 @@
#define IPC_MESSAGE_START AppCacheMsgStart
IPC_ENUM_TRAITS_MAX_VALUE(content::AppCacheEventID,
- content::APPCACHE_EVENT_ID_LAST)
+ content::AppCacheEventID::APPCACHE_OBSOLETE_EVENT)
IPC_ENUM_TRAITS_MAX_VALUE(content::AppCacheStatus,
- content::APPCACHE_STATUS_LAST)
+ content::AppCacheStatus::APPCACHE_STATUS_OBSOLETE)
IPC_ENUM_TRAITS_MAX_VALUE(content::AppCacheErrorReason,
- content::APPCACHE_ERROR_REASON_LAST)
+ content::AppCacheErrorReason::APPCACHE_UNKNOWN_ERROR)
IPC_STRUCT_TRAITS_BEGIN(content::AppCacheInfo)
IPC_STRUCT_TRAITS_MEMBER(manifest_url)
@@ -85,10 +85,6 @@ IPC_MESSAGE_CONTROL4(AppCacheHostMsg_SelectCache,
GURL /* opt_manifest_url */)
// Initiates worker specific cache selection algorithm for the given host.
-IPC_MESSAGE_CONTROL3(AppCacheHostMsg_SelectCacheForWorker,
- int /* host_id */,
- int /* parent_process_id */,
- int /* parent_host_id */)
IPC_MESSAGE_CONTROL2(AppCacheHostMsg_SelectCacheForSharedWorker,
int /* host_id */,
int64_t /* appcache_id */)
diff --git a/chromium/content/common/associated_interface_provider_impl.cc b/chromium/content/common/associated_interface_provider_impl.cc
index cdbe5a7737c..b594e22d4f2 100644
--- a/chromium/content/common/associated_interface_provider_impl.cc
+++ b/chromium/content/common/associated_interface_provider_impl.cc
@@ -15,7 +15,7 @@ class AssociatedInterfaceProviderImpl::LocalProvider
explicit LocalProvider(mojom::AssociatedInterfaceProviderAssociatedPtr* proxy)
: associated_interface_provider_binding_(this) {
associated_interface_provider_binding_.Bind(
- mojo::MakeIsolatedRequest(proxy));
+ mojo::MakeRequestAssociatedWithDedicatedPipe(proxy));
}
~LocalProvider() override {}
diff --git a/chromium/content/common/associated_interface_provider_impl.h b/chromium/content/common/associated_interface_provider_impl.h
index 71bca7711a1..cf5f0af7650 100644
--- a/chromium/content/common/associated_interface_provider_impl.h
+++ b/chromium/content/common/associated_interface_provider_impl.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_COMMON_ASSOCIATED_INTERFACE_PROVIDER_IMPL_H_
#define CONTENT_COMMON_ASSOCIATED_INTERFACE_PROVIDER_IMPL_H_
-#include "content/public/common/associated_interface_provider.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
#include <stdint.h>
#include <memory>
@@ -15,7 +15,8 @@
namespace content {
-class AssociatedInterfaceProviderImpl : public AssociatedInterfaceProvider {
+class AssociatedInterfaceProviderImpl
+ : public blink::AssociatedInterfaceProvider {
public:
// Binds this to a remote mojom::AssociatedInterfaceProvider.
explicit AssociatedInterfaceProviderImpl(
diff --git a/chromium/content/common/associated_interface_registry_impl.cc b/chromium/content/common/associated_interface_registry_impl.cc
index 468dc99664e..b10d08d2936 100644
--- a/chromium/content/common/associated_interface_registry_impl.cc
+++ b/chromium/content/common/associated_interface_registry_impl.cc
@@ -10,7 +10,8 @@
namespace content {
-AssociatedInterfaceRegistryImpl::AssociatedInterfaceRegistryImpl() {}
+AssociatedInterfaceRegistryImpl::AssociatedInterfaceRegistryImpl()
+ : weak_factory_(this) {}
AssociatedInterfaceRegistryImpl::~AssociatedInterfaceRegistryImpl() {}
@@ -40,4 +41,9 @@ void AssociatedInterfaceRegistryImpl::RemoveInterface(const std::string& name) {
interfaces_.erase(it);
}
+base::WeakPtr<AssociatedInterfaceRegistryImpl>
+AssociatedInterfaceRegistryImpl::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
} // namespace content
diff --git a/chromium/content/common/associated_interface_registry_impl.h b/chromium/content/common/associated_interface_registry_impl.h
index 4f7431c0497..2e4a107cb04 100644
--- a/chromium/content/common/associated_interface_registry_impl.h
+++ b/chromium/content/common/associated_interface_registry_impl.h
@@ -9,12 +9,14 @@
#include <string>
#include "base/macros.h"
-#include "content/public/common/associated_interface_registry.h"
+#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_registry.h"
namespace content {
-class AssociatedInterfaceRegistryImpl : public AssociatedInterfaceRegistry {
+class AssociatedInterfaceRegistryImpl
+ : public blink::AssociatedInterfaceRegistry {
public:
AssociatedInterfaceRegistryImpl();
~AssociatedInterfaceRegistryImpl() override;
@@ -27,8 +29,11 @@ class AssociatedInterfaceRegistryImpl : public AssociatedInterfaceRegistry {
void AddInterface(const std::string& name, const Binder& binder) override;
void RemoveInterface(const std::string& name) override;
+ base::WeakPtr<AssociatedInterfaceRegistryImpl> GetWeakPtr();
+
private:
std::map<std::string, Binder> interfaces_;
+ base::WeakPtrFactory<AssociatedInterfaceRegistryImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AssociatedInterfaceRegistryImpl);
};
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 f3f95d427ae..becd175c538 100644
--- a/chromium/content/common/background_fetch/background_fetch_struct_traits.cc
+++ b/chromium/content/common/background_fetch/background_fetch_struct_traits.cc
@@ -29,9 +29,7 @@ bool StructTraits<blink::mojom::BackgroundFetchRegistrationDataView,
Read(blink::mojom::BackgroundFetchRegistrationDataView data,
content::BackgroundFetchRegistration* registration) {
if (!data.ReadDeveloperId(&registration->developer_id) ||
- !data.ReadUniqueId(&registration->unique_id) ||
- !data.ReadIcons(&registration->icons) ||
- !data.ReadTitle(&registration->title)) {
+ !data.ReadUniqueId(&registration->unique_id)) {
return false;
}
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 86f4bede1dd..22ccecbc9fc 100644
--- a/chromium/content/common/background_fetch/background_fetch_struct_traits.h
+++ b/chromium/content/common/background_fetch/background_fetch_struct_traits.h
@@ -69,14 +69,6 @@ struct CONTENT_EXPORT
const content::BackgroundFetchRegistration& registration) {
return registration.downloaded;
}
- static const std::vector<content::IconDefinition>& icons(
- const content::BackgroundFetchRegistration& registration) {
- return registration.icons;
- }
- static const std::string& title(
- const content::BackgroundFetchRegistration& registration) {
- return registration.title;
- }
static bool Read(blink::mojom::BackgroundFetchRegistrationDataView data,
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 3d46714493a..3e8c85f1f56 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
@@ -61,10 +61,6 @@ TEST(BackgroundFetchStructTraitsTest, BackgroundFetchRegistrationRoundTrip) {
BackgroundFetchRegistration registration;
registration.developer_id = "my_id";
registration.unique_id = "7e57ab1e-c0de-a150-ca75-1e75f005ba11";
- registration.icons = {
- CreateIconDefinition("my_icon.png", "256x256", "image/png"),
- CreateIconDefinition("my_small_icon.jpg", "128x128", "image/jpg")};
- registration.title = "My Background Fetch";
registration.download_total = 9001;
BackgroundFetchRegistration roundtrip_registration;
@@ -75,13 +71,6 @@ TEST(BackgroundFetchStructTraitsTest, BackgroundFetchRegistrationRoundTrip) {
EXPECT_EQ(roundtrip_registration.developer_id, registration.developer_id);
EXPECT_EQ(roundtrip_registration.unique_id, registration.unique_id);
- ASSERT_EQ(roundtrip_registration.icons.size(), registration.icons.size());
- for (size_t i = 0; i < registration.icons.size(); ++i) {
- EXPECT_TRUE(IconDefinitionsAreIdentical(registration.icons[i],
- roundtrip_registration.icons[i]));
- }
-
- EXPECT_EQ(roundtrip_registration.title, registration.title);
EXPECT_EQ(roundtrip_registration.download_total, registration.download_total);
}
diff --git a/chromium/content/common/background_fetch/background_fetch_types.h b/chromium/content/common/background_fetch/background_fetch_types.h
index 8e57e36644d..685b624c299 100644
--- a/chromium/content/common/background_fetch/background_fetch_types.h
+++ b/chromium/content/common/background_fetch/background_fetch_types.h
@@ -65,10 +65,6 @@ struct CONTENT_EXPORT BackgroundFetchRegistration {
uint64_t download_total = 0;
uint64_t downloaded = 0;
// TODO(crbug.com/699957): Support the `activeFetches` member.
-
- // TODO(crbug.com/769770): Remove the following deprecated members.
- std::vector<IconDefinition> icons;
- std::string title;
};
// Represents a request/response pair for a settled Background Fetch fetch.
diff --git a/chromium/content/common/browser_plugin/browser_plugin_messages.h b/chromium/content/common/browser_plugin/browser_plugin_messages.h
index c147db29a90..6d19348f95b 100644
--- a/chromium/content/common/browser_plugin/browser_plugin_messages.h
+++ b/chromium/content/common/browser_plugin/browser_plugin_messages.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/process/process.h"
+#include "base/unguessable_token.h"
#include "cc/ipc/cc_param_traits.h"
#include "components/viz/common/surfaces/surface_info.h"
#include "content/common/content_export.h"
@@ -15,6 +16,7 @@
#include "content/common/cursors/webcursor.h"
#include "content/common/edit_command.h"
#include "content/public/common/drop_data.h"
+#include "content/public/common/screen_info.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_utils.h"
@@ -40,7 +42,7 @@ IPC_STRUCT_BEGIN(BrowserPluginHostMsg_Attach_Params)
IPC_STRUCT_MEMBER(bool, focused)
IPC_STRUCT_MEMBER(bool, visible)
// The new size of the guest view.
- IPC_STRUCT_MEMBER(gfx::Rect, view_rect)
+ IPC_STRUCT_MEMBER(gfx::Rect, frame_rect)
// Whether the browser plugin is a full page plugin document.
IPC_STRUCT_MEMBER(bool, is_full_page_plugin)
IPC_STRUCT_END()
@@ -141,7 +143,7 @@ IPC_MESSAGE_CONTROL5(BrowserPluginHostMsg_DragStatusUpdate,
blink::WebDragStatus /* drag_status */,
content::DropData /* drop_data */,
blink::WebDragOperationsMask /* operation_mask */,
- gfx::Point /* plugin_location */)
+ gfx::PointF /* plugin_location */)
// Sends a PointerLock Lock ACK to the BrowserPluginGuest.
IPC_MESSAGE_CONTROL2(BrowserPluginHostMsg_LockMouse_ACK,
@@ -153,9 +155,11 @@ IPC_MESSAGE_CONTROL1(BrowserPluginHostMsg_UnlockMouse_ACK,
int /* browser_plugin_instance_id */)
// Sent when plugin's position has changed.
-IPC_MESSAGE_CONTROL3(BrowserPluginHostMsg_UpdateGeometry,
+IPC_MESSAGE_CONTROL5(BrowserPluginHostMsg_UpdateResizeParams,
int /* browser_plugin_instance_id */,
- gfx::Rect /* view_rect */,
+ gfx::Rect /* frame_rect */,
+ content::ScreenInfo /* screen_info */,
+ uint64_t /* sequence_number */,
viz::LocalSurfaceId /* local_surface_id */)
IPC_MESSAGE_ROUTED2(BrowserPluginHostMsg_SatisfySequence,
@@ -185,6 +189,12 @@ IPC_MESSAGE_CONTROL2(BrowserPluginMsg_AdvanceFocus,
int /* browser_plugin_instance_id */,
bool /* reverse */)
+// When a guest resizes due to auto-resize, this message informs the
+// BrowserPlugin to request a new viz::LocalSurfaceId.
+IPC_MESSAGE_CONTROL2(BrowserPluginMsg_ResizeDueToAutoResize,
+ int /* browser_plugin_instance_id */,
+ uint64_t /* sequence_number */)
+
// When the guest starts/stops listening to touch events, it needs to notify the
// plugin in the embedder about it.
IPC_MESSAGE_CONTROL2(BrowserPluginMsg_ShouldAcceptTouchEvents,
@@ -211,4 +221,13 @@ IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetTooltipText,
int /* browser_plugin_instance_id */,
base::string16 /* tooltip_text */)
+#if defined(USE_AURA)
+// Sets the token that is used to embed the guest. |embed_token| is a token
+// that was generated from the window server and is expected to be supplied to
+// EmbedUsingToken().
+IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetMusEmbedToken,
+ int /* browser_plugin_instance_id */,
+ base::UnguessableToken /* embed_token */)
+#endif
+
#endif // CONTENT_COMMON_BROWSER_PLUGIN_BROWSER_PLUGIN_MESSAGES_H_
diff --git a/chromium/content/common/cache_storage/cache_storage_messages.h b/chromium/content/common/cache_storage/cache_storage_messages.h
index 5bf579ec5f9..f739e4bbd75 100644
--- a/chromium/content/common/cache_storage/cache_storage_messages.h
+++ b/chromium/content/common/cache_storage/cache_storage_messages.h
@@ -13,7 +13,7 @@
#include "content/common/service_worker/service_worker_types.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_param_traits.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCacheError.h"
+#include "third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h"
#include "url/origin.h"
#undef IPC_MESSAGE_EXPORT
@@ -42,8 +42,8 @@ IPC_STRUCT_TRAITS_BEGIN(content::CacheStorageBatchOperation)
IPC_STRUCT_TRAITS_MEMBER(match_params)
IPC_STRUCT_TRAITS_END()
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebServiceWorkerCacheError,
- blink::kWebServiceWorkerCacheErrorLast)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::CacheStorageError,
+ blink::mojom::CacheStorageError::kLast)
//---------------------------------------------------------------------------
// Messages sent from the child process to the browser.
@@ -144,19 +144,19 @@ IPC_MESSAGE_CONTROL3(CacheStorageMsg_CacheStorageMatchSuccess,
IPC_MESSAGE_CONTROL3(CacheStorageMsg_CacheStorageHasError,
int /* thread_id */,
int /* request_id */,
- blink::WebServiceWorkerCacheError /* reason */)
+ blink::mojom::CacheStorageError /* reason */)
IPC_MESSAGE_CONTROL3(CacheStorageMsg_CacheStorageOpenError,
int /* thread_id */,
int /* request_id */,
- blink::WebServiceWorkerCacheError /* reason */)
+ blink::mojom::CacheStorageError /* reason */)
IPC_MESSAGE_CONTROL3(CacheStorageMsg_CacheStorageDeleteError,
int /* thread_id */,
int /* request_id */,
- blink::WebServiceWorkerCacheError /* reason */)
+ blink::mojom::CacheStorageError /* reason */)
IPC_MESSAGE_CONTROL3(CacheStorageMsg_CacheStorageMatchError,
int /* thread_id */,
int /* request_id */,
- blink::WebServiceWorkerCacheError)
+ blink::mojom::CacheStorageError)
// Sent at successful completion of Cache operations.
IPC_MESSAGE_CONTROL3(CacheStorageMsg_CacheMatchSuccess,
@@ -179,18 +179,18 @@ IPC_MESSAGE_CONTROL2(CacheStorageMsg_CacheBatchSuccess,
IPC_MESSAGE_CONTROL3(CacheStorageMsg_CacheMatchError,
int /* thread_id */,
int /* request_id */,
- blink::WebServiceWorkerCacheError)
+ blink::mojom::CacheStorageError)
IPC_MESSAGE_CONTROL3(CacheStorageMsg_CacheMatchAllError,
int /* thread_id */,
int /* request_id */,
- blink::WebServiceWorkerCacheError)
+ blink::mojom::CacheStorageError)
IPC_MESSAGE_CONTROL3(CacheStorageMsg_CacheKeysError,
int /* thread_id */,
int /* request_id */,
- blink::WebServiceWorkerCacheError)
+ blink::mojom::CacheStorageError)
IPC_MESSAGE_CONTROL3(CacheStorageMsg_CacheBatchError,
int /* thread_id */,
int /* request_id */,
- blink::WebServiceWorkerCacheError)
+ blink::mojom::CacheStorageError)
#endif // CONTENT_COMMON_CACHE_STORAGE_CACHE_STORAGE_MESSAGES_H_
diff --git a/chromium/content/common/cache_storage/cache_storage_types.h b/chromium/content/common/cache_storage/cache_storage_types.h
index fb04e5b72cf..61d8b769170 100644
--- a/chromium/content/common/cache_storage/cache_storage_types.h
+++ b/chromium/content/common/cache_storage/cache_storage_types.h
@@ -47,19 +47,6 @@ struct CONTENT_EXPORT CacheStorageBatchOperation {
CacheStorageCacheQueryParams match_params;
};
-// This enum is used in histograms, so do not change the ordering and always
-// append new types to the end.
-enum CacheStorageError {
- CACHE_STORAGE_OK = 0,
- CACHE_STORAGE_ERROR_EXISTS,
- CACHE_STORAGE_ERROR_STORAGE,
- CACHE_STORAGE_ERROR_NOT_FOUND,
- CACHE_STORAGE_ERROR_QUOTA_EXCEEDED,
- CACHE_STORAGE_ERROR_CACHE_NAME_NOT_FOUND,
- CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
- CACHE_STORAGE_ERROR_LAST = CACHE_STORAGE_ERROR_QUERY_TOO_LARGE
-};
-
} // namespace content
#endif // CONTENT_COMMON_CACHE_STORAGE_CACHE_STORAGE_TYPES_H_
diff --git a/chromium/content/common/child_control.mojom b/chromium/content/common/child_control.mojom
new file mode 100644
index 00000000000..a73a317a3fe
--- /dev/null
+++ b/chromium/content/common/child_control.mojom
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+interface ChildControl {
+ // Tell the child process that it's safe to shutdown.
+ ProcessShutdown();
+
+ // Tell the child process to begin or end IPC message logging.
+ SetIPCLoggingEnabled(bool on);
+};
diff --git a/chromium/content/common/child_process_host_impl.cc b/chromium/content/common/child_process_host_impl.cc
index 55ba42c8c38..f27de00d968 100644
--- a/chromium/content/common/child_process_host_impl.cc
+++ b/chromium/content/common/child_process_host_impl.cc
@@ -22,7 +22,7 @@
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
-#include "content/common/child_process_messages.h"
+#include "content/public/common/bind_interface_helpers.h"
#include "content/public/common/child_process_host_delegate.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
@@ -36,8 +36,6 @@
#if defined(OS_LINUX)
#include "base/linux_util.h"
-#elif defined(OS_WIN)
-#include "content/common/font_cache_dispatcher_win.h"
#endif // OS_LINUX
namespace {
@@ -79,12 +77,7 @@ base::FilePath ChildProcessHost::GetChildPath(int flags) {
}
ChildProcessHostImpl::ChildProcessHostImpl(ChildProcessHostDelegate* delegate)
- : delegate_(delegate),
- opening_channel_(false) {
-#if defined(OS_WIN)
- AddFilter(new FontCacheDispatcher());
-#endif
-}
+ : delegate_(delegate), opening_channel_(false) {}
ChildProcessHostImpl::~ChildProcessHostImpl() {
// If a channel was never created than it wasn't registered and the filters
@@ -113,15 +106,15 @@ void ChildProcessHostImpl::BindInterface(
}
void ChildProcessHostImpl::ForceShutdown() {
- Send(new ChildProcessMsg_Shutdown());
+ child_control_->ProcessShutdown();
}
void ChildProcessHostImpl::CreateChannelMojo() {
-
mojo::MessagePipe pipe;
BindInterface(IPC::mojom::ChannelBootstrap::Name_, std::move(pipe.handle1));
- channel_ = IPC::ChannelMojo::Create(std::move(pipe.handle0),
- IPC::Channel::MODE_SERVER, this);
+ channel_ = IPC::ChannelMojo::Create(
+ std::move(pipe.handle0), IPC::Channel::MODE_SERVER, this,
+ base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get());
DCHECK(channel_);
bool initialized = InitChannel();
@@ -134,12 +127,20 @@ bool ChildProcessHostImpl::InitChannel() {
for (size_t i = 0; i < filters_.size(); ++i)
filters_[i]->OnFilterAdded(channel_.get());
+
delegate_->OnChannelInitialized(channel_.get());
+ // We want to bind this interface as early as possible, but the constructor is
+ // too early. |delegate_| may not be fully initialized at that point and thus
+ // may be unable to properly fulfill the BindInterface() call. Instead we bind
+ // here since the |delegate_| has already been initialized and this is the
+ // first potential use of the interface.
+ content::BindInterface(this, &child_control_);
+
// Make sure these messages get sent first.
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
bool enabled = IPC::Logging::GetInstance()->Enabled();
- Send(new ChildProcessMsg_SetIPCLoggingEnabled(enabled));
+ child_control_->SetIPCLoggingEnabled(enabled);
#endif
opening_channel_ = true;
@@ -212,14 +213,6 @@ bool ChildProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
}
if (!handled) {
- handled = true;
- IPC_BEGIN_MESSAGE_MAP(ChildProcessHostImpl, msg)
- IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
- OnShutdownRequest)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- if (!handled)
handled = delegate_->OnMessageReceived(msg);
}
@@ -258,9 +251,4 @@ void ChildProcessHostImpl::OnBadMessageReceived(const IPC::Message& message) {
delegate_->OnBadMessageReceived(message);
}
-void ChildProcessHostImpl::OnShutdownRequest() {
- if (delegate_->CanShutdown())
- Send(new ChildProcessMsg_Shutdown());
-}
-
} // namespace content
diff --git a/chromium/content/common/child_process_host_impl.h b/chromium/content/common/child_process_host_impl.h
index f2d371b4033..659cffaf25d 100644
--- a/chromium/content/common/child_process_host_impl.h
+++ b/chromium/content/common/child_process_host_impl.h
@@ -18,6 +18,7 @@
#include "base/process/process.h"
#include "base/strings/string16.h"
#include "build/build_config.h"
+#include "content/common/child_control.mojom.h"
#include "content/public/common/child_process_host.h"
#include "ipc/ipc_listener.h"
@@ -81,9 +82,6 @@ class CONTENT_EXPORT ChildProcessHostImpl : public ChildProcessHost,
void OnChannelError() override;
void OnBadMessageReceived(const IPC::Message& message) override;
- // Message handlers:
- void OnShutdownRequest();
-
// Initializes the IPC channel and returns true on success. |channel_| must be
// non-null.
bool InitChannel();
@@ -92,6 +90,7 @@ class CONTENT_EXPORT ChildProcessHostImpl : public ChildProcessHost,
base::Process peer_process_;
bool opening_channel_; // True while we're waiting the channel to be opened.
std::unique_ptr<IPC::Channel> channel_;
+ mojom::ChildControlPtr child_control_;
// Holds all the IPC message filters. Since this object lives on the IO
// thread, we don't have a IPC::ChannelProxy and so we manage filters
diff --git a/chromium/content/common/child_process_messages.h b/chromium/content/common/child_process_messages.h
deleted file mode 100644
index 0d955a33036..00000000000
--- a/chromium/content/common/child_process_messages.h
+++ /dev/null
@@ -1,106 +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_CHILD_PROCESS_MESSAGES_H_
-#define CONTENT_COMMON_CHILD_PROCESS_MESSAGES_H_
-
-// Common IPC messages used for child processes.
-
-#include <stdint.h>
-
-#include <string>
-#include <vector>
-
-#include "base/memory/shared_memory.h"
-#include "base/values.h"
-#include "build/build_config.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
-#include "content/common/content_export.h"
-#include "content/common/content_param_traits_macros.h"
-#include "gpu/command_buffer/common/sync_token.h"
-#include "gpu/ipc/common/gpu_param_traits_macros.h"
-#include "ipc/ipc_channel_handle.h"
-#include "ipc/ipc_features.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_platform_file.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/ipc/gfx_param_traits.h"
-#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
-
-#if defined(OS_LINUX)
-#include "base/threading/platform_thread.h"
-#endif
-
-IPC_STRUCT_TRAITS_BEGIN(base::LocationSnapshot)
- IPC_STRUCT_TRAITS_MEMBER(file_name)
- IPC_STRUCT_TRAITS_MEMBER(function_name)
- IPC_STRUCT_TRAITS_MEMBER(line_number)
-IPC_STRUCT_TRAITS_END()
-
-#if defined(OS_LINUX)
-IPC_ENUM_TRAITS_MAX_VALUE(base::ThreadPriority,
- base::ThreadPriority::REALTIME_AUDIO)
-#endif
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
-
-#define IPC_MESSAGE_START ChildProcessMsgStart
-
-// Messages sent from the browser to the child process.
-
-// Sent in response to ChildProcessHostMsg_ShutdownRequest to tell the child
-// process that it's safe to shutdown.
-IPC_MESSAGE_CONTROL0(ChildProcessMsg_Shutdown)
-
-#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
-// Tell the child process to begin or end IPC message logging.
-IPC_MESSAGE_CONTROL1(ChildProcessMsg_SetIPCLoggingEnabled,
- bool /* on or off */)
-#endif
-
-// Sent to child processes to tell them to enter or leave background mode.
-IPC_MESSAGE_CONTROL1(ChildProcessMsg_SetProcessBackgrounded,
- bool /* background */)
-
-// Sent to child processes to tell them to purge and suspend.
-IPC_MESSAGE_CONTROL0(ChildProcessMsg_PurgeAndSuspend)
-
-// Sent to child processes to tell them to resume from suspended mode.
-IPC_MESSAGE_CONTROL0(ChildProcessMsg_Resume)
-
-////////////////////////////////////////////////////////////////////////////////
-// Messages sent from the child process to the browser.
-
-// A renderer sends this when it wants to know whether a gpu process exists.
-IPC_SYNC_MESSAGE_CONTROL0_1(ChildProcessHostMsg_HasGpuProcess,
- bool /* result */)
-
-IPC_MESSAGE_CONTROL0(ChildProcessHostMsg_ShutdownRequest)
-
-// Request a histogram from the browser. The browser will send the histogram
-// data only if it has been passed the command line flag
-// switches::kDomAutomationController.
-IPC_SYNC_MESSAGE_CONTROL1_1(ChildProcessHostMsg_GetBrowserHistogram,
- std::string, /* histogram_name */
- std::string /* histogram_json */)
-
-#if defined(OS_WIN)
-// Request that the given font be loaded by the host so it's cached by the
-// OS. Please see ChildProcessHost::PreCacheFont for details.
-IPC_SYNC_MESSAGE_CONTROL1_0(ChildProcessHostMsg_PreCacheFont,
- LOGFONT /* font data */)
-
-// Release the cached font
-IPC_MESSAGE_CONTROL0(ChildProcessHostMsg_ReleaseCachedFonts)
-#endif // defined(OS_WIN)
-
-#if defined(OS_LINUX)
-// Asks the browser to change the priority of thread.
-IPC_MESSAGE_CONTROL2(ChildProcessHostMsg_SetThreadPriority,
- base::PlatformThreadId,
- base::ThreadPriority)
-#endif
-
-#endif // CONTENT_COMMON_CHILD_PROCESS_MESSAGES_H_
diff --git a/chromium/content/common/clipboard.mojom b/chromium/content/common/clipboard.mojom
new file mode 100644
index 00000000000..6e12b2732bb
--- /dev/null
+++ b/chromium/content/common/clipboard.mojom
@@ -0,0 +1,85 @@
+// Copyright 2017 The Chromium 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 "mojo/common/string16.mojom";
+import "ui/base/clipboard/mojom/clipboard.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
+import "url/mojo/url.mojom";
+
+enum ClipboardFormat {
+ kPlaintext,
+ kHtml,
+ kSmartPaste,
+ kBookmark,
+};
+
+interface ClipboardHost {
+ [Sync]
+ GetSequenceNumber(ui.mojom.ClipboardType type) => (uint64 result);
+
+ [Sync]
+ IsFormatAvailable(ClipboardFormat format,
+ ui.mojom.ClipboardType type) => (bool result);
+
+ [Sync]
+ ReadAvailableTypes(ui.mojom.ClipboardType type) =>
+ (array<mojo.common.mojom.String16> types, bool result);
+
+ [Sync]
+ ReadText(ui.mojom.ClipboardType type) => (mojo.common.mojom.String16 result);
+
+ [Sync]
+ ReadHtml(ui.mojom.ClipboardType type) => (mojo.common.mojom.String16 markup,
+ url.mojom.Url url,
+ uint32 fragment_start,
+ uint32 fragment_end);
+
+ [Sync]
+ ReadRtf(ui.mojom.ClipboardType type) => (string result);
+
+ [Sync]
+ ReadImage(ui.mojom.ClipboardType type) => (string blob_uuid,
+ string mime_type,
+ int64 size);
+
+ [Sync]
+ ReadCustomData(ui.mojom.ClipboardType clipboard_type,
+ mojo.common.mojom.String16 type) =>
+ (mojo.common.mojom.String16 result);
+
+ // Writing to the clipboard via IPC is a two-phase operation. First, the
+ // sender sends the different types of data it'd like to write to the
+ // receiver. Then, it sends a commit message to commit the data to the system
+ // clipboard.
+ WriteText(ui.mojom.ClipboardType type, mojo.common.mojom.String16 text);
+
+ WriteHtml(ui.mojom.ClipboardType type,
+ mojo.common.mojom.String16 markup,
+ url.mojom.Url url);
+
+ WriteSmartPasteMarker(ui.mojom.ClipboardType type);
+
+ WriteCustomData(
+ ui.mojom.ClipboardType type,
+ map<mojo.common.mojom.String16, mojo.common.mojom.String16> data);
+
+ // TODO(dcheng): The |url| parameter should really be a GURL, but <canvas>'s
+ // copy as image tries to set very long data: URLs on the clipboard. Using
+ // GURL causes the browser to kill the renderer for sending a bad IPC (GURLs
+ // bigger than 2 megabytes are considered to be bad). https://crbug.com/459822
+ WriteBookmark(ui.mojom.ClipboardType type,
+ string url,
+ mojo.common.mojom.String16 title);
+
+ WriteImage(ui.mojom.ClipboardType type,
+ gfx.mojom.Size size_in_pixels,
+ handle<shared_buffer> shared_buffer_handle);
+
+ CommitWrite(ui.mojom.ClipboardType type);
+
+ // OS_MACOSX only
+ WriteStringToFindPboard(mojo.common.mojom.String16 text);
+};
diff --git a/chromium/content/common/clipboard.typemap b/chromium/content/common/clipboard.typemap
new file mode 100644
index 00000000000..6eda0c1227c
--- /dev/null
+++ b/chromium/content/common/clipboard.typemap
@@ -0,0 +1,11 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//content/common/clipboard.mojom"
+public_headers = [ "//content/common/clipboard_format.h" ]
+public_deps = [
+ "//ui/base",
+]
+traits_headers = [ "//content/common/clipboard_struct_traits.h" ]
+type_mappings = [ "content.mojom.ClipboardFormat=content::ClipboardFormat" ]
diff --git a/chromium/content/common/clipboard_messages.h b/chromium/content/common/clipboard_messages.h
deleted file mode 100644
index 3b3d1be12cf..00000000000
--- a/chromium/content/common/clipboard_messages.h
+++ /dev/null
@@ -1,117 +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_CLIPBOARD_MESSAGES_H_
-#define CONTENT_COMMON_CLIPBOARD_MESSAGES_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "build/build_config.h"
-#include "base/memory/shared_memory.h"
-#include "base/strings/string16.h"
-#include "build/build_config.h"
-#include "content/common/clipboard_format.h"
-#include "content/common/content_export.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/param_traits_macros.h"
-#include "ui/base/clipboard/clipboard.h"
-#include "ui/gfx/geometry/size.h"
-#include "url/ipc/url_param_traits.h"
-
-// Singly-included section for types and/or struct declarations.
-#ifndef INTERNAL_CONTENT_COMMON_CLIPBOARD_MESSAGES_H_
-#define INTERNAL_CONTENT_COMMON_CLIPBOARD_MESSAGES_H_
-
-// Custom data consists of arbitrary MIME types an untrusted sender wants to
-// write to the clipboard. Note that exposing a general interface to do this is
-// dangerous--an untrusted sender could cause a DoS or code execution.
-typedef std::map<base::string16, base::string16> CustomDataMap;
-
-#endif // INTERNAL_CONTENT_COMMON_CLIPBOARD_MESSAGES_H_
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
-
-#define IPC_MESSAGE_START ClipboardMsgStart
-
-IPC_ENUM_TRAITS_MAX_VALUE(content::ClipboardFormat,
- content::CLIPBOARD_FORMAT_LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(ui::ClipboardType, ui::CLIPBOARD_TYPE_LAST)
-
-// Clipboard IPC messages sent from the renderer to the browser.
-
-IPC_SYNC_MESSAGE_CONTROL1_1(ClipboardHostMsg_GetSequenceNumber,
- ui::ClipboardType /* type */,
- uint64_t /* result */)
-IPC_SYNC_MESSAGE_CONTROL2_1(ClipboardHostMsg_IsFormatAvailable,
- content::ClipboardFormat /* format */,
- ui::ClipboardType /* type */,
- bool /* result */)
-IPC_MESSAGE_CONTROL1(ClipboardHostMsg_Clear,
- ui::ClipboardType /* type */)
-IPC_SYNC_MESSAGE_CONTROL1_2(ClipboardHostMsg_ReadAvailableTypes,
- ui::ClipboardType /* type */,
- std::vector<base::string16> /* types */,
- bool /* contains filenames */)
-IPC_SYNC_MESSAGE_CONTROL1_1(ClipboardHostMsg_ReadText,
- ui::ClipboardType /* type */,
- base::string16 /* result */)
-IPC_SYNC_MESSAGE_CONTROL1_4(ClipboardHostMsg_ReadHTML,
- ui::ClipboardType /* type */,
- base::string16 /* markup */,
- GURL /* url */,
- uint32_t /* fragment start */,
- uint32_t /* fragment end */)
-IPC_SYNC_MESSAGE_CONTROL1_1(ClipboardHostMsg_ReadRTF,
- ui::ClipboardType /* type */,
- std::string /* result */)
-IPC_SYNC_MESSAGE_CONTROL1_3(ClipboardHostMsg_ReadImage,
- ui::ClipboardType /* type */,
- std::string /* blob_uuid */,
- std::string /* mime_type */,
- int64_t /* size */)
-IPC_SYNC_MESSAGE_CONTROL2_1(ClipboardHostMsg_ReadCustomData,
- ui::ClipboardType /* type */,
- base::string16 /* type */,
- base::string16 /* result */)
-
-// Writing to the clipboard via IPC is a two-phase operation. First, the sender
-// sends the different types of data it'd like to write to the receiver. Then,
-// it sends a commit message to commit the data to the system clipboard.
-IPC_MESSAGE_CONTROL2(ClipboardHostMsg_WriteText,
- ui::ClipboardType /* type */,
- base::string16 /* text */)
-IPC_MESSAGE_CONTROL3(ClipboardHostMsg_WriteHTML,
- ui::ClipboardType /* type */,
- base::string16 /* markup */,
- GURL /* url */)
-IPC_MESSAGE_CONTROL1(ClipboardHostMsg_WriteSmartPasteMarker,
- ui::ClipboardType /* type */)
-IPC_MESSAGE_CONTROL2(ClipboardHostMsg_WriteCustomData,
- ui::ClipboardType /* type */,
- CustomDataMap /* custom data */)
-// TODO(dcheng): The |url| parameter should really be a GURL, but <canvas>'s
-// copy as image tries to set very long data: URLs on the clipboard. Using
-// GURL causes the browser to kill the renderer for sending a bad IPC (GURLs
-// bigger than 2 megabytes are considered to be bad). https://crbug.com/459822
-IPC_MESSAGE_CONTROL3(ClipboardHostMsg_WriteBookmark,
- ui::ClipboardType /* type */,
- std::string /* url */,
- base::string16 /* title */)
-IPC_SYNC_MESSAGE_CONTROL3_0(ClipboardHostMsg_WriteImage,
- ui::ClipboardType /* type */,
- gfx::Size /* size */,
- base::SharedMemoryHandle /* bitmap handle */)
-IPC_MESSAGE_CONTROL1(ClipboardHostMsg_CommitWrite, ui::ClipboardType /* type */)
-
-#if defined(OS_MACOSX)
-IPC_MESSAGE_CONTROL1(ClipboardHostMsg_FindPboardWriteStringAsync,
- base::string16 /* text */)
-#endif
-
-#endif // CONTENT_COMMON_CLIPBOARD_MESSAGES_H_
diff --git a/chromium/content/common/clipboard_struct_traits.h b/chromium/content/common/clipboard_struct_traits.h
new file mode 100644
index 00000000000..efc23b7a5cb
--- /dev/null
+++ b/chromium/content/common/clipboard_struct_traits.h
@@ -0,0 +1,54 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_CLIPBOARD_STRUCT_TRAITS_H_
+#define CONTENT_COMMON_CLIPBOARD_STRUCT_TRAITS_H_
+
+#include "content/common/clipboard.mojom.h"
+#include "content/common/clipboard_format.h"
+#include "mojo/public/cpp/bindings/enum_traits.h"
+
+namespace mojo {
+
+template <>
+struct EnumTraits<content::mojom::ClipboardFormat, content::ClipboardFormat> {
+ static content::mojom::ClipboardFormat ToMojom(
+ content::ClipboardFormat clipboard_format) {
+ switch (clipboard_format) {
+ case content::CLIPBOARD_FORMAT_PLAINTEXT:
+ return content::mojom::ClipboardFormat::kPlaintext;
+ case content::CLIPBOARD_FORMAT_HTML:
+ return content::mojom::ClipboardFormat::kHtml;
+ case content::CLIPBOARD_FORMAT_SMART_PASTE:
+ return content::mojom::ClipboardFormat::kSmartPaste;
+ case content::CLIPBOARD_FORMAT_BOOKMARK:
+ return content::mojom::ClipboardFormat::kBookmark;
+ }
+ NOTREACHED();
+ return content::mojom::ClipboardFormat::kPlaintext;
+ }
+
+ static bool FromMojom(content::mojom::ClipboardFormat clipboard_format,
+ content::ClipboardFormat* out) {
+ switch (clipboard_format) {
+ case content::mojom::ClipboardFormat::kPlaintext:
+ *out = content::CLIPBOARD_FORMAT_PLAINTEXT;
+ return true;
+ case content::mojom::ClipboardFormat::kHtml:
+ *out = content::CLIPBOARD_FORMAT_HTML;
+ return true;
+ case content::mojom::ClipboardFormat::kSmartPaste:
+ *out = content::CLIPBOARD_FORMAT_SMART_PASTE;
+ return true;
+ case content::mojom::ClipboardFormat::kBookmark:
+ *out = content::CLIPBOARD_FORMAT_BOOKMARK;
+ return true;
+ }
+ return false;
+ }
+};
+
+} // namespace mojo
+
+#endif // CONTENT_COMMON_CLIPBOARD_STRUCT_TRAITS_H_
diff --git a/chromium/content/common/common_param_traits_unittest.cc b/chromium/content/common/common_param_traits_unittest.cc
index ea3ac26a2c4..915ca4240df 100644
--- a/chromium/content/common/common_param_traits_unittest.cc
+++ b/chromium/content/common/common_param_traits_unittest.cc
@@ -91,7 +91,7 @@ TEST(IPCMessageTest, ListValue) {
base::ListValue input;
input.AppendDouble(42.42);
input.AppendString("forty");
- input.Append(base::MakeUnique<base::Value>());
+ input.Append(std::make_unique<base::Value>());
IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
IPC::WriteParam(&msg, input);
@@ -111,15 +111,15 @@ TEST(IPCMessageTest, ListValue) {
TEST(IPCMessageTest, DictionaryValue) {
base::DictionaryValue input;
- input.Set("null", base::MakeUnique<base::Value>());
+ input.Set("null", std::make_unique<base::Value>());
input.SetBoolean("bool", true);
input.SetInteger("int", 42);
- auto subdict = base::MakeUnique<base::DictionaryValue>();
+ auto subdict = std::make_unique<base::DictionaryValue>();
subdict->SetString("str", "forty two");
subdict->SetBoolean("bool", false);
- auto sublist = base::MakeUnique<base::ListValue>();
+ auto sublist = std::make_unique<base::ListValue>();
sublist->AppendDouble(42.42);
sublist->AppendString("forty");
sublist->AppendString("two");
@@ -194,9 +194,8 @@ TEST(IPCMessageTest, SSLInfo) {
net::SignedCertificateTimestampAndStatus(
sct, net::ct::SCT_STATUS_LOG_UNKNOWN));
- in.ct_compliance_details_available = true;
- in.ct_cert_policy_compliance =
- net::ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+ in.ct_policy_compliance =
+ net::ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
in.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
in.ocsp_result.revocation_status = net::OCSPRevocationStatus::REVOKED;
@@ -248,9 +247,7 @@ TEST(IPCMessageTest, SSLInfo) {
ASSERT_EQ(in.signed_certificate_timestamps[0].sct->log_description,
out.signed_certificate_timestamps[0].sct->log_description);
- ASSERT_EQ(in.ct_compliance_details_available,
- out.ct_compliance_details_available);
- ASSERT_EQ(in.ct_cert_policy_compliance, out.ct_cert_policy_compliance);
+ ASSERT_EQ(in.ct_policy_compliance, out.ct_policy_compliance);
ASSERT_EQ(in.ocsp_result, out.ocsp_result);
}
diff --git a/chromium/content/common/common_sandbox_support_linux.cc b/chromium/content/common/common_sandbox_support_linux.cc
index bf876b677dd..ed806b7f998 100644
--- a/chromium/content/common/common_sandbox_support_linux.cc
+++ b/chromium/content/common/common_sandbox_support_linux.cc
@@ -13,10 +13,12 @@
#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/posix/eintr_wrapper.h"
+#include "base/posix/global_descriptors.h"
#include "base/posix/unix_domain_socket.h"
#include "base/sys_byteorder.h"
#include "base/trace_event/trace_event.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
+#include "content/public/common/content_descriptors.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
namespace content {
@@ -97,7 +99,8 @@ bool GetFontTable(int fd,
int MakeSharedMemorySegmentViaIPC(size_t length, bool executable) {
base::Pickle request;
- request.WriteInt(LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT);
+ request.WriteInt(
+ service_manager::SandboxLinux::METHOD_MAKE_SHARED_MEMORY_SEGMENT);
request.WriteUInt32(length);
request.WriteBool(executable);
uint8_t reply_buf[10];
@@ -109,4 +112,8 @@ int MakeSharedMemorySegmentViaIPC(size_t length, bool executable) {
return result_fd;
}
+int GetSandboxFD() {
+ return kSandboxIPCChannel + base::GlobalDescriptors::kBaseDescriptor;
+}
+
} // namespace content
diff --git a/chromium/content/common/content_message_generator.h b/chromium/content/common/content_message_generator.h
index ef635e6024f..d125b0907ec 100644
--- a/chromium/content/common/content_message_generator.h
+++ b/chromium/content/common/content_message_generator.h
@@ -4,12 +4,6 @@
// Multiply-included file, hence no include guard.
-#undef CONTENT_COMMON_CHILD_PROCESS_MESSAGES_H_
-#include "content/common/child_process_messages.h"
-#ifndef CONTENT_COMMON_CHILD_PROCESS_MESSAGES_H_
-#error "Failed to include content/common/child_process_messages.h"
-#endif
-
#include "build/build_config.h"
#undef CONTENT_COMMON_ACCESSIBILITY_MESSAGES_H_
#include "content/common/accessibility_messages.h"
@@ -32,11 +26,6 @@
#ifndef CONTENT_COMMON_CACHE_STORAGE_CACHE_STORAGE_MESSAGES_H_
#error "Failed to include content/common/cache_storage/cache_storage_messages.h"
#endif
-#undef CONTENT_COMMON_CLIPBOARD_MESSAGES_H_
-#include "content/common/clipboard_messages.h"
-#ifndef CONTENT_COMMON_CLIPBOARD_MESSAGES_H_
-#error "Failed to include content/common/clipboard_messages.h"
-#endif
#undef CONTENT_COMMON_DEVTOOLS_MESSAGES_H_
#include "content/common/devtools_messages.h"
#ifndef CONTENT_COMMON_DEVTOOLS_MESSAGES_H_
@@ -115,16 +104,6 @@
#ifndef CONTENT_COMMON_PLATFORM_NOTIFICATION_MESSAGES_H_
#error "Failed to include content/common/platform_notification_messages.h"
#endif
-#undef CONTENT_COMMON_QUOTA_MESSAGES_H_
-#include "content/common/quota_messages.h"
-#ifndef CONTENT_COMMON_QUOTA_MESSAGES_H_
-#error "Failed to include content/common/quota_messages.h"
-#endif
-#undef CONTENT_COMMON_RENDER_PROCESS_MESSAGES_H_
-#include "content/common/render_process_messages.h"
-#ifndef CONTENT_COMMON_RENDER_PROCESS_MESSAGES_H_
-#error "Failed to include content/common/render_process_messages.h"
-#endif
#undef CONTENT_COMMON_RESOURCE_MESSAGES_H_
#include "content/common/resource_messages.h"
#ifndef CONTENT_COMMON_RESOURCE_MESSAGES_H_
diff --git a/chromium/content/common/content_param_traits.cc b/chromium/content/common/content_param_traits.cc
index 81ed82b7cc0..0a170fe1fd2 100644
--- a/chromium/content/common/content_param_traits.cc
+++ b/chromium/content/common/content_param_traits.cc
@@ -123,8 +123,8 @@ bool ParamTraits<scoped_refptr<storage::BlobHandle>>::Read(
if (!MojoMessageHelper::ReadMessagePipeFrom(m, iter, &handle))
return false;
DCHECK(handle.is_valid());
- storage::mojom::BlobPtr blob;
- blob.Bind(storage::mojom::BlobPtrInfo(std::move(handle), version));
+ blink::mojom::BlobPtr blob;
+ blob.Bind(blink::mojom::BlobPtrInfo(std::move(handle), version));
*r = base::MakeRefCounted<storage::BlobHandle>(std::move(blob));
return true;
}
diff --git a/chromium/content/common/content_param_traits_macros.h b/chromium/content/common/content_param_traits_macros.h
index afb9838ea3a..f7f8ea94725 100644
--- a/chromium/content/common/content_param_traits_macros.h
+++ b/chromium/content/common/content_param_traits_macros.h
@@ -11,16 +11,15 @@
#include "cc/ipc/cc_param_traits.h"
#include "content/common/content_export.h"
#include "content/common/download/mhtml_save_status.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/common/render_widget_surface_properties.h"
+#include "content/public/common/input_event_ack_state.h"
#include "content/public/common/request_context_frame_type.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/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/WebAddressSpace.h"
#include "third_party/WebKit/public/platform/WebContentSecurityPolicy.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
#include "third_party/WebKit/public/web/WebImeTextSpan.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/ipc/geometry/gfx_param_traits.h"
@@ -30,8 +29,6 @@
IPC_ENUM_TRAITS_MAX_VALUE(content::InputEventAckState,
content::INPUT_EVENT_ACK_STATE_MAX)
-IPC_ENUM_TRAITS_MAX_VALUE(content::ResourceType,
- content::RESOURCE_TYPE_LAST_TYPE - 1)
IPC_ENUM_TRAITS_MAX_VALUE(content::RequestContextType,
content::REQUEST_CONTEXT_TYPE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(content::RequestContextFrameType,
@@ -46,8 +43,8 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::WebAddressSpace, blink::kWebAddressSpaceLast)
IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::WebInputEvent::Type,
blink::WebInputEvent::kTypeFirst,
blink::WebInputEvent::kTypeLast)
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebPageVisibilityState,
- blink::kWebPageVisibilityStateLast)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::PageVisibilityState,
+ blink::mojom::PageVisibilityState::kLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebImeTextSpan::Type,
blink::WebImeTextSpan::Type::kMisspellingSuggestion)
diff --git a/chromium/content/common/content_security_policy/csp_context_unittest.cc b/chromium/content/common/content_security_policy/csp_context_unittest.cc
index d3a7c161280..ae5d6b965c4 100644
--- a/chromium/content/common/content_security_policy/csp_context_unittest.cc
+++ b/chromium/content/common/content_security_policy/csp_context_unittest.cc
@@ -85,7 +85,7 @@ TEST(CSPContextTest, SchemeShouldBypassCSP) {
TEST(CSPContextTest, MultiplePolicies) {
CSPContextTest context;
- context.SetSelf(url::Origin(GURL("http://example.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://example.com")));
CSPSource source_a("", "a.com", false, url::PORT_UNSPECIFIED, false, "");
CSPSource source_b("", "b.com", false, url::PORT_UNSPECIFIED, false, "");
@@ -112,7 +112,7 @@ TEST(CSPContextTest, MultiplePolicies) {
TEST(CSPContextTest, SanitizeDataForUseInCspViolation) {
CSPContextTest context;
- context.SetSelf(url::Origin(GURL("http://a.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://a.com")));
// Content-Security-Policy: frame-src "a.com/iframe"
context.AddContentSecurityPolicy(
@@ -162,7 +162,7 @@ TEST(CSPContextTest, SanitizeDataForUseInCspViolation) {
// When several policies are infringed, all of them must be reported.
TEST(CSPContextTest, MultipleInfringement) {
CSPContextTest context;
- context.SetSelf(url::Origin(GURL("http://example.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://example.com")));
CSPSource source_a("", "a.com", false, url::PORT_UNSPECIFIED, false, "");
CSPSource source_b("", "b.com", false, url::PORT_UNSPECIFIED, false, "");
diff --git a/chromium/content/common/content_security_policy/csp_source_list_unittest.cc b/chromium/content/common/content_security_policy/csp_source_list_unittest.cc
index 1f4f001991c..20115b731a3 100644
--- a/chromium/content/common/content_security_policy/csp_source_list_unittest.cc
+++ b/chromium/content/common/content_security_policy/csp_source_list_unittest.cc
@@ -23,7 +23,7 @@ bool Allow(const CSPSourceList& source_list,
TEST(CSPSourceList, MultipleSource) {
CSPContext context;
- context.SetSelf(url::Origin(GURL("http://example.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://example.com")));
CSPSourceList source_list(
false, // allow_self
false, // allow_star:
@@ -36,7 +36,7 @@ TEST(CSPSourceList, MultipleSource) {
TEST(CSPSourceList, AllowStar) {
CSPContext context;
- context.SetSelf(url::Origin(GURL("http://example.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://example.com")));
CSPSourceList source_list(false, // allow_self
true, // allow_star:
std::vector<CSPSource>()); // source_list
@@ -52,14 +52,14 @@ TEST(CSPSourceList, AllowStar) {
EXPECT_FALSE(Allow(source_list, GURL("applewebdata://a.test"), &context));
// With a protocol of 'file', '*' allow 'file:'
- context.SetSelf(url::Origin(GURL("file://example.com")));
+ context.SetSelf(url::Origin::Create(GURL("file://example.com")));
EXPECT_TRUE(Allow(source_list, GURL("file://not-example.com"), &context));
EXPECT_FALSE(Allow(source_list, GURL("applewebdata://a.test"), &context));
}
TEST(CSPSourceList, AllowSelf) {
CSPContext context;
- context.SetSelf(url::Origin(GURL("http://example.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://example.com")));
CSPSourceList source_list(true, // allow_self
false, // allow_star:
std::vector<CSPSource>()); // source_list
@@ -71,7 +71,7 @@ TEST(CSPSourceList, AllowSelf) {
TEST(CSPSourceList, AllowStarAndSelf) {
CSPContext context;
- context.SetSelf(url::Origin(GURL("https://a.com")));
+ context.SetSelf(url::Origin::Create(GURL("https://a.com")));
CSPSourceList source_list(false, // allow_self
false, // allow_star
std::vector<CSPSource>());
@@ -91,7 +91,7 @@ TEST(CSPSourceList, AllowStarAndSelf) {
TEST(CSPSourceList, AllowSelfWithUnspecifiedPort) {
CSPContext context;
- context.SetSelf(url::Origin(GURL("chrome://print")));
+ context.SetSelf(url::Origin::Create(GURL("chrome://print")));
CSPSourceList source_list(true, // allow_self
false, // allow_star:
std::vector<CSPSource>()); // source_list
@@ -104,7 +104,7 @@ TEST(CSPSourceList, AllowSelfWithUnspecifiedPort) {
TEST(CSPSourceList, AllowNone) {
CSPContext context;
- context.SetSelf(url::Origin(GURL("http://example.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://example.com")));
CSPSourceList source_list(false, // allow_self
false, // allow_star:
std::vector<CSPSource>()); // source_list
@@ -119,11 +119,12 @@ TEST(CSPSourceTest, SelfIsUnique) {
std::vector<CSPSource>()); // source_list
CSPContext context;
- context.SetSelf(url::Origin(GURL("http://a.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://a.com")));
EXPECT_TRUE(Allow(source_list, GURL("http://a.com"), &context));
EXPECT_FALSE(Allow(source_list, GURL("data:text/html,hello"), &context));
- context.SetSelf(url::Origin(GURL("data:text/html,<iframe src=[...]>")));
+ context.SetSelf(
+ url::Origin::Create(GURL("data:text/html,<iframe src=[...]>")));
EXPECT_FALSE(Allow(source_list, GURL("http://a.com"), &context));
EXPECT_FALSE(Allow(source_list, GURL("data:text/html,hello"), &context));
}
diff --git a/chromium/content/common/content_security_policy/csp_source_unittest.cc b/chromium/content/common/content_security_policy/csp_source_unittest.cc
index 81a1c5f14c1..47975912e0b 100644
--- a/chromium/content/common/content_security_policy/csp_source_unittest.cc
+++ b/chromium/content/common/content_security_policy/csp_source_unittest.cc
@@ -91,7 +91,7 @@ TEST(CSPSourceTest, AllowScheme) {
EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context));
// Self's scheme is http.
- context.SetSelf(url::Origin(GURL("http://a.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://a.com")));
EXPECT_TRUE(Allow(source, GURL("http://a.com"), &context));
EXPECT_TRUE(Allow(source, GURL("https://a.com"), &context));
EXPECT_TRUE(Allow(source, GURL("http-so://a.com"), &context));
@@ -99,7 +99,7 @@ TEST(CSPSourceTest, AllowScheme) {
EXPECT_FALSE(Allow(source, GURL("ftp://a.com"), &context));
// Self's is https.
- context.SetSelf(url::Origin(GURL("https://a.com")));
+ context.SetSelf(url::Origin::Create(GURL("https://a.com")));
EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context));
EXPECT_TRUE(Allow(source, GURL("https://a.com"), &context));
EXPECT_FALSE(Allow(source, GURL("http-so://a.com"), &context));
@@ -108,17 +108,18 @@ TEST(CSPSourceTest, AllowScheme) {
EXPECT_FALSE(Allow(source, GURL("ftp://a.com"), &context));
// Self's scheme is not in the http familly.
- context.SetSelf(url::Origin(GURL("ftp://a.com/")));
+ context.SetSelf(url::Origin::Create(GURL("ftp://a.com/")));
EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context));
EXPECT_TRUE(Allow(source, GURL("ftp://a.com"), &context));
// Self's scheme is unique (non standard scheme).
- context.SetSelf(url::Origin(GURL("non-standard-scheme://a.com")));
+ context.SetSelf(url::Origin::Create(GURL("non-standard-scheme://a.com")));
EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context));
EXPECT_FALSE(Allow(source, GURL("non-standard-scheme://a.com"), &context));
// Self's scheme is unique (data-url).
- context.SetSelf(url::Origin(GURL("data:text/html,<iframe src=[...]>")));
+ context.SetSelf(
+ url::Origin::Create(GURL("data:text/html,<iframe src=[...]>")));
EXPECT_FALSE(Allow(source, GURL("http://a.com"), &context));
EXPECT_FALSE(Allow(source, GURL("data:text/html,hello"), &context));
}
@@ -126,7 +127,7 @@ TEST(CSPSourceTest, AllowScheme) {
TEST(CSPSourceTest, AllowHost) {
CSPContext context;
- context.SetSelf(url::Origin(GURL("http://example.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://example.com")));
// Host is * (source-expression = "http://*")
{
@@ -162,7 +163,7 @@ TEST(CSPSourceTest, AllowHost) {
TEST(CSPSourceTest, AllowPort) {
CSPContext context;
- context.SetSelf(url::Origin(GURL("http://example.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://example.com")));
// Source's port unspecified.
{
@@ -218,7 +219,7 @@ TEST(CSPSourceTest, AllowPort) {
TEST(CSPSourceTest, AllowPath) {
CSPContext context;
- context.SetSelf(url::Origin(GURL("http://example.com")));
+ context.SetSelf(url::Origin::Create(GURL("http://example.com")));
// Path to a file
{
diff --git a/chromium/content/common/content_switches_internal.cc b/chromium/content/common/content_switches_internal.cc
index 89e8a737443..1033dd09347 100644
--- a/chromium/content/common/content_switches_internal.cc
+++ b/chromium/content/common/content_switches_internal.cc
@@ -88,19 +88,6 @@ bool IsPinchToZoomEnabled() {
return !command_line.HasSwitch(switches::kDisablePinch);
}
-#if defined(OS_WIN)
-
-bool IsWin32kLockdownEnabled() {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return false;
- const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
- if (cmd_line->HasSwitch(switches::kDisableWin32kLockDown))
- return false;
- return true;
-}
-
-#endif
-
V8CacheOptions GetV8CacheOptions() {
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
@@ -203,7 +190,7 @@ void WaitForDebugger(const std::string& label) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SigUSR1Handler;
- sigaction(SIGUSR1, &sa, NULL);
+ sigaction(SIGUSR1, &sa, nullptr);
pause();
#endif // defined(OS_ANDROID)
diff --git a/chromium/content/common/content_switches_internal.h b/chromium/content/common/content_switches_internal.h
index c694388478e..07eb90ab809 100644
--- a/chromium/content/common/content_switches_internal.h
+++ b/chromium/content/common/content_switches_internal.h
@@ -16,10 +16,7 @@ class CommandLine;
namespace content {
bool IsPinchToZoomEnabled();
-#if defined(OS_WIN)
-// Returns whether Win32k lockdown is enabled for child processes or not.
-bool IsWin32kLockdownEnabled();
-#endif
+
V8CacheOptions GetV8CacheOptions();
ProgressBarCompletion GetProgressBarCompletionPolicy();
diff --git a/chromium/content/common/cross_site_document_classifier_unittest.cc b/chromium/content/common/cross_site_document_classifier_unittest.cc
index c65c33e2dac..18ae2dbbc94 100644
--- a/chromium/content/common/cross_site_document_classifier_unittest.cc
+++ b/chromium/content/common/cross_site_document_classifier_unittest.cc
@@ -30,13 +30,13 @@ TEST(CrossSiteDocumentClassifierTest, IsSameSite) {
GURL a_com_url0("https://mock1.a.com:8080/page1.html");
GURL a_com_url1("https://mock2.a.com:9090/page2.html");
GURL a_com_url2("https://a.com/page3.html");
- url::Origin a_com_origin0(a_com_url0);
+ url::Origin a_com_origin0 = url::Origin::Create(a_com_url0);
EXPECT_TRUE(
CrossSiteDocumentClassifier::IsSameSite(a_com_origin0, a_com_url1));
- EXPECT_TRUE(CrossSiteDocumentClassifier::IsSameSite(url::Origin(a_com_url1),
- a_com_url2));
- EXPECT_TRUE(CrossSiteDocumentClassifier::IsSameSite(url::Origin(a_com_url2),
- a_com_url0));
+ EXPECT_TRUE(CrossSiteDocumentClassifier::IsSameSite(
+ url::Origin::Create(a_com_url1), a_com_url2));
+ EXPECT_TRUE(CrossSiteDocumentClassifier::IsSameSite(
+ url::Origin::Create(a_com_url2), a_com_url0));
GURL b_com_url0("https://mock1.b.com/index.html");
EXPECT_FALSE(
@@ -56,7 +56,7 @@ TEST(CrossSiteDocumentClassifierTest, IsSameSite) {
}
TEST(CrossSiteDocumentClassifierTest, IsValidCorsHeaderSet) {
- url::Origin frame_origin(GURL("http://www.google.com"));
+ url::Origin frame_origin = url::Origin::Create(GURL("http://www.google.com"));
GURL site_origin_url("http://www.yahoo.com");
EXPECT_TRUE(CrossSiteDocumentClassifier::IsValidCorsHeaderSet(
diff --git a/chromium/content/common/cursors/webcursor.cc b/chromium/content/common/cursors/webcursor.cc
index e34ab185550..42584ef2fd3 100644
--- a/chromium/content/common/cursors/webcursor.cc
+++ b/chromium/content/common/cursors/webcursor.cc
@@ -121,7 +121,7 @@ void WebCursor::Serialize(base::Pickle* pickle) const {
pickle->WriteInt(custom_size_.height());
pickle->WriteFloat(custom_scale_);
- const char* data = NULL;
+ const char* data = nullptr;
if (!custom_data_.empty())
data = &custom_data_[0];
pickle->WriteData(data, custom_data_.size());
diff --git a/chromium/content/common/cursors/webcursor_aurax11.cc b/chromium/content/common/cursors/webcursor_aurax11.cc
index feeba909193..00cc3ae46a0 100644
--- a/chromium/content/common/cursors/webcursor_aurax11.cc
+++ b/chromium/content/common/cursors/webcursor_aurax11.cc
@@ -4,15 +4,13 @@
#include "content/common/cursors/webcursor.h"
-#include <X11/cursorfont.h>
-#include <X11/Xcursor/Xcursor.h>
-#include <X11/Xlib.h>
#include "base/logging.h"
#include "third_party/WebKit/public/platform/WebCursorInfo.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/cursor/cursor_loader_x11.h"
#include "ui/base/x/x11_util.h"
+#include "ui/gfx/x/x11.h"
namespace content {
diff --git a/chromium/content/common/devtools.mojom b/chromium/content/common/devtools.mojom
new file mode 100644
index 00000000000..8ef620035d4
--- /dev/null
+++ b/chromium/content/common/devtools.mojom
@@ -0,0 +1,131 @@
+// Copyright 2017 The Chromium 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";
+
+// Provides extra capabilities required for DevTools frontend to function.
+// This includes communication channel from/to inspected target which implements
+// remote debugging protocol. Protocol messages go through browser process.
+// This interface is implemented in DevTools renderer.
+//
+// Instances of this interface must be associated with navigation-related
+// interface, since we should setup DevToolsFrontend before the navigation
+// commits in the frame.
+interface DevToolsFrontend {
+ // Sets up a main frame as a DevTools frontend. This exposes DevToolsHost
+ // object (see DevToolsHost.idl for details). The |api_script| is executed
+ // on each navigation in the frame before the DevTools frontend starts
+ // loading. It makes use of DevToolsHost to expose embedder capabilities to
+ // DevTools (e.g. connection to the inspected target).
+ SetupDevToolsFrontend(string api_script,
+ associated DevToolsFrontendHost host);
+
+ // Sets up a child frame to expose DevTools extension API by executing script
+ // |extension_api| on each navigation in the frame. This script provides
+ // required capabilities for DevTools extensions to function, implementing
+ // chrome.devtools extension API.
+ SetupDevToolsExtensionAPI(string extension_api);
+};
+
+// Provides embedder functionality to a frame serving as DevTools frontend.
+// This interface is implemented in browser.
+interface DevToolsFrontendHost {
+ // Sends a message to DevTools frontend embedder.
+ DispatchEmbedderMessage(string message);
+};
+
+
+// Used to send large messages in chunks from session to a host.
+struct DevToolsMessageChunk {
+ // Whether this is a first chunk in a message.
+ bool is_first;
+
+ // Whether this is a last chunk in a message.
+ bool is_last;
+
+ // The total size of the message being sent in chunks, only comes in
+ // a first chunk.
+ uint32 message_size;
+
+ // Chunk data.
+ string data;
+
+ // Call id as defined in DevTools protocol, only comes for responses.
+ int32 call_id;
+
+ // State for future reattach, only comes for responses in a last chunk.
+ string post_state;
+};
+
+// Implemented by debugging targets which expose remote debugging protocol.
+// Examples are local frame roots and service workers.
+//
+// Note that frame instances of this interface must be associated with
+// navigation-related interface, since we should reattach sessions before
+// the navigation commits in the frame.
+//
+// This interface is implemented in renderer hosting entity under debug.
+interface DevToolsAgent {
+ // Attaches a new debugging session. This session speaks remote debugging
+ // protocol and restores all the changes to original state once destroyed.
+ //
+ // Associated |session| receives messages on UI thread and guarantees
+ // relative ordering with e.g. navigations.
+ //
+ // Non-associated |io_session| receives messages on IO thread and may
+ // interrupt long running JavaScript on the main thread. It should be used
+ // for debugging messages which are intended to interrupt execution,
+ // e.g. requesting a pause. There is no ordering guarantee relative to
+ // regular |session|.
+ //
+ // If |reattach_state| is present, restores the state of the session to
+ // previously saved one (see DevToolsMessageChunk). This is useful when
+ // transferring a session from one agent to another while preserving the
+ // state. For example, cross-process navigation in a frame creates a new
+ // DevToolsAgent (in a different process), but we can preserve the state of
+ // debugging session by copying it from one agent to another.
+ //
+ // ------ Why separate sessions? ------
+ //
+ // To guarantee ordering with legacy IPC channel, we must bind session
+ // synchronously on the UI thread. Otherwise there is a time window
+ // when the request is not yet bound, but the messages may already come.
+ // In this case, messages will be sent to UI hoping that interface
+ // is bound there, and get incorrectly dispatched.
+ //
+ // On the other hand, we need to handle some of the messages on IO without
+ // going to UI first (as described above). This means an interface bound
+ // on IO thread. Thus a session per thread.
+ AttachDevToolsSession(associated DevToolsSessionHost host,
+ associated DevToolsSession& session,
+ DevToolsSession& io_session,
+ string? reattach_state);
+};
+
+// Represents an attached session which exposes remote debugging protocol.
+// This interface is implemented in renderer hosting entity under debug.
+interface DevToolsSession {
+ // Dispatches protocol message from a client to a debugging target.
+ // |method| is a method name as defined in protocol (e.g. "Runtime.evaluate").
+ // |call_id| is a command id as defined in protocol, and is going to be
+ // reported back to host in a response message (see DevToolsMessageChunk).
+ DispatchProtocolMessage(int32 call_id, string method, string message);
+
+ // Requests an element at specific position to be inspected.
+ InspectElement(gfx.mojom.Point point);
+};
+
+// A peer of DevToolsSession representing a remote debugging client
+// which receives notifications and responses from a session.
+// This interface is implemented in browser.
+interface DevToolsSessionHost {
+ // Dispatches protocol message (in chunks) to a remote debugging client.
+ DispatchProtocolMessage(DevToolsMessageChunk chunk);
+
+ // Requests a new DevTools window for a frame with given routing id.
+ // TODO(dgozman): get rid of routing id when possible.
+ RequestNewWindow(int32 frame_routing_id) => (bool success);
+};
diff --git a/chromium/content/common/devtools/devtools_network_conditions.cc b/chromium/content/common/devtools/devtools_network_conditions.cc
deleted file mode 100644
index d2e1437abc4..00000000000
--- a/chromium/content/common/devtools/devtools_network_conditions.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/devtools/devtools_network_conditions.h"
-
-namespace content {
-
-DevToolsNetworkConditions::DevToolsNetworkConditions()
- : DevToolsNetworkConditions(false) {}
-
-DevToolsNetworkConditions::DevToolsNetworkConditions(bool offline)
- : DevToolsNetworkConditions(offline, 0, 0, 0) {}
-
-DevToolsNetworkConditions::DevToolsNetworkConditions(bool offline,
- double latency,
- double download_throughput,
- double upload_throughput)
- : offline_(offline),
- latency_(latency),
- download_throughput_(download_throughput),
- upload_throughput_(upload_throughput) {}
-
-DevToolsNetworkConditions::~DevToolsNetworkConditions() {}
-
-bool DevToolsNetworkConditions::IsThrottling() const {
- return !offline_ && ((latency_ != 0) || (download_throughput_ != 0.0) ||
- (upload_throughput_ != 0));
-}
-
-} // namespace content
diff --git a/chromium/content/common/devtools/devtools_network_controller.h b/chromium/content/common/devtools/devtools_network_controller.h
deleted file mode 100644
index 471ac1eb342..00000000000
--- a/chromium/content/common/devtools/devtools_network_controller.h
+++ /dev/null
@@ -1,54 +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_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_CONTROLLER_H_
-#define CONTENT_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_CONTROLLER_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-class DevToolsNetworkConditions;
-class DevToolsNetworkInterceptor;
-
-// DevToolsNetworkController manages interceptors identified by client id
-// and their throttling conditions.
-class CONTENT_EXPORT DevToolsNetworkController {
- public:
- // Applies network emulation configuration.
- static void SetNetworkState(
- const std::string& client_id,
- std::unique_ptr<DevToolsNetworkConditions> conditions);
-
- static DevToolsNetworkInterceptor* GetInterceptor(
- const std::string& client_id);
-
- private:
- DevToolsNetworkController();
- ~DevToolsNetworkController();
-
- DevToolsNetworkInterceptor* FindInterceptor(const std::string& client_id);
- void SetConditions(const std::string& client_id,
- std::unique_ptr<DevToolsNetworkConditions> conditions);
-
- static DevToolsNetworkController* instance_;
-
- using InterceptorMap =
- std::map<std::string, std::unique_ptr<DevToolsNetworkInterceptor>>;
-
- InterceptorMap interceptors_;
- THREAD_CHECKER(thread_checker_);
-
- DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkController);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_CONTROLLER_H_
diff --git a/chromium/content/common/devtools_messages.h b/chromium/content/common/devtools_messages.h
index 49360f76cf5..c00f1330b1f 100644
--- a/chromium/content/common/devtools_messages.h
+++ b/chromium/content/common/devtools_messages.h
@@ -80,14 +80,11 @@ IPC_MESSAGE_ROUTED1(DevToolsClientMsg_DispatchOnInspectorFrontend,
// These are messages sent from DevToolsClient to DevToolsAgent through the
// browser.
// Tells agent that there is a client host connected to it.
-IPC_MESSAGE_ROUTED2(DevToolsAgentMsg_Attach,
- std::string /* host_id */,
- int /* session_id */)
+IPC_MESSAGE_ROUTED1(DevToolsAgentMsg_Attach, int /* session_id */)
// Tells agent that a client host was disconnected from another agent and
// connected to this one.
-IPC_MESSAGE_ROUTED3(DevToolsAgentMsg_Reattach,
- std::string /* host_id */,
+IPC_MESSAGE_ROUTED2(DevToolsAgentMsg_Reattach,
int /* session_id */,
std::string /* agent_state */)
@@ -108,7 +105,8 @@ IPC_MESSAGE_ROUTED3(DevToolsAgentMsg_InspectElement,
int /* y */)
// ACK for DevToolsAgentHostMsg_RequestNewWindow message.
-IPC_MESSAGE_ROUTED1(DevToolsAgentMsg_RequestNewWindow_ACK,
+IPC_MESSAGE_ROUTED2(DevToolsAgentMsg_RequestNewWindow_ACK,
+ int /* session_id */,
bool /* success */)
//-----------------------------------------------------------------------------
@@ -116,26 +114,8 @@ IPC_MESSAGE_ROUTED1(DevToolsAgentMsg_RequestNewWindow_ACK,
// Requests new DevTools window being opened for frame in the same process
// with given routing id.
-IPC_MESSAGE_ROUTED1(DevToolsAgentHostMsg_RequestNewWindow,
+IPC_MESSAGE_ROUTED2(DevToolsAgentHostMsg_RequestNewWindow,
+ int /* session_id */,
int /* frame_route_id */)
-
-//-----------------------------------------------------------------------------
-// These are messages sent from the browser to the renderer.
-
-// RenderViewHostDelegate::RenderViewCreated method sends this message to a
-// new renderer to notify it that it will host developer tools UI and should
-// set up all neccessary bindings and create DevToolsClient instance that
-// will handle communication with inspected page DevToolsAgent.
-IPC_MESSAGE_ROUTED1(DevToolsMsg_SetupDevToolsClient,
- std::string /* compatibility script */)
-
-
-//-----------------------------------------------------------------------------
-// These are messages sent from the renderer to the browser.
-
-// Transport from Inspector frontend to frontend host.
-IPC_MESSAGE_ROUTED1(DevToolsHostMsg_DispatchOnEmbedder,
- std::string /* message */)
-
#endif // CONTENT_COMMON_DEVTOOLS_MESSAGES_H_
diff --git a/chromium/content/common/drag_messages.h b/chromium/content/common/drag_messages.h
index 9d790d0e5da..875c7ee1aa0 100644
--- a/chromium/content/common/drag_messages.h
+++ b/chromium/content/common/drag_messages.h
@@ -23,31 +23,31 @@
IPC_MESSAGE_ROUTED5(DragMsg_TargetDragEnter,
std::vector<content::DropData::Metadata> /* drop_data */,
- gfx::Point /* client_pt */,
- gfx::Point /* screen_pt */,
+ gfx::PointF /* client_pt */,
+ gfx::PointF /* screen_pt */,
blink::WebDragOperationsMask /* ops_allowed */,
int /* key_modifiers */)
IPC_MESSAGE_ROUTED4(DragMsg_TargetDragOver,
- gfx::Point /* client_pt */,
- gfx::Point /* screen_pt */,
+ gfx::PointF /* client_pt */,
+ gfx::PointF /* screen_pt */,
blink::WebDragOperationsMask /* ops_allowed */,
int /* key_modifiers */)
IPC_MESSAGE_ROUTED2(DragMsg_TargetDragLeave,
- gfx::Point /* client_point */,
- gfx::Point /* screen_point */)
+ gfx::PointF /* client_point */,
+ gfx::PointF /* screen_point */)
IPC_MESSAGE_ROUTED4(DragMsg_TargetDrop,
content::DropData /* drop_data */,
- gfx::Point /* client_pt */,
- gfx::Point /* screen_pt */,
+ gfx::PointF /* client_pt */,
+ gfx::PointF /* screen_pt */,
int /* key_modifiers */)
// Notifies the renderer when and where the mouse-drag ended.
IPC_MESSAGE_ROUTED3(DragMsg_SourceEnded,
- gfx::Point /* client_pt */,
- gfx::Point /* screen_pt */,
+ gfx::PointF /* client_pt */,
+ gfx::PointF /* screen_pt */,
blink::WebDragOperation /* drag_operation */)
// Notifies the renderer that the system DoDragDrop call has ended.
diff --git a/chromium/content/common/feature_policy/README.md b/chromium/content/common/feature_policy/README.md
deleted file mode 100644
index f6ad3503b17..00000000000
--- a/chromium/content/common/feature_policy/README.md
+++ /dev/null
@@ -1,134 +0,0 @@
-## Feature Policy Guide
-### How to add a new feature to feature policy
-
-Feature policy (see [spec](https://wicg.github.io/feature-policy/)) is a
-mechanism that allows developers to selectively enable and disable various
-[browser features and
-APIs](https://cs.chromium.org/chromium/src/third_party/WebKit/public/platform/WebFeaturePolicyFeature.h)
-(e.g, "vibrate", "fullscreen", "usb", etc.). A feature policy can be defined
-via a HTTP header and/or an iframe "allow" attribute.
-
-Below is an example of a header policy (note that the header should be kept in
-one line, split into multiple for clarity reasons):
-
- Feature-Policy: {"vibrate": [],
- "geolocation": ["self", "https://example.com"],
- "camera": ["*"]}
-
-Soon the syntax will be updated
-([crbug.com/750259](https://bugs.chromium.org/p/chromium/issues/detail?id=750259)):
-
- Feature-Policy: vibrate "none"; geolocation "self" https://example.com; camera "*"
-
-
-- `vibrate` is disabled for all browsing contexts;
-- `geolocation` is disabled for all browsing contexts except for its own
- origin and those whose origin is "https://example.com";
-- `camera` is enabled for all browsing contexts.
-
-Below is an example of a container policy:
-
- <iframe allowpaymentrequest allow=’vibrate fullscreen’></iframe>
-
-Soon the syntax will be updated
-([crbug.com/726739](https://bugs.chromium.org/p/chromium/issues/detail?id=726739)):
-
- <iframe allowpaymentrequest allow='vibrate; fullscreen;'></iframe>
-
-OR
-
- <iframe allowpaymentrequest allow='vibrate "src"; fullscreen "src"'></iframe>
-
-
-- `payment` is enabled (via `allowpaymentrequest`) on all browsing contexts
- within the iframe;
-- `vibrate` and `fullscreen` are enabled on the origin of the URL of the
- iframe's `src` attribute.
-
-Combined with a header policy and a container policy, [inherited
-policy](https://wicg.github.io/feature-policy/#inherited-policy) defines the
-availability of a feature.
-See more details for how to [define an inherited policy for
-feature](https://wicg.github.io/feature-policy/#define-inherited-policy)
-
-#### Adding a new feature to feature policy
-A step-to-step guide with examples.
-
-##### Shipping features behind a flag
-There are currently two runtime-enabled flags: `FeaturePolicy` (status:
-stable) and `FeaturePolicyExperiementalFeatures` (staus: experimental).
-If the additional feature is unshipped, or if the correct behaviour with feature
-policy is undetermined, consider shipping the feature behind a flag (i.e.,
-`FeaturePolicyExperimentalFeatures`).
-
-##### Define new feature
-1. Feature policy features are defined in
-`third_party/WebKit/public/platform/WebFeaturePolicy.h`. Add the new feature
-enum with a brief decription about what the feature does in the comment, right
-above `LAST_FEATURE`
-
-2. Update `third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp`:
-Add your `("feature-name", FeatureEnumValue)` mapping to
- `GetDefaultFeatureNameMap()` (note: "feature-name" is the string web
- developers will be using to define the policy in the HTTP header and iframe
- "allow" attribute).
-+ If shipping behind the flag (`FeaturePolicyExperimentalFeatures`):
-Add the mapping inside the `if
-(RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled())`
-stament;
-+ Otherwise:
-Add the mapping above the if statment.
-
-##### Integrate the feature behaviour with feature policy
-1. Add a case for the feature in `IsSupportedInFeaturePolicy()` (which checks
-if feature policy is enabled and the feature is supported in feature policy):
-- If shipping behind the flag (`FeaturePolicyExperimentalFeatures`):
-
- return RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled();
-
-- Otherwise:
-
- return true;
-
-
-2. Implement the behaviour of the new feature for the 3 cases:
-- Default behaviour without feature policy
-i.e,
-
- if (!IsSupportedInFeaturePolicy(...)) {
- ...
- }
-
-- When feature policy is enabled and feature is enabled by feature policy;
-i.e,
-
- if (!IsSupportedInFeaturePolicy(...)) {
- if (frame->IsFeatureEnabled(...)) {
- ...
- }
- }
-
-- When feature policy is enabled and feature is disabled by feature policy.
-i.e,
-
- if (IsSupportedInFeaturePolicy(...)) {
- if (!frame->IsFeatureEnabled(...)) {
- ...
- }
- }
-
-
-3. Examples:
-- `vibrate`: `NavigatorVibration::vibrate()`
-- `payment`: `AllowedToUsePaymentRequest()`
-- `usb`: `USB::getDevices()`
-
-##### Write web-platform-tests
-To test the new feature with feature policy, refer to
-`third_party/WebKit/LayoutTests/external/wpt/feature-policy/README.md` for
-instructions on how to use the feature policy test framework.
-
-#### Contacts
-For more questions, please feel free to reach out to:
-loonybear@chromium.org
-iclelland@chromium.org
diff --git a/chromium/content/common/feature_policy/feature_policy.cc b/chromium/content/common/feature_policy/feature_policy.cc
deleted file mode 100644
index 3c2f3ed1c4d..00000000000
--- a/chromium/content/common/feature_policy/feature_policy.cc
+++ /dev/null
@@ -1,244 +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/feature_policy/feature_policy.h"
-
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/stl_util.h"
-
-namespace content {
-
-namespace {
-
-// Extracts a Whitelist from a ParsedFeaturePolicyDeclaration.
-std::unique_ptr<FeaturePolicy::Whitelist> WhitelistFromDeclaration(
- const ParsedFeaturePolicyDeclaration& parsed_declaration) {
- std::unique_ptr<FeaturePolicy::Whitelist> result =
- base::WrapUnique(new FeaturePolicy::Whitelist());
- if (parsed_declaration.matches_all_origins)
- result->AddAll();
- for (const auto& origin : parsed_declaration.origins)
- result->Add(origin);
- return result;
-}
-
-} // namespace
-
-ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration()
- : matches_all_origins(false) {}
-
-ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration(
- blink::WebFeaturePolicyFeature feature,
- bool matches_all_origins,
- std::vector<url::Origin> origins)
- : feature(feature),
- matches_all_origins(matches_all_origins),
- origins(origins) {}
-
-ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration(
- const ParsedFeaturePolicyDeclaration& rhs) = default;
-
-ParsedFeaturePolicyDeclaration::~ParsedFeaturePolicyDeclaration() {}
-
-bool operator==(const ParsedFeaturePolicyDeclaration& lhs,
- const ParsedFeaturePolicyDeclaration& rhs) {
- // This method returns true only when the arguments are actually identical,
- // including the order of elements in the origins vector.
- // TODO(iclelland): Consider making this return true when comparing equal-
- // but-not-identical whitelists, or eliminate those comparisons by maintaining
- // the whiteslists in a normalized form.
- // https://crbug.com/710324
- return std::tie(lhs.feature, lhs.matches_all_origins, lhs.origins) ==
- std::tie(rhs.feature, rhs.matches_all_origins, rhs.origins);
-}
-
-FeaturePolicy::Whitelist::Whitelist() : matches_all_origins_(false) {}
-
-FeaturePolicy::Whitelist::Whitelist(const Whitelist& rhs) = default;
-
-FeaturePolicy::Whitelist::~Whitelist() = default;
-
-void FeaturePolicy::Whitelist::Add(const url::Origin& origin) {
- origins_.push_back(origin);
-}
-
-void FeaturePolicy::Whitelist::AddAll() {
- matches_all_origins_ = true;
-}
-
-bool FeaturePolicy::Whitelist::Contains(const url::Origin& origin) const {
- // This does not handle the case where origin is an opaque origin, which is
- // also supposed to exist in the whitelist. (The identical opaque origins
- // should match in that case)
- // TODO(iclelland): Fix that, possibly by having another flag for
- // 'matches_self', which will explicitly match the policy's origin.
- // https://crbug.com/690520
- if (matches_all_origins_)
- return true;
- for (const auto& targetOrigin : origins_) {
- if (targetOrigin.IsSameOriginWith(origin))
- return true;
- }
- return false;
-}
-
-// static
-std::unique_ptr<FeaturePolicy> FeaturePolicy::CreateFromParentPolicy(
- const FeaturePolicy* parent_policy,
- const ParsedFeaturePolicyHeader& container_policy,
- const url::Origin& origin) {
- return CreateFromParentPolicy(parent_policy, container_policy, origin,
- GetDefaultFeatureList());
-}
-
-// static
-std::unique_ptr<FeaturePolicy> FeaturePolicy::CreateFromPolicyWithOrigin(
- const FeaturePolicy& policy,
- const url::Origin& origin) {
- std::unique_ptr<FeaturePolicy> new_policy =
- base::WrapUnique(new FeaturePolicy(origin, policy.feature_list_));
- new_policy->inherited_policies_ = policy.inherited_policies_;
- for (const auto& feature : policy.whitelists_) {
- new_policy->whitelists_[feature.first] =
- base::WrapUnique(new Whitelist(*feature.second));
- }
- return new_policy;
-}
-
-bool FeaturePolicy::IsFeatureEnabled(
- blink::WebFeaturePolicyFeature feature) const {
- return IsFeatureEnabledForOrigin(feature, origin_);
-}
-
-bool FeaturePolicy::IsFeatureEnabledForOrigin(
- blink::WebFeaturePolicyFeature feature,
- const url::Origin& origin) const {
- DCHECK(base::ContainsKey(feature_list_, feature));
- const FeaturePolicy::FeatureDefault default_policy =
- feature_list_.at(feature);
- DCHECK(base::ContainsKey(inherited_policies_, feature));
- if (!inherited_policies_.at(feature))
- return false;
- auto whitelist = whitelists_.find(feature);
- if (whitelist != whitelists_.end())
- return whitelist->second->Contains(origin);
- if (default_policy == FeaturePolicy::FeatureDefault::EnableForAll)
- return true;
- if (default_policy == FeaturePolicy::FeatureDefault::EnableForSelf) {
- // TODO(iclelland): Remove the pointer equality check once it is possible to
- // compare opaque origins successfully against themselves.
- // https://crbug.com/690520
- return (&origin_ == &origin) || origin_.IsSameOriginWith(origin);
- }
- return false;
-}
-
-void FeaturePolicy::SetHeaderPolicy(
- const ParsedFeaturePolicyHeader& parsed_header) {
- DCHECK(whitelists_.empty());
- for (const ParsedFeaturePolicyDeclaration& parsed_declaration :
- parsed_header) {
- blink::WebFeaturePolicyFeature feature = parsed_declaration.feature;
- DCHECK(feature != blink::WebFeaturePolicyFeature::kNotFound);
- whitelists_[feature] = WhitelistFromDeclaration(parsed_declaration);
- }
-}
-
-FeaturePolicy::FeaturePolicy(url::Origin origin,
- const FeatureList& feature_list)
- : origin_(origin), feature_list_(feature_list) {}
-
-FeaturePolicy::FeaturePolicy(url::Origin origin)
- : origin_(origin), feature_list_(GetDefaultFeatureList()) {}
-
-FeaturePolicy::~FeaturePolicy() {}
-
-// static
-std::unique_ptr<FeaturePolicy> FeaturePolicy::CreateFromParentPolicy(
- const FeaturePolicy* parent_policy,
- const ParsedFeaturePolicyHeader& container_policy,
- const url::Origin& origin,
- const FeaturePolicy::FeatureList& features) {
- // If there is a non-empty container policy, then there must also be a parent
- // policy.
- DCHECK(parent_policy || container_policy.empty());
-
- std::unique_ptr<FeaturePolicy> new_policy =
- base::WrapUnique(new FeaturePolicy(origin, features));
- for (const auto& feature : features) {
- if (!parent_policy ||
- parent_policy->IsFeatureEnabledForOrigin(feature.first, origin)) {
- new_policy->inherited_policies_[feature.first] = true;
- } else {
- new_policy->inherited_policies_[feature.first] = false;
- }
- }
- if (!container_policy.empty())
- new_policy->AddContainerPolicy(container_policy, parent_policy);
- return new_policy;
-}
-
-void FeaturePolicy::AddContainerPolicy(
- const ParsedFeaturePolicyHeader& container_policy,
- const FeaturePolicy* parent_policy) {
- DCHECK(parent_policy);
- for (const ParsedFeaturePolicyDeclaration& parsed_declaration :
- container_policy) {
- // If a feature is enabled in the parent frame, and the parent chooses to
- // delegate it to the child frame, using the iframe attribute, then the
- // feature should be enabled in the child frame.
- blink::WebFeaturePolicyFeature feature = parsed_declaration.feature;
- if (feature == blink::WebFeaturePolicyFeature::kNotFound)
- continue;
- if (WhitelistFromDeclaration(parsed_declaration)->Contains(origin_) &&
- parent_policy->IsFeatureEnabled(feature)) {
- inherited_policies_[feature] = true;
- } else {
- inherited_policies_[feature] = false;
- }
- }
-}
-
-// static
-// See third_party/WebKit/public/platform/WebFeaturePolicy.h for status of each
-// features (in spec, implemented, etc).
-const FeaturePolicy::FeatureList& FeaturePolicy::GetDefaultFeatureList() {
- CR_DEFINE_STATIC_LOCAL(FeatureList, default_feature_list,
- ({{blink::WebFeaturePolicyFeature::kCamera,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {blink::WebFeaturePolicyFeature::kEncryptedMedia,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {blink::WebFeaturePolicyFeature::kFullscreen,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {blink::WebFeaturePolicyFeature::kGeolocation,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {blink::WebFeaturePolicyFeature::kMicrophone,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {blink::WebFeaturePolicyFeature::kMidiFeature,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {blink::WebFeaturePolicyFeature::kPayment,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {blink::WebFeaturePolicyFeature::kSpeaker,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {blink::WebFeaturePolicyFeature::kVibrate,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {blink::WebFeaturePolicyFeature::kDocumentCookie,
- FeaturePolicy::FeatureDefault::EnableForAll},
- {blink::WebFeaturePolicyFeature::kDocumentDomain,
- FeaturePolicy::FeatureDefault::EnableForAll},
- {blink::WebFeaturePolicyFeature::kDocumentWrite,
- FeaturePolicy::FeatureDefault::EnableForAll},
- {blink::WebFeaturePolicyFeature::kSyncScript,
- FeaturePolicy::FeatureDefault::EnableForAll},
- {blink::WebFeaturePolicyFeature::kSyncXHR,
- FeaturePolicy::FeatureDefault::EnableForAll},
- {blink::WebFeaturePolicyFeature::kUsb,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {blink::WebFeaturePolicyFeature::kWebVr,
- FeaturePolicy::FeatureDefault::EnableForSelf}}));
- return default_feature_list;
-}
-
-} // namespace content
diff --git a/chromium/content/common/feature_policy/feature_policy.h b/chromium/content/common/feature_policy/feature_policy.h
deleted file mode 100644
index 4f9be784207..00000000000
--- a/chromium/content/common/feature_policy/feature_policy.h
+++ /dev/null
@@ -1,220 +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_FEATURE_POLICY_FEATURE_POLICY_H_
-#define CONTENT_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_
-
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
-#include "url/origin.h"
-
-namespace content {
-
-// Feature Policy is a mechanism for controlling the availability of web
-// platform features in a frame, including all embedded frames. It can be used
-// to remove features, automatically refuse API permission requests, or modify
-// the behaviour of features. (The specific changes which are made depend on the
-// feature; see the specification for details).
-//
-// Policies can be defined in the HTTP header stream, with the |Feature-Policy|
-// HTTP header, or can be set by the |allow| attributes on the iframe element
-// which embeds the document.
-//
-// See https://wicg.github.io/FeaturePolicy/
-//
-// Key concepts:
-//
-// Features
-// --------
-// Features which can be controlled by policy are defined by instances of enum
-// blink::WebFeaturePolicyFeature, declared in |WebFeaturePolicy.h|.
-//
-// Whitelists
-// ----------
-// Whitelists are collections of origins, although two special terms can be used
-// when declaring them:
-// "self" refers to the orgin of the frame which is declaring the policy.
-// "*" refers to all origins; any origin will match a whitelist which contains
-// it.
-//
-// Declarations
-// ------------
-// A feature policy declaration is a mapping of a feature name to a whitelist.
-// A set of declarations is a declared policy.
-//
-// Inherited Policy
-// ----------------
-// In addition to the declared policy (which may be empty), every frame has
-// an inherited policy, which is determined by the context in which it is
-// embedded, or by the defaults for each feature in the case of the top-level
-// document.
-//
-// Container Policy
-// ----------------
-// A declared policy can be set on a specific frame by the embedding page using
-// the iframe "allow" attribute, or through attributes such as "allowfullscreen"
-// or "allowpaymentrequest". This is the container policy for the embedded
-// frame.
-//
-// Defaults
-// --------
-// Each defined feature has a default policy, which determines whether the
-// feature is available when no policy has been declared, ans determines how the
-// feature is inherited across origin boundaries.
-//
-// If the default policy is in effect for a frame, then it controls how the
-// feature is inherited by any cross-origin iframes embedded by the frame. (See
-// the comments below in FeaturePolicy::DefaultPolicy for specifics)
-//
-// Policy Inheritance
-// ------------------
-// Policies in effect for a frame are inherited by any child frames it embeds.
-// Unless another policy is declared in the child, all same-origin children will
-// receive the same set of enables features as the parent frame. Whether or not
-// features are inherited by cross-origin iframes without an explicit policy is
-// determined by the feature's default policy. (Again, see the comments in
-// FeaturePolicy::DefaultPolicy for details)
-
-// This struct holds feature policy whitelist data that needs to be replicated
-// between a RenderFrame and any of its associated RenderFrameProxies. A list of
-// these form a ParsedFeaturePolicyHeader.
-// NOTE: These types are used for replication frame state between processes.
-// They exist only because we can't transfer WebVectors directly over IPC.
-struct CONTENT_EXPORT ParsedFeaturePolicyDeclaration {
- ParsedFeaturePolicyDeclaration();
- ParsedFeaturePolicyDeclaration(blink::WebFeaturePolicyFeature feature,
- bool matches_all_origins,
- std::vector<url::Origin> origins);
- ParsedFeaturePolicyDeclaration(const ParsedFeaturePolicyDeclaration& rhs);
- ~ParsedFeaturePolicyDeclaration();
-
- blink::WebFeaturePolicyFeature feature;
- bool matches_all_origins;
- std::vector<url::Origin> origins;
-};
-
-using ParsedFeaturePolicyHeader = std::vector<ParsedFeaturePolicyDeclaration>;
-
-bool CONTENT_EXPORT operator==(const ParsedFeaturePolicyDeclaration& lhs,
- const ParsedFeaturePolicyDeclaration& rhs);
-
-class CONTENT_EXPORT FeaturePolicy : public blink::WebFeaturePolicy {
- public:
- // Represents a collection of origins which make up a whitelist in a feature
- // policy. This collection may be set to match every origin (corresponding to
- // the "*" syntax in the policy string, in which case the Contains() method
- // will always return true.
- class Whitelist final {
- public:
- Whitelist();
- Whitelist(const Whitelist& rhs);
- ~Whitelist();
-
- // Adds a single origin to the whitelist.
- void Add(const url::Origin& origin);
-
- // Adds all origins to the whitelist.
- void AddAll();
-
- // Returns true if the given origin has been added to the whitelist.
- bool Contains(const url::Origin& origin) const;
-
- private:
- bool matches_all_origins_;
- std::vector<url::Origin> origins_;
- };
-
- // The FeaturePolicy::FeatureDefault enum defines the default enable state for
- // a feature when neither it nor any parent frame have declared an explicit
- // policy. The three possibilities map directly to Feature Policy Whitelist
- // semantics.
- enum class FeatureDefault {
- // Equivalent to []. If this default policy is in effect for a frame, then
- // the feature will not be enabled for that frame or any of its children.
- DisableForAll,
-
- // Equivalent to ["self"]. If this default policy is in effect for a frame,
- // then the feature will be enabled for that frame, and any same-origin
- // child frames, but not for any cross-origin child frames.
- EnableForSelf,
-
- // Equivalent to ["*"]. If in effect for a frame, then the feature is
- // enabled for that frame and all of its children.
- EnableForAll
- };
-
- using FeatureList = std::map<blink::WebFeaturePolicyFeature, FeatureDefault>;
-
- ~FeaturePolicy() override;
-
- static std::unique_ptr<FeaturePolicy> CreateFromParentPolicy(
- const FeaturePolicy* parent_policy,
- const ParsedFeaturePolicyHeader& container_policy,
- const url::Origin& origin);
-
- static std::unique_ptr<FeaturePolicy> CreateFromPolicyWithOrigin(
- const FeaturePolicy& policy,
- const url::Origin& origin);
-
- // WebFeaturePolicy implementation
- bool IsFeatureEnabled(blink::WebFeaturePolicyFeature feature) const override;
-
- // Returns whether or not the given feature is enabled by this policy for a
- // specific origin.
- bool IsFeatureEnabledForOrigin(blink::WebFeaturePolicyFeature feature,
- const url::Origin& origin) const;
-
- // Sets the declared policy from the parsed Feature-Policy HTTP header.
- // Unrecognized features will be ignored.
- void SetHeaderPolicy(const ParsedFeaturePolicyHeader& parsed_header);
-
- private:
- friend class FeaturePolicyTest;
- FRIEND_TEST_ALL_PREFIXES(NavigatorTestWithBrowserSideNavigation,
- FeaturePolicyNewChild);
-
- explicit FeaturePolicy(url::Origin origin);
- FeaturePolicy(url::Origin origin, const FeatureList& feature_list);
- static std::unique_ptr<FeaturePolicy> CreateFromParentPolicy(
- const FeaturePolicy* parent_policy,
- const ParsedFeaturePolicyHeader& container_policy,
- const url::Origin& origin,
- const FeatureList& features);
-
- // Updates the inherited policy with the declarations from the iframe allow*
- // attributes.
- void AddContainerPolicy(const ParsedFeaturePolicyHeader& container_policy,
- const FeaturePolicy* parent_policy);
-
- // Returns the list of features which can be controlled by Feature Policy.
- static const FeatureList& GetDefaultFeatureList();
-
- url::Origin origin_;
-
- // Map of feature names to declared whitelists. Any feature which is missing
- // from this map should use the inherited policy.
- std::map<blink::WebFeaturePolicyFeature, std::unique_ptr<Whitelist>>
- whitelists_;
-
- // Records whether or not each feature was enabled for this frame by its
- // parent frame.
- // TODO(iclelland): Generate, instead of this map, a set of bool flags, one
- // for each feature, as all features are supposed to be represented here.
- std::map<blink::WebFeaturePolicyFeature, bool> inherited_policies_;
-
- const FeatureList& feature_list_;
-
- DISALLOW_COPY_AND_ASSIGN(FeaturePolicy);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_FEATURE_POLICY_FEATURE_POLICY_H_
diff --git a/chromium/content/common/feature_policy/feature_policy_unittest.cc b/chromium/content/common/feature_policy/feature_policy_unittest.cc
deleted file mode 100644
index 1be6290d33e..00000000000
--- a/chromium/content/common/feature_policy/feature_policy_unittest.cc
+++ /dev/null
@@ -1,1007 +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/common/feature_policy/feature_policy.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace content {
-
-namespace {
-
-blink::WebFeaturePolicyFeature kDefaultOnFeature =
- static_cast<blink::WebFeaturePolicyFeature>(
- static_cast<int>(blink::WebFeaturePolicyFeature::LAST_FEATURE) + 1);
-
-blink::WebFeaturePolicyFeature kDefaultSelfFeature =
- static_cast<blink::WebFeaturePolicyFeature>(
- static_cast<int>(blink::WebFeaturePolicyFeature::LAST_FEATURE) + 2);
-
-blink::WebFeaturePolicyFeature kDefaultOffFeature =
- static_cast<blink::WebFeaturePolicyFeature>(
- static_cast<int>(blink::WebFeaturePolicyFeature::LAST_FEATURE) + 3);
-
-} // namespace
-
-class FeaturePolicyTest : public ::testing::Test {
- protected:
- FeaturePolicyTest()
- : feature_list_(
- {{kDefaultOnFeature, FeaturePolicy::FeatureDefault::EnableForAll},
- {kDefaultSelfFeature,
- FeaturePolicy::FeatureDefault::EnableForSelf},
- {kDefaultOffFeature,
- FeaturePolicy::FeatureDefault::DisableForAll}}) {}
-
- ~FeaturePolicyTest() override {}
-
- std::unique_ptr<FeaturePolicy> CreateFromParentPolicy(
- const FeaturePolicy* parent,
- const url::Origin& origin) {
- ParsedFeaturePolicyHeader empty_container_policy;
- return FeaturePolicy::CreateFromParentPolicy(parent, empty_container_policy,
- origin, feature_list_);
- }
-
- std::unique_ptr<FeaturePolicy> CreateFromParentWithFramePolicy(
- const FeaturePolicy* parent,
- const ParsedFeaturePolicyHeader& frame_policy,
- const url::Origin& origin) {
- return FeaturePolicy::CreateFromParentPolicy(parent, frame_policy, origin,
- feature_list_);
- }
- url::Origin origin_a_ = url::Origin(GURL("https://example.com/"));
- url::Origin origin_b_ = url::Origin(GURL("https://example.net/"));
- url::Origin origin_c_ = url::Origin(GURL("https://example.org/"));
-
- private:
- // Contains the list of controlled features, so that we are guaranteed to
- // have at least one of each kind of default behaviour represented.
- FeaturePolicy::FeatureList feature_list_;
-};
-
-TEST_F(FeaturePolicyTest, TestInitialPolicy) {
- // +-------------+
- // |(1)Origin A |
- // |No Policy |
- // +-------------+
- // Default-on and top-level-only features should be enabled in top-level
- // frame. Default-off features should be disabled.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy1->IsFeatureEnabled(kDefaultOffFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestInitialSameOriginChildPolicy) {
- // +-----------------+
- // |(1)Origin A |
- // |No Policy |
- // | +-------------+ |
- // | |(2)Origin A | |
- // | |No Policy | |
- // | +-------------+ |
- // +-----------------+
- // Default-on and Default-self features should be enabled in a same-origin
- // child frame. Default-off features should be disabled.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_a_);
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultOffFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestInitialCrossOriginChildPolicy) {
- // +-----------------+
- // |(1)Origin A |
- // |No Policy |
- // | +-------------+ |
- // | |(2)Origin B | |
- // | |No Policy | |
- // | +-------------+ |
- // +-----------------+
- // Default-on features should be enabled in child frame. Default-self and
- // Default-off features should be disabled.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultOffFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestCrossOriginChildCannotEnableFeature) {
- // +---------------------------------------+
- // |(1) Origin A |
- // |No Policy |
- // | +-----------------------------------+ |
- // | |(2) Origin B | |
- // | |Policy: {"default-self": ["self"]} | |
- // | +-----------------------------------+ |
- // +---------------------------------------+
- // Default-self feature should be disabled in cross origin frame, even if no
- // policy was specified in the parent frame.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- policy2->SetHeaderPolicy({{{kDefaultSelfFeature, false, {origin_b_}}}});
- EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestFrameSelfInheritance) {
- // +------------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-self": ["self"]} |
- // | +-----------------+ +-----------------+ |
- // | |(2) Origin A | |(4) Origin B | |
- // | |No Policy | |No Policy | |
- // | | +-------------+ | | +-------------+ | |
- // | | |(3)Origin A | | | |(5)Origin B | | |
- // | | |No Policy | | | |No Policy | | |
- // | | +-------------+ | | +-------------+ | |
- // | +-----------------+ +-----------------+ |
- // +------------------------------------------+
- // Feature should be enabled at the top-level, and through the chain of
- // same-origin frames 2 and 3. It should be disabled in frames 4 and 5, as
- // they are at a different origin.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy({{{kDefaultSelfFeature, false, {origin_a_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_a_);
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_a_);
- std::unique_ptr<FeaturePolicy> policy4 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy5 =
- CreateFromParentPolicy(policy4.get(), origin_b_);
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_TRUE(policy3->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy4->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy5->IsFeatureEnabled(kDefaultSelfFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestReflexiveFrameSelfInheritance) {
- // +-----------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-self": ["self"]} |
- // | +-----------------+ |
- // | |(2) Origin B | |
- // | |No Policy | |
- // | | +-------------+ | |
- // | | |(3)Origin A | | |
- // | | |No Policy | | |
- // | | +-------------+ | |
- // | +-----------------+ |
- // +-----------------------------------+
- // Feature which is enabled at top-level should be disabled in frame 3, as
- // it is embedded by frame 2, for which the feature is not enabled.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy({{{kDefaultSelfFeature, false, {origin_a_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_a_);
- EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy3->IsFeatureEnabled(kDefaultSelfFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestSelectiveFrameInheritance) {
- // +------------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-self": ["Origin B"]} |
- // | +-----------------+ +-----------------+ |
- // | |(2) Origin B | |(3) Origin C | |
- // | |No Policy | |No Policy | |
- // | | | | +-------------+ | |
- // | | | | |(4)Origin B | | |
- // | | | | |No Policy | | |
- // | | | | +-------------+ | |
- // | +-----------------+ +-----------------+ |
- // +------------------------------------------+
- // Feature should be enabled in second level Origin B frame, but disabled in
- // Frame 4, because it is embedded by frame 3, where the feature is not
- // enabled.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy({{{kDefaultSelfFeature, false, {origin_b_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy1.get(), origin_c_);
- std::unique_ptr<FeaturePolicy> policy4 =
- CreateFromParentPolicy(policy3.get(), origin_b_);
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy3->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy4->IsFeatureEnabled(kDefaultSelfFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestPolicyCanBlockSelf) {
- // +----------------------------+
- // |(1)Origin A |
- // |Policy: {"default-on": []} |
- // +----------------------------+
- // Default-on feature should be disabled in top-level frame.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultOnFeature, false, std::vector<url::Origin>()}}});
- EXPECT_FALSE(policy1->IsFeatureEnabled(kDefaultOnFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestParentPolicyBlocksSameOriginChildPolicy) {
- // +----------------------------+
- // |(1)Origin A |
- // |Policy: {"default-on": []} |
- // | +-------------+ |
- // | |(2)Origin A | |
- // | |No Policy | |
- // | +-------------+ |
- // +----------------------------+
- // Feature should be disabled in child frame.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultOnFeature, false, std::vector<url::Origin>()}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_a_);
- EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultOnFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestChildPolicyCanBlockSelf) {
- // +--------------------------------+
- // |(1)Origin A |
- // |No Policy |
- // | +----------------------------+ |
- // | |(2)Origin B | |
- // | |Policy: {"default-on": []} | |
- // | +----------------------------+ |
- // +--------------------------------+
- // Default-on feature should be disabled by cross-origin child frame.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- policy2->SetHeaderPolicy(
- {{{kDefaultOnFeature, false, std::vector<url::Origin>()}}});
- EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultOnFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestChildPolicyCanBlockChildren) {
- // +--------------------------------------+
- // |(1)Origin A |
- // |No Policy |
- // | +----------------------------------+ |
- // | |(2)Origin B | |
- // | |Policy: {"default-on": ["self"]} | |
- // | | +-------------+ | |
- // | | |(3)Origin C | | |
- // | | |No Policy | | |
- // | | +-------------+ | |
- // | +----------------------------------+ |
- // +--------------------------------------+
- // Default-on feature should be enabled in frames 1 and 2; disabled in frame
- // 3 by child frame policy.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- policy2->SetHeaderPolicy({{{kDefaultOnFeature, false, {origin_b_}}}});
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_FALSE(policy3->IsFeatureEnabled(kDefaultOnFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestParentPolicyBlocksCrossOriginChildPolicy) {
- // +----------------------------+
- // |(1)Origin A |
- // |Policy: {"default-on": []} |
- // | +-------------+ |
- // | |(2)Origin B | |
- // | |No Policy | |
- // | +-------------+ |
- // +----------------------------+
- // Default-on feature should be disabled in cross-origin child frame.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultOnFeature, false, std::vector<url::Origin>()}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultOnFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestEnableForAllOrigins) {
- // +--------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-self": ["*"]} |
- // | +-----------------+ |
- // | |(2) Origin B | |
- // | |No Policy | |
- // | | +-------------+ | |
- // | | |(3)Origin A | | |
- // | | |No Policy | | |
- // | | +-------------+ | |
- // | +-----------------+ |
- // +--------------------------------+
- // Feature should be enabled in top and second level; disabled in frame 3.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultSelfFeature, true, std::vector<url::Origin>()}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_a_);
- EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy3->IsFeatureEnabled(kDefaultSelfFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestDefaultOnEnablesForAllAncestors) {
- // +---------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-on": ["Origin B"]} |
- // | +-----------------------------------+ |
- // | |(2) Origin B | |
- // | |No Policy | |
- // | | +-------------+ +-------------+ | |
- // | | |(3)Origin B | |(4)Origin C | | |
- // | | |No Policy | |No Policy | | |
- // | | +-------------+ +-------------+ | |
- // | +-----------------------------------+ |
- // +---------------------------------------+
- // Feature should be disabled in frame 1; enabled in frames 2, 3 and 4.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy({{{kDefaultOnFeature, false, {origin_b_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy4 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- EXPECT_FALSE(policy1->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_TRUE(policy3->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_TRUE(policy4->IsFeatureEnabled(kDefaultOnFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestDefaultSelfRespectsSameOriginEmbedding) {
- // +---------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-self": ["Origin B"]} |
- // | +-----------------------------------+ |
- // | |(2) Origin B | |
- // | |No Policy | |
- // | | +-------------+ +-------------+ | |
- // | | |(3)Origin B | |(4)Origin C | | |
- // | | |No Policy | |No Policy | | |
- // | | +-------------+ +-------------+ | |
- // | +-----------------------------------+ |
- // +---------------------------------------+
- // Feature should be disabled in frames 1 and 4; enabled in frames 2 and 3.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy({{{kDefaultSelfFeature, false, {origin_b_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy4 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- EXPECT_FALSE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_TRUE(policy3->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy4->IsFeatureEnabled(kDefaultSelfFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestDefaultOffMustBeDelegatedToAllCrossOriginFrames) {
- // +------------------------------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-off": ["Origin B"]} |
- // | +--------------------------------------------------------+ |
- // | |(2) Origin B | |
- // | |Policy: {"default-off": ["self"]} | |
- // | | +-------------+ +----------------------------------+ | |
- // | | |(3)Origin B | |(4)Origin C | | |
- // | | |No Policy | |Policy: {"default-off": ["self"]} | | |
- // | | +-------------+ +----------------------------------+ | |
- // | +--------------------------------------------------------+ |
- // +------------------------------------------------------------+
- // Feature should be disabled in frames 1, 3 and 4; enabled in frame 2 only.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy({{{kDefaultOffFeature, false, {origin_b_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- policy2->SetHeaderPolicy({{{kDefaultOffFeature, false, {origin_b_}}}});
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy4 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- policy4->SetHeaderPolicy({{{kDefaultOffFeature, false, {origin_c_}}}});
- EXPECT_FALSE(policy1->IsFeatureEnabled(kDefaultOffFeature));
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultOffFeature));
- EXPECT_FALSE(policy3->IsFeatureEnabled(kDefaultOffFeature));
- EXPECT_FALSE(policy4->IsFeatureEnabled(kDefaultOffFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestReenableForAllOrigins) {
- // +------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-self": ["*"]} |
- // | +--------------------------------+ |
- // | |(2) Origin B | |
- // | |Policy: {"default-self": ["*"]} | |
- // | | +-------------+ | |
- // | | |(3)Origin A | | |
- // | | |No Policy | | |
- // | | +-------------+ | |
- // | +--------------------------------+ |
- // +------------------------------------+
- // Feature should be enabled in all frames.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultSelfFeature, true, std::vector<url::Origin>()}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- policy2->SetHeaderPolicy(
- {{{kDefaultSelfFeature, true, std::vector<url::Origin>()}}});
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_a_);
- EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_TRUE(policy3->IsFeatureEnabled(kDefaultSelfFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestBlockedFrameCannotReenable) {
- // +--------------------------------------+
- // |(1)Origin A |
- // |Policy: {"default-self": ["self"]} |
- // | +----------------------------------+ |
- // | |(2)Origin B | |
- // | |Policy: {"default-self": ["*"]} | |
- // | | +-------------+ +-------------+ | |
- // | | |(3)Origin A | |(4)Origin C | | |
- // | | |No Policy | |No Policy | | |
- // | | +-------------+ +-------------+ | |
- // | +----------------------------------+ |
- // +--------------------------------------+
- // Feature should be enabled at the top level; disabled in all other frames.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy({{{kDefaultSelfFeature, false, {origin_a_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- policy2->SetHeaderPolicy(
- {{{kDefaultSelfFeature, true, std::vector<url::Origin>()}}});
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_a_);
- std::unique_ptr<FeaturePolicy> policy4 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy3->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy4->IsFeatureEnabled(kDefaultSelfFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestEnabledFrameCanDelegate) {
- // +---------------------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-self": ["self", "Origin B"]} |
- // | +-----------------------------------------------+ |
- // | |(2) Origin B | |
- // | |Policy: {"default-self": ["self", "Origin C"]} | |
- // | | +-------------+ | |
- // | | |(3)Origin C | | |
- // | | |No Policy | | |
- // | | +-------------+ | |
- // | +-----------------------------------------------+ |
- // +---------------------------------------------------+
- // Feature should be enabled in all frames.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultSelfFeature, false, {origin_a_, origin_b_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- policy2->SetHeaderPolicy(
- {{{kDefaultSelfFeature, false, {origin_b_, origin_c_}}}});
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_TRUE(policy3->IsFeatureEnabled(kDefaultSelfFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestEnabledFrameCanDelegateByDefault) {
- // +-----------------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-on": ["self", "Origin B"]} |
- // | +--------------------+ +--------------------+ |
- // | |(2) Origin B | | (4) Origin C | |
- // | |No Policy | | No Policy | |
- // | | +-------------+ | | | |
- // | | |(3)Origin C | | | | |
- // | | |No Policy | | | | |
- // | | +-------------+ | | | |
- // | +--------------------+ +--------------------+ |
- // +-----------------------------------------------+
- // Feature should be enabled in frames 1, 2, and 3, and disabled in frame 4.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultOnFeature, false, {origin_a_, origin_b_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- std::unique_ptr<FeaturePolicy> policy4 =
- CreateFromParentPolicy(policy1.get(), origin_c_);
- EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_TRUE(policy3->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_FALSE(policy4->IsFeatureEnabled(kDefaultOnFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestNonNestedFeaturesDontDelegateByDefault) {
- // +-----------------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-self": ["self", "Origin B"]} |
- // | +--------------------+ +--------------------+ |
- // | |(2) Origin B | | (4) Origin C | |
- // | |No Policy | | No Policy | |
- // | | +-------------+ | | | |
- // | | |(3)Origin C | | | | |
- // | | |No Policy | | | | |
- // | | +-------------+ | | | |
- // | +--------------------+ +--------------------+ |
- // +-----------------------------------------------+
- // Feature should be enabled in frames 1 and 2, and disabled in frames 3 and
- // 4.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultSelfFeature, false, {origin_a_, origin_b_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- std::unique_ptr<FeaturePolicy> policy4 =
- CreateFromParentPolicy(policy1.get(), origin_c_);
- EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy3->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy4->IsFeatureEnabled(kDefaultSelfFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestFeaturesAreIndependent) {
- // +-----------------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-self": ["self", "Origin B"], |
- // | "default-on": ["self"]} |
- // | +-------------------------------------------+ |
- // | |(2) Origin B | |
- // | |Policy: {"default-self": ["*"], | |
- // | | "default-on": ["*"]} | |
- // | | +-------------+ | |
- // | | |(3)Origin C | | |
- // | | |No Policy | | |
- // | | +-------------+ | |
- // | +-------------------------------------------+ |
- // +-----------------------------------------------+
- // Default-self feature should be enabled in all frames; Default-on feature
- // should be enabled in frame 1, and disabled in frames 2 and 3.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultSelfFeature, false, {origin_a_, origin_b_}},
- {kDefaultOnFeature, false, {origin_a_}}}});
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentPolicy(policy1.get(), origin_b_);
- policy2->SetHeaderPolicy(
- {{{kDefaultSelfFeature, true, std::vector<url::Origin>()},
- {kDefaultOnFeature, true, std::vector<url::Origin>()}}});
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_TRUE(policy1->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_TRUE(policy2->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy2->IsFeatureEnabled(kDefaultOnFeature));
- EXPECT_TRUE(policy3->IsFeatureEnabled(kDefaultSelfFeature));
- EXPECT_FALSE(policy3->IsFeatureEnabled(kDefaultOnFeature));
-}
-
-TEST_F(FeaturePolicyTest, TestFeatureEnabledForOrigin) {
- // +-----------------------------------------------+
- // |(1) Origin A |
- // |Policy: {"default-off": ["self", "Origin B"]} |
- // +-----------------------------------------------+
- // Features should be enabled by the policy in frame 1 for origins A and B,
- // and disabled for origin C.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultOffFeature, false, {origin_a_, origin_b_}}}});
- EXPECT_TRUE(
- policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_a_));
- EXPECT_TRUE(
- policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_b_));
- EXPECT_FALSE(
- policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_c_));
-}
-
-// Test frame policies
-
-TEST_F(FeaturePolicyTest, TestSimpleFramePolicy) {
- // +-------------------------------------------------+
- // |(1)Origin A |
- // |No Policy |
- // | |
- // |<iframe policy='{"default-self": ["Origin B"]}'> |
- // | +-------------+ |
- // | |(2)Origin B | |
- // | |No Policy | |
- // | +-------------+ |
- // +-------------------------------------------------+
- // Default-self feature should be enabled in cross-origin child frame because
- // permission was delegated through frame policy.
- // This is the same scenario as when the iframe is declared as
- // <iframe allow="default-self">
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- ParsedFeaturePolicyHeader frame_policy = {
- {{kDefaultSelfFeature, false, {origin_b_}}}};
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy, origin_b_);
- EXPECT_TRUE(
- policy1->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_a_));
- EXPECT_FALSE(
- policy1->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_c_));
- EXPECT_FALSE(
- policy1->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_c_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_a_));
- EXPECT_TRUE(
- policy2->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_b_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_c_));
-}
-
-TEST_F(FeaturePolicyTest, TestAllOriginFramePolicy) {
- // +------------------------------------------+
- // |(1)Origin A |
- // |No Policy |
- // | |
- // |<iframe policy='{"default-self": ["*"]}'> |
- // | +-------------+ |
- // | |(2)Origin B | |
- // | |No Policy | |
- // | +-------------+ |
- // +------------------------------------------+
- // Default-self feature should be enabled in cross-origin child frame because
- // permission was delegated through frame policy.
- // This is the same scenario that arises when the iframe is declared as
- // <iframe allowfullscreen>
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- ParsedFeaturePolicyHeader frame_policy = {
- {{kDefaultSelfFeature, true, std::vector<url::Origin>()}}};
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy, origin_b_);
- EXPECT_TRUE(
- policy1->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_a_));
- EXPECT_FALSE(
- policy1->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_b_));
- EXPECT_FALSE(
- policy1->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_c_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_a_));
- EXPECT_TRUE(
- policy2->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_b_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_c_));
-}
-
-TEST_F(FeaturePolicyTest, TestFramePolicyCanBeFurtherDelegated) {
- // +-----------------------------------------------------+
- // |(1)Origin A |
- // |No Policy |
- // | |
- // |<iframe policy='{"default-self": ["Origin B"]}'> |
- // | +-------------------------------------------------+ |
- // | |(2)Origin B | |
- // | |No Policy | |
- // | | | |
- // | |<iframe policy='{"default-self": ["Origin C"]}'> | |
- // | | +-------------+ | |
- // | | |(3)Origin C | | |
- // | | |No Policy | | |
- // | | +-------------+ | |
- // | | | |
- // | |<iframe> (No frame policy) | |
- // | | +-------------+ | |
- // | | |(4)Origin C | | |
- // | | |No Policy | | |
- // | | +-------------+ | |
- // | +-------------------------------------------------+ |
- // +-----------------------------------------------------+
- // Default-self feature should be enabled in cross-origin child frames 2 and
- // 3. Feature should be disabled in frame 4 because it was not further
- // delegated through frame policy.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- ParsedFeaturePolicyHeader frame_policy1 = {
- {{kDefaultSelfFeature, false, {origin_b_}}}};
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_b_);
- ParsedFeaturePolicyHeader frame_policy2 = {
- {{kDefaultSelfFeature, false, {origin_c_}}}};
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentWithFramePolicy(policy2.get(), frame_policy2, origin_c_);
- std::unique_ptr<FeaturePolicy> policy4 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_a_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_b_));
- EXPECT_TRUE(
- policy3->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_c_));
- EXPECT_FALSE(
- policy4->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_a_));
- EXPECT_FALSE(
- policy4->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_b_));
- EXPECT_FALSE(
- policy4->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_c_));
-}
-
-TEST_F(FeaturePolicyTest, TestDefaultOnCanBeDisabledByFramePolicy) {
- // +-------------------------------------+
- // |(1)Origin A |
- // |No Policy |
- // | |
- // |<iframe policy='{"default-on": []}'> |
- // | +-------------+ |
- // | |(2)Origin A | |
- // | |No Policy | |
- // | +-------------+ |
- // | |
- // |<iframe policy='{"default-on": []}'> |
- // | +-------------+ |
- // | |(3)Origin B | |
- // | |No Policy | |
- // | +-------------+ |
- // +-------------------------------------+
- // Default-on feature should be disabled in both same-origin and cross-origin
- // child frames because permission was removed through frame policy.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- ParsedFeaturePolicyHeader frame_policy1 = {
- {{kDefaultOnFeature, false, std::vector<url::Origin>()}}};
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_a_);
- ParsedFeaturePolicyHeader frame_policy2 = {
- {{kDefaultOnFeature, false, std::vector<url::Origin>()}}};
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy2, origin_b_);
- EXPECT_TRUE(policy1->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_a_));
- EXPECT_TRUE(policy1->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_b_));
- EXPECT_TRUE(policy1->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_c_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_a_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_b_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_c_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_a_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_b_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultOnFeature, origin_c_));
-}
-
-TEST_F(FeaturePolicyTest, TestDefaultOffMustBeEnabledByChildFrame) {
- // +------------------------------------------------+
- // |(1)Origin A |
- // |Policy: {"default-off": ["self"]} |
- // | |
- // |<iframe policy='{"default-off": ["Origin A"]}'> |
- // | +-------------+ |
- // | |(2)Origin A | |
- // | |No Policy | |
- // | +-------------+ |
- // | |
- // |<iframe policy='{"default-off": ["Origin B"]}'> |
- // | +-------------+ |
- // | |(3)Origin B | |
- // | |No Policy | |
- // | +-------------+ |
- // +------------------------------------------------+
- // Default-off feature should be disabled in both same-origin and cross-origin
- // child frames because they did not declare their own policy to enable it.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy({{{kDefaultOffFeature, false, {origin_a_}}}});
- ParsedFeaturePolicyHeader frame_policy1 = {
- {{kDefaultOffFeature, false, {origin_a_}}}};
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_a_);
- ParsedFeaturePolicyHeader frame_policy2 = {
- {{kDefaultOffFeature, false, {origin_b_}}}};
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy2, origin_b_);
- EXPECT_TRUE(
- policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_a_));
- EXPECT_FALSE(
- policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_b_));
- EXPECT_FALSE(
- policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_c_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_a_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_b_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_c_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_a_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_b_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_c_));
-}
-
-TEST_F(FeaturePolicyTest, TestDefaultOffCanBeEnabledByChildFrame) {
- // +------------------------------------------------+
- // |(1)Origin A |
- // |Policy: {"default-off": ["self"]} |
- // | |
- // |<iframe policy='{"default-off": ["Origin A"]}'> |
- // | +--------------------------------------------+ |
- // | |(2)Origin A | |
- // | |Policy: {"default-off": ["self"]} | |
- // | +--------------------------------------------+ |
- // | |
- // |<iframe policy='{"default-off": ["Origin B"]}'> |
- // | +--------------------------------------------+ |
- // | |(3)Origin B | |
- // | |Policy: {"default-off": ["self"]} | |
- // | +--------------------------------------------+ |
- // +------------------------------------------------+
- // Default-off feature should be enabled in both same-origin and cross-origin
- // child frames because it is delegated through the parent's frame policy, and
- // they declare their own policy to enable it.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy({{{kDefaultOffFeature, false, {origin_a_}}}});
- ParsedFeaturePolicyHeader frame_policy1 = {
- {{kDefaultOffFeature, false, {origin_a_}}}};
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_a_);
- policy2->SetHeaderPolicy({{{kDefaultOffFeature, false, {origin_a_}}}});
- ParsedFeaturePolicyHeader frame_policy2 = {
- {{kDefaultOffFeature, false, {origin_b_}}}};
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy2, origin_b_);
- policy3->SetHeaderPolicy({{{kDefaultOffFeature, false, {origin_b_}}}});
- EXPECT_TRUE(
- policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_a_));
- EXPECT_FALSE(
- policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_b_));
- EXPECT_FALSE(
- policy1->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_c_));
- EXPECT_TRUE(
- policy2->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_a_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_b_));
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_c_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_a_));
- EXPECT_TRUE(
- policy3->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_b_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultOffFeature, origin_c_));
-}
-
-TEST_F(FeaturePolicyTest, TestFramePolicyModifiesHeaderPolicy) {
- // +-----------------------------------------------+
- // |(1)Origin A |
- // |Policy: {"default-self": ["self", "Origin B"]} |
- // | |
- // |<iframe policy='{"default-self": []}'> |
- // | +-------------------------------------------+ |
- // | |(2)Origin B | |
- // | |No Policy | |
- // | +-------------------------------------------+ |
- // | |
- // |<iframe policy='{"default-self": []}'> |
- // | +-------------------------------------------+ |
- // | |(3)Origin B | |
- // | |Policy: {"default-self": ["self"]} | |
- // | +-------------------------------------------+ |
- // +-----------------------------------------------+
- // Default-self feature should be disabled in both cross-origin child frames
- // by frame policy, even though the parent frame's header policy would
- // otherwise enable it. This is true regardless of the child frame's header
- // policy.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- policy1->SetHeaderPolicy(
- {{{kDefaultSelfFeature, false, {origin_a_, origin_b_}}}});
- ParsedFeaturePolicyHeader frame_policy1 = {
- {{kDefaultSelfFeature, false, std::vector<url::Origin>()}}};
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_b_);
- ParsedFeaturePolicyHeader frame_policy2 = {
- {{kDefaultSelfFeature, false, std::vector<url::Origin>()}}};
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy2, origin_b_);
- policy3->SetHeaderPolicy({{{kDefaultSelfFeature, false, {origin_b_}}}});
- EXPECT_FALSE(
- policy2->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_b_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_b_));
-}
-
-TEST_F(FeaturePolicyTest, TestCombineFrameAndHeaderPolicies) {
- // +-------------------------------------------------+
- // |(1)Origin A |
- // |No Policy |
- // | |
- // |<iframe policy='{"default-self": ["Origin B"]}'> |
- // | +---------------------------------------------+ |
- // | |(2)Origin B | |
- // | |Policy: {"default-self": ["*"]} | |
- // | | | |
- // | |<iframe policy='{"default-self": []}'> | |
- // | | +-------------+ | |
- // | | |(3)Origin C | | |
- // | | |No Policy | | |
- // | | +-------------+ | |
- // | | | |
- // | |<iframe> (No frame policy) | |
- // | | +-------------+ | |
- // | | |(4)Origin C | | |
- // | | |No Policy | | |
- // | | +-------------+ | |
- // | +---------------------------------------------+ |
- // +-------------------------------------------------+
- // Default-self feature should be enabled in cross-origin child frames 2 and
- // 4. Feature should be disabled in frame 3 by frame policy.
- std::unique_ptr<FeaturePolicy> policy1 =
- CreateFromParentPolicy(nullptr, origin_a_);
- ParsedFeaturePolicyHeader frame_policy1 = {
- {{kDefaultSelfFeature, false, {origin_b_}}}};
- std::unique_ptr<FeaturePolicy> policy2 =
- CreateFromParentWithFramePolicy(policy1.get(), frame_policy1, origin_b_);
- policy2->SetHeaderPolicy(
- {{{kDefaultSelfFeature, true, std::vector<url::Origin>()}}});
- ParsedFeaturePolicyHeader frame_policy2 = {
- {{kDefaultSelfFeature, false, std::vector<url::Origin>()}}};
- std::unique_ptr<FeaturePolicy> policy3 =
- CreateFromParentWithFramePolicy(policy2.get(), frame_policy2, origin_c_);
- std::unique_ptr<FeaturePolicy> policy4 =
- CreateFromParentPolicy(policy2.get(), origin_c_);
- EXPECT_TRUE(
- policy1->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_a_));
- EXPECT_TRUE(
- policy2->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_b_));
- EXPECT_FALSE(
- policy3->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_c_));
- EXPECT_TRUE(
- policy4->IsFeatureEnabledForOrigin(kDefaultSelfFeature, origin_c_));
-}
-
-} // namespace content
diff --git a/chromium/content/common/font_cache_dispatcher_win.cc b/chromium/content/common/font_cache_dispatcher_win.cc
index a4c897c2589..49fd1e96204 100644
--- a/chromium/content/common/font_cache_dispatcher_win.cc
+++ b/chromium/content/common/font_cache_dispatcher_win.cc
@@ -10,7 +10,8 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string16.h"
-#include "content/common/child_process_messages.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
namespace content {
namespace {
@@ -131,41 +132,20 @@ class FontCache {
}
-FontCacheDispatcher::FontCacheDispatcher()
- : sender_(NULL) {
-}
-
-bool FontCacheDispatcher::Send(IPC::Message* message) {
- if (sender_)
- return sender_->Send(message);
-
- delete message;
- return false;
-}
+FontCacheDispatcher::FontCacheDispatcher() {}
FontCacheDispatcher::~FontCacheDispatcher() {
}
-void FontCacheDispatcher::OnFilterAdded(IPC::Channel* channel) {
- sender_ = channel;
-}
-
-bool FontCacheDispatcher::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(FontCacheDispatcher, message)
- IPC_MESSAGE_HANDLER(ChildProcessHostMsg_PreCacheFont, OnPreCacheFont)
- IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ReleaseCachedFonts,
- OnReleaseCachedFonts)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void FontCacheDispatcher::OnChannelClosing() {
- sender_ = NULL;
+// static
+void FontCacheDispatcher::Create(
+ mojom::FontCacheWinRequest request,
+ const service_manager::BindSourceInfo& source_info) {
+ mojo::MakeStrongBinding(std::make_unique<FontCacheDispatcher>(),
+ std::move(request));
}
-void FontCacheDispatcher::OnPreCacheFont(const LOGFONT& font) {
+void FontCacheDispatcher::PreCacheFont(const LOGFONT& font) {
// If a child process is running in a sandbox, GetTextMetrics()
// can sometimes fail. If a font has not been loaded
// previously, GetTextMetrics() will try to load the font
@@ -182,7 +162,7 @@ void FontCacheDispatcher::OnPreCacheFont(const LOGFONT& font) {
FontCache::GetInstance()->PreCacheFont(font, this);
}
-void FontCacheDispatcher::OnReleaseCachedFonts() {
+void FontCacheDispatcher::ReleaseCachedFonts() {
// Release cached fonts that requested from a pid by decrementing the ref
// count. When ref count is zero, the handles are released.
FontCache::GetInstance()->ReleaseCachedFonts(this);
diff --git a/chromium/content/common/font_cache_dispatcher_win.h b/chromium/content/common/font_cache_dispatcher_win.h
index e5d5ca0799b..e817c3dcc79 100644
--- a/chromium/content/common/font_cache_dispatcher_win.h
+++ b/chromium/content/common/font_cache_dispatcher_win.h
@@ -9,34 +9,29 @@
#include "base/macros.h"
#include "base/memory/singleton.h"
-#include "ipc/ipc_sender.h"
-#include "ipc/message_filter.h"
+#include "content/common/font_cache_win.mojom.h"
+
+namespace service_manager {
+struct BindSourceInfo;
+}
namespace content {
// Dispatches messages used for font caching on Windows. This is needed because
// Windows can't load fonts into its kernel cache in sandboxed processes. So the
// sandboxed process asks the browser process to do this for it.
-class FontCacheDispatcher : public IPC::MessageFilter, public IPC::Sender {
+class FontCacheDispatcher : public mojom::FontCacheWin {
public:
FontCacheDispatcher();
-
- // IPC::Sender implementation:
- bool Send(IPC::Message* message) override;
-
- private:
~FontCacheDispatcher() override;
- // IPC::MessageFilter implementation:
- void OnFilterAdded(IPC::Channel* channel) override;
- bool OnMessageReceived(const IPC::Message& message) override;
- void OnChannelClosing() override;
-
- // Message handlers.
- void OnPreCacheFont(const LOGFONT& font);
- void OnReleaseCachedFonts();
+ static void Create(mojom::FontCacheWinRequest request,
+ const service_manager::BindSourceInfo& source_info);
- IPC::Sender* sender_;
+ private:
+ // mojom::FontCacheWin
+ void PreCacheFont(const LOGFONT&) override;
+ void ReleaseCachedFonts() override;
DISALLOW_COPY_AND_ASSIGN(FontCacheDispatcher);
};
diff --git a/chromium/content/common/font_cache_win.mojom b/chromium/content/common/font_cache_win.mojom
new file mode 100644
index 00000000000..8fd25748a4f
--- /dev/null
+++ b/chromium/content/common/font_cache_win.mojom
@@ -0,0 +1,18 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+import "mojo/common/logfont_win.mojom";
+
+// Messages sent from child processes to the browser on Windows only. This file
+// will not be built on other platforms.
+interface FontCacheWin {
+ // Request that the given font be loaded by the host so it's cached by the
+ // OS. Please see ChildProcessHost::PreCacheFont for details.
+ PreCacheFont(mojo.common.mojom.LOGFONT log_font);
+
+ // Release the cached fonts.
+ ReleaseCachedFonts();
+};
diff --git a/chromium/content/common/font_config_ipc_linux.cc b/chromium/content/common/font_config_ipc_linux.cc
index b1ad7cb0b3c..2596c992bcc 100644
--- a/chromium/content/common/font_config_ipc_linux.cc
+++ b/chromium/content/common/font_config_ipc_linux.cc
@@ -81,7 +81,7 @@ bool FontConfigIPC::matchFamilyName(const char familyName[],
uint8_t reply_buf[2048];
const ssize_t r = base::UnixDomainSocket::SendRecvMsg(
- fd_, reply_buf, sizeof(reply_buf), NULL, request);
+ fd_, reply_buf, sizeof(reply_buf), nullptr, request);
if (r == -1)
return false;
@@ -145,7 +145,7 @@ SkStreamAsset* FontConfigIPC::openStream(const FontIdentity& identity) {
const ssize_t r = base::UnixDomainSocket::SendRecvMsg(
fd_, reply_buf, sizeof(reply_buf), &result_fd, request);
if (r == -1)
- return NULL;
+ return nullptr;
base::Pickle reply(reinterpret_cast<char*>(reply_buf), r);
bool result;
@@ -153,7 +153,7 @@ SkStreamAsset* FontConfigIPC::openStream(const FontIdentity& identity) {
if (!iter.ReadBool(&result) || !result) {
if (result_fd)
CloseFD(result_fd);
- return NULL;
+ return nullptr;
}
return mapFileDescriptorToStream(result_fd);
diff --git a/chromium/content/common/font_list_fontconfig.cc b/chromium/content/common/font_list_fontconfig.cc
index 3a6062d63be..a14eae72b77 100644
--- a/chromium/content/common/font_list_fontconfig.cc
+++ b/chromium/content/common/font_list_fontconfig.cc
@@ -41,7 +41,7 @@ std::unique_ptr<base::ListValue> GetFontList_SlowBlocking() {
for (size_t i = 0; i < arraysize(allowed_formats); ++i) {
auto format_pattern = CreateFormatPattern(allowed_formats[i]);
std::unique_ptr<FcFontSet, decltype(&FcFontSetDestroy)> fontset(
- FcFontList(0, format_pattern.get(), object_set.get()),
+ FcFontList(nullptr, format_pattern.get(), object_set.get()),
FcFontSetDestroy);
for (int j = 0; j < fontset->nfont; ++j) {
char* family_string;
diff --git a/chromium/content/common/font_list_mac.mm b/chromium/content/common/font_list_mac.mm
index 2648a32c070..67d3d856609 100644
--- a/chromium/content/common/font_list_mac.mm
+++ b/chromium/content/common/font_list_mac.mm
@@ -34,7 +34,7 @@ std::unique_ptr<base::ListValue> GetFontList_SlowBlocking() {
for (NSString* family_name in sortedFonts) {
NSString* localized_family_name = fonts_dict[family_name];
- auto font_item = base::MakeUnique<base::ListValue>();
+ auto font_item = std::make_unique<base::ListValue>();
font_item->AppendString(base::SysNSStringToUTF16(family_name));
font_item->AppendString(base::SysNSStringToUTF16(localized_family_name));
font_list->Append(std::move(font_item));
diff --git a/chromium/content/common/font_list_win.cc b/chromium/content/common/font_list_win.cc
index cd1b8aaedc9..07ecc125142 100644
--- a/chromium/content/common/font_list_win.cc
+++ b/chromium/content/common/font_list_win.cc
@@ -47,7 +47,7 @@ std::unique_ptr<base::ListValue> GetFontList_SlowBlocking() {
std::unique_ptr<base::ListValue> font_list(new base::ListValue);
std::set<base::string16>::iterator iter;
for (iter = font_names.begin(); iter != font_names.end(); ++iter) {
- auto font_item = base::MakeUnique<base::ListValue>();
+ auto font_item = std::make_unique<base::ListValue>();
font_item->AppendString(*iter);
font_item->AppendString(*iter);
font_list->Append(std::move(font_item));
diff --git a/chromium/content/common/frame.mojom b/chromium/content/common/frame.mojom
index 2960e7c7a01..10c3996185b 100644
--- a/chromium/content/common/frame.mojom
+++ b/chromium/content/common/frame.mojom
@@ -4,7 +4,10 @@
module content.mojom;
+import "content/common/url_loader_factory_bundle.mojom";
+import "content/public/common/url_loader.mojom";
import "content/public/common/window_container_type.mojom";
+import "mojo/common/unguessable_token.mojom";
import "services/service_manager/public/interfaces/interface_provider.mojom";
import "third_party/WebKit/public/platform/referrer.mojom";
import "third_party/WebKit/public/web/window_features.mojom";
@@ -18,6 +21,45 @@ const string kNavigation_FrameSpec = "navigation:frame";
// Implemented by the frame provider (e.g. renderer processes).
interface Frame {
GetInterfaceProvider(service_manager.mojom.InterfaceProvider& interfaces);
+ GetCanonicalUrlForSharing() => (url.mojom.Url? canonical_url);
+};
+
+// See src/content/common/navigation_params.h
+[Native]
+struct CommonNavigationParams;
+
+// See src/content/common/navigation_params.h
+[Native]
+struct RequestNavigationParams;
+
+// Implemented by the frame provider and currently must be associated with the
+// legacy IPC channel.
+interface FrameNavigationControl {
+ // Tells the renderer that a navigation is ready to commit. The renderer
+ // should request |body_url| to get access to the stream containing the body
+ // of the response. When the Network Service is enabled, |body_url| is not
+ // used and instead the data is passed to the renderer via |body_data|. In
+ // that case |subresource_loader_factories| may also be provided by the
+ // browser as a a means for the renderer to load subresources where
+ // applicable.
+ //
+ // For automation driver-initiated navigations over the devtools protocol,
+ // |devtools_navigation_token_| is used to tag the navigation. This navigation
+ // token is then sent into the renderer and lands on the DocumentLoader. That
+ // way subsequent Blink-level frame lifecycle events can be associated with
+ // the concrete navigation.
+ // - The value should not be sent back to the browser.
+ // - The value on DocumentLoader may be generated in the renderer in some
+ // cases, and thus shouldn't be trusted.
+ // TODO(crbug.com/783506): Replace devtools navigation token with the generic
+ // navigation token that can be passed from renderer to the browser.
+ CommitNavigation(URLResponseHead head,
+ url.mojom.Url body_url,
+ CommonNavigationParams common_params,
+ RequestNavigationParams request_params,
+ handle<data_pipe_consumer>? body_data,
+ URLLoaderFactoryBundle? subresource_loader_factories,
+ mojo.common.mojom.UnguessableToken devtools_navigation_token);
};
// Implemented by the frame (e.g. renderer processes).
@@ -30,15 +72,10 @@ interface FrameBindingsControl {
AllowBindings(int32 enabled_bindings_flags);
};
-// Implemented by the frame server (i.e. the browser process).
-interface FrameHostInterfaceBroker {
- GetInterfaceProvider(service_manager.mojom.InterfaceProvider& interfaces);
-};
-
// Implemented by a service that provides implementations of the Frame
// interface. (e.g. renderer processes).
interface FrameFactory {
- CreateFrame(int32 frame_routing_id, Frame& frame, FrameHostInterfaceBroker host);
+ CreateFrame(int32 frame_routing_id, Frame& frame);
};
struct CreateNewWindowParams {
@@ -74,12 +111,20 @@ struct CreateNewWindowParams {
blink.mojom.WindowFeatures features;
};
+// Operation result when the renderer asks the browser to create a new window.
+enum CreateNewWindowStatus {
+ // Ignore creation of the new window. This can happen because creation is
+ // blocked or because the new window should have no opener relationship.
+ kIgnore,
+ // Reuse the current window rather than creating a new window.
+ kReuse,
+ // Create a new window using the corresponding params in |reply|.
+ kSuccess,
+};
+
+// All routing IDs in this struct must be set to a valid routing ID.
struct CreateNewWindowReply {
- // The ID of the view to be created. If the ID is MSG_ROUTING_NONE, then the
- // opener RenderFrame should not create a RenderView in its process.
- // MSG_ROUTING_NONE does not necessarily indicate failure; it may also occur
- // in cases where a window was created, but the opener relationship is
- // severed.
+ // The ID of the view to be created.
int32 route_id;
// The ID of the main frame hosted in the view.
@@ -88,8 +133,20 @@ struct CreateNewWindowReply {
// The ID of the widget for the main frame.
int32 main_frame_widget_route_id;
+ // The InterfaceProvider through which the main RenderFrame can access
+ // services exposed by its RenderFrameHost.
+ service_manager.mojom.InterfaceProvider main_frame_interface_provider;
+
// Duplicated from CreateNewWindowParams because legacy code.
int64 cloned_session_storage_namespace_id;
+
+ // Used for devtools instrumentation and trace-ability. The token is
+ // propagated to Blink's LocalFrame and both Blink and content/
+ // can tag calls and requests with this instrumentation token in order to
+ // attribute them to the context frame.
+ // |devtools_frame_token| is only defined by the browser and is never
+ // sent back from the renderer in the control calls.
+ mojo.common.mojom.UnguessableToken devtools_main_frame_token;
};
// An opaque handle that keeps alive the associated render process even after
@@ -102,11 +159,10 @@ struct DidCommitProvisionalLoadParams;
// Implemented by the frame server (i.e. the browser process). For messages that
// must be associated with the IPC channel.
interface FrameHost {
- // Sent by the renderer when it is creating a new window. The browser creates
- // a tab for it. If |reply.route_id| is MSG_ROUTING_NONE, the window couldn't
- // be created.
+ // Sent by the renderer to request the browser to create a new window. |reply|
+ // is only non-null on when status == CreateNewWindowStatus::kSuccess.
[Sync] CreateNewWindow(CreateNewWindowParams params)
- => (CreateNewWindowReply reply);
+ => (CreateNewWindowStatus status, CreateNewWindowReply? reply);
// Creates and returns a KeepAliveHandle.
IssueKeepAliveHandle(KeepAliveHandle& keep_alive_handle);
diff --git a/chromium/content/common/frame_messages.h b/chromium/content/common/frame_messages.h
index 18c4b420d78..3e00480ee1b 100644
--- a/chromium/content/common/frame_messages.h
+++ b/chromium/content/common/frame_messages.h
@@ -15,6 +15,7 @@
#include <string>
#include <vector>
+#include "base/optional.h"
#include "build/build_config.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/common/surfaces/surface_info.h"
@@ -46,16 +47,19 @@
#include "content/public/common/referrer.h"
#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_response.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 "ipc/ipc_message_macros.h"
#include "ipc/ipc_platform_file.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "ppapi/features/features.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
+#include "third_party/WebKit/common/frame_policy.h"
#include "third_party/WebKit/common/message_port/message_port_channel.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
#include "third_party/WebKit/public/platform/WebFocusType.h"
#include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h"
+#include "third_party/WebKit/public/platform/WebRemoteScrollProperties.h"
#include "third_party/WebKit/public/platform/WebSuddenTerminationDisablerType.h"
#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "third_party/WebKit/public/web/WebFrameOwnerProperties.h"
@@ -92,7 +96,12 @@ using FrameMsg_SerializeAsMHTML_FrameRoutingIdToContentIdMap =
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
#define IPC_MESSAGE_START FrameMsgStart
-
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebRemoteScrollProperties::Alignment,
+ blink::WebRemoteScrollProperties::kLastAlignment)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebRemoteScrollProperties::Type,
+ blink::WebRemoteScrollProperties::kLastType)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebRemoteScrollProperties::Behavior,
+ blink::WebRemoteScrollProperties::kLastBehavior)
IPC_ENUM_TRAITS_MIN_MAX_VALUE(content::JavaScriptDialogType,
content::JAVASCRIPT_DIALOG_TYPE_ALERT,
content::JAVASCRIPT_DIALOG_TYPE_PROMPT)
@@ -119,8 +128,8 @@ IPC_ENUM_TRAITS_MAX_VALUE(content::FileChooserParams::Mode,
content::FileChooserParams::Save)
IPC_ENUM_TRAITS_MAX_VALUE(content::CSPDirective::Name,
content::CSPDirective::NameLast)
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFeaturePolicyFeature,
- blink::WebFeaturePolicyFeature::LAST_FEATURE)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::FeaturePolicyFeature,
+ blink::FeaturePolicyFeature::LAST_FEATURE)
IPC_ENUM_TRAITS_MAX_VALUE(content::CSPDisposition,
content::CSPDisposition::LAST)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebTriggeringEventInfo,
@@ -133,6 +142,15 @@ IPC_STRUCT_TRAITS_BEGIN(blink::WebFindOptions)
IPC_STRUCT_TRAITS_MEMBER(force)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(blink::WebRemoteScrollProperties)
+ IPC_STRUCT_TRAITS_MEMBER(align_x)
+ IPC_STRUCT_TRAITS_MEMBER(align_y)
+ IPC_STRUCT_TRAITS_MEMBER(type)
+ IPC_STRUCT_TRAITS_MEMBER(make_visible_in_visual_viewport)
+ IPC_STRUCT_TRAITS_MEMBER(behavior)
+ IPC_STRUCT_TRAITS_MEMBER(is_for_scroll_sequence)
+IPC_STRUCT_TRAITS_END()
+
IPC_STRUCT_TRAITS_BEGIN(content::ColorSuggestion)
IPC_STRUCT_TRAITS_MEMBER(color)
IPC_STRUCT_TRAITS_MEMBER(label)
@@ -149,9 +167,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::ContextMenuParams)
IPC_STRUCT_TRAITS_MEMBER(has_image_contents)
IPC_STRUCT_TRAITS_MEMBER(properties)
IPC_STRUCT_TRAITS_MEMBER(page_url)
- IPC_STRUCT_TRAITS_MEMBER(keyword_url)
IPC_STRUCT_TRAITS_MEMBER(frame_url)
- IPC_STRUCT_TRAITS_MEMBER(frame_page_state)
IPC_STRUCT_TRAITS_MEMBER(media_flags)
IPC_STRUCT_TRAITS_MEMBER(selection_text)
IPC_STRUCT_TRAITS_MEMBER(title_text)
@@ -171,6 +187,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::ContextMenuParams)
IPC_STRUCT_TRAITS_MEMBER(source_type)
IPC_STRUCT_TRAITS_MEMBER(input_field_type)
IPC_STRUCT_TRAITS_MEMBER(selection_rect)
+ IPC_STRUCT_TRAITS_MEMBER(selection_start_offset)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::CustomContextMenuContext)
@@ -197,6 +214,11 @@ IPC_STRUCT_TRAITS_BEGIN(content::FrameOwnerProperties)
IPC_STRUCT_TRAITS_MEMBER(required_csp)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(blink::FramePolicy)
+ IPC_STRUCT_TRAITS_MEMBER(sandbox_flags)
+ IPC_STRUCT_TRAITS_MEMBER(container_policy)
+IPC_STRUCT_TRAITS_END()
+
IPC_STRUCT_TRAITS_BEGIN(content::PageImportanceSignals)
IPC_STRUCT_TRAITS_MEMBER(had_form_interaction)
IPC_STRUCT_TRAITS_END()
@@ -225,7 +247,21 @@ IPC_STRUCT_TRAITS_BEGIN(content::FrameNavigateParams)
IPC_STRUCT_TRAITS_MEMBER(redirects)
IPC_STRUCT_TRAITS_MEMBER(should_update_history)
IPC_STRUCT_TRAITS_MEMBER(contents_mime_type)
- IPC_STRUCT_TRAITS_MEMBER(socket_address)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(content::ScreenInfo)
+ IPC_STRUCT_TRAITS_MEMBER(device_scale_factor)
+ IPC_STRUCT_TRAITS_MEMBER(color_space)
+#if defined(OS_MACOSX)
+ IPC_STRUCT_TRAITS_MEMBER(icc_profile)
+#endif
+ IPC_STRUCT_TRAITS_MEMBER(depth)
+ IPC_STRUCT_TRAITS_MEMBER(depth_per_component)
+ IPC_STRUCT_TRAITS_MEMBER(is_monochrome)
+ IPC_STRUCT_TRAITS_MEMBER(rect)
+ IPC_STRUCT_TRAITS_MEMBER(available_rect)
+ IPC_STRUCT_TRAITS_MEMBER(orientation_type)
+ IPC_STRUCT_TRAITS_MEMBER(orientation_angle)
IPC_STRUCT_TRAITS_END()
// Parameters structure for mojom::FrameHost::DidCommitProvisionalLoad.
@@ -367,12 +403,12 @@ IPC_STRUCT_TRAITS_BEGIN(content::CommonNavigationParams)
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_END()
IPC_STRUCT_TRAITS_BEGIN(content::BeginNavigationParams)
IPC_STRUCT_TRAITS_MEMBER(headers)
IPC_STRUCT_TRAITS_MEMBER(load_flags)
- IPC_STRUCT_TRAITS_MEMBER(has_user_gesture)
IPC_STRUCT_TRAITS_MEMBER(skip_service_worker)
IPC_STRUCT_TRAITS_MEMBER(request_context_type)
IPC_STRUCT_TRAITS_MEMBER(mixed_content_context_type)
@@ -419,13 +455,12 @@ IPC_STRUCT_TRAITS_BEGIN(content::RequestNavigationParams)
IPC_STRUCT_TRAITS_MEMBER(navigation_timing)
IPC_STRUCT_TRAITS_MEMBER(service_worker_provider_id)
IPC_STRUCT_TRAITS_MEMBER(appcache_host_id)
- IPC_STRUCT_TRAITS_MEMBER(has_user_gesture)
#if defined(OS_ANDROID)
IPC_STRUCT_TRAITS_MEMBER(data_url_as_string)
#endif
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(content::ParsedFeaturePolicyDeclaration)
+IPC_STRUCT_TRAITS_BEGIN(blink::ParsedFeaturePolicyDeclaration)
IPC_STRUCT_TRAITS_MEMBER(feature)
IPC_STRUCT_TRAITS_MEMBER(matches_all_origins)
IPC_STRUCT_TRAITS_MEMBER(origins)
@@ -433,11 +468,10 @@ IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::FrameReplicationState)
IPC_STRUCT_TRAITS_MEMBER(origin)
- IPC_STRUCT_TRAITS_MEMBER(sandbox_flags)
IPC_STRUCT_TRAITS_MEMBER(name)
IPC_STRUCT_TRAITS_MEMBER(unique_name)
IPC_STRUCT_TRAITS_MEMBER(feature_policy_header)
- IPC_STRUCT_TRAITS_MEMBER(container_policy)
+ IPC_STRUCT_TRAITS_MEMBER(frame_policy)
IPC_STRUCT_TRAITS_MEMBER(accumulated_csp_headers)
IPC_STRUCT_TRAITS_MEMBER(scope)
IPC_STRUCT_TRAITS_MEMBER(insecure_request_policy)
@@ -560,8 +594,8 @@ IPC_STRUCT_BEGIN(FrameHostMsg_CreateChildFrame_Params)
IPC_STRUCT_MEMBER(blink::WebTreeScopeType, scope)
IPC_STRUCT_MEMBER(std::string, frame_name)
IPC_STRUCT_MEMBER(std::string, frame_unique_name)
- IPC_STRUCT_MEMBER(blink::WebSandboxFlags, sandbox_flags)
- IPC_STRUCT_MEMBER(content::ParsedFeaturePolicyHeader, container_policy)
+ IPC_STRUCT_MEMBER(bool, is_created_by_script)
+ IPC_STRUCT_MEMBER(blink::FramePolicy, frame_policy)
IPC_STRUCT_MEMBER(content::FrameOwnerProperties, frame_owner_properties)
IPC_STRUCT_END()
@@ -639,11 +673,6 @@ IPC_STRUCT_BEGIN(FrameMsg_MixedContentFound_Params)
IPC_STRUCT_MEMBER(content::SourceLocation, source_location)
IPC_STRUCT_END()
-IPC_STRUCT_BEGIN(FrameMsg_CommitDataNetworkService_Params)
- IPC_STRUCT_MEMBER(mojo::DataPipeConsumerHandle, handle)
- IPC_STRUCT_MEMBER(mojo::MessagePipeHandle, url_loader_factory)
-IPC_STRUCT_END()
-
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
// This message is used for supporting popup menus on Mac OS X and Android using
// native controls. See the FrameHostMsg_ShowPopup message.
@@ -848,9 +877,11 @@ IPC_MESSAGE_ROUTED1(FrameMsg_Collapse, bool /* collapsed */)
// Notifies the frame that its parent has changed the frame's sandbox flags or
// container policy.
-IPC_MESSAGE_ROUTED2(FrameMsg_DidUpdateFramePolicy,
- blink::WebSandboxFlags,
- content::ParsedFeaturePolicyHeader)
+IPC_MESSAGE_ROUTED1(FrameMsg_DidUpdateFramePolicy, blink::FramePolicy)
+
+// Sent to a frame proxy when the active sandbox flags on its real frame have
+// been updated by a CSP header which sets sandbox flags.
+IPC_MESSAGE_ROUTED1(FrameMsg_DidSetActiveSandboxFlags, blink::WebSandboxFlags)
// Update a proxy's window.name property. Used when the frame's name is
// changed in another process.
@@ -901,6 +932,11 @@ IPC_MESSAGE_ROUTED1(FrameMsg_PostMessageEvent, FrameMsg_PostMessage_Params)
// Tells the RenderFrame to clear the focused element (if any).
IPC_MESSAGE_ROUTED0(FrameMsg_ClearFocusedElement)
+// Informs the parent renderer that the child would like a new
+// viz::LocalSurfaceId in response to an auto-resize.
+IPC_MESSAGE_ROUTED1(FrameMsg_ResizeDueToAutoResize,
+ uint64_t /* sequence_number */)
+
#if defined(OS_ANDROID)
// Request the distance to the nearest find result in a frame from the point at
// (x, y), defined in fractions of the content document's width and height. The
@@ -945,27 +981,14 @@ IPC_MESSAGE_ROUTED2(FrameMsg_SelectPopupMenuItems,
#endif
// PlzNavigate
-// Tells the renderer that a navigation is ready to commit. The renderer should
-// request |stream_url| to get access to the stream containing the body of the
-// response. When --enable-network-service is in effect, |stream_url| is not
-// used, and instead the data is passed to the renderer in |commit_data.handle|.
-// When --enable-network-service, a URLLoaderFactory is optionally passed in
-// |commit_data| too.
-IPC_MESSAGE_ROUTED5(FrameMsg_CommitNavigation,
- content::ResourceResponseHead, /* response */
- GURL, /* stream_url */
- FrameMsg_CommitDataNetworkService_Params, /* commit_data */
- content::CommonNavigationParams, /* common_params */
- content::RequestNavigationParams /* request_params */)
-
-// PlzNavigate
// Tells the renderer that a navigation failed with the error code |error_code|
// and that the renderer should display an appropriate error page.
-IPC_MESSAGE_ROUTED4(FrameMsg_FailedNavigation,
+IPC_MESSAGE_ROUTED5(FrameMsg_FailedNavigation,
content::CommonNavigationParams, /* common_params */
content::RequestNavigationParams, /* request_params */
bool, /* stale_copy_in_cache */
- int /* error_code */)
+ int, /* error_code */
+ base::Optional<std::string> /* error_page_content */)
// PlzNavigate
// Tells the renderer that a navigation was blocked because a content security
@@ -1077,6 +1100,11 @@ IPC_MESSAGE_ROUTED1(FrameMsg_BlinkFeatureUsageReport,
IPC_MESSAGE_ROUTED1(FrameMsg_MixedContentFound,
FrameMsg_MixedContentFound_Params)
+// Sent to the parent process of a cross-process frame to request scrolling.
+IPC_MESSAGE_ROUTED2(FrameMsg_ScrollRectToVisible,
+ gfx::Rect /* rect_to_scroll */,
+ blink::WebRemoteScrollProperties /* properties */)
+
// -----------------------------------------------------------------------------
// Messages sent from the renderer to the browser.
@@ -1092,12 +1120,15 @@ IPC_MESSAGE_ROUTED4(FrameHostMsg_DidAddMessageToConsole,
//
// Each of these messages will have a corresponding FrameHostMsg_Detach message
// sent when the frame is detached from the DOM.
-// Note that |new_render_frame_id| and |devtools_frame_token| are out
-// parameters. Browser process defines them for the renderer process.
-IPC_SYNC_MESSAGE_CONTROL1_2(FrameHostMsg_CreateChildFrame,
- FrameHostMsg_CreateChildFrame_Params,
- int32_t /* new_routing_id */,
- base::UnguessableToken /* devtools_frame_token */)
+// Note that |new_render_frame_id|, |new_interface_provider|, and
+// |devtools_frame_token| are out parameters. Browser process defines them for
+// the renderer process.
+IPC_SYNC_MESSAGE_CONTROL1_3(
+ FrameHostMsg_CreateChildFrame,
+ FrameHostMsg_CreateChildFrame_Params,
+ int32_t, /* new_routing_id */
+ mojo::MessagePipeHandle, /* new_interface_provider */
+ base::UnguessableToken /* devtools_frame_token */)
// Sent by the renderer to the parent RenderFrameHost when a child frame is
// detached from the DOM.
@@ -1147,11 +1178,13 @@ IPC_MESSAGE_ROUTED2(FrameHostMsg_DidChangeName,
std::string /* name */,
std::string /* unique_name */)
-// Notifies the browser process that a non-empty Feature-Policy HTTP header was
-// delivered with the document being loaded into the frame. |parsed_header| is
-// a list of an origin whitelist for each feature in the policy.
-IPC_MESSAGE_ROUTED1(FrameHostMsg_DidSetFeaturePolicyHeader,
- content::ParsedFeaturePolicyHeader /* parsed_header */)
+// Notifies the browser process that HTTP headers which affect the frame
+// polices were delivered with the document being lodaded into the frame. This
+// can be either or both of 'Feature-Policy' or 'Content-Security-Policy' (which
+// can set sandbox flags).
+IPC_MESSAGE_ROUTED2(FrameHostMsg_DidSetFramePolicyHeaders,
+ blink::WebSandboxFlags,
+ blink::ParsedFeaturePolicy /* parsed_header */)
// Notifies the browser process about a new Content Security Policy that needs
// to be applies to the frame. This message is sent when a frame commits
@@ -1224,11 +1257,10 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_DidChangeOpener, int /* opener_routing_id */)
// Notifies the browser that sandbox flags or container policy have changed for
// a subframe of this frame.
-IPC_MESSAGE_ROUTED3(
+IPC_MESSAGE_ROUTED2(
FrameHostMsg_DidChangeFramePolicy,
int32_t /* subframe_routing_id */,
- blink::WebSandboxFlags /* updated_flags */,
- content::ParsedFeaturePolicyHeader /* updated container policy */)
+ blink::FramePolicy /* updated sandbox flags and container policy */)
// Notifies the browser that frame owner properties have changed for a subframe
// of this frame.
@@ -1445,11 +1477,12 @@ IPC_MESSAGE_ROUTED3(FrameHostMsg_BeforeUnload_ACK,
// Indicates that the current frame has swapped out, after a SwapOut message.
IPC_MESSAGE_ROUTED0(FrameHostMsg_SwapOut_ACK)
-// Tells the parent that a child's frame rect has changed (or the rect/scroll
-// position of a child's ancestor has changed).
-IPC_MESSAGE_ROUTED2(FrameHostMsg_FrameRectChanged,
+// Tells the browser that a child's resize parameters have changed.
+IPC_MESSAGE_ROUTED4(FrameHostMsg_UpdateResizeParams,
gfx::Rect /* frame_rect */,
- viz::LocalSurfaceId /* local_surface_id */)
+ content::ScreenInfo /* screen_info */,
+ uint64_t /* sequence_number */,
+ viz::SurfaceId /* surface_id */)
// Sent by a parent frame to update its child's viewport intersection rect for
// use by the IntersectionObserver API.
@@ -1462,6 +1495,14 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_VisibilityChanged, bool /* visible */)
// Sets or unsets the inert bit on a remote frame.
IPC_MESSAGE_ROUTED1(FrameHostMsg_SetIsInert, bool /* inert */)
+// Toggles render throttling on a remote frame. |is_throttled| indicates
+// whether the current frame should be throttled based on its viewport
+// visibility, and |subtree_throttled| indicates that an ancestor frame has
+// been throttled, so all descendant frames also should be throttled.
+IPC_MESSAGE_ROUTED2(FrameHostMsg_UpdateRenderThrottlingStatus,
+ bool /* is_throttled */,
+ bool /* subtree_throttled */)
+
// Indicates that this frame recieved a user gesture, so that the state can be
// propagated to any remote frames.
IPC_MESSAGE_ROUTED0(FrameHostMsg_SetHasReceivedUserGesture)
@@ -1693,6 +1734,11 @@ IPC_MESSAGE_ROUTED3(FrameHostMsg_WebUISend,
std::string /* message */,
base::ListValue /* args */)
+// Sent by a local root to request scrolling in its parent process.
+IPC_MESSAGE_ROUTED2(FrameHostMsg_ScrollRectToVisibleInParentFrame,
+ gfx::Rect /* rect_to_scroll */,
+ blink::WebRemoteScrollProperties /* properties */)
+
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
// Message to show/hide a popup menu using native controls.
diff --git a/chromium/content/common/frame_owner_properties.h b/chromium/content/common/frame_owner_properties.h
index 00bd2919ce8..363015cad02 100644
--- a/chromium/content/common/frame_owner_properties.h
+++ b/chromium/content/common/frame_owner_properties.h
@@ -8,7 +8,7 @@
#include <vector>
#include "content/common/content_export.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
#include "third_party/WebKit/public/web/WebFrameOwnerProperties.h"
namespace content {
diff --git a/chromium/content/common/frame_replication_state.cc b/chromium/content/common/frame_replication_state.cc
index b4feb5e4a3a..a8c14554700 100644
--- a/chromium/content/common/frame_replication_state.cc
+++ b/chromium/content/common/frame_replication_state.cc
@@ -4,13 +4,13 @@
#include "content/common/frame_replication_state.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
+#include "third_party/WebKit/common/sandbox_flags.h"
#include "third_party/WebKit/public/web/WebTreeScopeType.h"
namespace content {
FrameReplicationState::FrameReplicationState()
- : sandbox_flags(blink::WebSandboxFlags::kNone),
+ : active_sandbox_flags(blink::WebSandboxFlags::kNone),
scope(blink::WebTreeScopeType::kDocument),
insecure_request_policy(blink::kLeaveInsecureRequestsAlone),
has_potentially_trustworthy_unique_origin(false),
@@ -20,14 +20,13 @@ FrameReplicationState::FrameReplicationState(
blink::WebTreeScopeType scope,
const std::string& name,
const std::string& unique_name,
- blink::WebSandboxFlags sandbox_flags,
blink::WebInsecureRequestPolicy insecure_request_policy,
bool has_potentially_trustworthy_unique_origin,
bool has_received_user_gesture)
: origin(),
- sandbox_flags(sandbox_flags),
name(name),
unique_name(unique_name),
+ active_sandbox_flags(blink::WebSandboxFlags::kNone),
scope(scope),
insecure_request_policy(insecure_request_policy),
has_potentially_trustworthy_unique_origin(
diff --git a/chromium/content/common/frame_replication_state.h b/chromium/content/common/frame_replication_state.h
index d9e22c9dcaa..fe1ae5639e3 100644
--- a/chromium/content/common/frame_replication_state.h
+++ b/chromium/content/common/frame_replication_state.h
@@ -10,7 +10,8 @@
#include "content/common/content_export.h"
#include "content/common/content_security_policy_header.h"
-#include "content/common/feature_policy/feature_policy.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
+#include "third_party/WebKit/common/frame_policy.h"
#include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h"
#include "url/origin.h"
@@ -28,7 +29,6 @@ struct CONTENT_EXPORT FrameReplicationState {
FrameReplicationState(blink::WebTreeScopeType scope,
const std::string& name,
const std::string& unique_name,
- blink::WebSandboxFlags sandbox_flags,
blink::WebInsecureRequestPolicy insecure_request_policy,
bool has_potentially_trustworthy_unique_origin,
bool has_received_user_gesture);
@@ -47,20 +47,6 @@ struct CONTENT_EXPORT FrameReplicationState {
// compromized renderer.
url::Origin origin;
- // Sandbox flags currently in effect for the frame. |sandbox_flags| are
- // initialized for new child frames using the value of the <iframe> element's
- // "sandbox" attribute, combined with any sandbox flags in effect for the
- // parent frame.
- //
- // When a parent frame updates an <iframe>'s sandbox attribute via
- // JavaScript, |sandbox_flags| are updated only after the child frame commits
- // a navigation that makes the updated flags take effect. This is also the
- // point at which updates are sent to proxies (see
- // CommitPendingSandboxFlags()). The proxies need updated flags so that they
- // can be inherited properly if a proxy ever becomes a parent of a local
- // frame.
- blink::WebSandboxFlags sandbox_flags;
-
// The assigned name of the frame (see WebFrame::assignedName()).
//
// |name| is set when a new child frame is created using the value of the
@@ -88,10 +74,29 @@ struct CONTENT_EXPORT FrameReplicationState {
// Parsed feature policy header. May be empty if no header was sent with the
// document.
- ParsedFeaturePolicyHeader feature_policy_header;
-
- // Container Policy. May be empty if this is the top-level frame.
- ParsedFeaturePolicyHeader container_policy;
+ blink::ParsedFeaturePolicy feature_policy_header;
+
+ // Contains the currently active sandbox flags for this frame, including flags
+ // inherited from parent frames, the currently active flags from the <iframe>
+ // element hosting this frame, as well as any flags set from a
+ // Content-Security-Policy HTTP header.
+ blink::WebSandboxFlags active_sandbox_flags;
+
+ // Iframe sandbox flags and container policy currently in effect for the
+ // frame. Container policy may be empty if this is the top-level frame.
+ // |sandbox_flags| are initialized for new child frames using the value of the
+ // <iframe> element's "sandbox" attribute, combined with any sandbox flags in
+ // effect for the parent frame. This does *not* include any flags set by a
+ // Content-Security-Policy header delivered with the framed document.
+ //
+ // When a parent frame updates an <iframe>'s sandbox attribute via
+ // JavaScript, |sandbox_flags| are updated only after the child frame commits
+ // a navigation that makes the updated flags take effect. This is also the
+ // point at which updates are sent to proxies (see
+ // CommitPendingFramePolicy()). The proxies need updated flags so that they
+ // can be inherited properly if a proxy ever becomes a parent of a local
+ // frame.
+ blink::FramePolicy frame_policy;
// Accumulated CSP headers - gathered from http headers, <meta> elements,
// parent frames (in case of about:blank frames).
diff --git a/chromium/content/common/indexed_db/indexed_db.mojom b/chromium/content/common/indexed_db/indexed_db.mojom
index e6cf26fdbb8..ecab1b44a4a 100644
--- a/chromium/content/common/indexed_db/indexed_db.mojom
+++ b/chromium/content/common/indexed_db/indexed_db.mojom
@@ -11,7 +11,7 @@ module indexed_db.mojom;
import "mojo/common/file_path.mojom";
import "mojo/common/string16.mojom";
import "mojo/common/time.mojom";
-import "storage/public/interfaces/blobs.mojom";
+import "third_party/WebKit/common/blob/blob.mojom";
import "url/mojo/origin.mojom";
enum CursorDirection {
@@ -137,7 +137,7 @@ struct FileInfo {
};
struct BlobInfo {
- storage.mojom.Blob? blob;
+ blink.mojom.Blob? blob;
string uuid;
mojo.common.mojom.String16 mime_type;
int64 size;
diff --git a/chromium/content/common/input/OWNERS b/chromium/content/common/input/OWNERS
index ec220b4114a..f8dfd192dd2 100644
--- a/chromium/content/common/input/OWNERS
+++ b/chromium/content/common/input/OWNERS
@@ -1,4 +1,3 @@
-aelias@chromium.org
dtapuska@chromium.org
tdresser@chromium.org
diff --git a/chromium/content/common/input/input_event_ack.h b/chromium/content/common/input/input_event_ack.h
index 16149653580..5db1a07d443 100644
--- a/chromium/content/common/input/input_event_ack.h
+++ b/chromium/content/common/input/input_event_ack.h
@@ -12,8 +12,8 @@
#include "base/optional.h"
#include "cc/input/touch_action.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_source.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "ui/events/blink/did_overscroll_params.h"
#include "ui/latency/latency_info.h"
diff --git a/chromium/content/common/input/input_event_ack_state.cc b/chromium/content/common/input/input_event_ack_state.cc
new file mode 100644
index 00000000000..41b2743e5fc
--- /dev/null
+++ b/chromium/content/common/input/input_event_ack_state.cc
@@ -0,0 +1,34 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/common/input_event_ack_state.h"
+
+#include "base/logging.h"
+
+namespace content {
+
+const char* InputEventAckStateToString(InputEventAckState ack_state) {
+ switch (ack_state) {
+ case INPUT_EVENT_ACK_STATE_UNKNOWN:
+ return "UNKNOWN";
+ case INPUT_EVENT_ACK_STATE_CONSUMED:
+ return "CONSUMED";
+ case INPUT_EVENT_ACK_STATE_NOT_CONSUMED:
+ return "NOT_CONSUMED";
+ case INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE:
+ return "CONSUMED_SHOULD_BUBBLE";
+ case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS:
+ return "NO_CONSUMER_EXISTS";
+ case INPUT_EVENT_ACK_STATE_IGNORED:
+ return "IGNORED";
+ case INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING:
+ return "SET_NON_BLOCKING";
+ case INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING:
+ return "SET_NON_BLOCKING_DUE_TO_FLING";
+ }
+ DLOG(WARNING) << "InputEventAckStateToString: Unhandled InputEventAckState.";
+ return "";
+}
+
+} // 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 f5af72738e4..5d9656e3da8 100644
--- a/chromium/content/common/input/input_event_struct_traits.cc
+++ b/chromium/content/common/input/input_event_struct_traits.cc
@@ -119,6 +119,9 @@ bool StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::Read(
gesture_event->y = gesture_data->widget_position.y();
gesture_event->global_x = gesture_data->screen_position.x();
gesture_event->global_y = gesture_data->screen_position.y();
+ gesture_event->is_source_touch_event_set_non_blocking =
+ gesture_data->is_source_touch_event_set_non_blocking;
+ gesture_event->primary_pointer_type = gesture_data->primary_pointer_type;
gesture_event->source_device = gesture_data->source_device;
gesture_event->unique_touch_event_id = gesture_data->unique_touch_event_id;
gesture_event->resending_plugin_id = gesture_data->resending_plugin_id;
@@ -151,57 +154,12 @@ bool StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::Read(
gesture_event->data.long_press.height =
gesture_data->contact_size->height();
break;
-
case blink::WebInputEvent::Type::kGestureTwoFingerTap:
gesture_event->data.two_finger_tap.first_finger_width =
gesture_data->contact_size->width();
gesture_event->data.two_finger_tap.first_finger_height =
gesture_data->contact_size->height();
break;
- case blink::WebInputEvent::Type::kGestureScrollBegin:
- gesture_event->data.scroll_begin.delta_x_hint =
- gesture_data->scroll_data->delta_x;
- gesture_event->data.scroll_begin.delta_y_hint =
- gesture_data->scroll_data->delta_y;
- gesture_event->data.scroll_begin.delta_hint_units =
- gesture_data->scroll_data->delta_units;
- gesture_event->data.scroll_begin.target_viewport =
- gesture_data->scroll_data->target_viewport;
- gesture_event->data.scroll_begin.inertial_phase =
- gesture_data->scroll_data->inertial_phase;
- gesture_event->data.scroll_begin.synthetic =
- gesture_data->scroll_data->synthetic;
- gesture_event->data.scroll_begin.pointer_count =
- gesture_data->scroll_data->pointer_count;
- break;
- case blink::WebInputEvent::Type::kGestureScrollEnd:
- gesture_event->data.scroll_end.delta_units =
- gesture_data->scroll_data->delta_units;
- gesture_event->data.scroll_end.inertial_phase =
- gesture_data->scroll_data->inertial_phase;
- gesture_event->data.scroll_end.synthetic =
- gesture_data->scroll_data->synthetic;
- break;
- case blink::WebInputEvent::Type::kGestureScrollUpdate:
- gesture_event->data.scroll_update.delta_x =
- gesture_data->scroll_data->delta_x;
- gesture_event->data.scroll_update.delta_y =
- gesture_data->scroll_data->delta_y;
- gesture_event->data.scroll_update.delta_units =
- gesture_data->scroll_data->delta_units;
- gesture_event->data.scroll_update.inertial_phase =
- gesture_data->scroll_data->inertial_phase;
- if (gesture_data->scroll_data->update_details) {
- gesture_event->data.scroll_update.velocity_x =
- gesture_data->scroll_data->update_details->velocity_x;
- gesture_event->data.scroll_update.velocity_y =
- gesture_data->scroll_data->update_details->velocity_y;
- gesture_event->data.scroll_update
- .previous_update_in_sequence_prevented =
- gesture_data->scroll_data->update_details
- ->previous_update_in_sequence_prevented;
- }
- break;
}
}
@@ -256,6 +214,25 @@ bool StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::Read(
}
}
+ if (gesture_data->pinch_data &&
+ type == blink::WebInputEvent::Type::kGesturePinchUpdate) {
+ gesture_event->data.pinch_update.zoom_disabled =
+ gesture_data->pinch_data->zoom_disabled;
+ gesture_event->data.pinch_update.scale = gesture_data->pinch_data->scale;
+ }
+
+ if (gesture_data->tap_data) {
+ switch (type) {
+ default:
+ break;
+ case blink::WebInputEvent::Type::kGestureTap:
+ case blink::WebInputEvent::Type::kGestureTapUnconfirmed:
+ case blink::WebInputEvent::Type::kGestureDoubleTap:
+ gesture_event->data.tap.tap_count = gesture_data->tap_data->tap_count;
+ break;
+ }
+ }
+
if (gesture_data->fling_data) {
switch (type) {
default:
@@ -277,12 +254,6 @@ bool StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::Read(
}
}
- if (gesture_data->pinch_data &&
- type == blink::WebInputEvent::Type::kGesturePinchUpdate) {
- gesture_event->data.pinch_update.zoom_disabled =
- gesture_data->pinch_data->zoom_disabled;
- gesture_event->data.pinch_update.scale = gesture_data->pinch_data->scale;
- }
} else if (blink::WebInputEvent::IsTouchEventType(type)) {
content::mojom::TouchDataPtr touch_data;
if (!event.ReadTouchData<content::mojom::TouchDataPtr>(&touch_data))
@@ -424,6 +395,9 @@ StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::gesture_data(
gesture_data->screen_position = gesture_event->PositionInScreen();
gesture_data->widget_position = gesture_event->PositionInWidget();
gesture_data->source_device = gesture_event->source_device;
+ gesture_data->is_source_touch_event_set_non_blocking =
+ gesture_event->is_source_touch_event_set_non_blocking;
+ gesture_data->primary_pointer_type = gesture_event->primary_pointer_type;
gesture_data->unique_touch_event_id = gesture_event->unique_touch_event_id;
gesture_data->resending_plugin_id = gesture_event->resending_plugin_id;
switch (gesture_event->GetType()) {
diff --git a/chromium/content/common/input/input_handler.mojom b/chromium/content/common/input/input_handler.mojom
index b7a8296c456..26209b1d04c 100644
--- a/chromium/content/common/input/input_handler.mojom
+++ b/chromium/content/common/input/input_handler.mojom
@@ -107,6 +107,8 @@ struct GestureData {
gfx.mojom.PointF screen_position;
gfx.mojom.PointF widget_position;
GestureDevice source_device;
+ bool is_source_touch_event_set_non_blocking;
+ PointerType primary_pointer_type;
int32 unique_touch_event_id;
int32 resending_plugin_id;
gfx.mojom.Size? contact_size;
@@ -330,5 +332,6 @@ interface FrameInputHandler {
// Return an associated WidgetInputHandler interface so that input
// messages to the widget associated with this frame can be sent
// serially.
- GetWidgetInputHandler(associated WidgetInputHandler& interface_request);
+ GetWidgetInputHandler(associated WidgetInputHandler& interface_request,
+ WidgetInputHandlerHost host);
};
diff --git a/chromium/content/common/input/input_param_traits.cc b/chromium/content/common/input/input_param_traits.cc
index 66418e3fc17..8480dd0891a 100644
--- a/chromium/content/common/input/input_param_traits.cc
+++ b/chromium/content/common/input/input_param_traits.cc
@@ -28,7 +28,7 @@ bool ParamTraits<ui::WebScopedInputEvent>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
bool valid_web_event = false;
- WebInputEventPointer web_event_pointer = NULL;
+ WebInputEventPointer web_event_pointer = nullptr;
if (!ReadParam(m, iter, &valid_web_event) ||
!valid_web_event ||
!ReadParam(m, iter, &web_event_pointer) ||
diff --git a/chromium/content/common/input/input_param_traits_unittest.cc b/chromium/content/common/input/input_param_traits_unittest.cc
index 4bc88c5fd41..7235849ce32 100644
--- a/chromium/content/common/input/input_param_traits_unittest.cc
+++ b/chromium/content/common/input/input_param_traits_unittest.cc
@@ -85,35 +85,35 @@ TEST_F(InputParamTraitsTest, InitializedEvents) {
blink::WebInputEvent::kNoModifiers,
blink::WebInputEvent::kTimeStampForTesting);
key_event.native_key_code = 5;
- events.push_back(base::MakeUnique<InputEvent>(key_event, latency));
+ events.push_back(std::make_unique<InputEvent>(key_event, latency));
blink::WebMouseWheelEvent wheel_event(
blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
blink::WebInputEvent::kTimeStampForTesting);
wheel_event.delta_x = 10;
latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 1, 1);
- events.push_back(base::MakeUnique<InputEvent>(wheel_event, latency));
+ events.push_back(std::make_unique<InputEvent>(wheel_event, latency));
blink::WebMouseEvent mouse_event(blink::WebInputEvent::kMouseDown,
blink::WebInputEvent::kNoModifiers,
blink::WebInputEvent::kTimeStampForTesting);
mouse_event.SetPositionInWidget(10, 0);
latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 2, 2);
- events.push_back(base::MakeUnique<InputEvent>(mouse_event, latency));
+ events.push_back(std::make_unique<InputEvent>(mouse_event, latency));
blink::WebGestureEvent gesture_event(
blink::WebInputEvent::kGestureScrollBegin,
blink::WebInputEvent::kNoModifiers,
blink::WebInputEvent::kTimeStampForTesting);
gesture_event.x = -1;
- events.push_back(base::MakeUnique<InputEvent>(gesture_event, latency));
+ events.push_back(std::make_unique<InputEvent>(gesture_event, latency));
blink::WebTouchEvent touch_event(blink::WebInputEvent::kTouchStart,
blink::WebInputEvent::kNoModifiers,
blink::WebInputEvent::kTimeStampForTesting);
touch_event.touches_length = 1;
touch_event.touches[0].radius_x = 1;
- events.push_back(base::MakeUnique<InputEvent>(touch_event, latency));
+ events.push_back(std::make_unique<InputEvent>(touch_event, latency));
Verify(events);
}
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 b0c2d12f981..b813a134041 100644
--- a/chromium/content/common/input/synthetic_web_input_event_builders.cc
+++ b/chromium/content/common/input/synthetic_web_input_event_builders.cc
@@ -28,8 +28,8 @@ WebMouseEvent SyntheticWebMouseEventBuilder::Build(
WebMouseEvent SyntheticWebMouseEventBuilder::Build(
blink::WebInputEvent::Type type,
- int window_x,
- int window_y,
+ float window_x,
+ float window_y,
int modifiers,
blink::WebPointerProperties::PointerType pointer_type) {
DCHECK(WebInputEvent::IsMouseEventType(type));
diff --git a/chromium/content/common/input/synthetic_web_input_event_builders.h b/chromium/content/common/input/synthetic_web_input_event_builders.h
index 9985c43aa7c..e34268985c0 100644
--- a/chromium/content/common/input/synthetic_web_input_event_builders.h
+++ b/chromium/content/common/input/synthetic_web_input_event_builders.h
@@ -22,8 +22,8 @@ class CONTENT_EXPORT SyntheticWebMouseEventBuilder {
static blink::WebMouseEvent Build(blink::WebInputEvent::Type type);
static blink::WebMouseEvent Build(
blink::WebInputEvent::Type type,
- int window_x,
- int window_y,
+ float window_x,
+ float window_y,
int modifiers,
blink::WebPointerProperties::PointerType pointer_type =
blink::WebPointerProperties::PointerType::kMouse);
diff --git a/chromium/content/common/input/touch_event_stream_validator.cc b/chromium/content/common/input/touch_event_stream_validator.cc
index b5e70902792..aa2d2bb1a5a 100644
--- a/chromium/content/common/input/touch_event_stream_validator.cc
+++ b/chromium/content/common/input/touch_event_stream_validator.cc
@@ -23,7 +23,7 @@ const WebTouchPoint* FindTouchPoint(const WebTouchEvent& event, int id) {
if (event.touches[i].id == id)
return &event.touches[i];
}
- return NULL;
+ return nullptr;
}
std::string TouchPointIdsToString(const WebTouchEvent& event) {
diff --git a/chromium/content/common/input_messages.h b/chromium/content/common/input_messages.h
index 1cfd6f5f437..79aad9fc062 100644
--- a/chromium/content/common/input_messages.h
+++ b/chromium/content/common/input_messages.h
@@ -10,15 +10,13 @@
#include "base/strings/string16.h"
#include "build/build_config.h"
-#include "cc/input/scroll_boundary_behavior.h"
+#include "cc/input/overscroll_behavior.h"
#include "cc/input/touch_action.h"
#include "content/common/content_export.h"
#include "content/common/content_param_traits.h"
#include "content/common/edit_command.h"
#include "content/common/input/input_event.h"
#include "content/common/input/input_event_ack.h"
-#include "content/common/input/input_event_ack_source.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/common/input/input_event_dispatch_type.h"
#include "content/common/input/input_param_traits.h"
#include "content/common/input/synthetic_gesture_params.h"
@@ -28,6 +26,8 @@
#include "content/common/input/synthetic_smooth_drag_gesture_params.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/common/input/synthetic_tap_gesture_params.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/WebKit/public/platform/WebPointerProperties.h"
@@ -84,19 +84,18 @@ IPC_ENUM_TRAITS_MAX_VALUE(
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebTouchPoint::State,
blink::WebTouchPoint::State::kStateMax)
IPC_ENUM_TRAITS_MAX_VALUE(
- cc::ScrollBoundaryBehavior::ScrollBoundaryBehaviorType,
- cc::ScrollBoundaryBehavior::ScrollBoundaryBehaviorType::
- kScrollBoundaryBehaviorTypeMax)
+ cc::OverscrollBehavior::OverscrollBehaviorType,
+ cc::OverscrollBehavior::OverscrollBehaviorType::kOverscrollBehaviorTypeMax)
IPC_STRUCT_TRAITS_BEGIN(ui::DidOverscrollParams)
IPC_STRUCT_TRAITS_MEMBER(accumulated_overscroll)
IPC_STRUCT_TRAITS_MEMBER(latest_overscroll_delta)
IPC_STRUCT_TRAITS_MEMBER(current_fling_velocity)
IPC_STRUCT_TRAITS_MEMBER(causal_event_viewport_point)
- IPC_STRUCT_TRAITS_MEMBER(scroll_boundary_behavior)
+ IPC_STRUCT_TRAITS_MEMBER(overscroll_behavior)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(cc::ScrollBoundaryBehavior)
+IPC_STRUCT_TRAITS_BEGIN(cc::OverscrollBehavior)
IPC_STRUCT_TRAITS_MEMBER(x)
IPC_STRUCT_TRAITS_MEMBER(y)
IPC_STRUCT_TRAITS_END()
diff --git a/chromium/content/common/leveldb_wrapper.mojom b/chromium/content/common/leveldb_wrapper.mojom
index d900a880e77..8640584e445 100644
--- a/chromium/content/common/leveldb_wrapper.mojom
+++ b/chromium/content/common/leveldb_wrapper.mojom
@@ -72,10 +72,13 @@ interface LevelDBWrapper {
// Removes all the entries.
DeleteAll(string source) => (bool success);
- // Returns the value of the |key|.
+ // [DEPRECATED] Returns the value of the |key| only if values are
+ // stored in the internal in-memory cache. Fails if the |key| does not exist
+ // or if values are not required to be stored in the cache.
+ // TODO(ssid): Remove this function, crbug.com/764127.
Get(array<uint8> key) => (bool success, array<uint8> value);
- // Only used with small databases. Returns all key/value pairs.
+ // Returns all key/value pairs.
[Sync]
GetAll(associated LevelDBWrapperGetAllCallback complete_callback)
=> (leveldb.mojom.DatabaseError status, array<KeyValue> data);
diff --git a/chromium/content/common/loader_util.cc b/chromium/content/common/loader_util.cc
index 0886c2b9a59..894c00bcf1b 100644
--- a/chromium/content/common/loader_util.cc
+++ b/chromium/content/common/loader_util.cc
@@ -8,7 +8,9 @@
#include "base/strings/stringprintf.h"
#include "content/public/common/resource_devtools_info.h"
+#include "content/public/common/resource_request.h"
#include "content/public/common/resource_response.h"
+#include "net/base/load_flags.h"
#include "net/base/mime_sniffer.h"
#include "net/http/http_raw_request_headers.h"
#include "net/http/http_util.h"
@@ -16,6 +18,16 @@
namespace content {
+namespace {
+constexpr char kAcceptHeader[] = "Accept";
+constexpr char kFrameAcceptHeader[] =
+ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,"
+ "image/apng,*/*;q=0.8";
+constexpr char kStylesheetAcceptHeader[] = "text/css,*/*;q=0.1";
+constexpr char kImageAcceptHeader[] = "image/webp,image/apng,image/*,*/*;q=0.8";
+constexpr char kDefaultAcceptHeader[] = "*/*";
+} // namespace
+
bool ShouldSniffContent(net::URLRequest* url_request,
ResourceResponse* response) {
const std::string& mime_type = response->head.mime_type;
@@ -87,4 +99,63 @@ scoped_refptr<ResourceDevToolsInfo> BuildDevToolsInfo(
return info;
}
+void AttachAcceptHeader(ResourceType type, net::URLRequest* request) {
+ const char* accept_value = nullptr;
+ switch (type) {
+ case RESOURCE_TYPE_MAIN_FRAME:
+ case RESOURCE_TYPE_SUB_FRAME:
+ accept_value = kFrameAcceptHeader;
+ break;
+ case RESOURCE_TYPE_STYLESHEET:
+ accept_value = kStylesheetAcceptHeader;
+ break;
+ case RESOURCE_TYPE_FAVICON:
+ case RESOURCE_TYPE_IMAGE:
+ accept_value = kImageAcceptHeader;
+ break;
+ case RESOURCE_TYPE_SCRIPT:
+ case RESOURCE_TYPE_FONT_RESOURCE:
+ case RESOURCE_TYPE_SUB_RESOURCE:
+ case RESOURCE_TYPE_OBJECT:
+ case RESOURCE_TYPE_MEDIA:
+ case RESOURCE_TYPE_WORKER:
+ case RESOURCE_TYPE_SHARED_WORKER:
+ case RESOURCE_TYPE_PREFETCH:
+ case RESOURCE_TYPE_XHR:
+ case RESOURCE_TYPE_PING:
+ case RESOURCE_TYPE_SERVICE_WORKER:
+ case RESOURCE_TYPE_CSP_REPORT:
+ case RESOURCE_TYPE_PLUGIN_RESOURCE:
+ accept_value = kDefaultAcceptHeader;
+ break;
+ case RESOURCE_TYPE_LAST_TYPE:
+ NOTREACHED();
+ break;
+ }
+ // The false parameter prevents overwriting an existing accept header value,
+ // which is needed because JS can manually set an accept header on an XHR.
+ request->SetExtraRequestHeaderByName(kAcceptHeader, accept_value, false);
+}
+
+int BuildLoadFlagsForRequest(const ResourceRequest& request,
+ bool is_sync_load) {
+ int load_flags = request.load_flags;
+
+ // Although EV status is irrelevant to sub-frames and sub-resources, we have
+ // to perform EV certificate verification on all resources because an HTTP
+ // keep-alive connection created to load a sub-frame or a sub-resource could
+ // be reused to load a main frame.
+ load_flags |= net::LOAD_VERIFY_EV_CERT;
+ if (request.resource_type == RESOURCE_TYPE_MAIN_FRAME) {
+ load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED;
+ } else if (request.resource_type == RESOURCE_TYPE_PREFETCH) {
+ load_flags |= net::LOAD_PREFETCH;
+ }
+
+ if (is_sync_load)
+ load_flags |= net::LOAD_IGNORE_LIMITS;
+
+ return load_flags;
+}
+
} // namespace content
diff --git a/chromium/content/common/loader_util.h b/chromium/content/common/loader_util.h
index 8f232c32e86..e91cf4becac 100644
--- a/chromium/content/common/loader_util.h
+++ b/chromium/content/common/loader_util.h
@@ -6,6 +6,7 @@
#define CONTENT_COMMON_LOADER_UTIL_H_
#include "base/memory/ref_counted.h"
+#include "content/public/common/resource_type.h"
namespace net {
class HttpRawRequestHeaders;
@@ -15,6 +16,7 @@ class URLRequest;
namespace content {
struct ResourceDevToolsInfo;
+struct ResourceRequest;
struct ResourceResponse;
// Helper utilities shared between network service and ResourceDispatcherHost
@@ -31,6 +33,11 @@ scoped_refptr<ResourceDevToolsInfo> BuildDevToolsInfo(
const net::HttpRawRequestHeaders& raw_request_headers,
const net::HttpResponseHeaders* raw_response_headers);
+void AttachAcceptHeader(ResourceType type, net::URLRequest* request);
+
+int BuildLoadFlagsForRequest(const ResourceRequest& request_data,
+ bool is_sync_load);
+
} // namespace content
#endif // CONTENT_COMMON_LOADER_UTIL_H_
diff --git a/chromium/content/common/mac/attributed_string_coder.h b/chromium/content/common/mac/attributed_string_coder.h
index 6976d4e0a4d..5258884744c 100644
--- a/chromium/content/common/mac/attributed_string_coder.h
+++ b/chromium/content/common/mac/attributed_string_coder.h
@@ -9,7 +9,6 @@
#include "base/strings/string16.h"
#include "content/common/content_export.h"
-#include "content/common/mac/font_descriptor.h"
#include "ipc/ipc_message_utils.h"
#include "ui/gfx/range/range.h"
@@ -41,7 +40,9 @@ class CONTENT_EXPORT AttributedStringCoder {
class FontAttribute {
public:
FontAttribute(NSDictionary* ns_attributes, gfx::Range effective_range);
- FontAttribute(FontDescriptor font, gfx::Range range);
+ FontAttribute(const base::string16& font_name,
+ float font_point_size,
+ const gfx::Range& range);
FontAttribute();
~FontAttribute();
@@ -55,11 +56,13 @@ class CONTENT_EXPORT AttributedStringCoder {
bool ShouldEncode() const;
// Accessors:
- FontDescriptor font_descriptor() const { return font_descriptor_; }
- gfx::Range effective_range() const { return effective_range_; }
+ const base::string16& font_name() const { return font_name_; }
+ float font_point_size() const { return font_point_size_; }
+ const gfx::Range& effective_range() const { return effective_range_; }
private:
- FontDescriptor font_descriptor_;
+ base::string16 font_name_;
+ float font_point_size_;
gfx::Range effective_range_;
};
diff --git a/chromium/content/common/mac/attributed_string_coder.mm b/chromium/content/common/mac/attributed_string_coder.mm
index f8fa6b05271..18d28a03013 100644
--- a/chromium/content/common/mac/attributed_string_coder.mm
+++ b/chromium/content/common/mac/attributed_string_coder.mm
@@ -10,7 +10,6 @@
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
-#include "content/common/render_process_messages.h"
#include "content/public/common/common_param_traits.h"
#include "ipc/ipc_message_utils.h"
@@ -78,24 +77,24 @@ AttributedStringCoder::EncodedString::~EncodedString() {
AttributedStringCoder::FontAttribute::FontAttribute(NSDictionary* dict,
gfx::Range effective_range)
- : font_descriptor_(),
- effective_range_(effective_range) {
+ : font_name_(), font_point_size_(0), effective_range_(effective_range) {
NSFont* font = [dict objectForKey:NSFontAttributeName];
if (font) {
- font_descriptor_ = FontDescriptor(font);
+ font_name_ = base::SysNSStringToUTF16([font fontName]);
+ font_point_size_ = [font pointSize];
}
}
-AttributedStringCoder::FontAttribute::FontAttribute(FontDescriptor font,
- gfx::Range range)
- : font_descriptor_(font),
- effective_range_(range) {
-}
+AttributedStringCoder::FontAttribute::FontAttribute(
+ const base::string16& font_name,
+ float font_point_size,
+ const gfx::Range& range)
+ : font_name_(std::move(font_name)),
+ font_point_size_(font_point_size),
+ effective_range_(range) {}
AttributedStringCoder::FontAttribute::FontAttribute()
- : font_descriptor_(),
- effective_range_() {
-}
+ : font_name_(), font_point_size_(0), effective_range_() {}
AttributedStringCoder::FontAttribute::~FontAttribute() {
}
@@ -103,14 +102,15 @@ AttributedStringCoder::FontAttribute::~FontAttribute() {
NSDictionary*
AttributedStringCoder::FontAttribute::ToAttributesDictionary() const {
DCHECK(ShouldEncode());
- NSFont* font = font_descriptor_.ToNSFont();
+ NSString* font_name_ns = base::SysUTF16ToNSString(font_name_);
+ NSFont* font = [NSFont fontWithName:font_name_ns size:font_point_size_];
if (!font)
return [NSDictionary dictionary];
return [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
}
bool AttributedStringCoder::FontAttribute::ShouldEncode() const {
- return !font_descriptor_.font_name.empty();
+ return !font_name_.empty();
}
} // namespace mac
@@ -150,7 +150,8 @@ void ParamTraits<AttributedStringCoder::EncodedString>::Log(
void ParamTraits<AttributedStringCoder::FontAttribute>::Write(
base::Pickle* m,
const param_type& p) {
- WriteParam(m, p.font_descriptor());
+ WriteParam(m, p.font_name());
+ WriteParam(m, p.font_point_size());
WriteParam(m, p.effective_range());
}
@@ -160,14 +161,18 @@ bool ParamTraits<AttributedStringCoder::FontAttribute>::Read(
param_type* p) {
bool success = true;
- FontDescriptor font;
- success &= ReadParam(m, iter, &font);
+ base::string16 font_name;
+ success &= ReadParam(m, iter, &font_name);
+
+ float font_point_size;
+ success &= ReadParam(m, iter, &font_point_size);
gfx::Range range;
success &= ReadParam(m, iter, &range);
if (success) {
- *p = AttributedStringCoder::FontAttribute(font, range);
+ *p = AttributedStringCoder::FontAttribute(std::move(font_name),
+ font_point_size, range);
}
return success;
}
diff --git a/chromium/content/common/mac/attributed_string_coder_unittest.mm b/chromium/content/common/mac/attributed_string_coder_unittest.mm
index 314af39e21e..bc4991bb3fa 100644
--- a/chromium/content/common/mac/attributed_string_coder_unittest.mm
+++ b/chromium/content/common/mac/attributed_string_coder_unittest.mm
@@ -9,6 +9,7 @@
#include <memory>
#include "base/mac/scoped_nsobject.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
@@ -108,20 +109,16 @@ TEST_F(AttributedStringCoderTest, NilString) {
}
TEST_F(AttributedStringCoderTest, OutOfRange) {
+ NSFont* system_font = [NSFont systemFontOfSize:10];
+ base::string16 font_name = base::SysNSStringToUTF16([system_font fontName]);
AttributedStringCoder::EncodedString encoded(
base::ASCIIToUTF16("Hello World"));
encoded.attributes()->push_back(
- AttributedStringCoder::FontAttribute(
- FontDescriptor([NSFont systemFontOfSize:12]),
- gfx::Range(0, 5)));
+ AttributedStringCoder::FontAttribute(font_name, 12, gfx::Range(0, 5)));
encoded.attributes()->push_back(
- AttributedStringCoder::FontAttribute(
- FontDescriptor([NSFont systemFontOfSize:14]),
- gfx::Range(5, 100)));
+ AttributedStringCoder::FontAttribute(font_name, 14, gfx::Range(5, 100)));
encoded.attributes()->push_back(
- AttributedStringCoder::FontAttribute(
- FontDescriptor([NSFont systemFontOfSize:16]),
- gfx::Range(100, 5)));
+ AttributedStringCoder::FontAttribute(font_name, 16, gfx::Range(100, 5)));
NSAttributedString* decoded = AttributedStringCoder::Decode(&encoded);
EXPECT_TRUE(decoded);
diff --git a/chromium/content/common/mac/font_descriptor.h b/chromium/content/common/mac/font_descriptor.h
deleted file mode 100644
index 71d555dbaa8..00000000000
--- a/chromium/content/common/mac/font_descriptor.h
+++ /dev/null
@@ -1,36 +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_MAC_FONT_DESCRIPTOR_H_
-#define CONTENT_COMMON_MAC_FONT_DESCRIPTOR_H_
-
-#include "base/strings/string16.h"
-#include "content/common/content_export.h"
-
-#ifdef __OBJC__
-@class NSFont;
-#else
-class NSFont;
-#endif
-
-// Container to allow serializing an NSFont over IPC.
-struct CONTENT_EXPORT FontDescriptor {
- explicit FontDescriptor(NSFont* font);
- FontDescriptor(base::string16 name, float size);
-
- FontDescriptor() : font_point_size(0) {}
-
- // Return an autoreleased NSFont corresponding to the font description. Note
- // that this will return nil if the font specified isn't available in this
- // process.
- NSFont* ToNSFont() const;
-
- // Name of the font.
- base::string16 font_name;
-
- // Size in points.
- float font_point_size;
-};
-
-#endif // CONTENT_COMMON_MAC_FONT_DESCRIPTOR_H_
diff --git a/chromium/content/common/mac/font_descriptor.mm b/chromium/content/common/mac/font_descriptor.mm
deleted file mode 100644
index e5c04c124be..00000000000
--- a/chromium/content/common/mac/font_descriptor.mm
+++ /dev/null
@@ -1,25 +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/common/mac/font_descriptor.h"
-
-#include <Cocoa/Cocoa.h>
-
-#include "base/strings/sys_string_conversions.h"
-
-FontDescriptor::FontDescriptor(NSFont* font) {
- font_name = base::SysNSStringToUTF16([font fontName]);
- font_point_size = [font pointSize];
-}
-
-FontDescriptor::FontDescriptor(base::string16 name, float size) {
- font_name = name;
- font_point_size = size;
-}
-
-NSFont* FontDescriptor::ToNSFont() const {
- NSString* font_name_ns = base::SysUTF16ToNSString(font_name);
- NSFont* font = [NSFont fontWithName:font_name_ns size:font_point_size];
- return font;
-}
diff --git a/chromium/content/common/mac/font_descriptor_unittest.mm b/chromium/content/common/mac/font_descriptor_unittest.mm
deleted file mode 100644
index 5361a71b979..00000000000
--- a/chromium/content/common/mac/font_descriptor_unittest.mm
+++ /dev/null
@@ -1,114 +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/common/mac/font_descriptor.h"
-
-#include <Cocoa/Cocoa.h>
-
-#include "base/logging.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-namespace {
-
-class FontSerializationTest : public PlatformTest {};
-
-const std::string kCourierFontName("Courier");
-
-// Compare 2 fonts, make sure they point at the same font definition and have
-// the same style. Only Bold & Italic style attributes are tested since those
-// are the only ones we care about at the moment.
-bool CompareFonts(NSFont* font1, NSFont* font2) {
- ATSFontRef id1 = CTFontGetPlatformFont(reinterpret_cast<CTFontRef>(font1), 0);
- ATSFontRef id2 = CTFontGetPlatformFont(reinterpret_cast<CTFontRef>(font2), 0);
-
- if (id1 != id2) {
- DLOG(ERROR) << "ATSFontRefs for "
- << [[font1 fontName] UTF8String]
- << " and "
- << [[font2 fontName] UTF8String]
- << " are different";
- return false;
- }
-
- CGFloat size1 = [font1 pointSize];
- CGFloat size2 = [font2 pointSize];
- if (size1 != size2) {
- DLOG(ERROR) << "font sizes for "
- << [[font1 fontName] UTF8String] << " (" << size1 << ")"
- << "and"
- << [[font2 fontName] UTF8String] << " (" << size2 << ")"
- << " are different";
- return false;
- }
-
- NSFontTraitMask traits1 = [[NSFontManager sharedFontManager]
- traitsOfFont:font1];
- NSFontTraitMask traits2 = [[NSFontManager sharedFontManager]
- traitsOfFont:font2];
-
- bool is_bold1 = traits1 & NSBoldFontMask;
- bool is_bold2 = traits2 & NSBoldFontMask;
- bool is_italic1 = traits1 & NSItalicFontMask;
- bool is_italic2 = traits2 & NSItalicFontMask;
-
- if (is_bold1 != is_bold2 || is_italic1 != is_italic2) {
- DLOG(ERROR) << "Style information for "
- << [[font1 fontName] UTF8String]
- << " and "
- << [[font2 fontName] UTF8String]
- << " are different";
- return false;
- }
-
- return true;
-}
-
-// Create an NSFont via a FontDescriptor object.
-NSFont* MakeNSFont(const std::string& font_name, float font_point_size) {
- FontDescriptor desc;
- desc.font_name = base::UTF8ToUTF16(font_name);
- desc.font_point_size = font_point_size;
- return desc.ToNSFont();
-}
-
-// Verify that serialization and deserialization of fonts with various styles
-// is performed correctly by FontDescriptor.
-TEST_F(FontSerializationTest, StyledFonts) {
- NSFont* plain_font = [NSFont systemFontOfSize:12.0];
- ASSERT_TRUE(plain_font != nil);
- FontDescriptor desc_plain(plain_font);
- EXPECT_TRUE(CompareFonts(plain_font, desc_plain.ToNSFont()));
-
- NSFont* bold_font = [NSFont boldSystemFontOfSize:30.0];
- ASSERT_TRUE(bold_font != nil);
- FontDescriptor desc_bold(bold_font);
- EXPECT_TRUE(CompareFonts(bold_font, desc_bold.ToNSFont()));
-
- NSFont* italic_bold_font =
- [[NSFontManager sharedFontManager]
- fontWithFamily:base::SysUTF8ToNSString(kCourierFontName)
- traits:(NSBoldFontMask | NSItalicFontMask)
- weight:5
- size:18.0];
- ASSERT_TRUE(italic_bold_font != nil);
- FontDescriptor desc_italic_bold(italic_bold_font);
- EXPECT_TRUE(CompareFonts(italic_bold_font, desc_italic_bold.ToNSFont()));
-}
-
-// Test that FontDescriptor doesn't crash when used with bad parameters.
-// This is important since FontDescriptors are constructed with parameters
-// sent over IPC and bad values must not trigger unexpected behavior.
-TEST_F(FontSerializationTest, BadParameters) {
- EXPECT_NSNE(MakeNSFont(kCourierFontName, 12), nil);
- EXPECT_NSNE(MakeNSFont(kCourierFontName, std::numeric_limits<float>::min()),
- nil);
- EXPECT_NSNE(MakeNSFont(kCourierFontName, 0), nil);
- EXPECT_NSNE(MakeNSFont(kCourierFontName, std::numeric_limits<float>::max()),
- nil);
-}
-
-} // namespace
diff --git a/chromium/content/common/mac/font_loader.h b/chromium/content/common/mac/font_loader.h
index 4976a240ac8..a0d4b61c4fa 100644
--- a/chromium/content/common/mac/font_loader.h
+++ b/chromium/content/common/mac/font_loader.h
@@ -11,10 +11,8 @@
#include <stdint.h>
#include "base/callback_forward.h"
-#include "base/memory/shared_memory.h"
#include "content/common/content_export.h"
-
-struct FontDescriptor;
+#include "mojo/public/cpp/system/buffer.h"
namespace content {
@@ -26,26 +24,30 @@ namespace content {
class FontLoader {
public:
// Internal font load result data. Exposed here for testing.
- struct ResultInternal {
+ struct CONTENT_EXPORT ResultInternal {
+ ResultInternal();
+ ~ResultInternal();
uint32_t font_data_size = 0;
- base::SharedMemory font_data;
+ mojo::ScopedSharedBufferHandle font_data;
uint32_t font_id = 0;
};
// Callback for the reporting result of LoadFont().
// - The first argument is the data size.
- // - The SharedMemoryHandle points to a shared memory buffer containing the
- // raw data for the font file.
+ // - The ScopedSharedBufferHandle points to a shared memory buffer containing
+ // the raw data for the font file.
// - The last argument is the font_id: a unique identifier for the on-disk
// file we load for the font.
- using LoadedCallback =
- base::OnceCallback<void(uint32_t, base::SharedMemoryHandle, uint32_t)>;
+ using LoadedCallback = base::OnceCallback<
+ void(uint32_t, mojo::ScopedSharedBufferHandle, uint32_t)>;
// Load a font specified by |font| into a shared memory buffer suitable for
// sending over IPC. On failure, zeroes and an invalid handle are reported
// to the callback.
CONTENT_EXPORT
- static void LoadFont(const FontDescriptor& font, LoadedCallback callback);
+ static void LoadFont(const base::string16& font_name,
+ float font_point_size,
+ LoadedCallback callback);
// Given a shared memory buffer containing the raw data for a font file, load
// the font and return a CGFontRef.
@@ -59,13 +61,14 @@ class FontLoader {
// The caller is responsible for releasing this value via CGFontRelease()
// when done.
CONTENT_EXPORT
- static bool CGFontRefFromBuffer(base::SharedMemoryHandle font_data,
+ static bool CGFontRefFromBuffer(mojo::ScopedSharedBufferHandle font_data,
uint32_t font_data_size,
CGFontRef* out);
CONTENT_EXPORT
static std::unique_ptr<ResultInternal> LoadFontForTesting(
- const FontDescriptor& font);
+ const base::string16& font_name,
+ float font_point_size);
};
} // namespace content
diff --git a/chromium/content/common/mac/font_loader.mm b/chromium/content/common/mac/font_loader.mm
index 1435aa62e66..9cdd80684bf 100644
--- a/chromium/content/common/mac/font_loader.mm
+++ b/chromium/content/common/mac/font_loader.mm
@@ -21,20 +21,22 @@
#include "base/strings/sys_string_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_restrictions.h"
-#include "content/common/mac/font_descriptor.h"
namespace content {
namespace {
std::unique_ptr<FontLoader::ResultInternal> LoadFontOnFileThread(
- const FontDescriptor& font) {
- base::ThreadRestrictions::AssertIOAllowed();
+ const base::string16& font_name,
+ const float font_point_size) {
+ base::AssertBlockingAllowed();
- NSFont* font_to_encode = font.ToNSFont();
+ NSString* font_name_ns = base::SysUTF16ToNSString(font_name);
+ NSFont* font_to_encode =
+ [NSFont fontWithName:font_name_ns size:font_point_size];
// Load appropriate NSFont.
if (!font_to_encode) {
- DLOG(ERROR) << "Failed to load font " << font.font_name;
+ DLOG(ERROR) << "Failed to load font " << font_name;
return nullptr;
}
@@ -51,7 +53,7 @@ std::unique_ptr<FontLoader::ResultInternal> LoadFontOnFileThread(
base::mac::CFToNSCast(base::mac::CFCastStrict<CFURLRef>(
CTFontCopyAttribute(ct_font, kCTFontURLAttribute))));
if (![font_url isFileURL]) {
- DLOG(ERROR) << "Failed to find font file for " << font.font_name;
+ DLOG(ERROR) << "Failed to find font file for " << font_name;
return nullptr;
}
@@ -70,17 +72,24 @@ std::unique_ptr<FontLoader::ResultInternal> LoadFontOnFileThread(
return nullptr;
}
- auto result = base::MakeUnique<FontLoader::ResultInternal>();
+ auto result = std::make_unique<FontLoader::ResultInternal>();
int32_t font_file_size_32 = static_cast<int32_t>(font_file_size_64);
- if (!result->font_data.CreateAndMapAnonymous(font_file_size_32)) {
- DLOG(ERROR) << "Failed to create shmem area for " << font.font_name;
+ result->font_data = mojo::SharedBufferHandle::Create(font_file_size_32);
+ if (!result->font_data.is_valid()) {
+ DLOG(ERROR) << "Failed to create shmem area for " << font_name;
+ return nullptr;
+ }
+
+ mojo::ScopedSharedBufferMapping mapping =
+ result->font_data->Map(font_file_size_32);
+ if (!mapping) {
+ DLOG(ERROR) << "Failed to create shmem mapping for " << font_name;
return nullptr;
}
int32_t amt_read = base::ReadFile(
- font_path, reinterpret_cast<char*>(result->font_data.memory()),
- font_file_size_32);
+ font_path, static_cast<char*>(mapping.get()), font_file_size_32);
if (amt_read != font_file_size_32) {
DLOG(ERROR) << "Failed to read font data for " << font_path.value();
return nullptr;
@@ -92,10 +101,10 @@ std::unique_ptr<FontLoader::ResultInternal> LoadFontOnFileThread(
// ATS is deprecated. CoreText offers up the ATSFontRef typeface ID via
// CTFontGetPlatformFont.
result->font_id = CTFontGetPlatformFont(ct_font, nil);
- DCHECK_NE(0u, result->font_id);
-
- if (result->font_data_size == 0 || result->font_id == 0)
+ if (result->font_id == 0) {
+ DLOG(ERROR) << "Failed to get font id for " << font_path.value();
return nullptr;
+ }
return result;
}
@@ -103,23 +112,27 @@ std::unique_ptr<FontLoader::ResultInternal> LoadFontOnFileThread(
void ReplyOnUIThread(FontLoader::LoadedCallback callback,
std::unique_ptr<FontLoader::ResultInternal> result) {
if (!result) {
- std::move(callback).Run(0, base::SharedMemoryHandle(), 0);
+ std::move(callback).Run(0, mojo::ScopedSharedBufferHandle(), 0);
return;
}
DCHECK_NE(0u, result->font_data_size);
DCHECK_NE(0u, result->font_id);
- base::SharedMemoryHandle handle = result->font_data.handle().Duplicate();
- result->font_data.Unmap();
- result->font_data.Close();
- std::move(callback).Run(result->font_data_size, handle, result->font_id);
+ std::move(callback).Run(result->font_data_size, std::move(result->font_data),
+ result->font_id);
}
} // namespace
+FontLoader::ResultInternal::ResultInternal() = default;
+
+FontLoader::ResultInternal::~ResultInternal() = default;
+
// static
-void FontLoader::LoadFont(const FontDescriptor& font, LoadedCallback callback) {
+void FontLoader::LoadFont(const base::string16& font_name,
+ const float font_point_size,
+ LoadedCallback callback) {
// Tasks are triggered when font loading in the sandbox fails. Usually due to
// a user installing a third-party font manager. See crbug.com/72727. Web page
// rendering can't continue until a font is returned.
@@ -127,26 +140,21 @@ void FontLoader::LoadFont(const FontDescriptor& font, LoadedCallback callback) {
base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
base::PostTaskWithTraitsAndReplyWithResult(
- FROM_HERE, kTraits, base::BindOnce(&LoadFontOnFileThread, font),
+ FROM_HERE, kTraits,
+ base::BindOnce(&LoadFontOnFileThread, font_name, font_point_size),
base::BindOnce(&ReplyOnUIThread, std::move(callback)));
}
// static
-bool FontLoader::CGFontRefFromBuffer(base::SharedMemoryHandle font_data,
+bool FontLoader::CGFontRefFromBuffer(mojo::ScopedSharedBufferHandle font_data,
uint32_t font_data_size,
CGFontRef* out) {
*out = NULL;
-
- using base::SharedMemory;
- DCHECK(SharedMemory::IsHandleValid(font_data));
- DCHECK_GT(font_data_size, 0U);
-
- SharedMemory shm(font_data, /*read_only=*/true);
- if (!shm.Map(font_data_size))
+ mojo::ScopedSharedBufferMapping mapping = font_data->Map(font_data_size);
+ if (!mapping)
return false;
- NSData* data = [NSData dataWithBytes:shm.memory()
- length:font_data_size];
+ NSData* data = [NSData dataWithBytes:mapping.get() length:font_data_size];
base::ScopedCFTypeRef<CGDataProviderRef> provider(
CGDataProviderCreateWithCFData(base::mac::NSToCFCast(data)));
if (!provider)
@@ -162,8 +170,9 @@ bool FontLoader::CGFontRefFromBuffer(base::SharedMemoryHandle font_data,
// static
std::unique_ptr<FontLoader::ResultInternal> FontLoader::LoadFontForTesting(
- const FontDescriptor& font) {
- return LoadFontOnFileThread(font);
+ const base::string16& font_name,
+ const float font_point_size) {
+ return LoadFontOnFileThread(font_name, font_point_size);
}
} // namespace content
diff --git a/chromium/content/common/media/aec_dump_messages.h b/chromium/content/common/media/aec_dump_messages.h
index 427c82bb781..07d6855226b 100644
--- a/chromium/content/common/media/aec_dump_messages.h
+++ b/chromium/content/common/media/aec_dump_messages.h
@@ -26,6 +26,9 @@ IPC_MESSAGE_CONTROL2(AecDumpMsg_EnableAecDump,
// Tell the renderer to disable AEC dump in all consumers.
IPC_MESSAGE_CONTROL0(AecDumpMsg_DisableAecDump)
+// TODO(hlundin): Rename file to reflect expanded use; http://crbug.com/709919.
+IPC_MESSAGE_CONTROL1(AudioProcessingMsg_EnableAec3, bool /* enable */)
+
// Messages sent from the renderer to the browser.
// Registers a consumer with the browser. The consumer will then get a file
@@ -37,9 +40,7 @@ IPC_MESSAGE_CONTROL1(AecDumpMsg_RegisterAecDumpConsumer,
IPC_MESSAGE_CONTROL1(AecDumpMsg_UnregisterAecDumpConsumer,
int /* id */)
-// TODO(hlundin): Rename file to reflect expanded use; http://crbug.com/709919.
-IPC_MESSAGE_CONTROL2(AudioProcessingMsg_EnableAec3,
- int /* id */,
- bool /* enable */)
+// Response to browser process that AEC3 was enabled.
+IPC_MESSAGE_CONTROL0(AudioProcessingMsg_Aec3Enabled)
#endif // CONTENT_COMMON_MEDIA_AEC_DUMP_MESSAGES_H_
diff --git a/chromium/content/common/media/media_devices.mojom b/chromium/content/common/media/media_devices.mojom
deleted file mode 100644
index c466598c967..00000000000
--- a/chromium/content/common/media/media_devices.mojom
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module mojom;
-
-import "media/capture/mojo/video_capture_types.mojom";
-import "media/mojo/interfaces/audio_parameters.mojom";
-
-[Native]
-enum MediaDeviceType;
-
-[Native]
-struct MediaDeviceInfo;
-
-// The values for this enum match the ones defined in
-// https://w3c.github.io/mediacapture-main/#def-constraint-facingMode
-// with the addition of NONE, which would map to the empty string in
-// JavaScript.
-enum FacingMode {
- NONE,
- USER,
- ENVIRONMENT,
- LEFT,
- RIGHT
-};
-
-struct VideoInputDeviceCapabilities {
- string device_id;
- array<media.mojom.VideoCaptureFormat> formats;
- FacingMode facing_mode;
-};
-
-struct AudioInputDeviceCapabilities {
- string device_id;
- media.mojom.AudioParameters parameters;
-};
-
-// This object lives in the browser and is responsible for processing device
-// enumeration requests and managing subscriptions for device-change
-// notifications.
-interface MediaDevicesDispatcherHost {
- // The reply always contains NUM_MEDIA_DEVICE_TYPES elements.
- // The result is indexed by device type as defined in
- // content/common/media/media_devices.h.
- EnumerateDevices(bool request_audio_input,
- bool request_video_input,
- bool request_audio_output)
- => (array<array<MediaDeviceInfo>> enumeration);
-
- // Returns a list of video devices and their capabilities.
- // If there is a user-preferred device, it is the first in the result.
- // The result of this function is intended for the implementation details
- // of algorithms such as settings selection for getUserMedia.
- // Do not expose the data contained in the result of this function to
- // JavaScript.
- GetVideoInputCapabilities()
- => (array<VideoInputDeviceCapabilities> video_input_device_capabilities);
-
- // Returns a list of all video formats supported by a given device, regardless
- // of whether the device is being used or not. If the given |device_id| is
- // invalid, the result is empty.
- GetAllVideoInputDeviceFormats(string device_id)
- => (array<media.mojom.VideoCaptureFormat> formats);
-
- // Returns a list of video formats currently available for a given device.
- // When the device is in use, it is expected that the result will contain only
- // one entry. When the device is not in use, the result should be the same as
- // for GetAllVideoInputDeviceFormats. If the given |device_id| is not valid,
- // the result is empty.
- GetAvailableVideoInputDeviceFormats(string device_id)
- => (array<media.mojom.VideoCaptureFormat> formats);
-
- // Returns a list of audio input devices and their capabilities.
- // If there is a user-preferred device, it is the first in the result.
- // Otherwise, the system-default device is the first in the result.
- // The result of this function is intended for the implementation details
- // of algorithms such as settings selection for getUserMedia.
- // Do not expose the data contained in the result of this function to
- // JavaScript.
- GetAudioInputCapabilities()
- => (array<AudioInputDeviceCapabilities> audio_input_device_capabilities);
-
- // Creates a subscription for device-change notifications for the calling
- // frame/security origin. It is the responsibility of the caller to send
- // |subscription_id| values that are unique per device type.
- // Requests to create a subscription with an ID that already exists for type
- // |type| are invalid and result in a renderer crash.
- SubscribeDeviceChangeNotifications(MediaDeviceType type,
- uint32 subscription_id);
-
- // Removes a subscription to device-change notifications for the calling
- // frame. The caller is responsible for sending |subscription_id| values that
- // that refer to existing subscriptions for type |type|. Requests to remove
- // a nonexisting subscription with are invalid and result in a renderer crash.
- UnsubscribeDeviceChangeNotifications(MediaDeviceType type,
- uint32 subscription_id);
-};
-
-// This object lives in the renderer process and is used by the browser process
-// to pass device-change notifications to the renderer.
-interface MediaDevicesListener {
- // Called to notify a change in the set of devices of type |type| for
- // subscription |subscription_id|. |device_infos| contains the new list of
- // devices of type |type|, with device and group IDs obfuscated according to
- // the subscription's security origin.
- OnDevicesChanged(MediaDeviceType type,
- uint32 subscription_id,
- array<MediaDeviceInfo> device_infos);
-};
diff --git a/chromium/content/common/media/media_devices.typemap b/chromium/content/common/media/media_devices.typemap
index 586b971d7b1..3b65711fcdf 100644
--- a/chromium/content/common/media/media_devices.typemap
+++ b/chromium/content/common/media/media_devices.typemap
@@ -2,13 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-mojom = "//content/common/media/media_devices.mojom"
+mojom = "//third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom"
public_headers = [ "//content/common/media/media_devices.h" ]
traits_headers = [ "//content/common/media/media_devices_param_traits.h" ]
-deps = [
- "//content:export",
-]
type_mappings = [
- "mojom.MediaDeviceType=::content::MediaDeviceType",
- "mojom.MediaDeviceInfo=::content::MediaDeviceInfo",
+ "blink.mojom.MediaDeviceType=content::MediaDeviceType",
+ "blink.mojom.MediaDeviceInfo=content::MediaDeviceInfo",
]
diff --git a/chromium/content/common/media/media_player_delegate_messages.h b/chromium/content/common/media/media_player_delegate_messages.h
index 69f372344cc..3791fc15ed5 100644
--- a/chromium/content/common/media/media_player_delegate_messages.h
+++ b/chromium/content/common/media/media_player_delegate_messages.h
@@ -31,6 +31,14 @@ IPC_MESSAGE_ROUTED1(MediaPlayerDelegateMsg_Pause,
IPC_MESSAGE_ROUTED1(MediaPlayerDelegateMsg_Play,
int /* delegate_id, distinguishes instances */)
+IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_SeekForward,
+ int /* delegate_id, distinguishes instances */,
+ base::TimeDelta /* seek_time */)
+
+IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_SeekBackward,
+ int /* delegate_id, distinguishes instances */,
+ base::TimeDelta /* seek_time */)
+
IPC_MESSAGE_ROUTED0(MediaPlayerDelegateMsg_SuspendAllMediaPlayers)
IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_UpdateVolumeMultiplier,
diff --git a/chromium/content/common/media/media_stream.mojom b/chromium/content/common/media/media_stream.mojom
index 9bdc1ff543e..5a0d0cbfa1c 100644
--- a/chromium/content/common/media/media_stream.mojom
+++ b/chromium/content/common/media/media_stream.mojom
@@ -4,8 +4,6 @@
module content.mojom;
-import "url/mojo/origin.mojom";
-
// TODO(c.padhi): Add typemapping for MediaStreamDevice,
// see https://crbug.com/742682.
// Native struct content::MediaStreamDevice.
@@ -58,27 +56,9 @@ struct StreamControls {
bool disable_local_echo;
};
-// Per-frame renderer-side interface that is used by the browser process to
-// respond to media stream requests from the renderer.
-interface MediaStreamDispatcher {
- // Informs the renderer that browser has generated a stream successfully.
- OnStreamGenerated(int32 request_id, string label,
- array<MediaStreamDevice> audio_devices,
- array<MediaStreamDevice> video_devices);
-
- // Informs the renderer that browser has failed to generate a stream.
- OnStreamGenerationFailed(int32 request_id, MediaStreamRequestResult result);
-
- // TODO(wjia): should DeviceOpen* methods be merged with
- // StreamGenerat* ones?
- // Informs the renderer that browser has opened a device successfully.
- OnDeviceOpened(int32 request_id, string label, MediaStreamDevice device);
-
- // Informs the renderer that browser has failed to open a device.
- OnDeviceOpenFailed(int32 request_id);
-
- // The browser reports that a media device has been stopped. Stopping was
- // triggered from the browser process.
+// Per-frame renderer-side interface that receives device stopped notifications
+// from the browser process.
+interface MediaStreamDeviceObserver {
OnDeviceStopped(string label, MediaStreamDevice device);
};
@@ -87,18 +67,21 @@ interface MediaStreamDispatcher {
interface MediaStreamDispatcherHost {
// Requests a new media stream.
GenerateStream(int32 render_frame_id, int32 request_id,
- StreamControls controls, url.mojom.Origin security_origin,
- bool user_gesture);
+ StreamControls controls, bool user_gesture)
+ => (MediaStreamRequestResult result, string label,
+ array<MediaStreamDevice> audio_devices,
+ array<MediaStreamDevice> video_devices);
- // Cancels the request for a new media stream.
- CancelGenerateStream(int32 render_frame_id, int32 request_id);
+ // Cancels the request for a new media stream or opening a device.
+ CancelRequest(int32 render_frame_id, int32 request_id);
// Closes a stream device that has been opened by GenerateStream.
StopStreamDevice(int32 render_frame_id, string device_id);
// Opens a device identified by |device_id|.
OpenDevice(int32 render_frame_id, int32 request_id, string device_id,
- MediaStreamType type, url.mojom.Origin security_origin);
+ MediaStreamType type)
+ => (bool success, string label, MediaStreamDevice device);
// Cancels an open request identified by |label|.
CloseDevice(string label);
@@ -115,5 +98,5 @@ interface MediaStreamDispatcherHost {
bool is_secure);
// Tells the browser process that the stream has been started successfully.
- StreamStarted(string label);
+ OnStreamStarted(string label);
};
diff --git a/chromium/content/common/native_types.mojom b/chromium/content/common/native_types.mojom
index a8e8cff9702..527c588f034 100644
--- a/chromium/content/common/native_types.mojom
+++ b/chromium/content/common/native_types.mojom
@@ -29,6 +29,9 @@ enum ScrollbarButtonsPlacement;
enum ScrollerStyle;
[Native]
+enum V8CacheOptions;
+
+[Native]
struct WebPreferences;
// TODO(rockot): This should most likely be defined by network service mojom,
diff --git a/chromium/content/common/native_types.typemap b/chromium/content/common/native_types.typemap
index cf3a0b0c440..72c58746741 100644
--- a/chromium/content/common/native_types.typemap
+++ b/chromium/content/common/native_types.typemap
@@ -10,8 +10,8 @@ public_headers = [
"//content/common/frame_replication_state.h",
"//content/common/resize_params.h",
"//content/common/input/input_event.h",
- "//content/common/input/input_event_ack_source.h",
- "//content/common/input/input_event_ack_state.h",
+ "//content/public/common/input_event_ack_source.h",
+ "//content/public/common/input_event_ack_state.h",
"//content/common/input/synthetic_pinch_gesture_params.h",
"//content/common/input/synthetic_pointer_action_list_params.h",
"//content/common/input/synthetic_smooth_drag_gesture_params.h",
diff --git a/chromium/content/common/native_types_mac.typemap b/chromium/content/common/native_types_mac.typemap
index 6a9fef2fcf5..8790e5c7a73 100644
--- a/chromium/content/common/native_types_mac.typemap
+++ b/chromium/content/common/native_types_mac.typemap
@@ -3,6 +3,7 @@
# found in the LICENSE file.
mojom = "//content/common/native_types.mojom"
+os_whitelist = [ "mac" ]
public_headers = [
"//third_party/WebKit/public/platform/WebScrollbarButtonsPlacement.h",
"//third_party/WebKit/public/platform/mac/WebScrollbarTheme.h",
diff --git a/chromium/content/common/navigation_params.cc b/chromium/content/common/navigation_params.cc
index f1a53087139..ec20b6d014e 100644
--- a/chromium/content/common/navigation_params.cc
+++ b/chromium/content/common/navigation_params.cc
@@ -36,7 +36,8 @@ CommonNavigationParams::CommonNavigationParams()
navigation_start(base::TimeTicks::Now()),
method("GET"),
should_check_main_world_csp(CSPDisposition::CHECK),
- started_from_context_menu(false) {}
+ started_from_context_menu(false),
+ has_user_gesture(false) {}
CommonNavigationParams::CommonNavigationParams(
const GURL& url,
@@ -55,7 +56,8 @@ CommonNavigationParams::CommonNavigationParams(
const scoped_refptr<ResourceRequestBody>& post_data,
base::Optional<SourceLocation> source_location,
CSPDisposition should_check_main_world_csp,
- bool started_from_context_menu)
+ bool started_from_context_menu,
+ bool has_user_gesture)
: url(url),
referrer(referrer),
transition(transition),
@@ -72,7 +74,8 @@ CommonNavigationParams::CommonNavigationParams(
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) {
+ started_from_context_menu(started_from_context_menu),
+ has_user_gesture(has_user_gesture) {
// |method != "POST"| should imply absence of |post_data|.
if (method != "POST" && post_data) {
NOTREACHED();
@@ -88,7 +91,6 @@ CommonNavigationParams::~CommonNavigationParams() {
BeginNavigationParams::BeginNavigationParams()
: load_flags(0),
- has_user_gesture(false),
skip_service_worker(false),
request_context_type(REQUEST_CONTEXT_TYPE_LOCATION),
mixed_content_context_type(blink::WebMixedContentContextType::kBlockable),
@@ -97,7 +99,6 @@ BeginNavigationParams::BeginNavigationParams()
BeginNavigationParams::BeginNavigationParams(
std::string headers,
int load_flags,
- bool has_user_gesture,
bool skip_service_worker,
RequestContextType request_context_type,
blink::WebMixedContentContextType mixed_content_context_type,
@@ -105,7 +106,6 @@ BeginNavigationParams::BeginNavigationParams(
const base::Optional<url::Origin>& initiator_origin)
: headers(headers),
load_flags(load_flags),
- has_user_gesture(has_user_gesture),
skip_service_worker(skip_service_worker),
request_context_type(request_context_type),
mixed_content_context_type(mixed_content_context_type),
@@ -151,9 +151,7 @@ RequestNavigationParams::RequestNavigationParams()
should_clear_history_list(false),
should_create_service_worker(false),
service_worker_provider_id(kInvalidServiceWorkerProviderId),
- appcache_host_id(kAppCacheNoHostId),
- has_user_gesture(false) {
-}
+ appcache_host_id(kAppCacheNoHostId) {}
RequestNavigationParams::RequestNavigationParams(
bool is_overriding_user_agent,
@@ -171,8 +169,7 @@ RequestNavigationParams::RequestNavigationParams(
int current_history_list_offset,
int current_history_list_length,
bool is_view_source,
- bool should_clear_history_list,
- bool has_user_gesture)
+ bool should_clear_history_list)
: is_overriding_user_agent(is_overriding_user_agent),
redirects(redirects),
original_url(original_url),
@@ -191,8 +188,7 @@ RequestNavigationParams::RequestNavigationParams(
should_clear_history_list(should_clear_history_list),
should_create_service_worker(false),
service_worker_provider_id(kInvalidServiceWorkerProviderId),
- appcache_host_id(kAppCacheNoHostId),
- has_user_gesture(has_user_gesture) {}
+ appcache_host_id(kAppCacheNoHostId) {}
RequestNavigationParams::RequestNavigationParams(
const RequestNavigationParams& other) = default;
diff --git a/chromium/content/common/navigation_params.h b/chromium/content/common/navigation_params.h
index 19c2acc137b..5cabafb906a 100644
--- a/chromium/content/common/navigation_params.h
+++ b/chromium/content/common/navigation_params.h
@@ -47,8 +47,8 @@ struct CONTENT_EXPORT SourceLocation {
};
// The following structures hold parameters used during a navigation. In
-// particular they are used by FrameMsg_Navigate, FrameMsg_CommitNavigation and
-// FrameHostMsg_BeginNavigation.
+// particular they are used by FrameMsg_Navigate, FrameHostMsg_BeginNavigation,
+// and mojom::FrameNavigationControl.
// Provided by the browser or the renderer -------------------------------------
@@ -71,7 +71,8 @@ struct CONTENT_EXPORT CommonNavigationParams {
const scoped_refptr<ResourceRequestBody>& post_data,
base::Optional<SourceLocation> source_location,
CSPDisposition should_check_main_world_csp,
- bool started_from_context_menu);
+ bool started_from_context_menu,
+ bool has_user_gesture);
CommonNavigationParams(const CommonNavigationParams& other);
~CommonNavigationParams();
@@ -150,6 +151,9 @@ struct CONTENT_EXPORT CommonNavigationParams {
// Whether or not this navigation was started from a context menu.
bool started_from_context_menu;
+
+ // True if the request was user initiated.
+ bool has_user_gesture;
};
// Provided by the renderer ----------------------------------------------------
@@ -168,7 +172,6 @@ struct CONTENT_EXPORT BeginNavigationParams {
BeginNavigationParams(
std::string headers,
int load_flags,
- bool has_user_gesture,
bool skip_service_worker,
RequestContextType request_context_type,
blink::WebMixedContentContextType mixed_content_context_type,
@@ -183,9 +186,6 @@ struct CONTENT_EXPORT BeginNavigationParams {
// net::URLRequest load flags (net::LOAD_NORMAL) by default).
int load_flags;
- // True if the request was user initiated.
- bool has_user_gesture;
-
// True if the ServiceWorker should be skipped.
bool skip_service_worker;
@@ -276,8 +276,7 @@ struct CONTENT_EXPORT RequestNavigationParams {
int current_history_list_offset,
int current_history_list_length,
bool is_view_source,
- bool should_clear_history_list,
- bool has_user_gesture);
+ bool should_clear_history_list);
RequestNavigationParams(const RequestNavigationParams& other);
~RequestNavigationParams();
@@ -382,9 +381,6 @@ struct CONTENT_EXPORT RequestNavigationParams {
// The AppCache host id to be used to identify this navigation.
int appcache_host_id;
- // True if the navigation originated due to a user gesture.
- bool has_user_gesture;
-
#if defined(OS_ANDROID)
// The real content of the data: URL. Only used in Android WebView for
// implementing LoadDataWithBaseUrl API method to circumvent the restriction
diff --git a/chromium/content/common/navigation_params.typemap b/chromium/content/common/navigation_params.typemap
new file mode 100644
index 00000000000..792faa10a3d
--- /dev/null
+++ b/chromium/content/common/navigation_params.typemap
@@ -0,0 +1,14 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//content/common/frame.mojom"
+public_headers = [ "//content/common/navigation_params.h" ]
+traits_headers = [ "//content/common/frame_messages.h" ]
+deps = [
+ "//content:export",
+]
+type_mappings = [
+ "content.mojom.CommonNavigationParams=content::CommonNavigationParams",
+ "content.mojom.RequestNavigationParams=content::RequestNavigationParams",
+]
diff --git a/chromium/content/common/navigation_subresource_loader_params.cc b/chromium/content/common/navigation_subresource_loader_params.cc
new file mode 100644
index 00000000000..8bf57ebe86d
--- /dev/null
+++ b/chromium/content/common/navigation_subresource_loader_params.cc
@@ -0,0 +1,23 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/navigation_subresource_loader_params.h"
+
+namespace content {
+
+SubresourceLoaderParams::SubresourceLoaderParams() = default;
+SubresourceLoaderParams::~SubresourceLoaderParams() = default;
+
+SubresourceLoaderParams::SubresourceLoaderParams(
+ SubresourceLoaderParams&& other) {
+ loader_factory_info = std::move(other.loader_factory_info);
+}
+
+SubresourceLoaderParams& SubresourceLoaderParams::operator=(
+ SubresourceLoaderParams&& other) {
+ loader_factory_info = std::move(other.loader_factory_info);
+ return *this;
+}
+
+} // namespace content
diff --git a/chromium/content/common/navigation_subresource_loader_params.h b/chromium/content/common/navigation_subresource_loader_params.h
new file mode 100644
index 00000000000..cb93106b371
--- /dev/null
+++ b/chromium/content/common/navigation_subresource_loader_params.h
@@ -0,0 +1,34 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_NAVIGATION_SUBRESOURCE_LOADER_PARAMS_H_
+#define CONTENT_COMMON_NAVIGATION_SUBRESOURCE_LOADER_PARAMS_H_
+
+#include "content/common/service_worker/controller_service_worker.mojom.h"
+#include "content/public/common/url_loader_factory.mojom.h"
+
+namespace content {
+
+// For NetworkService glues:
+// Navigation parameters that are necessary to set-up a subresource loader
+// for the frame that is going to be created by the navigation.
+// Passed from the browser to the renderer when the navigation commits when
+// NetworkService or its glue code for relevant features is enabled.
+struct CONTENT_EXPORT SubresourceLoaderParams {
+ SubresourceLoaderParams();
+ ~SubresourceLoaderParams();
+
+ SubresourceLoaderParams(SubresourceLoaderParams&& other);
+ SubresourceLoaderParams& operator=(SubresourceLoaderParams&& other);
+
+ // The subresource loader factory info that is to be used to create a
+ // subresource loader in the renderer.
+ mojom::URLLoaderFactoryPtrInfo loader_factory_info;
+
+ // TODO(kinuko): Add the controller interface ptr for the service worker.
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_NAVIGATION_SUBRESOURCE_LOADER_PARAMS_H_
diff --git a/chromium/content/common/net/url_fetcher.cc b/chromium/content/common/net/url_fetcher.cc
index 6ac2bf75d8b..ab75940d575 100644
--- a/chromium/content/common/net/url_fetcher.cc
+++ b/chromium/content/common/net/url_fetcher.cc
@@ -16,7 +16,7 @@ namespace {
std::unique_ptr<base::SupportsUserData::Data> CreateURLRequestUserData(
int render_process_id,
int render_frame_id) {
- return base::MakeUnique<URLRequestUserData>(render_process_id,
+ return std::make_unique<URLRequestUserData>(render_process_id,
render_frame_id);
}
diff --git a/chromium/content/common/origin_trials/trial_policy_impl.cc b/chromium/content/common/origin_trials/trial_policy_impl.cc
index 9640757abea..607b2f1c04a 100644
--- a/chromium/content/common/origin_trials/trial_policy_impl.cc
+++ b/chromium/content/common/origin_trials/trial_policy_impl.cc
@@ -9,6 +9,7 @@
#include "content/public/common/content_features.h"
#include "content/public/common/origin_trial_policy.h"
#include "content/public/common/origin_util.h"
+#include "third_party/WebKit/common/origin_trials/trial_token_validator.h"
namespace content {
@@ -34,4 +35,10 @@ const OriginTrialPolicy* TrialPolicyImpl::policy() const {
return GetContentClient()->GetOriginTrialPolicy();
}
+std::unique_ptr<blink::TrialTokenValidator>
+TrialPolicyImpl::CreateValidatorForPolicy() {
+ return std::make_unique<blink::TrialTokenValidator>(
+ std::make_unique<TrialPolicyImpl>());
+}
+
} // namespace content
diff --git a/chromium/content/common/origin_trials/trial_policy_impl.h b/chromium/content/common/origin_trials/trial_policy_impl.h
index 00556266b78..6ea013f4798 100644
--- a/chromium/content/common/origin_trials/trial_policy_impl.h
+++ b/chromium/content/common/origin_trials/trial_policy_impl.h
@@ -9,6 +9,10 @@
#include "content/common/content_export.h"
#include "third_party/WebKit/common/origin_trials/trial_policy.h"
+namespace blink {
+class TrialTokenValidator;
+} // namespace blink
+
namespace content {
class OriginTrialPolicy;
@@ -27,6 +31,8 @@ class CONTENT_EXPORT TrialPolicyImpl : public blink::TrialPolicy {
bool IsTokenDisabled(base::StringPiece token_signature) const override;
bool IsOriginSecure(const GURL& url) const override;
+ static std::unique_ptr<blink::TrialTokenValidator> CreateValidatorForPolicy();
+
private:
const OriginTrialPolicy* policy() const;
};
diff --git a/chromium/content/common/origin_util.cc b/chromium/content/common/origin_util.cc
index 4de5ccb62c6..bf9e0bdf350 100644
--- a/chromium/content/common/origin_util.cc
+++ b/chromium/content/common/origin_util.cc
@@ -63,8 +63,7 @@ bool IsOriginWhiteListedTrustworthy(const url::Origin& origin) {
if (IsOriginUnique(origin))
return false;
- return base::ContainsValue(GetSecureOrigins(),
- origin.GetURL().HostNoBrackets());
+ return base::ContainsValue(GetSecureOrigins(), origin.GetURL());
}
bool IsPotentiallyTrustworthyOrigin(const url::Origin& origin) {
diff --git a/chromium/content/common/page_messages.h b/chromium/content/common/page_messages.h
index b1c511b4060..a1d38aabbcc 100644
--- a/chromium/content/common/page_messages.h
+++ b/chromium/content/common/page_messages.h
@@ -30,9 +30,6 @@ IPC_MESSAGE_ROUTED2(PageMsg_SetZoomLevel,
PageMsg_SetZoomLevel_Command /* command */,
double /* zoom_level */)
-IPC_MESSAGE_ROUTED1(PageMsg_SetDeviceScaleFactor,
- double /* device_scale_factor */)
-
// Informs the renderer that the page was hidden.
IPC_MESSAGE_ROUTED0(PageMsg_WasHidden)
diff --git a/chromium/content/common/page_state.mojom b/chromium/content/common/page_state.mojom
new file mode 100644
index 00000000000..f30a38c5a19
--- /dev/null
+++ b/chromium/content/common/page_state.mojom
@@ -0,0 +1,110 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.history.mojom;
+
+import "mojo/common/string16.mojom";
+import "mojo/common/time.mojom";
+import "third_party/WebKit/public/platform/referrer.mojom";
+import "url/mojo/url.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
+
+// This file contains the mojo IDL definitions for PageState and its constituent
+// parts. The resultant generated code is used to serialize and deserialize
+// PageState for the purpose of history restore.
+// When adding fields, assign your new field an explicity ordinal(@n) and
+// prefer to add fields to the end of the struct to simplify finding the
+// latest ordinal.
+// For backwards compatibility purposes, new fields must be tagged with a
+// [MinVersion=x] attribute; x is specified at the bottom of this comment
+// block.
+// You'll also need to read/write the new field's value when decoding and
+// encoding PageState, update PageStateSerializationTest to check that
+// your new field is preserved across serialization, and add a BackwardsCompat
+// test with associated serialized_vxx.dat file. Look for
+// DumpExpectedPageStateForBackwardsCompat in page_state_serialization_unittest
+// for how to do this.
+// Don't remove, or change the type of fields; this will break
+// compatibility. If re-ordering fields, make sure to retain the original
+// ordinal value.
+// Update the below value if your change introduces fields using it.
+// Next MinVersion: 2
+
+// Next Ordinal: 4
+struct FileSystemFile {
+ url.mojom.Url filesystem_url@0;
+ uint64 offset@1;
+ uint64 length@2;
+ mojo.common.mojom.Time modification_time@3;
+};
+
+// Next Ordinal: 4
+struct File {
+ mojo.common.mojom.String16 path@0;
+ uint64 offset@1;
+ uint64 length@2;
+ mojo.common.mojom.Time modification_time@3;
+};
+
+// Next Ordinal: 4
+union Element {
+ string blob_uuid@0;
+ array<uint8> bytes@1;
+ File file@2;
+ FileSystemFile file_system_file@3;
+};
+
+// Next Ordinal: 3
+struct RequestBody {
+ array<Element> elements@0;
+ int64 identifier@1;
+ bool contains_sensitive_info@2;
+};
+
+// Next Ordinal: 3
+struct HttpBody {
+ mojo.common.mojom.String16? http_content_type@0;
+ RequestBody? request_body@1;
+ bool contains_passwords@2 = false;
+};
+
+// This enum's values must match blink::WebHistoryScrollRestorationType. This
+// is enforced with static asserts in page_state_serialization.cc.
+[Extensible]
+enum ScrollRestorationType {
+ kAuto = 0,
+ kManual = 1
+};
+
+// Next Ordinal: 6
+struct ViewState {
+ gfx.mojom.PointF visual_viewport_scroll_offset@0;
+ gfx.mojom.Point scroll_offset@1;
+ double page_scale_factor@2;
+ // Serialized scroll anchor fields
+ [MinVersion=1] mojo.common.mojom.String16? scroll_anchor_selector@3;
+ [MinVersion=1] gfx.mojom.PointF? scroll_anchor_offset@4;
+ [MinVersion=1] uint64 scroll_anchor_simhash@5 = 0;
+};
+
+struct FrameState {
+ mojo.common.mojom.String16? url_string@0;
+ mojo.common.mojom.String16? referrer@1;
+ mojo.common.mojom.String16? target@2;
+ mojo.common.mojom.String16? state_object@3;
+ array<mojo.common.mojom.String16?> document_state@4;
+ ScrollRestorationType scroll_restoration_type@5;
+ ViewState? view_state@6;
+ int64 item_sequence_number@7;
+ int64 document_sequence_number@8;
+ blink.mojom.ReferrerPolicy referrer_policy@9;
+ HttpBody http_body@10;
+ array<FrameState> children@11;
+};
+
+// Next Ordinal: 2
+struct PageState {
+ array<mojo.common.mojom.String16?> referenced_files@0;
+ FrameState top@1;
+};
diff --git a/chromium/content/common/page_state_serialization.cc b/chromium/content/common/page_state_serialization.cc
index a379477d165..3c02086591c 100644
--- a/chromium/content/common/page_state_serialization.cc
+++ b/chromium/content/common/page_state_serialization.cc
@@ -4,8 +4,6 @@
#include "content/common/page_state_serialization.h"
-#include <stddef.h>
-
#include <algorithm>
#include <limits>
@@ -14,12 +12,32 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
+#include "content/common/page_state.mojom.h"
#include "content/common/unique_name_helper.h"
+#include "content/public/common/referrer_struct_traits.h"
#include "content/public/common/resource_request_body.h"
+#include "ipc/ipc_message_utils.h"
+#include "mojo/common/common_custom_types_struct_traits.h"
+#include "mojo/common/time_struct_traits.h"
+#include "third_party/WebKit/public/platform/WebHistoryScrollRestorationType.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
+#include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
+#include "url/mojo/url_gurl_struct_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,
+ blink::kWebHistoryScrollRestorationAuto);
+STATIC_ASSERT_ENUM(mojom::ScrollRestorationType::kManual,
+ blink::kWebHistoryScrollRestorationManual);
+
namespace {
#if defined(OS_ANDROID)
@@ -40,12 +58,12 @@ void AppendFileRangeToRequestBody(
const base::Optional<base::string16>& file_path,
int file_start,
int file_length,
- double file_modification_time) {
+ base::Time file_modification_time) {
request_body->AppendFileRange(
file_path ? base::FilePath::FromUTF16Unsafe(*file_path)
: base::FilePath(),
static_cast<uint64_t>(file_start), static_cast<uint64_t>(file_length),
- base::Time::FromDoubleT(file_modification_time));
+ file_modification_time);
}
void AppendURLRangeToRequestBody(
@@ -53,11 +71,10 @@ void AppendURLRangeToRequestBody(
const GURL& url,
int file_start,
int file_length,
- double file_modification_time) {
+ base::Time file_modification_time) {
request_body->AppendFileSystemFileRange(
url, static_cast<uint64_t>(file_start),
- static_cast<uint64_t>(file_length),
- base::Time::FromDoubleT(file_modification_time));
+ static_cast<uint64_t>(file_length), file_modification_time);
}
void AppendBlobToRequestBody(
@@ -200,7 +217,8 @@ struct SerializeObject {
// 23: Remove frame sequence number, there are easier ways.
// 24: Add did save scroll or scale state.
// 25: Limit the length of unique names: https://crbug.com/626202
-//
+// 26: Switch to mojo-based serialization.
+// 27: Add serialized scroll anchor to FrameState.
// NOTE: If the version is -1, then the pickle contains only a URL string.
// See ReadPageState.
//
@@ -208,11 +226,14 @@ const int kMinVersion = 11;
// NOTE: When changing the version, please add a backwards compatibility test.
// See PageStateSerializationTest.DumpExpectedPageStateForBackwardsCompat for
// instructions on how to generate the new test case.
-const int kCurrentVersion = 25;
+const int kCurrentVersion = 27;
-// A bunch of convenience functions to read/write to SerializeObjects. The
+// A bunch of convenience functions to write to/read from SerializeObjects. The
// de-serializers assume the input data will be in the correct format and fall
-// back to returning safe defaults when not.
+// back to returning safe defaults when not. These are mostly used by
+// legacy(pre-mojo) serialization methods. If you're making changes to the
+// PageState serialization format you almost certainly want to add/remove fields
+// in page_state.mojom rather than using these methods.
void WriteData(const void* data, int length, SerializeObject* obj) {
obj->pickle.WriteData(static_cast<const char*>(data), length);
@@ -224,7 +245,7 @@ void ReadData(SerializeObject* obj, const void** data, int* length) {
*data = tmp;
} else {
obj->parse_error = true;
- *data = NULL;
+ *data = nullptr;
*length = 0;
}
}
@@ -258,7 +279,7 @@ void WriteReal(double data, SerializeObject* obj) {
}
double ReadReal(SerializeObject* obj) {
- const void* tmp = NULL;
+ const void* tmp = nullptr;
int length = 0;
double value = 0.0;
ReadData(obj, &tmp, &length);
@@ -335,16 +356,16 @@ const base::char16* ReadStringNoCopy(SerializeObject* obj, int* num_chars) {
int length_in_bytes;
if (!obj->iter.ReadInt(&length_in_bytes)) {
obj->parse_error = true;
- return NULL;
+ return nullptr;
}
if (length_in_bytes < 0)
- return NULL;
+ return nullptr;
const char* data;
if (!obj->iter.ReadBytes(&data, length_in_bytes)) {
obj->parse_error = true;
- return NULL;
+ return nullptr;
}
if (num_chars)
@@ -432,6 +453,7 @@ void WriteResourceRequestBody(const ResourceRequestBody& request_body,
WriteInteger(blink::WebHTTPBody::Element::kTypeBlob, obj);
WriteStdString(element.blob_uuid(), obj);
break;
+ case ResourceRequestBody::Element::TYPE_RAW_FILE:
case ResourceRequestBody::Element::TYPE_BYTES_DESCRIPTION:
case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
default:
@@ -461,15 +483,17 @@ void ReadResourceRequestBody(
int64_t file_start = ReadInteger64(obj);
int64_t file_length = ReadInteger64(obj);
double file_modification_time = ReadReal(obj);
- AppendFileRangeToRequestBody(request_body, file_path, file_start,
- file_length, file_modification_time);
+ AppendFileRangeToRequestBody(
+ request_body, file_path, file_start, file_length,
+ base::Time::FromDoubleT(file_modification_time));
} else if (type == blink::WebHTTPBody::Element::kTypeFileSystemURL) {
GURL url = ReadGURL(obj);
int64_t file_start = ReadInteger64(obj);
int64_t file_length = ReadInteger64(obj);
double file_modification_time = ReadReal(obj);
- AppendURLRangeToRequestBody(request_body, url, file_start, file_length,
- file_modification_time);
+ AppendURLRangeToRequestBody(
+ request_body, url, file_start, file_length,
+ base::Time::FromDoubleT(file_modification_time));
} else if (type == blink::WebHTTPBody::Element::kTypeBlob) {
if (obj->version >= 16) {
std::string blob_uuid = ReadStdString(obj);
@@ -482,17 +506,6 @@ void ReadResourceRequestBody(
request_body->set_identifier(ReadInteger64(obj));
}
-// Writes an ExplodedHttpBody object into a SerializeObject for serialization.
-void WriteHttpBody(const ExplodedHttpBody& http_body, SerializeObject* obj) {
- bool is_null = http_body.request_body == nullptr;
- WriteBoolean(!is_null, obj);
- if (is_null)
- return;
-
- WriteResourceRequestBody(*http_body.request_body, obj);
- WriteBoolean(http_body.contains_passwords, obj);
-}
-
void ReadHttpBody(SerializeObject* obj, ExplodedHttpBody* http_body) {
// An initial boolean indicates if we have an HTTP body.
if (!ReadBoolean(obj))
@@ -505,60 +518,14 @@ void ReadHttpBody(SerializeObject* obj, ExplodedHttpBody* http_body) {
http_body->contains_passwords = ReadBoolean(obj);
}
-// Writes the ExplodedFrameState data into the SerializeObject object for
-// serialization.
-void WriteFrameState(
- const ExplodedFrameState& state, SerializeObject* obj, bool is_top) {
- // WARNING: This data may be persisted for later use. As such, care must be
- // taken when changing the serialized format. If a new field needs to be
- // written, only adding at the end will make it easier to deal with loading
- // older versions. Similarly, this should NOT save fields with sensitive
- // data, such as password fields.
-
- WriteString(state.url_string, obj);
- WriteString(state.target, obj);
- WriteBoolean(state.did_save_scroll_or_scale_state, obj);
-
- if (state.did_save_scroll_or_scale_state) {
- WriteInteger(state.scroll_offset.x(), obj);
- WriteInteger(state.scroll_offset.y(), obj);
- }
-
- WriteString(state.referrer, obj);
-
- WriteStringVector(state.document_state, obj);
-
- if (state.did_save_scroll_or_scale_state)
- WriteReal(state.page_scale_factor, obj);
-
- WriteInteger64(state.item_sequence_number, obj);
- WriteInteger64(state.document_sequence_number, obj);
- WriteInteger(static_cast<int>(state.referrer_policy), obj);
-
- if (state.did_save_scroll_or_scale_state) {
- WriteReal(state.visual_viewport_scroll_offset.x(), obj);
- WriteReal(state.visual_viewport_scroll_offset.y(), obj);
- }
-
- WriteInteger(state.scroll_restoration_type, obj);
-
- bool has_state_object = state.state_object.has_value();
- WriteBoolean(has_state_object, obj);
- if (has_state_object)
- WriteString(*state.state_object, obj);
-
- WriteHttpBody(state.http_body, obj);
-
- // NOTE: It is a quirk of the format that we still have to write the
- // http_content_type field when the HTTP body is null. That's why this code
- // is here instead of inside WriteHttpBody.
- WriteString(state.http_body.http_content_type, obj);
+void WriteHttpBody(const ExplodedHttpBody& http_body, SerializeObject* obj) {
+ bool is_null = http_body.request_body == nullptr;
+ WriteBoolean(!is_null, obj);
+ if (is_null)
+ return;
- // Subitems
- const std::vector<ExplodedFrameState>& children = state.children;
- WriteAndValidateVectorSize(children, obj);
- for (size_t i = 0; i < children.size(); ++i)
- WriteFrameState(children[i], obj, false);
+ WriteResourceRequestBody(*http_body.request_body, obj);
+ WriteBoolean(http_body.contains_passwords, obj);
}
void ReadFrameState(
@@ -681,12 +648,304 @@ void ReadFrameState(
ReadFrameState(obj, false, unique_name_replacements, &state->children[i]);
}
+// Writes the ExplodedFrameState data into the SerializeObject object for
+// serialization. This uses the custom, legacy format, and its implementation
+// should remain frozen in order to preserve this format.
+// TODO(pnoland, dcheng) Move the legacy write methods into a test-only helper.
+void WriteFrameState(const ExplodedFrameState& state,
+ SerializeObject* obj,
+ bool is_top) {
+ // WARNING: This data may be persisted for later use. As such, care must be
+ // taken when changing the serialized format. If a new field needs to be
+ // written, only adding at the end will make it easier to deal with loading
+ // older versions. Similarly, this should NOT save fields with sensitive
+ // data, such as password fields.
+
+ WriteString(state.url_string, obj);
+ WriteString(state.target, obj);
+ WriteBoolean(state.did_save_scroll_or_scale_state, obj);
+
+ if (state.did_save_scroll_or_scale_state) {
+ WriteInteger(state.scroll_offset.x(), obj);
+ WriteInteger(state.scroll_offset.y(), obj);
+ }
+
+ WriteString(state.referrer, obj);
+
+ WriteStringVector(state.document_state, obj);
+
+ if (state.did_save_scroll_or_scale_state)
+ WriteReal(state.page_scale_factor, obj);
+
+ WriteInteger64(state.item_sequence_number, obj);
+ WriteInteger64(state.document_sequence_number, obj);
+ WriteInteger(static_cast<int>(state.referrer_policy), obj);
+
+ if (state.did_save_scroll_or_scale_state) {
+ WriteReal(state.visual_viewport_scroll_offset.x(), obj);
+ WriteReal(state.visual_viewport_scroll_offset.y(), obj);
+ }
+
+ WriteInteger(state.scroll_restoration_type, obj);
+
+ bool has_state_object = state.state_object.has_value();
+ WriteBoolean(has_state_object, obj);
+ if (has_state_object)
+ WriteString(*state.state_object, obj);
+
+ WriteHttpBody(state.http_body, obj);
+
+ // NOTE: It is a quirk of the format that we still have to write the
+ // http_content_type field when the HTTP body is null. That's why this code
+ // is here instead of inside WriteHttpBody.
+ WriteString(state.http_body.http_content_type, obj);
+
+ // Subitems
+ const std::vector<ExplodedFrameState>& children = state.children;
+ WriteAndValidateVectorSize(children, obj);
+ for (size_t i = 0; i < children.size(); ++i)
+ WriteFrameState(children[i], obj, false);
+}
+
void WritePageState(const ExplodedPageState& state, SerializeObject* obj) {
WriteInteger(obj->version, obj);
WriteStringVector(state.referenced_files, obj);
WriteFrameState(state.top, obj, true);
}
+// Legacy read/write functions above this line. Don't change these.
+//-----------------------------------------------------------------------------
+// "Modern" read/write functions start here. These are probably what you want.
+
+void WriteResourceRequestBody(const ResourceRequestBody& request_body,
+ mojom::RequestBody* mojo_body) {
+ for (const auto& element : *request_body.elements()) {
+ mojom::ElementPtr data_element = mojom::Element::New();
+ switch (element.type()) {
+ case ResourceRequestBody::Element::TYPE_BYTES: {
+ data_element->set_bytes(std::vector<unsigned char>(
+ reinterpret_cast<const char*>(element.bytes()),
+ element.bytes() + element.length()));
+ break;
+ }
+ case ResourceRequestBody::Element::TYPE_FILE: {
+ mojom::FilePtr file = mojom::File::New(
+ element.path().AsUTF16Unsafe(), element.offset(), element.length(),
+ element.expected_modification_time());
+ data_element->set_file(std::move(file));
+ break;
+ }
+ case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM: {
+ mojom::FileSystemFilePtr file_system = mojom::FileSystemFile::New(
+ element.filesystem_url(), element.offset(), element.length(),
+ element.expected_modification_time());
+ data_element->set_file_system_file(std::move(file_system));
+ break;
+ }
+ case ResourceRequestBody::Element::TYPE_BLOB:
+ data_element->set_blob_uuid(element.blob_uuid());
+ break;
+ case ResourceRequestBody::Element::TYPE_RAW_FILE:
+ case ResourceRequestBody::Element::TYPE_BYTES_DESCRIPTION:
+ case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
+ case ResourceRequestBody::Element::TYPE_DATA_PIPE:
+ case ResourceRequestBody::Element::TYPE_UNKNOWN:
+ NOTREACHED();
+ continue;
+ }
+ mojo_body->elements.push_back(std::move(data_element));
+ }
+ mojo_body->identifier = request_body.identifier();
+}
+
+void ReadResourceRequestBody(
+ mojom::RequestBody* mojo_body,
+ const scoped_refptr<ResourceRequestBody>& request_body) {
+ for (const auto& element : mojo_body->elements) {
+ mojom::Element::Tag tag = element->which();
+ switch (tag) {
+ case 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();
+ AppendFileRangeToRequestBody(request_body, file->path, file->offset,
+ file->length, file->modification_time);
+ break;
+ }
+ case mojom::Element::Tag::FILE_SYSTEM_FILE: {
+ mojom::FileSystemFile* file_system =
+ element->get_file_system_file().get();
+ AppendURLRangeToRequestBody(request_body, file_system->filesystem_url,
+ file_system->offset, file_system->length,
+ file_system->modification_time);
+ break;
+ }
+ case mojom::Element::Tag::BLOB_UUID:
+ AppendBlobToRequestBody(request_body, element->get_blob_uuid());
+ break;
+ }
+ }
+ request_body->set_identifier(mojo_body->identifier);
+}
+
+void WriteHttpBody(const ExplodedHttpBody& http_body,
+ mojom::HttpBody* mojo_body) {
+ if (http_body.request_body != nullptr) {
+ mojo_body->request_body = 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,
+ mojo_body->request_body.get());
+ }
+}
+
+void ReadHttpBody(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) {
+ http_body->request_body = base::MakeRefCounted<ResourceRequestBody>();
+ ReadResourceRequestBody(mojo_body->request_body.get(),
+ http_body->request_body);
+ }
+}
+
+void WriteFrameState(const ExplodedFrameState& state,
+ mojom::FrameState* frame) {
+ frame->url_string = state.url_string;
+ frame->referrer = state.referrer;
+ frame->target = state.target;
+ frame->state_object = state.state_object;
+
+ for (const auto& s : state.document_state) {
+ frame->document_state.push_back(s);
+ }
+
+ frame->scroll_restoration_type =
+ static_cast<mojom::ScrollRestorationType>(state.scroll_restoration_type);
+
+ if (state.did_save_scroll_or_scale_state) {
+ frame->view_state = mojom::ViewState::New();
+ frame->view_state->scroll_offset = state.scroll_offset;
+ frame->view_state->visual_viewport_scroll_offset =
+ state.visual_viewport_scroll_offset;
+ frame->view_state->page_scale_factor = state.page_scale_factor;
+ // We discard all scroll anchor data if the selector is over the length
+ // limit. We don't want to bloat the size of FrameState, and the other
+ // fields are useless without the selector.
+ if (state.scroll_anchor_selector && state.scroll_anchor_selector->length() <
+ kMaxScrollAnchorSelectorLength) {
+ frame->view_state->scroll_anchor_selector = state.scroll_anchor_selector;
+ frame->view_state->scroll_anchor_offset = state.scroll_anchor_offset;
+ frame->view_state->scroll_anchor_simhash = state.scroll_anchor_simhash;
+ }
+ }
+
+ frame->item_sequence_number = state.item_sequence_number;
+ frame->document_sequence_number = state.document_sequence_number;
+
+ frame->referrer_policy = state.referrer_policy;
+
+ frame->http_body = 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();
+ WriteFrameState(child, child_frame.get());
+ frame->children.push_back(std::move(child_frame));
+ }
+}
+
+void ReadFrameState(mojom::FrameState* frame, ExplodedFrameState* state) {
+ state->url_string = frame->url_string;
+ state->referrer = frame->referrer;
+ state->target = frame->target;
+ state->state_object = frame->state_object;
+
+ for (const auto& s : frame->document_state) {
+ state->document_state.push_back(s);
+ }
+
+ state->scroll_restoration_type =
+ static_cast<blink::WebHistoryScrollRestorationType>(
+ frame->scroll_restoration_type);
+
+ if (frame->view_state) {
+ state->did_save_scroll_or_scale_state = true;
+ state->visual_viewport_scroll_offset =
+ frame->view_state->visual_viewport_scroll_offset;
+ state->scroll_offset = frame->view_state->scroll_offset;
+ state->page_scale_factor = frame->view_state->page_scale_factor;
+ }
+
+ if (frame->view_state) {
+ state->scroll_anchor_selector = frame->view_state->scroll_anchor_selector;
+ state->scroll_anchor_offset =
+ frame->view_state->scroll_anchor_offset.value_or(gfx::PointF());
+ state->scroll_anchor_simhash = frame->view_state->scroll_anchor_simhash;
+ }
+
+ state->item_sequence_number = frame->item_sequence_number;
+ state->document_sequence_number = frame->document_sequence_number;
+
+ state->referrer_policy = frame->referrer_policy;
+ if (frame->http_body) {
+ ReadHttpBody(frame->http_body.get(), &state->http_body);
+ } else {
+ state->http_body.request_body = nullptr;
+ }
+
+ state->children.resize(frame->children.size());
+ int i = 0;
+ for (const auto& child : frame->children)
+ ReadFrameState(child.get(), &state->children[i++]);
+}
+
+void ReadMojoPageState(SerializeObject* obj, ExplodedPageState* state) {
+ const void* tmp = nullptr;
+ int length = 0;
+ ReadData(obj, &tmp, &length);
+ DCHECK_GT(length, 0);
+ if (obj->parse_error)
+ return;
+
+ mojom::PageStatePtr page;
+ obj->parse_error = !(mojom::PageState::Deserialize(tmp, length, &page));
+ if (obj->parse_error)
+ return;
+
+ for (const auto& referenced_file : page->referenced_files) {
+ state->referenced_files.push_back(referenced_file);
+ }
+
+ ReadFrameState(page->top.get(), &state->top);
+
+ state->referenced_files.erase(std::unique(state->referenced_files.begin(),
+ state->referenced_files.end()),
+ state->referenced_files.end());
+}
+
+void WriteMojoPageState(const ExplodedPageState& state, SerializeObject* obj) {
+ WriteInteger(obj->version, obj);
+
+ mojom::PageStatePtr page = mojom::PageState::New();
+ for (const auto& referenced_file : state.referenced_files) {
+ page->referenced_files.push_back(referenced_file.value());
+ }
+
+ page->top = mojom::FrameState::New();
+ WriteFrameState(state.top, page->top.get());
+
+ std::vector<uint8_t> page_bytes = mojom::PageState::Serialize(&page);
+ obj->pickle.WriteData(reinterpret_cast<char*>(page_bytes.data()),
+ page_bytes.size());
+}
+
void ReadPageState(SerializeObject* obj, ExplodedPageState* state) {
obj->version = ReadInteger(obj);
@@ -702,6 +961,11 @@ void ReadPageState(SerializeObject* obj, ExplodedPageState* state) {
return;
}
+ if (obj->version >= 26) {
+ ReadMojoPageState(obj, state);
+ return;
+ }
+
if (obj->version >= 14)
ReadStringVector(obj, &state->referenced_files);
@@ -731,7 +995,8 @@ ExplodedFrameState::ExplodedFrameState()
item_sequence_number(0),
document_sequence_number(0),
page_scale_factor(0.0),
- referrer_policy(blink::kWebReferrerPolicyDefault) {}
+ referrer_policy(blink::kWebReferrerPolicyDefault),
+ scroll_anchor_simhash(0) {}
ExplodedFrameState::ExplodedFrameState(const ExplodedFrameState& other) {
assign(other);
@@ -760,6 +1025,9 @@ void ExplodedFrameState::assign(const ExplodedFrameState& other) {
page_scale_factor = other.page_scale_factor;
referrer_policy = other.referrer_policy;
http_body = other.http_body;
+ scroll_anchor_selector = other.scroll_anchor_selector;
+ scroll_anchor_offset = other.scroll_anchor_offset;
+ scroll_anchor_simhash = other.scroll_anchor_simhash;
children = other.children;
}
@@ -790,23 +1058,20 @@ int DecodePageStateForTesting(const std::string& encoded,
return DecodePageStateInternal(encoded, exploded);
}
-static void EncodePageStateInternal(const ExplodedPageState& exploded,
- int version,
- std::string* encoded) {
+void EncodePageState(const ExplodedPageState& exploded, std::string* encoded) {
SerializeObject obj;
- obj.version = version;
- WritePageState(exploded, &obj);
+ obj.version = kCurrentVersion;
+ WriteMojoPageState(exploded, &obj);
*encoded = obj.GetAsString();
}
-void EncodePageState(const ExplodedPageState& exploded, std::string* encoded) {
- EncodePageStateInternal(exploded, kCurrentVersion, encoded);
-}
-
-void EncodePageStateForTesting(const ExplodedPageState& exploded,
- int version,
- std::string* encoded) {
- EncodePageStateInternal(exploded, version, encoded);
+void LegacyEncodePageStateForTesting(const ExplodedPageState& exploded,
+ int version,
+ std::string* encoded) {
+ SerializeObject obj;
+ obj.version = version;
+ WritePageState(exploded, &obj);
+ *encoded = obj.GetAsString();
}
#if defined(OS_ANDROID)
@@ -835,7 +1100,7 @@ scoped_refptr<ResourceRequestBody> DecodeResourceRequestBody(const char* data,
std::string EncodeResourceRequestBody(
const ResourceRequestBody& resource_request_body) {
SerializeObject obj;
- obj.version = kCurrentVersion;
+ obj.version = 25;
WriteResourceRequestBody(resource_request_body, &obj);
// EncodeResourceRequestBody() is different from WriteResourceRequestBody()
// because it covers additional data (e.g.|contains_sensitive_info|) which
diff --git a/chromium/content/common/page_state_serialization.h b/chromium/content/common/page_state_serialization.h
index a04764fe451..943cc26e4af 100644
--- a/chromium/content/common/page_state_serialization.h
+++ b/chromium/content/common/page_state_serialization.h
@@ -24,6 +24,8 @@
namespace content {
+constexpr int kMaxScrollAnchorSelectorLength = 500;
+
struct CONTENT_EXPORT ExplodedHttpBody {
base::Optional<base::string16> http_content_type;
scoped_refptr<ResourceRequestBody> request_body;
@@ -48,6 +50,9 @@ struct CONTENT_EXPORT ExplodedFrameState {
double page_scale_factor;
blink::WebReferrerPolicy referrer_policy;
ExplodedHttpBody http_body;
+ base::Optional<base::string16> scroll_anchor_selector;
+ gfx::PointF scroll_anchor_offset;
+ uint64_t scroll_anchor_simhash;
std::vector<ExplodedFrameState> children;
ExplodedFrameState();
@@ -79,9 +84,10 @@ CONTENT_EXPORT int DecodePageStateForTesting(const std::string& encoded,
ExplodedPageState* exploded);
CONTENT_EXPORT void EncodePageState(const ExplodedPageState& exploded,
std::string* encoded);
-CONTENT_EXPORT void EncodePageStateForTesting(const ExplodedPageState& exploded,
- int version,
- std::string* encoded);
+CONTENT_EXPORT void LegacyEncodePageStateForTesting(
+ const ExplodedPageState& exploded,
+ int version,
+ std::string* encoded);
#if defined(OS_ANDROID)
CONTENT_EXPORT bool DecodePageStateWithDeviceScaleFactorForTesting(
diff --git a/chromium/content/common/page_state_serialization_unittest.cc b/chromium/content/common/page_state_serialization_unittest.cc
index 725d52caa1b..ab3dd5004c6 100644
--- a/chromium/content/common/page_state_serialization_unittest.cc
+++ b/chromium/content/common/page_state_serialization_unittest.cc
@@ -24,68 +24,79 @@ namespace {
//-----------------------------------------------------------------------------
template <typename T>
-void ExpectEquality(const T& a, const T& b) {
- EXPECT_EQ(a, b);
+void ExpectEquality(const T& expected, const T& actual) {
+ EXPECT_EQ(expected, actual);
}
template <typename T>
-void ExpectEquality(const std::vector<T>& a, const std::vector<T>& b) {
- EXPECT_EQ(a.size(), b.size());
- for (size_t i = 0; i < std::min(a.size(), b.size()); ++i)
- ExpectEquality(a[i], b[i]);
+void ExpectEquality(const std::vector<T>& expected,
+ const std::vector<T>& actual) {
+ EXPECT_EQ(expected.size(), actual.size());
+ for (size_t i = 0; i < std::min(expected.size(), actual.size()); ++i)
+ ExpectEquality(expected[i], actual[i]);
}
template <>
-void ExpectEquality(const ResourceRequestBody::Element& a,
- const ResourceRequestBody::Element& b) {
- EXPECT_EQ(a.type(), b.type());
- if (a.type() == ResourceRequestBody::Element::TYPE_BYTES &&
- b.type() == ResourceRequestBody::Element::TYPE_BYTES) {
- EXPECT_EQ(std::string(a.bytes(), a.length()),
- std::string(b.bytes(), b.length()));
+void ExpectEquality(const ResourceRequestBody::Element& expected,
+ const ResourceRequestBody::Element& actual) {
+ EXPECT_EQ(expected.type(), actual.type());
+ if (expected.type() == ResourceRequestBody::Element::TYPE_BYTES &&
+ actual.type() == ResourceRequestBody::Element::TYPE_BYTES) {
+ EXPECT_EQ(std::string(expected.bytes(), expected.length()),
+ std::string(actual.bytes(), actual.length()));
}
- EXPECT_EQ(a.path(), b.path());
- EXPECT_EQ(a.filesystem_url(), b.filesystem_url());
- EXPECT_EQ(a.offset(), b.offset());
- EXPECT_EQ(a.length(), b.length());
- EXPECT_EQ(a.expected_modification_time(), b.expected_modification_time());
- EXPECT_EQ(a.blob_uuid(), b.blob_uuid());
+ EXPECT_EQ(expected.path(), actual.path());
+ EXPECT_EQ(expected.filesystem_url(), actual.filesystem_url());
+ EXPECT_EQ(expected.offset(), actual.offset());
+ EXPECT_EQ(expected.length(), actual.length());
+ EXPECT_EQ(expected.expected_modification_time(),
+ actual.expected_modification_time());
+ EXPECT_EQ(expected.blob_uuid(), actual.blob_uuid());
}
template <>
-void ExpectEquality(const ExplodedHttpBody& a, const ExplodedHttpBody& b) {
- EXPECT_EQ(a.http_content_type, b.http_content_type);
- EXPECT_EQ(a.contains_passwords, b.contains_passwords);
- if (a.request_body == nullptr || b.request_body == nullptr) {
- EXPECT_EQ(nullptr, a.request_body);
- EXPECT_EQ(nullptr, b.request_body);
+void ExpectEquality(const ExplodedHttpBody& expected,
+ const ExplodedHttpBody& actual) {
+ EXPECT_EQ(expected.http_content_type, actual.http_content_type);
+ EXPECT_EQ(expected.contains_passwords, actual.contains_passwords);
+ if (expected.request_body == nullptr || actual.request_body == nullptr) {
+ EXPECT_EQ(nullptr, expected.request_body);
+ EXPECT_EQ(nullptr, actual.request_body);
} else {
- EXPECT_EQ(a.request_body->identifier(), b.request_body->identifier());
- ExpectEquality(*a.request_body->elements(), *b.request_body->elements());
+ EXPECT_EQ(expected.request_body->identifier(),
+ actual.request_body->identifier());
+ ExpectEquality(*expected.request_body->elements(),
+ *actual.request_body->elements());
}
}
template <>
-void ExpectEquality(const ExplodedFrameState& a, const ExplodedFrameState& b) {
- EXPECT_EQ(a.url_string, b.url_string);
- EXPECT_EQ(a.referrer, b.referrer);
- EXPECT_EQ(a.referrer_policy, b.referrer_policy);
- EXPECT_EQ(a.target, b.target);
- EXPECT_EQ(a.state_object, b.state_object);
- ExpectEquality(a.document_state, b.document_state);
- EXPECT_EQ(a.scroll_restoration_type, b.scroll_restoration_type);
- EXPECT_EQ(a.visual_viewport_scroll_offset, b.visual_viewport_scroll_offset);
- EXPECT_EQ(a.scroll_offset, b.scroll_offset);
- EXPECT_EQ(a.item_sequence_number, b.item_sequence_number);
- EXPECT_EQ(a.document_sequence_number, b.document_sequence_number);
- EXPECT_EQ(a.page_scale_factor, b.page_scale_factor);
- ExpectEquality(a.http_body, b.http_body);
- ExpectEquality(a.children, b.children);
-}
-
-void ExpectEquality(const ExplodedPageState& a, const ExplodedPageState& b) {
- ExpectEquality(a.referenced_files, b.referenced_files);
- ExpectEquality(a.top, b.top);
+void ExpectEquality(const ExplodedFrameState& expected,
+ const ExplodedFrameState& actual) {
+ EXPECT_EQ(expected.url_string, actual.url_string);
+ EXPECT_EQ(expected.referrer, actual.referrer);
+ EXPECT_EQ(expected.referrer_policy, actual.referrer_policy);
+ EXPECT_EQ(expected.target, actual.target);
+ EXPECT_EQ(expected.state_object, actual.state_object);
+ ExpectEquality(expected.document_state, actual.document_state);
+ EXPECT_EQ(expected.scroll_restoration_type, actual.scroll_restoration_type);
+ EXPECT_EQ(expected.visual_viewport_scroll_offset,
+ actual.visual_viewport_scroll_offset);
+ EXPECT_EQ(expected.scroll_offset, actual.scroll_offset);
+ EXPECT_EQ(expected.item_sequence_number, actual.item_sequence_number);
+ EXPECT_EQ(expected.document_sequence_number, actual.document_sequence_number);
+ EXPECT_EQ(expected.page_scale_factor, actual.page_scale_factor);
+ EXPECT_EQ(expected.scroll_anchor_selector, actual.scroll_anchor_selector);
+ EXPECT_EQ(expected.scroll_anchor_offset, actual.scroll_anchor_offset);
+ EXPECT_EQ(expected.scroll_anchor_simhash, actual.scroll_anchor_simhash);
+ ExpectEquality(expected.http_body, actual.http_body);
+ ExpectEquality(expected.children, actual.children);
+}
+
+void ExpectEquality(const ExplodedPageState& expected,
+ const ExplodedPageState& actual) {
+ ExpectEquality(expected.referenced_files, actual.referenced_files);
+ ExpectEquality(expected.top, actual.top);
}
//-----------------------------------------------------------------------------
@@ -112,6 +123,9 @@ class PageStateSerializationTest : public testing::Test {
frame_state->item_sequence_number = 1;
frame_state->document_sequence_number = 2;
frame_state->page_scale_factor = 2.0;
+ frame_state->scroll_anchor_selector = base::UTF8ToUTF16("#selector");
+ frame_state->scroll_anchor_offset = gfx::PointF(2.5, 3.5);
+ frame_state->scroll_anchor_simhash = 12345;
}
void PopulateHttpBody(
@@ -186,20 +200,14 @@ class PageStateSerializationTest : public testing::Test {
PopulateFrameStateForBackwardsCompatTest(&page_state->top, false);
}
- void TestBackwardsCompat(int version) {
- const char* suffix = "";
-
-#if defined(OS_ANDROID)
- // Unfortunately, the format of version 11 is different on Android, so we
- // need to use a special reference file.
- if (version == 11)
- suffix = "_android";
-#endif
-
+ void ReadBackwardsCompatPageState(const std::string& suffix,
+ int version,
+ ExplodedPageState* page_state) {
base::FilePath path;
PathService::Get(content::DIR_TEST_DATA, &path);
- path = path.AppendASCII("page_state").AppendASCII(
- base::StringPrintf("serialized_v%d%s.dat", version, suffix));
+ path = path.AppendASCII("page_state")
+ .AppendASCII(
+ base::StringPrintf("serialized_%s.dat", suffix.c_str()));
std::string file_contents;
if (!base::ReadFileToString(path, &file_contents)) {
@@ -207,30 +215,47 @@ class PageStateSerializationTest : public testing::Test {
return;
}
- std::string trimmed_contents;
- EXPECT_TRUE(base::RemoveChars(file_contents, "\r\n", &trimmed_contents));
+ std::string trimmed_file_contents;
+ EXPECT_TRUE(
+ base::RemoveChars(file_contents, "\r\n", &trimmed_file_contents));
- std::string encoded;
- EXPECT_TRUE(base::Base64Decode(trimmed_contents, &encoded));
+ std::string saved_encoded_state;
+ // PageState is encoded twice; once via EncodePageState, and again
+ // via Base64Decode, so we need to Base64Decode to get the original
+ // encoded PageState.
+ EXPECT_TRUE(
+ base::Base64Decode(trimmed_file_contents, &saved_encoded_state));
- ExplodedPageState output;
#if defined(OS_ANDROID)
// Because version 11 of the file format unfortunately bakes in the device
// scale factor on Android, perform this test by assuming a preset device
// scale factor, ignoring the device scale factor of the current device.
const float kPresetDeviceScaleFactor = 2.0f;
EXPECT_TRUE(DecodePageStateWithDeviceScaleFactorForTesting(
- encoded,
- kPresetDeviceScaleFactor,
- &output));
+ saved_encoded_state, kPresetDeviceScaleFactor, page_state));
#else
- EXPECT_EQ(version, DecodePageStateForTesting(encoded, &output));
+ EXPECT_EQ(version,
+ DecodePageStateForTesting(saved_encoded_state, page_state));
+#endif
+ }
+
+ void TestBackwardsCompat(int version) {
+ std::string suffix = base::StringPrintf("v%d", version);
+
+#if defined(OS_ANDROID)
+ // Unfortunately, the format of version 11 is different on Android, so we
+ // need to use a special reference file.
+ if (version == 11) {
+ suffix = std::string("v11_android");
+ }
#endif
- ExplodedPageState expected;
- PopulatePageStateForBackwardsCompatTest(&expected);
+ ExplodedPageState decoded_state;
+ ExplodedPageState expected_state;
+ PopulatePageStateForBackwardsCompatTest(&expected_state);
+ ReadBackwardsCompatPageState(suffix, version, &decoded_state);
- ExpectEquality(expected, output);
+ ExpectEquality(expected_state, decoded_state);
}
};
@@ -360,11 +385,65 @@ TEST_F(PageStateSerializationTest, BadMessagesTest2) {
EXPECT_FALSE(DecodePageState(s, &output));
}
+// Tests that LegacyEncodePageState, which uses the pre-mojo serialization
+// format, produces the exact same blob as it did when the test was written.
+// This ensures that the implementation is frozen, which is needed to correctly
+// test compatibility and migration.
+TEST_F(PageStateSerializationTest, LegacyEncodePageStateFrozen) {
+ ExplodedPageState actual_state;
+ PopulatePageStateForBackwardsCompatTest(&actual_state);
+
+ std::string actual_encoded_state;
+ LegacyEncodePageStateForTesting(actual_state, 25, &actual_encoded_state);
+
+ base::FilePath path;
+ PathService::Get(content::DIR_TEST_DATA, &path);
+ path = path.AppendASCII("page_state").AppendASCII("serialized_v25.dat");
+
+ std::string file_contents;
+ ASSERT_TRUE(base::ReadFileToString(path, &file_contents))
+ << "File not found: " << path.value();
+
+ std::string trimmed_file_contents;
+ EXPECT_TRUE(base::RemoveChars(file_contents, "\n", &trimmed_file_contents));
+
+ std::string expected_encoded_state;
+ EXPECT_TRUE(
+ base::Base64Decode(trimmed_file_contents, &expected_encoded_state));
+
+ ExpectEquality(actual_encoded_state, expected_encoded_state);
+}
+
+TEST_F(PageStateSerializationTest, ScrollAnchorSelectorLengthLimited) {
+ ExplodedPageState input;
+ PopulateFrameState(&input.top);
+
+ std::string excessive_length_string(kMaxScrollAnchorSelectorLength + 1, 'a');
+
+ input.top.scroll_anchor_selector = base::UTF8ToUTF16(excessive_length_string);
+
+ std::string encoded;
+ EncodePageState(input, &encoded);
+
+ ExplodedPageState output;
+ DecodePageState(encoded, &output);
+
+ // We should drop all the scroll anchor data if the length is over the limit.
+ EXPECT_FALSE(output.top.scroll_anchor_selector);
+ EXPECT_EQ(output.top.scroll_anchor_offset, gfx::PointF());
+ EXPECT_EQ(output.top.scroll_anchor_simhash, 0ul);
+}
+
// Change to #if 1 to enable this code. Run this test to generate data, based on
// the current serialization format, for the BackwardsCompat_vXX tests. This
// will generate an expected.dat in the temp directory, which should be moved
// //content/test/data/page_state/serialization_vXX.dat. A corresponding test
-// case for that version should also then be added below.
+// case for that version should also then be added below. You need to add such
+// a test for any addition/change to the schema of serialized page state.
+// If you're adding a field whose type is defined externally of
+// page_state.mojom, add an backwards compat test for that field specifically
+// by dumping a state object with only that field populated. See, e.g.,
+// BackwardsCompat_UrlString as an example.
//
// IMPORTANT: this code dumps the serialization as the *current* version, so if
// generating a backwards compat test for v23, the tree must be synced to a
@@ -451,5 +530,148 @@ TEST_F(PageStateSerializationTest, BackwardsCompat_v24) {
TestBackwardsCompat(24);
}
+TEST_F(PageStateSerializationTest, BackwardsCompat_v25) {
+ TestBackwardsCompat(25);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_v26) {
+ TestBackwardsCompat(26);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_v27) {
+ TestBackwardsCompat(27);
+}
+
+// Add your new backwards compat test for future versions *above* this
+// comment block; field-specific tests go *below* this comment block.
+// Any field additions require a new version and backcompat test; only fields
+// with external type definitions require their own dedicated test.
+// See DumpExpectedPageStateForBackwardsCompat for more details.
+// If any of the below tests fail, you likely made a backwards incompatible
+// change to a definition that page_state.mojom relies on. Ideally you should
+// find a way to avoid making this change; if that's not possible, contact the
+// page state serialization owners to figure out a resolution.
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_ReferencedFiles) {
+ ExplodedPageState state;
+ state.referenced_files.push_back(base::UTF8ToUTF16("file.txt"));
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("referenced_files", 26, &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_UrlString) {
+ ExplodedPageState state;
+ state.top.url_string = base::ASCIIToUTF16("http://chromium.org");
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("url_string", 26, &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_Referrer) {
+ ExplodedPageState state;
+ state.top.referrer = base::ASCIIToUTF16("http://www.google.com");
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("referrer", 26, &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_Target) {
+ ExplodedPageState state;
+ state.top.target = base::ASCIIToUTF16("http://www.google.com");
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("target", 26, &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_StateObject) {
+ ExplodedPageState state;
+ state.top.state_object = base::ASCIIToUTF16("state");
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("state_object", 26, &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_DocumentState) {
+ ExplodedPageState state;
+ state.top.document_state.push_back(base::ASCIIToUTF16(
+ "\n\r?% WebKit serialized form state version 8 \n\r=&"));
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("document_state", 26, &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_ScrollRestorationType) {
+ ExplodedPageState state;
+ state.top.scroll_restoration_type = blink::kWebHistoryScrollRestorationManual;
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("scroll_restoration_type", 26, &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_VisualViewportScrollOffset) {
+ ExplodedPageState state;
+ state.top.visual_viewport_scroll_offset = gfx::PointF(42.2, -42.2);
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("visual_viewport_scroll_offset", 26,
+ &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_ScrollOffset) {
+ ExplodedPageState state;
+ state.top.scroll_offset = gfx::Point(1, -1);
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("scroll_offset", 26, &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_ReferrerPolicy) {
+ ExplodedPageState state;
+ state.top.referrer_policy = blink::kWebReferrerPolicyAlways;
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("referrer_policy", 26, &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+TEST_F(PageStateSerializationTest, BackwardsCompat_HttpBody) {
+ ExplodedPageState state;
+ ExplodedHttpBody& http_body = state.top.http_body;
+
+ http_body.request_body = new ResourceRequestBody();
+ http_body.request_body->set_identifier(12345);
+ http_body.contains_passwords = false;
+ http_body.http_content_type = base::UTF8ToUTF16("text/foo");
+
+ std::string test_body("foo");
+ http_body.request_body->AppendBytes(test_body.data(), test_body.size());
+
+ http_body.request_body->AppendBlob("some_uuid");
+
+ base::FilePath path(FILE_PATH_LITERAL("file.txt"));
+ http_body.request_body->AppendFileRange(base::FilePath(path), 100, 1024,
+ base::Time::FromDoubleT(9999.0));
+
+ http_body.request_body->AppendFileSystemFileRange(
+ GURL("file://some_file.txt"), 100, 1024, base::Time::FromDoubleT(9999.0));
+
+ ExplodedPageState saved_state;
+ ReadBackwardsCompatPageState("http_body", 26, &saved_state);
+ ExpectEquality(state, saved_state);
+}
+
+// Add new backwards compat field-specific tests here. See comment above for
+// where to put backwards compat version tests.
+
} // namespace
} // namespace content
diff --git a/chromium/content/common/quarantine/quarantine_linux.cc b/chromium/content/common/quarantine/quarantine_linux.cc
index af207836d75..00bc669e21a 100644
--- a/chromium/content/common/quarantine/quarantine_linux.cc
+++ b/chromium/content/common/quarantine/quarantine_linux.cc
@@ -27,7 +27,7 @@ bool SetExtendedFileAttribute(const char* path,
const char* value,
size_t value_size,
int flags) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
int result = setxattr(path, name, value, value_size, flags);
if (result) {
DPLOG(ERROR) << "Could not set extended attribute " << name << " on file "
@@ -38,7 +38,7 @@ bool SetExtendedFileAttribute(const char* path,
}
std::string GetExtendedFileAttribute(const char* path, const char* name) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
ssize_t len = getxattr(path, name, nullptr, 0);
if (len <= 0)
return std::string();
diff --git a/chromium/content/common/quarantine/quarantine_linux_unittest.cc b/chromium/content/common/quarantine/quarantine_linux_unittest.cc
index 612d93f0d89..0f87e468962 100644
--- a/chromium/content/common/quarantine/quarantine_linux_unittest.cc
+++ b/chromium/content/common/quarantine/quarantine_linux_unittest.cc
@@ -60,7 +60,7 @@ class QuarantineLinuxTest : public testing::Test {
}
void GetExtendedAttributeNames(vector<string>* attr_names) const {
- ssize_t len = listxattr(test_file().value().c_str(), NULL, 0);
+ ssize_t len = listxattr(test_file().value().c_str(), nullptr, 0);
if (len <= static_cast<ssize_t>(0))
return;
char* buffer = new char[len];
diff --git a/chromium/content/common/quarantine/quarantine_mac.mm b/chromium/content/common/quarantine/quarantine_mac.mm
index 8dff600688f..2af1db03214 100644
--- a/chromium/content/common/quarantine/quarantine_mac.mm
+++ b/chromium/content/common/quarantine/quarantine_mac.mm
@@ -163,7 +163,7 @@ namespace {
bool AddOriginMetadataToFile(const base::FilePath& file,
const GURL& source,
const GURL& referrer) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
// There's no declaration for MDItemSetAttribute in any known public SDK.
// It exists in the 10.4 and 10.5 runtimes. To play it safe, do the lookup
// at runtime instead of declaring it ourselves and linking against what's
@@ -233,7 +233,7 @@ bool AddOriginMetadataToFile(const base::FilePath& file,
bool AddQuarantineMetadataToFile(const base::FilePath& file,
const GURL& source,
const GURL& referrer) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
base::scoped_nsobject<NSMutableDictionary> properties;
bool success = false;
if (@available(macos 10.10, *)) {
@@ -307,7 +307,7 @@ QuarantineFileResult QuarantineFile(const base::FilePath& file,
bool IsFileQuarantined(const base::FilePath& file,
const GURL& expected_source_url,
const GURL& referrer_url) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
if (!base::PathExists(file))
return false;
diff --git a/chromium/content/common/quarantine/quarantine_win.cc b/chromium/content/common/quarantine/quarantine_win.cc
index 3feb1966af8..8c3ddee8d9d 100644
--- a/chromium/content/common/quarantine/quarantine_win.cc
+++ b/chromium/content/common/quarantine/quarantine_win.cc
@@ -5,6 +5,7 @@
#include "content/public/common/quarantine.h"
#include <windows.h>
+#include <wrl/client.h>
#include <cguid.h>
#include <objbase.h>
@@ -25,7 +26,6 @@
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
-#include "base/win/scoped_comptr.h"
#include "base/win/scoped_handle.h"
#include "url/gurl.h"
@@ -196,7 +196,7 @@ bool InvokeAttachmentServices(const base::FilePath& full_path,
const std::string& referrer_url,
const GUID& client_guid,
HRESULT* save_result) {
- base::win::ScopedComPtr<IAttachmentExecute> attachment_services;
+ Microsoft::WRL::ComPtr<IAttachmentExecute> attachment_services;
HRESULT hr = ::CoCreateInstance(CLSID_AttachmentServices, nullptr, CLSCTX_ALL,
IID_PPV_ARGS(&attachment_services));
*save_result = S_OK;
@@ -300,7 +300,7 @@ QuarantineFileResult QuarantineFile(const base::FilePath& file,
const GURL& source_url,
const GURL& referrer_url,
const std::string& client_guid) {
- base::ThreadRestrictions::AssertIOAllowed();
+ base::AssertBlockingAllowed();
int64_t file_size = 0;
if (!base::PathExists(file) || !base::GetFileSize(file, &file_size))
diff --git a/chromium/content/common/quota_dispatcher_host.mojom b/chromium/content/common/quota_dispatcher_host.mojom
new file mode 100644
index 00000000000..385860d2abb
--- /dev/null
+++ b/chromium/content/common/quota_dispatcher_host.mojom
@@ -0,0 +1,35 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+import "storage/common/quota/quota_types.mojom";
+import "url/mojo/url.mojom";
+
+// API for the renderer process to request quota information from the browser
+// process.
+// TODO(sashab): Put callback parameters in an optional struct, only set on
+// success.
+// TODO(sashab): Remove origin_url and render_frame_id, moving this interface to
+// be per-execution context instead of per-process.
+// TODO(sashab): Change origin_url to a url.mojom.Origin instead.
+// TODO(sashab): Move this API and the necessary types to WebKit/common/.
+interface QuotaDispatcherHost {
+ // Renderer process queries storage usage and quota from the browser process.
+ QueryStorageUsageAndQuota(url.mojom.Url origin_url,
+ storage.mojom.StorageType storage_type) =>
+ (storage.mojom.QuotaStatusCode error,
+ int64 current_usage,
+ int64 current_quota);
+
+ // Renderer process requests storage quota from the browser process.
+ // render_frame_id is used for showing the permissions UI.
+ RequestStorageQuota(int64 render_frame_id,
+ url.mojom.Url origin_url,
+ storage.mojom.StorageType storage_type,
+ uint64 requested_size) =>
+ (storage.mojom.QuotaStatusCode error,
+ int64 current_usage,
+ int64 granted_quota);
+};
diff --git a/chromium/content/common/quota_messages.h b/chromium/content/common/quota_messages.h
deleted file mode 100644
index 5eec9b39f9a..00000000000
--- a/chromium/content/common/quota_messages.h
+++ /dev/null
@@ -1,55 +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_COMMON_QUOTA_MESSAGES_H_
-#define CONTENT_COMMON_QUOTA_MESSAGES_H_
-
-#include <stdint.h>
-
-#include "content/public/common/storage_quota_params.h"
-#include "ipc/ipc_message_macros.h"
-#include "storage/common/quota/quota_types.h"
-#include "url/gurl.h"
-
-#define IPC_MESSAGE_START QuotaMsgStart
-
-IPC_ENUM_TRAITS_MAX_VALUE(storage::StorageType, storage::kStorageTypeLast)
-IPC_ENUM_TRAITS_MAX_VALUE(storage::QuotaStatusCode, storage::kQuotaStatusLast)
-
-IPC_STRUCT_TRAITS_BEGIN(content::StorageQuotaParams)
- IPC_STRUCT_TRAITS_MEMBER(render_frame_id)
- IPC_STRUCT_TRAITS_MEMBER(request_id)
- IPC_STRUCT_TRAITS_MEMBER(origin_url)
- IPC_STRUCT_TRAITS_MEMBER(storage_type)
- IPC_STRUCT_TRAITS_MEMBER(requested_size)
- IPC_STRUCT_TRAITS_MEMBER(user_gesture)
-IPC_STRUCT_TRAITS_END()
-
-// Quota messages sent from the browser to the child process.
-
-IPC_MESSAGE_CONTROL3(QuotaMsg_DidGrantStorageQuota,
- int /* request_id */,
- int64_t /* current_usage */,
- int64_t /* granted_quota */)
-
-IPC_MESSAGE_CONTROL3(QuotaMsg_DidQueryStorageUsageAndQuota,
- int /* request_id */,
- int64_t /* current_usage */,
- int64_t /* current_quota */)
-
-IPC_MESSAGE_CONTROL2(QuotaMsg_DidFail,
- int /* request_id */,
- storage::QuotaStatusCode /* error */)
-
-// Quota messages sent from the child process to the browser.
-
-IPC_MESSAGE_CONTROL3(QuotaHostMsg_QueryStorageUsageAndQuota,
- int /* request_id */,
- GURL /* origin_url */,
- storage::StorageType /* type */)
-
-IPC_MESSAGE_CONTROL1(QuotaHostMsg_RequestStorageQuota,
- content::StorageQuotaParams)
-
-#endif // CONTENT_COMMON_QUOTA_MESSAGES_H_
diff --git a/chromium/content/common/render_frame_message_filter.mojom b/chromium/content/common/render_frame_message_filter.mojom
index 5bbf05eaf5f..0a9f1588c6a 100644
--- a/chromium/content/common/render_frame_message_filter.mojom
+++ b/chromium/content/common/render_frame_message_filter.mojom
@@ -7,10 +7,13 @@ module content.mojom;
import "url/mojo/url.mojom";
interface RenderFrameMessageFilter {
- // Sets a cookie. The cookie is set asynchronously, but will be available to
- // any subsequent GetCookies() request.
+ // Sets a cookie. Returns after the cookie write request has been scheduled on
+ // the IO thread (the database is modified asynchronously). This ensures that
+ // network requests issued after the cookie setter call are processed after
+ // the cookie change is committed, and therefore see the change.
+ [Sync]
SetCookie(int32 render_frame_id, url.mojom.Url url,
- url.mojom.Url first_party_for_cookies, string cookie);
+ url.mojom.Url first_party_for_cookies, string cookie) => ();
// Used to get cookies for the given URL. This may block waiting for a
// previous SetCookie message to be processed.
diff --git a/chromium/content/common/render_message_filter.mojom b/chromium/content/common/render_message_filter.mojom
index b61002b7377..c51b990a2ed 100644
--- a/chromium/content/common/render_message_filter.mojom
+++ b/chromium/content/common/render_message_filter.mojom
@@ -7,6 +7,11 @@ module content.mojom;
import "content/common/input/input_handler.mojom";
import "content/common/native_types.mojom";
import "content/common/widget.mojom";
+import "mojo/common/thread_priority.mojom";
+import "mojo/common/string16.mojom";
+import "mojo/common/time.mojom";
+import "url/mojo/origin.mojom";
+import "url/mojo/url.mojom";
interface RenderMessageFilter {
// Synchronously generates a new routing ID for the caller.
@@ -20,4 +25,29 @@ interface RenderMessageFilter {
// 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.common.mojom.Time expected_response_time,
+ array<uint8> data);
+
+ // Requests that the browser cache |data| for the specified CacheStorage entry.
+ DidGenerateCacheableMetadataInCacheStorage(
+ url.mojom.Url url, mojo.common.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);
+
+ // Asks the browser to change the priority of thread.
+ // (Linux only, NOP on other platforms.)
+ SetThreadPriority(int32 platform_thread_id,
+ mojo.common.mojom.ThreadPriority thread_priority);
+
+ // Request that the browser load a font into shared memory for us.
+ // TODO(https://crbug.com/676224). Only used for MacOS.
+ [Sync] LoadFont(mojo.common.mojom.String16 font_name, float font_point_size)
+ => (uint32 buffer_size, handle<shared_buffer>? font_data, uint32 font_id);
};
diff --git a/chromium/content/common/render_process_messages.h b/chromium/content/common/render_process_messages.h
deleted file mode 100644
index e30da603ea1..00000000000
--- a/chromium/content/common/render_process_messages.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_RENDER_PROCESS_MESSAGES_H_
-#define CONTENT_COMMON_RENDER_PROCESS_MESSAGES_H_
-
-// Common IPC messages used for render processes.
-
-#include <stdint.h>
-
-#include <string>
-
-#include "base/memory/shared_memory.h"
-#include "build/build_config.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_message_utils.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-
-#if defined(OS_MACOSX)
-#include "content/common/mac/font_descriptor.h"
-#endif
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
-
-#define IPC_MESSAGE_START RenderProcessMsgStart
-
-#if defined(OS_MACOSX)
-IPC_STRUCT_TRAITS_BEGIN(FontDescriptor)
- IPC_STRUCT_TRAITS_MEMBER(font_name)
- IPC_STRUCT_TRAITS_MEMBER(font_point_size)
-IPC_STRUCT_TRAITS_END()
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Messages sent from the browser to the render process.
-
-////////////////////////////////////////////////////////////////////////////////
-// Messages sent from the render process to the browser.
-
-// Message sent from the renderer to the browser to request that the browser
-// cache |data| associated with |url| and |expected_response_time|.
-IPC_MESSAGE_CONTROL3(RenderProcessHostMsg_DidGenerateCacheableMetadata,
- GURL /* url */,
- base::Time /* expected_response_time */,
- std::vector<char> /* data */)
-
-// Message sent from the renderer to the browser to request that the browser
-// cache |data| for the specified CacheStorage entry.
-IPC_MESSAGE_CONTROL5(
- RenderProcessHostMsg_DidGenerateCacheableMetadataInCacheStorage,
- GURL /* url */,
- base::Time /* expected_response_time */,
- std::vector<char> /* data */,
- url::Origin /* cache_storage_origin*/,
- std::string /* cache_storage_cache_name */)
-
-// Notify the browser that this render process can or can't be suddenly
-// terminated.
-IPC_MESSAGE_CONTROL1(RenderProcessHostMsg_SuddenTerminationChanged,
- bool /* enabled */)
-
-#if defined(OS_MACOSX)
-// Request that the browser load a font into shared memory for us.
-IPC_SYNC_MESSAGE_CONTROL1_3(RenderProcessHostMsg_LoadFont,
- FontDescriptor /* font to load */,
- uint32_t /* buffer size */,
- base::SharedMemoryHandle /* font data */,
- uint32_t /* font id */)
-#endif
-
-#endif // CONTENT_COMMON_RENDER_PROCESS_MESSAGES_H_
diff --git a/chromium/content/common/renderer.mojom b/chromium/content/common/renderer.mojom
index 91327fc65fc..ad8c015e595 100644
--- a/chromium/content/common/renderer.mojom
+++ b/chromium/content/common/renderer.mojom
@@ -9,6 +9,7 @@ import "content/common/service_worker/embedded_worker.mojom";
import "ipc/constants.mojom";
import "mojo/common/time.mojom";
import "mojo/common/unguessable_token.mojom";
+import "services/service_manager/public/interfaces/interface_provider.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
import "ui/gfx/mojo/icc_profile.mojom";
@@ -22,9 +23,17 @@ struct CreateViewParams {
// The ID of the view to be created.
int32 view_id = IPC.mojom.kRoutingIdNone;
- // The ID of the main frame hosted in the view.
+ // The ID of the main frame hosted in the view, or None if creating a view to
+ // host a main frame proxy.
int32 main_frame_routing_id = IPC.mojom.kRoutingIdNone;
+ // The InterfaceProvider through which the main RenderFrame can access
+ // services exposed by its RenderFrameHost.
+ //
+ // This is null precisely when |main_frame_routing_id| is MSG_ROUTING_NONE,
+ // that is, when creating a RenderView for a remote main frame.
+ service_manager.mojom.InterfaceProvider? main_frame_interface_provider;
+
// The ID of the widget for the main frame.
int32 main_frame_widget_routing_id = IPC.mojom.kRoutingIdNone;
@@ -114,6 +123,10 @@ struct CreateFrameParams {
// parent frame, in front of any other children.
int32 previous_sibling_routing_id;
+ // The InterfaceProvider through which the RenderFrame can access services
+ // exposed by its RenderFrameHost.
+ service_manager.mojom.InterfaceProvider interface_provider;
+
// When the new frame has a parent, |replication_state| holds the new frame's
// properties replicated from the process rendering the parent frame, such as
// the new frame's sandbox flags.
@@ -187,7 +200,7 @@ interface Renderer {
// The downstream throughput is computed in kilobits per second. If an
// estimate of the HTTP or transport RTT is unavailable, it will be set to
// net::nqe::internal::InvalidRTT(). If the throughput estimate is
- // unavailable, it will be set to net::nqe::internal::kInvalidThroughput.
+ // unavailable, it will be set to net::nqe::internal::INVALID_RTT_THROUGHPUT.
OnNetworkQualityChanged(EffectiveConnectionType effective_connection_type,
mojo.common.mojom.TimeDelta http_rtt,
mojo.common.mojom.TimeDelta transport_rtt,
@@ -208,4 +221,12 @@ interface Renderer {
// Tells the renderer to empty its plugin list cache, optional reloading
// pages containing plugins.
PurgePluginListCache(bool reload_pages);
+
+
+ // Tells the renderer process to enter or leave background mode.
+ // TODO(crbug:676224) Make this conditional on IPC_MESSAGE_LOG_ENABLED.
+ SetProcessBackgrounded(bool background);
+
+ // Tells the renderer process to purge and suspend.
+ ProcessPurgeAndSuspend();
};
diff --git a/chromium/content/common/renderer_host.mojom b/chromium/content/common/renderer_host.mojom
index 8269deaed43..d7d2c1bf08e 100644
--- a/chromium/content/common/renderer_host.mojom
+++ b/chromium/content/common/renderer_host.mojom
@@ -11,4 +11,18 @@ import "content/public/common/url_loader_factory.mojom";
interface RendererHost {
// Requests a URLLoaderFactory for the blob scheme.
GetBlobURLLoaderFactory(URLLoaderFactory& loader);
+
+ // Request a histogram from the browser. The browser will send the histogram
+ // data only if it has been passed the command line flag
+ // switches::kDomAutomationController.
+ [Sync]
+ GetBrowserHistogram(string name) => (string histogram_json);
+
+ // Notify the browser that this render process can or can't be suddenly
+ // terminated.
+ SuddenTerminationChanged(bool enabled);
+
+ // Request a child_control.Shutdown message to be sent to the renderer. This
+ // may not initiate a shutdown sequence in some cases.
+ ShutdownRequest();
};
diff --git a/chromium/content/common/resize_params.cc b/chromium/content/common/resize_params.cc
index 24d499aba0b..8d304f7ef60 100644
--- a/chromium/content/common/resize_params.cc
+++ b/chromium/content/common/resize_params.cc
@@ -8,6 +8,7 @@ namespace content {
ResizeParams::ResizeParams()
: browser_controls_shrink_blink_size(false),
+ scroll_focused_node_into_view(false),
top_controls_height(0.f),
bottom_controls_height(0.f),
is_fullscreen_granted(false),
diff --git a/chromium/content/common/resize_params.h b/chromium/content/common/resize_params.h
index 60ae351dd76..6092394141d 100644
--- a/chromium/content/common/resize_params.h
+++ b/chromium/content/common/resize_params.h
@@ -32,6 +32,10 @@ struct CONTENT_EXPORT ResizeParams {
// URL-bar (always false on platforms where URL-bar hiding isn't supported).
bool browser_controls_shrink_blink_size;
+ // Whether or not the focused node should be scrolled into view after the
+ // resize.
+ bool scroll_focused_node_into_view;
+
// The height of the top controls (always 0 on platforms where URL-bar hiding
// isn't supported).
float top_controls_height;
diff --git a/chromium/content/common/resource_messages.cc b/chromium/content/common/resource_messages.cc
index 8d2fadbdd22..b97fa77118a 100644
--- a/chromium/content/common/resource_messages.cc
+++ b/chromium/content/common/resource_messages.cc
@@ -4,6 +4,10 @@
#include "content/common/resource_messages.h"
+#include "base/files/file.h"
+#include "base/files/platform_file.h"
+#include "ipc/ipc_mojo_param_traits.h"
+#include "ipc/ipc_platform_file.h"
#include "net/base/load_timing_info.h"
#include "net/http/http_response_headers.h"
@@ -12,7 +16,7 @@ namespace IPC {
void ParamTraits<scoped_refptr<net::HttpResponseHeaders>>::Write(
base::Pickle* m,
const param_type& p) {
- WriteParam(m, p.get() != NULL);
+ WriteParam(m, p.get() != nullptr);
if (p.get()) {
// Do not disclose Set-Cookie headers over IPC.
p->Persist(m, net::HttpResponseHeaders::PERSIST_SANS_COOKIES);
@@ -53,8 +57,7 @@ bool ReadCert(const base::Pickle* m,
return false;
if (!has_object)
return true;
- *cert = net::X509Certificate::CreateFromPickle(
- iter, net::X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3);
+ *cert = net::X509Certificate::CreateFromPickle(iter);
return !!cert->get();
}
@@ -80,8 +83,7 @@ void ParamTraits<net::SSLInfo>::Write(base::Pickle* m, const param_type& p) {
WriteParam(m, p.public_key_hashes);
WriteParam(m, p.pinning_failure_log);
WriteParam(m, p.signed_certificate_timestamps);
- WriteParam(m, p.ct_compliance_details_available);
- WriteParam(m, p.ct_cert_policy_compliance);
+ WriteParam(m, p.ct_policy_compliance);
WriteParam(m, p.ocsp_result.response_status);
WriteParam(m, p.ocsp_result.revocation_status);
}
@@ -110,8 +112,7 @@ bool ParamTraits<net::SSLInfo>::Read(const base::Pickle* m,
ReadParam(m, iter, &r->public_key_hashes) &&
ReadParam(m, iter, &r->pinning_failure_log) &&
ReadParam(m, iter, &r->signed_certificate_timestamps) &&
- ReadParam(m, iter, &r->ct_compliance_details_available) &&
- ReadParam(m, iter, &r->ct_cert_policy_compliance) &&
+ ReadParam(m, iter, &r->ct_policy_compliance) &&
ReadParam(m, iter, &r->ocsp_result.response_status) &&
ReadParam(m, iter, &r->ocsp_result.revocation_status);
}
@@ -154,6 +155,16 @@ void ParamTraits<storage::DataElement>::Write(base::Pickle* m,
WriteParam(m, p.expected_modification_time());
break;
}
+ case storage::DataElement::TYPE_RAW_FILE: {
+ WriteParam(
+ m, IPC::GetPlatformFileForTransit(p.file().GetPlatformFile(),
+ false /* close_source_handle */));
+ WriteParam(m, p.path());
+ WriteParam(m, p.offset());
+ WriteParam(m, p.length());
+ WriteParam(m, p.expected_modification_time());
+ break;
+ }
case storage::DataElement::TYPE_FILE_FILESYSTEM: {
WriteParam(m, p.filesystem_url());
WriteParam(m, p.offset());
@@ -171,6 +182,14 @@ void ParamTraits<storage::DataElement>::Write(base::Pickle* m,
NOTREACHED() << "Can't be sent by IPC.";
break;
}
+ case storage::DataElement::TYPE_DATA_PIPE: {
+ WriteParam(m,
+ const_cast<network::mojom::DataPipeGetterPtr&>(p.data_pipe())
+ .PassInterface()
+ .PassHandle()
+ .release());
+ break;
+ }
case storage::DataElement::TYPE_UNKNOWN: {
NOTREACHED();
break;
@@ -216,6 +235,27 @@ bool ParamTraits<storage::DataElement>::Read(const base::Pickle* m,
expected_modification_time);
return true;
}
+ case storage::DataElement::TYPE_RAW_FILE: {
+ IPC::PlatformFileForTransit platform_file_for_transit;
+ if (!ReadParam(m, iter, &platform_file_for_transit))
+ return false;
+ base::File file = PlatformFileForTransitToFile(platform_file_for_transit);
+ base::FilePath file_path;
+ if (!ReadParam(m, iter, &file_path))
+ return false;
+ uint64_t offset;
+ if (!ReadParam(m, iter, &offset))
+ return false;
+ uint64_t length;
+ if (!ReadParam(m, iter, &length))
+ return false;
+ base::Time expected_modification_time;
+ if (!ReadParam(m, iter, &expected_modification_time))
+ return false;
+ r->SetToFileRange(std::move(file), file_path, offset, length,
+ expected_modification_time);
+ return true;
+ }
case storage::DataElement::TYPE_FILE_FILESYSTEM: {
GURL file_system_url;
uint64_t offset, length;
@@ -248,6 +288,16 @@ bool ParamTraits<storage::DataElement>::Read(const base::Pickle* m,
NOTREACHED() << "Can't be sent by IPC.";
return false;
}
+ case storage::DataElement::TYPE_DATA_PIPE: {
+ network::mojom::DataPipeGetterPtr data_pipe_getter;
+ mojo::MessagePipeHandle message_pipe;
+ if (!ReadParam(m, iter, &message_pipe))
+ return false;
+ data_pipe_getter.Bind(network::mojom::DataPipeGetterPtrInfo(
+ mojo::ScopedMessagePipeHandle(message_pipe), 0u));
+ r->SetToDataPipe(std::move(data_pipe_getter));
+ return true;
+ }
case storage::DataElement::TYPE_UNKNOWN: {
NOTREACHED();
return false;
@@ -264,7 +314,7 @@ void ParamTraits<storage::DataElement>::Log(const param_type& p,
void ParamTraits<scoped_refptr<content::ResourceDevToolsInfo>>::Write(
base::Pickle* m,
const param_type& p) {
- WriteParam(m, p.get() != NULL);
+ WriteParam(m, p.get() != nullptr);
if (p.get()) {
WriteParam(m, p->http_status_code);
WriteParam(m, p->http_status_text);
@@ -401,7 +451,7 @@ void ParamTraits<net::LoadTimingInfo>::Log(const param_type& p,
void ParamTraits<scoped_refptr<content::ResourceRequestBody>>::Write(
base::Pickle* m,
const param_type& p) {
- WriteParam(m, p.get() != NULL);
+ WriteParam(m, p.get() != nullptr);
if (p.get()) {
WriteParam(m, *p->elements());
WriteParam(m, p->identifier());
@@ -443,7 +493,7 @@ void ParamTraits<scoped_refptr<content::ResourceRequestBody>>::Log(
void ParamTraits<scoped_refptr<net::ct::SignedCertificateTimestamp>>::Write(
base::Pickle* m,
const param_type& p) {
- WriteParam(m, p.get() != NULL);
+ WriteParam(m, p.get() != nullptr);
if (p.get())
p->Persist(m);
}
diff --git a/chromium/content/common/resource_messages.h b/chromium/content/common/resource_messages.h
index f68a8b6c3e5..3b374968498 100644
--- a/chromium/content/common/resource_messages.h
+++ b/chromium/content/common/resource_messages.h
@@ -18,7 +18,6 @@
#include "content/public/common/common_param_traits.h"
#include "content/public/common/resource_request.h"
#include "content/public/common/resource_request_body.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "content/public/common/resource_response.h"
#include "content/public/common/service_worker_modes.h"
#include "ipc/ipc_message_macros.h"
@@ -30,6 +29,9 @@
#include "net/ssl/ssl_info.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/cors_error_status.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
+#include "services/network/public/interfaces/fetch_api.mojom.h"
#include "third_party/WebKit/public/platform/WebMixedContentContextType.h"
#ifndef INTERNAL_CONTENT_COMMON_RESOURCE_MESSAGES_H_
@@ -141,18 +143,18 @@ IPC_ENUM_TRAITS_MAX_VALUE(net::TokenBindingParam, net::TB_PARAM_ECDSAP256)
IPC_ENUM_TRAITS_MAX_VALUE(net::SSLInfo::HandshakeType,
net::SSLInfo::HANDSHAKE_FULL)
IPC_ENUM_TRAITS_MAX_VALUE(
- net::ct::CertPolicyCompliance,
- net::ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY)
+ net::ct::CTPolicyCompliance,
+ net::ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE)
IPC_ENUM_TRAITS_MAX_VALUE(net::OCSPVerifyResult::ResponseStatus,
net::OCSPVerifyResult::PARSE_RESPONSE_DATA_ERROR)
IPC_ENUM_TRAITS_MAX_VALUE(net::OCSPRevocationStatus,
net::OCSPRevocationStatus::UNKNOWN)
-IPC_ENUM_TRAITS_MAX_VALUE(content::FetchRequestMode,
- content::FETCH_REQUEST_MODE_LAST)
+IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::FetchRequestMode,
+ network::mojom::FetchRequestMode::kLast)
-IPC_ENUM_TRAITS_MAX_VALUE(content::FetchCredentialsMode,
- content::FETCH_CREDENTIALS_MODE_LAST)
+IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::FetchCredentialsMode,
+ network::mojom::FetchCredentialsMode::kLast)
IPC_ENUM_TRAITS_MAX_VALUE(content::FetchRedirectMode,
content::FetchRedirectMode::LAST)
@@ -252,7 +254,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::ResourceRequest)
IPC_STRUCT_TRAITS_MEMBER(visibility_state)
IPC_STRUCT_TRAITS_MEMBER(headers)
IPC_STRUCT_TRAITS_MEMBER(load_flags)
- IPC_STRUCT_TRAITS_MEMBER(origin_pid)
+ IPC_STRUCT_TRAITS_MEMBER(plugin_child_id)
IPC_STRUCT_TRAITS_MEMBER(resource_type)
IPC_STRUCT_TRAITS_MEMBER(priority)
IPC_STRUCT_TRAITS_MEMBER(request_context)
@@ -290,13 +292,23 @@ IPC_STRUCT_TRAITS_BEGIN(content::ResourceRequest)
IPC_STRUCT_TRAITS_END()
// Parameters for a ResourceMsg_RequestComplete
-IPC_STRUCT_TRAITS_BEGIN(content::ResourceRequestCompletionStatus)
+IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::CORSError,
+ network::mojom::CORSError::kLast)
+
+IPC_STRUCT_TRAITS_BEGIN(network::CORSErrorStatus)
+ IPC_STRUCT_TRAITS_MEMBER(cors_error)
+ IPC_STRUCT_TRAITS_MEMBER(related_response_headers)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(network::URLLoaderCompletionStatus)
IPC_STRUCT_TRAITS_MEMBER(error_code)
IPC_STRUCT_TRAITS_MEMBER(exists_in_cache)
IPC_STRUCT_TRAITS_MEMBER(completion_time)
IPC_STRUCT_TRAITS_MEMBER(encoded_data_length)
IPC_STRUCT_TRAITS_MEMBER(encoded_body_length)
IPC_STRUCT_TRAITS_MEMBER(decoded_body_length)
+ IPC_STRUCT_TRAITS_MEMBER(cors_error_status)
+ IPC_STRUCT_TRAITS_MEMBER(ssl_info)
IPC_STRUCT_TRAITS_END()
// Resource messages sent from the browser to the renderer.
@@ -332,15 +344,10 @@ IPC_MESSAGE_CONTROL3(ResourceMsg_ReceivedRedirect,
//
// NOTE: The shared memory handle should already be mapped into the process
// that receives this message.
-//
-// TODO(darin): The |renderer_pid| parameter is just a temporary parameter,
-// added to help in debugging crbug/160401.
-//
-IPC_MESSAGE_CONTROL4(ResourceMsg_SetDataBuffer,
+IPC_MESSAGE_CONTROL3(ResourceMsg_SetDataBuffer,
int /* request_id */,
base::SharedMemoryHandle /* shm_handle */,
- int /* shm_size */,
- base::ProcessId /* renderer_pid */)
+ int /* shm_size */)
// Sent when some data from a resource request is ready. The data offset and
// length specify a byte range into the shared memory buffer provided by the
@@ -362,7 +369,7 @@ IPC_MESSAGE_CONTROL3(ResourceMsg_DataDownloaded,
// Sent when the request has been completed.
IPC_MESSAGE_CONTROL2(ResourceMsg_RequestComplete,
int /* request_id */,
- content::ResourceRequestCompletionStatus)
+ network::URLLoaderCompletionStatus)
// Resource messages sent from the renderer to the browser.
diff --git a/chromium/content/common/sandbox_linux/sandbox_init_linux.cc b/chromium/content/common/sandbox_init_linux.cc
index f735837705c..4d81210f654 100644
--- a/chromium/content/common/sandbox_linux/sandbox_init_linux.cc
+++ b/chromium/content/common/sandbox_init_linux.cc
@@ -9,20 +9,20 @@
#include "base/files/scoped_file.h"
#include "build/build_config.h"
-#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h"
#include "sandbox/linux/bpf_dsl/policy.h"
+#include "services/service_manager/sandbox/linux/sandbox_seccomp_bpf_linux.h"
namespace content {
bool InitializeSandbox(std::unique_ptr<sandbox::bpf_dsl::Policy> policy,
base::ScopedFD proc_fd) {
- return SandboxSeccompBPF::StartSandboxWithExternalPolicy(std::move(policy),
- std::move(proc_fd));
+ return service_manager::SandboxSeccompBPF::StartSandboxWithExternalPolicy(
+ std::move(policy), std::move(proc_fd));
}
#if !defined(OS_NACL_NONSFI)
std::unique_ptr<sandbox::bpf_dsl::Policy> GetBPFSandboxBaselinePolicy() {
- return SandboxSeccompBPF::GetBaselinePolicy();
+ return service_manager::SandboxSeccompBPF::GetBaselinePolicy();
}
#endif // !defined(OS_NACL_NONSFI)
diff --git a/chromium/content/common/sandbox_init_mac.cc b/chromium/content/common/sandbox_init_mac.cc
index dca966f166e..f6241d0e97e 100644
--- a/chromium/content/common/sandbox_init_mac.cc
+++ b/chromium/content/common/sandbox_init_mac.cc
@@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/common/sandbox_init_mac.h"
+#include "content/public/common/sandbox_init.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "content/public/common/content_switches.h"
-#include "content/public/common/sandbox_init.h"
#include "media/gpu/vt_video_decode_accelerator_mac.h"
#include "sandbox/mac/seatbelt.h"
#include "services/service_manager/sandbox/mac/sandbox_mac.h"
+#include "services/service_manager/sandbox/sandbox.h"
#include "services/service_manager/sandbox/sandbox_type.h"
#include "ui/gl/init/gl_factory.h"
@@ -20,22 +20,6 @@ namespace content {
namespace {
-// NOTE: This function is the exact code for the entry point of mac sandbox
-// once it moves to service_manager/sandbox.
-bool InitializeSandboxInternal(service_manager::SandboxType sandbox_type,
- const base::FilePath& allowed_dir,
- base::OnceClosure hook) {
- // Warm up APIs before turning on the sandbox.
- service_manager::Sandbox::SandboxWarmup(sandbox_type);
-
- // Execute the post warmup callback.
- if (!hook.is_null())
- std::move(hook).Run();
-
- // Actually sandbox the process.
- return service_manager::Sandbox::EnableSandbox(sandbox_type, allowed_dir);
-}
-
// Helper method to make a closure from a closure.
base::OnceClosure MaybeWrapWithGPUSandboxHook(
service_manager::SandboxType sandbox_type,
@@ -93,23 +77,24 @@ bool GetSandboxInfoFromCommandLine(service_manager::SandboxType* sandbox_type,
bool InitializeSandbox(service_manager::SandboxType sandbox_type,
const base::FilePath& allowed_dir) {
- return InitializeSandboxInternal(
+ return service_manager::Sandbox::Initialize(
sandbox_type, allowed_dir,
MaybeWrapWithGPUSandboxHook(sandbox_type, base::OnceClosure()));
}
-bool InitializeSandboxWithPostWarmupHook(base::OnceClosure hook) {
+bool InitializeSandbox(base::OnceClosure post_warmup_hook) {
service_manager::SandboxType sandbox_type =
service_manager::SANDBOX_TYPE_INVALID;
base::FilePath allowed_dir;
return !GetSandboxInfoFromCommandLine(&sandbox_type, &allowed_dir) ||
- InitializeSandboxInternal(
+ service_manager::Sandbox::Initialize(
sandbox_type, allowed_dir,
- MaybeWrapWithGPUSandboxHook(sandbox_type, std::move(hook)));
+ MaybeWrapWithGPUSandboxHook(sandbox_type,
+ std::move(post_warmup_hook)));
}
bool InitializeSandbox() {
- return InitializeSandboxWithPostWarmupHook(base::OnceClosure());
+ return InitializeSandbox(base::OnceClosure());
}
} // namespace content
diff --git a/chromium/content/common/sandbox_init_mac.h b/chromium/content/common/sandbox_init_mac.h
deleted file mode 100644
index 375b3d992db..00000000000
--- a/chromium/content/common/sandbox_init_mac.h
+++ /dev/null
@@ -1,26 +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_SANDBOX_INIT_MAC_H_
-#define CONTENT_COMMON_SANDBOX_INIT_MAC_H_
-
-#include "base/callback_forward.h"
-
-namespace content {
-
-// Initialize the sandbox for renderer, gpu, utility, worker, and plugin
-// processes, depending on the command line flags. For the browser process which
-// is not sandboxed, this call is a no-op.
-// Returns true if the sandbox was initialized succesfully, false if an error
-// occurred. If process_type isn't one that needs sandboxing, true is always
-// returned.
-bool InitializeSandbox();
-
-// Initializes the sandbox, as described above, but executes the callback after
-// warmup and before initialization.
-bool InitializeSandboxWithPostWarmupHook(base::OnceClosure hook);
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_INIT_MAC_H_
diff --git a/chromium/content/common/sandbox_init_win.cc b/chromium/content/common/sandbox_init_win.cc
index fe3ca8cbe78..b5f1619f975 100644
--- a/chromium/content/common/sandbox_init_win.cc
+++ b/chromium/content/common/sandbox_init_win.cc
@@ -4,37 +4,53 @@
#include "content/public/common/sandbox_init.h"
+#include <string>
+
+#include "base/base_switches.h"
#include "base/logging.h"
-#include "content/common/sandbox_win.h"
+#include "base/trace_event/trace_event.h"
+#include "base/win/scoped_process_information.h"
+#include "content/common/content_switches_internal.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/sandbox_init.h"
+#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_types.h"
-#include "services/service_manager/sandbox/sandbox_type.h"
+#include "services/service_manager/sandbox/sandbox.h"
+#include "services/service_manager/sandbox/win/sandbox_win.h"
namespace content {
bool InitializeSandbox(service_manager::SandboxType sandbox_type,
sandbox::SandboxInterfaceInfo* sandbox_info) {
- sandbox::BrokerServices* broker_services = sandbox_info->broker_services;
- if (broker_services) {
- if (!InitBrokerServices(broker_services))
- return false;
-
- // IMPORTANT: This piece of code needs to run as early as possible in the
- // process because it will initialize the sandbox broker, which requires the
- // process to swap its window station. During this time all the UI will be
- // broken. This has to run before threads and windows are created.
- if (!service_manager::IsUnsandboxedSandboxType(sandbox_type)) {
- // Precreate the desktop and window station used by the renderers.
- scoped_refptr<sandbox::TargetPolicy> policy =
- broker_services->CreatePolicy();
- sandbox::ResultCode result = policy->CreateAlternateDesktop(true);
- CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result);
- }
- return true;
+ return service_manager::Sandbox::Initialize(sandbox_type, sandbox_info);
+}
+
+sandbox::ResultCode StartSandboxedProcess(
+ SandboxedProcessLauncherDelegate* delegate,
+ base::CommandLine* child_command_line,
+ const base::HandlesToInheritVector& handles_to_inherit,
+ base::Process* process) {
+ std::string type_str =
+ child_command_line->GetSwitchValueASCII(switches::kProcessType);
+ TRACE_EVENT1("startup", "StartProcessWithAccess", "type", type_str);
+
+ // Updates the command line arguments with debug-related flags. If debug
+ // flags have been used with this process, they will be filtered and added
+ // to child_command_line as needed.
+ const base::CommandLine* current_command_line =
+ base::CommandLine::ForCurrentProcess();
+ if (current_command_line->HasSwitch(switches::kWaitForDebuggerChildren)) {
+ std::string value = current_command_line->GetSwitchValueASCII(
+ switches::kWaitForDebuggerChildren);
+ child_command_line->AppendSwitchASCII(switches::kWaitForDebuggerChildren,
+ value);
+ if (value.empty() || value == type_str)
+ child_command_line->AppendSwitch(switches::kWaitForDebugger);
}
- return service_manager::IsUnsandboxedSandboxType(sandbox_type) ||
- InitTargetServices(sandbox_info->target_services);
+ return service_manager::SandboxWin::StartSandboxedProcess(
+ child_command_line, type_str, handles_to_inherit, delegate, process);
}
} // namespace content
diff --git a/chromium/content/common/sandbox_linux/OWNERS b/chromium/content/common/sandbox_linux/OWNERS
deleted file mode 100644
index 444aa4eff98..00000000000
--- a/chromium/content/common/sandbox_linux/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-jln@chromium.org
-jorgelo@chromium.org
-mdempsky@chromium.org
-rickyz@chromium.org
-rsesek@chromium.org
-
-# TEAM: security-dev@chromium.org
-# COMPONENT: Internals>Sandbox
diff --git a/chromium/content/common/sandbox_linux/bpf_cdm_policy_linux.cc b/chromium/content/common/sandbox_linux/bpf_cdm_policy_linux.cc
deleted file mode 100644
index 7b61c7fea3e..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_cdm_policy_linux.cc
+++ /dev/null
@@ -1,55 +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/sandbox_linux/bpf_cdm_policy_linux.h"
-
-#include <errno.h>
-
-#include "build/build_config.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
-#include "sandbox/linux/system_headers/linux_syscalls.h"
-
-using sandbox::SyscallSets;
-using sandbox::bpf_dsl::Allow;
-using sandbox::bpf_dsl::Error;
-using sandbox::bpf_dsl::ResultExpr;
-
-namespace content {
-
-CdmProcessPolicy::CdmProcessPolicy() {}
-CdmProcessPolicy::~CdmProcessPolicy() {}
-
-ResultExpr CdmProcessPolicy::EvaluateSyscall(int sysno) const {
- switch (sysno) {
- case __NR_ioctl:
- return sandbox::RestrictIoctl();
- // Allow the system calls below.
- case __NR_fdatasync:
- case __NR_fsync:
-#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \
- defined(__aarch64__)
- case __NR_getrlimit:
-#endif
-#if defined(__i386__) || defined(__arm__)
- case __NR_ugetrlimit:
-#endif
- case __NR_mremap: // https://crbug.com/546204
- case __NR_pread64:
- case __NR_pwrite64:
- case __NR_sysinfo:
- case __NR_times:
- case __NR_uname:
- return Allow();
- case __NR_sched_getaffinity:
- return sandbox::RestrictSchedTarget(GetPolicyPid(), sysno);
- default:
- // Default on the content baseline policy.
- return SandboxBPFBasePolicy::EvaluateSyscall(sysno);
- }
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/bpf_cdm_policy_linux.h b/chromium/content/common/sandbox_linux/bpf_cdm_policy_linux.h
deleted file mode 100644
index 8b98f02ce27..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_cdm_policy_linux.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_SANDBOX_LINUX_BPF_CDM_POLICY_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_BPF_CDM_POLICY_LINUX_H_
-
-#include "base/macros.h"
-#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
-
-namespace content {
-
-// This policy can be used by the process hosting a Content Decryption Module.
-class CdmProcessPolicy : public SandboxBPFBasePolicy {
- public:
- CdmProcessPolicy();
- ~CdmProcessPolicy() override;
-
- sandbox::bpf_dsl::ResultExpr EvaluateSyscall(
- int system_call_number) const override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CdmProcessPolicy);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_CDM_POLICY_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/bpf_cros_amd_gpu_policy_linux.cc b/chromium/content/common/sandbox_linux/bpf_cros_amd_gpu_policy_linux.cc
deleted file mode 100644
index a72d87e27b9..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_cros_amd_gpu_policy_linux.cc
+++ /dev/null
@@ -1,171 +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.
-
-#include "content/common/sandbox_linux/bpf_cros_amd_gpu_policy_linux.h"
-
-#include <dlfcn.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
-#include "sandbox/linux/syscall_broker/broker_file_permission.h"
-#include "sandbox/linux/system_headers/linux_syscalls.h"
-
-using sandbox::bpf_dsl::Allow;
-using sandbox::bpf_dsl::Arg;
-using sandbox::bpf_dsl::Error;
-using sandbox::bpf_dsl::If;
-using sandbox::bpf_dsl::ResultExpr;
-using sandbox::syscall_broker::BrokerFilePermission;
-
-namespace content {
-
-namespace {
-
-inline bool IsChromeOS() {
-#if defined(OS_CHROMEOS)
- return true;
-#else
- return false;
-#endif
-}
-
-void AddAmdGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
- static const char* kReadOnlyList[] = {"/etc/ld.so.cache",
- "/usr/lib64/libEGL.so.1",
- "/usr/lib64/libGLESv2.so.2"};
- int listSize = arraysize(kReadOnlyList);
-
- for (int i = 0; i < listSize; i++) {
- permissions->push_back(BrokerFilePermission::ReadOnly(kReadOnlyList[i]));
- }
-
- static const char* kReadWriteList[] = {
- "/dev/dri",
- "/dev/dri/card0",
- "/dev/dri/controlD64",
- "/dev/dri/renderD128",
- "/sys/class/drm/card0/device/config",
- "/sys/class/drm/controlD64/device/config",
- "/sys/class/drm/renderD128/device/config",
- "/usr/share/libdrm/amdgpu.ids"};
-
- listSize = arraysize(kReadWriteList);
-
- for (int i = 0; i < listSize; i++) {
- permissions->push_back(BrokerFilePermission::ReadWrite(kReadWriteList[i]));
- }
-
- static const char kCharDevices[] = "/sys/dev/char/";
- permissions->push_back(BrokerFilePermission::ReadOnlyRecursive(kCharDevices));
-}
-
-class CrosAmdGpuBrokerProcessPolicy : public CrosAmdGpuProcessPolicy {
- public:
- static sandbox::bpf_dsl::Policy* Create() {
- return new CrosAmdGpuBrokerProcessPolicy();
- }
- ~CrosAmdGpuBrokerProcessPolicy() override {}
-
- ResultExpr EvaluateSyscall(int system_call_number) const override;
-
- private:
- CrosAmdGpuBrokerProcessPolicy() {}
- DISALLOW_COPY_AND_ASSIGN(CrosAmdGpuBrokerProcessPolicy);
-};
-
-// A GPU broker policy is the same as a GPU policy with access, open,
-// openat and in the non-Chrome OS case unlink allowed.
-ResultExpr CrosAmdGpuBrokerProcessPolicy::EvaluateSyscall(int sysno) const {
- switch (sysno) {
- case __NR_faccessat:
- case __NR_openat:
-#if !defined(__aarch64__)
- case __NR_access:
- case __NR_open:
-#if !defined(OS_CHROMEOS)
- // The broker process needs to able to unlink the temporary
- // files that it may create. This is used by DRI3.
- case __NR_unlink:
-#endif // !defined(OS_CHROMEOS)
-#endif // !define(__aarch64__)
- return Allow();
- default:
- return CrosAmdGpuProcessPolicy::EvaluateSyscall(sysno);
- }
-}
-
-} // namespace
-
-CrosAmdGpuProcessPolicy::CrosAmdGpuProcessPolicy() {}
-
-CrosAmdGpuProcessPolicy::~CrosAmdGpuProcessPolicy() {}
-
-ResultExpr CrosAmdGpuProcessPolicy::EvaluateSyscall(int sysno) const {
- switch (sysno) {
- case __NR_fstatfs:
- case __NR_sched_setscheduler:
- case __NR_sysinfo:
- case __NR_uname:
-#if !defined(__aarch64__)
- case __NR_getdents:
- case __NR_readlink:
- case __NR_stat:
-#endif
- return Allow();
-#if defined(__x86_64__)
- // Allow only AF_UNIX for |domain|.
- case __NR_socket:
- case __NR_socketpair: {
- const Arg<int> domain(0);
- return If(domain == AF_UNIX, Allow()).Else(Error(EPERM));
- }
-#endif
- default:
- // Default to the generic GPU policy.
- return GpuProcessPolicy::EvaluateSyscall(sysno);
- }
-}
-
-bool CrosAmdGpuProcessPolicy::PreSandboxHook() {
- DCHECK(IsChromeOS());
- // Create a new broker process.
- DCHECK(!broker_process());
-
- // Add AMD-specific files to whitelist in the broker.
- std::vector<BrokerFilePermission> permissions;
-
- AddAmdGpuWhitelist(&permissions);
- InitGpuBrokerProcess(CrosAmdGpuBrokerProcessPolicy::Create, permissions);
-
- const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;
-
- // Preload the amdgpu-dependent libraries.
- errno = 0;
- if (NULL == dlopen("libglapi.so", dlopen_flag)) {
- LOG(ERROR) << "dlopen(libglapi.so) failed with error: " << dlerror();
- return false;
- }
- if (NULL == dlopen("/usr/lib64/dri/swrast_dri.so", dlopen_flag)) {
- LOG(ERROR) << "dlopen(swrast_dri.so) failed with error: " << dlerror();
- return false;
- }
- if (NULL == dlopen("/usr/lib64/dri/radeonsi_dri.so", dlopen_flag)) {
- LOG(ERROR) << "dlopen(radeonsi_dri.so) failed with error: " << dlerror();
- return false;
- }
-
- return true;
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/bpf_cros_amd_gpu_policy_linux.h b/chromium/content/common/sandbox_linux/bpf_cros_amd_gpu_policy_linux.h
deleted file mode 100644
index aed3a241fe0..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_cros_amd_gpu_policy_linux.h
+++ /dev/null
@@ -1,29 +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_SANDBOX_LINUX_BPF_CROS_AMD_GPU_POLICY_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_BPF_CROS_AMD_GPU_POLICY_LINUX_H_
-
-#include "base/macros.h"
-#include "content/common/sandbox_linux/bpf_gpu_policy_linux.h"
-
-namespace content {
-
-// This policy is for AMD GPUs running on Chrome OS.
-class CrosAmdGpuProcessPolicy : public GpuProcessPolicy {
- public:
- CrosAmdGpuProcessPolicy();
- ~CrosAmdGpuProcessPolicy() override;
-
- sandbox::bpf_dsl::ResultExpr EvaluateSyscall(
- int system_call_number) const override;
- bool PreSandboxHook() override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CrosAmdGpuProcessPolicy);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_CROS_AMD_GPU_POLICY_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc b/chromium/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc
deleted file mode 100644
index 012a7f678b9..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc
+++ /dev/null
@@ -1,182 +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/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h"
-
-#include <dlfcn.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "build/build_config.h"
-#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
-#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
-#include "sandbox/linux/syscall_broker/broker_file_permission.h"
-#include "sandbox/linux/system_headers/linux_syscalls.h"
-
-using sandbox::bpf_dsl::Allow;
-using sandbox::bpf_dsl::Arg;
-using sandbox::bpf_dsl::Error;
-using sandbox::bpf_dsl::If;
-using sandbox::bpf_dsl::ResultExpr;
-using sandbox::syscall_broker::BrokerFilePermission;
-using sandbox::SyscallSets;
-
-namespace content {
-
-namespace {
-
-inline bool IsChromeOS() {
-#if defined(OS_CHROMEOS)
- return true;
-#else
- return false;
-#endif
-}
-
-inline bool IsArchitectureArm() {
-#if defined(__arm__) || defined(__aarch64__)
- return true;
-#else
- return false;
-#endif
-}
-
-void AddArmMaliGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
- // Device file needed by the ARM GPU userspace.
- static const char kMali0Path[] = "/dev/mali0";
-
- // Image processor used on ARM platforms.
- static const char kDevImageProc0Path[] = "/dev/image-proc0";
-
- permissions->push_back(BrokerFilePermission::ReadWrite(kMali0Path));
- permissions->push_back(BrokerFilePermission::ReadWrite(kDevImageProc0Path));
-}
-
-void AddArmGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
- // On ARM we're enabling the sandbox before the X connection is made,
- // so we need to allow access to |.Xauthority|.
- static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
- 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));
- permissions->push_back(BrokerFilePermission::ReadOnly(kLibEglPath));
-
- AddArmMaliGpuWhitelist(permissions);
-}
-
-class CrosArmGpuBrokerProcessPolicy : public CrosArmGpuProcessPolicy {
- public:
- static sandbox::bpf_dsl::Policy* Create() {
- return new CrosArmGpuBrokerProcessPolicy();
- }
- ~CrosArmGpuBrokerProcessPolicy() override {}
-
- ResultExpr EvaluateSyscall(int system_call_number) const override;
-
- private:
- CrosArmGpuBrokerProcessPolicy() : CrosArmGpuProcessPolicy(false) {}
- DISALLOW_COPY_AND_ASSIGN(CrosArmGpuBrokerProcessPolicy);
-};
-
-// A GPU broker policy is the same as a GPU policy with open and
-// openat allowed.
-ResultExpr CrosArmGpuBrokerProcessPolicy::EvaluateSyscall(int sysno) const {
- switch (sysno) {
-#if !defined(__aarch64__)
- case __NR_access:
- case __NR_open:
-#endif // !defined(__aarch64__)
- case __NR_faccessat:
- case __NR_openat:
- return Allow();
- default:
- return CrosArmGpuProcessPolicy::EvaluateSyscall(sysno);
- }
-}
-
-} // namespace
-
-CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(bool allow_shmat)
-#if defined(__arm__) || defined(__aarch64__)
- : allow_shmat_(allow_shmat)
-#endif
-{
-}
-
-CrosArmGpuProcessPolicy::~CrosArmGpuProcessPolicy() {}
-
-ResultExpr CrosArmGpuProcessPolicy::EvaluateSyscall(int sysno) const {
-#if defined(__arm__) || defined(__aarch64__)
- if (allow_shmat_ && sysno == __NR_shmat)
- return Allow();
-#endif // defined(__arm__) || defined(__aarch64__)
-
- switch (sysno) {
-#if defined(__arm__) || defined(__aarch64__)
- // ARM GPU sandbox is started earlier so we need to allow networking
- // in the sandbox.
- case __NR_connect:
- case __NR_getpeername:
- case __NR_getsockname:
- case __NR_sysinfo:
- case __NR_uname:
- return Allow();
- // Allow only AF_UNIX for |domain|.
- case __NR_socket:
- case __NR_socketpair: {
- const Arg<int> domain(0);
- return If(domain == AF_UNIX, Allow()).Else(Error(EPERM));
- }
-#endif // defined(__arm__) || defined(__aarch64__)
- default:
- // Default to the generic GPU policy.
- return GpuProcessPolicy::EvaluateSyscall(sysno);
- }
-}
-
-bool CrosArmGpuProcessPolicy::PreSandboxHook() {
- DCHECK(IsChromeOS() && IsArchitectureArm());
- // Create a new broker process.
- DCHECK(!broker_process());
-
- // Add ARM-specific files to whitelist in the broker.
- std::vector<BrokerFilePermission> permissions;
-
- AddArmGpuWhitelist(&permissions);
- InitGpuBrokerProcess(CrosArmGpuBrokerProcessPolicy::Create, permissions);
-
- const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;
-
- // Preload the Mali library.
- dlopen("/usr/lib/libmali.so", dlopen_flag);
- // Preload the Tegra V4L2 (video decode acceleration) library.
- dlopen("/usr/lib/libtegrav4l2.so", dlopen_flag);
- // Resetting errno since platform-specific libraries will fail on other
- // platforms.
- errno = 0;
-
- return true;
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h b/chromium/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h
deleted file mode 100644
index c026f4e98f8..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h
+++ /dev/null
@@ -1,32 +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_COMMON_SANDBOX_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_
-
-#include "base/macros.h"
-#include "content/common/sandbox_linux/bpf_gpu_policy_linux.h"
-
-namespace content {
-
-// This policy is for Chrome OS ARM.
-class CrosArmGpuProcessPolicy : public GpuProcessPolicy {
- public:
- explicit CrosArmGpuProcessPolicy(bool allow_shmat);
- ~CrosArmGpuProcessPolicy() override;
-
- sandbox::bpf_dsl::ResultExpr EvaluateSyscall(
- int system_call_number) const override;
- bool PreSandboxHook() override;
-
- private:
-#if defined(__arm__) || defined(__aarch64__)
- const bool allow_shmat_; // Allow shmat(2).
-#endif
- DISALLOW_COPY_AND_ASSIGN(CrosArmGpuProcessPolicy);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/bpf_gpu_policy_linux.cc b/chromium/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
deleted file mode 100644
index ac5dc5aa0ab..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
+++ /dev/null
@@ -1,384 +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/common/sandbox_linux/bpf_gpu_policy_linux.h"
-
-#include <dlfcn.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/compiler_specific.h"
-#include "base/files/file_enumerator.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/stringprintf.h"
-#include "build/build_config.h"
-#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
-#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h"
-#include "content/public/common/content_switches.h"
-#include "media/gpu/features.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
-#include "sandbox/linux/syscall_broker/broker_file_permission.h"
-#include "sandbox/linux/syscall_broker/broker_process.h"
-#include "sandbox/linux/system_headers/linux_syscalls.h"
-#include "services/service_manager/embedder/set_process_title.h"
-
-using sandbox::arch_seccomp_data;
-using sandbox::bpf_dsl::Allow;
-using sandbox::bpf_dsl::ResultExpr;
-using sandbox::bpf_dsl::Trap;
-using sandbox::syscall_broker::BrokerFilePermission;
-using sandbox::syscall_broker::BrokerProcess;
-using sandbox::SyscallSets;
-
-namespace content {
-
-namespace {
-
-inline bool IsChromeOS() {
-#if defined(OS_CHROMEOS)
- return true;
-#else
- return false;
-#endif
-}
-
-inline bool IsArchitectureX86_64() {
-#if defined(__x86_64__)
- return true;
-#else
- return false;
-#endif
-}
-
-inline bool IsArchitectureI386() {
-#if defined(__i386__)
- return true;
-#else
- return false;
-#endif
-}
-
-inline bool IsArchitectureArm() {
-#if defined(__arm__) || defined(__aarch64__)
- return true;
-#else
- return false;
-#endif
-}
-
-inline bool UseV4L2Codec() {
-#if BUILDFLAG(USE_V4L2_CODEC)
- return true;
-#else
- return false;
-#endif
-}
-
-inline bool UseLibV4L2() {
-#if BUILDFLAG(USE_LIBV4L2)
- return true;
-#else
- return false;
-#endif
-}
-
-bool IsAcceleratedVaapiVideoEncodeEnabled() {
- bool accelerated_encode_enabled = false;
-#if defined(OS_CHROMEOS)
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- accelerated_encode_enabled =
- !command_line.HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode);
-#endif
- return accelerated_encode_enabled;
-}
-
-bool IsAcceleratedVideoDecodeEnabled() {
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- return !command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode);
-}
-
-intptr_t GpuSIGSYS_Handler(const struct arch_seccomp_data& args,
- void* aux_broker_process) {
- RAW_CHECK(aux_broker_process);
- BrokerProcess* broker_process =
- static_cast<BrokerProcess*>(aux_broker_process);
- switch (args.nr) {
-#if !defined(__aarch64__)
- case __NR_access:
- return broker_process->Access(reinterpret_cast<const char*>(args.args[0]),
- static_cast<int>(args.args[1]));
- case __NR_open:
-#if defined(MEMORY_SANITIZER)
- // http://crbug.com/372840
- __msan_unpoison_string(reinterpret_cast<const char*>(args.args[0]));
-#endif
- return broker_process->Open(reinterpret_cast<const char*>(args.args[0]),
- static_cast<int>(args.args[1]));
-#endif // !defined(__aarch64__)
- case __NR_faccessat:
- if (static_cast<int>(args.args[0]) == AT_FDCWD) {
- return broker_process->Access(
- reinterpret_cast<const char*>(args.args[1]),
- static_cast<int>(args.args[2]));
- } else {
- return -EPERM;
- }
- case __NR_openat:
- // Allow using openat() as open().
- if (static_cast<int>(args.args[0]) == AT_FDCWD) {
- return broker_process->Open(reinterpret_cast<const char*>(args.args[1]),
- static_cast<int>(args.args[2]));
- } else {
- return -EPERM;
- }
- default:
- RAW_CHECK(false);
- return -ENOSYS;
- }
-}
-
-void AddV4L2GpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
- if (IsAcceleratedVideoDecodeEnabled()) {
- // Device nodes for V4L2 video decode accelerator drivers.
- static const base::FilePath::CharType kDevicePath[] =
- FILE_PATH_LITERAL("/dev/");
- static const base::FilePath::CharType kVideoDecPattern[] = "video-dec[0-9]";
- base::FileEnumerator enumerator(base::FilePath(kDevicePath), false,
- base::FileEnumerator::FILES,
- base::FilePath(kVideoDecPattern).value());
- for (base::FilePath name = enumerator.Next(); !name.empty();
- name = enumerator.Next())
- permissions->push_back(BrokerFilePermission::ReadWrite(name.value()));
- }
-
- // Device node for V4L2 video encode accelerator drivers.
- static const char kDevVideoEncPath[] = "/dev/video-enc";
- permissions->push_back(BrokerFilePermission::ReadWrite(kDevVideoEncPath));
-
- // Device node for V4L2 JPEG decode accelerator drivers.
- static const char kDevJpegDecPath[] = "/dev/jpeg-dec";
- permissions->push_back(BrokerFilePermission::ReadWrite(kDevJpegDecPath));
-}
-
-class GpuBrokerProcessPolicy : public GpuProcessPolicy {
- public:
- static sandbox::bpf_dsl::Policy* Create() {
- return new GpuBrokerProcessPolicy();
- }
- ~GpuBrokerProcessPolicy() override {}
-
- ResultExpr EvaluateSyscall(int system_call_number) const override;
-
- private:
- GpuBrokerProcessPolicy() {}
- DISALLOW_COPY_AND_ASSIGN(GpuBrokerProcessPolicy);
-};
-
-// x86_64/i386 or desktop ARM.
-// A GPU broker policy is the same as a GPU policy with access, open,
-// openat and in the non-Chrome OS case unlink allowed.
-ResultExpr GpuBrokerProcessPolicy::EvaluateSyscall(int sysno) const {
- switch (sysno) {
-#if !defined(__aarch64__)
- case __NR_access:
- case __NR_open:
-#endif // !defined(__aarch64__)
- case __NR_faccessat:
- case __NR_openat:
-#if !defined(OS_CHROMEOS) && !defined(__aarch64__)
- // The broker process needs to able to unlink the temporary
- // files that it may create. This is used by DRI3.
- case __NR_unlink:
-#endif
- return Allow();
- default:
- return GpuProcessPolicy::EvaluateSyscall(sysno);
- }
-}
-
-void UpdateProcessTypeToGpuBroker() {
- base::CommandLine::StringVector exec =
- base::CommandLine::ForCurrentProcess()->GetArgs();
- base::CommandLine::Reset();
- base::CommandLine::Init(0, NULL);
- base::CommandLine::ForCurrentProcess()->InitFromArgv(exec);
- base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
- switches::kProcessType, "gpu-broker");
-
- // Update the process title. The argv was already cached by the call to
- // SetProcessTitleFromCommandLine in content_main_runner.cc, so we can pass
- // NULL here (we don't have the original argv at this point).
- service_manager::SetProcessTitleFromCommandLine(nullptr);
-}
-
-bool UpdateProcessTypeAndEnableSandbox(
- sandbox::bpf_dsl::Policy* (*broker_sandboxer_allocator)(void)) {
- DCHECK(broker_sandboxer_allocator);
- UpdateProcessTypeToGpuBroker();
- return SandboxSeccompBPF::StartSandboxWithExternalPolicy(
- base::WrapUnique(broker_sandboxer_allocator()), base::ScopedFD());
-}
-
-} // namespace
-
-GpuProcessPolicy::GpuProcessPolicy() : broker_process_(NULL) {}
-
-GpuProcessPolicy::~GpuProcessPolicy() {}
-
-// Main policy for x86_64/i386. Extended by CrosArmGpuProcessPolicy.
-ResultExpr GpuProcessPolicy::EvaluateSyscall(int sysno) const {
- switch (sysno) {
-#if !defined(OS_CHROMEOS)
- case __NR_ftruncate:
-#endif
- case __NR_ioctl:
- return Allow();
-#if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
- // The Nvidia driver uses flags not in the baseline policy
- // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT)
- case __NR_mmap:
-#endif
- // We also hit this on the linux_chromeos bot but don't yet know what
- // weird flags were involved.
- case __NR_mprotect:
- // TODO(jln): restrict prctl.
- case __NR_prctl:
- case __NR_sysinfo:
- return Allow();
-#if !defined(__aarch64__)
- case __NR_access:
- case __NR_open:
-#endif // !defined(__aarch64__)
- case __NR_faccessat:
- case __NR_openat:
- DCHECK(broker_process_);
- return Trap(GpuSIGSYS_Handler, broker_process_);
- case __NR_sched_getaffinity:
- case __NR_sched_setaffinity:
- return sandbox::RestrictSchedTarget(GetPolicyPid(), sysno);
- default:
- if (SyscallSets::IsEventFd(sysno))
- return Allow();
-
- // Default on the baseline policy.
- return SandboxBPFBasePolicy::EvaluateSyscall(sysno);
- }
-}
-
-bool GpuProcessPolicy::PreSandboxHook() {
- // Warm up resources needed by the policy we're about to enable and
- // eventually start a broker process.
- const bool chromeos_arm_gpu = IsChromeOS() && IsArchitectureArm();
- // This policy is for x86 or Desktop.
- DCHECK(!chromeos_arm_gpu);
-
- DCHECK(!broker_process());
- // Create a new broker process.
- InitGpuBrokerProcess(
- GpuBrokerProcessPolicy::Create,
- std::vector<BrokerFilePermission>()); // No extra files in whitelist.
-
- if (IsArchitectureX86_64() || IsArchitectureI386()) {
- // Accelerated video dlopen()'s some shared objects
- // inside the sandbox, so preload them now.
- if (IsAcceleratedVaapiVideoEncodeEnabled() ||
- IsAcceleratedVideoDecodeEnabled()) {
- const char* I965DrvVideoPath = NULL;
- const char* I965HybridDrvVideoPath = NULL;
-
- if (IsArchitectureX86_64()) {
- I965DrvVideoPath = "/usr/lib64/va/drivers/i965_drv_video.so";
- I965HybridDrvVideoPath = "/usr/lib64/va/drivers/hybrid_drv_video.so";
- } else if (IsArchitectureI386()) {
- I965DrvVideoPath = "/usr/lib/va/drivers/i965_drv_video.so";
- }
-
- dlopen(I965DrvVideoPath, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
- if (I965HybridDrvVideoPath)
- dlopen(I965HybridDrvVideoPath, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
- dlopen("libva.so.1", RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
-#if defined(USE_OZONE)
- dlopen("libva-drm.so.1", RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
-#elif defined(USE_X11)
- dlopen("libva-x11.so.1", RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
-#endif
- }
- }
-
- return true;
-}
-
-void GpuProcessPolicy::InitGpuBrokerProcess(
- sandbox::bpf_dsl::Policy* (*broker_sandboxer_allocator)(void),
- const std::vector<BrokerFilePermission>& permissions_extra) {
- static const char kDriRcPath[] = "/etc/drirc";
- static const char kDriCardBasePath[] = "/dev/dri/card";
-
- static const char kNvidiaCtlPath[] = "/dev/nvidiactl";
- static const char kNvidiaDeviceBasePath[] = "/dev/nvidia";
- static const char kNvidiaParamsPath[] = "/proc/driver/nvidia/params";
-
- static const char kDevShm[] = "/dev/shm/";
-
- CHECK(broker_process_ == NULL);
-
- // All GPU process policies need these files brokered out.
- std::vector<BrokerFilePermission> permissions;
- permissions.push_back(BrokerFilePermission::ReadOnly(kDriRcPath));
-
- if (!IsChromeOS()) {
- // For shared memory.
- permissions.push_back(
- BrokerFilePermission::ReadWriteCreateUnlinkRecursive(kDevShm));
- // For DRI cards.
- for (int i = 0; i <= 9; ++i) {
- permissions.push_back(BrokerFilePermission::ReadWrite(
- base::StringPrintf("%s%d", kDriCardBasePath, i)));
- }
- // For Nvidia GLX driver.
- permissions.push_back(BrokerFilePermission::ReadWrite(kNvidiaCtlPath));
- for (int i = 0; i <= 9; ++i) {
- permissions.push_back(BrokerFilePermission::ReadWrite(
- base::StringPrintf("%s%d", kNvidiaDeviceBasePath, i)));
- }
- permissions.push_back(BrokerFilePermission::ReadOnly(kNvidiaParamsPath));
- } else if (UseV4L2Codec()) {
- AddV4L2GpuWhitelist(&permissions);
- if (UseLibV4L2()) {
- dlopen("/usr/lib/libv4l2.so", RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
- // This is a device-specific encoder plugin.
- dlopen("/usr/lib/libv4l/plugins/libv4l-encplugin.so",
- RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
- }
- }
-
- // Add eventual extra files from permissions_extra.
- for (const auto& perm : permissions_extra) {
- permissions.push_back(perm);
- }
-
- broker_process_ = new BrokerProcess(GetFSDeniedErrno(), permissions);
- // The initialization callback will perform generic initialization and then
- // call broker_sandboxer_callback.
- CHECK(broker_process_->Init(base::Bind(&UpdateProcessTypeAndEnableSandbox,
- broker_sandboxer_allocator)));
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/bpf_gpu_policy_linux.h b/chromium/content/common/sandbox_linux/bpf_gpu_policy_linux.h
deleted file mode 100644
index 23b7c9d8d2a..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_gpu_policy_linux.h
+++ /dev/null
@@ -1,65 +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_COMMON_SANDBOX_LINUX_BPF_GPU_POLICY_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_BPF_GPU_POLICY_LINUX_H_
-
-#include <string>
-#include <vector>
-
-#include "base/callback_forward.h"
-#include "base/macros.h"
-#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
-
-namespace sandbox {
-namespace syscall_broker {
-class BrokerFilePermission;
-class BrokerProcess;
-}
-}
-
-namespace content {
-
-class GpuProcessPolicy : public SandboxBPFBasePolicy {
- public:
- GpuProcessPolicy();
- ~GpuProcessPolicy() override;
-
- sandbox::bpf_dsl::ResultExpr EvaluateSyscall(
- int system_call_number) const override;
-
- bool PreSandboxHook() override;
-
- protected:
- // Start a broker process to handle open() inside the sandbox.
- // |broker_sandboxer_allocator| is a function pointer which can allocate a
- // suitable sandbox policy for the broker process itself.
- // |permissions_extra| is a list of file permissions
- // that should be whitelisted by the broker process, in addition to
- // the basic ones.
- void InitGpuBrokerProcess(
- sandbox::bpf_dsl::Policy* (*broker_sandboxer_allocator)(void),
- const std::vector<sandbox::syscall_broker::BrokerFilePermission>&
- permissions_extra);
-
- sandbox::syscall_broker::BrokerProcess* broker_process() {
- return broker_process_;
- }
-
- private:
- // A BrokerProcess is a helper that is started before the sandbox is engaged
- // and will serve requests to access files over an IPC channel. The client of
- // this runs from a SIGSYS handler triggered by the seccomp-bpf sandbox.
- // This should never be destroyed, as after the sandbox is started it is
- // vital to the process.
- // This is allocated by InitGpuBrokerProcess, called from PreSandboxHook(),
- // which executes iff the sandbox is going to be enabled afterwards.
- sandbox::syscall_broker::BrokerProcess* broker_process_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuProcessPolicy);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_GPU_POLICY_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/bpf_pdf_compositor_policy_linux.cc b/chromium/content/common/sandbox_linux/bpf_pdf_compositor_policy_linux.cc
deleted file mode 100644
index 88f28d12017..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_pdf_compositor_policy_linux.cc
+++ /dev/null
@@ -1,55 +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/sandbox_linux/bpf_pdf_compositor_policy_linux.h"
-
-#include <errno.h>
-
-#include "build/build_config.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
-#include "sandbox/linux/system_headers/linux_syscalls.h"
-
-using sandbox::SyscallSets;
-using sandbox::bpf_dsl::Allow;
-using sandbox::bpf_dsl::Error;
-using sandbox::bpf_dsl::ResultExpr;
-
-namespace content {
-
-PdfCompositorProcessPolicy::PdfCompositorProcessPolicy() {}
-PdfCompositorProcessPolicy::~PdfCompositorProcessPolicy() {}
-
-ResultExpr PdfCompositorProcessPolicy::EvaluateSyscall(int sysno) const {
- // TODO(weili): the current set of policy is exactly same as utility process
- // policy. Check whether we can trim further.
- switch (sysno) {
- case __NR_ioctl:
- return sandbox::RestrictIoctl();
- // Allow the system calls below.
- case __NR_fdatasync:
- case __NR_fsync:
-#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \
- defined(__aarch64__)
- case __NR_getrlimit:
-#endif
-#if defined(__i386__) || defined(__arm__)
- case __NR_ugetrlimit:
-#endif
- case __NR_mremap: // https://crbug.com/546204
- case __NR_pread64:
- case __NR_pwrite64:
- case __NR_sysinfo:
- case __NR_times:
- case __NR_uname:
- return Allow();
- default:
- // Default on the content baseline policy.
- return SandboxBPFBasePolicy::EvaluateSyscall(sysno);
- }
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/bpf_pdf_compositor_policy_linux.h b/chromium/content/common/sandbox_linux/bpf_pdf_compositor_policy_linux.h
deleted file mode 100644
index 02b9ead7e02..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_pdf_compositor_policy_linux.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_SANDBOX_LINUX_BPF_PDF_COMPOSITOR_POLICY_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_BPF_PDF_COMPOSITOR_POLICY_LINUX_H_
-
-#include "base/macros.h"
-#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
-
-namespace content {
-
-// This policy can be used by pdf compositor utility processes.
-class PdfCompositorProcessPolicy : public SandboxBPFBasePolicy {
- public:
- PdfCompositorProcessPolicy();
- ~PdfCompositorProcessPolicy() override;
-
- sandbox::bpf_dsl::ResultExpr EvaluateSyscall(
- int system_call_number) const override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PdfCompositorProcessPolicy);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_PDF_COMPOSITOR_POLICY_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/bpf_ppapi_policy_linux.cc b/chromium/content/common/sandbox_linux/bpf_ppapi_policy_linux.cc
deleted file mode 100644
index e6ee6a8bbc4..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_ppapi_policy_linux.cc
+++ /dev/null
@@ -1,50 +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/common/sandbox_linux/bpf_ppapi_policy_linux.h"
-
-#include <errno.h>
-
-#include "build/build_config.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
-#include "sandbox/linux/system_headers/linux_syscalls.h"
-
-using sandbox::SyscallSets;
-using sandbox::bpf_dsl::Allow;
-using sandbox::bpf_dsl::Error;
-using sandbox::bpf_dsl::ResultExpr;
-
-namespace content {
-
-PpapiProcessPolicy::PpapiProcessPolicy() {}
-PpapiProcessPolicy::~PpapiProcessPolicy() {}
-
-ResultExpr PpapiProcessPolicy::EvaluateSyscall(int sysno) const {
- switch (sysno) {
- // TODO(jln): restrict prctl.
- case __NR_prctl:
- case __NR_pread64:
- case __NR_pwrite64:
- case __NR_sched_get_priority_max:
- case __NR_sched_get_priority_min:
- case __NR_sysinfo:
- case __NR_times:
- return Allow();
- case __NR_sched_getaffinity:
- case __NR_sched_getparam:
- case __NR_sched_getscheduler:
- case __NR_sched_setscheduler:
- return sandbox::RestrictSchedTarget(GetPolicyPid(), sysno);
- case __NR_ioctl:
- return Error(ENOTTY); // Flash Access.
- default:
- // Default on the baseline policy.
- return SandboxBPFBasePolicy::EvaluateSyscall(sysno);
- }
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/bpf_ppapi_policy_linux.h b/chromium/content/common/sandbox_linux/bpf_ppapi_policy_linux.h
deleted file mode 100644
index 62133ac1026..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_ppapi_policy_linux.h
+++ /dev/null
@@ -1,28 +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_COMMON_SANDBOX_LINUX_BPF_PPAPI_POLICY_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_BPF_PPAPI_POLICY_LINUX_H_
-
-#include "base/macros.h"
-#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
-
-namespace content {
-
-// Policy for Pepper plugins such as Flash.
-class PpapiProcessPolicy : public SandboxBPFBasePolicy {
- public:
- PpapiProcessPolicy();
- ~PpapiProcessPolicy() override;
-
- sandbox::bpf_dsl::ResultExpr EvaluateSyscall(
- int system_call_number) const override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PpapiProcessPolicy);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_PPAPI_POLICY_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.cc b/chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
deleted file mode 100644
index c2b7e823b05..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
+++ /dev/null
@@ -1,111 +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/common/sandbox_linux/bpf_renderer_policy_linux.h"
-
-#include <errno.h>
-#include <sys/ioctl.h>
-
-#include "build/build_config.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
-#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
-#include "sandbox/linux/system_headers/linux_syscalls.h"
-
-#if defined(OS_CHROMEOS)
-// TODO(vignatti): replace the local definitions below with #include
-// <linux/dma-buf.h> once kernel version 4.6 becomes widely used.
-#include <linux/types.h>
-
-struct local_dma_buf_sync {
- __u64 flags;
-};
-#define LOCAL_DMA_BUF_BASE 'b'
-#define LOCAL_DMA_BUF_IOCTL_SYNC \
- _IOW(LOCAL_DMA_BUF_BASE, 0, struct local_dma_buf_sync)
-#endif
-
-using sandbox::SyscallSets;
-using sandbox::bpf_dsl::Allow;
-using sandbox::bpf_dsl::Arg;
-using sandbox::bpf_dsl::Error;
-using sandbox::bpf_dsl::ResultExpr;
-
-namespace content {
-
-namespace {
-
-ResultExpr RestrictIoctl() {
- const Arg<unsigned long> request(1);
- return Switch(request)
- .SANDBOX_BPF_DSL_CASES((static_cast<unsigned long>(TCGETS), FIONREAD),
- Allow())
-#if defined(OS_CHROMEOS)
- .SANDBOX_BPF_DSL_CASES(
- (static_cast<unsigned long>(LOCAL_DMA_BUF_IOCTL_SYNC)), Allow())
-#endif
- .Default(sandbox::CrashSIGSYSIoctl());
-}
-
-} // namespace
-
-RendererProcessPolicy::RendererProcessPolicy() {}
-RendererProcessPolicy::~RendererProcessPolicy() {}
-
-ResultExpr RendererProcessPolicy::EvaluateSyscall(int sysno) const {
- switch (sysno) {
- // The baseline policy allows __NR_clock_gettime. Allow
- // clock_getres() for V8. crbug.com/329053.
- case __NR_clock_getres:
- return sandbox::RestrictClockID();
- case __NR_ioctl:
- return RestrictIoctl();
- // Allow the system calls below.
- case __NR_fdatasync:
- case __NR_fsync:
-#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \
- defined(__aarch64__)
- case __NR_getrlimit:
- case __NR_setrlimit:
-// We allow setrlimit to dynamically adjust the address space limit as
-// needed for WebAssembly memory objects (https://crbug.com/750378). Even
-// with setrlimit being allowed, we cannot raise rlim_max once it's
-// lowered. Thus we generally have the same protection because we normally
-// set rlim_max and rlim_cur together.
-//
-// See LinuxSandbox::LimitAddressSpace() in
-// content/common/sandbox_linux/sandbox_linux.cc and
-// ArrayBufferContents::ReserveMemory,
-// ArrayBufferContents::ReleaseReservedMemory in
-// third_party/WebKit/Source/platform/wtf/typed_arrays/ArrayBufferContents.cpp.
-#endif
-#if defined(__i386__) || defined(__arm__)
- case __NR_ugetrlimit:
-#endif
- case __NR_mremap: // See crbug.com/149834.
- case __NR_pread64:
- case __NR_pwrite64:
- case __NR_sched_get_priority_max:
- case __NR_sched_get_priority_min:
- case __NR_sysinfo:
- case __NR_times:
- case __NR_uname:
- return Allow();
- case __NR_sched_getaffinity:
- case __NR_sched_getparam:
- case __NR_sched_getscheduler:
- case __NR_sched_setscheduler:
- return sandbox::RestrictSchedTarget(GetPolicyPid(), sysno);
- case __NR_prlimit64:
- // See crbug.com/662450 and setrlimit comment above.
- return sandbox::RestrictPrlimit(GetPolicyPid());
- default:
- // Default on the content baseline policy.
- return SandboxBPFBasePolicy::EvaluateSyscall(sysno);
- }
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.h b/chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.h
deleted file mode 100644
index e5a0b405989..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_renderer_policy_linux.h
+++ /dev/null
@@ -1,28 +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_COMMON_SANDBOX_LINUX_BPF_RENDERER_POLICY_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_BPF_RENDERER_POLICY_LINUX_H_
-
-#include "base/macros.h"
-#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
-
-namespace content {
-
-// This policy can be used by both renderer and worker processes.
-class RendererProcessPolicy : public SandboxBPFBasePolicy {
- public:
- RendererProcessPolicy();
- ~RendererProcessPolicy() override;
-
- sandbox::bpf_dsl::ResultExpr EvaluateSyscall(
- int system_call_number) const override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RendererProcessPolicy);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_RENDERER_POLICY_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/bpf_utility_policy_linux.cc b/chromium/content/common/sandbox_linux/bpf_utility_policy_linux.cc
deleted file mode 100644
index 13367964e64..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_utility_policy_linux.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/sandbox_linux/bpf_utility_policy_linux.h"
-
-#include <errno.h>
-
-#include "build/build_config.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
-#include "sandbox/linux/system_headers/linux_syscalls.h"
-
-using sandbox::SyscallSets;
-using sandbox::bpf_dsl::Allow;
-using sandbox::bpf_dsl::Error;
-using sandbox::bpf_dsl::ResultExpr;
-
-namespace content {
-
-UtilityProcessPolicy::UtilityProcessPolicy() {
-}
-UtilityProcessPolicy::~UtilityProcessPolicy() {
-}
-
-ResultExpr UtilityProcessPolicy::EvaluateSyscall(int sysno) const {
- switch (sysno) {
- case __NR_ioctl:
- return sandbox::RestrictIoctl();
- // Allow the system calls below.
- case __NR_fdatasync:
- case __NR_fsync:
-#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \
- defined(__aarch64__)
- case __NR_getrlimit:
-#endif
-#if defined(__i386__) || defined(__arm__)
- case __NR_ugetrlimit:
-#endif
- case __NR_mremap: // https://crbug.com/546204
- case __NR_pread64:
- case __NR_pwrite64:
- case __NR_sysinfo:
- case __NR_times:
- case __NR_uname:
- return Allow();
- default:
- // Default on the content baseline policy.
- return SandboxBPFBasePolicy::EvaluateSyscall(sysno);
- }
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/bpf_utility_policy_linux.h b/chromium/content/common/sandbox_linux/bpf_utility_policy_linux.h
deleted file mode 100644
index b11dbcc257a..00000000000
--- a/chromium/content/common/sandbox_linux/bpf_utility_policy_linux.h
+++ /dev/null
@@ -1,28 +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_COMMON_SANDBOX_LINUX_BPF_UTILITY_POLICY_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_BPF_UTILITY_POLICY_LINUX_H_
-
-#include "base/macros.h"
-#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
-
-namespace content {
-
-// This policy can be used by utility processes.
-class UtilityProcessPolicy : public SandboxBPFBasePolicy {
- public:
- UtilityProcessPolicy();
- ~UtilityProcessPolicy() override;
-
- sandbox::bpf_dsl::ResultExpr EvaluateSyscall(
- int system_call_number) const override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(UtilityProcessPolicy);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_UTILITY_POLICY_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.cc b/chromium/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.cc
deleted file mode 100644
index 75bfe22c56e..00000000000
--- a/chromium/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.cc
+++ /dev/null
@@ -1,46 +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/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
-
-#include <errno.h>
-
-#include "base/logging.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
-#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
-
-using sandbox::bpf_dsl::ResultExpr;
-
-namespace content {
-
-namespace {
-
-// The errno used for denied file system access system calls, such as open(2).
-static const int kFSDeniedErrno = EPERM;
-
-} // namespace.
-
-SandboxBPFBasePolicy::SandboxBPFBasePolicy()
- : baseline_policy_(new sandbox::BaselinePolicy(kFSDeniedErrno)) {}
-SandboxBPFBasePolicy::~SandboxBPFBasePolicy() {}
-
-ResultExpr SandboxBPFBasePolicy::EvaluateSyscall(int system_call_number) const {
- DCHECK(baseline_policy_);
- return baseline_policy_->EvaluateSyscall(system_call_number);
-}
-
-ResultExpr SandboxBPFBasePolicy::InvalidSyscall() const {
- DCHECK(baseline_policy_);
- return baseline_policy_->InvalidSyscall();
-}
-
-bool SandboxBPFBasePolicy::PreSandboxHook() {
- return true;
-}
-
-int SandboxBPFBasePolicy::GetFSDeniedErrno() {
- return kFSDeniedErrno;
-}
-
-} // namespace content.
diff --git a/chromium/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h b/chromium/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h
deleted file mode 100644
index a5cc04f6497..00000000000
--- a/chromium/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h
+++ /dev/null
@@ -1,51 +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_COMMON_SANDBOX_LINUX_SANDBOX_BPF_BASE_POLICY_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_BPF_BASE_POLICY_LINUX_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h"
-#include "sandbox/linux/bpf_dsl/policy.h"
-#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
-
-namespace content {
-
-// The "baseline" BPF policy for content/. Any content/ seccomp-bpf policy
-// should inherit from it.
-// It implements the main Policy interface. Due to its nature
-// as a "kernel attack surface reduction" layer, it's implementation-defined.
-class SandboxBPFBasePolicy : public sandbox::bpf_dsl::Policy {
- public:
- SandboxBPFBasePolicy();
- ~SandboxBPFBasePolicy() override;
-
- sandbox::bpf_dsl::ResultExpr EvaluateSyscall(
- int system_call_number) const override;
- sandbox::bpf_dsl::ResultExpr InvalidSyscall() const override;
-
- // A policy can implement this hook to run code right before the policy
- // is passed to the BPF compiler and the sandbox is engaged.
- // If PreSandboxHook() returns true, the sandbox is guaranteed to be
- // engaged afterwards.
- // This will be used when enabling the sandbox though
- // SandboxSeccompBPF::StartSandbox().
- virtual bool PreSandboxHook();
-
- // Get the errno(3) to return for filesystem errors.
- static int GetFSDeniedErrno();
-
- pid_t GetPolicyPid() const { return baseline_policy_->policy_pid(); }
-
- private:
- // Compose the BaselinePolicy from sandbox/.
- std::unique_ptr<sandbox::BaselinePolicy> baseline_policy_;
- DISALLOW_COPY_AND_ASSIGN(SandboxBPFBasePolicy);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_BPF_BASE_POLICY_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/sandbox_debug_handling_linux.cc b/chromium/content/common/sandbox_linux/sandbox_debug_handling_linux.cc
deleted file mode 100644
index 65da474e4ed..00000000000
--- a/chromium/content/common/sandbox_linux/sandbox_debug_handling_linux.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/sandbox_linux/sandbox_debug_handling_linux.h"
-
-#include <errno.h>
-#include <signal.h>
-#include <stddef.h>
-#include <sys/prctl.h>
-#include <unistd.h>
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/strings/safe_sprintf.h"
-#include "content/public/common/content_switches.h"
-
-namespace content {
-
-namespace {
-
-void DoChrootSignalHandler(int) {
- const int old_errno = errno;
- const char kFirstMessage[] = "Chroot signal handler called.\n";
- ignore_result(write(STDERR_FILENO, kFirstMessage, sizeof(kFirstMessage) - 1));
-
- const int chroot_ret = chroot("/");
-
- char kSecondMessage[100];
- const ssize_t printed = base::strings::SafeSPrintf(
- kSecondMessage, "chroot() returned %d. Errno is %d.\n", chroot_ret,
- errno);
- if (printed > 0 && printed < static_cast<ssize_t>(sizeof(kSecondMessage))) {
- ignore_result(write(STDERR_FILENO, kSecondMessage, printed));
- }
- errno = old_errno;
-}
-
-// This is a quick hack to allow testing sandbox crash reports in production
-// binaries.
-// This installs a signal handler for SIGUSR2 that performs a chroot().
-// In most of our BPF policies, it is a "watched" system call which will
-// trigger a SIGSYS signal whose handler will crash.
-// This has been added during the investigation of https://crbug.com/415842.
-void InstallCrashTestHandler() {
- struct sigaction act = {};
- act.sa_handler = DoChrootSignalHandler;
- CHECK_EQ(0, sigemptyset(&act.sa_mask));
- act.sa_flags = 0;
-
- PCHECK(0 == sigaction(SIGUSR2, &act, NULL));
-}
-
-bool IsSandboxDebuggingEnabled() {
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- return command_line.HasSwitch(switches::kAllowSandboxDebugging);
-}
-
-} // namespace
-
-// static
-bool SandboxDebugHandling::SetDumpableStatusAndHandlers() {
- if (IsSandboxDebuggingEnabled()) {
- // If sandbox debugging is allowed, install a handler for sandbox-related
- // crash testing.
- InstallCrashTestHandler();
- return true;
- }
-
- if (prctl(PR_SET_DUMPABLE, 0) != 0) {
- PLOG(ERROR) << "Failed to set non-dumpable flag";
- return false;
- }
-
- return prctl(PR_GET_DUMPABLE) == 0;
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/sandbox_debug_handling_linux.h b/chromium/content/common/sandbox_linux/sandbox_debug_handling_linux.h
deleted file mode 100644
index 248b54b43e7..00000000000
--- a/chromium/content/common/sandbox_linux/sandbox_debug_handling_linux.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_DEBUG_HANDLING_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_DEBUG_HANDLING_LINUX_H_
-
-#include "base/macros.h"
-
-namespace content {
-
-class SandboxDebugHandling {
- public:
- // Depending on the command line, set the current process as
- // non dumpable. Also set any signal handlers for sandbox
- // debugging.
- static bool SetDumpableStatusAndHandlers();
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(SandboxDebugHandling);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_DEBUG_HANDLING_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/sandbox_linux.cc b/chromium/content/common/sandbox_linux/sandbox_linux.cc
deleted file mode 100644
index 420a72e481c..00000000000
--- a/chromium/content/common/sandbox_linux/sandbox_linux.cc
+++ /dev/null
@@ -1,490 +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/common/sandbox_linux/sandbox_linux.h"
-
-#include <dirent.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <limits>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/command_line.h"
-#include "base/debug/stack_trace.h"
-#include "base/feature_list.h"
-#include "base/files/scoped_file.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/singleton.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/sys_info.h"
-#include "base/time/time.h"
-#include "build/build_config.h"
-#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h"
-#include "content/public/common/content_features.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/sandbox_linux.h"
-#include "gpu/config/gpu_info.h"
-#include "sandbox/linux/services/credentials.h"
-#include "sandbox/linux/services/namespace_sandbox.h"
-#include "sandbox/linux/services/proc_util.h"
-#include "sandbox/linux/services/resource_limits.h"
-#include "sandbox/linux/services/thread_helpers.h"
-#include "sandbox/linux/services/yama.h"
-#include "sandbox/linux/suid/client/setuid_sandbox_client.h"
-#include "services/service_manager/sandbox/sandbox_type.h"
-#include "third_party/angle/src/gpu_info_util/SystemInfo.h"
-
-#if defined(ANY_OF_AMTLU_SANITIZER)
-#include <sanitizer/common_interface_defs.h>
-#endif
-
-using sandbox::Yama;
-
-namespace {
-
-struct FDCloser {
- inline void operator()(int* fd) const {
- DCHECK(fd);
- PCHECK(0 == IGNORE_EINTR(close(*fd)));
- *fd = -1;
- }
-};
-
-void LogSandboxStarted(const std::string& sandbox_name) {
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- const std::string process_type =
- command_line.GetSwitchValueASCII(switches::kProcessType);
- const std::string activated_sandbox =
- "Activated " + sandbox_name + " sandbox for process type: " +
- process_type + ".";
- VLOG(1) << activated_sandbox;
-}
-
-bool IsRunningTSAN() {
-#if defined(THREAD_SANITIZER)
- return true;
-#else
- return false;
-#endif
-}
-
-// Get a file descriptor to /proc. Either duplicate |proc_fd| or try to open
-// it by using the filesystem directly.
-// TODO(jln): get rid of this ugly interface.
-base::ScopedFD OpenProc(int proc_fd) {
- int ret_proc_fd = -1;
- if (proc_fd >= 0) {
- // If a handle to /proc is available, use it. This allows to bypass file
- // system restrictions.
- ret_proc_fd =
- HANDLE_EINTR(openat(proc_fd, ".", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
- } else {
- // Otherwise, make an attempt to access the file system directly.
- ret_proc_fd = HANDLE_EINTR(
- openat(AT_FDCWD, "/proc/", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
- }
- DCHECK_LE(0, ret_proc_fd);
- return base::ScopedFD(ret_proc_fd);
-}
-
-} // namespace
-
-namespace content {
-
-LinuxSandbox::LinuxSandbox()
- : proc_fd_(-1),
- seccomp_bpf_started_(false),
- sandbox_status_flags_(kSandboxLinuxInvalid),
- pre_initialized_(false),
- seccomp_bpf_supported_(false),
- seccomp_bpf_with_tsync_supported_(false),
- yama_is_enforcing_(false),
- initialize_sandbox_ran_(false),
- setuid_sandbox_client_(sandbox::SetuidSandboxClient::Create()) {
- if (setuid_sandbox_client_ == NULL) {
- LOG(FATAL) << "Failed to instantiate the setuid sandbox client.";
- }
-#if defined(ANY_OF_AMTLU_SANITIZER)
- sanitizer_args_ = base::WrapUnique(new __sanitizer_sandbox_arguments);
- *sanitizer_args_ = {0};
-#endif
-}
-
-LinuxSandbox::~LinuxSandbox() {
- if (pre_initialized_) {
- CHECK(initialize_sandbox_ran_);
- }
-}
-
-LinuxSandbox* LinuxSandbox::GetInstance() {
- LinuxSandbox* instance = base::Singleton<LinuxSandbox>::get();
- CHECK(instance);
- return instance;
-}
-
-void LinuxSandbox::PreinitializeSandbox() {
- CHECK(!pre_initialized_);
- seccomp_bpf_supported_ = false;
-#if defined(ANY_OF_AMTLU_SANITIZER)
- // Sanitizers need to open some resources before the sandbox is enabled.
- // This should not fork, not launch threads, not open a directory.
- __sanitizer_sandbox_on_notify(sanitizer_args());
- sanitizer_args_.reset();
-#endif
-
- // Open proc_fd_. It would break the security of the setuid sandbox if it was
- // not closed.
- // If LinuxSandbox::PreinitializeSandbox() runs, InitializeSandbox() must run
- // as well.
- proc_fd_ = HANDLE_EINTR(open("/proc", O_DIRECTORY | O_RDONLY | O_CLOEXEC));
- CHECK_GE(proc_fd_, 0);
- // We "pre-warm" the code that detects supports for seccomp BPF.
- if (SandboxSeccompBPF::IsSeccompBPFDesired()) {
- if (!SandboxSeccompBPF::SupportsSandbox()) {
- VLOG(1) << "Lacking support for seccomp-bpf sandbox.";
- } else {
- seccomp_bpf_supported_ = true;
- }
-
- if (SandboxSeccompBPF::SupportsSandboxWithTsync()) {
- seccomp_bpf_with_tsync_supported_ = true;
- }
- }
-
- // Yama is a "global", system-level status. We assume it will not regress
- // after startup.
- const int yama_status = Yama::GetStatus();
- yama_is_enforcing_ = (yama_status & Yama::STATUS_PRESENT) &&
- (yama_status & Yama::STATUS_ENFORCING);
- pre_initialized_ = true;
-}
-
-void LinuxSandbox::EngageNamespaceSandbox() {
- CHECK(pre_initialized_);
- // Check being in a new PID namespace created by the namespace sandbox and
- // being the init process.
- CHECK(sandbox::NamespaceSandbox::InNewPidNamespace());
- const pid_t pid = getpid();
- CHECK_EQ(1, pid);
-
- CHECK(sandbox::Credentials::MoveToNewUserNS());
- // Note: this requires SealSandbox() to be called later in this process to be
- // safe, as this class is keeping a file descriptor to /proc/.
- CHECK(sandbox::Credentials::DropFileSystemAccess(proc_fd_));
-
- // We do not drop CAP_SYS_ADMIN because we need it to place each child process
- // in its own PID namespace later on.
- std::vector<sandbox::Credentials::Capability> caps;
- caps.push_back(sandbox::Credentials::Capability::SYS_ADMIN);
- CHECK(sandbox::Credentials::SetCapabilities(proc_fd_, caps));
-}
-
-std::vector<int> LinuxSandbox::GetFileDescriptorsToClose() {
- std::vector<int> fds;
- if (proc_fd_ >= 0) {
- fds.push_back(proc_fd_);
- }
- return fds;
-}
-
-bool LinuxSandbox::InitializeSandbox(const gpu::GPUInfo* gpu_info) {
- LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance();
- return linux_sandbox->InitializeSandboxImpl(gpu_info);
-}
-
-void LinuxSandbox::StopThread(base::Thread* thread) {
- LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance();
- linux_sandbox->StopThreadImpl(thread);
-}
-
-int LinuxSandbox::GetStatus() {
- if (!pre_initialized_) {
- return 0;
- }
- if (kSandboxLinuxInvalid == sandbox_status_flags_) {
- // Initialize sandbox_status_flags_.
- sandbox_status_flags_ = 0;
- if (setuid_sandbox_client_->IsSandboxed()) {
- sandbox_status_flags_ |= kSandboxLinuxSUID;
- if (setuid_sandbox_client_->IsInNewPIDNamespace())
- sandbox_status_flags_ |= kSandboxLinuxPIDNS;
- if (setuid_sandbox_client_->IsInNewNETNamespace())
- sandbox_status_flags_ |= kSandboxLinuxNetNS;
- } else if (sandbox::NamespaceSandbox::InNewUserNamespace()) {
- sandbox_status_flags_ |= kSandboxLinuxUserNS;
- if (sandbox::NamespaceSandbox::InNewPidNamespace())
- sandbox_status_flags_ |= kSandboxLinuxPIDNS;
- if (sandbox::NamespaceSandbox::InNewNetNamespace())
- sandbox_status_flags_ |= kSandboxLinuxNetNS;
- }
-
- // We report whether the sandbox will be activated when renderers, workers
- // and PPAPI plugins go through sandbox initialization.
- if (seccomp_bpf_supported()) {
- sandbox_status_flags_ |= kSandboxLinuxSeccompBPF;
- }
-
- if (seccomp_bpf_with_tsync_supported()) {
- sandbox_status_flags_ |= kSandboxLinuxSeccompTSYNC;
- }
-
- if (yama_is_enforcing_) {
- sandbox_status_flags_ |= kSandboxLinuxYama;
- }
- }
-
- return sandbox_status_flags_;
-}
-
-// Threads are counted via /proc/self/task. This is a little hairy because of
-// PID namespaces and existing sandboxes, so "self" must really be used instead
-// of using the pid.
-bool LinuxSandbox::IsSingleThreaded() const {
- base::ScopedFD proc_fd(OpenProc(proc_fd_));
-
- CHECK(proc_fd.is_valid()) << "Could not count threads, the sandbox was not "
- << "pre-initialized properly.";
-
- const bool is_single_threaded =
- sandbox::ThreadHelpers::IsSingleThreaded(proc_fd.get());
-
- return is_single_threaded;
-}
-
-bool LinuxSandbox::seccomp_bpf_started() const {
- return seccomp_bpf_started_;
-}
-
-sandbox::SetuidSandboxClient*
- LinuxSandbox::setuid_sandbox_client() const {
- return setuid_sandbox_client_.get();
-}
-
-// For seccomp-bpf, we use the SandboxSeccompBPF class.
-bool LinuxSandbox::StartSeccompBPF(service_manager::SandboxType sandbox_type,
- const gpu::GPUInfo* gpu_info) {
- CHECK(!seccomp_bpf_started_);
- CHECK(pre_initialized_);
- if (!seccomp_bpf_supported())
- return false;
-
- SandboxSeccompBPF::Options opts;
- opts.use_amd_specific_policies =
- gpu_info && angle::IsAMD(gpu_info->active_gpu().vendor_id);
- if (!SandboxSeccompBPF::StartSandbox(sandbox_type, OpenProc(proc_fd_), opts))
- return false;
-
- seccomp_bpf_started_ = true;
- LogSandboxStarted("seccomp-bpf");
- return true;
-}
-
-bool LinuxSandbox::InitializeSandboxImpl(const gpu::GPUInfo* gpu_info) {
- DCHECK(!initialize_sandbox_ran_);
- initialize_sandbox_ran_ = true;
-
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- const std::string process_type =
- command_line->GetSwitchValueASCII(switches::kProcessType);
- service_manager::SandboxType sandbox_type =
- service_manager::SandboxTypeFromCommandLine(*command_line);
-
- // We need to make absolutely sure that our sandbox is "sealed" before
- // returning.
- // Unretained() since the current object is a Singleton.
- base::ScopedClosureRunner sandbox_sealer(
- base::BindOnce(&LinuxSandbox::SealSandbox, base::Unretained(this)));
- // Make sure that this function enables sandboxes as promised by GetStatus().
- // Unretained() since the current object is a Singleton.
- base::ScopedClosureRunner sandbox_promise_keeper(
- base::BindOnce(&LinuxSandbox::CheckForBrokenPromises,
- base::Unretained(this), sandbox_type));
-
- // No matter what, it's always an error to call InitializeSandbox() after
- // threads have been created.
- if (!IsSingleThreaded()) {
- std::string error_message =
- "InitializeSandbox() called with multiple threads in process " +
- process_type + ".";
- // TSAN starts a helper thread, so we don't start the sandbox and don't
- // even report an error about it.
- if (IsRunningTSAN())
- return false;
-
-#if defined(OS_CHROMEOS)
- if (base::SysInfo::IsRunningOnChromeOS() &&
- process_type == switches::kGpuProcess) {
- error_message += " This error can be safely ignored in VMTests.";
- }
-#endif
-
- // The GPU process is allowed to call InitializeSandbox() with threads.
- bool sandbox_failure_fatal = process_type != switches::kGpuProcess;
- // This can be disabled with the '--gpu-sandbox-failures-fatal' flag.
- // Setting the flag with no value or any value different than 'yes' or 'no'
- // is equal to setting '--gpu-sandbox-failures-fatal=yes'.
- if (process_type == switches::kGpuProcess &&
- command_line->HasSwitch(switches::kGpuSandboxFailuresFatal)) {
- const std::string switch_value =
- command_line->GetSwitchValueASCII(switches::kGpuSandboxFailuresFatal);
- sandbox_failure_fatal = switch_value != "no";
- }
-
- if (sandbox_failure_fatal)
- LOG(FATAL) << error_message;
-
- LOG(ERROR) << error_message;
- return false;
- }
-
- // Only one thread is running, pre-initialize if not already done.
- if (!pre_initialized_)
- PreinitializeSandbox();
-
- DCHECK(!HasOpenDirectories()) <<
- "InitializeSandbox() called after unexpected directories have been " <<
- "opened. This breaks the security of the setuid sandbox.";
-
- // Attempt to limit the future size of the address space of the process.
- LimitAddressSpace(process_type);
-
- // Try to enable seccomp-bpf.
- bool seccomp_bpf_started = StartSeccompBPF(sandbox_type, gpu_info);
-
- return seccomp_bpf_started;
-}
-
-void LinuxSandbox::StopThreadImpl(base::Thread* thread) {
- DCHECK(thread);
- StopThreadAndEnsureNotCounted(thread);
-}
-
-bool LinuxSandbox::seccomp_bpf_supported() const {
- CHECK(pre_initialized_);
- return seccomp_bpf_supported_;
-}
-
-bool LinuxSandbox::seccomp_bpf_with_tsync_supported() const {
- CHECK(pre_initialized_);
- return seccomp_bpf_with_tsync_supported_;
-}
-
-bool LinuxSandbox::LimitAddressSpace(const std::string& process_type) {
- (void) process_type;
-#if !defined(ANY_OF_AMTLU_SANITIZER)
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- if (service_manager::SandboxTypeFromCommandLine(*command_line) ==
- service_manager::SANDBOX_TYPE_NO_SANDBOX) {
- return false;
- }
- // Limit the address space to 4GB.
- // This is in the hope of making some kernel exploits more complex and less
- // reliable. It also limits sprays a little on 64 bits.
- rlim_t address_space_limit = std::numeric_limits<uint32_t>::max();
- rlim_t address_space_limit_max = std::numeric_limits<uint32_t>::max();
-
- if (sizeof(rlim_t) == 8) {
- // On 64 bits, V8 and possibly others will reserve massive memory ranges and
- // rely on on-demand paging for allocation. Unfortunately, even
- // MADV_DONTNEED ranges count towards RLIMIT_AS so this is not an option.
- // See crbug.com/169327 for a discussion.
- // On the GPU process, irrespective of V8, we can exhaust a 4GB address
- // space under normal usage, see crbug.com/271119.
- // For now, increase limit to 16GB for renderer, worker, and GPU processes
- // to accomodate.
- if (process_type == switches::kRendererProcess ||
- process_type == switches::kGpuProcess) {
- address_space_limit = 1ULL << 34;
- // WebAssembly memory objects use a large amount of address space when
- // trap-based bounds checks are enabled. To accomodate this, we allow the
- // address space limit to adjust dynamically up to a certain limit. The
- // limit is currently 4TiB, which should allow enough address space for
- // any reasonable page. See https://crbug.com/750378.
- if (base::FeatureList::IsEnabled(features::kWebAssemblyTrapHandler)) {
- address_space_limit_max = 1ULL << 42;
- } else {
- // If we are not using trap-based bounds checks, there's no reason to
- // allow the address space limit to grow.
- address_space_limit_max = address_space_limit;
- }
- }
- }
-
- // By default, add a limit to the VmData memory area that would prevent
- // allocations that can't be index by an int.
- rlim_t new_data_segment_max_size = std::numeric_limits<int>::max();
-
- if (sizeof(rlim_t) == 8) {
- // On 64 bits, increase the RLIMIT_DATA limit to 8GB.
- // RLIMIT_DATA did not account for mmap()-ed memory until
- // https://github.com/torvalds/linux/commit/84638335900f1995495838fe1bd4870c43ec1f6.
- // When Chrome runs on devices with this patch, it will OOM very easily.
- // See https://crbug.com/752185.
- new_data_segment_max_size = 1ULL << 33;
- }
-
- bool limited_as = sandbox::ResourceLimits::LowerSoftAndHardLimits(
- RLIMIT_AS, address_space_limit, address_space_limit_max);
- bool limited_data =
- sandbox::ResourceLimits::Lower(RLIMIT_DATA, new_data_segment_max_size);
-
- // Cache the resource limit before turning on the sandbox.
- base::SysInfo::AmountOfVirtualMemory();
-
- return limited_as && limited_data;
-#else
- base::SysInfo::AmountOfVirtualMemory();
- return false;
-#endif // !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) &&
- // !defined(THREAD_SANITIZER)
-}
-
-bool LinuxSandbox::HasOpenDirectories() const {
- return sandbox::ProcUtil::HasOpenDirectory(proc_fd_);
-}
-
-void LinuxSandbox::SealSandbox() {
- if (proc_fd_ >= 0) {
- int ret = IGNORE_EINTR(close(proc_fd_));
- CHECK_EQ(0, ret);
- proc_fd_ = -1;
- }
-}
-
-void LinuxSandbox::CheckForBrokenPromises(
- service_manager::SandboxType sandbox_type) {
- if (sandbox_type != service_manager::SANDBOX_TYPE_RENDERER &&
- sandbox_type != service_manager::SANDBOX_TYPE_PPAPI) {
- return;
- }
- // Make sure that any promise made with GetStatus() wasn't broken.
- bool promised_seccomp_bpf_would_start =
- (sandbox_status_flags_ != kSandboxLinuxInvalid) &&
- (GetStatus() & kSandboxLinuxSeccompBPF);
- CHECK(!promised_seccomp_bpf_would_start || seccomp_bpf_started_);
-}
-
-void LinuxSandbox::StopThreadAndEnsureNotCounted(base::Thread* thread) const {
- DCHECK(thread);
- base::ScopedFD proc_fd(OpenProc(proc_fd_));
- PCHECK(proc_fd.is_valid());
- CHECK(
- sandbox::ThreadHelpers::StopThreadAndWatchProcFS(proc_fd.get(), thread));
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/sandbox_linux.h b/chromium/content/common/sandbox_linux/sandbox_linux.h
deleted file mode 100644
index 684075c3bd7..00000000000
--- a/chromium/content/common/sandbox_linux/sandbox_linux.h
+++ /dev/null
@@ -1,195 +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_SANDBOX_LINUX_SANDBOX_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_LINUX_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/posix/global_descriptors.h"
-#include "content/public/common/content_descriptors.h"
-#include "content/public/common/sandbox_linux.h"
-#include "gpu/config/gpu_info.h"
-#include "services/service_manager/sandbox/sandbox_type.h"
-
-#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
- defined(THREAD_SANITIZER) || defined(LEAK_SANITIZER) || \
- defined(UNDEFINED_SANITIZER) || defined(SANITIZER_COVERAGE)
-#include <sanitizer/common_interface_defs.h>
-#define ANY_OF_AMTLU_SANITIZER 1
-#endif
-
-namespace base {
-template <typename T>
-struct DefaultSingletonTraits;
-class Thread;
-}
-namespace sandbox { class SetuidSandboxClient; }
-
-namespace content {
-
-inline int GetSandboxFD() {
- return kSandboxIPCChannel + base::GlobalDescriptors::kBaseDescriptor;
-}
-
-// A singleton class to represent and change our sandboxing state for the
-// three main Linux sandboxes.
-// The sandboxing model allows using two layers of sandboxing. The first layer
-// can be implemented either with unprivileged namespaces or with the setuid
-// sandbox. This class provides a way to engage the namespace sandbox, but does
-// not deal with the legacy setuid sandbox directly.
-// The second layer is mainly based on seccomp-bpf and is engaged with
-// InitializeSandbox(). InitializeSandbox() is also responsible for "sealing"
-// the first layer of sandboxing. That is, InitializeSandbox must always be
-// called to have any meaningful sandboxing at all.
-class LinuxSandbox {
- public:
- // This is a list of sandbox IPC methods which the renderer may send to the
- // sandbox host. See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md
- // This isn't the full list, values < 32 are reserved for methods called from
- // Skia.
- enum LinuxSandboxIPCMethods {
- METHOD_GET_FALLBACK_FONT_FOR_CHAR = 32,
- METHOD_LOCALTIME = 33,
- DEPRECATED_METHOD_GET_CHILD_WITH_INODE = 34,
- METHOD_GET_STYLE_FOR_STRIKE = 35,
- METHOD_MAKE_SHARED_MEMORY_SEGMENT = 36,
- METHOD_MATCH_WITH_FALLBACK = 37,
- };
-
- // Get our singleton instance.
- static LinuxSandbox* GetInstance();
-
- // Do some initialization that can only be done before any of the sandboxes
- // are enabled. If using the setuid sandbox, this should be called manually
- // before the setuid sandbox is engaged.
- // Security: When this runs, it is imperative that either InitializeSandbox()
- // runs as well or that all file descriptors returned in
- // GetFileDescriptorsToClose() get closed.
- // Otherwise file descriptors that bypass the security of the setuid sandbox
- // would be kept open. One must be particularly careful if a process performs
- // a fork().
- void PreinitializeSandbox();
-
- // Check that the current process is the init process of a new PID
- // namespace and then proceed to drop access to the file system by using
- // a new unprivileged namespace. This is a layer-1 sandbox.
- // In order for this sandbox to be effective, it must be "sealed" by calling
- // InitializeSandbox().
- void EngageNamespaceSandbox();
-
- // Return a list of file descriptors to close if PreinitializeSandbox() ran
- // but InitializeSandbox() won't. Avoid using.
- // TODO(jln): get rid of this hack.
- std::vector<int> GetFileDescriptorsToClose();
-
- // Seal an eventual layer-1 sandbox and initialize the layer-2 sandbox with
- // an adequate policy depending on the process type and command line
- // arguments.
- // Currently the layer-2 sandbox is composed of seccomp-bpf and address space
- // limitations. This will instantiate the LinuxSandbox singleton if it
- // doesn't already exist.
- // This function should only be called without any thread running.
- static bool InitializeSandbox(const gpu::GPUInfo* gpu_info = NULL);
-
- // Stop |thread| in a way that can be trusted by the sandbox.
- static void StopThread(base::Thread* thread);
-
- // Returns the status of the renderer, worker and ppapi sandbox. Can only
- // be queried after going through PreinitializeSandbox(). This is a bitmask
- // and uses the constants defined in "enum LinuxSandboxStatus". Since the
- // status needs to be provided before the sandboxes are actually started,
- // this returns what will actually happen once InitializeSandbox()
- // is called from inside these processes.
- int GetStatus();
- // Returns true if the current process is single-threaded or if the number
- // of threads cannot be determined.
- bool IsSingleThreaded() const;
- // Did we start Seccomp BPF?
- bool seccomp_bpf_started() const;
-
- // Simple accessor for our instance of the setuid sandbox. Will never return
- // NULL.
- // There is no StartSetuidSandbox(), the SetuidSandboxClient instance should
- // be used directly.
- sandbox::SetuidSandboxClient* setuid_sandbox_client() const;
-
- // Check the policy and eventually start the seccomp-bpf sandbox. This should
- // never be called with threads started. If we detect that threads have
- // started we will crash.
- bool StartSeccompBPF(service_manager::SandboxType sandbox_type,
- const gpu::GPUInfo* gpu_info);
-
- // Limit the address space of the current process (and its children).
- // to make some vulnerabilities harder to exploit.
- bool LimitAddressSpace(const std::string& process_type);
-
- // Returns a file descriptor to proc. The file descriptor is no longer valid
- // after the sandbox has been sealed.
- int proc_fd() const {
- DCHECK_NE(-1, proc_fd_);
- return proc_fd_;
- }
-
-#if defined(ANY_OF_AMTLU_SANITIZER)
- __sanitizer_sandbox_arguments* sanitizer_args() const {
- return sanitizer_args_.get();
- };
-#endif
-
- private:
- friend struct base::DefaultSingletonTraits<LinuxSandbox>;
-
- LinuxSandbox();
- ~LinuxSandbox();
-
- // Some methods are static and get an instance of the Singleton. These
- // are the non-static implementations.
- bool InitializeSandboxImpl(const gpu::GPUInfo* gpu_info);
- void StopThreadImpl(base::Thread* thread);
- // We must have been pre_initialized_ before using these.
- bool seccomp_bpf_supported() const;
- bool seccomp_bpf_with_tsync_supported() const;
- // Returns true if it can be determined that the current process has open
- // directories that are not managed by the LinuxSandbox class. This would
- // be a vulnerability as it would allow to bypass the setuid sandbox.
- bool HasOpenDirectories() const;
- // The last part of the initialization is to make sure any temporary "hole"
- // in the sandbox is closed. For now, this consists of closing proc_fd_.
- void SealSandbox();
- // GetStatus() makes promises as to how the sandbox will behave. This
- // checks that no promises have been broken.
- void CheckForBrokenPromises(service_manager::SandboxType sandbox_type);
- // Stop |thread| and make sure it does not appear in /proc/self/tasks/
- // anymore.
- void StopThreadAndEnsureNotCounted(base::Thread* thread) const;
-
- // A file descriptor to /proc. It's dangerous to have it around as it could
- // allow for sandbox bypasses. It needs to be closed before we consider
- // ourselves sandboxed.
- int proc_fd_;
- bool seccomp_bpf_started_;
- // The value returned by GetStatus(). Gets computed once and then cached.
- int sandbox_status_flags_;
- // Did PreinitializeSandbox() run?
- bool pre_initialized_;
- bool seccomp_bpf_supported_; // Accurate if pre_initialized_.
- bool seccomp_bpf_with_tsync_supported_; // Accurate if pre_initialized_.
- bool yama_is_enforcing_; // Accurate if pre_initialized_.
- bool initialize_sandbox_ran_; // InitializeSandbox() was called.
- std::unique_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client_;
-#if defined(ANY_OF_AMTLU_SANITIZER)
- std::unique_ptr<__sanitizer_sandbox_arguments> sanitizer_args_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(LinuxSandbox);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_LINUX_H_
diff --git a/chromium/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc b/chromium/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
deleted file mode 100644
index f8e866e1540..00000000000
--- a/chromium/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc
+++ /dev/null
@@ -1,299 +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/common/sandbox_linux/sandbox_seccomp_bpf_linux.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <memory>
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "build/build_config.h"
-#include "content/public/common/content_switches.h"
-#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
-#include "sandbox/sandbox_features.h"
-#include "services/service_manager/sandbox/sandbox_type.h"
-
-#if BUILDFLAG(USE_SECCOMP_BPF)
-
-#include "base/files/scoped_file.h"
-#include "base/posix/eintr_wrapper.h"
-#include "content/common/sandbox_linux/bpf_cdm_policy_linux.h"
-#include "content/common/sandbox_linux/bpf_cros_amd_gpu_policy_linux.h"
-#include "content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h"
-#include "content/common/sandbox_linux/bpf_gpu_policy_linux.h"
-#include "content/common/sandbox_linux/bpf_pdf_compositor_policy_linux.h"
-#include "content/common/sandbox_linux/bpf_ppapi_policy_linux.h"
-#include "content/common/sandbox_linux/bpf_renderer_policy_linux.h"
-#include "content/common/sandbox_linux/bpf_utility_policy_linux.h"
-#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
-#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
-#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
-#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
-#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
-#include "sandbox/linux/system_headers/linux_syscalls.h"
-
-using sandbox::BaselinePolicy;
-using sandbox::SandboxBPF;
-using sandbox::SyscallSets;
-using sandbox::bpf_dsl::Allow;
-using sandbox::bpf_dsl::ResultExpr;
-
-#else // BUILDFLAG(USE_SECCOMP_BPF)
-
-// Make sure that seccomp-bpf does not get disabled by mistake. Also make sure
-// that we think twice about this when adding a new architecture.
-#if !defined(ARCH_CPU_ARM64) && !defined(ARCH_CPU_MIPS64EL)
-#error "Seccomp-bpf disabled on supported architecture!"
-#endif // !defined(ARCH_CPU_ARM64) && !defined(ARCH_CPU_MIPS64EL)
-
-#endif // BUILDFLAG(USE_SECCOMP_BPF)
-
-namespace content {
-
-#if BUILDFLAG(USE_SECCOMP_BPF)
-namespace {
-
-// This function takes ownership of |policy|.
-void StartSandboxWithPolicy(std::unique_ptr<sandbox::bpf_dsl::Policy> policy,
- base::ScopedFD proc_fd) {
- // Starting the sandbox is a one-way operation. The kernel doesn't allow
- // us to unload a sandbox policy after it has been started. Nonetheless,
- // in order to make the use of the "Sandbox" object easier, we allow for
- // the object to be destroyed after the sandbox has been started. Note that
- // doing so does not stop the sandbox.
- SandboxBPF sandbox(std::move(policy));
- sandbox.SetProcFd(std::move(proc_fd));
- CHECK(sandbox.StartSandbox(SandboxBPF::SeccompLevel::SINGLE_THREADED));
-}
-
-#if !defined(OS_NACL_NONSFI)
-
-class BlacklistDebugAndNumaPolicy : public SandboxBPFBasePolicy {
- public:
- BlacklistDebugAndNumaPolicy() {}
- ~BlacklistDebugAndNumaPolicy() override {}
-
- ResultExpr EvaluateSyscall(int system_call_number) const override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BlacklistDebugAndNumaPolicy);
-};
-
-ResultExpr BlacklistDebugAndNumaPolicy::EvaluateSyscall(int sysno) const {
- if (SyscallSets::IsDebug(sysno) || SyscallSets::IsNuma(sysno))
- return sandbox::CrashSIGSYS();
-
- return Allow();
-}
-
-class AllowAllPolicy : public SandboxBPFBasePolicy {
- public:
- AllowAllPolicy() {}
- ~AllowAllPolicy() override {}
-
- ResultExpr EvaluateSyscall(int system_call_number) const override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy);
-};
-
-// Allow all syscalls.
-// This will still deny x32 or IA32 calls in 64 bits mode or
-// 64 bits system calls in compatibility mode.
-ResultExpr AllowAllPolicy::EvaluateSyscall(int sysno) const {
- return Allow();
-}
-
-// nacl_helper needs to be tiny and includes only part of content/
-// in its dependencies. Make sure to not link things that are not needed.
-#if !defined(IN_NACL_HELPER)
-inline bool IsChromeOS() {
-#if defined(OS_CHROMEOS)
- return true;
-#else
- return false;
-#endif
-}
-
-inline bool IsArchitectureArm() {
-#if defined(__arm__)
- return true;
-#else
- return false;
-#endif
-}
-
-// If a BPF policy is engaged for |process_type|, run a few sanity checks.
-void RunSandboxSanityChecks(service_manager::SandboxType sandbox_type) {
- switch (sandbox_type) {
- case service_manager::SANDBOX_TYPE_RENDERER:
- case service_manager::SANDBOX_TYPE_GPU:
- case service_manager::SANDBOX_TYPE_PPAPI:
- case service_manager::SANDBOX_TYPE_PDF_COMPOSITOR:
- case service_manager::SANDBOX_TYPE_CDM: {
- int syscall_ret;
- errno = 0;
-
- // Without the sandbox, this would EBADF.
- syscall_ret = fchmod(-1, 07777);
- CHECK_EQ(-1, syscall_ret);
- CHECK_EQ(EPERM, errno);
-
-// Run most of the sanity checks only in DEBUG mode to avoid a perf.
-// impact.
-#if !defined(NDEBUG)
- // open() must be restricted.
- syscall_ret = open("/etc/passwd", O_RDONLY);
- CHECK_EQ(-1, syscall_ret);
- CHECK_EQ(SandboxBPFBasePolicy::GetFSDeniedErrno(), errno);
-
- // We should never allow the creation of netlink sockets.
- syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0);
- CHECK_EQ(-1, syscall_ret);
- CHECK_EQ(EPERM, errno);
-#endif // !defined(NDEBUG)
- } break;
- default:
- // Otherwise, no checks required.
- break;
- }
-}
-
-std::unique_ptr<SandboxBPFBasePolicy> GetGpuProcessSandbox(
- bool use_amd_specific_policies) {
- if (IsChromeOS()) {
- if (IsArchitectureArm()) {
- return std::make_unique<CrosArmGpuProcessPolicy>(
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kGpuSandboxAllowSysVShm));
- }
- if (use_amd_specific_policies)
- return std::make_unique<CrosAmdGpuProcessPolicy>();
- }
- return std::make_unique<GpuProcessPolicy>();
-}
-
-// Initialize the seccomp-bpf sandbox.
-bool StartBPFSandbox(service_manager::SandboxType sandbox_type,
- base::ScopedFD proc_fd,
- const SandboxSeccompBPF::Options& options) {
- std::unique_ptr<SandboxBPFBasePolicy> policy;
- switch (sandbox_type) {
- case service_manager::SANDBOX_TYPE_GPU:
- policy = GetGpuProcessSandbox(options.use_amd_specific_policies);
- break;
- case service_manager::SANDBOX_TYPE_RENDERER:
- policy = std::make_unique<RendererProcessPolicy>();
- break;
- case service_manager::SANDBOX_TYPE_PPAPI:
- policy = std::make_unique<PpapiProcessPolicy>();
- break;
- case service_manager::SANDBOX_TYPE_UTILITY:
- case service_manager::SANDBOX_TYPE_PROFILING:
- policy = std::make_unique<UtilityProcessPolicy>();
- break;
- case service_manager::SANDBOX_TYPE_CDM:
- policy = std::make_unique<CdmProcessPolicy>();
- break;
- case service_manager::SANDBOX_TYPE_PDF_COMPOSITOR:
- policy = std::make_unique<PdfCompositorProcessPolicy>();
- break;
- case service_manager::SANDBOX_TYPE_NO_SANDBOX:
- default:
- NOTREACHED();
- policy = std::make_unique<AllowAllPolicy>();
- break;
- }
- CHECK(policy->PreSandboxHook());
- StartSandboxWithPolicy(std::move(policy), std::move(proc_fd));
- RunSandboxSanityChecks(sandbox_type);
- return true;
-}
-#endif // !defined(IN_NACL_HELPER)
-#endif // !defined(OS_NACL_NONSFI)
-
-} // namespace
-
-#endif // USE_SECCOMP_BPF
-
-// Is seccomp BPF globally enabled?
-bool SandboxSeccompBPF::IsSeccompBPFDesired() {
-#if BUILDFLAG(USE_SECCOMP_BPF)
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- return !command_line.HasSwitch(switches::kNoSandbox) &&
- !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox);
-#endif // USE_SECCOMP_BPF
- return false;
-}
-
-bool SandboxSeccompBPF::SupportsSandbox() {
-#if BUILDFLAG(USE_SECCOMP_BPF)
- return SandboxBPF::SupportsSeccompSandbox(
- SandboxBPF::SeccompLevel::SINGLE_THREADED);
-#endif
- return false;
-}
-
-#if !defined(OS_NACL_NONSFI)
-
-bool SandboxSeccompBPF::SupportsSandboxWithTsync() {
-#if BUILDFLAG(USE_SECCOMP_BPF)
- return SandboxBPF::SupportsSeccompSandbox(
- SandboxBPF::SeccompLevel::MULTI_THREADED);
-#endif
- return false;
-}
-
-bool SandboxSeccompBPF::StartSandbox(service_manager::SandboxType sandbox_type,
- base::ScopedFD proc_fd,
- const Options& options) {
-#if BUILDFLAG(USE_SECCOMP_BPF)
- if (!IsUnsandboxedSandboxType(sandbox_type) &&
- IsSeccompBPFDesired() && // Global switches policy.
- SupportsSandbox()) {
- // If the kernel supports the sandbox, and if the command line says we
- // should enable it, enable it or die.
- CHECK(StartBPFSandbox(sandbox_type, std::move(proc_fd), options));
- return true;
- }
-#endif
- return false;
-}
-
-#endif // !defined(OS_NACL_NONSFI)
-
-bool SandboxSeccompBPF::StartSandboxWithExternalPolicy(
- std::unique_ptr<sandbox::bpf_dsl::Policy> policy,
- base::ScopedFD proc_fd) {
-#if BUILDFLAG(USE_SECCOMP_BPF)
- if (IsSeccompBPFDesired() && SupportsSandbox()) {
- CHECK(policy);
- StartSandboxWithPolicy(std::move(policy), std::move(proc_fd));
- return true;
- }
-#endif // BUILDFLAG(USE_SECCOMP_BPF)
- return false;
-}
-
-#if !defined(OS_NACL_NONSFI)
-std::unique_ptr<sandbox::bpf_dsl::Policy>
-SandboxSeccompBPF::GetBaselinePolicy() {
-#if BUILDFLAG(USE_SECCOMP_BPF)
- return std::make_unique<BaselinePolicy>();
-#else
- return nullptr;
-#endif // BUILDFLAG(USE_SECCOMP_BPF)
-}
-#endif // !defined(OS_NACL_NONSFI)
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h b/chromium/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h
deleted file mode 100644
index a62300aca5d..00000000000
--- a/chromium/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h
+++ /dev/null
@@ -1,61 +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_SANDBOX_LINUX_SANDBOX_SECCOMP_BPF_LINUX_H_
-#define CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_SECCOMP_BPF_LINUX_H_
-
-#include <memory>
-#include <string>
-
-#include "base/files/scoped_file.h"
-#include "base/macros.h"
-#include "build/build_config.h"
-#include "sandbox/linux/bpf_dsl/policy.h"
-#include "services/service_manager/sandbox/sandbox_type.h"
-
-namespace content {
-
-// This class has two main sets of APIs. One can be used to start the sandbox
-// for internal content process types, the other is indirectly exposed as
-// a public content/ API and uses a supplied policy.
-class SandboxSeccompBPF {
- public:
- struct Options {
- bool use_amd_specific_policies = false; // For ChromiumOs.
- };
-
- // This is the API to enable a seccomp-bpf sandbox for content/
- // process-types:
- // Is the sandbox globally enabled, can anything use it at all ?
- // This looks at global command line flags to see if the sandbox
- // should be enabled at all.
- static bool IsSeccompBPFDesired();
- // Check if the kernel supports seccomp-bpf.
- static bool SupportsSandbox();
-
-#if !defined(OS_NACL_NONSFI)
- // Check if the kernel supports TSYNC (thread synchronization) with seccomp.
- static bool SupportsSandboxWithTsync();
- // Start the sandbox and apply the policy for sandbox_type, depending on
- // command line switches and options.
- static bool StartSandbox(service_manager::SandboxType sandbox_type,
- base::ScopedFD proc_fd,
- const Options& options);
-#endif // !defined(OS_NACL_NONSFI)
-
- // This is the API to enable a seccomp-bpf sandbox by using an
- // external policy.
- static bool StartSandboxWithExternalPolicy(
- std::unique_ptr<sandbox::bpf_dsl::Policy> policy,
- base::ScopedFD proc_fd);
- // The "baseline" policy can be a useful base to build a sandbox policy.
- static std::unique_ptr<sandbox::bpf_dsl::Policy> GetBaselinePolicy();
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(SandboxSeccompBPF);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_SECCOMP_BPF_LINUX_H_
diff --git a/chromium/content/common/sandbox_mac_diraccess_unittest.mm b/chromium/content/common/sandbox_mac_diraccess_unittest.mm
index d105d80d62b..cb6c1523599 100644
--- a/chromium/content/common/sandbox_mac_diraccess_unittest.mm
+++ b/chromium/content/common/sandbox_mac_diraccess_unittest.mm
@@ -72,7 +72,7 @@ TEST_F(MacDirAccessSandboxTest, SandboxAccess) {
// This step is important on OS X since the sandbox only understands "real"
// paths and the paths CreateNewTempDirectory() returns are empirically in
// /var which is a symlink to /private/var .
- tmp_dir = service_manager::Sandbox::GetCanonicalSandboxPath(tmp_dir);
+ tmp_dir = service_manager::SandboxMac::GetCanonicalPath(tmp_dir);
ScopedDirectory cleanup(&tmp_dir);
const char* sandbox_dir_cases[] = {
diff --git a/chromium/content/common/sandbox_mac_fontloading_unittest.mm b/chromium/content/common/sandbox_mac_fontloading_unittest.mm
index b0b0c6309a7..81c06a3abba 100644
--- a/chromium/content/common/sandbox_mac_fontloading_unittest.mm
+++ b/chromium/content/common/sandbox_mac_fontloading_unittest.mm
@@ -12,7 +12,7 @@
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/shared_memory.h"
-#include "content/common/mac/font_descriptor.h"
+#include "base/strings/utf_string_conversions.h"
#include "content/common/mac/font_loader.h"
#include "content/common/sandbox_mac_unittest_helper.h"
#include "services/service_manager/sandbox/sandbox_type.h"
@@ -27,7 +27,7 @@ class FontLoadingTestCase : public MacSandboxTestCase {
bool SandboxedTest() override;
private:
- std::unique_ptr<base::SharedMemory> font_shmem_;
+ mojo::ScopedSharedBufferHandle font_shmem_;
size_t font_data_length_;
};
REGISTER_SANDBOX_TEST_CASE(FontLoadingTestCase);
@@ -47,35 +47,32 @@ bool FontLoadingTestCase::BeforeSandboxInit() {
return false;
}
- font_shmem_.reset(new base::SharedMemory);
- if (!font_shmem_) {
+ font_shmem_ = mojo::SharedBufferHandle::Create(font_data_length_);
+ if (!font_shmem_.is_valid()) {
LOG(ERROR) << "Failed to create shared memory object.";
return false;
}
- if (!font_shmem_->CreateAndMapAnonymous(font_data_length_)) {
- LOG(ERROR) << "SharedMemory::Create failed";
+ mojo::ScopedSharedBufferMapping mapping = font_shmem_->Map(font_data_length_);
+ if (!mapping) {
+ LOG(ERROR) << "ScopedSharedBufferHandle::Map failed";
return false;
}
- memcpy(font_shmem_->memory(), font_data.c_str(), font_data_length_);
- if (!font_shmem_->Unmap()) {
- LOG(ERROR) << "SharedMemory::Unmap failed";
- return false;
- }
+ memcpy(mapping.get(), font_data.c_str(), font_data_length_);
return true;
}
bool FontLoadingTestCase::SandboxedTest() {
- base::SharedMemoryHandle shmem_handle = font_shmem_->handle().Duplicate();
- if (!shmem_handle.IsValid()) {
- LOG(ERROR) << "SharedMemory handle duplication failed";
+ mojo::ScopedSharedBufferHandle shmem_handle = font_shmem_->Clone();
+ if (!shmem_handle.is_valid()) {
+ LOG(ERROR) << "ScopedSharedBufferHandle handle duplication failed";
return false;
}
CGFontRef cg_font_ref;
- if (!FontLoader::CGFontRefFromBuffer(shmem_handle, font_data_length_,
- &cg_font_ref)) {
+ if (!FontLoader::CGFontRefFromBuffer(std::move(shmem_handle),
+ font_data_length_, &cg_font_ref)) {
LOG(ERROR) << "Call to CreateCGFontFromBuffer() failed";
return false;
}
@@ -112,16 +109,18 @@ TEST_F(MacSandboxTest, FontLoadingTest) {
ASSERT_TRUE(temp_file);
base::ScopedFILE temp_file_closer(temp_file);
- NSFont* srcFont = [NSFont fontWithName:@"Geeza Pro" size:16.0];
- FontDescriptor descriptor(srcFont);
std::unique_ptr<FontLoader::ResultInternal> result =
- FontLoader::LoadFontForTesting(descriptor);
+ FontLoader::LoadFontForTesting(base::ASCIIToUTF16("Geeza Pro"), 16);
EXPECT_GT(result->font_data_size, 0U);
EXPECT_GT(result->font_id, 0U);
- base::WriteFileDescriptor(
- fileno(temp_file), static_cast<const char*>(result->font_data.memory()),
- result->font_data_size);
+ mojo::ScopedSharedBufferMapping mapping =
+ result->font_data->Map(result->font_data_size);
+ ASSERT_TRUE(mapping);
+
+ base::WriteFileDescriptor(fileno(temp_file),
+ static_cast<const char*>(mapping.get()),
+ result->font_data_size);
ASSERT_TRUE(RunTestInSandbox(service_manager::SANDBOX_TYPE_RENDERER,
"FontLoadingTestCase",
diff --git a/chromium/content/common/sandbox_mac_unittest_helper.mm b/chromium/content/common/sandbox_mac_unittest_helper.mm
index 6767fa2b7e1..999d96eb3c0 100644
--- a/chromium/content/common/sandbox_mac_unittest_helper.mm
+++ b/chromium/content/common/sandbox_mac_unittest_helper.mm
@@ -156,10 +156,8 @@ MULTIPROCESS_TEST_MAIN(mac_sandbox_test_runner) {
return -1;
}
- service_manager::Sandbox::SandboxWarmup(sandbox_type);
-
- if (!service_manager::Sandbox::EnableSandbox(sandbox_type,
- base::FilePath())) {
+ service_manager::SandboxMac::Warmup(sandbox_type);
+ if (!service_manager::SandboxMac::Enable(sandbox_type, base::FilePath())) {
LOG(ERROR) << "Failed to initialize sandbox " << sandbox_type;
return -1;
}
diff --git a/chromium/content/common/sandbox_policy_fuchsia.cc b/chromium/content/common/sandbox_policy_fuchsia.cc
index 54826f98d7f..c302e852bb5 100644
--- a/chromium/content/common/sandbox_policy_fuchsia.cc
+++ b/chromium/content/common/sandbox_policy_fuchsia.cc
@@ -23,9 +23,11 @@ void UpdateLaunchOptionsForSandbox(service_manager::SandboxType type,
if (type != service_manager::SANDBOX_TYPE_NO_SANDBOX) {
options->clone_flags = LP_CLONE_FDIO_STDIO;
+ options->clear_environ = true;
} else {
- options->clone_flags = LP_CLONE_FDIO_NAMESPACE | LP_CLONE_DEFAULT_JOB |
- LP_CLONE_FDIO_CWD | LP_CLONE_FDIO_STDIO;
+ options->clone_flags =
+ LP_CLONE_FDIO_NAMESPACE | LP_CLONE_DEFAULT_JOB | LP_CLONE_FDIO_STDIO;
+ options->clear_environ = false;
}
}
diff --git a/chromium/content/common/sandbox_win.cc b/chromium/content/common/sandbox_win.cc
deleted file mode 100644
index 3c8150376bb..00000000000
--- a/chromium/content/common/sandbox_win.cc
+++ /dev/null
@@ -1,894 +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/common/sandbox_win.h"
-
-#include <stddef.h>
-
-#include <string>
-
-#include "base/base_switches.h"
-#include "base/command_line.h"
-#include "base/debug/activity_tracker.h"
-#include "base/debug/profiler.h"
-#include "base/feature_list.h"
-#include "base/files/file_util.h"
-#include "base/hash.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/shared_memory.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/path_service.h"
-#include "base/process/launch.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/sys_info.h"
-#include "base/trace_event/trace_event.h"
-#include "base/win/iat_patch_function.h"
-#include "base/win/scoped_handle.h"
-#include "base/win/scoped_process_information.h"
-#include "base/win/win_util.h"
-#include "base/win/windows_version.h"
-#include "content/common/content_switches_internal.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/sandbox_init.h"
-#include "content/public/common/sandboxed_process_launcher_delegate.h"
-#include "sandbox/win/src/process_mitigations.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sandbox_policy_base.h"
-#include "sandbox/win/src/win_utils.h"
-#include "services/service_manager/sandbox/sandbox_type.h"
-
-#if !defined(NACL_WIN64)
-#include "ui/gfx/win/direct_write.h" // nogncheck: unused #ifdef NACL_WIN64
-#endif // !defined(NACL_WIN64)
-
-static sandbox::BrokerServices* g_broker_services = NULL;
-
-namespace content {
-namespace {
-
-// The DLLs listed here are known (or under strong suspicion) of causing crashes
-// when they are loaded in the renderer. Note: at runtime we generate short
-// versions of the dll name only if the dll has an extension.
-// For more information about how this list is generated, and how to get off
-// of it, see:
-// https://sites.google.com/a/chromium.org/dev/Home/third-party-developers
-const wchar_t* const kTroublesomeDlls[] = {
- L"adialhk.dll", // Kaspersky Internet Security.
- L"acpiz.dll", // Unknown.
- L"activedetect32.dll", // Lenovo One Key Theater (crbug.com/536056).
- L"activedetect64.dll", // Lenovo One Key Theater (crbug.com/536056).
- L"airfoilinject3.dll", // Airfoil.
- L"akinsofthook32.dll", // Akinsoft Software Engineering.
- L"assistant_x64.dll", // Unknown.
- L"avcuf64.dll", // Bit Defender Internet Security x64.
- L"avgrsstx.dll", // AVG 8.
- L"babylonchromepi.dll", // Babylon translator.
- L"btkeyind.dll", // Widcomm Bluetooth.
- L"cmcsyshk.dll", // CMC Internet Security.
- L"cmsetac.dll", // Unknown (suspected malware).
- L"cooliris.dll", // CoolIris.
- L"cplushook.dll", // Unknown (suspected malware).
- L"dockshellhook.dll", // Stardock Objectdock.
- L"easyhook32.dll", // GDIPP and others.
- L"easyhook64.dll", // Symantec BlueCoat and others.
- L"esspd.dll", // Samsung Smart Security ESCORT.
- L"googledesktopnetwork3.dll", // Google Desktop Search v5.
- L"fwhook.dll", // PC Tools Firewall Plus.
- L"guard64.dll", // Comodo Internet Security x64.
- L"hookprocesscreation.dll", // Blumentals Program protector.
- L"hookterminateapis.dll", // Blumentals and Cyberprinter.
- L"hookprintapis.dll", // Cyberprinter.
- L"imon.dll", // NOD32 Antivirus.
- L"icatcdll.dll", // Samsung Smart Security ESCORT.
- L"icdcnl.dll", // Samsung Smart Security ESCORT.
- L"ioloHL.dll", // Iolo (System Mechanic).
- L"kloehk.dll", // Kaspersky Internet Security.
- L"lawenforcer.dll", // Spyware-Browser AntiSpyware (Spybro).
- L"libdivx.dll", // DivX.
- L"lvprcinj01.dll", // Logitech QuickCam.
- L"madchook.dll", // Madshi (generic hooking library).
- L"mdnsnsp.dll", // Bonjour.
- L"moonsysh.dll", // Moon Secure Antivirus.
- L"mpk.dll", // KGB Spy.
- L"npdivx32.dll", // DivX.
- L"npggNT.des", // GameGuard 2008.
- L"npggNT.dll", // GameGuard (older).
- L"oawatch.dll", // Online Armor.
- L"pastali32.dll", // PastaLeads.
- L"pavhook.dll", // Panda Internet Security.
- L"pavlsphook.dll", // Panda Antivirus.
- L"pavshook.dll", // Panda Antivirus.
- L"pavshookwow.dll", // Panda Antivirus.
- L"pctavhook.dll", // PC Tools Antivirus.
- L"pctgmhk.dll", // PC Tools Spyware Doctor.
- L"picrmi32.dll", // PicRec.
- L"picrmi64.dll", // PicRec.
- L"prntrack.dll", // Pharos Systems.
- L"protector.dll", // Unknown (suspected malware).
- L"radhslib.dll", // Radiant Naomi Internet Filter.
- L"radprlib.dll", // Radiant Naomi Internet Filter.
- L"rapportnikko.dll", // Trustware Rapport.
- L"rlhook.dll", // Trustware Bufferzone.
- L"rooksdol.dll", // Trustware Rapport.
- L"rndlpepperbrowserrecordhelper.dll", // RealPlayer.
- L"rpchromebrowserrecordhelper.dll", // RealPlayer.
- L"r3hook.dll", // Kaspersky Internet Security.
- L"sahook.dll", // McAfee Site Advisor.
- L"sbrige.dll", // Unknown.
- L"sc2hook.dll", // Supercopier 2.
- L"sdhook32.dll", // Spybot - Search & Destroy Live Protection.
- L"sguard.dll", // Iolo (System Guard).
- L"smum32.dll", // Spyware Doctor version 6.
- L"smumhook.dll", // Spyware Doctor version 5.
- L"ssldivx.dll", // DivX.
- L"syncor11.dll", // SynthCore Midi interface.
- L"systools.dll", // Panda Antivirus.
- L"tfwah.dll", // Threatfire (PC tools).
- L"wblind.dll", // Stardock Object desktop.
- L"wbhelp.dll", // Stardock Object desktop.
- L"windowsapihookdll32.dll", // Lenovo One Key Theater (crbug.com/536056).
- L"windowsapihookdll64.dll", // Lenovo One Key Theater (crbug.com/536056).
- L"winstylerthemehelper.dll" // Tuneup utilities 2006.
-};
-
-#if !defined(NACL_WIN64)
-// Adds the policy rules for the path and path\ with the semantic |access|.
-// If |children| is set to true, we need to add the wildcard rules to also
-// apply the rule to the subfiles and subfolders.
-bool AddDirectory(int path, const wchar_t* sub_dir, bool children,
- sandbox::TargetPolicy::Semantics access,
- sandbox::TargetPolicy* policy) {
- base::FilePath directory;
- if (!PathService::Get(path, &directory))
- return false;
-
- if (sub_dir)
- directory = base::MakeAbsoluteFilePath(directory.Append(sub_dir));
-
- sandbox::ResultCode result;
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, access,
- directory.value().c_str());
- if (result != sandbox::SBOX_ALL_OK)
- return false;
-
- std::wstring directory_str = directory.value() + L"\\";
- if (children)
- directory_str += L"*";
- // Otherwise, add the version of the path that ends with a separator.
-
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, access,
- directory_str.c_str());
- if (result != sandbox::SBOX_ALL_OK)
- return false;
-
- return true;
-}
-#endif // !defined(NACL_WIN64)
-
-// Compares the loaded |module| file name matches |module_name|.
-bool IsExpandedModuleName(HMODULE module, const wchar_t* module_name) {
- wchar_t path[MAX_PATH];
- DWORD sz = ::GetModuleFileNameW(module, path, arraysize(path));
- if ((sz == arraysize(path)) || (sz == 0)) {
- // XP does not set the last error properly, so we bail out anyway.
- return false;
- }
- if (!::GetLongPathName(path, path, arraysize(path)))
- return false;
- base::FilePath fname(path);
- return (fname.BaseName().value() == module_name);
-}
-
-// Adds a single dll by |module_name| into the |policy| blacklist.
-// If |check_in_browser| is true we only add an unload policy only if the dll
-// is also loaded in this process.
-void BlacklistAddOneDll(const wchar_t* module_name,
- bool check_in_browser,
- sandbox::TargetPolicy* policy) {
- HMODULE module = check_in_browser ? ::GetModuleHandleW(module_name) : NULL;
- if (!module) {
- // The module could have been loaded with a 8.3 short name. We check
- // the three most common cases: 'thelongname.dll' becomes
- // 'thelon~1.dll', 'thelon~2.dll' and 'thelon~3.dll'.
- std::wstring name(module_name);
- size_t period = name.rfind(L'.');
- DCHECK_NE(std::string::npos, period);
- DCHECK_LE(3U, (name.size() - period));
- if (period <= 8)
- return;
- for (wchar_t ix = '1'; ix <= '3'; ++ix) {
- const wchar_t suffix[] = {'~', ix, 0};
- std::wstring alt_name = name.substr(0, 6) + suffix;
- alt_name += name.substr(period, name.size());
- if (check_in_browser) {
- module = ::GetModuleHandleW(alt_name.c_str());
- if (!module)
- return;
- // We found it, but because it only has 6 significant letters, we
- // want to make sure it is the right one.
- if (!IsExpandedModuleName(module, module_name))
- return;
- }
- // Found a match. We add both forms to the policy.
- policy->AddDllToUnload(alt_name.c_str());
- }
- }
- policy->AddDllToUnload(module_name);
- DVLOG(1) << "dll to unload found: " << module_name;
- return;
-}
-
-// Adds policy rules for unloaded the known dlls that cause chrome to crash.
-// Eviction of injected DLLs is done by the sandbox so that the injected module
-// does not get a chance to execute any code.
-void AddGenericDllEvictionPolicy(sandbox::TargetPolicy* policy) {
- for (int ix = 0; ix != arraysize(kTroublesomeDlls); ++ix)
- BlacklistAddOneDll(kTroublesomeDlls[ix], true, policy);
-}
-
-// Returns the object path prepended with the current logon session.
-base::string16 PrependWindowsSessionPath(const base::char16* object) {
- // Cache this because it can't change after process creation.
- static DWORD s_session_id = 0;
- if (s_session_id == 0) {
- HANDLE token;
- DWORD session_id_length;
- DWORD session_id = 0;
-
- CHECK(::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token));
- CHECK(::GetTokenInformation(token, TokenSessionId, &session_id,
- sizeof(session_id), &session_id_length));
- CloseHandle(token);
- if (session_id)
- s_session_id = session_id;
- }
-
- return base::StringPrintf(L"\\Sessions\\%lu%ls", s_session_id, object);
-}
-
-// Checks if the sandbox can be let to run without a job object assigned.
-// Returns true if the job object has to be applied to the sandbox and false
-// otherwise.
-bool ShouldSetJobLevel(const base::CommandLine& cmd_line) {
- // Windows 8 allows nested jobs so we don't need to check if we are in other
- // job.
- if (base::win::GetVersion() >= base::win::VERSION_WIN8)
- return true;
-
- BOOL in_job = true;
- // Either there is no job yet associated so we must add our job,
- if (!::IsProcessInJob(::GetCurrentProcess(), NULL, &in_job))
- NOTREACHED() << "IsProcessInJob failed. " << GetLastError();
- if (!in_job)
- return true;
-
- // ...or there is a job but the JOB_OBJECT_LIMIT_BREAKAWAY_OK limit is set.
- JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = {};
- if (!::QueryInformationJobObject(NULL,
- JobObjectExtendedLimitInformation, &job_info,
- sizeof(job_info), NULL)) {
- NOTREACHED() << "QueryInformationJobObject failed. " << GetLastError();
- return true;
- }
- if (job_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK)
- return true;
-
- // Lastly in place of the flag which was supposed to be used only for running
- // Chrome in remote sessions we do this check explicitly here.
- // According to MS this flag can be false for a remote session only on Windows
- // Server 2012 and newer so if we do the check last we should be on the safe
- // side. See: https://msdn.microsoft.com/en-us/library/aa380798.aspx.
- if (!::GetSystemMetrics(SM_REMOTESESSION)) {
- // Measure how often we would have decided to apply the sandbox but the
- // user actually wanted to avoid it.
- // TODO(pastarmovj): Remove this check and the flag altogether once we are
- // convinced that the automatic logic is good enough.
- bool set_job = !cmd_line.HasSwitch(switches::kAllowNoSandboxJob);
- UMA_HISTOGRAM_BOOLEAN("Process.Sandbox.FlagOverrodeRemoteSessionCheck",
- !set_job);
- return set_job;
- }
-
- // Allow running without the sandbox in this case. This slightly reduces the
- // ability of the sandbox to protect its children from spawning new processes
- // or preventing them from shutting down Windows or accessing the clipboard.
- return false;
-}
-
-// Adds the generic policy rules to a sandbox TargetPolicy.
-sandbox::ResultCode AddGenericPolicy(sandbox::TargetPolicy* policy) {
- sandbox::ResultCode result;
-
- // Add the policy for the client side of a pipe. It is just a file
- // in the \pipe\ namespace. We restrict it to pipes that start with
- // "chrome." so the sandboxed process cannot connect to system services.
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
- sandbox::TargetPolicy::FILES_ALLOW_ANY,
- L"\\??\\pipe\\chrome.*");
- if (result != sandbox::SBOX_ALL_OK)
- return result;
-
- // Add the policy for the server side of nacl pipe. It is just a file
- // in the \pipe\ namespace. We restrict it to pipes that start with
- // "chrome.nacl" so the sandboxed process cannot connect to
- // system services.
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
- sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
- L"\\\\.\\pipe\\chrome.nacl.*");
- if (result != sandbox::SBOX_ALL_OK)
- return result;
-
- // Allow the server side of sync sockets, which are pipes that have
- // the "chrome.sync" namespace and a randomly generated suffix.
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
- sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
- L"\\\\.\\pipe\\chrome.sync.*");
- if (result != sandbox::SBOX_ALL_OK)
- return result;
-
- // Add the policy for debug message only in debug
-#ifndef NDEBUG
- base::FilePath app_dir;
- if (!PathService::Get(base::DIR_MODULE, &app_dir))
- return sandbox::SBOX_ERROR_GENERIC;
-
- wchar_t long_path_buf[MAX_PATH];
- DWORD long_path_return_value = GetLongPathName(app_dir.value().c_str(),
- long_path_buf,
- MAX_PATH);
- if (long_path_return_value == 0 || long_path_return_value >= MAX_PATH)
- return sandbox::SBOX_ERROR_NO_SPACE;
-
- base::FilePath debug_message(long_path_buf);
- debug_message = debug_message.AppendASCII("debug_message.exe");
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_PROCESS,
- sandbox::TargetPolicy::PROCESS_MIN_EXEC,
- debug_message.value().c_str());
- if (result != sandbox::SBOX_ALL_OK)
- return result;
-#endif // NDEBUG
-
- // Add the policy for read-only PDB file access for stack traces.
-#if !defined(OFFICIAL_BUILD)
- base::FilePath exe;
- if (!PathService::Get(base::FILE_EXE, &exe))
- return sandbox::SBOX_ERROR_GENERIC;
- base::FilePath pdb_path = exe.DirName().Append(L"*.pdb");
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
- sandbox::TargetPolicy::FILES_ALLOW_READONLY,
- pdb_path.value().c_str());
- if (result != sandbox::SBOX_ALL_OK)
- return result;
-#endif
-
-#if defined(SANITIZER_COVERAGE)
- DWORD coverage_dir_size =
- ::GetEnvironmentVariable(L"SANITIZER_COVERAGE_DIR", NULL, 0);
- if (coverage_dir_size == 0) {
- LOG(WARNING) << "SANITIZER_COVERAGE_DIR was not set, coverage won't work.";
- } else {
- std::wstring coverage_dir;
- wchar_t* coverage_dir_str =
- base::WriteInto(&coverage_dir, coverage_dir_size);
- coverage_dir_size = ::GetEnvironmentVariable(
- L"SANITIZER_COVERAGE_DIR", coverage_dir_str, coverage_dir_size);
- CHECK(coverage_dir.size() == coverage_dir_size);
- base::FilePath sancov_path =
- base::FilePath(coverage_dir).Append(L"*.sancov");
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
- sandbox::TargetPolicy::FILES_ALLOW_ANY,
- sancov_path.value().c_str());
- if (result != sandbox::SBOX_ALL_OK)
- return result;
- }
-#endif
-
- AddGenericDllEvictionPolicy(policy);
- return sandbox::SBOX_ALL_OK;
-}
-
-void LogLaunchWarning(sandbox::ResultCode last_warning, DWORD last_error) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Process.Sandbox.Launch.WarningResultCode",
- last_warning);
- UMA_HISTOGRAM_SPARSE_SLOWLY("Process.Sandbox.Launch.Warning", last_error);
-}
-
-sandbox::ResultCode AddPolicyForSandboxedProcess(
- sandbox::TargetPolicy* policy) {
- sandbox::ResultCode result = sandbox::SBOX_ALL_OK;
-
- // Win8+ adds a device DeviceApi that we don't need.
- if (base::win::GetVersion() >= base::win::VERSION_WIN8)
- result = policy->AddKernelObjectToClose(L"File", L"\\Device\\DeviceApi");
- if (result != sandbox::SBOX_ALL_OK)
- return result;
-
- // On 2003/Vista+ the initial token has to be restricted if the main
- // token is restricted.
- result = policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
- sandbox::USER_LOCKDOWN);
- if (result != sandbox::SBOX_ALL_OK)
- return result;
- // Prevents the renderers from manipulating low-integrity processes.
- result = policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_UNTRUSTED);
- if (result != sandbox::SBOX_ALL_OK)
- return result;
- result = policy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
- if (result != sandbox::SBOX_ALL_OK)
- return result;
- policy->SetLockdownDefaultDacl();
-
- result = policy->SetAlternateDesktop(true);
- if (result != sandbox::SBOX_ALL_OK) {
- // We ignore the result of setting the alternate desktop, however log
- // a launch warning.
- LogLaunchWarning(result, ::GetLastError());
- DLOG(WARNING) << "Failed to apply desktop security to the renderer";
- result = sandbox::SBOX_ALL_OK;
- }
-
- return result;
-}
-
-// Updates the command line arguments with debug-related flags. If debug flags
-// have been used with this process, they will be filtered and added to
-// command_line as needed.
-void ProcessDebugFlags(base::CommandLine* command_line) {
- const base::CommandLine& current_cmd_line =
- *base::CommandLine::ForCurrentProcess();
- std::string type = command_line->GetSwitchValueASCII(switches::kProcessType);
- if (current_cmd_line.HasSwitch(switches::kWaitForDebuggerChildren)) {
- // Look to pass-on the kWaitForDebugger flag.
- std::string value = current_cmd_line.GetSwitchValueASCII(
- switches::kWaitForDebuggerChildren);
- if (value.empty() || value == type) {
- command_line->AppendSwitch(switches::kWaitForDebugger);
- }
- command_line->AppendSwitchASCII(switches::kWaitForDebuggerChildren, value);
- }
-}
-
-// This code is test only, and attempts to catch unsafe uses of
-// DuplicateHandle() that copy privileged handles into sandboxed processes.
-#ifndef OFFICIAL_BUILD
-base::win::IATPatchFunction g_iat_patch_duplicate_handle;
-
-typedef BOOL (WINAPI *DuplicateHandleFunctionPtr)(HANDLE source_process_handle,
- HANDLE source_handle,
- HANDLE target_process_handle,
- LPHANDLE target_handle,
- DWORD desired_access,
- BOOL inherit_handle,
- DWORD options);
-
-DuplicateHandleFunctionPtr g_iat_orig_duplicate_handle;
-
-NtQueryObject g_QueryObject = NULL;
-
-static const char* kDuplicateHandleWarning =
- "You are attempting to duplicate a privileged handle into a sandboxed"
- " process.\n Please contact security@chromium.org for assistance.";
-
-void CheckDuplicateHandle(HANDLE handle) {
- // Get the object type (32 characters is safe; current max is 14).
- BYTE buffer[sizeof(OBJECT_TYPE_INFORMATION) + 32 * sizeof(wchar_t)];
- OBJECT_TYPE_INFORMATION* type_info =
- reinterpret_cast<OBJECT_TYPE_INFORMATION*>(buffer);
- ULONG size = sizeof(buffer) - sizeof(wchar_t);
- NTSTATUS error;
- error = g_QueryObject(handle, ObjectTypeInformation, type_info, size, &size);
- CHECK(NT_SUCCESS(error));
- type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0';
-
- // Get the object basic information.
- OBJECT_BASIC_INFORMATION basic_info;
- size = sizeof(basic_info);
- error = g_QueryObject(handle, ObjectBasicInformation, &basic_info, size,
- &size);
- CHECK(NT_SUCCESS(error));
-
- CHECK(!(basic_info.GrantedAccess & WRITE_DAC)) <<
- kDuplicateHandleWarning;
-
- if (0 == _wcsicmp(type_info->Name.Buffer, L"Process")) {
- const ACCESS_MASK kDangerousMask =
- ~static_cast<DWORD>(PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE);
- CHECK(!(basic_info.GrantedAccess & kDangerousMask)) <<
- kDuplicateHandleWarning;
- }
-}
-
-BOOL WINAPI DuplicateHandlePatch(HANDLE source_process_handle,
- HANDLE source_handle,
- HANDLE target_process_handle,
- LPHANDLE target_handle,
- DWORD desired_access,
- BOOL inherit_handle,
- DWORD options) {
- // Duplicate the handle so we get the final access mask.
- if (!g_iat_orig_duplicate_handle(source_process_handle, source_handle,
- target_process_handle, target_handle,
- desired_access, inherit_handle, options))
- return FALSE;
-
- // We're not worried about broker handles or not crossing process boundaries.
- if (source_process_handle == target_process_handle ||
- target_process_handle == ::GetCurrentProcess())
- return TRUE;
-
- // Only sandboxed children are placed in jobs, so just check them.
- BOOL is_in_job = FALSE;
- if (!::IsProcessInJob(target_process_handle, NULL, &is_in_job)) {
- // We need a handle with permission to check the job object.
- if (ERROR_ACCESS_DENIED == ::GetLastError()) {
- HANDLE temp_handle;
- CHECK(g_iat_orig_duplicate_handle(::GetCurrentProcess(),
- target_process_handle,
- ::GetCurrentProcess(),
- &temp_handle,
- PROCESS_QUERY_INFORMATION,
- FALSE, 0));
- base::win::ScopedHandle process(temp_handle);
- CHECK(::IsProcessInJob(process.Get(), NULL, &is_in_job));
- }
- }
-
- if (is_in_job) {
- // We never allow inheritable child handles.
- CHECK(!inherit_handle) << kDuplicateHandleWarning;
-
- // Duplicate the handle again, to get the final permissions.
- HANDLE temp_handle;
- CHECK(g_iat_orig_duplicate_handle(target_process_handle, *target_handle,
- ::GetCurrentProcess(), &temp_handle,
- 0, FALSE, DUPLICATE_SAME_ACCESS));
- base::win::ScopedHandle handle(temp_handle);
-
- // Callers use CHECK macro to make sure we get the right stack.
- CheckDuplicateHandle(handle.Get());
- }
-
- return TRUE;
-}
-#endif
-
-bool IsAppContainerEnabled() {
- if (base::win::GetVersion() < base::win::VERSION_WIN8)
- return false;
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- const std::string appcontainer_group_name =
- base::FieldTrialList::FindFullName("EnableAppContainer");
- if (command_line.HasSwitch(switches::kDisableAppContainer))
- return false;
- if (command_line.HasSwitch(switches::kEnableAppContainer))
- return true;
- return base::StartsWith(appcontainer_group_name, "Enabled",
- base::CompareCase::INSENSITIVE_ASCII);
-}
-
-sandbox::ResultCode SetJobMemoryLimit(const base::CommandLine& cmd_line,
- sandbox::TargetPolicy* policy) {
- DCHECK_NE(policy->GetJobLevel(), sandbox::JOB_NONE);
-
-#ifdef _WIN64
- int64_t GB = 1024 * 1024 * 1024;
- size_t memory_limit = 4 * GB;
-
- // Note that this command line flag hasn't been fetched by all
- // callers of SetJobLevel, only those in this file.
- if (cmd_line.GetSwitchValueASCII(switches::kProcessType) ==
- switches::kGpuProcess) {
- // Allow the GPU process's sandbox to access more physical memory if
- // it's available on the system.
- int64_t physical_memory = base::SysInfo::AmountOfPhysicalMemory();
- if (physical_memory > 16 * GB) {
- memory_limit = 16 * GB;
- } else if (physical_memory > 8 * GB) {
- memory_limit = 8 * GB;
- }
- }
- return policy->SetJobMemoryLimit(memory_limit);
-#else
- return sandbox::SBOX_ALL_OK;
-#endif
-}
-
-} // namespace
-
-sandbox::ResultCode SetJobLevel(const base::CommandLine& cmd_line,
- sandbox::JobLevel job_level,
- uint32_t ui_exceptions,
- sandbox::TargetPolicy* policy) {
- if (!ShouldSetJobLevel(cmd_line))
- return policy->SetJobLevel(sandbox::JOB_NONE, 0);
-
- sandbox::ResultCode ret = policy->SetJobLevel(job_level, ui_exceptions);
- if (ret != sandbox::SBOX_ALL_OK)
- return ret;
-
- return SetJobMemoryLimit(cmd_line, policy);
-}
-
-// This is for finch. See also crbug.com/464430 for details.
-const base::Feature kEnableCsrssLockdownFeature{
- "EnableCsrssLockdown", base::FEATURE_DISABLED_BY_DEFAULT};
-
-// TODO(jschuh): Need get these restrictions applied to NaCl and Pepper.
-// Just have to figure out what needs to be warmed up first.
-sandbox::ResultCode AddBaseHandleClosePolicy(sandbox::TargetPolicy* policy) {
- if (base::FeatureList::IsEnabled(kEnableCsrssLockdownFeature)) {
- // Close all ALPC ports.
- sandbox::ResultCode ret = policy->SetDisconnectCsrss();
- if (ret != sandbox::SBOX_ALL_OK) {
- return ret;
- }
- }
-
- // TODO(cpu): Add back the BaseNamedObjects policy.
- base::string16 object_path = PrependWindowsSessionPath(
- L"\\BaseNamedObjects\\windows_shell_global_counters");
- return policy->AddKernelObjectToClose(L"Section", object_path.data());
-}
-
-sandbox::ResultCode AddAppContainerPolicy(sandbox::TargetPolicy* policy,
- const wchar_t* sid) {
- if (IsAppContainerEnabled())
- return policy->SetLowBox(sid);
- return sandbox::SBOX_ALL_OK;
-}
-
-sandbox::ResultCode AddWin32kLockdownPolicy(sandbox::TargetPolicy* policy,
- bool enable_opm) {
-#if !defined(NACL_WIN64)
- if (!IsWin32kLockdownEnabled())
- return sandbox::SBOX_ALL_OK;
-
- // Enable win32k lockdown if not already.
- sandbox::MitigationFlags flags = policy->GetProcessMitigations();
- if ((flags & sandbox::MITIGATION_WIN32K_DISABLE) ==
- sandbox::MITIGATION_WIN32K_DISABLE)
- return sandbox::SBOX_ALL_OK;
-
- sandbox::ResultCode result =
- policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN,
- enable_opm ? sandbox::TargetPolicy::IMPLEMENT_OPM_APIS
- : sandbox::TargetPolicy::FAKE_USER_GDI_INIT,
- nullptr);
- if (result != sandbox::SBOX_ALL_OK)
- return result;
- if (enable_opm)
- policy->SetEnableOPMRedirection();
-
- flags |= sandbox::MITIGATION_WIN32K_DISABLE;
- return policy->SetProcessMitigations(flags);
-#else
- return sandbox::SBOX_ALL_OK;
-#endif
-}
-
-bool InitBrokerServices(sandbox::BrokerServices* broker_services) {
- // TODO(abarth): DCHECK(CalledOnValidThread());
- // See <http://b/1287166>.
- DCHECK(broker_services);
- DCHECK(!g_broker_services);
- sandbox::ResultCode result = broker_services->Init();
- g_broker_services = broker_services;
-
- // In non-official builds warn about dangerous uses of DuplicateHandle.
-#ifndef OFFICIAL_BUILD
- BOOL is_in_job = FALSE;
- CHECK(::IsProcessInJob(::GetCurrentProcess(), NULL, &is_in_job));
- // In a Syzygy-profiled binary, instrumented for import profiling, this
- // patch will end in infinite recursion on the attempted delegation to the
- // original function.
- if (!base::debug::IsBinaryInstrumented() &&
- !is_in_job && !g_iat_patch_duplicate_handle.is_patched()) {
- HMODULE module = NULL;
- wchar_t module_name[MAX_PATH];
- CHECK(::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- reinterpret_cast<LPCWSTR>(InitBrokerServices),
- &module));
- DWORD result = ::GetModuleFileNameW(module, module_name, MAX_PATH);
- if (result && (result != MAX_PATH)) {
- ResolveNTFunctionPtr("NtQueryObject", &g_QueryObject);
- result = g_iat_patch_duplicate_handle.Patch(
- module_name, "kernel32.dll", "DuplicateHandle",
- DuplicateHandlePatch);
- CHECK(result == 0);
- g_iat_orig_duplicate_handle =
- reinterpret_cast<DuplicateHandleFunctionPtr>(
- g_iat_patch_duplicate_handle.original_function());
- }
- }
-#endif
-
- return sandbox::SBOX_ALL_OK == result;
-}
-
-bool InitTargetServices(sandbox::TargetServices* target_services) {
- DCHECK(target_services);
- sandbox::ResultCode result = target_services->Init();
- return sandbox::SBOX_ALL_OK == result;
-}
-
-sandbox::ResultCode StartSandboxedProcess(
- SandboxedProcessLauncherDelegate* delegate,
- base::CommandLine* cmd_line,
- const base::HandlesToInheritVector& handles_to_inherit,
- base::Process* process) {
- DCHECK(delegate);
- const base::CommandLine& browser_command_line =
- *base::CommandLine::ForCurrentProcess();
- std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType);
-
- TRACE_EVENT1("startup", "StartProcessWithAccess", "type", type_str);
-
- // Propagate the --allow-no-job flag if present.
- if (browser_command_line.HasSwitch(switches::kAllowNoSandboxJob) &&
- !cmd_line->HasSwitch(switches::kAllowNoSandboxJob)) {
- cmd_line->AppendSwitch(switches::kAllowNoSandboxJob);
- }
-
- ProcessDebugFlags(cmd_line);
-
- if (service_manager::IsUnsandboxedSandboxType(delegate->GetSandboxType()) ||
- browser_command_line.HasSwitch(switches::kNoSandbox) ||
- cmd_line->HasSwitch(switches::kNoSandbox)) {
- base::LaunchOptions options;
- options.handles_to_inherit = handles_to_inherit;
- *process = base::LaunchProcess(*cmd_line, options);
- return sandbox::SBOX_ALL_OK;
- }
-
- scoped_refptr<sandbox::TargetPolicy> policy =
- g_broker_services->CreatePolicy();
-
- // Add any handles to be inherited to the policy.
- for (HANDLE handle : handles_to_inherit)
- policy->AddHandleToShare(handle);
-
- // Pre-startup mitigations.
- sandbox::MitigationFlags mitigations =
- sandbox::MITIGATION_HEAP_TERMINATE |
- sandbox::MITIGATION_BOTTOM_UP_ASLR |
- sandbox::MITIGATION_DEP |
- sandbox::MITIGATION_DEP_NO_ATL_THUNK |
- sandbox::MITIGATION_EXTENSION_POINT_DISABLE |
- sandbox::MITIGATION_SEHOP |
- sandbox::MITIGATION_NONSYSTEM_FONT_DISABLE |
- sandbox::MITIGATION_IMAGE_LOAD_NO_REMOTE |
- sandbox::MITIGATION_IMAGE_LOAD_NO_LOW_LABEL;
-
- sandbox::ResultCode result = sandbox::SBOX_ERROR_GENERIC;
- result = policy->SetProcessMitigations(mitigations);
-
- if (result != sandbox::SBOX_ALL_OK)
- return result;
-
-#if !defined(NACL_WIN64)
- if (type_str == switches::kRendererProcess && IsWin32kLockdownEnabled()) {
- result = AddWin32kLockdownPolicy(policy.get(), false);
- if (result != sandbox::SBOX_ALL_OK)
- return result;
- }
-#endif
-
- // Post-startup mitigations.
- mitigations = sandbox::MITIGATION_STRICT_HANDLE_CHECKS |
- sandbox::MITIGATION_DLL_SEARCH_ORDER;
- if (base::FeatureList::IsEnabled(features::kWinSboxForceMsSigned))
- mitigations |= sandbox::MITIGATION_FORCE_MS_SIGNED_BINS;
-
- result = policy->SetDelayedProcessMitigations(mitigations);
- if (result != sandbox::SBOX_ALL_OK)
- return result;
-
- result = SetJobLevel(*cmd_line, sandbox::JOB_LOCKDOWN, 0, policy.get());
- if (result != sandbox::SBOX_ALL_OK)
- return result;
-
- if (!delegate->DisableDefaultPolicy()) {
- result = AddPolicyForSandboxedProcess(policy.get());
- if (result != sandbox::SBOX_ALL_OK)
- return result;
- }
-
-#if !defined(NACL_WIN64)
- if (type_str == switches::kRendererProcess ||
- type_str == switches::kPpapiPluginProcess ||
- delegate->GetSandboxType() ==
- service_manager::SANDBOX_TYPE_PDF_COMPOSITOR) {
- AddDirectory(base::DIR_WINDOWS_FONTS, NULL, true,
- sandbox::TargetPolicy::FILES_ALLOW_READONLY, policy.get());
- }
-#endif
-
- if (type_str != switches::kRendererProcess) {
- // Hack for Google Desktop crash. Trick GD into not injecting its DLL into
- // this subprocess. See
- // http://code.google.com/p/chromium/issues/detail?id=25580
- cmd_line->AppendSwitchASCII("ignored", " --type=renderer ");
- }
-
- result = AddGenericPolicy(policy.get());
-
- if (result != sandbox::SBOX_ALL_OK) {
- NOTREACHED();
- return result;
- }
-
- // Allow the renderer and gpu processes to access the log file.
- if (type_str == switches::kRendererProcess ||
- type_str == switches::kGpuProcess) {
- if (logging::IsLoggingToFileEnabled()) {
- DCHECK(base::FilePath(logging::GetLogFileFullPath()).IsAbsolute());
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
- sandbox::TargetPolicy::FILES_ALLOW_ANY,
- logging::GetLogFileFullPath().c_str());
- if (result != sandbox::SBOX_ALL_OK)
- return result;
- }
- }
-
-#if !defined(OFFICIAL_BUILD)
- // If stdout/stderr point to a Windows console, these calls will
- // have no effect. These calls can fail with SBOX_ERROR_BAD_PARAMS.
- policy->SetStdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE));
- policy->SetStderrHandle(GetStdHandle(STD_ERROR_HANDLE));
-#endif
-
- if (!delegate->PreSpawnTarget(policy.get()))
- return sandbox::SBOX_ERROR_DELEGATE_PRE_SPAWN;
-
- TRACE_EVENT_BEGIN0("startup", "StartProcessWithAccess::LAUNCHPROCESS");
-
- PROCESS_INFORMATION temp_process_info = {};
- sandbox::ResultCode last_warning = sandbox::SBOX_ALL_OK;
- DWORD last_error = ERROR_SUCCESS;
- result = g_broker_services->SpawnTarget(
- cmd_line->GetProgram().value().c_str(),
- cmd_line->GetCommandLineString().c_str(), policy, &last_warning,
- &last_error, &temp_process_info);
-
- base::win::ScopedProcessInformation target(temp_process_info);
-
- TRACE_EVENT_END0("startup", "StartProcessWithAccess::LAUNCHPROCESS");
-
- base::debug::GlobalActivityTracker* tracker =
- base::debug::GlobalActivityTracker::Get();
- if (tracker) {
- tracker->RecordProcessLaunch(target.process_id(),
- cmd_line->GetCommandLineString());
- }
-
- if (sandbox::SBOX_ALL_OK != result) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Process.Sandbox.Launch.Error", last_error);
- if (result == sandbox::SBOX_ERROR_GENERIC)
- DPLOG(ERROR) << "Failed to launch process";
- else
- DLOG(ERROR) << "Failed to launch process. Error: " << result;
-
- return result;
- }
-
- if (sandbox::SBOX_ALL_OK != last_warning) {
- LogLaunchWarning(last_warning, last_error);
- }
-
- delegate->PostSpawnTarget(target.process_handle());
-
- CHECK(ResumeThread(target.thread_handle()) != static_cast<DWORD>(-1));
- *process = base::Process(target.TakeProcessHandle());
- return sandbox::SBOX_ALL_OK;
-}
-
-} // namespace content
diff --git a/chromium/content/common/sandbox_win.h b/chromium/content/common/sandbox_win.h
deleted file mode 100644
index 7bda68eaac3..00000000000
--- a/chromium/content/common/sandbox_win.h
+++ /dev/null
@@ -1,50 +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_SANDBOX_WIN_H_
-#define CONTENT_COMMON_SANDBOX_WIN_H_
-
-#include <stdint.h>
-
-#include "content/common/content_export.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/security_level.h"
-
-namespace base {
-class CommandLine;
-}
-
-namespace sandbox {
-class BrokerServices;
-class TargetPolicy;
-class TargetServices;
-}
-
-namespace content {
-
-// Wrapper around sandbox::TargetPolicy::SetJobLevel that checks if the sandbox
-// should be let to run without a job object assigned.
-sandbox::ResultCode SetJobLevel(const base::CommandLine& cmd_line,
- sandbox::JobLevel job_level,
- uint32_t ui_exceptions,
- sandbox::TargetPolicy* policy);
-
-// Closes handles that are opened at process creation and initialization.
-sandbox::ResultCode AddBaseHandleClosePolicy(sandbox::TargetPolicy* policy);
-
-// Add AppContainer policy for |sid| on supported OS.
-sandbox::ResultCode AddAppContainerPolicy(sandbox::TargetPolicy* policy,
- const wchar_t* sid);
-
-// Add the win32k lockdown policy on supported OS.
-sandbox::ResultCode AddWin32kLockdownPolicy(sandbox::TargetPolicy* policy,
- bool enable_opm);
-
-bool InitBrokerServices(sandbox::BrokerServices* broker_services);
-
-bool InitTargetServices(sandbox::TargetServices* target_services);
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SANDBOX_WIN_H_
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 b01fe85566d..1c72b821866 100644
--- a/chromium/content/common/service_manager/service_manager_connection_impl.cc
+++ b/chromium/content/common/service_manager/service_manager_connection_impl.cc
@@ -168,9 +168,8 @@ class ServiceManagerConnectionImpl::IOThreadContext
// Should bind |io_thread_checker_| to the context's thread.
DCHECK(io_thread_checker_.CalledOnValidThread());
service_context_.reset(new service_manager::ServiceContext(
- base::MakeUnique<service_manager::ForwardingService>(this),
- std::move(pending_service_request_),
- std::move(io_thread_connector_),
+ std::make_unique<service_manager::ForwardingService>(this),
+ std::move(pending_service_request_), std::move(io_thread_connector_),
std::move(pending_connector_request_)));
// MessageLoopObserver owns itself.
@@ -366,8 +365,8 @@ std::unique_ptr<ServiceManagerConnection> ServiceManagerConnection::Create(
scoped_refptr<base::SequencedTaskRunner> io_task_runner) {
if (service_manager_connection_factory)
return service_manager_connection_factory->Run();
- return base::MakeUnique<ServiceManagerConnectionImpl>(
- std::move(request), io_task_runner);
+ return std::make_unique<ServiceManagerConnectionImpl>(std::move(request),
+ io_task_runner);
}
ServiceManagerConnection::~ServiceManagerConnection() {}
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 d8c6ba69214..e1b238c25b2 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
@@ -21,7 +21,7 @@ constexpr char kTestServiceName[] = "test service";
std::unique_ptr<service_manager::Service> LaunchService(
base::WaitableEvent* event) {
event->Signal();
- return base::MakeUnique<service_manager::Service>();
+ return std::make_unique<service_manager::Service>();
}
} // namespace
diff --git a/chromium/content/common/service_worker/controller_service_worker.mojom b/chromium/content/common/service_worker/controller_service_worker.mojom
index a7d522edba9..4910c33bc21 100644
--- a/chromium/content/common/service_worker/controller_service_worker.mojom
+++ b/chromium/content/common/service_worker/controller_service_worker.mojom
@@ -6,17 +6,18 @@ module content.mojom;
import "mojo/common/time.mojom";
import "content/common/service_worker/service_worker_fetch_response_callback.mojom";
+import "content/public/common/url_loader.mojom";
import "third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom";
import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom";
// S13nServiceWorker:
-// Represents a service worker that is a controller. One of its Mojo end
-// points (i.e. the caller end) is passed to the controllee in the renderer
-// process, and used from there. Its other Mojo end point (i.e. the destination
-// of the events) is currently implemented by BrowserSideControllerServiceWorker
-// in the browser-process, but eventually this should be implemented by the
-// controller service worker in the renderer-process so that the events
-// dispatched by the controllees can be directly sent there.
+// Represents a service worker that is a 'controller'.
+// (https://w3c.github.io/ServiceWorker/#navigator-service-worker-controller)
+// One of its Mojo end points (i.e. the caller end) is passed to the
+// controllee in the renderer process, and used from there. Its other Mojo
+// end point (i.e. the destination of the events) is implemented by
+// ControllerServiceWorkerImpl in the renderer process where the controller
+// service worker runs.
//
// The controllees use this interface to directly talk to the controller. This
// implements a small subset of ServiceWorkerEventDispatcher, namely dispatch
@@ -34,10 +35,13 @@ interface ControllerServiceWorker {
// handler ran and all outstanding respondWith() and waitUntil() promises have
// settled. |response_callback| is called once the promise to respondWith()
// settles, or when the event handler ran without calling respondWith().
- DispatchFetchEvent(blink.mojom.FetchAPIRequest request,
+ DispatchFetchEvent(URLRequest request,
ServiceWorkerFetchResponseCallback response_callback)
=> (blink.mojom.ServiceWorkerEventStatus status,
mojo.common.mojom.Time dispatch_event_time);
// TODO(kinuko): Add DispatchExtendableMessageEvent() as well.
+
+ // Connects a new pipe to this controller instance.
+ Clone(ControllerServiceWorker& controller);
};
diff --git a/chromium/content/common/service_worker/embedded_worker.mojom b/chromium/content/common/service_worker/embedded_worker.mojom
index cf3bdffb847..6d61373e901 100644
--- a/chromium/content/common/service_worker/embedded_worker.mojom
+++ b/chromium/content/common/service_worker/embedded_worker.mojom
@@ -4,18 +4,51 @@
module content.mojom;
+import "content/common/native_types.mojom";
+import "content/common/service_worker/controller_service_worker.mojom";
import "content/common/service_worker/service_worker_event_dispatcher.mojom";
import "content/common/service_worker/service_worker_installed_scripts_manager.mojom";
import "content/common/service_worker/service_worker_provider.mojom";
import "mojo/common/string16.mojom";
import "mojo/common/time.mojom";
+import "mojo/common/unguessable_token.mojom";
import "services/service_manager/public/interfaces/interface_provider.mojom";
+import "third_party/WebKit/public/platform/modules/serviceworker/service_worker.mojom";
import "third_party/WebKit/public/web/console_message.mojom";
import "third_party/WebKit/public/web/worker_content_settings_proxy.mojom";
import "url/mojo/url.mojom";
-[Native]
-struct EmbeddedWorkerStartParams;
+// Parameters to launch a service worker. This is passed from the browser to the
+// renderer at mojom::EmbeddedWorkerInstanceClient::StartWorker().
+struct EmbeddedWorkerStartParams {
+ // The id of the embedded worker. This changes when the service worker is
+ // stopped and restarted.
+ int32 embedded_worker_id;
+ // The id of the service worker being started. This remains fixed even if the
+ // worker is stopped and restarted, or even if the browser restarts.
+ int64 service_worker_version_id;
+ // This service worker's registration's scope:
+ // https://w3c.github.io/ServiceWorker/#service-worker-registration-scope
+ url.mojom.Url scope;
+ // This service worker's script url:
+ // https://w3c.github.io/ServiceWorker/#dom-serviceworker-scripturl
+ url.mojom.Url script_url;
+ // The id to talk with the DevTools agent for the worker.
+ int32 worker_devtools_agent_route_id;
+ // Unique token identifying this worker for DevTools.
+ mojo.common.mojom.UnguessableToken devtools_worker_token;
+ // When true, worker script evaluation is blocked until
+ // EmbeddedWorkerInstanceClient::ResumeAfterDownload() is called.
+ bool pause_after_download;
+ // True if starting the worker should wait until DevTools gets ready.
+ bool wait_for_debugger;
+ // True if this service worker has been installed.
+ bool is_installed;
+ // Determines how eagerly V8 creates the code cache.
+ V8CacheOptions v8_cache_options;
+ // True if Data Saver is enabled.
+ bool data_saver_enabled;
+};
// Holds timing information about the start worker sequence for UMA.
struct EmbeddedWorkerStartTiming {
@@ -32,9 +65,17 @@ struct EmbeddedWorkerStartTiming {
interface EmbeddedWorkerInstanceClient {
// Called back as various functions in EmbeddedWorkerInstanceHost, such
// as OnThreadStarted(), OnStarted().
+ // |dispatcher_request| is used to dispatch events from (via) the browser
+ // process.
+ //
+ // S13nServiceWorker:
+ // |controller_request| is cloned and passed to each
+ // controllee to directly dispatch events from the controllees.
StartWorker(EmbeddedWorkerStartParams params,
ServiceWorkerEventDispatcher& dispatcher_request,
+ ControllerServiceWorker& controller_request,
ServiceWorkerInstalledScriptsInfo? installed_scripts_info,
+ associated blink.mojom.ServiceWorkerHost service_worker_host,
associated EmbeddedWorkerInstanceHost instance_host,
ServiceWorkerProviderInfoForStartWorker provider_info,
blink.mojom.WorkerContentSettingsProxy content_settings_proxy);
@@ -47,9 +88,20 @@ interface EmbeddedWorkerInstanceClient {
// EmbeddedWorkerInstanceHost is the browser-side ("Host") of
// EmbeddedWorkerInstanceClient. It allows control of a browser-side
// embedded worker instance. The renderer uses this interface to report
-// embedded worker state back to the browser. This interface is associated
-// with the EmbeddedWorkerInstanceClient interface.
+// embedded worker state back to the browser, or request termination of the
+// worker. This interface is associated with the EmbeddedWorkerInstanceClient
+// interface.
interface EmbeddedWorkerInstanceHost {
+ // S13nServiceWorker:
+ // Called when the worker requests to be terminated. The worker will request
+ // to be terminated when it realizes it has been idle for some time. The
+ // request may be ignored, for example when there are inflight events issued
+ // just before RequestTermination(). Note that the browser can terminate the
+ // worker at any time even if RequestTermination() is not called. For example,
+ // if the worker thread is continuously busy and the browser's periodic ping
+ // message has been missed, the browser will terminate the service worker.
+ RequestTermination();
+
// Indicates that the worker is ready for inspection.
OnReadyForInspection();
// Indicates that the worker has finished loading the script.
diff --git a/chromium/content/common/service_worker/embedded_worker.typemap b/chromium/content/common/service_worker/embedded_worker.typemap
index 664936bb937..c4de59c255e 100644
--- a/chromium/content/common/service_worker/embedded_worker.typemap
+++ b/chromium/content/common/service_worker/embedded_worker.typemap
@@ -5,6 +5,8 @@
mojom = "//content/common/service_worker/embedded_worker.mojom"
public_headers =
[ "//content/common/service_worker/embedded_worker_start_params.h" ]
-traits_headers =
- [ "//content/common/service_worker/embedded_worker_messages.h" ]
+traits_headers = [ "//content/common/service_worker/embedded_worker_start_params_struct_traits.h" ]
+sources = [
+ "//content/common/service_worker/embedded_worker_start_params_struct_traits.cc",
+]
type_mappings = [ "content.mojom.EmbeddedWorkerStartParams=::content::EmbeddedWorkerStartParams" ]
diff --git a/chromium/content/common/service_worker/embedded_worker_messages.h b/chromium/content/common/service_worker/embedded_worker_messages.h
index f31fcd1e9f7..6aff8b56479 100644
--- a/chromium/content/common/service_worker/embedded_worker_messages.h
+++ b/chromium/content/common/service_worker/embedded_worker_messages.h
@@ -23,24 +23,6 @@
#define IPC_MESSAGE_START EmbeddedWorkerMsgStart
-IPC_STRUCT_TRAITS_BEGIN(content::EmbeddedWorkerSettings)
- IPC_STRUCT_TRAITS_MEMBER(v8_cache_options)
- IPC_STRUCT_TRAITS_MEMBER(data_saver_enabled)
-IPC_STRUCT_TRAITS_END()
-
-// Parameters structure for EmbeddedWorkerMsg_StartWorker.
-IPC_STRUCT_TRAITS_BEGIN(content::EmbeddedWorkerStartParams)
- IPC_STRUCT_TRAITS_MEMBER(embedded_worker_id)
- IPC_STRUCT_TRAITS_MEMBER(service_worker_version_id)
- IPC_STRUCT_TRAITS_MEMBER(scope)
- IPC_STRUCT_TRAITS_MEMBER(script_url)
- IPC_STRUCT_TRAITS_MEMBER(worker_devtools_agent_route_id)
- IPC_STRUCT_TRAITS_MEMBER(pause_after_download)
- IPC_STRUCT_TRAITS_MEMBER(wait_for_debugger)
- IPC_STRUCT_TRAITS_MEMBER(is_installed)
- IPC_STRUCT_TRAITS_MEMBER(settings)
-IPC_STRUCT_TRAITS_END()
-
// Renderer -> Browser message to count an API use. |feature| must be one of the
// values from blink::UseCounter::Feature enum.
IPC_MESSAGE_CONTROL2(EmbeddedWorkerHostMsg_CountFeature,
diff --git a/chromium/content/common/service_worker/embedded_worker_start_params.h b/chromium/content/common/service_worker/embedded_worker_start_params.h
index 0d432192bd3..184e9db4a8b 100644
--- a/chromium/content/common/service_worker/embedded_worker_start_params.h
+++ b/chromium/content/common/service_worker/embedded_worker_start_params.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_START_PARAMS_H_
#define CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_START_PARAMS_H_
+#include "base/unguessable_token.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/embedded_worker_settings.h"
#include "url/gurl.h"
@@ -19,6 +20,7 @@ struct CONTENT_EXPORT EmbeddedWorkerStartParams {
GURL scope;
GURL script_url;
int worker_devtools_agent_route_id;
+ base::UnguessableToken devtools_worker_token;
bool pause_after_download;
bool wait_for_debugger;
bool is_installed;
diff --git a/chromium/content/common/service_worker/embedded_worker_start_params_struct_traits.cc b/chromium/content/common/service_worker/embedded_worker_start_params_struct_traits.cc
new file mode 100644
index 00000000000..470c8d91f1b
--- /dev/null
+++ b/chromium/content/common/service_worker/embedded_worker_start_params_struct_traits.cc
@@ -0,0 +1,33 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/service_worker/embedded_worker_start_params_struct_traits.h"
+
+#include "content/public/common/common_param_traits_macros.h"
+#include "mojo/common/common_custom_types_struct_traits.h"
+#include "url/mojo/url_gurl_struct_traits.h"
+
+namespace mojo {
+
+// static
+bool StructTraits<content::mojom::EmbeddedWorkerStartParamsDataView,
+ content::EmbeddedWorkerStartParams>::
+ Read(content::mojom::EmbeddedWorkerStartParamsDataView in,
+ content::EmbeddedWorkerStartParams* out) {
+ if (!in.ReadScope(&out->scope) || !in.ReadScriptUrl(&out->script_url) ||
+ !in.ReadDevtoolsWorkerToken(&out->devtools_worker_token) ||
+ !in.ReadV8CacheOptions(&out->settings.v8_cache_options)) {
+ return false;
+ }
+ out->embedded_worker_id = in.embedded_worker_id();
+ out->service_worker_version_id = in.service_worker_version_id();
+ out->worker_devtools_agent_route_id = in.worker_devtools_agent_route_id();
+ out->pause_after_download = in.pause_after_download();
+ out->wait_for_debugger = in.wait_for_debugger();
+ out->is_installed = in.is_installed();
+ out->settings.data_saver_enabled = in.data_saver_enabled();
+ return true;
+}
+
+} // namespace mojo
diff --git a/chromium/content/common/service_worker/embedded_worker_start_params_struct_traits.h b/chromium/content/common/service_worker/embedded_worker_start_params_struct_traits.h
new file mode 100644
index 00000000000..a5db318fc6e
--- /dev/null
+++ b/chromium/content/common/service_worker/embedded_worker_start_params_struct_traits.h
@@ -0,0 +1,64 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_START_PARAMS_STRUCT_TRAITS_H_
+#define CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_START_PARAMS_STRUCT_TRAITS_H_
+
+#include "content/common/service_worker/embedded_worker.mojom.h"
+
+namespace mojo {
+
+template <>
+struct StructTraits<content::mojom::EmbeddedWorkerStartParamsDataView,
+ content::EmbeddedWorkerStartParams> {
+ static int embedded_worker_id(
+ const content::EmbeddedWorkerStartParams& info) {
+ return info.embedded_worker_id;
+ }
+ static int64_t service_worker_version_id(
+ const content::EmbeddedWorkerStartParams& info) {
+ return info.service_worker_version_id;
+ }
+ static const GURL& scope(const content::EmbeddedWorkerStartParams& info) {
+ return info.scope;
+ }
+ static const GURL& script_url(
+ const content::EmbeddedWorkerStartParams& info) {
+ return info.script_url;
+ }
+ static int worker_devtools_agent_route_id(
+ const content::EmbeddedWorkerStartParams& info) {
+ return info.worker_devtools_agent_route_id;
+ }
+ static const base::UnguessableToken& devtools_worker_token(
+ const content::EmbeddedWorkerStartParams& info) {
+ return info.devtools_worker_token;
+ }
+ static bool pause_after_download(
+ const content::EmbeddedWorkerStartParams& info) {
+ return info.pause_after_download;
+ }
+ static bool wait_for_debugger(
+ const content::EmbeddedWorkerStartParams& info) {
+ return info.wait_for_debugger;
+ }
+ static bool is_installed(const content::EmbeddedWorkerStartParams& info) {
+ return info.is_installed;
+ }
+ static content::V8CacheOptions v8_cache_options(
+ const content::EmbeddedWorkerStartParams& info) {
+ return info.settings.v8_cache_options;
+ }
+ static bool data_saver_enabled(
+ const content::EmbeddedWorkerStartParams& info) {
+ return info.settings.data_saver_enabled;
+ }
+
+ static bool Read(content::mojom::EmbeddedWorkerStartParamsDataView in,
+ content::EmbeddedWorkerStartParams* out);
+};
+
+} // namespace mojo
+
+#endif // CONTENT_COMMON_SERVICE_WORKER_EMBEDDED_WORKER_START_PARAMS_STRUCT_TRAITS_H_
diff --git a/chromium/content/common/service_worker/service_worker_client_info.cc b/chromium/content/common/service_worker/service_worker_client_info.cc
index b0a2de15b66..19b4f841a01 100644
--- a/chromium/content/common/service_worker/service_worker_client_info.cc
+++ b/chromium/content/common/service_worker/service_worker_client_info.cc
@@ -6,28 +6,30 @@
#include "base/logging.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
+#include "third_party/WebKit/common/service_worker/service_worker_client.mojom.h"
namespace content {
ServiceWorkerClientInfo::ServiceWorkerClientInfo()
: ServiceWorkerClientInfo(std::string(),
- blink::kWebPageVisibilityStateLast,
+ blink::mojom::PageVisibilityState::kLast,
false,
GURL(),
REQUEST_CONTEXT_FRAME_TYPE_LAST,
base::TimeTicks(),
base::TimeTicks(),
- blink::kWebServiceWorkerClientTypeLast) {}
+ blink::mojom::ServiceWorkerClientType::kLast) {}
ServiceWorkerClientInfo::ServiceWorkerClientInfo(
const std::string& client_uuid,
- blink::WebPageVisibilityState page_visibility_state,
+ blink::mojom::PageVisibilityState page_visibility_state,
bool is_focused,
const GURL& url,
RequestContextFrameType frame_type,
base::TimeTicks last_focus_time,
base::TimeTicks create_time,
- blink::WebServiceWorkerClientType client_type)
+ blink::mojom::ServiceWorkerClientType client_type)
: client_uuid(client_uuid),
page_visibility_state(page_visibility_state),
is_focused(is_focused),
@@ -41,10 +43,10 @@ ServiceWorkerClientInfo::ServiceWorkerClientInfo(
const ServiceWorkerClientInfo& other) = default;
bool ServiceWorkerClientInfo::IsEmpty() const {
- return page_visibility_state == blink::kWebPageVisibilityStateLast &&
+ return page_visibility_state == blink::mojom::PageVisibilityState::kLast &&
is_focused == false && url.is_empty() &&
frame_type == REQUEST_CONTEXT_FRAME_TYPE_LAST &&
- client_type == blink::kWebServiceWorkerClientTypeLast;
+ client_type == blink::mojom::ServiceWorkerClientType::kLast;
}
bool ServiceWorkerClientInfo::IsValid() const {
diff --git a/chromium/content/common/service_worker/service_worker_client_info.h b/chromium/content/common/service_worker/service_worker_client_info.h
index 5d789e4b560..630fd43fef5 100644
--- a/chromium/content/common/service_worker/service_worker_client_info.h
+++ b/chromium/content/common/service_worker/service_worker_client_info.h
@@ -7,8 +7,8 @@
#include "base/time/time.h"
#include "content/public/common/request_context_frame_type.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerClientType.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
+#include "third_party/WebKit/common/service_worker/service_worker_client.mojom.h"
#include "url/gurl.h"
namespace content {
@@ -20,14 +20,15 @@ namespace content {
// constructor to fill the properties.
struct ServiceWorkerClientInfo {
ServiceWorkerClientInfo();
- ServiceWorkerClientInfo(const std::string& client_uuid,
- blink::WebPageVisibilityState page_visibility_state,
- bool is_focused,
- const GURL& url,
- RequestContextFrameType frame_type,
- base::TimeTicks last_focus_time,
- base::TimeTicks create_time,
- blink::WebServiceWorkerClientType client_type);
+ ServiceWorkerClientInfo(
+ const std::string& client_uuid,
+ blink::mojom::PageVisibilityState page_visibility_state,
+ bool is_focused,
+ const GURL& url,
+ RequestContextFrameType frame_type,
+ base::TimeTicks last_focus_time,
+ base::TimeTicks create_time,
+ blink::mojom::ServiceWorkerClientType client_type);
ServiceWorkerClientInfo(const ServiceWorkerClientInfo& other);
// Returns whether the instance is empty.
@@ -38,13 +39,13 @@ struct ServiceWorkerClientInfo {
bool IsValid() const;
std::string client_uuid;
- blink::WebPageVisibilityState page_visibility_state;
+ blink::mojom::PageVisibilityState page_visibility_state;
bool is_focused;
GURL url;
RequestContextFrameType frame_type;
base::TimeTicks last_focus_time;
base::TimeTicks create_time;
- blink::WebServiceWorkerClientType client_type;
+ blink::mojom::ServiceWorkerClientType client_type;
};
} // namespace content
diff --git a/chromium/content/common/service_worker/service_worker_container.mojom b/chromium/content/common/service_worker/service_worker_container.mojom
index a998621ffec..3be3efdc123 100644
--- a/chromium/content/common/service_worker/service_worker_container.mojom
+++ b/chromium/content/common/service_worker/service_worker_container.mojom
@@ -5,9 +5,11 @@
module content.mojom;
import "content/common/service_worker/controller_service_worker.mojom";
-import "content/common/service_worker/service_worker_types.mojom";
+import "mojo/common/string16.mojom";
import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom";
+import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom";
import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom";
+import "third_party/WebKit/public/platform/web_feature.mojom";
import "url/mojo/url.mojom";
// mojom::ServiceWorkerContainerHost is a browser-side interface. The renderer
@@ -16,43 +18,41 @@ import "url/mojo/url.mojom";
interface ServiceWorkerContainerHost {
// Corresponds to navigator.serviceWorker.register().
// Registers a service worker from |script_url| with |options|.
- // On success, |error| is kNone with |registration| and |attributes| set.
+ // On success, |error| is kNone with |registration| set.
// Otherwise, |error| and |error_msg| describe the failure.
Register(url.mojom.Url script_url,
blink.mojom.ServiceWorkerRegistrationOptions options)
=> (blink.mojom.ServiceWorkerErrorType error,
string? error_msg,
- blink.mojom.ServiceWorkerRegistrationObjectInfo? registration,
- ServiceWorkerVersionAttributes? attributes);
+ blink.mojom.ServiceWorkerRegistrationObjectInfo? registration);
// Corresponds to navigator.serviceWorker.getRegistration().
// Gets the service worker registration for the |client_url|.
- // On success, |error| is kNone with |registration| and |attributes| set.
+ // On success, |error| is kNone with |registration| set.
+ // In case there is no registration at |client_url|, or the registration is
+ // uninstalling, |error| is still kNone but with null |registration|.
// Otherwise, |error| and |error_msg| describe the failure.
GetRegistration(url.mojom.Url client_url)
=> (blink.mojom.ServiceWorkerErrorType error,
string? error_msg,
- blink.mojom.ServiceWorkerRegistrationObjectInfo? registration,
- ServiceWorkerVersionAttributes? attributes);
+ blink.mojom.ServiceWorkerRegistrationObjectInfo? registration);
// Corresponds to navigator.serviceWorker.getRegistrations().
// Gets all service worker registrations which have the same origin with
// the ServiceWorkerContainer that this interface hosts.
- // On success, |error| is kNone with |infos| and |attrs| set. Otherwise,
- // |error| and |error_msg| describe the failure.
+ // On success, |error| is kNone with |infos| set. Otherwise, |error| and
+ // |error_msg| describe the failure.
GetRegistrations()
=> (blink.mojom.ServiceWorkerErrorType error,
string? error_msg,
- array<blink.mojom.ServiceWorkerRegistrationObjectInfo>? infos,
- array<ServiceWorkerVersionAttributes>? attrs);
+ array<blink.mojom.ServiceWorkerRegistrationObjectInfo>? infos);
// Corresponds to navigator.serviceWorker.ready.
// Returns the service worker registration for the ServiceWorkerContainer that
// this interface hosts, once such a registration exists and has an active
// service worker.
GetRegistrationForReady()
- => (blink.mojom.ServiceWorkerRegistrationObjectInfo? registration,
- ServiceWorkerVersionAttributes? attributes);
+ => (blink.mojom.ServiceWorkerRegistrationObjectInfo? registration);
// S13nServiceWorker:
// Gets a Mojo end point to the controller ServiceWorker. This may start a
@@ -64,11 +64,16 @@ interface ServiceWorkerContainerHost {
// reported to the controllees, but the browser process is responsible for
// properly handling the failure and recording the reasons.
GetControllerServiceWorker(ControllerServiceWorker& controller);
+
+ // 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);
};
// mojom::ServiceWorkerContainer is a renderer-side interface.
// The browser process uses this interface to send messages to documents or
-// the service worker's context.
+// the service worker.
//
// Roughly corresponds to the web-exposed ServiceWorkerContainer interface,
// i.e., navigator.serviceWorker. Actually, the plan is for this interface to be
@@ -79,9 +84,26 @@ interface ServiceWorkerContainerHost {
// that can touch these objects should be a ServiceWorkerContainer, so it’s OK
// to use this name.
interface ServiceWorkerContainer {
- // TODO(xiaofeng.zhang): implement them.
- // SetController();
- // ServiceWorkerStateChanged();
- // ServiceWorkerRegistrationUpdateFound();
- // PostMessage();
+ // Corresponds to setting ServiceWorkerContainer#controller.
+ // If |controller| is invalid (its |handle_id| is invalid), then
+ // ServiceWorkerContainer#controller is cleared.
+ // If |controller| is valid, |used_features| is the set of features the
+ // controller has used, for UseCounter purposes.
+ // If |should_notify_controllerchange| is true, dispatch a 'controllerchange'
+ // event.
+ SetController(blink.mojom.ServiceWorkerObjectInfo controller,
+ array<blink.mojom.WebFeature> used_features,
+ bool should_notify_controllerchange);
+
+ // Corresponds to Client#postMessage().
+ // Sends |message| from the service worker |source| to this service worker
+ // client.
+ // TODO(xiaofeng.zhang): Use blink.mojom.TransferableMessage as the parameter.
+ PostMessageToClient(blink.mojom.ServiceWorkerObjectInfo source,
+ mojo.common.mojom.String16 message,
+ array<handle<message_pipe>> message_ports);
+
+ // Notifies this service worker client that its controller used a |feature|,
+ // for UseCounter purposes.
+ CountFeature(blink.mojom.WebFeature feature);
};
diff --git a/chromium/content/common/service_worker/service_worker_event_dispatcher.mojom b/chromium/content/common/service_worker/service_worker_event_dispatcher.mojom
index 709c64bcc34..bb2b3bf4892 100644
--- a/chromium/content/common/service_worker/service_worker_event_dispatcher.mojom
+++ b/chromium/content/common/service_worker/service_worker_event_dispatcher.mojom
@@ -8,7 +8,6 @@ import "content/common/service_worker/service_worker_fetch_response_callback.moj
import "content/public/common/url_loader.mojom";
import "mojo/common/string16.mojom";
import "mojo/common/time.mojom";
-import "storage/public/interfaces/blobs.mojom";
import "third_party/WebKit/public/platform/modules/background_sync/background_sync.mojom";
import "third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom";
import "third_party/WebKit/public/platform/modules/payments/payment_app.mojom";
@@ -62,7 +61,7 @@ struct ExtendableMessageEvent {
// 'simple events'. ServiceWorkerVersion::CreateSimpleEventCallback can be used
// to create the callback for these.
interface ServiceWorkerEventDispatcher {
- DispatchInstallEvent(associated ServiceWorkerInstallEventMethods method)
+ DispatchInstallEvent()
=> (blink.mojom.ServiceWorkerEventStatus status,
bool has_fetch_handler,
mojo.common.mojom.Time dispatch_event_time);
@@ -92,18 +91,26 @@ interface ServiceWorkerEventDispatcher {
=> (blink.mojom.ServiceWorkerEventStatus status,
mojo.common.mojom.Time dispatch_event_time);
- // The callback is called once the event finishes, which means the event
- // handler ran and all outstanding respondWith() and waitUntil() promises have
- // settled. |response_callback| is called once the promise to respondWith()
- // settles, or when the event handler ran without calling respondWith().
- // |fetch_event_id| is used internally when sending the response with a blob
- // body back to the browser process. In that case, |response_callback| won't
- // be called.
- DispatchFetchEvent(int32 fetch_event_id, blink.mojom.FetchAPIRequest request,
+ // The Dispatch*FetchEvent() callback is called once the event finishes,
+ // which means the event handler ran and all outstanding respondWith() and
+ // waitUntil() promises have settled. |response_callback| is called once the
+ // promise to respondWith() settles, or when the event handler ran without
+ // calling respondWith().
+ //
+ // Non-S13nServiceWorker
+ // TODO(falken): Migrate non-S13nServiceWorker to the non-legacy method.
+ DispatchLegacyFetchEvent(blink.mojom.FetchAPIRequest request,
+ FetchEventPreloadHandle? preload_handle,
+ ServiceWorkerFetchResponseCallback response_callback)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo.common.mojom.Time dispatch_event_time);
+ // S13nServiceWorker
+ DispatchFetchEvent(URLRequest request,
FetchEventPreloadHandle? preload_handle,
ServiceWorkerFetchResponseCallback response_callback)
=> (blink.mojom.ServiceWorkerEventStatus status,
mojo.common.mojom.Time dispatch_event_time);
+
DispatchNotificationClickEvent(string notification_id,
PlatformNotificationData notification_data,
int32 action_index,
@@ -150,11 +157,3 @@ interface ServiceWorkerEventDispatcher {
// dispatch an event.
Ping() => ();
};
-
-// This interface is passed from the browser to the renderer with
-// DispatchInstallEvent. The ordering between RegisterForeignFetchScopes and the
-// callback of DispatchInstallEvent should be preserved.
-interface ServiceWorkerInstallEventMethods {
- RegisterForeignFetchScopes(array<url.mojom.Url> sub_scopes,
- array<url.mojom.Origin> origins);
-};
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 2323e8b681f..aa84fa7240d 100644
--- a/chromium/content/common/service_worker/service_worker_fetch_request.typemap
+++ b/chromium/content/common/service_worker/service_worker_fetch_request.typemap
@@ -18,9 +18,7 @@ sources = [
"//content/common/service_worker/service_worker_fetch_request_struct_traits.cc",
]
type_mappings = [
- "blink.mojom.FetchCredentialsMode=::content::FetchCredentialsMode",
"blink.mojom.FetchRedirectMode=::content::FetchRedirectMode",
- "blink.mojom.FetchRequestMode=::content::FetchRequestMode",
"blink.mojom.FetchAPIRequest=::content::ServiceWorkerFetchRequest",
"blink.mojom.RequestContextFrameType=::content::RequestContextFrameType",
"blink.mojom.RequestContextType=::content::RequestContextType",
diff --git a/chromium/content/common/service_worker/service_worker_fetch_request_struct_traits.cc b/chromium/content/common/service_worker/service_worker_fetch_request_struct_traits.cc
index f5f9439910d..5e7b4b1c5e4 100644
--- a/chromium/content/common/service_worker/service_worker_fetch_request_struct_traits.cc
+++ b/chromium/content/common/service_worker/service_worker_fetch_request_struct_traits.cc
@@ -10,51 +10,11 @@
namespace mojo {
-using blink::mojom::FetchCredentialsMode;
using blink::mojom::FetchRedirectMode;
-using blink::mojom::FetchRequestMode;
using blink::mojom::RequestContextFrameType;
using blink::mojom::RequestContextType;
using blink::mojom::ServiceWorkerFetchType;
-
-FetchCredentialsMode
-EnumTraits<FetchCredentialsMode, content::FetchCredentialsMode>::ToMojom(
- content::FetchCredentialsMode input) {
- switch (input) {
- case content::FETCH_CREDENTIALS_MODE_OMIT:
- return FetchCredentialsMode::OMIT;
- case content::FETCH_CREDENTIALS_MODE_SAME_ORIGIN:
- return FetchCredentialsMode::SAME_ORIGIN;
- case content::FETCH_CREDENTIALS_MODE_INCLUDE:
- return FetchCredentialsMode::INCLUDE;
- case content::FETCH_CREDENTIALS_MODE_PASSWORD:
- return FetchCredentialsMode::PASSWORD;
- }
-
- NOTREACHED();
- return FetchCredentialsMode::OMIT;
-}
-
-bool EnumTraits<FetchCredentialsMode, content::FetchCredentialsMode>::FromMojom(
- FetchCredentialsMode input,
- content::FetchCredentialsMode* out) {
- switch (input) {
- case FetchCredentialsMode::OMIT:
- *out = content::FETCH_CREDENTIALS_MODE_OMIT;
- return true;
- case FetchCredentialsMode::SAME_ORIGIN:
- *out = content::FETCH_CREDENTIALS_MODE_SAME_ORIGIN;
- return true;
- case FetchCredentialsMode::INCLUDE:
- *out = content::FETCH_CREDENTIALS_MODE_INCLUDE;
- return true;
- case FetchCredentialsMode::PASSWORD:
- *out = content::FETCH_CREDENTIALS_MODE_PASSWORD;
- return true;
- }
-
- return false;
-}
+using network::mojom::FetchRequestMode;
FetchRedirectMode
EnumTraits<FetchRedirectMode, content::FetchRedirectMode>::ToMojom(
@@ -90,50 +50,6 @@ bool EnumTraits<FetchRedirectMode, content::FetchRedirectMode>::FromMojom(
return false;
}
-FetchRequestMode
-EnumTraits<FetchRequestMode, content::FetchRequestMode>::ToMojom(
- content::FetchRequestMode input) {
- switch (input) {
- case content::FETCH_REQUEST_MODE_SAME_ORIGIN:
- return FetchRequestMode::SAME_ORIGIN;
- case content::FETCH_REQUEST_MODE_NO_CORS:
- return FetchRequestMode::NO_CORS;
- case content::FETCH_REQUEST_MODE_CORS:
- return FetchRequestMode::CORS;
- case content::FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT:
- return FetchRequestMode::CORS_WITH_FORCED_PREFLIGHT;
- case content::FETCH_REQUEST_MODE_NAVIGATE:
- return FetchRequestMode::NAVIGATE;
- }
-
- NOTREACHED();
- return FetchRequestMode::NO_CORS;
-}
-
-bool EnumTraits<FetchRequestMode, content::FetchRequestMode>::FromMojom(
- FetchRequestMode input,
- content::FetchRequestMode* out) {
- switch (input) {
- case FetchRequestMode::SAME_ORIGIN:
- *out = content::FETCH_REQUEST_MODE_SAME_ORIGIN;
- return true;
- case FetchRequestMode::NO_CORS:
- *out = content::FETCH_REQUEST_MODE_NO_CORS;
- return true;
- case FetchRequestMode::CORS:
- *out = content::FETCH_REQUEST_MODE_CORS;
- return true;
- case FetchRequestMode::CORS_WITH_FORCED_PREFLIGHT:
- *out = content::FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT;
- return true;
- case FetchRequestMode::NAVIGATE:
- *out = content::FETCH_REQUEST_MODE_NAVIGATE;
- return true;
- }
-
- return false;
-}
-
RequestContextFrameType
EnumTraits<RequestContextFrameType, content::RequestContextFrameType>::ToMojom(
content::RequestContextFrameType input) {
@@ -368,8 +284,6 @@ EnumTraits<ServiceWorkerFetchType, content::ServiceWorkerFetchType>::ToMojom(
switch (input) {
case content::ServiceWorkerFetchType::FETCH:
return ServiceWorkerFetchType::FETCH;
- case content::ServiceWorkerFetchType::FOREIGN_FETCH:
- return ServiceWorkerFetchType::FOREIGN_FETCH;
}
NOTREACHED();
@@ -383,9 +297,6 @@ bool EnumTraits<ServiceWorkerFetchType, content::ServiceWorkerFetchType>::
case ServiceWorkerFetchType::FETCH:
*out = content::ServiceWorkerFetchType::FETCH;
return true;
- case ServiceWorkerFetchType::FOREIGN_FETCH:
- *out = content::ServiceWorkerFetchType::FOREIGN_FETCH;
- return true;
}
return false;
@@ -425,9 +336,11 @@ bool StructTraits<blink::mojom::FetchAPIRequestDataView,
out->blob_uuid = blob_uuid.value();
out->blob_size = data.blob_size();
}
- storage::mojom::BlobPtr blob = data.TakeBlob<storage::mojom::BlobPtr>();
+ blink::mojom::BlobPtr blob = data.TakeBlob<blink::mojom::BlobPtr>();
if (blob)
out->blob = base::MakeRefCounted<storage::BlobHandle>(std::move(blob));
+ out->cache_mode = data.cache_mode();
+ out->keepalive = data.keepalive();
out->is_reload = data.is_reload();
return true;
}
diff --git a/chromium/content/common/service_worker/service_worker_fetch_request_struct_traits.h b/chromium/content/common/service_worker/service_worker_fetch_request_struct_traits.h
index c35715425b2..89f0f431ee2 100644
--- a/chromium/content/common/service_worker/service_worker_fetch_request_struct_traits.h
+++ b/chromium/content/common/service_worker/service_worker_fetch_request_struct_traits.h
@@ -13,16 +13,6 @@
namespace mojo {
template <>
-struct EnumTraits<blink::mojom::FetchCredentialsMode,
- content::FetchCredentialsMode> {
- static blink::mojom::FetchCredentialsMode ToMojom(
- content::FetchCredentialsMode input);
-
- static bool FromMojom(blink::mojom::FetchCredentialsMode input,
- content::FetchCredentialsMode* out);
-};
-
-template <>
struct EnumTraits<blink::mojom::FetchRedirectMode, content::FetchRedirectMode> {
static blink::mojom::FetchRedirectMode ToMojom(
content::FetchRedirectMode input);
@@ -32,15 +22,6 @@ struct EnumTraits<blink::mojom::FetchRedirectMode, content::FetchRedirectMode> {
};
template <>
-struct EnumTraits<blink::mojom::FetchRequestMode, content::FetchRequestMode> {
- static blink::mojom::FetchRequestMode ToMojom(
- content::FetchRequestMode input);
-
- static bool FromMojom(blink::mojom::FetchRequestMode input,
- content::FetchRequestMode* out);
-};
-
-template <>
struct EnumTraits<blink::mojom::RequestContextFrameType,
content::RequestContextFrameType> {
static blink::mojom::RequestContextFrameType ToMojom(
@@ -73,7 +54,7 @@ struct EnumTraits<blink::mojom::ServiceWorkerFetchType,
template <>
struct StructTraits<blink::mojom::FetchAPIRequestDataView,
content::ServiceWorkerFetchRequest> {
- static content::FetchRequestMode mode(
+ static network::mojom::FetchRequestMode mode(
const content::ServiceWorkerFetchRequest& request) {
return request.mode;
}
@@ -114,7 +95,7 @@ struct StructTraits<blink::mojom::FetchAPIRequestDataView,
return request.blob_size;
}
- static storage::mojom::BlobPtr blob(
+ static blink::mojom::BlobPtr blob(
const content::ServiceWorkerFetchRequest& request) {
if (!request.blob)
return nullptr;
@@ -126,11 +107,16 @@ struct StructTraits<blink::mojom::FetchAPIRequestDataView,
return request.referrer;
}
- static content::FetchCredentialsMode credentials_mode(
+ static network::mojom::FetchCredentialsMode credentials_mode(
const content::ServiceWorkerFetchRequest& request) {
return request.credentials_mode;
}
+ static blink::mojom::FetchCacheMode cache_mode(
+ const content::ServiceWorkerFetchRequest& request) {
+ return request.cache_mode;
+ }
+
static content::FetchRedirectMode redirect_mode(
const content::ServiceWorkerFetchRequest& request) {
return request.redirect_mode;
@@ -141,6 +127,10 @@ struct StructTraits<blink::mojom::FetchAPIRequestDataView,
return request.integrity;
}
+ static bool keepalive(const content::ServiceWorkerFetchRequest& request) {
+ return request.keepalive;
+ }
+
static const std::string& client_id(
const content::ServiceWorkerFetchRequest& request) {
return request.client_id;
diff --git a/chromium/content/common/service_worker/service_worker_fetch_response_callback.mojom b/chromium/content/common/service_worker/service_worker_fetch_response_callback.mojom
index 567c6ba6745..288b5453ef8 100644
--- a/chromium/content/common/service_worker/service_worker_fetch_response_callback.mojom
+++ b/chromium/content/common/service_worker/service_worker_fetch_response_callback.mojom
@@ -5,7 +5,7 @@
module content.mojom;
import "mojo/common/time.mojom";
-import "storage/public/interfaces/blobs.mojom";
+import "third_party/WebKit/common/blob/blob.mojom";
import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_stream_handle.mojom";
[Native]
@@ -23,8 +23,14 @@ interface ServiceWorkerFetchResponseCallback {
// TODO(kinuko): This should not be necessary once we properly support
// transferring blob within |response|. See crbug.com/75523 for more details.
OnResponseBlob(ServiceWorkerResponse response,
- storage.mojom.Blob body_as_blob,
+ blink.mojom.Blob body_as_blob,
mojo.common.mojom.Time dispatch_event_time);
+ // Responds to the request with |response|. The body is provided as a
+ // non-Mojo Blob via |response.blob_uuid|. The callback is useful for Blob
+ // lifetime management purposes and is called once the caller is done with
+ // the Blob. TODO(kinuko): Remove this once MojoBlob is fully shipped.
+ OnResponseLegacyBlob(ServiceWorkerResponse response,
+ mojo.common.mojom.Time dispatch_event_time) => ();
// Responds to the request with |response|. The body is returned as a stream.
OnResponseStream(ServiceWorkerResponse response,
blink.mojom.ServiceWorkerStreamHandle body_as_stream,
diff --git a/chromium/content/common/service_worker/service_worker_installed_scripts_manager.mojom b/chromium/content/common/service_worker/service_worker_installed_scripts_manager.mojom
index 6179b2727c6..4d815cb2012 100644
--- a/chromium/content/common/service_worker/service_worker_installed_scripts_manager.mojom
+++ b/chromium/content/common/service_worker/service_worker_installed_scripts_manager.mojom
@@ -10,6 +10,7 @@ import "url/mojo/url.mojom";
// Contains information about the scripts of an installed service worker.
struct ServiceWorkerInstalledScriptsInfo {
ServiceWorkerInstalledScriptsManager& manager_request;
+ ServiceWorkerInstalledScriptsManagerHost manager_host_ptr;
array<url.mojom.Url> installed_urls;
};
@@ -29,6 +30,14 @@ struct ServiceWorkerScriptInfo {
uint64 meta_data_size;
};
+// Browser-side interface. The renderer uses this interface to request installed
+// scripts from the browser process.
+interface ServiceWorkerInstalledScriptsManagerHost {
+ // Requests to send the installed scripts over
+ // ServiceWorkerInstalledScriptsManager::TransferInstalledScript.
+ RequestInstalledScript(url.mojom.Url script_url);
+};
+
// Renderer-side interface. The browser uses this interface to send
// information about installed scripts to the renderer.
interface ServiceWorkerInstalledScriptsManager {
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 4be0245a591..a0c0b10caf2 100644
--- a/chromium/content/common/service_worker/service_worker_loader_helpers.cc
+++ b/chromium/content/common/service_worker/service_worker_loader_helpers.cc
@@ -16,8 +16,7 @@ namespace content {
// static
std::unique_ptr<ServiceWorkerFetchRequest>
ServiceWorkerLoaderHelpers::CreateFetchRequest(const ResourceRequest& request) {
- std::unique_ptr<ServiceWorkerFetchRequest> new_request =
- base::MakeUnique<ServiceWorkerFetchRequest>();
+ auto new_request = std::make_unique<ServiceWorkerFetchRequest>();
new_request->mode = request.fetch_request_mode;
new_request->is_main_resource_load =
ServiceWorkerUtils::IsMainResourceType(request.resource_type);
@@ -31,7 +30,10 @@ ServiceWorkerLoaderHelpers::CreateFetchRequest(const ResourceRequest& request) {
new_request->blob_uuid.clear();
new_request->blob_size = 0;
new_request->credentials_mode = request.fetch_credentials_mode;
+ new_request->cache_mode =
+ ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(request.load_flags);
new_request->redirect_mode = request.fetch_redirect_mode;
+ new_request->keepalive = request.keepalive;
new_request->is_reload = ui::PageTransitionCoreTypeIs(
request.transition_type, ui::PAGE_TRANSITION_RELOAD);
new_request->referrer =
@@ -74,7 +76,6 @@ void ServiceWorkerLoaderHelpers::SaveResponseInfo(
const ServiceWorkerResponse& response,
ResourceResponseHead* out_head) {
out_head->was_fetched_via_service_worker = true;
- out_head->was_fetched_via_foreign_fetch = false;
out_head->was_fallback_required_by_service_worker = false;
out_head->url_list_via_service_worker = response.url_list;
out_head->response_type_via_service_worker = response.response_type;
@@ -84,4 +85,34 @@ void ServiceWorkerLoaderHelpers::SaveResponseInfo(
out_head->did_service_worker_navigation_preload = false;
}
+// static
+base::Optional<net::RedirectInfo>
+ServiceWorkerLoaderHelpers::ComputeRedirectInfo(
+ const ResourceRequest& original_request,
+ const ResourceResponseHead& response_head,
+ bool token_binding_negotiated) {
+ std::string new_location;
+ if (!response_head.headers->IsRedirect(&new_location))
+ return base::nullopt;
+
+ std::string referrer_string;
+ net::URLRequest::ReferrerPolicy referrer_policy;
+ Referrer::ComputeReferrerInfo(
+ &referrer_string, &referrer_policy,
+ Referrer(original_request.referrer, original_request.referrer_policy));
+
+ // If the request is a MAIN_FRAME request, the first-party URL gets
+ // updated on redirects.
+ const net::URLRequest::FirstPartyURLPolicy first_party_url_policy =
+ original_request.resource_type == RESOURCE_TYPE_MAIN_FRAME
+ ? net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT
+ : net::URLRequest::NEVER_CHANGE_FIRST_PARTY_URL;
+ return net::RedirectInfo::ComputeRedirectInfo(
+ original_request.method, original_request.url,
+ original_request.site_for_cookies, first_party_url_policy,
+ referrer_policy, referrer_string, response_head.headers.get(),
+ response_head.headers->response_code(),
+ original_request.url.Resolve(new_location), token_binding_negotiated);
+}
+
} // namespace content
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 9ec0a3e4699..293d6d7d764 100644
--- a/chromium/content/common/service_worker/service_worker_loader_helpers.h
+++ b/chromium/content/common/service_worker/service_worker_loader_helpers.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_LOADER_HELPERS_H_
#define CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_LOADER_HELPERS_H_
+#include "base/optional.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "net/url_request/redirect_info.h"
namespace content {
@@ -28,6 +30,13 @@ class ServiceWorkerLoaderHelpers {
// Populates |out_head| (except for headers) with given |response|.
static void SaveResponseInfo(const ServiceWorkerResponse& response,
ResourceResponseHead* out_head);
+
+ // Returns a redirect info if |response_head| is an redirect response.
+ // Otherwise returns base::nullopt.
+ static base::Optional<net::RedirectInfo> ComputeRedirectInfo(
+ const ResourceRequest& original_request,
+ const ResourceResponseHead& response_head,
+ bool token_binding_negotiated);
};
} // namespace content
diff --git a/chromium/content/common/service_worker/service_worker_messages.h b/chromium/content/common/service_worker/service_worker_messages.h
index 1cff0666179..75f74401bf8 100644
--- a/chromium/content/common/service_worker/service_worker_messages.h
+++ b/chromium/content/common/service_worker/service_worker_messages.h
@@ -36,18 +36,15 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::ServiceWorkerErrorType,
IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::ServiceWorkerState,
blink::mojom::ServiceWorkerState::kLast)
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebServiceWorkerResponseError,
- blink::kWebServiceWorkerResponseErrorLast)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::ServiceWorkerResponseError,
+ blink::mojom::ServiceWorkerResponseError::kLast)
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebServiceWorkerClientType,
- blink::kWebServiceWorkerClientTypeLast)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::ServiceWorkerClientType,
+ blink::mojom::ServiceWorkerClientType::kLast)
IPC_ENUM_TRAITS_MAX_VALUE(network::mojom::FetchResponseType,
network::mojom::FetchResponseType::kLast)
-IPC_ENUM_TRAITS_MAX_VALUE(content::ServiceWorkerProviderType,
- content::SERVICE_WORKER_PROVIDER_TYPE_LAST)
-
IPC_ENUM_TRAITS_MAX_VALUE(content::ServiceWorkerFetchType,
content::ServiceWorkerFetchType::LAST)
@@ -56,11 +53,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::ExtendableMessageEventSource)
IPC_STRUCT_TRAITS_MEMBER(service_worker_info)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(content::NavigationPreloadState)
- IPC_STRUCT_TRAITS_MEMBER(enabled)
- IPC_STRUCT_TRAITS_MEMBER(header)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerFetchRequest)
IPC_STRUCT_TRAITS_MEMBER(mode)
IPC_STRUCT_TRAITS_MEMBER(is_main_resource_load)
@@ -76,14 +68,12 @@ IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerFetchRequest)
IPC_STRUCT_TRAITS_MEMBER(credentials_mode)
IPC_STRUCT_TRAITS_MEMBER(redirect_mode)
IPC_STRUCT_TRAITS_MEMBER(integrity)
+ IPC_STRUCT_TRAITS_MEMBER(keepalive)
IPC_STRUCT_TRAITS_MEMBER(client_id)
IPC_STRUCT_TRAITS_MEMBER(is_reload)
IPC_STRUCT_TRAITS_MEMBER(fetch_type)
IPC_STRUCT_TRAITS_END()
-IPC_ENUM_TRAITS_MAX_VALUE(content::ServiceWorkerFetchEventResult,
- content::SERVICE_WORKER_FETCH_EVENT_LAST)
-
IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerResponse)
IPC_STRUCT_TRAITS_MEMBER(url_list)
IPC_STRUCT_TRAITS_MEMBER(status_code)
@@ -98,21 +88,18 @@ IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerResponse)
IPC_STRUCT_TRAITS_MEMBER(is_in_cache_storage)
IPC_STRUCT_TRAITS_MEMBER(cache_storage_cache_name)
IPC_STRUCT_TRAITS_MEMBER(cors_exposed_header_names)
+ IPC_STRUCT_TRAITS_MEMBER(side_data_blob_uuid)
+ IPC_STRUCT_TRAITS_MEMBER(side_data_blob_size)
+ IPC_STRUCT_TRAITS_MEMBER(side_data_blob)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerObjectInfo)
+IPC_STRUCT_TRAITS_BEGIN(blink::mojom::ServiceWorkerObjectInfo)
IPC_STRUCT_TRAITS_MEMBER(handle_id)
IPC_STRUCT_TRAITS_MEMBER(url)
IPC_STRUCT_TRAITS_MEMBER(state)
IPC_STRUCT_TRAITS_MEMBER(version_id)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerVersionAttributes)
- IPC_STRUCT_TRAITS_MEMBER(installing)
- IPC_STRUCT_TRAITS_MEMBER(waiting)
- IPC_STRUCT_TRAITS_MEMBER(active)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerClientInfo)
IPC_STRUCT_TRAITS_MEMBER(client_uuid)
IPC_STRUCT_TRAITS_MEMBER(page_visibility_state)
@@ -127,68 +114,14 @@ IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerClientQueryOptions)
IPC_STRUCT_TRAITS_MEMBER(include_uncontrolled)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_BEGIN(ServiceWorkerMsg_MessageToDocument_Params)
- IPC_STRUCT_MEMBER(int, thread_id)
- IPC_STRUCT_MEMBER(int, provider_id)
- IPC_STRUCT_MEMBER(content::ServiceWorkerObjectInfo, service_worker_info)
- IPC_STRUCT_MEMBER(base::string16, message)
- IPC_STRUCT_MEMBER(std::vector<blink::MessagePortChannel>, message_ports)
-IPC_STRUCT_END()
-
IPC_STRUCT_TRAITS_BEGIN(content::PushEventPayload)
IPC_STRUCT_TRAITS_MEMBER(data)
IPC_STRUCT_TRAITS_MEMBER(is_null)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_BEGIN(ServiceWorkerMsg_SetControllerServiceWorker_Params)
- IPC_STRUCT_MEMBER(int, thread_id)
- IPC_STRUCT_MEMBER(int, provider_id)
- IPC_STRUCT_MEMBER(content::ServiceWorkerObjectInfo, object_info)
- IPC_STRUCT_MEMBER(bool, should_notify_controllerchange)
-
- // |used_features| is the set of features that the worker has used.
- // The values must be from blink::UseCounter::Feature enum.
- IPC_STRUCT_MEMBER(std::set<uint32_t>, used_features)
-IPC_STRUCT_END()
-
//---------------------------------------------------------------------------
// Messages sent from the child process to the browser.
-IPC_MESSAGE_CONTROL4(ServiceWorkerHostMsg_UpdateServiceWorker,
- int /* thread_id */,
- int /* request_id */,
- int /* provider_id */,
- int64_t /* registration_id */)
-
-IPC_MESSAGE_CONTROL4(ServiceWorkerHostMsg_UnregisterServiceWorker,
- int /* thread_id */,
- int /* request_id */,
- int /* provider_id */,
- int64_t /* registration_id */)
-
-// Asks the browser to enable/disable navigation preload for a registration.
-IPC_MESSAGE_CONTROL5(ServiceWorkerHostMsg_EnableNavigationPreload,
- int /* thread_id */,
- int /* request_id */,
- int /* provider_id */,
- int64_t /* registration_id */,
- bool /* enable */)
-
-// Asks the browser to get navigation preload state for a registration.
-IPC_MESSAGE_CONTROL4(ServiceWorkerHostMsg_GetNavigationPreloadState,
- int /* thread_id */,
- int /* request_id */,
- int /* provider_id */,
- int64_t /* registration_id */)
-
-// Asks the browser to set navigation preload header value for a registration.
-IPC_MESSAGE_CONTROL5(ServiceWorkerHostMsg_SetNavigationPreloadHeader,
- int /* thread_id */,
- int /* request_id */,
- int /* provider_id */,
- int64_t /* registration_id */,
- std::string /* header_value */)
-
// Sends ExtendableMessageEvent to a service worker (renderer->browser).
IPC_MESSAGE_CONTROL5(
ServiceWorkerHostMsg_PostMessageToWorker,
@@ -228,16 +161,6 @@ IPC_MESSAGE_ROUTED3(
base::string16 /* message */,
std::vector<blink::MessagePortChannel> /* sent_message_ports */)
-// ServiceWorker -> Browser message to request that the ServiceWorkerStorage
-// cache |data| associated with |url|.
-IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_SetCachedMetadata,
- GURL /* url */,
- std::vector<char> /* data */)
-
-// ServiceWorker -> Browser message to request that the ServiceWorkerStorage
-// clear the cache associated with |url|.
-IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_ClearCachedMetadata, GURL /* url */)
-
// Ask the browser to open a tab/window (renderer->browser).
IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_OpenNewTab,
int /* request_id */,
@@ -276,95 +199,12 @@ IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_ClaimClients,
// extract it and dispatch the message to the correct ServiceWorkerDispatcher
// on the correct thread.
-// Response to ServiceWorkerHostMsg_UpdateServiceWorker.
-IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_ServiceWorkerUpdated,
- int /* thread_id */,
- int /* request_id */)
-
-// Response to ServiceWorkerHostMsg_UnregisterServiceWorker.
-IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_ServiceWorkerUnregistered,
- int /* thread_id */,
- int /* request_id */,
- bool /* is_success */)
-
-// Sent when any kind of update error occurs during a
-// UpdateServiceWorker handler above.
-IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_ServiceWorkerUpdateError,
- int /* thread_id */,
- int /* request_id */,
- blink::mojom::ServiceWorkerErrorType,
- base::string16 /* message */)
-
-// Sent when any kind of registration error occurs during a
-// UnregisterServiceWorker handler above.
-IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_ServiceWorkerUnregistrationError,
- int /* thread_id */,
- int /* request_id */,
- blink::mojom::ServiceWorkerErrorType,
- base::string16 /* message */)
-
// Informs the child process that the ServiceWorker's state has changed.
IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_ServiceWorkerStateChanged,
int /* thread_id */,
int /* handle_id */,
blink::mojom::ServiceWorkerState)
-// Tells the child process to set service workers for the given registration.
-IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_SetVersionAttributes,
- int /* thread_id */,
- int /* registration_handle_id */,
- int /* changed_mask */,
- content::ServiceWorkerVersionAttributes)
-
-// Informs the child process that new ServiceWorker enters the installation
-// phase.
-IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_UpdateFound,
- int /* thread_id */,
- int /* registration_handle_id */)
-
-// Tells the child process to set the controller ServiceWorker for the given
-// provider.
-IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_SetControllerServiceWorker,
- ServiceWorkerMsg_SetControllerServiceWorker_Params)
-
-IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_DidEnableNavigationPreload,
- int /* thread_id */,
- int /* request_id */)
-IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_EnableNavigationPreloadError,
- int /* thread_id */,
- int /* request_id */,
- blink::mojom::ServiceWorkerErrorType,
- std::string /* message */)
-IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_DidGetNavigationPreloadState,
- int /* thread_id */,
- int /* request_id */,
- content::NavigationPreloadState /* state */)
-IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_GetNavigationPreloadStateError,
- int /* thread_id */,
- int /* request_id */,
- blink::mojom::ServiceWorkerErrorType,
- std::string /* message */)
-IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_DidSetNavigationPreloadHeader,
- int /* thread_id */,
- int /* request_id */)
-IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_SetNavigationPreloadHeaderError,
- int /* thread_id */,
- int /* request_id */,
- blink::mojom::ServiceWorkerErrorType,
- std::string /* message */)
-
-// Sends MessageEvent to a client document (browser->renderer).
-IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_MessageToDocument,
- ServiceWorkerMsg_MessageToDocument_Params)
-
-// Notifies a client that its controller used a feature, for UseCounter
-// purposes (browser->renderer). |feature| must be one of the values from
-// blink::UseCounter::Feature enum.
-IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_CountFeature,
- int /* thread_id */,
- int /* provider_id */,
- uint32_t /* feature */)
-
// Sent via EmbeddedWorker to dispatch events.
IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_DidSkipWaiting,
int /* request_id */)
diff --git a/chromium/content/common/service_worker/service_worker_provider.mojom b/chromium/content/common/service_worker/service_worker_provider.mojom
index 0198efeb6b5..44df68c728d 100644
--- a/chromium/content/common/service_worker/service_worker_provider.mojom
+++ b/chromium/content/common/service_worker/service_worker_provider.mojom
@@ -5,19 +5,24 @@
module content.mojom;
import "content/common/service_worker/service_worker_container.mojom";
-import "content/common/service_worker/service_worker_types.mojom";
import "content/public/common/url_loader_factory.mojom";
+import "services/service_manager/public/interfaces/interface_provider.mojom";
+import "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom";
import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom";
+// The name of the InterfaceProviderSpec in service manifests used by the
+// frame tree to expose service-worker-specific interfaces between renderer
+// and browser.
+const string kNavigation_ServiceWorkerSpec = "navigation:service_worker";
+
// Sent from the browser process to the renderer. Contains parameters for the
// constructor of ServiceWorkerNetworkProvider used for starting a service
// worker.
struct ServiceWorkerProviderInfoForStartWorker {
int32 provider_id;
- // |registration| and |attributes| are information about the service worker's
+ // |registration| is information about the service worker's
// registration used to populate ServiceWorkerGlobalScope#registration.
blink.mojom.ServiceWorkerRegistrationObjectInfo registration;
- ServiceWorkerVersionAttributes attributes;
associated ServiceWorkerContainerHost host_ptr_info;
associated ServiceWorkerContainer& client_request;
@@ -26,6 +31,8 @@ struct ServiceWorkerProviderInfoForStartWorker {
// The loader to use for loading the worker's main script and
// importScripts().
associated URLLoaderFactory? script_loader_factory_ptr_info;
+
+ service_manager.mojom.InterfaceProvider interface_provider;
};
// Sent from the renderer to the browser process. Contains parameters that
@@ -35,7 +42,7 @@ struct ServiceWorkerProviderInfoForStartWorker {
struct ServiceWorkerProviderHostInfo {
int32 provider_id;
int32 route_id;
- ServiceWorkerProviderType type;
+ blink.mojom.ServiceWorkerProviderType type;
bool is_parent_frame_secure;
associated ServiceWorkerContainerHost& host_request;
associated ServiceWorkerContainer client_ptr_info;
diff --git a/chromium/content/common/service_worker/service_worker_provider_host_info.cc b/chromium/content/common/service_worker/service_worker_provider_host_info.cc
index 610dbb8ae04..f387c1b5ae8 100644
--- a/chromium/content/common/service_worker/service_worker_provider_host_info.cc
+++ b/chromium/content/common/service_worker/service_worker_provider_host_info.cc
@@ -13,7 +13,7 @@ namespace {
void SetDefaultValues(ServiceWorkerProviderHostInfo* info) {
info->provider_id = kInvalidServiceWorkerProviderId;
info->route_id = MSG_ROUTING_NONE;
- info->type = SERVICE_WORKER_PROVIDER_UNKNOWN;
+ info->type = blink::mojom::ServiceWorkerProviderType::kUnknown;
info->is_parent_frame_secure = false;
}
@@ -22,7 +22,7 @@ void SetDefaultValues(ServiceWorkerProviderHostInfo* info) {
ServiceWorkerProviderHostInfo::ServiceWorkerProviderHostInfo()
: provider_id(kInvalidServiceWorkerProviderId),
route_id(MSG_ROUTING_NONE),
- type(SERVICE_WORKER_PROVIDER_UNKNOWN),
+ type(blink::mojom::ServiceWorkerProviderType::kUnknown),
is_parent_frame_secure(false) {}
ServiceWorkerProviderHostInfo::ServiceWorkerProviderHostInfo(
@@ -54,7 +54,7 @@ ServiceWorkerProviderHostInfo::ServiceWorkerProviderHostInfo(
ServiceWorkerProviderHostInfo::ServiceWorkerProviderHostInfo(
int provider_id,
int route_id,
- ServiceWorkerProviderType type,
+ blink::mojom::ServiceWorkerProviderType type,
bool is_parent_frame_secure)
: provider_id(provider_id),
route_id(route_id),
diff --git a/chromium/content/common/service_worker/service_worker_provider_host_info.h b/chromium/content/common/service_worker/service_worker_provider_host_info.h
index 68b05f9ae44..729eb483184 100644
--- a/chromium/content/common/service_worker/service_worker_provider_host_info.h
+++ b/chromium/content/common/service_worker/service_worker_provider_host_info.h
@@ -7,6 +7,7 @@
#include "content/common/service_worker/service_worker_container.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
namespace content {
@@ -22,7 +23,7 @@ struct CONTENT_EXPORT ServiceWorkerProviderHostInfo {
mojom::ServiceWorkerContainerAssociatedPtrInfo client_ptr_info);
ServiceWorkerProviderHostInfo(int provider_id,
int route_id,
- ServiceWorkerProviderType type,
+ blink::mojom::ServiceWorkerProviderType type,
bool is_parent_frame_secure);
~ServiceWorkerProviderHostInfo();
@@ -40,9 +41,9 @@ struct CONTENT_EXPORT ServiceWorkerProviderHostInfo {
// |route_id| is MSG_ROUTING_NONE.
int route_id;
- // This identifies whether this provider is for Service Worker controllees
- // (documents and Shared Workers) or for controllers (Service Workers).
- ServiceWorkerProviderType type;
+ // This identifies whether this provider is for a service worker or for a
+ // service worker client (Documents and Shared Workers).
+ blink::mojom::ServiceWorkerProviderType type;
// |is_parent_frame_secure| is false if the provider is created for a document
// whose parent frame is not secure from the point of view of the document;
diff --git a/chromium/content/common/service_worker/service_worker_provider_struct_traits.cc b/chromium/content/common/service_worker/service_worker_provider_struct_traits.cc
index a94ecaa1649..59833f84983 100644
--- a/chromium/content/common/service_worker/service_worker_provider_struct_traits.cc
+++ b/chromium/content/common/service_worker/service_worker_provider_struct_traits.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "content/common/service_worker/service_worker_provider_struct_traits.h"
-#include "content/common/service_worker/service_worker_types_struct_traits.h"
namespace mojo {
diff --git a/chromium/content/common/service_worker/service_worker_provider_struct_traits.h b/chromium/content/common/service_worker/service_worker_provider_struct_traits.h
index 11de12050fa..f099711a905 100644
--- a/chromium/content/common/service_worker/service_worker_provider_struct_traits.h
+++ b/chromium/content/common/service_worker/service_worker_provider_struct_traits.h
@@ -6,6 +6,7 @@
#define CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_STRUCT_TRAITS_H_
#include "content/common/service_worker/service_worker_provider.mojom.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
namespace mojo {
@@ -21,7 +22,7 @@ struct StructTraits<content::mojom::ServiceWorkerProviderHostInfoDataView,
return info.route_id;
}
- static content::ServiceWorkerProviderType type(
+ static blink::mojom::ServiceWorkerProviderType type(
const content::ServiceWorkerProviderHostInfo& info) {
return info.type;
}
diff --git a/chromium/content/common/service_worker/service_worker_types.cc b/chromium/content/common/service_worker/service_worker_types.cc
index acd914b074d..845669b6893 100644
--- a/chromium/content/common/service_worker/service_worker_types.cc
+++ b/chromium/content/common/service_worker/service_worker_types.cc
@@ -5,6 +5,7 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/service_worker_modes.h"
+#include "net/base/load_flags.h"
#include "storage/common/blob_storage/blob_handle.h"
namespace content {
@@ -22,16 +23,7 @@ const char kServiceWorkerGetRegistrationsErrorPrefix[] =
const char kFetchScriptError[] =
"An unknown error occurred when fetching the script.";
-ServiceWorkerFetchRequest::ServiceWorkerFetchRequest()
- : mode(FETCH_REQUEST_MODE_NO_CORS),
- is_main_resource_load(false),
- request_context_type(REQUEST_CONTEXT_TYPE_UNSPECIFIED),
- frame_type(REQUEST_CONTEXT_FRAME_TYPE_NONE),
- blob_size(0),
- credentials_mode(FETCH_CREDENTIALS_MODE_OMIT),
- redirect_mode(FetchRedirectMode::FOLLOW_MODE),
- is_reload(false),
- fetch_type(ServiceWorkerFetchType::FETCH) {}
+ServiceWorkerFetchRequest::ServiceWorkerFetchRequest() = default;
ServiceWorkerFetchRequest::ServiceWorkerFetchRequest(
const GURL& url,
@@ -39,19 +31,11 @@ ServiceWorkerFetchRequest::ServiceWorkerFetchRequest(
const ServiceWorkerHeaderMap& headers,
const Referrer& referrer,
bool is_reload)
- : mode(FETCH_REQUEST_MODE_NO_CORS),
- is_main_resource_load(false),
- request_context_type(REQUEST_CONTEXT_TYPE_UNSPECIFIED),
- frame_type(REQUEST_CONTEXT_FRAME_TYPE_NONE),
- url(url),
+ : url(url),
method(method),
headers(headers),
- blob_size(0),
referrer(referrer),
- credentials_mode(FETCH_CREDENTIALS_MODE_OMIT),
- redirect_mode(FetchRedirectMode::FOLLOW_MODE),
- is_reload(is_reload),
- fetch_type(ServiceWorkerFetchType::FETCH) {}
+ is_reload(is_reload) {}
ServiceWorkerFetchRequest::ServiceWorkerFetchRequest(
const ServiceWorkerFetchRequest& other) = default;
@@ -75,11 +59,40 @@ size_t ServiceWorkerFetchRequest::EstimatedStructSize() {
return size;
}
+// 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;
+}
+
ServiceWorkerResponse::ServiceWorkerResponse()
: status_code(0),
response_type(network::mojom::FetchResponseType::kOpaque),
blob_size(0),
- error(blink::kWebServiceWorkerResponseErrorUnknown) {}
+ error(blink::mojom::ServiceWorkerResponseError::kUnknown) {}
ServiceWorkerResponse::ServiceWorkerResponse(
std::unique_ptr<std::vector<GURL>> url_list,
@@ -90,7 +103,7 @@ ServiceWorkerResponse::ServiceWorkerResponse(
const std::string& blob_uuid,
uint64_t blob_size,
scoped_refptr<storage::BlobHandle> blob,
- blink::WebServiceWorkerResponseError error,
+ blink::mojom::ServiceWorkerResponseError error,
base::Time response_time,
bool is_in_cache_storage,
const std::string& cache_storage_cache_name,
@@ -130,21 +143,12 @@ size_t ServiceWorkerResponse::EstimatedStructSize() {
}
for (const auto& header : cors_exposed_header_names)
size += header.size();
+ size += side_data_blob_uuid.size();
return size;
}
-ServiceWorkerObjectInfo::ServiceWorkerObjectInfo()
- : handle_id(kInvalidServiceWorkerHandleId),
- state(blink::mojom::ServiceWorkerState::kUnknown),
- version_id(kInvalidServiceWorkerVersionId) {}
-
-bool ServiceWorkerObjectInfo::IsValid() const {
- return handle_id != kInvalidServiceWorkerHandleId &&
- version_id != kInvalidServiceWorkerVersionId;
-}
-
ServiceWorkerClientQueryOptions::ServiceWorkerClientQueryOptions()
- : client_type(blink::kWebServiceWorkerClientTypeWindow),
+ : client_type(blink::mojom::ServiceWorkerClientType::kWindow),
include_uncontrolled(false) {}
ExtendableMessageEventSource::ExtendableMessageEventSource() {}
@@ -154,16 +158,7 @@ ExtendableMessageEventSource::ExtendableMessageEventSource(
: client_info(client_info) {}
ExtendableMessageEventSource::ExtendableMessageEventSource(
- const ServiceWorkerObjectInfo& service_worker_info)
+ const blink::mojom::ServiceWorkerObjectInfo& service_worker_info)
: service_worker_info(service_worker_info) {}
-NavigationPreloadState::NavigationPreloadState()
- : enabled(false), header("true") {}
-
-NavigationPreloadState::NavigationPreloadState(bool enabled, std::string header)
- : enabled(enabled), header(header) {}
-
-NavigationPreloadState::NavigationPreloadState(
- const NavigationPreloadState& other) = default;
-
} // 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 123f986b037..5a3670351b4 100644
--- a/chromium/content/common/service_worker/service_worker_types.h
+++ b/chromium/content/common/service_worker/service_worker_types.h
@@ -20,9 +20,11 @@
#include "content/public/common/request_context_type.h"
#include "content/public/common/service_worker_modes.h"
#include "services/network/public/interfaces/fetch_api.mojom.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerClientType.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponseError.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
+#include "third_party/WebKit/common/service_worker/service_worker_client.mojom.h"
+#include "third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h"
+#include "third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_state.mojom.h"
#include "url/gurl.h"
@@ -49,8 +51,6 @@ extern const char kServiceWorkerGetRegistrationsErrorPrefix[];
extern const char kFetchScriptError[];
// Constants for invalid identifiers.
-static const int kInvalidServiceWorkerHandleId = -1;
-static const int64_t kInvalidServiceWorkerVersionId = -1;
static const int64_t kInvalidServiceWorkerResourceId = -1;
static const int kInvalidEmbeddedWorkerThreadId = -1;
@@ -59,31 +59,6 @@ static const int kInvalidEmbeddedWorkerThreadId = -1;
static constexpr base::TimeDelta kServiceWorkerScriptMaxCacheAge =
base::TimeDelta::FromHours(24);
-// ServiceWorker provider type.
-enum ServiceWorkerProviderType {
- SERVICE_WORKER_PROVIDER_UNKNOWN,
-
- // For ServiceWorker clients.
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- SERVICE_WORKER_PROVIDER_FOR_WORKER,
- SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER,
-
- // For ServiceWorkers.
- SERVICE_WORKER_PROVIDER_FOR_CONTROLLER,
-
- SERVICE_WORKER_PROVIDER_TYPE_LAST =
- SERVICE_WORKER_PROVIDER_FOR_CONTROLLER
-};
-
-// Indicates how the service worker handled a fetch event.
-enum ServiceWorkerFetchEventResult {
- // Browser should fallback to native fetch.
- SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
- // Service worker provided a ServiceWorkerResponse.
- SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
- SERVICE_WORKER_FETCH_EVENT_LAST = SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE
-};
-
struct ServiceWorkerCaseInsensitiveCompare {
bool operator()(const std::string& lhs, const std::string& rhs) const {
return base::CompareCaseInsensitiveASCII(lhs, rhs) < 0;
@@ -108,24 +83,31 @@ struct CONTENT_EXPORT ServiceWorkerFetchRequest {
~ServiceWorkerFetchRequest();
size_t EstimatedStructSize();
- // Be sure to update EstimatedSize() when adding members.
- FetchRequestMode mode;
- bool is_main_resource_load;
- RequestContextType request_context_type;
- RequestContextFrameType frame_type;
+ static blink::mojom::FetchCacheMode GetCacheModeFromLoadFlags(int load_flags);
+
+ // Be sure to update EstimatedStructSize() when adding members.
+ network::mojom::FetchRequestMode mode =
+ network::mojom::FetchRequestMode::kNoCORS;
+ bool is_main_resource_load = false;
+ RequestContextType request_context_type = REQUEST_CONTEXT_TYPE_UNSPECIFIED;
+ RequestContextFrameType frame_type = REQUEST_CONTEXT_FRAME_TYPE_NONE;
GURL url;
std::string method;
ServiceWorkerHeaderMap headers;
std::string blob_uuid;
- uint64_t blob_size;
+ uint64_t blob_size = 0;
scoped_refptr<storage::BlobHandle> blob;
Referrer referrer;
- FetchCredentialsMode credentials_mode;
- FetchRedirectMode redirect_mode;
+ network::mojom::FetchCredentialsMode credentials_mode =
+ network::mojom::FetchCredentialsMode::kOmit;
+ blink::mojom::FetchCacheMode cache_mode =
+ blink::mojom::FetchCacheMode::kDefault;
+ FetchRedirectMode redirect_mode = FetchRedirectMode::FOLLOW_MODE;
std::string integrity;
+ bool keepalive = false;
std::string client_id;
- bool is_reload;
- ServiceWorkerFetchType fetch_type;
+ bool is_reload = false;
+ ServiceWorkerFetchType fetch_type = ServiceWorkerFetchType::FETCH;
};
// Represents a response to a fetch.
@@ -140,7 +122,7 @@ struct CONTENT_EXPORT ServiceWorkerResponse {
const std::string& blob_uuid,
uint64_t blob_size,
scoped_refptr<storage::BlobHandle> blob,
- blink::WebServiceWorkerResponseError error,
+ blink::mojom::ServiceWorkerResponseError error,
base::Time response_time,
bool is_in_cache_storage,
const std::string& cache_storage_cache_name,
@@ -150,7 +132,7 @@ struct CONTENT_EXPORT ServiceWorkerResponse {
~ServiceWorkerResponse();
size_t EstimatedStructSize();
- // Be sure to update EstimatedSize() when adding members.
+ // Be sure to update EstimatedStructSize() when adding members.
std::vector<GURL> url_list;
int status_code;
std::string status_text;
@@ -163,31 +145,17 @@ struct CONTENT_EXPORT ServiceWorkerResponse {
uint64_t blob_size;
// |blob| is only used when features::kMojoBlobs is enabled.
scoped_refptr<storage::BlobHandle> blob;
- blink::WebServiceWorkerResponseError error;
+ blink::mojom::ServiceWorkerResponseError error;
base::Time response_time;
bool is_in_cache_storage = false;
std::string cache_storage_cache_name;
ServiceWorkerHeaderList cors_exposed_header_names;
-};
-
-// Represents initialization info for a WebServiceWorker object.
-struct CONTENT_EXPORT ServiceWorkerObjectInfo {
- ServiceWorkerObjectInfo();
-
- // Returns whether the instance is valid. A valid instance has valid
- // |handle_id| and |version_id|.
- bool IsValid() const;
-
- int handle_id;
- GURL url;
- blink::mojom::ServiceWorkerState state;
- int64_t version_id;
-};
-struct CONTENT_EXPORT ServiceWorkerVersionAttributes {
- ServiceWorkerObjectInfo installing;
- ServiceWorkerObjectInfo waiting;
- ServiceWorkerObjectInfo active;
+ // Side data is used to pass the metadata of the response (eg: V8 code cache).
+ std::string side_data_blob_uuid;
+ uint64_t side_data_blob_size = 0;
+ // |side_data_blob| is only used when features::kMojoBlobs is enabled.
+ scoped_refptr<storage::BlobHandle> side_data_blob;
};
class ChangedVersionAttributesMask {
@@ -216,7 +184,7 @@ class ChangedVersionAttributesMask {
struct ServiceWorkerClientQueryOptions {
ServiceWorkerClientQueryOptions();
- blink::WebServiceWorkerClientType client_type;
+ blink::mojom::ServiceWorkerClientType client_type;
bool include_uncontrolled;
};
@@ -225,19 +193,11 @@ struct ExtendableMessageEventSource {
explicit ExtendableMessageEventSource(
const ServiceWorkerClientInfo& client_info);
explicit ExtendableMessageEventSource(
- const ServiceWorkerObjectInfo& service_worker_info);
+ const blink::mojom::ServiceWorkerObjectInfo& service_worker_info);
// Exactly one of these infos should be valid.
ServiceWorkerClientInfo client_info;
- ServiceWorkerObjectInfo service_worker_info;
-};
-
-struct CONTENT_EXPORT NavigationPreloadState {
- NavigationPreloadState();
- NavigationPreloadState(bool enabled, std::string header);
- NavigationPreloadState(const NavigationPreloadState& other);
- bool enabled;
- std::string header;
+ blink::mojom::ServiceWorkerObjectInfo service_worker_info;
};
} // namespace content
diff --git a/chromium/content/common/service_worker/service_worker_types.mojom b/chromium/content/common/service_worker/service_worker_types.mojom
deleted file mode 100644
index ae8c0bd40f0..00000000000
--- a/chromium/content/common/service_worker/service_worker_types.mojom
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module content.mojom;
-
-enum ServiceWorkerProviderType {
- SERVICE_WORKER_PROVIDER_UNKNOWN,
-
- // For ServiceWorker clients.
- SERVICE_WORKER_PROVIDER_FOR_WINDOW,
- SERVICE_WORKER_PROVIDER_FOR_WORKER,
- SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER,
-
- // For ServiceWorkers.
- SERVICE_WORKER_PROVIDER_FOR_CONTROLLER,
-
- SERVICE_WORKER_PROVIDER_TYPE_LAST =
- SERVICE_WORKER_PROVIDER_FOR_CONTROLLER
-};
-
-// Struct for delivering the information about the installing, waiting and
-// active ServiceWorkers.
-// Defined in service_worker_types.h.
-[Native]
-struct ServiceWorkerVersionAttributes;
diff --git a/chromium/content/common/service_worker/service_worker_types.typemap b/chromium/content/common/service_worker/service_worker_types.typemap
deleted file mode 100644
index ed6313591de..00000000000
--- a/chromium/content/common/service_worker/service_worker_types.typemap
+++ /dev/null
@@ -1,20 +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.
-
-mojom = "//content/common/service_worker/service_worker_types.mojom"
-public_headers = [
- "//content/common/service_worker/service_worker_client_info.h",
- "//content/common/service_worker/service_worker_types.h",
-]
-traits_headers = [
- "//content/common/service_worker/service_worker_messages.h",
- "//content/common/service_worker/service_worker_types_struct_traits.h",
-]
-sources = [
- "//content/common/service_worker/service_worker_types_struct_traits.cc",
-]
-type_mappings = [
- "content.mojom.ServiceWorkerProviderType=::content::ServiceWorkerProviderType",
- "content.mojom.ServiceWorkerVersionAttributes=::content::ServiceWorkerVersionAttributes",
-]
diff --git a/chromium/content/common/service_worker/service_worker_types_struct_traits.cc b/chromium/content/common/service_worker/service_worker_types_struct_traits.cc
deleted file mode 100644
index 3e40fd520d4..00000000000
--- a/chromium/content/common/service_worker/service_worker_types_struct_traits.cc
+++ /dev/null
@@ -1,58 +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/common/service_worker/service_worker_types_struct_traits.h"
-
-#include "base/logging.h"
-
-namespace mojo {
-
-using content::mojom::ServiceWorkerProviderType;
-
-ServiceWorkerProviderType
-EnumTraits<ServiceWorkerProviderType, content::ServiceWorkerProviderType>::
- ToMojom(content::ServiceWorkerProviderType input) {
- switch (input) {
- case content::SERVICE_WORKER_PROVIDER_UNKNOWN:
- return ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_UNKNOWN;
- case content::SERVICE_WORKER_PROVIDER_FOR_WINDOW:
- return ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_FOR_WINDOW;
- case content::SERVICE_WORKER_PROVIDER_FOR_WORKER:
- return ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_FOR_WORKER;
- case content::SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER:
- return ServiceWorkerProviderType::
- SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER;
- case content::SERVICE_WORKER_PROVIDER_FOR_CONTROLLER:
- return ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_FOR_CONTROLLER;
- }
-
- NOTREACHED();
- return ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_UNKNOWN;
-}
-
-bool EnumTraits<ServiceWorkerProviderType, content::ServiceWorkerProviderType>::
- FromMojom(ServiceWorkerProviderType input,
- content::ServiceWorkerProviderType* out) {
- switch (input) {
- case ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_UNKNOWN:
- *out = content::SERVICE_WORKER_PROVIDER_UNKNOWN;
- return true;
- case ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_FOR_WINDOW:
- *out = content::SERVICE_WORKER_PROVIDER_FOR_WINDOW;
- return true;
- case ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_FOR_WORKER:
- *out = content::SERVICE_WORKER_PROVIDER_FOR_WORKER;
- return true;
- case ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER:
- *out = content::SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER;
- return true;
- case ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_FOR_CONTROLLER:
- *out = content::SERVICE_WORKER_PROVIDER_FOR_CONTROLLER;
- return true;
- }
-
- return false;
-}
-
-} // namespace mojo
diff --git a/chromium/content/common/service_worker/service_worker_types_struct_traits.h b/chromium/content/common/service_worker/service_worker_types_struct_traits.h
deleted file mode 100644
index fb4670de56a..00000000000
--- a/chromium/content/common/service_worker/service_worker_types_struct_traits.h
+++ /dev/null
@@ -1,24 +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_COMMON_SERVICE_WORKER_SERVICE_WORKER_TYPES_STRUCT_TRAITS_H_
-#define CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_TYPES_STRUCT_TRAITS_H_
-
-#include "content/common/service_worker/service_worker_types.mojom.h"
-
-namespace mojo {
-
-template <>
-struct EnumTraits<content::mojom::ServiceWorkerProviderType,
- content::ServiceWorkerProviderType> {
- static content::mojom::ServiceWorkerProviderType ToMojom(
- content::ServiceWorkerProviderType input);
-
- static bool FromMojom(content::mojom::ServiceWorkerProviderType input,
- content::ServiceWorkerProviderType* out);
-};
-
-} // namespace mojo
-
-#endif // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_TYPES_STRUCT_TRAITS_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
new file mode 100644
index 00000000000..9a5373ac91c
--- /dev/null
+++ b/chromium/content/common/service_worker/service_worker_types_unittest.cc
@@ -0,0 +1,44 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/service_worker/service_worker_types.h"
+#include "testing/gtest/include/gtest/gtest.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));
+}
+
+} // namespace
+
+} // namespace content
diff --git a/chromium/content/common/service_worker/service_worker_utils.cc b/chromium/content/common/service_worker/service_worker_utils.cc
index 92b9eee0d48..0494a2c8930 100644
--- a/chromium/content/common/service_worker/service_worker_utils.cc
+++ b/chromium/content/common/service_worker/service_worker_utils.cc
@@ -156,6 +156,14 @@ std::string ServiceWorkerUtils::ErrorTypeToString(
return oss.str();
}
+// static
+std::string ServiceWorkerUtils::ClientTypeToString(
+ blink::mojom::ServiceWorkerClientType type) {
+ std::ostringstream oss;
+ oss << type;
+ return oss.str();
+}
+
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 3dbd936f8b6..ec88d104657 100644
--- a/chromium/content/common/service_worker/service_worker_utils.h
+++ b/chromium/content/common/service_worker/service_worker_utils.h
@@ -44,7 +44,7 @@ class ServiceWorkerUtils {
const GURL& script_url,
std::string* error_message);
- static bool IsScriptStreamingEnabled();
+ CONTENT_EXPORT static bool IsScriptStreamingEnabled();
// Returns true if all members of |urls| have the same origin, and
// OriginCanAccessServiceWorkers is true for this origin.
@@ -64,6 +64,9 @@ class ServiceWorkerUtils {
static std::string ErrorTypeToString(
blink::mojom::ServiceWorkerErrorType error);
+
+ static std::string ClientTypeToString(
+ blink::mojom::ServiceWorkerClientType type);
};
class CONTENT_EXPORT LongestScopeMatcher {
diff --git a/chromium/content/common/shared_worker/shared_worker_factory.mojom b/chromium/content/common/shared_worker/shared_worker_factory.mojom
index 98ece293006..a4d868316d8 100644
--- a/chromium/content/common/shared_worker/shared_worker_factory.mojom
+++ b/chromium/content/common/shared_worker/shared_worker_factory.mojom
@@ -7,8 +7,15 @@ module content.mojom;
import "content/common/shared_worker/shared_worker.mojom";
import "content/common/shared_worker/shared_worker_host.mojom";
import "content/common/shared_worker/shared_worker_info.mojom";
+import "mojo/common/unguessable_token.mojom";
+import "services/service_manager/public/interfaces/interface_provider.mojom";
import "third_party/WebKit/public/web/worker_content_settings_proxy.mojom";
+// The name of the InterfaceProviderSpec in service manifests used by the
+// frame tree to expose shared-worker-specific interfaces between renderer and
+// browser.
+const string kNavigation_SharedWorkerSpec = "navigation:shared_worker";
+
// This interface is used to instantiate a shared worker. It is exported from a
// child process where the shared worker should run.
interface SharedWorkerFactory {
@@ -18,10 +25,15 @@ interface SharedWorkerFactory {
// TODO(darin): Eliminate |route_id| corresponding to legacy Chrome IPC,
// which is only needed for DevTools.
//
- CreateSharedWorker(SharedWorkerInfo info,
- bool pause_on_start,
- int32 route_id,
- blink.mojom.WorkerContentSettingsProxy content_settings,
- SharedWorkerHost host,
- SharedWorker& shared_worker);
+ // TODO(sammc): Change shared workers to obtain |content_settings| via
+ // |interface_provider| instead of receiving plumbing it here.
+ CreateSharedWorker(
+ SharedWorkerInfo info,
+ bool pause_on_start,
+ mojo.common.mojom.UnguessableToken devtools_worker_token,
+ int32 route_id,
+ blink.mojom.WorkerContentSettingsProxy content_settings,
+ SharedWorkerHost host,
+ SharedWorker& shared_worker,
+ service_manager.mojom.InterfaceProvider interface_provider);
};
diff --git a/chromium/content/common/shared_worker/shared_worker_info.mojom b/chromium/content/common/shared_worker/shared_worker_info.mojom
index 0b415391433..7b7e3ea8845 100644
--- a/chromium/content/common/shared_worker/shared_worker_info.mojom
+++ b/chromium/content/common/shared_worker/shared_worker_info.mojom
@@ -18,5 +18,4 @@ struct SharedWorkerInfo {
string content_security_policy;
blink.mojom.ContentSecurityPolicyType content_security_policy_type;
blink.mojom.AddressSpace creation_address_space;
- bool data_saver_enabled;
};
diff --git a/chromium/content/common/site_isolation_policy.cc b/chromium/content/common/site_isolation_policy.cc
index 16035a81660..b91327e0577 100644
--- a/chromium/content/common/site_isolation_policy.cc
+++ b/chromium/content/common/site_isolation_policy.cc
@@ -8,9 +8,11 @@
#include "base/command_line.h"
#include "base/feature_list.h"
+#include "base/macros.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_split.h"
+#include "base/timer/timer.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "url/gurl.h"
@@ -95,6 +97,19 @@ std::vector<url::Origin> SiteIsolationPolicy::ParseIsolatedOrigins(
}
// static
+void SiteIsolationPolicy::StartRecordingSiteIsolationFlagUsage() {
+ RecordSiteIsolationFlagUsage();
+ // Record the flag usage metrics every 24 hours. Even though site isolation
+ // 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(
+ FROM_HERE, base::TimeDelta::FromHours(24),
+ base::BindRepeating(&SiteIsolationPolicy::RecordSiteIsolationFlagUsage));
+}
+
+// static
void SiteIsolationPolicy::RecordSiteIsolationFlagUsage() {
// For --site-per-process and --isolate-origins, include flags specified on
// command-line, in chrome://flags, and via enterprise policy (i.e., include
diff --git a/chromium/content/common/site_isolation_policy.h b/chromium/content/common/site_isolation_policy.h
index eb4b799d0d3..1d416f428ce 100644
--- a/chromium/content/common/site_isolation_policy.h
+++ b/chromium/content/common/site_isolation_policy.h
@@ -49,9 +49,10 @@ class CONTENT_EXPORT SiteIsolationPolicy {
// ContentBrowserClient::GetOriginsRequiringDedicatedProcess.
static std::vector<url::Origin> GetIsolatedOrigins();
- // Records metrics about which site isolation command-line flags are present.
- // This should be called once on browser startup.
- static void RecordSiteIsolationFlagUsage();
+ // Records metrics about which site isolation command-line flags are present,
+ // and sets up a timer to keep recording them every 24 hours. This should be
+ // called once on browser startup.
+ static void StartRecordingSiteIsolationFlagUsage();
private:
SiteIsolationPolicy(); // Not instantiable.
@@ -59,6 +60,9 @@ class CONTENT_EXPORT SiteIsolationPolicy {
FRIEND_TEST_ALL_PREFIXES(SiteIsolationPolicyTest, ParseIsolatedOrigins);
static std::vector<url::Origin> ParseIsolatedOrigins(base::StringPiece arg);
+ // Records metrics about which site isolation command-line flags are present.
+ static void RecordSiteIsolationFlagUsage();
+
DISALLOW_COPY_AND_ASSIGN(SiteIsolationPolicy);
};
diff --git a/chromium/content/common/speech_recognition_messages.h b/chromium/content/common/speech_recognition_messages.h
index c004e5c01fd..e9d7f0693e4 100644
--- a/chromium/content/common/speech_recognition_messages.h
+++ b/chromium/content/common/speech_recognition_messages.h
@@ -9,14 +9,11 @@
#include <string>
-#include "base/memory/shared_memory.h"
-#include "base/sync_socket.h"
#include "content/public/common/speech_recognition_error.h"
#include "content/public/common/speech_recognition_grammar.h"
#include "content/public/common/speech_recognition_result.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_param_traits.h"
-#include "media/base/audio_parameters.h"
#include "ui/gfx/geometry/rect.h"
#define IPC_MESSAGE_START SpeechRecognitionMsgStart
@@ -68,8 +65,6 @@ IPC_STRUCT_BEGIN(SpeechRecognitionHostMsg_StartRequest_Params)
IPC_STRUCT_MEMBER(bool, continuous)
// Whether the user requested interim results or not.
IPC_STRUCT_MEMBER(bool, interim_results)
- // Wheter the user has set an audio track as input or not.
- IPC_STRUCT_MEMBER(bool, using_audio_track)
IPC_STRUCT_END()
@@ -123,10 +118,4 @@ IPC_MESSAGE_ROUTED1(SpeechRecognitionMsg_AudioEnded, int /* request_id */)
IPC_MESSAGE_ROUTED1(SpeechRecognitionMsg_Ended, int /* request_id */)
-IPC_MESSAGE_ROUTED4(SpeechRecognitionMsg_AudioReceiverReady,
- int /* request_id */,
- media::AudioParameters /* params */,
- base::SharedMemoryHandle /* memory */,
- base::SyncSocket::TransitDescriptor /* socket */)
-
#endif // CONTENT_COMMON_SPEECH_RECOGNITION_MESSAGES_H_
diff --git a/chromium/content/common/storage_partition_service.mojom b/chromium/content/common/storage_partition_service.mojom
index 5aca10a86e5..9e1816e75ef 100644
--- a/chromium/content/common/storage_partition_service.mojom
+++ b/chromium/content/common/storage_partition_service.mojom
@@ -11,4 +11,7 @@ import "url/mojo/origin.mojom";
interface StoragePartitionService {
OpenLocalStorage(url.mojom.Origin origin,
LevelDBWrapper& database);
+ OpenSessionStorage(int64 namespace_id,
+ url.mojom.Origin origin,
+ LevelDBWrapper& database);
};
diff --git a/chromium/content/common/throttling_url_loader.cc b/chromium/content/common/throttling_url_loader.cc
index ba68b0580a1..cfa211a788f 100644
--- a/chromium/content/common/throttling_url_loader.cc
+++ b/chromium/content/common/throttling_url_loader.cc
@@ -149,13 +149,14 @@ std::unique_ptr<ThrottlingURLLoader> ThrottlingURLLoader::CreateLoaderAndStart(
std::unique_ptr<ThrottlingURLLoader> ThrottlingURLLoader::CreateLoaderAndStart(
StartLoaderCallback start_loader_callback,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
+ int32_t routing_id,
const ResourceRequest& url_request,
mojom::URLLoaderClient* client,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
std::unique_ptr<ThrottlingURLLoader> loader(new ThrottlingURLLoader(
std::move(throttles), client, traffic_annotation));
- loader->Start(nullptr, 0, 0, mojom::kURLLoadOptionNone,
+ loader->Start(nullptr, routing_id, 0, mojom::kURLLoadOptionNone,
std::move(start_loader_callback), url_request,
std::move(task_runner));
return loader;
@@ -187,7 +188,7 @@ void ThrottlingURLLoader::SetPriority(net::RequestPriority priority,
if (!loader_cancelled_) {
DCHECK_EQ(DEFERRED_START, deferred_stage_);
priority_info_ =
- base::MakeUnique<PriorityInfo>(priority, intra_priority_value);
+ std::make_unique<PriorityInfo>(priority, intra_priority_value);
}
return;
}
@@ -241,7 +242,7 @@ void ThrottlingURLLoader::Start(
if (deferred) {
deferred_stage_ = DEFERRED_START;
start_info_ =
- base::MakeUnique<StartInfo>(factory, routing_id, request_id, options,
+ std::make_unique<StartInfo>(factory, routing_id, request_id, options,
std::move(start_loader_callback),
url_request, std::move(task_runner));
return;
@@ -286,6 +287,9 @@ void ThrottlingURLLoader::StartNow(
url_loader_->SetPriority(priority_info->priority,
priority_info->intra_priority_value);
}
+
+ // Initialize with the request URL, may be updated when on redirects
+ response_url_ = url_request.url;
}
bool ThrottlingURLLoader::HandleThrottleResult(URLLoaderThrottle* throttle,
@@ -323,14 +327,15 @@ void ThrottlingURLLoader::OnReceiveResponse(
for (auto& entry : throttles_) {
auto* throttle = entry.throttle.get();
bool throttle_deferred = false;
- throttle->WillProcessResponse(&throttle_deferred);
+ throttle->WillProcessResponse(response_url_, response_head,
+ &throttle_deferred);
if (!HandleThrottleResult(throttle, throttle_deferred, &deferred))
return;
}
if (deferred) {
deferred_stage_ = DEFERRED_RESPONSE;
- response_info_ = base::MakeUnique<ResponseInfo>(
+ response_info_ = std::make_unique<ResponseInfo>(
response_head, ssl_info, std::move(downloaded_file));
client_binding_.PauseIncomingMethodCallProcessing();
return;
@@ -361,12 +366,16 @@ void ThrottlingURLLoader::OnReceiveRedirect(
if (deferred) {
deferred_stage_ = DEFERRED_REDIRECT;
redirect_info_ =
- base::MakeUnique<RedirectInfo>(redirect_info, response_head);
+ std::make_unique<RedirectInfo>(redirect_info, response_head);
client_binding_.PauseIncomingMethodCallProcessing();
return;
}
}
+ // TODO(dhausknecht) at this point we do not actually know if we commit to the
+ // 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;
forwarding_client_->OnReceiveRedirect(redirect_info, response_head);
}
@@ -413,7 +422,7 @@ void ThrottlingURLLoader::OnStartLoadingResponseBody(
}
void ThrottlingURLLoader::OnComplete(
- const ResourceRequestCompletionStatus& status) {
+ const network::URLLoaderCompletionStatus& status) {
DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
DCHECK(!loader_cancelled_);
@@ -436,13 +445,13 @@ void ThrottlingURLLoader::CancelWithError(int error_code) {
if (loader_cancelled_)
return;
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = error_code;
- request_complete_data.completion_time = base::TimeTicks::Now();
+ network::URLLoaderCompletionStatus status;
+ status.error_code = error_code;
+ status.completion_time = base::TimeTicks::Now();
deferred_stage_ = DEFERRED_NONE;
DisconnectClient();
- forwarding_client_->OnComplete(request_complete_data);
+ forwarding_client_->OnComplete(status);
}
void ThrottlingURLLoader::Resume() {
@@ -463,6 +472,10 @@ void ThrottlingURLLoader::Resume() {
client_binding_.ResumeIncomingMethodCallProcessing();
forwarding_client_->OnReceiveRedirect(redirect_info_->redirect_info,
redirect_info_->response_head);
+ // TODO(dhausknecht) at this point we do not actually know if we commit to
+ // the 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_->redirect_info.new_url;
break;
}
case DEFERRED_RESPONSE: {
@@ -500,7 +513,7 @@ ThrottlingURLLoader::ThrottleEntry::ThrottleEntry(
ThrottlingURLLoader* loader,
std::unique_ptr<URLLoaderThrottle> the_throttle)
: delegate(
- base::MakeUnique<ForwardingThrottleDelegate>(loader,
+ std::make_unique<ForwardingThrottleDelegate>(loader,
the_throttle.get())),
throttle(std::move(the_throttle)) {
throttle->set_delegate(delegate.get());
diff --git a/chromium/content/common/throttling_url_loader.h b/chromium/content/common/throttling_url_loader.h
index 4ab2e389b45..dd1138f7e48 100644
--- a/chromium/content/common/throttling_url_loader.h
+++ b/chromium/content/common/throttling_url_loader.h
@@ -45,8 +45,7 @@ class CONTENT_EXPORT ThrottlingURLLoader : public mojom::URLLoaderClient {
const ResourceRequest& url_request,
mojom::URLLoaderClient* client,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- base::ThreadTaskRunnerHandle::Get());
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
using StartLoaderCallback =
base::OnceCallback<void(mojom::URLLoaderRequest request,
@@ -58,11 +57,11 @@ class CONTENT_EXPORT ThrottlingURLLoader : public mojom::URLLoaderClient {
static std::unique_ptr<ThrottlingURLLoader> CreateLoaderAndStart(
StartLoaderCallback start_loader_callback,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
+ int32_t routing_id,
const ResourceRequest& url_request,
mojom::URLLoaderClient* client,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- base::ThreadTaskRunnerHandle::Get());
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
~ThrottlingURLLoader() override;
@@ -131,7 +130,7 @@ class CONTENT_EXPORT ThrottlingURLLoader : public mojom::URLLoaderClient {
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- void OnComplete(const ResourceRequestCompletionStatus& status) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
void OnClientConnectionError();
@@ -241,6 +240,9 @@ class CONTENT_EXPORT ThrottlingURLLoader : public mojom::URLLoaderClient {
uint32_t inside_delegate_calls_ = 0;
+ // The latest request URL from where we expect a response
+ GURL response_url_;
+
DISALLOW_COPY_AND_ASSIGN(ThrottlingURLLoader);
};
diff --git a/chromium/content/common/throttling_url_loader_unittest.cc b/chromium/content/common/throttling_url_loader_unittest.cc
index 33f3cbd395e..1aea4949c4a 100644
--- a/chromium/content/common/throttling_url_loader_unittest.cc
+++ b/chromium/content/common/throttling_url_loader_unittest.cc
@@ -17,6 +17,9 @@
namespace content {
namespace {
+GURL request_url = GURL("http://example.org");
+GURL redirect_url = GURL("http://example.com");
+
class TestURLLoaderFactory : public mojom::URLLoaderFactory,
public mojom::URLLoader {
public:
@@ -48,11 +51,13 @@ class TestURLLoaderFactory : public mojom::URLLoaderFactory,
}
void NotifyClientOnReceiveRedirect() {
- client_ptr_->OnReceiveRedirect(net::RedirectInfo(), ResourceResponseHead());
+ net::RedirectInfo info;
+ info.new_url = redirect_url;
+ client_ptr_->OnReceiveRedirect(info, ResourceResponseHead());
}
void NotifyClientOnComplete(int error_code) {
- ResourceRequestCompletionStatus data;
+ network::URLLoaderCompletionStatus data;
data.error_code = error_code;
client_ptr_->OnComplete(data);
}
@@ -149,7 +154,7 @@ class TestURLLoaderClient : public mojom::URLLoaderClient {
void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override {}
- void OnComplete(const ResourceRequestCompletionStatus& status) override {
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override {
on_complete_called_++;
if (on_complete_callback_)
on_complete_callback_.Run(status.error_code);
@@ -189,6 +194,8 @@ class TestURLLoaderThrottle : public URLLoaderThrottle {
return will_process_response_called_;
}
+ GURL observed_response_url() const { return response_url_; }
+
void set_will_start_request_callback(const ThrottleCallback& callback) {
will_start_request_callback_ = callback;
}
@@ -218,16 +225,21 @@ class TestURLLoaderThrottle : public URLLoaderThrottle {
will_redirect_request_callback_.Run(delegate_, defer);
}
- void WillProcessResponse(bool* defer) override {
+ void WillProcessResponse(const GURL& response_url,
+ const ResourceResponseHead& response_head,
+ bool* defer) override {
will_process_response_called_++;
if (will_process_response_callback_)
will_process_response_callback_.Run(delegate_, defer);
+ response_url_ = response_url;
}
size_t will_start_request_called_ = 0;
size_t will_redirect_request_called_ = 0;
size_t will_process_response_called_ = 0;
+ GURL response_url_;
+
ThrottleCallback will_start_request_callback_;
ThrottleCallback will_redirect_request_callback_;
ThrottleCallback will_process_response_callback_;
@@ -247,7 +259,7 @@ class ThrottlingURLLoaderTest : public testing::Test {
protected:
// testing::Test implementation.
void SetUp() override {
- auto throttle = base::MakeUnique<TestURLLoaderThrottle>(
+ auto throttle = std::make_unique<TestURLLoaderThrottle>(
base::Bind(&ThrottlingURLLoaderTest::ResetThrottleRawPointer,
weak_factory_.GetWeakPtr()));
@@ -261,10 +273,11 @@ class ThrottlingURLLoaderTest : public testing::Test {
if (sync)
options |= mojom::kURLLoadOptionSynchronous;
ResourceRequest request;
- request.url = GURL("http://example.org");
+ request.url = request_url;
loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
factory_.factory_ptr().get(), std::move(throttles_), 0, 0, options,
- request, &client_, TRAFFIC_ANNOTATION_FOR_TESTS);
+ request, &client_, TRAFFIC_ANNOTATION_FOR_TESTS,
+ base::ThreadTaskRunnerHandle::Get());
factory_.factory_ptr().FlushForTesting();
}
@@ -355,6 +368,9 @@ TEST_F(ThrottlingURLLoaderTest, DeferBeforeStart) {
EXPECT_EQ(0u, throttle_->will_redirect_request_called());
EXPECT_EQ(1u, throttle_->will_process_response_called());
+ EXPECT_TRUE(
+ throttle_->observed_response_url().EqualsIgnoringRef(request_url));
+
EXPECT_EQ(1u, client_.on_received_response_called());
EXPECT_EQ(0u, client_.on_received_redirect_called());
EXPECT_EQ(1u, client_.on_complete_called());
@@ -462,6 +478,9 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeResponse) {
EXPECT_EQ(0u, throttle_->will_redirect_request_called());
EXPECT_EQ(1u, throttle_->will_process_response_called());
+ EXPECT_TRUE(
+ throttle_->observed_response_url().EqualsIgnoringRef(request_url));
+
EXPECT_EQ(0u, client_.on_received_response_called());
EXPECT_EQ(0u, client_.on_received_redirect_called());
EXPECT_EQ(1u, client_.on_complete_called());
@@ -495,6 +514,9 @@ TEST_F(ThrottlingURLLoaderTest, DeferBeforeResponse) {
EXPECT_EQ(0u, throttle_->will_redirect_request_called());
EXPECT_EQ(1u, throttle_->will_process_response_called());
+ EXPECT_TRUE(
+ throttle_->observed_response_url().EqualsIgnoringRef(request_url));
+
factory_.NotifyClientOnComplete(net::ERR_UNEXPECTED);
base::RunLoop run_loop3;
@@ -511,6 +533,9 @@ TEST_F(ThrottlingURLLoaderTest, DeferBeforeResponse) {
EXPECT_EQ(0u, throttle_->will_redirect_request_called());
EXPECT_EQ(1u, throttle_->will_process_response_called());
+ EXPECT_TRUE(
+ throttle_->observed_response_url().EqualsIgnoringRef(request_url));
+
EXPECT_EQ(1u, client_.on_received_response_called());
EXPECT_EQ(0u, client_.on_received_redirect_called());
EXPECT_EQ(1u, client_.on_complete_called());
@@ -600,6 +625,9 @@ TEST_F(ThrottlingURLLoaderTest, ResumeNoOpIfNotDeferred) {
EXPECT_EQ(1u, throttle_->will_redirect_request_called());
EXPECT_EQ(1u, throttle_->will_process_response_called());
+ EXPECT_TRUE(
+ throttle_->observed_response_url().EqualsIgnoringRef(redirect_url));
+
EXPECT_EQ(1u, client_.on_received_response_called());
EXPECT_EQ(1u, client_.on_received_redirect_called());
EXPECT_EQ(1u, client_.on_complete_called());
@@ -665,13 +693,16 @@ TEST_F(ThrottlingURLLoaderTest, ResumeNoOpIfAlreadyCanceled) {
EXPECT_EQ(0u, throttle_->will_redirect_request_called());
EXPECT_EQ(1u, throttle_->will_process_response_called());
+ EXPECT_TRUE(
+ throttle_->observed_response_url().EqualsIgnoringRef(request_url));
+
EXPECT_EQ(0u, client_.on_received_response_called());
EXPECT_EQ(0u, client_.on_received_redirect_called());
EXPECT_EQ(1u, client_.on_complete_called());
}
TEST_F(ThrottlingURLLoaderTest, MultipleThrottlesBasicSupport) {
- throttles_.emplace_back(base::MakeUnique<TestURLLoaderThrottle>());
+ throttles_.emplace_back(std::make_unique<TestURLLoaderThrottle>());
auto* throttle2 =
static_cast<TestURLLoaderThrottle*>(throttles_.back().get());
CreateLoaderAndStart();
@@ -682,7 +713,7 @@ TEST_F(ThrottlingURLLoaderTest, MultipleThrottlesBasicSupport) {
}
TEST_F(ThrottlingURLLoaderTest, BlockWithOneOfMultipleThrottles) {
- throttles_.emplace_back(base::MakeUnique<TestURLLoaderThrottle>());
+ throttles_.emplace_back(std::make_unique<TestURLLoaderThrottle>());
auto* throttle2 =
static_cast<TestURLLoaderThrottle*>(throttles_.back().get());
throttle2->set_will_start_request_callback(
@@ -730,13 +761,18 @@ TEST_F(ThrottlingURLLoaderTest, BlockWithOneOfMultipleThrottles) {
EXPECT_EQ(1u, throttle_->will_process_response_called());
EXPECT_EQ(1u, throttle2->will_process_response_called());
+ EXPECT_TRUE(
+ throttle_->observed_response_url().EqualsIgnoringRef(request_url));
+ EXPECT_TRUE(
+ throttle2->observed_response_url().EqualsIgnoringRef(request_url));
+
EXPECT_EQ(1u, client_.on_received_response_called());
EXPECT_EQ(0u, client_.on_received_redirect_called());
EXPECT_EQ(1u, client_.on_complete_called());
}
TEST_F(ThrottlingURLLoaderTest, BlockWithMultipleThrottles) {
- throttles_.emplace_back(base::MakeUnique<TestURLLoaderThrottle>());
+ throttles_.emplace_back(std::make_unique<TestURLLoaderThrottle>());
auto* throttle2 =
static_cast<TestURLLoaderThrottle*>(throttles_.back().get());
@@ -798,13 +834,18 @@ TEST_F(ThrottlingURLLoaderTest, BlockWithMultipleThrottles) {
EXPECT_EQ(1u, throttle_->will_process_response_called());
EXPECT_EQ(1u, throttle2->will_process_response_called());
+ EXPECT_TRUE(
+ throttle_->observed_response_url().EqualsIgnoringRef(request_url));
+ EXPECT_TRUE(
+ throttle2->observed_response_url().EqualsIgnoringRef(request_url));
+
EXPECT_EQ(1u, client_.on_received_response_called());
EXPECT_EQ(0u, client_.on_received_redirect_called());
EXPECT_EQ(1u, client_.on_complete_called());
}
TEST_F(ThrottlingURLLoaderTest, PauseResumeReadingBodyFromNet) {
- throttles_.emplace_back(base::MakeUnique<TestURLLoaderThrottle>());
+ throttles_.emplace_back(std::make_unique<TestURLLoaderThrottle>());
auto* throttle2 =
static_cast<TestURLLoaderThrottle*>(throttles_.back().get());
@@ -889,6 +930,9 @@ TEST_F(ThrottlingURLLoaderTest, DestroyingThrottlingURLLoaderInDelegateCall) {
EXPECT_EQ(0u, throttle_->will_redirect_request_called());
EXPECT_EQ(1u, throttle_->will_process_response_called());
+ EXPECT_TRUE(
+ throttle_->observed_response_url().EqualsIgnoringRef(request_url));
+
throttle_->delegate()->Resume();
run_loop2.Run();
diff --git a/chromium/content/common/typemaps.gni b/chromium/content/common/typemaps.gni
index 8ac58a5c262..2ff5ab98ddb 100644
--- a/chromium/content/common/typemaps.gni
+++ b/chromium/content/common/typemaps.gni
@@ -4,8 +4,11 @@
typemaps = [
"//content/common/background_fetch/background_fetch_types.typemap",
+ "//content/common/clipboard.typemap",
"//content/common/frame_messages.typemap",
"//content/common/native_types.typemap",
+ "//content/common/native_types_mac.typemap",
+ "//content/common/navigation_params.typemap",
"//content/common/media/media_devices.typemap",
"//content/common/media/media_stream.typemap",
"//content/common/push_messaging.typemap",
@@ -13,7 +16,7 @@ typemaps = [
"//content/common/service_worker/service_worker_event_dispatcher.typemap",
"//content/common/service_worker/service_worker_fetch_request.typemap",
"//content/common/service_worker/service_worker_provider.typemap",
- "//content/common/service_worker/service_worker_types.typemap",
+ "//content/common/url_loader_factory_bundle.typemap",
"//content/common/web_preferences.typemap",
"//content/common/media/media_session.typemap",
]
diff --git a/chromium/content/common/typemaps_mac.gni b/chromium/content/common/typemaps_mac.gni
deleted file mode 100644
index a45d2402aec..00000000000
--- a/chromium/content/common/typemaps_mac.gni
+++ /dev/null
@@ -1,5 +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.
-
-typemaps = [ "//content/common/native_types_mac.typemap" ]
diff --git a/chromium/content/common/unique_name_helper.cc b/chromium/content/common/unique_name_helper.cc
index 20992fc0caf..8aed7052e21 100644
--- a/chromium/content/common/unique_name_helper.cc
+++ b/chromium/content/common/unique_name_helper.cc
@@ -11,12 +11,15 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
+#include "base/unguessable_token.h"
#include "crypto/sha2.h"
namespace content {
namespace {
+bool g_preserve_stable_unique_name_for_testing = false;
+
using FrameAdapter = UniqueNameHelper::FrameAdapter;
class PendingChildFrameAdapter : public UniqueNameHelper::FrameAdapter {
@@ -56,6 +59,7 @@ class PendingChildFrameAdapter : public UniqueNameHelper::FrameAdapter {
constexpr char kFramePathPrefix[] = "<!--framePath /";
constexpr int kFramePathPrefixLength = 15;
constexpr int kFramePathSuffixLength = 3;
+constexpr char kDynamicFrameMarker[] = "<!--dynamicFrame";
// 80% of unique names are shorter than this, and it also guarantees that this
// won't ever increase the length of a unique name, as a hashed unique name is
@@ -189,15 +193,40 @@ UniqueNameHelper::UniqueNameHelper(FrameAdapter* frame) : frame_(frame) {}
UniqueNameHelper::~UniqueNameHelper() {}
std::string UniqueNameHelper::GenerateNameForNewChildFrame(
- const std::string& name) const {
- PendingChildFrameAdapter adapter(frame_);
- return CalculateNewName(&adapter, name);
+ const std::string& name,
+ bool is_created_by_script) const {
+ std::string unique_name_of_new_child;
+
+ // The deterministic part of unique name should be included if
+ // 1. The new subframe is not created by script or
+ // 2. The new subframe is created by script, but we are still asked for the
+ // old, stable part for layout tests (via
+ // |g_preserve_stable_unique_name_for_testing|).
+ if (!is_created_by_script || g_preserve_stable_unique_name_for_testing) {
+ PendingChildFrameAdapter adapter(frame_);
+ unique_name_of_new_child = CalculateNewName(&adapter, name);
+ }
+
+ // The random part of unique name is only included for subframes created from
+ // scripts.
+ if (is_created_by_script) {
+ unique_name_of_new_child += kDynamicFrameMarker;
+ unique_name_of_new_child += base::UnguessableToken::Create().ToString();
+ unique_name_of_new_child += "-->";
+ }
+
+ return unique_name_of_new_child;
}
void UniqueNameHelper::UpdateName(const std::string& name) {
+ // Don't update the unique name if it should remain frozen.
+ if (frozen_)
+ return;
+
// The unique name of the main frame is always the empty string.
if (frame_->IsMainFrame())
return;
+
// It's important to clear this before calculating a new name, as the
// calculation checks for collisions with existing unique names.
unique_name_.clear();
@@ -274,4 +303,17 @@ std::string UniqueNameHelper::CalculateLegacyNameForTesting(
return CalculateNameInternal(frame, name);
}
+// static
+void UniqueNameHelper::PreserveStableUniqueNameForTesting() {
+ g_preserve_stable_unique_name_for_testing = true;
+}
+
+std::string UniqueNameHelper::ExtractStableNameForTesting(
+ const std::string& unique_name) {
+ size_t i = unique_name.rfind(kDynamicFrameMarker);
+ if (i == std::string::npos)
+ return unique_name;
+ return unique_name.substr(0, i);
+}
+
} // namespace content
diff --git a/chromium/content/common/unique_name_helper.h b/chromium/content/common/unique_name_helper.h
index d816305dcbe..2f53cc96ed6 100644
--- a/chromium/content/common/unique_name_helper.h
+++ b/chromium/content/common/unique_name_helper.h
@@ -134,7 +134,15 @@ class CONTENT_EXPORT UniqueNameHelper {
// egg problem, this method is designed to be called on the *parent* frame of
// the future new child frame and return the value the new child frame should
// use.
- std::string GenerateNameForNewChildFrame(const std::string& name) const;
+ //
+ // |is_created_by_script| indicates if the new child is created via javascript
+ // (as opposed to being created from static html). In this case, the new child
+ // cannot be reliably identified in session history entries. To avoid
+ // accidentally using incorrect session history entries such a child gets a
+ // fresh, random, unique name every time it is created or recreated. See also
+ // https://crbug.com/500260.
+ std::string GenerateNameForNewChildFrame(const std::string& name,
+ bool is_created_by_script) const;
// Called after a browsing context name change to generate a new name. Note
// that this should not be called if the frame is no longer displaying the
@@ -142,6 +150,22 @@ class CONTENT_EXPORT UniqueNameHelper {
// history navigations. See https://crbug.com/607205.
void UpdateName(const std::string& name);
+ // Prevents future changes of the unique name. This avoids changing the
+ // unique name when the frame's assigned name changes in the future.
+ //
+ // Such freeze is desirable in case of frames created from javascript
+ // (see |is_created_by_script| parameter of GenerateNameForNewChildFrame)
+ // because their order of creation can be undeterministic and therefore
+ // their unique name should NOT be derived from their assigned name
+ // (because in case of a conflicting assigned name, their final unique
+ // names would be undetetministic potentially leading to
+ // https://crbug.com/500260).
+ //
+ // TODO(dcheng, lukasza): Consider making frame's unique name immutable (and
+ // if this is possible remove the explicit Freeze method). For more context
+ // see https://crbug.com/607205#c6.
+ void Freeze() { frozen_ = true; }
+
// Helper to update legacy names generated for PageState v24 and earlier. This
// function should be invoked starting from the root of the tree, traversing
// downwards. The exact traversal order is unimportant as long as this
@@ -155,9 +179,25 @@ class CONTENT_EXPORT UniqueNameHelper {
static std::string CalculateLegacyNameForTesting(const FrameAdapter* frame,
const std::string& name);
+ // Enters a mode causing future uses of GenerateNameForNewChildFrame to
+ // preserve the original, stable unique name, so that it can be recovered
+ // (e.g. for layout tests) by ExtractStableNameForTesting method below. This
+ // mode is not enabled by default, because it makes unique names longer, and
+ // thus negatively affects memory usage.
+ static void PreserveStableUniqueNameForTesting();
+
+ // Removes the random components of |unique_name|, so it can be used in test
+ // output that needs to be stable across test runs.
+ //
+ // Note: This method only works if |unique_name| was calculated after calling
+ // PreserveStableUniqueNameForTesting (see above).
+ static std::string ExtractStableNameForTesting(
+ const std::string& unique_name);
+
private:
FrameAdapter* const frame_;
std::string unique_name_;
+ bool frozen_ = false;
DISALLOW_COPY_AND_ASSIGN(UniqueNameHelper);
};
diff --git a/chromium/content/common/unique_name_helper_unittest.cc b/chromium/content/common/unique_name_helper_unittest.cc
index 12932e4c347..753a416813c 100644
--- a/chromium/content/common/unique_name_helper_unittest.cc
+++ b/chromium/content/common/unique_name_helper_unittest.cc
@@ -116,6 +116,12 @@ class TestFrameAdapter : public UniqueNameHelper::FrameAdapter {
}
}
+ void UpdateName(const std::string& new_name) {
+ unique_name_helper_.UpdateName(new_name);
+ }
+
+ void Freeze() { unique_name_helper_.Freeze(); }
+
private:
// Global toggle for the style of name to generate. Used to ensure that test
// code can consistently trigger the legacy generation path when needed.
@@ -163,7 +169,7 @@ void VerifyPageStateForTargetUpdate(const TestFrameAdapter& main_frame) {
// Version 24 is the last version with unlimited size unique names.
std::string encoded_state;
- EncodePageStateForTesting(in_state, 24, &encoded_state);
+ LegacyEncodePageStateForTesting(in_state, 24, &encoded_state);
ExplodedPageState out_state;
DecodePageState(encoded_state, &out_state);
@@ -407,5 +413,20 @@ TEST(UniqueNameHelper, GeneratedFramePathHashing) {
VerifyPageStateForTargetUpdate(main_frame);
}
+TEST(UniqueNameHelper, UpdateName) {
+ TestFrameAdapter main_frame(nullptr, -1, "my main frame");
+ EXPECT_EQ("", main_frame.GetUniqueName());
+
+ TestFrameAdapter frame_0(&main_frame, 0, "name1");
+ EXPECT_EQ("name1", frame_0.GetUniqueName());
+
+ frame_0.UpdateName("name2");
+ EXPECT_EQ("name2", frame_0.GetUniqueName());
+
+ frame_0.Freeze();
+ frame_0.UpdateName("name3");
+ EXPECT_EQ("name2", frame_0.GetUniqueName()); // No change expected.
+}
+
} // namespace
} // namespace content
diff --git a/chromium/content/common/url_loader_factory_bundle.cc b/chromium/content/common/url_loader_factory_bundle.cc
new file mode 100644
index 00000000000..a0128c843eb
--- /dev/null
+++ b/chromium/content/common/url_loader_factory_bundle.cc
@@ -0,0 +1,94 @@
+// Copyright 2017 The Chromium Authors. 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/url_loader_factory_bundle.h"
+
+#include <map>
+#include <string>
+
+#include "base/macros.h"
+#include "content/public/common/url_loader_factory.mojom.h"
+#include "url/gurl.h"
+
+class GURL;
+
+namespace content {
+
+URLLoaderFactoryBundleInfo::URLLoaderFactoryBundleInfo(
+ URLLoaderFactoryBundleInfo&&) = default;
+
+URLLoaderFactoryBundleInfo::URLLoaderFactoryBundleInfo(
+ mojom::URLLoaderFactoryPtrInfo default_factory_info,
+ std::map<std::string, mojom::URLLoaderFactoryPtrInfo> factories_info)
+ : default_factory_info(std::move(default_factory_info)),
+ factories_info(std::move(factories_info)) {}
+
+URLLoaderFactoryBundleInfo::~URLLoaderFactoryBundleInfo() = default;
+
+URLLoaderFactoryBundle::URLLoaderFactoryBundle() = default;
+
+URLLoaderFactoryBundle::URLLoaderFactoryBundle(URLLoaderFactoryBundle&&) =
+ default;
+
+URLLoaderFactoryBundle::URLLoaderFactoryBundle(
+ URLLoaderFactoryBundleInfo 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));
+}
+
+URLLoaderFactoryBundle::~URLLoaderFactoryBundle() = default;
+
+URLLoaderFactoryBundle& URLLoaderFactoryBundle::operator=(
+ URLLoaderFactoryBundle&&) = default;
+
+void URLLoaderFactoryBundle::SetDefaultFactory(
+ mojom::URLLoaderFactoryPtr factory) {
+ default_factory_ = std::move(factory);
+}
+
+void URLLoaderFactoryBundle::RegisterFactory(
+ const base::StringPiece& scheme,
+ mojom::URLLoaderFactoryPtr factory) {
+ DCHECK(factory.is_bound());
+ auto result = factories_.emplace(std::string(scheme), std::move(factory));
+ DCHECK(result.second);
+}
+
+mojom::URLLoaderFactory* URLLoaderFactoryBundle::GetFactoryForRequest(
+ const GURL& url) {
+ auto it = factories_.find(url.scheme());
+ if (it == factories_.end()) {
+ DCHECK(default_factory_.is_bound());
+ return default_factory_.get();
+ }
+ return it->second.get();
+}
+
+URLLoaderFactoryBundleInfo URLLoaderFactoryBundle::PassInfo() {
+ std::map<std::string, mojom::URLLoaderFactoryPtrInfo> factories_info;
+ for (auto& factory : factories_)
+ factories_info.emplace(factory.first, factory.second.PassInterface());
+ DCHECK(default_factory_.is_bound());
+ return URLLoaderFactoryBundleInfo(default_factory_.PassInterface(),
+ std::move(factories_info));
+}
+
+URLLoaderFactoryBundle URLLoaderFactoryBundle::Clone() {
+ DCHECK(default_factory_.is_bound());
+ mojom::URLLoaderFactoryPtr cloned_default_factory;
+ default_factory_->Clone(mojo::MakeRequest(&cloned_default_factory));
+
+ URLLoaderFactoryBundle new_bundle;
+ new_bundle.SetDefaultFactory(std::move(cloned_default_factory));
+ for (auto& factory : factories_) {
+ mojom::URLLoaderFactoryPtr cloned_factory;
+ factory.second->Clone(mojo::MakeRequest(&cloned_factory));
+ new_bundle.RegisterFactory(factory.first, std::move(cloned_factory));
+ }
+
+ return new_bundle;
+}
+
+} // namespace content
diff --git a/chromium/content/common/url_loader_factory_bundle.h b/chromium/content/common/url_loader_factory_bundle.h
new file mode 100644
index 00000000000..014725479e3
--- /dev/null
+++ b/chromium/content/common/url_loader_factory_bundle.h
@@ -0,0 +1,87 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_URL_LOADER_FACTORY_BUNDLE_H_
+#define CONTENT_COMMON_URL_LOADER_FACTORY_BUNDLE_H_
+
+#include <map>
+#include <string>
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "content/public/common/url_loader_factory.mojom.h"
+
+class GURL;
+
+namespace mojo {
+template <typename, typename>
+struct StructTraits;
+}
+
+namespace content {
+
+namespace mojom {
+class URLLoaderFactoryBundleDataView;
+}
+
+// Holds the internal state of a URLLoaderFactoryBundle in a form that is safe
+// to pass across sequences.
+struct CONTENT_EXPORT URLLoaderFactoryBundleInfo {
+ URLLoaderFactoryBundleInfo(URLLoaderFactoryBundleInfo&&);
+ URLLoaderFactoryBundleInfo(
+ mojom::URLLoaderFactoryPtrInfo default_factory_info,
+ std::map<std::string, mojom::URLLoaderFactoryPtrInfo> factories_info);
+ ~URLLoaderFactoryBundleInfo();
+
+ mojom::URLLoaderFactoryPtrInfo default_factory_info;
+ std::map<std::string, mojom::URLLoaderFactoryPtrInfo> factories_info;
+};
+
+// Encapsulates a collection of URLLoaderFactoryPtrs which can be usd to acquire
+// loaders for various types of resource requests.
+class CONTENT_EXPORT URLLoaderFactoryBundle {
+ public:
+ URLLoaderFactoryBundle();
+ URLLoaderFactoryBundle(URLLoaderFactoryBundle&&);
+ explicit URLLoaderFactoryBundle(URLLoaderFactoryBundleInfo info);
+ ~URLLoaderFactoryBundle();
+
+ URLLoaderFactoryBundle& operator=(URLLoaderFactoryBundle&&);
+
+ // Sets the default factory to use when no registered factories match a given
+ // |url|.
+ void SetDefaultFactory(mojom::URLLoaderFactoryPtr factory);
+
+ // Registers a new factory to handle requests matching scheme |scheme|.
+ void RegisterFactory(const base::StringPiece& scheme,
+ 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.
+ mojom::URLLoaderFactory* GetFactoryForRequest(const GURL& url);
+
+ // Passes out a structure which captures the internal state of this bundle in
+ // a form that is safe to pass across sequences. Effectively resets |this|
+ // to have no registered factories.
+ URLLoaderFactoryBundleInfo PassInfo();
+
+ // Creates a clone of this bundle which can be passed to and owned by another
+ // consumer. The clone operates identically to but independent from the
+ // original (this) bundle.
+ URLLoaderFactoryBundle Clone();
+
+ private:
+ friend struct mojo::StructTraits<mojom::URLLoaderFactoryBundleDataView,
+ URLLoaderFactoryBundle>;
+
+ mojom::URLLoaderFactoryPtr default_factory_;
+ std::map<std::string, mojom::URLLoaderFactoryPtr> factories_;
+
+ DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryBundle);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_URL_LOADER_FACTORY_BUNDLE_H_
diff --git a/chromium/content/common/url_loader_factory_bundle.mojom b/chromium/content/common/url_loader_factory_bundle.mojom
new file mode 100644
index 00000000000..1f0f9e2b439
--- /dev/null
+++ b/chromium/content/common/url_loader_factory_bundle.mojom
@@ -0,0 +1,16 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+import "content/public/common/url_loader_factory.mojom";
+
+// Serializes a collection of URLLoaderFactory interfaces.
+struct URLLoaderFactoryBundle {
+ // The default factory to be used when no others apply.
+ URLLoaderFactory default_factory;
+
+ // A mapping from URL scheme to factory interface.
+ map<string, URLLoaderFactory> factories;
+};
diff --git a/chromium/content/common/url_loader_factory_bundle.typemap b/chromium/content/common/url_loader_factory_bundle.typemap
new file mode 100644
index 00000000000..066c04c3ffa
--- /dev/null
+++ b/chromium/content/common/url_loader_factory_bundle.typemap
@@ -0,0 +1,13 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//content/common/url_loader_factory_bundle.mojom"
+public_headers = [ "//content/common/url_loader_factory_bundle.h" ]
+traits_headers =
+ [ "//content/common/url_loader_factory_bundle_struct_traits.h" ]
+sources = [
+ "//content/common/url_loader_factory_bundle_struct_traits.cc",
+]
+
+type_mappings = [ "content.mojom.URLLoaderFactoryBundle=content::URLLoaderFactoryBundle[move_only]" ]
diff --git a/chromium/content/common/url_loader_factory_bundle_struct_traits.cc b/chromium/content/common/url_loader_factory_bundle_struct_traits.cc
new file mode 100644
index 00000000000..917d12a59f9
--- /dev/null
+++ b/chromium/content/common/url_loader_factory_bundle_struct_traits.cc
@@ -0,0 +1,34 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/url_loader_factory_bundle_struct_traits.h"
+
+namespace mojo {
+
+using Traits = StructTraits<content::mojom::URLLoaderFactoryBundleDataView,
+ content::URLLoaderFactoryBundle>;
+
+// static
+content::mojom::URLLoaderFactoryPtr Traits::default_factory(
+ content::URLLoaderFactoryBundle& bundle) {
+ return std::move(bundle.default_factory_);
+}
+
+// static
+std::map<std::string, content::mojom::URLLoaderFactoryPtr> Traits::factories(
+ content::URLLoaderFactoryBundle& bundle) {
+ return std::move(bundle.factories_);
+}
+
+// static
+bool Traits::Read(content::mojom::URLLoaderFactoryBundleDataView data,
+ content::URLLoaderFactoryBundle* out_bundle) {
+ out_bundle->SetDefaultFactory(
+ data.TakeDefaultFactory<content::mojom::URLLoaderFactoryPtr>());
+ if (!data.ReadFactories(&out_bundle->factories_))
+ return false;
+ return true;
+}
+
+} // namespace mojo
diff --git a/chromium/content/common/url_loader_factory_bundle_struct_traits.h b/chromium/content/common/url_loader_factory_bundle_struct_traits.h
new file mode 100644
index 00000000000..f2630495fef
--- /dev/null
+++ b/chromium/content/common/url_loader_factory_bundle_struct_traits.h
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_URL_LOADER_FACTORY_BUNDLE_STRUCT_TRAITS_H_
+#define CONTENT_COMMON_URL_LOADER_FACTORY_BUNDLE_STRUCT_TRAITS_H_
+
+#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"
+
+namespace mojo {
+
+template <>
+struct StructTraits<content::mojom::URLLoaderFactoryBundleDataView,
+ content::URLLoaderFactoryBundle> {
+ static content::mojom::URLLoaderFactoryPtr default_factory(
+ content::URLLoaderFactoryBundle& bundle);
+
+ static std::map<std::string, content::mojom::URLLoaderFactoryPtr> factories(
+ content::URLLoaderFactoryBundle& bundle);
+
+ static bool Read(content::mojom::URLLoaderFactoryBundleDataView data,
+ content::URLLoaderFactoryBundle* out_bundle);
+};
+
+} // namespace mojo
+
+#endif // CONTENT_COMMON_URL_LOADER_FACTORY_BUNDLE_STRUCT_TRAITS_H_
diff --git a/chromium/content/common/view_messages.h b/chromium/content/common/view_messages.h
index 9184f48fde2..0cc0041c948 100644
--- a/chromium/content/common/view_messages.h
+++ b/chromium/content/common/view_messages.h
@@ -36,7 +36,6 @@
#include "content/public/common/page_zoom.h"
#include "content/public/common/referrer.h"
#include "content/public/common/renderer_preferences.h"
-#include "content/public/common/screen_info.h"
#include "content/public/common/three_d_api_types.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message_macros.h"
@@ -93,7 +92,7 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::WebTextDirection,
blink::WebTextDirection::kWebTextDirectionLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebDisplayMode,
blink::WebDisplayMode::kWebDisplayModeLast)
-IPC_ENUM_TRAITS(content::MenuItem::Type)
+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,
@@ -160,24 +159,12 @@ IPC_STRUCT_TRAITS_BEGIN(blink::WebDeviceEmulationParams)
IPC_STRUCT_TRAITS_MEMBER(screen_orientation_type)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(content::ScreenInfo)
- IPC_STRUCT_TRAITS_MEMBER(device_scale_factor)
- IPC_STRUCT_TRAITS_MEMBER(color_space)
- IPC_STRUCT_TRAITS_MEMBER(icc_profile)
- IPC_STRUCT_TRAITS_MEMBER(depth)
- IPC_STRUCT_TRAITS_MEMBER(depth_per_component)
- IPC_STRUCT_TRAITS_MEMBER(is_monochrome)
- IPC_STRUCT_TRAITS_MEMBER(rect)
- IPC_STRUCT_TRAITS_MEMBER(available_rect)
- IPC_STRUCT_TRAITS_MEMBER(orientation_type)
- IPC_STRUCT_TRAITS_MEMBER(orientation_angle)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_TRAITS_BEGIN(content::ResizeParams)
IPC_STRUCT_TRAITS_MEMBER(screen_info)
IPC_STRUCT_TRAITS_MEMBER(new_size)
IPC_STRUCT_TRAITS_MEMBER(physical_backing_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)
@@ -226,6 +213,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::RendererPreferences)
IPC_STRUCT_TRAITS_MEMBER(use_custom_colors)
IPC_STRUCT_TRAITS_MEMBER(enable_referrers)
IPC_STRUCT_TRAITS_MEMBER(enable_do_not_track)
+ IPC_STRUCT_TRAITS_MEMBER(enable_encrypted_media)
IPC_STRUCT_TRAITS_MEMBER(webrtc_ip_handling_policy)
IPC_STRUCT_TRAITS_MEMBER(webrtc_udp_min_port)
IPC_STRUCT_TRAITS_MEMBER(webrtc_udp_max_port)
@@ -356,8 +344,11 @@ IPC_MESSAGE_ROUTED1(ViewMsg_Resize, content::ResizeParams /* params */)
// Tells the widget to use the provided viz::LocalSurfaceId to submit
// CompositorFrames for autosize.
-IPC_MESSAGE_ROUTED2(ViewMsg_SetLocalSurfaceIdForAutoResize,
+IPC_MESSAGE_ROUTED5(ViewMsg_SetLocalSurfaceIdForAutoResize,
uint64_t /* sequence_number */,
+ gfx::Size /* min_size */,
+ gfx::Size /* max_size */,
+ content::ScreenInfo /* screen_info */,
viz::LocalSurfaceId /* local_surface_id */)
// Enables device emulation. See WebDeviceEmulationParams for description.
@@ -568,6 +559,11 @@ IPC_MESSAGE_ROUTED1(ViewMsg_SetViewportIntersection,
// Sets the inert bit on an out-of-process iframe.
IPC_MESSAGE_ROUTED1(ViewMsg_SetIsInert, bool /* inert */)
+// 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.
@@ -771,22 +767,6 @@ IPC_MESSAGE_ROUTED3(ViewHostMsg_ShowDisambiguationPopup,
IPC_MESSAGE_ROUTED1(ViewHostMsg_FocusedNodeTouched,
bool /* editable */)
-// Message sent from the renderer to the browser when an HTML form has failed
-// validation constraints.
-IPC_MESSAGE_ROUTED3(ViewHostMsg_ShowValidationMessage,
- gfx::Rect /* anchor rectangle in root view coordinate */,
- base::string16 /* validation message */,
- base::string16 /* supplemental text */)
-
-// Message sent from the renderer to the browser when a HTML form validation
-// message should be hidden from view.
-IPC_MESSAGE_ROUTED0(ViewHostMsg_HideValidationMessage)
-
-// Message sent from the renderer to the browser when the suggested co-ordinates
-// of the anchor for a HTML form validation message have changed.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_MoveValidationMessage,
- gfx::Rect /* anchor rectangle in root view coordinate */)
-
// 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)
diff --git a/chromium/content/common/web_database.mojom b/chromium/content/common/web_database.mojom
deleted file mode 100644
index 875acfbe42c..00000000000
--- a/chromium/content/common/web_database.mojom
+++ /dev/null
@@ -1,66 +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.
-
-module content.mojom;
-
-import "mojo/common/file.mojom";
-import "mojo/common/string16.mojom";
-import "url/mojo/origin.mojom";
-
-// WebDatabase messages sent from the browser to the renderer.
-interface WebDatabase {
- // Notifies the renderer process of the new database size.
- UpdateSize(url.mojom.Origin origin,
- mojo.common.mojom.String16 name,
- int64 size);
-
- // Asks the renderer process to close a database immediately.
- CloseImmediately(url.mojom.Origin origin, mojo.common.mojom.String16 name);
-};
-
-interface WebDatabaseHost {
- // Asks the browser process to open a DB file with the given name.
- [Sync]
- OpenFile(mojo.common.mojom.String16 vfs_file_name,
- int32 desired_flags) => (mojo.common.mojom.File? file);
-
- // Asks the browser process to delete a DB file.
- [Sync]
- DeleteFile(mojo.common.mojom.String16 vfs_file_name,
- bool sync_dir) => (int32 sqlite_error_code);
-
- // Asks the browser process to return the attributes of a DB file.
- [Sync]
- GetFileAttributes(mojo.common.mojom.String16 vfs_file_name) => (
- int32 attributes);
-
- // Asks the browser process to return the size of a DB file.
- [Sync]
- GetFileSize(mojo.common.mojom.String16 vfs_file_name) => (int64 size);
-
- // Asks the browser set the size of a DB file.
- [Sync]
- SetFileSize(mojo.common.mojom.String16 vfs_file_name,
- int64 expected_size) => (bool success);
-
- // Asks the browser process for the amount of space available to an origin.
- [Sync]
- GetSpaceAvailable(url.mojom.Origin origin) => (int64 space_available);
-
- // Notifies the browser process that a new database has been opened
- Opened(url.mojom.Origin origin, mojo.common.mojom.String16 database_name,
- mojo.common.mojom.String16 database_description, int64 estimated_size);
-
- // Notifies the browser process that a database might have been modified
- Modified(url.mojom.Origin origin, mojo.common.mojom.String16 database_name);
-
- // Notifies the browser process that a database is about to close
- Closed(url.mojom.Origin origin, mojo.common.mojom.String16 database_name);
-
- // Sent when a sqlite error indicates the database is corrupt.
- HandleSqliteError(url.mojom.Origin origin,
- mojo.common.mojom.String16 database_name,
- int32 error);
-
-};
diff --git a/chromium/content/common/web_preferences.typemap b/chromium/content/common/web_preferences.typemap
index c0c800720a6..546894e0d6b 100644
--- a/chromium/content/common/web_preferences.typemap
+++ b/chromium/content/common/web_preferences.typemap
@@ -2,7 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-mojom = "//content/common/renderer.mojom"
+mojom = "//content/common/native_types.mojom"
public_headers = [ "//content/public/common/web_preferences.h" ]
traits_headers = [ "//content/public/common/common_param_traits_macros.h" ]
-type_mappings = [ "content.mojom.WebPreferences=content::WebPreferences" ]
+type_mappings = [
+ "content.mojom.V8CacheOptions=content::V8CacheOptions",
+ "content.mojom.WebPreferences=content::WebPreferences",
+]
diff --git a/chromium/content/content_resources.grd b/chromium/content/content_resources.grd
index f47ff5d4010..2c9642c82ad 100644
--- a/chromium/content/content_resources.grd
+++ b/chromium/content/content_resources.grd
@@ -42,25 +42,6 @@
<include name="IDR_SERVICE_WORKER_INTERNALS_CSS" file="browser/resources/service_worker/serviceworker_internals.css" flattenhtml="true" compress="gzip" type="BINDATA" />
<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" />
- <if expr="not is_ios">
- <include name="IDR_MOJO_ASSOCIATED_BINDINGS_JS" file="../mojo/public/js/associated_bindings.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_BINDINGS_JS" file="../mojo/public/js/bindings.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_BUFFER_JS" file="../mojo/public/js/buffer.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_CODEC_JS" file="../mojo/public/js/codec.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_CONNECTOR_JS" file="../mojo/public/js/connector.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_CONTROL_MESSAGE_HANDLER_JS" file="../mojo/public/js/lib/control_message_handler.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_CONTROL_MESSAGE_PROXY_JS" file="../mojo/public/js/lib/control_message_proxy.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_INTERFACE_CONTROL_MESSAGES_MOJOM_JS" file="${root_gen_dir}/mojo/public/interfaces/bindings/interface_control_messages.mojom.js" use_base_dir="false" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_PIPE_CONTROL_MESSAGES_MOJOM_JS" file="${root_gen_dir}/mojo/public/interfaces/bindings/pipe_control_messages.mojom.js" use_base_dir="false" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_INTERFACE_TYPES_JS" file="../mojo/public/js/interface_types.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_ROUTER_JS" file="../mojo/public/js/router.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_UNICODE_JS" file="../mojo/public/js/unicode.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_VALIDATOR_JS" file="../mojo/public/js/validator.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_INTERFACE_ENDPOINT_CLIENT_JS" file="../mojo/public/js/lib/interface_endpoint_client.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_INTERFACE_ENDPOINT_HANDLE_JS" file="../mojo/public/js/lib/interface_endpoint_handle.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_PIPE_CONTROL_MESSAGE_HANDLER_JS" file="../mojo/public/js/lib/pipe_control_message_handler.js" flattenhtml="true" type="BINDATA" />
- <include name="IDR_MOJO_PIPE_CONTROL_MESSAGE_PROXY_JS" file="../mojo/public/js/lib/pipe_control_message_proxy.js" flattenhtml="true" type="BINDATA" />
- </if>
</includes>
</release>
</grit>
diff --git a/chromium/content/gpu/BUILD.gn b/chromium/content/gpu/BUILD.gn
index a5424bb7c11..b1277cbfae2 100644
--- a/chromium/content/gpu/BUILD.gn
+++ b/chromium/content/gpu/BUILD.gn
@@ -27,6 +27,7 @@ if (is_component_build) {
} else {
link_target_type = "static_library"
}
+
target(link_target_type, "gpu_sources") {
# This is an internal content API. Code outside of the content "component"
# (like content/test and content/shell) should depend on ":gpu" above.
@@ -38,6 +39,8 @@ target(link_target_type, "gpu_sources") {
"gpu_main.cc",
"gpu_process.cc",
"gpu_process.h",
+ "gpu_sandbox_hook_linux.cc",
+ "gpu_sandbox_hook_linux.h",
"gpu_service_factory.cc",
"gpu_service_factory.h",
"in_process_gpu_thread.cc",
@@ -59,6 +62,7 @@ target(link_target_type, "gpu_sources") {
"//content/public/common:common_sources",
"//gpu:gpu",
"//gpu/ipc/common:command_buffer_traits",
+ "//gpu/ipc/common:gpu_preferences_util",
"//gpu/ipc/service",
"//ipc",
"//media/gpu",
@@ -67,15 +71,16 @@ target(link_target_type, "gpu_sources") {
# TODO(jrummell): As //media/gpu/ipc/service is a source_set in a
# component build, determine if it should not be included here.
# http://crbug.com/702833.
+ "//components/viz/service/main",
"//media/gpu/ipc/service",
"//media/mojo/clients:clients",
"//services/service_manager/public/cpp",
"//services/service_manager/public/interfaces",
"//services/shape_detection:lib",
"//services/shape_detection/public/interfaces",
- "//services/ui/gpu",
- "//services/ui/gpu/interfaces",
+ "//services/viz/privileged/interfaces",
"//skia",
+ "//third_party/angle:angle_gpu_info_util",
"//ui/gfx/ipc",
"//ui/gl",
"//ui/gl/init",
@@ -114,4 +119,9 @@ target(link_target_type, "gpu_sources") {
if (enable_vulkan) {
deps += [ "//gpu/vulkan" ]
}
+
+ # Use DRI on desktop Linux builds.
+ if (is_desktop_linux && (!is_chromecast || is_cast_desktop_build)) {
+ configs += [ "//build/config/linux/dri" ]
+ }
}
diff --git a/chromium/content/gpu/DEPS b/chromium/content/gpu/DEPS
index 11a913643f5..084a0645313 100644
--- a/chromium/content/gpu/DEPS
+++ b/chromium/content/gpu/DEPS
@@ -8,8 +8,8 @@ include_rules = [
"+services/service_manager",
"+services/shape_detection",
"+services/ui/common",
- "+services/ui/gpu",
- "+services/viz/privileged/interfaces/gl",
+ "+services/viz/privileged/interfaces",
+ "+services/viz/service",
"+sandbox",
"+skia",
]
diff --git a/chromium/content/gpu/gpu_child_thread.cc b/chromium/content/gpu/gpu_child_thread.cc
index 1048a37c9aa..6752f55e381 100644
--- a/chromium/content/gpu/gpu_child_thread.cc
+++ b/chromium/content/gpu/gpu_child_thread.cc
@@ -9,12 +9,14 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/command_line.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/thread_checker.h"
#include "build/build_config.h"
+#include "components/viz/common/switches.h"
#include "content/child/child_process.h"
#include "content/gpu/gpu_service_factory.h"
#include "content/public/common/connection_filter.h"
@@ -44,11 +46,6 @@
namespace content {
namespace {
-bool IsVizEnabled() {
- // TODO(crbug.com/770833): Look at the --enable-viz flag instead.
- return false;
-}
-
ChildThreadImpl::Options GetOptions() {
ChildThreadImpl::Options::Builder builder;
@@ -106,7 +103,7 @@ class QueueingConnectionFilter : public ConnectionFilter {
registry_->BindInterface(interface_name, std::move(*interface_pipe));
} else {
std::unique_ptr<PendingRequest> request =
- base::MakeUnique<PendingRequest>();
+ std::make_unique<PendingRequest>();
request->interface_name = interface_name;
request->interface_pipe = std::move(*interface_pipe);
pending_requests_.push_back(std::move(request));
@@ -134,23 +131,26 @@ class QueueingConnectionFilter : public ConnectionFilter {
DISALLOW_COPY_AND_ASSIGN(QueueingConnectionFilter);
};
-ui::GpuMain::ExternalDependencies CreateGpuMainDependencies() {
- ui::GpuMain::ExternalDependencies deps;
- deps.create_display_compositor = IsVizEnabled();
+viz::VizMainImpl::ExternalDependencies CreateVizMainDependencies(
+ service_manager::Connector* connector) {
+ viz::VizMainImpl::ExternalDependencies deps;
+ deps.create_display_compositor =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableViz);
if (GetContentClient()->gpu())
deps.sync_point_manager = GetContentClient()->gpu()->GetSyncPointManager();
auto* process = ChildProcess::current();
deps.shutdown_event = process->GetShutDownEvent();
deps.io_thread_task_runner = process->io_task_runner();
+ deps.connector = connector;
return deps;
}
} // namespace
GpuChildThread::GpuChildThread(std::unique_ptr<gpu::GpuInit> gpu_init,
- ui::GpuMain::LogMessages log_messages)
+ viz::VizMainImpl::LogMessages log_messages)
: GpuChildThread(GetOptions(), std::move(gpu_init)) {
- gpu_main_.SetLogMessagesForHost(std::move(log_messages));
+ viz_main_.SetLogMessagesForHost(std::move(log_messages));
}
GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params,
@@ -165,7 +165,9 @@ GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params,
GpuChildThread::GpuChildThread(const ChildThreadImpl::Options& options,
std::unique_ptr<gpu::GpuInit> gpu_init)
: ChildThreadImpl(options),
- gpu_main_(this, CreateGpuMainDependencies(), std::move(gpu_init)),
+ viz_main_(this,
+ CreateVizMainDependencies(GetConnector()),
+ std::move(gpu_init)),
weak_factory_(this) {
if (in_process_gpu()) {
DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -178,7 +180,7 @@ GpuChildThread::GpuChildThread(const ChildThreadImpl::Options& options,
GpuChildThread::~GpuChildThread() {}
void GpuChildThread::Init(const base::Time& process_start_time) {
- gpu_main_.gpu_service()->set_start_time(process_start_time);
+ viz_main_.gpu_service()->set_start_time(process_start_time);
// When running in in-process mode, this has been set in the browser at
// ChromeBrowserMainPartsAndroid::PreMainMessageLoopRun().
@@ -189,11 +191,12 @@ void GpuChildThread::Init(const base::Time& process_start_time) {
}
#endif
- AssociatedInterfaceRegistry* associated_registry = &associated_interfaces_;
+ blink::AssociatedInterfaceRegistry* associated_registry =
+ &associated_interfaces_;
associated_registry->AddInterface(base::Bind(
- &GpuChildThread::CreateGpuMainService, base::Unretained(this)));
+ &GpuChildThread::CreateVizMainService, base::Unretained(this)));
- auto registry = base::MakeUnique<service_manager::BinderRegistry>();
+ auto registry = std::make_unique<service_manager::BinderRegistry>();
registry->AddInterface(base::Bind(&GpuChildThread::BindServiceFactoryRequest,
weak_factory_.GetWeakPtr()),
base::ThreadTaskRunnerHandle::Get());
@@ -201,7 +204,7 @@ void GpuChildThread::Init(const base::Time& process_start_time) {
GetContentClient()->gpu()->InitializeRegistry(registry.get());
std::unique_ptr<QueueingConnectionFilter> filter =
- base::MakeUnique<QueueingConnectionFilter>(GetIOTaskRunner(),
+ std::make_unique<QueueingConnectionFilter>(GetIOTaskRunner(),
std::move(registry));
release_pending_requests_closure_ = filter->GetReleaseCallback();
GetServiceManagerConnection()->AddConnectionFilter(std::move(filter));
@@ -209,13 +212,13 @@ void GpuChildThread::Init(const base::Time& process_start_time) {
StartServiceManagerConnection();
}
-void GpuChildThread::CreateGpuMainService(
- ui::mojom::GpuMainAssociatedRequest request) {
- gpu_main_.BindAssociated(std::move(request));
+void GpuChildThread::CreateVizMainService(
+ viz::mojom::VizMainAssociatedRequest request) {
+ viz_main_.BindAssociated(std::move(request));
}
bool GpuChildThread::in_process_gpu() const {
- return gpu_main_.gpu_service()->gpu_info().in_process_gpu;
+ return viz_main_.gpu_service()->gpu_info().in_process_gpu;
}
bool GpuChildThread::Send(IPC::Message* msg) {
@@ -296,7 +299,7 @@ std::unique_ptr<media::AndroidOverlay> GpuChildThread::CreateAndroidOverlay(
FROM_HERE, base::BindOnce(bind_connector_request, std::move(request)));
}
- return base::MakeUnique<media::MojoAndroidOverlay>(
+ return std::make_unique<media::MojoAndroidOverlay>(
std::move(overlay_provider), std::move(config), routing_token,
std::move(context_ref));
}
diff --git a/chromium/content/gpu/gpu_child_thread.h b/chromium/content/gpu/gpu_child_thread.h
index a1990df78a5..6bb47df8146 100644
--- a/chromium/content/gpu/gpu_child_thread.h
+++ b/chromium/content/gpu/gpu_child_thread.h
@@ -19,6 +19,7 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/viz/service/gl/gpu_service_impl.h"
+#include "components/viz/service/main/viz_main_impl.h"
#include "content/child/child_thread_impl.h"
#include "content/common/associated_interface_registry_impl.h"
#include "gpu/command_buffer/service/gpu_preferences.h"
@@ -34,8 +35,7 @@
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/cpp/service_context_ref.h"
#include "services/service_manager/public/interfaces/service_factory.mojom.h"
-#include "services/ui/gpu/gpu_main.h"
-#include "services/ui/gpu/interfaces/gpu_main.mojom.h"
+#include "services/viz/privileged/interfaces/viz_main.mojom.h"
#include "ui/gfx/native_widget_types.h"
namespace content {
@@ -45,10 +45,11 @@ class GpuServiceFactory;
// these per process. It does process initialization and shutdown. It forwards
// IPC messages to gpu::GpuChannelManager, which is responsible for issuing
// rendering commands to the GPU.
-class GpuChildThread : public ChildThreadImpl, public ui::GpuMain::Delegate {
+class GpuChildThread : public ChildThreadImpl,
+ public viz::VizMainImpl::Delegate {
public:
GpuChildThread(std::unique_ptr<gpu::GpuInit> gpu_init,
- ui::GpuMain::LogMessages deferred_messages);
+ viz::VizMainImpl::LogMessages deferred_messages);
GpuChildThread(const InProcessChildThreadParams& params,
std::unique_ptr<gpu::GpuInit> gpu_init);
@@ -61,7 +62,7 @@ class GpuChildThread : public ChildThreadImpl, public ui::GpuMain::Delegate {
GpuChildThread(const ChildThreadImpl::Options& options,
std::unique_ptr<gpu::GpuInit> gpu_init);
- void CreateGpuMainService(ui::mojom::GpuMainAssociatedRequest request);
+ void CreateVizMainService(viz::mojom::VizMainAssociatedRequest request);
bool in_process_gpu() const;
@@ -73,7 +74,7 @@ class GpuChildThread : public ChildThreadImpl, public ui::GpuMain::Delegate {
const std::string& name,
mojo::ScopedInterfaceEndpointHandle handle) override;
- // ui::GpuMain::Delegate:
+ // viz::VizMainImpl::Delegate:
void OnInitializationFailed() override;
void OnGpuServiceConnection(viz::GpuServiceImpl* gpu_service) override;
@@ -88,7 +89,7 @@ class GpuChildThread : public ChildThreadImpl, public ui::GpuMain::Delegate {
media::AndroidOverlayConfig);
#endif
- ui::GpuMain gpu_main_;
+ viz::VizMainImpl viz_main_;
// ServiceFactory for service_manager::Service hosting.
std::unique_ptr<GpuServiceFactory> service_factory_;
diff --git a/chromium/content/gpu/gpu_main.cc b/chromium/content/gpu/gpu_main.cc
index 556cf00e8ac..c170ebdf874 100644
--- a/chromium/content/gpu/gpu_main.cc
+++ b/chromium/content/gpu/gpu_main.cc
@@ -22,6 +22,7 @@
#include "base/timer/hi_res_timer_manager.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "components/viz/service/main/viz_main_impl.h"
#include "content/common/content_constants_internal.h"
#include "content/common/content_switches_internal.h"
#include "content/gpu/gpu_child_thread.h"
@@ -36,11 +37,12 @@
#include "gpu/config/gpu_switches.h"
#include "gpu/config/gpu_util.h"
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
+#include "gpu/ipc/common/gpu_preferences_util.h"
#include "gpu/ipc/service/gpu_config.h"
#include "gpu/ipc/service/gpu_init.h"
#include "gpu/ipc/service/gpu_watchdog_thread.h"
#include "media/gpu/features.h"
-#include "services/ui/gpu/gpu_main.h"
+#include "third_party/angle/src/gpu_info_util/SystemInfo.h"
#include "third_party/skia/include/core/SkGraphics.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/gfx/switches.h"
@@ -76,8 +78,10 @@
#if defined(OS_LINUX)
#include "content/common/font_config_ipc_linux.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
+#include "content/gpu/gpu_sandbox_hook_linux.h"
+#include "content/public/common/common_sandbox_support_linux.h"
#include "content/public/common/sandbox_init.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#include "third_party/skia/include/ports/SkFontConfigInterface.h"
#endif
@@ -99,19 +103,21 @@ namespace content {
namespace {
#if defined(OS_LINUX)
-bool StartSandboxLinux(gpu::GpuWatchdogThread*, const gpu::GPUInfo*);
+bool StartSandboxLinux(gpu::GpuWatchdogThread*,
+ const gpu::GPUInfo*,
+ const gpu::GpuPreferences&);
#elif defined(OS_WIN)
bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*);
#endif
-base::LazyInstance<ui::GpuMain::LogMessages>::DestructorAtExit
+base::LazyInstance<viz::VizMainImpl::LogMessages>::DestructorAtExit
deferred_messages = LAZY_INSTANCE_INITIALIZER;
bool GpuProcessLogMessageHandler(int severity,
const char* file, int line,
size_t message_start,
const std::string& str) {
- ui::GpuMain::LogMessage log;
+ viz::VizMainImpl::LogMessage log;
log.severity = severity;
log.header = str.substr(0, message_start);
log.message = str.substr(message_start);
@@ -155,13 +161,14 @@ class ContentSandboxHelper : public gpu::GpuSandboxHelper {
}
bool EnsureSandboxInitialized(gpu::GpuWatchdogThread* watchdog_thread,
- const gpu::GPUInfo* gpu_info) override {
+ const gpu::GPUInfo* gpu_info,
+ const gpu::GpuPreferences& gpu_prefs) override {
#if defined(OS_LINUX)
- return StartSandboxLinux(watchdog_thread, gpu_info);
+ return StartSandboxLinux(watchdog_thread, gpu_info, gpu_prefs);
#elif defined(OS_WIN)
return StartSandboxWindows(sandbox_info_);
#elif defined(OS_MACOSX)
- return service_manager::Sandbox::SandboxIsCurrentlyActive();
+ return service_manager::SandboxMac::IsCurrentlyActive();
#else
return false;
#endif
@@ -179,12 +186,21 @@ class ContentSandboxHelper : public gpu::GpuSandboxHelper {
// Main function for starting the Gpu process.
int GpuMain(const MainFunctionParams& parameters) {
TRACE_EVENT0("gpu", "GpuMain");
- base::trace_event::TraceLog::GetInstance()->SetProcessName("GPU Process");
+ base::trace_event::TraceLog::GetInstance()->set_process_name("GPU Process");
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventGpuProcessSortIndex);
const base::CommandLine& command_line = parameters.command_line;
- if (command_line.HasSwitch(switches::kGpuStartupDialog))
+
+ gpu::GpuPreferences gpu_preferences;
+ if (command_line.HasSwitch(switches::kGpuPreferences)) {
+ std::string value =
+ command_line.GetSwitchValueASCII(switches::kGpuPreferences);
+ bool success = gpu::SwitchValueToGpuPreferences(value, &gpu_preferences);
+ CHECK(success);
+ }
+
+ if (gpu_preferences.gpu_startup_dialog)
WaitForDebugger("Gpu");
base::Time start_time = base::Time::Now();
@@ -239,9 +255,10 @@ int GpuMain(const MainFunctionParams& parameters) {
#elif defined(OS_LINUX)
#error "Unsupported Linux platform."
#elif defined(OS_MACOSX)
- // This is necessary for CoreAnimation layers hosted in the GPU process to
- // be drawn. See http://crbug.com/312462.
- std::unique_ptr<base::MessagePump> pump(new base::MessagePumpCFRunLoop());
+ // Cross-process CoreAnimation requires a CFRunLoop to function at all, and
+ // requires a NSRunLoop to not starve under heavy load. See:
+ // https://crbug.com/312462#c51 and https://crbug.com/783298
+ std::unique_ptr<base::MessagePump> pump(new base::MessagePumpNSRunLoop());
main_message_loop.reset(new base::MessageLoop(std::move(pump)));
#else
main_message_loop.reset(
@@ -274,12 +291,12 @@ int GpuMain(const MainFunctionParams& parameters) {
// set up between the browser and GPU process, and the GPU process crashes or
// exits early, the browser process will never detect it. For this reason we
// defer tearing down the GPU process until receiving the initialization
- // message from the browser (through mojom::GpuMain::CreateGpuService()).
+ // message from the browser (through mojom::VizMain::CreateGpuService()).
const bool init_success = gpu_init->InitializeAndStartSandbox(
- const_cast<base::CommandLine*>(&command_line));
+ const_cast<base::CommandLine*>(&command_line), gpu_preferences);
const bool dead_on_arrival = !init_success;
- logging::SetLogMessageHandler(NULL);
+ logging::SetLogMessageHandler(nullptr);
GetContentClient()->SetGpuInfo(gpu_init->gpu_info());
base::ThreadPriority io_thread_priority = base::ThreadPriority::NORMAL;
@@ -325,24 +342,38 @@ namespace {
#if defined(OS_LINUX)
bool StartSandboxLinux(gpu::GpuWatchdogThread* watchdog_thread,
- const gpu::GPUInfo* gpu_info) {
+ const gpu::GPUInfo* gpu_info,
+ const gpu::GpuPreferences& gpu_prefs) {
TRACE_EVENT0("gpu,startup", "Initialize sandbox");
- bool res = false;
-
if (watchdog_thread) {
- // LinuxSandbox needs to be able to ensure that the thread
+ // SandboxLinux needs to be able to ensure that the thread
// has really been stopped.
- LinuxSandbox::StopThread(watchdog_thread);
+ service_manager::SandboxLinux::GetInstance()->StopThread(watchdog_thread);
}
- // LinuxSandbox::InitializeSandbox() must always be called
+ // SandboxLinux::InitializeSandbox() must always be called
// with only one thread.
- res = LinuxSandbox::InitializeSandbox(gpu_info);
+ service_manager::SandboxLinux::Options sandbox_options;
+ sandbox_options.use_amd_specific_policies =
+ gpu_info && angle::IsAMD(gpu_info->active_gpu().vendor_id);
+ sandbox_options.accelerated_video_decode_enabled =
+ !gpu_prefs.disable_accelerated_video_decode;
+
+#if defined(OS_CHROMEOS)
+ sandbox_options.vaapi_accelerated_video_encode_enabled =
+ !gpu_prefs.disable_vaapi_accelerated_video_encode;
+#endif
+
+ bool res = service_manager::SandboxLinux::GetInstance()->InitializeSandbox(
+ service_manager::SandboxTypeFromCommandLine(
+ *base::CommandLine::ForCurrentProcess()),
+ base::BindOnce(GpuProcessPreSandboxHook), sandbox_options);
+
if (watchdog_thread) {
- base::Thread::Options options;
- options.timer_slack = base::TIMER_SLACK_MAXIMUM;
- watchdog_thread->StartWithOptions(options);
+ base::Thread::Options thread_options;
+ thread_options.timer_slack = base::TIMER_SLACK_MAXIMUM;
+ watchdog_thread->StartWithOptions(thread_options);
}
return res;
diff --git a/chromium/content/gpu/gpu_sandbox_hook_linux.cc b/chromium/content/gpu/gpu_sandbox_hook_linux.cc
new file mode 100644
index 00000000000..c0ea3627ea5
--- /dev/null
+++ b/chromium/content/gpu/gpu_sandbox_hook_linux.cc
@@ -0,0 +1,351 @@
+// Copyright 2017 The Chromium Authors. 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/gpu/gpu_sandbox_hook_linux.h"
+
+#include <dlfcn.h>
+#include <errno.h>
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/files/file_enumerator.h"
+#include "base/files/scoped_file.h"
+#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
+#include "build/buildflag.h"
+#include "content/public/common/content_switches.h"
+#include "media/gpu/features.h"
+#include "sandbox/linux/bpf_dsl/policy.h"
+#include "sandbox/linux/syscall_broker/broker_file_permission.h"
+#include "sandbox/linux/syscall_broker/broker_process.h"
+#include "services/service_manager/embedder/set_process_title.h"
+#include "services/service_manager/sandbox/linux/bpf_cros_amd_gpu_policy_linux.h"
+#include "services/service_manager/sandbox/linux/bpf_cros_arm_gpu_policy_linux.h"
+#include "services/service_manager/sandbox/linux/bpf_gpu_policy_linux.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
+
+#if BUILDFLAG(USE_VAAPI)
+#include <va/va_version.h>
+#endif
+
+using sandbox::bpf_dsl::Policy;
+using sandbox::syscall_broker::BrokerFilePermission;
+using sandbox::syscall_broker::BrokerProcess;
+
+namespace content {
+namespace {
+
+inline bool IsChromeOS() {
+#if defined(OS_CHROMEOS)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsArchitectureX86_64() {
+#if defined(__x86_64__)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsArchitectureI386() {
+#if defined(__i386__)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsArchitectureArm() {
+#if defined(ARCH_CPU_ARM_FAMILY)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool UseV4L2Codec() {
+#if BUILDFLAG(USE_V4L2_CODEC)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool UseLibV4L2() {
+#if BUILDFLAG(USE_LIBV4L2)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsLibVAVersion2() {
+#if BUILDFLAG(USE_VAAPI) && VA_MAJOR_VERSION == 1
+ return true;
+#else
+ return false;
+#endif
+}
+
+constexpr int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;
+
+void AddV4L2GpuWhitelist(
+ std::vector<BrokerFilePermission>* permissions,
+ const service_manager::SandboxSeccompBPF::Options& options) {
+ if (options.accelerated_video_decode_enabled) {
+ // Device nodes for V4L2 video decode accelerator drivers.
+ static const base::FilePath::CharType kDevicePath[] =
+ FILE_PATH_LITERAL("/dev/");
+ static const base::FilePath::CharType kVideoDecPattern[] = "video-dec[0-9]";
+ base::FileEnumerator enumerator(base::FilePath(kDevicePath), false,
+ base::FileEnumerator::FILES,
+ base::FilePath(kVideoDecPattern).value());
+ for (base::FilePath name = enumerator.Next(); !name.empty();
+ name = enumerator.Next())
+ permissions->push_back(BrokerFilePermission::ReadWrite(name.value()));
+ }
+
+ // Device node for V4L2 video encode accelerator drivers.
+ static const char kDevVideoEncPath[] = "/dev/video-enc";
+ permissions->push_back(BrokerFilePermission::ReadWrite(kDevVideoEncPath));
+
+ // Device node for V4L2 JPEG decode accelerator drivers.
+ static const char kDevJpegDecPath[] = "/dev/jpeg-dec";
+ permissions->push_back(BrokerFilePermission::ReadWrite(kDevJpegDecPath));
+}
+
+void AddArmMaliGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
+ // Device file needed by the ARM GPU userspace.
+ static const char kMali0Path[] = "/dev/mali0";
+
+ // Image processor used on ARM platforms.
+ static const char kDevImageProc0Path[] = "/dev/image-proc0";
+
+ permissions->push_back(BrokerFilePermission::ReadWrite(kMali0Path));
+ permissions->push_back(BrokerFilePermission::ReadWrite(kDevImageProc0Path));
+}
+
+void AddAmdGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
+ static const char* const kReadOnlyList[] = {"/etc/ld.so.cache",
+ "/usr/lib64/libEGL.so.1",
+ "/usr/lib64/libGLESv2.so.2"};
+ for (const char* item : kReadOnlyList)
+ permissions->push_back(BrokerFilePermission::ReadOnly(item));
+
+ static const char* const kReadWriteList[] = {
+ "/dev/dri",
+ "/dev/dri/card0",
+ "/dev/dri/controlD64",
+ "/dev/dri/renderD128",
+ "/sys/class/drm/card0/device/config",
+ "/sys/class/drm/controlD64/device/config",
+ "/sys/class/drm/renderD128/device/config",
+ "/usr/share/libdrm/amdgpu.ids"};
+ for (const char* item : kReadWriteList)
+ permissions->push_back(BrokerFilePermission::ReadWrite(item));
+
+ static const char kCharDevices[] = "/sys/dev/char/";
+ permissions->push_back(BrokerFilePermission::ReadOnlyRecursive(kCharDevices));
+}
+
+void AddArmGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
+ // On ARM we're enabling the sandbox before the X connection is made,
+ // so we need to allow access to |.Xauthority|.
+ static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
+ 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));
+ permissions->push_back(BrokerFilePermission::ReadOnly(kLibEglPath));
+
+ AddArmMaliGpuWhitelist(permissions);
+}
+
+void AddStandardGpuWhiteList(std::vector<BrokerFilePermission>* permissions) {
+ static const char kDriCardBasePath[] = "/dev/dri/card";
+ static const char kNvidiaCtlPath[] = "/dev/nvidiactl";
+ static const char kNvidiaDeviceBasePath[] = "/dev/nvidia";
+ static const char kNvidiaParamsPath[] = "/proc/driver/nvidia/params";
+ static const char kDevShm[] = "/dev/shm/";
+
+ // For shared memory.
+ permissions->push_back(
+ BrokerFilePermission::ReadWriteCreateTemporaryRecursive(kDevShm));
+
+ // For DRI cards.
+ for (int i = 0; i <= 9; ++i) {
+ permissions->push_back(BrokerFilePermission::ReadWrite(
+ base::StringPrintf("%s%d", kDriCardBasePath, i)));
+ }
+
+ // For Nvidia GLX driver.
+ permissions->push_back(BrokerFilePermission::ReadWrite(kNvidiaCtlPath));
+ for (int i = 0; i < 10; ++i) {
+ permissions->push_back(BrokerFilePermission::ReadWrite(
+ base::StringPrintf("%s%d", kNvidiaDeviceBasePath, i)));
+ }
+ permissions->push_back(BrokerFilePermission::ReadOnly(kNvidiaParamsPath));
+}
+
+std::vector<BrokerFilePermission> FilePermissionsForGpu(
+ const service_manager::SandboxSeccompBPF::Options& options) {
+ std::vector<BrokerFilePermission> permissions;
+
+ // All GPU process policies need this file brokered out.
+ static const char kDriRcPath[] = "/etc/drirc";
+ permissions.push_back(BrokerFilePermission::ReadOnly(kDriRcPath));
+
+ if (IsChromeOS()) {
+ if (UseV4L2Codec())
+ AddV4L2GpuWhitelist(&permissions, options);
+ if (IsArchitectureArm()) {
+ AddArmGpuWhitelist(&permissions);
+ return permissions;
+ }
+ if (options.use_amd_specific_policies) {
+ AddAmdGpuWhitelist(&permissions);
+ return permissions;
+ }
+ }
+ AddStandardGpuWhiteList(&permissions);
+ return permissions;
+}
+
+void LoadArmGpuLibraries() {
+ // Preload the Mali library.
+ dlopen("/usr/lib/libmali.so", dlopen_flag);
+
+ // Preload the Tegra V4L2 (video decode acceleration) library.
+ dlopen("/usr/lib/libtegrav4l2.so", dlopen_flag);
+}
+
+bool LoadAmdGpuLibraries() {
+ // Preload the amdgpu-dependent libraries.
+ if (nullptr == dlopen("libglapi.so", dlopen_flag)) {
+ LOG(ERROR) << "dlopen(libglapi.so) failed with error: " << dlerror();
+ return false;
+ }
+
+ const char* radeonsi_lib = "/usr/lib64/dri/radeonsi_dri.so";
+#if defined(DRI_DRIVER_DIR)
+ radeonsi_lib = DRI_DRIVER_DIR "/radeonsi_dri.so";
+#endif
+ if (nullptr == dlopen(radeonsi_lib, dlopen_flag)) {
+ LOG(ERROR) << "dlopen(radeonsi_dri.so) failed with error: " << dlerror();
+ return false;
+ }
+ return true;
+}
+
+void LoadV4L2Libraries() {
+ if (UseLibV4L2()) {
+ dlopen("/usr/lib/libv4l2.so", dlopen_flag);
+
+ // This is a device-specific encoder plugin.
+ dlopen("/usr/lib/libv4l/plugins/libv4l-encplugin.so", dlopen_flag);
+ }
+}
+
+void LoadStandardLibraries(
+ const service_manager::SandboxSeccompBPF::Options& options) {
+ if (IsArchitectureX86_64() || IsArchitectureI386()) {
+ // Accelerated video dlopen()'s some shared objects
+ // inside the sandbox, so preload them now.
+ if (options.vaapi_accelerated_video_encode_enabled ||
+ options.accelerated_video_decode_enabled) {
+ if (IsLibVAVersion2()) {
+ if (IsArchitectureX86_64()) {
+ dlopen("/usr/lib64/va/drivers/i965_drv_video.so", dlopen_flag);
+ dlopen("/usr/lib64/va/drivers/hybrid_drv_video.so", dlopen_flag);
+ } else if (IsArchitectureI386()) {
+ dlopen("/usr/lib/va/drivers/i965_drv_video.so", dlopen_flag);
+ }
+ dlopen("libva.so.2", dlopen_flag);
+#if defined(USE_OZONE)
+ dlopen("libva-drm.so.2", dlopen_flag);
+#endif
+ } else {
+ // If we are linked against libva 1, we have two cases to handle:
+ // - the sysroot includes both libva 1 and 2, in which case the drivers
+ // are in /usr/lib{64}/va1/
+ // - the sysroot only includes libva 1, in which case the drivers are
+ // are in /usr/lib{64}/va/
+ // This is ugly, but temporary until all builds have switched to libva 2.
+ if (IsArchitectureX86_64()) {
+ if (!dlopen("/usr/lib64/va1/drivers/i965_drv_video.so", dlopen_flag))
+ dlopen("/usr/lib64/va/drivers/i965_drv_video.so", dlopen_flag);
+ if (!dlopen("/usr/lib64/va1/drivers/hybrid_drv_video.so", dlopen_flag))
+ dlopen("/usr/lib64/va/drivers/hybrid_drv_video.so", dlopen_flag);
+ } else if (IsArchitectureI386()) {
+ if (!dlopen("/usr/lib/va1/drivers/i965_drv_video.so", dlopen_flag))
+ dlopen("/usr/lib/va/drivers/i965_drv_video.so", dlopen_flag);
+ }
+ dlopen("libva.so.1", dlopen_flag);
+#if defined(USE_OZONE)
+ dlopen("libva-drm.so.1", dlopen_flag);
+#elif defined(USE_X11)
+ dlopen("libva-x11.so.1", dlopen_flag);
+#endif
+ }
+ }
+ }
+}
+
+bool LoadLibrariesForGpu(
+ const service_manager::SandboxSeccompBPF::Options& options) {
+ if (IsChromeOS()) {
+ if (UseV4L2Codec())
+ LoadV4L2Libraries();
+ if (IsArchitectureArm()) {
+ LoadArmGpuLibraries();
+ return true;
+ }
+ if (options.use_amd_specific_policies)
+ return LoadAmdGpuLibraries();
+ }
+ LoadStandardLibraries(options);
+ return true;
+}
+
+bool BrokerProcessPreSandboxHook(
+ service_manager::BPFBasePolicy* policy,
+ service_manager::SandboxLinux::Options options) {
+ // Oddly enough, we call back into gpu to invoke this service manager
+ // method, since it is part of the embedder component, and the service
+ // mananger's sandbox component is a lower layer that can't depend on it.
+ service_manager::SetProcessTitleFromCommandLine(nullptr);
+ return true;
+}
+
+} // namespace
+
+bool GpuProcessPreSandboxHook(service_manager::BPFBasePolicy* policy,
+ service_manager::SandboxLinux::Options options) {
+ auto* instance = service_manager::SandboxLinux::GetInstance();
+ instance->StartBrokerProcess(policy, FilePermissionsForGpu(options),
+ base::BindOnce(BrokerProcessPreSandboxHook),
+ options);
+
+ if (!LoadLibrariesForGpu(options))
+ return false;
+
+ // TODO(tsepez): enable namspace sandbox here once crashes are understood.
+
+ errno = 0;
+ return true;
+}
+
+} // namespace content
diff --git a/chromium/content/gpu/gpu_sandbox_hook_linux.h b/chromium/content/gpu/gpu_sandbox_hook_linux.h
new file mode 100644
index 00000000000..581f61f7a5b
--- /dev/null
+++ b/chromium/content/gpu/gpu_sandbox_hook_linux.h
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_GPU_GPU_SANDBOX_HOOK_LINUX_H_
+#define CONTENT_GPU_GPU_SANDBOX_HOOK_LINUX_H_
+
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
+
+namespace content {
+
+bool GpuProcessPreSandboxHook(service_manager::BPFBasePolicy* policy,
+ service_manager::SandboxLinux::Options options);
+
+} // namespace content
+
+#endif // CONTENT_GPU_GPU_SANDBOX_HOOK_LINUX_H_
diff --git a/chromium/content/gpu/gpu_service_factory.cc b/chromium/content/gpu/gpu_service_factory.cc
index c8d60024e39..9daced1ca4d 100644
--- a/chromium/content/gpu/gpu_service_factory.cc
+++ b/chromium/content/gpu/gpu_service_factory.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "services/shape_detection/public/interfaces/constants.mojom.h"
#include "services/shape_detection/shape_detection_service.h"
@@ -37,7 +38,12 @@ void GpuServiceFactory::RegisterServices(ServiceMap* services) {
info.factory =
base::Bind(&media::CreateGpuMediaService, gpu_preferences_, task_runner_,
media_gpu_channel_manager_, android_overlay_factory_cb_);
- info.use_own_thread = true;
+ // 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".
+ // TODO(crbug.com/786169): Check whether this needs to be single threaded.
+ info.task_runner = base::CreateSingleThreadTaskRunnerWithTraits(
+ {base::TaskPriority::USER_BLOCKING});
services->insert(std::make_pair("media", info));
#endif
diff --git a/chromium/content/gpu/in_process_gpu_thread.cc b/chromium/content/gpu/in_process_gpu_thread.cc
index 185ddee629a..39145978648 100644
--- a/chromium/content/gpu/in_process_gpu_thread.cc
+++ b/chromium/content/gpu/in_process_gpu_thread.cc
@@ -12,6 +12,7 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/gpu/content_gpu_client.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/config/gpu_info_collector.h"
#include "gpu/config/gpu_util.h"
#include "gpu/ipc/service/gpu_init.h"
@@ -27,10 +28,13 @@
namespace content {
-InProcessGpuThread::InProcessGpuThread(const InProcessChildThreadParams& params)
+InProcessGpuThread::InProcessGpuThread(
+ const InProcessChildThreadParams& params,
+ const gpu::GpuPreferences& gpu_preferences)
: base::Thread("Chrome_InProcGpuThread"),
params_(params),
- gpu_process_(NULL) {}
+ gpu_process_(nullptr),
+ gpu_preferences_(gpu_preferences) {}
InProcessGpuThread::~InProcessGpuThread() {
Stop();
@@ -54,6 +58,7 @@ void InProcessGpuThread::Init() {
auto gpu_init = std::make_unique<gpu::GpuInit>();
auto* client = GetContentClient()->gpu();
gpu_init->InitializeInProcess(base::CommandLine::ForCurrentProcess(),
+ gpu_preferences_,
client ? client->GetGPUInfo() : nullptr,
client ? client->GetGpuFeatureInfo() : nullptr);
@@ -77,8 +82,9 @@ void InProcessGpuThread::CleanUp() {
}
base::Thread* CreateInProcessGpuThread(
- const InProcessChildThreadParams& params) {
- return new InProcessGpuThread(params);
+ const InProcessChildThreadParams& params,
+ const gpu::GpuPreferences& gpu_preferences) {
+ return new InProcessGpuThread(params, gpu_preferences);
}
} // namespace content
diff --git a/chromium/content/gpu/in_process_gpu_thread.h b/chromium/content/gpu/in_process_gpu_thread.h
index 66af2058bdc..c8e96e88d47 100644
--- a/chromium/content/gpu/in_process_gpu_thread.h
+++ b/chromium/content/gpu/in_process_gpu_thread.h
@@ -11,6 +11,7 @@
#include "base/threading/thread.h"
#include "content/common/content_export.h"
#include "content/common/in_process_child_thread_params.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
namespace content {
@@ -20,7 +21,8 @@ class GpuProcess;
// with --in-process-gpu or --single-process.
class InProcessGpuThread : public base::Thread {
public:
- explicit InProcessGpuThread(const InProcessChildThreadParams& params);
+ explicit InProcessGpuThread(const InProcessChildThreadParams& params,
+ const gpu::GpuPreferences& gpu_preferences);
~InProcessGpuThread() override;
protected:
@@ -33,11 +35,14 @@ class InProcessGpuThread : public base::Thread {
// Deleted in CleanUp() on the gpu thread, so don't use smart pointers.
GpuProcess* gpu_process_;
+ gpu::GpuPreferences gpu_preferences_;
+
DISALLOW_COPY_AND_ASSIGN(InProcessGpuThread);
};
CONTENT_EXPORT base::Thread* CreateInProcessGpuThread(
- const InProcessChildThreadParams& params);
+ const InProcessChildThreadParams& params,
+ const gpu::GpuPreferences& gpu_preferences);
} // namespace content
diff --git a/chromium/content/network/BUILD.gn b/chromium/content/network/BUILD.gn
index 7f80049b444..7a6dec9130f 100644
--- a/chromium/content/network/BUILD.gn
+++ b/chromium/content/network/BUILD.gn
@@ -35,24 +35,42 @@ source_set("network_sources") {
sources = [
"cache_url_loader.cc",
"cache_url_loader.h",
- "cookie_manager_impl.cc",
- "cookie_manager_impl.h",
+ "cookie_manager.cc",
+ "cookie_manager.h",
"http_server_properties_pref_delegate.cc",
"http_server_properties_pref_delegate.h",
+ "network_change_manager.cc",
+ "network_change_manager.h",
"network_context.cc",
"network_context.h",
+ "network_sandbox_hook_linux.cc",
+ "network_sandbox_hook_linux.h",
"network_service_impl.cc",
"network_service_impl.h",
- "network_service_url_loader_factory_impl.cc",
- "network_service_url_loader_factory_impl.h",
+ "network_service_url_loader_factory.cc",
+ "network_service_url_loader_factory.h",
"proxy_resolver_factory_mojo.cc",
"proxy_resolver_factory_mojo.h",
"proxy_service_mojo.cc",
"proxy_service_mojo.h",
- "restricted_cookie_manager_impl.cc",
- "restricted_cookie_manager_impl.h",
- "url_loader_impl.cc",
- "url_loader_impl.h",
+ "restricted_cookie_manager.cc",
+ "restricted_cookie_manager.h",
+ "throttling/network_conditions.cc",
+ "throttling/network_conditions.h",
+ "throttling/throttling_controller.cc",
+ "throttling/throttling_controller.h",
+ "throttling/throttling_network_interceptor.cc",
+ "throttling/throttling_network_interceptor.h",
+ "throttling/throttling_network_transaction.cc",
+ "throttling/throttling_network_transaction.h",
+ "throttling/throttling_network_transaction_factory.cc",
+ "throttling/throttling_network_transaction_factory.h",
+ "throttling/throttling_upload_data_stream.cc",
+ "throttling/throttling_upload_data_stream.h",
+ "upload_progress_tracker.cc",
+ "upload_progress_tracker.h",
+ "url_loader.cc",
+ "url_loader.h",
]
configs += [ "//content:content_implementation" ]
diff --git a/chromium/content/network/DEPS b/chromium/content/network/DEPS
index 72414111d96..1b70a4601bd 100644
--- a/chromium/content/network/DEPS
+++ b/chromium/content/network/DEPS
@@ -1,6 +1,9 @@
# Tight rules since this will move to services/network. See README.
include_rules = [
"+components/network_session_configurator",
+ # Prefs are used to create an independent file with a persisted key:value
+ # store for networking-related data (Like which servers support QUIC), rather
+ # than to store user preferences.
"+components/prefs",
"-content",
"+content/common/content_export.h",
@@ -12,6 +15,7 @@ include_rules = [
"+content/public/common/network_service.mojom.h",
"+content/public/common/referrer.h",
"+content/public/common/resource_request.h",
+ "+content/public/common/resource_request_body.h",
"+content/public/common/resource_response.h",
"+content/public/common/url_constants.h",
"+content/public/common/url_loader.mojom.h",
@@ -19,6 +23,7 @@ include_rules = [
"+content/public/network",
"+services/network",
"+services/service_manager/public",
+ "+services/service_manager/sandbox",
]
specific_include_rules = {
diff --git a/chromium/content/network/OWNERS b/chromium/content/network/OWNERS
index 0374f39f131..7e6f7eb0dd3 100644
--- a/chromium/content/network/OWNERS
+++ b/chromium/content/network/OWNERS
@@ -1,9 +1,11 @@
ananta@chromium.org
-asanka@chromium.org
jam@chromium.org
+kinuko@chromium.org
mmenke@chromium.org
rdsmith@chromium.org
scottmg@chromium.org
+xunjieli@chromium.org
+yhirano@chromium.org
yzshen@chromium.org
per-file manifest.json=set noparent
diff --git a/chromium/content/browser/frame_host/PRESUBMIT.py b/chromium/content/network/PRESUBMIT.py
index d5a87427dea..e1c3e3327e2 100644
--- a/chromium/content/browser/frame_host/PRESUBMIT.py
+++ b/chromium/content/network/PRESUBMIT.py
@@ -1,7 +1,7 @@
# 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.
-"""Presubmit script for //content/browser/frame_host.
+"""Presubmit script for //content/network.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into depot_tools.
@@ -10,13 +10,13 @@ for more details about the presubmit API built into depot_tools.
def PostUploadHook(cl, change, output_api):
"""git cl upload will call this hook after the issue is created/modified.
- This hook adds extra try bots to the CL description in order to run site
- isolation tests in addition to CQ try bots.
+ This hook adds extra try bots to the CL description in order to run network
+ service tests in addition to CQ try bots.
"""
return output_api.EnsureCQIncludeTrybotsAreAdded(
cl,
[
- 'master.tryserver.chromium.linux:linux_site_isolation'
+ 'master.tryserver.chromium.linux:linux_mojo'
],
- 'Automatically added site isolation trybots to run tests on CQ.')
+ 'Automatically added network service trybots to run tests on CQ.')
diff --git a/chromium/content/network/cache_url_loader.cc b/chromium/content/network/cache_url_loader.cc
index 1ea062254df..6225f1aec0c 100644
--- a/chromium/content/network/cache_url_loader.cc
+++ b/chromium/content/network/cache_url_loader.cc
@@ -61,7 +61,7 @@ class CacheURLLoader {
mojo::common::BlockingCopyFromString(data_, data_pipe.producer_handle));
client_->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
- ResourceRequestCompletionStatus status(net::OK);
+ network::URLLoaderCompletionStatus status(net::OK);
status.encoded_data_length = data_.size();
status.encoded_body_length = data_.size();
client_->OnComplete(status);
diff --git a/chromium/content/network/cookie_manager_impl.cc b/chromium/content/network/cookie_manager.cc
index d7238daf856..22b602c7d56 100644
--- a/chromium/content/network/cookie_manager_impl.cc
+++ b/chromium/content/network/cookie_manager.cc
@@ -2,8 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/network/cookie_manager_impl.h"
+#include "content/network/cookie_manager.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_options.h"
@@ -32,15 +33,19 @@ class PredicateWrapper {
: std::set<std::string>()),
session_control_(filter->session_control) {}
+ // Return true if the given cookie should be deleted.
bool Predicate(const net::CanonicalCookie& cookie) {
// Ignore begin/end times; they're handled by method args.
bool result = true;
+ // Delete if the cookie is not in excluding_domains_.
if (use_excluding_domains_)
- result &= (excluding_domains_.count(cookie.Domain()) == 0);
+ result &= !DomainMatches(cookie, excluding_domains_);
+ // Delete if the cookie is in including_domains_.
if (use_including_domains_)
- result &= (including_domains_.count(cookie.Domain()) != 0);
+ result &= DomainMatches(cookie, including_domains_);
+ // Delete if the cookie is not the correct persistent or session type.
if (session_control_ !=
network::mojom::CookieDeletionSessionControl::IGNORE_CONTROL) {
// Relies on the assumption that there are only three values possible for
@@ -54,6 +59,25 @@ class PredicateWrapper {
}
private:
+ // Return true if the eTLD+1 of the domain matches any of the strings
+ // in |match_domains|, false otherwise.
+ bool DomainMatches(const net::CanonicalCookie& cookie,
+ const std::set<std::string>& match_domains) {
+ std::string effective_domain(
+ net::registry_controlled_domains::GetDomainAndRegistry(
+ // GetDomainAndRegistry() is insensitive to leading dots, i.e.
+ // to host/domain cookie distinctions.
+ cookie.Domain(),
+ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
+ // If the cookie's domain is is not parsed as belonging to a registry
+ // (e.g. for IP addresses or internal hostnames) an empty string will be
+ // returned. In this case, use the domain in the cookie.
+ if (effective_domain.empty())
+ effective_domain = cookie.Domain();
+
+ return match_domains.count(effective_domain) != 0;
+ }
+
bool use_excluding_domains_;
std::set<std::string> excluding_domains_;
@@ -93,42 +117,40 @@ network::mojom::CookieChangeCause ChangeCauseTranslation(
} // namespace
-CookieManagerImpl::NotificationRegistration::NotificationRegistration() {}
+CookieManager::NotificationRegistration::NotificationRegistration() {}
-CookieManagerImpl::NotificationRegistration::~NotificationRegistration() {}
+CookieManager::NotificationRegistration::~NotificationRegistration() {}
-CookieManagerImpl::CookieManagerImpl(net::CookieStore* cookie_store)
+CookieManager::CookieManager(net::CookieStore* cookie_store)
: cookie_store_(cookie_store) {}
-CookieManagerImpl::~CookieManagerImpl() {}
+CookieManager::~CookieManager() {}
-void CookieManagerImpl::AddRequest(
- network::mojom::CookieManagerRequest request) {
+void CookieManager::AddRequest(network::mojom::CookieManagerRequest request) {
bindings_.AddBinding(this, std::move(request));
}
-void CookieManagerImpl::GetAllCookies(GetAllCookiesCallback callback) {
+void CookieManager::GetAllCookies(GetAllCookiesCallback callback) {
cookie_store_->GetAllCookiesAsync(std::move(callback));
}
-void CookieManagerImpl::GetCookieList(const GURL& url,
- const net::CookieOptions& cookie_options,
- GetCookieListCallback callback) {
+void CookieManager::GetCookieList(const GURL& url,
+ const net::CookieOptions& cookie_options,
+ GetCookieListCallback callback) {
cookie_store_->GetCookieListWithOptionsAsync(url, cookie_options,
std::move(callback));
}
-void CookieManagerImpl::SetCanonicalCookie(
- const net::CanonicalCookie& cookie,
- bool secure_source,
- bool modify_http_only,
- SetCanonicalCookieCallback callback) {
+void CookieManager::SetCanonicalCookie(const net::CanonicalCookie& cookie,
+ bool secure_source,
+ bool modify_http_only,
+ SetCanonicalCookieCallback callback) {
cookie_store_->SetCanonicalCookieAsync(
- base::MakeUnique<net::CanonicalCookie>(cookie), secure_source,
+ std::make_unique<net::CanonicalCookie>(cookie), secure_source,
modify_http_only, std::move(callback));
}
-void CookieManagerImpl::DeleteCookies(
+void CookieManager::DeleteCookies(
network::mojom::CookieDeletionFilterPtr filter,
DeleteCookiesCallback callback) {
base::Time start_time;
@@ -143,24 +165,24 @@ void CookieManagerImpl::DeleteCookies(
cookie_store_->DeleteAllCreatedBetweenWithPredicateAsync(
start_time, end_time,
base::Bind(&PredicateWrapper::Predicate,
- base::MakeUnique<PredicateWrapper>(std::move(filter))),
+ std::make_unique<PredicateWrapper>(std::move(filter))),
std::move(callback));
}
-void CookieManagerImpl::RequestNotification(
+void CookieManager::RequestNotification(
const GURL& url,
const std::string& name,
network::mojom::CookieChangeNotificationPtr notification_pointer) {
std::unique_ptr<NotificationRegistration> notification_registration(
- base::MakeUnique<NotificationRegistration>());
+ std::make_unique<NotificationRegistration>());
notification_registration->notification_pointer =
std::move(notification_pointer);
notification_registration->subscription = cookie_store_->AddCallbackForCookie(
url, name,
- base::Bind(&CookieManagerImpl::CookieChanged,
+ base::Bind(&CookieManager::CookieChanged,
// base::Unretained is safe as destruction of the
- // CookieManagerImpl will also destroy the
+ // CookieManager will also destroy the
// notifications_registered list (which this object will be
// inserted into, below), which will destroy the
// CookieChangedSubscription, unregistering the callback.
@@ -171,9 +193,9 @@ void CookieManagerImpl::RequestNotification(
base::Unretained(notification_registration.get())));
notification_registration->notification_pointer.set_connection_error_handler(
- base::BindOnce(&CookieManagerImpl::NotificationPipeBroken,
+ base::BindOnce(&CookieManager::NotificationPipeBroken,
// base::Unretained is safe as destruction of the
- // CookieManagerImpl will also destroy the
+ // CookieManager will also destroy the
// notifications_registered list (which this object will be
// inserted into, below), which will destroy the
// notification_pointer, rendering this callback moot.
@@ -186,14 +208,14 @@ void CookieManagerImpl::RequestNotification(
notifications_registered_.push_back(std::move(notification_registration));
}
-void CookieManagerImpl::CookieChanged(NotificationRegistration* registration,
- const net::CanonicalCookie& cookie,
- net::CookieStore::ChangeCause cause) {
+void CookieManager::CookieChanged(NotificationRegistration* registration,
+ const net::CanonicalCookie& cookie,
+ net::CookieStore::ChangeCause cause) {
registration->notification_pointer->OnCookieChanged(
cookie, ChangeCauseTranslation(cause));
}
-void CookieManagerImpl::NotificationPipeBroken(
+void CookieManager::NotificationPipeBroken(
NotificationRegistration* registration) {
for (auto it = notifications_registered_.begin();
it != notifications_registered_.end(); ++it) {
@@ -208,7 +230,7 @@ void CookieManagerImpl::NotificationPipeBroken(
NOTREACHED();
}
-void CookieManagerImpl::CloneInterface(
+void CookieManager::CloneInterface(
network::mojom::CookieManagerRequest new_interface) {
AddRequest(std::move(new_interface));
}
diff --git a/chromium/content/network/cookie_manager_impl.h b/chromium/content/network/cookie_manager.h
index 1ef74da91ce..5f9438f7d79 100644
--- a/chromium/content/network/cookie_manager_impl.h
+++ b/chromium/content/network/cookie_manager.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_NETWORK_COOKIE_MANAGER_IMPL_H_
-#define CONTENT_NETWORK_COOKIE_MANAGER_IMPL_H_
+#ifndef CONTENT_NETWORK_COOKIE_MANAGER_H_
+#define CONTENT_NETWORK_COOKIE_MANAGER_H_
#include <memory>
#include <string>
@@ -24,13 +24,13 @@ namespace content {
// This is an IO thread object; all methods on this object must be called on
// the IO thread. Note that this does not restrict the locations from which
// mojo messages may be sent to the object.
-class CONTENT_EXPORT CookieManagerImpl : public network::mojom::CookieManager {
+class CONTENT_EXPORT CookieManager : public network::mojom::CookieManager {
public:
// Construct a CookieService that can serve mojo requests for the underlying
// cookie store. |*cookie_store| must outlive this object.
- explicit CookieManagerImpl(net::CookieStore* cookie_store);
+ explicit CookieManager(net::CookieStore* cookie_store);
- ~CookieManagerImpl() override;
+ ~CookieManager() override;
// Bind a cookie request to this object. Mojo messages
// coming through the associated pipe will be served by this object.
@@ -89,9 +89,9 @@ class CONTENT_EXPORT CookieManagerImpl : public network::mojom::CookieManager {
std::vector<std::unique_ptr<NotificationRegistration>>
notifications_registered_;
- DISALLOW_COPY_AND_ASSIGN(CookieManagerImpl);
+ DISALLOW_COPY_AND_ASSIGN(CookieManager);
};
} // namespace content
-#endif // CONTENT_NETWORK_COOKIE_MANAGER_IMPL_H_
+#endif // CONTENT_NETWORK_COOKIE_MANAGER_H_
diff --git a/chromium/content/network/cookie_manager_impl_unittest.cc b/chromium/content/network/cookie_manager_unittest.cc
index bb29f5cad31..2cf279ea301 100644
--- a/chromium/content/network/cookie_manager_impl_unittest.cc
+++ b/chromium/content/network/cookie_manager_unittest.cc
@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/network/cookie_manager_impl.h"
+#include "content/network/cookie_manager.h"
#include <algorithm>
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/time/time.h"
@@ -21,10 +22,10 @@
// * SynchronousMojoCookieWrapper: Takes a network::mojom::CookieManager at
// construction; exposes synchronous interfaces that wrap the
// network::mojom::CookieManager async interfaces to make testing easier.
-// * CookieChangeNotificationImpl: Test class implementing
+// * CookieChangeNotification: Test class implementing
// the CookieChangeNotification interface and recording
// incoming messages on it.
-// * CookieManagerImplTest: Test base class. Automatically sets up
+// * CookieManagerTest: Test base class. Automatically sets up
// a cookie store, a cookie service wrapping it, a mojo pipe
// connected to the server, and the cookie service implemented
// by the other end of the pipe.
@@ -133,59 +134,19 @@ class SynchronousCookieManager {
DISALLOW_COPY_AND_ASSIGN(SynchronousCookieManager);
};
-class CookieManagerImplTest : public testing::Test {
+class CookieManagerTest : public testing::Test {
public:
- CookieManagerImplTest()
+ CookieManagerTest()
: connection_error_seen_(false),
cookie_monster_(nullptr, nullptr),
- cookie_service_(base::MakeUnique<CookieManagerImpl>(&cookie_monster_)) {
+ cookie_service_(std::make_unique<CookieManager>(&cookie_monster_)) {
cookie_service_->AddRequest(mojo::MakeRequest(&cookie_service_ptr_));
service_wrapper_ =
- base::MakeUnique<SynchronousCookieManager>(cookie_service_ptr_.get());
+ std::make_unique<SynchronousCookieManager>(cookie_service_ptr_.get());
cookie_service_ptr_.set_connection_error_handler(base::BindOnce(
- &CookieManagerImplTest::OnConnectionError, base::Unretained(this)));
- }
- ~CookieManagerImplTest() override {}
-
- void SetUp() override {
- setup_time_ = base::Time::Now();
-
- // Set a couple of cookies for tests to play with.
- bool result;
- result = SetCanonicalCookie(
- net::CanonicalCookie(
- "A", "B", "foo_host", "/", base::Time(), base::Time(), base::Time(),
- /*secure=*/false, /*httponly=*/false,
- net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
- true, true);
- DCHECK(result);
-
- result = SetCanonicalCookie(
- net::CanonicalCookie(
- "C", "D", "foo_host2", "/with/path", base::Time(), base::Time(),
- base::Time(), /*secure=*/false, /*httponly=*/false,
- net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
- true, true);
- DCHECK(result);
-
- result = SetCanonicalCookie(
- net::CanonicalCookie(
- "Secure", "E", "foo_host", "/with/path", base::Time(), base::Time(),
- base::Time(), /*secure=*/true,
- /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_MEDIUM),
- true, true);
- DCHECK(result);
-
- result = SetCanonicalCookie(
- net::CanonicalCookie(
- "HttpOnly", "F", "foo_host", "/with/path", base::Time(),
- base::Time(), base::Time(), /*secure=*/false,
- /*httponly=*/true, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_MEDIUM),
- true, true);
- DCHECK(result);
+ &CookieManagerTest::OnConnectionError, base::Unretained(this)));
}
+ ~CookieManagerTest() override {}
// Tear down the remote service.
void NukeService() { cookie_service_.reset(); }
@@ -196,7 +157,7 @@ class CookieManagerImplTest : public testing::Test {
bool can_modify_httponly) {
net::ResultSavingCookieCallback<bool> callback;
cookie_monster_.SetCanonicalCookieAsync(
- base::MakeUnique<net::CanonicalCookie>(cookie), secure_source,
+ std::make_unique<net::CanonicalCookie>(cookie), secure_source,
can_modify_httponly,
base::BindOnce(&net::ResultSavingCookieCallback<bool>::Run,
base::Unretained(&callback)));
@@ -206,7 +167,7 @@ class CookieManagerImplTest : public testing::Test {
net::CookieStore* cookie_store() { return &cookie_monster_; }
- CookieManagerImpl* service_impl() const { return cookie_service_.get(); }
+ CookieManager* service() const { return cookie_service_.get(); }
// Return the cookie service at the client end of the mojo pipe.
network::mojom::CookieManager* cookie_service_client() {
@@ -216,8 +177,6 @@ class CookieManagerImplTest : public testing::Test {
// Synchronous wrapper
SynchronousCookieManager* service_wrapper() { return service_wrapper_.get(); }
- base::Time setup_time() const { return setup_time_; }
-
bool connection_error_seen() const { return connection_error_seen_; }
private:
@@ -227,12 +186,11 @@ class CookieManagerImplTest : public testing::Test {
base::MessageLoopForIO message_loop_;
net::CookieMonster cookie_monster_;
- std::unique_ptr<content::CookieManagerImpl> cookie_service_;
+ std::unique_ptr<content::CookieManager> cookie_service_;
network::mojom::CookieManagerPtr cookie_service_ptr_;
std::unique_ptr<SynchronousCookieManager> service_wrapper_;
- base::Time setup_time_;
- DISALLOW_COPY_AND_ASSIGN(CookieManagerImplTest);
+ DISALLOW_COPY_AND_ASSIGN(CookieManagerTest);
};
namespace {
@@ -246,8 +204,38 @@ bool CompareCanonicalCookies(const net::CanonicalCookie& c1,
// Test the GetAllCookies accessor. Also tests that canonical
// cookies come out of the store unchanged.
-TEST_F(CookieManagerImplTest, GetAllCookies) {
- base::Time now(base::Time::Now());
+TEST_F(CookieManagerTest, GetAllCookies) {
+ base::Time before_creation(base::Time::Now());
+
+ // Set some cookies for the test to play with.
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A", "B", "foo_host", "/", base::Time(), base::Time(), base::Time(),
+ /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "C", "D", "foo_host2", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "Secure", "E", "foo_host", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/true,
+ /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "HttpOnly", "F", "foo_host", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false,
+ /*httponly=*/true, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ base::Time after_creation(base::Time::Now());
std::vector<net::CanonicalCookie> cookies =
service_wrapper()->GetAllCookies();
@@ -259,8 +247,8 @@ TEST_F(CookieManagerImplTest, GetAllCookies) {
EXPECT_EQ("B", cookies[0].Value());
EXPECT_EQ("foo_host", cookies[0].Domain());
EXPECT_EQ("/", cookies[0].Path());
- EXPECT_LT(setup_time(), cookies[0].CreationDate());
- EXPECT_LT(cookies[0].CreationDate(), now);
+ EXPECT_LT(before_creation, cookies[0].CreationDate());
+ EXPECT_LE(cookies[0].CreationDate(), after_creation);
EXPECT_EQ(cookies[0].LastAccessDate(), base::Time());
EXPECT_EQ(cookies[0].ExpiryDate(), base::Time());
EXPECT_FALSE(cookies[0].IsPersistent());
@@ -273,8 +261,8 @@ TEST_F(CookieManagerImplTest, GetAllCookies) {
EXPECT_EQ("D", cookies[1].Value());
EXPECT_EQ("foo_host2", cookies[1].Domain());
EXPECT_EQ("/with/path", cookies[1].Path());
- EXPECT_LT(setup_time(), cookies[1].CreationDate());
- EXPECT_LT(cookies[1].CreationDate(), now);
+ EXPECT_LT(before_creation, cookies[1].CreationDate());
+ EXPECT_LE(cookies[1].CreationDate(), after_creation);
EXPECT_EQ(cookies[1].LastAccessDate(), base::Time());
EXPECT_EQ(cookies[1].ExpiryDate(), base::Time());
EXPECT_FALSE(cookies[1].IsPersistent());
@@ -287,8 +275,8 @@ TEST_F(CookieManagerImplTest, GetAllCookies) {
EXPECT_EQ("F", cookies[2].Value());
EXPECT_EQ("foo_host", cookies[2].Domain());
EXPECT_EQ("/with/path", cookies[2].Path());
- EXPECT_LT(setup_time(), cookies[2].CreationDate());
- EXPECT_LT(cookies[2].CreationDate(), now);
+ EXPECT_LT(before_creation, cookies[2].CreationDate());
+ EXPECT_LE(cookies[2].CreationDate(), after_creation);
EXPECT_EQ(cookies[2].LastAccessDate(), base::Time());
EXPECT_EQ(cookies[2].ExpiryDate(), base::Time());
EXPECT_FALSE(cookies[2].IsPersistent());
@@ -301,8 +289,8 @@ TEST_F(CookieManagerImplTest, GetAllCookies) {
EXPECT_EQ("E", cookies[3].Value());
EXPECT_EQ("foo_host", cookies[3].Domain());
EXPECT_EQ("/with/path", cookies[3].Path());
- EXPECT_LT(setup_time(), cookies[3].CreationDate());
- EXPECT_LT(cookies[3].CreationDate(), now);
+ EXPECT_LT(before_creation, cookies[3].CreationDate());
+ EXPECT_LE(cookies[3].CreationDate(), after_creation);
EXPECT_EQ(cookies[3].LastAccessDate(), base::Time());
EXPECT_EQ(cookies[3].ExpiryDate(), base::Time());
EXPECT_FALSE(cookies[3].IsPersistent());
@@ -312,7 +300,35 @@ TEST_F(CookieManagerImplTest, GetAllCookies) {
EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[3].Priority());
}
-TEST_F(CookieManagerImplTest, GetCookieList) {
+TEST_F(CookieManagerTest, GetCookieList) {
+ // Set some cookies for the test to play with.
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A", "B", "foo_host", "/", base::Time(), base::Time(), base::Time(),
+ /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "C", "D", "foo_host2", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "Secure", "E", "foo_host", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/true,
+ /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "HttpOnly", "F", "foo_host", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false,
+ /*httponly=*/true, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
std::vector<net::CanonicalCookie> cookies = service_wrapper()->GetCookieList(
GURL("https://foo_host/with/path"), net::CookieOptions());
@@ -326,11 +342,7 @@ TEST_F(CookieManagerImplTest, GetCookieList) {
EXPECT_EQ("E", cookies[1].Value());
}
-TEST_F(CookieManagerImplTest, GetCookieListHttpOnly) {
- // Clean out the cookies.
- network::mojom::CookieDeletionFilter filter;
- EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));
-
+TEST_F(CookieManagerTest, GetCookieListHttpOnly) {
// Create an httponly and a non-httponly cookie.
bool result;
result = SetCanonicalCookie(
@@ -367,11 +379,7 @@ TEST_F(CookieManagerImplTest, GetCookieListHttpOnly) {
EXPECT_EQ("C", cookies[1].Name());
}
-TEST_F(CookieManagerImplTest, GetCookieListSameSite) {
- // Clean out the cookies.
- network::mojom::CookieDeletionFilter filter;
- EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));
-
+TEST_F(CookieManagerTest, GetCookieListSameSite) {
// Create an unrestricted, a lax, and a strict cookie.
bool result;
result = SetCanonicalCookie(
@@ -427,12 +435,8 @@ TEST_F(CookieManagerImplTest, GetCookieListSameSite) {
EXPECT_EQ("E", cookies[2].Name());
}
-TEST_F(CookieManagerImplTest, GetCookieListAccessTime) {
- // Clean out the cookies and set a new, clean cookie.
- network::mojom::CookieDeletionFilter filter;
- EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));
- bool result;
- result = SetCanonicalCookie(
+TEST_F(CookieManagerTest, GetCookieListAccessTime) {
+ bool result = SetCanonicalCookie(
net::CanonicalCookie(
"A", "B", "foo_host", "/", base::Time(), base::Time(), base::Time(),
/*secure=*/false, /*httponly=*/false,
@@ -463,37 +467,35 @@ TEST_F(CookieManagerImplTest, GetCookieListAccessTime) {
EXPECT_LE(cookies[0].LastAccessDate(), base::Time::Now());
}
-TEST_F(CookieManagerImplTest, SetExtraCookie) {
- EXPECT_TRUE(service_wrapper()->SetCanonicalCookie(
+TEST_F(CookieManagerTest, DeleteThroughSet) {
+ // Set some cookies for the test to play with.
+ EXPECT_TRUE(SetCanonicalCookie(
net::CanonicalCookie(
- "X", "Y", "new_host", "/", base::Time(), base::Time(), base::Time(),
+ "A", "B", "foo_host", "/", base::Time(), base::Time(), base::Time(),
/*secure=*/false, /*httponly=*/false,
net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
- false, false));
-
- std::vector<net::CanonicalCookie> cookies =
- service_wrapper()->GetAllCookies();
-
- ASSERT_EQ(5u, cookies.size());
- std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
-
- EXPECT_EQ("A", cookies[0].Name());
- EXPECT_EQ("B", cookies[0].Value());
-
- EXPECT_EQ("C", cookies[1].Name());
- EXPECT_EQ("D", cookies[1].Value());
-
- EXPECT_EQ("HttpOnly", cookies[2].Name());
- EXPECT_EQ("F", cookies[2].Value());
-
- EXPECT_EQ("Secure", cookies[3].Name());
- EXPECT_EQ("E", cookies[3].Value());
-
- EXPECT_EQ("X", cookies[4].Name());
- EXPECT_EQ("Y", cookies[4].Value());
-}
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "C", "D", "foo_host2", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "Secure", "E", "foo_host", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/true,
+ /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "HttpOnly", "F", "foo_host", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false,
+ /*httponly=*/true, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
-TEST_F(CookieManagerImplTest, DeleteThroughSet) {
base::Time yesterday = base::Time::Now() - base::TimeDelta::FromDays(1);
EXPECT_TRUE(service_wrapper()->SetCanonicalCookie(
net::CanonicalCookie("A", "E", "foo_host", "/", base::Time(), yesterday,
@@ -518,7 +520,7 @@ TEST_F(CookieManagerImplTest, DeleteThroughSet) {
EXPECT_EQ("E", cookies[2].Value());
}
-TEST_F(CookieManagerImplTest, ConfirmSecureSetFails) {
+TEST_F(CookieManagerTest, ConfirmSecureSetFails) {
EXPECT_FALSE(service_wrapper()->SetCanonicalCookie(
net::CanonicalCookie(
"N", "O", "foo_host", "/", base::Time(), base::Time(), base::Time(),
@@ -528,10 +530,10 @@ TEST_F(CookieManagerImplTest, ConfirmSecureSetFails) {
std::vector<net::CanonicalCookie> cookies =
service_wrapper()->GetAllCookies();
- ASSERT_EQ(4u, cookies.size());
+ ASSERT_EQ(0u, cookies.size());
}
-TEST_F(CookieManagerImplTest, ConfirmHttpOnlySetFails) {
+TEST_F(CookieManagerTest, ConfirmHttpOnlySetFails) {
EXPECT_FALSE(service_wrapper()->SetCanonicalCookie(
net::CanonicalCookie(
"N", "O", "foo_host", "/", base::Time(), base::Time(), base::Time(),
@@ -541,10 +543,18 @@ TEST_F(CookieManagerImplTest, ConfirmHttpOnlySetFails) {
std::vector<net::CanonicalCookie> cookies =
service_wrapper()->GetAllCookies();
- ASSERT_EQ(4u, cookies.size());
+ ASSERT_EQ(0u, cookies.size());
}
-TEST_F(CookieManagerImplTest, ConfirmHttpOnlyOverwriteFails) {
+TEST_F(CookieManagerTest, ConfirmHttpOnlyOverwriteFails) {
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "HttpOnly", "F", "foo_host", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false,
+ /*httponly=*/true, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
EXPECT_FALSE(service_wrapper()->SetCanonicalCookie(
net::CanonicalCookie(
"HttpOnly", "Nope", "foo_host", "/with/path", base::Time(),
@@ -555,13 +565,41 @@ TEST_F(CookieManagerImplTest, ConfirmHttpOnlyOverwriteFails) {
std::vector<net::CanonicalCookie> cookies =
service_wrapper()->GetAllCookies();
- ASSERT_EQ(4u, cookies.size());
+ ASSERT_EQ(1u, cookies.size());
std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
- EXPECT_EQ("HttpOnly", cookies[2].Name());
- EXPECT_EQ("F", cookies[2].Value());
+ EXPECT_EQ("HttpOnly", cookies[0].Name());
+ EXPECT_EQ("F", cookies[0].Value());
}
-TEST_F(CookieManagerImplTest, DeleteEverything) {
+TEST_F(CookieManagerTest, DeleteEverything) {
+ // Set some cookies for the test to play with.
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A", "B", "foo_host", "/", base::Time(), base::Time(), base::Time(),
+ /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "C", "D", "foo_host2", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "Secure", "E", "foo_host", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/true,
+ /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "HttpOnly", "F", "foo_host", "/with/path", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false,
+ /*httponly=*/true, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
network::mojom::CookieDeletionFilter filter;
EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));
@@ -570,9 +608,7 @@ TEST_F(CookieManagerImplTest, DeleteEverything) {
ASSERT_EQ(0u, cookies.size());
}
-TEST_F(CookieManagerImplTest, DeleteByTime) {
- network::mojom::CookieDeletionFilter filter;
- EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));
+TEST_F(CookieManagerTest, DeleteByTime) {
base::Time now(base::Time::Now());
// Create three cookies and delete the middle one.
@@ -597,6 +633,7 @@ TEST_F(CookieManagerImplTest, DeleteByTime) {
net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
true, true));
+ network::mojom::CookieDeletionFilter filter;
filter.created_after_time = now - base::TimeDelta::FromMinutes(150);
filter.created_before_time = now - base::TimeDelta::FromMinutes(90);
EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));
@@ -608,10 +645,7 @@ TEST_F(CookieManagerImplTest, DeleteByTime) {
EXPECT_EQ("A3", cookies[1].Name());
}
-TEST_F(CookieManagerImplTest, DeleteByExcludingDomains) {
- network::mojom::CookieDeletionFilter filter;
- EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));
-
+TEST_F(CookieManagerTest, DeleteByExcludingDomains) {
// Create three cookies and delete the middle one.
EXPECT_TRUE(SetCanonicalCookie(
net::CanonicalCookie(
@@ -634,6 +668,7 @@ TEST_F(CookieManagerImplTest, DeleteByExcludingDomains) {
net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
true, true));
+ network::mojom::CookieDeletionFilter filter;
filter.excluding_domains = std::vector<std::string>();
filter.excluding_domains->push_back("foo_host2");
EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
@@ -643,10 +678,7 @@ TEST_F(CookieManagerImplTest, DeleteByExcludingDomains) {
EXPECT_EQ("A2", cookies[0].Name());
}
-TEST_F(CookieManagerImplTest, DeleteByIncludingDomains) {
- network::mojom::CookieDeletionFilter filter;
- EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));
-
+TEST_F(CookieManagerTest, DeleteByIncludingDomains) {
// Create three cookies and delete the middle one.
EXPECT_TRUE(SetCanonicalCookie(
net::CanonicalCookie(
@@ -669,6 +701,7 @@ TEST_F(CookieManagerImplTest, DeleteByIncludingDomains) {
net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
true, true));
+ network::mojom::CookieDeletionFilter filter;
filter.including_domains = std::vector<std::string>();
filter.including_domains->push_back("foo_host1");
filter.including_domains->push_back("foo_host3");
@@ -679,9 +712,444 @@ TEST_F(CookieManagerImplTest, DeleteByIncludingDomains) {
EXPECT_EQ("A2", cookies[0].Name());
}
-TEST_F(CookieManagerImplTest, DeleteBySessionStatus) {
+// Confirm deletion is based on eTLD+1
+TEST_F(CookieManagerTest, DeleteDetails_eTLD) {
+ // Two domains on diferent levels of the same eTLD both get deleted.
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A1", "val", "example.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A2", "val", "www.example.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A3", "val", "www.nonexample.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
network::mojom::CookieDeletionFilter filter;
- EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));
+ filter.including_domains = std::vector<std::string>();
+ filter.including_domains->push_back("example.com");
+ EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
+ std::vector<net::CanonicalCookie> cookies =
+ service_wrapper()->GetAllCookies();
+ EXPECT_EQ(1u, cookies.size());
+ EXPECT_EQ("A3", cookies[0].Name());
+ filter = network::mojom::CookieDeletionFilter();
+ EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));
+
+ // Same thing happens on an eTLD+1 which isn't a TLD+1.
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A1", "val", "example.co.uk", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A2", "val", "www.example.co.uk", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A3", "val", "www.nonexample.co.uk", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ filter.including_domains = std::vector<std::string>();
+ filter.including_domains->push_back("example.co.uk");
+ EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
+ cookies = service_wrapper()->GetAllCookies();
+ EXPECT_EQ(1u, cookies.size());
+ EXPECT_EQ("A3", cookies[0].Name());
+ filter = network::mojom::CookieDeletionFilter();
+ EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));
+
+ // Deletion of a second level domain that's an eTLD doesn't delete any
+ // subdomains.
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A1", "val", "example.co.uk", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A2", "val", "www.example.co.uk", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A3", "val", "www.nonexample.co.uk", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ filter.including_domains = std::vector<std::string>();
+ filter.including_domains->push_back("co.uk");
+ EXPECT_EQ(0u, service_wrapper()->DeleteCookies(filter));
+ cookies = service_wrapper()->GetAllCookies();
+ EXPECT_EQ(3u, cookies.size());
+ EXPECT_EQ("A1", cookies[0].Name());
+ EXPECT_EQ("A2", cookies[1].Name());
+ EXPECT_EQ("A3", cookies[2].Name());
+}
+
+// Confirm deletion ignores host/domain distinction.
+TEST_F(CookieManagerTest, DeleteDetails_HostDomain) {
+ // Create four cookies: A host (no leading .) and domain cookie
+ // (leading .) for each of two separate domains. Confirm that the
+ // filter deletes both of one domain and leaves the other alone.
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A1", "val", "foo_host.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A2", "val", ".foo_host.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A3", "val", "bar.host.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A4", "val", ".bar.host.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ network::mojom::CookieDeletionFilter filter;
+ filter.including_domains = std::vector<std::string>();
+ filter.including_domains->push_back("foo_host.com");
+ EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
+ std::vector<net::CanonicalCookie> cookies =
+ service_wrapper()->GetAllCookies();
+ EXPECT_EQ(2u, cookies.size());
+ std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
+ EXPECT_EQ("A3", cookies[0].Name());
+ EXPECT_EQ("A4", cookies[1].Name());
+}
+
+TEST_F(CookieManagerTest, DeleteDetails_eTLDvsPrivateRegistry) {
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A1", "val", "random.co.uk", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A2", "val", "sub.domain.random.co.uk", "/", base::Time(),
+ base::Time(), base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A3", "val", "random.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A4", "val", "random", "/", base::Time(), base::Time(), base::Time(),
+ /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A5", "val", "normal.co.uk", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ network::mojom::CookieDeletionFilter filter;
+ filter.including_domains = std::vector<std::string>();
+ filter.including_domains->push_back("random.co.uk");
+ EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
+ std::vector<net::CanonicalCookie> cookies =
+ service_wrapper()->GetAllCookies();
+ ASSERT_EQ(3u, cookies.size());
+ std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
+ EXPECT_EQ("A3", cookies[0].Name());
+ EXPECT_EQ("A4", cookies[1].Name());
+ EXPECT_EQ("A5", cookies[2].Name());
+}
+
+TEST_F(CookieManagerTest, DeleteDetails_PrivateRegistry) {
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A1", "val", "privatedomain", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ // Will not actually be treated as a private domain as it's under
+ // .com.
+ "A2", "val", "privatedomain.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ // Will not actually be treated as a private domain as it's two
+ // level
+ "A3", "val", "subdomain.privatedomain", "/", base::Time(),
+ base::Time(), base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ network::mojom::CookieDeletionFilter filter;
+ filter.including_domains = std::vector<std::string>();
+ filter.including_domains->push_back("privatedomain");
+ EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));
+ std::vector<net::CanonicalCookie> cookies =
+ service_wrapper()->GetAllCookies();
+ ASSERT_EQ(2u, cookies.size());
+ std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
+ EXPECT_EQ("A2", cookies[0].Name());
+ EXPECT_EQ("A3", cookies[1].Name());
+}
+
+// Test to probe and make sure the attributes that deletion should ignore
+// don't affect the results.
+TEST_F(CookieManagerTest, DeleteDetails_IgnoredFields) {
+ // Simple deletion filter
+ network::mojom::CookieDeletionFilter filter;
+ filter.including_domains = std::vector<std::string>();
+ filter.including_domains->push_back("example.com");
+
+ // Set two cookies for each ignored field, one that will be deleted by the
+ // above filter, and one that won't, with values unused in other tests
+ // for the ignored field. Secure & httponly are tested in
+ // DeleteDetails_Consumer below, and expiration does affect deletion
+ // through the persistence distinction.
+
+ // Value
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A01", "RandomValue", "example.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A02", "RandomValue", "canonical.com", "/", base::Time(),
+ base::Time(), base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ // Path
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A03", "val", "example.com", "/this/is/a/long/path", base::Time(),
+ base::Time(), base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A04", "val", "canonical.com", "/this/is/a/long/path", base::Time(),
+ base::Time(), base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ // Last_access
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A05", "val", "example.com", "/",
+ base::Time::Now() - base::TimeDelta::FromDays(3), base::Time(),
+ base::Time::Now() - base::TimeDelta::FromDays(3), /*secure=*/false,
+ /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A06", "val", "canonical.com", "/",
+ base::Time::Now() - base::TimeDelta::FromDays(3), base::Time(),
+ base::Time::Now() - base::TimeDelta::FromDays(3), /*secure=*/false,
+ /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ // Same_site
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie("A07", "val", "example.com", "/", base::Time(),
+ base::Time(), base::Time(), /*secure=*/false,
+ /*httponly=*/false, net::CookieSameSite::STRICT_MODE,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie("A08", "val", "canonical.com", "/", base::Time(),
+ base::Time(), base::Time(), /*secure=*/false,
+ /*httponly=*/false, net::CookieSameSite::STRICT_MODE,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ // Priority
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A09", "val", "example.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_HIGH),
+ true, true));
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A10", "val", "canonical.com", "/", base::Time(), base::Time(),
+ base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_HIGH),
+ true, true));
+
+ // Use the filter and make sure the result is the expected set.
+ EXPECT_EQ(5u, service_wrapper()->DeleteCookies(filter));
+ std::vector<net::CanonicalCookie> cookies =
+ service_wrapper()->GetAllCookies();
+ ASSERT_EQ(5u, cookies.size());
+ std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
+ EXPECT_EQ("A02", cookies[0].Name());
+ EXPECT_EQ("A04", cookies[1].Name());
+ EXPECT_EQ("A06", cookies[2].Name());
+ EXPECT_EQ("A08", cookies[3].Name());
+ EXPECT_EQ("A10", cookies[4].Name());
+}
+
+// A set of tests specified by the only consumer of this interface
+// (BrowsingDataFilterBuilderImpl).
+TEST_F(CookieManagerTest, DeleteDetails_Consumer) {
+ const char* filter_domains[] = {
+ "google.com",
+
+ // sp.nom.br is an eTLD, so this is a regular valid registrable domain,
+ // just like google.com.
+ "website.sp.nom.br",
+
+ // This domain will also not be found in registries, and since it has only
+ // one component, it will not be recognized as a valid registrable domain.
+ "fileserver",
+
+ // This domain will not be found in registries. It will be assumed that
+ // it belongs to an unknown registry, and since it has two components,
+ // they will be treated as the second level domain and TLD. Most
+ // importantly, it will NOT be treated as a subdomain of "fileserver".
+ "second-level-domain.fileserver",
+
+ // IP addresses are supported.
+ "192.168.1.1",
+ };
+ network::mojom::CookieDeletionFilter test_filter;
+ test_filter.including_domains = std::vector<std::string>();
+ for (int i = 0; i < static_cast<int>(arraysize(filter_domains)); ++i)
+ test_filter.including_domains->push_back(filter_domains[i]);
+
+ struct TestCase {
+ std::string domain;
+ std::string path;
+ bool expect_delete;
+ } test_cases[] = {
+ // We match any URL on the specified domains.
+ {"www.google.com", "/foo/bar", true},
+ {"www.sub.google.com", "/foo/bar", true},
+ {"sub.google.com", "/", true},
+ {"www.sub.google.com", "/foo/bar", true},
+ {"website.sp.nom.br", "/", true},
+ {"www.website.sp.nom.br", "/", true},
+ {"192.168.1.1", "/", true},
+
+ // Internal hostnames do not have subdomains.
+ {"fileserver", "/", true},
+ {"fileserver", "/foo/bar", true},
+ {"website.fileserver", "/foo/bar", false},
+
+ // This is a valid registrable domain with the TLD "fileserver", which
+ // is unrelated to the internal hostname "fileserver".
+ {"second-level-domain.fileserver", "/foo", true},
+ {"www.second-level-domain.fileserver", "/index.html", true},
+
+ // Different domains.
+ {"www.youtube.com", "/", false},
+ {"www.google.net", "/", false},
+ {"192.168.1.2", "/", false},
+
+ // Check both a bare eTLD.
+ {"sp.nom.br", "/", false},
+ };
+
+ network::mojom::CookieDeletionFilter clear_filter;
+ for (int i = 0; i < static_cast<int>(arraysize(test_cases)); ++i) {
+ TestCase& test_case(test_cases[i]);
+
+ // Clear store.
+ service_wrapper()->DeleteCookies(clear_filter);
+
+ // IP addresses and internal hostnames can only be host cookies.
+ bool exclude_domain_cookie =
+ (GURL("http://" + test_case.domain).HostIsIPAddress() ||
+ test_case.domain.find(".") == std::string::npos);
+
+ // Standard cookie
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A1", "val", test_cases[i].domain, test_cases[i].path, base::Time(),
+ base::Time(), base::Time(), /*secure=*/false, /*httponly=*/false,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ if (!exclude_domain_cookie) {
+ // Host cookie
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A2", "val", "." + test_cases[i].domain, test_cases[i].path,
+ base::Time(), base::Time(), base::Time(), /*secure=*/false,
+ /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+ }
+
+ // Httponly cookie
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A3", "val", test_cases[i].domain, test_cases[i].path, base::Time(),
+ base::Time(), base::Time(), /*secure=*/false, /*httponly=*/true,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ // Httponly and secure cookie
+ EXPECT_TRUE(SetCanonicalCookie(
+ net::CanonicalCookie(
+ "A4", "val", test_cases[i].domain, test_cases[i].path, base::Time(),
+ base::Time(), base::Time(), /*secure=*/false, /*httponly=*/true,
+ net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
+ true, true));
+
+ const uint32_t number_cookies = exclude_domain_cookie ? 3u : 4u;
+ EXPECT_EQ(number_cookies, service_wrapper()->GetAllCookies().size());
+ EXPECT_EQ(test_cases[i].expect_delete ? number_cookies : 0u,
+ service_wrapper()->DeleteCookies(test_filter))
+ << "Case " << i << " domain " << test_cases[i].domain << " path "
+ << test_cases[i].path << " expect "
+ << (test_cases[i].expect_delete ? "delete" : "keep");
+ EXPECT_EQ(test_cases[i].expect_delete ? 0u : number_cookies,
+ service_wrapper()->GetAllCookies().size());
+ }
+}
+
+TEST_F(CookieManagerTest, DeleteBySessionStatus) {
base::Time now(base::Time::Now());
// Create three cookies and delete the middle one.
@@ -707,6 +1175,7 @@ TEST_F(CookieManagerImplTest, DeleteBySessionStatus) {
net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM),
true, true));
+ network::mojom::CookieDeletionFilter filter;
filter.session_control =
network::mojom::CookieDeletionSessionControl::PERSISTENT_COOKIES;
EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));
@@ -718,9 +1187,7 @@ TEST_F(CookieManagerImplTest, DeleteBySessionStatus) {
EXPECT_EQ("A3", cookies[1].Name());
}
-TEST_F(CookieManagerImplTest, DeleteByAll) {
- network::mojom::CookieDeletionFilter filter;
- EXPECT_EQ(4u, service_wrapper()->DeleteCookies(filter));
+TEST_F(CookieManagerTest, DeleteByAll) {
base::Time now(base::Time::Now());
// Add a lot of cookies, only one of which will be deleted by the filter.
@@ -735,6 +1202,7 @@ TEST_F(CookieManagerImplTest, DeleteByAll) {
// Each of the other four cookies will vary in a way that will take it out
// of being deleted by one of the filter.
+ network::mojom::CookieDeletionFilter filter;
filter.created_after_time = now - base::TimeDelta::FromDays(4);
filter.created_before_time = now - base::TimeDelta::FromDays(2);
filter.including_domains = std::vector<std::string>();
@@ -812,7 +1280,7 @@ TEST_F(CookieManagerImplTest, DeleteByAll) {
}
// Receives and records notifications from the network::mojom::CookieManager.
-class CookieChangeNotificationImpl
+class CookieChangeNotification
: public network::mojom::CookieChangeNotification {
public:
struct Notification {
@@ -826,7 +1294,7 @@ class CookieChangeNotificationImpl
network::mojom::CookieChangeCause cause;
};
- CookieChangeNotificationImpl(
+ CookieChangeNotification(
network::mojom::CookieChangeNotificationRequest request)
: run_loop_(nullptr), binding_(this, std::move(request)) {}
@@ -863,20 +1331,21 @@ class CookieChangeNotificationImpl
mojo::Binding<network::mojom::CookieChangeNotification> binding_;
};
-TEST_F(CookieManagerImplTest, Notification) {
+TEST_F(CookieManagerTest, Notification) {
GURL notification_url("http://www.testing.com/pathele");
+ std::string notification_domain("testing.com");
std::string notification_name("Cookie_Name");
network::mojom::CookieChangeNotificationPtr ptr;
network::mojom::CookieChangeNotificationRequest request(
mojo::MakeRequest(&ptr));
- CookieChangeNotificationImpl notification_impl(std::move(request));
+ CookieChangeNotification notification(std::move(request));
cookie_service_client()->RequestNotification(
notification_url, notification_name, std::move(ptr));
- std::vector<CookieChangeNotificationImpl::Notification> notifications;
- notification_impl.GetCurrentNotifications(&notifications);
+ std::vector<CookieChangeNotification::Notification> notifications;
+ notification.GetCurrentNotifications(&notifications);
EXPECT_EQ(0u, notifications.size());
notifications.clear();
@@ -890,7 +1359,7 @@ TEST_F(CookieManagerImplTest, Notification) {
net::COOKIE_PRIORITY_MEDIUM),
true, true);
base::RunLoop().RunUntilIdle();
- notification_impl.GetCurrentNotifications(&notifications);
+ notification.GetCurrentNotifications(&notifications);
EXPECT_EQ(0u, notifications.size());
notifications.clear();
@@ -905,7 +1374,7 @@ TEST_F(CookieManagerImplTest, Notification) {
true, true);
base::RunLoop().RunUntilIdle();
- notification_impl.GetCurrentNotifications(&notifications);
+ notification.GetCurrentNotifications(&notifications);
EXPECT_EQ(0u, notifications.size());
notifications.clear();
@@ -919,13 +1388,13 @@ TEST_F(CookieManagerImplTest, Notification) {
true, true);
// Expect asynchrony
- notification_impl.GetCurrentNotifications(&notifications);
+ notification.GetCurrentNotifications(&notifications);
EXPECT_EQ(0u, notifications.size());
notifications.clear();
// Expect notification
- notification_impl.WaitForSomeNotification();
- notification_impl.GetCurrentNotifications(&notifications);
+ notification.WaitForSomeNotification();
+ notification.GetCurrentNotifications(&notifications);
EXPECT_EQ(1u, notifications.size());
EXPECT_EQ(notification_name, notifications[0].cookie.Name());
EXPECT_EQ(notification_url.host(), notifications[0].cookie.Domain());
@@ -938,12 +1407,14 @@ TEST_F(CookieManagerImplTest, Notification) {
// will not be generated.
network::mojom::CookieDeletionFilter filter;
filter.including_domains = std::vector<std::string>();
- filter.including_domains->push_back(notification_url.host());
- EXPECT_EQ(2u, service_wrapper()->DeleteCookies(filter));
+ filter.including_domains->push_back(notification_domain);
+ // If this test fails, it may indicate a problem which will lead to
+ // no notifications being generated and the test hanging, so assert.
+ ASSERT_EQ(2u, service_wrapper()->DeleteCookies(filter));
// The notification may already have arrived, or it may arrive in the future.
- notification_impl.WaitForSomeNotification();
- notification_impl.GetCurrentNotifications(&notifications);
+ notification.WaitForSomeNotification();
+ notification.GetCurrentNotifications(&notifications);
ASSERT_EQ(1u, notifications.size());
EXPECT_EQ(notification_name, notifications[0].cookie.Name());
EXPECT_EQ(notification_url.host(), notifications[0].cookie.Domain());
@@ -953,7 +1424,7 @@ TEST_F(CookieManagerImplTest, Notification) {
// Confirm the service operates properly if a returned notification interface
// is destroyed.
-TEST_F(CookieManagerImplTest, NotificationRequestDestroyed) {
+TEST_F(CookieManagerTest, NotificationRequestDestroyed) {
// Create two identical notification interfaces.
GURL notification_url("http://www.testing.com/pathele");
std::string notification_name("Cookie_Name");
@@ -961,16 +1432,16 @@ TEST_F(CookieManagerImplTest, NotificationRequestDestroyed) {
network::mojom::CookieChangeNotificationPtr ptr1;
network::mojom::CookieChangeNotificationRequest request1(
mojo::MakeRequest(&ptr1));
- std::unique_ptr<CookieChangeNotificationImpl> notification_impl1(
- base::MakeUnique<CookieChangeNotificationImpl>(std::move(request1)));
+ std::unique_ptr<CookieChangeNotification> notification1(
+ std::make_unique<CookieChangeNotification>(std::move(request1)));
cookie_service_client()->RequestNotification(
notification_url, notification_name, std::move(ptr1));
network::mojom::CookieChangeNotificationPtr ptr2;
network::mojom::CookieChangeNotificationRequest request2(
mojo::MakeRequest(&ptr2));
- std::unique_ptr<CookieChangeNotificationImpl> notification_impl2(
- base::MakeUnique<CookieChangeNotificationImpl>(std::move(request2)));
+ std::unique_ptr<CookieChangeNotification> notification2(
+ std::make_unique<CookieChangeNotification>(std::move(request2)));
cookie_service_client()->RequestNotification(
notification_url, notification_name, std::move(ptr2));
@@ -983,42 +1454,42 @@ TEST_F(CookieManagerImplTest, NotificationRequestDestroyed) {
net::COOKIE_PRIORITY_MEDIUM),
true, true);
- std::vector<CookieChangeNotificationImpl::Notification> notifications;
- notification_impl1->GetCurrentNotifications(&notifications);
+ std::vector<CookieChangeNotification::Notification> notifications;
+ notification1->GetCurrentNotifications(&notifications);
EXPECT_EQ(0u, notifications.size());
notifications.clear();
- notification_impl2->GetCurrentNotifications(&notifications);
+ notification2->GetCurrentNotifications(&notifications);
EXPECT_EQ(0u, notifications.size());
notifications.clear();
- notification_impl1->WaitForSomeNotification();
- notification_impl1->GetCurrentNotifications(&notifications);
+ notification1->WaitForSomeNotification();
+ notification1->GetCurrentNotifications(&notifications);
EXPECT_EQ(1u, notifications.size());
notifications.clear();
- notification_impl2->WaitForSomeNotification();
- notification_impl2->GetCurrentNotifications(&notifications);
+ notification2->WaitForSomeNotification();
+ notification2->GetCurrentNotifications(&notifications);
EXPECT_EQ(1u, notifications.size());
notifications.clear();
- EXPECT_EQ(2u, service_impl()->GetNotificationsBoundForTesting());
+ EXPECT_EQ(2u, service()->GetNotificationsBoundForTesting());
// Destroy the first interface
- notification_impl1.reset();
+ notification1.reset();
// Confirm the second interface can still receive notifications.
network::mojom::CookieDeletionFilter filter;
- EXPECT_EQ(5u, service_wrapper()->DeleteCookies(filter));
+ EXPECT_EQ(1u, service_wrapper()->DeleteCookies(filter));
- notification_impl2->WaitForSomeNotification();
- notification_impl2->GetCurrentNotifications(&notifications);
+ notification2->WaitForSomeNotification();
+ notification2->GetCurrentNotifications(&notifications);
EXPECT_EQ(1u, notifications.size());
notifications.clear();
- EXPECT_EQ(1u, service_impl()->GetNotificationsBoundForTesting());
+ EXPECT_EQ(1u, service()->GetNotificationsBoundForTesting());
}
// Confirm we get a connection error notification if the service dies.
-TEST_F(CookieManagerImplTest, ServiceDestructVisible) {
+TEST_F(CookieManagerTest, ServiceDestructVisible) {
EXPECT_FALSE(connection_error_seen());
NukeService();
base::RunLoop().RunUntilIdle();
@@ -1027,8 +1498,8 @@ TEST_F(CookieManagerImplTest, ServiceDestructVisible) {
// Test service cloning. Also confirm that the service notices if a client
// dies.
-TEST_F(CookieManagerImplTest, CloningAndClientDestructVisible) {
- EXPECT_EQ(1u, service_impl()->GetClientsBoundForTesting());
+TEST_F(CookieManagerTest, CloningAndClientDestructVisible) {
+ EXPECT_EQ(1u, service()->GetClientsBoundForTesting());
// Clone the interface.
network::mojom::CookieManagerPtr new_ptr;
@@ -1053,11 +1524,11 @@ TEST_F(CookieManagerImplTest, CloningAndClientDestructVisible) {
// After a synchronous round trip through the new client pointer, it
// should be reflected in the bindings seen on the server.
- EXPECT_EQ(2u, service_impl()->GetClientsBoundForTesting());
+ EXPECT_EQ(2u, service()->GetClientsBoundForTesting());
new_ptr.reset();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1u, service_impl()->GetClientsBoundForTesting());
+ EXPECT_EQ(1u, service()->GetClientsBoundForTesting());
}
} // namespace content
diff --git a/chromium/content/network/network_change_manager.cc b/chromium/content/network/network_change_manager.cc
new file mode 100644
index 00000000000..f4835a6f970
--- /dev/null
+++ b/chromium/content/network/network_change_manager.cc
@@ -0,0 +1,67 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/network/network_change_manager.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/logging.h"
+#include "net/base/network_change_notifier.h"
+
+namespace content {
+
+NetworkChangeManager::NetworkChangeManager(
+ std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier)
+ : network_change_notifier_(std::move(network_change_notifier)) {
+ net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
+ connection_type_ = network::mojom::ConnectionType(
+ net::NetworkChangeNotifier::GetConnectionType());
+}
+
+NetworkChangeManager::~NetworkChangeManager() {
+ net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
+}
+
+void NetworkChangeManager::AddRequest(
+ network::mojom::NetworkChangeManagerRequest request) {
+ bindings_.AddBinding(this, std::move(request));
+}
+
+void NetworkChangeManager::RequestNotifications(
+ network::mojom::NetworkChangeManagerClientPtr client_ptr) {
+ client_ptr.set_connection_error_handler(
+ base::Bind(&NetworkChangeManager::NotificationPipeBroken,
+ // base::Unretained is safe as destruction of the
+ // NetworkChangeManager will also destroy the
+ // |clients_| list (which this object will be
+ // inserted into, below), which will destroy the
+ // client_ptr, rendering this callback moot.
+ base::Unretained(this), base::Unretained(client_ptr.get())));
+ client_ptr->OnInitialConnectionType(connection_type_);
+ clients_.push_back(std::move(client_ptr));
+}
+
+size_t NetworkChangeManager::GetNumClientsForTesting() const {
+ return clients_.size();
+}
+
+void NetworkChangeManager::NotificationPipeBroken(
+ network::mojom::NetworkChangeManagerClient* client) {
+ clients_.erase(std::find_if(
+ clients_.begin(), clients_.end(),
+ [client](network::mojom::NetworkChangeManagerClientPtr& ptr) {
+ return ptr.get() == client;
+ }));
+}
+
+void NetworkChangeManager::OnNetworkChanged(
+ net::NetworkChangeNotifier::ConnectionType type) {
+ connection_type_ = network::mojom::ConnectionType(type);
+ for (const auto& client : clients_) {
+ client->OnNetworkChanged(connection_type_);
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/network/network_change_manager.h b/chromium/content/network/network_change_manager.h
new file mode 100644
index 00000000000..25aa4998fc9
--- /dev/null
+++ b/chromium/content/network/network_change_manager.h
@@ -0,0 +1,65 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_NETWORK_NETWORK_CHANGE_MANAGER_H_
+#define CONTENT_NETWORK_NETWORK_CHANGE_MANAGER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "build/build_config.h"
+#include "content/common/content_export.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "net/base/network_change_notifier.h"
+#include "services/network/public/interfaces/network_change_manager.mojom.h"
+
+namespace content {
+
+// Implementation of mojom::NetworkChangeManager. All accesses to this class are
+// done through mojo on the main thread. This registers itself to receive
+// broadcasts from net::NetworkChangeNotifier and rebroadcasts the notifications
+// to network::mojom::NetworkChangeManagerClients through mojo pipes.
+class CONTENT_EXPORT NetworkChangeManager
+ : public network::mojom::NetworkChangeManager,
+ public net::NetworkChangeNotifier::NetworkChangeObserver {
+ public:
+ // If |network_change_notifier| is not null, |this| will take ownership of it.
+ // Otherwise, the global net::NetworkChangeNotifier will be used.
+ explicit NetworkChangeManager(
+ std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier);
+
+ ~NetworkChangeManager() override;
+
+ // Binds a NetworkChangeManager request to this object. Mojo messages
+ // coming through the associated pipe will be served by this object.
+ void AddRequest(network::mojom::NetworkChangeManagerRequest request);
+
+ // mojom::NetworkChangeManager implementation:
+ void RequestNotifications(
+ network::mojom::NetworkChangeManagerClientPtr client_ptr) override;
+
+ size_t GetNumClientsForTesting() const;
+
+ private:
+ // Handles connection errors on notification pipes.
+ void NotificationPipeBroken(
+ network::mojom::NetworkChangeManagerClient* client);
+
+ // net::NetworkChangeNotifier::NetworkChangeObserver implementation:
+ void OnNetworkChanged(
+ net::NetworkChangeNotifier::ConnectionType type) override;
+
+ std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
+ mojo::BindingSet<network::mojom::NetworkChangeManager> bindings_;
+ std::vector<network::mojom::NetworkChangeManagerClientPtr> clients_;
+ network::mojom::ConnectionType connection_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkChangeManager);
+};
+
+} // namespace content
+
+#endif // CONTENT_NETWORK_NETWORK_CHANGE_MANAGER_H_
diff --git a/chromium/content/network/network_change_manager_unittest.cc b/chromium/content/network/network_change_manager_unittest.cc
new file mode 100644
index 00000000000..3d2c7cdb745
--- /dev/null
+++ b/chromium/content/network/network_change_manager_unittest.cc
@@ -0,0 +1,226 @@
+// Copyright 2017 The Chromium Authors. 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/network/network_change_manager.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
+#include "net/base/network_change_notifier.h"
+#include "services/network/public/interfaces/network_change_manager.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+// Type of notification expected in test.
+enum NotificationType {
+ // Default value.
+ NONE,
+ // OnInitialConnectionType() notification.
+ INITIAL,
+ // OnNetworkChanged() notification.
+ NETWORK_CHANGED,
+};
+
+class TestNetworkChangeManagerClient
+ : public network::mojom::NetworkChangeManagerClient {
+ public:
+ explicit TestNetworkChangeManagerClient(
+ content::NetworkChangeManager* network_change_manager)
+ : num_network_changed_(0),
+ run_loop_(std::make_unique<base::RunLoop>()),
+ notification_type_to_wait_(NONE),
+ connection_type_(network::mojom::ConnectionType::CONNECTION_UNKNOWN),
+ binding_(this) {
+ network::mojom::NetworkChangeManagerPtr manager_ptr;
+ network::mojom::NetworkChangeManagerRequest request(
+ mojo::MakeRequest(&manager_ptr));
+ network_change_manager->AddRequest(std::move(request));
+
+ network::mojom::NetworkChangeManagerClientPtr client_ptr;
+ network::mojom::NetworkChangeManagerClientRequest client_request(
+ mojo::MakeRequest(&client_ptr));
+ binding_.Bind(std::move(client_request));
+ manager_ptr->RequestNotifications(std::move(client_ptr));
+ }
+
+ ~TestNetworkChangeManagerClient() override {}
+
+ // NetworkChangeManagerClient implementation:
+ void OnInitialConnectionType(network::mojom::ConnectionType type) override {
+ connection_type_ = type;
+ if (notification_type_to_wait_ == INITIAL)
+ run_loop_->Quit();
+ }
+
+ void OnNetworkChanged(network::mojom::ConnectionType type) override {
+ num_network_changed_++;
+ connection_type_ = type;
+ if (notification_type_to_wait_ == NETWORK_CHANGED)
+ run_loop_->Quit();
+ }
+
+ // Returns the number of OnNetworkChanged() notifications.
+ size_t num_network_changed() const { return num_network_changed_; }
+
+ void WaitForNotification(NotificationType notification_type) {
+ notification_type_to_wait_ = notification_type;
+ run_loop_->Run();
+ run_loop_.reset(new base::RunLoop());
+ }
+
+ network::mojom::ConnectionType connection_type() const {
+ return connection_type_;
+ }
+
+ private:
+ size_t num_network_changed_;
+ std::unique_ptr<base::RunLoop> run_loop_;
+ NotificationType notification_type_to_wait_;
+ network::mojom::ConnectionType connection_type_;
+ mojo::Binding<network::mojom::NetworkChangeManagerClient> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestNetworkChangeManagerClient);
+};
+
+} // namespace
+
+class NetworkChangeManagerTest : public testing::Test {
+ public:
+ NetworkChangeManagerTest()
+ : network_change_manager_(new NetworkChangeManager(
+ base::WrapUnique(net::NetworkChangeNotifier::CreateMock()))) {
+ network_change_manager_client_ =
+ std::make_unique<TestNetworkChangeManagerClient>(
+ network_change_manager_.get());
+ }
+
+ ~NetworkChangeManagerTest() override {}
+
+ TestNetworkChangeManagerClient* network_change_manager_client() {
+ return network_change_manager_client_.get();
+ }
+
+ NetworkChangeManager* network_change_manager() const {
+ return network_change_manager_.get();
+ }
+
+ void SimulateNetworkChange(net::NetworkChangeNotifier::ConnectionType type) {
+ net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(type);
+ }
+
+ private:
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ std::unique_ptr<NetworkChangeManager> network_change_manager_;
+ std::unique_ptr<TestNetworkChangeManagerClient>
+ network_change_manager_client_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkChangeManagerTest);
+};
+
+TEST_F(NetworkChangeManagerTest, ClientNotified) {
+ // Simulate a new network change.
+ SimulateNetworkChange(net::NetworkChangeNotifier::CONNECTION_3G);
+ network_change_manager_client()->WaitForNotification(NETWORK_CHANGED);
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_3G,
+ network_change_manager_client()->connection_type());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, network_change_manager_client()->num_network_changed());
+}
+
+TEST_F(NetworkChangeManagerTest, OneClientPipeBroken) {
+ auto network_change_manager_client2 =
+ std::make_unique<TestNetworkChangeManagerClient>(
+ network_change_manager());
+
+ // Simulate a network change.
+ SimulateNetworkChange(net::NetworkChangeNotifier::CONNECTION_WIFI);
+
+ network_change_manager_client()->WaitForNotification(NETWORK_CHANGED);
+ network_change_manager_client2->WaitForNotification(NETWORK_CHANGED);
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_WIFI,
+ network_change_manager_client2->connection_type());
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(2u, network_change_manager()->GetNumClientsForTesting());
+
+ EXPECT_EQ(1u, network_change_manager_client()->num_network_changed());
+ EXPECT_EQ(1u, network_change_manager_client2->num_network_changed());
+ network_change_manager_client2.reset();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, network_change_manager()->GetNumClientsForTesting());
+
+ // Simulate a second network change, and the remaining client should be
+ // notified.
+ SimulateNetworkChange(net::NetworkChangeNotifier::CONNECTION_2G);
+
+ network_change_manager_client()->WaitForNotification(NETWORK_CHANGED);
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_2G,
+ network_change_manager_client()->connection_type());
+ EXPECT_EQ(2u, network_change_manager_client()->num_network_changed());
+}
+
+TEST_F(NetworkChangeManagerTest, NewClientReceivesCurrentType) {
+ // Simulate a network change.
+ SimulateNetworkChange(net::NetworkChangeNotifier::CONNECTION_BLUETOOTH);
+
+ network_change_manager_client()->WaitForNotification(NETWORK_CHANGED);
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_BLUETOOTH,
+ network_change_manager_client()->connection_type());
+ base::RunLoop().RunUntilIdle();
+
+ // Register a new client after the network change and it should receive the
+ // up-to-date connection type.
+ TestNetworkChangeManagerClient network_change_manager_client2(
+ network_change_manager());
+ network_change_manager_client2.WaitForNotification(INITIAL);
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_BLUETOOTH,
+ network_change_manager_client2.connection_type());
+}
+
+TEST(NetworkChangeConnectionTypeTest, ConnectionTypeEnumMatch) {
+ for (int typeInt = net::NetworkChangeNotifier::CONNECTION_UNKNOWN;
+ typeInt != net::NetworkChangeNotifier::CONNECTION_LAST; typeInt++) {
+ network::mojom::ConnectionType mojoType =
+ network::mojom::ConnectionType(typeInt);
+ switch (typeInt) {
+ case net::NetworkChangeNotifier::CONNECTION_UNKNOWN:
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_UNKNOWN, mojoType);
+ break;
+ case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_ETHERNET,
+ mojoType);
+ break;
+ case net::NetworkChangeNotifier::CONNECTION_WIFI:
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_WIFI, mojoType);
+ break;
+ case net::NetworkChangeNotifier::CONNECTION_2G:
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_2G, mojoType);
+ break;
+ case net::NetworkChangeNotifier::CONNECTION_3G:
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_3G, mojoType);
+ break;
+ case net::NetworkChangeNotifier::CONNECTION_4G:
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_4G, mojoType);
+ break;
+ case net::NetworkChangeNotifier::CONNECTION_NONE:
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_NONE, mojoType);
+ break;
+ case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH:
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_BLUETOOTH,
+ mojoType);
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_LAST, mojoType);
+ break;
+ }
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/network/network_context.cc b/chromium/content/network/network_context.cc
index 7974465fc96..f99d5f4f5f7 100644
--- a/chromium/content/network/network_context.cc
+++ b/chromium/content/network/network_context.cc
@@ -23,11 +23,15 @@
#include "content/network/cache_url_loader.h"
#include "content/network/http_server_properties_pref_delegate.h"
#include "content/network/network_service_impl.h"
-#include "content/network/network_service_url_loader_factory_impl.h"
-#include "content/network/restricted_cookie_manager_impl.h"
-#include "content/network/url_loader_impl.h"
+#include "content/network/network_service_url_loader_factory.h"
+#include "content/network/restricted_cookie_manager.h"
+#include "content/network/throttling/network_conditions.h"
+#include "content/network/throttling/throttling_controller.h"
+#include "content/network/throttling/throttling_network_transaction_factory.h"
+#include "content/network/url_loader.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
+#include "content/public/network/ignore_errors_cert_verifier.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/dns/host_resolver.h"
#include "net/dns/mapped_host_resolver.h"
@@ -51,7 +55,7 @@ NetworkContext::NetworkContext(NetworkServiceImpl* network_service,
owned_url_request_context_ = MakeURLRequestContext(params_.get());
url_request_context_ = owned_url_request_context_.get();
cookie_manager_ =
- base::MakeUnique<CookieManagerImpl>(url_request_context_->cookie_store());
+ std::make_unique<CookieManager>(url_request_context_->cookie_store());
network_service_->RegisterNetworkContext(this);
binding_.set_connection_error_handler(base::BindOnce(
&NetworkContext::OnConnectionError, base::Unretained(this)));
@@ -71,27 +75,27 @@ NetworkContext::NetworkContext(
if (params_ && params_->http_cache_path) {
// Only sample 0.1% of NetworkContexts that get created.
if (base::RandUint64() % 1000 == 0)
- disk_checker_ = base::MakeUnique<DiskChecker>(*params_->http_cache_path);
+ disk_checker_ = std::make_unique<DiskChecker>(*params_->http_cache_path);
}
network_service_->RegisterNetworkContext(this);
ApplyContextParamsToBuilder(builder.get(), params_.get());
owned_url_request_context_ = builder->Build();
url_request_context_ = owned_url_request_context_.get();
cookie_manager_ =
- base::MakeUnique<CookieManagerImpl>(url_request_context_->cookie_store());
+ std::make_unique<CookieManager>(url_request_context_->cookie_store());
}
NetworkContext::NetworkContext(mojom::NetworkContextRequest request,
net::URLRequestContext* url_request_context)
: network_service_(nullptr),
binding_(this, std::move(request)),
- cookie_manager_(base::MakeUnique<CookieManagerImpl>(
+ cookie_manager_(std::make_unique<CookieManager>(
url_request_context->cookie_store())) {
url_request_context_ = url_request_context;
}
NetworkContext::~NetworkContext() {
- // Call each URLLoaderImpl and ask it to release its net::URLRequest, as the
+ // Call each URLLoader and ask it to release its net::URLRequest, as the
// corresponding net::URLRequestContext is going away with this
// NetworkContext. The loaders can be deregistering themselves in Cleanup(),
// so have to be careful.
@@ -107,12 +111,12 @@ std::unique_ptr<NetworkContext> NetworkContext::CreateForTesting() {
return base::WrapUnique(new NetworkContext);
}
-void NetworkContext::RegisterURLLoader(URLLoaderImpl* url_loader) {
+void NetworkContext::RegisterURLLoader(URLLoader* url_loader) {
DCHECK(url_loaders_.count(url_loader) == 0);
url_loaders_.insert(url_loader);
}
-void NetworkContext::DeregisterURLLoader(URLLoaderImpl* url_loader) {
+void NetworkContext::DeregisterURLLoader(URLLoader* url_loader) {
size_t removed_count = url_loaders_.erase(url_loader);
DCHECK(removed_count);
}
@@ -121,7 +125,7 @@ void NetworkContext::CreateURLLoaderFactory(
mojom::URLLoaderFactoryRequest request,
uint32_t process_id) {
loader_factory_bindings_.AddBinding(
- base::MakeUnique<NetworkServiceURLLoaderFactoryImpl>(this, process_id),
+ std::make_unique<NetworkServiceURLLoaderFactory>(this, process_id),
std::move(request));
}
@@ -139,10 +143,10 @@ void NetworkContext::GetRestrictedCookieManager(
network::mojom::RestrictedCookieManagerRequest request,
int32_t render_process_id,
int32_t render_frame_id) {
- // TODO(crbug.com/729800): RestrictedCookieManagerImpl should own its bindings
- // and NetworkContext should own the RestrictedCookieManagerImpl
+ // TODO(crbug.com/729800): RestrictedCookieManager should own its bindings
+ // and NetworkContext should own the RestrictedCookieManager
// instances.
- mojo::MakeStrongBinding(base::MakeUnique<RestrictedCookieManagerImpl>(
+ mojo::MakeStrongBinding(std::make_unique<RestrictedCookieManager>(
url_request_context_->cookie_store(),
render_process_id, render_frame_id),
std::move(request));
@@ -220,12 +224,18 @@ std::unique_ptr<net::URLRequestContext> NetworkContext::MakeURLRequestContext(
config.proxy_rules().ParseFromString(
command_line->GetSwitchValueASCII(switches::kProxyServer));
std::unique_ptr<net::ProxyConfigService> fixed_config_service =
- base::MakeUnique<net::ProxyConfigServiceFixed>(config);
+ std::make_unique<net::ProxyConfigServiceFixed>(config);
builder.set_proxy_config_service(std::move(fixed_config_service));
} else {
builder.set_proxy_service(net::ProxyService::CreateDirect());
}
+ std::unique_ptr<net::CertVerifier> cert_verifier =
+ net::CertVerifier::CreateDefault();
+ builder.SetCertVerifier(
+ content::IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
+ *command_line, nullptr, std::move(cert_verifier)));
+
ApplyContextParamsToBuilder(&builder, network_context_params);
return builder.Build();
@@ -235,7 +245,7 @@ void NetworkContext::ApplyContextParamsToBuilder(
net::URLRequestContextBuilder* builder,
mojom::NetworkContextParams* network_context_params) {
// |network_service_| may be nullptr in tests.
- if (!builder->net_log() && network_service_)
+ if (network_service_)
builder->set_net_log(network_service_->net_log());
builder->set_enable_brotli(network_context_params->enable_brotli);
@@ -276,7 +286,7 @@ void NetworkContext::ApplyContextParamsToBuilder(
std::make_unique<net::HttpServerPropertiesManager>(
std::make_unique<HttpServerPropertiesPrefDelegate>(
pref_service_.get()),
- builder->net_log()));
+ network_service_->net_log()));
}
builder->set_data_enabled(network_context_params->enable_data_url_support);
@@ -304,6 +314,11 @@ void NetworkContext::ApplyContextParamsToBuilder(
network_context_params->http_09_on_non_default_ports_enabled;
builder->set_http_network_session_params(session_params);
+ builder->SetCreateHttpTransactionFactoryCallback(
+ base::BindOnce([](net::HttpNetworkSession* session)
+ -> std::unique_ptr<net::HttpTransactionFactory> {
+ return std::make_unique<ThrottlingNetworkTransactionFactory>(session);
+ }));
}
void NetworkContext::ClearNetworkingHistorySince(
@@ -321,4 +336,17 @@ void NetworkContext::ClearNetworkingHistorySince(
std::move(completion_callback).Run();
}
+void NetworkContext::SetNetworkConditions(
+ const std::string& profile_id,
+ mojom::NetworkConditionsPtr conditions) {
+ std::unique_ptr<NetworkConditions> network_conditions;
+ if (conditions) {
+ network_conditions.reset(new NetworkConditions(
+ conditions->offline, conditions->latency.InMillisecondsF(),
+ conditions->download_throughput, conditions->upload_throughput));
+ }
+ ThrottlingController::SetConditions(profile_id,
+ std::move(network_conditions));
+}
+
} // namespace content
diff --git a/chromium/content/network/network_context.h b/chromium/content/network/network_context.h
index 4e362d21a68..f152de9de44 100644
--- a/chromium/content/network/network_context.h
+++ b/chromium/content/network/network_context.h
@@ -15,7 +15,7 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "content/common/content_export.h"
-#include "content/network/cookie_manager_impl.h"
+#include "content/network/cookie_manager.h"
#include "content/public/common/network_service.mojom.h"
#include "content/public/common/url_loader_factory.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -31,7 +31,7 @@ class HttpServerPropertiesManager;
namespace content {
class NetworkServiceImpl;
-class URLLoaderImpl;
+class URLLoader;
// A NetworkContext creates and manages access to a URLRequestContext.
//
@@ -76,8 +76,8 @@ class CONTENT_EXPORT NetworkContext : public mojom::NetworkContext {
// These are called by individual url loaders as they are being created and
// destroyed.
- void RegisterURLLoader(URLLoaderImpl* url_loader);
- void DeregisterURLLoader(URLLoaderImpl* url_loader);
+ void RegisterURLLoader(URLLoader* url_loader);
+ void DeregisterURLLoader(URLLoader* url_loader);
// mojom::NetworkContext implementation:
void CreateURLLoaderFactory(mojom::URLLoaderFactoryRequest request,
@@ -100,6 +100,9 @@ class CONTENT_EXPORT NetworkContext : public mojom::NetworkContext {
// Disables use of QUIC by the NetworkContext.
void DisableQuic();
+ void SetNetworkConditions(const std::string& profile_id,
+ mojom::NetworkConditionsPtr conditions) override;
+
private:
NetworkContext();
@@ -126,20 +129,20 @@ class CONTENT_EXPORT NetworkContext : public mojom::NetworkContext {
net::URLRequestContext* url_request_context_ = nullptr;
// Put it below |url_request_context_| so that it outlives all the
- // NetworkServiceURLLoaderFactoryImpl instances.
+ // NetworkServiceURLLoaderFactory instances.
mojo::StrongBindingSet<mojom::URLLoaderFactory> loader_factory_bindings_;
- // URLLoaderImpls register themselves with the NetworkContext so that they can
+ // URLLoaders register themselves with the NetworkContext so that they can
// be cleaned up when the NetworkContext goes away. This is needed as
- // net::URLRequests held by URLLoaderImpls have to be gone when
+ // net::URLRequests held by URLLoaders have to be gone when
// net::URLRequestContext (held by NetworkContext) is destroyed.
- std::set<URLLoaderImpl*> url_loaders_;
+ std::set<URLLoader*> url_loaders_;
mojom::NetworkContextParamsPtr params_;
mojo::Binding<mojom::NetworkContext> binding_;
- std::unique_ptr<CookieManagerImpl> cookie_manager_;
+ std::unique_ptr<CookieManager> cookie_manager_;
// Temporary class to help diagnose the impact of https://crbug.com/711579.
// Every 24-hours, measures the size of the network cache and emits an UMA
diff --git a/chromium/content/network/network_context_unittest.cc b/chromium/content/network/network_context_unittest.cc
index a8c15c5fad1..d69e1d05a19 100644
--- a/chromium/content/network/network_context_unittest.cc
+++ b/chromium/content/network/network_context_unittest.cc
@@ -59,7 +59,7 @@ class NetworkContextTest : public testing::Test {
std::unique_ptr<NetworkContext> CreateContextWithParams(
mojom::NetworkContextParamsPtr context_params) {
- return base::MakeUnique<NetworkContext>(
+ return std::make_unique<NetworkContext>(
network_service_.get(), mojo::MakeRequest(&network_context_ptr_),
std::move(context_params));
}
diff --git a/chromium/content/network/network_sandbox_hook_linux.cc b/chromium/content/network/network_sandbox_hook_linux.cc
new file mode 100644
index 00000000000..d9d9371b87d
--- /dev/null
+++ b/chromium/content/network/network_sandbox_hook_linux.cc
@@ -0,0 +1,28 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/network/network_sandbox_hook_linux.h"
+
+#include "base/rand_util.h"
+#include "base/sys_info.h"
+
+using sandbox::syscall_broker::BrokerFilePermission;
+
+namespace content {
+
+bool NetworkPreSandboxHook(service_manager::BPFBasePolicy* policy,
+ service_manager::SandboxLinux::Options options) {
+ // TODO(tsepez): FIX THIS.
+ std::vector<BrokerFilePermission> file_permissions;
+ file_permissions.push_back(
+ BrokerFilePermission::ReadWriteCreateRecursive("/"));
+
+ service_manager::SandboxLinux::GetInstance()->StartBrokerProcess(
+ policy, std::move(file_permissions),
+ service_manager::SandboxLinux::PreSandboxHook(), options);
+
+ return true;
+}
+
+} // namespace content
diff --git a/chromium/content/network/network_sandbox_hook_linux.h b/chromium/content/network/network_sandbox_hook_linux.h
new file mode 100644
index 00000000000..9c3bcc7c8d3
--- /dev/null
+++ b/chromium/content/network/network_sandbox_hook_linux.h
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_NETWORK_NETWORK_SANDBOX_HOOK_LINUX_H_
+#define CONTENT_NETWORK_NETWORK_SANDBOX_HOOK_LINUX_H_
+
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
+
+namespace content {
+
+bool NetworkPreSandboxHook(service_manager::BPFBasePolicy* policy,
+ service_manager::SandboxLinux::Options options);
+
+} // namespace content
+
+#endif // CONTENT_NETWORK_NETWORK_SANDBOX_HOOK_LINUX_H_
diff --git a/chromium/content/network/network_service_impl.cc b/chromium/content/network/network_service_impl.cc
index 8dba0631306..f56582b7f7c 100644
--- a/chromium/content/network/network_service_impl.cc
+++ b/chromium/content/network/network_service_impl.cc
@@ -4,6 +4,8 @@
#include "content/network/network_service_impl.h"
+#include <utility>
+
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
@@ -12,14 +14,46 @@
#include "content/network/network_context.h"
#include "content/public/common/content_switches.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "net/base/logging_network_change_observer.h"
+#include "net/base/network_change_notifier.h"
#include "net/log/file_net_log_observer.h"
+#include "net/log/net_log.h"
#include "net/log/net_log_util.h"
#include "net/url_request/url_request_context_builder.h"
namespace content {
-std::unique_ptr<NetworkService> NetworkService::Create() {
- return base::MakeUnique<NetworkServiceImpl>(nullptr);
+namespace {
+
+std::unique_ptr<net::NetworkChangeNotifier>
+CreateNetworkChangeNotifierIfNeeded() {
+ // There is a global singleton net::NetworkChangeNotifier if NetworkService
+ // is running inside of the browser process.
+ if (!net::NetworkChangeNotifier::HasNetworkChangeNotifier()) {
+#if defined(OS_ANDROID)
+ // On Android, NetworkChangeNotifier objects are always set up in process
+ // before NetworkService is run.
+ return nullptr;
+#elif defined(OS_CHROMEOS) || defined(OS_IOS) || defined(OS_FUCHSIA)
+ // ChromeOS has its own implementation of NetworkChangeNotifier that lives
+ // outside of //net. iOS doesn't embed //content. Fuchsia doesn't have an
+ // implementation yet.
+ // TODO(xunjieli): Figure out what to do for these 3 platforms.
+ NOTIMPLEMENTED();
+ return nullptr;
+#endif
+ return base::WrapUnique(net::NetworkChangeNotifier::Create());
+ }
+ return nullptr;
+}
+
+} // namespace
+
+std::unique_ptr<NetworkService> NetworkService::Create(
+ mojom::NetworkServiceRequest request,
+ net::NetLog* net_log) {
+ return std::make_unique<NetworkServiceImpl>(nullptr, std::move(request),
+ net_log);
}
class NetworkServiceImpl::MojoNetLog : public net::NetLog {
@@ -55,21 +89,41 @@ class NetworkServiceImpl::MojoNetLog : public net::NetLog {
};
NetworkServiceImpl::NetworkServiceImpl(
- std::unique_ptr<service_manager::BinderRegistry> registry)
- : net_log_(new MojoNetLog), registry_(std::move(registry)), binding_(this) {
+ std::unique_ptr<service_manager::BinderRegistry> registry,
+ mojom::NetworkServiceRequest request,
+ net::NetLog* net_log)
+ : registry_(std::move(registry)), binding_(this) {
// |registry_| is nullptr when an in-process NetworkService is
// created directly. The latter is done in concert with using
- // CreateNetworkContextWithBuilder to ease the transition to using the network
- // service.
+ // CreateNetworkContextWithBuilder to ease the transition to using the
+ // network service.
if (registry_) {
+ DCHECK(!request.is_pending());
registry_->AddInterface<mojom::NetworkService>(
base::Bind(&NetworkServiceImpl::Create, base::Unretained(this)));
+ } else {
+ Create(std::move(request));
+ }
- // Note: The command line switches are only checked when running out of
- // process, since in in-process mode other code may already be writing to
- // the destination log file.
- net_log_->ProcessCommandLine(*base::CommandLine::ForCurrentProcess());
+ network_change_manager_ = std::make_unique<NetworkChangeManager>(
+ CreateNetworkChangeNotifierIfNeeded());
+
+ if (net_log) {
+ net_log_ = net_log;
+ } else {
+ owned_net_log_ = std::make_unique<MojoNetLog>();
+ // Note: The command line switches are only checked when not using the
+ // embedder's NetLog, as it may already be writing to the destination log
+ // file.
+ owned_net_log_->ProcessCommandLine(*base::CommandLine::ForCurrentProcess());
+ net_log_ = owned_net_log_.get();
}
+
+ // Add an observer that will emit network change events to the ChromeNetLog.
+ // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
+ // logging the network change before other IO thread consumers respond to it.
+ network_change_observer_.reset(
+ new net::LoggingNetworkChangeObserver(net_log_));
}
NetworkServiceImpl::~NetworkServiceImpl() {
@@ -87,7 +141,7 @@ NetworkServiceImpl::CreateNetworkContextWithBuilder(
std::unique_ptr<net::URLRequestContextBuilder> builder,
net::URLRequestContext** url_request_context) {
std::unique_ptr<NetworkContext> network_context =
- base::MakeUnique<NetworkContext>(this, std::move(request),
+ std::make_unique<NetworkContext>(this, std::move(request),
std::move(params), std::move(builder));
*url_request_context = network_context->url_request_context();
return network_context;
@@ -95,7 +149,7 @@ NetworkServiceImpl::CreateNetworkContextWithBuilder(
std::unique_ptr<NetworkServiceImpl> NetworkServiceImpl::CreateForTesting() {
return base::WrapUnique(new NetworkServiceImpl(
- base::MakeUnique<service_manager::BinderRegistry>()));
+ std::make_unique<service_manager::BinderRegistry>()));
}
void NetworkServiceImpl::RegisterNetworkContext(
@@ -110,6 +164,10 @@ void NetworkServiceImpl::DeregisterNetworkContext(
network_contexts_.erase(network_context);
}
+void NetworkServiceImpl::SetClient(mojom::NetworkServiceClientPtr client) {
+ client_ = std::move(client);
+}
+
void NetworkServiceImpl::CreateNetworkContext(
mojom::NetworkContextRequest request,
mojom::NetworkContextParamsPtr params) {
@@ -143,7 +201,12 @@ bool NetworkServiceImpl::HasRawHeadersAccess(uint32_t process_id) const {
}
net::NetLog* NetworkServiceImpl::net_log() const {
- return net_log_.get();
+ return net_log_;
+}
+
+void NetworkServiceImpl::GetNetworkChangeManager(
+ network::mojom::NetworkChangeManagerRequest request) {
+ network_change_manager_->AddRequest(std::move(request));
}
void NetworkServiceImpl::OnBindInterface(
diff --git a/chromium/content/network/network_service_impl.h b/chromium/content/network/network_service_impl.h
index 1465457a75c..ea7aac6c680 100644
--- a/chromium/content/network/network_service_impl.h
+++ b/chromium/content/network/network_service_impl.h
@@ -6,16 +6,22 @@
#define CONTENT_NETWORK_NETWORK_SERVICE_IMPL_H_
#include <memory>
+#include <set>
+#include <string>
#include "base/macros.h"
#include "content/common/content_export.h"
+#include "content/network/network_change_manager.h"
#include "content/public/common/network_service.mojom.h"
#include "content/public/network/network_service.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "services/network/public/interfaces/network_change_manager.mojom.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/service.h"
namespace net {
+class NetLog;
+class LoggingNetworkChangeObserver;
class URLRequestContext;
class URLRequestContextBuilder;
} // namespace net
@@ -27,8 +33,14 @@ class NetworkContext;
class CONTENT_EXPORT NetworkServiceImpl : public service_manager::Service,
public NetworkService {
public:
- explicit NetworkServiceImpl(
- std::unique_ptr<service_manager::BinderRegistry> registry);
+ // |net_log| is an optional shared NetLog, which will be used instead of the
+ // service's own NetLog. It must outlive the NetworkService.
+ //
+ // TODO(https://crbug.com/767450): Once the NetworkService can always create
+ // its own NetLog in production, remove the |net_log| argument.
+ NetworkServiceImpl(std::unique_ptr<service_manager::BinderRegistry> registry,
+ mojom::NetworkServiceRequest request = nullptr,
+ net::NetLog* net_log = nullptr);
~NetworkServiceImpl() override;
@@ -46,14 +58,18 @@ class CONTENT_EXPORT NetworkServiceImpl : public service_manager::Service,
void DeregisterNetworkContext(NetworkContext* network_context);
// mojom::NetworkService implementation:
+ void SetClient(mojom::NetworkServiceClientPtr client) override;
void CreateNetworkContext(mojom::NetworkContextRequest request,
mojom::NetworkContextParamsPtr params) override;
void DisableQuic() override;
void SetRawHeadersAccess(uint32_t process_id, bool allow) override;
+ void GetNetworkChangeManager(
+ network::mojom::NetworkChangeManagerRequest request) override;
bool quic_disabled() const { return quic_disabled_; }
bool HasRawHeadersAccess(uint32_t process_id) const;
+ mojom::NetworkServiceClient* client() { return client_.get(); }
net::NetLog* net_log() const;
private:
@@ -68,7 +84,19 @@ class CONTENT_EXPORT NetworkServiceImpl : public service_manager::Service,
void Create(mojom::NetworkServiceRequest request);
- std::unique_ptr<MojoNetLog> net_log_;
+ std::unique_ptr<MojoNetLog> owned_net_log_;
+ // TODO(https://crbug.com/767450): Remove this, once Chrome no longer creates
+ // its own NetLog.
+ net::NetLog* net_log_;
+
+ mojom::NetworkServiceClientPtr client_;
+
+ // Observer that logs network changes to the NetLog. Must be below the NetLog
+ // and the NetworkChangeNotifier (Once this class creates it), so it's
+ // destroyed before them.
+ std::unique_ptr<net::LoggingNetworkChangeObserver> network_change_observer_;
+
+ std::unique_ptr<NetworkChangeManager> network_change_manager_;
std::unique_ptr<service_manager::BinderRegistry> registry_;
diff --git a/chromium/content/network/network_service_unittest.cc b/chromium/content/network/network_service_unittest.cc
index ce367d63733..1089df9fb30 100644
--- a/chromium/content/network/network_service_unittest.cc
+++ b/chromium/content/network/network_service_unittest.cc
@@ -8,13 +8,16 @@
#include "base/strings/string_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/network/network_context.h"
#include "content/network/network_service_impl.h"
#include "content/public/common/network_service.mojom.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/test/test_url_loader_client.h"
+#include "net/base/mock_network_change_notifier.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "services/network/public/interfaces/network_change_manager.mojom.h"
#include "services/service_manager/public/cpp/service_context.h"
#include "services/service_manager/public/cpp/service_test.h"
#include "services/service_manager/public/interfaces/service_factory.mojom.h"
@@ -106,11 +109,12 @@ class ServiceTestClient : public service_manager::test::ServiceTestClient,
service_factory_bindings_.AddBinding(this, std::move(request));
}
+ std::unique_ptr<service_manager::ServiceContext> service_context_;
+
private:
service_manager::BinderRegistry registry_;
mojo::BindingSet<service_manager::mojom::ServiceFactory>
service_factory_bindings_;
- std::unique_ptr<service_manager::ServiceContext> service_context_;
};
} // namespace
@@ -120,7 +124,6 @@ class NetworkServiceTestWithService
public:
NetworkServiceTestWithService()
: ServiceTest("content_unittests",
- false,
base::test::ScopedTaskEnvironment::MainThreadType::IO) {}
~NetworkServiceTestWithService() override {}
@@ -135,10 +138,6 @@ class NetworkServiceTestWithService
void StartLoadingURL(const ResourceRequest& request, uint32_t process_id) {
client_.reset(new TestURLLoaderClient());
- mojom::NetworkContextParamsPtr context_params =
- mojom::NetworkContextParams::New();
- network_service_->CreateNetworkContext(mojo::MakeRequest(&network_context_),
- std::move(context_params));
mojom::URLLoaderFactoryPtr loader_factory;
network_context_->CreateURLLoaderFactory(mojo::MakeRequest(&loader_factory),
process_id);
@@ -153,10 +152,11 @@ class NetworkServiceTestWithService
TestURLLoaderClient* client() { return client_.get(); }
mojom::URLLoader* loader() { return loader_.get(); }
mojom::NetworkService* service() { return network_service_.get(); }
+ mojom::NetworkContext* context() { return network_context_.get(); }
private:
std::unique_ptr<service_manager::Service> CreateService() override {
- return base::MakeUnique<ServiceTestClient>(this);
+ return std::make_unique<ServiceTestClient>(this);
}
void SetUp() override {
@@ -165,6 +165,10 @@ class NetworkServiceTestWithService
ASSERT_TRUE(test_server_.Start());
service_manager::test::ServiceTest::SetUp();
connector()->BindInterface(mojom::kNetworkServiceName, &network_service_);
+ mojom::NetworkContextParamsPtr context_params =
+ mojom::NetworkContextParams::New();
+ network_service_->CreateNetworkContext(mojo::MakeRequest(&network_context_),
+ std::move(context_params));
}
net::EmbeddedTestServer test_server_;
@@ -268,6 +272,193 @@ TEST_F(NetworkServiceTestWithService, RawRequestAccessControl) {
EXPECT_FALSE(client()->response_head().devtools_info.get());
}
+TEST_F(NetworkServiceTestWithService, SetNetworkConditions) {
+ mojom::NetworkConditionsPtr network_conditions =
+ mojom::NetworkConditions::New();
+ network_conditions->offline = true;
+ context()->SetNetworkConditions("42", std::move(network_conditions));
+
+ ResourceRequest request;
+ request.url = test_server()->GetURL("/nocache.html");
+ request.method = "GET";
+
+ StartLoadingURL(request, 0);
+ client()->RunUntilComplete();
+ EXPECT_EQ(net::OK, client()->completion_status().error_code);
+
+ request.headers.AddHeaderFromString(
+ "X-DevTools-Emulate-Network-Conditions-Client-Id: 42");
+ StartLoadingURL(request, 0);
+ client()->RunUntilComplete();
+ EXPECT_EQ(net::ERR_INTERNET_DISCONNECTED,
+ client()->completion_status().error_code);
+
+ network_conditions = mojom::NetworkConditions::New();
+ network_conditions->offline = false;
+ context()->SetNetworkConditions("42", std::move(network_conditions));
+ StartLoadingURL(request, 0);
+ client()->RunUntilComplete();
+ EXPECT_EQ(net::OK, client()->completion_status().error_code);
+
+ network_conditions = mojom::NetworkConditions::New();
+ network_conditions->offline = true;
+ context()->SetNetworkConditions("42", std::move(network_conditions));
+
+ request.headers.AddHeaderFromString(
+ "X-DevTools-Emulate-Network-Conditions-Client-Id: 42");
+ StartLoadingURL(request, 0);
+ client()->RunUntilComplete();
+ EXPECT_EQ(net::ERR_INTERNET_DISCONNECTED,
+ client()->completion_status().error_code);
+ context()->SetNetworkConditions("42", nullptr);
+ StartLoadingURL(request, 0);
+ client()->RunUntilComplete();
+ EXPECT_EQ(net::OK, client()->completion_status().error_code);
+}
+
+class TestNetworkChangeManagerClient
+ : public network::mojom::NetworkChangeManagerClient {
+ public:
+ explicit TestNetworkChangeManagerClient(
+ mojom::NetworkService* network_service)
+ : connection_type_(network::mojom::ConnectionType::CONNECTION_UNKNOWN),
+ binding_(this) {
+ network::mojom::NetworkChangeManagerPtr manager_ptr;
+ network::mojom::NetworkChangeManagerRequest request(
+ mojo::MakeRequest(&manager_ptr));
+ network_service->GetNetworkChangeManager(std::move(request));
+
+ network::mojom::NetworkChangeManagerClientPtr client_ptr;
+ network::mojom::NetworkChangeManagerClientRequest client_request(
+ mojo::MakeRequest(&client_ptr));
+ binding_.Bind(std::move(client_request));
+ manager_ptr->RequestNotifications(std::move(client_ptr));
+ }
+
+ ~TestNetworkChangeManagerClient() override {}
+
+ // NetworkChangeManagerClient implementation:
+ void OnInitialConnectionType(network::mojom::ConnectionType type) override {
+ if (type == connection_type_)
+ run_loop_.Quit();
+ }
+
+ void OnNetworkChanged(network::mojom::ConnectionType type) override {
+ if (type == connection_type_)
+ run_loop_.Quit();
+ }
+
+ // Waits for the desired |connection_type| notification.
+ void WaitForNotification(network::mojom::ConnectionType type) {
+ connection_type_ = type;
+ run_loop_.Run();
+ }
+
+ private:
+ base::RunLoop run_loop_;
+ network::mojom::ConnectionType connection_type_;
+ mojo::Binding<network::mojom::NetworkChangeManagerClient> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestNetworkChangeManagerClient);
+};
+
+class NetworkChangeTest : public testing::Test {
+ public:
+ NetworkChangeTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO) {
+ service_ = NetworkServiceImpl::CreateForTesting();
+ }
+
+ ~NetworkChangeTest() override {}
+
+ NetworkService* service() const { return service_.get(); }
+
+ private:
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+#if defined(OS_ANDROID)
+ // On Android, NetworkChangeNotifier setup is more involved and needs to
+ // to be split between UI thread and network thread. Use a mock
+ // NetworkChangeNotifier in tests, so the test setup is simpler.
+ net::test::MockNetworkChangeNotifier network_change_notifier_;
+#endif
+ std::unique_ptr<NetworkService> service_;
+};
+
+// network::mojom:NetworkChangeManager currently doesn't support ChromeOS,
+// which has a different code path to set up net::NetworkChangeNotifier.
+#if defined(OS_CHROMEOS) || defined(OS_FUCHSIA)
+#define MAYBE_NetworkChangeManagerRequest DISABLED_NetworkChangeManagerRequest
+#else
+#define MAYBE_NetworkChangeManagerRequest NetworkChangeManagerRequest
+#endif
+TEST_F(NetworkChangeTest, MAYBE_NetworkChangeManagerRequest) {
+ TestNetworkChangeManagerClient manager_client(service());
+ net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
+ net::NetworkChangeNotifier::CONNECTION_3G);
+ manager_client.WaitForNotification(
+ network::mojom::ConnectionType::CONNECTION_3G);
+}
+
+class NetworkServiceNetworkChangeTest
+ : public service_manager::test::ServiceTest {
+ public:
+ NetworkServiceNetworkChangeTest()
+ : ServiceTest("content_unittests",
+ base::test::ScopedTaskEnvironment::MainThreadType::IO) {}
+ ~NetworkServiceNetworkChangeTest() override {}
+
+ mojom::NetworkService* service() { return network_service_.get(); }
+
+ private:
+ // A ServiceTestClient that broadcasts a network change notification in the
+ // network service's process.
+ class ServiceTestClientWithNetworkChange : public ServiceTestClient {
+ public:
+ explicit ServiceTestClientWithNetworkChange(
+ service_manager::test::ServiceTest* test)
+ : ServiceTestClient(test) {}
+ ~ServiceTestClientWithNetworkChange() override {}
+
+ protected:
+ void CreateService(service_manager::mojom::ServiceRequest request,
+ const std::string& name) override {
+ if (name == mojom::kNetworkServiceName) {
+ service_context_.reset(new service_manager::ServiceContext(
+ NetworkServiceImpl::CreateForTesting(), std::move(request)));
+ // Send a broadcast after NetworkService is actually created.
+ // Otherwise, this NotifyObservers is a no-op.
+ net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
+ net::NetworkChangeNotifier::CONNECTION_3G);
+ }
+ }
+ };
+ std::unique_ptr<service_manager::Service> CreateService() override {
+ return std::make_unique<ServiceTestClientWithNetworkChange>(this);
+ }
+
+ void SetUp() override {
+ service_manager::test::ServiceTest::SetUp();
+ connector()->BindInterface(mojom::kNetworkServiceName, &network_service_);
+ }
+
+ mojom::NetworkServicePtr network_service_;
+#if defined(OS_ANDROID)
+ // On Android, NetworkChangeNotifier setup is more involved and needs
+ // to be split between UI thread and network thread. Use a mock
+ // NetworkChangeNotifier in tests, so the test setup is simpler.
+ net::test::MockNetworkChangeNotifier network_change_notifier_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkServiceNetworkChangeTest);
+};
+
+TEST_F(NetworkServiceNetworkChangeTest, MAYBE_NetworkChangeManagerRequest) {
+ TestNetworkChangeManagerClient manager_client(service());
+ manager_client.WaitForNotification(
+ network::mojom::ConnectionType::CONNECTION_3G);
+}
+
} // namespace
} // namespace content
diff --git a/chromium/content/network/network_service_url_loader_factory_impl.cc b/chromium/content/network/network_service_url_loader_factory.cc
index 16d7ff9ca51..561ca6c1ec1 100644
--- a/chromium/content/network/network_service_url_loader_factory_impl.cc
+++ b/chromium/content/network/network_service_url_loader_factory.cc
@@ -2,27 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/network/network_service_url_loader_factory_impl.h"
+#include "content/network/network_service_url_loader_factory.h"
#include "base/logging.h"
#include "content/network/network_context.h"
#include "content/network/network_service_impl.h"
-#include "content/network/url_loader_impl.h"
+#include "content/network/url_loader.h"
#include "content/public/common/resource_request.h"
namespace content {
-NetworkServiceURLLoaderFactoryImpl::NetworkServiceURLLoaderFactoryImpl(
+NetworkServiceURLLoaderFactory::NetworkServiceURLLoaderFactory(
NetworkContext* context,
uint32_t process_id)
: context_(context), process_id_(process_id) {
ignore_result(process_id_);
}
-NetworkServiceURLLoaderFactoryImpl::~NetworkServiceURLLoaderFactoryImpl() =
- default;
+NetworkServiceURLLoaderFactory::~NetworkServiceURLLoaderFactory() = default;
-void NetworkServiceURLLoaderFactoryImpl::CreateLoaderAndStart(
+void NetworkServiceURLLoaderFactory::CreateLoaderAndStart(
mojom::URLLoaderRequest request,
int32_t routing_id,
int32_t request_id,
@@ -37,13 +36,14 @@ void NetworkServiceURLLoaderFactoryImpl::CreateLoaderAndStart(
if (!report_raw_headers)
DLOG(ERROR) << "Denying raw headers request by process " << process_id_;
}
- new URLLoaderImpl(
+ new URLLoader(
context_, std::move(request), options, url_request, report_raw_headers,
std::move(client),
- static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation));
+ static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation),
+ process_id_);
}
-void NetworkServiceURLLoaderFactoryImpl::Clone(
+void NetworkServiceURLLoaderFactory::Clone(
mojom::URLLoaderFactoryRequest request) {
context_->CreateURLLoaderFactory(std::move(request), process_id_);
}
diff --git a/chromium/content/network/network_service_url_loader_factory_impl.h b/chromium/content/network/network_service_url_loader_factory.h
index e0b9316bf2b..24339dd3c48 100644
--- a/chromium/content/network/network_service_url_loader_factory_impl.h
+++ b/chromium/content/network/network_service_url_loader_factory.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_NETWORK_NETWORK_SERVICE_URL_LOADER_FACTORY_IMPL_H_
-#define CONTENT_NETWORK_NETWORK_SERVICE_URL_LOADER_FACTORY_IMPL_H_
+#ifndef CONTENT_NETWORK_NETWORK_SERVICE_URL_LOADER_FACTORY_H_
+#define CONTENT_NETWORK_NETWORK_SERVICE_URL_LOADER_FACTORY_H_
#include "base/macros.h"
#include "content/public/common/url_loader_factory.mojom.h"
@@ -15,13 +15,12 @@ class NetworkContext;
// This class is an implementation of mojom::URLLoaderFactory that creates
// a mojom::URLLoader.
-class NetworkServiceURLLoaderFactoryImpl : public mojom::URLLoaderFactory {
+class NetworkServiceURLLoaderFactory : public mojom::URLLoaderFactory {
public:
// NOTE: |context| must outlive this instance.
- NetworkServiceURLLoaderFactoryImpl(NetworkContext* context,
- uint32_t process_id);
+ NetworkServiceURLLoaderFactory(NetworkContext* context, uint32_t process_id);
- ~NetworkServiceURLLoaderFactoryImpl() override;
+ ~NetworkServiceURLLoaderFactory() override;
// mojom::URLLoaderFactory implementation.
void CreateLoaderAndStart(mojom::URLLoaderRequest request,
@@ -37,11 +36,11 @@ class NetworkServiceURLLoaderFactoryImpl : public mojom::URLLoaderFactory {
private:
// Not owned.
NetworkContext* context_;
- int process_id_;
+ uint32_t process_id_;
- DISALLOW_COPY_AND_ASSIGN(NetworkServiceURLLoaderFactoryImpl);
+ DISALLOW_COPY_AND_ASSIGN(NetworkServiceURLLoaderFactory);
};
} // namespace content
-#endif // CONTENT_NETWORK_NETWORK_SERVICE_URL_LOADER_FACTORY_IMPL_H_
+#endif // CONTENT_NETWORK_NETWORK_SERVICE_URL_LOADER_FACTORY_H_
diff --git a/chromium/content/network/proxy_resolver_factory_mojo.cc b/chromium/content/network/proxy_resolver_factory_mojo.cc
index a9a1169f556..2ed821e2f4a 100644
--- a/chromium/content/network/proxy_resolver_factory_mojo.cc
+++ b/chromium/content/network/proxy_resolver_factory_mojo.cc
@@ -16,7 +16,6 @@
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
-#include "content/public/network/mojo_proxy_resolver_factory.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/load_states.h"
#include "net/base/net_errors.h"
@@ -114,12 +113,10 @@ class ProxyResolverMojo : public net::ProxyResolver {
// Constructs a ProxyResolverMojo that connects to a mojo proxy resolver
// implementation using |resolver_ptr|. The implementation uses
// |host_resolver| as the DNS resolver, using |host_resolver_binding| to
- // communicate with it. When deleted, the closure contained within
- // |on_delete_callback_runner| will be run.
+ // communicate with it.
ProxyResolverMojo(
proxy_resolver::mojom::ProxyResolverPtr resolver_ptr,
net::HostResolver* host_resolver,
- std::unique_ptr<base::ScopedClosureRunner> on_delete_callback_runner,
std::unique_ptr<net::ProxyResolverErrorObserver> error_observer,
net::NetLog* net_log);
~ProxyResolverMojo() override;
@@ -148,8 +145,6 @@ class ProxyResolverMojo : public net::ProxyResolver {
net::NetLog* net_log_;
- std::unique_ptr<base::ScopedClosureRunner> on_delete_callback_runner_;
-
DISALLOW_COPY_AND_ASSIGN(ProxyResolverMojo);
};
@@ -245,14 +240,12 @@ void ProxyResolverMojo::Job::ReportResult(int32_t error,
ProxyResolverMojo::ProxyResolverMojo(
proxy_resolver::mojom::ProxyResolverPtr resolver_ptr,
net::HostResolver* host_resolver,
- std::unique_ptr<base::ScopedClosureRunner> on_delete_callback_runner,
std::unique_ptr<net::ProxyResolverErrorObserver> error_observer,
net::NetLog* net_log)
: mojo_proxy_resolver_ptr_(std::move(resolver_ptr)),
host_resolver_(host_resolver),
error_observer_(std::move(error_observer)),
- net_log_(net_log),
- on_delete_callback_runner_(std::move(on_delete_callback_runner)) {
+ net_log_(net_log) {
mojo_proxy_resolver_ptr_.set_connection_error_handler(base::Bind(
&ProxyResolverMojo::OnConnectionError, base::Unretained(this)));
}
@@ -313,7 +306,7 @@ class ProxyResolverFactoryMojo::Job
error_observer_(std::move(error_observer)) {
proxy_resolver::mojom::ProxyResolverFactoryRequestClientPtr client;
binding_.Bind(mojo::MakeRequest(&client));
- on_delete_callback_runner_ = factory_->mojo_proxy_factory_->CreateResolver(
+ factory_->mojo_proxy_factory_->CreateResolver(
base::UTF16ToUTF8(pac_script->utf16()),
mojo::MakeRequest(&resolver_ptr_), std::move(client));
resolver_ptr_.set_connection_error_handler(
@@ -333,10 +326,8 @@ class ProxyResolverFactoryMojo::Job
if (error == net::OK) {
resolver_->reset(new ProxyResolverMojo(
std::move(resolver_ptr_), factory_->host_resolver_,
- std::move(on_delete_callback_runner_), std::move(error_observer_),
- factory_->net_log_));
+ std::move(error_observer_), factory_->net_log_));
}
- on_delete_callback_runner_.reset();
callback_.Run(error);
}
@@ -346,21 +337,21 @@ class ProxyResolverFactoryMojo::Job
proxy_resolver::mojom::ProxyResolverPtr resolver_ptr_;
mojo::Binding<proxy_resolver::mojom::ProxyResolverFactoryRequestClient>
binding_;
- std::unique_ptr<base::ScopedClosureRunner> on_delete_callback_runner_;
std::unique_ptr<net::ProxyResolverErrorObserver> error_observer_;
};
ProxyResolverFactoryMojo::ProxyResolverFactoryMojo(
- MojoProxyResolverFactory* mojo_proxy_factory,
+ proxy_resolver::mojom::ProxyResolverFactoryPtr mojo_proxy_factory,
net::HostResolver* host_resolver,
const base::Callback<std::unique_ptr<net::ProxyResolverErrorObserver>()>&
error_observer_factory,
net::NetLog* net_log)
: ProxyResolverFactory(true),
- mojo_proxy_factory_(mojo_proxy_factory),
+ mojo_proxy_factory_(std::move(mojo_proxy_factory)),
host_resolver_(host_resolver),
error_observer_factory_(error_observer_factory),
- net_log_(net_log) {}
+ net_log_(net_log),
+ weak_ptr_factory_(this) {}
ProxyResolverFactoryMojo::~ProxyResolverFactoryMojo() = default;
diff --git a/chromium/content/network/proxy_resolver_factory_mojo.h b/chromium/content/network/proxy_resolver_factory_mojo.h
index 576a921b4c7..019a1d41e17 100644
--- a/chromium/content/network/proxy_resolver_factory_mojo.h
+++ b/chromium/content/network/proxy_resolver_factory_mojo.h
@@ -9,10 +9,12 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/completion_callback.h"
#include "net/proxy/proxy_resolver_factory.h"
+#include "services/proxy_resolver/public/interfaces/proxy_resolver.mojom.h"
namespace net {
class HostResolver;
@@ -23,15 +25,13 @@ class ProxyResolverScriptData;
namespace content {
-class MojoProxyResolverFactory;
-
// Implementation of ProxyResolverFactory that connects to a Mojo service to
// create implementations of a Mojo proxy resolver to back a ProxyResolverMojo.
class CONTENT_EXPORT ProxyResolverFactoryMojo
: public net::ProxyResolverFactory {
public:
ProxyResolverFactoryMojo(
- MojoProxyResolverFactory* mojo_proxy_factory,
+ proxy_resolver::mojom::ProxyResolverFactoryPtr mojo_proxy_factory,
net::HostResolver* host_resolver,
const base::Callback<std::unique_ptr<net::ProxyResolverErrorObserver>()>&
error_observer_factory,
@@ -48,12 +48,14 @@ class CONTENT_EXPORT ProxyResolverFactoryMojo
private:
class Job;
- MojoProxyResolverFactory* const mojo_proxy_factory_;
+ proxy_resolver::mojom::ProxyResolverFactoryPtr mojo_proxy_factory_;
net::HostResolver* const host_resolver_;
const base::Callback<std::unique_ptr<net::ProxyResolverErrorObserver>()>
error_observer_factory_;
net::NetLog* const net_log_;
+ base::WeakPtrFactory<ProxyResolverFactoryMojo> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(ProxyResolverFactoryMojo);
};
diff --git a/chromium/content/network/proxy_resolver_factory_mojo_unittest.cc b/chromium/content/network/proxy_resolver_factory_mojo_unittest.cc
index 4a544a54b94..b0fd3102cd2 100644
--- a/chromium/content/network/proxy_resolver_factory_mojo_unittest.cc
+++ b/chromium/content/network/proxy_resolver_factory_mojo_unittest.cc
@@ -14,12 +14,10 @@
#include "base/bind.h"
#include "base/containers/queue.h"
#include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/values.h"
-#include "content/public/network/mojo_proxy_resolver_factory.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/load_states.h"
#include "net/base/net_errors.h"
@@ -271,9 +269,7 @@ void MockMojoProxyResolver::GetProxyForUrl(
break;
}
case GetProxyForUrlAction::WAIT_FOR_CLIENT_DISCONNECT: {
- base::MessageLoop::ScopedNestableTaskAllower nestable_allower(
- base::MessageLoop::current());
- base::RunLoop run_loop;
+ base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
client.set_connection_error_handler(run_loop.QuitClosure());
run_loop.Run();
ASSERT_TRUE(client.encountered_error());
@@ -444,9 +440,7 @@ void MockMojoProxyResolverFactory::CreateResolver(
break;
}
case CreateProxyResolverAction::WAIT_FOR_CLIENT_DISCONNECT: {
- base::MessageLoop::ScopedNestableTaskAllower nestable_allower(
- base::MessageLoop::current());
- base::RunLoop run_loop;
+ base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
client.set_connection_error_handler(run_loop.QuitClosure());
run_loop.Run();
ASSERT_TRUE(client.encountered_error());
@@ -528,14 +522,14 @@ void CheckCapturedNetLogEntries(const std::string& expected_string,
} // namespace
-class ProxyResolverFactoryMojoTest : public testing::Test,
- public MojoProxyResolverFactory {
+class ProxyResolverFactoryMojoTest : public testing::Test {
public:
void SetUp() override {
+ proxy_resolver::mojom::ProxyResolverFactoryPtr factory_ptr;
mock_proxy_resolver_factory_.reset(new MockMojoProxyResolverFactory(
- &mock_proxy_resolver_, mojo::MakeRequest(&factory_ptr_)));
+ &mock_proxy_resolver_, mojo::MakeRequest(&factory_ptr)));
proxy_resolver_factory_mojo_.reset(new ProxyResolverFactoryMojo(
- this, &host_resolver_,
+ std::move(factory_ptr), &host_resolver_,
base::Callback<std::unique_ptr<net::ProxyResolverErrorObserver>()>(),
&net_log_));
}
@@ -544,16 +538,6 @@ class ProxyResolverFactoryMojoTest : public testing::Test,
return std::make_unique<Request>(proxy_resolver_mojo_.get(), url);
}
- std::unique_ptr<base::ScopedClosureRunner> CreateResolver(
- const std::string& pac_script,
- mojo::InterfaceRequest<proxy_resolver::mojom::ProxyResolver> req,
- proxy_resolver::mojom::ProxyResolverFactoryRequestClientPtr client)
- override {
- factory_ptr_->CreateResolver(pac_script, std::move(req), std::move(client));
- return std::make_unique<base::ScopedClosureRunner>(
- on_delete_callback_.closure());
- }
-
net::ProxyInfo ProxyServersFromPacString(const std::string& pac_string) {
net::ProxyInfo proxy_info;
proxy_info.UsePacString(pac_string);
@@ -585,11 +569,9 @@ class ProxyResolverFactoryMojoTest : public testing::Test,
MockHostResolver host_resolver_;
net::TestNetLog net_log_;
std::unique_ptr<MockMojoProxyResolverFactory> mock_proxy_resolver_factory_;
- proxy_resolver::mojom::ProxyResolverFactoryPtr factory_ptr_;
std::unique_ptr<net::ProxyResolverFactory> proxy_resolver_factory_mojo_;
MockMojoProxyResolver mock_proxy_resolver_;
- net::TestClosure on_delete_callback_;
std::unique_ptr<net::ProxyResolver> proxy_resolver_mojo_;
};
@@ -638,7 +620,6 @@ TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Failed) {
callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
EXPECT_TRUE(request);
- on_delete_callback_.WaitForResult();
// A second attempt succeeds.
CreateProxyResolver();
@@ -687,7 +668,6 @@ TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_ResolverDisconnected) {
callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
EXPECT_TRUE(request);
- on_delete_callback_.WaitForResult();
}
TEST_F(ProxyResolverFactoryMojoTest,
@@ -706,7 +686,6 @@ TEST_F(ProxyResolverFactoryMojoTest,
base::Bind(&DeleteResolverFactoryRequestCallback, &request,
callback.callback()),
&request)));
- on_delete_callback_.WaitForResult();
}
TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Cancel) {
@@ -726,7 +705,6 @@ TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Cancel) {
// The Mojo request is still made.
mock_proxy_resolver_factory_->WaitForNextRequest();
- on_delete_callback_.WaitForResult();
}
TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_DnsRequest) {
@@ -880,7 +858,6 @@ TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_DeleteInCallback) {
base::Bind(&ProxyResolverFactoryMojoTest::DeleteProxyResolverCallback,
base::Unretained(this), callback.callback()),
&request, net_log)));
- on_delete_callback_.WaitForResult();
}
TEST_F(ProxyResolverFactoryMojoTest,
@@ -900,7 +877,6 @@ TEST_F(ProxyResolverFactoryMojoTest,
base::Bind(&ProxyResolverFactoryMojoTest::DeleteProxyResolverCallback,
base::Unretained(this), callback.callback()),
&request, net_log)));
- on_delete_callback_.WaitForResult();
}
TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_DnsRequest) {
@@ -922,6 +898,5 @@ TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_DnsRequest) {
TEST_F(ProxyResolverFactoryMojoTest, DeleteResolver) {
CreateProxyResolver();
proxy_resolver_mojo_.reset();
- on_delete_callback_.WaitForResult();
}
} // namespace content
diff --git a/chromium/content/network/proxy_service_mojo.cc b/chromium/content/network/proxy_service_mojo.cc
index 2f9f22bfdf9..49012c3316b 100644
--- a/chromium/content/network/proxy_service_mojo.cc
+++ b/chromium/content/network/proxy_service_mojo.cc
@@ -19,9 +19,9 @@
namespace content {
std::unique_ptr<net::ProxyService> CreateProxyServiceUsingMojoFactory(
- MojoProxyResolverFactory* mojo_proxy_factory,
+ proxy_resolver::mojom::ProxyResolverFactoryPtr mojo_proxy_factory,
std::unique_ptr<net::ProxyConfigService> proxy_config_service,
- net::ProxyScriptFetcher* proxy_script_fetcher,
+ std::unique_ptr<net::ProxyScriptFetcher> proxy_script_fetcher,
std::unique_ptr<net::DhcpProxyScriptFetcher> dhcp_proxy_script_fetcher,
net::HostResolver* host_resolver,
net::NetLog* net_log,
@@ -34,14 +34,14 @@ std::unique_ptr<net::ProxyService> CreateProxyServiceUsingMojoFactory(
std::unique_ptr<net::ProxyService> proxy_service(new net::ProxyService(
std::move(proxy_config_service),
std::make_unique<ProxyResolverFactoryMojo>(
- mojo_proxy_factory, host_resolver,
+ std::move(mojo_proxy_factory), host_resolver,
base::Bind(&net::NetworkDelegateErrorObserver::Create,
network_delegate, base::ThreadTaskRunnerHandle::Get()),
net_log),
net_log));
// Configure fetchers to use for PAC script downloads and auto-detect.
- proxy_service->SetProxyScriptFetchers(proxy_script_fetcher,
+ proxy_service->SetProxyScriptFetchers(std::move(proxy_script_fetcher),
std::move(dhcp_proxy_script_fetcher));
return proxy_service;
diff --git a/chromium/content/network/proxy_service_mojo.h b/chromium/content/network/proxy_service_mojo.h
index 7de266ab719..729ea7183f8 100644
--- a/chromium/content/network/proxy_service_mojo.h
+++ b/chromium/content/network/proxy_service_mojo.h
@@ -9,6 +9,7 @@
#include "content/common/content_export.h"
#include "net/proxy/dhcp_proxy_script_fetcher.h"
+#include "services/proxy_resolver/public/interfaces/proxy_resolver.mojom.h"
namespace net {
class HostResolver;
@@ -21,14 +22,12 @@ class ProxyService;
namespace content {
-class MojoProxyResolverFactory;
-
// Creates a proxy service that uses |mojo_proxy_factory| to create and connect
// to a Mojo proxy resolver service. This proxy service polls
// |proxy_config_service| to notice when the proxy settings change.
//
// |proxy_script_fetcher| specifies the dependency to use for downloading
-// any PAC scripts. The resulting ProxyService will take ownership of it.
+// any PAC scripts.
//
// |dhcp_proxy_script_fetcher| specifies the dependency to use for attempting
// to retrieve the most appropriate PAC script configured in DHCP.
@@ -38,9 +37,9 @@ class MojoProxyResolverFactory;
// lifetime of the ProxyService.
std::unique_ptr<net::ProxyService> CONTENT_EXPORT
CreateProxyServiceUsingMojoFactory(
- MojoProxyResolverFactory* mojo_proxy_factory,
+ proxy_resolver::mojom::ProxyResolverFactoryPtr mojo_proxy_factory,
std::unique_ptr<net::ProxyConfigService> proxy_config_service,
- net::ProxyScriptFetcher* proxy_script_fetcher,
+ std::unique_ptr<net::ProxyScriptFetcher> proxy_script_fetcher,
std::unique_ptr<net::DhcpProxyScriptFetcher> dhcp_proxy_script_fetcher,
net::HostResolver* host_resolver,
net::NetLog* net_log,
diff --git a/chromium/content/network/restricted_cookie_manager_impl.cc b/chromium/content/network/restricted_cookie_manager.cc
index ee9ed6d0fdf..db2e31efd14 100644
--- a/chromium/content/network/restricted_cookie_manager_impl.cc
+++ b/chromium/content/network/restricted_cookie_manager.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/network/restricted_cookie_manager_impl.h"
+#include "content/network/restricted_cookie_manager.h"
#include <memory>
#include <utility>
@@ -11,6 +11,7 @@
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h"
+#include "base/strings/string_util.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "mojo/public/cpp/bindings/message.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
@@ -20,18 +21,17 @@
namespace content {
-RestrictedCookieManagerImpl::RestrictedCookieManagerImpl(
- net::CookieStore* cookie_store,
- int render_process_id,
- int render_frame_id)
+RestrictedCookieManager::RestrictedCookieManager(net::CookieStore* cookie_store,
+ int render_process_id,
+ int render_frame_id)
: cookie_store_(cookie_store),
render_process_id_(render_process_id),
render_frame_id_(render_frame_id),
weak_ptr_factory_(this) {}
-RestrictedCookieManagerImpl::~RestrictedCookieManagerImpl() = default;
+RestrictedCookieManager::~RestrictedCookieManager() = default;
-void RestrictedCookieManagerImpl::GetAllForUrl(
+void RestrictedCookieManager::GetAllForUrl(
const GURL& url,
const GURL& site_for_cookies,
network::mojom::CookieManagerGetOptionsPtr options,
@@ -55,13 +55,12 @@ void RestrictedCookieManagerImpl::GetAllForUrl(
cookie_store_->GetCookieListWithOptionsAsync(
url, net_options,
- base::BindOnce(
- &RestrictedCookieManagerImpl::CookieListToGetAllForUrlCallback,
- weak_ptr_factory_.GetWeakPtr(), url, site_for_cookies,
- std::move(options), std::move(callback)));
+ base::BindOnce(&RestrictedCookieManager::CookieListToGetAllForUrlCallback,
+ weak_ptr_factory_.GetWeakPtr(), url, site_for_cookies,
+ std::move(options), std::move(callback)));
}
-void RestrictedCookieManagerImpl::CookieListToGetAllForUrlCallback(
+void RestrictedCookieManager::CookieListToGetAllForUrlCallback(
const GURL& url,
const GURL& site_for_cookies,
network::mojom::CookieManagerGetOptionsPtr options,
@@ -76,16 +75,29 @@ void RestrictedCookieManagerImpl::CookieListToGetAllForUrlCallback(
std::vector<net::CanonicalCookie> result;
result.reserve(cookie_list.size());
+ network::mojom::CookieMatchType match_type = options->match_type;
+ const std::string& match_name = options->name;
for (size_t i = 0; i < cookie_list.size(); ++i) {
- // TODO(pwnall): Parsing and canonicalization for net::CanonicalCookie.
const net::CanonicalCookie& cookie = cookie_list[i];
- // TODO(pwnall): Check cookie against options.
+ const std::string& cookie_name = cookie.Name();
+
+ if (match_type == network::mojom::CookieMatchType::EQUALS) {
+ if (cookie_name != match_name)
+ continue;
+ } else if (match_type == network::mojom::CookieMatchType::STARTS_WITH) {
+ if (!base::StartsWith(cookie_name, match_name,
+ base::CompareCase::SENSITIVE)) {
+ continue;
+ }
+ } else {
+ NOTREACHED();
+ }
result.emplace_back(cookie);
}
std::move(callback).Run(std::move(result));
}
-void RestrictedCookieManagerImpl::SetCanonicalCookie(
+void RestrictedCookieManager::SetCanonicalCookie(
const net::CanonicalCookie& cookie,
const GURL& url,
const GURL& site_for_cookies,
@@ -102,7 +114,7 @@ void RestrictedCookieManagerImpl::SetCanonicalCookie(
// set these fields.
net::CookieSameSite cookie_same_site_mode = net::CookieSameSite::STRICT_MODE;
net::CookiePriority cookie_priority = net::COOKIE_PRIORITY_DEFAULT;
- auto sanitized_cookie = base::MakeUnique<net::CanonicalCookie>(
+ auto sanitized_cookie = std::make_unique<net::CanonicalCookie>(
cookie.Name(), cookie.Value(), cookie.Domain(), cookie.Path(), now,
cookie.ExpiryDate(), now, cookie.IsSecure(), cookie.IsHttpOnly(),
cookie_same_site_mode, cookie_priority);
diff --git a/chromium/content/network/restricted_cookie_manager_impl.h b/chromium/content/network/restricted_cookie_manager.h
index c8a13d8d942..c2b20cd7e35 100644
--- a/chromium/content/network/restricted_cookie_manager_impl.h
+++ b/chromium/content/network/restricted_cookie_manager.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_NETWORK_RESTRICTED_COOKIE_MANAGER_IMPL_H_
-#define CONTENT_NETWORK_RESTRICTED_COOKIE_MANAGER_IMPL_H_
+#ifndef CONTENT_NETWORK_RESTRICTED_COOKIE_MANAGER_H_
+#define CONTENT_NETWORK_RESTRICTED_COOKIE_MANAGER_H_
#include <string>
@@ -28,13 +28,13 @@ namespace content {
// Instances of this class must be created and used on the I/O thread. Instances
// are created by CreateMojoService() and are bound to the lifetimes of the
// mojo connections that they serve, via mojo::StrongBinding.
-class CONTENT_EXPORT RestrictedCookieManagerImpl
+class CONTENT_EXPORT RestrictedCookieManager
: public network::mojom::RestrictedCookieManager {
public:
- RestrictedCookieManagerImpl(net::CookieStore* cookie_store,
- int render_process_id,
- int render_frame_id);
- ~RestrictedCookieManagerImpl() override;
+ RestrictedCookieManager(net::CookieStore* cookie_store,
+ int render_process_id,
+ int render_frame_id);
+ ~RestrictedCookieManager() override;
// Implements CookieStore.getAll() in the Async Cookies API.
//
@@ -63,11 +63,11 @@ class CONTENT_EXPORT RestrictedCookieManagerImpl
const int render_process_id_;
const int render_frame_id_;
- base::WeakPtrFactory<RestrictedCookieManagerImpl> weak_ptr_factory_;
+ base::WeakPtrFactory<RestrictedCookieManager> weak_ptr_factory_;
- DISALLOW_COPY_AND_ASSIGN(RestrictedCookieManagerImpl);
+ DISALLOW_COPY_AND_ASSIGN(RestrictedCookieManager);
};
} // namespace content
-#endif // CONTENT_NETWORK_RESTRICTED_COOKIE_MANAGER_IMPL_H_
+#endif // CONTENT_NETWORK_RESTRICTED_COOKIE_MANAGER_H_
diff --git a/chromium/content/network/restricted_cookie_manager_impl_unittest.cc b/chromium/content/network/restricted_cookie_manager_unittest.cc
index 411d394c04d..dab430a6754 100644
--- a/chromium/content/network/restricted_cookie_manager_impl_unittest.cc
+++ b/chromium/content/network/restricted_cookie_manager_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/network/restricted_cookie_manager_impl.h"
+#include "content/network/restricted_cookie_manager.h"
#include <algorithm>
@@ -76,28 +76,18 @@ class RestrictedCookieManagerSync {
DISALLOW_COPY_AND_ASSIGN(RestrictedCookieManagerSync);
};
-class RestrictedCookieManagerImplTest : public testing::Test {
+class RestrictedCookieManagerTest : public testing::Test {
public:
- RestrictedCookieManagerImplTest()
+ RestrictedCookieManagerTest()
: cookie_monster_(nullptr, nullptr),
- service_(
- base::MakeUnique<RestrictedCookieManagerImpl>(&cookie_monster_,
- MSG_ROUTING_NONE,
- MSG_ROUTING_NONE)),
+ service_(std::make_unique<RestrictedCookieManager>(&cookie_monster_,
+ MSG_ROUTING_NONE,
+ MSG_ROUTING_NONE)),
binding_(service_.get(), mojo::MakeRequest(&service_ptr_)) {
sync_service_ =
- base::MakeUnique<RestrictedCookieManagerSync>(service_ptr_.get());
- }
- ~RestrictedCookieManagerImplTest() override {}
-
- void SetUp() override {
- CHECK(SetCanonicalCookie(
- net::CanonicalCookie(
- "answer", "42", "example.com", "/", base::Time(), base::Time(),
- base::Time(), /* secure = */ false, /* httponly = */ false,
- net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_DEFAULT),
- true, true));
+ std::make_unique<RestrictedCookieManagerSync>(service_ptr_.get());
}
+ ~RestrictedCookieManagerTest() override {}
// Set a canonical cookie directly into the store.
bool SetCanonicalCookie(const net::CanonicalCookie& cookie,
@@ -105,7 +95,7 @@ class RestrictedCookieManagerImplTest : public testing::Test {
bool can_modify_httponly) {
net::ResultSavingCookieCallback<bool> callback;
cookie_monster_.SetCanonicalCookieAsync(
- base::MakeUnique<net::CanonicalCookie>(cookie), secure_source,
+ std::make_unique<net::CanonicalCookie>(cookie), secure_source,
can_modify_httponly,
base::BindOnce(&net::ResultSavingCookieCallback<bool>::Run,
base::Unretained(&callback)));
@@ -113,10 +103,27 @@ class RestrictedCookieManagerImplTest : public testing::Test {
return callback.result();
}
+ // Simplified helper for SetCanonicalCookie.
+ //
+ // Creates a CanonicalCookie that is not secure, not http-only,
+ // and not restricted to first parties. Crashes if the creation fails.
+ void SetSessionCookie(const char* name,
+ const char* value,
+ const char* domain,
+ const char* path) {
+ CHECK(SetCanonicalCookie(
+ net::CanonicalCookie(name, value, domain, path, base::Time(),
+ base::Time(), base::Time(), /* secure = */ false,
+ /* httponly = */ false,
+ net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_DEFAULT),
+ /* secure_source = */ true, /* can_modify_httponly = */ true));
+ }
+
protected:
base::MessageLoopForIO message_loop_;
net::CookieMonster cookie_monster_;
- std::unique_ptr<content::RestrictedCookieManagerImpl> service_;
+ std::unique_ptr<content::RestrictedCookieManager> service_;
network::mojom::RestrictedCookieManagerPtr service_ptr_;
mojo::Binding<network::mojom::RestrictedCookieManager> binding_;
std::unique_ptr<RestrictedCookieManagerSync> sync_service_;
@@ -131,7 +138,12 @@ bool CompareCanonicalCookies(const net::CanonicalCookie& c1,
} // anonymous namespace
-TEST_F(RestrictedCookieManagerImplTest, GetAllForUrl) {
+TEST_F(RestrictedCookieManagerTest, GetAllForUrlBlankFilter) {
+ SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
+ SetSessionCookie("cookie-name-2", "cookie-value-2", "example.com", "/");
+ SetSessionCookie("other-cookie-name", "other-cookie-value", "not-example.com",
+ "/");
+
auto options = network::mojom::CookieManagerGetOptions::New();
options->name = "";
options->match_type = network::mojom::CookieMatchType::STARTS_WITH;
@@ -139,22 +151,55 @@ TEST_F(RestrictedCookieManagerImplTest, GetAllForUrl) {
GURL("http://example.com/test/"), GURL("http://example.com"),
std::move(options));
- ASSERT_EQ(1u, cookies.size());
+ ASSERT_EQ(2u, cookies.size());
+ std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
+
+ EXPECT_EQ("cookie-name", cookies[0].Name());
+ EXPECT_EQ("cookie-value", cookies[0].Value());
- EXPECT_EQ("answer", cookies[0].Name());
- EXPECT_EQ("42", cookies[0].Value());
+ EXPECT_EQ("cookie-name-2", cookies[1].Name());
+ EXPECT_EQ("cookie-value-2", cookies[1].Value());
}
-TEST_F(RestrictedCookieManagerImplTest, SetCanonicalCookie) {
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- net::CanonicalCookie(
- "foo", "bar", "example.com", "/", base::Time(), base::Time(),
- base::Time(), /* secure = */ false, /* httponly = */ false,
- net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_DEFAULT),
- GURL("http://example.com/test/"), GURL("http://example.com")));
+TEST_F(RestrictedCookieManagerTest, GetAllForUrlEmptyFilter) {
+ SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
auto options = network::mojom::CookieManagerGetOptions::New();
options->name = "";
+ options->match_type = network::mojom::CookieMatchType::EQUALS;
+ std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
+ GURL("http://example.com/test/"), GURL("http://example.com"),
+ std::move(options));
+
+ ASSERT_EQ(0u, cookies.size());
+ std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
+}
+
+TEST_F(RestrictedCookieManagerTest, GetAllForUrlEqualsMatch) {
+ SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
+ SetSessionCookie("cookie-name-2", "cookie-value-2", "example.com", "/");
+
+ auto options = network::mojom::CookieManagerGetOptions::New();
+ options->name = "cookie-name";
+ options->match_type = network::mojom::CookieMatchType::EQUALS;
+ std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
+ GURL("http://example.com/test/"), GURL("http://example.com"),
+ std::move(options));
+
+ ASSERT_EQ(1u, cookies.size());
+
+ EXPECT_EQ("cookie-name", cookies[0].Name());
+ EXPECT_EQ("cookie-value", cookies[0].Value());
+}
+
+TEST_F(RestrictedCookieManagerTest, GetAllForUrlStartsWithMatch) {
+ SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
+ SetSessionCookie("cookie-name-2", "cookie-value-2", "example.com", "/");
+ SetSessionCookie("cookie-name-2b", "cookie-value-2b", "example.com", "/");
+ SetSessionCookie("cookie-name-3b", "cookie-value-3b", "example.com", "/");
+
+ auto options = network::mojom::CookieManagerGetOptions::New();
+ options->name = "cookie-name-2";
options->match_type = network::mojom::CookieMatchType::STARTS_WITH;
std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
GURL("http://example.com/test/"), GURL("http://example.com"),
@@ -163,11 +208,33 @@ TEST_F(RestrictedCookieManagerImplTest, SetCanonicalCookie) {
ASSERT_EQ(2u, cookies.size());
std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies);
- EXPECT_EQ("answer", cookies[0].Name());
- EXPECT_EQ("42", cookies[0].Value());
+ EXPECT_EQ("cookie-name-2", cookies[0].Name());
+ EXPECT_EQ("cookie-value-2", cookies[0].Value());
+
+ EXPECT_EQ("cookie-name-2b", cookies[1].Name());
+ EXPECT_EQ("cookie-value-2b", cookies[1].Value());
+}
+
+TEST_F(RestrictedCookieManagerTest, SetCanonicalCookie) {
+ EXPECT_TRUE(sync_service_->SetCanonicalCookie(
+ net::CanonicalCookie(
+ "new-name", "new-value", "example.com", "/", base::Time(),
+ base::Time(), base::Time(), /* secure = */ false,
+ /* httponly = */ false, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_DEFAULT),
+ GURL("http://example.com/test/"), GURL("http://example.com")));
+
+ auto options = network::mojom::CookieManagerGetOptions::New();
+ options->name = "new-name";
+ options->match_type = network::mojom::CookieMatchType::EQUALS;
+ std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
+ GURL("http://example.com/test/"), GURL("http://example.com"),
+ std::move(options));
+
+ ASSERT_EQ(1u, cookies.size());
- EXPECT_EQ("foo", cookies[1].Name());
- EXPECT_EQ("bar", cookies[1].Value());
+ EXPECT_EQ("new-name", cookies[0].Name());
+ EXPECT_EQ("new-value", cookies[0].Value());
}
} // namespace content
diff --git a/chromium/content/network/throttling/network_conditions.cc b/chromium/content/network/throttling/network_conditions.cc
new file mode 100644
index 00000000000..d4639fee0d4
--- /dev/null
+++ b/chromium/content/network/throttling/network_conditions.cc
@@ -0,0 +1,30 @@
+// 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/network/throttling/network_conditions.h"
+
+namespace content {
+
+NetworkConditions::NetworkConditions() : NetworkConditions(false) {}
+
+NetworkConditions::NetworkConditions(bool offline)
+ : NetworkConditions(offline, 0, 0, 0) {}
+
+NetworkConditions::NetworkConditions(bool offline,
+ double latency,
+ double download_throughput,
+ double upload_throughput)
+ : offline_(offline),
+ latency_(latency),
+ download_throughput_(download_throughput),
+ upload_throughput_(upload_throughput) {}
+
+NetworkConditions::~NetworkConditions() {}
+
+bool NetworkConditions::IsThrottling() const {
+ return !offline_ && ((latency_ != 0) || (download_throughput_ != 0.0) ||
+ (upload_throughput_ != 0));
+}
+
+} // namespace content
diff --git a/chromium/content/common/devtools/devtools_network_conditions.h b/chromium/content/network/throttling/network_conditions.h
index c076e76f320..037f1603961 100644
--- a/chromium/content/common/devtools/devtools_network_conditions.h
+++ b/chromium/content/network/throttling/network_conditions.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 CONTET_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_CONDITIONS_H_
-#define CONTET_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_CONDITIONS_H_
+#ifndef CONTET_NETWORK_THROTTLING_NETWORK_CONDITIONS_H_
+#define CONTET_NETWORK_THROTTLING_NETWORK_CONDITIONS_H_
#include <string>
#include <vector>
@@ -14,17 +14,17 @@
namespace content {
-// DevToolsNetworkConditions holds information about desired network conditions.
-class CONTENT_EXPORT DevToolsNetworkConditions {
+// NetworkConditions holds information about desired network conditions.
+class CONTENT_EXPORT NetworkConditions {
public:
- DevToolsNetworkConditions();
- ~DevToolsNetworkConditions();
+ NetworkConditions();
+ ~NetworkConditions();
- explicit DevToolsNetworkConditions(bool offline);
- DevToolsNetworkConditions(bool offline,
- double latency,
- double download_throughput,
- double upload_throughput);
+ explicit NetworkConditions(bool offline);
+ NetworkConditions(bool offline,
+ double latency,
+ double download_throughput,
+ double upload_throughput);
bool IsThrottling() const;
@@ -39,9 +39,9 @@ class CONTENT_EXPORT DevToolsNetworkConditions {
const double download_throughput_;
const double upload_throughput_;
- DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkConditions);
+ DISALLOW_COPY_AND_ASSIGN(NetworkConditions);
};
} // namespace content
-#endif // CONTET_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_CONDITIONS_H_
+#endif // CONTET_NETWORK_THROTTLING_NETWORK_CONDITIONS_H_
diff --git a/chromium/content/common/devtools/devtools_network_controller.cc b/chromium/content/network/throttling/throttling_controller.cc
index 3e485a5b237..8cea4eb94cb 100644
--- a/chromium/content/common/devtools/devtools_network_controller.cc
+++ b/chromium/content/network/throttling/throttling_controller.cc
@@ -2,23 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/common/devtools/devtools_network_controller.h"
+#include "content/network/throttling/throttling_controller.h"
#include <utility>
-#include "content/common/devtools/devtools_network_conditions.h"
-#include "content/common/devtools/devtools_network_interceptor.h"
+#include "content/network/throttling/network_conditions.h"
+#include "content/network/throttling/throttling_network_interceptor.h"
#include "net/http/http_request_info.h"
namespace content {
-DevToolsNetworkController* DevToolsNetworkController::instance_ = nullptr;
+ThrottlingController* ThrottlingController::instance_ = nullptr;
-DevToolsNetworkController::DevToolsNetworkController() = default;
-DevToolsNetworkController::~DevToolsNetworkController() = default;
+ThrottlingController::ThrottlingController() = default;
+ThrottlingController::~ThrottlingController() = default;
// static
-DevToolsNetworkInterceptor* DevToolsNetworkController::GetInterceptor(
+ThrottlingNetworkInterceptor* ThrottlingController::GetInterceptor(
const std::string& client_id) {
if (!instance_ || client_id.empty())
return nullptr;
@@ -26,41 +26,41 @@ DevToolsNetworkInterceptor* DevToolsNetworkController::GetInterceptor(
}
// static
-void DevToolsNetworkController::SetNetworkState(
+void ThrottlingController::SetConditions(
const std::string& client_id,
- std::unique_ptr<DevToolsNetworkConditions> conditions) {
+ std::unique_ptr<NetworkConditions> conditions) {
if (!instance_) {
if (!conditions)
return;
- instance_ = new DevToolsNetworkController();
+ instance_ = new ThrottlingController();
}
- instance_->SetConditions(client_id, std::move(conditions));
+ instance_->SetNetworkConditions(client_id, std::move(conditions));
}
-DevToolsNetworkInterceptor* DevToolsNetworkController::FindInterceptor(
+ThrottlingNetworkInterceptor* ThrottlingController::FindInterceptor(
const std::string& client_id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto it = interceptors_.find(client_id);
return it != interceptors_.end() ? it->second.get() : nullptr;
}
-void DevToolsNetworkController::SetConditions(
+void ThrottlingController::SetNetworkConditions(
const std::string& client_id,
- std::unique_ptr<DevToolsNetworkConditions> conditions) {
+ std::unique_ptr<NetworkConditions> conditions) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto it = interceptors_.find(client_id);
if (it == interceptors_.end()) {
if (!conditions)
return;
- std::unique_ptr<DevToolsNetworkInterceptor> new_interceptor(
- new DevToolsNetworkInterceptor());
+ std::unique_ptr<ThrottlingNetworkInterceptor> new_interceptor(
+ new ThrottlingNetworkInterceptor());
new_interceptor->UpdateConditions(std::move(conditions));
interceptors_[client_id] = std::move(new_interceptor);
} else {
if (!conditions) {
- std::unique_ptr<DevToolsNetworkConditions> online_conditions(
- new DevToolsNetworkConditions());
+ std::unique_ptr<NetworkConditions> online_conditions(
+ new NetworkConditions());
it->second->UpdateConditions(std::move(online_conditions));
interceptors_.erase(client_id);
if (interceptors_.empty()) {
diff --git a/chromium/content/network/throttling/throttling_controller.h b/chromium/content/network/throttling/throttling_controller.h
new file mode 100644
index 00000000000..bc8feba1af5
--- /dev/null
+++ b/chromium/content/network/throttling/throttling_controller.h
@@ -0,0 +1,54 @@
+// 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_NETWORK_THROTTLING_THROTTLING_NETWORK_CONTROLLER_H_
+#define CONTENT_NETWORK_THROTTLING_THROTTLING_NETWORK_CONTROLLER_H_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "base/threading/thread_checker.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class NetworkConditions;
+class ThrottlingNetworkInterceptor;
+
+// ThrottlingController manages interceptors identified by client id
+// and their throttling conditions.
+class CONTENT_EXPORT ThrottlingController {
+ public:
+ // Applies network emulation configuration.
+ static void SetConditions(const std::string& client_id,
+ std::unique_ptr<NetworkConditions>);
+ static void DisableThrottling(const std::string& client_id);
+
+ static ThrottlingNetworkInterceptor* GetInterceptor(
+ const std::string& client_id);
+
+ private:
+ ThrottlingController();
+ ~ThrottlingController();
+
+ ThrottlingNetworkInterceptor* FindInterceptor(const std::string& client_id);
+ void SetNetworkConditions(const std::string& client_id,
+ std::unique_ptr<NetworkConditions> conditions);
+
+ static ThrottlingController* instance_;
+
+ using InterceptorMap =
+ std::map<std::string, std::unique_ptr<ThrottlingNetworkInterceptor>>;
+
+ InterceptorMap interceptors_;
+ THREAD_CHECKER(thread_checker_);
+
+ DISALLOW_COPY_AND_ASSIGN(ThrottlingController);
+};
+
+} // namespace content
+
+#endif // CONTENT_NETWORK_THROTTLING_THROTTLING_NETWORK_CONTROLLER_H_
diff --git a/chromium/content/common/devtools/devtools_network_controller_unittest.cc b/chromium/content/network/throttling/throttling_controller_unittest.cc
index b30bb4a19f6..ea7a2caf5bc 100644
--- a/chromium/content/common/devtools/devtools_network_controller_unittest.cc
+++ b/chromium/content/network/throttling/throttling_controller_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/common/devtools/devtools_network_controller.h"
+#include "content/network/throttling/throttling_controller.h"
#include <stdint.h>
@@ -14,10 +14,11 @@
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
-#include "content/common/devtools/devtools_network_conditions.h"
-#include "content/common/devtools/devtools_network_interceptor.h"
-#include "content/common/devtools/devtools_network_transaction.h"
-#include "content/common/devtools/devtools_network_upload_data_stream.h"
+#include "base/test/test_mock_time_task_runner.h"
+#include "content/network/throttling/network_conditions.h"
+#include "content/network/throttling/throttling_network_interceptor.h"
+#include "content/network/throttling/throttling_network_transaction.h"
+#include "content/network/throttling/throttling_upload_data_stream.h"
#include "net/base/chunked_upload_data_stream.h"
#include "net/http/http_transaction_test_util.h"
#include "net/log/net_log_with_source.h"
@@ -52,10 +53,11 @@ class TestCallback {
int value_;
};
-class DevToolsNetworkControllerHelper {
+class ThrottlingControllerHelper {
public:
- DevToolsNetworkControllerHelper()
- : completion_callback_(
+ ThrottlingControllerHelper()
+ : task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>()),
+ completion_callback_(
base::Bind(&TestCallback::Run, base::Unretained(&callback_))),
mock_transaction_(kSimpleGET_Transaction),
buffer_(new net::IOBuffer(64)) {
@@ -69,20 +71,20 @@ class DevToolsNetworkControllerHelper {
network_layer_.CreateTransaction(net::DEFAULT_PRIORITY,
&network_transaction);
transaction_.reset(
- new DevToolsNetworkTransaction(std::move(network_transaction)));
+ new ThrottlingNetworkTransaction(std::move(network_transaction)));
+ message_loop_.SetTaskRunner(task_runner_);
}
void SetNetworkState(bool offline, double download, double upload) {
- std::unique_ptr<DevToolsNetworkConditions> conditions(
- new DevToolsNetworkConditions(offline, 0, download, upload));
- DevToolsNetworkController::SetNetworkState(kClientId,
- std::move(conditions));
+ std::unique_ptr<NetworkConditions> conditions(
+ new NetworkConditions(offline, 0, download, upload));
+ ThrottlingController::SetConditions(kClientId, std::move(conditions));
}
void SetNetworkState(const std::string& id, bool offline) {
- std::unique_ptr<DevToolsNetworkConditions> conditions(
- new DevToolsNetworkConditions(offline));
- DevToolsNetworkController::SetNetworkState(id, std::move(conditions));
+ std::unique_ptr<NetworkConditions> conditions(
+ new NetworkConditions(offline));
+ ThrottlingController::SetConditions(id, std::move(conditions));
}
int Start(bool with_upload) {
@@ -109,8 +111,8 @@ class DevToolsNetworkControllerHelper {
bool ShouldFail() {
if (transaction_->interceptor_)
return transaction_->interceptor_->IsOffline();
- DevToolsNetworkInterceptor* interceptor =
- DevToolsNetworkController::GetInterceptor(kClientId);
+ ThrottlingNetworkInterceptor* interceptor =
+ ThrottlingController::GetInterceptor(kClientId);
EXPECT_TRUE(!!interceptor);
return interceptor->IsOffline();
}
@@ -128,27 +130,30 @@ class DevToolsNetworkControllerHelper {
completion_callback_);
}
- ~DevToolsNetworkControllerHelper() {
- RemoveMockTransaction(&mock_transaction_);
- }
+ ~ThrottlingControllerHelper() { RemoveMockTransaction(&mock_transaction_); }
TestCallback* callback() { return &callback_; }
- DevToolsNetworkTransaction* transaction() { return transaction_.get(); }
+ ThrottlingNetworkTransaction* transaction() { return transaction_.get(); }
+
+ void FastForwardUntilNoTasksRemain() {
+ task_runner_->FastForwardUntilNoTasksRemain();
+ }
private:
+ scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
base::MessageLoop message_loop_;
MockNetworkLayer network_layer_;
TestCallback callback_;
net::CompletionCallback completion_callback_;
MockTransaction mock_transaction_;
- std::unique_ptr<DevToolsNetworkTransaction> transaction_;
+ std::unique_ptr<ThrottlingNetworkTransaction> transaction_;
scoped_refptr<net::IOBuffer> buffer_;
std::unique_ptr<net::ChunkedUploadDataStream> upload_data_stream_;
std::unique_ptr<MockHttpRequest> request_;
};
-TEST(DevToolsNetworkControllerTest, SingleDisableEnable) {
- DevToolsNetworkControllerHelper helper;
+TEST(ThrottlingControllerTest, SingleDisableEnable) {
+ ThrottlingControllerHelper helper;
helper.SetNetworkState(false, 0, 0);
helper.Start(false);
@@ -161,8 +166,8 @@ TEST(DevToolsNetworkControllerTest, SingleDisableEnable) {
base::RunLoop().RunUntilIdle();
}
-TEST(DevToolsNetworkControllerTest, InterceptorIsolation) {
- DevToolsNetworkControllerHelper helper;
+TEST(ThrottlingControllerTest, InterceptorIsolation) {
+ ThrottlingControllerHelper helper;
helper.SetNetworkState(false, 0, 0);
helper.Start(false);
@@ -177,8 +182,8 @@ TEST(DevToolsNetworkControllerTest, InterceptorIsolation) {
base::RunLoop().RunUntilIdle();
}
-TEST(DevToolsNetworkControllerTest, FailOnStart) {
- DevToolsNetworkControllerHelper helper;
+TEST(ThrottlingControllerTest, FailOnStart) {
+ ThrottlingControllerHelper helper;
helper.SetNetworkState(true, 0, 0);
int rv = helper.Start(false);
@@ -188,8 +193,8 @@ TEST(DevToolsNetworkControllerTest, FailOnStart) {
EXPECT_EQ(helper.callback()->run_count(), 0);
}
-TEST(DevToolsNetworkControllerTest, FailRunningTransaction) {
- DevToolsNetworkControllerHelper helper;
+TEST(ThrottlingControllerTest, FailRunningTransaction) {
+ ThrottlingControllerHelper helper;
helper.SetNetworkState(false, 0, 0);
TestCallback* callback = helper.callback();
@@ -204,8 +209,8 @@ TEST(DevToolsNetworkControllerTest, FailRunningTransaction) {
EXPECT_EQ(callback->run_count(), 0);
// Wait until HttpTrancation completes reading and invokes callback.
- // DevToolsNetworkTransaction should report error instead.
- base::RunLoop().RunUntilIdle();
+ // ThrottlingNetworkTransaction should report error instead.
+ helper.FastForwardUntilNoTasksRemain();
EXPECT_EQ(callback->run_count(), 1);
EXPECT_EQ(callback->value(), net::ERR_INTERNET_DISCONNECTED);
@@ -215,8 +220,8 @@ TEST(DevToolsNetworkControllerTest, FailRunningTransaction) {
EXPECT_EQ(callback->run_count(), 1);
}
-TEST(DevToolsNetworkControllerTest, ReadAfterFail) {
- DevToolsNetworkControllerHelper helper;
+TEST(ThrottlingControllerTest, ReadAfterFail) {
+ ThrottlingControllerHelper helper;
helper.SetNetworkState(false, 0, 0);
int rv = helper.Start(false);
@@ -236,8 +241,8 @@ TEST(DevToolsNetworkControllerTest, ReadAfterFail) {
EXPECT_EQ(helper.callback()->run_count(), 0);
}
-TEST(DevToolsNetworkControllerTest, CancelTransaction) {
- DevToolsNetworkControllerHelper helper;
+TEST(ThrottlingControllerTest, CancelTransaction) {
+ ThrottlingControllerHelper helper;
helper.SetNetworkState(false, 0, 0);
int rv = helper.Start(false);
@@ -251,8 +256,8 @@ TEST(DevToolsNetworkControllerTest, CancelTransaction) {
base::RunLoop().RunUntilIdle();
}
-TEST(DevToolsNetworkControllerTest, CancelFailedTransaction) {
- DevToolsNetworkControllerHelper helper;
+TEST(ThrottlingControllerTest, CancelFailedTransaction) {
+ ThrottlingControllerHelper helper;
helper.SetNetworkState(true, 0, 0);
int rv = helper.Start(false);
@@ -266,8 +271,8 @@ TEST(DevToolsNetworkControllerTest, CancelFailedTransaction) {
base::RunLoop().RunUntilIdle();
}
-TEST(DevToolsNetworkControllerTest, UploadDoesNotFail) {
- DevToolsNetworkControllerHelper helper;
+TEST(ThrottlingControllerTest, UploadDoesNotFail) {
+ ThrottlingControllerHelper helper;
helper.SetNetworkState(true, 0, 0);
int rv = helper.Start(true);
EXPECT_EQ(rv, net::ERR_INTERNET_DISCONNECTED);
@@ -275,46 +280,46 @@ TEST(DevToolsNetworkControllerTest, UploadDoesNotFail) {
EXPECT_EQ(rv, static_cast<int>(arraysize(kUploadData)));
}
-TEST(DevToolsNetworkControllerTest, DownloadOnly) {
- DevToolsNetworkControllerHelper helper;
+TEST(ThrottlingControllerTest, DownloadOnly) {
+ ThrottlingControllerHelper helper;
TestCallback* callback = helper.callback();
helper.SetNetworkState(false, 10000000, 0);
int rv = helper.Start(false);
EXPECT_EQ(rv, net::ERR_IO_PENDING);
- base::RunLoop().RunUntilIdle();
+ helper.FastForwardUntilNoTasksRemain();
EXPECT_EQ(callback->run_count(), 1);
EXPECT_GE(callback->value(), net::OK);
rv = helper.Read();
EXPECT_EQ(rv, net::ERR_IO_PENDING);
EXPECT_EQ(callback->run_count(), 1);
- base::RunLoop().RunUntilIdle();
+ helper.FastForwardUntilNoTasksRemain();
EXPECT_EQ(callback->run_count(), 2);
EXPECT_GE(callback->value(), net::OK);
}
-TEST(DevToolsNetworkControllerTest, UploadOnly) {
- DevToolsNetworkControllerHelper helper;
+TEST(ThrottlingControllerTest, UploadOnly) {
+ ThrottlingControllerHelper helper;
TestCallback* callback = helper.callback();
helper.SetNetworkState(false, 0, 1000000);
int rv = helper.Start(true);
EXPECT_EQ(rv, net::OK);
- base::RunLoop().RunUntilIdle();
+ helper.FastForwardUntilNoTasksRemain();
EXPECT_EQ(callback->run_count(), 0);
rv = helper.Read();
EXPECT_EQ(rv, net::ERR_IO_PENDING);
EXPECT_EQ(callback->run_count(), 0);
- base::RunLoop().RunUntilIdle();
+ helper.FastForwardUntilNoTasksRemain();
EXPECT_EQ(callback->run_count(), 1);
EXPECT_GE(callback->value(), net::OK);
rv = helper.ReadUploadData();
EXPECT_EQ(rv, net::ERR_IO_PENDING);
EXPECT_EQ(callback->run_count(), 1);
- base::RunLoop().RunUntilIdle();
+ helper.FastForwardUntilNoTasksRemain();
EXPECT_EQ(callback->run_count(), 2);
EXPECT_EQ(callback->value(), static_cast<int>(arraysize(kUploadData)));
}
diff --git a/chromium/content/common/devtools/devtools_network_interceptor.cc b/chromium/content/network/throttling/throttling_network_interceptor.cc
index 0379597e305..6054bfd475b 100644
--- a/chromium/content/common/devtools/devtools_network_interceptor.cc
+++ b/chromium/content/network/throttling/throttling_network_interceptor.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/common/devtools/devtools_network_interceptor.h"
+#include "content/network/throttling/throttling_network_interceptor.h"
#include <stddef.h>
#include <algorithm>
@@ -10,7 +10,7 @@
#include <utility>
#include "base/time/time.h"
-#include "content/common/devtools/devtools_network_conditions.h"
+#include "content/network/throttling/network_conditions.h"
#include "net/base/net_errors.h"
namespace content {
@@ -21,7 +21,7 @@ int64_t kPacketSize = 1500;
base::TimeDelta CalculateTickLength(double throughput) {
if (!throughput)
- return base::TimeDelta();
+ return base::TimeDelta::FromMicroseconds(1);
int64_t us_tick_length = (1000000L * kPacketSize) / throughput;
DCHECK(us_tick_length != 0);
if (us_tick_length == 0)
@@ -31,28 +31,28 @@ base::TimeDelta CalculateTickLength(double throughput) {
} // namespace
-DevToolsNetworkInterceptor::ThrottleRecord::ThrottleRecord() {}
+ThrottlingNetworkInterceptor::ThrottleRecord::ThrottleRecord() {}
-DevToolsNetworkInterceptor::ThrottleRecord::ThrottleRecord(
+ThrottlingNetworkInterceptor::ThrottleRecord::ThrottleRecord(
const ThrottleRecord& other) = default;
-DevToolsNetworkInterceptor::ThrottleRecord::~ThrottleRecord() {}
+ThrottlingNetworkInterceptor::ThrottleRecord::~ThrottleRecord() {}
-DevToolsNetworkInterceptor::DevToolsNetworkInterceptor()
- : conditions_(new DevToolsNetworkConditions()),
+ThrottlingNetworkInterceptor::ThrottlingNetworkInterceptor()
+ : conditions_(new NetworkConditions()),
download_last_tick_(0),
upload_last_tick_(0),
weak_ptr_factory_(this) {}
-DevToolsNetworkInterceptor::~DevToolsNetworkInterceptor() {}
+ThrottlingNetworkInterceptor::~ThrottlingNetworkInterceptor() {}
-base::WeakPtr<DevToolsNetworkInterceptor>
-DevToolsNetworkInterceptor::GetWeakPtr() {
+base::WeakPtr<ThrottlingNetworkInterceptor>
+ThrottlingNetworkInterceptor::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
-void DevToolsNetworkInterceptor::FinishRecords(ThrottleRecords* records,
- bool offline) {
+void ThrottlingNetworkInterceptor::FinishRecords(ThrottleRecords* records,
+ bool offline) {
ThrottleRecords temp;
temp.swap(*records);
for (const ThrottleRecord& record : temp) {
@@ -62,8 +62,8 @@ void DevToolsNetworkInterceptor::FinishRecords(ThrottleRecords* records,
}
}
-void DevToolsNetworkInterceptor::UpdateConditions(
- std::unique_ptr<DevToolsNetworkConditions> conditions) {
+void ThrottlingNetworkInterceptor::UpdateConditions(
+ std::unique_ptr<NetworkConditions> conditions) {
DCHECK(conditions);
base::TimeTicks now = base::TimeTicks::Now();
if (conditions_->IsThrottling())
@@ -99,7 +99,7 @@ void DevToolsNetworkInterceptor::UpdateConditions(
ArmTimer(now);
}
-uint64_t DevToolsNetworkInterceptor::UpdateThrottledRecords(
+uint64_t ThrottlingNetworkInterceptor::UpdateThrottledRecords(
base::TimeTicks now,
ThrottleRecords* records,
uint64_t last_tick,
@@ -125,7 +125,7 @@ uint64_t DevToolsNetworkInterceptor::UpdateThrottledRecords(
return new_tick;
}
-void DevToolsNetworkInterceptor::UpdateThrottled(base::TimeTicks now) {
+void ThrottlingNetworkInterceptor::UpdateThrottled(base::TimeTicks now) {
download_last_tick_ = UpdateThrottledRecords(
now, &download_, download_last_tick_, download_tick_length_);
upload_last_tick_ = UpdateThrottledRecords(now, &upload_, upload_last_tick_,
@@ -133,7 +133,7 @@ void DevToolsNetworkInterceptor::UpdateThrottled(base::TimeTicks now) {
UpdateSuspended(now);
}
-void DevToolsNetworkInterceptor::UpdateSuspended(base::TimeTicks now) {
+void ThrottlingNetworkInterceptor::UpdateSuspended(base::TimeTicks now) {
int64_t activation_baseline =
(now - latency_length_ - base::TimeTicks()).InMicroseconds();
ThrottleRecords suspended;
@@ -150,8 +150,8 @@ void DevToolsNetworkInterceptor::UpdateSuspended(base::TimeTicks now) {
suspended_.swap(suspended);
}
-void DevToolsNetworkInterceptor::CollectFinished(ThrottleRecords* records,
- ThrottleRecords* finished) {
+void ThrottlingNetworkInterceptor::CollectFinished(ThrottleRecords* records,
+ ThrottleRecords* finished) {
ThrottleRecords active;
for (const ThrottleRecord& record : *records) {
if (record.bytes < 0)
@@ -162,7 +162,7 @@ void DevToolsNetworkInterceptor::CollectFinished(ThrottleRecords* records,
records->swap(active);
}
-void DevToolsNetworkInterceptor::OnTimer() {
+void ThrottlingNetworkInterceptor::OnTimer() {
base::TimeTicks now = base::TimeTicks::Now();
UpdateThrottled(now);
@@ -175,7 +175,7 @@ void DevToolsNetworkInterceptor::OnTimer() {
ArmTimer(now);
}
-base::TimeTicks DevToolsNetworkInterceptor::CalculateDesiredTime(
+base::TimeTicks ThrottlingNetworkInterceptor::CalculateDesiredTime(
const ThrottleRecords& records,
uint64_t last_tick,
base::TimeDelta tick_length) {
@@ -190,7 +190,7 @@ base::TimeTicks DevToolsNetworkInterceptor::CalculateDesiredTime(
return offset_ + tick_length * (last_tick + min_ticks_left);
}
-void DevToolsNetworkInterceptor::ArmTimer(base::TimeTicks now) {
+void ThrottlingNetworkInterceptor::ArmTimer(base::TimeTicks now) {
size_t suspend_count = suspended_.size();
if (download_.empty() && upload_.empty() && !suspend_count)
return;
@@ -216,12 +216,12 @@ void DevToolsNetworkInterceptor::ArmTimer(base::TimeTicks now) {
desired_time = activation_time;
}
- timer_.Start(
- FROM_HERE, desired_time - now,
- base::Bind(&DevToolsNetworkInterceptor::OnTimer, base::Unretained(this)));
+ timer_.Start(FROM_HERE, desired_time - now,
+ base::Bind(&ThrottlingNetworkInterceptor::OnTimer,
+ base::Unretained(this)));
}
-int DevToolsNetworkInterceptor::StartThrottle(
+int ThrottlingNetworkInterceptor::StartThrottle(
int result,
int64_t bytes,
base::TimeTicks send_end,
@@ -234,8 +234,9 @@ int DevToolsNetworkInterceptor::StartThrottle(
if (conditions_->offline())
return is_upload ? result : net::ERR_INTERNET_DISCONNECTED;
- if ((is_upload && !conditions_->upload_throughput()) ||
- (!is_upload && !conditions_->download_throughput())) {
+ if (!conditions_->latency() &&
+ ((is_upload && !conditions_->upload_throughput()) ||
+ (!is_upload && !conditions_->download_throughput()))) {
return result;
}
@@ -263,14 +264,14 @@ int DevToolsNetworkInterceptor::StartThrottle(
return net::ERR_IO_PENDING;
}
-void DevToolsNetworkInterceptor::StopThrottle(
+void ThrottlingNetworkInterceptor::StopThrottle(
const ThrottleCallback& callback) {
RemoveRecord(&download_, callback);
RemoveRecord(&upload_, callback);
RemoveRecord(&suspended_, callback);
}
-void DevToolsNetworkInterceptor::RemoveRecord(
+void ThrottlingNetworkInterceptor::RemoveRecord(
ThrottleRecords* records,
const ThrottleCallback& callback) {
records->erase(std::remove_if(records->begin(), records->end(),
@@ -280,7 +281,7 @@ void DevToolsNetworkInterceptor::RemoveRecord(
records->end());
}
-bool DevToolsNetworkInterceptor::IsOffline() {
+bool ThrottlingNetworkInterceptor::IsOffline() {
return conditions_->offline();
}
diff --git a/chromium/content/common/devtools/devtools_network_interceptor.h b/chromium/content/network/throttling/throttling_network_interceptor.h
index 0bf40825be8..ea857f7c8d2 100644
--- a/chromium/content/common/devtools/devtools_network_interceptor.h
+++ b/chromium/content/network/throttling/throttling_network_interceptor.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_DEVTOOLS_DEVTOOLS_NETWORK_INTERCEPTOR_H_
-#define CONTENT_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_INTERCEPTOR_H_
+#ifndef CONTENT_NETWORK_THROTTLING_THROTTLING_NETWORK_INTERCEPTOR_H_
+#define CONTENT_NETWORK_THROTTLING_THROTTLING_NETWORK_INTERCEPTOR_H_
#include <stdint.h>
@@ -23,21 +23,21 @@ class TimeTicks;
} // namespace base
namespace content {
-class DevToolsNetworkConditions;
+class NetworkConditions;
-// DevToolsNetworkInterceptor emulates network conditions for transactions with
-// specific client id.
-class CONTENT_EXPORT DevToolsNetworkInterceptor {
+// ThrottlingNetworkInterceptor emulates network conditions for transactions
+// with specific client id.
+class CONTENT_EXPORT ThrottlingNetworkInterceptor {
public:
using ThrottleCallback = base::Callback<void(int, int64_t)>;
- DevToolsNetworkInterceptor();
- virtual ~DevToolsNetworkInterceptor();
+ ThrottlingNetworkInterceptor();
+ virtual ~ThrottlingNetworkInterceptor();
- base::WeakPtr<DevToolsNetworkInterceptor> GetWeakPtr();
+ base::WeakPtr<ThrottlingNetworkInterceptor> GetWeakPtr();
// Applies network emulation configuration.
- void UpdateConditions(std::unique_ptr<DevToolsNetworkConditions> conditions);
+ void UpdateConditions(std::unique_ptr<NetworkConditions> conditions);
// Throttles with |is_upload == true| always succeed, even in offline mode.
int StartThrottle(int result,
@@ -83,7 +83,7 @@ class CONTENT_EXPORT DevToolsNetworkInterceptor {
void RemoveRecord(ThrottleRecords* records, const ThrottleCallback& callback);
- std::unique_ptr<DevToolsNetworkConditions> conditions_;
+ std::unique_ptr<NetworkConditions> conditions_;
// Throttables suspended for a "latency" period.
ThrottleRecords suspended_;
@@ -100,11 +100,11 @@ class CONTENT_EXPORT DevToolsNetworkInterceptor {
uint64_t download_last_tick_;
uint64_t upload_last_tick_;
- base::WeakPtrFactory<DevToolsNetworkInterceptor> weak_ptr_factory_;
+ base::WeakPtrFactory<ThrottlingNetworkInterceptor> weak_ptr_factory_;
- DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkInterceptor);
+ DISALLOW_COPY_AND_ASSIGN(ThrottlingNetworkInterceptor);
};
} // namespace content
-#endif // CONTENT_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_INTERCEPTOR_H_
+#endif // CONTENT_NETWORK_THROTTLING_THROTTLING_NETWORK_INTERCEPTOR_H_
diff --git a/chromium/content/common/devtools/devtools_network_transaction.cc b/chromium/content/network/throttling/throttling_network_transaction.cc
index 848278571f1..b7df8df5630 100644
--- a/chromium/content/common/devtools/devtools_network_transaction.cc
+++ b/chromium/content/network/throttling/throttling_network_transaction.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/common/devtools/devtools_network_transaction.h"
+#include "content/network/throttling/throttling_network_transaction.h"
#include <utility>
#include "base/callback_helpers.h"
-#include "content/common/devtools/devtools_network_controller.h"
-#include "content/common/devtools/devtools_network_interceptor.h"
-#include "content/common/devtools/devtools_network_upload_data_stream.h"
+#include "content/network/throttling/throttling_controller.h"
+#include "content/network/throttling/throttling_network_interceptor.h"
+#include "content/network/throttling/throttling_upload_data_stream.h"
#include "net/base/load_timing_info.h"
#include "net/base/net_errors.h"
#include "net/http/http_network_transaction.h"
@@ -21,22 +21,22 @@ namespace content {
// Keep in sync with X_DevTools_Emulate_Network_Conditions_Client_Id defined in
// HTTPNames.json5.
const char
- DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId[] =
+ ThrottlingNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId[] =
"X-DevTools-Emulate-Network-Conditions-Client-Id";
-DevToolsNetworkTransaction::DevToolsNetworkTransaction(
+ThrottlingNetworkTransaction::ThrottlingNetworkTransaction(
std::unique_ptr<net::HttpTransaction> network_transaction)
: throttled_byte_count_(0),
network_transaction_(std::move(network_transaction)),
request_(nullptr),
failed_(false) {}
-DevToolsNetworkTransaction::~DevToolsNetworkTransaction() {
+ThrottlingNetworkTransaction::~ThrottlingNetworkTransaction() {
if (interceptor_ && !throttle_callback_.is_null())
interceptor_->StopThrottle(throttle_callback_);
}
-void DevToolsNetworkTransaction::IOCallback(
+void ThrottlingNetworkTransaction::IOCallback(
const net::CompletionCallback& callback,
bool start,
int result) {
@@ -45,7 +45,7 @@ void DevToolsNetworkTransaction::IOCallback(
callback.Run(result);
}
-int DevToolsNetworkTransaction::Throttle(
+int ThrottlingNetworkTransaction::Throttle(
const net::CompletionCallback& callback,
bool start,
int result) {
@@ -69,8 +69,9 @@ int DevToolsNetworkTransaction::Throttle(
if (result > 0)
throttled_byte_count_ += result;
- throttle_callback_ = base::Bind(&DevToolsNetworkTransaction::ThrottleCallback,
- base::Unretained(this), callback);
+ throttle_callback_ =
+ base::Bind(&ThrottlingNetworkTransaction::ThrottleCallback,
+ base::Unretained(this), callback);
int rv = interceptor_->StartThrottle(result, throttled_byte_count_, send_end,
start, false, throttle_callback_);
if (rv != net::ERR_IO_PENDING)
@@ -80,7 +81,7 @@ int DevToolsNetworkTransaction::Throttle(
return rv;
}
-void DevToolsNetworkTransaction::ThrottleCallback(
+void ThrottlingNetworkTransaction::ThrottleCallback(
const net::CompletionCallback& callback,
int result,
int64_t bytes) {
@@ -92,7 +93,7 @@ void DevToolsNetworkTransaction::ThrottleCallback(
callback.Run(result);
}
-void DevToolsNetworkTransaction::Fail() {
+void ThrottlingNetworkTransaction::Fail() {
DCHECK(request_);
DCHECK(!failed_);
failed_ = true;
@@ -102,7 +103,7 @@ void DevToolsNetworkTransaction::Fail() {
interceptor_.reset();
}
-bool DevToolsNetworkTransaction::CheckFailed() {
+bool ThrottlingNetworkTransaction::CheckFailed() {
if (failed_)
return true;
if (interceptor_ && interceptor_->IsOffline()) {
@@ -112,9 +113,9 @@ bool DevToolsNetworkTransaction::CheckFailed() {
return false;
}
-int DevToolsNetworkTransaction::Start(const net::HttpRequestInfo* request,
- const net::CompletionCallback& callback,
- const net::NetLogWithSource& net_log) {
+int ThrottlingNetworkTransaction::Start(const net::HttpRequestInfo* request,
+ const net::CompletionCallback& callback,
+ const net::NetLogWithSource& net_log) {
DCHECK(request);
request_ = request;
@@ -130,15 +131,15 @@ int DevToolsNetworkTransaction::Start(const net::HttpRequestInfo* request,
if (request_->upload_data_stream) {
custom_upload_data_stream_.reset(
- new DevToolsNetworkUploadDataStream(request_->upload_data_stream));
+ new ThrottlingUploadDataStream(request_->upload_data_stream));
custom_request_->upload_data_stream = custom_upload_data_stream_.get();
}
request_ = custom_request_.get();
}
- DevToolsNetworkInterceptor* interceptor =
- DevToolsNetworkController::GetInterceptor(client_id);
+ ThrottlingNetworkInterceptor* interceptor =
+ ThrottlingController::GetInterceptor(client_id);
if (interceptor) {
interceptor_ = interceptor->GetWeakPtr();
if (custom_upload_data_stream_)
@@ -153,13 +154,13 @@ int DevToolsNetworkTransaction::Start(const net::HttpRequestInfo* request,
int result = network_transaction_->Start(
request_,
- base::Bind(&DevToolsNetworkTransaction::IOCallback,
+ base::Bind(&ThrottlingNetworkTransaction::IOCallback,
base::Unretained(this), callback, true),
net_log);
return Throttle(callback, true, result);
}
-int DevToolsNetworkTransaction::RestartIgnoringLastError(
+int ThrottlingNetworkTransaction::RestartIgnoringLastError(
const net::CompletionCallback& callback) {
if (CheckFailed())
return net::ERR_INTERNET_DISCONNECTED;
@@ -167,12 +168,12 @@ int DevToolsNetworkTransaction::RestartIgnoringLastError(
return network_transaction_->RestartIgnoringLastError(callback);
int result = network_transaction_->RestartIgnoringLastError(
- base::Bind(&DevToolsNetworkTransaction::IOCallback,
+ base::Bind(&ThrottlingNetworkTransaction::IOCallback,
base::Unretained(this), callback, true));
return Throttle(callback, true, result);
}
-int DevToolsNetworkTransaction::RestartWithCertificate(
+int ThrottlingNetworkTransaction::RestartWithCertificate(
scoped_refptr<net::X509Certificate> client_cert,
scoped_refptr<net::SSLPrivateKey> client_private_key,
const net::CompletionCallback& callback) {
@@ -185,12 +186,12 @@ int DevToolsNetworkTransaction::RestartWithCertificate(
int result = network_transaction_->RestartWithCertificate(
std::move(client_cert), std::move(client_private_key),
- base::Bind(&DevToolsNetworkTransaction::IOCallback,
+ base::Bind(&ThrottlingNetworkTransaction::IOCallback,
base::Unretained(this), callback, true));
return Throttle(callback, true, result);
}
-int DevToolsNetworkTransaction::RestartWithAuth(
+int ThrottlingNetworkTransaction::RestartWithAuth(
const net::AuthCredentials& credentials,
const net::CompletionCallback& callback) {
if (CheckFailed())
@@ -199,18 +200,19 @@ int DevToolsNetworkTransaction::RestartWithAuth(
return network_transaction_->RestartWithAuth(credentials, callback);
int result = network_transaction_->RestartWithAuth(
- credentials, base::Bind(&DevToolsNetworkTransaction::IOCallback,
+ credentials, base::Bind(&ThrottlingNetworkTransaction::IOCallback,
base::Unretained(this), callback, true));
return Throttle(callback, true, result);
}
-bool DevToolsNetworkTransaction::IsReadyToRestartForAuth() {
+bool ThrottlingNetworkTransaction::IsReadyToRestartForAuth() {
return network_transaction_->IsReadyToRestartForAuth();
}
-int DevToolsNetworkTransaction::Read(net::IOBuffer* buf,
- int buf_len,
- const net::CompletionCallback& callback) {
+int ThrottlingNetworkTransaction::Read(
+ net::IOBuffer* buf,
+ int buf_len,
+ const net::CompletionCallback& callback) {
if (CheckFailed())
return net::ERR_INTERNET_DISCONNECTED;
if (!interceptor_)
@@ -218,7 +220,7 @@ int DevToolsNetworkTransaction::Read(net::IOBuffer* buf,
int result = network_transaction_->Read(
buf, buf_len,
- base::Bind(&DevToolsNetworkTransaction::IOCallback,
+ base::Bind(&ThrottlingNetworkTransaction::IOCallback,
base::Unretained(this), callback, false));
// URLRequestJob relies on synchronous end-of-stream notification.
if (result == 0)
@@ -226,92 +228,92 @@ int DevToolsNetworkTransaction::Read(net::IOBuffer* buf,
return Throttle(callback, false, result);
}
-void DevToolsNetworkTransaction::StopCaching() {
+void ThrottlingNetworkTransaction::StopCaching() {
network_transaction_->StopCaching();
}
-bool DevToolsNetworkTransaction::GetFullRequestHeaders(
+bool ThrottlingNetworkTransaction::GetFullRequestHeaders(
net::HttpRequestHeaders* headers) const {
return network_transaction_->GetFullRequestHeaders(headers);
}
-int64_t DevToolsNetworkTransaction::GetTotalReceivedBytes() const {
+int64_t ThrottlingNetworkTransaction::GetTotalReceivedBytes() const {
return network_transaction_->GetTotalReceivedBytes();
}
-int64_t DevToolsNetworkTransaction::GetTotalSentBytes() const {
+int64_t ThrottlingNetworkTransaction::GetTotalSentBytes() const {
return network_transaction_->GetTotalSentBytes();
}
-void DevToolsNetworkTransaction::DoneReading() {
+void ThrottlingNetworkTransaction::DoneReading() {
network_transaction_->DoneReading();
}
-const net::HttpResponseInfo* DevToolsNetworkTransaction::GetResponseInfo()
+const net::HttpResponseInfo* ThrottlingNetworkTransaction::GetResponseInfo()
const {
return network_transaction_->GetResponseInfo();
}
-net::LoadState DevToolsNetworkTransaction::GetLoadState() const {
+net::LoadState ThrottlingNetworkTransaction::GetLoadState() const {
return network_transaction_->GetLoadState();
}
-void DevToolsNetworkTransaction::SetQuicServerInfo(
+void ThrottlingNetworkTransaction::SetQuicServerInfo(
net::QuicServerInfo* quic_server_info) {
network_transaction_->SetQuicServerInfo(quic_server_info);
}
-bool DevToolsNetworkTransaction::GetLoadTimingInfo(
+bool ThrottlingNetworkTransaction::GetLoadTimingInfo(
net::LoadTimingInfo* load_timing_info) const {
return network_transaction_->GetLoadTimingInfo(load_timing_info);
}
-bool DevToolsNetworkTransaction::GetRemoteEndpoint(
+bool ThrottlingNetworkTransaction::GetRemoteEndpoint(
net::IPEndPoint* endpoint) const {
return network_transaction_->GetRemoteEndpoint(endpoint);
}
-void DevToolsNetworkTransaction::PopulateNetErrorDetails(
+void ThrottlingNetworkTransaction::PopulateNetErrorDetails(
net::NetErrorDetails* details) const {
return network_transaction_->PopulateNetErrorDetails(details);
}
-void DevToolsNetworkTransaction::SetPriority(net::RequestPriority priority) {
+void ThrottlingNetworkTransaction::SetPriority(net::RequestPriority priority) {
network_transaction_->SetPriority(priority);
}
-void DevToolsNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper(
+void ThrottlingNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper(
net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) {
network_transaction_->SetWebSocketHandshakeStreamCreateHelper(create_helper);
}
-void DevToolsNetworkTransaction::SetBeforeNetworkStartCallback(
+void ThrottlingNetworkTransaction::SetBeforeNetworkStartCallback(
const BeforeNetworkStartCallback& callback) {
network_transaction_->SetBeforeNetworkStartCallback(callback);
}
-void DevToolsNetworkTransaction::SetRequestHeadersCallback(
+void ThrottlingNetworkTransaction::SetRequestHeadersCallback(
net::RequestHeadersCallback callback) {
network_transaction_->SetRequestHeadersCallback(std::move(callback));
}
-void DevToolsNetworkTransaction::SetResponseHeadersCallback(
+void ThrottlingNetworkTransaction::SetResponseHeadersCallback(
net::ResponseHeadersCallback callback) {
network_transaction_->SetResponseHeadersCallback(std::move(callback));
}
-void DevToolsNetworkTransaction::SetBeforeHeadersSentCallback(
+void ThrottlingNetworkTransaction::SetBeforeHeadersSentCallback(
const BeforeHeadersSentCallback& callback) {
network_transaction_->SetBeforeHeadersSentCallback(callback);
}
-int DevToolsNetworkTransaction::ResumeNetworkStart() {
+int ThrottlingNetworkTransaction::ResumeNetworkStart() {
if (CheckFailed())
return net::ERR_INTERNET_DISCONNECTED;
return network_transaction_->ResumeNetworkStart();
}
-void DevToolsNetworkTransaction::GetConnectionAttempts(
+void ThrottlingNetworkTransaction::GetConnectionAttempts(
net::ConnectionAttempts* out) const {
network_transaction_->GetConnectionAttempts(out);
}
diff --git a/chromium/content/common/devtools/devtools_network_transaction.h b/chromium/content/network/throttling/throttling_network_transaction.h
index eee12595878..d34ca067871 100644
--- a/chromium/content/common/devtools/devtools_network_transaction.h
+++ b/chromium/content/network/throttling/throttling_network_transaction.h
@@ -12,7 +12,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
-#include "content/common/devtools/devtools_network_interceptor.h"
+#include "content/network/throttling/throttling_network_interceptor.h"
#include "net/base/completion_callback.h"
#include "net/base/load_states.h"
#include "net/base/net_error_details.h"
@@ -33,23 +33,24 @@ class X509Certificate;
namespace content {
-class DevToolsNetworkController;
-class DevToolsNetworkControllerHelper;
-class DevToolsNetworkUploadDataStream;
+class ThrottlingController;
+class ThrottlingControllerHelper;
+class ThrottlingUploadDataStream;
-// DevToolsNetworkTransaction is a wrapper for network transaction. All
+// ThrottlingNetworkTransaction is a wrapper for network transaction. All
// HttpTransaction methods are proxied to real transaction, but |callback|
// parameter is saved and replaced with proxy callback. Fail method should be
// used to simulate network outage. It runs saved callback (if any) with
// net::ERR_INTERNET_DISCONNECTED result value.
-class CONTENT_EXPORT DevToolsNetworkTransaction : public net::HttpTransaction {
+class CONTENT_EXPORT ThrottlingNetworkTransaction
+ : public net::HttpTransaction {
public:
static const char kDevToolsEmulateNetworkConditionsClientId[];
- explicit DevToolsNetworkTransaction(
+ explicit ThrottlingNetworkTransaction(
std::unique_ptr<net::HttpTransaction> network_transaction);
- ~DevToolsNetworkTransaction() override;
+ ~ThrottlingNetworkTransaction() override;
// HttpTransaction methods:
int Start(const net::HttpRequestInfo* request,
@@ -93,7 +94,7 @@ class CONTENT_EXPORT DevToolsNetworkTransaction : public net::HttpTransaction {
void GetConnectionAttempts(net::ConnectionAttempts* out) const override;
protected:
- friend class content::DevToolsNetworkControllerHelper;
+ friend class content::ThrottlingControllerHelper;
private:
void Fail();
@@ -107,14 +108,14 @@ class CONTENT_EXPORT DevToolsNetworkTransaction : public net::HttpTransaction {
int result,
int64_t bytes);
- DevToolsNetworkInterceptor::ThrottleCallback throttle_callback_;
+ ThrottlingNetworkInterceptor::ThrottleCallback throttle_callback_;
int64_t throttled_byte_count_;
- DevToolsNetworkController* controller_;
- base::WeakPtr<DevToolsNetworkInterceptor> interceptor_;
+ ThrottlingController* controller_;
+ base::WeakPtr<ThrottlingNetworkInterceptor> interceptor_;
// Modified upload data stream. Should be destructed after |custom_request_|.
- std::unique_ptr<DevToolsNetworkUploadDataStream> custom_upload_data_stream_;
+ std::unique_ptr<ThrottlingUploadDataStream> custom_upload_data_stream_;
// Modified request. Should be destructed after |network_transaction_|.
std::unique_ptr<net::HttpRequestInfo> custom_request_;
@@ -127,7 +128,7 @@ class CONTENT_EXPORT DevToolsNetworkTransaction : public net::HttpTransaction {
// True if Fail was already invoked.
bool failed_;
- DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkTransaction);
+ DISALLOW_COPY_AND_ASSIGN(ThrottlingNetworkTransaction);
};
} // namespace content
diff --git a/chromium/content/common/devtools/devtools_network_transaction_factory.cc b/chromium/content/network/throttling/throttling_network_transaction_factory.cc
index 7441c8be59e..c4762c70029 100644
--- a/chromium/content/common/devtools/devtools_network_transaction_factory.cc
+++ b/chromium/content/network/throttling/throttling_network_transaction_factory.cc
@@ -2,27 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/common/devtools/devtools_network_transaction_factory.h"
+#include "content/network/throttling/throttling_network_transaction_factory.h"
#include <set>
#include <string>
#include <utility>
-#include "content/common/devtools/devtools_network_controller.h"
-#include "content/common/devtools/devtools_network_transaction.h"
+#include "content/network/throttling/throttling_controller.h"
+#include "content/network/throttling/throttling_network_transaction.h"
#include "net/base/net_errors.h"
#include "net/http/http_network_layer.h"
#include "net/http/http_network_transaction.h"
namespace content {
-DevToolsNetworkTransactionFactory::DevToolsNetworkTransactionFactory(
+ThrottlingNetworkTransactionFactory::ThrottlingNetworkTransactionFactory(
net::HttpNetworkSession* session)
: network_layer_(new net::HttpNetworkLayer(session)) {}
-DevToolsNetworkTransactionFactory::~DevToolsNetworkTransactionFactory() {}
+ThrottlingNetworkTransactionFactory::~ThrottlingNetworkTransactionFactory() {}
-int DevToolsNetworkTransactionFactory::CreateTransaction(
+int ThrottlingNetworkTransactionFactory::CreateTransaction(
net::RequestPriority priority,
std::unique_ptr<net::HttpTransaction>* trans) {
std::unique_ptr<net::HttpTransaction> network_transaction;
@@ -30,15 +30,16 @@ int DevToolsNetworkTransactionFactory::CreateTransaction(
if (rv != net::OK) {
return rv;
}
- trans->reset(new DevToolsNetworkTransaction(std::move(network_transaction)));
+ trans->reset(
+ new ThrottlingNetworkTransaction(std::move(network_transaction)));
return net::OK;
}
-net::HttpCache* DevToolsNetworkTransactionFactory::GetCache() {
+net::HttpCache* ThrottlingNetworkTransactionFactory::GetCache() {
return network_layer_->GetCache();
}
-net::HttpNetworkSession* DevToolsNetworkTransactionFactory::GetSession() {
+net::HttpNetworkSession* ThrottlingNetworkTransactionFactory::GetSession() {
return network_layer_->GetSession();
}
diff --git a/chromium/content/common/devtools/devtools_network_transaction_factory.h b/chromium/content/network/throttling/throttling_network_transaction_factory.h
index 5929ed3dcab..7e5a38bb5fb 100644
--- a/chromium/content/common/devtools/devtools_network_transaction_factory.h
+++ b/chromium/content/network/throttling/throttling_network_transaction_factory.h
@@ -20,10 +20,11 @@ class HttpTransaction;
namespace content {
// NetworkTransactionFactory wraps HttpNetworkTransactions.
-class DevToolsNetworkTransactionFactory : public net::HttpTransactionFactory {
+class ThrottlingNetworkTransactionFactory : public net::HttpTransactionFactory {
public:
- explicit DevToolsNetworkTransactionFactory(net::HttpNetworkSession* session);
- ~DevToolsNetworkTransactionFactory() override;
+ explicit ThrottlingNetworkTransactionFactory(
+ net::HttpNetworkSession* session);
+ ~ThrottlingNetworkTransactionFactory() override;
// net::HttpTransactionFactory methods:
int CreateTransaction(net::RequestPriority priority,
@@ -34,7 +35,7 @@ class DevToolsNetworkTransactionFactory : public net::HttpTransactionFactory {
private:
std::unique_ptr<net::HttpTransactionFactory> network_layer_;
- DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkTransactionFactory);
+ DISALLOW_COPY_AND_ASSIGN(ThrottlingNetworkTransactionFactory);
};
} // namespace content
diff --git a/chromium/content/common/devtools/devtools_network_upload_data_stream.cc b/chromium/content/network/throttling/throttling_upload_data_stream.cc
index 73a745dcca2..4e0d1b9019a 100644
--- a/chromium/content/common/devtools/devtools_network_upload_data_stream.cc
+++ b/chromium/content/network/throttling/throttling_upload_data_stream.cc
@@ -2,43 +2,43 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/common/devtools/devtools_network_upload_data_stream.h"
+#include "content/network/throttling/throttling_upload_data_stream.h"
#include "net/base/net_errors.h"
namespace content {
-DevToolsNetworkUploadDataStream::DevToolsNetworkUploadDataStream(
+ThrottlingUploadDataStream::ThrottlingUploadDataStream(
net::UploadDataStream* upload_data_stream)
: net::UploadDataStream(upload_data_stream->is_chunked(),
upload_data_stream->identifier()),
throttle_callback_(
- base::Bind(&DevToolsNetworkUploadDataStream::ThrottleCallback,
+ base::Bind(&ThrottlingUploadDataStream::ThrottleCallback,
base::Unretained(this))),
throttled_byte_count_(0),
upload_data_stream_(upload_data_stream) {}
-DevToolsNetworkUploadDataStream::~DevToolsNetworkUploadDataStream() {
+ThrottlingUploadDataStream::~ThrottlingUploadDataStream() {
if (interceptor_)
interceptor_->StopThrottle(throttle_callback_);
}
-void DevToolsNetworkUploadDataStream::SetInterceptor(
- DevToolsNetworkInterceptor* interceptor) {
+void ThrottlingUploadDataStream::SetInterceptor(
+ ThrottlingNetworkInterceptor* interceptor) {
DCHECK(!interceptor_);
if (interceptor)
interceptor_ = interceptor->GetWeakPtr();
}
-bool DevToolsNetworkUploadDataStream::IsInMemory() const {
+bool ThrottlingUploadDataStream::IsInMemory() const {
return false;
}
-int DevToolsNetworkUploadDataStream::InitInternal(
+int ThrottlingUploadDataStream::InitInternal(
const net::NetLogWithSource& net_log) {
throttled_byte_count_ = 0;
int result = upload_data_stream_->Init(
- base::Bind(&DevToolsNetworkUploadDataStream::StreamInitCallback,
+ base::Bind(&ThrottlingUploadDataStream::StreamInitCallback,
base::Unretained(this)),
net_log);
if (result == net::OK && !is_chunked())
@@ -46,28 +46,27 @@ int DevToolsNetworkUploadDataStream::InitInternal(
return result;
}
-void DevToolsNetworkUploadDataStream::StreamInitCallback(int result) {
+void ThrottlingUploadDataStream::StreamInitCallback(int result) {
if (!is_chunked())
SetSize(upload_data_stream_->size());
OnInitCompleted(result);
}
-int DevToolsNetworkUploadDataStream::ReadInternal(net::IOBuffer* buf,
- int buf_len) {
+int ThrottlingUploadDataStream::ReadInternal(net::IOBuffer* buf, int buf_len) {
int result = upload_data_stream_->Read(
buf, buf_len,
- base::Bind(&DevToolsNetworkUploadDataStream::StreamReadCallback,
+ base::Bind(&ThrottlingUploadDataStream::StreamReadCallback,
base::Unretained(this)));
return ThrottleRead(result);
}
-void DevToolsNetworkUploadDataStream::StreamReadCallback(int result) {
+void ThrottlingUploadDataStream::StreamReadCallback(int result) {
result = ThrottleRead(result);
if (result != net::ERR_IO_PENDING)
OnReadCompleted(result);
}
-int DevToolsNetworkUploadDataStream::ThrottleRead(int result) {
+int ThrottlingUploadDataStream::ThrottleRead(int result) {
if (is_chunked() && upload_data_stream_->IsEOF())
SetIsFinalChunk();
@@ -81,13 +80,12 @@ int DevToolsNetworkUploadDataStream::ThrottleRead(int result) {
throttle_callback_);
}
-void DevToolsNetworkUploadDataStream::ThrottleCallback(int result,
- int64_t bytes) {
+void ThrottlingUploadDataStream::ThrottleCallback(int result, int64_t bytes) {
throttled_byte_count_ = bytes;
OnReadCompleted(result);
}
-void DevToolsNetworkUploadDataStream::ResetInternal() {
+void ThrottlingUploadDataStream::ResetInternal() {
upload_data_stream_->Reset();
throttled_byte_count_ = 0;
if (interceptor_)
diff --git a/chromium/content/common/devtools/devtools_network_upload_data_stream.h b/chromium/content/network/throttling/throttling_upload_data_stream.h
index 3c638e4ba4c..18adb63afba 100644
--- a/chromium/content/common/devtools/devtools_network_upload_data_stream.h
+++ b/chromium/content/network/throttling/throttling_upload_data_stream.h
@@ -2,31 +2,31 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_UPLOAD_DATA_STREAM_H_
-#define CONTENT_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_UPLOAD_DATA_STREAM_H_
+#ifndef CONTENT_NETWORK_THROTTLING_THROTTLING_UPLOAD_DATA_STREAM_H_
+#define CONTENT_NETWORK_THROTTLING_THROTTLING_UPLOAD_DATA_STREAM_H_
#include <stdint.h>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "content/common/devtools/devtools_network_interceptor.h"
+#include "content/network/throttling/throttling_network_interceptor.h"
#include "net/base/completion_callback.h"
#include "net/base/upload_data_stream.h"
namespace content {
-class DevToolsNetworkInterceptor;
+class ThrottlingNetworkInterceptor;
-// DevToolsNetworkUploadData is a wrapper for upload data stream, which proxies
+// ThrottlingUploadData is a wrapper for upload data stream, which proxies
// methods and throttles after the original method succeeds.
-class DevToolsNetworkUploadDataStream : public net::UploadDataStream {
+class ThrottlingUploadDataStream : public net::UploadDataStream {
public:
// Supplied |upload_data_stream| must outlive this object.
- explicit DevToolsNetworkUploadDataStream(
+ explicit ThrottlingUploadDataStream(
net::UploadDataStream* upload_data_stream);
- ~DevToolsNetworkUploadDataStream() override;
+ ~ThrottlingUploadDataStream() override;
- void SetInterceptor(DevToolsNetworkInterceptor* interceptor);
+ void SetInterceptor(ThrottlingNetworkInterceptor* interceptor);
private:
// net::UploadDataStream implementation.
@@ -41,15 +41,15 @@ class DevToolsNetworkUploadDataStream : public net::UploadDataStream {
int ThrottleRead(int result);
void ThrottleCallback(int result, int64_t bytes);
- DevToolsNetworkInterceptor::ThrottleCallback throttle_callback_;
+ ThrottlingNetworkInterceptor::ThrottleCallback throttle_callback_;
int64_t throttled_byte_count_;
net::UploadDataStream* upload_data_stream_;
- base::WeakPtr<DevToolsNetworkInterceptor> interceptor_;
+ base::WeakPtr<ThrottlingNetworkInterceptor> interceptor_;
- DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkUploadDataStream);
+ DISALLOW_COPY_AND_ASSIGN(ThrottlingUploadDataStream);
};
} // namespace content
-#endif // CONTENT_COMMON_DEVTOOLS_DEVTOOLS_NETWORK_UPLOAD_DATA_STREAM_H_
+#endif // CONTENT_NETWORK_THROTTLING_THROTTLING_UPLOAD_DATA_STREAM_H_
diff --git a/chromium/content/browser/loader/upload_progress_tracker.cc b/chromium/content/network/upload_progress_tracker.cc
index 603281b70a5..353d3d20be0 100644
--- a/chromium/content/browser/loader/upload_progress_tracker.cc
+++ b/chromium/content/network/upload_progress_tracker.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/browser/loader/upload_progress_tracker.h"
+#include "content/network/upload_progress_tracker.h"
#include "base/logging.h"
#include "net/base/upload_progress.h"
diff --git a/chromium/content/browser/loader/upload_progress_tracker.h b/chromium/content/network/upload_progress_tracker.h
index 8cf239d26b3..a14522b4bdc 100644
--- a/chromium/content/browser/loader/upload_progress_tracker.h
+++ b/chromium/content/network/upload_progress_tracker.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_LOADER_UPLOAD_PROGRESS_TRACKER_H_
-#define CONTENT_BROWSER_LOADER_UPLOAD_PROGRESS_TRACKER_H_
+#ifndef CONTENT_NETWORK_UPLOAD_PROGRESS_TRACKER_H_
+#define CONTENT_NETWORK_UPLOAD_PROGRESS_TRACKER_H_
#include <stdint.h>
@@ -67,4 +67,4 @@ class CONTENT_EXPORT UploadProgressTracker {
} // namespace content
-#endif // CONTENT_BROWSER_LOADER_UPLOAD_PROGRESS_TRACKER_H_
+#endif // CONTENT_NETWORK_UPLOAD_PROGRESS_TRACKER_H_
diff --git a/chromium/content/browser/loader/upload_progress_tracker_unittest.cc b/chromium/content/network/upload_progress_tracker_unittest.cc
index b5323e0641a..4ddf503c6e1 100644
--- a/chromium/content/browser/loader/upload_progress_tracker_unittest.cc
+++ b/chromium/content/network/upload_progress_tracker_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 "content/browser/loader/upload_progress_tracker.h"
+#include "content/network/upload_progress_tracker.h"
#include "base/bind.h"
#include "base/location.h"
@@ -276,4 +276,4 @@ TEST_F(UploadProgressTrackerTest, Completed) {
EXPECT_FALSE(mock_task_runner_->HasPendingTask());
}
-} // namespace context
+} // namespace content
diff --git a/chromium/content/network/url_loader_impl.cc b/chromium/content/network/url_loader.cc
index fb6a8e028df..536cec49eef 100644
--- a/chromium/content/network/url_loader_impl.cc
+++ b/chromium/content/network/url_loader.cc
@@ -2,24 +2,30 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/network/url_loader_impl.h"
+#include "content/network/url_loader.h"
#include <string>
+#include "base/files/file.h"
+#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "content/common/loader_util.h"
#include "content/network/network_context.h"
+#include "content/network/network_service_impl.h"
#include "content/public/common/referrer.h"
+#include "content/public/common/resource_request.h"
+#include "content/public/common/resource_request_body.h"
#include "content/public/common/resource_response.h"
#include "content/public/common/url_loader_factory.mojom.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
#include "net/base/elements_upload_data_stream.h"
-#include "net/base/load_flags.h"
#include "net/base/mime_sniffer.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_file_element_reader.h"
+#include "net/cert/symantec_certs.h"
#include "net/url_request/url_request_context.h"
#include "services/network/public/cpp/net_adapters.h"
@@ -28,31 +34,10 @@ namespace content {
namespace {
constexpr size_t kDefaultAllocationSize = 512 * 1024;
-// TODO: this duplicates ResourceDispatcherHostImpl::BuildLoadFlagsForRequest.
-int BuildLoadFlagsForRequest(const ResourceRequest& request,
- bool is_sync_load) {
- int load_flags = request.load_flags;
-
- // Although EV status is irrelevant to sub-frames and sub-resources, we have
- // to perform EV certificate verification on all resources because an HTTP
- // keep-alive connection created to load a sub-frame or a sub-resource could
- // be reused to load a main frame.
- load_flags |= net::LOAD_VERIFY_EV_CERT;
- if (request.resource_type == RESOURCE_TYPE_MAIN_FRAME) {
- load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED;
- } else if (request.resource_type == RESOURCE_TYPE_PREFETCH) {
- load_flags |= net::LOAD_PREFETCH;
- }
-
- if (is_sync_load)
- load_flags |= net::LOAD_IGNORE_LIMITS;
-
- return load_flags;
-}
-
// TODO: this duplicates some of PopulateResourceResponse in
// content/browser/loader/resource_loader.cc
void PopulateResourceResponse(net::URLRequest* request,
+ bool is_load_timing_enabled,
ResourceResponse* response) {
response->head.request_time = request->request_time();
response->head.response_time = request->response_time();
@@ -71,7 +56,20 @@ void PopulateResourceResponse(net::URLRequest* request,
response->head.effective_connection_type =
net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
- request->GetLoadTimingInfo(&response->head.load_timing);
+ if (is_load_timing_enabled)
+ request->GetLoadTimingInfo(&response->head.load_timing);
+
+ if (request->ssl_info().cert.get()) {
+ response->head.has_major_certificate_errors =
+ net::IsCertStatusError(request->ssl_info().cert_status) &&
+ !net::IsCertStatusMinorError(request->ssl_info().cert_status);
+ response->head.is_legacy_symantec_cert =
+ !response->head.has_major_certificate_errors &&
+ net::IsLegacySymantecCert(request->ssl_info().public_key_hashes);
+ response->head.cert_validity_start =
+ request->ssl_info().cert->valid_start();
+ response->head.cert_status = request->ssl_info().cert_status;
+ }
response->head.request_start = request->creation_time();
response->head.response_start = base::TimeTicks::Now();
@@ -123,6 +121,134 @@ class FileElementReader : public net::UploadFileElementReader {
DISALLOW_COPY_AND_ASSIGN(FileElementReader);
};
+class RawFileElementReader : public net::UploadFileElementReader {
+ public:
+ RawFileElementReader(ResourceRequestBody* resource_request_body,
+ base::TaskRunner* task_runner,
+ const ResourceRequestBody::Element& element)
+ : net::UploadFileElementReader(
+ task_runner,
+ // TODO(mmenke): Is duplicating this necessary?
+ element.file().Duplicate(),
+ element.path(),
+ element.offset(),
+ element.length(),
+ element.expected_modification_time()),
+ resource_request_body_(resource_request_body) {
+ DCHECK_EQ(ResourceRequestBody::Element::TYPE_RAW_FILE, element.type());
+ }
+
+ ~RawFileElementReader() override {}
+
+ private:
+ scoped_refptr<ResourceRequestBody> resource_request_body_;
+
+ DISALLOW_COPY_AND_ASSIGN(RawFileElementReader);
+};
+
+// A subclass of net::UploadElementReader to read data pipes.
+class DataPipeElementReader : public net::UploadElementReader {
+ public:
+ DataPipeElementReader(
+ scoped_refptr<ResourceRequestBody> resource_request_body,
+ network::mojom::DataPipeGetterPtr data_pipe_getter_)
+ : resource_request_body_(std::move(resource_request_body)),
+ data_pipe_getter_(std::move(data_pipe_getter_)),
+ handle_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL),
+ weak_factory_(this) {}
+
+ ~DataPipeElementReader() override {}
+
+ private:
+ void ReadCallback(int32_t status, uint64_t size) {
+ if (status == net::OK)
+ size_ = size;
+ if (!init_callback_.is_null())
+ std::move(init_callback_).Run(status);
+ }
+
+ void OnHandleReadable(MojoResult result) {
+ if (result == MOJO_RESULT_OK) {
+ int read = Read(buf_.get(), buf_length_, net::CompletionCallback());
+ DCHECK_GT(read, 0);
+ std::move(read_callback_).Run(read);
+ } else {
+ std::move(read_callback_).Run(net::ERR_FAILED);
+ }
+ buf_ = nullptr;
+ buf_length_ = 0;
+ }
+
+ // net::UploadElementReader implementation:
+ int Init(const net::CompletionCallback& callback) override {
+ // Init rewinds the stream. Throw away current state.
+ if (!read_callback_.is_null())
+ std::move(read_callback_).Run(net::ERR_FAILED);
+ buf_ = nullptr;
+ buf_length_ = 0;
+ handle_watcher_.Cancel();
+ size_ = 0;
+ bytes_read_ = 0;
+
+ // Get a new data pipe and start.
+ mojo::DataPipe data_pipe;
+ data_pipe_getter_->Read(std::move(data_pipe.producer_handle),
+ base::BindOnce(&DataPipeElementReader::ReadCallback,
+ weak_factory_.GetWeakPtr()));
+ data_pipe_ = std::move(data_pipe.consumer_handle);
+ handle_watcher_.Watch(data_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE,
+ base::Bind(&DataPipeElementReader::OnHandleReadable,
+ base::Unretained(this)));
+
+ init_callback_ = std::move(callback);
+ return net::ERR_IO_PENDING;
+ }
+
+ uint64_t GetContentLength() const override { return size_; }
+
+ uint64_t BytesRemaining() const override { return size_ - bytes_read_; }
+
+ int Read(net::IOBuffer* buf,
+ int buf_length,
+ const net::CompletionCallback& callback) override {
+ if (!BytesRemaining())
+ return net::OK;
+
+ uint32_t num_bytes = buf_length;
+ MojoResult rv =
+ data_pipe_->ReadData(buf->data(), &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+ if (rv == MOJO_RESULT_OK) {
+ bytes_read_ += num_bytes;
+ return num_bytes;
+ }
+
+ if (rv == MOJO_RESULT_SHOULD_WAIT) {
+ buf_ = buf;
+ buf_length_ = buf_length;
+ handle_watcher_.ArmOrNotify();
+ read_callback_ = std::move(callback);
+ return net::ERR_IO_PENDING;
+ }
+
+ return net::ERR_FAILED;
+ }
+
+ scoped_refptr<ResourceRequestBody> resource_request_body_;
+ network::mojom::DataPipeGetterPtr data_pipe_getter_;
+ mojo::ScopedDataPipeConsumerHandle data_pipe_;
+ mojo::SimpleWatcher handle_watcher_;
+ scoped_refptr<net::IOBuffer> buf_;
+ int buf_length_ = 0;
+ uint64_t size_ = 0;
+ uint64_t bytes_read_ = 0;
+ net::CompletionCallback init_callback_;
+ net::CompletionCallback read_callback_;
+
+ base::WeakPtrFactory<DataPipeElementReader> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(DataPipeElementReader);
+};
+
// TODO: copied from content/browser/loader/upload_data_stream_builder.cc.
std::unique_ptr<net::UploadDataStream> CreateUploadDataStream(
ResourceRequestBody* body,
@@ -132,17 +258,27 @@ std::unique_ptr<net::UploadDataStream> CreateUploadDataStream(
switch (element.type()) {
case ResourceRequestBody::Element::TYPE_BYTES:
element_readers.push_back(
- base::MakeUnique<BytesElementReader>(body, element));
+ std::make_unique<BytesElementReader>(body, element));
break;
case ResourceRequestBody::Element::TYPE_FILE:
- element_readers.push_back(base::MakeUnique<FileElementReader>(
+ element_readers.push_back(std::make_unique<FileElementReader>(
+ body, file_task_runner, element));
+ break;
+ case ResourceRequestBody::Element::TYPE_RAW_FILE:
+ element_readers.push_back(std::make_unique<RawFileElementReader>(
body, file_task_runner, element));
break;
case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM:
- NOTIMPLEMENTED();
+ CHECK(false) << "Should never be reached";
break;
case ResourceRequestBody::Element::TYPE_BLOB: {
- NOTIMPLEMENTED();
+ CHECK(false) << "Network service always uses DATA_PIPE for blobs.";
+ break;
+ }
+ case ResourceRequestBody::Element::TYPE_DATA_PIPE: {
+ element_readers.push_back(std::make_unique<DataPipeElementReader>(
+ body, const_cast<storage::DataElement*>(&element)
+ ->ReleaseDataPipeGetter()));
break;
}
case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
@@ -153,22 +289,26 @@ std::unique_ptr<net::UploadDataStream> CreateUploadDataStream(
}
}
- return base::MakeUnique<net::ElementsUploadDataStream>(
+ return std::make_unique<net::ElementsUploadDataStream>(
std::move(element_readers), body->identifier());
}
} // namespace
-URLLoaderImpl::URLLoaderImpl(
- NetworkContext* context,
- mojom::URLLoaderRequest url_loader_request,
- int32_t options,
- const ResourceRequest& request,
- bool report_raw_headers,
- mojom::URLLoaderClientPtr url_loader_client,
- const net::NetworkTrafficAnnotationTag& traffic_annotation)
+URLLoader::URLLoader(NetworkContext* context,
+ mojom::URLLoaderRequest url_loader_request,
+ int32_t options,
+ const ResourceRequest& request,
+ bool report_raw_headers,
+ mojom::URLLoaderClientPtr url_loader_client,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation,
+ uint32_t process_id)
: context_(context),
options_(options),
+ resource_type_(request.resource_type),
+ is_load_timing_enabled_(request.enable_load_timing),
+ process_id_(process_id),
+ render_frame_id_(request.render_frame_id),
connected_(true),
binding_(this, std::move(url_loader_request)),
url_loader_client_(std::move(url_loader_client)),
@@ -179,8 +319,8 @@ URLLoaderImpl::URLLoaderImpl(
report_raw_headers_(report_raw_headers),
weak_ptr_factory_(this) {
context_->RegisterURLLoader(this);
- binding_.set_connection_error_handler(base::BindOnce(
- &URLLoaderImpl::OnConnectionError, base::Unretained(this)));
+ binding_.set_connection_error_handler(
+ base::BindOnce(&URLLoader::OnConnectionError, base::Unretained(this)));
url_request_ = context_->url_request_context()->CreateRequest(
GURL(request.url), net::DEFAULT_PRIORITY, this, traffic_annotation);
@@ -200,6 +340,23 @@ URLLoaderImpl::URLLoaderImpl(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE});
url_request_->set_upload(
CreateUploadDataStream(request.request_body.get(), task_runner.get()));
+
+ if (request.enable_upload_progress) {
+ upload_progress_tracker_ = std::make_unique<UploadProgressTracker>(
+ FROM_HERE,
+ base::BindRepeating(&URLLoader::SendUploadProgress,
+ base::Unretained(this)),
+ url_request_.get());
+ }
+ }
+
+ url_request_->set_initiator(request.request_initiator);
+
+ // TODO(qinmin): network service shouldn't know about resource type, need
+ // to introduce another field to set this.
+ if (request.resource_type == RESOURCE_TYPE_MAIN_FRAME) {
+ url_request_->set_first_party_url_policy(
+ net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);
}
int load_flags = BuildLoadFlagsForRequest(request, false);
@@ -208,13 +365,16 @@ URLLoaderImpl::URLLoaderImpl(
url_request_->SetRequestHeadersCallback(
base::Bind(&net::HttpRawRequestHeaders::Assign,
base::Unretained(&raw_request_headers_)));
- url_request_->SetResponseHeadersCallback(base::Bind(
- &URLLoaderImpl::SetRawResponseHeaders, base::Unretained(this)));
+ url_request_->SetResponseHeadersCallback(
+ base::Bind(&URLLoader::SetRawResponseHeaders, base::Unretained(this)));
}
+
+ AttachAcceptHeader(request.resource_type, url_request_.get());
+
url_request_->Start();
}
-URLLoaderImpl::~URLLoaderImpl() {
+URLLoader::~URLLoader() {
context_->DeregisterURLLoader(this);
if (update_body_read_before_paused_)
@@ -232,13 +392,13 @@ URLLoaderImpl::~URLLoaderImpl() {
}
}
-void URLLoaderImpl::Cleanup() {
+void URLLoader::Cleanup() {
// The associated network context is going away and we have to destroy
// net::URLRequest held by this loader.
delete this;
}
-void URLLoaderImpl::FollowRedirect() {
+void URLLoader::FollowRedirect() {
if (!url_request_) {
NotifyCompleted(net::ERR_UNEXPECTED);
// |this| may have been deleted.
@@ -248,13 +408,13 @@ void URLLoaderImpl::FollowRedirect() {
url_request_->FollowDeferredRedirect();
}
-void URLLoaderImpl::SetPriority(net::RequestPriority priority,
- int32_t intra_priority_value) {
+void URLLoader::SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) {
NOTIMPLEMENTED();
}
-void URLLoaderImpl::PauseReadingBodyFromNet() {
- DVLOG(1) << "URLLoaderImpl pauses fetching response body for "
+void URLLoader::PauseReadingBodyFromNet() {
+ DVLOG(1) << "URLLoader pauses fetching response body for "
<< (url_request_ ? url_request_->original_url().spec()
: "a URL that has completed loading or failed.");
// Please note that we pause reading body in all cases. Even if the URL
@@ -274,8 +434,8 @@ void URLLoaderImpl::PauseReadingBodyFromNet() {
}
}
-void URLLoaderImpl::ResumeReadingBodyFromNet() {
- DVLOG(1) << "URLLoaderImpl resumes fetching response body for "
+void URLLoader::ResumeReadingBodyFromNet() {
+ DVLOG(1) << "URLLoader resumes fetching response body for "
<< (url_request_ ? url_request_->original_url().spec()
: "a URL that has completed loading or failed.");
should_pause_reading_body_ = false;
@@ -286,9 +446,9 @@ void URLLoaderImpl::ResumeReadingBodyFromNet() {
}
}
-void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request,
- const net::RedirectInfo& redirect_info,
- bool* defer_redirect) {
+void URLLoader::OnReceivedRedirect(net::URLRequest* url_request,
+ const net::RedirectInfo& redirect_info,
+ bool* defer_redirect) {
DCHECK(url_request == url_request_.get());
DCHECK(url_request->status().is_success());
@@ -297,7 +457,8 @@ void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request,
*defer_redirect = true;
scoped_refptr<ResourceResponse> response = new ResourceResponse();
- PopulateResourceResponse(url_request_.get(), response.get());
+ PopulateResourceResponse(url_request_.get(), is_load_timing_enabled_,
+ response.get());
if (report_raw_headers_) {
response->head.devtools_info = BuildDevToolsInfo(
*url_request_, raw_request_headers_, raw_response_headers_.get());
@@ -307,8 +468,34 @@ void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request,
url_loader_client_->OnReceiveRedirect(redirect_info, response->head);
}
-void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request,
- int net_error) {
+void URLLoader::OnAuthRequired(net::URLRequest* unused,
+ net::AuthChallengeInfo* auth_info) {
+ NOTIMPLEMENTED() << "http://crbug.com/756654";
+ net::URLRequest::Delegate::OnAuthRequired(unused, auth_info);
+}
+
+void URLLoader::OnCertificateRequested(net::URLRequest* unused,
+ net::SSLCertRequestInfo* cert_info) {
+ NOTIMPLEMENTED() << "http://crbug.com/756654";
+ net::URLRequest::Delegate::OnCertificateRequested(unused, cert_info);
+}
+
+void URLLoader::OnSSLCertificateError(net::URLRequest* request,
+ const net::SSLInfo& ssl_info,
+ bool fatal) {
+ // The network service can be null in tests.
+ if (!context_->network_service()) {
+ OnSSLCertificateErrorResponse(ssl_info, net::ERR_INSECURE_RESPONSE);
+ return;
+ }
+ context_->network_service()->client()->OnSSLCertificateError(
+ resource_type_, url_request_->url(), process_id_, render_frame_id_,
+ ssl_info, fatal,
+ base::Bind(&URLLoader::OnSSLCertificateErrorResponse,
+ weak_ptr_factory_.GetWeakPtr(), ssl_info));
+}
+
+void URLLoader::OnResponseStarted(net::URLRequest* url_request, int net_error) {
DCHECK(url_request == url_request_.get());
if (net_error != net::OK) {
@@ -317,8 +504,14 @@ void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request,
return;
}
+ if (upload_progress_tracker_) {
+ upload_progress_tracker_->OnUploadCompleted();
+ upload_progress_tracker_ = nullptr;
+ }
+
response_ = new ResourceResponse();
- PopulateResourceResponse(url_request_.get(), response_.get());
+ PopulateResourceResponse(url_request_.get(), is_load_timing_enabled_,
+ response_.get());
if (report_raw_headers_) {
response_->head.devtools_info = BuildDevToolsInfo(
*url_request_, raw_request_headers_, raw_response_headers_.get());
@@ -333,13 +526,13 @@ void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request,
consumer_handle_ = std::move(data_pipe.consumer_handle);
peer_closed_handle_watcher_.Watch(
response_body_stream_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- base::Bind(&URLLoaderImpl::OnResponseBodyStreamConsumerClosed,
+ base::Bind(&URLLoader::OnResponseBodyStreamConsumerClosed,
base::Unretained(this)));
peer_closed_handle_watcher_.ArmOrNotify();
writable_handle_watcher_.Watch(
response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
- base::Bind(&URLLoaderImpl::OnResponseBodyStreamReady,
+ base::Bind(&URLLoader::OnResponseBodyStreamReady,
base::Unretained(this)));
if (!(options_ & mojom::kURLLoadOptionSniffMimeType) ||
@@ -350,7 +543,7 @@ void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request,
ReadMore();
}
-void URLLoaderImpl::ReadMore() {
+void URLLoader::ReadMore() {
// Once the MIME type is sniffed, all data is sent as soon as it is read from
// the network.
DCHECK(consumer_handle_.is_valid() || !pending_write_);
@@ -400,7 +593,7 @@ void URLLoaderImpl::ReadMore() {
}
}
-void URLLoaderImpl::DidRead(int num_bytes, bool completed_synchronously) {
+void URLLoader::DidRead(int num_bytes, bool completed_synchronously) {
if (num_bytes > 0)
pending_write_buffer_offset_ += num_bytes;
if (update_body_read_before_paused_) {
@@ -441,53 +634,64 @@ void URLLoaderImpl::DidRead(int num_bytes, bool completed_synchronously) {
}
if (completed_synchronously) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&URLLoaderImpl::ReadMore,
- weak_ptr_factory_.GetWeakPtr()));
+ FROM_HERE,
+ base::BindOnce(&URLLoader::ReadMore, weak_ptr_factory_.GetWeakPtr()));
} else {
ReadMore();
}
}
-void URLLoaderImpl::OnReadCompleted(net::URLRequest* url_request,
- int bytes_read) {
+void URLLoader::OnReadCompleted(net::URLRequest* url_request, int bytes_read) {
DCHECK(url_request == url_request_.get());
DidRead(bytes_read, false);
// |this| may have been deleted.
}
-base::WeakPtr<URLLoaderImpl> URLLoaderImpl::GetWeakPtrForTests() {
+base::WeakPtr<URLLoader> URLLoader::GetWeakPtrForTests() {
return weak_ptr_factory_.GetWeakPtr();
}
-void URLLoaderImpl::NotifyCompleted(int error_code) {
+void URLLoader::NotifyCompleted(int error_code) {
+ // Ensure sending the final upload progress message here, since
+ // OnResponseCompleted can be called without OnResponseStarted on cancellation
+ // or error cases.
+ if (upload_progress_tracker_) {
+ upload_progress_tracker_->OnUploadCompleted();
+ upload_progress_tracker_ = nullptr;
+ }
+
if (consumer_handle_.is_valid())
SendResponseToClient();
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = error_code;
- request_complete_data.exists_in_cache =
- url_request_->response_info().was_cached;
- request_complete_data.completion_time = base::TimeTicks::Now();
- request_complete_data.encoded_data_length =
- url_request_->GetTotalReceivedBytes();
- request_complete_data.encoded_body_length = url_request_->GetRawBodyBytes();
- request_complete_data.decoded_body_length = total_written_bytes_;
-
- url_loader_client_->OnComplete(request_complete_data);
+ network::URLLoaderCompletionStatus status;
+ status.error_code = error_code;
+ status.exists_in_cache = url_request_->response_info().was_cached;
+ status.completion_time = base::TimeTicks::Now();
+ status.encoded_data_length = url_request_->GetTotalReceivedBytes();
+ status.encoded_body_length = url_request_->GetRawBodyBytes();
+ status.decoded_body_length = total_written_bytes_;
+
+ if ((options_ & mojom::kURLLoadOptionSendSSLInfoForCertificateError) &&
+ net::IsCertStatusError(url_request_->ssl_info().cert_status) &&
+ !net::IsCertStatusMinorError(url_request_->ssl_info().cert_status)) {
+ status.ssl_info = url_request_->ssl_info();
+ }
+
+ url_loader_client_->OnComplete(status);
DeleteIfNeeded();
}
-void URLLoaderImpl::OnConnectionError() {
+void URLLoader::OnConnectionError() {
connected_ = false;
DeleteIfNeeded();
}
-void URLLoaderImpl::OnResponseBodyStreamConsumerClosed(MojoResult result) {
+void URLLoader::OnResponseBodyStreamConsumerClosed(MojoResult result) {
CloseResponseBodyStreamProducer();
}
-void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) {
+void URLLoader::OnResponseBodyStreamReady(MojoResult result) {
if (result != MOJO_RESULT_OK) {
CloseResponseBodyStreamProducer();
return;
@@ -496,7 +700,7 @@ void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) {
ReadMore();
}
-void URLLoaderImpl::CloseResponseBodyStreamProducer() {
+void URLLoader::CloseResponseBodyStreamProducer() {
url_request_.reset();
peer_closed_handle_watcher_.Cancel();
writable_handle_watcher_.Cancel();
@@ -514,15 +718,15 @@ void URLLoaderImpl::CloseResponseBodyStreamProducer() {
DeleteIfNeeded();
}
-void URLLoaderImpl::DeleteIfNeeded() {
+void URLLoader::DeleteIfNeeded() {
bool has_data_pipe = pending_write_.get() || response_body_stream_.is_valid();
if (!connected_ && !has_data_pipe)
delete this;
}
-void URLLoaderImpl::SendResponseToClient() {
+void URLLoader::SendResponseToClient() {
base::Optional<net::SSLInfo> ssl_info;
- if (options_ & mojom::kURLLoadOptionSendSSLInfo)
+ if (options_ & mojom::kURLLoadOptionSendSSLInfoWithResponse)
ssl_info = url_request_->ssl_info();
mojom::DownloadedTempFilePtr downloaded_file_ptr;
url_loader_client_->OnReceiveResponse(response_->head, ssl_info,
@@ -541,7 +745,7 @@ void URLLoaderImpl::SendResponseToClient() {
response_ = nullptr;
}
-void URLLoaderImpl::CompletePendingWrite() {
+void URLLoader::CompletePendingWrite() {
response_body_stream_ =
pending_write_->Complete(pending_write_buffer_offset_);
total_written_bytes_ += pending_write_buffer_offset_;
@@ -549,16 +753,42 @@ void URLLoaderImpl::CompletePendingWrite() {
pending_write_buffer_offset_ = 0;
}
-void URLLoaderImpl::SetRawResponseHeaders(
+void URLLoader::SetRawResponseHeaders(
scoped_refptr<const net::HttpResponseHeaders> headers) {
raw_response_headers_ = headers;
}
-void URLLoaderImpl::UpdateBodyReadBeforePaused() {
+void URLLoader::UpdateBodyReadBeforePaused() {
DCHECK_GE(pending_write_buffer_offset_ + total_written_bytes_,
body_read_before_paused_);
body_read_before_paused_ =
pending_write_buffer_offset_ + total_written_bytes_;
}
+void URLLoader::SendUploadProgress(const net::UploadProgress& progress) {
+ url_loader_client_->OnUploadProgress(
+ progress.position(), progress.size(),
+ base::BindOnce(&URLLoader::OnUploadProgressACK,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void URLLoader::OnUploadProgressACK() {
+ if (upload_progress_tracker_)
+ upload_progress_tracker_->OnAckReceived();
+}
+
+void URLLoader::OnSSLCertificateErrorResponse(const net::SSLInfo& ssl_info,
+ int net_error) {
+ // The request can be NULL if it was cancelled by the client.
+ if (!url_request_ || !url_request_->is_pending())
+ return;
+
+ if (net_error == net::OK) {
+ url_request_->ContinueDespiteLastError();
+ return;
+ }
+
+ url_request_->CancelWithSSLError(net_error, ssl_info);
+}
+
} // namespace content
diff --git a/chromium/content/network/url_loader_impl.h b/chromium/content/network/url_loader.h
index 160277929a1..a182c2baeeb 100644
--- a/chromium/content/network/url_loader_impl.h
+++ b/chromium/content/network/url_loader.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_NETWORK_URL_LOADER_IMPL_H_
-#define CONTENT_NETWORK_URL_LOADER_IMPL_H_
+#ifndef CONTENT_NETWORK_URL_LOADER_H_
+#define CONTENT_NETWORK_URL_LOADER_H_
#include <stdint.h>
@@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
+#include "content/network/upload_progress_tracker.h"
#include "content/public/common/url_loader.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/data_pipe.h"
@@ -32,17 +33,18 @@ namespace content {
class NetworkContext;
struct ResourceResponse;
-class CONTENT_EXPORT URLLoaderImpl : public mojom::URLLoader,
- public net::URLRequest::Delegate {
+class CONTENT_EXPORT URLLoader : public mojom::URLLoader,
+ public net::URLRequest::Delegate {
public:
- URLLoaderImpl(NetworkContext* context,
- mojom::URLLoaderRequest url_loader_request,
- int32_t options,
- const ResourceRequest& request,
- bool report_raw_headers,
- mojom::URLLoaderClientPtr url_loader_client,
- const net::NetworkTrafficAnnotationTag& traffic_annotation);
- ~URLLoaderImpl() override;
+ URLLoader(NetworkContext* context,
+ mojom::URLLoaderRequest url_loader_request,
+ int32_t options,
+ const ResourceRequest& request,
+ bool report_raw_headers,
+ mojom::URLLoaderClientPtr url_loader_client,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation,
+ uint32_t process_id);
+ ~URLLoader() override;
// Called when the associated NetworkContext is going away.
void Cleanup();
@@ -58,11 +60,18 @@ class CONTENT_EXPORT URLLoaderImpl : public mojom::URLLoader,
void OnReceivedRedirect(net::URLRequest* url_request,
const net::RedirectInfo& redirect_info,
bool* defer_redirect) override;
+ void OnAuthRequired(net::URLRequest* request,
+ net::AuthChallengeInfo* info) override;
+ void OnCertificateRequested(net::URLRequest* request,
+ net::SSLCertRequestInfo* info) override;
+ void OnSSLCertificateError(net::URLRequest* request,
+ const net::SSLInfo& info,
+ bool fatal) override;
void OnResponseStarted(net::URLRequest* url_request, int net_error) override;
void OnReadCompleted(net::URLRequest* url_request, int bytes_read) override;
// Returns a WeakPtr so tests can validate that the object was destroyed.
- base::WeakPtr<URLLoaderImpl> GetWeakPtrForTests();
+ base::WeakPtr<URLLoader> GetWeakPtrForTests();
private:
void ReadMore();
@@ -77,9 +86,17 @@ class CONTENT_EXPORT URLLoaderImpl : public mojom::URLLoader,
void CompletePendingWrite();
void SetRawResponseHeaders(scoped_refptr<const net::HttpResponseHeaders>);
void UpdateBodyReadBeforePaused();
+ void SendUploadProgress(const net::UploadProgress& progress);
+ void OnUploadProgressACK();
+ void OnSSLCertificateErrorResponse(const net::SSLInfo& ssl_info,
+ int net_error);
NetworkContext* context_;
int32_t options_;
+ ResourceType resource_type_;
+ bool is_load_timing_enabled_;
+ uint32_t process_id_;
+ uint32_t render_frame_id_;
bool connected_;
std::unique_ptr<net::URLRequest> url_request_;
mojo::Binding<mojom::URLLoader> binding_;
@@ -102,6 +119,8 @@ class CONTENT_EXPORT URLLoaderImpl : public mojom::URLLoader,
net::HttpRawRequestHeaders raw_request_headers_;
scoped_refptr<const net::HttpResponseHeaders> raw_response_headers_;
+ std::unique_ptr<UploadProgressTracker> upload_progress_tracker_;
+
bool should_pause_reading_body_ = false;
// The response body stream is open, but transferring data is paused.
bool paused_reading_body_ = false;
@@ -118,11 +137,11 @@ class CONTENT_EXPORT URLLoaderImpl : public mojom::URLLoader,
// as BodyReadFromNetBeforePaused.
int64_t body_read_before_paused_ = -1;
- base::WeakPtrFactory<URLLoaderImpl> weak_ptr_factory_;
+ base::WeakPtrFactory<URLLoader> weak_ptr_factory_;
- DISALLOW_COPY_AND_ASSIGN(URLLoaderImpl);
+ DISALLOW_COPY_AND_ASSIGN(URLLoader);
};
} // namespace content
-#endif // CONTENT_NETWORK_URL_LOADER_IMPL_H_
+#endif // CONTENT_NETWORK_URL_LOADER_H_
diff --git a/chromium/content/network/url_loader_unittest.cc b/chromium/content/network/url_loader_unittest.cc
index 5c332cdd9fd..8233d4d7cd9 100644
--- a/chromium/content/network/url_loader_unittest.cc
+++ b/chromium/content/network/url_loader_unittest.cc
@@ -2,28 +2,43 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdint.h>
+
+#include <limits>
#include <list>
#include <memory>
#include <string>
#include "base/compiler_specific.h"
+#include "base/files/file.h"
+#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/network/network_context.h"
-#include "content/network/url_loader_impl.h"
+#include "content/network/url_loader.h"
#include "content/public/common/appcache_info.h"
#include "content/public/common/content_paths.h"
+#include "content/public/common/resource_request.h"
+#include "content/public/common/resource_request_body.h"
#include "content/public/test/controllable_http_response.h"
#include "content/public/test/test_url_loader_client.h"
+#include "mojo/common/data_pipe_utils.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/cpp/system/wait.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_flags.h"
#include "net/base/mime_sniffer.h"
+#include "net/base/net_errors.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_response.h"
+#include "net/test/test_data_directory.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
@@ -31,7 +46,9 @@
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_status.h"
+#include "net/url_request/url_request_test_job.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
namespace content {
@@ -44,10 +61,11 @@ static ResourceRequest CreateResourceRequest(const char* method,
request.method = std::string(method);
request.url = url;
request.site_for_cookies = url; // bypass third-party cookie blocking
- request.request_initiator = url::Origin(url); // ensure initiator is set
+ request.request_initiator =
+ url::Origin::Create(url); // ensure initiator is set
request.referrer_policy = blink::kWebReferrerPolicyDefault;
request.load_flags = 0;
- request.origin_pid = 0;
+ request.plugin_child_id = -1;
request.resource_type = type;
request.request_context = 0;
request.appcache_host_id = kAppCacheNoHostId;
@@ -144,23 +162,70 @@ class MultipleWritesInterceptor : public net::URLRequestInterceptor {
DISALLOW_COPY_AND_ASSIGN(MultipleWritesInterceptor);
};
+class SimpleDataPipeGetter : public network::mojom::DataPipeGetter {
+ public:
+ SimpleDataPipeGetter(const std::string& str,
+ network::mojom::DataPipeGetterRequest request)
+ : str_(str), binding_(this, std::move(request)) {}
+ ~SimpleDataPipeGetter() override = default;
+
+ // network::mojom::DataPipeGetter implementation:
+ void Read(mojo::ScopedDataPipeProducerHandle handle,
+ ReadCallback callback) override {
+ bool result = mojo::common::BlockingCopyFromString(str_, handle);
+ ASSERT_TRUE(result);
+ std::move(callback).Run(net::OK, str_.length());
+ }
+
+ private:
+ std::string str_;
+ mojo::Binding<network::mojom::DataPipeGetter> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(SimpleDataPipeGetter);
+};
+
+class RequestInterceptor : public net::URLRequestInterceptor {
+ public:
+ using InterceptCallback = base::Callback<void(net::URLRequest*)>;
+
+ explicit RequestInterceptor(const InterceptCallback& callback)
+ : callback_(callback) {}
+ ~RequestInterceptor() override {}
+
+ // URLRequestInterceptor implementation:
+ net::URLRequestJob* MaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ callback_.Run(request);
+ return nullptr;
+ }
+
+ private:
+ InterceptCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(RequestInterceptor);
+};
+
} // namespace
-class URLLoaderImplTest : public testing::Test {
+class URLLoaderTest : public testing::Test {
public:
- URLLoaderImplTest()
+ URLLoaderTest()
: scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::IO),
context_(NetworkContext::CreateForTesting()) {
net::URLRequestFailedJob::AddUrlHandler();
}
- ~URLLoaderImplTest() override {
+ ~URLLoaderTest() override {
net::URLRequestFilter::GetInstance()->ClearHandlers();
}
void SetUp() override {
test_server_.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
+ // This Unretained is safe because test_server_ is owned by |this|.
+ test_server_.RegisterRequestMonitor(
+ base::Bind(&URLLoaderTest::Monitor, base::Unretained(this)));
ASSERT_TRUE(test_server_.Start());
}
@@ -173,20 +238,32 @@ class URLLoaderImplTest : public testing::Test {
DCHECK(!ran_);
mojom::URLLoaderPtr loader;
- ResourceRequest request =
- CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME, url);
+ ResourceRequest request = CreateResourceRequest(
+ !request_body_ ? "GET" : "POST", resource_type_, url);
uint32_t options = mojom::kURLLoadOptionNone;
- if (send_ssl_)
- options |= mojom::kURLLoadOptionSendSSLInfo;
+ if (send_ssl_with_response_)
+ options |= mojom::kURLLoadOptionSendSSLInfoWithResponse;
if (sniff_)
options |= mojom::kURLLoadOptionSniffMimeType;
+ if (add_custom_accept_header_)
+ request.headers.SetHeader("accept", "custom/*");
+ if (send_ssl_for_cert_error_)
+ options |= mojom::kURLLoadOptionSendSSLInfoForCertificateError;
- URLLoaderImpl loader_impl(context(), mojo::MakeRequest(&loader), options,
- request, false, client_.CreateInterfacePtr(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ if (request_body_)
+ request.request_body = request_body_;
+
+ URLLoader loader_impl(context(), mojo::MakeRequest(&loader), options,
+ request, false, client_.CreateInterfacePtr(),
+ TRAFFIC_ANNOTATION_FOR_TESTS, 0);
ran_ = true;
+ if (expect_redirect_) {
+ client_.RunUntilRedirectReceived();
+ loader->FollowRedirect();
+ }
+
if (body) {
client_.RunUntilResponseBodyArrived();
*body = ReadBody();
@@ -203,9 +280,7 @@ class URLLoaderImplTest : public testing::Test {
}
void LoadAndCompareFile(const std::string& path) {
- base::FilePath file;
- PathService::Get(content::DIR_TEST_DATA, &file);
- file = file.AppendASCII(path);
+ base::FilePath file = GetTestFilePath(path);
std::string expected;
if (!base::ReadFileToString(file, &expected)) {
@@ -266,19 +341,64 @@ class URLLoaderImplTest : public testing::Test {
EXPECT_EQ(actual_body, expected_body);
}
+ // Adds an interceptor that can examine the URLRequest object.
+ void AddRequestObserver(
+ const GURL& url,
+ const RequestInterceptor::InterceptCallback& callback) {
+ net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
+ url, std::unique_ptr<net::URLRequestInterceptor>(
+ new RequestInterceptor(callback)));
+ }
+
net::EmbeddedTestServer* test_server() { return &test_server_; }
NetworkContext* context() { return context_.get(); }
TestURLLoaderClient* client() { return &client_; }
void DestroyContext() { context_.reset(); }
+ // Returns the path of the requested file in the test data directory.
+ base::FilePath GetTestFilePath(const std::string& file_name) {
+ base::FilePath file_path;
+ PathService::Get(DIR_TEST_DATA, &file_path);
+ return file_path.AppendASCII(file_name);
+ }
+
+ base::File OpenFileForUpload(const base::FilePath& file_path) {
+ int open_flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
+#if defined(OS_WIN)
+ open_flags |= base::File::FLAG_ASYNC;
+#endif // defined(OS_WIN)
+ base::File file(file_path, open_flags);
+ EXPECT_TRUE(file.IsValid());
+ return file;
+ }
+
// Configure how Load() works.
void set_sniff() {
DCHECK(!ran_);
sniff_ = true;
}
- void set_send_ssl() {
+ void set_send_ssl_with_response() {
+ DCHECK(!ran_);
+ send_ssl_with_response_ = true;
+ }
+ void set_send_ssl_for_cert_error() {
DCHECK(!ran_);
- send_ssl_ = true;
+ send_ssl_for_cert_error_ = true;
+ }
+ void set_add_custom_accept_header() {
+ DCHECK(!ran_);
+ add_custom_accept_header_ = true;
+ }
+ void set_expect_redirect() {
+ DCHECK(!ran_);
+ expect_redirect_ = true;
+ }
+ void set_resource_type(ResourceType type) {
+ DCHECK(!ran_);
+ resource_type_ = type;
+ }
+ void set_request_body(scoped_refptr<ResourceRequestBody> request_body) {
+ request_body_ = request_body;
}
// Convenience methods after calling Load();
@@ -353,34 +473,51 @@ class URLLoaderImplTest : public testing::Test {
return std::string(buffer.data(), buffer.size());
}
+ const net::test_server::HttpRequest& sent_request() const {
+ return sent_request_;
+ }
+
private:
+ void Monitor(const net::test_server::HttpRequest& request) {
+ sent_request_ = request;
+ }
+
base::test::ScopedTaskEnvironment scoped_task_environment_;
net::EmbeddedTestServer test_server_;
std::unique_ptr<NetworkContext> context_;
+
+ // Options applied to the created request in Load().
bool sniff_ = false;
- bool send_ssl_ = false;
+ bool send_ssl_with_response_ = false;
+ bool send_ssl_for_cert_error_ = false;
+ bool add_custom_accept_header_ = false;
+ bool expect_redirect_ = false;
+ ResourceType resource_type_ = RESOURCE_TYPE_MAIN_FRAME;
+ scoped_refptr<ResourceRequestBody> request_body_;
+
// Used to ensure that methods are called either before or after a request is
// made, since the test fixture is meant to be used only once.
bool ran_ = false;
+ net::test_server::HttpRequest sent_request_;
TestURLLoaderClient client_;
};
-TEST_F(URLLoaderImplTest, Basic) {
+TEST_F(URLLoaderTest, Basic) {
LoadAndCompareFile("simple_page.html");
}
-TEST_F(URLLoaderImplTest, Empty) {
+TEST_F(URLLoaderTest, Empty) {
LoadAndCompareFile("empty.html");
}
-TEST_F(URLLoaderImplTest, BasicSSL) {
+TEST_F(URLLoaderTest, BasicSSL) {
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_server.ServeFilesFromSourceDirectory(
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
GURL url = https_server.GetURL("/simple_page.html");
- set_send_ssl();
+ set_send_ssl_with_response();
EXPECT_EQ(net::OK, Load(url));
ASSERT_TRUE(!!ssl_info());
ASSERT_TRUE(!!ssl_info()->cert);
@@ -388,7 +525,7 @@ TEST_F(URLLoaderImplTest, BasicSSL) {
ASSERT_TRUE(https_server.GetCertificate()->Equals(ssl_info()->cert.get()));
}
-TEST_F(URLLoaderImplTest, SSLSentOnlyWhenRequested) {
+TEST_F(URLLoaderTest, SSLSentOnlyWhenRequested) {
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_server.ServeFilesFromSourceDirectory(
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
@@ -400,7 +537,7 @@ TEST_F(URLLoaderImplTest, SSLSentOnlyWhenRequested) {
}
// Test decoded_body_length / encoded_body_length when they're different.
-TEST_F(URLLoaderImplTest, GzipTest) {
+TEST_F(URLLoaderTest, GzipTest) {
std::string body;
EXPECT_EQ(net::OK, Load(test_server()->GetURL("/gzip-body?Body"), &body));
EXPECT_EQ("Body", body);
@@ -413,13 +550,13 @@ TEST_F(URLLoaderImplTest, GzipTest) {
client()->completion_status().encoded_data_length);
}
-TEST_F(URLLoaderImplTest, ErrorBeforeHeaders) {
+TEST_F(URLLoaderTest, ErrorBeforeHeaders) {
EXPECT_EQ(net::ERR_EMPTY_RESPONSE,
Load(test_server()->GetURL("/close-socket"), nullptr));
EXPECT_FALSE(client()->response_body().is_valid());
}
-TEST_F(URLLoaderImplTest, SyncErrorWhileReadingBody) {
+TEST_F(URLLoaderTest, SyncErrorWhileReadingBody) {
std::string body;
EXPECT_EQ(net::ERR_FAILED,
Load(net::URLRequestFailedJob::GetMockHttpUrlWithFailurePhase(
@@ -428,7 +565,7 @@ TEST_F(URLLoaderImplTest, SyncErrorWhileReadingBody) {
EXPECT_EQ("", body);
}
-TEST_F(URLLoaderImplTest, AsyncErrorWhileReadingBody) {
+TEST_F(URLLoaderTest, AsyncErrorWhileReadingBody) {
std::string body;
EXPECT_EQ(net::ERR_FAILED,
Load(net::URLRequestFailedJob::GetMockHttpUrlWithFailurePhase(
@@ -437,7 +574,7 @@ TEST_F(URLLoaderImplTest, AsyncErrorWhileReadingBody) {
EXPECT_EQ("", body);
}
-TEST_F(URLLoaderImplTest, SyncErrorWhileReadingBodyAfterBytesReceived) {
+TEST_F(URLLoaderTest, SyncErrorWhileReadingBodyAfterBytesReceived) {
const std::string kBody("Foo.");
std::list<std::string> packets;
@@ -450,7 +587,7 @@ TEST_F(URLLoaderImplTest, SyncErrorWhileReadingBodyAfterBytesReceived) {
EXPECT_EQ(kBody, body);
}
-TEST_F(URLLoaderImplTest, AsyncErrorWhileReadingBodyAfterBytesReceived) {
+TEST_F(URLLoaderTest, AsyncErrorWhileReadingBodyAfterBytesReceived) {
const std::string kBody("Foo.");
std::list<std::string> packets;
@@ -463,7 +600,7 @@ TEST_F(URLLoaderImplTest, AsyncErrorWhileReadingBodyAfterBytesReceived) {
EXPECT_EQ(kBody, body);
}
-TEST_F(URLLoaderImplTest, DestroyContextWithLiveRequest) {
+TEST_F(URLLoaderTest, DestroyContextWithLiveRequest) {
GURL url = test_server()->GetURL("/hung-after-headers");
ResourceRequest request =
CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME, url);
@@ -471,10 +608,10 @@ TEST_F(URLLoaderImplTest, DestroyContextWithLiveRequest) {
mojom::URLLoaderPtr loader;
// The loader is implicitly owned by the client and the NetworkContext, so
// don't hold on to a pointer to it.
- base::WeakPtr<URLLoaderImpl> loader_impl =
- (new URLLoaderImpl(context(), mojo::MakeRequest(&loader), 0, request,
- false, client()->CreateInterfacePtr(),
- TRAFFIC_ANNOTATION_FOR_TESTS))
+ base::WeakPtr<URLLoader> loader_impl =
+ (new URLLoader(context(), mojo::MakeRequest(&loader), 0, request, false,
+ client()->CreateInterfacePtr(),
+ TRAFFIC_ANNOTATION_FOR_TESTS, 0))
->GetWeakPtrForTests();
client()->RunUntilResponseReceived();
@@ -494,47 +631,47 @@ TEST_F(URLLoaderImplTest, DestroyContextWithLiveRequest) {
EXPECT_EQ(0u, client()->download_data_length());
}
-TEST_F(URLLoaderImplTest, DoNotSniffUnlessSpecified) {
+TEST_F(URLLoaderTest, DoNotSniffUnlessSpecified) {
EXPECT_EQ(net::OK,
Load(test_server()->GetURL("/content-sniffer-test0.html")));
ASSERT_TRUE(mime_type().empty());
}
-TEST_F(URLLoaderImplTest, SniffMimeType) {
+TEST_F(URLLoaderTest, SniffMimeType) {
set_sniff();
EXPECT_EQ(net::OK,
Load(test_server()->GetURL("/content-sniffer-test0.html")));
ASSERT_EQ(std::string("text/html"), mime_type());
}
-TEST_F(URLLoaderImplTest, RespectNoSniff) {
+TEST_F(URLLoaderTest, RespectNoSniff) {
set_sniff();
EXPECT_EQ(net::OK, Load(test_server()->GetURL("/nosniff-test.html")));
ASSERT_TRUE(mime_type().empty());
}
-TEST_F(URLLoaderImplTest, DoNotSniffHTMLFromTextPlain) {
+TEST_F(URLLoaderTest, DoNotSniffHTMLFromTextPlain) {
set_sniff();
EXPECT_EQ(net::OK,
Load(test_server()->GetURL("/content-sniffer-test1.html")));
ASSERT_EQ(std::string("text/plain"), mime_type());
}
-TEST_F(URLLoaderImplTest, DoNotSniffHTMLFromImageGIF) {
+TEST_F(URLLoaderTest, DoNotSniffHTMLFromImageGIF) {
set_sniff();
EXPECT_EQ(net::OK,
Load(test_server()->GetURL("/content-sniffer-test2.html")));
ASSERT_EQ(std::string("image/gif"), mime_type());
}
-TEST_F(URLLoaderImplTest, EmptyHtmlIsTextPlain) {
+TEST_F(URLLoaderTest, EmptyHtmlIsTextPlain) {
set_sniff();
EXPECT_EQ(net::OK,
Load(test_server()->GetURL("/content-sniffer-test4.html")));
ASSERT_EQ(std::string("text/plain"), mime_type());
}
-TEST_F(URLLoaderImplTest, EmptyHtmlIsTextPlainWithAsyncResponse) {
+TEST_F(URLLoaderTest, EmptyHtmlIsTextPlainWithAsyncResponse) {
set_sniff();
const std::string kBody;
@@ -552,7 +689,7 @@ TEST_F(URLLoaderImplTest, EmptyHtmlIsTextPlainWithAsyncResponse) {
// Tests the case where the first read doesn't have enough data to figure out
// the right mime type. The second read would have enough data even though the
// total bytes is still smaller than net::kMaxBytesToSniff.
-TEST_F(URLLoaderImplTest, FirstReadNotEnoughToSniff1) {
+TEST_F(URLLoaderTest, FirstReadNotEnoughToSniff1) {
set_sniff();
std::string first(500, 'a');
std::string second(std::string(100, 'b'));
@@ -564,7 +701,7 @@ TEST_F(URLLoaderImplTest, FirstReadNotEnoughToSniff1) {
}
// Like above, except that the total byte count is > kMaxBytesToSniff.
-TEST_F(URLLoaderImplTest, FirstReadNotEnoughToSniff2) {
+TEST_F(URLLoaderTest, FirstReadNotEnoughToSniff2) {
set_sniff();
std::string first(500, 'a');
std::string second(std::string(1000, 'b'));
@@ -577,7 +714,7 @@ TEST_F(URLLoaderImplTest, FirstReadNotEnoughToSniff2) {
// Tests that even if the first and only read is smaller than the minimum number
// of bytes needed to sniff, the loader works correctly and returns the data.
-TEST_F(URLLoaderImplTest, LoneReadNotEnoughToSniff) {
+TEST_F(URLLoaderTest, LoneReadNotEnoughToSniff) {
set_sniff();
std::string first(net::kMaxBytesToSniff - 100, 'a');
LoadPacketsAndVerifyContents(first, std::string());
@@ -585,7 +722,7 @@ TEST_F(URLLoaderImplTest, LoneReadNotEnoughToSniff) {
}
// Tests the simple case where the first read is enough to sniff.
-TEST_F(URLLoaderImplTest, FirstReadIsEnoughToSniff) {
+TEST_F(URLLoaderTest, FirstReadIsEnoughToSniff) {
set_sniff();
std::string first(net::kMaxBytesToSniff + 100, 'a');
LoadPacketsAndVerifyContents(first, std::string());
@@ -614,7 +751,7 @@ class NeverFinishedBodyHttpResponse : public net::test_server::HttpResponse {
}
};
-TEST_F(URLLoaderImplTest, CloseResponseBodyConsumerBeforeProducer) {
+TEST_F(URLLoaderTest, CloseResponseBodyConsumerBeforeProducer) {
net::EmbeddedTestServer server;
server.RegisterRequestHandler(
base::Bind([](const net::test_server::HttpRequest& request) {
@@ -629,9 +766,9 @@ TEST_F(URLLoaderImplTest, CloseResponseBodyConsumerBeforeProducer) {
mojom::URLLoaderPtr loader;
// The loader is implicitly owned by the client and the NetworkContext.
- new URLLoaderImpl(context(), mojo::MakeRequest(&loader), 0, request, false,
- client()->CreateInterfacePtr(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ new URLLoader(context(), mojo::MakeRequest(&loader), 0, request, false,
+ client()->CreateInterfacePtr(), TRAFFIC_ANNOTATION_FOR_TESTS,
+ 0);
client()->RunUntilResponseBodyArrived();
EXPECT_TRUE(client()->has_received_response());
@@ -657,7 +794,7 @@ TEST_F(URLLoaderImplTest, CloseResponseBodyConsumerBeforeProducer) {
EXPECT_FALSE(client()->has_received_completion());
}
-TEST_F(URLLoaderImplTest, PauseReadingBodyFromNetBeforeRespnoseHeaders) {
+TEST_F(URLLoaderTest, PauseReadingBodyFromNetBeforeRespnoseHeaders) {
const char* const kPath = "/hello.html";
const char* const kBodyContents = "This is the data as you requested.";
@@ -670,9 +807,9 @@ TEST_F(URLLoaderImplTest, PauseReadingBodyFromNetBeforeRespnoseHeaders) {
mojom::URLLoaderPtr loader;
// The loader is implicitly owned by the client and the NetworkContext.
- new URLLoaderImpl(context(), mojo::MakeRequest(&loader), 0, request, false,
- client()->CreateInterfacePtr(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ new URLLoader(context(), mojo::MakeRequest(&loader), 0, request, false,
+ client()->CreateInterfacePtr(), TRAFFIC_ANNOTATION_FOR_TESTS,
+ 0);
// Pausing reading response body from network stops future reads from the
// underlying URLRequest. So no data should be sent using the response body
@@ -713,7 +850,7 @@ TEST_F(URLLoaderImplTest, PauseReadingBodyFromNetBeforeRespnoseHeaders) {
EXPECT_EQ(kBodyContents, available_data);
}
-TEST_F(URLLoaderImplTest, PauseReadingBodyFromNetWhenReadIsPending) {
+TEST_F(URLLoaderTest, PauseReadingBodyFromNetWhenReadIsPending) {
const char* const kPath = "/hello.html";
const char* const kBodyContentsFirstHalf = "This is the first half.";
const char* const kBodyContentsSecondHalf = "This is the second half.";
@@ -727,9 +864,9 @@ TEST_F(URLLoaderImplTest, PauseReadingBodyFromNetWhenReadIsPending) {
mojom::URLLoaderPtr loader;
// The loader is implicitly owned by the client and the NetworkContext.
- new URLLoaderImpl(context(), mojo::MakeRequest(&loader), 0, request, false,
- client()->CreateInterfacePtr(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ new URLLoader(context(), mojo::MakeRequest(&loader), 0, request, false,
+ client()->CreateInterfacePtr(), TRAFFIC_ANNOTATION_FOR_TESTS,
+ 0);
response_controller.WaitForRequest();
response_controller.Send(
@@ -760,7 +897,7 @@ TEST_F(URLLoaderImplTest, PauseReadingBodyFromNetWhenReadIsPending) {
ReadBody());
}
-TEST_F(URLLoaderImplTest, ResumeReadingBodyFromNetAfterClosingConsumer) {
+TEST_F(URLLoaderTest, ResumeReadingBodyFromNetAfterClosingConsumer) {
const char* const kPath = "/hello.html";
const char* const kBodyContentsFirstHalf = "This is the first half.";
@@ -773,9 +910,9 @@ TEST_F(URLLoaderImplTest, ResumeReadingBodyFromNetAfterClosingConsumer) {
mojom::URLLoaderPtr loader;
// The loader is implicitly owned by the client and the NetworkContext.
- new URLLoaderImpl(context(), mojo::MakeRequest(&loader), 0, request, false,
- client()->CreateInterfacePtr(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ new URLLoader(context(), mojo::MakeRequest(&loader), 0, request, false,
+ client()->CreateInterfacePtr(), TRAFFIC_ANNOTATION_FOR_TESTS,
+ 0);
loader->PauseReadingBodyFromNet();
loader.FlushForTesting();
@@ -799,7 +936,7 @@ TEST_F(URLLoaderImplTest, ResumeReadingBodyFromNetAfterClosingConsumer) {
loader.FlushForTesting();
}
-TEST_F(URLLoaderImplTest, MultiplePauseResumeReadingBodyFromNet) {
+TEST_F(URLLoaderTest, MultiplePauseResumeReadingBodyFromNet) {
const char* const kPath = "/hello.html";
const char* const kBodyContentsFirstHalf = "This is the first half.";
const char* const kBodyContentsSecondHalf = "This is the second half.";
@@ -813,9 +950,9 @@ TEST_F(URLLoaderImplTest, MultiplePauseResumeReadingBodyFromNet) {
mojom::URLLoaderPtr loader;
// The loader is implicitly owned by the client and the NetworkContext.
- new URLLoaderImpl(context(), mojo::MakeRequest(&loader), 0, request, false,
- client()->CreateInterfacePtr(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ new URLLoader(context(), mojo::MakeRequest(&loader), 0, request, false,
+ client()->CreateInterfacePtr(), TRAFFIC_ANNOTATION_FOR_TESTS,
+ 0);
// It is okay to call ResumeReadingBodyFromNet() even if there is no prior
// PauseReadingBodyFromNet().
@@ -852,4 +989,282 @@ TEST_F(URLLoaderImplTest, MultiplePauseResumeReadingBodyFromNet) {
ReadBody());
}
+TEST_F(URLLoaderTest, AttachAcceptHeaderForStyleSheet) {
+ set_resource_type(RESOURCE_TYPE_STYLESHEET);
+ EXPECT_EQ(net::OK,
+ Load(test_server()->GetURL("/content-sniffer-test0.html")));
+
+ auto it = sent_request().headers.find("accept");
+ ASSERT_NE(it, sent_request().headers.end());
+ EXPECT_EQ(it->second, "text/css,*/*;q=0.1");
+}
+
+TEST_F(URLLoaderTest, AttachAcceptHeaderForXHR) {
+ set_resource_type(RESOURCE_TYPE_XHR);
+ EXPECT_EQ(net::OK,
+ Load(test_server()->GetURL("/content-sniffer-test0.html")));
+
+ auto it = sent_request().headers.find("accept");
+ ASSERT_NE(it, sent_request().headers.end());
+ EXPECT_EQ(it->second, "*/*");
+}
+
+TEST_F(URLLoaderTest, DoNotOverrideAcceptHeader) {
+ set_resource_type(RESOURCE_TYPE_XHR);
+ set_add_custom_accept_header();
+ EXPECT_EQ(net::OK,
+ Load(test_server()->GetURL("/content-sniffer-test0.html")));
+
+ auto it = sent_request().headers.find("accept");
+ ASSERT_NE(it, sent_request().headers.end());
+ EXPECT_EQ(it->second, "custom/*");
+}
+
+// Tests that a RESOURCE_TYPE_PREFETCH request sets the LOAD_PREFETCH flag.
+TEST_F(URLLoaderTest, SetPrefetchFlag) {
+ set_resource_type(RESOURCE_TYPE_PREFETCH);
+ GURL url = test_server()->GetURL("/simple_page.html");
+ int load_flags = 0;
+ AddRequestObserver(url, base::Bind(
+ [](int* load_flags, net::URLRequest* request) {
+ *load_flags = request->load_flags();
+ },
+ &load_flags));
+ EXPECT_EQ(net::OK, Load(url));
+
+ EXPECT_TRUE(load_flags & net::LOAD_PREFETCH);
+}
+
+TEST_F(URLLoaderTest, UploadBytes) {
+ const std::string kRequestBody = "Request Body";
+
+ scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
+ request_body->AppendBytes(kRequestBody.c_str(), kRequestBody.length());
+ set_request_body(std::move(request_body));
+
+ std::string response_body;
+ EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
+ EXPECT_EQ(kRequestBody, response_body);
+}
+
+TEST_F(URLLoaderTest, UploadFile) {
+ base::FilePath file_path = GetTestFilePath("simple_page.html");
+
+ std::string expected_body;
+ ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
+ << "File not found: " << file_path.value();
+
+ scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
+ request_body->AppendFileRange(
+ file_path, 0, std::numeric_limits<uint64_t>::max(), base::Time());
+ set_request_body(std::move(request_body));
+
+ std::string response_body;
+ EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
+ EXPECT_EQ(expected_body, response_body);
+}
+
+TEST_F(URLLoaderTest, UploadFileWithRange) {
+ base::FilePath file_path = GetTestFilePath("simple_page.html");
+
+ std::string expected_body;
+ ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
+ << "File not found: " << file_path.value();
+ expected_body = expected_body.substr(1, expected_body.size() - 2);
+
+ scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
+ request_body->AppendFileRange(file_path, 1, expected_body.size(),
+ base::Time());
+ set_request_body(std::move(request_body));
+
+ std::string response_body;
+ EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
+ EXPECT_EQ(expected_body, response_body);
+}
+
+TEST_F(URLLoaderTest, UploadRawFile) {
+ base::FilePath file_path = GetTestFilePath("simple_page.html");
+
+ std::string expected_body;
+ ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
+ << "File not found: " << file_path.value();
+
+ scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
+ request_body->AppendRawFileRange(
+ OpenFileForUpload(file_path), GetTestFilePath("should_be_ignored"), 0,
+ std::numeric_limits<uint64_t>::max(), base::Time());
+ set_request_body(std::move(request_body));
+
+ std::string response_body;
+ EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
+ EXPECT_EQ(expected_body, response_body);
+}
+
+TEST_F(URLLoaderTest, UploadRawFileWithRange) {
+ base::FilePath file_path = GetTestFilePath("simple_page.html");
+
+ std::string expected_body;
+ ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
+ << "File not found: " << file_path.value();
+ expected_body = expected_body.substr(1, expected_body.size() - 2);
+
+ scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
+ request_body->AppendRawFileRange(OpenFileForUpload(file_path),
+ GetTestFilePath("should_be_ignored"), 1,
+ expected_body.size(), base::Time());
+ set_request_body(std::move(request_body));
+
+ std::string response_body;
+ EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
+ EXPECT_EQ(expected_body, response_body);
+}
+
+// Tests a request body with a data pipe element.
+TEST_F(URLLoaderTest, UploadDataPipe) {
+ const std::string kRequestBody = "Request Body";
+
+ network::mojom::DataPipeGetterPtr data_pipe_getter_ptr;
+ auto data_pipe_getter = std::make_unique<SimpleDataPipeGetter>(
+ kRequestBody, mojo::MakeRequest(&data_pipe_getter_ptr));
+
+ auto request_body = base::MakeRefCounted<ResourceRequestBody>();
+ request_body->AppendDataPipe(std::move(data_pipe_getter_ptr));
+ set_request_body(std::move(request_body));
+
+ std::string response_body;
+ EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
+ EXPECT_EQ(kRequestBody, response_body);
+}
+
+// Same as above and tests that the body is sent after a 307 redirect.
+TEST_F(URLLoaderTest, UploadDataPipe_Redirect307) {
+ const std::string kRequestBody = "Request Body";
+
+ network::mojom::DataPipeGetterPtr data_pipe_getter_ptr;
+ auto data_pipe_getter = std::make_unique<SimpleDataPipeGetter>(
+ kRequestBody, mojo::MakeRequest(&data_pipe_getter_ptr));
+
+ auto request_body = base::MakeRefCounted<ResourceRequestBody>();
+ request_body->AppendDataPipe(std::move(data_pipe_getter_ptr));
+ set_request_body(std::move(request_body));
+ set_expect_redirect();
+
+ std::string response_body;
+ EXPECT_EQ(net::OK, Load(test_server()->GetURL("/redirect307-to-echo"),
+ &response_body));
+ EXPECT_EQ(kRequestBody, response_body);
+}
+
+TEST_F(URLLoaderTest, UploadDoubleRawFile) {
+ base::FilePath file_path = GetTestFilePath("simple_page.html");
+
+ std::string expected_body;
+ ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
+ << "File not found: " << file_path.value();
+
+ scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
+ request_body->AppendRawFileRange(
+ OpenFileForUpload(file_path), GetTestFilePath("should_be_ignored"), 0,
+ std::numeric_limits<uint64_t>::max(), base::Time());
+ request_body->AppendRawFileRange(
+ OpenFileForUpload(file_path), GetTestFilePath("should_be_ignored"), 0,
+ std::numeric_limits<uint64_t>::max(), base::Time());
+ set_request_body(std::move(request_body));
+
+ std::string response_body;
+ EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
+ EXPECT_EQ(expected_body + expected_body, response_body);
+}
+
+// Tests that SSLInfo is not attached to OnComplete messages when there is no
+// certificate error.
+TEST_F(URLLoaderTest, NoSSLInfoWithoutCertificateError) {
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ ASSERT_TRUE(https_server.Start());
+ set_send_ssl_for_cert_error();
+ EXPECT_EQ(net::OK, Load(https_server.GetURL("/")));
+ EXPECT_FALSE(client()->completion_status().ssl_info.has_value());
+}
+
+// Tests that SSLInfo is not attached to OnComplete messages when the
+// corresponding option is not set.
+TEST_F(URLLoaderTest, NoSSLInfoOnComplete) {
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
+ ASSERT_TRUE(https_server.Start());
+ EXPECT_EQ(net::ERR_INSECURE_RESPONSE, Load(https_server.GetURL("/")));
+ EXPECT_FALSE(client()->completion_status().ssl_info.has_value());
+}
+
+// Tests that SSLInfo is attached to OnComplete messages when the corresponding
+// option is set.
+TEST_F(URLLoaderTest, SSLInfoOnComplete) {
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
+ ASSERT_TRUE(https_server.Start());
+ set_send_ssl_for_cert_error();
+ EXPECT_EQ(net::ERR_INSECURE_RESPONSE, Load(https_server.GetURL("/")));
+ ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
+ EXPECT_TRUE(client()->completion_status().ssl_info.value().cert);
+ EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
+ client()->completion_status().ssl_info.value().cert_status);
+}
+
+// A mock URLRequestJob which simulates an HTTPS request with a certificate
+// error.
+class MockHTTPSURLRequestJob : public net::URLRequestTestJob {
+ public:
+ MockHTTPSURLRequestJob(net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const std::string& response_headers,
+ const std::string& response_data,
+ bool auto_advance)
+ : net::URLRequestTestJob(request,
+ network_delegate,
+ response_headers,
+ response_data,
+ auto_advance) {}
+
+ // net::URLRequestTestJob:
+ void GetResponseInfo(net::HttpResponseInfo* info) override {
+ // Get the original response info, but override the SSL info.
+ net::URLRequestJob::GetResponseInfo(info);
+ info->ssl_info.cert =
+ net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
+ info->ssl_info.cert_status = net::CERT_STATUS_DATE_INVALID;
+ }
+
+ private:
+ ~MockHTTPSURLRequestJob() override {}
+
+ DISALLOW_COPY_AND_ASSIGN(MockHTTPSURLRequestJob);
+};
+
+class MockHTTPSJobURLRequestInterceptor : public net::URLRequestInterceptor {
+ public:
+ explicit MockHTTPSJobURLRequestInterceptor() {}
+ ~MockHTTPSJobURLRequestInterceptor() override {}
+
+ // net::URLRequestInterceptor:
+ net::URLRequestJob* MaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return new MockHTTPSURLRequestJob(request, network_delegate, std::string(),
+ "dummy response", true);
+ }
+};
+
+// Tests that |cert_status| is set on the resource response.
+TEST_F(URLLoaderTest, CertStatusOnResponse) {
+ net::URLRequestFilter::GetInstance()->ClearHandlers();
+ net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
+ "https", "example.test",
+ std::unique_ptr<net::URLRequestInterceptor>(
+ new MockHTTPSJobURLRequestInterceptor()));
+
+ EXPECT_EQ(net::OK, Load(GURL("https://example.test/")));
+ EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
+ client()->response_head().cert_status);
+}
+
} // namespace content
diff --git a/chromium/content/ppapi_plugin/DEPS b/chromium/content/ppapi_plugin/DEPS
index f238daf4e16..fc443d2e7ad 100644
--- a/chromium/content/ppapi_plugin/DEPS
+++ b/chromium/content/ppapi_plugin/DEPS
@@ -6,5 +6,6 @@ include_rules = [
"+ppapi/c",
"+ppapi/proxy",
"+services/service_manager/public/cpp",
+ "+services/service_manager/sandbox",
"+services/ui/public/interfaces",
]
diff --git a/chromium/content/ppapi_plugin/broker_process_dispatcher.cc b/chromium/content/ppapi_plugin/broker_process_dispatcher.cc
index 87babc1b78a..629394972a9 100644
--- a/chromium/content/ppapi_plugin/broker_process_dispatcher.cc
+++ b/chromium/content/ppapi_plugin/broker_process_dispatcher.cc
@@ -81,9 +81,9 @@ BrokerProcessDispatcher::BrokerProcessDispatcher(
bool peer_is_browser)
: ppapi::proxy::BrokerSideDispatcher(connect_instance),
get_plugin_interface_(get_plugin_interface),
- flash_browser_operations_1_3_(NULL),
- flash_browser_operations_1_2_(NULL),
- flash_browser_operations_1_0_(NULL),
+ flash_browser_operations_1_3_(nullptr),
+ flash_browser_operations_1_2_(nullptr),
+ flash_browser_operations_1_0_(nullptr),
peer_is_browser_(peer_is_browser) {
if (get_plugin_interface) {
flash_browser_operations_1_0_ =
@@ -226,7 +226,7 @@ void BrokerProcessDispatcher::GetSitesWithData(
std::vector<std::string>* site_vector) {
std::string data_str = ConvertPluginDataPath(plugin_data_path);
if (flash_browser_operations_1_3_) {
- char** sites = NULL;
+ char** sites = nullptr;
flash_browser_operations_1_3_->GetSitesWithData(data_str.c_str(), &sites);
if (!sites)
return;
@@ -246,7 +246,8 @@ bool BrokerProcessDispatcher::ClearSiteData(
std::string data_str = ConvertPluginDataPath(plugin_data_path);
if (flash_browser_operations_1_3_) {
flash_browser_operations_1_3_->ClearSiteData(
- data_str.c_str(), site.empty() ? NULL : site.c_str(), flags, max_age);
+ data_str.c_str(), site.empty() ? nullptr : site.c_str(), flags,
+ max_age);
return true;
}
@@ -254,13 +255,15 @@ bool BrokerProcessDispatcher::ClearSiteData(
// goes to Stable.
if (flash_browser_operations_1_2_) {
flash_browser_operations_1_2_->ClearSiteData(
- data_str.c_str(), site.empty() ? NULL : site.c_str(), flags, max_age);
+ data_str.c_str(), site.empty() ? nullptr : site.c_str(), flags,
+ max_age);
return true;
}
if (flash_browser_operations_1_0_) {
flash_browser_operations_1_0_->ClearSiteData(
- data_str.c_str(), site.empty() ? NULL : site.c_str(), flags, max_age);
+ data_str.c_str(), site.empty() ? nullptr : site.c_str(), flags,
+ max_age);
return true;
}
diff --git a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc
index e26ffe9ab2d..bf3c786b509 100644
--- a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc
+++ b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc
@@ -13,7 +13,6 @@
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#include "content/child/child_thread_impl.h"
-#include "content/common/child_process_messages.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "third_party/WebKit/public/platform/WebStorageNamespace.h"
@@ -44,7 +43,7 @@ class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport {
virtual ~SandboxSupport() {}
#if defined(OS_MACOSX)
- bool LoadFont(NSFont* srcFont, CGFontRef* out, uint32_t* fontID) override;
+ bool LoadFont(CTFontRef srcFont, CGFontRef* out, uint32_t* fontID) override;
#elif defined(OS_POSIX)
SandboxSupport();
void GetFallbackFontForCharacter(
@@ -67,7 +66,7 @@ class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport {
#if defined(OS_MACOSX)
-bool PpapiBlinkPlatformImpl::SandboxSupport::LoadFont(NSFont* src_font,
+bool PpapiBlinkPlatformImpl::SandboxSupport::LoadFont(CTFontRef src_font,
CGFontRef* out,
uint32_t* font_id) {
// TODO(brettw) this should do the something similar to what
@@ -144,12 +143,12 @@ blink::WebThread* PpapiBlinkPlatformImpl::CurrentThread() {
blink::WebClipboard* PpapiBlinkPlatformImpl::Clipboard() {
NOTREACHED();
- return NULL;
+ return nullptr;
}
blink::WebFileUtilities* PpapiBlinkPlatformImpl::GetFileUtilities() {
NOTREACHED();
- return NULL;
+ return nullptr;
}
blink::WebSandboxSupport* PpapiBlinkPlatformImpl::GetSandboxSupport() {
@@ -195,14 +194,7 @@ blink::WebString PpapiBlinkPlatformImpl::DefaultLocale() {
blink::WebThemeEngine* PpapiBlinkPlatformImpl::ThemeEngine() {
NOTREACHED();
- return NULL;
-}
-
-std::unique_ptr<blink::WebURLLoader> PpapiBlinkPlatformImpl::CreateURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- NOTREACHED();
- return NULL;
+ return nullptr;
}
void PpapiBlinkPlatformImpl::GetPluginList(
diff --git a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h
index dfc2f2b1f4c..8a58a2ae1e2 100644
--- a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h
+++ b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h
@@ -39,9 +39,6 @@ class PpapiBlinkPlatformImpl : public BlinkPlatformImpl {
const blink::WebURL& site_for_cookies);
blink::WebString DefaultLocale() override;
blink::WebThemeEngine* ThemeEngine() override;
- std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
void GetPluginList(bool refresh,
const blink::WebSecurityOrigin& mainFrameOrigin,
blink::WebPluginListBuilder*) override;
diff --git a/chromium/content/ppapi_plugin/ppapi_broker_main.cc b/chromium/content/ppapi_plugin/ppapi_broker_main.cc
index 4ff86832466..176183f686f 100644
--- a/chromium/content/ppapi_plugin/ppapi_broker_main.cc
+++ b/chromium/content/ppapi_plugin/ppapi_broker_main.cc
@@ -23,7 +23,7 @@ int PpapiBrokerMain(const MainFunctionParams& parameters) {
base::MessageLoop main_message_loop;
base::PlatformThread::SetName("CrPPAPIBrokerMain");
- base::trace_event::TraceLog::GetInstance()->SetProcessName(
+ base::trace_event::TraceLog::GetInstance()->set_process_name(
"PPAPI Broker Process");
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventPpapiBrokerProcessSortIndex);
diff --git a/chromium/content/ppapi_plugin/ppapi_plugin_main.cc b/chromium/content/ppapi_plugin/ppapi_plugin_main.cc
index 87d9a670113..2037cbf8426 100644
--- a/chromium/content/ppapi_plugin/ppapi_plugin_main.cc
+++ b/chromium/content/ppapi_plugin/ppapi_plugin_main.cc
@@ -42,8 +42,8 @@
#endif
#if defined(OS_LINUX)
-#include "content/common/sandbox_linux/sandbox_linux.h"
#include "content/public/common/sandbox_init.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#endif
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
@@ -57,7 +57,7 @@
#if defined(OS_WIN)
sandbox::TargetServices* g_target_services = NULL;
#else
-void* g_target_services = 0;
+void* g_target_services = nullptr;
#endif
namespace content {
@@ -111,7 +111,7 @@ int PpapiPluginMain(const MainFunctionParams& parameters) {
base::MessageLoop main_message_loop;
base::PlatformThread::SetName("CrPPAPIMain");
- base::trace_event::TraceLog::GetInstance()->SetProcessName("PPAPI Process");
+ base::trace_event::TraceLog::GetInstance()->set_process_name("PPAPI Process");
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventPpapiProcessSortIndex);
@@ -121,7 +121,10 @@ int PpapiPluginMain(const MainFunctionParams& parameters) {
#endif
#if defined(OS_LINUX)
- LinuxSandbox::InitializeSandbox();
+ service_manager::SandboxLinux::GetInstance()->InitializeSandbox(
+ service_manager::SandboxTypeFromCommandLine(command_line),
+ service_manager::SandboxLinux::PreSandboxHook(),
+ service_manager::SandboxLinux::Options());
#endif
ChildProcess ppapi_process;
diff --git a/chromium/content/ppapi_plugin/ppapi_thread.cc b/chromium/content/ppapi_plugin/ppapi_thread.cc
index 3fb8953ba0f..fd1539c5ec5 100644
--- a/chromium/content/ppapi_plugin/ppapi_thread.cc
+++ b/chromium/content/ppapi_plugin/ppapi_thread.cc
@@ -29,7 +29,6 @@
#include "components/discardable_memory/client/client_discardable_shared_memory_manager.h"
#include "content/child/browser_font_resource_trusted.h"
#include "content/child/child_process.h"
-#include "content/common/child_process_messages.h"
#include "content/ppapi_plugin/broker_process_dispatcher.h"
#include "content/ppapi_plugin/plugin_process_dispatcher.h"
#include "content/ppapi_plugin/ppapi_blink_platform_impl.h"
@@ -61,8 +60,6 @@
#include "base/win/win_util.h"
#include "content/child/font_warmup_win.h"
#include "sandbox/win/src/sandbox.h"
-#elif defined(OS_MACOSX)
-#include "content/common/sandbox_init_mac.h"
#endif
#if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
@@ -94,9 +91,13 @@ static void WarmupWindowsLocales(const ppapi::PpapiPermissions& permissions) {
#endif
-static bool IsRunningInMash() {
+static bool IsRunningWithMus() {
+#if BUILDFLAG(ENABLE_MUS)
const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
- return cmdline->HasSwitch(switches::kIsRunningInMash);
+ return cmdline->HasSwitch(switches::kMus);
+#else
+ return false;
+#endif
}
namespace content {
@@ -107,7 +108,7 @@ typedef int32_t (*InitializeBrokerFunc)
PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker)
: is_broker_(is_broker),
plugin_globals_(GetIOTaskRunner()),
- connect_instance_func_(NULL),
+ connect_instance_func_(nullptr),
local_pp_module_(base::RandInt(0, std::numeric_limits<PP_Module>::max())),
next_plugin_dispatcher_id_(1) {
plugin_globals_.SetPluginProxyDelegate(this);
@@ -120,7 +121,7 @@ PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker)
if (!is_broker_) {
scoped_refptr<ppapi::proxy::PluginMessageFilter> plugin_filter(
new ppapi::proxy::PluginMessageFilter(
- NULL, plugin_globals_.resource_reply_thread_registrar()));
+ nullptr, plugin_globals_.resource_reply_thread_registrar()));
channel()->AddFilter(plugin_filter.get());
plugin_globals_.RegisterResourceMessageFilters(plugin_filter.get());
}
@@ -129,7 +130,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 (IsRunningInMash()) {
+ if (IsRunningWithMus()) {
#if defined(USE_AURA)
GetServiceManagerConnection()->GetConnector()->BindInterface(
ui::mojom::kServiceName, &manager_ptr);
@@ -140,7 +141,7 @@ PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker)
ChildThread::Get()->GetConnector()->BindInterface(
mojom::kBrowserServiceName, mojo::MakeRequest(&manager_ptr));
}
- discardable_shared_memory_manager_ = base::MakeUnique<
+ discardable_shared_memory_manager_ = std::make_unique<
discardable_memory::ClientDiscardableSharedMemoryManager>(
std::move(manager_ptr), GetIOTaskRunner());
base::DiscardableMemoryAllocator::SetInstance(
@@ -297,7 +298,7 @@ void PpapiThread::OnLoadPlugin(const base::FilePath& path,
// If the plugin isn't internal then load it from |path|.
base::ScopedNativeLibrary library;
- if (plugin_entry_points_.initialize_module == NULL) {
+ if (plugin_entry_points_.initialize_module == nullptr) {
// Load the plugin from the specified library.
base::NativeLibraryLoadError error;
base::TimeDelta load_time;
@@ -544,10 +545,10 @@ bool PpapiThread::SetupChannel(base::ProcessId renderer_pid,
int renderer_child_id,
bool incognito,
IPC::ChannelHandle* handle) {
- DCHECK(is_broker_ == (connect_instance_func_ != NULL));
+ DCHECK(is_broker_ == (connect_instance_func_ != nullptr));
mojo::MessagePipe pipe;
- ppapi::proxy::ProxyChannel* dispatcher = NULL;
+ ppapi::proxy::ProxyChannel* dispatcher = nullptr;
bool init_result = false;
if (is_broker_) {
bool peer_is_browser = renderer_pid == base::kNullProcessId;
diff --git a/chromium/content/public/android/BUILD.gn b/chromium/content/public/android/BUILD.gn
index c47ae17d848..a408468cd61 100644
--- a/chromium/content/public/android/BUILD.gn
+++ b/chromium/content/public/android/BUILD.gn
@@ -121,6 +121,7 @@ android_library("content_java") {
"java/src/org/chromium/content/browser/ContentVideoViewEmbedder.java",
"java/src/org/chromium/content/browser/ContentView.java",
"java/src/org/chromium/content/browser/ContentViewCore.java",
+ "java/src/org/chromium/content/browser/ContentViewCoreImpl.java",
"java/src/org/chromium/content/browser/ContentViewRenderView.java",
"java/src/org/chromium/content/browser/ContentViewStatics.java",
"java/src/org/chromium/content/browser/DeviceUtils.java",
@@ -141,9 +142,12 @@ android_library("content_java") {
"java/src/org/chromium/content/browser/PositionObserver.java",
"java/src/org/chromium/content/browser/RenderCoordinates.java",
"java/src/org/chromium/content/browser/ScreenOrientationProvider.java",
+ "java/src/org/chromium/content/browser/SelectionEventProxyImpl.java",
+ "java/src/org/chromium/content/browser/SelectionIndicesConverter.java",
"java/src/org/chromium/content/browser/SelectionPopupController.java",
"java/src/org/chromium/content/browser/SmartClipProvider.java",
"java/src/org/chromium/content/browser/SmartSelectionClient.java",
+ "java/src/org/chromium/content/browser/SmartSelectionMetricsLogger.java",
"java/src/org/chromium/content/browser/SmartSelectionProvider.java",
"java/src/org/chromium/content/browser/SpareChildConnection.java",
"java/src/org/chromium/content/browser/SpeechRecognition.java",
@@ -236,6 +240,7 @@ android_library("content_java") {
"java/src/org/chromium/content_public/browser/ScreenOrientationDelegate.java",
"java/src/org/chromium/content_public/browser/ScreenOrientationDelegateManager.java",
"java/src/org/chromium/content_public/browser/SelectionClient.java",
+ "java/src/org/chromium/content_public/browser/SelectionMetricsLogger.java",
"java/src/org/chromium/content_public/browser/SmartClipCallback.java",
"java/src/org/chromium/content_public/browser/WebContents.java",
"java/src/org/chromium/content_public/browser/WebContentsInternals.java",
@@ -304,7 +309,6 @@ java_strings_grd("content_strings_grd") {
java_cpp_enum("content_public_android_java_enums_srcjar") {
sources = [
"//content/browser/android/content_view_core.cc",
- "//content/browser/android/gesture_event_type.h",
"//content/public/browser/android/child_process_importance.h",
"//content/public/browser/android/motion_event_action.h",
"//content/public/browser/download_item.h",
@@ -340,7 +344,7 @@ generate_jni("content_jni_headers") {
"java/src/org/chromium/content/browser/ContentFeatureList.java",
"java/src/org/chromium/content/browser/ContentNfcDelegate.java",
"java/src/org/chromium/content/browser/ContentVideoView.java",
- "java/src/org/chromium/content/browser/ContentViewCore.java",
+ "java/src/org/chromium/content/browser/ContentViewCoreImpl.java",
"java/src/org/chromium/content/browser/ContentViewRenderView.java",
"java/src/org/chromium/content/browser/ContentViewStatics.java",
"java/src/org/chromium/content/browser/GpuProcessCallback.java",
@@ -496,6 +500,7 @@ junit_binary("content_junit_tests") {
"junit/src/org/chromium/content/browser/BindingManagerImplTest.java",
"junit/src/org/chromium/content/browser/MenuDescriptorTest.java",
"junit/src/org/chromium/content/browser/SelectionPopupControllerTest.java",
+ "junit/src/org/chromium/content/browser/SmartSelectionMetricsLoggerTest.java",
"junit/src/org/chromium/content/browser/SpareChildConnectionTest.java",
"junit/src/org/chromium/content/browser/androidoverlay/DialogOverlayCoreTest.java",
"junit/src/org/chromium/content/browser/input/RangeTest.java",
diff --git a/chromium/content/public/android/OWNERS b/chromium/content/public/android/OWNERS
index 89e7bda9fc3..d6c853c953b 100644
--- a/chromium/content/public/android/OWNERS
+++ b/chromium/content/public/android/OWNERS
@@ -1,4 +1,3 @@
-aelias@chromium.org
boliu@chromium.org
dtrainor@chromium.org
tedchoc@chromium.org
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/input/OWNERS b/chromium/content/public/android/junit/src/org/chromium/content/browser/input/OWNERS
index 575b818d22a..af72a1e9492 100644
--- a/chromium/content/public/android/junit/src/org/chromium/content/browser/input/OWNERS
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/input/OWNERS
@@ -1,4 +1,3 @@
-aelias@chromium.org
changwan@chromium.org
# TEAM: input-dev@chromium.org
diff --git a/chromium/content/public/app/BUILD.gn b/chromium/content/public/app/BUILD.gn
index ed3bc4a396a..28730e51d4a 100644
--- a/chromium/content/public/app/BUILD.gn
+++ b/chromium/content/public/app/BUILD.gn
@@ -23,6 +23,7 @@
import("//build/config/chrome_build.gni")
import("//build/config/ui.gni")
import("//services/service_manager/public/service_manifest.gni")
+import("//ui/base/ui_features.gni")
public_app_shared_sources = [
"content_jni_onload.h",
@@ -43,7 +44,7 @@ public_app_shared_deps = [
"//services/service_manager/public/cpp",
]
-if (use_aura) {
+if (enable_mus) {
public_app_shared_deps += [ "//ui/aura" ]
}
@@ -189,7 +190,12 @@ service_manifest("packaged_services_manifest") {
"//services/resource_coordinator:manifest",
"//services/shape_detection:manifest",
"//services/video_capture:manifest",
+ "//services/viz:manifest",
]
+
+ if (enable_mus) {
+ packaged_services += [ "//services/ui:manifest" ]
+ }
}
service_manifest("browser_manifest") {
diff --git a/chromium/content/public/app/content_main_delegate.cc b/chromium/content/public/app/content_main_delegate.cc
index ee57df8f018..f1a25d02889 100644
--- a/chromium/content/public/app/content_main_delegate.cc
+++ b/chromium/content/public/app/content_main_delegate.cc
@@ -5,7 +5,6 @@
#include "content/public/app/content_main_delegate.h"
#include "build/build_config.h"
-
#include "content/public/gpu/content_gpu_client.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/utility/content_utility_client.h"
@@ -42,12 +41,12 @@ bool ContentMainDelegate::DelaySandboxInitialization(
return false;
}
-#elif defined(OS_POSIX) && !defined(OS_ANDROID)
+#elif defined(OS_LINUX)
void ContentMainDelegate::ZygoteStarting(
std::vector<std::unique_ptr<ZygoteForkDelegate>>* delegates) {}
-#endif
+#endif // defined(OS_LINUX)
bool ContentMainDelegate::ShouldEnableProfilerRecording() {
return false;
@@ -61,12 +60,6 @@ void ContentMainDelegate::AdjustServiceProcessCommandLine(
const service_manager::Identity& identity,
base::CommandLine* command_line) {}
-bool ContentMainDelegate::ShouldTerminateServiceManagerOnInstanceQuit(
- const service_manager::Identity& identity,
- int* exit_code) {
- return false;
-}
-
void ContentMainDelegate::OnServiceManagerInitialized(
const base::Closure& quit_closure,
service_manager::BackgroundServiceManager* service_manager) {}
diff --git a/chromium/content/public/app/content_main_delegate.h b/chromium/content/public/app/content_main_delegate.h
index b31cf6ccc01..0868d0d1b1b 100644
--- a/chromium/content/public/app/content_main_delegate.h
+++ b/chromium/content/public/app/content_main_delegate.h
@@ -9,12 +9,19 @@
#include <string>
#include <vector>
+#include "base/callback_forward.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
-#include "services/service_manager/background/background_service_manager.h"
#include "services/service_manager/embedder/process_type.h"
-#include "services/service_manager/public/cpp/identity.h"
-#include "services/service_manager/public/cpp/service.h"
+
+namespace base {
+class CommandLine;
+}
+
+namespace service_manager {
+class BackgroundServiceManager;
+class Identity;
+} // namespace service_manager
namespace content {
@@ -69,7 +76,7 @@ class CONTENT_EXPORT ContentMainDelegate {
// want it at all.
virtual bool DelaySandboxInitialization(const std::string& process_type);
-#elif defined(OS_POSIX) && !defined(OS_ANDROID)
+#elif defined(OS_LINUX)
// Tells the embedder that the zygote process is starting, and allows it to
// specify one or more zygote delegates if it wishes by storing them in
// |*delegates|.
@@ -78,7 +85,7 @@ class CONTENT_EXPORT ContentMainDelegate {
// Called every time the zygote process forks.
virtual void ZygoteForked() {}
-#endif // OS_MACOSX
+#endif // defined(OS_LINUX)
// TODO(vadimt, yiyaoliu): Remove this function once crbug.com/453640 is
// fixed.
@@ -95,13 +102,6 @@ class CONTENT_EXPORT ContentMainDelegate {
const service_manager::Identity& identity,
base::CommandLine* command_line);
- // Indicates if the Service Manager should be terminated in response to a
- // specific service instance quitting. If this returns |true|, the value in
- // |*exit_code| will be returned from the Service Manager's process on exit.
- virtual bool ShouldTerminateServiceManagerOnInstanceQuit(
- const service_manager::Identity& identity,
- int* exit_code);
-
// Allows the embedder to perform arbitrary initialization within the Service
// Manager process immediately before the Service Manager runs its main loop.
//
diff --git a/chromium/content/public/app/mojo/content_browser_manifest.json b/chromium/content/public/app/mojo/content_browser_manifest.json
index d7c965f830f..b6dbf79f059 100644
--- a/chromium/content/public/app/mojo/content_browser_manifest.json
+++ b/chromium/content/public/app/mojo/content_browser_manifest.json
@@ -9,6 +9,9 @@
"discardable_memory::mojom::DiscardableSharedMemoryManager",
"memory_instrumentation::mojom::Coordinator"
],
+ "font_cache": [
+ "content::mojom::FontCacheWin"
+ ],
"gpu": [
"content::mojom::FieldTrialRecorder",
"media::mojom::AndroidOverlayProvider"
@@ -20,40 +23,40 @@
"renderer": [
"blink::mojom::BackgroundFetchService",
"blink::mojom::BackgroundSyncService",
+ "blink::mojom::BlobRegistry",
"blink::mojom::BroadcastChannelProvider",
"blink::mojom::Hyphenation",
"blink::mojom::MimeRegistry",
"blink::mojom::NotificationService",
"blink::mojom::OffscreenCanvasProvider",
- "blink::mojom::PermissionService",
- "blink::mojom::WebSocket",
+ "blink::mojom::ReportingServiceProxy",
+ "blink::mojom::WebDatabaseHost",
+ "content::mojom::ClipboardHost",
"content::mojom::FieldTrialRecorder",
"content::mojom::FileUtilitiesHost",
"content::mojom::FrameSinkProvider",
"content::mojom::MediaStreamDispatcherHost",
"content::mojom::MemoryCoordinatorHandle",
"content::mojom::PushMessaging",
+ "content::mojom::QuotaDispatcherHost",
"content::mojom::RendererHost",
+ "content::mojom::ReportingServiceProxy",
"content::mojom::ServiceWorkerDispatcherHost",
"content::mojom::StoragePartitionService",
"content::mojom::URLLoaderFactory",
"content::mojom::VideoCaptureHost",
- "content::mojom::WebDatabaseHost",
"content::mojom::WorkerURLLoaderFactoryProvider",
"device::mojom::BatteryMonitor",
+ "device::mojom::GamepadHapticsManager",
"device::mojom::GamepadMonitor",
"discardable_memory::mojom::DiscardableSharedMemoryManager",
"media::mojom::VideoDecodePerfHistory",
"memory_coordinator::mojom::MemoryCoordinatorHandle",
"metrics::mojom::SingleSampleMetricsProvider",
- "payments::mojom::PaymentManager",
- "shape_detection::mojom::BarcodeDetection",
- "shape_detection::mojom::FaceDetectionProvider",
- "resource_coordinator::mojom::CoordinationUnit",
- "shape_detection::mojom::TextDetection",
- "storage::mojom::BlobRegistry",
+ "resource_coordinator::mojom::ProcessCoordinationUnit",
"ui::mojom::Gpu",
- "viz::mojom::SharedBitmapAllocationNotifier"
+ "viz::mojom::SharedBitmapAllocationNotifier",
+ "viz::mojom::CompositingModeReporter"
],
"geolocation_config": [
"device::mojom::GeolocationConfig"
@@ -66,18 +69,19 @@
"*": [ "app" ],
"cdm": [ "media:cdm" ],
"content_browser": [
- "url_keyed_metrics",
"geolocation_config"
],
"content_gpu": [ "browser" ],
"content_plugin": [ "browser" ],
"content_renderer": [ "browser" ],
"content_utility": [ "browser" ],
- "data_decoder": [ "image_decoder" ],
+ "data_decoder": [ "image_decoder", "json_parser", "xml_parser" ],
"device": [
"device:battery_monitor",
"device:generic_sensor",
+ "device:geolocation",
"device:hid",
+ "device:input_service",
"device:nfc",
"device:serial",
"device:vibration",
@@ -85,12 +89,14 @@
],
"file": [ "file:filesystem", "file:leveldb" ],
"media": [ "media:media" ],
+ "metrics": [ "url_keyed_metrics" ],
"network": [
"network_service",
"test",
"url_loader"
],
- "ui": [ "display_output_protection" ],
+ "patch_service": [ "patch_file" ],
+ "ui": [ "arc_manager", "display_output_protection", "video_detector" ],
"service_manager": [
"service_manager:client_process",
"service_manager:instance_name",
@@ -106,7 +112,7 @@
"coordination_unit",
"coordination_unit_introspector",
"service_callbacks",
- "tab_signal",
+ "page_signal",
"tracing"
],
"video_capture": [ "capture", "tests" ]
@@ -120,9 +126,13 @@
// impossible this week. Remove once sky/ken fix this.
"autofill::mojom::AutofillDriver",
"autofill::mojom::PasswordManagerDriver",
+ "blink::mojom::DedicatedWorkerFactory",
+ "blink::mojom::GeolocationService",
"blink::mojom::InsecureInputService",
"blink::mojom::KeyboardLockService",
+ "blink::mojom::MediaDevicesDispatcherHost",
"blink::mojom::MediaSessionService",
+ "blink::mojom::NotificationService",
"blink::mojom::PermissionService",
"blink::mojom::PresentationService",
"blink::mojom::TextSuggestionHost",
@@ -138,7 +148,6 @@
"content::mojom::RendererAudioOutputStreamFactory",
"content::mojom::SharedWorkerConnector",
"device::mojom::Geolocation",
- "device::mojom::GeolocationService",
"device::mojom::NFC",
"device::mojom::SensorProvider",
"device::mojom::VibrationManager",
@@ -153,11 +162,10 @@
"media::mojom::Renderer",
"media::mojom::VideoDecodeStatsRecorder",
"media::mojom::WatchTimeRecorderProvider",
- "mojom::MediaDevicesDispatcherHost",
"network::mojom::RestrictedCookieManager",
"payments::mojom::PaymentManager",
"payments::mojom::PaymentRequest",
- "resource_coordinator::mojom::CoordinationUnit",
+ "resource_coordinator::mojom::FrameCoordinationUnit",
"shape_detection::mojom::BarcodeDetection",
"shape_detection::mojom::FaceDetectionProvider",
"shape_detection::mojom::TextDetection",
@@ -168,6 +176,44 @@
"requires": {
"content_renderer": [ "browser" ]
}
+ },
+ "navigation:dedicated_worker": {
+ "provides": {
+ "renderer": [
+ "blink::mojom::NotificationService",
+ "blink::mojom::PermissionService",
+ "payments::mojom::PaymentManager",
+ "shape_detection::mojom::BarcodeDetection",
+ "shape_detection::mojom::FaceDetectionProvider",
+ "shape_detection::mojom::TextDetection"
+ ]
+ }
+ },
+ "navigation:service_worker": {
+ "provides": {
+ "renderer": [
+ "blink::mojom::NotificationService",
+ "blink::mojom::PermissionService",
+ "blink::mojom::WebSocket",
+ "payments::mojom::PaymentManager",
+ "shape_detection::mojom::BarcodeDetection",
+ "shape_detection::mojom::FaceDetectionProvider",
+ "shape_detection::mojom::TextDetection"
+ ]
+ }
+ },
+ "navigation:shared_worker": {
+ "provides": {
+ "renderer": [
+ "blink::mojom::NotificationService",
+ "blink::mojom::PermissionService",
+ "blink::mojom::WebSocket",
+ "payments::mojom::PaymentManager",
+ "shape_detection::mojom::BarcodeDetection",
+ "shape_detection::mojom::FaceDetectionProvider",
+ "shape_detection::mojom::TextDetection"
+ ]
+ }
}
}
}
diff --git a/chromium/content/public/app/mojo/content_gpu_manifest.json b/chromium/content/public/app/mojo/content_gpu_manifest.json
index 7792bd14e1c..73477a0375f 100644
--- a/chromium/content/public/app/mojo/content_gpu_manifest.json
+++ b/chromium/content/public/app/mojo/content_gpu_manifest.json
@@ -6,11 +6,13 @@
"provides": {
"browser": [
"content::mojom::Child",
+ "content::mojom::ChildControl",
"content::mojom::ChildHistogramFetcher",
"content::mojom::ChildHistogramFetcherFactory",
"IPC::mojom::ChannelBootstrap",
"service_manager::mojom::ServiceFactory",
- "ui::mojom::GpuMain"
+ "viz::mojom::CompositingModeReporter",
+ "viz::mojom::VizMain"
],
"service_manager:service_factory": [
"service_manager::mojom::ServiceFactory"
@@ -19,7 +21,8 @@
"requires": {
"*": [ "app" ],
"content_browser": [ "gpu" ],
- "device": [ "device:power_monitor" ]
+ "device": [ "device:power_monitor" ],
+ "metrics": [ "url_keyed_metrics" ]
}
}
}
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 c3c69f8fbe0..358bd19fbd4 100644
--- a/chromium/content/public/app/mojo/content_packaged_services_manifest.json
+++ b/chromium/content/public/app/mojo/content_packaged_services_manifest.json
@@ -19,8 +19,8 @@
"*": [ "app" ],
"content_browser": [],
"service_manager": [
- "service_manager:all_users",
"service_manager:client_process",
+ "service_manager:singleton",
"service_manager:user_id"
]
}
diff --git a/chromium/content/public/app/mojo/content_plugin_manifest.json b/chromium/content/public/app/mojo/content_plugin_manifest.json
index d88d29736d1..21818a08231 100644
--- a/chromium/content/public/app/mojo/content_plugin_manifest.json
+++ b/chromium/content/public/app/mojo/content_plugin_manifest.json
@@ -6,6 +6,7 @@
"provides": {
"browser": [
"content::mojom::Child",
+ "content::mojom::ChildControl",
"content::mojom::ChildHistogramFetcher",
"content::mojom::ChildHistogramFetcherFactory",
"IPC::mojom::ChannelBootstrap"
@@ -16,7 +17,10 @@
},
"requires": {
"*": [ "app" ],
- "content_browser": [ "plugin" ],
+ "content_browser": [
+ "font_cache",
+ "plugin"
+ ],
"device": [ "device:power_monitor" ],
"ui": [ "discardable_memory" ]
}
diff --git a/chromium/content/public/app/mojo/content_renderer_manifest.json b/chromium/content/public/app/mojo/content_renderer_manifest.json
index 1e773f67149..d06258b6d8e 100644
--- a/chromium/content/public/app/mojo/content_renderer_manifest.json
+++ b/chromium/content/public/app/mojo/content_renderer_manifest.json
@@ -5,7 +5,10 @@
"service_manager:connector": {
"provides": {
"browser": [
+ "blink::mojom::OomIntervention",
+ "blink::mojom::WebDatabase",
"content::mojom::Child",
+ "content::mojom::ChildControl",
"content::mojom::ChildHistogramFetcher",
"content::mojom::ChildHistogramFetcherFactory",
"content::mojom::EmbeddedWorkerInstanceClient",
@@ -13,7 +16,6 @@
"content::mojom::FrameFactory",
"content::mojom::RenderWidgetWindowTreeClientFactory",
"content::mojom::SharedWorkerFactory",
- "content::mojom::WebDatabase",
"IPC::mojom::ChannelBootstrap",
"visitedlink::mojom::VisitedLinkNotificationSink",
"web_cache::mojom::WebCache"
@@ -25,6 +27,7 @@
"requires": {
"*": [ "app" ],
"content_browser": [ "renderer" ],
+ "metrics": [ "url_keyed_metrics" ],
"device": [
"device:power_monitor",
"device:screen_orientation",
@@ -44,17 +47,32 @@
"blink::mojom::EngagementClient",
"blink::mojom::InstallationService",
"blink::mojom::ManifestManager",
+ "blink::mojom::MediaDevicesListener",
"blink::mojom::TextSuggestionBackend",
"content::mojom::ImageDownloader",
"content::mojom::FrameInputHandler",
"content::mojom::MediaStreamDispatcher",
- "content::mojom::Widget",
- "mojom::MediaDevicesListener"
+ "content::mojom::Widget"
]
},
"requires": {
"content_browser": [ "renderer" ]
}
+ },
+ "navigation:dedicated_worker": {
+ "requires": {
+ "content_browser": [ "renderer" ]
+ }
+ },
+ "navigation:service_worker": {
+ "requires": {
+ "content_browser": [ "renderer" ]
+ }
+ },
+ "navigation:shared_worker": {
+ "requires": {
+ "content_browser": [ "renderer" ]
+ }
}
},
"required_files" : {
diff --git a/chromium/content/public/app/mojo/content_utility_manifest.json b/chromium/content/public/app/mojo/content_utility_manifest.json
index 4fe711da723..3b7266000b5 100644
--- a/chromium/content/public/app/mojo/content_utility_manifest.json
+++ b/chromium/content/public/app/mojo/content_utility_manifest.json
@@ -6,10 +6,11 @@
"provides": {
"browser": [
"content::mojom::Child",
- "printing::mojom::PDFToPWGRasterConverter",
+ "content::mojom::ChildControl",
"content::mojom::ChildHistogramFetcher",
"content::mojom::ChildHistogramFetcherFactory",
"IPC::mojom::ChannelBootstrap",
+ "printing::mojom::PDFToPWGRasterConverter",
"service_manager::mojom::ServiceFactory"
],
"service_manager:service_factory": [
@@ -18,6 +19,9 @@
},
"requires": {
"*": [ "app" ],
+ "content_browser": [
+ "font_cache"
+ ],
"device": [
"device:power_monitor",
"device:time_zone_monitor"
diff --git a/chromium/content/public/browser/BUILD.gn b/chromium/content/public/browser/BUILD.gn
index 2a8e39cb95f..ab5fdf3f559 100644
--- a/chromium/content/public/browser/BUILD.gn
+++ b/chromium/content/public/browser/BUILD.gn
@@ -115,12 +115,15 @@ source_set("browser_sources") {
"download_manager.h",
"download_manager_delegate.cc",
"download_manager_delegate.h",
+ "download_request_utils.h",
"download_save_info.cc",
"download_save_info.h",
+ "download_source.h",
"download_url_parameters.cc",
"download_url_parameters.h",
"favicon_status.cc",
"favicon_status.h",
+ "file_url_loader.h",
"focused_node_details.h",
"font_list_async.h",
"frame_service_base.h",
@@ -137,7 +140,6 @@ source_set("browser_sources") {
"guest_mode.cc",
"guest_mode.h",
"histogram_fetcher.h",
- "ignore_errors_cert_verifier.h",
"indexed_db_context.h",
"indexed_db_info.h",
"interstitial_page.h",
@@ -246,6 +248,7 @@ source_set("browser_sources") {
"service_worker_usage_info.h",
"session_storage_namespace.h",
"session_storage_usage_info.h",
+ "shared_worker_service.h",
"site_instance.h",
"speech_recognition_event_listener.h",
"speech_recognition_manager.h",
@@ -302,8 +305,6 @@ source_set("browser_sources") {
"websocket_handshake_request_info.h",
"webvr_service_provider.cc",
"webvr_service_provider.h",
- "worker_service.h",
- "worker_service_observer.h",
"zygote_handle_linux.h",
"zygote_host_linux.h",
]
@@ -380,6 +381,8 @@ source_set("browser_sources") {
sources += [
"desktop_capture.cc",
"desktop_capture.h",
+ "webrtc_log.cc",
+ "webrtc_log.h",
]
deps += [ "//third_party/webrtc/modules/desktop_capture" ]
}
diff --git a/chromium/content/public/browser/DEPS b/chromium/content/public/browser/DEPS
index 7ddda911251..f4b7aeee08c 100644
--- a/chromium/content/public/browser/DEPS
+++ b/chromium/content/public/browser/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+content/common/input/input_handler.mojom.h",
"+components/viz/common",
+ "+device/geolocation/public/cpp",
"+device/screen_orientation/public/interfaces",
"+services/device/public/interfaces",
"+services/service_manager/sandbox",
diff --git a/chromium/content/public/browser/android/OWNERS b/chromium/content/public/browser/android/OWNERS
index db48a41cd0d..5565397693f 100644
--- a/chromium/content/public/browser/android/OWNERS
+++ b/chromium/content/public/browser/android/OWNERS
@@ -1,4 +1,3 @@
-aelias@chromium.org
boliu@chromium.org
tedchoc@chromium.org
yfriedman@chromium.org
diff --git a/chromium/content/public/browser/android/compositor.h b/chromium/content/public/browser/android/compositor.h
index 9b5437bc89e..9b8eb491bd7 100644
--- a/chromium/content/public/browser/android/compositor.h
+++ b/chromium/content/public/browser/android/compositor.h
@@ -68,9 +68,15 @@ class CONTENT_EXPORT Compositor {
// Set the output surface bounds.
virtual void SetWindowBounds(const gfx::Size& size) = 0;
+ // Defer commits on the layer tree host.
+ virtual void SetDeferCommits(bool defer_commits) = 0;
+
// Set the output surface which the compositor renders into.
virtual void SetSurface(jobject surface) = 0;
+ // Set the background color used by the layer tree host.
+ virtual void SetBackgroundColor(int color) = 0;
+
// Tells the compositor to allocate an alpha channel. This won't take effect
// until the compositor selects a new egl config, usually when the underlying
// Android Surface changes format.
diff --git a/chromium/content/public/browser/background_fetch_delegate.h b/chromium/content/public/browser/background_fetch_delegate.h
index e8f0cb2d43a..8b6670062f1 100644
--- a/chromium/content/public/browser/background_fetch_delegate.h
+++ b/chromium/content/public/browser/background_fetch_delegate.h
@@ -21,6 +21,10 @@ class HttpRequestHeaders;
struct NetworkTrafficAnnotationTag;
} // namespace net
+namespace url {
+class Origin;
+} // namespace url
+
namespace content {
struct BackgroundFetchResponse;
struct BackgroundFetchResult;
@@ -29,50 +33,38 @@ struct BackgroundFetchResult;
// generally interface with the DownloadService or DownloadManager.
// Must only be used on the UI thread and generally expected to be called by the
// BackgroundFetchDelegateProxy.
-// TODO(delphick): Move this content/public/browser.
class CONTENT_EXPORT BackgroundFetchDelegate {
public:
- // Failures that happen after the download has already started.
- enum FailureReason {
- // Used when the download has been aborted after reaching a threshold where
- // it was decided it is not worth attempting to start again. This could be
- // either due to a specific number of failed retry attempts or a specific
- // number of wasted bytes due to the download restarting.
- NETWORK,
-
- // Used when the download was not completed before the timeout.
- TIMEDOUT,
-
- // Used when the failure reason is unknown.
- UNKNOWN,
- };
-
// Client interface that a BackgroundFetchDelegate would use to signal the
// progress of a background fetch.
class Client {
public:
virtual ~Client() {}
+ // Called when the entire download job has been cancelled by the delegate,
+ // e.g. because the user clicked cancel on a notification.
+ virtual void OnJobCancelled(const std::string& job_unique_id) = 0;
+
// Called after the download has started with the initial response
// (including headers and URL chain). Always called on the UI thread.
virtual void OnDownloadStarted(
- const std::string& guid,
+ const std::string& job_unique_id,
+ const std::string& download_guid,
std::unique_ptr<content::BackgroundFetchResponse> response) = 0;
// Called during the download to indicate the current progress. Always
// called on the UI thread.
- virtual void OnDownloadUpdated(const std::string& guid,
+ virtual void OnDownloadUpdated(const std::string& job_unique_id,
+ const std::string& download_guid,
uint64_t bytes_downloaded) = 0;
// Called after the download has completed giving the result including the
// path to the downloaded file and its size. Always called on the UI thread.
virtual void OnDownloadComplete(
- const std::string& guid,
+ const std::string& job_unique_id,
+ const std::string& download_guid,
std::unique_ptr<BackgroundFetchResult> result) = 0;
- virtual void OnDownloadFailed(const std::string& guid,
- FailureReason reason) = 0;
-
// Called by the delegate when it's shutting down to signal that the
// delegate is no longer valid.
virtual void OnDelegateShutdown() = 0;
@@ -82,13 +74,33 @@ class CONTENT_EXPORT BackgroundFetchDelegate {
virtual ~BackgroundFetchDelegate();
+ // Creates a new download grouping identified by |job_unique_id|. Further
+ // downloads started by DownloadUrl will also use this |job_unique_id| so that
+ // a notification can be updated with the current status. If the download was
+ // already started in a previous browser session, then |current_guids| should
+ // contain the GUIDs of in progress downloads, while completed downloads are
+ // recorded in |completed_parts|.
+ virtual void CreateDownloadJob(
+ const std::string& job_unique_id,
+ const std::string& title,
+ const url::Origin& origin,
+ int completed_parts,
+ int total_parts,
+ const std::vector<std::string>& current_guids) = 0;
+
+ // Creates a new download identified by |download_guid| in the download job
+ // identified by |job_unique_id|.
virtual void DownloadUrl(
- const std::string& guid,
+ const std::string& job_unique_id,
+ const std::string& download_guid,
const std::string& method,
const GURL& url,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
const net::HttpRequestHeaders& headers) = 0;
+ // Aborts any downloads associated with |job_unique_id|.
+ virtual void Abort(const std::string& job_unique_id) = 0;
+
// Set the client that the delegate should communicate changes to.
void SetDelegateClient(base::WeakPtr<Client> client) { client_ = client; }
diff --git a/chromium/content/public/browser/background_fetch_response.cc b/chromium/content/public/browser/background_fetch_response.cc
index 2b65eaf70c1..b27cd14524a 100644
--- a/chromium/content/public/browser/background_fetch_response.cc
+++ b/chromium/content/public/browser/background_fetch_response.cc
@@ -13,13 +13,17 @@ BackgroundFetchResponse::BackgroundFetchResponse(
BackgroundFetchResponse::~BackgroundFetchResponse() {}
-BackgroundFetchResult::BackgroundFetchResult(base::Time response_time)
- : response_time(response_time) {}
+BackgroundFetchResult::BackgroundFetchResult(base::Time response_time,
+ FailureReason failure_reason)
+ : response_time(response_time), failure_reason(failure_reason) {}
BackgroundFetchResult::BackgroundFetchResult(base::Time response_time,
const base::FilePath& path,
uint64_t file_size)
- : response_time(response_time), file_path(path), file_size(file_size) {}
+ : response_time(response_time),
+ file_path(path),
+ file_size(file_size),
+ failure_reason(FailureReason::NONE) {}
BackgroundFetchResult::~BackgroundFetchResult() {}
diff --git a/chromium/content/public/browser/background_fetch_response.h b/chromium/content/public/browser/background_fetch_response.h
index 1debd98f984..00bf91c49ea 100644
--- a/chromium/content/public/browser/background_fetch_response.h
+++ b/chromium/content/public/browser/background_fetch_response.h
@@ -31,8 +31,31 @@ struct CONTENT_EXPORT BackgroundFetchResponse {
};
struct CONTENT_EXPORT BackgroundFetchResult {
+ // Failures that happen after the download has already started and are
+ // reported via |BackgroundFetchDelegate::Client::OnDownloadComplete|.
+ enum class FailureReason {
+ // None of below failures occurred, although the fetch could still have
+ // failed with an error code such as 404.
+ NONE,
+
+ // Used when the download has been aborted after reaching a threshold where
+ // it was decided it is not worth attempting to start again. This could be
+ // either due to a specific number of failed retry attempts or a specific
+ // number of wasted bytes due to the download restarting.
+ NETWORK,
+
+ // Used when the download was not completed before the timeout.
+ TIMEDOUT,
+
+ // Used when the download was cancelled by the user.
+ CANCELLED,
+
+ // Used when the failure reason is unknown.
+ UNKNOWN,
+ };
+
// Constructor for failed downloads.
- explicit BackgroundFetchResult(base::Time response_time);
+ BackgroundFetchResult(base::Time response_time, FailureReason failure_reason);
// Constructor for successful downloads.
BackgroundFetchResult(base::Time response_time,
@@ -44,6 +67,7 @@ struct CONTENT_EXPORT BackgroundFetchResult {
const base::Time response_time;
const base::FilePath file_path;
const uint64_t file_size = 0;
+ FailureReason failure_reason;
private:
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchResult);
diff --git a/chromium/content/public/browser/browser_context.h b/chromium/content/public/browser/browser_context.h
index eff149812e0..f75be61ccde 100644
--- a/chromium/content/public/browser/browser_context.h
+++ b/chromium/content/public/browser/browser_context.h
@@ -41,6 +41,10 @@ namespace storage {
class ExternalMountPoints;
}
+namespace media {
+class VideoDecodePerfHistory;
+}
+
namespace net {
class URLRequestContextGetter;
}
@@ -127,12 +131,14 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
static StoragePartition* GetDefaultStoragePartition(
BrowserContext* browser_context);
- using BlobCallback = base::Callback<void(std::unique_ptr<BlobHandle>)>;
+ using BlobCallback = base::OnceCallback<void(std::unique_ptr<BlobHandle>)>;
// |callback| returns a nullptr scoped_ptr on failure.
static void CreateMemoryBackedBlob(BrowserContext* browser_context,
- const char* data, size_t length,
- const BlobCallback& callback);
+ const char* data,
+ size_t length,
+ const std::string& content_type,
+ BlobCallback callback);
// |callback| returns a nullptr scoped_ptr on failure.
static void CreateFileBackedBlob(BrowserContext* browser_context,
@@ -140,7 +146,7 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
int64_t offset,
int64_t size,
const base::Time& expected_modification_time,
- const BlobCallback& callback);
+ BlobCallback callback);
// Delivers a push message with |data| to the Service Worker identified by
// |origin| and |service_worker_registration_id|.
@@ -298,6 +304,12 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
// 2) The embedder saves its salt across restarts.
static std::string CreateRandomMediaDeviceIDSalt();
+ // Media service for storing/retrieving video decoding performance stats.
+ // Exposed here rather than StoragePartition because all SiteInstances should
+ // have similar decode performance and stats are not exposed to the web
+ // directly, so privacy is not compromised.
+ virtual media::VideoDecodePerfHistory* GetVideoDecodePerfHistory();
+
private:
const std::string media_device_id_salt_;
};
diff --git a/chromium/content/public/browser/browser_plugin_guest_delegate.h b/chromium/content/public/browser/browser_plugin_guest_delegate.h
index ef0ff9d6f67..9a3c2375c7f 100644
--- a/chromium/content/public/browser/browser_plugin_guest_delegate.h
+++ b/chromium/content/public/browser/browser_plugin_guest_delegate.h
@@ -56,11 +56,6 @@ class CONTENT_EXPORT BrowserPluginGuestDelegate {
// Returns the WebContents that currently owns this guest.
virtual WebContents* GetOwnerWebContents() const;
- // Notifies that the content size of the guest has changed.
- // Note: In autosize mode, it is possible that the guest size may not match
- // the element size.
- virtual void GuestSizeChanged(const gfx::Size& new_size) {}
-
// Asks the delegate if the given guest can lock the pointer.
// Invoking the |callback| synchronously is OK.
virtual void RequestPointerLockPermission(
diff --git a/chromium/content/public/browser/browser_thread.h b/chromium/content/public/browser/browser_thread.h
index 472a7136db0..e9ff7d5410c 100644
--- a/chromium/content/public/browser/browser_thread.h
+++ b/chromium/content/public/browser/browser_thread.h
@@ -236,12 +236,14 @@ class CONTENT_EXPORT BrowserThread {
// Use these templates in conjunction with RefCountedThreadSafe or scoped_ptr
// when you want to ensure that an object is deleted on a specific thread.
- // This is needed when an object can hop between threads
- // (i.e. IO -> FILE -> IO), and thread switching delays can mean that the
- // final IO tasks executes before the FILE task's stack unwinds.
- // This would lead to the object destructing on the FILE thread, which often
- // is not what you want (i.e. to unregister from NotificationService, to
- // notify other objects on the creating thread etc).
+ // This is needed when an object can hop between threads (i.e. UI -> IO ->
+ // UI), and thread switching delays can mean that the final UI tasks executes
+ // before the IO task's stack unwinds. This would lead to the object
+ // destructing on the IO thread, which often is not what you want (i.e. to
+ // unregister from NotificationService, to notify other objects on the
+ // creating thread etc). Note: see base::OnTaskRunnerDeleter and
+ // base::RefCountedDeleteOnSequence to bind to SequencedTaskRunner instead of
+ // specific BrowserThreads.
template<ID thread>
struct DeleteOnThread {
template<typename T>
@@ -280,13 +282,10 @@ class CONTENT_EXPORT BrowserThread {
// Sample usage with scoped_ptr:
// std::unique_ptr<Foo, BrowserThread::DeleteOnIOThread> ptr;
//
- // Note: when migrating BrowserThreads to TaskScheduler based
- // SequencedTaskRunners these map to base::OnTaskRunnerDeleter and
- // base::RefCountedDeleteOnSequence.
+ // Note: see base::OnTaskRunnerDeleter and base::RefCountedDeleteOnSequence to
+ // bind to SequencedTaskRunner instead of specific BrowserThreads.
struct DeleteOnUIThread : public DeleteOnThread<UI> { };
struct DeleteOnIOThread : public DeleteOnThread<IO> { };
- struct DeleteOnFileThread : public DeleteOnThread<FILE> { };
- struct DeleteOnDBThread : public DeleteOnThread<DB> { };
// Returns an appropriate error message for when DCHECK_CURRENTLY_ON() fails.
static std::string GetDCheckCurrentlyOnErrorMessage(ID expected);
diff --git a/chromium/content/public/browser/certificate_request_result_type.h b/chromium/content/public/browser/certificate_request_result_type.h
index 5a2b23b7f82..8b38022bfe3 100644
--- a/chromium/content/public/browser/certificate_request_result_type.h
+++ b/chromium/content/public/browser/certificate_request_result_type.h
@@ -16,7 +16,8 @@ enum CertificateRequestResultType {
// Cancels the request synchronously using a net::ERR_ABORTED.
CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL,
- // Denies the request synchronously using a net::ERR_INSECURE_RESPONSE.
+ // Denies the request synchronously using the certificate error code that was
+ // encountered.
CERTIFICATE_REQUEST_RESULT_TYPE_DENY,
};
diff --git a/chromium/content/public/browser/child_process_security_policy.h b/chromium/content/public/browser/child_process_security_policy.h
index f773bcce77c..9ebdbd08c7c 100644
--- a/chromium/content/public/browser/child_process_security_policy.h
+++ b/chromium/content/public/browser/child_process_security_policy.h
@@ -213,6 +213,31 @@ class ChildProcessSecurityPolicy {
// check is superseded by a UI thread check. See https://crbug.com/656752.
virtual bool HasSpecificPermissionForOrigin(int child_id,
const url::Origin& origin) = 0;
+
+ // This function will check whether |origin| requires process isolation, and
+ // if so, it will return true and put the most specific matching isolated
+ // origin into |result|.
+ //
+ // Such origins may be registered with the --isolate-origins command-line
+ // flag, via features::IsolateOrigins, via an IsolateOrigins enterprise
+ // policy, or by a content/ embedder using
+ // ContentBrowserClient::GetOriginsRequiringDedicatedProcess().
+ //
+ // If |origin| does not require process isolation, this function will return
+ // false, and |result| will be a unique origin. This means that neither
+ // |origin|, nor any origins for which |origin| is a subdomain, have been
+ // registered as isolated origins.
+ //
+ // For example, if both https://isolated.com/ and
+ // https://bar.foo.isolated.com/ are registered as isolated origins, then the
+ // values returned in |result| are:
+ // https://isolated.com/ --> https://isolated.com/
+ // https://foo.isolated.com/ --> https://isolated.com/
+ // https://bar.foo.isolated.com/ --> https://bar.foo.isolated.com/
+ // https://baz.bar.foo.isolated.com/ --> https://bar.foo.isolated.com/
+ // https://unisolated.com/ --> (unique origin)
+ virtual bool GetMatchingIsolatedOrigin(const url::Origin& origin,
+ url::Origin* result) = 0;
};
} // namespace content
diff --git a/chromium/content/public/browser/content_browser_client.cc b/chromium/content/public/browser/content_browser_client.cc
index 70cc5e2e8de..5ba7212ac60 100644
--- a/chromium/content/public/browser/content_browser_client.cc
+++ b/chromium/content/public/browser/content_browser_client.cc
@@ -18,6 +18,7 @@
#include "content/public/browser/vpn_service_proxy.h"
#include "content/public/common/content_features.h"
#include "content/public/common/url_loader_throttle.h"
+#include "device/geolocation/public/cpp/location_provider.h"
#include "media/audio/audio_manager.h"
#include "media/base/cdm_factory.h"
#include "media/media_features.h"
@@ -33,6 +34,13 @@
namespace content {
+void OverrideOnBindInterface(const service_manager::BindSourceInfo& remote_info,
+ const std::string& name,
+ mojo::ScopedMessagePipeHandle* handle) {
+ GetContentClient()->browser()->OverrideOnBindInterface(remote_info, name,
+ handle);
+}
+
BrowserMainParts* ContentBrowserClient::CreateBrowserMainParts(
const MainFunctionParams& parameters) {
return nullptr;
@@ -56,9 +64,12 @@ WebContentsViewDelegate* ContentBrowserClient::GetWebContentsViewDelegate(
return nullptr;
}
+bool ContentBrowserClient::AllowGpuLaunchRetryOnIOThread() {
+ return true;
+}
+
GURL ContentBrowserClient::GetEffectiveURL(BrowserContext* browser_context,
- const GURL& url,
- bool is_isolated_origin) {
+ const GURL& url) {
return url;
}
@@ -108,6 +119,12 @@ bool ContentBrowserClient::ShouldAllowOpenURL(SiteInstance* site_instance,
return true;
}
+bool ContentBrowserClient::IsURLAcceptableForWebUI(
+ BrowserContext* browser_context,
+ const GURL& url) {
+ return false;
+}
+
bool ContentBrowserClient::
ShouldFrameShareParentSiteInstanceDespiteTopDocumentIsolation(
const GURL& url,
@@ -167,6 +184,13 @@ ContentBrowserClient::GetOriginsRequiringDedicatedProcess() {
return std::vector<url::Origin>();
}
+bool ContentBrowserClient::IsFileAccessAllowed(
+ const base::FilePath& path,
+ const base::FilePath& absolute_path,
+ const base::FilePath& profile_path) {
+ return true;
+}
+
std::string ContentBrowserClient::GetApplicationLocale() {
return "en-US";
}
@@ -199,6 +223,17 @@ bool ContentBrowserClient::AllowServiceWorker(
return true;
}
+bool ContentBrowserClient::AllowSharedWorker(
+ const GURL& worker_url,
+ const GURL& main_frame_url,
+ const std::string& name,
+ const url::Origin& constructor_origin,
+ BrowserContext* context,
+ int render_process_id,
+ int render_frame_id) {
+ return true;
+}
+
bool ContentBrowserClient::IsDataSaverEnabled(BrowserContext* context) {
return false;
}
@@ -221,7 +256,7 @@ bool ContentBrowserClient::AllowGetCookie(const GURL& url,
bool ContentBrowserClient::AllowSetCookie(const GURL& url,
const GURL& first_party,
- const std::string& cookie_line,
+ const net::CanonicalCookie& cookie,
ResourceContext* context,
int render_process_id,
int render_frame_id,
@@ -292,6 +327,11 @@ net::URLRequestContext* ContentBrowserClient::OverrideRequestContextForURL(
return nullptr;
}
+std::unique_ptr<device::LocationProvider>
+ContentBrowserClient::OverrideSystemLocationProvider() {
+ return nullptr;
+}
+
void ContentBrowserClient::GetGeolocationRequestContext(
base::OnceCallback<void(scoped_refptr<net::URLRequestContextGetter>)>
callback) {
@@ -381,11 +421,6 @@ BrowserPpapiHost*
return nullptr;
}
-gpu::GpuChannelEstablishFactory*
-ContentBrowserClient::GetGpuChannelEstablishFactory() {
- return nullptr;
-}
-
bool ContentBrowserClient::AllowPepperSocketAPI(
BrowserContext* browser_context,
const GURL& url,
@@ -497,6 +532,11 @@ std::unique_ptr<base::Value> ContentBrowserClient::GetServiceManifestOverlay(
return nullptr;
}
+bool ContentBrowserClient::ShouldTerminateOnServiceQuit(
+ const service_manager::Identity& id) {
+ return false;
+}
+
std::vector<ContentBrowserClient::ServiceManifestInfo>
ContentBrowserClient::GetExtraServiceManifests() {
return std::vector<ContentBrowserClient::ServiceManifestInfo>();
@@ -522,6 +562,15 @@ ContentBrowserClient::CreateURLLoaderThrottles(
return std::vector<std::unique_ptr<URLLoaderThrottle>>();
}
+void ContentBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
+ RenderFrameHost* frame_host,
+ NonNetworkURLLoaderFactoryMap* factories) {}
+
+void ContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories(
+ RenderFrameHost* frame_host,
+ const GURL& frame_url,
+ NonNetworkURLLoaderFactoryMap* factories) {}
+
mojom::NetworkContextPtr ContentBrowserClient::CreateNetworkContext(
BrowserContext* context,
bool in_memory,
diff --git a/chromium/content/public/browser/content_browser_client.h b/chromium/content/public/browser/content_browser_client.h
index 61c108c53b9..6b6614b9b04 100644
--- a/chromium/content/public/browser/content_browser_client.h
+++ b/chromium/content/public/browser/content_browser_client.h
@@ -19,7 +19,6 @@
#include "build/build_config.h"
#include "content/public/browser/certificate_request_result_type.h"
#include "content/public/browser/navigation_throttle.h"
-#include "content/public/common/associated_interface_registry.h"
#include "content/public/common/content_client.h"
#include "content/public/common/media_stream_request.h"
#include "content/public/common/network_service.mojom.h"
@@ -35,7 +34,8 @@
#include "services/service_manager/sandbox/sandbox_type.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/quota/quota_manager.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_registry.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/web/window_features.mojom.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/window_open_disposition.h"
@@ -55,12 +55,12 @@ class CommandLine;
class FilePath;
}
-namespace gfx {
-class ImageSkia;
+namespace device {
+class LocationProvider;
}
-namespace gpu {
-class GpuChannelEstablishFactory;
+namespace gfx {
+class ImageSkia;
}
namespace media {
@@ -151,6 +151,11 @@ namespace mojom {
class NetworkContext;
}
+CONTENT_EXPORT void OverrideOnBindInterface(
+ const service_manager::BindSourceInfo& remote_info,
+ const std::string& name,
+ mojo::ScopedMessagePipeHandle* handle);
+
// Embedder API (or SPI) for participating in browser logic, to be implemented
// by the client of the content browser. See ChromeContentBrowserClient for the
// principal implementation. The methods are assumed to be called on the UI
@@ -196,6 +201,9 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual WebContentsViewDelegate* GetWebContentsViewDelegate(
WebContents* web_contents);
+ // Allow embedder control GPU process launch retry on failure behavior.
+ virtual bool AllowGpuLaunchRetryOnIOThread();
+
// Notifies that a render process will be created. This is called before
// the content layer adds its own BrowserMessageFilters, so that the
// embedder's IPC filters have priority.
@@ -206,12 +214,8 @@ class CONTENT_EXPORT ContentBrowserClient {
// Get the effective URL for the given actual URL, to allow an embedder to
// group different url schemes in the same SiteInstance.
- // |is_isolated_origin| specifies whether |url| corresponds to an origin that
- // requires process isolation. Certain kinds of effective URLs should be
- // ignored for such origins.
virtual GURL GetEffectiveURL(BrowserContext* browser_context,
- const GURL& url,
- bool is_isolated_origin);
+ const GURL& url);
// Returns whether all instances of the specified effective URL should be
// rendered by the same process, rather than using process-per-site-instance.
@@ -278,6 +282,12 @@ class CONTENT_EXPORT ContentBrowserClient {
// This also applies in cases where the new URL will open in another process.
virtual bool ShouldAllowOpenURL(SiteInstance* site_instance, const GURL& url);
+ // Returns whether a URL can be displayed within a WebUI for a given
+ // BrowserContext. Temporary workaround while crbug.com/768526 is resolved.
+ // Note: This is used by an internal Cast implementation of this class.
+ virtual bool IsURLAcceptableForWebUI(BrowserContext* browser_context,
+ const GURL& url);
+
// Allows the embedder to override parameters when navigating. Called for both
// opening new URLs and when transferring URLs across processes.
virtual void OverrideNavigationParams(SiteInstance* site_instance,
@@ -344,6 +354,12 @@ class CONTENT_EXPORT ContentBrowserClient {
// process.
virtual std::vector<url::Origin> GetOriginsRequiringDedicatedProcess();
+ // Indicates whether a file path should be accessible via file URL given a
+ // request from a browser context which lives within |profile_path|.
+ virtual bool IsFileAccessAllowed(const base::FilePath& path,
+ const base::FilePath& absolute_path,
+ const base::FilePath& profile_path);
+
// Allows the embedder to pass extra command line flags.
// switches::kProcessType will already be set at this point.
virtual void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
@@ -389,6 +405,17 @@ class CONTENT_EXPORT ContentBrowserClient {
ResourceContext* context,
const base::Callback<WebContents*(void)>& wc_getter);
+ // Allow the embedder to control if a Shared Worker can be connected from a
+ // given tab.
+ // This is called on the UI thread.
+ virtual bool AllowSharedWorker(const GURL& worker_url,
+ const GURL& main_frame_url,
+ const std::string& name,
+ const url::Origin& constructor_origin,
+ BrowserContext* context,
+ int render_process_id,
+ int render_frame_id);
+
virtual bool IsDataSaverEnabled(BrowserContext* context);
// Allow the embedder to return additional headers that should be sent when
@@ -410,7 +437,7 @@ class CONTENT_EXPORT ContentBrowserClient {
// This is called on the IO thread.
virtual bool AllowSetCookie(const GURL& url,
const GURL& first_party,
- const std::string& cookie_line,
+ const net::CanonicalCookie& cookie,
ResourceContext* context,
int render_process_id,
int render_frame_id,
@@ -468,6 +495,12 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual net::URLRequestContext* OverrideRequestContextForURL(
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
+ // created.
+ virtual std::unique_ptr<device::LocationProvider>
+ OverrideSystemLocationProvider();
+
// Allows the embedder to provide a URLRequestContextGetter to use for network
// geolocation queries.
// * May be called from any thread. A URLRequestContextGetter is then provided
@@ -623,9 +656,6 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual BrowserPpapiHost* GetExternalBrowserPpapiHost(
int plugin_child_id);
- // Gets the factory to use to establish a connection to the GPU process.
- virtual gpu::GpuChannelEstablishFactory* GetGpuChannelEstablishFactory();
-
// Returns true if the socket operation specified by |params| is allowed from
// the given |browser_context| and |url|. If |params| is nullptr, this method
// checks the basic "socket" permission, which is for those operations that
@@ -706,7 +736,7 @@ class CONTENT_EXPORT ContentBrowserClient {
// task runner is provided.
virtual void ExposeInterfacesToRenderer(
service_manager::BinderRegistry* registry,
- AssociatedInterfaceRegistry* associated_registry,
+ blink::AssociatedInterfaceRegistry* associated_registry,
RenderProcessHost* render_process_host) {}
// Called when RenderFrameHostImpl connects to the Media service. Expose
@@ -730,6 +760,15 @@ class CONTENT_EXPORT ContentBrowserClient {
const std::string& interface_name,
mojo::ScopedInterfaceEndpointHandle* handle);
+ // Content was unable to bind a request for this interface, so the embedder
+ // should try. This is called for interface requests from dedicated, shared
+ // and service workers.
+ virtual void BindInterfaceRequestFromWorker(
+ RenderProcessHost* render_process_host,
+ const url::Origin& origin,
+ const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) {}
+
// (Currently called only from GPUProcessHost, move somewhere more central).
// Called when a request to bind |interface_name| on |interface_pipe| is
// received from |source_info.identity|. If the request is bound,
@@ -746,6 +785,11 @@ class CONTENT_EXPORT ContentBrowserClient {
// Manager.
virtual void RegisterInProcessServices(StaticServiceMap* services) {}
+ virtual void OverrideOnBindInterface(
+ const service_manager::BindSourceInfo& remote_info,
+ const std::string& name,
+ mojo::ScopedMessagePipeHandle* handle) {}
+
using OutOfProcessServiceMap = std::map<std::string, base::string16>;
// Registers services to be loaded out of the browser process in an
@@ -753,6 +797,11 @@ class CONTENT_EXPORT ContentBrowserClient {
// to use for the service's host process when launched.
virtual void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) {}
+ // Allows the embedder to terminate the browser if a specific service instance
+ // quits or crashes.
+ virtual bool ShouldTerminateOnServiceQuit(
+ const service_manager::Identity& id);
+
// Allow the embedder to provide a dictionary loaded from a JSON file
// resembling a service manifest whose capabilities section will be merged
// with content's own for |name|. Additional entries will be appended to their
@@ -776,7 +825,7 @@ class CONTENT_EXPORT ContentBrowserClient {
// |visibility_state| should not be null. It will only be set if needed.
virtual void OverridePageVisibilityState(
RenderFrameHost* render_frame_host,
- blink::WebPageVisibilityState* visibility_state) {}
+ blink::mojom::PageVisibilityState* visibility_state) {}
// Allows an embedder to provide its own ControllerPresentationServiceDelegate
// implementation. Returns nullptr if unavailable.
@@ -878,6 +927,25 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual std::vector<std::unique_ptr<URLLoaderThrottle>>
CreateURLLoaderThrottles(const base::Callback<WebContents*()>& wc_getter);
+ // Allows the embedder to register per-scheme URLLoaderFactory implementations
+ // to handle navigation URL requests for schemes not handled by the Network
+ // Service. Only called when the Network Service is enabled.
+ using NonNetworkURLLoaderFactoryMap =
+ std::map<std::string, std::unique_ptr<mojom::URLLoaderFactory>>;
+ virtual void RegisterNonNetworkNavigationURLLoaderFactories(
+ RenderFrameHost* frame_host,
+ NonNetworkURLLoaderFactoryMap* factories);
+
+ // Allows the embedder to register per-scheme URLLoaderFactory implementations
+ // to handle subresource URL requests for schemes not handled by the Network
+ // Service. The factories added to this map will only be used to service
+ // subresource requests from |frame_host| as long as it's navigated to
+ // |frame_url|. Only called when the Network Service is enabled.
+ virtual void RegisterNonNetworkSubresourceURLLoaderFactories(
+ RenderFrameHost* frame_host,
+ const GURL& frame_url,
+ NonNetworkURLLoaderFactoryMap* factories);
+
// Creates a NetworkContext for a BrowserContext's StoragePartition. If the
// network service is enabled, it must return a NetworkContext using the
// network service. If the network service is disabled, the embedder may
diff --git a/chromium/content/public/browser/desktop_media_id.h b/chromium/content/public/browser/desktop_media_id.h
index 7b6cd1f1011..7119cdc1bd9 100644
--- a/chromium/content/public/browser/desktop_media_id.h
+++ b/chromium/content/public/browser/desktop_media_id.h
@@ -29,6 +29,8 @@ struct CONTENT_EXPORT DesktopMediaID {
// Represents an "unset" value for either |id| or |aura_id|.
static const Id kNullId = 0;
+ // Represents a fake id to create a dummy capturer for autotests.
+ static const Id kFakeId = -3;
#if defined(USE_AURA)
// Assigns integer identifier to the |window| and returns its DesktopMediaID.
diff --git a/chromium/content/public/browser/devtools_agent_host.h b/chromium/content/public/browser/devtools_agent_host.h
index 1ce8972ac70..6fa1c93ee6f 100644
--- a/chromium/content/public/browser/devtools_agent_host.h
+++ b/chromium/content/public/browser/devtools_agent_host.h
@@ -63,11 +63,6 @@ class CONTENT_EXPORT DevToolsAgentHost
// does exist.
static bool HasFor(WebContents* web_contents);
- // Returns DevToolsAgentHost that can be used for inspecting shared worker
- // with given worker process host id and routing id.
- static scoped_refptr<DevToolsAgentHost> GetForWorker(int worker_process_id,
- int worker_route_id);
-
// Creates DevToolsAgentHost that communicates to the target by means of
// provided |delegate|. |delegate| ownership is passed to the created agent
// host.
@@ -111,6 +106,10 @@ class CONTENT_EXPORT DevToolsAgentHost
// Stops remote debugging.
static void StopRemoteDebuggingServer();
+ // Starts remote debugging for browser target for the given fd=3
+ // for reading and fd=4 for writing remote debugging messages.
+ static void StartRemoteDebuggingPipeHandler();
+
// Observer is notified about changes in DevToolsAgentHosts.
static void AddObserver(DevToolsAgentHostObserver*);
static void RemoveObserver(DevToolsAgentHostObserver*);
diff --git a/chromium/content/public/browser/devtools_agent_host_client.h b/chromium/content/public/browser/devtools_agent_host_client.h
index be5d33757d2..c8f08114876 100644
--- a/chromium/content/public/browser/devtools_agent_host_client.h
+++ b/chromium/content/public/browser/devtools_agent_host_client.h
@@ -24,8 +24,7 @@ class CONTENT_EXPORT DevToolsAgentHostClient {
const std::string& message) = 0;
// This method is called when attached agent host is closed.
- virtual void AgentHostClosed(DevToolsAgentHost* agent_host,
- bool replaced_with_another_client) = 0;
+ virtual void AgentHostClosed(DevToolsAgentHost* agent_host) = 0;
};
} // namespace content
diff --git a/chromium/content/public/browser/download_item.h b/chromium/content/public/browser/download_item.h
index 15540f4de30..42b8575cdaa 100644
--- a/chromium/content/public/browser/download_item.h
+++ b/chromium/content/public/browser/download_item.h
@@ -84,6 +84,13 @@ class CONTENT_EXPORT DownloadItem : public base::SupportsUserData {
// TARGET_DISPOSITION_OVERWRITE.
};
+ // How download item is created. Used for trace event.
+ enum DownloadType {
+ TYPE_ACTIVE_DOWNLOAD,
+ TYPE_HISTORY_IMPORT,
+ TYPE_SAVE_PAGE_AS
+ };
+
// Callback used with AcquireFileAndDeleteDownload().
typedef base::Callback<void(const base::FilePath&)> AcquireFileCallback;
@@ -103,7 +110,6 @@ class CONTENT_EXPORT DownloadItem : public base::SupportsUserData {
// down.
virtual void OnDownloadDestroyed(DownloadItem* download) {}
- protected:
virtual ~Observer() {}
};
diff --git a/chromium/content/public/browser/download_manager_delegate.cc b/chromium/content/public/browser/download_manager_delegate.cc
index 9351ce22711..c21286c57b0 100644
--- a/chromium/content/public/browser/download_manager_delegate.cc
+++ b/chromium/content/public/browser/download_manager_delegate.cc
@@ -4,6 +4,7 @@
#include "content/public/browser/download_manager_delegate.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "content/public/browser/download_item.h"
namespace content {
@@ -34,15 +35,33 @@ bool DownloadManagerDelegate::ShouldOpenDownload(
return true;
}
+bool DownloadManagerDelegate::IsMostRecentDownloadItemAtFilePath(
+ DownloadItem* download) {
+ return true;
+}
+
bool DownloadManagerDelegate::GenerateFileHash() {
return false;
}
+download::InProgressCache* DownloadManagerDelegate::GetInProgressCache() {
+ return nullptr;
+}
+
std::string
DownloadManagerDelegate::ApplicationClientIdForFileScanning() const {
return std::string();
}
+void DownloadManagerDelegate::CheckDownloadAllowed(
+ const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
+ const GURL& url,
+ const std::string& request_method,
+ CheckDownloadAllowedCallback check_download_allowed_cb) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(std::move(check_download_allowed_cb), true));
+}
+
DownloadManagerDelegate::~DownloadManagerDelegate() {}
} // namespace content
diff --git a/chromium/content/public/browser/download_manager_delegate.h b/chromium/content/public/browser/download_manager_delegate.h
index dc33ded9221..71945605e30 100644
--- a/chromium/content/public/browser/download_manager_delegate.h
+++ b/chromium/content/public/browser/download_manager_delegate.h
@@ -14,8 +14,13 @@
#include "content/common/content_export.h"
#include "content/public/browser/download_danger_type.h"
#include "content/public/browser/download_item.h"
+#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/save_page_type.h"
+namespace download {
+class InProgressCache;
+} // namespace download
+
namespace content {
class BrowserContext;
@@ -68,6 +73,9 @@ using CheckForFileExistenceCallback = base::OnceCallback<void(bool result)>;
using DownloadIdCallback = base::Callback<void(uint32_t)>;
+// Called on whether a download is allowed to continue.
+using CheckDownloadAllowedCallback = base::OnceCallback<void(bool /*allow*/)>;
+
// Browser's download manager: manages all downloads and destination view.
class CONTENT_EXPORT DownloadManagerDelegate {
public:
@@ -123,6 +131,9 @@ class CONTENT_EXPORT DownloadManagerDelegate {
base::FilePath* download_save_dir,
bool* skip_dir_check) {}
+ // Returns the metadata cache for in-progress downloads.
+ virtual download::InProgressCache* GetInProgressCache();
+
// Asks the user for the path to save a page. The delegate calls the callback
// to give the answer.
virtual void ChooseSavePath(
@@ -148,6 +159,10 @@ class CONTENT_EXPORT DownloadManagerDelegate {
// Opens the file associated with this download.
virtual void OpenDownload(DownloadItem* download) {}
+ // Returns whether this is the most recent download in the rare event where
+ // multiple downloads are associated with the same file path.
+ virtual bool IsMostRecentDownloadItemAtFilePath(DownloadItem* download);
+
// Shows the download via the OS shell.
virtual void ShowDownloadInShell(DownloadItem* download) {}
@@ -163,6 +178,14 @@ class CONTENT_EXPORT DownloadManagerDelegate {
// This GUID is only used on Windows.
virtual std::string ApplicationClientIdForFileScanning() const;
+ // Checks whether download is allowed to continue. |check_download_allowed_cb|
+ // is called with the decision on completion.
+ virtual void CheckDownloadAllowed(
+ const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
+ const GURL& url,
+ const std::string& request_method,
+ CheckDownloadAllowedCallback check_download_allowed_cb);
+
protected:
virtual ~DownloadManagerDelegate();
};
diff --git a/chromium/content/public/browser/download_request_utils.h b/chromium/content/public/browser/download_request_utils.h
new file mode 100644
index 00000000000..a55c7040bc9
--- /dev/null
+++ b/chromium/content/public/browser/download_request_utils.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_DOWNLOAD_REQUEST_UTILS_H_
+#define CONTENT_PUBLIC_BROWSER_DOWNLOAD_REQUEST_UTILS_H_
+
+#include <string>
+
+#include "content/common/content_export.h"
+
+namespace net {
+class URLRequest;
+} // namespace net
+
+namespace content {
+
+// Utility methods for download requests.
+class CONTENT_EXPORT DownloadRequestUtils {
+ public:
+ // Returns the identifier for origin of the download.
+ static std::string GetRequestOriginFromRequest(
+ const net::URLRequest* request);
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_DOWNLOAD_REQUEST_UTILS_H_
diff --git a/chromium/content/public/browser/download_source.h b/chromium/content/public/browser/download_source.h
new file mode 100644
index 00000000000..040fd016975
--- /dev/null
+++ b/chromium/content/public/browser/download_source.h
@@ -0,0 +1,59 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_DOWNLOAD_SOURCE_H_
+#define CONTENT_PUBLIC_BROWSER_DOWNLOAD_SOURCE_H_
+
+namespace content {
+
+// The source of download.
+// Used in UMA metrics and persisted to disk.
+// Entries in this enum can only be appended instead of being deleted or reused.
+// Any changes here also needs to apply to enums.xml.
+enum class DownloadSource {
+ // The source is unknown.
+ UNKNOWN = 0,
+
+ // Download is triggered from navigation request.
+ NAVIGATION = 1,
+
+ // Drag and drop.
+ DRAG_AND_DROP = 2,
+
+ // User manually resume the download.
+ MANUAL_RESUMPTION = 3,
+
+ // Auto resumption in download system.
+ AUTO_RESUMPTION = 4,
+
+ // Renderer initiated download, mostly from Javascript or HTML <a> tag.
+ FROM_RENDERER = 5,
+
+ // Extension download API.
+ EXTENSION_API = 6,
+
+ // Extension web store installer.
+ EXTENSION_INSTALLER = 7,
+
+ // Plugin triggered download.
+ PLUGIN = 8,
+
+ // Plugin installer download.
+ PLUGIN_INSTALLER = 9,
+
+ // Download service API background download.
+ INTERNAL_API = 10,
+
+ // Save package download.
+ SAVE_PACKAGE = 11,
+
+ // Offline page download.
+ OFFLINE_PAGE = 12,
+
+ COUNT = 13
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_DOWNLOAD_SOURCE_H_
diff --git a/chromium/content/public/browser/download_url_parameters.cc b/chromium/content/public/browser/download_url_parameters.cc
index 39665acc6a0..31513760ae1 100644
--- a/chromium/content/public/browser/download_url_parameters.cc
+++ b/chromium/content/public/browser/download_url_parameters.cc
@@ -47,7 +47,8 @@ DownloadUrlParameters::DownloadUrlParameters(
do_not_prompt_for_login_(false),
fetch_error_body_(false),
transient_(false),
- traffic_annotation_(traffic_annotation) {}
+ traffic_annotation_(traffic_annotation),
+ download_source_(DownloadSource::UNKNOWN) {}
DownloadUrlParameters::~DownloadUrlParameters() {
}
diff --git a/chromium/content/public/browser/download_url_parameters.h b/chromium/content/public/browser/download_url_parameters.h
index 5495904f370..f15848524a6 100644
--- a/chromium/content/public/browser/download_url_parameters.h
+++ b/chromium/content/public/browser/download_url_parameters.h
@@ -18,6 +18,7 @@
#include "base/optional.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/download_save_info.h"
+#include "content/public/browser/download_source.h"
#include "content/public/common/referrer.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request_context_getter.h"
@@ -238,6 +239,17 @@ class CONTENT_EXPORT DownloadUrlParameters {
blob_data_handle_ = std::move(blob_data_handle);
}
+ // For downloads originating from custom tabs, this records the origin
+ // of the custom tab.
+ void set_request_origin(const std::string& origin) {
+ request_origin_ = origin;
+ }
+
+ // Sets the download source, which will be used in metrics recording.
+ void set_download_source(DownloadSource download_source) {
+ download_source_ = download_source;
+ }
+
const OnStartedCallback& callback() const { return callback_; }
bool content_initiated() const { return content_initiated_; }
const std::string& last_modified() const { return last_modified_; }
@@ -250,6 +262,7 @@ class CONTENT_EXPORT DownloadUrlParameters {
const Referrer& referrer() const { return referrer_; }
const std::string& referrer_encoding() const { return referrer_encoding_; }
const base::Optional<url::Origin>& initiator() const { return initiator_; }
+ const std::string& request_origin() const { return request_origin_; }
// These will be -1 if the request is not associated with a frame. See
// the constructors for more.
@@ -294,6 +307,8 @@ class CONTENT_EXPORT DownloadUrlParameters {
return traffic_annotation_;
}
+ DownloadSource download_source() const { return download_source_; }
+
private:
OnStartedCallback callback_;
bool content_initiated_;
@@ -320,6 +335,8 @@ class CONTENT_EXPORT DownloadUrlParameters {
std::string guid_;
std::unique_ptr<storage::BlobDataHandle> blob_data_handle_;
const net::NetworkTrafficAnnotationTag traffic_annotation_;
+ std::string request_origin_;
+ DownloadSource download_source_;
DISALLOW_COPY_AND_ASSIGN(DownloadUrlParameters);
};
diff --git a/chromium/content/public/browser/file_url_loader.h b/chromium/content/public/browser/file_url_loader.h
new file mode 100644
index 00000000000..e467256acb8
--- /dev/null
+++ b/chromium/content/public/browser/file_url_loader.h
@@ -0,0 +1,32 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_FILE_URL_LOADER_H_
+#define CONTENT_PUBLIC_BROWSER_FILE_URL_LOADER_H_
+
+#include "content/common/content_export.h"
+#include "content/public/common/url_loader.mojom.h"
+
+namespace content {
+
+struct ResourceRequest;
+
+// Helper to create a self-owned URLLoader instance which fulfills |request|
+// using the contents of the file at |path|. The URL in |request| must be a
+// file:// URL.
+//
+// Note that this does not restrict filesystem access *in any way*, so if the
+// file at |path| is accessible to the browser, it will be loaded and used to
+// the request.
+//
+// The URLLoader created by this function does *not* automatically follow
+// filesytem links (e.g. Windows shortcuts) or support directory listing.
+// A directory path will always yield a FILE_NOT_FOUND network error.
+CONTENT_EXPORT void CreateFileURLLoader(const ResourceRequest& request,
+ mojom::URLLoaderRequest loader,
+ mojom::URLLoaderClientPtr client);
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_FILE_URL_LOADER_H_
diff --git a/chromium/content/public/browser/gpu_data_manager.h b/chromium/content/public/browser/gpu_data_manager.h
index 06758fb71c3..d6db972a5dc 100644
--- a/chromium/content/public/browser/gpu_data_manager.h
+++ b/chromium/content/public/browser/gpu_data_manager.h
@@ -93,9 +93,6 @@ class GpuDataManager {
// Whether a GPU is in use (as opposed to a software renderer).
virtual bool HardwareAccelerationEnabled() const = 0;
- // Whether the browser compositor can be used.
- virtual bool CanUseGpuBrowserCompositor() const = 0;
-
// Extensions that are currently disabled.
virtual void GetDisabledExtensions(
std::string* disabled_extensions) const = 0;
diff --git a/chromium/content/public/browser/gpu_utils.cc b/chromium/content/public/browser/gpu_utils.cc
index 6aafb065d1e..06b7e88ee14 100644
--- a/chromium/content/public/browser/gpu_utils.cc
+++ b/chromium/content/public/browser/gpu_utils.cc
@@ -54,8 +54,6 @@ const gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
command_line->HasSwitch(switches::kSingleProcess);
gpu_preferences.in_process_gpu =
command_line->HasSwitch(switches::kInProcessGPU);
- gpu_preferences.ui_prioritize_in_gpu_process =
- command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess);
gpu_preferences.disable_accelerated_video_decode =
command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode);
#if defined(OS_CHROMEOS)
@@ -120,12 +118,21 @@ const gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
command_line->HasSwitch(switches::kGLShaderIntermOutput);
gpu_preferences.emulate_shader_precision =
command_line->HasSwitch(switches::kEmulateShaderPrecision);
+ gpu_preferences.enable_raster_decoder =
+ command_line->HasSwitch(switches::kEnableRasterDecoder);
gpu_preferences.enable_gpu_service_logging =
command_line->HasSwitch(switches::kEnableGPUServiceLogging);
gpu_preferences.enable_gpu_service_tracing =
command_line->HasSwitch(switches::kEnableGPUServiceTracing);
gpu_preferences.use_passthrough_cmd_decoder =
gpu::gles2::UsePassthroughCommandDecoder(command_line);
+ gpu_preferences.gpu_startup_dialog =
+ command_line->HasSwitch(switches::kGpuStartupDialog);
+ gpu_preferences.disable_gpu_watchdog =
+ command_line->HasSwitch(switches::kDisableGpuWatchdog) ||
+ (gpu_preferences.single_process || gpu_preferences.in_process_gpu);
+ gpu_preferences.gpu_sandbox_start_early =
+ command_line->HasSwitch(switches::kGpuSandboxStartEarly);
// Some of these preferences are set or adjusted in
// GpuDataManagerImplPrivate::AppendGpuCommandLine.
return gpu_preferences;
diff --git a/chromium/content/public/browser/guest_host.h b/chromium/content/public/browser/guest_host.h
index a1b429f535b..c955e4616c9 100644
--- a/chromium/content/public/browser/guest_host.h
+++ b/chromium/content/public/browser/guest_host.h
@@ -25,9 +25,6 @@ class GuestHost {
virtual int LoadURLWithParams(
const NavigationController::LoadURLParams& load_params) = 0;
- // Called when the GuestHost's size changes due to auto resize.
- virtual void GuestResizeDueToAutoResize(const gfx::Size& new_size) = 0;
-
// Sets the size of the guest WebContents.
virtual void SizeContents(const gfx::Size& new_size) = 0;
diff --git a/chromium/content/public/browser/host_zoom_map.h b/chromium/content/public/browser/host_zoom_map.h
index 14c960d1129..c64bbd37c6b 100644
--- a/chromium/content/public/browser/host_zoom_map.h
+++ b/chromium/content/public/browser/host_zoom_map.h
@@ -194,7 +194,7 @@ class HostZoomMap {
virtual std::unique_ptr<Subscription> AddZoomLevelChangedCallback(
const ZoomLevelChangedCallback& callback) = 0;
- virtual void SetClockForTesting(std::unique_ptr<base::Clock> clock) = 0;
+ virtual void SetClockForTesting(base::Clock* clock) = 0;
protected:
virtual ~HostZoomMap() {}
diff --git a/chromium/content/public/browser/javascript_dialog_manager.h b/chromium/content/public/browser/javascript_dialog_manager.h
index 74db785cec1..734dcf27da6 100644
--- a/chromium/content/public/browser/javascript_dialog_manager.h
+++ b/chromium/content/public/browser/javascript_dialog_manager.h
@@ -16,6 +16,7 @@
namespace content {
+class RenderFrameHost;
class WebContents;
// An interface consisting of methods that can be called to produce and manage
@@ -38,6 +39,7 @@ class CONTENT_EXPORT JavaScriptDialogManager {
// Displays a dialog asking the user if they want to leave a page.
virtual void RunBeforeUnloadDialog(WebContents* web_contents,
+ RenderFrameHost* render_frame_host,
bool is_reload,
DialogClosedCallback callback) = 0;
diff --git a/chromium/content/public/browser/media_session.h b/chromium/content/public/browser/media_session.h
index 914812cb49c..1a5ce982549 100644
--- a/chromium/content/public/browser/media_session.h
+++ b/chromium/content/public/browser/media_session.h
@@ -6,6 +6,7 @@
#define CONTENT_PUBLIC_BROWSER_MEDIA_SESSION_H_
#include "base/macros.h"
+#include "base/time/time.h"
#include "content/common/content_export.h"
namespace blink {
@@ -45,14 +46,20 @@ class MediaSession {
// |type| represents the origin of the request.
virtual void Resume(SuspendType suspend_type) = 0;
- // Resume the media session.
+ // Suspend the media session.
// |type| represents the origin of the request.
virtual void Suspend(SuspendType suspend_type) = 0;
- // Resume the media session.
+ // Stop the media session.
// |type| represents the origin of the request.
virtual void Stop(SuspendType suspend_type) = 0;
+ // Seek the media session forward.
+ virtual void SeekForward(base::TimeDelta seek_time) = 0;
+
+ // Seek the media session backward.
+ virtual void SeekBackward(base::TimeDelta seek_time) = 0;
+
// Return if the session can be controlled by Resume() and Suspend() calls
// above.
virtual bool IsControllable() const = 0;
diff --git a/chromium/content/public/browser/navigation_handle.h b/chromium/content/public/browser/navigation_handle.h
index 6bd4a62b39a..31fece58765 100644
--- a/chromium/content/public/browser/navigation_handle.h
+++ b/chromium/content/public/browser/navigation_handle.h
@@ -13,6 +13,7 @@
#include "content/public/browser/reload_type.h"
#include "content/public/browser/restore_type.h"
#include "content/public/common/referrer.h"
+#include "content/public/common/resource_request_body.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_info.h"
@@ -133,6 +134,12 @@ class CONTENT_EXPORT NavigationHandle {
// |bool IsPost()| as opposed to |const std::string& GetMethod()| method.
virtual bool IsPost() = 0;
+ // Returns the POST body associated with this navigation. This will be null
+ // for GET and/or other non-POST requests (or if a response to a POST request
+ // was a redirect that changed the method to GET - for example 302).
+ virtual const scoped_refptr<ResourceRequestBody>&
+ GetResourceRequestBody() = 0;
+
// Returns a sanitized version of the referrer for this request.
virtual const Referrer& GetReferrer() = 0;
@@ -231,6 +238,14 @@ class CONTENT_EXPORT NavigationHandle {
// encountering a server redirect).
virtual net::HttpResponseInfo::ConnectionInfo GetConnectionInfo() = 0;
+ // Returns the SSLInfo for a request that succeeded or failed due to a
+ // certificate error. In the case of other request failures or of a non-secure
+ // scheme, returns an empty object.
+ virtual const net::SSLInfo& GetSSLInfo() = 0;
+
+ // Whether the failure for a certificate error should be fatal.
+ virtual bool ShouldSSLErrorsBeFatal() = 0;
+
// Returns the ID of the URLRequest associated with this navigation. Can only
// be called from NavigationThrottle::WillProcessResponse and
// WebContentsObserver::ReadyToCommitNavigation.
@@ -281,6 +296,11 @@ class CONTENT_EXPORT NavigationHandle {
const GURL& new_referrer_url,
bool new_is_external_protocol) = 0;
+ // Simulates the network request failing.
+ virtual NavigationThrottle::ThrottleCheckResult CallWillFailRequestForTesting(
+ base::Optional<net::SSLInfo> ssl_info,
+ bool should_ssl_errors_be_fatal) = 0;
+
// Simulates the reception of the network response.
virtual NavigationThrottle::ThrottleCheckResult
CallWillProcessResponseForTesting(
diff --git a/chromium/content/public/browser/navigation_throttle.cc b/chromium/content/public/browser/navigation_throttle.cc
index 5b4e358bfa2..1bef677151d 100644
--- a/chromium/content/public/browser/navigation_throttle.cc
+++ b/chromium/content/public/browser/navigation_throttle.cc
@@ -71,6 +71,10 @@ NavigationThrottle::WillRedirectRequest() {
return NavigationThrottle::PROCEED;
}
+NavigationThrottle::ThrottleCheckResult NavigationThrottle::WillFailRequest() {
+ return NavigationThrottle::PROCEED;
+}
+
NavigationThrottle::ThrottleCheckResult
NavigationThrottle::WillProcessResponse() {
return NavigationThrottle::PROCEED;
diff --git a/chromium/content/public/browser/navigation_throttle.h b/chromium/content/public/browser/navigation_throttle.h
index 92a9cd0dc15..8186e0b805b 100644
--- a/chromium/content/public/browser/navigation_throttle.h
+++ b/chromium/content/public/browser/navigation_throttle.h
@@ -19,7 +19,9 @@ class CONTENT_EXPORT NavigationThrottle {
// Represents what a NavigationThrottle can decide to do to a navigation. Note
// that this enum is implicitly convertable to ThrottleCheckResult.
enum ThrottleAction {
- // The navigation proceeds uninterrupted.
+ // The action proceeds. This can either mean the navigation continues (e.g.
+ // for WillStartRequest) or that the navigation fails (e.g. for
+ // WillFailRequest).
PROCEED,
// Defers the navigation until the NavigationThrottle calls
@@ -108,7 +110,7 @@ class CONTENT_EXPORT NavigationThrottle {
ThrottleAction action() const { return action_; }
net::Error net_error_code() const { return net_error_code_; }
- base::Optional<std::string> error_page_content() {
+ const base::Optional<std::string>& error_page_content() {
return error_page_content_;
}
@@ -139,6 +141,15 @@ class CONTENT_EXPORT NavigationThrottle {
// CANCEL_AND_IGNORE or DEFER and perform the destruction asynchronously.
virtual ThrottleCheckResult WillRedirectRequest();
+ // Called when a request will fail.
+ //
+ // The implementer is responsible for ensuring that the WebContents this
+ // throttle is associated with remain alive during the duration of this
+ // method. Failing to do so will result in use-after-free bugs. Should the
+ // implementer need to destroy the WebContents, it should return CANCEL,
+ // CANCEL_AND_IGNORE or DEFER and perform the destruction asynchronously.
+ virtual ThrottleCheckResult WillFailRequest();
+
// Called when a response's headers and metadata are available.
//
// The implementer is responsible for ensuring that the WebContents this
diff --git a/chromium/content/public/browser/network_service_instance.cc b/chromium/content/public/browser/network_service_instance.cc
index 5cf29702c7e..0f62388854f 100644
--- a/chromium/content/public/browser/network_service_instance.cc
+++ b/chromium/content/public/browser/network_service_instance.cc
@@ -5,6 +5,7 @@
#include "content/public/browser/network_service_instance.h"
#include "base/feature_list.h"
+#include "content/browser/network_service_client.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
#include "content/public/common/network_service.mojom.h"
@@ -20,9 +21,16 @@ mojom::NetworkService* GetNetworkService() {
static mojom::NetworkServicePtr* g_network_service =
new mojom::NetworkServicePtr;
- if (!g_network_service->is_bound()) {
+ static NetworkServiceClient* g_client;
+ if (!g_network_service->is_bound() ||
+ g_network_service->encountered_error()) {
ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
mojom::kNetworkServiceName, g_network_service);
+
+ mojom::NetworkServiceClientPtr client_ptr;
+ delete g_client; // In case we're recreating the network service.
+ g_client = new NetworkServiceClient(mojo::MakeRequest(&client_ptr));
+ g_network_service->get()->SetClient(std::move(client_ptr));
}
return g_network_service->get();
}
diff --git a/chromium/content/public/browser/notification_event_dispatcher.h b/chromium/content/public/browser/notification_event_dispatcher.h
index 7ea8e1fdc96..66b91718bfb 100644
--- a/chromium/content/public/browser/notification_event_dispatcher.h
+++ b/chromium/content/public/browser/notification_event_dispatcher.h
@@ -19,16 +19,15 @@ namespace content {
class BrowserContext;
-// This is the dispatcher to be used for firing events related to persistent
-// notifications on a Service Worker. This class is a singleton, the instance of
-// which can be retrieved using the static GetInstance() method. All methods
-// must be called on the UI thread.
+// This is the dispatcher to be used for firing events related to notifications.
+// This class is a singleton, the instance of which can be retrieved using the
+// static GetInstance() method. All methods must be called on the UI thread.
class CONTENT_EXPORT NotificationEventDispatcher {
public:
static NotificationEventDispatcher* GetInstance();
using NotificationDispatchCompleteCallback =
- base::Callback<void(PersistentNotificationStatus)>;
+ base::OnceCallback<void(PersistentNotificationStatus)>;
// Dispatch methods for persistent (SW backed) notifications.
// TODO(miguelg) consider merging them with the non persistent ones below.
@@ -42,8 +41,7 @@ class CONTENT_EXPORT NotificationEventDispatcher {
const GURL& origin,
const base::Optional<int>& action_index,
const base::Optional<base::string16>& reply,
- const NotificationDispatchCompleteCallback&
- dispatch_complete_callback) = 0;
+ NotificationDispatchCompleteCallback dispatch_complete_callback) = 0;
// Dispatches the "notificationclose" event on the Service Worker associated
// with |notification_id| belonging to |origin|. The
@@ -54,8 +52,7 @@ class CONTENT_EXPORT NotificationEventDispatcher {
const std::string& notification_id,
const GURL& origin,
bool by_user,
- const NotificationDispatchCompleteCallback&
- dispatch_complete_callback) = 0;
+ NotificationDispatchCompleteCallback dispatch_complete_callback) = 0;
// Dispatch methods for the different non persistent (not backed by a service
// worker) notification events.
diff --git a/chromium/content/public/browser/overscroll_configuration.h b/chromium/content/public/browser/overscroll_configuration.h
index 369ae7d869b..d3db2a2c047 100644
--- a/chromium/content/public/browser/overscroll_configuration.h
+++ b/chromium/content/public/browser/overscroll_configuration.h
@@ -10,27 +10,20 @@
namespace content {
// Sets and retrieves various overscroll related configuration values.
-enum OverscrollConfig {
- OVERSCROLL_CONFIG_NONE,
+enum class OverscrollConfig {
+ // Threshold to complete touchpad overscroll, in terms of the percentage of
+ // the display size.
+ THRESHOLD_COMPLETE_TOUCHPAD,
- // Threshold to complete horizontal overscroll. For touchpad, it represents
- // the percentage of the display width. For touchscreen, it represents the
- // percentage of the window width.
- OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE,
+ // Threshold to complete touchscreen overscroll, in terms of the percentage of
+ // the display size.
+ THRESHOLD_COMPLETE_TOUCHSCREEN,
- // Threshold to complete vertical overscroll. For touchpad, it represents the
- // percentage of the display width. For touchscreen, it represents the
- // percentage of the window width.
- OVERSCROLL_CONFIG_VERT_THRESHOLD_COMPLETE,
+ // Threshold to start touchpad overscroll, in DIPs.
+ THRESHOLD_START_TOUCHPAD,
- // Threshold to start horizontal touchpad overscroll, in DIPs.
- OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHPAD,
-
- // Threshold to start horizontal touchscreen overscroll, in DIPs.
- OVERSCROLL_CONFIG_HORIZ_THRESHOLD_START_TOUCHSCREEN,
-
- // Threshold to start vertical overscroll, in DIPs.
- OVERSCROLL_CONFIG_VERT_THRESHOLD_START,
+ // Threshold to start touchscreen overscroll, in DIPs.
+ THRESHOLD_START_TOUCHSCREEN,
};
CONTENT_EXPORT float GetOverscrollConfig(OverscrollConfig config);
diff --git a/chromium/content/public/browser/page_navigator.cc b/chromium/content/public/browser/page_navigator.cc
index de8d88e0703..cb7da036ad1 100644
--- a/chromium/content/public/browser/page_navigator.cc
+++ b/chromium/content/public/browser/page_navigator.cc
@@ -16,7 +16,6 @@ OpenURLParams::OpenURLParams(const GURL& url,
uses_post(false),
frame_tree_node_id(-1),
disposition(disposition),
- force_new_process_for_new_contents(false),
transition(transition),
is_renderer_initiated(is_renderer_initiated),
should_replace_current_entry(false),
@@ -34,7 +33,6 @@ OpenURLParams::OpenURLParams(const GURL& url,
uses_post(false),
frame_tree_node_id(-1),
disposition(disposition),
- force_new_process_for_new_contents(false),
transition(transition),
is_renderer_initiated(is_renderer_initiated),
should_replace_current_entry(false),
@@ -52,7 +50,6 @@ OpenURLParams::OpenURLParams(const GURL& url,
uses_post(false),
frame_tree_node_id(frame_tree_node_id),
disposition(disposition),
- force_new_process_for_new_contents(false),
transition(transition),
is_renderer_initiated(is_renderer_initiated),
should_replace_current_entry(false),
@@ -63,7 +60,6 @@ OpenURLParams::OpenURLParams()
: uses_post(false),
frame_tree_node_id(-1),
disposition(WindowOpenDisposition::UNKNOWN),
- force_new_process_for_new_contents(false),
transition(ui::PAGE_TRANSITION_LINK),
is_renderer_initiated(false),
should_replace_current_entry(false),
diff --git a/chromium/content/public/browser/page_navigator.h b/chromium/content/public/browser/page_navigator.h
index 0f8f474aaf5..e9a874e4305 100644
--- a/chromium/content/public/browser/page_navigator.h
+++ b/chromium/content/public/browser/page_navigator.h
@@ -10,6 +10,7 @@
#define CONTENT_PUBLIC_BROWSER_PAGE_NAVIGATOR_H_
#include <string>
+#include <vector>
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
@@ -83,12 +84,6 @@ struct CONTENT_EXPORT OpenURLParams {
// The disposition requested by the navigation source.
WindowOpenDisposition disposition;
- // Controls creation of new web contents (in case |disposition| asks for a new
- // tab or window). If |force_new_process_for_new_contents| is true, then we
- // try to put the new contents in a new renderer, even if they are same-site
- // as |source_site_instance| (this is subject to renderer process limits).
- bool force_new_process_for_new_contents;
-
// The transition type of navigation.
ui::PageTransition transition;
diff --git a/chromium/content/public/browser/permission_type.h b/chromium/content/public/browser/permission_type.h
index 876eec5278c..9c5e09b4d0c 100644
--- a/chromium/content/public/browser/permission_type.h
+++ b/chromium/content/public/browser/permission_type.h
@@ -14,7 +14,7 @@ namespace content {
// immediately before PermissionType::NUM
enum class PermissionType {
MIDI_SYSEX = 1,
- PUSH_MESSAGING = 2,
+ // PUSH_MESSAGING = 2,
NOTIFICATIONS = 3,
GEOLOCATION = 4,
PROTECTED_MEDIA_IDENTIFIER = 5,
@@ -26,6 +26,8 @@ enum class PermissionType {
FLASH = 11,
SENSORS = 12,
ACCESSIBILITY_EVENTS = 13,
+ CLIPBOARD_READ = 14,
+ CLIPBOARD_WRITE = 15,
// Always keep this at the end.
NUM,
diff --git a/chromium/content/public/browser/platform_notification_service.h b/chromium/content/public/browser/platform_notification_service.h
index a8dcc86d4fd..71b8f2d61d4 100644
--- a/chromium/content/public/browser/platform_notification_service.h
+++ b/chromium/content/public/browser/platform_notification_service.h
@@ -53,16 +53,14 @@ class CONTENT_EXPORT PlatformNotificationService {
const GURL& origin,
int render_process_id) = 0;
- // Displays the notification described in |notification_data| to the user. A
- // closure through which the notification can be closed will be stored in the
- // |cancel_callback| argument. This method must be called on the UI thread.
+ // Displays the notification described in |notification_data| to the user.
+ // This method must be called on the UI thread.
virtual void DisplayNotification(
BrowserContext* browser_context,
const std::string& notification_id,
const GURL& origin,
const PlatformNotificationData& notification_data,
- const NotificationResources& notification_resources,
- base::Closure* cancel_callback) = 0;
+ const NotificationResources& notification_resources) = 0;
// Displays the persistent notification described in |notification_data| to
// the user. This method must be called on the UI thread.
@@ -74,8 +72,13 @@ class CONTENT_EXPORT PlatformNotificationService {
const PlatformNotificationData& notification_data,
const NotificationResources& notification_resources) = 0;
- // Closes the persistent notification identified by
- // |persistent_notification_id|. This method must be called on the UI thread.
+ // Closes the notification identified by |notification_id|. This method must
+ // be called on the UI thread.
+ virtual void CloseNotification(BrowserContext* browser_context,
+ const std::string& notification_id) = 0;
+
+ // Closes the persistent notification identified by |notification_id|. This
+ // method must be called on the UI thread.
virtual void ClosePersistentNotification(
BrowserContext* browser_context,
const std::string& notification_id) = 0;
diff --git a/chromium/content/public/browser/presentation_service_delegate.h b/chromium/content/public/browser/presentation_service_delegate.h
index 83f2f8313bb..7072c26fa55 100644
--- a/chromium/content/public/browser/presentation_service_delegate.h
+++ b/chromium/content/public/browser/presentation_service_delegate.h
@@ -181,10 +181,10 @@ class CONTENT_EXPORT ControllerPresentationServiceDelegate
const PresentationConnectionStateChangedCallback& state_changed_cb) = 0;
// Connect |controller_connection| owned by the controlling frame to the
- // offscreen presentation represented by |presentation_info|.
+ // local presentation represented by |presentation_info|.
// |render_process_id|, |render_frame_id|: ID of originating frame.
// |controller_connection|: Pointer to controller's presentation connection,
- // ownership passed from controlling frame to the offscreen presentation.
+ // ownership passed from controlling frame to the local presentation.
// |receiver_connection_request|: Mojo InterfaceRequest to be bind to receiver
// page's presentation connection.
virtual void ConnectToPresentation(
@@ -203,7 +203,7 @@ class CONTENT_EXPORT ReceiverPresentationServiceDelegate
// Registers a callback from the embedder when an offscreeen presentation has
// been successfully started.
// |receiver_available_callback|: Invoked when successfully starting a
- // offscreen presentation.
+ // local presentation.
virtual void RegisterReceiverConnectionAvailableCallback(
const content::ReceiverConnectionAvailableCallback&
receiver_available_callback) = 0;
diff --git a/chromium/content/public/browser/provision_fetcher_impl.cc b/chromium/content/public/browser/provision_fetcher_impl.cc
index edb2e5c0500..2cbef6dafb6 100644
--- a/chromium/content/public/browser/provision_fetcher_impl.cc
+++ b/chromium/content/public/browser/provision_fetcher_impl.cc
@@ -16,7 +16,7 @@ void ProvisionFetcherImpl::Create(
net::URLRequestContextGetter* context_getter,
media::mojom::ProvisionFetcherRequest request) {
DCHECK(context_getter);
- mojo::MakeStrongBinding(base::MakeUnique<ProvisionFetcherImpl>(
+ mojo::MakeStrongBinding(std::make_unique<ProvisionFetcherImpl>(
CreateProvisionFetcher(context_getter)),
std::move(request));
}
diff --git a/chromium/content/public/browser/render_frame_host.h b/chromium/content/public/browser/render_frame_host.h
index 644b1dd388a..bb3ae9b67cc 100644
--- a/chromium/content/public/browser/render_frame_host.h
+++ b/chromium/content/public/browser/render_frame_host.h
@@ -6,6 +6,7 @@
#define CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_
#include <string>
+#include <vector>
#include "base/callback_forward.h"
#include "build/build_config.h"
@@ -14,7 +15,7 @@
#include "content/public/common/file_chooser_params.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/WebSuddenTerminationDisablerType.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
@@ -22,7 +23,8 @@
#include "url/origin.h"
namespace blink {
-enum class WebFeaturePolicyFeature;
+class AssociatedInterfaceProvider;
+enum class FeaturePolicyFeature;
}
namespace base {
@@ -31,7 +33,7 @@ class Value;
}
namespace resource_coordinator {
-class ResourceCoordinatorInterface;
+class FrameResourceCoordinator;
}
namespace service_manager {
@@ -44,7 +46,6 @@ struct AXActionData;
namespace content {
-class AssociatedInterfaceProvider;
class RenderProcessHost;
class RenderViewHost;
class RenderWidgetHostView;
@@ -97,7 +98,7 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
// Returns the interface for the Global Resource Coordinator
// for this frame.
- virtual resource_coordinator::ResourceCoordinatorInterface*
+ virtual resource_coordinator::FrameResourceCoordinator*
GetFrameResourceCoordinator() = 0;
// Returns the process for this frame.
@@ -216,11 +217,12 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
// Returns the AssociatedInterfaceProvider that this process can use to access
// remote frame-specific Channel-associated interfaces for this frame.
- virtual AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() = 0;
+ virtual blink::AssociatedInterfaceProvider*
+ GetRemoteAssociatedInterfaces() = 0;
// Returns the visibility state of the frame. The different visibility states
// of a frame are defined in Blink.
- virtual blink::WebPageVisibilityState GetVisibilityState() = 0;
+ virtual blink::mojom::PageVisibilityState GetVisibilityState() = 0;
// Returns whether the RenderFrame in the renderer process has been created
// and still has a connection. This is valid for all frames.
@@ -297,7 +299,11 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
// Returns true if the given Feature Policy |feature| is enabled for this
// RenderFrameHost and is allowed to be used by it. Use this in the browser
// process to determine whether access to a feature is allowed.
- virtual bool IsFeatureEnabled(blink::WebFeaturePolicyFeature feature) = 0;
+ virtual bool IsFeatureEnabled(blink::FeaturePolicyFeature feature) = 0;
+
+ // Opens view-source tab for the document last committed in this
+ // RenderFrameHost.
+ virtual void ViewSource() = 0;
private:
// This interface should only be implemented inside content.
diff --git a/chromium/content/public/browser/render_process_host.h b/chromium/content/public/browser/render_process_host.h
index 0e21cf0c0c9..a2994ce4bed 100644
--- a/chromium/content/public/browser/render_process_host.h
+++ b/chromium/content/public/browser/render_process_host.h
@@ -35,7 +35,7 @@ class Identity;
}
namespace resource_coordinator {
-class ResourceCoordinatorInterface;
+class ProcessResourceCoordinator;
}
namespace viz {
@@ -273,26 +273,25 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
virtual bool StopWebRTCEventLog() = 0;
// Enables or disables WebRTC's echo canceller AEC3. Disabled implies
- // selecting the older AEC2.
- // Note: This will be removed once the AEC3 is fully rolled out and the old
- // AEC is deprecated.
- virtual void SetEchoCanceller3(bool enable) = 0;
-
- // When set, |callback| receives log messages regarding, for example, media
- // devices (webcams, mics, etc) that were initially requested in the render
- // process associated with this RenderProcessHost.
- virtual void SetWebRtcLogMessageCallback(
- base::Callback<void(const std::string&)> callback) = 0;
- virtual void ClearWebRtcLogMessageCallback() = 0;
-
- typedef base::Callback<void(std::unique_ptr<uint8_t[]> packet_header,
- size_t header_length,
- size_t packet_length,
- bool incoming)>
- WebRtcRtpPacketCallback;
-
- typedef base::Callback<void(bool incoming, bool outgoing)>
- WebRtcStopRtpDumpCallback;
+ // selecting the older AEC2. The operation is asynchronous, |callback| is run
+ // when done with the boolean indicating if successful and an error message.
+ // The error message is empty if successful.
+ // TODO(crbug.com/696930): Remove once the AEC3 is fully rolled out and the
+ // old AEC is deprecated.
+ virtual void SetEchoCanceller3(
+ bool enable,
+ base::OnceCallback<void(bool /* success */,
+ const std::string& /* error_message */)>
+ callback) = 0;
+
+ using WebRtcRtpPacketCallback =
+ base::Callback<void(std::unique_ptr<uint8_t[]> packet_header,
+ size_t header_length,
+ size_t packet_length,
+ bool incoming)>;
+
+ using WebRtcStopRtpDumpCallback =
+ base::Callback<void(bool incoming, bool outgoing)>;
// Starts passing RTP packets to |packet_callback| and returns the callback
// used to stop dumping.
@@ -380,7 +379,7 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
virtual mojom::Renderer* GetRendererInterface() = 0;
// Acquires the interface to the Global Resource Coordinator for this process.
- virtual resource_coordinator::ResourceCoordinatorInterface*
+ virtual resource_coordinator::ProcessResourceCoordinator*
GetProcessResourceCoordinator() = 0;
// Whether this process is locked out from ever being reused for sites other
@@ -466,6 +465,12 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
// not correspond to a live RenderProcessHost.
static RenderProcessHost* FromID(int render_process_id);
+ // Returns the RenderProcessHost given its renderer's service Identity.
+ // Returns nullptr if the Identity does not correspond to a live
+ // RenderProcessHost.
+ static RenderProcessHost* FromRendererIdentity(
+ const service_manager::Identity& identity);
+
// Returns whether the process-per-site model is in use (globally or just for
// the current site), in which case we should ensure there is only one
// RenderProcessHost per site for the entire browser context.
@@ -498,6 +503,6 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
static size_t GetMaxRendererProcessCount();
};
-} // namespace content.
+} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_RENDER_PROCESS_HOST_H_
diff --git a/chromium/content/public/browser/render_process_host_observer.h b/chromium/content/public/browser/render_process_host_observer.h
index 100bee675b3..660a4b59cda 100644
--- a/chromium/content/public/browser/render_process_host_observer.h
+++ b/chromium/content/public/browser/render_process_host_observer.h
@@ -22,6 +22,10 @@ class CONTENT_EXPORT RenderProcessHostObserver {
// RenderProcessHost and get RenderProcessExited notifications.
virtual void RenderProcessReady(RenderProcessHost* host) {}
+ // This method is invoked when the process when the process could shut down
+ // but may or may not be allowed.
+ virtual void RenderProcessShutdownRequested(RenderProcessHost* host) {}
+
// This method is invoked when the process is going to exit and should not be
// used for further navigations. Note that this is a COURTESY callback, not
// guaranteed to be called for any particular process. Because this is the
diff --git a/chromium/content/public/browser/render_widget_host.h b/chromium/content/public/browser/render_widget_host.h
index 9335c3484b6..e7358505998 100644
--- a/chromium/content/public/browser/render_widget_host.h
+++ b/chromium/content/public/browser/render_widget_host.h
@@ -11,13 +11,14 @@
#include "content/common/content_export.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/common/drop_data.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_sender.h"
#include "third_party/WebKit/public/platform/WebDragOperation.h"
#include "third_party/WebKit/public/platform/WebGestureEvent.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebTextDirection.h"
-#include "ui/gfx/geometry/size.h"
#include "ui/surface/transport_dib.h"
namespace blink {
@@ -25,6 +26,10 @@ class WebMouseEvent;
class WebMouseWheelEvent;
}
+namespace gfx {
+class Point;
+}
+
namespace ui {
class LatencyInfo;
}
@@ -197,6 +202,9 @@ class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender {
// warning too soon.
virtual void RestartHangMonitorTimeoutIfNecessary() = 0;
+ // Returns true if the renderer is considered unresponsive.
+ virtual bool IsCurrentlyUnresponsive() const = 0;
+
virtual void SetIgnoreInputEvents(bool ignore_input_events) = 0;
// Called to notify the RenderWidget that it has been resized.
@@ -224,7 +232,9 @@ class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender {
virtual ~InputEventObserver() {}
virtual void OnInputEvent(const blink::WebInputEvent&) {}
- virtual void OnInputEventAck(const blink::WebInputEvent&) {}
+ virtual void OnInputEventAck(InputEventAckSource source,
+ InputEventAckState state,
+ const blink::WebInputEvent&) {}
};
// Add/remove an input event observer.
@@ -237,33 +247,33 @@ class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender {
// Drag-and-drop drop target messages that get sent to Blink.
virtual void DragTargetDragEnter(
const DropData& drop_data,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
blink::WebDragOperationsMask operations_allowed,
int key_modifiers) {}
virtual void DragTargetDragEnterWithMetaData(
const std::vector<DropData::Metadata>& metadata,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
blink::WebDragOperationsMask operations_allowed,
- int key_modifiers) {};
+ int key_modifiers){};
virtual void DragTargetDragOver(
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
blink::WebDragOperationsMask operations_allowed,
int key_modifiers) {}
- virtual void DragTargetDragLeave(const gfx::Point& client_point,
- const gfx::Point& screen_point) {}
+ virtual void DragTargetDragLeave(const gfx::PointF& client_point,
+ const gfx::PointF& screen_point) {}
virtual void DragTargetDrop(const DropData& drop_data,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
int key_modifiers) {}
// Notifies the renderer that a drag operation that it started has ended,
// either in a drop or by being cancelled.
- virtual void DragSourceEndedAt(const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
- blink::WebDragOperation operation) {};
+ virtual void DragSourceEndedAt(const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
+ blink::WebDragOperation operation){};
// Notifies the renderer that we're done with the drag and drop operation.
// This allows the renderer to reset some state.
diff --git a/chromium/content/public/browser/render_widget_host_view.h b/chromium/content/public/browser/render_widget_host_view.h
index 995f917d9eb..6aa5a869ddc 100644
--- a/chromium/content/public/browser/render_widget_host_view.h
+++ b/chromium/content/public/browser/render_widget_host_view.h
@@ -14,6 +14,7 @@
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkImageInfo.h"
+#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/native_widget_types.h"
namespace gfx {
@@ -36,6 +37,7 @@ namespace content {
class RenderWidgetHost;
class RenderWidgetHostViewFrameSubscriber;
class TouchSelectionControllerClientManager;
+struct ScreenInfo;
// RenderWidgetHostView is an interface implemented by an object that acts as
// the "View" portion of a RenderWidgetHost. The RenderWidgetHost and its
@@ -79,14 +81,21 @@ class CONTENT_EXPORT RenderWidgetHostView {
// the top-level frame's renderer this is a no-op as they are already
// properly transformed; however, coordinates received from an out-of-process
// iframe renderer process require transformation.
- virtual gfx::Point TransformPointToRootCoordSpace(
- const gfx::Point& point) = 0;
-
- // A floating point variant of the above. PointF values will be snapped to
- // integral points before transformation.
virtual gfx::PointF TransformPointToRootCoordSpaceF(
const gfx::PointF& point) = 0;
+ // A int point variant of the above. Use float version to transform,
+ // then rounded back to int point.
+ gfx::Point TransformPointToRootCoordSpace(const gfx::Point& point) {
+ return gfx::ToRoundedPoint(
+ TransformPointToRootCoordSpaceF(gfx::PointF(point)));
+ }
+
+ // Converts a point in the root view's coordinate space to the coordinate
+ // space of whichever view is used to call this method.
+ virtual gfx::PointF TransformRootPointToViewCoordSpace(
+ const gfx::PointF& point) = 0;
+
// Retrieves the native view used to contain plugins and identify the
// renderer in IPC messages.
virtual gfx::NativeView GetNativeView() const = 0;
@@ -236,6 +245,9 @@ class CONTENT_EXPORT RenderWidgetHostView {
// when the value has changed. Views must initially default to false.
virtual void SetNeedsBeginFrames(bool needs_begin_frames) = 0;
+ // This method returns the ScreenInfo used by the view to render.
+ virtual void GetScreenInfo(ScreenInfo* screen_info) = 0;
+
#if defined(OS_MACOSX)
// Return the accelerated widget which hosts the CALayers that draw the
// content of the view in GetNativeView. This may be null.
diff --git a/chromium/content/public/browser/render_widget_host_view_mac_delegate.h b/chromium/content/public/browser/render_widget_host_view_mac_delegate.h
index 8e05950a767..da0360ceeed 100644
--- a/chromium/content/public/browser/render_widget_host_view_mac_delegate.h
+++ b/chromium/content/public/browser/render_widget_host_view_mac_delegate.h
@@ -12,6 +12,10 @@ class WebGestureEvent;
class WebMouseWheelEvent;
}
+namespace ui {
+struct DidOverscrollParams;
+}
+
// This protocol is used as a delegate for the NSView class used in the
// hierarchy. There are two ways to extend the view:
// - Implement the methods listed in the protocol below.
@@ -57,6 +61,7 @@ class WebMouseWheelEvent;
consumed:(BOOL)consumed;
- (void)rendererHandledGestureScrollEvent:(const blink::WebGestureEvent&)event
consumed:(BOOL)consumed;
+- (void)rendererHandledOverscrollEvent:(const ui::DidOverscrollParams&)params;
@end
#endif // CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_VIEW_MAC_DELEGATE_H_
diff --git a/chromium/content/public/browser/resource_dispatcher_host_delegate.cc b/chromium/content/public/browser/resource_dispatcher_host_delegate.cc
index f4f1a3cf40b..a96a467ce2d 100644
--- a/chromium/content/public/browser/resource_dispatcher_host_delegate.cc
+++ b/chromium/content/public/browser/resource_dispatcher_host_delegate.cc
@@ -86,8 +86,8 @@ void ResourceDispatcherHostDelegate::RequestComplete(
void ResourceDispatcherHostDelegate::RequestComplete(
net::URLRequest* url_request) {}
-PreviewsState ResourceDispatcherHostDelegate::GetPreviewsState(
- const net::URLRequest& url_request,
+PreviewsState ResourceDispatcherHostDelegate::DeterminePreviewsState(
+ net::URLRequest* url_request,
content::ResourceContext* resource_context,
PreviewsState previews_to_allow) {
return PREVIEWS_UNSPECIFIED;
@@ -104,8 +104,9 @@ ResourceDispatcherHostDelegate::CreateClientCertStore(
return std::unique_ptr<net::ClientCertStore>();
}
-bool ResourceDispatcherHostDelegate::ShouldUseResourceScheduler() const {
- return true;
+bool ResourceDispatcherHostDelegate::AllowRenderingMhtmlOverHttp(
+ net::URLRequest* request) const {
+ return false;
}
ResourceDispatcherHostDelegate::~ResourceDispatcherHostDelegate() {
diff --git a/chromium/content/public/browser/resource_dispatcher_host_delegate.h b/chromium/content/public/browser/resource_dispatcher_host_delegate.h
index 27ee2b29dad..7dea6538969 100644
--- a/chromium/content/public/browser/resource_dispatcher_host_delegate.h
+++ b/chromium/content/public/browser/resource_dispatcher_host_delegate.h
@@ -129,8 +129,8 @@ class CONTENT_EXPORT ResourceDispatcherHostDelegate {
// with an unspecified Previews state. If previews_to_allow is set to
// anything other than PREVIEWS_UNSPECIFIED, it is taken as a limit on
// available preview states.
- virtual PreviewsState GetPreviewsState(
- const net::URLRequest& url_request,
+ virtual PreviewsState DeterminePreviewsState(
+ net::URLRequest* url_request,
content::ResourceContext* resource_context,
PreviewsState previews_to_allow);
@@ -142,10 +142,8 @@ class CONTENT_EXPORT ResourceDispatcherHostDelegate {
virtual std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
ResourceContext* resource_context);
- // Whether or not to enable ResourceScheduling. This will almost always be
- // enabled, except for some C++ headless embedders who may implement their own
- // resource scheduling via protocol handlers.
- virtual bool ShouldUseResourceScheduler() const;
+ // Whether or not to allow load and render MHTML page from http/https URLs.
+ virtual bool AllowRenderingMhtmlOverHttp(net::URLRequest* request) const;
protected:
virtual ~ResourceDispatcherHostDelegate();
diff --git a/chromium/content/public/browser/resource_request_details.cc b/chromium/content/public/browser/resource_request_details.cc
index 0e790b68841..759915cf42d 100644
--- a/chromium/content/public/browser/resource_request_details.cc
+++ b/chromium/content/public/browser/resource_request_details.cc
@@ -31,13 +31,4 @@ ResourceRequestDetails::ResourceRequestDetails(const net::URLRequest* request,
ResourceRequestDetails::~ResourceRequestDetails() {}
-ResourceRedirectDetails::ResourceRedirectDetails(const net::URLRequest* request,
- bool has_certificate,
- const GURL& new_url)
- : ResourceRequestDetails(request, has_certificate),
- new_url(new_url) {
-}
-
-ResourceRedirectDetails::~ResourceRedirectDetails() {}
-
} // namespace content
diff --git a/chromium/content/public/browser/resource_request_details.h b/chromium/content/public/browser/resource_request_details.h
index e54e2c0fcc8..06b140186dd 100644
--- a/chromium/content/public/browser/resource_request_details.h
+++ b/chromium/content/public/browser/resource_request_details.h
@@ -43,17 +43,6 @@ struct ResourceRequestDetails {
int http_response_code;
};
-// Details about a redirection of a resource request.
-struct ResourceRedirectDetails : public ResourceRequestDetails {
- ResourceRedirectDetails(const net::URLRequest* request,
- bool has_certificate,
- const GURL& new_url);
- ~ResourceRedirectDetails() override;
-
- // The URL to which we are being redirected.
- GURL new_url;
-};
-
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_RESOURCE_REQUEST_DETAILS_H_
diff --git a/chromium/content/public/browser/resource_request_info.h b/chromium/content/public/browser/resource_request_info.h
index 9842408d2c3..374d38ec12c 100644
--- a/chromium/content/public/browser/resource_request_info.h
+++ b/chromium/content/public/browser/resource_request_info.h
@@ -8,9 +8,10 @@
#include "base/callback_forward.h"
#include "content/common/content_export.h"
#include "content/public/browser/global_request_id.h"
+#include "content/public/browser/navigation_ui_data.h"
#include "content/public/common/previews_state.h"
#include "content/public/common/resource_type.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
#include "ui/base/page_transition_types.h"
@@ -19,7 +20,6 @@ class URLRequest;
}
namespace content {
-class NavigationUIData;
class ResourceContext;
class WebContents;
@@ -40,16 +40,18 @@ class ResourceRequestInfo {
// download is not associated with a frame, the IDs can be all -1.
//
// NOTE: Add more parameters if you need to initialize other fields.
- CONTENT_EXPORT static void AllocateForTesting(net::URLRequest* request,
- ResourceType resource_type,
- ResourceContext* context,
- int render_process_id,
- int render_view_id,
- int render_frame_id,
- bool is_main_frame,
- bool allow_download,
- bool is_async,
- PreviewsState previews_state);
+ CONTENT_EXPORT static void AllocateForTesting(
+ net::URLRequest* request,
+ ResourceType resource_type,
+ ResourceContext* context,
+ int render_process_id,
+ int render_view_id,
+ int render_frame_id,
+ bool is_main_frame,
+ bool allow_download,
+ bool is_async,
+ PreviewsState previews_state,
+ std::unique_ptr<NavigationUIData> navigation_ui_data);
// Returns the associated RenderFrame for a given process. Returns false, if
// there is no associated RenderFrame. This method does not rely on the
@@ -108,9 +110,10 @@ class ResourceRequestInfo {
// The globally unique identifier for this request.
virtual GlobalRequestID GetGlobalRequestID() const = 0;
- // The pid of the originating process, if the request is sent on behalf of a
- // another process. Otherwise it is 0.
- virtual int GetOriginPID() const = 0;
+ // The child process unique ID of the originating process, if the request is
+ // was proxied through a renderer process on behalf of a pepper plugin
+ // process; -1 otherwise.
+ virtual int GetPluginChildID() const = 0;
// Returns the FrameTreeNode ID for this frame. This ID is browser-global and
// uniquely identifies a frame that hosts content.
@@ -138,7 +141,7 @@ class ResourceRequestInfo {
// Returns the associated visibility state at the time the request was started
// in the renderer.
- virtual blink::WebPageVisibilityState GetVisibilityState() const = 0;
+ virtual blink::mojom::PageVisibilityState GetVisibilityState() const = 0;
// Returns the associated page transition type.
virtual ui::PageTransition GetPageTransition() const = 0;
diff --git a/chromium/content/public/browser/shared_worker_service.h b/chromium/content/public/browser/shared_worker_service.h
new file mode 100644
index 00000000000..5ed1c72609e
--- /dev/null
+++ b/chromium/content/public/browser/shared_worker_service.h
@@ -0,0 +1,40 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_SHARED_WORKER_SERVICE_H_
+#define CONTENT_PUBLIC_BROWSER_SHARED_WORKER_SERVICE_H_
+
+namespace url {
+class Origin;
+} // namespace url
+
+namespace content {
+
+class ResourceContext;
+class StoragePartition;
+
+// A singleton for managing shared workers. These may be run in a separate
+// process, since multiple renderer processes can be talking to a single shared
+// worker. All the methods below can only be called on the UI thread. This
+// service does not manage service workers.
+class CONTENT_EXPORT SharedWorkerService {
+ public:
+ static SharedWorkerService* GetInstance();
+
+ // Terminates the given shared worker identified by its name, the URL of
+ // its main script resource, and the constructor origin. Returns true on
+ // success.
+ virtual bool TerminateWorker(const GURL& url,
+ const std::string& name,
+ const url::Origin& constructor_origin,
+ StoragePartition* storage_partition,
+ ResourceContext* resource_context) = 0;
+
+ protected:
+ virtual ~SharedWorkerService() = default;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_SHARED_WORKER_SERVICE_H_
diff --git a/chromium/content/public/browser/site_instance.h b/chromium/content/public/browser/site_instance.h
index 2d1a9a3dbca..a0739838640 100644
--- a/chromium/content/public/browser/site_instance.h
+++ b/chromium/content/public/browser/site_instance.h
@@ -152,6 +152,10 @@ class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance> {
content::BrowserContext* browser_context,
const GURL& url);
+ // Determine if a URL should "use up" a site. URLs such as about:blank or
+ // chrome-native:// leave the site unassigned.
+ static bool ShouldAssignSiteForURL(const GURL& url);
+
// Return whether both URLs are part of the same web site, for the purpose of
// assigning them to processes accordingly. The decision is currently based
// on the registered domain of the URLs (google.com, bbc.co.uk), as well as
diff --git a/chromium/content/public/browser/ssl_status.h b/chromium/content/public/browser/ssl_status.h
index d8c23ebd987..3e6ae04fbea 100644
--- a/chromium/content/public/browser/ssl_status.h
+++ b/chromium/content/public/browser/ssl_status.h
@@ -7,6 +7,7 @@
#include <stdint.h>
+#include <memory>
#include <vector>
#include "content/common/content_export.h"
@@ -55,20 +56,12 @@ struct CONTENT_EXPORT SSLStatus {
// loaded with certificate errors.
RAN_CONTENT_WITH_CERT_ERRORS = 1 << 3,
- // HTTP page containing a password input. Embedders may use this to
- // adjust UI on nonsecure pages that collect sensitive data.
- DISPLAYED_PASSWORD_FIELD_ON_HTTP = 1 << 4,
-
- // HTTP page containing a credit card input. Embedders may use this to
- // adjust UI on nonsecure pages that collect sensitive data.
- DISPLAYED_CREDIT_CARD_FIELD_ON_HTTP = 1 << 5,
-
// HTTPS page containing a form targeting an insecure action url.
DISPLAYED_FORM_WITH_INSECURE_ACTION = 1 << 6,
};
SSLStatus();
- SSLStatus(const net::SSLInfo& ssl_info);
+ explicit SSLStatus(const net::SSLInfo& ssl_info);
SSLStatus(const SSLStatus& other);
SSLStatus& operator=(SSLStatus other);
~SSLStatus();
diff --git a/chromium/content/public/browser/storage_partition.h b/chromium/content/public/browser/storage_partition.h
index c3c1aa9d535..fa9a14e8247 100644
--- a/chromium/content/public/browser/storage_partition.h
+++ b/chromium/content/public/browser/storage_partition.h
@@ -13,6 +13,7 @@
#include "base/files/file_path.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
+#include "content/public/common/url_loader_factory.mojom.h"
#include "net/cookies/cookie_store.h"
class GURL;
@@ -119,8 +120,7 @@ class CONTENT_EXPORT StoragePartition {
// inside this StoragePartition for the given |storage_origin|.
// Note session dom storage is not cleared even if you specify
// REMOVE_DATA_MASK_LOCAL_STORAGE.
- // |callback| is called when data deletion is done or at least the deletion is
- // scheduled.
+ // No notification is dispatched upon completion.
//
// TODO(ajwong): Right now, the embedder may have some
// URLRequestContextGetter objects that the StoragePartition does not know
@@ -130,8 +130,7 @@ class CONTENT_EXPORT StoragePartition {
virtual void ClearDataForOrigin(uint32_t remove_mask,
uint32_t quota_storage_remove_mask,
const GURL& storage_origin,
- net::URLRequestContextGetter* rq_context,
- const base::Closure& callback) = 0;
+ net::URLRequestContextGetter* rq_context) = 0;
// A callback type to check if a given origin matches a storage policy.
// Can be passed empty/null where used, which means the origin will always
@@ -156,7 +155,7 @@ class CONTENT_EXPORT StoragePartition {
const OriginMatcherFunction& origin_matcher,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) = 0;
+ base::OnceClosure callback) = 0;
// Similar to ClearData().
// Deletes all data out for the StoragePartition.
@@ -176,7 +175,7 @@ class CONTENT_EXPORT StoragePartition {
const CookieMatcherFunction& cookie_matcher,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) = 0;
+ base::OnceClosure callback) = 0;
// Clears the HTTP and media caches associated with this StoragePartition's
// request contexts. If |begin| and |end| are not null, only entries with
@@ -186,7 +185,7 @@ class CONTENT_EXPORT StoragePartition {
const base::Time begin,
const base::Time end,
const base::Callback<bool(const GURL&)>& url_matcher,
- const base::Closure& callback) = 0;
+ base::OnceClosure callback) = 0;
// Write any unwritten data to disk.
// Note: this method does not sync the data - it only ensures that any
@@ -196,6 +195,11 @@ class CONTENT_EXPORT StoragePartition {
// Clear the bluetooth allowed devices map. For test use only.
virtual void ClearBluetoothAllowedDevicesMapForTesting() = 0;
+ // Overrides the network URLLoaderFactory for subsequent requests. Passing a
+ // null pointer will restore the default behavior.
+ virtual void SetNetworkFactoryForTesting(
+ mojom::URLLoaderFactory* test_factory) = 0;
+
protected:
virtual ~StoragePartition() {}
};
diff --git a/chromium/content/public/browser/stored_payment_app.cc b/chromium/content/public/browser/stored_payment_app.cc
index e1c48a12bef..7d1a74794b1 100644
--- a/chromium/content/public/browser/stored_payment_app.cc
+++ b/chromium/content/public/browser/stored_payment_app.cc
@@ -10,6 +10,12 @@ StoredRelatedApplication::StoredRelatedApplication() = default;
StoredRelatedApplication::~StoredRelatedApplication() = default;
+StoredCapabilities::StoredCapabilities() = default;
+
+StoredCapabilities::StoredCapabilities(const StoredCapabilities&) = default;
+
+StoredCapabilities::~StoredCapabilities() = default;
+
StoredPaymentApp::StoredPaymentApp() = default;
StoredPaymentApp::~StoredPaymentApp() = default;
diff --git a/chromium/content/public/browser/stored_payment_app.h b/chromium/content/public/browser/stored_payment_app.h
index e8f6a0c3afc..359b3257aea 100644
--- a/chromium/content/public/browser/stored_payment_app.h
+++ b/chromium/content/public/browser/stored_payment_app.h
@@ -24,6 +24,19 @@ struct CONTENT_EXPORT StoredRelatedApplication {
std::string id;
};
+// This class represents the stored capabilities.
+struct CONTENT_EXPORT StoredCapabilities {
+ StoredCapabilities();
+ StoredCapabilities(const StoredCapabilities&);
+ ~StoredCapabilities();
+
+ // A list of ::payments::mojom::BasicCardNetwork.
+ std::vector<int32_t> supported_card_networks;
+
+ // A list of ::payments::mojom::BasicCardType.
+ std::vector<int32_t> supported_card_types;
+};
+
// This class represents the stored payment app.
struct CONTENT_EXPORT StoredPaymentApp {
StoredPaymentApp();
@@ -44,6 +57,12 @@ struct CONTENT_EXPORT StoredPaymentApp {
// A list of one or more enabled payment methods in this payment app.
std::vector<std::string> enabled_methods;
+ // A list of capabilities in this payment app.
+ // |capabilities| is non-empty only if |enabled_methods| contains "basic-card"
+ // for now and these |capabilities| apply only to the "basic-card" instrument,
+ // although we don't store the instruments individually.
+ std::vector<StoredCapabilities> capabilities;
+
// A flag indicates whether the app prefers the related applications.
bool prefer_related_applications = false;
diff --git a/chromium/content/public/browser/utility_process_host.h b/chromium/content/public/browser/utility_process_host.h
index 489f267f9bd..376a3c29fd5 100644
--- a/chromium/content/public/browser/utility_process_host.h
+++ b/chromium/content/public/browser/utility_process_host.h
@@ -62,11 +62,6 @@ class UtilityProcessHost : public IPC::Sender {
// SANDBOX_TYPE_NO_SANDBOX is specified.
virtual void SetSandboxType(service_manager::SandboxType sandbox_type) = 0;
-#if defined(OS_WIN)
- // Make the process run elevated.
- virtual void ElevatePrivileges() = 0;
-#endif
-
// Returns information about the utility child process.
virtual const ChildProcessData& GetData() = 0;
diff --git a/chromium/content/public/browser/utility_process_mojo_client.h b/chromium/content/public/browser/utility_process_mojo_client.h
index 9b4626fdd43..4bce6f2c054 100644
--- a/chromium/content/public/browser/utility_process_mojo_client.h
+++ b/chromium/content/public/browser/utility_process_mojo_client.h
@@ -140,7 +140,8 @@ class UtilityProcessMojoClient {
#if defined(OS_WIN)
if (run_elevated_) {
DCHECK(disable_sandbox_);
- utility_host_->ElevatePrivileges();
+ utility_host_->SetSandboxType(
+ service_manager::SANDBOX_TYPE_NO_SANDBOX_AND_ELEVATED_PRIVILEGES);
}
#endif // defined(OS_WIN)
diff --git a/chromium/content/public/browser/web_contents.cc b/chromium/content/public/browser/web_contents.cc
index fa0afb545df..53d56abb35a 100644
--- a/chromium/content/public/browser/web_contents.cc
+++ b/chromium/content/public/browser/web_contents.cc
@@ -29,8 +29,8 @@ WebContents::CreateParams::CreateParams(BrowserContext* context,
guest_delegate(nullptr),
context(nullptr),
renderer_initiated_creation(false),
- initialize_renderer(false) {
-}
+ initialize_renderer(false),
+ starting_sandbox_flags(blink::WebSandboxFlags::kNone) {}
WebContents::CreateParams::CreateParams(const CreateParams& other) = default;
diff --git a/chromium/content/public/browser/web_contents.h b/chromium/content/public/browser/web_contents.h
index 453942537f6..d6252667ed6 100644
--- a/chromium/content/public/browser/web_contents.h
+++ b/chromium/content/public/browser/web_contents.h
@@ -28,6 +28,7 @@
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_ui.h"
#include "content/public/common/stop_find_action.h"
+#include "third_party/WebKit/common/sandbox_flags.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/accessibility/ax_tree_update.h"
#include "ui/base/window_open_disposition.h"
@@ -65,7 +66,6 @@ namespace content {
class BrowserContext;
class BrowserPluginGuestDelegate;
class InterstitialPage;
-class PageState;
class RenderFrameHost;
class RenderViewHost;
class RenderWidgetHost;
@@ -170,6 +170,9 @@ class WebContents : public PageNavigator,
// Note that the pre-created renderer process may not be used if the first
// navigation requires a dedicated or privileged process, such as a WebUI.
bool initialize_renderer;
+
+ // Sandboxing flags set on the new WebContents.
+ blink::WebSandboxFlags starting_sandbox_flags;
};
// Creates a new WebContents.
@@ -639,12 +642,6 @@ class WebContents : public PageNavigator,
virtual void SetClosedByUserGesture(bool value) = 0;
virtual bool GetClosedByUserGesture() const = 0;
- // Opens view-source tab for this contents.
- virtual void ViewSource() = 0;
-
- virtual void ViewFrameSource(const GURL& url,
- const PageState& page_state) = 0;
-
// Gets the minimum/maximum zoom percent.
virtual int GetMinimumZoomPercent() const = 0;
virtual int GetMaximumZoomPercent() const = 0;
@@ -741,6 +738,10 @@ class WebContents : public PageNavigator,
// Returns true if audio has recently been audible from the WebContents.
virtual bool WasRecentlyAudible() = 0;
+ // Returns true if audio has been audible from the WebContents since the last
+ // navigation.
+ virtual bool WasEverAudible() = 0;
+
// The callback invoked when the renderer responds to a request for the main
// frame document's manifest. The url will be empty if the document specifies
// no manifest, and the manifest will be empty if any other failures occurred.
@@ -766,24 +767,6 @@ class WebContents : public PageNavigator,
// as soon as they are ready.
virtual void ResumeLoadingCreatedWebContents() = 0;
- // Called when the WebContents has displayed a password field on an
- // HTTP page. This method modifies the appropriate NavigationEntry's
- // SSLStatus to record the sensitive input field, so that embedders
- // can adjust the UI if desired.
- virtual void OnPasswordInputShownOnHttp() = 0;
-
- // Called when the WebContents has hidden all password fields on an
- // HTTP page. This method modifies the appropriate NavigationEntry's
- // SSLStatus to remove the presence of sensitive input fields, so that
- // embedders can adjust the UI if desired.
- virtual void OnAllPasswordInputsHiddenOnHttp() = 0;
-
- // Called when the WebContents has displayed a credit card field on an
- // HTTP page. This method modifies the appropriate NavigationEntry's
- // SSLStatus to record the sensitive input field, so that embedders
- // can adjust the UI if desired.
- virtual void OnCreditCardInputShownOnHttp() = 0;
-
// Sets whether the WebContents is for overlaying content on a page.
virtual void SetIsOverlayContent(bool is_overlay_content) = 0;
diff --git a/chromium/content/public/browser/web_contents_binding_set.h b/chromium/content/public/browser/web_contents_binding_set.h
index 0b56e880f7f..fe92574340e 100644
--- a/chromium/content/public/browser/web_contents_binding_set.h
+++ b/chromium/content/public/browser/web_contents_binding_set.h
@@ -116,7 +116,7 @@ class WebContentsFrameBindingSet : public WebContentsBindingSet {
: WebContentsBindingSet(
web_contents,
Interface::Name_,
- base::MakeUnique<FrameInterfaceBinder>(this, web_contents, impl)) {}
+ std::make_unique<FrameInterfaceBinder>(this, web_contents, impl)) {}
~WebContentsFrameBindingSet() {}
// Returns the RenderFrameHost currently targeted by a message dispatch to
diff --git a/chromium/content/public/browser/web_contents_delegate.cc b/chromium/content/public/browser/web_contents_delegate.cc
index 959fe727968..2ef566f7871 100644
--- a/chromium/content/public/browser/web_contents_delegate.cc
+++ b/chromium/content/public/browser/web_contents_delegate.cc
@@ -4,6 +4,8 @@
#include "content/public/browser/web_contents_delegate.h"
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
@@ -88,29 +90,6 @@ bool WebContentsDelegate::HandleContextMenu(
return false;
}
-void WebContentsDelegate::ViewSourceForTab(WebContents* source,
- const GURL& page_url) {
- // Fall back implementation based entirely on the view-source scheme.
- // It suffers from http://crbug.com/523 and that is why browser overrides
- // it with proper implementation.
- GURL url = GURL(kViewSourceScheme + std::string(":") + page_url.spec());
- OpenURLFromTab(
- source,
- OpenURLParams(url, Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
- ui::PAGE_TRANSITION_LINK, false));
-}
-
-void WebContentsDelegate::ViewSourceForFrame(WebContents* source,
- const GURL& frame_url,
- const PageState& page_state) {
- // Same as ViewSourceForTab, but for given subframe.
- GURL url = GURL(kViewSourceScheme + std::string(":") + frame_url.spec());
- OpenURLFromTab(
- source,
- OpenURLParams(url, Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
- ui::PAGE_TRANSITION_LINK, false));
-}
-
KeyboardEventProcessingResult WebContentsDelegate::PreHandleKeyboardEvent(
WebContents* source,
const NativeWebKeyboardEvent& event) {
@@ -247,7 +226,7 @@ void WebContentsDelegate::Detach(WebContents* web_contents) {
}
gfx::Size WebContentsDelegate::GetSizeForNewRenderView(
- WebContents* web_contents) const {
+ WebContents* web_contents) const {
return gfx::Size();
}
@@ -277,4 +256,16 @@ bool WebContentsDelegate::ShouldAllowRunningInsecureContent(
return allowed_per_prefs;
}
+int WebContentsDelegate::GetTopControlsHeight() const {
+ return 0;
+}
+
+int WebContentsDelegate::GetBottomControlsHeight() const {
+ return 0;
+}
+
+bool WebContentsDelegate::DoBrowserControlsShrinkBlinkSize() const {
+ return false;
+}
+
} // namespace content
diff --git a/chromium/content/public/browser/web_contents_delegate.h b/chromium/content/public/browser/web_contents_delegate.h
index 3f31a372ecb..37db677b743 100644
--- a/chromium/content/public/browser/web_contents_delegate.h
+++ b/chromium/content/public/browser/web_contents_delegate.h
@@ -42,7 +42,6 @@ class FilePath;
namespace content {
class ColorChooser;
class JavaScriptDialogManager;
-class PageState;
class RenderFrameHost;
class RenderWidgetHost;
class SessionStorageNamespace;
@@ -239,15 +238,6 @@ class CONTENT_EXPORT WebContentsDelegate {
// Returns true if the context menu operation was handled by the delegate.
virtual bool HandleContextMenu(const content::ContextMenuParams& params);
- // Opens source view for given WebContents that is navigated to the given
- // page url.
- virtual void ViewSourceForTab(WebContents* source, const GURL& page_url);
-
- // Opens source view for the given subframe.
- virtual void ViewSourceForFrame(WebContents* source,
- const GURL& url,
- const PageState& page_state);
-
// Allows delegates to handle keyboard events before sending to the renderer.
// See enum for description of return values.
virtual KeyboardEventProcessingResult PreHandleKeyboardEvent(
@@ -503,22 +493,6 @@ class CONTENT_EXPORT WebContentsDelegate {
// used.
virtual gfx::Size GetSizeForNewRenderView(WebContents* web_contents) const;
- // Notification that validation of a form displayed by the |web_contents|
- // has failed. There can only be one message per |web_contents| at a time.
- virtual void ShowValidationMessage(WebContents* web_contents,
- const gfx::Rect& anchor_in_root_view,
- const base::string16& main_text,
- const base::string16& sub_text) {}
-
- // Notification that the delegate should hide any showing form validation
- // message.
- virtual void HideValidationMessage(WebContents* web_contents) {}
-
- // Notification that the form element that triggered the validation failure
- // has moved.
- virtual void MoveValidationMessage(WebContents* web_contents,
- const gfx::Rect& anchor_in_root_view) {}
-
// Returns true if the WebContents is never visible.
virtual bool IsNeverVisible(WebContents* web_contents);
@@ -537,8 +511,8 @@ class CONTENT_EXPORT WebContentsDelegate {
// Requests the app banner. This method is called from the DevTools.
virtual void RequestAppBannerFromDevTools(content::WebContents* web_contents);
- // Called when audio change occurs
- virtual void OnAudioStateChanged(bool audible) {}
+ // Called when an audio change occurs.
+ virtual void OnAudioStateChanged(WebContents* web_contents, bool audible) {}
// Called when a suspicious navigation of the main frame has been blocked.
// Allows the delegate to provide some UI to let the user know about the
@@ -557,6 +531,15 @@ class CONTENT_EXPORT WebContentsDelegate {
const url::Origin& origin,
const GURL& resource_url);
+ // 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
+ // content to poll these values again, except part of resize. But this is not
+ // needed by embedder because it's always accompanied by view size change.
+ virtual int GetTopControlsHeight() const;
+ virtual int GetBottomControlsHeight() const;
+ virtual bool DoBrowserControlsShrinkBlinkSize() const;
+
// Give WebContentsDelegates the opportunity to adjust the previews state.
virtual void AdjustPreviewsStateForNavigation(PreviewsState* previews_state) {
}
diff --git a/chromium/content/public/browser/web_contents_observer.h b/chromium/content/public/browser/web_contents_observer.h
index 7b82d706ea0..131f2bc6f97 100644
--- a/chromium/content/public/browser/web_contents_observer.h
+++ b/chromium/content/public/browser/web_contents_observer.h
@@ -44,7 +44,6 @@ struct FaviconURL;
struct LoadCommittedDetails;
struct PrunedDetails;
struct Referrer;
-struct ResourceRedirectDetails;
struct ResourceRequestDetails;
// An observer API implemented by classes which are interested in various page
@@ -258,11 +257,6 @@ class CONTENT_EXPORT WebContentsObserver : public IPC::Listener {
virtual void DidGetResourceResponseStart(
const ResourceRequestDetails& details) {}
- // This method is invoked when a redirect has been received for a resource
- // request.
- virtual void DidGetRedirectForResourceRequest(
- const ResourceRedirectDetails& details) {}
-
// This method is invoked when a new non-pending navigation entry is created.
// This corresponds to one NavigationController entry being created
// (in the case of new navigations) or renavigated to (for back/forward
@@ -337,7 +331,9 @@ class CONTENT_EXPORT WebContentsObserver : public IPC::Listener {
virtual void FrameNameChanged(RenderFrameHost* render_frame_host,
const std::string& name) {}
- // This methods is invoked when the title of the WebContents is set.
+ // This method is invoked when the title of the WebContents is set. Note that
+ // |entry| may be null if the web page whose title changed has not yet had a
+ // NavigationEntry assigned to it.
virtual void TitleWasSet(NavigationEntry* entry) {}
virtual void AppCacheAccessed(const GURL& manifest_url,
@@ -435,8 +431,17 @@ class CONTENT_EXPORT WebContentsObserver : public IPC::Listener {
using MediaPlayerId = std::pair<RenderFrameHost*, int>;
virtual void MediaStartedPlaying(const MediaPlayerInfo& video_type,
const MediaPlayerId& id) {}
- virtual void MediaStoppedPlaying(const MediaPlayerInfo& video_type,
- const MediaPlayerId& id) {}
+ enum class MediaStoppedReason {
+ // The media was stopped for an unspecified reason.
+ kUnspecified,
+
+ // The media was stopped because it reached the end of the stream.
+ kReachedEndOfStream,
+ };
+ virtual void MediaStoppedPlaying(
+ const MediaPlayerInfo& video_type,
+ const MediaPlayerId& id,
+ WebContentsObserver::MediaStoppedReason reason) {}
virtual void MediaResized(const gfx::Size& size, const MediaPlayerId& id) {}
// Invoked when media enters or exits fullscreen. We must use a heuristic
// to determine this as it is not trivial for media with custom controls.
diff --git a/chromium/content/public/browser/web_contents_view_delegate.cc b/chromium/content/public/browser/web_contents_view_delegate.cc
index cc4f8ce639f..3d0a1bfd371 100644
--- a/chromium/content/public/browser/web_contents_view_delegate.cc
+++ b/chromium/content/public/browser/web_contents_view_delegate.cc
@@ -27,14 +27,18 @@ void WebContentsViewDelegate::ShowContextMenu(
void WebContentsViewDelegate::StoreFocus() {
}
-void WebContentsViewDelegate::RestoreFocus() {
+bool WebContentsViewDelegate::RestoreFocus() {
+ return false;
}
+void WebContentsViewDelegate::ResetStoredFocus() {}
+
bool WebContentsViewDelegate::Focus() {
return false;
}
-void WebContentsViewDelegate::TakeFocus(bool reverse) {
+bool WebContentsViewDelegate::TakeFocus(bool reverse) {
+ return false;
}
void WebContentsViewDelegate::SizeChanged(const gfx::Size& size) {
diff --git a/chromium/content/public/browser/web_contents_view_delegate.h b/chromium/content/public/browser/web_contents_view_delegate.h
index 21bf273e5d5..b7a1112ccab 100644
--- a/chromium/content/public/browser/web_contents_view_delegate.h
+++ b/chromium/content/public/browser/web_contents_view_delegate.h
@@ -45,13 +45,23 @@ class CONTENT_EXPORT WebContentsViewDelegate {
virtual void ShowContextMenu(RenderFrameHost* render_frame_host,
const ContextMenuParams& params);
- // These methods allow the embedder to intercept a WebContentsView's
- // implementation of these methods. See the WebContentsView interface
- // documentation for more information about these methods.
+ // Store the current focused view and start tracking it.
virtual void StoreFocus();
- virtual void RestoreFocus();
+
+ // Restore focus to stored view if possible, return true if successful.
+ virtual bool RestoreFocus();
+
+ // Clears any stored focus.
+ virtual void ResetStoredFocus();
+
+ // Allows the delegate to intercept a request to focus the WebContents,
+ // and focus something else instead. Returns true when intercepted.
virtual bool Focus();
- virtual void TakeFocus(bool reverse);
+
+ // Advance focus to the view that follows or precedes the WebContents.
+ virtual bool TakeFocus(bool reverse);
+
+ // Allows the delegate to update bounds for a special views.
virtual void SizeChanged(const gfx::Size& size);
// This method allows the embedder to specify the display color space (instead
diff --git a/chromium/content/public/browser/web_ui.h b/chromium/content/public/browser/web_ui.h
index 63524c3f9cc..76bd6a5f458 100644
--- a/chromium/content/public/browser/web_ui.h
+++ b/chromium/content/public/browser/web_ui.h
@@ -70,8 +70,7 @@ class CONTENT_EXPORT WebUI {
std::unique_ptr<WebUIMessageHandler> handler) = 0;
// Used by WebUIMessageHandlers. If the given message is already registered,
- // the call has no effect unless |register_callback_overwrites_| is set to
- // true.
+ // the call has no effect.
typedef base::Callback<void(const base::ListValue*)> MessageCallback;
virtual void RegisterMessageCallback(const std::string& message,
const MessageCallback& callback) = 0;
diff --git a/chromium/content/public/browser/webrtc_log.cc b/chromium/content/public/browser/webrtc_log.cc
new file mode 100644
index 00000000000..63939a99627
--- /dev/null
+++ b/chromium/content/public/browser/webrtc_log.cc
@@ -0,0 +1,26 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/webrtc_log.h"
+
+#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+// static
+void WebRtcLog::SetLogMessageCallback(
+ int render_process_id,
+ const base::Callback<void(const std::string&)>& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ MediaStreamManager::RegisterNativeLogCallback(render_process_id, callback);
+}
+
+// static
+void WebRtcLog::ClearLogMessageCallback(int render_process_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ MediaStreamManager::UnregisterNativeLogCallback(render_process_id);
+}
+
+} // namespace content
diff --git a/chromium/content/public/browser/webrtc_log.h b/chromium/content/public/browser/webrtc_log.h
new file mode 100644
index 00000000000..16fefc7f7ba
--- /dev/null
+++ b/chromium/content/public/browser/webrtc_log.h
@@ -0,0 +1,37 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_WEBRTC_LOG_H_
+#define CONTENT_PUBLIC_BROWSER_WEBRTC_LOG_H_
+
+#include <string>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "media/media_features.h"
+
+#if !BUILDFLAG(ENABLE_WEBRTC)
+#error "WebRTC not enabled."
+#endif
+
+namespace content {
+
+class CONTENT_EXPORT WebRtcLog {
+ public:
+ // When set, |callback| receives log messages regarding, for example, media
+ // devices (webcams, mics, etc) that were initially requested in the render
+ // process associated with the RenderProcessHost with |render_process_id|.
+ static void SetLogMessageCallback(
+ int render_process_id,
+ const base::Callback<void(const std::string&)>& callback);
+ static void ClearLogMessageCallback(int render_process_id);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcLog);
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_WEBRTC_LOG_H_
diff --git a/chromium/content/public/browser/worker_service.h b/chromium/content/public/browser/worker_service.h
deleted file mode 100644
index 9615fcddecc..00000000000
--- a/chromium/content/public/browser/worker_service.h
+++ /dev/null
@@ -1,53 +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_BROWSER_WORKER_SERVICE_H_
-#define CONTENT_PUBLIC_BROWSER_WORKER_SERVICE_H_
-
-#include <string>
-#include <vector>
-
-#include "content/common/content_export.h"
-#include "url/gurl.h"
-
-namespace content {
-
-class WorkerServiceObserver;
-
-// A singleton for managing HTML5 shared web workers. These may be run in a
-// separate process, since multiple renderer processes can be talking to a
-// single shared worker. All the methods below can only be called on the UI
-// thread.
-class CONTENT_EXPORT WorkerService {
- public:
- virtual ~WorkerService() {}
-
- // Returns the WorkerService singleton.
- static WorkerService* GetInstance();
-
- // Terminates the given worker. Returns true if the process was found.
- virtual bool TerminateWorker(int process_id, int route_id) = 0;
-
- // Terminates all workers and notifies when complete. This is used for
- // testing when it is important to make sure that all shared worker activity
- // has stopped.
- virtual void TerminateAllWorkersForTesting(base::OnceClosure callback) = 0;
-
- struct WorkerInfo {
- GURL url;
- std::string name;
- int process_id;
- int route_id;
- };
-
- // Return information about all the currently running workers.
- virtual std::vector<WorkerInfo> GetWorkers() = 0;
-
- virtual void AddObserver(WorkerServiceObserver* observer) = 0;
- virtual void RemoveObserver(WorkerServiceObserver* observer) = 0;
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_BROWSER_WORKER_SERVICE_H_
diff --git a/chromium/content/public/browser/worker_service_observer.h b/chromium/content/public/browser/worker_service_observer.h
deleted file mode 100644
index 8392fb7940a..00000000000
--- a/chromium/content/public/browser/worker_service_observer.h
+++ /dev/null
@@ -1,29 +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_BROWSER_WORKER_SERVICE_OBSERVER_H_
-#define CONTENT_PUBLIC_BROWSER_WORKER_SERVICE_OBSERVER_H_
-
-#include <string>
-
-class GURL;
-
-namespace content {
-
-// All the methods below are called on the UI thread.
-class WorkerServiceObserver {
- public:
- virtual void WorkerCreated(const GURL& url,
- const std::string& name,
- int process_id,
- int route_id) {}
- virtual void WorkerDestroyed(int process_id, int route_id) {}
-
- protected:
- virtual ~WorkerServiceObserver() {}
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_BROWSER_WORKER_SERVICE_OBSERVER_H_
diff --git a/chromium/content/public/child/BUILD.gn b/chromium/content/public/child/BUILD.gn
index bde29939a0e..8d8c9ac8acb 100644
--- a/chromium/content/public/child/BUILD.gn
+++ b/chromium/content/public/child/BUILD.gn
@@ -30,15 +30,8 @@ source_set("child_sources") {
sources = [
"child_process_sandbox_support_linux.h",
"child_thread.h",
- "child_url_loader_factory_getter.h",
"dwrite_font_proxy_init_win.h",
- "fixed_received_data.cc",
- "fixed_received_data.h",
"image_decoder_utils.h",
- "request_peer.h",
- "resource_dispatcher_delegate.h",
- "v8_value_converter.h",
- "worker_thread.h",
]
configs += [
diff --git a/chromium/content/public/common/BUILD.gn b/chromium/content/public/common/BUILD.gn
index 6fd09e08276..235a37ef45b 100644
--- a/chromium/content/public/common/BUILD.gn
+++ b/chromium/content/public/common/BUILD.gn
@@ -108,8 +108,6 @@ source_set("common_sources") {
sources = [
"appcache_info.h",
- "associated_interface_provider.h",
- "associated_interface_registry.h",
"bind_interface_helpers.h",
"bindings_policy.h",
"browser_controls_state.h",
@@ -153,6 +151,8 @@ source_set("common_sources") {
"frame_navigate_params.h",
"injection_test_mac.h",
"injection_test_win.h",
+ "input_event_ack_source.h",
+ "input_event_ack_state.h",
"isolated_world_ids.h",
"javascript_dialog_type.h",
"main_function_params.h",
@@ -170,7 +170,8 @@ source_set("common_sources") {
"mhtml_generation_params.h",
"mojo_channel_switches.cc",
"mojo_channel_switches.h",
- "mutable_network_traffic_annotation_tag_struct_traits.h",
+ "network_connection_tracker.cc",
+ "network_connection_tracker.h",
"notification_resources.cc",
"notification_resources.h",
"origin_trial_policy.cc",
@@ -207,8 +208,6 @@ source_set("common_sources") {
"resource_request.h",
"resource_request_body.cc",
"resource_request_body.h",
- "resource_request_completion_status.cc",
- "resource_request_completion_status.h",
"resource_response.cc",
"resource_response.h",
"resource_response_info.cc",
@@ -217,7 +216,6 @@ source_set("common_sources") {
"resource_type.h",
"result_codes.h",
"sandbox_init.h",
- "sandbox_linux.h",
"sandboxed_process_launcher_delegate.cc",
"sandboxed_process_launcher_delegate.h",
"screen_info.cc",
@@ -250,6 +248,7 @@ source_set("common_sources") {
"web_preferences.h",
"webplugininfo.cc",
"webplugininfo.h",
+ "webplugininfo_param_traits.h",
"zygote_fork_delegate_linux.h",
"zygote_handle.h",
]
@@ -273,6 +272,7 @@ source_set("common_sources") {
"//services/service_manager/public/cpp",
"//services/service_manager/public/interfaces",
"//third_party/WebKit/public:blink_headers",
+ "//third_party/WebKit/public:mojo_bindings",
"//ui/accessibility",
"//ui/surface",
"//url/ipc:url_ipc",
@@ -350,20 +350,24 @@ mojom("interfaces") {
visibility = [
":common_sources",
"//content/common/*",
+ "//chrome/common:mojo_bindings",
+ "//chrome/common:mojo_bindings_blink",
]
sources = [
+ "appcache_info.mojom",
"download_stream.mojom",
- "mutable_network_traffic_annotation_tag.mojom",
"network_service.mojom",
"network_service_test.mojom",
"push_messaging_status.mojom",
"url_loader.mojom",
"url_loader_factory.mojom",
+ "webplugininfo.mojom",
"window_container_type.mojom",
]
public_deps = [
+ ":resource_type_bindings",
"//mojo/common:common_custom_types",
"//services/network/public/interfaces",
"//url/mojo:url_mojom_gurl",
diff --git a/chromium/content/public/common/DEPS b/chromium/content/public/common/DEPS
index ced58cb0ed5..15b058f213d 100644
--- a/chromium/content/public/common/DEPS
+++ b/chromium/content/public/common/DEPS
@@ -1,6 +1,7 @@
specific_include_rules = {
".*\.cc": [
"+content/common",
+ "+services/network/public/cpp",
"+third_party/WebKit/common",
],
"simple_url_loader\.cc": [
@@ -14,4 +15,7 @@ specific_include_rules = {
"simple_url_loader_unittest\.cc": [
"+content/public/network",
],
+ "network_connection_tracker_unittest\.cc": [
+ "+content/public/network",
+ ],
}
diff --git a/chromium/content/public/common/OWNERS b/chromium/content/public/common/OWNERS
index 2e3716d6435..95b4485f660 100644
--- a/chromium/content/public/common/OWNERS
+++ b/chromium/content/public/common/OWNERS
@@ -4,6 +4,10 @@ per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
# DirectWrite
per-file dwrite_font_platform_win.h=scottmg@chromium.org
+# Network Service. These files will be moved into services/network.
+per-file network*=file://content/network/OWNERS
+per-file simple_url_loader*=file://content/network/OWNERS
+
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
per-file *_struct_traits*.*=set noparent
diff --git a/chromium/content/public/common/appcache_info.h b/chromium/content/public/common/appcache_info.h
index fa401e8453d..eb3ecb92dd8 100644
--- a/chromium/content/public/common/appcache_info.h
+++ b/chromium/content/public/common/appcache_info.h
@@ -11,6 +11,7 @@
#include "base/time/time.h"
#include "content/common/content_export.h"
+#include "content/public/common/appcache_info.mojom.h"
#include "third_party/WebKit/public/platform/WebApplicationCacheHost.h"
#include "url/gurl.h"
@@ -20,35 +21,13 @@ typedef base::OnceCallback<void(int)> OnceCompletionCallback;
static const int kAppCacheNoHostId =
blink::WebApplicationCacheHost::kAppCacheNoHostId;
-static const int64_t kAppCacheNoCacheId = 0;
-static const int64_t kAppCacheNoResponseId = 0;
-static const int64_t kAppCacheUnknownCacheId = -1;
-
-enum AppCacheStatus {
- APPCACHE_STATUS_UNCACHED,
- APPCACHE_STATUS_IDLE,
- APPCACHE_STATUS_CHECKING,
- APPCACHE_STATUS_DOWNLOADING,
- APPCACHE_STATUS_UPDATE_READY,
- APPCACHE_STATUS_OBSOLETE,
- APPCACHE_STATUS_LAST = APPCACHE_STATUS_OBSOLETE
-};
-
-struct CONTENT_EXPORT AppCacheInfo {
- AppCacheInfo();
- AppCacheInfo(const AppCacheInfo& other);
- ~AppCacheInfo();
-
- GURL manifest_url;
- base::Time creation_time;
- base::Time last_update_time;
- base::Time last_access_time;
- int64_t cache_id;
- int64_t group_id;
- AppCacheStatus status;
- int64_t size;
- bool is_complete;
-};
+
+using mojom::kAppCacheNoCacheId;
+using mojom::kAppCacheNoResponseId;
+using mojom::kAppCacheUnknownCacheId;
+
+using mojom::AppCacheStatus;
+using mojom::AppCacheInfo;
typedef std::vector<AppCacheInfo> AppCacheInfoVector;
diff --git a/chromium/content/public/common/appcache_info.mojom b/chromium/content/public/common/appcache_info.mojom
new file mode 100644
index 00000000000..0ccf447a4a4
--- /dev/null
+++ b/chromium/content/public/common/appcache_info.mojom
@@ -0,0 +1,33 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+import "mojo/common/time.mojom";
+import "url/mojo/url.mojom";
+
+const int64 kAppCacheNoCacheId = 0;
+const int64 kAppCacheNoResponseId = 0;
+const int64 kAppCacheUnknownCacheId = -1;
+
+enum AppCacheStatus {
+ APPCACHE_STATUS_UNCACHED,
+ APPCACHE_STATUS_IDLE,
+ APPCACHE_STATUS_CHECKING,
+ APPCACHE_STATUS_DOWNLOADING,
+ APPCACHE_STATUS_UPDATE_READY,
+ APPCACHE_STATUS_OBSOLETE,
+};
+
+struct AppCacheInfo {
+ url.mojom.Url manifest_url;
+ mojo.common.mojom.Time creation_time;
+ mojo.common.mojom.Time last_update_time;
+ mojo.common.mojom.Time last_access_time;
+ int64 cache_id;
+ int64 group_id;
+ AppCacheStatus status;
+ int64 size;
+ bool is_complete;
+};
diff --git a/chromium/content/public/common/associated_interface_provider.h b/chromium/content/public/common/associated_interface_provider.h
deleted file mode 100644
index 96b8c0254e8..00000000000
--- a/chromium/content/public/common/associated_interface_provider.h
+++ /dev/null
@@ -1,53 +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_ASSOCIATED_INTERFACE_PROVIDER_H_
-#define CONTENT_PUBLIC_COMMON_ASSOCIATED_INTERFACE_PROVIDER_H_
-
-#include <string>
-
-#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
-#include "mojo/public/cpp/bindings/associated_interface_request.h"
-#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
-
-namespace content {
-
-// A helper interface for connecting to remote Channel-associated interfaces.
-//
-// This is analogous to service_manager::InterfaceProvider in that it provides a
-// means of
-// binding proxies to remote interfaces, but this is specifically for interfaces
-// which must be assocaited with an IPC::Channel, i.e. retain FIFO message
-// ordering with respect to legacy IPC messages.
-//
-// The Channel with which the remote interfaces are associated depends on
-// the configuration of the specific AssociatedInterfaceProvider instance. For
-// example, RenderFrameHost exposes an instance of this class for which all
-// interfaces are associted with the IPC::ChannelProxy to the render process
-// which hosts its corresponding RenderFrame.
-class AssociatedInterfaceProvider {
- public:
- virtual ~AssociatedInterfaceProvider() {}
-
- // Passes an associated endpoint handle to the remote end to be bound to a
- // Channel-associated interface named |name|.
- virtual void GetInterface(const std::string& name,
- mojo::ScopedInterfaceEndpointHandle handle) = 0;
-
- // Templated helper for GetInterface().
- template <typename Interface>
- void GetInterface(mojo::AssociatedInterfacePtr<Interface>* proxy) {
- auto request = mojo::MakeRequest(proxy);
- GetInterface(Interface::Name_, request.PassHandle());
- }
-
- virtual void OverrideBinderForTesting(
- const std::string& name,
- const base::Callback<void(mojo::ScopedInterfaceEndpointHandle)>&
- binder) = 0;
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_ASSOCIATED_INTERFACE_PROVIDER_H_
diff --git a/chromium/content/public/common/associated_interface_registry.h b/chromium/content/public/common/associated_interface_registry.h
deleted file mode 100644
index 883438bb6c0..00000000000
--- a/chromium/content/public/common/associated_interface_registry.h
+++ /dev/null
@@ -1,62 +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_ASSOCIATED_INTERFACE_REGISTRY_H_
-#define CONTENT_PUBLIC_COMMON_ASSOCIATED_INTERFACE_REGISTRY_H_
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "mojo/public/cpp/bindings/associated_interface_request.h"
-#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
-
-namespace content {
-
-// An AssociatedInterfaceRegistry is a collection of associated interface-
-// binding callbacks mapped by interface name.
-//
-// This is used to register binding callbacks for interfaces which must be
-// associated with some IPC::ChannelProxy, meaning that messages on the
-// interface retain FIFO with respect to legacy Chrome IPC messages sent or
-// dispatched on the channel.
-//
-// The channel with which a registered interface is associated depends on the
-// configuration of the specific AssociatedInterfaceRegistry instance. For
-// example, RenderFrame exposes an instance of this class for which all
-// interfaces are associated with the IPC::SyncChannel to the browser.
-class AssociatedInterfaceRegistry {
- public:
- using Binder = base::Callback<void(mojo::ScopedInterfaceEndpointHandle)>;
-
- virtual ~AssociatedInterfaceRegistry() {}
-
- // Adds an interface binder to the registry.
- virtual void AddInterface(const std::string& name, const Binder& binder) = 0;
-
- // Removes an interface binder from the registry.
- virtual void RemoveInterface(const std::string& name) = 0;
-
- template <typename Interface>
- using InterfaceBinder =
- base::Callback<void(mojo::AssociatedInterfaceRequest<Interface>)>;
-
- // Templated helper for AddInterface() above.
- template <typename Interface>
- void AddInterface(const InterfaceBinder<Interface>& binder) {
- AddInterface(Interface::Name_,
- base::Bind(&BindInterface<Interface>, binder));
- }
-
- private:
- template <typename Interface>
- static void BindInterface(const InterfaceBinder<Interface>& binder,
- mojo::ScopedInterfaceEndpointHandle handle) {
- binder.Run(mojo::AssociatedInterfaceRequest<Interface>(std::move(handle)));
- }
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_ASSOCIATED_INTERFACE_REGISTRY_H_
diff --git a/chromium/content/public/common/bindings_policy.h b/chromium/content/public/common/bindings_policy.h
index f7b2f9258a5..08d1e4a312b 100644
--- a/chromium/content/public/common/bindings_policy.h
+++ b/chromium/content/public/common/bindings_policy.h
@@ -11,7 +11,13 @@ namespace content {
// to renderers.
enum BindingsPolicy {
// HTML-based UI bindings that allows the JS content to send JSON-encoded
- // data back to the browser process.
+ // data back to the browser process and to access Mojo system API and
+ // ServiceRegistry modules. The system API modules are defined in
+ // //mojo/public/js and provide the ability to create Mojo primitives such as
+ // message and data pipes. The Connector and InterfaceProvider modules (see
+ // //content/renderer/mojo) in turn allows these Mojo primitives to be used to
+ // connect to named services exposed by the browser. These bindings should not
+ // be exposed to normal web contents.
BINDINGS_POLICY_WEB_UI = 1 << 0,
// DOM automation bindings that allows the JS content to send JSON-encoded
// data back to automation in the parent process. (By default this isn't
@@ -22,16 +28,6 @@ enum BindingsPolicy {
// metrics. (By default this isn't allowed unless the app has been started up
// with the --enable-stats-collection-bindings switch.)
BINDINGS_POLICY_STATS_COLLECTION = 1 << 2,
- // Bindings that allows the JS content to access Mojo system API and
- // ServiceRegistry modules. The system API modules are defined in
- // //mojo/public/js and provide the ability to create Mojo primitives such as
- // message and data pipes. The ServiceRegistry module (see
- // //content/renderer/mojo/service_registry_js_wrapper.h) in turn allows these
- // Mojo primitives to be used to connect to named services exposed either by
- // the browser or testing code. These bindings should not be exposed to
- // normal web contents and are intended only for use with WebUI and layout
- // tests.
- BINDINGS_POLICY_MOJO = 1 << 3,
};
}
diff --git a/chromium/content/public/common/browser_side_navigation_policy.cc b/chromium/content/public/common/browser_side_navigation_policy.cc
index 106dbf7089e..9e16fac8dfe 100644
--- a/chromium/content/public/common/browser_side_navigation_policy.cc
+++ b/chromium/content/public/common/browser_side_navigation_policy.cc
@@ -37,4 +37,15 @@ bool IsBrowserSideNavigationEnabled() {
return base::FeatureList::IsEnabled(features::kBrowserSideNavigation);
}
+// Browser side navigation (aka PlzNavigate) is using blob URLs to deliver
+// the body of the main resource to the renderer process. When enabled, the
+// NavigationMojoResponse feature replaces this mechanism by a Mojo DataPipe.
+// Design doc: https://goo.gl/Rrrc7n.
+bool IsNavigationMojoResponseEnabled() {
+ if (!IsBrowserSideNavigationEnabled())
+ return false;
+
+ return base::FeatureList::IsEnabled(features::kNavigationMojoResponse);
+}
+
} // namespace content
diff --git a/chromium/content/public/common/browser_side_navigation_policy.h b/chromium/content/public/common/browser_side_navigation_policy.h
index 2c51587d3e0..8a2524a284e 100644
--- a/chromium/content/public/common/browser_side_navigation_policy.h
+++ b/chromium/content/public/common/browser_side_navigation_policy.h
@@ -9,12 +9,11 @@
// A centralized file for base helper methods and policy decisions about browser
// side navigation (aka PlzNavigate).
-// Note: For now this houses a single non-member method but we might change to
-// having an actual class if it should make more sense at some point.
namespace content {
CONTENT_EXPORT bool IsBrowserSideNavigationEnabled();
+CONTENT_EXPORT bool IsNavigationMojoResponseEnabled();
} // namespace content
diff --git a/chromium/content/public/common/common_param_traits_macros.h b/chromium/content/public/common/common_param_traits_macros.h
index 90951a5d5e5..63a73ad504d 100644
--- a/chromium/content/public/common/common_param_traits_macros.h
+++ b/chromium/content/public/common/common_param_traits_macros.h
@@ -11,13 +11,15 @@
#include "build/build_config.h"
#include "content/public/common/console_message_level.h"
#include "content/public/common/referrer.h"
+#include "content/public/common/resource_type.h"
#include "content/public/common/web_preferences.h"
-#include "content/public/common/webplugininfo.h"
+#include "content/public/common/webplugininfo_param_traits.h"
#include "ipc/ipc_message_macros.h"
#include "net/base/network_change_notifier.h"
#include "net/base/request_priority.h"
#include "net/http/http_request_headers.h"
#include "net/nqe/effective_connection_type.h"
+#include "third_party/WebKit/public/platform/WebHistoryScrollRestorationType.h"
#include "third_party/WebKit/public/platform/WebPoint.h"
#include "third_party/WebKit/public/platform/WebRect.h"
#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
@@ -53,6 +55,8 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFrameSerializerCacheControlPolicy,
blink::WebFrameSerializerCacheControlPolicy::kLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebReferrerPolicy,
blink::kWebReferrerPolicyLast)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebHistoryScrollRestorationType,
+ blink::kWebHistoryScrollRestorationManual)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebSecurityStyle, blink::kWebSecurityStyleLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::PermissionStatus,
blink::mojom::PermissionStatus::LAST)
@@ -61,6 +65,8 @@ IPC_ENUM_TRAITS_MAX_VALUE(content::EditingBehavior,
IPC_ENUM_TRAITS_MAX_VALUE(WindowOpenDisposition,
WindowOpenDisposition::MAX_VALUE)
IPC_ENUM_TRAITS_MAX_VALUE(net::RequestPriority, net::MAXIMUM_PRIORITY)
+IPC_ENUM_TRAITS_MAX_VALUE(content::ResourceType,
+ content::RESOURCE_TYPE_LAST_TYPE - 1)
IPC_ENUM_TRAITS_MAX_VALUE(content::V8CacheOptions,
content::V8_CACHE_OPTIONS_LAST)
#if defined(OS_ANDROID)
@@ -103,24 +109,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::Referrer)
IPC_STRUCT_TRAITS_MEMBER(policy)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(content::WebPluginMimeType)
- IPC_STRUCT_TRAITS_MEMBER(mime_type)
- IPC_STRUCT_TRAITS_MEMBER(file_extensions)
- IPC_STRUCT_TRAITS_MEMBER(description)
- IPC_STRUCT_TRAITS_MEMBER(additional_param_names)
- IPC_STRUCT_TRAITS_MEMBER(additional_param_values)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(content::WebPluginInfo)
- IPC_STRUCT_TRAITS_MEMBER(name)
- IPC_STRUCT_TRAITS_MEMBER(path)
- IPC_STRUCT_TRAITS_MEMBER(version)
- IPC_STRUCT_TRAITS_MEMBER(desc)
- IPC_STRUCT_TRAITS_MEMBER(mime_types)
- IPC_STRUCT_TRAITS_MEMBER(type)
- IPC_STRUCT_TRAITS_MEMBER(pepper_permissions)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
IPC_STRUCT_TRAITS_MEMBER(standard_font_family_map)
IPC_STRUCT_TRAITS_MEMBER(fixed_font_family_map)
@@ -139,7 +127,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
IPC_STRUCT_TRAITS_MEMBER(loads_images_automatically)
IPC_STRUCT_TRAITS_MEMBER(images_enabled)
IPC_STRUCT_TRAITS_MEMBER(plugins_enabled)
- IPC_STRUCT_TRAITS_MEMBER(encrypted_media_enabled)
IPC_STRUCT_TRAITS_MEMBER(dom_paste_enabled)
IPC_STRUCT_TRAITS_MEMBER(shrinks_standalone_images_to_fit)
IPC_STRUCT_TRAITS_MEMBER(text_areas_are_resizable)
diff --git a/chromium/content/public/common/common_sandbox_support_linux.h b/chromium/content/public/common/common_sandbox_support_linux.h
index b92d924b50a..dc63dd29deb 100644
--- a/chromium/content/public/common/common_sandbox_support_linux.h
+++ b/chromium/content/public/common/common_sandbox_support_linux.h
@@ -39,6 +39,10 @@ CONTENT_EXPORT bool GetFontTable(int fd,
CONTENT_EXPORT int MakeSharedMemorySegmentViaIPC(size_t length,
bool executable);
+// Gets the well-known file descriptor on which we expect to find the
+// sandbox IPC channel.
+CONTENT_EXPORT int GetSandboxFD();
+
}; // namespace content
#endif // CONTENT_PUBLIC_COMMON_COMMON_SANDBOX_SUPPORT_LINUX_H_
diff --git a/chromium/content/public/common/content_client.cc b/chromium/content/public/common/content_client.cc
index 790b4fcdd9a..3773438d01d 100644
--- a/chromium/content/public/common/content_client.cc
+++ b/chromium/content/public/common/content_client.cc
@@ -38,11 +38,6 @@ class InternalTestInitializer {
void SetContentClient(ContentClient* client) {
g_client = client;
-
- // TODO(jam): find out which static on Windows is causing this to have to be
- // called on startup.
- if (client)
- client->GetUserAgent();
}
ContentClient* GetContentClient() {
@@ -65,10 +60,7 @@ ContentClient::Schemes::Schemes() = default;
ContentClient::Schemes::~Schemes() = default;
ContentClient::ContentClient()
- : browser_(NULL),
- gpu_(NULL),
- renderer_(NULL),
- utility_(NULL) {}
+ : browser_(nullptr), gpu_(nullptr), renderer_(nullptr), utility_(nullptr) {}
ContentClient::~ContentClient() {
}
diff --git a/chromium/content/public/common/content_features.cc b/chromium/content/public/common/content_features.cc
index f11d51a320c..bb42f9817a1 100644
--- a/chromium/content/public/common/content_features.cc
+++ b/chromium/content/public/common/content_features.cc
@@ -26,7 +26,9 @@ const base::Feature kAllowContentInitiatedDataUrlNavigations{
const base::Feature kAsmJsToWebAssembly{"AsmJsToWebAssembly",
base::FEATURE_ENABLED_BY_DEFAULT};
-// Enables async wheel events.
+// Enables async wheel events. Note that this feature depends on
+// TouchpadAndWheelScrollLatching and enabling it when latching is disabled
+// won't have any impacts.
const base::Feature kAsyncWheelEvents{"AsyncWheelEvents",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -49,12 +51,12 @@ const base::Feature kBrotliEncoding{"brotli-encoding",
const base::Feature kBrowserSideNavigation{"browser-side-navigation",
base::FEATURE_ENABLED_BY_DEFAULT};
-// Toggles whether the buggy RSA parser is used.
-//
-// TODO(davidben): Remove this after Chrome 61 is released to
-// stable. https://crbug.com/735616.
-const base::Feature kBuggyRSAParser{"BuggyRSAParser",
- base::FEATURE_DISABLED_BY_DEFAULT};
+// Browser side navigation (aka PlzNavigate) is using blob URLs to deliver
+// the body of the main resource to the renderer process. When enabled, the
+// NavigationMojoResponse feature replaces this mechanism by a Mojo DataPipe.
+// Design doc: https://goo.gl/Rrrc7n.
+const base::Feature kNavigationMojoResponse{"NavigationMojoResponse",
+ base::FEATURE_DISABLED_BY_DEFAULT};
// If Canvas2D Image Chromium is allowed, this feature controls whether it is
// enabled.
@@ -148,14 +150,14 @@ const base::Feature kLazyParseCSS{"LazyParseCSS",
base::FEATURE_DISABLED_BY_DEFAULT};
// Use Mojo IPC for resource loading.
-const base::Feature kLoadingWithMojo {
- "LoadingWithMojo",
-#if defined(OS_ANDROID)
- base::FEATURE_DISABLED_BY_DEFAULT
-#else
- base::FEATURE_ENABLED_BY_DEFAULT
-#endif
-};
+const base::Feature kLoadingWithMojo{"LoadingWithMojo",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
+// If this feature is enabled, media-device enumerations use a cache that is
+// invalidated upon notifications sent by base::SystemMonitor. If disabled, the
+// cache is considered invalid on every enumeration request.
+const base::Feature kMediaDevicesSystemMonitorCache{
+ "MediaDevicesSystemMonitorCaching", base::FEATURE_DISABLED_BY_DEFAULT};
// Enables the memory coordinator.
// WARNING:
@@ -178,24 +180,32 @@ const base::Feature kMainThreadBusyScrollIntervention{
"MainThreadBusyScrollIntervention", base::FEATURE_DISABLED_BY_DEFAULT};
// Blob mojofication.
-const base::Feature kMojoBlobs{"MojoBlobs", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kMojoBlobs{"MojoBlobs", base::FEATURE_ENABLED_BY_DEFAULT};
// Mojo-based Input Event routing.
const base::Feature kMojoInputMessages{"MojoInputMessages",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Mojo-based Session Storage.
+const base::Feature kMojoSessionStorage{"MojoSessionStorage",
+ base::FEATURE_DISABLED_BY_DEFAULT};
// Enables/disables hardware video encode acceleration using Mojo (falls back).
const base::Feature kMojoVideoEncodeAccelerator{
"MojoVideoEncodeAccelerator", base::FEATURE_ENABLED_BY_DEFAULT};
-// ES6 Modules.
-const base::Feature kModuleScripts{"ModuleScripts",
- base::FEATURE_ENABLED_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};
+
+// Use Mojo IPC for notifications.
+const base::Feature kNotificationsWithMojo{"NotificationsWithMojo",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Resource fetch optimizations for workers. See crbug.com/443374
const base::Feature kOffMainThreadFetch{"OffMainThreadFetch",
base::FEATURE_ENABLED_BY_DEFAULT};
@@ -239,14 +249,6 @@ const base::Feature kPurgeAndSuspend {
#endif
};
-// RAF aligned mouse input events support.
-const base::Feature kRafAlignedMouseInputEvents{
- "RafAlignedMouseInput", base::FEATURE_ENABLED_BY_DEFAULT};
-
-// RAF aligned touch input events support.
-const base::Feature kRafAlignedTouchInputEvents{
- "RafAlignedTouchInput", base::FEATURE_ENABLED_BY_DEFAULT};
-
// If Pepper 3D Image Chromium is allowed, this feature controls whether it is
// enabled.
const base::Feature kPepper3DImageChromium {
@@ -258,6 +260,14 @@ const base::Feature kPepper3DImageChromium {
#endif
};
+// Generate V8 full code cache for PWAs.
+const base::Feature kPWAFullCodeCache{"PWAFullCodeCache",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Port some content::ResourceScheduler functionalities to renderer.
+const base::Feature kRendererSideResourceScheduler{
+ "RendererSideResourceSchduler", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Throttle Blink's rendering pipeline based on frame visibility.
const base::Feature kRenderingPipelineThrottling{
"RenderingPipelineThrottling", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -266,6 +276,10 @@ const base::Feature kRenderingPipelineThrottling{
const base::Feature kReportRendererPeakMemoryStats{
"ReportRendererPeakMemoryStats", base::FEATURE_DISABLED_BY_DEFAULT};
+// When loading CSS from a 'file:' URL, require a CSS-like file extension.
+const base::Feature kRequireCSSExtensionForFile{
+ "RequireCSSExtensionForFile", base::FEATURE_ENABLED_BY_DEFAULT};
+
// Loading Dispatcher v0 support with ResourceLoadScheduler (crbug.com/729954).
const base::Feature kResourceLoadScheduler{"ResourceLoadScheduler",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -286,11 +300,15 @@ const base::Feature kServiceWorkerPaymentApps{
// Streaming installed scripts on starting service workers.
const base::Feature kServiceWorkerScriptStreaming{
- "ServiceWorkerScriptStreaming", base::FEATURE_DISABLED_BY_DEFAULT};
+ "ServiceWorkerScriptStreaming", base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Generate V8 full code cache of service worker scripts.
+const base::Feature kServiceWorkerScriptFullCodeCache{
+ "ServiceWorkerScriptFullCodeCache", base::FEATURE_DISABLED_BY_DEFAULT};
// http://tc39.github.io/ecmascript_sharedmem/shmem.html
const base::Feature kSharedArrayBuffer{"SharedArrayBuffer",
- base::FEATURE_ENABLED_BY_DEFAULT};
+ base::FEATURE_DISABLED_BY_DEFAULT};
// An experiment to require process isolation for the sign-in origin,
// https://accounts.google.com. Launch bug: https://crbug.com/739418.
@@ -302,18 +320,25 @@ const base::Feature kSignInProcessIsolation{"sign-in-process-isolation",
const base::Feature kSitePerProcess{"site-per-process",
base::FEATURE_DISABLED_BY_DEFAULT};
-// An experiment for skipping compositing small scrollers.
-const base::Feature kSkipCompositingSmallScrollers{
- "SkipCompositingSmallScrollers", base::FEATURE_DISABLED_BY_DEFAULT};
-
// Paint invalidation based on slimming paint. See https://goo.gl/eQczQW
const base::Feature kSlimmingPaintInvalidation{
"SlimmingPaintInvalidation", base::FEATURE_ENABLED_BY_DEFAULT};
+// Stop loading tasks and loading of resources in background, on Android,
+// after allowed grace time. Launch bug: https://crbug.com/775761.
+const base::Feature kStopLoadingInBackground{"stop-loading-in-background",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Throttle Blink timers in out-of-view cross origin frames.
const base::Feature kTimerThrottlingForHiddenFrames{
"TimerThrottlingForHiddenFrames", 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
+// today.
+const base::Feature kUserActivationV2{"UserActivationV2",
+ base::FEATURE_DISABLED_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.
@@ -329,10 +354,13 @@ const base::Feature kTurnOff2DAndOpacityCompositorAnimations{
"TurnOff2DAndOpacityCompositorAnimations",
base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kEnablePreventLayerSquashing{
+ "EnablePreventLayerSquashing", base::FEATURE_ENABLED_BY_DEFAULT};
+
// Use Feature Policy to gate the use of permission features like midi,
// geolocation, camera, microphone, etc.
const base::Feature kUseFeaturePolicyForPermissions{
- "UseFeaturePolicyForPermissions", base::FEATURE_DISABLED_BY_DEFAULT};
+ "UseFeaturePolicyForPermissions", base::FEATURE_ENABLED_BY_DEFAULT};
// Use MojoAudioOutputIPC and RenderFrameAudioOutputStreamFactory rather than
// AudioMessageFilter and AudioRendererHost.
@@ -343,16 +371,6 @@ const base::Feature kUseMojoAudioOutputStreamFactory{
const base::Feature kVibrateRequiresUserGesture{
"VibrateRequiresUserGesture", base::FEATURE_ENABLED_BY_DEFAULT};
-// Enables VR UI.
-const base::Feature kVrShell {
- "VrShell",
-#if defined(OS_ANDROID)
- base::FEATURE_ENABLED_BY_DEFAULT
-#else
- base::FEATURE_DISABLED_BY_DEFAULT
-#endif
-};
-
// Enable WebAssembly structured cloning.
// http://webassembly.org/
const base::Feature kWebAssembly{"WebAssembly",
@@ -433,10 +451,18 @@ const char kIsolateOriginsFieldTrialParamName[] = "OriginsList";
const base::Feature kKeepAliveRendererForKeepaliveRequests{
"KeepAliveRendererForKeepaliveRequests", base::FEATURE_ENABLED_BY_DEFAULT};
-// Enables WebVR experimental rendering optimizations.
-const base::Feature kWebVRExperimentalRendering{
+// Controls whether WebVR experimental rendering optimizations is enabled.
+const base::Feature kWebVrExperimentalRendering{
"WebVRExperimentalRendering", base::FEATURE_DISABLED_BY_DEFAULT};
+// Controls whether WebVR VSync-aligned render loop timing is enabled.
+const base::Feature kWebVrVsyncAlign{"WebVrVsyncAlign",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Enabled "work stealing" in the script runner.
+const base::Feature kWorkStealingInScriptRunner{
+ "WorkStealingInScriptRunner", base::FEATURE_DISABLED_BY_DEFAULT};
+
#if defined(OS_ANDROID)
// Autofill Accessibility in Android.
// crbug.com/627860
@@ -450,24 +476,8 @@ const base::Feature kHideIncorrectlySizedFullscreenFrames{
// Controls whether the WebNFC API is enabled:
// https://w3c.github.io/web-nfc/
const base::Feature kWebNfc{"WebNFC", base::FEATURE_DISABLED_BY_DEFAULT};
-
-// Enables WebVR VSync-aligned render loop timing.
-const base::Feature kWebVrVsyncAlign{"WebVrVsyncAlign",
- base::FEATURE_ENABLED_BY_DEFAULT};
#endif // defined(OS_ANDROID)
-#if defined(OS_WIN)
-// Emergency "off switch" for new Windows sandbox security mitigation,
-// sandbox::MITIGATION_EXTENSION_POINT_DISABLE.
-const base::Feature kWinSboxDisableExtensionPoints{
- "WinSboxDisableExtensionPoint", base::FEATURE_ENABLED_BY_DEFAULT};
-
-// Emergency "off switch" for new Windows sandbox security mitigation,
-// sandbox::MITIGATION_FORCE_MS_SIGNED_BINS.
-const base::Feature kWinSboxForceMsSigned{"WinSboxForceMsSigned",
- base::FEATURE_ENABLED_BY_DEFAULT};
-#endif // defined(OS_WIN)
-
#if defined(OS_MACOSX)
// Enables caching of media devices for the purpose of enumerating them.
const base::Feature kDeviceMonitorMac{"DeviceMonitorMac",
@@ -483,6 +493,10 @@ const base::Feature kMacV2Sandbox{"MacV2Sandbox",
const base::Feature kV8ContextSnapshot{"V8ContextSnapshot",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Enables future V8 VM features
+const base::Feature kV8VmFuture{"V8VmFuture",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
bool IsMojoBlobsEnabled() {
return base::FeatureList::IsEnabled(features::kMojoBlobs) ||
base::FeatureList::IsEnabled(features::kNetworkService);
diff --git a/chromium/content/public/common/content_features.h b/chromium/content/public/common/content_features.h
index a72f19f4a06..bea95725346 100644
--- a/chromium/content/public/common/content_features.h
+++ b/chromium/content/public/common/content_features.h
@@ -25,7 +25,7 @@ CONTENT_EXPORT extern const base::Feature kBlockCredentialedSubresources;
CONTENT_EXPORT extern const base::Feature kDataSaverHoldback;
CONTENT_EXPORT extern const base::Feature kBrotliEncoding;
CONTENT_EXPORT extern const base::Feature kBrowserSideNavigation;
-CONTENT_EXPORT extern const base::Feature kBuggyRSAParser;
+CONTENT_EXPORT extern const base::Feature kNavigationMojoResponse;
CONTENT_EXPORT extern const base::Feature kCanvas2DImageChromium;
CONTENT_EXPORT extern const base::Feature kCheckerImaging;
CONTENT_EXPORT extern const base::Feature kCompositeOpaqueFixedPosition;
@@ -51,15 +51,18 @@ CONTENT_EXPORT extern const base::Feature
CONTENT_EXPORT extern const base::Feature kLazyInitializeMediaControls;
CONTENT_EXPORT extern const base::Feature kLazyParseCSS;
CONTENT_EXPORT extern const base::Feature kLoadingWithMojo;
+CONTENT_EXPORT extern const base::Feature kMediaDevicesSystemMonitorCache;
CONTENT_EXPORT extern const base::Feature kMemoryCoordinator;
CONTENT_EXPORT extern const base::Feature kNetworkService;
CONTENT_EXPORT extern const base::Feature kNotificationContentImage;
CONTENT_EXPORT extern const base::Feature kMainThreadBusyScrollIntervention;
CONTENT_EXPORT extern const base::Feature kMojoBlobs;
CONTENT_EXPORT extern const base::Feature kMojoInputMessages;
+CONTENT_EXPORT extern const base::Feature kMojoSessionStorage;
CONTENT_EXPORT extern const base::Feature kMojoVideoEncodeAccelerator;
-CONTENT_EXPORT extern const base::Feature kModuleScripts;
CONTENT_EXPORT extern const base::Feature kModuleScriptsDynamicImport;
+CONTENT_EXPORT extern const base::Feature kModuleScriptsImportMetaUrl;
+CONTENT_EXPORT extern const base::Feature kNotificationsWithMojo;
CONTENT_EXPORT extern const base::Feature kOffMainThreadFetch;
CONTENT_EXPORT extern const base::Feature kOriginManifest;
CONTENT_EXPORT extern const base::Feature kOriginTrials;
@@ -69,31 +72,35 @@ CONTENT_EXPORT extern const base::Feature kPassiveDocumentEventListeners;
CONTENT_EXPORT extern const base::Feature kPassiveEventListenersDueToFling;
CONTENT_EXPORT extern const base::Feature kPepper3DImageChromium;
CONTENT_EXPORT extern const base::Feature kPurgeAndSuspend;
-CONTENT_EXPORT extern const base::Feature kRafAlignedMouseInputEvents;
-CONTENT_EXPORT extern const base::Feature kRafAlignedTouchInputEvents;
+CONTENT_EXPORT extern const base::Feature kPWAFullCodeCache;
+CONTENT_EXPORT extern const base::Feature kRendererSideResourceScheduler;
CONTENT_EXPORT extern const base::Feature kRenderingPipelineThrottling;
CONTENT_EXPORT extern const base::Feature kReportRendererPeakMemoryStats;
+CONTENT_EXPORT extern const base::Feature kRequireCSSExtensionForFile;
CONTENT_EXPORT extern const base::Feature kResourceLoadScheduler;
CONTENT_EXPORT extern const base::Feature kScrollAnchoring;
CONTENT_EXPORT
extern const base::Feature kSendBeaconThrowForBlobWithNonSimpleType;
CONTENT_EXPORT extern const base::Feature kServiceWorkerPaymentApps;
CONTENT_EXPORT extern const base::Feature kServiceWorkerScriptStreaming;
+CONTENT_EXPORT extern const base::Feature kServiceWorkerScriptFullCodeCache;
CONTENT_EXPORT extern const base::Feature kSharedArrayBuffer;
CONTENT_EXPORT extern const base::Feature kSignInProcessIsolation;
CONTENT_EXPORT extern const base::Feature kSitePerProcess;
-CONTENT_EXPORT extern const base::Feature kSkipCompositingSmallScrollers;
CONTENT_EXPORT extern const base::Feature kSlimmingPaintInvalidation;
+CONTENT_EXPORT extern const base::Feature kStopLoadingInBackground;
CONTENT_EXPORT extern const base::Feature kTimerThrottlingForHiddenFrames;
CONTENT_EXPORT extern const base::Feature kTopDocumentIsolation;
CONTENT_EXPORT extern const base::Feature kTouchpadAndWheelScrollLatching;
CONTENT_EXPORT extern const base::Feature
kTurnOff2DAndOpacityCompositorAnimations;
+CONTENT_EXPORT extern const base::Feature kEnablePreventLayerSquashing;
CONTENT_EXPORT extern const base::Feature kUseFeaturePolicyForPermissions;
CONTENT_EXPORT extern const base::Feature kUseMojoAudioOutputStreamFactory;
+CONTENT_EXPORT extern const base::Feature kUserActivationV2;
CONTENT_EXPORT extern const base::Feature kV8ContextSnapshot;
+CONTENT_EXPORT extern const base::Feature kV8VmFuture;
CONTENT_EXPORT extern const base::Feature kVibrateRequiresUserGesture;
-CONTENT_EXPORT extern const base::Feature kVrShell;
CONTENT_EXPORT extern const base::Feature kWebAssembly;
CONTENT_EXPORT extern const base::Feature kWebAssemblyStreaming;
CONTENT_EXPORT extern const base::Feature kWebAssemblyTrapHandler;
@@ -107,21 +114,17 @@ CONTENT_EXPORT extern const base::Feature kWebRtcScreenshareSwEncoding;
CONTENT_EXPORT extern const base::Feature kWebRtcUseEchoCanceller3;
CONTENT_EXPORT extern const base::Feature kWebRtcUseGpuMemoryBufferVideoFrames;
CONTENT_EXPORT extern const base::Feature kWebUsb;
-CONTENT_EXPORT extern const base::Feature kWebVRExperimentalRendering;
+CONTENT_EXPORT extern const base::Feature kWebVrExperimentalRendering;
+CONTENT_EXPORT extern const base::Feature kWebVrVsyncAlign;
+CONTENT_EXPORT extern const base::Feature kWorkStealingInScriptRunner;
#if defined(OS_ANDROID)
CONTENT_EXPORT extern const base::Feature kAndroidAutofillAccessibility;
CONTENT_EXPORT extern const base::Feature kHideIncorrectlySizedFullscreenFrames;
CONTENT_EXPORT extern const base::Feature kImeThread;
CONTENT_EXPORT extern const base::Feature kWebNfc;
-CONTENT_EXPORT extern const base::Feature kWebVrVsyncAlign;
#endif // defined(OS_ANDROID)
-#if defined(OS_WIN)
-CONTENT_EXPORT extern const base::Feature kWinSboxDisableExtensionPoints;
-CONTENT_EXPORT extern const base::Feature kWinSboxForceMsSigned;
-#endif // defined(OS_WIN)
-
#if defined(OS_MACOSX)
CONTENT_EXPORT extern const base::Feature kDeviceMonitorMac;
CONTENT_EXPORT extern const base::Feature kMacV2Sandbox;
diff --git a/chromium/content/public/common/content_switches.cc b/chromium/content/public/common/content_switches.cc
index 4e699d1c319..05368394d10 100644
--- a/chromium/content/public/common/content_switches.cc
+++ b/chromium/content/public/common/content_switches.cc
@@ -40,17 +40,6 @@ const char kAllowInsecureLocalhost[] = "allow-insecure-localhost";
const char kAllowLoopbackInPeerConnection[] =
"allow-loopback-in-peer-connection";
-// Enables the sandboxed processes to run without a job object assigned to them.
-// This flag is required to allow Chrome to run in RemoteApps or Citrix. This
-// flag can reduce the security of the sandboxed processes and allow them to do
-// certain API calls like shut down Windows or access the clipboard. Also we
-// lose the chance to kill some processes until the outer job that owns them
-// finishes.
-const char kAllowNoSandboxJob[] = "allow-no-sandbox-job";
-
-// Allows debugging of sandboxed processes (see zygote_main_linux.cc).
-const char kAllowSandboxDebugging[] = "allow-sandbox-debugging";
-
// Uses the android SkFontManager on linux. The specified directory should
// include the configuration xml file with the name "fonts.xml".
// This is used in blimp to emulate android fonts on linux.
@@ -105,7 +94,7 @@ const char kDisableBackingStoreLimit[] = "disable-backing-store-limit";
// Disable backgrounding renders for occluded windows. Done for tests to avoid
// nondeterministic behavior.
-extern const char kDisableBackgroundingOccludedWindowsForTesting[] =
+const char kDisableBackgroundingOccludedWindowsForTesting[] =
"disable-backgrounding-occluded-windows";
// Disable task throttling of timer tasks from background pages.
@@ -132,9 +121,6 @@ const char kDisableWebGL[] = "disable-webgl";
// Disable WebGL2.
const char kDisableWebGL2[] = "disable-webgl2";
-// Comma-separated list of feature names to disable. See also kEnableFeatures.
-const char kDisableFeatures[] = "disable-features";
-
// Disable FileSystem API.
const char kDisableFileSystem[] = "disable-file-system";
@@ -169,8 +155,8 @@ const char kDisableGpuMemoryBufferCompositorResources[] =
const char kDisableGpuMemoryBufferVideoFrames[] =
"disable-gpu-memory-buffer-video-frames";
-// Disable the limit on the number of times the GPU process may be restarted.
-// For tests and platforms where software fallback is disabled.
+// For tests, to disable the limit on the number of times the GPU process may be
+// restarted.
const char kDisableGpuProcessCrashLimit[] = "disable-gpu-process-crash-limit";
// When using CPU rasterizing disable low resolution tiling. This uses
@@ -181,6 +167,10 @@ const char kDisableLowResTiling[] = "disable-low-res-tiling";
// Disable the GPU process sandbox.
const char kDisableGpuSandbox[] = "disable-gpu-sandbox";
+// Disable the thread that crashes the GPU process if it stops responding to
+// messages.
+const char kDisableGpuWatchdog[] = "disable-gpu-watchdog";
+
// Suppresses hang monitor dialogs in renderer processes. This may allow slow
// unload handlers on a page to prevent the tab from closing, but the Task
// Manager can be used to terminate the offending process in this case.
@@ -216,6 +206,11 @@ const char kDisableMojoLocalStorage[] = "disable-mojo-local-storage";
// Disables usage of the namespace sandbox.
const char kDisableNamespaceSandbox[] = "disable-namespace-sandbox";
+// Disables clearing the rendering output of a renderer when it didn't commit
+// new output for a while after a top-frame navigation.
+const char kDisableNewContentRenderingTimeout[] =
+ "disable-new-content-rendering-timeout";
+
// Disables the Web Notification and the Push APIs.
const char kDisableNotifications[] = "disable-notifications";
@@ -268,11 +263,9 @@ const char kDisableRendererBackgrounding[] = "disable-renderer-backgrounding";
// useful for tests that want to force disabling.
const char kDisableResizeLock[] = "disable-resize-lock";
-// Disable the seccomp filter sandbox (seccomp-bpf) (Linux only).
-const char kDisableSeccompFilterSandbox[] = "disable-seccomp-filter-sandbox";
-
-// Disable the setuid sandbox (Linux only).
-const char kDisableSetuidSandbox[] = "disable-setuid-sandbox";
+// Whether the ResourceScheduler is disabled. Note this is only useful for C++
+// Headless embedders who need to implement their own resource scheduling.
+const char kDisableResourceScheduler[] = "disable-resource-scheduler";
// Disable shared workers.
const char kDisableSharedWorkers[] = "disable-shared-workers";
@@ -382,9 +375,6 @@ const char kEnableExperimentalWebPlatformFeatures[] =
const char kDisableOriginTrialControlledBlinkFeatures[] =
"disable-origin-trial-controlled-blink-features";
-// Comma-separated list of feature names to enable. See also kDisableFeatures.
-const char kEnableFeatures[] = "enable-features";
-
// Makes the GL worker context run asynchronously by using a separate stream.
const char kEnableGpuAsyncWorkerContext[] = "enable-gpu-async-worker-context";
@@ -435,10 +425,6 @@ const char kEnableRGBA4444Textures[] = "enable-rgba-4444-textures";
// Set options to cache V8 data. (off, preparse data, or code)
const char kV8CacheOptions[] = "v8-cache-options";
-// Set strategies to cache V8 data in CacheStorage. (off, normal, or aggressive)
-const char kV8CacheStrategiesForCacheStorage[] =
- "v8-cache-strategies-for-cache-storage";
-
// Cause the OS X sandbox write to syslog every time an access to a resource
// is denied by the sandbox.
const char kEnableSandboxLogging[] = "enable-sandbox-logging";
@@ -559,11 +545,8 @@ const char kGpuLauncher[] = "gpu-launcher";
// Makes this process a GPU sub-process.
const char kGpuProcess[] = "gpu-process";
-// Allows shmat() system call in the GPU sandbox.
-const char kGpuSandboxAllowSysVShm[] = "gpu-sandbox-allow-sysv-shm";
-
-// Makes GPU sandbox failures fatal.
-const char kGpuSandboxFailuresFatal[] = "gpu-sandbox-failures-fatal";
+// Starts the GPU sandbox before creating a GL context.
+const char kGpuSandboxStartEarly[] = "gpu-sandbox-start-early";
// Causes the GPU process to display a dialog on launch.
const char kGpuStartupDialog[] = "gpu-startup-dialog";
@@ -602,9 +585,6 @@ const char kIPCConnectionTimeout[] = "ipc-connection-timeout";
// --isolate-origins=https://www.foo.com,https://www.bar.com
const char kIsolateOrigins[] = "isolate-origins";
-// Chrome is running in Mash.
-const char kIsRunningInMash[] = "is-running-in-mash";
-
// Disable latest shipping ECMAScript 6 features.
const char kDisableJavaScriptHarmonyShipping[] =
"disable-javascript-harmony-shipping";
@@ -623,11 +603,12 @@ const char kLogGpuControlListDecisions[] = "log-gpu-control-list-decisions";
const char kLoggingLevel[] = "log-level";
// Overrides the default file name to use for general-purpose logging (does not
-// affect which events are logged). Currently supported only in app_shell.
-// TODO(crbug.com/760431): Make this work in chrome and content_shell too.
+// affect which events are logged).
const char kLogFile[] = "log-file";
-// Enables saving net log events to a file and sets the file name to use.
+// Enables saving net log events to a file. If a value is given, it used as the
+// path the the file, otherwise the file is named netlog.json and placed in the
+// user data directory.
const char kLogNetLog[] = "log-net-log";
// Resizes of the main frame are caused by changing between landscape and
@@ -668,10 +649,6 @@ const char kNoSandbox[] = "no-sandbox";
// zygote to work.
const char kNoZygote[] = "no-zygote";
-// Enable or disable appcontainer/lowbox for renderer on Win8+ platforms.
-const char kEnableAppContainer[] = "enable-appcontainer";
-const char kDisableAppContainer[] = "disable-appcontainer";
-
// Number of worker threads used to rasterize content.
const char kNumRasterThreads[] = "num-raster-threads";
@@ -767,13 +744,12 @@ const char kProxyServer[] = "proxy-server";
// Defaults to disabled.
const char kPullToRefresh[] = "pull-to-refresh";
-// Enables more web features over insecure connections. Designed to be used
-// for testing purposes only.
-const char kReduceSecurityForTesting[] = "reduce-security-for-testing";
-
// Register Pepper plugins (see pepper_plugin_list.cc for its format).
const char kRegisterPepperPlugins[] = "register-pepper-plugins";
+// Enables remote debug over stdio pipes [in=3, out=4].
+const char kRemoteDebuggingPipe[] = "remote-debugging-pipe";
+
// Enables remote debug over HTTP on the specified port.
const char kRemoteDebuggingPort[] = "remote-debugging-port";
@@ -881,9 +857,6 @@ const char kTouchEventFeatureDetectionDisabled[] = "disabled";
// the platform default is used.
const char kTouchTextSelectionStrategy[] = "touch-selection-strategy";
-// Prioritizes the UI's command stream in the GPU process
-const char kUIPrioritizeInGpuProcess[] = "ui-prioritize-in-gpu-process";
-
// Bypass the media stream infobar by selecting the default device for media
// streams (e.g. WebRTC). Works with --use-fake-device-for-media-stream.
const char kUseFakeUIForMediaStream[] = "use-fake-ui-for-media-stream";
@@ -908,8 +881,6 @@ const char kUtilityProcess[] = "utility";
// This flag specifies the directory that can be accessed.
const char kUtilityProcessAllowedDir[] = "utility-allowed-dir";
-const char kUtilityProcessRunningElevated[] = "utility-run-elevated";
-
// Causes the utility process to display a dialog on launch.
const char kUtilityStartupDialog[] = "utility-startup-dialog";
@@ -1071,9 +1042,6 @@ const char kDeviceScaleFactor[] = "device-scale-factor";
// Disable the Legacy Window which corresponds to the size of the WebContents.
const char kDisableLegacyIntermediateWindow[] = "disable-legacy-window";
-// Disables the Win32K process mitigation policy for child processes.
-const char kDisableWin32kLockDown[] = "disable-win32k-lockdown";
-
// Enables experimental hardware acceleration for VP8/VP9 video decoding.
// Bitmask - 0x1=Microsoft, 0x2=AMD, 0x03=Try all.
const char kEnableAcceleratedVpxDecode[] = "enable-accelerated-vpx-decode";
diff --git a/chromium/content/public/common/content_switches.h b/chromium/content/public/common/content_switches.h
index 27049240d42..3c277af8358 100644
--- a/chromium/content/public/common/content_switches.h
+++ b/chromium/content/public/common/content_switches.h
@@ -21,8 +21,6 @@ CONTENT_EXPORT extern const char kAgcStartupMinVolume[];
CONTENT_EXPORT extern const char kAllowFileAccessFromFiles[];
CONTENT_EXPORT extern const char kAllowInsecureLocalhost[];
CONTENT_EXPORT extern const char kAllowLoopbackInPeerConnection[];
-CONTENT_EXPORT extern const char kAllowNoSandboxJob[];
-CONTENT_EXPORT extern const char kAllowSandboxDebugging[];
CONTENT_EXPORT extern const char kAndroidFontsPath[];
CONTENT_EXPORT extern const char kBlinkSettings[];
CONTENT_EXPORT extern const char kBrowserCrashTest[];
@@ -50,7 +48,6 @@ CONTENT_EXPORT extern const char kDisableDisplayList2dCanvas[];
extern const char kDisableDomainBlockingFor3DAPIs[];
CONTENT_EXPORT extern const char kDisableWebGL[];
CONTENT_EXPORT extern const char kDisableWebGL2[];
-CONTENT_EXPORT extern const char kDisableFeatures[];
CONTENT_EXPORT extern const char kDisableFileSystem[];
CONTENT_EXPORT extern const char kDisableFlash3d[];
CONTENT_EXPORT extern const char kDisableFlashStage3d[];
@@ -63,6 +60,7 @@ CONTENT_EXPORT extern const char kDisableGpuMemoryBufferCompositorResources[];
CONTENT_EXPORT extern const char kDisableGpuMemoryBufferVideoFrames[];
extern const char kDisableGpuProcessCrashLimit[];
CONTENT_EXPORT extern const char kDisableGpuSandbox[];
+CONTENT_EXPORT extern const char kDisableGpuWatchdog[];
CONTENT_EXPORT extern const char kDisableJavaScriptHarmonyShipping[];
CONTENT_EXPORT extern const char kDisableLowLatencyDxva[];
CONTENT_EXPORT extern const char kDisableLowResTiling[];
@@ -75,6 +73,7 @@ CONTENT_EXPORT extern const char kDisableLocalStorage[];
CONTENT_EXPORT extern const char kDisableLogging[];
CONTENT_EXPORT extern const char kDisableMojoLocalStorage[];
CONTENT_EXPORT extern const char kDisableNamespaceSandbox[];
+CONTENT_EXPORT extern const char kDisableNewContentRenderingTimeout[];
CONTENT_EXPORT extern const char kDisableNotifications[];
CONTENT_EXPORT extern const char kDisableOriginTrialControlledBlinkFeatures[];
CONTENT_EXPORT extern const char kDisablePartialRaster[];
@@ -91,8 +90,7 @@ CONTENT_EXPORT extern const char kDisableRemotePlaybackAPI[];
extern const char kDisableRendererAccessibility[];
CONTENT_EXPORT extern const char kDisableRendererBackgrounding[];
CONTENT_EXPORT extern const char kDisableResizeLock[];
-CONTENT_EXPORT extern const char kDisableSeccompFilterSandbox[];
-CONTENT_EXPORT extern const char kDisableSetuidSandbox[];
+CONTENT_EXPORT extern const char kDisableResourceScheduler[];
CONTENT_EXPORT extern const char kDisableSharedWorkers[];
CONTENT_EXPORT extern const char kDisableSkiaRuntimeOpts[];
CONTENT_EXPORT extern const char kDisableSmoothScrolling[];
@@ -120,7 +118,6 @@ CONTENT_EXPORT extern const char kEnableDisplayList2dCanvas[];
CONTENT_EXPORT extern const char kEnableDistanceFieldText[];
CONTENT_EXPORT extern const char kEnableExperimentalCanvasFeatures[];
CONTENT_EXPORT extern const char kEnableExperimentalWebPlatformFeatures[];
-CONTENT_EXPORT extern const char kEnableFeatures[];
CONTENT_EXPORT extern const char kEnableGpuAsyncWorkerContext[];
CONTENT_EXPORT extern const char kEnableGpuMemoryBufferCompositorResources[];
CONTENT_EXPORT extern const char kEnableGpuMemoryBufferVideoFrames[];
@@ -166,8 +163,7 @@ CONTENT_EXPORT extern const char kForceRendererAccessibility[];
CONTENT_EXPORT extern const char kGenerateAccessibilityTestExpectations[];
extern const char kGpuLauncher[];
CONTENT_EXPORT extern const char kGpuProcess[];
-CONTENT_EXPORT extern const char kGpuSandboxAllowSysVShm[];
-CONTENT_EXPORT extern const char kGpuSandboxFailuresFatal[];
+CONTENT_EXPORT extern const char kGpuSandboxStartEarly[];
CONTENT_EXPORT extern const char kGpuStartupDialog[];
CONTENT_EXPORT extern const char kHistoryEntryRequiresUserGesture[];
CONTENT_EXPORT extern const char kHostResolverRules[];
@@ -175,7 +171,6 @@ CONTENT_EXPORT extern const char kIgnoreCertificateErrorsSPKIList[];
CONTENT_EXPORT extern const char kInProcessGPU[];
CONTENT_EXPORT extern const char kIPCConnectionTimeout[];
CONTENT_EXPORT extern const char kIsolateOrigins[];
-CONTENT_EXPORT extern const char kIsRunningInMash[];
CONTENT_EXPORT extern const char kJavaScriptFlags[];
CONTENT_EXPORT extern const char kJavaScriptHarmony[];
CONTENT_EXPORT extern const char kLogGpuControlListDecisions[];
@@ -212,9 +207,9 @@ CONTENT_EXPORT extern const char kProcessPerTab[];
CONTENT_EXPORT extern const char kProcessType[];
CONTENT_EXPORT extern const char kProxyServer[];
CONTENT_EXPORT extern const char kPullToRefresh[];
-CONTENT_EXPORT extern const char kReduceSecurityForTesting[];
CONTENT_EXPORT extern const char kReducedReferrerGranularity[];
CONTENT_EXPORT extern const char kRegisterPepperPlugins[];
+CONTENT_EXPORT extern const char kRemoteDebuggingPipe[];
CONTENT_EXPORT extern const char kRemoteDebuggingPort[];
CONTENT_EXPORT extern const char kRendererClientId[];
extern const char kRendererCmdPrefix[];
@@ -237,7 +232,6 @@ CONTENT_EXPORT extern const char kTouchEventFeatureDetectionAuto[];
CONTENT_EXPORT extern const char kTouchEventFeatureDetectionEnabled[];
CONTENT_EXPORT extern const char kTouchEventFeatureDetectionDisabled[];
CONTENT_EXPORT extern const char kTouchTextSelectionStrategy[];
-CONTENT_EXPORT extern const char kUIPrioritizeInGpuProcess[];
CONTENT_EXPORT extern const char kUseFakeUIForMediaStream[];
CONTENT_EXPORT extern const char kContentImageTextureTarget[];
CONTENT_EXPORT extern const char kVideoImageTextureTarget[];
@@ -245,10 +239,8 @@ CONTENT_EXPORT extern const char kUseMobileUserAgent[];
extern const char kUtilityCmdPrefix[];
CONTENT_EXPORT extern const char kUtilityProcess[];
extern const char kUtilityProcessAllowedDir[];
-CONTENT_EXPORT extern const char kUtilityProcessRunningElevated[];
CONTENT_EXPORT extern const char kUtilityStartupDialog[];
CONTENT_EXPORT extern const char kV8CacheOptions[];
-CONTENT_EXPORT extern const char kV8CacheStrategiesForCacheStorage[];
CONTENT_EXPORT extern const char kValidateInputEventStream[];
CONTENT_EXPORT extern const char kWaitForDebuggerChildren[];
CONTENT_EXPORT extern const char kZygoteCmdPrefix[];
@@ -301,7 +293,6 @@ CONTENT_EXPORT extern const char kPrefetchArgumentOther[];
// like renderers, etc.
CONTENT_EXPORT extern const char kDeviceScaleFactor[];
CONTENT_EXPORT extern const char kDisableLegacyIntermediateWindow[];
-CONTENT_EXPORT extern const char kDisableWin32kLockDown[];
CONTENT_EXPORT extern const char kEnableAcceleratedVpxDecode[];
CONTENT_EXPORT extern const char kEnableWin7WebRtcHWH264Decoding[];
// Switch to pass the font cache shared memory handle to the renderer.
diff --git a/chromium/content/public/common/context_menu_params.cc b/chromium/content/public/common/context_menu_params.cc
index bfb5430c10c..cd929b465ea 100644
--- a/chromium/content/public/common/context_menu_params.cc
+++ b/chromium/content/public/common/context_menu_params.cc
@@ -31,7 +31,8 @@ ContextMenuParams::ContextMenuParams()
edit_flags(0),
referrer_policy(blink::kWebReferrerPolicyDefault),
source_type(ui::MENU_SOURCE_NONE),
- input_field_type(blink::WebContextMenuData::kInputFieldTypeNone) {}
+ input_field_type(blink::WebContextMenuData::kInputFieldTypeNone),
+ selection_start_offset(0) {}
ContextMenuParams::ContextMenuParams(const ContextMenuParams& other) = default;
diff --git a/chromium/content/public/common/context_menu_params.h b/chromium/content/public/common/context_menu_params.h
index 0abff18021e..a05a75c3457 100644
--- a/chromium/content/public/common/context_menu_params.h
+++ b/chromium/content/public/common/context_menu_params.h
@@ -15,7 +15,6 @@
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/common/menu_item.h"
-#include "content/public/common/page_state.h"
#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
#include "third_party/WebKit/public/web/WebContextMenuData.h"
#include "ui/base/ui_base_types.h"
@@ -87,16 +86,9 @@ struct CONTENT_EXPORT ContextMenuParams {
// on.
GURL page_url;
- // This is the absolute keyword search URL including the %s search tag when
- // the "Add as search engine..." option is clicked (left empty if not used).
- GURL keyword_url;
-
// This is the URL of the subframe that the context menu was invoked on.
GURL frame_url;
- // This is the page state of the frame on which the context menu was invoked.
- PageState frame_page_state;
-
// These are the parameters for the media element that the context menu
// was invoked on.
int media_flags;
@@ -157,6 +149,9 @@ struct CONTENT_EXPORT ContextMenuParams {
// Rect representing the coordinates in the document space of the selection.
gfx::Rect selection_rect;
+
+ // Start position of the selection text.
+ int selection_start_offset;
};
} // namespace content
diff --git a/chromium/content/public/common/cors_error_status.typemap b/chromium/content/public/common/cors_error_status.typemap
new file mode 100644
index 00000000000..6b66c33b1ac
--- /dev/null
+++ b/chromium/content/public/common/cors_error_status.typemap
@@ -0,0 +1,13 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//content/public/common/url_loader.mojom"
+public_headers = [ "//services/network/public/cpp/cors_error_status.h" ]
+traits_headers = [ "//content/common/resource_messages.h" ]
+deps = [
+ "//content:export",
+ "//net:net",
+ "//third_party/WebKit/public:blink_headers",
+]
+type_mappings = [ "content.mojom.CORSErrorStatus=network::CORSErrorStatus" ]
diff --git a/chromium/content/public/common/drop_data.cc b/chromium/content/public/common/drop_data.cc
index 242a8038ac7..e71e3da3fd2 100644
--- a/chromium/content/public/common/drop_data.cc
+++ b/chromium/content/public/common/drop_data.cc
@@ -7,7 +7,6 @@
#include "base/strings/utf_string_conversions.h"
#include "net/base/filename_util.h"
#include "net/base/mime_util.h"
-#include "third_party/WebKit/common/mime_util/mime_util.h"
namespace content {
@@ -65,7 +64,8 @@ base::Optional<base::FilePath> DropData::GetSafeFilenameForImageFileContents()
std::string mime_type;
if (net::GetWellKnownMimeTypeFromExtension(file_contents_filename_extension,
&mime_type) &&
- blink::IsSupportedImageMimeType(mime_type)) {
+ base::StartsWith(mime_type, "image/",
+ base::CompareCase::INSENSITIVE_ASCII)) {
return file_name.ReplaceExtension(file_contents_filename_extension);
}
return base::nullopt;
diff --git a/chromium/content/public/common/drop_data.h b/chromium/content/public/common/drop_data.h
index 204d6715de1..3e0dabaa7e4 100644
--- a/chromium/content/public/common/drop_data.h
+++ b/chromium/content/public/common/drop_data.h
@@ -11,8 +11,8 @@
#include <stdint.h>
-#include <map>
#include <string>
+#include <unordered_map>
#include <vector>
#include "base/files/file_path.h"
@@ -110,7 +110,7 @@ struct CONTENT_EXPORT DropData {
base::FilePath::StringType file_contents_filename_extension;
std::string file_contents_content_disposition;
- std::map<base::string16, base::string16> custom_data;
+ std::unordered_map<base::string16, base::string16> custom_data;
// The key-modifiers present for this update, included here so BrowserPlugin
// can forward them to the guest renderer.
diff --git a/chromium/content/public/common/drop_data_unittest.cc b/chromium/content/public/common/drop_data_unittest.cc
new file mode 100644
index 00000000000..fcf4fe4454b
--- /dev/null
+++ b/chromium/content/public/common/drop_data_unittest.cc
@@ -0,0 +1,77 @@
+// Copyright 2017 The Chromium Authors. 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/drop_data.h"
+
+#include "base/files/file_path.h"
+#include "base/optional.h"
+#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
+#include "net/base/mime_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(OS_WIN)
+#include "base/strings/utf_string_conversions.h"
+#define CONVERT_IF_NEEDED(x) base::UTF8ToUTF16((x))
+#else
+#define CONVERT_IF_NEEDED(x) x
+#endif
+
+namespace content {
+
+TEST(DropDataTest, GetSafeFilenameForImageFileContents) {
+ static constexpr struct {
+ const char* const extension;
+ const bool is_well_known;
+ const bool should_generate_filename;
+ } kTestCases[] = {
+ // Extensions with a well-known but non-image MIME type should not result
+ // in the generation of a filename.
+ {"exe", true, false},
+ {"html", true, false},
+ {"js", true, false},
+ // Extensions that do not have a well-known MIME type should not result in
+ // the generation of a filename.
+ {"should-not-be-known-extension", false, false},
+ // Extensions with a well-known MIME type should result in the generation
+ // of a filename.
+ {"bmp", true, true},
+ {"gif", true, true},
+ {"ico", true, true},
+ {"jpg", true, true},
+ {"png", true, true},
+ {"svg", true, true},
+ {"tif", true, true},
+ {"xbm", true, true},
+ {"webp", true, true},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(test_case.extension);
+ std::string ignored;
+ ASSERT_EQ(test_case.is_well_known,
+ net::GetWellKnownMimeTypeFromExtension(
+ CONVERT_IF_NEEDED(test_case.extension), &ignored));
+
+ DropData drop_data;
+ drop_data.file_contents_source_url =
+ GURL(base::StringPrintf("https://example.com/testresource"));
+ drop_data.file_contents_filename_extension =
+ CONVERT_IF_NEEDED(test_case.extension);
+ base::Optional<base::FilePath> generated_name =
+ drop_data.GetSafeFilenameForImageFileContents();
+ ASSERT_EQ(test_case.should_generate_filename, generated_name.has_value());
+
+ if (test_case.should_generate_filename) {
+ // base::FilePath::Extension() returns the preceeding dot, so drop it
+ // before doing the comparison.
+ EXPECT_EQ(CONVERT_IF_NEEDED(test_case.extension),
+ generated_name->Extension().substr(1));
+ }
+ }
+}
+
+} // namespace content
+
+#undef CONVERT_IF_NEEDED
diff --git a/chromium/content/common/input/input_event_ack_source.h b/chromium/content/public/common/input_event_ack_source.h
index ea376391cc8..a7fc9a4be47 100644
--- a/chromium/content/common/input/input_event_ack_source.h
+++ b/chromium/content/public/common/input_event_ack_source.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_COMMON_INPUT_INPUT_EVENT_ACK_SOURCE_H_
-#define CONTENT_COMMON_INPUT_INPUT_EVENT_ACK_SOURCE_H_
+#ifndef CONTENT_PUBLIC_COMMON_INPUT_EVENT_ACK_SOURCE_H_
+#define CONTENT_PUBLIC_COMMON_INPUT_EVENT_ACK_SOURCE_H_
namespace content {
@@ -21,4 +21,4 @@ enum class InputEventAckSource {
} // namespace content
-#endif // CONTENT_COMMON_INPUT_INPUT_EVENT_ACK_SOURCE_H_
+#endif // CONTENT_PUBLIC_COMMON_INPUT_EVENT_ACK_SOURCE_H_
diff --git a/chromium/content/common/input/input_event_ack_state.h b/chromium/content/public/common/input_event_ack_state.h
index dfaece55e5f..16b31e58d94 100644
--- a/chromium/content/common/input/input_event_ack_state.h
+++ b/chromium/content/public/common/input_event_ack_state.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_INPUT_INPUT_EVENT_ACK_STATE_H_
-#define CONTENT_COMMON_INPUT_INPUT_EVENT_ACK_STATE_H_
+#ifndef CONTENT_PUBLIC_COMMON_INPUT_EVENT_ACK_STATE_H_
+#define CONTENT_PUBLIC_COMMON_INPUT_EVENT_ACK_STATE_H_
namespace content {
@@ -21,6 +21,8 @@ enum InputEventAckState {
INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING
};
+const char* InputEventAckStateToString(InputEventAckState ack_state);
+
} // namespace content
-#endif // CONTENT_COMMON_INPUT_INPUT_EVENT_ACK_STATE_H_
+#endif // CONTENT_PUBLIC_COMMON_INPUT_EVENT_ACK_STATE_H_
diff --git a/chromium/content/public/common/manifest.cc b/chromium/content/public/common/manifest.cc
index 3bbba515a6c..ad5211065be 100644
--- a/chromium/content/public/common/manifest.cc
+++ b/chromium/content/public/common/manifest.cc
@@ -53,7 +53,8 @@ bool Manifest::IsEmpty() const {
related_applications.empty() && !prefer_related_applications &&
theme_color == Manifest::kInvalidOrMissingColor &&
background_color == Manifest::kInvalidOrMissingColor &&
- gcm_sender_id.is_null() && scope.is_empty();
+ splash_screen_url.is_empty() && gcm_sender_id.is_null() &&
+ scope.is_empty();
}
} // namespace content
diff --git a/chromium/content/public/common/manifest.h b/chromium/content/public/common/manifest.h
index 6c4ab52c677..6ff768c21e2 100644
--- a/chromium/content/public/common/manifest.h
+++ b/chromium/content/public/common/manifest.h
@@ -150,6 +150,10 @@ struct CONTENT_EXPORT Manifest {
// present.
int64_t background_color;
+ // A URL of the HTML splash screen.
+ // Empty if the parsing failed or the field was not present.
+ GURL splash_screen_url;
+
// This is a proprietary extension of the web Manifest, double-check that it
// is okay to use this entry.
// Null if parsing failed or the field was not present.
diff --git a/chromium/content/public/common/manifest.typemap b/chromium/content/public/common/manifest.typemap
index 7ca0eff1a7e..3584ce3a661 100644
--- a/chromium/content/public/common/manifest.typemap
+++ b/chromium/content/public/common/manifest.typemap
@@ -9,7 +9,7 @@ sources = [
"//content/public/common/manifest_struct_traits.cc",
]
type_mappings = [
- "blink.mojom.Manifest=content::Manifest",
+ "blink.mojom.Manifest=content::Manifest[nullable_is_same_type]",
"blink.mojom.ManifestIcon=content::Manifest::Icon",
"blink.mojom.ManifestRelatedApplication=content::Manifest::RelatedApplication",
"blink.mojom.ManifestShareTarget=content::Manifest::ShareTarget",
diff --git a/chromium/content/public/common/manifest_struct_traits.cc b/chromium/content/public/common/manifest_struct_traits.cc
index 80cbce661c7..c344ff3410c 100644
--- a/chromium/content/public/common/manifest_struct_traits.cc
+++ b/chromium/content/public/common/manifest_struct_traits.cc
@@ -85,6 +85,9 @@ bool StructTraits<blink::mojom::ManifestDataView, content::Manifest>::Read(
if (!ValidateColor(out->background_color))
return false;
+ if (!data.ReadSplashScreenUrl(&out->splash_screen_url))
+ return false;
+
if (!data.ReadDisplay(&out->display))
return false;
diff --git a/chromium/content/public/common/manifest_struct_traits.h b/chromium/content/public/common/manifest_struct_traits.h
index d6b06b24c1a..1c195d65a10 100644
--- a/chromium/content/public/common/manifest_struct_traits.h
+++ b/chromium/content/public/common/manifest_struct_traits.h
@@ -30,6 +30,10 @@ inline base::Optional<base::StringPiece16> TruncateNullableString16(
template <>
struct StructTraits<blink::mojom::ManifestDataView, content::Manifest> {
+ static bool IsNull(const content::Manifest& m) { return m.IsEmpty(); }
+
+ static void SetToNull(content::Manifest* m) { *m = content::Manifest(); }
+
static base::Optional<base::StringPiece16> name(const content::Manifest& m) {
return internal::TruncateNullableString16(m.name);
}
@@ -67,6 +71,10 @@ struct StructTraits<blink::mojom::ManifestDataView, content::Manifest> {
return m.background_color;
}
+ static const GURL& splash_screen_url(const content::Manifest& m) {
+ return m.splash_screen_url;
+ }
+
static const std::vector<content::Manifest::Icon>& icons(
const content::Manifest& m) {
return m.icons;
diff --git a/chromium/content/public/common/menu_item.h b/chromium/content/public/common/menu_item.h
index 8597433371e..e3cea30a799 100644
--- a/chromium/content/public/common/menu_item.h
+++ b/chromium/content/public/common/menu_item.h
@@ -21,7 +21,8 @@ struct CONTENT_EXPORT MenuItem {
CHECKABLE_OPTION = blink::WebMenuItemInfo::kCheckableOption,
GROUP = blink::WebMenuItemInfo::kGroup,
SEPARATOR = blink::WebMenuItemInfo::kSeparator,
- SUBMENU // This is currently only used by Pepper, not by WebKit.
+ SUBMENU, // This is currently only used by Pepper, not by WebKit.
+ TYPE_LAST = SUBMENU
};
MenuItem();
diff --git a/chromium/content/public/common/mutable_network_traffic_annotation_tag.typemap b/chromium/content/public/common/mutable_network_traffic_annotation_tag.typemap
deleted file mode 100644
index 986566b13c5..00000000000
--- a/chromium/content/public/common/mutable_network_traffic_annotation_tag.typemap
+++ /dev/null
@@ -1,10 +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 = "//content/public/common/mutable_network_traffic_annotation_tag.mojom"
-traits_headers = [ "//content/public/common/mutable_network_traffic_annotation_tag_struct_traits.h" ]
-deps = [
- "//net:traffic_annotation",
-]
-type_mappings = [ "content.mojom.MutableNetworkTrafficAnnotationTag=net::MutableNetworkTrafficAnnotationTag" ]
diff --git a/chromium/content/public/common/mutable_network_traffic_annotation_tag_struct_traits.h b/chromium/content/public/common/mutable_network_traffic_annotation_tag_struct_traits.h
deleted file mode 100644
index d17df8b0898..00000000000
--- a/chromium/content/public/common/mutable_network_traffic_annotation_tag_struct_traits.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_COMMON_MUTABLE_NETWORK_TRAFFIC_ANNOTATION_PARAM_TRAITS_H_
-#define CONTENT_PUBLIC_COMMON_MUTABLE_NETWORK_TRAFFIC_ANNOTATION_PARAM_TRAITS_H_
-
-#include "content/public/common/mutable_network_traffic_annotation_tag.mojom.h"
-#include "mojo/common/common_custom_types_struct_traits.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<content::mojom::MutableNetworkTrafficAnnotationTagDataView,
- net::MutableNetworkTrafficAnnotationTag> {
- static int32_t unique_id_hash_code(
- const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
- return traffic_annotation.unique_id_hash_code;
- }
- static bool Read(
- content::mojom::MutableNetworkTrafficAnnotationTagDataView data,
- net::MutableNetworkTrafficAnnotationTag* out) {
- out->unique_id_hash_code = data.unique_id_hash_code();
- return true;
- }
-};
-
-} // namespace mojo
-
-#endif // CONTENT_PUBLIC_COMMON_MUTABLE_NETWORK_TRAFFIC_ANNOTATION_PARAM_TRAITS_H_
diff --git a/chromium/content/public/common/network_connection_tracker.cc b/chromium/content/public/common/network_connection_tracker.cc
new file mode 100644
index 00000000000..cbe277a5415
--- /dev/null
+++ b/chromium/content/public/common/network_connection_tracker.cc
@@ -0,0 +1,147 @@
+// Copyright 2017 The Chromium Authors. 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/network_connection_tracker.h"
+
+#include <utility>
+
+#include "base/task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "content/public/common/network_service.mojom.h"
+#include "services/network/public/interfaces/network_change_manager.mojom.h"
+
+namespace content {
+
+namespace {
+
+// Wraps a |user_callback| when GetConnectionType() is called on a different
+// thread than NetworkConnectionTracker's thread.
+void OnGetConnectionType(
+ scoped_refptr<base::TaskRunner> task_runner,
+ NetworkConnectionTracker::ConnectionTypeCallback user_callback,
+ network::mojom::ConnectionType connection_type) {
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](NetworkConnectionTracker::ConnectionTypeCallback callback,
+ network::mojom::ConnectionType type) {
+ std::move(callback).Run(type);
+ },
+ std::move(user_callback), connection_type));
+}
+
+static const int32_t kConnectionTypeInvalid = -1;
+
+} // namespace
+
+NetworkConnectionTracker::NetworkConnectionTracker()
+ : task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ connection_type_(kConnectionTypeInvalid),
+ network_change_observer_list_(
+ new base::ObserverListThreadSafe<NetworkConnectionObserver>(
+ base::ObserverListPolicy::EXISTING_ONLY)),
+ binding_(this) {}
+
+void NetworkConnectionTracker::Initialize(
+ mojom::NetworkService* network_service) {
+ DCHECK(!binding_.is_bound());
+ DCHECK(network_service);
+ // Get NetworkChangeManagerPtr.
+ network::mojom::NetworkChangeManagerPtr manager_ptr;
+ network::mojom::NetworkChangeManagerRequest request(
+ mojo::MakeRequest(&manager_ptr));
+ network_service->GetNetworkChangeManager(std::move(request));
+
+ // Request notification from NetworkChangeManagerPtr.
+ network::mojom::NetworkChangeManagerClientPtr client_ptr;
+ network::mojom::NetworkChangeManagerClientRequest client_request(
+ mojo::MakeRequest(&client_ptr));
+ binding_.Bind(std::move(client_request));
+ manager_ptr->RequestNotifications(std::move(client_ptr));
+}
+
+NetworkConnectionTracker::~NetworkConnectionTracker() {
+ network_change_observer_list_->AssertEmpty();
+}
+
+bool NetworkConnectionTracker::GetConnectionType(
+ network::mojom::ConnectionType* type,
+ ConnectionTypeCallback callback) {
+ // |connection_type_| is initialized when NetworkService starts up. In most
+ // cases, it won't be kConnectionTypeInvalid and code will return early.
+ base::subtle::Atomic32 type_value =
+ base::subtle::NoBarrier_Load(&connection_type_);
+ if (type_value != kConnectionTypeInvalid) {
+ *type = static_cast<network::mojom::ConnectionType>(type_value);
+ return true;
+ }
+ base::AutoLock lock(lock_);
+ // Check again after getting the lock, and return early if
+ // OnInitialConnectionType() is called after first NoBarrier_Load.
+ type_value = base::subtle::NoBarrier_Load(&connection_type_);
+ if (type_value != kConnectionTypeInvalid) {
+ *type = static_cast<network::mojom::ConnectionType>(type_value);
+ return true;
+ }
+ if (!task_runner_->RunsTasksInCurrentSequence()) {
+ connection_type_callbacks_.push_back(base::BindOnce(
+ &OnGetConnectionType, base::ThreadTaskRunnerHandle::Get(),
+ std::move(callback)));
+ } else {
+ connection_type_callbacks_.push_back(std::move(callback));
+ }
+ return false;
+}
+
+// static
+bool NetworkConnectionTracker::IsConnectionCellular(
+ network::mojom::ConnectionType type) {
+ bool is_cellular = false;
+ switch (type) {
+ case network::mojom::ConnectionType::CONNECTION_2G:
+ case network::mojom::ConnectionType::CONNECTION_3G:
+ case network::mojom::ConnectionType::CONNECTION_4G:
+ is_cellular = true;
+ break;
+ case network::mojom::ConnectionType::CONNECTION_UNKNOWN:
+ case network::mojom::ConnectionType::CONNECTION_ETHERNET:
+ case network::mojom::ConnectionType::CONNECTION_WIFI:
+ case network::mojom::ConnectionType::CONNECTION_NONE:
+ case network::mojom::ConnectionType::CONNECTION_BLUETOOTH:
+ is_cellular = false;
+ break;
+ }
+ return is_cellular;
+}
+
+void NetworkConnectionTracker::AddNetworkConnectionObserver(
+ NetworkConnectionObserver* observer) {
+ network_change_observer_list_->AddObserver(observer);
+}
+
+void NetworkConnectionTracker::RemoveNetworkConnectionObserver(
+ NetworkConnectionObserver* observer) {
+ network_change_observer_list_->RemoveObserver(observer);
+}
+
+void NetworkConnectionTracker::OnInitialConnectionType(
+ network::mojom::ConnectionType type) {
+ base::AutoLock lock(lock_);
+ base::subtle::NoBarrier_Store(&connection_type_,
+ static_cast<base::subtle::Atomic32>(type));
+ while (!connection_type_callbacks_.empty()) {
+ std::move(connection_type_callbacks_.front()).Run(type);
+ connection_type_callbacks_.pop_front();
+ }
+}
+
+void NetworkConnectionTracker::OnNetworkChanged(
+ network::mojom::ConnectionType type) {
+ base::subtle::NoBarrier_Store(&connection_type_,
+ static_cast<base::subtle::Atomic32>(type));
+ network_change_observer_list_->Notify(
+ FROM_HERE, &NetworkConnectionObserver::OnConnectionChanged, type);
+}
+
+} // namespace content
diff --git a/chromium/content/public/common/network_connection_tracker.h b/chromium/content/public/common/network_connection_tracker.h
new file mode 100644
index 00000000000..541a78fe8de
--- /dev/null
+++ b/chromium/content/public/common/network_connection_tracker.h
@@ -0,0 +1,117 @@
+// Copyright 2017 The Chromium Authors. 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_NETWORK_CONNECTION_TRACKER_H_
+#define CONTENT_PUBLIC_COMMON_NETWORK_CONNECTION_TRACKER_H_
+
+#include <list>
+#include <memory>
+
+#include "base/atomicops.h"
+#include "base/callback.h"
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/observer_list_threadsafe.h"
+#include "base/synchronization/lock.h"
+#include "content/common/content_export.h"
+#include "content/public/common/network_service.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "services/network/public/interfaces/network_change_manager.mojom.h"
+
+namespace content {
+
+// This class subscribes to network change events from
+// network::mojom::NetworkChangeManager and propogates these notifications to
+// its NetworkConnectionObservers registered through
+// AddObserver()/RemoveObserver().
+class CONTENT_EXPORT NetworkConnectionTracker
+ : public network::mojom::NetworkChangeManagerClient {
+ public:
+ typedef base::OnceCallback<void(network::mojom::ConnectionType)>
+ ConnectionTypeCallback;
+
+ class CONTENT_EXPORT NetworkConnectionObserver {
+ public:
+ // Please refer to NetworkChangeManagerClient::OnNetworkChanged for when
+ // this method is invoked.
+ virtual void OnConnectionChanged(network::mojom::ConnectionType type) = 0;
+
+ protected:
+ NetworkConnectionObserver() {}
+ virtual ~NetworkConnectionObserver() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NetworkConnectionObserver);
+ };
+
+ NetworkConnectionTracker();
+
+ ~NetworkConnectionTracker() override;
+
+ // Starts listening for connection notifications from |network_service|.
+ // Observers may be added and GetConnectionType called, but no network
+ // information will be provided until this method is called. For unit tests,
+ // this class can be subclassed, and OnInitialConnectionType /
+ // OnNetworkChanged may be called directly, instead of providing a
+ // NetworkService.
+ void Initialize(mojom::NetworkService* network_service);
+
+ // If connection type can be retrieved synchronously, returns true and |type|
+ // will contain the current connection type; Otherwise, returns false, in
+ // which case, |callback| will be called on the calling thread when connection
+ // type is ready. This method is thread safe. Please also refer to
+ // net::NetworkChangeNotifier::GetConnectionType() for documentation.
+ virtual bool GetConnectionType(network::mojom::ConnectionType* type,
+ ConnectionTypeCallback callback);
+
+ // Returns true if |type| is a cellular connection.
+ // Returns false if |type| is CONNECTION_UNKNOWN, and thus, depending on the
+ // implementation of GetConnectionType(), it is possible that
+ // IsConnectionCellular(GetConnectionType()) returns false even if the
+ // current connection is cellular.
+ static bool IsConnectionCellular(network::mojom::ConnectionType type);
+
+ // Registers |observer| to receive notifications of network changes. The
+ // thread on which this is called is the thread on which |observer| will be
+ // called back with notifications.
+ void AddNetworkConnectionObserver(NetworkConnectionObserver* observer);
+
+ // Unregisters |observer| from receiving notifications. This must be called
+ // on the same thread on which AddObserver() was called.
+ // All observers must be unregistred before |this| is destroyed.
+ void RemoveNetworkConnectionObserver(NetworkConnectionObserver* observer);
+
+ protected:
+ // NetworkChangeManagerClient implementation. Protected for testing.
+ void OnInitialConnectionType(network::mojom::ConnectionType type) override;
+ void OnNetworkChanged(network::mojom::ConnectionType type) override;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(NetworkGetConnectionTest,
+ GetConnectionTypeOnDifferentThread);
+ // The task runner that |this| lives on.
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
+ // Protect access to |connection_type_callbacks_|.
+ base::Lock lock_;
+
+ // Saves user callback if GetConnectionType() cannot complete synchronously.
+ std::list<ConnectionTypeCallback> connection_type_callbacks_;
+
+ // |connection_type_| is set on one thread but read on many threads.
+ // The default value is -1 before OnInitialConnectionType().
+ base::subtle::Atomic32 connection_type_;
+
+ const scoped_refptr<base::ObserverListThreadSafe<NetworkConnectionObserver>>
+ network_change_observer_list_;
+
+ mojo::Binding<network::mojom::NetworkChangeManagerClient> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkConnectionTracker);
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_COMMON_NETWORK_CONNECTION_TRACKER_H_
diff --git a/chromium/content/public/common/network_connection_tracker_unittest.cc b/chromium/content/public/common/network_connection_tracker_unittest.cc
new file mode 100644
index 00000000000..327f14562f6
--- /dev/null
+++ b/chromium/content/public/common/network_connection_tracker_unittest.cc
@@ -0,0 +1,317 @@
+// Copyright 2017 The Chromium Authors. 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/network_connection_tracker.h"
+
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_checker.h"
+#include "content/public/network/network_service.h"
+#include "net/base/mock_network_change_notifier.h"
+#include "services/network/public/interfaces/network_change_manager.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+class TestNetworkConnectionObserver
+ : public NetworkConnectionTracker::NetworkConnectionObserver {
+ public:
+ explicit TestNetworkConnectionObserver(NetworkConnectionTracker* tracker)
+ : num_notifications_(0),
+ tracker_(tracker),
+ run_loop_(std::make_unique<base::RunLoop>()),
+ connection_type_(network::mojom::ConnectionType::CONNECTION_UNKNOWN) {
+ tracker_->AddNetworkConnectionObserver(this);
+ }
+
+ ~TestNetworkConnectionObserver() override {
+ tracker_->RemoveNetworkConnectionObserver(this);
+ }
+
+ // Helper to synchronously get connection type from NetworkConnectionTracker.
+ network::mojom::ConnectionType GetConnectionTypeSync() {
+ network::mojom::ConnectionType type;
+ base::RunLoop run_loop;
+ bool sync = tracker_->GetConnectionType(
+ &type,
+ base::Bind(&TestNetworkConnectionObserver::GetConnectionTypeCallback,
+ &run_loop, &type));
+ if (!sync)
+ run_loop.Run();
+ return type;
+ }
+
+ // NetworkConnectionObserver implementation:
+ void OnConnectionChanged(network::mojom::ConnectionType type) override {
+ EXPECT_EQ(type, GetConnectionTypeSync());
+
+ num_notifications_++;
+ connection_type_ = type;
+ run_loop_->Quit();
+ }
+
+ size_t num_notifications() const { return num_notifications_; }
+ void WaitForNotification() {
+ run_loop_->Run();
+ run_loop_.reset(new base::RunLoop());
+ }
+
+ network::mojom::ConnectionType connection_type() const {
+ return connection_type_;
+ }
+
+ private:
+ static void GetConnectionTypeCallback(base::RunLoop* run_loop,
+ network::mojom::ConnectionType* out,
+ network::mojom::ConnectionType type) {
+ *out = type;
+ run_loop->Quit();
+ }
+
+ size_t num_notifications_;
+ NetworkConnectionTracker* tracker_;
+ std::unique_ptr<base::RunLoop> run_loop_;
+ network::mojom::ConnectionType connection_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestNetworkConnectionObserver);
+};
+
+// A helper class to call NetworkConnectionTracker::GetConnectionType().
+class ConnectionTypeGetter {
+ public:
+ explicit ConnectionTypeGetter(NetworkConnectionTracker* tracker)
+ : tracker_(tracker),
+ connection_type_(network::mojom::ConnectionType::CONNECTION_UNKNOWN) {}
+ ~ConnectionTypeGetter() {}
+
+ bool GetConnectionType() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return tracker_->GetConnectionType(
+ &connection_type_,
+ base::Bind(&ConnectionTypeGetter::OnGetConnectionType,
+ base::Unretained(this)));
+ }
+
+ void WaitForConnectionType(
+ network::mojom::ConnectionType expected_connection_type) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ run_loop_.Run();
+ EXPECT_EQ(expected_connection_type, connection_type_);
+ }
+
+ network::mojom::ConnectionType connection_type() const {
+ return connection_type_;
+ }
+
+ private:
+ void OnGetConnectionType(network::mojom::ConnectionType type) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ connection_type_ = type;
+ run_loop_.Quit();
+ }
+
+ base::RunLoop run_loop_;
+ NetworkConnectionTracker* tracker_;
+ network::mojom::ConnectionType connection_type_;
+ THREAD_CHECKER(thread_checker_);
+
+ DISALLOW_COPY_AND_ASSIGN(ConnectionTypeGetter);
+};
+
+} // namespace
+
+class NetworkConnectionTrackerTest : public testing::Test {
+ public:
+ NetworkConnectionTrackerTest() {
+ mojom::NetworkServicePtr network_service_ptr;
+ mojom::NetworkServiceRequest network_service_request =
+ mojo::MakeRequest(&network_service_ptr);
+ network_service_ =
+ NetworkService::Create(std::move(network_service_request),
+ /*netlog=*/nullptr);
+ tracker_ = std::make_unique<NetworkConnectionTracker>();
+ tracker_->Initialize(network_service_.get());
+ observer_ = std::make_unique<TestNetworkConnectionObserver>(tracker_.get());
+ }
+
+ ~NetworkConnectionTrackerTest() override {}
+
+ NetworkService* network_service() { return network_service_.get(); }
+
+ NetworkConnectionTracker* network_connection_tracker() {
+ return tracker_.get();
+ }
+
+ TestNetworkConnectionObserver* network_connection_observer() {
+ return observer_.get();
+ }
+
+ // Simulates a connection type change and broadcast it to observers.
+ void SimulateConnectionTypeChange(
+ net::NetworkChangeNotifier::ConnectionType type) {
+ mock_network_change_notifier_.NotifyObserversOfNetworkChangeForTests(type);
+ }
+
+ // Sets the current connection type of the mock network change notifier.
+ void SetConnectionType(net::NetworkChangeNotifier::ConnectionType type) {
+ mock_network_change_notifier_.SetConnectionType(type);
+ }
+
+ private:
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ net::test::MockNetworkChangeNotifier mock_network_change_notifier_;
+ std::unique_ptr<NetworkService> network_service_;
+ std::unique_ptr<NetworkConnectionTracker> tracker_;
+ std::unique_ptr<TestNetworkConnectionObserver> observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkConnectionTrackerTest);
+};
+
+TEST_F(NetworkConnectionTrackerTest, ObserverNotified) {
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_UNKNOWN,
+ network_connection_observer()->connection_type());
+
+ // Simulate a network change.
+ SimulateConnectionTypeChange(
+ net::NetworkChangeNotifier::ConnectionType::CONNECTION_3G);
+
+ network_connection_observer()->WaitForNotification();
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_3G,
+ network_connection_observer()->connection_type());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, network_connection_observer()->num_notifications());
+}
+
+TEST_F(NetworkConnectionTrackerTest, UnregisteredObserverNotNotified) {
+ auto network_connection_observer2 =
+ std::make_unique<TestNetworkConnectionObserver>(
+ network_connection_tracker());
+
+ // Simulate a network change.
+ SimulateConnectionTypeChange(
+ net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI);
+
+ network_connection_observer2->WaitForNotification();
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_WIFI,
+ network_connection_observer2->connection_type());
+ network_connection_observer()->WaitForNotification();
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_WIFI,
+ network_connection_observer()->connection_type());
+ base::RunLoop().RunUntilIdle();
+
+ network_connection_observer2.reset();
+
+ // Simulate an another network change.
+ SimulateConnectionTypeChange(
+ net::NetworkChangeNotifier::ConnectionType::CONNECTION_2G);
+ network_connection_observer()->WaitForNotification();
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_2G,
+ network_connection_observer()->connection_type());
+ EXPECT_EQ(2u, network_connection_observer()->num_notifications());
+}
+
+TEST_F(NetworkConnectionTrackerTest, GetConnectionType) {
+ SetConnectionType(net::NetworkChangeNotifier::ConnectionType::CONNECTION_3G);
+ // Creates a new NetworkService so it initializes a NetworkChangeManager
+ // with initial connection type as CONNECTION_3G.
+ mojom::NetworkServicePtr network_service_ptr;
+ mojom::NetworkServiceRequest network_service_request =
+ mojo::MakeRequest(&network_service_ptr);
+ std::unique_ptr<NetworkService> network_service =
+ NetworkService::Create(std::move(network_service_request), nullptr);
+ NetworkConnectionTracker tracker;
+ tracker.Initialize(network_service_ptr.get());
+
+ ConnectionTypeGetter getter1(&tracker), getter2(&tracker);
+ // These two GetConnectionType() will finish asynchonously because network
+ // service is not yet set up.
+ EXPECT_FALSE(getter1.GetConnectionType());
+ EXPECT_FALSE(getter2.GetConnectionType());
+
+ getter1.WaitForConnectionType(
+ /*expected_connection_type=*/network::mojom::ConnectionType::
+ CONNECTION_3G);
+ getter2.WaitForConnectionType(
+ /*expected_connection_type=*/network::mojom::ConnectionType::
+ CONNECTION_3G);
+
+ ConnectionTypeGetter getter3(&tracker);
+ // This GetConnectionType() should finish synchronously.
+ EXPECT_TRUE(getter3.GetConnectionType());
+ EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_3G,
+ getter3.connection_type());
+}
+
+// Tests GetConnectionType() on a different thread.
+class NetworkGetConnectionTest : public NetworkConnectionTrackerTest {
+ public:
+ NetworkGetConnectionTest()
+ : getter_thread_("NetworkGetConnectionTestThread") {
+ getter_thread_.Start();
+ }
+
+ ~NetworkGetConnectionTest() override {}
+
+ void GetConnectionType() {
+ DCHECK(getter_thread_.task_runner()->RunsTasksInCurrentSequence());
+ getter_ =
+ std::make_unique<ConnectionTypeGetter>(network_connection_tracker());
+ EXPECT_FALSE(getter_->GetConnectionType());
+ }
+
+ void WaitForConnectionType(
+ network::mojom::ConnectionType expected_connection_type) {
+ DCHECK(getter_thread_.task_runner()->RunsTasksInCurrentSequence());
+ getter_->WaitForConnectionType(expected_connection_type);
+ }
+
+ base::Thread* getter_thread() { return &getter_thread_; }
+
+ private:
+ base::Thread getter_thread_;
+
+ // Accessed on |getter_thread_|.
+ std::unique_ptr<ConnectionTypeGetter> getter_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkGetConnectionTest);
+};
+
+TEST_F(NetworkGetConnectionTest, GetConnectionTypeOnDifferentThread) {
+ // Flush pending OnInitialConnectionType() notification and force |tracker| to
+ // use async for GetConnectionType() calls.
+ base::RunLoop().RunUntilIdle();
+ base::subtle::NoBarrier_Store(&network_connection_tracker()->connection_type_,
+ -1);
+ {
+ base::RunLoop run_loop;
+ getter_thread()->task_runner()->PostTaskAndReply(
+ FROM_HERE,
+ base::BindOnce(&NetworkGetConnectionTest::GetConnectionType,
+ base::Unretained(this)),
+ base::BindOnce([](base::RunLoop* run_loop) { run_loop->Quit(); },
+ base::Unretained(&run_loop)));
+ run_loop.Run();
+ }
+
+ network_connection_tracker()->OnInitialConnectionType(
+ network::mojom::ConnectionType::CONNECTION_3G);
+ {
+ base::RunLoop run_loop;
+ getter_thread()->task_runner()->PostTaskAndReply(
+ FROM_HERE,
+ base::BindOnce(&NetworkGetConnectionTest::WaitForConnectionType,
+ base::Unretained(this),
+ /*expected_connection_type=*/
+ network::mojom::ConnectionType::CONNECTION_3G),
+ base::BindOnce([](base::RunLoop* run_loop) { run_loop->Quit(); },
+ base::Unretained(&run_loop)));
+ run_loop.Run();
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/public/common/network_service.mojom b/chromium/content/public/common/network_service.mojom
index e4e953bf748..b602537f4cd 100644
--- a/chromium/content/public/common/network_service.mojom
+++ b/chromium/content/public/common/network_service.mojom
@@ -6,12 +6,17 @@ module content.mojom;
import "mojo/common/file_path.mojom";
import "mojo/common/time.mojom";
+import "resource_type.mojom";
import "url_loader.mojom";
import "url_loader_factory.mojom";
import "url/mojo/url.mojom";
import "services/network/public/interfaces/cookie_manager.mojom";
+import "services/network/public/interfaces/network_change_manager.mojom";
import "services/network/public/interfaces/restricted_cookie_manager.mojom";
+[Native]
+struct SSLInfo;
+
// Parameters for constructing a network context.
struct NetworkContextParams {
// Name used by memory tools to identify the context.
@@ -58,6 +63,21 @@ struct NetworkContextParams {
bool http_09_on_non_default_ports_enabled = false;
};
+struct NetworkConditions {
+ // If set, the offline state is simulated and other fields are ignored.
+ bool offline;
+
+ // Channel round-trip latency, i.e. minimum time between request sent and
+ // response received.
+ mojo.common.mojom.TimeDelta latency;
+
+ // Maximal aggregated download throughput (bytes/sec). 0 disables download throttling.
+ double download_throughput;
+
+ // Maximal aggregated upload throughput (bytes/sec). 0 disables upload throttling.
+ double upload_throughput;
+};
+
// Represents a distinct context for making network requests, with its own
// storage (e.g. cookies and cache).
interface NetworkContext {
@@ -66,12 +86,12 @@ interface NetworkContext {
CreateURLLoaderFactory(URLLoaderFactory& url_loader_factory,
uint32 process_id);
- // Handle a request to display cache data to the user. |url| is parsed to
+ // Handles a request to display cache data to the user. |url| is parsed to
// display different parts of the cache.
HandleViewCacheRequest(url.mojom.Url url,
URLLoaderClient client);
- // Get the CookieManager associated with this network context.
+ // Gets the CookieManager associated with this network context.
GetCookieManager(network.mojom.CookieManager& cookie_manager);
// TODO(crbug.com/729800): Switch from {process,frame}_id to the network
@@ -88,10 +108,33 @@ interface NetworkContext {
//
// The callback will be invoked once the data has been deleted.
ClearNetworkingHistorySince(mojo.common.mojom.Time start_time) => ();
+
+ // Configures network conditions for the specified throttling profile.
+ // The throttling will be applied only to requests that have
+ // X-DevTools-Emulate-Network-Conditions-Client-Id: <profile_id>
+ // header with matching <profile_id>.
+ // Passing null NetworkConditions disables the throttling.
+ // TODO(caseq): get rid of header, make profile_id part of ResourceRequest.
+ SetNetworkConditions(string profile_id, NetworkConditions? conditions);
+};
+
+// Network service interface to the browser.
+interface NetworkServiceClient {
+ // Called when an SSL certificate is encountered.
+ // The callback argument is a net::ERROR value. If it's net::OK, then the
+ // request is resumed. Otherwise it's cancelled with the given error.
+ OnSSLCertificateError(ResourceType resource_type,
+ url.mojom.Url url,
+ uint32 process_id,
+ uint32 routing_id,
+ SSLInfo ssl_info,
+ bool fatal) => (int32 net_error);
};
// Browser interface to the network service.
interface NetworkService {
+ SetClient(NetworkServiceClient client);
+
// Creates a new network context with the given parameters.
CreateNetworkContext(NetworkContext& context,
NetworkContextParams params);
@@ -105,4 +148,8 @@ interface NetworkService {
// permission increases risks in case the child process becomes compromised,
// so this should be done only in specific cases (e.g. DevTools attached).
SetRawHeadersAccess(uint32 process_id, bool allow);
+
+ // Gets the NetworkChangeManager.
+ GetNetworkChangeManager(
+ network.mojom.NetworkChangeManager& network_change_manager);
};
diff --git a/chromium/content/public/common/network_service_test.mojom b/chromium/content/public/common/network_service_test.mojom
index fa25e518356..7e9b7fbeb3a 100644
--- a/chromium/content/public/common/network_service_test.mojom
+++ b/chromium/content/public/common/network_service_test.mojom
@@ -4,6 +4,8 @@
module content.mojom;
+import "services/network/public/interfaces/network_change_manager.mojom";
+
struct Rule {
string host_pattern;
string replacement;
@@ -15,4 +17,12 @@ interface NetworkServiceTest {
// service is running.
[Sync]
AddRules(array<Rule> rules) => ();
+
+ // Simulates a network connection type change. The new connection type will be
+ // updated to |type| and broadcasts will be sent to
+ // NetworkConnectionManagerClient implementations.
+ SimulateNetworkChange(network.mojom.ConnectionType type) => ();
+
+ // Crash the process where network service is running.
+ SimulateCrash();
};
diff --git a/chromium/content/public/common/pepper_plugin_info.cc b/chromium/content/public/common/pepper_plugin_info.cc
index f0678f6b706..8e3b911d507 100644
--- a/chromium/content/public/common/pepper_plugin_info.cc
+++ b/chromium/content/public/common/pepper_plugin_info.cc
@@ -10,10 +10,9 @@
namespace content {
PepperPluginInfo::EntryPoints::EntryPoints()
- : get_interface(NULL),
- initialize_module(NULL),
- shutdown_module(NULL) {
-}
+ : get_interface(nullptr),
+ initialize_module(nullptr),
+ shutdown_module(nullptr) {}
PepperPluginInfo::PepperPluginInfo()
: is_internal(false),
diff --git a/chromium/content/public/common/referrer_struct_traits.cc b/chromium/content/public/common/referrer_struct_traits.cc
index 6fc851b7f28..33dafc00c0d 100644
--- a/chromium/content/public/common/referrer_struct_traits.cc
+++ b/chromium/content/public/common/referrer_struct_traits.cc
@@ -4,7 +4,6 @@
#include "content/public/common/referrer_struct_traits.h"
-#include "third_party/WebKit/public/platform/ReferrerPolicyEnumTraits.h"
#include "url/mojo/url_gurl_struct_traits.h"
namespace mojo {
diff --git a/chromium/content/public/common/referrer_struct_traits.h b/chromium/content/public/common/referrer_struct_traits.h
index f7a7b023a98..142aaee5057 100644
--- a/chromium/content/public/common/referrer_struct_traits.h
+++ b/chromium/content/public/common/referrer_struct_traits.h
@@ -7,6 +7,7 @@
#include "content/common/content_export.h"
#include "content/public/common/referrer.h"
+#include "third_party/WebKit/public/platform/ReferrerPolicyEnumTraits.h"
#include "third_party/WebKit/public/platform/referrer.mojom.h"
namespace mojo {
diff --git a/chromium/content/public/common/renderer_preferences.cc b/chromium/content/public/common/renderer_preferences.cc
index dc4edacff88..be9f5f80efb 100644
--- a/chromium/content/public/common/renderer_preferences.cc
+++ b/chromium/content/public/common/renderer_preferences.cc
@@ -27,10 +27,11 @@ RendererPreferences::RendererPreferences()
inactive_selection_bg_color(SkColorSetRGB(200, 200, 200)),
inactive_selection_fg_color(SkColorSetRGB(50, 50, 50)),
browser_handles_all_top_level_requests(false),
- caret_blink_interval(0.5),
+ caret_blink_interval(base::TimeDelta::FromMilliseconds(500)),
use_custom_colors(true),
enable_referrers(true),
enable_do_not_track(false),
+ enable_encrypted_media(true),
webrtc_udp_min_port(0),
webrtc_udp_max_port(0),
tap_multiple_targets_strategy(TAP_MULTIPLE_TARGETS_STRATEGY_POPUP),
diff --git a/chromium/content/public/common/renderer_preferences.h b/chromium/content/public/common/renderer_preferences.h
index 4fcdea55684..f113b5618e5 100644
--- a/chromium/content/public/common/renderer_preferences.h
+++ b/chromium/content/public/common/renderer_preferences.h
@@ -83,10 +83,10 @@ struct CONTENT_EXPORT RendererPreferences {
// Browser wants a look at all top-level navigation requests.
bool browser_handles_all_top_level_requests;
- // Cursor blink rate in seconds.
+ // Cursor blink rate.
// Currently only changed from default on Linux. Uses |gtk-cursor-blink|
// from GtkSettings.
- double caret_blink_interval;
+ base::TimeDelta caret_blink_interval;
// Whether or not to set custom colors at all.
bool use_custom_colors;
@@ -97,6 +97,11 @@ struct CONTENT_EXPORT RendererPreferences {
// Set to true to indicate that the preference to set DNT to 1 is enabled.
bool enable_do_not_track;
+ // Whether to allow the use of Encrypted Media Extensions (EME), except for
+ // the use of Clear Key key system which is always allowed as required by the
+ // spec.
+ bool enable_encrypted_media;
+
// This is the IP handling policy override for WebRTC. The value must be one
// of the strings defined in privacy.json. The allowed values are specified
// in webrtc_ip_handling_policy.h.
diff --git a/chromium/content/public/common/resource_request.h b/chromium/content/public/common/resource_request.h
index c4e27d68510..cdfd4e114fd 100644
--- a/chromium/content/public/common/resource_request.h
+++ b/chromium/content/public/common/resource_request.h
@@ -11,6 +11,7 @@
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "content/common/content_export.h"
+#include "content/public/common/child_process_host.h"
#include "content/public/common/previews_state.h"
#include "content/public/common/request_context_frame_type.h"
#include "content/public/common/request_context_type.h"
@@ -19,8 +20,9 @@
#include "content/public/common/service_worker_modes.h"
#include "net/base/request_priority.h"
#include "net/http/http_request_headers.h"
+#include "services/network/public/interfaces/fetch_api.mojom.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/WebMixedContentContextType.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"
@@ -58,8 +60,8 @@ struct CONTENT_EXPORT ResourceRequest {
blink::WebReferrerPolicy referrer_policy = blink::kWebReferrerPolicyAlways;
// The frame's visibility state.
- blink::WebPageVisibilityState visibility_state =
- blink::kWebPageVisibilityStateVisible;
+ blink::mojom::PageVisibilityState visibility_state =
+ blink::mojom::PageVisibilityState::kVisible;
// Additional HTTP request headers.
net::HttpRequestHeaders headers;
@@ -67,12 +69,15 @@ struct CONTENT_EXPORT ResourceRequest {
// net::URLRequest load flags (0 by default).
int load_flags = 0;
- // Process ID from which this request originated, or zero if it originated
- // in the renderer itself.
- int origin_pid = 0;
+ // If this request originated from a pepper plugin running in a child
+ // process, this identifies which process it came from. Otherwise, it
+ // is zero.
+ int plugin_child_id = ChildProcessHost::kInvalidUniqueID;
// What this resource load is for (main frame, sub-frame, sub-resource,
// object).
+ // TODO(qinmin): this is used for legacy code path. With network service, it
+ // shouldn't know about resource type.
ResourceType resource_type = RESOURCE_TYPE_MAIN_FRAME;
// The priority of this request determined by Blink.
@@ -88,6 +93,16 @@ struct CONTENT_EXPORT ResourceRequest {
// True if corresponding AppCache group should be resetted.
bool should_reset_appcache = false;
+ // https://wicg.github.io/cors-rfc1918/#external-request
+ // TODO(toyoshim): The browser should know better than renderers do.
+ // This is used to plumb Blink decided information for legacy code path, but
+ // eventually we should remove this.
+ bool is_external_request = false;
+
+ // A policy to decide if CORS-preflight fetch should be performed.
+ network::mojom::CORSPreflightPolicy cors_preflight_policy =
+ network::mojom::CORSPreflightPolicy::kConsiderPreflight;
+
// Indicates which frame (or worker context) the request is being loaded into,
// or kInvalidServiceWorkerProviderId.
int service_worker_provider_id = kInvalidServiceWorkerProviderId;
@@ -101,10 +116,12 @@ struct CONTENT_EXPORT ResourceRequest {
ServiceWorkerMode service_worker_mode = ServiceWorkerMode::ALL;
// The request mode passed to the ServiceWorker.
- FetchRequestMode fetch_request_mode = FETCH_REQUEST_MODE_SAME_ORIGIN;
+ network::mojom::FetchRequestMode fetch_request_mode =
+ network::mojom::FetchRequestMode::kSameOrigin;
// The credentials mode passed to the ServiceWorker.
- FetchCredentialsMode fetch_credentials_mode = FETCH_CREDENTIALS_MODE_OMIT;
+ network::mojom::FetchCredentialsMode fetch_credentials_mode =
+ network::mojom::FetchCredentialsMode::kOmit;
// The redirect mode used in Fetch API.
FetchRedirectMode fetch_redirect_mode = FetchRedirectMode::FOLLOW_MODE;
diff --git a/chromium/content/public/common/resource_request_body.cc b/chromium/content/public/common/resource_request_body.cc
index 3e0a8c8e3e9..579a6528746 100644
--- a/chromium/content/public/common/resource_request_body.cc
+++ b/chromium/content/public/common/resource_request_body.cc
@@ -54,6 +54,17 @@ void ResourceRequestBody::AppendFileRange(
expected_modification_time);
}
+void ResourceRequestBody::AppendRawFileRange(
+ base::File file,
+ const base::FilePath& file_path,
+ uint64_t offset,
+ uint64_t length,
+ const base::Time& expected_modification_time) {
+ elements_.push_back(Element());
+ elements_.back().SetToFileRange(std::move(file), file_path, offset, length,
+ expected_modification_time);
+}
+
void ResourceRequestBody::AppendBlob(const std::string& uuid) {
elements_.push_back(Element());
elements_.back().SetToBlob(uuid);
@@ -69,6 +80,12 @@ void ResourceRequestBody::AppendFileSystemFileRange(
expected_modification_time);
}
+void ResourceRequestBody::AppendDataPipe(
+ network::mojom::DataPipeGetterPtr data_pipe_getter) {
+ elements_.push_back(Element());
+ elements_.back().SetToDataPipe(std::move(data_pipe_getter));
+}
+
std::vector<base::FilePath> ResourceRequestBody::GetReferencedFiles() const {
std::vector<base::FilePath> result;
for (const auto& element : *elements()) {
diff --git a/chromium/content/public/common/resource_request_body.h b/chromium/content/public/common/resource_request_body.h
index bf2bf5d508d..ad6c7b18e13 100644
--- a/chromium/content/public/common/resource_request_body.h
+++ b/chromium/content/public/common/resource_request_body.h
@@ -10,6 +10,8 @@
#include <string>
#include <vector>
+#include "base/files/file.h"
+#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "build/build_config.h"
@@ -53,12 +55,20 @@ class CONTENT_EXPORT ResourceRequestBody
uint64_t offset,
uint64_t length,
const base::Time& expected_modification_time);
+ // Appends the specified part of |file|. If |length| extends beyond the end of
+ // the file, it will be set to the end of the file.
+ void AppendRawFileRange(base::File file,
+ const base::FilePath& file_path,
+ uint64_t offset,
+ uint64_t length,
+ const base::Time& expected_modification_time);
void AppendBlob(const std::string& uuid);
void AppendFileSystemFileRange(const GURL& url,
uint64_t offset,
uint64_t length,
const base::Time& expected_modification_time);
+ void AppendDataPipe(network::mojom::DataPipeGetterPtr data_pipe_getter);
const std::vector<Element>* elements() const { return &elements_; }
std::vector<Element>* elements_mutable() { return &elements_; }
diff --git a/chromium/content/public/common/resource_request_completion_status.cc b/chromium/content/public/common/resource_request_completion_status.cc
deleted file mode 100644
index 26ad6acb3ab..00000000000
--- a/chromium/content/public/common/resource_request_completion_status.cc
+++ /dev/null
@@ -1,20 +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/resource_request_completion_status.h"
-
-#include "net/base/net_errors.h"
-
-namespace content {
-
-ResourceRequestCompletionStatus::ResourceRequestCompletionStatus() = default;
-ResourceRequestCompletionStatus::ResourceRequestCompletionStatus(
- const ResourceRequestCompletionStatus& status) = default;
-
-ResourceRequestCompletionStatus::ResourceRequestCompletionStatus(int error_code)
- : error_code(error_code), completion_time(base::TimeTicks::Now()) {}
-
-ResourceRequestCompletionStatus::~ResourceRequestCompletionStatus() = default;
-
-} // namespace content
diff --git a/chromium/content/public/common/resource_request_completion_status.h b/chromium/content/public/common/resource_request_completion_status.h
deleted file mode 100644
index a19fb24e14c..00000000000
--- a/chromium/content/public/common/resource_request_completion_status.h
+++ /dev/null
@@ -1,48 +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_RESOURCE_REQUEST_COMPLETION_STATUS_H_
-#define CONTENT_PUBLIC_COMMON_RESOURCE_REQUEST_COMPLETION_STATUS_H_
-
-#include <stdint.h>
-#include <string>
-
-#include "base/time/time.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-struct CONTENT_EXPORT ResourceRequestCompletionStatus {
- ResourceRequestCompletionStatus();
- ResourceRequestCompletionStatus(
- const ResourceRequestCompletionStatus& status);
-
- // Sets |error_code| to |error_code| and |completion_time| to
- // base::TimeTicks::Now().
- explicit ResourceRequestCompletionStatus(int error_code);
-
- ~ResourceRequestCompletionStatus();
-
- // The error code.
- int error_code = 0;
-
- // A copy of the data requested exists in the cache.
- bool exists_in_cache = false;
-
- // Time the request completed.
- base::TimeTicks completion_time;
-
- // Total amount of data received from the network.
- int64_t encoded_data_length = 0;
-
- // The length of the response body before removing any content encodings.
- int64_t encoded_body_length = 0;
-
- // The length of the response body after decoding.
- int64_t decoded_body_length = 0;
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_RESOURCE_REQUEST_COMPLETION_STATUS_H_
diff --git a/chromium/content/public/common/resource_response.cc b/chromium/content/public/common/resource_response.cc
index 1153d380916..e3e2a664472 100644
--- a/chromium/content/public/common/resource_response.cc
+++ b/chromium/content/public/common/resource_response.cc
@@ -41,8 +41,6 @@ scoped_refptr<ResourceResponse> ResourceResponse::DeepCopy() const {
new_response->head.socket_address = head.socket_address;
new_response->head.was_fetched_via_service_worker =
head.was_fetched_via_service_worker;
- new_response->head.was_fetched_via_foreign_fetch =
- head.was_fetched_via_foreign_fetch;
new_response->head.was_fallback_required_by_service_worker =
head.was_fallback_required_by_service_worker;
new_response->head.url_list_via_service_worker =
diff --git a/chromium/content/public/common/resource_response_info.cc b/chromium/content/public/common/resource_response_info.cc
index c1e853f2a06..8de8efad2df 100644
--- a/chromium/content/public/common/resource_response_info.cc
+++ b/chromium/content/public/common/resource_response_info.cc
@@ -22,7 +22,6 @@ ResourceResponseInfo::ResourceResponseInfo()
was_alternate_protocol_available(false),
connection_info(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN),
was_fetched_via_service_worker(false),
- was_fetched_via_foreign_fetch(false),
was_fallback_required_by_service_worker(false),
response_type_via_service_worker(
network::mojom::FetchResponseType::kDefault),
diff --git a/chromium/content/public/common/resource_response_info.h b/chromium/content/public/common/resource_response_info.h
index 73c50fd4899..3740425227d 100644
--- a/chromium/content/public/common/resource_response_info.h
+++ b/chromium/content/public/common/resource_response_info.h
@@ -115,9 +115,6 @@ struct CONTENT_EXPORT ResourceResponseInfo {
// True if the response was fetched by a ServiceWorker.
bool was_fetched_via_service_worker;
- // True if the response was fetched by a foreign fetch ServiceWorker;
- bool was_fetched_via_foreign_fetch;
-
// True when the request whoes mode is |CORS| or |CORS-with-forced-preflight|
// is sent to a ServiceWorker but FetchEvent.respondWith is not called. So the
// renderer have to resend the request with skip service worker flag
@@ -162,8 +159,7 @@ struct CONTENT_EXPORT ResourceResponseInfo {
std::vector<std::string> certificate;
// Bitmask of status info of the SSL certificate. See cert_status_flags.h for
- // values. Only present if the renderer process set report_raw_headers to
- // true.
+ // values.
net::CertStatus cert_status;
// Information about the SSL connection itself. See
diff --git a/chromium/content/public/common/sandbox_init.h b/chromium/content/public/common/sandbox_init.h
index cfe078b469d..b05b0332b9c 100644
--- a/chromium/content/public/common/sandbox_init.h
+++ b/chromium/content/public/common/sandbox_init.h
@@ -7,6 +7,7 @@
#include <memory>
+#include "base/callback_forward.h"
#include "base/files/scoped_file.h"
#include "base/memory/shared_memory.h"
#include "base/process/launch.h"
@@ -51,7 +52,7 @@ CONTENT_EXPORT bool InitializeSandbox(
// the handles.
CONTENT_EXPORT sandbox::ResultCode StartSandboxedProcess(
SandboxedProcessLauncherDelegate* delegate,
- base::CommandLine* cmd_line,
+ base::CommandLine* child_command_line,
const base::HandlesToInheritVector& handles_to_inherit,
base::Process* process);
@@ -67,6 +68,18 @@ CONTENT_EXPORT sandbox::ResultCode StartSandboxedProcess(
CONTENT_EXPORT bool InitializeSandbox(service_manager::SandboxType sandbox_type,
const base::FilePath& allowed_path);
+// Initialize the sandbox for renderer, gpu, utility, worker, and plugin
+// processes, depending on the command line flags. For the browser process which
+// is not sandboxed, this call is a no-op.
+// Returns true if the sandbox was initialized succesfully, false if an error
+// occurred. If process_type isn't one that needs sandboxing, true is always
+// returned.
+CONTENT_EXPORT bool InitializeSandbox();
+
+// Initializes the sandbox, as described above, but executes the callback after
+// warmup and before initialization.
+CONTENT_EXPORT bool InitializeSandbox(base::OnceClosure post_warmup_hook);
+
#elif defined(OS_LINUX) || defined(OS_NACL_NONSFI)
// Initialize a seccomp-bpf sandbox. |policy| may not be NULL.
diff --git a/chromium/content/public/common/sandbox_linux.h b/chromium/content/public/common/sandbox_linux.h
deleted file mode 100644
index acee4037e74..00000000000
--- a/chromium/content/public/common/sandbox_linux.h
+++ /dev/null
@@ -1,41 +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_SANDBOX_LINUX_H_
-#define CONTENT_PUBLIC_COMMON_SANDBOX_LINUX_H_
-
-namespace content {
-
-// These form a bitmask which describes the conditions of the Linux sandbox.
-// Note: this doesn't strictly give you the current status, it states
-// what will be enabled when the relevant processes are initialized.
-enum LinuxSandboxStatus {
- // SUID sandbox active.
- kSandboxLinuxSUID = 1 << 0,
-
- // Sandbox is using a new PID namespace.
- kSandboxLinuxPIDNS = 1 << 1,
-
- // Sandbox is using a new network namespace.
- kSandboxLinuxNetNS = 1 << 2,
-
- // seccomp-bpf sandbox active.
- kSandboxLinuxSeccompBPF = 1 << 3,
-
- // The Yama LSM module is present and enforcing.
- kSandboxLinuxYama = 1 << 4,
-
- // seccomp-bpf sandbox is active and the kernel supports TSYNC.
- kSandboxLinuxSeccompTSYNC = 1 << 5,
-
- // User namespace sandbox active.
- kSandboxLinuxUserNS = 1 << 6,
-
- // A flag that denotes an invalid sandbox status.
- kSandboxLinuxInvalid = 1 << 31,
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_SANDBOX_LINUX_H_
diff --git a/chromium/content/public/common/sandboxed_process_launcher_delegate.cc b/chromium/content/public/common/sandboxed_process_launcher_delegate.cc
index efe3134bcc6..1c65e1024d6 100644
--- a/chromium/content/public/common/sandboxed_process_launcher_delegate.cc
+++ b/chromium/content/public/common/sandboxed_process_launcher_delegate.cc
@@ -9,10 +9,6 @@
namespace content {
#if defined(OS_WIN)
-bool SandboxedProcessLauncherDelegate::ShouldLaunchElevated() {
- return false;
-}
-
bool SandboxedProcessLauncherDelegate::DisableDefaultPolicy() {
return false;
}
@@ -22,6 +18,13 @@ bool SandboxedProcessLauncherDelegate::PreSpawnTarget(
return true;
}
+void SandboxedProcessLauncherDelegate::PostSpawnTarget(
+ base::ProcessHandle process) {}
+
+bool SandboxedProcessLauncherDelegate::ShouldLaunchElevated() {
+ return false;
+}
+
#elif(OS_POSIX)
#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
diff --git a/chromium/content/public/common/sandboxed_process_launcher_delegate.h b/chromium/content/public/common/sandboxed_process_launcher_delegate.h
index 2764b17773f..ff9073c2a4f 100644
--- a/chromium/content/public/common/sandboxed_process_launcher_delegate.h
+++ b/chromium/content/public/common/sandboxed_process_launcher_delegate.h
@@ -5,45 +5,36 @@
#ifndef CONTENT_PUBLIC_COMMON_SANDBOXED_PROCESS_LAUNCHER_DELEGATE_H_
#define CONTENT_PUBLIC_COMMON_SANDBOXED_PROCESS_LAUNCHER_DELEGATE_H_
-#include <cstddef>
-
#include "base/environment.h"
#include "base/files/scoped_file.h"
#include "base/process/process.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/common/zygote_handle.h"
+#include "services/service_manager/sandbox/sandbox_delegate.h"
#include "services/service_manager/sandbox/sandbox_type.h"
-namespace sandbox {
-class TargetPolicy;
-}
-
namespace content {
// Allows a caller of StartSandboxedProcess or
// BrowserChildProcessHost/ChildProcessLauncher to control the sandbox policy,
// i.e. to loosen it if needed.
// The methods below will be called on the PROCESS_LAUNCHER thread.
-class CONTENT_EXPORT SandboxedProcessLauncherDelegate {
+class CONTENT_EXPORT SandboxedProcessLauncherDelegate
+ : public service_manager::SandboxDelegate {
public:
- virtual ~SandboxedProcessLauncherDelegate() {}
+ ~SandboxedProcessLauncherDelegate() override {}
#if defined(OS_WIN)
+ // SandboxDelegate:
+ bool DisableDefaultPolicy() override;
+ bool PreSpawnTarget(sandbox::TargetPolicy* policy) override;
+ void PostSpawnTarget(base::ProcessHandle process) override;
+
// Override to return true if the process should be launched as an elevated
// process (which implies no sandbox).
virtual bool ShouldLaunchElevated();
- // Whether to disable the default policy specified in
- // AddPolicyForSandboxedProcess.
- virtual bool DisableDefaultPolicy();
-
- // Called right before spawning the process. Returns false on failure.
- virtual bool PreSpawnTarget(sandbox::TargetPolicy* policy);
-
- // Called right after the process is launched, but before its thread is run.
- virtual void PostSpawnTarget(base::ProcessHandle process) {}
-
#elif defined(OS_POSIX)
#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
@@ -55,11 +46,7 @@ class CONTENT_EXPORT SandboxedProcessLauncherDelegate {
// Override this if the process needs a non-empty environment map.
virtual base::EnvironmentMap GetEnvironment();
-#endif
-
- // Returns the SandboxType to enforce on the process, or
- // SANDBOX_TYPE_NO_SANDBOX to run without a sandbox policy.
- virtual service_manager::SandboxType GetSandboxType() = 0;
+#endif // defined(OS_POSIX)
};
} // namespace content
diff --git a/chromium/content/public/common/screen_info.h b/chromium/content/public/common/screen_info.h
index a6ff7c7ff5e..d25d136493b 100644
--- a/chromium/content/public/common/screen_info.h
+++ b/chromium/content/public/common/screen_info.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_PUBLIC_COMMON_SCREEN_INFO_H_
#define CONTENT_PUBLIC_COMMON_SCREEN_INFO_H_
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/common/screen_orientation_values.h"
#include "ui/gfx/color_space.h"
@@ -27,8 +28,14 @@ struct CONTENT_EXPORT ScreenInfo {
// The color space of the output display.
gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
- // The ICC profile from which |color_space| was derived, if any.
+#if defined(OS_MACOSX)
+ // The ICC profile from which |color_space| was derived, if any. This is
+ // used only on macOS, to ensure that the color profile set on an IOSurface
+ // exactly match that of the display, when possible (because that has
+ // significant power implications).
+ // https://crbug.com/766736#c1
gfx::ICCProfile icc_profile;
+#endif
// The screen depth in bits per pixel
uint32_t depth = 0;
diff --git a/chromium/content/public/common/service_worker_modes.h b/chromium/content/public/common/service_worker_modes.h
index 2972579f20b..6459e174a0b 100644
--- a/chromium/content/public/common/service_worker_modes.h
+++ b/chromium/content/public/common/service_worker_modes.h
@@ -13,23 +13,6 @@ static const int kInvalidServiceWorkerProviderId = -1;
// The enum entries below are written to histograms and thus cannot be deleted
// or reordered.
// New entries must be added immediately before the end.
-enum FetchRequestMode {
- FETCH_REQUEST_MODE_SAME_ORIGIN,
- FETCH_REQUEST_MODE_NO_CORS,
- FETCH_REQUEST_MODE_CORS,
- FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT,
- FETCH_REQUEST_MODE_NAVIGATE,
- FETCH_REQUEST_MODE_LAST = FETCH_REQUEST_MODE_NAVIGATE
-};
-
-enum FetchCredentialsMode {
- FETCH_CREDENTIALS_MODE_OMIT,
- FETCH_CREDENTIALS_MODE_SAME_ORIGIN,
- FETCH_CREDENTIALS_MODE_INCLUDE,
- FETCH_CREDENTIALS_MODE_PASSWORD,
- FETCH_CREDENTIALS_MODE_LAST = FETCH_CREDENTIALS_MODE_PASSWORD
-};
-
enum class FetchRedirectMode {
FOLLOW_MODE,
ERROR_MODE,
@@ -37,24 +20,19 @@ enum class FetchRedirectMode {
LAST = MANUAL_MODE
};
-// Whether this is a regular fetch, or a foreign fetch request.
+// Whether this is a regular fetch, or a foreign fetch request (now removed).
// Duplicate of blink::mojom::ServiceWorkerFetchType.
-enum class ServiceWorkerFetchType {
- FETCH,
- FOREIGN_FETCH,
- LAST = FOREIGN_FETCH
-};
+// TODO(falken): Remove this since it's always FETCH.
+enum class ServiceWorkerFetchType { FETCH, LAST = FETCH };
-// Indicates which service workers will receive fetch events for this request.
+// Indicates whether service workers will receive fetch events for this request.
+// TODO(falken): This enum made more sense when there was a foreign fetch mode.
+// Find better names or fold this into a boolean.
enum class ServiceWorkerMode {
- // Relevant local and foreign service workers will get a fetch or
- // foreignfetch event for this request.
- ALL,
- // Only relevant foreign service workers will get a foreignfetch event for
- // this request.
- FOREIGN,
- // Neither local nor foreign service workers will get events for this
+ // The relevant service worker, if any, will get a fetch event for this
// request.
+ ALL,
+ // No service worker will get events for this request.
NONE,
LAST = NONE
};
diff --git a/chromium/content/public/common/simple_url_loader.cc b/chromium/content/public/common/simple_url_loader.cc
index 1cf3c637430..7c77f5c457c 100644
--- a/chromium/content/public/common/simple_url_loader.cc
+++ b/chromium/content/public/common/simple_url_loader.cc
@@ -17,6 +17,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "base/task_scheduler/post_task.h"
@@ -37,14 +38,167 @@ namespace content {
namespace {
-class SimpleURLLoaderImpl;
+// This file contains SimpleURLLoaderImpl, several BodyHandler implementations,
+// and BodyReader.
+//
+// SimpleURLLoaderImpl implements URLLoaderClient and drives the URLLoader.
+//
+// Each SimpleURLLoaderImpl creates a BodyHandler when the request is started.
+// The BodyHandler drives the body pipe, handles body data as needed (writes it
+// to a string, file, etc), and handles passing that data to the consumer's
+// callback.
+//
+// BodyReader is a utility class that BodyHandler implementations use to drive
+// the BodyPipe. This isn't handled by the SimpleURLLoader as some BodyHandlers
+// consume data off thread, so having it as a separate class allows the data
+// pipe to be used off thread, reducing use of the main thread.
+
+class BodyHandler;
-// BodyHandler is an abstract class from which classes for a specific use case
-// (e.g. read response to a string, write it to a file) will derive. Those
-// clases may use BodyReader to handle reading data from the body pipe.
+class SimpleURLLoaderImpl : public SimpleURLLoader,
+ public mojom::URLLoaderClient {
+ public:
+ SimpleURLLoaderImpl(std::unique_ptr<ResourceRequest> resource_request,
+ const net::NetworkTrafficAnnotationTag& annotation_tag);
+ ~SimpleURLLoaderImpl() override;
+
+ // SimpleURLLoader implementation.
+ void DownloadToString(mojom::URLLoaderFactory* url_loader_factory,
+ BodyAsStringCallback body_as_string_callback,
+ size_t max_body_size) override;
+ void DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+ mojom::URLLoaderFactory* url_loader_factory,
+ BodyAsStringCallback body_as_string_callback) override;
+ void DownloadToFile(
+ mojom::URLLoaderFactory* url_loader_factory,
+ DownloadToFileCompleteCallback download_to_file_complete_callback,
+ const base::FilePath& file_path,
+ int64_t max_body_size) override;
+ void DownloadToTempFile(
+ mojom::URLLoaderFactory* url_loader_factory,
+ DownloadToFileCompleteCallback download_to_file_complete_callback,
+ int64_t max_body_size) override;
+ void SetOnRedirectCallback(
+ const OnRedirectCallback& on_redirect_callback) override;
+ void SetAllowPartialResults(bool allow_partial_results) override;
+ void SetAllowHttpErrorResults(bool allow_http_error_results) override;
+ void SetRetryOptions(int max_retries, int retry_mode) override;
+ int NetError() const override;
+ const ResourceResponseHead* ResponseInfo() const override;
+
+ // Called by BodyHandler when the BodyHandler body handler is done. If |error|
+ // is not net::OK, some error occurred reading or consuming the body. If it is
+ // net::OK, the pipe was closed and all data received was successfully
+ // handled. This could indicate an error, concellation, or completion. To
+ // determine which case this is, the size will also be compared to the size
+ // reported in network::URLLoaderCompletionStatus(), if
+ // network::URLLoaderCompletionStatus indicates a success.
+ void OnBodyHandlerDone(net::Error error, int64_t received_body_size);
+
+ // Finished the request with the provided error code, after freeing Mojo
+ // resources. Closes any open pipes, so no URLLoader or BodyHandlers callbacks
+ // will be invoked after this is called.
+ void FinishWithResult(int net_error);
+
+ private:
+ // Per-request state values. This object is re-created for each retry.
+ // Separating out the values makes re-initializing them on retry simpler.
+ struct RequestState {
+ RequestState() = default;
+ ~RequestState() = default;
+
+ bool request_completed = false;
+ // The expected total size of the body, taken from
+ // network::URLLoaderCompletionStatus.
+ int64_t expected_body_size = 0;
+
+ bool body_started = false;
+ bool body_completed = false;
+ // Final size of the body. Set once the body's Mojo pipe has been closed.
+ int64_t received_body_size = 0;
+
+ // Set to true when FinishWithResult() is called. Once that happens, the
+ // consumer is informed of completion, and both pipes are closed.
+ bool finished = false;
+
+ // Result of the request.
+ int net_error = net::ERR_IO_PENDING;
+
+ std::unique_ptr<ResourceResponseHead> response_info;
+ };
+
+ // Prepares internal state to start a request, and then calls StartRequest().
+ // Only used for the initial request (Not retries).
+ void Start(mojom::URLLoaderFactory* url_loader_factory);
+
+ // Starts a request. Used for both the initial request and retries, if any.
+ void StartRequest(mojom::URLLoaderFactory* url_loader_factory);
+
+ // Re-initializes state of |this| and |body_handler_| prior to retrying a
+ // request.
+ void Retry();
+
+ // mojom::URLLoaderClient implementation;
+ void OnReceiveResponse(const ResourceResponseHead& response_head,
+ const base::Optional<net::SSLInfo>& ssl_info,
+ mojom::DownloadedTempFilePtr downloaded_file) override;
+ void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& response_head) override;
+ void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override;
+ void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override;
+ void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
+ void OnUploadProgress(int64_t current_position,
+ int64_t total_size,
+ OnUploadProgressCallback ack_callback) override;
+ void OnStartLoadingResponseBody(
+ mojo::ScopedDataPipeConsumerHandle body) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
+
+ // Bound to the URLLoaderClient message pipe (|client_binding_|) via
+ // set_connection_error_handler.
+ void OnConnectionError();
+
+ // Completes the request by calling FinishWithResult() if OnComplete() was
+ // called and either no body pipe was ever received, or the body pipe was
+ // closed.
+ void MaybeComplete();
+
+ OnRedirectCallback on_redirect_callback_;
+ bool allow_partial_results_ = false;
+ bool allow_http_error_results_ = false;
+
+ // Information related to retrying.
+ int remaining_retries_ = 0;
+ int retry_mode_ = RETRY_NEVER;
+
+ // The next values contain all the information required to restart the
+ // request.
+
+ // Populated in the constructor, and cleared once no longer needed, when no
+ // more retries are possible.
+ std::unique_ptr<ResourceRequest> resource_request_;
+ const net::NetworkTrafficAnnotationTag annotation_tag_;
+ // Cloned from the input URLLoaderFactory if it may be needed to follow
+ // redirects.
+ content::mojom::URLLoaderFactoryPtr url_loader_factory_ptr_;
+ std::unique_ptr<BodyHandler> body_handler_;
+
+ mojo::Binding<mojom::URLLoaderClient> client_binding_;
+ mojom::URLLoaderPtr url_loader_;
+
+ // Per-request state. Always non-null, but re-created on redirect.
+ std::unique_ptr<RequestState> request_state_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+
+ base::WeakPtrFactory<SimpleURLLoaderImpl> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(SimpleURLLoaderImpl);
+};
// Utility class to drive the pipe reading a response body. Can be created on
-// one thread and then used to read data on another.
+// one thread and then used to read data on another. A BodyReader may only be
+// used once. If a request is retried, a new one must be created.
class BodyReader {
public:
class Delegate {
@@ -194,6 +348,13 @@ class BodyHandler {
// being sent to the consumer.
virtual void NotifyConsumerOfCompletion(bool destroy_results) = 0;
+ // Called before retrying a request. Only called either before receiving a
+ // body pipe, or after the body pipe has been closed, so there should be no
+ // pending callbacks when invoked. |retry_callback| should be invoked when
+ // the BodyHandler is ready for the request to be retried. Callback may be
+ // invoked synchronously.
+ virtual void PrepareToRetry(base::OnceClosure retry_callback) = 0;
+
protected:
SimpleURLLoaderImpl* simple_url_loader() { return simple_url_loader_; }
@@ -212,20 +373,51 @@ class SaveToStringBodyHandler : public BodyHandler,
SimpleURLLoader::BodyAsStringCallback body_as_string_callback,
int64_t max_body_size)
: BodyHandler(simple_url_loader),
- body_as_string_callback_(std::move(body_as_string_callback)),
- body_reader_(std::make_unique<BodyReader>(this, max_body_size)) {}
+ max_body_size_(max_body_size),
+ body_as_string_callback_(std::move(body_as_string_callback)) {}
~SaveToStringBodyHandler() override {}
// BodyHandler implementation:
+
void OnStartLoadingResponseBody(
- mojo::ScopedDataPipeConsumerHandle body_data_pipe) override;
- void NotifyConsumerOfCompletion(bool destroy_results) override;
+ mojo::ScopedDataPipeConsumerHandle body_data_pipe) override {
+ DCHECK(!body_);
+ DCHECK(!body_reader_);
+
+ body_ = std::make_unique<std::string>();
+ body_reader_ = std::make_unique<BodyReader>(this, max_body_size_);
+ body_reader_->Start(std::move(body_data_pipe));
+ }
+
+ void NotifyConsumerOfCompletion(bool destroy_results) override {
+ body_reader_.reset();
+ if (destroy_results)
+ body_.reset();
+
+ std::move(body_as_string_callback_).Run(std::move(body_));
+ }
+
+ void PrepareToRetry(base::OnceClosure retry_callback) override {
+ body_.reset();
+ body_reader_.reset();
+ std::move(retry_callback).Run();
+ }
private:
// BodyReader::Delegate implementation.
- net::Error OnDataRead(uint32_t length, const char* data) override;
- void OnDone(net::Error error, int64_t total_bytes) override;
+
+ net::Error OnDataRead(uint32_t length, const char* data) override {
+ body_->append(data, length);
+ return net::OK;
+ }
+
+ void OnDone(net::Error error, int64_t total_bytes) override {
+ DCHECK_EQ(body_->size(), static_cast<size_t>(total_bytes));
+ simple_url_loader()->OnBodyHandlerDone(error, total_bytes);
+ }
+
+ const int64_t max_body_size_;
std::unique_ptr<std::string> body_;
SimpleURLLoader::BodyAsStringCallback body_as_string_callback_;
@@ -240,17 +432,21 @@ class SaveToFileBodyHandler : public BodyHandler {
public:
// |net_priority| is the priority from the ResourceRequest, and is used to
// determine the TaskPriority of the sequence used to read from the response
- // body and write to the file.
+ // body and write to the file. If |create_temp_file| is true, a temp file is
+ // created instead of using |path|.
SaveToFileBodyHandler(SimpleURLLoaderImpl* simple_url_loader,
SimpleURLLoader::DownloadToFileCompleteCallback
download_to_file_complete_callback,
const base::FilePath& path,
+ bool create_temp_file,
uint64_t max_body_size,
net::RequestPriority request_priority)
: BodyHandler(simple_url_loader),
download_to_file_complete_callback_(
std::move(download_to_file_complete_callback)),
weak_ptr_factory_(this) {
+ DCHECK(create_temp_file || !path.empty());
+
// Choose the TaskPriority based on the net request priority.
// TODO(mmenke): Can something better be done here?
base::TaskPriority task_priority;
@@ -263,14 +459,18 @@ class SaveToFileBodyHandler : public BodyHandler {
}
// Can only do this after initializing the WeakPtrFactory.
- file_writer_ =
- std::make_unique<FileWriter>(path, max_body_size, task_priority);
+ file_writer_ = std::make_unique<FileWriter>(path, create_temp_file,
+ max_body_size, task_priority);
}
~SaveToFileBodyHandler() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (file_writer_)
- FileWriter::Destroy(std::move(file_writer_), base::OnceClosure());
+ if (file_writer_) {
+ // |file_writer_| is only non-null at this point if any downloaded file
+ // wasn't passed to the consumer. Destroy any partially downloaded file.
+ file_writer_->DeleteFile(base::OnceClosure());
+ FileWriter::Destroy(std::move(file_writer_));
+ }
}
// BodyHandler implementation:
@@ -293,17 +493,32 @@ class SaveToFileBodyHandler : public BodyHandler {
// To avoid any issues if the consumer tries to re-download a file to the
// same location, don't invoke the callback until any partially downloaded
// file has been destroyed.
- FileWriter::Destroy(
- std::move(file_writer_),
+ file_writer_->DeleteFile(
base::Bind(&SaveToFileBodyHandler::InvokeCallbackAsynchronously,
weak_ptr_factory_.GetWeakPtr()));
+ FileWriter::Destroy(std::move(file_writer_));
return;
}
- file_writer_->ReleaseFile();
+ // Destroy the |file_writer_|, so the file won't be destroyed in |this|'s
+ // destructor.
+ FileWriter::Destroy(std::move(file_writer_));
+
std::move(download_to_file_complete_callback_).Run(path_);
}
+ void PrepareToRetry(base::OnceClosure retry_callback) override {
+ // |file_writer_| is only destroyed when notifying the consumer of
+ // completion and in the destructor. After either of those happens, a
+ // request should not be retried.
+ DCHECK(file_writer_);
+
+ // Delete file and wait for it to be destroyed, so if the retry fails
+ // before trying to create a new file, the consumer will still only be
+ // notified of completion after the file is destroyed.
+ file_writer_->DeleteFile(std::move(retry_callback));
+ }
+
private:
// Class to read from a mojo::ScopedDataPipeConsumerHandle and write the
// contents to a file. Does all reading and writing on a separate file
@@ -311,31 +526,33 @@ class SaveToFileBodyHandler : public BodyHandler {
// BodyHandler's TaskRunner. All private methods and the destructor are run
// on the file TaskRunner.
//
- // Destroys the file that it's saving to on destruction, unless ReleaseFile()
- // is called first, so on cancellation and errors, the default behavior is to
- // clean up after itself.
- //
// FileWriter is owned by the SaveToFileBodyHandler and destroyed by a task
// moving its unique_ptr to the |file_writer_task_runner_|. As a result, tasks
// posted to |file_writer_task_runner_| can always use base::Unretained. Tasks
// posted the other way, however, require the SaveToFileBodyHandler to use
// WeakPtrs, since the SaveToFileBodyHandler can be destroyed at any time.
+ //
+ // When a request is retried, the FileWriter deletes any partially downloaded
+ // file, and is then reused.
class FileWriter : public BodyReader::Delegate {
public:
using OnDoneCallback = base::OnceCallback<void(net::Error error,
int64_t total_bytes,
const base::FilePath& path)>;
- explicit FileWriter(const base::FilePath& path,
- int64_t max_body_size,
- base::TaskPriority priority)
+ FileWriter(const base::FilePath& path,
+ bool create_temp_file,
+ int64_t max_body_size,
+ base::TaskPriority priority)
: body_handler_task_runner_(base::SequencedTaskRunnerHandle::Get()),
file_writer_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), priority,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN})),
path_(path),
- body_reader_(std::make_unique<BodyReader>(this, max_body_size)) {
+ create_temp_file_(create_temp_file),
+ max_body_size_(max_body_size) {
DCHECK(body_handler_task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(create_temp_file_ || !path_.empty());
}
// Starts reading from |body_data_pipe| and writing to the file.
@@ -349,44 +566,37 @@ class SaveToFileBodyHandler : public BodyHandler {
std::move(on_done_callback)));
}
- // Releases ownership of the downloaded file. If not called before
- // destruction, file will automatically be destroyed in the destructor.
- void ReleaseFile() {
+ // Deletes any partially downloaded file, and closes the body pipe, if open.
+ // Must be called if SaveToFileBodyHandler's OnDone() method is never
+ // invoked, to avoid keeping around partial downloads that were never passed
+ // to the consumer.
+ //
+ // If |on_file_deleted_closure| is non-null, it will be invoked on the
+ // caller's task runner once the file has been deleted.
+ void DeleteFile(base::OnceClosure on_file_deleted_closure) {
DCHECK(body_handler_task_runner_->RunsTasksInCurrentSequence());
file_writer_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&FileWriter::ReleaseFileOnFileSequence,
- base::Unretained(this)));
+ FROM_HERE, base::BindOnce(&FileWriter::DeleteFileOnFileSequence,
+ base::Unretained(this),
+ std::move(on_file_deleted_closure)));
}
// Destroys the FileWriter on the file TaskRunner.
- //
- // If |on_destroyed_closure| is non-null, it will be invoked on the caller's
- // task runner once the FileWriter has been destroyed.
- static void Destroy(std::unique_ptr<FileWriter> file_writer,
- base::OnceClosure on_destroyed_closure) {
+ static void Destroy(std::unique_ptr<FileWriter> file_writer) {
DCHECK(
file_writer->body_handler_task_runner_->RunsTasksInCurrentSequence());
+
// Have to stash this pointer before posting a task, since |file_writer|
// is bound to the callback that's posted to the TaskRunner.
base::SequencedTaskRunner* task_runner =
file_writer->file_writer_task_runner_.get();
-
- task_runner->PostTask(FROM_HERE,
- base::BindOnce(&FileWriter::DestroyOnFileSequence,
- std::move(file_writer),
- std::move(on_destroyed_closure)));
+ task_runner->DeleteSoon(FROM_HERE, std::move(file_writer));
}
// Destructor is only public so the consumer can keep it in a unique_ptr.
// Class must be destroyed by using Destroy().
~FileWriter() override {
DCHECK(file_writer_task_runner_->RunsTasksInCurrentSequence());
- file_.Close();
-
- if (owns_file_) {
- DCHECK(!path_.empty());
- base::DeleteFile(path_, false /* recursive */);
- }
}
private:
@@ -395,10 +605,24 @@ class SaveToFileBodyHandler : public BodyHandler {
OnDoneCallback on_done_callback) {
DCHECK(file_writer_task_runner_->RunsTasksInCurrentSequence());
DCHECK(!file_.IsValid());
+ DCHECK(!body_reader_);
+
+ bool have_path = !create_temp_file_;
+ if (!have_path) {
+ DCHECK(create_temp_file_);
+ have_path = base::CreateTemporaryFile(&path_);
+ // CreateTemporaryFile() creates an empty file.
+ if (have_path)
+ owns_file_ = true;
+ }
+
+ if (have_path) {
+ // Try to initialize |file_|, creating the file if needed.
+ file_.Initialize(
+ path_, base::File::FLAG_WRITE | base::File::FLAG_CREATE_ALWAYS);
+ }
- // Try to create the file.
- file_.Initialize(path_,
- base::File::FLAG_WRITE | base::File::FLAG_CREATE_ALWAYS);
+ // If CreateTemporaryFile() or File::Initialize() failed, report failure.
if (!file_.IsValid()) {
body_handler_task_runner_->PostTask(
FROM_HERE, base::BindOnce(std::move(on_done_callback),
@@ -410,6 +634,7 @@ class SaveToFileBodyHandler : public BodyHandler {
on_done_callback_ = std::move(on_done_callback);
owns_file_ = true;
+ body_reader_ = std::make_unique<BodyReader>(this, max_body_size_);
body_reader_->Start(std::move(body_data_pipe));
}
@@ -437,34 +662,36 @@ class SaveToFileBodyHandler : public BodyHandler {
// Close the file so that there's no ownership contention when the
// consumer uses it.
file_.Close();
+ body_reader_.reset();
body_handler_task_runner_->PostTask(
FROM_HERE, base::BindOnce(std::move(on_done_callback_), error,
total_bytes, path_));
}
- // Closes the file, so it won't be deleted on destruction.
- void ReleaseFileOnFileSequence() {
+ void DeleteFileOnFileSequence(base::OnceClosure on_file_deleted_closure) {
DCHECK(file_writer_task_runner_->RunsTasksInCurrentSequence());
- owns_file_ = false;
- }
- static void DestroyOnFileSequence(std::unique_ptr<FileWriter> file_writer,
- base::OnceClosure on_destroyed_closure) {
- DCHECK(
- file_writer->file_writer_task_runner_->RunsTasksInCurrentSequence());
+ if (owns_file_) {
+ // Close the file before deleting it, if it's still open.
+ file_.Close();
+
+ // Close the body pipe.
+ body_reader_.reset();
+
+ // May as well clean this up, too.
+ on_done_callback_.Reset();
- // Need to grab this before deleting |file_writer|.
- scoped_refptr<base::SequencedTaskRunner> body_handler_task_runner =
- file_writer->body_handler_task_runner_;
+ DCHECK(!path_.empty());
+ base::DeleteFile(path_, false /* recursive */);
- // Need to delete |FileWriter| before posting a task to invoke the
- // callback.
- file_writer.reset();
+ owns_file_ = false;
+ }
- if (on_destroyed_closure)
- body_handler_task_runner->PostTask(FROM_HERE,
- std::move(on_destroyed_closure));
+ if (on_file_deleted_closure) {
+ body_handler_task_runner_->PostTask(FROM_HERE,
+ std::move(on_file_deleted_closure));
+ }
}
// These are set on cosntruction and accessed on both task runners.
@@ -475,6 +702,9 @@ class SaveToFileBodyHandler : public BodyHandler {
// |file_writer_task_runner_|.
base::FilePath path_;
+ const bool create_temp_file_;
+ const int64_t max_body_size_;
+
// File being downloaded to. Created just before reading from the data pipe.
base::File file_;
@@ -482,8 +712,8 @@ class SaveToFileBodyHandler : public BodyHandler {
std::unique_ptr<BodyReader> body_reader_;
- // If true, destroys the file in the destructor. Set to true once the file
- // is created.
+ // True if a file was successfully created. Set to false when the file is
+ // destroyed.
bool owns_file_ = false;
DISALLOW_COPY_AND_ASSIGN(FileWriter);
@@ -497,7 +727,10 @@ class SaveToFileBodyHandler : public BodyHandler {
void OnDone(net::Error error,
int64_t total_bytes,
- const base::FilePath& path);
+ const base::FilePath& path) {
+ path_ = path;
+ simple_url_loader()->OnBodyHandlerDone(error, total_bytes);
+ }
// Path of the file. Set in OnDone().
base::FilePath path_;
@@ -514,145 +747,14 @@ class SaveToFileBodyHandler : public BodyHandler {
DISALLOW_COPY_AND_ASSIGN(SaveToFileBodyHandler);
};
-class SimpleURLLoaderImpl : public SimpleURLLoader,
- public mojom::URLLoaderClient {
- public:
- SimpleURLLoaderImpl();
- ~SimpleURLLoaderImpl() override;
-
- // SimpleURLLoader implementation.
- void DownloadToString(const ResourceRequest& resource_request,
- mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag,
- BodyAsStringCallback body_as_string_callback,
- size_t max_body_size) override;
- void DownloadToStringOfUnboundedSizeUntilCrashAndDie(
- const ResourceRequest& resource_request,
- mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag,
- BodyAsStringCallback body_as_string_callback) override;
- void DownloadToFile(
- const ResourceRequest& resource_request,
- mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag,
- DownloadToFileCompleteCallback download_to_file_complete_callback,
- const base::FilePath& file_path,
- int64_t max_body_size) override;
- void SetAllowPartialResults(bool allow_partial_results) override;
- void SetAllowHttpErrorResults(bool allow_http_error_results) override;
- int NetError() const override;
- const ResourceResponseHead* ResponseInfo() const override;
-
- // Called by BodyHandler when the BodyHandler body handler is done. If |error|
- // is not net::OK, some error occurred reading or consuming the body. If it is
- // net::OK, the pipe was closed and all data received was successfully
- // handled. This could indicate an error, concellation, or completion. To
- // determine which case this is, the size will also be compared to the size
- // reported in ResourceRequestCompletionStatus(), if
- // ResourceRequestCompletionStatus indicates a success.
- void OnBodyHandlerDone(net::Error error, int64_t received_body_size);
-
- // Finished the request with the provided error code, after freeing Mojo
- // resources. Closes any open pipes, so no URLLoader or BodyHandlers callbacks
- // will be invoked after this is called.
- void FinishWithResult(int net_error);
-
- private:
- void StartInternal(const ResourceRequest& resource_request,
- mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag);
-
- // mojom::URLLoaderClient implementation;
- void OnReceiveResponse(const ResourceResponseHead& response_head,
- const base::Optional<net::SSLInfo>& ssl_info,
- mojom::DownloadedTempFilePtr downloaded_file) override;
- void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
- const ResourceResponseHead& response_head) override;
- void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override;
- void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override;
- void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
- void OnUploadProgress(int64_t current_position,
- int64_t total_size,
- OnUploadProgressCallback ack_callback) override;
- void OnStartLoadingResponseBody(
- mojo::ScopedDataPipeConsumerHandle body) override;
- void OnComplete(const ResourceRequestCompletionStatus& status) override;
-
- // Bound to the URLLoaderClient message pipe (|client_binding_|) via
- // set_connection_error_handler.
- void OnConnectionError();
-
- // Completes the request by calling FinishWithResult() if OnComplete() was
- // called and either no body pipe was ever received, or the body pipe was
- // closed.
- void MaybeComplete();
-
- bool allow_partial_results_ = false;
- bool allow_http_error_results_ = false;
-
- mojom::URLLoaderPtr url_loader_;
- mojo::Binding<mojom::URLLoaderClient> client_binding_;
- std::unique_ptr<BodyHandler> body_handler_;
-
- bool request_completed_ = false;
- // The expected total size of the body, taken from
- // ResourceRequestCompletionStatus.
- int64_t expected_body_size_ = 0;
-
- bool body_started_ = false;
- bool body_completed_ = false;
- // Final size of the body. Set once the body's Mojo pipe has been closed.
- int64_t received_body_size_ = 0;
-
- // Set to true when FinishWithResult() is called. Once that happens, the
- // consumer is informed of completion, and both pipes are closed.
- bool finished_ = false;
-
- // Result of the request.
- int net_error_ = net::ERR_IO_PENDING;
-
- std::unique_ptr<ResourceResponseHead> response_info_;
-
- SEQUENCE_CHECKER(sequence_checker_);
-
- DISALLOW_COPY_AND_ASSIGN(SimpleURLLoaderImpl);
-};
-
-void SaveToStringBodyHandler::OnStartLoadingResponseBody(
- mojo::ScopedDataPipeConsumerHandle body_data_pipe) {
- DCHECK(!body_);
-
- body_ = base::MakeUnique<std::string>();
- body_reader_->Start(std::move(body_data_pipe));
-}
-
-net::Error SaveToStringBodyHandler::OnDataRead(uint32_t length,
- const char* data) {
- body_->append(data, length);
- return net::OK;
-}
-
-void SaveToStringBodyHandler::OnDone(net::Error error, int64_t total_bytes) {
- DCHECK_EQ(body_->size(), static_cast<size_t>(total_bytes));
- simple_url_loader()->OnBodyHandlerDone(error, total_bytes);
-}
-
-void SaveToStringBodyHandler::NotifyConsumerOfCompletion(bool destroy_results) {
- body_reader_.reset();
- if (destroy_results)
- body_.reset();
-
- std::move(body_as_string_callback_).Run(std::move(body_));
-}
-
-void SaveToFileBodyHandler::OnDone(net::Error error,
- int64_t total_bytes,
- const base::FilePath& path) {
- path_ = path;
- simple_url_loader()->OnBodyHandlerDone(error, total_bytes);
-}
-
-SimpleURLLoaderImpl::SimpleURLLoaderImpl() : client_binding_(this) {
+SimpleURLLoaderImpl::SimpleURLLoaderImpl(
+ std::unique_ptr<ResourceRequest> resource_request,
+ const net::NetworkTrafficAnnotationTag& annotation_tag)
+ : resource_request_(std::move(resource_request)),
+ annotation_tag_(annotation_tag),
+ client_binding_(this),
+ request_state_(std::make_unique<RequestState>()),
+ weak_ptr_factory_(this) {
// Allow creation and use on different threads.
DETACH_FROM_SEQUENCE(sequence_checker_);
}
@@ -660,74 +762,95 @@ SimpleURLLoaderImpl::SimpleURLLoaderImpl() : client_binding_(this) {
SimpleURLLoaderImpl::~SimpleURLLoaderImpl() {}
void SimpleURLLoaderImpl::DownloadToString(
- const ResourceRequest& resource_request,
mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag,
BodyAsStringCallback body_as_string_callback,
size_t max_body_size) {
DCHECK_LE(max_body_size, kMaxBoundedStringDownloadSize);
- body_handler_ = base::MakeUnique<SaveToStringBodyHandler>(
+ body_handler_ = std::make_unique<SaveToStringBodyHandler>(
this, std::move(body_as_string_callback), max_body_size);
- StartInternal(resource_request, url_loader_factory, annotation_tag);
+ Start(url_loader_factory);
}
void SimpleURLLoaderImpl::DownloadToStringOfUnboundedSizeUntilCrashAndDie(
- const ResourceRequest& resource_request,
mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag,
BodyAsStringCallback body_as_string_callback) {
- body_handler_ = base::MakeUnique<SaveToStringBodyHandler>(
+ body_handler_ = std::make_unique<SaveToStringBodyHandler>(
this, std::move(body_as_string_callback),
- // int64_t because ResourceRequestCompletionStatus::decoded_body_length is
- // an int64_t, not a size_t.
+ // int64_t because network::URLLoaderCompletionStatus::decoded_body_length
+ // is an int64_t, not a size_t.
std::numeric_limits<int64_t>::max());
- StartInternal(resource_request, url_loader_factory, annotation_tag);
+ Start(url_loader_factory);
}
void SimpleURLLoaderImpl::DownloadToFile(
- const ResourceRequest& resource_request,
mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag,
DownloadToFileCompleteCallback download_to_file_complete_callback,
const base::FilePath& file_path,
int64_t max_body_size) {
+ DCHECK(!file_path.empty());
body_handler_ = std::make_unique<SaveToFileBodyHandler>(
this, std::move(download_to_file_complete_callback), file_path,
- max_body_size, resource_request.priority);
- StartInternal(resource_request, url_loader_factory, annotation_tag);
+ false /* create_temp_file */, max_body_size, resource_request_->priority);
+ Start(url_loader_factory);
+}
+
+void SimpleURLLoaderImpl::DownloadToTempFile(
+ mojom::URLLoaderFactory* url_loader_factory,
+ DownloadToFileCompleteCallback download_to_file_complete_callback,
+ int64_t max_body_size) {
+ body_handler_ = std::make_unique<SaveToFileBodyHandler>(
+ this, std::move(download_to_file_complete_callback), base::FilePath(),
+ true /* create_temp_file */, max_body_size, resource_request_->priority);
+ Start(url_loader_factory);
+}
+
+void SimpleURLLoaderImpl::SetOnRedirectCallback(
+ const OnRedirectCallback& on_redirect_callback) {
+ on_redirect_callback_ = on_redirect_callback;
}
void SimpleURLLoaderImpl::SetAllowPartialResults(bool allow_partial_results) {
- // Simplest way to check if a request has not yet been started.
+ // Check if a request has not yet been started.
DCHECK(!body_handler_);
allow_partial_results_ = allow_partial_results;
}
void SimpleURLLoaderImpl::SetAllowHttpErrorResults(
bool allow_http_error_results) {
- // Simplest way to check if a request has not yet been started.
+ // Check if a request has not yet been started.
DCHECK(!body_handler_);
allow_http_error_results_ = allow_http_error_results;
}
+void SimpleURLLoaderImpl::SetRetryOptions(int max_retries, int retry_mode) {
+ // Check if a request has not yet been started.
+ DCHECK(!body_handler_);
+ DCHECK_GE(max_retries, 0);
+ // Non-zero |max_retries| makes no sense when retries are disabled.
+ DCHECK(max_retries > 0 || retry_mode == RETRY_NEVER);
+
+ remaining_retries_ = max_retries;
+ retry_mode_ = retry_mode;
+}
+
int SimpleURLLoaderImpl::NetError() const {
// Should only be called once the request is compelete.
- DCHECK(finished_);
- DCHECK_NE(net::ERR_IO_PENDING, net_error_);
- return net_error_;
+ DCHECK(request_state_->finished);
+ DCHECK_NE(net::ERR_IO_PENDING, request_state_->net_error);
+ return request_state_->net_error;
}
const ResourceResponseHead* SimpleURLLoaderImpl::ResponseInfo() const {
// Should only be called once the request is compelete.
- DCHECK(finished_);
- return response_info_.get();
+ DCHECK(request_state_->finished);
+ return request_state_->response_info.get();
}
void SimpleURLLoaderImpl::OnBodyHandlerDone(net::Error error,
int64_t received_body_size) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(body_started_);
- DCHECK(!body_completed_);
+ DCHECK(request_state_->body_started);
+ DCHECK(!request_state_->body_completed);
// If there's an error, fail request and report it immediately.
if (error != net::OK) {
@@ -737,34 +860,49 @@ void SimpleURLLoaderImpl::OnBodyHandlerDone(net::Error error,
// Otherwise, need to wait until the URLRequestClient pipe receives a complete
// message or is closed, to determine if the entire body was received.
- body_completed_ = true;
- received_body_size_ = received_body_size;
+ request_state_->body_completed = true;
+ request_state_->received_body_size = received_body_size;
MaybeComplete();
}
void SimpleURLLoaderImpl::FinishWithResult(int net_error) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(!finished_);
+ DCHECK(!request_state_->finished);
client_binding_.Close();
url_loader_.reset();
- finished_ = true;
- net_error_ = net_error;
+ request_state_->finished = true;
+ request_state_->net_error = net_error;
// If it's a partial download or an error was received, erase the body.
- bool destroy_results = net_error_ != net::OK && !allow_partial_results_;
+ bool destroy_results =
+ request_state_->net_error != net::OK && !allow_partial_results_;
body_handler_->NotifyConsumerOfCompletion(destroy_results);
}
-void SimpleURLLoaderImpl::StartInternal(
- const ResourceRequest& resource_request,
- mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag) {
+void SimpleURLLoaderImpl::Start(mojom::URLLoaderFactory* url_loader_factory) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(resource_request_);
// It's illegal to use a single SimpleURLLoaderImpl to make multiple requests.
- DCHECK(!finished_);
+ DCHECK(!request_state_->finished);
DCHECK(!url_loader_);
- DCHECK(!body_started_);
+ DCHECK(!request_state_->body_started);
+
+ // If retries are enabled, stash the information needed to retry a request.
+ if (remaining_retries_ > 0) {
+ // Clone the URLLoaderFactory, to avoid any dependencies on its lifetime.
+ // Results in an easier to use API, with no shutdown ordering requirements,
+ // at the cost of some resources.
+ url_loader_factory->Clone(mojo::MakeRequest(&url_loader_factory_ptr_));
+ }
+
+ StartRequest(url_loader_factory);
+}
+
+void SimpleURLLoaderImpl::StartRequest(
+ mojom::URLLoaderFactory* url_loader_factory) {
+ DCHECK(resource_request_);
+ DCHECK(url_loader_factory);
mojom::URLLoaderClientPtr client_ptr;
client_binding_.Bind(mojo::MakeRequest(&client_ptr));
@@ -772,8 +910,30 @@ void SimpleURLLoaderImpl::StartInternal(
&SimpleURLLoaderImpl::OnConnectionError, base::Unretained(this)));
url_loader_factory->CreateLoaderAndStart(
mojo::MakeRequest(&url_loader_), 0 /* routing_id */, 0 /* request_id */,
- 0 /* options */, resource_request, std::move(client_ptr),
- net::MutableNetworkTrafficAnnotationTag(annotation_tag));
+ 0 /* options */, *resource_request_, std::move(client_ptr),
+ net::MutableNetworkTrafficAnnotationTag(annotation_tag_));
+
+ // If no more retries left, can clean up a little.
+ if (remaining_retries_ == 0) {
+ resource_request_.reset();
+ url_loader_factory_ptr_.reset();
+ }
+}
+
+void SimpleURLLoaderImpl::Retry() {
+ DCHECK(resource_request_);
+ DCHECK(url_loader_factory_ptr_);
+ DCHECK_GT(remaining_retries_, 0);
+ --remaining_retries_;
+
+ client_binding_.Close();
+ url_loader_.reset();
+
+ request_state_ = std::make_unique<RequestState>();
+
+ body_handler_->PrepareToRetry(base::Bind(&SimpleURLLoaderImpl::StartRequest,
+ weak_ptr_factory_.GetWeakPtr(),
+ url_loader_factory_ptr_.get()));
}
void SimpleURLLoaderImpl::OnReceiveResponse(
@@ -781,30 +941,54 @@ void SimpleURLLoaderImpl::OnReceiveResponse(
const base::Optional<net::SSLInfo>& ssl_info,
mojom::DownloadedTempFilePtr downloaded_file) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (response_info_) {
+ if (request_state_->response_info) {
// The final headers have already been received, so the URLLoader is
// violating the API contract.
FinishWithResult(net::ERR_UNEXPECTED);
return;
}
- response_info_ = base::MakeUnique<ResourceResponseHead>(response_head);
- if (!allow_http_error_results_ && response_head.headers &&
- response_head.headers->response_code() / 100 != 2) {
- FinishWithResult(net::ERR_FAILED);
+ // Assume a 200 response unless headers were received indicating otherwise.
+ // No headers indicates this was not a real HTTP response (Could be a file
+ // URL, FTP, response could have been provided by something else, etc).
+ int response_code = 200;
+ if (response_head.headers)
+ response_code = response_head.headers->response_code();
+
+ // If a 5xx response was received, and |this| should retry on 5xx errors,
+ // retry the request.
+ if (response_code / 100 == 5 && remaining_retries_ > 0 &&
+ (retry_mode_ & RETRY_ON_5XX)) {
+ Retry();
+ return;
}
+
+ request_state_->response_info =
+ std::make_unique<ResourceResponseHead>(response_head);
+ if (!allow_http_error_results_ && response_code / 100 != 2)
+ FinishWithResult(net::ERR_FAILED);
}
void SimpleURLLoaderImpl::OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const ResourceResponseHead& response_head) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (response_info_) {
+ if (request_state_->response_info) {
// If the headers have already been received, the URLLoader is violating the
// API contract.
FinishWithResult(net::ERR_UNEXPECTED);
return;
}
+
+ if (on_redirect_callback_) {
+ base::WeakPtr<SimpleURLLoaderImpl> weak_this =
+ weak_ptr_factory_.GetWeakPtr();
+ on_redirect_callback_.Run(redirect_info, response_head);
+ // If deleted by the callback, bail now.
+ if (!weak_this)
+ return;
+ }
+
url_loader_->FollowRedirect();
}
@@ -828,34 +1012,34 @@ void SimpleURLLoaderImpl::OnUploadProgress(
void SimpleURLLoaderImpl::OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (body_started_ || !response_info_) {
+ if (request_state_->body_started || !request_state_->response_info) {
// If this was already called, or the headers have not yet been received,
// the URLLoader is violating the API contract.
FinishWithResult(net::ERR_UNEXPECTED);
return;
}
- body_started_ = true;
+ request_state_->body_started = true;
body_handler_->OnStartLoadingResponseBody(std::move(body));
}
void SimpleURLLoaderImpl::OnComplete(
- const ResourceRequestCompletionStatus& status) {
+ const network::URLLoaderCompletionStatus& status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Request should not have been completed yet.
- DCHECK(!finished_);
- DCHECK(!request_completed_);
+ DCHECK(!request_state_->finished);
+ DCHECK(!request_state_->request_completed);
// Close pipes to ignore any subsequent close notification.
client_binding_.Close();
url_loader_.reset();
- request_completed_ = true;
- expected_body_size_ = status.decoded_body_length;
- net_error_ = status.error_code;
+ request_state_->request_completed = true;
+ request_state_->expected_body_size = status.decoded_body_length;
+ request_state_->net_error = status.error_code;
// If |status| indicates success, but the body pipe was never received, the
// URLLoader is violating the API contract.
- if (net_error_ == net::OK && !body_started_)
- net_error_ = net::ERR_UNEXPECTED;
+ if (request_state_->net_error == net::OK && !request_state_->body_started)
+ request_state_->net_error = net::ERR_UNEXPECTED;
MaybeComplete();
}
@@ -867,12 +1051,12 @@ void SimpleURLLoaderImpl::OnConnectionError() {
// due to peer death, or peer not calling OnComplete() on cancellation.
// Request should not have been completed yet.
- DCHECK(!finished_);
- DCHECK(!request_completed_);
- DCHECK_EQ(net::ERR_IO_PENDING, net_error_);
+ DCHECK(!request_state_->finished);
+ DCHECK(!request_state_->request_completed);
+ DCHECK_EQ(net::ERR_IO_PENDING, request_state_->net_error);
- request_completed_ = true;
- net_error_ = net::ERR_FAILED;
+ request_state_->request_completed = true;
+ request_state_->net_error = net::ERR_FAILED;
// Wait to receive any pending data on the data pipe before reporting the
// failure.
MaybeComplete();
@@ -881,39 +1065,55 @@ void SimpleURLLoaderImpl::OnConnectionError() {
void SimpleURLLoaderImpl::MaybeComplete() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Request should not have completed yet.
- DCHECK(!finished_);
+ DCHECK(!request_state_->finished);
// Make sure the URLLoader's pipe has been closed.
- if (!request_completed_)
+ if (!request_state_->request_completed)
return;
// Make sure the body pipe either was never opened or has been closed. Even if
// the request failed, if allow_partial_results_ is true, may still be able to
// read more data.
- if (body_started_ && !body_completed_)
+ if (request_state_->body_started && !request_state_->body_completed)
return;
+ // Retry on network change errors. Waiting for body complete isn't strictly
+ // necessary, but it guarantees a consistent situation, with no reads pending
+ // on the body pipe.
+ if (request_state_->net_error == net::ERR_NETWORK_CHANGED &&
+ remaining_retries_ > 0 && (retry_mode_ & RETRY_ON_NETWORK_CHANGE)) {
+ Retry();
+ return;
+ }
+
// When OnCompleted sees a success result, still need to report an error if
// the size isn't what was expected.
- if (net_error_ == net::OK && expected_body_size_ != received_body_size_) {
- if (expected_body_size_ > received_body_size_) {
+ if (request_state_->net_error == net::OK &&
+ request_state_->expected_body_size !=
+ request_state_->received_body_size) {
+ if (request_state_->expected_body_size >
+ request_state_->received_body_size) {
// The body pipe was closed before it received the entire body.
- net_error_ = net::ERR_FAILED;
+ request_state_->net_error = net::ERR_FAILED;
} else {
// The caller provided more data through the pipe than it reported in
- // ResourceRequestCompletionStatus, so the URLLoader is violating the API
- // contract. Just fail the request.
- net_error_ = net::ERR_UNEXPECTED;
+ // network::URLLoaderCompletionStatus, so the URLLoader is violating the
+ // API contract. Just fail the request.
+ request_state_->net_error = net::ERR_UNEXPECTED;
}
}
- FinishWithResult(net_error_);
+ FinishWithResult(request_state_->net_error);
}
} // namespace
-std::unique_ptr<SimpleURLLoader> SimpleURLLoader::Create() {
- return base::MakeUnique<SimpleURLLoaderImpl>();
+std::unique_ptr<SimpleURLLoader> SimpleURLLoader::Create(
+ std::unique_ptr<ResourceRequest> resource_request,
+ const net::NetworkTrafficAnnotationTag& annotation_tag) {
+ DCHECK(resource_request);
+ return std::make_unique<SimpleURLLoaderImpl>(std::move(resource_request),
+ annotation_tag);
}
SimpleURLLoader::~SimpleURLLoader() {}
diff --git a/chromium/content/public/common/simple_url_loader.h b/chromium/content/public/common/simple_url_loader.h
index 7cd6b745ba3..64df533e057 100644
--- a/chromium/content/public/common/simple_url_loader.h
+++ b/chromium/content/public/common/simple_url_loader.h
@@ -12,6 +12,7 @@
#include <string>
#include "base/callback_forward.h"
+#include "base/macros.h"
#include "content/common/content_export.h"
namespace base {
@@ -20,6 +21,7 @@ class FilePath;
namespace net {
struct NetworkTrafficAnnotationTag;
+struct RedirectInfo;
} // namespace net
namespace content {
@@ -41,15 +43,25 @@ class URLLoaderFactory;
// Each SimpleURLLoader can only be used for a single request.
//
// TODO(mmenke): Support the following:
-// * Save to (temp) file.
// * Consumer-provided methods to receive streaming (with backpressure).
-// * Monitoring (And cancelling during) redirects.
// * Uploads (Fixed strings, files, data streams (with backpressure), chunked
// uploads). ResourceRequest may already have some support, but should make it
// simple.
-// * Retrying.
+// * Maybe some sort of retry backoff or delay? ServiceURLLoaderContext enables
+// throttling for its URLFetchers. Could additionally/alternatively support
+// 503 + Retry-After.
class CONTENT_EXPORT SimpleURLLoader {
public:
+ // When a failed request should automatically be retried. These are intended
+ // to be ORed together.
+ enum RetryMode {
+ RETRY_NEVER = 0x0,
+ // Retries whenever the server returns a 5xx response code.
+ RETRY_ON_5XX = 0x1,
+ // Retries on net::ERR_NETWORK_CHANGED.
+ RETRY_ON_NETWORK_CHANGE = 0x2,
+ };
+
// The maximum size DownloadToString will accept.
const size_t kMaxBoundedStringDownloadSize = 1024 * 1024;
@@ -63,13 +75,24 @@ class CONTENT_EXPORT SimpleURLLoader {
using DownloadToFileCompleteCallback =
base::OnceCallback<void(const base::FilePath& path)>;
- static std::unique_ptr<SimpleURLLoader> Create();
+ // Callback used when a redirect is being followed. It is safe to delete the
+ // SimpleURLLoader during the callback.
+ using OnRedirectCallback =
+ base::RepeatingCallback<void(const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& response_head)>;
+
+ // Creates a SimpleURLLoader for |resource_request|. The request can be
+ // started by calling any one of the Download methods once. The loader may not
+ // be reused.
+ static std::unique_ptr<SimpleURLLoader> Create(
+ std::unique_ptr<ResourceRequest> resource_request,
+ const net::NetworkTrafficAnnotationTag& annotation_tag);
virtual ~SimpleURLLoader();
- // Starts a request for |resource_request| using |network_context|. The
- // SimpleURLLoader will accumulate all downloaded data in an in-memory string
- // of bounded size. If |max_body_size| is exceeded, the request will fail with
+ // Starts the request using |network_context|. The SimpleURLLoader will
+ // accumulate all downloaded data in an in-memory string of bounded size. If
+ // |max_body_size| is exceeded, the request will fail with
// net::ERR_INSUFFICIENT_RESOURCES. |max_body_size| must be no greater than 1
// MiB. For anything larger, it's recommended to either save to a temp file,
// or consume the data as it is received.
@@ -79,9 +102,7 @@ class CONTENT_EXPORT SimpleURLLoader {
// SimpleURLLoader before the callback is invoked will return in cancelling
// the request, and the callback will not be called.
virtual void DownloadToString(
- const ResourceRequest& resource_request,
mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag,
BodyAsStringCallback body_as_string_callback,
size_t max_body_size) = 0;
@@ -91,9 +112,7 @@ class CONTENT_EXPORT SimpleURLLoader {
// instead (DownloadToString if the body is expected to be of reasonable
// length, or DownloadToFile otherwise).
virtual void DownloadToStringOfUnboundedSizeUntilCrashAndDie(
- const ResourceRequest& resource_request,
mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag,
BodyAsStringCallback body_as_string_callback) = 0;
// SimpleURLLoader will download the entire response to a file at the
@@ -110,13 +129,23 @@ class CONTENT_EXPORT SimpleURLLoader {
// downloaded file will be deleted asynchronously and the callback will not be
// invoked, regardless of other settings.
virtual void DownloadToFile(
- const ResourceRequest& resource_request,
mojom::URLLoaderFactory* url_loader_factory,
- const net::NetworkTrafficAnnotationTag& annotation_tag,
DownloadToFileCompleteCallback download_to_file_complete_callback,
const base::FilePath& file_path,
int64_t max_body_size = std::numeric_limits<int64_t>::max()) = 0;
+ // Same as DownloadToFile, but creates a temporary file instead of taking a
+ // FilePath.
+ virtual void DownloadToTempFile(
+ mojom::URLLoaderFactory* url_loader_factory,
+ DownloadToFileCompleteCallback download_to_file_complete_callback,
+ int64_t max_body_size = std::numeric_limits<int64_t>::max()) = 0;
+
+ // Sets callback to be invoked during redirects. Callback may delete the
+ // SimpleURLLoader.
+ virtual void SetOnRedirectCallback(
+ const OnRedirectCallback& on_redirect_callback) = 0;
+
// Sets whether partially received results are allowed. Defaults to false.
// When true, if an error is received after reading the body starts or the max
// allowed body size exceeded, the partial response body that was received
@@ -142,6 +171,21 @@ class CONTENT_EXPORT SimpleURLLoader {
// TODO(mmenke): Consider adding a new error code for this.
virtual void SetAllowHttpErrorResults(bool allow_http_error_results) = 0;
+ // Sets the when to try and the max number of times to retry a request, if
+ // any. |max_retries| is the number of times to retry the request, not
+ // counting the initial request. |retry_mode| is a combination of one or more
+ // RetryModes, indicating when the request should be retried. If it is
+ // RETRY_NEVER, |max_retries| must be 0.
+ //
+ // By default, a request will not be retried.
+ //
+ // When a request is retried, the the request will start again using the
+ // initial content::ResourceRequest, even if the request was redirected.
+ //
+ // Calling this multiple times will overwrite the values previously passed to
+ // this method. May only be called before the request is started.
+ virtual void SetRetryOptions(int max_retries, int retry_mode) = 0;
+
// Returns the net::Error representing the final status of the request. May
// only be called once the loader has informed the caller of completion.
virtual int NetError() const = 0;
@@ -153,6 +197,9 @@ class CONTENT_EXPORT SimpleURLLoader {
protected:
SimpleURLLoader();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SimpleURLLoader);
};
} // namespace content
diff --git a/chromium/content/public/common/simple_url_loader_unittest.cc b/chromium/content/public/common/simple_url_loader_unittest.cc
index c1a12a5c4e1..97f1854cbc6 100644
--- a/chromium/content/public/common/simple_url_loader_unittest.cc
+++ b/chromium/content/public/common/simple_url_loader_unittest.cc
@@ -25,7 +25,6 @@
#include "base/test/scoped_task_environment.h"
#include "content/public/common/network_service.mojom.h"
#include "content/public/common/resource_request.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "content/public/common/resource_response.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
@@ -33,6 +32,7 @@
#include "content/public/network/network_service.h"
#include "mojo/public/c/system/types.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/http/http_response_headers.h"
@@ -42,6 +42,7 @@
#include "net/test/embedded_test_server/http_response.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -65,12 +66,17 @@ const char kTruncatedBody[] = "Truncated Body";
// and check the result.
class SimpleLoaderTestHelper {
public:
- // What the response should be downloaded to.
- enum class DownloadType { TO_STRING, TO_FILE };
+ // What the response should be downloaded to. Running all tests for all types
+ // is more than strictly needed, but simplest just to cover all cases.
+ enum class DownloadType { TO_STRING, TO_FILE, TO_TEMP_FILE };
- explicit SimpleLoaderTestHelper(DownloadType download_type)
+ explicit SimpleLoaderTestHelper(
+ std::unique_ptr<ResourceRequest> resource_request,
+ DownloadType download_type)
: download_type_(download_type),
- simple_url_loader_(SimpleURLLoader::Create()) {
+ simple_url_loader_(
+ SimpleURLLoader::Create(std::move(resource_request),
+ TRAFFIC_ANNOTATION_FOR_TESTS)) {
// Create a desistination directory, if downloading to a file.
if (download_type_ == DownloadType::TO_FILE) {
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
@@ -91,22 +97,19 @@ class SimpleLoaderTestHelper {
// |max_body_size| of -1 means don't use a max body size (Use
// DownloadToStringOfUnboundedSizeUntilCrashAndDie for string downloads, and
// don't specify a size for other types of downloads).
- void StartRequest(mojom::URLLoaderFactory* url_loader_factory,
- const ResourceRequest& resource_request,
- int64_t max_body_size = -1) {
+ void StartSimpleLoader(mojom::URLLoaderFactory* url_loader_factory,
+ int64_t max_body_size = -1) {
EXPECT_FALSE(done_);
switch (download_type_) {
case DownloadType::TO_STRING:
if (max_body_size < 0) {
simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
- resource_request, url_loader_factory,
- TRAFFIC_ANNOTATION_FOR_TESTS,
+ url_loader_factory,
base::BindOnce(&SimpleLoaderTestHelper::DownloadedToString,
base::Unretained(this)));
} else {
simple_url_loader_->DownloadToString(
- resource_request, url_loader_factory,
- TRAFFIC_ANNOTATION_FOR_TESTS,
+ url_loader_factory,
base::BindOnce(&SimpleLoaderTestHelper::DownloadedToString,
base::Unretained(this)),
max_body_size);
@@ -115,60 +118,45 @@ class SimpleLoaderTestHelper {
case DownloadType::TO_FILE:
if (max_body_size < 0) {
simple_url_loader_->DownloadToFile(
- resource_request, url_loader_factory,
- TRAFFIC_ANNOTATION_FOR_TESTS,
+ url_loader_factory,
base::BindOnce(&SimpleLoaderTestHelper::DownloadedToFile,
base::Unretained(this)),
dest_path_);
} else {
simple_url_loader_->DownloadToFile(
- resource_request, url_loader_factory,
- TRAFFIC_ANNOTATION_FOR_TESTS,
+ url_loader_factory,
base::BindOnce(&SimpleLoaderTestHelper::DownloadedToFile,
base::Unretained(this)),
dest_path_, max_body_size);
}
break;
+ case DownloadType::TO_TEMP_FILE:
+ if (max_body_size < 0) {
+ simple_url_loader_->DownloadToTempFile(
+ url_loader_factory,
+ base::BindOnce(&SimpleLoaderTestHelper::DownloadedToFile,
+ base::Unretained(this)));
+ } else {
+ simple_url_loader_->DownloadToTempFile(
+ url_loader_factory,
+ base::BindOnce(&SimpleLoaderTestHelper::DownloadedToFile,
+ base::Unretained(this)),
+ max_body_size);
+ }
+ break;
}
}
- // Runs a SimpleURLLoader using the provided ResourceRequest and waits for
- // completion.
- void RunRequest(mojom::URLLoaderFactory* url_loader_factory,
- const ResourceRequest& resource_request,
- int64_t max_body_size = -1) {
- StartRequest(url_loader_factory, resource_request, max_body_size);
+ // Starts the SimpleURLLoader waits for completion.
+ void StartSimpleLoaderAndWait(mojom::URLLoaderFactory* url_loader_factory,
+ int64_t max_body_size = -1) {
+ StartSimpleLoader(url_loader_factory, max_body_size);
Wait();
}
- // Simpler version of RunRequest that takes a URL instead.
- void RunRequestForURL(mojom::URLLoaderFactory* url_loader_factory,
- const GURL& url) {
- ResourceRequest resource_request;
- resource_request.url = url;
- RunRequest(url_loader_factory, resource_request);
- }
-
- // Runs a SimpleURLLoader using the provided ResourceRequest using the
- // provided max size and waits for completion.
- void RunRequestWithBoundedSize(mojom::URLLoaderFactory* url_loader_factory,
- const ResourceRequest& resource_request,
- int64_t max_body_size) {
- RunRequest(url_loader_factory, resource_request, max_body_size);
- }
-
- // Simpler version of RunRequestWithBoundedSize that takes a URL instead.
- void RunRequestForURLWithBoundedSize(
- mojom::URLLoaderFactory* url_loader_factory,
- const GURL& url,
- size_t max_size) {
- ResourceRequest resource_request;
- resource_request.url = url;
- RunRequestWithBoundedSize(url_loader_factory, resource_request, max_size);
- }
-
- // Waits until the request is completed. Automatically called by RunRequest
- // methods, but exposed so some tests can start the SimpleURLLoader directly.
+ // Waits until the request is completed. Automatically called by
+ // StartSimpleLoaderAndWait, but exposed so some tests can start the
+ // SimpleURLLoader directly.
void Wait() { run_loop_.Run(); }
// Sets whether a file should still exists on download-to-file errors.
@@ -223,20 +211,34 @@ class SimpleLoaderTestHelper {
void DownloadedToFile(const base::FilePath& file_path) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
EXPECT_FALSE(done_);
- EXPECT_EQ(DownloadType::TO_FILE, download_type_);
+ EXPECT_TRUE(download_type_ == DownloadType::TO_FILE ||
+ download_type_ == DownloadType::TO_TEMP_FILE);
EXPECT_FALSE(response_body_);
- // Make sure the destination file exists if |file_path| is non-empty, or the
- // file is expected to exist on error.
- EXPECT_EQ(!file_path.empty() || expect_path_exists_on_error_,
- base::PathExists(dest_path_));
-
if (!file_path.empty()) {
- EXPECT_EQ(dest_path_, file_path);
+ EXPECT_TRUE(base::PathExists(file_path));
response_body_ = std::make_unique<std::string>();
- EXPECT_TRUE(base::ReadFileToString(dest_path_, response_body_.get()));
+ EXPECT_TRUE(base::ReadFileToString(file_path, response_body_.get()));
}
+ // Can do some additional checks in the TO_FILE case. Unfortunately, in the
+ // temp file case, can't check that temp files were cleaned up, since it's
+ // a shared directory.
+ if (download_type_ == DownloadType::TO_FILE) {
+ // Make sure the destination file exists if |file_path| is non-empty, or
+ // the file is expected to exist on error.
+ EXPECT_EQ(!file_path.empty() || expect_path_exists_on_error_,
+ base::PathExists(dest_path_));
+
+ if (!file_path.empty())
+ EXPECT_EQ(dest_path_, file_path);
+ }
+
+ // Clean up file, so tests don't leave around files in the temp directory.
+ // Only matters in the TO_TEMP_FILE case.
+ if (!file_path.empty())
+ base::DeleteFile(file_path, false);
+
done_ = true;
run_loop_.Quit();
}
@@ -267,7 +269,7 @@ std::unique_ptr<net::test_server::HttpResponse> HandleResponseSize(
return nullptr;
std::unique_ptr<net::test_server::BasicHttpResponse> response =
- base::MakeUnique<net::test_server::BasicHttpResponse>();
+ std::make_unique<net::test_server::BasicHttpResponse>();
uint32_t length;
if (!base::StringToUint(request.GetURL().query(), &length)) {
@@ -287,7 +289,7 @@ std::unique_ptr<net::test_server::HttpResponse> HandleInvalidGzip(
return nullptr;
std::unique_ptr<net::test_server::BasicHttpResponse> response =
- base::MakeUnique<net::test_server::BasicHttpResponse>();
+ std::make_unique<net::test_server::BasicHttpResponse>();
response->AddCustomHeader("Content-Encoding", "gzip");
response->set_content("Not gzipped");
@@ -302,7 +304,7 @@ std::unique_ptr<net::test_server::HttpResponse> HandleTruncatedBody(
return nullptr;
std::unique_ptr<net::test_server::RawHttpResponse> response =
- base::MakeUnique<net::test_server::RawHttpResponse>(
+ std::make_unique<net::test_server::RawHttpResponse>(
base::StringPrintf("HTTP/1.1 200 OK\r\n"
"Content-Length: %" PRIuS "\r\n",
strlen(kTruncatedBody) + 4),
@@ -316,13 +318,18 @@ class SimpleURLLoaderTestBase {
public:
SimpleURLLoaderTestBase()
: scoped_task_environment_(
- base::test::ScopedTaskEnvironment::MainThreadType::IO),
- network_service_(NetworkService::Create()) {
+ base::test::ScopedTaskEnvironment::MainThreadType::IO) {
+ mojom::NetworkServicePtr network_service_ptr;
+ mojom::NetworkServiceRequest network_service_request =
+ mojo::MakeRequest(&network_service_ptr);
+ network_service_ =
+ NetworkService::Create(std::move(network_service_request),
+ /*netlog=*/nullptr);
mojom::NetworkContextParamsPtr context_params =
mojom::NetworkContextParams::New();
context_params->enable_data_url_support = true;
- network_service_->CreateNetworkContext(mojo::MakeRequest(&network_context_),
- std::move(context_params));
+ network_service_ptr->CreateNetworkContext(
+ mojo::MakeRequest(&network_context_), std::move(context_params));
network_context_->CreateURLLoaderFactory(
mojo::MakeRequest(&url_loader_factory_), 0);
@@ -351,101 +358,208 @@ class SimpleURLLoaderTest
: public SimpleURLLoaderTestBase,
public testing::TestWithParam<SimpleLoaderTestHelper::DownloadType> {
public:
- SimpleURLLoaderTest() : test_helper_(GetParam()) {}
+ SimpleURLLoaderTest() {}
~SimpleURLLoaderTest() override {}
- SimpleLoaderTestHelper* test_helper() { return &test_helper_; }
+ std::unique_ptr<SimpleLoaderTestHelper> CreateHelper(
+ std::unique_ptr<ResourceRequest> resource_request) {
+ EXPECT_TRUE(resource_request);
+ return std::make_unique<SimpleLoaderTestHelper>(std::move(resource_request),
+ GetParam());
+ }
- private:
- SimpleLoaderTestHelper test_helper_;
+ std::unique_ptr<SimpleLoaderTestHelper> CreateHelperForURL(const GURL& url) {
+ std::unique_ptr<ResourceRequest> resource_request =
+ std::make_unique<ResourceRequest>();
+ resource_request->url = url;
+ return std::make_unique<SimpleLoaderTestHelper>(std::move(resource_request),
+ GetParam());
+ }
};
TEST_P(SimpleURLLoaderTest, BasicRequest) {
- ResourceRequest resource_request;
+ std::unique_ptr<ResourceRequest> resource_request =
+ std::make_unique<ResourceRequest>();
// Use a more interesting request than "/echo", just to verify more than the
// request URL is hooked up.
- resource_request.url = test_server_.GetURL("/echoheader?foo");
- resource_request.headers.SetHeader("foo", "Expected Response");
- test_helper()->RunRequest(url_loader_factory_.get(), resource_request);
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ("Expected Response", *test_helper()->response_body());
+ resource_request->url = test_server_.GetURL("/echoheader?foo");
+ resource_request->headers.SetHeader("foo", "Expected Response");
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelper(std::move(resource_request));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("Expected Response", *test_helper->response_body());
}
// Test that SimpleURLLoader handles data URLs, which don't have headers.
TEST_P(SimpleURLLoaderTest, DataURL) {
- ResourceRequest resource_request;
- resource_request.url = GURL("data:text/plain,foo");
- test_helper()->RunRequest(url_loader_factory_.get(), resource_request);
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- ASSERT_TRUE(test_helper()->simple_url_loader()->ResponseInfo());
- EXPECT_FALSE(test_helper()->simple_url_loader()->ResponseInfo()->headers);
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ("foo", *test_helper()->response_body());
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("data:text/plain,foo"));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ ASSERT_TRUE(test_helper->simple_url_loader()->ResponseInfo());
+ EXPECT_FALSE(test_helper->simple_url_loader()->ResponseInfo()->headers);
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("foo", *test_helper->response_body());
}
// Make sure the class works when the size of the encoded and decoded bodies are
// different.
TEST_P(SimpleURLLoaderTest, GzipBody) {
- ResourceRequest resource_request;
- resource_request.url = test_server_.GetURL("/gzip-body?foo");
- test_helper()->RunRequest(url_loader_factory_.get(), resource_request);
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ("foo", *test_helper()->response_body());
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL("/gzip-body?foo"));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("foo", *test_helper->response_body());
}
// Make sure redirects are followed.
TEST_P(SimpleURLLoaderTest, Redirect) {
- test_helper()->RunRequestForURL(
- url_loader_factory_.get(),
- test_server_.GetURL("/server-redirect?" +
- test_server_.GetURL("/echo").spec()));
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ("Echo", *test_helper()->response_body());
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ "/server-redirect?" + test_server_.GetURL("/echo").spec()));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("Echo", *test_helper->response_body());
+}
+
+// Make sure OnRedirectCallback is invoked on a redirect.
+TEST_P(SimpleURLLoaderTest, OnRedirectCallback) {
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ "/server-redirect?" + test_server_.GetURL("/echo").spec()));
+
+ int num_redirects = 0;
+ net::RedirectInfo redirect_info;
+ ResourceResponseHead response_head;
+ test_helper->simple_url_loader()->SetOnRedirectCallback(base::Bind(
+ [](int* num_redirects, net::RedirectInfo* redirect_info_ptr,
+ ResourceResponseHead* response_head_ptr,
+ const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& response_head) {
+ ++*num_redirects;
+ *redirect_info_ptr = redirect_info;
+ *response_head_ptr = response_head;
+ },
+ base::Unretained(&num_redirects), base::Unretained(&redirect_info),
+ base::Unretained(&response_head)));
+
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("Echo", *test_helper->response_body());
+
+ EXPECT_EQ(1, num_redirects);
+ EXPECT_EQ(test_server_.GetURL("/echo"), redirect_info.new_url);
+ ASSERT_TRUE(response_head.headers);
+ EXPECT_EQ(301, response_head.headers->response_code());
+}
+
+// Make sure OnRedirectCallback is invoked on each redirect.
+TEST_P(SimpleURLLoaderTest, OnRedirectCallbackTwoRedirects) {
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ "/server-redirect?" +
+ test_server_
+ .GetURL("/server-redirect?" + test_server_.GetURL("/echo").spec())
+ .spec()));
+ int num_redirects = 0;
+ test_helper->simple_url_loader()->SetOnRedirectCallback(base::Bind(
+ [](int* num_redirects, const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& response_head) { ++*num_redirects; },
+ base::Unretained(&num_redirects)));
+
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
+
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("Echo", *test_helper->response_body());
+
+ EXPECT_EQ(2, num_redirects);
+}
+
+TEST_P(SimpleURLLoaderTest, DeleteInOnRedirectCallback) {
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ "/server-redirect?" + test_server_.GetURL("/echo").spec()));
+
+ SimpleLoaderTestHelper* unowned_test_helper = test_helper.get();
+ base::RunLoop run_loop;
+ unowned_test_helper->simple_url_loader()->SetOnRedirectCallback(base::Bind(
+ [](std::unique_ptr<SimpleLoaderTestHelper> test_helper,
+ base::RunLoop* run_loop, const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& response_head) { run_loop->Quit(); },
+ base::Passed(std::move(test_helper)), &run_loop));
+
+ unowned_test_helper->StartSimpleLoader(url_loader_factory_.get());
+
+ run_loop.Run();
+}
+
+// Check the case where a URLLoaderFactory with a closed Mojo pipe was passed
+// in.
+TEST_P(SimpleURLLoaderTest, DisconnectedURLLoader) {
+ // Destroy the NetworkContext, and wait for the Mojo URLLoaderFactory proxy to
+ // be informed of the closed pipe.
+ network_context_.reset();
+ base::RunLoop().RunUntilIdle();
+
+ std::unique_ptr<ResourceRequest> resource_request =
+ std::make_unique<ResourceRequest>();
+ resource_request->url = test_server_.GetURL("/echoheader?foo");
+ resource_request->headers.SetHeader("foo", "Expected Response");
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelper(std::move(resource_request));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
+
+ EXPECT_EQ(net::ERR_FAILED, test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->simple_url_loader()->ResponseInfo());
}
// Check that no body is returned with an HTTP error response.
TEST_P(SimpleURLLoaderTest, HttpErrorStatusCodeResponse) {
- test_helper()->RunRequestForURL(url_loader_factory_.get(),
- test_server_.GetURL("/echo?status=400"));
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL("/echo?status=400"));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
- EXPECT_EQ(net::ERR_FAILED, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(400, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ EXPECT_EQ(net::ERR_FAILED, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(400, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
// Check that the body is returned with an HTTP error response, when
// SetAllowHttpErrorResults(true) is called.
TEST_P(SimpleURLLoaderTest, HttpErrorStatusCodeResponseAllowed) {
- test_helper()->simple_url_loader()->SetAllowHttpErrorResults(true);
- test_helper()->RunRequestForURL(url_loader_factory_.get(),
- test_server_.GetURL("/echo?status=400"));
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(400, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ("Echo", *test_helper()->response_body());
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL("/echo?status=400"));
+ test_helper->simple_url_loader()->SetAllowHttpErrorResults(true);
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(400, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("Echo", *test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, EmptyResponseBody) {
- test_helper()->RunRequestForURL(url_loader_factory_.get(),
- test_server_.GetURL("/nocontent"));
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL("/nocontent"));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(204, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(204, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
// A response body is sent from the NetworkService, but it's empty.
- EXPECT_EQ("", *test_helper()->response_body());
+ EXPECT_EQ("", *test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, BigResponseBody) {
@@ -454,233 +568,245 @@ TEST_P(SimpleURLLoaderTest, BigResponseBody) {
// that DownloadToStringOfUnboundedSizeUntilCrashAndDie() can receive strings
// longer than DownloadToString() allows.
const uint32_t kResponseSize = 2 * 1024 * 1024;
- test_helper()->RunRequestForURL(url_loader_factory_.get(),
- test_server_.GetURL(base::StringPrintf(
- "/response-size?%u", kResponseSize)));
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ(kResponseSize, test_helper()->response_body()->length());
- EXPECT_EQ(std::string(kResponseSize, 'a'), *test_helper()->response_body());
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ base::StringPrintf("/response-size?%u", kResponseSize)));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ(kResponseSize, test_helper->response_body()->length());
+ EXPECT_EQ(std::string(kResponseSize, 'a'), *test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, ResponseBodyWithSizeMatchingLimit) {
const uint32_t kResponseSize = 16;
- test_helper()->RunRequestForURLWithBoundedSize(
- url_loader_factory_.get(),
- test_server_.GetURL(
- base::StringPrintf("/response-size?%u", kResponseSize)),
- kResponseSize);
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ(kResponseSize, test_helper()->response_body()->length());
- EXPECT_EQ(std::string(kResponseSize, 'a'), *test_helper()->response_body());
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ base::StringPrintf("/response-size?%u", kResponseSize)));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get(),
+ kResponseSize);
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ(kResponseSize, test_helper->response_body()->length());
+ EXPECT_EQ(std::string(kResponseSize, 'a'), *test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, ResponseBodyWithSizeBelowLimit) {
const uint32_t kResponseSize = 16;
const uint32_t kMaxResponseSize = kResponseSize + 1;
- test_helper()->RunRequestForURLWithBoundedSize(
- url_loader_factory_.get(),
- test_server_.GetURL(
- base::StringPrintf("/response-size?%u", kResponseSize)),
- kMaxResponseSize);
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ(kResponseSize, test_helper()->response_body()->length());
- EXPECT_EQ(std::string(kResponseSize, 'a'), *test_helper()->response_body());
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ base::StringPrintf("/response-size?%u", kResponseSize)));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get(),
+ kMaxResponseSize);
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ(kResponseSize, test_helper->response_body()->length());
+ EXPECT_EQ(std::string(kResponseSize, 'a'), *test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, ResponseBodyWithSizeAboveLimit) {
const uint32_t kResponseSize = 16;
- test_helper()->RunRequestForURLWithBoundedSize(
- url_loader_factory_.get(),
- test_server_.GetURL(
- base::StringPrintf("/response-size?%u", kResponseSize)),
- kResponseSize - 1);
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ base::StringPrintf("/response-size?%u", kResponseSize)));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get(),
+ kResponseSize - 1);
EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_FALSE(test_helper()->response_body());
+ test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->response_body());
}
// Same as above, but with setting allow_partial_results to true.
TEST_P(SimpleURLLoaderTest, ResponseBodyWithSizeAboveLimitPartialResponse) {
const uint32_t kResponseSize = 16;
const uint32_t kMaxResponseSize = kResponseSize - 1;
- test_helper()->simple_url_loader()->SetAllowPartialResults(true);
- test_helper()->RunRequestForURLWithBoundedSize(
- url_loader_factory_.get(),
- test_server_.GetURL(
- base::StringPrintf("/response-size?%u", kResponseSize)),
- kMaxResponseSize);
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ base::StringPrintf("/response-size?%u", kResponseSize)));
+ test_helper->simple_url_loader()->SetAllowPartialResults(true);
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get(),
+ kMaxResponseSize);
EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES,
- test_helper()->simple_url_loader()->NetError());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ(std::string(kMaxResponseSize, 'a'),
- *test_helper()->response_body());
- EXPECT_EQ(kMaxResponseSize, test_helper()->response_body()->length());
+ test_helper->simple_url_loader()->NetError());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ(std::string(kMaxResponseSize, 'a'), *test_helper->response_body());
+ EXPECT_EQ(kMaxResponseSize, test_helper->response_body()->length());
}
// The next 4 tests duplicate the above 4, but with larger response sizes. This
// means the size limit will not be exceeded on the first read.
TEST_P(SimpleURLLoaderTest, BigResponseBodyWithSizeMatchingLimit) {
const uint32_t kResponseSize = 512 * 1024;
- test_helper()->RunRequestForURLWithBoundedSize(
- url_loader_factory_.get(),
- test_server_.GetURL(
- base::StringPrintf("/response-size?%u", kResponseSize)),
- kResponseSize);
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ(kResponseSize, test_helper()->response_body()->length());
- EXPECT_EQ(std::string(kResponseSize, 'a'), *test_helper()->response_body());
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ base::StringPrintf("/response-size?%u", kResponseSize)));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get(),
+ kResponseSize);
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ(kResponseSize, test_helper->response_body()->length());
+ EXPECT_EQ(std::string(kResponseSize, 'a'), *test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, BigResponseBodyWithSizeBelowLimit) {
const uint32_t kResponseSize = 512 * 1024;
const uint32_t kMaxResponseSize = kResponseSize + 1;
- test_helper()->RunRequestForURLWithBoundedSize(
- url_loader_factory_.get(),
- test_server_.GetURL(
- base::StringPrintf("/response-size?%u", kResponseSize)),
- kMaxResponseSize);
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ(kResponseSize, test_helper()->response_body()->length());
- EXPECT_EQ(std::string(kResponseSize, 'a'), *test_helper()->response_body());
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ base::StringPrintf("/response-size?%u", kResponseSize)));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get(),
+ kMaxResponseSize);
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ(kResponseSize, test_helper->response_body()->length());
+ EXPECT_EQ(std::string(kResponseSize, 'a'), *test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, BigResponseBodyWithSizeAboveLimit) {
const uint32_t kResponseSize = 512 * 1024;
- test_helper()->RunRequestForURLWithBoundedSize(
- url_loader_factory_.get(),
- test_server_.GetURL(
- base::StringPrintf("/response-size?%u", kResponseSize)),
- kResponseSize - 1);
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ base::StringPrintf("/response-size?%u", kResponseSize)));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get(),
+ kResponseSize - 1);
EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_FALSE(test_helper()->response_body());
+ test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, BigResponseBodyWithSizeAboveLimitPartialResponse) {
const uint32_t kResponseSize = 512 * 1024;
const uint32_t kMaxResponseSize = kResponseSize - 1;
- test_helper()->simple_url_loader()->SetAllowPartialResults(true);
- test_helper()->RunRequestForURLWithBoundedSize(
- url_loader_factory_.get(),
- test_server_.GetURL(
- base::StringPrintf("/response-size?%u", kResponseSize)),
- kMaxResponseSize);
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(
+ base::StringPrintf("/response-size?%u", kResponseSize)));
+ test_helper->simple_url_loader()->SetAllowPartialResults(true);
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get(),
+ kMaxResponseSize);
EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES,
- test_helper()->simple_url_loader()->NetError());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ(std::string(kMaxResponseSize, 'a'),
- *test_helper()->response_body());
- EXPECT_EQ(kMaxResponseSize, test_helper()->response_body()->length());
+ test_helper->simple_url_loader()->NetError());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ(std::string(kMaxResponseSize, 'a'), *test_helper->response_body());
+ EXPECT_EQ(kMaxResponseSize, test_helper->response_body()->length());
}
TEST_P(SimpleURLLoaderTest, NetErrorBeforeHeaders) {
- test_helper()->RunRequestForURL(url_loader_factory_.get(),
- test_server_.GetURL("/close-socket"));
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL("/close-socket"));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
EXPECT_EQ(net::ERR_EMPTY_RESPONSE,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_FALSE(test_helper()->simple_url_loader()->ResponseInfo());
- EXPECT_FALSE(test_helper()->response_body());
+ test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->simple_url_loader()->ResponseInfo());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, NetErrorBeforeHeadersWithPartialResults) {
// Allow response body on error. There should still be no response body, since
// the error is before body reading starts.
- test_helper()->simple_url_loader()->SetAllowPartialResults(true);
- test_helper()->RunRequestForURL(url_loader_factory_.get(),
- test_server_.GetURL("/close-socket"));
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL("/close-socket"));
+ test_helper->simple_url_loader()->SetAllowPartialResults(true);
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
- EXPECT_FALSE(test_helper()->response_body());
+ EXPECT_FALSE(test_helper->response_body());
EXPECT_EQ(net::ERR_EMPTY_RESPONSE,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_FALSE(test_helper()->simple_url_loader()->ResponseInfo());
+ test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->simple_url_loader()->ResponseInfo());
}
TEST_P(SimpleURLLoaderTest, NetErrorAfterHeaders) {
- test_helper()->RunRequestForURL(url_loader_factory_.get(),
- test_server_.GetURL(kInvalidGzipPath));
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(kInvalidGzipPath));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
EXPECT_EQ(net::ERR_CONTENT_DECODING_FAILED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, NetErrorAfterHeadersWithPartialResults) {
// Allow response body on error. This case results in a 0-byte response body.
- test_helper()->simple_url_loader()->SetAllowPartialResults(true);
- test_helper()->RunRequestForURL(url_loader_factory_.get(),
- test_server_.GetURL(kInvalidGzipPath));
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(kInvalidGzipPath));
+ test_helper->simple_url_loader()->SetAllowPartialResults(true);
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
EXPECT_EQ(net::ERR_CONTENT_DECODING_FAILED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ("", *test_helper()->response_body());
+ test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("", *test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, TruncatedBody) {
- test_helper()->RunRequestForURL(url_loader_factory_.get(),
- test_server_.GetURL(kTruncatedBodyPath));
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(kTruncatedBodyPath));
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
EXPECT_EQ(net::ERR_CONTENT_LENGTH_MISMATCH,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, TruncatedBodyWithPartialResults) {
- test_helper()->simple_url_loader()->SetAllowPartialResults(true);
- test_helper()->RunRequestForURL(url_loader_factory_.get(),
- test_server_.GetURL(kTruncatedBodyPath));
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL(kTruncatedBodyPath));
+ test_helper->simple_url_loader()->SetAllowPartialResults(true);
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
EXPECT_EQ(net::ERR_CONTENT_LENGTH_MISMATCH,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ(kTruncatedBody, *test_helper()->response_body());
+ test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ(kTruncatedBody, *test_helper->response_body());
}
// Test case where NetworkService is destroyed before headers are received (and
// before the request is even made, for that matter).
TEST_P(SimpleURLLoaderTest, DestroyServiceBeforeResponseStarts) {
- ResourceRequest resource_request;
- resource_request.url = test_server_.GetURL("/hung");
- test_helper()->StartRequest(url_loader_factory_.get(), resource_request);
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(test_server_.GetURL("/hung"));
+ test_helper->StartSimpleLoader(url_loader_factory_.get());
network_service_ = nullptr;
- test_helper()->Wait();
+ test_helper->Wait();
- EXPECT_EQ(net::ERR_FAILED, test_helper()->simple_url_loader()->NetError());
- EXPECT_FALSE(test_helper()->response_body());
- ASSERT_FALSE(test_helper()->simple_url_loader()->ResponseInfo());
+ EXPECT_EQ(net::ERR_FAILED, test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->response_body());
+ ASSERT_FALSE(test_helper->simple_url_loader()->ResponseInfo());
}
enum class TestLoaderEvent {
kReceivedRedirect,
+ // Receive a response with a 200 status code.
kReceivedResponse,
+ // Receive a response with a 401 status code.
+ kReceived401Response,
+ // Receive a response with a 501 status code.
+ kReceived501Response,
kBodyBufferReceived,
kBodyDataRead,
// ResponseComplete indicates a success.
kResponseComplete,
// ResponseComplete is passed a network error (net::ERR_TIMED_OUT).
kResponseCompleteFailed,
+ // ResponseComplete is passed net::ERR_NETWORK_CHANGED.
+ kResponseCompleteNetworkChanged,
// Less body data is received than is expected.
kResponseCompleteTruncated,
// More body data is received than is expected.
@@ -733,6 +859,26 @@ class MockURLLoader : public mojom::URLLoader {
base::Optional<net::SSLInfo>(), nullptr);
break;
}
+ case TestLoaderEvent::kReceived401Response: {
+ ResourceResponseHead response_info;
+ std::string headers("HTTP/1.0 401 Client Borkage");
+ response_info.headers =
+ new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
+ headers.c_str(), headers.size()));
+ client_->OnReceiveResponse(response_info,
+ base::Optional<net::SSLInfo>(), nullptr);
+ break;
+ }
+ case TestLoaderEvent::kReceived501Response: {
+ ResourceResponseHead response_info;
+ std::string headers("HTTP/1.0 501 Server Borkage");
+ response_info.headers =
+ new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
+ headers.c_str(), headers.size()));
+ client_->OnReceiveResponse(response_info,
+ base::Optional<net::SSLInfo>(), nullptr);
+ break;
+ }
case TestLoaderEvent::kBodyBufferReceived: {
mojo::DataPipe data_pipe(1024);
body_stream_ = std::move(data_pipe.producer_handle);
@@ -751,35 +897,42 @@ class MockURLLoader : public mojom::URLLoader {
break;
}
case TestLoaderEvent::kResponseComplete: {
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = net::OK;
- request_complete_data.decoded_body_length = CountBytesToSend();
- client_->OnComplete(request_complete_data);
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::OK;
+ status.decoded_body_length = CountBytesToSend();
+ client_->OnComplete(status);
break;
}
case TestLoaderEvent::kResponseCompleteFailed: {
- ResourceRequestCompletionStatus request_complete_data;
+ network::URLLoaderCompletionStatus status;
// Use an error that SimpleURLLoader doesn't create itself, so clear
// when this is the source of the error code.
- request_complete_data.error_code = net::ERR_TIMED_OUT;
- request_complete_data.decoded_body_length = CountBytesToSend();
- client_->OnComplete(request_complete_data);
+ status.error_code = net::ERR_TIMED_OUT;
+ status.decoded_body_length = CountBytesToSend();
+ client_->OnComplete(status);
+ break;
+ }
+ case TestLoaderEvent::kResponseCompleteNetworkChanged: {
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::ERR_NETWORK_CHANGED;
+ status.decoded_body_length = CountBytesToSend();
+ client_->OnComplete(status);
break;
}
case TestLoaderEvent::kResponseCompleteTruncated: {
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = net::OK;
- request_complete_data.decoded_body_length = CountBytesToSend() + 1;
- client_->OnComplete(request_complete_data);
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::OK;
+ status.decoded_body_length = CountBytesToSend() + 1;
+ client_->OnComplete(status);
break;
}
case TestLoaderEvent::kResponseCompleteWithExtraData: {
// Make sure |decoded_body_length| doesn't underflow.
DCHECK_GT(CountBytesToSend(), 0u);
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = net::OK;
- request_complete_data.decoded_body_length = CountBytesToSend() - 1;
- client_->OnComplete(request_complete_data);
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::OK;
+ status.decoded_body_length = CountBytesToSend() - 1;
+ client_->OnComplete(status);
}
case TestLoaderEvent::kClientPipeClosed: {
EXPECT_TRUE(binding_.is_bound());
@@ -798,7 +951,7 @@ class MockURLLoader : public mojom::URLLoader {
~MockURLLoader() override {}
// mojom::URLLoader implementation:
- void FollowRedirect() override { NOTREACHED(); }
+ void FollowRedirect() override {}
void SetPriority(net::RequestPriority priority,
int32_t intra_priority_value) override {
NOTREACHED();
@@ -842,6 +995,7 @@ class MockURLLoaderFactory : public mojom::URLLoaderFactory {
~MockURLLoaderFactory() override {}
// mojom::URLLoaderFactory implementation:
+
void CreateLoaderAndStart(mojom::URLLoaderRequest url_loader_request,
int32_t routing_id,
int32_t request_id,
@@ -850,25 +1004,77 @@ class MockURLLoaderFactory : public mojom::URLLoaderFactory {
mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag&
traffic_annotation) override {
- EXPECT_FALSE(url_loader_);
- url_loader_ = base::MakeUnique<MockURLLoader>(
+ ASSERT_FALSE(test_events_.empty());
+ requested_urls_.push_back(url_request.url);
+ url_loaders_.push_back(std::make_unique<MockURLLoader>(
scoped_task_environment_, std::move(url_loader_request),
- std::move(client), std::move(test_events_));
- url_loader_->RunTest();
+ std::move(client), test_events_.front()));
+ test_events_.pop_front();
+
+ url_loader_queue_.push_back(url_loaders_.back().get());
}
- void Clone(mojom::URLLoaderFactoryRequest request) override { NOTREACHED(); }
- MockURLLoader* url_loader() const { return url_loader_.get(); }
+ void Clone(mojom::URLLoaderFactoryRequest request) override {
+ mojo::BindingId id = binding_set_.AddBinding(this, std::move(request));
+ if (close_new_binding_on_clone_)
+ binding_set_.RemoveBinding(id);
+ }
- void AddEvent(TestLoaderEvent test_event) {
- DCHECK(!url_loader_);
- test_events_.push_back(test_event);
+ // Makes clone fail close the newly created binding after bining the request,
+ // Simulating the case where the network service goes away before the cloned
+ // interface is used.
+ void set_close_new_binding_on_clone(bool close_new_binding_on_clone) {
+ close_new_binding_on_clone_ = close_new_binding_on_clone;
}
+ // Adds a events that will be returned by a single MockURLLoader. Mutliple
+ // calls mean multiple MockURLLoaders are expected to be created. Each will
+ // run to completion before the next one is expected to be created.
+ void AddEvents(const std::vector<TestLoaderEvent> events) {
+ DCHECK(url_loaders_.empty());
+ test_events_.push_back(events);
+ }
+
+ // Runs all events for all created URLLoaders, in order.
+ void RunTest(SimpleLoaderTestHelper* test_helper,
+ bool wait_for_completion = true) {
+ mojom::URLLoaderFactoryPtr factory;
+ binding_set_.AddBinding(this, mojo::MakeRequest(&factory));
+
+ test_helper->StartSimpleLoader(factory.get());
+
+ // Wait for the first URLLoader to start receiving messages.
+ base::RunLoop().RunUntilIdle();
+
+ while (!url_loader_queue_.empty()) {
+ url_loader_queue_.front()->RunTest();
+ url_loader_queue_.pop_front();
+ }
+
+ if (wait_for_completion)
+ test_helper->Wait();
+
+ // All loads with added events should have been created and had their
+ // RunTest() methods called by the time the above loop completes.
+ EXPECT_TRUE(test_events_.empty());
+ }
+
+ const std::list<GURL>& requested_urls() const { return requested_urls_; }
+
private:
base::test::ScopedTaskEnvironment* scoped_task_environment_;
- std::unique_ptr<MockURLLoader> url_loader_;
- std::vector<TestLoaderEvent> test_events_;
+ std::list<std::unique_ptr<MockURLLoader>> url_loaders_;
+ std::list<std::vector<TestLoaderEvent>> test_events_;
+
+ bool close_new_binding_on_clone_ = false;
+
+ // Queue of URLLoaders that have yet to had their RunTest method called.
+ // Separate list than |url_loaders_| so that old pipes aren't destroyed.
+ std::list<MockURLLoader*> url_loader_queue_;
+
+ std::list<GURL> requested_urls_;
+
+ mojo::BindingSet<mojom::URLLoaderFactory> binding_set_;
DISALLOW_COPY_AND_ASSIGN(MockURLLoaderFactory);
};
@@ -876,38 +1082,42 @@ class MockURLLoaderFactory : public mojom::URLLoaderFactory {
// Check that the request fails if OnComplete() is called before anything else.
TEST_P(SimpleURLLoaderTest, ResponseCompleteBeforeReceivedResponse) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kResponseComplete);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_UNEXPECTED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_FALSE(test_helper()->simple_url_loader()->ResponseInfo());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents({TestLoaderEvent::kResponseComplete});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_UNEXPECTED, test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->simple_url_loader()->ResponseInfo());
+ EXPECT_FALSE(test_helper->response_body());
}
// Check that the request fails if OnComplete() is called before the body pipe
// is received.
TEST_P(SimpleURLLoaderTest, ResponseCompleteAfterReceivedResponse) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kResponseComplete);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_UNEXPECTED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kResponseComplete});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_UNEXPECTED, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, CloseClientPipeBeforeBodyStarts) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kClientPipeClosed);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_FAILED, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kClientPipeClosed});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_FAILED, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
// This test tries closing the client pipe / completing the request in most
@@ -946,50 +1156,53 @@ TEST_P(SimpleURLLoaderTest, CloseClientPipeOrder) {
continue;
}
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
+ std::vector<TestLoaderEvent> events;
+ events.push_back(TestLoaderEvent::kReceivedResponse);
+ events.push_back(TestLoaderEvent::kBodyBufferReceived);
if (close_client_order == ClientCloseOrder::kBeforeData)
- loader_factory.AddEvent(close_client_event);
+ events.push_back(close_client_event);
for (uint32_t i = 0; i < bytes_received; ++i) {
- loader_factory.AddEvent(TestLoaderEvent::kBodyDataRead);
+ events.push_back(TestLoaderEvent::kBodyDataRead);
if (i == 0 && close_client_order == ClientCloseOrder::kDuringData)
- loader_factory.AddEvent(close_client_event);
+ events.push_back(close_client_event);
}
if (close_client_order == ClientCloseOrder::kAfterData)
- loader_factory.AddEvent(close_client_event);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferClosed);
+ events.push_back(close_client_event);
+ events.push_back(TestLoaderEvent::kBodyBufferClosed);
if (close_client_order == ClientCloseOrder::kAfterBufferClosed)
- loader_factory.AddEvent(close_client_event);
+ events.push_back(close_client_event);
+ loader_factory.AddEvents(events);
- SimpleLoaderTestHelper test_helper(GetParam());
- test_helper.simple_url_loader()->SetAllowPartialResults(
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ test_helper->simple_url_loader()->SetAllowPartialResults(
allow_partial_results);
- test_helper.RunRequestForURL(&loader_factory, GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
- EXPECT_EQ(200, test_helper.GetResponseCode());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
if (close_client_event != TestLoaderEvent::kResponseComplete) {
if (close_client_event ==
TestLoaderEvent::kResponseCompleteFailed) {
EXPECT_EQ(net::ERR_TIMED_OUT,
- test_helper.simple_url_loader()->NetError());
+ test_helper->simple_url_loader()->NetError());
} else {
EXPECT_EQ(net::ERR_FAILED,
- test_helper.simple_url_loader()->NetError());
+ test_helper->simple_url_loader()->NetError());
}
if (!allow_partial_results) {
- EXPECT_FALSE(test_helper.response_body());
+ EXPECT_FALSE(test_helper->response_body());
} else {
- ASSERT_TRUE(test_helper.response_body());
+ ASSERT_TRUE(test_helper->response_body());
EXPECT_EQ(std::string(bytes_received, 'a'),
- *test_helper.response_body());
+ *test_helper->response_body());
}
} else {
- EXPECT_EQ(net::OK, test_helper.simple_url_loader()->NetError());
- ASSERT_TRUE(test_helper.response_body());
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ ASSERT_TRUE(test_helper->response_body());
EXPECT_EQ(std::string(bytes_received, 'a'),
- *test_helper.response_body());
+ *test_helper->response_body());
}
}
}
@@ -1000,209 +1213,492 @@ TEST_P(SimpleURLLoaderTest, CloseClientPipeOrder) {
// Make sure the close client pipe message doesn't cause any issues.
TEST_P(SimpleURLLoaderTest, ErrorAndCloseClientPipeBeforeBodyStarts) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kResponseCompleteFailed);
- loader_factory.AddEvent(TestLoaderEvent::kClientPipeClosed);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_TIMED_OUT, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents({TestLoaderEvent::kReceivedResponse,
+ TestLoaderEvent::kResponseCompleteFailed,
+ TestLoaderEvent::kClientPipeClosed});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_TIMED_OUT, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
// Make sure the close client pipe message doesn't cause any issues.
TEST_P(SimpleURLLoaderTest, SuccessAndCloseClientPipeBeforeBodyComplete) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- loader_factory.AddEvent(TestLoaderEvent::kResponseComplete);
- loader_factory.AddEvent(TestLoaderEvent::kClientPipeClosed);
- loader_factory.AddEvent(TestLoaderEvent::kBodyDataRead);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferClosed);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ("a", *test_helper()->response_body());
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kResponseComplete, TestLoaderEvent::kClientPipeClosed,
+ TestLoaderEvent::kBodyDataRead, TestLoaderEvent::kBodyBufferClosed});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("a", *test_helper->response_body());
}
// Make sure the close client pipe message doesn't cause any issues.
TEST_P(SimpleURLLoaderTest, SuccessAndCloseClientPipeAfterBodyComplete) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- loader_factory.AddEvent(TestLoaderEvent::kBodyDataRead);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferClosed);
- loader_factory.AddEvent(TestLoaderEvent::kResponseComplete);
- loader_factory.AddEvent(TestLoaderEvent::kClientPipeClosed);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ("a", *test_helper()->response_body());
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyDataRead, TestLoaderEvent::kBodyBufferClosed,
+ TestLoaderEvent::kResponseComplete, TestLoaderEvent::kClientPipeClosed});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("a", *test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, DoubleReceivedResponse) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_UNEXPECTED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kReceivedResponse});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_UNEXPECTED, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, RedirectAfterReseivedResponse) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedRedirect);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_UNEXPECTED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kReceivedRedirect});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_UNEXPECTED, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, UnexpectedBodyBufferReceived) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_UNEXPECTED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_FALSE(test_helper()->simple_url_loader()->ResponseInfo());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents({TestLoaderEvent::kBodyBufferReceived});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_UNEXPECTED, test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->simple_url_loader()->ResponseInfo());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, DoubleBodyBufferReceived) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_UNEXPECTED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents({TestLoaderEvent::kReceivedResponse,
+ TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyBufferReceived});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_UNEXPECTED, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, UnexpectedMessageAfterBodyStarts) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- loader_factory.AddEvent(TestLoaderEvent::kBodyDataRead);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedRedirect);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_UNEXPECTED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyDataRead, TestLoaderEvent::kReceivedRedirect});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_UNEXPECTED, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, UnexpectedMessageAfterBodyStarts2) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- loader_factory.AddEvent(TestLoaderEvent::kBodyDataRead);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_UNEXPECTED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyDataRead, TestLoaderEvent::kBodyBufferReceived});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_UNEXPECTED, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, UnexpectedMessageAfterBodyComplete) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- loader_factory.AddEvent(TestLoaderEvent::kBodyDataRead);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferClosed);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_UNEXPECTED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyDataRead, TestLoaderEvent::kBodyBufferClosed,
+ TestLoaderEvent::kBodyBufferReceived});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_UNEXPECTED, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
}
TEST_P(SimpleURLLoaderTest, MoreDataThanExpected) {
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
- loader_factory.AddEvent(TestLoaderEvent::kBodyDataRead);
- loader_factory.AddEvent(TestLoaderEvent::kBodyDataRead);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferClosed);
- loader_factory.AddEvent(TestLoaderEvent::kResponseCompleteWithExtraData);
- test_helper()->RunRequestForURL(&loader_factory, GURL("foo://bar/"));
-
- EXPECT_EQ(net::ERR_UNEXPECTED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_EQ(200, test_helper()->GetResponseCode());
- EXPECT_FALSE(test_helper()->response_body());
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyDataRead, TestLoaderEvent::kBodyDataRead,
+ TestLoaderEvent::kBodyBufferClosed,
+ TestLoaderEvent::kResponseCompleteWithExtraData});
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_UNEXPECTED, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
+}
+
+TEST_P(SimpleURLLoaderTest, RetryOn5xx) {
+ const GURL kInitialURL("foo://bar/initial");
+ struct TestCase {
+ // Parameters passed to SetRetryOptions.
+ int max_retries;
+ int retry_mode;
+
+ // Number of 5xx responses before a successful response.
+ int num_5xx;
+
+ // Whether the request is expected to succeed in the end.
+ bool expect_success;
+
+ // Expected times the url should be requested.
+ uint32_t expected_num_requests;
+ } const kTestCases[] = {
+ // No retry on 5xx when retries disabled.
+ {0, SimpleURLLoader::RETRY_NEVER, 1, false, 1},
+
+ // No retry on 5xx when retries enabled on network change.
+ {1, SimpleURLLoader::RETRY_ON_NETWORK_CHANGE, 1, false, 1},
+
+ // As many retries allowed as 5xx errors.
+ {1, SimpleURLLoader::RETRY_ON_5XX, 1, true, 2},
+ {1,
+ SimpleURLLoader::RETRY_ON_5XX | SimpleURLLoader::RETRY_ON_NETWORK_CHANGE,
+ 1, true, 2},
+ {2, SimpleURLLoader::RETRY_ON_5XX, 2, true, 3},
+
+ // More retries than 5xx errors.
+ {2, SimpleURLLoader::RETRY_ON_5XX, 1, true, 2},
+
+ // Fewer retries than 5xx errors.
+ {1, SimpleURLLoader::RETRY_ON_5XX, 2, false, 2},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ MockURLLoaderFactory loader_factory(&scoped_task_environment_);
+ for (int i = 0; i < test_case.num_5xx; i++) {
+ loader_factory.AddEvents({TestLoaderEvent::kReceived501Response});
+ }
+
+ if (test_case.expect_success) {
+ // Valid response with a 1-byte body.
+ loader_factory.AddEvents({TestLoaderEvent::kReceivedResponse,
+ TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyDataRead,
+ TestLoaderEvent::kBodyBufferClosed,
+ TestLoaderEvent::kResponseComplete});
+ }
+
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL(kInitialURL));
+ test_helper->simple_url_loader()->SetRetryOptions(test_case.max_retries,
+ test_case.retry_mode);
+ loader_factory.RunTest(test_helper.get());
+
+ if (test_case.expect_success) {
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ(1u, test_helper->response_body()->size());
+ } else {
+ EXPECT_EQ(501, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
+ }
+
+ EXPECT_EQ(test_case.expected_num_requests,
+ loader_factory.requested_urls().size());
+ for (const auto& url : loader_factory.requested_urls()) {
+ EXPECT_EQ(kInitialURL, url);
+ }
+ }
+}
+
+// Test that when retrying on 5xx is enabled, there's no retry on a 4xx error.
+TEST_P(SimpleURLLoaderTest, NoRetryOn4xx) {
+ MockURLLoaderFactory loader_factory(&scoped_task_environment_);
+ loader_factory.AddEvents({TestLoaderEvent::kReceived401Response});
+
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ test_helper->simple_url_loader()->SetRetryOptions(
+ 1, SimpleURLLoader::RETRY_ON_5XX);
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(401, test_helper->GetResponseCode());
+ EXPECT_FALSE(test_helper->response_body());
+ EXPECT_EQ(1u, loader_factory.requested_urls().size());
+}
+
+// Checks that retrying after a redirect works. The original URL should be
+// re-requested.
+TEST_P(SimpleURLLoaderTest, RetryAfterRedirect) {
+ const GURL kInitialURL("foo://bar/initial");
+ MockURLLoaderFactory loader_factory(&scoped_task_environment_);
+ loader_factory.AddEvents({TestLoaderEvent::kReceivedRedirect,
+ TestLoaderEvent::kReceived501Response});
+ loader_factory.AddEvents(
+ {TestLoaderEvent::kReceivedRedirect, TestLoaderEvent::kReceivedResponse,
+ TestLoaderEvent::kBodyBufferReceived, TestLoaderEvent::kBodyBufferClosed,
+ TestLoaderEvent::kResponseComplete});
+
+ int num_redirects = 0;
+
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(kInitialURL);
+ test_helper->simple_url_loader()->SetRetryOptions(
+ 1, SimpleURLLoader::RETRY_ON_5XX);
+ test_helper->simple_url_loader()->SetOnRedirectCallback(base::Bind(
+ [](int* num_redirects, const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& response_head) { ++*num_redirects; },
+ base::Unretained(&num_redirects)));
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ EXPECT_TRUE(test_helper->response_body());
+ EXPECT_EQ(2, num_redirects);
+
+ EXPECT_EQ(2u, loader_factory.requested_urls().size());
+ for (const auto& url : loader_factory.requested_urls()) {
+ EXPECT_EQ(kInitialURL, url);
+ }
+}
+
+TEST_P(SimpleURLLoaderTest, RetryOnNetworkChange) {
+ // TestLoaderEvents up to (and including) a network change. Since
+ // SimpleURLLoader always waits for the body buffer to be closed before
+ // retrying, everything that has a kBodyBufferReceived message must also have
+ // a kBodyBufferClosed message. Each test case will be tried against each of
+ // these event sequences.
+ const std::vector<std::vector<TestLoaderEvent>> kNetworkChangedEvents = {
+ {TestLoaderEvent::kResponseCompleteNetworkChanged},
+ {TestLoaderEvent::kReceivedResponse,
+ TestLoaderEvent::kResponseCompleteNetworkChanged},
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyBufferClosed,
+ TestLoaderEvent::kResponseCompleteNetworkChanged},
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kResponseCompleteNetworkChanged,
+ TestLoaderEvent::kBodyBufferClosed},
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyDataRead, TestLoaderEvent::kBodyBufferClosed,
+ TestLoaderEvent::kResponseCompleteNetworkChanged},
+ {TestLoaderEvent::kReceivedResponse, TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyDataRead,
+ TestLoaderEvent::kResponseCompleteNetworkChanged,
+ TestLoaderEvent::kBodyBufferClosed},
+ {TestLoaderEvent::kReceivedRedirect,
+ TestLoaderEvent::kResponseCompleteNetworkChanged},
+ };
+
+ const GURL kInitialURL("foo://bar/initial");
+
+ // Test cases in which to try each entry in kNetworkChangedEvents.
+ struct TestCase {
+ // Parameters passed to SetRetryOptions.
+ int max_retries;
+ int retry_mode;
+
+ // Number of network changes responses before a successful response.
+ // For each network change, the entire sequence of an entry in
+ // kNetworkChangedEvents is repeated.
+ int num_network_changes;
+
+ // Whether the request is expected to succeed in the end.
+ bool expect_success;
+
+ // Expected times the url should be requested.
+ uint32_t expected_num_requests;
+ } const kTestCases[] = {
+ // No retry on network change when retries disabled.
+ {0, SimpleURLLoader::RETRY_NEVER, 1, false, 1},
+
+ // No retry on network change when retries enabled on 5xx response.
+ {1, SimpleURLLoader::RETRY_ON_5XX, 1, false, 1},
+
+ // As many retries allowed as network changes.
+ {1, SimpleURLLoader::RETRY_ON_NETWORK_CHANGE, 1, true, 2},
+ {1,
+ SimpleURLLoader::RETRY_ON_NETWORK_CHANGE | SimpleURLLoader::RETRY_ON_5XX,
+ 1, true, 2},
+ {2, SimpleURLLoader::RETRY_ON_NETWORK_CHANGE, 2, true, 3},
+
+ // More retries than network changes.
+ {2, SimpleURLLoader::RETRY_ON_NETWORK_CHANGE, 1, true, 2},
+
+ // Fewer retries than network changes.
+ {1, SimpleURLLoader::RETRY_ON_NETWORK_CHANGE, 2, false, 2},
+ };
+
+ for (const auto& network_events : kNetworkChangedEvents) {
+ for (const auto& test_case : kTestCases) {
+ MockURLLoaderFactory loader_factory(&scoped_task_environment_);
+ for (int i = 0; i < test_case.num_network_changes; i++) {
+ loader_factory.AddEvents(network_events);
+ }
+
+ if (test_case.expect_success) {
+ // Valid response with a 1-byte body.
+ loader_factory.AddEvents({TestLoaderEvent::kReceivedResponse,
+ TestLoaderEvent::kBodyBufferReceived,
+ TestLoaderEvent::kBodyDataRead,
+ TestLoaderEvent::kBodyBufferClosed,
+ TestLoaderEvent::kResponseComplete});
+ }
+
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL(kInitialURL));
+ test_helper->simple_url_loader()->SetRetryOptions(test_case.max_retries,
+ test_case.retry_mode);
+ loader_factory.RunTest(test_helper.get());
+
+ if (test_case.expect_success) {
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ EXPECT_EQ(200, test_helper->GetResponseCode());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ(1u, test_helper->response_body()->size());
+ } else {
+ EXPECT_EQ(net::ERR_NETWORK_CHANGED,
+ test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->response_body());
+ }
+
+ EXPECT_EQ(test_case.expected_num_requests,
+ loader_factory.requested_urls().size());
+ for (const auto& url : loader_factory.requested_urls()) {
+ EXPECT_EQ(kInitialURL, url);
+ }
+ }
+ }
+
+ // Check that there's no retry for each entry in kNetworkChangedEvents when an
+ // error other than a network change is received.
+ for (const auto& network_events : kNetworkChangedEvents) {
+ std::vector<TestLoaderEvent> modifed_network_events = network_events;
+ for (auto& test_loader_event : modifed_network_events) {
+ if (test_loader_event == TestLoaderEvent::kResponseCompleteNetworkChanged)
+ test_loader_event = TestLoaderEvent::kResponseCompleteFailed;
+ }
+ MockURLLoaderFactory loader_factory(&scoped_task_environment_);
+ loader_factory.AddEvents(modifed_network_events);
+
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL(kInitialURL));
+ test_helper->simple_url_loader()->SetRetryOptions(
+ 1, SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
+ loader_factory.RunTest(test_helper.get());
+
+ EXPECT_EQ(net::ERR_TIMED_OUT, test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->response_body());
+ EXPECT_EQ(1u, loader_factory.requested_urls().size());
+ }
+}
+
+// Check the case where the URLLoaderFactory has been disconnected before the
+// request is retried.
+TEST_P(SimpleURLLoaderTest, RetryWithUnboundFactory) {
+ MockURLLoaderFactory loader_factory(&scoped_task_environment_);
+ loader_factory.AddEvents({TestLoaderEvent::kResponseCompleteNetworkChanged});
+ // Since clone fails asynchronously, this shouldn't be any different from
+ // the new URLLoaderFactory being disconnected in some other way.
+ loader_factory.set_close_new_binding_on_clone(true);
+
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("foo://bar/"));
+ test_helper->simple_url_loader()->SetRetryOptions(
+ 1, SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
+ loader_factory.RunTest(test_helper.get());
+ EXPECT_EQ(net::ERR_FAILED, test_helper->simple_url_loader()->NetError());
+ EXPECT_FALSE(test_helper->response_body());
}
INSTANTIATE_TEST_CASE_P(
/* No prefix */,
SimpleURLLoaderTest,
testing::Values(SimpleLoaderTestHelper::DownloadType::TO_STRING,
- SimpleLoaderTestHelper::DownloadType::TO_FILE));
+ SimpleLoaderTestHelper::DownloadType::TO_FILE,
+ SimpleLoaderTestHelper::DownloadType::TO_TEMP_FILE));
class SimpleURLLoaderFileTest : public SimpleURLLoaderTestBase,
public testing::Test {
public:
- SimpleURLLoaderFileTest()
- : test_helper_(SimpleLoaderTestHelper::DownloadType::TO_FILE) {}
+ SimpleURLLoaderFileTest() {}
~SimpleURLLoaderFileTest() override {}
- SimpleLoaderTestHelper* test_helper() { return &test_helper_; }
-
- private:
- SimpleLoaderTestHelper test_helper_;
+ std::unique_ptr<SimpleLoaderTestHelper> CreateHelperForURL(const GURL& url) {
+ std::unique_ptr<ResourceRequest> resource_request =
+ std::make_unique<ResourceRequest>();
+ resource_request->url = url;
+ return std::make_unique<SimpleLoaderTestHelper>(
+ std::move(resource_request),
+ SimpleLoaderTestHelper::DownloadType::TO_FILE);
+ }
};
// Make sure that an existing file will be completely overwritten.
TEST_F(SimpleURLLoaderFileTest, OverwriteFile) {
std::string junk_data(100, '!');
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("data:text/plain,foo"));
ASSERT_EQ(static_cast<int>(junk_data.size()),
- base::WriteFile(test_helper()->dest_path(), junk_data.data(),
+ base::WriteFile(test_helper->dest_path(), junk_data.data(),
junk_data.size()));
- ASSERT_TRUE(base::PathExists(test_helper()->dest_path()));
+ ASSERT_TRUE(base::PathExists(test_helper->dest_path()));
- ResourceRequest resource_request;
- resource_request.url = GURL("data:text/plain,foo");
- test_helper()->RunRequest(url_loader_factory_.get(), resource_request);
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
- EXPECT_EQ(net::OK, test_helper()->simple_url_loader()->NetError());
- ASSERT_TRUE(test_helper()->simple_url_loader()->ResponseInfo());
- ASSERT_TRUE(test_helper()->response_body());
- EXPECT_EQ("foo", *test_helper()->response_body());
+ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError());
+ ASSERT_TRUE(test_helper->simple_url_loader()->ResponseInfo());
+ ASSERT_TRUE(test_helper->response_body());
+ EXPECT_EQ("foo", *test_helper->response_body());
}
// Make sure that file creation errors are handled correctly.
TEST_F(SimpleURLLoaderFileTest, FileCreateError) {
- ASSERT_TRUE(base::CreateDirectory(test_helper()->dest_path()));
- ASSERT_TRUE(base::PathExists(test_helper()->dest_path()));
+ std::unique_ptr<SimpleLoaderTestHelper> test_helper =
+ CreateHelperForURL(GURL("data:text/plain,foo"));
+ ASSERT_TRUE(base::CreateDirectory(test_helper->dest_path()));
+ ASSERT_TRUE(base::PathExists(test_helper->dest_path()));
- ResourceRequest resource_request;
- resource_request.url = GURL("data:text/plain,foo");
// The directory should still exist after the download fails.
- test_helper()->set_expect_path_exists_on_error(true);
- test_helper()->RunRequest(url_loader_factory_.get(), resource_request);
+ test_helper->set_expect_path_exists_on_error(true);
+ test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get());
EXPECT_EQ(net::ERR_ACCESS_DENIED,
- test_helper()->simple_url_loader()->NetError());
- EXPECT_TRUE(test_helper()->simple_url_loader()->ResponseInfo());
- EXPECT_FALSE(test_helper()->response_body());
+ test_helper->simple_url_loader()->NetError());
+ EXPECT_TRUE(test_helper->simple_url_loader()->ResponseInfo());
+ EXPECT_FALSE(test_helper->response_body());
}
// Make sure that destroying the loader destroys a partially downloaded file.
@@ -1216,23 +1712,24 @@ TEST_F(SimpleURLLoaderFileTest, DeleteLoaderDuringRequestDestroysFile) {
continue;
MockURLLoaderFactory loader_factory(&scoped_task_environment_);
- loader_factory.AddEvent(TestLoaderEvent::kReceivedResponse);
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferReceived);
+ std::vector<TestLoaderEvent> events;
+ events.push_back(TestLoaderEvent::kReceivedResponse);
+ events.push_back(TestLoaderEvent::kBodyBufferReceived);
if (body_data_read)
- loader_factory.AddEvent(TestLoaderEvent::kBodyDataRead);
+ events.push_back(TestLoaderEvent::kBodyDataRead);
if (body_buffer_closed)
- loader_factory.AddEvent(TestLoaderEvent::kBodyBufferClosed);
+ events.push_back(TestLoaderEvent::kBodyBufferClosed);
if (client_pipe_closed)
- loader_factory.AddEvent(TestLoaderEvent::kClientPipeClosed);
-
- // The request just hangs after receiving some body data.
- ResourceRequest resource_request;
- resource_request.url = GURL("foo://bar/");
+ events.push_back(TestLoaderEvent::kClientPipeClosed);
+ loader_factory.AddEvents(events);
std::unique_ptr<SimpleLoaderTestHelper> test_helper =
- std::make_unique<SimpleLoaderTestHelper>(
- SimpleLoaderTestHelper::DownloadType::TO_FILE);
- test_helper->StartRequest(&loader_factory, resource_request);
+ CreateHelperForURL(GURL("foo://bar/"));
+
+ // Run events without waiting for the request to complete, since the
+ // request will hang.
+ loader_factory.RunTest(test_helper.get(),
+ false /* wait_for_completion */);
// Wait for the request to advance as far as it's going to.
scoped_task_environment_.RunUntilIdle();
diff --git a/chromium/content/public/common/storage_quota_params.h b/chromium/content/public/common/storage_quota_params.h
index 173b9aedc16..fdc2c3a85e8 100644
--- a/chromium/content/public/common/storage_quota_params.h
+++ b/chromium/content/public/common/storage_quota_params.h
@@ -19,19 +19,13 @@ namespace content {
struct CONTENT_EXPORT StorageQuotaParams {
StorageQuotaParams()
: render_frame_id(MSG_ROUTING_NONE),
- request_id(-1),
storage_type(storage::kStorageTypeTemporary),
- requested_size(0),
- user_gesture(false) {}
+ requested_size(0) {}
int render_frame_id;
- int request_id;
GURL origin_url;
storage::StorageType storage_type;
uint64_t requested_size;
-
- // Request was made in the context of a user gesture.
- bool user_gesture;
};
} // namespace content
diff --git a/chromium/content/public/common/typemaps.gni b/chromium/content/public/common/typemaps.gni
index db3e842ab11..83d3436f241 100644
--- a/chromium/content/public/common/typemaps.gni
+++ b/chromium/content/public/common/typemaps.gni
@@ -3,13 +3,14 @@
# found in the LICENSE file.
typemaps = [
+ "//content/public/common/cors_error_status.typemap",
"//content/public/common/manifest.typemap",
- "//content/public/common/mutable_network_traffic_annotation_tag.typemap",
"//content/public/common/referrer.typemap",
"//content/public/common/resource_type.typemap",
"//content/public/common/ssl_info.typemap",
- "//content/public/common/url_loader_status.typemap",
+ "//content/public/common/url_loader_completion_status.typemap",
"//content/public/common/url_request.typemap",
"//content/public/common/url_request_redirect_info.typemap",
"//content/public/common/url_response_head.typemap",
+ "//content/public/common/webplugininfo.typemap",
]
diff --git a/chromium/content/public/common/url_constants.cc b/chromium/content/public/common/url_constants.cc
index 20fac1002b9..00fd70c23a0 100644
--- a/chromium/content/public/common/url_constants.cc
+++ b/chromium/content/public/common/url_constants.cc
@@ -58,6 +58,17 @@ const char kChromeUIPpapiFlashHangURL[] = "chrome://ppapiflashhang/";
#if defined(OS_ANDROID)
const char kChromeUIGpuJavaCrashURL[] = "chrome://gpu-java-crash/";
#endif
+#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
+const char kChromeUICrashHeapOverflowURL[] = "chrome://crash/heap-overflow";
+const char kChromeUICrashHeapUnderflowURL[] = "chrome://crash/heap-underflow";
+const char kChromeUICrashUseAfterFreeURL[] = "chrome://crash/use-after-free";
+#endif
+#if defined(SYZYASAN)
+const char kChromeUICrashCorruptHeapBlockURL[] =
+ "chrome://crash/corrupt-heap-block";
+const char kChromeUICrashCorruptHeapURL[] = "chrome://crash/corrupt-heap";
+const char kChromeUICrashDcheckURL[] = "chrome://crash/dcheck";
+#endif
// This error URL is loaded in normal web renderer processes, so it should not
// have a chrome:// scheme that might let it be confused with a WebUI page.
diff --git a/chromium/content/public/common/url_constants.h b/chromium/content/public/common/url_constants.h
index 68e432e5792..001f000157a 100644
--- a/chromium/content/public/common/url_constants.h
+++ b/chromium/content/public/common/url_constants.h
@@ -67,6 +67,16 @@ CONTENT_EXPORT extern const char kChromeUIPpapiFlashHangURL[];
#if defined(OS_ANDROID)
CONTENT_EXPORT extern const char kChromeUIGpuJavaCrashURL[];
#endif
+#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
+CONTENT_EXPORT extern const char kChromeUICrashHeapOverflowURL[];
+CONTENT_EXPORT extern const char kChromeUICrashHeapUnderflowURL[];
+CONTENT_EXPORT extern const char kChromeUICrashUseAfterFreeURL[];
+#endif
+#if defined(SYZYASAN)
+CONTENT_EXPORT extern const char kChromeUICrashCorruptHeapBlockURL[];
+CONTENT_EXPORT extern const char kChromeUICrashCorruptHeapURL[];
+CONTENT_EXPORT extern const char kChromeUICrashDcheckURL[];
+#endif
// Special URL used to start a navigation to an error page.
CONTENT_EXPORT extern const char kUnreachableWebDataURL[];
diff --git a/chromium/content/public/common/url_loader.mojom b/chromium/content/public/common/url_loader.mojom
index b77d3e6303b..1db483e6e24 100644
--- a/chromium/content/public/common/url_loader.mojom
+++ b/chromium/content/public/common/url_loader.mojom
@@ -17,7 +17,10 @@ struct SSLInfo;
struct URLRequestRedirectInfo;
[Native]
-struct URLLoaderStatus;
+struct CORSErrorStatus;
+
+[Native]
+struct URLLoaderCompletionStatus;
// This enum corresponds to net::RequestPriority. See its comments for details.
enum RequestPriority {
@@ -62,8 +65,8 @@ interface DownloadedTempFile {
interface URLLoaderClient {
// Called when the response head is received.
// |downloaded_file| is non-null in the 'download_to_file' case.
- // |ssl_info| is non-null if kSendSSLInfo was specified to
- // CreateLoaderAndStart.
+ // |ssl_info| is non-null if |kURLLoadOptionsSendSSLInfoWithResponse|
+ // was specified to CreateLoaderAndStart.
OnReceiveResponse(URLResponseHead head,
SSLInfo? ssl_info,
DownloadedTempFile? downloaded_file);
@@ -104,7 +107,8 @@ interface URLLoaderClient {
OnStartLoadingResponseBody(handle<data_pipe_consumer> body);
// Called when the loading completes. No notification will be dispatched for
- // this client after this message arrives.
- OnComplete(URLLoaderStatus completion_status);
+ // this client after this message arrives. |status| has its |ssl_info| field
+ // set only when |kURLLoadOptionsSendSSLInfoForCertificateError| was set.
+ OnComplete(URLLoaderCompletionStatus status);
};
diff --git a/chromium/content/public/common/url_loader_status.typemap b/chromium/content/public/common/url_loader_completion_status.typemap
index 28c8bd7ec93..18b46bc5195 100644
--- a/chromium/content/public/common/url_loader_status.typemap
+++ b/chromium/content/public/common/url_loader_completion_status.typemap
@@ -4,12 +4,12 @@
mojom = "//content/public/common/url_loader.mojom"
public_headers =
- [ "//content/public/common/resource_request_completion_status.h" ]
+ [ "//services/network/public/cpp/url_loader_completion_status.h" ]
traits_headers = [ "//content/common/resource_messages.h" ]
deps = [
"//content:export",
"//net:net",
+ "//services/network/public/cpp",
"//third_party/WebKit/public:blink_headers",
]
-type_mappings =
- [ "content.mojom.URLLoaderStatus=content::ResourceRequestCompletionStatus" ]
+type_mappings = [ "content.mojom.URLLoaderCompletionStatus=network::URLLoaderCompletionStatus" ]
diff --git a/chromium/content/public/common/url_loader_factory.mojom b/chromium/content/public/common/url_loader_factory.mojom
index 1d69a7c7172..7e610eb797e 100644
--- a/chromium/content/public/common/url_loader_factory.mojom
+++ b/chromium/content/public/common/url_loader_factory.mojom
@@ -4,29 +4,37 @@
module content.mojom;
-import "mutable_network_traffic_annotation_tag.mojom";
+import "services/network/public/interfaces/mutable_network_traffic_annotation_tag.mojom";
import "url_loader.mojom";
const uint32 kURLLoadOptionNone = 0;
// Sends the net::SSLInfo struct in OnReceiveResponse.
-const uint32 kURLLoadOptionSendSSLInfo = 1;
+const uint32 kURLLoadOptionSendSSLInfoWithResponse = 1;
// Enables mime sniffing. NOTE: this is only used with the network service.
const uint32 kURLLoadOptionSniffMimeType = 2;
// Indicates that execution is blocking on the completion of the request.
const uint32 kURLLoadOptionSynchronous = 4;
+// Sends the net::SSLInfo struct in OnComplete when the connection had a major
+// certificate error.
+const uint32 kURLLoadOptionSendSSLInfoForCertificateError = 8;
interface URLLoaderFactory {
// Creats a URLLoader and starts loading with the given |request|. |client|'s
// method will be called when certain events related to that loading
- // (e.g., response arrival) happen. |request_id| is for compatibility with
- // the existing Chrome IPC.
+ // (e.g., response arrival) happen.
+ // |routing_id| is the routing_id for subframe requests, and is the
+ // frame_tree_node_id for frame requests.
+ // TODO: once MojoLoading is only codepath and we have one factory per frame,
+ // remove this.
+ // |request_id| is for compatibility with the existing Chrome IPC.
CreateLoaderAndStart(URLLoader& loader,
int32 routing_id,
int32 request_id,
uint32 options,
URLRequest request,
URLLoaderClient client,
- MutableNetworkTrafficAnnotationTag traffic_annotation);
+ network.mojom.MutableNetworkTrafficAnnotationTag
+ traffic_annotation);
// Connects a new pipe to this instance of the URLLoaderFactory interface.
Clone(URLLoaderFactory& factory);
diff --git a/chromium/content/public/common/url_loader_throttle.cc b/chromium/content/public/common/url_loader_throttle.cc
index 12147a01fc2..20115f9df1e 100644
--- a/chromium/content/public/common/url_loader_throttle.cc
+++ b/chromium/content/public/common/url_loader_throttle.cc
@@ -26,7 +26,10 @@ void URLLoaderThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info,
bool* defer) {}
-void URLLoaderThrottle::WillProcessResponse(bool* defer) {}
+void URLLoaderThrottle::WillProcessResponse(
+ const GURL& response_url,
+ const ResourceResponseHead& response_head,
+ bool* defer) {}
URLLoaderThrottle::URLLoaderThrottle() {}
diff --git a/chromium/content/public/common/url_loader_throttle.h b/chromium/content/public/common/url_loader_throttle.h
index 402761815d0..e6d67ccf90e 100644
--- a/chromium/content/public/common/url_loader_throttle.h
+++ b/chromium/content/public/common/url_loader_throttle.h
@@ -8,6 +8,8 @@
#include "content/common/content_export.h"
#include "content/public/common/resource_type.h"
+class GURL;
+
namespace net {
struct RedirectInfo;
}
@@ -15,6 +17,7 @@ struct RedirectInfo;
namespace content {
struct ResourceRequest;
+struct ResourceResponseHead;
// A URLLoaderThrottle gets notified at various points during the process of
// loading a resource. At each stage, it has the opportunity to defer the
@@ -69,7 +72,10 @@ class CONTENT_EXPORT URLLoaderThrottle {
bool* defer);
// Called when the response headers and meta data are available.
- virtual void WillProcessResponse(bool* defer);
+ // TODO(776312): Migrate this URL to ResourceResponseHead.
+ virtual void WillProcessResponse(const GURL& response_url,
+ const ResourceResponseHead& response_head,
+ bool* defer);
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
diff --git a/chromium/content/public/common/url_utils.cc b/chromium/content/public/common/url_utils.cc
index 7253dd82a09..712320af451 100644
--- a/chromium/content/public/common/url_utils.cc
+++ b/chromium/content/public/common/url_utils.cc
@@ -41,6 +41,11 @@ bool IsURLHandledByNetworkStack(const GURL& url) {
return false;
}
+ // Renderer debug URLs (e.g. chrome://kill) are handled in the renderer
+ // process directly and should not be sent to the network stack.
+ if (IsRendererDebugURL(url))
+ return false;
+
// For you information, even though a "data:" url doesn't generate actual
// network requests, it is handled by the network stack and so must return
// true. The reason is that a few "data:" urls can't be handled locally. For
@@ -53,4 +58,44 @@ bool IsURLHandledByNetworkStack(const GURL& url) {
return true;
}
+bool IsURLHandledByNetworkService(const GURL& url) {
+ return url.SchemeIsHTTPOrHTTPS() || url.SchemeIsWSOrWSS() ||
+ url.SchemeIs(url::kFtpScheme) || url.SchemeIs(url::kGopherScheme);
+}
+
+bool IsRendererDebugURL(const GURL& url) {
+ if (!url.is_valid())
+ return false;
+
+ if (url.SchemeIs(url::kJavaScriptScheme))
+ return true;
+
+ if (!url.SchemeIs(kChromeUIScheme))
+ return false;
+
+ if (url == kChromeUICheckCrashURL || url == kChromeUIBadCastCrashURL ||
+ url == kChromeUICrashURL || url == kChromeUIDumpURL ||
+ url == kChromeUIKillURL || url == kChromeUIHangURL ||
+ url == kChromeUIShorthangURL || url == kChromeUIMemoryExhaustURL) {
+ return true;
+ }
+
+#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
+ if (url == kChromeUICrashHeapOverflowURL ||
+ url == kChromeUICrashHeapUnderflowURL ||
+ url == kChromeUICrashUseAfterFreeURL) {
+ return true;
+ }
+#endif
+
+#if defined(SYZYASAN)
+ if (url == kChromeUICrashCorruptHeapBlockURL ||
+ url == kChromeUICrashCorruptHeapURL || url == kChromeUICrashDcheckURL) {
+ return true;
+ }
+#endif
+
+ return false;
+}
+
} // namespace content
diff --git a/chromium/content/public/common/url_utils.h b/chromium/content/public/common/url_utils.h
index 60d447c9bf3..7161cbd9688 100644
--- a/chromium/content/public/common/url_utils.h
+++ b/chromium/content/public/common/url_utils.h
@@ -22,7 +22,22 @@ CONTENT_EXPORT bool IsSavableURL(const GURL& url);
// Helper function to determine if the navigation to |url| should make a request
// to the network stack. A request should not be sent for JavaScript URLs or
// about:blank. In these cases, no request needs to be sent.
-bool CONTENT_EXPORT IsURLHandledByNetworkStack(const GURL& url);
+CONTENT_EXPORT bool IsURLHandledByNetworkStack(const GURL& url);
+
+// Returns whether the given url is either a debugging url handled in the
+// renderer process, such as one that crashes or hangs the renderer, or a
+// javascript: URL that operates on the current page in the renderer. Such URLs
+// do not represent actual navigations and can be loaded in any SiteInstance.
+CONTENT_EXPORT bool IsRendererDebugURL(const GURL& url);
+
+// Helper function to determine if a request for |url| refers to a network
+// resource (as opposed to a local browser resource like files or blobs). Used
+// when the Network Service is enabled.
+//
+// Note that this is not equivalent to the above function, as several
+// non-network schemes are handled by the network stack when the Network Service
+// is disabled.
+bool CONTENT_EXPORT IsURLHandledByNetworkService(const GURL& url);
} // namespace content
diff --git a/chromium/content/public/common/web_preferences.cc b/chromium/content/public/common/web_preferences.cc
index 722afb30f66..cc20936125f 100644
--- a/chromium/content/public/common/web_preferences.cc
+++ b/chromium/content/public/common/web_preferences.cc
@@ -87,7 +87,6 @@ WebPreferences::WebPreferences()
loads_images_automatically(true),
images_enabled(true),
plugins_enabled(true),
- encrypted_media_enabled(true),
dom_paste_enabled(false), // enables execCommand("paste")
shrinks_standalone_images_to_fit(true),
text_areas_are_resizable(true),
diff --git a/chromium/content/public/common/web_preferences.h b/chromium/content/public/common/web_preferences.h
index c81979993ad..361505babff 100644
--- a/chromium/content/public/common/web_preferences.h
+++ b/chromium/content/public/common/web_preferences.h
@@ -112,7 +112,6 @@ struct CONTENT_EXPORT WebPreferences {
bool loads_images_automatically;
bool images_enabled;
bool plugins_enabled;
- bool encrypted_media_enabled;
bool dom_paste_enabled;
bool shrinks_standalone_images_to_fit;
bool text_areas_are_resizable;
diff --git a/chromium/content/public/common/webplugininfo.h b/chromium/content/public/common/webplugininfo.h
index 4061522d2cf..e1560e5b086 100644
--- a/chromium/content/public/common/webplugininfo.h
+++ b/chromium/content/public/common/webplugininfo.h
@@ -39,8 +39,14 @@ struct CONTENT_EXPORT WebPluginMimeType {
base::string16 description;
// Extra parameters to include when instantiating the plugin.
- std::vector<base::string16> additional_param_names;
- std::vector<base::string16> additional_param_values;
+ struct Param {
+ Param() = default;
+ Param(base::string16 n, base::string16 v)
+ : name(std::move(n)), value(std::move(v)) {}
+ base::string16 name;
+ base::string16 value;
+ };
+ std::vector<Param> additional_params;
};
// Describes an available Pepper plugin.
diff --git a/chromium/content/public/common/mutable_network_traffic_annotation_tag.mojom b/chromium/content/public/common/webplugininfo.mojom
index acc2d9eef45..7d9723dba99 100644
--- a/chromium/content/public/common/mutable_network_traffic_annotation_tag.mojom
+++ b/chromium/content/public/common/webplugininfo.mojom
@@ -4,6 +4,5 @@
module content.mojom;
-struct MutableNetworkTrafficAnnotationTag {
- uint32 unique_id_hash_code;
-};
+[Native]
+struct WebPluginInfo;
diff --git a/chromium/content/public/common/webplugininfo.typemap b/chromium/content/public/common/webplugininfo.typemap
new file mode 100644
index 00000000000..6083ceeab09
--- /dev/null
+++ b/chromium/content/public/common/webplugininfo.typemap
@@ -0,0 +1,12 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//content/public/common/webplugininfo.mojom"
+public_headers = [ "//content/public/common/webplugininfo.h" ]
+traits_headers = [ "//content/public/common/webplugininfo_param_traits.h" ]
+public_deps = [
+ "//ipc",
+]
+
+type_mappings = [ "content.mojom.WebPluginInfo=content::WebPluginInfo" ]
diff --git a/chromium/content/public/common/webplugininfo_param_traits.h b/chromium/content/public/common/webplugininfo_param_traits.h
new file mode 100644
index 00000000000..27182e84b28
--- /dev/null
+++ b/chromium/content/public/common/webplugininfo_param_traits.h
@@ -0,0 +1,33 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Multiply included file.
+
+#include "content/public/common/webplugininfo.h"
+#include "ipc/ipc_message_macros.h"
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+
+IPC_STRUCT_TRAITS_BEGIN(content::WebPluginMimeType::Param)
+ IPC_STRUCT_TRAITS_MEMBER(name)
+ IPC_STRUCT_TRAITS_MEMBER(value)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(content::WebPluginMimeType)
+ IPC_STRUCT_TRAITS_MEMBER(mime_type)
+ IPC_STRUCT_TRAITS_MEMBER(file_extensions)
+ IPC_STRUCT_TRAITS_MEMBER(description)
+ IPC_STRUCT_TRAITS_MEMBER(additional_params)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(content::WebPluginInfo)
+ IPC_STRUCT_TRAITS_MEMBER(name)
+ IPC_STRUCT_TRAITS_MEMBER(path)
+ IPC_STRUCT_TRAITS_MEMBER(version)
+ IPC_STRUCT_TRAITS_MEMBER(desc)
+ IPC_STRUCT_TRAITS_MEMBER(mime_types)
+ IPC_STRUCT_TRAITS_MEMBER(type)
+ IPC_STRUCT_TRAITS_MEMBER(pepper_permissions)
+IPC_STRUCT_TRAITS_END()
diff --git a/chromium/content/public/network/BUILD.gn b/chromium/content/public/network/BUILD.gn
index 23721c8d015..e1f855264e6 100644
--- a/chromium/content/public/network/BUILD.gn
+++ b/chromium/content/public/network/BUILD.gn
@@ -21,6 +21,8 @@ target("source_set", "network_sources") {
configs += [ "//content:content_implementation" ]
sources = [
+ "ignore_errors_cert_verifier.cc",
+ "ignore_errors_cert_verifier.h",
"network_service.h",
"url_request_context_builder_mojo.cc",
"url_request_context_builder_mojo.h",
@@ -30,5 +32,7 @@ target("source_set", "network_sources") {
"//base",
"//content:export",
"//content/common:mojo_bindings",
+ "//content/public/common:common_sources",
+ "//services/proxy_resolver/public/interfaces",
]
}
diff --git a/chromium/content/public/network/DEPS b/chromium/content/public/network/DEPS
index 31545d01b46..e2720f757e3 100644
--- a/chromium/content/public/network/DEPS
+++ b/chromium/content/public/network/DEPS
@@ -1,5 +1,6 @@
specific_include_rules = {
".*\.cc": [
"+content/network",
+ "+services/proxy_resolver/public/interfaces",
],
}
diff --git a/chromium/content/browser/ssl/ignore_errors_cert_verifier.cc b/chromium/content/public/network/ignore_errors_cert_verifier.cc
index 7fe840b8820..5cf65652b25 100644
--- a/chromium/content/browser/ssl/ignore_errors_cert_verifier.cc
+++ b/chromium/content/public/network/ignore_errors_cert_verifier.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/public/browser/ignore_errors_cert_verifier.h"
+#include "content/public/network/ignore_errors_cert_verifier.h"
#include <iterator>
#include <utility>
@@ -36,7 +36,7 @@ std::unique_ptr<CertVerifier> IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
const base::CommandLine& command_line,
const char* user_data_dir_switch,
std::unique_ptr<CertVerifier> verifier) {
- if (!command_line.HasSwitch(user_data_dir_switch) ||
+ if ((user_data_dir_switch && !command_line.HasSwitch(user_data_dir_switch)) ||
!command_line.HasSwitch(switches::kIgnoreCertificateErrorsSPKIList)) {
return verifier;
}
@@ -44,7 +44,7 @@ std::unique_ptr<CertVerifier> IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
base::SplitString(command_line.GetSwitchValueASCII(
switches::kIgnoreCertificateErrorsSPKIList),
",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- return base::MakeUnique<IgnoreErrorsCertVerifier>(
+ return std::make_unique<IgnoreErrorsCertVerifier>(
std::move(verifier), IgnoreErrorsCertVerifier::MakeWhitelist(spki_list));
}
diff --git a/chromium/content/public/browser/ignore_errors_cert_verifier.h b/chromium/content/public/network/ignore_errors_cert_verifier.h
index 28625b4e976..9c5c50304b9 100644
--- a/chromium/content/public/browser/ignore_errors_cert_verifier.h
+++ b/chromium/content/public/network/ignore_errors_cert_verifier.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_PUBLIC_BROWSER_IGNORE_ERRORS_CERT_VERIFIER_H_
-#define CONTENT_PUBLIC_BROWSER_IGNORE_ERRORS_CERT_VERIFIER_H_
+#ifndef CONTENT_PUBLIC_NETWORK_IGNORE_ERRORS_CERT_VERIFIER_H_
+#define CONTENT_PUBLIC_NETWORK_IGNORE_ERRORS_CERT_VERIFIER_H_
#include <memory>
#include <string>
@@ -30,13 +30,15 @@ class CONTENT_EXPORT IgnoreErrorsCertVerifier : public net::CertVerifier {
using SPKIHashSet =
base::flat_set<net::SHA256HashValue, net::SHA256HashValueLessThan>;
- // MaybeWrapCertVerifier returns an IgnoreErrorsCertVerifier wrapping the
- // supplied verifier using the whitelist from the
- // --ignore-certificate-errors-spki-list flag of the command line if the
- // --user-data-dir flag is also present. If either of these flags are missing,
- // it returns the supplied verifier.
+ // If the |user_data_dir_switch| is passed in as a valid pointer but
+ // --user-data-dir flag is missing, or --ignore-certificate-errors-spki-list
+ // flag is missing then MaybeWrapCertVerifier returns the supplied verifier.
+ // Otherwise it returns an IgnoreErrorsCertVerifier wrapping the supplied
+ // verifier using the whitelist from the
+ // --ignore-certificate-errors-spki-list flag.
+ //
// As the --user-data-dir flag is embedder defined, the flag to check for
- // needs to be passed in.
+ // needs to be passed in from |user_data_dir_switch|.
static std::unique_ptr<net::CertVerifier> MaybeWrapCertVerifier(
const base::CommandLine& command_line,
const char* user_data_dir_switch,
@@ -75,4 +77,4 @@ class CONTENT_EXPORT IgnoreErrorsCertVerifier : public net::CertVerifier {
} // namespace content
-#endif // CONTENT_PUBLIC_BROWSER_IGNORE_ERRORS_CERT_VERIFIER_H_
+#endif // CONTENT_PUBLIC_NETWORK_IGNORE_ERRORS_CERT_VERIFIER_H_
diff --git a/chromium/content/browser/ssl/ignore_errors_cert_verifier_unittest.cc b/chromium/content/public/network/ignore_errors_cert_verifier_unittest.cc
index 29ea418ec07..a7dc3bdbe0e 100644
--- a/chromium/content/browser/ssl/ignore_errors_cert_verifier_unittest.cc
+++ b/chromium/content/public/network/ignore_errors_cert_verifier_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 "content/public/browser/ignore_errors_cert_verifier.h"
+#include "content/public/network/ignore_errors_cert_verifier.h"
#include "base/base64.h"
#include "base/files/file_path.h"
@@ -165,7 +165,7 @@ class IgnoreCertificateErrorsSPKIListFlagTest
command_line.AppendSwitchASCII(switches::kIgnoreCertificateErrorsSPKIList,
base::JoinString(MakeWhitelist(), ","));
- auto mock_verifier = base::MakeUnique<MockCertVerifier>();
+ auto mock_verifier = std::make_unique<MockCertVerifier>();
mock_verifier->set_default_result(ERR_CERT_INVALID);
verifier_ = IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
command_line, kTestUserDataDirSwitch, std::move(mock_verifier));
diff --git a/chromium/content/public/network/mojo_proxy_resolver_factory.h b/chromium/content/public/network/mojo_proxy_resolver_factory.h
deleted file mode 100644
index 3d0888636b2..00000000000
--- a/chromium/content/public/network/mojo_proxy_resolver_factory.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_NETWORK_MOJO_PROXY_RESOLVER_FACTORY_H_
-#define CONTENT_PUBLIC_NETWORK_MOJO_PROXY_RESOLVER_FACTORY_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "base/callback_helpers.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
-#include "net/interfaces/host_resolver_service.mojom.h"
-#include "services/proxy_resolver/public/interfaces/proxy_resolver.mojom.h"
-
-namespace content {
-
-// Factory for connecting to Mojo ProxyResolver services.
-class MojoProxyResolverFactory {
- public:
- // Connect to a new ProxyResolver service using request |req|, using
- // |host_resolver| as the DNS resolver. The return value should be released
- // when the connection to |req| is no longer needed.
- // Note: The connection request |req| may be resolved asynchronously.
- virtual std::unique_ptr<base::ScopedClosureRunner> CreateResolver(
- const std::string& pac_script,
- mojo::InterfaceRequest<proxy_resolver::mojom::ProxyResolver> req,
- proxy_resolver::mojom::ProxyResolverFactoryRequestClientPtr client) = 0;
-
- protected:
- virtual ~MojoProxyResolverFactory() = default;
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_NETWORK_MOJO_PROXY_RESOLVER_FACTORY_H_
diff --git a/chromium/content/public/network/network_service.h b/chromium/content/public/network/network_service.h
index e257853573f..31d31127ea3 100644
--- a/chromium/content/public/network/network_service.h
+++ b/chromium/content/public/network/network_service.h
@@ -11,6 +11,7 @@
#include "content/public/common/network_service.mojom.h"
namespace net {
+class NetLog;
class URLRequestContext;
class URLRequestContextBuilder;
} // namespace net
@@ -20,7 +21,15 @@ namespace content {
// Allows an in-process NetworkService to be set up.
class CONTENT_EXPORT NetworkService : public mojom::NetworkService {
public:
- static std::unique_ptr<NetworkService> Create();
+ // Creates a NetworkService instance on the current thread, optionally using
+ // the passed-in NetLog. Does not take ownership of |net_log|. Must be
+ // destroyed before |net_log|.
+ //
+ // TODO(https://crbug.com/767450): Make it so NetworkService can always create
+ // its own NetLog, instead of sharing one.
+ static std::unique_ptr<NetworkService> Create(
+ mojom::NetworkServiceRequest request,
+ net::NetLog* net_log = nullptr);
// Can be used to seed a NetworkContext with a consumer-configured
// URLRequestContextBuilder, which |params| will then be applied to. The
@@ -33,8 +42,8 @@ class CONTENT_EXPORT NetworkService : public mojom::NetworkService {
// NetworkService, and will be removed once that ships.
virtual std::unique_ptr<mojom::NetworkContext>
CreateNetworkContextWithBuilder(
- content::mojom::NetworkContextRequest request,
- content::mojom::NetworkContextParamsPtr params,
+ mojom::NetworkContextRequest request,
+ mojom::NetworkContextParamsPtr params,
std::unique_ptr<net::URLRequestContextBuilder> builder,
net::URLRequestContext** url_request_context) = 0;
diff --git a/chromium/content/public/network/url_request_context_builder_mojo.cc b/chromium/content/public/network/url_request_context_builder_mojo.cc
index 644d208ede4..ee8e187e676 100644
--- a/chromium/content/public/network/url_request_context_builder_mojo.cc
+++ b/chromium/content/public/network/url_request_context_builder_mojo.cc
@@ -17,6 +17,17 @@ URLRequestContextBuilderMojo::URLRequestContextBuilderMojo()
URLRequestContextBuilderMojo::~URLRequestContextBuilderMojo() = default;
+void URLRequestContextBuilderMojo::SetDhcpFetcherFactory(
+ std::unique_ptr<net::DhcpProxyScriptFetcherFactory> dhcp_fetcher_factory) {
+ dhcp_fetcher_factory_ = std::move(dhcp_fetcher_factory);
+}
+
+void URLRequestContextBuilderMojo::SetMojoProxyResolverFactory(
+ proxy_resolver::mojom::ProxyResolverFactoryPtr
+ mojo_proxy_resolver_factory) {
+ mojo_proxy_resolver_factory_ = std::move(mojo_proxy_resolver_factory);
+}
+
std::unique_ptr<net::ProxyService>
URLRequestContextBuilderMojo::CreateProxyService(
std::unique_ptr<net::ProxyConfigService> proxy_config_service,
@@ -37,9 +48,9 @@ URLRequestContextBuilderMojo::CreateProxyService(
dhcp_fetcher_factory_->Create(url_request_context);
std::unique_ptr<net::ProxyScriptFetcher> proxy_script_fetcher =
std::make_unique<net::ProxyScriptFetcherImpl>(url_request_context);
- return content::CreateProxyServiceUsingMojoFactory(
- mojo_proxy_resolver_factory_, std::move(proxy_config_service),
- proxy_script_fetcher.release(), std::move(dhcp_proxy_script_fetcher),
+ return CreateProxyServiceUsingMojoFactory(
+ std::move(mojo_proxy_resolver_factory_), std::move(proxy_config_service),
+ std::move(proxy_script_fetcher), std::move(dhcp_proxy_script_fetcher),
host_resolver, net_log, network_delegate);
}
diff --git a/chromium/content/public/network/url_request_context_builder_mojo.h b/chromium/content/public/network/url_request_context_builder_mojo.h
index 3bef68b7925..0e6b2a1ddcc 100644
--- a/chromium/content/public/network/url_request_context_builder_mojo.h
+++ b/chromium/content/public/network/url_request_context_builder_mojo.h
@@ -12,6 +12,7 @@
#include "content/common/content_export.h"
#include "net/proxy/dhcp_proxy_script_fetcher_factory.h"
#include "net/url_request/url_request_context_builder.h"
+#include "services/proxy_resolver/public/interfaces/proxy_resolver.mojom.h"
namespace net {
class HostResolver;
@@ -23,12 +24,10 @@ class URLRequestContext;
namespace content {
-class MojoProxyResolverFactory;
-
// Specialization of URLRequestContextBuilder that can create a ProxyService
// that uses a Mojo ProxyResolver. The consumer is responsible for providing
-// the MojoProxyResolverFactory. If a PoxyService is set directly via the
-// URLRequestContextBuilder API, it will be used instead.
+// the proxy_resolver::mojom::ProxyResolverFactory. If a ProxyService is set
+// directly via the URLRequestContextBuilder API, it will be used instead.
class CONTENT_EXPORT URLRequestContextBuilderMojo
: public net::URLRequestContextBuilder {
public:
@@ -36,20 +35,15 @@ class CONTENT_EXPORT URLRequestContextBuilderMojo
~URLRequestContextBuilderMojo() override;
// Overrides default DhcpProxyScriptFetcherFactory. Ignored if no
- // MojoProxyResolverFactory is provided.
- void set_dhcp_fetcher_factory(
- std::unique_ptr<net::DhcpProxyScriptFetcherFactory>
- dhcp_fetcher_factory) {
- dhcp_fetcher_factory_ = std::move(dhcp_fetcher_factory);
- }
+ // proxy_resolver::mojom::ProxyResolverFactory is provided.
+ void SetDhcpFetcherFactory(
+ std::unique_ptr<net::DhcpProxyScriptFetcherFactory> dhcp_fetcher_factory);
// Sets Mojo factory used to create ProxyResolvers. If not set, falls back to
- // URLRequestContext's default behavior. The passed in factory must outlive
- // the URLRequestContext the builder creates.
- void set_mojo_proxy_resolver_factory(
- MojoProxyResolverFactory* mojo_proxy_resolver_factory) {
- mojo_proxy_resolver_factory_ = mojo_proxy_resolver_factory;
- }
+ // URLRequestContext's default behavior.
+ void SetMojoProxyResolverFactory(
+ proxy_resolver::mojom::ProxyResolverFactoryPtr
+ mojo_proxy_resolver_factory);
private:
std::unique_ptr<net::ProxyService> CreateProxyService(
@@ -61,7 +55,7 @@ class CONTENT_EXPORT URLRequestContextBuilderMojo
std::unique_ptr<net::DhcpProxyScriptFetcherFactory> dhcp_fetcher_factory_;
- MojoProxyResolverFactory* mojo_proxy_resolver_factory_ = nullptr;
+ proxy_resolver::mojom::ProxyResolverFactoryPtr mojo_proxy_resolver_factory_;
DISALLOW_COPY_AND_ASSIGN(URLRequestContextBuilderMojo);
};
diff --git a/chromium/content/public/renderer/BUILD.gn b/chromium/content/public/renderer/BUILD.gn
index b3c712b3a93..26bea0eff4e 100644
--- a/chromium/content/public/renderer/BUILD.gn
+++ b/chromium/content/public/renderer/BUILD.gn
@@ -32,6 +32,7 @@ target(link_target_type, "renderer_sources") {
"associated_resource_fetcher.h",
"browser_plugin_delegate.cc",
"browser_plugin_delegate.h",
+ "child_url_loader_factory_getter.h",
"chrome_object_extensions_utils.cc",
"chrome_object_extensions_utils.h",
"content_renderer_client.cc",
@@ -39,6 +40,8 @@ target(link_target_type, "renderer_sources") {
"context_menu_client.h",
"document_state.cc",
"document_state.h",
+ "fixed_received_data.cc",
+ "fixed_received_data.h",
"navigation_state.cc",
"navigation_state.h",
"pepper_plugin_instance.h",
@@ -61,12 +64,16 @@ target(link_target_type, "renderer_sources") {
"render_view_visitor.h",
"renderer_gamepad_provider.h",
"renderer_ppapi_host.h",
+ "request_peer.h",
+ "resource_dispatcher_delegate.h",
"resource_fetcher.h",
"seccomp_sandbox_status_android.h",
+ "v8_value_converter.h",
"video_encode_accelerator.cc",
"video_encode_accelerator.h",
"window_features_converter.cc",
"window_features_converter.h",
+ "worker_thread.h",
]
configs += [ "//content:content_implementation" ]
diff --git a/chromium/content/public/renderer/associated_resource_fetcher.h b/chromium/content/public/renderer/associated_resource_fetcher.h
index 52e6e9f2292..f6c12d88d1d 100644
--- a/chromium/content/public/renderer/associated_resource_fetcher.h
+++ b/chromium/content/public/renderer/associated_resource_fetcher.h
@@ -9,8 +9,8 @@
#include "base/callback.h"
#include "content/common/content_export.h"
-#include "third_party/WebKit/public/platform/WebCachePolicy.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
+#include "third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
class GURL;
@@ -44,7 +44,7 @@ class CONTENT_EXPORT AssociatedResourceFetcher {
virtual void SetServiceWorkerMode(
blink::WebURLRequest::ServiceWorkerMode service_worker_mode) = 0;
- virtual void SetCachePolicy(blink::WebCachePolicy policy) = 0;
+ virtual void SetCacheMode(blink::mojom::FetchCacheMode mode) = 0;
// Associate the corresponding WebURLLoaderOptions to the loader. Must be
// called before Start. Used if the LoaderType is FRAME_ASSOCIATED_LOADER.
@@ -62,8 +62,8 @@ class CONTENT_EXPORT AssociatedResourceFetcher {
virtual void Start(
blink::WebLocalFrame* frame,
blink::WebURLRequest::RequestContext request_context,
- blink::WebURLRequest::FetchRequestMode fetch_request_mode,
- blink::WebURLRequest::FetchCredentialsMode fetch_credentials_mode,
+ network::mojom::FetchRequestMode fetch_request_mode,
+ network::mojom::FetchCredentialsMode fetch_credentials_mode,
blink::WebURLRequest::FrameType frame_type,
const Callback& callback) = 0;
diff --git a/chromium/content/public/child/child_url_loader_factory_getter.h b/chromium/content/public/renderer/child_url_loader_factory_getter.h
index 3f394e260d5..38c03d33e05 100644
--- a/chromium/content/public/child/child_url_loader_factory_getter.h
+++ b/chromium/content/public/renderer/child_url_loader_factory_getter.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_PUBLIC_CHILD_CHILD_URL_LOADER_FACTORY_GETTER_H_
-#define CONTENT_PUBLIC_CHILD_CHILD_URL_LOADER_FACTORY_GETTER_H_
+#ifndef CONTENT_PUBLIC_RENDERER_CHILD_URL_LOADER_FACTORY_GETTER_H_
+#define CONTENT_PUBLIC_RENDERER_CHILD_URL_LOADER_FACTORY_GETTER_H_
#include "base/memory/ref_counted.h"
#include "content/public/common/url_loader_factory.mojom.h"
@@ -54,4 +54,4 @@ class ChildURLLoaderFactoryGetter
} // namespace content
-#endif // CONTENT_PUBLIC_CHILD_CHILD_URL_LOADER_FACTORY_GETTER_H_
+#endif // CONTENT_PUBLIC_RENDERER_CHILD_URL_LOADER_FACTORY_GETTER_H_
diff --git a/chromium/content/public/renderer/content_renderer_client.cc b/chromium/content/public/renderer/content_renderer_client.cc
index d8a56e64875..3e3d132705a 100644
--- a/chromium/content/public/renderer/content_renderer_client.cc
+++ b/chromium/content/public/renderer/content_renderer_client.cc
@@ -47,6 +47,10 @@ bool ContentRendererClient::ShouldSuppressErrorPage(RenderFrame* render_frame,
return false;
}
+bool ContentRendererClient::ShouldTrackUseCounter(const GURL& url) {
+ return true;
+}
+
void ContentRendererClient::DeferMediaLoad(
RenderFrame* render_frame,
bool has_played_media_before,
@@ -54,12 +58,6 @@ void ContentRendererClient::DeferMediaLoad(
closure.Run();
}
-std::unique_ptr<blink::WebMediaStreamCenter>
-ContentRendererClient::OverrideCreateWebMediaStreamCenter(
- blink::WebMediaStreamCenterClient* client) {
- return nullptr;
-}
-
std::unique_ptr<blink::WebMIDIAccessor>
ContentRendererClient::OverrideCreateMIDIAccessor(
blink::WebMIDIAccessorClient* client) {
@@ -161,7 +159,7 @@ ContentRendererClient::GetPrescientNetworking() {
bool ContentRendererClient::ShouldOverridePageVisibilityState(
const RenderFrame* render_frame,
- blink::WebPageVisibilityState* override_state) {
+ blink::mojom::PageVisibilityState* override_state) {
return false;
}
diff --git a/chromium/content/public/renderer/content_renderer_client.h b/chromium/content/public/renderer/content_renderer_client.h
index a05d000287b..3d34633700d 100644
--- a/chromium/content/public/renderer/content_renderer_client.h
+++ b/chromium/content/public/renderer/content_renderer_client.h
@@ -19,8 +19,8 @@
#include "build/build_config.h"
#include "content/public/common/content_client.h"
#include "media/base/decode_capabilities.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/WebContentSettingsClient.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
#include "third_party/WebKit/public/web/WebNavigationPolicy.h"
#include "third_party/WebKit/public/web/WebNavigationType.h"
#include "ui/base/page_transition_types.h"
@@ -41,8 +41,6 @@ class WebFrame;
class WebLocalFrame;
class WebMIDIAccessor;
class WebMIDIAccessorClient;
-class WebMediaStreamCenter;
-class WebMediaStreamCenterClient;
class WebPlugin;
class WebPrescientNetworking;
class WebSocketHandshakeThrottle;
@@ -119,6 +117,10 @@ class CONTENT_EXPORT ContentRendererClient {
virtual bool ShouldSuppressErrorPage(RenderFrame* render_frame,
const GURL& url);
+ // Returns false for new tab page activities, which should be filtered out in
+ // UseCounter; returns true otherwise.
+ virtual bool ShouldTrackUseCounter(const GURL& url);
+
// Returns the information to display when a navigation error occurs.
// If |error_html| is not null then it may be set to a HTML page containing
// the details of the error and maybe links to more info.
@@ -149,11 +151,6 @@ class CONTENT_EXPORT ContentRendererClient {
bool has_played_media_before,
const base::Closure& closure);
- // Allows the embedder to override creating a WebMediaStreamCenter. If it
- // returns NULL the content layer will create the stream center.
- virtual std::unique_ptr<blink::WebMediaStreamCenter>
- OverrideCreateWebMediaStreamCenter(blink::WebMediaStreamCenterClient* client);
-
// Allows the embedder to override creating a WebMIDIAccessor. If it
// returns NULL the content layer will create the MIDI accessor.
virtual std::unique_ptr<blink::WebMIDIAccessor> OverrideCreateMIDIAccessor(
@@ -248,7 +245,7 @@ class CONTENT_EXPORT ContentRendererClient {
virtual blink::WebPrescientNetworking* GetPrescientNetworking();
virtual bool ShouldOverridePageVisibilityState(
const RenderFrame* render_frame,
- blink::WebPageVisibilityState* override_state);
+ blink::mojom::PageVisibilityState* override_state);
// Returns true if the given Pepper plugin is external (requiring special
// startup steps).
diff --git a/chromium/content/public/child/fixed_received_data.cc b/chromium/content/public/renderer/fixed_received_data.cc
index 7f9030bacc6..a185a31cb98 100644
--- a/chromium/content/public/child/fixed_received_data.cc
+++ b/chromium/content/public/renderer/fixed_received_data.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/public/child/fixed_received_data.h"
+#include "content/public/renderer/fixed_received_data.h"
namespace content {
diff --git a/chromium/content/public/child/fixed_received_data.h b/chromium/content/public/renderer/fixed_received_data.h
index 0869ed075c4..5660bad3148 100644
--- a/chromium/content/public/child/fixed_received_data.h
+++ b/chromium/content/public/renderer/fixed_received_data.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_PUBLIC_CHILD_FIXED_RECEIVED_DATA_H_
-#define CONTENT_PUBLIC_CHILD_FIXED_RECEIVED_DATA_H_
+#ifndef CONTENT_PUBLIC_RENDERER_FIXED_RECEIVED_DATA_H_
+#define CONTENT_PUBLIC_RENDERER_FIXED_RECEIVED_DATA_H_
#include <stddef.h>
@@ -11,7 +11,7 @@
#include "base/macros.h"
#include "content/common/content_export.h"
-#include "content/public/child/request_peer.h"
+#include "content/public/renderer/request_peer.h"
namespace content {
@@ -34,4 +34,4 @@ class CONTENT_EXPORT FixedReceivedData final
} // namespace content
-#endif // CONTENT_PUBLIC_CHILD_FIXED_RECEIVED_DATA_H_
+#endif // CONTENT_PUBLIC_RENDERER_FIXED_RECEIVED_DATA_H_
diff --git a/chromium/content/public/renderer/render_frame.h b/chromium/content/public/renderer/render_frame.h
index 6ba116cc4cd..229f73c8ef4 100644
--- a/chromium/content/public/renderer/render_frame.h
+++ b/chromium/content/public/renderer/render_frame.h
@@ -19,12 +19,14 @@
#include "ipc/ipc_sender.h"
#include "ppapi/features/features.h"
#include "services/service_manager/public/cpp/binder_registry.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/TaskType.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
#include "third_party/WebKit/public/web/WebNavigationPolicy.h"
#include "third_party/WebKit/public/web/WebTriggeringEventInfo.h"
namespace blink {
+class AssociatedInterfaceProvider;
+class AssociatedInterfaceRegistry;
class WebFrame;
class WebLocalFrame;
class WebPlugin;
@@ -51,8 +53,6 @@ class Isolate;
}
namespace content {
-class AssociatedInterfaceProvider;
-class AssociatedInterfaceRegistry;
class ChildURLLoaderFactoryGetter;
class ContextMenuClient;
class PluginInstanceThrottler;
@@ -167,12 +167,14 @@ class CONTENT_EXPORT RenderFrame : public IPC::Listener,
// Returns the AssociatedInterfaceRegistry this frame can use to expose
// frame-specific Channel-associated interfaces to the remote RenderFrameHost.
- virtual AssociatedInterfaceRegistry* GetAssociatedInterfaceRegistry() = 0;
+ virtual blink::AssociatedInterfaceRegistry*
+ GetAssociatedInterfaceRegistry() = 0;
// Returns the AssociatedInterfaceProvider this frame can use to access
- // frame-specific Channel-assocaited interfaces from the remote
+ // frame-specific Channel-associated interfaces from the remote
// RenderFrameHost.
- virtual AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() = 0;
+ virtual blink::AssociatedInterfaceProvider*
+ GetRemoteAssociatedInterfaces() = 0;
#if BUILDFLAG(ENABLE_PLUGINS)
// Registers a plugin that has been marked peripheral. If the origin
@@ -253,7 +255,7 @@ class CONTENT_EXPORT RenderFrame : public IPC::Listener,
virtual bool IsPasting() const = 0;
// Returns the current visibility of the frame.
- virtual blink::WebPageVisibilityState GetVisibilityState() const = 0;
+ virtual blink::mojom::PageVisibilityState GetVisibilityState() const = 0;
// If PlzNavigate is enabled, returns true in between teh time that Blink
// requests navigation until the browser responds with the result.
diff --git a/chromium/content/public/renderer/render_frame_observer.cc b/chromium/content/public/renderer/render_frame_observer.cc
index 9e26c91976b..6b7909b41b0 100644
--- a/chromium/content/public/renderer/render_frame_observer.cc
+++ b/chromium/content/public/renderer/render_frame_observer.cc
@@ -46,7 +46,7 @@ RenderFrame* RenderFrameObserver::render_frame() const {
}
void RenderFrameObserver::RenderFrameGone() {
- render_frame_ = NULL;
+ render_frame_ = nullptr;
}
} // namespace content
diff --git a/chromium/content/public/renderer/render_thread.cc b/chromium/content/public/renderer/render_thread.cc
index 4cc2c50f733..b8189baa56d 100644
--- a/chromium/content/public/renderer/render_thread.cc
+++ b/chromium/content/public/renderer/render_thread.cc
@@ -24,7 +24,7 @@ RenderThread::RenderThread() {
}
RenderThread::~RenderThread() {
- lazy_tls.Pointer()->Set(NULL);
+ lazy_tls.Pointer()->Set(nullptr);
}
} // namespace content
diff --git a/chromium/content/public/renderer/render_thread_observer.h b/chromium/content/public/renderer/render_thread_observer.h
index 97af873217f..35b708e7a26 100644
--- a/chromium/content/public/renderer/render_thread_observer.h
+++ b/chromium/content/public/renderer/render_thread_observer.h
@@ -8,12 +8,15 @@
#include "base/macros.h"
#include "content/common/content_export.h"
+namespace blink {
+class AssociatedInterfaceRegistry;
+}
+
namespace IPC {
class Message;
}
namespace content {
-class AssociatedInterfaceRegistry;
// Base class for objects that want to filter control IPC messages and get
// notified of events.
@@ -24,9 +27,9 @@ class CONTENT_EXPORT RenderThreadObserver {
// Allows handling incoming Mojo requests.
virtual void RegisterMojoInterfaces(
- AssociatedInterfaceRegistry* associated_interfaces) {}
+ blink::AssociatedInterfaceRegistry* associated_interfaces) {}
virtual void UnregisterMojoInterfaces(
- AssociatedInterfaceRegistry* associated_interfaces) {}
+ blink::AssociatedInterfaceRegistry* associated_interfaces) {}
// Allows filtering of control messages.
virtual bool OnControlMessageReceived(const IPC::Message& message);
diff --git a/chromium/content/public/renderer/render_view.h b/chromium/content/public/renderer/render_view.h
index b6de6986e81..b1d79d080a3 100644
--- a/chromium/content/public/renderer/render_view.h
+++ b/chromium/content/public/renderer/render_view.h
@@ -70,6 +70,9 @@ class CONTENT_EXPORT RenderView : public IPC::Sender {
// Returns the device scale factor of the display the render view is in.
virtual float GetDeviceScaleFactor() const = 0;
+ // Returns the device scale factor of the display the render view is in.
+ virtual float GetZoomLevel() const = 0;
+
// Gets WebKit related preferences associated with this view.
virtual const WebPreferences& GetWebkitPreferences() = 0;
diff --git a/chromium/content/public/renderer/renderer_ppapi_host.h b/chromium/content/public/renderer/renderer_ppapi_host.h
index 068b82a92e6..b376692d4fc 100644
--- a/chromium/content/public/renderer/renderer_ppapi_host.h
+++ b/chromium/content/public/renderer/renderer_ppapi_host.h
@@ -83,10 +83,6 @@ class RendererPpapiHost {
virtual blink::WebPluginContainer* GetContainerForInstance(
PP_Instance instance) const = 0;
- // Returns the PID of the child process containing the plugin. If running
- // in-process, this returns base::kNullProcessId.
- virtual base::ProcessId GetPluginPID() const = 0;
-
// Returns true if the given instance is considered to be currently
// processing a user gesture or the plugin module has the "override user
// gesture" flag set (in which case it can always do things normally
diff --git a/chromium/content/public/child/request_peer.h b/chromium/content/public/renderer/request_peer.h
index 3ecdf0e408e..888bd868d6b 100644
--- a/chromium/content/public/child/request_peer.h
+++ b/chromium/content/public/renderer/request_peer.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_PUBLIC_CHILD_REQUEST_PEER_H_
-#define CONTENT_PUBLIC_CHILD_REQUEST_PEER_H_
+#ifndef CONTENT_PUBLIC_RENDERER_REQUEST_PEER_H_
+#define CONTENT_PUBLIC_RENDERER_REQUEST_PEER_H_
#include <stdint.h>
@@ -12,14 +12,14 @@
#include "content/common/content_export.h"
-namespace base {
-class TimeTicks;
-}
-
namespace net {
struct RedirectInfo;
}
+namespace network {
+struct URLLoaderCompletionStatus;
+}
+
namespace content {
struct ResourceResponseInfo;
@@ -93,16 +93,12 @@ class CONTENT_EXPORT RequestPeer {
// Called when the response is complete. This method signals completion of
// the resource load.
- virtual void OnCompletedRequest(int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size) = 0;
+ virtual void OnCompletedRequest(
+ const network::URLLoaderCompletionStatus& status) = 0;
virtual ~RequestPeer() {}
};
} // namespace content
-#endif // CONTENT_PUBLIC_CHILD_REQUEST_PEER_H_
+#endif // CONTENT_PUBLIC_RENDERER_REQUEST_PEER_H_
diff --git a/chromium/content/public/child/resource_dispatcher_delegate.h b/chromium/content/public/renderer/resource_dispatcher_delegate.h
index c8566f4fd57..f920439fbbb 100644
--- a/chromium/content/public/child/resource_dispatcher_delegate.h
+++ b/chromium/content/public/renderer/resource_dispatcher_delegate.h
@@ -2,19 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_PUBLIC_CHILD_RESOURCE_DISPATCHER_DELEGATE_H_
-#define CONTENT_PUBLIC_CHILD_RESOURCE_DISPATCHER_DELEGATE_H_
+#ifndef CONTENT_PUBLIC_RENDERER_RESOURCE_DISPATCHER_DELEGATE_H_
+#define CONTENT_PUBLIC_RENDERER_RESOURCE_DISPATCHER_DELEGATE_H_
#include <string>
#include "content/common/content_export.h"
#include "content/public/common/resource_type.h"
-class GURL;
-
namespace content {
class RequestPeer;
+struct ResourceResponseHead;
// Interface that allows observing request events and optionally replacing
// the peer. Note that if it doesn't replace the peer it must return the
@@ -29,12 +28,18 @@ class CONTENT_EXPORT ResourceDispatcherDelegate {
ResourceType resource_type,
int error_code) = 0;
+ // Note that |url|, |referrer| and |method| are the final values (e.g. after
+ // any redirects).
virtual std::unique_ptr<RequestPeer> OnReceivedResponse(
std::unique_ptr<RequestPeer> current_peer,
- const std::string& mime_type,
- const GURL& url) = 0;
+ int render_frame_id,
+ const GURL& url,
+ const GURL& referrer,
+ const std::string& method,
+ ResourceType resource_type,
+ const ResourceResponseHead& response_head) = 0;
};
} // namespace content
-#endif // CONTENT_PUBLIC_CHILD_RESOURCE_DISPATCHER_DELEGATE_H_
+#endif // CONTENT_PUBLIC_RENDERER_RESOURCE_DISPATCHER_DELEGATE_H_
diff --git a/chromium/content/public/child/v8_value_converter.h b/chromium/content/public/renderer/v8_value_converter.h
index 56305492c63..9bdeb2413a2 100644
--- a/chromium/content/public/child/v8_value_converter.h
+++ b/chromium/content/public/renderer/v8_value_converter.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_PUBLIC_CHILD_V8_VALUE_CONVERTER_H_
-#define CONTENT_PUBLIC_CHILD_V8_VALUE_CONVERTER_H_
+#ifndef CONTENT_PUBLIC_RENDERER_V8_VALUE_CONVERTER_H_
+#define CONTENT_PUBLIC_RENDERER_V8_VALUE_CONVERTER_H_
#include <memory>
@@ -132,4 +132,4 @@ class CONTENT_EXPORT V8ValueConverter {
} // namespace content
-#endif // CONTENT_PUBLIC_CHILD_V8_VALUE_CONVERTER_H_
+#endif // CONTENT_PUBLIC_RENDERER_V8_VALUE_CONVERTER_H_
diff --git a/chromium/content/public/renderer/video_encode_accelerator.cc b/chromium/content/public/renderer/video_encode_accelerator.cc
index 99eebcd1f99..9d75b2a83cc 100644
--- a/chromium/content/public/renderer/video_encode_accelerator.cc
+++ b/chromium/content/public/renderer/video_encode_accelerator.cc
@@ -18,7 +18,7 @@ void CreateVideoEncodeAccelerator(
media::GpuVideoAcceleratorFactories* gpu_factories =
RenderThreadImpl::current()->GetGpuFactories();
if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) {
- callback.Run(NULL, std::unique_ptr<media::VideoEncodeAccelerator>());
+ callback.Run(nullptr, std::unique_ptr<media::VideoEncodeAccelerator>());
return;
}
diff --git a/chromium/content/public/child/worker_thread.h b/chromium/content/public/renderer/worker_thread.h
index 926b3bd9586..85a042c1505 100644
--- a/chromium/content/public/child/worker_thread.h
+++ b/chromium/content/public/renderer/worker_thread.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_PUBLIC_CHILD_WORKER_THREAD_H_
-#define CONTENT_PUBLIC_CHILD_WORKER_THREAD_H_
+#ifndef CONTENT_PUBLIC_RENDERER_WORKER_THREAD_H_
+#define CONTENT_PUBLIC_RENDERER_WORKER_THREAD_H_
#include "base/callback.h"
#include "base/macros.h"
@@ -51,4 +51,4 @@ class CONTENT_EXPORT WorkerThread {
} // namespace content
-#endif // CONTENT_PUBLIC_CHILD_WORKER_THREAD_H_
+#endif // CONTENT_PUBLIC_RENDERER_WORKER_THREAD_H_
diff --git a/chromium/content/public/test/android/BUILD.gn b/chromium/content/public/test/android/BUILD.gn
index 2ff16e3c591..b76543658e2 100644
--- a/chromium/content/public/test/android/BUILD.gn
+++ b/chromium/content/public/test/android/BUILD.gn
@@ -39,6 +39,7 @@ android_library("content_java_test_support") {
"javatests/src/org/chromium/content/browser/test/NativeLibraryTestRule.java",
"javatests/src/org/chromium/content/browser/test/util/ApplicationUtils.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",
@@ -48,6 +49,7 @@ android_library("content_java_test_support") {
"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/TestContentViewCore.java",
"javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java",
"javatests/src/org/chromium/content/browser/test/util/TestTouchUtils.java",
"javatests/src/org/chromium/content/browser/test/util/TestWebContentsObserver.java",
diff --git a/chromium/content/public/utility/content_utility_client.h b/chromium/content/public/utility/content_utility_client.h
index 9e7274f33dd..56f16390d26 100644
--- a/chromium/content/public/utility/content_utility_client.h
+++ b/chromium/content/public/utility/content_utility_client.h
@@ -13,10 +13,6 @@
#include "services/service_manager/embedder/embedded_service_info.h"
#include "services/service_manager/public/cpp/binder_registry.h"
-namespace service_manager {
-class InterfaceRegistry;
-}
-
namespace content {
// Embedder API for participating in renderer logic.
@@ -33,11 +29,6 @@ class CONTENT_EXPORT ContentUtilityClient {
// Allows the embedder to filter messages.
virtual bool OnMessageReceived(const IPC::Message& message);
- // Allows the client to expose interfaces from this utility process to the
- // browser process via |registry|.
- virtual void ExposeInterfacesToBrowser(
- service_manager::InterfaceRegistry* registry) {}
-
virtual void RegisterServices(StaticServiceMap* services) {}
virtual void RegisterNetworkBinders(
diff --git a/chromium/content/public/utility/utility_thread.cc b/chromium/content/public/utility/utility_thread.cc
index c75c258608b..df192924874 100644
--- a/chromium/content/public/utility/utility_thread.cc
+++ b/chromium/content/public/utility/utility_thread.cc
@@ -23,7 +23,7 @@ UtilityThread::UtilityThread() {
}
UtilityThread::~UtilityThread() {
- lazy_tls.Pointer()->Set(NULL);
+ lazy_tls.Pointer()->Set(nullptr);
}
} // namespace content
diff --git a/chromium/content/renderer/BUILD.gn b/chromium/content/renderer/BUILD.gn
index 98599431899..7cb7e736b02 100644
--- a/chromium/content/renderer/BUILD.gn
+++ b/chromium/content/renderer/BUILD.gn
@@ -46,6 +46,24 @@ target(link_target_type, "renderer") {
"android/synchronous_compositor_registry.h",
"android/synchronous_layer_tree_frame_sink.cc",
"android/synchronous_layer_tree_frame_sink.h",
+ "appcache/appcache_backend_proxy.cc",
+ "appcache/appcache_backend_proxy.h",
+ "appcache/appcache_dispatcher.cc",
+ "appcache/appcache_dispatcher.h",
+ "appcache/appcache_frontend_impl.cc",
+ "appcache/appcache_frontend_impl.h",
+ "appcache/web_application_cache_host_impl.cc",
+ "appcache/web_application_cache_host_impl.h",
+ "background_sync/background_sync_type_converters.cc",
+ "background_sync/background_sync_type_converters.h",
+ "blob_storage/blob_consolidation.cc",
+ "blob_storage/blob_consolidation.h",
+ "blob_storage/blob_message_filter.cc",
+ "blob_storage/blob_message_filter.h",
+ "blob_storage/blob_transport_controller.cc",
+ "blob_storage/blob_transport_controller.h",
+ "blob_storage/webblobregistry_impl.cc",
+ "blob_storage/webblobregistry_impl.h",
"browser_plugin/browser_plugin.cc",
"browser_plugin/browser_plugin.h",
"browser_plugin/browser_plugin_manager.cc",
@@ -60,6 +78,8 @@ target(link_target_type, "renderer") {
"categorized_worker_pool.h",
"child_frame_compositing_helper.cc",
"child_frame_compositing_helper.h",
+ "child_message_filter.cc",
+ "child_message_filter.h",
"clipboard_utils.cc",
"clipboard_utils.h",
"content_security_policy_util.cc",
@@ -75,12 +95,10 @@ target(link_target_type, "renderer") {
"device_sensors/device_sensor_event_pump.h",
"devtools/devtools_agent.cc",
"devtools/devtools_agent.h",
- "devtools/devtools_agent_filter.cc",
- "devtools/devtools_agent_filter.h",
- "devtools/devtools_client.cc",
- "devtools/devtools_client.h",
"devtools/devtools_cpu_throttler.cc",
"devtools/devtools_cpu_throttler.h",
+ "devtools/devtools_frontend_impl.cc",
+ "devtools/devtools_frontend_impl.h",
"devtools/render_widget_screen_metrics_emulator.cc",
"devtools/render_widget_screen_metrics_emulator.h",
"devtools/render_widget_screen_metrics_emulator_delegate.h",
@@ -99,6 +117,8 @@ target(link_target_type, "renderer") {
"dom_storage/local_storage_cached_areas.h",
"dom_storage/local_storage_namespace.cc",
"dom_storage/local_storage_namespace.h",
+ "dom_storage/session_web_storage_namespace_impl.cc",
+ "dom_storage/session_web_storage_namespace_impl.h",
"dom_storage/webstoragearea_impl.cc",
"dom_storage/webstoragearea_impl.h",
"dom_storage/webstoragenamespace_impl.cc",
@@ -115,6 +135,16 @@ 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",
@@ -155,6 +185,20 @@ target(link_target_type, "renderer") {
"ime_event_guard.h",
"in_process_renderer_thread.cc",
"in_process_renderer_thread.h",
+ "indexed_db/indexed_db_callbacks_impl.cc",
+ "indexed_db/indexed_db_callbacks_impl.h",
+ "indexed_db/indexed_db_database_callbacks_impl.cc",
+ "indexed_db/indexed_db_database_callbacks_impl.h",
+ "indexed_db/indexed_db_dispatcher.cc",
+ "indexed_db/indexed_db_dispatcher.h",
+ "indexed_db/indexed_db_key_builders.cc",
+ "indexed_db/indexed_db_key_builders.h",
+ "indexed_db/webidbcursor_impl.cc",
+ "indexed_db/webidbcursor_impl.h",
+ "indexed_db/webidbdatabase_impl.cc",
+ "indexed_db/webidbdatabase_impl.h",
+ "indexed_db/webidbfactory_impl.cc",
+ "indexed_db/webidbfactory_impl.h",
"input/frame_input_handler_impl.cc",
"input/frame_input_handler_impl.h",
"input/input_event_filter.cc",
@@ -194,8 +238,44 @@ target(link_target_type, "renderer") {
"java/gin_java_function_invocation_helper.h",
"layout_test_dependencies.cc",
"layout_test_dependencies.h",
- "manifest/manifest_debug_info.cc",
- "manifest/manifest_debug_info.h",
+ "loader/child_resource_message_filter.cc",
+ "loader/child_resource_message_filter.h",
+ "loader/child_url_loader_factory_getter_impl.cc",
+ "loader/child_url_loader_factory_getter_impl.h",
+ "loader/cors_url_loader.cc",
+ "loader/cors_url_loader.h",
+ "loader/cors_url_loader_factory.cc",
+ "loader/cors_url_loader_factory.h",
+ "loader/ftp_directory_listing_response_delegate.cc",
+ "loader/ftp_directory_listing_response_delegate.h",
+ "loader/request_extra_data.cc",
+ "loader/request_extra_data.h",
+ "loader/resource_dispatcher.cc",
+ "loader/resource_dispatcher.h",
+ "loader/resource_scheduling_filter.cc",
+ "loader/resource_scheduling_filter.h",
+ "loader/shared_memory_data_consumer_handle.cc",
+ "loader/shared_memory_data_consumer_handle.h",
+ "loader/shared_memory_received_data_factory.cc",
+ "loader/shared_memory_received_data_factory.h",
+ "loader/site_isolation_stats_gatherer.cc",
+ "loader/site_isolation_stats_gatherer.h",
+ "loader/sync_load_context.cc",
+ "loader/sync_load_context.h",
+ "loader/sync_load_response.cc",
+ "loader/sync_load_response.h",
+ "loader/url_loader_client_impl.cc",
+ "loader/url_loader_client_impl.h",
+ "loader/url_response_body_consumer.cc",
+ "loader/url_response_body_consumer.h",
+ "loader/web_data_consumer_handle_impl.cc",
+ "loader/web_data_consumer_handle_impl.h",
+ "loader/web_url_loader_impl.cc",
+ "loader/web_url_loader_impl.h",
+ "loader/web_url_request_util.cc",
+ "loader/web_url_request_util.h",
+ "loader/weburlresponse_extradata_impl.cc",
+ "loader/weburlresponse_extradata_impl.h",
"manifest/manifest_manager.cc",
"manifest/manifest_manager.h",
"manifest/manifest_parser.cc",
@@ -246,6 +326,8 @@ target(link_target_type, "renderer") {
"media/media_permission_dispatcher.h",
"media/midi_message_filter.cc",
"media/midi_message_filter.h",
+ "media/mojo_audio_input_ipc.cc",
+ "media/mojo_audio_input_ipc.h",
"media/mojo_audio_output_ipc.cc",
"media/mojo_audio_output_ipc.h",
"media/render_media_client.cc",
@@ -275,18 +357,18 @@ target(link_target_type, "renderer") {
"mojo/blink_interface_registry_impl.h",
"mojo/interface_provider_js_wrapper.cc",
"mojo/interface_provider_js_wrapper.h",
- "mojo_bindings_controller.cc",
- "mojo_bindings_controller.h",
- "mojo_context_state.cc",
- "mojo_context_state.h",
- "mojo_main_runner.cc",
- "mojo_main_runner.h",
"mouse_lock_dispatcher.cc",
"mouse_lock_dispatcher.h",
"navigation_state_impl.cc",
"navigation_state_impl.h",
"net_info_helper.cc",
"net_info_helper.h",
+ "notifications/notification_data_conversions.cc",
+ "notifications/notification_data_conversions.h",
+ "notifications/notification_dispatcher.cc",
+ "notifications/notification_dispatcher.h",
+ "notifications/notification_manager.cc",
+ "notifications/notification_manager.h",
"origin_trials/web_trial_token_validator_impl.cc",
"origin_trials/web_trial_token_validator_impl.h",
"p2p/network_list_manager.h",
@@ -299,6 +381,10 @@ target(link_target_type, "renderer") {
"presentation/presentation_dispatcher.h",
"push_messaging/push_messaging_client.cc",
"push_messaging/push_messaging_client.h",
+ "push_messaging/push_provider.cc",
+ "push_messaging/push_provider.h",
+ "quota_dispatcher.cc",
+ "quota_dispatcher.h",
"render_frame_impl.cc",
"render_frame_impl.h",
"render_frame_proxy.cc",
@@ -321,8 +407,6 @@ target(link_target_type, "renderer") {
"render_widget_owner_delegate.h",
"renderer_blink_platform_impl.cc",
"renderer_blink_platform_impl.h",
- "renderer_clipboard_delegate.cc",
- "renderer_clipboard_delegate.h",
"renderer_main.cc",
"renderer_main_platform_delegate.h",
"renderer_main_platform_delegate_android.cc",
@@ -347,6 +431,10 @@ target(link_target_type, "renderer") {
"screen_orientation/screen_orientation_dispatcher.h",
"seccomp_sandbox_status_android.cc",
"seccomp_sandbox_status_android.h",
+ "service_worker/controller_service_worker_connector.cc",
+ "service_worker/controller_service_worker_connector.h",
+ "service_worker/controller_service_worker_impl.cc",
+ "service_worker/controller_service_worker_impl.h",
"service_worker/embedded_worker_devtools_agent.cc",
"service_worker/embedded_worker_devtools_agent.h",
"service_worker/embedded_worker_instance_client_impl.cc",
@@ -355,16 +443,36 @@ target(link_target_type, "renderer") {
"service_worker/service_worker_context_client.h",
"service_worker/service_worker_context_message_filter.cc",
"service_worker/service_worker_context_message_filter.h",
+ "service_worker/service_worker_dispatcher.cc",
+ "service_worker/service_worker_dispatcher.h",
"service_worker/service_worker_fetch_context_impl.cc",
"service_worker/service_worker_fetch_context_impl.h",
+ "service_worker/service_worker_handle_reference.cc",
+ "service_worker/service_worker_handle_reference.h",
+ "service_worker/service_worker_message_filter.cc",
+ "service_worker/service_worker_message_filter.h",
+ "service_worker/service_worker_network_provider.cc",
+ "service_worker/service_worker_network_provider.h",
+ "service_worker/service_worker_provider_context.cc",
+ "service_worker/service_worker_provider_context.h",
+ "service_worker/service_worker_subresource_loader.cc",
+ "service_worker/service_worker_subresource_loader.h",
+ "service_worker/service_worker_timeout_timer.cc",
+ "service_worker/service_worker_timeout_timer.h",
"service_worker/service_worker_type_converters.cc",
"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",
+ "service_worker/web_service_worker_registration_impl.h",
"service_worker/worker_fetch_context_impl.cc",
"service_worker/worker_fetch_context_impl.h",
"shared_memory_seqlock_reader.cc",
@@ -373,6 +481,8 @@ target(link_target_type, "renderer") {
"shared_worker/embedded_shared_worker_stub.h",
"shared_worker/shared_worker_client_impl.cc",
"shared_worker/shared_worker_client_impl.h",
+ "shared_worker/shared_worker_devtools_agent.cc",
+ "shared_worker/shared_worker_devtools_agent.h",
"shared_worker/shared_worker_factory_impl.cc",
"shared_worker/shared_worker_factory_impl.h",
"shared_worker/shared_worker_repository.cc",
@@ -385,12 +495,18 @@ target(link_target_type, "renderer") {
"stats_collection_controller.h",
"stats_collection_observer.cc",
"stats_collection_observer.h",
+ "storage_util.cc",
+ "storage_util.h",
"text_input_client_observer.cc",
"text_input_client_observer.h",
"theme_helper_mac.h",
"theme_helper_mac.mm",
"top_level_blame_context.cc",
"top_level_blame_context.h",
+ "v8_value_converter_impl.cc",
+ "v8_value_converter_impl.h",
+ "web_database_observer_impl.cc",
+ "web_database_observer_impl.h",
"web_frame_utils.cc",
"web_frame_utils.h",
"web_ui_extension.cc",
@@ -399,6 +515,8 @@ target(link_target_type, "renderer") {
"web_ui_extension_data.h",
"webclipboard_impl.cc",
"webclipboard_impl.h",
+ "webfileutilities_impl.cc",
+ "webfileutilities_impl.h",
"webgraphicscontext3d_provider_impl.cc",
"webgraphicscontext3d_provider_impl.h",
"webpublicsuffixlist_impl.cc",
@@ -407,6 +525,10 @@ target(link_target_type, "renderer") {
"webscrollbarbehavior_impl_aura.h",
"webscrollbarbehavior_impl_mac.h",
"webscrollbarbehavior_impl_mac.mm",
+ "worker_thread_message_filter.cc",
+ "worker_thread_message_filter.h",
+ "worker_thread_registry.cc",
+ "worker_thread_registry.h",
]
if (!is_component_build) {
@@ -496,6 +618,7 @@ target(link_target_type, "renderer") {
"//third_party/WebKit/common:blink_common",
"//third_party/WebKit/public:blink",
"//third_party/WebKit/public:features",
+ "//third_party/WebKit/public:media_devices_mojo_bindings",
"//third_party/WebKit/public:mojo_bindings",
"//third_party/boringssl",
"//third_party/icu",
@@ -620,8 +743,8 @@ target(link_target_type, "renderer") {
"media/media_stream_constraints_util_video_content.h",
"media/media_stream_constraints_util_video_device.cc",
"media/media_stream_constraints_util_video_device.h",
- "media/media_stream_dispatcher.cc",
- "media/media_stream_dispatcher.h",
+ "media/media_stream_device_observer.cc",
+ "media/media_stream_device_observer.h",
"media/media_stream_dispatcher_eventhandler.h",
"media/media_stream_registry_interface.h",
"media/media_stream_renderer_factory_impl.cc",
@@ -653,8 +776,6 @@ target(link_target_type, "renderer") {
"media/rtc_peer_connection_handler.cc",
"media/rtc_peer_connection_handler.h",
"media/secure_display_link_tracker.h",
- "media/speech_recognition_audio_sink.cc",
- "media/speech_recognition_audio_sink.h",
"media/track_audio_renderer.cc",
"media/track_audio_renderer.h",
"media/user_media_client_impl.cc",
@@ -669,6 +790,8 @@ target(link_target_type, "renderer") {
"media/webmediaplayer_ms.h",
"media/webmediaplayer_ms_compositor.cc",
"media/webmediaplayer_ms_compositor.h",
+ "media/webrtc/audio_codec_factory.cc",
+ "media/webrtc/audio_codec_factory.h",
"media/webrtc/media_stream_remote_video_source.cc",
"media/webrtc/media_stream_remote_video_source.h",
"media/webrtc/media_stream_track_metrics.cc",
@@ -704,6 +827,8 @@ target(link_target_type, "renderer") {
"media/webrtc/webrtc_media_stream_track_adapter.h",
"media/webrtc/webrtc_media_stream_track_adapter_map.cc",
"media/webrtc/webrtc_media_stream_track_adapter_map.h",
+ "media/webrtc/webrtc_set_remote_description_observer.cc",
+ "media/webrtc/webrtc_set_remote_description_observer.h",
"media/webrtc/webrtc_video_capturer_adapter.cc",
"media/webrtc/webrtc_video_capturer_adapter.h",
"media/webrtc/webrtc_video_frame_adapter.cc",
@@ -726,6 +851,12 @@ target(link_target_type, "renderer") {
"media_capture_from_element/html_audio_element_capturer_source.h",
"media_capture_from_element/html_video_element_capturer_source.cc",
"media_capture_from_element/html_video_element_capturer_source.h",
+ "media_recorder/audio_track_encoder.cc",
+ "media_recorder/audio_track_encoder.h",
+ "media_recorder/audio_track_opus_encoder.cc",
+ "media_recorder/audio_track_opus_encoder.h",
+ "media_recorder/audio_track_pcm_encoder.cc",
+ "media_recorder/audio_track_pcm_encoder.h",
"media_recorder/audio_track_recorder.cc",
"media_recorder/audio_track_recorder.h",
"media_recorder/media_recorder_handler.cc",
@@ -785,13 +916,25 @@ target(link_target_type, "renderer") {
"//third_party/webrtc/api:optional",
"//third_party/webrtc/api:rtc_stats_api",
"//third_party/webrtc/api:video_frame_api",
- "//third_party/webrtc/api/audio_codecs:builtin_audio_decoder_factory",
- "//third_party/webrtc/api/audio_codecs:builtin_audio_encoder_factory",
+ "//third_party/webrtc/api:video_frame_api_i420",
+ "//third_party/webrtc/api/audio_codecs:audio_codecs_api",
+ "//third_party/webrtc/api/audio_codecs/L16:audio_decoder_L16",
+ "//third_party/webrtc/api/audio_codecs/L16:audio_encoder_L16",
+ "//third_party/webrtc/api/audio_codecs/g711:audio_decoder_g711",
+ "//third_party/webrtc/api/audio_codecs/g711:audio_encoder_g711",
+ "//third_party/webrtc/api/audio_codecs/g722:audio_decoder_g722",
+ "//third_party/webrtc/api/audio_codecs/g722:audio_encoder_g722",
+ "//third_party/webrtc/api/audio_codecs/isac:audio_decoder_isac",
+ "//third_party/webrtc/api/audio_codecs/isac:audio_encoder_isac",
+ "//third_party/webrtc/api/audio_codecs/opus:audio_decoder_opus",
+ "//third_party/webrtc/api/audio_codecs/opus:audio_encoder_opus",
+ "//third_party/webrtc/api/video_codecs:video_codecs_api",
"//third_party/webrtc/common_video:common_video",
"//third_party/webrtc/media:rtc_media",
"//third_party/webrtc/media:rtc_media_base",
"//third_party/webrtc/modules/audio_device",
"//third_party/webrtc/modules/audio_processing",
+ "//third_party/webrtc/modules/audio_processing:audio_processing_statistics",
"//third_party/webrtc/modules/audio_processing/aec_dump",
"//third_party/webrtc/modules/video_coding:webrtc_h264",
"//third_party/webrtc/p2p:libstunprober",
diff --git a/chromium/content/renderer/DEPS b/chromium/content/renderer/DEPS
index 501c4755235..7d55efcedf4 100644
--- a/chromium/content/renderer/DEPS
+++ b/chromium/content/renderer/DEPS
@@ -23,7 +23,6 @@ include_rules = [
"+mojo",
"+services",
"-storage/browser",
- "+storage/public/interfaces",
"+third_party/hyphen/hyphen.h",
"+third_party/webrtc_overrides",
"+third_party/WebKit/common/origin_trials",
@@ -47,5 +46,8 @@ specific_include_rules = {
# embedded in mus won't be able to talk to the native ozone.
"renderer_main\.cc": [
"+ui/ozone/public/client_native_pixmap_factory_ozone.h",
+ ],
+ "service_worker_subresource_loader_unittest\.cc": [
+ "+storage/browser",
]
}
diff --git a/chromium/content/renderer/OWNERS b/chromium/content/renderer/OWNERS
index d83f872960a..91c0867c671 100644
--- a/chromium/content/renderer/OWNERS
+++ b/chromium/content/renderer/OWNERS
@@ -1,9 +1,8 @@
+haraken@chromium.org
+
# For Blink API usage
dglazkov@chromium.org
-# For Android
-aelias@chromium.org
-
# Mac Sandbox profiles.
per-file *.sb=set noparent
per-file *.sb=rsesek@chromium.org
@@ -11,3 +10,6 @@ per-file *.sb=rsesek@chromium.org
# DirectWrite specific changes.
per-file renderer_font_platform_win.*=scottmg@chromium.org
per-file renderer_font_platform_win.*=cpu@chromium.org
+
+# For surface ID propagation and synchronization
+per-file child_frame_compositing_helper.*=fsamuel@chromium.org
diff --git a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
index cc683647020..1a22fd94b2f 100644
--- a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
+++ b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
@@ -110,8 +110,10 @@ ui::AXRole AXRoleFromBlink(blink::WebAXRole role) {
return ui::AX_ROLE_COLUMN;
case blink::kWebAXRoleColumnHeader:
return ui::AX_ROLE_COLUMN_HEADER;
- case blink::kWebAXRoleComboBox:
- return ui::AX_ROLE_COMBO_BOX;
+ case blink::kWebAXRoleComboBoxGrouping:
+ return ui::AX_ROLE_COMBO_BOX_GROUPING;
+ case blink::kWebAXRoleComboBoxMenuButton:
+ return ui::AX_ROLE_COMBO_BOX_MENU_BUTTON;
case blink::kWebAXRoleComplementary:
return ui::AX_ROLE_COMPLEMENTARY;
case blink::kWebAXRoleContentInfo:
@@ -282,6 +284,8 @@ ui::AXRole AXRoleFromBlink(blink::WebAXRole role) {
return ui::AX_ROLE_TERM;
case blink::kWebAXRoleTextField:
return ui::AX_ROLE_TEXT_FIELD;
+ case blink::kWebAXRoleTextFieldWithComboBox:
+ return ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX;
case blink::kWebAXRoleTime:
return ui::AX_ROLE_TIME;
case blink::kWebAXRoleTimer:
diff --git a/chromium/content/renderer/accessibility/blink_ax_tree_source.cc b/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
index 7eb04afbfbc..319e9fac45e 100644
--- a/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -431,13 +431,16 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
WebAXObject offset_container;
WebFloatRect bounds_in_container;
SkMatrix44 container_transform;
+ bool clips_children = false;
src.GetRelativeBounds(offset_container, bounds_in_container,
- container_transform);
+ container_transform, &clips_children);
dst->location = bounds_in_container;
if (!container_transform.isIdentity())
dst->transform = base::WrapUnique(new gfx::Transform(container_transform));
if (!offset_container.IsDetached())
dst->offset_container_id = offset_container.AxID();
+ if (clips_children)
+ dst->AddBoolAttribute(ui::AX_ATTR_CLIPS_CHILDREN, true);
AXContentNodeDataSparseAttributeAdapter sparse_attribute_adapter(dst);
src.GetSparseAXAttributes(sparse_attribute_adapter);
@@ -717,6 +720,11 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
if (src.MinValueForRange(&min_value)) {
dst->AddFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE, min_value);
}
+
+ float step_value;
+ if (src.StepValueForRange(&step_value)) {
+ dst->AddFloatAttribute(ui::AX_ATTR_STEP_VALUE_FOR_RANGE, step_value);
+ }
}
if (dst->role == ui::AX_ROLE_DIALOG ||
@@ -905,15 +913,15 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
// parent is the row, the row adds it as a child, and the column adds it
// as an indirect child.
int child_count = src.ChildCount();
+ std::vector<int32_t> indirect_child_ids;
for (int i = 0; i < child_count; ++i) {
WebAXObject child = src.ChildAt(i);
- std::vector<int32_t> indirect_child_ids;
if (!is_iframe && !child.IsDetached() && !IsParentUnignoredOf(src, child))
indirect_child_ids.push_back(child.AxID());
- if (indirect_child_ids.size() > 0) {
- dst->AddIntListAttribute(
- ui::AX_ATTR_INDIRECT_CHILD_IDS, indirect_child_ids);
- }
+ }
+ if (indirect_child_ids.size() > 0) {
+ dst->AddIntListAttribute(ui::AX_ATTR_INDIRECT_CHILD_IDS,
+ indirect_child_ids);
}
if (src.IsScrollableContainer()) {
diff --git a/chromium/content/renderer/accessibility/render_accessibility_impl.cc b/chromium/content/renderer/accessibility/render_accessibility_impl.cc
index 903ae5172b3..3dd8173b33e 100644
--- a/chromium/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl.cc
@@ -80,7 +80,20 @@ void RenderAccessibilityImpl::SnapshotAccessibilityTree(
ScopedFreezeBlinkAXTreeSource freeze(&tree_source);
BlinkAXTreeSerializer serializer(&tree_source);
serializer.set_max_node_count(kMaxSnapshotNodeCount);
- serializer.SerializeChanges(context.Root(), response);
+
+ if (serializer.SerializeChanges(context.Root(), response))
+ return;
+
+ // It's possible for the page to fail to serialize the first time due to
+ // aria-owns rearranging the page while it's being scanned. Try a second
+ // time.
+ *response = AXContentTreeUpdate();
+ if (serializer.SerializeChanges(context.Root(), response))
+ return;
+
+ // It failed again. Clear the response object because it might have errors.
+ *response = AXContentTreeUpdate();
+ LOG(WARNING) << "Unable to serialize accessibility tree.";
}
RenderAccessibilityImpl::RenderAccessibilityImpl(RenderFrameImpl* render_frame,
@@ -271,12 +284,24 @@ void RenderAccessibilityImpl::HandleAXEvent(
}
}
+ // 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 &&
+ event == ui::AX_EVENT_CHILDREN_CHANGED) {
+ WebAXObject popup_like_object = obj.ParentObject();
+ if (!popup_like_object.IsDetached()) {
+ serializer_.DeleteClientSubtree(popup_like_object);
+ HandleAXEvent(popup_like_object, ui::AX_EVENT_CHILDREN_CHANGED);
+ }
+ }
+
// Add the accessibility object to our cache and ensure it's valid.
AccessibilityHostMsg_EventParams acc_event;
acc_event.id = obj.AxID();
acc_event.event_type = event;
- if (blink::WebUserGestureIndicator::IsProcessingUserGesture())
+ if (blink::WebUserGestureIndicator::IsProcessingUserGesture(
+ render_frame_->GetWebFrame()))
acc_event.event_from = ui::AX_EVENT_FROM_USER;
else if (during_action_)
acc_event.event_from = ui::AX_EVENT_FROM_ACTION;
@@ -359,7 +384,7 @@ void RenderAccessibilityImpl::OnPluginRootNodeUpdated() {
}
WebDocument RenderAccessibilityImpl::GetMainDocument() {
- if (render_frame_ && render_frame_->GetWebFrame())
+ if (render_frame_->GetWebFrame())
return render_frame_->GetWebFrame()->GetDocument();
return WebDocument();
}
@@ -629,7 +654,11 @@ void RenderAccessibilityImpl::OnHitTest(const gfx::Point& point,
data.HasContentIntAttribute(
AX_CONTENT_ATTR_CHILD_BROWSER_PLUGIN_INSTANCE_ID)) {
Send(new AccessibilityHostMsg_ChildFrameHitTestResult(
- routing_id(), point, obj.AxID(), event_to_fire));
+ routing_id(), point,
+ data.GetContentIntAttribute(AX_CONTENT_ATTR_CHILD_ROUTING_ID),
+ data.GetContentIntAttribute(
+ AX_CONTENT_ATTR_CHILD_BROWSER_PLUGIN_INSTANCE_ID),
+ event_to_fire));
return;
}
diff --git a/chromium/content/renderer/accessibility/render_accessibility_impl.h b/chromium/content/renderer/accessibility/render_accessibility_impl.h
index 8cff8e90b00..7093dbd51c0 100644
--- a/chromium/content/renderer/accessibility/render_accessibility_impl.h
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl.h
@@ -112,9 +112,6 @@ class CONTENT_EXPORT RenderAccessibilityImpl
// versions. If any have moved, send an IPC with the new locations.
void SendLocationChanges();
- // The RenderFrameImpl that owns us.
- RenderFrameImpl* render_frame_;
-
private:
// RenderFrameObserver implementation.
void OnDestruct() override;
@@ -131,6 +128,9 @@ class CONTENT_EXPORT RenderAccessibilityImpl
void AddPluginTreeToUpdate(AXContentTreeUpdate* update);
void ScrollPlugin(int id_to_make_visible);
+ // The RenderFrameImpl that owns us.
+ RenderFrameImpl* render_frame_;
+
// Events from Blink are collected until they are ready to be
// sent to the browser.
std::vector<AccessibilityHostMsg_EventParams> pending_events_;
diff --git a/chromium/content/renderer/android/synchronous_compositor_filter.cc b/chromium/content/renderer/android/synchronous_compositor_filter.cc
index d045e9ca80e..79b9de0f0f3 100644
--- a/chromium/content/renderer/android/synchronous_compositor_filter.cc
+++ b/chromium/content/renderer/android/synchronous_compositor_filter.cc
@@ -187,7 +187,7 @@ void SynchronousCompositorFilter::CreateSynchronousCompositorProxy(
ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
DCHECK(sync_compositor_map_.find(routing_id) == sync_compositor_map_.end());
std::unique_ptr<SynchronousCompositorProxy> proxy =
- base::MakeUnique<SynchronousCompositorProxy>(
+ std::make_unique<SynchronousCompositorProxy>(
routing_id, this, synchronous_input_handler_proxy);
sync_compositor_map_[routing_id] = std::move(proxy);
}
diff --git a/chromium/content/renderer/android/synchronous_compositor_proxy.h b/chromium/content/renderer/android/synchronous_compositor_proxy.h
index 6e2c12323e7..af52f8074f8 100644
--- a/chromium/content/renderer/android/synchronous_compositor_proxy.h
+++ b/chromium/content/renderer/android/synchronous_compositor_proxy.h
@@ -10,7 +10,7 @@
#include "base/macros.h"
#include "base/optional.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
#include "content/renderer/android/synchronous_layer_tree_frame_sink.h"
#include "ui/events/blink/synchronous_input_handler_proxy.h"
#include "ui/gfx/geometry/scroll_offset.h"
diff --git a/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.cc b/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.cc
index 742d80f24d5..79b5099e03a 100644
--- a/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.cc
+++ b/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.cc
@@ -24,7 +24,7 @@
#include "components/viz/service/display/output_surface.h"
#include "components/viz/service/display/output_surface_frame.h"
#include "components/viz/service/display/software_output_device.h"
-#include "components/viz/service/display/texture_mailbox_deleter.h"
+#include "components/viz/service/display/texture_deleter.h"
#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "content/common/android/sync_compositor_messages.h"
@@ -190,8 +190,8 @@ bool SynchronousLayerTreeFrameSink::BindToClient(
viz::RendererSettings software_renderer_settings;
- auto output_surface = base::MakeUnique<SoftwareOutputSurface>(
- base::MakeUnique<SoftwareDevice>(&current_sw_canvas_));
+ auto output_surface = std::make_unique<SoftwareOutputSurface>(
+ std::make_unique<SoftwareDevice>(&current_sw_canvas_));
software_output_surface_ = output_surface.get();
// The gpu_memory_buffer_manager here is null as the Display is only used for
@@ -201,10 +201,10 @@ bool SynchronousLayerTreeFrameSink::BindToClient(
// resources.
// TODO(crbug.com/692814): The Display never sends its resources out of
// process so there is no reason for it to use a SharedBitmapManager.
- display_ = base::MakeUnique<viz::Display>(
+ display_ = std::make_unique<viz::Display>(
shared_bitmap_manager_, nullptr /* gpu_memory_buffer_manager */,
software_renderer_settings, kRootFrameSinkId, std::move(output_surface),
- nullptr /* scheduler */, nullptr /* texture_mailbox_deleter */);
+ nullptr /* scheduler */, nullptr /* current_task_runner */);
display_->Initialize(&display_client_,
frame_sink_manager_->surface_manager());
display_->SetVisible(true);
@@ -314,7 +314,7 @@ void SynchronousLayerTreeFrameSink::SubmitCompositorFrame(
surface_quad->SetNew(
shared_quad_state, gfx::Rect(child_size), gfx::Rect(child_size),
viz::SurfaceId(kChildFrameSinkId, child_local_surface_id_),
- viz::SurfaceDrawQuadType::PRIMARY, SK_ColorWHITE, nullptr);
+ base::nullopt, SK_ColorWHITE, false);
bool result = child_support_->SubmitCompositorFrame(child_local_surface_id_,
std::move(frame));
@@ -497,6 +497,15 @@ void SynchronousLayerTreeFrameSink::DidReceiveCompositorFrameAck(
ReclaimResources(resources);
}
+void SynchronousLayerTreeFrameSink::DidPresentCompositorFrame(
+ uint32_t presentation_token,
+ base::TimeTicks time,
+ base::TimeDelta refresh,
+ uint32_t flags) {}
+
+void SynchronousLayerTreeFrameSink::DidDiscardCompositorFrame(
+ uint32_t presentation_token) {}
+
void SynchronousLayerTreeFrameSink::OnBeginFrame(
const viz::BeginFrameArgs& args) {}
diff --git a/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.h b/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.h
index acfb95934a8..a3af84f93ca 100644
--- a/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.h
+++ b/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.h
@@ -98,6 +98,11 @@ class SynchronousLayerTreeFrameSink
// viz::mojom::CompositorFrameSinkClient implementation.
void DidReceiveCompositorFrameAck(
const std::vector<viz::ReturnedResource>& resources) override;
+ void DidPresentCompositorFrame(uint32_t presentation_token,
+ base::TimeTicks time,
+ base::TimeDelta refresh,
+ uint32_t flags) override;
+ void DidDiscardCompositorFrame(uint32_t presentation_token) override;
void OnBeginFrame(const viz::BeginFrameArgs& args) override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
diff --git a/chromium/content/child/appcache/OWNERS b/chromium/content/renderer/appcache/OWNERS
index 92b1943e320..21ddbb8551d 100644
--- a/chromium/content/child/appcache/OWNERS
+++ b/chromium/content/renderer/appcache/OWNERS
@@ -1,3 +1,7 @@
+pwnall@chromium.org
+jsbell@chromium.org
+
+# OOO until this comment is removed.
michaeln@chromium.org
# TEAM: storage-dev@chromium.org
diff --git a/chromium/content/child/appcache/appcache_backend_proxy.cc b/chromium/content/renderer/appcache/appcache_backend_proxy.cc
index c6b7ebd30d1..6b7ad4c5c9a 100644
--- a/chromium/content/child/appcache/appcache_backend_proxy.cc
+++ b/chromium/content/renderer/appcache/appcache_backend_proxy.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/child/appcache/appcache_backend_proxy.h"
+#include "content/renderer/appcache/appcache_backend_proxy.h"
#include "content/common/appcache_messages.h"
@@ -33,13 +33,6 @@ void AppCacheBackendProxy::SelectCache(
manifest_url));
}
-void AppCacheBackendProxy::SelectCacheForWorker(
- int host_id, int parent_process_id, int parent_host_id) {
- sender_->Send(new AppCacheHostMsg_SelectCacheForWorker(
- host_id, parent_process_id,
- parent_host_id));
-}
-
void AppCacheBackendProxy::SelectCacheForSharedWorker(int host_id,
int64_t appcache_id) {
sender_->Send(new AppCacheHostMsg_SelectCacheForSharedWorker(
@@ -56,7 +49,7 @@ void AppCacheBackendProxy::MarkAsForeignEntry(
}
AppCacheStatus AppCacheBackendProxy::GetStatus(int host_id) {
- AppCacheStatus status = APPCACHE_STATUS_UNCACHED;
+ AppCacheStatus status = AppCacheStatus::APPCACHE_STATUS_UNCACHED;
sender_->Send(new AppCacheHostMsg_GetStatus(host_id, &status));
return status;
}
diff --git a/chromium/content/child/appcache/appcache_backend_proxy.h b/chromium/content/renderer/appcache/appcache_backend_proxy.h
index 9c929c981b4..5ae06c5b38e 100644
--- a/chromium/content/child/appcache/appcache_backend_proxy.h
+++ b/chromium/content/renderer/appcache/appcache_backend_proxy.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_CHILD_APPCACHE_APPCACHE_BACKEND_PROXY_H_
-#define CONTENT_CHILD_APPCACHE_APPCACHE_BACKEND_PROXY_H_
+#ifndef CONTENT_RENDERER_APPCACHE_APPCACHE_BACKEND_PROXY_H_
+#define CONTENT_RENDERER_APPCACHE_APPCACHE_BACKEND_PROXY_H_
#include <stdint.h>
@@ -29,9 +29,6 @@ class AppCacheBackendProxy : public AppCacheBackend {
const GURL& document_url,
const int64_t cache_document_was_loaded_from,
const GURL& manifest_url) override;
- void SelectCacheForWorker(int host_id,
- int parent_process_id,
- int parent_host_id) override;
void SelectCacheForSharedWorker(int host_id, int64_t appcache_id) override;
void MarkAsForeignEntry(int host_id,
const GURL& document_url,
@@ -49,4 +46,4 @@ class AppCacheBackendProxy : public AppCacheBackend {
} // namespace content
-#endif // CONTENT_CHILD_APPCACHE_APPCACHE_BACKEND_PROXY_H_
+#endif // CONTENT_RENDERER_APPCACHE_APPCACHE_BACKEND_PROXY_H_
diff --git a/chromium/content/child/appcache/appcache_dispatcher.cc b/chromium/content/renderer/appcache/appcache_dispatcher.cc
index 0685219bba3..fad1973fad3 100644
--- a/chromium/content/child/appcache/appcache_dispatcher.cc
+++ b/chromium/content/renderer/appcache/appcache_dispatcher.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/child/appcache/appcache_dispatcher.h"
+#include "content/renderer/appcache/appcache_dispatcher.h"
#include "content/common/appcache_messages.h"
diff --git a/chromium/content/child/appcache/appcache_dispatcher.h b/chromium/content/renderer/appcache/appcache_dispatcher.h
index 2b43dc7e468..c1505ce7350 100644
--- a/chromium/content/child/appcache/appcache_dispatcher.h
+++ b/chromium/content/renderer/appcache/appcache_dispatcher.h
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_APPCACHE_APPCACHE_DISPATCHER_H_
-#define CONTENT_CHILD_APPCACHE_APPCACHE_DISPATCHER_H_
+#ifndef CONTENT_RENDERER_APPCACHE_APPCACHE_DISPATCHER_H_
+#define CONTENT_RENDERER_APPCACHE_APPCACHE_DISPATCHER_H_
#include <memory>
#include <string>
#include <vector>
-#include "content/child/appcache/appcache_backend_proxy.h"
#include "content/common/appcache_interfaces.h"
+#include "content/renderer/appcache/appcache_backend_proxy.h"
#include "ipc/ipc_listener.h"
#include "mojo/public/cpp/system/message_pipe.h"
@@ -52,4 +52,4 @@ class AppCacheDispatcher : public IPC::Listener {
} // namespace content
-#endif // CONTENT_CHILD_APPCACHE_APPCACHE_DISPATCHER_H_
+#endif // CONTENT_RENDERER_APPCACHE_APPCACHE_DISPATCHER_H_
diff --git a/chromium/content/child/appcache/appcache_frontend_impl.cc b/chromium/content/renderer/appcache/appcache_frontend_impl.cc
index 448ab75c8a7..88723a80083 100644
--- a/chromium/content/child/appcache/appcache_frontend_impl.cc
+++ b/chromium/content/renderer/appcache/appcache_frontend_impl.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/appcache/appcache_frontend_impl.h"
+#include "content/renderer/appcache/appcache_frontend_impl.h"
#include "base/logging.h"
-#include "content/child/appcache/web_application_cache_host_impl.h"
+#include "content/renderer/appcache/web_application_cache_host_impl.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
using blink::WebApplicationCacheHost;
@@ -37,9 +37,11 @@ void AppCacheFrontendImpl::OnStatusChanged(const std::vector<int>& host_ids,
void AppCacheFrontendImpl::OnEventRaised(const std::vector<int>& host_ids,
AppCacheEventID event_id) {
- DCHECK(event_id !=
- APPCACHE_PROGRESS_EVENT); // See OnProgressEventRaised.
- DCHECK(event_id != APPCACHE_ERROR_EVENT); // See OnErrorEventRaised.
+ DCHECK_NE(
+ event_id,
+ 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) {
WebApplicationCacheHostImpl* host = GetHost(*i);
@@ -103,47 +105,51 @@ void AppCacheFrontendImpl::OnSetSubresourceFactory(
"mismatched enum: " #a)
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kUncached,
- APPCACHE_STATUS_UNCACHED);
-STATIC_ASSERT_ENUM(WebApplicationCacheHost::kIdle, APPCACHE_STATUS_IDLE);
+ AppCacheStatus::APPCACHE_STATUS_UNCACHED);
+STATIC_ASSERT_ENUM(WebApplicationCacheHost::kIdle,
+ AppCacheStatus::APPCACHE_STATUS_IDLE);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kChecking,
- APPCACHE_STATUS_CHECKING);
+ AppCacheStatus::APPCACHE_STATUS_CHECKING);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kDownloading,
- APPCACHE_STATUS_DOWNLOADING);
+ AppCacheStatus::APPCACHE_STATUS_DOWNLOADING);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kUpdateReady,
- APPCACHE_STATUS_UPDATE_READY);
+ AppCacheStatus::APPCACHE_STATUS_UPDATE_READY);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kObsolete,
- APPCACHE_STATUS_OBSOLETE);
+ AppCacheStatus::APPCACHE_STATUS_OBSOLETE);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kCheckingEvent,
- APPCACHE_CHECKING_EVENT);
-STATIC_ASSERT_ENUM(WebApplicationCacheHost::kErrorEvent, APPCACHE_ERROR_EVENT);
+ AppCacheEventID::APPCACHE_CHECKING_EVENT);
+STATIC_ASSERT_ENUM(WebApplicationCacheHost::kErrorEvent,
+ AppCacheEventID::APPCACHE_ERROR_EVENT);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kNoUpdateEvent,
- APPCACHE_NO_UPDATE_EVENT);
+ AppCacheEventID::APPCACHE_NO_UPDATE_EVENT);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kDownloadingEvent,
- APPCACHE_DOWNLOADING_EVENT);
+ AppCacheEventID::APPCACHE_DOWNLOADING_EVENT);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kProgressEvent,
- APPCACHE_PROGRESS_EVENT);
+ AppCacheEventID::APPCACHE_PROGRESS_EVENT);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kUpdateReadyEvent,
- APPCACHE_UPDATE_READY_EVENT);
+ AppCacheEventID::APPCACHE_UPDATE_READY_EVENT);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kCachedEvent,
- APPCACHE_CACHED_EVENT);
+ AppCacheEventID::APPCACHE_CACHED_EVENT);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kObsoleteEvent,
- APPCACHE_OBSOLETE_EVENT);
+ AppCacheEventID::APPCACHE_OBSOLETE_EVENT);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kManifestError,
- APPCACHE_MANIFEST_ERROR);
+ AppCacheErrorReason::APPCACHE_MANIFEST_ERROR);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kSignatureError,
- APPCACHE_SIGNATURE_ERROR);
+ AppCacheErrorReason::APPCACHE_SIGNATURE_ERROR);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kResourceError,
- APPCACHE_RESOURCE_ERROR);
+ AppCacheErrorReason::APPCACHE_RESOURCE_ERROR);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kChangedError,
- APPCACHE_CHANGED_ERROR);
-STATIC_ASSERT_ENUM(WebApplicationCacheHost::kAbortError, APPCACHE_ABORT_ERROR);
-STATIC_ASSERT_ENUM(WebApplicationCacheHost::kQuotaError, APPCACHE_QUOTA_ERROR);
+ AppCacheErrorReason::APPCACHE_CHANGED_ERROR);
+STATIC_ASSERT_ENUM(WebApplicationCacheHost::kAbortError,
+ AppCacheErrorReason::APPCACHE_ABORT_ERROR);
+STATIC_ASSERT_ENUM(WebApplicationCacheHost::kQuotaError,
+ AppCacheErrorReason::APPCACHE_QUOTA_ERROR);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kPolicyError,
- APPCACHE_POLICY_ERROR);
+ AppCacheErrorReason::APPCACHE_POLICY_ERROR);
STATIC_ASSERT_ENUM(WebApplicationCacheHost::kUnknownError,
- APPCACHE_UNKNOWN_ERROR);
+ AppCacheErrorReason::APPCACHE_UNKNOWN_ERROR);
STATIC_ASSERT_ENUM(WebConsoleMessage::kLevelVerbose, APPCACHE_LOG_VERBOSE);
STATIC_ASSERT_ENUM(WebConsoleMessage::kLevelInfo, APPCACHE_LOG_INFO);
diff --git a/chromium/content/child/appcache/appcache_frontend_impl.h b/chromium/content/renderer/appcache/appcache_frontend_impl.h
index 65ad617257f..19fa7778ff9 100644
--- a/chromium/content/child/appcache/appcache_frontend_impl.h
+++ b/chromium/content/renderer/appcache/appcache_frontend_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_APPCACHE_APPCACHE_FRONTEND_IMPL_H_
-#define CONTENT_CHILD_APPCACHE_APPCACHE_FRONTEND_IMPL_H_
+#ifndef CONTENT_RENDERER_APPCACHE_APPCACHE_FRONTEND_IMPL_H_
+#define CONTENT_RENDERER_APPCACHE_APPCACHE_FRONTEND_IMPL_H_
#include "content/common/appcache_interfaces.h"
@@ -33,4 +33,4 @@ class AppCacheFrontendImpl : public AppCacheFrontend {
} // namespace content
-#endif // CONTENT_CHILD_APPCACHE_APPCACHE_FRONTEND_IMPL_H_
+#endif // CONTENT_RENDERER_APPCACHE_APPCACHE_FRONTEND_IMPL_H_
diff --git a/chromium/content/child/appcache/web_application_cache_host_impl.cc b/chromium/content/renderer/appcache/web_application_cache_host_impl.cc
index 33d422b9e49..a1c6a45fd12 100644
--- a/chromium/content/child/appcache/web_application_cache_host_impl.cc
+++ b/chromium/content/renderer/appcache/web_application_cache_host_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/appcache/web_application_cache_host_impl.h"
+#include "content/renderer/appcache/web_application_cache_host_impl.h"
#include <stddef.h>
@@ -62,7 +62,7 @@ WebApplicationCacheHostImpl::WebApplicationCacheHostImpl(
int appcache_host_id)
: client_(client),
backend_(backend),
- status_(APPCACHE_STATUS_UNCACHED),
+ status_(AppCacheStatus::APPCACHE_STATUS_UNCACHED),
is_scheme_supported_(false),
is_get_method_(false),
is_new_master_entry_(MAYBE_NEW_ENTRY),
@@ -99,33 +99,35 @@ void WebApplicationCacheHostImpl::OnStatusChanged(
void WebApplicationCacheHostImpl::OnEventRaised(
AppCacheEventID event_id) {
- DCHECK(event_id !=
- APPCACHE_PROGRESS_EVENT); // See OnProgressEventRaised.
- DCHECK(event_id != APPCACHE_ERROR_EVENT); // See OnErrorEventRaised.
+ DCHECK_NE(
+ event_id,
+ AppCacheEventID::APPCACHE_PROGRESS_EVENT); // See OnProgressEventRaised.
+ DCHECK_NE(event_id,
+ AppCacheEventID::APPCACHE_ERROR_EVENT); // See OnErrorEventRaised.
// Emit logging output prior to calling out to script as we can get
// deleted within the script event handler.
const char kFormatString[] = "Application Cache %s event";
- std::string message = base::StringPrintf(kFormatString,
- kEventNames[event_id]);
+ std::string message = base::StringPrintf(
+ kFormatString, kEventNames[static_cast<int>(event_id)]);
OnLogMessage(APPCACHE_LOG_INFO, message);
switch (event_id) {
- case APPCACHE_CHECKING_EVENT:
- status_ = APPCACHE_STATUS_CHECKING;
+ case AppCacheEventID::APPCACHE_CHECKING_EVENT:
+ status_ = AppCacheStatus::APPCACHE_STATUS_CHECKING;
break;
- case APPCACHE_DOWNLOADING_EVENT:
- status_ = APPCACHE_STATUS_DOWNLOADING;
+ case AppCacheEventID::APPCACHE_DOWNLOADING_EVENT:
+ status_ = AppCacheStatus::APPCACHE_STATUS_DOWNLOADING;
break;
- case APPCACHE_UPDATE_READY_EVENT:
- status_ = APPCACHE_STATUS_UPDATE_READY;
+ case AppCacheEventID::APPCACHE_UPDATE_READY_EVENT:
+ status_ = AppCacheStatus::APPCACHE_STATUS_UPDATE_READY;
break;
- case APPCACHE_CACHED_EVENT:
- case APPCACHE_NO_UPDATE_EVENT:
- status_ = APPCACHE_STATUS_IDLE;
+ case AppCacheEventID::APPCACHE_CACHED_EVENT:
+ case AppCacheEventID::APPCACHE_NO_UPDATE_EVENT:
+ status_ = AppCacheStatus::APPCACHE_STATUS_IDLE;
break;
- case APPCACHE_OBSOLETE_EVENT:
- status_ = APPCACHE_STATUS_OBSOLETE;
+ case AppCacheEventID::APPCACHE_OBSOLETE_EVENT:
+ status_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
break;
default:
NOTREACHED();
@@ -143,7 +145,7 @@ void WebApplicationCacheHostImpl::OnProgressEventRaised(
std::string message = base::StringPrintf(kFormatString, num_complete,
num_total, url.spec().c_str());
OnLogMessage(APPCACHE_LOG_INFO, message);
- status_ = APPCACHE_STATUS_DOWNLOADING;
+ status_ = AppCacheStatus::APPCACHE_STATUS_DOWNLOADING;
client_->NotifyProgressEventListener(url, num_total, num_complete);
}
@@ -156,11 +158,11 @@ void WebApplicationCacheHostImpl::OnErrorEventRaised(
base::StringPrintf(kFormatString, details.message.c_str());
OnLogMessage(APPCACHE_LOG_ERROR, full_message);
- status_ = cache_info_.is_complete ? APPCACHE_STATUS_IDLE :
- APPCACHE_STATUS_UNCACHED;
+ status_ = cache_info_.is_complete ? AppCacheStatus::APPCACHE_STATUS_IDLE
+ : AppCacheStatus::APPCACHE_STATUS_UNCACHED;
if (details.is_cross_origin) {
// Don't leak detailed information to script for cross-origin resources.
- DCHECK_EQ(APPCACHE_RESOURCE_ERROR, details.reason);
+ DCHECK_EQ(AppCacheErrorReason::APPCACHE_RESOURCE_ERROR, details.reason);
client_->NotifyErrorEventListener(static_cast<ErrorReason>(details.reason),
details.url, 0, WebString());
} else {
@@ -171,37 +173,32 @@ void WebApplicationCacheHostImpl::OnErrorEventRaised(
}
void WebApplicationCacheHostImpl::WillStartMainResourceRequest(
- WebURLRequest& request,
+ const WebURL& url,
+ const WebString& method_webstring,
const WebApplicationCacheHost* spawning_host) {
- request.SetAppCacheHostID(host_id_);
+ original_main_resource_url_ = ClearUrlRef(url);
- original_main_resource_url_ = ClearUrlRef(request.Url());
-
- std::string method = request.HttpMethod().Utf8();
+ std::string method = method_webstring.Utf8();
is_get_method_ = (method == kHttpGETMethod);
DCHECK(method == base::ToUpperASCII(method));
const WebApplicationCacheHostImpl* spawning_host_impl =
static_cast<const WebApplicationCacheHostImpl*>(spawning_host);
if (spawning_host_impl && (spawning_host_impl != this) &&
- (spawning_host_impl->status_ != APPCACHE_STATUS_UNCACHED)) {
+ (spawning_host_impl->status_ !=
+ AppCacheStatus::APPCACHE_STATUS_UNCACHED)) {
backend_->SetSpawningHostId(host_id_, spawning_host_impl->host_id());
}
}
-void WebApplicationCacheHostImpl::WillStartSubResourceRequest(
- WebURLRequest& request) {
- request.SetAppCacheHostID(host_id_);
-}
-
void WebApplicationCacheHostImpl::SelectCacheWithoutManifest() {
if (was_select_cache_called_)
return;
was_select_cache_called_ = true;
status_ = (document_response_.AppCacheID() == kAppCacheNoCacheId)
- ? APPCACHE_STATUS_UNCACHED
- : APPCACHE_STATUS_CHECKING;
+ ? AppCacheStatus::APPCACHE_STATUS_UNCACHED
+ : AppCacheStatus::APPCACHE_STATUS_CHECKING;
is_new_master_entry_ = OLD_ENTRY;
backend_->SelectCache(host_id_, document_url_,
document_response_.AppCacheID(), GURL());
@@ -220,10 +217,10 @@ bool WebApplicationCacheHostImpl::SelectCacheWithManifest(
if (document_response_.AppCacheID() == kAppCacheNoCacheId) {
if (is_scheme_supported_ && is_get_method_ &&
(manifest_gurl.GetOrigin() == document_url_.GetOrigin())) {
- status_ = APPCACHE_STATUS_CHECKING;
+ status_ = AppCacheStatus::APPCACHE_STATUS_CHECKING;
is_new_master_entry_ = NEW_ENTRY;
} else {
- status_ = APPCACHE_STATUS_UNCACHED;
+ status_ = AppCacheStatus::APPCACHE_STATUS_UNCACHED;
is_new_master_entry_ = OLD_ENTRY;
manifest_gurl = GURL();
}
@@ -240,11 +237,11 @@ bool WebApplicationCacheHostImpl::SelectCacheWithManifest(
if (document_manifest_gurl != manifest_gurl) {
backend_->MarkAsForeignEntry(host_id_, document_url_,
document_response_.AppCacheID());
- status_ = APPCACHE_STATUS_UNCACHED;
+ status_ = AppCacheStatus::APPCACHE_STATUS_UNCACHED;
return false; // the navigation will be restarted
}
- status_ = APPCACHE_STATUS_CHECKING;
+ status_ = AppCacheStatus::APPCACHE_STATUS_CHECKING;
// Its a 'master' entry thats already in the cache.
backend_->SelectCache(host_id_, document_url_,
@@ -287,9 +284,9 @@ WebApplicationCacheHost::Status WebApplicationCacheHostImpl::GetStatus() {
bool WebApplicationCacheHostImpl::StartUpdate() {
if (!backend_->StartUpdate(host_id_))
return false;
- if (status_ == APPCACHE_STATUS_IDLE ||
- status_ == APPCACHE_STATUS_UPDATE_READY)
- status_ = APPCACHE_STATUS_CHECKING;
+ if (status_ == AppCacheStatus::APPCACHE_STATUS_IDLE ||
+ status_ == AppCacheStatus::APPCACHE_STATUS_UPDATE_READY)
+ status_ = AppCacheStatus::APPCACHE_STATUS_CHECKING;
else
status_ = backend_->GetStatus(host_id_);
return true;
diff --git a/chromium/content/child/appcache/web_application_cache_host_impl.h b/chromium/content/renderer/appcache/web_application_cache_host_impl.h
index caffefd49f2..7af412ac1be 100644
--- a/chromium/content/child/appcache/web_application_cache_host_impl.h
+++ b/chromium/content/renderer/appcache/web_application_cache_host_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_
-#define CONTENT_CHILD_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_
+#ifndef CONTENT_RENDERER_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_
+#define CONTENT_RENDERER_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_
#include <string>
@@ -42,9 +42,9 @@ class WebApplicationCacheHostImpl : public blink::WebApplicationCacheHost {
// blink::WebApplicationCacheHost:
void WillStartMainResourceRequest(
- blink::WebURLRequest&,
- const blink::WebApplicationCacheHost*) override;
- void WillStartSubResourceRequest(blink::WebURLRequest&) override;
+ const blink::WebURL& url,
+ const blink::WebString& method,
+ const WebApplicationCacheHost* spawning_host) override;
void SelectCacheWithoutManifest() override;
bool SelectCacheWithManifest(const blink::WebURL& manifestURL) override;
void DidReceiveResponseForMainResource(const blink::WebURLResponse&) override;
@@ -82,4 +82,4 @@ class WebApplicationCacheHostImpl : public blink::WebApplicationCacheHost {
} // namespace content
-#endif // CONTENT_CHILD_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_
+#endif // CONTENT_RENDERER_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_
diff --git a/chromium/content/child/background_sync/OWNERS b/chromium/content/renderer/background_sync/OWNERS
index 01f2d3213b0..01f2d3213b0 100644
--- a/chromium/content/child/background_sync/OWNERS
+++ b/chromium/content/renderer/background_sync/OWNERS
diff --git a/chromium/content/child/background_sync/background_sync_type_converters.cc b/chromium/content/renderer/background_sync/background_sync_type_converters.cc
index af6f6e2f4a9..19962a6d8b4 100644
--- a/chromium/content/child/background_sync/background_sync_type_converters.cc
+++ b/chromium/content/renderer/background_sync/background_sync_type_converters.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/child/background_sync/background_sync_type_converters.h"
+#include "content/renderer/background_sync/background_sync_type_converters.h"
#include "base/logging.h"
diff --git a/chromium/content/child/background_sync/background_sync_type_converters.h b/chromium/content/renderer/background_sync/background_sync_type_converters.h
index 4cc396a5e29..dd9c151c077 100644
--- a/chromium/content/child/background_sync/background_sync_type_converters.h
+++ b/chromium/content/renderer/background_sync/background_sync_type_converters.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_CHILD_BACKGROUND_SYNC_BACKGROUND_SYNC_TYPE_CONVERTERS_H_
-#define CONTENT_CHILD_BACKGROUND_SYNC_BACKGROUND_SYNC_TYPE_CONVERTERS_H_
+#ifndef CONTENT_RENDERER_BACKGROUND_SYNC_BACKGROUND_SYNC_TYPE_CONVERTERS_H_
+#define CONTENT_RENDERER_BACKGROUND_SYNC_BACKGROUND_SYNC_TYPE_CONVERTERS_H_
#include <memory>
@@ -35,4 +35,4 @@ struct CONTENT_EXPORT
} // namespace mojo
-#endif // CONTENT_CHILD_BACKGROUND_SYNC_BACKGROUND_SYNC_TYPE_CONVERTERS_H_
+#endif // CONTENT_RENDERER_BACKGROUND_SYNC_BACKGROUND_SYNC_TYPE_CONVERTERS_H_
diff --git a/chromium/content/child/blob_storage/OWNERS b/chromium/content/renderer/blob_storage/OWNERS
index 471c08e8a01..471c08e8a01 100644
--- a/chromium/content/child/blob_storage/OWNERS
+++ b/chromium/content/renderer/blob_storage/OWNERS
diff --git a/chromium/content/child/blob_storage/blob_consolidation.cc b/chromium/content/renderer/blob_storage/blob_consolidation.cc
index a403dc1f4a1..68a0d3a0c26 100644
--- a/chromium/content/child/blob_storage/blob_consolidation.cc
+++ b/chromium/content/renderer/blob_storage/blob_consolidation.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/child/blob_storage/blob_consolidation.h"
+#include "content/renderer/blob_storage/blob_consolidation.h"
#include <algorithm>
#include <limits>
diff --git a/chromium/content/child/blob_storage/blob_consolidation.h b/chromium/content/renderer/blob_storage/blob_consolidation.h
index 06d1051424d..b837d555872 100644
--- a/chromium/content/child/blob_storage/blob_consolidation.h
+++ b/chromium/content/renderer/blob_storage/blob_consolidation.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_CHILD_BLOB_STORAGE_BLOB_CONSOLIDATION_H_
-#define CONTENT_CHILD_BLOB_STORAGE_BLOB_CONSOLIDATION_H_
+#ifndef CONTENT_RENDERER_BLOB_STORAGE_BLOB_CONSOLIDATION_H_
+#define CONTENT_RENDERER_BLOB_STORAGE_BLOB_CONSOLIDATION_H_
#include <stddef.h>
#include <stdint.h>
@@ -138,4 +138,4 @@ class CONTENT_EXPORT BlobConsolidation
};
} // namespace content
-#endif // CONTENT_CHILD_BLOB_STORAGE_BLOB_CONSOLIDATION_H_
+#endif // CONTENT_RENDERER_BLOB_STORAGE_BLOB_CONSOLIDATION_H_
diff --git a/chromium/content/child/blob_storage/blob_consolidation_unittest.cc b/chromium/content/renderer/blob_storage/blob_consolidation_unittest.cc
index ee1bfb06915..33df3aa1c9c 100644
--- a/chromium/content/child/blob_storage/blob_consolidation_unittest.cc
+++ b/chromium/content/renderer/blob_storage/blob_consolidation_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 "content/child/blob_storage/blob_consolidation.h"
+#include "content/renderer/blob_storage/blob_consolidation.h"
#include <stddef.h>
diff --git a/chromium/content/child/blob_storage/blob_message_filter.cc b/chromium/content/renderer/blob_storage/blob_message_filter.cc
index 368f64e601f..6fc8d6a9ec9 100644
--- a/chromium/content/child/blob_storage/blob_message_filter.cc
+++ b/chromium/content/renderer/blob_storage/blob_message_filter.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/blob_storage/blob_message_filter.h"
+#include "content/renderer/blob_storage/blob_message_filter.h"
#include "base/bind.h"
#include "base/task_runner.h"
-#include "content/child/blob_storage/blob_transport_controller.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/fileapi/webblob_messages.h"
+#include "content/renderer/blob_storage/blob_transport_controller.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_sender.h"
#include "storage/common/blob_storage/blob_item_bytes_request.h"
diff --git a/chromium/content/child/blob_storage/blob_message_filter.h b/chromium/content/renderer/blob_storage/blob_message_filter.h
index 796a8c08f86..308f8c13ebf 100644
--- a/chromium/content/child/blob_storage/blob_message_filter.h
+++ b/chromium/content/renderer/blob_storage/blob_message_filter.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_CHILD_BLOB_STORAGE_BLOB_MESSAGE_FILTER_H_
-#define CONTENT_CHILD_BLOB_STORAGE_BLOB_MESSAGE_FILTER_H_
+#ifndef CONTENT_RENDERER_BLOB_STORAGE_BLOB_MESSAGE_FILTER_H_
+#define CONTENT_RENDERER_BLOB_STORAGE_BLOB_MESSAGE_FILTER_H_
#include <stddef.h>
@@ -65,4 +65,4 @@ class BlobMessageFilter : public IPC::MessageFilter {
};
} // namespace content
-#endif // CONTENT_CHILD_BLOB_STORAGE_BLOB_MESSAGE_FILTER_H_
+#endif // CONTENT_RENDERER_BLOB_STORAGE_BLOB_MESSAGE_FILTER_H_
diff --git a/chromium/content/child/blob_storage/blob_transport_controller.cc b/chromium/content/renderer/blob_storage/blob_transport_controller.cc
index 203b751e464..76d7b31f53a 100644
--- a/chromium/content/child/blob_storage/blob_transport_controller.cc
+++ b/chromium/content/renderer/blob_storage/blob_transport_controller.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/blob_storage/blob_transport_controller.h"
+#include "content/renderer/blob_storage/blob_transport_controller.h"
#include <limits>
#include <memory>
@@ -25,10 +25,10 @@
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
-#include "content/child/blob_storage/blob_consolidation.h"
#include "content/child/child_process.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/fileapi/webblob_messages.h"
+#include "content/renderer/blob_storage/blob_consolidation.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_sender.h"
#include "storage/common/blob_storage/blob_item_bytes_request.h"
@@ -255,7 +255,7 @@ void BlobTransportController::OnMemoryRequest(
SharedMemoryHandle& handle = (*memory_handles)[request.handle_index];
size_t size = shared_memory_sizes[request.handle_index];
DCHECK(SharedMemory::IsHandleValid(handle));
- auto shared_memory = base::MakeUnique<SharedMemory>(handle, false);
+ auto shared_memory = std::make_unique<SharedMemory>(handle, false);
if (!shared_memory->Map(size)) {
// This would happen if the renderer process doesn't have enough
@@ -368,8 +368,10 @@ void BlobTransportController::GetDescriptions(
base::Time::FromDoubleT(item.expected_modification_time));
break;
}
+ case DataElement::TYPE_RAW_FILE:
case DataElement::TYPE_DISK_CACHE_ENTRY:
case DataElement::TYPE_BYTES_DESCRIPTION:
+ case DataElement::TYPE_DATA_PIPE:
case DataElement::TYPE_UNKNOWN:
NOTREACHED();
}
diff --git a/chromium/content/child/blob_storage/blob_transport_controller.h b/chromium/content/renderer/blob_storage/blob_transport_controller.h
index 4042e173853..a3c8e5a5694 100644
--- a/chromium/content/child/blob_storage/blob_transport_controller.h
+++ b/chromium/content/renderer/blob_storage/blob_transport_controller.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_BLOB_STORAGE_BLOB_TRANSPORT_CONTROLLER_H_
-#define CONTENT_CHILD_BLOB_STORAGE_BLOB_TRANSPORT_CONTROLLER_H_
+#ifndef CONTENT_RENDERER_BLOB_STORAGE_BLOB_TRANSPORT_CONTROLLER_H_
+#define CONTENT_RENDERER_BLOB_STORAGE_BLOB_TRANSPORT_CONTROLLER_H_
#include <stddef.h>
@@ -144,4 +144,4 @@ class CONTENT_EXPORT BlobTransportController {
};
} // namespace content
-#endif // CONTENT_CHILD_BLOB_STORAGE_BLOB_TRANSPORT_CONTROLLER_H_
+#endif // CONTENT_RENDERER_BLOB_STORAGE_BLOB_TRANSPORT_CONTROLLER_H_
diff --git a/chromium/content/child/blob_storage/blob_transport_controller_unittest.cc b/chromium/content/renderer/blob_storage/blob_transport_controller_unittest.cc
index b7c054d068d..9253c65e8cb 100644
--- a/chromium/content/child/blob_storage/blob_transport_controller_unittest.cc
+++ b/chromium/content/renderer/blob_storage/blob_transport_controller_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/blob_storage/blob_transport_controller.h"
+#include "content/renderer/blob_storage/blob_transport_controller.h"
#include <stddef.h>
#include <stdint.h>
@@ -19,9 +19,9 @@
#include "base/test/test_file_util.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/blob_storage/blob_consolidation.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/fileapi/webblob_messages.h"
+#include "content/renderer/blob_storage/blob_consolidation.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_platform_file.h"
#include "ipc/ipc_sender.h"
diff --git a/chromium/content/child/blob_storage/webblobregistry_impl.cc b/chromium/content/renderer/blob_storage/webblobregistry_impl.cc
index 5caf208c65f..c9f42698baa 100644
--- a/chromium/content/child/blob_storage/webblobregistry_impl.cc
+++ b/chromium/content/renderer/blob_storage/webblobregistry_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/blob_storage/webblobregistry_impl.h"
+#include "content/renderer/blob_storage/webblobregistry_impl.h"
#include "base/bind.h"
#include "base/files/file_path.h"
@@ -15,10 +15,10 @@
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
-#include "content/child/blob_storage/blob_consolidation.h"
-#include "content/child/blob_storage/blob_transport_controller.h"
#include "content/child/child_thread_impl.h"
#include "content/child/thread_safe_sender.h"
+#include "content/renderer/blob_storage/blob_consolidation.h"
+#include "content/renderer/blob_storage/blob_transport_controller.h"
#include "content/common/fileapi/webblob_messages.h"
#include "third_party/WebKit/public/platform/FilePathConversion.h"
#include "third_party/WebKit/public/platform/WebBlobData.h"
diff --git a/chromium/content/child/blob_storage/webblobregistry_impl.h b/chromium/content/renderer/blob_storage/webblobregistry_impl.h
index 44c44ac102c..1ce502b81d1 100644
--- a/chromium/content/child/blob_storage/webblobregistry_impl.h
+++ b/chromium/content/renderer/blob_storage/webblobregistry_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_BLOB_STORAGE_WEBBLOBREGISTRY_IMPL_H_
-#define CONTENT_CHILD_BLOB_STORAGE_WEBBLOBREGISTRY_IMPL_H_
+#ifndef CONTENT_RENDERER_BLOB_STORAGE_WEBBLOBREGISTRY_IMPL_H_
+#define CONTENT_RENDERER_BLOB_STORAGE_WEBBLOBREGISTRY_IMPL_H_
#include <stddef.h>
#include <stdint.h>
@@ -90,4 +90,4 @@ class WebBlobRegistryImpl : public blink::WebBlobRegistry {
} // namespace content
-#endif // CONTENT_CHILD_BLOB_STORAGE_WEBBLOBREGISTRY_IMPL_H_
+#endif // CONTENT_RENDERER_BLOB_STORAGE_WEBBLOBREGISTRY_IMPL_H_
diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.cc b/chromium/content/renderer/browser_plugin/browser_plugin.cc
index 75218ea2e5c..95f5aa5c86a 100644
--- a/chromium/content/renderer/browser_plugin/browser_plugin.cc
+++ b/chromium/content/renderer/browser_plugin/browser_plugin.cc
@@ -18,8 +18,8 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "components/viz/common/features.h"
#include "components/viz/common/surfaces/surface_info.h"
-#include "components/viz/common/switches.h"
#include "content/common/browser_plugin/browser_plugin_constants.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
#include "content/common/view_messages.h"
@@ -32,6 +32,7 @@
#include "content/renderer/child_frame_compositing_helper.h"
#include "content/renderer/cursor_utils.h"
#include "content/renderer/drop_data_builder.h"
+#include "content/renderer/mash_util.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/sad_plugin.h"
#include "third_party/WebKit/public/platform/WebCoalescedInputEvent.h"
@@ -47,6 +48,11 @@
#include "third_party/WebKit/public/web/WebView.h"
#include "ui/events/keycodes/keyboard_codes.h"
+#if defined(USE_AURA)
+#include "content/renderer/mus/mus_embedded_frame.h"
+#include "content/renderer/mus/renderer_window_tree_client.h"
+#endif
+
using blink::WebPluginContainer;
using blink::WebPoint;
using blink::WebRect;
@@ -95,10 +101,7 @@ BrowserPlugin::BrowserPlugin(
if (delegate_)
delegate_->SetElementInstanceID(browser_plugin_instance_id_);
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- enable_surface_synchronization_ =
- command_line.HasSwitch(switches::kEnableSurfaceSynchronization);
+ enable_surface_synchronization_ = features::IsSurfaceSynchronizationEnabled();
}
BrowserPlugin::~BrowserPlugin() {
@@ -118,8 +121,13 @@ bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone, OnGuestGone)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestReady, OnGuestReady)
+ IPC_MESSAGE_HANDLER(BrowserPluginMsg_ResizeDueToAutoResize,
+ OnResizeDueToAutoResize)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetMouseLock, OnSetMouseLock)
+#if defined(USE_AURA)
+ IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetMusEmbedToken, OnSetMusEmbedToken)
+#endif
IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetTooltipText, OnSetTooltipText)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents,
OnShouldAcceptTouchEvents)
@@ -133,12 +141,15 @@ void BrowserPlugin::OnSetChildFrameSurface(
int browser_plugin_instance_id,
const viz::SurfaceInfo& surface_info,
const viz::SurfaceSequence& sequence) {
- if (!attached())
+ if (!attached() || IsRunningWithMus())
return;
- if (!enable_surface_synchronization_)
- compositing_helper_->SetPrimarySurfaceInfo(surface_info);
- compositing_helper_->SetFallbackSurfaceInfo(surface_info, sequence);
+ if (!enable_surface_synchronization_) {
+ compositing_helper_->SetPrimarySurfaceId(surface_info.id(),
+ frame_rect().size());
+ }
+ compositing_helper_->SetFallbackSurfaceId(surface_info.id(),
+ frame_rect().size(), sequence);
}
void BrowserPlugin::SendSatisfySequence(const viz::SurfaceSequence& sequence) {
@@ -162,7 +173,7 @@ void BrowserPlugin::Attach() {
BrowserPluginHostMsg_Attach_Params attach_params;
attach_params.focused = ShouldGuestBeFocused();
attach_params.visible = visible_;
- attach_params.view_rect = view_rect();
+ attach_params.frame_rect = frame_rect();
attach_params.is_full_page_plugin = false;
if (Container()) {
blink::WebLocalFrame* frame = Container()->GetDocument().GetFrame();
@@ -174,6 +185,14 @@ void BrowserPlugin::Attach() {
->GetDocument()
.IsPluginDocument();
}
+#if defined(USE_AURA)
+ if (pending_embed_token_) {
+ base::Optional<base::UnguessableToken> embed_token =
+ std::move(pending_embed_token_);
+ CreateMusWindowAndEmbed(*embed_token);
+ }
+#endif
+
BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_Attach(
render_frame_routing_id_,
browser_plugin_instance_id_,
@@ -194,7 +213,8 @@ void BrowserPlugin::Attach() {
}
}
- ViewRectsChanged(view_rect());
+ sent_resize_params_ = base::nullopt;
+ WasResized();
}
void BrowserPlugin::Detach() {
@@ -212,6 +232,74 @@ void BrowserPlugin::Detach() {
void BrowserPlugin::DidCommitCompositorFrame() {
}
+#if defined(USE_AURA)
+void BrowserPlugin::CreateMusWindowAndEmbed(
+ const base::UnguessableToken& embed_token) {
+ RenderFrameImpl* render_frame =
+ RenderFrameImpl::FromRoutingID(render_frame_routing_id_);
+ if (!render_frame) {
+ pending_embed_token_ = embed_token;
+ return;
+ }
+ RendererWindowTreeClient* renderer_window_tree_client =
+ RendererWindowTreeClient::Get(
+ render_frame->GetRenderWidget()->routing_id());
+ DCHECK(renderer_window_tree_client);
+ mus_embedded_frame_ =
+ renderer_window_tree_client->CreateMusEmbeddedFrame(this, embed_token);
+ if (attached() && local_surface_id_.is_valid()) {
+ mus_embedded_frame_->SetWindowBounds(local_surface_id_,
+ FrameRectInPixels());
+ }
+}
+#endif
+
+void BrowserPlugin::WasResized() {
+ bool size_changed = !sent_resize_params_ ||
+ sent_resize_params_->frame_rect.size() !=
+ pending_resize_params_.frame_rect.size() ||
+ sent_resize_params_->sequence_number !=
+ pending_resize_params_.sequence_number;
+
+ bool synchronized_params_changed =
+ !sent_resize_params_ || size_changed ||
+ sent_resize_params_->screen_info != pending_resize_params_.screen_info;
+
+ if (synchronized_params_changed)
+ local_surface_id_ = local_surface_id_allocator_.GenerateId();
+
+ if (enable_surface_synchronization_ && frame_sink_id_.is_valid()) {
+ compositing_helper_->SetPrimarySurfaceId(
+ viz::SurfaceId(frame_sink_id_, local_surface_id_), frame_rect().size());
+ }
+
+ bool position_changed =
+ !sent_resize_params_ || sent_resize_params_->frame_rect.origin() !=
+ pending_resize_params_.frame_rect.origin();
+ bool resize_params_changed = synchronized_params_changed || position_changed;
+
+ if (resize_params_changed && attached()) {
+ // Let the browser know about the updated view rect.
+ BrowserPluginManager::Get()->Send(
+ new BrowserPluginHostMsg_UpdateResizeParams(
+ browser_plugin_instance_id_, frame_rect(), screen_info(),
+ auto_size_sequence_number(), local_surface_id_));
+ }
+
+ if (delegate_ && size_changed)
+ delegate_->DidResizeElement(frame_rect().size());
+
+ if (resize_params_changed && attached())
+ sent_resize_params_ = pending_resize_params_;
+
+#if defined(USE_AURA)
+ if (IsRunningWithMus() && mus_embedded_frame_) {
+ mus_embedded_frame_->SetWindowBounds(local_surface_id_,
+ FrameRectInPixels());
+ }
+#endif
+}
+
void BrowserPlugin::OnAdvanceFocus(int browser_plugin_instance_id,
bool reverse) {
auto* render_frame =
@@ -231,12 +319,14 @@ void BrowserPlugin::OnGuestReady(int browser_plugin_instance_id,
const viz::FrameSinkId& frame_sink_id) {
guest_crashed_ = false;
frame_sink_id_ = frame_sink_id;
- if (!view_rect_)
- return;
+ sent_resize_params_ = base::nullopt;
+ WasResized();
+}
- gfx::Rect view_rect = *view_rect_;
- view_rect_ = gfx::Rect();
- ViewRectsChanged(view_rect);
+void BrowserPlugin::OnResizeDueToAutoResize(int browser_plugin_instance_id,
+ uint64_t sequence_number) {
+ pending_resize_params_.sequence_number = sequence_number;
+ WasResized();
}
void BrowserPlugin::OnSetCursor(int browser_plugin_instance_id,
@@ -265,6 +355,20 @@ void BrowserPlugin::OnSetMouseLock(int browser_plugin_instance_id,
}
}
+#if defined(USE_AURA)
+void BrowserPlugin::OnSetMusEmbedToken(
+ int instance_id,
+ const base::UnguessableToken& embed_token) {
+ DCHECK(IsRunningWithMus());
+ if (!attached_) {
+ pending_embed_token_ = embed_token;
+ } else {
+ pending_embed_token_.reset();
+ CreateMusWindowAndEmbed(embed_token);
+ }
+}
+#endif
+
void BrowserPlugin::OnSetTooltipText(int instance_id,
const base::string16& tooltip_text) {
// Show tooltip text by setting the BrowserPlugin's |title| attribute.
@@ -280,6 +384,19 @@ void BrowserPlugin::OnShouldAcceptTouchEvents(int browser_plugin_instance_id,
}
}
+gfx::Rect BrowserPlugin::FrameRectInPixels() const {
+ const float device_scale_factor = GetDeviceScaleFactor();
+ return gfx::Rect(
+ gfx::ScaleToFlooredPoint(frame_rect().origin(), device_scale_factor),
+ gfx::ScaleToCeiledSize(frame_rect().size(), device_scale_factor));
+}
+
+float BrowserPlugin::GetDeviceScaleFactor() const {
+ return RenderFrameImpl::FromWebFrame(Container()->GetDocument().GetFrame())
+ ->GetRenderWidget()
+ ->GetOriginalDeviceScaleFactor();
+}
+
void BrowserPlugin::UpdateInternalInstanceId() {
// This is a way to notify observers of our attributes that this plugin is
// available in render tree.
@@ -290,36 +407,6 @@ void BrowserPlugin::UpdateInternalInstanceId() {
base::UTF8ToUTF16(base::IntToString(browser_plugin_instance_id_)));
}
-void BrowserPlugin::ViewRectsChanged(const gfx::Rect& view_rect) {
- bool rect_size_changed =
- !view_rect_ || view_rect_->size() != view_rect.size();
- if (rect_size_changed || !local_surface_id_.is_valid()) {
- local_surface_id_ = local_surface_id_allocator_.GenerateId();
- if (enable_surface_synchronization_ && frame_sink_id_.is_valid()) {
- RenderWidget* render_widget =
- RenderFrameImpl::FromWebFrame(Container()->GetDocument().GetFrame())
- ->GetRenderWidget();
- float device_scale_factor = render_widget->GetOriginalDeviceScaleFactor();
- viz::SurfaceInfo surface_info(
- viz::SurfaceId(frame_sink_id_, local_surface_id_),
- device_scale_factor,
- gfx::ScaleToCeiledSize(view_rect.size(), device_scale_factor));
- compositing_helper_->SetPrimarySurfaceInfo(surface_info);
- }
- }
-
- view_rect_ = view_rect;
-
- if (attached()) {
- // Let the browser know about the updated view rect.
- BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_UpdateGeometry(
- browser_plugin_instance_id_, *view_rect_, local_surface_id_));
- }
-
- if (rect_size_changed && delegate_)
- delegate_->DidResizeElement(view_rect_->size());
-}
-
void BrowserPlugin::UpdateGuestFocusState(blink::WebFocusType focus_type) {
if (!attached())
return;
@@ -330,6 +417,11 @@ void BrowserPlugin::UpdateGuestFocusState(blink::WebFocusType focus_type) {
focus_type));
}
+void BrowserPlugin::ScreenInfoChanged(const ScreenInfo& screen_info) {
+ pending_resize_params_.screen_info = screen_info;
+ WasResized();
+}
+
bool BrowserPlugin::ShouldGuestBeFocused() const {
bool embedder_focused = false;
auto* render_frame =
@@ -366,6 +458,11 @@ bool BrowserPlugin::Initialize(WebPluginContainer* container) {
compositing_helper_.reset(ChildFrameCompositingHelper::CreateForBrowserPlugin(
weak_ptr_factory_.GetWeakPtr()));
+ RenderWidget* render_widget =
+ RenderFrameImpl::FromWebFrame(container_->GetDocument().GetFrame())
+ ->GetRenderWidget();
+ pending_resize_params_.screen_info = render_widget->screen_info();
+
return true;
}
@@ -430,7 +527,7 @@ void BrowserPlugin::UpdateGeometry(const WebRect& plugin_rect_in_viewport,
RenderFrameImpl::FromWebFrame(Container()->GetDocument().GetFrame())
->GetRenderWidget();
render_widget->ConvertViewportToWindow(&rect_in_css);
- gfx::Rect view_rect = rect_in_css;
+ gfx::Rect frame_rect = rect_in_css;
if (!ready_) {
if (delegate_)
@@ -438,7 +535,9 @@ void BrowserPlugin::UpdateGeometry(const WebRect& plugin_rect_in_viewport,
ready_ = true;
}
- ViewRectsChanged(view_rect);
+ pending_resize_params_.frame_rect = frame_rect;
+ pending_resize_params_.screen_info = render_widget->screen_info();
+ WasResized();
}
void BrowserPlugin::UpdateFocus(bool focused, blink::WebFocusType focus_type) {
@@ -520,8 +619,8 @@ blink::WebInputEventResult BrowserPlugin::HandleInputEvent(
bool BrowserPlugin::HandleDragStatusUpdate(blink::WebDragStatus drag_status,
const blink::WebDragData& drag_data,
blink::WebDragOperationsMask mask,
- const blink::WebPoint& position,
- const blink::WebPoint& screen) {
+ const blink::WebFloatPoint& position,
+ const blink::WebFloatPoint& screen) {
if (guest_crashed_ || !attached())
return false;
BrowserPluginManager::Get()->Send(
@@ -662,4 +761,20 @@ bool BrowserPlugin::HandleMouseLockedInputEvent(
return true;
}
+#if defined(USE_AURA)
+void BrowserPlugin::OnMusEmbeddedFrameSurfaceChanged(
+ const viz::SurfaceInfo& surface_info) {
+ if (!attached_)
+ return;
+
+ compositing_helper_->SetFallbackSurfaceId(
+ surface_info.id(), frame_rect().size(), viz::SurfaceSequence());
+}
+
+void BrowserPlugin::OnMusEmbeddedFrameSinkIdAllocated(
+ const viz::FrameSinkId& frame_sink_id) {
+ OnGuestReady(browser_plugin_instance_id_, frame_sink_id);
+}
+#endif
+
} // namespace content
diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.h b/chromium/content/renderer/browser_plugin/browser_plugin.h
index f6ac20d1b33..37d61fe29ca 100644
--- a/chromium/content/renderer/browser_plugin/browser_plugin.h
+++ b/chromium/content/renderer/browser_plugin/browser_plugin.h
@@ -16,6 +16,7 @@
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "content/public/common/screen_info.h"
#include "content/renderer/mouse_lock_dispatcher.h"
#include "content/renderer/render_view_impl.h"
#include "third_party/WebKit/public/web/WebDragStatus.h"
@@ -23,6 +24,14 @@
#include "third_party/WebKit/public/web/WebInputMethodController.h"
#include "third_party/WebKit/public/web/WebNode.h"
+#if defined(USE_AURA)
+#include "content/renderer/mus/mus_embedded_frame_delegate.h"
+#endif
+
+namespace base {
+class UnguessableToken;
+}
+
namespace viz {
class SurfaceInfo;
struct SurfaceSequence;
@@ -34,7 +43,14 @@ class BrowserPluginDelegate;
class BrowserPluginManager;
class ChildFrameCompositingHelper;
+#if defined(USE_AURA)
+class MusEmbeddedFrame;
+#endif
+
class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
+#if defined(USE_AURA)
+ public MusEmbeddedFrameDelegate,
+#endif
public MouseLockDispatcher::LockTarget {
public:
static BrowserPlugin* GetFromNode(blink::WebNode& node);
@@ -56,6 +72,8 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
// Informs the guest of an updated focus state.
void UpdateGuestFocusState(blink::WebFocusType focus_type);
+ void ScreenInfoChanged(const ScreenInfo& screen_info);
+
// Indicates whether the guest should be focused.
bool ShouldGuestBeFocused() const;
@@ -74,6 +92,8 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
// sent, if needed.
void DidCommitCompositorFrame();
+ void WasResized();
+
// Returns whether a message should be forwarded to BrowserPlugin.
static bool ShouldForwardToBrowserPlugin(const IPC::Message& message);
@@ -100,8 +120,8 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
bool HandleDragStatusUpdate(blink::WebDragStatus drag_status,
const blink::WebDragData& drag_data,
blink::WebDragOperationsMask mask,
- const blink::WebPoint& position,
- const blink::WebPoint& screen) override;
+ 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 DidFinishLoading() override;
@@ -146,27 +166,55 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
~BrowserPlugin() override;
- gfx::Rect view_rect() const { return view_rect_.value_or(gfx::Rect()); }
+ const gfx::Rect& frame_rect() const {
+ return pending_resize_params_.frame_rect;
+ }
+ gfx::Rect FrameRectInPixels() const;
+ float GetDeviceScaleFactor() const;
+
+ const ScreenInfo& screen_info() const {
+ return pending_resize_params_.screen_info;
+ }
+
+ uint64_t auto_size_sequence_number() const {
+ return pending_resize_params_.sequence_number;
+ }
void UpdateInternalInstanceId();
- void ViewRectsChanged(const gfx::Rect& view_rect);
+#if defined(USE_AURA)
+ void CreateMusWindowAndEmbed(const base::UnguessableToken& embed_token);
+#endif
// IPC message handlers.
// Please keep in alphabetical order.
void OnAdvanceFocus(int instance_id, bool reverse);
void OnGuestGone(int instance_id);
void OnGuestReady(int instance_id, const viz::FrameSinkId& frame_sink_id);
+ void OnResizeDueToAutoResize(int browser_plugin_instance_id,
+ uint64_t sequence_number);
void OnSetChildFrameSurface(int instance_id,
const viz::SurfaceInfo& surface_info,
const viz::SurfaceSequence& sequence);
void OnSetContentsOpaque(int instance_id, bool opaque);
void OnSetCursor(int instance_id, const WebCursor& cursor);
void OnSetMouseLock(int instance_id, bool enable);
+#if defined(USE_AURA)
+ void OnSetMusEmbedToken(int instance_id,
+ const base::UnguessableToken& embed_token);
+#endif
void OnSetTooltipText(int browser_plugin_instance_id,
const base::string16& tooltip_text);
void OnShouldAcceptTouchEvents(int instance_id, bool accept);
+#if defined(USE_AURA)
+ // MusEmbeddedFrameDelegate
+ void OnMusEmbeddedFrameSurfaceChanged(
+ const viz::SurfaceInfo& surface_info) override;
+ void OnMusEmbeddedFrameSinkIdAllocated(
+ const viz::FrameSinkId& frame_sink_id) override;
+#endif
+
// This indicates whether this BrowserPlugin has been attached to a
// WebContents and is ready to receive IPCs.
bool attached_;
@@ -176,7 +224,6 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
const int render_frame_routing_id_;
blink::WebPluginContainer* container_;
// The plugin's rect in css pixels.
- base::Optional<gfx::Rect> view_rect_;
bool guest_crashed_;
bool plugin_focused_;
// Tracks the visibility of the browser plugin regardless of the whole
@@ -203,10 +250,32 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
bool enable_surface_synchronization_ = false;
+
+ // TODO(fsamuel): We might want to unify this with content::ResizeParams.
+ struct ResizeParams {
+ gfx::Rect frame_rect;
+ ScreenInfo screen_info;
+ uint64_t sequence_number = 0lu;
+ };
+
+ // The last ResizeParams sent to the browser process, if any.
+ base::Optional<ResizeParams> sent_resize_params_;
+
+ // The current set of ResizeParams. This may or may not match
+ // |sent_resize_params_|.
+ ResizeParams pending_resize_params_;
+
// We call lifetime managing methods on |delegate_|, but we do not directly
// own this. The delegate destroys itself.
base::WeakPtr<BrowserPluginDelegate> delegate_;
+#if defined(USE_AURA)
+ // Set if OnSetMusEmbedToken() is called before attached.
+ base::Optional<base::UnguessableToken> pending_embed_token_;
+
+ std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame_;
+#endif
+
// Weak factory used in v8 |MakeWeak| callback, since the v8 callback might
// get called after BrowserPlugin has been destroyed.
base::WeakPtrFactory<BrowserPlugin> weak_ptr_factory_;
diff --git a/chromium/content/renderer/browser_plugin/browser_plugin_manager.cc b/chromium/content/renderer/browser_plugin/browser_plugin_manager.cc
index 021215e6072..00f03320310 100644
--- a/chromium/content/renderer/browser_plugin/browser_plugin_manager.cc
+++ b/chromium/content/renderer/browser_plugin/browser_plugin_manager.cc
@@ -9,6 +9,7 @@
#include "content/common/browser_plugin/browser_plugin_constants.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
#include "content/common/frame_messages.h"
+#include "content/public/common/screen_info.h"
#include "content/public/renderer/browser_plugin_delegate.h"
#include "content/renderer/browser_plugin/browser_plugin.h"
#include "content/renderer/render_thread_impl.h"
@@ -56,6 +57,14 @@ void BrowserPluginManager::UpdateFocusState() {
}
}
+void BrowserPluginManager::ScreenInfoChanged(const ScreenInfo& screen_info) {
+ base::IDMap<BrowserPlugin*>::iterator iter(&instances_);
+ while (!iter.IsAtEnd()) {
+ iter.GetCurrentValue()->ScreenInfoChanged(screen_info);
+ iter.Advance();
+ }
+}
+
void BrowserPluginManager::Attach(int browser_plugin_instance_id) {
BrowserPlugin* plugin = GetBrowserPlugin(browser_plugin_instance_id);
if (plugin)
diff --git a/chromium/content/renderer/browser_plugin/browser_plugin_manager.h b/chromium/content/renderer/browser_plugin/browser_plugin_manager.h
index f14224993de..bdd39fab469 100644
--- a/chromium/content/renderer/browser_plugin/browser_plugin_manager.h
+++ b/chromium/content/renderer/browser_plugin/browser_plugin_manager.h
@@ -16,6 +16,7 @@ namespace content {
class BrowserPlugin;
class BrowserPluginDelegate;
class RenderFrame;
+struct ScreenInfo;
// BrowserPluginManager manages the routing of messages to the appropriate
// BrowserPlugin object based on its instance ID. There is one BrowserPlugin
@@ -49,6 +50,8 @@ class CONTENT_EXPORT BrowserPluginManager : public RenderThreadObserver {
void UpdateFocusState();
+ void ScreenInfoChanged(const ScreenInfo& screen_info);
+
// Returns a new instance ID to be used by BrowserPlugin. Instance IDs are
// unique per process.
int GetNextInstanceID();
diff --git a/chromium/content/renderer/browser_render_view_browsertest.cc b/chromium/content/renderer/browser_render_view_browsertest.cc
index 88e3b0f92f5..9fa30416650 100644
--- a/chromium/content/renderer/browser_render_view_browsertest.cc
+++ b/chromium/content/renderer/browser_render_view_browsertest.cc
@@ -59,8 +59,8 @@ class TestShellContentRendererClient : public ShellContentRendererClient {
if (error_html)
*error_html = "A suffusion of yellow.";
latest_error_valid_ = true;
- latest_error_reason_ = error.reason;
- latest_error_stale_copy_in_cache_ = error.stale_copy_in_cache;
+ latest_error_reason_ = error.reason();
+ latest_error_stale_copy_in_cache_ = error.has_copy_in_cache();
}
bool GetLatestError(int* error_code, bool* stale_cache_entry_present) {
@@ -199,7 +199,7 @@ IN_PROC_BROWSER_TEST_F(RenderViewBrowserTest, ConfirmCacheInformationPlumbed) {
ASSERT_TRUE(embedded_test_server()->Start());
// Load URL with "nocache" set, to create stale cache.
- GURL test_url(embedded_test_server()->GetURL("/nocache.html"));
+ GURL test_url(embedded_test_server()->GetURL("/nocache-with-etag.html"));
NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1);
// Reload same URL after forcing an error from the the network layer;
diff --git a/chromium/content/renderer/cache_storage/cache_storage_dispatcher.cc b/chromium/content/renderer/cache_storage/cache_storage_dispatcher.cc
index 01966e5f8c4..8fb3a234c69 100644
--- a/chromium/content/renderer/cache_storage/cache_storage_dispatcher.cc
+++ b/chromium/content/renderer/cache_storage/cache_storage_dispatcher.cc
@@ -32,7 +32,7 @@
namespace content {
using base::TimeTicks;
-using blink::WebServiceWorkerCacheError;
+using blink::mojom::CacheStorageError;
using blink::WebServiceWorkerCacheStorage;
using blink::WebServiceWorkerRequest;
using blink::WebString;
@@ -121,7 +121,7 @@ template <typename T>
void ClearCallbacksMapWithErrors(T* callbacks_map) {
typename T::iterator iter(callbacks_map);
while (!iter.IsAtEnd()) {
- iter.GetCurrentValue()->OnError(blink::kWebServiceWorkerCacheErrorNotFound);
+ iter.GetCurrentValue()->OnError(CacheStorageError::kErrorNotFound);
callbacks_map->Remove(iter.GetCurrentKey());
iter.Advance();
}
@@ -207,7 +207,7 @@ CacheStorageDispatcher* CacheStorageDispatcher::ThreadSpecificInstance(
ThreadSafeSender* thread_safe_sender) {
if (g_cache_storage_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
NOTREACHED() << "Re-instantiating TLS CacheStorageDispatcher.";
- g_cache_storage_dispatcher_tls.Pointer()->Set(NULL);
+ g_cache_storage_dispatcher_tls.Pointer()->Set(nullptr);
}
if (g_cache_storage_dispatcher_tls.Pointer()->Get())
return g_cache_storage_dispatcher_tls.Pointer()->Get();
@@ -341,10 +341,9 @@ void CacheStorageDispatcher::OnCacheStorageMatchSuccess(
match_times_.erase(request_id);
}
-void CacheStorageDispatcher::OnCacheStorageHasError(
- int thread_id,
- int request_id,
- blink::WebServiceWorkerCacheError reason) {
+void CacheStorageDispatcher::OnCacheStorageHasError(int thread_id,
+ int request_id,
+ CacheStorageError reason) {
DCHECK_EQ(thread_id, CurrentWorkerId());
WebServiceWorkerCacheStorage::CacheStorageCallbacks* callbacks =
has_callbacks_.Lookup(request_id);
@@ -353,10 +352,9 @@ void CacheStorageDispatcher::OnCacheStorageHasError(
has_times_.erase(request_id);
}
-void CacheStorageDispatcher::OnCacheStorageOpenError(
- int thread_id,
- int request_id,
- blink::WebServiceWorkerCacheError reason) {
+void CacheStorageDispatcher::OnCacheStorageOpenError(int thread_id,
+ int request_id,
+ CacheStorageError reason) {
DCHECK_EQ(thread_id, CurrentWorkerId());
WebServiceWorkerCacheStorage::CacheStorageWithCacheCallbacks* callbacks =
open_callbacks_.Lookup(request_id);
@@ -368,7 +366,7 @@ void CacheStorageDispatcher::OnCacheStorageOpenError(
void CacheStorageDispatcher::OnCacheStorageDeleteError(
int thread_id,
int request_id,
- blink::WebServiceWorkerCacheError reason) {
+ CacheStorageError reason) {
DCHECK_EQ(thread_id, CurrentWorkerId());
WebServiceWorkerCacheStorage::CacheStorageCallbacks* callbacks =
delete_callbacks_.Lookup(request_id);
@@ -380,7 +378,7 @@ void CacheStorageDispatcher::OnCacheStorageDeleteError(
void CacheStorageDispatcher::OnCacheStorageMatchError(
int thread_id,
int request_id,
- blink::WebServiceWorkerCacheError reason) {
+ CacheStorageError reason) {
DCHECK_EQ(thread_id, CurrentWorkerId());
WebServiceWorkerCacheStorage::CacheStorageMatchCallbacks* callbacks =
match_callbacks_.Lookup(request_id);
@@ -450,10 +448,9 @@ void CacheStorageDispatcher::OnCacheBatchSuccess(
cache_batch_times_.erase(request_id);
}
-void CacheStorageDispatcher::OnCacheMatchError(
- int thread_id,
- int request_id,
- blink::WebServiceWorkerCacheError reason) {
+void CacheStorageDispatcher::OnCacheMatchError(int thread_id,
+ int request_id,
+ CacheStorageError reason) {
DCHECK_EQ(thread_id, CurrentWorkerId());
blink::WebServiceWorkerCache::CacheMatchCallbacks* callbacks =
cache_match_callbacks_.Lookup(request_id);
@@ -462,10 +459,9 @@ void CacheStorageDispatcher::OnCacheMatchError(
cache_match_times_.erase(request_id);
}
-void CacheStorageDispatcher::OnCacheMatchAllError(
- int thread_id,
- int request_id,
- blink::WebServiceWorkerCacheError reason) {
+void CacheStorageDispatcher::OnCacheMatchAllError(int thread_id,
+ int request_id,
+ CacheStorageError reason) {
DCHECK_EQ(thread_id, CurrentWorkerId());
blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks =
cache_match_all_callbacks_.Lookup(request_id);
@@ -474,10 +470,9 @@ void CacheStorageDispatcher::OnCacheMatchAllError(
cache_match_all_times_.erase(request_id);
}
-void CacheStorageDispatcher::OnCacheKeysError(
- int thread_id,
- int request_id,
- blink::WebServiceWorkerCacheError reason) {
+void CacheStorageDispatcher::OnCacheKeysError(int thread_id,
+ int request_id,
+ CacheStorageError reason) {
DCHECK_EQ(thread_id, CurrentWorkerId());
blink::WebServiceWorkerCache::CacheWithRequestsCallbacks* callbacks =
cache_keys_callbacks_.Lookup(request_id);
@@ -486,14 +481,13 @@ void CacheStorageDispatcher::OnCacheKeysError(
cache_keys_times_.erase(request_id);
}
-void CacheStorageDispatcher::OnCacheBatchError(
- int thread_id,
- int request_id,
- blink::WebServiceWorkerCacheError reason) {
+void CacheStorageDispatcher::OnCacheBatchError(int thread_id,
+ int request_id,
+ CacheStorageError reason) {
DCHECK_EQ(thread_id, CurrentWorkerId());
blink::WebServiceWorkerCache::CacheBatchCallbacks* callbacks =
cache_batch_callbacks_.Lookup(request_id);
- callbacks->OnError(blink::WebServiceWorkerCacheError(reason));
+ callbacks->OnError(CacheStorageError(reason));
cache_batch_callbacks_.Remove(request_id);
cache_batch_times_.erase(request_id);
}
diff --git a/chromium/content/renderer/cache_storage/cache_storage_dispatcher.h b/chromium/content/renderer/cache_storage/cache_storage_dispatcher.h
index a0771bc6b7a..6130bf8bc21 100644
--- a/chromium/content/renderer/cache_storage/cache_storage_dispatcher.h
+++ b/chromium/content/renderer/cache_storage/cache_storage_dispatcher.h
@@ -15,10 +15,10 @@
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
-#include "content/public/child/worker_thread.h"
+#include "content/public/renderer/worker_thread.h"
#include "ipc/ipc_message.h"
+#include "third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCache.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCacheError.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCacheStorage.h"
namespace url {
@@ -64,16 +64,16 @@ class CacheStorageDispatcher : public WorkerThread::Observer {
void OnCacheStorageHasError(int thread_id,
int request_id,
- blink::WebServiceWorkerCacheError reason);
+ blink::mojom::CacheStorageError reason);
void OnCacheStorageOpenError(int thread_id,
int request_id,
- blink::WebServiceWorkerCacheError reason);
+ blink::mojom::CacheStorageError reason);
void OnCacheStorageDeleteError(int thread_id,
int request_id,
- blink::WebServiceWorkerCacheError reason);
+ blink::mojom::CacheStorageError reason);
void OnCacheStorageMatchError(int thread_id,
int request_id,
- blink::WebServiceWorkerCacheError reason);
+ blink::mojom::CacheStorageError reason);
// Message handlers for Cache messages from the browser process.
void OnCacheMatchSuccess(int thread_id,
@@ -92,16 +92,16 @@ class CacheStorageDispatcher : public WorkerThread::Observer {
void OnCacheMatchError(int thread_id,
int request_id,
- blink::WebServiceWorkerCacheError reason);
+ blink::mojom::CacheStorageError reason);
void OnCacheMatchAllError(int thread_id,
int request_id,
- blink::WebServiceWorkerCacheError reason);
+ blink::mojom::CacheStorageError reason);
void OnCacheKeysError(int thread_id,
int request_id,
- blink::WebServiceWorkerCacheError reason);
+ blink::mojom::CacheStorageError reason);
void OnCacheBatchError(int thread_id,
int request_id,
- blink::WebServiceWorkerCacheError reason);
+ blink::mojom::CacheStorageError reason);
// TODO(jsbell): These are only called by WebServiceWorkerCacheStorageImpl
// and should be renamed to match Chromium conventions. crbug.com/439389
diff --git a/chromium/content/renderer/cache_storage/cache_storage_message_filter.h b/chromium/content/renderer/cache_storage/cache_storage_message_filter.h
index 28d0a41611a..6527594a58a 100644
--- a/chromium/content/renderer/cache_storage/cache_storage_message_filter.h
+++ b/chromium/content/renderer/cache_storage/cache_storage_message_filter.h
@@ -7,7 +7,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "content/child/worker_thread_message_filter.h"
+#include "content/renderer/worker_thread_message_filter.h"
namespace content {
diff --git a/chromium/content/renderer/cache_storage/webserviceworkercachestorage_impl.h b/chromium/content/renderer/cache_storage/webserviceworkercachestorage_impl.h
index 9b7c2fc472d..f7243567cc7 100644
--- a/chromium/content/renderer/cache_storage/webserviceworkercachestorage_impl.h
+++ b/chromium/content/renderer/cache_storage/webserviceworkercachestorage_impl.h
@@ -11,7 +11,6 @@
#include "content/child/thread_safe_sender.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCache.h"
-#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCacheError.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCacheStorage.h"
#include "url/origin.h"
diff --git a/chromium/content/renderer/child_frame_compositing_helper.cc b/chromium/content/renderer/child_frame_compositing_helper.cc
index dd13fcd97c6..c9d8866d683 100644
--- a/chromium/content/renderer/child_frame_compositing_helper.cc
+++ b/chromium/content/renderer/child_frame_compositing_helper.cc
@@ -209,21 +209,6 @@ void ChildFrameCompositingHelper::UpdateWebLayer(
web_layer_ = std::move(layer);
}
-void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
- const viz::SurfaceInfo& surface_info,
- cc::Layer* layer) {
- if (last_surface_size_in_pixels_ == surface_info.size_in_pixels())
- return;
-
- last_surface_size_in_pixels_ = surface_info.size_in_pixels();
- // The container size is in DIP, so is the layer size.
- // Buffer size is in physical pixels, so we need to adjust
- // it by the device scale factor.
- gfx::Size device_scale_adjusted_size = gfx::ScaleToFlooredSize(
- surface_info.size_in_pixels(), 1.0f / surface_info.device_scale_factor());
- layer->SetBounds(device_scale_adjusted_size);
-}
-
void ChildFrameCompositingHelper::OnContainerDestroy() {
UpdateWebLayer(nullptr);
}
@@ -261,24 +246,20 @@ void ChildFrameCompositingHelper::ChildFrameGone() {
UpdateWebLayer(std::move(layer));
}
-void ChildFrameCompositingHelper::SetPrimarySurfaceInfo(
- const viz::SurfaceInfo& surface_info) {
- last_primary_surface_id_ = surface_info.id();
- float scale_factor = surface_info.device_scale_factor();
- // TODO(oshima): This is a stopgap fix so that the compositor does not
- // scaledown the content when 2x frame data is added to 1x parent frame data.
- // Fix this in cc/.
- if (IsUseZoomForDSFEnabled())
- scale_factor = 1.0f;
+void ChildFrameCompositingHelper::SetPrimarySurfaceId(
+ const viz::SurfaceId& surface_id,
+ const gfx::Size& frame_size_in_dip) {
+ if (last_primary_surface_id_ == surface_id)
+ return;
+
+ last_primary_surface_id_ = surface_id;
surface_layer_ = cc::SurfaceLayer::Create(surface_reference_factory_);
surface_layer_->SetMasksToBounds(true);
surface_layer_->SetDefaultBackgroundColor(SK_ColorTRANSPARENT);
- viz::SurfaceInfo modified_surface_info(surface_info.id(), scale_factor,
- surface_info.size_in_pixels());
- surface_layer_->SetPrimarySurfaceInfo(modified_surface_info);
- surface_layer_->SetFallbackSurfaceInfo(fallback_surface_info_);
+ surface_layer_->SetPrimarySurfaceId(surface_id);
+ surface_layer_->SetFallbackSurfaceId(fallback_surface_id_);
std::unique_ptr<cc_blink::WebLayerImpl> layer(
new cc_blink::WebLayerImpl(surface_layer_));
@@ -290,22 +271,19 @@ void ChildFrameCompositingHelper::SetPrimarySurfaceInfo(
UpdateVisibility(true);
- CheckSizeAndAdjustLayerProperties(
- surface_info,
- static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer());
+ static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())
+ ->layer()
+ ->SetBounds(frame_size_in_dip);
}
-void ChildFrameCompositingHelper::SetFallbackSurfaceInfo(
- const viz::SurfaceInfo& surface_info,
+void ChildFrameCompositingHelper::SetFallbackSurfaceId(
+ const viz::SurfaceId& surface_id,
+ const gfx::Size& frame_size_in_dip,
const viz::SurfaceSequence& sequence) {
- fallback_surface_info_ = surface_info;
- float scale_factor = surface_info.device_scale_factor();
- // TODO(oshima): This is a stopgap fix so that the compositor does not
- // scaledown the content when 2x frame data is added to 1x parent frame data.
- // Fix this in cc/.
- if (IsUseZoomForDSFEnabled())
- scale_factor = 1.0f;
+ if (fallback_surface_id_ == surface_id)
+ return;
+ fallback_surface_id_ = surface_id;
// The RWHV creates a destruction dependency on the surface that needs to be
// satisfied. The reference factory will satisfy it when a new reference has
// been created.
@@ -321,9 +299,12 @@ void ChildFrameCompositingHelper::SetFallbackSurfaceInfo(
}
}
- viz::SurfaceInfo modified_surface_info(surface_info.id(), scale_factor,
- surface_info.size_in_pixels());
- surface_layer_->SetFallbackSurfaceInfo(modified_surface_info);
+ if (!surface_layer_) {
+ SetPrimarySurfaceId(surface_id, frame_size_in_dip);
+ return;
+ }
+
+ surface_layer_->SetFallbackSurfaceId(surface_id);
}
void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
diff --git a/chromium/content/renderer/child_frame_compositing_helper.h b/chromium/content/renderer/child_frame_compositing_helper.h
index 77e17f08ed2..d67244ab270 100644
--- a/chromium/content/renderer/child_frame_compositing_helper.h
+++ b/chromium/content/renderer/child_frame_compositing_helper.h
@@ -22,8 +22,6 @@
namespace cc {
struct SurfaceSequence;
-
-class Layer;
}
namespace blink {
@@ -37,7 +35,7 @@ class Size;
}
namespace viz {
-class SurfaceInfo;
+class SurfaceId;
}
namespace content {
@@ -55,9 +53,11 @@ class CONTENT_EXPORT ChildFrameCompositingHelper {
RenderFrameProxy* render_frame_proxy);
void OnContainerDestroy();
- void SetPrimarySurfaceInfo(const viz::SurfaceInfo& surface_info);
- void SetFallbackSurfaceInfo(const viz::SurfaceInfo& surface_info,
- const viz::SurfaceSequence& sequence);
+ void SetPrimarySurfaceId(const viz::SurfaceId& surface_id,
+ const gfx::Size& frame_size_in_dip);
+ void SetFallbackSurfaceId(const viz::SurfaceId& surface_id,
+ const gfx::Size& frame_size_in_dip,
+ const viz::SurfaceSequence& sequence);
void UpdateVisibility(bool);
void ChildFrameGone();
@@ -76,16 +76,13 @@ class CONTENT_EXPORT ChildFrameCompositingHelper {
blink::WebPluginContainer* GetContainer();
- void CheckSizeAndAdjustLayerProperties(const viz::SurfaceInfo& surface_info,
- cc::Layer* layer);
void UpdateWebLayer(std::unique_ptr<blink::WebLayer> layer);
const int host_routing_id_;
viz::SurfaceId last_primary_surface_id_;
- gfx::Size last_surface_size_in_pixels_;
- viz::SurfaceInfo fallback_surface_info_;
+ viz::SurfaceId fallback_surface_id_;
// The lifetime of this weak pointer should be greater than the lifetime of
// other member objects, as they may access this pointer during their
diff --git a/chromium/content/child/child_message_filter.cc b/chromium/content/renderer/child_message_filter.cc
index a2b99fab4b6..c212d4835fa 100644
--- a/chromium/content/child/child_message_filter.cc
+++ b/chromium/content/renderer/child_message_filter.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/child/child_message_filter.h"
+#include "content/renderer/child_message_filter.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -48,11 +48,11 @@ bool ChildMessageFilter::Send(IPC::Message* message) {
base::TaskRunner* ChildMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& msg) {
- return NULL;
+ return nullptr;
}
ChildMessageFilter::ChildMessageFilter()
- : internal_(NULL),
+ : internal_(nullptr),
thread_safe_sender_(ChildThreadImpl::current()->thread_safe_sender()) {}
ChildMessageFilter::~ChildMessageFilter() {}
diff --git a/chromium/content/child/child_message_filter.h b/chromium/content/renderer/child_message_filter.h
index 85787d92a3e..d02cf3a09d3 100644
--- a/chromium/content/child/child_message_filter.h
+++ b/chromium/content/renderer/child_message_filter.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_CHILD_CHILD_MESSAGE_FILTER_H_
-#define CONTENT_CHILD_CHILD_MESSAGE_FILTER_H_
+#ifndef CONTENT_RENDERER_CHILD_MESSAGE_FILTER_H_
+#define CONTENT_RENDERER_CHILD_MESSAGE_FILTER_H_
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -71,4 +71,4 @@ class ChildMessageFilter
} // namespace content
-#endif // CONTENT_CHILD_CHILD_MESSAGE_FILTER_H_
+#endif // CONTENT_RENDERER_CHILD_MESSAGE_FILTER_H_
diff --git a/chromium/content/renderer/context_menu_params_builder.cc b/chromium/content/renderer/context_menu_params_builder.cc
index 61eb893cf99..2adab17796f 100644
--- a/chromium/content/renderer/context_menu_params_builder.cc
+++ b/chromium/content/renderer/context_menu_params_builder.cc
@@ -25,10 +25,10 @@ ContextMenuParams ContextMenuParamsBuilder::Build(
params.src_url = data.src_url;
params.has_image_contents = data.has_image_contents;
params.page_url = data.page_url;
- params.keyword_url = data.keyword_url;
params.frame_url = data.frame_url;
params.media_flags = data.media_flags;
params.selection_text = data.selected_text.Utf16();
+ params.selection_start_offset = data.selection_start_offset;
params.title_text = data.title_text.Utf16();
params.misspelled_word = data.misspelled_word.Utf16();
params.spellcheck_enabled = data.is_spell_checking_enabled;
@@ -55,11 +55,6 @@ ContextMenuParams ContextMenuParamsBuilder::Build(
for (size_t i = 0; i < data.custom_items.size(); ++i)
params.custom_items.push_back(MenuItemBuilder::Build(data.custom_items[i]));
- if (!data.frame_history_item.IsNull()) {
- params.frame_page_state =
- SingleHistoryItemToPageState(data.frame_history_item);
- }
-
params.link_text = data.link_text.Utf16();
params.source_type = static_cast<ui::MenuSourceType>(data.source_type);
diff --git a/chromium/content/renderer/devtools/devtools_agent.cc b/chromium/content/renderer/devtools/devtools_agent.cc
index 8d3abc305d0..685c39f6aca 100644
--- a/chromium/content/renderer/devtools/devtools_agent.cc
+++ b/chromium/content/renderer/devtools/devtools_agent.cc
@@ -15,13 +15,13 @@
#include "base/run_loop.h"
#include "base/sequence_checker.h"
#include "base/strings/string_number_conversions.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
+#include "content/child/child_process.h"
#include "content/common/devtools_messages.h"
#include "content/common/frame_messages.h"
#include "content/public/common/manifest.h"
-#include "content/renderer/devtools/devtools_client.h"
#include "content/renderer/devtools/devtools_cpu_throttler.h"
-#include "content/renderer/manifest/manifest_manager.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_widget.h"
#include "ipc/ipc_channel.h"
@@ -43,7 +43,9 @@ namespace content {
namespace {
-const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
+// TODO(dgozman): somehow get this from a mojo config.
+// See kMaximumMojoMessageSize in services/service_manager/embedder/main.cc.
+const size_t kMaxMessageChunkSize = 128 * 1024 * 1024 / 4;
const char kPageGetAppManifest[] = "Page.getAppManifest";
class WebKitClientMessageLoopImpl
@@ -57,11 +59,9 @@ class WebKitClientMessageLoopImpl
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
base::RunLoop* const previous_run_loop = run_loop_;
- base::RunLoop run_loop;
+ base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
run_loop_ = &run_loop;
- base::MessageLoop::ScopedNestableTaskAllower allow(
- base::MessageLoop::current());
run_loop.Run();
run_loop_ = previous_run_loop;
@@ -79,46 +79,121 @@ class WebKitClientMessageLoopImpl
SEQUENCE_CHECKER(sequence_checker_);
};
-typedef std::map<int, DevToolsAgent*> IdToAgentMap;
-base::LazyInstance<IdToAgentMap>::Leaky
- g_agent_for_routing_id = LAZY_INSTANCE_INITIALIZER;
-
} // namespace
+class DevToolsAgent::MessageImpl : public WebDevToolsAgent::MessageDescriptor {
+ public:
+ MessageImpl(base::WeakPtr<DevToolsAgent> agent,
+ const std::string& method,
+ const std::string& message)
+ : agent_(std::move(agent)), method_(method), msg_(message) {}
+ ~MessageImpl() override {}
+
+ WebDevToolsAgent* Agent() override {
+ if (!agent_)
+ return nullptr;
+ return agent_->GetWebAgent();
+ }
+ WebString Message() override { return WebString::FromUTF8(msg_); }
+ WebString Method() override { return WebString::FromUTF8(method_); }
+
+ private:
+ base::WeakPtr<DevToolsAgent> agent_;
+ std::string method_;
+ std::string msg_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageImpl);
+};
+
+// Created and stored in unique_ptr on UI.
+// Binds request, receives messages and destroys on IO.
+class DevToolsAgent::IOSession : public mojom::DevToolsSession {
+ public:
+ IOSession(int session_id,
+ base::SequencedTaskRunner* session_task_runner,
+ base::WeakPtr<DevToolsAgent> agent,
+ mojom::DevToolsSessionRequest request)
+ : session_id_(session_id),
+ agent_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ agent_(std::move(agent)),
+ binding_(this) {
+ session_task_runner->PostTask(
+ FROM_HERE, base::BindOnce(&IOSession::BindInterface,
+ base::Unretained(this), std::move(request)));
+ }
+
+ ~IOSession() override {}
+
+ void BindInterface(mojom::DevToolsSessionRequest request) {
+ binding_.Bind(std::move(request));
+ }
+
+ // mojom::DevToolsSession implementation.
+ void DispatchProtocolMessage(int call_id,
+ const std::string& method,
+ const std::string& message) override {
+ DCHECK(WebDevToolsAgent::ShouldInterruptForMethod(
+ WebString::FromUTF8(method)));
+ WebDevToolsAgent::InterruptAndDispatch(
+ session_id_, new DevToolsAgent::MessageImpl(agent_, method, message));
+ agent_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&DevToolsAgent::DispatchOnInspectorBackend,
+ agent_, session_id_, call_id, method, message));
+ }
+
+ void InspectElement(const gfx::Point& point) override { NOTREACHED(); }
+
+ private:
+ int session_id_;
+ scoped_refptr<base::SingleThreadTaskRunner> agent_task_runner_;
+ base::WeakPtr<DevToolsAgent> agent_;
+ mojo::Binding<mojom::DevToolsSession> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(IOSession);
+};
+
+class DevToolsAgent::Session : public mojom::DevToolsSession {
+ public:
+ Session(int session_id,
+ DevToolsAgent* agent,
+ mojom::DevToolsSessionAssociatedRequest request)
+ : session_id_(session_id),
+ agent_(agent),
+ binding_(this, std::move(request)) {}
+
+ ~Session() override {}
+
+ // mojom::DevToolsSession implementation.
+ void DispatchProtocolMessage(int call_id,
+ const std::string& method,
+ const std::string& message) override {
+ DCHECK(!WebDevToolsAgent::ShouldInterruptForMethod(
+ WebString::FromUTF8(method)));
+ agent_->DispatchOnInspectorBackend(session_id_, call_id, method, message);
+ }
+
+ void InspectElement(const gfx::Point& point) override {
+ agent_->InspectElement(session_id_, point);
+ }
+
+ private:
+ int session_id_;
+ DevToolsAgent* agent_;
+ mojo::AssociatedBinding<mojom::DevToolsSession> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(Session);
+};
+
DevToolsAgent::DevToolsAgent(RenderFrameImpl* frame)
: RenderFrameObserver(frame),
- is_devtools_client_(false),
+ binding_(this),
paused_(false),
frame_(frame),
weak_factory_(this) {
- g_agent_for_routing_id.Get()[routing_id()] = this;
frame_->GetWebFrame()->SetDevToolsAgentClient(this);
}
DevToolsAgent::~DevToolsAgent() {
- g_agent_for_routing_id.Get().erase(routing_id());
-}
-
-// Called on the Renderer thread.
-bool DevToolsAgent::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(DevToolsAgent, message)
- IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Attach, OnAttach)
- IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Reattach, OnReattach)
- IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Detach, OnDetach)
- IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DispatchOnInspectorBackend,
- OnDispatchOnInspectorBackend)
- IPC_MESSAGE_HANDLER(DevToolsAgentMsg_InspectElement, OnInspectElement)
- IPC_MESSAGE_HANDLER(DevToolsAgentMsg_RequestNewWindow_ACK,
- OnRequestNewWindowACK)
- IPC_MESSAGE_HANDLER(DevToolsMsg_SetupDevToolsClient, OnSetupDevToolsClient)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- if (message.type() == FrameMsg_Navigate::ID)
- ContinueProgram(); // Don't want to swallow the message.
-
- return handled;
}
void DevToolsAgent::WidgetWillClose() {
@@ -129,17 +204,50 @@ void DevToolsAgent::OnDestruct() {
delete this;
}
+void DevToolsAgent::AttachDevToolsSession(
+ mojom::DevToolsSessionHostAssociatedPtrInfo host,
+ mojom::DevToolsSessionAssociatedRequest session,
+ mojom::DevToolsSessionRequest io_session,
+ const base::Optional<std::string>& reattach_state) {
+ int session_id = ++last_session_id_;
+
+ if (reattach_state.has_value()) {
+ GetWebAgent()->Reattach(session_id,
+ WebString::FromUTF8(reattach_state.value()));
+ } else {
+ GetWebAgent()->Attach(session_id);
+ }
+
+ sessions_[session_id].reset(
+ new Session(session_id, this, std::move(session)));
+
+ base::SequencedTaskRunner* io_task_runner =
+ ChildProcess::current()->io_task_runner();
+ io_sessions_.emplace(
+ session_id,
+ std::unique_ptr<IOSession, base::OnTaskRunnerDeleter>(
+ new IOSession(session_id, io_task_runner, weak_factory_.GetWeakPtr(),
+ std::move(io_session)),
+ base::OnTaskRunnerDeleter(io_task_runner)));
+
+ hosts_[session_id].Bind(std::move(host));
+ hosts_[session_id].set_connection_error_handler(base::BindOnce(
+ &DevToolsAgent::DetachSession, base::Unretained(this), session_id));
+}
+
+void DevToolsAgent::DetachSession(int session_id) {
+ GetWebAgent()->Detach(session_id);
+ io_sessions_.erase(session_id);
+ sessions_.erase(session_id);
+ hosts_.erase(session_id);
+}
+
void DevToolsAgent::SendProtocolMessage(int session_id,
int call_id,
const blink::WebString& message,
const blink::WebString& state_cookie) {
- if (!send_protocol_message_callback_for_test_.is_null()) {
- send_protocol_message_callback_for_test_.Run(
- session_id, call_id, message.Utf8(), state_cookie.Utf8());
- return;
- }
- SendChunkedProtocolMessage(this, routing_id(), session_id, call_id,
- message.Utf8(), state_cookie.Utf8());
+ SendChunkedProtocolMessage(session_id, call_id, message.Utf8(),
+ state_cookie.Utf8());
}
// static
@@ -161,12 +269,18 @@ void DevToolsAgent::DidExitDebugLoop() {
paused_ = false;
}
-bool DevToolsAgent::RequestDevToolsForFrame(blink::WebLocalFrame* webFrame) {
+bool DevToolsAgent::RequestDevToolsForFrame(int session_id,
+ blink::WebLocalFrame* webFrame) {
RenderFrameImpl* frame = RenderFrameImpl::FromWebFrame(webFrame);
if (!frame)
return false;
- Send(new DevToolsAgentHostMsg_RequestNewWindow(routing_id(),
- frame->GetRoutingID()));
+ auto it = hosts_.find(session_id);
+ if (it == hosts_.end())
+ return false;
+ it->second->RequestNewWindow(
+ frame->GetRoutingID(),
+ base::Bind(&DevToolsAgent::OnRequestNewWindowCompleted,
+ weak_factory_.GetWeakPtr(), session_id));
return true;
}
@@ -191,78 +305,43 @@ void DevToolsAgent::SetCPUThrottlingRate(double rate) {
DevToolsCPUThrottler::GetInstance()->SetThrottlingRate(rate);
}
-// static
-DevToolsAgent* DevToolsAgent::FromRoutingId(int routing_id) {
- IdToAgentMap::iterator it = g_agent_for_routing_id.Get().find(routing_id);
- if (it != g_agent_for_routing_id.Get().end()) {
- return it->second;
- }
- return NULL;
-}
-
-// static
-void DevToolsAgent::SendChunkedProtocolMessage(IPC::Sender* sender,
- int routing_id,
- int session_id,
+void DevToolsAgent::SendChunkedProtocolMessage(int session_id,
int call_id,
- const std::string& message,
- const std::string& post_state) {
- DevToolsMessageChunk chunk;
- chunk.message_size = message.size();
- chunk.is_first = true;
-
- if (message.length() < kMaxMessageChunkSize) {
- chunk.data = message;
- chunk.session_id = session_id;
- chunk.call_id = call_id;
- chunk.post_state = post_state;
- chunk.is_last = true;
- sender->Send(new DevToolsClientMsg_DispatchOnInspectorFrontend(
- routing_id, chunk));
+ std::string message,
+ std::string post_state) {
+ if (!send_protocol_message_callback_for_test_.is_null()) {
+ send_protocol_message_callback_for_test_.Run(
+ session_id, call_id, std::move(message), std::move(post_state));
return;
}
+ auto it = hosts_.find(session_id);
+ if (it == hosts_.end())
+ return;
+
+ bool single_chunk = message.length() < kMaxMessageChunkSize;
for (size_t pos = 0; pos < message.length(); pos += kMaxMessageChunkSize) {
- chunk.is_last = pos + kMaxMessageChunkSize >= message.length();
- chunk.session_id = session_id;
- chunk.call_id = chunk.is_last ? call_id : 0;
- chunk.post_state = chunk.is_last ? post_state : std::string();
- chunk.data = message.substr(pos, kMaxMessageChunkSize);
- sender->Send(new DevToolsClientMsg_DispatchOnInspectorFrontend(
- routing_id, chunk));
- chunk.is_first = false;
- chunk.message_size = 0;
+ mojom::DevToolsMessageChunkPtr chunk = mojom::DevToolsMessageChunk::New();
+ chunk->is_first = pos == 0;
+ chunk->message_size = chunk->is_first ? message.size() : 0;
+ chunk->is_last = pos + kMaxMessageChunkSize >= message.length();
+ chunk->call_id = chunk->is_last ? call_id : 0;
+ chunk->post_state = chunk->is_last ? std::move(post_state) : std::string();
+ chunk->data = single_chunk ? std::move(message)
+ : message.substr(pos, kMaxMessageChunkSize);
+ it->second->DispatchProtocolMessage(std::move(chunk));
}
}
-void DevToolsAgent::OnAttach(const std::string& host_id, int session_id) {
- GetWebAgent()->Attach(WebString::FromUTF8(host_id), session_id);
- session_ids_.insert(session_id);
-}
-
-void DevToolsAgent::OnReattach(const std::string& host_id,
- int session_id,
- const std::string& agent_state) {
- GetWebAgent()->Reattach(WebString::FromUTF8(host_id), session_id,
- WebString::FromUTF8(agent_state));
- session_ids_.insert(session_id);
-}
-
-void DevToolsAgent::OnDetach(int session_id) {
- GetWebAgent()->Detach(session_id);
- session_ids_.erase(session_id);
-}
-
-void DevToolsAgent::OnDispatchOnInspectorBackend(int session_id,
- int call_id,
- const std::string& method,
- const std::string& message) {
- TRACE_EVENT0("devtools", "DevToolsAgent::OnDispatchOnInspectorBackend");
+void DevToolsAgent::DispatchOnInspectorBackend(int session_id,
+ int call_id,
+ const std::string& method,
+ const std::string& message) {
+ TRACE_EVENT0("devtools", "DevToolsAgent::DispatchOnInspectorBackend");
if (method == kPageGetAppManifest) {
- ManifestManager* manager = frame_->manifest_manager();
- manager->GetManifest(base::BindOnce(&DevToolsAgent::GotManifest,
- weak_factory_.GetWeakPtr(), session_id,
- call_id));
+ frame_->GetManifestManager().RequestManifestDebugInfo(
+ base::BindOnce(&DevToolsAgent::GotManifest, weak_factory_.GetWeakPtr(),
+ session_id, call_id));
return;
}
GetWebAgent()->DispatchOnInspectorBackend(session_id, call_id,
@@ -270,82 +349,80 @@ void DevToolsAgent::OnDispatchOnInspectorBackend(int session_id,
WebString::FromUTF8(message));
}
-void DevToolsAgent::OnInspectElement(int session_id, int x, int y) {
- blink::WebFloatRect point_rect(x, y, 0, 0);
+void DevToolsAgent::InspectElement(int session_id, const gfx::Point& point) {
+ blink::WebFloatRect point_rect(point.x(), point.y(), 0, 0);
frame_->GetRenderWidget()->ConvertWindowToViewport(&point_rect);
GetWebAgent()->InspectElementAt(session_id,
WebPoint(point_rect.x, point_rect.y));
}
-void DevToolsAgent::OnRequestNewWindowACK(bool success) {
+void DevToolsAgent::OnRequestNewWindowCompleted(int session_id, bool success) {
if (!success)
- GetWebAgent()->FailedToRequestDevTools();
+ GetWebAgent()->FailedToRequestDevTools(session_id);
}
void DevToolsAgent::ContinueProgram() {
GetWebAgent()->ContinueProgram();
}
-void DevToolsAgent::OnSetupDevToolsClient(const std::string& api_script) {
- // We only want to register once; and only in main frame.
- if (is_devtools_client_)
- return;
- is_devtools_client_ = true;
- new DevToolsClient(frame_, api_script);
-}
-
WebDevToolsAgent* DevToolsAgent::GetWebAgent() {
return frame_->GetWebFrame()->DevToolsAgent();
}
+void DevToolsAgent::BindRequest(mojom::DevToolsAgentAssociatedRequest request) {
+ binding_.Bind(std::move(request));
+}
+
+base::WeakPtr<DevToolsAgent> DevToolsAgent::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
bool DevToolsAgent::IsAttached() {
- return !!session_ids_.size();
+ return !hosts_.empty();
}
void DevToolsAgent::DetachAllSessions() {
- for (int session_id : session_ids_)
- GetWebAgent()->Detach(session_id);
- session_ids_.clear();
+ for (auto& it : hosts_)
+ GetWebAgent()->Detach(it.first);
+ hosts_.clear();
+ io_sessions_.clear();
+ sessions_.clear();
}
void DevToolsAgent::GotManifest(int session_id,
int call_id,
const GURL& manifest_url,
- const Manifest& manifest,
- const ManifestDebugInfo& debug_info) {
- if (!IsAttached())
- return;
-
+ blink::mojom::ManifestDebugInfoPtr debug_info) {
std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue());
response->SetInteger("id", call_id);
std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
std::unique_ptr<base::ListValue> errors(new base::ListValue());
bool failed = false;
- for (const auto& error : debug_info.errors) {
- std::unique_ptr<base::DictionaryValue> error_value(
- new base::DictionaryValue());
- error_value->SetString("message", error.message);
- error_value->SetBoolean("critical", error.critical);
- error_value->SetInteger("line", error.line);
- error_value->SetInteger("column", error.column);
- if (error.critical)
- failed = true;
- errors->Append(std::move(error_value));
+ if (debug_info) {
+ for (const auto& error : debug_info->errors) {
+ std::unique_ptr<base::DictionaryValue> error_value(
+ new base::DictionaryValue());
+ error_value->SetString("message", error->message);
+ error_value->SetBoolean("critical", error->critical);
+ error_value->SetInteger("line", error->line);
+ error_value->SetInteger("column", error->column);
+ if (error->critical)
+ failed = true;
+ errors->Append(std::move(error_value));
+ }
+ if (!failed)
+ result->SetString("data", debug_info->raw_manifest);
}
- WebString url =
- frame_->GetWebFrame()->GetDocument().ManifestURL().GetString();
- result->SetString("url", url.Utf16());
- if (!failed)
- result->SetString("data", debug_info.raw_data);
+ result->SetString("url", manifest_url.possibly_invalid_spec());
result->Set("errors", std::move(errors));
response->Set("result", std::move(result));
std::string json_message;
base::JSONWriter::Write(*response, &json_message);
- SendChunkedProtocolMessage(this, routing_id(), session_id, call_id,
- json_message, std::string());
+ SendChunkedProtocolMessage(session_id, call_id, std::move(json_message),
+ std::string());
}
} // namespace content
diff --git a/chromium/content/renderer/devtools/devtools_agent.h b/chromium/content/renderer/devtools/devtools_agent.h
index ae34dd59caf..30626310027 100644
--- a/chromium/content/renderer/devtools/devtools_agent.h
+++ b/chromium/content/renderer/devtools/devtools_agent.h
@@ -10,10 +10,14 @@
#include <string>
#include "base/callback.h"
+#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
+#include "content/common/devtools.mojom.h"
#include "content/public/renderer/render_frame_observer.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "third_party/WebKit/public/platform/modules/manifest/manifest.mojom.h"
#include "third_party/WebKit/public/web/WebDevToolsAgentClient.h"
namespace blink {
@@ -25,82 +29,79 @@ class GURL;
namespace content {
class RenderFrameImpl;
-struct Manifest;
-struct ManifestDebugInfo;
-// DevToolsAgent belongs to the inspectable RenderFrameImpl and communicates
-// with WebDevToolsAgent. There is a corresponding DevToolsAgentHost
-// on the browser side.
+// Implementation of content.mojom.DevToolsAgent interface for RenderFrameImpl.
class CONTENT_EXPORT DevToolsAgent : public RenderFrameObserver,
- public blink::WebDevToolsAgentClient {
+ public blink::WebDevToolsAgentClient,
+ public mojom::DevToolsAgent {
public:
explicit DevToolsAgent(RenderFrameImpl* frame);
~DevToolsAgent() override;
- // Returns agent instance for its routing id.
- static DevToolsAgent* FromRoutingId(int routing_id);
-
- static void SendChunkedProtocolMessage(IPC::Sender* sender,
- int routing_id,
- int session_id,
- int call_id,
- const std::string& message,
- const std::string& post_state);
static blink::WebDevToolsAgentClient::WebKitClientMessageLoop*
createMessageLoopWrapper();
- blink::WebDevToolsAgent* GetWebAgent();
-
+ void BindRequest(mojom::DevToolsAgentAssociatedRequest request);
+ base::WeakPtr<DevToolsAgent> GetWeakPtr();
bool IsAttached();
void DetachAllSessions();
+ void ContinueProgram();
private:
friend class DevToolsAgentTest;
+ class Session;
+ class IOSession;
+ class MessageImpl;
// RenderFrameObserver implementation.
- bool OnMessageReceived(const IPC::Message& message) override;
void WidgetWillClose() override;
void OnDestruct() override;
+ // mojom::DevToolsAgent implementation.
+ void AttachDevToolsSession(
+ mojom::DevToolsSessionHostAssociatedPtrInfo host,
+ mojom::DevToolsSessionAssociatedRequest session,
+ mojom::DevToolsSessionRequest io_session,
+ const base::Optional<std::string>& reattach_state) override;
+
// WebDevToolsAgentClient implementation.
void SendProtocolMessage(int session_id,
int call_id,
- const blink::WebString& response,
- const blink::WebString& state) override;
+ const blink::WebString& message,
+ const blink::WebString& state_cookie) override;
blink::WebDevToolsAgentClient::WebKitClientMessageLoop*
CreateClientMessageLoop() override;
void WillEnterDebugLoop() override;
void DidExitDebugLoop() override;
-
- bool RequestDevToolsForFrame(blink::WebLocalFrame* frame) override;
-
+ bool RequestDevToolsForFrame(int session_id,
+ blink::WebLocalFrame* frame) override;
void EnableTracing(const blink::WebString& category_filter) override;
void DisableTracing() override;
-
void SetCPUThrottlingRate(double rate) override;
- void OnAttach(const std::string& host_id, int session_id);
- void OnReattach(const std::string& host_id,
- int session_id,
- const std::string& agent_state);
- void OnDetach(int session_id);
- void OnDispatchOnInspectorBackend(int session_id,
- int call_id,
- const std::string& method,
- const std::string& message);
- void OnInspectElement(int session_id, int x, int y);
- void OnRequestNewWindowACK(bool success);
- void ContinueProgram();
- void OnSetupDevToolsClient(const std::string& api_script);
-
+ void DetachSession(int session_id);
+ blink::WebDevToolsAgent* GetWebAgent();
+ void DispatchOnInspectorBackend(int session_id,
+ int call_id,
+ const std::string& method,
+ const std::string& message);
+ void InspectElement(int session_id, const gfx::Point& point);
+ void OnRequestNewWindowCompleted(int session_id, bool success);
void GotManifest(int session_id,
int command_id,
const GURL& manifest_url,
- const Manifest& manifest,
- const ManifestDebugInfo& debug_info);
-
- std::set<int> session_ids_;
- bool is_devtools_client_;
+ blink::mojom::ManifestDebugInfoPtr debug_info);
+ void SendChunkedProtocolMessage(int session_id,
+ int call_id,
+ std::string message,
+ std::string post_state);
+
+ mojo::AssociatedBinding<mojom::DevToolsAgent> binding_;
+ int last_session_id_ = 0;
+ base::flat_map<int, std::unique_ptr<Session>> sessions_;
+ base::flat_map<int, std::unique_ptr<IOSession, base::OnTaskRunnerDeleter>>
+ io_sessions_;
+ base::flat_map<int, mojom::DevToolsSessionHostAssociatedPtr> hosts_;
bool paused_;
RenderFrameImpl* frame_;
base::Callback<void(int, int, const std::string&, const std::string&)>
diff --git a/chromium/content/renderer/devtools/devtools_agent_filter.cc b/chromium/content/renderer/devtools/devtools_agent_filter.cc
deleted file mode 100644
index 94fd5c68d66..00000000000
--- a/chromium/content/renderer/devtools/devtools_agent_filter.cc
+++ /dev/null
@@ -1,103 +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/devtools/devtools_agent_filter.h"
-
-#include "base/bind.h"
-#include "content/child/child_process.h"
-#include "content/common/devtools_messages.h"
-#include "content/renderer/devtools/devtools_agent.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebDevToolsAgent.h"
-
-using blink::WebDevToolsAgent;
-using blink::WebString;
-
-namespace content {
-
-namespace {
-
-class MessageImpl : public WebDevToolsAgent::MessageDescriptor {
- public:
- MessageImpl(
- const std::string& method,
- const std::string& message,
- int routing_id)
- : method_(method),
- msg_(message),
- routing_id_(routing_id) {
- }
- ~MessageImpl() override {}
- WebDevToolsAgent* Agent() override {
- DevToolsAgent* agent = DevToolsAgent::FromRoutingId(routing_id_);
- if (!agent)
- return 0;
- return agent->GetWebAgent();
- }
- WebString Message() override { return WebString::FromUTF8(msg_); }
- WebString Method() override { return WebString::FromUTF8(method_); }
-
- private:
- std::string method_;
- std::string msg_;
- int routing_id_;
-};
-
-} // namespace
-
-DevToolsAgentFilter::DevToolsAgentFilter()
- : io_task_runner_(ChildProcess::current()->io_task_runner()),
- current_routing_id_(0) {}
-
-bool DevToolsAgentFilter::OnMessageReceived(const IPC::Message& message) {
- // Dispatch debugger commands directly from IO.
- current_routing_id_ = message.routing_id();
- IPC_BEGIN_MESSAGE_MAP(DevToolsAgentFilter, message)
- IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DispatchOnInspectorBackend,
- OnDispatchOnInspectorBackend)
- IPC_END_MESSAGE_MAP()
- return false;
-}
-
-DevToolsAgentFilter::~DevToolsAgentFilter() {}
-
-void DevToolsAgentFilter::OnDispatchOnInspectorBackend(
- int session_id,
- int call_id,
- const std::string& method,
- const std::string& message) {
- if (embedded_worker_routes_.find(current_routing_id_) !=
- embedded_worker_routes_.end()) {
- return;
- }
-
- if (WebDevToolsAgent::ShouldInterruptForMethod(WebString::FromUTF8(method))) {
- WebDevToolsAgent::InterruptAndDispatch(
- session_id, new MessageImpl(method, message, current_routing_id_));
- }
-}
-
-void DevToolsAgentFilter::AddEmbeddedWorkerRouteOnMainThread(
- int32_t routing_id) {
- io_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&DevToolsAgentFilter::AddEmbeddedWorkerRoute,
- this, routing_id));
-}
-
-void DevToolsAgentFilter::RemoveEmbeddedWorkerRouteOnMainThread(
- int32_t routing_id) {
- io_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&DevToolsAgentFilter::RemoveEmbeddedWorkerRoute,
- this, routing_id));
-}
-
-void DevToolsAgentFilter::AddEmbeddedWorkerRoute(int32_t routing_id) {
- embedded_worker_routes_.insert(routing_id);
-}
-
-void DevToolsAgentFilter::RemoveEmbeddedWorkerRoute(int32_t routing_id) {
- embedded_worker_routes_.erase(routing_id);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/devtools/devtools_agent_filter.h b/chromium/content/renderer/devtools/devtools_agent_filter.h
deleted file mode 100644
index 69fcb29e405..00000000000
--- a/chromium/content/renderer/devtools/devtools_agent_filter.h
+++ /dev/null
@@ -1,68 +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_DEVTOOLS_DEVTOOLS_AGENT_FILTER_H_
-#define CONTENT_RENDERER_DEVTOOLS_DEVTOOLS_AGENT_FILTER_H_
-
-#include <stdint.h>
-
-#include <set>
-#include <string>
-
-#include "base/macros.h"
-#include "ipc/message_filter.h"
-
-struct DevToolsMessageData;
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace content {
-
-// DevToolsAgentFilter is registered as an IPC filter in order to be able to
-// dispatch messages while on the IO thread. The reason for that is that while
-// debugging, Render thread is being held by the v8 and hence no messages
-// are being dispatched there. While holding the thread in a tight loop,
-// v8 provides thread-safe Api for controlling debugger. In our case v8's Api
-// is being used from this communication agent on the IO thread.
-class DevToolsAgentFilter : public IPC::MessageFilter {
- public:
- // There is a single instance of this class instantiated by the RenderThread.
- DevToolsAgentFilter();
-
- static void SendRpcMessage(const DevToolsMessageData& data);
-
- // IPC::MessageFilter override. Called on IO thread.
- bool OnMessageReceived(const IPC::Message& message) override;
-
- // Called on the main thread.
- void AddEmbeddedWorkerRouteOnMainThread(int32_t routing_id);
- void RemoveEmbeddedWorkerRouteOnMainThread(int32_t routing_id);
-
- protected:
- ~DevToolsAgentFilter() override;
-
- private:
- void OnDispatchOnInspectorBackend(
- int session_id,
- int call_id,
- const std::string& method,
- const std::string& message);
-
- // Called on IO thread
- void AddEmbeddedWorkerRoute(int32_t routing_id);
- void RemoveEmbeddedWorkerRoute(int32_t routing_id);
-
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
- int current_routing_id_;
-
- std::set<int32_t> embedded_worker_routes_;
-
- DISALLOW_COPY_AND_ASSIGN(DevToolsAgentFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_DEVTOOLS_DEVTOOLS_AGENT_FILTER_H_
diff --git a/chromium/content/renderer/devtools/devtools_client.cc b/chromium/content/renderer/devtools/devtools_client.cc
deleted file mode 100644
index 01a482af38f..00000000000
--- a/chromium/content/renderer/devtools/devtools_client.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/devtools/devtools_client.h"
-
-#include "base/command_line.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/utf_string_conversions.h"
-#include "content/common/devtools_messages.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/url_constants.h"
-#include "content/renderer/render_thread_impl.h"
-#include "content/renderer/render_view_impl.h"
-#include "third_party/WebKit/public/platform/WebFloatPoint.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebDevToolsFrontend.h"
-#include "ui/base/ui_base_switches.h"
-
-using blink::WebDevToolsFrontend;
-using blink::WebString;
-
-namespace content {
-
-DevToolsClient::DevToolsClient(RenderFrame* render_frame,
- const std::string& api_script)
- : RenderFrameObserver(render_frame), api_script_(api_script) {
- if (render_frame->IsMainFrame()) {
- web_tools_frontend_.reset(
- WebDevToolsFrontend::Create(render_frame->GetWebFrame(), this));
- }
-}
-
-DevToolsClient::~DevToolsClient() {
-}
-
-void DevToolsClient::DidClearWindowObject() {
- if (!api_script_.empty())
- render_frame()->ExecuteJavaScript(base::UTF8ToUTF16(api_script_));
-}
-
-void DevToolsClient::OnDestruct() {
- delete this;
-}
-
-void DevToolsClient::SendMessageToEmbedder(const WebString& message) {
- Send(new DevToolsHostMsg_DispatchOnEmbedder(routing_id(), message.Utf8()));
-}
-
-bool DevToolsClient::IsUnderTest() {
- return RenderThreadImpl::current()->layout_test_mode();
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/devtools/devtools_client.h b/chromium/content/renderer/devtools/devtools_client.h
deleted file mode 100644
index 7c32dee4b91..00000000000
--- a/chromium/content/renderer/devtools/devtools_client.h
+++ /dev/null
@@ -1,57 +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_DEVTOOLS_DEVTOOLS_CLIENT_H_
-#define CONTENT_RENDERER_DEVTOOLS_DEVTOOLS_CLIENT_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "content/public/renderer/render_frame_observer.h"
-#include "third_party/WebKit/public/web/WebDevToolsFrontendClient.h"
-
-namespace blink {
-class WebDevToolsFrontend;
-class WebString;
-}
-
-namespace content {
-
-// Developer tools UI end of communication channel between the render process of
-// the page being inspected and tools UI renderer process. All messages will
-// go through browser process. On the side of the inspected page there's
-// corresponding DevToolsAgent object.
-// TODO(yurys): now the client is almost empty later it will delegate calls to
-// code in glue
-class CONTENT_EXPORT DevToolsClient : public RenderFrameObserver,
- public blink::WebDevToolsFrontendClient {
- public:
- DevToolsClient(RenderFrame* render_frame, const std::string& api_script);
- ~DevToolsClient() override;
-
- private:
- // RenderFrameObserver overrides.
- void DidClearWindowObject() override;
- void OnDestruct() override;
-
- // WebDevToolsFrontendClient implementation.
- void SendMessageToEmbedder(const blink::WebString&) override;
-
- bool IsUnderTest() override;
-
- void OnDispatchOnInspectorFrontend(const std::string& message,
- uint32_t total_size);
-
- std::string api_script_;
- std::unique_ptr<blink::WebDevToolsFrontend> web_tools_frontend_;
-
- DISALLOW_COPY_AND_ASSIGN(DevToolsClient);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_DEVTOOLS_DEVTOOLS_CLIENT_H_
diff --git a/chromium/content/renderer/devtools/devtools_cpu_throttler.cc b/chromium/content/renderer/devtools/devtools_cpu_throttler.cc
index 647ce0e128c..9769a07fe80 100644
--- a/chromium/content/renderer/devtools/devtools_cpu_throttler.cc
+++ b/chromium/content/renderer/devtools/devtools_cpu_throttler.cc
@@ -111,7 +111,7 @@ void CPUThrottlingThread::InstallSignalHandler() {
void CPUThrottlingThread::RestoreSignalHandler() {
if (!signal_handler_installed_)
return;
- sigaction(SIGUSR2, &old_signal_handler_, 0);
+ sigaction(SIGUSR2, &old_signal_handler_, nullptr);
signal_handler_installed_ = false;
}
diff --git a/chromium/content/renderer/devtools/devtools_frontend_impl.cc b/chromium/content/renderer/devtools/devtools_frontend_impl.cc
new file mode 100644
index 00000000000..1400750ed24
--- /dev/null
+++ b/chromium/content/renderer/devtools/devtools_frontend_impl.cc
@@ -0,0 +1,67 @@
+// 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/devtools/devtools_frontend_impl.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "content/renderer/render_frame_impl.h"
+#include "content/renderer/render_thread_impl.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/web/WebDevToolsFrontend.h"
+
+namespace content {
+
+// static
+void DevToolsFrontendImpl::CreateMojoService(
+ RenderFrame* render_frame,
+ mojom::DevToolsFrontendAssociatedRequest request) {
+ // Self-destructs on render frame deletion.
+ new DevToolsFrontendImpl(render_frame, std::move(request));
+}
+
+DevToolsFrontendImpl::DevToolsFrontendImpl(
+ RenderFrame* render_frame,
+ mojom::DevToolsFrontendAssociatedRequest request)
+ : RenderFrameObserver(render_frame), binding_(this, std::move(request)) {}
+
+DevToolsFrontendImpl::~DevToolsFrontendImpl() {}
+
+void DevToolsFrontendImpl::DidClearWindowObject() {
+ if (!api_script_.empty())
+ render_frame()->ExecuteJavaScript(base::UTF8ToUTF16(api_script_));
+}
+
+void DevToolsFrontendImpl::OnDestruct() {
+ delete this;
+}
+
+void DevToolsFrontendImpl::SendMessageToEmbedder(
+ const blink::WebString& message) {
+ if (host_)
+ host_->DispatchEmbedderMessage(message.Utf8());
+}
+
+bool DevToolsFrontendImpl::IsUnderTest() {
+ return RenderThreadImpl::current()->layout_test_mode();
+}
+
+void DevToolsFrontendImpl::SetupDevToolsFrontend(
+ const std::string& api_script,
+ mojom::DevToolsFrontendHostAssociatedPtrInfo host) {
+ DCHECK(render_frame()->IsMainFrame());
+ api_script_ = api_script;
+ web_devtools_frontend_.reset(
+ blink::WebDevToolsFrontend::Create(render_frame()->GetWebFrame(), this));
+ host_.Bind(std::move(host));
+ host_.set_connection_error_handler(base::BindOnce(
+ &DevToolsFrontendImpl::OnDestruct, base::Unretained(this)));
+}
+
+void DevToolsFrontendImpl::SetupDevToolsExtensionAPI(
+ const std::string& extension_api) {
+ DCHECK(!render_frame()->IsMainFrame());
+ api_script_ = extension_api;
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/devtools/devtools_frontend_impl.h b/chromium/content/renderer/devtools/devtools_frontend_impl.h
new file mode 100644
index 00000000000..6bab4f39b5f
--- /dev/null
+++ b/chromium/content/renderer/devtools/devtools_frontend_impl.h
@@ -0,0 +1,65 @@
+// 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_DEVTOOLS_DEVTOOLS_FRONTEND_IMPL_H_
+#define CONTENT_RENDERER_DEVTOOLS_DEVTOOLS_FRONTEND_IMPL_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "content/common/devtools.mojom.h"
+#include "content/public/renderer/render_frame_observer.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "third_party/WebKit/public/web/WebDevToolsFrontendClient.h"
+
+namespace blink {
+class WebDevToolsFrontend;
+class WebString;
+} // namespace blink
+
+namespace content {
+
+// Implementation of content.mojom.DevToolsFrontend interface.
+class DevToolsFrontendImpl : public RenderFrameObserver,
+ public blink::WebDevToolsFrontendClient,
+ public mojom::DevToolsFrontend {
+ public:
+ ~DevToolsFrontendImpl() override;
+
+ static void CreateMojoService(
+ RenderFrame* render_frame,
+ mojom::DevToolsFrontendAssociatedRequest request);
+
+ private:
+ DevToolsFrontendImpl(RenderFrame* render_frame,
+ mojom::DevToolsFrontendAssociatedRequest request);
+
+ // RenderFrameObserver overrides.
+ void DidClearWindowObject() override;
+ void OnDestruct() override;
+
+ // WebDevToolsFrontendClient implementation.
+ void SendMessageToEmbedder(const blink::WebString& message) override;
+ bool IsUnderTest() override;
+
+ // mojom::DevToolsFrontend implementation.
+ void SetupDevToolsFrontend(
+ const std::string& api_script,
+ mojom::DevToolsFrontendHostAssociatedPtrInfo host) override;
+ void SetupDevToolsExtensionAPI(const std::string& extension_api) override;
+
+ std::unique_ptr<blink::WebDevToolsFrontend> web_devtools_frontend_;
+ std::string api_script_;
+ mojom::DevToolsFrontendHostAssociatedPtr host_;
+ mojo::AssociatedBinding<mojom::DevToolsFrontend> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsFrontendImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_DEVTOOLS_DEVTOOLS_FRONTEND_IMPL_H_
diff --git a/chromium/content/renderer/dom_automation_controller.cc b/chromium/content/renderer/dom_automation_controller.cc
index 4f02ed6d61a..60d29f63540 100644
--- a/chromium/content/renderer/dom_automation_controller.cc
+++ b/chromium/content/renderer/dom_automation_controller.cc
@@ -6,10 +6,9 @@
#include "base/json/json_string_value_serializer.h"
#include "base/strings/string_util.h"
-#include "content/child/v8_value_converter_impl.h"
-#include "content/common/child_process_messages.h"
#include "content/common/frame_messages.h"
#include "content/renderer/render_view_impl.h"
+#include "content/renderer/v8_value_converter_impl.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "third_party/WebKit/public/web/WebKit.h"
diff --git a/chromium/content/renderer/dom_serializer_browsertest.cc b/chromium/content/renderer/dom_serializer_browsertest.cc
index 4b970141957..18b18f3f6b0 100644
--- a/chromium/content/renderer/dom_serializer_browsertest.cc
+++ b/chromium/content/renderer/dom_serializer_browsertest.cc
@@ -36,6 +36,7 @@
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebElementCollection.h"
+#include "third_party/WebKit/public/web/WebFrameContentDumper.h"
#include "third_party/WebKit/public/web/WebFrameSerializer.h"
#include "third_party/WebKit/public/web/WebFrameSerializerClient.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
@@ -166,7 +167,7 @@ class DomSerializerTests : public ContentBrowserTest,
void SerializeDomForURL(const GURL& frame_url) {
// Find corresponding WebFrame according to frame_url.
WebFrame* web_frame = FindSubFrameByURL(frame_url);
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
WebString file_path = WebString::FromUTF8("c:\\dummy.htm");
SingleLinkRewritingDelegate delegate(frame_url, file_path);
// Start serializing DOM.
@@ -178,7 +179,7 @@ class DomSerializerTests : public ContentBrowserTest,
void SerializeHTMLDOMWithDocTypeOnRenderer(const GURL& file_url) {
// Make sure original contents have document type.
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(HasDocType(doc));
// Do serialization.
@@ -196,7 +197,7 @@ class DomSerializerTests : public ContentBrowserTest,
void SerializeHTMLDOMWithoutDocTypeOnRenderer(const GURL& file_url) {
// Make sure original contents do not have document type.
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(!HasDocType(doc));
// Do serialization.
@@ -242,7 +243,7 @@ class DomSerializerTests : public ContentBrowserTest,
const GURL& file_url) {
// Make sure there is no META charset declaration in original document.
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement head_element = doc.Head();
@@ -264,7 +265,7 @@ class DomSerializerTests : public ContentBrowserTest,
// Make sure the first child of HEAD element is META which has charset
// declaration in serialized contents.
web_frame = GetMainFrame();
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
head_element = doc.Head();
@@ -291,7 +292,7 @@ class DomSerializerTests : public ContentBrowserTest,
// Make sure there are multiple META charset declarations in original
// document.
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement head_element = doc.Head();
@@ -318,7 +319,7 @@ class DomSerializerTests : public ContentBrowserTest,
// Make sure only first child of HEAD element is META which has charset
// declaration in serialized contents.
web_frame = GetMainFrame();
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
head_element = doc.Head();
@@ -355,7 +356,7 @@ class DomSerializerTests : public ContentBrowserTest,
// Get BODY's text content in DOM.
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement body_ele = doc.Body();
@@ -407,7 +408,7 @@ class DomSerializerTests : public ContentBrowserTest,
LoadContents(original_contents, file_url, WebString());
// Get value of BODY's title attribute in DOM.
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement body_ele = doc.Body();
@@ -449,7 +450,8 @@ class DomSerializerTests : public ContentBrowserTest,
'%', 0x2285, 0x00b9, '\'', 0
};
WebString value = body_element.GetAttribute("title");
- WebString content = doc.ContentAsTextForTesting();
+ WebString content = blink::WebFrameContentDumper::DumpWebViewAsText(
+ web_frame->View(), 1024);
ASSERT_TRUE(base::UTF16ToWide(value.Utf16()) == parsed_value);
ASSERT_TRUE(base::UTF16ToWide(content.Utf16()) == parsed_value);
@@ -473,7 +475,7 @@ class DomSerializerTests : public ContentBrowserTest,
// this test file, also all links are relative URLs in this test file, so we
// need to check those relative URLs and make sure document has BASE tag.
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
// Go through all descent nodes.
@@ -516,7 +518,7 @@ class DomSerializerTests : public ContentBrowserTest,
// BASE tags in serialized HTML data. Each of those BASE tags have same base
// URL which is as same as URL of current test file.
web_frame = GetMainFrame();
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
// Go through all descent nodes.
@@ -564,7 +566,7 @@ class DomSerializerTests : public ContentBrowserTest,
// Make sure the head tag is empty.
WebLocalFrame* web_frame = GetMainFrame();
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement head_element = doc.Head();
@@ -579,7 +581,7 @@ class DomSerializerTests : public ContentBrowserTest,
LoadContents(serialized_contents_, file_url,
web_frame->GetDocument().Encoding());
web_frame = GetMainFrame();
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
head_element = doc.Head();
@@ -604,7 +606,7 @@ class DomSerializerTests : public ContentBrowserTest,
void SubResourceForElementsInNonHTMLNamespaceOnRenderer(
const GURL& file_url) {
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
- ASSERT_TRUE(web_frame != NULL);
+ ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
WebNode lastNodeInBody = doc.Body().LastChild();
ASSERT_TRUE(lastNodeInBody.IsElementNode());
diff --git a/chromium/content/renderer/dom_storage/DEPS b/chromium/content/renderer/dom_storage/DEPS
index 495daf36db9..b1259df127b 100644
--- a/chromium/content/renderer/dom_storage/DEPS
+++ b/chromium/content/renderer/dom_storage/DEPS
@@ -7,5 +7,7 @@ specific_include_rules = {
"+content/renderer/dom_storage/local_storage_cached_areas.h",
"+content/renderer/dom_storage/local_storage_area.h",
"+content/renderer/dom_storage/local_storage_namespace.h",
+ "+content/renderer/dom_storage/mock_leveldb_wrapper.h",
+ "+content/renderer/render_thread_impl.h",
],
}
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 8721c94a712..dc3f333607b 100644
--- a/chromium/content/renderer/dom_storage/dom_storage_cached_area.cc
+++ b/chromium/content/renderer/dom_storage/dom_storage_cached_area.cc
@@ -11,16 +11,20 @@
#include "build/build_config.h"
#include "content/common/dom_storage/dom_storage_map.h"
#include "content/renderer/dom_storage/dom_storage_proxy.h"
+#include "third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h"
namespace content {
-DOMStorageCachedArea::DOMStorageCachedArea(int64_t namespace_id,
- const GURL& origin,
- DOMStorageProxy* proxy)
+DOMStorageCachedArea::DOMStorageCachedArea(
+ int64_t namespace_id,
+ const GURL& origin,
+ DOMStorageProxy* proxy,
+ blink::scheduler::RendererScheduler* renderer_scheduler)
: ignore_all_mutations_(false),
namespace_id_(namespace_id),
origin_(origin),
proxy_(proxy),
+ renderer_scheduler_(renderer_scheduler),
weak_factory_(this) {}
DOMStorageCachedArea::~DOMStorageCachedArea() {}
@@ -68,10 +72,14 @@ bool DOMStorageCachedArea::SetItem(int connection_id,
#endif // !defined(OS_ANDROID)
// Ignore mutations to 'key' until OnSetItemComplete.
+ blink::WebScopedVirtualTimePauser virtual_time_pauser =
+ renderer_scheduler_->CreateWebScopedVirtualTimePauser();
+ virtual_time_pauser.PauseVirtualTime(true);
ignore_key_mutations_[key]++;
proxy_->SetItem(connection_id, key, value, old_value, page_url,
base::Bind(&DOMStorageCachedArea::OnSetItemComplete,
- weak_factory_.GetWeakPtr(), key));
+ weak_factory_.GetWeakPtr(), key,
+ base::Passed(std::move(virtual_time_pauser))));
return true;
}
@@ -91,11 +99,15 @@ void DOMStorageCachedArea::RemoveItem(int connection_id,
#endif
// Ignore mutations to 'key' until OnRemoveItemComplete.
+ blink::WebScopedVirtualTimePauser virtual_time_pauser =
+ renderer_scheduler_->CreateWebScopedVirtualTimePauser();
+ virtual_time_pauser.PauseVirtualTime(true);
ignore_key_mutations_[key]++;
proxy_->RemoveItem(connection_id, key,
base::NullableString16(old_value, false), page_url,
base::Bind(&DOMStorageCachedArea::OnRemoveItemComplete,
- weak_factory_.GetWeakPtr(), key));
+ weak_factory_.GetWeakPtr(), key,
+ base::Passed(std::move(virtual_time_pauser))));
}
void DOMStorageCachedArea::Clear(int connection_id, const GURL& page_url) {
@@ -104,11 +116,14 @@ void DOMStorageCachedArea::Clear(int connection_id, const GURL& page_url) {
map_ = new DOMStorageMap(kPerStorageAreaQuota);
// Ignore all mutations until OnClearComplete time.
+ blink::WebScopedVirtualTimePauser virtual_time_pauser =
+ renderer_scheduler_->CreateWebScopedVirtualTimePauser();
+ virtual_time_pauser.PauseVirtualTime(true);
ignore_all_mutations_ = true;
- proxy_->ClearArea(connection_id,
- page_url,
+ proxy_->ClearArea(connection_id, page_url,
base::Bind(&DOMStorageCachedArea::OnClearComplete,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr(),
+ base::Passed(std::move(virtual_time_pauser))));
}
void DOMStorageCachedArea::ApplyMutation(
@@ -202,7 +217,7 @@ void DOMStorageCachedArea::Prime(int connection_id) {
}
void DOMStorageCachedArea::Reset() {
- map_ = NULL;
+ map_ = nullptr;
weak_factory_.InvalidateWeakPtrs();
ignore_key_mutations_.clear();
ignore_all_mutations_ = false;
@@ -215,6 +230,7 @@ void DOMStorageCachedArea::OnLoadComplete(bool success) {
}
void DOMStorageCachedArea::OnSetItemComplete(const base::string16& key,
+ blink::WebScopedVirtualTimePauser,
bool success) {
if (!success) {
Reset();
@@ -227,8 +243,10 @@ void DOMStorageCachedArea::OnSetItemComplete(const base::string16& key,
ignore_key_mutations_.erase(found);
}
-void DOMStorageCachedArea::OnRemoveItemComplete(const base::string16& key,
- bool success) {
+void DOMStorageCachedArea::OnRemoveItemComplete(
+ const base::string16& key,
+ blink::WebScopedVirtualTimePauser,
+ bool success) {
DCHECK(success);
std::map<base::string16, int>::iterator found =
ignore_key_mutations_.find(key);
@@ -237,7 +255,8 @@ void DOMStorageCachedArea::OnRemoveItemComplete(const base::string16& key,
ignore_key_mutations_.erase(found);
}
-void DOMStorageCachedArea::OnClearComplete(bool success) {
+void DOMStorageCachedArea::OnClearComplete(blink::WebScopedVirtualTimePauser,
+ bool success) {
DCHECK(success);
DCHECK(ignore_all_mutations_);
ignore_all_mutations_ = false;
diff --git a/chromium/content/renderer/dom_storage/dom_storage_cached_area.h b/chromium/content/renderer/dom_storage/dom_storage_cached_area.h
index be365c087a4..21a9496898e 100644
--- a/chromium/content/renderer/dom_storage/dom_storage_cached_area.h
+++ b/chromium/content/renderer/dom_storage/dom_storage_cached_area.h
@@ -14,8 +14,15 @@
#include "base/memory/weak_ptr.h"
#include "base/strings/nullable_string16.h"
#include "content/common/content_export.h"
+#include "third_party/WebKit/public/platform/WebScopedVirtualTimePauser.h"
#include "url/gurl.h"
+namespace blink {
+namespace scheduler {
+class RendererScheduler;
+}
+} // namespace blink
+
namespace content {
class DOMStorageMap;
@@ -32,7 +39,8 @@ class CONTENT_EXPORT DOMStorageCachedArea
public:
DOMStorageCachedArea(int64_t namespace_id,
const GURL& origin,
- DOMStorageProxy* proxy);
+ DOMStorageProxy* proxy,
+ blink::scheduler::RendererScheduler* renderer_scheduler);
int64_t namespace_id() const { return namespace_id_; }
const GURL& origin() const { return origin_; }
@@ -72,9 +80,15 @@ class CONTENT_EXPORT DOMStorageCachedArea
// mutation events from other processes from overwriting local
// changes made after the mutation.
void OnLoadComplete(bool success);
- void OnSetItemComplete(const base::string16& key, bool success);
- void OnClearComplete(bool success);
- void OnRemoveItemComplete(const base::string16& key, bool success);
+ void OnSetItemComplete(const base::string16& key,
+ blink::WebScopedVirtualTimePauser virtual_time_pauser,
+ bool success);
+ void OnClearComplete(blink::WebScopedVirtualTimePauser virtual_time_pauser,
+ bool success);
+ void OnRemoveItemComplete(
+ const base::string16& key,
+ blink::WebScopedVirtualTimePauser virtual_time_pauser,
+ bool success);
bool should_ignore_key_mutation(const base::string16& key) const {
return ignore_key_mutations_.find(key) != ignore_key_mutations_.end();
@@ -87,6 +101,7 @@ class CONTENT_EXPORT DOMStorageCachedArea
GURL origin_;
scoped_refptr<DOMStorageMap> map_;
scoped_refptr<DOMStorageProxy> proxy_;
+ blink::scheduler::RendererScheduler* renderer_scheduler_; // NOT OWNED
base::WeakPtrFactory<DOMStorageCachedArea> weak_factory_;
};
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 46b3815e316..9b4859f48ce 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,9 +9,12 @@
#include <list>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "content/renderer/dom_storage/dom_storage_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h"
namespace content {
@@ -128,7 +131,11 @@ class DOMStorageCachedAreaTest : public testing::Test {
const base::string16 kValue;
const GURL kPageUrl;
- void SetUp() override { mock_proxy_ = new MockProxy(); }
+ void SetUp() override {
+ renderer_scheduler_ =
+ base::MakeUnique<blink::scheduler::FakeRendererScheduler>();
+ mock_proxy_ = new MockProxy();
+ }
bool IsPrimed(DOMStorageCachedArea* cached_area) {
return cached_area->map_.get();
@@ -154,13 +161,15 @@ class DOMStorageCachedAreaTest : public testing::Test {
}
protected:
+ base::MessageLoop message_loop_; // Needed to construct a RendererScheduler.
+ std::unique_ptr<blink::scheduler::RendererScheduler> renderer_scheduler_;
scoped_refptr<MockProxy> mock_proxy_;
};
TEST_F(DOMStorageCachedAreaTest, Basics) {
EXPECT_TRUE(mock_proxy_->HasOneRef());
- scoped_refptr<DOMStorageCachedArea> cached_area =
- new DOMStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_.get());
+ scoped_refptr<DOMStorageCachedArea> cached_area = new DOMStorageCachedArea(
+ kNamespaceId, kOrigin, mock_proxy_.get(), renderer_scheduler_.get());
EXPECT_EQ(kNamespaceId, cached_area->namespace_id());
EXPECT_EQ(kOrigin, cached_area->origin());
EXPECT_FALSE(mock_proxy_->HasOneRef());
@@ -184,8 +193,8 @@ TEST_F(DOMStorageCachedAreaTest, Basics) {
TEST_F(DOMStorageCachedAreaTest, Getters) {
const int kConnectionId = 7;
- scoped_refptr<DOMStorageCachedArea> cached_area =
- new DOMStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_.get());
+ scoped_refptr<DOMStorageCachedArea> cached_area = new DOMStorageCachedArea(
+ kNamespaceId, kOrigin, mock_proxy_.get(), renderer_scheduler_.get());
// GetLength, we expect to see one call to load in the proxy.
EXPECT_FALSE(IsPrimed(cached_area.get()));
@@ -219,8 +228,8 @@ TEST_F(DOMStorageCachedAreaTest, Getters) {
TEST_F(DOMStorageCachedAreaTest, Setters) {
const int kConnectionId = 7;
- scoped_refptr<DOMStorageCachedArea> cached_area =
- new DOMStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_.get());
+ scoped_refptr<DOMStorageCachedArea> cached_area = new DOMStorageCachedArea(
+ kNamespaceId, kOrigin, mock_proxy_.get(), renderer_scheduler_.get());
// SetItem, we expect a call to load followed by a call to set item
// in the proxy.
@@ -274,8 +283,8 @@ TEST_F(DOMStorageCachedAreaTest, Setters) {
TEST_F(DOMStorageCachedAreaTest, MutationsAreIgnoredUntilLoadCompletion) {
const int kConnectionId = 7;
- scoped_refptr<DOMStorageCachedArea> cached_area =
- new DOMStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_.get());
+ scoped_refptr<DOMStorageCachedArea> cached_area = new DOMStorageCachedArea(
+ kNamespaceId, kOrigin, mock_proxy_.get(), renderer_scheduler_.get());
EXPECT_TRUE(cached_area->GetItem(kConnectionId, kKey).is_null());
EXPECT_TRUE(IsPrimed(cached_area.get()));
EXPECT_TRUE(IsIgnoringAllMutations(cached_area.get()));
@@ -297,8 +306,8 @@ TEST_F(DOMStorageCachedAreaTest, MutationsAreIgnoredUntilLoadCompletion) {
TEST_F(DOMStorageCachedAreaTest, MutationsAreIgnoredUntilClearCompletion) {
const int kConnectionId = 4;
- scoped_refptr<DOMStorageCachedArea> cached_area =
- new DOMStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_.get());
+ scoped_refptr<DOMStorageCachedArea> cached_area = new DOMStorageCachedArea(
+ kNamespaceId, kOrigin, mock_proxy_.get(), renderer_scheduler_.get());
cached_area->Clear(kConnectionId, kPageUrl);
EXPECT_TRUE(IsIgnoringAllMutations(cached_area.get()));
mock_proxy_->CompleteOnePendingCallback(true);
@@ -319,8 +328,8 @@ TEST_F(DOMStorageCachedAreaTest, MutationsAreIgnoredUntilClearCompletion) {
TEST_F(DOMStorageCachedAreaTest, KeyMutationsAreIgnoredUntilCompletion) {
const int kConnectionId = 8;
- scoped_refptr<DOMStorageCachedArea> cached_area =
- new DOMStorageCachedArea(kNamespaceId, kOrigin, mock_proxy_.get());
+ scoped_refptr<DOMStorageCachedArea> cached_area = new DOMStorageCachedArea(
+ kNamespaceId, kOrigin, mock_proxy_.get(), renderer_scheduler_.get());
// SetItem
EXPECT_TRUE(cached_area->SetItem(kConnectionId, kKey, kValue, kPageUrl));
diff --git a/chromium/content/renderer/dom_storage/dom_storage_dispatcher.cc b/chromium/content/renderer/dom_storage/dom_storage_dispatcher.cc
index 9d2ec453b1a..797e8a6f626 100644
--- a/chromium/content/renderer/dom_storage/dom_storage_dispatcher.cc
+++ b/chromium/content/renderer/dom_storage/dom_storage_dispatcher.cc
@@ -36,7 +36,7 @@ class MessageThrottlingFilter : public IPC::MessageFilter {
: pending_count_(0), sender_(sender) {}
void SendThrottled(IPC::Message* message);
- void Shutdown() { sender_ = NULL; }
+ void Shutdown() { sender_ = nullptr; }
private:
~MessageThrottlingFilter() override {}
@@ -172,7 +172,7 @@ class DomStorageDispatcher::ProxyImpl : public DOMStorageProxy {
CachedAreaHolder* GetAreaHolder(const std::string& key) {
CachedAreaMap::iterator found = cached_areas_.find(key);
if (found == cached_areas_.end())
- return NULL;
+ return nullptr;
return &(found->second);
}
@@ -196,8 +196,9 @@ DOMStorageCachedArea* DomStorageDispatcher::ProxyImpl::OpenCachedArea(
++(holder->open_count_);
return holder->area_.get();
}
- scoped_refptr<DOMStorageCachedArea> area =
- new DOMStorageCachedArea(namespace_id, origin, this);
+ scoped_refptr<DOMStorageCachedArea> area = new DOMStorageCachedArea(
+ namespace_id, origin, this,
+ content::RenderThreadImpl::current()->GetRendererScheduler());
cached_areas_[key] = CachedAreaHolder(area.get(), 1);
return area.get();
}
@@ -220,7 +221,7 @@ DOMStorageCachedArea* DomStorageDispatcher::ProxyImpl::LookupCachedArea(
std::string key = GetCachedAreaKey(namespace_id, origin);
CachedAreaHolder* holder = GetAreaHolder(key);
if (!holder)
- return NULL;
+ return nullptr;
return holder->area_.get();
}
@@ -231,7 +232,7 @@ void DomStorageDispatcher::ProxyImpl::CompleteOnePendingCallback(bool success) {
void DomStorageDispatcher::ProxyImpl::Shutdown() {
throttling_filter_->Shutdown();
sender_->RemoveFilter(throttling_filter_.get());
- sender_ = NULL;
+ sender_ = nullptr;
cached_areas_.clear();
pending_callbacks_.clear();
}
@@ -315,7 +316,7 @@ bool DomStorageDispatcher::OnMessageReceived(const IPC::Message& msg) {
void DomStorageDispatcher::OnStorageEvent(
const DOMStorageMsg_Event_Params& params) {
- WebStorageAreaImpl* originating_area = NULL;
+ WebStorageAreaImpl* originating_area = nullptr;
if (params.connection_id) {
originating_area = WebStorageAreaImpl::FromConnectionId(
params.connection_id);
diff --git a/chromium/content/renderer/dom_storage/local_storage_cached_area.cc b/chromium/content/renderer/dom_storage/local_storage_cached_area.cc
index 9cb50576aa6..9fee07310fe 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_area.cc
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_area.cc
@@ -16,6 +16,7 @@
#include "content/common/storage_partition_service.mojom.h"
#include "content/renderer/dom_storage/local_storage_area.h"
#include "content/renderer/dom_storage/local_storage_cached_areas.h"
+#include "content/renderer/render_thread_impl.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebStorageEventDispatcher.h"
@@ -67,11 +68,36 @@ void UnpackSource(const std::string& source,
}
LocalStorageCachedArea::LocalStorageCachedArea(
+ int64_t namespace_id,
const url::Origin& origin,
mojom::StoragePartitionService* storage_partition_service,
- LocalStorageCachedAreas* cached_areas)
- : origin_(origin), binding_(this),
- cached_areas_(cached_areas), weak_factory_(this) {
+ LocalStorageCachedAreas* cached_areas,
+ blink::scheduler::RendererScheduler* renderer_scheduler)
+ : namespace_id_(namespace_id),
+ origin_(origin),
+ binding_(this),
+ cached_areas_(cached_areas),
+ renderer_scheduler_(renderer_scheduler),
+ weak_factory_(this) {
+ DCHECK_NE(namespace_id, kInvalidSessionStorageNamespaceId);
+ storage_partition_service->OpenSessionStorage(namespace_id, origin_,
+ mojo::MakeRequest(&leveldb_));
+ mojom::LevelDBObserverAssociatedPtrInfo ptr_info;
+ binding_.Bind(mojo::MakeRequest(&ptr_info));
+ leveldb_->AddObserver(std::move(ptr_info));
+}
+
+LocalStorageCachedArea::LocalStorageCachedArea(
+ const url::Origin& origin,
+ mojom::StoragePartitionService* storage_partition_service,
+ LocalStorageCachedAreas* cached_areas,
+ blink::scheduler::RendererScheduler* renderer_scheduler)
+ : namespace_id_(kLocalStorageNamespaceId),
+ origin_(origin),
+ binding_(this),
+ cached_areas_(cached_areas),
+ renderer_scheduler_(renderer_scheduler),
+ weak_factory_(this) {
storage_partition_service->OpenLocalStorage(origin_,
mojo::MakeRequest(&leveldb_));
mojom::LevelDBObserverAssociatedPtrInfo ptr_info;
@@ -79,9 +105,7 @@ LocalStorageCachedArea::LocalStorageCachedArea(
leveldb_->AddObserver(std::move(ptr_info));
}
-LocalStorageCachedArea::~LocalStorageCachedArea() {
- cached_areas_->CacheAreaClosed(this);
-}
+LocalStorageCachedArea::~LocalStorageCachedArea() {}
unsigned LocalStorageCachedArea::GetLength() {
EnsureLoaded();
@@ -124,10 +148,15 @@ bool LocalStorageCachedArea::SetItem(const base::string16& key,
base::Optional<std::vector<uint8_t>> optional_old_value;
if (!old_nullable_value.is_null())
optional_old_value = String16ToUint8Vector(old_nullable_value.string());
+
+ blink::WebScopedVirtualTimePauser virtual_time_pauser =
+ renderer_scheduler_->CreateWebScopedVirtualTimePauser();
+ virtual_time_pauser.PauseVirtualTime(true);
leveldb_->Put(String16ToUint8Vector(key), String16ToUint8Vector(value),
optional_old_value, PackSource(page_url, storage_area_id),
base::BindOnce(&LocalStorageCachedArea::OnSetItemComplete,
- weak_factory_.GetWeakPtr(), key));
+ weak_factory_.GetWeakPtr(), key,
+ std::move(virtual_time_pauser)));
return true;
}
@@ -149,10 +178,15 @@ void LocalStorageCachedArea::RemoveItem(const base::string16& key,
base::Optional<std::vector<uint8_t>> optional_old_value;
if (should_send_old_value_on_mutations_)
optional_old_value = String16ToUint8Vector(old_value);
+
+ blink::WebScopedVirtualTimePauser virtual_time_pauser =
+ renderer_scheduler_->CreateWebScopedVirtualTimePauser();
+ virtual_time_pauser.PauseVirtualTime(true);
leveldb_->Delete(String16ToUint8Vector(key), optional_old_value,
PackSource(page_url, storage_area_id),
base::BindOnce(&LocalStorageCachedArea::OnRemoveItemComplete,
- weak_factory_.GetWeakPtr(), key));
+ weak_factory_.GetWeakPtr(), key,
+ std::move(virtual_time_pauser)));
}
void LocalStorageCachedArea::Clear(const GURL& page_url,
@@ -161,9 +195,14 @@ void LocalStorageCachedArea::Clear(const GURL& page_url,
Reset();
map_ = new DOMStorageMap(kPerStorageAreaQuota);
ignore_all_mutations_ = true;
+
+ blink::WebScopedVirtualTimePauser virtual_time_pauser =
+ renderer_scheduler_->CreateWebScopedVirtualTimePauser();
+ virtual_time_pauser.PauseVirtualTime(true);
leveldb_->DeleteAll(PackSource(page_url, storage_area_id),
base::BindOnce(&LocalStorageCachedArea::OnClearComplete,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr(),
+ std::move(virtual_time_pauser)));
}
void LocalStorageCachedArea::AreaCreated(LocalStorageArea* area) {
@@ -389,8 +428,10 @@ void LocalStorageCachedArea::EnsureLoaded() {
}
}
-void LocalStorageCachedArea::OnSetItemComplete(const base::string16& key,
- bool success) {
+void LocalStorageCachedArea::OnSetItemComplete(
+ const base::string16& key,
+ blink::WebScopedVirtualTimePauser,
+ bool success) {
if (!success) {
Reset();
return;
@@ -403,7 +444,9 @@ void LocalStorageCachedArea::OnSetItemComplete(const base::string16& key,
}
void LocalStorageCachedArea::OnRemoveItemComplete(
- const base::string16& key, bool success) {
+ const base::string16& key,
+ blink::WebScopedVirtualTimePauser,
+ bool success) {
DCHECK(success);
auto found = ignore_key_mutations_.find(key);
DCHECK(found != ignore_key_mutations_.end());
@@ -411,7 +454,8 @@ void LocalStorageCachedArea::OnRemoveItemComplete(
ignore_key_mutations_.erase(found);
}
-void LocalStorageCachedArea::OnClearComplete(bool success) {
+void LocalStorageCachedArea::OnClearComplete(blink::WebScopedVirtualTimePauser,
+ bool success) {
DCHECK(success);
DCHECK(ignore_all_mutations_);
ignore_all_mutations_ = false;
@@ -427,7 +471,7 @@ void LocalStorageCachedArea::OnGetAllComplete(bool success) {
}
void LocalStorageCachedArea::Reset() {
- map_ = NULL;
+ map_ = nullptr;
ignore_key_mutations_.clear();
ignore_all_mutations_ = false;
weak_factory_.InvalidateWeakPtrs();
diff --git a/chromium/content/renderer/dom_storage/local_storage_cached_area.h b/chromium/content/renderer/dom_storage/local_storage_cached_area.h
index a28121d146f..dc19eff66d9 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_area.h
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_area.h
@@ -11,13 +11,20 @@
#include "base/memory/ref_counted.h"
#include "base/strings/nullable_string16.h"
#include "content/common/content_export.h"
+#include "content/common/dom_storage/dom_storage_map.h"
#include "content/common/leveldb_wrapper.mojom.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "third_party/WebKit/public/platform/WebScopedVirtualTimePauser.h"
#include "url/gurl.h"
#include "url/origin.h"
+namespace blink {
+namespace scheduler {
+class RendererScheduler;
+}
+} // namespace blink
+
namespace content {
-class DOMStorageMap;
class LocalStorageArea;
class LocalStorageCachedAreas;
@@ -33,14 +40,22 @@ class StoragePartitionService;
// callbacks.
// There is one LocalStorageCachedArea for potentially many LocalStorageArea
// objects.
+// TODO(dmurph): Rename to remove LocalStorage.
class CONTENT_EXPORT LocalStorageCachedArea
: public mojom::LevelDBObserver,
public base::RefCounted<LocalStorageCachedArea> {
public:
LocalStorageCachedArea(
+ int64_t namespace_id,
+ const url::Origin& origin,
+ mojom::StoragePartitionService* storage_partition_service,
+ LocalStorageCachedAreas* cached_areas,
+ blink::scheduler::RendererScheduler* renderer_schedule);
+ LocalStorageCachedArea(
const url::Origin& origin,
mojom::StoragePartitionService* storage_partition_service,
- LocalStorageCachedAreas* cached_areas);
+ LocalStorageCachedAreas* cached_areas,
+ blink::scheduler::RendererScheduler* renderer_schedule);
// These correspond to blink::WebStorageArea.
unsigned GetLength();
@@ -60,8 +75,11 @@ class CONTENT_EXPORT LocalStorageCachedArea
void AreaCreated(LocalStorageArea* area);
void AreaDestroyed(LocalStorageArea* area);
+ int64_t namespace_id() { return namespace_id_; }
const url::Origin& origin() { return origin_; }
+ size_t memory_used() const { return map_ ? map_->memory_used() : 0; }
+
private:
friend class base::RefCounted<LocalStorageCachedArea>;
~LocalStorageCachedArea() override;
@@ -97,14 +115,21 @@ class CONTENT_EXPORT LocalStorageCachedArea
// fetched already.
void EnsureLoaded();
- void OnSetItemComplete(const base::string16& key, bool success);
- void OnRemoveItemComplete(const base::string16& key, bool success);
- void OnClearComplete(bool success);
+ void OnSetItemComplete(const base::string16& key,
+ blink::WebScopedVirtualTimePauser virtual_time_pauser,
+ bool success);
+ void OnRemoveItemComplete(
+ const base::string16& key,
+ blink::WebScopedVirtualTimePauser virtual_time_pauser,
+ bool success);
+ void OnClearComplete(blink::WebScopedVirtualTimePauser virtual_time_pauser,
+ bool success);
void OnGetAllComplete(bool success);
// Resets the object back to its newly constructed state.
void Reset();
+ int64_t namespace_id_;
url::Origin origin_;
scoped_refptr<DOMStorageMap> map_;
std::map<base::string16, int> ignore_key_mutations_;
@@ -115,6 +140,7 @@ class CONTENT_EXPORT LocalStorageCachedArea
mojo::AssociatedBinding<mojom::LevelDBObserver> binding_;
LocalStorageCachedAreas* cached_areas_;
std::map<std::string, LocalStorageArea*> areas_;
+ blink::scheduler::RendererScheduler* renderer_scheduler_; // NOT OWNED
base::WeakPtrFactory<LocalStorageCachedArea> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(LocalStorageCachedArea);
diff --git a/chromium/content/renderer/dom_storage/local_storage_cached_area_unittest.cc b/chromium/content/renderer/dom_storage/local_storage_cached_area_unittest.cc
index d3b36a61a0d..072ce06403c 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_area_unittest.cc
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_area_unittest.cc
@@ -11,135 +11,25 @@
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/leveldb_wrapper.mojom.h"
-#include "content/common/storage_partition_service.mojom.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/renderer/dom_storage/local_storage_cached_areas.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "content/renderer/dom_storage/mock_leveldb_wrapper.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h"
namespace content {
-namespace {
-
-class MockLevelDBWrapper : public mojom::StoragePartitionService,
- public mojom::LevelDBWrapper {
- public:
- // StoragePartitionService implementation:
- void OpenLocalStorage(const url::Origin& origin,
- mojom::LevelDBWrapperRequest database) override {
- bindings_.AddBinding(this, std::move(database));
- }
-
- // LevelDBWrapper implementation:
- void AddObserver(mojom::LevelDBObserverAssociatedPtrInfo observer) override {}
-
- void Put(const std::vector<uint8_t>& key,
- const std::vector<uint8_t>& value,
- const base::Optional<std::vector<uint8_t>>& client_old_value,
- const std::string& source,
- PutCallback callback) override {
- observed_put_ = true;
- observed_key_ = key;
- observed_value_ = value;
- observed_source_ = source;
- pending_callbacks_.push_back(std::move(callback));
- }
-
- void Delete(const std::vector<uint8_t>& key,
- const base::Optional<std::vector<uint8_t>>& client_old_value,
- const std::string& source,
- DeleteCallback callback) override {
- observed_delete_ = true;
- observed_key_ = key;
- observed_source_ = source;
- pending_callbacks_.push_back(std::move(callback));
- }
-
- void DeleteAll(const std::string& source,
- DeleteAllCallback callback) override {
- observed_delete_all_ = true;
- observed_source_ = source;
- pending_callbacks_.push_back(std::move(callback));
- }
-
- void Get(const std::vector<uint8_t>& key, GetCallback callback) override {}
-
- void GetAll(
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo complete_callback,
- GetAllCallback callback) override {
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtr complete_ptr;
- complete_ptr.Bind(std::move(complete_callback));
- pending_callbacks_.push_back(
- base::BindOnce(&mojom::LevelDBWrapperGetAllCallback::Complete,
- std::move(complete_ptr)));
-
- observed_get_all_ = true;
- std::vector<mojom::KeyValuePtr> all;
- for (const auto& it : get_all_return_values_) {
- mojom::KeyValuePtr kv = mojom::KeyValue::New();
- kv->key = it.first;
- kv->value = it.second;
- all.push_back(std::move(kv));
- }
- std::move(callback).Run(leveldb::mojom::DatabaseError::OK, std::move(all));
- }
-
- // Methods and members for use by test fixtures.
- bool HasBindings() { return !bindings_.empty(); }
-
- void ResetObservations() {
- observed_get_all_ = false;
- observed_put_ = false;
- observed_delete_ = false;
- observed_delete_all_ = false;
- observed_key_.clear();
- observed_value_.clear();
- observed_source_.clear();
- }
-
- void CompleteAllPendingCallbacks() {
- while (!pending_callbacks_.empty())
- CompleteOnePendingCallback(true);
- }
-
- void CompleteOnePendingCallback(bool success) {
- ASSERT_TRUE(!pending_callbacks_.empty());
- std::move(pending_callbacks_.front()).Run(success);
- pending_callbacks_.pop_front();
- }
-
- void Flush() { bindings_.FlushForTesting(); }
-
- void CloseAllBindings() { bindings_.CloseAllBindings(); }
-
- using ResultCallback = base::OnceCallback<void(bool)>;
- std::list<ResultCallback> pending_callbacks_;
- bool observed_get_all_ = false;
- bool observed_put_ = false;
- bool observed_delete_ = false;
- bool observed_delete_all_ = false;
- std::vector<uint8_t> observed_key_;
- std::vector<uint8_t> observed_value_;
- std::string observed_source_;
-
- std::map<std::vector<uint8_t>, std::vector<uint8_t>> get_all_return_values_;
-
- private:
- mojo::BindingSet<mojom::LevelDBWrapper> bindings_;
-};
-
-} // namespace
-
class LocalStorageCachedAreaTest : public testing::Test {
public:
LocalStorageCachedAreaTest()
- : kOrigin(GURL("http://dom_storage/")),
+ : kOrigin(url::Origin::Create(GURL("http://dom_storage/"))),
kKey(base::ASCIIToUTF16("key")),
kValue(base::ASCIIToUTF16("value")),
kPageUrl("http://dom_storage/page"),
kStorageAreaId("7"),
kSource(kPageUrl.spec() + "\n" + kStorageAreaId),
- cached_areas_(&mock_leveldb_wrapper_) {}
+ renderer_scheduler_(new blink::scheduler::FakeRendererScheduler()),
+ cached_areas_(&mock_leveldb_wrapper_, renderer_scheduler_.get()) {}
const url::Origin kOrigin;
const base::string16 kKey;
@@ -185,6 +75,7 @@ class LocalStorageCachedAreaTest : public testing::Test {
protected:
TestBrowserThreadBundle test_browser_thread_bundle_;
MockLevelDBWrapper mock_leveldb_wrapper_;
+ std::unique_ptr<blink::scheduler::RendererScheduler> renderer_scheduler_;
LocalStorageCachedAreas cached_areas_;
};
@@ -215,8 +106,8 @@ TEST_F(LocalStorageCachedAreaTest, Getters) {
EXPECT_FALSE(IsCacheLoaded(cached_area.get()));
EXPECT_EQ(0u, cached_area->GetLength());
EXPECT_TRUE(IsCacheLoaded(cached_area.get()));
- EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all_);
- EXPECT_EQ(1u, mock_leveldb_wrapper_.pending_callbacks_.size());
+ EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all());
+ EXPECT_EQ(1u, mock_leveldb_wrapper_.pending_callbacks().size());
EXPECT_TRUE(IsIgnoringAllMutations(cached_area.get()));
mock_leveldb_wrapper_.CompleteAllPendingCallbacks();
mock_leveldb_wrapper_.Flush();
@@ -227,16 +118,16 @@ TEST_F(LocalStorageCachedAreaTest, Getters) {
EXPECT_FALSE(IsCacheLoaded(cached_area.get()));
EXPECT_TRUE(cached_area->GetKey(2).is_null());
EXPECT_TRUE(IsCacheLoaded(cached_area.get()));
- EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all_);
- EXPECT_EQ(1u, mock_leveldb_wrapper_.pending_callbacks_.size());
+ EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all());
+ EXPECT_EQ(1u, mock_leveldb_wrapper_.pending_callbacks().size());
// GetItem, ditto.
ResetAll(cached_area.get());
EXPECT_FALSE(IsCacheLoaded(cached_area.get()));
EXPECT_TRUE(cached_area->GetItem(kKey).is_null());
EXPECT_TRUE(IsCacheLoaded(cached_area.get()));
- EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all_);
- EXPECT_EQ(1u, mock_leveldb_wrapper_.pending_callbacks_.size());
+ EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all());
+ EXPECT_EQ(1u, mock_leveldb_wrapper_.pending_callbacks().size());
}
TEST_F(LocalStorageCachedAreaTest, Setters) {
@@ -248,13 +139,13 @@ TEST_F(LocalStorageCachedAreaTest, Setters) {
EXPECT_TRUE(cached_area->SetItem(kKey, kValue, kPageUrl, kStorageAreaId));
mock_leveldb_wrapper_.Flush();
EXPECT_TRUE(IsCacheLoaded(cached_area.get()));
- EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all_);
- EXPECT_TRUE(mock_leveldb_wrapper_.observed_put_);
- EXPECT_EQ(kSource, mock_leveldb_wrapper_.observed_source_);
- EXPECT_EQ(String16ToUint8Vector(kKey), mock_leveldb_wrapper_.observed_key_);
+ EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all());
+ EXPECT_TRUE(mock_leveldb_wrapper_.observed_put());
+ EXPECT_EQ(kSource, mock_leveldb_wrapper_.observed_source());
+ EXPECT_EQ(String16ToUint8Vector(kKey), mock_leveldb_wrapper_.observed_key());
EXPECT_EQ(String16ToUint8Vector(kValue),
- mock_leveldb_wrapper_.observed_value_);
- EXPECT_EQ(2u, mock_leveldb_wrapper_.pending_callbacks_.size());
+ mock_leveldb_wrapper_.observed_value());
+ EXPECT_EQ(2u, mock_leveldb_wrapper_.pending_callbacks().size());
// Clear, we expect a just the one call to clear in the db since
// there's no need to load the data prior to deleting it.
@@ -263,9 +154,9 @@ TEST_F(LocalStorageCachedAreaTest, Setters) {
cached_area->Clear(kPageUrl, kStorageAreaId);
mock_leveldb_wrapper_.Flush();
EXPECT_TRUE(IsCacheLoaded(cached_area.get()));
- EXPECT_TRUE(mock_leveldb_wrapper_.observed_delete_all_);
- EXPECT_EQ(kSource, mock_leveldb_wrapper_.observed_source_);
- EXPECT_EQ(1u, mock_leveldb_wrapper_.pending_callbacks_.size());
+ EXPECT_TRUE(mock_leveldb_wrapper_.observed_delete_all());
+ EXPECT_EQ(kSource, mock_leveldb_wrapper_.observed_source());
+ EXPECT_EQ(1u, mock_leveldb_wrapper_.pending_callbacks().size());
// RemoveItem with nothing to remove, expect just one call to load.
ResetAll(cached_area.get());
@@ -273,24 +164,25 @@ TEST_F(LocalStorageCachedAreaTest, Setters) {
cached_area->RemoveItem(kKey, kPageUrl, kStorageAreaId);
mock_leveldb_wrapper_.Flush();
EXPECT_TRUE(IsCacheLoaded(cached_area.get()));
- EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all_);
- EXPECT_FALSE(mock_leveldb_wrapper_.observed_delete_);
- EXPECT_EQ(1u, mock_leveldb_wrapper_.pending_callbacks_.size());
+ EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all());
+ EXPECT_FALSE(mock_leveldb_wrapper_.observed_delete());
+ EXPECT_EQ(1u, mock_leveldb_wrapper_.pending_callbacks().size());
// RemoveItem with something to remove, expect a call to load followed
// by a call to remove.
ResetAll(cached_area.get());
- mock_leveldb_wrapper_.get_all_return_values_[String16ToUint8Vector(kKey)] =
+ mock_leveldb_wrapper_
+ .mutable_get_all_return_values()[String16ToUint8Vector(kKey)] =
String16ToUint8Vector(kValue);
EXPECT_FALSE(IsCacheLoaded(cached_area.get()));
cached_area->RemoveItem(kKey, kPageUrl, kStorageAreaId);
mock_leveldb_wrapper_.Flush();
EXPECT_TRUE(IsCacheLoaded(cached_area.get()));
- EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all_);
- EXPECT_TRUE(mock_leveldb_wrapper_.observed_delete_);
- EXPECT_EQ(kSource, mock_leveldb_wrapper_.observed_source_);
- EXPECT_EQ(String16ToUint8Vector(kKey), mock_leveldb_wrapper_.observed_key_);
- EXPECT_EQ(2u, mock_leveldb_wrapper_.pending_callbacks_.size());
+ EXPECT_TRUE(mock_leveldb_wrapper_.observed_get_all());
+ EXPECT_TRUE(mock_leveldb_wrapper_.observed_delete());
+ EXPECT_EQ(kSource, mock_leveldb_wrapper_.observed_source());
+ EXPECT_EQ(String16ToUint8Vector(kKey), mock_leveldb_wrapper_.observed_key());
+ EXPECT_EQ(2u, mock_leveldb_wrapper_.pending_callbacks().size());
}
TEST_F(LocalStorageCachedAreaTest, MutationsAreIgnoredUntilLoadCompletion) {
@@ -411,7 +303,8 @@ TEST_F(LocalStorageCachedAreaTest, BrowserDisconnect) {
cached_areas_.GetCachedArea(kOrigin);
// GetLength to prime the cache.
- mock_leveldb_wrapper_.get_all_return_values_[String16ToUint8Vector(kKey)] =
+ mock_leveldb_wrapper_
+ .mutable_get_all_return_values()[String16ToUint8Vector(kKey)] =
String16ToUint8Vector(kValue);
EXPECT_EQ(1u, cached_area->GetLength());
EXPECT_TRUE(IsCacheLoaded(cached_area.get()));
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 6c9840143fa..a9e4728a4c6 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_areas.cc
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_areas.cc
@@ -4,31 +4,107 @@
#include "content/renderer/dom_storage/local_storage_cached_areas.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/sys_info.h"
+#include "content/common/dom_storage/dom_storage_types.h"
#include "content/renderer/dom_storage/local_storage_cached_area.h"
+#include "content/renderer/render_thread_impl.h"
namespace content {
+namespace {
+const size_t kTotalCacheLimitInBytesLowEnd = 1 * 1024 * 1024;
+const size_t kTotalCacheLimitInBytes = 5 * 1024 * 1024;
+} // namespace
LocalStorageCachedAreas::LocalStorageCachedAreas(
- mojom::StoragePartitionService* storage_partition_service)
- : storage_partition_service_(storage_partition_service) {}
+ mojom::StoragePartitionService* storage_partition_service,
+ blink::scheduler::RendererScheduler* renderer_scheduler)
+ : storage_partition_service_(storage_partition_service),
+ total_cache_limit_(base::SysInfo::IsLowEndDevice()
+ ? kTotalCacheLimitInBytesLowEnd
+ : kTotalCacheLimitInBytes),
+ renderer_scheduler_(renderer_scheduler) {}
-LocalStorageCachedAreas::~LocalStorageCachedAreas() {
-}
+LocalStorageCachedAreas::~LocalStorageCachedAreas() {}
scoped_refptr<LocalStorageCachedArea> LocalStorageCachedAreas::GetCachedArea(
const url::Origin& origin) {
- if (cached_areas_.find(origin) == cached_areas_.end()) {
- cached_areas_[origin] = new LocalStorageCachedArea(
- origin, storage_partition_service_, this);
- }
+ return GetCachedArea(kLocalStorageNamespaceId, origin, renderer_scheduler_);
+}
+
+scoped_refptr<LocalStorageCachedArea>
+LocalStorageCachedAreas::GetSessionStorageArea(int64_t namespace_id,
+ const url::Origin& origin) {
+ DCHECK_NE(kLocalStorageNamespaceId, kInvalidSessionStorageNamespaceId);
+ return GetCachedArea(namespace_id, origin, renderer_scheduler_);
+}
+
+size_t LocalStorageCachedAreas::TotalCacheSize() const {
+ size_t total = 0;
+ for (const auto& it : cached_areas_)
+ total += it.second.get()->memory_used();
+ return total;
+}
- return base::WrapRefCounted(cached_areas_[origin]);
+void LocalStorageCachedAreas::ClearAreasIfNeeded() {
+ if (TotalCacheSize() < total_cache_limit_)
+ return;
+ auto it = cached_areas_.begin();
+ while (it != cached_areas_.end()) {
+ if (it->second->HasOneRef())
+ it = cached_areas_.erase(it);
+ else
+ ++it;
+ }
}
-void LocalStorageCachedAreas::CacheAreaClosed(
- LocalStorageCachedArea* cached_area) {
- DCHECK(cached_areas_.find(cached_area->origin()) != cached_areas_.end());
- cached_areas_.erase(cached_area->origin());
+scoped_refptr<LocalStorageCachedArea> LocalStorageCachedAreas::GetCachedArea(
+ int64_t namespace_id,
+ const url::Origin& origin,
+ blink::scheduler::RendererScheduler* scheduler) {
+ AreaKey key(namespace_id, origin);
+
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum class CacheMetrics {
+ kMiss = 0, // Area not in cache.
+ kHit = 1, // Area with refcount = 0 loaded from cache.
+ kUnused = 2, // Cache was not used. Area had refcount > 0.
+ kMaxValue
+ };
+
+ auto it = cached_areas_.find(key);
+ CacheMetrics metric;
+ if (it != cached_areas_.end()) {
+ if (it->second->HasOneRef()) {
+ metric = CacheMetrics::kHit;
+ } else {
+ metric = CacheMetrics::kUnused;
+ }
+ } else {
+ metric = CacheMetrics::kMiss;
+ }
+ if (namespace_id == kLocalStorageNamespaceId) {
+ UMA_HISTOGRAM_ENUMERATION("LocalStorage.RendererAreaCacheHit", metric,
+ CacheMetrics::kMaxValue);
+ } else {
+ LOCAL_HISTOGRAM_ENUMERATION("SessionStorage.RendererAreaCacheHit", metric,
+ CacheMetrics::kMaxValue);
+ }
+
+ if (it == cached_areas_.end()) {
+ ClearAreasIfNeeded();
+ scoped_refptr<LocalStorageCachedArea> area;
+ if (namespace_id == kLocalStorageNamespaceId) {
+ area = base::MakeRefCounted<LocalStorageCachedArea>(
+ origin, storage_partition_service_, this, scheduler);
+ } else {
+ area = base::MakeRefCounted<LocalStorageCachedArea>(
+ namespace_id, origin, storage_partition_service_, this, scheduler);
+ }
+ it = cached_areas_.emplace(key, std::move(area)).first;
+ }
+ return it->second;
}
} // namespace content
diff --git a/chromium/content/renderer/dom_storage/local_storage_cached_areas.h b/chromium/content/renderer/dom_storage/local_storage_cached_areas.h
index ae9ee99093d..37e7ef815d4 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_areas.h
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_areas.h
@@ -12,6 +12,12 @@
#include "content/common/content_export.h"
#include "url/origin.h"
+namespace blink {
+namespace scheduler {
+class RendererScheduler;
+}
+} // namespace blink
+
namespace content {
class LocalStorageCachedArea;
@@ -23,25 +29,44 @@ class StoragePartitionService;
// needed because we can have n LocalStorageArea objects for the same origin but
// we want just one LocalStorageCachedArea to service them (no point in having
// multiple caches of the same data in the same process).
+// TODO(dmurph): Rename to remove LocalStorage.
class CONTENT_EXPORT LocalStorageCachedAreas {
public:
- explicit LocalStorageCachedAreas(
- mojom::StoragePartitionService* storage_partition_service);
+ LocalStorageCachedAreas(
+ mojom::StoragePartitionService* storage_partition_service,
+ blink::scheduler::RendererScheduler* renderer_schedule);
~LocalStorageCachedAreas();
// Returns, creating if necessary, a cached storage area for the given origin.
scoped_refptr<LocalStorageCachedArea>
GetCachedArea(const url::Origin& origin);
- // Called by LocalStorageCachedArea on destruction.
- void CacheAreaClosed(LocalStorageCachedArea* cached_area);
+ scoped_refptr<LocalStorageCachedArea> GetSessionStorageArea(
+ int64_t namespace_id,
+ const url::Origin& origin);
+
+ size_t TotalCacheSize() const;
+
+ void set_cache_limit_for_testing(size_t limit) { total_cache_limit_ = limit; }
private:
+ void ClearAreasIfNeeded();
+
+ scoped_refptr<LocalStorageCachedArea> GetCachedArea(
+ int64_t namespace_id,
+ const url::Origin& origin,
+ blink::scheduler::RendererScheduler* scheduler);
+
mojom::StoragePartitionService* const storage_partition_service_;
- // Maps from an origin to its LocalStorageCachedArea object. The object owns
- // itself.
- std::map<url::Origin, LocalStorageCachedArea*> cached_areas_;
+ // Maps from a namespace + origin to its LocalStorageCachedArea object. When
+ // this map is the only reference to the object, it can be deleted by the
+ // cache.
+ using AreaKey = std::pair<int64_t, url::Origin>;
+ std::map<AreaKey, scoped_refptr<LocalStorageCachedArea>> cached_areas_;
+ size_t total_cache_limit_;
+
+ blink::scheduler::RendererScheduler* renderer_scheduler_; // NOT OWNED
DISALLOW_COPY_AND_ASSIGN(LocalStorageCachedAreas);
};
diff --git a/chromium/content/renderer/dom_storage/local_storage_cached_areas_unittest.cc b/chromium/content/renderer/dom_storage/local_storage_cached_areas_unittest.cc
new file mode 100644
index 00000000000..05c58668fbd
--- /dev/null
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_areas_unittest.cc
@@ -0,0 +1,59 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/dom_storage/local_storage_cached_areas.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
+#include "content/renderer/dom_storage/local_storage_cached_area.h"
+#include "content/renderer/dom_storage/mock_leveldb_wrapper.h"
+#include "third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h"
+
+namespace content {
+
+TEST(LocalStorageCachedAreasTest, CacheLimit) {
+ base::test::ScopedTaskEnvironment scoped_task_environment;
+ const url::Origin kOrigin = url::Origin::Create(GURL("http://dom_storage1/"));
+ const url::Origin kOrigin2 =
+ url::Origin::Create(GURL("http://dom_storage2/"));
+ const url::Origin kOrigin3 =
+ url::Origin::Create(GURL("http://dom_storage3/"));
+ const base::string16 kKey = base::ASCIIToUTF16("key");
+ const base::string16 kValue = base::ASCIIToUTF16("value");
+ const GURL kPageUrl("http://dom_storage/page");
+ const std::string kStorageAreaId("7");
+ const size_t kCacheLimit = 100;
+
+ blink::scheduler::FakeRendererScheduler renderer_scheduler;
+
+ MockLevelDBWrapper mock_leveldb_wrapper;
+ LocalStorageCachedAreas cached_areas(&mock_leveldb_wrapper,
+ &renderer_scheduler);
+ cached_areas.set_cache_limit_for_testing(kCacheLimit);
+
+ scoped_refptr<LocalStorageCachedArea> cached_area1 =
+ cached_areas.GetCachedArea(kOrigin);
+ cached_area1->SetItem(kKey, kValue, kPageUrl, kStorageAreaId);
+ const LocalStorageCachedArea* area1_ptr = cached_area1.get();
+ size_t expected_total = (kKey.size() + kValue.size()) * sizeof(base::char16);
+ EXPECT_EQ(expected_total, cached_area1->memory_used());
+ EXPECT_EQ(expected_total, cached_areas.TotalCacheSize());
+ cached_area1 = nullptr;
+
+ scoped_refptr<LocalStorageCachedArea> cached_area2 =
+ cached_areas.GetCachedArea(kOrigin2);
+ cached_area2->SetItem(kKey, kValue, kPageUrl, kStorageAreaId);
+ // Area for kOrigin should still be alive.
+ EXPECT_EQ(2 * cached_area2->memory_used(), cached_areas.TotalCacheSize());
+ EXPECT_EQ(area1_ptr, cached_areas.GetCachedArea(kOrigin));
+
+ base::string16 long_value(kCacheLimit, 'a');
+ cached_area2->SetItem(kKey, long_value, kPageUrl, kStorageAreaId);
+ // Cache is cleared when a new area is opened.
+ scoped_refptr<LocalStorageCachedArea> cached_area3 =
+ cached_areas.GetCachedArea(kOrigin3);
+ EXPECT_EQ(cached_area2->memory_used(), cached_areas.TotalCacheSize());
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.cc b/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.cc
new file mode 100644
index 00000000000..8addc7733f6
--- /dev/null
+++ b/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.cc
@@ -0,0 +1,81 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/dom_storage/mock_leveldb_wrapper.h"
+
+namespace content {
+
+MockLevelDBWrapper::MockLevelDBWrapper() {}
+MockLevelDBWrapper::~MockLevelDBWrapper() {}
+
+void MockLevelDBWrapper::OpenLocalStorage(
+ const url::Origin& origin,
+ mojom::LevelDBWrapperRequest database) {
+ bindings_.AddBinding(this, std::move(database));
+}
+
+void MockLevelDBWrapper::OpenSessionStorage(
+ int64_t namespace_id,
+ const url::Origin& origin,
+ mojom::LevelDBWrapperRequest database) {
+ bindings_.AddBinding(this, std::move(database));
+}
+
+void MockLevelDBWrapper::AddObserver(
+ mojom::LevelDBObserverAssociatedPtrInfo observer) {}
+
+void MockLevelDBWrapper::Put(
+ const std::vector<uint8_t>& key,
+ const std::vector<uint8_t>& value,
+ const base::Optional<std::vector<uint8_t>>& client_old_value,
+ const std::string& source,
+ PutCallback callback) {
+ observed_put_ = true;
+ observed_key_ = key;
+ observed_value_ = value;
+ observed_source_ = source;
+ pending_callbacks_.push_back(std::move(callback));
+}
+
+void MockLevelDBWrapper::Delete(
+ const std::vector<uint8_t>& key,
+ const base::Optional<std::vector<uint8_t>>& client_old_value,
+ const std::string& source,
+ DeleteCallback callback) {
+ observed_delete_ = true;
+ observed_key_ = key;
+ observed_source_ = source;
+ pending_callbacks_.push_back(std::move(callback));
+}
+
+void MockLevelDBWrapper::DeleteAll(const std::string& source,
+ DeleteAllCallback callback) {
+ observed_delete_all_ = true;
+ observed_source_ = source;
+ pending_callbacks_.push_back(std::move(callback));
+}
+
+void MockLevelDBWrapper::Get(const std::vector<uint8_t>& key,
+ GetCallback callback) {}
+
+void MockLevelDBWrapper::GetAll(
+ mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo complete_callback,
+ GetAllCallback callback) {
+ mojom::LevelDBWrapperGetAllCallbackAssociatedPtr complete_ptr;
+ complete_ptr.Bind(std::move(complete_callback));
+ pending_callbacks_.push_back(base::BindOnce(
+ &mojom::LevelDBWrapperGetAllCallback::Complete, std::move(complete_ptr)));
+
+ observed_get_all_ = true;
+ std::vector<mojom::KeyValuePtr> all;
+ for (const auto& it : get_all_return_values_) {
+ mojom::KeyValuePtr kv = mojom::KeyValue::New();
+ kv->key = it.first;
+ kv->value = it.second;
+ all.push_back(std::move(kv));
+ }
+ std::move(callback).Run(leveldb::mojom::DatabaseError::OK, std::move(all));
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.h b/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.h
new file mode 100644
index 00000000000..95293cf4ba4
--- /dev/null
+++ b/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.h
@@ -0,0 +1,117 @@
+// Copyright 2017 The Chromium Authors. 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_DOM_STORAGE_MOCK_LEVELDB_WRAPPER_H
+#define CONTENT_RENDERER_DOM_STORAGE_MOCK_LEVELDB_WRAPPER_H
+
+#include "content/common/leveldb_wrapper.mojom.h"
+#include "content/common/storage_partition_service.mojom.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+// Mock LevelDBWrapper that records all read and write events. It also
+// implements a mock StoragePartitionService.
+class MockLevelDBWrapper : public mojom::StoragePartitionService,
+ public mojom::LevelDBWrapper {
+ public:
+ using ResultCallback = base::OnceCallback<void(bool)>;
+
+ MockLevelDBWrapper();
+ ~MockLevelDBWrapper() override;
+
+ // StoragePartitionService implementation:
+ void OpenLocalStorage(const url::Origin& origin,
+ mojom::LevelDBWrapperRequest database) override;
+ void OpenSessionStorage(int64_t namespace_id,
+ const url::Origin& origin,
+ mojom::LevelDBWrapperRequest database) override;
+
+ // LevelDBWrapper implementation:
+ void AddObserver(mojom::LevelDBObserverAssociatedPtrInfo observer) override;
+
+ void Put(const std::vector<uint8_t>& key,
+ const std::vector<uint8_t>& value,
+ const base::Optional<std::vector<uint8_t>>& client_old_value,
+ const std::string& source,
+ PutCallback callback) override;
+
+ void Delete(const std::vector<uint8_t>& key,
+ const base::Optional<std::vector<uint8_t>>& client_old_value,
+ const std::string& source,
+ DeleteCallback callback) override;
+
+ void DeleteAll(const std::string& source,
+ DeleteAllCallback callback) override;
+
+ void Get(const std::vector<uint8_t>& key, GetCallback callback) override;
+
+ void GetAll(
+ mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo complete_callback,
+ GetAllCallback callback) override;
+
+ // Methods and members for use by test fixtures.
+ bool HasBindings() { return !bindings_.empty(); }
+
+ void ResetObservations() {
+ observed_get_all_ = false;
+ observed_put_ = false;
+ observed_delete_ = false;
+ observed_delete_all_ = false;
+ observed_key_.clear();
+ observed_value_.clear();
+ observed_source_.clear();
+ }
+
+ void CompleteAllPendingCallbacks() {
+ while (!pending_callbacks_.empty())
+ CompleteOnePendingCallback(true);
+ }
+
+ void CompleteOnePendingCallback(bool success) {
+ ASSERT_TRUE(!pending_callbacks_.empty());
+ std::move(pending_callbacks_.front()).Run(success);
+ pending_callbacks_.pop_front();
+ }
+
+ void Flush() { bindings_.FlushForTesting(); }
+
+ void CloseAllBindings() { bindings_.CloseAllBindings(); }
+
+ const std::list<ResultCallback>& pending_callbacks() const {
+ return pending_callbacks_;
+ }
+
+ bool observed_get_all() const { return observed_get_all_; }
+ bool observed_put() const { return observed_put_; }
+ bool observed_delete() const { return observed_delete_; }
+ bool observed_delete_all() const { return observed_delete_all_; }
+ const std::vector<uint8_t>& observed_key() const { return observed_key_; }
+ const std::vector<uint8_t>& observed_value() const { return observed_value_; }
+ const std::string& observed_source() const { return observed_source_; }
+
+ std::map<std::vector<uint8_t>, std::vector<uint8_t>>&
+ mutable_get_all_return_values() {
+ return get_all_return_values_;
+ }
+
+ private:
+ std::list<ResultCallback> pending_callbacks_;
+ bool observed_get_all_ = false;
+ bool observed_put_ = false;
+ bool observed_delete_ = false;
+ bool observed_delete_all_ = false;
+ std::vector<uint8_t> observed_key_;
+ std::vector<uint8_t> observed_value_;
+ std::string observed_source_;
+
+ std::map<std::vector<uint8_t>, std::vector<uint8_t>> get_all_return_values_;
+
+ mojo::BindingSet<mojom::LevelDBWrapper> bindings_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_DOM_STORAGE_MOCK_LEVELDB_WRAPPER_H
diff --git a/chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.cc b/chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.cc
new file mode 100644
index 00000000000..12843e3e0b6
--- /dev/null
+++ b/chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.cc
@@ -0,0 +1,41 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/dom_storage/session_web_storage_namespace_impl.h"
+
+#include "content/renderer/dom_storage/local_storage_area.h"
+#include "content/renderer/dom_storage/local_storage_cached_areas.h"
+#include "third_party/WebKit/public/platform/URLConversion.h"
+#include "third_party/WebKit/public/platform/WebURL.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+using blink::WebStorageArea;
+using blink::WebStorageNamespace;
+
+namespace content {
+
+SessionWebStorageNamespaceImpl::SessionWebStorageNamespaceImpl(
+ int64_t namespace_id,
+ LocalStorageCachedAreas* local_storage_cached_areas)
+ : namespace_id_(namespace_id),
+ local_storage_cached_areas_(local_storage_cached_areas) {}
+
+SessionWebStorageNamespaceImpl::~SessionWebStorageNamespaceImpl() {}
+
+WebStorageArea* SessionWebStorageNamespaceImpl::CreateStorageArea(
+ const blink::WebSecurityOrigin& origin) {
+ return new LocalStorageArea(
+ local_storage_cached_areas_->GetSessionStorageArea(namespace_id_,
+ origin));
+}
+
+bool SessionWebStorageNamespaceImpl::IsSameNamespace(
+ const WebStorageNamespace& other) const {
+ const SessionWebStorageNamespaceImpl* other_impl =
+ static_cast<const SessionWebStorageNamespaceImpl*>(&other);
+ return namespace_id_ == other_impl->namespace_id_;
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.h b/chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.h
new file mode 100644
index 00000000000..9c3df88cffb
--- /dev/null
+++ b/chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.h
@@ -0,0 +1,37 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_DOM_STORAGE_SESSION_WEB_STORAGE_NAMESPACE_IMPL_H_
+#define CONTENT_RENDERER_DOM_STORAGE_SESSION_WEB_STORAGE_NAMESPACE_IMPL_H_
+
+#include "base/macros.h"
+#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
+#include "third_party/WebKit/public/platform/WebStorageNamespace.h"
+
+namespace content {
+class LocalStorageCachedAreas;
+
+class SessionWebStorageNamespaceImpl : public blink::WebStorageNamespace {
+ public:
+ // |local_storage_cached_areas| is guaranteed to outlive this object.
+ SessionWebStorageNamespaceImpl(
+ int64_t namespace_id,
+ LocalStorageCachedAreas* local_storage_cached_areas);
+ ~SessionWebStorageNamespaceImpl() override;
+
+ // blink::WebStorageNamespace:
+ blink::WebStorageArea* CreateStorageArea(
+ const blink::WebSecurityOrigin& origin) override;
+ bool IsSameNamespace(const WebStorageNamespace&) const override;
+
+ private:
+ int64_t namespace_id_;
+ LocalStorageCachedAreas* const local_storage_cached_areas_;
+
+ DISALLOW_COPY_AND_ASSIGN(SessionWebStorageNamespaceImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_DOM_STORAGE_SESSION_WEB_STORAGE_NAMESPACE_IMPL_H_
diff --git a/chromium/content/renderer/dom_storage/webstoragenamespace_impl.cc b/chromium/content/renderer/dom_storage/webstoragenamespace_impl.cc
index ee2a940286c..72600b830e7 100644
--- a/chromium/content/renderer/dom_storage/webstoragenamespace_impl.cc
+++ b/chromium/content/renderer/dom_storage/webstoragenamespace_impl.cc
@@ -39,7 +39,7 @@ WebStorageNamespace* WebStorageNamespaceImpl::copy() {
// session storage is used. In the WebViewClient::createView, we do the
// book-keeping necessary to make it a true copy-on-write despite not doing
// anything here, now.
- return NULL;
+ return nullptr;
}
bool WebStorageNamespaceImpl::IsSameNamespace(
diff --git a/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.cc b/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.cc
index 3fe708027bc..7d7c0a4b28c 100644
--- a/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.cc
+++ b/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.cc
@@ -135,12 +135,12 @@ void AssociatedResourceFetcherImpl::SetServiceWorkerMode(
request_.SetServiceWorkerMode(service_worker_mode);
}
-void AssociatedResourceFetcherImpl::SetCachePolicy(
- blink::WebCachePolicy policy) {
+void AssociatedResourceFetcherImpl::SetCacheMode(
+ blink::mojom::FetchCacheMode mode) {
DCHECK(!request_.IsNull());
DCHECK(!loader_);
- request_.SetCachePolicy(policy);
+ request_.SetCacheMode(mode);
}
void AssociatedResourceFetcherImpl::SetLoaderOptions(
@@ -154,8 +154,8 @@ void AssociatedResourceFetcherImpl::SetLoaderOptions(
void AssociatedResourceFetcherImpl::Start(
blink::WebLocalFrame* frame,
blink::WebURLRequest::RequestContext request_context,
- blink::WebURLRequest::FetchRequestMode fetch_request_mode,
- blink::WebURLRequest::FetchCredentialsMode fetch_credentials_mode,
+ network::mojom::FetchRequestMode fetch_request_mode,
+ network::mojom::FetchCredentialsMode fetch_credentials_mode,
blink::WebURLRequest::FrameType frame_type,
const Callback& callback) {
DCHECK(!loader_);
diff --git a/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.h b/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.h
index 83383209e64..6db146355b4 100644
--- a/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.h
+++ b/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.h
@@ -13,7 +13,6 @@
#include "base/macros.h"
#include "base/timer/timer.h"
#include "content/public/renderer/associated_resource_fetcher.h"
-#include "third_party/WebKit/public/platform/WebCachePolicy.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebAssociatedURLLoaderOptions.h"
@@ -31,13 +30,13 @@ class AssociatedResourceFetcherImpl : public AssociatedResourceFetcher {
// AssociatedResourceFetcher implementation:
void SetServiceWorkerMode(
blink::WebURLRequest::ServiceWorkerMode service_worker_mode) override;
- void SetCachePolicy(blink::WebCachePolicy policy) override;
+ void SetCacheMode(blink::mojom::FetchCacheMode mode) override;
void SetLoaderOptions(
const blink::WebAssociatedURLLoaderOptions& options) override;
void Start(blink::WebLocalFrame* frame,
blink::WebURLRequest::RequestContext request_context,
- blink::WebURLRequest::FetchRequestMode request_mode,
- blink::WebURLRequest::FetchCredentialsMode fetch_credentials_mode,
+ network::mojom::FetchRequestMode request_mode,
+ network::mojom::FetchCredentialsMode fetch_credentials_mode,
blink::WebURLRequest::FrameType frame_type,
const Callback& callback) override;
diff --git a/chromium/content/renderer/fetchers/manifest_fetcher.cc b/chromium/content/renderer/fetchers/manifest_fetcher.cc
index cd59d12b248..722c030efcb 100644
--- a/chromium/content/renderer/fetchers/manifest_fetcher.cc
+++ b/chromium/content/renderer/fetchers/manifest_fetcher.cc
@@ -35,9 +35,9 @@ void ManifestFetcher::Start(blink::WebLocalFrame* frame,
// true, and "omit" otherwise.
fetcher_->Start(
frame, blink::WebURLRequest::kRequestContextManifest,
- blink::WebURLRequest::kFetchRequestModeCORS,
- use_credentials ? blink::WebURLRequest::kFetchCredentialsModeInclude
- : blink::WebURLRequest::kFetchCredentialsModeOmit,
+ network::mojom::FetchRequestMode::kCORS,
+ use_credentials ? network::mojom::FetchCredentialsMode::kInclude
+ : network::mojom::FetchCredentialsMode::kOmit,
blink::WebURLRequest::kFrameTypeNone,
base::Bind(&ManifestFetcher::OnLoadComplete, base::Unretained(this)));
}
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 d6527120a5a..aa9c63ef80d 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(
WebLocalFrame* frame,
int id,
WebURLRequest::RequestContext request_context,
- blink::WebCachePolicy cache_policy,
+ blink::mojom::FetchCacheMode cache_mode,
const Callback& callback)
: callback_(callback),
id_(id),
@@ -43,11 +43,11 @@ MultiResolutionImageResourceFetcher::MultiResolutionImageResourceFetcher(
if (request_context == WebURLRequest::kRequestContextFavicon)
fetcher_->SetServiceWorkerMode(WebURLRequest::ServiceWorkerMode::kNone);
- fetcher_->SetCachePolicy(cache_policy);
+ fetcher_->SetCacheMode(cache_mode);
fetcher_->Start(
- frame, request_context, WebURLRequest::kFetchRequestModeNoCORS,
- WebURLRequest::kFetchCredentialsModeInclude,
+ frame, request_context, network::mojom::FetchRequestMode::kNoCORS,
+ network::mojom::FetchCredentialsMode::kInclude,
WebURLRequest::kFrameTypeNone,
base::Bind(&MultiResolutionImageResourceFetcher::OnURLFetchComplete,
base::Unretained(this)));
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 98020c79eee..e748c3ffcf4 100644
--- a/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h
+++ b/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h
@@ -11,8 +11,8 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "third_party/WebKit/public/platform/WebCachePolicy.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
+#include "third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
#include "url/gurl.h"
class SkBitmap;
@@ -38,7 +38,7 @@ class MultiResolutionImageResourceFetcher {
blink::WebLocalFrame* frame,
int id,
blink::WebURLRequest::RequestContext request_context,
- blink::WebCachePolicy cache_policy,
+ blink::mojom::FetchCacheMode cache_mode,
const Callback& callback);
virtual ~MultiResolutionImageResourceFetcher();
diff --git a/chromium/content/renderer/fetchers/resource_fetcher_browsertest.cc b/chromium/content/renderer/fetchers/resource_fetcher_browsertest.cc
index 2ff25adb0a8..44d98a5c2c9 100644
--- a/chromium/content/renderer/fetchers/resource_fetcher_browsertest.cc
+++ b/chromium/content/renderer/fetchers/resource_fetcher_browsertest.cc
@@ -14,9 +14,9 @@
#include "build/build_config.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "content/public/test/content_browser_test.h"
@@ -100,7 +100,7 @@ class FetcherDelegate {
base::Closure quit_task_;
};
-FetcherDelegate* FetcherDelegate::instance_ = NULL;
+FetcherDelegate* FetcherDelegate::instance_ = nullptr;
class EvilFetcherDelegate : public FetcherDelegate {
public:
diff --git a/chromium/content/renderer/fetchers/resource_fetcher_impl.cc b/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
index 2abb745e6ca..c52e16afb7d 100644
--- a/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
+++ b/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
@@ -9,12 +9,12 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "content/child/resource_dispatcher.h"
-#include "content/child/web_url_request_util.h"
#include "content/common/possibly_associated_interface_ptr.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
#include "content/public/common/resource_request_body.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
#include "content/public/renderer/render_frame.h"
+#include "content/renderer/loader/resource_dispatcher.h"
+#include "content/renderer/loader/web_url_request_util.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/net_errors.h"
#include "net/http/http_request_headers.h"
@@ -208,7 +208,7 @@ class ResourceFetcherImpl::ClientImpl : public mojom::URLLoaderClient {
base::Unretained(this)));
ReadDataPipe();
}
- void OnComplete(const ResourceRequestCompletionStatus& status) override {
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override {
// When Cancel() sets |complete_|, OnComplete() may be called.
if (completed_)
return;
@@ -312,7 +312,7 @@ void ResourceFetcherImpl::Start(
}
request_.resource_type = WebURLRequestContextToResourceType(request_context);
- client_ = base::MakeUnique<ClientImpl>(this, std::move(callback),
+ client_ = std::make_unique<ClientImpl>(this, std::move(callback),
maximum_download_size);
// TODO(kinuko, toyoshim): This task runner should be given by the consumer
// of this class.
diff --git a/chromium/content/child/file_info_util.cc b/chromium/content/renderer/file_info_util.cc
index dd5c3dd6949..94aa0183889 100644
--- a/chromium/content/child/file_info_util.cc
+++ b/chromium/content/renderer/file_info_util.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/child/file_info_util.h"
+#include "content/renderer/file_info_util.h"
#include "base/logging.h"
#include "third_party/WebKit/public/platform/WebFileInfo.h"
diff --git a/chromium/content/child/file_info_util.h b/chromium/content/renderer/file_info_util.h
index 82a11728b72..662a7e9dbce 100644
--- a/chromium/content/child/file_info_util.h
+++ b/chromium/content/renderer/file_info_util.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_CHILD_FILE_INFO_UTIL_H_
-#define CONTENT_CHILD_FILE_INFO_UTIL_H_
+#ifndef CONTENT_RENDERER_FILE_INFO_UTIL_H_
+#define CONTENT_RENDERER_FILE_INFO_UTIL_H_
#include "base/files/file.h"
@@ -19,4 +19,4 @@ void FileInfoToWebFileInfo(const base::File::Info& file_info,
} // namespace content
-#endif // CONTENT_CHILD_FILE_INFO_UTIL_H_
+#endif // CONTENT_RENDERER_FILE_INFO_UTIL_H_
diff --git a/chromium/content/child/fileapi/OWNERS b/chromium/content/renderer/fileapi/OWNERS
index bd016af34e0..c72d620620e 100644
--- a/chromium/content/child/fileapi/OWNERS
+++ b/chromium/content/renderer/fileapi/OWNERS
@@ -1,4 +1,6 @@
+jsbell@chromium.org
michaeln@chromium.org
+pwnall@chromium.org
jianli@chromium.org
tzik@chromium.org
nhiroki@chromium.org
diff --git a/chromium/content/child/fileapi/file_system_dispatcher.cc b/chromium/content/renderer/fileapi/file_system_dispatcher.cc
index 68bcd88b34a..b2f2ad37280 100644
--- a/chromium/content/child/fileapi/file_system_dispatcher.cc
+++ b/chromium/content/renderer/fileapi/file_system_dispatcher.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/child/fileapi/file_system_dispatcher.h"
+#include "content/renderer/fileapi/file_system_dispatcher.h"
#include <memory>
diff --git a/chromium/content/child/fileapi/file_system_dispatcher.h b/chromium/content/renderer/fileapi/file_system_dispatcher.h
index faf73617bbc..88e9378c638 100644
--- a/chromium/content/child/fileapi/file_system_dispatcher.h
+++ b/chromium/content/renderer/fileapi/file_system_dispatcher.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_CHILD_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
-#define CONTENT_CHILD_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
+#ifndef CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
+#define CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
#include <stdint.h>
@@ -151,4 +151,4 @@ class FileSystemDispatcher : public IPC::Listener {
} // namespace content
-#endif // CONTENT_CHILD_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
+#endif // CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
diff --git a/chromium/content/child/fileapi/webfilesystem_impl.cc b/chromium/content/renderer/fileapi/webfilesystem_impl.cc
index 71291180bbb..1ec25c920cc 100644
--- a/chromium/content/child/fileapi/webfilesystem_impl.cc
+++ b/chromium/content/renderer/fileapi/webfilesystem_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/fileapi/webfilesystem_impl.h"
+#include "content/renderer/fileapi/webfilesystem_impl.h"
#include <stddef.h>
#include <tuple>
@@ -15,11 +15,11 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_local.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/child_thread_impl.h"
-#include "content/child/file_info_util.h"
-#include "content/child/fileapi/file_system_dispatcher.h"
-#include "content/child/fileapi/webfilewriter_impl.h"
#include "content/common/fileapi/file_system_messages.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/directory_entry.h"
#include "storage/common/fileapi/file_system_util.h"
#include "third_party/WebKit/public/platform/FilePathConversion.h"
@@ -106,12 +106,12 @@ void CallDispatcherOnMainThread(
return;
waitable_results->WaitAndRun();
}
- if (!ChildThreadImpl::current() ||
- !ChildThreadImpl::current()->file_system_dispatcher())
+ if (!RenderThreadImpl::current() ||
+ !RenderThreadImpl::current()->file_system_dispatcher())
return;
DCHECK(!waitable_results);
- DispatchToMethod(ChildThreadImpl::current()->file_system_dispatcher(),
+ DispatchToMethod(RenderThreadImpl::current()->file_system_dispatcher(),
method, params);
}
@@ -176,7 +176,7 @@ void RunCallbacks(
const base::Callback<void(WebFileSystemCallbacks*)>& callback,
CallbacksUnregisterMode callbacks_unregister_mode) {
WebFileSystemImpl* filesystem =
- WebFileSystemImpl::ThreadSpecificInstance(NULL);
+ WebFileSystemImpl::ThreadSpecificInstance(nullptr);
if (!filesystem)
return;
WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id);
@@ -294,7 +294,7 @@ void DidCreateFileWriter(
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread_task_runner,
const base::File::Info& file_info) {
WebFileSystemImpl* filesystem =
- WebFileSystemImpl::ThreadSpecificInstance(NULL);
+ WebFileSystemImpl::ThreadSpecificInstance(nullptr);
if (!filesystem)
return;
@@ -334,7 +334,7 @@ void DidCreateSnapshotFile(
const base::FilePath& platform_path,
int request_id) {
WebFileSystemImpl* filesystem =
- WebFileSystemImpl::ThreadSpecificInstance(NULL);
+ WebFileSystemImpl::ThreadSpecificInstance(nullptr);
if (!filesystem)
return;
@@ -398,7 +398,7 @@ WebFileSystemImpl::WebFileSystemImpl(
WebFileSystemImpl::~WebFileSystemImpl() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- g_webfilesystem_tls.Pointer()->Set(NULL);
+ g_webfilesystem_tls.Pointer()->Set(nullptr);
}
void WebFileSystemImpl::WillStopCurrentWorkerThread() {
@@ -680,7 +680,7 @@ void WebFileSystemImpl::UnregisterCallbacks(int callbacks_id) {
WaitableCallbackResults* WebFileSystemImpl::MaybeCreateWaitableResults(
const WebFileSystemCallbacks& callbacks, int callbacks_id) {
if (!callbacks.ShouldBlockUntilCompletion())
- return NULL;
+ return nullptr;
WaitableCallbackResults* results = new WaitableCallbackResults();
waitable_results_[callbacks_id] = results;
return results;
diff --git a/chromium/content/child/fileapi/webfilesystem_impl.h b/chromium/content/renderer/fileapi/webfilesystem_impl.h
index 133becd205c..c42b5d2555d 100644
--- a/chromium/content/child/fileapi/webfilesystem_impl.h
+++ b/chromium/content/renderer/fileapi/webfilesystem_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_FILEAPI_WEBFILESYSTEM_IMPL_H_
-#define CONTENT_CHILD_FILEAPI_WEBFILESYSTEM_IMPL_H_
+#ifndef CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_
+#define CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_
#include <map>
@@ -11,7 +11,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
-#include "content/public/child/worker_thread.h"
+#include "content/public/renderer/worker_thread.h"
#include "third_party/WebKit/public/platform/WebFileSystem.h"
namespace base {
@@ -114,4 +114,4 @@ class WebFileSystemImpl : public blink::WebFileSystem,
} // namespace content
-#endif // CONTENT_CHILD_FILEAPI_WEBFILESYSTEM_IMPL_H_
+#endif // CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_
diff --git a/chromium/content/child/fileapi/webfilewriter_base.cc b/chromium/content/renderer/fileapi/webfilewriter_base.cc
index 7efbdbd1543..c264b8f4e9c 100644
--- a/chromium/content/child/fileapi/webfilewriter_base.cc
+++ b/chromium/content/renderer/fileapi/webfilewriter_base.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/fileapi/webfilewriter_base.h"
+#include "content/renderer/fileapi/webfilewriter_base.h"
#include "base/logging.h"
#include "storage/common/fileapi/file_system_util.h"
diff --git a/chromium/content/child/fileapi/webfilewriter_base.h b/chromium/content/renderer/fileapi/webfilewriter_base.h
index 150c699ac48..d721275ddb2 100644
--- a/chromium/content/child/fileapi/webfilewriter_base.h
+++ b/chromium/content/renderer/fileapi/webfilewriter_base.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_CHILD_FILEAPI_WEBFILEWRITER_BASE_H_
-#define CONTENT_CHILD_FILEAPI_WEBFILEWRITER_BASE_H_
+#ifndef CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_BASE_H_
+#define CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_BASE_H_
#include <stdint.h>
@@ -68,4 +68,4 @@ class CONTENT_EXPORT WebFileWriterBase : public blink::WebFileWriter {
} // namespace content
-#endif // CONTENT_CHILD_FILEAPI_WEBFILEWRITER_BASE_H_
+#endif // CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_BASE_H_
diff --git a/chromium/content/child/fileapi/webfilewriter_base_unittest.cc b/chromium/content/renderer/fileapi/webfilewriter_base_unittest.cc
index 6c37e1c15c2..9fa99582ee8 100644
--- a/chromium/content/child/fileapi/webfilewriter_base_unittest.cc
+++ b/chromium/content/renderer/fileapi/webfilewriter_base_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 "content/child/fileapi/webfilewriter_base.h"
+#include "content/renderer/fileapi/webfilewriter_base.h"
#include <stdint.h>
@@ -149,14 +149,14 @@ class FileWriterTest : public testing::Test,
received_did_write_complete_ = true;
if (delete_in_client_callback_)
- testable_writer_.reset(NULL);
+ testable_writer_.reset(nullptr);
}
void DidTruncate() override {
EXPECT_FALSE(received_did_truncate_);
received_did_truncate_ = true;
if (delete_in_client_callback_)
- testable_writer_.reset(NULL);
+ testable_writer_.reset(nullptr);
}
void DidFail(blink::WebFileError error) override {
@@ -164,7 +164,7 @@ class FileWriterTest : public testing::Test,
received_did_fail_ = true;
fail_error_received_ = error;
if (delete_in_client_callback_)
- testable_writer_.reset(NULL);
+ testable_writer_.reset(nullptr);
}
protected:
diff --git a/chromium/content/child/fileapi/webfilewriter_impl.cc b/chromium/content/renderer/fileapi/webfilewriter_impl.cc
index 64583514e34..61c646a4e1d 100644
--- a/chromium/content/child/fileapi/webfilewriter_impl.cc
+++ b/chromium/content/renderer/fileapi/webfilewriter_impl.cc
@@ -2,22 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/fileapi/webfilewriter_impl.h"
+#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/child/child_thread_impl.h"
-#include "content/child/fileapi/file_system_dispatcher.h"
-#include "content/public/child/worker_thread.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 {
namespace {
FileSystemDispatcher* GetFileSystemDispatcher() {
- return ChildThreadImpl::current() ?
- ChildThreadImpl::current()->file_system_dispatcher() : NULL;
+ return RenderThreadImpl::current()
+ ? RenderThreadImpl::current()->file_system_dispatcher()
+ : nullptr;
}
} // namespace
@@ -49,7 +50,7 @@ class WebFileWriterImpl::WriterBridge
status_callback_ = status_callback;
if (!GetFileSystemDispatcher())
return;
- ChildThreadImpl::current()->file_system_dispatcher()->Truncate(
+ RenderThreadImpl::current()->file_system_dispatcher()->Truncate(
path, offset, &request_id_,
base::Bind(&WriterBridge::DidFinish, this));
}
@@ -63,7 +64,7 @@ class WebFileWriterImpl::WriterBridge
status_callback_ = error_callback;
if (!GetFileSystemDispatcher())
return;
- ChildThreadImpl::current()->file_system_dispatcher()->Write(
+ RenderThreadImpl::current()->file_system_dispatcher()->Write(
path, id, offset, &request_id_,
base::Bind(&WriterBridge::DidWrite, this),
base::Bind(&WriterBridge::DidFinish, this));
@@ -73,7 +74,7 @@ class WebFileWriterImpl::WriterBridge
status_callback_ = status_callback;
if (!GetFileSystemDispatcher())
return;
- ChildThreadImpl::current()->file_system_dispatcher()->Cancel(
+ RenderThreadImpl::current()->file_system_dispatcher()->Cancel(
request_id_,
base::Bind(&WriterBridge::DidFinish, this));
}
diff --git a/chromium/content/child/fileapi/webfilewriter_impl.h b/chromium/content/renderer/fileapi/webfilewriter_impl.h
index 613df928345..2737ea76fe6 100644
--- a/chromium/content/child/fileapi/webfilewriter_impl.h
+++ b/chromium/content/renderer/fileapi/webfilewriter_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_FILEAPI_WEBFILEWRITER_IMPL_H_
-#define CONTENT_CHILD_FILEAPI_WEBFILEWRITER_IMPL_H_
+#ifndef CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_IMPL_H_
+#define CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_IMPL_H_
#include <stdint.h>
@@ -12,7 +12,7 @@
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "content/child/fileapi/webfilewriter_base.h"
+#include "content/renderer/fileapi/webfilewriter_base.h"
namespace base {
class SingleThreadTaskRunner;
@@ -55,4 +55,4 @@ class WebFileWriterImpl : public WebFileWriterBase,
} // namespace content
-#endif // CONTENT_CHILD_FILEAPI_WEBFILEWRITER_IMPL_H_
+#endif // CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_IMPL_H_
diff --git a/chromium/content/renderer/frame_owner_properties.cc b/chromium/content/renderer/frame_owner_properties.cc
index 21c2541ca6d..73ed983960b 100644
--- a/chromium/content/renderer/frame_owner_properties.cc
+++ b/chromium/content/renderer/frame_owner_properties.cc
@@ -7,7 +7,7 @@
#include <algorithm>
#include <iterator>
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
#include "third_party/WebKit/public/platform/modules/permissions/permission.mojom.h"
namespace content {
diff --git a/chromium/content/renderer/gamepad_shared_memory_reader.cc b/chromium/content/renderer/gamepad_shared_memory_reader.cc
index 65a20fb5dff..daee4fe36da 100644
--- a/chromium/content/renderer/gamepad_shared_memory_reader.cc
+++ b/chromium/content/renderer/gamepad_shared_memory_reader.cc
@@ -18,7 +18,7 @@ namespace content {
GamepadSharedMemoryReader::GamepadSharedMemoryReader(RenderThread* thread)
: RendererGamepadProvider(thread),
- gamepad_hardware_buffer_(NULL),
+ gamepad_hardware_buffer_(nullptr),
ever_interacted_with_(false),
binding_(this) {
if (thread) {
diff --git a/chromium/content/renderer/gpu/compositor_dependencies.h b/chromium/content/renderer/gpu/compositor_dependencies.h
index 712e2cb8971..91f629ecdd7 100644
--- a/chromium/content/renderer/gpu/compositor_dependencies.h
+++ b/chromium/content/renderer/gpu/compositor_dependencies.h
@@ -17,6 +17,7 @@ class SingleThreadTaskRunner;
namespace cc {
class TaskGraphRunner;
+class UkmRecorderFactory;
}
namespace blink {
@@ -50,6 +51,8 @@ class CompositorDependencies {
virtual cc::TaskGraphRunner* GetTaskGraphRunner() = 0;
virtual bool IsThreadedAnimationEnabled() = 0;
virtual bool IsScrollAnimatorEnabled() = 0;
+ virtual std::unique_ptr<cc::UkmRecorderFactory>
+ CreateUkmRecorderFactory() = 0;
virtual ~CompositorDependencies() {}
};
diff --git a/chromium/content/renderer/gpu/compositor_external_begin_frame_source.cc b/chromium/content/renderer/gpu/compositor_external_begin_frame_source.cc
index 2233f5916ef..867179b6497 100644
--- a/chromium/content/renderer/gpu/compositor_external_begin_frame_source.cc
+++ b/chromium/content/renderer/gpu/compositor_external_begin_frame_source.cc
@@ -14,7 +14,8 @@ CompositorExternalBeginFrameSource::CompositorExternalBeginFrameSource(
CompositorForwardingMessageFilter* filter,
IPC::SyncMessageFilter* sync_message_filter,
int routing_id)
- : external_begin_frame_source_(this),
+ : BeginFrameSource(kNotRestartableId),
+ external_begin_frame_source_(this),
begin_frame_source_filter_(filter),
message_sender_(sync_message_filter),
routing_id_(routing_id) {
diff --git a/chromium/content/renderer/gpu/frame_swap_message_queue.cc b/chromium/content/renderer/gpu/frame_swap_message_queue.cc
index 3f43b95dead..ba0f87b4416 100644
--- a/chromium/content/renderer/gpu/frame_swap_message_queue.cc
+++ b/chromium/content/renderer/gpu/frame_swap_message_queue.cc
@@ -139,7 +139,7 @@ FrameSwapMessageSubQueue* FrameSwapMessageQueue::GetSubQueue(
break;
}
NOTREACHED();
- return NULL;
+ return nullptr;
}
void FrameSwapMessageQueue::QueueMessageForFrame(
@@ -195,7 +195,7 @@ void FrameSwapMessageQueue::DrainMessages(
std::unique_ptr<FrameSwapMessageQueue::SendMessageScope>
FrameSwapMessageQueue::AcquireSendMessageScope() {
- return base::MakeUnique<SendMessageScopeImpl>(&lock_);
+ return std::make_unique<SendMessageScopeImpl>(&lock_);
}
// static
diff --git a/chromium/content/renderer/gpu/frame_swap_message_queue_unittest.cc b/chromium/content/renderer/gpu/frame_swap_message_queue_unittest.cc
index 75d0e42341e..10efd7194f9 100644
--- a/chromium/content/renderer/gpu/frame_swap_message_queue_unittest.cc
+++ b/chromium/content/renderer/gpu/frame_swap_message_queue_unittest.cc
@@ -23,7 +23,7 @@ class FrameSwapMessageQueueTest : public testing::Test {
protected:
void QueueNextSwapMessage(std::unique_ptr<IPC::Message> msg) {
queue_->QueueMessageForFrame(MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 0,
- std::move(msg), NULL);
+ std::move(msg), nullptr);
}
void QueueNextSwapMessage(std::unique_ptr<IPC::Message> msg, bool* first) {
@@ -34,7 +34,7 @@ class FrameSwapMessageQueueTest : public testing::Test {
void QueueVisualStateMessage(int source_frame_number,
std::unique_ptr<IPC::Message> msg) {
queue_->QueueMessageForFrame(MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE,
- source_frame_number, std::move(msg), NULL);
+ source_frame_number, std::move(msg), nullptr);
}
void QueueVisualStateMessage(int source_frame_number,
@@ -65,7 +65,7 @@ class FrameSwapMessageQueueTest : public testing::Test {
}
std::unique_ptr<IPC::Message> CloneMessage(const IPC::Message& other) {
- return base::MakeUnique<IPC::Message>(other);
+ return std::make_unique<IPC::Message>(other);
}
void TestDidNotSwap(cc::SwapPromise::DidNotSwapReason reason);
@@ -264,27 +264,27 @@ class NotifiesDeletionMessage : public IPC::Message {
TEST_F(FrameSwapMessageQueueTest, TestDeletesNextSwapMessage) {
bool message_deleted = false;
- QueueNextSwapMessage(base::MakeUnique<NotifiesDeletionMessage>(
+ QueueNextSwapMessage(std::make_unique<NotifiesDeletionMessage>(
&message_deleted, first_message_));
- queue_ = NULL;
+ queue_ = nullptr;
ASSERT_TRUE(message_deleted);
}
TEST_F(FrameSwapMessageQueueTest, TestDeletesVisualStateMessage) {
bool message_deleted = false;
- QueueVisualStateMessage(1, base::MakeUnique<NotifiesDeletionMessage>(
+ QueueVisualStateMessage(1, std::make_unique<NotifiesDeletionMessage>(
&message_deleted, first_message_));
- queue_ = NULL;
+ queue_ = nullptr;
ASSERT_TRUE(message_deleted);
}
TEST_F(FrameSwapMessageQueueTest, TestDeletesQueuedVisualStateMessage) {
bool message_deleted = false;
- QueueVisualStateMessage(1, base::MakeUnique<NotifiesDeletionMessage>(
+ QueueVisualStateMessage(1, std::make_unique<NotifiesDeletionMessage>(
&message_deleted, first_message_));
queue_->DidActivate(1);
queue_->DidSwap(1);
- queue_ = NULL;
+ queue_ = nullptr;
ASSERT_TRUE(message_deleted);
}
diff --git a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
index 9989170b624..3d9797f1147 100644
--- a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -21,7 +21,6 @@
#include "cc/layers/layer.h"
#include "cc/paint/skia_paint_canvas.h"
#include "cc/trees/layer_tree_host.h"
-#include "content/common/child_process_messages.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"
@@ -29,10 +28,10 @@
#include "content/common/input/synthetic_smooth_drag_gesture_params.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/common/input/synthetic_tap_gesture_params.h"
-#include "content/public/child/v8_value_converter.h"
#include "content/public/common/content_switches.h"
#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/render_widget_compositor.h"
#include "content/renderer/render_thread_impl.h"
@@ -41,6 +40,7 @@
#include "gin/arguments.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
+#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/platform/WebMouseEvent.h"
@@ -67,7 +67,7 @@
#if defined(OS_WIN) && !defined(NDEBUG)
#include <XpsObjectModel.h>
#include <objbase.h>
-#include "base/win/scoped_comptr.h"
+#include <wrl/client.h>
#endif
using blink::WebCanvas;
@@ -241,10 +241,10 @@ class CallbackAndContext : public base::RefCounted<CallbackAndContext> {
class GpuBenchmarkingContext {
public:
GpuBenchmarkingContext()
- : web_frame_(NULL),
- web_view_(NULL),
- render_view_impl_(NULL),
- compositor_(NULL) {}
+ : web_frame_(nullptr),
+ web_view_(nullptr),
+ render_view_impl_(nullptr),
+ compositor_(nullptr) {}
bool Init(bool init_compositor) {
web_frame_ = WebLocalFrame::FrameForCurrentContext();
@@ -253,14 +253,14 @@ class GpuBenchmarkingContext {
web_view_ = web_frame_->View();
if (!web_view_) {
- web_frame_ = NULL;
+ web_frame_ = nullptr;
return false;
}
render_view_impl_ = RenderViewImpl::FromWebView(web_view_);
if (!render_view_impl_) {
- web_frame_ = NULL;
- web_view_ = NULL;
+ web_frame_ = nullptr;
+ web_view_ = nullptr;
return false;
}
@@ -269,9 +269,9 @@ class GpuBenchmarkingContext {
compositor_ = render_view_impl_->GetWidget()->compositor();
if (!compositor_) {
- web_frame_ = NULL;
- web_view_ = NULL;
- render_view_impl_ = NULL;
+ web_frame_ = nullptr;
+ web_view_ = nullptr;
+ render_view_impl_ = nullptr;
return false;
}
@@ -279,19 +279,19 @@ class GpuBenchmarkingContext {
}
WebLocalFrame* web_frame() const {
- DCHECK(web_frame_ != NULL);
+ DCHECK(web_frame_ != nullptr);
return web_frame_;
}
WebView* web_view() const {
- DCHECK(web_view_ != NULL);
+ DCHECK(web_view_ != nullptr);
return web_view_;
}
RenderViewImpl* render_view_impl() const {
- DCHECK(render_view_impl_ != NULL);
+ DCHECK(render_view_impl_ != nullptr);
return render_view_impl_;
}
RenderWidgetCompositor* compositor() const {
- DCHECK(compositor_ != NULL);
+ DCHECK(compositor_ != nullptr);
return compositor_;
}
@@ -330,11 +330,12 @@ void OnSyntheticGestureCompleted(CallbackAndContext* callback_and_context) {
WebLocalFrame* frame = WebLocalFrame::FrameForContext(context);
if (frame && !callback.IsEmpty()) {
frame->CallFunctionEvenIfScriptDisabled(callback, v8::Object::New(isolate),
- 0, NULL);
+ 0, nullptr);
}
}
-bool BeginSmoothScroll(v8::Isolate* isolate,
+bool BeginSmoothScroll(GpuBenchmarkingContext* context,
+ gin::Arguments* args,
mojom::InputInjectorPtr& injector,
float pixels_to_scroll,
v8::Local<v8::Function> callback,
@@ -344,29 +345,32 @@ bool BeginSmoothScroll(v8::Isolate* isolate,
bool prevent_fling,
float start_x,
float start_y) {
- GpuBenchmarkingContext context;
- if (!context.Init(false))
+ gfx::Rect rect = context->render_view_impl()->GetWidget()->ViewRect();
+ rect -= rect.OffsetFromOrigin();
+ if (!rect.Contains(start_x, start_y)) {
+ args->ThrowTypeError("Start point not in bounds");
return false;
+ }
if (gesture_source_type == SyntheticGestureParams::MOUSE_INPUT) {
// Ensure the mouse is centered and visible, in case it will
// trigger any hover or mousemove effects.
- context.web_view()->SetIsActive(true);
- blink::WebRect contentRect =
- context.render_view_impl()->GetWidget()->ViewRect();
+ context->web_view()->SetIsActive(true);
+ blink::WebRect content_rect =
+ context->render_view_impl()->GetWidget()->ViewRect();
blink::WebMouseEvent mouseMove(
blink::WebInputEvent::kMouseMove, blink::WebInputEvent::kNoModifiers,
ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- mouseMove.SetPositionInWidget((contentRect.x + contentRect.width / 2),
- (contentRect.y + contentRect.height / 2));
- context.web_view()->HandleInputEvent(
+ mouseMove.SetPositionInWidget((content_rect.x + content_rect.width / 2.0),
+ (content_rect.y + content_rect.height / 2.0));
+ context->web_view()->HandleInputEvent(
blink::WebCoalescedInputEvent(mouseMove));
- context.web_view()->SetCursorVisibilityState(true);
+ context->web_view()->SetCursorVisibilityState(true);
}
scoped_refptr<CallbackAndContext> callback_and_context =
- new CallbackAndContext(isolate, callback,
- context.web_frame()->MainWorldScriptContext());
+ new CallbackAndContext(args->isolate(), callback,
+ context->web_frame()->MainWorldScriptContext());
SyntheticSmoothScrollGestureParams gesture_params;
@@ -417,7 +421,8 @@ bool BeginSmoothScroll(v8::Isolate* isolate,
return true;
}
-bool BeginSmoothDrag(v8::Isolate* isolate,
+bool BeginSmoothDrag(GpuBenchmarkingContext* context,
+ gin::Arguments* args,
mojom::InputInjectorPtr& injector,
float start_x,
float start_y,
@@ -426,12 +431,15 @@ bool BeginSmoothDrag(v8::Isolate* isolate,
v8::Local<v8::Function> callback,
int gesture_source_type,
float speed_in_pixels_s) {
- GpuBenchmarkingContext context;
- if (!context.Init(false))
+ gfx::Rect rect = context->render_view_impl()->GetWidget()->ViewRect();
+ rect -= rect.OffsetFromOrigin();
+ if (!rect.Contains(start_x, start_y)) {
+ args->ThrowTypeError("Start point not in bounds");
return false;
+ }
scoped_refptr<CallbackAndContext> callback_and_context =
- new CallbackAndContext(isolate, callback,
- context.web_frame()->MainWorldScriptContext());
+ new CallbackAndContext(args->isolate(), callback,
+ context->web_frame()->MainWorldScriptContext());
SyntheticSmoothDragGestureParams gesture_params;
@@ -513,7 +521,7 @@ static sk_sp<SkDocument> MakeXPSDocument(SkWStream* s) {
COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
// In non-sandboxed mode, we will need to create and hold on to the
// factory before entering the sandbox.
- base::win::ScopedComPtr<IXpsOMObjectFactory> factory;
+ Microsoft::WRL::ComPtr<IXpsOMObjectFactory> factory;
HRESULT hr = ::CoCreateInstance(CLSID_XpsOMObjectFactory, nullptr,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory));
if (FAILED(hr) || !factory) {
@@ -583,6 +591,9 @@ gin::ObjectTemplateBuilder GpuBenchmarking::GetObjectTemplateBuilder(
.SetMethod("scrollBounce", &GpuBenchmarking::ScrollBounce)
.SetMethod("pinchBy", &GpuBenchmarking::PinchBy)
.SetMethod("pageScaleFactor", &GpuBenchmarking::PageScaleFactor)
+ .SetMethod("setPageScaleFactor", &GpuBenchmarking::SetPageScaleFactor)
+ .SetMethod("setBrowserControlsShown",
+ &GpuBenchmarking::SetBrowserControlsShown)
.SetMethod("tap", &GpuBenchmarking::Tap)
.SetMethod("pointerActionSequence",
&GpuBenchmarking::PointerActionSequence)
@@ -698,7 +709,7 @@ bool GpuBenchmarking::SmoothScrollBy(gin::Arguments* args) {
}
EnsureRemoteInterface();
- return BeginSmoothScroll(args->isolate(), input_injector_, pixels_to_scroll,
+ return BeginSmoothScroll(&context, args, input_injector_, pixels_to_scroll,
callback, gesture_source_type, direction,
speed_in_pixels_s, true, start_x, start_y);
}
@@ -727,7 +738,7 @@ bool GpuBenchmarking::SmoothDrag(gin::Arguments* args) {
}
EnsureRemoteInterface();
- return BeginSmoothDrag(args->isolate(), input_injector_, start_x, start_y,
+ return BeginSmoothDrag(&context, args, input_injector_, start_x, start_y,
end_x, end_y, callback, gesture_source_type,
speed_in_pixels_s);
}
@@ -757,7 +768,7 @@ bool GpuBenchmarking::Swipe(gin::Arguments* args) {
EnsureRemoteInterface();
return BeginSmoothScroll(
- args->isolate(), input_injector_, -pixels_to_scroll, callback,
+ &context, args, input_injector_, -pixels_to_scroll, callback,
1, // TOUCH_INPUT
direction, speed_in_pixels_s, false, start_x, start_y);
}
@@ -767,15 +778,16 @@ bool GpuBenchmarking::ScrollBounce(gin::Arguments* args) {
if (!context.Init(false))
return false;
- blink::WebRect rect = context.render_view_impl()->GetWidget()->ViewRect();
+ blink::WebRect content_rect =
+ context.render_view_impl()->GetWidget()->ViewRect();
std::string direction = "down";
float distance_length = 0;
float overscroll_length = 0;
int repeat_count = 1;
v8::Local<v8::Function> callback;
- float start_x = rect.width / 2;
- float start_y = rect.height / 2;
+ float start_x = content_rect.width / 2;
+ float start_y = content_rect.height / 2;
float speed_in_pixels_s = 800;
if (!GetOptionalArg(args, &direction) ||
@@ -789,6 +801,13 @@ bool GpuBenchmarking::ScrollBounce(gin::Arguments* args) {
return false;
}
+ gfx::Rect rect = context.render_view_impl()->GetWidget()->ViewRect();
+ rect -= rect.OffsetFromOrigin();
+ if (!rect.Contains(start_x, start_y)) {
+ args->ThrowTypeError("Start point not in bounds");
+ return false;
+ }
+
scoped_refptr<CallbackAndContext> callback_and_context =
new CallbackAndContext(args->isolate(), callback,
context.web_frame()->MainWorldScriptContext());
@@ -840,7 +859,6 @@ bool GpuBenchmarking::PinchBy(gin::Arguments* args) {
v8::Local<v8::Function> callback;
float relative_pointer_speed_in_pixels_s = 800;
-
if (!GetArg(args, &scale_factor) ||
!GetArg(args, &anchor_x) ||
!GetArg(args, &anchor_y) ||
@@ -849,6 +867,13 @@ bool GpuBenchmarking::PinchBy(gin::Arguments* args) {
return false;
}
+ gfx::Rect rect = context.render_view_impl()->GetWidget()->ViewRect();
+ rect -= rect.OffsetFromOrigin();
+ if (!rect.Contains(anchor_x, anchor_y)) {
+ args->ThrowTypeError("Anchor point not in bounds");
+ return false;
+ }
+
SyntheticPinchGestureParams gesture_params;
gesture_params.scale_factor = scale_factor;
@@ -874,6 +899,23 @@ float GpuBenchmarking::PageScaleFactor() {
return context.web_view()->PageScaleFactor();
}
+void GpuBenchmarking::SetPageScaleFactor(float scale) {
+ GpuBenchmarkingContext context;
+ if (!context.Init(false))
+ return;
+ context.web_view()->SetPageScaleFactor(scale);
+}
+
+void GpuBenchmarking::SetBrowserControlsShown(bool show) {
+ GpuBenchmarkingContext context;
+ if (!context.Init(false))
+ return;
+ context.web_view()->UpdateBrowserControlsState(
+ blink::kWebBrowserControlsBoth,
+ show ? blink::kWebBrowserControlsShown : blink::kWebBrowserControlsHidden,
+ false);
+}
+
float GpuBenchmarking::VisualViewportY() {
GpuBenchmarkingContext context;
if (!context.Init(false))
@@ -933,11 +975,10 @@ bool GpuBenchmarking::Tap(gin::Arguments* args) {
return false;
}
- // Convert coordinates from CSS pixels to density independent pixels (DIPs).
gfx::Rect rect = context.render_view_impl()->GetWidget()->ViewRect();
rect -= rect.OffsetFromOrigin();
if (!rect.Contains(position_x, position_y)) {
- args->ThrowError();
+ args->ThrowTypeError("Start point not in bounds");
return false;
}
@@ -1062,10 +1103,10 @@ bool GpuBenchmarking::HasGpuChannel() {
bool GpuBenchmarking::HasGpuProcess() {
bool has_gpu_process = false;
- if (!RenderThreadImpl::current()->Send(
- new ChildProcessHostMsg_HasGpuProcess(&has_gpu_process)))
+ if (!RenderThreadImpl::current()->render_message_filter()->HasGpuProcess(
+ &has_gpu_process)) {
return false;
-
+ }
return has_gpu_process;
}
@@ -1073,10 +1114,14 @@ void GpuBenchmarking::GetGpuDriverBugWorkarounds(gin::Arguments* args) {
std::vector<std::string> gpu_driver_bug_workarounds;
gpu::GpuChannelHost* gpu_channel =
RenderThreadImpl::current()->GetGpuChannel();
- if (!gpu_channel ||
- !gpu_channel->Send(new GpuChannelMsg_GetDriverBugWorkArounds(
- &gpu_driver_bug_workarounds))) {
+ if (!gpu_channel)
return;
+ const std::vector<int32_t>& workarounds =
+ gpu_channel->gpu_feature_info().enabled_gpu_driver_bug_workarounds;
+ for (int32_t workaround : workarounds) {
+ gpu_driver_bug_workarounds.push_back(
+ gpu::GpuDriverBugWorkaroundTypeToString(
+ static_cast<gpu::GpuDriverBugWorkaroundType>(workaround)));
}
v8::Local<v8::Value> result;
diff --git a/chromium/content/renderer/gpu/gpu_benchmarking_extension.h b/chromium/content/renderer/gpu/gpu_benchmarking_extension.h
index 73e2dcffdfc..477f5ed1291 100644
--- a/chromium/content/renderer/gpu/gpu_benchmarking_extension.h
+++ b/chromium/content/renderer/gpu/gpu_benchmarking_extension.h
@@ -70,6 +70,10 @@ class GpuBenchmarking : public gin::Wrappable<GpuBenchmarking> {
// Returns the page scale factor applied as a result of pinch-zoom.
float PageScaleFactor();
+ // Sets the page scale factor applied as a result of pinch-zoom.
+ void SetPageScaleFactor(float scale);
+
+ void SetBrowserControlsShown(bool shown);
void ClearImageCache();
int RunMicroBenchmark(gin::Arguments* args);
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 d61780b8ac9..42020a97003 100644
--- a/chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc
+++ b/chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc
@@ -46,7 +46,7 @@ class TestSyncMessageFilter : public IPC::SyncMessageFilter {
std::vector<IPC::Message> messages = std::get<1>(param);
last_swap_messages_.clear();
for (const IPC::Message& message : messages) {
- last_swap_messages_.push_back(base::MakeUnique<IPC::Message>(message));
+ last_swap_messages_.push_back(std::make_unique<IPC::Message>(message));
}
delete message;
} else {
diff --git a/chromium/content/renderer/gpu/render_widget_compositor.cc b/chromium/content/renderer/gpu/render_widget_compositor.cc
index c479c198743..248835a0a79 100644
--- a/chromium/content/renderer/gpu/render_widget_compositor.cc
+++ b/chromium/content/renderer/gpu/render_widget_compositor.cc
@@ -43,12 +43,13 @@
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_mutator.h"
#include "cc/trees/swap_promise.h"
+#include "cc/trees/ukm_manager.h"
+#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/common/resources/single_release_callback.h"
-#include "components/viz/common/switches.h"
#include "content/common/content_switches_internal.h"
#include "content/common/layer_tree_settings_factory.h"
#include "content/public/common/content_client.h"
@@ -90,7 +91,7 @@ using blink::WebSelection;
using blink::WebSize;
using blink::WebBrowserControlsState;
using blink::WebLayerTreeView;
-using blink::WebScrollBoundaryBehavior;
+using blink::WebOverscrollBehavior;
namespace content {
namespace {
@@ -279,8 +280,7 @@ std::unique_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create(
RenderWidgetCompositor::RenderWidgetCompositor(
RenderWidgetCompositorDelegate* delegate,
CompositorDependencies* compositor_deps)
- : num_failed_recreate_attempts_(0),
- delegate_(delegate),
+ : delegate_(delegate),
compositor_deps_(compositor_deps),
threaded_(!!compositor_deps_->GetCompositorImplThreadTaskRunner()),
never_visible_(false),
@@ -321,6 +321,7 @@ std::unique_ptr<cc::LayerTreeHost> RenderWidgetCompositor::CreateLayerTreeHost(
params.task_graph_runner = deps->GetTaskGraphRunner();
params.main_task_runner = deps->GetCompositorMainThreadTaskRunner();
params.mutator_host = mutator_host;
+ params.ukm_recorder_factory = deps->CreateUkmRecorderFactory();
if (base::TaskScheduler::GetInstance()) {
// The image worker thread needs to allow waiting since it makes discardable
// shared memory allocations which need to make synchronous calls to the
@@ -459,7 +460,7 @@ cc::LayerTreeSettings RenderWidgetCompositor::GenerateLayerTreeSettings(
settings.initial_debug_state.SetRecordRenderingStats(
cmd.HasSwitch(cc::switches::kEnableGpuBenchmarking));
settings.enable_surface_synchronization =
- cmd.HasSwitch(switches::kEnableSurfaceSynchronization);
+ features::IsSurfaceSynchronizationEnabled();
if (cmd.HasSwitch(cc::switches::kSlowDownRasterScaleFactor)) {
const int kMinSlowDownScaleFactor = 0;
@@ -533,15 +534,13 @@ cc::LayerTreeSettings RenderWidgetCompositor::GenerateLayerTreeSettings(
}
// On desktop, if there's over 4GB of memory on the machine, increase the
- // image decode budget to 256MB for both gpu and software.
+ // working set size to 256MB for both gpu and software.
const int kImageDecodeMemoryThresholdMB = 4 * 1024;
if (base::SysInfo::AmountOfPhysicalMemoryMB() >=
kImageDecodeMemoryThresholdMB) {
- settings.decoded_image_cache_budget_bytes = 256 * 1024 * 1024;
settings.decoded_image_working_set_budget_bytes = 256 * 1024 * 1024;
} else {
- // These are the defaults, but recorded here as well.
- settings.decoded_image_cache_budget_bytes = 128 * 1024 * 1024;
+ // This is the default, but recorded here as well.
settings.decoded_image_working_set_budget_bytes = 128 * 1024 * 1024;
}
#endif // defined(OS_ANDROID)
@@ -556,11 +555,6 @@ cc::LayerTreeSettings RenderWidgetCompositor::GenerateLayerTreeSettings(
!using_synchronous_compositor) {
settings.preferred_tile_format = viz::RGBA_4444;
}
-
- // When running on a low end device, we limit cached bytes to 512KB.
- // This allows pages which are light on images to stay in cache, but
- // prevents most long-term caching.
- settings.decoded_image_cache_budget_bytes = 512 * 1024;
}
if (cmd.HasSwitch(switches::kEnableLowResTiling))
@@ -590,8 +584,10 @@ cc::LayerTreeSettings RenderWidgetCompositor::GenerateLayerTreeSettings(
settings.disallow_non_exact_resource_reuse =
cmd.HasSwitch(switches::kDisallowNonExactResourceReuse);
- settings.wait_for_all_pipeline_stages_before_draw =
- cmd.HasSwitch(cc::switches::kRunAllCompositorStagesBeforeDraw);
+ if (cmd.HasSwitch(cc::switches::kRunAllCompositorStagesBeforeDraw)) {
+ settings.wait_for_all_pipeline_stages_before_draw = true;
+ settings.enable_latency_recovery = false;
+ }
settings.enable_image_animations =
cmd.HasSwitch(switches::kEnableCompositorImageAnimations);
@@ -733,7 +729,7 @@ void RenderWidgetCompositor::SetNeedsForcedRedraw() {
std::unique_ptr<cc::SwapPromiseMonitor>
RenderWidgetCompositor::CreateLatencyInfoSwapPromiseMonitor(
ui::LatencyInfo* latency) {
- return base::MakeUnique<cc::LatencyInfoSwapPromiseMonitor>(
+ return std::make_unique<cc::LatencyInfoSwapPromiseMonitor>(
latency, layer_tree_host_->GetSwapPromiseManager(), nullptr);
}
@@ -813,6 +809,9 @@ void RenderWidgetCompositor::SetVisible(bool visible) {
return;
layer_tree_host_->SetVisible(visible);
+
+ if (visible && layer_tree_frame_sink_request_failed_while_invisible_)
+ DidFailToInitializeLayerTreeFrameSink();
}
void RenderWidgetCompositor::SetPageScaleFactorAndLimits(
@@ -973,12 +972,6 @@ void RenderWidgetCompositor::UpdateEventRectsForSubframeIfNecessary() {
touch_end_cancel_properties ==
WebEventListenerProperties::kBlockingAndPassive;
- WebEventListenerProperties wheel_event_properties =
- EventListenerProperties(WebEventListenerClass::kMouseWheel);
- bool has_wheel_handlers =
- wheel_event_properties == WebEventListenerProperties::kBlocking ||
- wheel_event_properties == WebEventListenerProperties::kBlockingAndPassive;
-
cc::Layer* root_layer = layer_tree_host_->root_layer();
cc::TouchActionRegion touch_event_handler;
@@ -987,11 +980,6 @@ void RenderWidgetCompositor::UpdateEventRectsForSubframeIfNecessary() {
gfx::Rect(gfx::Point(), root_layer->bounds()));
}
root_layer->SetTouchActionRegion(std::move(touch_event_handler));
-
- cc::Region wheel_handler_region;
- if (has_wheel_handlers)
- wheel_handler_region = gfx::Rect(gfx::Point(), root_layer->bounds());
- root_layer->SetNonFastScrollableRegion(wheel_handler_region);
}
blink::WebEventListenerProperties
@@ -1157,8 +1145,8 @@ void RenderWidgetCompositor::SetBrowserControlsShownRatio(float ratio) {
void RenderWidgetCompositor::RequestDecode(
const PaintImage& image,
- const base::Callback<void(bool)>& callback) {
- layer_tree_host_->QueueImageDecode(image, callback);
+ base::OnceCallback<void(bool)> callback) {
+ layer_tree_host_->QueueImageDecode(image, std::move(callback));
// If we're compositing synchronously, the SetNeedsCommit call which will be
// issued by |layer_tree_host_| is not going to cause a commit, due to the
@@ -1173,9 +1161,9 @@ void RenderWidgetCompositor::RequestDecode(
}
}
-void RenderWidgetCompositor::SetScrollBoundaryBehavior(
- const WebScrollBoundaryBehavior& behavior) {
- layer_tree_host_->SetScrollBoundaryBehavior(behavior);
+void RenderWidgetCompositor::SetOverscrollBehavior(
+ const WebOverscrollBehavior& behavior) {
+ layer_tree_host_->SetOverscrollBehavior(behavior);
}
void RenderWidgetCompositor::WillBeginMainFrame() {
@@ -1228,24 +1216,20 @@ void RenderWidgetCompositor::RequestNewLayerTreeFrameSink() {
// the CreateLayerTreeFrameSink task.
if (delegate_->IsClosing())
return;
-
- bool fallback = num_failed_recreate_attempts_ >=
- LAYER_TREE_FRAME_SINK_RETRIES_BEFORE_FALLBACK;
-#ifdef OS_ANDROID
- LOG_IF(FATAL, fallback) << "Android does not support fallback frame sinks.";
-#endif
-
delegate_->RequestNewLayerTreeFrameSink(
- fallback, base::Bind(&RenderWidgetCompositor::SetLayerTreeFrameSink,
- weak_factory_.GetWeakPtr()));
+ base::Bind(&RenderWidgetCompositor::SetLayerTreeFrameSink,
+ weak_factory_.GetWeakPtr()));
}
void RenderWidgetCompositor::DidInitializeLayerTreeFrameSink() {
- num_failed_recreate_attempts_ = 0;
}
void RenderWidgetCompositor::DidFailToInitializeLayerTreeFrameSink() {
- ++num_failed_recreate_attempts_;
+ if (!layer_tree_host_->IsVisible()) {
+ layer_tree_frame_sink_request_failed_while_invisible_ = true;
+ return;
+ }
+ layer_tree_frame_sink_request_failed_while_invisible_ = false;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&RenderWidgetCompositor::RequestNewLayerTreeFrameSink,
@@ -1309,7 +1293,7 @@ void RenderWidgetCompositor::SetContentSourceId(uint32_t id) {
}
void RenderWidgetCompositor::NotifySwapTime(ReportTimeCallback callback) {
- QueueSwapPromise(base::MakeUnique<ReportTimeSwapPromise>(
+ QueueSwapPromise(std::make_unique<ReportTimeSwapPromise>(
std::move(callback), base::ThreadTaskRunnerHandle::Get()));
}
@@ -1317,4 +1301,8 @@ void RenderWidgetCompositor::RequestBeginMainFrameNotExpected(bool new_state) {
layer_tree_host_->RequestBeginMainFrameNotExpected(new_state);
}
+void RenderWidgetCompositor::SetURLForUkm(const GURL& url) {
+ layer_tree_host_->SetURLForUkm(url);
+}
+
} // namespace content
diff --git a/chromium/content/renderer/gpu/render_widget_compositor.h b/chromium/content/renderer/gpu/render_widget_compositor.h
index b42ba96a9cb..2885499101b 100644
--- a/chromium/content/renderer/gpu/render_widget_compositor.h
+++ b/chromium/content/renderer/gpu/render_widget_compositor.h
@@ -11,8 +11,8 @@
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/values.h"
-#include "build/build_config.h"
#include "cc/input/browser_controls_state.h"
+#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
#include "cc/trees/layer_tree_settings.h"
@@ -21,6 +21,7 @@
#include "cc/trees/swap_promise_monitor.h"
#include "content/common/content_export.h"
#include "content/renderer/gpu/compositor_dependencies.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/WebKit/public/platform/WebLayerTreeView.h"
#include "ui/gfx/geometry/rect.h"
@@ -125,6 +126,7 @@ class CONTENT_EXPORT RenderWidgetCompositor
void SetContentSourceId(uint32_t source_id);
void SetViewportSize(const gfx::Size& device_viewport_size,
const viz::LocalSurfaceId& local_surface_id);
+ void SetURLForUkm(const GURL& url);
// WebLayerTreeView implementation.
viz::FrameSinkId GetFrameSinkId() override;
@@ -184,10 +186,9 @@ class CONTENT_EXPORT RenderWidgetCompositor
bool shrink) override;
void SetBrowserControlsShownRatio(float) override;
void RequestDecode(const PaintImage& image,
- const base::Callback<void(bool)>& callback) override;
+ base::OnceCallback<void(bool)> callback) override;
- void SetScrollBoundaryBehavior(
- const blink::WebScrollBoundaryBehavior&) override;
+ void SetOverscrollBehavior(const blink::WebOverscrollBehavior&) override;
// cc::LayerTreeHostClient implementation.
void WillBeginMainFrame() override;
@@ -219,13 +220,9 @@ class CONTENT_EXPORT RenderWidgetCompositor
void DidLoseLayerTreeFrameSink() override;
void RequestBeginMainFrameNotExpected(bool new_state) override;
- enum {
-#if defined(OS_ANDROID)
- LAYER_TREE_FRAME_SINK_RETRIES_BEFORE_FALLBACK = 4,
-#else
- LAYER_TREE_FRAME_SINK_RETRIES_BEFORE_FALLBACK = 1,
-#endif
- };
+ const cc::LayerTreeSettings& GetLayerTreeSettings() const {
+ return layer_tree_host_->GetSettings();
+ }
protected:
friend class RenderViewImplScaleFactorTest;
@@ -243,7 +240,6 @@ class CONTENT_EXPORT RenderWidgetCompositor
bool CompositeIsSynchronous() const;
void SynchronouslyComposite();
- int num_failed_recreate_attempts_;
RenderWidgetCompositorDelegate* const delegate_;
CompositorDependencies* const compositor_deps_;
const bool threaded_;
@@ -252,6 +248,8 @@ class CONTENT_EXPORT RenderWidgetCompositor
bool never_visible_;
bool is_for_oopif_;
+ bool layer_tree_frame_sink_request_failed_while_invisible_ = false;
+
blink::WebLayoutAndPaintAsyncCallback* layout_and_paint_async_callback_;
viz::FrameSinkId frame_sink_id_;
diff --git a/chromium/content/renderer/gpu/render_widget_compositor_delegate.h b/chromium/content/renderer/gpu/render_widget_compositor_delegate.h
index 256b08303e1..bd60ef5e199 100644
--- a/chromium/content/renderer/gpu/render_widget_compositor_delegate.h
+++ b/chromium/content/renderer/gpu/render_widget_compositor_delegate.h
@@ -53,7 +53,6 @@ class CONTENT_EXPORT RenderWidgetCompositorDelegate {
// Requests a LayerTreeFrameSink to submit CompositorFrames to.
virtual void RequestNewLayerTreeFrameSink(
- bool fallback,
const LayerTreeFrameSinkCallback& callback) = 0;
// Notifies that the draw commands for a committed frame have been issued.
diff --git a/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc b/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc
index f5330b62233..9ac77a98e59 100644
--- a/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc
+++ b/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc
@@ -36,6 +36,7 @@ namespace {
enum FailureMode {
NO_FAILURE,
+ BIND_CONTEXT_FAILURE,
GPU_CHANNEL_FAILURE,
};
@@ -52,7 +53,6 @@ class StubRenderWidgetCompositorDelegate
bool has_scrolled_by_touch) override {}
void BeginMainFrame(double frame_time_sec) override {}
void RequestNewLayerTreeFrameSink(
- bool fallback,
const LayerTreeFrameSinkCallback& callback) override {
callback.Run(nullptr);
}
@@ -76,18 +76,16 @@ class FakeRenderWidgetCompositorDelegate
FakeRenderWidgetCompositorDelegate() = default;
void RequestNewLayerTreeFrameSink(
- bool fallback,
const LayerTreeFrameSinkCallback& callback) override {
- last_create_was_fallback_ = fallback;
-
- bool success = num_failures_ >= num_failures_before_success_;
- if (!success && use_null_layer_tree_frame_sink_) {
+ // Subtract one cuz the current request has already been counted but should
+ // not be included for this.
+ if (num_requests_since_last_success_ - 1 < num_requests_before_success_) {
callback.Run(std::unique_ptr<cc::LayerTreeFrameSink>());
return;
}
auto context_provider = cc::TestContextProvider::Create();
- if (!success) {
+ if (num_failures_since_last_success_ < num_failures_before_success_) {
context_provider->UnboundTestContext3d()->loseContextCHROMIUM(
GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
}
@@ -97,22 +95,20 @@ class FakeRenderWidgetCompositorDelegate
void Reset() {
num_requests_ = 0;
+ num_requests_before_success_ = 0;
num_requests_since_last_success_ = 0;
num_failures_ = 0;
num_failures_before_success_ = 0;
- num_fallback_successes_ = 0;
+ num_failures_since_last_success_ = 0;
num_successes_ = 0;
}
void add_success() {
- if (last_create_was_fallback_)
- ++num_fallback_successes_;
- else
- ++num_successes_;
+ ++num_successes_;
num_requests_since_last_success_ = 0;
+ num_failures_since_last_success_ = 0;
}
int num_successes() const { return num_successes_; }
- int num_fallback_successes() const { return num_fallback_successes_; }
void add_request() {
++num_requests_since_last_success_;
@@ -120,9 +116,15 @@ class FakeRenderWidgetCompositorDelegate
}
int num_requests() const { return num_requests_; }
- void add_failure() { ++num_failures_; }
+ void add_failure() {
+ ++num_failures_since_last_success_;
+ ++num_failures_;
+ }
int num_failures() const { return num_failures_; }
+ void set_num_requests_before_success(int n) {
+ num_requests_before_success_ = n;
+ }
void set_num_failures_before_success(int n) {
num_failures_before_success_ = n;
}
@@ -130,26 +132,20 @@ class FakeRenderWidgetCompositorDelegate
return num_failures_before_success_;
}
- void set_use_null_layer_tree_frame_sink(bool u) {
- use_null_layer_tree_frame_sink_ = u;
- }
-
private:
int num_requests_ = 0;
+ int num_requests_before_success_ = 0;
int num_requests_since_last_success_ = 0;
int num_failures_ = 0;
int num_failures_before_success_ = 0;
- int num_fallback_successes_ = 0;
+ int num_failures_since_last_success_ = 0;
int num_successes_ = 0;
- bool last_create_was_fallback_ = false;
- bool use_null_layer_tree_frame_sink_ = true;
DISALLOW_COPY_AND_ASSIGN(FakeRenderWidgetCompositorDelegate);
};
// Verify that failing to create an output surface will cause the compositor
-// to attempt to repeatedly create another output surface. After enough
-// failures, verify that it attempts to create a fallback output surface.
+// to attempt to repeatedly create another output surface.
// The use null output surface parameter allows testing whether failures
// from RenderWidget (couldn't create an output surface) vs failures from
// the compositor (couldn't bind the output surface) are handled identically.
@@ -180,7 +176,8 @@ class RenderWidgetLayerTreeFrameSink : public RenderWidgetCompositor {
void DidInitializeLayerTreeFrameSink() override {
RenderWidgetCompositor::DidInitializeLayerTreeFrameSink();
delegate_->add_success();
- if (delegate_->num_requests() == expected_requests_) {
+ if (delegate_->num_successes() == expected_successes_) {
+ EXPECT_EQ(delegate_->num_requests(), expected_requests_);
EndTest();
} else {
// Post the synchronous composite task so that it is not called
@@ -196,42 +193,35 @@ class RenderWidgetLayerTreeFrameSink : public RenderWidgetCompositor {
RenderWidgetCompositor::DidFailToInitializeLayerTreeFrameSink();
delegate_->add_failure();
if (delegate_->num_requests() == expected_requests_) {
+ EXPECT_EQ(delegate_->num_successes(), expected_successes_);
EndTest();
return;
}
}
- void SetUp(int expected_successes, FailureMode failure_mode) {
+ void SetUp(int expected_successes,
+ int num_tries,
+ FailureMode failure_mode,
+ base::RunLoop* run_loop) {
+ run_loop_ = run_loop;
failure_mode_ = failure_mode;
+ expected_successes_ = expected_successes;
switch (failure_mode_) {
case NO_FAILURE:
- expected_requests_ = 1;
+ expected_requests_ = expected_successes;
break;
+ case BIND_CONTEXT_FAILURE:
case GPU_CHANNEL_FAILURE:
- expected_requests_ = 2;
+ expected_requests_ = num_tries * std::max(1, expected_successes);
break;
}
- expected_successes_ = expected_successes;
- expected_requests_ += (expected_successes - 1);
}
- void EndTest() { base::RunLoop::QuitCurrentWhenIdleDeprecated(); }
-
- void AfterTest() {
- if (failure_mode_ == NO_FAILURE) {
- EXPECT_EQ(expected_successes_, delegate_->num_successes());
- EXPECT_EQ(0, delegate_->num_fallback_successes());
- } else if (failure_mode_ == GPU_CHANNEL_FAILURE) {
- EXPECT_EQ(0, delegate_->num_successes());
- EXPECT_EQ(1, delegate_->num_fallback_successes());
- } else {
- NOTREACHED();
- }
- EXPECT_EQ(expected_requests_, delegate_->num_requests());
- }
+ void EndTest() { run_loop_->Quit(); }
private:
FakeRenderWidgetCompositorDelegate* delegate_;
+ base::RunLoop* run_loop_ = nullptr;
int expected_successes_ = 0;
int expected_requests_ = 0;
FailureMode failure_mode_ = NO_FAILURE;
@@ -256,22 +246,38 @@ class RenderWidgetLayerTreeFrameSinkTest : public testing::Test {
std::move(animation_host));
}
- void RunTest(bool use_null_layer_tree_frame_sink,
- int expected_successes,
- FailureMode failure_mode) {
+ void RunTest(int expected_successes, FailureMode failure_mode) {
compositor_delegate_.Reset();
- compositor_delegate_.set_use_null_layer_tree_frame_sink(
- use_null_layer_tree_frame_sink);
- compositor_delegate_.set_num_failures_before_success(
- failure_mode == NO_FAILURE ? 0 : 1);
- render_widget_compositor_.SetUp(expected_successes, failure_mode);
+ // 6 is just an artibrary "large" number to show it keeps trying.
+ const int kTries = 6;
+ // If it should fail, then it will fail every attempt, otherwise it fails
+ // until the last attempt.
+ int tries_before_success = kTries - (expected_successes ? 1 : 0);
+ switch (failure_mode) {
+ case NO_FAILURE:
+ compositor_delegate_.set_num_failures_before_success(0);
+ compositor_delegate_.set_num_requests_before_success(0);
+ break;
+ case BIND_CONTEXT_FAILURE:
+ compositor_delegate_.set_num_failures_before_success(
+ tries_before_success);
+ compositor_delegate_.set_num_requests_before_success(0);
+ break;
+ case GPU_CHANNEL_FAILURE:
+ compositor_delegate_.set_num_failures_before_success(0);
+ compositor_delegate_.set_num_requests_before_success(
+ tries_before_success);
+ break;
+ }
+ base::RunLoop run_loop;
+ render_widget_compositor_.SetUp(expected_successes, kTries, failure_mode,
+ &run_loop);
render_widget_compositor_.SetVisible(true);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&RenderWidgetLayerTreeFrameSink::SynchronousComposite,
base::Unretained(&render_widget_compositor_)));
- base::RunLoop().Run();
- render_widget_compositor_.AfterTest();
+ run_loop.Run();
}
protected:
@@ -286,33 +292,109 @@ class RenderWidgetLayerTreeFrameSinkTest : public testing::Test {
};
TEST_F(RenderWidgetLayerTreeFrameSinkTest, SucceedOnce) {
- RunTest(false, 1, NO_FAILURE);
+ RunTest(1, NO_FAILURE);
+}
+
+TEST_F(RenderWidgetLayerTreeFrameSinkTest, SucceedOnce_AfterNullChannel) {
+ RunTest(1, GPU_CHANNEL_FAILURE);
+}
+
+TEST_F(RenderWidgetLayerTreeFrameSinkTest, SucceedOnce_AfterLostContext) {
+ RunTest(1, BIND_CONTEXT_FAILURE);
}
TEST_F(RenderWidgetLayerTreeFrameSinkTest, SucceedTwice) {
- RunTest(false, 2, NO_FAILURE);
+ RunTest(2, NO_FAILURE);
}
-TEST_F(RenderWidgetLayerTreeFrameSinkTest, FailOnceNull) {
- RunTest(true, 1, NO_FAILURE);
+TEST_F(RenderWidgetLayerTreeFrameSinkTest, SucceedTwice_AfterNullChannel) {
+ RunTest(2, GPU_CHANNEL_FAILURE);
}
-// Android doesn't support fallback frame sinks. (crbug.com/721102)
-#if !defined(OS_ANDROID)
-TEST_F(RenderWidgetLayerTreeFrameSinkTest, SoftwareFallbackSucceed) {
- RunTest(false, 1, GPU_CHANNEL_FAILURE);
+TEST_F(RenderWidgetLayerTreeFrameSinkTest, SucceedTwice_AfterLostContext) {
+ RunTest(2, BIND_CONTEXT_FAILURE);
+}
+
+TEST_F(RenderWidgetLayerTreeFrameSinkTest, FailWithNullChannel) {
+ RunTest(0, GPU_CHANNEL_FAILURE);
}
-TEST_F(RenderWidgetLayerTreeFrameSinkTest, FallbackSuccessNull) {
- RunTest(true, 1, GPU_CHANNEL_FAILURE);
+TEST_F(RenderWidgetLayerTreeFrameSinkTest, FailWithLostContext) {
+ RunTest(0, BIND_CONTEXT_FAILURE);
}
-TEST_F(RenderWidgetLayerTreeFrameSinkTest, FallbackSuccessNormalSuccess) {
- // The first success is a fallback, but the next should not be a fallback.
- RunTest(false, 1, GPU_CHANNEL_FAILURE);
- RunTest(false, 1, NO_FAILURE);
+class VisibilityTestRenderWidgetCompositor : public RenderWidgetCompositor {
+ public:
+ VisibilityTestRenderWidgetCompositor(
+ StubRenderWidgetCompositorDelegate* delegate,
+ CompositorDependencies* compositor_deps)
+ : RenderWidgetCompositor(delegate, compositor_deps) {}
+
+ void RequestNewLayerTreeFrameSink() override {
+ RenderWidgetCompositor::RequestNewLayerTreeFrameSink();
+ num_requests_sent_++;
+ if (run_loop_)
+ run_loop_->Quit();
+ }
+
+ void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
+ int num_requests_sent() { return num_requests_sent_; }
+
+ private:
+ int num_requests_sent_ = 0;
+ base::RunLoop* run_loop_;
+};
+
+TEST(RenderWidgetCompositorTest, VisibilityTest) {
+ // Test that RenderWidgetCompositor does not retry FrameSink request while
+ // invisible.
+
+ base::MessageLoop message_loop;
+
+ FakeCompositorDependencies compositor_deps;
+ // Synchronously callback with null FrameSink.
+ StubRenderWidgetCompositorDelegate compositor_delegate;
+ VisibilityTestRenderWidgetCompositor render_widget_compositor(
+ &compositor_delegate, &compositor_deps);
+
+ auto animation_host = cc::AnimationHost::CreateMainInstance();
+ ScreenInfo dummy_screen_info;
+ const float initial_device_scale_factor = 1.f;
+ auto layer_tree_host = RenderWidgetCompositor::CreateLayerTreeHost(
+ &render_widget_compositor, &render_widget_compositor,
+ animation_host.get(), &compositor_deps, initial_device_scale_factor,
+ dummy_screen_info);
+ render_widget_compositor.Initialize(std::move(layer_tree_host),
+ std::move(animation_host));
+
+ {
+ // Make one request and stop immediately while invisible.
+ base::RunLoop run_loop;
+ render_widget_compositor.set_run_loop(&run_loop);
+ render_widget_compositor.SetVisible(false);
+ render_widget_compositor.RequestNewLayerTreeFrameSink();
+ run_loop.Run();
+ render_widget_compositor.set_run_loop(nullptr);
+ EXPECT_EQ(1, render_widget_compositor.num_requests_sent());
+ }
+
+ {
+ // Make sure there are no more requests.
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ EXPECT_EQ(1, render_widget_compositor.num_requests_sent());
+ }
+
+ {
+ // Becoming visible retries request.
+ base::RunLoop run_loop;
+ render_widget_compositor.set_run_loop(&run_loop);
+ render_widget_compositor.SetVisible(true);
+ run_loop.Run();
+ render_widget_compositor.set_run_loop(nullptr);
+ EXPECT_EQ(2, render_widget_compositor.num_requests_sent());
+ }
}
-#endif
// Verify desktop memory limit calculations.
#if !defined(OS_ANDROID)
diff --git a/chromium/content/renderer/history_entry.cc b/chromium/content/renderer/history_entry.cc
index bbf9c06832a..a95f235dc6b 100644
--- a/chromium/content/renderer/history_entry.cc
+++ b/chromium/content/renderer/history_entry.cc
@@ -47,7 +47,7 @@ namespace content {
HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild(
const WebHistoryItem& item) {
- children_.push_back(base::MakeUnique<HistoryNode>(entry_, item));
+ children_.push_back(std::make_unique<HistoryNode>(entry_, item));
return children_.back().get();
}
diff --git a/chromium/content/renderer/history_serialization.cc b/chromium/content/renderer/history_serialization.cc
index f9bfc08f311..0c29a57834b 100644
--- a/chromium/content/renderer/history_serialization.cc
+++ b/chromium/content/renderer/history_serialization.cc
@@ -8,10 +8,10 @@
#include <algorithm>
#include "base/strings/nullable_string16.h"
-#include "content/child/web_url_request_util.h"
#include "content/common/page_state_serialization.h"
#include "content/public/common/page_state.h"
#include "content/renderer/history_entry.h"
+#include "content/renderer/loader/web_url_request_util.h"
#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebFloatPoint.h"
#include "third_party/WebKit/public/platform/WebHTTPBody.h"
@@ -65,6 +65,12 @@ void GenerateFrameStateFromItem(const WebHistoryItem& item,
state->http_body.request_body = GetRequestBodyForWebHTTPBody(http_body);
state->http_body.contains_passwords = http_body.ContainsPasswordData();
}
+
+ blink::ScrollAnchorData anchor = item.GetScrollAnchorData();
+ state->scroll_anchor_selector =
+ WebString::ToOptionalString16(anchor.selector_);
+ state->scroll_anchor_offset = anchor.offset_;
+ state->scroll_anchor_simhash = anchor.simhash_;
}
void RecursivelyGenerateHistoryItem(const ExplodedFrameState& state,
@@ -107,6 +113,10 @@ void RecursivelyGenerateHistoryItem(const ExplodedFrameState& state,
item.SetHTTPBody(
GetWebHTTPBodyForRequestBody(state.http_body.request_body));
}
+
+ item.SetScrollAnchorData({WebString::FromUTF16(state.scroll_anchor_selector),
+ state.scroll_anchor_offset,
+ state.scroll_anchor_simhash});
node->set_item(item);
for (size_t i = 0; i < state.children.size(); ++i)
diff --git a/chromium/content/renderer/idle_user_detector.cc b/chromium/content/renderer/idle_user_detector.cc
index 4414b9638af..74799834fff 100644
--- a/chromium/content/renderer/idle_user_detector.cc
+++ b/chromium/content/renderer/idle_user_detector.cc
@@ -26,7 +26,7 @@ bool IdleUserDetector::OnMessageReceived(const IPC::Message& message) {
void IdleUserDetector::ActivityDetected() {
if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) {
RenderThreadImpl* render_thread = RenderThreadImpl::current();
- if (render_thread != NULL) {
+ if (render_thread != nullptr) {
render_thread->PostponeIdleNotification();
}
}
diff --git a/chromium/content/renderer/image_downloader/image_downloader_base.cc b/chromium/content/renderer/image_downloader/image_downloader_base.cc
index 72e91ccad9f..4101c8dbe45 100644
--- a/chromium/content/renderer/image_downloader/image_downloader_base.cc
+++ b/chromium/content/renderer/image_downloader/image_downloader_base.cc
@@ -15,14 +15,13 @@
#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/WebKit/public/platform/WebCachePolicy.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
+#include "third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "ui/gfx/favicon_size.h"
#include "ui/gfx/geometry/size.h"
#include "url/url_constants.h"
-using blink::WebCachePolicy;
using blink::WebFrame;
using blink::WebURLRequest;
@@ -90,12 +89,12 @@ bool ImageDownloaderBase::FetchImage(const GURL& image_url,
// Create an image resource fetcher and assign it with a call back object.
image_fetchers_.push_back(
- base::MakeUnique<MultiResolutionImageResourceFetcher>(
+ std::make_unique<MultiResolutionImageResourceFetcher>(
image_url, frame, 0,
is_favicon ? WebURLRequest::kRequestContextFavicon
: WebURLRequest::kRequestContextImage,
- bypass_cache ? WebCachePolicy::kBypassingCache
- : WebCachePolicy::kUseProtocolCachePolicy,
+ bypass_cache ? blink::mojom::FetchCacheMode::kBypassCache
+ : blink::mojom::FetchCacheMode::kDefault,
base::Bind(&ImageDownloaderBase::DidFetchImage,
base::Unretained(this), callback)));
return true;
diff --git a/chromium/content/renderer/image_downloader/image_downloader_impl.cc b/chromium/content/renderer/image_downloader/image_downloader_impl.cc
index 3514a92af3c..6a70cc48a18 100644
--- a/chromium/content/renderer/image_downloader/image_downloader_impl.cc
+++ b/chromium/content/renderer/image_downloader/image_downloader_impl.cc
@@ -50,7 +50,7 @@ void FilterAndResizeImagesForMaximalSize(
if (max_image_size == 0)
max_image_size = std::numeric_limits<uint32_t>::max();
- const SkBitmap* min_image = NULL;
+ const SkBitmap* min_image = nullptr;
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|.
diff --git a/chromium/content/child/indexed_db/OWNERS b/chromium/content/renderer/indexed_db/OWNERS
index bbe466e537d..bbe466e537d 100644
--- a/chromium/content/child/indexed_db/OWNERS
+++ b/chromium/content/renderer/indexed_db/OWNERS
diff --git a/chromium/content/child/indexed_db/indexed_db_callbacks_impl.cc b/chromium/content/renderer/indexed_db/indexed_db_callbacks_impl.cc
index b20040d0de1..f1c36388119 100644
--- a/chromium/content/child/indexed_db/indexed_db_callbacks_impl.cc
+++ b/chromium/content/renderer/indexed_db/indexed_db_callbacks_impl.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/child/indexed_db/indexed_db_callbacks_impl.h"
+#include "content/renderer/indexed_db/indexed_db_callbacks_impl.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/indexed_db/indexed_db_dispatcher.h"
-#include "content/child/indexed_db/indexed_db_key_builders.h"
-#include "content/child/indexed_db/webidbcursor_impl.h"
-#include "content/child/indexed_db/webidbdatabase_impl.h"
#include "content/common/indexed_db/indexed_db_constants.h"
+#include "content/renderer/indexed_db/indexed_db_dispatcher.h"
+#include "content/renderer/indexed_db/indexed_db_key_builders.h"
+#include "content/renderer/indexed_db/webidbcursor_impl.h"
+#include "content/renderer/indexed_db/webidbdatabase_impl.h"
#include "third_party/WebKit/public/platform/FilePathConversion.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBCallbacks.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseError.h"
@@ -92,12 +92,11 @@ void IndexedDBCallbacksImpl::ConvertValue(
WebString::FromUTF16(info->file->name),
WebString::FromUTF16(info->mime_type),
info->file->last_modified.ToDoubleT(), info->size,
- info->blob.PassInterface().PassHandle());
+ info->blob.PassHandle());
} else {
- local_blob_info[i] =
- WebBlobInfo(WebString::FromUTF8(info->uuid),
- WebString::FromUTF16(info->mime_type), info->size,
- info->blob.PassInterface().PassHandle());
+ local_blob_info[i] = WebBlobInfo(WebString::FromUTF8(info->uuid),
+ WebString::FromUTF16(info->mime_type),
+ info->size, info->blob.PassHandle());
}
}
diff --git a/chromium/content/child/indexed_db/indexed_db_callbacks_impl.h b/chromium/content/renderer/indexed_db/indexed_db_callbacks_impl.h
index cfdf6655287..31e24f8ed3c 100644
--- a/chromium/content/child/indexed_db/indexed_db_callbacks_impl.h
+++ b/chromium/content/renderer/indexed_db/indexed_db_callbacks_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_INDEXED_DB_INDEXED_DB_CALLBACKS_IMPL_H_
-#define CONTENT_CHILD_INDEXED_DB_INDEXED_DB_CALLBACKS_IMPL_H_
+#ifndef CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_CALLBACKS_IMPL_H_
+#define CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_CALLBACKS_IMPL_H_
#include "base/single_thread_task_runner.h"
#include "content/common/indexed_db/indexed_db.mojom.h"
@@ -121,4 +121,4 @@ class IndexedDBCallbacksImpl : public indexed_db::mojom::Callbacks {
} // namespace content
-#endif // CONTENT_CHILD_INDEXED_DB_INDEXED_DB_CALLBACKS_IMPL_H_
+#endif // CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_CALLBACKS_IMPL_H_
diff --git a/chromium/content/child/indexed_db/indexed_db_database_callbacks_impl.cc b/chromium/content/renderer/indexed_db/indexed_db_database_callbacks_impl.cc
index e5fce1d3d5a..af8c6f45c3a 100644
--- a/chromium/content/child/indexed_db/indexed_db_database_callbacks_impl.cc
+++ b/chromium/content/renderer/indexed_db/indexed_db_database_callbacks_impl.cc
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/indexed_db/indexed_db_database_callbacks_impl.h"
+#include "content/renderer/indexed_db/indexed_db_database_callbacks_impl.h"
#include <unordered_map>
#include <utility>
#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/indexed_db/indexed_db_callbacks_impl.h"
-#include "content/child/indexed_db/indexed_db_dispatcher.h"
-#include "content/child/indexed_db/indexed_db_key_builders.h"
+#include "content/renderer/indexed_db/indexed_db_callbacks_impl.h"
+#include "content/renderer/indexed_db/indexed_db_dispatcher.h"
+#include "content/renderer/indexed_db/indexed_db_key_builders.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCallbacks.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseError.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBObservation.h"
diff --git a/chromium/content/child/indexed_db/indexed_db_database_callbacks_impl.h b/chromium/content/renderer/indexed_db/indexed_db_database_callbacks_impl.h
index a466345a3b7..544a90a0259 100644
--- a/chromium/content/child/indexed_db/indexed_db_database_callbacks_impl.h
+++ b/chromium/content/renderer/indexed_db/indexed_db_database_callbacks_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_INDEXED_DB_INDEXED_DB_DATABASE_CALLBACKS_IMPL_H_
-#define CONTENT_CHILD_INDEXED_DB_INDEXED_DB_DATABASE_CALLBACKS_IMPL_H_
+#ifndef CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_DATABASE_CALLBACKS_IMPL_H_
+#define CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_DATABASE_CALLBACKS_IMPL_H_
#include "content/common/indexed_db/indexed_db.mojom.h"
@@ -38,4 +38,4 @@ class IndexedDBDatabaseCallbacksImpl
} // namespace content
-#endif // CONTENT_CHILD_INDEXED_DB_INDEXED_DB_DATABASE_CALLBACKS_IMPL_H_
+#endif // CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_DATABASE_CALLBACKS_IMPL_H_
diff --git a/chromium/content/child/indexed_db/indexed_db_dispatcher.cc b/chromium/content/renderer/indexed_db/indexed_db_dispatcher.cc
index b2e3d160e13..3e2acceb763 100644
--- a/chromium/content/child/indexed_db/indexed_db_dispatcher.cc
+++ b/chromium/content/renderer/indexed_db/indexed_db_dispatcher.cc
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/indexed_db/indexed_db_dispatcher.h"
+#include "content/renderer/indexed_db/indexed_db_dispatcher.h"
#include <utility>
#include "base/lazy_instance.h"
#include "base/memory/ptr_util.h"
#include "base/threading/thread_local.h"
-#include "content/child/indexed_db/indexed_db_key_builders.h"
-#include "content/child/indexed_db/webidbcursor_impl.h"
+#include "content/renderer/indexed_db/indexed_db_key_builders.h"
+#include "content/renderer/indexed_db/webidbcursor_impl.h"
#include "ipc/ipc_channel.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCallbacks.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBObservation.h"
@@ -45,7 +45,7 @@ IndexedDBDispatcher::~IndexedDBDispatcher() {
IndexedDBDispatcher* IndexedDBDispatcher::ThreadSpecificInstance() {
if (g_idb_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
NOTREACHED() << "Re-instantiating TLS IndexedDBDispatcher.";
- g_idb_dispatcher_tls.Pointer()->Set(NULL);
+ g_idb_dispatcher_tls.Pointer()->Set(nullptr);
}
if (g_idb_dispatcher_tls.Pointer()->Get())
return g_idb_dispatcher_tls.Pointer()->Get();
diff --git a/chromium/content/child/indexed_db/indexed_db_dispatcher.h b/chromium/content/renderer/indexed_db/indexed_db_dispatcher.h
index cf0ffcc125e..a7a5922d664 100644
--- a/chromium/content/child/indexed_db/indexed_db_dispatcher.h
+++ b/chromium/content/renderer/indexed_db/indexed_db_dispatcher.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_CHILD_INDEXED_DB_INDEXED_DB_DISPATCHER_H_
-#define CONTENT_CHILD_INDEXED_DB_INDEXED_DB_DISPATCHER_H_
+#ifndef CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_DISPATCHER_H_
+#define CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_DISPATCHER_H_
#include <stddef.h>
#include <stdint.h>
@@ -11,11 +11,11 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/strings/nullable_string16.h"
-#include "content/child/indexed_db/indexed_db_callbacks_impl.h"
-#include "content/child/indexed_db/indexed_db_database_callbacks_impl.h"
#include "content/common/content_export.h"
#include "content/common/indexed_db/indexed_db_constants.h"
-#include "content/public/child/worker_thread.h"
+#include "content/public/renderer/worker_thread.h"
+#include "content/renderer/indexed_db/indexed_db_callbacks_impl.h"
+#include "content/renderer/indexed_db/indexed_db_database_callbacks_impl.h"
#include "ipc/ipc_sync_message_filter.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBCallbacks.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h"
@@ -87,4 +87,4 @@ class CONTENT_EXPORT IndexedDBDispatcher : public WorkerThread::Observer {
} // namespace content
-#endif // CONTENT_CHILD_INDEXED_DB_INDEXED_DB_DISPATCHER_H_
+#endif // CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_DISPATCHER_H_
diff --git a/chromium/content/child/indexed_db/indexed_db_key_builders.cc b/chromium/content/renderer/indexed_db/indexed_db_key_builders.cc
index e8345e90051..b9e2eac0aa7 100644
--- a/chromium/content/child/indexed_db/indexed_db_key_builders.cc
+++ b/chromium/content/renderer/indexed_db/indexed_db_key_builders.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/child/indexed_db/indexed_db_key_builders.h"
+#include "content/renderer/indexed_db/indexed_db_key_builders.h"
#include <stddef.h>
diff --git a/chromium/content/child/indexed_db/indexed_db_key_builders.h b/chromium/content/renderer/indexed_db/indexed_db_key_builders.h
index fd88b74c748..a70aa13f5e0 100644
--- a/chromium/content/child/indexed_db/indexed_db_key_builders.h
+++ b/chromium/content/renderer/indexed_db/indexed_db_key_builders.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_CHILD_INDEXED_DB_INDEXED_DB_KEY_BUILDERS_H_
-#define CONTENT_CHILD_INDEXED_DB_INDEXED_DB_KEY_BUILDERS_H_
+#ifndef CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_KEY_BUILDERS_H_
+#define CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_KEY_BUILDERS_H_
#include "base/macros.h"
#include "content/common/content_export.h"
@@ -70,4 +70,4 @@ class CONTENT_EXPORT WebIDBKeyPathBuilder {
} // namespace content
-#endif // CONTENT_CHILD_INDEXED_DB_INDEXED_DB_KEY_BUILDERS_H_
+#endif // CONTENT_RENDERER_INDEXED_DB_INDEXED_DB_KEY_BUILDERS_H_
diff --git a/chromium/content/child/indexed_db/mock_webidbcallbacks.cc b/chromium/content/renderer/indexed_db/mock_webidbcallbacks.cc
index faa4113b067..9d56cfde61b 100644
--- a/chromium/content/child/indexed_db/mock_webidbcallbacks.cc
+++ b/chromium/content/renderer/indexed_db/mock_webidbcallbacks.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/child/indexed_db/mock_webidbcallbacks.h"
+#include "content/renderer/indexed_db/mock_webidbcallbacks.h"
namespace content {
diff --git a/chromium/content/child/indexed_db/mock_webidbcallbacks.h b/chromium/content/renderer/indexed_db/mock_webidbcallbacks.h
index 4f756b65af2..5cbba7add4d 100644
--- a/chromium/content/child/indexed_db/mock_webidbcallbacks.h
+++ b/chromium/content/renderer/indexed_db/mock_webidbcallbacks.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_CHILD_INDEXED_DB_MOCK_WEBIDBCALLBACKS_H_
-#define CONTENT_CHILD_INDEXED_DB_MOCK_WEBIDBCALLBACKS_H_
+#ifndef CONTENT_RENDERER_INDEXED_DB_MOCK_WEBIDBCALLBACKS_H_
+#define CONTENT_RENDERER_INDEXED_DB_MOCK_WEBIDBCALLBACKS_H_
#include "base/macros.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -53,4 +53,4 @@ class MockWebIDBCallbacks : public blink::WebIDBCallbacks {
} // namespace content
-#endif // CONTENT_CHILD_INDEXED_DB_MOCK_WEBIDBCALLBACKS_H_
+#endif // CONTENT_RENDERER_INDEXED_DB_MOCK_WEBIDBCALLBACKS_H_
diff --git a/chromium/content/child/indexed_db/webidbcursor_impl.cc b/chromium/content/renderer/indexed_db/webidbcursor_impl.cc
index 0710320b161..f828457c62f 100644
--- a/chromium/content/child/indexed_db/webidbcursor_impl.cc
+++ b/chromium/content/renderer/indexed_db/webidbcursor_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/indexed_db/webidbcursor_impl.h"
+#include "content/renderer/indexed_db/webidbcursor_impl.h"
#include <stddef.h>
@@ -10,8 +10,8 @@
#include <vector>
#include "base/memory/ptr_util.h"
-#include "content/child/indexed_db/indexed_db_dispatcher.h"
-#include "content/child/indexed_db/indexed_db_key_builders.h"
+#include "content/renderer/indexed_db/indexed_db_dispatcher.h"
+#include "content/renderer/indexed_db/indexed_db_key_builders.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBValue.h"
@@ -91,7 +91,7 @@ void WebIDBCursorImpl::Advance(unsigned long count,
IndexedDBDispatcher::ThreadSpecificInstance()->ResetCursorPrefetchCaches(
transaction_id_, this);
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
std::move(callbacks), transaction_id_, weak_factory_.GetWeakPtr(),
io_runner_);
io_runner_->PostTask(
@@ -120,7 +120,7 @@ void WebIDBCursorImpl::Continue(const WebIDBKey& key,
// Request pre-fetch.
++pending_onsuccess_callbacks_;
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
std::move(callbacks), transaction_id_, weak_factory_.GetWeakPtr(),
io_runner_);
io_runner_->PostTask(
@@ -144,7 +144,7 @@ void WebIDBCursorImpl::Continue(const WebIDBKey& key,
IndexedDBDispatcher::ThreadSpecificInstance()->ResetCursorPrefetchCaches(
transaction_id_, this);
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
std::move(callbacks), transaction_id_, weak_factory_.GetWeakPtr(),
io_runner_);
io_runner_->PostTask(
diff --git a/chromium/content/child/indexed_db/webidbcursor_impl.h b/chromium/content/renderer/indexed_db/webidbcursor_impl.h
index 61cccf24dc6..07bf653e645 100644
--- a/chromium/content/child/indexed_db/webidbcursor_impl.h
+++ b/chromium/content/renderer/indexed_db/webidbcursor_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_INDEXED_DB_WEBIDBCURSOR_IMPL_H_
-#define CONTENT_CHILD_INDEXED_DB_WEBIDBCURSOR_IMPL_H_
+#ifndef CONTENT_RENDERER_INDEXED_DB_WEBIDBCURSOR_IMPL_H_
+#define CONTENT_RENDERER_INDEXED_DB_WEBIDBCURSOR_IMPL_H_
#include <stdint.h>
@@ -95,4 +95,4 @@ class CONTENT_EXPORT WebIDBCursorImpl : public blink::WebIDBCursor {
} // namespace content
-#endif // CONTENT_CHILD_INDEXED_DB_WEBIDBCURSOR_IMPL_H_
+#endif // CONTENT_RENDERER_INDEXED_DB_WEBIDBCURSOR_IMPL_H_
diff --git a/chromium/content/child/indexed_db/webidbcursor_impl_unittest.cc b/chromium/content/renderer/indexed_db/webidbcursor_impl_unittest.cc
index 1dba4728b84..fcce315a81c 100644
--- a/chromium/content/child/indexed_db/webidbcursor_impl_unittest.cc
+++ b/chromium/content/renderer/indexed_db/webidbcursor_impl_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/indexed_db/webidbcursor_impl.h"
+#include "content/renderer/indexed_db/webidbcursor_impl.h"
#include <stddef.h>
#include <stdint.h>
@@ -15,10 +15,10 @@
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
-#include "content/child/indexed_db/indexed_db_key_builders.h"
-#include "content/child/indexed_db/mock_webidbcallbacks.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/indexed_db/indexed_db_key.h"
+#include "content/renderer/indexed_db/indexed_db_key_builders.h"
+#include "content/renderer/indexed_db/mock_webidbcallbacks.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebData.h"
@@ -97,8 +97,8 @@ class MockCursorImpl : public Cursor {
class MockContinueCallbacks : public StrictMock<MockWebIDBCallbacks> {
public:
- MockContinueCallbacks(IndexedDBKey* key = 0,
- WebVector<WebBlobInfo>* webBlobInfo = 0)
+ MockContinueCallbacks(IndexedDBKey* key = nullptr,
+ WebVector<WebBlobInfo>* webBlobInfo = nullptr)
: key_(key), web_blob_info_(webBlobInfo) {}
void OnSuccess(const WebIDBKey& key,
@@ -122,9 +122,9 @@ class WebIDBCursorImplTest : public testing::Test {
WebIDBCursorImplTest() {
null_key_.AssignNull();
indexed_db::mojom::CursorAssociatedPtr ptr;
- mock_cursor_ =
- base::MakeUnique<MockCursorImpl>(mojo::MakeIsolatedRequest(&ptr));
- cursor_ = base::MakeUnique<WebIDBCursorImpl>(
+ mock_cursor_ = std::make_unique<MockCursorImpl>(
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&ptr));
+ cursor_ = std::make_unique<WebIDBCursorImpl>(
ptr.PassInterface(), 1, base::ThreadTaskRunnerHandle::Get());
}
diff --git a/chromium/content/child/indexed_db/webidbdatabase_impl.cc b/chromium/content/renderer/indexed_db/webidbdatabase_impl.cc
index 48bb3b61645..bc7cbea06b4 100644
--- a/chromium/content/child/indexed_db/webidbdatabase_impl.cc
+++ b/chromium/content/renderer/indexed_db/webidbdatabase_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/indexed_db/webidbdatabase_impl.h"
+#include "content/renderer/indexed_db/webidbdatabase_impl.h"
#include <stddef.h>
@@ -13,9 +13,9 @@
#include "base/memory/ptr_util.h"
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
-#include "content/child/indexed_db/indexed_db_callbacks_impl.h"
-#include "content/child/indexed_db/indexed_db_dispatcher.h"
-#include "content/child/indexed_db/indexed_db_key_builders.h"
+#include "content/renderer/indexed_db/indexed_db_callbacks_impl.h"
+#include "content/renderer/indexed_db/indexed_db_dispatcher.h"
+#include "content/renderer/indexed_db/indexed_db_key_builders.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "third_party/WebKit/public/platform/FilePathConversion.h"
#include "third_party/WebKit/public/platform/WebBlobInfo.h"
@@ -264,7 +264,7 @@ void WebIDBDatabaseImpl::Get(long long transaction_id,
IndexedDBDispatcher::ThreadSpecificInstance()->ResetCursorPrefetchCaches(
transaction_id, nullptr);
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), transaction_id, nullptr, io_runner_);
io_runner_->PostTask(
FROM_HERE, base::BindOnce(&IOThreadHelper::Get, base::Unretained(helper_),
@@ -283,7 +283,7 @@ void WebIDBDatabaseImpl::GetAll(long long transaction_id,
IndexedDBDispatcher::ThreadSpecificInstance()->ResetCursorPrefetchCaches(
transaction_id, nullptr);
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), transaction_id, nullptr, io_runner_);
io_runner_->PostTask(
FROM_HERE,
@@ -339,12 +339,12 @@ void WebIDBDatabaseImpl::Put(long long transaction_id,
blob_info->uuid = info.Uuid().Latin1();
DCHECK(blob_info->uuid.size());
blob_info->mime_type = info.GetType().Utf16();
- blob_info->blob.Bind(storage::mojom::BlobPtrInfo(
- info.CloneBlobHandle(), storage::mojom::Blob::Version_));
+ blob_info->blob = blink::mojom::BlobPtrInfo(info.CloneBlobHandle(),
+ blink::mojom::Blob::Version_);
mojo_value->blob_or_file_info.push_back(std::move(blob_info));
}
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), transaction_id, nullptr, io_runner_);
io_runner_->PostTask(
FROM_HERE,
@@ -391,7 +391,7 @@ void WebIDBDatabaseImpl::OpenCursor(long long transaction_id,
IndexedDBDispatcher::ThreadSpecificInstance()->ResetCursorPrefetchCaches(
transaction_id, nullptr);
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), transaction_id, nullptr, io_runner_);
io_runner_->PostTask(
FROM_HERE,
@@ -409,7 +409,7 @@ void WebIDBDatabaseImpl::Count(long long transaction_id,
IndexedDBDispatcher::ThreadSpecificInstance()->ResetCursorPrefetchCaches(
transaction_id, nullptr);
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), transaction_id, nullptr, io_runner_);
io_runner_->PostTask(
FROM_HERE,
@@ -426,7 +426,7 @@ void WebIDBDatabaseImpl::DeleteRange(long long transaction_id,
IndexedDBDispatcher::ThreadSpecificInstance()->ResetCursorPrefetchCaches(
transaction_id, nullptr);
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), transaction_id, nullptr, io_runner_);
io_runner_->PostTask(
FROM_HERE,
@@ -442,7 +442,7 @@ void WebIDBDatabaseImpl::Clear(long long transaction_id,
IndexedDBDispatcher::ThreadSpecificInstance()->ResetCursorPrefetchCaches(
transaction_id, nullptr);
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), transaction_id, nullptr, io_runner_);
io_runner_->PostTask(
FROM_HERE,
diff --git a/chromium/content/child/indexed_db/webidbdatabase_impl.h b/chromium/content/renderer/indexed_db/webidbdatabase_impl.h
index 6b34bf31fe3..d5ebc00b97d 100644
--- a/chromium/content/child/indexed_db/webidbdatabase_impl.h
+++ b/chromium/content/renderer/indexed_db/webidbdatabase_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_INDEXED_DB_WEBIDBDATABASE_IMPL_H_
-#define CONTENT_CHILD_INDEXED_DB_WEBIDBDATABASE_IMPL_H_
+#ifndef CONTENT_RENDERER_INDEXED_DB_WEBIDBDATABASE_IMPL_H_
+#define CONTENT_RENDERER_INDEXED_DB_WEBIDBDATABASE_IMPL_H_
#include <stdint.h>
@@ -148,4 +148,4 @@ class CONTENT_EXPORT WebIDBDatabaseImpl : public blink::WebIDBDatabase {
} // namespace content
-#endif // CONTENT_CHILD_INDEXED_DB_WEBIDBDATABASE_IMPL_H_
+#endif // CONTENT_RENDERER_INDEXED_DB_WEBIDBDATABASE_IMPL_H_
diff --git a/chromium/content/child/indexed_db/webidbdatabase_impl_unittest.cc b/chromium/content/renderer/indexed_db/webidbdatabase_impl_unittest.cc
index 58149445bc7..016c38425a5 100644
--- a/chromium/content/child/indexed_db/webidbdatabase_impl_unittest.cc
+++ b/chromium/content/renderer/indexed_db/webidbdatabase_impl_unittest.cc
@@ -9,11 +9,11 @@
#include "base/macros.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/indexed_db/mock_webidbcallbacks.h"
-#include "content/child/indexed_db/webidbdatabase_impl.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/indexed_db/indexed_db_key.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/renderer/indexed_db/mock_webidbcallbacks.h"
+#include "content/renderer/indexed_db/webidbdatabase_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebBlobInfo.h"
#include "third_party/WebKit/public/platform/WebData.h"
diff --git a/chromium/content/child/indexed_db/webidbfactory_impl.cc b/chromium/content/renderer/indexed_db/webidbfactory_impl.cc
index a10f56bb942..38854fa395d 100644
--- a/chromium/content/child/indexed_db/webidbfactory_impl.cc
+++ b/chromium/content/renderer/indexed_db/webidbfactory_impl.cc
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/indexed_db/webidbfactory_impl.h"
+#include "content/renderer/indexed_db/webidbfactory_impl.h"
#include "base/memory/ptr_util.h"
-#include "content/child/indexed_db/indexed_db_callbacks_impl.h"
-#include "content/child/indexed_db/indexed_db_database_callbacks_impl.h"
-#include "content/child/storage_util.h"
+#include "content/renderer/indexed_db/indexed_db_callbacks_impl.h"
+#include "content/renderer/indexed_db/indexed_db_database_callbacks_impl.h"
+#include "content/renderer/storage_util.h"
#include "ipc/ipc_sync_channel.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
@@ -67,7 +67,7 @@ WebIDBFactoryImpl::~WebIDBFactoryImpl() {
void WebIDBFactoryImpl::GetDatabaseNames(WebIDBCallbacks* callbacks,
const WebSecurityOrigin& origin) {
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), IndexedDBCallbacksImpl::kNoTransaction,
nullptr, io_runner_);
io_runner_->PostTask(
@@ -83,10 +83,10 @@ void WebIDBFactoryImpl::Open(const WebString& name,
WebIDBCallbacks* callbacks,
WebIDBDatabaseCallbacks* database_callbacks,
const WebSecurityOrigin& origin) {
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), transaction_id, nullptr, io_runner_);
auto database_callbacks_impl =
- base::MakeUnique<IndexedDBDatabaseCallbacksImpl>(
+ std::make_unique<IndexedDBDatabaseCallbacksImpl>(
base::WrapUnique(database_callbacks));
io_runner_->PostTask(
FROM_HERE,
@@ -100,7 +100,7 @@ void WebIDBFactoryImpl::DeleteDatabase(const WebString& name,
WebIDBCallbacks* callbacks,
const WebSecurityOrigin& origin,
bool force_close) {
- auto callbacks_impl = base::MakeUnique<IndexedDBCallbacksImpl>(
+ auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), IndexedDBCallbacksImpl::kNoTransaction,
nullptr, io_runner_);
io_runner_->PostTask(
diff --git a/chromium/content/child/indexed_db/webidbfactory_impl.h b/chromium/content/renderer/indexed_db/webidbfactory_impl.h
index 9df2173be59..d81c0d8d46c 100644
--- a/chromium/content/child/indexed_db/webidbfactory_impl.h
+++ b/chromium/content/renderer/indexed_db/webidbfactory_impl.h
@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_INDEXED_DB_WEBIDBFACTORY_IMPL_H_
-#define CONTENT_CHILD_INDEXED_DB_WEBIDBFACTORY_IMPL_H_
+#ifndef CONTENT_RENDERER_INDEXED_DB_WEBIDBFACTORY_IMPL_H_
+#define CONTENT_RENDERER_INDEXED_DB_WEBIDBFACTORY_IMPL_H_
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "content/common/indexed_db/indexed_db.mojom.h"
-#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBCallbacks.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCallbacks.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBFactory.h"
@@ -53,4 +52,4 @@ class WebIDBFactoryImpl : public blink::WebIDBFactory {
} // namespace content
-#endif // CONTENT_CHILD_INDEXED_DB_WEBIDBFACTORY_IMPL_H_
+#endif // CONTENT_RENDERER_INDEXED_DB_WEBIDBFACTORY_IMPL_H_
diff --git a/chromium/content/renderer/input/OWNERS b/chromium/content/renderer/input/OWNERS
index 90ec5a03b30..5becb59f9da 100644
--- a/chromium/content/renderer/input/OWNERS
+++ b/chromium/content/renderer/input/OWNERS
@@ -1,4 +1,3 @@
-aelias@chromium.org
dtapuska@chromium.org
tdresser@chromium.org
diff --git a/chromium/content/renderer/input/frame_input_handler_impl.cc b/chromium/content/renderer/input/frame_input_handler_impl.cc
index 95989263dd0..80e1566863c 100644
--- a/chromium/content/renderer/input/frame_input_handler_impl.cc
+++ b/chromium/content/renderer/input/frame_input_handler_impl.cc
@@ -143,6 +143,7 @@ void FrameInputHandlerImpl::SetEditableSelectionOffsets(int32_t start,
}
if (!render_frame_)
return;
+ HandlingState handling_state(render_frame_, UpdateState::kIsSelectingRange);
render_frame_->GetWebFrame()->SetEditableSelectionOffsets(start, end);
}
@@ -268,8 +269,7 @@ void FrameInputHandlerImpl::CollapseSelection() {
if (range.IsNull())
return;
- HandlingState handling_state(render_frame_.get(),
- UpdateState::kIsSelectingRange);
+ HandlingState handling_state(render_frame_, UpdateState::kIsSelectingRange);
render_frame_->GetWebFrame()->SelectRange(
blink::WebRange(range.EndOffset(), 0),
blink::WebLocalFrame::kHideSelectionHandle,
@@ -290,8 +290,7 @@ void FrameInputHandlerImpl::SelectRange(const gfx::Point& base,
if (!render_frame_)
return;
RenderViewImpl* render_view = render_frame_->render_view();
- HandlingState handling_state(render_frame_.get(),
- UpdateState::kIsSelectingRange);
+ HandlingState handling_state(render_frame_, UpdateState::kIsSelectingRange);
render_frame_->GetWebFrame()->SelectRange(
render_view->ConvertWindowPointToViewport(base),
render_view->ConvertWindowPointToViewport(extent));
@@ -320,8 +319,7 @@ void FrameInputHandlerImpl::AdjustSelectionByCharacterOffset(
if (start - end > range.length() || range.StartOffset() + start < 0)
return;
- HandlingState handling_state(render_frame_.get(),
- UpdateState::kIsSelectingRange);
+ HandlingState handling_state(render_frame_, UpdateState::kIsSelectingRange);
// A negative adjust amount moves the selection towards the beginning of
// the document, a positive amount moves the selection towards the end of
// the document.
@@ -343,8 +341,7 @@ void FrameInputHandlerImpl::MoveRangeSelectionExtent(const gfx::Point& extent) {
if (!render_frame_)
return;
- HandlingState handling_state(render_frame_.get(),
- UpdateState::kIsSelectingRange);
+ HandlingState handling_state(render_frame_, UpdateState::kIsSelectingRange);
render_frame_->GetWebFrame()->MoveRangeSelectionExtent(
render_frame_->render_view()->ConvertWindowPointToViewport(extent));
}
@@ -361,8 +358,7 @@ void FrameInputHandlerImpl::ScrollFocusedEditableNodeIntoRect(
if (!render_frame_)
return;
- RenderViewImpl* render_view = render_frame_->render_view();
- render_view->ScrollFocusedEditableNodeIntoRect(rect);
+ render_frame_->ScrollFocusedEditableElementIntoRect(rect);
}
void FrameInputHandlerImpl::MoveCaret(const gfx::Point& point) {
@@ -381,18 +377,20 @@ void FrameInputHandlerImpl::MoveCaret(const gfx::Point& point) {
}
void FrameInputHandlerImpl::GetWidgetInputHandler(
- mojom::WidgetInputHandlerAssociatedRequest interface_request) {
+ mojom::WidgetInputHandlerAssociatedRequest interface_request,
+ mojom::WidgetInputHandlerHostPtr host) {
if (!main_thread_task_runner_->BelongsToCurrentThread()) {
main_thread_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&FrameInputHandlerImpl::GetWidgetInputHandler,
- weak_this_, std::move(interface_request)));
+ weak_this_, std::move(interface_request),
+ std::move(host)));
return;
}
if (!render_frame_)
return;
render_frame_->GetRenderWidget()
->widget_input_handler_manager()
- ->AddAssociatedInterface(std::move(interface_request));
+ ->AddAssociatedInterface(std::move(interface_request), std::move(host));
}
void FrameInputHandlerImpl::ExecuteCommandOnMainThread(
@@ -401,7 +399,7 @@ void FrameInputHandlerImpl::ExecuteCommandOnMainThread(
if (!render_frame_)
return;
- HandlingState handling_state(render_frame_.get(), update_state);
+ HandlingState handling_state(render_frame_, update_state);
render_frame_->GetWebFrame()->ExecuteCommand(
blink::WebString::FromUTF8(command));
}
@@ -425,7 +423,7 @@ void FrameInputHandlerImpl::BindNow(mojom::FrameInputHandlerRequest request) {
}
FrameInputHandlerImpl::HandlingState::HandlingState(
- RenderFrameImpl* render_frame,
+ const base::WeakPtr<RenderFrameImpl>& render_frame,
UpdateState state)
: render_frame_(render_frame),
original_select_range_value_(render_frame->handling_select_range()),
@@ -442,6 +440,9 @@ FrameInputHandlerImpl::HandlingState::HandlingState(
}
FrameInputHandlerImpl::HandlingState::~HandlingState() {
+ // RenderFrame may have been destroyed while this object was on the stack.
+ if (!render_frame_)
+ return;
render_frame_->set_handling_select_range(original_select_range_value_);
render_frame_->set_is_pasting(original_pasting_value_);
}
diff --git a/chromium/content/renderer/input/frame_input_handler_impl.h b/chromium/content/renderer/input/frame_input_handler_impl.h
index 17742d08c9d..be452f97f52 100644
--- a/chromium/content/renderer/input/frame_input_handler_impl.h
+++ b/chromium/content/renderer/input/frame_input_handler_impl.h
@@ -73,7 +73,8 @@ class FrameInputHandlerImpl : public mojom::FrameInputHandler {
void ScrollFocusedEditableNodeIntoRect(const gfx::Rect& rect) override;
void MoveCaret(const gfx::Point& point) override;
void GetWidgetInputHandler(
- mojom::WidgetInputHandlerAssociatedRequest interface_request) override;
+ mojom::WidgetInputHandlerAssociatedRequest interface_request,
+ mojom::WidgetInputHandlerHostPtr host) override;
private:
~FrameInputHandlerImpl() override;
@@ -81,11 +82,12 @@ class FrameInputHandlerImpl : public mojom::FrameInputHandler {
class HandlingState {
public:
- HandlingState(RenderFrameImpl* render_frame, UpdateState state);
+ HandlingState(const base::WeakPtr<RenderFrameImpl>& render_frame,
+ UpdateState state);
~HandlingState();
private:
- RenderFrameImpl* render_frame_;
+ base::WeakPtr<RenderFrameImpl> render_frame_;
bool original_select_range_value_;
bool original_pasting_value_;
};
diff --git a/chromium/content/renderer/input/input_event_filter.cc b/chromium/content/renderer/input/input_event_filter.cc
index 0d504a2543e..90c5ae0e5cc 100644
--- a/chromium/content/renderer/input/input_event_filter.cc
+++ b/chromium/content/renderer/input/input_event_filter.cc
@@ -60,9 +60,9 @@ InputEventFilter::InputEventFilter(
const scoped_refptr<base::SingleThreadTaskRunner>& target_task_runner)
: main_task_runner_(main_task_runner),
main_listener_(main_listener),
- sender_(NULL),
+ sender_(nullptr),
target_task_runner_(target_task_runner),
- input_handler_manager_(NULL) {
+ input_handler_manager_(nullptr) {
DCHECK(target_task_runner_.get());
DCHECK(main_task_runner_->BelongsToCurrentThread());
}
@@ -103,7 +103,7 @@ void InputEventFilter::DidOverscroll(int routing_id,
}
void InputEventFilter::DidStopFlinging(int routing_id) {
- SendMessage(base::MakeUnique<InputHostMsg_DidStopFlinging>(routing_id));
+ SendMessage(std::make_unique<InputHostMsg_DidStopFlinging>(routing_id));
}
void InputEventFilter::QueueClosureForMainThreadEventQueue(
@@ -118,7 +118,6 @@ void InputEventFilter::QueueClosureForMainThreadEventQueue(
// For some reason we didn't find an event queue for the route.
// Don't drop the task on the floor allow it to execute.
- NOTREACHED();
main_task_runner_->PostTask(FROM_HERE, closure);
}
@@ -139,7 +138,7 @@ void InputEventFilter::SetWhiteListedTouchAction(int routing_id,
cc::TouchAction touch_action,
uint32_t unique_touch_event_id,
InputEventAckState ack_state) {
- SendMessage(base::MakeUnique<InputHostMsg_SetWhiteListedTouchAction>(
+ SendMessage(std::make_unique<InputHostMsg_SetWhiteListedTouchAction>(
routing_id, touch_action, unique_touch_event_id, ack_state));
}
@@ -149,11 +148,11 @@ void InputEventFilter::OnFilterAdded(IPC::Channel* channel) {
}
void InputEventFilter::OnFilterRemoved() {
- sender_ = NULL;
+ sender_ = nullptr;
}
void InputEventFilter::OnChannelClosing() {
- sender_ = NULL;
+ sender_ = nullptr;
}
// This function returns true if the IPC message is one that the compositor
diff --git a/chromium/content/renderer/input/input_event_filter.h b/chromium/content/renderer/input/input_event_filter.h
index f0a5f3be0a2..ae0ab45897c 100644
--- a/chromium/content/renderer/input/input_event_filter.h
+++ b/chromium/content/renderer/input/input_event_filter.h
@@ -12,7 +12,7 @@
#include "base/callback.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
#include "content/renderer/input/input_handler_manager_client.h"
#include "content/renderer/input/main_thread_event_queue.h"
#include "ipc/message_filter.h"
diff --git a/chromium/content/renderer/input/input_event_filter_unittest.cc b/chromium/content/renderer/input/input_event_filter_unittest.cc
index 595e4e79eed..e69101230e8 100644
--- a/chromium/content/renderer/input/input_event_filter_unittest.cc
+++ b/chromium/content/renderer/input/input_event_filter_unittest.cc
@@ -46,7 +46,6 @@ const base::TimeDelta kFrameInterval = base::TimeDelta::FromMilliseconds(16);
bool ShouldBlockEventStream(const blink::WebInputEvent& event) {
return ui::WebInputEventTraits::ShouldBlockEventStream(
event,
- base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents),
base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching));
}
@@ -214,7 +213,7 @@ class InputEventFilterTest : public testing::Test,
base::Bind(base::IgnoreResult(&IPCMessageRecorder::OnMessageReceived),
base::Unretained(&message_recorder_)),
main_task_runner_, main_task_runner_);
- event_recorder_ = base::MakeUnique<InputEventRecorder>(filter_.get());
+ event_recorder_ = std::make_unique<InputEventRecorder>(filter_.get());
filter_->SetInputHandlerManager(event_recorder_.get());
filter_->OnFilterAdded(&ipc_sink_);
}
diff --git a/chromium/content/renderer/input/input_handler_manager.cc b/chromium/content/renderer/input/input_handler_manager.cc
index 19b9e758150..f21b297e57e 100644
--- a/chromium/content/renderer/input/input_handler_manager.cc
+++ b/chromium/content/renderer/input/input_handler_manager.cc
@@ -26,8 +26,6 @@ using blink::scheduler::RendererScheduler;
namespace content {
-namespace {
-
InputEventAckState InputEventDispositionToAck(
InputHandlerProxy::EventDisposition disposition) {
switch (disposition) {
@@ -48,8 +46,6 @@ InputEventAckState InputEventDispositionToAck(
return INPUT_EVENT_ACK_STATE_UNKNOWN;
}
-} // namespace
-
InputHandlerManager::InputHandlerManager(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
InputHandlerManagerClient* client,
diff --git a/chromium/content/renderer/input/input_handler_manager.h b/chromium/content/renderer/input/input_handler_manager.h
index ed11376affc..40e32e671d2 100644
--- a/chromium/content/renderer/input/input_handler_manager.h
+++ b/chromium/content/renderer/input/input_handler_manager.h
@@ -10,7 +10,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
#include "content/renderer/render_view_impl.h"
#include "ui/events/blink/input_handler_proxy.h"
@@ -44,6 +44,9 @@ class InputHandlerManagerClient;
class MainThreadEventQueue;
class SynchronousInputHandlerProxyClient;
+InputEventAckState InputEventDispositionToAck(
+ ui::InputHandlerProxy::EventDisposition disposition);
+
// InputHandlerManager class manages InputHandlerProxy instances for
// the WebViews in this renderer.
class CONTENT_EXPORT InputHandlerManager {
diff --git a/chromium/content/renderer/input/input_handler_manager_client.h b/chromium/content/renderer/input/input_handler_manager_client.h
index 4802e5458cd..c155b0a3320 100644
--- a/chromium/content/renderer/input/input_handler_manager_client.h
+++ b/chromium/content/renderer/input/input_handler_manager_client.h
@@ -10,7 +10,7 @@
#include "base/macros.h"
#include "cc/input/touch_action.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
#include "third_party/WebKit/public/platform/WebInputEventResult.h"
#include "ui/events/blink/web_input_event_traits.h"
#include "ui/gfx/geometry/vector2d_f.h"
diff --git a/chromium/content/renderer/input/input_handler_wrapper.cc b/chromium/content/renderer/input/input_handler_wrapper.cc
index 8b8768729c1..af23c3f798e 100644
--- a/chromium/content/renderer/input/input_handler_wrapper.cc
+++ b/chromium/content/renderer/input/input_handler_wrapper.cc
@@ -76,13 +76,13 @@ void InputHandlerWrapper::DidOverscroll(
const gfx::Vector2dF& latest_overscroll_delta,
const gfx::Vector2dF& current_fling_velocity,
const gfx::PointF& causal_event_viewport_point,
- const cc::ScrollBoundaryBehavior& scroll_boundary_behavior) {
+ const cc::OverscrollBehavior& overscroll_behavior) {
ui::DidOverscrollParams params;
params.accumulated_overscroll = accumulated_overscroll;
params.latest_overscroll_delta = latest_overscroll_delta;
params.current_fling_velocity = current_fling_velocity;
params.causal_event_viewport_point = causal_event_viewport_point;
- params.scroll_boundary_behavior = scroll_boundary_behavior;
+ params.overscroll_behavior = overscroll_behavior;
input_handler_manager_->DidOverscroll(routing_id_, params);
}
diff --git a/chromium/content/renderer/input/input_handler_wrapper.h b/chromium/content/renderer/input/input_handler_wrapper.h
index ec4175a50bd..4f849f8de70 100644
--- a/chromium/content/renderer/input/input_handler_wrapper.h
+++ b/chromium/content/renderer/input/input_handler_wrapper.h
@@ -54,7 +54,7 @@ class InputHandlerWrapper : public ui::InputHandlerProxyClient {
const gfx::Vector2dF& latest_overscroll_delta,
const gfx::Vector2dF& current_fling_velocity,
const gfx::PointF& causal_event_viewport_point,
- const cc::ScrollBoundaryBehavior& scroll_boundary_behavior) override;
+ const cc::OverscrollBehavior& overscroll_behavior) override;
void DidStopFlinging() override;
void DidAnimateForInput() override;
void GenerateScrollBeginAndSendToMainThread(
diff --git a/chromium/content/renderer/input/main_thread_event_queue.cc b/chromium/content/renderer/input/main_thread_event_queue.cc
index 46ec788812b..a9efa0cdead 100644
--- a/chromium/content/renderer/input/main_thread_event_queue.cc
+++ b/chromium/content/renderer/input/main_thread_event_queue.cc
@@ -238,13 +238,8 @@ MainThreadEventQueue::MainThreadEventQueue(
enable_non_blocking_due_to_main_thread_responsiveness_flag_(
base::FeatureList::IsEnabled(
features::kMainThreadBusyScrollIntervention)),
- handle_raf_aligned_touch_input_(
- allow_raf_aligned_input &&
- base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents)),
- handle_raf_aligned_mouse_input_(
- allow_raf_aligned_input &&
- base::FeatureList::IsEnabled(features::kRafAlignedMouseInputEvents)),
needs_low_latency_(false),
+ allow_raf_aligned_input_(allow_raf_aligned_input),
main_task_runner_(main_task_runner),
renderer_scheduler_(renderer_scheduler),
use_raf_fallback_timer_(true) {
@@ -379,8 +374,6 @@ void MainThreadEventQueue::QueueClosure(base::OnceClosure closure) {
}
void MainThreadEventQueue::PossiblyScheduleMainFrame() {
- if (IsRafAlignedInputDisabled())
- return;
bool needs_main_frame = false;
{
base::AutoLock lock(shared_state_lock_);
@@ -447,9 +440,6 @@ void MainThreadEventQueue::RafFallbackTimerFired() {
}
void MainThreadEventQueue::DispatchRafAlignedInput(base::TimeTicks frame_time) {
- if (IsRafAlignedInputDisabled())
- return;
-
raf_fallback_timer_.Stop();
size_t queue_size_at_start;
@@ -471,8 +461,7 @@ void MainThreadEventQueue::DispatchRafAlignedInput(base::TimeTicks frame_time) {
if (IsRafAlignedEvent(shared_state_.events_.front())) {
// Throttle touchmoves that are async.
- if (handle_raf_aligned_touch_input_ &&
- IsAsyncTouchMove(shared_state_.events_.front())) {
+ if (IsAsyncTouchMove(shared_state_.events_.front())) {
if (shared_state_.events_.size() == 1 &&
frame_time < shared_state_.last_async_touch_move_timestamp_ +
kAsyncTouchMoveInterval) {
@@ -523,10 +512,6 @@ void MainThreadEventQueue::QueueEvent(
SetNeedsMainFrame();
}
-bool MainThreadEventQueue::IsRafAlignedInputDisabled() const {
- return !handle_raf_aligned_mouse_input_ && !handle_raf_aligned_touch_input_;
-}
-
bool MainThreadEventQueue::IsRafAlignedEvent(
const std::unique_ptr<MainThreadEventQueueTask>& item) const {
if (!item->IsWebInputEvent())
@@ -536,9 +521,9 @@ bool MainThreadEventQueue::IsRafAlignedEvent(
switch (event->event().GetType()) {
case blink::WebInputEvent::kMouseMove:
case blink::WebInputEvent::kMouseWheel:
- return handle_raf_aligned_mouse_input_ && !needs_low_latency_;
case blink::WebInputEvent::kTouchMove:
- return handle_raf_aligned_touch_input_ && !needs_low_latency_;
+ return allow_raf_aligned_input_ && !needs_low_latency_ &&
+ !needs_low_latency_until_pointer_up_;
default:
return false;
}
@@ -550,6 +535,21 @@ void MainThreadEventQueue::HandleEventOnMainThread(
HandledEventCallback handled_callback) {
if (client_)
client_->HandleInputEvent(event, latency, std::move(handled_callback));
+
+ if (needs_low_latency_until_pointer_up_) {
+ // Reset the needs low latency until pointer up mode if necessary.
+ switch (event.Event().GetType()) {
+ case blink::WebInputEvent::kMouseUp:
+ case blink::WebInputEvent::kTouchCancel:
+ case blink::WebInputEvent::kTouchEnd:
+ case blink::WebInputEvent::kPointerCancel:
+ case blink::WebInputEvent::kPointerUp:
+ needs_low_latency_until_pointer_up_ = false;
+ break;
+ default:
+ break;
+ }
+ }
}
void MainThreadEventQueue::SetNeedsMainFrame() {
@@ -578,4 +578,8 @@ void MainThreadEventQueue::SetNeedsLowLatency(bool low_latency) {
needs_low_latency_ = low_latency;
}
+void MainThreadEventQueue::RequestUnbufferedInputEvents() {
+ needs_low_latency_until_pointer_up_ = true;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/input/main_thread_event_queue.h b/chromium/content/renderer/input/main_thread_event_queue.h
index d2b434eabb5..509609b119e 100644
--- a/chromium/content/renderer/input/main_thread_event_queue.h
+++ b/chromium/content/renderer/input/main_thread_event_queue.h
@@ -10,9 +10,9 @@
#include "base/single_thread_task_runner.h"
#include "cc/input/touch_action.h"
#include "content/common/content_export.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/common/input/input_event_dispatch_type.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/input_event_ack_state.h"
#include "content/renderer/input/main_thread_event_queue_task_list.h"
#include "content/renderer/input/scoped_web_input_event_with_latency_info.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
@@ -100,6 +100,9 @@ class CONTENT_EXPORT MainThreadEventQueue
void ClearClient();
void SetNeedsLowLatency(bool low_latency);
+ // Request unbuffered input events until next pointerup.
+ void RequestUnbufferedInputEvents();
+
protected:
friend class base::RefCountedThreadSafe<MainThreadEventQueue>;
virtual ~MainThreadEventQueue();
@@ -112,11 +115,6 @@ class CONTENT_EXPORT MainThreadEventQueue
const ui::LatencyInfo& latency,
HandledEventCallback handled_callback);
- void SendEventToMainThread(const blink::WebInputEvent* event,
- const ui::LatencyInfo& latency,
- InputEventDispatchType original_dispatch_type);
-
- bool IsRafAlignedInputDisabled() const;
bool IsRafAlignedEvent(
const std::unique_ptr<MainThreadEventQueueTask>& item) const;
void RafFallbackTimerFired();
@@ -133,9 +131,9 @@ class CONTENT_EXPORT MainThreadEventQueue
bool enable_fling_passive_listener_flag_;
bool enable_non_blocking_due_to_main_thread_responsiveness_flag_;
base::TimeDelta main_thread_responsiveness_threshold_;
- bool handle_raf_aligned_touch_input_;
- bool handle_raf_aligned_mouse_input_;
bool needs_low_latency_;
+ bool allow_raf_aligned_input_;
+ bool needs_low_latency_until_pointer_up_ = false;
// Contains data to be shared between main thread and compositor thread.
struct SharedState {
diff --git a/chromium/content/renderer/input/main_thread_event_queue_task.h b/chromium/content/renderer/input/main_thread_event_queue_task.h
index eb0ede9591d..f41552a280b 100644
--- a/chromium/content/renderer/input/main_thread_event_queue_task.h
+++ b/chromium/content/renderer/input/main_thread_event_queue_task.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_RENDERER_INPUT_MAIN_THREAD_EVENT_QUEUE_TASK_H_
#define CONTENT_RENDERER_INPUT_MAIN_THREAD_EVENT_QUEUE_TASK_H_
-#include "content/common/input/input_event_ack_state.h"
+#include "content/public/common/input_event_ack_state.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h"
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 0d6fa5ec53d..a2e711a32e8 100644
--- a/chromium/content/renderer/input/main_thread_event_queue_unittest.cc
+++ b/chromium/content/renderer/input/main_thread_event_queue_unittest.cc
@@ -41,9 +41,6 @@ bool operator==(const WebTouchEvent& lhs, const WebTouchEvent& rhs) {
namespace content {
namespace {
-const unsigned kRafAlignedEnabledTouch = 1;
-const unsigned kRafAlignedEnabledMouse = 1 << 1;
-
// Simulate a 16ms frame signal.
const base::TimeDelta kFrameInterval = base::TimeDelta::FromMilliseconds(16);
@@ -153,31 +150,14 @@ class HandledEventCallbackTracker {
base::WeakPtrFactory<HandledEventCallbackTracker> weak_ptr_factory_;
};
-class MainThreadEventQueueTest : public testing::TestWithParam<unsigned>,
+class MainThreadEventQueueTest : public testing::Test,
public MainThreadEventQueueClient {
public:
MainThreadEventQueueTest()
: main_task_runner_(new base::TestSimpleTaskRunner()),
- raf_aligned_input_setting_(GetParam()),
needs_main_frame_(false),
closure_count_(0) {
- std::vector<base::StringPiece> features;
- std::vector<base::StringPiece> disabled_features;
- if (raf_aligned_input_setting_ & kRafAlignedEnabledTouch) {
- features.push_back(features::kRafAlignedTouchInputEvents.name);
- } else {
- disabled_features.push_back(features::kRafAlignedTouchInputEvents.name);
- }
- if (raf_aligned_input_setting_ & kRafAlignedEnabledMouse) {
- features.push_back(features::kRafAlignedMouseInputEvents.name);
- } else {
- disabled_features.push_back(features::kRafAlignedMouseInputEvents.name);
- }
-
- feature_list_.InitFromCommandLine(base::JoinString(features, ","),
- base::JoinString(disabled_features, ","));
-
- handler_callback_ = base::MakeUnique<HandledEventCallbackTracker>();
+ handler_callback_ = std::make_unique<HandledEventCallbackTracker>();
}
void SetUp() override {
@@ -209,6 +189,10 @@ class MainThreadEventQueueTest : public testing::TestWithParam<unsigned>,
return queue_->shared_state_.events_;
}
+ bool needs_low_latency_until_pointer_up() {
+ return queue_->needs_low_latency_until_pointer_up_;
+ }
+
bool last_touch_start_forced_nonblocking_due_to_fling() {
return queue_->last_touch_start_forced_nonblocking_due_to_fling_;
}
@@ -247,7 +231,7 @@ class MainThreadEventQueueTest : public testing::TestWithParam<unsigned>,
std::vector<ReceivedCallback> GetAndResetCallbackResults() {
std::unique_ptr<HandledEventCallbackTracker> callback =
- base::MakeUnique<HandledEventCallbackTracker>();
+ std::make_unique<HandledEventCallbackTracker>();
handler_callback_.swap(callback);
return callback->GetReceivedCallbacks();
}
@@ -266,7 +250,7 @@ class MainThreadEventQueueTest : public testing::TestWithParam<unsigned>,
unsigned closure_count_;
};
-TEST_P(MainThreadEventQueueTest, NonBlockingWheel) {
+TEST_F(MainThreadEventQueueTest, NonBlockingWheel) {
base::HistogramTester histogram_tester;
WebMouseWheelEvent kEvents[4] = {
@@ -287,8 +271,7 @@ TEST_P(MainThreadEventQueueTest, NonBlockingWheel) {
HandleEvent(event, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
EXPECT_EQ(2u, event_queue().size());
- EXPECT_EQ((raf_aligned_input_setting_ & kRafAlignedEnabledMouse) == 0,
- main_task_runner_->HasPendingTask());
+ EXPECT_FALSE(main_task_runner_->HasPendingTask());
RunPendingTasksWithSimulatedRaf();
EXPECT_THAT(GetAndResetCallbackResults(),
testing::Each(ReceivedCallback(
@@ -367,7 +350,7 @@ TEST_P(MainThreadEventQueueTest, NonBlockingWheel) {
histogram_tester.ExpectUniqueSample(kCoalescedCountHistogram, 1, 2);
}
-TEST_P(MainThreadEventQueueTest, NonBlockingTouch) {
+TEST_F(MainThreadEventQueueTest, NonBlockingTouch) {
base::HistogramTester histogram_tester;
EXPECT_CALL(renderer_scheduler_,
@@ -468,7 +451,7 @@ TEST_P(MainThreadEventQueueTest, NonBlockingTouch) {
histogram_tester.ExpectBucketCount(kCoalescedCountHistogram, 1, 1);
}
-TEST_P(MainThreadEventQueueTest, BlockingTouch) {
+TEST_F(MainThreadEventQueueTest, BlockingTouch) {
base::HistogramTester histogram_tester;
SyntheticWebTouchEvent kEvents[4];
kEvents[0].PressPoint(10, 10);
@@ -523,7 +506,7 @@ TEST_P(MainThreadEventQueueTest, BlockingTouch) {
histogram_tester.ExpectUniqueSample(kCoalescedCountHistogram, 2, 2);
}
-TEST_P(MainThreadEventQueueTest, InterleavedEvents) {
+TEST_F(MainThreadEventQueueTest, InterleavedEvents) {
WebMouseWheelEvent kWheelEvents[2] = {
SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, 53, 0, false),
SyntheticWebMouseWheelEventBuilder::Build(20, 20, 0, 53, 0, false),
@@ -547,9 +530,7 @@ TEST_P(MainThreadEventQueueTest, InterleavedEvents) {
HandleEvent(kTouchEvents[1], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
EXPECT_EQ(2u, event_queue().size());
- EXPECT_EQ(raf_aligned_input_setting_ !=
- (kRafAlignedEnabledMouse | kRafAlignedEnabledTouch),
- main_task_runner_->HasPendingTask());
+ EXPECT_FALSE(main_task_runner_->HasPendingTask());
RunPendingTasksWithSimulatedRaf();
EXPECT_THAT(GetAndResetCallbackResults(),
testing::Each(ReceivedCallback(
@@ -588,11 +569,7 @@ TEST_P(MainThreadEventQueueTest, InterleavedEvents) {
}
}
-TEST_P(MainThreadEventQueueTest, RafAlignedMouseInput) {
- // Don't run the test when we aren't supporting rAF aligned input.
- if ((raf_aligned_input_setting_ & kRafAlignedEnabledMouse) == 0)
- return;
-
+TEST_F(MainThreadEventQueueTest, RafAlignedMouseInput) {
WebMouseEvent mouseDown = SyntheticWebMouseEventBuilder::Build(
WebInputEvent::kMouseDown, 10, 10, 0);
@@ -672,11 +649,7 @@ TEST_P(MainThreadEventQueueTest, RafAlignedMouseInput) {
handled_tasks_.at(4)->taskAsEvent()->Event().GetModifiers());
}
-TEST_P(MainThreadEventQueueTest, RafAlignedTouchInput) {
- // Don't run the test when we aren't supporting rAF aligned input.
- if ((raf_aligned_input_setting_ & kRafAlignedEnabledTouch) == 0)
- return;
-
+TEST_F(MainThreadEventQueueTest, RafAlignedTouchInput) {
SyntheticWebTouchEvent kEvents[3];
kEvents[0].PressPoint(10, 10);
kEvents[1].PressPoint(10, 10);
@@ -753,11 +726,7 @@ TEST_P(MainThreadEventQueueTest, RafAlignedTouchInput) {
CallbackReceivedState::kCalledAfterHandleEvent, false)));
}
-TEST_P(MainThreadEventQueueTest, RafAlignedTouchInputCoalescedMoves) {
- // Don't run the test when we aren't supporting rAF aligned input.
- if ((raf_aligned_input_setting_ & kRafAlignedEnabledTouch) == 0)
- return;
-
+TEST_F(MainThreadEventQueueTest, RafAlignedTouchInputCoalescedMoves) {
SyntheticWebTouchEvent kEvents[2];
kEvents[0].PressPoint(10, 10);
kEvents[0].MovePoint(0, 50, 50);
@@ -827,11 +796,7 @@ TEST_P(MainThreadEventQueueTest, RafAlignedTouchInputCoalescedMoves) {
CallbackReceivedState::kCalledWhileHandlingEvent, false)));
}
-TEST_P(MainThreadEventQueueTest, RafAlignedTouchInputThrottlingMoves) {
- // Don't run the test when we aren't supporting rAF aligned input.
- if ((raf_aligned_input_setting_ & kRafAlignedEnabledTouch) == 0)
- return;
-
+TEST_F(MainThreadEventQueueTest, RafAlignedTouchInputThrottlingMoves) {
EXPECT_CALL(renderer_scheduler_,
DidHandleInputEventOnMainThread(testing::_, testing::_))
.Times(2);
@@ -877,7 +842,7 @@ TEST_P(MainThreadEventQueueTest, RafAlignedTouchInputThrottlingMoves) {
EXPECT_EQ(0u, event_queue().size());
}
-TEST_P(MainThreadEventQueueTest, LowLatency) {
+TEST_F(MainThreadEventQueueTest, LowLatency) {
SyntheticWebTouchEvent kEvents[2];
kEvents[0].PressPoint(10, 10);
kEvents[1].PressPoint(10, 10);
@@ -928,13 +893,8 @@ TEST_P(MainThreadEventQueueTest, LowLatency) {
EXPECT_EQ(2u, event_queue().size());
EXPECT_TRUE(main_task_runner_->HasPendingTask());
- if ((raf_aligned_input_setting_ & kRafAlignedEnabledTouch) == 0) {
- EXPECT_FALSE(needs_main_frame_);
- main_task_runner_->RunUntilIdle();
- } else {
- EXPECT_TRUE(needs_main_frame_);
- RunPendingTasksWithSimulatedRaf();
- }
+ EXPECT_TRUE(needs_main_frame_);
+ RunPendingTasksWithSimulatedRaf();
EXPECT_THAT(GetAndResetCallbackResults(),
testing::Each(ReceivedCallback(
CallbackReceivedState::kCalledWhileHandlingEvent, false)));
@@ -945,22 +905,16 @@ TEST_P(MainThreadEventQueueTest, LowLatency) {
HandleEvent(mouse_wheel, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
EXPECT_EQ(2u, event_queue().size());
- if ((raf_aligned_input_setting_ & kRafAlignedEnabledMouse) == 0) {
- EXPECT_TRUE(main_task_runner_->HasPendingTask());
- EXPECT_FALSE(needs_main_frame_);
- main_task_runner_->RunUntilIdle();
- } else {
- EXPECT_FALSE(main_task_runner_->HasPendingTask());
- EXPECT_TRUE(needs_main_frame_);
- RunPendingTasksWithSimulatedRaf();
- }
+ EXPECT_FALSE(main_task_runner_->HasPendingTask());
+ EXPECT_TRUE(needs_main_frame_);
+ RunPendingTasksWithSimulatedRaf();
EXPECT_THAT(GetAndResetCallbackResults(),
testing::Each(ReceivedCallback(
CallbackReceivedState::kCalledWhileHandlingEvent, false)));
EXPECT_EQ(0u, event_queue().size());
}
-TEST_P(MainThreadEventQueueTest, BlockingTouchesDuringFling) {
+TEST_F(MainThreadEventQueueTest, BlockingTouchesDuringFling) {
SyntheticWebTouchEvent kEvents;
kEvents.PressPoint(10, 10);
kEvents.touch_start_or_first_touch_move = true;
@@ -992,8 +946,7 @@ TEST_P(MainThreadEventQueueTest, BlockingTouchesDuringFling) {
kEvents.MovePoint(0, 30, 30);
EXPECT_FALSE(main_task_runner_->HasPendingTask());
HandleEvent(kEvents, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING);
- EXPECT_EQ((raf_aligned_input_setting_ & kRafAlignedEnabledTouch) == 0,
- main_task_runner_->HasPendingTask());
+ EXPECT_FALSE(main_task_runner_->HasPendingTask());
RunPendingTasksWithSimulatedRaf();
EXPECT_THAT(GetAndResetCallbackResults(),
testing::Each(ReceivedCallback(
@@ -1049,7 +1002,7 @@ TEST_P(MainThreadEventQueueTest, BlockingTouchesDuringFling) {
EXPECT_EQ(kEvents, *last_touch_event);
}
-TEST_P(MainThreadEventQueueTest, BlockingTouchesOutsideFling) {
+TEST_F(MainThreadEventQueueTest, BlockingTouchesOutsideFling) {
SyntheticWebTouchEvent kEvents;
kEvents.PressPoint(10, 10);
kEvents.touch_start_or_first_touch_move = true;
@@ -1135,14 +1088,6 @@ TEST_P(MainThreadEventQueueTest, BlockingTouchesOutsideFling) {
EXPECT_EQ(kEvents, *last_touch_event);
}
-// The boolean parameterized test varies whether rAF aligned input
-// is enabled or not.
-INSTANTIATE_TEST_CASE_P(
- MainThreadEventQueueTests,
- MainThreadEventQueueTest,
- testing::Range(0u,
- (kRafAlignedEnabledTouch | kRafAlignedEnabledMouse) + 1));
-
class MainThreadEventQueueInitializationTest
: public testing::Test,
public MainThreadEventQueueClient {
@@ -1200,7 +1145,7 @@ TEST_F(MainThreadEventQueueInitializationTest,
main_thread_responsiveness_threshold());
}
-TEST_P(MainThreadEventQueueTest, QueuingTwoClosures) {
+TEST_F(MainThreadEventQueueTest, QueuingTwoClosures) {
EXPECT_FALSE(main_task_runner_->HasPendingTask());
EXPECT_EQ(0u, event_queue().size());
@@ -1214,7 +1159,7 @@ TEST_P(MainThreadEventQueueTest, QueuingTwoClosures) {
EXPECT_EQ(2u, handled_tasks_.at(1)->taskAsClosure());
}
-TEST_P(MainThreadEventQueueTest, QueuingClosureWithRafEvent) {
+TEST_F(MainThreadEventQueueTest, QueuingClosureWithRafEvent) {
SyntheticWebTouchEvent kEvents[2];
kEvents[0].PressPoint(10, 10);
kEvents[1].PressPoint(10, 10);
@@ -1240,18 +1185,13 @@ TEST_P(MainThreadEventQueueTest, QueuingClosureWithRafEvent) {
HandleEvent(kEvents[1], INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(4u, event_queue().size());
- if ((raf_aligned_input_setting_ & kRafAlignedEnabledTouch) != 0) {
- EXPECT_TRUE(needs_main_frame_);
- main_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(needs_main_frame_);
+ main_task_runner_->RunUntilIdle();
- // The queue should still have the rAF event.
- EXPECT_TRUE(needs_main_frame_);
- EXPECT_EQ(1u, event_queue().size());
- RunPendingTasksWithSimulatedRaf();
- } else {
- EXPECT_FALSE(needs_main_frame_);
- main_task_runner_->RunUntilIdle();
- }
+ // The queue should still have the rAF event.
+ EXPECT_TRUE(needs_main_frame_);
+ EXPECT_EQ(1u, event_queue().size());
+ RunPendingTasksWithSimulatedRaf();
EXPECT_EQ(0u, event_queue().size());
EXPECT_THAT(GetAndResetCallbackResults(),
@@ -1268,7 +1208,7 @@ TEST_P(MainThreadEventQueueTest, QueuingClosureWithRafEvent) {
handled_tasks_.at(3)->taskAsEvent()->Event().GetType());
}
-TEST_P(MainThreadEventQueueTest, QueuingClosuresBetweenEvents) {
+TEST_F(MainThreadEventQueueTest, QueuingClosuresBetweenEvents) {
SyntheticWebTouchEvent kEvents[2];
kEvents[0].PressPoint(10, 10);
kEvents[1].PressPoint(10, 10);
@@ -1303,7 +1243,7 @@ TEST_P(MainThreadEventQueueTest, QueuingClosuresBetweenEvents) {
handled_tasks_.at(3)->taskAsEvent()->Event().GetType());
}
-TEST_P(MainThreadEventQueueTest, BlockingTouchMoveBecomesNonBlocking) {
+TEST_F(MainThreadEventQueueTest, BlockingTouchMoveBecomesNonBlocking) {
SyntheticWebTouchEvent kEvents[2];
kEvents[0].PressPoint(10, 10);
kEvents[0].MovePoint(0, 20, 20);
@@ -1350,7 +1290,7 @@ TEST_P(MainThreadEventQueueTest, BlockingTouchMoveBecomesNonBlocking) {
.dispatch_type);
}
-TEST_P(MainThreadEventQueueTest, BlockingTouchMoveWithTouchEnd) {
+TEST_F(MainThreadEventQueueTest, BlockingTouchMoveWithTouchEnd) {
SyntheticWebTouchEvent kEvents[2];
kEvents[0].PressPoint(10, 10);
kEvents[0].MovePoint(0, 20, 20);
@@ -1390,4 +1330,78 @@ TEST_P(MainThreadEventQueueTest, BlockingTouchMoveWithTouchEnd) {
.dispatch_type);
}
+TEST_F(MainThreadEventQueueTest, UnbufferedDispatchTouchEvent) {
+ SyntheticWebTouchEvent kEvents[3];
+ kEvents[0].PressPoint(10, 10);
+ kEvents[1].PressPoint(10, 10);
+ kEvents[1].MovePoint(0, 20, 20);
+ kEvents[2].PressPoint(10, 10);
+ kEvents[2].ReleasePoint(0);
+
+ EXPECT_FALSE(main_task_runner_->HasPendingTask());
+ EXPECT_EQ(0u, event_queue().size());
+
+ EXPECT_CALL(renderer_scheduler_,
+ DidHandleInputEventOnMainThread(testing::_, testing::_))
+ .Times(3);
+
+ EXPECT_EQ(WebInputEvent::kBlocking, kEvents[0].dispatch_type);
+ EXPECT_EQ(WebInputEvent::kBlocking, kEvents[1].dispatch_type);
+ HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ queue_->RequestUnbufferedInputEvents();
+ EXPECT_EQ(1u, event_queue().size());
+ RunPendingTasksWithSimulatedRaf();
+ EXPECT_TRUE(needs_low_latency_until_pointer_up());
+ EXPECT_FALSE(needs_main_frame_);
+
+ HandleEvent(kEvents[1], INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1u, event_queue().size());
+ RunPendingTasksWithSimulatedRaf();
+ EXPECT_TRUE(needs_low_latency_until_pointer_up());
+ EXPECT_FALSE(needs_main_frame_);
+
+ HandleEvent(kEvents[2], INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1u, event_queue().size());
+ RunPendingTasksWithSimulatedRaf();
+ EXPECT_FALSE(needs_low_latency_until_pointer_up());
+ EXPECT_FALSE(needs_main_frame_);
+}
+
+TEST_F(MainThreadEventQueueTest, UnbufferedDispatchMouseEvent) {
+ WebMouseEvent mouse_down = SyntheticWebMouseEventBuilder::Build(
+ WebInputEvent::kMouseDown, 10, 10, 0);
+ WebMouseEvent mouse_move = SyntheticWebMouseEventBuilder::Build(
+ WebInputEvent::kMouseMove, 10, 10, 0);
+ WebMouseEvent mouse_up =
+ SyntheticWebMouseEventBuilder::Build(WebInputEvent::kMouseUp, 10, 10, 0);
+
+ EXPECT_FALSE(main_task_runner_->HasPendingTask());
+ EXPECT_EQ(0u, event_queue().size());
+
+ EXPECT_CALL(renderer_scheduler_,
+ DidHandleInputEventOnMainThread(testing::_, testing::_))
+ .Times(3);
+
+ HandleEvent(mouse_down, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+ queue_->RequestUnbufferedInputEvents();
+ EXPECT_EQ(1u, event_queue().size());
+ RunPendingTasksWithSimulatedRaf();
+ EXPECT_TRUE(needs_low_latency_until_pointer_up());
+ EXPECT_FALSE(needs_main_frame_);
+
+ HandleEvent(mouse_move, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+ queue_->RequestUnbufferedInputEvents();
+ EXPECT_EQ(1u, event_queue().size());
+ RunPendingTasksWithSimulatedRaf();
+ EXPECT_TRUE(needs_low_latency_until_pointer_up());
+ EXPECT_FALSE(needs_main_frame_);
+
+ HandleEvent(mouse_up, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+ queue_->RequestUnbufferedInputEvents();
+ EXPECT_EQ(1u, event_queue().size());
+ RunPendingTasksWithSimulatedRaf();
+ EXPECT_FALSE(needs_low_latency_until_pointer_up());
+ EXPECT_FALSE(needs_main_frame_);
+}
+
} // namespace content
diff --git a/chromium/content/renderer/input/render_widget_input_handler.cc b/chromium/content/renderer/input/render_widget_input_handler.cc
index 49102e04948..0b50355914d 100644
--- a/chromium/content/renderer/input/render_widget_input_handler.cc
+++ b/chromium/content/renderer/input/render_widget_input_handler.cc
@@ -14,8 +14,9 @@
#include "build/build_config.h"
#include "cc/trees/swap_promise_monitor.h"
#include "content/common/input/input_event_ack.h"
-#include "content/common/input/input_event_ack_state.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/input_event_ack_state.h"
+#include "content/public/renderer/render_frame.h"
#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/ime_event_guard.h"
#include "content/renderer/input/render_widget_input_handler_delegate.h"
@@ -28,6 +29,9 @@
#include "third_party/WebKit/public/platform/WebMouseWheelEvent.h"
#include "third_party/WebKit/public/platform/WebTouchEvent.h"
#include "third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
+#include "third_party/WebKit/public/web/WebNode.h"
#include "ui/events/blink/web_input_event_traits.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/latency/latency_info.h"
@@ -44,7 +48,7 @@ using blink::WebInputEventResult;
using blink::WebKeyboardEvent;
using blink::WebMouseEvent;
using blink::WebMouseWheelEvent;
-using blink::WebScrollBoundaryBehavior;
+using blink::WebOverscrollBehavior;
using blink::WebTouchEvent;
using blink::WebTouchPoint;
using ui::DidOverscrollParams;
@@ -153,6 +157,23 @@ RenderWidgetInputHandler::RenderWidgetInputHandler(
RenderWidgetInputHandler::~RenderWidgetInputHandler() {}
+int RenderWidgetInputHandler::GetWidgetRoutingIdAtPoint(
+ const gfx::Point& point) {
+ blink::WebNode result_node =
+ widget_->GetWebWidget()
+ ->HitTestResultAt(blink::WebPoint(point.x(), point.y()))
+ .GetNode();
+
+ blink::WebFrame* result_frame =
+ blink::WebFrame::FromFrameOwnerElement(result_node);
+ if (!result_frame) {
+ // This means that the node is not an iframe itself. So we just return the
+ // the frame containing the node.
+ result_frame = result_node.GetDocument().GetFrame();
+ }
+ return RenderFrame::GetRoutingIdForWebFrame(result_frame);
+}
+
void RenderWidgetInputHandler::HandleInputEvent(
const blink::WebCoalescedInputEvent& coalesced_event,
const ui::LatencyInfo& latency_info,
@@ -241,7 +262,13 @@ void RenderWidgetInputHandler::HandleInputEvent(
static_cast<const WebKeyboardEvent&>(input_event);
if (key_event.native_key_code == AKEYCODE_DPAD_CENTER &&
widget_->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE) {
- widget_->ShowVirtualKeyboardOnElementFocus();
+ // Show the keyboard on keyup (not keydown) to match the behavior of
+ // Android's TextView.
+ if (key_event.GetType() == WebInputEvent::kKeyUp)
+ widget_->ShowVirtualKeyboardOnElementFocus();
+ // Prevent default for both keydown and keyup (letting the keydown go
+ // through to the web app would cause compatibility problems since
+ // DPAD_CENTER is also used as a "confirm" button).
prevent_default = true;
}
#endif
@@ -275,19 +302,6 @@ void RenderWidgetInputHandler::HandleInputEvent(
LogPassiveEventListenersUma(processed, touch.dispatch_type,
input_event.TimeStampSeconds(), latency_info);
-
- // TODO(lanwei): Remove this metric for event latency outside fling in M56,
- // once we've gathered enough data to decide if we want to ship the passive
- // event listener for fling, see https://crbug.com/638661.
- if (touch.dispatch_type == WebInputEvent::kBlocking &&
- touch.touch_start_or_first_touch_move &&
- base::TimeTicks::IsHighResolution()) {
- base::TimeTicks now = base::TimeTicks::Now();
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- "Event.Touch.TouchLatencyOutsideFling",
- GetEventLatencyMicros(input_event.TimeStampSeconds(), now), 1,
- 100000000, 50);
- }
} else if (input_event.GetType() == WebInputEvent::kMouseWheel) {
LogPassiveEventListenersUma(
processed,
@@ -307,23 +321,6 @@ void RenderWidgetInputHandler::HandleInputEvent(
InputEventAckState ack_result = processed == WebInputEventResult::kNotHandled
? INPUT_EVENT_ACK_STATE_NOT_CONSUMED
: INPUT_EVENT_ACK_STATE_CONSUMED;
- if (processed == WebInputEventResult::kNotHandled &&
- input_event.GetType() == WebInputEvent::kTouchStart) {
- const WebTouchEvent& touch_event =
- static_cast<const WebTouchEvent&>(input_event);
- // Hit-test for all the pressed touch points. If there is a touch-handler
- // for any of the touch points, then the renderer should continue to receive
- // touch events.
- ack_result = INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
- for (size_t i = 0; i < touch_event.touches_length; ++i) {
- if (touch_event.touches[i].state == WebTouchPoint::kStatePressed &&
- delegate_->HasTouchEventHandlersAt(
- gfx::ToFlooredPoint(touch_event.touches[i].PositionInWidget()))) {
- ack_result = INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
- break;
- }
- }
- }
// Send gesture scroll events and their dispositions to the compositor thread,
// so that they can be used to produce the elastic overscroll effect on Mac.
@@ -367,7 +364,7 @@ void RenderWidgetInputHandler::HandleInputEvent(
// Virtual keyboard is not supported, so react to focus change immediately.
if (processed != WebInputEventResult::kNotHandled &&
(input_event.GetType() == WebInputEvent::kTouchEnd ||
- input_event.GetType() == WebInputEvent::kMouseUp)) {
+ input_event.GetType() == WebInputEvent::kMouseDown)) {
delegate_->FocusChangeComplete();
}
#endif
@@ -378,7 +375,7 @@ void RenderWidgetInputHandler::DidOverscrollFromBlink(
const WebFloatSize& accumulatedOverscroll,
const WebFloatPoint& position,
const WebFloatSize& velocity,
- const WebScrollBoundaryBehavior& behavior) {
+ const WebOverscrollBehavior& behavior) {
std::unique_ptr<DidOverscrollParams> params(new DidOverscrollParams());
params->accumulated_overscroll = gfx::Vector2dF(
accumulatedOverscroll.width, accumulatedOverscroll.height);
@@ -387,7 +384,7 @@ void RenderWidgetInputHandler::DidOverscrollFromBlink(
params->current_fling_velocity =
gfx::Vector2dF(velocity.width, velocity.height);
params->causal_event_viewport_point = gfx::PointF(position.x, position.y);
- params->scroll_boundary_behavior = behavior;
+ params->overscroll_behavior = behavior;
// If we're currently handling an event, stash the overscroll data such that
// it can be bundled in the event ack.
diff --git a/chromium/content/renderer/input/render_widget_input_handler.h b/chromium/content/renderer/input/render_widget_input_handler.h
index 453ac9f0ae3..2e8431a6e0e 100644
--- a/chromium/content/renderer/input/render_widget_input_handler.h
+++ b/chromium/content/renderer/input/render_widget_input_handler.h
@@ -19,7 +19,7 @@
namespace blink {
struct WebFloatPoint;
struct WebFloatSize;
-struct WebScrollBoundaryBehavior;
+struct WebOverscrollBehavior;
}
namespace ui {
@@ -39,6 +39,10 @@ class CONTENT_EXPORT RenderWidgetInputHandler {
RenderWidget* widget);
virtual ~RenderWidgetInputHandler();
+ // Hit test the given point to find out the frame underneath and
+ // return the routing id for that frame.
+ int GetWidgetRoutingIdAtPoint(const gfx::Point& point);
+
// Handle input events from the input event provider.
virtual void HandleInputEvent(
const blink::WebCoalescedInputEvent& coalesced_event,
@@ -50,7 +54,7 @@ class CONTENT_EXPORT RenderWidgetInputHandler {
const blink::WebFloatSize& accumulatedOverscroll,
const blink::WebFloatPoint& position,
const blink::WebFloatSize& velocity,
- const blink::WebScrollBoundaryBehavior& behavior);
+ const blink::WebOverscrollBehavior& behavior);
bool handling_input_event() const { return handling_input_event_; }
void set_handling_input_event(bool handling_input_event) {
diff --git a/chromium/content/renderer/input/render_widget_input_handler_delegate.h b/chromium/content/renderer/input/render_widget_input_handler_delegate.h
index 13d7367d407..3349e718384 100644
--- a/chromium/content/renderer/input/render_widget_input_handler_delegate.h
+++ b/chromium/content/renderer/input/render_widget_input_handler_delegate.h
@@ -17,7 +17,6 @@ class WebMouseEvent;
}
namespace gfx {
-class Point;
class Vector2dF;
}
@@ -32,10 +31,6 @@ class CONTENT_EXPORT RenderWidgetInputHandlerDelegate {
// Called when animations due to focus change have completed (if any).
virtual void FocusChangeComplete() = 0;
- // Check whether the WebWidget has any touch event handlers registered
- // at the given point.
- virtual bool HasTouchEventHandlersAt(const gfx::Point& point) const = 0;
-
// Called to forward a gesture event to the compositor thread, to effect
// the elastic overscroll effect.
virtual void ObserveGestureEventAndResult(
diff --git a/chromium/content/renderer/input/widget_input_handler_impl.cc b/chromium/content/renderer/input/widget_input_handler_impl.cc
index c32c7510ba3..c06b9b0a345 100644
--- a/chromium/content/renderer/input/widget_input_handler_impl.cc
+++ b/chromium/content/renderer/input/widget_input_handler_impl.cc
@@ -43,9 +43,11 @@ std::vector<blink::WebImeTextSpan> ConvertUIImeTextSpansToBlinkImeTextSpans(
void RunClosureIfNotSwappedOut(base::WeakPtr<RenderWidget> render_widget,
base::OnceClosure closure) {
// Input messages must not be processed if the RenderWidget is in swapped out
- // state.
- if (!render_widget || render_widget->is_swapped_out())
+ // or closing state.
+ if (!render_widget || render_widget->is_swapped_out() ||
+ render_widget->IsClosing()) {
return;
+ }
std::move(closure).Run();
}
diff --git a/chromium/content/renderer/input/widget_input_handler_manager.cc b/chromium/content/renderer/input/widget_input_handler_manager.cc
index b3a8f95600b..4a20df3bc96 100644
--- a/chromium/content/renderer/input/widget_input_handler_manager.cc
+++ b/chromium/content/renderer/input/widget_input_handler_manager.cc
@@ -11,6 +11,7 @@
#include "content/common/input_messages.h"
#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/ime_event_guard.h"
+#include "content/renderer/input/input_handler_manager.h"
#include "content/renderer/input/widget_input_handler_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_widget.h"
@@ -23,26 +24,6 @@
namespace content {
namespace {
-InputEventAckState InputEventDispositionToAck(
- ui::InputHandlerProxy::EventDisposition disposition) {
- switch (disposition) {
- case ui::InputHandlerProxy::DID_HANDLE:
- return INPUT_EVENT_ACK_STATE_CONSUMED;
- case ui::InputHandlerProxy::DID_NOT_HANDLE:
- return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
- case ui::InputHandlerProxy::DID_NOT_HANDLE_NON_BLOCKING_DUE_TO_FLING:
- return INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING;
- case ui::InputHandlerProxy::DROP_EVENT:
- return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
- case ui::InputHandlerProxy::DID_HANDLE_NON_BLOCKING:
- return INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING;
- case ui::InputHandlerProxy::DID_HANDLE_SHOULD_BUBBLE:
- return INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE;
- }
- NOTREACHED();
- return INPUT_EVENT_ACK_STATE_UNKNOWN;
-}
-
void CallCallback(mojom::WidgetInputHandler::DispatchEventCallback callback,
InputEventAckState ack_state,
const ui::LatencyInfo& latency_info,
@@ -95,44 +76,47 @@ void WidgetInputHandlerManager::Init() {
WidgetInputHandlerManager::~WidgetInputHandlerManager() {}
void WidgetInputHandlerManager::AddAssociatedInterface(
- mojom::WidgetInputHandlerAssociatedRequest request) {
+ mojom::WidgetInputHandlerAssociatedRequest request,
+ mojom::WidgetInputHandlerHostPtr host) {
if (compositor_task_runner_) {
+ associated_host_ =
+ mojo::ThreadSafeInterfacePtr<mojom::WidgetInputHandlerHost>::Create(
+ host.PassInterface(), compositor_task_runner_);
// Mojo channel bound on compositor thread.
compositor_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WidgetInputHandlerManager::BindAssociatedChannel, this,
std::move(request)));
} else {
+ associated_host_ =
+ mojo::ThreadSafeInterfacePtr<mojom::WidgetInputHandlerHost>::Create(
+ std::move(host));
// Mojo channel bound on main thread.
BindAssociatedChannel(std::move(request));
}
}
-void WidgetInputHandlerManager::SetWidgetInputHandlerHost(
+void WidgetInputHandlerManager::AddInterface(
+ mojom::WidgetInputHandlerRequest request,
mojom::WidgetInputHandlerHostPtr host) {
if (compositor_task_runner_) {
host_ = mojo::ThreadSafeInterfacePtr<mojom::WidgetInputHandlerHost>::Create(
host.PassInterface(), compositor_task_runner_);
- } else {
- host_ = mojo::ThreadSafeInterfacePtr<mojom::WidgetInputHandlerHost>::Create(
- std::move(host));
- }
-}
-
-void WidgetInputHandlerManager::AddInterface(
- mojom::WidgetInputHandlerRequest request) {
- if (compositor_task_runner_) {
// Mojo channel bound on compositor thread.
compositor_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&WidgetInputHandlerManager::BindChannel, this,
std::move(request)));
} else {
+ host_ = mojo::ThreadSafeInterfacePtr<mojom::WidgetInputHandlerHost>::Create(
+ std::move(host));
// Mojo channel bound on main thread.
BindChannel(std::move(request));
}
}
-void WidgetInputHandlerManager::WillShutdown() {}
+void WidgetInputHandlerManager::WillShutdown() {
+ input_handler_proxy_.reset();
+}
void WidgetInputHandlerManager::TransferActiveWheelFlingAnimation(
const blink::WebActiveWheelFlingParameters& params) {
@@ -165,20 +149,24 @@ void WidgetInputHandlerManager::DidOverscroll(
const gfx::Vector2dF& latest_overscroll_delta,
const gfx::Vector2dF& current_fling_velocity,
const gfx::PointF& causal_event_viewport_point,
- const cc::ScrollBoundaryBehavior& scroll_boundary_behavior) {
+ const cc::OverscrollBehavior& overscroll_behavior) {
+ mojom::WidgetInputHandlerHost* host = GetWidgetInputHandlerHost();
+ if (!host)
+ return;
ui::DidOverscrollParams params;
params.accumulated_overscroll = accumulated_overscroll;
params.latest_overscroll_delta = latest_overscroll_delta;
params.current_fling_velocity = current_fling_velocity;
params.causal_event_viewport_point = causal_event_viewport_point;
- params.scroll_boundary_behavior = scroll_boundary_behavior;
- DCHECK(host_);
- (*host_)->DidOverscroll(params);
+ params.overscroll_behavior = overscroll_behavior;
+ host->DidOverscroll(params);
}
void WidgetInputHandlerManager::DidStopFlinging() {
- DCHECK(host_);
- (*host_)->DidStopFlinging();
+ mojom::WidgetInputHandlerHost* host = GetWidgetInputHandlerHost();
+ if (!host)
+ return;
+ host->DidStopFlinging();
}
void WidgetInputHandlerManager::DidAnimateForInput() {
@@ -207,25 +195,31 @@ void WidgetInputHandlerManager::SetWhiteListedTouchAction(
cc::TouchAction touch_action,
uint32_t unique_touch_event_id,
ui::InputHandlerProxy::EventDisposition event_disposition) {
+ mojom::WidgetInputHandlerHost* host = GetWidgetInputHandlerHost();
+ if (!host)
+ return;
InputEventAckState ack_state = InputEventDispositionToAck(event_disposition);
- DCHECK(host_);
- (*host_)->SetWhiteListedTouchAction(touch_action, unique_touch_event_id,
- ack_state);
+ host->SetWhiteListedTouchAction(touch_action, unique_touch_event_id,
+ ack_state);
}
void WidgetInputHandlerManager::ProcessTouchAction(
cc::TouchAction touch_action) {
- DCHECK(host_);
// Cancel the touch timeout on TouchActionNone since it is a good hint
// that author doesn't want scrolling.
- if (touch_action == cc::TouchAction::kTouchActionNone)
- (*host_)->CancelTouchTimeout();
+ if (touch_action == cc::TouchAction::kTouchActionNone) {
+ if (mojom::WidgetInputHandlerHost* host = GetWidgetInputHandlerHost())
+ host->CancelTouchTimeout();
+ }
}
-const WidgetInputHandlerManager::WidgetInputHandlerHost&
+mojom::WidgetInputHandlerHost*
WidgetInputHandlerManager::GetWidgetInputHandlerHost() {
- DCHECK(host_);
- return host_;
+ if (associated_host_)
+ return associated_host_.get()->get();
+ if (host_)
+ return host_.get()->get();
+ return nullptr;
}
void WidgetInputHandlerManager::ObserveGestureEventOnMainThread(
@@ -244,6 +238,13 @@ void WidgetInputHandlerManager::DispatchEvent(
std::unique_ptr<content::InputEvent> event,
mojom::WidgetInputHandler::DispatchEventCallback callback) {
if (!event || !event->web_event) {
+ // Call |callback| if it was available indicating this event wasn't
+ // handled.
+ if (callback) {
+ std::move(callback).Run(
+ InputEventAckSource::MAIN_THREAD, ui::LatencyInfo(),
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED, base::nullopt, base::nullopt);
+ }
return;
}
@@ -256,6 +257,15 @@ void WidgetInputHandlerManager::DispatchEvent(
}
if (compositor_task_runner_) {
+ // If the input_handler_proxy has disappeared ensure we just ack event.
+ if (!input_handler_proxy_) {
+ if (callback) {
+ std::move(callback).Run(
+ InputEventAckSource::MAIN_THREAD, ui::LatencyInfo(),
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED, base::nullopt, base::nullopt);
+ }
+ return;
+ }
CHECK(!main_thread_task_runner_->BelongsToCurrentThread());
input_handler_proxy_->HandleInputEventWithLatencyInfo(
std::move(event->web_event), event->latency_info,
@@ -271,7 +281,7 @@ void WidgetInputHandlerManager::DispatchEvent(
void WidgetInputHandlerManager::InitOnCompositorThread(
const base::WeakPtr<cc::InputHandler>& input_handler,
bool smooth_scroll_enabled) {
- input_handler_proxy_ = base::MakeUnique<ui::InputHandlerProxy>(
+ input_handler_proxy_ = std::make_unique<ui::InputHandlerProxy>(
input_handler.get(), this,
base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching));
input_handler_proxy_->set_smooth_scroll_enabled(smooth_scroll_enabled);
@@ -279,15 +289,25 @@ void WidgetInputHandlerManager::InitOnCompositorThread(
void WidgetInputHandlerManager::BindAssociatedChannel(
mojom::WidgetInputHandlerAssociatedRequest request) {
+ if (!request.is_pending())
+ return;
+ // Don't pass the |input_event_queue_| on if we don't have a
+ // |compositor_task_runner_| as events might get out of order.
WidgetInputHandlerImpl* handler = new WidgetInputHandlerImpl(
- this, main_thread_task_runner_, input_event_queue_, render_widget_);
+ this, main_thread_task_runner_,
+ compositor_task_runner_ ? input_event_queue_ : nullptr, render_widget_);
handler->SetAssociatedBinding(std::move(request));
}
void WidgetInputHandlerManager::BindChannel(
mojom::WidgetInputHandlerRequest request) {
+ if (!request.is_pending())
+ return;
+ // Don't pass the |input_event_queue_| on if we don't have a
+ // |compositor_task_runner_| as events might get out of order.
WidgetInputHandlerImpl* handler = new WidgetInputHandlerImpl(
- this, main_thread_task_runner_, input_event_queue_, render_widget_);
+ this, main_thread_task_runner_,
+ compositor_task_runner_ ? input_event_queue_ : nullptr, render_widget_);
handler->SetBinding(std::move(request));
}
@@ -295,10 +315,13 @@ void WidgetInputHandlerManager::HandleInputEvent(
const ui::WebScopedInputEvent& event,
const ui::LatencyInfo& latency,
mojom::WidgetInputHandler::DispatchEventCallback callback) {
- if (!render_widget_ || render_widget_->is_swapped_out()) {
- std::move(callback).Run(InputEventAckSource::MAIN_THREAD, latency,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED, base::nullopt,
- base::nullopt);
+ if (!render_widget_ || render_widget_->is_swapped_out() ||
+ render_widget_->IsClosing()) {
+ if (callback) {
+ std::move(callback).Run(InputEventAckSource::MAIN_THREAD, latency,
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED, base::nullopt,
+ base::nullopt);
+ }
return;
}
auto send_callback = base::BindOnce(
@@ -338,7 +361,6 @@ void WidgetInputHandlerManager::DidHandleInputEventAndOverscroll(
InputEventDispatchType dispatch_type = callback.is_null()
? DISPATCH_TYPE_NON_BLOCKING
: DISPATCH_TYPE_BLOCKING;
-
HandledEventCallback handled_event =
base::BindOnce(&WidgetInputHandlerManager::HandledInputEvent, this,
std::move(callback));
@@ -365,14 +387,24 @@ void WidgetInputHandlerManager::HandledInputEvent(
base::Optional<cc::TouchAction> touch_action) {
if (!callback)
return;
- if (compositor_task_runner_) {
+
+ // This method is called from either the main thread or the compositor thread.
+ bool is_compositor_thread = compositor_task_runner_ &&
+ compositor_task_runner_->BelongsToCurrentThread();
+
+ // If there is a compositor task runner and the current thread isn't the
+ // compositor thread proxy it over to the compositor thread.
+ if (compositor_task_runner_ && !is_compositor_thread) {
compositor_task_runner_->PostTask(
FROM_HERE, base::BindOnce(CallCallback, std::move(callback), ack_state,
latency_info, std::move(overscroll_params),
touch_action));
} else {
+ // Otherwise call the callback immediately.
std::move(callback).Run(
- InputEventAckSource::COMPOSITOR_THREAD, latency_info, ack_state,
+ is_compositor_thread ? InputEventAckSource::COMPOSITOR_THREAD
+ : InputEventAckSource::MAIN_THREAD,
+ latency_info, ack_state,
overscroll_params
? base::Optional<ui::DidOverscrollParams>(*overscroll_params)
: base::nullopt,
@@ -383,6 +415,8 @@ void WidgetInputHandlerManager::HandledInputEvent(
void WidgetInputHandlerManager::ObserveGestureEventOnCompositorThread(
const blink::WebGestureEvent& gesture_event,
const cc::InputHandlerScrollResult& scroll_result) {
+ if (!input_handler_proxy_)
+ return;
DCHECK(input_handler_proxy_->scroll_elasticity_controller());
input_handler_proxy_->scroll_elasticity_controller()
->ObserveGestureEventAndResult(gesture_event, scroll_result);
diff --git a/chromium/content/renderer/input/widget_input_handler_manager.h b/chromium/content/renderer/input/widget_input_handler_manager.h
index b15b6cdd415..d29015eb6a0 100644
--- a/chromium/content/renderer/input/widget_input_handler_manager.h
+++ b/chromium/content/renderer/input/widget_input_handler_manager.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_RENDERER_INPUT_WIDGET_INPUT_HANDLER_MANAGER_H_
#define CONTENT_RENDERER_INPUT_WIDGET_INPUT_HANDLER_MANAGER_H_
+#include "content/common/content_export.h"
#include "content/common/input/input_handler.mojom.h"
#include "content/renderer/render_frame_impl.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
@@ -24,7 +25,7 @@ class MainThreadEventQueue;
// This class maintains the compositor InputHandlerProxy and is
// responsible for passing input events on the compositor and main threads.
// The lifecycle of this object matches that of the RenderWidget.
-class WidgetInputHandlerManager
+class CONTENT_EXPORT WidgetInputHandlerManager
: public base::RefCountedThreadSafe<WidgetInputHandlerManager>,
public ui::InputHandlerProxyClient {
public:
@@ -33,10 +34,11 @@ class WidgetInputHandlerManager
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
blink::scheduler::RendererScheduler* renderer_scheduler);
void AddAssociatedInterface(
- mojom::WidgetInputHandlerAssociatedRequest interface_request);
+ mojom::WidgetInputHandlerAssociatedRequest interface_request,
+ mojom::WidgetInputHandlerHostPtr host);
- void SetWidgetInputHandlerHost(mojom::WidgetInputHandlerHostPtr host);
- void AddInterface(mojom::WidgetInputHandlerRequest interface_request);
+ void AddInterface(mojom::WidgetInputHandlerRequest interface_request,
+ mojom::WidgetInputHandlerHostPtr host);
// InputHandlerProxyClient overrides.
void WillShutdown() override;
@@ -55,7 +57,7 @@ class WidgetInputHandlerManager
const gfx::Vector2dF& latest_overscroll_delta,
const gfx::Vector2dF& current_fling_velocity,
const gfx::PointF& causal_event_viewport_point,
- const cc::ScrollBoundaryBehavior& scroll_boundary_behavior) override;
+ const cc::OverscrollBehavior& overscroll_behavior) override;
void DidStopFlinging() override;
void DidAnimateForInput() override;
void GenerateScrollBeginAndSendToMainThread(
@@ -74,9 +76,7 @@ class WidgetInputHandlerManager
void ProcessTouchAction(cc::TouchAction touch_action);
- using WidgetInputHandlerHost = scoped_refptr<
- mojo::ThreadSafeInterfacePtr<mojom::WidgetInputHandlerHost>>;
- const WidgetInputHandlerHost& GetWidgetInputHandlerHost();
+ mojom::WidgetInputHandlerHost* GetWidgetInputHandlerHost();
protected:
friend class base::RefCountedThreadSafe<WidgetInputHandlerManager>;
@@ -122,10 +122,17 @@ class WidgetInputHandlerManager
// thread.
std::unique_ptr<ui::InputHandlerProxy> input_handler_proxy_;
+ using WidgetInputHandlerHost = scoped_refptr<
+ mojo::ThreadSafeInterfacePtr<mojom::WidgetInputHandlerHost>>;
+
// The WidgetInputHandlerHost is bound on the compositor task runner
// but class can be called on the compositor and main thread.
WidgetInputHandlerHost host_;
+ // Host that was passed as part of the FrameInputHandler associated
+ // channel.
+ WidgetInputHandlerHost associated_host_;
+
// Any thread can access these variables.
scoped_refptr<MainThreadEventQueue> input_event_queue_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/chromium/content/renderer/installedapp/related_apps_fetcher.cc b/chromium/content/renderer/installedapp/related_apps_fetcher.cc
index 46c2e31b4ee..7cade92a323 100644
--- a/chromium/content/renderer/installedapp/related_apps_fetcher.cc
+++ b/chromium/content/renderer/installedapp/related_apps_fetcher.cc
@@ -6,14 +6,15 @@
#include "base/bind.h"
#include "content/public/common/manifest.h"
-#include "content/renderer/manifest/manifest_debug_info.h"
-#include "content/renderer/manifest/manifest_manager.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/modules/installedapp/WebRelatedApplication.h"
+#include "third_party/WebKit/public/platform/modules/manifest/manifest.mojom.h"
+#include "third_party/WebKit/public/platform/modules/manifest/manifest_manager.mojom.h"
namespace content {
-RelatedAppsFetcher::RelatedAppsFetcher(ManifestManager* manifest_manager)
+RelatedAppsFetcher::RelatedAppsFetcher(
+ blink::mojom::ManifestManager* manifest_manager)
: manifest_manager_(manifest_manager) {}
RelatedAppsFetcher::~RelatedAppsFetcher() {}
@@ -22,7 +23,7 @@ void RelatedAppsFetcher::GetManifestRelatedApplications(
std::unique_ptr<blink::WebCallbacks<
const blink::WebVector<blink::WebRelatedApplication>&,
void>> callbacks) {
- manifest_manager_->GetManifest(
+ manifest_manager_->RequestManifest(
base::BindOnce(&RelatedAppsFetcher::OnGetManifestForRelatedApplications,
base::Unretained(this), base::Passed(&callbacks)));
}
@@ -32,8 +33,7 @@ void RelatedAppsFetcher::OnGetManifestForRelatedApplications(
const blink::WebVector<blink::WebRelatedApplication>&,
void>> callbacks,
const GURL& /*url*/,
- const Manifest& manifest,
- const ManifestDebugInfo& /*manifest_debug_info*/) {
+ const Manifest& manifest) {
std::vector<blink::WebRelatedApplication> related_apps;
for (const auto& relatedApplication : manifest.related_applications) {
blink::WebRelatedApplication webRelatedApplication;
diff --git a/chromium/content/renderer/installedapp/related_apps_fetcher.h b/chromium/content/renderer/installedapp/related_apps_fetcher.h
index 379a9f52381..d97f3463088 100644
--- a/chromium/content/renderer/installedapp/related_apps_fetcher.h
+++ b/chromium/content/renderer/installedapp/related_apps_fetcher.h
@@ -11,15 +11,20 @@
#include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/modules/installedapp/WebRelatedAppsFetcher.h"
+namespace blink {
+namespace mojom {
+class ManifestManager;
+}
+} // namespace blink
+
namespace content {
struct Manifest;
-struct ManifestDebugInfo;
class ManifestManager;
class CONTENT_EXPORT RelatedAppsFetcher : public blink::WebRelatedAppsFetcher {
public:
- explicit RelatedAppsFetcher(ManifestManager* manifest_manager);
+ explicit RelatedAppsFetcher(blink::mojom::ManifestManager* manifest_manager);
~RelatedAppsFetcher() override;
// blink::WebRelatedAppsFetcher overrides:
@@ -36,10 +41,9 @@ class CONTENT_EXPORT RelatedAppsFetcher : public blink::WebRelatedAppsFetcher {
const blink::WebVector<blink::WebRelatedApplication>&,
void>> callbacks,
const GURL& url,
- const Manifest& manifest,
- const ManifestDebugInfo& manifest_debug_info);
+ const Manifest& manifest);
- ManifestManager* manifest_manager_;
+ blink::mojom::ManifestManager* const manifest_manager_;
DISALLOW_COPY_AND_ASSIGN(RelatedAppsFetcher);
};
diff --git a/chromium/content/renderer/internal_document_state_data.cc b/chromium/content/renderer/internal_document_state_data.cc
index 9d01f6c36e9..72d99be7aba 100644
--- a/chromium/content/renderer/internal_document_state_data.cc
+++ b/chromium/content/renderer/internal_document_state_data.cc
@@ -22,7 +22,7 @@ InternalDocumentStateData::InternalDocumentStateData()
is_overriding_user_agent_(false),
must_reset_scroll_and_scale_state_(false),
cache_policy_override_set_(false),
- cache_policy_override_(blink::WebCachePolicy::kUseProtocolCachePolicy) {}
+ cache_policy_override_(blink::mojom::FetchCacheMode::kDefault) {}
// static
InternalDocumentStateData* InternalDocumentStateData::FromDocumentLoader(
@@ -35,7 +35,7 @@ InternalDocumentStateData* InternalDocumentStateData::FromDocumentLoader(
InternalDocumentStateData* InternalDocumentStateData::FromDocumentState(
DocumentState* ds) {
if (!ds)
- return NULL;
+ return nullptr;
InternalDocumentStateData* data = static_cast<InternalDocumentStateData*>(
ds->GetUserData(&kUserDataKey));
if (!data) {
diff --git a/chromium/content/renderer/internal_document_state_data.h b/chromium/content/renderer/internal_document_state_data.h
index 3f78f000182..2c01d0b5c44 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/WebKit/public/platform/WebCachePolicy.h"
+#include "third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
#include "url/gurl.h"
namespace blink {
@@ -63,16 +63,16 @@ class InternalDocumentStateData : public base::SupportsUserData::Data {
// Sets the cache policy. The cache policy is only used if explicitly set and
// by default is not set. You can mark a NavigationState as not having a cache
// state by way of clear_cache_policy_override.
- void set_cache_policy_override(blink::WebCachePolicy cache_policy) {
+ void set_cache_policy_override(blink::mojom::FetchCacheMode cache_policy) {
cache_policy_override_ = cache_policy;
cache_policy_override_set_ = true;
}
- blink::WebCachePolicy cache_policy_override() const {
+ blink::mojom::FetchCacheMode cache_policy_override() const {
return cache_policy_override_;
}
void clear_cache_policy_override() {
cache_policy_override_set_ = false;
- cache_policy_override_ = blink::WebCachePolicy::kUseProtocolCachePolicy;
+ cache_policy_override_ = blink::mojom::FetchCacheMode::kDefault;
}
bool is_cache_policy_override_set() const {
return cache_policy_override_set_;
@@ -85,7 +85,7 @@ class InternalDocumentStateData : public base::SupportsUserData::Data {
bool is_overriding_user_agent_;
bool must_reset_scroll_and_scale_state_;
bool cache_policy_override_set_;
- blink::WebCachePolicy cache_policy_override_;
+ blink::mojom::FetchCacheMode cache_policy_override_;
DISALLOW_COPY_AND_ASSIGN(InternalDocumentStateData);
};
diff --git a/chromium/content/renderer/java/gin_java_bridge_value_converter.cc b/chromium/content/renderer/java/gin_java_bridge_value_converter.cc
index 8a6230db97c..3d929edae6e 100644
--- a/chromium/content/renderer/java/gin_java_bridge_value_converter.cc
+++ b/chromium/content/renderer/java/gin_java_bridge_value_converter.cc
@@ -85,7 +85,7 @@ class TypedArraySerializerImpl : public TypedArraySerializer {
*end = element + typed_array_->Length();
element != end;
++element) {
- out->Append(base::MakeUnique<base::Value>(ListType(*element)));
+ out->Append(std::make_unique<base::Value>(ListType(*element)));
}
}
diff --git a/chromium/content/renderer/java/gin_java_bridge_value_converter.h b/chromium/content/renderer/java/gin_java_bridge_value_converter.h
index 9ab3849a3f5..d1f0310cab6 100644
--- a/chromium/content/renderer/java/gin_java_bridge_value_converter.h
+++ b/chromium/content/renderer/java/gin_java_bridge_value_converter.h
@@ -9,7 +9,7 @@
#include "base/macros.h"
#include "content/common/content_export.h"
-#include "content/public/child/v8_value_converter.h"
+#include "content/public/renderer/v8_value_converter.h"
namespace content {
diff --git a/chromium/content/renderer/java/gin_java_function_invocation_helper.cc b/chromium/content/renderer/java/gin_java_function_invocation_helper.cc
index 873e2032e6c..78f890cb9c2 100644
--- a/chromium/content/renderer/java/gin_java_function_invocation_helper.cc
+++ b/chromium/content/renderer/java/gin_java_function_invocation_helper.cc
@@ -10,7 +10,7 @@
#include "base/values.h"
#include "content/common/android/gin_java_bridge_errors.h"
#include "content/common/android/gin_java_bridge_value.h"
-#include "content/public/child/v8_value_converter.h"
+#include "content/public/renderer/v8_value_converter.h"
#include "content/renderer/java/gin_java_bridge_object.h"
#include "content/renderer/java/gin_java_bridge_value_converter.h"
@@ -69,7 +69,7 @@ v8::Local<v8::Value> GinJavaFunctionInvocationHelper::Invoke(
if (arg.get())
arguments.Append(std::move(arg));
else
- arguments.Append(base::MakeUnique<base::Value>());
+ arguments.Append(std::make_unique<base::Value>());
}
}
diff --git a/chromium/content/renderer/loader/OWNERS b/chromium/content/renderer/loader/OWNERS
new file mode 100644
index 00000000000..acbf93af41e
--- /dev/null
+++ b/chromium/content/renderer/loader/OWNERS
@@ -0,0 +1 @@
+yhirano@chromium.org
diff --git a/chromium/content/child/child_resource_message_filter.cc b/chromium/content/renderer/loader/child_resource_message_filter.cc
index b1571e7a670..542dc86f252 100644
--- a/chromium/content/child/child_resource_message_filter.cc
+++ b/chromium/content/renderer/loader/child_resource_message_filter.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/child_resource_message_filter.h"
+#include "content/renderer/loader/child_resource_message_filter.h"
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/resource_dispatcher.h"
#include "content/common/resource_messages.h"
+#include "content/renderer/loader/resource_dispatcher.h"
namespace content {
diff --git a/chromium/content/child/child_resource_message_filter.h b/chromium/content/renderer/loader/child_resource_message_filter.h
index 2059a29b18a..a8315fc8049 100644
--- a/chromium/content/child/child_resource_message_filter.h
+++ b/chromium/content/renderer/loader/child_resource_message_filter.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_CHILD_CHILD_RESOURCE_MESSAGE_FILTER_H_
-#define CONTENT_CHILD_CHILD_RESOURCE_MESSAGE_FILTER_H_
+#ifndef CONTENT_RENDERER_LOADER_CHILD_RESOURCE_MESSAGE_FILTER_H_
+#define CONTENT_RENDERER_LOADER_CHILD_RESOURCE_MESSAGE_FILTER_H_
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -51,4 +51,4 @@ class ChildResourceMessageFilter : public IPC::MessageFilter {
} // namespace content
-#endif // CONTENT_CHILD_CHILD_RESOURCE_MESSAGE_FILTER_H_
+#endif // CONTENT_RENDERER_LOADER_CHILD_RESOURCE_MESSAGE_FILTER_H_
diff --git a/chromium/content/child/child_url_loader_factory_getter_impl.cc b/chromium/content/renderer/loader/child_url_loader_factory_getter_impl.cc
index 92a0fcabb8e..08056249ef0 100644
--- a/chromium/content/child/child_url_loader_factory_getter_impl.cc
+++ b/chromium/content/renderer/loader/child_url_loader_factory_getter_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/child_url_loader_factory_getter_impl.h"
+#include "content/renderer/loader/child_url_loader_factory_getter_impl.h"
#include "base/feature_list.h"
#include "content/public/common/content_features.h"
diff --git a/chromium/content/child/child_url_loader_factory_getter_impl.h b/chromium/content/renderer/loader/child_url_loader_factory_getter_impl.h
index b1c78003313..52bc4bcb44f 100644
--- a/chromium/content/child/child_url_loader_factory_getter_impl.h
+++ b/chromium/content/renderer/loader/child_url_loader_factory_getter_impl.h
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_CHILD_URL_LOADER_FACTORY_GETTER_IMPL_H_
-#define CONTENT_CHILD_CHILD_URL_LOADER_FACTORY_GETTER_IMPL_H_
+#ifndef CONTENT_RENDERER_LOADER_CHILD_URL_LOADER_FACTORY_GETTER_IMPL_H_
+#define CONTENT_RENDERER_LOADER_CHILD_URL_LOADER_FACTORY_GETTER_IMPL_H_
#include "base/callback.h"
#include "content/common/content_export.h"
#include "content/common/possibly_associated_interface_ptr.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
namespace content {
@@ -53,4 +53,4 @@ class CONTENT_EXPORT ChildURLLoaderFactoryGetterImpl
} // namespace content
-#endif // CONTENT_CHILD_CHILD_URL_LOADER_FACTORY_GETTER_IMPL_H_
+#endif // CONTENT_RENDERER_LOADER_CHILD_URL_LOADER_FACTORY_GETTER_IMPL_H_
diff --git a/chromium/content/renderer/loader/cors_url_loader.cc b/chromium/content/renderer/loader/cors_url_loader.cc
new file mode 100644
index 00000000000..5cc36f84d1f
--- /dev/null
+++ b/chromium/content/renderer/loader/cors_url_loader.cc
@@ -0,0 +1,219 @@
+// Copyright 2017 The Chromium Authors. 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/loader/cors_url_loader.h"
+
+#include "content/public/common/origin_util.h"
+#include "content/public/common/service_worker_modes.h"
+#include "third_party/WebKit/public/platform/WebCORS.h"
+#include "third_party/WebKit/public/platform/WebHTTPHeaderMap.h"
+#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
+#include "third_party/WebKit/public/platform/WebURLRequest.h"
+
+using network::mojom::CORSError;
+using network::mojom::FetchRequestMode;
+
+namespace content {
+
+namespace {
+
+bool CalculateCORSFlag(const ResourceRequest& request) {
+ if (request.fetch_request_mode == FetchRequestMode::kNavigate &&
+ (request.resource_type == RESOURCE_TYPE_MAIN_FRAME ||
+ request.resource_type == RESOURCE_TYPE_SUB_FRAME)) {
+ return false;
+ }
+ url::Origin url_origin = url::Origin::Create(request.url);
+ if (IsOriginWhiteListedTrustworthy(url_origin))
+ return false;
+ if (!request.request_initiator.has_value())
+ return true;
+ url::Origin security_origin(request.request_initiator.value());
+ return !security_origin.IsSameOriginWith(url_origin);
+}
+
+} // namespace
+
+// TODO(toyoshim): At the moment this class simply forwards all calls to the
+// underlying network loader. Part of the effort to move CORS handling out of
+// Blink: http://crbug/736308.
+CORSURLLoader::CORSURLLoader(
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const ResourceRequest& resource_request,
+ mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
+ mojom::URLLoaderFactory* network_loader_factory)
+ : network_loader_factory_(network_loader_factory),
+ network_client_binding_(this),
+ forwarding_client_(std::move(client)),
+ security_origin_(
+ resource_request.request_initiator.value_or(url::Origin())),
+ last_response_url_(resource_request.url),
+ fetch_request_mode_(resource_request.fetch_request_mode),
+ fetch_credentials_mode_(resource_request.fetch_credentials_mode),
+ fetch_cors_flag_(CalculateCORSFlag(resource_request)) {
+ DCHECK(network_loader_factory_);
+
+ if (fetch_cors_flag_ &&
+ fetch_request_mode_ == FetchRequestMode::kSameOrigin) {
+ forwarding_client_->OnComplete(network::URLLoaderCompletionStatus(
+ network::CORSErrorStatus(CORSError::kDisallowedByMode)));
+ return;
+ }
+
+ // TODO(toyoshim): Needs some checks if the calculated fetch_cors_flag_
+ // is allowed in this request or not.
+
+ mojom::URLLoaderClientPtr network_client;
+ network_client_binding_.Bind(mojo::MakeRequest(&network_client));
+ // Binding |this| as an unretained pointer is safe because
+ // |network_client_binding_| shares this object's lifetime.
+ network_client_binding_.set_connection_error_handler(base::BindOnce(
+ &CORSURLLoader::OnUpstreamConnectionError, base::Unretained(this)));
+ network_loader_factory_->CreateLoaderAndStart(
+ mojo::MakeRequest(&network_loader_), routing_id, request_id, options,
+ resource_request, std::move(network_client), traffic_annotation);
+}
+
+CORSURLLoader::~CORSURLLoader() {}
+
+void CORSURLLoader::FollowRedirect() {
+ DCHECK(network_loader_);
+ DCHECK(is_waiting_follow_redirect_call_);
+ is_waiting_follow_redirect_call_ = false;
+ network_loader_->FollowRedirect();
+}
+
+void CORSURLLoader::SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) {
+ // TODO(toyoshim): Should not be called during the redirect decisions, but
+ // Blink calls actually.
+ // DCHECK(!is_waiting_follow_redirect_call_);
+ if (network_loader_)
+ network_loader_->SetPriority(priority, intra_priority_value);
+}
+
+void CORSURLLoader::PauseReadingBodyFromNet() {
+ DCHECK(!is_waiting_follow_redirect_call_);
+ if (network_loader_)
+ network_loader_->PauseReadingBodyFromNet();
+}
+
+void CORSURLLoader::ResumeReadingBodyFromNet() {
+ DCHECK(!is_waiting_follow_redirect_call_);
+ if (network_loader_)
+ network_loader_->ResumeReadingBodyFromNet();
+}
+
+void CORSURLLoader::OnReceiveResponse(
+ const ResourceResponseHead& response_head,
+ const base::Optional<net::SSLInfo>& ssl_info,
+ mojom::DownloadedTempFilePtr downloaded_file) {
+ DCHECK(network_loader_);
+ DCHECK(forwarding_client_);
+ DCHECK(!is_waiting_follow_redirect_call_);
+ if (fetch_cors_flag_ &&
+ blink::WebCORS::IsCORSEnabledRequestMode(fetch_request_mode_)) {
+ base::Optional<CORSError> cors_error = blink::WebCORS::CheckAccess(
+ last_response_url_, response_head.headers->response_code(),
+ blink::WebHTTPHeaderMap(response_head.headers.get()),
+ fetch_credentials_mode_, security_origin_);
+ if (cors_error) {
+ // TODO(toyoshim): Generate related_response_headers here.
+ network::CORSErrorStatus cors_error_status(*cors_error);
+ HandleComplete(network::URLLoaderCompletionStatus(cors_error_status));
+ return;
+ }
+ }
+ forwarding_client_->OnReceiveResponse(response_head, ssl_info,
+ std::move(downloaded_file));
+}
+
+void CORSURLLoader::OnReceiveRedirect(
+ const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& response_head) {
+ DCHECK(network_loader_);
+ DCHECK(forwarding_client_);
+ DCHECK(!is_waiting_follow_redirect_call_);
+
+ // TODO(toyoshim): Following code expects OnReceivedRedirect is invoked
+ // asynchronously, and |last_response_url_| and other methods should not be
+ // accessed until FollowRedirect() is called.
+ // We need to ensure callback behaviors once redirect implementation in this
+ // class is ready for testing.
+ is_waiting_follow_redirect_call_ = true;
+ last_response_url_ = redirect_info.new_url;
+ forwarding_client_->OnReceiveRedirect(redirect_info, response_head);
+}
+
+void CORSURLLoader::OnDataDownloaded(int64_t data_len,
+ int64_t encoded_data_len) {
+ DCHECK(network_loader_);
+ DCHECK(forwarding_client_);
+ DCHECK(!is_waiting_follow_redirect_call_);
+ forwarding_client_->OnDataDownloaded(data_len, encoded_data_len);
+}
+
+void CORSURLLoader::OnUploadProgress(int64_t current_position,
+ int64_t total_size,
+ OnUploadProgressCallback ack_callback) {
+ DCHECK(network_loader_);
+ DCHECK(forwarding_client_);
+ DCHECK(!is_waiting_follow_redirect_call_);
+ forwarding_client_->OnUploadProgress(current_position, total_size,
+ std::move(ack_callback));
+}
+
+void CORSURLLoader::OnReceiveCachedMetadata(const std::vector<uint8_t>& data) {
+ DCHECK(network_loader_);
+ DCHECK(forwarding_client_);
+ DCHECK(!is_waiting_follow_redirect_call_);
+ forwarding_client_->OnReceiveCachedMetadata(data);
+}
+
+void CORSURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
+ DCHECK(network_loader_);
+ DCHECK(forwarding_client_);
+ DCHECK(!is_waiting_follow_redirect_call_);
+ forwarding_client_->OnTransferSizeUpdated(transfer_size_diff);
+}
+
+void CORSURLLoader::OnStartLoadingResponseBody(
+ mojo::ScopedDataPipeConsumerHandle body) {
+ DCHECK(network_loader_);
+ DCHECK(forwarding_client_);
+ DCHECK(!is_waiting_follow_redirect_call_);
+ forwarding_client_->OnStartLoadingResponseBody(std::move(body));
+}
+
+void CORSURLLoader::OnComplete(
+ const network::URLLoaderCompletionStatus& status) {
+ DCHECK(network_loader_);
+ DCHECK(forwarding_client_);
+ DCHECK(!is_waiting_follow_redirect_call_);
+ HandleComplete(status);
+}
+
+void CORSURLLoader::OnUpstreamConnectionError() {
+ // |network_client_binding_| has experienced a connection error and will no
+ // longer call any of the mojom::URLLoaderClient methods above. The client
+ // pipe to the downstream client is closed to inform it of this failure. The
+ // client should respond by closing its mojom::URLLoader pipe which will cause
+ // this object to be destroyed.
+ forwarding_client_.reset();
+}
+
+void CORSURLLoader::HandleComplete(
+ const network::URLLoaderCompletionStatus& status) {
+ forwarding_client_->OnComplete(status);
+ forwarding_client_.reset();
+
+ // Close pipes to ignore possible subsequent callback invocations.
+ network_client_binding_.Close();
+ network_loader_.reset();
+}
+
+} // namespace content
diff --git a/chromium/content/child/loader/cors_url_loader.h b/chromium/content/renderer/loader/cors_url_loader.h
index efa8f941dd9..768319497a7 100644
--- a/chromium/content/child/loader/cors_url_loader.h
+++ b/chromium/content/renderer/loader/cors_url_loader.h
@@ -2,19 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_LOADER_CORS_URL_LOADER_H_
-#define CONTENT_CHILD_LOADER_CORS_URL_LOADER_H_
+#ifndef CONTENT_RENDERER_LOADER_CORS_URL_LOADER_H_
+#define CONTENT_RENDERER_LOADER_CORS_URL_LOADER_H_
#include "content/public/common/url_loader_factory.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/public/interfaces/fetch_api.mojom.h"
+#include "url/gurl.h"
+#include "url/origin.h"
namespace content {
// Wrapper class that adds cross-origin resource sharing capabilities
-// (https://www.w3.org/TR/cors/), delegating requests as well as potential
-// preflight requests to the supplied |network_loader_factory|. It is owned by
-// the CORSURLLoaderFactory that created it.
+// (https://fetch.spec.whatwg.org/#http-cors-protocol), delegating requests as
+// well as potential preflight requests to the supplied
+// |network_loader_factory|. It is owned by the CORSURLLoaderFactory that
+// created it.
class CONTENT_EXPORT CORSURLLoader : public mojom::URLLoader,
public mojom::URLLoaderClient {
public:
@@ -51,14 +55,16 @@ class CONTENT_EXPORT CORSURLLoader : public mojom::URLLoader,
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- void OnComplete(
- const ResourceRequestCompletionStatus& completion_status) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
+ private:
// Called when there is a connection error on the upstream pipe used for the
// actual request.
void OnUpstreamConnectionError();
- private:
+ // Handles OnComplete() callback.
+ void HandleComplete(const network::URLLoaderCompletionStatus& status);
+
// This raw URLLoaderFactory pointer is shared with the CORSURLLoaderFactory
// that created and owns this object.
mojom::URLLoaderFactory* network_loader_factory_;
@@ -70,9 +76,25 @@ class CONTENT_EXPORT CORSURLLoader : public mojom::URLLoader,
// To be a URLLoader for the client.
mojom::URLLoaderClientPtr forwarding_client_;
+ // Request initiator's origin.
+ url::Origin security_origin_;
+
+ // The last response URL, that is usually the requested URL, but can be
+ // different if redirects happen.
+ GURL last_response_url_;
+
+ // A flag to indicate that the instance is waiting for that forwarding_client_
+ // calls FollowRedirect.
+ bool is_waiting_follow_redirect_call_ = false;
+
+ // Corresponds to the Fetch spec, https://fetch.spec.whatwg.org/.
+ network::mojom::FetchRequestMode fetch_request_mode_;
+ network::mojom::FetchCredentialsMode fetch_credentials_mode_;
+ bool fetch_cors_flag_;
+
DISALLOW_COPY_AND_ASSIGN(CORSURLLoader);
};
} // namespace content
-#endif // CONTENT_CHILD_LOADER_CORS_URL_LOADER_H_
+#endif // CONTENT_RENDERER_LOADER_CORS_URL_LOADER_H_
diff --git a/chromium/content/child/loader/cors_url_loader_factory.cc b/chromium/content/renderer/loader/cors_url_loader_factory.cc
index 47295f35b11..741f3ecc6da 100644
--- a/chromium/content/child/loader/cors_url_loader_factory.cc
+++ b/chromium/content/renderer/loader/cors_url_loader_factory.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/loader/cors_url_loader_factory.h"
+#include "content/renderer/loader/cors_url_loader_factory.h"
-#include "content/child/loader/cors_url_loader.h"
#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/renderer/loader/cors_url_loader.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
namespace content {
@@ -48,7 +48,7 @@ void CORSURLLoaderFactory::CreateLoaderAndStart(
// Instances of CORSURLLoader are owned by this class and their pipe so that
// they can share |network_loader_factory_|.
loader_bindings_.AddBinding(
- base::MakeUnique<CORSURLLoader>(
+ std::make_unique<CORSURLLoader>(
routing_id, request_id, options, resource_request, std::move(client),
traffic_annotation, network_loader_factory_.get()),
std::move(request));
diff --git a/chromium/content/child/loader/cors_url_loader_factory.h b/chromium/content/renderer/loader/cors_url_loader_factory.h
index d2336818b64..4fb4f4a9395 100644
--- a/chromium/content/child/loader/cors_url_loader_factory.h
+++ b/chromium/content/renderer/loader/cors_url_loader_factory.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_CHILD_LOADER_CORS_URL_LOADER_FACTORY_H_
-#define CONTENT_CHILD_LOADER_CORS_URL_LOADER_FACTORY_H_
+#ifndef CONTENT_RENDERER_LOADER_CORS_URL_LOADER_FACTORY_H_
+#define CONTENT_RENDERER_LOADER_CORS_URL_LOADER_FACTORY_H_
#include "content/common/content_export.h"
#include "content/common/possibly_associated_interface_ptr.h"
@@ -56,4 +56,4 @@ class CONTENT_EXPORT CORSURLLoaderFactory : public mojom::URLLoaderFactory {
} // namespace content
-#endif // CONTENT_CHILD_LOADER_CORS_URL_LOADER_FACTORY_H_
+#endif // CONTENT_RENDERER_LOADER_CORS_URL_LOADER_FACTORY_H_
diff --git a/chromium/content/renderer/loader/cors_url_loader_unittest.cc b/chromium/content/renderer/loader/cors_url_loader_unittest.cc
new file mode 100644
index 00000000000..a60c52db028
--- /dev/null
+++ b/chromium/content/renderer/loader/cors_url_loader_unittest.cc
@@ -0,0 +1,250 @@
+// Copyright 2017 The Chromium Authors. 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/loader/cors_url_loader.h"
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "content/public/common/url_loader.mojom.h"
+#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/public/test/test_url_loader_client.h"
+#include "content/renderer/loader/cors_url_loader_factory.h"
+#include "net/http/http_request_headers.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using network::mojom::FetchRequestMode;
+
+namespace content {
+namespace {
+
+class TestURLLoaderFactory : public mojom::URLLoaderFactory {
+ public:
+ TestURLLoaderFactory() = default;
+ ~TestURLLoaderFactory() override = default;
+
+ void NotifyClientOnReceiveResponse(const std::string& extra_header) {
+ DCHECK(client_ptr_);
+ ResourceResponseHead response;
+ response.headers = new net::HttpResponseHeaders(
+ "HTTP/1.1 200 OK\n"
+ "Content-Type: image/png\n");
+ if (!extra_header.empty())
+ response.headers->AddHeader(extra_header);
+
+ client_ptr_->OnReceiveResponse(response, base::nullopt /* ssl_info */,
+ nullptr /* downloaded_file */);
+ }
+
+ void NotifyClientOnComplete(int error_code) {
+ DCHECK(client_ptr_);
+ client_ptr_->OnComplete(network::URLLoaderCompletionStatus(error_code));
+ }
+
+ bool IsCreateLoaderAndStartCalled() { return !!client_ptr_; }
+
+ private:
+ // mojom::URLLoaderFactory implementation.
+ void CreateLoaderAndStart(mojom::URLLoaderRequest request,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const ResourceRequest& url_request,
+ mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag&
+ traffic_annotation) override {
+ DCHECK(client);
+ client_ptr_ = std::move(client);
+ }
+
+ void Clone(mojom::URLLoaderFactoryRequest request) override { NOTREACHED(); }
+
+ mojom::URLLoaderClientPtr client_ptr_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestURLLoaderFactory);
+};
+
+class CORSURLLoaderTest : public testing::Test {
+ public:
+ CORSURLLoaderTest()
+ : test_network_factory_binding_(&test_network_loader_factory_) {}
+
+ protected:
+ void CreateLoaderAndStart(const GURL& origin,
+ const GURL& url,
+ FetchRequestMode fetch_request_mode) {
+ mojom::URLLoaderFactoryPtr network_factory_ptr;
+ test_network_factory_binding_.Bind(mojo::MakeRequest(&network_factory_ptr));
+
+ mojom::URLLoaderFactoryPtr loader_factory_ptr;
+ CORSURLLoaderFactory::CreateAndBind(network_factory_ptr.PassInterface(),
+ mojo::MakeRequest(&loader_factory_ptr));
+
+ ResourceRequest request;
+ request.resource_type = RESOURCE_TYPE_IMAGE;
+ request.fetch_request_context_type = REQUEST_CONTEXT_TYPE_IMAGE;
+ request.fetch_request_mode = fetch_request_mode;
+ request.method = net::HttpRequestHeaders::kGetMethod;
+ request.url = url;
+ request.request_initiator = url::Origin::Create(origin);
+
+ loader_factory_ptr->CreateLoaderAndStart(
+ mojo::MakeRequest(&url_loader_), 0 /* routing_id */, 0 /* request_id */,
+ mojom::kURLLoadOptionNone, request,
+ test_cors_loader_client_.CreateInterfacePtr(),
+ net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
+
+ // Flushes to ensure that the request is handled and
+ // TestURLLoaderFactory::CreateLoaderAndStart() runs internally.
+ loader_factory_ptr.FlushForTesting();
+ }
+
+ bool IsNetworkLoaderStarted() {
+ return test_network_loader_factory_.IsCreateLoaderAndStartCalled();
+ }
+
+ void NotifyLoaderClientOnReceiveResponse(
+ const std::string& extra_header = std::string()) {
+ test_network_loader_factory_.NotifyClientOnReceiveResponse(extra_header);
+ }
+
+ void NotifyLoaderClientOnComplete(int error_code) {
+ test_network_loader_factory_.NotifyClientOnComplete(error_code);
+ }
+
+ const TestURLLoaderClient& client() const { return test_cors_loader_client_; }
+
+ void RunUntilComplete() { test_cors_loader_client_.RunUntilComplete(); }
+
+ private:
+ // Be the first member so it is destroyed last.
+ base::MessageLoop message_loop_;
+
+ // TestURLLoaderFactory instance and mojo binding.
+ TestURLLoaderFactory test_network_loader_factory_;
+ mojo::Binding<mojom::URLLoaderFactory> test_network_factory_binding_;
+
+ // Holds URLLoaderPtr that CreateLoaderAndStart() creates.
+ mojom::URLLoaderPtr url_loader_;
+
+ // TestURLLoaderClient that records callback activities.
+ TestURLLoaderClient test_cors_loader_client_;
+
+ DISALLOW_COPY_AND_ASSIGN(CORSURLLoaderTest);
+};
+
+TEST_F(CORSURLLoaderTest, SameOriginRequest) {
+ const GURL url("http://example.com/foo.png");
+ CreateLoaderAndStart(url.GetOrigin(), url, FetchRequestMode::kSameOrigin);
+
+ NotifyLoaderClientOnReceiveResponse();
+ NotifyLoaderClientOnComplete(net::OK);
+
+ RunUntilComplete();
+
+ EXPECT_TRUE(IsNetworkLoaderStarted());
+ EXPECT_FALSE(client().has_received_redirect());
+ EXPECT_TRUE(client().has_received_response());
+ EXPECT_TRUE(client().has_received_completion());
+ EXPECT_EQ(net::OK, client().completion_status().error_code);
+}
+
+TEST_F(CORSURLLoaderTest, CrossOriginRequestWithNoCORSMode) {
+ const GURL origin("http://example.com");
+ const GURL url("http://other.com/foo.png");
+ CreateLoaderAndStart(origin, url, FetchRequestMode::kNoCORS);
+
+ NotifyLoaderClientOnReceiveResponse();
+ NotifyLoaderClientOnComplete(net::OK);
+
+ RunUntilComplete();
+
+ EXPECT_TRUE(IsNetworkLoaderStarted());
+ EXPECT_FALSE(client().has_received_redirect());
+ EXPECT_TRUE(client().has_received_response());
+ EXPECT_TRUE(client().has_received_completion());
+ EXPECT_EQ(net::OK, client().completion_status().error_code);
+}
+
+TEST_F(CORSURLLoaderTest, CrossOriginRequestFetchRequestModeSameOrigin) {
+ const GURL origin("http://example.com");
+ const GURL url("http://other.com/foo.png");
+ CreateLoaderAndStart(origin, url,
+ network::mojom::FetchRequestMode::kSameOrigin);
+
+ RunUntilComplete();
+
+ // This call never hits the network URLLoader (i.e. the TestURLLoaderFactory)
+ // because it is fails right away.
+ EXPECT_FALSE(IsNetworkLoaderStarted());
+ EXPECT_FALSE(client().has_received_redirect());
+ EXPECT_FALSE(client().has_received_response());
+ EXPECT_EQ(net::ERR_FAILED, client().completion_status().error_code);
+ ASSERT_TRUE(client().completion_status().cors_error_status);
+ EXPECT_EQ(network::mojom::CORSError::kDisallowedByMode,
+ client().completion_status().cors_error_status->cors_error);
+}
+
+TEST_F(CORSURLLoaderTest, CrossOriginRequestWithCORSModeButMissingCORSHeader) {
+ const GURL origin("http://example.com");
+ const GURL url("http://other.com/foo.png");
+ CreateLoaderAndStart(origin, url, FetchRequestMode::kCORS);
+
+ NotifyLoaderClientOnReceiveResponse();
+ NotifyLoaderClientOnComplete(net::OK);
+
+ RunUntilComplete();
+
+ EXPECT_TRUE(IsNetworkLoaderStarted());
+ EXPECT_FALSE(client().has_received_redirect());
+ EXPECT_FALSE(client().has_received_response());
+ EXPECT_EQ(net::ERR_FAILED, client().completion_status().error_code);
+ ASSERT_TRUE(client().completion_status().cors_error_status);
+ EXPECT_EQ(network::mojom::CORSError::kMissingAllowOriginHeader,
+ client().completion_status().cors_error_status->cors_error);
+}
+
+TEST_F(CORSURLLoaderTest, CrossOriginRequestWithCORSMode) {
+ const GURL origin("http://example.com");
+ const GURL url("http://other.com/foo.png");
+ CreateLoaderAndStart(origin, url, FetchRequestMode::kCORS);
+
+ NotifyLoaderClientOnReceiveResponse(
+ "Access-Control-Allow-Origin: http://example.com");
+ NotifyLoaderClientOnComplete(net::OK);
+
+ RunUntilComplete();
+
+ EXPECT_TRUE(IsNetworkLoaderStarted());
+ EXPECT_FALSE(client().has_received_redirect());
+ EXPECT_TRUE(client().has_received_response());
+ EXPECT_TRUE(client().has_received_completion());
+ EXPECT_EQ(net::OK, client().completion_status().error_code);
+}
+
+TEST_F(CORSURLLoaderTest,
+ CrossOriginRequestFetchRequestWithCORSModeButMismatchedCORSHeader) {
+ const GURL origin("http://example.com");
+ const GURL url("http://other.com/foo.png");
+ CreateLoaderAndStart(origin, url, FetchRequestMode::kCORS);
+
+ NotifyLoaderClientOnReceiveResponse(
+ "Access-Control-Allow-Origin: http://some-other-domain.com");
+ NotifyLoaderClientOnComplete(net::OK);
+
+ RunUntilComplete();
+
+ EXPECT_TRUE(IsNetworkLoaderStarted());
+ EXPECT_FALSE(client().has_received_redirect());
+ EXPECT_FALSE(client().has_received_response());
+ EXPECT_EQ(net::ERR_FAILED, client().completion_status().error_code);
+ ASSERT_TRUE(client().completion_status().cors_error_status);
+ EXPECT_EQ(network::mojom::CORSError::kAllowOriginMismatch,
+ client().completion_status().cors_error_status->cors_error);
+}
+
+} // namespace
+} // namespace content
diff --git a/chromium/content/child/ftp_directory_listing_response_delegate.cc b/chromium/content/renderer/loader/ftp_directory_listing_response_delegate.cc
index e2534202ceb..fb99d337070 100644
--- a/chromium/content/child/ftp_directory_listing_response_delegate.cc
+++ b/chromium/content/renderer/loader/ftp_directory_listing_response_delegate.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/ftp_directory_listing_response_delegate.h"
+#include "content/renderer/loader/ftp_directory_listing_response_delegate.h"
#include <stddef.h>
#include <stdint.h>
@@ -16,7 +16,7 @@
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
-#include "content/child/weburlresponse_extradata_impl.h"
+#include "content/renderer/loader/weburlresponse_extradata_impl.h"
#include "net/base/directory_listing.h"
#include "net/base/escape.h"
#include "net/base/net_errors.h"
diff --git a/chromium/content/child/ftp_directory_listing_response_delegate.h b/chromium/content/renderer/loader/ftp_directory_listing_response_delegate.h
index 0d1a61f3e97..d98d2b7ffe4 100644
--- a/chromium/content/child/ftp_directory_listing_response_delegate.h
+++ b/chromium/content/renderer/loader/ftp_directory_listing_response_delegate.h
@@ -5,8 +5,8 @@
// A delegate class of WebURLLoaderImpl that handles text/vnd.chromium.ftp-dir
// data.
-#ifndef CONTENT_CHILD_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_
-#define CONTENT_CHILD_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_
+#ifndef CONTENT_RENDERER_LOADER_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_
+#define CONTENT_RENDERER_LOADER_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_
#include <string>
@@ -53,4 +53,4 @@ class FtpDirectoryListingResponseDelegate {
} // namespace content
-#endif // CONTENT_CHILD_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_
+#endif // CONTENT_RENDERER_LOADER_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_
diff --git a/chromium/content/child/request_extra_data.cc b/chromium/content/renderer/loader/request_extra_data.cc
index 1d400ac128c..ea53c655933 100644
--- a/chromium/content/child/request_extra_data.cc
+++ b/chromium/content/renderer/loader/request_extra_data.cc
@@ -2,19 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/request_extra_data.h"
+#include "content/renderer/loader/request_extra_data.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/resource_request.h"
#include "content/public/common/service_worker_modes.h"
#include "ipc/ipc_message.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
using blink::WebString;
namespace content {
RequestExtraData::RequestExtraData()
- : visibility_state_(blink::kWebPageVisibilityStateVisible),
+ : visibility_state_(blink::mojom::PageVisibilityState::kVisible),
render_frame_id_(MSG_ROUTING_NONE),
is_main_frame_(false),
allow_download_(true),
diff --git a/chromium/content/child/request_extra_data.h b/chromium/content/renderer/loader/request_extra_data.h
index 2240a4655ef..d2b78f4195c 100644
--- a/chromium/content/child/request_extra_data.h
+++ b/chromium/content/renderer/loader/request_extra_data.h
@@ -9,11 +9,11 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "content/child/web_url_loader_impl.h"
#include "content/common/content_export.h"
#include "content/common/navigation_params.h"
#include "content/public/common/url_loader_throttle.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
+#include "content/renderer/loader/web_url_loader_impl.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "ui/base/page_transition_types.h"
@@ -31,7 +31,8 @@ class CONTENT_EXPORT RequestExtraData : public blink::WebURLRequest::ExtraData {
RequestExtraData();
~RequestExtraData() override;
- void set_visibility_state(blink::WebPageVisibilityState visibility_state) {
+ void set_visibility_state(
+ blink::mojom::PageVisibilityState visibility_state) {
visibility_state_ = visibility_state;
}
void set_render_frame_id(int render_frame_id) {
@@ -146,7 +147,7 @@ class CONTENT_EXPORT RequestExtraData : public blink::WebURLRequest::ExtraData {
void CopyToResourceRequest(ResourceRequest* request) const;
private:
- blink::WebPageVisibilityState visibility_state_;
+ blink::mojom::PageVisibilityState visibility_state_;
int render_frame_id_;
bool is_main_frame_;
url::Origin frame_origin_;
diff --git a/chromium/content/child/resource_dispatcher.cc b/chromium/content/renderer/loader/resource_dispatcher.cc
index 01c61f4f4a6..0fc8b684ac7 100644
--- a/chromium/content/child/resource_dispatcher.cc
+++ b/chromium/content/renderer/loader/resource_dispatcher.cc
@@ -4,7 +4,7 @@
// See http://dev.chromium.org/developers/design-documents/multi-process-resource-loading
-#include "content/child/resource_dispatcher.h"
+#include "content/renderer/loader/resource_dispatcher.h"
#include <utility>
@@ -22,28 +22,28 @@
#include "base/synchronization/waitable_event.h"
#include "base/task_scheduler/post_task.h"
#include "build/build_config.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/resource_scheduling_filter.h"
-#include "content/child/shared_memory_received_data_factory.h"
-#include "content/child/site_isolation_stats_gatherer.h"
-#include "content/child/sync_load_context.h"
-#include "content/child/sync_load_response.h"
-#include "content/child/url_loader_client_impl.h"
#include "content/common/inter_process_time_ticks_converter.h"
#include "content/common/navigation_params.h"
#include "content/common/resource_messages.h"
#include "content/common/throttling_url_loader.h"
-#include "content/public/child/fixed_received_data.h"
-#include "content/public/child/request_peer.h"
-#include "content/public/child/resource_dispatcher_delegate.h"
#include "content/public/common/content_features.h"
#include "content/public/common/resource_request.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "content/public/common/resource_response.h"
#include "content/public/common/resource_type.h"
+#include "content/public/renderer/fixed_received_data.h"
+#include "content/public/renderer/request_peer.h"
+#include "content/public/renderer/resource_dispatcher_delegate.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/loader/resource_scheduling_filter.h"
+#include "content/renderer/loader/shared_memory_received_data_factory.h"
+#include "content/renderer/loader/site_isolation_stats_gatherer.h"
+#include "content/renderer/loader/sync_load_context.h"
+#include "content/renderer/loader/sync_load_response.h"
+#include "content/renderer/loader/url_loader_client_impl.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/http/http_response_headers.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
namespace content {
@@ -94,7 +94,7 @@ ResourceDispatcher::ResourceDispatcher(
IPC::Sender* sender,
scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner)
: message_sender_(sender),
- delegate_(NULL),
+ delegate_(nullptr),
io_timestamp_(base::TimeTicks()),
thread_task_runner_(thread_task_runner),
weak_factory_(this) {}
@@ -143,7 +143,7 @@ ResourceDispatcher::GetPendingRequestInfo(int request_id) {
PendingRequestMap::iterator it = pending_requests_.find(request_id);
if (it == pending_requests_.end()) {
// This might happen for kill()ed requests on the webkit end.
- return NULL;
+ return nullptr;
}
return it->second.get();
}
@@ -175,8 +175,10 @@ void ResourceDispatcher::OnReceivedResponse(
if (delegate_) {
std::unique_ptr<RequestPeer> new_peer = delegate_->OnReceivedResponse(
- std::move(request_info->peer), response_head.mime_type,
- request_info->url);
+ std::move(request_info->peer), request_info->render_frame_id,
+ request_info->response_url, request_info->response_referrer,
+ request_info->response_method, request_info->resource_type,
+ response_head);
DCHECK(new_peer);
request_info->peer = std::move(new_peer);
}
@@ -186,8 +188,7 @@ void ResourceDispatcher::OnReceivedResponse(
request_info->site_isolation_metadata =
SiteIsolationStatsGatherer::OnReceivedResponse(
request_info->frame_origin, request_info->response_url,
- request_info->resource_type, request_info->origin_pid,
- renderer_response_info);
+ request_info->resource_type, renderer_response_info);
request_info->peer->OnReceivedResponse(renderer_response_info);
}
@@ -206,8 +207,7 @@ void ResourceDispatcher::OnReceivedCachedMetadata(
void ResourceDispatcher::OnSetDataBuffer(int request_id,
base::SharedMemoryHandle shm_handle,
- int shm_size,
- base::ProcessId renderer_pid) {
+ int shm_size) {
TRACE_EVENT0("loader", "ResourceDispatcher::OnSetDataBuffer");
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
if (!request_info)
@@ -224,10 +224,6 @@ void ResourceDispatcher::OnSetDataBuffer(int request_id,
bool ok = request_info->buffer->Map(shm_size);
if (!ok) {
- // Added to help debug crbug/160401.
- base::ProcessId renderer_pid_copy = renderer_pid;
- base::debug::Alias(&renderer_pid_copy);
-
base::SharedMemoryHandle shm_handle_copy = shm_handle;
base::debug::Alias(&shm_handle_copy);
@@ -315,6 +311,8 @@ void ResourceDispatcher::OnReceivedRedirect(
// We update the response_url here so that we can send it to
// SiteIsolationStatsGatherer later when OnReceivedResponse is called.
request_info->response_url = redirect_info.new_url;
+ request_info->response_method = redirect_info.new_method;
+ request_info->response_referrer = GURL(redirect_info.new_referrer);
request_info->pending_redirect_message.reset(
new ResourceHostMsg_FollowRedirect(request_id));
if (!request_info->is_deferred) {
@@ -340,7 +338,7 @@ void ResourceDispatcher::FollowPendingRedirect(
void ResourceDispatcher::OnRequestComplete(
int request_id,
- const ResourceRequestCompletionStatus& request_complete_data) {
+ const network::URLLoaderCompletionStatus& status) {
TRACE_EVENT0("loader", "ResourceDispatcher::OnRequestComplete");
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
@@ -358,26 +356,21 @@ void ResourceDispatcher::OnRequestComplete(
if (delegate_) {
std::unique_ptr<RequestPeer> new_peer = delegate_->OnRequestComplete(
std::move(request_info->peer), request_info->resource_type,
- request_complete_data.error_code);
+ status.error_code);
DCHECK(new_peer);
request_info->peer = std::move(new_peer);
}
- base::TimeTicks renderer_completion_time = ToRendererCompletionTime(
- *request_info, request_complete_data.completion_time);
-
// The request ID will be removed from our pending list in the destructor.
// Normally, dispatching this message causes the reference-counted request to
// die immediately.
// TODO(kinuko): Revisit here. This probably needs to call request_info->peer
// but the past attempt to change it seems to have caused crashes.
// (crbug.com/547047)
- peer->OnCompletedRequest(request_complete_data.error_code,
- request_complete_data.exists_in_cache,
- renderer_completion_time,
- request_complete_data.encoded_data_length,
- request_complete_data.encoded_body_length,
- request_complete_data.decoded_body_length);
+ network::URLLoaderCompletionStatus renderer_status(status);
+ renderer_status.completion_time =
+ ToRendererCompletionTime(*request_info, status.completion_time);
+ peer->OnCompletedRequest(renderer_status);
}
bool ResourceDispatcher::RemovePendingRequest(int request_id) {
@@ -484,16 +477,20 @@ void ResourceDispatcher::OnTransferSizeUpdated(int request_id,
ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
std::unique_ptr<RequestPeer> peer,
ResourceType resource_type,
- int origin_pid,
+ int render_frame_id,
const url::Origin& frame_origin,
const GURL& request_url,
+ const std::string& method,
+ const GURL& referrer,
bool download_to_file)
: peer(std::move(peer)),
resource_type(resource_type),
- origin_pid(origin_pid),
+ render_frame_id(render_frame_id),
url(request_url),
frame_origin(frame_origin),
response_url(request_url),
+ response_method(method),
+ response_referrer(referrer),
download_to_file(download_to_file),
request_start(base::TimeTicks::Now()) {}
@@ -631,9 +628,10 @@ int ResourceDispatcher::StartAsync(
// Compute a unique request_id for this renderer process.
int request_id = MakeRequestID();
- pending_requests_[request_id] = base::MakeUnique<PendingRequestInfo>(
- std::move(peer), request->resource_type, request->origin_pid,
- frame_origin, request->url, request->download_to_file);
+ pending_requests_[request_id] = std::make_unique<PendingRequestInfo>(
+ std::move(peer), request->resource_type, request->render_frame_id,
+ frame_origin, request->url, request->method, request->referrer,
+ request->download_to_file);
if (resource_scheduling_filter_.get() && loading_task_runner) {
resource_scheduling_filter_->SetRequestIdTaskRunner(request_id,
@@ -645,7 +643,7 @@ int ResourceDispatcher::StartAsync(
if (consumer_handle.is_valid()) {
pending_requests_[request_id]->url_loader_client =
- base::MakeUnique<URLLoaderClientImpl>(request_id, this, task_runner);
+ std::make_unique<URLLoaderClientImpl>(request_id, this, task_runner);
task_runner->PostTask(
FROM_HERE, base::BindOnce(&ResourceDispatcher::ContinueForNavigation,
@@ -780,14 +778,14 @@ void ResourceDispatcher::ContinueForNavigation(
// Call OnComplete now too, as it won't get called on the client.
// TODO(kinuko): Fill this properly.
- ResourceRequestCompletionStatus completion_status;
- completion_status.error_code = net::OK;
- completion_status.exists_in_cache = false;
- completion_status.completion_time = base::TimeTicks::Now();
- completion_status.encoded_data_length = -1;
- completion_status.encoded_body_length = -1;
- completion_status.decoded_body_length = -1;
- client_ptr->OnComplete(completion_status);
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::OK;
+ status.exists_in_cache = false;
+ status.completion_time = base::TimeTicks::Now();
+ status.encoded_data_length = -1;
+ status.encoded_body_length = -1;
+ status.decoded_body_length = -1;
+ client_ptr->OnComplete(status);
}
// static
diff --git a/chromium/content/child/resource_dispatcher.h b/chromium/content/renderer/loader/resource_dispatcher.h
index 599eeaca035..0313783b98e 100644
--- a/chromium/content/child/resource_dispatcher.h
+++ b/chromium/content/renderer/loader/resource_dispatcher.h
@@ -4,8 +4,8 @@
// See http://dev.chromium.org/developers/design-documents/multi-process-resource-loading
-#ifndef CONTENT_CHILD_RESOURCE_DISPATCHER_H_
-#define CONTENT_CHILD_RESOURCE_DISPATCHER_H_
+#ifndef CONTENT_RENDERER_LOADER_RESOURCE_DISPATCHER_H_
+#define CONTENT_RENDERER_LOADER_RESOURCE_DISPATCHER_H_
#include <stdint.h>
@@ -38,13 +38,16 @@ namespace net {
struct RedirectInfo;
}
+namespace network {
+struct URLLoaderCompletionStatus;
+}
+
namespace content {
class RequestPeer;
class ResourceDispatcherDelegate;
class ResourceSchedulingFilter;
struct ResourceResponseInfo;
struct ResourceRequest;
-struct ResourceRequestCompletionStatus;
struct ResourceResponseHead;
class SharedMemoryReceivedDataFactory;
struct SiteIsolationResponseMetaData;
@@ -177,27 +180,29 @@ class CONTENT_EXPORT ResourceDispatcher : public IPC::Listener {
struct PendingRequestInfo {
PendingRequestInfo(std::unique_ptr<RequestPeer> peer,
ResourceType resource_type,
- int origin_pid,
+ int render_frame_id,
const url::Origin& frame_origin,
const GURL& request_url,
+ const std::string& method,
+ const GURL& referrer,
bool download_to_file);
~PendingRequestInfo();
std::unique_ptr<RequestPeer> peer;
ResourceType resource_type;
- // The PID of the original process which issued this request. This gets
- // non-zero only for a request proxied by another renderer, particularly
- // requests from plugins.
- int origin_pid;
+ int render_frame_id;
MessageQueue deferred_message_queue;
bool is_deferred = false;
// Original requested url.
GURL url;
// The security origin of the frame that initiates this request.
url::Origin frame_origin;
- // The url of the latest response even in case of redirection.
+ // The url, method and referrer of the latest response even in case of
+ // redirection.
GURL response_url;
+ std::string response_method;
+ GURL response_referrer;
bool download_to_file;
std::unique_ptr<IPC::Message> pending_redirect_message;
base::TimeTicks request_start;
@@ -231,16 +236,14 @@ class CONTENT_EXPORT ResourceDispatcher : public IPC::Listener {
const ResourceResponseHead& response_head);
void OnSetDataBuffer(int request_id,
base::SharedMemoryHandle shm_handle,
- int shm_size,
- base::ProcessId renderer_pid);
+ int shm_size);
void OnReceivedData(int request_id,
int data_offset,
int data_length,
int encoded_data_length);
void OnDownloadedData(int request_id, int data_len, int encoded_data_length);
- void OnRequestComplete(
- int request_id,
- const ResourceRequestCompletionStatus& request_complete_data);
+ void OnRequestComplete(int request_id,
+ const network::URLLoaderCompletionStatus& status);
// Dispatch the message to one of the message response handlers.
void DispatchMessage(const IPC::Message& message);
@@ -300,4 +303,4 @@ class CONTENT_EXPORT ResourceDispatcher : public IPC::Listener {
} // namespace content
-#endif // CONTENT_CHILD_RESOURCE_DISPATCHER_H_
+#endif // CONTENT_RENDERER_LOADER_RESOURCE_DISPATCHER_H_
diff --git a/chromium/content/child/resource_dispatcher_unittest.cc b/chromium/content/renderer/loader/resource_dispatcher_unittest.cc
index 4b16b12806f..1f48a73d067 100644
--- a/chromium/content/child/resource_dispatcher_unittest.cc
+++ b/chromium/content/renderer/loader/resource_dispatcher_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 "content/child/resource_dispatcher.h"
+#include "content/renderer/loader/resource_dispatcher.h"
#include <stddef.h>
#include <stdint.h>
@@ -20,24 +20,24 @@
#include "base/process/process_handle.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/test_request_peer.h"
#include "content/common/appcache_interfaces.h"
#include "content/common/resource_messages.h"
-#include "content/public/child/fixed_received_data.h"
-#include "content/public/child/request_peer.h"
-#include "content/public/child/resource_dispatcher_delegate.h"
#include "content/public/common/content_features.h"
#include "content/public/common/request_context_frame_type.h"
#include "content/public/common/resource_request.h"
#include "content/public/common/resource_request_body.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "content/public/common/resource_response.h"
#include "content/public/common/service_worker_modes.h"
+#include "content/public/renderer/fixed_received_data.h"
+#include "content/public/renderer/request_peer.h"
+#include "content/public/renderer/resource_dispatcher_delegate.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/loader/test_request_peer.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/http/http_response_headers.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
#include "url/gurl.h"
@@ -173,7 +173,7 @@ class ResourceDispatcherTest : public testing::Test, public IPC::Sender {
shared_memory->handle().Duplicate();
EXPECT_TRUE(duplicate_handle.IsValid());
EXPECT_TRUE(dispatcher_->OnMessageReceived(ResourceMsg_SetDataBuffer(
- request_id, duplicate_handle, shared_memory->requested_size(), 0)));
+ request_id, duplicate_handle, shared_memory->requested_size())));
}
void NotifyDataReceived(int request_id, const std::string& data) {
@@ -193,12 +193,12 @@ class ResourceDispatcherTest : public testing::Test, public IPC::Sender {
}
void NotifyRequestComplete(int request_id, size_t total_size) {
- ResourceRequestCompletionStatus request_complete_data;
- request_complete_data.error_code = net::OK;
- request_complete_data.exists_in_cache = false;
- request_complete_data.encoded_data_length = total_size;
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::OK;
+ status.exists_in_cache = false;
+ status.encoded_data_length = total_size;
EXPECT_TRUE(dispatcher_->OnMessageReceived(
- ResourceMsg_RequestComplete(request_id, request_complete_data)));
+ ResourceMsg_RequestComplete(request_id, status)));
}
std::unique_ptr<ResourceRequest> CreateResourceRequest(
@@ -211,7 +211,7 @@ class ResourceDispatcherTest : public testing::Test, public IPC::Sender {
request->referrer_policy = blink::kWebReferrerPolicyDefault;
request->resource_type = RESOURCE_TYPE_SUB_RESOURCE;
request->priority = net::LOW;
- request->fetch_request_mode = FETCH_REQUEST_MODE_NO_CORS;
+ request->fetch_request_mode = network::mojom::FetchRequestMode::kNoCORS;
request->fetch_frame_type = REQUEST_CONTEXT_FRAME_TYPE_NONE;
request->download_to_file = download_to_file;
@@ -266,7 +266,7 @@ TEST_F(ResourceDispatcherTest, RoundTrip) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- StartAsync(std::move(request), NULL, &peer_context);
+ StartAsync(std::move(request), nullptr, &peer_context);
int id = ConsumeRequestResource();
EXPECT_EQ(0u, queued_messages());
@@ -297,11 +297,11 @@ TEST_F(ResourceDispatcherTest, MultipleRequests) {
std::unique_ptr<ResourceRequest> request1(CreateResourceRequest(false));
TestRequestPeer::Context peer_context1;
- StartAsync(std::move(request1), NULL, &peer_context1);
+ StartAsync(std::move(request1), nullptr, &peer_context1);
std::unique_ptr<ResourceRequest> request2(CreateResourceRequest(false));
TestRequestPeer::Context peer_context2;
- StartAsync(std::move(request2), NULL, &peer_context2);
+ StartAsync(std::move(request2), nullptr, &peer_context2);
int id1 = ConsumeRequestResource();
int id2 = ConsumeRequestResource();
@@ -338,7 +338,7 @@ TEST_F(ResourceDispatcherTest, MultipleRequests) {
TEST_F(ResourceDispatcherTest, Cancel) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- int request_id = StartAsync(std::move(request), NULL, &peer_context);
+ int request_id = StartAsync(std::move(request), nullptr, &peer_context);
int id = ConsumeRequestResource();
EXPECT_EQ(0u, queued_messages());
@@ -363,7 +363,7 @@ TEST_F(ResourceDispatcherTest, Cancel) {
TEST_F(ResourceDispatcherTest, CancelDuringCallback) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- StartAsync(std::move(request), NULL, &peer_context);
+ StartAsync(std::move(request), nullptr, &peer_context);
peer_context.cancel_on_receive_response = true;
int id = ConsumeRequestResource();
@@ -398,9 +398,13 @@ class TestResourceDispatcherDelegate : public ResourceDispatcherDelegate {
std::unique_ptr<RequestPeer> OnReceivedResponse(
std::unique_ptr<RequestPeer> current_peer,
- const std::string& mime_type,
- const GURL& url) override {
- return base::MakeUnique<WrapperPeer>(std::move(current_peer));
+ int render_frame_id,
+ const GURL& url,
+ const GURL& referrer,
+ const std::string& method,
+ ResourceType resource_type,
+ const ResourceResponseHead& response_head) override {
+ return std::make_unique<WrapperPeer>(std::move(current_peer));
}
class WrapperPeer : public RequestPeer {
@@ -426,20 +430,14 @@ class TestResourceDispatcherDelegate : public ResourceDispatcherDelegate {
}
void OnTransferSizeUpdated(int transfer_size_diff) override {}
- void OnCompletedRequest(int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size) override {
+ void OnCompletedRequest(
+ const network::URLLoaderCompletionStatus& status) override {
original_peer_->OnReceivedResponse(response_info_);
if (!data_.empty()) {
original_peer_->OnReceivedData(
- base::MakeUnique<FixedReceivedData>(data_.data(), data_.size()));
+ std::make_unique<FixedReceivedData>(data_.data(), data_.size()));
}
- original_peer_->OnCompletedRequest(error_code, stale_copy_in_cache,
- completion_time, total_transfer_size,
- encoded_body_size, decoded_body_size);
+ original_peer_->OnCompletedRequest(status);
}
private:
@@ -538,7 +536,7 @@ TEST_F(ResourceDispatcherTest, CancelDuringCallbackWithWrapperPeer) {
TEST_F(ResourceDispatcherTest, Redirect) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- StartAsync(std::move(request), NULL, &peer_context);
+ StartAsync(std::move(request), nullptr, &peer_context);
int id = ConsumeRequestResource();
@@ -569,7 +567,7 @@ TEST_F(ResourceDispatcherTest, Redirect) {
TEST_F(ResourceDispatcherTest, CancelDuringRedirect) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- StartAsync(std::move(request), NULL, &peer_context);
+ StartAsync(std::move(request), nullptr, &peer_context);
peer_context.follow_redirects = false;
int id = ConsumeRequestResource();
@@ -599,7 +597,7 @@ TEST_F(ResourceDispatcherTest, CancelDuringRedirect) {
TEST_F(ResourceDispatcherTest, Defer) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- int request_id = StartAsync(std::move(request), NULL, &peer_context);
+ int request_id = StartAsync(std::move(request), nullptr, &peer_context);
int id = ConsumeRequestResource();
EXPECT_EQ(0u, queued_messages());
@@ -633,7 +631,7 @@ TEST_F(ResourceDispatcherTest, Defer) {
TEST_F(ResourceDispatcherTest, DeferOnRedirect) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- int request_id = StartAsync(std::move(request), NULL, &peer_context);
+ int request_id = StartAsync(std::move(request), nullptr, &peer_context);
peer_context.defer_on_redirect = true;
int id = ConsumeRequestResource();
@@ -672,7 +670,7 @@ TEST_F(ResourceDispatcherTest, DeferOnRedirect) {
TEST_F(ResourceDispatcherTest, CancelDeferredRequest) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- int request_id = StartAsync(std::move(request), NULL, &peer_context);
+ int request_id = StartAsync(std::move(request), nullptr, &peer_context);
int id = ConsumeRequestResource();
EXPECT_EQ(0u, queued_messages());
@@ -697,7 +695,7 @@ TEST_F(ResourceDispatcherTest, CancelDeferredRequest) {
TEST_F(ResourceDispatcherTest, CancelWhileFlushingDeferredRequests) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- int request_id = StartAsync(std::move(request), NULL, &peer_context);
+ int request_id = StartAsync(std::move(request), nullptr, &peer_context);
// Cancel the request when the data message is handled.
peer_context.cancel_on_receive_data = true;
@@ -742,7 +740,7 @@ TEST_F(ResourceDispatcherTest,
CancelWhileFlushingDeferredRequestsFromOnMessageReceived) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- int request_id = StartAsync(std::move(request), NULL, &peer_context);
+ int request_id = StartAsync(std::move(request), nullptr, &peer_context);
// Cancel the request when the data message is handled.
peer_context.cancel_on_receive_data = true;
@@ -802,7 +800,7 @@ TEST_F(ResourceDispatcherTest,
TEST_F(ResourceDispatcherTest, DownloadToFile) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(true));
TestRequestPeer::Context peer_context;
- int request_id = StartAsync(std::move(request), NULL, &peer_context);
+ int request_id = StartAsync(std::move(request), nullptr, &peer_context);
const int kDownloadedIncrement = 100;
const int kEncodedIncrement = 50;
@@ -843,7 +841,7 @@ TEST_F(ResourceDispatcherTest, DownloadToFile) {
TEST_F(ResourceDispatcherTest, CancelDownloadToFile) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(true));
TestRequestPeer::Context peer_context;
- int request_id = StartAsync(std::move(request), NULL, &peer_context);
+ int request_id = StartAsync(std::move(request), nullptr, &peer_context);
int id = ConsumeRequestResource();
EXPECT_EQ(0u, queued_messages());
@@ -876,7 +874,7 @@ class TimeConversionTest : public ResourceDispatcherTest {
void PerformTest(const ResourceResponseHead& response_head) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
TestRequestPeer::Context peer_context;
- StartAsync(std::move(request), NULL, &peer_context);
+ StartAsync(std::move(request), nullptr, &peer_context);
dispatcher()->OnMessageReceived(
ResourceMsg_ReceivedResponse(0, response_head));
diff --git a/chromium/content/child/resource_scheduling_filter.cc b/chromium/content/renderer/loader/resource_scheduling_filter.cc
index 3d09af42f9f..ca0cb037016 100644
--- a/chromium/content/child/resource_scheduling_filter.cc
+++ b/chromium/content/renderer/loader/resource_scheduling_filter.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/resource_scheduling_filter.h"
+#include "content/renderer/loader/resource_scheduling_filter.h"
#include <utility>
#include "base/bind.h"
#include "base/location.h"
-#include "content/child/resource_dispatcher.h"
+#include "content/renderer/loader/resource_dispatcher.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_start.h"
diff --git a/chromium/content/child/resource_scheduling_filter.h b/chromium/content/renderer/loader/resource_scheduling_filter.h
index e355fc8ba15..63233b10c17 100644
--- a/chromium/content/child/resource_scheduling_filter.h
+++ b/chromium/content/renderer/loader/resource_scheduling_filter.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_CHILD_RESOURCE_SCHEDULING_FILTER_H_
-#define CONTENT_CHILD_RESOURCE_SCHEDULING_FILTER_H_
+#ifndef CONTENT_RENDERER_LOADER_RESOURCE_SCHEDULING_FILTER_H_
+#define CONTENT_RENDERER_LOADER_RESOURCE_SCHEDULING_FILTER_H_
#include <stdint.h>
@@ -64,4 +64,4 @@ class CONTENT_EXPORT ResourceSchedulingFilter : public IPC::MessageFilter {
} // namespace content
-#endif // CONTENT_CHILD_RESOURCE_SCHEDULING_FILTER_H_
+#endif // CONTENT_RENDERER_LOADER_RESOURCE_SCHEDULING_FILTER_H_
diff --git a/chromium/content/child/shared_memory_data_consumer_handle.cc b/chromium/content/renderer/loader/shared_memory_data_consumer_handle.cc
index 44c938484c9..f216a6e0072 100644
--- a/chromium/content/child/shared_memory_data_consumer_handle.cc
+++ b/chromium/content/renderer/loader/shared_memory_data_consumer_handle.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/child/shared_memory_data_consumer_handle.h"
+#include "content/renderer/loader/shared_memory_data_consumer_handle.h"
#include <algorithm>
#include <utility>
@@ -15,7 +15,7 @@
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/public/child/fixed_received_data.h"
+#include "content/public/renderer/fixed_received_data.h"
namespace content {
@@ -293,9 +293,9 @@ void SharedMemoryDataConsumerHandle::Writer::AddData(
std::unique_ptr<RequestPeer::ThreadSafeReceivedData> data_to_pass;
if (mode_ == kApplyBackpressure) {
data_to_pass =
- base::MakeUnique<DelegateThreadSafeReceivedData>(std::move(data));
+ std::make_unique<DelegateThreadSafeReceivedData>(std::move(data));
} else {
- data_to_pass = base::MakeUnique<FixedReceivedData>(data.get());
+ data_to_pass = std::make_unique<FixedReceivedData>(data.get());
}
context_->Push(std::move(data_to_pass));
}
diff --git a/chromium/content/child/shared_memory_data_consumer_handle.h b/chromium/content/renderer/loader/shared_memory_data_consumer_handle.h
index b1b1af7e545..c5afb3842ed 100644
--- a/chromium/content/child/shared_memory_data_consumer_handle.h
+++ b/chromium/content/renderer/loader/shared_memory_data_consumer_handle.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_CHILD_SHARED_MEMORY_DATA_CONSUMER_HANDLE_H_
-#define CONTENT_CHILD_SHARED_MEMORY_DATA_CONSUMER_HANDLE_H_
+#ifndef CONTENT_RENDERER_LOADER_SHARED_MEMORY_DATA_CONSUMER_HANDLE_H_
+#define CONTENT_RENDERER_LOADER_SHARED_MEMORY_DATA_CONSUMER_HANDLE_H_
#include <stddef.h>
@@ -13,7 +13,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
-#include "content/public/child/request_peer.h"
+#include "content/public/renderer/request_peer.h"
#include "third_party/WebKit/public/platform/WebDataConsumerHandle.h"
namespace content {
@@ -93,4 +93,4 @@ class CONTENT_EXPORT SharedMemoryDataConsumerHandle final
} // namespace content
-#endif // CONTENT_CHILD_SHARED_MEMORY_DATA_CONSUMER_HANDLE_H_
+#endif // CONTENT_RENDERER_LOADER_SHARED_MEMORY_DATA_CONSUMER_HANDLE_H_
diff --git a/chromium/content/child/shared_memory_data_consumer_handle_unittest.cc b/chromium/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc
index d08e431fca8..fe6d2cdff51 100644
--- a/chromium/content/child/shared_memory_data_consumer_handle_unittest.cc
+++ b/chromium/content/renderer/loader/shared_memory_data_consumer_handle_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 "content/child/shared_memory_data_consumer_handle.h"
+#include "content/renderer/loader/shared_memory_data_consumer_handle.h"
#include <stddef.h>
#include <string.h>
@@ -23,7 +23,7 @@
#include "base/task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/public/child/fixed_received_data.h"
+#include "content/public/renderer/fixed_received_data.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -197,7 +197,7 @@ class SharedMemoryDataConsumerHandleTest
handle_.reset(new SharedMemoryDataConsumerHandle(GetParam(), &writer_));
}
std::unique_ptr<FixedReceivedData> NewFixedData(const char* s) {
- return base::MakeUnique<FixedReceivedData>(s, strlen(s));
+ return std::make_unique<FixedReceivedData>(s, strlen(s));
}
StrictMock<MockClient> client_;
@@ -901,17 +901,17 @@ TEST(SharedMemoryDataConsumerHandleBackpressureTest, Read) {
size_t size;
std::unique_ptr<Writer> writer;
- auto handle = base::MakeUnique<SharedMemoryDataConsumerHandle>(
+ auto handle = std::make_unique<SharedMemoryDataConsumerHandle>(
kApplyBackpressure, &writer);
scoped_refptr<Logger> logger(new Logger);
writer->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data1", "Once ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data1", "Once ", logger));
writer->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data2", "upon ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data2", "upon ", logger));
writer->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data3", "a ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data3", "a ", logger));
writer->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data4", "time ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data4", "time ", logger));
auto reader = handle->ObtainReader(nullptr);
logger->Add("1");
@@ -946,15 +946,15 @@ TEST(SharedMemoryDataConsumerHandleBackpressureTest, CloseAndReset) {
size_t size;
std::unique_ptr<Writer> writer;
- auto handle = base::MakeUnique<SharedMemoryDataConsumerHandle>(
+ auto handle = std::make_unique<SharedMemoryDataConsumerHandle>(
kApplyBackpressure, &writer);
scoped_refptr<Logger> logger(new Logger);
writer->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data1", "Once ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data1", "Once ", logger));
writer->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data2", "upon ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data2", "upon ", logger));
writer->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data3", "a ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data3", "a ", logger));
auto reader = handle->ObtainReader(nullptr);
logger->Add("1");
@@ -989,16 +989,16 @@ TEST(SharedMemoryDataConsumerHandleBackpressureTest, CloseAndReset) {
TEST(SharedMemoryDataConsumerHandleWithoutBackpressureTest, AddData) {
base::MessageLoop loop;
std::unique_ptr<Writer> writer;
- auto handle = base::MakeUnique<SharedMemoryDataConsumerHandle>(
+ auto handle = std::make_unique<SharedMemoryDataConsumerHandle>(
kDoNotApplyBackpressure, &writer);
scoped_refptr<Logger> logger(new Logger);
logger->Add("1");
writer->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data1", "Once ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data1", "Once ", logger));
logger->Add("2");
writer->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data2", "upon ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data2", "upon ", logger));
logger->Add("3");
EXPECT_EQ(
@@ -1012,7 +1012,7 @@ TEST(SharedMemoryDataConsumerHandleWithoutBackpressureTest, AddData) {
TEST_F(ThreadedSharedMemoryDataConsumerHandleTest, Read) {
base::RunLoop run_loop;
- auto operation = base::MakeUnique<ReadDataOperation>(
+ auto operation = std::make_unique<ReadDataOperation>(
std::move(handle_), &loop_, run_loop.QuitClosure());
scoped_refptr<Logger> logger(new Logger);
@@ -1025,15 +1025,15 @@ TEST_F(ThreadedSharedMemoryDataConsumerHandleTest, Read) {
logger->Add("1");
writer_->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data1", "Once ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data1", "Once ", logger));
writer_->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data2", "upon ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data2", "upon ", logger));
writer_->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data3", "a time ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data3", "a time ", logger));
writer_->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data4", "there ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data4", "there ", logger));
writer_->AddData(
- base::MakeUnique<LoggingFixedReceivedData>("data5", "was ", logger));
+ std::make_unique<LoggingFixedReceivedData>("data5", "was ", logger));
writer_->Close();
logger->Add("2");
diff --git a/chromium/content/child/shared_memory_received_data_factory.cc b/chromium/content/renderer/loader/shared_memory_received_data_factory.cc
index d66a471b270..b9530d50a42 100644
--- a/chromium/content/child/shared_memory_received_data_factory.cc
+++ b/chromium/content/renderer/loader/shared_memory_received_data_factory.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/child/shared_memory_received_data_factory.h"
+#include "content/renderer/loader/shared_memory_received_data_factory.h"
#include <algorithm>
@@ -64,7 +64,7 @@ SharedMemoryReceivedDataFactory::Create(int offset, int length) {
const char* payload = start + offset;
TicketId id = id_++;
- return base::MakeUnique<SharedMemoryReceivedData>(payload, length, this, id);
+ return std::make_unique<SharedMemoryReceivedData>(payload, length, this, id);
}
void SharedMemoryReceivedDataFactory::Stop() {
diff --git a/chromium/content/child/shared_memory_received_data_factory.h b/chromium/content/renderer/loader/shared_memory_received_data_factory.h
index e838391531b..72018cb718f 100644
--- a/chromium/content/child/shared_memory_received_data_factory.h
+++ b/chromium/content/renderer/loader/shared_memory_received_data_factory.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_CHILD_SHARED_MEMORY_RECEIVED_DATA_FACTORY_H_
-#define CONTENT_CHILD_SHARED_MEMORY_RECEIVED_DATA_FACTORY_H_
+#ifndef CONTENT_RENDERER_LOADER_SHARED_MEMORY_RECEIVED_DATA_FACTORY_H_
+#define CONTENT_RENDERER_LOADER_SHARED_MEMORY_RECEIVED_DATA_FACTORY_H_
#include <stddef.h>
#include <stdint.h>
@@ -16,7 +16,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
#include "content/common/content_export.h"
-#include "content/public/child/request_peer.h"
+#include "content/public/renderer/request_peer.h"
namespace IPC {
class Sender;
@@ -66,4 +66,4 @@ class CONTENT_EXPORT SharedMemoryReceivedDataFactory final
} // namespace content
-#endif // CONTENT_CHILD_SHARED_MEMORY_RECEIVED_DATA_FACTORY_H_
+#endif // CONTENT_RENDERER_LOADER_SHARED_MEMORY_RECEIVED_DATA_FACTORY_H_
diff --git a/chromium/content/child/shared_memory_received_data_factory_unittest.cc b/chromium/content/renderer/loader/shared_memory_received_data_factory_unittest.cc
index f0562b25aa7..8957d3ffd76 100644
--- a/chromium/content/child/shared_memory_received_data_factory_unittest.cc
+++ b/chromium/content/renderer/loader/shared_memory_received_data_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 "content/child/shared_memory_received_data_factory.h"
+#include "content/renderer/loader/shared_memory_received_data_factory.h"
#include <stddef.h>
#include <tuple>
diff --git a/chromium/content/child/site_isolation_stats_gatherer.cc b/chromium/content/renderer/loader/site_isolation_stats_gatherer.cc
index 9350a5b1d65..49fce4e0c37 100644
--- a/chromium/content/child/site_isolation_stats_gatherer.cc
+++ b/chromium/content/renderer/loader/site_isolation_stats_gatherer.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/child/site_isolation_stats_gatherer.h"
+#include "content/renderer/loader/site_isolation_stats_gatherer.h"
#include <stddef.h>
#include <stdint.h>
@@ -101,19 +101,10 @@ SiteIsolationStatsGatherer::OnReceivedResponse(
const url::Origin& frame_origin,
const GURL& response_url,
ResourceType resource_type,
- int origin_pid,
const ResourceResponseInfo& info) {
if (!g_stats_gathering_enabled)
return nullptr;
- // if |origin_pid| is non-zero, it means that this response is for a plugin
- // spawned from this renderer process. We exclude responses for plugins for
- // now, but eventually, we're going to make plugin processes directly talk to
- // the browser process so that we don't apply cross-site document blocking to
- // them.
- if (origin_pid)
- return nullptr;
-
UMA_HISTOGRAM_COUNTS("SiteIsolation.AllResponses", 1);
// See if this is for navigation. If it is, don't block it, under the
@@ -142,7 +133,7 @@ SiteIsolationStatsGatherer::OnReceivedResponse(
std::string access_control_origin;
// We can use a case-insensitive header name for EnumerateHeader().
- info.headers->EnumerateHeader(NULL, "access-control-allow-origin",
+ info.headers->EnumerateHeader(nullptr, "access-control-allow-origin",
&access_control_origin);
if (CrossSiteDocumentClassifier::IsValidCorsHeaderSet(
frame_origin, response_url, access_control_origin)) {
@@ -151,7 +142,7 @@ SiteIsolationStatsGatherer::OnReceivedResponse(
// Real XSD data collection starts from here.
std::string no_sniff;
- info.headers->EnumerateHeader(NULL, "x-content-type-options", &no_sniff);
+ info.headers->EnumerateHeader(nullptr, "x-content-type-options", &no_sniff);
std::unique_ptr<SiteIsolationResponseMetaData> resp_data(
new SiteIsolationResponseMetaData);
diff --git a/chromium/content/child/site_isolation_stats_gatherer.h b/chromium/content/renderer/loader/site_isolation_stats_gatherer.h
index dea0f5214a7..5ddf914e7ac 100644
--- a/chromium/content/child/site_isolation_stats_gatherer.h
+++ b/chromium/content/renderer/loader/site_isolation_stats_gatherer.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_CHILD_SITE_ISOLATION_STATS_GATHERER_H_
-#define CONTENT_CHILD_SITE_ISOLATION_STATS_GATHERER_H_
+#ifndef CONTENT_RENDERER_LOADER_SITE_ISOLATION_STATS_GATHERER_H_
+#define CONTENT_RENDERER_LOADER_SITE_ISOLATION_STATS_GATHERER_H_
#include <memory>
#include <string>
@@ -73,7 +73,6 @@ class CONTENT_EXPORT SiteIsolationStatsGatherer {
const url::Origin& frame_origin,
const GURL& response_url,
ResourceType resource_type,
- int origin_pid,
const ResourceResponseInfo& info);
// Examines the first chunk of network data in case response_url is registered
@@ -98,4 +97,4 @@ class CONTENT_EXPORT SiteIsolationStatsGatherer {
} // namespace content
-#endif // CONTENT_CHILD_SITE_ISOLATION_STATS_GATHERER_H_
+#endif // CONTENT_RENDERER_LOADER_SITE_ISOLATION_STATS_GATHERER_H_
diff --git a/chromium/content/child/site_isolation_stats_gatherer_browsertest.cc b/chromium/content/renderer/loader/site_isolation_stats_gatherer_browsertest.cc
index 5df256242ee..5df256242ee 100644
--- a/chromium/content/child/site_isolation_stats_gatherer_browsertest.cc
+++ b/chromium/content/renderer/loader/site_isolation_stats_gatherer_browsertest.cc
diff --git a/chromium/content/child/site_isolation_stats_gatherer_unittest.cc b/chromium/content/renderer/loader/site_isolation_stats_gatherer_unittest.cc
index 23feb4a5bb7..f34659c993c 100644
--- a/chromium/content/child/site_isolation_stats_gatherer_unittest.cc
+++ b/chromium/content/renderer/loader/site_isolation_stats_gatherer_unittest.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "base/strings/string_piece.h"
-#include "content/child/site_isolation_stats_gatherer.h"
+#include "content/renderer/loader/site_isolation_stats_gatherer.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::StringPiece;
diff --git a/chromium/content/child/sync_load_context.cc b/chromium/content/renderer/loader/sync_load_context.cc
index 3d0cf504ac4..b367bda46c6 100644
--- a/chromium/content/child/sync_load_context.cc
+++ b/chromium/content/renderer/loader/sync_load_context.cc
@@ -2,16 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/sync_load_context.h"
+#include "content/renderer/loader/sync_load_context.h"
#include <string>
#include "base/logging.h"
#include "base/synchronization/waitable_event.h"
-#include "content/child/sync_load_response.h"
#include "content/public/common/resource_request.h"
#include "content/public/common/resource_response_info.h"
#include "content/public/common/url_loader_throttle.h"
+#include "content/renderer/loader/sync_load_response.h"
#include "net/url_request/redirect_info.h"
namespace content {
@@ -46,7 +46,7 @@ SyncLoadContext::SyncLoadContext(
url_loader_factory_.Bind(std::move(url_loader_factory));
// Constructs a new ResourceDispatcher specifically for this request.
- resource_dispatcher_ = base::MakeUnique<ResourceDispatcher>(
+ resource_dispatcher_ = std::make_unique<ResourceDispatcher>(
nullptr, base::ThreadTaskRunnerHandle::Get());
// Initialize the final URL with the original request URL. It will be
@@ -98,15 +98,13 @@ void SyncLoadContext::OnReceivedData(std::unique_ptr<ReceivedData> data) {
void SyncLoadContext::OnTransferSizeUpdated(int transfer_size_diff) {}
-void SyncLoadContext::OnCompletedRequest(int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size) {
- response_->error_code = error_code;
- response_->encoded_data_length = total_transfer_size;
- response_->encoded_body_length = encoded_body_size;
+void SyncLoadContext::OnCompletedRequest(
+ const network::URLLoaderCompletionStatus& status) {
+ response_->error_code = status.error_code;
+ if (status.cors_error_status)
+ response_->cors_error = status.cors_error_status->cors_error;
+ response_->encoded_data_length = status.encoded_data_length;
+ response_->encoded_body_length = status.encoded_body_length;
event_->Signal();
// This will indirectly cause this object to be deleted.
diff --git a/chromium/content/child/sync_load_context.h b/chromium/content/renderer/loader/sync_load_context.h
index d3d8e15c17c..d02549e9818 100644
--- a/chromium/content/child/sync_load_context.h
+++ b/chromium/content/renderer/loader/sync_load_context.h
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_SYNC_LOAD_CONTEXT_H_
-#define CONTENT_CHILD_SYNC_LOAD_CONTEXT_H_
+#ifndef CONTENT_RENDERER_LOADER_SYNC_LOAD_CONTEXT_H_
+#define CONTENT_RENDERER_LOADER_SYNC_LOAD_CONTEXT_H_
#include "base/macros.h"
-#include "content/child/resource_dispatcher.h"
-#include "content/public/child/request_peer.h"
#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/public/renderer/request_peer.h"
+#include "content/renderer/loader/resource_dispatcher.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
namespace base {
@@ -56,12 +56,8 @@ class SyncLoadContext : public RequestPeer {
void OnDownloadedData(int len, int encoded_data_length) override;
void OnReceivedData(std::unique_ptr<ReceivedData> data) override;
void OnTransferSizeUpdated(int transfer_size_diff) override;
- void OnCompletedRequest(int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size) override;
+ void OnCompletedRequest(
+ const network::URLLoaderCompletionStatus& status) override;
// This raw pointer will remain valid for the lifetime of this object because
// it remains on the stack until |event_| is signaled.
@@ -81,4 +77,4 @@ class SyncLoadContext : public RequestPeer {
} // namespace content
-#endif // CONTENT_CHILD_SYNC_LOAD_CONTEXT_H_
+#endif // CONTENT_RENDERER_LOADER_SYNC_LOAD_CONTEXT_H_
diff --git a/chromium/content/child/sync_load_response.cc b/chromium/content/renderer/loader/sync_load_response.cc
index 163153aa237..a9e8ee12ded 100644
--- a/chromium/content/child/sync_load_response.cc
+++ b/chromium/content/renderer/loader/sync_load_response.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/child/sync_load_response.h"
+#include "content/renderer/loader/sync_load_response.h"
namespace content {
diff --git a/chromium/content/child/sync_load_response.h b/chromium/content/renderer/loader/sync_load_response.h
index 677f13fc584..160d9bba207 100644
--- a/chromium/content/child/sync_load_response.h
+++ b/chromium/content/renderer/loader/sync_load_response.h
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_SYNC_LOAD_RESPONSE_H_
-#define CONTENT_CHILD_SYNC_LOAD_RESPONSE_H_
+#ifndef CONTENT_RENDERER_CHILD_SYNC_LOAD_RESPONSE_H_
+#define CONTENT_RENDERER_CHILD_SYNC_LOAD_RESPONSE_H_
#include <string>
+#include "base/optional.h"
+#include "content/common/content_export.h"
#include "content/public/common/resource_response_info.h"
+#include "services/network/public/interfaces/cors.mojom.h"
#include "url/gurl.h"
namespace content {
@@ -19,7 +22,10 @@ struct CONTENT_EXPORT SyncLoadResponse : ResourceResponseInfo {
~SyncLoadResponse();
// The response error code.
- int error_code;
+ int error_code = 0;
+
+ // Optional CORS error details.
+ base::Optional<network::mojom::CORSError> cors_error;
// The final URL of the response. This may differ from the request URL in
// the case of a server redirect.
@@ -31,4 +37,4 @@ struct CONTENT_EXPORT SyncLoadResponse : ResourceResponseInfo {
} // namespace content
-#endif // CONTENT_CHILD_SYNC_LOAD_RESPONSE_H_
+#endif // CONTENT_RENDERER_CHILD_SYNC_LOAD_RESPONSE_H_
diff --git a/chromium/content/child/test_request_peer.cc b/chromium/content/renderer/loader/test_request_peer.cc
index 6ae64974c2b..70d16c1d602 100644
--- a/chromium/content/child/test_request_peer.cc
+++ b/chromium/content/renderer/loader/test_request_peer.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/test_request_peer.h"
+#include "content/renderer/loader/test_request_peer.h"
-#include "content/child/resource_dispatcher.h"
+#include "content/renderer/loader/resource_dispatcher.h"
#include "net/url_request/redirect_info.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -80,12 +80,8 @@ void TestRequestPeer::OnReceivedCachedMetadata(const char* data, int len) {
context_->cached_metadata = std::vector<char>(data, data + len);
}
-void TestRequestPeer::OnCompletedRequest(int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size) {
+void TestRequestPeer::OnCompletedRequest(
+ const network::URLLoaderCompletionStatus& status) {
if (context_->cancelled)
return;
EXPECT_TRUE(context_->received_response);
diff --git a/chromium/content/child/test_request_peer.h b/chromium/content/renderer/loader/test_request_peer.h
index f224d49e6ac..4ff4a521161 100644
--- a/chromium/content/child/test_request_peer.h
+++ b/chromium/content/renderer/loader/test_request_peer.h
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_TEST_REQUEST_PEER_H_
-#define CONTENT_CHILD_TEST_REQUEST_PEER_H_
+#ifndef CONTENT_RENDERER_LOADER_TEST_REQUEST_PEER_H_
+#define CONTENT_RENDERER_LOADER_TEST_REQUEST_PEER_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/time/time.h"
-#include "content/public/child/request_peer.h"
+#include "content/public/renderer/request_peer.h"
namespace net {
struct RedirectInfo;
@@ -38,12 +38,8 @@ class TestRequestPeer : public RequestPeer {
void OnReceivedData(std::unique_ptr<ReceivedData> data) override;
void OnTransferSizeUpdated(int transfer_size_diff) override;
void OnReceivedCachedMetadata(const char* data, int len) override;
- void OnCompletedRequest(int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size) override;
+ void OnCompletedRequest(
+ const network::URLLoaderCompletionStatus& status) override;
struct Context final {
Context();
@@ -87,4 +83,4 @@ class TestRequestPeer : public RequestPeer {
} // namespace content
-#endif // CONTENT_CHILD_TEST_REQUEST_PEER_H_
+#endif // CONTENT_RENDERER_LOADER_TEST_REQUEST_PEER_H_
diff --git a/chromium/content/child/url_loader_client_impl.cc b/chromium/content/renderer/loader/url_loader_client_impl.cc
index ffb360115cb..885b798e12b 100644
--- a/chromium/content/child/url_loader_client_impl.cc
+++ b/chromium/content/renderer/loader/url_loader_client_impl.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/url_loader_client_impl.h"
+#include "content/renderer/loader/url_loader_client_impl.h"
#include "base/callback.h"
#include "base/single_thread_task_runner.h"
-#include "content/child/resource_dispatcher.h"
-#include "content/child/url_response_body_consumer.h"
#include "content/common/resource_messages.h"
+#include "content/renderer/loader/resource_dispatcher.h"
+#include "content/renderer/loader/url_response_body_consumer.h"
#include "net/url_request/redirect_info.h"
namespace content {
@@ -174,7 +174,7 @@ void URLLoaderClientImpl::OnStartLoadingResponseBody(
}
void URLLoaderClientImpl::OnComplete(
- const ResourceRequestCompletionStatus& status) {
+ const network::URLLoaderCompletionStatus& status) {
if (!body_consumer_) {
if (NeedsStoringMessage()) {
StoreAndDispatch(ResourceMsg_RequestComplete(request_id_, status));
diff --git a/chromium/content/child/url_loader_client_impl.h b/chromium/content/renderer/loader/url_loader_client_impl.h
index 16af56c054d..e4743548413 100644
--- a/chromium/content/child/url_loader_client_impl.h
+++ b/chromium/content/renderer/loader/url_loader_client_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_URL_LOADER_CLIENT_IMPL_H_
-#define CONTENT_CHILD_URL_LOADER_CLIENT_IMPL_H_
+#ifndef CONTENT_RENDERER_LOADER_URL_LOADER_CLIENT_IMPL_H_
+#define CONTENT_RENDERER_LOADER_URL_LOADER_CLIENT_IMPL_H_
#include <stdint.h>
#include <vector>
@@ -23,10 +23,13 @@ namespace net {
struct RedirectInfo;
} // namespace net
+namespace network {
+struct URLLoaderCompletionStatus;
+} // namespace network
+
namespace content {
class ResourceDispatcher;
class URLResponseBodyConsumer;
-struct ResourceRequestCompletionStatus;
struct ResourceResponseHead;
class CONTENT_EXPORT URLLoaderClientImpl final : public mojom::URLLoaderClient {
@@ -60,7 +63,7 @@ class CONTENT_EXPORT URLLoaderClientImpl final : public mojom::URLLoaderClient {
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- void OnComplete(const ResourceRequestCompletionStatus& status) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
private:
bool NeedsStoringMessage() const;
@@ -80,4 +83,4 @@ class CONTENT_EXPORT URLLoaderClientImpl final : public mojom::URLLoaderClient {
} // namespace content
-#endif // CONTENT_CHILD_URL_LOADER_CLIENT_IMPL_H_
+#endif // CONTENT_RENDERER_LOADER_URL_LOADER_CLIENT_IMPL_H_
diff --git a/chromium/content/child/url_loader_client_impl_unittest.cc b/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
index 63f50b57d53..572a0cf1d58 100644
--- a/chromium/content/child/url_loader_client_impl_unittest.cc
+++ b/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/url_loader_client_impl.h"
+#include "content/renderer/loader/url_loader_client_impl.h"
#include <vector>
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
-#include "content/child/resource_dispatcher.h"
-#include "content/child/test_request_peer.h"
#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/renderer/loader/resource_dispatcher.h"
+#include "content/renderer/loader/test_request_peer.h"
#include "ipc/ipc_sender.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
@@ -30,9 +30,9 @@ class URLLoaderClientImplTest : public ::testing::Test,
mojo_binding_.Bind(mojo::MakeRequest(&url_loader_factory_proxy_));
request_id_ = dispatcher_->StartAsync(
- base::MakeUnique<ResourceRequest>(), 0, nullptr, url::Origin(),
+ std::make_unique<ResourceRequest>(), 0, nullptr, url::Origin(),
TRAFFIC_ANNOTATION_FOR_TESTS, false,
- base::MakeUnique<TestRequestPeer>(dispatcher_.get(),
+ std::make_unique<TestRequestPeer>(dispatcher_.get(),
&request_peer_context_),
blink::WebURLRequest::LoadingIPCType::kMojo,
url_loader_factory_proxy_.get(),
@@ -176,10 +176,10 @@ TEST_F(URLLoaderClientImplTest, OnTransferSizeUpdated) {
TEST_F(URLLoaderClientImplTest, OnCompleteWithoutResponseBody) {
ResourceResponseHead response_head;
- ResourceRequestCompletionStatus completion_status;
+ network::URLLoaderCompletionStatus status;
url_loader_client_->OnReceiveResponse(response_head, base::nullopt, nullptr);
- url_loader_client_->OnComplete(completion_status);
+ url_loader_client_->OnComplete(status);
EXPECT_FALSE(request_peer_context_.received_response);
EXPECT_FALSE(request_peer_context_.complete);
@@ -190,7 +190,7 @@ TEST_F(URLLoaderClientImplTest, OnCompleteWithoutResponseBody) {
TEST_F(URLLoaderClientImplTest, OnCompleteWithResponseBody) {
ResourceResponseHead response_head;
- ResourceRequestCompletionStatus completion_status;
+ network::URLLoaderCompletionStatus status;
url_loader_client_->OnReceiveResponse(response_head, base::nullopt, nullptr);
mojo::DataPipe data_pipe(DataPipeOptions());
@@ -209,7 +209,7 @@ TEST_F(URLLoaderClientImplTest, OnCompleteWithResponseBody) {
EXPECT_TRUE(request_peer_context_.received_response);
EXPECT_EQ("hello", request_peer_context_.data);
- url_loader_client_->OnComplete(completion_status);
+ url_loader_client_->OnComplete(status);
EXPECT_FALSE(request_peer_context_.complete);
base::RunLoop().RunUntilIdle();
@@ -224,13 +224,13 @@ TEST_F(URLLoaderClientImplTest, OnCompleteWithResponseBody) {
// restore the order.
TEST_F(URLLoaderClientImplTest, OnCompleteShouldBeTheLastMessage) {
ResourceResponseHead response_head;
- ResourceRequestCompletionStatus completion_status;
+ network::URLLoaderCompletionStatus status;
url_loader_client_->OnReceiveResponse(response_head, base::nullopt, nullptr);
mojo::DataPipe data_pipe(DataPipeOptions());
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
- url_loader_client_->OnComplete(completion_status);
+ url_loader_client_->OnComplete(status);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(request_peer_context_.received_response);
@@ -256,13 +256,13 @@ TEST_F(URLLoaderClientImplTest, CancelOnReceiveResponse) {
request_peer_context_.cancel_on_receive_response = true;
ResourceResponseHead response_head;
- ResourceRequestCompletionStatus completion_status;
+ network::URLLoaderCompletionStatus status;
url_loader_client_->OnReceiveResponse(response_head, base::nullopt, nullptr);
mojo::DataPipe data_pipe(DataPipeOptions());
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
- url_loader_client_->OnComplete(completion_status);
+ url_loader_client_->OnComplete(status);
EXPECT_FALSE(request_peer_context_.received_response);
EXPECT_FALSE(request_peer_context_.complete);
@@ -278,7 +278,7 @@ TEST_F(URLLoaderClientImplTest, CancelOnReceiveData) {
request_peer_context_.cancel_on_receive_data = true;
ResourceResponseHead response_head;
- ResourceRequestCompletionStatus completion_status;
+ network::URLLoaderCompletionStatus status;
mojo::DataPipe data_pipe(DataPipeOptions());
uint32_t size = 5;
@@ -290,7 +290,7 @@ TEST_F(URLLoaderClientImplTest, CancelOnReceiveData) {
url_loader_client_->OnReceiveResponse(response_head, base::nullopt, nullptr);
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
- url_loader_client_->OnComplete(completion_status);
+ url_loader_client_->OnComplete(status);
EXPECT_FALSE(request_peer_context_.received_response);
EXPECT_EQ("", request_peer_context_.data);
@@ -306,10 +306,10 @@ TEST_F(URLLoaderClientImplTest, CancelOnReceiveData) {
TEST_F(URLLoaderClientImplTest, Defer) {
ResourceResponseHead response_head;
- ResourceRequestCompletionStatus completion_status;
+ network::URLLoaderCompletionStatus status;
url_loader_client_->OnReceiveResponse(response_head, base::nullopt, nullptr);
- url_loader_client_->OnComplete(completion_status);
+ url_loader_client_->OnComplete(status);
EXPECT_FALSE(request_peer_context_.received_response);
EXPECT_FALSE(request_peer_context_.complete);
@@ -331,7 +331,7 @@ TEST_F(URLLoaderClientImplTest, Defer) {
TEST_F(URLLoaderClientImplTest, DeferWithResponseBody) {
ResourceResponseHead response_head;
- ResourceRequestCompletionStatus completion_status;
+ network::URLLoaderCompletionStatus status;
url_loader_client_->OnReceiveResponse(response_head, base::nullopt, nullptr);
mojo::DataPipe data_pipe(DataPipeOptions());
@@ -344,7 +344,7 @@ TEST_F(URLLoaderClientImplTest, DeferWithResponseBody) {
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
- url_loader_client_->OnComplete(completion_status);
+ url_loader_client_->OnComplete(status);
EXPECT_FALSE(request_peer_context_.received_response);
EXPECT_FALSE(request_peer_context_.complete);
@@ -372,7 +372,7 @@ TEST_F(URLLoaderClientImplTest, DeferWithResponseBody) {
// we have a separate test.
TEST_F(URLLoaderClientImplTest, DeferWithTransferSizeUpdated) {
ResourceResponseHead response_head;
- ResourceRequestCompletionStatus completion_status;
+ network::URLLoaderCompletionStatus status;
url_loader_client_->OnReceiveResponse(response_head, base::nullopt, nullptr);
mojo::DataPipe data_pipe(DataPipeOptions());
@@ -386,7 +386,7 @@ TEST_F(URLLoaderClientImplTest, DeferWithTransferSizeUpdated) {
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
url_loader_client_->OnTransferSizeUpdated(4);
- url_loader_client_->OnComplete(completion_status);
+ url_loader_client_->OnComplete(status);
EXPECT_FALSE(request_peer_context_.received_response);
EXPECT_FALSE(request_peer_context_.complete);
@@ -419,7 +419,7 @@ TEST_F(URLLoaderClientImplTest, SetDeferredDuringFlushingDeferredMessage) {
net::RedirectInfo redirect_info;
ResourceResponseHead response_head;
- ResourceRequestCompletionStatus completion_status;
+ network::URLLoaderCompletionStatus status;
url_loader_client_->OnReceiveRedirect(redirect_info, response_head);
url_loader_client_->OnReceiveResponse(response_head, base::nullopt, nullptr);
@@ -434,7 +434,7 @@ TEST_F(URLLoaderClientImplTest, SetDeferredDuringFlushingDeferredMessage) {
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
url_loader_client_->OnTransferSizeUpdated(4);
- url_loader_client_->OnComplete(completion_status);
+ url_loader_client_->OnComplete(status);
EXPECT_EQ(0, request_peer_context_.seen_redirects);
EXPECT_FALSE(request_peer_context_.received_response);
@@ -481,12 +481,12 @@ TEST_F(URLLoaderClientImplTest,
request_peer_context_.defer_on_transfer_size_updated = true;
ResourceResponseHead response_head;
- ResourceRequestCompletionStatus completion_status;
+ network::URLLoaderCompletionStatus status;
url_loader_client_->OnReceiveResponse(response_head, base::nullopt, nullptr);
url_loader_client_->OnTransferSizeUpdated(4);
- url_loader_client_->OnComplete(completion_status);
+ url_loader_client_->OnComplete(status);
EXPECT_FALSE(request_peer_context_.received_response);
EXPECT_FALSE(request_peer_context_.complete);
diff --git a/chromium/content/child/url_response_body_consumer.cc b/chromium/content/renderer/loader/url_response_body_consumer.cc
index 436db7614f8..0ffa014fd26 100644
--- a/chromium/content/child/url_response_body_consumer.cc
+++ b/chromium/content/renderer/loader/url_response_body_consumer.cc
@@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/url_response_body_consumer.h"
+#include "content/renderer/loader/url_response_body_consumer.h"
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "content/child/resource_dispatcher.h"
-#include "content/child/site_isolation_stats_gatherer.h"
#include "content/common/resource_messages.h"
-#include "content/public/child/request_peer.h"
-#include "content/public/common/resource_request_completion_status.h"
+#include "content/public/renderer/request_peer.h"
+#include "content/renderer/loader/resource_dispatcher.h"
+#include "content/renderer/loader/site_isolation_stats_gatherer.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
namespace content {
@@ -61,11 +61,11 @@ URLResponseBodyConsumer::URLResponseBodyConsumer(
URLResponseBodyConsumer::~URLResponseBodyConsumer() {}
void URLResponseBodyConsumer::OnComplete(
- const ResourceRequestCompletionStatus& status) {
+ const network::URLLoaderCompletionStatus& status) {
if (has_been_cancelled_)
return;
has_received_completion_ = true;
- completion_status_ = status;
+ status_ = status;
NotifyCompletionIfAppropriate();
}
@@ -127,7 +127,7 @@ void URLResponseBodyConsumer::OnReadable(MojoResult unused) {
return;
}
if (result != MOJO_RESULT_OK) {
- completion_status_.error_code = net::ERR_FAILED;
+ status_.error_code = net::ERR_FAILED;
has_seen_end_of_data_ = true;
has_received_completion_ = true;
NotifyCompletionIfAppropriate();
@@ -158,7 +158,7 @@ void URLResponseBodyConsumer::OnReadable(MojoResult unused) {
request_info->site_isolation_metadata.reset();
}
- request_info->peer->OnReceivedData(base::MakeUnique<ReceivedData>(
+ request_info->peer->OnReceivedData(std::make_unique<ReceivedData>(
static_cast<const char*>(buffer), available, this));
}
}
@@ -171,7 +171,7 @@ void URLResponseBodyConsumer::NotifyCompletionIfAppropriate() {
// Cancel this instance in order not to notify twice.
Cancel();
- resource_dispatcher_->OnRequestComplete(request_id_, completion_status_);
+ resource_dispatcher_->OnRequestComplete(request_id_, status_);
// |this| may be deleted.
}
diff --git a/chromium/content/child/url_response_body_consumer.h b/chromium/content/renderer/loader/url_response_body_consumer.h
index ecbbf0db957..d99d2577f13 100644
--- a/chromium/content/child/url_response_body_consumer.h
+++ b/chromium/content/renderer/loader/url_response_body_consumer.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_CHILD_URL_RESPONSE_BODY_CONSUMER_H_
-#define CONTENT_CHILD_URL_RESPONSE_BODY_CONSUMER_H_
+#ifndef CONTENT_RENDERER_LOADER_URL_RESPONSE_BODY_CONSUMER_H_
+#define CONTENT_RENDERER_LOADER_URL_RESPONSE_BODY_CONSUMER_H_
#include <stddef.h>
#include <stdint.h>
@@ -20,10 +20,13 @@
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/simple_watcher.h"
+namespace network {
+struct URLLoaderCompletionStatus;
+} // namespace network
+
namespace content {
class ResourceDispatcher;
-struct ResourceRequestCompletionStatus;
// This class pulls data from a data pipe and dispatches it to the
// ResourceDispatcher. This class is used only for mojo-enabled requests.
@@ -41,7 +44,7 @@ class CONTENT_EXPORT URLResponseBodyConsumer final
// ResourceDispatcher when the both following conditions hold:
// 1) This function has been called and the completion status is set, and
// 2) All data is read from the handle.
- void OnComplete(const ResourceRequestCompletionStatus& status);
+ void OnComplete(const network::URLLoaderCompletionStatus& status);
// Cancels watching the handle and dispatches an error to the
// ResourceDispatcher. This function does nothing if the reading is already
@@ -76,7 +79,7 @@ class CONTENT_EXPORT URLResponseBodyConsumer final
ResourceDispatcher* resource_dispatcher_;
mojo::ScopedDataPipeConsumerHandle handle_;
mojo::SimpleWatcher handle_watcher_;
- ResourceRequestCompletionStatus completion_status_;
+ network::URLLoaderCompletionStatus status_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
bool has_received_completion_ = false;
@@ -90,4 +93,4 @@ class CONTENT_EXPORT URLResponseBodyConsumer final
} // namespace content
-#endif // CONTENT_CHILD_URL_RESPONSE_BODY_CONSUMER_H_
+#endif // CONTENT_RENDERER_LOADER_URL_RESPONSE_BODY_CONSUMER_H_
diff --git a/chromium/content/child/url_response_body_consumer_unittest.cc b/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc
index 824e442f7ee..3b26571fa0e 100644
--- a/chromium/content/child/url_response_body_consumer_unittest.cc
+++ b/chromium/content/renderer/loader/url_response_body_consumer_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 "content/child/url_response_body_consumer.h"
+#include "content/renderer/loader/url_response_body_consumer.h"
#include "base/bind.h"
#include "base/callback_forward.h"
@@ -11,16 +11,16 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/resource_dispatcher.h"
#include "content/common/resource_messages.h"
-#include "content/public/child/request_peer.h"
#include "content/public/common/request_context_frame_type.h"
#include "content/public/common/resource_request.h"
-#include "content/public/common/resource_request_completion_status.h"
#include "content/public/common/service_worker_modes.h"
+#include "content/public/renderer/request_peer.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/loader/resource_dispatcher.h"
#include "net/base/request_priority.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -64,15 +64,11 @@ class TestRequestPeer : public RequestPeer {
void OnTransferSizeUpdated(int transfer_size_diff) override {}
- void OnCompletedRequest(int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size) override {
+ void OnCompletedRequest(
+ const network::URLLoaderCompletionStatus& status) override {
EXPECT_FALSE(context_->complete);
context_->complete = true;
- context_->error_code = error_code;
+ context_->error_code = status.error_code;
context_->run_loop_quit_closure.Run();
}
@@ -116,7 +112,7 @@ class URLResponseBodyConsumerTest : public ::testing::Test,
request->url = GURL("http://www.example.com/");
request->priority = net::LOW;
request->appcache_host_id = 0;
- request->fetch_request_mode = FETCH_REQUEST_MODE_NO_CORS;
+ request->fetch_request_mode = network::mojom::FetchRequestMode::kNoCORS;
request->fetch_frame_type = REQUEST_CONTEXT_FRAME_TYPE_NONE;
const RequestExtraData extra_data;
@@ -140,7 +136,7 @@ class URLResponseBodyConsumerTest : public ::testing::Test,
return dispatcher_->StartAsync(
std::move(request), 0, nullptr, url::Origin(),
TRAFFIC_ANNOTATION_FOR_TESTS, false,
- base::MakeUnique<TestRequestPeer>(context, message_loop_.task_runner()),
+ std::make_unique<TestRequestPeer>(context, message_loop_.task_runner()),
blink::WebURLRequest::LoadingIPCType::kChromeIPC, nullptr,
std::vector<std::unique_ptr<URLLoaderThrottle>>(),
mojo::ScopedDataPipeConsumerHandle());
@@ -193,7 +189,7 @@ TEST_F(URLResponseBodyConsumerTest, OnCompleteThenClose) {
message_loop_.task_runner()));
consumer->ArmOrNotify();
- consumer->OnComplete(ResourceRequestCompletionStatus());
+ consumer->OnComplete(network::URLLoaderCompletionStatus());
mojo::ScopedDataPipeProducerHandle writer =
std::move(data_pipe.producer_handle);
std::string buffer = "hello";
@@ -228,7 +224,7 @@ TEST_F(URLResponseBodyConsumerTest, OnCompleteThenCloseWithAsyncRelease) {
message_loop_.task_runner()));
consumer->ArmOrNotify();
- consumer->OnComplete(ResourceRequestCompletionStatus());
+ consumer->OnComplete(network::URLLoaderCompletionStatus());
mojo::ScopedDataPipeProducerHandle writer =
std::move(data_pipe.producer_handle);
std::string buffer = "hello";
@@ -260,7 +256,7 @@ TEST_F(URLResponseBodyConsumerTest, CloseThenOnComplete) {
message_loop_.task_runner()));
consumer->ArmOrNotify();
- ResourceRequestCompletionStatus status;
+ network::URLLoaderCompletionStatus status;
status.error_code = net::ERR_FAILED;
data_pipe.producer_handle.reset();
consumer->OnComplete(status);
diff --git a/chromium/content/child/web_data_consumer_handle_impl.cc b/chromium/content/renderer/loader/web_data_consumer_handle_impl.cc
index 21a021bede1..bc8386ed388 100644
--- a/chromium/content/child/web_data_consumer_handle_impl.cc
+++ b/chromium/content/renderer/loader/web_data_consumer_handle_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/web_data_consumer_handle_impl.h"
+#include "content/renderer/loader/web_data_consumer_handle_impl.h"
#include <stdint.h>
diff --git a/chromium/content/child/web_data_consumer_handle_impl.h b/chromium/content/renderer/loader/web_data_consumer_handle_impl.h
index e40ff796b9f..5a9a018dad4 100644
--- a/chromium/content/child/web_data_consumer_handle_impl.h
+++ b/chromium/content/renderer/loader/web_data_consumer_handle_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_WEB_DATA_CONSUMER_HANDLE_IMPL_H_
-#define CONTENT_CHILD_WEB_DATA_CONSUMER_HANDLE_IMPL_H_
+#ifndef CONTENT_RENDERER_LOADER_WEB_DATA_CONSUMER_HANDLE_IMPL_H_
+#define CONTENT_RENDERER_LOADER_WEB_DATA_CONSUMER_HANDLE_IMPL_H_
#include <stddef.h>
@@ -61,4 +61,4 @@ class CONTENT_EXPORT WebDataConsumerHandleImpl final
} // namespace content
-#endif // CONTENT_CHILD_WEB_DATA_CONSUMER_HANDLE_IMPL_H_
+#endif // CONTENT_RENDERER_LOADER_WEB_DATA_CONSUMER_HANDLE_IMPL_H_
diff --git a/chromium/content/child/web_data_consumer_handle_impl_unittest.cc b/chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc
index 5451317a206..5faab10d170 100644
--- a/chromium/content/child/web_data_consumer_handle_impl_unittest.cc
+++ b/chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/web_data_consumer_handle_impl.h"
+#include "content/renderer/loader/web_data_consumer_handle_impl.h"
#include <stddef.h>
#include <stdint.h>
@@ -240,7 +240,7 @@ class WebDataConsumerHandleImplTest : public ::testing::Test {
TEST_F(WebDataConsumerHandleImplTest, ReadData) {
base::RunLoop run_loop;
- auto operation = base::MakeUnique<ReadDataOperation>(
+ auto operation = std::make_unique<ReadDataOperation>(
std::move(consumer_), &message_loop_, run_loop.QuitClosure());
base::Thread t("DataConsumerHandle test thread");
@@ -261,7 +261,7 @@ TEST_F(WebDataConsumerHandleImplTest, ReadData) {
TEST_F(WebDataConsumerHandleImplTest, TwoPhaseReadData) {
base::RunLoop run_loop;
- auto operation = base::MakeUnique<TwoPhaseReadDataOperation>(
+ auto operation = std::make_unique<TwoPhaseReadDataOperation>(
std::move(consumer_), &message_loop_, run_loop.QuitClosure());
base::Thread t("DataConsumerHandle test thread");
@@ -325,7 +325,7 @@ TEST_F(WebDataConsumerHandleImplTest, DidGetReadable) {
static constexpr size_t kTotalSize = kBlockSize * 3;
std::unique_ptr<CountDidGetReadableClient> client =
- base::MakeUnique<CountDidGetReadableClient>();
+ std::make_unique<CountDidGetReadableClient>();
std::unique_ptr<WebDataConsumerHandleImpl> handle(
new WebDataConsumerHandleImpl(std::move(consumer_)));
std::unique_ptr<WebDataConsumerHandle::Reader> reader(
diff --git a/chromium/content/child/web_url_loader_impl.cc b/chromium/content/renderer/loader/web_url_loader_impl.cc
index a238026334b..4d6f3aa8f2c 100644
--- a/chromium/content/child/web_url_loader_impl.cc
+++ b/chromium/content/renderer/loader/web_url_loader_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/web_url_loader_impl.h"
+#include "content/renderer/loader/web_url_loader_impl.h"
#include <stdint.h>
@@ -25,18 +25,9 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/child/child_thread_impl.h"
-#include "content/child/ftp_directory_listing_response_delegate.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/resource_dispatcher.h"
#include "content/child/scoped_child_process_reference.h"
-#include "content/child/shared_memory_data_consumer_handle.h"
-#include "content/child/sync_load_response.h"
-#include "content/child/web_url_request_util.h"
-#include "content/child/weburlresponse_extradata_impl.h"
#include "content/common/resource_messages.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/child/fixed_received_data.h"
-#include "content/public/child/request_peer.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_features.h"
#include "content/public/common/referrer.h"
@@ -44,6 +35,16 @@
#include "content/public/common/resource_request_body.h"
#include "content/public/common/service_worker_modes.h"
#include "content/public/common/url_loader.mojom.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
+#include "content/public/renderer/fixed_received_data.h"
+#include "content/public/renderer/request_peer.h"
+#include "content/renderer/loader/ftp_directory_listing_response_delegate.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/loader/resource_dispatcher.h"
+#include "content/renderer/loader/shared_memory_data_consumer_handle.h"
+#include "content/renderer/loader/sync_load_response.h"
+#include "content/renderer/loader/web_url_request_util.h"
+#include "content/renderer/loader/weburlresponse_extradata_impl.h"
#include "net/base/data_url.h"
#include "net/base/filename_util.h"
#include "net/base/net_errors.h"
@@ -166,22 +167,22 @@ void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing,
net::RequestPriority ConvertWebKitPriorityToNetPriority(
const WebURLRequest::Priority& priority) {
switch (priority) {
- case WebURLRequest::kPriorityVeryHigh:
+ case WebURLRequest::Priority::kVeryHigh:
return net::HIGHEST;
- case WebURLRequest::kPriorityHigh:
+ case WebURLRequest::Priority::kHigh:
return net::MEDIUM;
- case WebURLRequest::kPriorityMedium:
+ case WebURLRequest::Priority::kMedium:
return net::LOW;
- case WebURLRequest::kPriorityLow:
+ case WebURLRequest::Priority::kLow:
return net::LOWEST;
- case WebURLRequest::kPriorityVeryLow:
+ case WebURLRequest::Priority::kVeryLow:
return net::IDLE;
- case WebURLRequest::kPriorityUnresolved:
+ case WebURLRequest::Priority::kUnresolved:
default:
NOTREACHED();
return net::LOW;
@@ -344,6 +345,40 @@ StreamOverrideParameters::~StreamOverrideParameters() {
std::move(on_delete).Run(stream_url);
}
+WebURLLoaderFactoryImpl::WebURLLoaderFactoryImpl(
+ base::WeakPtr<ResourceDispatcher> resource_dispatcher,
+ scoped_refptr<ChildURLLoaderFactoryGetter> loader_factory_getter)
+ : resource_dispatcher_(std::move(resource_dispatcher)),
+ loader_factory_getter_(std::move(loader_factory_getter)) {}
+
+WebURLLoaderFactoryImpl::~WebURLLoaderFactoryImpl() = default;
+
+std::unique_ptr<WebURLLoaderFactoryImpl>
+WebURLLoaderFactoryImpl::CreateTestOnlyFactory() {
+ return std::make_unique<WebURLLoaderFactoryImpl>(nullptr, nullptr);
+}
+
+std::unique_ptr<blink::WebURLLoader> WebURLLoaderFactoryImpl::CreateURLLoader(
+ const blink::WebURLRequest& request,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ if (!loader_factory_getter_) {
+ // In some tests like RenderViewTests loader_factory_getter_ is not
+ // available. These tests can still use data URLs to bypass the
+ // ResourceDispatcher.
+ if (!task_runner)
+ task_runner = base::ThreadTaskRunnerHandle::Get();
+ return std::make_unique<WebURLLoaderImpl>(resource_dispatcher_.get(),
+ std::move(task_runner),
+ nullptr /* factory */);
+ }
+
+ DCHECK(task_runner);
+ DCHECK(resource_dispatcher_);
+ return std::make_unique<WebURLLoaderImpl>(
+ resource_dispatcher_.get(), std::move(task_runner),
+ loader_factory_getter_->GetFactoryForURL(request.Url()));
+}
+
// This inner class exists since the WebURLLoader may be deleted while inside a
// call to WebURLLoaderClient. Refcounting is to keep the context from being
// deleted if it may have work to do after calling into the client.
@@ -375,12 +410,7 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context> {
void OnReceivedData(std::unique_ptr<ReceivedData> data);
void OnTransferSizeUpdated(int transfer_size_diff);
void OnReceivedCachedMetadata(const char* data, int len);
- void OnCompletedRequest(int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size);
+ void OnCompletedRequest(const network::URLLoaderCompletionStatus& status);
private:
friend class base::RefCounted<Context>;
@@ -438,12 +468,8 @@ class WebURLLoaderImpl::RequestPeerImpl : public RequestPeer {
void OnReceivedData(std::unique_ptr<ReceivedData> data) override;
void OnTransferSizeUpdated(int transfer_size_diff) override;
void OnReceivedCachedMetadata(const char* data, int len) override;
- void OnCompletedRequest(int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size) override;
+ void OnCompletedRequest(
+ const network::URLLoaderCompletionStatus& status) override;
private:
scoped_refptr<Context> context_;
@@ -461,12 +487,12 @@ WebURLLoaderImpl::Context::Context(
: loader_(loader),
use_stream_on_response_(false),
report_raw_headers_(false),
- client_(NULL),
+ client_(nullptr),
resource_dispatcher_(resource_dispatcher),
task_runner_(std::move(task_runner)),
keep_alive_handle_(
keep_alive_handle_ptr
- ? base::MakeUnique<KeepAliveHandleWithChildProcessReference>(
+ ? std::make_unique<KeepAliveHandleWithChildProcessReference>(
std::move(keep_alive_handle_ptr))
: nullptr),
defers_loading_(NOT_DEFERRING),
@@ -497,8 +523,8 @@ void WebURLLoaderImpl::Context::Cancel() {
ftp_listing_delegate_->Cancel();
// Do not make any further calls to the client.
- client_ = NULL;
- loader_ = NULL;
+ client_ = nullptr;
+ loader_ = nullptr;
}
void WebURLLoaderImpl::Context::SetDefersLoading(bool value) {
@@ -586,21 +612,21 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
resource_request->headers = GetWebURLRequestHeaders(request);
resource_request->load_flags = GetLoadFlagsForWebURLRequest(request);
- // origin_pid only needs to be non-zero if the request originates outside
- // the render process, so we can use requestorProcessID even for requests
- // from in-process plugins.
- resource_request->origin_pid = request.RequestorProcessID();
+ // |plugin_child_id| only needs to be non-zero if the request originates
+ // outside the render process, so we can use requestorProcessID even
+ // for requests from in-process plugins.
+ resource_request->plugin_child_id = request.GetPluginChildID();
resource_request->resource_type = WebURLRequestToResourceType(request);
resource_request->priority =
ConvertWebKitPriorityToNetPriority(request.GetPriority());
resource_request->appcache_host_id = request.AppCacheHostID();
resource_request->should_reset_appcache = request.ShouldResetAppCache();
+ resource_request->is_external_request = request.IsExternalRequest();
+ resource_request->cors_preflight_policy = request.GetCORSPreflightPolicy();
resource_request->service_worker_mode =
GetServiceWorkerModeForWebURLRequest(request);
- resource_request->fetch_request_mode =
- GetFetchRequestModeForWebURLRequest(request);
- resource_request->fetch_credentials_mode =
- GetFetchCredentialsModeForWebURLRequest(request);
+ resource_request->fetch_request_mode = request.GetFetchRequestMode();
+ resource_request->fetch_credentials_mode = request.GetFetchCredentialsMode();
resource_request->fetch_redirect_mode =
GetFetchRedirectModeForWebURLRequest(request);
resource_request->fetch_integrity =
@@ -669,7 +695,7 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
std::move(resource_request), request.RequestorID(), task_runner_,
extra_data->frame_origin(), GetTrafficAnnotationTag(request),
false /* is_sync */,
- base::MakeUnique<WebURLLoaderImpl::RequestPeerImpl>(this),
+ std::make_unique<WebURLLoaderImpl::RequestPeerImpl>(this),
request.GetLoadingIPCType(), url_loader_factory_,
extra_data->TakeURLLoaderThrottles(), std::move(consumer_handle));
@@ -721,11 +747,6 @@ void WebURLLoaderImpl::Context::OnReceivedResponse(
// received on the browser side, and has been passed down to the renderer.
if (stream_override_) {
CHECK(IsBrowserSideNavigationEnabled());
- // Compute the delta between the response sizes so that the accurate
- // transfer size can be reported at the end of the request.
- stream_override_->total_transfer_size_delta =
- stream_override_->response.encoded_data_length -
- initial_info.encoded_data_length;
info = stream_override_->response;
// Replay the redirects that happened during navigation.
@@ -755,7 +776,7 @@ void WebURLLoaderImpl::Context::OnReceivedResponse(
}
if (info.headers.get() && info.mime_type == "multipart/x-mixed-replace") {
std::string content_type;
- info.headers->EnumerateHeader(NULL, "content-type", &content_type);
+ info.headers->EnumerateHeader(nullptr, "content-type", &content_type);
std::string mime_type;
std::string charset;
@@ -775,7 +796,7 @@ void WebURLLoaderImpl::Context::OnReceivedResponse(
mode = SharedMemoryDataConsumerHandle::kApplyBackpressure;
}
- auto read_handle = base::MakeUnique<SharedMemoryDataConsumerHandle>(
+ auto read_handle = std::make_unique<SharedMemoryDataConsumerHandle>(
mode, base::Bind(&Context::CancelBodyStreaming, this),
&body_stream_writer_);
@@ -799,7 +820,7 @@ void WebURLLoaderImpl::Context::OnReceivedResponse(
DCHECK(!ftp_listing_delegate_);
if (info.mime_type == "text/vnd.chromium.ftp-dir" && !show_raw_listing) {
ftp_listing_delegate_ =
- base::MakeUnique<FtpDirectoryListingResponseDelegate>(client_, loader_,
+ std::make_unique<FtpDirectoryListingResponseDelegate>(client_, loader_,
response);
}
}
@@ -861,12 +882,10 @@ void WebURLLoaderImpl::Context::OnReceivedCachedMetadata(
}
void WebURLLoaderImpl::Context::OnCompletedRequest(
- int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size) {
+ const network::URLLoaderCompletionStatus& status) {
+ int64_t total_transfer_size = status.encoded_data_length;
+ int64_t encoded_body_size = status.encoded_body_length;
+
if (stream_override_ && stream_override_->stream_url.is_empty()) {
// TODO(kinuko|scottmg|jam): This is wrong. https://crbug.com/705744.
total_transfer_size = stream_override_->total_transferred;
@@ -875,10 +894,10 @@ void WebURLLoaderImpl::Context::OnCompletedRequest(
if (ftp_listing_delegate_) {
ftp_listing_delegate_->OnCompletedRequest();
- ftp_listing_delegate_.reset(NULL);
+ ftp_listing_delegate_.reset(nullptr);
}
- if (body_stream_writer_ && error_code != net::OK)
+ if (body_stream_writer_ && status.error_code != net::OK)
body_stream_writer_->Fail();
body_stream_writer_.reset();
@@ -887,20 +906,20 @@ void WebURLLoaderImpl::Context::OnCompletedRequest(
"loading", "WebURLLoaderImpl::Context::OnCompletedRequest",
this, TRACE_EVENT_FLAG_FLOW_IN);
- if (error_code != net::OK) {
- WebURLError error(url_, stale_copy_in_cache, error_code);
- client_->DidFail(error, total_transfer_size, encoded_body_size,
- decoded_body_size);
+ if (status.error_code != net::OK) {
+ const WebURLError::HasCopyInCache has_copy_in_cache =
+ status.exists_in_cache ? WebURLError::HasCopyInCache::kTrue
+ : WebURLError::HasCopyInCache::kFalse;
+ client_->DidFail(
+ status.cors_error_status
+ ? WebURLError(*status.cors_error_status, has_copy_in_cache, url_)
+ : WebURLError(status.error_code, has_copy_in_cache,
+ WebURLError::IsWebSecurityViolation::kFalse, url_),
+ total_transfer_size, encoded_body_size, status.decoded_body_length);
} else {
- // PlzNavigate: compute the accurate transfer size for navigations.
- if (stream_override_) {
- DCHECK(IsBrowserSideNavigationEnabled());
- total_transfer_size += stream_override_->total_transfer_size_delta;
- }
-
- client_->DidFinishLoading((completion_time - TimeTicks()).InSecondsF(),
- total_transfer_size, encoded_body_size,
- decoded_body_size);
+ client_->DidFinishLoading(
+ (status.completion_time - TimeTicks()).InSecondsF(),
+ total_transfer_size, encoded_body_size, status.decoded_body_length);
}
}
}
@@ -916,7 +935,7 @@ void WebURLLoaderImpl::Context::CancelBodyStreaming() {
// Notify renderer clients that the request is canceled.
if (ftp_listing_delegate_) {
ftp_listing_delegate_->OnCompletedRequest();
- ftp_listing_delegate_.reset(NULL);
+ ftp_listing_delegate_.reset(nullptr);
}
if (body_stream_writer_) {
@@ -925,7 +944,7 @@ void WebURLLoaderImpl::Context::CancelBodyStreaming() {
}
if (client_) {
// TODO(yhirano): Set |stale_copy_in_cache| appropriately if possible.
- client_->DidFail(WebURLError(url_, false, net::ERR_ABORTED),
+ client_->DidFail(WebURLError(net::ERR_ABORTED, url_),
WebURLLoaderClient::kUnknownEncodedDataLength, 0, 0);
}
@@ -972,7 +991,8 @@ bool WebURLLoaderImpl::Context::CanHandleDataURLRequestLocally(
return true;
std::string mime_type, unused_charset;
- if (net::DataURL::Parse(request.Url(), &mime_type, &unused_charset, NULL) &&
+ if (net::DataURL::Parse(request.Url(), &mime_type, &unused_charset,
+ nullptr) &&
blink::IsSupportedMimeType(mime_type))
return true;
@@ -995,121 +1015,13 @@ void WebURLLoaderImpl::Context::HandleDataURL() {
OnReceivedResponse(info);
auto size = data.size();
if (size != 0)
- OnReceivedData(base::MakeUnique<FixedReceivedData>(data.data(), size));
- }
-
- OnCompletedRequest(error_code, false, base::TimeTicks::Now(), 0, data.size(),
- data.size());
-}
-
-// static
-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:
- return net::DefineNetworkTrafficAnnotation("blink_resource_loader", R"(
- semantics {
- sender: "Blink Resource Loader"
- description:
- "Blink-initiated request, which includes all resources for "
- "normal page loads, chrome URLs, and downloads."
- trigger:
- "The user navigates to a URL or downloads a file. Also when a "
- "webpage, ServiceWorker, or chrome:// uses any network communication."
- data: "Anything the initiator wants to send."
- destination: OTHER
- }
- policy {
- cookies_allowed: YES
- cookies_store: "user"
- setting: "These requests cannot be disabled in settings."
- policy_exception_justification:
- "Not implemented. Without these requests, Chrome will be unable "
- "to load any webpage."
- })");
-
- case WebURLRequest::kRequestContextEmbed:
- case WebURLRequest::kRequestContextObject:
- case WebURLRequest::kRequestContextPlugin:
- return net::DefineNetworkTrafficAnnotation(
- "blink_extension_resource_loader", R"(
- semantics {
- sender: "Blink Resource Loader"
- description:
- "Blink-initiated request for resources required for NaCl instances "
- "tagged with <embed> or <object>, or installed extensions."
- trigger:
- "An extension or NaCl instance may initiate a request at any time, "
- "even in the background."
- data: "Anything the initiator wants to send."
- destination: OTHER
- }
- policy {
- cookies_allowed: YES
- cookies_store: "user"
- setting:
- "These requests cannot be disabled in settings, but they are "
- "sent only if user installs extensions."
- chrome_policy {
- ExtensionInstallBlacklist {
- ExtensionInstallBlacklist: {
- entries: '*'
- }
- }
- }
- })");
-
- case WebURLRequest::kRequestContextFavicon:
- return net::DefineNetworkTrafficAnnotation("favicon_loader", R"(
- semantics {
- sender: "Blink Resource Loader"
- description:
- "Chrome sends a request to download favicon for a URL."
- trigger:
- "Navigating to a URL."
- data: "None."
- destination: WEBSITE
- }
- policy {
- cookies_allowed: YES
- cookies_store: "user"
- setting: "These requests cannot be disabled in settings."
- policy_exception_justification:
- "Not implemented."
- })");
+ OnReceivedData(std::make_unique<FixedReceivedData>(data.data(), size));
}
- return net::NetworkTrafficAnnotationTag::NotReached();
+ network::URLLoaderCompletionStatus status(error_code);
+ status.encoded_body_length = data.size();
+ status.decoded_body_length = data.size();
+ OnCompletedRequest(status);
}
// WebURLLoaderImpl::RequestPeerImpl ------------------------------------------
@@ -1156,15 +1068,8 @@ void WebURLLoaderImpl::RequestPeerImpl::OnReceivedCachedMetadata(
}
void WebURLLoaderImpl::RequestPeerImpl::OnCompletedRequest(
- int error_code,
- bool stale_copy_in_cache,
- const base::TimeTicks& completion_time,
- int64_t total_transfer_size,
- int64_t encoded_body_size,
- int64_t decoded_body_size) {
- context_->OnCompletedRequest(error_code, stale_copy_in_cache, completion_time,
- total_transfer_size, encoded_body_size,
- decoded_body_size);
+ const network::URLLoaderCompletionStatus& status) {
+ context_->OnCompletedRequest(status);
}
// WebURLLoaderImpl -----------------------------------------------------------
@@ -1219,7 +1124,6 @@ void WebURLLoaderImpl::PopulateURLResponse(const WebURL& url,
blink::FilePathToWebString(info.download_file_path));
response->SetWasFetchedViaSPDY(info.was_fetched_via_spdy);
response->SetWasFetchedViaServiceWorker(info.was_fetched_via_service_worker);
- response->SetWasFetchedViaForeignFetch(info.was_fetched_via_foreign_fetch);
response->SetWasFallbackRequiredByServiceWorker(
info.was_fallback_required_by_service_worker);
response->SetResponseTypeViaServiceWorker(
@@ -1326,7 +1230,7 @@ void WebURLLoaderImpl::PopulateURLResponse(const WebURL& url,
void WebURLLoaderImpl::LoadSynchronously(const WebURLRequest& request,
WebURLResponse& response,
- WebURLError& error,
+ base::Optional<WebURLError>& error,
WebData& data,
int64_t& encoded_data_length,
int64_t& encoded_body_length) {
@@ -1338,13 +1242,22 @@ void WebURLLoaderImpl::LoadSynchronously(const WebURLRequest& request,
// TODO(tc): For file loads, we may want to include a more descriptive
// status code or status text.
- int error_code = sync_load_response.error_code;
+ const int error_code = sync_load_response.error_code;
if (error_code != net::OK) {
- error = WebURLError(final_url, false, error_code);
- if (error_code == net::ERR_ABORTED) {
+ if (sync_load_response.cors_error) {
+ // TODO(toyoshim): Pass CORS error related headers here.
+ error =
+ WebURLError(network::CORSErrorStatus(*sync_load_response.cors_error),
+ WebURLError::HasCopyInCache::kFalse, final_url);
+ } else {
// SyncResourceHandler returns ERR_ABORTED for CORS redirect errors,
// so we treat the error as a web security violation.
- error.is_web_security_violation = true;
+ const WebURLError::IsWebSecurityViolation is_web_security_violation =
+ error_code == net::ERR_ABORTED
+ ? WebURLError::IsWebSecurityViolation::kTrue
+ : WebURLError::IsWebSecurityViolation::kFalse;
+ error = WebURLError(error_code, WebURLError::HasCopyInCache::kFalse,
+ is_web_security_violation, final_url);
}
return;
}
@@ -1364,7 +1277,7 @@ void WebURLLoaderImpl::LoadAsynchronously(const WebURLRequest& request,
DCHECK(!context_->client());
context_->set_client(client);
- context_->Start(request, NULL);
+ context_->Start(request, nullptr);
}
void WebURLLoaderImpl::Cancel() {
@@ -1380,4 +1293,116 @@ void WebURLLoaderImpl::DidChangePriority(WebURLRequest::Priority new_priority,
context_->DidChangePriority(new_priority, intra_priority_value);
}
+// static
+// We have this function at the bottom of this file because it confuses
+// syntax highliting.
+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:
+ return net::DefineNetworkTrafficAnnotation("blink_resource_loader", R"(
+ semantics {
+ sender: "Blink Resource Loader"
+ description:
+ "Blink-initiated request, which includes all resources for "
+ "normal page loads, chrome URLs, and downloads."
+ trigger:
+ "The user navigates to a URL or downloads a file. Also when a "
+ "webpage, ServiceWorker, or chrome:// uses any network communication."
+ data: "Anything the initiator wants to send."
+ destination: OTHER
+ }
+ policy {
+ cookies_allowed: YES
+ cookies_store: "user"
+ setting: "These requests cannot be disabled in settings."
+ policy_exception_justification:
+ "Not implemented. Without these requests, Chrome will be unable "
+ "to load any webpage."
+ })");
+
+ case WebURLRequest::kRequestContextEmbed:
+ case WebURLRequest::kRequestContextObject:
+ case WebURLRequest::kRequestContextPlugin:
+ return net::DefineNetworkTrafficAnnotation(
+ "blink_extension_resource_loader", R"(
+ semantics {
+ sender: "Blink Resource Loader"
+ description:
+ "Blink-initiated request for resources required for NaCl instances "
+ "tagged with <embed> or <object>, or installed extensions."
+ trigger:
+ "An extension or NaCl instance may initiate a request at any time, "
+ "even in the background."
+ data: "Anything the initiator wants to send."
+ destination: OTHER
+ }
+ policy {
+ cookies_allowed: YES
+ cookies_store: "user"
+ setting:
+ "These requests cannot be disabled in settings, but they are "
+ "sent only if user installs extensions."
+ chrome_policy {
+ ExtensionInstallBlacklist {
+ ExtensionInstallBlacklist: {
+ entries: '*'
+ }
+ }
+ }
+ })");
+
+ case WebURLRequest::kRequestContextFavicon:
+ return net::DefineNetworkTrafficAnnotation("favicon_loader", R"(
+ semantics {
+ sender: "Blink Resource Loader"
+ description:
+ "Chrome sends a request to download favicon for a URL."
+ trigger:
+ "Navigating to a URL."
+ data: "None."
+ destination: WEBSITE
+ }
+ policy {
+ cookies_allowed: YES
+ cookies_store: "user"
+ setting: "These requests cannot be disabled in settings."
+ policy_exception_justification:
+ "Not implemented."
+ })");
+ }
+
+ return net::NetworkTrafficAnnotationTag::NotReached();
+}
+
} // namespace content
diff --git a/chromium/content/child/web_url_loader_impl.h b/chromium/content/renderer/loader/web_url_loader_impl.h
index 35c5d713f7a..2d19fe09c3a 100644
--- a/chromium/content/child/web_url_loader_impl.h
+++ b/chromium/content/renderer/loader/web_url_loader_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_WEB_URL_LOADER_IMPL_H_
-#define CONTENT_CHILD_WEB_URL_LOADER_IMPL_H_
+#ifndef CONTENT_RENDERER_LOADER_WEB_URL_LOADER_IMPL_H_
+#define CONTENT_RENDERER_LOADER_WEB_URL_LOADER_IMPL_H_
#include <vector>
@@ -17,6 +17,7 @@
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/url_request/redirect_info.h"
#include "third_party/WebKit/public/platform/WebURLLoader.h"
+#include "third_party/WebKit/public/platform/WebURLLoaderFactory.h"
#include "url/gurl.h"
namespace base {
@@ -25,6 +26,7 @@ class SingleThreadTaskRunner;
namespace content {
+class ChildURLLoaderFactoryGetter;
class ResourceDispatcher;
struct ResourceResponseInfo;
@@ -41,10 +43,6 @@ struct CONTENT_EXPORT StreamOverrideParameters {
std::vector<ResourceResponseInfo> redirect_responses;
std::vector<net::RedirectInfo> redirect_infos;
- // The delta between the actual transfer size and the one reported by the
- // AsyncResourceLoader due to not having the ResourceResponse.
- int total_transfer_size_delta;
-
int total_transferred = 0;
// Called when this struct is deleted. Used to notify the browser that it can
@@ -52,6 +50,28 @@ struct CONTENT_EXPORT StreamOverrideParameters {
base::OnceCallback<void(const GURL&)> on_delete;
};
+// Default implementation of WebURLLoaderFactory.
+class CONTENT_EXPORT WebURLLoaderFactoryImpl
+ : public blink::WebURLLoaderFactory {
+ public:
+ WebURLLoaderFactoryImpl(
+ base::WeakPtr<ResourceDispatcher> resource_dispatcher,
+ scoped_refptr<ChildURLLoaderFactoryGetter> loader_factory_getter);
+ ~WebURLLoaderFactoryImpl() override;
+
+ // Creates a test-only factory which can be used only for data URLs.
+ static std::unique_ptr<WebURLLoaderFactoryImpl> CreateTestOnlyFactory();
+
+ std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
+ const blink::WebURLRequest& request,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
+
+ private:
+ base::WeakPtr<ResourceDispatcher> resource_dispatcher_;
+ scoped_refptr<ChildURLLoaderFactoryGetter> loader_factory_getter_;
+ DISALLOW_COPY_AND_ASSIGN(WebURLLoaderFactoryImpl);
+};
+
class CONTENT_EXPORT WebURLLoaderImpl : public blink::WebURLLoader {
public:
WebURLLoaderImpl(ResourceDispatcher* resource_dispatcher,
@@ -72,7 +92,7 @@ class CONTENT_EXPORT WebURLLoaderImpl : public blink::WebURLLoader {
// WebURLLoader methods:
void LoadSynchronously(const blink::WebURLRequest& request,
blink::WebURLResponse& response,
- blink::WebURLError& error,
+ base::Optional<blink::WebURLError>& error,
blink::WebData& data,
int64_t& encoded_data_length,
int64_t& encoded_body_length) override;
@@ -92,4 +112,4 @@ class CONTENT_EXPORT WebURLLoaderImpl : public blink::WebURLLoader {
} // namespace content
-#endif // CONTENT_CHILD_WEB_URL_LOADER_IMPL_H_
+#endif // CONTENT_RENDERER_LOADER_WEB_URL_LOADER_IMPL_H_
diff --git a/chromium/content/child/web_url_loader_impl_unittest.cc b/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
index ccdaa78a227..5b096cf3552 100644
--- a/chromium/content/child/web_url_loader_impl_unittest.cc
+++ b/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/web_url_loader_impl.h"
+#include "content/renderer/loader/web_url_loader_impl.h"
#include <stdint.h>
#include <string.h>
@@ -19,13 +19,13 @@
#include "base/single_thread_task_runner.h"
#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/resource_dispatcher.h"
-#include "content/child/sync_load_response.h"
-#include "content/public/child/fixed_received_data.h"
-#include "content/public/child/request_peer.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/resource_response_info.h"
+#include "content/public/renderer/fixed_received_data.h"
+#include "content/public/renderer/request_peer.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/loader/resource_dispatcher.h"
+#include "content/renderer/loader/sync_load_response.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
@@ -215,8 +215,7 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient {
// The response should have started, but must not have finished, or failed.
EXPECT_TRUE(did_receive_response_);
EXPECT_FALSE(did_finish_);
- EXPECT_EQ(net::OK, error_.reason);
- EXPECT_EQ(blink::WebURLError::Domain::kEmpty, error_.domain);
+ EXPECT_FALSE(error_);
received_data_.append(data, dataLength);
@@ -264,7 +263,7 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient {
bool did_receive_response() const { return did_receive_response_; }
const std::string& received_data() const { return received_data_; }
bool did_finish() const { return did_finish_; }
- const blink::WebURLError& error() const { return error_; }
+ const base::Optional<blink::WebURLError>& error() const { return error_; }
const blink::WebURLResponse& response() const { return response_; }
private:
@@ -281,7 +280,7 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient {
bool did_receive_response_;
std::string received_data_;
bool did_finish_;
- blink::WebURLError error_;
+ base::Optional<blink::WebURLError> error_;
blink::WebURLResponse response_;
DISALLOW_COPY_AND_ASSIGN(TestWebURLLoaderClient);
@@ -346,29 +345,32 @@ class WebURLLoaderImplTest : public testing::Test {
EXPECT_EQ("", client()->received_data());
auto size = strlen(kTestData);
peer()->OnReceivedData(
- base::MakeUnique<FixedReceivedData>(kTestData, size));
+ std::make_unique<FixedReceivedData>(kTestData, size));
EXPECT_EQ(kTestData, client()->received_data());
}
void DoCompleteRequest() {
EXPECT_FALSE(client()->did_finish());
- peer()->OnCompletedRequest(net::OK, false, base::TimeTicks(),
- strlen(kTestData), strlen(kTestData),
- strlen(kTestData));
+ network::URLLoaderCompletionStatus status(net::OK);
+ status.encoded_data_length = arraysize(kTestData);
+ status.encoded_body_length = arraysize(kTestData);
+ status.decoded_body_length = arraysize(kTestData);
+ peer()->OnCompletedRequest(status);
EXPECT_TRUE(client()->did_finish());
// There should be no error.
- EXPECT_EQ(net::OK, client()->error().reason);
- EXPECT_EQ(blink::WebURLError::Domain::kEmpty, client()->error().domain);
+ EXPECT_FALSE(client()->error());
}
void DoFailRequest() {
EXPECT_FALSE(client()->did_finish());
- peer()->OnCompletedRequest(net::ERR_FAILED, false, base::TimeTicks(),
- strlen(kTestData), strlen(kTestData),
- strlen(kTestData));
+ network::URLLoaderCompletionStatus status(net::ERR_FAILED);
+ status.encoded_data_length = arraysize(kTestData);
+ status.encoded_body_length = arraysize(kTestData);
+ status.decoded_body_length = arraysize(kTestData);
+ peer()->OnCompletedRequest(status);
EXPECT_FALSE(client()->did_finish());
- EXPECT_EQ(net::ERR_FAILED, client()->error().reason);
- EXPECT_EQ(blink::WebURLError::Domain::kNet, client()->error().domain);
+ ASSERT_TRUE(client()->error());
+ EXPECT_EQ(net::ERR_FAILED, client()->error()->reason());
}
void DoReceiveResponseFtp() {
@@ -382,7 +384,7 @@ class WebURLLoaderImplTest : public testing::Test {
void DoReceiveDataFtp() {
auto size = strlen(kFtpDirListing);
peer()->OnReceivedData(
- base::MakeUnique<FixedReceivedData>(kFtpDirListing, size));
+ std::make_unique<FixedReceivedData>(kFtpDirListing, size));
// The FTP delegate should modify the data the client sees.
EXPECT_NE(kFtpDirListing, client()->received_data());
}
@@ -478,8 +480,7 @@ TEST_F(WebURLLoaderImplTest, DataURL) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ("blah!", client()->received_data());
EXPECT_TRUE(client()->did_finish());
- EXPECT_EQ(net::OK, client()->error().reason);
- EXPECT_EQ(blink::WebURLError::Domain::kEmpty, client()->error().domain);
+ EXPECT_FALSE(client()->error());
}
TEST_F(WebURLLoaderImplTest, DataURLDeleteOnReceiveResponse) {
@@ -544,8 +545,7 @@ TEST_F(WebURLLoaderImplTest, DataURLDefersLoading) {
EXPECT_TRUE(client()->did_finish());
EXPECT_EQ("blah!", client()->received_data());
- EXPECT_EQ(net::OK, client()->error().reason);
- EXPECT_EQ(blink::WebURLError::Domain::kEmpty, client()->error().domain);
+ EXPECT_FALSE(client()->error());
}
TEST_F(WebURLLoaderImplTest, DefersLoadingBeforeStart) {
@@ -591,9 +591,12 @@ TEST_F(WebURLLoaderImplTest, FtpDeleteOnReceiveMoreData) {
// Directory listings are only parsed once the request completes, so this will
// cancel in DoReceiveDataFtp, before the request finishes.
client()->set_delete_on_receive_data();
- peer()->OnCompletedRequest(net::OK, false, base::TimeTicks(),
- strlen(kTestData), strlen(kTestData),
- strlen(kTestData));
+
+ network::URLLoaderCompletionStatus status(net::OK);
+ status.encoded_data_length = arraysize(kTestData);
+ status.encoded_body_length = arraysize(kTestData);
+ status.decoded_body_length = arraysize(kTestData);
+ peer()->OnCompletedRequest(status);
EXPECT_FALSE(client()->did_finish());
}
@@ -701,7 +704,7 @@ TEST_F(WebURLLoaderImplTest, SyncLengths) {
dispatcher()->set_sync_load_response(sync_load_response);
blink::WebURLResponse response;
- blink::WebURLError error;
+ base::Optional<blink::WebURLError> error;
blink::WebData data;
int64_t encoded_data_length = 0;
int64_t encoded_body_length = 0;
diff --git a/chromium/content/child/web_url_request_util.cc b/chromium/content/renderer/loader/web_url_request_util.cc
index 1081d7c1371..d2ce71c7b61 100644
--- a/chromium/content/child/web_url_request_util.cc
+++ b/chromium/content/renderer/loader/web_url_request_util.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/child/web_url_request_util.h"
+#include "content/renderer/loader/web_url_request_util.h"
#include <stddef.h>
#include <stdint.h>
@@ -11,18 +11,30 @@
#include "base/logging.h"
#include "base/strings/string_util.h"
-#include "content/child/request_extra_data.h"
+#include "base/task_scheduler/post_task.h"
+#include "content/child/child_thread_impl.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/service_names.mojom.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/http/http_util.h"
+#include "services/network/public/interfaces/data_pipe_getter.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/WebKit/common/blob/blob.mojom.h"
+#include "third_party/WebKit/common/blob/blob_registry.mojom.h"
#include "third_party/WebKit/public/platform/FilePathConversion.h"
-#include "third_party/WebKit/public/platform/WebCachePolicy.h"
+#include "third_party/WebKit/public/platform/Platform.h"
#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
#include "third_party/WebKit/public/platform/WebMixedContent.h"
#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/WebThread.h"
+#include "third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
-using blink::WebCachePolicy;
+using blink::mojom::FetchCacheMode;
using blink::WebData;
using blink::WebHTTPBody;
using blink::WebString;
@@ -93,6 +105,82 @@ class HeaderFlattener : public blink::WebHTTPHeaderVisitor {
std::string buffer_;
};
+// Vends data pipes to read a Blob. It stays alive by StrongBinding to the Mojo
+// request.
+class DataPipeGetter : public network::mojom::DataPipeGetter {
+ public:
+ DataPipeGetter(blink::mojom::BlobPtr blob,
+ network::mojom::DataPipeGetterRequest request) {
+ // If a sync XHR is doing the upload, then the main thread will be blocked.
+ // So we must bind on a background thread, otherwise the methods below will
+ // never be called and the process will hang.
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {base::TaskPriority::USER_VISIBLE,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DataPipeGetter::BindInternal, base::Unretained(this),
+ blob.PassInterface(), std::move(request)));
+ }
+ ~DataPipeGetter() override = default;
+
+ private:
+ class BlobReaderClient : public blink::mojom::BlobReaderClient {
+ public:
+ explicit BlobReaderClient(ReadCallback callback)
+ : callback_(std::move(callback)) {
+ DCHECK(!callback_.is_null());
+ }
+ ~BlobReaderClient() override = default;
+
+ // blink::mojom::BlobReaderClient implementation:
+ void OnCalculatedSize(uint64_t total_size,
+ uint64_t expected_content_size) override {
+ // Check if null since it's conceivable OnComplete() was already called
+ // with error.
+ if (!callback_.is_null())
+ std::move(callback_).Run(net::OK, total_size);
+ }
+ void OnComplete(int32_t status, uint64_t data_length) override {
+ // Check if null since OnCalculatedSize() may have already been called
+ // and an error occurred later.
+ if (!callback_.is_null() && status != net::OK) {
+ // On error, signal failure immediately. On success, OnCalculatedSize()
+ // is guaranteed to be called, and the result will be signaled from
+ // there.
+ std::move(callback_).Run(status, 0);
+ }
+ }
+
+ private:
+ ReadCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(BlobReaderClient);
+ };
+
+ void BindInternal(blink::mojom::BlobPtrInfo blob,
+ network::mojom::DataPipeGetterRequest request) {
+ mojo::MakeStrongBinding(base::WrapUnique(this), std::move(request));
+ blob_.Bind(std::move(blob));
+ }
+
+ // network::mojom::DataPipeGetter implementation:
+ void Read(mojo::ScopedDataPipeProducerHandle handle,
+ ReadCallback callback) override {
+ blink::mojom::BlobReaderClientPtr blob_reader_client_ptr;
+ mojo::MakeStrongBinding(
+ std::make_unique<BlobReaderClient>(std::move(callback)),
+ mojo::MakeRequest(&blob_reader_client_ptr));
+ blob_->ReadAll(std::move(handle), std::move(blob_reader_client_ptr));
+ }
+
+ private:
+ blink::mojom::BlobPtr blob_;
+
+ DISALLOW_COPY_AND_ASSIGN(DataPipeGetter);
+};
+
} // namespace
ResourceType WebURLRequestContextToResourceType(
@@ -232,25 +320,28 @@ std::string GetWebURLRequestHeadersAsString(
int GetLoadFlagsForWebURLRequest(const WebURLRequest& request) {
int load_flags = net::LOAD_NORMAL;
GURL url = request.Url();
- switch (request.GetCachePolicy()) {
- case WebCachePolicy::kValidatingCacheData:
+ switch (request.GetCacheMode()) {
+ case FetchCacheMode::kNoStore:
+ load_flags |= net::LOAD_DISABLE_CACHE;
+ break;
+ case FetchCacheMode::kValidateCache:
load_flags |= net::LOAD_VALIDATE_CACHE;
break;
- case WebCachePolicy::kBypassingCache:
+ case FetchCacheMode::kBypassCache:
load_flags |= net::LOAD_BYPASS_CACHE;
break;
- case WebCachePolicy::kReturnCacheDataElseLoad:
+ case FetchCacheMode::kForceCache:
load_flags |= net::LOAD_SKIP_CACHE_VALIDATION;
break;
- case WebCachePolicy::kReturnCacheDataDontLoad:
+ case FetchCacheMode::kOnlyIfCached:
load_flags |= net::LOAD_ONLY_FROM_CACHE | net::LOAD_SKIP_CACHE_VALIDATION;
break;
- case WebCachePolicy::kReturnCacheDataIfValid:
+ case FetchCacheMode::kUnspecifiedOnlyIfCachedStrict:
load_flags |= net::LOAD_ONLY_FROM_CACHE;
break;
- case WebCachePolicy::kUseProtocolCachePolicy:
+ case FetchCacheMode::kDefault:
break;
- case WebCachePolicy::kBypassCacheLoadOnlyFromCache:
+ case FetchCacheMode::kUnspecifiedForceCacheMiss:
load_flags |= net::LOAD_ONLY_FROM_CACHE | net::LOAD_BYPASS_CACHE;
break;
}
@@ -290,17 +381,13 @@ WebHTTPBody GetWebHTTPBodyForRequestBody(
: -1,
element.expected_modification_time().ToDoubleT());
break;
- case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM:
- http_body.AppendFileSystemURLRange(
- element.filesystem_url(), element.offset(),
- (element.length() != std::numeric_limits<uint64_t>::max())
- ? element.length()
- : -1,
- element.expected_modification_time().ToDoubleT());
- break;
case ResourceRequestBody::Element::TYPE_BLOB:
http_body.AppendBlob(WebString::FromASCII(element.blob_uuid()));
break;
+ case ResourceRequestBody::Element::TYPE_DATA_PIPE:
+ // TODO(falken): Implement this.
+ NOTIMPLEMENTED() << "data pipe";
+ break;
case ResourceRequestBody::Element::TYPE_BYTES_DESCRIPTION:
case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
default:
@@ -326,11 +413,18 @@ scoped_refptr<ResourceRequestBody> GetRequestBodyForWebURLRequest(
return GetRequestBodyForWebHTTPBody(request.HttpBody());
}
+void GetBlobRegistry(blink::mojom::BlobRegistryRequest request) {
+ ChildThreadImpl::current()->GetConnector()->BindInterface(
+ mojom::kBrowserServiceName, std::move(request));
+}
+
scoped_refptr<ResourceRequestBody> GetRequestBodyForWebHTTPBody(
const blink::WebHTTPBody& httpBody) {
scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody();
size_t i = 0;
WebHTTPBody::Element element;
+ // TODO(jam): cache this somewhere so we don't request it each time?
+ blink::mojom::BlobRegistryPtr blob_registry;
while (httpBody.ElementAt(i++, element)) {
switch (element.type) {
case WebHTTPBody::Element::kTypeData:
@@ -363,9 +457,38 @@ scoped_refptr<ResourceRequestBody> GetRequestBodyForWebHTTPBody(
base::Time::FromDoubleT(element.modification_time));
break;
}
- case WebHTTPBody::Element::kTypeBlob:
- request_body->AppendBlob(element.blob_uuid.Utf8());
+ case WebHTTPBody::Element::kTypeBlob: {
+ if (base::FeatureList::IsEnabled(features::kNetworkService)) {
+ if (!blob_registry.is_bound()) {
+ if (ChildThreadImpl::current()) {
+ ChildThreadImpl::current()->GetConnector()->BindInterface(
+ mojom::kBrowserServiceName, MakeRequest(&blob_registry));
+ } else {
+ // TODO(sammc): We should use per-frame / per-worker
+ // InterfaceProvider instead (crbug.com/734210).
+ blink::Platform::Current()
+ ->MainThread()
+ ->GetSingleThreadTaskRunner()
+ ->PostTask(FROM_HERE,
+ base::BindOnce(&GetBlobRegistry,
+ MakeRequest(&blob_registry)));
+ }
+ }
+ blink::mojom::BlobPtr blob_ptr;
+ blob_registry->GetBlobFromUUID(MakeRequest(&blob_ptr),
+ element.blob_uuid.Utf8());
+
+ network::mojom::DataPipeGetterPtr data_pipe_getter_ptr;
+ // Object deletes itself.
+ new DataPipeGetter(std::move(blob_ptr),
+ MakeRequest(&data_pipe_getter_ptr));
+
+ request_body->AppendDataPipe(std::move(data_pipe_getter_ptr));
+ } else {
+ request_body->AppendBlob(element.blob_uuid.Utf8());
+ }
break;
+ }
default:
NOTREACHED();
}
@@ -379,36 +502,6 @@ scoped_refptr<ResourceRequestBody> GetRequestBodyForWebHTTPBody(
static_assert(static_cast<int>(a) == static_cast<int>(b), \
"mismatching enums: " #a)
-STATIC_ASSERT_ENUM(FETCH_REQUEST_MODE_SAME_ORIGIN,
- WebURLRequest::kFetchRequestModeSameOrigin);
-STATIC_ASSERT_ENUM(FETCH_REQUEST_MODE_NO_CORS,
- WebURLRequest::kFetchRequestModeNoCORS);
-STATIC_ASSERT_ENUM(FETCH_REQUEST_MODE_CORS,
- WebURLRequest::kFetchRequestModeCORS);
-STATIC_ASSERT_ENUM(FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT,
- WebURLRequest::kFetchRequestModeCORSWithForcedPreflight);
-STATIC_ASSERT_ENUM(FETCH_REQUEST_MODE_NAVIGATE,
- WebURLRequest::kFetchRequestModeNavigate);
-
-FetchRequestMode GetFetchRequestModeForWebURLRequest(
- const WebURLRequest& request) {
- return static_cast<FetchRequestMode>(request.GetFetchRequestMode());
-}
-
-STATIC_ASSERT_ENUM(FETCH_CREDENTIALS_MODE_OMIT,
- WebURLRequest::kFetchCredentialsModeOmit);
-STATIC_ASSERT_ENUM(FETCH_CREDENTIALS_MODE_SAME_ORIGIN,
- WebURLRequest::kFetchCredentialsModeSameOrigin);
-STATIC_ASSERT_ENUM(FETCH_CREDENTIALS_MODE_INCLUDE,
- WebURLRequest::kFetchCredentialsModeInclude);
-STATIC_ASSERT_ENUM(FETCH_CREDENTIALS_MODE_PASSWORD,
- WebURLRequest::kFetchCredentialsModePassword);
-
-FetchCredentialsMode GetFetchCredentialsModeForWebURLRequest(
- const WebURLRequest& request) {
- return static_cast<FetchCredentialsMode>(request.GetFetchCredentialsMode());
-}
-
STATIC_ASSERT_ENUM(FetchRedirectMode::FOLLOW_MODE,
WebURLRequest::kFetchRedirectModeFollow);
STATIC_ASSERT_ENUM(FetchRedirectMode::ERROR_MODE,
@@ -528,8 +621,6 @@ blink::WebMixedContentContextType GetMixedContentContextTypeForWebURLRequest(
STATIC_ASSERT_ENUM(ServiceWorkerMode::NONE,
WebURLRequest::ServiceWorkerMode::kNone);
-STATIC_ASSERT_ENUM(ServiceWorkerMode::FOREIGN,
- WebURLRequest::ServiceWorkerMode::kForeign);
STATIC_ASSERT_ENUM(ServiceWorkerMode::ALL,
WebURLRequest::ServiceWorkerMode::kAll);
diff --git a/chromium/content/child/web_url_request_util.h b/chromium/content/renderer/loader/web_url_request_util.h
index f7f8a8839f5..205927f4700 100644
--- a/chromium/content/child/web_url_request_util.h
+++ b/chromium/content/renderer/loader/web_url_request_util.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_CHILD_WEB_URL_REQUEST_UTIL_H_
-#define CONTENT_CHILD_WEB_URL_REQUEST_UTIL_H_
+#ifndef CONTENT_RENDERER_LOADER_WEB_URL_REQUEST_UTIL_H_
+#define CONTENT_RENDERER_LOADER_WEB_URL_REQUEST_UTIL_H_
#include <string>
@@ -53,10 +53,6 @@ scoped_refptr<ResourceRequestBody> GetRequestBodyForWebURLRequest(
// Helper functions to convert enums from the blink type to the content
// type.
-FetchRequestMode GetFetchRequestModeForWebURLRequest(
- const blink::WebURLRequest& request);
-FetchCredentialsMode GetFetchCredentialsModeForWebURLRequest(
- const blink::WebURLRequest& request);
FetchRedirectMode GetFetchRedirectModeForWebURLRequest(
const blink::WebURLRequest& request);
std::string GetFetchIntegrityForWebURLRequest(
@@ -72,4 +68,4 @@ ServiceWorkerMode GetServiceWorkerModeForWebURLRequest(
} // namespace content
-#endif // CONTENT_CHILD_WEB_URL_REQUEST_UTIL_H_
+#endif // CONTENT_RENDERER_LOADER_WEB_URL_REQUEST_UTIL_H_
diff --git a/chromium/content/child/weburlresponse_extradata_impl.cc b/chromium/content/renderer/loader/weburlresponse_extradata_impl.cc
index ebd4d036163..c30ad8e14cd 100644
--- a/chromium/content/child/weburlresponse_extradata_impl.cc
+++ b/chromium/content/renderer/loader/weburlresponse_extradata_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/weburlresponse_extradata_impl.h"
+#include "content/renderer/loader/weburlresponse_extradata_impl.h"
namespace content {
diff --git a/chromium/content/child/weburlresponse_extradata_impl.h b/chromium/content/renderer/loader/weburlresponse_extradata_impl.h
index 79746ba5ada..0827cfb9247 100644
--- a/chromium/content/child/weburlresponse_extradata_impl.h
+++ b/chromium/content/renderer/loader/weburlresponse_extradata_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_WEBURLRESPONSE_EXTRADATA_IMPL_H_
-#define CONTENT_CHILD_WEBURLRESPONSE_EXTRADATA_IMPL_H_
+#ifndef CONTENT_RENDERER_LOADER_WEBURLRESPONSE_EXTRADATA_IMPL_H_
+#define CONTENT_RENDERER_LOADER_WEBURLRESPONSE_EXTRADATA_IMPL_H_
#include <string>
@@ -82,4 +82,4 @@ class CONTENT_EXPORT WebURLResponseExtraDataImpl
} // namespace content
-#endif // CONTENT_CHILD_WEBURLRESPONSE_EXTRADATA_IMPL_H_
+#endif // CONTENT_RENDERER_LOADER_WEBURLRESPONSE_EXTRADATA_IMPL_H_
diff --git a/chromium/content/renderer/manifest/manifest_debug_info.cc b/chromium/content/renderer/manifest/manifest_debug_info.cc
deleted file mode 100644
index c2ff627aa3c..00000000000
--- a/chromium/content/renderer/manifest/manifest_debug_info.cc
+++ /dev/null
@@ -1,13 +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/renderer/manifest/manifest_debug_info.h"
-
-namespace content {
-
-ManifestDebugInfo::ManifestDebugInfo() = default;
-
-ManifestDebugInfo::~ManifestDebugInfo() = default;
-
-} // namespace content
diff --git a/chromium/content/renderer/manifest/manifest_debug_info.h b/chromium/content/renderer/manifest/manifest_debug_info.h
deleted file mode 100644
index b5ff700603f..00000000000
--- a/chromium/content/renderer/manifest/manifest_debug_info.h
+++ /dev/null
@@ -1,38 +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_RENDERER_MANIFEST_MANIFEST_DEBUG_INFO_H_
-#define CONTENT_RENDERER_MANIFEST_MANIFEST_DEBUG_INFO_H_
-
-#include <string>
-#include <vector>
-
-namespace content {
-
-// ManifestDebugInfo contains debug information for the parsed manifest.
-// It is created upon parsing and is available along the Manifest itself
-// via ManifestManager. Parsing errors can be generic and critical, critical
-// errors result in parser failure.
-struct ManifestDebugInfo {
- struct Error {
- Error(const std::string& message, bool critical, int line, int column)
- : message(message),
- critical(critical),
- line(line),
- column(column) {}
- std::string message;
- bool critical;
- int line;
- int column;
- };
-
- ManifestDebugInfo();
- ~ManifestDebugInfo();
- std::vector<Error> errors;
- std::string raw_data;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MANIFEST_MANIFEST_DEBUG_INFO_H_
diff --git a/chromium/content/renderer/manifest/manifest_manager.cc b/chromium/content/renderer/manifest/manifest_manager.cc
index 55d0aa8266e..e473be973a0 100644
--- a/chromium/content/renderer/manifest/manifest_manager.cc
+++ b/chromium/content/renderer/manifest/manifest_manager.cc
@@ -8,11 +8,11 @@
#include "base/bind.h"
#include "base/strings/nullable_string16.h"
-#include "content/public/common/associated_interface_provider.h"
#include "content/public/renderer/render_frame.h"
#include "content/renderer/fetchers/manifest_fetcher.h"
#include "content/renderer/manifest/manifest_parser.h"
#include "content/renderer/manifest/manifest_uma_util.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
#include "third_party/WebKit/public/web/WebDocument.h"
@@ -37,26 +37,37 @@ ManifestManager::~ManifestManager() {
}
void ManifestManager::RequestManifest(RequestManifestCallback callback) {
- GetManifest(base::BindOnce(&ManifestManager::OnRequestManifestComplete,
- base::Unretained(this), std::move(callback)));
+ RequestManifestImpl(base::BindOnce(
+ [](RequestManifestCallback callback, const GURL& manifest_url,
+ const Manifest& manifest,
+ const blink::mojom::ManifestDebugInfo* debug_info) {
+ std::move(callback).Run(manifest_url, manifest);
+ },
+ std::move(callback)));
}
-void ManifestManager::OnRequestManifestComplete(
- RequestManifestCallback callback,
- const GURL& url,
- const Manifest& manifest,
- const ManifestDebugInfo& debug_info) {
- std::move(callback).Run(url, manifest);
+void ManifestManager::RequestManifestDebugInfo(
+ RequestManifestDebugInfoCallback callback) {
+ RequestManifestImpl(base::BindOnce(
+ [](RequestManifestDebugInfoCallback callback, const GURL& manifest_url,
+ const Manifest& manifest,
+ const blink::mojom::ManifestDebugInfo* debug_info) {
+ std::move(callback).Run(manifest_url,
+ debug_info ? debug_info->Clone() : nullptr);
+ },
+ std::move(callback)));
}
-void ManifestManager::GetManifest(GetManifestCallback callback) {
+void ManifestManager::RequestManifestImpl(
+ InternalRequestManifestCallback callback) {
if (!may_have_manifest_) {
- std::move(callback).Run(GURL(), Manifest(), ManifestDebugInfo());
+ std::move(callback).Run(GURL(), Manifest(), nullptr);
return;
}
if (!manifest_dirty_) {
- std::move(callback).Run(manifest_url_, manifest_, manifest_debug_info_);
+ std::move(callback).Run(manifest_url_, manifest_,
+ manifest_debug_info_.get());
return;
}
@@ -73,6 +84,7 @@ void ManifestManager::DidChangeManifest() {
may_have_manifest_ = true;
manifest_dirty_ = true;
manifest_url_ = GURL();
+ manifest_debug_info_ = nullptr;
if (!render_frame()->IsMainFrame())
return;
@@ -138,6 +150,7 @@ void ManifestManager::OnManifestFetchComplete(
const blink::WebURLResponse& response,
const std::string& data) {
if (response.IsNull() && data.empty()) {
+ manifest_debug_info_ = nullptr;
ManifestUmaUtil::FetchFailed(ManifestUmaUtil::FETCH_UNSPECIFIED_REASON);
ResolveCallbacks(ResolveStateFailure);
return;
@@ -150,19 +163,20 @@ void ManifestManager::OnManifestFetchComplete(
parser.Parse();
fetcher_.reset();
- manifest_debug_info_.raw_data = data;
- parser.TakeErrors(&manifest_debug_info_.errors);
+ manifest_debug_info_ = blink::mojom::ManifestDebugInfo::New();
+ manifest_debug_info_->raw_manifest = data;
+ parser.TakeErrors(&manifest_debug_info_->errors);
- for (const auto& error : manifest_debug_info_.errors) {
+ for (const auto& error : manifest_debug_info_->errors) {
blink::WebConsoleMessage message;
- message.level = error.critical ? blink::WebConsoleMessage::kLevelError
- : blink::WebConsoleMessage::kLevelWarning;
+ message.level = error->critical ? blink::WebConsoleMessage::kLevelError
+ : blink::WebConsoleMessage::kLevelWarning;
message.text =
- blink::WebString::FromUTF8(GetMessagePrefix() + error.message);
+ blink::WebString::FromUTF8(GetMessagePrefix() + error->message);
message.url =
render_frame()->GetWebFrame()->GetDocument().ManifestURL().GetString();
- message.line_number = error.line;
- message.column_number = error.column;
+ message.line_number = error->line;
+ message.column_number = error->column;
render_frame()->GetWebFrame()->AddMessageToConsole(message);
}
@@ -190,21 +204,21 @@ void ManifestManager::ResolveCallbacks(ResolveState state) {
manifest_dirty_ = state != ResolveStateSuccess;
- std::vector<GetManifestCallback> callbacks;
+ std::vector<InternalRequestManifestCallback> callbacks;
swap(callbacks, pending_callbacks_);
- for (auto& callback : callbacks)
- std::move(callback).Run(manifest_url_, manifest_, manifest_debug_info_);
+ for (auto& callback : callbacks) {
+ std::move(callback).Run(manifest_url_, manifest_,
+ manifest_debug_info_.get());
+ }
}
void ManifestManager::BindToRequest(
- blink::mojom::ManifestManagerAssociatedRequest request) {
+ blink::mojom::ManifestManagerRequest request) {
bindings_.AddBinding(this, std::move(request));
}
-void ManifestManager::OnDestruct() {
- delete this;
-}
+void ManifestManager::OnDestruct() {}
void ManifestManager::ReportManifestChange() {
auto manifest_url =
diff --git a/chromium/content/renderer/manifest/manifest_manager.h b/chromium/content/renderer/manifest/manifest_manager.h
index 5b7d3f2e6d4..7535681f0ff 100644
--- a/chromium/content/renderer/manifest/manifest_manager.h
+++ b/chromium/content/renderer/manifest/manifest_manager.h
@@ -15,8 +15,7 @@
#include "content/common/manifest_observer.mojom.h"
#include "content/public/common/manifest.h"
#include "content/public/renderer/render_frame_observer.h"
-#include "content/renderer/manifest/manifest_debug_info.h"
-#include "mojo/public/cpp/bindings/associated_binding_set.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
#include "third_party/WebKit/public/platform/modules/manifest/manifest_manager.mojom.h"
class GURL;
@@ -32,28 +31,20 @@ class ManifestFetcher;
// The ManifestManager is a helper class that takes care of fetching and parsing
// the Manifest of the associated RenderFrame. It uses the ManifestFetcher and
// the ManifestParser in order to do so.
-// There are two expected consumers of this helper: ManifestManagerHost, via IPC
-// messages and callers inside the renderer process. The latter should use
-// GetManifest().
+//
+// Consumers should use the mojo ManifestManager interface to use this class.
class ManifestManager : public RenderFrameObserver,
public blink::mojom::ManifestManager {
public:
- using GetManifestCallback = base::OnceCallback<
- void(const GURL&, const Manifest&, const ManifestDebugInfo&)>;
-
explicit ManifestManager(RenderFrame* render_frame);
~ManifestManager() override;
- // Will call the given |callback| with the Manifest associated with the
- // RenderFrame if any. Will pass an empty Manifest in case of error.
- void GetManifest(GetManifestCallback callback);
-
// RenderFrameObserver implementation.
void DidChangeManifest() override;
void DidCommitProvisionalLoad(bool is_new_navigation,
bool is_same_document_navigation) override;
- void BindToRequest(blink::mojom::ManifestManagerAssociatedRequest request);
+ void BindToRequest(blink::mojom::ManifestManagerRequest request);
private:
enum ResolveState {
@@ -61,17 +52,20 @@ class ManifestManager : public RenderFrameObserver,
ResolveStateFailure
};
+ using InternalRequestManifestCallback =
+ base::OnceCallback<void(const GURL&,
+ const Manifest&,
+ const blink::mojom::ManifestDebugInfo*)>;
+
// RenderFrameObserver implementation.
void OnDestruct() override;
// blink::mojom::ManifestManager implementation.
void RequestManifest(RequestManifestCallback callback) override;
+ void RequestManifestDebugInfo(
+ RequestManifestDebugInfoCallback callback) override;
- // Called when receiving a RequestManifest() call from the browser process.
- void OnRequestManifestComplete(RequestManifestCallback callback,
- const GURL& url,
- const Manifest& manifest,
- const ManifestDebugInfo& debug_info);
+ void RequestManifestImpl(InternalRequestManifestCallback callback);
void FetchManifest();
void OnManifestFetchComplete(const GURL& document_url,
@@ -100,13 +94,13 @@ class ManifestManager : public RenderFrameObserver,
GURL manifest_url_;
// Current Manifest debug information.
- ManifestDebugInfo manifest_debug_info_;
+ blink::mojom::ManifestDebugInfoPtr manifest_debug_info_;
mojom::ManifestUrlChangeObserverAssociatedPtr manifest_change_observer_;
- std::vector<GetManifestCallback> pending_callbacks_;
+ std::vector<InternalRequestManifestCallback> pending_callbacks_;
- mojo::AssociatedBindingSet<blink::mojom::ManifestManager> bindings_;
+ mojo::BindingSet<blink::mojom::ManifestManager> bindings_;
base::WeakPtrFactory<ManifestManager> weak_factory_;
diff --git a/chromium/content/renderer/manifest/manifest_parser.cc b/chromium/content/renderer/manifest/manifest_parser.cc
index a5ecd7b8007..faf66e6d451 100644
--- a/chromium/content/renderer/manifest/manifest_parser.cc
+++ b/chromium/content/renderer/manifest/manifest_parser.cc
@@ -75,6 +75,7 @@ void ManifestParser::Parse() {
ParsePreferRelatedApplications(*dictionary);
manifest_.theme_color = ParseThemeColor(*dictionary);
manifest_.background_color = ParseBackgroundColor(*dictionary);
+ manifest_.splash_screen_url = ParseSplashScreenURL(*dictionary);
manifest_.gcm_sender_id = ParseGCMSenderID(*dictionary);
ManifestUmaUtil::ParseSucceeded(manifest_);
@@ -85,7 +86,7 @@ const Manifest& ManifestParser::manifest() const {
}
void ManifestParser::TakeErrors(
- std::vector<ManifestDebugInfo::Error>* errors) {
+ std::vector<blink::mojom::ManifestErrorPtr>* errors) {
errors->clear();
errors->swap(errors_);
}
@@ -155,15 +156,32 @@ int64_t ManifestParser::ParseColor(
GURL ManifestParser::ParseURL(const base::DictionaryValue& dictionary,
const std::string& key,
- const GURL& base_url) {
+ const GURL& base_url,
+ ParseURLOriginRestrictions origin_restriction) {
base::NullableString16 url_str = ParseString(dictionary, key, NoTrim);
if (url_str.is_null())
return GURL();
GURL resolved = base_url.Resolve(url_str.string());
- if (!resolved.is_valid())
+ if (!resolved.is_valid()) {
AddErrorInfo("property '" + key + "' ignored, URL is invalid.");
- return resolved;
+ return GURL();
+ }
+
+ switch (origin_restriction) {
+ case ParseURLOriginRestrictions::kSameOriginOnly:
+ if (resolved.GetOrigin() != document_url_.GetOrigin()) {
+ AddErrorInfo("property '" + key +
+ "' ignored, should be same origin as document.");
+ return GURL();
+ }
+ return resolved;
+ case ParseURLOriginRestrictions::kNoRestrictions:
+ return resolved;
+ }
+
+ NOTREACHED();
+ return GURL();
}
base::NullableString16 ManifestParser::ParseName(
@@ -177,43 +195,28 @@ base::NullableString16 ManifestParser::ParseShortName(
}
GURL ManifestParser::ParseStartURL(const base::DictionaryValue& dictionary) {
- GURL start_url = ParseURL(dictionary, "start_url", manifest_url_);
- if (!start_url.is_valid())
- return GURL();
-
- if (start_url.GetOrigin() != document_url_.GetOrigin()) {
- AddErrorInfo("property 'start_url' ignored, should be "
- "same origin as document.");
- return GURL();
- }
-
- return start_url;
+ return ParseURL(dictionary, "start_url", manifest_url_,
+ ParseURLOriginRestrictions::kSameOriginOnly);
}
GURL ManifestParser::ParseScope(const base::DictionaryValue& dictionary,
const GURL& start_url) {
- GURL scope = ParseURL(dictionary, "scope", manifest_url_);
- if (!scope.is_valid()) {
- return GURL();
- }
-
- if (scope.GetOrigin() != document_url_.GetOrigin()) {
- AddErrorInfo("property 'scope' ignored, should be "
- "same origin as document.");
- return GURL();
- }
-
- // According to the spec, if the start_url cannot be parsed, the document URL
- // should be used as the start URL. If the start_url could not be parsed,
- // check that the document URL is within scope.
- GURL check_in_scope = start_url.is_empty() ? document_url_ : start_url;
- if (check_in_scope.GetOrigin() != scope.GetOrigin() ||
- !base::StartsWith(check_in_scope.path(), scope.path(),
- base::CompareCase::SENSITIVE)) {
- AddErrorInfo(
- "property 'scope' ignored. Start url should be within scope "
- "of scope URL.");
- return GURL();
+ GURL scope = ParseURL(dictionary, "scope", manifest_url_,
+ ParseURLOriginRestrictions::kSameOriginOnly);
+
+ if (!scope.is_empty()) {
+ // According to the spec, if the start_url cannot be parsed, the document
+ // URL should be used as the start URL. If the start_url could not be
+ // parsed, check that the document URL is within scope.
+ GURL check_in_scope = start_url.is_empty() ? document_url_ : start_url;
+ if (check_in_scope.GetOrigin() != scope.GetOrigin() ||
+ !base::StartsWith(check_in_scope.path(), scope.path(),
+ base::CompareCase::SENSITIVE)) {
+ AddErrorInfo(
+ "property 'scope' ignored. Start url should be within scope "
+ "of scope URL.");
+ return GURL();
+ }
}
return scope;
}
@@ -248,7 +251,8 @@ blink::WebScreenOrientationLockType ManifestParser::ParseOrientation(
}
GURL ManifestParser::ParseIconSrc(const base::DictionaryValue& icon) {
- return ParseURL(icon, "src", manifest_url_);
+ return ParseURL(icon, "src", manifest_url_,
+ ParseURLOriginRestrictions::kNoRestrictions);
}
base::string16 ManifestParser::ParseIconType(
@@ -371,7 +375,8 @@ base::NullableString16 ManifestParser::ParseRelatedApplicationPlatform(
GURL ManifestParser::ParseRelatedApplicationURL(
const base::DictionaryValue& application) {
- return ParseURL(application, "url", manifest_url_);
+ return ParseURL(application, "url", manifest_url_,
+ ParseURLOriginRestrictions::kNoRestrictions);
}
base::NullableString16 ManifestParser::ParseRelatedApplicationId(
@@ -439,6 +444,12 @@ int64_t ManifestParser::ParseBackgroundColor(
return ParseColor(dictionary, "background_color");
}
+GURL ManifestParser::ParseSplashScreenURL(
+ const base::DictionaryValue& dictionary) {
+ return ParseURL(dictionary, "splash_screen_url", manifest_url_,
+ ParseURLOriginRestrictions::kSameOriginOnly);
+}
+
base::NullableString16 ManifestParser::ParseGCMSenderID(
const base::DictionaryValue& dictionary) {
return ParseString(dictionary, "gcm_sender_id", Trim);
@@ -448,7 +459,8 @@ void ManifestParser::AddErrorInfo(const std::string& error_msg,
bool critical,
int error_line,
int error_column) {
- errors_.push_back({error_msg, critical, error_line, error_column});
+ errors_.push_back(
+ {base::in_place, error_msg, critical, error_line, error_column});
}
} // namespace content
diff --git a/chromium/content/renderer/manifest/manifest_parser.h b/chromium/content/renderer/manifest/manifest_parser.h
index 0dfb1882409..30972b9086c 100644
--- a/chromium/content/renderer/manifest/manifest_parser.h
+++ b/chromium/content/renderer/manifest/manifest_parser.h
@@ -15,7 +15,7 @@
#include "base/strings/string_piece.h"
#include "content/common/content_export.h"
#include "content/public/common/manifest.h"
-#include "content/renderer/manifest/manifest_debug_info.h"
+#include "third_party/WebKit/public/platform/modules/manifest/manifest.mojom.h"
class GURL;
@@ -42,7 +42,7 @@ class CONTENT_EXPORT ManifestParser {
const Manifest& manifest() const;
bool failed() const;
- void TakeErrors(std::vector<ManifestDebugInfo::Error>* errors);
+ void TakeErrors(std::vector<blink::mojom::ManifestErrorPtr>* errors);
private:
// Used to indicate whether to strip whitespace when parsing a string.
@@ -51,6 +51,12 @@ class CONTENT_EXPORT ManifestParser {
NoTrim
};
+ // Indicate whether a parsed URL should be restricted to document origin.
+ enum class ParseURLOriginRestrictions {
+ kNoRestrictions = 0,
+ kSameOriginOnly,
+ };
+
// Helper function to parse booleans present on a given |dictionary| in a
// given field identified by its |key|.
// Returns the parsed boolean if any, or |default_value| if parsing failed.
@@ -74,11 +80,14 @@ class CONTENT_EXPORT ManifestParser {
// Helper function to parse URLs present on a given |dictionary| in a given
// field identified by its |key|. The URL is first parsed as a string then
- // resolved using |base_url|.
- // Returns a GURL. If the parsing failed, the GURL will not be valid.
+ // resolved using |base_url|. |enforce_document_origin| specified whether to
+ // enforce matching of the document's and parsed URL's origins.
+ // Returns a GURL. If the parsing failed or origin matching was enforced but
+ // not present, the returned GURL will be empty.
GURL ParseURL(const base::DictionaryValue& dictionary,
const std::string& key,
- const GURL& base_url);
+ const GURL& base_url,
+ ParseURLOriginRestrictions origin_restriction);
// Parses the 'name' field of the manifest, as defined in:
// https://w3c.github.io/manifest/#dfn-steps-for-processing-the-name-member
@@ -204,6 +213,10 @@ class CONTENT_EXPORT ManifestParser {
// Manifest::kInvalidOrMissingColor if the parsing failed.
int64_t ParseBackgroundColor(const base::DictionaryValue& dictionary);
+ // Parses the 'splash_screen_url' field of the manifest.
+ // Returns the parsed GURL if any, an empty GURL if the parsing failed.
+ GURL ParseSplashScreenURL(const base::DictionaryValue& dictionary);
+
// Parses the 'gcm_sender_id' field of the manifest.
// This is a proprietary extension of the Web Manifest specification.
// Returns the parsed string if any, a null string if the parsing failed.
@@ -221,7 +234,7 @@ class CONTENT_EXPORT ManifestParser {
bool failed_;
Manifest manifest_;
- std::vector<ManifestDebugInfo::Error> errors_;
+ std::vector<blink::mojom::ManifestErrorPtr> errors_;
DISALLOW_COPY_AND_ASSIGN(ManifestParser);
};
diff --git a/chromium/content/renderer/manifest/manifest_parser_unittest.cc b/chromium/content/renderer/manifest/manifest_parser_unittest.cc
index f27d82abe9f..df2da1014f2 100644
--- a/chromium/content/renderer/manifest/manifest_parser_unittest.cc
+++ b/chromium/content/renderer/manifest/manifest_parser_unittest.cc
@@ -34,12 +34,12 @@ class ManifestParserTest : public testing::Test {
const GURL& document_url) {
ManifestParser parser(data, manifest_url, document_url);
parser.Parse();
- std::vector<ManifestDebugInfo::Error> errors;
+ std::vector<blink::mojom::ManifestErrorPtr> errors;
parser.TakeErrors(&errors);
errors_.clear();
- for (const auto& error : errors)
- errors_.push_back(error.message);
+ for (auto& error : errors)
+ errors_.push_back(std::move(error->message));
return parser.manifest();
}
@@ -76,7 +76,7 @@ TEST_F(ManifestParserTest, CrashTest) {
GURL url("http://example.com");
ManifestParser parser(json, url, url);
parser.Parse();
- std::vector<ManifestDebugInfo::Error> errors;
+ std::vector<blink::mojom::ManifestErrorPtr> errors;
parser.TakeErrors(&errors);
// .Parse() should have been call without crashing and succeeded.
@@ -101,6 +101,7 @@ TEST_F(ManifestParserTest, EmptyStringNull) {
ASSERT_EQ(manifest.orientation, blink::kWebScreenOrientationLockDefault);
ASSERT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
ASSERT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
+ ASSERT_TRUE(manifest.splash_screen_url.is_empty());
ASSERT_TRUE(manifest.gcm_sender_id.is_null());
ASSERT_TRUE(manifest.scope.is_empty());
}
@@ -120,6 +121,7 @@ TEST_F(ManifestParserTest, ValidNoContentParses) {
ASSERT_EQ(manifest.orientation, blink::kWebScreenOrientationLockDefault);
ASSERT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
ASSERT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
+ ASSERT_TRUE(manifest.splash_screen_url.is_empty());
ASSERT_TRUE(manifest.gcm_sender_id.is_null());
ASSERT_TRUE(manifest.scope.is_empty());
}
@@ -1136,6 +1138,18 @@ TEST_F(ManifestParserTest, RelatedApplicationsParseRules) {
EXPECT_EQ(0u, GetErrorCount());
}
+ // Application with an invalid url.
+ {
+ Manifest manifest = ParseManifest(
+ "{ \"related_applications\": ["
+ "{\"platform\": \"play\", \"url\": \"http://www.foo.com:co&uk\"}]}");
+ EXPECT_TRUE(manifest.IsEmpty());
+ EXPECT_EQ(2u, GetErrorCount());
+ EXPECT_EQ("property 'url' ignored, URL is invalid.", errors()[0]);
+ EXPECT_EQ("one of 'url' or 'id' is required, related application ignored.",
+ errors()[1]);
+ }
+
// Valid application, with id.
{
Manifest manifest = ParseManifest(
@@ -1573,6 +1587,90 @@ TEST_F(ManifestParserTest, BackgroundColorParserRules) {
}
}
+TEST_F(ManifestParserTest, SplashScreenUrlParseRules) {
+ // Smoke test.
+ {
+ Manifest manifest =
+ ParseManifest("{ \"splash_screen_url\": \"splash.html\" }");
+ ASSERT_EQ(manifest.splash_screen_url.spec(),
+ default_document_url.Resolve("splash.html").spec());
+ ASSERT_FALSE(manifest.IsEmpty());
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Whitespaces.
+ {
+ Manifest manifest =
+ ParseManifest("{ \"splash_screen_url\": \" splash.html\" }");
+ ASSERT_EQ(manifest.splash_screen_url.spec(),
+ default_document_url.Resolve("splash.html").spec());
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Don't parse if property isn't a string.
+ {
+ Manifest manifest = ParseManifest("{ \"splash_screen_url\": {} }");
+ ASSERT_TRUE(manifest.splash_screen_url.is_empty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'splash_screen_url' ignored, type string expected.",
+ errors()[0]);
+ }
+
+ // Don't parse if property isn't a string.
+ {
+ Manifest manifest = ParseManifest("{ \"splash_screen_url\": 42 }");
+ ASSERT_TRUE(manifest.splash_screen_url.is_empty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'splash_screen_url' ignored, type string expected.",
+ errors()[0]);
+ }
+
+ // Don't parse if property isn't a valid URL.
+ {
+ Manifest manifest =
+ ParseManifest("{ \"splash_screen_url\": \"http://www.google.ca:a\" }");
+ ASSERT_TRUE(manifest.splash_screen_url.is_empty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'splash_screen_url' ignored, URL is invalid.",
+ errors()[0]);
+ }
+
+ // Absolute splash_screen_url, same origin with document.
+ {
+ Manifest manifest = ParseManifestWithURLs(
+ "{ \"splash_screen_url\": \"http://foo.com/splash.html\" }",
+ GURL("http://foo.com/manifest.json"),
+ GURL("http://foo.com/index.html"));
+ ASSERT_EQ(manifest.splash_screen_url.spec(), "http://foo.com/splash.html");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Absolute splash_screen_url, cross origin with document.
+ {
+ Manifest manifest = ParseManifestWithURLs(
+ "{ \"splash_screen_url\": \"http://bar.com/splash.html\" }",
+ GURL("http://foo.com/manifest.json"),
+ GURL("http://foo.com/index.html"));
+ ASSERT_TRUE(manifest.splash_screen_url.is_empty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ(
+ "property 'splash_screen_url' ignored, should "
+ "be same origin as document.",
+ errors()[0]);
+ }
+
+ // Resolving has to happen based on the manifest_url.
+ {
+ Manifest manifest =
+ ParseManifestWithURLs("{ \"splash_screen_url\": \"splash.html\" }",
+ GURL("http://foo.com/splashy/manifest.json"),
+ GURL("http://foo.com/index.html"));
+ ASSERT_EQ(manifest.splash_screen_url.spec(),
+ "http://foo.com/splashy/splash.html");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+}
+
TEST_F(ManifestParserTest, GCMSenderIDParseRules) {
// Smoke test.
{
diff --git a/chromium/content/renderer/mash_util.cc b/chromium/content/renderer/mash_util.cc
index 23c587730a0..4c3b525d508 100644
--- a/chromium/content/renderer/mash_util.cc
+++ b/chromium/content/renderer/mash_util.cc
@@ -5,13 +5,17 @@
#include "content/renderer/mash_util.h"
#include "base/command_line.h"
-#include "content/public/common/content_switches.h"
+#include "ui/base/ui_base_switches.h"
namespace content {
-bool IsRunningInMash() {
+bool IsRunningWithMus() {
+#if BUILDFLAG(ENABLE_MUS)
const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
- return cmdline->HasSwitch(switches::kIsRunningInMash);
+ return cmdline->HasSwitch(switches::kMus);
+#else
+ return false;
+#endif
}
} // namespace content
diff --git a/chromium/content/renderer/mash_util.h b/chromium/content/renderer/mash_util.h
index 9091cce43b8..3933b739a59 100644
--- a/chromium/content/renderer/mash_util.h
+++ b/chromium/content/renderer/mash_util.h
@@ -7,7 +7,7 @@
namespace content {
-bool IsRunningInMash();
+bool IsRunningWithMus();
} // namespace content
diff --git a/chromium/content/renderer/media/OWNERS b/chromium/content/renderer/media/OWNERS
index f57633a09d5..dac18fd5a24 100644
--- a/chromium/content/renderer/media/OWNERS
+++ b/chromium/content/renderer/media/OWNERS
@@ -1,5 +1,4 @@
file://media/OWNERS
-mcasas@chromium.org
miu@chromium.org
# WebRTC OWNERS.
diff --git a/chromium/content/renderer/media/aec_dump_message_filter.cc b/chromium/content/renderer/media/aec_dump_message_filter.cc
index fe63cb660d3..f423391bbba 100644
--- a/chromium/content/renderer/media/aec_dump_message_filter.cc
+++ b/chromium/content/renderer/media/aec_dump_message_filter.cc
@@ -16,12 +16,12 @@ const int kInvalidDelegateId = -1;
namespace content {
-AecDumpMessageFilter* AecDumpMessageFilter::g_filter = NULL;
+AecDumpMessageFilter* AecDumpMessageFilter::g_filter = nullptr;
AecDumpMessageFilter::AecDumpMessageFilter(
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner)
- : sender_(NULL),
+ : sender_(nullptr),
delegate_id_counter_(1),
io_task_runner_(io_task_runner),
main_task_runner_(main_task_runner) {
@@ -31,7 +31,7 @@ AecDumpMessageFilter::AecDumpMessageFilter(
AecDumpMessageFilter::~AecDumpMessageFilter() {
DCHECK_EQ(g_filter, this);
- g_filter = NULL;
+ g_filter = nullptr;
}
// static
@@ -48,10 +48,6 @@ void AecDumpMessageFilter::AddDelegate(
int id = delegate_id_counter_++;
delegates_[id] = delegate;
- if (override_aec3_) {
- delegate->OnAec3Enable(*override_aec3_);
- }
-
io_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&AecDumpMessageFilter::RegisterAecDumpConsumer, this, id));
@@ -72,6 +68,11 @@ void AecDumpMessageFilter::RemoveDelegate(
id));
}
+base::Optional<bool> AecDumpMessageFilter::GetOverrideAec3() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return override_aec3_;
+}
+
void AecDumpMessageFilter::Send(IPC::Message* message) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
if (sender_)
@@ -115,7 +116,7 @@ void AecDumpMessageFilter::OnFilterRemoved() {
void AecDumpMessageFilter::OnChannelClosing() {
DCHECK(io_task_runner_->BelongsToCurrentThread());
- sender_ = NULL;
+ sender_ = nullptr;
main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&AecDumpMessageFilter::DoChannelClosingOnDelegates, this));
@@ -136,11 +137,11 @@ void AecDumpMessageFilter::OnDisableAecDump() {
FROM_HERE, base::BindOnce(&AecDumpMessageFilter::DoDisableAecDump, this));
}
-void AecDumpMessageFilter::OnEnableAec3(int id, bool enable) {
+void AecDumpMessageFilter::OnEnableAec3(bool enable) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
main_task_runner_->PostTask(
FROM_HERE,
- base::BindOnce(&AecDumpMessageFilter::DoEnableAec3, this, id, enable));
+ base::BindOnce(&AecDumpMessageFilter::DoEnableAec3, this, enable));
}
void AecDumpMessageFilter::DoEnableAecDump(
@@ -186,13 +187,16 @@ int AecDumpMessageFilter::GetIdForDelegate(
return kInvalidDelegateId;
}
-void AecDumpMessageFilter::DoEnableAec3(int id, bool enable) {
+void AecDumpMessageFilter::DoEnableAec3(bool enable) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- DelegateMap::iterator it = delegates_.find(id);
- if (it != delegates_.end()) {
- it->second->OnAec3Enable(enable);
- }
+ // TODO(grunell): Remove enabling on delegates when clients have changed to
+ // enable before creating streams.
+ for (auto delegate : delegates_)
+ delegate.second->OnAec3Enable(enable);
override_aec3_ = enable;
+ io_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&AecDumpMessageFilter::Send, this,
+ new AudioProcessingMsg_Aec3Enabled()));
}
} // namespace content
diff --git a/chromium/content/renderer/media/aec_dump_message_filter.h b/chromium/content/renderer/media/aec_dump_message_filter.h
index 4bb39cf1eea..3e64108cd63 100644
--- a/chromium/content/renderer/media/aec_dump_message_filter.h
+++ b/chromium/content/renderer/media/aec_dump_message_filter.h
@@ -8,6 +8,7 @@
#include <memory>
#include "base/macros.h"
+#include "base/optional.h"
#include "content/common/content_export.h"
#include "content/renderer/render_thread_impl.h"
#include "ipc/ipc_platform_file.h"
@@ -40,10 +41,13 @@ class CONTENT_EXPORT AecDumpMessageFilter : public IPC::MessageFilter {
// Getter for the one AecDumpMessageFilter object.
static scoped_refptr<AecDumpMessageFilter> Get();
- // Adds a delegate that receives the enable and disable notifications.
+ // Adds a delegate that receives the enable and disable notifications. Must be
+ // called on the main task runner (|main_task_runner| in constructor). All
+ // calls on |delegate| are done on the main task runner.
void AddDelegate(AecDumpMessageFilter::AecDumpDelegate* delegate);
- // Removes a delegate.
+ // Removes a delegate. Must be called on the main task runner
+ // (|main_task_runner| in constructor).
void RemoveDelegate(AecDumpMessageFilter::AecDumpDelegate* delegate);
// IO task runner associated with this message filter.
@@ -51,6 +55,10 @@ class CONTENT_EXPORT AecDumpMessageFilter : public IPC::MessageFilter {
return io_task_runner_;
}
+ // Returns the AEC3 setting. Must be called on the main task runner
+ // (|main_task_runner| in constructor).
+ base::Optional<bool> GetOverrideAec3() const;
+
protected:
~AecDumpMessageFilter() override;
@@ -75,14 +83,14 @@ class CONTENT_EXPORT AecDumpMessageFilter : public IPC::MessageFilter {
// Accessed on |io_task_runner_|.
void OnEnableAecDump(int id, IPC::PlatformFileForTransit file_handle);
void OnDisableAecDump();
- void OnEnableAec3(int id, bool enable);
+ void OnEnableAec3(bool enable);
// Accessed on |main_task_runner_|.
void DoEnableAecDump(int id, IPC::PlatformFileForTransit file_handle);
void DoDisableAecDump();
void DoChannelClosingOnDelegates();
int GetIdForDelegate(AecDumpMessageFilter::AecDumpDelegate* delegate);
- void DoEnableAec3(int id, bool enable);
+ void DoEnableAec3(bool enable);
// Accessed on |io_task_runner_|.
IPC::Sender* sender_;
diff --git a/chromium/content/renderer/media/android/media_player_renderer_client_factory.cc b/chromium/content/renderer/media/android/media_player_renderer_client_factory.cc
index c9f1d5bb554..3289a72ab3b 100644
--- a/chromium/content/renderer/media/android/media_player_renderer_client_factory.cc
+++ b/chromium/content/renderer/media/android/media_player_renderer_client_factory.cc
@@ -39,7 +39,7 @@ MediaPlayerRendererClientFactory::CreateRenderer(
media::ScopedStreamTextureWrapper stream_texture_wrapper =
get_stream_texture_wrapper_cb_.Run();
- return base::MakeUnique<MediaPlayerRendererClient>(
+ return std::make_unique<MediaPlayerRendererClient>(
media_task_runner, compositor_task_runner_, mojo_renderer,
std::move(stream_texture_wrapper), video_renderer_sink);
}
diff --git a/chromium/content/renderer/media/android/stream_texture_factory.cc b/chromium/content/renderer/media/android/stream_texture_factory.cc
index 395455cd523..fd7d4c67839 100644
--- a/chromium/content/renderer/media/android/stream_texture_factory.cc
+++ b/chromium/content/renderer/media/android/stream_texture_factory.cc
@@ -103,7 +103,7 @@ ScopedStreamTextureProxy StreamTextureFactory::CreateProxy(
if (!route_id)
return ScopedStreamTextureProxy();
return ScopedStreamTextureProxy(new StreamTextureProxy(
- base::MakeUnique<StreamTextureHost>(channel_, route_id)));
+ std::make_unique<StreamTextureHost>(channel_, route_id)));
}
unsigned StreamTextureFactory::CreateStreamTexture(
diff --git a/chromium/content/renderer/media/apply_constraints_processor.cc b/chromium/content/renderer/media/apply_constraints_processor.cc
index 38d166dc1a5..9b8657db5ba 100644
--- a/chromium/content/renderer/media/apply_constraints_processor.cc
+++ b/chromium/content/renderer/media/apply_constraints_processor.cc
@@ -25,22 +25,22 @@
namespace content {
namespace {
-::mojom::FacingMode GetMojoFacingMode(
+blink::mojom::FacingMode GetMojoFacingMode(
const blink::WebMediaStreamTrack::FacingMode facing_mode) {
switch (facing_mode) {
case blink::WebMediaStreamTrack::FacingMode::kUser:
- return ::mojom::FacingMode::USER;
+ return blink::mojom::FacingMode::USER;
case blink::WebMediaStreamTrack::FacingMode::kEnvironment:
- return ::mojom::FacingMode::ENVIRONMENT;
+ return blink::mojom::FacingMode::ENVIRONMENT;
case blink::WebMediaStreamTrack::FacingMode::kLeft:
- return ::mojom::FacingMode::LEFT;
+ return blink::mojom::FacingMode::LEFT;
case blink::WebMediaStreamTrack::FacingMode::kRight:
- return ::mojom::FacingMode::RIGHT;
+ return blink::mojom::FacingMode::RIGHT;
case blink::WebMediaStreamTrack::FacingMode::kNone:
- return ::mojom::FacingMode::NONE;
+ return blink::mojom::FacingMode::NONE;
}
NOTREACHED();
- return ::mojom::FacingMode::NONE;
+ return blink::mojom::FacingMode::NONE;
}
void RequestFailed(blink::WebApplyConstraintsRequest request,
@@ -238,8 +238,8 @@ VideoCaptureSettings ApplyConstraintsProcessor::SelectVideoSettings(
DCHECK(request_completed_cb_);
DCHECK_GT(formats.size(), 0U);
- ::mojom::VideoInputDeviceCapabilitiesPtr device_capabilities =
- ::mojom::VideoInputDeviceCapabilities::New();
+ blink::mojom::VideoInputDeviceCapabilitiesPtr device_capabilities =
+ blink::mojom::VideoInputDeviceCapabilities::New();
device_capabilities->device_id =
current_request_.Track().Source().Id().Ascii();
device_capabilities->facing_mode =
@@ -340,7 +340,7 @@ void ApplyConstraintsProcessor::CleanupRequest(
video_source_ = nullptr;
}
-const ::mojom::MediaDevicesDispatcherHostPtr&
+const blink::mojom::MediaDevicesDispatcherHostPtr&
ApplyConstraintsProcessor::GetMediaDevicesDispatcher() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return media_devices_dispatcher_cb_.Run();
diff --git a/chromium/content/renderer/media/apply_constraints_processor.h b/chromium/content/renderer/media/apply_constraints_processor.h
index 6ad3b285b22..2a19299579d 100644
--- a/chromium/content/renderer/media/apply_constraints_processor.h
+++ b/chromium/content/renderer/media/apply_constraints_processor.h
@@ -10,9 +10,9 @@
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "content/common/content_export.h"
-#include "content/common/media/media_devices.mojom.h"
#include "content/renderer/media/media_stream_constraints_util.h"
#include "media/capture/video_capture_types.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
#include "third_party/WebKit/public/web/WebApplyConstraintsRequest.h"
namespace blink {
@@ -30,8 +30,8 @@ class MediaStreamVideoTrack;
// render thread. There should be only one ApplyConstraintsProcessor per frame.
class CONTENT_EXPORT ApplyConstraintsProcessor {
public:
- using MediaDevicesDispatcherCallback =
- base::RepeatingCallback<const ::mojom::MediaDevicesDispatcherHostPtr&()>;
+ using MediaDevicesDispatcherCallback = base::RepeatingCallback<
+ const blink::mojom::MediaDevicesDispatcherHostPtr&()>;
ApplyConstraintsProcessor(
MediaDevicesDispatcherCallback media_devices_dispatcher_cb);
~ApplyConstraintsProcessor();
@@ -65,7 +65,8 @@ class CONTENT_EXPORT ApplyConstraintsProcessor {
void ApplyConstraintsFailed(const char* failed_constraint_name);
void CannotApplyConstraints(const blink::WebString& message);
void CleanupRequest(base::OnceClosure web_request_callback);
- const ::mojom::MediaDevicesDispatcherHostPtr& GetMediaDevicesDispatcher();
+ const blink::mojom::MediaDevicesDispatcherHostPtr&
+ GetMediaDevicesDispatcher();
// ApplyConstraints requests are processed sequentially. |current_request_|
// contains the request currently being processed, if any.
diff --git a/chromium/content/renderer/media/audio_device_factory.cc b/chromium/content/renderer/media/audio_device_factory.cc
index 7f72d259d07..8e9aac24fab 100644
--- a/chromium/content/renderer/media/audio_device_factory.cc
+++ b/chromium/content/renderer/media/audio_device_factory.cc
@@ -23,7 +23,7 @@
namespace content {
// static
-AudioDeviceFactory* AudioDeviceFactory::factory_ = NULL;
+AudioDeviceFactory* AudioDeviceFactory::factory_ = nullptr;
namespace {
#if defined(OS_WIN) || defined(OS_MACOSX) || \
@@ -199,7 +199,7 @@ AudioDeviceFactory::AudioDeviceFactory() {
}
AudioDeviceFactory::~AudioDeviceFactory() {
- factory_ = NULL;
+ factory_ = nullptr;
}
// static
diff --git a/chromium/content/renderer/media/audio_input_message_filter.cc b/chromium/content/renderer/media/audio_input_message_filter.cc
index a67f1655b1e..7ddca260041 100644
--- a/chromium/content/renderer/media/audio_input_message_filter.cc
+++ b/chromium/content/renderer/media/audio_input_message_filter.cc
@@ -51,18 +51,18 @@ class AudioInputMessageFilter::AudioInputIPCImpl : public media::AudioInputIPC {
int stream_id_;
};
-AudioInputMessageFilter* AudioInputMessageFilter::g_filter = NULL;
+AudioInputMessageFilter* AudioInputMessageFilter::g_filter = nullptr;
AudioInputMessageFilter::AudioInputMessageFilter(
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
- : sender_(NULL), io_task_runner_(io_task_runner) {
+ : sender_(nullptr), io_task_runner_(io_task_runner) {
DCHECK(!g_filter);
g_filter = this;
}
AudioInputMessageFilter::~AudioInputMessageFilter() {
DCHECK_EQ(g_filter, this);
- g_filter = NULL;
+ g_filter = nullptr;
}
// static
@@ -109,7 +109,7 @@ void AudioInputMessageFilter::OnFilterRemoved() {
void AudioInputMessageFilter::OnChannelClosing() {
DCHECK(io_task_runner_->BelongsToCurrentThread());
- sender_ = NULL;
+ sender_ = nullptr;
DLOG_IF(WARNING, !delegates_.IsEmpty())
<< "Not all audio devices have been closed.";
diff --git a/chromium/content/renderer/media/audio_ipc_factory.cc b/chromium/content/renderer/media/audio_ipc_factory.cc
index 0f02785efec..5ab138aabfa 100644
--- a/chromium/content/renderer/media/audio_ipc_factory.cc
+++ b/chromium/content/renderer/media/audio_ipc_factory.cc
@@ -37,7 +37,7 @@ std::unique_ptr<media::AudioOutputIPC> AudioIPCFactory::CreateAudioOutputIPC(
int frame_id) const {
if (UsingMojoFactories()) {
// Unretained is safe due to the contract at the top of the header file.
- return base::MakeUnique<MojoAudioOutputIPC>(base::BindRepeating(
+ return std::make_unique<MojoAudioOutputIPC>(base::BindRepeating(
&AudioIPCFactory::GetRemoteFactory, base::Unretained(this), frame_id));
}
return audio_message_filter_->CreateAudioOutputIPC(frame_id);
diff --git a/chromium/content/renderer/media/audio_ipc_factory_unittest.cc b/chromium/content/renderer/media/audio_ipc_factory_unittest.cc
index a99ae277821..88b1773b437 100644
--- a/chromium/content/renderer/media/audio_ipc_factory_unittest.cc
+++ b/chromium/content/renderer/media/audio_ipc_factory_unittest.cc
@@ -28,7 +28,7 @@ namespace {
const int kRenderFrameId = 0;
std::unique_ptr<base::Thread> MakeIOThread() {
- auto io_thread = base::MakeUnique<base::Thread>("test IO thread");
+ auto io_thread = std::make_unique<base::Thread>("test IO thread");
base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0);
CHECK(io_thread->StartWithOptions(thread_options));
return io_thread;
diff --git a/chromium/content/renderer/media/audio_message_filter.cc b/chromium/content/renderer/media/audio_message_filter.cc
index abe24b04313..b1f2106e781 100644
--- a/chromium/content/renderer/media/audio_message_filter.cc
+++ b/chromium/content/renderer/media/audio_message_filter.cc
@@ -43,18 +43,18 @@ class AudioMessageFilter::AudioOutputIPCImpl : public media::AudioOutputIPC {
bool stream_created_;
};
-AudioMessageFilter* AudioMessageFilter::g_filter = NULL;
+AudioMessageFilter* AudioMessageFilter::g_filter = nullptr;
AudioMessageFilter::AudioMessageFilter(
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
- : sender_(NULL), io_task_runner_(io_task_runner) {
+ : sender_(nullptr), io_task_runner_(io_task_runner) {
DCHECK(!g_filter);
g_filter = this;
}
AudioMessageFilter::~AudioMessageFilter() {
DCHECK_EQ(g_filter, this);
- g_filter = NULL;
+ g_filter = nullptr;
}
// static
@@ -168,7 +168,7 @@ void AudioMessageFilter::OnFilterRemoved() {
void AudioMessageFilter::OnChannelClosing() {
DCHECK(io_task_runner_->BelongsToCurrentThread());
- sender_ = NULL;
+ sender_ = nullptr;
DLOG_IF(WARNING, !delegates_.IsEmpty())
<< "Not all audio devices have been closed.";
diff --git a/chromium/content/renderer/media/audio_message_filter_unittest.cc b/chromium/content/renderer/media/audio_message_filter_unittest.cc
index 1950724293b..f38c1ec47a5 100644
--- a/chromium/content/renderer/media/audio_message_filter_unittest.cc
+++ b/chromium/content/renderer/media/audio_message_filter_unittest.cc
@@ -143,7 +143,7 @@ TEST(AudioMessageFilterTest, Basic) {
delegate.Reset();
ipc->CloseStream();
- EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(NULL),
+ EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(nullptr),
filter->delegates_.Lookup(kStreamId));
}
@@ -185,9 +185,9 @@ TEST(AudioMessageFilterTest, Delegates) {
ipc1->CloseStream();
ipc2->CloseStream();
- EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(NULL),
+ EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(nullptr),
filter->delegates_.Lookup(kStreamId1));
- EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(NULL),
+ EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(nullptr),
filter->delegates_.Lookup(kStreamId2));
}
diff --git a/chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc b/chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
index 5672d522621..86c0c38c70c 100644
--- a/chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
+++ b/chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
@@ -112,7 +112,7 @@ class AudioRendererMixerManagerTest : public testing::Test {
mock_sink_matched_device_(
new media::MockAudioRendererSink(kMatchedDeviceId,
media::OUTPUT_DEVICE_STATUS_OK)),
- kSecurityOrigin2(GURL("http://localhost")) {}
+ kSecurityOrigin2(url::Origin::Create(GURL("http://localhost"))) {}
media::AudioRendererMixer* GetMixer(
int source_render_frame_id,
diff --git a/chromium/content/renderer/media/audio_repetition_detector.cc b/chromium/content/renderer/media/audio_repetition_detector.cc
index ced9a7fdd07..cd39a07b93c 100644
--- a/chromium/content/renderer/media/audio_repetition_detector.cc
+++ b/chromium/content/renderer/media/audio_repetition_detector.cc
@@ -41,7 +41,7 @@ AudioRepetitionDetector::AudioRepetitionDetector(
max_look_back_ms_ = temp.back();
for (int look_back : temp)
- states_.push_back(base::MakeUnique<State>(look_back));
+ states_.push_back(std::make_unique<State>(look_back));
}
AudioRepetitionDetector::~AudioRepetitionDetector() {
diff --git a/chromium/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc b/chromium/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc
index 5cad0ab04b5..97b5d423c1c 100644
--- a/chromium/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc
+++ b/chromium/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc
@@ -85,7 +85,7 @@ PepperCdmWrapperImpl::PepperCdmWrapperImpl(
PepperCdmWrapperImpl::~PepperCdmWrapperImpl() {
// Destroy the nested objects in reverse order.
- plugin_instance_ = NULL;
+ plugin_instance_ = nullptr;
helper_plugin_.reset();
}
diff --git a/chromium/content/renderer/media/cdm/ppapi_decryptor.cc b/chromium/content/renderer/media/cdm/ppapi_decryptor.cc
index 7faec01c400..ffcb3e964ba 100644
--- a/chromium/content/renderer/media/cdm/ppapi_decryptor.cc
+++ b/chromium/content/renderer/media/cdm/ppapi_decryptor.cc
@@ -269,7 +269,7 @@ void PpapiDecryptor::Decrypt(
DVLOG(3) << __func__ << " - stream_type: " << stream_type;
if (!CdmDelegate() ||
!CdmDelegate()->Decrypt(stream_type, encrypted, decrypt_cb)) {
- decrypt_cb.Run(kError, NULL);
+ decrypt_cb.Run(kError, nullptr);
}
}
@@ -366,7 +366,7 @@ void PpapiDecryptor::DecryptAndDecodeVideo(
DVLOG(3) << __func__;
if (!CdmDelegate() ||
!CdmDelegate()->DecryptAndDecodeVideo(encrypted, video_decode_cb)) {
- video_decode_cb.Run(kError, NULL);
+ video_decode_cb.Run(kError, nullptr);
}
}
@@ -465,7 +465,8 @@ void PpapiDecryptor::OnFatalPluginError() {
ContentDecryptorDelegate* PpapiDecryptor::CdmDelegate() {
DCHECK(render_task_runner_->BelongsToCurrentThread());
- return (pepper_cdm_wrapper_) ? pepper_cdm_wrapper_->GetCdmDelegate() : NULL;
+ return (pepper_cdm_wrapper_) ? pepper_cdm_wrapper_->GetCdmDelegate()
+ : nullptr;
}
} // namespace content
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 e0ead2c99c8..27f25294955 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
@@ -215,7 +215,7 @@ bool GpuVideoAcceleratorFactoriesImpl::CreateTextures(
gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (texture_target == GL_TEXTURE_2D) {
gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(),
- 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
gles2->GenMailboxCHROMIUM(texture_mailboxes->at(i).name);
gles2->ProduceTextureCHROMIUM(texture_target,
@@ -333,7 +333,7 @@ std::unique_ptr<media::GpuVideoAcceleratorFactories::ScopedGLContextLock>
GpuVideoAcceleratorFactoriesImpl::GetGLContextLock() {
if (CheckContextLost())
return nullptr;
- return base::MakeUnique<ScopedGLContextLockImpl>(context_provider_);
+ return std::make_unique<ScopedGLContextLockImpl>(context_provider_);
}
std::unique_ptr<base::SharedMemory>
diff --git a/chromium/content/renderer/media/gpu/rtc_video_encoder.cc b/chromium/content/renderer/media/gpu/rtc_video_encoder.cc
index 7cb385f152e..8a2a2d3fb96 100644
--- a/chromium/content/renderer/media/gpu/rtc_video_encoder.cc
+++ b/chromium/content/renderer/media/gpu/rtc_video_encoder.cc
@@ -65,23 +65,14 @@ webrtc::VideoCodecType ProfileToWebRtcVideoCodecType(
// Returns true if successful.
bool GetRTPFragmentationHeaderH264(webrtc::RTPFragmentationHeader* header,
const uint8_t* data, uint32_t length) {
- media::H264Parser parser;
- parser.SetStream(data, length);
-
std::vector<media::H264NALU> nalu_vector;
- while (true) {
- media::H264NALU nalu;
- const media::H264Parser::Result result = parser.AdvanceToNextNALU(&nalu);
- if (result == media::H264Parser::kOk) {
- nalu_vector.push_back(nalu);
- } else if (result == media::H264Parser::kEOStream) {
- break;
- } else {
- DLOG(ERROR) << "Unexpected H264 parser result";
- return false;
- }
+ if (!media::H264Parser::ParseNALUs(data, length, &nalu_vector)) {
+ // H264Parser::ParseNALUs() has logged the errors already.
+ return false;
}
+ // TODO(zijiehe): Find a right place to share the following logic between
+ // //content and //remoting.
header->VerifyAndAllocateFragmentationHeader(nalu_vector.size());
for (size_t i = 0; i < nalu_vector.size(); ++i) {
header->fragmentationOffset[i] = nalu_vector[i].data - data;
@@ -610,7 +601,7 @@ void RTCVideoEncoder::Impl::EncodeOneFrame() {
// input_next_frame_* state before we hand off the VideoFrame to the VEA.
const webrtc::VideoFrame* next_frame = input_next_frame_;
const bool next_frame_keyframe = input_next_frame_keyframe_;
- input_next_frame_ = NULL;
+ input_next_frame_ = nullptr;
input_next_frame_keyframe_ = false;
if (!video_encoder_) {
@@ -709,8 +700,8 @@ void RTCVideoEncoder::Impl::SignalAsyncWaiter(int32_t retval) {
DCHECK(thread_checker_.CalledOnValidThread());
*async_retval_ = retval;
async_waiter_->Signal();
- async_retval_ = NULL;
- async_waiter_ = NULL;
+ async_retval_ = nullptr;
+ async_waiter_ = nullptr;
}
bool RTCVideoEncoder::Impl::IsBitrateTooHigh(uint32_t bitrate) {
@@ -914,7 +905,7 @@ int32_t RTCVideoEncoder::Release() {
FROM_HERE,
base::BindOnce(&RTCVideoEncoder::Impl::Destroy, impl_, &release_waiter));
release_waiter.Wait();
- impl_ = NULL;
+ impl_ = nullptr;
return WEBRTC_VIDEO_CODEC_OK;
}
diff --git a/chromium/content/renderer/media/gpu/rtc_video_encoder_unittest.cc b/chromium/content/renderer/media/gpu/rtc_video_encoder_unittest.cc
index dc3f4b4cf09..31bccb04fd3 100644
--- a/chromium/content/renderer/media/gpu/rtc_video_encoder_unittest.cc
+++ b/chromium/content/renderer/media/gpu/rtc_video_encoder_unittest.cc
@@ -125,7 +125,7 @@ class RTCVideoEncoderTest
ADD_FAILURE() << "Unexpected codec type: " << codec_type;
media_profile = media::VIDEO_CODEC_PROFILE_UNKNOWN;
}
- rtc_encoder_ = base::MakeUnique<RTCVideoEncoder>(media_profile,
+ rtc_encoder_ = std::make_unique<RTCVideoEncoder>(media_profile,
mock_gpu_factories_.get());
}
@@ -292,15 +292,7 @@ TEST_F(RTCVideoEncoderTest, EncodeScaledFrame) {
rtc_encoder_->Encode(rtc_frame, nullptr, &frame_types));
}
-// We cannot run this test on Android because AndroidVideoEncodeAccelerator does
-// not preserve timestamps.
-#if defined(OS_ANDROID)
-#define MAYBE_PreserveTimestamps DISABLED_PreserveTimestamps
-#else
-#define MAYBE_PreserveTimestamps PreserveTimestamps
-#endif // defined(OS_ANDROID)
-
-TEST_F(RTCVideoEncoderTest, MAYBE_PreserveTimestamps) {
+TEST_F(RTCVideoEncoderTest, PreserveTimestamps) {
const webrtc::VideoCodecType codec_type = webrtc::kVideoCodecVP8;
CreateEncoder(codec_type);
webrtc::VideoCodec codec = GetDefaultCodec();
diff --git a/chromium/content/renderer/media/media_devices_event_dispatcher.cc b/chromium/content/renderer/media/media_devices_event_dispatcher.cc
index 8cda5e9cfcd..9c4a323d334 100644
--- a/chromium/content/renderer/media/media_devices_event_dispatcher.cc
+++ b/chromium/content/renderer/media/media_devices_event_dispatcher.cc
@@ -111,11 +111,11 @@ void MediaDevicesEventDispatcher::OnDestruct() {
}
void MediaDevicesEventDispatcher::SetMediaDevicesDispatcherForTesting(
- ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher) {
+ blink::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher) {
media_devices_dispatcher_ = std::move(media_devices_dispatcher);
}
-const ::mojom::MediaDevicesDispatcherHostPtr&
+const blink::mojom::MediaDevicesDispatcherHostPtr&
MediaDevicesEventDispatcher::GetMediaDevicesDispatcher() {
if (!media_devices_dispatcher_) {
render_frame()->GetRemoteInterfaces()->GetInterface(
diff --git a/chromium/content/renderer/media/media_devices_event_dispatcher.h b/chromium/content/renderer/media/media_devices_event_dispatcher.h
index daa3ed6505e..806105d8c4e 100644
--- a/chromium/content/renderer/media/media_devices_event_dispatcher.h
+++ b/chromium/content/renderer/media/media_devices_event_dispatcher.h
@@ -15,9 +15,9 @@
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "content/common/media/media_devices.h"
-#include "content/common/media/media_devices.mojom.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_observer_tracker.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
namespace content {
@@ -80,12 +80,13 @@ class CONTENT_EXPORT MediaDevicesEventDispatcher
void OnDestruct() override;
void SetMediaDevicesDispatcherForTesting(
- ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher);
+ blink::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher);
private:
explicit MediaDevicesEventDispatcher(RenderFrame* render_frame);
- const ::mojom::MediaDevicesDispatcherHostPtr& GetMediaDevicesDispatcher();
+ const blink::mojom::MediaDevicesDispatcherHostPtr&
+ GetMediaDevicesDispatcher();
SubscriptionId current_id_;
@@ -93,7 +94,7 @@ class CONTENT_EXPORT MediaDevicesEventDispatcher
using SubscriptionList = std::vector<Subscription>;
SubscriptionList device_change_subscriptions_[NUM_MEDIA_DEVICE_TYPES];
- ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher_;
+ blink::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher_;
base::ThreadChecker thread_checker_;
diff --git a/chromium/content/renderer/media/media_devices_event_dispatcher_unittest.cc b/chromium/content/renderer/media/media_devices_event_dispatcher_unittest.cc
index 674c55972f4..e3dbe6b0857 100644
--- a/chromium/content/renderer/media/media_devices_event_dispatcher_unittest.cc
+++ b/chromium/content/renderer/media/media_devices_event_dispatcher_unittest.cc
@@ -31,7 +31,7 @@ class MockMediaDevicesEventSubscriber {
};
class MockMediaDevicesDispatcherHost
- : public ::mojom::MediaDevicesDispatcherHost {
+ : public blink::mojom::MediaDevicesDispatcherHost {
public:
MockMediaDevicesDispatcherHost() : binding_(this) {}
@@ -69,14 +69,14 @@ class MockMediaDevicesDispatcherHost
NOTREACHED();
}
- ::mojom::MediaDevicesDispatcherHostPtr CreateInterfacePtrAndBind() {
- ::mojom::MediaDevicesDispatcherHostPtr ptr;
+ blink::mojom::MediaDevicesDispatcherHostPtr CreateInterfacePtrAndBind() {
+ blink::mojom::MediaDevicesDispatcherHostPtr ptr;
binding_.Bind(mojo::MakeRequest(&ptr));
return ptr;
}
private:
- mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_;
+ mojo::Binding<blink::mojom::MediaDevicesDispatcherHost> binding_;
};
class MediaDevicesEventDispatcherTest : public ::testing::Test {
@@ -85,7 +85,7 @@ class MediaDevicesEventDispatcherTest : public ::testing::Test {
void SetUp() override {
event_dispatcher_ = MediaDevicesEventDispatcher::GetForRenderFrame(nullptr);
- ::mojom::MediaDevicesDispatcherHostPtr ptr =
+ blink::mojom::MediaDevicesDispatcherHostPtr ptr =
media_devices_dispatcher_.CreateInterfacePtrAndBind();
event_dispatcher_->SetMediaDevicesDispatcherForTesting(std::move(ptr));
}
diff --git a/chromium/content/renderer/media/media_devices_listener_impl.cc b/chromium/content/renderer/media/media_devices_listener_impl.cc
index 858803645cc..019fbeb7eb7 100644
--- a/chromium/content/renderer/media/media_devices_listener_impl.cc
+++ b/chromium/content/renderer/media/media_devices_listener_impl.cc
@@ -16,9 +16,9 @@ namespace content {
// static
void MediaDevicesListenerImpl::Create(
int render_frame_id,
- ::mojom::MediaDevicesListenerRequest request) {
+ blink::mojom::MediaDevicesListenerRequest request) {
mojo::MakeStrongBinding(
- base::MakeUnique<MediaDevicesListenerImpl>(render_frame_id),
+ std::make_unique<MediaDevicesListenerImpl>(render_frame_id),
std::move(request));
}
diff --git a/chromium/content/renderer/media/media_devices_listener_impl.h b/chromium/content/renderer/media/media_devices_listener_impl.h
index 5198457a6c8..7e24ebff0ea 100644
--- a/chromium/content/renderer/media/media_devices_listener_impl.h
+++ b/chromium/content/renderer/media/media_devices_listener_impl.h
@@ -9,21 +9,21 @@
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "content/common/media/media_devices.h"
-#include "content/common/media/media_devices.mojom.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
namespace content {
// This class implements a Mojo object that receives notifications about changes
// in the set of media devices for a given frame.
class CONTENT_EXPORT MediaDevicesListenerImpl
- : public ::mojom::MediaDevicesListener {
+ : public blink::mojom::MediaDevicesListener {
public:
static void Create(int render_frame_id,
- ::mojom::MediaDevicesListenerRequest request);
+ blink::mojom::MediaDevicesListenerRequest request);
explicit MediaDevicesListenerImpl(int render_frame_id);
~MediaDevicesListenerImpl() override;
- // ::mojom::MediaDevicesListener implementation.
+ // blink::mojom::MediaDevicesListener implementation.
void OnDevicesChanged(MediaDeviceType type,
uint32_t subscription_id,
const MediaDeviceInfoArray& device_infos) override;
diff --git a/chromium/content/renderer/media/media_factory.cc b/chromium/content/renderer/media/media_factory.cc
index 59d42e7e33f..f322e93a5a5 100644
--- a/chromium/content/renderer/media/media_factory.cc
+++ b/chromium/content/renderer/media/media_factory.cc
@@ -156,7 +156,7 @@ void MediaFactory::SetupMojo() {
GetRemoterFactory()->Create(std::move(remoting_source),
mojo::MakeRequest(&remoter));
remoting_sink_observer_ =
- base::MakeUnique<media::remoting::SinkAvailabilityObserver>(
+ std::make_unique<media::remoting::SinkAvailabilityObserver>(
std::move(remoting_source_request), std::move(remoter));
#endif // BUILDFLAG(ENABLE_MEDIA_REMOTING)
}
@@ -197,7 +197,8 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
blink::WebMediaPlayerEncryptedMediaClient* encrypted_client,
blink::WebContentDecryptionModule* initial_cdm,
const blink::WebString& sink_id,
- blink::WebLayerTreeView* layer_tree_view) {
+ blink::WebLayerTreeView* layer_tree_view,
+ const cc::LayerTreeSettings& settings) {
blink::WebLocalFrame* web_frame = render_frame_->GetWebFrame();
blink::WebSecurityOrigin security_origin =
render_frame_->GetWebFrame()->GetSecurityOrigin();
@@ -268,9 +269,9 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
#endif
if (!fetch_context_) {
- fetch_context_ = base::MakeUnique<FrameFetchContext>(web_frame);
+ fetch_context_ = std::make_unique<FrameFetchContext>(web_frame);
DCHECK(!url_index_);
- url_index_ = base::MakeUnique<media::UrlIndex>(fetch_context_.get());
+ url_index_ = std::make_unique<media::UrlIndex>(fetch_context_.get());
}
DCHECK_EQ(static_cast<FrameFetchContext*>(fetch_context_.get())->frame(),
web_frame);
@@ -280,6 +281,26 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
mojo::MakeRequest(&watch_time_recorder_provider_));
}
+ scoped_refptr<base::SingleThreadTaskRunner>
+ video_frame_compositor_task_runner;
+ std::unique_ptr<blink::WebVideoFrameSubmitter> submitter;
+ if (base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideo)) {
+ // TODO(lethalantidote): Use a separate task_runner. https://crbug/753605.
+ video_frame_compositor_task_runner =
+ render_thread->GetMediaThreadTaskRunner();
+ submitter = blink::WebVideoFrameSubmitter::Create(
+ base::BindRepeating(
+ &PostMediaContextProviderToCallback,
+ RenderThreadImpl::current()->GetCompositorMainThreadTaskRunner()),
+ RenderThreadImpl::current()->GetSharedBitmapManager(),
+ RenderThreadImpl::current()->GetGpuMemoryBufferManager(), settings);
+ } else {
+ video_frame_compositor_task_runner =
+ render_thread->compositor_task_runner()
+ ? render_thread->compositor_task_runner()
+ : base::ThreadTaskRunnerHandle::Get();
+ }
+
DCHECK(layer_tree_view);
std::unique_ptr<media::WebMediaPlayerParams> params(
new media::WebMediaPlayerParams(
@@ -291,6 +312,7 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
audio_renderer_sink, render_thread->GetMediaThreadTaskRunner(),
render_thread->GetWorkerTaskRunner(),
render_thread->compositor_task_runner(),
+ video_frame_compositor_task_runner,
base::Bind(&v8::Isolate::AdjustAmountOfExternalAllocatedMemory,
base::Unretained(blink::MainThreadIsolate())),
initial_cdm, media_surface_manager_, request_routing_token_cb_,
@@ -301,14 +323,16 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
base::Bind(&MediaFactory::CreateVideoDecodeStatsRecorder,
base::Unretained(this)),
base::Bind(&blink::WebSurfaceLayerBridge::Create, layer_tree_view),
- base::BindRepeating(
- &PostMediaContextProviderToCallback,
- RenderThreadImpl::current()->GetCompositorMainThreadTaskRunner()),
RenderThreadImpl::current()->SharedMainThreadContextProvider()));
+ std::unique_ptr<media::VideoFrameCompositor> vfc =
+ std::make_unique<media::VideoFrameCompositor>(
+ params->video_frame_compositor_task_runner(), std::move(submitter));
+
media::WebMediaPlayerImpl* media_player = new media::WebMediaPlayerImpl(
web_frame, client, encrypted_client, GetWebMediaPlayerDelegate(),
- std::move(factory_selector), url_index_.get(), std::move(params));
+ std::move(factory_selector), url_index_.get(), std::move(vfc),
+ std::move(params));
#if defined(OS_ANDROID) // WMPI_CAST
media_player->SetMediaPlayerManager(GetMediaPlayerManager());
@@ -341,7 +365,7 @@ MediaFactory::CreateRendererFactorySelector(
if (!render_thread)
return nullptr;
- auto factory_selector = base::MakeUnique<media::RendererFactorySelector>();
+ auto factory_selector = std::make_unique<media::RendererFactorySelector>();
#if defined(OS_ANDROID)
DCHECK(remote_interfaces_);
@@ -349,7 +373,7 @@ MediaFactory::CreateRendererFactorySelector(
// The only MojoRendererService that is registered at the RenderFrameHost
// level uses the MediaPlayerRenderer as its underlying media::Renderer.
auto mojo_media_player_renderer_factory =
- base::MakeUnique<media::MojoRendererFactory>(
+ std::make_unique<media::MojoRendererFactory>(
media::MojoRendererFactory::GetGpuFactoriesCB(),
remote_interfaces_->get());
@@ -357,7 +381,7 @@ MediaFactory::CreateRendererFactorySelector(
// might fallback to it if the final redirected URL is an HLS url.
factory_selector->AddFactory(
media::RendererFactorySelector::FactoryType::MEDIA_PLAYER,
- base::MakeUnique<MediaPlayerRendererClientFactory>(
+ std::make_unique<MediaPlayerRendererClientFactory>(
render_thread->compositor_task_runner(),
std::move(mojo_media_player_renderer_factory),
base::Bind(&StreamTextureWrapperImpl::Create,
@@ -380,7 +404,7 @@ MediaFactory::CreateRendererFactorySelector(
if (use_mojo_renderer_factory) {
factory_selector->AddFactory(
media::RendererFactorySelector::FactoryType::MOJO,
- base::MakeUnique<media::MojoRendererFactory>(
+ std::make_unique<media::MojoRendererFactory>(
base::Bind(&RenderThreadImpl::GetGpuFactories,
base::Unretained(render_thread)),
GetMediaInterfaceFactory()));
@@ -393,7 +417,7 @@ MediaFactory::CreateRendererFactorySelector(
if (!use_mojo_renderer_factory) {
factory_selector->AddFactory(
media::RendererFactorySelector::FactoryType::DEFAULT,
- base::MakeUnique<media::DefaultRendererFactory>(
+ std::make_unique<media::DefaultRendererFactory>(
media_log, decoder_factory,
base::Bind(&RenderThreadImpl::GetGpuFactories,
base::Unretained(render_thread))));
@@ -415,7 +439,7 @@ MediaFactory::CreateRendererFactorySelector(
*out_media_observer = remoting_controller->GetWeakPtr();
auto courier_factory =
- base::MakeUnique<media::remoting::CourierRendererFactory>(
+ std::make_unique<media::remoting::CourierRendererFactory>(
std::move(remoting_controller));
// base::Unretained is safe here because |factory_selector| owns
@@ -447,7 +471,7 @@ blink::WebMediaPlayer* MediaFactory::CreateWebMediaPlayerForMediaStream(
return new WebMediaPlayerMS(
frame, client, GetWebMediaPlayerDelegate(),
- base::MakeUnique<RenderMediaLog>(url::Origin(security_origin).GetURL()),
+ std::make_unique<RenderMediaLog>(url::Origin(security_origin).GetURL()),
CreateMediaStreamRendererFactory(), render_thread->GetIOTaskRunner(),
compositor_task_runner, render_thread->GetMediaThreadTaskRunner(),
render_thread->GetWorkerTaskRunner(), render_thread->GetGpuFactories(),
diff --git a/chromium/content/renderer/media/media_factory.h b/chromium/content/renderer/media/media_factory.h
index 9888f606704..98cfb2eba85 100644
--- a/chromium/content/renderer/media/media_factory.h
+++ b/chromium/content/renderer/media/media_factory.h
@@ -36,6 +36,10 @@ class WebMediaPlayerClient;
class WebMediaPlayerEncryptedMediaClient;
}
+namespace cc {
+class LayerTreeSettings;
+}
+
namespace media {
class CdmFactory;
class DecoderFactory;
@@ -100,7 +104,8 @@ class MediaFactory {
blink::WebMediaPlayerEncryptedMediaClient* encrypted_client,
blink::WebContentDecryptionModule* initial_cdm,
const blink::WebString& sink_id,
- blink::WebLayerTreeView* layer_tree_view);
+ blink::WebLayerTreeView* layer_tree_view,
+ const cc::LayerTreeSettings& settings);
// Provides an EncryptedMediaClient to connect blink's EME layer to media's
// implementation of requestMediaKeySystemAccess. Will always return the same
diff --git a/chromium/content/renderer/media/media_permission_dispatcher.cc b/chromium/content/renderer/media/media_permission_dispatcher.cc
index 320fa9ed3b6..eeb8742ba30 100644
--- a/chromium/content/renderer/media/media_permission_dispatcher.cc
+++ b/chromium/content/renderer/media/media_permission_dispatcher.cc
@@ -43,12 +43,15 @@ blink::mojom::PermissionDescriptorPtr MediaPermissionTypeToPermissionDescriptor(
namespace content {
MediaPermissionDispatcher::MediaPermissionDispatcher(
- const ConnectToServiceCB& connect_to_service_cb)
+ 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()),
next_request_id_(0),
weak_factory_(this) {
DCHECK(!connect_to_service_cb_.is_null());
+ DCHECK(!is_encrypted_media_enabled_cb_.is_null());
weak_ptr_ = weak_factory_.GetWeakPtr();
}
@@ -85,7 +88,7 @@ void MediaPermissionDispatcher::HasPermission(
GetPermissionService()->HasPermission(
MediaPermissionTypeToPermissionDescriptor(type),
- url::Origin(security_origin),
+ url::Origin::Create(security_origin),
base::BindOnce(&MediaPermissionDispatcher::OnPermissionStatus, weak_ptr_,
request_id));
}
@@ -110,12 +113,16 @@ void MediaPermissionDispatcher::RequestPermission(
GetPermissionService()->RequestPermission(
MediaPermissionTypeToPermissionDescriptor(type),
- url::Origin(security_origin),
+ url::Origin::Create(security_origin),
blink::WebUserGestureIndicator::IsProcessingUserGesture(),
base::BindOnce(&MediaPermissionDispatcher::OnPermissionStatus, weak_ptr_,
request_id));
}
+bool MediaPermissionDispatcher::IsEncryptedMediaEnabled() {
+ return is_encrypted_media_enabled_cb_.Run();
+}
+
uint32_t MediaPermissionDispatcher::RegisterCallback(
const PermissionStatusCB& permission_status_cb) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
diff --git a/chromium/content/renderer/media/media_permission_dispatcher.h b/chromium/content/renderer/media/media_permission_dispatcher.h
index d386eca58d0..583bf80fe4e 100644
--- a/chromium/content/renderer/media/media_permission_dispatcher.h
+++ b/chromium/content/renderer/media/media_permission_dispatcher.h
@@ -26,11 +26,13 @@ namespace content {
// MediaPermission implementation using content PermissionService.
class CONTENT_EXPORT MediaPermissionDispatcher : public media::MediaPermission {
public:
- using ConnectToServiceCB = base::Callback<void(
+ using ConnectToServiceCB = base::RepeatingCallback<void(
mojo::InterfaceRequest<blink::mojom::PermissionService>)>;
+ using IsEncryptedMediaEnabledCB = base::RepeatingCallback<bool()>;
- explicit MediaPermissionDispatcher(
- const ConnectToServiceCB& connect_to_service_cb);
+ MediaPermissionDispatcher(
+ const ConnectToServiceCB& connect_to_service_cb,
+ const IsEncryptedMediaEnabledCB& is_encrypted_media_enabled_cb);
~MediaPermissionDispatcher() override;
// Called when the frame owning this MediaPermissionDispatcher is navigated.
@@ -46,6 +48,7 @@ class CONTENT_EXPORT MediaPermissionDispatcher : public media::MediaPermission {
Type type,
const GURL& security_origin,
const PermissionStatusCB& permission_status_cb) override;
+ bool IsEncryptedMediaEnabled() override;
private:
// Map of request IDs and pending PermissionStatusCBs.
@@ -66,6 +69,7 @@ class CONTENT_EXPORT MediaPermissionDispatcher : public media::MediaPermission {
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_;
diff --git a/chromium/content/renderer/media/media_stream_audio_processor.cc b/chromium/content/renderer/media/media_stream_audio_processor.cc
index 22f52762987..b8749729a55 100644
--- a/chromium/content/renderer/media/media_stream_audio_processor.cc
+++ b/chromium/content/renderer/media/media_stream_audio_processor.cc
@@ -30,6 +30,7 @@
#include "media/base/audio_parameters.h"
#include "media/base/channel_layout.h"
#include "third_party/webrtc/api/mediaconstraintsinterface.h"
+#include "third_party/webrtc/modules/audio_processing/include/audio_processing_statistics.h"
#include "third_party/webrtc/modules/audio_processing/typing_detection.h"
namespace content {
@@ -319,12 +320,17 @@ MediaStreamAudioProcessor::MediaStreamAudioProcessor(
DCHECK(main_thread_runner_);
capture_thread_checker_.DetachFromThread();
render_thread_checker_.DetachFromThread();
- InitializeAudioProcessingModule(properties);
- aec_dump_message_filter_ = AecDumpMessageFilter::Get();
// In unit tests not creating a message filter, |aec_dump_message_filter_|
- // will be NULL. We can just ignore that. Other unit tests and browser tests
- // ensure that we do get the filter when we should.
+ // will be null. We can just ignore that below. Other unit tests and browser
+ // tests ensure that we do get the filter when we should.
+ aec_dump_message_filter_ = AecDumpMessageFilter::Get();
+
+ if (aec_dump_message_filter_)
+ override_aec3_ = aec_dump_message_filter_->GetOverrideAec3();
+
+ InitializeAudioProcessingModule(properties);
+
if (aec_dump_message_filter_.get())
aec_dump_message_filter_->AddDelegate(this);
@@ -429,7 +435,7 @@ void MediaStreamAudioProcessor::Stop() {
if (aec_dump_message_filter_.get()) {
aec_dump_message_filter_->RemoveDelegate(this);
- aec_dump_message_filter_ = NULL;
+ aec_dump_message_filter_ = nullptr;
}
if (!audio_processing_.get())
@@ -441,7 +447,7 @@ void MediaStreamAudioProcessor::Stop() {
if (playout_data_source_) {
playout_data_source_->RemovePlayoutSink(this);
- playout_data_source_ = NULL;
+ playout_data_source_ = nullptr;
}
if (echo_information_)
@@ -507,13 +513,13 @@ void MediaStreamAudioProcessor::OnAec3Enable(bool enable) {
// information then will not be properly updated.
echo_information_.reset();
} else {
- echo_information_ = base::MakeUnique<EchoInformation>();
+ echo_information_ = std::make_unique<EchoInformation>();
}
}
void MediaStreamAudioProcessor::OnIpcClosing() {
DCHECK(main_thread_runner_->BelongsToCurrentThread());
- aec_dump_message_filter_ = NULL;
+ aec_dump_message_filter_ = nullptr;
}
// static
@@ -600,6 +606,15 @@ void MediaStreamAudioProcessor::GetStats(AudioProcessorStats* stats) {
GetAudioProcessingStats(audio_processing_.get(), stats);
}
+webrtc::AudioProcessorInterface::AudioProcessorStatistics
+MediaStreamAudioProcessor::GetStats(bool has_remote_tracks) {
+ AudioProcessorStatistics stats;
+ stats.typing_noise_detected =
+ (base::subtle::Acquire_Load(&typing_detected_) != false);
+ stats.apm_statistics = audio_processing_->GetStatistics(has_remote_tracks);
+ return stats;
+}
+
void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
const AudioProcessingProperties& properties) {
DCHECK(main_thread_runner_->BelongsToCurrentThread());
@@ -659,10 +674,8 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
// If the experimental AGC is enabled, check for overridden config params.
if (properties.goog_experimental_auto_gain_control) {
auto startup_min_volume = GetStartupMinVolumeForAgc();
- constexpr int kClippingLevelMin = 70;
- // TODO(hlundin) Make this value default in WebRTC and clean up here.
- config.Set<webrtc::ExperimentalAgc>(new webrtc::ExperimentalAgc(
- true, startup_min_volume.value_or(0), kClippingLevelMin));
+ config.Set<webrtc::ExperimentalAgc>(
+ new webrtc::ExperimentalAgc(true, startup_min_volume.value_or(0)));
}
// Create and configure the webrtc::AudioProcessing.
@@ -684,7 +697,7 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
if (!apm_config.echo_canceller3.enabled) {
// Prepare for logging echo information. If there are data remaining in
// |echo_information_| we simply discard it.
- echo_information_ = base::MakeUnique<EchoInformation>();
+ echo_information_ = std::make_unique<EchoInformation>();
} else {
// Do not log any echo information when AEC3 is active, as the echo
// information then will not be properly updated.
diff --git a/chromium/content/renderer/media/media_stream_audio_processor.h b/chromium/content/renderer/media/media_stream_audio_processor.h
index 71b8254793d..f72952f7c73 100644
--- a/chromium/content/renderer/media/media_stream_audio_processor.h
+++ b/chromium/content/renderer/media/media_stream_audio_processor.h
@@ -118,6 +118,8 @@ class CONTENT_EXPORT MediaStreamAudioProcessor
// AecDumpMessageFilter::AecDumpDelegate implementation.
// Called on the main render thread.
+ // TODO(grunell): Remove OnAec3Enable when clients have changed to enable
+ // before creating streams.
void OnAecDumpFile(const IPC::PlatformFileForTransit& file_handle) override;
void OnDisableAecDump() override;
void OnAec3Enable(bool enable) override;
@@ -149,6 +151,9 @@ class CONTENT_EXPORT MediaStreamAudioProcessor
// This method is called on the libjingle thread.
void GetStats(AudioProcessorStats* stats) override;
+ // This method is called on the libjingle thread.
+ AudioProcessorStatistics GetStats(bool has_remote_tracks) override;
+
// Helper to initialize the WebRtc AudioProcessing.
void InitializeAudioProcessingModule(
const AudioProcessingProperties& properties);
diff --git a/chromium/content/renderer/media/media_stream_audio_processor_options.h b/chromium/content/renderer/media/media_stream_audio_processor_options.h
index 9972921bbde..fe4becc7104 100644
--- a/chromium/content/renderer/media/media_stream_audio_processor_options.h
+++ b/chromium/content/renderer/media/media_stream_audio_processor_options.h
@@ -47,6 +47,7 @@ struct CONTENT_EXPORT AudioProcessingProperties {
bool enable_sw_echo_cancellation = true;
bool disable_hw_echo_cancellation = false;
+ bool disable_hw_noise_suppression = false;
bool goog_audio_mirroring = false;
bool goog_auto_gain_control = true;
bool goog_experimental_echo_cancellation =
diff --git a/chromium/content/renderer/media/media_stream_audio_processor_unittest.cc b/chromium/content/renderer/media/media_stream_audio_processor_unittest.cc
index 0960aa19186..d302a534703 100644
--- a/chromium/content/renderer/media/media_stream_audio_processor_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_audio_processor_unittest.cc
@@ -29,6 +29,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
#include "third_party/webrtc/api/mediastreaminterface.h"
+#include "third_party/webrtc/rtc_base/refcountedobject.h"
using ::testing::_;
using ::testing::AnyNumber;
@@ -224,7 +225,7 @@ class MediaStreamAudioProcessorTest : public ::testing::Test {
#endif
TEST_F(MediaStreamAudioProcessorTest, MAYBE_WithAudioProcessing) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new WebRtcAudioDeviceImpl());
+ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
scoped_refptr<MediaStreamAudioProcessor> audio_processor(
new rtc::RefCountedObject<MediaStreamAudioProcessor>(
@@ -248,7 +249,7 @@ TEST_F(MediaStreamAudioProcessorTest, TurnOffDefaultConstraints) {
// Turn off the default constraints and pass it to MediaStreamAudioProcessor.
properties.DisableDefaultPropertiesForTesting();
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new WebRtcAudioDeviceImpl());
+ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
scoped_refptr<MediaStreamAudioProcessor> audio_processor(
new rtc::RefCountedObject<MediaStreamAudioProcessor>(
properties, webrtc_audio_device.get()));
@@ -273,7 +274,7 @@ TEST_F(MediaStreamAudioProcessorTest, TurnOffDefaultConstraints) {
#endif
TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new WebRtcAudioDeviceImpl());
+ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
scoped_refptr<MediaStreamAudioProcessor> audio_processor(
new rtc::RefCountedObject<MediaStreamAudioProcessor>(
@@ -312,7 +313,7 @@ TEST_F(MediaStreamAudioProcessorTest, GetAecDumpMessageFilter) {
base::ThreadTaskRunnerHandle::Get()));
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new WebRtcAudioDeviceImpl());
+ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
scoped_refptr<MediaStreamAudioProcessor> audio_processor(
new rtc::RefCountedObject<MediaStreamAudioProcessor>(
@@ -327,7 +328,7 @@ TEST_F(MediaStreamAudioProcessorTest, GetAecDumpMessageFilter) {
TEST_F(MediaStreamAudioProcessorTest, StartStopAecDump) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new WebRtcAudioDeviceImpl());
+ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
base::ScopedTempDir temp_directory;
@@ -361,7 +362,7 @@ TEST_F(MediaStreamAudioProcessorTest, StartStopAecDump) {
TEST_F(MediaStreamAudioProcessorTest, TestStereoAudio) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new WebRtcAudioDeviceImpl());
+ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
// Turn off the audio processing and turn on the stereo channels mirroring.
properties.DisableDefaultPropertiesForTesting();
@@ -425,7 +426,7 @@ TEST_F(MediaStreamAudioProcessorTest, TestStereoAudio) {
#endif
TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestWithKeyboardMicChannel) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new WebRtcAudioDeviceImpl());
+ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
scoped_refptr<MediaStreamAudioProcessor> audio_processor(
new rtc::RefCountedObject<MediaStreamAudioProcessor>(
@@ -450,7 +451,7 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestWithKeyboardMicChannel) {
// Test that the OnAec3Enable method has the desired effect on the APM config.
TEST_F(MediaStreamAudioProcessorTest, TestAec3Switch) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new WebRtcAudioDeviceImpl());
+ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
scoped_refptr<MediaStreamAudioProcessor> audio_processor(
new rtc::RefCountedObject<MediaStreamAudioProcessor>(
@@ -471,7 +472,7 @@ TEST_F(MediaStreamAudioProcessorTest, TestAec3Switch) {
// outcome is that AEC3 should be disabled in all cases.
TEST_F(MediaStreamAudioProcessorTest, TestAec3Switch_AecOff) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new WebRtcAudioDeviceImpl());
+ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
// Disable the AEC.
properties.enable_sw_echo_cancellation = false;
diff --git a/chromium/content/renderer/media/media_stream_audio_track.cc b/chromium/content/renderer/media/media_stream_audio_track.cc
index 3c167fbdcd6..3d12468bbc0 100644
--- a/chromium/content/renderer/media/media_stream_audio_track.cc
+++ b/chromium/content/renderer/media/media_stream_audio_track.cc
@@ -4,6 +4,7 @@
#include "content/renderer/media/media_stream_audio_track.h"
+#include <utility>
#include <vector>
#include "base/callback_helpers.h"
@@ -102,7 +103,7 @@ void MediaStreamAudioTrack::Start(const base::Closure& stop_callback) {
stop_callback_ = stop_callback;
}
-void MediaStreamAudioTrack::Stop() {
+void MediaStreamAudioTrack::StopAndNotify(base::OnceClosure callback) {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "Stopping MediaStreamAudioTrack@" << this << '.';
@@ -116,6 +117,8 @@ void MediaStreamAudioTrack::Stop() {
sink->OnReadyStateChanged(blink::WebMediaStreamSource::kReadyStateEnded);
}
+ if (callback)
+ std::move(callback).Run();
weak_factory_.InvalidateWeakPtrs();
}
diff --git a/chromium/content/renderer/media/media_stream_audio_track.h b/chromium/content/renderer/media/media_stream_audio_track.h
index 636e030a017..0d7950d43ec 100644
--- a/chromium/content/renderer/media/media_stream_audio_track.h
+++ b/chromium/content/renderer/media/media_stream_audio_track.h
@@ -61,7 +61,7 @@ class CONTENT_EXPORT MediaStreamAudioTrack : public MediaStreamTrack {
// Halts the flow of audio data from the source (and to the sinks), and then
// notifies all sinks of the "ended" state.
- void Stop() final;
+ void StopAndNotify(base::OnceClosure callback) final;
// MediaStreamTrack override.
void SetEnabled(bool enabled) override;
diff --git a/chromium/content/renderer/media/media_stream_center.cc b/chromium/content/renderer/media/media_stream_center.cc
index 7e1f32dc4f9..4178b583185 100644
--- a/chromium/content/renderer/media/media_stream_center.cc
+++ b/chromium/content/renderer/media/media_stream_center.cc
@@ -60,7 +60,7 @@ void CreateNativeAudioMediaStreamTrack(
}
void CreateNativeVideoMediaStreamTrack(blink::WebMediaStreamTrack track) {
- DCHECK(track.GetTrackData() == NULL);
+ DCHECK(track.GetTrackData() == nullptr);
blink::WebMediaStreamSource source = track.Source();
DCHECK_EQ(source.GetType(), blink::WebMediaStreamSource::kTypeVideo);
MediaStreamVideoSource* native_source =
@@ -154,14 +154,6 @@ void MediaStreamCenter::DidDisableMediaStreamTrack(
native_track->SetEnabled(false);
}
-bool MediaStreamCenter::DidStopMediaStreamTrack(
- const blink::WebMediaStreamTrack& track) {
- DVLOG(1) << "MediaStreamCenter::didStopMediaStreamTrack";
- MediaStreamTrack* native_track = MediaStreamTrack::GetTrack(track);
- native_track->Stop();
- return true;
-}
-
blink::WebAudioSourceProvider*
MediaStreamCenter::CreateWebAudioSourceFromMediaStreamTrack(
const blink::WebMediaStreamTrack& track) {
@@ -182,23 +174,6 @@ MediaStreamCenter::CreateWebAudioSourceFromMediaStreamTrack(
return new WebRtcLocalAudioSourceProvider(track);
}
-void MediaStreamCenter::DidStopLocalMediaStream(
- const blink::WebMediaStream& stream) {
- DVLOG(1) << "MediaStreamCenter::didStopLocalMediaStream";
-
- // TODO(perkj): MediaStream::Stop is being deprecated. But for the moment we
- // need to support both MediaStream::Stop and MediaStreamTrack::Stop.
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- stream.AudioTracks(audio_tracks);
- for (size_t i = 0; i < audio_tracks.size(); ++i)
- DidStopMediaStreamTrack(audio_tracks[i]);
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- stream.VideoTracks(video_tracks);
- for (size_t i = 0; i < video_tracks.size(); ++i)
- DidStopMediaStreamTrack(video_tracks[i]);
-}
-
void MediaStreamCenter::DidStopMediaStreamSource(
const blink::WebMediaStreamSource& web_source) {
if (web_source.IsNull())
diff --git a/chromium/content/renderer/media/media_stream_center.h b/chromium/content/renderer/media/media_stream_center.h
index 871dc84761d..0269ef27930 100644
--- a/chromium/content/renderer/media/media_stream_center.h
+++ b/chromium/content/renderer/media/media_stream_center.h
@@ -46,11 +46,6 @@ class CONTENT_EXPORT MediaStreamCenter : public blink::WebMediaStreamCenter {
void DidDisableMediaStreamTrack(
const blink::WebMediaStreamTrack& track) override;
- void DidStopLocalMediaStream(const blink::WebMediaStream& stream) override;
-
- bool DidStopMediaStreamTrack(
- const blink::WebMediaStreamTrack& track) override;
-
blink::WebAudioSourceProvider* CreateWebAudioSourceFromMediaStreamTrack(
const blink::WebMediaStreamTrack& track) override;
diff --git a/chromium/content/renderer/media/media_stream_constraints_util.h b/chromium/content/renderer/media/media_stream_constraints_util.h
index 213efba5fe2..0538eb868e5 100644
--- a/chromium/content/renderer/media/media_stream_constraints_util.h
+++ b/chromium/content/renderer/media/media_stream_constraints_util.h
@@ -9,11 +9,11 @@
#include "base/logging.h"
#include "content/common/content_export.h"
-#include "content/common/media/media_devices.mojom.h"
#include "content/renderer/media/media_stream_audio_processor_options.h"
#include "content/renderer/media/video_track_adapter.h"
#include "media/capture/video_capture_types.h"
#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
#include "third_party/webrtc/api/optional.h"
namespace content {
diff --git a/chromium/content/renderer/media/media_stream_constraints_util_audio.cc b/chromium/content/renderer/media/media_stream_constraints_util_audio.cc
index 105c51cc87f..5c3ea10a5ce 100644
--- a/chromium/content/renderer/media/media_stream_constraints_util_audio.cc
+++ b/chromium/content/renderer/media/media_stream_constraints_util_audio.cc
@@ -20,13 +20,13 @@ namespace content {
namespace {
-// This class has the same data as ::mojom::AudioInputDeviceCapabilities, but
-// adds extra operations to simplify access to device parameters.
+// This class has the same data as blink::mojom::AudioInputDeviceCapabilities,
+// but adds extra operations to simplify access to device parameters.
class AudioDeviceInfo {
public:
// This constructor is intended for device capture.
explicit AudioDeviceInfo(
- const ::mojom::AudioInputDeviceCapabilitiesPtr& device_info)
+ const blink::mojom::AudioInputDeviceCapabilitiesPtr& device_info)
: device_id_(device_info->device_id),
parameters_(device_info->parameters) {
DCHECK(parameters_.IsValid());
@@ -458,7 +458,8 @@ AudioProcessingProperties SelectAudioProcessingProperties(
const AudioCaptureCandidates& candidates,
const blink::WebMediaTrackConstraintSet& basic_constraint_set,
const media::AudioParameters& audio_parameters,
- bool is_device_capture) {
+ bool is_device_capture,
+ bool should_disable_hardware_noise_suppression) {
DCHECK(!candidates.IsEmpty());
base::Optional<bool> echo_cancellation =
SelectOptionalBool(candidates.echo_cancellation_set(),
@@ -480,6 +481,9 @@ AudioProcessingProperties SelectAudioProcessingProperties(
properties.disable_hw_echo_cancellation =
(echo_cancellation && !*echo_cancellation) ||
(goog_echo_cancellation && !*goog_echo_cancellation);
+ properties.disable_hw_noise_suppression =
+ should_disable_hardware_noise_suppression &&
+ !properties.disable_hw_echo_cancellation;
properties.goog_audio_mirroring =
SelectBool(candidates.goog_audio_mirroring_set(),
@@ -512,7 +516,8 @@ AudioCaptureSettings SelectResult(
const AudioCaptureCandidates& candidates,
const blink::WebMediaTrackConstraintSet& basic_constraint_set,
const std::string& default_device_id,
- const std::string& media_stream_source) {
+ const std::string& media_stream_source,
+ bool should_disable_hardware_noise_suppression) {
bool is_device_capture = media_stream_source.empty();
AudioDeviceInfo device_info =
SelectDevice(candidates.audio_device_set(), basic_constraint_set,
@@ -530,9 +535,9 @@ AudioCaptureSettings SelectResult(
basic_constraint_set.render_to_associated_sink, false);
AudioProcessingProperties audio_processing_properties =
- SelectAudioProcessingProperties(candidates, basic_constraint_set,
- device_info.parameters(),
- is_device_capture);
+ SelectAudioProcessingProperties(
+ candidates, basic_constraint_set, device_info.parameters(),
+ is_device_capture, should_disable_hardware_noise_suppression);
return AudioCaptureSettings(device_info.device_id(), device_info.parameters(),
hotword_enabled, disable_local_echo,
@@ -544,7 +549,8 @@ AudioCaptureSettings SelectResult(
AudioCaptureSettings SelectSettingsAudioCapture(
const AudioDeviceCaptureCapabilities& capabilities,
- const blink::WebMediaConstraints& constraints) {
+ const blink::WebMediaConstraints& constraints,
+ bool should_disable_hardware_noise_suppression) {
std::string media_stream_source = GetMediaStreamSource(constraints);
bool is_device_capture = media_stream_source.empty();
if (is_device_capture && capabilities.empty())
@@ -571,7 +577,8 @@ AudioCaptureSettings SelectSettingsAudioCapture(
default_device_id = (*capabilities.begin())->device_id;
return SelectResult(candidates, constraints.Basic(), default_device_id,
- media_stream_source);
+ media_stream_source,
+ should_disable_hardware_noise_suppression);
}
} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_constraints_util_audio.h b/chromium/content/renderer/media/media_stream_constraints_util_audio.h
index e08f0b904bc..eaf77a27de2 100644
--- a/chromium/content/renderer/media/media_stream_constraints_util_audio.h
+++ b/chromium/content/renderer/media/media_stream_constraints_util_audio.h
@@ -9,8 +9,8 @@
#include <vector>
#include "content/common/content_export.h"
-#include "content/common/media/media_devices.mojom.h"
#include "content/renderer/media/media_stream_constraints_util.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
namespace blink {
class WebMediaConstraints;
@@ -19,7 +19,7 @@ class WebMediaConstraints;
namespace content {
using AudioDeviceCaptureCapabilities =
- std::vector<::mojom::AudioInputDeviceCapabilitiesPtr>;
+ std::vector<blink::mojom::AudioInputDeviceCapabilitiesPtr>;
// This function implements the SelectSettings algorithm for audio tracks as
// described in https://w3c.github.io/mediacapture-main/#dfn-selectsettings
@@ -91,7 +91,8 @@ using AudioDeviceCaptureCapabilities =
// channelCount and groupId. http://crbug.com/731170
AudioCaptureSettings CONTENT_EXPORT
SelectSettingsAudioCapture(const AudioDeviceCaptureCapabilities& capabilities,
- const blink::WebMediaConstraints& constraints);
+ const blink::WebMediaConstraints& constraints,
+ bool should_disable_hardware_noise_suppression);
} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_constraints_util_audio_unittest.cc b/chromium/content/renderer/media/media_stream_constraints_util_audio_unittest.cc
index ec2f9ede6a0..cbfb5708605 100644
--- a/chromium/content/renderer/media/media_stream_constraints_util_audio_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_constraints_util_audio_unittest.cc
@@ -8,12 +8,12 @@
#include <string>
#include <utility>
-#include "content/common/media/media_devices.mojom.h"
#include "content/common/media/media_stream_controls.h"
#include "content/renderer/media/mock_constraint_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
namespace content {
@@ -59,8 +59,8 @@ class MediaStreamConstraintsUtilAudioTest
if (!IsDeviceCapture())
return;
- ::mojom::AudioInputDeviceCapabilitiesPtr device =
- ::mojom::AudioInputDeviceCapabilities::New();
+ blink::mojom::AudioInputDeviceCapabilitiesPtr device =
+ blink::mojom::AudioInputDeviceCapabilities::New();
device->device_id = "default_device";
device->parameters = media::AudioParameters(
media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
@@ -68,7 +68,7 @@ class MediaStreamConstraintsUtilAudioTest
media::AudioParameters::kAudioCDSampleRate, 16, 1000);
capabilities_.push_back(std::move(device));
- device = ::mojom::AudioInputDeviceCapabilities::New();
+ device = blink::mojom::AudioInputDeviceCapabilities::New();
device->device_id = "hw_echo_canceller_device";
device->parameters = media::AudioParameters(
media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
@@ -77,7 +77,7 @@ class MediaStreamConstraintsUtilAudioTest
device->parameters.set_effects(media::AudioParameters::ECHO_CANCELLER);
capabilities_.push_back(std::move(device));
- device = ::mojom::AudioInputDeviceCapabilities::New();
+ device = blink::mojom::AudioInputDeviceCapabilities::New();
device->device_id = "geometry device";
device->parameters = media::AudioParameters(
media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
@@ -106,7 +106,7 @@ class MediaStreamConstraintsUtilAudioTest
AudioCaptureSettings SelectSettings() {
blink::WebMediaConstraints constraints =
constraint_factory_.CreateWebMediaConstraints();
- return SelectSettingsAudioCapture(capabilities_, constraints);
+ return SelectSettingsAudioCapture(capabilities_, constraints, false);
}
// When googExperimentalEchoCancellation is not explicitly set, its default
@@ -270,8 +270,9 @@ class MediaStreamConstraintsUtilAudioTest
}
}
- void CheckDevice(const mojom::AudioInputDeviceCapabilities& expected_device,
- const AudioCaptureSettings& result) {
+ void CheckDevice(
+ const blink::mojom::AudioInputDeviceCapabilities& expected_device,
+ const AudioCaptureSettings& result) {
EXPECT_EQ(expected_device.device_id, result.device_id());
EXPECT_EQ(expected_device.parameters.sample_rate(),
result.device_parameters().sample_rate());
@@ -306,10 +307,10 @@ class MediaStreamConstraintsUtilAudioTest
MockConstraintFactory constraint_factory_;
AudioDeviceCaptureCapabilities capabilities_;
- const mojom::AudioInputDeviceCapabilities* default_device_ = nullptr;
- const mojom::AudioInputDeviceCapabilities* hw_echo_canceller_device_ =
+ const blink::mojom::AudioInputDeviceCapabilities* default_device_ = nullptr;
+ const blink::mojom::AudioInputDeviceCapabilities* hw_echo_canceller_device_ =
nullptr;
- const mojom::AudioInputDeviceCapabilities* geometry_device_ = nullptr;
+ const blink::mojom::AudioInputDeviceCapabilities* geometry_device_ = nullptr;
const std::vector<media::Point> kMicPositions = {{8, 8, 8}, {4, 4, 4}};
};
@@ -957,7 +958,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, NoDevicesNoConstraints) {
AudioDeviceCaptureCapabilities capabilities;
auto result = SelectSettingsAudioCapture(
- capabilities, constraint_factory_.CreateWebMediaConstraints());
+ capabilities, constraint_factory_.CreateWebMediaConstraints(), false);
EXPECT_FALSE(result.HasValue());
EXPECT_TRUE(std::string(result.failed_constraint_name()).empty());
}
@@ -970,7 +971,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, NoDevicesWithConstraints) {
AudioDeviceCaptureCapabilities capabilities;
constraint_factory_.basic().sample_size.SetExact(16);
auto result = SelectSettingsAudioCapture(
- capabilities, constraint_factory_.CreateWebMediaConstraints());
+ capabilities, constraint_factory_.CreateWebMediaConstraints(), false);
EXPECT_FALSE(result.HasValue());
EXPECT_TRUE(std::string(result.failed_constraint_name()).empty());
}
diff --git a/chromium/content/renderer/media/media_stream_constraints_util_video_content.cc b/chromium/content/renderer/media/media_stream_constraints_util_video_content.cc
index eb54b54f7ab..7eb3e41ec19 100644
--- a/chromium/content/renderer/media/media_stream_constraints_util_video_content.cc
+++ b/chromium/content/renderer/media/media_stream_constraints_util_video_content.cc
@@ -249,7 +249,7 @@ base::Optional<bool> SelectNoiseReductionFromCandidates(
return base::Optional<bool>(candidates.FirstElement());
}
-int ClampToValidDimension(int value) {
+int ClampToValidScreenCastDimension(int value) {
if (value > kMaxScreenCastDimension)
return kMaxScreenCastDimension;
else if (value < kMinScreenCastDimension)
@@ -286,8 +286,8 @@ VideoCaptureSettings SelectResultFromCandidates(
// When the given maximum values are large, the computed values using default
// aspect ratio may fall out of range. Ensure the defaults are in the valid
// range.
- default_height = ClampToValidDimension(default_height);
- default_width = ClampToValidDimension(default_width);
+ default_height = ClampToValidScreenCastDimension(default_height);
+ default_width = ClampToValidScreenCastDimension(default_width);
// If a maximum frame rate is explicitly given, use it as default for
// better compatibility with the old constraints algorithm.
diff --git a/chromium/content/renderer/media/media_stream_constraints_util_video_device.cc b/chromium/content/renderer/media/media_stream_constraints_util_video_device.cc
index 137fd5346f5..34bcba1bc3f 100644
--- a/chromium/content/renderer/media/media_stream_constraints_util_video_device.cc
+++ b/chromium/content/renderer/media/media_stream_constraints_util_video_device.cc
@@ -33,15 +33,15 @@ const double kMinSourceAspectRatio = 0.05;
const char kVideoKindColor[] = "color";
const char kVideoKindDepth[] = "depth";
-blink::WebString ToWebString(::mojom::FacingMode facing_mode) {
+blink::WebString ToWebString(blink::mojom::FacingMode facing_mode) {
switch (facing_mode) {
- case ::mojom::FacingMode::USER:
+ case blink::mojom::FacingMode::USER:
return blink::WebString::FromASCII("user");
- case ::mojom::FacingMode::ENVIRONMENT:
+ case blink::mojom::FacingMode::ENVIRONMENT:
return blink::WebString::FromASCII("environment");
- case ::mojom::FacingMode::LEFT:
+ case blink::mojom::FacingMode::LEFT:
return blink::WebString::FromASCII("left");
- case ::mojom::FacingMode::RIGHT:
+ case blink::mojom::FacingMode::RIGHT:
return blink::WebString::FromASCII("right");
default:
return blink::WebString::FromASCII("");
@@ -52,7 +52,7 @@ struct Candidate {
public:
Candidate(const std::string& device_id,
const media::VideoCaptureFormat& format,
- ::mojom::FacingMode facing_mode,
+ blink::mojom::FacingMode facing_mode,
media::PowerLineFrequency power_line_frequency,
const base::Optional<bool>& noise_reduction)
: device_id_(device_id),
@@ -77,7 +77,7 @@ struct Candidate {
// Accessors.
const media::VideoCaptureFormat& format() const { return format_; }
const std::string& device_id() const { return device_id_; }
- ::mojom::FacingMode facing_mode() const { return facing_mode_; }
+ blink::mojom::FacingMode facing_mode() const { return facing_mode_; }
media::PowerLineFrequency power_line_frequency() const {
return power_line_frequency_;
}
@@ -88,7 +88,7 @@ struct Candidate {
private:
std::string device_id_;
media::VideoCaptureFormat format_;
- ::mojom::FacingMode facing_mode_;
+ blink::mojom::FacingMode facing_mode_;
media::PowerLineFrequency power_line_frequency_;
base::Optional<bool> noise_reduction_;
};
@@ -433,7 +433,7 @@ double NoiseReductionConstraintSourceDistance(
// characteristics that have a fixed value.
double DeviceSourceDistance(
const std::string& device_id,
- ::mojom::FacingMode facing_mode,
+ blink::mojom::FacingMode facing_mode,
const blink::WebMediaTrackConstraintSet& constraint_set,
const char** failed_constraint_name) {
return StringConstraintSourceDistance(blink::WebString::FromASCII(device_id),
diff --git a/chromium/content/renderer/media/media_stream_constraints_util_video_device.h b/chromium/content/renderer/media/media_stream_constraints_util_video_device.h
index 3160299e666..3e624ab42f7 100644
--- a/chromium/content/renderer/media/media_stream_constraints_util_video_device.h
+++ b/chromium/content/renderer/media/media_stream_constraints_util_video_device.h
@@ -10,9 +10,9 @@
#include "base/optional.h"
#include "content/common/content_export.h"
-#include "content/common/media/media_devices.mojom.h"
#include "content/renderer/media/media_stream_constraints_util.h"
#include "media/capture/video_capture_types.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
namespace blink {
class WebString;
@@ -34,7 +34,8 @@ struct CONTENT_EXPORT VideoDeviceCaptureCapabilities {
VideoDeviceCaptureCapabilities&& other);
// Each field is independent of each other.
- std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> device_capabilities;
+ std::vector<blink::mojom::VideoInputDeviceCapabilitiesPtr>
+ device_capabilities;
std::vector<media::PowerLineFrequency> power_line_capabilities;
std::vector<base::Optional<bool>> noise_reduction_capabilities;
};
diff --git a/chromium/content/renderer/media/media_stream_constraints_util_video_device_unittest.cc b/chromium/content/renderer/media/media_stream_constraints_util_video_device_unittest.cc
index ce733ea120b..b37603b3be1 100644
--- a/chromium/content/renderer/media/media_stream_constraints_util_video_device_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_constraints_util_video_device_unittest.cc
@@ -70,10 +70,10 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
public:
void SetUp() override {
// Default device. It is default because it is the first in the enumeration.
- ::mojom::VideoInputDeviceCapabilitiesPtr device =
- ::mojom::VideoInputDeviceCapabilities::New();
+ blink::mojom::VideoInputDeviceCapabilitiesPtr device =
+ blink::mojom::VideoInputDeviceCapabilities::New();
device->device_id = kDeviceID1;
- device->facing_mode = ::mojom::FacingMode::NONE;
+ device->facing_mode = blink::mojom::FacingMode::NONE;
device->formats = {
media::VideoCaptureFormat(gfx::Size(200, 200), 40.0f,
media::PIXEL_FORMAT_I420),
@@ -86,9 +86,9 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
capabilities_.device_capabilities.push_back(std::move(device));
// A low-resolution device.
- device = ::mojom::VideoInputDeviceCapabilities::New();
+ device = blink::mojom::VideoInputDeviceCapabilities::New();
device->device_id = kDeviceID2;
- device->facing_mode = ::mojom::FacingMode::ENVIRONMENT;
+ device->facing_mode = blink::mojom::FacingMode::ENVIRONMENT;
device->formats = {
media::VideoCaptureFormat(gfx::Size(40, 30), 20.0f,
media::PIXEL_FORMAT_I420),
@@ -106,9 +106,9 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
capabilities_.device_capabilities.push_back(std::move(device));
// A high-resolution device.
- device = ::mojom::VideoInputDeviceCapabilities::New();
+ device = blink::mojom::VideoInputDeviceCapabilities::New();
device->device_id = kDeviceID3;
- device->facing_mode = ::mojom::FacingMode::USER;
+ device->facing_mode = blink::mojom::FacingMode::USER;
device->formats = {
media::VideoCaptureFormat(gfx::Size(600, 400), 10.0f,
media::PIXEL_FORMAT_I420),
@@ -137,18 +137,18 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
capabilities_.device_capabilities.push_back(std::move(device));
// A depth capture device.
- device = ::mojom::VideoInputDeviceCapabilities::New();
+ device = blink::mojom::VideoInputDeviceCapabilities::New();
device->device_id = kDeviceID4;
- device->facing_mode = ::mojom::FacingMode::ENVIRONMENT;
+ device->facing_mode = blink::mojom::FacingMode::ENVIRONMENT;
device->formats = {media::VideoCaptureFormat(gfx::Size(640, 480), 30.0f,
media::PIXEL_FORMAT_Y16)};
capabilities_.device_capabilities.push_back(std::move(device));
// A device that reports invalid frame rates. These devices exist and should
// be supported if no constraints are placed on the frame rate.
- device = ::mojom::VideoInputDeviceCapabilities::New();
+ device = blink::mojom::VideoInputDeviceCapabilities::New();
device->device_id = kDeviceID5;
- device->facing_mode = ::mojom::FacingMode::NONE;
+ device->facing_mode = blink::mojom::FacingMode::NONE;
device->formats = {
media::VideoCaptureFormat(
gfx::Size(MediaStreamVideoSource::kDefaultWidth,
@@ -188,10 +188,10 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
}
VideoDeviceCaptureCapabilities capabilities_;
- const mojom::VideoInputDeviceCapabilities* default_device_;
- const mojom::VideoInputDeviceCapabilities* low_res_device_;
- const mojom::VideoInputDeviceCapabilities* high_res_device_;
- const mojom::VideoInputDeviceCapabilities* invalid_frame_rate_device_;
+ const blink::mojom::VideoInputDeviceCapabilities* default_device_;
+ const blink::mojom::VideoInputDeviceCapabilities* low_res_device_;
+ const blink::mojom::VideoInputDeviceCapabilities* high_res_device_;
+ const blink::mojom::VideoInputDeviceCapabilities* invalid_frame_rate_device_;
// Closest formats to the default settings.
const media::VideoCaptureFormat* default_closest_format_;
const media::VideoCaptureFormat* low_res_closest_format_;
@@ -382,10 +382,10 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
// Manually adding device capabilities because VideoDeviceCaptureCapabilities
// is move only.
VideoDeviceCaptureCapabilities capabilities;
- ::mojom::VideoInputDeviceCapabilitiesPtr device =
- ::mojom::VideoInputDeviceCapabilities::New();
+ blink::mojom::VideoInputDeviceCapabilitiesPtr device =
+ blink::mojom::VideoInputDeviceCapabilities::New();
device->device_id = kDeviceID1;
- device->facing_mode = ::mojom::FacingMode::NONE;
+ device->facing_mode = blink::mojom::FacingMode::NONE;
device->formats = {
media::VideoCaptureFormat(gfx::Size(200, 200), 40.0f,
media::PIXEL_FORMAT_I420),
@@ -445,7 +445,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFacingMode) {
// Only the low-res device supports environment facing mode. Should select
// default settings for everything else.
EXPECT_EQ(low_res_device_->device_id, result.device_id());
- EXPECT_EQ(::mojom::FacingMode::ENVIRONMENT, low_res_device_->facing_mode);
+ EXPECT_EQ(blink::mojom::FacingMode::ENVIRONMENT,
+ low_res_device_->facing_mode);
EXPECT_EQ(*low_res_closest_format_, result.Format());
EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
result.PowerLineFrequency());
@@ -458,7 +459,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFacingMode) {
// Only the high-res device supports user facing mode. Should select default
// settings for everything else.
EXPECT_EQ(high_res_device_->device_id, result.device_id());
- EXPECT_EQ(::mojom::FacingMode::USER, high_res_device_->facing_mode);
+ EXPECT_EQ(blink::mojom::FacingMode::USER, high_res_device_->facing_mode);
EXPECT_EQ(*high_res_closest_format_, result.Format());
EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
result.PowerLineFrequency());
diff --git a/chromium/content/renderer/media/media_stream_device_observer.cc b/chromium/content/renderer/media/media_stream_device_observer.cc
new file mode 100644
index 00000000000..89bbfc7c62e
--- /dev/null
+++ b/chromium/content/renderer/media/media_stream_device_observer.cc
@@ -0,0 +1,199 @@
+// 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/media/media_stream_device_observer.h"
+
+#include <stddef.h>
+
+#include <utility>
+
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "content/child/child_thread_impl.h"
+#include "content/public/common/service_names.mojom.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
+#include "url/origin.h"
+
+namespace content {
+
+namespace {
+
+bool RemoveStreamDeviceFromArray(const MediaStreamDevice& device,
+ MediaStreamDevices* devices) {
+ for (MediaStreamDevices::iterator device_it = devices->begin();
+ device_it != devices->end(); ++device_it) {
+ if (device_it->IsSameDevice(device)) {
+ devices->erase(device_it);
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+struct MediaStreamDeviceObserver::Stream {
+ Stream() {}
+ ~Stream() {}
+ base::WeakPtr<MediaStreamDispatcherEventHandler> handler;
+ MediaStreamDevices audio_devices;
+ MediaStreamDevices video_devices;
+};
+
+MediaStreamDeviceObserver::MediaStreamDeviceObserver(RenderFrame* render_frame)
+ : RenderFrameObserver(render_frame), binding_(this) {
+ registry_.AddInterface(base::Bind(
+ &MediaStreamDeviceObserver::BindMediaStreamDeviceObserverRequest,
+ base::Unretained(this)));
+}
+
+MediaStreamDeviceObserver::~MediaStreamDeviceObserver() {}
+
+MediaStreamDevices MediaStreamDeviceObserver::GetNonScreenCaptureDevices() {
+ MediaStreamDevices video_devices;
+ for (const auto& stream_it : label_stream_map_) {
+ for (const auto& video_device : stream_it.second.video_devices) {
+ if (!IsScreenCaptureMediaType(video_device.type))
+ video_devices.push_back(video_device);
+ }
+ }
+ return video_devices;
+}
+
+void MediaStreamDeviceObserver::OnInterfaceRequestForFrame(
+ const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle* interface_pipe) {
+ registry_.TryBindInterface(interface_name, interface_pipe);
+}
+
+void MediaStreamDeviceObserver::OnDestruct() {
+ // Do not self-destruct. UserMediaClientImpl owns |this|.
+}
+
+void MediaStreamDeviceObserver::OnDeviceStopped(
+ const std::string& label,
+ const MediaStreamDevice& device) {
+ DVLOG(1) << __func__ << " label=" << label << " device_id=" << device.id;
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto it = label_stream_map_.find(label);
+ if (it == label_stream_map_.end()) {
+ // This can happen if a user happen stop a the device from JS at the same
+ // time as the underlying media device is unplugged from the system.
+ return;
+ }
+ Stream* stream = &it->second;
+ if (IsAudioInputMediaType(device.type))
+ RemoveStreamDeviceFromArray(device, &stream->audio_devices);
+ else
+ RemoveStreamDeviceFromArray(device, &stream->video_devices);
+
+ if (stream->handler.get())
+ stream->handler->OnDeviceStopped(device);
+
+ // |it| could have already been invalidated in the function call above. So we
+ // need to check if |label| is still in |label_stream_map_| again.
+ // Note: this is a quick fix to the crash caused by erasing the invalidated
+ // iterator from |label_stream_map_| (crbug.com/616884). Future work needs to
+ // be done to resolve this re-entrancy issue.
+ it = label_stream_map_.find(label);
+ if (it == label_stream_map_.end())
+ return;
+ stream = &it->second;
+ if (stream->audio_devices.empty() && stream->video_devices.empty())
+ label_stream_map_.erase(it);
+}
+
+void MediaStreamDeviceObserver::BindMediaStreamDeviceObserverRequest(
+ mojom::MediaStreamDeviceObserverRequest request) {
+ binding_.Bind(std::move(request));
+}
+
+void MediaStreamDeviceObserver::AddStream(
+ const std::string& label,
+ const MediaStreamDevices& audio_devices,
+ const MediaStreamDevices& video_devices,
+ const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ Stream stream;
+ stream.handler = event_handler;
+ stream.audio_devices = audio_devices;
+ stream.video_devices = video_devices;
+
+ label_stream_map_[label] = stream;
+}
+
+void MediaStreamDeviceObserver::AddStream(const std::string& label,
+ const MediaStreamDevice& device) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ Stream stream;
+ if (IsAudioInputMediaType(device.type))
+ stream.audio_devices.push_back(device);
+ else if (IsVideoMediaType(device.type))
+ stream.video_devices.push_back(device);
+ else
+ NOTREACHED();
+
+ label_stream_map_[label] = stream;
+}
+
+bool MediaStreamDeviceObserver::RemoveStream(const std::string& label) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto it = label_stream_map_.find(label);
+ if (it == label_stream_map_.end())
+ return false;
+
+ label_stream_map_.erase(it);
+ return true;
+}
+
+void MediaStreamDeviceObserver::RemoveStreamDevice(
+ const MediaStreamDevice& device) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // Remove |device| from all streams in |label_stream_map_|.
+ bool device_found = false;
+ auto stream_it = label_stream_map_.begin();
+ while (stream_it != label_stream_map_.end()) {
+ MediaStreamDevices& audio_devices = stream_it->second.audio_devices;
+ MediaStreamDevices& video_devices = stream_it->second.video_devices;
+
+ if (RemoveStreamDeviceFromArray(device, &audio_devices) ||
+ RemoveStreamDeviceFromArray(device, &video_devices)) {
+ device_found = true;
+ if (audio_devices.empty() && video_devices.empty()) {
+ label_stream_map_.erase(stream_it++);
+ continue;
+ }
+ }
+ ++stream_it;
+ }
+ DCHECK(device_found);
+}
+
+int MediaStreamDeviceObserver::audio_session_id(const std::string& label) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto it = label_stream_map_.find(label);
+ if (it == label_stream_map_.end() || it->second.audio_devices.empty())
+ return MediaStreamDevice::kNoId;
+
+ return it->second.audio_devices[0].session_id;
+}
+
+int MediaStreamDeviceObserver::video_session_id(const std::string& label) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto it = label_stream_map_.find(label);
+ if (it == label_stream_map_.end() || it->second.video_devices.empty())
+ return MediaStreamDevice::kNoId;
+
+ return it->second.video_devices[0].session_id;
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_device_observer.h b/chromium/content/renderer/media/media_stream_device_observer.h
new file mode 100644
index 00000000000..b72878ab529
--- /dev/null
+++ b/chromium/content/renderer/media/media_stream_device_observer.h
@@ -0,0 +1,93 @@
+// 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_MEDIA_MEDIA_STREAM_DEVICE_OBSERVER_H_
+#define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_DEVICE_OBSERVER_H_
+
+#include <list>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "content/common/content_export.h"
+#include "content/common/media/media_stream.mojom.h"
+#include "content/public/common/media_stream_request.h"
+#include "content/public/renderer/render_frame_observer.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
+
+namespace content {
+
+class MediaStreamDispatcherEventHandler;
+
+// This class implements a Mojo object that receives device stopped
+// notifications and forwards them to MediaStreamDispatcherEventHandler.
+class CONTENT_EXPORT MediaStreamDeviceObserver
+ : public RenderFrameObserver,
+ public mojom::MediaStreamDeviceObserver {
+ public:
+ explicit MediaStreamDeviceObserver(RenderFrame* render_frame);
+ ~MediaStreamDeviceObserver() override;
+
+ // Get all the media devices of video capture, e.g. webcam. This is the set
+ // of devices that should be suspended when the content frame is no longer
+ // being shown to the user.
+ MediaStreamDevices GetNonScreenCaptureDevices();
+
+ void AddStream(
+ const std::string& label,
+ const MediaStreamDevices& audio_devices,
+ const MediaStreamDevices& video_devices,
+ const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler);
+ void AddStream(const std::string& label, const MediaStreamDevice& device);
+ bool RemoveStream(const std::string& label);
+ void RemoveStreamDevice(const MediaStreamDevice& device);
+
+ // Get the video session_id given a label. The label identifies a stream.
+ int video_session_id(const std::string& label);
+ // Returns an audio session_id given a label.
+ int audio_session_id(const std::string& label);
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(MediaStreamDeviceObserverTest,
+ GetNonScreenCaptureDevices);
+
+ // Private class for keeping track of opened devices and who have
+ // opened it.
+ struct Stream;
+
+ // RenderFrameObserver override.
+ void OnInterfaceRequestForFrame(
+ const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle* interface_pipe) override;
+ void OnDestruct() override;
+
+ // mojom::MediaStreamDeviceObserver implementation.
+ void OnDeviceStopped(const std::string& label,
+ const MediaStreamDevice& device) override;
+
+ void BindMediaStreamDeviceObserverRequest(
+ mojom::MediaStreamDeviceObserverRequest request);
+
+ mojo::Binding<mojom::MediaStreamDeviceObserver> binding_;
+
+ // Used for DCHECKs so methods calls won't execute in the wrong thread.
+ base::ThreadChecker thread_checker_;
+
+ typedef std::map<std::string, Stream> LabelStreamMap;
+ LabelStreamMap label_stream_map_;
+
+ service_manager::BinderRegistry registry_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaStreamDeviceObserver);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_DEVICE_OBSERVER_H_ \ No newline at end of file
diff --git a/chromium/content/renderer/media/media_stream_device_observer_unittest.cc b/chromium/content/renderer/media/media_stream_device_observer_unittest.cc
new file mode 100644
index 00000000000..f82a56a11b7
--- /dev/null
+++ b/chromium/content/renderer/media/media_stream_device_observer_unittest.cc
@@ -0,0 +1,91 @@
+// 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/media/media_stream_device_observer.h"
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
+#include "content/public/common/media_stream_request.h"
+#include "content/renderer/media/mock_mojo_media_stream_dispatcher_host.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class MediaStreamDeviceObserverTest : public ::testing::Test {
+ public:
+ MediaStreamDeviceObserverTest()
+ : observer_(std::make_unique<MediaStreamDeviceObserver>(nullptr)) {}
+
+ void OnDeviceOpened(base::Closure quit_closure,
+ bool success,
+ const std::string& label,
+ const MediaStreamDevice& device) {
+ if (success) {
+ stream_label_ = label;
+ observer_->AddStream(label, device);
+ }
+
+ quit_closure.Run();
+ }
+
+ protected:
+ std::string stream_label_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ MockMojoMediaStreamDispatcherHost mock_dispatcher_host_;
+ std::unique_ptr<MediaStreamDeviceObserver> observer_;
+};
+
+TEST_F(MediaStreamDeviceObserverTest, GetNonScreenCaptureDevices) {
+ const int kRenderId = 3;
+ const int kRequestId1 = 5;
+ const int kRequestId2 = 7;
+
+ EXPECT_EQ(observer_->label_stream_map_.size(), 0u);
+
+ // OpenDevice request 1
+ base::RunLoop run_loop1;
+ mock_dispatcher_host_.OpenDevice(
+ kRenderId, kRequestId1, "device_path", MEDIA_DEVICE_VIDEO_CAPTURE,
+ base::BindOnce(&MediaStreamDeviceObserverTest::OnDeviceOpened,
+ base::Unretained(this), run_loop1.QuitClosure()));
+ run_loop1.Run();
+ std::string stream_label1 = stream_label_;
+
+ // OpenDevice request 2
+ base::RunLoop run_loop2;
+ mock_dispatcher_host_.OpenDevice(
+ kRenderId, kRequestId2, "screen_capture", MEDIA_DESKTOP_VIDEO_CAPTURE,
+ base::BindOnce(&MediaStreamDeviceObserverTest::OnDeviceOpened,
+ base::Unretained(this), run_loop2.QuitClosure()));
+ run_loop2.Run();
+ std::string stream_label2 = stream_label_;
+
+ EXPECT_EQ(observer_->label_stream_map_.size(), 2u);
+
+ // Only the device with type MEDIA_DEVICE_VIDEO_CAPTURE will be returned.
+ MediaStreamDevices video_devices = observer_->GetNonScreenCaptureDevices();
+ EXPECT_EQ(video_devices.size(), 1u);
+ EXPECT_EQ(video_devices[0].type, MEDIA_DEVICE_VIDEO_CAPTURE);
+
+ // Close the device from request 2.
+ observer_->RemoveStream(stream_label2);
+ EXPECT_EQ(observer_->video_session_id(stream_label2),
+ MediaStreamDevice::kNoId);
+
+ // Close the device from request 1.
+ observer_->RemoveStream(stream_label1);
+ EXPECT_EQ(observer_->video_session_id(stream_label1),
+ MediaStreamDevice::kNoId);
+
+ // Verify that the request have been completed.
+ EXPECT_EQ(observer_->label_stream_map_.size(), 0u);
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_dispatcher.cc b/chromium/content/renderer/media/media_stream_dispatcher.cc
deleted file mode 100644
index b83c2a22b71..00000000000
--- a/chromium/content/renderer/media/media_stream_dispatcher.cc
+++ /dev/null
@@ -1,370 +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/media/media_stream_dispatcher.h"
-
-#include <stddef.h>
-
-#include "base/bind_helpers.h"
-#include "base/logging.h"
-#include "content/child/child_thread_impl.h"
-#include "content/public/common/service_names.mojom.h"
-#include "content/public/renderer/render_frame.h"
-#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "url/origin.h"
-
-namespace content {
-
-namespace {
-
-bool RemoveStreamDeviceFromArray(const MediaStreamDevice& device,
- MediaStreamDevices* devices) {
- for (MediaStreamDevices::iterator device_it = devices->begin();
- device_it != devices->end(); ++device_it) {
- if (device_it->IsSameDevice(device)) {
- devices->erase(device_it);
- return true;
- }
- }
- return false;
-}
-
-} // namespace
-
-// A request is identified by pair (request_id, handler), or ipc_request.
-// There could be multiple clients making requests and each has its own
-// request_id sequence.
-// The ipc_request is garanteed to be unique when it's created in
-// MediaStreamDispatcher.
-struct MediaStreamDispatcher::Request {
- Request(const base::WeakPtr<MediaStreamDispatcherEventHandler>& handler,
- int request_id,
- int ipc_request)
- : handler(handler),
- request_id(request_id),
- ipc_request(ipc_request) {
- }
- bool IsThisRequest(
- int request_id1,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& handler1) {
- return (request_id1 == request_id && handler1.get() == handler.get());
- }
- base::WeakPtr<MediaStreamDispatcherEventHandler> handler;
- int request_id;
- int ipc_request;
-};
-
-struct MediaStreamDispatcher::Stream {
- Stream() {}
- ~Stream() {}
- base::WeakPtr<MediaStreamDispatcherEventHandler> handler;
- MediaStreamDevices audio_devices;
- MediaStreamDevices video_devices;
-};
-
-MediaStreamDispatcher::MediaStreamDispatcher(RenderFrame* render_frame)
- : RenderFrameObserver(render_frame),
- dispatcher_host_(nullptr),
- binding_(this),
- next_ipc_id_(0) {
- registry_.AddInterface(
- base::Bind(&MediaStreamDispatcher::BindMediaStreamDispatcherRequest,
- base::Unretained(this)));
-}
-
-MediaStreamDispatcher::~MediaStreamDispatcher() {}
-
-void MediaStreamDispatcher::GenerateStream(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler,
- const StreamControls& controls,
- const url::Origin& security_origin,
- bool is_processing_user_gesture) {
- DVLOG(1) << __func__ << " request_id= " << request_id;
- DCHECK(thread_checker_.CalledOnValidThread());
-
- requests_.push_back(Request(event_handler, request_id, next_ipc_id_));
- GetMediaStreamDispatcherHost()->GenerateStream(routing_id(), next_ipc_id_++,
- controls, security_origin,
- is_processing_user_gesture);
-}
-
-void MediaStreamDispatcher::CancelGenerateStream(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler) {
- DVLOG(1) << __func__ << " request_id= " << request_id;
- DCHECK(thread_checker_.CalledOnValidThread());
-
- for (auto it = requests_.begin(); it != requests_.end(); ++it) {
- if (it->IsThisRequest(request_id, event_handler)) {
- int ipc_request = it->ipc_request;
- requests_.erase(it);
- GetMediaStreamDispatcherHost()->CancelGenerateStream(routing_id(),
- ipc_request);
- break;
- }
- }
-}
-
-void MediaStreamDispatcher::StopStreamDevice(const MediaStreamDevice& device) {
- DVLOG(1) << __func__ << " device_id= " << device.id;
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // Remove |device| from all streams in |label_stream_map_|.
- bool device_found = false;
- LabelStreamMap::iterator stream_it = label_stream_map_.begin();
- while (stream_it != label_stream_map_.end()) {
- MediaStreamDevices& audio_devices = stream_it->second.audio_devices;
- MediaStreamDevices& video_devices = stream_it->second.video_devices;
-
- if (RemoveStreamDeviceFromArray(device, &audio_devices) ||
- RemoveStreamDeviceFromArray(device, &video_devices)) {
- device_found = true;
- if (audio_devices.empty() && video_devices.empty()) {
- label_stream_map_.erase(stream_it++);
- continue;
- }
- }
- ++stream_it;
- }
- DCHECK(device_found);
-
- GetMediaStreamDispatcherHost()->StopStreamDevice(routing_id(), device.id);
-}
-
-void MediaStreamDispatcher::OpenDevice(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler,
- const std::string& device_id,
- MediaStreamType type,
- const url::Origin& security_origin) {
- DVLOG(1) << __func__ << " request_id= " << request_id;
- DCHECK(thread_checker_.CalledOnValidThread());
-
- requests_.push_back(Request(event_handler, request_id, next_ipc_id_));
- GetMediaStreamDispatcherHost()->OpenDevice(routing_id(), next_ipc_id_++,
- device_id, type, security_origin);
-}
-
-void MediaStreamDispatcher::CancelOpenDevice(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler) {
- DVLOG(1) << __func__ << " request_id= " << request_id;
- DCHECK(thread_checker_.CalledOnValidThread());
-
- CancelGenerateStream(request_id, event_handler);
-}
-
-void MediaStreamDispatcher::CloseDevice(const std::string& label) {
- DVLOG(1) << __func__ << " label= " << label;
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!label.empty());
-
- LabelStreamMap::iterator it = label_stream_map_.find(label);
- if (it == label_stream_map_.end())
- return;
- label_stream_map_.erase(it);
-
- GetMediaStreamDispatcherHost()->CloseDevice(label);
-}
-
-void MediaStreamDispatcher::OnStreamStarted(const std::string& label) {
- DVLOG(1) << __func__ << " label= " << label;
- DCHECK(thread_checker_.CalledOnValidThread());
-
- GetMediaStreamDispatcherHost()->StreamStarted(label);
-}
-
-MediaStreamDevices MediaStreamDispatcher::GetNonScreenCaptureDevices() {
- MediaStreamDevices video_devices;
- for (const auto& stream_it : label_stream_map_) {
- for (const auto& video_device : stream_it.second.video_devices) {
- if (!IsScreenCaptureMediaType(video_device.type))
- video_devices.push_back(video_device);
- }
- }
- return video_devices;
-}
-
-void MediaStreamDispatcher::OnInterfaceRequestForFrame(
- const std::string& interface_name,
- mojo::ScopedMessagePipeHandle* interface_pipe) {
- registry_.TryBindInterface(interface_name, interface_pipe);
-}
-
-void MediaStreamDispatcher::OnDestruct() {
- // Do not self-destruct. UserMediaClientImpl owns |this|.
-}
-
-void MediaStreamDispatcher::OnStreamGenerated(
- int32_t request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- for (auto it = requests_.begin(); it != requests_.end(); ++it) {
- Request& request = *it;
- if (request.ipc_request != request_id)
- continue;
- Stream new_stream;
- new_stream.handler = request.handler;
- new_stream.audio_devices = audio_devices;
- new_stream.video_devices = video_devices;
- label_stream_map_[label] = new_stream;
- if (request.handler.get()) {
- request.handler->OnStreamGenerated(request.request_id, label,
- audio_devices, video_devices);
- DVLOG(1) << __func__ << " request_id=" << request.request_id
- << " label=" << label;
- }
- requests_.erase(it);
- break;
- }
-}
-
-void MediaStreamDispatcher::OnStreamGenerationFailed(
- int32_t request_id,
- MediaStreamRequestResult result) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- for (auto it = requests_.begin(); it != requests_.end(); ++it) {
- Request& request = *it;
- if (request.ipc_request != request_id)
- continue;
- if (request.handler.get()) {
- request.handler->OnStreamGenerationFailed(request.request_id, result);
- DVLOG(1) << __func__ << " request_id=" << request.request_id;
- }
- requests_.erase(it);
- break;
- }
-}
-
-void MediaStreamDispatcher::OnDeviceOpened(int32_t request_id,
- const std::string& label,
- const MediaStreamDevice& device) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- for (auto it = requests_.begin(); it != requests_.end(); ++it) {
- Request& request = *it;
- if (request.ipc_request != request_id)
- continue;
- Stream new_stream;
- new_stream.handler = request.handler;
- if (IsAudioInputMediaType(device.type))
- new_stream.audio_devices.push_back(device);
- else if (IsVideoMediaType(device.type))
- new_stream.video_devices.push_back(device);
- else
- NOTREACHED();
-
- label_stream_map_[label] = new_stream;
- if (request.handler.get()) {
- request.handler->OnDeviceOpened(request.request_id, label, device);
- DVLOG(1) << __func__ << " request_id=" << request.request_id
- << " label=" << label;
- }
- requests_.erase(it);
- break;
- }
-}
-
-void MediaStreamDispatcher::OnDeviceOpenFailed(int32_t request_id) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- for (auto it = requests_.begin(); it != requests_.end(); ++it) {
- Request& request = *it;
- if (request.ipc_request != request_id)
- continue;
- if (request.handler.get()) {
- request.handler->OnDeviceOpenFailed(request.request_id);
- DVLOG(1) << __func__ << " request_id=" << request.request_id;
- }
- requests_.erase(it);
- break;
- }
-}
-
-void MediaStreamDispatcher::OnDeviceStopped(const std::string& label,
- const MediaStreamDevice& device) {
- DVLOG(1) << __func__ << " label=" << label << " device_id=" << device.id;
- DCHECK(thread_checker_.CalledOnValidThread());
-
- LabelStreamMap::iterator it = label_stream_map_.find(label);
- if (it == label_stream_map_.end()) {
- // This can happen if a user happen stop a the device from JS at the same
- // time as the underlying media device is unplugged from the system.
- return;
- }
- Stream* stream = &it->second;
- if (IsAudioInputMediaType(device.type))
- RemoveStreamDeviceFromArray(device, &stream->audio_devices);
- else
- RemoveStreamDeviceFromArray(device, &stream->video_devices);
-
- if (stream->handler.get())
- stream->handler->OnDeviceStopped(label, device);
-
- // |it| could have already been invalidated in the function call above. So we
- // need to check if |label| is still in |label_stream_map_| again.
- // Note: this is a quick fix to the crash caused by erasing the invalidated
- // iterator from |label_stream_map_| (crbug.com/616884). Future work needs to
- // be done to resolve this re-entrancy issue.
- it = label_stream_map_.find(label);
- if (it == label_stream_map_.end())
- return;
- stream = &it->second;
- if (stream->audio_devices.empty() && stream->video_devices.empty())
- label_stream_map_.erase(it);
-}
-
-void MediaStreamDispatcher::BindMediaStreamDispatcherRequest(
- mojom::MediaStreamDispatcherRequest request) {
- binding_.Bind(std::move(request));
-}
-
-const mojom::MediaStreamDispatcherHostPtr&
-MediaStreamDispatcher::GetMediaStreamDispatcherHost() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- if (!dispatcher_host_) {
- ChildThreadImpl::current()->GetConnector()->BindInterface(
- mojom::kBrowserServiceName, &dispatcher_host_);
- }
- return dispatcher_host_;
-};
-
-int MediaStreamDispatcher::audio_session_id(const std::string& label,
- int index) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- LabelStreamMap::iterator it = label_stream_map_.find(label);
- if (it == label_stream_map_.end() ||
- it->second.audio_devices.size() <= static_cast<size_t>(index)) {
- return MediaStreamDevice::kNoId;
- }
- return it->second.audio_devices[index].session_id;
-}
-
-bool MediaStreamDispatcher::IsStream(const std::string& label) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- return label_stream_map_.find(label) != label_stream_map_.end();
-}
-
-int MediaStreamDispatcher::video_session_id(const std::string& label,
- int index) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- LabelStreamMap::iterator it = label_stream_map_.find(label);
- if (it == label_stream_map_.end() ||
- it->second.video_devices.size() <= static_cast<size_t>(index)) {
- return MediaStreamDevice::kNoId;
- }
- return it->second.video_devices[index].session_id;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_dispatcher.h b/chromium/content/renderer/media/media_stream_dispatcher.h
deleted file mode 100644
index 3a763b7835e..00000000000
--- a/chromium/content/renderer/media/media_stream_dispatcher.h
+++ /dev/null
@@ -1,158 +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_MEDIA_MEDIA_STREAM_DISPATCHER_H_
-#define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_DISPATCHER_H_
-
-#include <list>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "content/common/content_export.h"
-#include "content/common/media/media_stream.mojom.h"
-#include "content/public/common/media_stream_request.h"
-#include "content/public/renderer/render_frame_observer.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "services/service_manager/public/cpp/binder_registry.h"
-
-namespace url {
-class Origin;
-}
-
-namespace content {
-
-class MediaStreamDispatcherEventHandler;
-
-// MediaStreamDispatcher is a delegate for the Media Stream API messages.
-// MediaStreams are used by WebKit to open media devices such as Video Capture
-// and Audio input devices.
-// It's the complement of MediaStreamDispatcherHost (owned by
-// RenderProcessHostImpl).
-class CONTENT_EXPORT MediaStreamDispatcher
- : public RenderFrameObserver,
- public mojom::MediaStreamDispatcher {
- public:
- explicit MediaStreamDispatcher(RenderFrame* render_frame);
- ~MediaStreamDispatcher() override;
-
- // Request a new media stream to be created.
- // This can be used either by WebKit or a plugin.
- // Note: The event_handler must be valid for as long as the stream exists.
- virtual void GenerateStream(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler,
- const StreamControls& controls,
- const url::Origin& security_origin,
- bool is_processing_user_gesture);
-
- // Cancel the request for a new media stream to be created.
- virtual void CancelGenerateStream(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler);
-
- // Stop a started device that has been requested by calling GenerateStream.
- virtual void StopStreamDevice(const MediaStreamDevice& device);
-
- // Request to open a device.
- void OpenDevice(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler,
- const std::string& device_id,
- MediaStreamType type,
- const url::Origin& security_origin);
-
- // Cancel the request to open a device.
- virtual void CancelOpenDevice(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler);
-
- // Close a started device. |label| is provided in OnDeviceOpened.
- void CloseDevice(const std::string& label);
-
- // This method is called when the stream is started successfully.
- void OnStreamStarted(const std::string& label);
-
- // Get all the media devices of video capture, e.g. webcam. This is the set
- // of devices that should be suspended when the content frame is no longer
- // being shown to the user.
- MediaStreamDevices GetNonScreenCaptureDevices();
-
- // Check if the label is a valid stream.
- virtual bool IsStream(const std::string& label);
- // Get the video session_id given a label. The label identifies a stream.
- // index is the index in the video_device_array of the stream.
- virtual int video_session_id(const std::string& label, int index);
- // Returns an audio session_id given a label and an index.
- virtual int audio_session_id(const std::string& label, int index);
-
- private:
- friend class MediaStreamDispatcherTest;
- friend class UserMediaClientImplTest;
- FRIEND_TEST_ALL_PREFIXES(MediaStreamDispatcherTest, BasicVideoDevice);
- FRIEND_TEST_ALL_PREFIXES(MediaStreamDispatcherTest, TestFailure);
- FRIEND_TEST_ALL_PREFIXES(MediaStreamDispatcherTest, CancelGenerateStream);
- FRIEND_TEST_ALL_PREFIXES(MediaStreamDispatcherTest,
- GetNonScreenCaptureDevices);
- FRIEND_TEST_ALL_PREFIXES(MediaStreamDispatcherTest, DeviceClosed);
-
- struct Request;
-
- // Private class for keeping track of opened devices and who have
- // opened it.
- struct Stream;
-
- // RenderFrameObserver override.
- void OnInterfaceRequestForFrame(
- const std::string& interface_name,
- mojo::ScopedMessagePipeHandle* interface_pipe) override;
- void OnDestruct() override;
-
- // mojom::MediaStreamDispatcher implementation.
- void OnStreamGenerated(int32_t request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) override;
- void OnStreamGenerationFailed(int32_t request_id,
- MediaStreamRequestResult result) override;
- void OnDeviceOpened(int32_t request_id,
- const std::string& label,
- const MediaStreamDevice& device) override;
- void OnDeviceOpenFailed(int32_t request_id) override;
- void OnDeviceStopped(const std::string& label,
- const MediaStreamDevice& device) override;
-
- void BindMediaStreamDispatcherRequest(
- mojom::MediaStreamDispatcherRequest request);
-
- const mojom::MediaStreamDispatcherHostPtr& GetMediaStreamDispatcherHost();
-
- mojom::MediaStreamDispatcherHostPtr dispatcher_host_;
- mojo::Binding<mojom::MediaStreamDispatcher> binding_;
-
- // Used for DCHECKs so methods calls won't execute in the wrong thread.
- base::ThreadChecker thread_checker_;
-
- int next_ipc_id_;
- typedef std::map<std::string, Stream> LabelStreamMap;
- LabelStreamMap label_stream_map_;
-
- // List of calls made to the browser process that have not yet completed or
- // been canceled.
- typedef std::list<Request> RequestList;
- RequestList requests_;
-
- service_manager::BinderRegistry registry_;
-
- DISALLOW_COPY_AND_ASSIGN(MediaStreamDispatcher);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_DISPATCHER_H_
diff --git a/chromium/content/renderer/media/media_stream_dispatcher_eventhandler.h b/chromium/content/renderer/media/media_stream_dispatcher_eventhandler.h
index f5b663e64ca..369e40b4458 100644
--- a/chromium/content/renderer/media/media_stream_dispatcher_eventhandler.h
+++ b/chromium/content/renderer/media/media_stream_dispatcher_eventhandler.h
@@ -14,28 +14,8 @@ namespace content {
class CONTENT_EXPORT MediaStreamDispatcherEventHandler {
public:
- // A new media stream have been created.
- virtual void OnStreamGenerated(int request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) = 0;
-
- // Creation of a new media stream failed. The user might have denied access
- // to the requested devices or no device is available.
- virtual void OnStreamGenerationFailed(int request_id,
- MediaStreamRequestResult result) = 0;
-
- // A device has been stopped in the browser processes.
- virtual void OnDeviceStopped(const std::string& label,
- const MediaStreamDevice& device) = 0;
-
- // A device has been opened.
- virtual void OnDeviceOpened(int request_id,
- const std::string& label,
- const MediaStreamDevice& device) = 0;
-
- // Failed to open the device.
- virtual void OnDeviceOpenFailed(int request_id) = 0;
+ // A device has been stopped in the browser process.
+ virtual void OnDeviceStopped(const MediaStreamDevice& device) = 0;
protected:
virtual ~MediaStreamDispatcherEventHandler() {}
diff --git a/chromium/content/renderer/media/media_stream_dispatcher_unittest.cc b/chromium/content/renderer/media/media_stream_dispatcher_unittest.cc
deleted file mode 100644
index 88c7fd32dda..00000000000
--- a/chromium/content/renderer/media/media_stream_dispatcher_unittest.cc
+++ /dev/null
@@ -1,376 +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/media/media_stream_dispatcher.h"
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-
-#include "base/memory/weak_ptr.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/test/scoped_task_environment.h"
-#include "content/public/common/media_stream_request.h"
-#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
-#include "content/renderer/media/mock_mojo_media_stream_dispatcher_host.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-
-namespace content {
-
-const int kAudioSessionId = 3;
-const int kVideoSessionId = 5;
-const int kScreenSessionId = 7;
-const int kRequestId1 = 10;
-const int kRequestId2 = 20;
-
-class MockMediaStreamDispatcherEventHandler
- : public MediaStreamDispatcherEventHandler,
- public base::SupportsWeakPtr<MockMediaStreamDispatcherEventHandler> {
- public:
- MockMediaStreamDispatcherEventHandler() : request_id_(-1) {}
-
- void OnStreamGenerated(int request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) override {
- request_id_ = request_id;
- label_ = label;
- if (audio_devices.size()) {
- DCHECK(audio_devices.size() == 1);
- audio_device_ = audio_devices[0];
- }
- if (video_devices.size()) {
- DCHECK(video_devices.size() == 1);
- video_device_ = video_devices[0];
- }
- }
-
- void OnStreamGenerationFailed(int request_id,
- MediaStreamRequestResult result) override {
- request_id_ = request_id;
- }
-
- void OnDeviceStopped(const std::string& label,
- const MediaStreamDevice& device) override {
- device_stopped_label_ = label;
- if (IsVideoMediaType(device.type))
- EXPECT_TRUE(device.IsSameDevice(video_device_));
- if (IsAudioInputMediaType(device.type))
- EXPECT_TRUE(device.IsSameDevice(audio_device_));
- }
-
- void OnDeviceOpened(int request_id,
- const std::string& label,
- const MediaStreamDevice& device) override {
- request_id_ = request_id;
- label_ = label;
- }
-
- void OnDeviceOpenFailed(int request_id) override { request_id_ = request_id; }
-
- void ResetStoredParameters() {
- request_id_ = -1;
- label_.clear();
- device_stopped_label_.clear();
- audio_device_ = MediaStreamDevice();
- video_device_ = MediaStreamDevice();
- }
-
- int request_id_;
- std::string label_;
- std::string device_stopped_label_;
- MediaStreamDevice audio_device_;
- MediaStreamDevice video_device_;
-};
-
-class MediaStreamDispatcherTest : public ::testing::Test {
- public:
- MediaStreamDispatcherTest()
- : dispatcher_(base::MakeUnique<MediaStreamDispatcher>(nullptr)),
- handler_(base::MakeUnique<MockMediaStreamDispatcherEventHandler>()),
- controls_(true, true),
- security_origin_(GURL("http://test.com")) {
- mojom::MediaStreamDispatcherHostPtr dispatcher_host =
- mock_dispatcher_host_.CreateInterfacePtrAndBind();
- dispatcher_->dispatcher_host_ = std::move(dispatcher_host);
- }
-
- // Generates a request for a MediaStream and returns the request id that is
- // used in mojo IPC. Use this returned id in CompleteGenerateStream to
- // identify the request.
- int GenerateStream(int request_id) {
- int next_ipc_id = dispatcher_->next_ipc_id_;
- dispatcher_->GenerateStream(request_id, handler_->AsWeakPtr(), controls_,
- security_origin_, true);
- return next_ipc_id;
- }
-
- // CompleteGenerateStream calls the MediaStreamDispathcer::OnStreamGenerated.
- // |ipc_id| must be the the id returned by GenerateStream.
- std::string CompleteGenerateStream(int ipc_id,
- int request_id) {
- MediaStreamDevices audio_devices(controls_.audio.requested ? 1 : 0);
- if (controls_.audio.requested) {
- MediaStreamDevice audio_device;
- audio_device.name = "Microphone";
- audio_device.type = MEDIA_DEVICE_AUDIO_CAPTURE;
- audio_device.session_id = kAudioSessionId;
- audio_devices[0] = audio_device;
- }
-
- MediaStreamDevices video_devices(controls_.video.requested ? 1 : 0);
- if (controls_.video.requested) {
- MediaStreamDevice video_device;
- video_device.name = "Camera";
- video_device.type = MEDIA_DEVICE_VIDEO_CAPTURE;
- video_device.session_id = kVideoSessionId;
- video_devices[0] = video_device;
- }
-
- std::string label = "stream" + base::IntToString(ipc_id);
-
- handler_->ResetStoredParameters();
- dispatcher_->OnStreamGenerated(ipc_id, label, audio_devices, video_devices);
-
- EXPECT_EQ(handler_->request_id_, request_id);
- EXPECT_EQ(handler_->label_, label);
-
- if (controls_.audio.requested)
- EXPECT_EQ(dispatcher_->audio_session_id(label, 0), kAudioSessionId);
-
- if (controls_.video.requested)
- EXPECT_EQ(dispatcher_->video_session_id(label, 0), kVideoSessionId);
-
- return label;
- }
-
- protected:
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- MockMojoMediaStreamDispatcherHost mock_dispatcher_host_;
- std::unique_ptr<MediaStreamDispatcher> dispatcher_;
- std::unique_ptr<MockMediaStreamDispatcherEventHandler> handler_;
- StreamControls controls_;
- url::Origin security_origin_;
-};
-
-TEST_F(MediaStreamDispatcherTest, GenerateStreamAndStopDevices) {
- int ipc_request_id1 = GenerateStream(kRequestId1);
- int ipc_request_id2 = GenerateStream(kRequestId2);
- EXPECT_NE(ipc_request_id1, ipc_request_id2);
-
- // Complete the creation of stream1.
- const std::string& label1 =
- CompleteGenerateStream(ipc_request_id1, kRequestId1);
-
- // Complete the creation of stream2.
- const std::string& label2 =
- CompleteGenerateStream(ipc_request_id2, kRequestId2);
-
- // Stop the actual audio device and verify that there is no valid
- // |session_id|.
- dispatcher_->StopStreamDevice(handler_->audio_device_);
- EXPECT_EQ(dispatcher_->audio_session_id(label1, 0), MediaStreamDevice::kNoId);
- EXPECT_EQ(dispatcher_->audio_session_id(label2, 0), MediaStreamDevice::kNoId);
-
- // Stop the actual video device and verify that there is no valid
- // |session_id|.
- dispatcher_->StopStreamDevice(handler_->video_device_);
- EXPECT_EQ(dispatcher_->video_session_id(label1, 0), MediaStreamDevice::kNoId);
- EXPECT_EQ(dispatcher_->video_session_id(label2, 0), MediaStreamDevice::kNoId);
-}
-
-TEST_F(MediaStreamDispatcherTest, BasicVideoDevice) {
- MediaStreamDevice video_device;
- video_device.name = "Camera";
- video_device.id = "device_path";
- video_device.type = MEDIA_DEVICE_VIDEO_CAPTURE;
- video_device.session_id = kVideoSessionId;
-
- EXPECT_EQ(dispatcher_->requests_.size(), size_t(0));
- EXPECT_EQ(dispatcher_->label_stream_map_.size(), size_t(0));
-
- int ipc_request_id1 = dispatcher_->next_ipc_id_;
- dispatcher_->OpenDevice(kRequestId1, handler_->AsWeakPtr(), video_device.id,
- MEDIA_DEVICE_VIDEO_CAPTURE, security_origin_);
- int ipc_request_id2 = dispatcher_->next_ipc_id_;
- EXPECT_NE(ipc_request_id1, ipc_request_id2);
- dispatcher_->OpenDevice(kRequestId2, handler_->AsWeakPtr(), video_device.id,
- MEDIA_DEVICE_VIDEO_CAPTURE, security_origin_);
- EXPECT_EQ(dispatcher_->requests_.size(), size_t(2));
-
- // Complete the OpenDevice of request 1.
- std::string stream_label1 = std::string("stream1");
- dispatcher_->OnDeviceOpened(ipc_request_id1, stream_label1, video_device);
- EXPECT_EQ(handler_->request_id_, kRequestId1);
-
- // Complete the OpenDevice of request 2.
- std::string stream_label2 = std::string("stream2");
- dispatcher_->OnDeviceOpened(ipc_request_id2, stream_label2, video_device);
- EXPECT_EQ(handler_->request_id_, kRequestId2);
-
- EXPECT_EQ(dispatcher_->requests_.size(), size_t(0));
- EXPECT_EQ(dispatcher_->label_stream_map_.size(), size_t(2));
-
- // Check the video_session_id.
- EXPECT_EQ(dispatcher_->video_session_id(stream_label1, 0), kVideoSessionId);
- EXPECT_EQ(dispatcher_->video_session_id(stream_label2, 0), kVideoSessionId);
-
- // Close the device from request 2.
- dispatcher_->CloseDevice(stream_label2);
- EXPECT_EQ(dispatcher_->video_session_id(stream_label2, 0),
- MediaStreamDevice::kNoId);
-
- // Close the device from request 1.
- dispatcher_->CloseDevice(stream_label1);
- EXPECT_EQ(dispatcher_->video_session_id(stream_label1, 0),
- MediaStreamDevice::kNoId);
- EXPECT_EQ(dispatcher_->label_stream_map_.size(), size_t(0));
-
- // Verify that the request have been completed.
- EXPECT_EQ(dispatcher_->label_stream_map_.size(), size_t(0));
- EXPECT_EQ(dispatcher_->requests_.size(), size_t(0));
-}
-
-TEST_F(MediaStreamDispatcherTest, TestFailure) {
- // Test failure when creating a stream.
- int ipc_request_id1 = GenerateStream(kRequestId1);
- dispatcher_->OnStreamGenerationFailed(ipc_request_id1,
- MEDIA_DEVICE_PERMISSION_DENIED);
-
- // Verify that the request have been completed.
- EXPECT_EQ(handler_->request_id_, kRequestId1);
- EXPECT_EQ(dispatcher_->requests_.size(), size_t(0));
-
- // Create a new stream.
- ipc_request_id1 = GenerateStream(kRequestId1);
-
- MediaStreamDevices audio_devices(1);
- MediaStreamDevice audio_device;
- audio_device.name = "Microphone";
- audio_device.type = MEDIA_DEVICE_AUDIO_CAPTURE;
- audio_device.session_id = kAudioSessionId;
- audio_devices[0] = audio_device;
-
- MediaStreamDevices video_devices(1);
- MediaStreamDevice video_device;
- video_device.name = "Camera";
- video_device.type = MEDIA_DEVICE_VIDEO_CAPTURE;
- video_device.session_id = kVideoSessionId;
- video_devices[0] = video_device;
-
- // Complete the creation of stream1.
- std::string stream_label1 = std::string("stream1");
- dispatcher_->OnStreamGenerated(ipc_request_id1, stream_label1, audio_devices,
- video_devices);
- EXPECT_EQ(handler_->request_id_, kRequestId1);
- EXPECT_EQ(handler_->label_, stream_label1);
- EXPECT_EQ(dispatcher_->video_session_id(stream_label1, 0), kVideoSessionId);
-}
-
-TEST_F(MediaStreamDispatcherTest, CancelGenerateStream) {
- int ipc_request_id1 = GenerateStream(kRequestId1);
- GenerateStream(kRequestId2);
-
- EXPECT_EQ(2u, dispatcher_->requests_.size());
- dispatcher_->CancelGenerateStream(kRequestId2, handler_->AsWeakPtr());
- EXPECT_EQ(1u, dispatcher_->requests_.size());
-
- // Complete the creation of stream1.
- MediaStreamDevice audio_device;
- audio_device.name = "Microphone";
- audio_device.type = MEDIA_DEVICE_AUDIO_CAPTURE;
- audio_device.session_id = kAudioSessionId;
- MediaStreamDevices audio_devices(1);
- audio_devices[0] = audio_device;
-
- MediaStreamDevice video_device;
- video_device.name = "Camera";
- video_device.type = MEDIA_DEVICE_VIDEO_CAPTURE;
- video_device.session_id = kVideoSessionId;
- MediaStreamDevices video_devices(1);
- video_devices[0] = video_device;
-
- std::string stream_label1 = "stream1";
- dispatcher_->OnStreamGenerated(ipc_request_id1, stream_label1, audio_devices,
- video_devices);
- EXPECT_EQ(handler_->request_id_, kRequestId1);
- EXPECT_EQ(handler_->label_, stream_label1);
- EXPECT_EQ(0u, dispatcher_->requests_.size());
-}
-
-// Test that the MediaStreamDispatcherEventHandler is notified when the message
-// OnDeviceStopped is received.
-TEST_F(MediaStreamDispatcherTest, DeviceClosed) {
- int ipc_request_id = GenerateStream(kRequestId1);
- const std::string& label =
- CompleteGenerateStream(ipc_request_id, kRequestId1);
-
- dispatcher_->OnDeviceStopped(label, handler_->video_device_);
- // Verify that MediaStreamDispatcherEventHandler::OnDeviceStopped has been
- // called.
- EXPECT_EQ(label, handler_->device_stopped_label_);
- EXPECT_EQ(dispatcher_->video_session_id(label, 0), MediaStreamDevice::kNoId);
-}
-
-TEST_F(MediaStreamDispatcherTest, GetNonScreenCaptureDevices) {
- MediaStreamDevice video_device;
- video_device.name = "Camera";
- video_device.id = "device_path";
- video_device.type = MEDIA_DEVICE_VIDEO_CAPTURE;
- video_device.session_id = kVideoSessionId;
-
- MediaStreamDevice screen_device;
- screen_device.name = "Screen";
- screen_device.id = "screen_capture";
- screen_device.type = MEDIA_DESKTOP_VIDEO_CAPTURE;
- screen_device.session_id = kScreenSessionId;
-
- EXPECT_EQ(dispatcher_->requests_.size(), 0u);
- EXPECT_EQ(dispatcher_->label_stream_map_.size(), 0u);
-
- int ipc_request_id1 = dispatcher_->next_ipc_id_;
- dispatcher_->OpenDevice(kRequestId1, handler_->AsWeakPtr(), video_device.id,
- MEDIA_DEVICE_VIDEO_CAPTURE, security_origin_);
- int ipc_request_id2 = dispatcher_->next_ipc_id_;
- EXPECT_NE(ipc_request_id1, ipc_request_id2);
- dispatcher_->OpenDevice(kRequestId2, handler_->AsWeakPtr(), screen_device.id,
- MEDIA_DESKTOP_VIDEO_CAPTURE, security_origin_);
- EXPECT_EQ(dispatcher_->requests_.size(), 2u);
-
- // Complete the OpenDevice of request 1.
- std::string stream_label1 = std::string("stream1");
- dispatcher_->OnDeviceOpened(ipc_request_id1, stream_label1, video_device);
- EXPECT_EQ(handler_->request_id_, kRequestId1);
-
- // Complete the OpenDevice of request 2.
- std::string stream_label2 = std::string("stream2");
- dispatcher_->OnDeviceOpened(ipc_request_id2, stream_label2, screen_device);
- EXPECT_EQ(handler_->request_id_, kRequestId2);
-
- EXPECT_EQ(dispatcher_->requests_.size(), 0u);
- EXPECT_EQ(dispatcher_->label_stream_map_.size(), 2u);
-
- // Only the device with type MEDIA_DEVICE_VIDEO_CAPTURE will be returned.
- MediaStreamDevices video_devices = dispatcher_->GetNonScreenCaptureDevices();
- EXPECT_EQ(video_devices.size(), 1u);
-
- // Close the device from request 2.
- dispatcher_->CloseDevice(stream_label2);
- EXPECT_EQ(dispatcher_->video_session_id(stream_label2, 0),
- MediaStreamDevice::kNoId);
-
- // Close the device from request 1.
- dispatcher_->CloseDevice(stream_label1);
- EXPECT_EQ(dispatcher_->video_session_id(stream_label1, 0),
- MediaStreamDevice::kNoId);
-
- // Verify that the request have been completed.
- EXPECT_EQ(dispatcher_->label_stream_map_.size(), 0u);
- EXPECT_EQ(dispatcher_->requests_.size(), 0u);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_renderer_factory_impl.cc b/chromium/content/renderer/media/media_stream_renderer_factory_impl.cc
index 8c664341110..27210034255 100644
--- a/chromium/content/renderer/media/media_stream_renderer_factory_impl.cc
+++ b/chromium/content/renderer/media/media_stream_renderer_factory_impl.cc
@@ -74,7 +74,7 @@ MediaStreamRendererFactoryImpl::GetVideoRenderer(
web_stream.VideoTracks(video_tracks);
if (video_tracks.IsEmpty() ||
!MediaStreamVideoTrack::GetTrack(video_tracks[0])) {
- return NULL;
+ return nullptr;
}
return new MediaStreamVideoRendererSink(video_tracks[0], error_cb, repaint_cb,
diff --git a/chromium/content/renderer/media/media_stream_source.cc b/chromium/content/renderer/media/media_stream_source.cc
index a4f76abebd8..94c59a35c84 100644
--- a/chromium/content/renderer/media/media_stream_source.cc
+++ b/chromium/content/renderer/media/media_stream_source.cc
@@ -22,6 +22,10 @@ MediaStreamSource::~MediaStreamSource() {
void MediaStreamSource::StopSource() {
DCHECK(thread_checker_.CalledOnValidThread());
DoStopSource();
+ FinalizeStopSource();
+}
+
+void MediaStreamSource::FinalizeStopSource() {
if (!stop_callback_.is_null())
base::ResetAndReturn(&stop_callback_).Run(Owner());
Owner().SetReadyState(blink::WebMediaStreamSource::kReadyStateEnded);
diff --git a/chromium/content/renderer/media/media_stream_source.h b/chromium/content/renderer/media/media_stream_source.h
index 3c1da929883..215bf9e3044 100644
--- a/chromium/content/renderer/media/media_stream_source.h
+++ b/chromium/content/renderer/media/media_stream_source.h
@@ -36,9 +36,7 @@ class CONTENT_EXPORT MediaStreamSource
// JavaScript call to GetUserMedia, e.g., a camera or microphone.
const MediaStreamDevice& device() const { return device_; }
- // Stops the source (by calling DoStopSource()). This runs the
- // |stop_callback_| (if set), and then sets the
- // WebMediaStreamSource::readyState to ended.
+ // Stops the source (by calling DoStopSource()) and runs FinalizeStopSource().
void StopSource();
// Sets the source's state to muted or to live.
@@ -60,6 +58,11 @@ class CONTENT_EXPORT MediaStreamSource
// its own Stop method.
virtual void DoStopSource() = 0;
+ // Runs the stop callback (if set) and sets the
+ // WebMediaStreamSource::readyState to ended. This can be used by
+ // implementations to implement custom stop methods.
+ void FinalizeStopSource();
+
private:
MediaStreamDevice device_;
SourceStoppedCallback stop_callback_;
diff --git a/chromium/content/renderer/media/media_stream_track.h b/chromium/content/renderer/media/media_stream_track.h
index ae7fc1fba3c..e5fdf6d75f3 100644
--- a/chromium/content/renderer/media/media_stream_track.h
+++ b/chromium/content/renderer/media/media_stream_track.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/threading/thread_checker.h"
@@ -32,7 +33,10 @@ class CONTENT_EXPORT MediaStreamTrack
virtual void SetContentHint(
blink::WebMediaStreamTrack::ContentHintType content_hint) = 0;
- virtual void Stop() = 0;
+ // If |callback| is not null, it is invoked when the track has stopped.
+ virtual void StopAndNotify(base::OnceClosure callback) = 0;
+
+ void Stop() { StopAndNotify(base::OnceClosure()); }
// TODO(hta): Make method pure virtual when all tracks have the method.
void GetSettings(blink::WebMediaStreamTrack::Settings& settings) override {}
diff --git a/chromium/content/renderer/media/media_stream_video_capturer_source.cc b/chromium/content/renderer/media/media_stream_video_capturer_source.cc
index 22fc3bf212a..a148e7ac75c 100644
--- a/chromium/content/renderer/media/media_stream_video_capturer_source.cc
+++ b/chromium/content/renderer/media/media_stream_video_capturer_source.cc
@@ -161,9 +161,7 @@ void LocalVideoCapturerSource::OnStateUpdate(VideoCaptureState state) {
MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource(
const SourceStoppedCallback& stop_callback,
std::unique_ptr<media::VideoCapturerSource> source)
- : RenderFrameObserver(nullptr),
- dispatcher_host_(nullptr),
- source_(std::move(source)) {
+ : dispatcher_host_(nullptr), source_(std::move(source)) {
media::VideoCaptureFormats preferred_formats = source_->GetPreferredFormats();
if (!preferred_formats.empty())
capture_params_.requested_format = preferred_formats.front();
@@ -173,10 +171,8 @@ MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource(
MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource(
const SourceStoppedCallback& stop_callback,
const MediaStreamDevice& device,
- const media::VideoCaptureParams& capture_params,
- RenderFrame* render_frame)
- : RenderFrameObserver(render_frame),
- dispatcher_host_(nullptr),
+ const media::VideoCaptureParams& capture_params)
+ : dispatcher_host_(nullptr),
source_(new LocalVideoCapturerSource(device.session_id)),
capture_params_(capture_params) {
SetStopCallback(stop_callback);
@@ -224,12 +220,18 @@ void MediaStreamVideoCapturerSource::StopSourceImpl() {
}
void MediaStreamVideoCapturerSource::StopSourceForRestartImpl() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (state_ != STARTED) {
OnStopForRestartDone(false);
return;
}
state_ = STOPPING_FOR_RESTART;
source_->StopCapture();
+
+ // Force state update for nondevice sources, since they do not
+ // automatically update state after StopCapture().
+ if (device().type == MEDIA_NO_SERVICE)
+ OnRunStateChanged(capture_params_, false);
}
void MediaStreamVideoCapturerSource::RestartSourceImpl(
diff --git a/chromium/content/renderer/media/media_stream_video_capturer_source.h b/chromium/content/renderer/media/media_stream_video_capturer_source.h
index 4c01d3808e3..7ff5461cd73 100644
--- a/chromium/content/renderer/media/media_stream_video_capturer_source.h
+++ b/chromium/content/renderer/media/media_stream_video_capturer_source.h
@@ -13,7 +13,6 @@
#include "base/threading/thread_checker.h"
#include "content/common/media/media_stream.mojom.h"
#include "content/common/media/video_capture.h"
-#include "content/public/renderer/render_frame_observer.h"
#include "content/renderer/media/media_stream_video_source.h"
namespace media {
@@ -27,8 +26,7 @@ namespace content {
// Render thread. Objects can be constructed either by indicating a |device| to
// look for, or by plugging in a |source| constructed elsewhere.
class CONTENT_EXPORT MediaStreamVideoCapturerSource
- : public MediaStreamVideoSource,
- public RenderFrameObserver {
+ : public MediaStreamVideoSource {
public:
MediaStreamVideoCapturerSource(
const SourceStoppedCallback& stop_callback,
@@ -36,8 +34,7 @@ class CONTENT_EXPORT MediaStreamVideoCapturerSource
MediaStreamVideoCapturerSource(
const SourceStoppedCallback& stop_callback,
const MediaStreamDevice& device,
- const media::VideoCaptureParams& capture_params,
- RenderFrame* render_frame);
+ const media::VideoCaptureParams& capture_params);
~MediaStreamVideoCapturerSource() override;
private:
@@ -61,9 +58,6 @@ class CONTENT_EXPORT MediaStreamVideoCapturerSource
base::Optional<media::VideoCaptureParams> GetCurrentCaptureParams()
const override;
- // RenderFrameObserver implementation.
- void OnDestruct() final {}
-
// Method to bind as RunningCallback in VideoCapturerSource::StartCapture().
void OnRunStateChanged(const media::VideoCaptureParams& new_capture_params,
bool is_running);
diff --git a/chromium/content/renderer/media/media_stream_video_capturer_source_unittest.cc b/chromium/content/renderer/media/media_stream_video_capturer_source_unittest.cc
index 98e8b713be4..c79a9f7972a 100644
--- a/chromium/content/renderer/media/media_stream_video_capturer_source_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_video_capturer_source_unittest.cc
@@ -105,7 +105,7 @@ class MediaStreamVideoCapturerSourceTest : public testing::Test {
base::test::ScopedTaskEnvironment::MainThreadType::UI),
child_process_(new ChildProcess()),
source_stopped_(false) {
- auto delegate = base::MakeUnique<MockVideoCapturerSource>();
+ auto delegate = std::make_unique<MockVideoCapturerSource>();
delegate_ = delegate.get();
EXPECT_CALL(*delegate_, GetPreferredFormats());
source_ = new MediaStreamVideoCapturerSource(
@@ -153,13 +153,18 @@ class MediaStreamVideoCapturerSourceTest : public testing::Test {
source_->OnRunStateChanged(delegate_->capture_params(), result);
}
+ void SetStopCaptureFlag() { stop_capture_flag_ = true; }
+
+ MOCK_METHOD0(MockNotification, void());
+
protected:
void OnConstraintsApplied(MediaStreamSource* source,
MediaStreamRequestResult result,
const blink::WebString& result_name) {}
- // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks
- // and Sources below into believing they are on the right threads.
+ // A ChildProcess is needed to fool the Tracks and Sources into believing they
+ // are on the right threads. A ScopedTaskEnvironment must be instantiated
+ // before ChildProcess to prevent it from leaking a TaskScheduler.
base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<ChildProcess> child_process_;
@@ -169,6 +174,7 @@ class MediaStreamVideoCapturerSourceTest : public testing::Test {
MockVideoCapturerSource* delegate_; // owned by |source_|.
blink::WebString webkit_source_id_;
bool source_stopped_;
+ bool stop_capture_flag_ = false;
};
TEST_F(MediaStreamVideoCapturerSourceTest, StartAndStop) {
@@ -317,4 +323,34 @@ TEST_F(MediaStreamVideoCapturerSourceTest, Restart) {
EXPECT_FALSE(source_->IsRunning());
}
+TEST_F(MediaStreamVideoCapturerSourceTest, StartStopAndNotify) {
+ InSequence s;
+ EXPECT_CALL(mock_delegate(), MockStartCapture(_, _, _));
+ blink::WebMediaStreamTrack web_track =
+ StartSource(VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
+ webkit_source_.GetReadyState());
+ EXPECT_FALSE(source_stopped_);
+
+ stop_capture_flag_ = false;
+ EXPECT_CALL(mock_delegate(), MockStopCapture())
+ .WillOnce(InvokeWithoutArgs(
+ this, &MediaStreamVideoCapturerSourceTest::SetStopCaptureFlag));
+ EXPECT_CALL(*this, MockNotification());
+ MediaStreamTrack* track = MediaStreamTrack::GetTrack(web_track);
+ track->StopAndNotify(
+ base::BindOnce(&MediaStreamVideoCapturerSourceTest::MockNotification,
+ base::Unretained(this)));
+ EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded,
+ webkit_source_.GetReadyState());
+ EXPECT_TRUE(source_stopped_);
+ // It is a requirement that StopCapture() gets called in the same task as
+ // StopAndNotify(), as CORS security checks for element capture rely on this.
+ EXPECT_TRUE(stop_capture_flag_);
+ // The readyState is updated in the current task, but the notification is
+ // received on a separate task.
+ base::RunLoop().RunUntilIdle();
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_video_renderer_sink_unittest.cc b/chromium/content/renderer/media/media_stream_video_renderer_sink_unittest.cc
index e582fcaa7c0..af99cc1a614 100644
--- a/chromium/content/renderer/media/media_stream_video_renderer_sink_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_video_renderer_sink_unittest.cc
@@ -9,9 +9,9 @@
#include "base/bind.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 "content/child/child_process.h"
#include "content/renderer/media/media_stream_video_track.h"
#include "content/renderer/media/mock_media_stream_registry.h"
@@ -57,8 +57,10 @@ class MediaStreamVideoRendererSinkTest : public testing::Test {
base::Unretained(this)),
base::Bind(&MediaStreamVideoRendererSinkTest::RepaintCallback,
base::Unretained(this)),
- child_process_->io_task_runner(), message_loop_.task_runner(),
- message_loop_.task_runner(), nullptr /* gpu_factories */);
+ child_process_->io_task_runner(),
+ scoped_task_environment_.GetMainThreadTaskRunner(),
+ scoped_task_environment_.GetMainThreadTaskRunner(),
+ nullptr /* gpu_factories */);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(IsInStoppedState());
@@ -109,9 +111,10 @@ class MediaStreamVideoRendererSinkTest : public testing::Test {
scoped_refptr<MediaStreamVideoRendererSink> media_stream_video_renderer_sink_;
protected:
- // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks
- // and Sources in |registry_| into believing they are on the right threads.
- base::MessageLoopForUI message_loop_;
+ // A ChildProcess is needed to fool the Tracks and Sources into believing they
+ // are on the right threads. A ScopedTaskEnvironment must be instantiated
+ // before ChildProcess to prevent it from leaking a TaskScheduler.
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
const std::unique_ptr<ChildProcess> child_process_;
blink::WebMediaStreamTrack blink_track_;
@@ -204,8 +207,10 @@ class MediaStreamVideoRendererSinkTransparencyTest
base::Bind(&MediaStreamVideoRendererSinkTransparencyTest::
VerifyTransparentFrame,
base::Unretained(this)),
- child_process_->io_task_runner(), message_loop_.task_runner(),
- message_loop_.task_runner(), nullptr /* gpu_factories */);
+ child_process_->io_task_runner(),
+ scoped_task_environment_.GetMainThreadTaskRunner(),
+ scoped_task_environment_.GetMainThreadTaskRunner(),
+ nullptr /* gpu_factories */);
}
void VerifyTransparentFrame(scoped_refptr<media::VideoFrame> frame) {
diff --git a/chromium/content/renderer/media/media_stream_video_source.cc b/chromium/content/renderer/media/media_stream_video_source.cc
index 66f2274f515..23a718918c4 100644
--- a/chromium/content/renderer/media/media_stream_video_source.cc
+++ b/chromium/content/renderer/media/media_stream_video_source.cc
@@ -56,7 +56,7 @@ void MediaStreamVideoSource::AddTrack(
pending_tracks_.push_back(PendingTrackInfo(
track, frame_callback,
- base::MakeUnique<VideoTrackAdapterSettings>(track_adapter_settings),
+ std::make_unique<VideoTrackAdapterSettings>(track_adapter_settings),
callback));
switch (state_) {
@@ -82,7 +82,8 @@ void MediaStreamVideoSource::AddTrack(
}
}
-void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) {
+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);
@@ -90,6 +91,13 @@ void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) {
tracks_.erase(it);
secure_tracker_.Remove(video_track);
+ {
+ auto it = std::find(suspended_tracks_.begin(), suspended_tracks_.end(),
+ video_track);
+ if (it != suspended_tracks_.end())
+ suspended_tracks_.erase(it);
+ }
+
for (auto it = pending_tracks_.begin(); it != pending_tracks_.end(); ++it) {
if (it->track == video_track) {
pending_tracks_.erase(it);
@@ -101,8 +109,67 @@ void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) {
// failed and |frame_adapter_->AddCallback| has not been called.
track_adapter_->RemoveTrack(video_track);
- if (tracks_.empty())
+ if (tracks_.empty()) {
+ if (callback) {
+ // Use StopForRestart() in order to get a notification of when the
+ // source is actually stopped (if supported). The source will not be
+ // restarted.
+ // The intent is to have the same effect as StopSource() (i.e., having
+ // the readyState updated and invoking the source's stop callback on this
+ // task), but getting a notification of when the source has actually
+ // stopped so that clients have a mechanism to serialize the creation and
+ // destruction of video sources. Without such serialization it is possible
+ // that concurrent creation and destruction of sources that share the same
+ // underlying implementation results in failed source creation since
+ // 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,
+ weak_factory_.GetWeakPtr(),
+ std::move(callback)));
+ if (state_ == STOPPING_FOR_RESTART || state_ == STOPPED_FOR_RESTART) {
+ // If the source supports restarting, it is necessary to call
+ // FinalizeStopSource() to ensure the same behavior as StopSource(),
+ // even if the underlying implementation takes longer to actually stop.
+ // In particular, Tab capture and capture from element require the
+ // source's stop callback to be invoked on this task in order to ensure
+ // correct behavior.
+ FinalizeStopSource();
+ } else {
+ // If the source does not support restarting, call StopSource()
+ // to ensure stop on this task. DidRemoveLastTrack() 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();
+ }
+ } else {
+ StopSource();
+ }
+ } else if (callback) {
+ std::move(callback).Run();
+ }
+}
+
+void MediaStreamVideoSource::DidRemoveLastTrack(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) {
+ state_ = ENDED;
+ }
+
+ if (state_ != ENDED) {
+ // This can happen if a source that supports StopForRestart() fails to
+ // actually stop the source after trying to stop it. The contract for
+ // StopForRestart() allows this, but it should not happen in practice.
+ LOG(WARNING) << "Source unexpectedly failed to stop. Force stopping and "
+ "sending notification anyway";
StopSource();
+ }
+ std::move(callback).Run();
}
void MediaStreamVideoSource::ReconfigureTrack(
@@ -139,8 +206,9 @@ void MediaStreamVideoSource::StopSourceForRestartImpl() {
void MediaStreamVideoSource::OnStopForRestartDone(bool did_stop_for_restart) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (state_ == ENDED)
+ if (state_ == ENDED) {
return;
+ }
DCHECK_EQ(state_, STOPPING_FOR_RESTART);
if (did_stop_for_restart) {
diff --git a/chromium/content/renderer/media/media_stream_video_source.h b/chromium/content/renderer/media/media_stream_video_source.h
index dd7485f2c41..7484256fa07 100644
--- a/chromium/content/renderer/media/media_stream_video_source.h
+++ b/chromium/content/renderer/media/media_stream_video_source.h
@@ -66,7 +66,7 @@ class CONTENT_EXPORT MediaStreamVideoSource : public MediaStreamSource {
const VideoTrackAdapterSettings& track_adapter_settings,
const VideoCaptureDeliverFrameCB& frame_callback,
const ConstraintsCallback& callback);
- void RemoveTrack(MediaStreamVideoTrack* track);
+ void RemoveTrack(MediaStreamVideoTrack* track, base::OnceClosure callback);
// Reconfigures this MediaStreamVideoSource to use |adapter_settings| on
// |track|, as long as |track| is connected to this source.
@@ -253,6 +253,7 @@ class CONTENT_EXPORT MediaStreamVideoSource : public MediaStreamSource {
void StartFrameMonitoring();
void UpdateTrackSettings(MediaStreamVideoTrack* track,
const VideoTrackAdapterSettings& adapter_settings);
+ void DidRemoveLastTrack(base::OnceClosure callback, RestartResult result);
State state_;
diff --git a/chromium/content/renderer/media/media_stream_video_source_unittest.cc b/chromium/content/renderer/media/media_stream_video_source_unittest.cc
index 620452e5cc7..617ec923cbc 100644
--- a/chromium/content/renderer/media/media_stream_video_source_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_video_source_unittest.cc
@@ -70,6 +70,8 @@ class MediaStreamVideoSourceTest : public ::testing::Test {
blink::WebHeap::CollectAllGarbageForTesting();
}
+ MOCK_METHOD0(MockNotification, void());
+
protected:
MediaStreamVideoSource* source() { return mock_source_; }
@@ -637,4 +639,58 @@ TEST_F(MediaStreamVideoSourceTest, FailedRestartAfterStopForRestart) {
blink::WebMediaStreamSource::kReadyStateEnded);
}
+TEST_F(MediaStreamVideoSourceTest, StartStopAndNotifyRestartSupported) {
+ blink::WebMediaStreamTrack web_track = CreateTrack("123");
+ mock_source()->EnableStopForRestart();
+ mock_source()->StartMockedSource();
+ EXPECT_EQ(NumberOfSuccessConstraintsCallbacks(), 1);
+ EXPECT_EQ(web_track.Source().GetReadyState(),
+ blink::WebMediaStreamSource::kReadyStateLive);
+
+ EXPECT_CALL(*this, MockNotification());
+ MediaStreamTrack* track = MediaStreamTrack::GetTrack(web_track);
+ track->StopAndNotify(base::BindOnce(
+ &MediaStreamVideoSourceTest::MockNotification, base::Unretained(this)));
+ EXPECT_EQ(web_track.Source().GetReadyState(),
+ blink::WebMediaStreamSource::kReadyStateEnded);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(MediaStreamVideoSourceTest, StartStopAndNotifyRestartNotSupported) {
+ blink::WebMediaStreamTrack web_track = CreateTrack("123");
+ mock_source()->DisableStopForRestart();
+ mock_source()->StartMockedSource();
+ EXPECT_EQ(NumberOfSuccessConstraintsCallbacks(), 1);
+ EXPECT_EQ(web_track.Source().GetReadyState(),
+ blink::WebMediaStreamSource::kReadyStateLive);
+
+ EXPECT_CALL(*this, MockNotification());
+ MediaStreamTrack* track = MediaStreamTrack::GetTrack(web_track);
+ track->StopAndNotify(base::BindOnce(
+ &MediaStreamVideoSourceTest::MockNotification, base::Unretained(this)));
+ EXPECT_EQ(web_track.Source().GetReadyState(),
+ blink::WebMediaStreamSource::kReadyStateEnded);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(MediaStreamVideoSourceTest, StopSuspendedTrack) {
+ blink::WebMediaStreamTrack web_track1 = CreateTrack("123");
+ mock_source()->StartMockedSource();
+ blink::WebMediaStreamTrack web_track2 = CreateTrack("123");
+
+ // Simulate assigning |track1| to a sink, then removing it from the sink, and
+ // then stopping it.
+ MediaStreamVideoTrack* track1 =
+ MediaStreamVideoTrack::GetVideoTrack(web_track1);
+ mock_source()->UpdateHasConsumers(track1, true);
+ mock_source()->UpdateHasConsumers(track1, false);
+ track1->Stop();
+
+ // Simulate assigning |track2| to a sink. The source should not be suspended.
+ MediaStreamVideoTrack* track2 =
+ MediaStreamVideoTrack::GetVideoTrack(web_track2);
+ mock_source()->UpdateHasConsumers(track2, true);
+ EXPECT_FALSE(mock_source()->is_suspended());
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_video_track.cc b/chromium/content/renderer/media/media_stream_video_track.cc
index 38bf137a798..3f05dbcc7c6 100644
--- a/chromium/content/renderer/media/media_stream_video_track.cc
+++ b/chromium/content/renderer/media/media_stream_video_track.cc
@@ -155,7 +155,7 @@ void MediaStreamVideoTrack::FrameDeliverer::SetEnabledOnIO(bool enabled) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
enabled_ = enabled;
if (enabled_)
- black_frame_ = NULL;
+ black_frame_ = nullptr;
}
void MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO(
@@ -258,7 +258,7 @@ MediaStreamVideoTrack::MediaStreamVideoTrack(
frame_deliverer_(
new MediaStreamVideoTrack::FrameDeliverer(source->io_task_runner(),
enabled)),
- adapter_settings_(base::MakeUnique<VideoTrackAdapterSettings>(
+ adapter_settings_(std::make_unique<VideoTrackAdapterSettings>(
VideoTrackAdapterSettings())),
is_screencast_(false),
source_(source->GetWeakPtr()) {
@@ -282,7 +282,7 @@ MediaStreamVideoTrack::MediaStreamVideoTrack(
new MediaStreamVideoTrack::FrameDeliverer(source->io_task_runner(),
enabled)),
adapter_settings_(
- base::MakeUnique<VideoTrackAdapterSettings>(adapter_settings)),
+ std::make_unique<VideoTrackAdapterSettings>(adapter_settings)),
noise_reduction_(noise_reduction),
is_screencast_(is_screen_cast),
min_frame_rate_(min_frame_rate),
@@ -348,11 +348,13 @@ void MediaStreamVideoTrack::SetContentHint(
sink->OnContentHintChanged(content_hint);
}
-void MediaStreamVideoTrack::Stop() {
+void MediaStreamVideoTrack::StopAndNotify(base::OnceClosure callback) {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
if (source_) {
- source_->RemoveTrack(this);
- source_ = NULL;
+ source_->RemoveTrack(this, std::move(callback));
+ source_ = nullptr;
+ } else if (callback) {
+ std::move(callback).Run();
}
OnReadyStateChanged(blink::WebMediaStreamSource::kReadyStateEnded);
}
diff --git a/chromium/content/renderer/media/media_stream_video_track.h b/chromium/content/renderer/media/media_stream_video_track.h
index 87f6b7bea39..d2ae8005df7 100644
--- a/chromium/content/renderer/media/media_stream_video_track.h
+++ b/chromium/content/renderer/media/media_stream_video_track.h
@@ -77,7 +77,7 @@ class CONTENT_EXPORT MediaStreamVideoTrack : public MediaStreamTrack {
void SetEnabled(bool enabled) override;
void SetContentHint(
blink::WebMediaStreamTrack::ContentHintType content_hint) override;
- void Stop() override;
+ void StopAndNotify(base::OnceClosure callback) override;
void GetSettings(blink::WebMediaStreamTrack::Settings& settings) override;
void OnReadyStateChanged(blink::WebMediaStreamSource::ReadyState state);
diff --git a/chromium/content/renderer/media/media_stream_video_track_unittest.cc b/chromium/content/renderer/media/media_stream_video_track_unittest.cc
index e55ce1627c1..94b64bbe802 100644
--- a/chromium/content/renderer/media/media_stream_video_track_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_video_track_unittest.cc
@@ -7,9 +7,9 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.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_checker_impl.h"
#include "content/child/child_process.h"
#include "content/renderer/media/media_stream_video_track.h"
@@ -34,7 +34,8 @@ ACTION_P(RunClosure, closure) {
class MediaStreamVideoTrackTest : public ::testing::Test {
public:
MediaStreamVideoTrackTest()
- : child_process_(new ChildProcess()),
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI),
mock_source_(nullptr),
source_started_(false) {}
@@ -59,10 +60,6 @@ class MediaStreamVideoTrackTest : public ::testing::Test {
}
protected:
- base::MessageLoop* io_message_loop() const {
- return child_process_->io_message_loop();
- }
-
void InitializeSource() {
blink_source_.Reset();
mock_source_ = new MockMediaStreamVideoSource(
@@ -124,8 +121,10 @@ class MediaStreamVideoTrackTest : public ::testing::Test {
}
private:
- const base::MessageLoopForUI message_loop_;
- const std::unique_ptr<ChildProcess> child_process_;
+ // The ScopedTaskEnvironment prevents the ChildProcess from leaking a
+ // TaskScheduler.
+ const base::test::ScopedTaskEnvironment scoped_task_environment_;
+ const ChildProcess child_process_;
blink::WebMediaStreamSource blink_source_;
// |mock_source_| is owned by |webkit_source_|.
MockMediaStreamVideoSource* mock_source_;
diff --git a/chromium/content/renderer/media/mock_media_stream_dispatcher.cc b/chromium/content/renderer/media/mock_media_stream_dispatcher.cc
deleted file mode 100644
index e2fd636b7ed..00000000000
--- a/chromium/content/renderer/media/mock_media_stream_dispatcher.cc
+++ /dev/null
@@ -1,117 +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/media/mock_media_stream_dispatcher.h"
-
-#include "base/strings/string_number_conversions.h"
-#include "media/base/audio_parameters.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-// Used for ID for output devices and for matching output device ID for input
-// devices.
-const char kAudioOutputDeviceIdPrefix[] = "audio_output_device_id";
-
-namespace content {
-
-MockMediaStreamDispatcher::MockMediaStreamDispatcher()
- : MediaStreamDispatcher(nullptr),
- audio_input_request_id_(-1),
- request_stream_counter_(0),
- stop_audio_device_counter_(0),
- stop_video_device_counter_(0),
- session_id_(0),
- test_same_id_(false) {}
-
-MockMediaStreamDispatcher::~MockMediaStreamDispatcher() {}
-
-void MockMediaStreamDispatcher::GenerateStream(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler,
- const StreamControls& controls,
- const url::Origin& security_origin,
- bool is_processing_user_gesture) {
- // Audio and video share the same request so we use |audio_input_request_id_|
- // only.
- audio_input_request_id_ = request_id;
-
- stream_label_ = "local_stream" + base::IntToString(request_id);
- audio_devices_.clear();
- video_devices_.clear();
-
- if (controls.audio.requested) {
- AddAudioDeviceToArray(false, controls.audio.device_id);
- }
- if (controls.video.requested) {
- AddVideoDeviceToArray(true, controls.video.device_id);
- }
- ++request_stream_counter_;
-}
-
-void MockMediaStreamDispatcher::CancelGenerateStream(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler) {
- EXPECT_EQ(request_id, audio_input_request_id_);
-}
-
-void MockMediaStreamDispatcher::StopStreamDevice(
- const MediaStreamDevice& device) {
- if (IsAudioInputMediaType(device.type)) {
- ++stop_audio_device_counter_;
- return;
- }
- if (IsVideoMediaType(device.type)) {
- ++stop_video_device_counter_;
- return;
- }
- NOTREACHED();
-}
-
-bool MockMediaStreamDispatcher::IsStream(const std::string& label) {
- return true;
-}
-
-int MockMediaStreamDispatcher::video_session_id(const std::string& label,
- int index) {
- return -1;
-}
-
-int MockMediaStreamDispatcher::audio_session_id(const std::string& label,
- int index) {
- return -1;
-}
-
-void MockMediaStreamDispatcher::AddAudioDeviceToArray(
- bool matched_output,
- const std::string& device_id) {
- MediaStreamDevice audio_device;
- audio_device.id =
- (test_same_id_ ? "test_id" : device_id) + base::IntToString(session_id_);
- audio_device.name = "microphone";
- audio_device.type = MEDIA_DEVICE_AUDIO_CAPTURE;
- audio_device.video_facing = media::MEDIA_VIDEO_FACING_NONE;
- if (matched_output) {
- audio_device.matched_output_device_id =
- kAudioOutputDeviceIdPrefix + base::IntToString(session_id_);
- }
- audio_device.session_id = session_id_;
- audio_device.input = media::AudioParameters::UnavailableDeviceParams();
- audio_devices_.push_back(audio_device);
-}
-
-void MockMediaStreamDispatcher::AddVideoDeviceToArray(
- bool facing_user,
- const std::string& device_id) {
- MediaStreamDevice video_device;
- video_device.id =
- (test_same_id_ ? "test_id" : device_id) + base::IntToString(session_id_);
- video_device.name = "usb video camera";
- video_device.type = MEDIA_DEVICE_VIDEO_CAPTURE;
- video_device.video_facing = facing_user
- ? media::MEDIA_VIDEO_FACING_USER
- : media::MEDIA_VIDEO_FACING_ENVIRONMENT;
- video_device.session_id = session_id_;
- video_devices_.push_back(video_device);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/mock_media_stream_dispatcher.h b/chromium/content/renderer/media/mock_media_stream_dispatcher.h
deleted file mode 100644
index f8610747a76..00000000000
--- a/chromium/content/renderer/media/mock_media_stream_dispatcher.h
+++ /dev/null
@@ -1,71 +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_MEDIA_MOCK_MEDIA_STREAM_DISPATCHER_H_
-#define CONTENT_RENDERER_MEDIA_MOCK_MEDIA_STREAM_DISPATCHER_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "content/public/common/media_stream_request.h"
-#include "content/renderer/media/media_stream_dispatcher.h"
-#include "url/origin.h"
-
-namespace content {
-
-// This class is a mock implementation of MediaStreamDispatcher.
-class MockMediaStreamDispatcher : public MediaStreamDispatcher {
- public:
- MockMediaStreamDispatcher();
- ~MockMediaStreamDispatcher() override;
-
- void GenerateStream(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler,
- const StreamControls& controls,
- const url::Origin& security_origin,
- bool is_procesing_user_gesture) override;
- void CancelGenerateStream(
- int request_id,
- const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler)
- override;
- void StopStreamDevice(const MediaStreamDevice& device) override;
- bool IsStream(const std::string& label) override;
- int video_session_id(const std::string& label, int index) override;
- int audio_session_id(const std::string& label, int index) override;
-
- int audio_input_request_id() const { return audio_input_request_id_; }
- int request_stream_counter() const { return request_stream_counter_; }
- void IncrementSessionId() { ++session_id_; }
- void TestSameId() { test_same_id_ = true; }
-
- int stop_audio_device_counter() const { return stop_audio_device_counter_; }
- int stop_video_device_counter() const { return stop_video_device_counter_; }
-
- const std::string& stream_label() const { return stream_label_;}
- const MediaStreamDevices& audio_devices() const { return audio_devices_; }
- const MediaStreamDevices& video_devices() const { return video_devices_; }
-
- private:
- void AddAudioDeviceToArray(bool matched_output, const std::string& device_id);
- void AddVideoDeviceToArray(bool facing_user, const std::string& device_id);
-
- int audio_input_request_id_;
- base::WeakPtr<MediaStreamDispatcherEventHandler> event_handler_;
- int request_stream_counter_;
- int stop_audio_device_counter_;
- int stop_video_device_counter_;
-
- std::string stream_label_;
- int session_id_;
- bool test_same_id_;
- MediaStreamDevices audio_devices_;
- MediaStreamDevices video_devices_;
-
- DISALLOW_COPY_AND_ASSIGN(MockMediaStreamDispatcher);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_MOCK_MEDIA_STREAM_DISPATCHER_H_
diff --git a/chromium/content/renderer/media/mock_media_stream_video_source.cc b/chromium/content/renderer/media/mock_media_stream_video_source.cc
index 0f747b8bd7e..d47b2fcec32 100644
--- a/chromium/content/renderer/media/mock_media_stream_video_source.cc
+++ b/chromium/content/renderer/media/mock_media_stream_video_source.cc
@@ -56,6 +56,10 @@ void MockMediaStreamVideoSource::RequestRefreshFrame() {
}
}
+void MockMediaStreamVideoSource::OnHasConsumers(bool has_consumers) {
+ is_suspended_ = !has_consumers;
+}
+
void MockMediaStreamVideoSource::StartSourceImpl(
const VideoCaptureDeliverFrameCB& frame_callback) {
DCHECK(frame_callback_.is_null());
diff --git a/chromium/content/renderer/media/mock_media_stream_video_source.h b/chromium/content/renderer/media/mock_media_stream_video_source.h
index 2af2e857a96..46599a2ce8e 100644
--- a/chromium/content/renderer/media/mock_media_stream_video_source.h
+++ b/chromium/content/renderer/media/mock_media_stream_video_source.h
@@ -53,10 +53,13 @@ class MockMediaStreamVideoSource : public MediaStreamVideoSource {
void EnableRestart() { can_restart_ = true; }
void DisableRestart() { can_restart_ = false; }
+ bool is_suspended() { return is_suspended_; }
+
// Implements MediaStreamVideoSource.
void RequestRefreshFrame() override;
base::Optional<media::VideoCaptureParams> GetCurrentCaptureParams()
const override;
+ void OnHasConsumers(bool has_consumers) override;
protected:
// Implements MediaStreamVideoSource.
@@ -77,6 +80,7 @@ class MockMediaStreamVideoSource : public MediaStreamVideoSource {
bool is_stopped_for_restart_ = false;
bool can_stop_for_restart_ = true;
bool can_restart_ = true;
+ bool is_suspended_ = false;
VideoCaptureDeliverFrameCB frame_callback_;
DISALLOW_COPY_AND_ASSIGN(MockMediaStreamVideoSource);
diff --git a/chromium/content/renderer/media/mock_mojo_media_stream_dispatcher_host.cc b/chromium/content/renderer/media/mock_mojo_media_stream_dispatcher_host.cc
index bb9a5a715f6..627d6580d93 100644
--- a/chromium/content/renderer/media/mock_mojo_media_stream_dispatcher_host.cc
+++ b/chromium/content/renderer/media/mock_mojo_media_stream_dispatcher_host.cc
@@ -4,17 +4,96 @@
#include "content/renderer/media/mock_mojo_media_stream_dispatcher_host.h"
+#include "base/strings/string_number_conversions.h"
+
namespace content {
-MockMojoMediaStreamDispatcherHost::MockMojoMediaStreamDispatcherHost() {}
+MockMojoMediaStreamDispatcherHost::MockMojoMediaStreamDispatcherHost()
+ : binding_(this) {}
MockMojoMediaStreamDispatcherHost::~MockMojoMediaStreamDispatcherHost() {}
mojom::MediaStreamDispatcherHostPtr
MockMojoMediaStreamDispatcherHost::CreateInterfacePtrAndBind() {
mojom::MediaStreamDispatcherHostPtr dispatcher_host;
- bindings_.AddBinding(this, mojo::MakeRequest(&dispatcher_host));
+ binding_.Bind(mojo::MakeRequest(&dispatcher_host));
return dispatcher_host;
}
+void MockMojoMediaStreamDispatcherHost::GenerateStream(
+ int32_t render_frame_id,
+ int32_t request_id,
+ const StreamControls& controls,
+ bool user_gesture,
+ GenerateStreamCallback callback) {
+ request_id_ = request_id;
+ audio_devices_.clear();
+ video_devices_.clear();
+ ++request_stream_counter_;
+
+ if (controls.audio.requested) {
+ MediaStreamDevice audio_device;
+ audio_device.id = controls.audio.device_id + base::IntToString(session_id_);
+ audio_device.name = "microphone";
+ audio_device.type = MEDIA_DEVICE_AUDIO_CAPTURE;
+ audio_device.session_id = session_id_;
+ audio_devices_.push_back(audio_device);
+ }
+
+ if (controls.video.requested) {
+ MediaStreamDevice video_device;
+ video_device.id = controls.video.device_id + base::IntToString(session_id_);
+ video_device.name = "usb video camera";
+ video_device.type = MEDIA_DEVICE_VIDEO_CAPTURE;
+ video_device.video_facing = media::MEDIA_VIDEO_FACING_USER;
+ video_device.session_id = session_id_;
+ video_devices_.push_back(video_device);
+ }
+
+ if (do_not_run_cb_) {
+ generate_stream_cb_ = std::move(callback);
+ } else {
+ std::move(callback).Run(MEDIA_DEVICE_OK,
+ "dummy" + base::IntToString(request_id_),
+ audio_devices_, video_devices_);
+ }
+}
+
+void MockMojoMediaStreamDispatcherHost::CancelRequest(int32_t render_frame_id,
+ int32_t request_id) {
+ EXPECT_EQ(request_id, request_id_);
+}
+
+void MockMojoMediaStreamDispatcherHost::StopStreamDevice(
+ int32_t render_frame_id,
+ const std::string& device_id) {
+ for (const MediaStreamDevice& device : audio_devices_) {
+ if (device.id == device_id) {
+ ++stop_audio_device_counter_;
+ return;
+ }
+ }
+ for (const MediaStreamDevice& device : video_devices_) {
+ if (device.id == device_id) {
+ ++stop_video_device_counter_;
+ return;
+ }
+ }
+ NOTREACHED();
+}
+
+void MockMojoMediaStreamDispatcherHost::OpenDevice(
+ int32_t render_frame_id,
+ int32_t request_id,
+ const std::string& device_id,
+ MediaStreamType type,
+ OpenDeviceCallback callback) {
+ MediaStreamDevice device;
+ device.id = device_id;
+ device.type = type;
+ device.session_id = session_id_;
+ std::move(callback).Run(true /* success */,
+ "dummy" + base::IntToString(request_id), device);
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/mock_mojo_media_stream_dispatcher_host.h b/chromium/content/renderer/media/mock_mojo_media_stream_dispatcher_host.h
index 40a9bc63f81..005f8e0af04 100644
--- a/chromium/content/renderer/media/mock_mojo_media_stream_dispatcher_host.h
+++ b/chromium/content/renderer/media/mock_mojo_media_stream_dispatcher_host.h
@@ -11,13 +11,9 @@
#include "content/common/media/media_stream.mojom.h"
#include "content/common/media/media_stream_controls.h"
#include "content/public/common/media_stream_request.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gmock/include/gmock/gmock.h"
-namespace url {
-class Origin;
-}
-
namespace content {
class MockMojoMediaStreamDispatcherHost
@@ -28,23 +24,45 @@ class MockMojoMediaStreamDispatcherHost
mojom::MediaStreamDispatcherHostPtr CreateInterfacePtrAndBind();
- MOCK_METHOD5(
- GenerateStream,
- void(int32_t, int32_t, const StreamControls&, const url::Origin&, bool));
- MOCK_METHOD2(CancelGenerateStream, void(int32_t, int32_t));
- MOCK_METHOD2(StopStreamDevice, void(int32_t, const std::string&));
- MOCK_METHOD5(OpenDevice,
- void(int32_t,
- int32_t,
- const std::string&,
- MediaStreamType,
- const url::Origin&));
+ void GenerateStream(int32_t render_frame_id,
+ int32_t request_id,
+ const StreamControls& controls,
+ bool user_gesture,
+ GenerateStreamCallback callback) override;
+ void CancelRequest(int32_t render_frame_id, int32_t request_id) override;
+ void StopStreamDevice(int32_t render_frame_id,
+ const std::string& device_id) override;
+ void OpenDevice(int32_t render_frame_id,
+ int32_t request_id,
+ const std::string& device_id,
+ MediaStreamType type,
+ OpenDeviceCallback callback) override;
+
MOCK_METHOD1(CloseDevice, void(const std::string&));
MOCK_METHOD3(SetCapturingLinkSecured, void(int32_t, MediaStreamType, bool));
- MOCK_METHOD1(StreamStarted, void(const std::string&));
+ MOCK_METHOD1(OnStreamStarted, void(const std::string&));
+
+ void IncrementSessionId() { ++session_id_; }
+ void DoNotRunCallback() { do_not_run_cb_ = true; }
+
+ int request_stream_counter() const { return request_stream_counter_; }
+ int stop_audio_device_counter() const { return stop_audio_device_counter_; }
+ int stop_video_device_counter() const { return stop_video_device_counter_; }
+
+ const MediaStreamDevices& audio_devices() const { return audio_devices_; }
+ const MediaStreamDevices& video_devices() const { return video_devices_; }
private:
- mojo::BindingSet<mojom::MediaStreamDispatcherHost> bindings_;
+ int request_id_ = -1;
+ int request_stream_counter_ = 0;
+ int stop_audio_device_counter_ = 0;
+ int stop_video_device_counter_ = 0;
+ int session_id_ = 0;
+ bool do_not_run_cb_ = false;
+ MediaStreamDevices audio_devices_;
+ MediaStreamDevices video_devices_;
+ GenerateStreamCallback generate_stream_cb_;
+ mojo::Binding<mojom::MediaStreamDispatcherHost> binding_;
DISALLOW_COPY_AND_ASSIGN(MockMojoMediaStreamDispatcherHost);
};
diff --git a/chromium/content/renderer/media/mock_peer_connection_impl.cc b/chromium/content/renderer/media/mock_peer_connection_impl.cc
index c667604910d..69dcf141ee5 100644
--- a/chromium/content/renderer/media/mock_peer_connection_impl.cc
+++ b/chromium/content/renderer/media/mock_peer_connection_impl.cc
@@ -36,7 +36,7 @@ class MockStreamCollection : public webrtc::StreamCollectionInterface {
if (streams_[i]->label() == label)
return streams_[i];
}
- return NULL;
+ return nullptr;
}
webrtc::MediaStreamTrackInterface* FindAudioTrack(
const std::string& id) override {
@@ -46,7 +46,7 @@ class MockStreamCollection : public webrtc::StreamCollectionInterface {
if (track)
return track;
}
- return NULL;
+ return nullptr;
}
webrtc::MediaStreamTrackInterface* FindVideoTrack(
const std::string& id) override {
@@ -56,7 +56,7 @@ class MockStreamCollection : public webrtc::StreamCollectionInterface {
if (track)
return track;
}
- return NULL;
+ return nullptr;
}
void AddStream(MediaStreamInterface* stream) {
streams_.push_back(stream);
@@ -83,14 +83,11 @@ class MockStreamCollection : public webrtc::StreamCollectionInterface {
class MockDtmfSender : public DtmfSenderInterface {
public:
explicit MockDtmfSender(AudioTrackInterface* track)
- : track_(track),
- observer_(NULL),
- duration_(0),
- inter_tone_gap_(0) {}
+ : track_(track), observer_(nullptr), duration_(0), inter_tone_gap_(0) {}
void RegisterObserver(DtmfSenderObserverInterface* observer) override {
observer_ = observer;
}
- void UnregisterObserver() override { observer_ = NULL; }
+ void UnregisterObserver() override { observer_ = nullptr; }
bool CanInsertDtmf() override { return true; }
bool InsertDtmf(const std::string& tones,
int duration,
@@ -116,42 +113,47 @@ class MockDtmfSender : public DtmfSenderInterface {
int inter_tone_gap_;
};
-class FakeRtpReceiver : public webrtc::RtpReceiverInterface {
- public:
- FakeRtpReceiver(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track)
- : track_(track) {}
+FakeRtpReceiver::FakeRtpReceiver(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams)
+ : track_(std::move(track)), streams_(std::move(streams)) {}
- rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track() const override {
- return track_;
- }
+FakeRtpReceiver::~FakeRtpReceiver() {}
- cricket::MediaType media_type() const override {
- NOTIMPLEMENTED();
- return cricket::MEDIA_TYPE_AUDIO;
- }
+rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> FakeRtpReceiver::track()
+ const {
+ return track_;
+}
- std::string id() const override {
- NOTIMPLEMENTED();
- return "";
- }
+std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>
+FakeRtpReceiver::streams() const {
+ return streams_;
+}
- webrtc::RtpParameters GetParameters() const override {
- NOTIMPLEMENTED();
- return webrtc::RtpParameters();
- }
+cricket::MediaType FakeRtpReceiver::media_type() const {
+ NOTIMPLEMENTED();
+ return cricket::MEDIA_TYPE_AUDIO;
+}
- bool SetParameters(const webrtc::RtpParameters& parameters) override {
- NOTIMPLEMENTED();
- return false;
- }
+std::string FakeRtpReceiver::id() const {
+ NOTIMPLEMENTED();
+ return "";
+}
- void SetObserver(webrtc::RtpReceiverObserverInterface* observer) override {
- NOTIMPLEMENTED();
- }
+webrtc::RtpParameters FakeRtpReceiver::GetParameters() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpParameters();
+}
- private:
- rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track_;
-};
+bool FakeRtpReceiver::SetParameters(const webrtc::RtpParameters& parameters) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+void FakeRtpReceiver::SetObserver(
+ webrtc::RtpReceiverObserverInterface* observer) {
+ NOTIMPLEMENTED();
+}
const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer";
const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer";
@@ -169,8 +171,17 @@ MockPeerConnectionImpl::MockPeerConnectionImpl(
observer_(observer) {
ON_CALL(*this, SetLocalDescription(_, _)).WillByDefault(testing::Invoke(
this, &MockPeerConnectionImpl::SetLocalDescriptionWorker));
+ // TODO(hbos): Remove once no longer mandatory to implement.
ON_CALL(*this, SetRemoteDescription(_, _)).WillByDefault(testing::Invoke(
this, &MockPeerConnectionImpl::SetRemoteDescriptionWorker));
+ ON_CALL(*this, SetRemoteDescriptionForMock(_, _))
+ .WillByDefault(testing::Invoke(
+ [this](
+ std::unique_ptr<webrtc::SessionDescriptionInterface>* desc,
+ rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface>*
+ observer) {
+ SetRemoteDescriptionWorker(nullptr, desc->release());
+ }));
}
MockPeerConnectionImpl::~MockPeerConnectionImpl() {}
@@ -202,7 +213,7 @@ void MockPeerConnectionImpl::RemoveStream(
rtc::scoped_refptr<DtmfSenderInterface>
MockPeerConnectionImpl::CreateDtmfSender(AudioTrackInterface* track) {
if (!track) {
- return NULL;
+ return nullptr;
}
return new rtc::RefCountedObject<MockDtmfSender>(track);
}
@@ -295,7 +306,7 @@ void MockPeerConnectionImpl::CreateOffer(
DCHECK(observer);
created_sessiondescription_.reset(
dependency_factory_->CreateSessionDescription("unknown", kDummyOffer,
- NULL));
+ nullptr));
}
void MockPeerConnectionImpl::CreateAnswer(
@@ -304,7 +315,7 @@ void MockPeerConnectionImpl::CreateAnswer(
DCHECK(observer);
created_sessiondescription_.reset(
dependency_factory_->CreateSessionDescription("unknown", kDummyAnswer,
- NULL));
+ nullptr));
}
void MockPeerConnectionImpl::SetLocalDescriptionWorker(
diff --git a/chromium/content/renderer/media/mock_peer_connection_impl.h b/chromium/content/renderer/media/mock_peer_connection_impl.h
index 914e0430bba..809551567c2 100644
--- a/chromium/content/renderer/media/mock_peer_connection_impl.h
+++ b/chromium/content/renderer/media/mock_peer_connection_impl.h
@@ -97,10 +97,23 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
webrtc::SessionDescriptionInterface* desc));
void SetLocalDescriptionWorker(
webrtc::SetSessionDescriptionObserver* observer,
- webrtc::SessionDescriptionInterface* desc) ;
+ webrtc::SessionDescriptionInterface* desc);
+ // TODO(hbos): Remove once no longer mandatory to implement.
MOCK_METHOD2(SetRemoteDescription,
void(webrtc::SetSessionDescriptionObserver* observer,
webrtc::SessionDescriptionInterface* desc));
+ void SetRemoteDescription(
+ std::unique_ptr<webrtc::SessionDescriptionInterface> desc,
+ rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface>
+ observer) override {
+ SetRemoteDescriptionForMock(&desc, &observer);
+ }
+ // Work-around due to MOCK_METHOD being unable to handle move-only arguments.
+ MOCK_METHOD2(
+ SetRemoteDescriptionForMock,
+ void(std::unique_ptr<webrtc::SessionDescriptionInterface>* desc,
+ rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface>*
+ observer));
void SetRemoteDescriptionWorker(
webrtc::SetSessionDescriptionObserver* observer,
webrtc::SessionDescriptionInterface* desc);
@@ -163,6 +176,27 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
DISALLOW_COPY_AND_ASSIGN(MockPeerConnectionImpl);
};
+class FakeRtpReceiver : public webrtc::RtpReceiverInterface {
+ public:
+ FakeRtpReceiver(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>
+ streams = {});
+ ~FakeRtpReceiver() override;
+
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track() const override;
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams()
+ const override;
+ cricket::MediaType media_type() const override;
+ std::string id() const override;
+ webrtc::RtpParameters GetParameters() const override;
+ bool SetParameters(const webrtc::RtpParameters& parameters) override;
+ void SetObserver(webrtc::RtpReceiverObserverInterface* observer) override;
+
+ private:
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track_;
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams_;
+};
+
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_MOCK_PEER_CONNECTION_IMPL_H_
diff --git a/chromium/content/renderer/media/mock_web_rtc_peer_connection_handler_client.cc b/chromium/content/renderer/media/mock_web_rtc_peer_connection_handler_client.cc
index 7715233baac..77827322bce 100644
--- a/chromium/content/renderer/media/mock_web_rtc_peer_connection_handler_client.cc
+++ b/chromium/content/renderer/media/mock_web_rtc_peer_connection_handler_client.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/WebKit/public/platform/WebMediaStream.h"
+#include "third_party/WebKit/public/platform/WebRTCRtpReceiver.h"
#include "third_party/WebKit/public/platform/WebString.h"
using testing::_;
@@ -19,36 +20,37 @@ MockWebRTCPeerConnectionHandlerClient()
.WillByDefault(
testing::Invoke(this, &MockWebRTCPeerConnectionHandlerClient::
didGenerateICECandidateWorker));
- ON_CALL(*this, DidAddRemoteStream(_, _))
+ ON_CALL(*this, DidAddRemoteTrackForMock(_))
.WillByDefault(testing::Invoke(
this,
- &MockWebRTCPeerConnectionHandlerClient::didAddRemoteStreamWorker));
- ON_CALL(*this, DidRemoveRemoteStream(_))
+ &MockWebRTCPeerConnectionHandlerClient::didAddRemoteTrackWorker));
+ ON_CALL(*this, DidRemoveRemoteTrackForMock(_))
.WillByDefault(testing::Invoke(
this,
- &MockWebRTCPeerConnectionHandlerClient::didRemoveRemoteStreamWorker));
+ &MockWebRTCPeerConnectionHandlerClient::didRemoveRemoteTrackWorker));
}
MockWebRTCPeerConnectionHandlerClient::
~MockWebRTCPeerConnectionHandlerClient() {}
void MockWebRTCPeerConnectionHandlerClient::didGenerateICECandidateWorker(
- const blink::WebRTCICECandidate& candidate) {
- candidate_sdp_ = candidate.Candidate().Utf8();
- candidate_mline_index_ = candidate.SdpMLineIndex();
- candidate_mid_ = candidate.SdpMid().Utf8();
+ scoped_refptr<blink::WebRTCICECandidate> candidate) {
+ candidate_sdp_ = candidate->Candidate().Utf8();
+ candidate_mline_index_ = candidate->SdpMLineIndex();
+ candidate_mid_ = candidate->SdpMid().Utf8();
}
-void MockWebRTCPeerConnectionHandlerClient::didAddRemoteStreamWorker(
- const blink::WebMediaStream& stream_descriptor,
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>>*
- stream_web_rtp_receivers) {
- remote_steam_ = stream_descriptor;
+void MockWebRTCPeerConnectionHandlerClient::didAddRemoteTrackWorker(
+ std::unique_ptr<blink::WebRTCRtpReceiver>* web_rtp_receiver) {
+ blink::WebVector<blink::WebMediaStream> web_streams =
+ (*web_rtp_receiver)->Streams();
+ DCHECK_EQ(1u, web_streams.size());
+ remote_stream_ = web_streams[0];
}
-void MockWebRTCPeerConnectionHandlerClient::didRemoveRemoteStreamWorker(
- const blink::WebMediaStream& stream_descriptor) {
- remote_steam_.Reset();
+void MockWebRTCPeerConnectionHandlerClient::didRemoveRemoteTrackWorker(
+ std::unique_ptr<blink::WebRTCRtpReceiver>* web_rtp_receiver) {
+ remote_stream_.Reset();
}
} // namespace content
diff --git a/chromium/content/renderer/media/mock_web_rtc_peer_connection_handler_client.h b/chromium/content/renderer/media/mock_web_rtc_peer_connection_handler_client.h
index adfc57480a7..8d50017eba6 100644
--- a/chromium/content/renderer/media/mock_web_rtc_peer_connection_handler_client.h
+++ b/chromium/content/renderer/media/mock_web_rtc_peer_connection_handler_client.h
@@ -13,6 +13,7 @@
#include "third_party/WebKit/public/platform/WebMediaStream.h"
#include "third_party/WebKit/public/platform/WebRTCICECandidate.h"
#include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h"
+#include "third_party/WebKit/public/platform/WebRTCRtpReceiver.h"
namespace content {
@@ -25,37 +26,44 @@ class MockWebRTCPeerConnectionHandlerClient
// WebRTCPeerConnectionHandlerClient implementation.
MOCK_METHOD0(NegotiationNeeded, void());
MOCK_METHOD1(DidGenerateICECandidate,
- void(const blink::WebRTCICECandidate& candidate));
+ void(scoped_refptr<blink::WebRTCICECandidate> candidate));
MOCK_METHOD1(DidChangeSignalingState, void(SignalingState state));
MOCK_METHOD1(DidChangeICEGatheringState, void(ICEGatheringState state));
MOCK_METHOD1(DidChangeICEConnectionState, void(ICEConnectionState state));
- MOCK_METHOD2(
- DidAddRemoteStream,
- void(const blink::WebMediaStream& stream_descriptor,
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>>*));
- MOCK_METHOD1(DidRemoveRemoteStream,
- void(const blink::WebMediaStream& stream_descriptor));
+ void DidAddRemoteTrack(
+ std::unique_ptr<blink::WebRTCRtpReceiver> web_rtp_receiver) {
+ DidAddRemoteTrackForMock(&web_rtp_receiver);
+ }
+ void DidRemoveRemoteTrack(
+ std::unique_ptr<blink::WebRTCRtpReceiver> web_rtp_receiver) {
+ DidRemoveRemoteTrackForMock(&web_rtp_receiver);
+ }
MOCK_METHOD1(DidAddRemoteDataChannel, void(blink::WebRTCDataChannelHandler*));
MOCK_METHOD0(ReleasePeerConnectionHandler, void());
+ // Move-only arguments do not play nicely with MOCK, the workaround is to
+ // EXPECT_CALL with these instead.
+ MOCK_METHOD1(DidAddRemoteTrackForMock,
+ void(std::unique_ptr<blink::WebRTCRtpReceiver>*));
+ MOCK_METHOD1(DidRemoveRemoteTrackForMock,
+ void(std::unique_ptr<blink::WebRTCRtpReceiver>*));
+
void didGenerateICECandidateWorker(
- const blink::WebRTCICECandidate& candidate);
- void didAddRemoteStreamWorker(
- const blink::WebMediaStream& stream_descriptor,
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>>*
- stream_web_rtp_receivers);
- void didRemoveRemoteStreamWorker(
- const blink::WebMediaStream& stream_descriptor);
+ scoped_refptr<blink::WebRTCICECandidate> candidate);
+ void didAddRemoteTrackWorker(
+ std::unique_ptr<blink::WebRTCRtpReceiver>* stream_web_rtp_receivers);
+ void didRemoveRemoteTrackWorker(
+ std::unique_ptr<blink::WebRTCRtpReceiver>* stream_web_rtp_receivers);
const std::string& candidate_sdp() const { return candidate_sdp_; }
int candidate_mlineindex() const {
return candidate_mline_index_;
}
const std::string& candidate_mid() const { return candidate_mid_ ; }
- const blink::WebMediaStream& remote_stream() const { return remote_steam_;}
+ const blink::WebMediaStream& remote_stream() const { return remote_stream_; }
private:
- blink::WebMediaStream remote_steam_;
+ blink::WebMediaStream remote_stream_;
std::string candidate_sdp_;
int candidate_mline_index_;
std::string candidate_mid_;
diff --git a/chromium/content/renderer/media/mojo_audio_input_ipc.cc b/chromium/content/renderer/media/mojo_audio_input_ipc.cc
new file mode 100644
index 00000000000..ae28c9a41f2
--- /dev/null
+++ b/chromium/content/renderer/media/mojo_audio_input_ipc.cc
@@ -0,0 +1,103 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/mojo_audio_input_ipc.h"
+
+#include <utility>
+
+#include "base/bind_helpers.h"
+#include "media/audio/audio_device_description.h"
+#include "mojo/public/cpp/system/platform_handle.h"
+
+namespace content {
+
+MojoAudioInputIPC::MojoAudioInputIPC(StreamCreatorCB stream_creator)
+ : stream_creator_(std::move(stream_creator)),
+ client_binding_(this),
+ weak_factory_(this) {}
+
+MojoAudioInputIPC::~MojoAudioInputIPC() = default;
+
+void MojoAudioInputIPC::CreateStream(media::AudioInputIPCDelegate* delegate,
+ int session_id,
+ const media::AudioParameters& params,
+ bool automatic_gain_control,
+ uint32_t total_segments) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(delegate);
+ DCHECK(!delegate_);
+
+ delegate_ = delegate;
+
+ media::mojom::AudioInputStreamClientPtr client;
+ client_binding_.Bind(mojo::MakeRequest(&client));
+ client_binding_.set_connection_error_handler(base::BindOnce(
+ &media::AudioInputIPCDelegate::OnError, base::Unretained(delegate_)));
+
+ stream_creator_.Run(mojo::MakeRequest(&stream_), session_id, params,
+ automatic_gain_control, total_segments, std::move(client),
+ base::BindOnce(&MojoAudioInputIPC::StreamCreated,
+ weak_factory_.GetWeakPtr()));
+
+ // Unretained is safe since |delegate_| is required to remain valid until
+ // CloseStream is called, which closes the binding.
+ stream_.set_connection_error_handler(base::BindOnce(
+ &media::AudioInputIPCDelegate::OnError, base::Unretained(delegate_)));
+}
+
+void MojoAudioInputIPC::RecordStream() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (stream_.is_bound())
+ stream_->Record();
+}
+
+void MojoAudioInputIPC::SetVolume(double volume) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (stream_.is_bound())
+ stream_->SetVolume(volume);
+}
+
+void MojoAudioInputIPC::CloseStream() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ client_binding_.Close();
+ stream_.reset();
+ delegate_ = nullptr;
+}
+
+void MojoAudioInputIPC::StreamCreated(
+ mojo::ScopedSharedBufferHandle shared_memory,
+ mojo::ScopedHandle socket,
+ bool initially_muted) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(delegate_);
+ DCHECK(socket.is_valid());
+ DCHECK(shared_memory.is_valid());
+
+ base::PlatformFile socket_handle;
+ auto result = mojo::UnwrapPlatformFile(std::move(socket), &socket_handle);
+ DCHECK_EQ(result, MOJO_RESULT_OK);
+
+ base::SharedMemoryHandle memory_handle;
+ bool read_only = true;
+ result = mojo::UnwrapSharedMemoryHandle(std::move(shared_memory),
+ &memory_handle, nullptr, &read_only);
+ DCHECK_EQ(result, MOJO_RESULT_OK);
+ DCHECK(read_only);
+
+ delegate_->OnStreamCreated(memory_handle, socket_handle, initially_muted);
+}
+
+void MojoAudioInputIPC::OnError() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(delegate_);
+ delegate_->OnError();
+}
+
+void MojoAudioInputIPC::OnMutedStateChanged(bool is_muted) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(delegate_);
+ delegate_->OnMuted(is_muted);
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/mojo_audio_input_ipc.h b/chromium/content/renderer/media/mojo_audio_input_ipc.h
new file mode 100644
index 00000000000..66ff89263b8
--- /dev/null
+++ b/chromium/content/renderer/media/mojo_audio_input_ipc.h
@@ -0,0 +1,80 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_MOJO_AUDIO_INPUT_IPC_H_
+#define CONTENT_RENDERER_MEDIA_MOJO_AUDIO_INPUT_IPC_H_
+
+#include <string>
+
+#include "base/callback_helpers.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "content/common/content_export.h"
+#include "media/audio/audio_input_ipc.h"
+#include "media/mojo/interfaces/audio_input_stream.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+namespace content {
+
+// MojoAudioInputIPC is a renderer-side class for handling creation,
+// initialization and control of an input stream. May only be used on a single
+// thread.
+class CONTENT_EXPORT MojoAudioInputIPC
+ : public media::AudioInputIPC,
+ public media::mojom::AudioInputStreamClient {
+ public:
+ using StreamCreatedCB =
+ base::OnceCallback<void(mojo::ScopedSharedBufferHandle shared_memory,
+ mojo::ScopedHandle socket,
+ bool initially_muted)>;
+
+ using StreamCreatorCB = base::RepeatingCallback<void(
+ media::mojom::AudioInputStreamRequest,
+ int64_t session_id,
+ media::AudioParameters params,
+ bool automatic_gain_control,
+ uint32_t total_segments,
+ media::mojom::AudioInputStreamClientPtr client,
+ StreamCreatedCB on_stream_created)>;
+
+ // |stream_creator| is required to create a stream and call on_stream_created.
+ // It will get posted on the |main_task_runner| during CreateStream.
+ explicit MojoAudioInputIPC(StreamCreatorCB stream_creator);
+ ~MojoAudioInputIPC() override;
+
+ // AudioInputIPC implementation
+ void CreateStream(media::AudioInputIPCDelegate* delegate,
+ int session_id,
+ const media::AudioParameters& params,
+ bool automatic_gain_control,
+ uint32_t total_segments) override;
+ void RecordStream() override;
+ void SetVolume(double volume) override;
+ void CloseStream() override;
+
+ private:
+ void StreamCreated(mojo::ScopedSharedBufferHandle shared_memory,
+ mojo::ScopedHandle socket,
+ bool initially_muted);
+
+ void OnError() override;
+ void OnMutedStateChanged(bool is_muted) override;
+
+ StreamCreatorCB stream_creator_;
+
+ THREAD_CHECKER(thread_checker_);
+
+ media::mojom::AudioInputStreamPtr stream_;
+ mojo::Binding<AudioInputStreamClient> client_binding_;
+ media::AudioInputIPCDelegate* delegate_ = nullptr;
+
+ base::WeakPtrFactory<MojoAudioInputIPC> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(MojoAudioInputIPC);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_MOJO_AUDIO_INPUT_IPC_H_
diff --git a/chromium/content/renderer/media/mojo_audio_input_ipc_unittest.cc b/chromium/content/renderer/media/mojo_audio_input_ipc_unittest.cc
new file mode 100644
index 00000000000..4ff63b2d8f7
--- /dev/null
+++ b/chromium/content/renderer/media/mojo_audio_input_ipc_unittest.cc
@@ -0,0 +1,249 @@
+// Copyright 2017 The Chromium Authors. 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/mojo_audio_input_ipc.h"
+
+#include <algorithm>
+#include <memory>
+#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 "media/audio/audio_device_description.h"
+#include "media/base/audio_parameters.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/system/buffer.h"
+#include "mojo/public/cpp/system/platform_handle.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/origin.h"
+
+using testing::_;
+using testing::AtLeast;
+using testing::Invoke;
+using testing::Mock;
+using testing::StrictMock;
+
+namespace content {
+
+namespace {
+
+const int kSessionId = 1234;
+const size_t kMemoryLength = 4321;
+const size_t kTotalSegments = 1;
+const double kNewVolume = 0.271828;
+
+media::AudioParameters Params() {
+ return media::AudioParameters::UnavailableDeviceParams();
+}
+
+class MockStream : public media::mojom::AudioInputStream {
+ public:
+ MOCK_METHOD0(Record, void());
+ MOCK_METHOD1(SetVolume, void(double));
+};
+
+class MockDelegate : public media::AudioInputIPCDelegate {
+ public:
+ MockDelegate() {}
+ ~MockDelegate() override {}
+
+ void OnStreamCreated(base::SharedMemoryHandle mem_handle,
+ base::SyncSocket::Handle socket_handle,
+ bool initially_muted) override {
+ base::SharedMemory sh_mem(
+ mem_handle, /*read_only*/ false); // Releases the shared memory handle.
+ base::SyncSocket socket(socket_handle); // Releases the socket descriptor.
+ GotOnStreamCreated(initially_muted);
+ }
+
+ MOCK_METHOD1(GotOnStreamCreated, void(bool initially_muted));
+ MOCK_METHOD0(OnError, void());
+ MOCK_METHOD1(OnMuted, void(bool));
+ MOCK_METHOD0(OnIPCClosed, void());
+};
+
+class FakeStreamCreator {
+ public:
+ FakeStreamCreator(media::mojom::AudioInputStream* stream,
+ bool initially_muted)
+ : stream_(stream), initially_muted_(initially_muted) {}
+
+ void Create(media::mojom::AudioInputStreamRequest stream_request,
+ int64_t session_id,
+ media::AudioParameters params,
+ bool automatic_gain_control,
+ uint32_t total_segments,
+ media::mojom::AudioInputStreamClientPtr client,
+ MojoAudioInputIPC::StreamCreatedCB on_stream_created) {
+ EXPECT_EQ(binding_, base::nullopt);
+ EXPECT_NE(stream_, nullptr);
+ std::swap(client_, client);
+ binding_.emplace(stream_, std::move(stream_request));
+ base::CancelableSyncSocket foreign_socket;
+ EXPECT_TRUE(
+ base::CancelableSyncSocket::CreatePair(&socket_, &foreign_socket));
+ std::move(on_stream_created)
+ .Run(mojo::SharedBufferHandle::Create(kMemoryLength)
+ ->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY),
+ mojo::WrapPlatformFile(foreign_socket.Release()),
+ initially_muted_);
+ }
+
+ MojoAudioInputIPC::StreamCreatorCB GetCallback() {
+ return base::BindRepeating(&FakeStreamCreator::Create,
+ base::Unretained(this));
+ }
+
+ void Rearm() {
+ binding_.reset();
+ socket_.Close();
+ }
+
+ void SignalError() {
+ ASSERT_TRUE(client_);
+ client_->OnError();
+ }
+
+ private:
+ media::mojom::AudioInputStream* stream_;
+ media::mojom::AudioInputStreamClientPtr client_;
+ base::Optional<mojo::Binding<media::mojom::AudioInputStream>> binding_;
+ bool initially_muted_;
+ base::CancelableSyncSocket socket_;
+};
+
+} // namespace
+
+TEST(MojoAudioInputIPC, OnStreamCreated_Propagates) {
+ base::MessageLoopForIO message_loop;
+ StrictMock<MockStream> stream;
+ StrictMock<MockDelegate> delegate;
+ FakeStreamCreator creator(&stream, false);
+
+ const std::unique_ptr<media::AudioInputIPC> ipc =
+ std::make_unique<MojoAudioInputIPC>(creator.GetCallback());
+
+ EXPECT_CALL(delegate, GotOnStreamCreated(false));
+
+ ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments);
+ base::RunLoop().RunUntilIdle();
+
+ ipc->CloseStream();
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST(MojoAudioInputIPC, OnStreamCreated_PropagatesInitiallyMuted) {
+ base::MessageLoopForIO message_loop;
+ StrictMock<MockStream> stream;
+ StrictMock<MockDelegate> delegate;
+ FakeStreamCreator creator(&stream, true);
+
+ const std::unique_ptr<media::AudioInputIPC> ipc =
+ std::make_unique<MojoAudioInputIPC>(creator.GetCallback());
+
+ EXPECT_CALL(delegate, GotOnStreamCreated(true));
+
+ ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments);
+ base::RunLoop().RunUntilIdle();
+
+ ipc->CloseStream();
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST(MojoAudioInputIPC, IsReusable) {
+ base::MessageLoopForIO message_loop;
+ StrictMock<MockStream> stream;
+ StrictMock<MockDelegate> delegate;
+ FakeStreamCreator creator(&stream, false);
+
+ const std::unique_ptr<media::AudioInputIPC> ipc =
+ std::make_unique<MojoAudioInputIPC>(creator.GetCallback());
+
+ for (int i = 0; i < 5; ++i) {
+ creator.Rearm();
+
+ EXPECT_CALL(delegate, GotOnStreamCreated(_));
+
+ ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments);
+ base::RunLoop().RunUntilIdle();
+ Mock::VerifyAndClearExpectations(&delegate);
+
+ ipc->CloseStream();
+ base::RunLoop().RunUntilIdle();
+ }
+}
+
+TEST(MojoAudioInputIPC, IsReusableAfterError) {
+ base::MessageLoopForIO message_loop;
+ StrictMock<MockStream> stream;
+ StrictMock<MockDelegate> delegate;
+ FakeStreamCreator creator(&stream, false);
+
+ const std::unique_ptr<media::AudioInputIPC> ipc =
+ std::make_unique<MojoAudioInputIPC>(creator.GetCallback());
+
+ for (int i = 0; i < 5; ++i) {
+ creator.Rearm();
+
+ EXPECT_CALL(delegate, GotOnStreamCreated(_));
+
+ ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments);
+ base::RunLoop().RunUntilIdle();
+ Mock::VerifyAndClearExpectations(&delegate);
+
+ EXPECT_CALL(delegate, OnError());
+ creator.SignalError();
+ base::RunLoop().RunUntilIdle();
+ Mock::VerifyAndClearExpectations(&delegate);
+
+ ipc->CloseStream();
+ base::RunLoop().RunUntilIdle();
+ }
+}
+
+TEST(MojoAudioInputIPC, Record_Records) {
+ base::MessageLoopForIO message_loop;
+ StrictMock<MockStream> stream;
+ StrictMock<MockDelegate> delegate;
+ FakeStreamCreator creator(&stream, false);
+
+ const std::unique_ptr<media::AudioInputIPC> ipc =
+ std::make_unique<MojoAudioInputIPC>(creator.GetCallback());
+
+ EXPECT_CALL(delegate, GotOnStreamCreated(_));
+ EXPECT_CALL(stream, Record());
+
+ ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments);
+ ipc->RecordStream();
+ base::RunLoop().RunUntilIdle();
+
+ ipc->CloseStream();
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST(MojoAudioInputIPC, SetVolume_SetsVolume) {
+ base::MessageLoopForIO message_loop;
+ StrictMock<MockStream> stream;
+ StrictMock<MockDelegate> delegate;
+ FakeStreamCreator creator(&stream, false);
+
+ const std::unique_ptr<media::AudioInputIPC> ipc =
+ std::make_unique<MojoAudioInputIPC>(creator.GetCallback());
+
+ EXPECT_CALL(delegate, GotOnStreamCreated(_));
+ EXPECT_CALL(stream, SetVolume(kNewVolume));
+
+ ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments);
+ ipc->SetVolume(kNewVolume);
+ base::RunLoop().RunUntilIdle();
+
+ ipc->CloseStream();
+ base::RunLoop().RunUntilIdle();
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/mojo_audio_output_ipc_unittest.cc b/chromium/content/renderer/media/mojo_audio_output_ipc_unittest.cc
index 4973b695661..c5624ace5b3 100644
--- a/chromium/content/renderer/media/mojo_audio_output_ipc_unittest.cc
+++ b/chromium/content/renderer/media/mojo_audio_output_ipc_unittest.cc
@@ -204,7 +204,7 @@ TEST(MojoAudioOutputIPC, AuthorizeWithoutFactory_CallsAuthorizedWithError) {
StrictMock<MockDelegate> delegate;
std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(NullAccessor());
+ std::make_unique<MojoAudioOutputIPC>(NullAccessor());
EXPECT_CALL(delegate,
OnDeviceAuthorized(media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL, _,
@@ -224,9 +224,9 @@ TEST(MojoAudioOutputIPC, DeviceAuthorized_Propagates) {
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
stream_factory.PrepareProviderForAuthorization(
- kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(nullptr));
+ kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(nullptr));
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
@@ -246,9 +246,9 @@ TEST(MojoAudioOutputIPC, OnDeviceCreated_Propagates) {
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
stream_factory.PrepareProviderForAuthorization(
- kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
+ kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
ipc->CreateStream(&delegate, Params());
@@ -270,7 +270,7 @@ TEST(MojoAudioOutputIPC,
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
// Note: This call implicitly EXPECTs that authorization is requested,
// and constructing the TestStreamProvider with a |&stream| EXPECTs that the
@@ -278,7 +278,7 @@ TEST(MojoAudioOutputIPC,
// device and no session id.
stream_factory.PrepareProviderForAuthorization(
0, std::string(media::AudioDeviceDescription::kDefaultDeviceId),
- base::MakeUnique<TestStreamProvider>(&stream));
+ std::make_unique<TestStreamProvider>(&stream));
ipc->CreateStream(&delegate, Params());
@@ -296,11 +296,11 @@ TEST(MojoAudioOutputIPC, IsReusable) {
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
for (int i = 0; i < 5; ++i) {
stream_factory.PrepareProviderForAuthorization(
- kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
+ kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
ipc->CreateStream(&delegate, Params());
@@ -325,10 +325,10 @@ TEST(MojoAudioOutputIPC, IsReusableAfterError) {
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
stream_factory.PrepareProviderForAuthorization(
- kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(nullptr));
+ kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(nullptr));
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
EXPECT_CALL(delegate, OnDeviceAuthorized(
@@ -346,7 +346,7 @@ TEST(MojoAudioOutputIPC, IsReusableAfterError) {
for (int i = 0; i < 5; ++i) {
stream_factory.PrepareProviderForAuthorization(
- kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
+ kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
ipc->CreateStream(&delegate, Params());
@@ -375,7 +375,7 @@ TEST(MojoAudioOutputIPC, DeviceNotAuthorized_Propagates) {
StrictMock<MockDelegate> delegate;
std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
stream_factory.RefuseNextRequest(kSessionId, kDeviceId);
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
@@ -404,7 +404,7 @@ TEST(MojoAudioOutputIPC,
StrictMock<MockDelegate> delegate;
std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
@@ -430,11 +430,11 @@ TEST(MojoAudioOutputIPC,
base::MessageLoopForIO message_loop;
TestRemoteFactory stream_factory;
stream_factory.PrepareProviderForAuthorization(
- kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(nullptr));
+ kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(nullptr));
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
@@ -456,10 +456,10 @@ TEST(MojoAudioOutputIPC, AuthorizeNoClose_DCHECKs) {
StrictMock<MockDelegate> delegate;
stream_factory.PrepareProviderForAuthorization(
- kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(nullptr));
+ kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(nullptr));
std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
EXPECT_DCHECK_DEATH(ipc.reset());
@@ -476,10 +476,10 @@ TEST(MojoAudioOutputIPC, CreateNoClose_DCHECKs) {
stream_factory.PrepareProviderForAuthorization(
0, std::string(media::AudioDeviceDescription::kDefaultDeviceId),
- base::MakeUnique<TestStreamProvider>(&stream));
+ std::make_unique<TestStreamProvider>(&stream));
std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
ipc->CreateStream(&delegate, Params());
EXPECT_DCHECK_DEATH(ipc.reset());
@@ -495,9 +495,9 @@ TEST(MojoAudioOutputIPC, Play_Plays) {
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
stream_factory.PrepareProviderForAuthorization(
- kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
+ kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
ipc->CreateStream(&delegate, Params());
@@ -521,9 +521,9 @@ TEST(MojoAudioOutputIPC, Pause_Pauses) {
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
stream_factory.PrepareProviderForAuthorization(
- kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
+ kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
ipc->CreateStream(&delegate, Params());
@@ -547,9 +547,9 @@ TEST(MojoAudioOutputIPC, SetVolume_SetsVolume) {
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioOutputIPC> ipc =
- base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
+ std::make_unique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
stream_factory.PrepareProviderForAuthorization(
- kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
+ kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(&stream));
ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
ipc->CreateStream(&delegate, Params());
diff --git a/chromium/content/renderer/media/peer_connection_tracker.cc b/chromium/content/renderer/media/peer_connection_tracker.cc
index 5d09c4bbbb7..de9a77bde42 100644
--- a/chromium/content/renderer/media/peer_connection_tracker.cc
+++ b/chromium/content/renderer/media/peer_connection_tracker.cc
@@ -254,9 +254,9 @@ static const char* GetIceGatheringStateString(
static std::unique_ptr<base::DictionaryValue> GetDictValueStats(
const StatsReport& report) {
if (report.values().empty())
- return NULL;
+ return nullptr;
- auto values = base::MakeUnique<base::ListValue>();
+ auto values = std::make_unique<base::ListValue>();
for (const auto& v : report.values()) {
const StatsReport::ValuePtr& value = v.second;
@@ -286,7 +286,7 @@ static std::unique_ptr<base::DictionaryValue> GetDictValueStats(
}
}
- auto dict = base::MakeUnique<base::DictionaryValue>();
+ auto dict = std::make_unique<base::DictionaryValue>();
dict->SetDouble("timestamp", report.timestamp());
dict->Set("values", std::move(values));
@@ -299,12 +299,12 @@ static std::unique_ptr<base::DictionaryValue> GetDictValue(
const StatsReport& report) {
std::unique_ptr<base::DictionaryValue> stats = GetDictValueStats(report);
if (!stats)
- return NULL;
+ return nullptr;
// Note:
// The format must be consistent with what webrtc_internals.js expects.
// If you change it here, you must change webrtc_internals.js as well.
- auto result = base::MakeUnique<base::DictionaryValue>();
+ auto result = std::make_unique<base::DictionaryValue>();
result->Set("stats", std::move(stats));
result->SetString("id", report.id()->ToString());
result->SetString("type", report.TypeToString());
@@ -550,18 +550,18 @@ void PeerConnectionTracker::TrackSetConfiguration(
}
void PeerConnectionTracker::TrackAddIceCandidate(
- RTCPeerConnectionHandler* pc_handler,
- const blink::WebRTCICECandidate& candidate,
- Source source,
- bool succeeded) {
+ RTCPeerConnectionHandler* pc_handler,
+ scoped_refptr<blink::WebRTCICECandidate> candidate,
+ Source source,
+ bool succeeded) {
DCHECK(main_thread_.CalledOnValidThread());
int id = GetLocalIDForHandler(pc_handler);
if (id == -1)
return;
std::string value =
- "sdpMid: " + candidate.SdpMid().Utf8() + ", " +
- "sdpMLineIndex: " + base::UintToString(candidate.SdpMLineIndex()) + ", " +
- "candidate: " + candidate.Candidate().Utf8();
+ "sdpMid: " + candidate->SdpMid().Utf8() + ", " +
+ "sdpMLineIndex: " + base::UintToString(candidate->SdpMLineIndex()) +
+ ", " + "candidate: " + candidate->Candidate().Utf8();
// OnIceCandidate always succeeds as it's a callback from the browser.
DCHECK(source != SOURCE_LOCAL || succeeded);
diff --git a/chromium/content/renderer/media/peer_connection_tracker.h b/chromium/content/renderer/media/peer_connection_tracker.h
index 1bb740a8f16..8bbcbe3ba08 100644
--- a/chromium/content/renderer/media/peer_connection_tracker.h
+++ b/chromium/content/renderer/media/peer_connection_tracker.h
@@ -68,8 +68,8 @@ class CONTENT_EXPORT PeerConnectionTracker
// UnregisterPeerConnection, otherwise the Track* call has no effect.
//
- // Sends an update when a PeerConnection has been created in Javascript. This
- // should be called once and only once for each PeerConnection. The
+ // Sends an update when a PeerConnection has been created in Javascript. This
+ // should be called once and only once for each PeerConnection. The
// |pc_handler| is the handler object associated with the PeerConnection, the
// |servers| are the server configurations used to establish the connection,
// the |constraints| are the media constraints used to initialize the
@@ -110,7 +110,7 @@ class CONTENT_EXPORT PeerConnectionTracker
// Sends an update when an Ice candidate is added.
virtual void TrackAddIceCandidate(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebRTCICECandidate& candidate,
+ scoped_refptr<blink::WebRTCICECandidate> candidate,
Source source,
bool succeeded);
@@ -176,7 +176,7 @@ class CONTENT_EXPORT PeerConnectionTracker
// The return value will always be positive.
int GetNextLocalID();
- // Looks up a handler in our map and if found, returns its ID. If the handler
+ // Looks up a handler in our map and if found, returns its ID. If the handler
// is not registered, the return value will be -1.
int GetLocalIDForHandler(RTCPeerConnectionHandler* handler) const;
diff --git a/chromium/content/renderer/media/pepper_to_video_track_adapter_unittest.cc b/chromium/content/renderer/media/pepper_to_video_track_adapter_unittest.cc
index c5e0115e402..b371a23bb1c 100644
--- a/chromium/content/renderer/media/pepper_to_video_track_adapter_unittest.cc
+++ b/chromium/content/renderer/media/pepper_to_video_track_adapter_unittest.cc
@@ -44,8 +44,9 @@ class PepperToVideoTrackAdapterTest : public PpapiUnittest {
}
protected:
- // A ChildProcess and a MessageLoop are both needed to fool the Tracks and
- // Sources inside |registry_| into believing they are on the right threads.
+ // 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_;
@@ -63,7 +64,7 @@ TEST_F(PepperToVideoTrackAdapterTest, Open) {
}
TEST_F(PepperToVideoTrackAdapterTest, PutFrame) {
- FrameWriterInterface* frame_writer = NULL;
+ FrameWriterInterface* frame_writer = nullptr;
EXPECT_TRUE(PepperToVideoTrackAdapter::Open(registry_.get(),
kTestStreamUrl, &frame_writer));
ASSERT_TRUE(frame_writer);
@@ -77,7 +78,7 @@ TEST_F(PepperToVideoTrackAdapterTest, PutFrame) {
// Verify the native video track has been added.
MediaStreamVideoTrack* native_track =
MediaStreamVideoTrack::GetVideoTrack(video_tracks[0]);
- ASSERT_TRUE(native_track != NULL);
+ ASSERT_TRUE(native_track != nullptr);
MockMediaStreamVideoSink sink;
native_track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
diff --git a/chromium/content/renderer/media/render_media_log.cc b/chromium/content/renderer/media/render_media_log.cc
index 2972ec7a862..60201ae1edf 100644
--- a/chromium/content/renderer/media/render_media_log.cc
+++ b/chromium/content/renderer/media/render_media_log.cc
@@ -42,7 +42,7 @@ namespace content {
RenderMediaLog::RenderMediaLog(const GURL& security_origin)
: security_origin_(security_origin),
task_runner_(base::ThreadTaskRunnerHandle::Get()),
- tick_clock_(new base::DefaultTickClock()),
+ tick_clock_(base::DefaultTickClock::GetInstance()),
last_ipc_send_time_(tick_clock_->NowTicks()),
ipc_send_pending_(false),
weak_factory_(this) {
@@ -182,10 +182,9 @@ void RenderMediaLog::SendQueuedMediaEvents() {
RenderThread::Get()->Send(new ViewHostMsg_MediaLogEvents(events_to_send));
}
-void RenderMediaLog::SetTickClockForTesting(
- std::unique_ptr<base::TickClock> tick_clock) {
+void RenderMediaLog::SetTickClockForTesting(base::TickClock* tick_clock) {
base::AutoLock auto_lock(lock_);
- tick_clock_.swap(tick_clock);
+ tick_clock_ = tick_clock;
last_ipc_send_time_ = tick_clock_->NowTicks();
}
diff --git a/chromium/content/renderer/media/render_media_log.h b/chromium/content/renderer/media/render_media_log.h
index 62c1256bf34..cc27d5cfcf8 100644
--- a/chromium/content/renderer/media/render_media_log.h
+++ b/chromium/content/renderer/media/render_media_log.h
@@ -43,7 +43,7 @@ class CONTENT_EXPORT RenderMediaLog : public media::MediaLog {
void RecordRapporWithSecurityOrigin(const std::string& metric) override;
// Will reset |last_ipc_send_time_| with the value of NowTicks().
- void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
+ void SetTickClockForTesting(base::TickClock* tick_clock);
void SetTaskRunnerForTesting(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
@@ -62,7 +62,7 @@ class CONTENT_EXPORT RenderMediaLog : public media::MediaLog {
// sequence for throttled send on |task_runner_| and coherent retrieval by
// GetErrorMessage().
mutable base::Lock lock_;
- std::unique_ptr<base::TickClock> tick_clock_;
+ base::TickClock* tick_clock_;
base::TimeTicks last_ipc_send_time_;
std::vector<media::MediaLogEvent> queued_media_events_;
diff --git a/chromium/content/renderer/media/render_media_log_unittest.cc b/chromium/content/renderer/media/render_media_log_unittest.cc
index 410c8dfe1a8..d96e5e49002 100644
--- a/chromium/content/renderer/media/render_media_log_unittest.cc
+++ b/chromium/content/renderer/media/render_media_log_unittest.cc
@@ -19,9 +19,8 @@ class RenderMediaLogTest : public testing::Test {
public:
RenderMediaLogTest()
: log_(GURL("http://foo.com")),
- tick_clock_(new base::SimpleTestTickClock()),
task_runner_(new base::TestMockTimeTaskRunner()) {
- log_.SetTickClockForTesting(std::unique_ptr<base::TickClock>(tick_clock_));
+ log_.SetTickClockForTesting(&tick_clock_);
log_.SetTaskRunnerForTesting(task_runner_);
}
@@ -36,7 +35,7 @@ class RenderMediaLogTest : public testing::Test {
}
void Advance(base::TimeDelta delta) {
- tick_clock_->Advance(delta);
+ tick_clock_.Advance(delta);
task_runner_->FastForwardBy(delta);
}
@@ -58,8 +57,8 @@ class RenderMediaLogTest : public testing::Test {
private:
base::MessageLoop message_loop_;
MockRenderThread render_thread_;
+ base::SimpleTestTickClock tick_clock_;
RenderMediaLog log_;
- base::SimpleTestTickClock* tick_clock_; // Owned by |log_|.
scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
DISALLOW_COPY_AND_ASSIGN(RenderMediaLogTest);
diff --git a/chromium/content/renderer/media/renderer_webaudiodevice_impl.h b/chromium/content/renderer/media/renderer_webaudiodevice_impl.h
index b573e2fae2e..4b887a8bef0 100644
--- a/chromium/content/renderer/media/renderer_webaudiodevice_impl.h
+++ b/chromium/content/renderer/media/renderer_webaudiodevice_impl.h
@@ -15,7 +15,6 @@
#include "media/base/audio_renderer_sink.h"
#include "third_party/WebKit/public/platform/WebAudioDevice.h"
#include "third_party/WebKit/public/platform/WebAudioLatencyHint.h"
-#include "third_party/WebKit/public/platform/WebVector.h"
#include "url/origin.h"
namespace base {
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
index 0a927d67087..a22486e4c7b 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -38,8 +38,7 @@ RendererWebMediaPlayerDelegate::RendererWebMediaPlayerDelegate(
: RenderFrameObserver(render_frame),
allow_idle_cleanup_(
content::GetContentClient()->renderer()->AllowIdleMediaSuspend()),
- default_tick_clock_(new base::DefaultTickClock()),
- tick_clock_(default_tick_clock_.get()) {
+ tick_clock_(base::DefaultTickClock::GetInstance()) {
idle_cleanup_interval_ = base::TimeDelta::FromSeconds(5);
idle_timeout_ = base::TimeDelta::FromSeconds(15);
@@ -222,6 +221,10 @@ bool RendererWebMediaPlayerDelegate::OnMessageReceived(
IPC_BEGIN_MESSAGE_MAP(RendererWebMediaPlayerDelegate, msg)
IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_Pause, OnMediaDelegatePause)
IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_Play, OnMediaDelegatePlay)
+ IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_SeekForward,
+ OnMediaDelegateSeekForward)
+ IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_SeekBackward,
+ OnMediaDelegateSeekBackward)
IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_SuspendAllMediaPlayers,
OnMediaDelegateSuspendAllMediaPlayers)
IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_UpdateVolumeMultiplier,
@@ -288,6 +291,26 @@ void RendererWebMediaPlayerDelegate::OnMediaDelegatePlay(int player_id) {
}
}
+void RendererWebMediaPlayerDelegate::OnMediaDelegateSeekForward(
+ int player_id,
+ base::TimeDelta seek_time) {
+ RecordAction(base::UserMetricsAction("Media.Controls.RemoteSeekForward"));
+
+ Observer* observer = id_map_.Lookup(player_id);
+ if (observer)
+ observer->OnSeekForward(seek_time.InSecondsF());
+}
+
+void RendererWebMediaPlayerDelegate::OnMediaDelegateSeekBackward(
+ int player_id,
+ base::TimeDelta seek_time) {
+ RecordAction(base::UserMetricsAction("Media.Controls.RemoteSeekBackward"));
+
+ Observer* observer = id_map_.Lookup(player_id);
+ if (observer)
+ observer->OnSeekBackward(seek_time.InSecondsF());
+}
+
void RendererWebMediaPlayerDelegate::OnMediaDelegateSuspendAllMediaPlayers() {
is_frame_closed_ = true;
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
index 21744a52f3e..65dea01258d 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -83,6 +83,8 @@ class CONTENT_EXPORT RendererWebMediaPlayerDelegate
private:
void OnMediaDelegatePause(int player_id);
void OnMediaDelegatePlay(int player_id);
+ void OnMediaDelegateSeekForward(int player_id, base::TimeDelta seek_time);
+ void OnMediaDelegateSeekBackward(int player_id, base::TimeDelta seek_time);
void OnMediaDelegateSuspendAllMediaPlayers();
void OnMediaDelegateVolumeMultiplierUpdate(int player_id, double multiplier);
void OnMediaDelegateBecamePersistentVideo(int player_id, bool value);
@@ -134,7 +136,6 @@ class CONTENT_EXPORT RendererWebMediaPlayerDelegate
// Clock used for calculating when players have become stale. May be
// overridden for testing.
- std::unique_ptr<base::DefaultTickClock> default_tick_clock_;
base::TickClock* tick_clock_;
#if defined(OS_ANDROID)
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc b/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
index 2015354f310..2eae16d02b0 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
@@ -43,6 +43,8 @@ class MockWebMediaPlayerDelegateObserver
MOCK_METHOD0(OnIdleTimeout, void());
MOCK_METHOD0(OnPlay, void());
MOCK_METHOD0(OnPause, void());
+ MOCK_METHOD1(OnSeekForward, void(double));
+ MOCK_METHOD1(OnSeekBackward, void(double));
MOCK_METHOD1(OnVolumeMultiplierUpdate, void(double));
MOCK_METHOD1(OnBecamePersistentVideo, void(bool));
};
@@ -208,6 +210,18 @@ TEST_F(RendererWebMediaPlayerDelegateTest, DeliversObserverNotifications) {
MediaPlayerDelegateMsg_Play play_msg(0, delegate_id);
delegate_manager_->OnMessageReceived(play_msg);
+ const double kTestSeekForwardSeconds = 1.0;
+ EXPECT_CALL(observer_1_, OnSeekForward(kTestSeekForwardSeconds));
+ MediaPlayerDelegateMsg_SeekForward seek_forward_msg(
+ 0, delegate_id, base::TimeDelta::FromSeconds(kTestSeekForwardSeconds));
+ delegate_manager_->OnMessageReceived(seek_forward_msg);
+
+ const double kTestSeekBackwardSeconds = 2.0;
+ EXPECT_CALL(observer_1_, OnSeekBackward(kTestSeekBackwardSeconds));
+ MediaPlayerDelegateMsg_SeekBackward seek_backward_msg(
+ 0, delegate_id, base::TimeDelta::FromSeconds(kTestSeekBackwardSeconds));
+ delegate_manager_->OnMessageReceived(seek_backward_msg);
+
const double kTestMultiplier = 0.5;
EXPECT_CALL(observer_1_, OnVolumeMultiplierUpdate(kTestMultiplier));
MediaPlayerDelegateMsg_UpdateVolumeMultiplier volume_msg(0, delegate_id,
diff --git a/chromium/content/renderer/media/rtc_certificate_generator.cc b/chromium/content/renderer/media/rtc_certificate_generator.cc
index 5a2032787a2..f79b21441f5 100644
--- a/chromium/content/renderer/media/rtc_certificate_generator.cc
+++ b/chromium/content/renderer/media/rtc_certificate_generator.cc
@@ -95,7 +95,7 @@ class RTCCertificateGeneratorRequest
base::BindOnce(
&RTCCertificateGeneratorRequest::DoCallbackOnMainThread, this,
base::Passed(std::move(observer)),
- base::Passed(base::MakeUnique<RTCCertificate>(certificate))));
+ base::Passed(std::make_unique<RTCCertificate>(certificate))));
}
void DoCallbackOnMainThread(
@@ -168,7 +168,7 @@ std::unique_ptr<blink::WebRTCCertificate> RTCCertificateGenerator::FromPEM(
pem_private_key.Utf8(), pem_certificate.Utf8()));
if (!certificate)
return nullptr;
- return base::MakeUnique<RTCCertificate>(certificate);
+ return std::make_unique<RTCCertificate>(certificate);
}
} // namespace content
diff --git a/chromium/content/renderer/media/rtc_data_channel_handler.cc b/chromium/content/renderer/media/rtc_data_channel_handler.cc
index dc82acb3098..d423b3626f1 100644
--- a/chromium/content/renderer/media/rtc_data_channel_handler.cc
+++ b/chromium/content/renderer/media/rtc_data_channel_handler.cc
@@ -134,7 +134,7 @@ RtcDataChannelHandler::RtcDataChannelHandler(
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
webrtc::DataChannelInterface* channel)
: observer_(new Observer(this, main_thread, channel)),
- webkit_client_(NULL) {
+ webkit_client_(nullptr) {
DVLOG(1) << "RtcDataChannelHandler " << channel->label();
// Detach from the ctor thread since we can be constructed on either the main
diff --git a/chromium/content/renderer/media/rtc_dtmf_sender_handler.cc b/chromium/content/renderer/media/rtc_dtmf_sender_handler.cc
index 9804fc986ca..d61b43bde03 100644
--- a/chromium/content/renderer/media/rtc_dtmf_sender_handler.cc
+++ b/chromium/content/renderer/media/rtc_dtmf_sender_handler.cc
@@ -50,9 +50,7 @@ class RtcDtmfSenderHandler::Observer :
};
RtcDtmfSenderHandler::RtcDtmfSenderHandler(DtmfSenderInterface* dtmf_sender)
- : dtmf_sender_(dtmf_sender),
- webkit_client_(NULL),
- weak_factory_(this) {
+ : dtmf_sender_(dtmf_sender), webkit_client_(nullptr), weak_factory_(this) {
DVLOG(1) << "::ctor";
observer_ = new Observer(weak_factory_.GetWeakPtr());
dtmf_sender_->RegisterObserver(observer_.get());
@@ -63,7 +61,7 @@ RtcDtmfSenderHandler::~RtcDtmfSenderHandler() {
DVLOG(1) << "::dtor";
dtmf_sender_->UnregisterObserver();
// Release |observer| before |weak_factory_| is destroyed.
- observer_ = NULL;
+ observer_ = nullptr;
}
void RtcDtmfSenderHandler::SetClient(
diff --git a/chromium/content/renderer/media/rtc_peer_connection_handler.cc b/chromium/content/renderer/media/rtc_peer_connection_handler.cc
index 710d7938334..fd3f94f0428 100644
--- a/chromium/content/renderer/media/rtc_peer_connection_handler.cc
+++ b/chromium/content/renderer/media/rtc_peer_connection_handler.cc
@@ -28,9 +28,9 @@
#include "content/renderer/media/rtc_data_channel_handler.h"
#include "content/renderer/media/rtc_dtmf_sender_handler.h"
#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
-#include "content/renderer/media/webrtc/rtc_rtp_receiver.h"
#include "content/renderer/media/webrtc/rtc_stats.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h"
+#include "content/renderer/media/webrtc/webrtc_set_remote_description_observer.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
#include "content/renderer/media/webrtc_uma_histograms.h"
#include "content/renderer/render_thread_impl.h"
@@ -454,12 +454,12 @@ class CreateSessionDescriptionRequest
SessionDescriptionRequestTracker tracker_;
};
-// Class mapping responses from calls to libjingle
-// SetLocalDescription/SetRemoteDescription and a blink::WebRTCVoidRequest.
-class SetSessionDescriptionRequest
+// Class mapping responses from calls to libjingle SetLocalDescription and a
+// blink::WebRTCVoidRequest.
+class SetLocalDescriptionRequest
: public webrtc::SetSessionDescriptionObserver {
public:
- explicit SetSessionDescriptionRequest(
+ explicit SetLocalDescriptionRequest(
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
const blink::WebRTCVoidRequest& request,
const base::WeakPtr<RTCPeerConnectionHandler>& handler,
@@ -467,25 +467,24 @@ class SetSessionDescriptionRequest
PeerConnectionTracker::Action action)
: main_thread_(main_thread),
webkit_request_(request),
- tracker_(handler, tracker, action) {
- }
+ tracker_(handler, tracker, action) {}
void OnSuccess() override {
if (!main_thread_->BelongsToCurrentThread()) {
main_thread_->PostTask(
FROM_HERE,
- base::BindOnce(&SetSessionDescriptionRequest::OnSuccess, this));
+ base::BindOnce(&SetLocalDescriptionRequest::OnSuccess, this));
return;
}
- tracker_.TrackOnSuccess(NULL);
+ tracker_.TrackOnSuccess(nullptr);
webkit_request_.RequestSucceeded();
webkit_request_.Reset();
}
void OnFailure(const std::string& error) override {
if (!main_thread_->BelongsToCurrentThread()) {
main_thread_->PostTask(
- FROM_HERE, base::BindOnce(&SetSessionDescriptionRequest::OnFailure,
- this, error));
+ FROM_HERE,
+ base::BindOnce(&SetLocalDescriptionRequest::OnFailure, this, error));
return;
}
tracker_.TrackOnFailure(error);
@@ -494,14 +493,14 @@ class SetSessionDescriptionRequest
}
protected:
- ~SetSessionDescriptionRequest() override {
+ ~SetLocalDescriptionRequest() override {
// This object is reference counted and its callback methods |OnSuccess| and
// |OnFailure| will be invoked on libjingle's signaling thread and posted to
// the main thread. Since the main thread may complete before the signaling
// thread has deferenced this object there is no guarantee that this object
// is destructed on the main thread.
DLOG_IF(ERROR, !webkit_request_.IsNull())
- << "SetSessionDescriptionRequest not completed. Shutting down?";
+ << "SetLocalDescriptionRequest not completed. Shutting down?";
}
private:
@@ -924,29 +923,17 @@ std::set<RTCPeerConnectionHandler*>* GetPeerConnectionHandlers() {
return handlers;
}
-rtc::scoped_refptr<webrtc::RtpReceiverInterface> FindReceiverForTrack(
- const std::string& track_id,
- const std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>>&
- webrtc_receivers) {
- for (const auto& webrtc_receiver : webrtc_receivers) {
- if (webrtc_receiver->track()->id() == track_id)
- return webrtc_receiver;
+// Counts the number of receivers that have |webrtc_stream| as an associated
+// stream.
+size_t GetRemoteStreamUsageCount(
+ const std::map<uintptr_t, std::unique_ptr<RTCRtpReceiver>>& rtp_receivers,
+ const webrtc::MediaStreamInterface* webrtc_stream) {
+ size_t usage_count = 0;
+ for (const auto& receiver_entry : rtp_receivers) {
+ if (receiver_entry.second->HasStream(webrtc_stream))
+ ++usage_count;
}
- return nullptr;
-}
-
-std::unique_ptr<RTCRtpReceiver> CreateRTCRtpReceiverForTrack(
- webrtc::MediaStreamTrackInterface* webrtc_track,
- const std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>>&
- webrtc_receivers,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map) {
- auto webrtc_receiver =
- FindReceiverForTrack(webrtc_track->id(), webrtc_receivers);
- DCHECK(webrtc_receiver);
- auto track_adapter = track_adapter_map->GetRemoteTrackAdapter(webrtc_track);
- DCHECK(track_adapter);
- return base::MakeUnique<RTCRtpReceiver>(std::move(webrtc_receiver),
- std::move(track_adapter));
+ return usage_count;
}
} // namespace
@@ -986,29 +973,178 @@ void LocalRTCStatsResponse::addStats(const blink::WebRTCLegacyStats& stats) {
impl_.AddStats(stats);
}
-// Receives notifications from a PeerConnection object about state changes,
-// track addition/removal etc. The callbacks we receive here come on the
-// signaling thread, so this class takes care of delivering them to an
-// RTCPeerConnectionHandler instance on the main thread.
-// In order to do safe PostTask-ing, the class is reference counted and
-// checks for the existence of the RTCPeerConnectionHandler instance before
-// delivering callbacks on the main thread.
-class RTCPeerConnectionHandler::Observer
- : public base::RefCountedThreadSafe<RTCPeerConnectionHandler::Observer>,
- public PeerConnectionObserver {
+// Processes the resulting state changes of a SetRemoteDescription call.
+class RTCPeerConnectionHandler::WebRtcSetRemoteDescriptionObserverImpl
+ : public WebRtcSetRemoteDescriptionObserver {
public:
- Observer(const base::WeakPtr<RTCPeerConnectionHandler>& handler)
+ WebRtcSetRemoteDescriptionObserverImpl(
+ base::WeakPtr<RTCPeerConnectionHandler> handler,
+ blink::WebRTCVoidRequest web_request,
+ base::WeakPtr<PeerConnectionTracker> tracker)
: handler_(handler),
main_thread_(base::ThreadTaskRunnerHandle::Get()),
- stream_adapter_map_(handler_->stream_adapter_map_),
- native_peer_connection_(nullptr) {
- DCHECK(stream_adapter_map_);
+ web_request_(web_request),
+ tracker_(tracker) {}
+
+ void OnSetRemoteDescriptionComplete(
+ webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>
+ states_or_error) override {
+ if (!states_or_error.ok()) {
+ auto& error = states_or_error.error();
+ if (tracker_ && handler_) {
+ tracker_->TrackSessionDescriptionCallback(
+ handler_.get(),
+ PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION, "OnFailure",
+ error.message());
+ }
+ // TODO(hbos): Use |error.type()| to reject the promise with the
+ // appropriate DOMException.
+ web_request_.RequestFailed(blink::WebString::FromUTF8(error.message()));
+ web_request_.Reset();
+ return;
+ }
+
+ auto& states = states_or_error.value();
+ if (handler_) {
+ // Determine which receivers have been removed before processing the
+ // removal as to not invalidate the iterator.
+ std::vector<RTCRtpReceiver*> removed_receivers;
+ for (auto it = handler_->rtp_receivers_.begin();
+ it != handler_->rtp_receivers_.end(); ++it) {
+ if (ReceiverWasRemoved(*it->second, states.receiver_states))
+ removed_receivers.push_back(it->second.get());
+ }
+
+ // Update stream states (which tracks belong to which streams).
+ for (auto& stream_state : GetStreamStates(states, removed_receivers)) {
+ stream_state.stream_ref->adapter().SetTracks(
+ std::move(stream_state.track_refs));
+ }
+
+ // Process the addition of remote receivers/tracks.
+ for (auto& receiver_state : states.receiver_states) {
+ if (ReceiverWasAdded(receiver_state)) {
+ handler_->OnAddRemoteTrack(receiver_state.receiver,
+ std::move(receiver_state.track_ref),
+ std::move(receiver_state.stream_refs));
+ }
+ }
+ // Process the removal of remote receivers/tracks.
+ for (auto* removed_receiver : removed_receivers)
+ handler_->OnRemoveRemoteTrack(removed_receiver->webrtc_receiver());
+ if (tracker_) {
+ tracker_->TrackSessionDescriptionCallback(
+ handler_.get(),
+ PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION, "OnSuccess",
+ "");
+ }
+ }
+ // Resolve the promise in a post to ensure any events scheduled for
+ // dispatching will have fired by the time the promise is resolved.
+ // TODO(hbos): Don't schedule/post to fire events/resolve the promise.
+ // Instead, do it all synchronously. This must happen as the last step
+ // before returning so that all effects of SRD have occurred when the event
+ // executes. https://crbug.com/788558
+ main_thread_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &RTCPeerConnectionHandler::WebRtcSetRemoteDescriptionObserverImpl::
+ ResolvePromise,
+ this));
}
- void Initialize(webrtc::PeerConnectionInterface* native_peer_connection) {
- native_peer_connection_ = native_peer_connection;
+ private:
+ ~WebRtcSetRemoteDescriptionObserverImpl() override {}
+
+ // Describes which tracks belong to a stream in terms of AdapterRefs.
+ struct StreamState {
+ StreamState(
+ std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> stream_ref)
+ : stream_ref(std::move(stream_ref)) {}
+
+ std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> stream_ref;
+ std::vector<std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>>
+ track_refs;
+ };
+
+ void ResolvePromise() {
+ web_request_.RequestSucceeded();
+ web_request_.Reset();
+ }
+
+ bool ReceiverWasAdded(const WebRtcReceiverState& receiver_state) {
+ return handler_->rtp_receivers_.find(
+ RTCRtpReceiver::getId(receiver_state.receiver.get())) ==
+ handler_->rtp_receivers_.end();
+ }
+
+ bool ReceiverWasRemoved(
+ const RTCRtpReceiver& receiver,
+ const std::vector<WebRtcReceiverState>& receiver_states) {
+ for (const auto& receiver_state : receiver_states) {
+ if (receiver_state.receiver == receiver.webrtc_receiver())
+ return false;
+ }
+ return true;
+ }
+
+ // Determines the stream states from the current state of receivers and the
+ // receivers that are about to be removed. Produces a stable order of streams.
+ std::vector<StreamState> GetStreamStates(
+ const WebRtcSetRemoteDescriptionObserver::States& states,
+ const std::vector<RTCRtpReceiver*>& removed_receivers) {
+ std::vector<StreamState> stream_states;
+ // The receiver's track belongs to all of its streams. A stream may be
+ // associated with multiple tracks (multiple receivers).
+ for (auto& receiver_state : states.receiver_states) {
+ for (auto& stream_ref : receiver_state.stream_refs) {
+ auto* stream_state =
+ GetOrAddStreamStateForStream(*stream_ref, &stream_states);
+ stream_state->track_refs.push_back(receiver_state.track_ref->Copy());
+ }
+ }
+ // The track of removed receivers do not belong to any stream. Make sure we
+ // have a stream state for any streams belonging to receivers about to be
+ // removed in case it was the last receiver referencing that stream.
+ for (auto* removed_receiver : removed_receivers)
+ for (auto& stream_ref : removed_receiver->StreamAdapterRefs())
+ GetOrAddStreamStateForStream(*stream_ref, &stream_states);
+ return stream_states;
+ }
+
+ StreamState* GetOrAddStreamStateForStream(
+ const WebRtcMediaStreamAdapterMap::AdapterRef& stream_ref,
+ std::vector<StreamState>* stream_states) {
+ auto* webrtc_stream = stream_ref.adapter().webrtc_stream().get();
+ for (auto& stream_state : *stream_states) {
+ if (stream_state.stream_ref->adapter().webrtc_stream().get() ==
+ webrtc_stream) {
+ return &stream_state;
+ }
+ }
+ stream_states->push_back(StreamState(stream_ref.Copy()));
+ return &stream_states->back();
}
+ base::WeakPtr<RTCPeerConnectionHandler> handler_;
+ scoped_refptr<base::SequencedTaskRunner> main_thread_;
+ blink::WebRTCVoidRequest web_request_;
+ base::WeakPtr<PeerConnectionTracker> tracker_;
+};
+
+// Receives notifications from a PeerConnection object about state changes. The
+// callbacks we receive here come on the webrtc signaling thread, so this class
+// takes care of delivering them to an RTCPeerConnectionHandler instance on the
+// main thread. In order to do safe PostTask-ing, the class is reference counted
+// and checks for the existence of the RTCPeerConnectionHandler instance before
+// delivering callbacks on the main thread.
+class RTCPeerConnectionHandler::Observer
+ : public base::RefCountedThreadSafe<RTCPeerConnectionHandler::Observer>,
+ public PeerConnectionObserver {
+ public:
+ Observer(const base::WeakPtr<RTCPeerConnectionHandler>& handler)
+ : handler_(handler), main_thread_(base::ThreadTaskRunnerHandle::Get()) {}
+
protected:
friend class base::RefCountedThreadSafe<RTCPeerConnectionHandler::Observer>;
virtual ~Observer() {}
@@ -1025,56 +1161,9 @@ class RTCPeerConnectionHandler::Observer
}
}
- void OnAddStream(
- rtc::scoped_refptr<MediaStreamInterface> remote_webrtc_stream) override {
- DCHECK(!main_thread_->BelongsToCurrentThread());
- DCHECK(remote_webrtc_stream);
- DCHECK(native_peer_connection_);
- DCHECK(remote_webrtc_stream);
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
- remote_stream_adapter_ref =
- stream_adapter_map_->GetOrCreateRemoteStreamAdapter(
- remote_webrtc_stream.get());
-
- // Because |SetRemoteDescription| is asynchronous it is unsafe to query the
- // |native_peer_connection_|'s state after the callback has jumped back to
- // the main thread - something could happen in-between this callback on the
- // signaling thread and |OnAddStreamImpl|. Every state that the callback on
- // the main thread needs to know about has to be passed as arguments.
- // Get all receivers that belong to the stream's track.
- std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>>
- webrtc_receivers = native_peer_connection_->GetReceivers();
- std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> stream_web_receivers;
- for (const auto& webrtc_audio_track :
- remote_webrtc_stream->GetAudioTracks()) {
- stream_web_receivers.push_back(CreateRTCRtpReceiverForTrack(
- webrtc_audio_track.get(), webrtc_receivers,
- stream_adapter_map_->track_adapter_map()));
- }
- for (const auto& webrtc_video_track :
- remote_webrtc_stream->GetVideoTracks()) {
- stream_web_receivers.push_back(CreateRTCRtpReceiverForTrack(
- webrtc_video_track.get(), webrtc_receivers,
- stream_adapter_map_->track_adapter_map()));
- }
-
- // The webkit object owned by |RemoteMediaStreamImpl|, will be initialized
- // asynchronously and the posted task will execute after that initialization
- // is done.
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&RTCPeerConnectionHandler::Observer::OnAddStreamImpl,
- this, base::Passed(&remote_stream_adapter_ref),
- base::Passed(&stream_web_receivers)));
- }
-
- void OnRemoveStream(
- rtc::scoped_refptr<MediaStreamInterface> remote_webrtc_stream) override {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&RTCPeerConnectionHandler::Observer::OnRemoveStreamImpl,
- this, base::WrapRefCounted(remote_webrtc_stream.get())));
- }
+ // TODO(hbos): Remove once no longer mandatory to implement.
+ void OnAddStream(rtc::scoped_refptr<MediaStreamInterface>) override {}
+ void OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface>) override {}
void OnDataChannel(
rtc::scoped_refptr<DataChannelInterface> data_channel) override {
@@ -1140,25 +1229,6 @@ class RTCPeerConnectionHandler::Observer
candidate->candidate().address().family()));
}
- void OnAddStreamImpl(std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
- remote_stream_adapter_ref,
- std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>>
- stream_webrtc_receivers) {
- DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(remote_stream_adapter_ref->adapter().is_initialized());
- if (handler_) {
- handler_->OnAddStream(std::move(remote_stream_adapter_ref),
- std::move(stream_webrtc_receivers));
- }
- }
-
- void OnRemoveStreamImpl(
- const scoped_refptr<MediaStreamInterface>& remote_webrtc_stream) {
- DCHECK(main_thread_->BelongsToCurrentThread());
- if (handler_)
- handler_->OnRemoveStream(remote_webrtc_stream);
- }
-
void OnDataChannelImpl(std::unique_ptr<RtcDataChannelHandler> handler) {
DCHECK(main_thread_->BelongsToCurrentThread());
if (handler_)
@@ -1177,10 +1247,6 @@ class RTCPeerConnectionHandler::Observer
private:
const base::WeakPtr<RTCPeerConnectionHandler> handler_;
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- const scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map_;
- // Raw pointer. Only guaranteed to be valid within within callbacks on the
- // signaling thread since these are triggered by |native_peer_connection_|.
- webrtc::PeerConnectionInterface* native_peer_connection_;
};
RTCPeerConnectionHandler::RTCPeerConnectionHandler(
@@ -1250,7 +1316,6 @@ bool RTCPeerConnectionHandler::Initialize(
peer_connection_observer_ = new Observer(weak_factory_.GetWeakPtr());
native_peer_connection_ = dependency_factory_->CreatePeerConnection(
configuration_, frame_, peer_connection_observer_.get());
- peer_connection_observer_->Initialize(native_peer_connection_.get());
if (!native_peer_connection_.get()) {
LOG(ERROR) << "Failed to initialize native PeerConnection.";
@@ -1279,7 +1344,6 @@ bool RTCPeerConnectionHandler::InitializeForTest(
native_peer_connection_ = dependency_factory_->CreatePeerConnection(
configuration_, nullptr, peer_connection_observer_.get());
- peer_connection_observer_->Initialize(native_peer_connection_.get());
if (!native_peer_connection_.get()) {
LOG(ERROR) << "Failed to initialize native PeerConnection.";
return false;
@@ -1420,8 +1484,8 @@ void RTCPeerConnectionHandler::SetLocalDescription(
}
}
- scoped_refptr<SetSessionDescriptionRequest> set_request(
- new rtc::RefCountedObject<SetSessionDescriptionRequest>(
+ scoped_refptr<SetLocalDescriptionRequest> set_request(
+ new rtc::RefCountedObject<SetLocalDescriptionRequest>(
base::ThreadTaskRunnerHandle::Get(), request,
weak_factory_.GetWeakPtr(), peer_connection_tracker_,
PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION));
@@ -1452,8 +1516,8 @@ void RTCPeerConnectionHandler::SetRemoteDescription(
webrtc::SdpParseError error;
// Since CreateNativeSessionDescription uses the dependency factory, we need
// to make this call on the current thread to be safe.
- webrtc::SessionDescriptionInterface* native_desc =
- CreateNativeSessionDescription(sdp, type, &error);
+ std::unique_ptr<webrtc::SessionDescriptionInterface> native_desc(
+ CreateNativeSessionDescription(sdp, type, &error));
if (!native_desc) {
std::string reason_str = "Failed to parse SessionDescription. ";
reason_str.append(error.line);
@@ -1469,8 +1533,9 @@ void RTCPeerConnectionHandler::SetRemoteDescription(
return;
}
- if (!first_remote_description_ && IsOfferOrAnswer(native_desc)) {
- first_remote_description_.reset(new FirstSessionDescription(native_desc));
+ if (!first_remote_description_ && IsOfferOrAnswer(native_desc.get())) {
+ first_remote_description_.reset(
+ new FirstSessionDescription(native_desc.get()));
if (first_local_description_) {
ReportFirstSessionDescriptions(
*first_local_description_,
@@ -1478,18 +1543,29 @@ void RTCPeerConnectionHandler::SetRemoteDescription(
}
}
- scoped_refptr<SetSessionDescriptionRequest> set_request(
- new rtc::RefCountedObject<SetSessionDescriptionRequest>(
- base::ThreadTaskRunnerHandle::Get(), request,
- weak_factory_.GetWeakPtr(), peer_connection_tracker_,
- PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION));
+ scoped_refptr<WebRtcSetRemoteDescriptionObserverImpl> content_observer(
+ new WebRtcSetRemoteDescriptionObserverImpl(
+ weak_factory_.GetWeakPtr(), request, peer_connection_tracker_));
+
+ rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface>
+ webrtc_observer(WebRtcSetRemoteDescriptionObserverHandler::Create(
+ base::ThreadTaskRunnerHandle::Get(),
+ native_peer_connection_, stream_adapter_map_,
+ content_observer)
+ .get());
+
signaling_thread()->PostTask(
FROM_HERE,
base::BindOnce(
&RunClosureWithTrace,
- base::Bind(&webrtc::PeerConnectionInterface::SetRemoteDescription,
- native_peer_connection_, base::RetainedRef(set_request),
- base::Unretained(native_desc)),
+ base::Bind(
+ static_cast<void (webrtc::PeerConnectionInterface::*)(
+ std::unique_ptr<webrtc::SessionDescriptionInterface>,
+ rtc::scoped_refptr<
+ webrtc::SetRemoteDescriptionObserverInterface>)>(
+ &webrtc::PeerConnectionInterface::SetRemoteDescription),
+ native_peer_connection_, base::Passed(&native_desc),
+ webrtc_observer),
"SetRemoteDescription"));
}
@@ -1554,7 +1630,7 @@ blink::WebRTCErrorType RTCPeerConnectionHandler::SetConfiguration(
bool RTCPeerConnectionHandler::AddICECandidate(
const blink::WebRTCVoidRequest& request,
- const blink::WebRTCICECandidate& candidate) {
+ scoped_refptr<blink::WebRTCICECandidate> candidate) {
DCHECK(thread_checker_.CalledOnValidThread());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::addICECandidate");
// Libjingle currently does not accept callbacks for addICECandidate.
@@ -1562,7 +1638,7 @@ bool RTCPeerConnectionHandler::AddICECandidate(
// TODO(tommi): Instead of calling addICECandidate here, we can do a
// PostTaskAndReply kind of a thing.
- bool result = AddICECandidate(candidate);
+ bool result = AddICECandidate(std::move(candidate));
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&RTCPeerConnectionHandler::OnaddICECandidateResult,
@@ -1572,13 +1648,13 @@ bool RTCPeerConnectionHandler::AddICECandidate(
}
bool RTCPeerConnectionHandler::AddICECandidate(
- const blink::WebRTCICECandidate& candidate) {
+ scoped_refptr<blink::WebRTCICECandidate> candidate) {
DCHECK(thread_checker_.CalledOnValidThread());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::addICECandidate");
std::unique_ptr<webrtc::IceCandidateInterface> native_candidate(
- dependency_factory_->CreateIceCandidate(candidate.SdpMid().Utf8(),
- candidate.SdpMLineIndex(),
- candidate.Candidate().Utf8()));
+ dependency_factory_->CreateIceCandidate(candidate->SdpMid().Utf8(),
+ candidate->SdpMLineIndex(),
+ candidate->Candidate().Utf8()));
bool return_value = false;
if (native_candidate) {
@@ -1591,7 +1667,8 @@ bool RTCPeerConnectionHandler::AddICECandidate(
if (peer_connection_tracker_) {
peer_connection_tracker_->TrackAddIceCandidate(
- this, candidate, PeerConnectionTracker::SOURCE_REMOTE, return_value);
+ this, std::move(candidate), PeerConnectionTracker::SOURCE_REMOTE,
+ return_value);
}
return return_value;
}
@@ -1758,7 +1835,7 @@ RTCPeerConnectionHandler::GetSenders() {
}
it = rtp_senders_
.insert(std::make_pair(
- id, base::MakeUnique<RTCRtpSender>(
+ id, std::make_unique<RTCRtpSender>(
webrtc_senders[i].get(), std::move(track_adapter))))
.first;
}
@@ -1784,30 +1861,6 @@ RTCPeerConnectionHandler::GetSenders() {
return web_senders;
}
-blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>>
-RTCPeerConnectionHandler::GetReceivers() {
- DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::getReceivers");
-
- std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>>
- webrtc_receivers = native_peer_connection_->GetReceivers();
- std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> web_receivers;
- for (const auto& webrtc_receiver : webrtc_receivers) {
- std::unique_ptr<blink::WebRTCRtpReceiver> web_receiver =
- GetWebRTCRtpReceiver(webrtc_receiver);
- // |web_receiver| is null if we cannot find an initialized track adapter for
- // it. This can happen because adding and removing tracks happens
- // asynchronously.
- if (web_receiver)
- web_receivers.push_back(std::move(web_receiver));
- }
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>> web_vector(
- web_receivers.size());
- for (size_t i = 0; i < web_vector.size(); ++i)
- web_vector[i] = std::move(web_receivers[i]);
- return web_vector;
-}
-
std::unique_ptr<blink::WebRTCRtpSender> RTCPeerConnectionHandler::AddTrack(
const blink::WebMediaStreamTrack& track,
const blink::WebVector<blink::WebMediaStream>& streams) {
@@ -1836,7 +1889,7 @@ std::unique_ptr<blink::WebRTCRtpSender> RTCPeerConnectionHandler::AddTrack(
auto it = rtp_senders_
.insert(std::make_pair(
webrtc_sender_id,
- base::MakeUnique<RTCRtpSender>(std::move(webrtc_sender),
+ std::make_unique<RTCRtpSender>(std::move(webrtc_sender),
std::move(track_adapter),
std::move(stream_adapters))))
.first;
@@ -1898,7 +1951,7 @@ blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::CreateDataChannel(
native_peer_connection_->CreateDataChannel(label.Utf8(), &config));
if (!webrtc_channel) {
DLOG(ERROR) << "Could not create native data channel.";
- return NULL;
+ return nullptr;
}
if (peer_connection_tracker_) {
peer_connection_tracker_->TrackCreateDataChannel(
@@ -2045,71 +2098,89 @@ void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
client_->NegotiationNeeded();
}
-void RTCPeerConnectionHandler::OnAddStream(
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
- remote_stream_adapter_ref,
- std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>>
- stream_webrtc_receivers) {
+void RTCPeerConnectionHandler::OnAddRemoteTrack(
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ remote_track_adapter_ref,
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ remote_stream_adapter_refs) {
DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnAddStreamImpl");
- DCHECK(FindRemoteStreamAdapter(
- remote_stream_adapter_ref->adapter().webrtc_stream()) ==
- remote_streams_.end());
- DCHECK(remote_stream_adapter_ref->adapter().is_initialized());
-
- const WebRtcMediaStreamAdapter* remote_stream_adapter =
- &remote_stream_adapter_ref->adapter();
- remote_streams_.push_back(std::move(remote_stream_adapter_ref));
-
- if (peer_connection_tracker_) {
- peer_connection_tracker_->TrackAddStream(
- this, remote_stream_adapter->web_stream(),
- PeerConnectionTracker::SOURCE_REMOTE);
- }
-
- PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
-
- track_metrics_.AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM,
- remote_stream_adapter->webrtc_stream().get());
- if (!is_closed_) {
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>>
- web_vector_stream_webrtc_receivers(stream_webrtc_receivers.size());
- for (size_t i = 0; i < stream_webrtc_receivers.size(); ++i) {
- web_vector_stream_webrtc_receivers[i] =
- std::move(stream_webrtc_receivers[i]);
+ TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnAddRemoteTrack");
+
+ for (const auto& remote_stream_adapter_ref : remote_stream_adapter_refs) {
+ // New remote stream?
+ if (FindRemoteStreamAdapter(
+ remote_stream_adapter_ref->adapter().webrtc_stream()) ==
+ remote_streams_.end()) {
+ // TODO(hbos): Define getRemoteStreams() in terms of streams of receivers
+ // and remove |remote_streams_|. https://crbug.com/741618
+ remote_streams_.push_back(remote_stream_adapter_ref->Copy());
+
+ // Update metrics.
+ // TODO(hbos): Update metrics to correspond to track added/removed events,
+ // not streams. https://crbug.com/765170
+ if (peer_connection_tracker_) {
+ peer_connection_tracker_->TrackAddStream(
+ this, remote_stream_adapter_ref->adapter().web_stream(),
+ PeerConnectionTracker::SOURCE_REMOTE);
+ }
+ PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
+ track_metrics_.AddStream(
+ MediaStreamTrackMetrics::RECEIVED_STREAM,
+ remote_stream_adapter_ref->adapter().webrtc_stream().get());
}
- client_->DidAddRemoteStream(remote_stream_adapter->web_stream(),
- &web_vector_stream_webrtc_receivers);
}
+
+ uintptr_t receiver_id = RTCRtpReceiver::getId(webrtc_receiver.get());
+ DCHECK(rtp_receivers_.find(receiver_id) == rtp_receivers_.end());
+ const std::unique_ptr<RTCRtpReceiver>& rtp_receiver =
+ rtp_receivers_
+ .insert(std::make_pair(
+ receiver_id,
+ std::make_unique<RTCRtpReceiver>(
+ webrtc_receiver.get(), std::move(remote_track_adapter_ref),
+ std::move(remote_stream_adapter_refs))))
+ .first->second;
+ if (!is_closed_)
+ client_->DidAddRemoteTrack(rtp_receiver->ShallowCopy());
}
-void RTCPeerConnectionHandler::OnRemoveStream(
- const scoped_refptr<webrtc::MediaStreamInterface>& remote_webrtc_stream) {
+void RTCPeerConnectionHandler::OnRemoveRemoteTrack(
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver) {
DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnRemoveStreamImpl");
- auto it = FindRemoteStreamAdapter(remote_webrtc_stream);
- if (it == remote_streams_.end()) {
- NOTREACHED() << "Stream not found";
- return;
- }
-
- track_metrics_.RemoveStream(MediaStreamTrackMetrics::RECEIVED_STREAM,
- remote_webrtc_stream.get());
- PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
+ TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnRemoveRemoteTrack");
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
- remote_stream_adapter_ref = std::move(*it);
- remote_streams_.erase(it);
-
- if (peer_connection_tracker_) {
- peer_connection_tracker_->TrackRemoveStream(
- this, remote_stream_adapter_ref->adapter().web_stream(),
- PeerConnectionTracker::SOURCE_REMOTE);
- }
-
- if (!is_closed_) {
- client_->DidRemoveRemoteStream(
- remote_stream_adapter_ref->adapter().web_stream());
+ uintptr_t receiver_id = RTCRtpReceiver::getId(webrtc_receiver.get());
+ auto it = rtp_receivers_.find(receiver_id);
+ DCHECK(it != rtp_receivers_.end());
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ remote_stream_adapter_refs = it->second->StreamAdapterRefs();
+ if (!is_closed_)
+ client_->DidRemoveRemoteTrack(it->second->ShallowCopy());
+ rtp_receivers_.erase(it);
+
+ for (const auto& remote_stream_adapter_ref : remote_stream_adapter_refs) {
+ // Was this the last usage of the remote stream?
+ if (GetRemoteStreamUsageCount(
+ rtp_receivers_,
+ remote_stream_adapter_ref->adapter().webrtc_stream().get()) == 0) {
+ // Remove from |remote_streams_|.
+ auto it = FindRemoteStreamAdapter(
+ remote_stream_adapter_ref->adapter().webrtc_stream());
+ DCHECK(it != remote_streams_.end());
+ remote_streams_.erase(it);
+
+ // Update metrics.
+ track_metrics_.RemoveStream(
+ MediaStreamTrackMetrics::RECEIVED_STREAM,
+ remote_stream_adapter_ref->adapter().webrtc_stream().get());
+ PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
+ if (peer_connection_tracker_) {
+ peer_connection_tracker_->TrackRemoveStream(
+ this, remote_stream_adapter_ref->adapter().web_stream(),
+ PeerConnectionTracker::SOURCE_REMOTE);
+ }
+ }
}
}
@@ -2132,10 +2203,10 @@ void RTCPeerConnectionHandler::OnIceCandidate(
int component, int address_family) {
DCHECK(thread_checker_.CalledOnValidThread());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateImpl");
- blink::WebRTCICECandidate web_candidate;
- web_candidate.Initialize(blink::WebString::FromUTF8(sdp),
- blink::WebString::FromUTF8(sdp_mid),
- sdp_mline_index);
+ scoped_refptr<blink::WebRTCICECandidate> web_candidate =
+ blink::WebRTCICECandidate::Create(blink::WebString::FromUTF8(sdp),
+ blink::WebString::FromUTF8(sdp_mid),
+ sdp_mline_index);
if (peer_connection_tracker_) {
peer_connection_tracker_->TrackAddIceCandidate(
this, web_candidate, PeerConnectionTracker::SOURCE_LOCAL, true);
@@ -2153,7 +2224,7 @@ void RTCPeerConnectionHandler::OnIceCandidate(
}
}
if (!is_closed_)
- client_->DidGenerateICECandidate(web_candidate);
+ client_->DidGenerateICECandidate(std::move(web_candidate));
}
webrtc::SessionDescriptionInterface*
@@ -2214,22 +2285,6 @@ RTCPeerConnectionHandler::FindRemoteStreamAdapter(
});
}
-std::unique_ptr<blink::WebRTCRtpReceiver>
-RTCPeerConnectionHandler::GetWebRTCRtpReceiver(
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver) {
- rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track =
- webrtc_receiver->track();
- DCHECK(webrtc_track);
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter =
- track_adapter_map_->GetRemoteTrackAdapter(webrtc_track);
- if (!track_adapter)
- return nullptr;
- // Create a reference to the receiver. Multiple |RTCRtpReceiver|s can
- // reference the same webrtc track, see |id|.
- return base::MakeUnique<RTCRtpReceiver>(webrtc_receiver,
- std::move(track_adapter));
-}
-
scoped_refptr<base::SingleThreadTaskRunner>
RTCPeerConnectionHandler::signaling_thread() const {
DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/chromium/content/renderer/media/rtc_peer_connection_handler.h b/chromium/content/renderer/media/rtc_peer_connection_handler.h
index 6788e3da0fd..e3bc45426f7 100644
--- a/chromium/content/renderer/media/rtc_peer_connection_handler.h
+++ b/chromium/content/renderer/media/rtc_peer_connection_handler.h
@@ -21,6 +21,7 @@
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "content/renderer/media/webrtc/media_stream_track_metrics.h"
+#include "content/renderer/media/webrtc/rtc_rtp_receiver.h"
#include "content/renderer/media/webrtc/rtc_rtp_sender.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
@@ -134,9 +135,11 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
blink::WebRTCErrorType SetConfiguration(
const blink::WebRTCConfiguration& configuration) override;
- bool AddICECandidate(const blink::WebRTCICECandidate& candidate) override;
- bool AddICECandidate(const blink::WebRTCVoidRequest& request,
- const blink::WebRTCICECandidate& candidate) override;
+ bool AddICECandidate(
+ scoped_refptr<blink::WebRTCICECandidate> candidate) override;
+ bool AddICECandidate(
+ const blink::WebRTCVoidRequest& request,
+ scoped_refptr<blink::WebRTCICECandidate> candidate) override;
virtual void OnaddICECandidateResult(const blink::WebRTCVoidRequest& request,
bool result);
@@ -148,8 +151,6 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
std::unique_ptr<blink::WebRTCStatsReportCallback> callback) override;
blink::WebVector<std::unique_ptr<blink::WebRTCRtpSender>> GetSenders()
override;
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>> GetReceivers()
- override;
std::unique_ptr<blink::WebRTCRtpSender> AddTrack(
const blink::WebMediaStreamTrack& web_track,
const blink::WebVector<blink::WebMediaStream>& web_streams) override;
@@ -190,6 +191,8 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
class Observer;
friend class Observer;
+ class WebRtcSetRemoteDescriptionObserverImpl;
+ friend class WebRtcSetRemoteDescriptionObserverImpl;
void OnSignalingChange(
webrtc::PeerConnectionInterface::SignalingState new_state);
@@ -198,12 +201,14 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
void OnIceGatheringChange(
webrtc::PeerConnectionInterface::IceGatheringState new_state);
void OnRenegotiationNeeded();
- void OnAddStream(
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
- remote_stream_adapter_ref,
- std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> web_receivers);
- void OnRemoveStream(
- const scoped_refptr<webrtc::MediaStreamInterface>& remote_webrtc_stream);
+ void OnAddRemoteTrack(
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ remote_track_adapter_ref,
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ remote_stream_adapter_refs);
+ void OnRemoveRemoteTrack(
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver);
void OnDataChannel(std::unique_ptr<RtcDataChannelHandler> handler);
void OnIceCandidate(const std::string& sdp, const std::string& sdp_mid,
int sdp_mline_index, int component, int address_family);
@@ -242,8 +247,6 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>::iterator
FindRemoteStreamAdapter(
const scoped_refptr<webrtc::MediaStreamInterface>& webrtc_stream);
- std::unique_ptr<blink::WebRTCRtpReceiver> GetWebRTCRtpReceiver(
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver);
scoped_refptr<base::SingleThreadTaskRunner> signaling_thread() const;
@@ -309,12 +312,10 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
// corresponding content layer sender. This is needed to retain the senders'
// associated set of streams for senders created by |AddTrack|.
std::map<uintptr_t, std::unique_ptr<RTCRtpSender>> rtp_senders_;
- // We don't need an "rtp_receivers_" map as long as the blink layer receivers
- // are not GC'd (protecting the relevant adapters from destruction). These can
- // be constructed anew on every |GetReceivers| call.
- // TODO(hbos): When receivers can be created separately from remote streams we
- // should add an "rtp_receivers_" map too to get rid of the requirement for
- // the blink layer to keep a receiver reference. https://crbug.com/741619
+ // Maps |RTCRtpReceiver::getId|s of |webrtc::RtpReceiverInterface|s to the
+ // corresponding content layer receivers. The set of receivers is needed in
+ // order to keep its associated track's and streams' adapters alive.
+ std::map<uintptr_t, std::unique_ptr<RTCRtpReceiver>> rtp_receivers_;
base::WeakPtr<PeerConnectionTracker> peer_connection_tracker_;
diff --git a/chromium/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/chromium/content/renderer/media/rtc_peer_connection_handler_unittest.cc
index 6d133a8053c..b7362c4e15f 100644
--- a/chromium/content/renderer/media/rtc_peer_connection_handler_unittest.cc
+++ b/chromium/content/renderer/media/rtc_peer_connection_handler_unittest.cc
@@ -13,11 +13,11 @@
#include <vector>
#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/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "content/child/child_process.h"
@@ -56,24 +56,22 @@
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebHeap.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
+#include "third_party/webrtc/api/rtpreceiverinterface.h"
#include "third_party/webrtc/stats/test/rtcteststats.h"
static const char kDummySdp[] = "dummy sdp";
static const char kDummySdpType[] = "dummy type";
using blink::WebRTCPeerConnectionHandlerClient;
-using testing::NiceMock;
using testing::_;
+using testing::Invoke;
+using testing::NiceMock;
using testing::Ref;
using testing::SaveArg;
using testing::WithArg;
namespace content {
-ACTION_P2(ExitMessageLoop, message_loop, quit_closure) {
- message_loop->task_runner()->PostTask(FROM_HERE, quit_closure);
-}
-
// Action SaveArgPointeeMove<k>(pointer) saves the value pointed to by the k-th
// (0-based) argument of the mock function by moving it to *pointer.
ACTION_TEMPLATE(SaveArgPointeeMove,
@@ -136,7 +134,7 @@ class MockRTCStatsRequest : public LocalRTCStatsRequest {
if (request_succeeded_called_) {
return response_.get();
} else {
- return NULL;
+ return nullptr;
}
}
@@ -168,7 +166,7 @@ class MockPeerConnectionTracker : public PeerConnectionTracker {
const webrtc::PeerConnectionInterface::RTCConfiguration& config));
MOCK_METHOD4(TrackAddIceCandidate,
void(RTCPeerConnectionHandler* pc_handler,
- const blink::WebRTCICECandidate& candidate,
+ scoped_refptr<blink::WebRTCICECandidate> candidate,
Source source,
bool succeeded));
MOCK_METHOD3(TrackAddStream,
@@ -262,9 +260,7 @@ class RTCPeerConnectionHandlerUnderTest : public RTCPeerConnectionHandler {
class RTCPeerConnectionHandlerTest : public ::testing::Test {
public:
- RTCPeerConnectionHandlerTest() : mock_peer_connection_(NULL) {
- child_process_.reset(new ChildProcess());
- }
+ RTCPeerConnectionHandlerTest() : mock_peer_connection_(nullptr) {}
void SetUp() override {
mock_client_.reset(new NiceMock<MockWebRTCPeerConnectionHandlerClient>());
@@ -384,16 +380,46 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
void InvokeOnAddStream(
const rtc::scoped_refptr<webrtc::MediaStreamInterface>& remote_stream) {
- InvokeOnSignalingThread(
- base::Bind(&webrtc::PeerConnectionObserver::OnAddStream,
- base::Unretained(pc_handler_->observer()), remote_stream));
+ for (const auto& audio_track : remote_stream->GetAudioTracks()) {
+ InvokeOnAddTrack(audio_track, remote_stream);
+ }
+ for (const auto& video_track : remote_stream->GetVideoTracks()) {
+ InvokeOnAddTrack(video_track, remote_stream);
+ }
+ }
+
+ void InvokeOnAddTrack(
+ const rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>& remote_track,
+ const rtc::scoped_refptr<webrtc::MediaStreamInterface>& remote_stream) {
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver(
+ new rtc::RefCountedObject<FakeRtpReceiver>(remote_track));
+ receivers_by_track_.insert(std::make_pair(remote_track.get(), receiver));
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>
+ receiver_streams;
+ receiver_streams.push_back(remote_stream);
+ InvokeOnSignalingThread(base::Bind(
+ &webrtc::PeerConnectionObserver::OnAddTrack,
+ base::Unretained(pc_handler_->observer()), receiver, receiver_streams));
}
void InvokeOnRemoveStream(
const rtc::scoped_refptr<webrtc::MediaStreamInterface>& remote_stream) {
+ for (const auto& audio_track : remote_stream->GetAudioTracks()) {
+ InvokeOnRemoveTrack(audio_track);
+ }
+ for (const auto& video_track : remote_stream->GetVideoTracks()) {
+ InvokeOnRemoveTrack(video_track);
+ }
+ }
+
+ void InvokeOnRemoveTrack(
+ const rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>&
+ remote_track) {
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver =
+ receivers_by_track_.find(remote_track.get())->second;
InvokeOnSignalingThread(
- base::Bind(&webrtc::PeerConnectionObserver::OnRemoveStream,
- base::Unretained(pc_handler_->observer()), remote_stream));
+ base::Bind(&webrtc::PeerConnectionObserver::OnRemoveTrack,
+ base::Unretained(pc_handler_->observer()), receiver));
}
template <typename T>
@@ -420,8 +446,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
bool HasReceiverForEveryTrack(
const rtc::scoped_refptr<webrtc::MediaStreamInterface>& remote_stream,
- const blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>>&
- receivers) {
+ const std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>>& receivers) {
for (const auto& audio_track : remote_stream->GetAudioTracks()) {
if (!HasReceiverForTrack(*audio_track.get(), receivers))
return false;
@@ -435,8 +460,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
bool HasReceiverForTrack(
const webrtc::MediaStreamTrackInterface& track,
- const blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>>&
- receivers) {
+ const std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>>& receivers) {
for (const auto& receiver : receivers) {
if (receiver->Track().Id().Utf8() == track.id())
return true;
@@ -470,8 +494,10 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
}
public:
- base::MessageLoop message_loop_;
- std::unique_ptr<ChildProcess> child_process_;
+ // The ScopedTaskEnvironment prevents the ChildProcess from leaking a
+ // TaskScheduler.
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ ChildProcess child_process_;
std::unique_ptr<MockWebRTCPeerConnectionHandlerClient> mock_client_;
std::unique_ptr<MockPeerConnectionDependencyFactory> mock_dependency_factory_;
std::unique_ptr<NiceMock<MockPeerConnectionTracker>> mock_tracker_;
@@ -480,12 +506,16 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
// Weak reference to the mocked native peer connection implementation.
MockPeerConnectionImpl* mock_peer_connection_;
+
+ std::map<webrtc::MediaStreamTrackInterface*,
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface>>
+ receivers_by_track_;
};
TEST_F(RTCPeerConnectionHandlerTest, Destruct) {
EXPECT_CALL(*mock_tracker_.get(), UnregisterPeerConnection(pc_handler_.get()))
.Times(1);
- pc_handler_.reset(NULL);
+ pc_handler_.reset(nullptr);
}
TEST_F(RTCPeerConnectionHandlerTest, NoCallbacksToClientAfterStop) {
@@ -511,13 +541,12 @@ TEST_F(RTCPeerConnectionHandlerTest, NoCallbacksToClientAfterStop) {
pc_handler_->observer()->OnIceConnectionChange(
webrtc::PeerConnectionInterface::kIceConnectionDisconnected);
- EXPECT_CALL(*mock_client_.get(), DidAddRemoteStream(_, _)).Times(0);
- std::string remote_stream_label("remote_stream");
+ EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_)).Times(0);
rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
+ AddRemoteMockMediaStream("remote_stream", "video", "audio"));
InvokeOnAddStream(remote_stream);
- EXPECT_CALL(*mock_client_.get(), DidRemoveRemoteStream(_)).Times(0);
+ EXPECT_CALL(*mock_client_.get(), DidRemoveRemoteTrackForMock(_)).Times(0);
InvokeOnRemoveStream(remote_stream);
EXPECT_CALL(*mock_client_.get(), DidAddRemoteDataChannel(_)).Times(0);
@@ -542,9 +571,9 @@ TEST_F(RTCPeerConnectionHandlerTest, CreateOffer) {
// TODO(perkj): Can blink::WebRTCSessionDescriptionRequest be changed so
// the |reqest| requestSucceeded can be tested? Currently the |request| object
// can not be initialized from a unit test.
- EXPECT_FALSE(mock_peer_connection_->created_session_description() != NULL);
+ EXPECT_FALSE(mock_peer_connection_->created_session_description() != nullptr);
pc_handler_->CreateOffer(request, options);
- EXPECT_TRUE(mock_peer_connection_->created_session_description() != NULL);
+ EXPECT_TRUE(mock_peer_connection_->created_session_description() != nullptr);
}
TEST_F(RTCPeerConnectionHandlerTest, CreateAnswer) {
@@ -554,9 +583,9 @@ TEST_F(RTCPeerConnectionHandlerTest, CreateAnswer) {
// TODO(perkj): Can blink::WebRTCSessionDescriptionRequest be changed so
// the |reqest| requestSucceeded can be tested? Currently the |request| object
// can not be initialized from a unit test.
- EXPECT_FALSE(mock_peer_connection_->created_session_description() != NULL);
+ EXPECT_FALSE(mock_peer_connection_->created_session_description() != nullptr);
pc_handler_->CreateAnswer(request, options);
- EXPECT_TRUE(mock_peer_connection_->created_session_description() != NULL);
+ EXPECT_TRUE(mock_peer_connection_->created_session_description() != nullptr);
}
TEST_F(RTCPeerConnectionHandlerTest, setLocalDescription) {
@@ -578,7 +607,7 @@ TEST_F(RTCPeerConnectionHandlerTest, setLocalDescription) {
EXPECT_EQ(description.Sdp(), pc_handler_->LocalDescription().Sdp());
std::string sdp_string;
- ASSERT_TRUE(mock_peer_connection_->local_description() != NULL);
+ ASSERT_TRUE(mock_peer_connection_->local_description() != nullptr);
EXPECT_EQ(kDummySdpType, mock_peer_connection_->local_description()->type());
mock_peer_connection_->local_description()->ToString(&sdp_string);
EXPECT_EQ(kDummySdp, sdp_string);
@@ -626,7 +655,7 @@ TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescription) {
TrackSetSessionDescription(pc_handler_.get(), kDummySdp,
kDummySdpType,
PeerConnectionTracker::SOURCE_REMOTE));
- EXPECT_CALL(*mock_peer_connection_, SetRemoteDescription(_, _));
+ EXPECT_CALL(*mock_peer_connection_, SetRemoteDescriptionForMock(_, _));
pc_handler_->SetRemoteDescription(request, description);
RunMessageLoopsUntilIdle();
@@ -634,7 +663,7 @@ TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescription) {
EXPECT_EQ(description.Sdp(), pc_handler_->RemoteDescription().Sdp());
std::string sdp_string;
- ASSERT_TRUE(mock_peer_connection_->remote_description() != NULL);
+ ASSERT_TRUE(mock_peer_connection_->remote_description() != nullptr);
EXPECT_EQ(kDummySdpType, mock_peer_connection_->remote_description()->type());
mock_peer_connection_->remote_description()->ToString(&sdp_string);
EXPECT_EQ(kDummySdp, sdp_string);
@@ -696,14 +725,12 @@ TEST_F(RTCPeerConnectionHandlerTest, setConfigurationError) {
}
TEST_F(RTCPeerConnectionHandlerTest, addICECandidate) {
- blink::WebRTCICECandidate candidate;
- candidate.Initialize(kDummySdp, "sdpMid", 1);
+ scoped_refptr<blink::WebRTCICECandidate> candidate =
+ blink::WebRTCICECandidate::Create(kDummySdp, "sdpMid", 1);
EXPECT_CALL(*mock_tracker_.get(),
- TrackAddIceCandidate(pc_handler_.get(),
- testing::Ref(candidate),
- PeerConnectionTracker::SOURCE_REMOTE,
- true));
+ TrackAddIceCandidate(pc_handler_.get(), candidate,
+ PeerConnectionTracker::SOURCE_REMOTE, true));
EXPECT_TRUE(pc_handler_->AddICECandidate(candidate));
EXPECT_EQ(kDummySdp, mock_peer_connection_->ice_sdp());
EXPECT_EQ(1, mock_peer_connection_->sdp_mline_index());
@@ -809,14 +836,27 @@ TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithLocalSelector) {
StopAllTracks(local_stream);
}
-TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithRemoteSelector) {
- rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
+// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
+TEST_F(RTCPeerConnectionHandlerTest, DISABLED_GetStatsWithRemoteSelector) {
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
AddRemoteMockMediaStream("remote_stream", "video", "audio"));
- InvokeOnAddStream(stream);
- const blink::WebMediaStream& remote_stream = mock_client_->remote_stream();
+ std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
+ // Grab the added receivers and media stream when it's been successfully added
+ // to the PC.
+ blink::WebMediaStream webkit_stream;
+ EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
+ .WillRepeatedly(
+ Invoke([&webkit_stream, &receivers](
+ std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
+ webkit_stream = (*receiver)->Streams()[0];
+ receivers.push_back(std::move(*receiver));
+ }));
+ InvokeOnAddStream(remote_stream);
+ RunMessageLoopsUntilIdle();
+ EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
blink::WebVector<blink::WebMediaStreamTrack> tracks;
- remote_stream.AudioTracks(tracks);
+ webkit_stream.AudioTracks(tracks);
ASSERT_LE(1ul, tracks.size());
scoped_refptr<MockRTCStatsRequest> request(
@@ -970,51 +1010,6 @@ TEST_F(RTCPeerConnectionHandlerTest, GetRTCStats) {
EXPECT_EQ(defined_stats_count, 1);
}
-TEST_F(RTCPeerConnectionHandlerTest, GetReceivers) {
- std::vector<blink::WebMediaStream> remote_streams;
-
- InvokeOnAddStream(AddRemoteMockMediaStream("stream0", "video0", "audio0"));
- remote_streams.push_back(mock_client_->remote_stream());
- InvokeOnAddStream(AddRemoteMockMediaStream("stream1", "video1", "audio1"));
- remote_streams.push_back(mock_client_->remote_stream());
- InvokeOnAddStream(AddRemoteMockMediaStream("stream2", "video2", "audio2"));
- remote_streams.push_back(mock_client_->remote_stream());
-
- std::set<std::string> expected_remote_track_ids;
- expected_remote_track_ids.insert("video0");
- expected_remote_track_ids.insert("audio0");
- expected_remote_track_ids.insert("video1");
- expected_remote_track_ids.insert("audio1");
- expected_remote_track_ids.insert("video2");
- expected_remote_track_ids.insert("audio2");
-
- std::set<std::string> remote_track_ids;
- for (const auto& remote_stream : remote_streams) {
- blink::WebVector<blink::WebMediaStreamTrack> tracks;
- remote_stream.AudioTracks(tracks);
- for (const auto& audio_track : tracks) {
- remote_track_ids.insert(audio_track.Id().Utf8());
- }
- remote_stream.VideoTracks(tracks);
- for (const auto& video_track : tracks) {
- remote_track_ids.insert(video_track.Id().Utf8());
- }
- }
- EXPECT_EQ(expected_remote_track_ids, remote_track_ids);
-
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers =
- pc_handler_->GetReceivers();
- EXPECT_EQ(remote_track_ids.size(), receivers.size());
- std::set<uintptr_t> receiver_ids;
- std::set<std::string> receiver_track_ids;
- for (const auto& receiver : receivers) {
- receiver_ids.insert(receiver->Id());
- receiver_track_ids.insert(receiver->Track().Id().Utf8());
- }
- EXPECT_EQ(expected_remote_track_ids.size(), receiver_ids.size());
- EXPECT_EQ(expected_remote_track_ids.size(), receiver_track_ids.size());
-}
-
TEST_F(RTCPeerConnectionHandlerTest, OnSignalingChange) {
testing::InSequence sequence;
@@ -1209,61 +1204,71 @@ TEST_F(RTCPeerConnectionHandlerTest, OnIceGatheringChange) {
EXPECT_EQ("", mock_client_->candidate_sdp());
}
-TEST_F(RTCPeerConnectionHandlerTest, OnAddAndOnRemoveStream) {
- std::string remote_stream_label("remote_stream");
+// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
+TEST_F(RTCPeerConnectionHandlerTest, DISABLED_OnAddAndOnRemoveStream) {
rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
-
- testing::InSequence sequence;
- EXPECT_CALL(
- *mock_tracker_.get(),
- TrackAddStream(
- pc_handler_.get(),
- testing::Property(&blink::WebMediaStream::Id,
- blink::WebString::FromASCII(remote_stream_label)),
- PeerConnectionTracker::SOURCE_REMOTE));
- EXPECT_CALL(
- *mock_client_.get(),
- DidAddRemoteStream(
- testing::Property(&blink::WebMediaStream::Id,
- blink::WebString::FromASCII(remote_stream_label)),
- _))
- .WillOnce(SaveArgPointeeMove<1>(&receivers));
-
+ AddRemoteMockMediaStream("remote_stream", "video", "audio"));
+ // Grab the added receivers when it's been successfully added to the PC.
+ std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers_added;
+ EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
+ .WillRepeatedly(
+ Invoke([&receivers_added](
+ std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
+ receivers_added.push_back(std::move(*receiver));
+ }));
+ EXPECT_CALL(*mock_tracker_.get(),
+ TrackAddStream(pc_handler_.get(),
+ testing::Property(
+ &blink::WebMediaStream::Id,
+ blink::WebString::FromASCII("remote_stream")),
+ PeerConnectionTracker::SOURCE_REMOTE));
+ // Grab the removed receivers when it's been successfully added to the PC.
+ std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers_removed;
EXPECT_CALL(
*mock_tracker_.get(),
TrackRemoveStream(
pc_handler_.get(),
testing::Property(&blink::WebMediaStream::Id,
- blink::WebString::FromASCII(remote_stream_label)),
+ blink::WebString::FromASCII("remote_stream")),
PeerConnectionTracker::SOURCE_REMOTE));
- EXPECT_CALL(*mock_client_.get(),
- DidRemoveRemoteStream(testing::Property(
- &blink::WebMediaStream::Id,
- blink::WebString::FromASCII(remote_stream_label))));
+ EXPECT_CALL(*mock_client_.get(), DidRemoveRemoteTrackForMock(_))
+ .WillRepeatedly(
+ Invoke([&receivers_removed](
+ std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
+ receivers_removed.push_back(std::move(*receiver));
+ }));
InvokeOnAddStream(remote_stream);
- EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
+ RunMessageLoopsUntilIdle();
+ EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers_added));
InvokeOnRemoveStream(remote_stream);
+ RunMessageLoopsUntilIdle();
+
+ EXPECT_EQ(receivers_added.size(), 2u);
+ EXPECT_EQ(receivers_added.size(), receivers_removed.size());
+ EXPECT_EQ(receivers_added[0]->Id(), receivers_removed[0]->Id());
+ EXPECT_EQ(receivers_added[1]->Id(), receivers_removed[1]->Id());
}
// This test that WebKit is notified about remote track state changes.
-TEST_F(RTCPeerConnectionHandlerTest, RemoteTrackState) {
- std::string remote_stream_label("remote_stream");
+// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
+TEST_F(RTCPeerConnectionHandlerTest, DISABLED_RemoteTrackState) {
rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
-
- testing::InSequence sequence;
- EXPECT_CALL(
- *mock_client_.get(),
- DidAddRemoteStream(
- testing::Property(&blink::WebMediaStream::Id,
- blink::WebString::FromASCII(remote_stream_label)),
- _));
+ AddRemoteMockMediaStream("remote_stream", "video", "audio"));
+ std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
+ // Grab the added receivers and media stream when it's been successfully added
+ // to the PC.
+ blink::WebMediaStream webkit_stream;
+ EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
+ .WillRepeatedly(
+ Invoke([&webkit_stream, &receivers](
+ std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
+ webkit_stream = (*receiver)->Streams()[0];
+ receivers.push_back(std::move(*receiver));
+ }));
InvokeOnAddStream(remote_stream);
- const blink::WebMediaStream& webkit_stream = mock_client_->remote_stream();
+ RunMessageLoopsUntilIdle();
+ EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
webkit_stream.AudioTracks(audio_tracks);
@@ -1290,28 +1295,25 @@ TEST_F(RTCPeerConnectionHandlerTest, RemoteTrackState) {
video_tracks[0].Source().GetReadyState());
}
-TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddAudioTrackFromRemoteStream) {
- std::string remote_stream_label("remote_stream");
- base::RunLoop run_loop;
-
+// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
+TEST_F(RTCPeerConnectionHandlerTest,
+ DISABLED_RemoveAndAddAudioTrackFromRemoteStream) {
rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
-
- // Grab the added media stream when it's been successfully added to the PC.
+ AddRemoteMockMediaStream("remote_stream", "video", "audio"));
+ std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
+ // Grab the added receivers and media stream when it's been successfully added
+ // to the PC.
blink::WebMediaStream webkit_stream;
- EXPECT_CALL(
- *mock_client_.get(),
- DidAddRemoteStream(
- testing::Property(&blink::WebMediaStream::Id,
- blink::WebString::FromASCII(remote_stream_label)),
- _))
- .WillOnce(DoAll(SaveArg<0>(&webkit_stream),
- SaveArgPointeeMove<1>(&receivers),
- ExitMessageLoop(&message_loop_, run_loop.QuitClosure())));
+ EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
+ .WillRepeatedly(
+ Invoke([&webkit_stream, &receivers](
+ std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
+ webkit_stream = (*receiver)->Streams()[0];
+ receivers.push_back(std::move(*receiver));
+ }));
InvokeOnAddStream(remote_stream);
+ RunMessageLoopsUntilIdle();
EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
- run_loop.Run();
{
// Test in a small scope so that |audio_tracks| don't hold on to destroyed
@@ -1341,29 +1343,25 @@ TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddAudioTrackFromRemoteStream) {
EXPECT_EQ(1u, modified_audio_tracks2.size());
}
-TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddVideoTrackFromRemoteStream) {
- std::string remote_stream_label("remote_stream");
- base::RunLoop run_loop;
-
+// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
+TEST_F(RTCPeerConnectionHandlerTest,
+ DISABLED_RemoveAndAddVideoTrackFromRemoteStream) {
rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
-
- // Grab the added media stream when it's been successfully added to the PC.
+ AddRemoteMockMediaStream("remote_stream", "video", "audio"));
+ std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
+ // Grab the added receivers and media stream when it's been successfully added
+ // to the PC.
blink::WebMediaStream webkit_stream;
- EXPECT_CALL(
- *mock_client_.get(),
- DidAddRemoteStream(
- testing::Property(&blink::WebMediaStream::Id,
- blink::WebString::FromASCII(remote_stream_label)),
- _))
- .WillOnce(DoAll(SaveArg<0>(&webkit_stream),
- SaveArgPointeeMove<1>(&receivers),
- ExitMessageLoop(&message_loop_, run_loop.QuitClosure())));
-
+ EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
+ .WillRepeatedly(
+ Invoke([&webkit_stream, &receivers](
+ std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
+ webkit_stream = (*receiver)->Streams()[0];
+ receivers.push_back(std::move(*receiver));
+ }));
InvokeOnAddStream(remote_stream);
+ RunMessageLoopsUntilIdle();
EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
- run_loop.Run();
{
// Test in a small scope so that |video_tracks| don't hold on to destroyed
@@ -1394,29 +1392,25 @@ TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddVideoTrackFromRemoteStream) {
EXPECT_EQ(1u, modified_video_tracks2.size());
}
-TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddTracksFromRemoteStream) {
- std::string remote_stream_label("remote_stream");
- base::RunLoop run_loop;
-
+// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659
+TEST_F(RTCPeerConnectionHandlerTest,
+ DISABLED_RemoveAndAddTracksFromRemoteStream) {
rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
- AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
- blink::WebVector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
-
- // Grab the added media stream when it's been successfully added to the PC.
+ AddRemoteMockMediaStream("remote_stream", "video", "audio"));
+ std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers;
+ // Grab the added receivers and media stream when it's been successfully added
+ // to the PC.
blink::WebMediaStream webkit_stream;
- EXPECT_CALL(
- *mock_client_.get(),
- DidAddRemoteStream(
- testing::Property(&blink::WebMediaStream::Id,
- blink::WebString::FromASCII(remote_stream_label)),
- _))
- .WillOnce(DoAll(SaveArg<0>(&webkit_stream),
- SaveArgPointeeMove<1>(&receivers),
- ExitMessageLoop(&message_loop_, run_loop.QuitClosure())));
-
+ EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_))
+ .WillRepeatedly(
+ Invoke([&webkit_stream, &receivers](
+ std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
+ webkit_stream = (*receiver)->Streams()[0];
+ receivers.push_back(std::move(*receiver));
+ }));
InvokeOnAddStream(remote_stream);
+ RunMessageLoopsUntilIdle();
EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
- run_loop.Run();
{
// Test in a small scope so that |audio_tracks| don't hold on to destroyed
@@ -1493,7 +1487,7 @@ TEST_F(RTCPeerConnectionHandlerTest, CreateDataChannel) {
PeerConnectionTracker::SOURCE_LOCAL));
std::unique_ptr<blink::WebRTCDataChannelHandler> channel(
pc_handler_->CreateDataChannel("d1", blink::WebRTCDataChannelInit()));
- EXPECT_TRUE(channel.get() != NULL);
+ EXPECT_TRUE(channel.get() != nullptr);
EXPECT_EQ(label, channel->Label());
channel->SetClient(nullptr);
}
diff --git a/chromium/content/renderer/media/speech_recognition_audio_sink.cc b/chromium/content/renderer/media/speech_recognition_audio_sink.cc
deleted file mode 100644
index 2dd07e4766a..00000000000
--- a/chromium/content/renderer/media/speech_recognition_audio_sink.cc
+++ /dev/null
@@ -1,183 +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/media/speech_recognition_audio_sink.h"
-
-#include <stddef.h>
-#include <utility>
-
-#include "base/logging.h"
-#include "base/memory/shared_memory.h"
-#include "base/time/time.h"
-#include "content/renderer/media/media_stream_audio_source.h"
-#include "media/base/audio_fifo.h"
-#include "media/base/audio_parameters.h"
-
-namespace content {
-
-SpeechRecognitionAudioSink::SpeechRecognitionAudioSink(
- const blink::WebMediaStreamTrack& track,
- const media::AudioParameters& params,
- const base::SharedMemoryHandle memory,
- std::unique_ptr<base::SyncSocket> socket,
- const OnStoppedCB& on_stopped_cb)
- : track_(track),
- shared_memory_(memory, false),
- socket_(std::move(socket)),
- output_params_(params),
- track_stopped_(false),
- buffer_index_(0),
- on_stopped_cb_(on_stopped_cb) {
- DCHECK(socket_.get());
- DCHECK(main_render_thread_checker_.CalledOnValidThread());
- DCHECK(params.IsValid());
- DCHECK(IsSupportedTrack(track));
- const size_t kSharedMemorySize =
- media::ComputeAudioInputBufferSize(params, 1u);
- CHECK(shared_memory_.Map(kSharedMemorySize));
-
- media::AudioInputBuffer* buffer =
- static_cast<media::AudioInputBuffer*>(shared_memory_.memory());
-
- // The peer must manage their own counter and reset it to 0.
- DCHECK_EQ(0U, buffer->params.size);
- output_bus_ = media::AudioBus::WrapMemory(params, buffer->audio);
-
- // Connect this audio sink to the track
- MediaStreamAudioSink::AddToAudioTrack(this, track_);
-}
-
-SpeechRecognitionAudioSink::~SpeechRecognitionAudioSink() {
- DCHECK(main_render_thread_checker_.CalledOnValidThread());
- if (audio_converter_.get())
- audio_converter_->RemoveInput(this);
-
- // Notify the track before this sink goes away.
- if (!track_stopped_)
- MediaStreamAudioSink::RemoveFromAudioTrack(this, track_);
-}
-
-// static
-bool SpeechRecognitionAudioSink::IsSupportedTrack(
- const blink::WebMediaStreamTrack& track) {
- MediaStreamAudioSource* native_source =
- MediaStreamAudioSource::From(track.Source());
- if (!native_source)
- return false;
-
- const MediaStreamDevice& device = native_source->device();
- // Purposely only support tracks from an audio device. Dissallow WebAudio.
- return (device.type == content::MEDIA_DEVICE_AUDIO_CAPTURE);
-}
-
-void SpeechRecognitionAudioSink::OnSetFormat(
- const media::AudioParameters& input_params) {
- DCHECK(input_params.IsValid());
- DCHECK_LE(
- input_params.frames_per_buffer() * 1000 / input_params.sample_rate(),
- output_params_.frames_per_buffer() * 1000 / output_params_.sample_rate());
-
- // Detach the thread here because it will be a new capture thread
- // calling OnSetFormat() and OnData() if the source is restarted.
- capture_thread_checker_.DetachFromThread();
-
- input_params_ = input_params;
- fifo_buffer_size_ =
- std::ceil(output_params_.frames_per_buffer() *
- static_cast<double>(input_params_.sample_rate()) /
- output_params_.sample_rate());
- DCHECK_GE(fifo_buffer_size_, input_params_.frames_per_buffer());
-
- // Allows for some delays on the peer.
- static const int kNumberOfBuffersInFifo = 2;
- int frames_in_fifo = kNumberOfBuffersInFifo * fifo_buffer_size_;
- fifo_.reset(new media::AudioFifo(input_params.channels(), frames_in_fifo));
-
- // Create the audio converter with |disable_fifo| as false so that the
- // converter will request input_params.frames_per_buffer() each time.
- // This will not increase the complexity as there is only one client to
- // the converter.
- audio_converter_.reset(
- new media::AudioConverter(input_params, output_params_, false));
- audio_converter_->AddInput(this);
-}
-
-void SpeechRecognitionAudioSink::OnReadyStateChanged(
- blink::WebMediaStreamSource::ReadyState state) {
- DCHECK(main_render_thread_checker_.CalledOnValidThread());
- DCHECK(!track_stopped_);
-
- if (state == blink::WebMediaStreamSource::kReadyStateEnded) {
- track_stopped_ = true;
-
- if (!on_stopped_cb_.is_null())
- on_stopped_cb_.Run();
- }
-}
-
-void SpeechRecognitionAudioSink::OnData(
- const media::AudioBus& audio_bus,
- base::TimeTicks estimated_capture_time) {
- DCHECK(capture_thread_checker_.CalledOnValidThread());
- DCHECK_EQ(audio_bus.frames(), input_params_.frames_per_buffer());
- DCHECK_EQ(audio_bus.channels(), input_params_.channels());
- if (fifo_->frames() + audio_bus.frames() > fifo_->max_frames()) {
- // This would indicate a serious issue with the browser process or the
- // SyncSocket and/or SharedMemory. We drop any previous buffers and try to
- // recover by resuming where the peer left of.
- DLOG(ERROR) << "Audio FIFO overflow";
- fifo_->Clear();
- buffer_index_ = GetAudioInputBuffer()->params.size;
- }
-
- fifo_->Push(&audio_bus);
- // Wait for FIFO to have at least |fifo_buffer_size_| frames ready.
- if (fifo_->frames() < fifo_buffer_size_)
- return;
-
- // Make sure the previous output buffer was consumed by the peer before we
- // send the next buffer.
- // The peer must write to it (incrementing by 1) once the the buffer was
- // consumed. This is intentional not to block this audio capturing thread.
- if (buffer_index_ != GetAudioInputBuffer()->params.size) {
- DVLOG(1) << "Buffer synchronization lag";
- return;
- }
-
- audio_converter_->Convert(output_bus_.get());
-
- // Notify peer to consume buffer |buffer_index_| on |output_bus_|.
- const size_t bytes_sent =
- socket_->Send(&buffer_index_, sizeof(buffer_index_));
- if (bytes_sent != sizeof(buffer_index_)) {
- // The send ocasionally fails if the user changes their input audio device.
- DVLOG(1) << "Failed sending buffer index to peer";
- // We have discarded this buffer, but could still recover on the next one.
- return;
- }
-
- // Count the sent buffer. We expect the peer to do the same on their end.
- ++buffer_index_;
-}
-
-double SpeechRecognitionAudioSink::ProvideInput(media::AudioBus* audio_bus,
- uint32_t frames_delayed) {
- DCHECK(capture_thread_checker_.CalledOnValidThread());
- if (fifo_->frames() >= audio_bus->frames())
- fifo_->Consume(audio_bus, 0, audio_bus->frames());
- else
- audio_bus->Zero();
-
- // Return volume greater than zero to indicate we have more data.
- return 1.0;
-}
-
-media::AudioInputBuffer*
-SpeechRecognitionAudioSink::GetAudioInputBuffer() const {
- DCHECK(capture_thread_checker_.CalledOnValidThread());
- DCHECK(shared_memory_.memory());
- return static_cast<media::AudioInputBuffer*>(shared_memory_.memory());
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/speech_recognition_audio_sink.h b/chromium/content/renderer/media/speech_recognition_audio_sink.h
deleted file mode 100644
index b0c0369c1a7..00000000000
--- a/chromium/content/renderer/media/speech_recognition_audio_sink.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MEDIA_SPEECH_RECOGNITION_AUDIO_SINK_H_
-#define CONTENT_RENDERER_MEDIA_SPEECH_RECOGNITION_AUDIO_SINK_H_
-
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/shared_memory.h"
-#include "base/sync_socket.h"
-#include "base/threading/thread_checker.h"
-#include "content/common/content_export.h"
-#include "content/public/renderer/media_stream_audio_sink.h"
-#include "media/base/audio_converter.h"
-#include "media/base/audio_parameters.h"
-#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
-
-namespace media {
-class AudioBus;
-class AudioFifo;
-}
-
-namespace content {
-
-// SpeechRecognitionAudioSink works as an audio sink to the
-// WebRtcLocalAudioTrack. It stores the capture data into a FIFO.
-// When the FIFO has enough data for resampling, it converts it,
-// passes the buffer to the WebSpeechRecognizer via SharedMemory
-// and notifies it via SyncSocket followed by incrementing the |buffer_index_|.
-// WebSpeechRecognizer increments the shared buffer index to synchronize.
-class CONTENT_EXPORT SpeechRecognitionAudioSink
- : public media::AudioConverter::InputCallback,
- public MediaStreamAudioSink {
- public:
- typedef base::Callback<void()> OnStoppedCB;
-
- // Socket ownership is transferred to the class via constructor.
- SpeechRecognitionAudioSink(const blink::WebMediaStreamTrack& track,
- const media::AudioParameters& params,
- const base::SharedMemoryHandle memory,
- std::unique_ptr<base::SyncSocket> socket,
- const OnStoppedCB& on_stopped_cb);
-
- ~SpeechRecognitionAudioSink() override;
-
- // Returns whether the provided track is supported.
- static bool IsSupportedTrack(const blink::WebMediaStreamTrack& track);
-
- private:
- // content::MediaStreamAudioSink implementation.
- void OnReadyStateChanged(
- blink::WebMediaStreamSource::ReadyState state) override;
-
- void OnData(const media::AudioBus& audio_bus,
- base::TimeTicks estimated_capture_time) override;
- void OnSetFormat(const media::AudioParameters& params) override;
-
- // media::AudioConverter::Inputcallback implementation.
- double ProvideInput(media::AudioBus* audio_bus,
- uint32_t frames_delayed) override;
-
- // Returns the pointer to the audio input buffer mapped in the shared memory.
- media::AudioInputBuffer* GetAudioInputBuffer() const;
-
- // Number of frames per buffer in FIFO. When the buffer is full we convert and
- // consume it on the |output_bus_|. Size of the buffer depends on the
- // resampler. Example: for 44.1 to 16.0 conversion, it should be 4100 frames.
- int fifo_buffer_size_;
-
- // Used to DCHECK that some methods are called on the main render thread.
- base::ThreadChecker main_render_thread_checker_;
-
- // Used to DCHECK that some methods are called on the capture audio thread.
- base::ThreadChecker capture_thread_checker_;
-
- // The audio track that this audio sink is connected to.
- const blink::WebMediaStreamTrack track_;
-
- // Shared memory used by audio buses on both browser and renderer processes.
- base::SharedMemory shared_memory_;
-
- // Socket for synchronization of audio bus reads/writes.
- // Created on the renderer client and passed here. Accessed on capture thread.
- std::unique_ptr<base::SyncSocket> socket_;
-
- // Used as a resampler to deliver appropriate format to speech recognition.
- std::unique_ptr<media::AudioConverter> audio_converter_;
-
- // FIFO is used for queuing audio frames before we resample.
- std::unique_ptr<media::AudioFifo> fifo_;
-
- // Audio bus shared with the browser process via |shared_memory_|.
- std::unique_ptr<media::AudioBus> output_bus_;
-
- // Params of the source audio. Can change when |OnSetFormat()| occurs.
- media::AudioParameters input_params_;
-
- // Params used by speech recognition.
- const media::AudioParameters output_params_;
-
- // Whether the track has been stopped.
- bool track_stopped_;
-
- // Local counter of audio buffers for synchronization.
- uint32_t buffer_index_;
-
- // Callback for the renderer client. Called when the audio track was stopped.
- const OnStoppedCB on_stopped_cb_;
-
- DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionAudioSink);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_SPEECH_RECOGNITION_AUDIO_SINK_H_
diff --git a/chromium/content/renderer/media/speech_recognition_audio_sink_unittest.cc b/chromium/content/renderer/media/speech_recognition_audio_sink_unittest.cc
deleted file mode 100644
index e116e48c5b1..00000000000
--- a/chromium/content/renderer/media/speech_recognition_audio_sink_unittest.cc
+++ /dev/null
@@ -1,547 +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/media/speech_recognition_audio_sink.h"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "content/renderer/media/media_stream_audio_source.h"
-#include "content/renderer/media/media_stream_audio_track.h"
-#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
-#include "media/base/audio_bus.h"
-#include "media/base/audio_parameters.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebHeap.h"
-
-namespace {
-
-// Supported speech recognition audio parameters.
-const int kSpeechRecognitionSampleRate = 16000;
-const int kSpeechRecognitionFramesPerBuffer = 1600;
-
-// Input audio format.
-const media::AudioParameters::Format kInputFormat =
- media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
-const media::ChannelLayout kInputChannelLayout = media::CHANNEL_LAYOUT_MONO;
-const int kInputChannels = 1;
-const int kInputBitsPerSample = 16;
-
-// Output audio format.
-const media::AudioParameters::Format kOutputFormat =
- media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
-const media::ChannelLayout kOutputChannelLayout = media::CHANNEL_LAYOUT_STEREO;
-const int kOutputChannels = 2;
-const int kOutputBitsPerSample = 16;
-
-// Mocked out sockets used for Send/Receive.
-// Data is written and read from a shared buffer used as a FIFO and there is
-// no blocking. |OnSendCB| is used to trigger a |Receive| on the other socket.
-class MockSyncSocket : public base::SyncSocket {
- public:
- // This allows for 2 requests in queue between the |MockSyncSocket|s.
- static const int kSharedBufferSize = 8;
-
- // Buffer to be shared between two |MockSyncSocket|s. Allocated on heap.
- struct SharedBuffer {
- SharedBuffer() : data(), start(0), length(0) {}
-
- uint8_t data[kSharedBufferSize];
- size_t start;
- size_t length;
- };
-
- // Callback used for pairing an A.Send() with B.Receieve() without blocking.
- typedef base::Callback<void()> OnSendCB;
-
- explicit MockSyncSocket(SharedBuffer* shared_buffer)
- : buffer_(shared_buffer),
- in_failure_mode_(false) {}
-
- MockSyncSocket(SharedBuffer* shared_buffer, const OnSendCB& on_send_cb)
- : buffer_(shared_buffer),
- on_send_cb_(on_send_cb),
- in_failure_mode_(false) {}
-
- size_t Send(const void* buffer, size_t length) override;
- size_t Receive(void* buffer, size_t length) override;
-
- // When |in_failure_mode_| == true, the socket fails to send.
- void SetFailureMode(bool in_failure_mode) {
- in_failure_mode_ = in_failure_mode;
- }
-
- private:
- SharedBuffer* buffer_;
- const OnSendCB on_send_cb_;
- bool in_failure_mode_;
-
- DISALLOW_COPY_AND_ASSIGN(MockSyncSocket);
-};
-
-// base::SyncSocket implementation
-size_t MockSyncSocket::Send(const void* buffer, size_t length) {
- if (in_failure_mode_)
- return 0;
-
- const uint8_t* b = static_cast<const uint8_t*>(buffer);
- for (size_t i = 0; i < length; ++i, ++buffer_->length)
- buffer_->data[buffer_->start + buffer_->length] = b[i];
-
- on_send_cb_.Run();
- return length;
-}
-
-size_t MockSyncSocket::Receive(void* buffer, size_t length) {
- uint8_t* b = static_cast<uint8_t*>(buffer);
- for (size_t i = buffer_->start; i < buffer_->length; ++i, ++buffer_->start)
- b[i] = buffer_->data[buffer_->start];
-
- // Since buffer is used sequentially, we can reset the buffer indices here.
- buffer_->start = buffer_->length = 0;
- return length;
-}
-
-// This fake class is the consumer used to verify behaviour of the producer.
-// The |Initialize()| method shows what the consumer should be responsible for
-// in the production code (minus the mocks).
-class FakeSpeechRecognizer {
- public:
- FakeSpeechRecognizer() : is_responsive_(true) {}
-
- void Initialize(
- const blink::WebMediaStreamTrack& track,
- const media::AudioParameters& sink_params,
- base::SharedMemoryHandle* foreign_memory_handle) {
- // Shared memory is allocated, mapped and shared.
- const uint32_t kSharedMemorySize =
- media::ComputeAudioInputBufferSize(sink_params, 1u);
- shared_memory_.reset(new base::SharedMemory());
- ASSERT_TRUE(shared_memory_->CreateAndMapAnonymous(kSharedMemorySize));
- memset(shared_memory_->memory(), 0, kSharedMemorySize);
- *foreign_memory_handle = shared_memory_->handle().Duplicate();
- ASSERT_TRUE(foreign_memory_handle->IsValid());
-
- // Wrap the shared memory for the audio bus.
- media::AudioInputBuffer* buffer =
- static_cast<media::AudioInputBuffer*>(shared_memory_->memory());
-
- audio_track_bus_ = media::AudioBus::WrapMemory(sink_params, buffer->audio);
- audio_track_bus_->Zero();
-
- // Reference to the counter used to synchronize.
- buffer->params.size = 0U;
-
- // Create a shared buffer for the |MockSyncSocket|s.
- shared_buffer_.reset(new MockSyncSocket::SharedBuffer());
-
- // Local socket will receive signals from the producer.
- receiving_socket_.reset(new MockSyncSocket(shared_buffer_.get()));
-
- // We automatically trigger a Receive when data is sent over the socket.
- sending_socket_ = new MockSyncSocket(
- shared_buffer_.get(),
- base::Bind(&FakeSpeechRecognizer::EmulateReceiveThreadLoopIteration,
- base::Unretained(this)));
-
- // This is usually done to pair the sockets. Here it's not effective.
- base::SyncSocket::CreatePair(receiving_socket_.get(), sending_socket_);
- }
-
- // Emulates a single iteraton of a thread receiving on the socket.
- // This would normally be done on a receiving thread's task on the browser.
- void EmulateReceiveThreadLoopIteration() {
- if (!is_responsive_)
- return;
-
- const int kSize = sizeof(media::AudioInputBufferParameters().size);
- receiving_socket_->Receive(&(GetAudioInputBuffer()->params.size), kSize);
-
- // Notify the producer that the audio buffer has been consumed.
- GetAudioInputBuffer()->params.size++;
- }
-
- // Used to simulate an unresponsive behaviour of the consumer.
- void SimulateResponsiveness(bool is_responsive) {
- is_responsive_ = is_responsive;
- }
-
- media::AudioInputBuffer * GetAudioInputBuffer() const {
- return static_cast<media::AudioInputBuffer*>(shared_memory_->memory());
- }
-
- MockSyncSocket* sending_socket() { return sending_socket_; }
- media::AudioBus* audio_bus() const { return audio_track_bus_.get(); }
-
-
- private:
- bool is_responsive_;
-
- // Shared memory for the audio and synchronization.
- std::unique_ptr<base::SharedMemory> shared_memory_;
-
- // Fake sockets and their shared buffer.
- std::unique_ptr<MockSyncSocket::SharedBuffer> shared_buffer_;
- std::unique_ptr<MockSyncSocket> receiving_socket_;
- MockSyncSocket* sending_socket_;
-
- // Audio bus wrapping the shared memory from the renderer.
- std::unique_ptr<media::AudioBus> audio_track_bus_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeSpeechRecognizer);
-};
-
-} // namespace
-
-namespace content {
-
-namespace {
-
-class TestDrivenAudioSource : public MediaStreamAudioSource {
- public:
- TestDrivenAudioSource() : MediaStreamAudioSource(true) {}
- ~TestDrivenAudioSource() final {}
-
- // Expose protected methods as public for testing.
- using MediaStreamAudioSource::SetFormat;
- using MediaStreamAudioSource::DeliverDataToTracks;
-};
-
-} // namespace
-
-class SpeechRecognitionAudioSinkTest : public testing::Test {
- public:
- SpeechRecognitionAudioSinkTest() {}
-
- ~SpeechRecognitionAudioSinkTest() {
- blink_source_.Reset();
- blink_track_.Reset();
- speech_audio_sink_.reset();
- blink::WebHeap::CollectAllGarbageForTesting();
- }
-
- // Initializes the producer and consumer with specified audio parameters.
- // Returns the minimal number of input audio buffers which need to be captured
- // before they get sent to the consumer.
- uint32_t Initialize(int input_sample_rate,
- int input_frames_per_buffer,
- int output_sample_rate,
- int output_frames_per_buffer) {
- // Audio Environment setup.
- source_params_.Reset(kInputFormat,
- kInputChannelLayout,
- input_sample_rate,
- kInputBitsPerSample,
- input_frames_per_buffer);
- sink_params_.Reset(kOutputFormat,
- kOutputChannelLayout,
- output_sample_rate,
- kOutputBitsPerSample,
- output_frames_per_buffer);
- source_bus_ =
- media::AudioBus::Create(kInputChannels, input_frames_per_buffer);
- source_bus_->Zero();
- first_frame_capture_time_ = base::TimeTicks::Now();
- sample_frames_captured_ = 0;
-
- // Prepare the track and audio source.
- PrepareBlinkTrackOfType(MEDIA_DEVICE_AUDIO_CAPTURE, &blink_track_);
- blink_source_ = blink_track_.Source();
- static_cast<TestDrivenAudioSource*>(
- MediaStreamAudioSource::From(blink_source_))->SetFormat(source_params_);
-
- // Create and initialize the consumer.
- recognizer_.reset(new FakeSpeechRecognizer());
- base::SharedMemoryHandle foreign_memory_handle;
- recognizer_->Initialize(blink_track_, sink_params_, &foreign_memory_handle);
-
- // Create the producer.
- std::unique_ptr<base::SyncSocket> sending_socket(
- recognizer_->sending_socket());
- speech_audio_sink_.reset(new SpeechRecognitionAudioSink(
- blink_track_, sink_params_, foreign_memory_handle,
- std::move(sending_socket),
- base::Bind(&SpeechRecognitionAudioSinkTest::StoppedCallback,
- base::Unretained(this))));
-
- // Return number of buffers needed to trigger resampling and consumption.
- return static_cast<uint32_t>(std::ceil(
- static_cast<double>(output_frames_per_buffer * input_sample_rate) /
- (input_frames_per_buffer * output_sample_rate)));
- }
-
- // Mock callback expected to be called when the track is stopped.
- MOCK_METHOD0(StoppedCallback, void());
-
- protected:
- // Prepares a blink track of a given MediaStreamType and attaches the native
- // track which can be used to capture audio data and pass it to the producer.
- void PrepareBlinkTrackOfType(const MediaStreamType device_type,
- blink::WebMediaStreamTrack* blink_track) {
- blink::WebMediaStreamSource blink_source;
- blink_source.Initialize(blink::WebString::FromUTF8("dummy_source_id"),
- blink::WebMediaStreamSource::kTypeAudio,
- blink::WebString::FromUTF8("dummy_source_name"),
- false /* remote */);
- TestDrivenAudioSource* const audio_source = new TestDrivenAudioSource();
- audio_source->SetDevice(
- MediaStreamDevice(device_type, "mock_device_id", "Mock device"));
- blink_source.SetExtraData(audio_source); // Takes ownership.
-
- blink_track->Initialize(blink::WebString::FromUTF8("dummy_track"),
- blink_source);
- ASSERT_TRUE(audio_source->ConnectToTrack(*blink_track));
- }
-
- // Emulates an audio capture device capturing data from the source.
- inline void CaptureAudio(const uint32_t buffers) {
- for (uint32_t i = 0; i < buffers; ++i) {
- const base::TimeTicks estimated_capture_time = first_frame_capture_time_ +
- (sample_frames_captured_ * base::TimeDelta::FromSeconds(1) /
- source_params_.sample_rate());
- static_cast<TestDrivenAudioSource*>(
- MediaStreamAudioSource::From(blink_source_))
- ->DeliverDataToTracks(*source_bus_, estimated_capture_time);
- sample_frames_captured_ += source_bus_->frames();
- }
- }
-
- // Used to simulate a problem with sockets.
- void SetFailureModeOnForeignSocket(bool in_failure_mode) {
- recognizer()->sending_socket()->SetFailureMode(in_failure_mode);
- }
-
- // Helper method for verifying captured audio data has been consumed.
- inline void AssertConsumedBuffers(const uint32_t buffer_index) {
- ASSERT_EQ(buffer_index, recognizer()->GetAudioInputBuffer()->params.size);
- }
-
- // Helper method for providing audio data to producer and verifying it was
- // consumed on the recognizer.
- inline void CaptureAudioAndAssertConsumedBuffers(
- const uint32_t buffers,
- const uint32_t buffer_index) {
- CaptureAudio(buffers);
- AssertConsumedBuffers(buffer_index);
- }
-
- // Helper method to capture and assert consumption at different sample rates
- // and audio buffer sizes.
- inline void AssertConsumptionForAudioParameters(
- const int input_sample_rate,
- const int input_frames_per_buffer,
- const int output_sample_rate,
- const int output_frames_per_buffer,
- const uint32_t consumptions) {
- const uint32_t buffers_per_notification =
- Initialize(input_sample_rate, input_frames_per_buffer,
- output_sample_rate, output_frames_per_buffer);
- AssertConsumedBuffers(0U);
-
- for (uint32_t i = 1U; i <= consumptions; ++i) {
- CaptureAudio(buffers_per_notification);
- ASSERT_EQ(i, recognizer()->GetAudioInputBuffer()->params.size)
- << "Tested at rates: "
- << "In(" << input_sample_rate << ", " << input_frames_per_buffer
- << ") "
- << "Out(" << output_sample_rate << ", " << output_frames_per_buffer
- << ")";
- }
- }
-
- media::AudioBus* source_bus() const { return source_bus_.get(); }
-
- FakeSpeechRecognizer* recognizer() const { return recognizer_.get(); }
-
- const media::AudioParameters& sink_params() const { return sink_params_; }
-
- MediaStreamAudioTrack* native_track() const {
- return MediaStreamAudioTrack::From(blink_track_);
- }
-
- private:
- MockPeerConnectionDependencyFactory mock_dependency_factory_;
-
- // Producer.
- std::unique_ptr<SpeechRecognitionAudioSink> speech_audio_sink_;
-
- // Consumer.
- std::unique_ptr<FakeSpeechRecognizer> recognizer_;
-
- // Audio related members.
- std::unique_ptr<media::AudioBus> source_bus_;
- media::AudioParameters source_params_;
- media::AudioParameters sink_params_;
- blink::WebMediaStreamSource blink_source_;
- blink::WebMediaStreamTrack blink_track_;
-
- base::TimeTicks first_frame_capture_time_;
- int64_t sample_frames_captured_;
-
- base::MessageLoop message_loop_;
-
- DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionAudioSinkTest);
-};
-
-// Not all types of tracks are supported. This test checks if that policy is
-// implemented correctly.
-TEST_F(SpeechRecognitionAudioSinkTest, CheckIsSupportedAudioTrack) {
- typedef std::map<MediaStreamType, bool> SupportedTrackPolicy;
-
- // This test must be aligned with the policy of supported tracks.
- SupportedTrackPolicy p;
- p[MEDIA_NO_SERVICE] = false;
- p[MEDIA_DEVICE_AUDIO_CAPTURE] = true; // The only one supported for now.
- p[MEDIA_DEVICE_VIDEO_CAPTURE] = false;
- p[MEDIA_TAB_AUDIO_CAPTURE] = false;
- p[MEDIA_TAB_VIDEO_CAPTURE] = false;
- p[MEDIA_DESKTOP_VIDEO_CAPTURE] = false;
- p[MEDIA_DESKTOP_AUDIO_CAPTURE] = false;
-
- // Ensure this test gets updated along with |content::MediaStreamType| enum.
- EXPECT_EQ(NUM_MEDIA_TYPES, p.size());
-
- // Check the the entire policy.
- for (SupportedTrackPolicy::iterator it = p.begin(); it != p.end(); ++it) {
- blink::WebMediaStreamTrack blink_track;
- PrepareBlinkTrackOfType(it->first, &blink_track);
- ASSERT_EQ(
- it->second,
- SpeechRecognitionAudioSink::IsSupportedTrack(blink_track));
- }
-}
-
-// Checks if the producer can support the listed range of input sample rates
-// and associated buffer sizes.
-TEST_F(SpeechRecognitionAudioSinkTest, RecognizerNotifiedOnSocket) {
- const size_t kNumAudioParamTuples = 24;
- const int kAudioParams[kNumAudioParamTuples][2] = {
- {8000, 80}, {8000, 800}, {16000, 160}, {16000, 1600},
- {24000, 240}, {24000, 2400}, {32000, 320}, {32000, 3200},
- {44100, 441}, {44100, 4410}, {48000, 480}, {48000, 4800},
- {96000, 960}, {96000, 9600}, {11025, 111}, {11025, 1103},
- {22050, 221}, {22050, 2205}, {88200, 882}, {88200, 8820},
- {176400, 1764}, {176400, 17640}, {192000, 1920}, {192000, 19200}};
-
- // Check all listed tuples of input sample rates and buffers sizes.
- for (size_t i = 0; i < kNumAudioParamTuples; ++i) {
- AssertConsumptionForAudioParameters(
- kAudioParams[i][0], kAudioParams[i][1],
- kSpeechRecognitionSampleRate, kSpeechRecognitionFramesPerBuffer, 3U);
- }
-}
-
-// Checks that the input data is getting resampled to the target sample rate.
-TEST_F(SpeechRecognitionAudioSinkTest, AudioDataIsResampledOnSink) {
- EXPECT_GE(kInputChannels, 1);
- EXPECT_GE(kOutputChannels, 1);
-
- // Input audio is sampled at 44.1 KHz with data chunks of 10ms. Desired output
- // is corresponding to the speech recognition engine requirements: 16 KHz with
- // 100 ms chunks (1600 frames per buffer).
- const uint32_t kSourceFrames = 441;
- const uint32_t buffers_per_notification =
- Initialize(44100, kSourceFrames, 16000, 1600);
- // Fill audio input frames with 0, 1, 2, 3, ..., 440.
- int16_t source_data[kSourceFrames * kInputChannels];
- for (uint32_t i = 0; i < kSourceFrames; ++i) {
- for (int c = 0; c < kInputChannels; ++c)
- source_data[i * kInputChannels + c] = i;
- }
- source_bus()->FromInterleaved(
- source_data, kSourceFrames, sizeof(source_data[0]));
-
- // Prepare sink audio bus and data for rendering.
- media::AudioBus* sink_bus = recognizer()->audio_bus();
- const uint32_t kSinkDataLength = 1600 * kOutputChannels;
- int16_t sink_data[kSinkDataLength] = {0};
-
- // Render the audio data from the recognizer.
- sink_bus->ToInterleaved(sink_bus->frames(),
- sink_params().bits_per_sample() / 8, sink_data);
-
- // Checking only a fraction of the sink frames.
- const uint32_t kNumFramesToTest = 12;
-
- // Check all channels are zeroed out before we trigger resampling.
- for (uint32_t i = 0; i < kNumFramesToTest; ++i) {
- for (int c = 0; c < kOutputChannels; ++c)
- EXPECT_EQ(0, sink_data[i * kOutputChannels + c]);
- }
-
- // Trigger the speech sink to resample the input data.
- AssertConsumedBuffers(0U);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 1U);
-
- // Render the audio data from the recognizer.
- sink_bus->ToInterleaved(sink_bus->frames(),
- sink_params().bits_per_sample() / 8, sink_data);
-
- // Resampled data expected frames. Extracted based on |source_data|.
- const int16_t kExpectedData[kNumFramesToTest] = {0, 2, 5, 8, 11, 13,
- 16, 19, 22, 24, 27, 30};
-
- // Check all channels have the same resampled data.
- for (uint32_t i = 0; i < kNumFramesToTest; ++i) {
- for (int c = 0; c < kOutputChannels; ++c)
- EXPECT_EQ(kExpectedData[i], sink_data[i * kOutputChannels + c]);
- }
-}
-
-// Checks that the producer does not misbehave when a socket failure occurs.
-TEST_F(SpeechRecognitionAudioSinkTest, SyncSocketFailsSendingData) {
- const uint32_t buffers_per_notification = Initialize(44100, 441, 16000, 1600);
- // Start with no problems on the socket.
- AssertConsumedBuffers(0U);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 1U);
-
- // A failure occurs (socket cannot send).
- SetFailureModeOnForeignSocket(true);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 1U);
-}
-
-// A very unlikely scenario in which the peer is not synchronizing for a long
-// time (e.g. 300 ms) which results in dropping cached buffers and restarting.
-// We check that the FIFO overflow does not occur and that the producer is able
-// to resume.
-TEST_F(SpeechRecognitionAudioSinkTest, RepeatedSycnhronizationLag) {
- const uint32_t buffers_per_notification = Initialize(44100, 441, 16000, 1600);
-
- // Start with no synchronization problems.
- AssertConsumedBuffers(0U);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 1U);
-
- // Consumer gets out of sync.
- recognizer()->SimulateResponsiveness(false);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 1U);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 1U);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 1U);
-
- // Consumer recovers.
- recognizer()->SimulateResponsiveness(true);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 2U);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 3U);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 4U);
-}
-
-// Checks that an OnStoppedCallback is issued when the track is stopped.
-TEST_F(SpeechRecognitionAudioSinkTest, OnReadyStateChangedOccured) {
- const uint32_t buffers_per_notification = Initialize(44100, 441, 16000, 1600);
- AssertConsumedBuffers(0U);
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 1U);
- EXPECT_CALL(*this, StoppedCallback()).Times(1);
-
- native_track()->Stop();
- CaptureAudioAndAssertConsumedBuffers(buffers_per_notification, 1U);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/track_audio_renderer.cc b/chromium/content/renderer/media/track_audio_renderer.cc
index ba9b28d2ef1..cdb4d1ad918 100644
--- a/chromium/content/renderer/media/track_audio_renderer.cc
+++ b/chromium/content/renderer/media/track_audio_renderer.cc
@@ -171,7 +171,7 @@ void TrackAudioRenderer::Stop() {
// when the |sink_| is never started.
if (sink_) {
sink_->Stop();
- sink_ = NULL;
+ sink_ = nullptr;
}
if (!sink_started_ && IsLocalRenderer()) {
diff --git a/chromium/content/renderer/media/user_media_client_impl.cc b/chromium/content/renderer/media/user_media_client_impl.cc
index e046cdc4ea8..8614ced4a1e 100644
--- a/chromium/content/renderer/media/user_media_client_impl.cc
+++ b/chromium/content/renderer/media/user_media_client_impl.cc
@@ -16,7 +16,7 @@
#include "base/threading/sequenced_task_runner_handle.h"
#include "content/public/renderer/render_frame.h"
#include "content/renderer/media/apply_constraints_processor.h"
-#include "content/renderer/media/media_stream_dispatcher.h"
+#include "content/renderer/media/media_stream_device_observer.h"
#include "content/renderer/media/media_stream_video_track.h"
#include "content/renderer/media/peer_connection_tracker.h"
#include "content/renderer/media/webrtc_logging.h"
@@ -57,6 +57,7 @@ UserMediaClientImpl::Request::Request(std::unique_ptr<UserMediaRequest> request)
: user_media_request_(std::move(request)) {
DCHECK(user_media_request_);
DCHECK(apply_constraints_request_.IsNull());
+ DCHECK(web_track_to_stop_.IsNull());
}
UserMediaClientImpl::Request::Request(
@@ -64,12 +65,32 @@ UserMediaClientImpl::Request::Request(
: apply_constraints_request_(request) {
DCHECK(!apply_constraints_request_.IsNull());
DCHECK(!user_media_request_);
+ DCHECK(web_track_to_stop_.IsNull());
+}
+
+UserMediaClientImpl::Request::Request(
+ const blink::WebMediaStreamTrack& web_track_to_stop)
+ : web_track_to_stop_(web_track_to_stop) {
+ DCHECK(!web_track_to_stop_.IsNull());
+ DCHECK(!user_media_request_);
+ DCHECK(apply_constraints_request_.IsNull());
}
UserMediaClientImpl::Request::Request(Request&& other)
: user_media_request_(std::move(other.user_media_request_)),
- apply_constraints_request_(other.apply_constraints_request_) {
- DCHECK(!IsApplyConstraints() || !IsUserMedia());
+ apply_constraints_request_(other.apply_constraints_request_),
+ web_track_to_stop_(other.web_track_to_stop_) {
+#if DCHECK_IS_ON()
+ int num_types = 0;
+ if (IsUserMedia())
+ num_types++;
+ if (IsApplyConstraints())
+ num_types++;
+ if (IsStopTrack())
+ num_types++;
+
+ DCHECK_EQ(num_types, 1);
+#endif
}
UserMediaClientImpl::Request& UserMediaClientImpl::Request::operator=(
@@ -96,14 +117,14 @@ UserMediaClientImpl::UserMediaClientImpl(
UserMediaClientImpl::UserMediaClientImpl(
RenderFrame* render_frame,
PeerConnectionDependencyFactory* dependency_factory,
- std::unique_ptr<MediaStreamDispatcher> media_stream_dispatcher,
+ std::unique_ptr<MediaStreamDeviceObserver> media_stream_device_observer,
const scoped_refptr<base::TaskRunner>& worker_task_runner)
: UserMediaClientImpl(
render_frame,
- base::MakeUnique<UserMediaProcessor>(
+ std::make_unique<UserMediaProcessor>(
render_frame,
dependency_factory,
- std::move(media_stream_dispatcher),
+ std::move(media_stream_device_observer),
base::BindRepeating(
&UserMediaClientImpl::GetMediaDevicesDispatcher,
base::Unretained(this)),
@@ -148,17 +169,15 @@ void UserMediaClientImpl::RequestUserMedia(
// The value returned by isProcessingUserGesture() is used by the browser to
// make decisions about the permissions UI. Its value can be lost while
// switching threads, so saving its value here.
+ bool user_gesture = blink::WebUserGestureIndicator::IsProcessingUserGesture(
+ web_request.OwnerDocument().IsNull()
+ ? nullptr
+ : web_request.OwnerDocument().GetFrame());
std::unique_ptr<UserMediaRequest> request_info =
- base::MakeUnique<UserMediaRequest>(
- request_id, web_request,
- blink::WebUserGestureIndicator::IsProcessingUserGesture());
+ std::make_unique<UserMediaRequest>(request_id, web_request, user_gesture);
pending_request_infos_.push_back(Request(std::move(request_info)));
- if (!is_processing_request_) {
- base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&UserMediaClientImpl::MaybeProcessNextRequestInfo,
- weak_factory_.GetWeakPtr()));
- }
+ if (!is_processing_request_)
+ MaybeProcessNextRequestInfo();
}
void UserMediaClientImpl::ApplyConstraints(
@@ -166,12 +185,15 @@ void UserMediaClientImpl::ApplyConstraints(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// TODO(guidou): Implement applyConstraints(). http://crbug.com/338503
pending_request_infos_.push_back(Request(web_request));
- if (!is_processing_request_) {
- base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&UserMediaClientImpl::MaybeProcessNextRequestInfo,
- weak_factory_.GetWeakPtr()));
- }
+ if (!is_processing_request_)
+ MaybeProcessNextRequestInfo();
+}
+
+void UserMediaClientImpl::StopTrack(
+ const blink::WebMediaStreamTrack& web_track) {
+ pending_request_infos_.push_back(Request(web_track));
+ if (!is_processing_request_)
+ MaybeProcessNextRequestInfo();
}
void UserMediaClientImpl::MaybeProcessNextRequestInfo() {
@@ -190,12 +212,22 @@ void UserMediaClientImpl::MaybeProcessNextRequestInfo() {
current_request.MoveUserMediaRequest(),
base::BindOnce(&UserMediaClientImpl::CurrentRequestCompleted,
base::Unretained(this)));
- } else {
- DCHECK(current_request.IsApplyConstraints());
+ } else if (current_request.IsApplyConstraints()) {
apply_constraints_processor_->ProcessRequest(
current_request.apply_constraints_request(),
base::BindOnce(&UserMediaClientImpl::CurrentRequestCompleted,
base::Unretained(this)));
+ } else {
+ DCHECK(current_request.IsStopTrack());
+ MediaStreamTrack* track =
+ MediaStreamTrack::GetTrack(current_request.web_track_to_stop());
+ if (track) {
+ track->StopAndNotify(
+ base::BindOnce(&UserMediaClientImpl::CurrentRequestCompleted,
+ weak_factory_.GetWeakPtr()));
+ } else {
+ CurrentRequestCompleted();
+ }
}
}
@@ -330,11 +362,11 @@ void UserMediaClientImpl::WillCommitProvisionalLoad() {
}
void UserMediaClientImpl::SetMediaDevicesDispatcherForTesting(
- ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher) {
+ blink::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher) {
media_devices_dispatcher_ = std::move(media_devices_dispatcher);
}
-const ::mojom::MediaDevicesDispatcherHostPtr&
+const blink::mojom::MediaDevicesDispatcherHostPtr&
UserMediaClientImpl::GetMediaDevicesDispatcher() {
if (!media_devices_dispatcher_) {
render_frame()->GetRemoteInterfaces()->GetInterface(
diff --git a/chromium/content/renderer/media/user_media_client_impl.h b/chromium/content/renderer/media/user_media_client_impl.h
index 78a27e7d849..02d925d62e4 100644
--- a/chromium/content/renderer/media/user_media_client_impl.h
+++ b/chromium/content/renderer/media/user_media_client_impl.h
@@ -15,11 +15,11 @@
#include "base/sequence_checker.h"
#include "content/common/content_export.h"
#include "content/common/media/media_devices.h"
-#include "content/common/media/media_devices.mojom.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/renderer/media/media_devices_event_dispatcher.h"
#include "content/renderer/media/user_media_processor.h"
#include "third_party/WebKit/public/platform/WebVector.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
#include "third_party/WebKit/public/web/WebApplyConstraintsRequest.h"
#include "third_party/WebKit/public/web/WebMediaDeviceChangeObserver.h"
#include "third_party/WebKit/public/web/WebMediaDevicesRequest.h"
@@ -33,7 +33,7 @@ class TaskRunner;
namespace content {
class ApplyConstraintsProcessor;
-class MediaStreamDispatcher;
+class MediaStreamDeviceObserver;
class PeerConnectionDependencyFactory;
// UserMediaClientImpl handles requests coming from the Blink MediaDevices
@@ -49,14 +49,14 @@ class CONTENT_EXPORT UserMediaClientImpl : public RenderFrameObserver,
UserMediaClientImpl(
RenderFrame* render_frame,
PeerConnectionDependencyFactory* dependency_factory,
- std::unique_ptr<MediaStreamDispatcher> media_stream_dispatcher,
+ std::unique_ptr<MediaStreamDeviceObserver> media_stream_device_observer,
const scoped_refptr<base::TaskRunner>& worker_task_runner);
UserMediaClientImpl(RenderFrame* render_frame,
std::unique_ptr<UserMediaProcessor> user_media_processor);
~UserMediaClientImpl() override;
- MediaStreamDispatcher* media_stream_dispatcher() const {
- return user_media_processor_->media_stream_dispatcher();
+ MediaStreamDeviceObserver* media_stream_device_observer() const {
+ return user_media_processor_->media_stream_device_observer();
}
// blink::WebUserMediaClient implementation
@@ -69,12 +69,13 @@ class CONTENT_EXPORT UserMediaClientImpl : public RenderFrameObserver,
const blink::WebMediaDeviceChangeObserver& observer) override;
void ApplyConstraints(
const blink::WebApplyConstraintsRequest& web_request) override;
+ void StopTrack(const blink::WebMediaStreamTrack& web_track) override;
// RenderFrameObserver override
void WillCommitProvisionalLoad() override;
void SetMediaDevicesDispatcherForTesting(
- ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher);
+ blink::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher);
protected:
// This method is virtual for test purposes. A test can override it to
@@ -89,6 +90,7 @@ class CONTENT_EXPORT UserMediaClientImpl : public RenderFrameObserver,
public:
explicit Request(std::unique_ptr<UserMediaRequest> request);
explicit Request(const blink::WebApplyConstraintsRequest& request);
+ explicit Request(const blink::WebMediaStreamTrack& request);
Request(Request&& other);
Request& operator=(Request&& other);
~Request();
@@ -98,20 +100,23 @@ class CONTENT_EXPORT UserMediaClientImpl : public RenderFrameObserver,
UserMediaRequest* user_media_request() const {
return user_media_request_.get();
}
-
const blink::WebApplyConstraintsRequest& apply_constraints_request() const {
return apply_constraints_request_;
}
+ const blink::WebMediaStreamTrack& web_track_to_stop() const {
+ return web_track_to_stop_;
+ }
+ bool IsUserMedia() const { return !!user_media_request_; }
bool IsApplyConstraints() const {
return !apply_constraints_request_.IsNull();
}
-
- bool IsUserMedia() const { return !!user_media_request_; }
+ bool IsStopTrack() const { return !web_track_to_stop_.IsNull(); }
private:
std::unique_ptr<UserMediaRequest> user_media_request_;
blink::WebApplyConstraintsRequest apply_constraints_request_;
+ blink::WebMediaStreamTrack web_track_to_stop_;
};
void MaybeProcessNextRequestInfo();
@@ -131,7 +136,8 @@ class CONTENT_EXPORT UserMediaClientImpl : public RenderFrameObserver,
void DevicesChanged(MediaDeviceType device_type,
const MediaDeviceInfoArray& device_infos);
- const ::mojom::MediaDevicesDispatcherHostPtr& GetMediaDevicesDispatcher();
+ const blink::mojom::MediaDevicesDispatcherHostPtr&
+ GetMediaDevicesDispatcher();
// |user_media_processor_| is a unique_ptr for testing purposes.
std::unique_ptr<UserMediaProcessor> user_media_processor_;
@@ -139,7 +145,7 @@ class CONTENT_EXPORT UserMediaClientImpl : public RenderFrameObserver,
// problems in builds that do not include WebRTC.
std::unique_ptr<ApplyConstraintsProcessor> apply_constraints_processor_;
- ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher_;
+ blink::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher_;
// UserMedia requests are processed sequentially. |is_processing_request_|
// is a flag that indicates if a request is being processed at a given time,
diff --git a/chromium/content/renderer/media/user_media_client_impl_unittest.cc b/chromium/content/renderer/media/user_media_client_impl_unittest.cc
index 78611a1b065..f426338847c 100644
--- a/chromium/content/renderer/media/user_media_client_impl_unittest.cc
+++ b/chromium/content/renderer/media/user_media_client_impl_unittest.cc
@@ -11,18 +11,18 @@
#include <utility>
#include <vector>
-#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 "content/child/child_process.h"
#include "content/common/media/media_devices.h"
#include "content/renderer/media/media_stream_audio_processor_options.h"
#include "content/renderer/media/media_stream_audio_source.h"
#include "content/renderer/media/media_stream_constraints_util.h"
#include "content/renderer/media/media_stream_constraints_util_video_content.h"
+#include "content/renderer/media/media_stream_device_observer.h"
#include "content/renderer/media/media_stream_track.h"
#include "content/renderer/media/mock_constraint_factory.h"
-#include "content/renderer/media/mock_media_stream_dispatcher.h"
#include "content/renderer/media/mock_media_stream_video_source.h"
#include "content/renderer/media/mock_mojo_media_stream_dispatcher_host.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
@@ -151,7 +151,7 @@ const char kFakeVideoInputDeviceId2[] = "fake_video_input 2";
const char kFakeAudioOutputDeviceId1[] = "fake_audio_output 1";
class MockMediaDevicesDispatcherHost
- : public ::mojom::MediaDevicesDispatcherHost {
+ : public blink::mojom::MediaDevicesDispatcherHost {
public:
MockMediaDevicesDispatcherHost() {}
void EnumerateDevices(bool request_audio_input,
@@ -180,10 +180,10 @@ class MockMediaDevicesDispatcherHost
void GetVideoInputCapabilities(
GetVideoInputCapabilitiesCallback client_callback) override {
- ::mojom::VideoInputDeviceCapabilitiesPtr device =
- ::mojom::VideoInputDeviceCapabilities::New();
+ blink::mojom::VideoInputDeviceCapabilitiesPtr device =
+ blink::mojom::VideoInputDeviceCapabilities::New();
device->device_id = kFakeVideoInputDeviceId1;
- device->facing_mode = ::mojom::FacingMode::USER;
+ device->facing_mode = blink::mojom::FacingMode::USER;
if (!video_source_ || !video_source_->IsRunning() ||
!video_source_->GetCurrentFormat()) {
device->formats.push_back(media::VideoCaptureFormat(
@@ -195,12 +195,12 @@ class MockMediaDevicesDispatcherHost
} else {
device->formats.push_back(*video_source_->GetCurrentFormat());
}
- std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> result;
+ std::vector<blink::mojom::VideoInputDeviceCapabilitiesPtr> result;
result.push_back(std::move(device));
- device = ::mojom::VideoInputDeviceCapabilities::New();
+ device = blink::mojom::VideoInputDeviceCapabilities::New();
device->device_id = kFakeVideoInputDeviceId2;
- device->facing_mode = ::mojom::FacingMode::ENVIRONMENT;
+ device->facing_mode = blink::mojom::FacingMode::ENVIRONMENT;
device->formats.push_back(media::VideoCaptureFormat(
gfx::Size(640, 480), 30.0f, media::PIXEL_FORMAT_I420));
result.push_back(std::move(device));
@@ -210,19 +210,19 @@ class MockMediaDevicesDispatcherHost
void GetAudioInputCapabilities(
GetAudioInputCapabilitiesCallback client_callback) override {
- std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> result;
- ::mojom::AudioInputDeviceCapabilitiesPtr device =
- ::mojom::AudioInputDeviceCapabilities::New();
+ std::vector<blink::mojom::AudioInputDeviceCapabilitiesPtr> result;
+ blink::mojom::AudioInputDeviceCapabilitiesPtr device =
+ blink::mojom::AudioInputDeviceCapabilities::New();
device->device_id = media::AudioDeviceDescription::kDefaultDeviceId;
device->parameters = audio_parameters_;
result.push_back(std::move(device));
- device = ::mojom::AudioInputDeviceCapabilities::New();
+ device = blink::mojom::AudioInputDeviceCapabilities::New();
device->device_id = kFakeAudioInputDeviceId1;
device->parameters = audio_parameters_;
result.push_back(std::move(device));
- device = ::mojom::AudioInputDeviceCapabilities::New();
+ device = blink::mojom::AudioInputDeviceCapabilities::New();
device->device_id = kFakeAudioInputDeviceId2;
device->parameters = audio_parameters_;
result.push_back(std::move(device));
@@ -289,13 +289,13 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor {
public:
UserMediaProcessorUnderTest(
PeerConnectionDependencyFactory* dependency_factory,
- std::unique_ptr<MediaStreamDispatcher> media_stream_dispatcher,
- ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher,
+ std::unique_ptr<MediaStreamDeviceObserver> media_stream_device_observer,
+ blink::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher,
RequestState* state)
: UserMediaProcessor(
nullptr,
dependency_factory,
- std::move(media_stream_dispatcher),
+ std::move(media_stream_device_observer),
base::BindRepeating(
&UserMediaProcessorUnderTest::media_devices_dispatcher,
base::Unretained(this)),
@@ -304,7 +304,7 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor {
media_devices_dispatcher_(std::move(media_devices_dispatcher)),
state_(state) {}
- const ::mojom::MediaDevicesDispatcherHostPtr& media_devices_dispatcher()
+ const blink::mojom::MediaDevicesDispatcherHostPtr& media_devices_dispatcher()
const {
return media_devices_dispatcher_;
}
@@ -329,7 +329,7 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor {
}
content::MediaStreamRequestResult error_reason() const { return result_; }
- blink::WebString error_name() const { return result_name_; }
+ blink::WebString constraint_name() const { return constraint_name_; }
// UserMediaProcessor overrides.
MediaStreamVideoSource* CreateVideoSource(
@@ -351,10 +351,9 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor {
public:
FailedAtLifeAudioSource() : MediaStreamAudioSource(true) {}
~FailedAtLifeAudioSource() override {}
+
protected:
- bool EnsureSourceIsStarted() override {
- return false;
- }
+ bool EnsureSourceIsStarted() override { return false; }
};
source = new FailedAtLifeAudioSource();
} else {
@@ -382,12 +381,13 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor {
*state_ = REQUEST_SUCCEEDED;
}
- void GetUserMediaRequestFailed(content::MediaStreamRequestResult result,
- const blink::WebString& result_name) override {
+ void GetUserMediaRequestFailed(
+ content::MediaStreamRequestResult result,
+ const blink::WebString& constraint_name) override {
last_generated_stream_.Reset();
*state_ = REQUEST_FAILED;
result_ = result;
- result_name_ = result_name;
+ constraint_name_ = constraint_name;
}
private:
@@ -398,12 +398,12 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor {
}
PeerConnectionDependencyFactory* factory_;
- ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher_;
+ blink::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher_;
MockMediaStreamVideoCapturerSource* video_source_ = nullptr;
bool create_source_that_fails_ = false;
blink::WebMediaStream last_generated_stream_;
content::MediaStreamRequestResult result_ = NUM_MEDIA_REQUEST_RESULTS;
- blink::WebString result_name_;
+ blink::WebString constraint_name_;
RequestState* state_;
};
@@ -461,24 +461,24 @@ class UserMediaClientImplTest : public ::testing::Test {
void SetUp() override {
// Create our test object.
- child_process_.reset(new ChildProcess());
dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
- ms_dispatcher_ = new MockMediaStreamDispatcher();
- mojom::MediaStreamDispatcherHostPtr dispatcher_host =
- mock_dispatcher_host_.CreateInterfacePtrAndBind();
- ms_dispatcher_->dispatcher_host_ = std::move(dispatcher_host);
+ msd_observer_ = new MediaStreamDeviceObserver(nullptr);
- ::mojom::MediaDevicesDispatcherHostPtr user_media_processor_host_proxy;
+ blink::mojom::MediaDevicesDispatcherHostPtr user_media_processor_host_proxy;
binding_user_media_processor_.Bind(
mojo::MakeRequest(&user_media_processor_host_proxy));
user_media_processor_ = new UserMediaProcessorUnderTest(
- dependency_factory_.get(), base::WrapUnique(ms_dispatcher_),
- std::move(user_media_processor_host_proxy), &state_),
+ dependency_factory_.get(), base::WrapUnique(msd_observer_),
+ std::move(user_media_processor_host_proxy), &state_);
+ mojom::MediaStreamDispatcherHostPtr dispatcher_host =
+ mock_dispatcher_host_.CreateInterfacePtrAndBind();
+ user_media_processor_->set_media_stream_dispatcher_host_for_testing(
+ std::move(dispatcher_host));
- user_media_client_impl_ = base::MakeUnique<UserMediaClientImplUnderTest>(
+ user_media_client_impl_ = std::make_unique<UserMediaClientImplUnderTest>(
user_media_processor_, &state_);
- ::mojom::MediaDevicesDispatcherHostPtr user_media_client_host_proxy;
+ blink::mojom::MediaDevicesDispatcherHostPtr user_media_client_host_proxy;
binding_user_media_client_.Bind(
mojo::MakeRequest(&user_media_client_host_proxy));
user_media_client_impl_->SetMediaDevicesDispatcherForTesting(
@@ -486,7 +486,7 @@ class UserMediaClientImplTest : public ::testing::Test {
base::WeakPtr<MediaDevicesEventDispatcher> event_dispatcher =
MediaDevicesEventDispatcher::GetForRenderFrame(nullptr);
- ::mojom::MediaDevicesDispatcherHostPtr event_dispatcher_host_proxy;
+ blink::mojom::MediaDevicesDispatcherHostPtr event_dispatcher_host_proxy;
binding_event_dispatcher_.Bind(
mojo::MakeRequest(&event_dispatcher_host_proxy));
event_dispatcher->SetMediaDevicesDispatcherForTesting(
@@ -501,11 +501,11 @@ class UserMediaClientImplTest : public ::testing::Test {
void LoadNewDocumentInFrame() {
user_media_client_impl_->WillCommitProvisionalLoad();
+ base::RunLoop().RunUntilIdle();
}
blink::WebMediaStream RequestLocalMediaStream() {
user_media_client_impl_->RequestUserMediaForTest();
- FakeMediaStreamDispatcherRequestUserMediaComplete();
StartMockedVideoSource();
EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
@@ -527,7 +527,6 @@ class UserMediaClientImplTest : public ::testing::Test {
blink::WebUserMediaRequest::CreateForTesting(
blink::WebMediaConstraints(), CreateDefaultConstraints());
user_media_client_impl_->RequestUserMediaForTest(user_media_request);
- FakeMediaStreamDispatcherRequestUserMediaComplete();
StartMockedVideoSource();
EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
@@ -544,15 +543,6 @@ class UserMediaClientImplTest : public ::testing::Test {
return video_tracks[0];
}
- void FakeMediaStreamDispatcherRequestUserMediaComplete() {
- // Audio request ID is used as the shared request ID.
- user_media_processor_->OnStreamGenerated(
- ms_dispatcher_->audio_input_request_id(),
- ms_dispatcher_->stream_label(), ms_dispatcher_->audio_devices(),
- ms_dispatcher_->video_devices());
- base::RunLoop().RunUntilIdle();
- }
-
void StartMockedVideoSource() {
MockMediaStreamVideoCapturerSource* video_source =
user_media_processor_->last_created_video_source();
@@ -579,18 +569,17 @@ class UserMediaClientImplTest : public ::testing::Test {
blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
video_constraints);
user_media_client_impl_->RequestUserMediaForTest(request);
- FakeMediaStreamDispatcherRequestUserMediaComplete();
StartMockedVideoSource();
EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
- EXPECT_EQ(1U, ms_dispatcher_->audio_devices().size());
- EXPECT_EQ(1U, ms_dispatcher_->video_devices().size());
- // MockMediaStreamDispatcher appends the session ID to its internal device
- // IDs.
+ EXPECT_EQ(1U, mock_dispatcher_host_.audio_devices().size());
+ EXPECT_EQ(1U, mock_dispatcher_host_.video_devices().size());
+ // MockMojoMediaStreamDispatcherHost appends the session ID to its internal
+ // device IDs.
EXPECT_EQ(std::string(expected_audio_device_id) + "0",
- ms_dispatcher_->audio_devices()[0].id);
+ mock_dispatcher_host_.audio_devices()[0].id);
EXPECT_EQ(std::string(expected_video_device_id) + "0",
- ms_dispatcher_->video_devices()[0].id);
+ mock_dispatcher_host_.video_devices()[0].id);
}
void ApplyConstraintsVideoMode(
@@ -614,16 +603,20 @@ class UserMediaClientImplTest : public ::testing::Test {
RequestState request_state() const { return state_; }
protected:
- base::MessageLoop message_loop_;
- std::unique_ptr<ChildProcess> child_process_;
- MockMediaStreamDispatcher* ms_dispatcher_ =
+ // The ScopedTaskEnvironment prevents the ChildProcess from leaking a
+ // TaskScheduler.
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ ChildProcess child_process_;
+ MediaStreamDeviceObserver* msd_observer_ =
nullptr; // Owned by |used_media_processor_|.
MockMojoMediaStreamDispatcherHost mock_dispatcher_host_;
MockMediaDevicesDispatcherHost media_devices_dispatcher_;
- mojo::Binding<::mojom::MediaDevicesDispatcherHost>
+ mojo::Binding<blink::mojom::MediaDevicesDispatcherHost>
binding_user_media_processor_;
- mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_user_media_client_;
- mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_event_dispatcher_;
+ mojo::Binding<blink::mojom::MediaDevicesDispatcherHost>
+ binding_user_media_client_;
+ mojo::Binding<blink::mojom::MediaDevicesDispatcherHost>
+ binding_event_dispatcher_;
UserMediaProcessorUnderTest* user_media_processor_ =
nullptr; // Owned by |user_media_client_impl_|
@@ -670,7 +663,7 @@ TEST_F(UserMediaClientImplTest, GenerateTwoMediaStreamsWithDifferentSources) {
blink::WebMediaStream desc1 = RequestLocalMediaStream();
// Make sure another device is selected (another |session_id|) in the next
// gUM request.
- ms_dispatcher_->IncrementSessionId();
+ mock_dispatcher_host_.IncrementSessionId();
blink::WebMediaStream desc2 = RequestLocalMediaStream();
blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
@@ -702,13 +695,15 @@ TEST_F(UserMediaClientImplTest, StopLocalTracks) {
mixed_desc.AudioTracks(audio_tracks);
MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
audio_track->Stop();
- EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
mixed_desc.VideoTracks(video_tracks);
MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
video_track->Stop();
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}
// This test that a source is not stopped even if the tracks in a
@@ -724,25 +719,29 @@ TEST_F(UserMediaClientImplTest, StopLocalTracksWhenTwoStreamUseSameDevices) {
desc1.AudioTracks(audio_tracks1);
MediaStreamTrack* audio_track1 = MediaStreamTrack::GetTrack(audio_tracks1[0]);
audio_track1->Stop();
- EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0, mock_dispatcher_host_.stop_audio_device_counter());
blink::WebVector<blink::WebMediaStreamTrack> audio_tracks2;
desc2.AudioTracks(audio_tracks2);
MediaStreamTrack* audio_track2 = MediaStreamTrack::GetTrack(audio_tracks2[0]);
audio_track2->Stop();
- EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
blink::WebVector<blink::WebMediaStreamTrack> video_tracks1;
desc1.VideoTracks(video_tracks1);
MediaStreamTrack* video_track1 = MediaStreamTrack::GetTrack(video_tracks1[0]);
video_track1->Stop();
- EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0, mock_dispatcher_host_.stop_video_device_counter());
blink::WebVector<blink::WebMediaStreamTrack> video_tracks2;
desc2.VideoTracks(video_tracks2);
MediaStreamTrack* video_track2 = MediaStreamTrack::GetTrack(video_tracks2[0]);
video_track2->Stop();
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}
TEST_F(UserMediaClientImplTest, StopSourceWhenMediaStreamGoesOutOfScope) {
@@ -752,10 +751,11 @@ TEST_F(UserMediaClientImplTest, StopSourceWhenMediaStreamGoesOutOfScope) {
// MediaStream.
user_media_processor_->ClearLastGeneratedStream();
blink::WebHeap::CollectAllGarbageForTesting();
+ base::RunLoop().RunUntilIdle();
// Expect the sources to be stopped when the MediaStream goes out of scope.
- EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}
// Test that the MediaStreams are deleted if a new document is loaded in the
@@ -766,57 +766,58 @@ TEST_F(UserMediaClientImplTest, LoadNewDocumentInFrame) {
blink::WebMediaStream desc2 = RequestLocalMediaStream();
LoadNewDocumentInFrame();
blink::WebHeap::CollectAllGarbageForTesting();
- EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}
// This test what happens if a video source to a MediaSteam fails to start.
TEST_F(UserMediaClientImplTest, MediaVideoSourceFailToStart) {
user_media_client_impl_->RequestUserMediaForTest();
- FakeMediaStreamDispatcherRequestUserMediaComplete();
FailToStartMockedVideoSource();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(REQUEST_FAILED, request_state());
EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE,
user_media_processor_->error_reason());
blink::WebHeap::CollectAllGarbageForTesting();
- EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
- EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}
// This test what happens if an audio source fail to initialize.
TEST_F(UserMediaClientImplTest, MediaAudioSourceFailToInitialize) {
user_media_processor_->SetCreateSourceThatFails(true);
user_media_client_impl_->RequestUserMediaForTest();
- FakeMediaStreamDispatcherRequestUserMediaComplete();
StartMockedVideoSource();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(REQUEST_FAILED, request_state());
EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE,
user_media_processor_->error_reason());
blink::WebHeap::CollectAllGarbageForTesting();
- EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
- EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}
// This test what happens if UserMediaClientImpl is deleted before a source has
// started.
TEST_F(UserMediaClientImplTest, MediaStreamImplShutDown) {
user_media_client_impl_->RequestUserMediaForTest();
- FakeMediaStreamDispatcherRequestUserMediaComplete();
- EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
EXPECT_EQ(REQUEST_NOT_COMPLETE, request_state());
user_media_client_impl_.reset();
}
// This test what happens if a new document is loaded in the frame while the
-// MediaStream is being generated by the MediaStreamDispatcher.
+// MediaStream is being generated by the MediaStreamDeviceObserver.
TEST_F(UserMediaClientImplTest, ReloadFrameWhileGeneratingStream) {
+ mock_dispatcher_host_.DoNotRunCallback();
+
user_media_client_impl_->RequestUserMediaForTest();
LoadNewDocumentInFrame();
- EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
- EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
- EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
+ EXPECT_EQ(0, mock_dispatcher_host_.stop_audio_device_counter());
+ EXPECT_EQ(0, mock_dispatcher_host_.stop_video_device_counter());
EXPECT_EQ(REQUEST_NOT_COMPLETE, request_state());
}
@@ -824,11 +825,10 @@ TEST_F(UserMediaClientImplTest, ReloadFrameWhileGeneratingStream) {
// sources are being started.
TEST_F(UserMediaClientImplTest, ReloadFrameWhileGeneratingSources) {
user_media_client_impl_->RequestUserMediaForTest();
- FakeMediaStreamDispatcherRequestUserMediaComplete();
- EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
LoadNewDocumentInFrame();
- EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
EXPECT_EQ(REQUEST_NOT_COMPLETE, request_state());
}
@@ -836,23 +836,25 @@ TEST_F(UserMediaClientImplTest, ReloadFrameWhileGeneratingSources) {
// been reloaded.
TEST_F(UserMediaClientImplTest, StopTrackAfterReload) {
blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
- EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
LoadNewDocumentInFrame();
blink::WebHeap::CollectAllGarbageForTesting();
- EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
mixed_desc.AudioTracks(audio_tracks);
MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
audio_track->Stop();
- EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
mixed_desc.VideoTracks(video_tracks);
MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
video_track->Stop();
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}
TEST_F(UserMediaClientImplTest, EnumerateMediaDevices) {
@@ -1052,6 +1054,7 @@ TEST_F(UserMediaClientImplTest, DefaultDesktopCapturePropagate) {
VideoCaptureSettings video_capture_settings =
user_media_processor_->VideoSettings();
user_media_client_impl_->CancelUserMediaRequest(request);
+ base::RunLoop().RunUntilIdle();
// Check default values selected by the constraints algorithm.
EXPECT_TRUE(audio_capture_settings.HasValue());
@@ -1098,6 +1101,8 @@ TEST_F(UserMediaClientImplTest, DefaultDesktopCapturePropagate) {
}
TEST_F(UserMediaClientImplTest, NonDefaultAudioConstraintsPropagate) {
+ mock_dispatcher_host_.DoNotRunCallback();
+
MockConstraintFactory factory;
factory.basic().device_id.SetExact(
blink::WebString::FromASCII(kFakeAudioInputDeviceId1));
@@ -1182,32 +1187,6 @@ TEST_F(UserMediaClientImplTest, ObserveMediaDeviceChanges) {
base::RunLoop().RunUntilIdle();
}
-// This test what happens if the audio stream has same id with video stream.
-TEST_F(UserMediaClientImplTest, AudioVideoWithSameId) {
- ms_dispatcher_->TestSameId();
-
- // Generate a stream with both audio and video.
- blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
-
- // Remove video track. This should trigger
- // UserMediaClientImpl::OnLocalSourceStopped, and has video track to be
- // removed from its |local_sources_|.
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- mixed_desc.VideoTracks(video_tracks);
- MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
- video_track->Stop();
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
- EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
-
- // Now we load a new document in the web frame. If in the above Stop() call,
- // UserMediaClientImpl accidentally removed audio track, then video track will
- // be removed again here, which is incorrect.
- LoadNewDocumentInFrame();
- blink::WebHeap::CollectAllGarbageForTesting();
- EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
- EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
-}
-
TEST_F(UserMediaClientImplTest, CreateWithMandatoryInvalidAudioDeviceId) {
blink::WebMediaConstraints audio_constraints =
CreateDeviceConstraints(kInvalidDeviceId);
@@ -1251,8 +1230,8 @@ TEST_F(UserMediaClientImplTest, CreateWithBasicIdealValidDeviceId) {
TEST_F(UserMediaClientImplTest, CreateWithAdvancedExactValidDeviceId) {
blink::WebMediaConstraints audio_constraints =
CreateDeviceConstraints(nullptr, nullptr, kFakeAudioInputDeviceId1);
- blink::WebMediaConstraints video_constraints = CreateDeviceConstraints(
- nullptr, nullptr, kFakeVideoInputDeviceId1);
+ blink::WebMediaConstraints video_constraints =
+ CreateDeviceConstraints(nullptr, nullptr, kFakeVideoInputDeviceId1);
TestValidRequestWithConstraints(audio_constraints, video_constraints,
kFakeAudioInputDeviceId1,
kFakeVideoInputDeviceId1);
@@ -1263,8 +1242,8 @@ TEST_F(UserMediaClientImplTest, CreateWithAllOptionalInvalidDeviceId) {
CreateDeviceConstraints(nullptr, kInvalidDeviceId, kInvalidDeviceId);
blink::WebMediaConstraints video_constraints =
CreateDeviceConstraints(nullptr, kInvalidDeviceId, kInvalidDeviceId);
- // MockMediaStreamDispatcher uses empty string as default audio device ID.
- // MockMediaDevicesDispatcher uses the first device in the enumeration as
+ // MockMojoMediaStreamDispatcherHost uses empty string as default audio device
+ // ID. MockMediaDevicesDispatcher uses the first device in the enumeration as
// default audio or video device ID.
std::string expected_audio_device_id =
media::AudioDeviceDescription::kDefaultDeviceId;
@@ -1296,7 +1275,7 @@ TEST_F(UserMediaClientImplTest, CreateWithFacingModeEnvironment) {
}
TEST_F(UserMediaClientImplTest, ApplyConstraintsVideoDeviceSingleTrack) {
- EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
+ EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
MediaStreamVideoTrack* track =
MediaStreamVideoTrack::GetVideoTrack(web_track);
@@ -1328,7 +1307,7 @@ TEST_F(UserMediaClientImplTest, ApplyConstraintsVideoDeviceSingleTrack) {
}
TEST_F(UserMediaClientImplTest, ApplyConstraintsVideoDeviceTwoTracks) {
- EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
+ EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
MockMediaStreamVideoCapturerSource* source =
user_media_processor_->last_created_video_source();
@@ -1342,7 +1321,7 @@ TEST_F(UserMediaClientImplTest, ApplyConstraintsVideoDeviceTwoTracks) {
// Create a new track and verify that it uses the same source and that the
// source's format did not change. The new track uses the same format as the
// source by default.
- EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
+ EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
blink::WebMediaStreamTrack web_track2 = RequestLocalVideoTrack();
CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track2, 1024, 768,
20.0);
@@ -1376,7 +1355,7 @@ TEST_F(UserMediaClientImplTest, ApplyConstraintsVideoDeviceTwoTracks) {
TEST_F(UserMediaClientImplTest,
ApplyConstraintsVideoDeviceFailsToStopForRestart) {
- EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
+ EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
MockMediaStreamVideoCapturerSource* source =
user_media_processor_->last_created_video_source();
@@ -1396,7 +1375,7 @@ TEST_F(UserMediaClientImplTest,
TEST_F(UserMediaClientImplTest,
ApplyConstraintsVideoDeviceFailsToRestartAfterStop) {
- EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
+ EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
MockMediaStreamVideoCapturerSource* source =
user_media_processor_->last_created_video_source();
@@ -1418,7 +1397,7 @@ TEST_F(UserMediaClientImplTest,
}
TEST_F(UserMediaClientImplTest, ApplyConstraintsVideoDeviceStopped) {
- EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
+ EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
MockMediaStreamVideoCapturerSource* source =
user_media_processor_->last_created_video_source();
diff --git a/chromium/content/renderer/media/user_media_processor.cc b/chromium/content/renderer/media/user_media_processor.cc
index 7b49973f352..721744f1ed8 100644
--- a/chromium/content/renderer/media/user_media_processor.cc
+++ b/chromium/content/renderer/media/user_media_processor.cc
@@ -17,7 +17,9 @@
#include "base/task_runner.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "content/child/child_thread_impl.h"
#include "content/common/media/media_stream_controls.h"
+#include "content/public/common/service_names.mojom.h"
#include "content/public/renderer/render_frame.h"
#include "content/renderer/media/local_media_stream_audio_source.h"
#include "content/renderer/media/media_stream_audio_processor.h"
@@ -26,7 +28,7 @@
#include "content/renderer/media/media_stream_constraints_util_audio.h"
#include "content/renderer/media/media_stream_constraints_util_video_content.h"
#include "content/renderer/media/media_stream_constraints_util_video_device.h"
-#include "content/renderer/media/media_stream_dispatcher.h"
+#include "content/renderer/media/media_stream_device_observer.h"
#include "content/renderer/media/media_stream_video_capturer_source.h"
#include "content/renderer/media/media_stream_video_track.h"
#include "content/renderer/media/user_media_client_impl.h"
@@ -36,6 +38,7 @@
#include "content/renderer/media/webrtc_uma_histograms.h"
#include "media/base/audio_parameters.h"
#include "media/capture/video_capture_types.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
#include "third_party/WebKit/public/platform/WebMediaStream.h"
#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
@@ -320,17 +323,18 @@ void UserMediaProcessor::RequestInfo::OnAudioSourceStarted(
UserMediaProcessor::UserMediaProcessor(
RenderFrame* render_frame,
PeerConnectionDependencyFactory* dependency_factory,
- std::unique_ptr<MediaStreamDispatcher> media_stream_dispatcher,
+ std::unique_ptr<MediaStreamDeviceObserver> media_stream_device_observer,
MediaDevicesDispatcherCallback media_devices_dispatcher_cb,
const scoped_refptr<base::TaskRunner>& worker_task_runner)
: dependency_factory_(dependency_factory),
- media_stream_dispatcher_(std::move(media_stream_dispatcher)),
+ media_stream_device_observer_(std::move(media_stream_device_observer)),
media_devices_dispatcher_cb_(std::move(media_devices_dispatcher_cb)),
worker_task_runner_(worker_task_runner),
- render_frame_(render_frame),
+ render_frame_id_(render_frame ? render_frame->GetRoutingID()
+ : MSG_ROUTING_NONE),
weak_factory_(this) {
DCHECK(dependency_factory_);
- DCHECK(media_stream_dispatcher_.get());
+ DCHECK(media_stream_device_observer_.get());
}
UserMediaProcessor::~UserMediaProcessor() {
@@ -351,7 +355,7 @@ void UserMediaProcessor::ProcessRequest(
DCHECK(!request_completed_cb_);
DCHECK(!current_request_info_);
request_completed_cb_ = std::move(callback);
- current_request_info_ = base::MakeUnique<RequestInfo>(std::move(request));
+ current_request_info_ = std::make_unique<RequestInfo>(std::move(request));
// TODO(guidou): Set up audio and video in parallel.
if (current_request_info_->web_request().Audio()) {
SetupAudioInput();
@@ -390,7 +394,7 @@ void UserMediaProcessor::SetupAudioInput() {
void UserMediaProcessor::SelectAudioSettings(
const blink::WebUserMediaRequest& web_request,
- std::vector<::mojom::AudioInputDeviceCapabilitiesPtr>
+ std::vector<blink::mojom::AudioInputDeviceCapabilitiesPtr>
audio_input_capabilities) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// The frame might reload or |web_request| might be cancelled while
@@ -401,7 +405,8 @@ void UserMediaProcessor::SelectAudioSettings(
DCHECK(current_request_info_->stream_controls()->audio.requested);
auto settings = SelectSettingsAudioCapture(
- std::move(audio_input_capabilities), web_request.AudioConstraints());
+ std::move(audio_input_capabilities), web_request.AudioConstraints(),
+ web_request.ShouldDisableHardwareNoiseSuppression());
if (!settings.HasValue()) {
blink::WebString failed_constraint_name =
blink::WebString::FromASCII(settings.failed_constraint_name());
@@ -466,7 +471,7 @@ void UserMediaProcessor::SetupVideoInput() {
void UserMediaProcessor::SelectVideoDeviceSettings(
const blink::WebUserMediaRequest& web_request,
- std::vector<::mojom::VideoInputDeviceCapabilitiesPtr>
+ std::vector<blink::mojom::VideoInputDeviceCapabilitiesPtr>
video_input_capabilities) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// The frame might reload or |web_request| might be cancelled while
@@ -556,30 +561,40 @@ void UserMediaProcessor::GenerateStreamForCurrentRequestInfo() {
current_request_info_->stream_controls()->video.device_id.c_str()));
current_request_info_->set_state(RequestInfo::State::SENT_FOR_GENERATION);
- // The browser replies to this request by invoking OnStreamGenerated() if
- // successful, or OnStreamGenerationFailed() if not.
- media_stream_dispatcher_->GenerateStream(
- current_request_info_->request_id(), weak_factory_.GetWeakPtr(),
+ // The browser replies to this request by invoking OnStreamGenerated().
+ GetMediaStreamDispatcherHost()->GenerateStream(
+ render_frame_id_, current_request_info_->request_id(),
*current_request_info_->stream_controls(),
- current_request_info_->security_origin(),
- current_request_info_->is_processing_user_gesture());
+ current_request_info_->is_processing_user_gesture(),
+ base::BindOnce(&UserMediaProcessor::OnStreamGenerated,
+ weak_factory_.GetWeakPtr(),
+ current_request_info_->request_id()));
}
-// Callback from MediaStreamDispatcher.
-// The requested stream have been generated by the MediaStreamDispatcher.
void UserMediaProcessor::OnStreamGenerated(
int request_id,
+ MediaStreamRequestResult result,
const std::string& label,
const MediaStreamDevices& audio_devices,
const MediaStreamDevices& video_devices) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (result != MEDIA_DEVICE_OK) {
+ OnStreamGenerationFailed(request_id, result);
+ return;
+ }
+
if (!IsCurrentRequestInfo(request_id)) {
// This can happen if the request is cancelled or the frame reloads while
- // MediaStreamDispatcher is processing the request.
+ // MediaStreamDispatcherHost is processing the request.
DVLOG(1) << "Request ID not found";
OnStreamGeneratedForCancelledRequest(audio_devices, video_devices);
return;
}
+
+ media_stream_device_observer_->AddStream(label, audio_devices, video_devices,
+ weak_factory_.GetWeakPtr());
+
current_request_info_->set_state(RequestInfo::State::GENERATED);
for (const auto* devices : {&audio_devices, &video_devices}) {
@@ -617,13 +632,17 @@ void UserMediaProcessor::OnStreamGeneratedForCancelledRequest(
const MediaStreamDevices& video_devices) {
// Only stop the device if the device is not used in another MediaStream.
for (auto it = audio_devices.begin(); it != audio_devices.end(); ++it) {
- if (!FindLocalSource(*it))
- media_stream_dispatcher_->StopStreamDevice(*it);
+ if (!FindLocalSource(*it)) {
+ GetMediaStreamDispatcherHost()->StopStreamDevice(render_frame_id_,
+ it->id);
+ }
}
for (auto it = video_devices.begin(); it != video_devices.end(); ++it) {
- if (!FindLocalSource(*it))
- media_stream_dispatcher_->StopStreamDevice(*it);
+ if (!FindLocalSource(*it)) {
+ GetMediaStreamDispatcherHost()->StopStreamDevice(render_frame_id_,
+ it->id);
+ }
}
}
@@ -670,26 +689,21 @@ void UserMediaProcessor::NotifyCurrentRequestInfoOfAudioSourceStarted(
current_request_info_->OnAudioSourceStarted(source, result, result_name);
}
-// Callback from MediaStreamDispatcher.
-// The requested stream failed to be generated.
void UserMediaProcessor::OnStreamGenerationFailed(
int request_id,
MediaStreamRequestResult result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!IsCurrentRequestInfo(request_id)) {
// This can happen if the request is cancelled or the frame reloads while
- // MediaStreamDispatcher is processing the request.
+ // MediaStreamDispatcherHost is processing the request.
return;
}
- GetUserMediaRequestFailed(result, "");
+ GetUserMediaRequestFailed(result);
DeleteWebRequest(current_request_info_->web_request());
}
-// Callback from MediaStreamDispatcher.
-// The browser process has stopped a device used by a MediaStream.
-void UserMediaProcessor::OnDeviceStopped(const std::string& label,
- const MediaStreamDevice& device) {
+void UserMediaProcessor::OnDeviceStopped(const MediaStreamDevice& device) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "UserMediaClientImpl::OnDeviceStopped("
<< "{device_id = " << device.id << "})";
@@ -785,15 +799,15 @@ MediaStreamAudioSource* UserMediaProcessor::CreateAudioSource(
!MediaStreamAudioProcessor::WouldModifyAudio(
audio_processing_properties)) {
*has_sw_echo_cancellation = false;
- return new LocalMediaStreamAudioSource(render_frame_->GetRoutingID(),
- device, source_ready);
+ return new LocalMediaStreamAudioSource(render_frame_id_, device,
+ source_ready);
}
// The audio device is not associated with screen capture and also requires
// processing.
ProcessedLocalAudioSource* source = new ProcessedLocalAudioSource(
- render_frame_->GetRoutingID(), device, audio_processing_properties,
- source_ready, dependency_factory_);
+ render_frame_id_, device, audio_processing_properties, source_ready,
+ dependency_factory_);
*has_sw_echo_cancellation =
audio_processing_properties.enable_sw_echo_cancellation;
return source;
@@ -808,8 +822,7 @@ MediaStreamVideoSource* UserMediaProcessor::CreateVideoSource(
return new MediaStreamVideoCapturerSource(
stop_callback, device,
- current_request_info_->video_capture_settings().capture_params(),
- render_frame_);
+ current_request_info_->video_capture_settings().capture_params());
}
void UserMediaProcessor::CreateVideoTracks(
@@ -846,7 +859,9 @@ void UserMediaProcessor::CreateAudioTracks(
// be removed.
for (auto& device : overridden_audio_devices) {
device.matched_output_device_id = "";
- device.matched_output = media::AudioParameters::UnavailableDeviceParams();
+ // Audio parameters must be invalid in order to ensure that the matched
+ // output device will not be used.
+ device.matched_output = media::AudioParameters();
}
}
@@ -867,14 +882,14 @@ void UserMediaProcessor::OnCreateNativeTracksCompleted(
const std::string& label,
RequestInfo* request_info,
MediaStreamRequestResult result,
- const blink::WebString& result_name) {
+ const blink::WebString& constraint_name) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (result == MEDIA_DEVICE_OK) {
GetUserMediaRequestSucceeded(*request_info->web_stream(),
request_info->web_request());
- media_stream_dispatcher_->OnStreamStarted(label);
+ GetMediaStreamDispatcherHost()->OnStreamStarted(label);
} else {
- GetUserMediaRequestFailed(result, result_name);
+ GetUserMediaRequestFailed(result, constraint_name);
blink::WebVector<blink::WebMediaStreamTrack> tracks;
request_info->web_stream()->AudioTracks(tracks);
@@ -894,19 +909,6 @@ void UserMediaProcessor::OnCreateNativeTracksCompleted(
DeleteWebRequest(request_info->web_request());
}
-void UserMediaProcessor::OnDeviceOpened(int request_id,
- const std::string& label,
- const MediaStreamDevice& device) {
- DVLOG(1) << "UserMediaClientImpl::OnDeviceOpened(" << request_id << ", "
- << label << ")";
- NOTIMPLEMENTED();
-}
-
-void UserMediaProcessor::OnDeviceOpenFailed(int request_id) {
- DVLOG(1) << "UserMediaProcessor::VideoDeviceOpenFailed(" << request_id << ")";
- NOTIMPLEMENTED();
-}
-
void UserMediaProcessor::GetUserMediaRequestSucceeded(
const blink::WebMediaStream& stream,
blink::WebUserMediaRequest web_request) {
@@ -936,7 +938,7 @@ void UserMediaProcessor::DelayedGetUserMediaRequestSucceeded(
void UserMediaProcessor::GetUserMediaRequestFailed(
MediaStreamRequestResult result,
- const blink::WebString& result_name) {
+ const blink::WebString& constraint_name) {
DCHECK(current_request_info_);
WebRtcLogMessage(
base::StringPrintf("UMCI::GetUserMediaRequestFailed. request_id=%d",
@@ -951,13 +953,13 @@ void UserMediaProcessor::GetUserMediaRequestFailed(
base::BindOnce(&UserMediaProcessor::DelayedGetUserMediaRequestFailed,
weak_factory_.GetWeakPtr(),
current_request_info_->web_request(), result,
- result_name));
+ constraint_name));
}
void UserMediaProcessor::DelayedGetUserMediaRequestFailed(
blink::WebUserMediaRequest web_request,
MediaStreamRequestResult result,
- const blink::WebString& result_name) {
+ const blink::WebString& constraint_name) {
LogUserMediaRequestResult(result);
DeleteWebRequest(web_request);
switch (result) {
@@ -966,47 +968,64 @@ void UserMediaProcessor::DelayedGetUserMediaRequestFailed(
NOTREACHED();
return;
case MEDIA_DEVICE_PERMISSION_DENIED:
- web_request.RequestDenied();
+ web_request.RequestFailed(
+ blink::WebUserMediaRequest::Error::kPermissionDenied,
+ "Permission denied");
return;
case MEDIA_DEVICE_PERMISSION_DISMISSED:
- web_request.RequestFailedUASpecific("PermissionDismissedError");
+ web_request.RequestFailed(
+ blink::WebUserMediaRequest::Error::kPermissionDismissed,
+ "Permission dismissed");
return;
case MEDIA_DEVICE_INVALID_STATE:
- web_request.RequestFailedUASpecific("InvalidStateError");
+ web_request.RequestFailed(
+ blink::WebUserMediaRequest::Error::kInvalidState, "Invalid state");
return;
case MEDIA_DEVICE_NO_HARDWARE:
- web_request.RequestFailedUASpecific("DevicesNotFoundError");
+ web_request.RequestFailed(
+ blink::WebUserMediaRequest::Error::kDevicesNotFound,
+ "Requested device not found");
return;
case MEDIA_DEVICE_INVALID_SECURITY_ORIGIN_DEPRECATED:
NOTREACHED();
return;
case MEDIA_DEVICE_TAB_CAPTURE_FAILURE:
- web_request.RequestFailedUASpecific("TabCaptureError");
+ web_request.RequestFailed(blink::WebUserMediaRequest::Error::kTabCapture,
+ "Error starting tab capture");
return;
case MEDIA_DEVICE_SCREEN_CAPTURE_FAILURE:
- web_request.RequestFailedUASpecific("ScreenCaptureError");
+ web_request.RequestFailed(
+ blink::WebUserMediaRequest::Error::kScreenCapture,
+ "Error starting screen capture");
return;
case MEDIA_DEVICE_CAPTURE_FAILURE:
- web_request.RequestFailedUASpecific("DeviceCaptureError");
+ web_request.RequestFailed(blink::WebUserMediaRequest::Error::kCapture,
+ "Error starting capture");
return;
case MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED:
- web_request.RequestFailedConstraint(result_name);
+ web_request.RequestFailedConstraint(constraint_name);
return;
case MEDIA_DEVICE_TRACK_START_FAILURE:
- web_request.RequestFailedUASpecific("TrackStartError");
+ web_request.RequestFailed(blink::WebUserMediaRequest::Error::kTrackStart,
+ "Could not start source");
return;
case MEDIA_DEVICE_NOT_SUPPORTED:
- web_request.RequestFailedUASpecific("MediaDeviceNotSupported");
+ web_request.RequestFailed(
+ blink::WebUserMediaRequest::Error::kNotSupported, "Not supported");
return;
case MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN:
- web_request.RequestFailedUASpecific("MediaDeviceFailedDueToShutdown");
+ web_request.RequestFailed(
+ blink::WebUserMediaRequest::Error::kFailedDueToShutdown,
+ "Failed due to shutdown");
return;
case MEDIA_DEVICE_KILL_SWITCH_ON:
- web_request.RequestFailedUASpecific("MediaDeviceKillSwitchOn");
+ web_request.RequestFailed(
+ blink::WebUserMediaRequest::Error::kKillSwitchOn);
return;
}
NOTREACHED();
- web_request.RequestFailed();
+ web_request.RequestFailed(
+ blink::WebUserMediaRequest::Error::kPermissionDenied);
}
const blink::WebMediaStreamSource* UserMediaProcessor::FindLocalSource(
@@ -1104,8 +1123,9 @@ bool UserMediaProcessor::DeleteWebRequest(
void UserMediaProcessor::StopAllProcessing() {
if (current_request_info_) {
// If the request is not generated, it means that a request has been sent to
- // the MediaStreamDispatcher to generate a stream but MediaStreamDispatcher
- // has not yet responded and we need to cancel the request.
+ // the MediaStreamDispatcherHost to generate a stream but
+ // MediaStreamDispatcherHost has not yet responded and we need to cancel the
+ // request.
if (current_request_info_->state() == RequestInfo::State::GENERATED) {
DCHECK(current_request_info_->HasPendingSources());
LogUserMediaRequestWithNoResult(
@@ -1114,8 +1134,8 @@ void UserMediaProcessor::StopAllProcessing() {
DCHECK(!current_request_info_->HasPendingSources());
if (current_request_info_->state() ==
RequestInfo::State::SENT_FOR_GENERATION) {
- media_stream_dispatcher_->CancelGenerateStream(
- current_request_info_->request_id(), weak_factory_.GetWeakPtr());
+ GetMediaStreamDispatcherHost()->CancelRequest(
+ render_frame_id_, current_request_info_->request_id());
}
LogUserMediaRequestWithNoResult(MEDIA_STREAM_REQUEST_NOT_GENERATED);
}
@@ -1141,7 +1161,9 @@ void UserMediaProcessor::OnLocalSourceStopped(
MediaStreamSource* source_impl =
static_cast<MediaStreamSource*>(source.GetExtraData());
- media_stream_dispatcher_->StopStreamDevice(source_impl->device());
+ media_stream_device_observer_->RemoveStreamDevice(source_impl->device());
+ GetMediaStreamDispatcherHost()->StopStreamDevice(render_frame_id_,
+ source_impl->device().id);
}
void UserMediaProcessor::StopLocalSource(
@@ -1153,14 +1175,25 @@ void UserMediaProcessor::StopLocalSource(
<< "{device_id = " << source_impl->device().id << "})";
if (notify_dispatcher) {
- media_stream_dispatcher_->StopStreamDevice(source_impl->device());
+ media_stream_device_observer_->RemoveStreamDevice(source_impl->device());
+ GetMediaStreamDispatcherHost()->StopStreamDevice(render_frame_id_,
+ source_impl->device().id);
}
source_impl->ResetSourceStoppedCallback();
source_impl->StopSource();
}
-const ::mojom::MediaDevicesDispatcherHostPtr&
+const mojom::MediaStreamDispatcherHostPtr&
+UserMediaProcessor::GetMediaStreamDispatcherHost() {
+ if (!dispatcher_host_) {
+ ChildThreadImpl::current()->GetConnector()->BindInterface(
+ mojom::kBrowserServiceName, &dispatcher_host_);
+ }
+ return dispatcher_host_;
+}
+
+const blink::mojom::MediaDevicesDispatcherHostPtr&
UserMediaProcessor::GetMediaDevicesDispatcher() {
return media_devices_dispatcher_cb_.Run();
}
diff --git a/chromium/content/renderer/media/user_media_processor.h b/chromium/content/renderer/media/user_media_processor.h
index ea403dda90d..e43b4a211cc 100644
--- a/chromium/content/renderer/media/user_media_processor.h
+++ b/chromium/content/renderer/media/user_media_processor.h
@@ -15,10 +15,11 @@
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "content/common/content_export.h"
-#include "content/common/media/media_devices.mojom.h"
+#include "content/common/media/media_stream.mojom.h"
#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
#include "content/renderer/media/media_stream_source.h"
#include "third_party/WebKit/public/platform/WebVector.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
#include "third_party/WebKit/public/web/WebUserMediaRequest.h"
namespace base {
@@ -36,7 +37,7 @@ namespace content {
class AudioCaptureSettings;
class MediaStreamAudioSource;
-class MediaStreamDispatcher;
+class MediaStreamDeviceObserver;
class MediaStreamVideoSource;
class PeerConnectionDependencyFactory;
class VideoCaptureSettings;
@@ -63,13 +64,13 @@ struct UserMediaRequest {
class CONTENT_EXPORT UserMediaProcessor
: public MediaStreamDispatcherEventHandler {
public:
- using MediaDevicesDispatcherCallback =
- base::RepeatingCallback<const ::mojom::MediaDevicesDispatcherHostPtr&()>;
+ using MediaDevicesDispatcherCallback = base::RepeatingCallback<
+ const blink::mojom::MediaDevicesDispatcherHostPtr&()>;
// |render_frame| and |dependency_factory| must outlive this instance.
UserMediaProcessor(
RenderFrame* render_frame,
PeerConnectionDependencyFactory* dependency_factory,
- std::unique_ptr<MediaStreamDispatcher> media_stream_dispatcher,
+ std::unique_ptr<MediaStreamDeviceObserver> media_stream_device_observer,
MediaDevicesDispatcherCallback media_devices_dispatcher_cb,
const scoped_refptr<base::TaskRunner>& worker_task_runner);
~UserMediaProcessor() override;
@@ -100,23 +101,17 @@ class CONTENT_EXPORT UserMediaProcessor
// those sources.
void StopAllProcessing();
- MediaStreamDispatcher* media_stream_dispatcher() const {
- return media_stream_dispatcher_.get();
+ MediaStreamDeviceObserver* media_stream_device_observer() const {
+ return media_stream_device_observer_.get();
}
// MediaStreamDispatcherEventHandler implementation.
- void OnStreamGenerated(int request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) override;
- void OnStreamGenerationFailed(int request_id,
- MediaStreamRequestResult result) override;
- void OnDeviceStopped(const std::string& label,
- const MediaStreamDevice& device) override;
- void OnDeviceOpened(int request_id,
- const std::string& label,
- const MediaStreamDevice& device) override;
- void OnDeviceOpenFailed(int request_id) override;
+ void OnDeviceStopped(const MediaStreamDevice& device) override;
+
+ void set_media_stream_dispatcher_host_for_testing(
+ mojom::MediaStreamDispatcherHostPtr dispatcher_host) {
+ dispatcher_host_ = std::move(dispatcher_host);
+ }
protected:
// These methods are virtual for test purposes. A test can override them to
@@ -125,8 +120,9 @@ class CONTENT_EXPORT UserMediaProcessor
virtual void GetUserMediaRequestSucceeded(
const blink::WebMediaStream& stream,
blink::WebUserMediaRequest web_request);
- virtual void GetUserMediaRequestFailed(MediaStreamRequestResult result,
- const blink::WebString& result_name);
+ virtual void GetUserMediaRequestFailed(
+ MediaStreamRequestResult result,
+ const blink::WebString& constraint_name = blink::WebString());
// Creates a MediaStreamAudioSource/MediaStreamVideoSource objects.
// These are virtual for test purposes.
@@ -150,21 +146,30 @@ class CONTENT_EXPORT UserMediaProcessor
class RequestInfo;
typedef std::vector<blink::WebMediaStreamSource> LocalStreamSources;
+ void OnStreamGenerated(int request_id,
+ MediaStreamRequestResult result,
+ const std::string& label,
+ const MediaStreamDevices& audio_devices,
+ const MediaStreamDevices& video_devices);
+ void OnStreamGenerationFailed(int request_id,
+ MediaStreamRequestResult result);
+
bool IsCurrentRequestInfo(int request_id) const;
bool IsCurrentRequestInfo(
const blink::WebUserMediaRequest& web_request) const;
void DelayedGetUserMediaRequestSucceeded(
const blink::WebMediaStream& stream,
blink::WebUserMediaRequest web_request);
- void DelayedGetUserMediaRequestFailed(blink::WebUserMediaRequest web_request,
- MediaStreamRequestResult result,
- const blink::WebString& result_name);
+ void DelayedGetUserMediaRequestFailed(
+ blink::WebUserMediaRequest web_request,
+ MediaStreamRequestResult result,
+ const blink::WebString& constraint_name);
// Called when |source| has been stopped from JavaScript.
void OnLocalSourceStopped(const blink::WebMediaStreamSource& source);
// Creates a WebKit representation of stream sources based on
- // |devices| from the MediaStreamDispatcher.
+ // |devices| from the MediaStreamDispatcherHost.
blink::WebMediaStreamSource InitializeVideoSourceObject(
const MediaStreamDevice& device);
@@ -237,17 +242,20 @@ class CONTENT_EXPORT UserMediaProcessor
void StopLocalSource(const blink::WebMediaStreamSource& source,
bool notify_dispatcher);
- const ::mojom::MediaDevicesDispatcherHostPtr& GetMediaDevicesDispatcher();
+ const mojom::MediaStreamDispatcherHostPtr& GetMediaStreamDispatcherHost();
+ const blink::mojom::MediaDevicesDispatcherHostPtr&
+ GetMediaDevicesDispatcher();
void SetupAudioInput();
- void SelectAudioSettings(const blink::WebUserMediaRequest& web_request,
- std::vector<::mojom::AudioInputDeviceCapabilitiesPtr>
- audio_input_capabilities);
+ void SelectAudioSettings(
+ const blink::WebUserMediaRequest& web_request,
+ std::vector<blink::mojom::AudioInputDeviceCapabilitiesPtr>
+ audio_input_capabilities);
void SetupVideoInput();
void SelectVideoDeviceSettings(
const blink::WebUserMediaRequest& web_request,
- std::vector<::mojom::VideoInputDeviceCapabilitiesPtr>
+ std::vector<blink::mojom::VideoInputDeviceCapabilitiesPtr>
video_input_capabilities);
void FinalizeSelectVideoDeviceSettings(
const blink::WebUserMediaRequest& web_request,
@@ -264,13 +272,17 @@ class CONTENT_EXPORT UserMediaProcessor
// audio.
PeerConnectionDependencyFactory* const dependency_factory_;
- // UserMediaProcessor owns MediaStreamDispatcher instead of RenderFrameImpl
- // (or RenderFrameObserver) to ensure tear-down occurs in the right order.
- const std::unique_ptr<MediaStreamDispatcher> media_stream_dispatcher_;
+ // UserMediaProcessor owns MediaStreamDeviceObserver instead of
+ // RenderFrameImpl (or RenderFrameObserver) to ensure tear-down occurs in the
+ // right order.
+ const std::unique_ptr<MediaStreamDeviceObserver>
+ media_stream_device_observer_;
LocalStreamSources local_sources_;
LocalStreamSources pending_local_sources_;
+ mojom::MediaStreamDispatcherHostPtr dispatcher_host_;
+
// UserMedia requests are processed sequentially. |current_request_info_|
// contains the request currently being processed, if any, and
// |pending_request_infos_| is a list of queued requests.
@@ -280,7 +292,7 @@ class CONTENT_EXPORT UserMediaProcessor
const scoped_refptr<base::TaskRunner> worker_task_runner_;
- RenderFrame* const render_frame_;
+ const int render_frame_id_;
SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chromium/content/renderer/media/video_capture_impl_manager_unittest.cc b/chromium/content/renderer/media/video_capture_impl_manager_unittest.cc
index f9b48d723f4..58765ea019d 100644
--- a/chromium/content/renderer/media/video_capture_impl_manager_unittest.cc
+++ b/chromium/content/renderer/media/video_capture_impl_manager_unittest.cc
@@ -111,7 +111,7 @@ class MockVideoCaptureImplManager : public VideoCaptureImplManager {
private:
std::unique_ptr<VideoCaptureImpl> CreateVideoCaptureImplForTesting(
media::VideoCaptureSessionId session_id) const override {
- auto video_capture_impl = base::MakeUnique<MockVideoCaptureImpl>(
+ auto video_capture_impl = std::make_unique<MockVideoCaptureImpl>(
session_id, pause_callback_, stop_capture_callback_);
video_capture_impl->SetVideoCaptureHostForTesting(video_capture_impl.get());
return std::move(video_capture_impl);
diff --git a/chromium/content/renderer/media/video_track_adapter.cc b/chromium/content/renderer/media/video_track_adapter.cc
index 95916141044..7aad8d6ea18 100644
--- a/chromium/content/renderer/media/video_track_adapter.cc
+++ b/chromium/content/renderer/media/video_track_adapter.cc
@@ -208,7 +208,7 @@ VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveAndGetCallback(
// Make sure the VideoCaptureDeliverFrameCB is released on the main
// render thread since it was added on the main render thread in
// VideoTrackAdapter::AddTrack.
- ret = base::MakeUnique<VideoCaptureDeliverFrameCB>(it->second);
+ ret = std::make_unique<VideoCaptureDeliverFrameCB>(it->second);
callbacks_.erase(it);
break;
}
diff --git a/chromium/content/renderer/media/video_track_to_pepper_adapter.cc b/chromium/content/renderer/media/video_track_to_pepper_adapter.cc
index e1b33fef706..92aafa28937 100644
--- a/chromium/content/renderer/media/video_track_to_pepper_adapter.cc
+++ b/chromium/content/renderer/media/video_track_to_pepper_adapter.cc
@@ -28,10 +28,7 @@ namespace content {
class PpFrameReceiver : public MediaStreamVideoSink {
public:
PpFrameReceiver(blink::WebMediaStreamTrack track)
- : track_(track),
- reader_(NULL),
- weak_factory_(this) {
- }
+ : track_(track), reader_(nullptr), weak_factory_(this) {}
~PpFrameReceiver() override {}
@@ -137,7 +134,7 @@ VideoTrackToPepperAdapter::SourceInfo::SourceInfo(
}
VideoTrackToPepperAdapter::SourceInfo::~SourceInfo() {
- receiver_->SetReader(NULL);
+ receiver_->SetReader(nullptr);
}
} // namespace content
diff --git a/chromium/content/renderer/media/video_track_to_pepper_adapter_unittest.cc b/chromium/content/renderer/media/video_track_to_pepper_adapter_unittest.cc
index 655cbc0cb92..c9e914b329a 100644
--- a/chromium/content/renderer/media/video_track_to_pepper_adapter_unittest.cc
+++ b/chromium/content/renderer/media/video_track_to_pepper_adapter_unittest.cc
@@ -4,7 +4,7 @@
#include <string>
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "content/child/child_process.h"
#include "content/renderer/media/mock_media_stream_registry.h"
#include "content/renderer/media/video_track_to_pepper_adapter.h"
@@ -41,11 +41,13 @@ class VideoTrackToPepperAdapterTest : public ::testing::Test,
}
protected:
- std::unique_ptr<VideoTrackToPepperAdapter> handler_;
- // A ChildProcess and a MessageLoop are both needed to fool the Tracks and
- // Sources inside |registry_| into believing they are on the right threads.
+ // 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_;
- const base::MessageLoop message_loop_;
+ std::unique_ptr<VideoTrackToPepperAdapter> handler_;
std::unique_ptr<MockMediaStreamRegistry> registry_;
};
@@ -63,7 +65,7 @@ TEST_F(VideoTrackToPepperAdapterTest, OpenClose) {
EXPECT_CALL(*this, GotFrame(captured_frame));
DeliverFrameForTesting(captured_frame);
- EXPECT_FALSE(handler_->Close(NULL));
+ EXPECT_FALSE(handler_->Close(nullptr));
EXPECT_TRUE(handler_->Close(this));
}
diff --git a/chromium/content/renderer/media/webmediaplayer_ms.cc b/chromium/content/renderer/media/webmediaplayer_ms.cc
index af6988b0c08..3f5ebc6f3e4 100644
--- a/chromium/content/renderer/media/webmediaplayer_ms.cc
+++ b/chromium/content/renderer/media/webmediaplayer_ms.cc
@@ -749,6 +749,14 @@ void WebMediaPlayerMS::OnPause() {
// TODO(perkj, magjed): See TODO in OnPlay().
}
+void WebMediaPlayerMS::OnSeekForward(double seconds) {
+ // TODO(perkj, magjed): See TODO in OnPlay().
+}
+
+void WebMediaPlayerMS::OnSeekBackward(double seconds) {
+ // TODO(perkj, magjed): See TODO in OnPlay().
+}
+
void WebMediaPlayerMS::OnVolumeMultiplierUpdate(double multiplier) {
// TODO(perkj, magjed): See TODO in OnPlay().
}
@@ -821,11 +829,11 @@ bool WebMediaPlayerMS::TexImageImpl(TexImageFunctionID functionID,
// GPU Process crashed.
if (!provider)
return false;
- return media::SkCanvasVideoRenderer::TexImage2D(
+ return media::PaintCanvasVideoRenderer::TexImage2D(
target, texture, gl, provider->ContextCapabilities(), video_frame.get(),
level, internalformat, format, type, flip_y, premultiply_alpha);
} else if (functionID == kTexSubImage2D) {
- return media::SkCanvasVideoRenderer::TexSubImage2D(
+ return media::PaintCanvasVideoRenderer::TexSubImage2D(
target, gl, video_frame.get(), level, format, type, xoffset, yoffset,
flip_y, premultiply_alpha);
}
@@ -892,7 +900,8 @@ void WebMediaPlayerMS::SetReadyState(WebMediaPlayer::ReadyState state) {
get_client()->ReadyStateChanged();
}
-media::SkCanvasVideoRenderer* WebMediaPlayerMS::GetSkCanvasVideoRenderer() {
+media::PaintCanvasVideoRenderer*
+WebMediaPlayerMS::GetPaintCanvasVideoRenderer() {
return &video_renderer_;
}
diff --git a/chromium/content/renderer/media/webmediaplayer_ms.h b/chromium/content/renderer/media/webmediaplayer_ms.h
index c1825713da6..cb3f22fd958 100644
--- a/chromium/content/renderer/media/webmediaplayer_ms.h
+++ b/chromium/content/renderer/media/webmediaplayer_ms.h
@@ -16,7 +16,7 @@
#include "content/common/content_export.h"
#include "media/blink/webmediaplayer_delegate.h"
#include "media/blink/webmediaplayer_util.h"
-#include "media/renderers/skcanvas_video_renderer.h"
+#include "media/renderers/paint_canvas_video_renderer.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
#include "third_party/WebKit/public/platform/WebMediaStream.h"
@@ -111,7 +111,7 @@ class CONTENT_EXPORT WebMediaPlayerMS
cc::PaintFlags& flags,
int already_uploaded_id,
VideoFrameUploadMetadata* out_metadata) override;
- media::SkCanvasVideoRenderer* GetSkCanvasVideoRenderer();
+ media::PaintCanvasVideoRenderer* GetPaintCanvasVideoRenderer();
void ResetCanvasCache();
// Methods to trigger resize event.
@@ -156,6 +156,8 @@ class CONTENT_EXPORT WebMediaPlayerMS
void OnIdleTimeout() override;
void OnPlay() override;
void OnPause() override;
+ void OnSeekForward(double seconds) override;
+ void OnSeekBackward(double seconds) override;
void OnVolumeMultiplierUpdate(double multiplier) override;
void OnBecamePersistentVideo(bool value) override;
@@ -231,7 +233,7 @@ class CONTENT_EXPORT WebMediaPlayerMS
// WebMediaPlayer may also receive directives (play, pause) from the delegate
// via the WebMediaPlayerDelegate::Observer interface after registration.
//
- // NOTE: HTMLMediaElement is a Blink::SuspendableObject, and will receive a
+ // NOTE: HTMLMediaElement is a Blink::PausableObject, and will receive a
// call to contextDestroyed() when Blink::Document::shutdown() is called.
// Document::shutdown() is called before the frame detaches (and before the
// frame is destroyed). RenderFrameImpl owns of |delegate_|, and is guaranteed
@@ -249,7 +251,7 @@ class CONTENT_EXPORT WebMediaPlayerMS
std::unique_ptr<cc_blink::WebLayerImpl> video_weblayer_;
scoped_refptr<MediaStreamAudioRenderer> audio_renderer_; // Weak
- media::SkCanvasVideoRenderer video_renderer_;
+ media::PaintCanvasVideoRenderer video_renderer_;
bool paused_;
media::VideoRotation video_rotation_;
diff --git a/chromium/content/renderer/media/webmediaplayer_ms_compositor.cc b/chromium/content/renderer/media/webmediaplayer_ms_compositor.cc
index 4a65bbcace8..c76a9e5dbad 100644
--- a/chromium/content/renderer/media/webmediaplayer_ms_compositor.cc
+++ b/chromium/content/renderer/media/webmediaplayer_ms_compositor.cc
@@ -19,7 +19,7 @@
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "media/filters/video_renderer_algorithm.h"
-#include "media/renderers/skcanvas_video_renderer.h"
+#include "media/renderers/paint_canvas_video_renderer.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/public/platform/WebMediaStream.h"
@@ -37,7 +37,7 @@ namespace {
// This function copies |frame| to a new I420 or YV12A media::VideoFrame.
scoped_refptr<media::VideoFrame> CopyFrame(
const scoped_refptr<media::VideoFrame>& frame,
- media::SkCanvasVideoRenderer* video_renderer) {
+ media::PaintCanvasVideoRenderer* video_renderer) {
scoped_refptr<media::VideoFrame> new_frame;
if (frame->HasTextures()) {
DCHECK(frame->format() == media::PIXEL_FORMAT_ARGB ||
@@ -462,7 +462,7 @@ void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal() {
// there might be a finite number of available buffers. E.g, video that
// originates from a video camera, HW decoded frames.
scoped_refptr<media::VideoFrame> copied_frame =
- CopyFrame(current_frame_ref, player_->GetSkCanvasVideoRenderer());
+ CopyFrame(current_frame_ref, player_->GetPaintCanvasVideoRenderer());
// Copying frame can take time, so only set the copied frame if
// |current_frame_| hasn't been changed.
{
diff --git a/chromium/content/renderer/media/webmediaplayer_ms_unittest.cc b/chromium/content/renderer/media/webmediaplayer_ms_unittest.cc
index 480d7827484..eb3f386f920 100644
--- a/chromium/content/renderer/media/webmediaplayer_ms_unittest.cc
+++ b/chromium/content/renderer/media/webmediaplayer_ms_unittest.cc
@@ -455,7 +455,7 @@ class WebMediaPlayerMSTest
nullptr,
this,
&delegate_,
- base::MakeUnique<media::MediaLog>(),
+ std::make_unique<media::MediaLog>(),
std::unique_ptr<MediaStreamRendererFactory>(render_factory_),
message_loop_.task_runner(),
message_loop_.task_runner(),
diff --git a/chromium/content/renderer/media/webrtc/audio_codec_factory.cc b/chromium/content/renderer/media/webrtc/audio_codec_factory.cc
new file mode 100644
index 00000000000..62b96aac885
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/audio_codec_factory.cc
@@ -0,0 +1,85 @@
+// Copyright 2017 The Chromium Authors. 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/webrtc/audio_codec_factory.h"
+
+#include <memory>
+#include <vector>
+
+#include "third_party/webrtc/api/audio_codecs/L16/audio_decoder_L16.h"
+#include "third_party/webrtc/api/audio_codecs/L16/audio_encoder_L16.h"
+#include "third_party/webrtc/api/audio_codecs/audio_decoder_factory_template.h"
+#include "third_party/webrtc/api/audio_codecs/audio_encoder_factory_template.h"
+#include "third_party/webrtc/api/audio_codecs/g711/audio_decoder_g711.h"
+#include "third_party/webrtc/api/audio_codecs/g711/audio_encoder_g711.h"
+#include "third_party/webrtc/api/audio_codecs/g722/audio_decoder_g722.h"
+#include "third_party/webrtc/api/audio_codecs/g722/audio_encoder_g722.h"
+#include "third_party/webrtc/api/audio_codecs/isac/audio_decoder_isac.h"
+#include "third_party/webrtc/api/audio_codecs/isac/audio_encoder_isac.h"
+#include "third_party/webrtc/api/audio_codecs/opus/audio_decoder_opus.h"
+#include "third_party/webrtc/api/audio_codecs/opus/audio_encoder_opus.h"
+
+namespace content {
+
+namespace {
+
+// Modify an audio encoder to not advertise support for anything.
+template <typename T>
+struct NotAdvertisedEncoder {
+ using Config = typename T::Config;
+ static rtc::Optional<Config> SdpToConfig(
+ const webrtc::SdpAudioFormat& audio_format) {
+ return T::SdpToConfig(audio_format);
+ }
+ static void AppendSupportedEncoders(
+ std::vector<webrtc::AudioCodecSpec>* specs) {
+ // Don't advertise support for anything.
+ }
+ static webrtc::AudioCodecInfo QueryAudioEncoder(const Config& config) {
+ return T::QueryAudioEncoder(config);
+ }
+ static std::unique_ptr<webrtc::AudioEncoder> MakeAudioEncoder(
+ const Config& config,
+ int payload_type) {
+ return T::MakeAudioEncoder(config, payload_type);
+ }
+};
+
+// Modify an audio decoder to not advertise support for anything.
+template <typename T>
+struct NotAdvertisedDecoder {
+ using Config = typename T::Config;
+ static rtc::Optional<Config> SdpToConfig(
+ const webrtc::SdpAudioFormat& audio_format) {
+ return T::SdpToConfig(audio_format);
+ }
+ static void AppendSupportedDecoders(
+ std::vector<webrtc::AudioCodecSpec>* specs) {
+ // Don't advertise support for anything.
+ }
+ static std::unique_ptr<webrtc::AudioDecoder> MakeAudioDecoder(
+ const Config& config) {
+ return T::MakeAudioDecoder(config);
+ }
+};
+
+} // namespace
+
+rtc::scoped_refptr<webrtc::AudioEncoderFactory>
+CreateWebrtcAudioEncoderFactory() {
+ return webrtc::CreateAudioEncoderFactory<
+ webrtc::AudioEncoderOpus, webrtc::AudioEncoderIsac,
+ webrtc::AudioEncoderG722, webrtc::AudioEncoderG711,
+ NotAdvertisedEncoder<webrtc::AudioEncoderL16>>();
+}
+
+rtc::scoped_refptr<webrtc::AudioDecoderFactory>
+CreateWebrtcAudioDecoderFactory() {
+ return webrtc::CreateAudioDecoderFactory<
+ webrtc::AudioDecoderOpus, webrtc::AudioDecoderIsac,
+ webrtc::AudioDecoderG722, webrtc::AudioDecoderG711,
+ NotAdvertisedDecoder<webrtc::AudioDecoderL16>>();
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/audio_codec_factory.h b/chromium/content/renderer/media/webrtc/audio_codec_factory.h
new file mode 100644
index 00000000000..057c71160ca
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/audio_codec_factory.h
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_CODEC_FACTORY_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_CODEC_FACTORY_H_
+
+#include "third_party/webrtc/api/audio_codecs/audio_decoder_factory.h"
+#include "third_party/webrtc/api/audio_codecs/audio_encoder_factory.h"
+#include "third_party/webrtc/rtc_base/scoped_ref_ptr.h"
+
+namespace content {
+
+rtc::scoped_refptr<webrtc::AudioEncoderFactory>
+CreateWebrtcAudioEncoderFactory();
+
+rtc::scoped_refptr<webrtc::AudioDecoderFactory>
+CreateWebrtcAudioDecoderFactory();
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_CODEC_FACTORY_H_
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 e0132f76893..1b2a2abae66 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
@@ -121,25 +121,39 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
->getMediaVideoFrame();
video_frame->set_timestamp(elapsed_timestamp);
} else {
- scoped_refptr<webrtc::PlanarYuvBuffer> yuv_buffer;
- media::VideoPixelFormat pixel_format;
- if (buffer->type() == webrtc::VideoFrameBuffer::Type::kI444) {
- yuv_buffer = buffer->GetI444();
- pixel_format = media::PIXEL_FORMAT_YV24;
+ const gfx::Size size(buffer->width(), buffer->height());
+ const bool has_alpha =
+ buffer->type() == webrtc::VideoFrameBuffer::Type::kI420A;
+ if (has_alpha) {
+ const webrtc::I420ABufferInterface* yuva_buffer = buffer->GetI420A();
+ video_frame = media::VideoFrame::WrapExternalYuvaData(
+ media::PIXEL_FORMAT_YV12A, size, gfx::Rect(size), size,
+ yuva_buffer->StrideY(), yuva_buffer->StrideU(),
+ yuva_buffer->StrideV(), yuva_buffer->StrideA(),
+ const_cast<uint8_t*>(yuva_buffer->DataY()),
+ const_cast<uint8_t*>(yuva_buffer->DataU()),
+ const_cast<uint8_t*>(yuva_buffer->DataV()),
+ const_cast<uint8_t*>(yuva_buffer->DataA()), elapsed_timestamp);
} else {
- yuv_buffer = buffer->ToI420();
- pixel_format = media::PIXEL_FORMAT_YV12;
+ scoped_refptr<webrtc::PlanarYuvBuffer> yuv_buffer;
+ media::VideoPixelFormat pixel_format;
+ if (buffer->type() == webrtc::VideoFrameBuffer::Type::kI444) {
+ yuv_buffer = buffer->GetI444();
+ pixel_format = media::PIXEL_FORMAT_YV24;
+ } else {
+ yuv_buffer = buffer->ToI420();
+ pixel_format = media::PIXEL_FORMAT_YV12;
+ }
+ // Make a shallow copy. Both |frame| and |video_frame| will share a single
+ // reference counted frame buffer. Const cast and hope no one will
+ // overwrite the data.
+ video_frame = media::VideoFrame::WrapExternalYuvData(
+ pixel_format, size, gfx::Rect(size), size, yuv_buffer->StrideY(),
+ yuv_buffer->StrideU(), yuv_buffer->StrideV(),
+ const_cast<uint8_t*>(yuv_buffer->DataY()),
+ const_cast<uint8_t*>(yuv_buffer->DataU()),
+ const_cast<uint8_t*>(yuv_buffer->DataV()), elapsed_timestamp);
}
- gfx::Size size(yuv_buffer->width(), yuv_buffer->height());
- // Make a shallow copy. Both |frame| and |video_frame| will share a single
- // reference counted frame buffer. Const cast and hope no one will overwrite
- // the data.
- video_frame = media::VideoFrame::WrapExternalYuvData(
- pixel_format, size, gfx::Rect(size), size, yuv_buffer->StrideY(),
- yuv_buffer->StrideU(), yuv_buffer->StrideV(),
- const_cast<uint8_t*>(yuv_buffer->DataY()),
- const_cast<uint8_t*>(yuv_buffer->DataU()),
- const_cast<uint8_t*>(yuv_buffer->DataV()), elapsed_timestamp);
if (!video_frame)
return;
// The bind ensures that we keep a reference to the underlying buffer.
diff --git a/chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc b/chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc
index a4b708c3b99..e340bd0b928 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc
@@ -279,7 +279,7 @@ void MediaStreamTrackMetrics::AddStream(StreamType type,
MediaStreamInterface* stream) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
observers_.push_back(
- base::MakeUnique<MediaStreamTrackMetricsObserver>(type, stream, this));
+ std::make_unique<MediaStreamTrackMetricsObserver>(type, stream, this));
SendLifeTimeMessageDependingOnIceState(observers_.back().get());
}
diff --git a/chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc b/chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc
index 83a2d2273d0..b93fab8bdb6 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc
@@ -99,7 +99,7 @@ class MediaStreamTrackMetricsTest : public testing::Test {
void TearDown() override {
signaling_thread_.Stop();
metrics_.reset();
- stream_ = NULL;
+ stream_ = nullptr;
}
// Adds an audio track to |stream_| on the signaling thread to simulate how
diff --git a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
index 53bcefb8ee4..4af35d74384 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
@@ -213,8 +213,8 @@ void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::
// thread, it should be released on the render thread.
base::AutoLock auto_lock(capture_adapter_stop_lock_);
// |video_source| owns |capture_adapter_|.
- capture_adapter_ = NULL;
- video_source_ = NULL;
+ capture_adapter_ = nullptr;
+ video_source_ = nullptr;
}
void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::SetContentHint(
diff --git a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
index aea2898f37b..7890480b44f 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
@@ -48,8 +48,9 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test {
private:
MockMediaStreamRegistry registry_;
- // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks
- // and Sources in |registry_| into believing they are on the right threads.
+ // A ChildProcess is needed to fool the Tracks and Sources into believing they
+ // are on the right threads. A ScopedTaskEnvironment must be instantiated
+ // before ChildProcess to prevent it from leaking a TaskScheduler.
base::test::ScopedTaskEnvironment scoped_task_environment_;
const ChildProcess child_process_;
};
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 f885ad601dd..9e7213121b6 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
@@ -89,13 +89,13 @@ VideoTrackVector MockMediaStream::GetVideoTracks() {
rtc::scoped_refptr<AudioTrackInterface> MockMediaStream::FindAudioTrack(
const std::string& track_id) {
AudioTrackVector::iterator it = FindTrack(&audio_track_vector_, track_id);
- return it == audio_track_vector_.end() ? NULL : *it;
+ 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);
- return it == video_track_vector_.end() ? NULL : *it;
+ return it == video_track_vector_.end() ? nullptr : *it;
}
void MockMediaStream::RegisterObserver(ObserverInterface* observer) {
@@ -180,7 +180,7 @@ MockWebRtcVideoTrack::MockWebRtcVideoTrack(
source_(source),
enabled_(true),
state_(webrtc::MediaStreamTrackInterface::kLive),
- sink_(NULL) {}
+ sink_(nullptr) {}
MockWebRtcVideoTrack::~MockWebRtcVideoTrack() {}
@@ -199,7 +199,7 @@ void MockWebRtcVideoTrack::AddOrUpdateSink(
void MockWebRtcVideoTrack::RemoveSink(
rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) {
DCHECK(sink_ == sink);
- sink_ = NULL;
+ sink_ = nullptr;
}
VideoTrackSourceInterface* MockWebRtcVideoTrack::GetSource() const {
@@ -250,11 +250,11 @@ class MockSessionDescription : public SessionDescriptionInterface {
~MockSessionDescription() override {}
cricket::SessionDescription* description() override {
NOTIMPLEMENTED();
- return NULL;
+ return nullptr;
}
const cricket::SessionDescription* description() const override {
NOTIMPLEMENTED();
- return NULL;
+ return nullptr;
}
std::string session_id() const override {
NOTIMPLEMENTED();
@@ -276,7 +276,7 @@ class MockSessionDescription : public SessionDescriptionInterface {
const IceCandidateCollection* candidates(
size_t mediasection_index) const override {
NOTIMPLEMENTED();
- return NULL;
+ return nullptr;
}
bool ToString(std::string* out) const override {
@@ -317,7 +317,7 @@ class MockIceCandidate : public IceCandidateInterface {
};
MockPeerConnectionDependencyFactory::MockPeerConnectionDependencyFactory()
- : PeerConnectionDependencyFactory(NULL),
+ : PeerConnectionDependencyFactory(nullptr),
signaling_thread_("MockPCFactory WebRtc Signaling Thread") {
EnsureWebRtcAudioDeviceImpl();
CHECK(signaling_thread_.Start());
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 9d05ac07166..d8e343cbadf 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -36,6 +36,7 @@
#include "content/renderer/media/media_stream_video_source.h"
#include "content/renderer/media/media_stream_video_track.h"
#include "content/renderer/media/rtc_peer_connection_handler.h"
+#include "content/renderer/media/webrtc/audio_codec_factory.h"
#include "content/renderer/media/webrtc/stun_field_trial.h"
#include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
@@ -61,11 +62,13 @@
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"
-#include "third_party/webrtc/api/audio_codecs/builtin_audio_encoder_factory.h"
#include "third_party/webrtc/api/mediaconstraintsinterface.h"
+#include "third_party/webrtc/api/video_codecs/video_decoder_factory.h"
+#include "third_party/webrtc/api/video_codecs/video_encoder_factory.h"
#include "third_party/webrtc/api/videosourceproxy.h"
+#include "third_party/webrtc/media/engine/convert_legacy_video_factory.h"
#include "third_party/webrtc/modules/video_coding/codecs/h264/include/h264.h"
+#include "third_party/webrtc/rtc_base/refcountedobject.h"
#include "third_party/webrtc/rtc_base/ssladapter.h"
#if defined(OS_ANDROID)
@@ -103,10 +106,10 @@ bool IsValidPortRange(uint16_t min_port, uint16_t max_port) {
PeerConnectionDependencyFactory::PeerConnectionDependencyFactory(
P2PSocketDispatcher* p2p_socket_dispatcher)
- : network_manager_(NULL),
+ : network_manager_(nullptr),
p2p_socket_dispatcher_(p2p_socket_dispatcher),
- signaling_thread_(NULL),
- worker_thread_(NULL),
+ signaling_thread_(nullptr),
+ worker_thread_(nullptr),
chrome_signaling_thread_("Chrome_libJingle_Signaling"),
chrome_worker_thread_("Chrome_libJingle_WorkerThread") {
TryScheduleStunProbeTrial();
@@ -126,7 +129,7 @@ PeerConnectionDependencyFactory::CreateRTCPeerConnectionHandler(
// webKitRTCPeerConnection.
UpdateWebRTCMethodCount(WEBKIT_RTC_PEER_CONNECTION);
- return base::MakeUnique<RTCPeerConnectionHandler>(client, this);
+ return std::make_unique<RTCPeerConnectionHandler>(client, this);
}
const scoped_refptr<webrtc::PeerConnectionFactoryInterface>&
@@ -253,11 +256,17 @@ void PeerConnectionDependencyFactory::InitializeSignalingThread(
encoder_factory.reset();
#endif
+ // TODO(magjed): Update RTCVideoEncoderFactory/RTCVideoDecoderFactory to new
+ // interface and let Chromium be responsible in what order video codecs are
+ // listed, instead of using
+ // cricket::ConvertVideoEncoderFactory/cricket::ConvertVideoDecoderFactory.
pc_factory_ = webrtc::CreatePeerConnectionFactory(
- worker_thread_, signaling_thread_, audio_device_.get(),
- webrtc::CreateBuiltinAudioEncoderFactory(),
- webrtc::CreateBuiltinAudioDecoderFactory(), encoder_factory.release(),
- decoder_factory.release());
+ worker_thread_ /* network thread */, worker_thread_, signaling_thread_,
+ audio_device_.get(), CreateWebrtcAudioEncoderFactory(),
+ CreateWebrtcAudioDecoderFactory(),
+ cricket::ConvertVideoEncoderFactory(std::move(encoder_factory)),
+ cricket::ConvertVideoDecoderFactory(std::move(decoder_factory)),
+ nullptr /* audio_mixer */, nullptr /* audio_processing */);
CHECK(pc_factory_.get());
webrtc::PeerConnectionFactoryInterface::Options factory_options;
@@ -274,7 +283,7 @@ void PeerConnectionDependencyFactory::InitializeSignalingThread(
}
bool PeerConnectionDependencyFactory::PeerConnectionFactoryCreated() {
- return pc_factory_.get() != NULL;
+ return pc_factory_.get() != nullptr;
}
scoped_refptr<webrtc::PeerConnectionInterface>
@@ -285,7 +294,7 @@ PeerConnectionDependencyFactory::CreatePeerConnection(
CHECK(web_frame);
CHECK(observer);
if (!GetPcFactory().get())
- return NULL;
+ return nullptr;
// Copy the flag from Preference associated with this WebLocalFrame.
P2PPortAllocator::Config port_config;
@@ -514,12 +523,12 @@ void PeerConnectionDependencyFactory::CreateIpcNetworkManagerOnWorkerThread(
void PeerConnectionDependencyFactory::DeleteIpcNetworkManager() {
DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread());
delete network_manager_;
- network_manager_ = NULL;
+ network_manager_ = nullptr;
}
void PeerConnectionDependencyFactory::CleanupPeerConnectionFactory() {
DVLOG(1) << "PeerConnectionDependencyFactory::CleanupPeerConnectionFactory()";
- pc_factory_ = NULL;
+ pc_factory_ = nullptr;
if (network_manager_) {
// The network manager needs to free its resources on the thread they were
// created, which is the worked thread.
@@ -564,7 +573,7 @@ void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() {
if (audio_device_.get())
return;
- audio_device_ = new WebRtcAudioDeviceImpl();
+ audio_device_ = new rtc::RefCountedObject<WebRtcAudioDeviceImpl>();
}
} // namespace content
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 1747aecf857..fa23cf1ab6f 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
@@ -25,7 +25,7 @@ TEST_F(PeerConnectionDependencyFactoryTest, CreateRTCPeerConnectionHandler) {
MockWebRTCPeerConnectionHandlerClient client_jsep;
std::unique_ptr<blink::WebRTCPeerConnectionHandler> pc_handler(
dependency_factory_->CreateRTCPeerConnectionHandler(&client_jsep));
- EXPECT_TRUE(pc_handler.get() != NULL);
+ EXPECT_TRUE(pc_handler.get() != nullptr);
}
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/processed_local_audio_source.cc b/chromium/content/renderer/media/webrtc/processed_local_audio_source.cc
index 4ae867fe977..f6e0842faa6 100644
--- a/chromium/content/renderer/media/webrtc/processed_local_audio_source.cc
+++ b/chromium/content/renderer/media/webrtc/processed_local_audio_source.cc
@@ -92,16 +92,31 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() {
device().session_id, device().matched_output.sample_rate(),
device().matched_output.frames_per_buffer(), device().input.effects()));
+ MediaStreamDevice modified_device(device());
+ bool device_is_modified = false;
+
// Disable HW echo cancellation if constraints explicitly specified no
// echo cancellation.
if (audio_processing_properties_.disable_hw_echo_cancellation &&
(device().input.effects() & media::AudioParameters::ECHO_CANCELLER)) {
- MediaStreamDevice modified_device(device());
modified_device.input.set_effects(modified_device.input.effects() &
~media::AudioParameters::ECHO_CANCELLER);
- SetDevice(modified_device);
+ device_is_modified = true;
+ }
+
+ // Disable noise suppression on the device if the properties explicitly
+ // specify to do so.
+ if (audio_processing_properties_.disable_hw_noise_suppression &&
+ (device().input.effects() & media::AudioParameters::NOISE_SUPPRESSION)) {
+ modified_device.input.set_effects(
+ modified_device.input.effects() &
+ ~media::AudioParameters::NOISE_SUPPRESSION);
+ device_is_modified = true;
}
+ if (device_is_modified)
+ SetDevice(modified_device);
+
// Create the MediaStreamAudioProcessor, bound to the WebRTC audio device
// module.
WebRtcAudioDeviceImpl* const rtc_audio_device =
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc
index 18dafc4d3d7..5a5f854731d 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc
@@ -17,40 +17,86 @@ uintptr_t RTCRtpReceiver::getId(
}
RTCRtpReceiver::RTCRtpReceiver(
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_rtp_receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter)
- : webrtc_rtp_receiver_(std::move(webrtc_rtp_receiver)),
- track_adapter_(std::move(track_adapter)) {
- DCHECK(webrtc_rtp_receiver_);
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter,
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ stream_adapter_refs)
+ : webrtc_receiver_(std::move(webrtc_receiver)),
+ track_adapter_(std::move(track_adapter)),
+ stream_adapter_refs_(std::move(stream_adapter_refs)) {
+ DCHECK(webrtc_receiver_);
DCHECK(track_adapter_);
}
RTCRtpReceiver::~RTCRtpReceiver() {}
+std::unique_ptr<RTCRtpReceiver> RTCRtpReceiver::ShallowCopy() const {
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ stream_adapter_ref_copies(stream_adapter_refs_.size());
+ for (size_t i = 0; i < stream_adapter_refs_.size(); ++i) {
+ stream_adapter_ref_copies[i] = stream_adapter_refs_[i]->Copy();
+ }
+ return std::make_unique<RTCRtpReceiver>(webrtc_receiver_,
+ track_adapter_->Copy(),
+ std::move(stream_adapter_ref_copies));
+}
+
uintptr_t RTCRtpReceiver::Id() const {
- return getId(webrtc_rtp_receiver_.get());
+ return getId(webrtc_receiver_.get());
}
const blink::WebMediaStreamTrack& RTCRtpReceiver::Track() const {
- DCHECK(track_adapter_->webrtc_track() == webrtc_rtp_receiver_->track());
+ DCHECK(track_adapter_->webrtc_track() == webrtc_receiver_->track());
return track_adapter_->web_track();
}
+blink::WebVector<blink::WebMediaStream> RTCRtpReceiver::Streams() const {
+ blink::WebVector<blink::WebMediaStream> web_streams(
+ stream_adapter_refs_.size());
+ for (size_t i = 0; i < stream_adapter_refs_.size(); ++i)
+ web_streams[i] = stream_adapter_refs_[i]->adapter().web_stream();
+ return web_streams;
+}
+
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
RTCRtpReceiver::GetSources() {
- auto webrtc_sources = webrtc_rtp_receiver_->GetSources();
+ auto webrtc_sources = webrtc_receiver_->GetSources();
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>> sources(
webrtc_sources.size());
for (size_t i = 0; i < webrtc_sources.size(); ++i) {
- sources[i] = base::MakeUnique<RTCRtpContributingSource>(webrtc_sources[i]);
+ sources[i] = std::make_unique<RTCRtpContributingSource>(webrtc_sources[i]);
}
return sources;
}
+webrtc::RtpReceiverInterface* RTCRtpReceiver::webrtc_receiver() const {
+ return webrtc_receiver_.get();
+}
+
const webrtc::MediaStreamTrackInterface& RTCRtpReceiver::webrtc_track() const {
- DCHECK(track_adapter_->webrtc_track() == webrtc_rtp_receiver_->track());
+ DCHECK(track_adapter_->webrtc_track() == webrtc_receiver_->track());
DCHECK(track_adapter_->webrtc_track());
return *track_adapter_->webrtc_track();
}
+bool RTCRtpReceiver::HasStream(
+ const webrtc::MediaStreamInterface* webrtc_stream) const {
+ for (const auto& stream_adapter : stream_adapter_refs_) {
+ if (webrtc_stream == stream_adapter->adapter().webrtc_stream().get())
+ return true;
+ }
+ return false;
+}
+
+std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+RTCRtpReceiver::StreamAdapterRefs() const {
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ stream_adapter_copies;
+ stream_adapter_copies.reserve(stream_adapter_refs_.size());
+ for (const auto& stream_adapter : stream_adapter_refs_) {
+ stream_adapter_copies.push_back(stream_adapter->Copy());
+ }
+ return stream_adapter_copies;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h
index 39dc2f7b5f7..e9daa24dbb7 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h
@@ -8,9 +8,12 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/WebKit/public/platform/WebMediaStream.h"
#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
#include "third_party/WebKit/public/platform/WebRTCRtpReceiver.h"
+#include "third_party/webrtc/api/mediastreaminterface.h"
#include "third_party/webrtc/api/rtpreceiverinterface.h"
namespace content {
@@ -24,24 +27,40 @@ class CONTENT_EXPORT RTCRtpReceiver : public blink::WebRTCRtpReceiver {
const webrtc::RtpReceiverInterface* webrtc_rtp_receiver);
RTCRtpReceiver(
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_rtp_receiver,
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- track_adapter);
+ track_adapter,
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ stream_adapter_refs);
~RTCRtpReceiver() override;
+ // Creates a shallow copy of the receiver, representing the same underlying
+ // webrtc receiver as the original.
+ std::unique_ptr<RTCRtpReceiver> ShallowCopy() const;
+
uintptr_t Id() const override;
const blink::WebMediaStreamTrack& Track() const override;
+ blink::WebVector<blink::WebMediaStream> Streams() const override;
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
GetSources() override;
+ webrtc::RtpReceiverInterface* webrtc_receiver() const;
const webrtc::MediaStreamTrackInterface& webrtc_track() const;
+ bool HasStream(const webrtc::MediaStreamInterface* webrtc_stream) const;
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ StreamAdapterRefs() const;
private:
- const rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_rtp_receiver_;
+ const rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_;
+
// The track adapter is the glue between blink and webrtc layer tracks.
// Keeping a reference to the adapter ensures it is not disposed, as is
// required as long as the webrtc layer track is in use by the receiver.
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter_;
+ // Similarly, references needs to be kept to the stream adapters of streams
+ // associated with the receiver.
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ stream_adapter_refs_;
DISALLOW_COPY_AND_ASSIGN(RTCRtpReceiver);
};
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
index 21f59685509..08c7498443a 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
@@ -60,7 +60,7 @@ std::unique_ptr<RTCRtpSender> RTCRtpSender::ShallowCopy() const {
for (size_t i = 0; i < stream_adapters_.size(); ++i) {
stream_adapter_copies[i] = stream_adapters_[i]->Copy();
}
- return base::MakeUnique<RTCRtpSender>(webrtc_rtp_sender_,
+ return std::make_unique<RTCRtpSender>(webrtc_rtp_sender_,
track_adapter_->Copy(),
std::move(stream_adapter_copies));
}
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc
index 90038f381da..32040d6f18b 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc
@@ -24,7 +24,7 @@ WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
PeerConnectionDependencyFactory* factory,
scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
const blink::WebMediaStream& web_stream) {
- return base::MakeUnique<LocalWebRtcMediaStreamAdapter>(
+ return std::make_unique<LocalWebRtcMediaStreamAdapter>(
factory, std::move(track_adapter_map), web_stream);
}
@@ -34,7 +34,7 @@ WebRtcMediaStreamAdapter::CreateRemoteStreamAdapter(
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream) {
- return base::MakeUnique<RemoteWebRtcMediaStreamAdapter>(
+ return std::make_unique<RemoteWebRtcMediaStreamAdapter>(
std::move(main_thread), std::move(track_adapter_map),
std::move(webrtc_stream));
}
@@ -108,6 +108,11 @@ const blink::WebMediaStream& LocalWebRtcMediaStreamAdapter::web_stream() const {
return web_stream_;
}
+void LocalWebRtcMediaStreamAdapter::SetTracks(
+ WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs) {
+ NOTIMPLEMENTED() << "Not supported for local stream adapters.";
+}
+
void LocalWebRtcMediaStreamAdapter::TrackAdded(
const blink::WebMediaStreamTrack& web_track) {
DCHECK(adapter_refs_.find(web_track.UniqueId()) == adapter_refs_.end());
@@ -148,100 +153,33 @@ void LocalWebRtcMediaStreamAdapter::TrackRemoved(
adapter_refs_.erase(it);
}
-class RemoteWebRtcMediaStreamAdapter::WebRtcStreamObserver
- : public webrtc::ObserverInterface,
- public base::RefCountedThreadSafe<WebRtcStreamObserver> {
- public:
- WebRtcStreamObserver(
- base::WeakPtr<RemoteWebRtcMediaStreamAdapter> adapter,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream)
- : adapter_(adapter),
- main_thread_(std::move(main_thread)),
- track_adapter_map_(std::move(track_adapter_map)),
- webrtc_stream_(std::move(webrtc_stream)) {
- webrtc_stream_->RegisterObserver(this);
- }
-
- const scoped_refptr<base::SingleThreadTaskRunner>& main_thread() const {
- return main_thread_;
- }
-
- const scoped_refptr<webrtc::MediaStreamInterface>& webrtc_stream() const {
- return webrtc_stream_;
- }
-
- void InitializeOnMainThread(const std::string& label,
- RemoteAdapterRefMap adapter_refs,
- size_t audio_track_count,
- size_t video_track_count) {
- DCHECK(main_thread_->BelongsToCurrentThread());
- if (adapter_) {
- adapter_->InitializeOnMainThread(label, std::move(adapter_refs),
- audio_track_count, video_track_count);
- }
- }
-
- // Uninitializes the observer, unregisters from receiving notifications and
- // releases the webrtc stream. Must be called from the main thread before
- // releasing the main reference.
- void Unregister() {
- DCHECK(main_thread_->BelongsToCurrentThread());
- webrtc_stream_->UnregisterObserver(this);
- // Since we're guaranteed to not get further notifications, it's safe to
- // release the webrtc_stream_ here.
- webrtc_stream_ = nullptr;
- }
-
- private:
- friend class base::RefCountedThreadSafe<WebRtcStreamObserver>;
-
- ~WebRtcStreamObserver() override {
- DCHECK(!webrtc_stream_.get()) << "Unregister hasn't been called";
- }
-
- // |webrtc::ObserverInterface| implementation.
- void OnChanged() override {
- RemoteAdapterRefMap new_adapter_refs =
- RemoteWebRtcMediaStreamAdapter::GetRemoteAdapterRefMapFromWebRtcStream(
- track_adapter_map_, webrtc_stream_.get());
- main_thread_->PostTask(
- FROM_HERE, base::BindOnce(&WebRtcStreamObserver::OnChangedOnMainThread,
- this, base::Passed(&new_adapter_refs)));
- }
-
- void OnChangedOnMainThread(RemoteAdapterRefMap new_adapter_refs) {
- DCHECK(main_thread_->BelongsToCurrentThread());
- if (adapter_)
- adapter_->OnChanged(std::move(new_adapter_refs));
+// static
+bool RemoteWebRtcMediaStreamAdapter::RemoteAdapterRefsContainsTrack(
+ const RemoteAdapterRefs& adapter_refs,
+ webrtc::MediaStreamTrackInterface* webrtc_track) {
+ for (const auto& adapter_ref : adapter_refs) {
+ if (adapter_ref->webrtc_track() == webrtc_track)
+ return true;
}
-
- base::WeakPtr<RemoteWebRtcMediaStreamAdapter> adapter_;
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- const scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream_;
-};
+ return false;
+}
// static
-RemoteWebRtcMediaStreamAdapter::RemoteAdapterRefMap
-RemoteWebRtcMediaStreamAdapter::GetRemoteAdapterRefMapFromWebRtcStream(
+RemoteWebRtcMediaStreamAdapter::RemoteAdapterRefs
+RemoteWebRtcMediaStreamAdapter::GetRemoteAdapterRefsFromWebRtcStream(
const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
webrtc::MediaStreamInterface* webrtc_stream) {
- RemoteAdapterRefMap adapter_refs;
+ // TODO(hbos): When adapter's |webrtc_track| can be called from any thread so
+ // can RemoteAdapterRefsContainsTrack and we can DCHECK here that we don't end
+ // up with duplicate entries. https://crbug.com/756436
+ RemoteAdapterRefs adapter_refs;
for (auto& webrtc_audio_track : webrtc_stream->GetAudioTracks()) {
- DCHECK(adapter_refs.find(webrtc_audio_track.get()) == adapter_refs.end());
- adapter_refs.insert(
- std::make_pair(webrtc_audio_track.get(),
- track_adapter_map->GetOrCreateRemoteTrackAdapter(
- webrtc_audio_track.get())));
+ adapter_refs.push_back(track_adapter_map->GetOrCreateRemoteTrackAdapter(
+ webrtc_audio_track.get()));
}
for (auto& webrtc_video_track : webrtc_stream->GetVideoTracks()) {
- DCHECK(adapter_refs.find(webrtc_video_track.get()) == adapter_refs.end());
- adapter_refs.insert(
- std::make_pair(webrtc_video_track.get(),
- track_adapter_map->GetOrCreateRemoteTrackAdapter(
- webrtc_video_track.get())));
+ adapter_refs.push_back(track_adapter_map->GetOrCreateRemoteTrackAdapter(
+ webrtc_video_track.get()));
}
return adapter_refs;
}
@@ -259,17 +197,13 @@ RemoteWebRtcMediaStreamAdapter::RemoteWebRtcMediaStreamAdapter(
weak_factory_(this) {
DCHECK(!main_thread_->BelongsToCurrentThread());
DCHECK(track_adapter_map_);
- observer_ = new RemoteWebRtcMediaStreamAdapter::WebRtcStreamObserver(
- weak_factory_.GetWeakPtr(), main_thread_, track_adapter_map_,
- webrtc_stream_);
- RemoteAdapterRefMap adapter_refs = GetRemoteAdapterRefMapFromWebRtcStream(
+ RemoteAdapterRefs adapter_refs = GetRemoteAdapterRefsFromWebRtcStream(
track_adapter_map_, webrtc_stream_.get());
main_thread_->PostTask(
FROM_HERE,
- base::BindOnce(&RemoteWebRtcMediaStreamAdapter::WebRtcStreamObserver::
- InitializeOnMainThread,
- observer_, webrtc_stream_->label(),
+ base::BindOnce(&RemoteWebRtcMediaStreamAdapter::InitializeOnMainThread,
+ weak_factory_.GetWeakPtr(), webrtc_stream_->label(),
base::Passed(&adapter_refs),
webrtc_stream_->GetAudioTracks().size(),
webrtc_stream_->GetVideoTracks().size()));
@@ -277,8 +211,7 @@ RemoteWebRtcMediaStreamAdapter::RemoteWebRtcMediaStreamAdapter(
RemoteWebRtcMediaStreamAdapter::~RemoteWebRtcMediaStreamAdapter() {
DCHECK(main_thread_->BelongsToCurrentThread());
- observer_->Unregister();
- OnChanged(RemoteAdapterRefMap());
+ SetTracks(RemoteAdapterRefs());
}
bool RemoteWebRtcMediaStreamAdapter::is_initialized() const {
@@ -302,7 +235,7 @@ const blink::WebMediaStream& RemoteWebRtcMediaStreamAdapter::web_stream()
void RemoteWebRtcMediaStreamAdapter::InitializeOnMainThread(
const std::string& label,
- RemoteAdapterRefMap adapter_refs,
+ RemoteAdapterRefs adapter_refs,
size_t audio_track_count,
size_t video_track_count) {
DCHECK(main_thread_->BelongsToCurrentThread());
@@ -315,8 +248,8 @@ void RemoteWebRtcMediaStreamAdapter::InitializeOnMainThread(
video_track_count);
size_t audio_i = 0;
size_t video_i = 0;
- for (const auto& it : adapter_refs_) {
- const blink::WebMediaStreamTrack& web_track = it.second->web_track();
+ for (const auto& adapter_ref : adapter_refs_) {
+ const blink::WebMediaStreamTrack& web_track = adapter_ref->web_track();
if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio)
web_audio_tracks[audio_i++] = web_track;
else
@@ -325,30 +258,33 @@ void RemoteWebRtcMediaStreamAdapter::InitializeOnMainThread(
web_stream_.Initialize(blink::WebString::FromUTF8(label), web_audio_tracks,
web_video_tracks);
- webrtc_stream_ = observer_->webrtc_stream();
base::AutoLock scoped_lock(lock_);
is_initialized_ = true;
}
-void RemoteWebRtcMediaStreamAdapter::OnChanged(
- RemoteAdapterRefMap new_adapter_refs) {
+void RemoteWebRtcMediaStreamAdapter::SetTracks(
+ WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs) {
DCHECK(main_thread_->BelongsToCurrentThread());
// Find removed tracks.
- for (auto it = adapter_refs_.begin(); it != adapter_refs_.end();) {
- if (new_adapter_refs.find(it->first) == new_adapter_refs.end()) {
- web_stream_.RemoveTrack(it->second->web_track());
- it = adapter_refs_.erase(it);
- } else {
- ++it;
- }
- }
+ base::EraseIf(
+ adapter_refs_,
+ [this, &track_refs](
+ const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+ track_ref) {
+ bool erase = !RemoteAdapterRefsContainsTrack(track_refs,
+ track_ref->webrtc_track());
+ if (erase)
+ web_stream_.RemoveTrack(track_ref->web_track());
+ return erase;
+ });
// Find added tracks.
- for (auto& it : new_adapter_refs) {
- if (adapter_refs_.find(it.first) == adapter_refs_.end()) {
- web_stream_.AddTrack(it.second->web_track());
- adapter_refs_.insert(std::make_pair(it.first, std::move(it.second)));
+ for (auto& track_ref : track_refs) {
+ if (!RemoteAdapterRefsContainsTrack(adapter_refs_,
+ track_ref->webrtc_track())) {
+ web_stream_.AddTrack(track_ref->web_track());
+ adapter_refs_.push_back(std::move(track_ref));
}
}
}
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
index 9a4215ad7ec..85dc842d0b6 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
@@ -34,6 +34,9 @@ class PeerConnectionDependencyFactory;
// destroyed on the main thread.
class CONTENT_EXPORT WebRtcMediaStreamAdapter {
public:
+ using TrackAdapterRefs = std::vector<
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>>;
+
// Creates an adapter for a local media stream. The adapter is already
// initialized. Invoked on the main thread.
static std::unique_ptr<WebRtcMediaStreamAdapter> CreateLocalStreamAdapter(
@@ -60,6 +63,8 @@ class CONTENT_EXPORT WebRtcMediaStreamAdapter {
(web_stream_.Id() == stream.Id());
}
+ virtual void SetTracks(TrackAdapterRefs track_refs) = 0;
+
protected:
WebRtcMediaStreamAdapter(
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
@@ -97,6 +102,7 @@ class LocalWebRtcMediaStreamAdapter : public WebRtcMediaStreamAdapter,
const scoped_refptr<webrtc::MediaStreamInterface>& webrtc_stream()
const override;
const blink::WebMediaStream& web_stream() const override;
+ void SetTracks(TrackAdapterRefs track_refs) override;
private:
// A map between web track UniqueIDs and references to track adapters.
@@ -137,35 +143,34 @@ class RemoteWebRtcMediaStreamAdapter : public WebRtcMediaStreamAdapter {
const scoped_refptr<webrtc::MediaStreamInterface>& webrtc_stream()
const override;
const blink::WebMediaStream& web_stream() const override;
+ void SetTracks(TrackAdapterRefs track_refs) override;
private:
- // A map between webrtc tracks and references to track adapters.
- using RemoteAdapterRefMap =
- std::map<webrtc::MediaStreamTrackInterface*,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>>;
+ // Track adapters for the remote webrtc tracks of a stream.
+ using RemoteAdapterRefs = WebRtcMediaStreamAdapter::TrackAdapterRefs;
+
+ static bool RemoteAdapterRefsContainsTrack(
+ const RemoteAdapterRefs& adapter_refs,
+ webrtc::MediaStreamTrackInterface* track);
// Gets the adapters for the tracks that are members of the webrtc stream.
// Invoke on webrtc signaling thread. New adapters are initialized in a post
// to the main thread after which their |web_track| becomes available.
- static RemoteAdapterRefMap GetRemoteAdapterRefMapFromWebRtcStream(
+ static RemoteAdapterRefs GetRemoteAdapterRefsFromWebRtcStream(
const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
webrtc::MediaStreamInterface* webrtc_stream);
- class WebRtcStreamObserver;
-
void InitializeOnMainThread(const std::string& label,
- RemoteAdapterRefMap track_adapter_refs,
+ RemoteAdapterRefs track_adapter_refs,
size_t audio_track_count,
size_t video_track_count);
- void OnChanged(RemoteAdapterRefMap new_adapter_refs);
mutable base::Lock lock_;
bool is_initialized_;
- scoped_refptr<WebRtcStreamObserver> observer_;
// Track adapters belonging to this stream. Keeping adapter references alive
// ensures the adapters are not disposed by the |track_adapter_map_| as long
// as the webrtc layer track is in use by the webrtc layer stream.
- RemoteAdapterRefMap adapter_refs_;
+ RemoteAdapterRefs adapter_refs_;
base::WeakPtrFactory<RemoteWebRtcMediaStreamAdapter> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RemoteWebRtcMediaStreamAdapter);
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc
index 04a3570a4a6..89ef430708b 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc
@@ -28,6 +28,7 @@ WebRtcMediaStreamAdapterMap::AdapterRef::AdapterRef(
: map_(std::move(map)), type_(type), adapter_entry_(adapter_entry) {
DCHECK(map_);
DCHECK(adapter_entry_);
+ map_->lock_.AssertAcquired();
++adapter_entry_->ref_count;
}
@@ -111,10 +112,20 @@ WebRtcMediaStreamAdapterMap::GetOrCreateLocalStreamAdapter(
AdapterEntry* adapter_entry =
local_stream_adapters_.FindByPrimary(web_stream.UniqueId());
if (!adapter_entry) {
- adapter_entry = local_stream_adapters_.Insert(
- web_stream.UniqueId(),
- WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- factory_, track_adapter_map_, web_stream));
+ std::unique_ptr<WebRtcMediaStreamAdapter> adapter;
+ {
+ // Make sure we don't hold the lock while calling out to
+ // CreateLocalStreamAdapter(). The reason is that constructing a local
+ // stream adapter, will synchronize with WebRTC's signaling thread and
+ // callbacks on the signaling thread might end up coming back to us
+ // and we might need the lock then.
+ base::AutoUnlock scoped_unlock(lock_);
+ adapter = WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
+ factory_, track_adapter_map_, web_stream);
+ }
+
+ adapter_entry = local_stream_adapters_.Insert(web_stream.UniqueId(),
+ std::move(adapter));
DCHECK(adapter_entry->adapter->is_initialized());
local_stream_adapters_.SetSecondaryKey(
web_stream.UniqueId(), adapter_entry->adapter->webrtc_stream().get());
@@ -161,10 +172,20 @@ WebRtcMediaStreamAdapterMap::GetOrCreateRemoteStreamAdapter(
AdapterEntry* adapter_entry =
remote_stream_adapters_.FindByPrimary(webrtc_stream.get());
if (!adapter_entry) {
- adapter_entry = remote_stream_adapters_.Insert(
- webrtc_stream.get(),
- WebRtcMediaStreamAdapter::CreateRemoteStreamAdapter(
- main_thread_, track_adapter_map_, webrtc_stream.get()));
+ // Make sure we don't hold the lock while calling out to
+ // CreateRemoteStreamAdapter(). The reason is that it might synchronize
+ // with other threads, possibly the main thread, where we might need to grab
+ // the lock (e.g. inside of GetOrCreateLocalStreamAdapter()).
+ std::unique_ptr<WebRtcMediaStreamAdapter> adapter;
+ {
+ base::AutoUnlock scoped_unlock(lock_);
+ adapter = WebRtcMediaStreamAdapter::CreateRemoteStreamAdapter(
+ main_thread_, track_adapter_map_, webrtc_stream.get());
+ }
+
+ adapter_entry =
+ remote_stream_adapters_.Insert(webrtc_stream.get(), std::move(adapter));
+
// The new adapter is initialized in a post to the main thread. As soon as
// it is initialized we map its |webrtc_stream| to the
// |remote_stream_adapters_| entry as its secondary key. This ensures that
@@ -189,6 +210,7 @@ size_t WebRtcMediaStreamAdapterMap::GetRemoteStreamCount() const {
void WebRtcMediaStreamAdapterMap::OnRemoteStreamAdapterInitialized(
std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref) {
+ DCHECK(main_thread_->BelongsToCurrentThread());
DCHECK(adapter_ref->is_initialized());
{
base::AutoLock scoped_lock(lock_);
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h
index 521ca5f73a5..1d7ab4ca59e 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h
@@ -58,6 +58,7 @@ class CONTENT_EXPORT WebRtcMediaStreamAdapterMap
const WebRtcMediaStreamAdapter& adapter() const {
return *adapter_entry_->adapter;
}
+ WebRtcMediaStreamAdapter& adapter() { return *adapter_entry_->adapter; }
private:
friend class WebRtcMediaStreamAdapterMap;
@@ -152,9 +153,9 @@ class CONTENT_EXPORT WebRtcMediaStreamAdapterMap
// Pointer to a |PeerConnectionDependencyFactory| owned by the |RenderThread|.
// It's valid for the lifetime of |RenderThread|.
PeerConnectionDependencyFactory* const factory_;
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
+ const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
// Takes care of creating and owning track adapters, used by stream adapters.
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
+ const scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
mutable base::Lock lock_;
LocalStreamAdapterMap local_stream_adapters_;
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc
index 0b00c2dbce2..dbbe22f743f 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc
@@ -9,10 +9,10 @@
#include <memory>
#include <string>
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/child/child_process.h"
#include "content/renderer/media/media_stream_video_source.h"
@@ -38,7 +38,6 @@ namespace content {
class WebRtcMediaStreamAdapterTest : public ::testing::Test {
public:
void SetUp() override {
- child_process_.reset(new ChildProcess());
dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
track_adapter_map_ =
new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get());
@@ -50,8 +49,10 @@ class WebRtcMediaStreamAdapterTest : public ::testing::Test {
}
protected:
- base::MessageLoop message_loop_;
- std::unique_ptr<ChildProcess> child_process_;
+ // The ScopedTaskEnvironment prevents the ChildProcess from leaking a
+ // TaskScheduler.
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ ChildProcess child_process_;
std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
};
@@ -145,21 +146,33 @@ class RemoteWebRtcMediaStreamAdapterTest : public WebRtcMediaStreamAdapterTest {
return adapter;
}
+ // Adds the track and gets the adapters for the stream's resulting tracks.
template <typename TrackType>
- void AddTrack(webrtc::MediaStreamInterface* webrtc_stream,
- TrackType* webrtc_track) {
+ WebRtcMediaStreamAdapter::TrackAdapterRefs AddTrack(
+ webrtc::MediaStreamInterface* webrtc_stream,
+ TrackType* webrtc_track) {
typedef bool (webrtc::MediaStreamInterface::*AddTrack)(TrackType*);
dependency_factory_->GetWebRtcSignalingThread()->PostTask(
FROM_HERE, base::BindOnce(base::IgnoreResult<AddTrack>(
&webrtc::MediaStreamInterface::AddTrack),
base::Unretained(webrtc_stream),
base::Unretained(webrtc_track)));
+ WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs;
+ dependency_factory_->GetWebRtcSignalingThread()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&RemoteWebRtcMediaStreamAdapterTest::
+ GetStreamTrackRefsOnSignalingThread,
+ base::Unretained(this), base::Unretained(webrtc_stream),
+ base::Unretained(&track_refs)));
RunMessageLoopsUntilIdle();
+ return track_refs;
}
+ // Removes the track and gets the adapters for the stream's resulting tracks.
template <typename TrackType>
- void RemoveTrack(webrtc::MediaStreamInterface* webrtc_stream,
- TrackType* webrtc_track) {
+ WebRtcMediaStreamAdapter::TrackAdapterRefs RemoveTrack(
+ webrtc::MediaStreamInterface* webrtc_stream,
+ TrackType* webrtc_track) {
typedef bool (webrtc::MediaStreamInterface::*RemoveTrack)(TrackType*);
dependency_factory_->GetWebRtcSignalingThread()->PostTask(
FROM_HERE,
@@ -167,7 +180,15 @@ class RemoteWebRtcMediaStreamAdapterTest : public WebRtcMediaStreamAdapterTest {
&webrtc::MediaStreamInterface::RemoveTrack),
base::Unretained(webrtc_stream),
base::Unretained(webrtc_track)));
+ WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs;
+ dependency_factory_->GetWebRtcSignalingThread()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&RemoteWebRtcMediaStreamAdapterTest::
+ GetStreamTrackRefsOnSignalingThread,
+ base::Unretained(this), base::Unretained(webrtc_stream),
+ base::Unretained(&track_refs)));
RunMessageLoopsUntilIdle();
+ return track_refs;
}
private:
@@ -180,6 +201,21 @@ class RemoteWebRtcMediaStreamAdapterTest : public WebRtcMediaStreamAdapterTest {
EXPECT_FALSE((*adapter)->is_initialized());
}
+ void GetStreamTrackRefsOnSignalingThread(
+ webrtc::MediaStreamInterface* webrtc_stream,
+ WebRtcMediaStreamAdapter::TrackAdapterRefs* out_track_refs) {
+ WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs;
+ for (auto& audio_track : webrtc_stream->GetAudioTracks()) {
+ track_refs.push_back(
+ track_adapter_map_->GetOrCreateRemoteTrackAdapter(audio_track.get()));
+ }
+ for (auto& video_track : webrtc_stream->GetVideoTracks()) {
+ track_refs.push_back(
+ track_adapter_map_->GetOrCreateRemoteTrackAdapter(video_track.get()));
+ }
+ *out_track_refs = std::move(track_refs);
+ }
+
// Runs message loops on the webrtc signaling thread and the main thread until
// idle.
void RunMessageLoopsUntilIdle() {
@@ -190,6 +226,7 @@ class RemoteWebRtcMediaStreamAdapterTest : public WebRtcMediaStreamAdapterTest {
FROM_HERE,
base::BindOnce(&RemoteWebRtcMediaStreamAdapterTest::SignalEvent,
base::Unretained(this), &waitable_event));
+ // TODO(hbos): Use base::RunLoop instead of WaitableEvent.
waitable_event.Wait();
base::RunLoop().RunUntilIdle();
}
@@ -334,21 +371,23 @@ TEST_F(RemoteWebRtcMediaStreamAdapterTest, RemoveAndAddTrack) {
// Modify the webrtc layer stream, make sure the web layer stream is updated.
rtc::scoped_refptr<webrtc::AudioTrackInterface> webrtc_audio_track =
webrtc_stream->GetAudioTracks()[0];
- RemoveTrack(webrtc_stream.get(), webrtc_audio_track.get());
+ adapter->SetTracks(
+ RemoveTrack(webrtc_stream.get(), webrtc_audio_track.get()));
adapter->web_stream().AudioTracks(web_audio_tracks);
EXPECT_EQ(0u, web_audio_tracks.size());
rtc::scoped_refptr<webrtc::VideoTrackInterface> webrtc_video_track =
webrtc_stream->GetVideoTracks()[0];
- RemoveTrack(webrtc_stream.get(), webrtc_video_track.get());
+ adapter->SetTracks(
+ RemoveTrack(webrtc_stream.get(), webrtc_video_track.get()));
adapter->web_stream().VideoTracks(web_video_tracks);
EXPECT_EQ(0u, web_video_tracks.size());
- AddTrack(webrtc_stream.get(), webrtc_audio_track.get());
+ adapter->SetTracks(AddTrack(webrtc_stream.get(), webrtc_audio_track.get()));
adapter->web_stream().AudioTracks(web_audio_tracks);
EXPECT_EQ(1u, web_audio_tracks.size());
- AddTrack(webrtc_stream.get(), webrtc_video_track.get());
+ adapter->SetTracks(AddTrack(webrtc_stream.get(), webrtc_video_track.get()));
adapter->web_stream().VideoTracks(web_video_tracks);
EXPECT_EQ(1u, web_video_tracks.size());
}
diff --git a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc b/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc
new file mode 100644
index 00000000000..dceb863941d
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc/webrtc_set_remote_description_observer.h"
+
+#include "base/logging.h"
+
+namespace content {
+
+WebRtcReceiverState::WebRtcReceiverState(
+ scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ stream_refs)
+ : receiver(std::move(receiver)),
+ track_ref(std::move(track_ref)),
+ stream_refs(std::move(stream_refs)) {}
+
+WebRtcReceiverState::WebRtcReceiverState(WebRtcReceiverState&& other) = default;
+
+WebRtcReceiverState& WebRtcReceiverState::operator=(
+ WebRtcReceiverState&& other) = default;
+
+WebRtcReceiverState::~WebRtcReceiverState() {}
+
+WebRtcSetRemoteDescriptionObserver::States::States() {}
+
+WebRtcSetRemoteDescriptionObserver::States::States(States&& other)
+ : receiver_states(std::move(other.receiver_states)) {}
+
+WebRtcSetRemoteDescriptionObserver::States::~States() {}
+
+WebRtcSetRemoteDescriptionObserver::States&
+WebRtcSetRemoteDescriptionObserver::States::operator=(States&& other) {
+ receiver_states = std::move(other.receiver_states);
+ return *this;
+}
+
+WebRtcSetRemoteDescriptionObserver::WebRtcSetRemoteDescriptionObserver() {}
+
+WebRtcSetRemoteDescriptionObserver::~WebRtcSetRemoteDescriptionObserver() {}
+
+scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler>
+WebRtcSetRemoteDescriptionObserverHandler::Create(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map,
+ scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer) {
+ return new rtc::RefCountedObject<WebRtcSetRemoteDescriptionObserverHandler>(
+ std::move(main_thread), std::move(pc), std::move(stream_adapter_map),
+ std::move(observer));
+}
+
+WebRtcSetRemoteDescriptionObserverHandler::
+ WebRtcSetRemoteDescriptionObserverHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map,
+ scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer)
+ : main_thread_(std::move(main_thread)),
+ pc_(std::move(pc)),
+ stream_adapter_map_(std::move(stream_adapter_map)),
+ observer_(std::move(observer)) {}
+
+WebRtcSetRemoteDescriptionObserverHandler::
+ ~WebRtcSetRemoteDescriptionObserverHandler() {}
+
+void WebRtcSetRemoteDescriptionObserverHandler::OnSetRemoteDescriptionComplete(
+ webrtc::RTCError error) {
+ DCHECK(!main_thread_->BelongsToCurrentThread());
+
+ webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>
+ states_or_error;
+ if (error.ok()) {
+ WebRtcSetRemoteDescriptionObserver::States states;
+ for (const auto& webrtc_receiver : pc_->GetReceivers()) {
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref =
+ track_adapter_map()->GetOrCreateRemoteTrackAdapter(
+ webrtc_receiver->track().get());
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ stream_refs;
+ for (const auto& stream : webrtc_receiver->streams()) {
+ stream_refs.push_back(
+ stream_adapter_map_->GetOrCreateRemoteStreamAdapter(stream.get()));
+ }
+ states.receiver_states.push_back(WebRtcReceiverState(
+ webrtc_receiver.get(), std::move(track_ref), std::move(stream_refs)));
+ }
+ states_or_error = std::move(states);
+ } else {
+ states_or_error = std::move(error);
+ }
+ main_thread_->PostTask(
+ FROM_HERE, base::BindOnce(&WebRtcSetRemoteDescriptionObserverHandler::
+ OnSetRemoteDescriptionCompleteOnMainThread,
+ this, base::Passed(&states_or_error)));
+}
+
+void WebRtcSetRemoteDescriptionObserverHandler::
+ OnSetRemoteDescriptionCompleteOnMainThread(
+ webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>
+ states_or_error) {
+ DCHECK(main_thread_->BelongsToCurrentThread());
+ observer_->OnSetRemoteDescriptionComplete(std::move(states_or_error));
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h b/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h
new file mode 100644
index 00000000000..f4b96b8853c
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h
@@ -0,0 +1,138 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_REMOTE_DESCRIPTION_OBSERVER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_REMOTE_DESCRIPTION_OBSERVER_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "content/common/content_export.h"
+#include "content/renderer/media/rtc_peer_connection_handler.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h"
+#include "third_party/webrtc/api/rtcerror.h"
+#include "third_party/webrtc/api/rtpreceiverinterface.h"
+#include "third_party/webrtc/api/setremotedescriptionobserverinterface.h"
+#include "third_party/webrtc/rtc_base/refcount.h"
+#include "third_party/webrtc/rtc_base/refcountedobject.h"
+#include "third_party/webrtc/rtc_base/scoped_ref_ptr.h"
+
+namespace content {
+
+// Describes an instance of a receiver at the time the SRD call was completed.
+// Because webrtc and content operate on different threads, webrtc objects may
+// have been modified by the time we synchronize the receivers on the main
+// thread, and members of this class should be inspected rather than members of
+// |receiver|.
+struct CONTENT_EXPORT WebRtcReceiverState {
+ WebRtcReceiverState(
+ scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ stream_refs);
+ WebRtcReceiverState(WebRtcReceiverState&& other);
+ ~WebRtcReceiverState();
+
+ WebRtcReceiverState& operator=(WebRtcReceiverState&& other);
+
+ scoped_refptr<webrtc::RtpReceiverInterface> receiver;
+ // The receiver's track when the SRD occurred.
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
+ // The receiver's associated set of streams when the SRD occurred.
+ std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
+ stream_refs;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcReceiverState);
+};
+
+// The content layer correspondent of
+// webrtc::SetRemoteDescriptionObserverInterface. It's an interface with
+// callbacks for handling the result of SetRemoteDescription on the main thread.
+// The implementation should process the state changes of the
+// SetRemoteDescription by inspecting the updated States.
+class CONTENT_EXPORT WebRtcSetRemoteDescriptionObserver
+ : public base::RefCountedThreadSafe<WebRtcSetRemoteDescriptionObserver> {
+ public:
+ // The relevant peer connection states as they were when the
+ // SetRemoteDescription call completed. This is used instead of inspecting the
+ // PeerConnection and other webrtc objects directly because they may have been
+ // modified before we reach the main thread.
+ struct CONTENT_EXPORT States {
+ States();
+ States(States&& other);
+ ~States();
+
+ States& operator=(States&& other);
+
+ // The receivers at the time of the event.
+ std::vector<WebRtcReceiverState> receiver_states;
+
+ DISALLOW_COPY_AND_ASSIGN(States);
+ };
+
+ WebRtcSetRemoteDescriptionObserver();
+
+ // Invoked asynchronously on the main thread after the SetRemoteDescription
+ // completed on the webrtc signaling thread.
+ virtual void OnSetRemoteDescriptionComplete(
+ webrtc::RTCErrorOr<States> states_or_error) = 0;
+
+ protected:
+ friend class base::RefCountedThreadSafe<WebRtcSetRemoteDescriptionObserver>;
+ virtual ~WebRtcSetRemoteDescriptionObserver();
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSetRemoteDescriptionObserver);
+};
+
+// The glue between webrtc and content layer observers listening to
+// SetRemoteDescription. This observer listens on the webrtc signaling thread
+// for the result of SetRemoteDescription, copies any relevant webrtc peer
+// connection states such that they can be processed on the main thread, and
+// invokes the WebRtcSetRemoteDescriptionObserver on the main thread with the
+// state changes.
+class CONTENT_EXPORT WebRtcSetRemoteDescriptionObserverHandler
+ : public webrtc::SetRemoteDescriptionObserverInterface {
+ public:
+ static scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler> Create(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map,
+ scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer);
+
+ // webrtc::SetRemoteDescriptionObserverInterface implementation.
+ void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override;
+
+ protected:
+ WebRtcSetRemoteDescriptionObserverHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map,
+ scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer);
+ ~WebRtcSetRemoteDescriptionObserverHandler() override;
+
+ private:
+ void OnSetRemoteDescriptionCompleteOnMainThread(
+ webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>
+ states_or_error);
+
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map() const {
+ return stream_adapter_map_->track_adapter_map();
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
+ scoped_refptr<webrtc::PeerConnectionInterface> pc_;
+ scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map_;
+ scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSetRemoteDescriptionObserverHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_REMOTE_DESCRIPTION_OBSERVER_H_
diff --git a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc
new file mode 100644
index 00000000000..1f34512a36c
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc
@@ -0,0 +1,149 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc/webrtc_set_remote_description_observer.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#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/threading/thread_task_runner_handle.h"
+#include "content/child/child_process.h"
+#include "content/renderer/media/mock_peer_connection_impl.h"
+#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebHeap.h"
+#include "third_party/webrtc/api/peerconnectioninterface.h"
+#include "third_party/webrtc/media/base/fakemediaengine.h"
+#include "third_party/webrtc/pc/test/mock_peerconnection.h"
+
+using ::testing::Return;
+
+namespace content {
+
+class WebRtcSetRemoteDescriptionObserverForTest
+ : public WebRtcSetRemoteDescriptionObserver {
+ public:
+ bool called() const { return states_or_error_.has_value(); }
+ bool result() const { return states_or_error_->ok(); }
+
+ const WebRtcSetRemoteDescriptionObserver::States& states() const {
+ DCHECK(called() && result());
+ return states_or_error_->value();
+ }
+ const webrtc::RTCError& error() const {
+ DCHECK(called() && !result());
+ return states_or_error_->error();
+ }
+
+ // WebRtcSetRemoteDescriptionObserver implementation.
+ void OnSetRemoteDescriptionComplete(
+ webrtc::RTCErrorOr<States> states_or_error) override {
+ states_or_error_ = std::move(states_or_error);
+ }
+
+ private:
+ ~WebRtcSetRemoteDescriptionObserverForTest() override {}
+
+ base::Optional<webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>>
+ states_or_error_;
+ WebRtcSetRemoteDescriptionObserver::States states_;
+};
+
+class WebRtcSetRemoteDescriptionObserverHandlerTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ pc_ = new webrtc::MockPeerConnection(new webrtc::FakePeerConnectionFactory(
+ std::unique_ptr<cricket::MediaEngineInterface>(
+ new cricket::FakeMediaEngine())));
+ dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
+ main_thread_ = base::ThreadTaskRunnerHandle::Get();
+ scoped_refptr<WebRtcMediaStreamAdapterMap> map =
+ new WebRtcMediaStreamAdapterMap(
+ dependency_factory_.get(),
+ new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get()));
+ observer_ = new WebRtcSetRemoteDescriptionObserverForTest();
+ observer_handler_ = WebRtcSetRemoteDescriptionObserverHandler::Create(
+ main_thread_, pc_, map, observer_);
+ }
+
+ void TearDown() override { blink::WebHeap::CollectAllGarbageForTesting(); }
+
+ void InvokeOnSetRemoteDescriptionComplete(webrtc::RTCError error) {
+ base::RunLoop run_loop;
+ dependency_factory_->GetWebRtcSignalingThread()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &WebRtcSetRemoteDescriptionObserverHandlerTest::
+ InvokeOnSetRemoteDescriptionCompleteOnSignalingThread,
+ base::Unretained(this), base::Passed(&error),
+ base::Unretained(&run_loop)));
+ run_loop.Run();
+ }
+
+ protected:
+ void InvokeOnSetRemoteDescriptionCompleteOnSignalingThread(
+ webrtc::RTCError error,
+ base::RunLoop* run_loop) {
+ observer_handler_->OnSetRemoteDescriptionComplete(std::move(error));
+ run_loop->Quit();
+ }
+
+ // Message loop and child process are needed for task queues and threading to
+ // work, as is necessary to create tracks and adapters.
+ base::MessageLoop message_loop_;
+ ChildProcess child_process_;
+
+ scoped_refptr<webrtc::MockPeerConnection> pc_;
+ std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
+ scoped_refptr<WebRtcSetRemoteDescriptionObserverForTest> observer_;
+ scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler> observer_handler_;
+
+ std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> receivers_;
+};
+
+TEST_F(WebRtcSetRemoteDescriptionObserverHandlerTest, OnSuccess) {
+ scoped_refptr<MockWebRtcAudioTrack> added_track =
+ MockWebRtcAudioTrack::Create("added_track");
+ scoped_refptr<webrtc::MediaStreamInterface> added_stream(
+ new rtc::RefCountedObject<MockMediaStream>("added_stream"));
+ scoped_refptr<webrtc::RtpReceiverInterface> added_receiver(
+ new rtc::RefCountedObject<FakeRtpReceiver>(
+ added_track.get(),
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>(
+ {added_stream.get()})));
+
+ receivers_.push_back(added_receiver.get());
+ EXPECT_CALL(*pc_, GetReceivers()).WillRepeatedly(Return(receivers_));
+
+ InvokeOnSetRemoteDescriptionComplete(webrtc::RTCError::OK());
+ EXPECT_TRUE(observer_->called());
+ EXPECT_TRUE(observer_->result());
+
+ EXPECT_EQ(1u, observer_->states().receiver_states.size());
+ const WebRtcReceiverState& receiver_state =
+ observer_->states().receiver_states[0];
+ EXPECT_EQ(added_receiver, receiver_state.receiver);
+ EXPECT_EQ(added_track, receiver_state.track_ref->webrtc_track());
+ EXPECT_EQ(1u, receiver_state.stream_refs.size());
+ EXPECT_EQ(added_stream,
+ receiver_state.stream_refs[0]->adapter().webrtc_stream());
+}
+
+TEST_F(WebRtcSetRemoteDescriptionObserverHandlerTest, OnFailure) {
+ webrtc::RTCError error(webrtc::RTCErrorType::INVALID_PARAMETER, "Oh noes!");
+ InvokeOnSetRemoteDescriptionComplete(std::move(error));
+ EXPECT_TRUE(observer_->called());
+ EXPECT_FALSE(observer_->result());
+ EXPECT_EQ(std::string("Oh noes!"), observer_->error().message());
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc b/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
index bd14bf1b80d..9e2c6ec571c 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
@@ -14,7 +14,7 @@
#include "content/renderer/render_thread_impl.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_util.h"
-#include "media/renderers/skcanvas_video_renderer.h"
+#include "media/renderers/paint_canvas_video_renderer.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/libyuv/include/libyuv/convert.h"
@@ -55,7 +55,7 @@ class WebRtcVideoCapturerAdapter::TextureFrameCopier
public:
TextureFrameCopier()
: main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
- canvas_video_renderer_(new media::SkCanvasVideoRenderer) {
+ canvas_video_renderer_(new media::PaintCanvasVideoRenderer) {
RenderThreadImpl* const main_thread = RenderThreadImpl::current();
if (main_thread)
provider_ = main_thread->SharedMainThreadContextProvider();
@@ -145,7 +145,7 @@ class WebRtcVideoCapturerAdapter::TextureFrameCopier
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
scoped_refptr<ui::ContextProviderCommandBuffer> provider_;
- std::unique_ptr<media::SkCanvasVideoRenderer> canvas_video_renderer_;
+ std::unique_ptr<media::PaintCanvasVideoRenderer> canvas_video_renderer_;
};
WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter(
@@ -179,10 +179,6 @@ void WebRtcVideoCapturerAdapter::OnFrameCaptured(
return;
}
scoped_refptr<media::VideoFrame> frame = input_frame;
- // Drop alpha channel since we do not support it yet.
- if (frame->format() == media::PIXEL_FORMAT_YV12A)
- frame = media::WrapAsI420VideoFrame(input_frame);
-
const int orig_width = frame->natural_size().width();
const int orig_height = frame->natural_size().height();
int adapted_width;
@@ -247,10 +243,12 @@ void WebRtcVideoCapturerAdapter::OnFrameCaptured(
}
// We need to scale the frame before we hand it over to webrtc.
+ const bool has_alpha = video_frame->format() == media::PIXEL_FORMAT_YV12A;
scoped_refptr<media::VideoFrame> scaled_frame =
- scaled_frame_pool_.CreateFrame(media::PIXEL_FORMAT_I420, adapted_size,
- gfx::Rect(adapted_size), adapted_size,
- frame->timestamp());
+ scaled_frame_pool_.CreateFrame(
+ has_alpha ? media::PIXEL_FORMAT_YV12A : media::PIXEL_FORMAT_I420,
+ adapted_size, gfx::Rect(adapted_size), adapted_size,
+ frame->timestamp());
libyuv::I420Scale(video_frame->visible_data(media::VideoFrame::kYPlane),
video_frame->stride(media::VideoFrame::kYPlane),
video_frame->visible_data(media::VideoFrame::kUPlane),
@@ -266,6 +264,15 @@ void WebRtcVideoCapturerAdapter::OnFrameCaptured(
scaled_frame->data(media::VideoFrame::kVPlane),
scaled_frame->stride(media::VideoFrame::kVPlane),
adapted_width, adapted_height, libyuv::kFilterBilinear);
+ if (has_alpha) {
+ libyuv::ScalePlane(video_frame->visible_data(media::VideoFrame::kAPlane),
+ video_frame->stride(media::VideoFrame::kAPlane),
+ video_frame->visible_rect().width(),
+ video_frame->visible_rect().height(),
+ scaled_frame->data(media::VideoFrame::kAPlane),
+ scaled_frame->stride(media::VideoFrame::kAPlane),
+ adapted_width, adapted_height, libyuv::kFilterBilinear);
+ }
OnFrame(webrtc::VideoFrame(
new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(
@@ -290,7 +297,7 @@ void WebRtcVideoCapturerAdapter::Stop() {
DVLOG(3) << __func__;
DCHECK(running_);
running_ = false;
- SetCaptureFormat(NULL);
+ SetCaptureFormat(nullptr);
SignalStateChange(this, cricket::CS_STOPPED);
}
diff --git a/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc
index 68435cf5d3e..2133e8a293c 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc
@@ -5,9 +5,9 @@
#include <algorithm>
#include "base/bind.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/test/scoped_task_environment.h"
#include "content/child/child_process.h"
#include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
#include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h"
@@ -26,7 +26,9 @@ class WebRtcVideoCapturerAdapterTest
public ::testing::Test {
public:
WebRtcVideoCapturerAdapterTest()
- : adapter_(new WebRtcVideoCapturerAdapter(
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO),
+ adapter_(new WebRtcVideoCapturerAdapter(
false,
blink::WebMediaStreamTrack::ContentHintType::kNone)),
output_frame_width_(0),
@@ -56,7 +58,8 @@ class WebRtcVideoCapturerAdapterTest
}
void TestSourceTextureFrame() {
- EXPECT_TRUE(message_loop_.IsCurrent());
+ EXPECT_TRUE(scoped_task_environment_.GetMainThreadTaskRunner()
+ ->BelongsToCurrentThread());
gpu::MailboxHolder holders[media::VideoFrame::kMaxPlanes] = {
gpu::MailboxHolder(gpu::Mailbox::Generate(), gpu::SyncToken(), 5)};
scoped_refptr<media::VideoFrame> frame =
@@ -136,7 +139,9 @@ class WebRtcVideoCapturerAdapterTest
}
private:
- const base::MessageLoopForIO message_loop_;
+ // The ScopedTaskEnvironment prevents the ChildProcess from leaking a
+ // TaskScheduler.
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
const ChildProcess child_process_;
std::unique_ptr<WebRtcVideoCapturerAdapter> adapter_;
diff --git a/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc b/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc
index 8d726638aad..f49629bc6d7 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc
@@ -5,14 +5,16 @@
#include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h"
#include "base/logging.h"
+#include "third_party/webrtc/common_video/include/video_frame_buffer.h"
#include "third_party/webrtc/rtc_base/refcountedobject.h"
namespace {
-class I420Adapter : public webrtc::I420BufferInterface {
+template <typename Base>
+class FrameAdapter : public Base {
public:
- explicit I420Adapter(const scoped_refptr<media::VideoFrame>& frame)
- : frame_(frame) {}
+ explicit FrameAdapter(const scoped_refptr<media::VideoFrame>& frame)
+ : frame_(std::move(frame)) {}
private:
int width() const override { return frame_->visible_rect().width(); }
@@ -45,6 +47,24 @@ class I420Adapter : public webrtc::I420BufferInterface {
scoped_refptr<media::VideoFrame> frame_;
};
+template <typename BaseWithA>
+class FrameAdapterWithA : public FrameAdapter<BaseWithA> {
+ public:
+ FrameAdapterWithA(const scoped_refptr<media::VideoFrame>& frame)
+ : FrameAdapter<BaseWithA>(std::move(frame)), frame_(std::move(frame)) {}
+
+ private:
+ const uint8_t* DataA() const override {
+ return frame_->visible_data(media::VideoFrame::kAPlane);
+ }
+
+ int StrideA() const override {
+ return frame_->stride(media::VideoFrame::kAPlane);
+ }
+
+ scoped_refptr<media::VideoFrame> frame_;
+};
+
void IsValidFrame(const scoped_refptr<media::VideoFrame>& frame) {
// Paranoia checks.
DCHECK(frame);
@@ -52,7 +72,8 @@ void IsValidFrame(const scoped_refptr<media::VideoFrame>& frame) {
frame->format(), frame->storage_type(), frame->coded_size(),
frame->visible_rect(), frame->natural_size()));
DCHECK(media::PIXEL_FORMAT_I420 == frame->format() ||
- media::PIXEL_FORMAT_YV12 == frame->format());
+ media::PIXEL_FORMAT_YV12 == frame->format() ||
+ media::PIXEL_FORMAT_YV12A == frame->format());
CHECK(reinterpret_cast<void*>(frame->data(media::VideoFrame::kYPlane)));
CHECK(reinterpret_cast<void*>(frame->data(media::VideoFrame::kUPlane)));
CHECK(reinterpret_cast<void*>(frame->data(media::VideoFrame::kVPlane)));
@@ -101,7 +122,12 @@ WebRtcVideoFrameAdapter::ToI420() {
}
IsValidFrame(frame_);
- return new rtc::RefCountedObject<I420Adapter>(frame_);
+ if (media::PIXEL_FORMAT_YV12A == frame_->format()) {
+ return new rtc::RefCountedObject<
+ FrameAdapterWithA<webrtc::I420ABufferInterface>>(frame_);
+ }
+ return new rtc::RefCountedObject<FrameAdapter<webrtc::I420BufferInterface>>(
+ frame_);
}
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc_audio_device_impl.cc b/chromium/content/renderer/media/webrtc_audio_device_impl.cc
index 86169a29f6d..3d94e977d0d 100644
--- a/chromium/content/renderer/media/webrtc_audio_device_impl.cc
+++ b/chromium/content/renderer/media/webrtc_audio_device_impl.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/trace_event/trace_event.h"
#include "content/renderer/media/webrtc/processed_local_audio_source.h"
@@ -14,18 +15,13 @@
#include "media/base/audio_parameters.h"
#include "media/base/sample_rates.h"
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif
-
using media::AudioParameters;
using media::ChannelLayout;
namespace content {
WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()
- : ref_count_(0),
- audio_transport_callback_(NULL),
+ : audio_transport_callback_(nullptr),
output_delay_ms_(0),
initialized_(false),
playing_(false),
@@ -47,22 +43,6 @@ WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl() {
DCHECK(!initialized_) << "Terminate must have been called.";
}
-int32_t WebRtcAudioDeviceImpl::AddRef() const {
- // We can be AddRefed and released on both the UI thread as well as
- // libjingle's signaling thread.
- return base::subtle::Barrier_AtomicIncrement(&ref_count_, 1);
-}
-
-int32_t WebRtcAudioDeviceImpl::Release() const {
- // We can be AddRefed and released on both the UI thread as well as
- // libjingle's signaling thread.
- int ret = base::subtle::Barrier_AtomicIncrement(&ref_count_, -1);
- if (ret == 0) {
- delete this;
- }
- return ret;
-}
-
void WebRtcAudioDeviceImpl::RenderData(media::AudioBus* audio_bus,
int sample_rate,
int audio_delay_milliseconds,
@@ -88,38 +68,33 @@ void WebRtcAudioDeviceImpl::RenderData(media::AudioBus* audio_bus,
}
render_buffer_.resize(audio_bus->frames() * audio_bus->channels());
- int frames_per_10_ms = (sample_rate / 100);
+ int frames_per_10_ms = sample_rate / 100;
int bytes_per_sample = sizeof(render_buffer_[0]);
// Client should always ask for 10ms.
DCHECK_EQ(audio_bus->frames(), frames_per_10_ms);
// Get 10ms audio and copy result to temporary byte buffer.
+ static const int kBitsPerByte = 8;
int64_t elapsed_time_ms = -1;
int64_t ntp_time_ms = -1;
- static const int kBitsPerByte = 8;
- int16_t* audio_data = &render_buffer_[0];
+ int16_t* audio_data = render_buffer_.data();
TRACE_EVENT_BEGIN0("audio", "VoE::PullRenderData");
audio_transport_callback_->PullRenderData(
bytes_per_sample * kBitsPerByte, sample_rate, audio_bus->channels(),
frames_per_10_ms, audio_data, &elapsed_time_ms, &ntp_time_ms);
TRACE_EVENT_END0("audio", "VoE::PullRenderData");
- if (elapsed_time_ms >= 0) {
+ if (elapsed_time_ms >= 0)
*current_time = base::TimeDelta::FromMilliseconds(elapsed_time_ms);
- }
// De-interleave each channel and convert to 32-bit floating-point
// with nominal range -1.0 -> +1.0 to match the callback format.
- audio_bus->FromInterleaved(&render_buffer_[0],
- audio_bus->frames(),
- bytes_per_sample);
+ audio_bus->FromInterleaved(audio_data, audio_bus->frames(), bytes_per_sample);
// Pass the render data to the playout sinks.
base::AutoLock auto_lock(lock_);
- for (PlayoutDataSinkList::const_iterator it = playout_sinks_.begin();
- it != playout_sinks_.end(); ++it) {
- (*it)->OnPlayoutData(audio_bus, sample_rate, audio_delay_milliseconds);
- }
+ for (auto* sink : playout_sinks_)
+ sink->OnPlayoutData(audio_bus, sample_rate, audio_delay_milliseconds);
}
void WebRtcAudioDeviceImpl::RemoveAudioRenderer(WebRtcAudioRenderer* renderer) {
@@ -127,12 +102,10 @@ void WebRtcAudioDeviceImpl::RemoveAudioRenderer(WebRtcAudioRenderer* renderer) {
base::AutoLock auto_lock(lock_);
DCHECK_EQ(renderer, renderer_.get());
// Notify the playout sink of the change.
- for (PlayoutDataSinkList::const_iterator it = playout_sinks_.begin();
- it != playout_sinks_.end(); ++it) {
- (*it)->OnPlayoutDataSourceChanged();
- }
+ for (auto* sink : playout_sinks_)
+ sink->OnPlayoutDataSourceChanged();
- renderer_ = NULL;
+ renderer_ = nullptr;
}
void WebRtcAudioDeviceImpl::AudioRendererThreadStopped() {
@@ -150,7 +123,7 @@ int32_t WebRtcAudioDeviceImpl::RegisterAudioCallback(
DVLOG(1) << "WebRtcAudioDeviceImpl::RegisterAudioCallback()";
DCHECK(signaling_thread_checker_.CalledOnValidThread());
base::AutoLock lock(lock_);
- DCHECK_EQ(audio_transport_callback_ == NULL, audio_callback != NULL);
+ DCHECK_EQ(audio_transport_callback_ == nullptr, audio_callback != nullptr);
audio_transport_callback_ = audio_callback;
return 0;
}
@@ -178,7 +151,7 @@ int32_t WebRtcAudioDeviceImpl::Terminate() {
StopRecording();
StopPlayout();
- DCHECK(!renderer_.get() || !renderer_->IsStarted())
+ DCHECK(!renderer_ || !renderer_->IsStarted())
<< "The shared audio renderer shouldn't be running";
{
@@ -209,7 +182,7 @@ bool WebRtcAudioDeviceImpl::PlayoutIsInitialized() const {
int32_t WebRtcAudioDeviceImpl::RecordingIsAvailable(bool* available) {
DCHECK(signaling_thread_checker_.CalledOnValidThread());
base::AutoLock auto_lock(lock_);
- *available = (!capturers_.empty());
+ *available = !capturers_.empty();
return 0;
}
@@ -217,7 +190,7 @@ bool WebRtcAudioDeviceImpl::RecordingIsInitialized() const {
DVLOG(1) << "WebRtcAudioDeviceImpl::RecordingIsInitialized()";
DCHECK(signaling_thread_checker_.CalledOnValidThread());
base::AutoLock auto_lock(lock_);
- return (!capturers_.empty());
+ return !capturers_.empty();
}
int32_t WebRtcAudioDeviceImpl::StartPlayout() {
@@ -340,7 +313,7 @@ int32_t WebRtcAudioDeviceImpl::StereoPlayoutIsAvailable(bool* available) const {
// thread we're on since it might incorrectly initialize the
// worker_thread_checker_.
base::AutoLock auto_lock(lock_);
- *available = renderer_.get() && renderer_->channels() == 2;
+ *available = renderer_ && renderer_->channels() == 2;
return 0;
}
@@ -368,34 +341,6 @@ int32_t WebRtcAudioDeviceImpl::PlayoutDelay(uint16_t* delay_ms) const {
return 0;
}
-int32_t WebRtcAudioDeviceImpl::RecordingDelay(uint16_t* delay_ms) const {
- DCHECK(signaling_thread_checker_.CalledOnValidThread());
-
- // There is no way to report a correct delay value to WebRTC since there
- // might be multiple ProcessedLocalAudioSource instances.
- NOTREACHED();
- return -1;
-}
-
-int32_t WebRtcAudioDeviceImpl::RecordingSampleRate(
- uint32_t* sample_rate) const {
- DCHECK(signaling_thread_checker_.CalledOnValidThread());
- // We use the default capturer as the recording sample rate.
- base::AutoLock auto_lock(lock_);
- if (capturers_.empty())
- return -1;
- const media::AudioParameters& params = capturers_.back()->GetInputFormat();
- *sample_rate = static_cast<uint32_t>(params.sample_rate());
- return 0;
-}
-
-int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate(
- uint32_t* sample_rate) const {
- DCHECK(signaling_thread_checker_.CalledOnValidThread());
- *sample_rate = renderer_.get() ? renderer_->sample_rate() : 0;
- return 0;
-}
-
bool WebRtcAudioDeviceImpl::SetAudioRenderer(WebRtcAudioRenderer* renderer) {
DCHECK(main_thread_checker_.CalledOnValidThread());
DCHECK(renderer);
@@ -403,7 +348,7 @@ bool WebRtcAudioDeviceImpl::SetAudioRenderer(WebRtcAudioRenderer* renderer) {
// Here we acquire |lock_| in order to protect the internal state.
{
base::AutoLock auto_lock(lock_);
- if (renderer_.get())
+ if (renderer_)
return false;
}
@@ -428,7 +373,7 @@ bool WebRtcAudioDeviceImpl::SetAudioRenderer(WebRtcAudioRenderer* renderer) {
// We acquire |lock_| again and assert our precondition, since we are
// accessing the internal state again.
base::AutoLock auto_lock(lock_);
- DCHECK(!renderer_.get());
+ DCHECK(!renderer_);
renderer_ = renderer;
return true;
}
@@ -441,8 +386,7 @@ void WebRtcAudioDeviceImpl::AddAudioCapturer(
DCHECK(!capturer->device().id.empty());
base::AutoLock auto_lock(lock_);
- DCHECK(std::find(capturers_.begin(), capturers_.end(), capturer) ==
- capturers_.end());
+ DCHECK(!base::ContainsValue(capturers_, capturer));
capturers_.push_back(capturer);
}
@@ -460,8 +404,7 @@ void WebRtcAudioDeviceImpl::AddPlayoutSink(
DCHECK(main_thread_checker_.CalledOnValidThread());
DCHECK(sink);
base::AutoLock auto_lock(lock_);
- DCHECK(std::find(playout_sinks_.begin(), playout_sinks_.end(), sink) ==
- playout_sinks_.end());
+ DCHECK(!base::ContainsValue(playout_sinks_, sink));
playout_sinks_.push_back(sink);
}
diff --git a/chromium/content/renderer/media/webrtc_audio_device_impl.h b/chromium/content/renderer/media/webrtc_audio_device_impl.h
index c2939fae986..15606bf5e9d 100644
--- a/chromium/content/renderer/media/webrtc_audio_device_impl.h
+++ b/chromium/content/renderer/media/webrtc_audio_device_impl.h
@@ -260,12 +260,9 @@ class CONTENT_EXPORT WebRtcAudioDeviceImpl : public WebRtcAudioDeviceNotImpl,
// Instances of this object are created on the main render thread.
WebRtcAudioDeviceImpl();
- // webrtc::RefCountedModule implementation.
- // The creator must call AddRef() after construction and use Release()
- // to release the reference and delete this object.
- // Called on the main render thread.
- int32_t AddRef() const override;
- int32_t Release() const override;
+ protected:
+ // Make destructor protected, we should only be deleted by Release().
+ ~WebRtcAudioDeviceImpl() override;
private:
// webrtc::AudioDeviceModule implementation.
@@ -303,9 +300,6 @@ class CONTENT_EXPORT WebRtcAudioDeviceImpl : public WebRtcAudioDeviceNotImpl,
int32_t StereoPlayoutIsAvailable(bool* available) const override;
int32_t StereoRecordingIsAvailable(bool* available) const override;
int32_t PlayoutDelay(uint16_t* delay_ms) const override;
- int32_t RecordingDelay(uint16_t* delay_ms) const override;
- int32_t RecordingSampleRate(uint32_t* sample_rate) const override;
- int32_t PlayoutSampleRate(uint32_t* sample_rate) const override;
public:
// Sets the |renderer_|, returns false if |renderer_| already exists.
@@ -338,9 +332,6 @@ class CONTENT_EXPORT WebRtcAudioDeviceImpl : public WebRtcAudioDeviceNotImpl,
typedef std::list<WebRtcPlayoutDataSource::Sink*> PlayoutDataSinkList;
class RenderBuffer;
- // Make destructor private to ensure that we can only be deleted by Release().
- ~WebRtcAudioDeviceImpl() override;
-
// WebRtcAudioRendererSource implementation.
// Called on the AudioOutputDevice worker thread.
@@ -364,8 +355,6 @@ class CONTENT_EXPORT WebRtcAudioDeviceImpl : public WebRtcAudioDeviceNotImpl,
base::ThreadChecker worker_thread_checker_;
base::ThreadChecker audio_renderer_thread_checker_;
- mutable int ref_count_;
-
// List of captures which provides access to the native audio input layer
// in the browser process. The last capturer in this list is considered the
// "default capturer" by the methods implementing the
diff --git a/chromium/content/renderer/media/webrtc_audio_device_not_impl.cc b/chromium/content/renderer/media/webrtc_audio_device_not_impl.cc
index 7847e814dc5..ee25ec22ed4 100644
--- a/chromium/content/renderer/media/webrtc_audio_device_not_impl.cc
+++ b/chromium/content/renderer/media/webrtc_audio_device_not_impl.cc
@@ -13,11 +13,6 @@ int32_t WebRtcAudioDeviceNotImpl::ActiveAudioLayer(
return 0;
}
-webrtc::AudioDeviceModule::ErrorCode
-WebRtcAudioDeviceNotImpl::LastError() const {
- return AudioDeviceModule::kAdmErrNone;
-}
-
int16_t WebRtcAudioDeviceNotImpl::PlayoutDevices() {
return 0;
}
@@ -142,33 +137,6 @@ int32_t WebRtcAudioDeviceNotImpl::StereoRecording(bool* enabled) const {
return 0;
}
-int32_t WebRtcAudioDeviceNotImpl::SetRecordingChannel(
- const ChannelType channel) {
- return 0;
-}
-
-int32_t WebRtcAudioDeviceNotImpl::RecordingChannel(ChannelType* channel) const {
- return 0;
-}
-
-int32_t WebRtcAudioDeviceNotImpl::SetRecordingSampleRate(
- const uint32_t samples_per_sec) {
- return 0;
-}
-
-int32_t WebRtcAudioDeviceNotImpl::SetPlayoutSampleRate(
- const uint32_t samples_per_sec) {
- return 0;
-}
-
-int32_t WebRtcAudioDeviceNotImpl::SetLoudspeakerStatus(bool enable) {
- return 0;
-}
-
-int32_t WebRtcAudioDeviceNotImpl::GetLoudspeakerStatus(bool* enabled) const {
- return 0;
-}
-
int32_t WebRtcAudioDeviceNotImpl::SetAGC(bool enable) {
return 0;
}
diff --git a/chromium/content/renderer/media/webrtc_audio_device_not_impl.h b/chromium/content/renderer/media/webrtc_audio_device_not_impl.h
index d0c508263a7..824e5d9739b 100644
--- a/chromium/content/renderer/media/webrtc_audio_device_not_impl.h
+++ b/chromium/content/renderer/media/webrtc_audio_device_not_impl.h
@@ -31,7 +31,6 @@ class CONTENT_EXPORT WebRtcAudioDeviceNotImpl
// implementation in WebRtcAudioDeviceImpl when needed.
int32_t ActiveAudioLayer(AudioLayer* audio_layer) const override;
- webrtc::AudioDeviceModule::ErrorCode LastError() const override;
int16_t PlayoutDevices() override;
int16_t RecordingDevices() override;
int32_t PlayoutDeviceName(uint16_t index,
@@ -66,12 +65,6 @@ class CONTENT_EXPORT WebRtcAudioDeviceNotImpl
int32_t StereoPlayout(bool* enabled) const override;
int32_t SetStereoRecording(bool enable) override;
int32_t StereoRecording(bool* enabled) const override;
- int32_t SetRecordingChannel(const ChannelType channel) override;
- int32_t RecordingChannel(ChannelType* channel) const override;
- int32_t SetRecordingSampleRate(const uint32_t samples_per_sec) override;
- int32_t SetPlayoutSampleRate(const uint32_t samples_per_sec) override;
- int32_t SetLoudspeakerStatus(bool enable) override;
- int32_t GetLoudspeakerStatus(bool* enabled) const override;
int32_t SetAGC(bool enable) override;
bool AGC() const override;
bool BuiltInAECIsAvailable() const override;
diff --git a/chromium/content/renderer/media/webrtc_audio_renderer.cc b/chromium/content/renderer/media/webrtc_audio_renderer.cc
index b269e1d6f04..1951725c622 100644
--- a/chromium/content/renderer/media/webrtc_audio_renderer.cc
+++ b/chromium/content/renderer/media/webrtc_audio_renderer.cc
@@ -173,7 +173,7 @@ WebRtcAudioRenderer::WebRtcAudioRenderer(
session_id_(session_id),
signaling_thread_(signaling_thread),
media_stream_(media_stream),
- source_(NULL),
+ source_(nullptr),
play_ref_count_(0),
start_ref_count_(0),
sink_params_(kFormat, kChannelLayout, 0, kBitsPerSample, 0),
@@ -324,7 +324,7 @@ void WebRtcAudioRenderer::Stop() {
DVLOG(1) << "Calling RemoveAudioRenderer and Stop().";
source_->RemoveAudioRenderer(this);
- source_ = NULL;
+ source_ = nullptr;
state_ = UNINITIALIZED;
}
diff --git a/chromium/content/renderer/media/webrtc_logging.cc b/chromium/content/renderer/media/webrtc_logging.cc
index 572c3a05430..c2e90575844 100644
--- a/chromium/content/renderer/media/webrtc_logging.cc
+++ b/chromium/content/renderer/media/webrtc_logging.cc
@@ -11,7 +11,7 @@
namespace content {
// Shall only be set once and never go back to NULL.
-WebRtcLogMessageDelegate* g_webrtc_logging_delegate = NULL;
+WebRtcLogMessageDelegate* g_webrtc_logging_delegate = nullptr;
void InitWebRtcLoggingDelegate(WebRtcLogMessageDelegate* delegate) {
CHECK(!g_webrtc_logging_delegate);
diff --git a/chromium/content/renderer/media_capture_from_element/canvas_capture_handler.cc b/chromium/content/renderer/media_capture_from_element/canvas_capture_handler.cc
index bd7eea16199..8cbf497c8aa 100644
--- a/chromium/content/renderer/media_capture_from_element/canvas_capture_handler.cc
+++ b/chromium/content/renderer/media_capture_from_element/canvas_capture_handler.cc
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/rand_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/viz/common/gl_helper.h"
#include "content/public/renderer/render_thread.h"
#include "content/renderer/media/media_stream_video_capturer_source.h"
#include "content/renderer/media/media_stream_video_source.h"
@@ -18,19 +19,15 @@
#include "content/renderer/media/webrtc_uma_histograms.h"
#include "content/renderer/render_thread_impl.h"
#include "media/base/limits.h"
+#include "skia/ext/texture_handle.h"
+#include "third_party/WebKit/public/platform/WebGraphicsContext3DProvider.h"
#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/libyuv/include/libyuv.h"
#include "third_party/skia/include/core/SkImage.h"
-namespace {
-
using media::VideoFrame;
-const size_t kArgbBytesPerPixel = 4;
-
-} // namespace
-
namespace content {
// Implementation VideoCapturerSource that is owned by
@@ -40,8 +37,10 @@ namespace content {
class VideoCapturerSource : public media::VideoCapturerSource {
public:
VideoCapturerSource(base::WeakPtr<CanvasCaptureHandler> canvas_handler,
+ const blink::WebSize& size,
double frame_rate)
- : frame_rate_(static_cast<float>(
+ : size_(size),
+ frame_rate_(static_cast<float>(
std::min(static_cast<double>(media::limits::kMaxFramesPerSecond),
frame_rate))),
canvas_handler_(canvas_handler) {
@@ -51,14 +50,11 @@ class VideoCapturerSource : public media::VideoCapturerSource {
protected:
media::VideoCaptureFormats GetPreferredFormats() override {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
- const blink::WebSize& size = canvas_handler_->GetSourceSize();
media::VideoCaptureFormats formats;
- formats.push_back(
- media::VideoCaptureFormat(gfx::Size(size.width, size.height),
- frame_rate_, media::PIXEL_FORMAT_I420));
- formats.push_back(
- media::VideoCaptureFormat(gfx::Size(size.width, size.height),
- frame_rate_, media::PIXEL_FORMAT_YV12A));
+ formats.push_back(media::VideoCaptureFormat(size_, frame_rate_,
+ media::PIXEL_FORMAT_I420));
+ formats.push_back(media::VideoCaptureFormat(size_, frame_rate_,
+ media::PIXEL_FORMAT_YV12A));
return formats;
}
void StartCapture(const media::VideoCaptureParams& params,
@@ -79,6 +75,7 @@ class VideoCapturerSource : public media::VideoCapturerSource {
}
private:
+ const blink::WebSize size_;
const float frame_rate_;
// Bound to Main Render thread.
base::ThreadChecker main_render_thread_checker_;
@@ -91,19 +88,17 @@ class CanvasCaptureHandler::CanvasCaptureHandlerDelegate {
public:
explicit CanvasCaptureHandlerDelegate(
media::VideoCapturerSource::VideoCaptureDeliverFrameCB new_frame_callback)
- : new_frame_callback_(new_frame_callback),
- weak_ptr_factory_(this) {
+ : new_frame_callback_(new_frame_callback), weak_ptr_factory_(this) {
io_thread_checker_.DetachFromThread();
}
~CanvasCaptureHandlerDelegate() {
DCHECK(io_thread_checker_.CalledOnValidThread());
}
- void SendNewFrameOnIOThread(
- const scoped_refptr<media::VideoFrame>& video_frame,
- const base::TimeTicks& current_time) {
+ void SendNewFrameOnIOThread(scoped_refptr<VideoFrame> video_frame,
+ base::TimeTicks current_time) {
DCHECK(io_thread_checker_.CalledOnValidThread());
- new_frame_callback_.Run(video_frame, current_time);
+ new_frame_callback_.Run(std::move(video_frame), current_time);
}
base::WeakPtr<CanvasCaptureHandlerDelegate> GetWeakPtrForIOThread() {
@@ -123,14 +118,14 @@ class CanvasCaptureHandler::CanvasCaptureHandlerDelegate {
CanvasCaptureHandler::CanvasCaptureHandler(
const blink::WebSize& size,
double frame_rate,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
blink::WebMediaStreamTrack* track)
: ask_for_new_frame_(false),
- size_(size),
- io_task_runner_(io_task_runner),
+ io_task_runner_(std::move(io_task_runner)),
weak_ptr_factory_(this) {
std::unique_ptr<media::VideoCapturerSource> video_source(
- new VideoCapturerSource(weak_ptr_factory_.GetWeakPtr(), frame_rate));
+ new VideoCapturerSource(weak_ptr_factory_.GetWeakPtr(), size,
+ frame_rate));
AddVideoCapturerSourceToVideoTrack(std::move(video_source), track);
}
@@ -145,19 +140,56 @@ std::unique_ptr<CanvasCaptureHandler>
CanvasCaptureHandler::CreateCanvasCaptureHandler(
const blink::WebSize& size,
double frame_rate,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
blink::WebMediaStreamTrack* track) {
// Save histogram data so we can see how much CanvasCapture is used.
// The histogram counts the number of calls to the JS API.
UpdateWebRTCMethodCount(WEBKIT_CANVAS_CAPTURE_STREAM);
- return std::unique_ptr<CanvasCaptureHandler>(
- new CanvasCaptureHandler(size, frame_rate, io_task_runner, track));
+ return std::unique_ptr<CanvasCaptureHandler>(new CanvasCaptureHandler(
+ size, frame_rate, std::move(io_task_runner), track));
}
-void CanvasCaptureHandler::SendNewFrame(const SkImage* image) {
+void CanvasCaptureHandler::SendNewFrame(
+ sk_sp<SkImage> image,
+ blink::WebGraphicsContext3DProvider* context_provider) {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
- CreateNewFrame(image);
+ DCHECK(image);
+ TRACE_EVENT0("webrtc", "CanvasCaptureHandler::SendNewFrame");
+
+ // Initially try accessing pixels directly if they are in memory.
+ SkPixmap pixmap;
+ if (image->peekPixels(&pixmap) &&
+ (pixmap.colorType() == kRGBA_8888_SkColorType ||
+ pixmap.colorType() == kBGRA_8888_SkColorType) &&
+ (pixmap.alphaType() == kUnpremul_SkAlphaType || image->isOpaque())) {
+ const base::TimeTicks timestamp = base::TimeTicks::Now();
+ SendFrame(ConvertToYUVFrame(image->isOpaque(), false,
+ static_cast<const uint8*>(pixmap.addr(0, 0)),
+ gfx::Size(pixmap.width(), pixmap.height()),
+ pixmap.rowBytes(), pixmap.colorType()),
+ timestamp);
+ return;
+ }
+
+ // Copy the pixels into memory synchronously. This call may block the main
+ // render thread.
+ if (!image->isTextureBacked()) {
+ ReadARGBPixelsSync(image);
+ return;
+ }
+
+ if (!context_provider) {
+ DLOG(ERROR) << "Context lost, skipping frame";
+ return;
+ }
+
+ // Try async reading SkImage if it is texture backed.
+ if (image->isOpaque()) {
+ ReadYUVPixelsAsync(image, context_provider);
+ } else {
+ ReadARGBPixelsAsync(image, context_provider);
+ }
}
bool CanvasCaptureHandler::NeedsNewFrame() const {
@@ -201,98 +233,225 @@ void CanvasCaptureHandler::StopVideoCapture() {
io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release());
}
-void CanvasCaptureHandler::CreateNewFrame(const SkImage* image) {
- DVLOG(4) << __func__;
+void CanvasCaptureHandler::ReadARGBPixelsSync(sk_sp<SkImage> image) {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
- DCHECK(image);
- TRACE_EVENT0("webrtc", "CanvasCaptureHandler::CreateNewFrame");
- const uint8_t* source_ptr = nullptr;
- size_t source_length = 0;
- size_t source_stride = 0;
- gfx::Size image_size(image->width(), image->height());
- SkColorType source_color_type = kUnknown_SkColorType;
-
- // Initially try accessing pixels directly if they are in memory.
- SkPixmap pixmap;
- if (image->peekPixels(&pixmap) &&
- (pixmap.colorType() == kRGBA_8888_SkColorType ||
- pixmap.colorType() == kBGRA_8888_SkColorType) &&
- pixmap.alphaType() == kUnpremul_SkAlphaType) {
- source_ptr = static_cast<const uint8*>(pixmap.addr(0, 0));
- source_length = pixmap.computeByteSize();
- source_stride = pixmap.rowBytes();
- image_size.set_width(pixmap.width());
- image_size.set_height(pixmap.height());
- source_color_type = pixmap.colorType();
+ const base::TimeTicks timestamp = base::TimeTicks::Now();
+ const gfx::Size image_size(image->width(), image->height());
+ scoped_refptr<VideoFrame> temp_argb_frame = frame_pool_.CreateFrame(
+ media::PIXEL_FORMAT_ARGB, image_size, gfx::Rect(image_size), image_size,
+ base::TimeDelta());
+ if (!temp_argb_frame) {
+ DLOG(ERROR) << "Couldn't allocate video frame";
+ return;
}
+ const bool is_opaque = image->isOpaque();
+ SkImageInfo image_info = SkImageInfo::MakeN32(
+ image_size.width(), image_size.height(),
+ is_opaque ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
+ if (!image->readPixels(image_info,
+ temp_argb_frame->visible_data(VideoFrame::kARGBPlane),
+ temp_argb_frame->stride(VideoFrame::kARGBPlane),
+ 0 /*srcX*/, 0 /*srcY*/)) {
+ DLOG(ERROR) << "Couldn't read SkImage using readPixels()";
+ return;
+ }
+ SendFrame(
+ ConvertToYUVFrame(
+ is_opaque, false /* flip */,
+ temp_argb_frame->visible_data(VideoFrame::kARGBPlane), image_size,
+ temp_argb_frame->stride(VideoFrame::kARGBPlane), kN32_SkColorType),
+ timestamp);
+}
+
+void CanvasCaptureHandler::ReadARGBPixelsAsync(
+ sk_sp<SkImage> image,
+ blink::WebGraphicsContext3DProvider* context_provider) {
+ DCHECK(main_render_thread_checker_.CalledOnValidThread());
- // Copy the pixels into memory. This call may block main render thread.
- if (!source_ptr) {
- if (image_size != last_size) {
- temp_data_stride_ = kArgbBytesPerPixel * image_size.width();
- temp_data_.resize(temp_data_stride_ * image_size.height());
- image_info_ = SkImageInfo::MakeN32(
- image_size.width(), image_size.height(), kUnpremul_SkAlphaType);
- last_size = image_size;
- }
- if (image->readPixels(image_info_, &temp_data_[0], temp_data_stride_, 0,
- 0)) {
- source_ptr = temp_data_.data();
- source_length = temp_data_.size();
- source_stride = temp_data_stride_;
- source_color_type = kN32_SkColorType;
- } else {
- DLOG(ERROR) << "Couldn't read SkImage pixels";
- return;
- }
+ const base::TimeTicks timestamp = base::TimeTicks::Now();
+ const gfx::Size image_size(image->width(), image->height());
+ scoped_refptr<VideoFrame> temp_argb_frame = frame_pool_.CreateFrame(
+ media::PIXEL_FORMAT_ARGB, image_size, gfx::Rect(image_size), image_size,
+ base::TimeDelta());
+ if (!temp_argb_frame) {
+ DLOG(ERROR) << "Couldn't allocate video frame";
+ return;
}
+ GrSurfaceOrigin surface_origin = kTopLeft_GrSurfaceOrigin;
+ const GrGLTextureInfo* texture_info = skia::GrBackendObjectToGrGLTextureInfo(
+ image->getTextureHandle(true, &surface_origin));
+ DCHECK(texture_info);
+ DCHECK(context_provider->GetGLHelper());
+ context_provider->GetGLHelper()->ReadbackTextureAsync(
+ texture_info->fID, image_size,
+ temp_argb_frame->visible_data(VideoFrame::kARGBPlane), kN32_SkColorType,
+ base::Bind(&CanvasCaptureHandler::OnARGBPixelsReadAsync,
+ weak_ptr_factory_.GetWeakPtr(), image, temp_argb_frame,
+ timestamp, surface_origin != kTopLeft_GrSurfaceOrigin));
+}
+
+void CanvasCaptureHandler::ReadYUVPixelsAsync(
+ sk_sp<SkImage> image,
+ blink::WebGraphicsContext3DProvider* context_provider) {
+ DCHECK(main_render_thread_checker_.CalledOnValidThread());
- const bool isOpaque = image->isOpaque();
const base::TimeTicks timestamp = base::TimeTicks::Now();
- scoped_refptr<media::VideoFrame> video_frame = frame_pool_.CreateFrame(
- isOpaque ? media::PIXEL_FORMAT_I420 : media::PIXEL_FORMAT_YV12A,
- image_size, gfx::Rect(image_size), image_size,
- timestamp - base::TimeTicks());
- DCHECK(video_frame);
- libyuv::FourCC source_pixel_format = libyuv::FOURCC_ANY;
+ const gfx::Size image_size(image->width(), image->height());
+ scoped_refptr<VideoFrame> output_frame = frame_pool_.CreateFrame(
+ media::PIXEL_FORMAT_I420, image_size, gfx::Rect(image_size), image_size,
+ base::TimeDelta());
+ if (!output_frame) {
+ DLOG(ERROR) << "Couldn't allocate video frame";
+ return;
+ }
+
+ GrSurfaceOrigin surface_origin = kTopLeft_GrSurfaceOrigin;
+ const GrGLTextureInfo* texture_info = skia::GrBackendObjectToGrGLTextureInfo(
+ image->getTextureHandle(true, &surface_origin));
+ DCHECK(texture_info);
+ DCHECK(context_provider->GetGLHelper());
+ const gpu::MailboxHolder& mailbox_holder =
+ context_provider->GetGLHelper()->ProduceMailboxHolderFromTexture(
+ texture_info->fID);
+ DCHECK_EQ(static_cast<int>(texture_info->fTarget), GL_TEXTURE_2D);
+ viz::ReadbackYUVInterface* const yuv_reader =
+ context_provider->GetGLHelper()->GetReadbackPipelineYUV(
+ surface_origin != kTopLeft_GrSurfaceOrigin);
+ yuv_reader->ReadbackYUV(
+ mailbox_holder.mailbox, mailbox_holder.sync_token, image_size,
+ gfx::Rect(image_size), output_frame->stride(media::VideoFrame::kYPlane),
+ output_frame->visible_data(media::VideoFrame::kYPlane),
+ output_frame->stride(media::VideoFrame::kUPlane),
+ output_frame->visible_data(media::VideoFrame::kUPlane),
+ output_frame->stride(media::VideoFrame::kVPlane),
+ output_frame->visible_data(media::VideoFrame::kVPlane), gfx::Point(0, 0),
+ base::Bind(&CanvasCaptureHandler::OnYUVPixelsReadAsync,
+ weak_ptr_factory_.GetWeakPtr(), image, output_frame,
+ timestamp));
+ context_provider->InvalidateGrContext(
+ viz::ReadbackYUVInterface::GetGrGLBackendStateChanges());
+}
+
+void CanvasCaptureHandler::OnARGBPixelsReadAsync(
+ sk_sp<SkImage> image,
+ scoped_refptr<media::VideoFrame> temp_argb_frame,
+ base::TimeTicks this_frame_ticks,
+ bool flip,
+ bool success) {
+ DCHECK(main_render_thread_checker_.CalledOnValidThread());
+ if (!success) {
+ DLOG(ERROR) << "Couldn't read SkImage using async callback";
+ // Async reading is not supported on some platforms, see
+ // http://crbug.com/788386.
+ ReadARGBPixelsSync(image);
+ return;
+ }
+ // Let |image| fall out of scope after we are done reading.
+ const bool is_opaque = image->isOpaque();
+ image = nullptr;
+
+ SendFrame(
+ ConvertToYUVFrame(is_opaque, flip,
+ temp_argb_frame->visible_data(VideoFrame::kARGBPlane),
+ temp_argb_frame->visible_rect().size(),
+ temp_argb_frame->stride(VideoFrame::kARGBPlane),
+ kN32_SkColorType),
+ this_frame_ticks);
+}
+
+void CanvasCaptureHandler::OnYUVPixelsReadAsync(
+ sk_sp<SkImage> /* image */,
+ scoped_refptr<media::VideoFrame> yuv_frame,
+ base::TimeTicks this_frame_ticks,
+ bool success) {
+ DCHECK(main_render_thread_checker_.CalledOnValidThread());
+ if (!success) {
+ DLOG(ERROR) << "Couldn't read SkImage using async callback";
+ return;
+ }
+ SendFrame(yuv_frame, this_frame_ticks);
+}
+
+scoped_refptr<media::VideoFrame> CanvasCaptureHandler::ConvertToYUVFrame(
+ bool is_opaque,
+ bool flip,
+ const uint8_t* source_ptr,
+ const gfx::Size& image_size,
+ int stride,
+ SkColorType source_color_type) {
+ DVLOG(4) << __func__;
+ DCHECK(main_render_thread_checker_.CalledOnValidThread());
+ TRACE_EVENT0("webrtc", "CanvasCaptureHandler::ConvertToYUVFrame");
+
+ scoped_refptr<VideoFrame> video_frame = frame_pool_.CreateFrame(
+ is_opaque ? media::PIXEL_FORMAT_I420 : media::PIXEL_FORMAT_YV12A,
+ image_size, gfx::Rect(image_size), image_size, base::TimeDelta());
+ if (!video_frame) {
+ DLOG(ERROR) << "Couldn't allocate video frame";
+ return nullptr;
+ }
+
+ int (*ConvertToI420)(const uint8* src_argb, int src_stride_argb, uint8* dst_y,
+ int dst_stride_y, uint8* dst_u, int dst_stride_u,
+ uint8* dst_v, int dst_stride_v, int width, int height) =
+ nullptr;
switch (source_color_type) {
case kRGBA_8888_SkColorType:
- source_pixel_format = libyuv::FOURCC_ABGR;
+ ConvertToI420 = libyuv::ABGRToI420;
break;
case kBGRA_8888_SkColorType:
- source_pixel_format = libyuv::FOURCC_ARGB;
+ ConvertToI420 = libyuv::ARGBToI420;
break;
default:
- NOTREACHED() << "Unexpected SkColorType.";
+ NOTIMPLEMENTED() << "Unexpected SkColorType.";
+ return nullptr;
+ }
+
+ if (ConvertToI420(source_ptr, stride,
+ video_frame->visible_data(media::VideoFrame::kYPlane),
+ video_frame->stride(media::VideoFrame::kYPlane),
+ video_frame->visible_data(media::VideoFrame::kUPlane),
+ video_frame->stride(media::VideoFrame::kUPlane),
+ video_frame->visible_data(media::VideoFrame::kVPlane),
+ video_frame->stride(media::VideoFrame::kVPlane),
+ image_size.width(),
+ (flip ? -1 : 1) * image_size.height()) != 0) {
+ DLOG(ERROR) << "Couldn't convert to I420";
+ return nullptr;
}
- libyuv::ConvertToI420(source_ptr, source_length,
- video_frame->visible_data(media::VideoFrame::kYPlane),
- video_frame->stride(media::VideoFrame::kYPlane),
- video_frame->visible_data(media::VideoFrame::kUPlane),
- video_frame->stride(media::VideoFrame::kUPlane),
- video_frame->visible_data(media::VideoFrame::kVPlane),
- video_frame->stride(media::VideoFrame::kVPlane),
- 0 /* crop_x */, 0 /* crop_y */, image_size.width(),
- image_size.height(), image_size.width(),
- image_size.height(), libyuv::kRotate0,
- source_pixel_format);
- if (!isOpaque) {
+ if (!is_opaque) {
// It is ok to use ARGB function because alpha has the same alignment for
// both ABGR and ARGB.
- libyuv::ARGBExtractAlpha(source_ptr, source_stride,
- video_frame->visible_data(VideoFrame::kAPlane),
- video_frame->stride(VideoFrame::kAPlane),
- image_size.width(), image_size.height());
+ libyuv::ARGBExtractAlpha(
+ source_ptr, stride, video_frame->visible_data(VideoFrame::kAPlane),
+ video_frame->stride(VideoFrame::kAPlane), image_size.width(),
+ (flip ? -1 : 1) * image_size.height());
}
+ return video_frame;
+}
+
+void CanvasCaptureHandler::SendFrame(scoped_refptr<VideoFrame> video_frame,
+ base::TimeTicks this_frame_ticks) {
+ DCHECK(main_render_thread_checker_.CalledOnValidThread());
+
+ // If this function is called asynchronously, |delegate_| might have been
+ // released already in StopVideoCapture().
+ if (!delegate_ || !video_frame)
+ return;
+
+ if (!first_frame_ticks_)
+ first_frame_ticks_ = this_frame_ticks;
+ video_frame->set_timestamp(this_frame_ticks - *first_frame_ticks_);
+
last_frame_ = video_frame;
io_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&CanvasCaptureHandler::CanvasCaptureHandlerDelegate::
SendNewFrameOnIOThread,
- delegate_->GetWeakPtrForIOThread(), video_frame,
- timestamp));
+ delegate_->GetWeakPtrForIOThread(), std::move(video_frame),
+ this_frame_ticks));
}
void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack(
diff --git a/chromium/content/renderer/media_capture_from_element/canvas_capture_handler.h b/chromium/content/renderer/media_capture_from_element/canvas_capture_handler.h
index 548426598a1..d9f28613b51 100644
--- a/chromium/content/renderer/media_capture_from_element/canvas_capture_handler.h
+++ b/chromium/content/renderer/media_capture_from_element/canvas_capture_handler.h
@@ -45,11 +45,13 @@ class CONTENT_EXPORT CanvasCaptureHandler final
static std::unique_ptr<CanvasCaptureHandler> CreateCanvasCaptureHandler(
const blink::WebSize& size,
double frame_rate,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
blink::WebMediaStreamTrack* track);
- // blink::WebCanvasCaptureHandler Implementation.
- void SendNewFrame(const SkImage* image) override;
+ // blink::WebCanvasCaptureHandler implementation.
+ void SendNewFrame(
+ sk_sp<SkImage> image,
+ blink::WebGraphicsContext3DProvider* context_provider) override;
bool NeedsNewFrame() const override;
// Functions called by media::VideoCapturerSource implementation.
@@ -60,7 +62,6 @@ class CONTENT_EXPORT CanvasCaptureHandler final
const media::VideoCapturerSource::RunningCallback& running_callback);
void RequestRefreshFrame();
void StopVideoCapture();
- blink::WebSize GetSourceSize() const { return size_; }
private:
// A VideoCapturerSource instance is created, which is responsible for handing
@@ -70,10 +71,37 @@ class CONTENT_EXPORT CanvasCaptureHandler final
CanvasCaptureHandler(
const blink::WebSize& size,
double frame_rate,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
blink::WebMediaStreamTrack* track);
- void CreateNewFrame(const SkImage* image);
+ // Helper functions to read pixel content.
+ void ReadARGBPixelsSync(sk_sp<SkImage> image);
+ void ReadARGBPixelsAsync(
+ sk_sp<SkImage> image,
+ blink::WebGraphicsContext3DProvider* context_provider);
+ void ReadYUVPixelsAsync(
+ sk_sp<SkImage> image,
+ blink::WebGraphicsContext3DProvider* context_provider);
+ void OnARGBPixelsReadAsync(sk_sp<SkImage> image,
+ scoped_refptr<media::VideoFrame> temp_argb_frame,
+ base::TimeTicks this_frame_ticks,
+ bool flip,
+ bool success);
+ void OnYUVPixelsReadAsync(sk_sp<SkImage> image,
+ scoped_refptr<media::VideoFrame> yuv_frame,
+ base::TimeTicks this_frame_ticks,
+ bool success);
+
+ scoped_refptr<media::VideoFrame> ConvertToYUVFrame(
+ bool is_opaque,
+ bool flip,
+ const uint8_t* source_ptr,
+ const gfx::Size& image_size,
+ int stride,
+ SkColorType source_color_type);
+ void SendFrame(scoped_refptr<media::VideoFrame> video_frame,
+ base::TimeTicks this_frame_ticks);
+
void AddVideoCapturerSourceToVideoTrack(
std::unique_ptr<media::VideoCapturerSource> source,
blink::WebMediaStreamTrack* web_track);
@@ -84,14 +112,8 @@ class CONTENT_EXPORT CanvasCaptureHandler final
media::VideoCaptureFormat capture_format_;
bool ask_for_new_frame_;
-
- const blink::WebSize size_;
- gfx::Size last_size;
- std::vector<uint8_t> temp_data_;
- size_t temp_data_stride_;
- SkImageInfo image_info_;
media::VideoFramePool frame_pool_;
-
+ base::Optional<base::TimeTicks> first_frame_ticks_;
scoped_refptr<media::VideoFrame> last_frame_;
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
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 c3af903bd88..ef921206488 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
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/renderer/media_capture_from_element/canvas_capture_handler.h"
+
#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/test/scoped_task_environment.h"
#include "content/child/child_process.h"
#include "content/renderer/media/media_stream_video_capturer_source.h"
-#include "content/renderer/media_capture_from_element/canvas_capture_handler.h"
#include "media/base/limits.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -48,13 +48,15 @@ ACTION_P(RunClosure, closure) {
class CanvasCaptureHandlerTest
: public TestWithParam<testing::tuple<bool, int, int>> {
public:
- CanvasCaptureHandlerTest() {}
+ CanvasCaptureHandlerTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
void SetUp() override {
canvas_capture_handler_ = CanvasCaptureHandler::CreateCanvasCaptureHandler(
blink::WebSize(kTestCanvasCaptureWidth, kTestCanvasCaptureHeight),
- kTestCanvasCaptureFramesPerSecond, message_loop_.task_runner(),
- &track_);
+ kTestCanvasCaptureFramesPerSecond,
+ scoped_task_environment_.GetMainThreadTaskRunner(), &track_);
}
void TearDown() override {
@@ -96,8 +98,6 @@ class CanvasCaptureHandlerTest
else
EXPECT_EQ(media::PIXEL_FORMAT_YV12A, video_frame->format());
- EXPECT_EQ(video_frame->timestamp().InMilliseconds(),
- (estimated_capture_time - base::TimeTicks()).InMilliseconds());
const gfx::Size& size = video_frame->visible_rect().size();
EXPECT_EQ(expected_width, size.width());
EXPECT_EQ(expected_height, size.height());
@@ -127,9 +127,10 @@ class CanvasCaptureHandlerTest
return ms_source->source_.get();
}
- // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks
- // and Sources into believing they are on the right threads.
- base::MessageLoopForUI message_loop_;
+ // A ChildProcess is needed to fool the Tracks and Sources believing they are
+ // on the right threads. A ScopedTaskEnvironment must be instantiated before
+ // ChildProcess to prevent it from leaking a TaskScheduler.
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
ChildProcess child_process_;
private:
@@ -188,8 +189,8 @@ TEST_P(CanvasCaptureHandlerTest, GetFormatsStartAndStop) {
canvas_capture_handler_->SendNewFrame(
GenerateTestImage(testing::get<0>(GetParam()),
testing::get<1>(GetParam()),
- testing::get<2>(GetParam()))
- .get());
+ testing::get<2>(GetParam())),
+ nullptr);
run_loop.Run();
source->StopCapture();
@@ -210,11 +211,12 @@ TEST_P(CanvasCaptureHandlerTest, VerifyFrame) {
EXPECT_CALL(*this, DoOnRunning(true)).Times(1);
media::VideoCaptureParams params;
source->StartCapture(
- params, base::Bind(&CanvasCaptureHandlerTest::OnVerifyDeliveredFrame,
- base::Unretained(this), opaque_frame, width, height),
+ params,
+ base::Bind(&CanvasCaptureHandlerTest::OnVerifyDeliveredFrame,
+ base::Unretained(this), opaque_frame, width, height),
base::Bind(&CanvasCaptureHandlerTest::OnRunning, base::Unretained(this)));
canvas_capture_handler_->SendNewFrame(
- GenerateTestImage(opaque_frame, width, height).get());
+ GenerateTestImage(opaque_frame, width, height), nullptr);
run_loop.RunUntilIdle();
}
diff --git a/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source.cc b/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source.cc
index 1d1e3ca5637..6edea073991 100644
--- a/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source.cc
+++ b/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source.cc
@@ -90,7 +90,7 @@ void HtmlVideoElementCapturerSource::StartCapture(
running_callback_.Run(false);
return;
}
- canvas_ = base::MakeUnique<cc::SkiaPaintCanvas>(bitmap_);
+ canvas_ = std::make_unique<cc::SkiaPaintCanvas>(bitmap_);
new_frame_callback_ = new_frame_callback;
// Force |capture_frame_rate_| to be in between k{Min,Max}FramesPerSecond.
diff --git a/chromium/content/renderer/media_recorder/audio_track_encoder.cc b/chromium/content/renderer/media_recorder/audio_track_encoder.cc
new file mode 100644
index 00000000000..6e1c6470b82
--- /dev/null
+++ b/chromium/content/renderer/media_recorder/audio_track_encoder.cc
@@ -0,0 +1,20 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media_recorder/audio_track_encoder.h"
+
+namespace content {
+
+AudioTrackEncoder::AudioTrackEncoder(OnEncodedAudioCB on_encoded_audio_cb)
+ : paused_(false), on_encoded_audio_cb_(std::move(on_encoded_audio_cb)) {
+ // AudioTrackEncoder is constructed on the thread that ATR lives on, but
+ // should operate only on the encoder thread after that. Reset
+ // |encoder_thread_checker_| here, as the next call to CalledOnValidThread()
+ // will be from the encoder thread.
+ DETACH_FROM_THREAD(encoder_thread_checker_);
+}
+
+AudioTrackEncoder::~AudioTrackEncoder() {}
+
+} // namespace content
diff --git a/chromium/content/renderer/media_recorder/audio_track_encoder.h b/chromium/content/renderer/media_recorder/audio_track_encoder.h
new file mode 100644
index 00000000000..048a736b65d
--- /dev/null
+++ b/chromium/content/renderer/media_recorder/audio_track_encoder.h
@@ -0,0 +1,62 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_RECORDER_AUDIO_TRACK_ENCODER_H_
+#define CONTENT_RENDERER_MEDIA_RECORDER_AUDIO_TRACK_ENCODER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_checker.h"
+#include "base/time/time.h"
+#include "media/base/audio_bus.h"
+#include "media/base/audio_parameters.h"
+
+namespace content {
+
+// Base interface for an AudioTrackEncoder. This class and its subclasses are
+// used by AudioTrackRecorder to encode audio before output. These are private
+// classes and should not be used outside of AudioTrackRecorder.
+//
+// AudioTrackEncoder is created and destroyed on ATR's main thread (usually the
+// main render thread) but otherwise should operate entirely on
+// |encoder_thread_|, which is owned by AudioTrackRecorder. Be sure to delete
+// |encoder_thread_| before deleting the AudioTrackEncoder using it.
+class AudioTrackEncoder : public base::RefCountedThreadSafe<AudioTrackEncoder> {
+ public:
+ using OnEncodedAudioCB =
+ base::Callback<void(const media::AudioParameters& params,
+ std::unique_ptr<std::string> encoded_data,
+ base::TimeTicks capture_time)>;
+
+ explicit AudioTrackEncoder(OnEncodedAudioCB on_encoded_audio_cb);
+
+ virtual void OnSetFormat(const media::AudioParameters& params) = 0;
+ virtual void EncodeAudio(std::unique_ptr<media::AudioBus> audio_bus,
+ base::TimeTicks capture_time) = 0;
+
+ void set_paused(bool paused) { paused_ = paused; }
+
+ protected:
+ friend class base::RefCountedThreadSafe<AudioTrackEncoder>;
+
+ virtual ~AudioTrackEncoder();
+
+ bool paused_;
+
+ const OnEncodedAudioCB on_encoded_audio_cb_;
+
+ THREAD_CHECKER(encoder_thread_checker_);
+
+ // The original input audio parameters.
+ media::AudioParameters input_params_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioTrackEncoder);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_RECORDER_AUDIO_TRACK_ENCODER_H_
diff --git a/chromium/content/renderer/media_recorder/audio_track_opus_encoder.cc b/chromium/content/renderer/media_recorder/audio_track_opus_encoder.cc
new file mode 100644
index 00000000000..3f92f4f2ec3
--- /dev/null
+++ b/chromium/content/renderer/media_recorder/audio_track_opus_encoder.cc
@@ -0,0 +1,200 @@
+// Copyright 2017 The Chromium Authors. 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_recorder/audio_track_opus_encoder.h"
+
+#include <string>
+#include <utility>
+
+#include "media/base/audio_sample_types.h"
+#include "media/base/audio_timestamp_helper.h"
+
+namespace {
+
+enum : int {
+ // Recommended value for opus_encode_float(), according to documentation in
+ // third_party/opus/src/include/opus.h, so that the Opus encoder does not
+ // degrade the audio due to memory constraints, and is independent of the
+ // duration of the encoded buffer.
+ kOpusMaxDataBytes = 4000,
+
+ // Opus preferred sampling rate for encoding. This is also the one WebM likes
+ // to have: https://wiki.xiph.org/MatroskaOpus.
+ kOpusPreferredSamplingRate = 48000,
+
+ // For Opus, we try to encode 60ms, the maximum Opus buffer, for quality
+ // reasons.
+ kOpusPreferredBufferDurationMs = 60,
+
+ // Maximum buffer multiplier for the AudioEncoders' AudioFifo. Recording is
+ // not real time, hence a certain buffering is allowed.
+ kMaxNumberOfFifoBuffers = 2,
+};
+
+// The amount of Frames in a 60 ms buffer @ 48000 samples/second.
+const int kOpusPreferredFramesPerBuffer = kOpusPreferredSamplingRate *
+ kOpusPreferredBufferDurationMs /
+ base::Time::kMillisecondsPerSecond;
+
+// Tries to encode |data_in|'s |num_samples| into |data_out|.
+bool DoEncode(OpusEncoder* opus_encoder,
+ float* data_in,
+ int num_samples,
+ std::string* data_out) {
+ DCHECK_EQ(kOpusPreferredFramesPerBuffer, num_samples);
+
+ data_out->resize(kOpusMaxDataBytes);
+ const opus_int32 result = opus_encode_float(
+ opus_encoder, data_in, num_samples,
+ reinterpret_cast<uint8_t*>(base::string_as_array(data_out)),
+ kOpusMaxDataBytes);
+
+ if (result > 1) {
+ // TODO(ajose): Investigate improving this. http://crbug.com/547918
+ data_out->resize(result);
+ return true;
+ }
+ // If |result| in {0,1}, do nothing; the documentation says that a return
+ // value of zero or one means the packet does not need to be transmitted.
+ // Otherwise, we have an error.
+ DLOG_IF(ERROR, result < 0) << " encode failed: " << opus_strerror(result);
+ return false;
+}
+
+} // anonymous namespace
+
+namespace content {
+
+AudioTrackOpusEncoder::AudioTrackOpusEncoder(
+ OnEncodedAudioCB on_encoded_audio_cb,
+ int32_t bits_per_second)
+ : AudioTrackEncoder(std::move(on_encoded_audio_cb)),
+ bits_per_second_(bits_per_second),
+ opus_encoder_(nullptr) {}
+
+AudioTrackOpusEncoder::~AudioTrackOpusEncoder() {
+ // We don't DCHECK that we're on the encoder thread here, as it should have
+ // already been deleted at this point.
+ DestroyExistingOpusEncoder();
+}
+
+double AudioTrackOpusEncoder::ProvideInput(media::AudioBus* audio_bus,
+ uint32_t frames_delayed) {
+ fifo_->Consume(audio_bus, 0, audio_bus->frames());
+ return 1.0;
+}
+
+void AudioTrackOpusEncoder::OnSetFormat(
+ const media::AudioParameters& input_params) {
+ DVLOG(1) << __func__;
+ DCHECK_CALLED_ON_VALID_THREAD(encoder_thread_checker_);
+ if (input_params_.Equals(input_params))
+ return;
+
+ DestroyExistingOpusEncoder();
+
+ if (!input_params.IsValid()) {
+ DLOG(ERROR) << "Invalid params: " << input_params.AsHumanReadableString();
+ return;
+ }
+ input_params_ = input_params;
+ input_params_.set_frames_per_buffer(input_params_.sample_rate() *
+ kOpusPreferredBufferDurationMs /
+ base::Time::kMillisecondsPerSecond);
+
+ // third_party/libopus supports up to 2 channels (see implementation of
+ // opus_encoder_create()): force |converted_params_| to at most those.
+ converted_params_ = media::AudioParameters(
+ media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ media::GuessChannelLayout(std::min(input_params_.channels(), 2)),
+ kOpusPreferredSamplingRate, input_params_.bits_per_sample(),
+ kOpusPreferredFramesPerBuffer);
+ DVLOG(1) << "|input_params_|:" << input_params_.AsHumanReadableString()
+ << " -->|converted_params_|:"
+ << converted_params_.AsHumanReadableString();
+
+ converter_.reset(new media::AudioConverter(input_params_, converted_params_,
+ false /* disable_fifo */));
+ converter_->AddInput(this);
+ converter_->PrimeWithSilence();
+
+ fifo_.reset(new media::AudioFifo(
+ input_params_.channels(),
+ kMaxNumberOfFifoBuffers * input_params_.frames_per_buffer()));
+
+ buffer_.reset(new float[converted_params_.channels() *
+ converted_params_.frames_per_buffer()]);
+
+ // Initialize OpusEncoder.
+ int opus_result;
+ opus_encoder_ = opus_encoder_create(converted_params_.sample_rate(),
+ converted_params_.channels(),
+ OPUS_APPLICATION_AUDIO, &opus_result);
+ if (opus_result < 0) {
+ DLOG(ERROR) << "Couldn't init Opus encoder: " << opus_strerror(opus_result)
+ << ", sample rate: " << converted_params_.sample_rate()
+ << ", channels: " << converted_params_.channels();
+ return;
+ }
+
+ // Note: As of 2013-10-31, the encoder in "auto bitrate" mode would use a
+ // variable bitrate up to 102kbps for 2-channel, 48 kHz audio and a 10 ms
+ // buffer duration. The Opus library authors may, of course, adjust this in
+ // later versions.
+ const opus_int32 bitrate =
+ (bits_per_second_ > 0) ? bits_per_second_ : OPUS_AUTO;
+ if (opus_encoder_ctl(opus_encoder_, OPUS_SET_BITRATE(bitrate)) != OPUS_OK) {
+ DLOG(ERROR) << "Failed to set Opus bitrate: " << bitrate;
+ return;
+ }
+}
+
+void AudioTrackOpusEncoder::EncodeAudio(
+ std::unique_ptr<media::AudioBus> input_bus,
+ base::TimeTicks capture_time) {
+ DVLOG(3) << __func__ << ", #frames " << input_bus->frames();
+ DCHECK_CALLED_ON_VALID_THREAD(encoder_thread_checker_);
+ DCHECK_EQ(input_bus->channels(), input_params_.channels());
+ DCHECK(!capture_time.is_null());
+ DCHECK(converter_);
+
+ if (!is_initialized() || paused_)
+ return;
+
+ // TODO(mcasas): Consider using a
+ // base::circular_deque<std::unique_ptr<AudioBus>> instead of an AudioFifo,
+ // to avoid copying data needlessly since we know the sizes of both input and
+ // output and they are multiples.
+ fifo_->Push(input_bus.get());
+
+ // Wait to have enough |input_bus|s to guarantee a satisfactory conversion.
+ while (fifo_->frames() >= input_params_.frames_per_buffer()) {
+ std::unique_ptr<media::AudioBus> audio_bus = media::AudioBus::Create(
+ converted_params_.channels(), kOpusPreferredFramesPerBuffer);
+ converter_->Convert(audio_bus.get());
+ audio_bus->ToInterleaved<media::Float32SampleTypeTraits>(
+ audio_bus->frames(), buffer_.get());
+
+ std::unique_ptr<std::string> encoded_data(new std::string());
+ if (DoEncode(opus_encoder_, buffer_.get(), kOpusPreferredFramesPerBuffer,
+ encoded_data.get())) {
+ const base::TimeTicks capture_time_of_first_sample =
+ capture_time - media::AudioTimestampHelper::FramesToTime(
+ input_bus->frames(), input_params_.sample_rate());
+ on_encoded_audio_cb_.Run(converted_params_, std::move(encoded_data),
+ capture_time_of_first_sample);
+ }
+ }
+}
+
+void AudioTrackOpusEncoder::DestroyExistingOpusEncoder() {
+ // We don't DCHECK that we're on the encoder thread here, as this could be
+ // called from the dtor (main thread) or from OnSetFormat() (encoder thread).
+ if (opus_encoder_) {
+ opus_encoder_destroy(opus_encoder_);
+ opus_encoder_ = nullptr;
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media_recorder/audio_track_opus_encoder.h b/chromium/content/renderer/media_recorder/audio_track_opus_encoder.h
new file mode 100644
index 00000000000..103a07492e2
--- /dev/null
+++ b/chromium/content/renderer/media_recorder/audio_track_opus_encoder.h
@@ -0,0 +1,69 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_RECORDER_AUDIO_TRACK_OPUS_ENCODER_H_
+#define CONTENT_RENDERER_MEDIA_RECORDER_AUDIO_TRACK_OPUS_ENCODER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "content/renderer/media_recorder/audio_track_encoder.h"
+#include "media/base/audio_bus.h"
+#include "media/base/audio_converter.h"
+#include "media/base/audio_fifo.h"
+#include "media/base/audio_parameters.h"
+#include "third_party/opus/src/include/opus.h"
+
+namespace content {
+
+// Class encapsulating Opus-related encoding details. It contains an
+// AudioConverter to adapt incoming data to the format Opus likes to have.
+class AudioTrackOpusEncoder : public AudioTrackEncoder,
+ public media::AudioConverter::InputCallback {
+ public:
+ AudioTrackOpusEncoder(OnEncodedAudioCB on_encoded_audio_cb,
+ int32_t bits_per_second);
+
+ void OnSetFormat(const media::AudioParameters& params) override;
+ void EncodeAudio(std::unique_ptr<media::AudioBus> input_bus,
+ base::TimeTicks capture_time) override;
+
+ private:
+ ~AudioTrackOpusEncoder() override;
+
+ bool is_initialized() const { return !!opus_encoder_; }
+
+ void DestroyExistingOpusEncoder();
+
+ // media::AudioConverted::InputCallback implementation.
+ double ProvideInput(media::AudioBus* audio_bus,
+ uint32_t frames_delayed) override;
+
+ // Target bitrate for Opus. If 0, Opus provide automatic bitrate is used.
+ const int32_t bits_per_second_;
+
+ // Output parameters after audio conversion. This differs from the input
+ // parameters only in sample_rate() and frames_per_buffer(): output should be
+ // 48ksamples/s and 2880, respectively.
+ media::AudioParameters converted_params_;
+
+ // Sample rate adapter from the input audio to what OpusEncoder desires.
+ std::unique_ptr<media::AudioConverter> converter_;
+
+ // Buffer for holding the original input audio before it goes to the
+ // converter.
+ std::unique_ptr<media::AudioFifo> fifo_;
+
+ // Buffer for passing AudioBus data from the converter to the encoder.
+ std::unique_ptr<float[]> buffer_;
+
+ OpusEncoder* opus_encoder_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioTrackOpusEncoder);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_RECORDER_AUDIO_TRACK_OPUS_ENCODER_H_
diff --git a/chromium/content/renderer/media_recorder/audio_track_pcm_encoder.cc b/chromium/content/renderer/media_recorder/audio_track_pcm_encoder.cc
new file mode 100644
index 00000000000..6bae562f8d4
--- /dev/null
+++ b/chromium/content/renderer/media_recorder/audio_track_pcm_encoder.cc
@@ -0,0 +1,56 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media_recorder/audio_track_pcm_encoder.h"
+
+#include <string.h>
+#include <string>
+
+#include "media/base/audio_sample_types.h"
+#include "media/base/audio_timestamp_helper.h"
+
+namespace content {
+
+AudioTrackPcmEncoder::AudioTrackPcmEncoder(OnEncodedAudioCB on_encoded_audio_cb)
+ : AudioTrackEncoder(std::move(on_encoded_audio_cb)) {}
+
+void AudioTrackPcmEncoder::OnSetFormat(
+ const media::AudioParameters& input_params) {
+ DVLOG(1) << __func__
+ << ", |input_params_|: " << input_params_.AsHumanReadableString();
+ DCHECK_CALLED_ON_VALID_THREAD(encoder_thread_checker_);
+
+ if (!input_params.IsValid()) {
+ DLOG(ERROR) << "Invalid params: " << input_params.AsHumanReadableString();
+ return;
+ }
+ input_params_ = input_params;
+}
+
+void AudioTrackPcmEncoder::EncodeAudio(
+ std::unique_ptr<media::AudioBus> input_bus,
+ base::TimeTicks capture_time) {
+ DVLOG(3) << __func__ << ", #frames " << input_bus->frames();
+ DCHECK_CALLED_ON_VALID_THREAD(encoder_thread_checker_);
+ DCHECK_EQ(input_bus->channels(), input_params_.channels());
+ DCHECK(!capture_time.is_null());
+
+ if (paused_)
+ return;
+
+ std::unique_ptr<std::string> encoded_data_string(new std::string());
+ encoded_data_string->resize(input_bus->frames() * input_bus->channels() *
+ sizeof(float));
+ char* encoded_data_ptr = base::string_as_array(encoded_data_string.get());
+ input_bus->ToInterleaved<media::Float32SampleTypeTraits>(
+ input_bus->frames(), reinterpret_cast<float*>(encoded_data_ptr));
+
+ const base::TimeTicks capture_time_of_first_sample =
+ capture_time - media::AudioTimestampHelper::FramesToTime(
+ input_bus->frames(), input_params_.sample_rate());
+ on_encoded_audio_cb_.Run(input_params_, std::move(encoded_data_string),
+ capture_time_of_first_sample);
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media_recorder/audio_track_pcm_encoder.h b/chromium/content/renderer/media_recorder/audio_track_pcm_encoder.h
new file mode 100644
index 00000000000..e0ec868c53f
--- /dev/null
+++ b/chromium/content/renderer/media_recorder/audio_track_pcm_encoder.h
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_RECORDER_AUDIO_TRACK_PCM_ENCODER_H_
+#define CONTENT_RENDERER_MEDIA_RECORDER_AUDIO_TRACK_PCM_ENCODER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "content/renderer/media_recorder/audio_track_encoder.h"
+#include "media/base/audio_bus.h"
+#include "media/base/audio_parameters.h"
+
+namespace content {
+
+// A signed, 16-bit linear audio "encoder" that will just pass the audio right
+// back out again.
+class AudioTrackPcmEncoder : public AudioTrackEncoder {
+ public:
+ explicit AudioTrackPcmEncoder(OnEncodedAudioCB on_encoded_audio_cb);
+
+ void OnSetFormat(const media::AudioParameters& params) override;
+ void EncodeAudio(std::unique_ptr<media::AudioBus> input_bus,
+ base::TimeTicks capture_time) override;
+
+ private:
+ ~AudioTrackPcmEncoder() override {}
+
+ DISALLOW_COPY_AND_ASSIGN(AudioTrackPcmEncoder);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_RECORDER_AUDIO_TRACK_PCM_ENCODER_H_
diff --git a/chromium/content/renderer/media_recorder/audio_track_recorder.cc b/chromium/content/renderer/media_recorder/audio_track_recorder.cc
index 61b2229b94e..047395dcbae 100644
--- a/chromium/content/renderer/media_recorder/audio_track_recorder.cc
+++ b/chromium/content/renderer/media_recorder/audio_track_recorder.cc
@@ -11,13 +11,11 @@
#include "base/macros.h"
#include "base/stl_util.h"
#include "content/renderer/media/media_stream_audio_track.h"
+#include "content/renderer/media_recorder/audio_track_opus_encoder.h"
+#include "content/renderer/media_recorder/audio_track_pcm_encoder.h"
#include "media/base/audio_bus.h"
-#include "media/base/audio_converter.h"
-#include "media/base/audio_fifo.h"
#include "media/base/audio_parameters.h"
-#include "media/base/audio_sample_types.h"
#include "media/base/bind_to_current_loop.h"
-#include "third_party/opus/src/include/opus.h"
// Note that this code follows the Chrome media convention of defining a "frame"
// as "one multi-channel sample" as opposed to another common definition meaning
@@ -27,267 +25,18 @@
namespace content {
-namespace {
-
-enum : int {
- // Recommended value for opus_encode_float(), according to documentation in
- // third_party/opus/src/include/opus.h, so that the Opus encoder does not
- // degrade the audio due to memory constraints, and is independent of the
- // duration of the encoded buffer.
- kOpusMaxDataBytes = 4000,
-
- // Opus preferred sampling rate for encoding. This is also the one WebM likes
- // to have: https://wiki.xiph.org/MatroskaOpus.
- kOpusPreferredSamplingRate = 48000,
-
- // For quality reasons we try to encode 60ms, the maximum Opus buffer.
- kOpusPreferredBufferDurationMs = 60,
-
- // Maximum amount of buffers that can be held in the AudioEncoders' AudioFifo.
- // Recording is not real time, hence a certain buffering is allowed.
- kMaxNumberOfFifoBuffers = 2,
-};
-
-// The amount of Frames in a 60 ms buffer @ 48000 samples/second.
-const int kOpusPreferredFramesPerBuffer = kOpusPreferredSamplingRate *
- kOpusPreferredBufferDurationMs /
- base::Time::kMillisecondsPerSecond;
-
-// Tries to encode |data_in|'s |num_samples| into |data_out|.
-bool DoEncode(OpusEncoder* opus_encoder,
- float* data_in,
- int num_samples,
- std::string* data_out) {
- DCHECK_EQ(kOpusPreferredFramesPerBuffer, num_samples);
-
- data_out->resize(kOpusMaxDataBytes);
- const opus_int32 result = opus_encode_float(
- opus_encoder, data_in, num_samples,
- reinterpret_cast<uint8_t*>(base::string_as_array(data_out)),
- kOpusMaxDataBytes);
-
- if (result > 1) {
- // TODO(ajose): Investigate improving this. http://crbug.com/547918
- data_out->resize(result);
- return true;
- }
- // If |result| in {0,1}, do nothing; the documentation says that a return
- // value of zero or one means the packet does not need to be transmitted.
- // Otherwise, we have an error.
- DLOG_IF(ERROR, result < 0) << " encode failed: " << opus_strerror(result);
- return false;
-}
-
-} // anonymous namespace
-
-// Nested class encapsulating opus-related encoding details. It contains an
-// AudioConverter to adapt incoming data to the format Opus likes to have.
-// AudioEncoder is created and destroyed on ATR's main thread (usually the main
-// render thread) but otherwise should operate entirely on |encoder_thread_|,
-// which is owned by AudioTrackRecorder. Be sure to delete |encoder_thread_|
-// before deleting the AudioEncoder using it.
-class AudioTrackRecorder::AudioEncoder
- : public base::RefCountedThreadSafe<AudioEncoder>,
- public media::AudioConverter::InputCallback {
- public:
- AudioEncoder(const OnEncodedAudioCB& on_encoded_audio_cb,
- int32_t bits_per_second);
-
- void OnSetFormat(const media::AudioParameters& params);
-
- void EncodeAudio(std::unique_ptr<media::AudioBus> audio_bus,
- const base::TimeTicks& capture_time);
-
- void set_paused(bool paused) { paused_ = paused; }
-
- private:
- friend class base::RefCountedThreadSafe<AudioEncoder>;
- ~AudioEncoder() override;
-
- bool is_initialized() const { return !!opus_encoder_; }
-
- // media::AudioConverted::InputCallback implementation.
- double ProvideInput(media::AudioBus* audio_bus,
- uint32_t frames_delayed) override;
-
- void DestroyExistingOpusEncoder();
-
- const OnEncodedAudioCB on_encoded_audio_cb_;
-
- // Target bitrate for Opus. If 0, Opus provide automatic bitrate is used.
- const int32_t bits_per_second_;
-
- base::ThreadChecker encoder_thread_checker_;
-
- // Track Audio (ingress) and Opus encoder input parameters, respectively. They
- // only differ in their sample_rate() and frames_per_buffer(): output is
- // 48ksamples/s and 2880, respectively.
- media::AudioParameters input_params_;
- media::AudioParameters output_params_;
-
- // Sampling rate adapter between an OpusEncoder supported and the provided.
- std::unique_ptr<media::AudioConverter> converter_;
- std::unique_ptr<media::AudioFifo> fifo_;
-
- // Buffer for passing AudioBus data to OpusEncoder.
- std::unique_ptr<float[]> buffer_;
-
- // While |paused_|, AudioBuses are not encoded.
- bool paused_;
-
- OpusEncoder* opus_encoder_;
-
- DISALLOW_COPY_AND_ASSIGN(AudioEncoder);
-};
-
-AudioTrackRecorder::AudioEncoder::AudioEncoder(
- const OnEncodedAudioCB& on_encoded_audio_cb,
- int32_t bits_per_second)
- : on_encoded_audio_cb_(on_encoded_audio_cb),
- bits_per_second_(bits_per_second),
- paused_(false),
- opus_encoder_(nullptr) {
- // AudioEncoder is constructed on the thread that ATR lives on, but should
- // operate only on the encoder thread after that. Reset
- // |encoder_thread_checker_| here, as the next call to CalledOnValidThread()
- // will be from the encoder thread.
- encoder_thread_checker_.DetachFromThread();
-}
-
-AudioTrackRecorder::AudioEncoder::~AudioEncoder() {
- // We don't DCHECK that we're on the encoder thread here, as it should have
- // already been deleted at this point.
- DestroyExistingOpusEncoder();
-}
-
-void AudioTrackRecorder::AudioEncoder::OnSetFormat(
- const media::AudioParameters& input_params) {
- DVLOG(1) << __func__;
- DCHECK(encoder_thread_checker_.CalledOnValidThread());
- if (input_params_.Equals(input_params))
- return;
-
- DestroyExistingOpusEncoder();
-
- if (!input_params.IsValid()) {
- DLOG(ERROR) << "Invalid params: " << input_params.AsHumanReadableString();
- return;
- }
- input_params_ = input_params;
- input_params_.set_frames_per_buffer(input_params_.sample_rate() *
- kOpusPreferredBufferDurationMs /
- base::Time::kMillisecondsPerSecond);
-
- // third_party/libopus supports up to 2 channels (see implementation of
- // opus_encoder_create()): force |output_params_| to at most those.
- output_params_ = media::AudioParameters(
- media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
- media::GuessChannelLayout(std::min(input_params_.channels(), 2)),
- kOpusPreferredSamplingRate,
- input_params_.bits_per_sample(),
- kOpusPreferredFramesPerBuffer);
- DVLOG(1) << "|input_params_|:" << input_params_.AsHumanReadableString()
- << " -->|output_params_|:" << output_params_.AsHumanReadableString();
-
- converter_.reset(new media::AudioConverter(input_params_, output_params_,
- false /* disable_fifo */));
- converter_->AddInput(this);
- converter_->PrimeWithSilence();
-
- fifo_.reset(new media::AudioFifo(
- input_params_.channels(),
- kMaxNumberOfFifoBuffers * input_params_.frames_per_buffer()));
-
- buffer_.reset(new float[output_params_.channels() *
- output_params_.frames_per_buffer()]);
-
- // Initialize OpusEncoder.
- int opus_result;
- opus_encoder_ = opus_encoder_create(output_params_.sample_rate(),
- output_params_.channels(),
- OPUS_APPLICATION_AUDIO,
- &opus_result);
- if (opus_result < 0) {
- DLOG(ERROR) << "Couldn't init opus encoder: " << opus_strerror(opus_result)
- << ", sample rate: " << output_params_.sample_rate()
- << ", channels: " << output_params_.channels();
- return;
- }
-
- // Note: As of 2013-10-31, the encoder in "auto bitrate" mode would use a
- // variable bitrate up to 102kbps for 2-channel, 48 kHz audio and a 10 ms
- // buffer duration. The opus library authors may, of course, adjust this in
- // later versions.
- const opus_int32 bitrate =
- (bits_per_second_ > 0) ? bits_per_second_ : OPUS_AUTO;
- if (opus_encoder_ctl(opus_encoder_, OPUS_SET_BITRATE(bitrate)) != OPUS_OK) {
- DLOG(ERROR) << "Failed to set opus bitrate: " << bitrate;
- return;
- }
-}
-
-void AudioTrackRecorder::AudioEncoder::EncodeAudio(
- std::unique_ptr<media::AudioBus> input_bus,
- const base::TimeTicks& capture_time) {
- DVLOG(3) << __func__ << ", #frames " << input_bus->frames();
- DCHECK(encoder_thread_checker_.CalledOnValidThread());
- DCHECK_EQ(input_bus->channels(), input_params_.channels());
- DCHECK(!capture_time.is_null());
- DCHECK(converter_);
-
- if (!is_initialized() || paused_)
- return;
- // TODO(mcasas): Consider using a
- // base::circular_deque<std::unique_ptr<AudioBus>> instead of an AudioFifo,
- // to avoid copying data needlessly since we know the sizes of both input and
- // output and they are multiples.
- fifo_->Push(input_bus.get());
-
- // Wait to have enough |input_bus|s to guarantee a satisfactory conversion.
- while (fifo_->frames() >= input_params_.frames_per_buffer()) {
- std::unique_ptr<media::AudioBus> audio_bus = media::AudioBus::Create(
- output_params_.channels(), kOpusPreferredFramesPerBuffer);
- converter_->Convert(audio_bus.get());
- audio_bus->ToInterleaved<media::Float32SampleTypeTraits>(
- audio_bus->frames(), buffer_.get());
-
- std::unique_ptr<std::string> encoded_data(new std::string());
- if (DoEncode(opus_encoder_, buffer_.get(), kOpusPreferredFramesPerBuffer,
- encoded_data.get())) {
- const base::TimeTicks capture_time_of_first_sample =
- capture_time -
- base::TimeDelta::FromMicroseconds(fifo_->frames() *
- base::Time::kMicrosecondsPerSecond /
- input_params_.sample_rate());
- on_encoded_audio_cb_.Run(output_params_, std::move(encoded_data),
- capture_time_of_first_sample);
- }
- }
-}
-
-double AudioTrackRecorder::AudioEncoder::ProvideInput(
- media::AudioBus* audio_bus,
- uint32_t frames_delayed) {
- fifo_->Consume(audio_bus, 0, audio_bus->frames());
- return 1.0; // Return volume greater than zero to indicate we have more data.
+AudioTrackRecorder::CodecId AudioTrackRecorder::GetPreferredCodecId() {
+ return CodecId::OPUS;
}
-void AudioTrackRecorder::AudioEncoder::DestroyExistingOpusEncoder() {
- // We don't DCHECK that we're on the encoder thread here, as this could be
- // called from the dtor (main thread) or from OnSetFormat() (encoder thread).
- if (opus_encoder_) {
- opus_encoder_destroy(opus_encoder_);
- opus_encoder_ = nullptr;
- }
-}
-
-AudioTrackRecorder::AudioTrackRecorder(
- const blink::WebMediaStreamTrack& track,
- const OnEncodedAudioCB& on_encoded_audio_cb,
- int32_t bits_per_second)
+AudioTrackRecorder::AudioTrackRecorder(CodecId codec,
+ const blink::WebMediaStreamTrack& track,
+ OnEncodedAudioCB on_encoded_audio_cb,
+ int32_t bits_per_second)
: track_(track),
- encoder_(new AudioEncoder(media::BindToCurrentLoop(on_encoded_audio_cb),
- bits_per_second)),
+ encoder_(CreateAudioEncoder(codec,
+ std::move(on_encoded_audio_cb),
+ bits_per_second)),
encoder_thread_("AudioEncoderThread") {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
DCHECK(!track_.IsNull());
@@ -306,13 +55,31 @@ AudioTrackRecorder::~AudioTrackRecorder() {
MediaStreamAudioSink::RemoveFromAudioTrack(this, track_);
}
+// Creates an audio encoder from the codec. Returns nullptr if the codec is
+// invalid.
+AudioTrackEncoder* AudioTrackRecorder::CreateAudioEncoder(
+ CodecId codec,
+ OnEncodedAudioCB on_encoded_audio_cb,
+ int32_t bits_per_second) {
+ if (codec == CodecId::PCM) {
+ return new AudioTrackPcmEncoder(
+ media::BindToCurrentLoop(std::move(on_encoded_audio_cb)));
+ }
+
+ // All other paths will use the AudioTrackOpusEncoder.
+ return new AudioTrackOpusEncoder(
+ media::BindToCurrentLoop(std::move(on_encoded_audio_cb)),
+ bits_per_second);
+}
+
void AudioTrackRecorder::OnSetFormat(const media::AudioParameters& params) {
// If the source is restarted, might have changed to another capture thread.
capture_thread_checker_.DetachFromThread();
DCHECK(capture_thread_checker_.CalledOnValidThread());
encoder_thread_.task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&AudioEncoder::OnSetFormat, encoder_, params));
+ FROM_HERE,
+ base::BindOnce(&AudioTrackEncoder::OnSetFormat, encoder_, params));
}
void AudioTrackRecorder::OnData(const media::AudioBus& audio_bus,
@@ -325,7 +92,7 @@ void AudioTrackRecorder::OnData(const media::AudioBus& audio_bus,
audio_bus.CopyTo(audio_data.get());
encoder_thread_.task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&AudioEncoder::EncodeAudio, encoder_,
+ FROM_HERE, base::BindOnce(&AudioTrackEncoder::EncodeAudio, encoder_,
base::Passed(&audio_data), capture_time));
}
@@ -333,14 +100,16 @@ void AudioTrackRecorder::Pause() {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
DCHECK(encoder_);
encoder_thread_.task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&AudioEncoder::set_paused, encoder_, true));
+ FROM_HERE,
+ base::BindOnce(&AudioTrackEncoder::set_paused, encoder_, true));
}
void AudioTrackRecorder::Resume() {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
DCHECK(encoder_);
encoder_thread_.task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&AudioEncoder::set_paused, encoder_, false));
+ FROM_HERE,
+ base::BindOnce(&AudioTrackEncoder::set_paused, encoder_, false));
}
} // namespace content
diff --git a/chromium/content/renderer/media_recorder/audio_track_recorder.h b/chromium/content/renderer/media_recorder/audio_track_recorder.h
index 6ee2a5711e7..eea054429a9 100644
--- a/chromium/content/renderer/media_recorder/audio_track_recorder.h
+++ b/chromium/content/renderer/media_recorder/audio_track_recorder.h
@@ -14,6 +14,7 @@
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "content/public/renderer/media_stream_audio_sink.h"
+#include "content/renderer/media_recorder/audio_track_encoder.h"
#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
namespace media {
@@ -28,17 +29,27 @@ namespace content {
// single thread (the main Render thread) but can recieve MediaStreamAudioSink-
// related calls on a different "live audio" thread (referred to internally as
// the "capture thread"). It owns an internal thread to use for encoding, on
-// which lives an AudioEncoder (a private nested class of ATR) with its own
-// threading subtleties, see the implementation file.
+// which lives an AudioTrackEncoder with its own threading subtleties, see the
+// implementation file.
class CONTENT_EXPORT AudioTrackRecorder : public MediaStreamAudioSink {
public:
+ enum class CodecId {
+ // Do not change the order of codecs. Add new ones right before LAST.
+ OPUS,
+ PCM, // 32-bit little-endian float.
+ LAST
+ };
+
using OnEncodedAudioCB =
base::Callback<void(const media::AudioParameters& params,
std::unique_ptr<std::string> encoded_data,
base::TimeTicks capture_time)>;
- AudioTrackRecorder(const blink::WebMediaStreamTrack& track,
- const OnEncodedAudioCB& on_encoded_audio_cb,
+ static CodecId GetPreferredCodecId();
+
+ AudioTrackRecorder(CodecId codec,
+ const blink::WebMediaStreamTrack& track,
+ OnEncodedAudioCB on_encoded_audio_cb,
int32_t bits_per_second);
~AudioTrackRecorder() override;
@@ -51,9 +62,12 @@ class CONTENT_EXPORT AudioTrackRecorder : public MediaStreamAudioSink {
void Resume();
private:
- // Forward declaration of nested class for handling encoding.
- // See the implementation file for details.
- class AudioEncoder;
+ // Creates an audio encoder from |codec|. Returns nullptr if the codec is
+ // invalid.
+ static AudioTrackEncoder* CreateAudioEncoder(
+ CodecId codec,
+ OnEncodedAudioCB on_encoded_audio_cb,
+ int32_t bits_per_second);
// Used to check that we are destroyed on the same thread we were created on.
base::ThreadChecker main_render_thread_checker_;
@@ -68,10 +82,11 @@ class CONTENT_EXPORT AudioTrackRecorder : public MediaStreamAudioSink {
// Thin wrapper around OpusEncoder.
// |encoder_| should be initialized before |encoder_thread_| such that
// |encoder_thread_| is destructed first. This, combined with all
- // AudioEncoder work (aside from construction and destruction) happening on
- // |encoder_thread_|, should allow us to be sure that all AudioEncoder work is
- // done by the time we destroy it on ATR's thread.
- const scoped_refptr<AudioEncoder> encoder_;
+ // AudioTrackEncoder work (aside from construction and destruction) happening
+ // on |encoder_thread_|, should allow us to be sure that all AudioTrackEncoder
+ // work is done by the time we destroy it on ATR's thread.
+ const scoped_refptr<AudioTrackEncoder> encoder_;
+
// The thread on which |encoder_| works.
base::Thread encoder_thread_;
diff --git a/chromium/content/renderer/media_recorder/audio_track_recorder_unittest.cc b/chromium/content/renderer/media_recorder/audio_track_recorder_unittest.cc
index c3aab7339b6..85fc10f3338 100644
--- a/chromium/content/renderer/media_recorder/audio_track_recorder_unittest.cc
+++ b/chromium/content/renderer/media_recorder/audio_track_recorder_unittest.cc
@@ -17,6 +17,7 @@
#include "base/time/time.h"
#include "content/renderer/media/media_stream_audio_source.h"
#include "media/audio/simple_sources.h"
+#include "media/base/audio_sample_types.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebString.h"
@@ -62,6 +63,7 @@ struct ATRTestParams {
const media::ChannelLayout channel_layout;
const int sample_rate;
const int bits_per_sample;
+ const AudioTrackRecorder::CodecId codec;
};
const ATRTestParams kATRTestParams[] = {
@@ -69,34 +71,33 @@ const ATRTestParams kATRTestParams[] = {
{media::AudioParameters::AUDIO_PCM_LOW_LATENCY, /* input format */
media::CHANNEL_LAYOUT_STEREO, /* channel layout */
kDefaultSampleRate, /* sample rate */
- kDefaultBitsPerSample}, /* bits per sample */
+ kDefaultBitsPerSample, /* bits per sample */
+ AudioTrackRecorder::CodecId::OPUS}, /* codec for encoding */
// Change to mono:
- {media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
- media::CHANNEL_LAYOUT_MONO,
- kDefaultSampleRate,
- kDefaultBitsPerSample},
+ {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
+ kDefaultSampleRate, kDefaultBitsPerSample,
+ AudioTrackRecorder::CodecId::OPUS},
// Different sampling rate as well:
+ {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
+ 24000, kDefaultBitsPerSample, AudioTrackRecorder::CodecId::OPUS},
{media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
- media::CHANNEL_LAYOUT_MONO,
- 24000,
- kDefaultBitsPerSample},
- {media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
- media::CHANNEL_LAYOUT_STEREO,
- 8000,
- kDefaultBitsPerSample},
+ media::CHANNEL_LAYOUT_STEREO, 8000, kDefaultBitsPerSample,
+ AudioTrackRecorder::CodecId::OPUS},
// Using a non-default Opus sampling rate (48, 24, 16, 12, or 8 kHz).
+ {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
+ 22050, kDefaultBitsPerSample, AudioTrackRecorder::CodecId::OPUS},
{media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
- media::CHANNEL_LAYOUT_MONO,
- 22050,
- kDefaultBitsPerSample},
+ media::CHANNEL_LAYOUT_STEREO, 44100, kDefaultBitsPerSample,
+ AudioTrackRecorder::CodecId::OPUS},
{media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
- media::CHANNEL_LAYOUT_STEREO,
- 44100,
- kDefaultBitsPerSample},
+ media::CHANNEL_LAYOUT_STEREO, 96000, kDefaultBitsPerSample,
+ AudioTrackRecorder::CodecId::OPUS},
+ {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
+ kDefaultSampleRate, kDefaultBitsPerSample,
+ AudioTrackRecorder::CodecId::PCM},
{media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
- media::CHANNEL_LAYOUT_STEREO,
- 96000,
- kDefaultBitsPerSample},
+ media::CHANNEL_LAYOUT_STEREO, kDefaultSampleRate, kDefaultBitsPerSample,
+ AudioTrackRecorder::CodecId::PCM},
};
class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
@@ -104,7 +105,8 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
// Initialize |first_params_| based on test parameters, and |second_params_|
// to always be the same thing.
AudioTrackRecorderTest()
- : first_params_(GetParam().input_format,
+ : codec_(GetParam().codec),
+ first_params_(GetParam().input_format,
GetParam().channel_layout,
GetParam().sample_rate,
GetParam().bits_per_sample,
@@ -120,12 +122,14 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
second_source_(second_params_.channels(),
440,
second_params_.sample_rate()),
- opus_decoder_(nullptr) {
+ opus_decoder_(nullptr),
+ first_source_cache_pos_(0) {
ResetDecoder(first_params_);
PrepareBlinkTrack();
audio_track_recorder_.reset(new AudioTrackRecorder(
- blink_track_, base::Bind(&AudioTrackRecorderTest::OnEncodedAudio,
- base::Unretained(this)),
+ codec_, blink_track_,
+ base::Bind(&AudioTrackRecorderTest::OnEncodedAudio,
+ base::Unretained(this)),
0 /* bits_per_second */));
}
@@ -150,7 +154,7 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
opus_decoder_create(kDefaultSampleRate, params.channels(), &error);
EXPECT_TRUE(error == OPUS_OK && opus_decoder_);
- buffer_.reset(new float[kFramesPerBuffer * params.channels()]);
+ opus_buffer_.reset(new float[kFramesPerBuffer * params.channels()]);
}
std::unique_ptr<media::AudioBus> GetFirstSourceAudioBus() {
@@ -160,6 +164,18 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
base::Time::kMillisecondsPerSecond));
first_source_.OnMoreData(base::TimeDelta(), base::TimeTicks::Now(), 0,
bus.get());
+
+ // Save the samples that we read into the first_source_cache_.
+ std::unique_ptr<media::AudioBus> cache_bus(
+ media::AudioBus::Create(bus->channels(), bus->frames()));
+ bus->CopyTo(cache_bus.get());
+
+ int current_size = first_source_cache_.size();
+ first_source_cache_.resize(current_size +
+ cache_bus->frames() * cache_bus->channels());
+ cache_bus->ToInterleaved<media::Float32SampleTypeTraits>(
+ cache_bus->frames(), &first_source_cache_[current_size]);
+
return bus;
}
std::unique_ptr<media::AudioBus> GetSecondSourceAudioBus() {
@@ -181,13 +197,29 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
std::unique_ptr<std::string> encoded_data,
TimeTicks timestamp) {
EXPECT_TRUE(!encoded_data->empty());
- // Decode |encoded_data| and check we get the expected number of frames
- // per buffer.
- EXPECT_EQ(kDefaultSampleRate * kOpusBufferDurationMs / 1000,
- opus_decode_float(
- opus_decoder_, reinterpret_cast<uint8_t*>(
- base::string_as_array(encoded_data.get())),
- encoded_data->size(), buffer_.get(), kFramesPerBuffer, 0));
+
+ if (codec_ == AudioTrackRecorder::CodecId::OPUS) {
+ // Decode |encoded_data| and check we get the expected number of frames
+ // per buffer.
+ EXPECT_EQ(
+ kDefaultSampleRate * kOpusBufferDurationMs / 1000,
+ opus_decode_float(opus_decoder_,
+ reinterpret_cast<uint8_t*>(
+ base::string_as_array(encoded_data.get())),
+ encoded_data->size(), opus_buffer_.get(),
+ kFramesPerBuffer, 0));
+ } else if (codec_ == AudioTrackRecorder::CodecId::PCM) {
+ // Manually confirm that we're getting the same data out as what we
+ // generated from the sine wave.
+ for (size_t b = 0; b + 3 < encoded_data->size() &&
+ first_source_cache_pos_ < first_source_cache_.size();
+ b += sizeof(first_source_cache_[0]), ++first_source_cache_pos_) {
+ float sample;
+ memcpy(&sample, &(*encoded_data)[b], 4);
+ ASSERT_FLOAT_EQ(sample, first_source_cache_[first_source_cache_pos_])
+ << "(Sample " << first_source_cache_pos_ << ")";
+ }
+ }
DoOnEncodedAudio(params, *encoded_data, timestamp);
}
@@ -198,6 +230,9 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
std::unique_ptr<AudioTrackRecorder> audio_track_recorder_;
blink::WebMediaStreamTrack blink_track_;
+ // The codec we'll use for compression the audio.
+ const AudioTrackRecorder::CodecId codec_;
+
// Two different sets of AudioParameters for testing re-init of ATR.
const media::AudioParameters first_params_;
const media::AudioParameters second_params_;
@@ -208,7 +243,12 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
// Decoder for verifying data was properly encoded.
OpusDecoder* opus_decoder_;
- std::unique_ptr<float[]> buffer_;
+ std::unique_ptr<float[]> opus_buffer_;
+
+ // Save the data we generate from the first source so that we might compare it
+ // later if we happen to be using the PCM encoder.
+ std::vector<float> first_source_cache_;
+ size_t first_source_cache_pos_;
private:
// Prepares a blink track of a given MediaStreamType and attaches the native
@@ -230,7 +270,10 @@ class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
DISALLOW_COPY_AND_ASSIGN(AudioTrackRecorderTest);
};
-TEST_P(AudioTrackRecorderTest, OnData) {
+TEST_P(AudioTrackRecorderTest, OnDataOpus) {
+ if (codec_ != AudioTrackRecorder::CodecId::OPUS)
+ return;
+
InSequence s;
base::RunLoop run_loop;
base::Closure quit_closure = run_loop.QuitClosure();
@@ -274,7 +317,32 @@ TEST_P(AudioTrackRecorderTest, OnData) {
Mock::VerifyAndClearExpectations(this);
}
+TEST_P(AudioTrackRecorderTest, OnDataPcm) {
+ if (codec_ != AudioTrackRecorder::CodecId::PCM)
+ return;
+
+ InSequence s;
+ base::RunLoop run_loop;
+ base::Closure quit_closure = run_loop.QuitClosure();
+
+ audio_track_recorder_->OnSetFormat(first_params_);
+
+ EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _)).Times(5);
+ EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _))
+ .WillOnce(RunClosure(quit_closure));
+
+ audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), TimeTicks::Now());
+ for (int i = 0; i < kRatioInputToOutputFrames - 1; ++i)
+ audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), TimeTicks::Now());
+
+ run_loop.Run();
+ Mock::VerifyAndClearExpectations(this);
+}
+
TEST_P(AudioTrackRecorderTest, PauseResume) {
+ if (codec_ != AudioTrackRecorder::CodecId::OPUS)
+ return;
+
InSequence s;
base::RunLoop run_loop;
base::Closure quit_closure = run_loop.QuitClosure();
diff --git a/chromium/content/renderer/media_recorder/media_recorder_handler.cc b/chromium/content/renderer/media_recorder/media_recorder_handler.cc
index afb94fa308b..bb25367329d 100644
--- a/chromium/content/renderer/media_recorder/media_recorder_handler.cc
+++ b/chromium/content/renderer/media_recorder/media_recorder_handler.cc
@@ -19,9 +19,11 @@
#include "content/renderer/media/webrtc_uma_histograms.h"
#include "content/renderer/media_recorder/audio_track_recorder.h"
#include "media/base/audio_bus.h"
+#include "media/base/audio_codecs.h"
#include "media/base/audio_parameters.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/mime_util.h"
+#include "media/base/video_codecs.h"
#include "media/base/video_frame.h"
#include "media/muxers/webm_muxer.h"
#include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h"
@@ -63,27 +65,53 @@ media::VideoCodec CodecIdToMediaVideoCodec(VideoTrackRecorder::CodecId id) {
case VideoTrackRecorder::CodecId::LAST:
return media::kUnknownVideoCodec;
}
- NOTREACHED() << "Unsupported codec";
+ NOTREACHED() << "Unsupported video codec";
return media::kUnknownVideoCodec;
}
+media::AudioCodec CodecIdToMediaAudioCodec(AudioTrackRecorder::CodecId id) {
+ switch (id) {
+ case AudioTrackRecorder::CodecId::PCM:
+ return media::kCodecPCM;
+ case AudioTrackRecorder::CodecId::OPUS:
+ return media::kCodecOpus;
+ case AudioTrackRecorder::CodecId::LAST:
+ return media::kUnknownAudioCodec;
+ }
+ NOTREACHED() << "Unsupported audio codec";
+ return media::kUnknownAudioCodec;
+}
+
// Extracts the first recognised CodecId of |codecs| or CodecId::LAST if none
// of them is known.
-VideoTrackRecorder::CodecId StringToCodecId(const blink::WebString& codecs) {
+VideoTrackRecorder::CodecId VideoStringToCodecId(
+ const blink::WebString& codecs) {
const std::string& codecs_str = ToLowerASCII(codecs.Utf8());
if (codecs_str.find("vp8") != std::string::npos)
return VideoTrackRecorder::CodecId::VP8;
- else if (codecs_str.find("vp9") != std::string::npos)
+ if (codecs_str.find("vp9") != std::string::npos)
return VideoTrackRecorder::CodecId::VP9;
#if BUILDFLAG(RTC_USE_H264)
- else if (codecs_str.find("h264") != std::string::npos ||
- codecs_str.find("avc1") != std::string::npos)
+ if (codecs_str.find("h264") != std::string::npos ||
+ codecs_str.find("avc1") != std::string::npos)
return VideoTrackRecorder::CodecId::H264;
#endif
return VideoTrackRecorder::CodecId::LAST;
}
+AudioTrackRecorder::CodecId AudioStringToCodecId(
+ const blink::WebString& codecs) {
+ const std::string& codecs_str = ToLowerASCII(codecs.Utf8());
+
+ if (codecs_str.find("opus") != std::string::npos)
+ return AudioTrackRecorder::CodecId::OPUS;
+ if (codecs_str.find("pcm") != std::string::npos)
+ return AudioTrackRecorder::CodecId::PCM;
+
+ return AudioTrackRecorder::CodecId::LAST;
+}
+
void OnEncodingInfoError(
std::unique_ptr<WebMediaCapabilitiesQueryCallbacks> callbacks) {
callbacks->OnError();
@@ -94,7 +122,8 @@ void OnEncodingInfoError(
MediaRecorderHandler::MediaRecorderHandler()
: video_bits_per_second_(0),
audio_bits_per_second_(0),
- codec_id_(VideoTrackRecorder::CodecId::VP8),
+ video_codec_id_(VideoTrackRecorder::CodecId::VP8),
+ audio_codec_id_(AudioTrackRecorder::CodecId::OPUS),
recording_(false),
client_(nullptr),
weak_factory_(this) {}
@@ -121,16 +150,17 @@ bool MediaRecorderHandler::CanSupportMimeType(
const bool video = base::EqualsCaseInsensitiveASCII(type, "video/webm") ||
base::EqualsCaseInsensitiveASCII(type, "video/x-matroska");
const bool audio =
- video ? false : base::EqualsCaseInsensitiveASCII(type, "audio/webm");
+ video ? false : (base::EqualsCaseInsensitiveASCII(type, "audio/webm"));
if (!video && !audio)
return false;
// Both |video| and |audio| support empty |codecs|; |type| == "video" supports
- // vp8, vp9, h264 and avc1 or opus; |type| = "audio", supports only opus.
+ // vp8, vp9, h264 and avc1 or opus; |type| = "audio", supports opus or pcm
+ // (little-endian 32-bit float).
// http://www.webmproject.org/docs/container Sec:"HTML5 Video Type Parameters"
- static const char* const kVideoCodecs[] = {"vp8", "vp9", "h264", "avc1",
- "opus"};
- static const char* const kAudioCodecs[] = { "opus" };
+ static const char* const kVideoCodecs[] = {"vp8", "vp9", "h264",
+ "avc1", "opus", "pcm"};
+ static const char* const kAudioCodecs[] = {"opus", "pcm"};
const char* const* codecs = video ? &kVideoCodecs[0] : &kAudioCodecs[0];
const int codecs_count =
video ? arraysize(kVideoCodecs) : arraysize(kAudioCodecs);
@@ -166,13 +196,24 @@ bool MediaRecorderHandler::Initialize(
}
// Once established that we support the codec(s), hunt then individually.
- const VideoTrackRecorder::CodecId codec_id = StringToCodecId(codecs);
- codec_id_ = (codec_id != VideoTrackRecorder::CodecId::LAST)
- ? codec_id
- : VideoTrackRecorder::GetPreferredCodecId();
-
- DVLOG_IF(1, codec_id == VideoTrackRecorder::CodecId::LAST)
- << "Falling back to preferred codec id " << static_cast<int>(codec_id_);
+ const VideoTrackRecorder::CodecId video_codec_id =
+ VideoStringToCodecId(codecs);
+ video_codec_id_ = (video_codec_id != VideoTrackRecorder::CodecId::LAST)
+ ? video_codec_id
+ : VideoTrackRecorder::GetPreferredCodecId();
+ DVLOG_IF(1, video_codec_id == VideoTrackRecorder::CodecId::LAST)
+ << "Falling back to preferred video codec id "
+ << static_cast<int>(video_codec_id_);
+
+ // Do the same for the audio codec(s).
+ const AudioTrackRecorder::CodecId audio_codec_id =
+ AudioStringToCodecId(codecs);
+ audio_codec_id_ = (audio_codec_id != AudioTrackRecorder::CodecId::LAST)
+ ? audio_codec_id
+ : AudioTrackRecorder::GetPreferredCodecId();
+ DVLOG_IF(1, audio_codec_id == AudioTrackRecorder::CodecId::LAST)
+ << "Falling back to preferred audio codec id "
+ << static_cast<int>(audio_codec_id_);
media_stream_ = media_stream;
DCHECK(client);
@@ -217,10 +258,12 @@ bool MediaRecorderHandler::Start(int timeslice) {
return false;
}
- webm_muxer_.reset(new media::WebmMuxer(
- CodecIdToMediaVideoCodec(codec_id_), use_video_tracks, use_audio_tracks,
- base::Bind(&MediaRecorderHandler::WriteData,
- weak_factory_.GetWeakPtr())));
+ webm_muxer_.reset(
+ new media::WebmMuxer(CodecIdToMediaVideoCodec(video_codec_id_),
+ CodecIdToMediaAudioCodec(audio_codec_id_),
+ use_video_tracks, use_audio_tracks,
+ base::Bind(&MediaRecorderHandler::WriteData,
+ weak_factory_.GetWeakPtr())));
if (use_video_tracks) {
// TODO(mcasas): The muxer API supports only one video track. Extend it to
@@ -236,8 +279,9 @@ bool MediaRecorderHandler::Start(int timeslice) {
media::BindToCurrentLoop(base::Bind(
&MediaRecorderHandler::OnEncodedVideo, weak_factory_.GetWeakPtr()));
- video_recorders_.emplace_back(new VideoTrackRecorder(
- codec_id_, video_track, on_encoded_video_cb, video_bits_per_second_));
+ video_recorders_.emplace_back(
+ new VideoTrackRecorder(video_codec_id_, video_track,
+ on_encoded_video_cb, video_bits_per_second_));
}
if (use_audio_tracks) {
@@ -255,7 +299,8 @@ bool MediaRecorderHandler::Start(int timeslice) {
&MediaRecorderHandler::OnEncodedAudio, weak_factory_.GetWeakPtr()));
audio_recorders_.emplace_back(new AudioTrackRecorder(
- audio_track, on_encoded_audio_cb, audio_bits_per_second_));
+ audio_codec_id_, audio_track, std::move(on_encoded_audio_cb),
+ audio_bits_per_second_));
}
recording_ = true;
@@ -327,7 +372,8 @@ void MediaRecorderHandler::EncodingInfo(
if (configuration.video_configuration && info->supported) {
const bool is_likely_accelerated =
VideoTrackRecorder::CanUseAcceleratedEncoder(
- StringToCodecId(codec), configuration.video_configuration->width,
+ VideoStringToCodecId(codec),
+ configuration.video_configuration->width,
configuration.video_configuration->height);
const float pixels_per_second =
diff --git a/chromium/content/renderer/media_recorder/media_recorder_handler.h b/chromium/content/renderer/media_recorder/media_recorder_handler.h
index b24ef92e81b..bd6f2bd6b34 100644
--- a/chromium/content/renderer/media_recorder/media_recorder_handler.h
+++ b/chromium/content/renderer/media_recorder/media_recorder_handler.h
@@ -13,6 +13,7 @@
#include "base/strings/string_piece.h"
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
+#include "content/renderer/media_recorder/audio_track_recorder.h"
#include "content/renderer/media_recorder/video_track_recorder.h"
#include "third_party/WebKit/public/platform/WebMediaRecorderHandler.h"
#include "third_party/WebKit/public/platform/WebMediaStream.h"
@@ -98,7 +99,10 @@ class CONTENT_EXPORT MediaRecorderHandler final
int32_t audio_bits_per_second_;
// Video Codec, VP8 is used by default.
- VideoTrackRecorder::CodecId codec_id_;
+ VideoTrackRecorder::CodecId video_codec_id_;
+
+ // Audio Codec, OPUS is used by default.
+ AudioTrackRecorder::CodecId audio_codec_id_;
// |client_| has no notion of time, thus may configure us via start(timeslice)
// to notify it after a certain |timeslice_| has passed. We use a moving
diff --git a/chromium/content/renderer/media_recorder/media_recorder_handler_unittest.cc b/chromium/content/renderer/media_recorder/media_recorder_handler_unittest.cc
index 6b5b6878df1..a93a26f62bb 100644
--- a/chromium/content/renderer/media_recorder/media_recorder_handler_unittest.cc
+++ b/chromium/content/renderer/media_recorder/media_recorder_handler_unittest.cc
@@ -67,7 +67,10 @@ static const MediaRecorderTestParams kMediaRecorderTestParams[] = {
#if BUILDFLAG(RTC_USE_H264)
{true, false, "video/webm", "h264", false},
#endif
- {false, true, "video/webm", "vp8", true}};
+ {false, true, "audio/webm", "opus", true},
+ {false, true, "audio/webm", "", true}, // Should default to opus.
+ {false, true, "audio/webm", "pcm", true},
+};
class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams>,
public blink::WebMediaRecorderHandlerClient {
@@ -188,6 +191,9 @@ TEST_F(MediaRecorderHandlerTest, CanSupportMimeType) {
const WebString example_good_codecs_6(WebString::FromASCII("OpUs"));
EXPECT_TRUE(media_recorder_handler_->CanSupportMimeType(
mime_type_audio, example_good_codecs_6));
+ const WebString example_good_codecs_7(WebString::FromASCII("pcm"));
+ EXPECT_TRUE(media_recorder_handler_->CanSupportMimeType(
+ mime_type_audio, example_good_codecs_7));
const WebString example_unsupported_codecs_2(WebString::FromASCII("vorbis"));
EXPECT_FALSE(media_recorder_handler_->CanSupportMimeType(
@@ -311,17 +317,19 @@ INSTANTIATE_TEST_CASE_P(,
MediaRecorderHandlerTest,
ValuesIn(kMediaRecorderTestParams));
-// Sends 2 frames and expect them as WebM contained encoded data in writeData().
-TEST_P(MediaRecorderHandlerTest, EncodeAudioFrames) {
+// Sends 2 frames and expect them as WebM (or MKV) contained encoded audio data
+// in writeData().
+TEST_P(MediaRecorderHandlerTest, OpusEncodeAudioFrames) {
// Audio-only test.
if (GetParam().has_video)
return;
AddTracks();
- const WebString mime_type(WebString::FromASCII("audio/webm"));
- EXPECT_TRUE(media_recorder_handler_->Initialize(
- this, registry_.test_stream(), mime_type, WebString(), 0, 0));
+ const WebString mime_type(WebString::FromASCII(GetParam().mime_type));
+ const WebString codecs(WebString::FromASCII(GetParam().codecs));
+ EXPECT_TRUE(media_recorder_handler_->Initialize(this, registry_.test_stream(),
+ mime_type, codecs, 0, 0));
EXPECT_TRUE(media_recorder_handler_->Start(0));
InSequence s;
diff --git a/chromium/content/renderer/media_recorder/video_track_recorder.cc b/chromium/content/renderer/media_recorder/video_track_recorder.cc
index 5420ac83e67..da7f868cbb7 100644
--- a/chromium/content/renderer/media_recorder/video_track_recorder.cc
+++ b/chromium/content/renderer/media_recorder/video_track_recorder.cc
@@ -23,7 +23,7 @@
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "media/filters/context_3d.h"
-#include "media/renderers/skcanvas_video_renderer.h"
+#include "media/renderers/paint_canvas_video_renderer.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/libyuv/include/libyuv.h"
@@ -257,7 +257,7 @@ void VideoTrackRecorder::Encoder::RetrieveFrameOnMainThread(
video_frame->timestamp());
} else {
// Accelerated decoders produce ARGB/ABGR texture-backed frames (see
- // https://crbug.com/585242), fetch them using a SkCanvasVideoRenderer.
+ // https://crbug.com/585242), fetch them using a PaintCanvasVideoRenderer.
DCHECK(video_frame->HasTextures());
DCHECK_EQ(media::PIXEL_FORMAT_ARGB, video_frame->format());
@@ -285,10 +285,10 @@ void VideoTrackRecorder::Encoder::RetrieveFrameOnMainThread(
if (!canvas_ || canvas_->imageInfo().width() != info.width() ||
canvas_->imageInfo().height() != info.height()) {
bitmap_.allocPixels(info);
- canvas_ = base::MakeUnique<cc::SkiaPaintCanvas>(bitmap_);
+ canvas_ = std::make_unique<cc::SkiaPaintCanvas>(bitmap_);
}
if (!video_renderer_)
- video_renderer_.reset(new media::SkCanvasVideoRenderer);
+ video_renderer_.reset(new media::PaintCanvasVideoRenderer);
DCHECK(context_provider->ContextGL());
video_renderer_->Copy(video_frame.get(), canvas_.get(),
diff --git a/chromium/content/renderer/media_recorder/video_track_recorder.h b/chromium/content/renderer/media_recorder/video_track_recorder.h
index 64bc28d386f..9293f475913 100644
--- a/chromium/content/renderer/media_recorder/video_track_recorder.h
+++ b/chromium/content/renderer/media_recorder/video_track_recorder.h
@@ -27,7 +27,7 @@ class PaintCanvas;
} // namespace cc
namespace media {
-class SkCanvasVideoRenderer;
+class PaintCanvasVideoRenderer;
class VideoFrame;
} // namespace media
@@ -153,7 +153,7 @@ class CONTENT_EXPORT VideoTrackRecorder : public MediaStreamVideoSink {
// Used to retrieve incoming opaque VideoFrames (i.e. VideoFrames backed by
// textures). Created on-demand on |main_task_runner_|.
- std::unique_ptr<media::SkCanvasVideoRenderer> video_renderer_;
+ std::unique_ptr<media::PaintCanvasVideoRenderer> video_renderer_;
SkBitmap bitmap_;
std::unique_ptr<cc::PaintCanvas> canvas_;
diff --git a/chromium/content/renderer/media_recorder/video_track_recorder_unittest.cc b/chromium/content/renderer/media_recorder/video_track_recorder_unittest.cc
index b46b6c2bc4d..1a0606f1976 100644
--- a/chromium/content/renderer/media_recorder/video_track_recorder_unittest.cc
+++ b/chromium/content/renderer/media_recorder/video_track_recorder_unittest.cc
@@ -13,9 +13,10 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
#include "content/child/child_process.h"
#include "content/renderer/media/media_stream_video_track.h"
#include "content/renderer/media/mock_media_stream_video_source.h"
@@ -61,7 +62,10 @@ class VideoTrackRecorderTest
: public TestWithParam<
testing::tuple<VideoTrackRecorder::CodecId, gfx::Size, bool>> {
public:
- VideoTrackRecorderTest() : mock_source_(new MockMediaStreamVideoSource()) {
+ VideoTrackRecorderTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI),
+ mock_source_(new MockMediaStreamVideoSource()) {
const blink::WebString webkit_track_id(
blink::WebString::FromASCII("dummy"));
blink_source_.Initialize(webkit_track_id,
@@ -78,7 +82,8 @@ class VideoTrackRecorderTest
// Paranoia checks.
EXPECT_EQ(blink_track_.Source().GetExtraData(),
blink_source_.GetExtraData());
- EXPECT_TRUE(message_loop_.IsCurrent());
+ EXPECT_TRUE(scoped_task_environment_.GetMainThreadTaskRunner()
+ ->BelongsToCurrentThread());
}
~VideoTrackRecorderTest() {
@@ -114,7 +119,8 @@ class VideoTrackRecorderTest
void Encode(const scoped_refptr<VideoFrame>& frame,
base::TimeTicks capture_time) {
- EXPECT_TRUE(message_loop_.IsCurrent());
+ EXPECT_TRUE(scoped_task_environment_.GetMainThreadTaskRunner()
+ ->BelongsToCurrentThread());
video_track_recorder_->OnVideoFrameForTesting(frame, capture_time);
}
@@ -132,9 +138,10 @@ class VideoTrackRecorderTest
return video_track_recorder_->encoder_->num_frames_in_encode_;
}
- // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks
- // and Sources below into believing they are on the right threads.
- const base::MessageLoopForUI message_loop_;
+ // A ChildProcess is needed to fool the Tracks and Sources into believing they
+ // are on the right threads. A ScopedTaskEnvironment must be instantiated
+ // before ChildProcess to prevent it from leaking a TaskScheduler.
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
const ChildProcess child_process_;
// All members are non-const due to the series of initialize() calls needed.
diff --git a/chromium/content/renderer/media_recorder/vpx_encoder.cc b/chromium/content/renderer/media_recorder/vpx_encoder.cc
index 6a5db03d2e6..dcfcc05a916 100644
--- a/chromium/content/renderer/media_recorder/vpx_encoder.cc
+++ b/chromium/content/renderer/media_recorder/vpx_encoder.cc
@@ -174,9 +174,9 @@ void VpxEncoder::DoEncode(vpx_codec_ctx_t* const encoder,
<< " -" << vpx_codec_error_detail(encoder);
*keyframe = false;
- vpx_codec_iter_t iter = NULL;
- const vpx_codec_cx_pkt_t* pkt = NULL;
- while ((pkt = vpx_codec_get_cx_data(encoder, &iter)) != NULL) {
+ vpx_codec_iter_t iter = nullptr;
+ const vpx_codec_cx_pkt_t* pkt = nullptr;
+ while ((pkt = vpx_codec_get_cx_data(encoder, &iter)) != nullptr) {
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
continue;
output_data->assign(static_cast<char*>(pkt->data.frame.buf),
diff --git a/chromium/content/renderer/mojo/blink_connector_js_wrapper.cc b/chromium/content/renderer/mojo/blink_connector_js_wrapper.cc
index abf402c89c7..e074f8d7bec 100644
--- a/chromium/content/renderer/mojo/blink_connector_js_wrapper.cc
+++ b/chromium/content/renderer/mojo/blink_connector_js_wrapper.cc
@@ -34,11 +34,7 @@ gin::Handle<BlinkConnectorJsWrapper> BlinkConnectorJsWrapper::Create(
gin::ObjectTemplateBuilder BlinkConnectorJsWrapper::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return Wrappable<BlinkConnectorJsWrapper>::GetObjectTemplateBuilder(isolate)
- .SetMethod("bindInterface", &BlinkConnectorJsWrapper::BindInterface)
- .SetMethod("addInterfaceOverrideForTesting",
- &BlinkConnectorJsWrapper::AddOverrideForTesting)
- .SetMethod("clearInterfaceOverridesForTesting",
- &BlinkConnectorJsWrapper::ClearOverridesForTesting);
+ .SetMethod("bindInterface", &BlinkConnectorJsWrapper::BindInterface);
}
mojo::Handle BlinkConnectorJsWrapper::BindInterface(
@@ -54,23 +50,6 @@ mojo::Handle BlinkConnectorJsWrapper::BindInterface(
return pipe.handle1.release();
}
-void BlinkConnectorJsWrapper::AddOverrideForTesting(
- const std::string& service_name,
- const std::string& interface_name,
- v8::Local<v8::Function> service_factory) {
- ScopedJsFactory factory(v8::Isolate::GetCurrent(), service_factory);
- service_manager::Connector::TestApi test_api(connector_.get());
- test_api.OverrideBinderForTesting(
- service_name, interface_name,
- base::Bind(&BlinkConnectorJsWrapper::CallJsFactory,
- weak_factory_.GetWeakPtr(), factory));
-}
-
-void BlinkConnectorJsWrapper::ClearOverridesForTesting() {
- service_manager::Connector::TestApi test_api(connector_.get());
- test_api.ClearBinderOverrides();
-}
-
BlinkConnectorJsWrapper::BlinkConnectorJsWrapper(
v8::Isolate* isolate,
v8::Local<v8::Context> context,
@@ -83,22 +62,6 @@ BlinkConnectorJsWrapper::BlinkConnectorJsWrapper(
v8::WeakCallbackType::kParameter);
}
-void BlinkConnectorJsWrapper::CallJsFactory(
- const ScopedJsFactory& factory,
- mojo::ScopedMessagePipeHandle pipe) {
- if (context_.IsEmpty())
- return;
-
- v8::HandleScope handle_scope(isolate_);
- v8::Local<v8::Context> context = context_.Get(isolate_);
- v8::Context::Scope context_scope(context);
- v8::Local<v8::Value> argv[] = {
- gin::ConvertToV8(isolate_, mojo::Handle(pipe.release().value()))};
- blink::WebLocalFrame::FrameForContext(context)
- ->CallFunctionEvenIfScriptDisabled(factory.Get(isolate_),
- v8::Undefined(isolate_), 1, argv);
-}
-
// static
void BlinkConnectorJsWrapper::ClearContext(
const v8::WeakCallbackInfo<BlinkConnectorJsWrapper>& data) {
diff --git a/chromium/content/renderer/mojo/blink_connector_js_wrapper.h b/chromium/content/renderer/mojo/blink_connector_js_wrapper.h
index 34fe942e60b..40fad97954e 100644
--- a/chromium/content/renderer/mojo/blink_connector_js_wrapper.h
+++ b/chromium/content/renderer/mojo/blink_connector_js_wrapper.h
@@ -37,10 +37,6 @@ class CONTENT_EXPORT BlinkConnectorJsWrapper
v8::Isolate* isolate) override;
// JS interface implementation.
- void AddOverrideForTesting(const std::string& service_name,
- const std::string& interface_name,
- v8::Local<v8::Function> interface_factory);
- void ClearOverridesForTesting();
mojo::Handle BindInterface(const std::string& service_name,
const std::string& interface_name);
diff --git a/chromium/content/renderer/mojo/blink_interface_registry_impl.cc b/chromium/content/renderer/mojo/blink_interface_registry_impl.cc
index 9f53ede0630..34113b87bee 100644
--- a/chromium/content/renderer/mojo/blink_interface_registry_impl.cc
+++ b/chromium/content/renderer/mojo/blink_interface_registry_impl.cc
@@ -12,18 +12,31 @@
namespace content {
BlinkInterfaceRegistryImpl::BlinkInterfaceRegistryImpl(
- base::WeakPtr<service_manager::BinderRegistry> interface_registry)
- : interface_registry_(interface_registry) {}
+ base::WeakPtr<service_manager::BinderRegistry> interface_registry,
+ base::WeakPtr<AssociatedInterfaceRegistryImpl>
+ associated_interface_registry)
+ : interface_registry_(interface_registry),
+ associated_interface_registry_(associated_interface_registry) {}
BlinkInterfaceRegistryImpl::~BlinkInterfaceRegistryImpl() = default;
void BlinkInterfaceRegistryImpl::AddInterface(
const char* name,
- const blink::InterfaceFactory& factory) {
+ const blink::InterfaceFactory& factory,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
if (!interface_registry_)
return;
- interface_registry_->AddInterface(name, factory);
+ interface_registry_->AddInterface(name, factory, std::move(task_runner));
+}
+
+void BlinkInterfaceRegistryImpl::AddAssociatedInterface(
+ const char* name,
+ const blink::AssociatedInterfaceFactory& factory) {
+ if (!associated_interface_registry_)
+ return;
+
+ associated_interface_registry_->AddInterface(name, factory);
}
} // namespace content
diff --git a/chromium/content/renderer/mojo/blink_interface_registry_impl.h b/chromium/content/renderer/mojo/blink_interface_registry_impl.h
index bd6f6b32e3a..82960fd499d 100644
--- a/chromium/content/renderer/mojo/blink_interface_registry_impl.h
+++ b/chromium/content/renderer/mojo/blink_interface_registry_impl.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "content/common/associated_interface_registry_impl.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "third_party/WebKit/public/platform/InterfaceRegistry.h"
@@ -14,16 +15,25 @@ namespace content {
class BlinkInterfaceRegistryImpl final : public blink::InterfaceRegistry {
public:
- explicit BlinkInterfaceRegistryImpl(
- base::WeakPtr<service_manager::BinderRegistry> interface_registry);
+ BlinkInterfaceRegistryImpl(
+ base::WeakPtr<service_manager::BinderRegistry> interface_registry,
+ base::WeakPtr<AssociatedInterfaceRegistryImpl>
+ associated_interface_registry);
~BlinkInterfaceRegistryImpl();
// blink::InterfaceRegistry override.
- void AddInterface(const char* name,
- const blink::InterfaceFactory& factory) override;
+ void AddInterface(
+ const char* name,
+ const blink::InterfaceFactory& factory,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
+ void AddAssociatedInterface(
+ const char* name,
+ const blink::AssociatedInterfaceFactory& factory) override;
private:
const base::WeakPtr<service_manager::BinderRegistry> interface_registry_;
+ const base::WeakPtr<AssociatedInterfaceRegistryImpl>
+ associated_interface_registry_;
DISALLOW_COPY_AND_ASSIGN(BlinkInterfaceRegistryImpl);
};
diff --git a/chromium/content/renderer/mojo/interface_provider_js_wrapper.cc b/chromium/content/renderer/mojo/interface_provider_js_wrapper.cc
index 352ee01b5fe..220105b385c 100644
--- a/chromium/content/renderer/mojo/interface_provider_js_wrapper.cc
+++ b/chromium/content/renderer/mojo/interface_provider_js_wrapper.cc
@@ -11,7 +11,6 @@
#include "mojo/edk/js/handle.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
namespace content {
@@ -50,13 +49,8 @@ gin::Handle<InterfaceProviderJsWrapper> InterfaceProviderJsWrapper::Create(
gin::ObjectTemplateBuilder
InterfaceProviderJsWrapper::GetObjectTemplateBuilder(v8::Isolate* isolate) {
return Wrappable<InterfaceProviderJsWrapper>::GetObjectTemplateBuilder(
- isolate)
- .SetMethod("getInterface",
- &InterfaceProviderJsWrapper::GetInterface)
- .SetMethod("addInterfaceOverrideForTesting",
- &InterfaceProviderJsWrapper::AddOverrideForTesting)
- .SetMethod("clearInterfaceOverridesForTesting",
- &InterfaceProviderJsWrapper::ClearOverridesForTesting);
+ isolate)
+ .SetMethod("getInterface", &InterfaceProviderJsWrapper::GetInterface);
}
mojo::Handle InterfaceProviderJsWrapper::GetInterface(
@@ -74,34 +68,6 @@ mojo::Handle InterfaceProviderJsWrapper::GetInterface(
return pipe.handle1.release();
}
-void InterfaceProviderJsWrapper::AddOverrideForTesting(
- const std::string& interface_name,
- v8::Local<v8::Function> service_factory) {
- ScopedJsFactory factory(v8::Isolate::GetCurrent(), service_factory);
- BindCallback callback = base::Bind(&InterfaceProviderJsWrapper::CallJsFactory,
- weak_factory_.GetWeakPtr(), factory);
- if (remote_interfaces_) {
- service_manager::InterfaceProvider::TestApi test_api(
- remote_interfaces_.get());
- test_api.SetBinderForName(interface_name, callback);
- } else if (connector_) {
- service_manager::Connector::TestApi test_api(connector_.get());
- test_api.OverrideBinderForTesting(mojom::kBrowserServiceName,
- interface_name, callback);
- }
-}
-
-void InterfaceProviderJsWrapper::ClearOverridesForTesting() {
- if (remote_interfaces_) {
- service_manager::InterfaceProvider::TestApi test_api(
- remote_interfaces_.get());
- test_api.ClearBinders();
- } else if (connector_) {
- service_manager::Connector::TestApi test_api(connector_.get());
- test_api.ClearBinderOverrides();
- }
-}
-
InterfaceProviderJsWrapper::InterfaceProviderJsWrapper(
v8::Isolate* isolate,
v8::Local<v8::Context> context,
@@ -126,22 +92,6 @@ InterfaceProviderJsWrapper::InterfaceProviderJsWrapper(
v8::WeakCallbackType::kParameter);
}
-void InterfaceProviderJsWrapper::CallJsFactory(
- const ScopedJsFactory& factory,
- mojo::ScopedMessagePipeHandle pipe) {
- if (context_.IsEmpty())
- return;
-
- v8::HandleScope handle_scope(isolate_);
- v8::Local<v8::Context> context = context_.Get(isolate_);
- v8::Context::Scope context_scope(context);
- v8::Local<v8::Value> argv[] = {
- gin::ConvertToV8(isolate_, mojo::Handle(pipe.release().value()))};
- blink::WebLocalFrame::FrameForContext(context)
- ->CallFunctionEvenIfScriptDisabled(factory.Get(isolate_),
- v8::Undefined(isolate_), 1, argv);
-}
-
// static
void InterfaceProviderJsWrapper::ClearContext(
const v8::WeakCallbackInfo<InterfaceProviderJsWrapper>& data) {
diff --git a/chromium/content/renderer/mojo/interface_provider_js_wrapper.h b/chromium/content/renderer/mojo/interface_provider_js_wrapper.h
index b6dd37a8ea0..b0f00b27e6a 100644
--- a/chromium/content/renderer/mojo/interface_provider_js_wrapper.h
+++ b/chromium/content/renderer/mojo/interface_provider_js_wrapper.h
@@ -42,9 +42,6 @@ class CONTENT_EXPORT InterfaceProviderJsWrapper
v8::Isolate* isolate) override;
// JS interface implementation.
- void AddOverrideForTesting(const std::string& interface_name,
- v8::Local<v8::Function> interface_factory);
- void ClearOverridesForTesting();
mojo::Handle GetInterface(const std::string& interface_name);
static gin::WrapperInfo kWrapperInfo;
diff --git a/chromium/content/renderer/mojo_bindings_controller.cc b/chromium/content/renderer/mojo_bindings_controller.cc
deleted file mode 100644
index e17bf7e1d0c..00000000000
--- a/chromium/content/renderer/mojo_bindings_controller.cc
+++ /dev/null
@@ -1,129 +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/mojo_bindings_controller.h"
-
-#include "base/memory/ptr_util.h"
-#include "content/common/view_messages.h"
-#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/render_view.h"
-#include "content/renderer/mojo_context_state.h"
-#include "gin/per_context_data.h"
-#include "third_party/WebKit/public/web/WebContextFeatures.h"
-#include "third_party/WebKit/public/web/WebKit.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebView.h"
-#include "v8/include/v8.h"
-
-namespace content {
-
-namespace {
-
-const char kMojoContextStateKey[] = "MojoContextState";
-
-struct MojoContextStateData : public base::SupportsUserData::Data {
- std::unique_ptr<MojoContextState> state;
-};
-
-} // namespace
-
-MojoBindingsController::MojoBindingsController(RenderFrame* render_frame,
- MojoBindingsType bindings_type)
- : RenderFrameObserver(render_frame),
- RenderFrameObserverTracker<MojoBindingsController>(render_frame),
- bindings_type_(bindings_type) {}
-
-MojoBindingsController::~MojoBindingsController() {
-}
-
-void MojoBindingsController::CreateContextState() {
- v8::HandleScope handle_scope(blink::MainThreadIsolate());
- blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
- v8::Local<v8::Context> context = frame->MainWorldScriptContext();
- gin::PerContextData* context_data = gin::PerContextData::From(context);
- auto data = base::MakeUnique<MojoContextStateData>();
- data->state.reset(new MojoContextState(frame, context, bindings_type_));
- context_data->SetUserData(kMojoContextStateKey, std::move(data));
-}
-
-void MojoBindingsController::DestroyContextState(
- v8::Local<v8::Context> context) {
- gin::PerContextData* context_data = gin::PerContextData::From(context);
- if (!context_data)
- return;
- context_data->RemoveUserData(kMojoContextStateKey);
-}
-
-MojoContextState* MojoBindingsController::GetContextState() {
- v8::HandleScope handle_scope(blink::MainThreadIsolate());
- v8::Local<v8::Context> context =
- render_frame()->GetWebFrame()->MainWorldScriptContext();
- gin::PerContextData* context_data = gin::PerContextData::From(context);
- if (!context_data)
- return NULL;
- MojoContextStateData* context_state = static_cast<MojoContextStateData*>(
- context_data->GetUserData(kMojoContextStateKey));
- return context_state ? context_state->state.get() : NULL;
-}
-
-void MojoBindingsController::DidCreateScriptContext(
- v8::Local<v8::Context> context,
- int world_id) {
- // NOTE: Layout tests already get this turned on by the RuntimeEnabled feature
- // setting. We avoid manually installing them here for layout tests, because
- // some layout tests (namely at
- // least virtual/stable/webexposed/global-interface-listing.html) may be run
- // with such features explicitly disabled. We do not want to unconditionally
- // install Mojo bindings in such environments.
- //
- // We also only allow these bindings to be installed when creating the main
- // world context.
- if (bindings_type_ != MojoBindingsType::FOR_LAYOUT_TESTS && world_id == 0) {
- blink::WebContextFeatures::EnableMojoJS(context, true);
- // These bindings are only needed by WebUI tests however the browsertest
- // framework does not currently inform the renderer if it is being started
- // by a test. The gin bindings also expose the test interface to WebUI
- // contexts.
- blink::WebContextFeatures::EnableMojoJSTest(context, true);
- }
-}
-
-void MojoBindingsController::WillReleaseScriptContext(
- v8::Local<v8::Context> context,
- int world_id) {
- DestroyContextState(context);
-}
-
-void MojoBindingsController::RunScriptsAtDocumentStart() {
- CreateContextState();
-}
-
-void MojoBindingsController::RunScriptsAtDocumentReady() {
- v8::HandleScope handle_scope(blink::MainThreadIsolate());
- MojoContextState* state = GetContextState();
- if (state)
- state->Run();
-}
-
-void MojoBindingsController::DidClearWindowObject() {
- // NOTE: this function may be called early on twice. From the constructor
- // mainWorldScriptContext() may trigger this to be called. If we are created
- // before the page is loaded (which is very likely), then on first load this
- // is called. In the case of the latter we may have already supplied the
- // handle to the context state so that if we destroy now the handle is
- // lost. If this is the result of the first load then the contextstate should
- // be empty and we don't need to destroy it.
- MojoContextState* state = GetContextState();
- if (state && !state->module_added())
- return;
-
- v8::HandleScope handle_scope(blink::MainThreadIsolate());
- DestroyContextState(render_frame()->GetWebFrame()->MainWorldScriptContext());
-}
-
-void MojoBindingsController::OnDestruct() {
- delete this;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/mojo_bindings_controller.h b/chromium/content/renderer/mojo_bindings_controller.h
deleted file mode 100644
index 0a684393599..00000000000
--- a/chromium/content/renderer/mojo_bindings_controller.h
+++ /dev/null
@@ -1,60 +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_MOJO_BINDINGS_CONTROLLER_H_
-#define CONTENT_RENDERER_MOJO_BINDINGS_CONTROLLER_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "content/public/renderer/render_frame_observer.h"
-#include "content/public/renderer/render_frame_observer_tracker.h"
-#include "mojo/public/cpp/system/core.h"
-
-namespace content {
-
-class MojoContextState;
-
-enum class MojoBindingsType { FOR_WEB_UI, FOR_LAYOUT_TESTS };
-
-// MojoBindingsController is responsible for enabling the renderer side of mojo
-// bindings. It creates (and destroys) a MojoContextState at the appropriate
-// times and handles the necessary browser messages. MojoBindingsController
-// destroys itself when the RendererFrame it is created with is destroyed.
-//
-// TODO(rockot): Clean up this class as we migrate everything to the native
-// Blink bindings, which only require the implementation of
-// DidCreateScriptContext() we have here.
-class MojoBindingsController
- : public RenderFrameObserver,
- public RenderFrameObserverTracker<MojoBindingsController> {
- public:
- MojoBindingsController(RenderFrame* render_frame,
- MojoBindingsType bindings_type);
- void RunScriptsAtDocumentStart();
- void RunScriptsAtDocumentReady();
-
- private:
- ~MojoBindingsController() override;
-
- void CreateContextState();
- void DestroyContextState(v8::Local<v8::Context> context);
- MojoContextState* GetContextState();
-
- // RenderFrameObserver overrides:
- void DidCreateScriptContext(v8::Local<v8::Context> context,
- int world_id) override;
- void WillReleaseScriptContext(v8::Local<v8::Context> context,
- int world_id) override;
- void DidClearWindowObject() override;
- void OnDestruct() override;
-
- const MojoBindingsType bindings_type_;
-
- DISALLOW_COPY_AND_ASSIGN(MojoBindingsController);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MOJO_BINDINGS_CONTROLLER_H_
diff --git a/chromium/content/renderer/mojo_context_state.cc b/chromium/content/renderer/mojo_context_state.cc
deleted file mode 100644
index c9cae485740..00000000000
--- a/chromium/content/renderer/mojo_context_state.cc
+++ /dev/null
@@ -1,267 +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/mojo_context_state.h"
-
-#include <stddef.h>
-
-#include <map>
-#include <string>
-
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/stl_util.h"
-#include "content/grit/content_resources.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
-#include "content/public/common/content_client.h"
-#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/resource_fetcher.h"
-#include "content/renderer/mojo_bindings_controller.h"
-#include "content/renderer/mojo_main_runner.h"
-#include "gin/converter.h"
-#include "gin/modules/module_registry.h"
-#include "gin/per_context_data.h"
-#include "gin/public/context_holder.h"
-#include "gin/try_catch.h"
-#include "mojo/public/js/constants.h"
-#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
-#include "third_party/WebKit/public/platform/WebURLResponse.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebScriptSource.h"
-
-using v8::Context;
-using v8::HandleScope;
-using v8::Isolate;
-using v8::Object;
-using v8::ObjectTemplate;
-using v8::Script;
-
-namespace content {
-
-namespace {
-
-void RunMain(base::WeakPtr<gin::Runner> runner,
- v8::Local<v8::Value> module) {
- v8::Isolate* isolate = runner->GetContextHolder()->isolate();
- v8::Local<v8::Function> start;
- CHECK(gin::ConvertFromV8(isolate, module, &start));
- runner->Call(start, runner->global(), 0, NULL);
-}
-
-using ModuleSourceMap =
- std::map<std::string, scoped_refptr<base::RefCountedMemory>>;
-
-base::LazyInstance<std::unique_ptr<ModuleSourceMap>>::Leaky g_module_sources;
-
-scoped_refptr<base::RefCountedMemory> GetBuiltinModuleData(
- const std::string& path) {
- static const struct {
- const char* path;
- const int id;
- } kBuiltinModuleResources[] = {
- {mojo::kAssociatedBindingsModuleName, IDR_MOJO_ASSOCIATED_BINDINGS_JS},
- {mojo::kBindingsModuleName, IDR_MOJO_BINDINGS_JS},
- {mojo::kBufferModuleName, IDR_MOJO_BUFFER_JS},
- {mojo::kCodecModuleName, IDR_MOJO_CODEC_JS},
- {mojo::kConnectorModuleName, IDR_MOJO_CONNECTOR_JS},
- {mojo::kControlMessageHandlerModuleName,
- IDR_MOJO_CONTROL_MESSAGE_HANDLER_JS},
- {mojo::kControlMessageProxyModuleName, IDR_MOJO_CONTROL_MESSAGE_PROXY_JS},
- {mojo::kInterfaceControlMessagesMojom,
- IDR_MOJO_INTERFACE_CONTROL_MESSAGES_MOJOM_JS},
- {mojo::kInterfaceEndpointClientModuleName,
- IDR_MOJO_INTERFACE_ENDPOINT_CLIENT_JS},
- {mojo::kInterfaceEndpointHandleModuleName,
- IDR_MOJO_INTERFACE_ENDPOINT_HANDLE_JS},
- {mojo::kInterfaceTypesModuleName, IDR_MOJO_INTERFACE_TYPES_JS},
- {mojo::kPipeControlMessageHandlerModuleName,
- IDR_MOJO_PIPE_CONTROL_MESSAGE_HANDLER_JS},
- {mojo::kPipeControlMessageProxyModuleName,
- IDR_MOJO_PIPE_CONTROL_MESSAGE_PROXY_JS},
- {mojo::kPipeControlMessagesMojom,
- IDR_MOJO_PIPE_CONTROL_MESSAGES_MOJOM_JS},
- {mojo::kRouterModuleName, IDR_MOJO_ROUTER_JS},
- {mojo::kUnicodeModuleName, IDR_MOJO_UNICODE_JS},
- {mojo::kValidatorModuleName, IDR_MOJO_VALIDATOR_JS},
- };
-
- std::unique_ptr<ModuleSourceMap>& module_sources = g_module_sources.Get();
- if (!module_sources) {
- // Initialize the module source map on first access.
- module_sources.reset(new ModuleSourceMap);
- for (size_t i = 0; i < arraysize(kBuiltinModuleResources); ++i) {
- const auto& resource = kBuiltinModuleResources[i];
- scoped_refptr<base::RefCountedMemory> data =
- GetContentClient()->GetDataResourceBytes(resource.id);
- DCHECK_GT(data->size(), 0u);
- module_sources->insert(std::make_pair(std::string(resource.path), data));
- }
- }
-
- DCHECK(module_sources);
- auto source_iter = module_sources->find(path);
- if (source_iter == module_sources->end())
- return nullptr;
- return source_iter->second;
-}
-
-std::string GetModulePrefixForBindingsType(MojoBindingsType bindings_type,
- blink::WebLocalFrame* frame) {
- switch (bindings_type) {
- case MojoBindingsType::FOR_WEB_UI:
- return frame->GetSecurityOrigin().ToString().Utf8() + "/";
- case MojoBindingsType::FOR_LAYOUT_TESTS:
- return "layout-test-mojom://";
- }
- NOTREACHED();
- return "";
-}
-
-} // namespace
-
-MojoContextState::MojoContextState(blink::WebLocalFrame* frame,
- v8::Local<v8::Context> context,
- MojoBindingsType bindings_type)
- : frame_(frame),
- module_added_(false),
- module_prefix_(GetModulePrefixForBindingsType(bindings_type, frame)) {
- gin::PerContextData* context_data = gin::PerContextData::From(context);
- gin::ContextHolder* context_holder = context_data->context_holder();
- runner_.reset(new MojoMainRunner(frame_, context_holder));
- gin::Runner::Scope scoper(runner_.get());
- gin::ModuleRegistry::From(context)->AddObserver(this);
- content::RenderFrame::FromWebFrame(frame)
- ->EnsureMojoBuiltinsAreAvailable(context_holder->isolate(), context);
- v8::Local<v8::Object> install_target;
- if (bindings_type == MojoBindingsType::FOR_LAYOUT_TESTS) {
- // In layout tests we install the module system under 'gin.define'
- // for now to avoid globally exposing something as generic as 'define'.
- //
- // TODO(rockot): Remove this if/when we can integrate gin + ES6 modules.
- install_target = v8::Object::New(context->GetIsolate());
- gin::SetProperty(context->GetIsolate(), context->Global(),
- gin::StringToSymbol(context->GetIsolate(), "gin"),
- install_target);
- } else {
- // Otherwise we're fine installing a global 'define'.
- install_target = context->Global();
- }
- gin::ModuleRegistry::InstallGlobals(context->GetIsolate(), install_target);
- // Warning |frame| may be destroyed.
- // TODO(sky): add test for this.
-}
-
-MojoContextState::~MojoContextState() {
- gin::Runner::Scope scoper(runner_.get());
- gin::ModuleRegistry::From(
- runner_->GetContextHolder()->context())->RemoveObserver(this);
-}
-
-void MojoContextState::Run() {
- gin::ContextHolder* context_holder = runner_->GetContextHolder();
- gin::ModuleRegistry::From(context_holder->context())->LoadModule(
- context_holder->isolate(),
- "main",
- base::Bind(RunMain, runner_->GetWeakPtr()));
-}
-
-void MojoContextState::FetchModules(const std::vector<std::string>& ids) {
- gin::Runner::Scope scoper(runner_.get());
- gin::ContextHolder* context_holder = runner_->GetContextHolder();
- gin::ModuleRegistry* registry = gin::ModuleRegistry::From(
- context_holder->context());
- for (size_t i = 0; i < ids.size(); ++i) {
- if (fetched_modules_.find(ids[i]) == fetched_modules_.end() &&
- registry->available_modules().count(ids[i]) == 0) {
- scoped_refptr<base::RefCountedMemory> data = GetBuiltinModuleData(ids[i]);
- if (data)
- runner_->Run(std::string(data->front_as<char>(), data->size()), ids[i]);
- else
- FetchModule(ids[i]);
- }
- }
-}
-
-void MojoContextState::FetchModule(const std::string& id) {
- static const net::NetworkTrafficAnnotationTag network_traffic_annotation_tag =
- net::DefineNetworkTrafficAnnotation("mojo_context_state", R"(
- semantics {
- sender: "MojoContextState"
- description:
- "Chrome does fetch for AMD-style module loading of Mojo JavaScript "
- "bindings."
- trigger:
- "When AMD-style module loading of Mojo JavaScript bindings is used."
- data:
- "Load JavaScript files for Mojo bindings from embedded resources. "
- "Nothing is sent over networks."
- destination: OTHER
- }
- policy {
- cookies_allowed: NO
- setting: "These requests cannot be disabled in settings."
- policy_exception_justification:
- "Not implemented. Without these requests, Chrome will not work."
- })");
-
- const GURL url(module_prefix_ + id);
- // TODO(sky): better error checks here?
- DCHECK(url.is_valid() && !url.is_empty());
- DCHECK(fetched_modules_.find(id) == fetched_modules_.end());
- fetched_modules_.insert(id);
- module_fetchers_.push_back(ResourceFetcher::Create(url));
- module_fetchers_.back()->Start(
- frame_, blink::WebURLRequest::kRequestContextScript,
- RenderFrame::FromWebFrame(frame_)
- ->GetDefaultURLLoaderFactoryGetter()
- ->GetNetworkLoaderFactory(),
- network_traffic_annotation_tag,
- base::BindOnce(&MojoContextState::OnFetchModuleComplete,
- base::Unretained(this), module_fetchers_.back().get(),
- id));
-}
-
-void MojoContextState::OnFetchModuleComplete(
- ResourceFetcher* fetcher,
- const std::string& id,
- const blink::WebURLResponse& response,
- const std::string& data) {
- if (response.IsNull()) {
- LOG(ERROR) << "Failed to fetch source for module \"" << id << "\"";
- return;
- }
- DCHECK_EQ(module_prefix_ + id, response.Url().GetString().Utf8());
- // We can't delete fetch right now as the arguments to this function come from
- // it and are used below. Instead use a scope_ptr to cleanup.
- auto iter =
- std::find_if(module_fetchers_.begin(), module_fetchers_.end(),
- [fetcher](const std::unique_ptr<ResourceFetcher>& item) {
- return item.get() == fetcher;
- });
- std::unique_ptr<ResourceFetcher> deleter = std::move(*iter);
- module_fetchers_.erase(iter);
-
- if (data.empty()) {
- LOG(ERROR) << "Fetched empty source for module \"" << id << "\"";
- return;
- }
-
- runner_->Run(data, id);
-}
-
-void MojoContextState::OnDidAddPendingModule(
- const std::string& id,
- const std::vector<std::string>& dependencies) {
- FetchModules(dependencies);
-
- gin::ContextHolder* context_holder = runner_->GetContextHolder();
- gin::ModuleRegistry* registry = gin::ModuleRegistry::From(
- context_holder->context());
- registry->AttemptToLoadMoreModules(context_holder->isolate());
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/mojo_context_state.h b/chromium/content/renderer/mojo_context_state.h
deleted file mode 100644
index 7b67ee3f6ba..00000000000
--- a/chromium/content/renderer/mojo_context_state.h
+++ /dev/null
@@ -1,86 +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_MOJO_CONTEXT_STATE_H_
-#define CONTENT_RENDERER_MOJO_CONTEXT_STATE_H_
-
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "gin/modules/module_registry_observer.h"
-#include "v8/include/v8.h"
-
-namespace blink {
-class WebLocalFrame;
-class WebURLResponse;
-}
-
-namespace content {
-
-class ResourceFetcher;
-class MojoMainRunner;
-enum class MojoBindingsType;
-
-// MojoContextState manages the modules needed for mojo bindings. It does this
-// by way of gin. Non-builtin modules are downloaded by way of ResourceFetchers.
-class MojoContextState : public gin::ModuleRegistryObserver {
- public:
- MojoContextState(blink::WebLocalFrame* frame,
- v8::Local<v8::Context> context,
- MojoBindingsType bindings_type);
- ~MojoContextState() override;
-
- void Run();
-
- // Returns true if at least one module was added.
- bool module_added() const { return module_added_; }
-
- private:
- class Loader;
-
- // Invokes FetchModule() for any modules that have not already been
- // downloaded.
- void FetchModules(const std::vector<std::string>& ids);
-
- // Creates a ResourceFetcher to download |module|.
- void FetchModule(const std::string& module);
-
- // Callback once a module has finished downloading. Passes data to |runner_|.
- void OnFetchModuleComplete(ResourceFetcher* fetcher,
- const std::string& id,
- const blink::WebURLResponse& response,
- const std::string& data);
-
- // gin::ModuleRegistryObserver overrides:
- void OnDidAddPendingModule(
- const std::string& id,
- const std::vector<std::string>& dependencies) override;
-
- // Frame script is executed in. Also used to download resources.
- blink::WebLocalFrame* frame_;
-
- // See description above getter.
- bool module_added_;
-
- // Executes the script from gin.
- std::unique_ptr<MojoMainRunner> runner_;
-
- // Set of fetchers we're waiting on to download script.
- std::vector<std::unique_ptr<ResourceFetcher>> module_fetchers_;
-
- // Set of modules we've fetched script from.
- std::set<std::string> fetched_modules_;
-
- // The prefix to use for all module requests.
- const std::string module_prefix_;
-
- DISALLOW_COPY_AND_ASSIGN(MojoContextState);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MOJO_CONTEXT_STATE_H_
diff --git a/chromium/content/renderer/mojo_main_runner.cc b/chromium/content/renderer/mojo_main_runner.cc
deleted file mode 100644
index 0fb5ebe6b0c..00000000000
--- a/chromium/content/renderer/mojo_main_runner.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/mojo_main_runner.h"
-
-#include "content/public/renderer/render_frame.h"
-#include "gin/modules/module_registry.h"
-#include "gin/per_context_data.h"
-#include "gin/public/context_holder.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebScriptSource.h"
-
-using v8::Context;
-using v8::HandleScope;
-using v8::Isolate;
-using v8::Object;
-using v8::ObjectTemplate;
-using v8::Script;
-
-namespace content {
-
-MojoMainRunner::MojoMainRunner(blink::WebLocalFrame* frame,
- gin::ContextHolder* context_holder)
- : frame_(frame), context_holder_(context_holder) {
- DCHECK(frame_);
- v8::Isolate::Scope isolate_scope(context_holder->isolate());
- HandleScope handle_scope(context_holder->isolate());
- // Note: this installs the runner globally. If we need to support more than
- // one runner at a time we'll have to revisit this.
- gin::PerContextData::From(context_holder->context())->set_runner(this);
-}
-
-MojoMainRunner::~MojoMainRunner() {
-}
-
-void MojoMainRunner::Run(const std::string& source,
- const std::string& resource_name) {
- frame_->ExecuteScript(
- blink::WebScriptSource(blink::WebString::FromUTF8(source)));
-}
-
-v8::Local<v8::Value> MojoMainRunner::Call(v8::Local<v8::Function> function,
- v8::Local<v8::Value> receiver,
- int argc,
- v8::Local<v8::Value> argv[]) {
- return frame_->CallFunctionEvenIfScriptDisabled(function, receiver, argc,
- argv);
-}
-
-gin::ContextHolder* MojoMainRunner::GetContextHolder() {
- return context_holder_;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/mojo_main_runner.h b/chromium/content/renderer/mojo_main_runner.h
deleted file mode 100644
index f8087bfed30..00000000000
--- a/chromium/content/renderer/mojo_main_runner.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MOJO_MAIN_RUNNER_H_
-#define CONTENT_RENDERER_MOJO_MAIN_RUNNER_H_
-
-#include "base/macros.h"
-#include "gin/runner.h"
-
-namespace blink {
-class WebLocalFrame;
-}
-
-namespace content {
-
-// Implementation of gin::Runner that forwards Runner functions to WebFrame.
-class MojoMainRunner : public gin::Runner {
- public:
- // Does not take ownership of ContextHolder.
- MojoMainRunner(blink::WebLocalFrame* frame,
- gin::ContextHolder* context_holder);
- ~MojoMainRunner() override;
-
- // Runner overrides:
- void Run(const std::string& source,
- const std::string& resource_name) override;
- v8::Local<v8::Value> Call(v8::Local<v8::Function> function,
- v8::Local<v8::Value> receiver,
- int argc,
- v8::Local<v8::Value> argv[]) override;
- gin::ContextHolder* GetContextHolder() override;
-
- private:
- // Frame to execute script in.
- blink::WebLocalFrame* frame_;
-
- // Created by blink bindings to V8.
- gin::ContextHolder* context_holder_;
-
- DISALLOW_COPY_AND_ASSIGN(MojoMainRunner);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MOJO_MAIN_RUNNER_H_
diff --git a/chromium/content/renderer/mouse_lock_dispatcher.cc b/chromium/content/renderer/mouse_lock_dispatcher.cc
index 5b42b6e965a..eba09d869bd 100644
--- a/chromium/content/renderer/mouse_lock_dispatcher.cc
+++ b/chromium/content/renderer/mouse_lock_dispatcher.cc
@@ -9,11 +9,11 @@
namespace content {
-MouseLockDispatcher::MouseLockDispatcher() : mouse_locked_(false),
- pending_lock_request_(false),
- pending_unlock_request_(false),
- target_(NULL) {
-}
+MouseLockDispatcher::MouseLockDispatcher()
+ : mouse_locked_(false),
+ pending_lock_request_(false),
+ pending_unlock_request_(false),
+ target_(nullptr) {}
MouseLockDispatcher::~MouseLockDispatcher() {
}
@@ -40,7 +40,7 @@ void MouseLockDispatcher::UnlockMouse(LockTarget* target) {
void MouseLockDispatcher::OnLockTargetDestroyed(LockTarget* target) {
if (target == target_) {
UnlockMouse(target);
- target_ = NULL;
+ target_ = nullptr;
}
}
@@ -69,7 +69,7 @@ void MouseLockDispatcher::OnLockMouseACK(bool succeeded) {
LockTarget* last_target = target_;
if (!succeeded)
- target_ = NULL;
+ target_ = nullptr;
// Callbacks made after all state modification to prevent reentrant errors
// such as OnLockMouseACK() synchronously calling LockMouse().
@@ -85,7 +85,7 @@ void MouseLockDispatcher::OnMouseLockLost() {
pending_unlock_request_ = false;
LockTarget* last_target = target_;
- target_ = NULL;
+ target_ = nullptr;
// Callbacks made after all state modification to prevent reentrant errors
// such as OnMouseLockLost() synchronously calling LockMouse().
diff --git a/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc b/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
index 3096394ab25..e2ad5ca0706 100644
--- a/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
+++ b/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
@@ -83,7 +83,7 @@ TEST_F(MouseLockDispatcherTest, BasicMockLockTarget) {
EXPECT_CALL(*target_, OnLockMouseACK(false));
// Start unlocked.
- EXPECT_FALSE(dispatcher()->IsMouseLockedTo(NULL));
+ EXPECT_FALSE(dispatcher()->IsMouseLockedTo(nullptr));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
// Lock.
@@ -121,7 +121,7 @@ TEST_F(MouseLockDispatcherTest, DeleteAndUnlock) {
// Don't receive mouse events or lock lost.
dispatcher()->OnLockTargetDestroyed(target_);
delete target_;
- target_ = NULL;
+ target_ = nullptr;
dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
@@ -139,7 +139,7 @@ TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockSuccess) {
// Before receiving response delete the target.
dispatcher()->OnLockTargetDestroyed(target_);
delete target_;
- target_ = NULL;
+ target_ = nullptr;
// Lock response.
widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
@@ -157,7 +157,7 @@ TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockFail) {
// Before receiving response delete the target.
dispatcher()->OnLockTargetDestroyed(target_);
delete target_;
- target_ = NULL;
+ target_ = nullptr;
// Lock response.
widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
diff --git a/chromium/content/renderer/mus/BUILD.gn b/chromium/content/renderer/mus/BUILD.gn
index 502f4a7f794..2271a155d0c 100644
--- a/chromium/content/renderer/mus/BUILD.gn
+++ b/chromium/content/renderer/mus/BUILD.gn
@@ -7,6 +7,9 @@ static_library("mus") {
visibility = [ "//content/renderer/*" ]
sources = [
+ "mus_embedded_frame.cc",
+ "mus_embedded_frame.h",
+ "mus_embedded_frame_delegate.h",
"render_widget_window_tree_client_factory.cc",
"render_widget_window_tree_client_factory.h",
"renderer_window_tree_client.cc",
diff --git a/chromium/content/renderer/mus/mus_embedded_frame.cc b/chromium/content/renderer/mus/mus_embedded_frame.cc
new file mode 100644
index 00000000000..81aadcbe6ec
--- /dev/null
+++ b/chromium/content/renderer/mus/mus_embedded_frame.cc
@@ -0,0 +1,121 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/mus/mus_embedded_frame.h"
+
+#include <map>
+
+#include "base/command_line.h"
+#include "base/lazy_instance.h"
+#include "cc/base/switches.h"
+#include "components/viz/client/client_layer_tree_frame_sink.h"
+#include "components/viz/client/hit_test_data_provider.h"
+#include "components/viz/client/local_surface_id_provider.h"
+#include "components/viz/common/surfaces/surface_sequence.h"
+#include "content/renderer/mus/renderer_window_tree_client.h"
+#include "services/ui/public/cpp/property_type_converters.h"
+#include "services/ui/public/interfaces/window_manager.mojom.h"
+
+namespace content {
+namespace {
+
+// Callback from embedding a child frame.
+void OnEmbedAck(bool success) {
+ DCHECK(success);
+}
+
+} // namespace
+
+MusEmbeddedFrame::~MusEmbeddedFrame() {
+ renderer_window_tree_client_->OnEmbeddedFrameDestroyed(this);
+
+ // If the tree changed the old tree the window was created in was dropped and
+ // the server implictly cleaned up. As such, no need to do cleanup here (and
+ // we don't have a handle to the right WindowTree at this point).
+ if (tree_changed_)
+ return;
+
+ // If there is |pending_state_| it means we didn't actually create the window
+ // yet and there is nothing to do.
+ if (pending_state_)
+ return;
+
+ window_tree()->DeleteWindow(GetAndAdvanceNextChangeId(), window_id_);
+}
+
+void MusEmbeddedFrame::SetWindowBounds(
+ const viz::LocalSurfaceId& local_surface_id,
+ const gfx::Rect& bounds) {
+ if (tree_changed_)
+ return;
+
+ if (!window_tree()) {
+ DCHECK(pending_state_);
+ pending_state_->bounds = bounds;
+ pending_state_->local_surface_id = local_surface_id;
+ pending_state_->was_set_window_bounds_called = true;
+ return;
+ }
+
+ window_tree()->SetWindowBounds(GetAndAdvanceNextChangeId(), window_id_,
+ bounds, local_surface_id);
+}
+
+MusEmbeddedFrame::MusEmbeddedFrame(
+ RendererWindowTreeClient* renderer_window_tree_client,
+ MusEmbeddedFrameDelegate* delegate,
+ ui::ClientSpecificId window_id,
+ const base::UnguessableToken& token)
+ : renderer_window_tree_client_(renderer_window_tree_client),
+ delegate_(delegate),
+ window_id_(window_id) {
+ if (!window_tree()) {
+ pending_state_ = std::make_unique<PendingState>();
+ pending_state_->token = token;
+ return;
+ }
+ CreateChildWindowAndEmbed(token);
+}
+
+void MusEmbeddedFrame::CreateChildWindowAndEmbed(
+ const base::UnguessableToken& token) {
+ // Set a name for debugging.
+ std::unordered_map<std::string, std::vector<uint8_t>> properties;
+ properties[ui::mojom::WindowManager::kName_Property] =
+ mojo::ConvertTo<std::vector<uint8_t>>(std::string("RendererFrame"));
+ window_tree()->NewWindow(GetAndAdvanceNextChangeId(), window_id_, properties);
+ window_tree()->AddWindow(GetAndAdvanceNextChangeId(),
+ renderer_window_tree_client_->root_window_id_,
+ window_id_);
+ window_tree()->EmbedUsingToken(window_id_, token, 0, base::Bind(&OnEmbedAck));
+}
+
+void MusEmbeddedFrame::OnTreeAvailable() {
+ // See header for description, always called before OnTreeWillChange().
+ DCHECK(!tree_changed_);
+ std::unique_ptr<PendingState> pending_state = std::move(pending_state_);
+ CreateChildWindowAndEmbed(pending_state->token);
+ if (pending_state->was_set_window_bounds_called)
+ SetWindowBounds(pending_state->local_surface_id, pending_state->bounds);
+}
+
+void MusEmbeddedFrame::OnTreeWillChange() {
+ tree_changed_ = true;
+}
+
+uint32_t MusEmbeddedFrame::GetAndAdvanceNextChangeId() {
+ return renderer_window_tree_client_->GetAndAdvanceNextChangeId();
+}
+
+ui::mojom::WindowTree* MusEmbeddedFrame::window_tree() {
+ // Once |tree_changed_| is true the WindowTree this instance used has changed
+ // and it no longer makes sense to use it (the original window was deleted).
+ return tree_changed_ ? nullptr : renderer_window_tree_client_->tree_.get();
+}
+
+MusEmbeddedFrame::PendingState::PendingState() = default;
+
+MusEmbeddedFrame::PendingState::~PendingState() = default;
+
+} // namespace content
diff --git a/chromium/content/renderer/mus/mus_embedded_frame.h b/chromium/content/renderer/mus/mus_embedded_frame.h
new file mode 100644
index 00000000000..3639c8af1ef
--- /dev/null
+++ b/chromium/content/renderer/mus/mus_embedded_frame.h
@@ -0,0 +1,87 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_H_
+#define CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/unguessable_token.h"
+#include "components/viz/common/surfaces/local_surface_id.h"
+#include "services/ui/common/types.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace ui {
+namespace mojom {
+class WindowTree;
+}
+} // namespace ui
+
+namespace content {
+
+class MusEmbeddedFrameDelegate;
+class RendererWindowTreeClient;
+
+// MusEmbeddedFrame represents an embedding of an OOPIF frame. Internally this
+// creates a window in the window server and calls Embed().
+class MusEmbeddedFrame {
+ public:
+ ~MusEmbeddedFrame();
+
+ // Sets the bounds (in pixels) of the embedded frame.
+ void SetWindowBounds(const viz::LocalSurfaceId& local_surface_id,
+ const gfx::Rect& bounds);
+
+ private:
+ friend class RendererWindowTreeClient;
+
+ // Stores state that needs to pushed to the server once the connection has
+ // been established (OnEmbed() is called).
+ struct PendingState {
+ PendingState();
+ ~PendingState();
+
+ base::UnguessableToken token;
+ viz::LocalSurfaceId local_surface_id;
+ gfx::Rect bounds;
+ // True if SetWindowBounds() was called.
+ bool was_set_window_bounds_called = false;
+ };
+
+ MusEmbeddedFrame(RendererWindowTreeClient* renderer_window_tree_client,
+ MusEmbeddedFrameDelegate* delegate,
+ ui::ClientSpecificId window_id,
+ const base::UnguessableToken& token);
+
+ // Called once the WindowTree has been obtained. This is only called if
+ // the MusEmbeddedFrame is created before the WindowTree has been obtained.
+ void OnTreeAvailable();
+
+ // Called when the WindowTree held by |renderer_window_tree_client_| is about
+ // to change. This means the renderer was reembeded.
+ void OnTreeWillChange();
+
+ // Does the actual embedding.
+ void CreateChildWindowAndEmbed(const base::UnguessableToken& token);
+
+ uint32_t GetAndAdvanceNextChangeId();
+
+ ui::mojom::WindowTree* window_tree();
+
+ RendererWindowTreeClient* renderer_window_tree_client_;
+ MusEmbeddedFrameDelegate* delegate_;
+ const ui::ClientSpecificId window_id_;
+
+ std::unique_ptr<PendingState> pending_state_;
+
+ // If set, the WindowTree that state was created on has changed.
+ bool tree_changed_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(MusEmbeddedFrame);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_H_
diff --git a/chromium/content/renderer/mus/mus_embedded_frame_delegate.h b/chromium/content/renderer/mus/mus_embedded_frame_delegate.h
new file mode 100644
index 00000000000..4c6be417e88
--- /dev/null
+++ b/chromium/content/renderer/mus/mus_embedded_frame_delegate.h
@@ -0,0 +1,31 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_DELEGATE_H_
+#define CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_DELEGATE_H_
+
+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;
+
+ protected:
+ virtual ~MusEmbeddedFrameDelegate() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MUS_MUS_EMBEDDED_FRAME_DELEGATE_H_
diff --git a/chromium/content/renderer/mus/render_widget_window_tree_client_factory.cc b/chromium/content/renderer/mus/render_widget_window_tree_client_factory.cc
index 92c9d0d7542..d413d475479 100644
--- a/chromium/content/renderer/mus/render_widget_window_tree_client_factory.cc
+++ b/chromium/content/renderer/mus/render_widget_window_tree_client_factory.cc
@@ -86,7 +86,7 @@ class RenderWidgetWindowTreeClientFactoryImpl
void CreateRenderWidgetWindowTreeClientFactory(
ServiceManagerConnection* connection) {
connection->AddConnectionFilter(
- base::MakeUnique<RenderWidgetWindowTreeClientFactoryImpl>());
+ std::make_unique<RenderWidgetWindowTreeClientFactoryImpl>());
}
} // namespace content
diff --git a/chromium/content/renderer/mus/renderer_window_tree_client.cc b/chromium/content/renderer/mus/renderer_window_tree_client.cc
index f92334912af..596740f63a6 100644
--- a/chromium/content/renderer/mus/renderer_window_tree_client.cc
+++ b/chromium/content/renderer/mus/renderer_window_tree_client.cc
@@ -12,7 +12,10 @@
#include "components/viz/client/client_layer_tree_frame_sink.h"
#include "components/viz/client/hit_test_data_provider.h"
#include "components/viz/client/local_surface_id_provider.h"
+#include "components/viz/common/surfaces/surface_sequence.h"
#include "content/renderer/mash_util.h"
+#include "content/renderer/mus/mus_embedded_frame.h"
+#include "content/renderer/mus/mus_embedded_frame_delegate.h"
#include "content/renderer/render_frame_proxy.h"
namespace content {
@@ -23,16 +26,11 @@ using ConnectionMap = std::map<int, RendererWindowTreeClient*>;
base::LazyInstance<ConnectionMap>::Leaky g_connections =
LAZY_INSTANCE_INITIALIZER;
-// Callback from embedding a child frame.
-void OnEmbedAck(bool success) {
- DCHECK(success);
-}
-
} // namespace
// static
void RendererWindowTreeClient::CreateIfNecessary(int routing_id) {
- if (!IsRunningInMash() || Get(routing_id))
+ if (!IsRunningWithMus() || Get(routing_id))
return;
RendererWindowTreeClient* connection =
new RendererWindowTreeClient(routing_id);
@@ -56,6 +54,10 @@ void RendererWindowTreeClient::Bind(
ui::mojom::WindowTreeClientRequest request,
mojom::RenderWidgetWindowTreeClientRequest
render_widget_window_tree_client_request) {
+ // Bind() may be called multiple times.
+ binding_.Close();
+ render_widget_window_tree_client_binding_.Close();
+
binding_.Bind(std::move(request));
render_widget_window_tree_client_binding_.Bind(
std::move(render_widget_window_tree_client_request));
@@ -78,7 +80,10 @@ void RendererWindowTreeClient::SetVisible(bool visible) {
return;
visible_ = visible;
- // TODO(sky): determine when window should be updated.
+ if (tree_) {
+ tree_->SetWindowVisibility(GetAndAdvanceNextChangeId(), root_window_id_,
+ visible);
+ }
}
void RendererWindowTreeClient::RequestLayerTreeFrameSink(
@@ -97,6 +102,16 @@ void RendererWindowTreeClient::RequestLayerTreeFrameSink(
pending_layer_tree_frame_sink_callback_ = callback;
}
+std::unique_ptr<MusEmbeddedFrame>
+RendererWindowTreeClient::CreateMusEmbeddedFrame(
+ MusEmbeddedFrameDelegate* delegate,
+ const base::UnguessableToken& token) {
+ std::unique_ptr<MusEmbeddedFrame> frame = base::WrapUnique<MusEmbeddedFrame>(
+ new MusEmbeddedFrame(this, delegate, ++next_window_id_, token));
+ embedded_frames_.insert(frame.get());
+ return frame;
+}
+
RendererWindowTreeClient::RendererWindowTreeClient(int routing_id)
: routing_id_(routing_id),
binding_(this),
@@ -107,16 +122,6 @@ RendererWindowTreeClient::~RendererWindowTreeClient() {
DCHECK(embedded_frames_.empty());
}
-std::unique_ptr<MusEmbeddedFrame>
-RendererWindowTreeClient::CreateMusEmbeddedFrame(
- RenderFrameProxy* render_frame_proxy,
- const base::UnguessableToken& token) {
- std::unique_ptr<MusEmbeddedFrame> frame = base::WrapUnique<MusEmbeddedFrame>(
- new MusEmbeddedFrame(this, render_frame_proxy, ++next_window_id_, token));
- embedded_frames_.insert(frame.get());
- return frame;
-}
-
void RendererWindowTreeClient::RequestLayerTreeFrameSinkInternal(
scoped_refptr<viz::ContextProvider> context_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
@@ -132,9 +137,9 @@ void RendererWindowTreeClient::RequestLayerTreeFrameSinkInternal(
params.pipes.compositor_frame_sink_info = std::move(sink_info);
params.pipes.client_request = std::move(client_request);
params.local_surface_id_provider =
- base::MakeUnique<viz::DefaultLocalSurfaceIdProvider>();
+ std::make_unique<viz::DefaultLocalSurfaceIdProvider>();
params.enable_surface_synchronization = true;
- auto frame_sink = base::MakeUnique<viz::ClientLayerTreeFrameSink>(
+ auto frame_sink = std::make_unique<viz::ClientLayerTreeFrameSink>(
std::move(context_provider), nullptr /* worker_context_provider */,
&params);
tree_->AttachCompositorFrameSink(root_window_id_, std::move(sink_request),
@@ -170,11 +175,20 @@ void RendererWindowTreeClient::OnEmbed(
ui::Id focused_window_id,
bool drawn,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) {
+ const bool is_reembed = tree_.is_bound();
+ if (is_reembed) {
+ for (MusEmbeddedFrame* frame : embedded_frames_)
+ frame->OnTreeWillChange();
+ }
root_window_id_ = root->window_id;
+
tree_ = std::move(tree);
- // TODO(sky): determine when window should be updated.
- for (MusEmbeddedFrame* frame : embedded_frames_)
- frame->OnTreeAvailable();
+ tree_->SetWindowVisibility(GetAndAdvanceNextChangeId(), root_window_id_,
+ visible_);
+ if (!is_reembed) {
+ for (MusEmbeddedFrame* frame : embedded_frames_)
+ frame->OnTreeAvailable();
+ }
if (!pending_layer_tree_frame_sink_callback_.is_null()) {
RequestLayerTreeFrameSinkInternal(std::move(pending_context_provider_),
@@ -203,7 +217,7 @@ void RendererWindowTreeClient::OnFrameSinkIdAllocated(
const viz::FrameSinkId& frame_sink_id) {
for (MusEmbeddedFrame* embedded_frame : embedded_frames_) {
if (embedded_frame->window_id_ == window_id) {
- embedded_frame->render_frame_proxy_->OnMusFrameSinkIdAllocated(
+ embedded_frame->delegate_->OnMusEmbeddedFrameSinkIdAllocated(
frame_sink_id);
return;
}
@@ -298,7 +312,12 @@ void RendererWindowTreeClient::OnWindowCursorChanged(ui::Id window_id,
void RendererWindowTreeClient::OnWindowSurfaceChanged(
ui::Id window_id,
const viz::SurfaceInfo& surface_info) {
- NOTIMPLEMENTED();
+ for (MusEmbeddedFrame* embedded_frame : embedded_frames_) {
+ if (embedded_frame->window_id_ == window_id) {
+ embedded_frame->delegate_->OnMusEmbeddedFrameSurfaceChanged(surface_info);
+ return;
+ }
+ }
}
void RendererWindowTreeClient::OnDragDropStart(
@@ -336,7 +355,9 @@ void RendererWindowTreeClient::OnDragDropDone() {}
void RendererWindowTreeClient::OnChangeCompleted(uint32_t change_id,
bool success) {
// Don't DCHECK success, as it's possible we'll try to do some operations
- // after unembedded, which means all operations will fail.
+ // after unembedded, which means all operations will fail. Additionally
+ // setting the window visibility may fail for the root frame (the browser
+ // controls the visibility of the root frame).
}
void RendererWindowTreeClient::RequestClose(uint32_t window_id) {}
@@ -346,72 +367,4 @@ void RendererWindowTreeClient::GetWindowManager(
NOTREACHED();
}
-// MusEmbeddedFrame ------------------------------------------------------------
-
-MusEmbeddedFrame::~MusEmbeddedFrame() {
- renderer_window_tree_client_->OnEmbeddedFrameDestroyed(this);
- // If there is |pending_state_| it means we didn't actually create the window
- // yet and there is nothing to do.
- if (pending_state_)
- return;
-
- window_tree()->DeleteWindow(GetAndAdvanceNextChangeId(), window_id_);
-}
-
-void MusEmbeddedFrame::SetWindowBounds(
- const viz::LocalSurfaceId& local_surface_id,
- const gfx::Rect& bounds) {
- if (!window_tree()) {
- DCHECK(pending_state_);
- pending_state_->bounds = bounds;
- pending_state_->local_surface_id = local_surface_id;
- pending_state_->was_set_window_bounds_called = true;
- return;
- }
-
- window_tree()->SetWindowBounds(GetAndAdvanceNextChangeId(), window_id_,
- bounds, local_surface_id);
-}
-
-MusEmbeddedFrame::MusEmbeddedFrame(
- RendererWindowTreeClient* renderer_window_tree_client,
- RenderFrameProxy* proxy,
- ui::ClientSpecificId window_id,
- const base::UnguessableToken& token)
- : renderer_window_tree_client_(renderer_window_tree_client),
- render_frame_proxy_(proxy),
- window_id_(window_id) {
- if (!window_tree()) {
- pending_state_ = base::MakeUnique<PendingState>();
- pending_state_->token = token;
- return;
- }
- CreateChildWindowAndEmbed(token);
-}
-
-void MusEmbeddedFrame::CreateChildWindowAndEmbed(
- const base::UnguessableToken& token) {
- window_tree()->NewWindow(GetAndAdvanceNextChangeId(), window_id_,
- base::nullopt);
- window_tree()->AddWindow(GetAndAdvanceNextChangeId(),
- renderer_window_tree_client_->root_window_id_,
- window_id_);
- window_tree()->EmbedUsingToken(window_id_, token, 0, base::Bind(&OnEmbedAck));
-}
-
-void MusEmbeddedFrame::OnTreeAvailable() {
- std::unique_ptr<PendingState> pending_state = std::move(pending_state_);
- CreateChildWindowAndEmbed(pending_state->token);
- if (pending_state->was_set_window_bounds_called)
- SetWindowBounds(pending_state->local_surface_id, pending_state->bounds);
-}
-
-uint32_t MusEmbeddedFrame::GetAndAdvanceNextChangeId() {
- return renderer_window_tree_client_->GetAndAdvanceNextChangeId();
-}
-
-MusEmbeddedFrame::PendingState::PendingState() = default;
-
-MusEmbeddedFrame::PendingState::~PendingState() = default;
-
} // namespace content
diff --git a/chromium/content/renderer/mus/renderer_window_tree_client.h b/chromium/content/renderer/mus/renderer_window_tree_client.h
index 22fbde9b27b..1e0f08d33a3 100644
--- a/chromium/content/renderer/mus/renderer_window_tree_client.h
+++ b/chromium/content/renderer/mus/renderer_window_tree_client.h
@@ -37,6 +37,7 @@ class ContextProvider;
namespace content {
class MusEmbeddedFrame;
+class MusEmbeddedFrameDelegate;
class RenderFrameProxy;
// ui.mojom.WindowTreeClient implementation for RenderWidget. This lives and
@@ -77,16 +78,18 @@ class RendererWindowTreeClient : public ui::mojom::WindowTreeClient,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
const LayerTreeFrameSinkCallback& callback);
+ // Creates a new MusEmbeddedFrame. |token| is an UnguessableToken that was
+ // registered for an embedding with mus (specifically ui::mojom::WindowTree).
+ std::unique_ptr<MusEmbeddedFrame> CreateMusEmbeddedFrame(
+ MusEmbeddedFrameDelegate* mus_embedded_frame_delegate,
+ const base::UnguessableToken& token);
+
private:
friend class MusEmbeddedFrame;
explicit RendererWindowTreeClient(int routing_id);
~RendererWindowTreeClient() override;
- std::unique_ptr<MusEmbeddedFrame> CreateMusEmbeddedFrame(
- RenderFrameProxy* render_frame_proxy,
- const base::UnguessableToken& token);
-
void RequestLayerTreeFrameSinkInternal(
scoped_refptr<viz::ContextProvider> context_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
@@ -229,59 +232,6 @@ class RendererWindowTreeClient : public ui::mojom::WindowTreeClient,
DISALLOW_COPY_AND_ASSIGN(RendererWindowTreeClient);
};
-// MusEmbeddedFrame represents an embedding of an OOPIF frame. This is done
-// by creating a window and calling Embed().
-class MusEmbeddedFrame {
- public:
- ~MusEmbeddedFrame();
-
- // Sets the bounds of the embedded frame.
- void SetWindowBounds(const viz::LocalSurfaceId& local_surface_id,
- const gfx::Rect& bounds);
-
- private:
- friend class RendererWindowTreeClient;
-
- // Stores state that needs to pushed to the server once the connection has
- // been established (OnEmbed() is called).
- struct PendingState {
- PendingState();
- ~PendingState();
-
- base::UnguessableToken token;
- viz::LocalSurfaceId local_surface_id;
- gfx::Rect bounds;
- // True if SetWindowBounds() was called.
- bool was_set_window_bounds_called = false;
- };
-
- MusEmbeddedFrame(RendererWindowTreeClient* renderer_window_tree_client,
- RenderFrameProxy* proxy,
- ui::ClientSpecificId window_id,
- const base::UnguessableToken& token);
-
- // Called once the WindowTree has been obtained. This is only called if
- // the MusEmbeddedFrame is created before the WindowTree has been obtained.
- void OnTreeAvailable();
-
- // Does the actual embedding.
- void CreateChildWindowAndEmbed(const base::UnguessableToken& token);
-
- uint32_t GetAndAdvanceNextChangeId();
-
- ui::mojom::WindowTree* window_tree() {
- return renderer_window_tree_client_->tree_.get();
- }
-
- RendererWindowTreeClient* renderer_window_tree_client_;
- RenderFrameProxy* render_frame_proxy_;
- const ui::ClientSpecificId window_id_;
-
- std::unique_ptr<PendingState> pending_state_;
-
- DISALLOW_COPY_AND_ASSIGN(MusEmbeddedFrame);
-};
-
} // namespace content
#endif // CONTENT_RENDERER_MUS_RENDERER_WINDOW_TREE_CLIENT_H_
diff --git a/chromium/content/child/notifications/OWNERS b/chromium/content/renderer/notifications/OWNERS
index c7d29e3573d..c7d29e3573d 100644
--- a/chromium/content/child/notifications/OWNERS
+++ b/chromium/content/renderer/notifications/OWNERS
diff --git a/chromium/content/child/notifications/notification_data_conversions.cc b/chromium/content/renderer/notifications/notification_data_conversions.cc
index f54985d4f7d..6f611563fc3 100644
--- a/chromium/content/child/notifications/notification_data_conversions.cc
+++ b/chromium/content/renderer/notifications/notification_data_conversions.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/child/notifications/notification_data_conversions.h"
+#include "content/renderer/notifications/notification_data_conversions.h"
#include <stddef.h>
diff --git a/chromium/content/child/notifications/notification_data_conversions.h b/chromium/content/renderer/notifications/notification_data_conversions.h
index 445ff60316d..7adc1df192e 100644
--- a/chromium/content/child/notifications/notification_data_conversions.h
+++ b/chromium/content/renderer/notifications/notification_data_conversions.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_CHILD_NOTIFICATIONS_NOTIFICATION_DATA_CONVERSIONS_H_
-#define CONTENT_CHILD_NOTIFICATIONS_NOTIFICATION_DATA_CONVERSIONS_H_
+#ifndef CONTENT_RENDERER_NOTIFICATIONS_NOTIFICATION_DATA_CONVERSIONS_H_
+#define CONTENT_RENDERER_NOTIFICATIONS_NOTIFICATION_DATA_CONVERSIONS_H_
#include "content/common/content_export.h"
#include "content/public/common/platform_notification_data.h"
@@ -21,4 +21,4 @@ CONTENT_EXPORT blink::WebNotificationData ToWebNotificationData(
} // namespace content
-#endif // CONTENT_CHILD_NOTIFICATIONS_NOTIFICATION_DATA_CONVERSIONS_H_
+#endif // CONTENT_RENDERER_NOTIFICATIONS_NOTIFICATION_DATA_CONVERSIONS_H_
diff --git a/chromium/content/child/notifications/notification_data_conversions_unittest.cc b/chromium/content/renderer/notifications/notification_data_conversions_unittest.cc
index c5955ac0472..2edc32e5204 100644
--- a/chromium/content/child/notifications/notification_data_conversions_unittest.cc
+++ b/chromium/content/renderer/notifications/notification_data_conversions_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 "content/child/notifications/notification_data_conversions.h"
+#include "content/renderer/notifications/notification_data_conversions.h"
#include <stddef.h>
#include <stdint.h>
diff --git a/chromium/content/child/notifications/notification_dispatcher.cc b/chromium/content/renderer/notifications/notification_dispatcher.cc
index f840b40e376..3bad7ebff2a 100644
--- a/chromium/content/child/notifications/notification_dispatcher.cc
+++ b/chromium/content/renderer/notifications/notification_dispatcher.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/notifications/notification_dispatcher.h"
+#include "content/renderer/notifications/notification_dispatcher.h"
#include <limits>
-#include "content/child/notifications/notification_manager.h"
+#include "content/renderer/notifications/notification_manager.h"
namespace content {
diff --git a/chromium/content/child/notifications/notification_dispatcher.h b/chromium/content/renderer/notifications/notification_dispatcher.h
index 2df766126e7..a4f66d67724 100644
--- a/chromium/content/child/notifications/notification_dispatcher.h
+++ b/chromium/content/renderer/notifications/notification_dispatcher.h
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_NOTIFICATIONS_NOTIFICATION_DISPATCHER_H_
-#define CONTENT_CHILD_NOTIFICATIONS_NOTIFICATION_DISPATCHER_H_
+#ifndef CONTENT_RENDERER_NOTIFICATIONS_NOTIFICATION_DISPATCHER_H_
+#define CONTENT_RENDERER_NOTIFICATIONS_NOTIFICATION_DISPATCHER_H_
#include <map>
#include "base/macros.h"
#include "base/synchronization/lock.h"
-#include "content/child/worker_thread_message_filter.h"
+#include "content/renderer/worker_thread_message_filter.h"
namespace content {
@@ -42,4 +42,4 @@ class NotificationDispatcher : public WorkerThreadMessageFilter {
} // namespace content
-#endif // CONTENT_CHILD_NOTIFICATIONS_NOTIFICATION_DISPATCHER_H_
+#endif // CONTENT_RENDERER_NOTIFICATIONS_NOTIFICATION_DISPATCHER_H_
diff --git a/chromium/content/child/notifications/notification_manager.cc b/chromium/content/renderer/notifications/notification_manager.cc
index e92f560bb66..72ae8ac5c6d 100644
--- a/chromium/content/child/notifications/notification_manager.cc
+++ b/chromium/content/renderer/notifications/notification_manager.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/notifications/notification_manager.h"
+#include "content/renderer/notifications/notification_manager.h"
#include <utility>
@@ -10,12 +10,12 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_local.h"
-#include "content/child/notifications/notification_data_conversions.h"
-#include "content/child/notifications/notification_dispatcher.h"
-#include "content/child/service_worker/web_service_worker_registration_impl.h"
#include "content/child/thread_safe_sender.h"
#include "content/public/common/notification_resources.h"
#include "content/public/common/platform_notification_data.h"
+#include "content/renderer/notifications/notification_data_conversions.h"
+#include "content/renderer/notifications/notification_dispatcher.h"
+#include "content/renderer/service_worker/web_service_worker_registration_impl.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationDelegate.h"
diff --git a/chromium/content/child/notifications/notification_manager.h b/chromium/content/renderer/notifications/notification_manager.h
index 964c59894e6..12af7d90b94 100644
--- a/chromium/content/child/notifications/notification_manager.h
+++ b/chromium/content/renderer/notifications/notification_manager.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_NOTIFICATIONS_NOTIFICATION_MANAGER_H_
-#define CONTENT_CHILD_NOTIFICATIONS_NOTIFICATION_MANAGER_H_
+#ifndef CONTENT_RENDERER_NOTIFICATIONS_NOTIFICATION_MANAGER_H_
+#define CONTENT_RENDERER_NOTIFICATIONS_NOTIFICATION_MANAGER_H_
#include <stddef.h>
#include <stdint.h>
@@ -16,9 +16,9 @@
#include "base/containers/id_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "content/child/notifications/notification_dispatcher.h"
#include "content/common/platform_notification_messages.h"
-#include "content/public/child/worker_thread.h"
+#include "content/public/renderer/worker_thread.h"
+#include "content/renderer/notifications/notification_dispatcher.h"
#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationManager.h"
#include "url/gurl.h"
@@ -110,4 +110,4 @@ class NotificationManager : public blink::WebNotificationManager,
} // namespace content
-#endif // CONTENT_CHILD_NOTIFICATIONS_NOTIFICATION_MANAGER_H_
+#endif // CONTENT_RENDERER_NOTIFICATIONS_NOTIFICATION_MANAGER_H_
diff --git a/chromium/content/renderer/p2p/filtering_network_manager_unittest.cc b/chromium/content/renderer/p2p/filtering_network_manager_unittest.cc
index b52506bb2dc..bb0e994ff32 100644
--- a/chromium/content/renderer/p2p/filtering_network_manager_unittest.cc
+++ b/chromium/content/renderer/p2p/filtering_network_manager_unittest.cc
@@ -100,6 +100,8 @@ class MockMediaPermission : public media::MediaPermission {
}
}
+ bool IsEncryptedMediaEnabled() override { return true; }
+
void SetMicPermission(bool granted) {
if (mic_callback_.is_null())
return;
diff --git a/chromium/content/renderer/p2p/ipc_socket_factory.cc b/chromium/content/renderer/p2p/ipc_socket_factory.cc
index 4ab9bd3ce7e..186ae4201d7 100644
--- a/chromium/content/renderer/p2p/ipc_socket_factory.cc
+++ b/chromium/content/renderer/p2p/ipc_socket_factory.cc
@@ -768,7 +768,7 @@ rtc::AsyncPacketSocket* IpcPacketSocketFactory::CreateServerTcpSocket(
int opts) {
// TODO(sergeyu): Implement SSL support.
if (opts & rtc::PacketSocketFactory::OPT_SSLTCP)
- return NULL;
+ return nullptr;
P2PSocketType type = (opts & rtc::PacketSocketFactory::OPT_STUN) ?
P2P_SOCKET_STUN_TCP_SERVER : P2P_SOCKET_TCP_SERVER;
@@ -777,7 +777,7 @@ rtc::AsyncPacketSocket* IpcPacketSocketFactory::CreateServerTcpSocket(
std::unique_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
if (!socket->Init(type, socket_client, local_address, min_port, max_port,
rtc::SocketAddress())) {
- return NULL;
+ return nullptr;
}
return socket.release();
}
@@ -802,7 +802,7 @@ rtc::AsyncPacketSocket* IpcPacketSocketFactory::CreateClientTcpSocket(
new P2PSocketClientImpl(socket_dispatcher_);
std::unique_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
if (!socket->Init(type, socket_client, local_address, 0, 0, remote_address))
- return NULL;
+ return nullptr;
return socket.release();
}
diff --git a/chromium/content/renderer/p2p/socket_client_impl.cc b/chromium/content/renderer/p2p/socket_client_impl.cc
index 6aeeac249f2..8ad4afe03d0 100644
--- a/chromium/content/renderer/p2p/socket_client_impl.cc
+++ b/chromium/content/renderer/p2p/socket_client_impl.cc
@@ -33,7 +33,7 @@ P2PSocketClientImpl::P2PSocketClientImpl(P2PSocketDispatcher* dispatcher)
ipc_task_runner_(dispatcher->task_runner()),
delegate_task_runner_(base::ThreadTaskRunnerHandle::Get()),
socket_id_(0),
- delegate_(NULL),
+ delegate_(nullptr),
state_(STATE_UNINITIALIZED),
random_socket_id_(0),
next_packet_id_(0) {
@@ -122,7 +122,7 @@ void P2PSocketClientImpl::SetOption(P2PSocketOption option,
void P2PSocketClientImpl::Close() {
DCHECK(delegate_task_runner_->BelongsToCurrentThread());
- delegate_ = NULL;
+ delegate_ = nullptr;
ipc_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&P2PSocketClientImpl::DoClose, this));
@@ -252,7 +252,7 @@ void P2PSocketClientImpl::DeliverOnDataReceived(
void P2PSocketClientImpl::Detach() {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
- dispatcher_ = NULL;
+ dispatcher_ = nullptr;
OnError();
}
diff --git a/chromium/content/renderer/p2p/socket_dispatcher.cc b/chromium/content/renderer/p2p/socket_dispatcher.cc
index 27079acec92..7459bef41d9 100644
--- a/chromium/content/renderer/p2p/socket_dispatcher.cc
+++ b/chromium/content/renderer/p2p/socket_dispatcher.cc
@@ -22,8 +22,7 @@ P2PSocketDispatcher::P2PSocketDispatcher(
network_notifications_started_(false),
network_list_observers_(
new base::ObserverListThreadSafe<NetworkListObserver>()),
- sender_(NULL) {
-}
+ sender_(nullptr) {}
P2PSocketDispatcher::~P2PSocketDispatcher() {
network_list_observers_->AssertEmpty();
@@ -77,7 +76,7 @@ void P2PSocketDispatcher::OnFilterAdded(IPC::Channel* channel) {
}
void P2PSocketDispatcher::OnFilterRemoved() {
- sender_ = NULL;
+ sender_ = nullptr;
}
void P2PSocketDispatcher::OnChannelConnected(int32_t peer_id) {
@@ -85,7 +84,7 @@ void P2PSocketDispatcher::OnChannelConnected(int32_t peer_id) {
}
void P2PSocketDispatcher::OnChannelClosing() {
- sender_ = NULL;
+ sender_ = nullptr;
connected_ = false;
}
@@ -190,12 +189,12 @@ void P2PSocketDispatcher::OnDataReceived(
P2PSocketClientImpl* P2PSocketDispatcher::GetClient(int socket_id) {
P2PSocketClientImpl* client = clients_.Lookup(socket_id);
- if (client == NULL) {
+ if (client == nullptr) {
// This may happen if the socket was closed, but the browser side
// hasn't processed the close message by the time it sends the
// message to the renderer.
DVLOG(1) << "Received P2P message for socket that doesn't exist.";
- return NULL;
+ return nullptr;
}
return client;
diff --git a/chromium/content/renderer/pepper/content_decryptor_delegate.cc b/chromium/content/renderer/pepper/content_decryptor_delegate.cc
index d03c5d30552..c2bb46b2a6d 100644
--- a/chromium/content/renderer/pepper/content_decryptor_delegate.cc
+++ b/chromium/content/renderer/pepper/content_decryptor_delegate.cc
@@ -66,7 +66,7 @@ bool MakeBufferResource(PP_Instance instance,
DCHECK(resource);
if (data.empty()) {
- resource = NULL;
+ resource = nullptr;
return true;
}
@@ -385,8 +385,6 @@ CdmMessageType PpCdmMessageTypeToMediaMessageType(
}
}
-// TODO(xhwang): Unify EME UMA reporting code when prefixed EME is deprecated.
-// See http://crbug.com/412987 for details.
void ReportSystemCodeUMA(const std::string& key_system, uint32_t system_code) {
// Sparse histogram macro does not cache the histogram, so it's safe to use
// macro with non-static histogram name here.
@@ -594,14 +592,14 @@ bool ContentDecryptorDelegate::CancelDecrypt(
// Release the shared memory as it can still be in use by the plugin.
// The next Decrypt() call will need to allocate a new shared memory
// buffer.
- audio_input_resource_ = NULL;
+ audio_input_resource_ = nullptr;
decrypt_cb = audio_decrypt_cb_.ResetAndReturn();
break;
case Decryptor::kVideo:
// Release the shared memory as it can still be in use by the plugin.
// The next Decrypt() call will need to allocate a new shared memory
// buffer.
- video_input_resource_ = NULL;
+ video_input_resource_ = nullptr;
decrypt_cb = video_decrypt_cb_.ResetAndReturn();
break;
default:
@@ -610,7 +608,7 @@ bool ContentDecryptorDelegate::CancelDecrypt(
}
if (!decrypt_cb.is_null())
- decrypt_cb.Run(Decryptor::kSuccess, NULL);
+ decrypt_cb.Run(Decryptor::kSuccess, nullptr);
return true;
}
@@ -847,7 +845,7 @@ void ContentDecryptorDelegate::OnSessionKeysChange(
keys_info.reserve(key_count);
for (uint32_t i = 0; i < key_count; ++i) {
const auto& info = key_information[i];
- keys_info.push_back(base::MakeUnique<media::CdmKeyInformation>(
+ keys_info.push_back(std::make_unique<media::CdmKeyInformation>(
info.key_id, info.key_id_size,
PpCdmKeyStatusToCdmKeyInformationKeyStatus(info.key_status),
info.system_code));
@@ -948,19 +946,19 @@ void ContentDecryptorDelegate::DeliverBlock(
Decryptor::Status status =
PpDecryptResultToMediaDecryptorStatus(block_info->result);
if (status != Decryptor::kSuccess) {
- decrypt_cb.Run(status, NULL);
+ decrypt_cb.Run(status, nullptr);
return;
}
EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true);
if (!enter.succeeded()) {
- decrypt_cb.Run(Decryptor::kError, NULL);
+ decrypt_cb.Run(Decryptor::kError, nullptr);
return;
}
BufferAutoMapper mapper(enter.object());
if (!mapper.data() || !mapper.size() ||
mapper.size() < block_info->data_size) {
- decrypt_cb.Run(Decryptor::kError, NULL);
+ decrypt_cb.Run(Decryptor::kError, nullptr);
return;
}
@@ -990,16 +988,16 @@ static uint8_t* GetMappedBuffer(PP_Resource resource,
scoped_refptr<PPB_Buffer_Impl>* ppb_buffer) {
EnterResourceNoLock<PPB_Buffer_API> enter(resource, true);
if (!enter.succeeded())
- return NULL;
+ return nullptr;
uint8_t* mapped_data = static_cast<uint8_t*>(enter.object()->Map());
if (!enter.object()->IsMapped() || !mapped_data)
- return NULL;
+ return nullptr;
uint32_t mapped_size = 0;
if (!enter.object()->Describe(&mapped_size) || !mapped_size) {
enter.object()->Unmap();
- return NULL;
+ return nullptr;
}
*ppb_buffer = static_cast<PPB_Buffer_Impl*>(enter.object());
@@ -1031,7 +1029,7 @@ void ContentDecryptorDelegate::DeliverFrame(
PpDecryptResultToMediaDecryptorStatus(frame_info->result);
if (status != Decryptor::kSuccess) {
DCHECK(!frame_info->tracking_info.buffer_id);
- video_decode_cb.Run(status, NULL);
+ video_decode_cb.Run(status, nullptr);
return;
}
@@ -1039,7 +1037,7 @@ void ContentDecryptorDelegate::DeliverFrame(
uint8_t* frame_data = GetMappedBuffer(decrypted_frame, &ppb_buffer);
if (!frame_data) {
FreeBuffer(frame_info->tracking_info.buffer_id);
- video_decode_cb.Run(Decryptor::kError, NULL);
+ video_decode_cb.Run(Decryptor::kError, nullptr);
return;
}
@@ -1049,7 +1047,7 @@ void ContentDecryptorDelegate::DeliverFrame(
PpDecryptedFrameFormatToMediaVideoFormat(frame_info->format);
if (video_pixel_format == media::PIXEL_FORMAT_UNKNOWN) {
FreeBuffer(frame_info->tracking_info.buffer_id);
- video_decode_cb.Run(Decryptor::kError, NULL);
+ video_decode_cb.Run(Decryptor::kError, nullptr);
return;
}
@@ -1066,7 +1064,7 @@ void ContentDecryptorDelegate::DeliverFrame(
frame_info->tracking_info.timestamp));
if (!decoded_frame) {
FreeBuffer(frame_info->tracking_info.buffer_id);
- video_decode_cb.Run(Decryptor::kError, NULL);
+ video_decode_cb.Run(Decryptor::kError, nullptr);
return;
}
decoded_frame->AddDestructionObserver(
@@ -1130,7 +1128,7 @@ void ContentDecryptorDelegate::CancelDecode(Decryptor::StreamType stream_type) {
// Release the shared memory as it can still be in use by the plugin.
// The next DecryptAndDecode() call will need to allocate a new shared
// memory buffer.
- audio_input_resource_ = NULL;
+ audio_input_resource_ = nullptr;
if (!audio_decode_cb_.is_null())
audio_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess,
Decryptor::AudioFrames());
@@ -1139,9 +1137,9 @@ void ContentDecryptorDelegate::CancelDecode(Decryptor::StreamType stream_type) {
// Release the shared memory as it can still be in use by the plugin.
// The next DecryptAndDecode() call will need to allocate a new shared
// memory buffer.
- video_input_resource_ = NULL;
+ video_input_resource_ = nullptr;
if (!video_decode_cb_.is_null())
- video_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess, NULL);
+ video_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess, nullptr);
break;
default:
NOTREACHED();
@@ -1156,7 +1154,7 @@ bool ContentDecryptorDelegate::MakeMediaBufferResource(
// End of stream buffers are represented as null resources.
if (buffer->end_of_stream()) {
- *resource = NULL;
+ *resource = nullptr;
return true;
}
@@ -1193,7 +1191,7 @@ bool ContentDecryptorDelegate::MakeMediaBufferResource(
BufferAutoMapper mapper(media_resource.get());
if (!mapper.data() || mapper.size() < data_size) {
- media_resource = NULL;
+ media_resource = nullptr;
return false;
}
memcpy(mapper.data(), buffer->data(), data_size);
@@ -1296,14 +1294,14 @@ void ContentDecryptorDelegate::SatisfyAllPendingCallbacksOnError() {
if (!video_decoder_init_cb_.is_null())
video_decoder_init_cb_.ResetAndReturn().Run(false);
- audio_input_resource_ = NULL;
- video_input_resource_ = NULL;
+ audio_input_resource_ = nullptr;
+ video_input_resource_ = nullptr;
if (!audio_decrypt_cb_.is_null())
- audio_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL);
+ audio_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, nullptr);
if (!video_decrypt_cb_.is_null())
- video_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL);
+ video_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, nullptr);
if (!audio_decode_cb_.is_null()) {
const media::Decryptor::AudioFrames empty_frames;
@@ -1312,7 +1310,7 @@ void ContentDecryptorDelegate::SatisfyAllPendingCallbacksOnError() {
}
if (!video_decode_cb_.is_null())
- video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL);
+ video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, nullptr);
cdm_promise_adapter_.Clear();
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 d7580440951..d859446b521 100644
--- a/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc
+++ b/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc
@@ -39,6 +39,7 @@
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/serialized_structs.h"
#include "ppapi/shared_impl/ppb_image_data_shared.h"
+#include "services/service_manager/sandbox/switches.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebPluginContainer.h"
@@ -125,7 +126,7 @@ ContentRendererPepperHostFactory::CreateResourceHost(
case PpapiHostMsg_Compositor_Create::ID: {
if (!CanUseCompositorAPI(host_, instance))
return nullptr;
- return base::MakeUnique<PepperCompositorHost>(host_, instance, resource);
+ return std::make_unique<PepperCompositorHost>(host_, instance, resource);
}
case PpapiHostMsg_FileRef_CreateForFileAPI::ID: {
PP_Resource file_system;
@@ -135,7 +136,7 @@ ContentRendererPepperHostFactory::CreateResourceHost(
NOTREACHED();
return nullptr;
}
- return base::MakeUnique<PepperFileRefRendererHost>(
+ return std::make_unique<PepperFileRefRendererHost>(
host_, instance, resource, file_system, internal_path);
}
case PpapiHostMsg_FileSystem_Create::ID: {
@@ -145,7 +146,7 @@ ContentRendererPepperHostFactory::CreateResourceHost(
NOTREACHED();
return nullptr;
}
- return base::MakeUnique<PepperFileSystemHost>(host_, instance, resource,
+ return std::make_unique<PepperFileSystemHost>(host_, instance, resource,
file_system_type);
}
case PpapiHostMsg_Graphics2D_Create::ID: {
@@ -166,7 +167,7 @@ ContentRendererPepperHostFactory::CreateResourceHost(
// TODO(ananta)
// Look into whether this causes a loss of functionality. From cursory
// testing things seem to work well.
- if (IsWin32kLockdownEnabled())
+ if (service_manager::IsWin32kLockdownEnabled())
image_type = ppapi::PPB_ImageData_Shared::SIMPLE;
#endif
scoped_refptr<PPB_ImageData_Impl> image_data(new PPB_ImageData_Impl(
@@ -175,30 +176,30 @@ ContentRendererPepperHostFactory::CreateResourceHost(
host_, instance, resource, size, is_always_opaque, image_data));
}
case PpapiHostMsg_URLLoader_Create::ID:
- return base::MakeUnique<PepperURLLoaderHost>(host_, false, instance,
+ return std::make_unique<PepperURLLoaderHost>(host_, false, instance,
resource);
case PpapiHostMsg_VideoDecoder_Create::ID:
- return base::MakeUnique<PepperVideoDecoderHost>(host_, instance,
+ return std::make_unique<PepperVideoDecoderHost>(host_, instance,
resource);
case PpapiHostMsg_VideoEncoder_Create::ID:
- return base::MakeUnique<PepperVideoEncoderHost>(host_, instance,
+ return std::make_unique<PepperVideoEncoderHost>(host_, instance,
resource);
case PpapiHostMsg_WebSocket_Create::ID:
- return base::MakeUnique<PepperWebSocketHost>(host_, instance, resource);
+ return std::make_unique<PepperWebSocketHost>(host_, instance, resource);
#if BUILDFLAG(ENABLE_WEBRTC)
case PpapiHostMsg_MediaStreamVideoTrack_Create::ID:
- return base::MakeUnique<PepperMediaStreamVideoTrackHost>(host_, instance,
+ 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 base::MakeUnique<PepperVideoDestinationHost>(host_, instance,
+ return std::make_unique<PepperVideoDestinationHost>(host_, instance,
resource);
case PpapiHostMsg_VideoSource_Create::ID:
if (CanUseMediaStreamAPI(host_, instance))
- return base::MakeUnique<PepperVideoSourceHost>(host_, instance,
+ return std::make_unique<PepperVideoSourceHost>(host_, instance,
resource);
#endif // BUILDFLAG(ENABLE_WEBRTC)
}
@@ -207,16 +208,16 @@ ContentRendererPepperHostFactory::CreateResourceHost(
if (GetPermissions().HasPermission(ppapi::PERMISSION_DEV)) {
switch (message.type()) {
case PpapiHostMsg_AudioEncoder_Create::ID:
- return base::MakeUnique<PepperAudioEncoderHost>(host_, instance,
+ return std::make_unique<PepperAudioEncoderHost>(host_, instance,
resource);
case PpapiHostMsg_AudioInput_Create::ID:
- return base::MakeUnique<PepperAudioInputHost>(host_, instance,
+ return std::make_unique<PepperAudioInputHost>(host_, instance,
resource);
case PpapiHostMsg_AudioOutput_Create::ID:
- return base::MakeUnique<PepperAudioOutputHost>(host_, instance,
+ return std::make_unique<PepperAudioOutputHost>(host_, instance,
resource);
case PpapiHostMsg_FileChooser_Create::ID:
- return base::MakeUnique<PepperFileChooserHost>(host_, instance,
+ return std::make_unique<PepperFileChooserHost>(host_, instance,
resource);
case PpapiHostMsg_VideoCapture_Create::ID: {
std::unique_ptr<PepperVideoCaptureHost> host(
diff --git a/chromium/content/renderer/pepper/event_conversion.cc b/chromium/content/renderer/pepper/event_conversion.cc
index a666241ea0a..0bb01694174 100644
--- a/chromium/content/renderer/pepper/event_conversion.cc
+++ b/chromium/content/renderer/pepper/event_conversion.cc
@@ -612,7 +612,7 @@ WebInputEvent* CreateWebInputEvent(const InputEventData& event) {
std::unique_ptr<WebInputEvent> web_input_event;
switch (event.event_type) {
case PP_INPUTEVENT_TYPE_UNDEFINED:
- return NULL;
+ return nullptr;
case PP_INPUTEVENT_TYPE_MOUSEDOWN:
case PP_INPUTEVENT_TYPE_MOUSEUP:
case PP_INPUTEVENT_TYPE_MOUSEMOVE:
diff --git a/chromium/content/renderer/pepper/host_array_buffer_var.cc b/chromium/content/renderer/pepper/host_array_buffer_var.cc
index e1ac407c306..84cb02ae4aa 100644
--- a/chromium/content/renderer/pepper/host_array_buffer_var.cc
+++ b/chromium/content/renderer/pepper/host_array_buffer_var.cc
@@ -46,7 +46,7 @@ HostArrayBufferVar::~HostArrayBufferVar() {}
void* HostArrayBufferVar::Map() {
if (!valid_)
- return NULL;
+ return nullptr;
return buffer_.Data();
}
diff --git a/chromium/content/renderer/pepper/host_globals.cc b/chromium/content/renderer/pepper/host_globals.cc
index 4dd5b743c4a..057ef4fd444 100644
--- a/chromium/content/renderer/pepper/host_globals.cc
+++ b/chromium/content/renderer/pepper/host_globals.cc
@@ -81,7 +81,7 @@ WebConsoleMessage MakeLogMessage(PP_LogLevel level,
} // namespace
-HostGlobals* HostGlobals::host_globals_ = NULL;
+HostGlobals* HostGlobals::host_globals_ = nullptr;
HostGlobals::HostGlobals()
: ppapi::PpapiGlobals(),
@@ -95,7 +95,7 @@ HostGlobals::HostGlobals()
HostGlobals::~HostGlobals() {
DCHECK(host_globals_ == this || !host_globals_);
- host_globals_ = NULL;
+ host_globals_ = nullptr;
}
ppapi::ResourceTracker* HostGlobals::GetResourceTracker() {
@@ -108,7 +108,7 @@ ppapi::CallbackTracker* HostGlobals::GetCallbackTrackerForInstance(
PP_Instance instance) {
InstanceMap::iterator found = instance_map_.find(instance);
if (found == instance_map_.end())
- return NULL;
+ return nullptr;
return found->second->module()->GetCallbackTracker().get();
}
@@ -122,7 +122,7 @@ ppapi::thunk::ResourceCreationAPI* HostGlobals::GetResourceCreationAPI(
PP_Instance pp_instance) {
PepperPluginInstanceImpl* instance = GetInstance(pp_instance);
if (!instance)
- return NULL;
+ return nullptr;
return &instance->resource_creation();
}
@@ -193,7 +193,9 @@ base::TaskRunner* HostGlobals::GetFileTaskRunner() {
return RenderThreadImpl::current()->GetFileThreadTaskRunner().get();
}
-ppapi::MessageLoopShared* HostGlobals::GetCurrentMessageLoop() { return NULL; }
+ppapi::MessageLoopShared* HostGlobals::GetCurrentMessageLoop() {
+ return nullptr;
+}
PP_Module HostGlobals::AddModule(PluginModule* module) {
#ifndef NDEBUG
@@ -230,7 +232,7 @@ PluginModule* HostGlobals::GetModule(PP_Module module) {
<< module << " is not a PP_Module.";
ModuleMap::iterator found = module_map_.find(module);
if (found == module_map_.end())
- return NULL;
+ return nullptr;
return found->second;
}
@@ -271,7 +273,7 @@ PepperPluginInstanceImpl* HostGlobals::GetInstance(PP_Instance instance) {
<< instance << " is not a PP_Instance.";
InstanceMap::iterator found = instance_map_.find(instance);
if (found == instance_map_.end())
- return NULL;
+ return nullptr;
return found->second;
}
diff --git a/chromium/content/renderer/pepper/host_var_tracker_unittest.cc b/chromium/content/renderer/pepper/host_var_tracker_unittest.cc
index 75d0f262f30..2c282161d7f 100644
--- a/chromium/content/renderer/pepper/host_var_tracker_unittest.cc
+++ b/chromium/content/renderer/pepper/host_var_tracker_unittest.cc
@@ -86,7 +86,7 @@ TEST_F(HostVarTrackerTest, DeleteObjectVarWithInstance) {
// Make a second instance (the test harness already creates & manages one).
scoped_refptr<PepperPluginInstanceImpl> instance2(
- PepperPluginInstanceImpl::Create(NULL, module(), NULL, GURL()));
+ PepperPluginInstanceImpl::Create(nullptr, module(), nullptr, GURL()));
PP_Instance pp_instance2 = instance2->pp_instance();
{
@@ -102,7 +102,7 @@ TEST_F(HostVarTrackerTest, DeleteObjectVarWithInstance) {
}
// Free the instance, this should release the ObjectVar.
- instance2 = NULL;
+ instance2 = nullptr;
EXPECT_EQ(0, tracker().GetLiveV8ObjectVarsForTest(pp_instance2));
}
diff --git a/chromium/content/renderer/pepper/message_channel.cc b/chromium/content/renderer/pepper/message_channel.cc
index c109a31140d..4a9f3a03b26 100644
--- a/chromium/content/renderer/pepper/message_channel.cc
+++ b/chromium/content/renderer/pepper/message_channel.cc
@@ -98,7 +98,7 @@ MessageChannel::~MessageChannel() {
void MessageChannel::InstanceDeleted() {
UnregisterSyncMessageStatusObserver();
- instance_ = NULL;
+ instance_ = nullptr;
}
void MessageChannel::PostMessageToJavaScript(PP_Var message_data) {
diff --git a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc
index c5cebdac9da..ad9a0df001e 100644
--- a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc
+++ b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc
@@ -41,25 +41,20 @@ RenderFrame* MockRendererPpapiHost::GetRenderFrameForInstance(
PP_Instance instance) const {
if (instance == pp_instance_)
return render_frame_;
- return NULL;
+ return nullptr;
}
RenderView* MockRendererPpapiHost::GetRenderViewForInstance(
PP_Instance instance) const {
if (instance == pp_instance_)
return render_view_;
- return NULL;
+ return nullptr;
}
blink::WebPluginContainer* MockRendererPpapiHost::GetContainerForInstance(
PP_Instance instance) const {
NOTIMPLEMENTED();
- return NULL;
-}
-
-base::ProcessId MockRendererPpapiHost::GetPluginPID() const {
- NOTIMPLEMENTED();
- return base::kNullProcessId;
+ return nullptr;
}
bool MockRendererPpapiHost::HasUserGesture(PP_Instance instance) const {
diff --git a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h
index 503a2252db2..375c2127a3f 100644
--- a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h
+++ b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h
@@ -39,7 +39,6 @@ class MockRendererPpapiHost : public RendererPpapiHost {
RenderView* GetRenderViewForInstance(PP_Instance instance) const override;
blink::WebPluginContainer* GetContainerForInstance(
PP_Instance instance) const override;
- base::ProcessId GetPluginPID() const override;
bool HasUserGesture(PP_Instance instance) const override;
int GetRoutingIDForWidget(PP_Instance instance) const override;
gfx::Point PluginPointToRenderFrame(PP_Instance instance,
diff --git a/chromium/content/renderer/pepper/pepper_audio_input_host.cc b/chromium/content/renderer/pepper/pepper_audio_input_host.cc
index 579de1615e9..f25c532d0ac 100644
--- a/chromium/content/renderer/pepper/pepper_audio_input_host.cc
+++ b/chromium/content/renderer/pepper/pepper_audio_input_host.cc
@@ -34,7 +34,7 @@ PepperAudioInputHost::PepperAudioInputHost(RendererPpapiHostImpl* host,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
renderer_ppapi_host_(host),
- audio_input_(NULL),
+ audio_input_(nullptr),
enumeration_helper_(this,
PepperMediaDeviceManager::GetForRenderFrame(
host->GetRenderFrameForInstance(pp_instance())),
@@ -183,7 +183,7 @@ void PepperAudioInputHost::Close() {
return;
audio_input_->ShutDown();
- audio_input_ = NULL;
+ audio_input_ = nullptr;
if (open_context_.is_valid())
SendOpenReply(PP_ERROR_ABORTED);
diff --git a/chromium/content/renderer/pepper/pepper_audio_output_host.cc b/chromium/content/renderer/pepper/pepper_audio_output_host.cc
index 59674b7367b..fdde5d03e27 100644
--- a/chromium/content/renderer/pepper/pepper_audio_output_host.cc
+++ b/chromium/content/renderer/pepper/pepper_audio_output_host.cc
@@ -36,7 +36,7 @@ PepperAudioOutputHost::PepperAudioOutputHost(RendererPpapiHostImpl* host,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
renderer_ppapi_host_(host),
- audio_output_(NULL),
+ audio_output_(nullptr),
playback_throttled_(false),
enumeration_helper_(this,
PepperMediaDeviceManager::GetForRenderFrame(
@@ -224,7 +224,7 @@ void PepperAudioOutputHost::Close() {
return;
audio_output_->ShutDown();
- audio_output_ = NULL;
+ audio_output_ = nullptr;
if (open_context_.is_valid())
SendOpenReply(PP_ERROR_ABORTED);
diff --git a/chromium/content/renderer/pepper/pepper_broker.cc b/chromium/content/renderer/pepper/pepper_broker.cc
index e201224a8f8..1f5cd9fd35a 100644
--- a/chromium/content/renderer/pepper/pepper_broker.cc
+++ b/chromium/content/renderer/pepper/pepper_broker.cc
@@ -110,8 +110,8 @@ PepperBroker::PepperBroker(PluginModule* plugin_module)
PepperBroker::~PepperBroker() {
ReportFailureToClients(PP_ERROR_ABORTED);
- plugin_module_->SetBroker(NULL);
- plugin_module_ = NULL;
+ plugin_module_->SetBroker(nullptr);
+ plugin_module_ = nullptr;
}
// If the channel is not ready, queue the connection.
diff --git a/chromium/content/renderer/pepper/pepper_compositor_host.cc b/chromium/content/renderer/pepper/pepper_compositor_host.cc
index 79098c156dc..e6e3168abe9 100644
--- a/chromium/content/renderer/pepper/pepper_compositor_host.cc
+++ b/chromium/content/renderer/pepper/pepper_compositor_host.cc
@@ -16,13 +16,14 @@
#include "cc/layers/texture_layer.h"
#include "cc/trees/layer_tree_host.h"
#include "components/viz/client/client_shared_bitmap_manager.h"
-#include "components/viz/common/quads/texture_mailbox.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/pepper/gfx_conversion.h"
#include "content/renderer/pepper/host_globals.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
#include "content/renderer/render_thread_impl.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/sync_token.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/ppapi_host.h"
@@ -149,12 +150,11 @@ PepperCompositorHost::LayerData::LayerData(const LayerData& other) = default;
PepperCompositorHost::LayerData::~LayerData() {}
-PepperCompositorHost::PepperCompositorHost(
- RendererPpapiHost* host,
- PP_Instance instance,
- PP_Resource resource)
+PepperCompositorHost::PepperCompositorHost(RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
- bound_instance_(NULL),
+ bound_instance_(nullptr),
weak_factory_(this) {
layer_ = cc::Layer::Create();
// TODO(penghuang): SetMasksToBounds() can be expensive if the layer is
@@ -281,11 +281,11 @@ void PepperCompositorHost::UpdateLayer(
static_cast<cc::TextureLayer*>(layer.get()));
if (!old_layer ||
new_layer->common.resource_id != old_layer->common.resource_id) {
- viz::TextureMailbox mailbox(new_layer->texture->mailbox,
- new_layer->texture->sync_token,
- new_layer->texture->target);
- texture_layer->SetTextureMailbox(
- mailbox,
+ auto resource = viz::TransferableResource::MakeGL(
+ new_layer->texture->mailbox, GL_LINEAR, new_layer->texture->target,
+ new_layer->texture->sync_token);
+ texture_layer->SetTransferableResource(
+ resource,
viz::SingleReleaseCallback::Create(base::Bind(
&PepperCompositorHost::ResourceReleased,
weak_factory_.GetWeakPtr(), new_layer->common.resource_id)));
@@ -319,9 +319,10 @@ void PepperCompositorHost::UpdateLayer(
->shared_bitmap_manager()
->GetBitmapForSharedMemory(image_shm.get());
- viz::TextureMailbox mailbox(bitmap.get(), PP_ToGfxSize(desc.size));
- image_layer->SetTextureMailbox(
- mailbox,
+ auto resource = viz::TransferableResource::MakeSoftware(
+ bitmap->id(), bitmap->sequence_number(), PP_ToGfxSize(desc.size));
+ image_layer->SetTransferableResource(
+ resource,
viz::SingleReleaseCallback::Create(base::Bind(
&PepperCompositorHost::ImageReleased, weak_factory_.GetWeakPtr(),
new_layer->common.resource_id, base::Passed(&image_shm),
@@ -369,7 +370,7 @@ int32_t PepperCompositorHost::OnHostMsgCommitLayers(
// plugin and keep current layers set by the previous CommitLayers()
// unchanged.
for (size_t i = 0; i < layers.size(); ++i) {
- const ppapi::CompositorLayerData* old_layer = NULL;
+ const ppapi::CompositorLayerData* old_layer = nullptr;
if (!reset && i < layers_.size())
old_layer = &layers_[i].pp_layer;
int32_t rv = VerifyCommittedLayer(old_layer, &layers[i], &image_shms[i]);
@@ -386,16 +387,16 @@ int32_t PepperCompositorHost::OnHostMsgCommitLayers(
for (size_t i = 0; i < layers.size(); ++i) {
const ppapi::CompositorLayerData* pp_layer = &layers[i];
- LayerData* data = i >= layers_.size() ? NULL : &layers_[i];
+ LayerData* data = i >= layers_.size() ? nullptr : &layers_[i];
DCHECK(!data || data->cc_layer.get());
- scoped_refptr<cc::Layer> cc_layer = data ? data->cc_layer : NULL;
- ppapi::CompositorLayerData* old_layer = data ? &data->pp_layer : NULL;
+ scoped_refptr<cc::Layer> cc_layer = data ? data->cc_layer : nullptr;
+ ppapi::CompositorLayerData* old_layer = data ? &data->pp_layer : nullptr;
if (!cc_layer.get()) {
if (pp_layer->color)
cc_layer = cc::SolidColorLayer::Create();
else if (pp_layer->texture || pp_layer->image)
- cc_layer = cc::TextureLayer::CreateForMailbox(NULL);
+ cc_layer = cc::TextureLayer::CreateForMailbox(nullptr);
layer_->AddChild(cc_layer);
}
diff --git a/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.cc b/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.cc
index 7151e0253e3..02a3158c248 100644
--- a/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.cc
+++ b/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.cc
@@ -193,7 +193,7 @@ int32_t PepperDeviceEnumerationHostHelper::OnMonitorDeviceChange(
int32_t PepperDeviceEnumerationHostHelper::OnStopMonitoringDeviceChange(
HostMessageContext* /* context */) {
- monitor_.reset(NULL);
+ monitor_.reset(nullptr);
return PP_OK;
}
@@ -201,7 +201,7 @@ void PepperDeviceEnumerationHostHelper::OnEnumerateDevicesComplete(
const std::vector<ppapi::DeviceRefData>& devices) {
DCHECK(enumerate_devices_context_.is_valid());
- enumerate_.reset(NULL);
+ enumerate_.reset(nullptr);
enumerate_devices_context_.params.set_result(PP_OK);
resource_host_->host()->SendReply(
diff --git a/chromium/content/renderer/pepper/pepper_file_chooser_host.cc b/chromium/content/renderer/pepper/pepper_file_chooser_host.cc
index 1ef25c28be2..c305400f6f2 100644
--- a/chromium/content/renderer/pepper/pepper_file_chooser_host.cc
+++ b/chromium/content/renderer/pepper/pepper_file_chooser_host.cc
@@ -76,7 +76,7 @@ PepperFileChooserHost::PepperFileChooserHost(RendererPpapiHost* host,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
renderer_ppapi_host_(host),
- handler_(NULL),
+ handler_(nullptr),
weak_factory_(this) {}
PepperFileChooserHost::~PepperFileChooserHost() {}
@@ -116,7 +116,7 @@ void PepperFileChooserHost::StoreChosenFiles(
host()->SendReply(reply_context_,
PpapiPluginMsg_FileChooser_ShowReply(chosen_files));
reply_context_ = ppapi::host::ReplyMessageContext();
- handler_ = NULL; // Handler deletes itself.
+ handler_ = nullptr; // Handler deletes itself.
}
}
@@ -157,7 +157,7 @@ int32_t PepperFileChooserHost::OnShow(
if (!render_frame || !render_frame->ScheduleFileChooser(params, handler_)) {
delete handler_;
- handler_ = NULL;
+ handler_ = nullptr;
return PP_ERROR_NOACCESS;
}
@@ -188,7 +188,7 @@ void PepperFileChooserHost::DidCreateResourceHosts(
host()->SendReply(reply_context_,
PpapiPluginMsg_FileChooser_ShowReply(chosen_files));
reply_context_ = ppapi::host::ReplyMessageContext();
- handler_ = NULL; // Handler deletes itself.
+ handler_ = nullptr; // Handler deletes itself.
}
} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_file_system_host.cc b/chromium/content/renderer/pepper/pepper_file_system_host.cc
index e2f19d5d0f1..75a255a52de 100644
--- a/chromium/content/renderer/pepper/pepper_file_system_host.cc
+++ b/chromium/content/renderer/pepper/pepper_file_system_host.cc
@@ -6,12 +6,12 @@
#include "base/bind.h"
#include "base/callback.h"
-#include "content/child/child_thread_impl.h"
-#include "content/child/fileapi/file_system_dispatcher.h"
#include "content/common/pepper_file_util.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"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/ppapi_host.h"
@@ -100,7 +100,7 @@ int32_t PepperFileSystemHost::OnHostMsgOpen(
return PP_ERROR_FAILED;
FileSystemDispatcher* file_system_dispatcher =
- ChildThreadImpl::current()->file_system_dispatcher();
+ RenderThreadImpl::current()->file_system_dispatcher();
reply_context_ = context->MakeReplyMessageContext();
file_system_dispatcher->OpenFileSystem(
document_url.GetOrigin(), file_system_type,
diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc b/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc
index f5b12e356a4..cfb923c875b 100644
--- a/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc
+++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc
@@ -10,14 +10,16 @@
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/numerics/checked_math.h"
#include "base/single_thread_task_runner.h"
+#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/paint/paint_flags.h"
#include "components/viz/client/client_shared_bitmap_manager.h"
+#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/quads/shared_bitmap.h"
-#include "components/viz/common/quads/texture_mailbox.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/pepper/gfx_conversion.h"
@@ -25,6 +27,9 @@
#include "content/renderer/pepper/plugin_instance_throttler_impl.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
#include "content/renderer/render_thread_impl.h"
+#include "gpu/GLES2/gl2extchromium.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/capabilities.h"
#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_rect.h"
@@ -35,7 +40,10 @@
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/ppb_view_shared.h"
#include "ppapi/thunk/enter.h"
+#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "skia/ext/platform_canvas.h"
+#include "third_party/khronos/GLES2/gl2.h"
+#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkSwizzle.h"
#include "ui/gfx/blit.h"
@@ -170,7 +178,7 @@ PepperGraphics2DHost* PepperGraphics2DHost::Create(
PP_ToBool(is_always_opaque),
backing_store)) {
delete resource_host;
- return NULL;
+ return nullptr;
}
return resource_host;
}
@@ -180,15 +188,23 @@ PepperGraphics2DHost::PepperGraphics2DHost(RendererPpapiHost* host,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
renderer_ppapi_host_(host),
- bound_instance_(NULL),
+ bound_instance_(nullptr),
need_flush_ack_(false),
offscreen_flush_pending_(false),
is_always_opaque_(false),
scale_(1.0f),
- is_running_in_process_(host->IsRunningInProcess()),
- texture_mailbox_modified_(true) {}
+ is_running_in_process_(host->IsRunningInProcess()) {}
PepperGraphics2DHost::~PepperGraphics2DHost() {
+ // Delete textures owned by PepperGraphics2DHost, but not those sent to the
+ // compositor, since those will be deleted by ReleaseTextureCallback() when it
+ // runs.
+ while (main_thread_context_ && !recycled_texture_copies_.empty()) {
+ uint32_t texture_id = recycled_texture_copies_.back().id;
+ main_thread_context_->ContextGL()->DeleteTextures(1, &texture_id);
+ recycled_texture_copies_.pop_back();
+ }
+
// Unbind from the instance when destroyed if we're still bound.
if (bound_instance_)
bound_instance_->BindGraphics(bound_instance_->pp_instance(), 0);
@@ -206,11 +222,27 @@ bool PepperGraphics2DHost::Init(
height,
true) ||
!image_data_->Map()) {
- image_data_ = NULL;
+ image_data_ = nullptr;
return false;
}
is_always_opaque_ = is_always_opaque;
scale_ = 1.0f;
+
+ // Gets the texture target for RGBA and BGRA textures if we can make
+ // image-backed textures for direct scanout (for use in overlays).
+ RenderThreadImpl* rti = RenderThreadImpl::current();
+ if (rti && rti->IsGpuMemoryBufferCompositorResourcesEnabled()) {
+ const auto& map = rti->GetBufferToTextureTargetMap();
+ auto target_it = map.find(viz::BufferToTextureTargetKey(
+ gfx::BufferUsage::SCANOUT, gfx::BufferFormat::BGRA_8888));
+ if (target_it != map.end())
+ scanout_texture_target_bgra_ = target_it->second;
+ target_it = map.find(viz::BufferToTextureTargetKey(
+ gfx::BufferUsage::SCANOUT, gfx::BufferFormat::RGBA_8888));
+ if (target_it != map.end())
+ scanout_texture_target_rgba_ = target_it->second;
+ }
+
return true;
}
@@ -307,7 +339,7 @@ bool PepperGraphics2DHost::BindToInstance(
}
cached_bitmap_.reset();
- texture_mailbox_modified_ = true;
+ composited_output_modified_ = true;
bound_instance_ = new_instance;
return true;
@@ -381,10 +413,6 @@ float PepperGraphics2DHost::GetScale() const { return scale_; }
bool PepperGraphics2DHost::IsAlwaysOpaque() const { return is_always_opaque_; }
-PPB_ImageData_Impl* PepperGraphics2DHost::ImageData() {
- return image_data_.get();
-}
-
gfx::Size PepperGraphics2DHost::Size() const {
if (!image_data_.get())
return gfx::Size();
@@ -410,9 +438,8 @@ int32_t PepperGraphics2DHost::OnHostMsgPaintImageData(
QueuedOperation operation(QueuedOperation::PAINT);
operation.paint_image = image_resource;
- if (!ValidateAndConvertRect(src_rect_specified ? &src_rect : NULL,
- image_resource->width(),
- image_resource->height(),
+ if (!ValidateAndConvertRect(src_rect_specified ? &src_rect : nullptr,
+ image_resource->width(), image_resource->height(),
&operation.paint_src_rect))
return PP_ERROR_BADARGUMENT;
@@ -441,9 +468,8 @@ int32_t PepperGraphics2DHost::OnHostMsgScroll(
const PP_Rect& clip,
const PP_Point& amount) {
QueuedOperation operation(QueuedOperation::SCROLL);
- if (!ValidateAndConvertRect(clip_specified ? &clip : NULL,
- image_data_->width(),
- image_data_->height(),
+ if (!ValidateAndConvertRect(clip_specified ? &clip : nullptr,
+ image_data_->width(), image_data_->height(),
&operation.scroll_clip_rect))
return PP_ERROR_BADARGUMENT;
@@ -494,7 +520,7 @@ int32_t PepperGraphics2DHost::OnHostMsgFlush(
PP_Resource old_image_data = 0;
flush_reply_context_ = context->MakeReplyMessageContext();
if (is_running_in_process_)
- return Flush(NULL);
+ return Flush(nullptr);
// Reuse image data when running out of process.
int32_t result = Flush(&old_image_data);
@@ -545,7 +571,7 @@ int32_t PepperGraphics2DHost::OnHostMsgReadImageData(
return ReadImageData(image, &top_left) ? PP_OK : PP_ERROR_FAILED;
}
-void PepperGraphics2DHost::ReleaseCallback(
+void PepperGraphics2DHost::ReleaseSoftwareCallback(
std::unique_ptr<viz::SharedBitmap> bitmap,
const gfx::Size& bitmap_size,
const gpu::SyncToken& sync_token,
@@ -558,12 +584,178 @@ void PepperGraphics2DHost::ReleaseCallback(
cached_bitmap_size_ = bitmap_size;
}
-bool PepperGraphics2DHost::PrepareTextureMailbox(
- viz::TextureMailbox* mailbox,
+// static
+void PepperGraphics2DHost::ReleaseTextureCallback(
+ base::WeakPtr<PepperGraphics2DHost> host,
+ scoped_refptr<viz::ContextProvider> context,
+ uint32_t id,
+ const gpu::SyncToken& sync_token,
+ bool lost) {
+ if (sync_token.HasData())
+ context->ContextGL()->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
+ if (host && !lost) {
+ // Recycle the texture to be used in future frames. This moves it from
+ // the busy textures list to the recycled list.
+ auto it = host->texture_copies_.begin();
+ for (; it != host->texture_copies_.end(); ++it) {
+ if (it->id == id) {
+ host->recycled_texture_copies_.push_back(*it);
+ host->texture_copies_.erase(it);
+ break;
+ }
+ }
+ return;
+ }
+
+ // The otherwise, the texture can not be reused so remove it from the busy
+ // texture list and delete it.
+ if (host) {
+ auto matches_id = [id](const TextureInfo& info) { return info.id == id; };
+ base::EraseIf(host->texture_copies_, matches_id);
+ }
+ context->ContextGL()->DeleteTextures(1, &id);
+}
+
+bool PepperGraphics2DHost::PrepareTransferableResource(
+ viz::TransferableResource* transferable_resource,
std::unique_ptr<viz::SingleReleaseCallback>* release_callback) {
- if (!texture_mailbox_modified_)
+ // Reuse the |main_thread_context_| if it is not lost. If it is lost, we
+ // can't reuse the texture ids, they are invalid. If the compositing mode
+ // changed, the context will be lost also, so we get both together.
+ if (!main_thread_context_ ||
+ main_thread_context_->ContextGL()->GetGraphicsResetStatusKHR() !=
+ GL_NO_ERROR) {
+ texture_copies_.clear();
+ recycled_texture_copies_.clear();
+ main_thread_context_ = nullptr;
+
+ if (!is_gpu_compositing_disabled_) {
+ RenderThreadImpl* rti = RenderThreadImpl::current();
+ is_gpu_compositing_disabled_ = rti->IsGpuCompositingDisabled();
+ if (!is_gpu_compositing_disabled_) {
+ // Using gpu compositing.
+ main_thread_context_ = rti->SharedMainThreadContextProvider();
+ } else {
+ // Just switched to software compositing. Force us to send the
+ // frame to the compositor again even if not changed.
+ composited_output_modified_ = true;
+ }
+ }
+ }
+
+ if (!composited_output_modified_)
return false;
- // TODO(jbauman): Send image_data_ through mailbox to avoid copy.
+
+ // Context creation failed, so we're unable to give this frame to the
+ // compositor. Try again next time.
+ if (!is_gpu_compositing_disabled_ && !main_thread_context_)
+ return false;
+
+ // When gpu compositing, the compositor expects gpu resources, so we copy the
+ // |image_data_| into a texture.
+ if (main_thread_context_) {
+ auto* gl = main_thread_context_->ContextGL();
+
+ // The bitmap in |image_data_| uses the skia N32 byte order.
+ constexpr bool bitmap_is_bgra = kN32_SkColorType == kBGRA_8888_SkColorType;
+ const bool texture_can_be_bgra =
+ main_thread_context_->ContextCapabilities().texture_format_bgra8888;
+ const bool upload_bgra = bitmap_is_bgra && texture_can_be_bgra;
+ const uint32_t format = upload_bgra ? GL_BGRA_EXT : GL_RGBA;
+
+ bool overlay_candidate = false;
+ uint32_t texture_target = GL_TEXTURE_2D;
+ uint32_t storage_format = 0;
+ if (main_thread_context_->ContextCapabilities().texture_storage_image) {
+ if (upload_bgra && scanout_texture_target_bgra_) {
+ texture_target = scanout_texture_target_bgra_;
+ storage_format = GL_BGRA8_EXT;
+ overlay_candidate = true;
+ } else if (!upload_bgra && scanout_texture_target_rgba_) {
+ texture_target = scanout_texture_target_rgba_;
+ storage_format = GL_RGBA8_OES;
+ overlay_candidate = true;
+ }
+ }
+
+ const gfx::Size size(image_data_->width(), image_data_->height());
+
+ uint32_t texture_id = 0;
+ gpu::Mailbox gpu_mailbox;
+ while (!recycled_texture_copies_.empty()) {
+ if (recycled_texture_copies_.back().size == size) {
+ texture_id = recycled_texture_copies_.back().id;
+ gpu_mailbox = recycled_texture_copies_.back().mailbox;
+ recycled_texture_copies_.pop_back();
+ gl->BindTexture(texture_target, texture_id);
+ break;
+ }
+ uint32_t id = recycled_texture_copies_.back().id;
+ main_thread_context_->ContextGL()->DeleteTextures(1, &id);
+ recycled_texture_copies_.pop_back();
+ }
+ if (!texture_id) {
+ gl->GenTextures(1, &texture_id);
+ gl->BindTexture(texture_target, texture_id);
+ gl->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ if (overlay_candidate) {
+ gl->TexStorage2DImageCHROMIUM(texture_target, storage_format,
+ GL_SCANOUT_CHROMIUM, size.width(),
+ size.height());
+ } else {
+ gl->TexImage2D(texture_target, 0, format, size.width(), size.height(),
+ 0, format, GL_UNSIGNED_BYTE, nullptr);
+ }
+
+ gl->GenMailboxCHROMIUM(gpu_mailbox.name);
+ gl->ProduceTextureCHROMIUM(texture_target, gpu_mailbox.name);
+ }
+
+ TextureInfo info;
+ info.id = texture_id;
+ info.mailbox = gpu_mailbox;
+ info.size = size;
+ texture_copies_.push_back(std::move(info));
+
+ void* src = image_data_->Map();
+
+ // Convert to RGBA if we can't upload BGRA. This is slow sad times.
+ std::unique_ptr<uint32_t[]> swizzled;
+ if (bitmap_is_bgra != upload_bgra) {
+ size_t num_pixels = (base::CheckedNumeric<size_t>(image_data_->width()) *
+ image_data_->height())
+ .ValueOrDie();
+ swizzled = std::make_unique<uint32_t[]>(num_pixels);
+ SkSwapRB(swizzled.get(), static_cast<uint32_t*>(src), num_pixels);
+ src = swizzled.get();
+ }
+
+ gl->TexSubImage2D(texture_target, 0, 0, 0, size.width(), size.height(),
+ format, GL_UNSIGNED_BYTE, src);
+ image_data_->Unmap();
+ swizzled.reset();
+
+ gpu::SyncToken sync_token;
+ uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM();
+ gl->OrderingBarrierCHROMIUM();
+ gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
+
+ gl->BindTexture(texture_target, 0);
+
+ *transferable_resource = viz::TransferableResource::MakeGLOverlay(
+ std::move(gpu_mailbox), GL_LINEAR, texture_target,
+ std::move(sync_token), size, overlay_candidate);
+ *release_callback = viz::SingleReleaseCallback::Create(
+ base::Bind(&ReleaseTextureCallback, this->AsWeakPtr(),
+ main_thread_context_, texture_id));
+ composited_output_modified_ = false;
+ return true;
+ }
+
gfx::Size pixel_image_size(image_data_->width(), image_data_->height());
std::unique_ptr<viz::SharedBitmap> shared_bitmap;
if (cached_bitmap_) {
@@ -584,16 +776,17 @@ bool PepperGraphics2DHost::PrepareTextureMailbox(
viz::SharedBitmap::CheckedSizeInBytes(pixel_image_size));
image_data_->Unmap();
- *mailbox = viz::TextureMailbox(shared_bitmap.get(), pixel_image_size);
- *release_callback = viz::SingleReleaseCallback::Create(
- base::Bind(&PepperGraphics2DHost::ReleaseCallback, this->AsWeakPtr(),
- base::Passed(&shared_bitmap), pixel_image_size));
- texture_mailbox_modified_ = false;
+ *transferable_resource = viz::TransferableResource::MakeSoftware(
+ shared_bitmap->id(), shared_bitmap->sequence_number(), pixel_image_size);
+ *release_callback = viz::SingleReleaseCallback::Create(base::Bind(
+ &PepperGraphics2DHost::ReleaseSoftwareCallback, this->AsWeakPtr(),
+ base::Passed(&shared_bitmap), pixel_image_size));
+ composited_output_modified_ = false;
return true;
}
void PepperGraphics2DHost::AttachedToNewLayer() {
- texture_mailbox_modified_ = true;
+ composited_output_modified_ = true;
}
int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) {
@@ -626,9 +819,9 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) {
// reference, if there are more than one ReplaceContents calls queued
// the first |old_image_data| will get overwritten and leaked. So we
// only supply this for the first call.
- ExecuteReplaceContents(operation.replace_image.get(),
- &op_rect,
- done_replace_contents ? NULL : old_image_data);
+ ExecuteReplaceContents(
+ operation.replace_image.get(), &op_rect,
+ done_replace_contents ? nullptr : old_image_data);
done_replace_contents = true;
break;
}
@@ -672,7 +865,7 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) {
if (!op_rect_in_viewport.IsEmpty())
bound_instance_->InvalidateRect(op_rect_in_viewport);
}
- texture_mailbox_modified_ = true;
+ composited_output_modified_ = true;
}
}
queued_operations_.clear();
@@ -701,7 +894,8 @@ void PepperGraphics2DHost::ExecuteTransform(const float& scale,
const gfx::PointF& translate,
gfx::Rect* invalidated_rect) {
bound_instance_->SetGraphics2DTransform(scale, translate);
- *invalidated_rect = PP_ToGfxRect(bound_instance_->view_data().clip_rect);
+ *invalidated_rect =
+ gfx::Rect(0, 0, image_data_->width(), image_data_->height());
}
void PepperGraphics2DHost::ExecutePaintImageData(PPB_ImageData_Impl* image,
diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host.h b/chromium/content/renderer/pepper/pepper_graphics_2d_host.h
index a9e125809cf..16a2395133a 100644
--- a/chromium/content/renderer/pepper/pepper_graphics_2d_host.h
+++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
+#include "gpu/command_buffer/common/mailbox.h"
#include "ppapi/c/ppb_graphics_2d.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/resource_host.h"
@@ -30,9 +31,10 @@ struct SyncToken;
}
namespace viz {
+class ContextProvider;
class SharedBitmap;
class SingleReleaseCallback;
-class TextureMailbox;
+struct TransferableResource;
}
namespace content {
@@ -72,8 +74,8 @@ class CONTENT_EXPORT PepperGraphics2DHost
const gfx::Rect& plugin_rect,
const gfx::Rect& paint_rect);
- bool PrepareTextureMailbox(
- viz::TextureMailbox* mailbox,
+ bool PrepareTransferableResource(
+ viz::TransferableResource* transferable_resource,
std::unique_ptr<viz::SingleReleaseCallback>* release_callback);
void AttachedToNewLayer();
@@ -84,7 +86,6 @@ class CONTENT_EXPORT PepperGraphics2DHost
float GetScale() const;
void SetLayerTransform(float scale, const PP_Point& transform);
bool IsAlwaysOpaque() const;
- PPB_ImageData_Impl* ImageData();
gfx::Size Size() const;
void ClearCache();
@@ -171,10 +172,20 @@ class CONTENT_EXPORT PepperGraphics2DHost
gfx::Rect* op_rect,
gfx::Point* delta);
- void ReleaseCallback(std::unique_ptr<viz::SharedBitmap> bitmap,
- const gfx::Size& bitmap_size,
- const gpu::SyncToken& sync_token,
- bool lost_resource);
+ // Callback when compositor is done with a software resource given to it.
+ void ReleaseSoftwareCallback(std::unique_ptr<viz::SharedBitmap> bitmap,
+ const gfx::Size& bitmap_size,
+ const gpu::SyncToken& sync_token,
+ bool lost_resource);
+ // Callback when compositor is done with a gpu resource given to it. Static
+ // for speed. Just kidding, it's so this can clean up the texture if the host
+ // has been destroyed.
+ static void ReleaseTextureCallback(
+ base::WeakPtr<PepperGraphics2DHost> host,
+ scoped_refptr<viz::ContextProvider> context,
+ uint32_t id,
+ const gpu::SyncToken& sync_token,
+ bool lost);
RendererPpapiHost* renderer_ppapi_host_;
@@ -212,7 +223,29 @@ class CONTENT_EXPORT PepperGraphics2DHost
bool is_running_in_process_;
- bool texture_mailbox_modified_;
+ bool composited_output_modified_ = true;
+
+ // Local cache of the compositing mode. This is sticky, once true it stays
+ // that way.
+ bool is_gpu_compositing_disabled_ = false;
+ // The shared main thread context provider, used to upload 2d pepper frames
+ // if the compositor is expecting gpu content.
+ scoped_refptr<viz::ContextProvider> main_thread_context_;
+ struct TextureInfo {
+ uint32_t id;
+ gpu::Mailbox mailbox;
+ gfx::Size size;
+ };
+ // The ids of textures holding the copied contents of software frames to
+ // give to the compositor via GL. Textures in this list are in use by the
+ // compositor and are treated as owned by the compositor until the
+ // ReleaseTextureCallback() informs otherwise.
+ std::vector<TextureInfo> texture_copies_;
+ // Texture ids move from |texture_copies_| to here once they are available for
+ // reuse.
+ std::vector<TextureInfo> recycled_texture_copies_;
+ uint32_t scanout_texture_target_rgba_ = 0;
+ uint32_t scanout_texture_target_bgra_ = 0;
// This is a bitmap that was recently released by the compositor and may be
// used to transfer bytes to the compositor again.
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 327645fc8f8..5b24e209631 100644
--- a/chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc
+++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc
@@ -29,7 +29,7 @@ class PepperGraphics2DHostTest : public testing::Test {
return PepperGraphics2DHost::ConvertToLogicalPixels(scale, op_rect, delta);
}
- PepperGraphics2DHostTest() : renderer_ppapi_host_(NULL, 12345) {}
+ PepperGraphics2DHostTest() : renderer_ppapi_host_(nullptr, 12345) {}
~PepperGraphics2DHostTest() override {
ppapi::ProxyAutoLock proxy_lock;
@@ -56,8 +56,8 @@ class PepperGraphics2DHostTest : public testing::Test {
ppapi::HostResource image_data_resource;
image_data_resource.SetHostResource(image_data->pp_instance(),
image_data->pp_resource());
- host_->OnHostMsgPaintImageData(
- NULL, image_data_resource, PP_Point(), false, PP_Rect());
+ host_->OnHostMsgPaintImageData(nullptr, image_data_resource, PP_Point(),
+ false, PP_Rect());
}
void Flush() {
@@ -149,7 +149,7 @@ TEST_F(PepperGraphics2DHostTest, ConvertToLogicalPixels) {
}
// Reverse the scale and ensure all the original pixels are still inside
// the result.
- ConvertToLogicalPixels(1.0f / tests[i].scale, &r1, NULL);
+ ConvertToLogicalPixels(1.0f / tests[i].scale, &r1, nullptr);
EXPECT_TRUE(r1.Contains(orig));
}
}
diff --git a/chromium/content/renderer/pepper/pepper_in_process_router.cc b/chromium/content/renderer/pepper/pepper_in_process_router.cc
index ca038bbad2b..be02edbf768 100644
--- a/chromium/content/renderer/pepper/pepper_in_process_router.cc
+++ b/chromium/content/renderer/pepper/pepper_in_process_router.cc
@@ -132,7 +132,7 @@ bool PepperInProcessRouter::SendToHost(IPC::Message* msg) {
DCHECK(result) << "The message was not handled by the host.";
pending_message_id_ = 0;
- reply_deserializer_.reset(NULL);
+ reply_deserializer_.reset(nullptr);
return reply_result_;
}
diff --git a/chromium/content/renderer/pepper/pepper_media_device_manager.cc b/chromium/content/renderer/pepper/pepper_media_device_manager.cc
index 247b5c54b46..db0bd30b6c5 100644
--- a/chromium/content/renderer/pepper/pepper_media_device_manager.cc
+++ b/chromium/content/renderer/pepper/pepper_media_device_manager.cc
@@ -9,14 +9,17 @@
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "content/child/child_thread_impl.h"
#include "content/public/common/console_message_level.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/service_names.mojom.h"
#include "content/renderer/media/media_devices_event_dispatcher.h"
-#include "content/renderer/media/media_stream_dispatcher.h"
+#include "content/renderer/media/media_stream_device_observer.h"
#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
#include "content/renderer/render_frame_impl.h"
#include "media/media_features.h"
#include "ppapi/shared_impl/ppb_device_ref_shared.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
namespace content {
@@ -150,20 +153,23 @@ int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type,
kPepperInsecureOriginMessage);
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&PepperMediaDeviceManager::OnDeviceOpenFailed,
- AsWeakPtr(), request_id));
+ FROM_HERE,
+ base::BindOnce(&PepperMediaDeviceManager::OnDeviceOpened, AsWeakPtr(),
+ request_id, false, std::string(), MediaStreamDevice()));
return request_id;
}
#if BUILDFLAG(ENABLE_WEBRTC)
- GetMediaStreamDispatcher()->OpenDevice(
- request_id, AsWeakPtr(), device_id,
+ GetMediaStreamDispatcherHost()->OpenDevice(
+ routing_id(), request_id, device_id,
PepperMediaDeviceManager::FromPepperDeviceType(type),
- url::Origin(host->GetDocumentURL(pp_instance).GetOrigin()));
+ base::BindOnce(&PepperMediaDeviceManager::OnDeviceOpened, AsWeakPtr(),
+ request_id));
#else
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed,
- AsWeakPtr(), request_id));
+ FROM_HERE,
+ base::Bind(&PepperMediaDeviceManager::OnDeviceOpened, AsWeakPtr(),
+ request_id, false, std::string(), MediaStreamDevice()));
#endif
return request_id;
@@ -173,13 +179,16 @@ void PepperMediaDeviceManager::CancelOpenDevice(int request_id) {
open_callbacks_.erase(request_id);
#if BUILDFLAG(ENABLE_WEBRTC)
- GetMediaStreamDispatcher()->CancelOpenDevice(request_id, AsWeakPtr());
+ GetMediaStreamDispatcherHost()->CancelRequest(routing_id(), request_id);
#endif
}
void PepperMediaDeviceManager::CloseDevice(const std::string& label) {
#if BUILDFLAG(ENABLE_WEBRTC)
- GetMediaStreamDispatcher()->CloseDevice(label);
+ if (!GetMediaStreamDeviceObserver()->RemoveStream(label))
+ return;
+
+ GetMediaStreamDispatcherHost()->CloseDevice(label);
#endif
}
@@ -188,9 +197,9 @@ int PepperMediaDeviceManager::GetSessionID(PP_DeviceType_Dev type,
#if BUILDFLAG(ENABLE_WEBRTC)
switch (type) {
case PP_DEVICETYPE_DEV_AUDIOCAPTURE:
- return GetMediaStreamDispatcher()->audio_session_id(label, 0);
+ return GetMediaStreamDeviceObserver()->audio_session_id(label);
case PP_DEVICETYPE_DEV_VIDEOCAPTURE:
- return GetMediaStreamDispatcher()->video_session_id(label, 0);
+ return GetMediaStreamDeviceObserver()->video_session_id(label);
default:
NOTREACHED();
return 0;
@@ -200,30 +209,6 @@ int PepperMediaDeviceManager::GetSessionID(PP_DeviceType_Dev type,
#endif
}
-void PepperMediaDeviceManager::OnStreamGenerated(
- int request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) {}
-
-void PepperMediaDeviceManager::OnStreamGenerationFailed(
- int request_id,
- MediaStreamRequestResult result) {}
-
-void PepperMediaDeviceManager::OnDeviceStopped(
- const std::string& label,
- const MediaStreamDevice& device) {}
-
-void PepperMediaDeviceManager::OnDeviceOpened(int request_id,
- const std::string& label,
- const MediaStreamDevice& device) {
- NotifyDeviceOpened(request_id, true, label);
-}
-
-void PepperMediaDeviceManager::OnDeviceOpenFailed(int request_id) {
- NotifyDeviceOpened(request_id, false, std::string());
-}
-
// static
MediaStreamType PepperMediaDeviceManager::FromPepperDeviceType(
PP_DeviceType_Dev type) {
@@ -240,19 +225,23 @@ MediaStreamType PepperMediaDeviceManager::FromPepperDeviceType(
}
}
-void PepperMediaDeviceManager::NotifyDeviceOpened(int request_id,
- bool succeeded,
- const std::string& label) {
+void PepperMediaDeviceManager::OnDeviceOpened(int request_id,
+ bool success,
+ const std::string& label,
+ const MediaStreamDevice& device) {
OpenCallbackMap::iterator iter = open_callbacks_.find(request_id);
if (iter == open_callbacks_.end()) {
// The callback may have been unregistered.
return;
}
+ if (success)
+ GetMediaStreamDeviceObserver()->AddStream(label, device);
+
OpenDeviceCallback callback = iter->second;
open_callbacks_.erase(iter);
- callback.Run(request_id, succeeded, label);
+ callback.Run(request_id, success, success ? label : std::string());
}
void PepperMediaDeviceManager::DevicesEnumerated(
@@ -274,16 +263,26 @@ void PepperMediaDeviceManager::DevicesChanged(
client_callback.Run(devices);
}
-MediaStreamDispatcher* PepperMediaDeviceManager::GetMediaStreamDispatcher()
- const {
+const mojom::MediaStreamDispatcherHostPtr&
+PepperMediaDeviceManager::GetMediaStreamDispatcherHost() {
+ if (!dispatcher_host_) {
+ ChildThreadImpl::current()->GetConnector()->BindInterface(
+ mojom::kBrowserServiceName, &dispatcher_host_);
+ }
+ return dispatcher_host_;
+}
+
+MediaStreamDeviceObserver*
+PepperMediaDeviceManager::GetMediaStreamDeviceObserver() const {
DCHECK(render_frame());
- MediaStreamDispatcher* const dispatcher =
- static_cast<RenderFrameImpl*>(render_frame())->GetMediaStreamDispatcher();
- DCHECK(dispatcher);
- return dispatcher;
+ MediaStreamDeviceObserver* const observer =
+ static_cast<RenderFrameImpl*>(render_frame())
+ ->GetMediaStreamDeviceObserver();
+ DCHECK(observer);
+ return observer;
}
-const ::mojom::MediaDevicesDispatcherHostPtr&
+const blink::mojom::MediaDevicesDispatcherHostPtr&
PepperMediaDeviceManager::GetMediaDevicesDispatcher() {
if (!media_devices_dispatcher_) {
CHECK(render_frame());
diff --git a/chromium/content/renderer/pepper/pepper_media_device_manager.h b/chromium/content/renderer/pepper/pepper_media_device_manager.h
index 2000648a6ac..329cd56271e 100644
--- a/chromium/content/renderer/pepper/pepper_media_device_manager.h
+++ b/chromium/content/renderer/pepper/pepper_media_device_manager.h
@@ -12,19 +12,18 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/media/media_devices.h"
-#include "content/common/media/media_devices.mojom.h"
+#include "content/common/media/media_stream.mojom.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_observer_tracker.h"
-#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
#include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
#include "ppapi/c/pp_instance.h"
+#include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
namespace content {
-class MediaStreamDispatcher;
+class MediaStreamDeviceObserver;
class PepperMediaDeviceManager
- : public MediaStreamDispatcherEventHandler,
- public PepperDeviceEnumerationHostHelper::Delegate,
+ : public PepperDeviceEnumerationHostHelper::Delegate,
public RenderFrameObserver,
public RenderFrameObserverTracker<PepperMediaDeviceManager>,
public base::SupportsWeakPtr<PepperMediaDeviceManager> {
@@ -62,20 +61,6 @@ class PepperMediaDeviceManager
// Gets audio/video session ID given a label.
int GetSessionID(PP_DeviceType_Dev type, const std::string& label);
- // MediaStreamDispatcherEventHandler implementation.
- void OnStreamGenerated(int request_id,
- const std::string& label,
- const MediaStreamDevices& audio_devices,
- const MediaStreamDevices& video_devices) override;
- void OnStreamGenerationFailed(int request_id,
- MediaStreamRequestResult result) override;
- void OnDeviceStopped(const std::string& label,
- const MediaStreamDevice& device) override;
- void OnDeviceOpened(int request_id,
- const std::string& label,
- const MediaStreamDevice& device) override;
- void OnDeviceOpenFailed(int request_id) override;
-
// Stream type conversion.
static MediaStreamType FromPepperDeviceType(PP_DeviceType_Dev type);
@@ -89,9 +74,10 @@ class PepperMediaDeviceManager
// a reentrancy problem.
void StopEnumerateDevicesDelayed(int request_id);
- void NotifyDeviceOpened(int request_id,
- bool succeeded,
- const std::string& label);
+ void OnDeviceOpened(int request_id,
+ bool success,
+ const std::string& label,
+ const MediaStreamDevice& device);
void DevicesEnumerated(const DevicesCallback& callback,
MediaDeviceType type,
@@ -101,15 +87,18 @@ class PepperMediaDeviceManager
MediaDeviceType type,
const MediaDeviceInfoArray& enumeration);
- MediaStreamDispatcher* GetMediaStreamDispatcher() const;
- const ::mojom::MediaDevicesDispatcherHostPtr& GetMediaDevicesDispatcher();
+ const mojom::MediaStreamDispatcherHostPtr& GetMediaStreamDispatcherHost();
+ MediaStreamDeviceObserver* GetMediaStreamDeviceObserver() const;
+ const blink::mojom::MediaDevicesDispatcherHostPtr&
+ GetMediaDevicesDispatcher();
int next_id_;
typedef std::map<int, OpenDeviceCallback> OpenCallbackMap;
OpenCallbackMap open_callbacks_;
- ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher_;
+ mojom::MediaStreamDispatcherHostPtr dispatcher_host_;
+ blink::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher_;
DISALLOW_COPY_AND_ASSIGN(PepperMediaDeviceManager);
};
diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_input.cc b/chromium/content/renderer/pepper/pepper_platform_audio_input.cc
index 8006c1aca0b..07f44c07139 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_input.cc
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_input.cc
@@ -41,7 +41,7 @@ PepperPlatformAudioInput* PepperPlatformAudioInput::Create(
audio_input->AddRef();
return audio_input.get();
}
- return NULL;
+ return nullptr;
}
void PepperPlatformAudioInput::StartCapture() {
@@ -69,7 +69,7 @@ void PepperPlatformAudioInput::ShutDown() {
// Called on the main thread to stop all audio callbacks. We must only change
// the client on the main thread, and the delegates from the I/O thread.
- client_ = NULL;
+ client_ = nullptr;
io_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&PepperPlatformAudioInput::ShutDownOnIOThread, this));
@@ -127,14 +127,13 @@ PepperPlatformAudioInput::~PepperPlatformAudioInput() {
}
PepperPlatformAudioInput::PepperPlatformAudioInput()
- : client_(NULL),
+ : client_(nullptr),
main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
io_task_runner_(ChildProcess::current()->io_task_runner()),
render_frame_id_(MSG_ROUTING_NONE),
create_stream_sent_(false),
pending_open_device_(false),
- pending_open_device_id_(-1) {
-}
+ pending_open_device_id_(-1) {}
bool PepperPlatformAudioInput::Initialize(
int render_frame_id,
@@ -277,8 +276,9 @@ PepperMediaDeviceManager* PepperPlatformAudioInput::GetMediaDeviceManager() {
RenderFrameImpl* const render_frame =
RenderFrameImpl::FromRoutingID(render_frame_id_);
- return render_frame ?
- PepperMediaDeviceManager::GetForRenderFrame(render_frame).get() : NULL;
+ return render_frame
+ ? PepperMediaDeviceManager::GetForRenderFrame(render_frame).get()
+ : nullptr;
}
} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output.cc b/chromium/content/renderer/pepper/pepper_platform_audio_output.cc
index 9f06c13a514..56147c04c2c 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_output.cc
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_output.cc
@@ -34,7 +34,7 @@ PepperPlatformAudioOutput* PepperPlatformAudioOutput::Create(
audio_output->AddRef();
return audio_output.get();
}
- return NULL;
+ return nullptr;
}
bool PepperPlatformAudioOutput::StartPlayback() {
@@ -73,7 +73,7 @@ bool PepperPlatformAudioOutput::SetVolume(double volume) {
void PepperPlatformAudioOutput::ShutDown() {
// Called on the main thread to stop all audio callbacks. We must only change
// the client on the main thread, and the delegates from the I/O thread.
- client_ = NULL;
+ client_ = nullptr;
io_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&PepperPlatformAudioOutput::ShutDownOnIOThread, this));
@@ -121,10 +121,9 @@ PepperPlatformAudioOutput::~PepperPlatformAudioOutput() {
}
PepperPlatformAudioOutput::PepperPlatformAudioOutput()
- : client_(NULL),
+ : client_(nullptr),
main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
- io_task_runner_(ChildProcess::current()->io_task_runner()) {
-}
+ io_task_runner_(ChildProcess::current()->io_task_runner()) {}
bool PepperPlatformAudioOutput::Initialize(int sample_rate,
int frames_per_buffer,
diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output_dev.cc b/chromium/content/renderer/pepper/pepper_platform_audio_output_dev.cc
index e6b8d1a9582..69cd0f23f9b 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_output_dev.cc
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_output_dev.cc
@@ -54,7 +54,7 @@ PepperPlatformAudioOutputDev* PepperPlatformAudioOutputDev::Create(
audio_output->AddRef();
return audio_output.get();
}
- return NULL;
+ return nullptr;
}
void PepperPlatformAudioOutputDev::RequestDeviceAuthorization() {
@@ -103,7 +103,7 @@ bool PepperPlatformAudioOutputDev::SetVolume(double volume) {
void PepperPlatformAudioOutputDev::ShutDown() {
// Called on the main thread to stop all audio callbacks. We must only change
// the client on the main thread, and the delegates from the I/O thread.
- client_ = NULL;
+ client_ = nullptr;
io_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&PepperPlatformAudioOutputDev::ShutDownOnIOThread, this));
@@ -233,7 +233,7 @@ PepperPlatformAudioOutputDev::PepperPlatformAudioOutputDev(
const std::string& device_id,
const GURL& document_url,
base::TimeDelta authorization_timeout)
- : client_(NULL),
+ : client_(nullptr),
main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
io_task_runner_(ChildProcess::current()->io_task_runner()),
render_frame_id_(render_frame_id),
@@ -242,7 +242,7 @@ PepperPlatformAudioOutputDev::PepperPlatformAudioOutputDev(
play_on_start_(false),
session_id_(0),
device_id_(device_id),
- security_origin_(document_url),
+ security_origin_(url::Origin::Create(document_url)),
did_receive_auth_(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED),
device_status_(media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL),
diff --git a/chromium/content/renderer/pepper/pepper_platform_camera_device.cc b/chromium/content/renderer/pepper/pepper_platform_camera_device.cc
index 030135b2c67..4d07a0c066e 100644
--- a/chromium/content/renderer/pepper/pepper_platform_camera_device.cc
+++ b/chromium/content/renderer/pepper/pepper_platform_camera_device.cc
@@ -53,7 +53,7 @@ void PepperPlatformCameraDevice::GetSupportedVideoCaptureFormats() {
void PepperPlatformCameraDevice::DetachEventHandler() {
DCHECK(thread_checker_.CalledOnValidThread());
- handler_ = NULL;
+ handler_ = nullptr;
if (!release_device_cb_.is_null()) {
base::ResetAndReturn(&release_device_cb_).Run();
}
@@ -122,7 +122,7 @@ PepperMediaDeviceManager* PepperPlatformCameraDevice::GetMediaDeviceManager() {
RenderFrameImpl::FromRoutingID(render_frame_id_);
return render_frame
? PepperMediaDeviceManager::GetForRenderFrame(render_frame).get()
- : NULL;
+ : nullptr;
}
} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_platform_video_capture.cc b/chromium/content/renderer/pepper/pepper_platform_video_capture.cc
index e3fae3824d9..912109513bf 100644
--- a/chromium/content/renderer/pepper/pepper_platform_video_capture.cc
+++ b/chromium/content/renderer/pepper/pepper_platform_video_capture.cc
@@ -67,7 +67,7 @@ void PepperPlatformVideoCapture::StopCapture() {
}
void PepperPlatformVideoCapture::DetachEventHandler() {
- handler_ = NULL;
+ handler_ = nullptr;
StopCapture();
if (!release_device_cb_.is_null()) {
release_device_cb_.Run();
@@ -147,8 +147,9 @@ void PepperPlatformVideoCapture::OnFrameReady(
PepperMediaDeviceManager* PepperPlatformVideoCapture::GetMediaDeviceManager() {
RenderFrameImpl* const render_frame =
RenderFrameImpl::FromRoutingID(render_frame_id_);
- return render_frame ?
- PepperMediaDeviceManager::GetForRenderFrame(render_frame).get() : NULL;
+ return render_frame
+ ? PepperMediaDeviceManager::GetForRenderFrame(render_frame).get()
+ : nullptr;
}
} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 7486abc505a..5555f5c7b38 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -311,7 +311,7 @@ bool SecurityOriginForInstance(PP_Instance instance_id,
// is not modified.
std::unique_ptr<const char* []> StringVectorToArgArray(
const std::vector<std::string>& vector) {
- auto array = base::MakeUnique<const char* []>(vector.size());
+ auto array = std::make_unique<const char* []>(vector.size());
for (size_t i = 0; i < vector.size(); ++i)
array[i] = vector[i].c_str();
return array;
@@ -364,6 +364,25 @@ class PluginInstanceLockTarget : public MouseLockDispatcher::LockTarget {
PepperPluginInstanceImpl* plugin_;
};
+void PrintPDFOutput(PP_Resource print_output,
+ printing::PdfMetafileSkia* metafile) {
+#if BUILDFLAG(ENABLE_PRINTING)
+ DCHECK(metafile);
+
+ ppapi::thunk::EnterResourceNoLock<PPB_Buffer_API> enter(print_output, true);
+ if (enter.failed())
+ return;
+
+ BufferAutoMapper mapper(enter.object());
+ if (!mapper.data() || !mapper.size()) {
+ NOTREACHED();
+ return;
+ }
+
+ metafile->InitFromData(mapper.data(), mapper.size());
+#endif // BUILDFLAG(ENABLE_PRINTING)
+}
+
} // namespace
// static
@@ -377,7 +396,7 @@ PepperPluginInstanceImpl* PepperPluginInstanceImpl::Create(
PPP_Instance_Combined* ppp_instance_combined =
PPP_Instance_Combined::Create(get_plugin_interface_func);
if (!ppp_instance_combined)
- return NULL;
+ return nullptr;
return new PepperPluginInstanceImpl(render_frame,
module,
@@ -445,7 +464,7 @@ void PepperPluginInstanceImpl::ExternalDocumentLoader::DidFail(
if (finished_loading_)
return;
- error_ = base::MakeUnique<WebURLError>(error);
+ error_ = std::make_unique<WebURLError>(error);
}
PepperPluginInstanceImpl::GamepadImpl::GamepadImpl()
@@ -488,29 +507,29 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl(
full_frame_(false),
viewport_to_dip_scale_(1.0f),
sent_initial_did_change_view_(false),
- bound_graphics_2d_platform_(NULL),
- bound_compositor_(NULL),
+ bound_graphics_2d_platform_(nullptr),
+ bound_compositor_(nullptr),
has_webkit_focus_(false),
has_content_area_focus_(false),
find_identifier_(-1),
- plugin_find_interface_(NULL),
- plugin_input_event_interface_(NULL),
- plugin_mouse_lock_interface_(NULL),
- plugin_pdf_interface_(NULL),
- plugin_private_interface_(NULL),
- plugin_textinput_interface_(NULL),
+ plugin_find_interface_(nullptr),
+ plugin_input_event_interface_(nullptr),
+ plugin_mouse_lock_interface_(nullptr),
+ plugin_pdf_interface_(nullptr),
+ plugin_private_interface_(nullptr),
+ plugin_textinput_interface_(nullptr),
checked_for_plugin_input_event_interface_(false),
checked_for_plugin_pdf_interface_(false),
metafile_(nullptr),
gamepad_impl_(new GamepadImpl()),
- uma_private_impl_(NULL),
- plugin_print_interface_(NULL),
+ uma_private_impl_(nullptr),
+ plugin_print_interface_(nullptr),
always_on_top_(false),
- fullscreen_container_(NULL),
+ fullscreen_container_(nullptr),
flash_fullscreen_(false),
desired_fullscreen_state_(false),
- message_channel_(NULL),
- sad_plugin_(NULL),
+ message_channel_(nullptr),
+ sad_plugin_(nullptr),
input_event_mask_(0),
filtered_input_event_mask_(0),
text_input_type_(kPluginDefaultTextInputType),
@@ -520,12 +539,12 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl(
selection_caret_(0),
selection_anchor_(0),
pending_user_gesture_(0.0),
- document_loader_(NULL),
+ document_loader_(nullptr),
external_document_load_(false),
isolate_(v8::Isolate::GetCurrent()),
is_deleted_(false),
initialized_(false),
- audio_controller_(base::MakeUnique<PepperAudioController>(this)),
+ audio_controller_(std::make_unique<PepperAudioController>(this)),
view_change_weak_ptr_factory_(this),
weak_factory_(this) {
pp_instance_ = HostGlobals::Get()->AddInstance(this);
@@ -618,7 +637,7 @@ v8::Local<v8::Object> PepperPluginInstanceImpl::GetMessageChannelObject() {
}
void PepperPluginInstanceImpl::MessageChannelDestroyed() {
- message_channel_ = NULL;
+ message_channel_ = nullptr;
message_channel_object_.Reset();
}
@@ -678,14 +697,14 @@ void PepperPluginInstanceImpl::Delete() {
if (fullscreen_container_) {
fullscreen_container_->Destroy();
- fullscreen_container_ = NULL;
+ fullscreen_container_ = nullptr;
}
// Force-unbind any Graphics. In the case of Graphics2D, if the plugin
// leaks the graphics 2D, it may actually get cleaned up after our
// destruction, so we need its pointers to be up to date.
BindGraphics(pp_instance(), 0);
- container_ = NULL;
+ container_ = nullptr;
}
bool PepperPluginInstanceImpl::is_deleted() const { return is_deleted_; }
@@ -755,15 +774,16 @@ void PepperPluginInstanceImpl::ScrollRect(int dx,
}
}
-void PepperPluginInstanceImpl::CommitTextureMailbox(
- const viz::TextureMailbox& texture_mailbox) {
- if (committed_texture_.IsValid() && !IsTextureInUse(committed_texture_)) {
+void PepperPluginInstanceImpl::CommitTransferableResource(
+ const viz::TransferableResource& resource) {
+ if (!committed_texture_.mailbox_holder.mailbox.IsZero() &&
+ !IsTextureInUse(committed_texture_)) {
committed_texture_graphics_3d_->ReturnFrontBuffer(
- committed_texture_.mailbox(), committed_texture_consumed_sync_token_,
- false);
+ committed_texture_.mailbox_holder.mailbox,
+ committed_texture_consumed_sync_token_, false);
}
- committed_texture_ = texture_mailbox;
+ committed_texture_ = resource;
committed_texture_graphics_3d_ = bound_graphics_3d_;
committed_texture_consumed_sync_token_ = gpu::SyncToken();
@@ -779,7 +799,7 @@ void PepperPluginInstanceImpl::CommitTextureMailbox(
void PepperPluginInstanceImpl::PassCommittedTextureToTextureLayer() {
DCHECK(bound_graphics_3d_);
- if (!committed_texture_.IsValid())
+ if (committed_texture_.mailbox_holder.mailbox.IsZero())
return;
std::unique_ptr<viz::SingleReleaseCallback> callback(
@@ -789,17 +809,18 @@ void PepperPluginInstanceImpl::PassCommittedTextureToTextureLayer() {
committed_texture_graphics_3d_)));
IncrementTextureReferenceCount(committed_texture_);
- texture_layer_->SetTextureMailbox(committed_texture_, std::move(callback));
+ texture_layer_->SetTransferableResource(committed_texture_,
+ std::move(callback));
}
void PepperPluginInstanceImpl::FinishedConsumingCommittedTexture(
- const viz::TextureMailbox& texture_mailbox,
+ const viz::TransferableResource& resource,
scoped_refptr<PPB_Graphics3D_Impl> graphics_3d,
const gpu::SyncToken& sync_token,
bool is_lost) {
- bool removed = DecrementTextureReferenceCount(texture_mailbox);
- bool is_committed_texture =
- committed_texture_.mailbox() == texture_mailbox.mailbox();
+ bool removed = DecrementTextureReferenceCount(resource);
+ bool is_committed_texture = committed_texture_.mailbox_holder.mailbox ==
+ resource.mailbox_holder.mailbox;
if (is_committed_texture && !is_lost) {
committed_texture_consumed_sync_token_ = sync_token;
@@ -807,7 +828,7 @@ void PepperPluginInstanceImpl::FinishedConsumingCommittedTexture(
}
if (removed && !is_committed_texture) {
- graphics_3d->ReturnFrontBuffer(texture_mailbox.mailbox(), sync_token,
+ graphics_3d->ReturnFrontBuffer(resource.mailbox_holder.mailbox, sync_token,
is_lost);
}
}
@@ -892,7 +913,7 @@ bool PepperPluginInstanceImpl::HandleDocumentLoad(
// The external proxy isn't available, so save the response and record
// document load notifications for later replay.
external_document_response_ = response;
- external_document_loader_ = base::MakeUnique<ExternalDocumentLoader>();
+ external_document_loader_ = std::make_unique<ExternalDocumentLoader>();
document_loader_ = external_document_loader_.get();
return true;
}
@@ -911,7 +932,7 @@ bool PepperPluginInstanceImpl::HandleDocumentLoad(
// call into the instance and expect it to be valid.
RendererPpapiHostImpl* host_impl = module_->renderer_ppapi_host();
auto loader_host =
- base::MakeUnique<PepperURLLoaderHost>(host_impl, true, pp_instance(), 0);
+ std::make_unique<PepperURLLoaderHost>(host_impl, true, pp_instance(), 0);
// TODO(teravest): Remove set_document_loader() from instance and clean up
// this relationship.
set_document_loader(loader_host.get());
@@ -1168,7 +1189,8 @@ bool PepperPluginInstanceImpl::HandleInputEvent(
// Allow the user gesture to be pending after the plugin handles the
// event. This allows out-of-process plugins to respond to the user
// gesture after processing has finished here.
- if (WebUserGestureIndicator::IsProcessingUserGesture()) {
+ if (WebUserGestureIndicator::IsProcessingUserGesture(
+ render_frame_->GetWebFrame())) {
pending_user_gesture_ =
ppapi::TimeTicksToPPTimeTicks(base::TimeTicks::Now());
pending_user_gesture_token_ =
@@ -1327,7 +1349,7 @@ void PepperPluginInstanceImpl::ViewChanged(
}
}
- UpdateFlashFullscreenState(fullscreen_container_ != NULL);
+ UpdateFlashFullscreenState(fullscreen_container_ != nullptr);
// During plugin initialization, there are often re-layouts. Avoid sending
// intermediate sizes the plugin and throttler.
@@ -1777,7 +1799,7 @@ void PepperPluginInstanceImpl::SendDidChangeView() {
}
if (throttler_) {
- throttler_->Initialize(render_frame_, url::Origin(plugin_url_),
+ throttler_->Initialize(render_frame_, url::Origin::Create(plugin_url_),
module()->name(), unobscured_rect_.size());
}
}
@@ -1890,6 +1912,7 @@ int PepperPluginInstanceImpl::PrintBegin(const WebPrintParams& print_params) {
current_print_settings_ = print_settings;
metafile_ = nullptr;
ranges_.clear();
+ ranges_.reserve(num_pages);
return num_pages;
}
@@ -1897,62 +1920,51 @@ void PepperPluginInstanceImpl::PrintPage(int page_number,
blink::WebCanvas* canvas) {
#if BUILDFLAG(ENABLE_PRINTING)
DCHECK(plugin_print_interface_);
- PP_PrintPageNumberRange_Dev page_range;
- page_range.first_page_number = page_range.last_page_number = page_number;
- // The canvas only has a metafile on it for print preview.
+
+ // |canvas| should always have an associated metafile.
printing::PdfMetafileSkia* metafile =
printing::MetafileSkiaWrapper::GetMetafileFromCanvas(canvas);
- bool save_for_later = (metafile != NULL);
-#if defined(OS_MACOSX)
- save_for_later = save_for_later && cc::IsPreviewMetafile(canvas);
-#endif // defined(OS_MACOSX)
- if (save_for_later) {
- ranges_.push_back(page_range);
- metafile_ = metafile;
+ DCHECK(metafile);
+
+ // |ranges_| should be empty IFF |metafile_| is not set.
+ DCHECK_EQ(ranges_.empty(), !metafile_);
+ if (metafile_) {
+ // The metafile should be the same across all calls for a given print job.
+ DCHECK_EQ(metafile_, metafile);
} else {
- PrintPageHelper(&page_range, 1, metafile);
+ // Store |metafile| on the first call.
+ metafile_ = metafile;
}
+
+ PP_PrintPageNumberRange_Dev page_range = {page_number, page_number};
+ ranges_.push_back(page_range);
#endif
}
-void PepperPluginInstanceImpl::PrintPageHelper(
- PP_PrintPageNumberRange_Dev* page_ranges,
- int num_ranges,
- printing::PdfMetafileSkia* metafile) {
+void PepperPluginInstanceImpl::PrintEnd() {
// Keep a reference on the stack. See NOTE above.
scoped_refptr<PepperPluginInstanceImpl> ref(this);
DCHECK(plugin_print_interface_);
- if (!plugin_print_interface_)
- return;
- PP_Resource print_output = plugin_print_interface_->PrintPages(
- pp_instance(), page_ranges, num_ranges);
- if (!print_output)
- return;
-
- if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF ||
- current_print_settings_.format == PP_PRINTOUTPUTFORMAT_RASTER)
- PrintPDFOutput(print_output, metafile);
- // Now we need to release the print output resource.
- PluginModule::GetCore()->ReleaseResource(print_output);
-}
+ if (!ranges_.empty()) {
+ PP_Resource print_output = plugin_print_interface_->PrintPages(
+ pp_instance(), ranges_.data(), ranges_.size());
+ if (print_output) {
+ if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF ||
+ current_print_settings_.format == PP_PRINTOUTPUTFORMAT_RASTER) {
+ PrintPDFOutput(print_output, metafile_);
+ }
-void PepperPluginInstanceImpl::PrintEnd() {
- // Keep a reference on the stack. See NOTE above.
- scoped_refptr<PepperPluginInstanceImpl> ref(this);
- if (!ranges_.empty())
- PrintPageHelper(&(ranges_.front()), ranges_.size(), metafile_);
- metafile_ = nullptr;
- ranges_.clear();
+ // Now release the print output resource.
+ PluginModule::GetCore()->ReleaseResource(print_output);
+ }
- DCHECK(plugin_print_interface_);
- if (plugin_print_interface_)
- plugin_print_interface_->End(pp_instance());
+ ranges_.clear();
+ metafile_ = nullptr;
+ }
+ plugin_print_interface_->End(pp_instance());
memset(&current_print_settings_, 0, sizeof(current_print_settings_));
-#if defined(OS_MACOSX)
- last_printed_page_ = NULL;
-#endif // defined(OS_MACOSX)
}
bool PepperPluginInstanceImpl::GetPrintPresetOptionsFromDocument(
@@ -2011,7 +2023,7 @@ void PepperPluginInstanceImpl::RotateView(WebPlugin::RotationType type) {
}
bool PepperPluginInstanceImpl::FlashIsFullscreenOrPending() {
- return fullscreen_container_ != NULL;
+ return fullscreen_container_ != nullptr;
}
bool PepperPluginInstanceImpl::IsFullscreenOrPending() {
@@ -2095,33 +2107,9 @@ bool PepperPluginInstanceImpl::IsViewAccelerated() {
WebLocalFrame* frame = document.GetFrame();
if (!frame)
return false;
- WebView* view = frame->View();
- if (!view)
- return false;
-
- return view->IsAcceleratedCompositingActive();
-}
-bool PepperPluginInstanceImpl::PrintPDFOutput(
- PP_Resource print_output,
- printing::PdfMetafileSkia* metafile) {
-#if BUILDFLAG(ENABLE_PRINTING)
- ppapi::thunk::EnterResourceNoLock<PPB_Buffer_API> enter(print_output, true);
- if (enter.failed())
- return false;
-
- BufferAutoMapper mapper(enter.object());
- if (!mapper.data() || !mapper.size()) {
- NOTREACHED();
- return false;
- }
-
- if (metafile)
- return metafile->InitFromData(mapper.data(), mapper.size());
-
- NOTREACHED();
-#endif // ENABLE_PRINTING
- return false;
+ WebView* view = frame->View();
+ return view && view->IsAcceleratedCompositingActive();
}
void PepperPluginInstanceImpl::UpdateLayer(bool force_creation) {
@@ -2150,22 +2138,22 @@ void PepperPluginInstanceImpl::UpdateLayer(bool force_creation) {
if (texture_layer_ || compositor_layer_) {
if (!layer_bound_to_fullscreen_)
- container_->SetWebLayer(NULL);
+ container_->SetWebLayer(nullptr);
else if (fullscreen_container_)
- fullscreen_container_->SetLayer(NULL);
+ fullscreen_container_->SetLayer(nullptr);
web_layer_.reset();
if (texture_layer_) {
texture_layer_->ClearClient();
- texture_layer_ = NULL;
+ texture_layer_ = nullptr;
}
- compositor_layer_ = NULL;
+ compositor_layer_ = nullptr;
}
if (want_texture_layer) {
bool opaque = false;
if (want_3d_layer) {
DCHECK(bound_graphics_3d_.get());
- texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL);
+ texture_layer_ = cc::TextureLayer::CreateForMailbox(nullptr);
opaque = bound_graphics_3d_->IsOpaque();
PassCommittedTextureToTextureLayer();
@@ -2177,7 +2165,7 @@ void PepperPluginInstanceImpl::UpdateLayer(bool force_creation) {
texture_layer_->SetFlipped(false);
}
- auto layer = base::MakeUnique<cc_blink::WebLayerImpl>(texture_layer_);
+ auto layer = std::make_unique<cc_blink::WebLayerImpl>(texture_layer_);
// Ignore transparency in fullscreen, since that's what Flash always
// wants to do, and that lets it not recreate a context if
// wmode=transparent was specified.
@@ -2187,7 +2175,7 @@ void PepperPluginInstanceImpl::UpdateLayer(bool force_creation) {
web_layer_ = std::move(layer);
} else if (want_compositor_layer) {
compositor_layer_ = bound_compositor_->layer();
- web_layer_ = base::MakeUnique<cc_blink::WebLayerImpl>(compositor_layer_);
+ web_layer_ = std::make_unique<cc_blink::WebLayerImpl>(compositor_layer_);
}
if (web_layer_) {
@@ -2206,13 +2194,13 @@ void PepperPluginInstanceImpl::UpdateLayer(bool force_creation) {
UpdateLayerTransform();
}
-bool PepperPluginInstanceImpl::PrepareTextureMailbox(
- viz::TextureMailbox* mailbox,
+bool PepperPluginInstanceImpl::PrepareTransferableResource(
+ viz::TransferableResource* transferable_resource,
std::unique_ptr<viz::SingleReleaseCallback>* release_callback) {
if (!bound_graphics_2d_platform_)
return false;
- return bound_graphics_2d_platform_->PrepareTextureMailbox(mailbox,
- release_callback);
+ return bound_graphics_2d_platform_->PrepareTransferableResource(
+ transferable_resource, release_callback);
}
void PepperPluginInstanceImpl::AccessibilityModeChanged() {
@@ -2372,7 +2360,7 @@ PepperPluginInstanceImpl::GetContentDecryptorDelegate() {
if (!plugin_decryption_interface)
return nullptr;
- content_decryptor_delegate_ = base::MakeUnique<ContentDecryptorDelegate>(
+ content_decryptor_delegate_ = std::make_unique<ContentDecryptorDelegate>(
pp_instance_, plugin_decryption_interface);
return content_decryptor_delegate_.get();
}
@@ -2385,15 +2373,15 @@ PP_Bool PepperPluginInstanceImpl::BindGraphics(PP_Instance instance,
scoped_refptr<ppapi::Resource> old_graphics = bound_graphics_3d_.get();
if (bound_graphics_3d_.get()) {
bound_graphics_3d_->BindToInstance(false);
- bound_graphics_3d_ = NULL;
+ bound_graphics_3d_ = nullptr;
}
if (bound_graphics_2d_platform_) {
- bound_graphics_2d_platform_->BindToInstance(NULL);
- bound_graphics_2d_platform_ = NULL;
+ bound_graphics_2d_platform_->BindToInstance(nullptr);
+ bound_graphics_2d_platform_ = nullptr;
}
if (bound_compositor_) {
- bound_compositor_->BindToInstance(NULL);
- bound_compositor_ = NULL;
+ bound_compositor_->BindToInstance(nullptr);
+ bound_compositor_ = nullptr;
}
// Special-case clearing the current device.
@@ -2412,8 +2400,8 @@ PP_Bool PepperPluginInstanceImpl::BindGraphics(PP_Instance instance,
const ppapi::host::PpapiHost* ppapi_host =
RendererPpapiHost::GetForPPInstance(instance)->GetPpapiHost();
ppapi::host::ResourceHost* host = ppapi_host->GetResourceHost(device);
- PepperGraphics2DHost* graphics_2d = NULL;
- PepperCompositorHost* compositor = NULL;
+ PepperGraphics2DHost* graphics_2d = nullptr;
+ PepperCompositorHost* compositor = nullptr;
if (host) {
if (host->IsGraphics2DHost()) {
graphics_2d = static_cast<PepperGraphics2DHost*>(host);
@@ -2429,7 +2417,7 @@ PP_Bool PepperPluginInstanceImpl::BindGraphics(PP_Instance instance,
PPB_Graphics3D_Impl* graphics_3d =
enter_3d.succeeded()
? static_cast<PPB_Graphics3D_Impl*>(enter_3d.object())
- : NULL;
+ : nullptr;
if (compositor) {
if (compositor->BindToInstance(this)) {
@@ -2477,7 +2465,7 @@ PP_Var PepperPluginInstanceImpl::GetWindowObject(PP_Instance instance) {
if (!container_)
return PP_MakeUndefined();
V8VarConverter converter(pp_instance_, V8VarConverter::kAllowObjectVars);
- PepperTryCatchVar try_catch(this, &converter, NULL);
+ PepperTryCatchVar try_catch(this, &converter, nullptr);
WebLocalFrame* frame = container_->GetDocument().GetFrame();
if (!frame) {
try_catch.SetException("No frame exists for window object.");
@@ -2494,7 +2482,7 @@ PP_Var PepperPluginInstanceImpl::GetOwnerElementObject(PP_Instance instance) {
if (!container_)
return PP_MakeUndefined();
V8VarConverter converter(pp_instance_, V8VarConverter::kAllowObjectVars);
- PepperTryCatchVar try_catch(this, &converter, NULL);
+ PepperTryCatchVar try_catch(this, &converter, nullptr);
ScopedPPVar result = try_catch.FromV8(container_->V8ObjectForElement());
DCHECK(!try_catch.HasException());
return result.Release();
@@ -2551,24 +2539,24 @@ PP_Var PepperPluginInstanceImpl::ExecuteScript(PP_Instance instance,
uint32_t PepperPluginInstanceImpl::GetAudioHardwareOutputSampleRate(
PP_Instance instance) {
- return render_frame()
- ? AudioDeviceFactory::GetOutputDeviceInfo(
- render_frame()->GetRoutingID(), 0 /* session_id */,
- std::string() /* device_id */, url::Origin(document_url()))
- .output_params()
- .sample_rate()
- : 0;
+ return render_frame() ? AudioDeviceFactory::GetOutputDeviceInfo(
+ render_frame()->GetRoutingID(),
+ 0 /* session_id */, std::string() /* device_id */,
+ url::Origin::Create(document_url()))
+ .output_params()
+ .sample_rate()
+ : 0;
}
uint32_t PepperPluginInstanceImpl::GetAudioHardwareOutputBufferSize(
PP_Instance instance) {
- return render_frame()
- ? AudioDeviceFactory::GetOutputDeviceInfo(
- render_frame()->GetRoutingID(), 0 /* session_id */,
- std::string() /* device_id */, url::Origin(document_url()))
- .output_params()
- .frames_per_buffer()
- : 0;
+ return render_frame() ? AudioDeviceFactory::GetOutputDeviceInfo(
+ render_frame()->GetRoutingID(),
+ 0 /* session_id */, std::string() /* device_id */,
+ url::Origin::Create(document_url()))
+ .output_params()
+ .frames_per_buffer()
+ : 0;
}
PP_Var PepperPluginInstanceImpl::GetDefaultCharSet(PP_Instance instance) {
@@ -2753,7 +2741,7 @@ void PepperPluginInstanceImpl::SetTickmarks(PP_Instance instance,
tickmark.Scale(1 / viewport_to_dip_scale_);
tickmarks_converted[i] = blink::WebRect(gfx::ToEnclosedRect(tickmark));
}
- blink::WebLocalFrame* frame = render_frame_->GetWebFrame();
+ WebLocalFrame* frame = render_frame_->GetWebFrame();
frame->SetTickmarks(tickmarks_converted);
}
@@ -2803,7 +2791,7 @@ ppapi::Resource* PepperPluginInstanceImpl::GetSingletonResource(
case ppapi::PDF_SINGLETON_ID:
case ppapi::TRUETYPE_FONT_SINGLETON_ID:
NOTIMPLEMENTED();
- return NULL;
+ return nullptr;
case ppapi::GAMEPAD_SINGLETON_ID:
return gamepad_impl_.get();
case ppapi::UMA_SINGLETON_ID: {
@@ -2820,7 +2808,7 @@ ppapi::Resource* PepperPluginInstanceImpl::GetSingletonResource(
}
NOTREACHED();
- return NULL;
+ return nullptr;
}
int32_t PepperPluginInstanceImpl::RequestInputEvents(PP_Instance instance,
@@ -2860,7 +2848,7 @@ PP_Bool PepperPluginInstanceImpl::SetCursor(PP_Instance instance,
return PP_FALSE;
if (type != PP_MOUSECURSOR_TYPE_CUSTOM) {
- DoSetCursor(base::MakeUnique<WebCursorInfo>(
+ DoSetCursor(std::make_unique<WebCursorInfo>(
static_cast<WebCursorInfo::Type>(type)));
return PP_TRUE;
}
@@ -2876,7 +2864,7 @@ PP_Bool PepperPluginInstanceImpl::SetCursor(PP_Instance instance,
return PP_FALSE;
auto custom_cursor =
- base::MakeUnique<WebCursorInfo>(WebCursorInfo::kTypeCustom);
+ std::make_unique<WebCursorInfo>(WebCursorInfo::kTypeCustom);
custom_cursor->hot_spot.x = hot_spot->x;
custom_cursor->hot_spot.y = hot_spot->y;
@@ -3083,14 +3071,14 @@ PP_ExternalPluginResult PepperPluginInstanceImpl::ResetAsProxied(
instance_interface_.reset(ppp_instance_combined);
// Clear all PPP interfaces we may have cached.
- plugin_find_interface_ = NULL;
- plugin_input_event_interface_ = NULL;
+ plugin_find_interface_ = nullptr;
+ plugin_input_event_interface_ = nullptr;
checked_for_plugin_input_event_interface_ = false;
- plugin_mouse_lock_interface_ = NULL;
- plugin_pdf_interface_ = NULL;
+ plugin_mouse_lock_interface_ = nullptr;
+ plugin_pdf_interface_ = nullptr;
checked_for_plugin_pdf_interface_ = false;
- plugin_private_interface_ = NULL;
- plugin_textinput_interface_ = NULL;
+ plugin_private_interface_ = nullptr;
+ plugin_textinput_interface_ = nullptr;
// Re-send the DidCreate event via the proxy.
std::unique_ptr<const char* []> argn_array(StringVectorToArgArray(argn_));
@@ -3111,7 +3099,7 @@ PP_ExternalPluginResult PepperPluginInstanceImpl::ResetAsProxied(
DCHECK(external_document_load_);
external_document_load_ = false;
if (!external_document_response_.IsNull()) {
- document_loader_ = NULL;
+ document_loader_ = nullptr;
// Pass the response to the new proxy.
HandleDocumentLoad(external_document_response_);
external_document_response_ = blink::WebURLResponse();
@@ -3254,7 +3242,7 @@ bool PepperPluginInstanceImpl::FlashSetFullscreen(bool fullscreen,
} else {
DCHECK(fullscreen_container_);
fullscreen_container_->Destroy();
- fullscreen_container_ = NULL;
+ fullscreen_container_ = nullptr;
UpdateFlashFullscreenState(false);
if (!delay_report) {
ReportGeometry();
@@ -3434,7 +3422,7 @@ bool PepperPluginInstanceImpl::LockMouse() {
MouseLockDispatcher::LockTarget*
PepperPluginInstanceImpl::GetOrCreateLockTargetAdapter() {
if (!lock_target_)
- lock_target_ = base::MakeUnique<PluginInstanceLockTarget>(this);
+ lock_target_ = std::make_unique<PluginInstanceLockTarget>(this);
return lock_target_.get();
}
@@ -3508,14 +3496,14 @@ void PepperPluginInstanceImpl::ConvertDIPToViewport(gfx::Rect* rect) const {
}
void PepperPluginInstanceImpl::IncrementTextureReferenceCount(
- const viz::TextureMailbox& mailbox) {
+ const viz::TransferableResource& resource) {
auto it =
std::find_if(texture_ref_counts_.begin(), texture_ref_counts_.end(),
- [&mailbox](const TextureMailboxRefCount& ref_count) {
- return ref_count.first.mailbox() == mailbox.mailbox();
+ [&resource](const MailboxRefCount& ref_count) {
+ return ref_count.first == resource.mailbox_holder.mailbox;
});
if (it == texture_ref_counts_.end()) {
- texture_ref_counts_.push_back(std::make_pair(mailbox, 1));
+ texture_ref_counts_.emplace_back(resource.mailbox_holder.mailbox, 1);
return;
}
@@ -3523,11 +3511,11 @@ void PepperPluginInstanceImpl::IncrementTextureReferenceCount(
}
bool PepperPluginInstanceImpl::DecrementTextureReferenceCount(
- const viz::TextureMailbox& mailbox) {
+ const viz::TransferableResource& resource) {
auto it =
std::find_if(texture_ref_counts_.begin(), texture_ref_counts_.end(),
- [&mailbox](const TextureMailboxRefCount& ref_count) {
- return ref_count.first.mailbox() == mailbox.mailbox();
+ [&resource](const MailboxRefCount& ref_count) {
+ return ref_count.first == resource.mailbox_holder.mailbox;
});
DCHECK(it != texture_ref_counts_.end());
@@ -3541,11 +3529,11 @@ bool PepperPluginInstanceImpl::DecrementTextureReferenceCount(
}
bool PepperPluginInstanceImpl::IsTextureInUse(
- const viz::TextureMailbox& mailbox) const {
+ const viz::TransferableResource& resource) const {
auto it =
std::find_if(texture_ref_counts_.begin(), texture_ref_counts_.end(),
- [&mailbox](const TextureMailboxRefCount& ref_count) {
- return ref_count.first.mailbox() == mailbox.mailbox();
+ [&resource](const MailboxRefCount& ref_count) {
+ return ref_count.first == resource.mailbox_holder.mailbox;
});
return it != texture_ref_counts_.end();
}
diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h
index e2f29d927b2..5c3b02a7989 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h
+++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -25,7 +25,7 @@
#include "cc/layers/content_layer_client.h"
#include "cc/layers/layer.h"
#include "cc/layers/texture_layer_client.h"
-#include "components/viz/common/quads/texture_mailbox.h"
+#include "components/viz/common/resources/transferable_resource.h"
#include "content/common/content_export.h"
#include "content/public/renderer/pepper_plugin_instance.h"
#include "content/public/renderer/plugin_instance_throttler.h"
@@ -117,7 +117,6 @@ class PluginInstanceThrottlerImpl;
class PluginModule;
class PluginObject;
class PPB_Graphics3D_Impl;
-class PPB_ImageData_Impl;
class RenderFrameImpl;
// Represents one time a plugin appears on one web page.
@@ -201,15 +200,15 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// slow path can also be triggered if there is an overlapping frame.
void ScrollRect(int dx, int dy, const gfx::Rect& rect);
- // Commit the texture mailbox to the screen.
- void CommitTextureMailbox(const viz::TextureMailbox& texture_mailbox);
+ // Commit the output to the screen.
+ void CommitTransferableResource(const viz::TransferableResource& resource);
// Passes the committed texture to |texture_layer_| and marks it as in use.
void PassCommittedTextureToTextureLayer();
// Callback when the compositor is finished consuming the committed texture.
void FinishedConsumingCommittedTexture(
- const viz::TextureMailbox& texture_mailbox,
+ const viz::TransferableResource& resource,
scoped_refptr<PPB_Graphics3D_Impl> graphics_3d,
const gpu::SyncToken& sync_token,
bool is_lost);
@@ -559,8 +558,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
bool IsValidInstanceOf(PluginModule* module);
// cc::TextureLayerClient implementation.
- bool PrepareTextureMailbox(
- viz::TextureMailbox* mailbox,
+ bool PrepareTransferableResource(
+ viz::TransferableResource* transferable_resource,
std::unique_ptr<viz::SingleReleaseCallback>* release_callback) override;
// RenderFrameObserver
@@ -664,8 +663,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// print format that we can handle (we can handle only PDF).
bool GetPreferredPrintOutputFormat(PP_PrintOutputFormat_Dev* format,
const blink::WebPrintParams& params);
- bool PrintPDFOutput(PP_Resource print_output,
- printing::PdfMetafileSkia* metafile);
// Updates the layer for compositing. This creates a layer and attaches to the
// container if:
@@ -678,11 +675,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// to the container. Set to true if the bound device has been changed.
void UpdateLayer(bool force_creation);
- // Internal helper function for PrintPage().
- void PrintPageHelper(PP_PrintPageNumberRange_Dev* page_ranges,
- int num_ranges,
- printing::PdfMetafileSkia* metafile);
-
void DoSetCursor(std::unique_ptr<blink::WebCursorInfo> cursor);
// Internal helper functions for HandleCompositionXXX().
@@ -729,27 +721,27 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
void ConvertRectToDIP(PP_Rect* rect) const;
void ConvertDIPToViewport(gfx::Rect* rect) const;
- // Each time CommitTextureMailbox() is called, this instance is given
- // ownership
- // of a viz::TextureMailbox. This instance always needs to hold on to the most
- // recently committed viz::TextureMailbox, since UpdateLayer() might require
- // it.
- // Since it is possible for a viz::TextureMailbox to be passed to
- // texture_layer_ more than once, a reference counting mechanism is necessary
- // to ensure that a viz::TextureMailbox isn't returned until all copies of it
- // have been released by texture_layer_.
+ // Each time CommitTransferableResource() is called, this instance is given
+ // ownership of a texture and gpu::Mailbox. This instance always needs to hold
+ // on to the most recently committed texture, since UpdateLayer() might
+ // require it. Since it is possible for a gpu::Mailbox to be passed to
+ // |texture_layer_| more than once, a reference counting mechanism is
+ // necessary to ensure that a texture isn't returned until all copies of
+ // it have been released by texture_layer_.
//
- // This method should be called each time a viz::TextureMailbox is passed to
- // |texture_layer_|. It increments an internal reference count.
- void IncrementTextureReferenceCount(const viz::TextureMailbox& mailbox);
+ // This method should be called each time a viz::TransferableResource is
+ // passed to |texture_layer_|. It increments an internal reference count.
+ void IncrementTextureReferenceCount(
+ const viz::TransferableResource& resource);
// This method should be called each time |texture_layer_| finishes consuming
- // a viz::TextureMailbox. It decrements an internal reference count. Returns
- // whether the last reference was removed.
- bool DecrementTextureReferenceCount(const viz::TextureMailbox& mailbox);
+ // a viz::TransferableResource. It decrements an internal reference count.
+ // Returns whether the last reference was removed.
+ bool DecrementTextureReferenceCount(
+ const viz::TransferableResource& resource);
- // Whether a given viz::TextureMailbox is in use by |texture_layer_|.
- bool IsTextureInUse(const viz::TextureMailbox& mailbox) const;
+ // Whether a given viz::TransferableResource is in use by |texture_layer_|.
+ bool IsTextureInUse(const viz::TransferableResource& resource) const;
RenderFrameImpl* render_frame_;
scoped_refptr<PluginModule> module_;
@@ -843,21 +835,15 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// This is only valid between a successful PrintBegin call and a PrintEnd
// call.
PP_PrintSettings_Dev current_print_settings_;
-#if defined(OS_MACOSX)
- // On the Mac, when we draw the bitmap to the PDFContext, it seems necessary
- // to keep the pixels valid until CGContextEndPage is called. We use this
- // variable to hold on to the pixels.
- scoped_refptr<PPB_ImageData_Impl> last_printed_page_;
-#endif // defined(OS_MACOSX)
- // Always when printing to PDF on Linux and when printing for preview on Mac
- // and Win, the entire document goes into one metafile. However, when users
- // print only a subset of all the pages, it is impossible to know if a call
- // to PrintPage() is the last call. Thus in PrintPage(), just store the page
- // number in |ranges_|. The hack is in PrintEnd(), where a valid |metafile_|
- // is preserved in PrintWebFrameHelper::PrintPages. This makes it possible
- // to generate the entire PDF given the variables below:
+
+ // The entire document goes into one metafile. However, it is impossible to
+ // know if a call to PrintPage() is the last call. Thus in PrintPage(), just
+ // store the page number in |ranges_|. The hack is in PrintEnd(), where a
+ // valid |metafile_| is preserved in PrintWebFrameHelper::PrintPages(). This
+ // makes it possible to generate the entire PDF given the variables below:
//
- // The most recently used metafile_, guaranteed to be valid.
+ // The metafile to save into, which is guaranteed to be valid between a
+ // successful PrintBegin call and a PrintEnd call.
printing::PdfMetafileSkia* metafile_;
// An array of page ranges.
std::vector<PP_PrintPageNumberRange_Dev> ranges_;
@@ -976,7 +962,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// The most recently committed texture. This is kept around in case the layer
// needs to be regenerated.
- viz::TextureMailbox committed_texture_;
+ viz::TransferableResource committed_texture_;
// The Graphics3D that produced the most recently committed texture.
scoped_refptr<PPB_Graphics3D_Impl> committed_texture_graphics_3d_;
@@ -984,11 +970,11 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
gpu::SyncToken committed_texture_consumed_sync_token_;
// Holds the number of references |texture_layer_| has to any given
- // viz::TextureMailbox.
+ // gpu::Mailbox.
// We expect there to be no more than 10 textures in use at a time. A
// std::vector will have better performance than a std::map.
- using TextureMailboxRefCount = std::pair<viz::TextureMailbox, int>;
- std::vector<TextureMailboxRefCount> texture_ref_counts_;
+ using MailboxRefCount = std::pair<gpu::Mailbox, int>;
+ std::vector<MailboxRefCount> texture_ref_counts_;
bool initialized_;
diff --git a/chromium/content/renderer/pepper/pepper_plugin_registry.cc b/chromium/content/renderer/pepper/pepper_plugin_registry.cc
index e90972f637a..b91ba72ed35 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_registry.cc
+++ b/chromium/content/renderer/pepper/pepper_plugin_registry.cc
@@ -16,7 +16,7 @@ namespace content {
// static
PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
- static PepperPluginRegistry* registry = NULL;
+ static PepperPluginRegistry* registry = nullptr;
// This object leaks. It is a temporary hack to work around a crash.
// http://code.google.com/p/chromium/issues/detail?id=63234
if (!registry) {
@@ -48,7 +48,7 @@ const PepperPluginInfo* PepperPluginRegistry::GetInfoForPlugin(
PluginModule* PepperPluginRegistry::GetLiveModule(const base::FilePath& path) {
NonOwningModuleMap::iterator module_iter = live_modules_.find(path);
if (module_iter == live_modules_.end())
- return NULL;
+ return nullptr;
// Check the instances for the module to see if they've all been Delete()d.
// We don't want to return a PluginModule in that case, since the plugin may
@@ -68,7 +68,7 @@ PluginModule* PepperPluginRegistry::GetLiveModule(const base::FilePath& path) {
return module_iter->second;
++instance_iter;
}
- return NULL;
+ return nullptr;
}
void PepperPluginRegistry::AddLiveModule(const base::FilePath& path,
diff --git a/chromium/content/renderer/pepper/pepper_url_loader_host.cc b/chromium/content/renderer/pepper/pepper_url_loader_host.cc
index 6b2c548ebb5..9b01074f7e4 100644
--- a/chromium/content/renderer/pepper/pepper_url_loader_host.cc
+++ b/chromium/content/renderer/pepper/pepper_url_loader_host.cc
@@ -92,7 +92,7 @@ PepperURLLoaderHost::~PepperURLLoaderHost() {
renderer_ppapi_host_->GetPluginInstanceImpl(pp_instance());
if (instance_object) {
DCHECK(instance_object->document_loader() == this);
- instance_object->set_document_loader(NULL);
+ instance_object->set_document_loader(nullptr);
}
}
@@ -163,7 +163,7 @@ void PepperURLLoaderHost::DidReceiveData(const char* data, int data_length) {
bytes_received_ += data_length;
UpdateProgress();
- auto message = base::MakeUnique<PpapiPluginMsg_URLLoader_SendData>();
+ auto message = std::make_unique<PpapiPluginMsg_URLLoader_SendData>();
message->WriteData(data, data_length);
SendUpdateToPlugin(std::move(message));
}
@@ -171,27 +171,25 @@ void PepperURLLoaderHost::DidReceiveData(const char* data, int data_length) {
void PepperURLLoaderHost::DidFinishLoading(double finish_time) {
// Note that |loader| will be NULL for document loads.
SendUpdateToPlugin(
- base::MakeUnique<PpapiPluginMsg_URLLoader_FinishedLoading>(PP_OK));
+ std::make_unique<PpapiPluginMsg_URLLoader_FinishedLoading>(PP_OK));
}
void PepperURLLoaderHost::DidFail(const WebURLError& error) {
// Note that |loader| will be NULL for document loads.
int32_t pp_error = PP_ERROR_FAILED;
- if (error.domain == WebURLError::Domain::kNet) {
- // TODO(bbudge): Extend pp_errors.h to cover interesting network errors
- // from the net error domain.
- switch (error.reason) {
- case net::ERR_ACCESS_DENIED:
- case net::ERR_NETWORK_ACCESS_DENIED:
- pp_error = PP_ERROR_NOACCESS;
- break;
- }
+ // TODO(bbudge): Extend pp_errors.h to cover interesting network errors
+ // from the net error domain.
+ switch (error.reason()) {
+ case net::ERR_ACCESS_DENIED:
+ case net::ERR_NETWORK_ACCESS_DENIED:
+ pp_error = PP_ERROR_NOACCESS;
+ break;
}
- if (error.is_web_security_violation)
+ if (error.is_web_security_violation())
pp_error = PP_ERROR_NOACCESS;
SendUpdateToPlugin(
- base::MakeUnique<PpapiPluginMsg_URLLoader_FinishedLoading>(pp_error));
+ std::make_unique<PpapiPluginMsg_URLLoader_FinishedLoading>(pp_error));
}
void PepperURLLoaderHost::DidConnectPendingHostToResource() {
@@ -212,7 +210,7 @@ int32_t PepperURLLoaderHost::OnHostMsgOpen(
if (ret != PP_OK)
SendUpdateToPlugin(
- base::MakeUnique<PpapiPluginMsg_URLLoader_FinishedLoading>(ret));
+ std::make_unique<PpapiPluginMsg_URLLoader_FinishedLoading>(ret));
return PP_OK;
}
@@ -257,7 +255,8 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen(
}
web_request.SetRequestContext(WebURLRequest::kRequestContextPlugin);
- web_request.SetRequestorProcessID(renderer_ppapi_host_->GetPluginPID());
+ web_request.SetPluginChildID(renderer_ppapi_host_->GetPluginChildId());
+
// The requests from the plugins with private permission which can bypass same
// origin must skip the ServiceWorker.
web_request.SetServiceWorkerMode(
@@ -272,14 +271,14 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen(
if (filled_in_request_data.allow_cross_origin_requests) {
// Allow cross-origin requests with access control. The request specifies
// if credentials are to be sent.
- web_request.SetFetchRequestMode(WebURLRequest::kFetchRequestModeCORS);
+ web_request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCORS);
web_request.SetFetchCredentialsMode(
filled_in_request_data.allow_credentials
- ? WebURLRequest::kFetchCredentialsModeInclude
- : WebURLRequest::kFetchCredentialsModeOmit);
+ ? network::mojom::FetchCredentialsMode::kInclude
+ : network::mojom::FetchCredentialsMode::kOmit);
} else {
web_request.SetFetchRequestMode(
- WebURLRequest::kFetchRequestModeSameOrigin);
+ network::mojom::FetchRequestMode::kSameOrigin);
// Same-origin requests can always send credentials. Use the default
// credentials mode "include".
}
@@ -383,7 +382,7 @@ WebLocalFrame* PepperURLLoaderHost::GetFrame() {
static_cast<PepperPluginInstanceImpl*>(
renderer_ppapi_host_->GetPluginInstance(pp_instance()));
if (!instance_object || instance_object->is_deleted())
- return NULL;
+ return nullptr;
return instance_object->GetContainer()->GetDocument().GetFrame();
}
@@ -420,7 +419,7 @@ void PepperURLLoaderHost::SaveResponse(const WebURLResponse& response) {
void PepperURLLoaderHost::DidDataFromWebURLResponse(
const ppapi::URLResponseInfoData& data) {
SendUpdateToPlugin(
- base::MakeUnique<PpapiPluginMsg_URLLoader_ReceivedResponse>(data));
+ std::make_unique<PpapiPluginMsg_URLLoader_ReceivedResponse>(data));
}
void PepperURLLoaderHost::UpdateProgress() {
@@ -434,7 +433,7 @@ void PepperURLLoaderHost::UpdateProgress() {
// flag.
ppapi::proxy::ResourceMessageReplyParams params;
SendUpdateToPlugin(
- base::MakeUnique<PpapiPluginMsg_URLLoader_UpdateProgress>(
+ std::make_unique<PpapiPluginMsg_URLLoader_UpdateProgress>(
record_upload ? bytes_sent_ : -1,
record_upload ? total_bytes_to_be_sent_ : -1,
record_download ? bytes_received_ : -1,
diff --git a/chromium/content/renderer/pepper/pepper_video_capture_host.cc b/chromium/content/renderer/pepper/pepper_video_capture_host.cc
index 60cc0ea8f59..7e9f8c59932 100644
--- a/chromium/content/renderer/pepper/pepper_video_capture_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_capture_host.cc
@@ -408,8 +408,7 @@ bool PepperVideoCaptureHost::SetStatus(PP_VideoCaptureStatus_Dev status,
}
PepperVideoCaptureHost::BufferInfo::BufferInfo()
- : in_use(false), data(NULL), buffer() {
-}
+ : in_use(false), data(nullptr), buffer() {}
PepperVideoCaptureHost::BufferInfo::BufferInfo(const BufferInfo& other) =
default;
diff --git a/chromium/content/renderer/pepper/pepper_video_destination_host.cc b/chromium/content/renderer/pepper/pepper_video_destination_host.cc
index 3f682db8ab0..aa3567d20c6 100644
--- a/chromium/content/renderer/pepper/pepper_video_destination_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_destination_host.cc
@@ -52,9 +52,9 @@ int32_t PepperVideoDestinationHost::OnHostMsgOpen(
if (!gurl.is_valid())
return PP_ERROR_BADARGUMENT;
- FrameWriterInterface* frame_writer = NULL;
- if (!PepperToVideoTrackAdapter::Open(
- NULL /* registry */, gurl.spec(), &frame_writer))
+ FrameWriterInterface* frame_writer = nullptr;
+ if (!PepperToVideoTrackAdapter::Open(nullptr /* registry */, gurl.spec(),
+ &frame_writer))
return PP_ERROR_FAILED;
frame_writer_.reset(frame_writer);
@@ -101,7 +101,7 @@ int32_t PepperVideoDestinationHost::OnHostMsgPutFrame(
int32_t PepperVideoDestinationHost::OnHostMsgClose(
HostMessageContext* context) {
- frame_writer_.reset(NULL);
+ frame_writer_.reset(nullptr);
return PP_OK;
}
diff --git a/chromium/content/renderer/pepper/pepper_video_encoder_host.cc b/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
index a9c7fe16855..9381551e2c1 100644
--- a/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
@@ -404,7 +404,7 @@ void PepperVideoEncoderHost::RequireBitstreamBuffers(
break;
}
- shm_buffers_.push_back(base::MakeUnique<ShmBuffer>(i, std::move(shm)));
+ shm_buffers_.push_back(std::make_unique<ShmBuffer>(i, std::move(shm)));
}
// Feed buffers to the encoder.
@@ -530,11 +530,13 @@ bool PepperVideoEncoderHost::EnsureGpuChannel() {
if (!channel)
return false;
- command_buffer_ = gpu::CommandBufferProxyImpl::Create(
- std::move(channel), gpu::kNullSurfaceHandle, nullptr, kGpuStreamIdDefault,
- kGpuStreamPriorityDefault, gpu::gles2::ContextCreationAttribHelper(),
- GURL::EmptyGURL(), base::ThreadTaskRunnerHandle::Get());
- if (!command_buffer_) {
+ command_buffer_ = std::make_unique<gpu::CommandBufferProxyImpl>(
+ std::move(channel), kGpuStreamIdDefault,
+ base::ThreadTaskRunnerHandle::Get());
+ auto result = command_buffer_->Initialize(
+ gpu::kNullSurfaceHandle, nullptr, kGpuStreamPriorityDefault,
+ gpu::gles2::ContextCreationAttribHelper(), GURL::EmptyGURL());
+ if (result != gpu::ContextResult::kSuccess) {
Close();
return false;
}
diff --git a/chromium/content/renderer/pepper/pepper_video_source_host.cc b/chromium/content/renderer/pepper/pepper_video_source_host.cc
index 0e564b3b520..ea38aa9a54c 100644
--- a/chromium/content/renderer/pepper/pepper_video_source_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_source_host.cc
@@ -176,7 +176,7 @@ void PepperVideoSourceHost::SendGetFrameReply() {
dispatcher->ShareSharedMemoryHandleWithRemote(local_shm->handle());
} else {
// We need to allocate new shared memory.
- shared_image_ = NULL; // Release any previous image.
+ shared_image_ = nullptr; // Release any previous image.
ppapi::ScopedPPResource resource(
ppapi::ScopedPPResource::PassRef(),
@@ -209,7 +209,7 @@ void PepperVideoSourceHost::SendGetFrameReply() {
DCHECK(!shared_image_->IsMapped()); // New memory should not be mapped.
if (!shared_image_->Map() || shared_image_->GetMappedBitmap().empty()) {
- shared_image_ = NULL;
+ shared_image_ = nullptr;
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
}
@@ -236,7 +236,7 @@ void PepperVideoSourceHost::SendGetFrameReply() {
frame = last_frame_;
// Frame resolution doesn't change frequently, so don't keep any unnecessary
// buffers around.
- scaled_frame_ = NULL;
+ scaled_frame_ = nullptr;
} else {
// We need to create an intermediate scaled frame. Make sure we have
// allocated one of correct size.
@@ -270,7 +270,7 @@ void PepperVideoSourceHost::SendGetFrameReply() {
libyuv::kFilterBilinear);
frame = scaled_frame_;
}
- last_frame_ = NULL;
+ last_frame_ = nullptr;
libyuv::I420ToARGB(frame->visible_data(media::VideoFrame::kYPlane),
frame->stride(media::VideoFrame::kYPlane),
@@ -313,10 +313,10 @@ void PepperVideoSourceHost::Close() {
if (frame_source_.get() && !stream_url_.empty())
frame_source_->Close(frame_receiver_.get());
- frame_source_.reset(NULL);
+ frame_source_.reset(nullptr);
stream_url_.clear();
- shared_image_ = NULL;
+ shared_image_ = nullptr;
}
} // namespace content
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 de30148efd7..2f04d788823 100644
--- a/chromium/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc
+++ b/chromium/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc
@@ -43,7 +43,8 @@ class PluginInstanceThrottlerImplTest
void SetUp() override {
throttler_.reset(
new PluginInstanceThrottlerImpl(RenderFrame::DONT_RECORD_DECISION));
- throttler_->Initialize(nullptr, url::Origin(GURL("http://example.com")),
+ throttler_->Initialize(nullptr,
+ url::Origin::Create(GURL("http://example.com")),
"Shockwave Flash", gfx::Size(100, 100));
throttler_->AddObserver(this);
}
diff --git a/chromium/content/renderer/pepper/plugin_module.cc b/chromium/content/renderer/pepper/plugin_module.cc
index 1c05507a93a..0cb3d60459f 100644
--- a/chromium/content/renderer/pepper/plugin_module.cc
+++ b/chromium/content/renderer/pepper/plugin_module.cc
@@ -172,7 +172,7 @@ namespace {
// TODO(raymes): I'm not sure if it is completely necessary to leak the
// HostGlobals. Figure out the shutdown sequence and find a way to do this
// more elegantly.
-HostGlobals* host_globals = NULL;
+HostGlobals* host_globals = nullptr;
// Maintains all currently loaded plugin libs for validating PP_Module
// identifiers.
@@ -297,9 +297,7 @@ PP_Bool ReadImageData(PP_Resource device_context_2d,
}
void RunMessageLoop(PP_Instance instance) {
- base::MessageLoop::ScopedNestableTaskAllower allow(
- base::MessageLoop::current());
- base::RunLoop().Run();
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).Run();
}
void QuitMessageLoop(PP_Instance instance) {
@@ -430,7 +428,7 @@ const void* InternalGetInterface(const char* name) {
if (strcmp(name, PPB_TESTING_PRIVATE_INTERFACE) == 0)
return &testing_interface;
}
- return NULL;
+ return nullptr;
}
const void* GetInterface(const char* name) {
@@ -499,13 +497,13 @@ PluginModule::PluginModule(const std::string& name,
: callback_tracker_(new ppapi::CallbackTracker),
is_in_destructor_(false),
is_crashed_(false),
- broker_(NULL),
- library_(NULL),
+ broker_(nullptr),
+ library_(nullptr),
name_(name),
version_(version),
path_(path),
permissions_(ppapi::PpapiPermissions::GetForCommandLine(perms.GetBits())),
- reserve_instance_id_(NULL) {
+ reserve_instance_id_(nullptr) {
// Ensure the globals object is created.
if (!host_globals)
host_globals = new HostGlobals;
@@ -568,7 +566,7 @@ bool PluginModule::InitAsInternalPlugin(
}
bool PluginModule::InitAsLibrary(const base::FilePath& path) {
- base::NativeLibrary library = base::LoadNativeLibrary(path, NULL);
+ base::NativeLibrary library = base::LoadNativeLibrary(path, nullptr);
if (!library)
return false;
@@ -643,7 +641,7 @@ PepperPluginInstanceImpl* PluginModule::CreateInstance(
render_frame, this, container, plugin_url);
if (!instance) {
LOG(WARNING) << "Plugin doesn't support instance interface, failing.";
- return NULL;
+ return nullptr;
}
if (host_dispatcher_wrapper_)
host_dispatcher_wrapper_->AddInstance(instance->pp_instance());
@@ -663,7 +661,7 @@ const void* PluginModule::GetPluginInterface(const char* name) const {
// In-process plugins.
if (!entry_points_.get_interface)
- return NULL;
+ return nullptr;
return entry_points_.get_interface(name);
}
@@ -756,13 +754,13 @@ RendererPpapiHostImpl* PluginModule::CreateOutOfProcessModule(
// static
void PluginModule::ResetHostGlobalsForTest() {
delete host_globals;
- host_globals = NULL;
+ host_globals = nullptr;
}
bool PluginModule::InitializeModule(
const PepperPluginInfo::EntryPoints& entry_points) {
DCHECK(!host_dispatcher_wrapper_.get()) << "Don't call for proxied modules.";
- DCHECK(entry_points.initialize_module != NULL);
+ DCHECK(entry_points.initialize_module != nullptr);
int retval = entry_points.initialize_module(pp_module(), &GetInterface);
if (retval != 0) {
#if BUILDFLAG(ENABLE_NACL)
diff --git a/chromium/content/renderer/pepper/plugin_object.cc b/chromium/content/renderer/pepper/plugin_object.cc
index 1cc915afdc5..98d8a2257e0 100644
--- a/chromium/content/renderer/pepper/plugin_object.cc
+++ b/chromium/content/renderer/pepper/plugin_object.cc
@@ -67,7 +67,7 @@ PluginObject* PluginObject::FromV8Object(v8::Isolate* isolate,
gin::ConvertFromV8(isolate, v8_object, &plugin_object)) {
return plugin_object;
}
- return NULL;
+ return nullptr;
}
// static
@@ -76,7 +76,7 @@ PP_Var PluginObject::Create(PepperPluginInstanceImpl* instance,
void* ppp_class_data) {
V8VarConverter var_converter(instance->pp_instance(),
V8VarConverter::kAllowObjectVars);
- PepperTryCatchVar try_catch(instance, &var_converter, NULL);
+ PepperTryCatchVar try_catch(instance, &var_converter, nullptr);
// If the V8 context is empty, we may be in the process of tearing down the
// frame and may not have a valid isolate (in particular due to re-entrancy).
// We shouldn't try to call gin::CreateHandle.
@@ -183,7 +183,7 @@ std::vector<std::string> PluginObject::EnumerateNamedProperties(
}
void PluginObject::InstanceDeleted() {
- instance_ = NULL;
+ instance_ = nullptr;
}
PluginObject::PluginObject(PepperPluginInstanceImpl* instance,
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 91a2df58a4e..2475fcf66fe 100644
--- a/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
+++ b/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
@@ -26,7 +26,7 @@ namespace content {
class PluginPowerSaverHelperTest : public RenderViewTest {
public:
- PluginPowerSaverHelperTest() : sink_(NULL) {}
+ PluginPowerSaverHelperTest() : sink_(nullptr) {}
void SetUp() override {
RenderViewTest::SetUp();
@@ -46,20 +46,21 @@ class PluginPowerSaverHelperTest : public RenderViewTest {
TEST_F(PluginPowerSaverHelperTest, TemporaryOriginWhitelist) {
EXPECT_EQ(RenderFrame::CONTENT_STATUS_PERIPHERAL,
frame()->GetPeripheralContentStatus(
- url::Origin(GURL("http://same.com")),
- url::Origin(GURL("http://other.com")), gfx::Size(100, 100),
- RenderFrame::DONT_RECORD_DECISION));
+ url::Origin::Create(GURL("http://same.com")),
+ url::Origin::Create(GURL("http://other.com")),
+ gfx::Size(100, 100), RenderFrame::DONT_RECORD_DECISION));
// Clear out other messages so we find just the plugin power saver IPCs.
sink_->ClearMessages();
- frame()->WhitelistContentOrigin(url::Origin(GURL("http://other.com")));
+ frame()->WhitelistContentOrigin(
+ url::Origin::Create(GURL("http://other.com")));
EXPECT_EQ(RenderFrame::CONTENT_STATUS_ESSENTIAL_CROSS_ORIGIN_WHITELISTED,
frame()->GetPeripheralContentStatus(
- url::Origin(GURL("http://same.com")),
- url::Origin(GURL("http://other.com")), gfx::Size(100, 100),
- RenderFrame::DONT_RECORD_DECISION));
+ url::Origin::Create(GURL("http://same.com")),
+ url::Origin::Create(GURL("http://other.com")),
+ gfx::Size(100, 100), RenderFrame::DONT_RECORD_DECISION));
// Test that we've sent an IPC to the browser.
ASSERT_EQ(1u, sink_->message_count());
@@ -67,17 +68,17 @@ TEST_F(PluginPowerSaverHelperTest, TemporaryOriginWhitelist) {
EXPECT_EQ(FrameHostMsg_PluginContentOriginAllowed::ID, msg->type());
FrameHostMsg_PluginContentOriginAllowed::Param params;
FrameHostMsg_PluginContentOriginAllowed::Read(msg, &params);
- EXPECT_TRUE(url::Origin(GURL("http://other.com"))
+ EXPECT_TRUE(url::Origin::Create(GURL("http://other.com"))
.IsSameOriginWith(std::get<0>(params)));
}
TEST_F(PluginPowerSaverHelperTest, UnthrottleOnExPostFactoWhitelist) {
base::RunLoop loop;
- frame()->RegisterPeripheralPlugin(url::Origin(GURL("http://other.com")),
- loop.QuitClosure());
+ frame()->RegisterPeripheralPlugin(
+ url::Origin::Create(GURL("http://other.com")), loop.QuitClosure());
std::set<url::Origin> origin_whitelist;
- origin_whitelist.insert(url::Origin(GURL("http://other.com")));
+ origin_whitelist.insert(url::Origin::Create(GURL("http://other.com")));
frame()->OnMessageReceived(FrameMsg_UpdatePluginContentOriginWhitelist(
frame()->GetRoutingID(), origin_whitelist));
@@ -86,21 +87,22 @@ TEST_F(PluginPowerSaverHelperTest, UnthrottleOnExPostFactoWhitelist) {
}
TEST_F(PluginPowerSaverHelperTest, ClearWhitelistOnNavigate) {
- frame()->WhitelistContentOrigin(url::Origin(GURL("http://other.com")));
+ frame()->WhitelistContentOrigin(
+ url::Origin::Create(GURL("http://other.com")));
EXPECT_EQ(RenderFrame::CONTENT_STATUS_ESSENTIAL_CROSS_ORIGIN_WHITELISTED,
frame()->GetPeripheralContentStatus(
- url::Origin(GURL("http://same.com")),
- url::Origin(GURL("http://other.com")), gfx::Size(100, 100),
- RenderFrame::DONT_RECORD_DECISION));
+ url::Origin::Create(GURL("http://same.com")),
+ url::Origin::Create(GURL("http://other.com")),
+ gfx::Size(100, 100), RenderFrame::DONT_RECORD_DECISION));
LoadHTML("<html></html>");
EXPECT_EQ(RenderFrame::CONTENT_STATUS_PERIPHERAL,
frame()->GetPeripheralContentStatus(
- url::Origin(GURL("http://same.com")),
- url::Origin(GURL("http://other.com")), gfx::Size(100, 100),
- RenderFrame::DONT_RECORD_DECISION));
+ url::Origin::Create(GURL("http://same.com")),
+ url::Origin::Create(GURL("http://other.com")),
+ gfx::Size(100, 100), RenderFrame::DONT_RECORD_DECISION));
}
} // namespace content
diff --git a/chromium/content/renderer/pepper/ppb_audio_impl.cc b/chromium/content/renderer/pepper/ppb_audio_impl.cc
index 43426b5b5fa..21d939262aa 100644
--- a/chromium/content/renderer/pepper/ppb_audio_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_audio_impl.cc
@@ -31,7 +31,7 @@ namespace content {
PPB_Audio_Impl::PPB_Audio_Impl(PP_Instance instance)
: Resource(ppapi::OBJECT_IS_IMPL, instance),
- audio_(NULL),
+ audio_(nullptr),
playback_throttled_(false) {
PepperPluginInstanceImpl* plugin_instance =
static_cast<PepperPluginInstanceImpl*>(
@@ -58,7 +58,7 @@ PPB_Audio_Impl::~PPB_Audio_Impl() {
// destructor.
if (audio_) {
audio_->ShutDown();
- audio_ = NULL;
+ audio_ = nullptr;
}
}
diff --git a/chromium/content/renderer/pepper/ppb_broker_impl.cc b/chromium/content/renderer/pepper/ppb_broker_impl.cc
index d80c0611aa6..c5d8a5bf248 100644
--- a/chromium/content/renderer/pepper/ppb_broker_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_broker_impl.cc
@@ -5,6 +5,7 @@
#include "content/renderer/pepper/ppb_broker_impl.h"
#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
#include "content/renderer/pepper/host_globals.h"
@@ -24,21 +25,26 @@ using ppapi::TrackedCallback;
namespace content {
+enum class PepperBrokerAction { CREATE = 0, CONNECT = 1, NUM };
+
// PPB_Broker_Impl ------------------------------------------------------
PPB_Broker_Impl::PPB_Broker_Impl(PP_Instance instance)
: Resource(ppapi::OBJECT_IS_IMPL, instance),
- broker_(NULL),
+ broker_(nullptr),
connect_callback_(),
pipe_handle_(PlatformFileToInt(base::SyncSocket::kInvalidHandle)),
routing_id_(RenderThreadImpl::current()->GenerateRoutingID()) {
ChildThreadImpl::current()->GetRouter()->AddRoute(routing_id_, this);
+
+ UMA_HISTOGRAM_ENUMERATION("Pepper.BrokerAction", PepperBrokerAction::CREATE,
+ PepperBrokerAction::NUM);
}
PPB_Broker_Impl::~PPB_Broker_Impl() {
if (broker_) {
broker_->Disconnect(this);
- broker_ = NULL;
+ broker_ = nullptr;
}
// The plugin owns the handle.
@@ -52,6 +58,9 @@ int32_t PPB_Broker_Impl::Connect(
scoped_refptr<TrackedCallback> connect_callback) {
// TODO(ddorwin): Return PP_ERROR_FAILED if plugin is in-process.
+ UMA_HISTOGRAM_ENUMERATION("Pepper.BrokerAction", PepperBrokerAction::CONNECT,
+ PepperBrokerAction::NUM);
+
if (broker_) {
// May only be called once.
return PP_ERROR_FAILED;
diff --git a/chromium/content/renderer/pepper/ppb_buffer_impl.cc b/chromium/content/renderer/pepper/ppb_buffer_impl.cc
index 5bec0da4b0b..3da947a5102 100644
--- a/chromium/content/renderer/pepper/ppb_buffer_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_buffer_impl.cc
@@ -53,7 +53,7 @@ bool PPB_Buffer_Impl::Init(uint32_t size) {
size_ = size;
shared_memory_.reset(
RenderThread::Get()->HostAllocateSharedMemoryBuffer(size).release());
- return shared_memory_.get() != NULL;
+ return shared_memory_.get() != nullptr;
}
PP_Bool PPB_Buffer_Impl::Describe(uint32_t* size_in_bytes) {
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 c3a2872efcf..3de9ec4dff3 100644
--- a/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc
@@ -87,11 +87,9 @@ int32_t PPB_Flash_MessageLoop_Impl::InternalRun(
// destroyed when the nested run loop exits.
scoped_refptr<State> state_protector(state_);
{
- base::MessageLoop::ScopedNestableTaskAllower allow(
- base::MessageLoop::current());
blink::WebView::WillEnterModalLoop();
- base::RunLoop().Run();
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).Run();
blink::WebView::DidExitModalLoop();
}
diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
index 040fa5e4f45..f59d98050bf 100644
--- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -70,7 +70,7 @@ PP_Resource PPB_Graphics3D_Impl::CreateRaw(
gpu::Capabilities* capabilities,
base::SharedMemoryHandle* shared_state_handle,
gpu::CommandBufferId* command_buffer_id) {
- PPB_Graphics3D_API* share_api = NULL;
+ PPB_Graphics3D_API* share_api = nullptr;
if (share_context) {
EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
if (enter.failed())
@@ -185,19 +185,20 @@ int32_t PPB_Graphics3D_Impl::DoSwapBuffers(const gpu::SyncToken& sync_token,
// Don't need to check for NULL from GetPluginInstance since when we're
// bound, we know our instance is valid.
bool is_overlay_candidate = use_image_chromium_;
- viz::TextureMailbox texture_mailbox(
- taken_front_buffer_, sync_token,
-// TODO(reveman): Get texture target from browser process.
+ // TODO(reveman): Get texture target from browser process.
+ uint32_t target = GL_TEXTURE_2D;
#if defined(OS_MACOSX)
- use_image_chromium_ ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D,
-#else
- GL_TEXTURE_2D,
+ if (use_image_chromium_)
+ target = GL_TEXTURE_RECTANGLE_ARB;
#endif
- size, is_overlay_candidate);
+ viz::TransferableResource resource =
+ viz::TransferableResource::MakeGLOverlay(taken_front_buffer_, GL_LINEAR,
+ target, sync_token, size,
+ is_overlay_candidate);
taken_front_buffer_.SetZero();
HostGlobals::Get()
->GetInstance(pp_instance())
- ->CommitTextureMailbox(texture_mailbox);
+ ->CommitTransferableResource(resource);
commit_pending_ = true;
} else {
// Wait for the command to complete on the GPU to allow for throttling.
@@ -238,6 +239,8 @@ bool PPB_Graphics3D_Impl::InitRaw(
RenderThreadImpl* render_thread = RenderThreadImpl::current();
if (!render_thread)
return false;
+ if (render_thread->IsGpuCompositingDisabled())
+ return false;
scoped_refptr<gpu::GpuChannelHost> channel =
render_thread->EstablishGpuChannelSync();
@@ -256,7 +259,7 @@ bool PPB_Graphics3D_Impl::InitRaw(
attrib_helper.should_use_native_gmb_for_backbuffer = use_image_chromium_;
attrib_helper.context_type = gpu::gles2::CONTEXT_TYPE_OPENGLES2;
- gpu::CommandBufferProxyImpl* share_buffer = NULL;
+ gpu::CommandBufferProxyImpl* share_buffer = nullptr;
if (!plugin_instance->is_flash_plugin())
UMA_HISTOGRAM_BOOLEAN("Pepper.Graphics3DHasShareGroup", !!share_context);
if (share_context) {
@@ -265,11 +268,13 @@ bool PPB_Graphics3D_Impl::InitRaw(
share_buffer = share_graphics->GetCommandBufferProxy();
}
- command_buffer_ = gpu::CommandBufferProxyImpl::Create(
- std::move(channel), gpu::kNullSurfaceHandle, share_buffer,
- kGpuStreamIdDefault, kGpuStreamPriorityDefault, attrib_helper,
- GURL::EmptyGURL(), base::ThreadTaskRunnerHandle::Get());
- if (!command_buffer_)
+ command_buffer_ = std::make_unique<gpu::CommandBufferProxyImpl>(
+ std::move(channel), kGpuStreamIdDefault,
+ base::ThreadTaskRunnerHandle::Get());
+ auto result = command_buffer_->Initialize(
+ gpu::kNullSurfaceHandle, share_buffer, kGpuStreamPriorityDefault,
+ attrib_helper, GURL::EmptyGURL());
+ if (result != gpu::ContextResult::kSuccess)
return false;
command_buffer_->SetGpuControlClient(this);
diff --git a/chromium/content/renderer/pepper/ppb_image_data_impl.cc b/chromium/content/renderer/pepper/ppb_image_data_impl.cc
index d17f087b7cb..bb355c0888a 100644
--- a/chromium/content/renderer/pepper/ppb_image_data_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_image_data_impl.cc
@@ -171,7 +171,7 @@ void* ImageDataPlatformBackend::Map() {
const bool is_opaque = false;
mapped_canvas_ = dib_->GetPlatformCanvas(width_, height_, is_opaque);
if (!mapped_canvas_)
- return NULL;
+ return nullptr;
}
SkPixmap pixmap;
skia::GetWritablePixels(mapped_canvas_.get(), &pixmap);
@@ -234,7 +234,9 @@ bool ImageDataSimpleBackend::Init(PPB_ImageData_Impl* impl,
bool ImageDataSimpleBackend::IsMapped() const { return map_count_ > 0; }
-TransportDIB* ImageDataSimpleBackend::GetTransportDIB() const { return NULL; }
+TransportDIB* ImageDataSimpleBackend::GetTransportDIB() const {
+ return nullptr;
+}
void* ImageDataSimpleBackend::Map() {
DCHECK(shared_memory_.get());
@@ -243,7 +245,7 @@ void* ImageDataSimpleBackend::Map() {
skia_bitmap_.setPixels(shared_memory_->memory());
// Our platform bitmaps are set to opaque by default, which we don't want.
skia_bitmap_.setAlphaType(kPremul_SkAlphaType);
- skia_canvas_ = base::MakeUnique<SkCanvas>(skia_bitmap_);
+ skia_canvas_ = std::make_unique<SkCanvas>(skia_bitmap_);
return skia_bitmap_.getAddr32(0, 0);
}
return shared_memory_->memory();
@@ -263,7 +265,7 @@ int32_t ImageDataSimpleBackend::GetSharedMemory(base::SharedMemory** shm,
SkCanvas* ImageDataSimpleBackend::GetCanvas() {
if (!IsMapped())
- return NULL;
+ return nullptr;
return skia_canvas_.get();
}
diff --git a/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc b/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc
index aa773472b0e..fd73dae1d91 100644
--- a/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc
@@ -44,7 +44,7 @@ class ObjectAccessor {
public:
ObjectAccessor(PP_Var var)
: object_var_(V8ObjectVar::FromPPVar(var).get()),
- instance_(object_var_ ? object_var_->instance() : NULL) {
+ instance_(object_var_ ? object_var_->instance() : nullptr) {
if (instance_) {
converter_.reset(new V8VarConverter(instance_->pp_instance(),
V8VarConverter::kAllowObjectVars));
@@ -151,7 +151,7 @@ void EnumerateProperties(PP_Var var,
PepperTryCatchVar try_catch(accessor.instance(), accessor.converter(),
exception);
- *properties = NULL;
+ *properties = nullptr;
*property_count = 0;
v8::Local<v8::Array> identifiers = accessor.GetObject()->GetPropertyNames();
@@ -261,7 +261,7 @@ PP_Var CallDeprecatedInternal(PP_Var var,
}
blink::WebPluginContainer* container = accessor.instance()->container();
- blink::WebLocalFrame* frame = NULL;
+ blink::WebLocalFrame* frame = nullptr;
if (container)
frame = container->GetDocument().GetFrame();
diff --git a/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc b/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc
index 311ae6febfa..3437b190f03 100644
--- a/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc
@@ -94,8 +94,7 @@ PP_VideoDecodeError_Dev MediaToPPError(
namespace content {
PPB_VideoDecoder_Impl::PPB_VideoDecoder_Impl(PP_Instance instance)
- : PPB_VideoDecoder_Shared(instance), ppp_videodecoder_(NULL) {
-}
+ : PPB_VideoDecoder_Shared(instance), ppp_videodecoder_(nullptr) {}
PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() { Destroy(); }
@@ -235,7 +234,7 @@ void PPB_VideoDecoder_Impl::Destroy() {
FlushCommandBuffer();
decoder_.reset();
- ppp_videodecoder_ = NULL;
+ ppp_videodecoder_ = nullptr;
::ppapi::PPB_VideoDecoder_Shared::Destroy();
}
diff --git a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc
index 68d029bdeec..952ba132e6f 100644
--- a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc
+++ b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc
@@ -59,7 +59,7 @@ RendererPpapiHostImpl::RendererPpapiHostImpl(
RendererPpapiHostImpl::RendererPpapiHostImpl(
PluginModule* module,
const ppapi::PpapiPermissions& permissions)
- : module_(module), dispatcher_(NULL), is_external_plugin_host_(false) {
+ : module_(module), dispatcher_(nullptr), is_external_plugin_host_(false) {
// Hook the host up to the in-process router.
in_process_router_.reset(new PepperInProcessRouter(this));
ppapi_host_.reset(new ppapi::host::PpapiHost(
@@ -111,7 +111,7 @@ RendererPpapiHostImpl* RendererPpapiHostImpl::GetForPPInstance(
PepperPluginInstanceImpl* instance =
HostGlobals::Get()->GetInstance(pp_instance);
if (!instance)
- return NULL;
+ return nullptr;
// All modules created by content will have their embedder state be the
// host impl.
@@ -142,7 +142,7 @@ RenderFrame* RendererPpapiHostImpl::GetRenderFrameForInstance(
PP_Instance instance) const {
PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
if (!instance_object)
- return NULL;
+ return nullptr;
// Since we're the embedder, we can make assumptions about the helper on
// the instance and get back to our RenderFrame.
@@ -153,7 +153,7 @@ RenderView* RendererPpapiHostImpl::GetRenderViewForInstance(
PP_Instance instance) const {
PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
if (!instance_object)
- return NULL;
+ return nullptr;
// Since we're the embedder, we can make assumptions about the helper on
// the instance and get back to our RenderView.
@@ -173,16 +173,10 @@ blink::WebPluginContainer* RendererPpapiHostImpl::GetContainerForInstance(
PP_Instance instance) const {
PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
if (!instance_object)
- return NULL;
+ return nullptr;
return instance_object->container();
}
-base::ProcessId RendererPpapiHostImpl::GetPluginPID() const {
- if (dispatcher_)
- return dispatcher_->peer_pid();
- return base::kNullProcessId;
-}
-
bool RendererPpapiHostImpl::HasUserGesture(PP_Instance instance) const {
PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
if (!instance_object)
@@ -287,14 +281,18 @@ bool RendererPpapiHostImpl::IsSecureContext(PP_Instance pp_instance) const {
content::IsOriginSecure(instance->GetPluginURL());
}
+int RendererPpapiHostImpl::GetPluginChildId() const {
+ return module_->GetPluginChildId();
+}
+
PepperPluginInstanceImpl* RendererPpapiHostImpl::GetAndValidateInstance(
PP_Instance pp_instance) const {
PepperPluginInstanceImpl* instance =
HostGlobals::Get()->GetInstance(pp_instance);
if (!instance)
- return NULL;
+ return nullptr;
if (!instance->IsValidInstanceOf(module_))
- return NULL;
+ return nullptr;
return instance;
}
diff --git a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h
index e87ba2a0764..d8d6eddaf93 100644
--- a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h
+++ b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h
@@ -80,7 +80,6 @@ class RendererPpapiHostImpl : public RendererPpapiHost {
RenderView* GetRenderViewForInstance(PP_Instance instance) const override;
blink::WebPluginContainer* GetContainerForInstance(
PP_Instance instance) const override;
- base::ProcessId GetPluginPID() const override;
bool HasUserGesture(PP_Instance instance) const override;
int GetRoutingIDForWidget(PP_Instance instance) const override;
gfx::Point PluginPointToRenderFrame(PP_Instance instance,
@@ -103,6 +102,13 @@ class RendererPpapiHostImpl : public RendererPpapiHost {
// Returns whether the plugin is running in a secure context.
bool IsSecureContext(PP_Instance pp_instance) const;
+ // Returns the plugin child process ID if the plugin is running out of
+ // process. Returns -1 otherwise. This is the ID that the browser process uses
+ // to idetify the child process for the plugin. This isn't directly useful
+ // from our process (the renderer) except in messages to the browser to
+ // disambiguate plugins.
+ int GetPluginChildId() const;
+
void set_viewport_to_dip_scale(float viewport_to_dip_scale) {
DCHECK_LT(0, viewport_to_dip_scale_);
viewport_to_dip_scale_ = viewport_to_dip_scale;
diff --git a/chromium/content/renderer/pepper/resource_converter.cc b/chromium/content/renderer/pepper/resource_converter.cc
index fb183499184..4c33c05607e 100644
--- a/chromium/content/renderer/pepper/resource_converter.cc
+++ b/chromium/content/renderer/pepper/resource_converter.cc
@@ -310,7 +310,7 @@ bool ResourceConverterImpl::ToV8Value(const PP_Var& var,
::ppapi::host::PpapiHost* ppapi_host = renderer_ppapi_host->GetPpapiHost();
::ppapi::host::ResourceHost* resource_host =
ppapi_host->GetResourceHost(resource_id);
- if (resource_host == NULL) {
+ if (resource_host == nullptr) {
LOG(ERROR) << "No resource host for resource #" << resource_id;
return false;
}
diff --git a/chromium/content/renderer/pepper/resource_creation_impl.cc b/chromium/content/renderer/pepper/resource_creation_impl.cc
index 073a0b01d43..f848425f516 100644
--- a/chromium/content/renderer/pepper/resource_creation_impl.cc
+++ b/chromium/content/renderer/pepper/resource_creation_impl.cc
@@ -21,6 +21,7 @@
#include "ppapi/shared_impl/ppb_image_data_shared.h"
#include "ppapi/shared_impl/ppb_input_event_shared.h"
#include "ppapi/shared_impl/var.h"
+#include "services/service_manager/sandbox/switches.h"
#if defined(OS_WIN)
#include "base/command_line.h"
@@ -155,7 +156,7 @@ PP_Resource ResourceCreationImpl::CreateImageData(PP_Instance instance,
// TODO(ananta)
// Look into whether this causes a loss of functionality. From cursory
// testing things seem to work well.
- if (IsWin32kLockdownEnabled())
+ if (service_manager::IsWin32kLockdownEnabled())
return CreateImageDataSimple(instance, format, size, init_to_zero);
#endif
return PPB_ImageData_Impl::Create(instance,
diff --git a/chromium/content/renderer/pepper/url_request_info_util.cc b/chromium/content/renderer/pepper/url_request_info_util.cc
index c3ade42ff0d..38efaba9b3f 100644
--- a/chromium/content/renderer/pepper/url_request_info_util.cc
+++ b/chromium/content/renderer/pepper/url_request_info_util.cc
@@ -9,8 +9,8 @@
#include "base/logging.h"
#include "base/strings/string_util.h"
-#include "content/child/request_extra_data.h"
#include "content/common/fileapi/file_system_messages.h"
+#include "content/renderer/loader/request_extra_data.h"
#include "content/renderer/pepper/host_globals.h"
#include "content/renderer/pepper/pepper_file_ref_renderer_host.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
@@ -243,7 +243,7 @@ bool URLRequestRequiresUniversalAccess(const URLRequestInfoData& data) {
return data.has_custom_referrer_url ||
data.has_custom_content_transfer_encoding ||
data.has_custom_user_agent ||
- url::FindAndCompareScheme(data.url, url::kJavaScriptScheme, NULL);
+ url::FindAndCompareScheme(data.url, url::kJavaScriptScheme, nullptr);
}
} // namespace content
diff --git a/chromium/content/renderer/pepper/v8_var_converter_unittest.cc b/chromium/content/renderer/pepper/v8_var_converter_unittest.cc
index 857a1d69619..17c5ed2685d 100644
--- a/chromium/content/renderer/pepper/v8_var_converter_unittest.cc
+++ b/chromium/content/renderer/pepper/v8_var_converter_unittest.cc
@@ -180,7 +180,7 @@ class V8VarConverterTest : public testing::Test {
ProxyLock::Acquire();
v8::HandleScope handle_scope(isolate_);
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_);
- context_.Reset(isolate_, v8::Context::New(isolate_, NULL, global));
+ context_.Reset(isolate_, v8::Context::New(isolate_, nullptr, global));
}
void TearDown() override {
context_.Reset();
diff --git a/chromium/content/renderer/pepper/v8object_var.cc b/chromium/content/renderer/pepper/v8object_var.cc
index a95c529cd49..9e7ee57c3c1 100644
--- a/chromium/content/renderer/pepper/v8object_var.cc
+++ b/chromium/content/renderer/pepper/v8object_var.cc
@@ -45,13 +45,13 @@ void V8ObjectVar::InstanceDeleted() {
// This is called by the HostVarTracker which will take care of removing us
// from its set.
DCHECK(instance_);
- instance_ = NULL;
+ instance_ = nullptr;
}
// static
scoped_refptr<V8ObjectVar> V8ObjectVar::FromPPVar(PP_Var var) {
if (var.type != PP_VARTYPE_OBJECT)
- return scoped_refptr<V8ObjectVar>(NULL);
+ return scoped_refptr<V8ObjectVar>(nullptr);
scoped_refptr<Var> var_object(
PpapiGlobals::Get()->GetVarTracker()->GetVar(var));
if (!var_object.get())
diff --git a/chromium/content/renderer/pepper/video_decoder_shim.cc b/chromium/content/renderer/pepper/video_decoder_shim.cc
index ddc5f6a4e9e..8efb305a3b0 100644
--- a/chromium/content/renderer/pepper/video_decoder_shim.cc
+++ b/chromium/content/renderer/pepper/video_decoder_shim.cc
@@ -31,7 +31,6 @@
#include "media/base/video_decoder.h"
#include "media/filters/ffmpeg_video_decoder.h"
#include "media/filters/vpx_video_decoder.h"
-#include "media/renderers/skcanvas_video_renderer.h"
#include "media/video/picture.h"
#include "media/video/video_decode_accelerator.h"
#include "ppapi/c/pp_errors.h"
@@ -161,7 +160,7 @@ GLuint VideoDecoderShim::YUVConverter::CreateTexture() {
// Create texture with default size - will be resized upon first frame.
gl_->TexImage2D(GL_TEXTURE_2D, 0, internal_format_, 2, 2, 0, format_,
- GL_UNSIGNED_BYTE, NULL);
+ GL_UNSIGNED_BYTE, nullptr);
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -178,7 +177,7 @@ GLuint VideoDecoderShim::YUVConverter::CompileShader(const char* name,
const char* code) {
GLuint shader = gl_->CreateShader(type);
- gl_->ShaderSource(shader, 1, (const GLchar**)&code, NULL);
+ gl_->ShaderSource(shader, 1, (const GLchar**)&code, nullptr);
gl_->CompileShader(shader);
#ifndef NDEBUG
@@ -363,8 +362,8 @@ bool VideoDecoderShim::YUVConverter::Initialize() {
void VideoDecoderShim::YUVConverter::Convert(
const scoped_refptr<media::VideoFrame>& frame,
GLuint tex_out) {
- const float* yuv_matrix = 0;
- const float* yuv_adjust = 0;
+ const float* yuv_matrix = nullptr;
+ const float* yuv_adjust = nullptr;
if (video_format_ != frame->format()) {
// The constants below were taken from
@@ -558,7 +557,7 @@ void VideoDecoderShim::YUVConverter::Convert(
gl_->BindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
gl_->EnableVertexAttribArray(0);
gl_->VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat),
- static_cast<const void*>(0));
+ static_cast<const void*>(nullptr));
gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
diff --git a/chromium/content/renderer/peripheral_content_heuristic_unittest.cc b/chromium/content/renderer/peripheral_content_heuristic_unittest.cc
index 408147b5037..56d006c815e 100644
--- a/chromium/content/renderer/peripheral_content_heuristic_unittest.cc
+++ b/chromium/content/renderer/peripheral_content_heuristic_unittest.cc
@@ -22,57 +22,58 @@ const char kOtherOrigin[] = "http://other.com";
TEST(PeripheralContentHeuristic, AllowSameOrigin) {
EXPECT_EQ(RenderFrame::CONTENT_STATUS_ESSENTIAL_SAME_ORIGIN,
PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kSameOrigin)), gfx::Size(100, 100)));
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kSameOrigin)), gfx::Size(100, 100)));
EXPECT_EQ(RenderFrame::CONTENT_STATUS_ESSENTIAL_SAME_ORIGIN,
PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kSameOrigin)), gfx::Size(1000, 1000)));
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kSameOrigin)), gfx::Size(1000, 1000)));
}
TEST(PeripheralContentHeuristic, DisallowCrossOriginUnlessLarge) {
EXPECT_EQ(RenderFrame::CONTENT_STATUS_PERIPHERAL,
PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kOtherOrigin)), gfx::Size(100, 100)));
- EXPECT_EQ(RenderFrame::CONTENT_STATUS_ESSENTIAL_CROSS_ORIGIN_BIG,
- PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kOtherOrigin)), gfx::Size(1000, 1000)));
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kOtherOrigin)), gfx::Size(100, 100)));
+ EXPECT_EQ(
+ RenderFrame::CONTENT_STATUS_ESSENTIAL_CROSS_ORIGIN_BIG,
+ PeripheralContentHeuristic::GetPeripheralStatus(
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kOtherOrigin)), gfx::Size(1000, 1000)));
}
TEST(PeripheralContentHeuristic, TinyContent) {
EXPECT_EQ(RenderFrame::CONTENT_STATUS_TINY,
PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kSameOrigin)), gfx::Size(1, 1)));
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kSameOrigin)), gfx::Size(1, 1)));
EXPECT_EQ(RenderFrame::CONTENT_STATUS_TINY,
PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kOtherOrigin)), gfx::Size(1, 1)));
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kOtherOrigin)), gfx::Size(1, 1)));
EXPECT_EQ(RenderFrame::CONTENT_STATUS_TINY,
PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kOtherOrigin)), gfx::Size(5, 5)));
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kOtherOrigin)), gfx::Size(5, 5)));
EXPECT_EQ(RenderFrame::CONTENT_STATUS_PERIPHERAL,
PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kOtherOrigin)), gfx::Size(10, 10)));
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kOtherOrigin)), gfx::Size(10, 10)));
}
TEST(PeripheralContentHeuristic, TemporaryOriginWhitelist) {
EXPECT_EQ(RenderFrame::CONTENT_STATUS_PERIPHERAL,
PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kOtherOrigin)), gfx::Size(100, 100)));
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kOtherOrigin)), gfx::Size(100, 100)));
std::set<url::Origin> whitelist;
- whitelist.insert(url::Origin(GURL(kOtherOrigin)));
+ whitelist.insert(url::Origin::Create(GURL(kOtherOrigin)));
EXPECT_EQ(RenderFrame::CONTENT_STATUS_ESSENTIAL_CROSS_ORIGIN_WHITELISTED,
PeripheralContentHeuristic::GetPeripheralStatus(
- whitelist, url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kOtherOrigin)), gfx::Size(100, 100)));
+ whitelist, url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kOtherOrigin)), gfx::Size(100, 100)));
}
TEST(PeripheralContentHeuristic, UndefinedSize) {
@@ -80,20 +81,20 @@ TEST(PeripheralContentHeuristic, UndefinedSize) {
// whitelisted origins) are marked tiny until proven otherwise.
EXPECT_EQ(RenderFrame::CONTENT_STATUS_TINY,
PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kSameOrigin)), gfx::Size()));
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kSameOrigin)), gfx::Size()));
std::set<url::Origin> whitelist;
- whitelist.insert(url::Origin(GURL(kOtherOrigin)));
+ whitelist.insert(url::Origin::Create(GURL(kOtherOrigin)));
EXPECT_EQ(RenderFrame::CONTENT_STATUS_TINY,
PeripheralContentHeuristic::GetPeripheralStatus(
- whitelist, url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kOtherOrigin)), gfx::Size()));
+ whitelist, url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kOtherOrigin)), gfx::Size()));
EXPECT_EQ(RenderFrame::CONTENT_STATUS_TINY,
PeripheralContentHeuristic::GetPeripheralStatus(
- std::set<url::Origin>(), url::Origin(GURL(kSameOrigin)),
- url::Origin(GURL(kOtherOrigin)), gfx::Size()));
+ std::set<url::Origin>(), url::Origin::Create(GURL(kSameOrigin)),
+ url::Origin::Create(GURL(kOtherOrigin)), gfx::Size()));
}
} // namespace content
diff --git a/chromium/content/renderer/presentation/presentation_dispatcher_unittest.cc b/chromium/content/renderer/presentation/presentation_dispatcher_unittest.cc
index ae1e8183d6c..cd948ec4269 100644
--- a/chromium/content/renderer/presentation/presentation_dispatcher_unittest.cc
+++ b/chromium/content/renderer/presentation/presentation_dispatcher_unittest.cc
@@ -185,7 +185,7 @@ class TestPresentationDispatcher : public PresentationDispatcher {
private:
void ConnectToPresentationServiceIfNeeded() override {
if (!mock_binding_) {
- mock_binding_ = base::MakeUnique<mojo::Binding<PresentationService>>(
+ mock_binding_ = std::make_unique<mojo::Binding<PresentationService>>(
mock_presentation_service_,
mojo::MakeRequest(&presentation_service_));
}
@@ -319,7 +319,7 @@ TEST_F(PresentationDispatcherTest, TestStartPresentation) {
EXPECT_CALL(connection, Init()).Times(1);
dispatcher_.StartPresentation(
- urls_, base::MakeUnique<TestWebPresentationConnectionCallback>(
+ urls_, std::make_unique<TestWebPresentationConnectionCallback>(
url1_, presentation_id_, &connection));
run_loop.RunUntilIdle();
}
@@ -342,7 +342,7 @@ TEST_F(PresentationDispatcherTest, TestStartPresentationError) {
}));
dispatcher_.StartPresentation(
urls_,
- base::MakeUnique<TestWebPresentationConnectionErrorCallback>(
+ std::make_unique<TestWebPresentationConnectionErrorCallback>(
WebPresentationError::kErrorTypeNoAvailableScreens, error_message));
run_loop.RunUntilIdle();
}
@@ -368,7 +368,7 @@ TEST_F(PresentationDispatcherTest, TestReconnectPresentationError) {
}));
dispatcher_.ReconnectPresentation(
urls_, presentation_id_,
- base::MakeUnique<TestWebPresentationConnectionErrorCallback>(
+ std::make_unique<TestWebPresentationConnectionErrorCallback>(
WebPresentationError::kErrorTypeNoAvailableScreens, error_message));
run_loop.RunUntilIdle();
}
@@ -394,7 +394,7 @@ TEST_F(PresentationDispatcherTest, TestReconnectPresentation) {
EXPECT_CALL(connection, Init()).Times(1);
dispatcher_.ReconnectPresentation(
urls_, presentation_id_,
- base::MakeUnique<TestWebPresentationConnectionCallback>(
+ std::make_unique<TestWebPresentationConnectionCallback>(
url1_, presentation_id_, &connection));
run_loop.RunUntilIdle();
}
@@ -421,7 +421,7 @@ TEST_F(PresentationDispatcherTest, TestReconnectPresentationNoConnection) {
EXPECT_CALL(connection, Init()).Times(0);
dispatcher_.ReconnectPresentation(
urls_, presentation_id_,
- base::MakeUnique<TestWebPresentationConnectionCallback>(
+ std::make_unique<TestWebPresentationConnectionCallback>(
url1_, presentation_id_, nullptr));
run_loop.RunUntilIdle();
}
@@ -436,7 +436,7 @@ TEST_F(PresentationDispatcherTest, TestListenForScreenAvailability) {
}
dispatcher_.GetAvailability(
- urls_, base::MakeUnique<WebPresentationAvailabilityCallbacks>());
+ urls_, std::make_unique<WebPresentationAvailabilityCallbacks>());
dispatcher_.OnScreenAvailabilityUpdated(url1_, ScreenAvailability::AVAILABLE);
run_loop1.RunUntilIdle();
@@ -602,7 +602,7 @@ TEST_F(PresentationDispatcherTest, StartListeningListenToEachURLOnce) {
for (auto* mock_observer : mock_observers_) {
client()->GetAvailability(
mock_observer->Urls(),
- base::MakeUnique<WebPresentationAvailabilityCallbacks>());
+ std::make_unique<WebPresentationAvailabilityCallbacks>());
client()->StartListening(mock_observer);
}
run_loop.RunUntilIdle();
@@ -628,7 +628,7 @@ TEST_F(PresentationDispatcherTest, StopListeningListenToEachURLOnce) {
for (auto* mock_observer : mock_observers_) {
client()->GetAvailability(
mock_observer->Urls(),
- base::MakeUnique<WebPresentationAvailabilityCallbacks>());
+ std::make_unique<WebPresentationAvailabilityCallbacks>());
client()->StartListening(mock_observer);
}
@@ -660,7 +660,7 @@ TEST_F(PresentationDispatcherTest,
for (auto* mock_observer : mock_observers_) {
client()->GetAvailability(
mock_observer->Urls(),
- base::MakeUnique<WebPresentationAvailabilityCallbacks>());
+ std::make_unique<WebPresentationAvailabilityCallbacks>());
}
for (auto* mock_observer : mock_observers_)
@@ -692,7 +692,7 @@ TEST_F(PresentationDispatcherTest,
for (auto* mock_observer : mock_observers_) {
client()->GetAvailability(
mock_observer->Urls(),
- base::MakeUnique<WebPresentationAvailabilityCallbacks>());
+ std::make_unique<WebPresentationAvailabilityCallbacks>());
client()->StartListening(mock_observer);
}
@@ -729,7 +729,7 @@ TEST_F(PresentationDispatcherTest,
for (auto* mock_observer : mock_observers_) {
client()->GetAvailability(
mock_observer->Urls(),
- base::MakeUnique<WebPresentationAvailabilityCallbacks>());
+ std::make_unique<WebPresentationAvailabilityCallbacks>());
client()->StartListening(mock_observer);
}
diff --git a/chromium/content/renderer/push_messaging/push_messaging_client.cc b/chromium/content/renderer/push_messaging/push_messaging_client.cc
index 0b9ea5345d3..f0450f49a6c 100644
--- a/chromium/content/renderer/push_messaging/push_messaging_client.cc
+++ b/chromium/content/renderer/push_messaging/push_messaging_client.cc
@@ -10,15 +10,15 @@
#include "base/bind_helpers.h"
#include "base/strings/utf_string_conversions.h"
#include "content/child/child_thread_impl.h"
-#include "content/child/push_messaging/push_provider.h"
-#include "content/child/service_worker/web_service_worker_registration_impl.h"
#include "content/common/push_messaging.mojom.h"
#include "content/public/common/push_messaging_status.mojom.h"
#include "content/public/common/service_names.mojom.h"
-#include "content/renderer/manifest/manifest_manager.h"
+#include "content/renderer/push_messaging/push_provider.h"
#include "content/renderer/render_frame_impl.h"
+#include "content/renderer/service_worker/web_service_worker_registration_impl.h"
#include "services/service_manager/public/cpp/connector.h"
#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/modules/manifest/manifest_manager.mojom.h"
#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushError.h"
#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushSubscription.h"
#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushSubscriptionOptions.h"
@@ -56,11 +56,11 @@ void PushMessagingClient::Subscribe(
// fetching the manifest.
if (options.application_server_key.IsEmpty()) {
RenderFrameImpl::FromRoutingID(routing_id())
- ->manifest_manager()
- ->GetManifest(base::BindOnce(&PushMessagingClient::DidGetManifest,
- base::Unretained(this),
- service_worker_registration, options,
- user_gesture, base::Passed(&callbacks)));
+ ->GetManifestManager()
+ .RequestManifest(
+ base::BindOnce(&PushMessagingClient::DidGetManifest,
+ base::Unretained(this), service_worker_registration,
+ options, user_gesture, base::Passed(&callbacks)));
} else {
PushSubscriptionOptions content_options;
content_options.user_visible_only = options.user_visible_only;
@@ -78,8 +78,7 @@ void PushMessagingClient::DidGetManifest(
bool user_gesture,
std::unique_ptr<blink::WebPushSubscriptionCallbacks> callbacks,
const GURL& manifest_url,
- const Manifest& manifest,
- const ManifestDebugInfo&) {
+ const Manifest& manifest) {
// Get the sender_info from the manifest since it wasn't provided by
// the caller.
if (manifest.IsEmpty()) {
diff --git a/chromium/content/renderer/push_messaging/push_messaging_client.h b/chromium/content/renderer/push_messaging/push_messaging_client.h
index d243ec205f7..331ef4da2b8 100644
--- a/chromium/content/renderer/push_messaging/push_messaging_client.h
+++ b/chromium/content/renderer/push_messaging/push_messaging_client.h
@@ -14,6 +14,7 @@
#include "base/macros.h"
#include "content/common/push_messaging.mojom.h"
#include "content/public/renderer/render_frame_observer.h"
+#include "third_party/WebKit/public/platform/modules/manifest/manifest.mojom.h"
#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushClient.h"
#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h"
@@ -30,7 +31,6 @@ enum class PushRegistrationStatus;
}
struct Manifest;
-struct ManifestDebugInfo;
struct PushSubscriptionOptions;
class PushMessagingClient : public RenderFrameObserver,
@@ -56,8 +56,7 @@ class PushMessagingClient : public RenderFrameObserver,
bool user_gesture,
std::unique_ptr<blink::WebPushSubscriptionCallbacks> callbacks,
const GURL& manifest_url,
- const Manifest& manifest,
- const ManifestDebugInfo&);
+ const Manifest& manifest);
void DoSubscribe(
blink::WebServiceWorkerRegistration* service_worker_registration,
diff --git a/chromium/content/child/push_messaging/push_provider.cc b/chromium/content/renderer/push_messaging/push_provider.cc
index 78823505b37..d562990b001 100644
--- a/chromium/content/child/push_messaging/push_provider.cc
+++ b/chromium/content/renderer/push_messaging/push_provider.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/child/push_messaging/push_provider.h"
+#include "content/renderer/push_messaging/push_provider.h"
#include <memory>
#include <utility>
@@ -11,11 +11,11 @@
#include "base/lazy_instance.h"
#include "base/threading/thread_local.h"
#include "content/child/child_thread_impl.h"
-#include "content/child/service_worker/web_service_worker_registration_impl.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/push_messaging_status.mojom.h"
#include "content/public/common/push_subscription_options.h"
#include "content/public/common/service_names.mojom.h"
+#include "content/renderer/service_worker/web_service_worker_registration_impl.h"
#include "services/service_manager/public/cpp/connector.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushSubscription.h"
diff --git a/chromium/content/child/push_messaging/push_provider.h b/chromium/content/renderer/push_messaging/push_provider.h
index 07d3bdaa424..08a75cc0a32 100644
--- a/chromium/content/child/push_messaging/push_provider.h
+++ b/chromium/content/renderer/push_messaging/push_provider.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_CHILD_PUSH_MESSAGING_PUSH_PROVIDER_H_
-#define CONTENT_CHILD_PUSH_MESSAGING_PUSH_PROVIDER_H_
+#ifndef CONTENT_RENDERER_PUSH_MESSAGING_PUSH_PROVIDER_H_
+#define CONTENT_RENDERER_PUSH_MESSAGING_PUSH_PROVIDER_H_
#include <stdint.h>
@@ -14,7 +14,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/push_messaging.mojom.h"
-#include "content/public/child/worker_thread.h"
+#include "content/public/renderer/worker_thread.h"
#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushError.h"
#include "third_party/WebKit/public/platform/modules/push_messaging/WebPushProvider.h"
@@ -106,4 +106,4 @@ class PushProvider : public blink::WebPushProvider,
} // namespace content
-#endif // CONTENT_CHILD_PUSH_MESSAGING_PUSH_PROVIDER_H_
+#endif // CONTENT_RENDERER_PUSH_MESSAGING_PUSH_PROVIDER_H_
diff --git a/chromium/content/child/quota_dispatcher.cc b/chromium/content/renderer/quota_dispatcher.cc
index 761173e5204..daa181acd54 100644
--- a/chromium/content/child/quota_dispatcher.cc
+++ b/chromium/content/renderer/quota_dispatcher.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/child/quota_dispatcher.h"
+#include "content/renderer/quota_dispatcher.h"
#include <memory>
#include <utility>
@@ -11,12 +11,11 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/threading/thread_local.h"
-#include "content/child/quota_message_filter.h"
-#include "content/child/thread_safe_sender.h"
-#include "content/common/quota_messages.h"
+#include "content/public/common/service_names.mojom.h"
+#include "content/public/renderer/render_thread.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h"
#include "third_party/WebKit/public/platform/WebStorageQuotaType.h"
-#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "url/gurl.h"
using blink::WebStorageQuotaCallbacks;
@@ -60,13 +59,27 @@ int CurrentWorkerId() {
return WorkerThread::GetCurrentId();
}
+void BindConnectorOnMainThread(mojom::QuotaDispatcherHostRequest request) {
+ DCHECK(RenderThread::Get());
+ RenderThread::Get()->GetConnector()->BindInterface(mojom::kBrowserServiceName,
+ std::move(request));
+}
+
} // namespace
-QuotaDispatcher::QuotaDispatcher(ThreadSafeSender* thread_safe_sender,
- QuotaMessageFilter* quota_message_filter)
- : thread_safe_sender_(thread_safe_sender),
- quota_message_filter_(quota_message_filter) {
+QuotaDispatcher::QuotaDispatcher(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
+ : main_thread_task_runner_(main_thread_task_runner) {
g_quota_dispatcher_tls.Pointer()->Set(this);
+
+ auto request = mojo::MakeRequest(&quota_host_);
+ if (main_thread_task_runner_->BelongsToCurrentThread()) {
+ BindConnectorOnMainThread(std::move(request));
+ } else {
+ main_thread_task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&BindConnectorOnMainThread, std::move(request)));
+ }
}
QuotaDispatcher::~QuotaDispatcher() {
@@ -77,17 +90,15 @@ QuotaDispatcher::~QuotaDispatcher() {
iter.Advance();
}
- g_quota_dispatcher_tls.Pointer()->Set(NULL);
+ g_quota_dispatcher_tls.Pointer()->Set(nullptr);
}
QuotaDispatcher* QuotaDispatcher::ThreadSpecificInstance(
- ThreadSafeSender* thread_safe_sender,
- QuotaMessageFilter* quota_message_filter) {
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
if (g_quota_dispatcher_tls.Pointer()->Get())
return g_quota_dispatcher_tls.Pointer()->Get();
- QuotaDispatcher* dispatcher = new QuotaDispatcher(
- thread_safe_sender, quota_message_filter);
+ QuotaDispatcher* dispatcher = new QuotaDispatcher(task_runner);
if (WorkerThread::GetCurrentId())
WorkerThread::AddObserver(dispatcher);
return dispatcher;
@@ -97,70 +108,65 @@ void QuotaDispatcher::WillStopCurrentWorkerThread() {
delete this;
}
-void QuotaDispatcher::OnMessageReceived(const IPC::Message& msg) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(QuotaDispatcher, msg)
- IPC_MESSAGE_HANDLER(QuotaMsg_DidGrantStorageQuota,
- DidGrantStorageQuota)
- IPC_MESSAGE_HANDLER(QuotaMsg_DidQueryStorageUsageAndQuota,
- DidQueryStorageUsageAndQuota);
- IPC_MESSAGE_HANDLER(QuotaMsg_DidFail, DidFail);
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- DCHECK(handled) << "Unhandled message:" << msg.type();
-}
-
void QuotaDispatcher::QueryStorageUsageAndQuota(
const GURL& origin_url,
StorageType type,
std::unique_ptr<Callback> callback) {
DCHECK(callback);
- int request_id = quota_message_filter_->GenerateRequestID(CurrentWorkerId());
- pending_quota_callbacks_.AddWithID(std::move(callback), request_id);
- thread_safe_sender_->Send(new QuotaHostMsg_QueryStorageUsageAndQuota(
- request_id, origin_url, type));
+ int request_id = pending_quota_callbacks_.Add(std::move(callback));
+ quota_host_->QueryStorageUsageAndQuota(
+ origin_url, type,
+ base::BindOnce(&QuotaDispatcher::DidQueryStorageUsageAndQuota,
+ base::Unretained(this), request_id));
}
void QuotaDispatcher::RequestStorageQuota(int render_frame_id,
const GURL& origin_url,
StorageType type,
- uint64_t requested_size,
+ int64_t requested_size,
std::unique_ptr<Callback> callback) {
DCHECK(callback);
- DCHECK(CurrentWorkerId() == 0);
- int request_id = quota_message_filter_->GenerateRequestID(CurrentWorkerId());
- pending_quota_callbacks_.AddWithID(std::move(callback), request_id);
-
- StorageQuotaParams params;
- params.render_frame_id = render_frame_id;
- params.request_id = request_id;
- params.origin_url = origin_url;
- params.storage_type = type;
- params.requested_size = requested_size;
- params.user_gesture =
- blink::WebUserGestureIndicator::IsProcessingUserGesture();
- thread_safe_sender_->Send(new QuotaHostMsg_RequestStorageQuota(params));
+ DCHECK_EQ(CurrentWorkerId(), 0)
+ << "Requests may show permission UI and are not allowed from workers.";
+ int request_id = pending_quota_callbacks_.Add(std::move(callback));
+ quota_host_->RequestStorageQuota(
+ render_frame_id, origin_url, type, requested_size,
+ base::BindOnce(&QuotaDispatcher::DidGrantStorageQuota,
+ base::Unretained(this), request_id));
}
// static
std::unique_ptr<QuotaDispatcher::Callback>
QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(
blink::WebStorageQuotaCallbacks callbacks) {
- return base::MakeUnique<WebStorageQuotaDispatcherCallback>(callbacks);
+ return std::make_unique<WebStorageQuotaDispatcherCallback>(callbacks);
}
-void QuotaDispatcher::DidGrantStorageQuota(int request_id,
+void QuotaDispatcher::DidGrantStorageQuota(int64_t request_id,
+ storage::QuotaStatusCode status,
int64_t current_usage,
int64_t granted_quota) {
+ if (status != storage::kQuotaStatusOk) {
+ DidFail(request_id, status);
+ return;
+ }
+
Callback* callback = pending_quota_callbacks_.Lookup(request_id);
DCHECK(callback);
callback->DidGrantStorageQuota(current_usage, granted_quota);
pending_quota_callbacks_.Remove(request_id);
}
-void QuotaDispatcher::DidQueryStorageUsageAndQuota(int request_id,
- int64_t current_usage,
- int64_t current_quota) {
+void QuotaDispatcher::DidQueryStorageUsageAndQuota(
+ int64_t request_id,
+ storage::QuotaStatusCode status,
+ int64_t current_usage,
+ int64_t current_quota) {
+ if (status != storage::kQuotaStatusOk) {
+ DidFail(request_id, status);
+ return;
+ }
+
Callback* callback = pending_quota_callbacks_.Lookup(request_id);
DCHECK(callback);
callback->DidQueryStorageUsageAndQuota(current_usage, current_quota);
diff --git a/chromium/content/child/quota_dispatcher.h b/chromium/content/renderer/quota_dispatcher.h
index fbbf6ddd973..ef1af8291af 100644
--- a/chromium/content/child/quota_dispatcher.h
+++ b/chromium/content/renderer/quota_dispatcher.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_CHILD_QUOTA_DISPATCHER_H_
-#define CONTENT_CHILD_QUOTA_DISPATCHER_H_
+#ifndef CONTENT_RENDERER_QUOTA_DISPATCHER_H_
+#define CONTENT_RENDERER_QUOTA_DISPATCHER_H_
#include <stdint.h>
@@ -13,31 +13,26 @@
#include "base/containers/id_map.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "content/public/child/worker_thread.h"
-#include "storage/common/quota/quota_types.h"
+#include "content/common/quota_dispatcher_host.mojom.h"
+#include "content/public/renderer/worker_thread.h"
class GURL;
-namespace IPC {
-class Message;
-}
-
namespace blink {
class WebStorageQuotaCallbacks;
}
namespace content {
-class ThreadSafeSender;
-class QuotaMessageFilter;
-
// Dispatches and sends quota related messages sent to/from a child
// process from/to the main browser process. There is one instance
// per each thread. Thread-specific instance can be obtained by
// ThreadSpecificInstance().
+// TODO(sashab): Change this to be per-execution context instead of per-process.
class QuotaDispatcher : public WorkerThread::Observer {
public:
+ // TODO(sashab): Remove this wrapper, using lambdas or just the web callback
+ // itself.
class Callback {
public:
virtual ~Callback() {}
@@ -46,28 +41,23 @@ class QuotaDispatcher : public WorkerThread::Observer {
virtual void DidFail(storage::QuotaStatusCode status) = 0;
};
- QuotaDispatcher(ThreadSafeSender* thread_safe_sender,
- QuotaMessageFilter* quota_message_filter);
+ explicit QuotaDispatcher(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
~QuotaDispatcher() override;
- // |thread_safe_sender| and |quota_message_filter| are used if
- // calling this leads to construction.
static QuotaDispatcher* ThreadSpecificInstance(
- ThreadSafeSender* thread_safe_sender,
- QuotaMessageFilter* quota_message_filter);
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
// WorkerThread::Observer implementation.
void WillStopCurrentWorkerThread() override;
- void OnMessageReceived(const IPC::Message& msg);
-
void QueryStorageUsageAndQuota(const GURL& gurl,
storage::StorageType type,
std::unique_ptr<Callback> callback);
void RequestStorageQuota(int render_frame_id,
const GURL& gurl,
storage::StorageType type,
- uint64_t requested_size,
+ int64_t requested_size,
std::unique_ptr<Callback> callback);
// Creates a new Callback instance for WebStorageQuotaCallbacks.
@@ -76,22 +66,27 @@ class QuotaDispatcher : public WorkerThread::Observer {
private:
// Message handlers.
- void DidQueryStorageUsageAndQuota(int request_id,
+ void DidQueryStorageUsageAndQuota(int64_t request_id,
+ storage::QuotaStatusCode status,
int64_t current_usage,
int64_t current_quota);
- void DidGrantStorageQuota(int request_id,
+ void DidGrantStorageQuota(int64_t request_id,
+ storage::QuotaStatusCode status,
int64_t current_usage,
int64_t granted_quota);
void DidFail(int request_id, storage::QuotaStatusCode error);
- base::IDMap<std::unique_ptr<Callback>> pending_quota_callbacks_;
+ content::mojom::QuotaDispatcherHostPtr quota_host_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
- scoped_refptr<ThreadSafeSender> thread_safe_sender_;
- scoped_refptr<QuotaMessageFilter> quota_message_filter_;
+ // TODO(sashab, nverne): Once default callbacks are available for dropped mojo
+ // callbacks (crbug.com/775358), use them to call DidFail for them in the
+ // destructor and remove this.
+ base::IDMap<std::unique_ptr<Callback>> pending_quota_callbacks_;
DISALLOW_COPY_AND_ASSIGN(QuotaDispatcher);
};
} // namespace content
-#endif // CONTENT_CHILD_QUOTA_DISPATCHER_H_
+#endif // CONTENT_RENDERER_QUOTA_DISPATCHER_H_
diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc
index f1f58918685..40f9cef599d 100644
--- a/chromium/content/renderer/render_frame_impl.cc
+++ b/chromium/content/renderer/render_frame_impl.cc
@@ -28,10 +28,13 @@
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
+#include "base/optional.h"
#include "base/process/process.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -39,22 +42,10 @@
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
-#include "content/child/appcache/appcache_dispatcher.h"
-#include "content/child/feature_policy/feature_policy_platform.h"
-#include "content/child/quota_dispatcher.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/service_worker/service_worker_handle_reference.h"
-#include "content/child/service_worker/service_worker_network_provider.h"
-#include "content/child/service_worker/service_worker_provider_context.h"
-#include "content/child/service_worker/web_service_worker_provider_impl.h"
-#include "content/child/v8_value_converter_impl.h"
-#include "content/child/web_url_loader_impl.h"
-#include "content/child/web_url_request_util.h"
-#include "content/child/weburlresponse_extradata_impl.h"
#include "content/common/accessibility_messages.h"
#include "content/common/associated_interface_provider_impl.h"
#include "content/common/associated_interfaces.mojom.h"
-#include "content/common/clipboard_messages.h"
+#include "content/common/clipboard.mojom.h"
#include "content/common/content_constants_internal.h"
#include "content/common/content_security_policy/csp_context.h"
#include "content/common/content_security_policy_header.h"
@@ -73,9 +64,8 @@
#include "content/common/site_isolation_policy.h"
#include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
#include "content/public/common/appcache_info.h"
-#include "content/public/common/associated_interface_provider.h"
+#include "content/public/common/bind_interface_helpers.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_constants.h"
@@ -93,6 +83,7 @@
#include "content/public/common/url_loader_throttle.h"
#include "content/public/common/url_utils.h"
#include "content/public/renderer/browser_plugin_delegate.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/context_menu_client.h"
#include "content/public/renderer/document_state.h"
@@ -101,16 +92,19 @@
#include "content/public/renderer/render_frame_visitor.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/accessibility/render_accessibility_impl.h"
+#include "content/renderer/appcache/appcache_dispatcher.h"
#include "content/renderer/browser_plugin/browser_plugin.h"
#include "content/renderer/browser_plugin/browser_plugin_manager.h"
#include "content/renderer/content_security_policy_util.h"
#include "content/renderer/context_menu_params_builder.h"
#include "content/renderer/devtools/devtools_agent.h"
+#include "content/renderer/devtools/devtools_frontend_impl.h"
#include "content/renderer/dom_automation_controller.h"
#include "content/renderer/effective_connection_type_helper.h"
#include "content/renderer/external_popup_menu.h"
#include "content/renderer/frame_owner_properties.h"
#include "content/renderer/gpu/gpu_benchmarking_extension.h"
+#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/history_entry.h"
#include "content/renderer/history_serialization.h"
#include "content/renderer/image_downloader/image_downloader_impl.h"
@@ -119,22 +113,26 @@
#include "content/renderer/input/input_handler_manager.h"
#include "content/renderer/installedapp/related_apps_fetcher.h"
#include "content/renderer/internal_document_state_data.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/loader/web_url_loader_impl.h"
+#include "content/renderer/loader/web_url_request_util.h"
+#include "content/renderer/loader/weburlresponse_extradata_impl.h"
#include "content/renderer/manifest/manifest_manager.h"
#include "content/renderer/media/audio_device_factory.h"
#include "content/renderer/media/audio_ipc_factory.h"
#include "content/renderer/media/media_devices_listener_impl.h"
#include "content/renderer/media/media_permission_dispatcher.h"
-#include "content/renderer/media/media_stream_dispatcher.h"
+#include "content/renderer/media/media_stream_device_observer.h"
#include "content/renderer/media/user_media_client_impl.h"
#include "content/renderer/mojo/blink_connector_js_wrapper.h"
#include "content/renderer/mojo/blink_interface_registry_impl.h"
#include "content/renderer/mojo/interface_provider_js_wrapper.h"
-#include "content/renderer/mojo_bindings_controller.h"
#include "content/renderer/navigation_state_impl.h"
#include "content/renderer/pepper/pepper_audio_controller.h"
#include "content/renderer/pepper/plugin_instance_throttler_impl.h"
#include "content/renderer/presentation/presentation_dispatcher.h"
#include "content/renderer/push_messaging/push_messaging_client.h"
+#include "content/renderer/quota_dispatcher.h"
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_thread_impl.h"
@@ -145,10 +143,15 @@
#include "content/renderer/renderer_webcolorchooser_impl.h"
#include "content/renderer/savable_resources.h"
#include "content/renderer/screen_orientation/screen_orientation_dispatcher.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.h"
+#include "content/renderer/service_worker/service_worker_network_provider.h"
+#include "content/renderer/service_worker/service_worker_provider_context.h"
+#include "content/renderer/service_worker/web_service_worker_provider_impl.h"
#include "content/renderer/service_worker/worker_fetch_context_impl.h"
#include "content/renderer/shared_worker/shared_worker_repository.h"
#include "content/renderer/skia_benchmarking_extension.h"
#include "content/renderer/stats_collection_controller.h"
+#include "content/renderer/v8_value_converter_impl.h"
#include "content/renderer/web_frame_utils.h"
#include "content/renderer/web_ui_extension.h"
#include "content/renderer/web_ui_extension_data.h"
@@ -168,18 +171,22 @@
#include "ppapi/features/features.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
+#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "storage/common/data_element.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/WebKit/common/frame_policy.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/FilePathConversion.h"
#include "third_party/WebKit/public/platform/InterfaceProvider.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
-#include "third_party/WebKit/public/platform/WebCachePolicy.h"
#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebFocusType.h"
#include "third_party/WebKit/public/platform/WebKeyboardEvent.h"
#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
#include "third_party/WebKit/public/platform/WebMediaPlayerSource.h"
#include "third_party/WebKit/public/platform/WebPoint.h"
+#include "third_party/WebKit/public/platform/WebRemoteScrollProperties.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h"
#include "third_party/WebKit/public/platform/WebString.h"
@@ -187,10 +194,13 @@
#include "third_party/WebKit/public/platform/WebURLError.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/platform/WebVector.h"
+#include "third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
#include "third_party/WebKit/public/platform/modules/permissions/permission.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h"
+#include "third_party/WebKit/public/web/WebAutofillClient.h"
#include "third_party/WebKit/public/web/WebColorSuggestion.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
+#include "third_party/WebKit/public/web/WebContextFeatures.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "third_party/WebKit/public/web/WebFrameOwnerProperties.h"
@@ -221,6 +231,7 @@
#include "url/origin.h"
#include "url/url_constants.h"
#include "url/url_util.h"
+#include "v8/include/v8.h"
#if BUILDFLAG(ENABLE_PLUGINS)
#include "content/renderer/pepper/pepper_browser_connection.h"
@@ -243,7 +254,6 @@
using base::Time;
using base::TimeDelta;
-using blink::WebCachePolicy;
using blink::WebContentDecryptionModule;
using blink::WebContextMenuData;
using blink::WebData;
@@ -308,6 +318,9 @@ namespace content {
namespace {
+const base::Feature kConsumeGestureOnNavigation = {
+ "ConsumeGestureOnNavigation", base::FEATURE_DISABLED_BY_DEFAULT};
+
const int kExtraCharsBeforeAndAfterSelection = 100;
typedef std::map<int, RenderFrameImpl*> RoutingIDFrameMap;
@@ -392,7 +405,7 @@ bool IsBrowserInitiated(NavigationParams* pending) {
// Returns false unless this is a top-level navigation.
bool IsTopLevelNavigation(WebFrame* frame) {
- return frame->Parent() == NULL;
+ return frame->Parent() == nullptr;
}
WebURLRequest CreateURLRequestForNavigation(
@@ -417,7 +430,7 @@ WebURLRequest CreateURLRequestForNavigation(
request.SetHTTPMethod(WebString::FromUTF8(navigation_method));
if (is_view_source_mode_enabled)
- request.SetCachePolicy(WebCachePolicy::kReturnCacheDataElseLoad);
+ request.SetCacheMode(blink::mojom::FetchCacheMode::kForceCache);
WebString web_referrer;
if (common_params.referrer.url.is_valid()) {
@@ -427,7 +440,7 @@ WebURLRequest CreateURLRequestForNavigation(
request.SetHTTPReferrer(web_referrer, common_params.referrer.policy);
if (!web_referrer.IsEmpty()) {
request.AddHTTPOriginIfNeeded(
- WebSecurityOrigin(url::Origin(common_params.referrer.url)));
+ WebSecurityOrigin(url::Origin::Create(common_params.referrer.url)));
}
}
@@ -534,7 +547,8 @@ 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 */);
+ should_check_main_world_csp, false /* started_from_context_menu */,
+ info.url_request.HasUserGesture());
}
WebFrameLoadType ReloadFrameLoadTypeFor(
@@ -718,8 +732,91 @@ std::vector<gfx::Size> ConvertToFaviconSizes(
return result;
}
+// Use this for histograms with dynamically generated names, which otherwise
+// can't use the UMA_HISTOGRAM_MEMORY_MB macro without code duplication.
+void RecordSuffixedMemoryMBHistogram(base::StringPiece name,
+ base::StringPiece suffix,
+ int sample_mb) {
+ std::string name_with_suffix;
+ name.CopyToString(&name_with_suffix);
+ suffix.AppendToString(&name_with_suffix);
+ base::UmaHistogramMemoryMB(name_with_suffix, sample_mb);
+}
+
+void RecordSuffixedRendererMemoryMetrics(
+ const RenderThreadImpl::RendererMemoryMetrics& memory_metrics,
+ base::StringPiece suffix) {
+ RecordSuffixedMemoryMBHistogram("Memory.Experimental.Renderer.PartitionAlloc",
+ suffix,
+ memory_metrics.partition_alloc_kb / 1024);
+ RecordSuffixedMemoryMBHistogram("Memory.Experimental.Renderer.BlinkGC",
+ suffix, memory_metrics.blink_gc_kb / 1024);
+ RecordSuffixedMemoryMBHistogram("Memory.Experimental.Renderer.Malloc", suffix,
+ memory_metrics.malloc_mb);
+ RecordSuffixedMemoryMBHistogram("Memory.Experimental.Renderer.Discardable",
+ suffix, memory_metrics.discardable_kb / 1024);
+ RecordSuffixedMemoryMBHistogram(
+ "Memory.Experimental.Renderer.V8MainThreadIsolate", suffix,
+ memory_metrics.v8_main_thread_isolate_mb);
+ RecordSuffixedMemoryMBHistogram("Memory.Experimental.Renderer.TotalAllocated",
+ suffix, memory_metrics.total_allocated_mb);
+ RecordSuffixedMemoryMBHistogram(
+ "Memory.Experimental.Renderer.NonDiscardableTotalAllocated", suffix,
+ memory_metrics.non_discardable_total_allocated_mb);
+ RecordSuffixedMemoryMBHistogram(
+ "Memory.Experimental.Renderer.TotalAllocatedPerRenderView", suffix,
+ memory_metrics.total_allocated_per_render_view_mb);
+}
+
} // namespace
+class RenderFrameImpl::FrameURLLoaderFactory
+ : public blink::WebURLLoaderFactory {
+ public:
+ FrameURLLoaderFactory(
+ base::WeakPtr<RenderFrameImpl> frame,
+ scoped_refptr<ChildURLLoaderFactoryGetter> loader_factory_getter)
+ : frame_(std::move(frame)),
+ loader_factory_getter_(std::move(loader_factory_getter)) {}
+
+ ~FrameURLLoaderFactory() override = default;
+
+ std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
+ const WebURLRequest& request,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
+ // This should not be called if the frame is detached.
+ DCHECK(frame_);
+ frame_->UpdatePeakMemoryStats();
+
+ mojom::URLLoaderFactory* factory;
+ if (base::FeatureList::IsEnabled(features::kNetworkService)) {
+ factory = frame_->GetSubresourceLoaderFactories().GetFactoryForRequest(
+ request.Url());
+ } else {
+ factory = frame_->GetDefaultURLLoaderFactoryGetter()->GetFactoryForURL(
+ request.Url(), frame_->custom_url_loader_factory());
+ }
+ DCHECK(factory);
+
+ mojom::KeepAliveHandlePtr keep_alive_handle;
+ if (base::FeatureList::IsEnabled(
+ features::kKeepAliveRendererForKeepaliveRequests) &&
+ request.GetKeepalive()) {
+ frame_->GetFrameHost()->IssueKeepAliveHandle(
+ mojo::MakeRequest(&keep_alive_handle));
+ }
+ return std::make_unique<WebURLLoaderImpl>(
+ RenderThreadImpl::current()->resource_dispatcher(),
+ std::move(task_runner), factory, std::move(keep_alive_handle));
+ }
+
+ private:
+ base::WeakPtr<RenderFrameImpl> frame_;
+ scoped_refptr<ChildURLLoaderFactoryGetter> loader_factory_getter_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameURLLoaderFactory);
+};
+
// The following methods are outside of the anonymous namespace to ensure that
// the corresponding symbols get emmitted even on symbol_level 1.
NOINLINE void ExhaustMemory() {
@@ -760,45 +857,28 @@ NOINLINE void BadCastCrashIntentionally() {
NOINLINE void MaybeTriggerAsanError(const GURL& url) {
// NOTE(rogerm): We intentionally perform an invalid heap access here in
// order to trigger an Address Sanitizer (ASAN) error report.
- const char kCrashDomain[] = "crash";
- const char kHeapOverflow[] = "/heap-overflow";
- const char kHeapUnderflow[] = "/heap-underflow";
- const char kUseAfterFree[] = "/use-after-free";
-#if defined(SYZYASAN)
- const char kCorruptHeapBlock[] = "/corrupt-heap-block";
- const char kCorruptHeap[] = "/corrupt-heap";
- const char kDcheck[] = "/dcheck";
-#endif
-
- if (!url.DomainIs(kCrashDomain))
- return;
-
- if (!url.has_path())
- return;
-
- std::string crash_type(url.path());
- if (crash_type == kHeapOverflow) {
+ if (url == kChromeUICrashHeapOverflowURL) {
LOG(ERROR) << "Intentionally causing ASAN heap overflow"
<< " because user navigated to " << url.spec();
base::debug::AsanHeapOverflow();
- } else if (crash_type == kHeapUnderflow) {
+ } else if (url == kChromeUICrashHeapUnderflowURL) {
LOG(ERROR) << "Intentionally causing ASAN heap underflow"
<< " because user navigated to " << url.spec();
base::debug::AsanHeapUnderflow();
- } else if (crash_type == kUseAfterFree) {
+ } else if (url == kChromeUICrashUseAfterFreeURL) {
LOG(ERROR) << "Intentionally causing ASAN heap use-after-free"
<< " because user navigated to " << url.spec();
base::debug::AsanHeapUseAfterFree();
#if defined(SYZYASAN)
- } else if (crash_type == kCorruptHeapBlock) {
+ } else if (url == kChromeUICrashCorruptHeapBlockURL) {
LOG(ERROR) << "Intentionally causing ASAN corrupt heap block"
<< " because user navigated to " << url.spec();
base::debug::AsanCorruptHeapBlock();
- } else if (crash_type == kCorruptHeap) {
+ } else if (url == kChromeUICrashCorruptHeapURL) {
LOG(ERROR) << "Intentionally causing ASAN corrupt heap"
<< " because user navigated to " << url.spec();
base::debug::AsanCorruptHeap();
- } else if (crash_type == kDcheck) {
+ } else if (url == kChromeUICrashDcheckURL) {
LOG(ERROR) << "Intentionally DCHECKING because user navigated to "
<< url.spec();
@@ -808,9 +888,14 @@ NOINLINE void MaybeTriggerAsanError(const GURL& url) {
}
#endif // ADDRESS_SANITIZER || SYZYASAN
-void MaybeHandleDebugURL(const GURL& url) {
+// Returns true if the URL is a debug URL, false otherwise. These URLs do not
+// commit, though they are intentionally left in the address bar above the
+// effect they cause (e.g., a sad tab).
+bool MaybeHandleDebugURL(const GURL& url) {
if (!url.SchemeIs(kChromeUIScheme))
- return;
+ return false;
+ bool is_debug_url =
+ IsRendererDebugURL(url) && !url.SchemeIs(url::kJavaScriptScheme);
if (url == kChromeUIBadCastCrashURL) {
LOG(ERROR) << "Intentionally crashing (with bad cast)"
<< " because user navigated to " << url.spec();
@@ -853,6 +938,7 @@ void MaybeHandleDebugURL(const GURL& url) {
#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
MaybeTriggerAsanError(url);
#endif // ADDRESS_SANITIZER || SYZYASAN
+ return is_debug_url;
}
struct RenderFrameImpl::PendingFileChooser {
@@ -962,14 +1048,16 @@ blink::WebLocalFrame* RenderFrameImpl::UniqueNameFrameAdapter::GetWebFrame()
RenderFrameImpl* RenderFrameImpl::Create(
RenderViewImpl* render_view,
int32_t routing_id,
+ service_manager::mojom::InterfaceProviderPtr interface_provider,
const base::UnguessableToken& devtools_frame_token) {
DCHECK(routing_id != MSG_ROUTING_NONE);
- CreateParams params(render_view, routing_id, devtools_frame_token);
+ CreateParams params(render_view, routing_id, std::move(interface_provider),
+ devtools_frame_token);
if (g_create_render_frame_impl)
- return g_create_render_frame_impl(params);
+ return g_create_render_frame_impl(std::move(params));
else
- return new RenderFrameImpl(params);
+ return new RenderFrameImpl(std::move(params));
}
// static
@@ -983,13 +1071,14 @@ RenderFrameImpl* RenderFrameImpl::FromRoutingID(int routing_id) {
g_routing_id_frame_map.Get().find(routing_id);
if (iter != g_routing_id_frame_map.Get().end())
return iter->second;
- return NULL;
+ return nullptr;
}
// static
RenderFrameImpl* RenderFrameImpl::CreateMainFrame(
RenderViewImpl* render_view,
int32_t routing_id,
+ service_manager::mojom::InterfaceProviderPtr interface_provider,
int32_t widget_routing_id,
bool hidden,
const ScreenInfo& screen_info,
@@ -1000,8 +1089,9 @@ RenderFrameImpl* RenderFrameImpl::CreateMainFrame(
// A main frame RenderFrame must have a RenderWidget.
DCHECK_NE(MSG_ROUTING_NONE, widget_routing_id);
- RenderFrameImpl* render_frame =
- RenderFrameImpl::Create(render_view, routing_id, devtools_frame_token);
+ RenderFrameImpl* render_frame = RenderFrameImpl::Create(
+ render_view, routing_id, std::move(interface_provider),
+ devtools_frame_token);
render_frame->InitializeBlameContext(nullptr);
WebLocalFrame* web_frame = WebLocalFrame::CreateMainFrame(
render_view->webview(), render_frame,
@@ -1009,7 +1099,7 @@ RenderFrameImpl* RenderFrameImpl::CreateMainFrame(
// This conversion is a little sad, as this often comes from a
// WebString...
WebString::FromUTF8(replicated_state.name),
- replicated_state.sandbox_flags);
+ replicated_state.frame_policy.sandbox_flags);
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
@@ -1023,6 +1113,7 @@ RenderFrameImpl* RenderFrameImpl::CreateMainFrame(
// static
void RenderFrameImpl::CreateFrame(
int routing_id,
+ service_manager::mojom::InterfaceProviderPtr interface_provider,
int proxy_routing_id,
int opener_routing_id,
int parent_routing_id,
@@ -1056,17 +1147,18 @@ void RenderFrameImpl::CreateFrame(
previous_sibling_web_frame = previous_sibling_proxy->web_frame();
// Create the RenderFrame and WebLocalFrame, linking the two.
- render_frame = RenderFrameImpl::Create(parent_proxy->render_view(),
- routing_id, devtools_frame_token);
+ render_frame = RenderFrameImpl::Create(
+ parent_proxy->render_view(), routing_id, std::move(interface_provider),
+ devtools_frame_token);
render_frame->InitializeBlameContext(FromRoutingID(parent_routing_id));
render_frame->unique_name_helper_.set_propagated_name(
replicated_state.unique_name);
web_frame = parent_web_frame->CreateLocalChild(
replicated_state.scope, WebString::FromUTF8(replicated_state.name),
- replicated_state.sandbox_flags, render_frame,
+ replicated_state.frame_policy.sandbox_flags, render_frame,
render_frame->blink_interface_registry_.get(),
previous_sibling_web_frame,
- FeaturePolicyHeaderToWeb(replicated_state.container_policy),
+ replicated_state.frame_policy.container_policy,
ConvertFrameOwnerPropertiesToWebFrameOwnerProperties(
frame_owner_properties),
ResolveOpener(opener_routing_id));
@@ -1085,14 +1177,15 @@ void RenderFrameImpl::CreateFrame(
return;
render_frame = RenderFrameImpl::Create(proxy->render_view(), routing_id,
+ std::move(interface_provider),
devtools_frame_token);
render_frame->InitializeBlameContext(nullptr);
render_frame->proxy_routing_id_ = proxy_routing_id;
proxy->set_provisional_frame_routing_id(routing_id);
web_frame = blink::WebLocalFrame::CreateProvisional(
render_frame, render_frame->blink_interface_registry_.get(),
- proxy->web_frame(), replicated_state.sandbox_flags,
- FeaturePolicyHeaderToWeb(replicated_state.container_policy));
+ proxy->web_frame(), replicated_state.frame_policy.sandbox_flags,
+ replicated_state.frame_policy.container_policy);
}
CHECK(parent_routing_id != MSG_ROUTING_NONE || !web_frame->Parent());
@@ -1100,11 +1193,6 @@ void RenderFrameImpl::CreateFrame(
render_frame->render_widget_ = RenderWidget::CreateForFrame(
widget_params.routing_id, widget_params.hidden,
render_frame->render_view_->screen_info(), compositor_deps, web_frame);
- // TODO(avi): The main frame re-uses the RenderViewImpl as its widget, so
- // avoid double-registering the frame as an observer.
- // https://crbug.com/545684
- if (web_frame->Parent())
- render_frame->render_widget_->RegisterRenderFrame(render_frame);
}
render_frame->Initialize();
@@ -1140,7 +1228,7 @@ RenderFrameImpl* RenderFrameImpl::FromWebFrame(blink::WebFrame* web_frame) {
FrameMap::iterator iter = g_frame_map.Get().find(web_frame);
if (iter != g_frame_map.Get().end())
return iter->second;
- return NULL;
+ return nullptr;
}
// static
@@ -1175,9 +1263,25 @@ blink::WebURL RenderFrameImpl::OverrideFlashEmbedWithHTML(
return GetContentClient()->renderer()->OverrideFlashEmbedWithHTML(url);
}
+// RenderFrameImpl::CreateParams --------------------------------------------
+
+RenderFrameImpl::CreateParams::CreateParams(
+ RenderViewImpl* render_view,
+ int32_t routing_id,
+ service_manager::mojom::InterfaceProviderPtr interface_provider,
+ const base::UnguessableToken& devtools_frame_token)
+ : render_view(render_view),
+ routing_id(routing_id),
+ interface_provider(std::move(interface_provider)),
+ devtools_frame_token(devtools_frame_token) {}
+RenderFrameImpl::CreateParams::~CreateParams() = default;
+RenderFrameImpl::CreateParams::CreateParams(CreateParams&&) = default;
+RenderFrameImpl::CreateParams& RenderFrameImpl::CreateParams::operator=(
+ CreateParams&&) = default;
+
// RenderFrameImpl ----------------------------------------------------------
-RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
- : frame_(NULL),
+RenderFrameImpl::RenderFrameImpl(CreateParams params)
+ : frame_(nullptr),
is_main_frame_(true),
unique_name_frame_adapter_(this),
unique_name_helper_(&unique_name_frame_adapter_),
@@ -1194,13 +1298,12 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
selection_text_offset_(0),
selection_range_(gfx::Range::InvalidRange()),
handling_select_range_(false),
- web_user_media_client_(NULL),
+ web_user_media_client_(nullptr),
devtools_agent_(nullptr),
- presentation_dispatcher_(NULL),
- push_messaging_client_(NULL),
- screen_orientation_dispatcher_(NULL),
- manifest_manager_(NULL),
- render_accessibility_(NULL),
+ presentation_dispatcher_(nullptr),
+ push_messaging_client_(nullptr),
+ screen_orientation_dispatcher_(nullptr),
+ render_accessibility_(nullptr),
previews_state_(PREVIEWS_UNSPECIFIED),
effective_connection_type_(
blink::WebEffectiveConnectionType::kTypeUnknown),
@@ -1216,6 +1319,7 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
frame_binding_(this),
host_zoom_binding_(this),
frame_bindings_control_binding_(this),
+ frame_navigation_control_binding_(this),
has_accessed_initial_document_(false),
media_factory_(this,
base::Bind(&RenderFrameImpl::RequestOverlayRoutingToken,
@@ -1223,12 +1327,12 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
devtools_frame_token_(
blink::WebString::FromUTF8(params.devtools_frame_token.ToString())),
weak_factory_(this) {
- service_manager::mojom::InterfaceProviderPtr remote_interfaces;
- pending_remote_interface_provider_request_ = MakeRequest(&remote_interfaces);
- remote_interfaces_.reset(new service_manager::InterfaceProvider);
- remote_interfaces_->Bind(std::move(remote_interfaces));
- blink_interface_registry_.reset(
- new BlinkInterfaceRegistryImpl(registry_.GetWeakPtr()));
+ // The InterfaceProvider to access Mojo services exposed by the RFHI must be
+ // provided at construction time. See: https://crbug.com/729021/.
+ CHECK(params.interface_provider.is_bound());
+ remote_interfaces_.Bind(std::move(params.interface_provider));
+ blink_interface_registry_.reset(new BlinkInterfaceRegistryImpl(
+ registry_.GetWeakPtr(), associated_interfaces_.GetWeakPtr()));
// Must call after binding our own remote interfaces.
media_factory_.SetupMojo();
@@ -1239,8 +1343,6 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
RenderThread::Get()->AddRoute(routing_id_, this);
- render_view_->RegisterRenderFrame(this);
-
// Everything below subclasses RenderFrameObserver and is automatically
// deleted when the RenderFrame gets deleted.
#if defined(OS_ANDROID)
@@ -1252,7 +1354,7 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
plugin_power_saver_helper_ = new PluginPowerSaverHelper(this);
#endif
- manifest_manager_ = new ManifestManager(this);
+ manifest_manager_ = std::make_unique<ManifestManager>(this);
memset(&peak_memory_metrics_, 0,
sizeof(RenderThreadImpl::RendererMemoryMetrics));
}
@@ -1298,7 +1400,6 @@ RenderFrameImpl::~RenderFrameImpl() {
render_view_->main_render_frame_ = nullptr;
}
- render_view_->UnregisterRenderFrame(this);
g_routing_id_frame_map.Get().erase(routing_id_);
RenderThread::Get()->RemoveRoute(routing_id_);
}
@@ -1306,6 +1407,8 @@ RenderFrameImpl::~RenderFrameImpl() {
void RenderFrameImpl::Initialize() {
is_main_frame_ = !frame_->Parent();
+ GetRenderWidget()->RegisterRenderFrame(this);
+
RenderFrameImpl* parent_frame =
RenderFrameImpl::FromWebFrame(frame_->Parent());
if (parent_frame) {
@@ -1328,7 +1431,7 @@ void RenderFrameImpl::Initialize() {
new PepperBrowserConnection(this);
#endif
shared_worker_repository_ =
- base::MakeUnique<SharedWorkerRepository>(GetInterfaceProvider());
+ std::make_unique<SharedWorkerRepository>(GetInterfaceProvider());
GetWebFrame()->SetSharedWorkerRepositoryClient(
shared_worker_repository_.get());
@@ -1368,7 +1471,7 @@ void RenderFrameImpl::Initialize() {
void RenderFrameImpl::InitializeBlameContext(RenderFrameImpl* parent_frame) {
DCHECK(!blame_context_);
- blame_context_ = base::MakeUnique<FrameBlameContext>(this, parent_frame);
+ blame_context_ = std::make_unique<FrameBlameContext>(this, parent_frame);
blame_context_->Initialize();
}
@@ -1560,15 +1663,16 @@ void RenderFrameImpl::OnImeFinishComposingText(bool keep_selection) {
}
#endif // BUILDFLAG(ENABLE_PLUGINS)
-MediaStreamDispatcher* RenderFrameImpl::GetMediaStreamDispatcher() {
+MediaStreamDeviceObserver* RenderFrameImpl::GetMediaStreamDeviceObserver() {
if (!web_user_media_client_)
InitializeUserMediaClient();
return web_user_media_client_
- ? web_user_media_client_->media_stream_dispatcher()
+ ? web_user_media_client_->media_stream_device_observer()
: nullptr;
}
void RenderFrameImpl::ScriptedPrint(bool user_initiated) {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.ScriptedPrint");
for (auto& observer : observers_)
observer.ScriptedPrint(user_initiated);
}
@@ -1603,9 +1707,12 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
GetContentClient()->SetActiveURL(frame_->GetDocument().Url());
- for (auto& observer : observers_) {
- if (observer.OnMessageReceived(msg))
- return true;
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.OnMessageReceived");
+ for (auto& observer : observers_) {
+ if (observer.OnMessageReceived(msg))
+ return true;
+ }
}
bool handled = true;
@@ -1675,7 +1782,6 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
OnSnapshotAccessibilityTree)
IPC_MESSAGE_HANDLER(FrameMsg_ExtractSmartClipData, OnExtractSmartClipData)
IPC_MESSAGE_HANDLER(FrameMsg_UpdateOpener, OnUpdateOpener)
- IPC_MESSAGE_HANDLER(FrameMsg_CommitNavigation, OnCommitNavigation)
IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateFramePolicy, OnDidUpdateFramePolicy)
IPC_MESSAGE_HANDLER(FrameMsg_SetFrameOwnerProperties,
OnSetFrameOwnerProperties)
@@ -1743,8 +1849,13 @@ void RenderFrameImpl::OnNavigate(
DCHECK(!IsBrowserSideNavigationEnabled());
TRACE_EVENT2("navigation,rail", "RenderFrameImpl::OnNavigate", "id",
routing_id_, "url", common_params.url.possibly_invalid_spec());
+ if (devtools_agent_)
+ devtools_agent_->ContinueProgram();
NavigateInternal(common_params, start_params, request_params,
- std::unique_ptr<StreamOverrideParameters>());
+ std::unique_ptr<StreamOverrideParameters>(),
+ /*subresource_loader_factories=*/base::nullopt,
+ /* non-plznavigate navigations are not traced */
+ base::UnguessableToken::Create());
}
void RenderFrameImpl::BindEngagement(
@@ -1759,13 +1870,9 @@ void RenderFrameImpl::BindMediaEngagement(
void RenderFrameImpl::BindFrame(
const service_manager::BindSourceInfo& browser_info,
- mojom::FrameRequest request,
- mojom::FrameHostInterfaceBrokerPtr frame_host_interface_broker) {
+ mojom::FrameRequest request) {
browser_info_ = browser_info;
frame_binding_.Bind(std::move(request));
- frame_host_interface_broker_ = std::move(frame_host_interface_broker);
- frame_host_interface_broker_->GetInterfaceProvider(
- std::move(pending_remote_interface_provider_request_));
}
void RenderFrameImpl::BindFrameBindingsControl(
@@ -1773,8 +1880,13 @@ void RenderFrameImpl::BindFrameBindingsControl(
frame_bindings_control_binding_.Bind(std::move(request));
}
-ManifestManager* RenderFrameImpl::manifest_manager() {
- return manifest_manager_;
+void RenderFrameImpl::BindFrameNavigationControl(
+ mojom::FrameNavigationControlAssociatedRequest request) {
+ frame_navigation_control_binding_.Bind(std::move(request));
+}
+
+blink::mojom::ManifestManager& RenderFrameImpl::GetManifestManager() {
+ return *manifest_manager_;
}
void RenderFrameImpl::SetPendingNavigationParams(
@@ -1808,7 +1920,7 @@ void RenderFrameImpl::OnSwapOut(
const FrameReplicationState& replicated_frame_state) {
TRACE_EVENT1("navigation,rail", "RenderFrameImpl::OnSwapOut",
"id", routing_id_);
- RenderFrameProxy* proxy = NULL;
+ RenderFrameProxy* proxy = nullptr;
// Swap this RenderFrame out so the frame can navigate to a page rendered by
// a different process. This involves running the unload handler and
@@ -1939,9 +2051,7 @@ void RenderFrameImpl::OnMoveCaret(const gfx::Point& point) {
void RenderFrameImpl::OnScrollFocusedEditableNodeIntoRect(
const gfx::Rect& rect) {
- // TODO(dtapuska): Move the implementation of scroll focused
- // editable node into rect into this class.
- render_view_->ScrollFocusedEditableNodeIntoRect(rect);
+ ScrollFocusedEditableElementIntoRect(rect);
}
void RenderFrameImpl::OnUndo() {
@@ -1984,8 +2094,9 @@ void RenderFrameImpl::OnCopyToFindPboard() {
// than the |OnCopy()| case.
if (frame_->HasSelection()) {
base::string16 selection = frame_->SelectionAsText().Utf16();
- RenderThread::Get()->Send(
- new ClipboardHostMsg_FindPboardWriteStringAsync(selection));
+ RenderThreadImpl::current_blink_platform_impl()
+ ->GetClipboardHost()
+ .WriteStringToFindPboard(selection);
}
}
#endif
@@ -2189,10 +2300,10 @@ void RenderFrameImpl::JavaScriptIsolatedWorldRequest::Completed(
std::unique_ptr<base::Value> result_value(
converter.FromV8Value(value, context));
list.Append(result_value ? std::move(result_value)
- : base::MakeUnique<base::Value>());
+ : std::make_unique<base::Value>());
}
} else {
- list.Set(0, base::MakeUnique<base::Value>());
+ list.Set(0, std::make_unique<base::Value>());
}
render_frame_impl_.get()->Send(
new FrameHostMsg_JavaScriptExecuteResponse(routing_id_, id_, list));
@@ -2217,9 +2328,9 @@ void RenderFrameImpl::HandleJavascriptExecutionResult(
std::unique_ptr<base::Value> result_value(
converter.FromV8Value(result, context));
list.Set(0, result_value ? std::move(result_value)
- : base::MakeUnique<base::Value>());
+ : std::make_unique<base::Value>());
} else {
- list.Set(0, base::MakeUnique<base::Value>());
+ list.Set(0, std::make_unique<base::Value>());
}
Send(new FrameHostMsg_JavaScriptExecuteResponse(routing_id_, id, list));
}
@@ -2311,10 +2422,9 @@ void RenderFrameImpl::OnUpdateOpener(int opener_routing_id) {
}
void RenderFrameImpl::OnDidUpdateFramePolicy(
- blink::WebSandboxFlags flags,
- const ParsedFeaturePolicyHeader& container_policy) {
- frame_->SetFrameOwnerPolicy(flags,
- FeaturePolicyHeaderToWeb(container_policy));
+ const blink::FramePolicy& frame_policy) {
+ frame_->SetFrameOwnerPolicy(frame_policy.sandbox_flags,
+ frame_policy.container_policy);
}
void RenderFrameImpl::OnSetFrameOwnerProperties(
@@ -2383,7 +2493,7 @@ void RenderFrameImpl::OnTextTrackSettingsChanged(
void RenderFrameImpl::OnPostMessageEvent(
const FrameMsg_PostMessage_Params& params) {
// Find the source frame if it exists.
- WebFrame* source_frame = NULL;
+ WebFrame* source_frame = nullptr;
if (params.source_routing_id != MSG_ROUTING_NONE) {
RenderFrameProxy* source_proxy =
RenderFrameProxy::FromRoutingID(params.source_routing_id);
@@ -2504,7 +2614,7 @@ bool RenderFrameImpl::ScheduleFileChooser(
}
file_chooser_completions_.push_back(
- base::MakeUnique<PendingFileChooser>(params, completion));
+ std::make_unique<PendingFileChooser>(params, completion));
if (file_chooser_completions_.size() == 1) {
// Actually show the browse dialog when this is the first request.
Send(new FrameHostMsg_RunFileChooser(routing_id_, params));
@@ -2512,23 +2622,80 @@ bool RenderFrameImpl::ScheduleFileChooser(
return true;
}
+void RenderFrameImpl::DidFailProvisionalLoadInternal(
+ const WebURLError& error,
+ blink::WebHistoryCommitType commit_type,
+ const base::Optional<std::string>& error_page_content) {
+ 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);
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidFailProvisionalLoad");
+ for (auto& observer : observers_)
+ observer.DidFailProvisionalLoad(error);
+ }
+
+ WebDocumentLoader* document_loader = frame_->GetProvisionalDocumentLoader();
+ if (!document_loader)
+ return;
+
+ const WebURLRequest& failed_request = document_loader->GetRequest();
+
+ // Notify the browser that we failed a provisional load with an error.
+ SendFailedProvisionalLoad(failed_request, error, frame_);
+
+ if (!ShouldDisplayErrorPageForFailedLoad(error.reason(), error.url()))
+ return;
+
+ // Make sure we never show errors in view source mode.
+ frame_->EnableViewSourceMode(false);
+
+ DocumentState* document_state =
+ DocumentState::FromDocumentLoader(document_loader);
+ NavigationStateImpl* navigation_state =
+ static_cast<NavigationStateImpl*>(document_state->navigation_state());
+
+ // 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.
+ // Otherwise, we do a normal load, which simulates a 'go' navigation as far
+ // as session history is concerned.
+ bool replace = commit_type != blink::kWebStandardCommit;
+
+ // 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 NavigationParams(
+ navigation_state->common_params(), navigation_state->start_params(),
+ navigation_state->request_params()));
+ }
+
+ // Load an error page.
+ LoadNavigationErrorPage(failed_request, error, replace, nullptr,
+ error_page_content);
+}
+
void RenderFrameImpl::LoadNavigationErrorPage(
const WebURLRequest& failed_request,
const WebURLError& error,
bool replace,
- HistoryEntry* entry) {
+ HistoryEntry* entry,
+ const base::Optional<std::string>& error_page_content) {
blink::WebFrameLoadType frame_load_type =
entry ? blink::WebFrameLoadType::kBackForward
: blink::WebFrameLoadType::kStandard;
const blink::WebHistoryItem& history_item =
entry ? entry->root() : blink::WebHistoryItem();
- DCHECK_EQ(WebURLError::Domain::kNet, error.domain);
// Requests blocked by the X-Frame-Options HTTP response header don't display
// error pages but a blank page instead.
// TODO(alexmos, mkwst, arthursonzogni): This block can be removed once error
// pages are refactored. See crbug.com/588314 and crbug.com/622385.
- if (error.reason == net::ERR_BLOCKED_BY_RESPONSE) {
+ if (error.reason() == net::ERR_BLOCKED_BY_RESPONSE) {
// Do not preserve the history item for blocked navigations, since we will
// not attempt to reload it later. Also, it is important that the document
// sequence number is not preserved, so that other navigations will not be
@@ -2541,11 +2708,15 @@ void RenderFrameImpl::LoadNavigationErrorPage(
}
std::string error_html;
- GetContentClient()->renderer()->GetNavigationErrorStrings(
- this, failed_request, error, &error_html, nullptr);
+ if (error_page_content.has_value()) {
+ error_html = error_page_content.value();
+ } else {
+ GetContentClient()->renderer()->GetNavigationErrorStrings(
+ this, failed_request, error, &error_html, nullptr);
+ }
LoadNavigationErrorPageInternal(error_html, GURL(kUnreachableWebDataURL),
- error.unreachable_url, replace,
- frame_load_type, history_item);
+ error.url(), replace, frame_load_type,
+ history_item);
}
void RenderFrameImpl::LoadNavigationErrorPageForHttpStatusError(
@@ -2583,6 +2754,7 @@ void RenderFrameImpl::LoadNavigationErrorPageInternal(
void RenderFrameImpl::DidMeaningfulLayout(
blink::WebMeaningfulLayout layout_type) {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidMeaningfulLayout");
for (auto& observer : observers_)
observer.DidMeaningfulLayout(layout_type);
}
@@ -2695,10 +2867,7 @@ blink::WebPlugin* RenderFrameImpl::CreatePlugin(
}
void RenderFrameImpl::LoadErrorPage(int reason) {
- blink::WebURLError error;
- error.unreachable_url = frame_->GetDocument().Url();
- error.domain = blink::WebURLError::Domain::kNet;
- error.reason = reason;
+ WebURLError error(reason, frame_->GetDocument().Url());
std::string error_html;
GetContentClient()->renderer()->GetNavigationErrorStrings(
@@ -2707,8 +2876,8 @@ void RenderFrameImpl::LoadErrorPage(int reason) {
frame_->LoadData(error_html, WebString::FromUTF8("text/html"),
WebString::FromUTF8("UTF-8"), GURL(kUnreachableWebDataURL),
- error.unreachable_url, true,
- blink::WebFrameLoadType::kStandard, blink::WebHistoryItem(),
+ error.url(), true, blink::WebFrameLoadType::kStandard,
+ blink::WebHistoryItem(),
blink::kWebHistoryDifferentDocumentLoad, true);
}
@@ -2723,15 +2892,15 @@ void RenderFrameImpl::BindLocalInterface(
}
service_manager::InterfaceProvider* RenderFrameImpl::GetRemoteInterfaces() {
- return remote_interfaces_.get();
+ return &remote_interfaces_;
}
-AssociatedInterfaceRegistry*
+blink::AssociatedInterfaceRegistry*
RenderFrameImpl::GetAssociatedInterfaceRegistry() {
return &associated_interfaces_;
}
-AssociatedInterfaceProvider*
+blink::AssociatedInterfaceProvider*
RenderFrameImpl::GetRemoteAssociatedInterfaces() {
if (!remote_associated_interfaces_) {
ChildThreadImpl* thread = ChildThreadImpl::current();
@@ -2823,8 +2992,7 @@ void RenderFrameImpl::EnsureMojoBuiltinsAreAvailable(
mojo::edk::js::Support::GetModule(isolate));
registry->AddBuiltinModule(
isolate, InterfaceProviderJsWrapper::kPerFrameModuleName,
- InterfaceProviderJsWrapper::Create(
- isolate, context, remote_interfaces_.get())
+ InterfaceProviderJsWrapper::Create(isolate, context, &remote_interfaces_)
.ToV8());
registry->AddBuiltinModule(
isolate, InterfaceProviderJsWrapper::kPerProcessModuleName,
@@ -2917,6 +3085,13 @@ void RenderFrameImpl::GetInterfaceProvider(
browser_info_.identity, std::move(request),
std::move(provider));
}
+void RenderFrameImpl::GetCanonicalUrlForSharing(
+ GetCanonicalUrlForSharingCallback callback) {
+ WebURL canonical_url = GetWebFrame()->GetDocument().CanonicalUrlForSharing();
+ std::move(callback).Run(canonical_url.IsNull()
+ ? base::nullopt
+ : base::make_optional(GURL(canonical_url)));
+}
void RenderFrameImpl::AllowBindings(int32_t enabled_bindings_flags) {
if (IsMainFrame() && (enabled_bindings_flags & BINDINGS_POLICY_WEB_UI) &&
@@ -2930,8 +3105,68 @@ void RenderFrameImpl::AllowBindings(int32_t enabled_bindings_flags) {
// Keep track of the total bindings accumulated in this process.
RenderProcess::current()->AddBindings(enabled_bindings_flags);
+}
- MaybeEnableMojoBindings();
+// mojom::FrameNavigationControl implementation --------------------------------
+
+void RenderFrameImpl::CommitNavigation(
+ const ResourceResponseHead& head,
+ const GURL& body_url,
+ const CommonNavigationParams& common_params,
+ const RequestNavigationParams& request_params,
+ mojo::ScopedDataPipeConsumerHandle body_data,
+ base::Optional<URLLoaderFactoryBundle> subresource_loader_factories,
+ const base::UnguessableToken& devtools_navigation_token) {
+ CHECK(IsBrowserSideNavigationEnabled());
+ // If this was a renderer-initiated navigation (nav_entry_id == 0) from this
+ // frame, but it was aborted, then ignore it.
+ if (!browser_side_navigation_pending_ &&
+ !browser_side_navigation_pending_url_.is_empty() &&
+ browser_side_navigation_pending_url_ == request_params.original_url &&
+ request_params.nav_entry_id == 0) {
+ browser_side_navigation_pending_url_ = GURL();
+ return;
+ }
+
+ // This will override the url requested by the WebURLLoader, as well as
+ // provide it with the response to the request.
+ std::unique_ptr<StreamOverrideParameters> stream_override(
+ new StreamOverrideParameters());
+ stream_override->stream_url = body_url;
+ stream_override->consumer_handle = std::move(body_data);
+ stream_override->response = head;
+ stream_override->redirects = request_params.redirects;
+ stream_override->redirect_responses = request_params.redirect_response;
+ stream_override->redirect_infos = request_params.redirect_infos;
+
+ // Used to notify the browser that it can release its |stream_handle_| when
+ // the |stream_override| object isn't used anymore.
+ // TODO(clamy): Remove this when we switch to Mojo streams.
+ stream_override->on_delete = base::BindOnce(
+ [](base::WeakPtr<RenderFrameImpl> weak_self, const GURL& url) {
+ if (RenderFrameImpl* self = weak_self.get()) {
+ self->Send(
+ new FrameHostMsg_StreamHandleConsumed(self->routing_id_, url));
+ }
+ },
+ weak_factory_.GetWeakPtr());
+
+ // 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(
+ common_params.has_user_gesture ? new blink::WebScopedUserGesture(frame_)
+ : nullptr);
+
+ browser_side_navigation_pending_ = false;
+ browser_side_navigation_pending_url_ = GURL();
+
+ NavigateInternal(common_params, StartNavigationParams(), request_params,
+ std::move(stream_override),
+ std::move(subresource_loader_factories),
+ devtools_navigation_token);
+
+ // Don't add code after this since NavigateInternal may have destroyed this
+ // RenderFrameImpl.
}
// mojom::HostZoom implementation ----------------------------------------------
@@ -2995,8 +3230,11 @@ blink::WebMediaPlayer* RenderFrameImpl::CreateMediaPlayer(
WebContentDecryptionModule* initial_cdm,
const blink::WebString& sink_id,
blink::WebLayerTreeView* layer_tree_view) {
- return media_factory_.CreateMediaPlayer(
- source, client, encrypted_client, initial_cdm, sink_id, layer_tree_view);
+ const cc::LayerTreeSettings& settings =
+ GetRenderWidget()->compositor()->GetLayerTreeSettings();
+ return media_factory_.CreateMediaPlayer(source, client, encrypted_client,
+ initial_cdm, sink_id, layer_tree_view,
+ settings);
}
std::unique_ptr<blink::WebApplicationCacheHost>
@@ -3014,7 +3252,7 @@ RenderFrameImpl::CreateApplicationCacheHost(
NavigationStateImpl* navigation_state =
static_cast<NavigationStateImpl*>(document_state->navigation_state());
- return base::MakeUnique<RendererWebApplicationCacheHostImpl>(
+ return std::make_unique<RendererWebApplicationCacheHostImpl>(
RenderViewImpl::FromWebView(frame_->View()), client,
RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy(),
navigation_state->request_params().appcache_host_id, routing_id_);
@@ -3038,19 +3276,29 @@ RenderFrameImpl::CreateWorkerFetchContext() {
ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider(
web_provider);
mojom::ServiceWorkerWorkerClientRequest service_worker_client_request;
+ mojom::ServiceWorkerContainerHostPtrInfo container_host_ptr_info;
+ ServiceWorkerProviderContext* provider_context = provider->context();
// Some sandboxed iframes are not allowed to use service worker so don't have
// a real service worker provider, so the provider context is null.
- if (provider->context()) {
+ if (provider_context) {
service_worker_client_request =
- provider->context()->CreateWorkerClientRequest();
+ provider_context->CreateWorkerClientRequest();
+ // 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 (ServiceWorkerUtils::IsServicificationEnabled())
+ container_host_ptr_info = provider_context->CloneContainerHostPtrInfo();
}
ChildURLLoaderFactoryGetter* url_loader_factory_getter =
GetDefaultURLLoaderFactoryGetter();
DCHECK(url_loader_factory_getter);
std::unique_ptr<WorkerFetchContextImpl> worker_fetch_context =
- base::MakeUnique<WorkerFetchContextImpl>(
+ std::make_unique<WorkerFetchContextImpl>(
std::move(service_worker_client_request),
+ std::move(container_host_ptr_info),
url_loader_factory_getter->GetClonedInfo());
worker_fetch_context->set_parent_frame_id(routing_id_);
@@ -3058,12 +3306,17 @@ RenderFrameImpl::CreateWorkerFetchContext() {
frame_->GetDocument().SiteForCookies());
worker_fetch_context->set_is_secure_context(
frame_->GetDocument().IsSecureContext());
- worker_fetch_context->set_service_worker_provider_id(
- provider->provider_id());
- worker_fetch_context->set_is_controlled_by_service_worker(
- provider->IsControlledByServiceWorker());
- for (auto& observer : observers_)
- observer.WillCreateWorkerFetchContext(worker_fetch_context.get());
+ worker_fetch_context->set_service_worker_provider_id(provider->provider_id());
+ worker_fetch_context->set_is_controlled_by_service_worker(
+ provider->IsControlledByServiceWorker());
+ worker_fetch_context->set_origin_url(
+ GURL(frame_->GetDocument().Url()).GetOrigin());
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER(
+ "RenderFrameObservers.WillCreateWorkerFetchContext");
+ for (auto& observer : observers_)
+ observer.WillCreateWorkerFetchContext(worker_fetch_context.get());
+ }
return std::move(worker_fetch_context);
}
@@ -3088,7 +3341,7 @@ WebExternalPopupMenu* RenderFrameImpl::CreateExternalPopupMenu(
}
return external_popup_menu_.get();
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -3114,13 +3367,17 @@ RenderFrameImpl::CreateServiceWorkerProvider() {
// The context can be null when the frame is sandboxed.
return nullptr;
}
- return base::MakeUnique<WebServiceWorkerProviderImpl>(
+ return std::make_unique<WebServiceWorkerProviderImpl>(
ChildThreadImpl::current()->thread_safe_sender(), provider->context());
}
service_manager::InterfaceProvider* RenderFrameImpl::GetInterfaceProvider() {
- DCHECK(remote_interfaces_);
- return remote_interfaces_.get();
+ return &remote_interfaces_;
+}
+
+blink::AssociatedInterfaceProvider*
+RenderFrameImpl::GetRemoteNavigationAssociatedInterfaces() {
+ return GetRemoteAssociatedInterfaces();
}
void RenderFrameImpl::DidAccessInitialDocument() {
@@ -3151,13 +3408,14 @@ blink::WebLocalFrame* RenderFrameImpl::CreateChildFrame(
const blink::WebString& name,
const blink::WebString& fallback_name,
blink::WebSandboxFlags sandbox_flags,
- const blink::WebParsedFeaturePolicy& container_policy,
+ const blink::ParsedFeaturePolicy& container_policy,
const blink::WebFrameOwnerProperties& frame_owner_properties) {
DCHECK_EQ(frame_, parent);
// Synchronously notify the browser of a child frame creation to get the
// routing_id for the RenderFrame.
int child_routing_id = MSG_ROUTING_NONE;
+ mojo::MessagePipeHandle child_interface_provider_handle;
base::UnguessableToken devtools_frame_token;
FrameHostMsg_CreateChildFrame_Params params;
params.parent_routing_id = routing_id_;
@@ -3177,14 +3435,17 @@ blink::WebLocalFrame* RenderFrameImpl::CreateChildFrame(
// Note that Blink can't be changed to just pass |fallback_name| as |name| in
// the case |name| is empty: |fallback_name| should never affect the actual
// browsing context name, only unique name generation.
+ params.is_created_by_script =
+ v8::Isolate::GetCurrent() && v8::Isolate::GetCurrent()->InContext();
params.frame_unique_name = unique_name_helper_.GenerateNameForNewChildFrame(
- params.frame_name.empty() ? fallback_name.Utf8() : params.frame_name);
- params.sandbox_flags = sandbox_flags;
- params.container_policy = FeaturePolicyHeaderFromWeb(container_policy);
+ params.frame_name.empty() ? fallback_name.Utf8() : params.frame_name,
+ params.is_created_by_script);
+ params.frame_policy = {sandbox_flags, container_policy};
params.frame_owner_properties =
ConvertWebFrameOwnerPropertiesToFrameOwnerProperties(
frame_owner_properties);
Send(new FrameHostMsg_CreateChildFrame(params, &child_routing_id,
+ &child_interface_provider_handle,
&devtools_frame_token));
// Allocation of routing id failed, so we can't create a child frame. This can
@@ -3194,6 +3455,12 @@ blink::WebLocalFrame* RenderFrameImpl::CreateChildFrame(
if (child_routing_id == MSG_ROUTING_NONE)
return nullptr;
+ CHECK(child_interface_provider_handle.is_valid());
+ service_manager::mojom::InterfaceProviderPtr child_interface_provider;
+ child_interface_provider.Bind(
+ service_manager::mojom::InterfaceProviderPtrInfo(
+ mojo::ScopedMessagePipeHandle(child_interface_provider_handle), 0u));
+
// This method is always called by local frames, never remote frames.
// Tracing analysis uses this to find main frames when this value is
@@ -3204,9 +3471,12 @@ blink::WebLocalFrame* RenderFrameImpl::CreateChildFrame(
// Create the RenderFrame and WebLocalFrame, linking the two.
RenderFrameImpl* child_render_frame = RenderFrameImpl::Create(
- render_view_, child_routing_id, devtools_frame_token);
+ render_view_, child_routing_id, std::move(child_interface_provider),
+ devtools_frame_token);
child_render_frame->unique_name_helper_.set_propagated_name(
params.frame_unique_name);
+ if (params.is_created_by_script)
+ child_render_frame->unique_name_helper_.Freeze();
child_render_frame->InitializeBlameContext(this);
blink::WebLocalFrame* web_frame = parent->CreateLocalChild(
scope, child_render_frame,
@@ -3242,10 +3512,9 @@ void RenderFrameImpl::FrameDetached(DetachType type) {
Send(new FrameHostMsg_Detach(routing_id_));
// Clean up the associated RenderWidget for the frame, if there is one.
- if (render_widget_) {
- render_widget_->UnregisterRenderFrame(this);
+ GetRenderWidget()->UnregisterRenderFrame(this);
+ if (render_widget_)
render_widget_->CloseForFrame();
- }
// We need to clean up subframes by removing them from the map and deleting
// the RenderFrameImpl. In contrast, the main frame is owned by its
@@ -3286,6 +3555,7 @@ void RenderFrameImpl::FrameFocused() {
}
void RenderFrameImpl::WillCommitProvisionalLoad() {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.WillCommitProvisionalLoad");
for (auto& observer : observers_)
observer.WillCommitProvisionalLoad();
}
@@ -3317,16 +3587,21 @@ void RenderFrameImpl::DidUpdateToUniqueOrigin(
void RenderFrameImpl::DidChangeFramePolicy(
blink::WebFrame* child_frame,
blink::WebSandboxFlags flags,
- const blink::WebParsedFeaturePolicy& container_policy) {
+ const blink::ParsedFeaturePolicy& container_policy) {
Send(new FrameHostMsg_DidChangeFramePolicy(
- routing_id_, RenderFrame::GetRoutingIdForWebFrame(child_frame), flags,
- FeaturePolicyHeaderFromWeb(container_policy)));
+ routing_id_, RenderFrame::GetRoutingIdForWebFrame(child_frame),
+ {flags, container_policy}));
}
-void RenderFrameImpl::DidSetFeaturePolicyHeader(
- const blink::WebParsedFeaturePolicy& parsed_header) {
- Send(new FrameHostMsg_DidSetFeaturePolicyHeader(
- routing_id_, FeaturePolicyHeaderFromWeb(parsed_header)));
+void RenderFrameImpl::DidSetFramePolicyHeaders(
+ blink::WebSandboxFlags flags,
+ const blink::ParsedFeaturePolicy& parsed_header) {
+ // If either Feature Policy or Sandbox Flags are different from the default
+ // (empty) values, then send them to the browser.
+ if (!parsed_header.empty() || flags != blink::WebSandboxFlags::kNone) {
+ Send(new FrameHostMsg_DidSetFramePolicyHeaders(routing_id_, flags,
+ parsed_header));
+ }
}
void RenderFrameImpl::DidAddContentSecurityPolicies(
@@ -3415,6 +3690,7 @@ void RenderFrameImpl::DownloadURL(const blink::WebURLRequest& request,
}
void RenderFrameImpl::WillSendSubmitEvent(const blink::WebFormElement& form) {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.WillSendSubmitEvent");
for (auto& observer : observers_)
observer.WillSendSubmitEvent(form);
}
@@ -3438,8 +3714,11 @@ void RenderFrameImpl::WillSubmitForm(const blink::WebFormElement& form) {
internal_data->set_searchable_form_encoding(
web_searchable_form_data.Encoding().Utf8());
- for (auto& observer : observers_)
- observer.WillSubmitForm(form);
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.WillSubmitForm");
+ for (auto& observer : observers_)
+ observer.WillSubmitForm(form);
+ }
}
void RenderFrameImpl::DidCreateDocumentLoader(
@@ -3581,10 +3860,11 @@ void RenderFrameImpl::DidStartProvisionalLoad(
document_state->navigation_state());
bool is_top_most = !frame_->Parent();
if (is_top_most) {
- render_view_->set_navigation_gesture(
- WebUserGestureIndicator::IsProcessingUserGesture()
+ auto navigation_gesture =
+ WebUserGestureIndicator::IsProcessingUserGesture(frame_)
? NavigationGestureUser
- : NavigationGestureAuto);
+ : 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
@@ -3596,12 +3876,18 @@ void RenderFrameImpl::DidStartProvisionalLoad(
navigation_state->common_params().navigation_start;
DCHECK(!navigation_start.is_null());
- for (auto& observer : observers_)
- observer.DidStartProvisionalLoad(document_loader);
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidStartProvisionalLoad");
+ for (auto& observer : observers_)
+ observer.DidStartProvisionalLoad(document_loader);
+ }
std::vector<GURL> redirect_chain;
GetRedirectChain(document_loader, &redirect_chain);
+ if (ConsumeGestureOnNavigation())
+ WebUserGestureIndicator::ConsumeUserGesture(frame_);
+
Send(new FrameHostMsg_DidStartProvisionalLoad(
routing_id_, document_loader->GetRequest().Url(), redirect_chain,
navigation_start));
@@ -3613,55 +3899,9 @@ void RenderFrameImpl::DidReceiveServerRedirectForProvisionalLoad() {
}
void RenderFrameImpl::DidFailProvisionalLoad(
- const blink::WebURLError& error,
+ const WebURLError& error,
blink::WebHistoryCommitType commit_type) {
- 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);
-
- WebDocumentLoader* document_loader = frame_->GetProvisionalDocumentLoader();
- if (!document_loader)
- return;
-
- const WebURLRequest& failed_request = document_loader->GetRequest();
-
- // Notify the browser that we failed a provisional load with an error.
- SendFailedProvisionalLoad(failed_request, error, frame_);
-
- if (!ShouldDisplayErrorPageForFailedLoad(error.reason, error.unreachable_url))
- return;
-
- // Make sure we never show errors in view source mode.
- frame_->EnableViewSourceMode(false);
-
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(document_loader);
- NavigationStateImpl* navigation_state =
- static_cast<NavigationStateImpl*>(document_state->navigation_state());
-
- // 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.
- // Otherwise, we do a normal load, which simulates a 'go' navigation as far
- // as session history is concerned.
- bool replace = commit_type != blink::kWebStandardCommit;
-
- // 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 NavigationParams(
- navigation_state->common_params(), navigation_state->start_params(),
- navigation_state->request_params()));
- }
-
- // Load an error page.
- LoadNavigationErrorPage(failed_request, error, replace, nullptr);
+ DidFailProvisionalLoadInternal(error, commit_type, base::nullopt);
}
void RenderFrameImpl::DidCommitProvisionalLoad(
@@ -3741,9 +3981,18 @@ void RenderFrameImpl::DidCommitProvisionalLoad(
// Navigations that change the document represent a new content source. Keep
// track of that on the widget to help the browser process detect when stale
// compositor frames are being shown after a commit.
- if (is_main_frame_ && !navigation_state->WasWithinSameDocument())
+ if (is_main_frame_ && !navigation_state->WasWithinSameDocument()) {
GetRenderWidget()->IncrementContentSourceId();
+ // Update the URL used to key Ukm metrics in the compositor if the
+ // navigation is not in the same document, which represents a new source
+ // URL.
+ // Note that this is only done for the main frame since the metrics for all
+ // frames are keyed to the main frame's URL.
+ if (GetRenderWidget()->compositor())
+ GetRenderWidget()->compositor()->SetURLForUkm(GetLoadingUrl());
+ }
+
// When we perform a new navigation, we need to update the last committed
// session history entry with state for the page we are leaving. Do this
// before updating the current history item.
@@ -3788,11 +4037,17 @@ void RenderFrameImpl::DidCommitProvisionalLoad(
}
}
+ if (commit_type == blink::WebHistoryCommitType::kWebBackForwardCommit)
+ render_view_->DidCommitProvisionalHistoryLoad();
+
for (auto& observer : render_view_->observers_)
observer.DidCommitProvisionalLoad(frame_, is_new_navigation);
- for (auto& observer : observers_) {
- observer.DidCommitProvisionalLoad(
- is_new_navigation, navigation_state->WasWithinSameDocument());
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidCommitProvisionalLoad");
+ for (auto& observer : observers_) {
+ observer.DidCommitProvisionalLoad(
+ is_new_navigation, navigation_state->WasWithinSameDocument());
+ }
}
// Notify the MediaPermissionDispatcher that its connection will be closed
@@ -3850,8 +4105,11 @@ void RenderFrameImpl::DidClearWindowObject() {
for (auto& observer : render_view_->observers())
observer.DidClearWindowObject(frame_);
- for (auto& observer : observers_)
- observer.DidClearWindowObject();
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidClearWindowObject");
+ for (auto& observer : observers_)
+ observer.DidClearWindowObject();
+ }
}
void RenderFrameImpl::DidCreateDocumentElement() {
@@ -3876,16 +4134,6 @@ void RenderFrameImpl::DidCreateDocumentElement() {
}
void RenderFrameImpl::RunScriptsAtDocumentElementAvailable() {
- base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr();
-
- MojoBindingsController* mojo_bindings_controller =
- MojoBindingsController::Get(this);
- if (mojo_bindings_controller)
- mojo_bindings_controller->RunScriptsAtDocumentStart();
-
- if (!weak_self.get())
- return;
-
GetContentClient()->renderer()->RunScriptsAtDocumentStart(this);
// Do not use |this|! ContentClient might have deleted them by now!
}
@@ -3937,8 +4185,11 @@ void RenderFrameImpl::DidFinishDocumentLoad() {
"RenderFrameImpl::didFinishDocumentLoad", "id", routing_id_);
Send(new FrameHostMsg_DidFinishDocumentLoad(routing_id_));
- for (auto& observer : observers_)
- observer.DidFinishDocumentLoad();
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidFinishDocumentLoad");
+ for (auto& observer : observers_)
+ observer.DidFinishDocumentLoad();
+ }
// Check whether we have new encoding name.
UpdateEncoding(frame_, frame_->View()->PageEncoding().Utf8());
@@ -3947,14 +4198,6 @@ void RenderFrameImpl::DidFinishDocumentLoad() {
void RenderFrameImpl::RunScriptsAtDocumentReady(bool document_is_empty) {
base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr();
- MojoBindingsController* mojo_bindings_controller =
- MojoBindingsController::Get(this);
- if (mojo_bindings_controller)
- mojo_bindings_controller->RunScriptsAtDocumentReady();
-
- if (!weak_self.get())
- return;
-
GetContentClient()->renderer()->RunScriptsAtDocumentEnd(this);
// ContentClient might have deleted |frame_| and |this| by now!
@@ -4008,7 +4251,7 @@ void RenderFrameImpl::DidHandleOnloadEvents() {
}
}
-void RenderFrameImpl::DidFailLoad(const blink::WebURLError& error,
+void RenderFrameImpl::DidFailLoad(const WebURLError& error,
blink::WebHistoryCommitType commit_type) {
TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didFailLoad",
"id", routing_id_);
@@ -4024,8 +4267,8 @@ void RenderFrameImpl::DidFailLoad(const blink::WebURLError& error,
error,
nullptr,
&error_description);
- Send(new FrameHostMsg_DidFailLoadWithError(routing_id_, failed_request.Url(),
- error.reason, error_description));
+ Send(new FrameHostMsg_DidFailLoadWithError(
+ routing_id_, failed_request.Url(), error.reason(), error_description));
}
void RenderFrameImpl::DidFinishLoad() {
@@ -4036,76 +4279,31 @@ void RenderFrameImpl::DidFinishLoad() {
TRACE_EVENT_SCOPE_PROCESS);
}
- for (auto& observer : observers_)
- observer.DidFinishLoad();
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidFinishLoad");
+ for (auto& observer : observers_)
+ observer.DidFinishLoad();
+ }
WebDocumentLoader* document_loader = frame_->GetDocumentLoader();
Send(new FrameHostMsg_DidFinishLoad(routing_id_,
document_loader->GetRequest().Url()));
ReportPeakMemoryStats();
- if (RenderThreadImpl::current()) {
- RenderThreadImpl::RendererMemoryMetrics memory_metrics;
- if (!RenderThreadImpl::current()->GetRendererMemoryMetrics(&memory_metrics))
- return;
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.PartitionAlloc.DidFinishLoad",
- memory_metrics.partition_alloc_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.BlinkGC.DidFinishLoad",
- memory_metrics.blink_gc_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.Malloc.DidFinishLoad",
- memory_metrics.malloc_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.Discardable.DidFinishLoad",
- memory_metrics.discardable_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.V8MainThreadIsolate.DidFinishLoad",
- memory_metrics.v8_main_thread_isolate_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.TotalAllocated.DidFinishLoad",
- memory_metrics.total_allocated_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.NonDiscardableTotalAllocated."
- "DidFinishLoad",
- memory_metrics.non_discardable_total_allocated_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.TotalAllocatedPerRenderView."
- "DidFinishLoad",
- memory_metrics.total_allocated_per_render_view_mb);
- if (IsMainFrame()) {
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.PartitionAlloc."
- "MainFrameDidFinishLoad",
- memory_metrics.partition_alloc_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.BlinkGC.MainFrameDidFinishLoad",
- memory_metrics.blink_gc_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.Malloc.MainFrameDidFinishLoad",
- memory_metrics.malloc_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.Discardable.MainFrameDidFinishLoad",
- memory_metrics.discardable_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.V8MainThreadIsolate."
- "MainFrameDidFinishLoad",
- memory_metrics.v8_main_thread_isolate_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.TotalAllocated."
- "MainFrameDidFinishLoad",
- memory_metrics.total_allocated_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.NonDiscardableTotalAllocated."
- "MainFrameDidFinishLoad",
- memory_metrics.non_discardable_total_allocated_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.TotalAllocatedPerRenderView."
- "MainFrameDidFinishLoad",
- memory_metrics.total_allocated_per_render_view_mb);
- }
- }
+ if (!RenderThreadImpl::current())
+ return;
+ RenderThreadImpl::RendererMemoryMetrics memory_metrics;
+ if (!RenderThreadImpl::current()->GetRendererMemoryMetrics(&memory_metrics))
+ return;
+ RecordSuffixedRendererMemoryMetrics(memory_metrics, ".DidFinishLoad");
+ if (!IsMainFrame())
+ return;
+ RecordSuffixedRendererMemoryMetrics(memory_metrics,
+ ".MainFrameDidFinishLoad");
+ if (!IsControlledByServiceWorker())
+ return;
+ RecordSuffixedRendererMemoryMetrics(
+ memory_metrics, ".ServiceWorkerControlledMainFrameDidFinishLoad");
}
void RenderFrameImpl::DidNavigateWithinPage(
@@ -4237,13 +4435,13 @@ blink::WebColorChooser* RenderFrameImpl::CreateColorChooser(
void RenderFrameImpl::RunModalAlertDialog(const blink::WebString& message) {
RunJavaScriptDialog(JAVASCRIPT_DIALOG_TYPE_ALERT, message.Utf16(),
- base::string16(), frame_->GetDocument().Url(), NULL);
+ base::string16(), frame_->GetDocument().Url(), nullptr);
}
bool RenderFrameImpl::RunModalConfirmDialog(const blink::WebString& message) {
return RunJavaScriptDialog(JAVASCRIPT_DIALOG_TYPE_CONFIRM, message.Utf16(),
base::string16(), frame_->GetDocument().Url(),
- NULL);
+ nullptr);
}
bool RenderFrameImpl::RunModalPromptDialog(
@@ -4255,7 +4453,7 @@ bool RenderFrameImpl::RunModalPromptDialog(
default_value.Utf16(),
frame_->GetDocument().Url(), &result);
if (ok)
- actual_value->Assign(WebString::FromUTF16(result));
+ *actual_value = WebString::FromUTF16(result);
return ok;
}
@@ -4378,7 +4576,7 @@ void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) {
}
if (internal_data->is_cache_policy_override_set())
- request.SetCachePolicy(internal_data->cache_policy_override());
+ request.SetCacheMode(internal_data->cache_policy_override());
// 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
@@ -4497,7 +4695,8 @@ void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) {
// don't register this id on the browser side, since the download manager
// expects to find a RenderViewHost based off the id.
request.SetRequestorID(render_view_->GetRoutingID());
- request.SetHasUserGesture(WebUserGestureIndicator::IsProcessingUserGesture());
+ request.SetHasUserGesture(
+ WebUserGestureIndicator::IsProcessingUserGesture(frame_));
// StartNavigationParams should only apply to navigational requests (and not
// to subresource requests). For example - Content-Type header provided via
@@ -4636,10 +4835,24 @@ void RenderFrameImpl::DidObserveNewFeatureUsage(
observer.DidObserveNewFeatureUsage(feature);
}
+bool RenderFrameImpl::ShouldTrackUseCounter(const blink::WebURL& url) {
+ return GetContentClient()->renderer()->ShouldTrackUseCounter(url);
+}
+
void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) {
- for (auto& observer : observers_)
- observer.DidCreateScriptContext(context, world_id);
+ if ((enabled_bindings_ & BINDINGS_POLICY_WEB_UI) && IsMainFrame() &&
+ world_id == ISOLATED_WORLD_ID_GLOBAL) {
+ // We only allow these bindings to be installed when creating the main
+ // world context of the main frame.
+ blink::WebContextFeatures::EnableMojoJS(context, true);
+ }
+
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidCreateScriptContext");
+ for (auto& observer : observers_)
+ observer.DidCreateScriptContext(context, world_id);
+ }
}
void RenderFrameImpl::WillReleaseScriptContext(v8::Local<v8::Context> context,
@@ -4651,8 +4864,11 @@ void RenderFrameImpl::WillReleaseScriptContext(v8::Local<v8::Context> context,
void RenderFrameImpl::DidChangeScrollOffset() {
render_view_->StartNavStateSyncTimerIfNecessary(this);
- for (auto& observer : observers_)
- observer.DidChangeScrollOffset();
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.DidChangeScrollOffset");
+ for (auto& observer : observers_)
+ observer.DidChangeScrollOffset();
+ }
}
void RenderFrameImpl::WillInsertBody() {
@@ -4688,7 +4904,7 @@ void RenderFrameImpl::RequestStorageQuota(
callbacks.DidFail(blink::kWebStorageQuotaErrorAbort);
return;
}
- ChildThreadImpl::current()->quota_dispatcher()->RequestStorageQuota(
+ RenderThreadImpl::current()->quota_dispatcher()->RequestStorageQuota(
routing_id_, url::Origin(origin).GetURL(),
static_cast<storage::StorageType>(type), requested_size,
QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks));
@@ -4708,7 +4924,7 @@ blink::WebPushClient* RenderFrameImpl::PushClient() {
blink::WebRelatedAppsFetcher* RenderFrameImpl::GetRelatedAppsFetcher() {
if (!related_apps_fetcher_)
- related_apps_fetcher_.reset(new RelatedAppsFetcher(manifest_manager_));
+ related_apps_fetcher_.reset(new RelatedAppsFetcher(&GetManifestManager()));
return related_apps_fetcher_.get();
}
@@ -4756,7 +4972,7 @@ blink::WebString RenderFrameImpl::UserAgentOverride() {
InternalDocumentStateData* internal_data =
document_loader
? InternalDocumentStateData::FromDocumentLoader(document_loader)
- : NULL;
+ : nullptr;
if (internal_data && internal_data->is_overriding_user_agent())
return WebString::FromUTF8(
render_view_->renderer_preferences_.user_agent_override);
@@ -4832,14 +5048,14 @@ void RenderFrameImpl::SuddenTerminationDisablerChanged(
void RenderFrameImpl::RegisterProtocolHandler(const WebString& scheme,
const WebURL& url,
const WebString& title) {
- bool user_gesture = WebUserGestureIndicator::IsProcessingUserGesture();
+ bool user_gesture = WebUserGestureIndicator::IsProcessingUserGesture(frame_);
Send(new FrameHostMsg_RegisterProtocolHandler(routing_id_, scheme.Utf8(), url,
title.Utf16(), user_gesture));
}
void RenderFrameImpl::UnregisterProtocolHandler(const WebString& scheme,
const WebURL& url) {
- bool user_gesture = WebUserGestureIndicator::IsProcessingUserGesture();
+ bool user_gesture = WebUserGestureIndicator::IsProcessingUserGesture(frame_);
Send(new FrameHostMsg_UnregisterProtocolHandler(routing_id_, scheme.Utf8(),
url, user_gesture));
}
@@ -4973,13 +5189,12 @@ void RenderFrameImpl::SendDidCommitProvisionalLoad(
}
std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params =
- base::MakeUnique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
+ std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
params->http_status_code = response.HttpStatusCode();
params->url_is_unreachable = document_loader->HasUnreachableURL();
params->method = "GET";
params->intended_as_new_entry =
navigation_state->request_params().intended_as_new_entry;
- params->did_create_new_entry = commit_type == blink::kWebStandardCommit;
params->should_replace_current_entry =
document_loader->ReplacesCurrentHistoryItem();
params->post_id = -1;
@@ -4992,10 +5207,21 @@ void RenderFrameImpl::SendDidCommitProvisionalLoad(
// are unwound or moved to RenderFrameHost (crbug.com/304341) we can move the
// client to be based on the routing_id of the RenderFrameHost.
params->render_view_routing_id = render_view_->routing_id();
- params->socket_address.set_host(response.RemoteIPAddress().Utf8());
- params->socket_address.set_port(response.RemotePort());
params->was_within_same_document = navigation_state->WasWithinSameDocument();
+ // "Standard" commits from Blink create new NavigationEntries. We also treat
+ // main frame "inert" commits as creating new NavigationEntries if they
+ // replace the current entry on a cross-document navigation (e.g., client
+ // redirects, location.replace, navigation to same URL), since this will
+ // replace all the subframes and could go cross-origin. We don't want to rely
+ // on updating the existing NavigationEntry in this case, since it could leave
+ // stale state around.
+ params->did_create_new_entry =
+ (commit_type == blink::kWebStandardCommit) ||
+ (commit_type == blink::kWebHistoryInertCommit && !frame->Parent() &&
+ params->should_replace_current_entry &&
+ !params->was_within_same_document);
+
WebDocument frame_document = frame->GetDocument();
// Set the origin of the frame. This will be replicated to the corresponding
// RenderFrameProxies in other processes.
@@ -5143,7 +5369,8 @@ void RenderFrameImpl::SendDidCommitProvisionalLoad(
if (params->origin.scheme() != url::kFileScheme ||
!render_view_->GetWebkitPreferences()
.allow_universal_access_from_file_urls) {
- CHECK(params->origin.IsSamePhysicalOriginWith(url::Origin(params->url)))
+ CHECK(params->origin.IsSamePhysicalOriginWith(
+ url::Origin::Create(params->url)))
<< " url:" << params->url << " origin:" << params->origin;
}
}
@@ -5188,6 +5415,7 @@ bool RenderFrameImpl::SwapIn() {
render_view_->main_render_frame_ = this;
if (render_view_->is_swapped_out())
render_view_->SetSwappedOut(false);
+ render_view_->UpdateWebViewWithDeviceScaleFactor();
}
return true;
@@ -5235,6 +5463,7 @@ void RenderFrameImpl::HandleWebAccessibilityEvent(
}
void RenderFrameImpl::FocusedNodeChanged(const WebNode& node) {
+ has_scrolled_focused_editable_node_into_rect_ = false;
bool is_editable = false;
gfx::Rect node_bounds;
if (!node.IsNull() && node.IsElementNode()) {
@@ -5250,8 +5479,11 @@ void RenderFrameImpl::FocusedNodeChanged(const WebNode& node) {
// focused input and the newly focused input share the exact same state.
GetRenderWidget()->ClearTextInputState();
- for (auto& observer : observers_)
- observer.FocusedNodeChanged(node);
+ {
+ SCOPED_UMA_HISTOGRAM_TIMER("RenderFrameObservers.FocusedNodeChanged");
+ for (auto& observer : observers_)
+ observer.FocusedNodeChanged(node);
+ }
}
void RenderFrameImpl::FocusedNodeChangedForAccessibility(const WebNode& node) {
@@ -5260,71 +5492,12 @@ void RenderFrameImpl::FocusedNodeChangedForAccessibility(const WebNode& node) {
}
// PlzNavigate
-void RenderFrameImpl::OnCommitNavigation(
- const ResourceResponseHead& response,
- const GURL& stream_url,
- const FrameMsg_CommitDataNetworkService_Params& commit_data,
- const CommonNavigationParams& common_params,
- const RequestNavigationParams& request_params) {
- CHECK(IsBrowserSideNavigationEnabled());
- // If this was a renderer-initiated navigation (nav_entry_id == 0) from this
- // frame, but it was aborted, then ignore it.
- if (!browser_side_navigation_pending_ &&
- !browser_side_navigation_pending_url_.is_empty() &&
- browser_side_navigation_pending_url_ == request_params.original_url &&
- request_params.nav_entry_id == 0) {
- browser_side_navigation_pending_url_ = GURL();
- return;
- }
-
- // This will override the url requested by the WebURLLoader, as well as
- // provide it with the response to the request.
- std::unique_ptr<StreamOverrideParameters> stream_override(
- new StreamOverrideParameters());
- stream_override->stream_url = stream_url;
- stream_override->consumer_handle =
- mojo::ScopedDataPipeConsumerHandle(commit_data.handle);
- stream_override->response = response;
- stream_override->redirects = request_params.redirects;
- stream_override->redirect_responses = request_params.redirect_response;
- stream_override->redirect_infos = request_params.redirect_infos;
-
- // Used to notify the browser that it can release its |stream_handle_| when
- // the |stream_override| object isn't used anymore.
- // TODO(clamy): Remove this when we switch to Mojo streams.
- stream_override->on_delete = base::BindOnce(
- [](base::WeakPtr<RenderFrameImpl> weak_self, const GURL& url) {
- if (RenderFrameImpl* self = weak_self.get()) {
- self->Send(
- new FrameHostMsg_StreamHandleConsumed(self->routing_id_, url));
- }
- },
- weak_factory_.GetWeakPtr());
-
- SetCustomURLLoadeFactory(commit_data.url_loader_factory);
-
- // 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(
- request_params.has_user_gesture ? new blink::WebScopedUserGesture(frame_)
- : nullptr);
-
- browser_side_navigation_pending_ = false;
- browser_side_navigation_pending_url_ = GURL();
-
- NavigateInternal(common_params, StartNavigationParams(), request_params,
- std::move(stream_override));
-
- // Don't add code after this since NavigateInternal may have destroyed this
- // RenderFrameImpl.
-}
-
-// PlzNavigate
void RenderFrameImpl::OnFailedNavigation(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
bool has_stale_copy_in_cache,
- int error_code) {
+ int error_code,
+ const base::Optional<std::string>& error_page_content) {
DCHECK(IsBrowserSideNavigationEnabled());
bool is_reload =
FrameMsg_Navigate_Type::IsReload(common_params.navigation_type);
@@ -5344,8 +5517,11 @@ void RenderFrameImpl::OnFailedNavigation(
common_params, StartNavigationParams(), request_params));
// Send the provisional load failure.
- blink::WebURLError error(common_params.url, has_stale_copy_in_cache,
- error_code);
+ WebURLError error(
+ error_code,
+ has_stale_copy_in_cache ? WebURLError::HasCopyInCache::kTrue
+ : WebURLError::HasCopyInCache::kFalse,
+ WebURLError::IsWebSecurityViolation::kFalse, common_params.url);
WebURLRequest failed_request =
CreateURLRequestForNavigation(common_params, request_params,
std::unique_ptr<StreamOverrideParameters>(),
@@ -5404,8 +5580,17 @@ void RenderFrameImpl::OnFailedNavigation(
// notification.
bool had_provisional_document_loader = frame_->GetProvisionalDocumentLoader();
if (request_params.nav_entry_id == 0) {
- DidFailProvisionalLoad(error, replace ? blink::kWebHistoryInertCommit
- : blink::kWebStandardCommit);
+ blink::WebHistoryCommitType commit_type =
+ replace ? blink::kWebHistoryInertCommit : blink::kWebStandardCommit;
+ if (error_page_content.has_value()) {
+ DidFailProvisionalLoadInternal(error, commit_type, error_page_content);
+ } else {
+ // TODO(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);
+ }
if (!weak_this)
return;
}
@@ -5414,8 +5599,8 @@ void RenderFrameImpl::OnFailedNavigation(
// GetProvisionalDocumentLoader(), LoadNavigationErrorPage wasn't called, so
// do it now.
if (request_params.nav_entry_id != 0 || !had_provisional_document_loader) {
- LoadNavigationErrorPage(failed_request, error, replace,
- history_entry.get());
+ LoadNavigationErrorPage(failed_request, error, replace, history_entry.get(),
+ error_page_content);
if (!weak_this)
return;
}
@@ -5597,9 +5782,9 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
render_view_->HistoryForwardListCount() < 1 &&
// The parent page must have set the child's window.opener to null before
// redirecting to the desired URL.
- frame_->Opener() == NULL &&
+ frame_->Opener() == nullptr &&
// Must be a top-level frame.
- frame_->Parent() == NULL &&
+ frame_->Parent() == nullptr &&
// Must not have issued the request from this page.
is_content_initiated &&
// Must be targeted at the current tab.
@@ -6059,15 +6244,17 @@ void RenderFrameImpl::OpenURL(const NavigationPolicyInfo& info,
params.should_replace_current_entry = info.replaces_current_history_item &&
render_view_->history_list_length_;
}
- params.user_gesture = WebUserGestureIndicator::IsProcessingUserGesture();
+ params.user_gesture =
+ WebUserGestureIndicator::IsProcessingUserGesture(frame_);
if (GetContentClient()->renderer()->AllowPopup())
params.user_gesture = true;
- if (policy == blink::kWebNavigationPolicyNewBackgroundTab ||
+ if (ConsumeGestureOnNavigation() ||
+ policy == blink::kWebNavigationPolicyNewBackgroundTab ||
policy == blink::kWebNavigationPolicyNewForegroundTab ||
policy == blink::kWebNavigationPolicyNewWindow ||
policy == blink::kWebNavigationPolicyNewPopup) {
- WebUserGestureIndicator::ConsumeUserGesture();
+ WebUserGestureIndicator::ConsumeUserGesture(frame_);
}
if (is_history_navigation_in_new_child)
@@ -6080,9 +6267,23 @@ void RenderFrameImpl::NavigateInternal(
const CommonNavigationParams& common_params,
const StartNavigationParams& start_params,
const RequestNavigationParams& request_params,
- std::unique_ptr<StreamOverrideParameters> stream_params) {
+ std::unique_ptr<StreamOverrideParameters> stream_params,
+ base::Optional<URLLoaderFactoryBundle> subresource_loader_factories,
+ const base::UnguessableToken& devtools_navigation_token) {
bool browser_side_navigation = IsBrowserSideNavigationEnabled();
+ // First, check if this is a Debug URL. If so, handle it and stop the
+ // navigation right away.
+ base::WeakPtr<RenderFrameImpl> weak_this = weak_factory_.GetWeakPtr();
+ if (MaybeHandleDebugURL(common_params.url)) {
+ // The browser expects the frame to be loading the requested URL. Inform it
+ // that the load stopped if needed, while leaving the debug URL visible in
+ // the address bar.
+ if (weak_this && frame_ && !frame_->IsLoading())
+ Send(new FrameHostMsg_DidStopLoading(routing_id_));
+ return;
+ }
+
// PlzNavigate
// Clear pending navigations which weren't sent to the browser because we
// did not get a didStartProvisionalLoad() notification for them.
@@ -6093,7 +6294,7 @@ void RenderFrameImpl::NavigateInternal(
bool is_reload =
FrameMsg_Navigate_Type::IsReload(common_params.navigation_type);
bool is_history_navigation = request_params.page_state.IsValid();
- WebCachePolicy cache_policy = WebCachePolicy::kUseProtocolCachePolicy;
+ auto cache_mode = blink::mojom::FetchCacheMode::kDefault;
RenderFrameImpl::PrepareRenderViewForNavigation(
common_params.url, request_params);
@@ -6110,7 +6311,7 @@ void RenderFrameImpl::NavigateInternal(
// We cannot reload if we do not have any history state. This happens, for
// example, when recovering from a crash.
is_reload = false;
- cache_policy = WebCachePolicy::kValidatingCacheData;
+ cache_mode = blink::mojom::FetchCacheMode::kValidateCache;
}
// If the navigation is for "view source", the WebLocalFrame needs to be put
@@ -6144,6 +6345,22 @@ void RenderFrameImpl::NavigateInternal(
IsBrowserSideNavigationEnabled() &&
FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type);
+ // Sanity check that the browser always sends us new loader factories on
+ // cross-document navigations with the Network Service enabled.
+ DCHECK(is_same_document ||
+ common_params.url.SchemeIs(url::kJavaScriptScheme) ||
+ !base::FeatureList::IsEnabled(features::kNetworkService) ||
+ subresource_loader_factories.has_value());
+
+ if (subresource_loader_factories)
+ subresource_loader_factories_ = std::move(subresource_loader_factories);
+
+ // If the Network Service is enabled, by this point the frame should always
+ // have subresource loader factories, even if they're from a previous (but
+ // same-document) commit.
+ DCHECK(!base::FeatureList::IsEnabled(features::kNetworkService) ||
+ subresource_loader_factories_.has_value());
+
WebURLRequest request = CreateURLRequestForNavigation(
common_params, request_params, std::move(stream_params),
frame_->IsViewSourceModeEnabled(), is_same_document);
@@ -6165,7 +6382,7 @@ void RenderFrameImpl::NavigateInternal(
bool has_history_navigation_in_frame = false;
#if defined(OS_ANDROID)
- request.SetHasUserGesture(request_params.has_user_gesture);
+ request.SetHasUserGesture(common_params.has_user_gesture);
#endif
if (browser_side_navigation) {
@@ -6270,7 +6487,7 @@ void RenderFrameImpl::NavigateInternal(
// will be done based on the history item during the load.
if (!browser_side_navigation && should_load_request) {
request = frame_->RequestFromHistoryItem(item_for_history_navigation,
- cache_policy);
+ cache_mode);
}
}
} else {
@@ -6313,16 +6530,15 @@ void RenderFrameImpl::NavigateInternal(
item_for_history_navigation, history_load_type,
is_client_redirect);
} else {
+ // Load the request.
+ frame_->Load(request, load_type, item_for_history_navigation,
+ history_load_type, is_client_redirect,
+ devtools_navigation_token);
+
// 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
// method should return immediately and not touch any part of the object,
// otherwise it will result in a use-after-free bug.
- base::WeakPtr<RenderFrameImpl> weak_this = weak_factory_.GetWeakPtr();
-
- // Load the request.
- frame_->Load(request, load_type, item_for_history_navigation,
- history_load_type, is_client_redirect);
-
if (!weak_this)
return;
}
@@ -6350,6 +6566,18 @@ void RenderFrameImpl::NavigateInternal(
}
}
+URLLoaderFactoryBundle& RenderFrameImpl::GetSubresourceLoaderFactories() {
+ DCHECK(base::FeatureList::IsEnabled(features::kNetworkService));
+ if (!subresource_loader_factories_) {
+ RenderFrameImpl* creator = RenderFrameImpl::FromWebFrame(
+ frame_->Parent() ? frame_->Parent() : frame_->Opener());
+ DCHECK(creator);
+ subresource_loader_factories_ =
+ creator->GetSubresourceLoaderFactories().Clone();
+ }
+ return *subresource_loader_factories_;
+}
+
void RenderFrameImpl::UpdateEncoding(WebFrame* frame,
const std::string& encoding_name) {
// Only update main frame's encoding_name.
@@ -6416,13 +6644,43 @@ void RenderFrameImpl::SyncSelectionIfRequired() {
GetRenderWidget()->UpdateSelectionBounds();
}
-void RenderFrameImpl::SetCustomURLLoadeFactory(
- mojo::MessagePipeHandle custom_loader_factory_handle) {
- // Chrome doesn't use interface versioning.
- mojom::URLLoaderFactoryPtr url_loader_factory;
- url_loader_factory.Bind(mojom::URLLoaderFactoryPtrInfo(
- mojo::ScopedMessagePipeHandle(custom_loader_factory_handle), 0u));
- custom_url_loader_factory_ = std::move(url_loader_factory);
+void RenderFrameImpl::SetCustomURLLoaderFactory(
+ mojom::URLLoaderFactoryPtr factory) {
+ if (base::FeatureList::IsEnabled(features::kNetworkService)) {
+ // When the network service is enabled, all subresource loads go through
+ // a factory from |subresource_loader_factories|. In this case we simply
+ // replace the existing default factory within the bundle.
+ GetSubresourceLoaderFactories().SetDefaultFactory(std::move(factory));
+ } else {
+ custom_url_loader_factory_ = std::move(factory);
+ }
+}
+
+void RenderFrameImpl::ScrollFocusedEditableElementIntoRect(
+ const gfx::Rect& rect) {
+ // TODO(ekaramad): Perhaps we should remove |rect| since all it seems to be
+ // doing is helping verify if scrolling animation for a given focused editable
+ // element has finished.
+ blink::WebAutofillClient* autofill_client = frame_->AutofillClient();
+ if (has_scrolled_focused_editable_node_into_rect_ &&
+ rect == rect_for_scrolled_focused_editable_node_ && autofill_client) {
+ autofill_client->DidCompleteFocusChangeInFrame();
+ return;
+ }
+
+ if (!render_view_->webview()->ScrollFocusedEditableElementIntoView())
+ return;
+
+ rect_for_scrolled_focused_editable_node_ = rect;
+ has_scrolled_focused_editable_node_into_rect_ = true;
+ if (!GetRenderWidget()->compositor()->HasPendingPageScaleAnimation() &&
+ autofill_client) {
+ autofill_client->DidCompleteFocusChangeInFrame();
+ }
+}
+
+void RenderFrameImpl::DidChangeVisibleViewport() {
+ has_scrolled_focused_editable_node_into_rect_ = false;
}
void RenderFrameImpl::InitializeUserMediaClient() {
@@ -6434,7 +6692,7 @@ void RenderFrameImpl::InitializeUserMediaClient() {
DCHECK(!web_user_media_client_);
web_user_media_client_ = new UserMediaClientImpl(
this, RenderThreadImpl::current()->GetPeerConnectionDependencyFactory(),
- base::MakeUnique<MediaStreamDispatcher>(this),
+ std::make_unique<MediaStreamDeviceObserver>(this),
render_thread->GetWorkerTaskRunner());
registry_.AddInterface(
base::Bind(&MediaDevicesListenerImpl::Create, GetRoutingID()));
@@ -6446,8 +6704,6 @@ void RenderFrameImpl::PrepareRenderViewForNavigation(
const RequestNavigationParams& request_params) {
DCHECK(render_view_->webview());
- MaybeHandleDebugURL(url);
-
if (is_main_frame_) {
for (auto& observer : render_view_->observers_)
observer.Navigate(url);
@@ -6505,10 +6761,10 @@ void RenderFrameImpl::BeginNavigation(const NavigationPolicyInfo& info) {
// TODO(clamy): Data urls should not be sent back to the browser either.
// These values are assumed on the browser side for navigations. These checks
// ensure the renderer has the correct values.
- DCHECK_EQ(FETCH_REQUEST_MODE_NAVIGATE,
- GetFetchRequestModeForWebURLRequest(info.url_request));
- DCHECK_EQ(FETCH_CREDENTIALS_MODE_INCLUDE,
- GetFetchCredentialsModeForWebURLRequest(info.url_request));
+ DCHECK_EQ(network::mojom::FetchRequestMode::kNavigate,
+ info.url_request.GetFetchRequestMode());
+ DCHECK_EQ(network::mojom::FetchCredentialsMode::kInclude,
+ info.url_request.GetFetchCredentialsMode());
DCHECK(GetFetchRedirectModeForWebURLRequest(info.url_request) ==
FetchRedirectMode::MANUAL_MODE);
DCHECK(frame_->Parent() ||
@@ -6538,7 +6794,6 @@ void RenderFrameImpl::BeginNavigation(const NavigationPolicyInfo& info) {
BeginNavigationParams begin_navigation_params(
GetWebURLRequestHeadersAsString(info.url_request), load_flags,
- info.url_request.HasUserGesture(),
info.url_request.GetServiceWorkerMode() !=
blink::WebURLRequest::ServiceWorkerMode::kAll,
GetRequestContextTypeForWebURLRequest(info.url_request),
@@ -6614,55 +6869,19 @@ void RenderFrameImpl::SendUpdateState() {
routing_id_, SingleHistoryItemToPageState(current_history_item_)));
}
-void RenderFrameImpl::MaybeEnableMojoBindings() {
- // BINDINGS_POLICY_WEB_UI and BINDINGS_POLICY_MOJO are mutually exclusive.
- // They provide access to Mojo bindings, but do so in incompatible ways.
- const int kAllBindingsTypes = BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO;
-
- // Make sure that at most one of BINDINGS_POLICY_WEB_UI and
- // BINDINGS_POLICY_MOJO have been set.
- // NOTE x & (x - 1) == 0 is true iff x is zero or a power of two.
- DCHECK_EQ((enabled_bindings_ & kAllBindingsTypes) &
- ((enabled_bindings_ & kAllBindingsTypes) - 1),
- 0);
-
- // In single process, multiple RenderFrames share a RenderProcess. The
- // RenderProcess's bindings may not be the same as an individual RenderFrame's
- // bindings. In multiprocess, such RenderFrames are enforced to be in
- // different RenderProcesses.
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- if (!command_line.HasSwitch(switches::kSingleProcess)) {
- DCHECK_EQ(RenderProcess::current()->GetEnabledBindings(),
- enabled_bindings_);
- }
-
- // If an MojoBindingsController already exists for this RenderFrameImpl, avoid
- // creating another one. It is not kept as a member, as it deletes itself when
- // the frame is destroyed.
- if (RenderFrameObserverTracker<MojoBindingsController>::Get(this))
- return;
-
- if (IsMainFrame() && enabled_bindings_ & BINDINGS_POLICY_WEB_UI) {
- new MojoBindingsController(this, MojoBindingsType::FOR_WEB_UI);
- } else if (enabled_bindings_ & BINDINGS_POLICY_MOJO) {
- new MojoBindingsController(this, MojoBindingsType::FOR_LAYOUT_TESTS);
- }
-}
-
void RenderFrameImpl::SendFailedProvisionalLoad(
const blink::WebURLRequest& request,
- const blink::WebURLError& error,
+ const WebURLError& error,
blink::WebLocalFrame* frame) {
bool show_repost_interstitial =
- (error.reason == net::ERR_CACHE_MISS &&
+ (error.reason() == net::ERR_CACHE_MISS &&
base::EqualsASCII(request.HttpMethod().Utf16(), "POST"));
FrameHostMsg_DidFailProvisionalLoadWithError_Params params;
- params.error_code = error.reason;
+ params.error_code = error.reason();
GetContentClient()->renderer()->GetNavigationErrorStrings(
this, request, error, nullptr, &params.error_description);
- params.url = error.unreachable_url;
+ params.url = error.url(),
params.showing_repost_interstitial = show_repost_interstitial;
Send(new FrameHostMsg_DidFailProvisionalLoadWithError(routing_id_, params));
}
@@ -6721,7 +6940,7 @@ void RenderFrameImpl::PopulateDocumentStateFromPending(
// UseProtocolCachePolicy to mean both "normal load" and "determine cache
// policy based on load type, etc".
internal_data->set_cache_policy_override(
- WebCachePolicy::kUseProtocolCachePolicy);
+ blink::mojom::FetchCacheMode::kDefault);
}
internal_data->set_is_overriding_user_agent(
@@ -6778,9 +6997,12 @@ void RenderFrameImpl::UpdateNavigationState(DocumentState* document_state,
media::MediaPermission* RenderFrameImpl::GetMediaPermission() {
if (!media_permission_dispatcher_) {
- media_permission_dispatcher_.reset(new MediaPermissionDispatcher(base::Bind(
- &RenderFrameImpl::GetInterface<blink::mojom::PermissionService>,
- base::Unretained(this))));
+ media_permission_dispatcher_.reset(new MediaPermissionDispatcher(
+ base::Bind(
+ &RenderFrameImpl::GetInterface<blink::mojom::PermissionService>,
+ base::Unretained(this)),
+ base::Bind(&RenderFrameImpl::IsEncryptedMediaEnabled,
+ base::Unretained(this))));
}
return media_permission_dispatcher_.get();
}
@@ -6826,18 +7048,30 @@ void RenderFrameImpl::RegisterMojoInterfaces() {
GetAssociatedInterfaceRegistry()->AddInterface(
base::Bind(&RenderFrameImpl::BindEngagement, weak_factory_.GetWeakPtr()));
+ if (devtools_agent_) {
+ GetAssociatedInterfaceRegistry()->AddInterface(
+ base::Bind(&DevToolsAgent::BindRequest, devtools_agent_->GetWeakPtr()));
+ }
+
GetAssociatedInterfaceRegistry()->AddInterface(base::Bind(
&RenderFrameImpl::BindMediaEngagement, weak_factory_.GetWeakPtr()));
GetAssociatedInterfaceRegistry()->AddInterface(base::Bind(
&RenderFrameImpl::BindFrameBindingsControl, weak_factory_.GetWeakPtr()));
+ GetAssociatedInterfaceRegistry()->AddInterface(
+ base::Bind(&RenderFrameImpl::BindFrameNavigationControl,
+ weak_factory_.GetWeakPtr()));
+
registry_.AddInterface(base::Bind(&FrameInputHandlerImpl::CreateMojoService,
weak_factory_.GetWeakPtr()));
registry_.AddInterface(
base::Bind(&RenderFrameImpl::BindWidget, weak_factory_.GetWeakPtr()));
+ GetAssociatedInterfaceRegistry()->AddInterface(base::Bind(
+ &DevToolsFrontendImpl::CreateMojoService, base::Unretained(this)));
+
if (!frame_->Parent()) {
// Only main frame have ImageDownloader service.
registry_.AddInterface(base::Bind(&ImageDownloaderImpl::CreateMojoService,
@@ -6848,8 +7082,9 @@ void RenderFrameImpl::RegisterMojoInterfaces() {
&RenderFrameImpl::OnHostZoomClientRequest, weak_factory_.GetWeakPtr()));
// Web manifests are only requested for main frames.
- GetAssociatedInterfaceRegistry()->AddInterface(base::Bind(
- &ManifestManager::BindToRequest, base::Unretained(manifest_manager_)));
+ registry_.AddInterface(
+ base::Bind(&ManifestManager::BindToRequest,
+ base::Unretained(manifest_manager_.get())));
}
}
@@ -6858,6 +7093,10 @@ 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());
@@ -6875,42 +7114,28 @@ void RenderFrameImpl::CheckIfAudioSinkExistsAndIsAuthorized(
.device_status());
}
-blink::WebPageVisibilityState RenderFrameImpl::VisibilityState() const {
+blink::mojom::PageVisibilityState RenderFrameImpl::VisibilityState() const {
const RenderFrameImpl* local_root = GetLocalRoot();
- blink::WebPageVisibilityState current_state =
+ blink::mojom::PageVisibilityState current_state =
local_root->render_widget_->is_hidden()
- ? blink::kWebPageVisibilityStateHidden
- : blink::kWebPageVisibilityStateVisible;
- blink::WebPageVisibilityState override_state = current_state;
+ ? blink::mojom::PageVisibilityState::kHidden
+ : blink::mojom::PageVisibilityState::kVisible;
+ blink::mojom::PageVisibilityState override_state = current_state;
if (GetContentClient()->renderer()->ShouldOverridePageVisibilityState(
this, &override_state))
return override_state;
return current_state;
}
-std::unique_ptr<blink::WebURLLoader> RenderFrameImpl::CreateURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- // Currently the tests (RenderViewTests) that need URLLoader but do not
- // have ChildThread use the Platform::Current()->CreateURLLoader().
- DCHECK(ChildThreadImpl::current());
-
- UpdatePeakMemoryStats();
-
- mojom::URLLoaderFactory* factory =
- GetDefaultURLLoaderFactoryGetter()->GetFactoryForURL(
- request.Url(), custom_url_loader_factory_.get());
- DCHECK(factory);
-
- mojom::KeepAliveHandlePtr keep_alive_handle;
- if (base::FeatureList::IsEnabled(
- features::kKeepAliveRendererForKeepaliveRequests) &&
- request.GetKeepalive()) {
- GetFrameHost()->IssueKeepAliveHandle(mojo::MakeRequest(&keep_alive_handle));
+std::unique_ptr<blink::WebURLLoaderFactory>
+RenderFrameImpl::CreateURLLoaderFactory() {
+ if (!RenderThreadImpl::current()) {
+ // Some tests (e.g. RenderViewTests) do not have RenderThreadImpl,
+ // use the platform's default WebURLLoaderFactoryImpl for them.
+ return WebURLLoaderFactoryImpl::CreateTestOnlyFactory();
}
- return base::MakeUnique<WebURLLoaderImpl>(
- ChildThreadImpl::current()->resource_dispatcher(), std::move(task_runner),
- factory, std::move(keep_alive_handle));
+ return std::make_unique<FrameURLLoaderFactory>(
+ weak_factory_.GetWeakPtr(), GetDefaultURLLoaderFactoryGetter());
}
void RenderFrameImpl::DraggableRegionsChanged() {
@@ -6918,7 +7143,15 @@ void RenderFrameImpl::DraggableRegionsChanged() {
observer.DraggableRegionsChanged();
}
-blink::WebPageVisibilityState RenderFrameImpl::GetVisibilityState() const {
+void RenderFrameImpl::ScrollRectToVisibleInParentFrame(
+ const blink::WebRect& rect_to_scroll,
+ const blink::WebRemoteScrollProperties& properties) {
+ DCHECK(IsLocalRoot());
+ Send(new FrameHostMsg_ScrollRectToVisibleInParentFrame(
+ routing_id_, rect_to_scroll, properties));
+}
+
+blink::mojom::PageVisibilityState RenderFrameImpl::GetVisibilityState() const {
return VisibilityState();
}
@@ -7115,61 +7348,31 @@ void RenderFrameImpl::ReportPeakMemoryStats() {
if (!base::FeatureList::IsEnabled(features::kReportRendererPeakMemoryStats))
return;
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.PartitionAlloc.PeakDuringLoad",
- peak_memory_metrics_.partition_alloc_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB("Memory.Experimental.Renderer.BlinkGC.PeakDuringLoad",
- peak_memory_metrics_.blink_gc_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB("Memory.Experimental.Renderer.Malloc.PeakDuringLoad",
- peak_memory_metrics_.malloc_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.Discardable.PeakDuringLoad",
- peak_memory_metrics_.discardable_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.V8MainThreadIsolate.PeakDuringLoad",
- peak_memory_metrics_.v8_main_thread_isolate_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.TotalAllocated.PeakDuringLoad",
- peak_memory_metrics_.total_allocated_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.NonDiscardableTotalAllocated."
- "PeakDuringLoad",
- peak_memory_metrics_.non_discardable_total_allocated_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.TotalAllocatedPerRenderView."
- "PeakDuringLoad",
- peak_memory_metrics_.total_allocated_per_render_view_mb);
- if (IsMainFrame()) {
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.PartitionAlloc."
- "MainFrame.PeakDuringLoad",
- peak_memory_metrics_.partition_alloc_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.BlinkGC.MainFrame.PeakDuringLoad",
- peak_memory_metrics_.blink_gc_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.Malloc.MainFrame.PeakDuringLoad",
- peak_memory_metrics_.malloc_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.Discardable.MainFrame.PeakDuringLoad",
- peak_memory_metrics_.discardable_kb / 1024);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.V8MainThreadIsolate."
- "MainFrame.PeakDuringLoad",
- peak_memory_metrics_.v8_main_thread_isolate_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.TotalAllocated."
- "MainFrame.PeakDuringLoad",
- peak_memory_metrics_.total_allocated_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.NonDiscardableTotalAllocated."
- "MainFrame.PeakDuringLoad",
- peak_memory_metrics_.non_discardable_total_allocated_mb);
- UMA_HISTOGRAM_MEMORY_MB(
- "Memory.Experimental.Renderer.TotalAllocatedPerRenderView."
- "MainFrame.PeakDuringLoad",
- peak_memory_metrics_.total_allocated_per_render_view_mb);
- }
+ RecordSuffixedRendererMemoryMetrics(peak_memory_metrics_, ".PeakDuringLoad");
+ if (!IsMainFrame())
+ return;
+ RecordSuffixedRendererMemoryMetrics(peak_memory_metrics_,
+ ".MainFrame.PeakDuringLoad");
+ if (!IsControlledByServiceWorker())
+ return;
+ RecordSuffixedRendererMemoryMetrics(
+ peak_memory_metrics_, ".ServiceWorkerControlledMainFrame.PeakDuringLoad");
+}
+
+bool RenderFrameImpl::ConsumeGestureOnNavigation() const {
+ return is_main_frame_ &&
+ base::FeatureList::IsEnabled(kConsumeGestureOnNavigation);
+}
+
+bool RenderFrameImpl::IsControlledByServiceWorker() {
+ blink::WebServiceWorkerNetworkProvider* web_provider =
+ frame_->GetDocumentLoader()->GetServiceWorkerNetworkProvider();
+ if (!web_provider)
+ return false;
+ ServiceWorkerNetworkProvider* provider =
+ ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider(
+ web_provider);
+ return provider->IsControlledByServiceWorker();
}
RenderFrameImpl::PendingNavigationInfo::PendingNavigationInfo(
diff --git a/chromium/content/renderer/render_frame_impl.h b/chromium/content/renderer/render_frame_impl.h
index 981e06445a6..a06fdcd7dfe 100644
--- a/chromium/content/renderer/render_frame_impl.h
+++ b/chromium/content/renderer/render_frame_impl.h
@@ -12,6 +12,7 @@
#include <memory>
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include "base/callback.h"
@@ -37,6 +38,7 @@
#include "content/common/possibly_associated_interface_ptr.h"
#include "content/common/renderer.mojom.h"
#include "content/common/unique_name_helper.h"
+#include "content/common/url_loader_factory_bundle.h"
#include "content/common/widget.mojom.h"
#include "content/public/common/console_message_level.h"
#include "content/public/common/javascript_dialog_type.h"
@@ -61,16 +63,17 @@
#include "ppapi/features/features.h"
#include "services/service_manager/public/cpp/bind_source_info.h"
#include "services/service_manager/public/cpp/binder_registry.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
#include "services/service_manager/public/interfaces/connector.mojom.h"
#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
-#include "third_party/WebKit/public/platform/WebCachePolicy.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/WebEffectiveConnectionType.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
#include "third_party/WebKit/public/platform/WebFocusType.h"
#include "third_party/WebKit/public/platform/WebLoadingBehaviorFlag.h"
#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
#include "third_party/WebKit/public/platform/media_engagement.mojom.h"
+#include "third_party/WebKit/public/platform/modules/manifest/manifest_manager.mojom.h"
#include "third_party/WebKit/public/platform/site_engagement.mojom.h"
#include "third_party/WebKit/public/web/WebAXObject.h"
#include "third_party/WebKit/public/web/WebDocumentLoader.h"
@@ -91,7 +94,6 @@
#include "content/renderer/pepper/plugin_power_saver_helper.h"
#endif
-struct FrameMsg_CommitDataNetworkService_Params;
struct FrameMsg_MixedContentFound_Params;
struct FrameMsg_PostMessage_Params;
struct FrameMsg_SerializeAsMHTML_Params;
@@ -109,6 +111,8 @@ struct WebCursorInfo;
struct WebFindOptions;
class WebLayerTreeView;
class WebRelatedAppsFetcher;
+struct FramePolicy;
+struct WebRemoteScrollProperties;
} // namespace blink
namespace gfx {
@@ -140,7 +144,7 @@ class ExternalPopupMenu;
class HistoryEntry;
class ManifestManager;
class MediaPermissionDispatcher;
-class MediaStreamDispatcher;
+class MediaStreamDeviceObserver;
class NavigationState;
class PepperPluginInstanceImpl;
class PresentationDispatcher;
@@ -169,15 +173,12 @@ struct ScreenInfo;
struct StartNavigationParams;
struct StreamOverrideParameters;
-namespace {
-class CreateFrameWidgetParams;
-}
-
class CONTENT_EXPORT RenderFrameImpl
: public RenderFrame,
blink::mojom::EngagementClient,
blink::mojom::MediaEngagementClient,
mojom::Frame,
+ mojom::FrameNavigationControl,
mojom::HostZoom,
mojom::FrameBindingsControl,
public blink::WebFrameClient,
@@ -188,6 +189,7 @@ class CONTENT_EXPORT RenderFrameImpl
static RenderFrameImpl* CreateMainFrame(
RenderViewImpl* render_view,
int32_t routing_id,
+ service_manager::mojom::InterfaceProviderPtr interface_provider,
int32_t widget_routing_id,
bool hidden,
const ScreenInfo& screen_info,
@@ -215,16 +217,18 @@ class CONTENT_EXPORT RenderFrameImpl
// Note: This is called only when RenderFrame is being created in response
// to IPC message from the browser process. All other frame creation is driven
// through Blink and Create.
- static void CreateFrame(int routing_id,
- int proxy_routing_id,
- int opener_routing_id,
- int parent_routing_id,
- int previous_sibling_routing_id,
- const base::UnguessableToken& devtools_frame_token,
- const FrameReplicationState& replicated_state,
- CompositorDependencies* compositor_deps,
- const mojom::CreateFrameWidgetParams& params,
- const FrameOwnerProperties& frame_owner_properties);
+ static void CreateFrame(
+ int routing_id,
+ service_manager::mojom::InterfaceProviderPtr interface_provider,
+ int proxy_routing_id,
+ int opener_routing_id,
+ int parent_routing_id,
+ int previous_sibling_routing_id,
+ const base::UnguessableToken& devtools_frame_token,
+ const FrameReplicationState& replicated_state,
+ CompositorDependencies* compositor_deps,
+ const mojom::CreateFrameWidgetParams& params,
+ const FrameOwnerProperties& frame_owner_properties);
// Returns the RenderFrameImpl for the given routing ID.
static RenderFrameImpl* FromRoutingID(int routing_id);
@@ -234,22 +238,24 @@ class CONTENT_EXPORT RenderFrameImpl
// Used by content_layouttest_support to hook into the creation of
// RenderFrameImpls.
- struct CreateParams {
- CreateParams(RenderViewImpl* render_view,
- int32_t routing_id,
- const base::UnguessableToken& devtools_frame_token)
- : render_view(render_view),
- routing_id(routing_id),
- devtools_frame_token(devtools_frame_token) {}
- ~CreateParams() {}
+ struct CONTENT_EXPORT CreateParams {
+ CreateParams(
+ RenderViewImpl* render_view,
+ int32_t routing_id,
+ service_manager::mojom::InterfaceProviderPtr interface_provider,
+ const base::UnguessableToken& devtools_frame_token);
+ ~CreateParams();
+
+ CreateParams(CreateParams&&);
+ CreateParams& operator=(CreateParams&&);
RenderViewImpl* render_view;
int32_t routing_id;
+ service_manager::mojom::InterfaceProviderPtr interface_provider;
base::UnguessableToken devtools_frame_token;
};
- using CreateRenderFrameImplFunction =
- RenderFrameImpl* (*)(const CreateParams&);
+ using CreateRenderFrameImplFunction = RenderFrameImpl* (*)(CreateParams);
static void InstallCreateHook(
CreateRenderFrameImplFunction create_render_frame_impl);
@@ -418,7 +424,7 @@ class CONTENT_EXPORT RenderFrameImpl
// May return NULL in some cases, especially if userMediaClient() returns
// NULL.
- MediaStreamDispatcher* GetMediaStreamDispatcher();
+ MediaStreamDeviceObserver* GetMediaStreamDeviceObserver();
void ScriptedPrint(bool user_initiated);
@@ -456,8 +462,8 @@ class CONTENT_EXPORT RenderFrameImpl
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override;
service_manager::InterfaceProvider* GetRemoteInterfaces() override;
- AssociatedInterfaceRegistry* GetAssociatedInterfaceRegistry() override;
- AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override;
+ blink::AssociatedInterfaceRegistry* GetAssociatedInterfaceRegistry() override;
+ blink::AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override;
#if BUILDFLAG(ENABLE_PLUGINS)
void RegisterPeripheralPlugin(
const url::Origin& content_origin,
@@ -485,7 +491,7 @@ class CONTENT_EXPORT RenderFrameImpl
void SetPreviewsState(PreviewsState previews_state) override;
PreviewsState GetPreviewsState() const override;
bool IsPasting() const override;
- blink::WebPageVisibilityState GetVisibilityState() const override;
+ blink::mojom::PageVisibilityState GetVisibilityState() const override;
bool IsBrowserSideNavigationPending() override;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(
blink::TaskType task_type) override;
@@ -505,10 +511,22 @@ class CONTENT_EXPORT RenderFrameImpl
// mojom::Frame implementation:
void GetInterfaceProvider(
service_manager::mojom::InterfaceProviderRequest request) override;
+ void GetCanonicalUrlForSharing(
+ GetCanonicalUrlForSharingCallback callback) override;
// mojom::FrameBindingsControl implementation:
void AllowBindings(int32_t enabled_bindings_flags) override;
+ // mojom::FrameNavigationControl implementation:
+ void CommitNavigation(
+ const ResourceResponseHead& head,
+ const GURL& body_url,
+ const CommonNavigationParams& common_params,
+ const RequestNavigationParams& request_params,
+ mojo::ScopedDataPipeConsumerHandle body_data,
+ base::Optional<URLLoaderFactoryBundle> subresource_loaders,
+ const base::UnguessableToken& devtools_navigation_token) override;
+
// mojom::HostZoom implementation:
void SetHostZoomLevel(const GURL& url, double zoom_level) override;
@@ -535,6 +553,8 @@ class CONTENT_EXPORT RenderFrameImpl
std::unique_ptr<blink::WebServiceWorkerProvider> CreateServiceWorkerProvider()
override;
service_manager::InterfaceProvider* GetInterfaceProvider() override;
+ blink::AssociatedInterfaceProvider* GetRemoteNavigationAssociatedInterfaces()
+ override;
void DidAccessInitialDocument() override;
blink::WebLocalFrame* CreateChildFrame(
blink::WebLocalFrame* parent,
@@ -542,7 +562,7 @@ class CONTENT_EXPORT RenderFrameImpl
const blink::WebString& name,
const blink::WebString& fallback_name,
blink::WebSandboxFlags sandbox_flags,
- const blink::WebParsedFeaturePolicy& container_policy,
+ const blink::ParsedFeaturePolicy& container_policy,
const blink::WebFrameOwnerProperties& frame_owner_properties) override;
void DidChangeOpener(blink::WebFrame* frame) override;
void FrameDetached(DetachType type) override;
@@ -556,9 +576,10 @@ class CONTENT_EXPORT RenderFrameImpl
void DidChangeFramePolicy(
blink::WebFrame* child_frame,
blink::WebSandboxFlags flags,
- const blink::WebParsedFeaturePolicy& container_policy) override;
- void DidSetFeaturePolicyHeader(
- const blink::WebParsedFeaturePolicy& parsed_header) override;
+ const blink::ParsedFeaturePolicy& container_policy) override;
+ void DidSetFramePolicyHeaders(
+ blink::WebSandboxFlags flags,
+ const blink::ParsedFeaturePolicy& parsed_header) override;
void DidAddContentSecurityPolicies(
const blink::WebVector<blink::WebContentSecurityPolicy>&) override;
void DidChangeFrameOwnerProperties(
@@ -657,6 +678,7 @@ class CONTENT_EXPORT RenderFrameImpl
void DidObserveLoadingBehavior(
blink::WebLoadingBehaviorFlag behavior) override;
void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) override;
+ bool ShouldTrackUseCounter(const blink::WebURL& url) override;
void DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) override;
void WillReleaseScriptContext(v8::Local<v8::Context> context,
@@ -708,11 +730,15 @@ class CONTENT_EXPORT RenderFrameImpl
const blink::WebString& sink_id,
const blink::WebSecurityOrigin& security_origin,
blink::WebSetSinkIdCallbacks* web_callbacks) override;
- blink::WebPageVisibilityState VisibilityState() const override;
- std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
+ blink::mojom::PageVisibilityState VisibilityState() const override;
+ std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory() override;
void DraggableRegionsChanged() override;
+ // |rect_to_scroll| is with respect to this frame's origin. |rect_to_scroll|
+ // will later be converted to this frame's parent frame origin before being
+ // continuing recursive scrolling in the parent frame's process.
+ void ScrollRectToVisibleInParentFrame(
+ const blink::WebRect& rect_to_scroll,
+ const blink::WebRemoteScrollProperties& properties) override;
// WebFrameSerializerClient implementation:
void DidSerializeDataForFrame(
@@ -729,16 +755,17 @@ class CONTENT_EXPORT RenderFrameImpl
// Binds to the FrameHost in the browser.
void BindFrame(const service_manager::BindSourceInfo& browser_info,
- mojom::FrameRequest request,
- mojom::FrameHostInterfaceBrokerPtr frame_host);
+ mojom::FrameRequest request);
// Virtual so that a TestRenderFrame can mock out the interface.
virtual mojom::FrameHost* GetFrameHost();
void BindFrameBindingsControl(
mojom::FrameBindingsControlAssociatedRequest request);
+ void BindFrameNavigationControl(
+ mojom::FrameNavigationControlAssociatedRequest request);
- ManifestManager* manifest_manager();
+ blink::mojom::ManifestManager& GetManifestManager();
// TODO(creis): Remove when the only caller, the HistoryController, is no
// more.
@@ -764,6 +791,13 @@ class CONTENT_EXPORT RenderFrameImpl
bool ScheduleFileChooser(const FileChooserParams& params,
blink::WebFileChooserCompletion* completion);
+ // Internal version of DidFailProvisionalLoad() that allows specifying
+ // |error_page_content|.
+ void DidFailProvisionalLoadInternal(
+ const blink::WebURLError& error,
+ blink::WebHistoryCommitType commit_type,
+ const base::Optional<std::string>& error_page_content);
+
bool handling_select_range() const { return handling_select_range_; }
void set_is_pasting(bool value) { is_pasting_ = value; }
@@ -812,11 +846,13 @@ class CONTENT_EXPORT RenderFrameImpl
void SyncSelectionIfRequired();
// Sets the custom URLLoaderFactory instance to be used for network requests.
- void SetCustomURLLoadeFactory(
- mojo::MessagePipeHandle custom_loader_factory_handle);
+ void SetCustomURLLoaderFactory(mojom::URLLoaderFactoryPtr factory);
+
+ void ScrollFocusedEditableElementIntoRect(const gfx::Rect& rect);
+ void DidChangeVisibleViewport();
protected:
- explicit RenderFrameImpl(const CreateParams& params);
+ explicit RenderFrameImpl(CreateParams params);
private:
friend class RenderFrameImplTest;
@@ -829,6 +865,7 @@ class CONTENT_EXPORT RenderFrameImpl
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuTest, ShowPopupThenNavigate);
FRIEND_TEST_ALL_PREFIXES(RenderAccessibilityImplTest,
AccessibilityMessagesQueueWhileSwappedOut);
+ FRIEND_TEST_ALL_PREFIXES(RenderFrameImplTest, LocalChildFrameWasShown);
FRIEND_TEST_ALL_PREFIXES(RenderFrameImplTest, ZoomLimit);
FRIEND_TEST_ALL_PREFIXES(RenderFrameImplTest,
TestOverlayRoutingTokenSendsLater);
@@ -884,15 +921,19 @@ class CONTENT_EXPORT RenderFrameImpl
T original_value_;
};
+ 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.
+ // frame belongs to, and |interface_provider| is the RenderFrameHost's
+ // InterfaceProvider through which services are exposed to the RenderFrame.
static RenderFrameImpl* Create(
RenderViewImpl* render_view,
int32_t routing_id,
+ service_manager::mojom::InterfaceProviderPtr interface_provider,
const base::UnguessableToken& devtools_frame_token);
// Functions to add and remove observers for this object.
@@ -984,9 +1025,7 @@ class CONTENT_EXPORT RenderFrameImpl
void OnSnapshotAccessibilityTree(int callback_id);
void OnExtractSmartClipData(uint32_t callback_id, const gfx::Rect& rect);
void OnUpdateOpener(int opener_routing_id);
- void OnDidUpdateFramePolicy(
- blink::WebSandboxFlags flags,
- const ParsedFeaturePolicyHeader& container_policy);
+ void OnDidUpdateFramePolicy(const blink::FramePolicy& frame_policy);
void OnSetFrameOwnerProperties(
const FrameOwnerProperties& frame_owner_properties);
void OnAdvanceFocus(blink::WebFocusType type, int32_t source_routing_id);
@@ -995,16 +1034,12 @@ class CONTENT_EXPORT RenderFrameImpl
void OnTextTrackSettingsChanged(
const FrameMsg_TextTrackSettings_Params& params);
void OnPostMessageEvent(const FrameMsg_PostMessage_Params& params);
- void OnCommitNavigation(
- const ResourceResponseHead& response,
- const GURL& stream_url,
- const FrameMsg_CommitDataNetworkService_Params& commit_data,
+ void OnFailedNavigation(
const CommonNavigationParams& common_params,
- const RequestNavigationParams& request_params);
- void OnFailedNavigation(const CommonNavigationParams& common_params,
- const RequestNavigationParams& request_params,
- bool has_stale_copy_in_cache,
- int error_code);
+ const RequestNavigationParams& request_params,
+ bool has_stale_copy_in_cache,
+ int error_code,
+ const base::Optional<std::string>& error_page_content);
void OnReportContentSecurityPolicyViolation(
const content::CSPViolationParams& violation_params);
void OnGetSavableResourceLinks();
@@ -1060,7 +1095,7 @@ class CONTENT_EXPORT RenderFrameImpl
// the current code path and the browser-side navigation path (in
// development). Currently used by OnNavigate, with all *NavigationParams
// provided by the browser. |stream_params| should be null.
- // PlzNavigate: used by OnCommitNavigation, with |common_params| and
+ // PlzNavigate: used by CommitNavigation, with |common_params| and
// |request_params| received by the browser. |stream_params| should be non
// null and created from the information provided by the browser.
// |start_params| is not used.
@@ -1068,7 +1103,17 @@ class CONTENT_EXPORT RenderFrameImpl
const CommonNavigationParams& common_params,
const StartNavigationParams& start_params,
const RequestNavigationParams& request_params,
- std::unique_ptr<StreamOverrideParameters> stream_params);
+ std::unique_ptr<StreamOverrideParameters> stream_params,
+ base::Optional<URLLoaderFactoryBundle> subresource_loader_factories,
+ const base::UnguessableToken& devtools_navigation_token);
+
+ // Returns a URLLoaderFactoryBundle which can be used to request subresources
+ // for this frame. Only valid to call when the Network Service is enabled.
+ // For frames with committed navigations, this bundle is provided by the
+ // browser at navigation time. For any other frames (i.e. frames on the
+ // initial about:blank Document), the bundle returned here is lazily cloned
+ // from the parent or opener's own bundle.
+ URLLoaderFactoryBundle& GetSubresourceLoaderFactories();
// 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
@@ -1094,10 +1139,12 @@ class CONTENT_EXPORT RenderFrameImpl
// Loads the appropriate error page for the specified failure into the frame.
// |entry| is only used by PlzNavigate when navigating to a history item.
- void LoadNavigationErrorPage(const blink::WebURLRequest& failed_request,
- const blink::WebURLError& error,
- bool replace,
- HistoryEntry* entry);
+ void LoadNavigationErrorPage(
+ const blink::WebURLRequest& failed_request,
+ const blink::WebURLError& error,
+ bool replace,
+ HistoryEntry* entry,
+ const base::Optional<std::string>& error_page_content);
void LoadNavigationErrorPageForHttpStatusError(
const blink::WebURLRequest& failed_request,
const GURL& unreachable_url,
@@ -1196,6 +1243,11 @@ 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);
@@ -1211,6 +1263,16 @@ class CONTENT_EXPORT RenderFrameImpl
void ShowDeferredContextMenu(const ContextMenuParams& params);
+ // Whether or not a navigation in this frame consumes user gestures.
+ bool ConsumeGestureOnNavigation() const;
+
+ // Whether or not the frame is controlled by a service worker.
+ bool IsControlledByServiceWorker();
+
+ mojom::URLLoaderFactory* custom_url_loader_factory() {
+ return custom_url_loader_factory_.get();
+ }
+
// Stores the WebLocalFrame we are associated with. This is null from the
// constructor until BindToFrame() is called, and it is null after
// FrameDetached() is called until destruction (which is asynchronous in the
@@ -1365,10 +1427,8 @@ class CONTENT_EXPORT RenderFrameImpl
PushMessagingClient* push_messaging_client_;
service_manager::BinderRegistry registry_;
- std::unique_ptr<service_manager::InterfaceProvider> remote_interfaces_;
+ service_manager::InterfaceProvider remote_interfaces_;
std::unique_ptr<BlinkInterfaceRegistryImpl> blink_interface_registry_;
- service_manager::mojom::InterfaceProviderRequest
- pending_remote_interface_provider_request_;
service_manager::BindSourceInfo local_info_;
service_manager::BindSourceInfo remote_info_;
@@ -1382,7 +1442,7 @@ class CONTENT_EXPORT RenderFrameImpl
// The Manifest Manager handles the manifest requests from the browser
// process.
- ManifestManager* manifest_manager_;
+ std::unique_ptr<ManifestManager> manifest_manager_;
// The current accessibility mode.
ui::AXMode accessibility_mode_;
@@ -1455,7 +1515,8 @@ class CONTENT_EXPORT RenderFrameImpl
mojo::AssociatedBinding<mojom::HostZoom> host_zoom_binding_;
mojo::AssociatedBinding<mojom::FrameBindingsControl>
frame_bindings_control_binding_;
- mojom::FrameHostInterfaceBrokerPtr frame_host_interface_broker_;
+ mojo::AssociatedBinding<mojom::FrameNavigationControl>
+ frame_navigation_control_binding_;
// Indicates whether |didAccessInitialDocument| was called.
bool has_accessed_initial_document_;
@@ -1466,6 +1527,7 @@ class CONTENT_EXPORT RenderFrameImpl
AssociatedInterfaceRegistryImpl associated_interfaces_;
std::unique_ptr<AssociatedInterfaceProviderImpl>
remote_associated_interfaces_;
+ mojom::FrameHostAssociatedPtr frame_host_;
// TODO(dcheng): Remove these members.
bool committed_first_load_ = false;
@@ -1515,6 +1577,10 @@ class CONTENT_EXPORT RenderFrameImpl
scoped_refptr<ChildURLLoaderFactoryGetter> url_loader_factory_getter_;
+ // URLLoaderFactory instances used for subresource loading when the Network
+ // Service is enabled.
+ base::Optional<URLLoaderFactoryBundle> subresource_loader_factories_;
+
// AndroidOverlay routing token from the browser, if we have one yet.
base::Optional<base::UnguessableToken> overlay_routing_token_;
@@ -1530,6 +1596,11 @@ class CONTENT_EXPORT RenderFrameImpl
// sent back from the renderer in the control calls.
blink::WebString devtools_frame_token_;
+ // Bookkeeping to suppress redundant scroll and focus requests for an already
+ // scrolled and focused editable node.
+ bool has_scrolled_focused_editable_node_into_rect_ = false;
+ gfx::Rect rect_for_scrolled_focused_editable_node_;
+
base::WeakPtrFactory<RenderFrameImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameImpl);
diff --git a/chromium/content/renderer/render_frame_impl_browsertest.cc b/chromium/content/renderer/render_frame_impl_browsertest.cc
index 3585fb90ebb..548dfa4b401 100644
--- a/chromium/content/renderer/render_frame_impl_browsertest.cc
+++ b/chromium/content/renderer/render_frame_impl_browsertest.cc
@@ -9,7 +9,6 @@
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
-#include "content/child/web_url_loader_impl.h"
#include "content/common/frame_messages.h"
#include "content/common/frame_owner_properties.h"
#include "content/common/renderer.mojom.h"
@@ -19,6 +18,8 @@
#include "content/public/test/frame_load_waiter.h"
#include "content/public/test/render_view_test.h"
#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/render_frame_impl.h"
#include "content/renderer/render_view_impl.h"
@@ -41,6 +42,7 @@ namespace {
const int32_t kSubframeRouteId = 20;
const int32_t kSubframeWidgetRouteId = 21;
const int32_t kFrameProxyRouteId = 22;
+const int32_t kEmbeddedSubframeRouteId = 23;
} // namespace
namespace content {
@@ -74,11 +76,13 @@ class RenderFrameImplTest : public RenderViewTest {
view_->GetMainRenderFrame()->GetWebFrame()->FirstChild())
->OnSwapOut(kFrameProxyRouteId, false, frame_replication_state);
+ service_manager::mojom::InterfaceProviderPtr stub_interface_provider;
+ mojo::MakeRequest(&stub_interface_provider);
RenderFrameImpl::CreateFrame(
- kSubframeRouteId, MSG_ROUTING_NONE, MSG_ROUTING_NONE,
- kFrameProxyRouteId, MSG_ROUTING_NONE, base::UnguessableToken::Create(),
- frame_replication_state, &compositor_deps_, widget_params,
- FrameOwnerProperties());
+ kSubframeRouteId, std::move(stub_interface_provider), MSG_ROUTING_NONE,
+ MSG_ROUTING_NONE, kFrameProxyRouteId, MSG_ROUTING_NONE,
+ base::UnguessableToken::Create(), frame_replication_state,
+ &compositor_deps_, widget_params, FrameOwnerProperties());
frame_ = RenderFrameImpl::FromRoutingID(kSubframeRouteId);
EXPECT_FALSE(frame_->is_main_frame_);
@@ -181,20 +185,45 @@ TEST_F(RenderFrameImplTest, FrameWasShown) {
EXPECT_TRUE(observer.visible());
}
+// Verify that a local subframe of a frame with a RenderWidget processes a
+// WasShown message.
+TEST_F(RenderFrameImplTest, LocalChildFrameWasShown) {
+ service_manager::mojom::InterfaceProviderPtr stub_interface_provider;
+ mojo::MakeRequest(&stub_interface_provider);
+
+ // Create and initialize a local child frame of the simulated OOPIF, which
+ // is a grandchild of the remote main frame.
+ RenderFrameImpl* grandchild = RenderFrameImpl::Create(
+ frame()->render_view(), kEmbeddedSubframeRouteId,
+ std::move(stub_interface_provider), base::UnguessableToken::Create());
+ blink::WebLocalFrame* parent_web_frame = frame()->GetWebFrame();
+
+ parent_web_frame->CreateLocalChild(
+ blink::WebTreeScopeType::kDocument, grandchild,
+ grandchild->blink_interface_registry_.get());
+ grandchild->in_frame_tree_ = true;
+ grandchild->Initialize();
+
+ EXPECT_EQ(grandchild->GetRenderWidget(), frame()->GetRenderWidget());
+
+ RenderFrameTestObserver observer(grandchild);
+
+ ViewMsg_WasShown was_shown_message(0, true, ui::LatencyInfo());
+ frame_widget()->OnMessageReceived(was_shown_message);
+
+ EXPECT_FALSE(frame_widget()->is_hidden());
+ EXPECT_TRUE(observer.visible());
+}
+
// 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) {
- RenderFrameTestObserver observer(frame());
-
ViewMsg_Close close_message(0);
frame_widget()->OnMessageReceived(close_message);
ViewMsg_WasShown was_shown_message(0, true, ui::LatencyInfo());
+ // Test passes if this does not crash.
static_cast<RenderViewImpl*>(view_)->OnMessageReceived(was_shown_message);
-
- // This test is primarily checking that this case does not crash, but
- // observers should still be notified.
- EXPECT_TRUE(observer.visible());
}
// Test that LoFi state only updates for new main frame documents. Subframes
@@ -359,7 +388,8 @@ TEST_F(RenderFrameImplTest, ZoomLimit) {
GetMainRenderFrame()->SetHostZoomLevel(common_params.url, kMinZoomLevel);
GetMainRenderFrame()->NavigateInternal(
common_params, StartNavigationParams(), RequestNavigationParams(),
- std::unique_ptr<StreamOverrideParameters>());
+ std::unique_ptr<StreamOverrideParameters>(), URLLoaderFactoryBundle(),
+ base::UnguessableToken::Create());
base::RunLoop().RunUntilIdle();
EXPECT_DOUBLE_EQ(kMinZoomLevel, view_->GetWebView()->ZoomLevel());
@@ -370,7 +400,8 @@ TEST_F(RenderFrameImplTest, ZoomLimit) {
GetMainRenderFrame()->SetHostZoomLevel(common_params.url, kMaxZoomLevel);
GetMainRenderFrame()->NavigateInternal(
common_params, StartNavigationParams(), RequestNavigationParams(),
- std::unique_ptr<StreamOverrideParameters>());
+ std::unique_ptr<StreamOverrideParameters>(), URLLoaderFactoryBundle(),
+ base::UnguessableToken::Create());
base::RunLoop().RunUntilIdle();
EXPECT_DOUBLE_EQ(kMaxZoomLevel, view_->GetWebView()->ZoomLevel());
}
diff --git a/chromium/content/renderer/render_frame_proxy.cc b/chromium/content/renderer/render_frame_proxy.cc
index 1f4034bc3b7..f610f834c2a 100644
--- a/chromium/content/renderer/render_frame_proxy.cc
+++ b/chromium/content/renderer/render_frame_proxy.cc
@@ -10,9 +10,7 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
-#include "components/viz/common/switches.h"
-#include "content/child/feature_policy/feature_policy_platform.h"
-#include "content/child/web_url_request_util.h"
+#include "components/viz/common/features.h"
#include "content/common/content_switches_internal.h"
#include "content/common/frame_messages.h"
#include "content/common/frame_owner_properties.h"
@@ -23,16 +21,19 @@
#include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/screen_info.h"
#include "content/renderer/child_frame_compositing_helper.h"
#include "content/renderer/frame_owner_properties.h"
+#include "content/renderer/loader/web_url_request_util.h"
#include "content/renderer/mash_util.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "content/renderer/render_widget.h"
#include "ipc/ipc_message_macros.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
+#include "third_party/WebKit/common/frame_policy.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
-#include "third_party/WebKit/public/platform/WebFeaturePolicy.h"
#include "third_party/WebKit/public/platform/WebRect.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
@@ -41,6 +42,7 @@
#include "third_party/WebKit/public/web/WebView.h"
#if defined(USE_AURA)
+#include "content/renderer/mus/mus_embedded_frame.h"
#include "content/renderer/mus/renderer_window_tree_client.h"
#endif
@@ -133,9 +135,8 @@ RenderFrameProxy* RenderFrameProxy::CreateFrameProxy(
web_frame = parent->web_frame()->CreateRemoteChild(
replicated_state.scope,
blink::WebString::FromUTF8(replicated_state.name),
- replicated_state.sandbox_flags,
- FeaturePolicyHeaderToWeb(replicated_state.container_policy),
- proxy.get(), opener);
+ replicated_state.frame_policy.sandbox_flags,
+ replicated_state.frame_policy.container_policy, proxy.get(), opener);
proxy->unique_name_ = replicated_state.unique_name;
render_view = parent->render_view();
render_widget = parent->render_widget();
@@ -178,7 +179,7 @@ RenderFrameProxy* RenderFrameProxy::FromWebFrame(
// RenderFrameProxy is already deleted--in which case, it's not safe to touch
// |web_frame|.
NOTREACHED();
- return NULL;
+ return nullptr;
}
RenderFrameProxy::RenderFrameProxy(int routing_id)
@@ -218,16 +219,15 @@ void RenderFrameProxy::Init(blink::WebRemoteFrame* web_frame,
g_frame_map.Get().insert(std::make_pair(web_frame_, this));
CHECK(result.second) << "Inserted a duplicate item.";
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- enable_surface_synchronization_ =
- command_line.HasSwitch(switches::kEnableSurfaceSynchronization);
+ enable_surface_synchronization_ = features::IsSurfaceSynchronizationEnabled();
compositing_helper_.reset(
ChildFrameCompositingHelper::CreateForRenderFrameProxy(this));
+ pending_resize_params_.screen_info = render_widget_->screen_info();
+
#if defined(USE_AURA)
- if (IsRunningInMash()) {
+ if (IsRunningWithMus()) {
RendererWindowTreeClient* renderer_window_tree_client =
RendererWindowTreeClient::Get(render_widget_->routing_id());
// It's possible a MusEmbeddedFrame has already been scheduled for creation
@@ -240,11 +240,10 @@ void RenderFrameProxy::Init(blink::WebRemoteFrame* web_frame,
#endif
}
-void RenderFrameProxy::ResendFrameRects() {
- // Reset |frame_rect_| in order to allocate a new viz::LocalSurfaceId.
- gfx::Rect rect = frame_rect_;
- frame_rect_ = gfx::Rect();
- FrameRectsChanged(rect);
+void RenderFrameProxy::ResendResizeParams() {
+ // Reset |sent_resize_params_| in order to allocate a new viz::LocalSurfaceId.
+ sent_resize_params_ = base::nullopt;
+ WasResized();
}
void RenderFrameProxy::WillBeginCompositorFrame() {
@@ -261,16 +260,20 @@ void RenderFrameProxy::WillBeginCompositorFrame() {
void RenderFrameProxy::DidCommitCompositorFrame() {
}
+void RenderFrameProxy::OnScreenInfoChanged(const ScreenInfo& screen_info) {
+ pending_resize_params_.screen_info = screen_info;
+ WasResized();
+}
+
void RenderFrameProxy::SetReplicatedState(const FrameReplicationState& state) {
DCHECK(web_frame_);
web_frame_->SetReplicatedOrigin(state.origin);
- web_frame_->SetReplicatedSandboxFlags(state.sandbox_flags);
+ web_frame_->SetReplicatedSandboxFlags(state.active_sandbox_flags);
web_frame_->SetReplicatedName(blink::WebString::FromUTF8(state.name));
web_frame_->SetReplicatedInsecureRequestPolicy(state.insecure_request_policy);
web_frame_->SetReplicatedPotentiallyTrustworthyUniqueOrigin(
state.has_potentially_trustworthy_unique_origin);
- web_frame_->SetReplicatedFeaturePolicyHeader(
- FeaturePolicyHeaderToWeb(state.feature_policy_header));
+ web_frame_->SetReplicatedFeaturePolicyHeader(state.feature_policy_header);
if (state.has_received_user_gesture)
web_frame_->SetHasReceivedUserGesture();
@@ -278,8 +281,8 @@ void RenderFrameProxy::SetReplicatedState(const FrameReplicationState& state) {
OnAddContentSecurityPolicies(state.accumulated_csp_headers);
}
-// Update the proxy's SecurityContext and FrameOwner with new sandbox flags
-// and container policy that were set by its parent in another process.
+// Update the proxy's FrameOwner with new sandbox flags and container policy
+// that were set by its parent in another process.
//
// Normally, when a frame's sandbox attribute is changed dynamically, the
// frame's FrameOwner is updated with the new sandbox flags right away, while
@@ -288,31 +291,46 @@ void RenderFrameProxy::SetReplicatedState(const FrameReplicationState& state) {
//
// Currently, there is no use case for a proxy's pending FrameOwner sandbox
// flags, so there's no message sent to proxies when the sandbox attribute is
-// first updated. Instead, the update message is sent and this function is
-// called when the new flags take effect, so that the proxy updates its
-// SecurityContext. This is needed to ensure that sandbox flags are inherited
-// properly if this proxy ever parents a local frame. The proxy's FrameOwner
-// flags are also updated here with the caveat that the FrameOwner won't learn
-// about updates to its flags until they take effect.
+// first updated. Instead, the active flags are updated when they take effect,
+// by OnDidSetActiveSandboxFlags. The proxy's FrameOwner flags are updated here
+// with the caveat that the FrameOwner won't learn about updates to its flags
+// until they take effect.
void RenderFrameProxy::OnDidUpdateFramePolicy(
- blink::WebSandboxFlags flags,
- const ParsedFeaturePolicyHeader& container_policy) {
- web_frame_->SetReplicatedSandboxFlags(flags);
- web_frame_->SetFrameOwnerPolicy(flags,
- FeaturePolicyHeaderToWeb(container_policy));
+ const blink::FramePolicy& frame_policy) {
+ DCHECK(web_frame()->Parent());
+ web_frame_->SetFrameOwnerPolicy(frame_policy.sandbox_flags,
+ frame_policy.container_policy);
}
-void RenderFrameProxy::MaybeUpdateCompositingHelper() {
- if (!frame_sink_id_.is_valid() || !local_surface_id_.is_valid())
- return;
+// Update the proxy's SecurityContext with new sandbox flags that were set
+// during navigation. Unlike changes to the FrameOwner, which are handled by
+// OnDidUpdateFramePolicy, these flags should be considered effective
+// immediately.
+//
+// These flags are needed on the remote frame's SecurityContext to ensure that
+// sandbox flags are inherited properly if this proxy ever parents a local
+// frame.
+void RenderFrameProxy::OnDidSetActiveSandboxFlags(
+ blink::WebSandboxFlags active_sandbox_flags) {
+ web_frame_->SetReplicatedSandboxFlags(active_sandbox_flags);
+}
- float device_scale_factor = render_widget_->GetOriginalDeviceScaleFactor();
- viz::SurfaceInfo surface_info(
- viz::SurfaceId(frame_sink_id_, local_surface_id_), device_scale_factor,
- gfx::ScaleToCeiledSize(frame_rect_.size(), device_scale_factor));
+void RenderFrameProxy::SetChildFrameSurface(
+ const viz::SurfaceInfo& surface_info,
+ const viz::SurfaceSequence& sequence) {
+ // If this WebFrame has already been detached, its parent will be null. This
+ // can happen when swapping a WebRemoteFrame with a WebLocalFrame, where this
+ // message may arrive after the frame was removed from the frame tree, but
+ // before the frame has been destroyed. http://crbug.com/446575.
+ if (!web_frame()->Parent())
+ return;
- if (enable_surface_synchronization_)
- compositing_helper_->SetPrimarySurfaceInfo(surface_info);
+ if (!enable_surface_synchronization_) {
+ compositing_helper_->SetPrimarySurfaceId(surface_info.id(),
+ frame_rect().size());
+ }
+ compositing_helper_->SetFallbackSurfaceId(surface_info.id(),
+ frame_rect().size(), sequence);
}
bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
@@ -334,6 +352,8 @@ bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(FrameMsg_DidStartLoading, OnDidStartLoading)
IPC_MESSAGE_HANDLER(FrameMsg_DidStopLoading, OnDidStopLoading)
IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateFramePolicy, OnDidUpdateFramePolicy)
+ IPC_MESSAGE_HANDLER(FrameMsg_DidSetActiveSandboxFlags,
+ OnDidSetActiveSandboxFlags)
IPC_MESSAGE_HANDLER(FrameMsg_DispatchLoad, OnDispatchLoad)
IPC_MESSAGE_HANDLER(FrameMsg_Collapse, OnCollapse)
IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateName, OnDidUpdateName)
@@ -347,10 +367,12 @@ bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
OnSetFrameOwnerProperties)
IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateOrigin, OnDidUpdateOrigin)
IPC_MESSAGE_HANDLER(InputMsg_SetFocus, OnSetPageFocus)
+ IPC_MESSAGE_HANDLER(FrameMsg_ResizeDueToAutoResize, OnResizeDueToAutoResize)
IPC_MESSAGE_HANDLER(FrameMsg_SetFocusedFrame, OnSetFocusedFrame)
IPC_MESSAGE_HANDLER(FrameMsg_WillEnterFullscreen, OnWillEnterFullscreen)
IPC_MESSAGE_HANDLER(FrameMsg_SetHasReceivedUserGesture,
OnSetHasReceivedUserGesture)
+ IPC_MESSAGE_HANDLER(FrameMsg_ScrollRectToVisible, OnScrollRectToVisible)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -374,16 +396,7 @@ void RenderFrameProxy::OnChildFrameProcessGone() {
void RenderFrameProxy::OnSetChildFrameSurface(
const viz::SurfaceInfo& surface_info,
const viz::SurfaceSequence& sequence) {
- // If this WebFrame has already been detached, its parent will be null. This
- // can happen when swapping a WebRemoteFrame with a WebLocalFrame, where this
- // message may arrive after the frame was removed from the frame tree, but
- // before the frame has been destroyed. http://crbug.com/446575.
- if (!web_frame()->Parent())
- return;
-
- if (!enable_surface_synchronization_)
- compositing_helper_->SetPrimarySurfaceInfo(surface_info);
- compositing_helper_->SetFallbackSurfaceInfo(surface_info, sequence);
+ SetChildFrameSurface(surface_info, sequence);
}
void RenderFrameProxy::OnUpdateOpener(int opener_routing_id) {
@@ -397,12 +410,12 @@ void RenderFrameProxy::OnDidStartLoading() {
void RenderFrameProxy::OnViewChanged(const viz::FrameSinkId& frame_sink_id) {
// In mash the FrameSinkId comes from RendererWindowTreeClient.
- if (!IsRunningInMash())
+ if (!IsRunningWithMus())
frame_sink_id_ = frame_sink_id;
// Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
// changes.
- ResendFrameRects();
+ ResendResizeParams();
}
void RenderFrameProxy::OnDidStopLoading() {
@@ -473,22 +486,62 @@ void RenderFrameProxy::OnSetHasReceivedUserGesture() {
web_frame_->SetHasReceivedUserGesture();
}
-#if defined(USE_AURA)
-void RenderFrameProxy::OnMusFrameSinkIdAllocated(
- const viz::FrameSinkId& frame_sink_id) {
- frame_sink_id_ = frame_sink_id;
- MaybeUpdateCompositingHelper();
- // Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
- // changes.
- ResendFrameRects();
+void RenderFrameProxy::OnScrollRectToVisible(
+ const gfx::Rect& rect_to_scroll,
+ const blink::WebRemoteScrollProperties& properties) {
+ web_frame_->ScrollRectToVisible(rect_to_scroll, properties);
+}
+
+void RenderFrameProxy::OnResizeDueToAutoResize(uint64_t sequence_number) {
+ pending_resize_params_.sequence_number = sequence_number;
+ WasResized();
}
+#if defined(USE_AURA)
void RenderFrameProxy::SetMusEmbeddedFrame(
std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame) {
mus_embedded_frame_ = std::move(mus_embedded_frame);
}
#endif
+void RenderFrameProxy::WasResized() {
+ if (!frame_sink_id_.is_valid())
+ return;
+
+ bool synchronized_params_changed =
+ !sent_resize_params_ ||
+ sent_resize_params_->frame_rect.size() !=
+ pending_resize_params_.frame_rect.size() ||
+ sent_resize_params_->screen_info != pending_resize_params_.screen_info ||
+ sent_resize_params_->sequence_number !=
+ pending_resize_params_.sequence_number;
+
+ if (synchronized_params_changed)
+ local_surface_id_ = local_surface_id_allocator_.GenerateId();
+
+ viz::SurfaceId surface_id(frame_sink_id_, local_surface_id_);
+ if (enable_surface_synchronization_)
+ compositing_helper_->SetPrimarySurfaceId(surface_id, frame_rect().size());
+
+ bool rect_changed =
+ !sent_resize_params_ ||
+ sent_resize_params_->frame_rect != pending_resize_params_.frame_rect;
+ bool resize_params_changed = synchronized_params_changed || rect_changed;
+
+#if defined(USE_AURA)
+ if (rect_changed && mus_embedded_frame_)
+ mus_embedded_frame_->SetWindowBounds(local_surface_id_, frame_rect());
+#endif
+
+ if (resize_params_changed) {
+ // Let the browser know about the updated view rect.
+ Send(new FrameHostMsg_UpdateResizeParams(
+ routing_id_, frame_rect(), screen_info(), auto_size_sequence_number(),
+ surface_id));
+ sent_resize_params_ = pending_resize_params_;
+ }
+}
+
void RenderFrameProxy::FrameDetached(DetachType type) {
#if defined(USE_AURA)
mus_embedded_frame_.reset();
@@ -576,30 +629,9 @@ void RenderFrameProxy::Navigate(const blink::WebURLRequest& request,
}
void RenderFrameProxy::FrameRectsChanged(const blink::WebRect& frame_rect) {
- gfx::Rect rect = frame_rect;
- const bool did_size_change = frame_rect_.size() != rect.size();
-#if defined(USE_AURA)
- const bool did_rect_change = did_size_change || frame_rect_ != rect;
-#endif
-
- frame_rect_ = rect;
-
- if (did_size_change || !local_surface_id_.is_valid()) {
- local_surface_id_ = local_surface_id_allocator_.GenerateId();
- MaybeUpdateCompositingHelper();
- }
-
-#if defined(USE_AURA)
- if (did_rect_change && mus_embedded_frame_)
- mus_embedded_frame_->SetWindowBounds(local_surface_id_, rect);
-#endif
-
- if (IsUseZoomForDSFEnabled()) {
- rect = gfx::ScaleToEnclosingRect(
- rect, 1.f / render_widget_->GetOriginalDeviceScaleFactor());
- }
-
- Send(new FrameHostMsg_FrameRectChanged(routing_id_, rect, local_surface_id_));
+ pending_resize_params_.frame_rect = gfx::Rect(frame_rect);
+ pending_resize_params_.screen_info = render_widget_->screen_info();
+ WasResized();
}
void RenderFrameProxy::UpdateRemoteViewportIntersection(
@@ -616,6 +648,12 @@ void RenderFrameProxy::SetIsInert(bool inert) {
Send(new FrameHostMsg_SetIsInert(routing_id_, inert));
}
+void RenderFrameProxy::UpdateRenderThrottlingStatus(bool is_throttled,
+ bool subtree_throttled) {
+ Send(new FrameHostMsg_UpdateRenderThrottlingStatus(routing_id_, is_throttled,
+ subtree_throttled));
+}
+
void RenderFrameProxy::DidChangeOpener(blink::WebFrame* opener) {
// A proxy shouldn't normally be disowning its opener. It is possible to get
// here when a proxy that is being detached clears its opener, in which case
@@ -642,4 +680,19 @@ void RenderFrameProxy::FrameFocused() {
Send(new FrameHostMsg_FrameFocused(routing_id_));
}
+#if defined(USE_AURA)
+void RenderFrameProxy::OnMusEmbeddedFrameSurfaceChanged(
+ const viz::SurfaceInfo& surface_info) {
+ SetChildFrameSurface(surface_info, viz::SurfaceSequence());
+}
+
+void RenderFrameProxy::OnMusEmbeddedFrameSinkIdAllocated(
+ const viz::FrameSinkId& frame_sink_id) {
+ frame_sink_id_ = frame_sink_id;
+ // Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
+ // changes.
+ ResendResizeParams();
+}
+#endif
+
} // namespace
diff --git a/chromium/content/renderer/render_frame_proxy.h b/chromium/content/renderer/render_frame_proxy.h
index 96095b41321..00f88ee4690 100644
--- a/chromium/content/renderer/render_frame_proxy.h
+++ b/chromium/content/renderer/render_frame_proxy.h
@@ -9,17 +9,24 @@
#include "base/memory/ref_counted.h"
#include "components/viz/common/surfaces/local_surface_id_allocator.h"
#include "content/common/content_export.h"
-#include "content/common/feature_policy/feature_policy.h"
+#include "content/public/common/screen_info.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.h"
#include "third_party/WebKit/public/platform/WebFocusType.h"
#include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h"
#include "third_party/WebKit/public/web/WebRemoteFrame.h"
#include "third_party/WebKit/public/web/WebRemoteFrameClient.h"
#include "url/origin.h"
+#if defined(USE_AURA)
+#include "content/renderer/mus/mus_embedded_frame_delegate.h"
+#endif
+
namespace blink {
+struct FramePolicy;
struct WebRect;
+struct WebRemoteScrollProperties;
}
namespace viz {
@@ -63,6 +70,9 @@ class MusEmbeddedFrame;
// RenderFrame is created for it.
class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
public IPC::Sender,
+#if defined(USE_AURA)
+ public MusEmbeddedFrameDelegate,
+#endif
public blink::WebRemoteFrameClient {
public:
// This method should be used to create a RenderFrameProxy, which will replace
@@ -115,6 +125,10 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
// when a compositor frame has committed.
void DidCommitCompositorFrame();
+ // Out-of-process child frames receive a signal from RenderWidget when the
+ // ScreenInfo has changed.
+ void OnScreenInfoChanged(const ScreenInfo& screen_info);
+
// Pass replicated information, such as security origin, to this
// RenderFrameProxy's WebRemoteFrame.
void SetReplicatedState(const FrameReplicationState& state);
@@ -134,13 +148,24 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
RenderWidget* render_widget() { return render_widget_; }
#if defined(USE_AURA)
- // Called when mus determines the FrameSinkId.
- void OnMusFrameSinkIdAllocated(const viz::FrameSinkId& frame_sink_id);
-
void SetMusEmbeddedFrame(
std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame);
#endif
+ void WasResized();
+
+ const gfx::Rect& frame_rect() const {
+ return pending_resize_params_.frame_rect;
+ }
+
+ const ScreenInfo& screen_info() const {
+ return pending_resize_params_.screen_info;
+ }
+
+ uint64_t auto_size_sequence_number() const {
+ return pending_resize_params_.sequence_number;
+ }
+
// blink::WebRemoteFrameClient implementation:
void FrameDetached(DetachType type) override;
void ForwardPostMessage(blink::WebLocalFrame* sourceFrame,
@@ -154,6 +179,8 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
const blink::WebRect& viewportIntersection) override;
void VisibilityChanged(bool visible) override;
void SetIsInert(bool) override;
+ void UpdateRenderThrottlingStatus(bool is_throttled,
+ bool subtree_throttled) override;
void DidChangeOpener(blink::WebFrame* opener) override;
void AdvanceFocus(blink::WebFocusType type,
blink::WebLocalFrame* source) override;
@@ -169,9 +196,10 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
RenderViewImpl* render_view,
RenderWidget* render_widget);
- void ResendFrameRects();
+ void ResendResizeParams();
- void MaybeUpdateCompositingHelper();
+ void SetChildFrameSurface(const viz::SurfaceInfo& surface_info,
+ const viz::SurfaceSequence& sequence);
// IPC::Listener
bool OnMessageReceived(const IPC::Message& msg) override;
@@ -185,9 +213,8 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
void OnUpdateOpener(int opener_routing_id);
void OnViewChanged(const viz::FrameSinkId& frame_sink_id);
void OnDidStopLoading();
- void OnDidUpdateFramePolicy(
- blink::WebSandboxFlags flags,
- const ParsedFeaturePolicyHeader& container_policy);
+ void OnDidUpdateFramePolicy(const blink::FramePolicy& frame_policy);
+ void OnDidSetActiveSandboxFlags(blink::WebSandboxFlags active_sandbox_flags);
void OnDispatchLoad();
void OnCollapse(bool collapsed);
void OnDidUpdateName(const std::string& name, const std::string& unique_name);
@@ -202,6 +229,18 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
void OnSetFocusedFrame();
void OnWillEnterFullscreen();
void OnSetHasReceivedUserGesture();
+ void OnScrollRectToVisible(
+ const gfx::Rect& rect_to_scroll,
+ const blink::WebRemoteScrollProperties& properties);
+ void OnResizeDueToAutoResize(uint64_t sequence_number);
+
+#if defined(USE_AURA)
+ // MusEmbeddedFrameDelegate
+ void OnMusEmbeddedFrameSurfaceChanged(
+ const viz::SurfaceInfo& surface_info) override;
+ void OnMusEmbeddedFrameSinkIdAllocated(
+ const viz::FrameSinkId& frame_sink_id) override;
+#endif
// The routing ID by which this RenderFrameProxy is known.
const int routing_id_;
@@ -218,7 +257,23 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
RenderViewImpl* render_view_;
RenderWidget* render_widget_;
- gfx::Rect frame_rect_;
+ // TODO(fsamuel): We might want to unify this with content::ResizeParams.
+ // TODO(fsamuel): Most RenderFrameProxys don't host viz::Surfaces and
+ // therefore don't care to synchronize ResizeParams with viz::LocalSurfaceIds.
+ // Perhaps this can be moved to ChildFrameCompositingHelper?
+ struct ResizeParams {
+ gfx::Rect frame_rect;
+ ScreenInfo screen_info;
+ uint64_t sequence_number = 0lu;
+ };
+
+ // The last ResizeParams sent to the browser process, if any.
+ base::Optional<ResizeParams> sent_resize_params_;
+
+ // The current set of ResizeParams. This may or may not match
+ // |sent_resize_params_|.
+ ResizeParams pending_resize_params_;
+
viz::FrameSinkId frame_sink_id_;
viz::LocalSurfaceId local_surface_id_;
viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
diff --git a/chromium/content/renderer/render_process_impl.cc b/chromium/content/renderer/render_process_impl.cc
index a074479fa80..c42b77c1d47 100644
--- a/chromium/content/renderer/render_process_impl.cc
+++ b/chromium/content/renderer/render_process_impl.cc
@@ -27,13 +27,13 @@
#include "base/sys_info.h"
#include "base/task_scheduler/initialization_util.h"
#include "base/time/time.h"
-#include "content/child/site_isolation_stats_gatherer.h"
#include "content/common/task_scheduler.h"
#include "content/public/common/bindings_policy.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/renderer/content_renderer_client.h"
+#include "content/renderer/loader/site_isolation_stats_gatherer.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "v8/include/v8.h"
@@ -70,7 +70,7 @@ GetDefaultTaskSchedulerInitParams() {
constexpr int kMaxNumThreadsInForegroundBlockingPool = 1;
constexpr auto kSuggestedReclaimTime = base::TimeDelta::FromSeconds(30);
- return base::MakeUnique<base::TaskScheduler::InitParams>(
+ return std::make_unique<base::TaskScheduler::InitParams>(
base::SchedulerWorkerPoolParams(kMaxNumThreadsInBackgroundPool,
kSuggestedReclaimTime),
base::SchedulerWorkerPoolParams(kMaxNumThreadsInBackgroundBlockingPool,
@@ -150,10 +150,15 @@ RenderProcessImpl::RenderProcessImpl(
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");
SetV8FlagIfNotFeature(features::kWebAssembly,
"--wasm-disable-structured-cloning");
+
+ SetV8FlagIfFeature(features::kV8VmFuture, "--future");
+ SetV8FlagIfNotFeature(features::kV8VmFuture, "--no-future");
SetV8FlagIfFeature(features::kSharedArrayBuffer,
"--harmony-sharedarraybuffer");
SetV8FlagIfNotFeature(features::kSharedArrayBuffer,
diff --git a/chromium/content/renderer/render_thread_impl.cc b/chromium/content/renderer/render_thread_impl.cc
index 13eeab3a946..10b32b1254c 100644
--- a/chromium/content/renderer/render_thread_impl.cc
+++ b/chromium/content/renderer/render_thread_impl.cc
@@ -56,31 +56,19 @@
#include "components/viz/client/client_shared_bitmap_manager.h"
#include "components/viz/client/hit_test_data_provider.h"
#include "components/viz/client/local_surface_id_provider.h"
+#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/gpu/vulkan_in_process_context_provider.h"
#include "components/viz/common/resources/buffer_to_texture_target_map.h"
-#include "components/viz/common/switches.h"
-#include "content/child/appcache/appcache_dispatcher.h"
-#include "content/child/appcache/appcache_frontend_impl.h"
-#include "content/child/blob_storage/blob_message_filter.h"
-#include "content/child/child_resource_message_filter.h"
-#include "content/child/indexed_db/indexed_db_dispatcher.h"
#include "content/child/memory/child_memory_coordinator_impl.h"
-#include "content/child/resource_dispatcher.h"
-#include "content/child/resource_scheduling_filter.h"
#include "content/child/runtime_features.h"
#include "content/child/thread_safe_sender.h"
-#include "content/child/web_database_impl.h"
-#include "content/child/web_database_observer_impl.h"
-#include "content/child/worker_thread_registry.h"
-#include "content/common/child_process_messages.h"
#include "content/common/content_constants_internal.h"
#include "content/common/dom_storage/dom_storage_messages.h"
#include "content/common/features.h"
#include "content/common/frame_messages.h"
#include "content/common/frame_owner_properties.h"
#include "content/common/gpu_stream_constants.h"
-#include "content/common/render_process_messages.h"
#include "content/common/resource_messages.h"
#include "content/common/site_isolation_policy.h"
#include "content/common/view_messages.h"
@@ -96,21 +84,29 @@
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/render_thread_observer.h"
#include "content/public/renderer/render_view_visitor.h"
+#include "content/renderer/appcache/appcache_dispatcher.h"
+#include "content/renderer/appcache/appcache_frontend_impl.h"
+#include "content/renderer/blob_storage/blob_message_filter.h"
#include "content/renderer/browser_plugin/browser_plugin_manager.h"
#include "content/renderer/cache_storage/cache_storage_dispatcher.h"
#include "content/renderer/cache_storage/cache_storage_message_filter.h"
#include "content/renderer/categorized_worker_pool.h"
-#include "content/renderer/devtools/devtools_agent_filter.h"
#include "content/renderer/dom_storage/dom_storage_dispatcher.h"
#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/compositor_external_begin_frame_source.h"
#include "content/renderer/gpu/compositor_forwarding_message_filter.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
+#include "content/renderer/indexed_db/indexed_db_dispatcher.h"
#include "content/renderer/input/input_event_filter.h"
#include "content/renderer/input/input_handler_manager.h"
#include "content/renderer/input/main_thread_input_event_filter.h"
+#include "content/renderer/loader/child_resource_message_filter.h"
+#include "content/renderer/loader/resource_dispatcher.h"
+#include "content/renderer/loader/resource_scheduling_filter.h"
#include "content/renderer/mash_util.h"
#include "content/renderer/media/audio_input_message_filter.h"
#include "content/renderer/media/audio_message_filter.h"
@@ -120,10 +116,13 @@
#include "content/renderer/media/midi_message_filter.h"
#include "content/renderer/media/render_media_client.h"
#include "content/renderer/media/video_capture_impl_manager.h"
+#include "content/renderer/mojo/blink_interface_registry_impl.h"
#include "content/renderer/mus/render_widget_window_tree_client_factory.h"
#include "content/renderer/mus/renderer_window_tree_client.h"
#include "content/renderer/net_info_helper.h"
+#include "content/renderer/notifications/notification_dispatcher.h"
#include "content/renderer/p2p/socket_dispatcher.h"
+#include "content/renderer/quota_dispatcher.h"
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_process_impl.h"
#include "content/renderer/render_view_impl.h"
@@ -132,8 +131,11 @@
#include "content/renderer/service_worker/embedded_worker_instance_client_impl.h"
#include "content/renderer/service_worker/service_worker_context_client.h"
#include "content/renderer/service_worker/service_worker_context_message_filter.h"
+#include "content/renderer/service_worker/service_worker_message_filter.h"
#include "content/renderer/shared_worker/embedded_shared_worker_stub.h"
#include "content/renderer/shared_worker/shared_worker_factory_impl.h"
+#include "content/renderer/web_database_observer_impl.h"
+#include "content/renderer/worker_thread_registry.h"
#include "device/gamepad/public/cpp/gamepads.h"
#include "gin/public/debug.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -155,6 +157,7 @@
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/base/url_util.h"
#include "ppapi/features/features.h"
+#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
@@ -182,6 +185,7 @@
#include "third_party/skia/include/core/SkGraphics.h"
#include "ui/base/layout.h"
#include "ui/base/ui_base_switches.h"
+#include "ui/base/ui_base_switches_util.h"
#include "ui/display/display_switches.h"
#include "ui/gl/gl_switches.h"
@@ -333,10 +337,8 @@ class FrameFactoryImpl : public mojom::FrameFactory {
private:
// mojom::FrameFactory:
- void CreateFrame(
- int32_t frame_routing_id,
- mojom::FrameRequest frame_request,
- mojom::FrameHostInterfaceBrokerPtr frame_host_interface_broker) override {
+ void CreateFrame(int32_t frame_routing_id,
+ mojom::FrameRequest frame_request) override {
// TODO(morrita): This is for investigating http://crbug.com/415059 and
// should be removed once it is fixed.
CHECK_LT(routing_id_highmark_, frame_routing_id);
@@ -349,13 +351,11 @@ class FrameFactoryImpl : public mojom::FrameFactory {
// we want.
if (!frame) {
RenderThreadImpl::current()->RegisterPendingFrameCreate(
- source_info_, frame_routing_id, std::move(frame_request),
- std::move(frame_host_interface_broker));
+ source_info_, frame_routing_id, std::move(frame_request));
return;
}
- frame->BindFrame(source_info_, std::move(frame_request),
- std::move(frame_host_interface_broker));
+ frame->BindFrame(source_info_, std::move(frame_request));
}
private:
@@ -365,7 +365,7 @@ class FrameFactoryImpl : public mojom::FrameFactory {
void CreateFrameFactory(mojom::FrameFactoryRequest request,
const service_manager::BindSourceInfo& source_info) {
- mojo::MakeStrongBinding(base::MakeUnique<FrameFactoryImpl>(source_info),
+ mojo::MakeStrongBinding(std::make_unique<FrameFactoryImpl>(source_info),
std::move(request));
}
@@ -439,6 +439,28 @@ class RendererLocalSurfaceIdProvider : public viz::LocalSurfaceIdProvider {
RenderWidgetSurfaceProperties surface_properties_;
};
+// This factory is used to defer binding of the InterfacePtr to the compositor
+// thread.
+class UkmRecorderFactoryImpl : public cc::UkmRecorderFactory {
+ public:
+ UkmRecorderFactoryImpl(ukm::mojom::UkmRecorderInterfacePtrInfo info)
+ : info_(std::move(info)) {
+ DCHECK(info_.is_valid());
+ }
+ ~UkmRecorderFactoryImpl() override = default;
+
+ std::unique_ptr<ukm::UkmRecorder> CreateRecorder() override {
+ DCHECK(info_.is_valid());
+
+ ukm::mojom::UkmRecorderInterfacePtr recorder;
+ recorder.Bind(std::move(info_));
+ return std::make_unique<ukm::MojoUkmRecorder>(std::move(recorder));
+ }
+
+ private:
+ ukm::mojom::UkmRecorderInterfacePtrInfo info_;
+};
+
} // namespace
RenderThreadImpl::HistogramCustomizer::HistogramCustomizer() {
@@ -602,15 +624,18 @@ RenderThreadImpl::RenderThreadImpl(
const InProcessChildThreadParams& params,
std::unique_ptr<blink::scheduler::RendererScheduler> scheduler,
const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue)
- : ChildThreadImpl(Options::Builder()
- .InBrowserProcess(params)
- .AutoStartServiceManagerConnection(false)
- .ConnectToBrowser(true)
- .Build()),
+ : ChildThreadImpl(
+ Options::Builder()
+ .InBrowserProcess(params)
+ .AutoStartServiceManagerConnection(false)
+ .ConnectToBrowser(true)
+ .IPCTaskRunner(scheduler ? scheduler->IPCTaskRunner() : nullptr)
+ .Build()),
renderer_scheduler_(std::move(scheduler)),
categorized_worker_pool_(new CategorizedWorkerPool()),
renderer_binding_(this),
- client_id_(1) {
+ client_id_(1),
+ compositing_mode_watcher_binding_(this) {
Init(resource_task_queue);
}
@@ -619,15 +644,18 @@ RenderThreadImpl::RenderThreadImpl(
RenderThreadImpl::RenderThreadImpl(
std::unique_ptr<base::MessageLoop> main_message_loop,
std::unique_ptr<blink::scheduler::RendererScheduler> scheduler)
- : ChildThreadImpl(Options::Builder()
- .AutoStartServiceManagerConnection(false)
- .ConnectToBrowser(true)
- .Build()),
+ : ChildThreadImpl(
+ Options::Builder()
+ .AutoStartServiceManagerConnection(false)
+ .ConnectToBrowser(true)
+ .IPCTaskRunner(scheduler ? scheduler->IPCTaskRunner() : nullptr)
+ .Build()),
renderer_scheduler_(std::move(scheduler)),
main_message_loop_(std::move(main_message_loop)),
categorized_worker_pool_(new CategorizedWorkerPool()),
is_scroll_animator_enabled_(false),
- renderer_binding_(this) {
+ renderer_binding_(this),
+ compositing_mode_watcher_binding_(this) {
scoped_refptr<base::SingleThreadTaskRunner> test_task_counter;
DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kRendererClientId));
@@ -659,22 +687,38 @@ void RenderThreadImpl::Init(
base::BindRepeating(&CreateSingleSampleMetricsProvider,
message_loop()->task_runner(), GetConnector()));
- gpu_ = ui::Gpu::Create(
- GetConnector(),
- IsRunningInMash() ? ui::mojom::kServiceName : mojom::kBrowserServiceName,
- GetIOTaskRunner());
+ gpu_ =
+ ui::Gpu::Create(GetConnector(),
+ switches::IsMusHostingViz() ? ui::mojom::kServiceName
+ : mojom::kBrowserServiceName,
+ GetIOTaskRunner());
viz::mojom::SharedBitmapAllocationNotifierPtr
shared_bitmap_allocation_notifier_ptr;
GetConnector()->BindInterface(
mojom::kBrowserServiceName,
mojo::MakeRequest(&shared_bitmap_allocation_notifier_ptr));
- shared_bitmap_manager_ = base::MakeUnique<viz::ClientSharedBitmapManager>(
+ shared_bitmap_manager_ = std::make_unique<viz::ClientSharedBitmapManager>(
viz::mojom::ThreadSafeSharedBitmapAllocationNotifierPtr::Create(
shared_bitmap_allocation_notifier_ptr.PassInterface(),
GetChannel()->ipc_task_runner_refptr()));
- InitializeWebKit(resource_task_queue);
+ notification_dispatcher_ =
+ new NotificationDispatcher(thread_safe_sender());
+ AddFilter(notification_dispatcher_->GetFilter());
+
+ resource_dispatcher_.reset(new ResourceDispatcher(
+ this, message_loop()->task_runner()));
+ resource_message_filter_ =
+ new ChildResourceMessageFilter(resource_dispatcher_.get());
+ AddFilter(resource_message_filter_.get());
+ quota_dispatcher_.reset(new QuotaDispatcher(message_loop()->task_runner()));
+
+ auto registry = std::make_unique<service_manager::BinderRegistry>();
+ BlinkInterfaceRegistryImpl interface_registry(
+ registry->GetWeakPtr(), associated_interfaces_.GetWeakPtr());
+
+ InitializeWebKit(resource_task_queue, &interface_registry);
blink_initialized_time_ = base::TimeTicks::Now();
// In single process the single process is all there is.
@@ -690,6 +734,7 @@ void RenderThreadImpl::Init(
main_thread_indexed_db_dispatcher_.reset(new IndexedDBDispatcher());
main_thread_cache_storage_dispatcher_.reset(
new CacheStorageDispatcher(thread_safe_sender()));
+ file_system_dispatcher_.reset(new FileSystemDispatcher());
// Note: This may reorder messages from the ResourceDispatcher with respect to
// other subsystems.
@@ -697,7 +742,7 @@ void RenderThreadImpl::Init(
static_cast<RenderThread*>(this), renderer_scheduler_.get(),
base::TimeDelta::FromSecondsD(kThrottledResourceRequestFlushPeriodS),
kMaxResourceRequestsPerFlushWhenThrottled));
- resource_dispatcher()->set_message_sender(resource_dispatch_throttler_.get());
+ resource_dispatcher_->set_message_sender(resource_dispatch_throttler_.get());
blob_message_filter_ = new BlobMessageFilter(GetFileThreadTaskRunner());
AddFilter(blob_message_filter_.get());
@@ -749,29 +794,24 @@ void RenderThreadImpl::Init(
// Register exported services:
#if defined(USE_AURA)
- if (IsRunningInMash()) {
+ if (IsRunningWithMus()) {
CreateRenderWidgetWindowTreeClientFactory(GetServiceManagerConnection());
}
#endif
- {
- auto registry = std::make_unique<service_manager::BinderRegistry>();
- registry->AddInterface(base::Bind(&WebDatabaseImpl::Create),
- GetIOTaskRunner());
- registry->AddInterface(base::Bind(&SharedWorkerFactoryImpl::Create),
- base::ThreadTaskRunnerHandle::Get());
- GetServiceManagerConnection()->AddConnectionFilter(
- std::make_unique<SimpleConnectionFilter>(std::move(registry)));
- }
+ registry->AddInterface(base::Bind(&SharedWorkerFactoryImpl::Create),
+ base::ThreadTaskRunnerHandle::Get());
+ GetServiceManagerConnection()->AddConnectionFilter(
+ std::make_unique<SimpleConnectionFilter>(std::move(registry)));
{
auto registry_with_source_info =
- base::MakeUnique<service_manager::BinderRegistryWithArgs<
+ std::make_unique<service_manager::BinderRegistryWithArgs<
const service_manager::BindSourceInfo&>>();
registry_with_source_info->AddInterface(
base::Bind(&CreateFrameFactory), base::ThreadTaskRunnerHandle::Get());
GetServiceManagerConnection()->AddConnectionFilter(
- base::MakeUnique<SimpleConnectionFilterWithSourceInfo>(
+ std::make_unique<SimpleConnectionFilterWithSourceInfo>(
std::move(registry_with_source_info)));
}
@@ -836,6 +876,9 @@ void RenderThreadImpl::Init(
#endif
}
+ if (command_line.HasSwitch(switches::kDisableGpuCompositing))
+ is_gpu_compositing_disabled_ = true;
+
is_gpu_rasterization_forced_ =
command_line.HasSwitch(switches::kForceGpuRasterization);
is_async_worker_context_enabled_ =
@@ -904,7 +947,7 @@ void RenderThreadImpl::Init(
categorized_worker_pool_->Start(num_raster_threads);
discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr;
- if (IsRunningInMash()) {
+ if (IsRunningWithMus()) {
#if defined(USE_AURA)
GetServiceManagerConnection()->GetConnector()->BindInterface(
ui::mojom::kServiceName, &manager_ptr);
@@ -916,7 +959,7 @@ void RenderThreadImpl::Init(
mojom::kBrowserServiceName, mojo::MakeRequest(&manager_ptr));
}
- discardable_shared_memory_manager_ = base::MakeUnique<
+ discardable_shared_memory_manager_ = std::make_unique<
discardable_memory::ClientDiscardableSharedMemoryManager>(
std::move(manager_ptr), GetIOTaskRunner());
@@ -930,8 +973,9 @@ void RenderThreadImpl::Init(
mojo::MakeRequest(&storage_partition_service_));
#if defined(OS_LINUX)
- ChildProcess::current()->SetIOThreadPriority(base::ThreadPriority::DISPLAY);
- ChildThreadImpl::current()->SetThreadPriority(
+ render_message_filter()->SetThreadPriority(
+ ChildProcess::current()->io_thread_id(), base::ThreadPriority::DISPLAY);
+ render_message_filter()->SetThreadPriority(
categorized_worker_pool_->background_worker_thread_id(),
base::ThreadPriority::BACKGROUND);
#endif
@@ -949,17 +993,30 @@ void RenderThreadImpl::Init(
if (!command_line.HasSwitch(switches::kSingleProcess))
base::SequencedWorkerPool::EnableForProcess();
- EVP_set_buggy_rsa_parser(
- base::FeatureList::IsEnabled(features::kBuggyRSAParser));
-
GetConnector()->BindInterface(mojom::kBrowserServiceName,
mojo::MakeRequest(&frame_sink_provider_));
-}
-RenderThreadImpl::~RenderThreadImpl() {
+ if (!is_gpu_compositing_disabled_) {
+ GetConnector()->BindInterface(
+ mojom::kBrowserServiceName,
+ mojo::MakeRequest(&compositing_mode_reporter_));
+
+ // Make |this| a CompositingModeWatcher for the
+ // |compositing_mode_reporter_|.
+ viz::mojom::CompositingModeWatcherPtr watcher_ptr;
+ compositing_mode_watcher_binding_.Bind(mojo::MakeRequest(&watcher_ptr));
+ compositing_mode_reporter_->AddCompositingModeWatcher(
+ std::move(watcher_ptr));
+ }
}
+RenderThreadImpl::~RenderThreadImpl() = default;
+
void RenderThreadImpl::Shutdown() {
+ ChildThreadImpl::Shutdown();
+ quota_dispatcher_.reset();
+ file_system_dispatcher_.reset();
+ 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
@@ -1054,8 +1111,7 @@ void RenderThreadImpl::AddRoute(int32_t routing_id, IPC::Listener* listener) {
return;
scoped_refptr<PendingFrameCreate> create(it->second);
- frame->BindFrame(it->second->browser_info(), it->second->TakeFrameRequest(),
- it->second->TakeInterfaceBroker());
+ frame->BindFrame(it->second->browser_info(), it->second->TakeFrameRequest());
pending_frame_creates_.erase(it);
}
@@ -1063,33 +1119,14 @@ void RenderThreadImpl::RemoveRoute(int32_t routing_id) {
ChildThreadImpl::GetRouter()->RemoveRoute(routing_id);
}
-void RenderThreadImpl::AddEmbeddedWorkerRoute(int32_t routing_id,
- IPC::Listener* listener) {
- AddRoute(routing_id, listener);
- if (devtools_agent_message_filter_.get()) {
- devtools_agent_message_filter_->AddEmbeddedWorkerRouteOnMainThread(
- routing_id);
- }
-}
-
-void RenderThreadImpl::RemoveEmbeddedWorkerRoute(int32_t routing_id) {
- RemoveRoute(routing_id);
- if (devtools_agent_message_filter_.get()) {
- devtools_agent_message_filter_->RemoveEmbeddedWorkerRouteOnMainThread(
- routing_id);
- }
-}
-
void RenderThreadImpl::RegisterPendingFrameCreate(
const service_manager::BindSourceInfo& browser_info,
int routing_id,
- mojom::FrameRequest frame_request,
- mojom::FrameHostInterfaceBrokerPtr frame_host_interface_broker) {
+ mojom::FrameRequest frame_request) {
std::pair<PendingFrameCreateMap::iterator, bool> result =
pending_frame_creates_.insert(std::make_pair(
routing_id, base::MakeRefCounted<PendingFrameCreate>(
- browser_info, routing_id, std::move(frame_request),
- std::move(frame_host_interface_broker))));
+ browser_info, routing_id, std::move(frame_request))));
CHECK(result.second) << "Inserting a duplicate item.";
}
@@ -1099,8 +1136,7 @@ mojom::StoragePartitionService* RenderThreadImpl::GetStoragePartitionService() {
mojom::RendererHost* RenderThreadImpl::GetRendererHost() {
if (!renderer_host_) {
- GetConnector()->BindInterface(mojom::kBrowserServiceName,
- mojo::MakeRequest(&renderer_host_));
+ GetChannel()->GetRemoteAssociatedInterface(&renderer_host_);
}
return renderer_host_.get();
}
@@ -1131,7 +1167,7 @@ void RenderThreadImpl::RemoveObserver(RenderThreadObserver* observer) {
void RenderThreadImpl::SetResourceDispatcherDelegate(
ResourceDispatcherDelegate* delegate) {
- resource_dispatcher()->set_delegate(delegate);
+ resource_dispatcher_->set_delegate(delegate);
}
void RenderThreadImpl::InitializeCompositorThread() {
@@ -1148,8 +1184,8 @@ void RenderThreadImpl::InitializeCompositorThread() {
base::BindOnce(base::IgnoreResult(&ThreadRestrictions::SetIOAllowed),
false));
#if defined(OS_LINUX)
- ChildThreadImpl::current()->SetThreadPriority(compositor_thread_->ThreadId(),
- base::ThreadPriority::DISPLAY);
+ render_message_filter()->SetThreadPriority(compositor_thread_->ThreadId(),
+ base::ThreadPriority::DISPLAY);
#endif
if (!base::FeatureList::IsEnabled(features::kMojoInputMessages)) {
@@ -1184,7 +1220,8 @@ void RenderThreadImpl::InitializeCompositorThread() {
}
void RenderThreadImpl::InitializeWebKit(
- const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue) {
+ const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue,
+ blink::InterfaceRegistry* interface_registry) {
DCHECK(!blink_platform_impl_);
const base::CommandLine& command_line =
@@ -1201,7 +1238,7 @@ void RenderThreadImpl::InitializeWebKit(
GetContentClient()
->renderer()
->SetRuntimeFeaturesDefaultsBeforeBlinkInitialization();
- blink::Initialize(blink_platform_impl_.get());
+ blink::Initialize(blink_platform_impl_.get(), interface_registry);
v8::Isolate* isolate = blink::MainThreadIsolate();
isolate->SetCreateHistogramFunction(CreateHistogram);
@@ -1225,15 +1262,15 @@ void RenderThreadImpl::InitializeWebKit(
// particular task runner.
scoped_refptr<ResourceSchedulingFilter> filter(
new ResourceSchedulingFilter(
- resource_task_queue2, resource_dispatcher()));
+ resource_task_queue2, resource_dispatcher_.get()));
channel()->AddFilter(filter.get());
- resource_dispatcher()->SetResourceSchedulingFilter(filter);
+ resource_dispatcher_->SetResourceSchedulingFilter(filter);
// The ChildResourceMessageFilter and the ResourceDispatcher need to use the
// same queue to ensure tasks are executed in the expected order.
- child_resource_message_filter()->SetMainThreadTaskRunner(
+ resource_message_filter_->SetMainThreadTaskRunner(
resource_task_queue2);
- resource_dispatcher()->SetThreadTaskRunner(resource_task_queue2);
+ resource_dispatcher_->SetThreadTaskRunner(resource_task_queue2);
if (!command_line.HasSwitch(switches::kDisableThreadedCompositing))
InitializeCompositorThread();
@@ -1262,9 +1299,6 @@ void RenderThreadImpl::InitializeWebKit(
RenderMediaClient::Initialize();
- devtools_agent_message_filter_ = new DevToolsAgentFilter();
- AddFilter(devtools_agent_message_filter_.get());
-
if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) {
ScheduleIdleHandler(kLongIdleHandlerDelayMs);
} else {
@@ -1273,6 +1307,10 @@ void RenderThreadImpl::InitializeWebKit(
isolate->IsolateInBackgroundNotification();
}
+ service_worker_message_filter_ =
+ new ServiceWorkerMessageFilter(thread_safe_sender());
+ AddFilter(service_worker_message_filter_->GetFilter());
+
renderer_scheduler_->SetStoppingWhenBackgroundedEnabled(
GetContentClient()->renderer()->AllowStoppingWhenProcessBackgrounded());
@@ -1450,7 +1488,8 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
support_oop_rasterization,
ui::command_buffer_metrics::MEDIA_CONTEXT,
kGpuStreamIdDefault, kGpuStreamPriorityDefault);
- if (!media_context_provider->BindToCurrentThread())
+ auto result = media_context_provider->BindToCurrentThread();
+ if (result != gpu::ContextResult::kSuccess)
return nullptr;
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner =
@@ -1458,14 +1497,11 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
const bool enable_video_accelerator =
!cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode);
const bool enable_gpu_memory_buffer_video_frames =
+ !is_gpu_compositing_disabled_ &&
#if defined(OS_MACOSX) || defined(OS_LINUX)
- !cmd_line->HasSwitch(switches::kDisableGpuMemoryBufferVideoFrames) &&
- !cmd_line->HasSwitch(switches::kDisableGpuCompositing) &&
- !gpu_channel_host->gpu_info().software_rendering;
+ !cmd_line->HasSwitch(switches::kDisableGpuMemoryBufferVideoFrames);
#elif defined(OS_WIN)
!cmd_line->HasSwitch(switches::kDisableGpuMemoryBufferVideoFrames) &&
- !cmd_line->HasSwitch(switches::kDisableGpuCompositing) &&
- !gpu_channel_host->gpu_info().software_rendering &&
(cmd_line->HasSwitch(switches::kEnableGpuMemoryBufferVideoFrames) ||
gpu_channel_host->gpu_info().supports_overlays);
#else
@@ -1505,7 +1541,8 @@ RenderThreadImpl::SharedMainThreadContextProvider() {
support_oop_rasterization,
ui::command_buffer_metrics::RENDERER_MAINTHREAD_CONTEXT,
kGpuStreamIdDefault, kGpuStreamPriorityDefault);
- if (!shared_main_thread_contexts_->BindToCurrentThread())
+ auto result = shared_main_thread_contexts_->BindToCurrentThread();
+ if (result != gpu::ContextResult::kSuccess)
shared_main_thread_contexts_ = nullptr;
return shared_main_thread_contexts_;
}
@@ -1558,6 +1595,15 @@ void RenderThreadImpl::SetRendererProcessType(
renderer_scheduler_->SetRendererProcessType(type);
}
+bool RenderThreadImpl::OnMessageReceived(const IPC::Message& msg) {
+ // Resource responses are sent to the resource dispatcher.
+ if (resource_dispatcher_->OnMessageReceived(msg))
+ return true;
+ if (file_system_dispatcher_->OnMessageReceived(msg))
+ return true;
+ return ChildThreadImpl::OnMessageReceived(msg);
+}
+
void RenderThreadImpl::OnAssociatedInterfaceRequest(
const std::string& name,
mojo::ScopedInterfaceEndpointHandle handle) {
@@ -1633,7 +1679,7 @@ blink::scheduler::RendererScheduler* RenderThreadImpl::GetRendererScheduler() {
std::unique_ptr<viz::BeginFrameSource>
RenderThreadImpl::CreateExternalBeginFrameSource(int routing_id) {
- return base::MakeUnique<CompositorExternalBeginFrameSource>(
+ return std::make_unique<CompositorExternalBeginFrameSource>(
compositor_message_filter_.get(), sync_message_filter(), routing_id);
}
@@ -1642,8 +1688,8 @@ RenderThreadImpl::CreateSyntheticBeginFrameSource() {
base::SingleThreadTaskRunner* compositor_impl_side_task_runner =
compositor_task_runner_ ? compositor_task_runner_.get()
: base::ThreadTaskRunnerHandle::Get().get();
- return base::MakeUnique<viz::BackToBackBeginFrameSource>(
- base::MakeUnique<viz::DelayBasedTimeSource>(
+ return std::make_unique<viz::BackToBackBeginFrameSource>(
+ std::make_unique<viz::DelayBasedTimeSource>(
compositor_impl_side_task_runner));
}
@@ -1659,6 +1705,13 @@ bool RenderThreadImpl::IsScrollAnimatorEnabled() {
return is_scroll_animator_enabled_;
}
+std::unique_ptr<cc::UkmRecorderFactory>
+RenderThreadImpl::CreateUkmRecorderFactory() {
+ ukm::mojom::UkmRecorderInterfacePtrInfo info;
+ mojo::MakeRequest(&info);
+ return std::make_unique<UkmRecorderFactoryImpl>(std::move(info));
+}
+
void RenderThreadImpl::OnRAILModeChanged(v8::RAILMode rail_mode) {
blink::MainThreadIsolate()->SetRAILMode(rail_mode);
blink::SetRAILModeOnWorkerThreadIsolates(rail_mode);
@@ -1678,6 +1731,18 @@ void RenderThreadImpl::OnChannelError() {
ChildThreadImpl::OnChannelError();
}
+void RenderThreadImpl::OnProcessFinalRelease() {
+ if (on_channel_error_called())
+ return;
+ // The child process shutdown sequence is a request response based mechanism,
+ // where we send out an initial feeler request to the child process host
+ // instance in the browser to verify if it's ok to shutdown the child process.
+ // The browser then sends back a response if it's ok to shutdown. This avoids
+ // race conditions if the process refcount is 0 but there's an IPC message
+ // inflight that would addref it.
+ GetRendererHost()->ShutdownRequest();
+}
+
bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
for (auto& observer : observers_) {
if (observer.OnControlMessageReceived(msg))
@@ -1692,8 +1757,12 @@ bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
return false;
}
-void RenderThreadImpl::OnProcessBackgrounded(bool backgrounded) {
- ChildThreadImpl::OnProcessBackgrounded(backgrounded);
+void RenderThreadImpl::SetProcessBackgrounded(bool backgrounded) {
+ // Set timer slack to maximum on main thread when in background.
+ base::TimerSlack timer_slack = base::TIMER_SLACK_NONE;
+ if (backgrounded)
+ timer_slack = base::TIMER_SLACK_MAXIMUM;
+ base::MessageLoop::current()->SetTimerSlack(timer_slack);
renderer_scheduler_->SetRendererBackgrounded(backgrounded);
if (backgrounded) {
@@ -1722,8 +1791,7 @@ void RenderThreadImpl::OnProcessBackgrounded(bool backgrounded) {
}
}
-void RenderThreadImpl::OnProcessPurgeAndSuspend() {
- ChildThreadImpl::OnProcessPurgeAndSuspend();
+void RenderThreadImpl::ProcessPurgeAndSuspend() {
if (!RendererIsHidden())
return;
@@ -1904,42 +1972,41 @@ void RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics(
1024);
}
-scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync() {
- TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync");
-
- if (gpu_channel_) {
- // Do nothing if we already have a GPU channel or are already
- // establishing one.
- if (!gpu_channel_->IsLost())
- return gpu_channel_;
+void RenderThreadImpl::CompositingModeFallbackToSoftware() {
+ gpu_->LoseChannel();
+ is_gpu_compositing_disabled_ = true;
+}
- // Recreate the channel if it has been lost.
- gpu_channel_->DestroyChannel();
- gpu_channel_ = nullptr;
- }
+scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync(
+ bool* connection_error) {
+ TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync");
- gpu_channel_ = gpu_->EstablishGpuChannelSync();
- if (gpu_channel_)
- GetContentClient()->SetGpuInfo(gpu_channel_->gpu_info());
- return gpu_channel_;
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel =
+ gpu_->EstablishGpuChannelSync(connection_error);
+ if (gpu_channel)
+ GetContentClient()->SetGpuInfo(gpu_channel->gpu_info());
+ return gpu_channel;
}
void RenderThreadImpl::RequestNewLayerTreeFrameSink(
- bool use_software,
int routing_id,
scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
const GURL& url,
const LayerTreeFrameSinkCallback& callback) {
+ // 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_) {
+ LOG(FATAL) << "Layout tests require gpu compositing, but it is disabled.";
+ return;
+ }
+
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kDisableGpuCompositing))
- use_software = true;
-
viz::ClientLayerTreeFrameSink::InitParams params;
params.enable_surface_synchronization =
- command_line.HasSwitch(switches::kEnableSurfaceSynchronization);
+ features::IsSurfaceSynchronizationEnabled();
params.local_surface_id_provider =
- base::MakeUnique<RendererLocalSurfaceIdProvider>();
+ std::make_unique<RendererLocalSurfaceIdProvider>();
// In disable gpu vsync mode, also let the renderer tick as fast as it
// can. The top level begin frame source will also be running as a back
@@ -1952,12 +2019,18 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
}
#if defined(USE_AURA)
- if (!use_software && IsRunningInMash()) {
+ if (switches::IsMusHostingViz()) {
if (!RendererWindowTreeClient::Get(routing_id)) {
callback.Run(nullptr);
return;
}
- scoped_refptr<gpu::GpuChannelHost> channel = EstablishGpuChannelSync();
+ bool connection_error = false;
+ scoped_refptr<gpu::GpuChannelHost> channel =
+ EstablishGpuChannelSync(&connection_error);
+ // If the connection to the host is gone, then don't bother running the
+ // |callback| to retry.
+ if (connection_error)
+ return;
// If the channel could not be established correctly, then return null. This
// would cause the compositor to wait and try again at a later time.
if (!channel) {
@@ -1984,38 +2057,36 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
DCHECK(!layout_test_mode());
frame_sink_provider_->CreateForWidget(routing_id, std::move(sink_request),
std::move(client));
- callback.Run(base::MakeUnique<viz::ClientLayerTreeFrameSink>(
+ callback.Run(std::make_unique<viz::ClientLayerTreeFrameSink>(
std::move(vulkan_context_provider), &params));
return;
}
}
- // Create a gpu process channel and verify we want to use GPU compositing
- // before creating any context providers.
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host;
- if (!use_software) {
- gpu_channel_host = EstablishGpuChannelSync();
- if (!gpu_channel_host) {
- // Cause the compositor to wait and try again.
- callback.Run(nullptr);
- return;
- }
- // We may get a valid channel, but with a software renderer. In that case,
- // disable GPU compositing.
- if (gpu_channel_host->gpu_info().software_rendering)
- use_software = true;
- }
-
- if (use_software) {
+ if (is_gpu_compositing_disabled_) {
DCHECK(!layout_test_mode());
frame_sink_provider_->CreateForWidget(routing_id, std::move(sink_request),
std::move(client));
params.shared_bitmap_manager = shared_bitmap_manager();
- callback.Run(base::MakeUnique<viz::ClientLayerTreeFrameSink>(
+ callback.Run(std::make_unique<viz::ClientLayerTreeFrameSink>(
nullptr, nullptr, &params));
return;
}
+ bool connection_error = false;
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
+ EstablishGpuChannelSync(&connection_error);
+ // If the connection to the host is gone, then don't bother running the
+ // |callback| to retry.
+ if (connection_error)
+ return;
+ if (!gpu_channel_host) {
+ // Wait and try again. We may hear that the compositing mode has switched
+ // to software in the meantime.
+ callback.Run(nullptr);
+ return;
+ }
+
scoped_refptr<ui::ContextProviderCommandBuffer> worker_context_provider =
SharedCompositorWorkerContextProvider();
if (!worker_context_provider) {
@@ -2070,7 +2141,7 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
params.synthetic_begin_frame_source
? std::move(params.synthetic_begin_frame_source)
: CreateExternalBeginFrameSource(routing_id);
- callback.Run(base::MakeUnique<SynchronousLayerTreeFrameSink>(
+ callback.Run(std::make_unique<SynchronousLayerTreeFrameSink>(
std::move(context_provider), std::move(worker_context_provider),
GetGpuMemoryBufferManager(), shared_bitmap_manager(), routing_id,
g_next_layer_tree_frame_sink_id++, std::move(begin_frame_source),
@@ -2082,12 +2153,12 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
frame_sink_provider_->CreateForWidget(routing_id, std::move(sink_request),
std::move(client));
params.gpu_memory_buffer_manager = GetGpuMemoryBufferManager();
- callback.Run(base::MakeUnique<viz::ClientLayerTreeFrameSink>(
+ callback.Run(std::make_unique<viz::ClientLayerTreeFrameSink>(
std::move(context_provider), std::move(worker_context_provider),
&params));
}
-AssociatedInterfaceRegistry*
+blink::AssociatedInterfaceRegistry*
RenderThreadImpl::GetAssociatedInterfaceRegistry() {
return &associated_interfaces_;
}
@@ -2106,13 +2177,8 @@ RenderThreadImpl::CreateMediaStreamCenter(
std::unique_ptr<blink::WebMediaStreamCenter> media_stream_center;
#if BUILDFLAG(ENABLE_WEBRTC)
if (!media_stream_center) {
- media_stream_center =
- GetContentClient()->renderer()->OverrideCreateWebMediaStreamCenter(
- client);
- if (!media_stream_center) {
- media_stream_center = base::MakeUnique<MediaStreamCenter>(
- client, GetPeerConnectionDependencyFactory());
- }
+ media_stream_center = std::make_unique<MediaStreamCenter>(
+ client, GetPeerConnectionDependencyFactory());
}
#endif
return media_stream_center;
@@ -2139,18 +2205,14 @@ mojom::RenderMessageFilter* RenderThreadImpl::render_message_filter() {
}
gpu::GpuChannelHost* RenderThreadImpl::GetGpuChannel() {
- if (!gpu_channel_)
- return nullptr;
- if (gpu_channel_->IsLost())
- return nullptr;
- return gpu_channel_.get();
+ return gpu_->GetGpuChannel().get();
}
void RenderThreadImpl::CreateView(mojom::CreateViewParamsPtr params) {
CompositorDependencies* compositor_deps = this;
is_scroll_animator_enabled_ = params->web_preferences.enable_scroll_animator;
// When bringing in render_view, also bring in webkit's glue and jsbindings.
- RenderViewImpl::Create(compositor_deps, *params,
+ RenderViewImpl::Create(compositor_deps, std::move(params),
RenderWidget::ShowCallback());
}
@@ -2172,8 +2234,11 @@ void RenderThreadImpl::CreateFrame(mojom::CreateFrameParamsPtr params) {
base::debug::SetCrashKeyValue("newframe_replicated_origin",
params->replication_state.origin.Serialize());
CompositorDependencies* compositor_deps = this;
+ service_manager::mojom::InterfaceProviderPtr interface_provider(
+ std::move(params->interface_provider));
RenderFrameImpl::CreateFrame(
- params->routing_id, params->proxy_routing_id, params->opener_routing_id,
+ params->routing_id, std::move(interface_provider),
+ params->proxy_routing_id, params->opener_routing_id,
params->parent_routing_id, params->previous_sibling_routing_id,
params->devtools_frame_token, params->replication_state, compositor_deps,
*params->widget_params, params->frame_owner_properties);
@@ -2396,7 +2461,8 @@ RenderThreadImpl::SharedCompositorWorkerContextProvider() {
support_oop_rasterization,
ui::command_buffer_metrics::RENDER_WORKER_CONTEXT, stream_id,
stream_priority);
- if (!shared_worker_context_provider_->BindToCurrentThread())
+ auto result = shared_worker_context_provider_->BindToCurrentThread();
+ if (result != gpu::ContextResult::kSuccess)
shared_worker_context_provider_ = nullptr;
return shared_worker_context_provider_;
}
@@ -2470,19 +2536,10 @@ void RenderThreadImpl::ReleaseFreeMemory() {
RenderThreadImpl::PendingFrameCreate::PendingFrameCreate(
const service_manager::BindSourceInfo& browser_info,
int routing_id,
- mojom::FrameRequest frame_request,
- mojom::FrameHostInterfaceBrokerPtr frame_host_interface_broker)
+ mojom::FrameRequest frame_request)
: browser_info_(browser_info),
routing_id_(routing_id),
- frame_request_(std::move(frame_request)),
- frame_host_interface_broker_(std::move(frame_host_interface_broker)) {
- // The RenderFrame may be deleted before the CreateFrame message is received.
- // In that case, the RenderFrameHost should cancel the create, which is
- // detected by setting an error handler on |frame_host_interface_broker_|.
- frame_host_interface_broker_.set_connection_error_handler(
- base::BindOnce(&RenderThreadImpl::PendingFrameCreate::OnConnectionError,
- base::Unretained(this)));
-}
+ frame_request_(std::move(frame_request)) {}
RenderThreadImpl::PendingFrameCreate::~PendingFrameCreate() {
}
diff --git a/chromium/content/renderer/render_thread_impl.h b/chromium/content/renderer/render_thread_impl.h
index 5695809a51e..52229562347 100644
--- a/chromium/content/renderer/render_thread_impl.h
+++ b/chromium/content/renderer/render_thread_impl.h
@@ -46,6 +46,7 @@
#include "content/renderer/layout_test_dependencies.h"
#include "content/renderer/media/audio_ipc_factory.h"
#include "gpu/ipc/client/gpu_channel_host.h"
+#include "ipc/ipc_sync_channel.h"
#include "media/media_features.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -53,6 +54,7 @@
#include "net/base/network_change_notifier.h"
#include "net/nqe/effective_connection_type.h"
#include "services/service_manager/public/cpp/bind_source_info.h"
+#include "services/viz/public/interfaces/compositing/compositing_mode_watcher.mojom.h"
#include "third_party/WebKit/public/platform/WebConnectionType.h"
#include "third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h"
#include "third_party/WebKit/public/web/WebMemoryStatistics.h"
@@ -68,6 +70,7 @@ namespace blink {
namespace scheduler {
class WebThreadBase;
}
+class InterfaceRegistry;
class WebMediaStreamCenter;
class WebMediaStreamCenterClient;
}
@@ -129,21 +132,26 @@ class AudioRendererMixerManager;
class BlobMessageFilter;
class BrowserPluginManager;
class CacheStorageDispatcher;
+class CategorizedWorkerPool;
+class ChildResourceMessageFilter;
class CompositorForwardingMessageFilter;
-class DevToolsAgentFilter;
class DomStorageDispatcher;
+class FileSystemDispatcher;
class FrameSwapMessageQueue;
+class GpuVideoAcceleratorFactoriesImpl;
class IndexedDBDispatcher;
class InputHandlerManager;
class MidiMessageFilter;
+class NotificationDispatcher;
class P2PSocketDispatcher;
class PeerConnectionDependencyFactory;
class PeerConnectionTracker;
-class CategorizedWorkerPool;
+class QuotaDispatcher;
class RenderThreadObserver;
class RendererBlinkPlatformImpl;
-class GpuVideoAcceleratorFactoriesImpl;
+class ResourceDispatcher;
class ResourceDispatchThrottler;
+class ServiceWorkerMessageFilter;
class VideoCaptureImplManager;
#if defined(OS_ANDROID)
@@ -173,6 +181,7 @@ class CONTENT_EXPORT RenderThreadImpl
public ChildMemoryCoordinatorDelegate,
public base::MemoryCoordinatorClient,
public mojom::Renderer,
+ public viz::mojom::CompositingModeWatcher,
public CompositorDependencies {
public:
static RenderThreadImpl* Create(const InProcessChildThreadParams& params);
@@ -227,6 +236,7 @@ class CONTENT_EXPORT RenderThreadImpl
blink::scheduler::RendererProcessType type) override;
// IPC::Listener implementation via ChildThreadImpl:
+ bool OnMessageReceived(const IPC::Message& msg) override;
void OnAssociatedInterfaceRequest(
const std::string& name,
mojo::ScopedInterfaceEndpointHandle handle) override;
@@ -253,28 +263,40 @@ class CONTENT_EXPORT RenderThreadImpl
cc::TaskGraphRunner* GetTaskGraphRunner() override;
bool IsThreadedAnimationEnabled() override;
bool IsScrollAnimatorEnabled() override;
+ std::unique_ptr<cc::UkmRecorderFactory> CreateUkmRecorderFactory() override;
// blink::scheduler::RendererScheduler::RAILModeObserver implementation.
void OnRAILModeChanged(v8::RAILMode rail_mode) override;
+ // viz::mojom::CompositingModeWatcher implementation.
+ void CompositingModeFallbackToSoftware() override;
+
+ // Whether gpu compositing is being used or is disabled for software
+ // compositing. Clients of the compositor should give resources that match
+ // the appropriate mode.
+ bool IsGpuCompositingDisabled() { return is_gpu_compositing_disabled_; }
+
// Synchronously establish a channel to the GPU plugin if not previously
// established or if it has been lost (for example if the GPU plugin crashed).
// If there is a pending asynchronous request, it will be completed by the
- // time this routine returns.
- scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync();
+ // time this routine returns. If |connection_error| is set to true, it was
+ // unable to connect to the host process to try establish a channel, which
+ // should mean that the host is shutting this process down and there's no
+ // reason to retry.
+ scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync(
+ bool* connection_error = nullptr);
gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager();
using LayerTreeFrameSinkCallback =
base::Callback<void(std::unique_ptr<cc::LayerTreeFrameSink>)>;
void RequestNewLayerTreeFrameSink(
- bool use_software,
int routing_id,
scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
const GURL& url,
const LayerTreeFrameSinkCallback& callback);
- AssociatedInterfaceRegistry* GetAssociatedInterfaceRegistry();
+ blink::AssociatedInterfaceRegistry* GetAssociatedInterfaceRegistry();
std::unique_ptr<cc::SwapPromise> RequestCopyOfOutputForLayoutTest(
int32_t routing_id,
@@ -324,10 +346,22 @@ class CONTENT_EXPORT RenderThreadImpl
return audio_input_message_filter_.get();
}
+ FileSystemDispatcher* file_system_dispatcher() const {
+ return file_system_dispatcher_.get();
+ }
+
MidiMessageFilter* midi_message_filter() {
return midi_message_filter_.get();
}
+ QuotaDispatcher* quota_dispatcher() const {
+ return quota_dispatcher_.get();
+ }
+
+ ResourceDispatcher* resource_dispatcher() const {
+ return resource_dispatcher_.get();
+ }
+
#if defined(OS_ANDROID)
SynchronousCompositorFilter* sync_compositor_message_filter() {
return sync_compositor_message_filter_.get();
@@ -369,6 +403,10 @@ class CONTENT_EXPORT RenderThreadImpl
return shared_bitmap_manager_.get();
}
+ NotificationDispatcher* notification_dispatcher() const {
+ return notification_dispatcher_.get();
+ }
+
mojom::RenderFrameMessageFilter* render_frame_message_filter();
mojom::RenderMessageFilter* render_message_filter();
@@ -480,14 +518,10 @@ class CONTENT_EXPORT RenderThreadImpl
void WidgetHidden();
void WidgetRestored();
- void AddEmbeddedWorkerRoute(int32_t routing_id, IPC::Listener* listener);
- void RemoveEmbeddedWorkerRoute(int32_t routing_id);
-
void RegisterPendingFrameCreate(
const service_manager::BindSourceInfo& source_info,
int routing_id,
- mojom::FrameRequest frame,
- mojom::FrameHostInterfaceBrokerPtr host);
+ mojom::FrameRequest frame);
mojom::StoragePartitionService* GetStoragePartitionService();
mojom::RendererHost* GetRendererHost();
@@ -519,13 +553,12 @@ class CONTENT_EXPORT RenderThreadImpl
std::unique_ptr<blink::scheduler::RendererScheduler> scheduler);
private:
+ void OnProcessFinalRelease() override;
// IPC::Listener
void OnChannelError() override;
// ChildThread
bool OnControlMessageReceived(const IPC::Message& msg) override;
- void OnProcessBackgrounded(bool backgrounded) override;
- void OnProcessPurgeAndSuspend() override;
void RecordAction(const base::UserMetricsAction& action) override;
void RecordComputedAction(const std::string& action) override;
@@ -545,7 +578,8 @@ class CONTENT_EXPORT RenderThreadImpl
void InitializeCompositorThread();
void InitializeWebKit(
- const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue);
+ const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue,
+ blink::InterfaceRegistry* registry);
void OnTransferBitmap(const SkBitmap& bitmap, int resource_id);
void OnGetAccessibilityTree();
@@ -575,6 +609,8 @@ class CONTENT_EXPORT RenderThreadImpl
const std::string& highlight_text_color,
const std::string& highlight_color) override;
void PurgePluginListCache(bool reload_pages) override;
+ void SetProcessBackgrounded(bool backgrounded) override;
+ void ProcessPurgeAndSuspend() override;
void OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
@@ -611,14 +647,18 @@ class CONTENT_EXPORT RenderThreadImpl
std::unique_ptr<IndexedDBDispatcher> main_thread_indexed_db_dispatcher_;
std::unique_ptr<blink::scheduler::RendererScheduler> renderer_scheduler_;
std::unique_ptr<RendererBlinkPlatformImpl> blink_platform_impl_;
+ std::unique_ptr<ResourceDispatcher> resource_dispatcher_;
std::unique_ptr<ResourceDispatchThrottler> resource_dispatch_throttler_;
std::unique_ptr<CacheStorageDispatcher> main_thread_cache_storage_dispatcher_;
+ std::unique_ptr<FileSystemDispatcher> file_system_dispatcher_;
+ std::unique_ptr<QuotaDispatcher> quota_dispatcher_;
// Used on the renderer and IPC threads.
scoped_refptr<BlobMessageFilter> blob_message_filter_;
scoped_refptr<AudioInputMessageFilter> audio_input_message_filter_;
scoped_refptr<MidiMessageFilter> midi_message_filter_;
- scoped_refptr<DevToolsAgentFilter> devtools_agent_message_filter_;
+ scoped_refptr<ServiceWorkerMessageFilter> service_worker_message_filter_;
+ scoped_refptr<ChildResourceMessageFilter> resource_message_filter_;
std::unique_ptr<BrowserPluginManager> browser_plugin_manager_;
@@ -649,6 +689,8 @@ class CONTENT_EXPORT RenderThreadImpl
std::unique_ptr<viz::ClientSharedBitmapManager> shared_bitmap_manager_;
+ scoped_refptr<NotificationDispatcher> notification_dispatcher_;
+
// The time Blink was initialized. Used for UMA.
base::TimeTicks blink_initialized_time_;
@@ -672,8 +714,10 @@ class CONTENT_EXPORT RenderThreadImpl
// Timer that periodically calls IdleHandler.
base::RepeatingTimer idle_timer_;
- // The channel from the renderer process to the GPU process.
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_;
+ // 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;
// The message loop of the renderer main thread.
// This message loop should be destructed before the RenderThreadImpl
@@ -745,21 +789,14 @@ class CONTENT_EXPORT RenderThreadImpl
class PendingFrameCreate : public base::RefCounted<PendingFrameCreate> {
public:
- PendingFrameCreate(
- const service_manager::BindSourceInfo& source_info,
- int routing_id,
- mojom::FrameRequest frame_request,
- mojom::FrameHostInterfaceBrokerPtr frame_host_interface_broker);
+ PendingFrameCreate(const service_manager::BindSourceInfo& source_info,
+ int routing_id,
+ mojom::FrameRequest frame_request);
const service_manager::BindSourceInfo& browser_info() const {
return browser_info_;
}
mojom::FrameRequest TakeFrameRequest() { return std::move(frame_request_); }
- mojom::FrameHostInterfaceBrokerPtr TakeInterfaceBroker() {
- frame_host_interface_broker_.set_connection_error_handler(
- base::Closure());
- return std::move(frame_host_interface_broker_);
- }
private:
friend class base::RefCounted<PendingFrameCreate>;
@@ -772,7 +809,6 @@ class CONTENT_EXPORT RenderThreadImpl
service_manager::BindSourceInfo browser_info_;
int routing_id_;
mojom::FrameRequest frame_request_;
- mojom::FrameHostInterfaceBrokerPtr frame_host_interface_broker_;
};
using PendingFrameCreateMap =
@@ -780,7 +816,7 @@ class CONTENT_EXPORT RenderThreadImpl
PendingFrameCreateMap pending_frame_creates_;
mojom::StoragePartitionServicePtr storage_partition_service_;
- mojom::RendererHostPtr renderer_host_;
+ mojom::RendererHostAssociatedPtr renderer_host_;
AssociatedInterfaceRegistryImpl associated_interfaces_;
@@ -798,6 +834,13 @@ class CONTENT_EXPORT RenderThreadImpl
mojom::FrameSinkProviderPtr frame_sink_provider_;
+ // A mojo connection to the CompositingModeReporter service.
+ viz::mojom::CompositingModeReporterPtr compositing_mode_reporter_;
+ // The class is a CompositingModeWatcher, which is bound to mojo through
+ // this member.
+ mojo::Binding<viz::mojom::CompositingModeWatcher>
+ compositing_mode_watcher_binding_;
+
DISALLOW_COPY_AND_ASSIGN(RenderThreadImpl);
};
diff --git a/chromium/content/renderer/render_thread_impl_browsertest.cc b/chromium/content/renderer/render_thread_impl_browsertest.cc
index d0023625813..d591bd6c1a5 100644
--- a/chromium/content/renderer/render_thread_impl_browsertest.cc
+++ b/chromium/content/renderer/render_thread_impl_browsertest.cc
@@ -17,6 +17,7 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
+#include "base/test/scoped_feature_list.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -28,6 +29,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.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/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
@@ -195,10 +197,11 @@ class RenderThreadImplBrowserTest : public testing::Test {
child_connection_->BindInterface(IPC::mojom::ChannelBootstrap::Name_,
std::move(pipe.handle1));
- channel_ =
- IPC::ChannelProxy::Create(IPC::ChannelMojo::CreateServerFactory(
- std::move(pipe.handle0), io_task_runner),
- nullptr, io_task_runner);
+ channel_ = IPC::ChannelProxy::Create(
+ IPC::ChannelMojo::CreateServerFactory(
+ std::move(pipe.handle0), io_task_runner,
+ base::ThreadTaskRunnerHandle::Get()),
+ nullptr, io_task_runner, base::ThreadTaskRunnerHandle::Get());
mock_process_.reset(new MockRenderProcess);
test_task_counter_ = base::MakeRefCounted<TestTaskCounter>();
@@ -228,7 +231,7 @@ class RenderThreadImplBrowserTest : public testing::Test {
std::move(renderer_scheduler), test_task_counter);
cmd->InitFromArgv(old_argv);
- run_loop_ = base::MakeUnique<base::RunLoop>();
+ run_loop_ = std::make_unique<base::RunLoop>();
test_msg_filter_ = base::MakeRefCounted<QuitOnTestMsgFilter>(
run_loop_->QuitWhenIdleClosure());
thread_->AddFilter(test_msg_filter_.get());
@@ -265,6 +268,17 @@ class RenderThreadImplBrowserTest : public testing::Test {
std::unique_ptr<base::RunLoop> run_loop_;
};
+class RenderThreadImplMojoInputMessagesDisabledBrowserTest
+ : public RenderThreadImplBrowserTest {
+ public:
+ RenderThreadImplMojoInputMessagesDisabledBrowserTest() {
+ feature_list_.InitAndDisableFeature(features::kMojoInputMessages);
+ }
+
+ private:
+ base::test::ScopedFeatureList feature_list_;
+};
+
void CheckRenderThreadInputHandlerManager(RenderThreadImpl* thread) {
ASSERT_TRUE(thread->input_handler_manager());
}
@@ -280,7 +294,7 @@ void CheckRenderThreadInputHandlerManager(RenderThreadImpl* thread) {
#define MAYBE_InputHandlerManagerDestroyedAfterCompositorThread \
InputHandlerManagerDestroyedAfterCompositorThread
#endif
-TEST_F(RenderThreadImplBrowserTest,
+TEST_F(RenderThreadImplMojoInputMessagesDisabledBrowserTest,
WILL_LEAK(MAYBE_InputHandlerManagerDestroyedAfterCompositorThread)) {
ASSERT_TRUE(thread_->input_handler_manager());
diff --git a/chromium/content/renderer/render_view_browsertest.cc b/chromium/content/renderer/render_view_browsertest.cc
index 3f710d06466..f02e349e058 100644
--- a/chromium/content/renderer/render_view_browsertest.cc
+++ b/chromium/content/renderer/render_view_browsertest.cc
@@ -22,8 +22,6 @@
#include "base/values.h"
#include "build/build_config.h"
#include "cc/trees/layer_tree_host.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/service_worker/service_worker_network_provider.h"
#include "content/common/content_switches_internal.h"
#include "content/common/frame_messages.h"
#include "content/common/frame_owner_properties.h"
@@ -53,10 +51,12 @@
#include "content/renderer/gpu/render_widget_compositor.h"
#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/render_frame_proxy.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_view_impl.h"
+#include "content/renderer/service_worker/service_worker_network_provider.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/test/mock_keyboard.h"
@@ -70,6 +70,7 @@
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h"
+#include "third_party/WebKit/public/web/WebDevToolsAgent.h"
#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h"
#include "third_party/WebKit/public/web/WebDocumentLoader.h"
#include "third_party/WebKit/public/web/WebFrameContentDumper.h"
@@ -95,12 +96,12 @@
#endif
#if defined(USE_AURA) && defined(USE_X11)
-#include <X11/Xlib.h>
#include "base/memory/ptr_util.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/test/events_test_utils.h"
#include "ui/events/test/events_test_utils_x11.h"
+#include "ui/gfx/x/x11.h"
#endif
#if defined(USE_OZONE)
@@ -155,7 +156,7 @@ class WebUITestWebUIControllerFactory : public WebUIControllerFactory {
public:
WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
const GURL& url) const override {
- return NULL;
+ return nullptr;
}
WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
const GURL& url) const override {
@@ -194,7 +195,7 @@ FrameReplicationState ReconstructReplicationStateForTesting(
// blink API...
result.name = frame->AssignedName().Utf8();
result.unique_name = test_render_frame->unique_name();
- result.sandbox_flags = frame->EffectiveSandboxFlags();
+ result.frame_policy.sandbox_flags = frame->EffectiveSandboxFlags();
// result.should_enforce_strict_mixed_content_checking is calculated in the
// browser...
result.origin = frame->GetSecurityOrigin();
@@ -419,15 +420,14 @@ class DevToolsAgentTest : public RenderViewImplTest {
void Attach() {
notifications_ = std::vector<std::string>();
expecting_pause_ = false;
- std::string host_id = "host_id";
- agent()->OnAttach(host_id, 17);
+ agent()->GetWebAgent()->Attach(17);
agent()->send_protocol_message_callback_for_test_ = base::Bind(
&DevToolsAgentTest::OnDevToolsMessage, base::Unretained(this));
}
void Detach() {
agent()->send_protocol_message_callback_for_test_.Reset();
- agent()->DetachAllSessions();
+ agent()->GetWebAgent()->Detach(17);
}
bool IsPaused() {
@@ -436,7 +436,7 @@ class DevToolsAgentTest : public RenderViewImplTest {
void DispatchDevToolsMessage(const std::string& method,
const std::string& message) {
- agent()->OnDispatchOnInspectorBackend(17, 1, method, message);
+ agent()->DispatchOnInspectorBackend(17, 1, method, message);
}
void CloseWhilePaused() {
@@ -444,8 +444,10 @@ class DevToolsAgentTest : public RenderViewImplTest {
view()->NotifyOnClose();
}
- void OnDevToolsMessage(
- int, int, const std::string& message, const std::string&) {
+ void OnDevToolsMessage(int,
+ int,
+ const std::string& message,
+ const std::string&) {
last_message_ = base::WrapUnique(static_cast<base::DictionaryValue*>(
base::JSONReader::Read(message).release()));
int id;
@@ -468,6 +470,12 @@ class DevToolsAgentTest : public RenderViewImplTest {
base::Unretained(this), "Debugger.resume",
"{\"id\":100,\"method\":\"Debugger.resume\"}"));
}
+
+ if (notification == "Page.windowOpen") {
+ window_open_notification_ =
+ base::WrapUnique(static_cast<base::DictionaryValue*>(
+ base::JSONReader::Read(message).release()));
+ }
}
}
@@ -489,6 +497,10 @@ class DevToolsAgentTest : public RenderViewImplTest {
call_frames_count_ = call_frames_count;
}
+ base::DictionaryValue* WindowOpenNotification() {
+ return window_open_notification_.get();
+ }
+
private:
DevToolsAgent* agent() {
return frame()->devtools_agent();
@@ -496,6 +508,7 @@ class DevToolsAgentTest : public RenderViewImplTest {
std::vector<std::string> notifications_;
std::unique_ptr<base::DictionaryValue> last_message_;
+ std::unique_ptr<base::DictionaryValue> window_open_notification_;
int call_frames_count_;
bool expecting_pause_;
};
@@ -655,6 +668,7 @@ TEST_F(RenderViewImplTest, OnNavigationLoadDataWithBaseURL) {
request_params.data_url_as_string =
"data:text/html,<html><head><title>Data page</title></head></html>";
+ render_thread_->sink().ClearMessages();
frame()->Navigate(common_params, StartNavigationParams(),
request_params);
const IPC::Message* frame_title_msg = nullptr;
@@ -680,9 +694,9 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicy) {
// Navigations to normal HTTP URLs can be handled locally.
blink::WebURLRequest request(GURL("http://foo.com"));
- request.SetFetchRequestMode(blink::WebURLRequest::kFetchRequestModeNavigate);
+ request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNavigate);
request.SetFetchCredentialsMode(
- blink::WebURLRequest::kFetchCredentialsModeInclude);
+ network::mojom::FetchCredentialsMode::kInclude);
request.SetFetchRedirectMode(blink::WebURLRequest::kFetchRedirectModeManual);
request.SetFrameType(blink::WebURLRequest::kFrameTypeTopLevel);
request.SetRequestContext(blink::WebURLRequest::kRequestContextInternal);
@@ -827,7 +841,7 @@ TEST_F(RenderViewImplTest, OriginReplicationForSwapOut) {
// WebRemoteFrame.
content::FrameReplicationState replication_state =
ReconstructReplicationStateForTesting(child_frame);
- replication_state.origin = url::Origin(GURL("http://foo.com"));
+ replication_state.origin = url::Origin::Create(GURL("http://foo.com"));
child_frame->SwapOut(kProxyRoutingId, true, replication_state);
// The child frame should now be a WebRemoteFrame.
@@ -851,6 +865,59 @@ TEST_F(RenderViewImplTest, OriginReplicationForSwapOut) {
web_frame->FirstChild()->NextSibling()->GetSecurityOrigin().IsUnique());
}
+// When we enable --use-zoom-for-dsf, visiting the first web page after opening
+// a new tab looks fine, but visiting the second web page renders smaller DOM
+// elements. We can solve this by updating DSF after swapping in the main frame.
+// See crbug.com/737777#c37.
+TEST_F(RenderViewImplScaleFactorTest, UpdateDSFAfterSwapIn) {
+ DoSetUp();
+ // The bug reproduces if zoom is used for devices scale factor.
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableUseZoomForDSF);
+ const float device_scale = 3.0f;
+ SetDeviceScaleFactor(device_scale);
+ EXPECT_EQ(device_scale, view()->GetDeviceScaleFactor());
+
+ LoadHTML("Hello world!");
+
+ // Swap the main frame out after which it should become a WebRemoteFrame.
+ content::FrameReplicationState replication_state =
+ ReconstructReplicationStateForTesting(frame());
+ // replication_state.origin = url::Origin(GURL("http://foo.com"));
+ frame()->SwapOut(kProxyRoutingId, true, replication_state);
+ EXPECT_TRUE(view()->webview()->MainFrame()->IsWebRemoteFrame());
+
+ // Do the remote-to-local transition for the proxy, which is to create a
+ // provisional local frame.
+ int routing_id = kProxyRoutingId + 1;
+ service_manager::mojom::InterfaceProviderPtr stub_interface_provider;
+ mojo::MakeRequest(&stub_interface_provider);
+ mojom::CreateFrameWidgetParams widget_params;
+ widget_params.routing_id = view()->GetRoutingID();
+ widget_params.hidden = false;
+ RenderFrameImpl::CreateFrame(
+ routing_id, std::move(stub_interface_provider), kProxyRoutingId,
+ MSG_ROUTING_NONE, MSG_ROUTING_NONE, MSG_ROUTING_NONE,
+ base::UnguessableToken::Create(), replication_state, nullptr,
+ widget_params, FrameOwnerProperties());
+ TestRenderFrame* provisional_frame =
+ static_cast<TestRenderFrame*>(RenderFrameImpl::FromRoutingID(routing_id));
+ EXPECT_TRUE(provisional_frame);
+
+ // Navigate to other page, which triggers the swap in.
+ CommonNavigationParams common_params;
+ StartNavigationParams start_params;
+ RequestNavigationParams request_params;
+ common_params.url = GURL("data:text/html,<div>Page</div>");
+ common_params.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
+ common_params.transition = ui::PAGE_TRANSITION_TYPED;
+
+ provisional_frame->Navigate(common_params, start_params, request_params);
+
+ EXPECT_EQ(device_scale, view()->GetDeviceScaleFactor());
+ EXPECT_EQ(device_scale, view()->webview()->ZoomFactorForDeviceScaleFactor());
+}
+
// Test that when a parent detaches a remote child after the provisional
// RenderFrame is created but before it is navigated, the RenderFrame is
// destroyed along with the proxy. This protects against races in
@@ -874,13 +941,16 @@ TEST_F(RenderViewImplTest, DetachingProxyAlsoDestroysProvisionalFrame) {
// Do the first step of a remote-to-local transition for the child proxy,
// which is to create a provisional local frame.
int routing_id = kProxyRoutingId + 1;
+ service_manager::mojom::InterfaceProviderPtr stub_interface_provider;
+ mojo::MakeRequest(&stub_interface_provider);
mojom::CreateFrameWidgetParams widget_params;
widget_params.routing_id = MSG_ROUTING_NONE;
widget_params.hidden = false;
RenderFrameImpl::CreateFrame(
- routing_id, kProxyRoutingId, MSG_ROUTING_NONE, frame()->GetRoutingID(),
- MSG_ROUTING_NONE, base::UnguessableToken::Create(), replication_state,
- nullptr, widget_params, FrameOwnerProperties());
+ routing_id, std::move(stub_interface_provider), kProxyRoutingId,
+ MSG_ROUTING_NONE, frame()->GetRoutingID(), MSG_ROUTING_NONE,
+ base::UnguessableToken::Create(), replication_state, nullptr,
+ widget_params, FrameOwnerProperties());
{
TestRenderFrame* provisional_frame = static_cast<TestRenderFrame*>(
RenderFrameImpl::FromRoutingID(routing_id));
@@ -1091,7 +1161,7 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
// to activate IMEs.
view()->UpdateTextInputState();
const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
- EXPECT_TRUE(msg != NULL);
+ EXPECT_TRUE(msg != nullptr);
EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
ViewHostMsg_TextInputStateChanged::Param params;
ViewHostMsg_TextInputStateChanged::Read(msg, &params);
@@ -1112,7 +1182,7 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
// to de-activate IMEs.
view()->UpdateTextInputState();
msg = render_thread_->sink().GetMessageAt(0);
- EXPECT_TRUE(msg != NULL);
+ EXPECT_TRUE(msg != nullptr);
EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
ViewHostMsg_TextInputStateChanged::Read(msg, &params);
p = std::get<0>(params);
@@ -1127,7 +1197,8 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
test_case->input_id);
// Move the input focus to the target <input> element, where we should
// activate IMEs.
- ExecuteJavaScriptAndReturnIntValue(base::ASCIIToUTF16(javascript), NULL);
+ ExecuteJavaScriptAndReturnIntValue(base::ASCIIToUTF16(javascript),
+ nullptr);
base::RunLoop().RunUntilIdle();
render_thread_->sink().ClearMessages();
@@ -1136,7 +1207,7 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
view()->UpdateTextInputState();
base::RunLoop().RunUntilIdle();
const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
- EXPECT_TRUE(msg != NULL);
+ EXPECT_TRUE(msg != nullptr);
EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
ViewHostMsg_TextInputStateChanged::Read(msg, &params);
p = std::get<0>(params);
@@ -1178,9 +1249,9 @@ TEST_F(RenderViewImplTest, ImeComposition) {
};
static const ImeMessage kImeMessages[] = {
// Scenario 1: input a Chinese word with Microsoft IME.
- {IME_INITIALIZE, true, 0, 0, NULL, NULL},
- {IME_SETINPUTMODE, true, 0, 0, NULL, NULL},
- {IME_SETFOCUS, true, 0, 0, NULL, NULL},
+ {IME_INITIALIZE, true, 0, 0, nullptr, nullptr},
+ {IME_SETINPUTMODE, true, 0, 0, nullptr, nullptr},
+ {IME_SETFOCUS, true, 0, 0, nullptr, nullptr},
{IME_SETCOMPOSITION, false, 1, 1, L"n", L"n"},
{IME_SETCOMPOSITION, false, 2, 2, L"ni", L"ni"},
{IME_SETCOMPOSITION, false, 3, 3, L"nih", L"nih"},
@@ -1188,9 +1259,9 @@ TEST_F(RenderViewImplTest, ImeComposition) {
{IME_SETCOMPOSITION, false, 5, 5, L"nihao", L"nihao"},
{IME_COMMITTEXT, false, -1, -1, L"\x4F60\x597D", L"\x4F60\x597D"},
// Scenario 2: input a Japanese word with Microsoft IME.
- {IME_INITIALIZE, true, 0, 0, NULL, NULL},
- {IME_SETINPUTMODE, true, 0, 0, NULL, NULL},
- {IME_SETFOCUS, true, 0, 0, NULL, NULL},
+ {IME_INITIALIZE, true, 0, 0, nullptr, nullptr},
+ {IME_SETINPUTMODE, true, 0, 0, nullptr, nullptr},
+ {IME_SETFOCUS, true, 0, 0, nullptr, nullptr},
{IME_SETCOMPOSITION, false, 0, 1, L"\xFF4B", L"\xFF4B"},
{IME_SETCOMPOSITION, false, 0, 1, L"\x304B", L"\x304B"},
{IME_SETCOMPOSITION, false, 0, 2, L"\x304B\xFF4E", L"\x304B\xFF4E"},
@@ -1203,9 +1274,9 @@ TEST_F(RenderViewImplTest, ImeComposition) {
{IME_FINISHCOMPOSINGTEXT, false, -1, -1, L"", L"\x6F22\x5B57"},
{IME_CANCELCOMPOSITION, false, -1, -1, L"", L"\x6F22\x5B57"},
// Scenario 3: input a Korean word with Microsot IME.
- {IME_INITIALIZE, true, 0, 0, NULL, NULL},
- {IME_SETINPUTMODE, true, 0, 0, NULL, NULL},
- {IME_SETFOCUS, true, 0, 0, NULL, NULL},
+ {IME_INITIALIZE, true, 0, 0, nullptr, nullptr},
+ {IME_SETINPUTMODE, true, 0, 0, nullptr, nullptr},
+ {IME_SETFOCUS, true, 0, 0, nullptr, nullptr},
{IME_SETCOMPOSITION, false, 0, 1, L"\x3147", L"\x3147"},
{IME_SETCOMPOSITION, false, 0, 1, L"\xC544", L"\xC544"},
{IME_SETCOMPOSITION, false, 0, 1, L"\xC548", L"\xC548"},
@@ -1306,12 +1377,8 @@ TEST_F(RenderViewImplTest, OnSetTextDirection) {
WebTextDirection direction;
const wchar_t* expected_result;
} kTextDirection[] = {
- {blink::kWebTextDirectionRightToLeft,
- L"\x000A"
- L"rtl,rtl"},
- {blink::kWebTextDirectionLeftToRight,
- L"\x000A"
- L"ltr,ltr"},
+ {blink::kWebTextDirectionRightToLeft, L"rtl,rtl"},
+ {blink::kWebTextDirectionLeftToRight, L"ltr,ltr"},
};
for (size_t i = 0; i < arraysize(kTextDirection); ++i) {
// Set the text direction of the <textarea> element.
@@ -1341,10 +1408,7 @@ TEST_F(RenderViewImplTest, OnSetTextDirection) {
// Crashy, http://crbug.com/53247.
TEST_F(RenderViewImplTest, DISABLED_DidFailProvisionalLoadWithErrorForError) {
GetMainFrame()->EnableViewSourceMode(true);
- WebURLError error;
- error.domain = WebURLError::Domain::kNet;
- error.reason = net::ERR_FILE_NOT_FOUND;
- error.unreachable_url = GURL("http://foo");
+ WebURLError error(net::ERR_FILE_NOT_FOUND, GURL("http://foo"));
WebLocalFrame* web_frame = GetMainFrame();
// Start a load that will reach provisional state synchronously,
@@ -1364,10 +1428,7 @@ TEST_F(RenderViewImplTest, DISABLED_DidFailProvisionalLoadWithErrorForError) {
TEST_F(RenderViewImplTest, DidFailProvisionalLoadWithErrorForCancellation) {
GetMainFrame()->EnableViewSourceMode(true);
- WebURLError error;
- error.domain = WebURLError::Domain::kNet;
- error.reason = net::ERR_ABORTED;
- error.unreachable_url = GURL("http://foo");
+ WebURLError error(net::ERR_ABORTED, GURL("http://foo"));
WebLocalFrame* web_frame = GetMainFrame();
// Start a load that will reach provisional state synchronously,
@@ -1847,10 +1908,8 @@ class RendererErrorPageTest : public RenderViewImplTest {
#endif
TEST_F(RendererErrorPageTest, MAYBE_Suppresses) {
- WebURLError error;
- error.domain = WebURLError::Domain::kNet;
- error.reason = net::ERR_FILE_NOT_FOUND;
- error.unreachable_url = GURL("http://example.com/suppress");
+ WebURLError error(net::ERR_FILE_NOT_FOUND,
+ GURL("http://example.com/suppress"));
// Start a load that will reach provisional state synchronously,
// but won't complete synchronously.
@@ -1877,10 +1936,8 @@ TEST_F(RendererErrorPageTest, MAYBE_Suppresses) {
#endif
TEST_F(RendererErrorPageTest, MAYBE_DoesNotSuppress) {
- WebURLError error;
- error.domain = WebURLError::Domain::kNet;
- error.reason = net::ERR_FILE_NOT_FOUND;
- error.unreachable_url = GURL("http://example.com/dont-suppress");
+ WebURLError error(net::ERR_FILE_NOT_FOUND,
+ GURL("http://example.com/dont-suppress"));
// Start a load that will reach provisional state synchronously,
// but won't complete synchronously.
@@ -2653,4 +2710,62 @@ TEST_F(DevToolsAgentTest, CallFramesInIsolatedWorld) {
Detach();
}
+TEST_F(DevToolsAgentTest, WindowOpenWithEmptyURL) {
+ Attach();
+ DispatchDevToolsMessage("Page.enable",
+ "{\"id\":1,\"method\":\"Page.enable\"}");
+ LoadHTMLWithUrlOverride("<script>window.open()</script>",
+ "https://www.example.com");
+
+ base::DictionaryValue* notification = WindowOpenNotification();
+ EXPECT_TRUE(notification);
+ const base::Value* params_value = notification->FindKey("params");
+ EXPECT_TRUE(params_value && params_value->is_dict());
+ const base::Value* url_value = params_value->FindKey("url");
+ EXPECT_TRUE(url_value);
+ EXPECT_EQ(url::kAboutBlankURL, url_value->GetString());
+}
+
+TEST_F(DevToolsAgentTest, WindowOpenWithRelativeURL) {
+ // Enable browser side navigation to avoid actually load url for the new
+ // window.
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableBrowserSideNavigation);
+ Attach();
+ DispatchDevToolsMessage("Page.enable",
+ "{\"id\":1,\"method\":\"Page.enable\"}");
+ LoadHTMLWithUrlOverride("<script>window.open('path')</script>",
+ "https://www.example.com");
+
+ base::DictionaryValue* notification = WindowOpenNotification();
+ EXPECT_TRUE(notification);
+ const base::Value* params_value = notification->FindKey("params");
+ EXPECT_TRUE(params_value && params_value->is_dict());
+ const base::Value* url_value = params_value->FindKey("url");
+ EXPECT_TRUE(url_value);
+ EXPECT_EQ("https://www.example.com/path", url_value->GetString());
+}
+
+TEST_F(DevToolsAgentTest, WindowOpenFromClick) {
+ // Enable browser side navigation to avoid actually load url for the new
+ // window.
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableBrowserSideNavigation);
+ Attach();
+ DispatchDevToolsMessage("Page.enable",
+ "{\"id\":1,\"method\":\"Page.enable\"}");
+ LoadHTMLWithUrlOverride(
+ "<a id='my_anchor' href='/anchor' target='_blank'> </a>\n"
+ "<script>document.getElementById('my_anchor').click();</script>",
+ "https://www.example.com");
+
+ base::DictionaryValue* notification = WindowOpenNotification();
+ EXPECT_TRUE(notification);
+ const base::Value* params_value = notification->FindKey("params");
+ EXPECT_TRUE(params_value && params_value->is_dict());
+ const base::Value* url_value = params_value->FindKey("url");
+ EXPECT_TRUE(url_value);
+ EXPECT_EQ("https://www.example.com/anchor", url_value->GetString());
+}
+
} // namespace content
diff --git a/chromium/content/renderer/render_view_impl.cc b/chromium/content/renderer/render_view_impl.cc
index 22bd13a28fb..f86a3361d53 100644
--- a/chromium/content/renderer/render_view_impl.cc
+++ b/chromium/content/renderer/render_view_impl.cc
@@ -41,10 +41,6 @@
#include "cc/base/switches.h"
#include "cc/paint/skia_paint_canvas.h"
#include "components/viz/client/client_shared_bitmap_manager.h"
-#include "content/child/appcache/appcache_dispatcher.h"
-#include "content/child/appcache/web_application_cache_host_impl.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/v8_value_converter_impl.h"
#include "content/common/content_constants_internal.h"
#include "content/common/content_switches_internal.h"
#include "content/common/dom_storage/dom_storage_types.h"
@@ -55,7 +51,6 @@
#include "content/common/page_messages.h"
#include "content/common/render_message_filter.mojom.h"
#include "content/common/view_messages.h"
-#include "content/public/common/associated_interface_provider.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
@@ -73,9 +68,10 @@
#include "content/public/renderer/render_view_observer.h"
#include "content/public/renderer/render_view_visitor.h"
#include "content/public/renderer/window_features_converter.h"
+#include "content/renderer/appcache/appcache_dispatcher.h"
+#include "content/renderer/appcache/web_application_cache_host_impl.h"
#include "content/renderer/browser_plugin/browser_plugin.h"
#include "content/renderer/browser_plugin/browser_plugin_manager.h"
-#include "content/renderer/dom_storage/webstoragenamespace_impl.h"
#include "content/renderer/drop_data_builder.h"
#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/history_serialization.h"
@@ -83,8 +79,9 @@
#include "content/renderer/ime_event_guard.h"
#include "content/renderer/input/input_handler_manager.h"
#include "content/renderer/internal_document_state_data.h"
+#include "content/renderer/loader/request_extra_data.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/media_stream_dispatcher.h"
+#include "content/renderer/media/media_stream_device_observer.h"
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/navigation_state_impl.h"
#include "content/renderer/render_frame_impl.h"
@@ -96,6 +93,7 @@
#include "content/renderer/resizing_mode_selector.h"
#include "content/renderer/savable_resources.h"
#include "content/renderer/speech_recognition_dispatcher.h"
+#include "content/renderer/v8_value_converter_impl.h"
#include "content/renderer/web_ui_extension_data.h"
#include "media/audio/audio_output_device.h"
#include "media/base/media_switches.h"
@@ -109,6 +107,8 @@
#include "net/http/http_util.h"
#include "ppapi/features/features.h"
#include "skia/ext/platform_canvas.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/FilePathConversion.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebConnectionType.h"
@@ -116,6 +116,7 @@
#include "third_party/WebKit/public/platform/WebImage.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/WebKit/public/platform/WebInputEventResult.h"
+#include "third_party/WebKit/public/platform/WebNetworkStateNotifier.h"
#include "third_party/WebKit/public/platform/WebPoint.h"
#include "third_party/WebKit/public/platform/WebRect.h"
#include "third_party/WebKit/public/platform/WebRuntimeFeatures.h"
@@ -235,7 +236,6 @@ using blink::WebSecurityOrigin;
using blink::WebSecurityPolicy;
using blink::WebSettings;
using blink::WebSize;
-using blink::WebStorageNamespace;
using blink::WebStorageQuotaCallbacks;
using blink::WebStorageQuotaError;
using blink::WebStorageQuotaType;
@@ -253,7 +253,6 @@ using blink::WebView;
using blink::WebWidget;
using blink::WebWindowFeatures;
using blink::WebRuntimeFeatures;
-using base::Time;
using base::TimeDelta;
@@ -445,31 +444,6 @@ void ApplyBlinkSettings(const base::CommandLine& command_line,
}
}
-WebSettings::V8CacheStrategiesForCacheStorage
-GetV8CacheStrategiesForCacheStorage() {
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- std::string v8_cache_strategies = command_line.GetSwitchValueASCII(
- switches::kV8CacheStrategiesForCacheStorage);
- if (v8_cache_strategies.empty()) {
- v8_cache_strategies =
- base::FieldTrialList::FindFullName("V8CacheStrategiesForCacheStorage");
- }
-
- if (base::StartsWith(v8_cache_strategies, "none",
- base::CompareCase::SENSITIVE)) {
- return WebSettings::V8CacheStrategiesForCacheStorage::kNone;
- } else if (base::StartsWith(v8_cache_strategies, "normal",
- base::CompareCase::SENSITIVE)) {
- return WebSettings::V8CacheStrategiesForCacheStorage::kNormal;
- } else if (base::StartsWith(v8_cache_strategies, "aggressive",
- base::CompareCase::SENSITIVE)) {
- return WebSettings::V8CacheStrategiesForCacheStorage::kAggressive;
- } else {
- return WebSettings::V8CacheStrategiesForCacheStorage::kDefault;
- }
-}
-
// This class represents promise which is robust to (will not be broken by)
// |DidNotSwapReason::SWAP_FAILS| events.
class AlwaysDrawSwapPromise : public cc::SwapPromise {
@@ -541,11 +515,10 @@ RenderViewImpl::RenderViewImpl(CompositorDependencies* compositor_deps,
top_controls_height_(0.f),
bottom_controls_height_(0.f),
webview_(nullptr),
- has_scrolled_focused_editable_node_into_rect_(false),
page_zoom_level_(params.page_zoom_level),
main_render_frame_(nullptr),
frame_widget_(nullptr),
- speech_recognition_dispatcher_(NULL),
+ speech_recognition_dispatcher_(nullptr),
#if defined(OS_ANDROID)
was_created_by_renderer_(false),
#endif
@@ -556,7 +529,7 @@ RenderViewImpl::RenderViewImpl(CompositorDependencies* compositor_deps,
}
void RenderViewImpl::Initialize(
- const mojom::CreateViewParams& params,
+ mojom::CreateViewParamsPtr params,
const RenderWidget::ShowCallback& show_callback) {
bool was_created_by_renderer = !show_callback.is_null();
#if defined(OS_ANDROID)
@@ -564,11 +537,11 @@ void RenderViewImpl::Initialize(
// HandleNavigation codepath.
was_created_by_renderer_ = was_created_by_renderer;
#endif
- display_mode_ = params.initial_size.display_mode;
+ display_mode_ = params->initial_size.display_mode;
- webview_ = WebView::Create(this, is_hidden()
- ? blink::kWebPageVisibilityStateHidden
- : blink::kWebPageVisibilityStateVisible);
+ webview_ = WebView::Create(
+ this, is_hidden() ? blink::mojom::PageVisibilityState::kHidden
+ : blink::mojom::PageVisibilityState::kVisible);
RenderWidget::Init(show_callback, webview_->GetWidget());
g_view_map.Get().insert(std::make_pair(webview(), this));
@@ -620,23 +593,28 @@ void RenderViewImpl::Initialize(
ApplyBlinkSettings(command_line, webview()->GetSettings());
WebFrame* opener_frame =
- RenderFrameImpl::ResolveOpener(params.opener_frame_route_id);
+ RenderFrameImpl::ResolveOpener(params->opener_frame_route_id);
- if (params.main_frame_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(
+ std::move(params->main_frame_interface_provider));
main_render_frame_ = RenderFrameImpl::CreateMainFrame(
- this, params.main_frame_routing_id, params.main_frame_widget_routing_id,
- params.hidden, screen_info(), compositor_deps_, opener_frame,
- params.devtools_main_frame_token, params.replicated_frame_state);
+ this, params->main_frame_routing_id,
+ std::move(main_frame_interface_provider),
+ params->main_frame_widget_routing_id, params->hidden, screen_info(),
+ compositor_deps_, opener_frame, params->devtools_main_frame_token,
+ params->replicated_frame_state);
}
// 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) {
- CHECK(params.swapped_out);
- RenderFrameProxy::CreateFrameProxy(params.proxy_routing_id, GetRoutingID(),
+ if (params->proxy_routing_id != MSG_ROUTING_NONE) {
+ CHECK(params->swapped_out);
+ RenderFrameProxy::CreateFrameProxy(params->proxy_routing_id, GetRoutingID(),
opener_frame, MSG_ROUTING_NONE,
- params.replicated_frame_state);
+ params->replicated_frame_state);
}
if (main_render_frame_)
@@ -650,32 +628,29 @@ void RenderViewImpl::Initialize(
did_show_ = true;
// TODO(davidben): Move this state from Blink into content.
- if (params.window_was_created_with_opener)
+ if (params->window_was_created_with_opener)
webview()->SetOpenedByDOM();
UpdateWebViewWithDeviceScaleFactor();
- OnSetRendererPrefs(params.renderer_preferences);
+ OnSetRendererPrefs(params->renderer_preferences);
- if (!params.enable_auto_resize) {
- OnResize(params.initial_size);
+ if (!params->enable_auto_resize) {
+ OnResize(params->initial_size);
} else {
- OnEnableAutoResize(params.min_size, params.max_size);
+ OnEnableAutoResize(params->min_size, params->max_size);
}
idle_user_detector_.reset(new IdleUserDetector(this));
GetContentClient()->renderer()->RenderViewCreated(this);
- page_zoom_level_ = params.page_zoom_level;
+ page_zoom_level_ = params->page_zoom_level;
}
RenderViewImpl::~RenderViewImpl() {
DCHECK(!frame_widget_);
- for (BitmapMap::iterator it = disambiguation_bitmaps_.begin();
- it != disambiguation_bitmaps_.end();
- ++it)
- delete it->second;
+ disambiguation_bitmaps_.clear();
#if defined(OS_ANDROID)
// The date/time picker client is both a std::unique_ptr member of this class
@@ -768,7 +743,6 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
settings->SetLoadsImagesAutomatically(prefs.loads_images_automatically);
settings->SetImagesEnabled(prefs.images_enabled);
settings->SetPluginsEnabled(prefs.plugins_enabled);
- settings->SetEncryptedMediaEnabled(prefs.encrypted_media_enabled);
settings->SetDOMPasteAllowed(prefs.dom_paste_enabled);
settings->SetTextAreasAreResizable(prefs.text_areas_are_resizable);
settings->SetAllowScriptsToCloseWindows(prefs.allow_scripts_to_close_windows);
@@ -778,7 +752,7 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
WebRuntimeFeatures::EnableXSLT(prefs.xslt_enabled);
settings->SetXSSAuditorEnabled(prefs.xss_auditor_enabled);
settings->SetDNSPrefetchingEnabled(prefs.dns_prefetching_enabled);
- settings->SetDataSaverEnabled(
+ blink::WebNetworkStateNotifier::SetSaveDataEnabled(
prefs.data_saver_enabled &&
!base::FeatureList::IsEnabled(features::kDataSaverHoldback));
settings->SetLocalStorageEnabled(prefs.local_storage_enabled);
@@ -889,9 +863,6 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
settings->SetV8CacheOptions(
static_cast<WebSettings::V8CacheOptions>(prefs.v8_cache_options));
- settings->SetV8CacheStrategiesForCacheStorage(
- GetV8CacheStrategiesForCacheStorage());
-
settings->SetImageAnimationPolicy(
static_cast<WebSettings::ImageAnimationPolicy>(prefs.animation_policy));
@@ -1018,9 +989,6 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
WebRuntimeFeatures::EnableNewRemotePlaybackPipeline(
base::FeatureList::IsEnabled(media::kNewRemotePlaybackPipeline));
- WebRuntimeFeatures::EnablePreloadDefaultIsMetadata(
- base::FeatureList::IsEnabled(media::kPreloadDefaultIsMetadata));
-
settings->SetPresentationReceiver(prefs.presentation_receiver);
settings->SetMediaControlsEnabled(prefs.media_controls_enabled);
@@ -1038,16 +1006,16 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
/*static*/
RenderViewImpl* RenderViewImpl::Create(
CompositorDependencies* compositor_deps,
- const mojom::CreateViewParams& params,
+ mojom::CreateViewParamsPtr params,
const RenderWidget::ShowCallback& show_callback) {
- DCHECK(params.view_id != MSG_ROUTING_NONE);
- RenderViewImpl* render_view = NULL;
+ DCHECK(params->view_id != MSG_ROUTING_NONE);
+ RenderViewImpl* render_view;
if (g_create_render_view_impl)
- render_view = g_create_render_view_impl(compositor_deps, params);
+ render_view = g_create_render_view_impl(compositor_deps, *params);
else
- render_view = new RenderViewImpl(compositor_deps, params);
+ render_view = new RenderViewImpl(compositor_deps, *params);
- render_view->Initialize(params, show_callback);
+ render_view->Initialize(std::move(params), show_callback);
return render_view;
}
@@ -1103,13 +1071,6 @@ void RenderViewImpl::OnGetRenderedText() {
// RenderWidgetInputHandlerDelegate -----------------------------------------
-bool RenderViewImpl::DoesRenderWidgetHaveTouchEventHandlersAt(
- const gfx::Point& point) const {
- if (!webview())
- return false;
- return webview()->HasTouchEventHandlersAt(point);
-}
-
bool RenderViewImpl::RenderWidgetWillHandleMouseEvent(
const blink::WebMouseEvent& event) {
// If the mouse is locked, only the current owner of the mouse lock can
@@ -1120,7 +1081,7 @@ bool RenderViewImpl::RenderWidgetWillHandleMouseEvent(
// IPC::Listener implementation ----------------------------------------------
bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
- WebFrame* main_frame = webview() ? webview()->MainFrame() : NULL;
+ WebFrame* main_frame = webview() ? webview()->MainFrame() : nullptr;
if (main_frame && main_frame->IsWebLocalFrame())
GetContentClient()->SetActiveURL(
main_frame->ToWebLocalFrame()->GetDocument().Url());
@@ -1155,6 +1116,8 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
OnEnablePreferredSizeChangedMode)
IPC_MESSAGE_HANDLER(ViewMsg_EnableAutoResize, OnEnableAutoResize)
IPC_MESSAGE_HANDLER(ViewMsg_DisableAutoResize, OnDisableAutoResize)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetLocalSurfaceIdForAutoResize,
+ OnSetLocalSurfaceIdForAutoResize)
IPC_MESSAGE_HANDLER(ViewMsg_DisableScrollbarsForSmallWindows,
OnDisableScrollbarsForSmallWindows)
IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
@@ -1172,7 +1135,6 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(PageMsg_UpdateWindowScreenRect,
OnUpdateWindowScreenRect)
IPC_MESSAGE_HANDLER(PageMsg_SetZoomLevel, OnSetZoomLevel)
- IPC_MESSAGE_HANDLER(PageMsg_SetDeviceScaleFactor, OnSetDeviceScaleFactor);
IPC_MESSAGE_HANDLER(PageMsg_WasHidden, OnPageWasHidden)
IPC_MESSAGE_HANDLER(PageMsg_WasShown, OnPageWasShown)
IPC_MESSAGE_HANDLER(PageMsg_SetHistoryOffsetAndLength,
@@ -1232,26 +1194,6 @@ void RenderViewImpl::OnUpdateTargetURLAck() {
target_url_status_ = TARGET_NONE;
}
-void RenderViewImpl::ScrollFocusedEditableNodeIntoRect(const gfx::Rect& rect) {
- blink::WebAutofillClient* autofill_client = nullptr;
- if (auto* focused_frame = GetWebView()->FocusedFrame())
- autofill_client = focused_frame->AutofillClient();
-
- if (has_scrolled_focused_editable_node_into_rect_ &&
- rect == rect_for_scrolled_focused_editable_node_ && autofill_client) {
- autofill_client->DidCompleteFocusChangeInFrame();
- return;
- }
-
- if (!webview()->ScrollFocusedEditableElementIntoRect(rect))
- return;
-
- rect_for_scrolled_focused_editable_node_ = rect;
- has_scrolled_focused_editable_node_into_rect_ = true;
- if (!compositor()->HasPendingPageScaleAnimation() && autofill_client)
- autofill_client->DidCompleteFocusChangeInFrame();
-}
-
void RenderViewImpl::OnSetHistoryOffsetAndLength(int history_offset,
int history_length) {
DCHECK_GE(history_offset, -1);
@@ -1313,7 +1255,7 @@ void RenderViewImpl::ApplyWebPreferencesInternal(
void RenderViewImpl::OnForceRedraw(const ui::LatencyInfo& latency_info) {
if (RenderWidgetCompositor* rwc = compositor()) {
rwc->QueueSwapPromise(
- base::MakeUnique<AlwaysDrawSwapPromise>(latency_info));
+ std::make_unique<AlwaysDrawSwapPromise>(latency_info));
rwc->SetNeedsForcedRedraw();
}
}
@@ -1331,7 +1273,8 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
WebSandboxFlags sandbox_flags) {
RenderFrameImpl* creator_frame = RenderFrameImpl::FromWebFrame(creator);
mojom::CreateNewWindowParamsPtr params = mojom::CreateNewWindowParams::New();
- params->user_gesture = WebUserGestureIndicator::IsProcessingUserGesture();
+ params->user_gesture =
+ WebUserGestureIndicator::IsProcessingUserGesture(creator);
if (GetContentClient()->renderer()->AllowPopup())
params->user_gesture = true;
params->window_container_type = WindowFeaturesToContainerType(features);
@@ -1353,10 +1296,11 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
params->disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB;
bool opened_by_user_gesture = params->user_gesture;
+ mojom::CreateNewWindowStatus status;
mojom::CreateNewWindowReplyPtr reply;
auto* frame_host = creator_frame->GetFrameHost();
- bool err = !frame_host->CreateNewWindow(std::move(params), &reply);
- if (err || reply->route_id == MSG_ROUTING_NONE)
+ bool err = !frame_host->CreateNewWindow(std::move(params), &status, &reply);
+ if (err || status == mojom::CreateNewWindowStatus::kIgnore)
return nullptr;
// For Android WebView, we support a pop-up like behavior for window.open()
@@ -1365,10 +1309,18 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
// passed. We also don't need to consume user gestures to protect against
// multiple windows being opened, because, well, the app doesn't support
// multiple windows.
- if (reply->route_id == GetRoutingID())
+ // TODO(dcheng): It's awkward that this is plumbed into Blink but not really
+ // used much in Blink, except to enable layout testing... perhaps this should
+ // be checked directly in the browser side.
+ if (status == mojom::CreateNewWindowStatus::kReuse)
return webview();
- WebUserGestureIndicator::ConsumeUserGesture();
+ DCHECK(reply);
+ DCHECK_NE(MSG_ROUTING_NONE, reply->route_id);
+ DCHECK_NE(MSG_ROUTING_NONE, reply->main_frame_route_id);
+ DCHECK_NE(MSG_ROUTING_NONE, reply->main_frame_widget_route_id);
+
+ WebUserGestureIndicator::ConsumeUserGesture(creator);
// While this view may be a background extension page, it can spawn a visible
// render view. So we just assume that the new one is not another background
@@ -1384,31 +1336,35 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
// return from this call synchronously, we just have to make our best guess
// and rely on the browser sending a WasHidden / WasShown message if it
// disagrees.
- mojom::CreateViewParams view_params;
+ mojom::CreateViewParamsPtr view_params = mojom::CreateViewParams::New();
- view_params.opener_frame_route_id = creator_frame->GetRoutingID();
+ view_params->opener_frame_route_id = creator_frame->GetRoutingID();
DCHECK_EQ(GetRoutingID(), creator_frame->render_view()->GetRoutingID());
- view_params.window_was_created_with_opener = true;
- view_params.renderer_preferences = renderer_preferences_;
- view_params.web_preferences = webkit_preferences_;
- view_params.view_id = reply->route_id;
- view_params.main_frame_routing_id = reply->main_frame_route_id;
- view_params.main_frame_widget_routing_id = reply->main_frame_widget_route_id;
- view_params.session_storage_namespace_id =
+ view_params->window_was_created_with_opener = true;
+ view_params->renderer_preferences = renderer_preferences_;
+ view_params->web_preferences = webkit_preferences_;
+ view_params->view_id = reply->route_id;
+ view_params->main_frame_routing_id = reply->main_frame_route_id;
+ view_params->main_frame_interface_provider =
+ std::move(reply->main_frame_interface_provider);
+ 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;
- view_params.swapped_out = false;
- view_params.replicated_frame_state.sandbox_flags = sandbox_flags;
- view_params.replicated_frame_state.name = frame_name_utf8;
+ view_params->swapped_out = false;
+ view_params->replicated_frame_state.frame_policy.sandbox_flags =
+ sandbox_flags;
+ view_params->replicated_frame_state.name = frame_name_utf8;
+ view_params->devtools_main_frame_token = reply->devtools_main_frame_token;
// Even if the main frame has a name, the main frame's unique name is always
// the empty string.
- view_params.hidden = is_background_tab;
- view_params.never_visible = never_visible;
- view_params.initial_size = initial_size;
- view_params.enable_auto_resize = false;
- view_params.min_size = gfx::Size();
- view_params.max_size = gfx::Size();
- view_params.page_zoom_level = page_zoom_level_;
+ view_params->hidden = is_background_tab;
+ view_params->never_visible = never_visible;
+ view_params->initial_size = initial_size;
+ view_params->enable_auto_resize = false;
+ view_params->min_size = gfx::Size();
+ view_params->max_size = gfx::Size();
+ view_params->page_zoom_level = page_zoom_level_;
// Unretained() is safe here because our calling function will also call
// show().
@@ -1416,17 +1372,17 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
base::Bind(&RenderFrameImpl::ShowCreatedWindow,
base::Unretained(creator_frame), opened_by_user_gesture);
- RenderViewImpl* view =
- RenderViewImpl::Create(compositor_deps_, view_params, show_callback);
+ RenderViewImpl* view = RenderViewImpl::Create(
+ compositor_deps_, std::move(view_params), show_callback);
return view->webview();
}
-WebWidget* RenderViewImpl::CreatePopupMenu(blink::WebPopupType popup_type) {
+WebWidget* RenderViewImpl::CreatePopup(blink::WebPopupType popup_type) {
RenderWidget* widget = RenderWidget::CreateForPopup(this, compositor_deps_,
popup_type, screen_info_);
if (!widget)
- return NULL;
+ return nullptr;
if (screen_metrics_emulator_) {
widget->SetPopupOriginAdjustmentsForEmulation(
screen_metrics_emulator_.get());
@@ -1434,9 +1390,9 @@ WebWidget* RenderViewImpl::CreatePopupMenu(blink::WebPopupType popup_type) {
return widget->GetWebWidget();
}
-WebStorageNamespace* RenderViewImpl::CreateSessionStorageNamespace() {
+int64_t RenderViewImpl::GetSessionStorageNamespaceId() {
CHECK(session_storage_namespace_id_ != kInvalidSessionStorageNamespaceId);
- return new WebStorageNamespaceImpl(session_storage_namespace_id_);
+ return session_storage_namespace_id_;
}
void RenderViewImpl::PrintPage(WebLocalFrame* frame) {
@@ -1523,33 +1479,6 @@ void RenderViewImpl::SetValidationMessageDirection(
}
}
-void RenderViewImpl::ShowValidationMessage(
- const blink::WebRect& anchor_in_viewport,
- const blink::WebString& main_text,
- blink::WebTextDirection main_text_hint,
- const blink::WebString& sub_text,
- blink::WebTextDirection sub_text_hint) {
- base::string16 wrapped_main_text = main_text.Utf16();
- base::string16 wrapped_sub_text = sub_text.Utf16();
-
- SetValidationMessageDirection(
- &wrapped_main_text, main_text_hint, &wrapped_sub_text, sub_text_hint);
-
- Send(new ViewHostMsg_ShowValidationMessage(
- GetRoutingID(), AdjustValidationMessageAnchor(anchor_in_viewport),
- wrapped_main_text, wrapped_sub_text));
-}
-
-void RenderViewImpl::HideValidationMessage() {
- Send(new ViewHostMsg_HideValidationMessage(GetRoutingID()));
-}
-
-void RenderViewImpl::MoveValidationMessage(
- const blink::WebRect& anchor_in_viewport) {
- Send(new ViewHostMsg_MoveValidationMessage(
- GetRoutingID(), AdjustValidationMessageAnchor(anchor_in_viewport)));
-}
-
void RenderViewImpl::UpdateTargetURL(const GURL& url,
const GURL& fallback_url) {
GURL latest_url = url.is_empty() ? fallback_url : url;
@@ -1633,8 +1562,6 @@ void RenderViewImpl::FocusPrevious() {
// TODO(esprehn): Blink only ever passes Elements, this should take WebElement.
void RenderViewImpl::FocusedNodeChanged(const WebNode& fromNode,
const WebNode& toNode) {
- has_scrolled_focused_editable_node_into_rect_ = false;
-
RenderFrameImpl* previous_frame = nullptr;
if (!fromNode.IsNull())
previous_frame =
@@ -1671,9 +1598,18 @@ void RenderViewImpl::DidUpdateLayout() {
}
void RenderViewImpl::NavigateBackForwardSoon(int offset) {
+ history_navigation_virtual_time_pauser_ =
+ RenderThreadImpl::current()
+ ->GetRendererScheduler()
+ ->CreateWebScopedVirtualTimePauser();
+ history_navigation_virtual_time_pauser_.PauseVirtualTime(true);
Send(new ViewHostMsg_GoToEntryAtOffset(GetRoutingID(), offset));
}
+void RenderViewImpl::DidCommitProvisionalHistoryLoad() {
+ history_navigation_virtual_time_pauser_.PauseVirtualTime(false);
+}
+
int RenderViewImpl::HistoryBackListCount() {
return history_list_offset_ < 0 ? 0 : history_list_offset_;
}
@@ -1688,7 +1624,13 @@ void RenderViewImpl::DidFocus() {
// TODO(jcivelli): when https://bugs.webkit.org/show_bug.cgi?id=33389 is fixed
// we won't have to test for user gesture anymore and we can
// move that code back to render_widget.cc
- if (WebUserGestureIndicator::IsProcessingUserGesture() &&
+ WebFrame* main_frame = webview() ? webview()->MainFrame() : nullptr;
+ bool is_processing_user_gesture =
+ WebUserGestureIndicator::IsProcessingUserGesture(
+ main_frame && main_frame->IsWebLocalFrame()
+ ? main_frame->ToWebLocalFrame()
+ : nullptr);
+ if (is_processing_user_gesture &&
!RenderThreadImpl::current()->layout_test_mode()) {
Send(new ViewHostMsg_Focus(GetRoutingID()));
}
@@ -1766,7 +1708,7 @@ void RenderViewImpl::DidOverscroll(
const blink::WebFloatSize& accumulatedOverscroll,
const blink::WebFloatPoint& positionInViewport,
const blink::WebFloatSize& velocityInViewport,
- const blink::WebScrollBoundaryBehavior& behavior) {
+ const blink::WebOverscrollBehavior& behavior) {
RenderWidget::DidOverscroll(overscrollDelta, accumulatedOverscroll,
positionInViewport, velocityInViewport, behavior);
}
@@ -1883,6 +1825,10 @@ float RenderViewImpl::GetDeviceScaleFactor() const {
return device_scale_factor_;
}
+float RenderViewImpl::GetZoomLevel() const {
+ return page_zoom_level_;
+}
+
const WebPreferences& RenderViewImpl::GetWebkitPreferences() {
return webkit_preferences_;
}
@@ -1963,7 +1909,6 @@ void RenderViewImpl::OnEnableAutoResize(const gfx::Size& min_size,
return;
auto_resize_mode_ = true;
- AutoResizeCompositor();
if (IsUseZoomForDSFEnabled()) {
webview()->EnableAutoResizeMode(
@@ -1997,6 +1942,27 @@ void RenderViewImpl::OnDisableAutoResize(const gfx::Size& new_size) {
}
}
+void RenderViewImpl::OnSetLocalSurfaceIdForAutoResize(
+ uint64_t sequence_number,
+ const gfx::Size& min_size,
+ const gfx::Size& max_size,
+ const content::ScreenInfo& screen_info,
+ const viz::LocalSurfaceId& local_surface_id) {
+ if (!auto_resize_mode_ || resize_or_repaint_ack_num_ != sequence_number)
+ return;
+
+ SetLocalSurfaceIdForAutoResize(sequence_number, screen_info,
+ local_surface_id);
+
+ if (IsUseZoomForDSFEnabled()) {
+ webview()->EnableAutoResizeMode(
+ gfx::ScaleToCeiledSize(min_size, device_scale_factor_),
+ gfx::ScaleToCeiledSize(max_size, device_scale_factor_));
+ } else {
+ webview()->EnableAutoResizeMode(min_size, max_size);
+ }
+}
+
void RenderViewImpl::OnEnablePreferredSizeChangedMode() {
if (send_preferred_size_changes_)
return;
@@ -2103,8 +2069,6 @@ void RenderViewImpl::OnResize(const ResizeParams& params) {
}
}
- gfx::Size old_visible_viewport_size = visible_viewport_size_;
-
browser_controls_shrink_blink_size_ =
params.browser_controls_shrink_blink_size;
top_controls_height_ = params.top_controls_height;
@@ -2112,8 +2076,8 @@ void RenderViewImpl::OnResize(const ResizeParams& params) {
RenderWidget::OnResize(params);
- if (old_visible_viewport_size != visible_viewport_size_)
- has_scrolled_focused_editable_node_into_rect_ = false;
+ if (params.scroll_focused_node_into_view)
+ webview()->ScrollFocusedEditableElementIntoView();
}
void RenderViewImpl::OnSetBackgroundOpaque(bool opaque) {
@@ -2171,9 +2135,9 @@ void RenderViewImpl::OnPageWasHidden() {
// frame. Currently, this is done because the main frame may override the
// visibility of the page when prerendering. In order to fix this,
// prerendering must be made aware of OOPIFs. https://crbug.com/440544
- blink::WebPageVisibilityState visibilityState =
+ blink::mojom::PageVisibilityState visibilityState =
GetMainRenderFrame() ? GetMainRenderFrame()->VisibilityState()
- : blink::kWebPageVisibilityStateHidden;
+ : blink::mojom::PageVisibilityState::kHidden;
webview()->SetVisibilityState(visibilityState, false);
}
}
@@ -2184,9 +2148,9 @@ void RenderViewImpl::OnPageWasShown() {
#endif
if (webview()) {
- blink::WebPageVisibilityState visibilityState =
+ blink::mojom::PageVisibilityState visibilityState =
GetMainRenderFrame() ? GetMainRenderFrame()->VisibilityState()
- : blink::kWebPageVisibilityStateVisible;
+ : blink::mojom::PageVisibilityState::kVisible;
webview()->SetVisibilityState(visibilityState, false);
}
}
@@ -2201,8 +2165,9 @@ void RenderViewImpl::OnUpdateScreenInfo(const ScreenInfo& screen_info) {
GURL RenderViewImpl::GetURLForGraphicsContext3D() {
DCHECK(webview());
- if (webview()->MainFrame()->IsWebLocalFrame())
- return GURL(webview()->MainFrame()->ToWebLocalFrame()->GetDocument().Url());
+ 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");
}
@@ -2233,7 +2198,7 @@ void RenderViewImpl::OnDeviceScaleFactorChanged() {
RenderWidget::OnDeviceScaleFactorChanged();
UpdateWebViewWithDeviceScaleFactor();
if (auto_resize_mode_)
- AutoResizeCompositor();
+ AutoResizeCompositor(viz::LocalSurfaceId());
}
void RenderViewImpl::SetScreenMetricsEmulationParameters(
@@ -2309,7 +2274,7 @@ bool RenderViewImpl::OpenDateTimeChooser(
void RenderViewImpl::DismissDateTimeDialog() {
DCHECK(date_time_picker_client_);
- date_time_picker_client_.reset(NULL);
+ date_time_picker_client_.reset();
}
bool RenderViewImpl::DidTapMultipleTargets(
@@ -2345,7 +2310,7 @@ bool RenderViewImpl::DidTapMultipleTargets(
RenderThreadImpl::current()->shared_bitmap_manager();
std::unique_ptr<viz::SharedBitmap> shared_bitmap =
manager->AllocateSharedBitmap(canvas_size);
- CHECK(!!shared_bitmap);
+ CHECK(shared_bitmap);
{
SkBitmap bitmap;
SkImageInfo info = SkImageInfo::MakeN32Premul(canvas_size.width(),
@@ -2377,7 +2342,7 @@ bool RenderViewImpl::DidTapMultipleTargets(
GetRoutingID(), physical_window_zoom_rect, canvas_size,
shared_bitmap->id()));
viz::SharedBitmapId id = shared_bitmap->id();
- disambiguation_bitmaps_[id] = shared_bitmap.release();
+ disambiguation_bitmaps_[id] = std::move(shared_bitmap);
handled = true;
break;
}
@@ -2394,13 +2359,13 @@ void RenderViewImpl::SuspendVideoCaptureDevices(bool suspend) {
if (!main_render_frame_)
return;
- MediaStreamDispatcher* media_stream_dispatcher =
- main_render_frame_->GetMediaStreamDispatcher();
- if (!media_stream_dispatcher)
+ MediaStreamDeviceObserver* media_stream_device_observer =
+ main_render_frame_->GetMediaStreamDeviceObserver();
+ if (!media_stream_device_observer)
return;
MediaStreamDevices video_devices =
- media_stream_dispatcher->GetNonScreenCaptureDevices();
+ media_stream_device_observer->GetNonScreenCaptureDevices();
RenderThreadImpl::current()->video_capture_impl_manager()->SuspendDevices(
video_devices, suspend);
#endif // BUILDFLAG(ENABLE_WEBRTC)
@@ -2475,10 +2440,8 @@ void RenderViewImpl::DisableAutoResizeForTesting(const gfx::Size& new_size) {
void RenderViewImpl::OnReleaseDisambiguationPopupBitmap(
const viz::SharedBitmapId& id) {
- BitmapMap::iterator it = disambiguation_bitmaps_.find(id);
- DCHECK(it != disambiguation_bitmaps_.end());
- delete it->second;
- disambiguation_bitmaps_.erase(it);
+ size_t erased_count = disambiguation_bitmaps_.erase(id);
+ DCHECK_EQ(1U, erased_count);
}
void RenderViewImpl::OnResolveTapDisambiguation(double timestamp_seconds,
diff --git a/chromium/content/renderer/render_view_impl.h b/chromium/content/renderer/render_view_impl.h
index 52662032fb7..0c17a24f160 100644
--- a/chromium/content/renderer/render_view_impl.h
+++ b/chromium/content/renderer/render_view_impl.h
@@ -42,6 +42,7 @@
#include "content/renderer/stats_collection_observer.h"
#include "ipc/ipc_platform_file.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
+#include "third_party/WebKit/public/platform/WebScopedVirtualTimePauser.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/web/WebAXObject.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
@@ -72,7 +73,6 @@ class WebDateTimeChooserCompletion;
class WebGestureEvent;
class WebMouseEvent;
class WebSpeechRecognizer;
-class WebStorageNamespace;
class WebTappedInfo;
class WebURLRequest;
struct WebDateTimeChooserParams;
@@ -123,7 +123,7 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
// send an additional IPC to finish making this view visible.
static RenderViewImpl* Create(
CompositorDependencies* compositor_deps,
- const mojom::CreateViewParams& params,
+ mojom::CreateViewParamsPtr params,
const RenderWidget::ShowCallback& show_callback);
// Used by content_layouttest_support to hook into the creation of
@@ -232,6 +232,8 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void UseSynchronousResizeModeForTesting(bool enable);
+ void DidCommitProvisionalHistoryLoad();
+
// Control autoresize mode.
void EnableAutoResizeForTesting(const gfx::Size& min_size,
const gfx::Size& max_size);
@@ -261,7 +263,7 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
const blink::WebFloatSize& accumulatedOverscroll,
const blink::WebFloatPoint& positionInViewport,
const blink::WebFloatSize& velocityInViewport,
- const blink::WebScrollBoundaryBehavior& behavior) override;
+ const blink::WebOverscrollBehavior& behavior) override;
void HasTouchEventHandlers(bool has_handlers) override;
blink::WebScreenInfo GetScreenInfo() override;
void SetToolTipText(const blink::WebString&,
@@ -280,8 +282,8 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
blink::WebNavigationPolicy policy,
bool suppress_opener,
blink::WebSandboxFlags sandbox_flags) override;
- blink::WebWidget* CreatePopupMenu(blink::WebPopupType popup_type) override;
- blink::WebStorageNamespace* CreateSessionStorageNamespace() override;
+ blink::WebWidget* CreatePopup(blink::WebPopupType popup_type) override;
+ int64_t GetSessionStorageNamespaceId() override;
void PrintPage(blink::WebLocalFrame* frame) override;
bool EnumerateChosenDirectory(
const blink::WebString& path,
@@ -290,13 +292,6 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
blink::WebTextDirection main_text_hint,
base::string16* sub_text,
blink::WebTextDirection sub_text_hint);
- void ShowValidationMessage(const blink::WebRect& anchor_in_viewport,
- const blink::WebString& main_text,
- blink::WebTextDirection main_text_hint,
- const blink::WebString& sub_text,
- blink::WebTextDirection hint) override;
- void HideValidationMessage() override;
- void MoveValidationMessage(const blink::WebRect& anchor_in_viewport) override;
void SetMouseOverURL(const blink::WebURL& url) override;
void SetKeyboardFocusURL(const blink::WebURL& url) override;
bool AcceptsLoadDrops() override;
@@ -340,6 +335,7 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
int GetRoutingID() const override;
gfx::Size GetSize() const override;
float GetDeviceScaleFactor() const override;
+ float GetZoomLevel() const override;
const WebPreferences& GetWebkitPreferences() override;
void SetWebkitPreferences(const WebPreferences& preferences) override;
blink::WebView* GetWebView() override;
@@ -373,7 +369,8 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void HandleInputEvent(const blink::WebCoalescedInputEvent& input_event,
const ui::LatencyInfo& latency_info,
HandledEventCallback callback) override;
- void ScrollFocusedEditableNodeIntoRect(const gfx::Rect& rect);
+
+ void UpdateWebViewWithDeviceScaleFactor();
protected:
// RenderWidget overrides:
@@ -391,7 +388,7 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
RenderViewImpl(CompositorDependencies* compositor_deps,
const mojom::CreateViewParams& params);
- void Initialize(const mojom::CreateViewParams& params,
+ void Initialize(mojom::CreateViewParamsPtr params,
const RenderWidget::ShowCallback& show_callback);
void SetScreenMetricsEmulationParameters(
bool enabled,
@@ -437,6 +434,7 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest,
GetCompositionCharacterBoundsTest);
FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, OnNavigationHttpPost);
+ FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, UpdateDSFAfterSwapIn);
FRIEND_TEST_ALL_PREFIXES(RenderViewImplScaleFactorTest,
ScreenMetricsEmulationWithOriginalDSF1);
FRIEND_TEST_ALL_PREFIXES(RenderViewImplScaleFactorTest,
@@ -470,8 +468,6 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
// RenderWidgetOwnerDelegate implementation ----------------------------------
- bool DoesRenderWidgetHaveTouchEventHandlersAt(
- const gfx::Point& point) const override;
bool RenderWidgetWillHandleMouseEvent(
const blink::WebMouseEvent& event) override;
@@ -509,6 +505,12 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void OnEnablePreferredSizeChangedMode();
void OnEnableAutoResize(const gfx::Size& min_size, const gfx::Size& max_size);
void OnDisableAutoResize(const gfx::Size& new_size);
+ void OnSetLocalSurfaceIdForAutoResize(
+ uint64_t sequence_number,
+ const gfx::Size& min_size,
+ const gfx::Size& max_size,
+ const content::ScreenInfo& screen_info,
+ const viz::LocalSurfaceId& local_surface_id);
void OnEnumerateDirectoryResponse(int id,
const std::vector<base::FilePath>& paths);
void OnMediaPlayerActionAt(const gfx::Point& location,
@@ -603,8 +605,6 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void UpdateThemePrefs() {}
#endif
- void UpdateWebViewWithDeviceScaleFactor();
-
// Send the appropriate ack to be able discard this input event message.
void OnDiscardInputEvent(
const blink::WebInputEvent* input_event,
@@ -734,11 +734,6 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
// states for the sizes).
base::OneShotTimer check_preferred_size_timer_;
- // Bookkeeping to suppress redundant scroll and focus requests for an already
- // scrolled and focused editable node.
- bool has_scrolled_focused_editable_node_into_rect_;
- gfx::Rect rect_for_scrolled_focused_editable_node_;
-
// Used to indicate the zoom level to be used during subframe loads, since
// they should match page zoom level.
double page_zoom_level_;
@@ -788,11 +783,13 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
// constructors call the AddObservers method of RenderViewImpl.
std::unique_ptr<StatsCollectionObserver> stats_collection_observer_;
- typedef std::map<viz::SharedBitmapId, viz::SharedBitmap*> BitmapMap;
- BitmapMap disambiguation_bitmaps_;
+ std::map<viz::SharedBitmapId, std::unique_ptr<viz::SharedBitmap>>
+ disambiguation_bitmaps_;
std::unique_ptr<IdleUserDetector> idle_user_detector_;
+ blink::WebScopedVirtualTimePauser history_navigation_virtual_time_pauser_;
+
// ---------------------------------------------------------------------------
// ADDING NEW DATA? Please see if it fits appropriately in one of the above
// sections rather than throwing it randomly at the end. If you're adding a
diff --git a/chromium/content/renderer/render_widget.cc b/chromium/content/renderer/render_widget.cc
index 2d5fe563da6..74df4096a16 100644
--- a/chromium/content/renderer/render_widget.cc
+++ b/chromium/content/renderer/render_widget.cc
@@ -42,7 +42,9 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/context_menu_params.h"
#include "content/public/common/drop_data.h"
+#include "content/public/common/service_names.mojom.h"
#include "content/public/renderer/content_renderer_client.h"
+#include "content/renderer/browser_plugin/browser_plugin_manager.h"
#include "content/renderer/cursor_utils.h"
#include "content/renderer/devtools/render_widget_screen_metrics_emulator.h"
#include "content/renderer/drop_data_builder.h"
@@ -66,6 +68,7 @@
#include "content/renderer/resizing_mode_selector.h"
#include "ipc/ipc_message_start.h"
#include "ipc/ipc_sync_message.h"
+#include "ipc/ipc_sync_message_filter.h"
#include "ppapi/features/features.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/public/platform/FilePathConversion.h"
@@ -297,14 +300,11 @@ WebDragData DropDataToWebDragData(const DropData& drop_data) {
item_list.push_back(item);
}
- for (std::map<base::string16, base::string16>::const_iterator it =
- drop_data.custom_data.begin();
- it != drop_data.custom_data.end();
- ++it) {
+ for (const auto& it : drop_data.custom_data) {
WebDragData::Item item;
item.storage_type = WebDragData::Item::kStorageTypeString;
- item.string_type = WebString::FromUTF16(it->first);
- item.string_data = WebString::FromUTF16(it->second);
+ item.string_type = WebString::FromUTF16(it.first);
+ item.string_data = WebString::FromUTF16(it.second);
item_list.push_back(item);
}
@@ -353,7 +353,7 @@ RenderWidget::RenderWidget(int32_t widget_routing_id,
owner_delegate_(nullptr),
next_paint_flags_(0),
auto_resize_mode_(false),
- need_update_rect_for_auto_resize_(false),
+ need_resize_ack_for_auto_resize_(false),
did_show_(false),
is_hidden_(hidden),
compositor_never_visible_(never_visible),
@@ -403,7 +403,7 @@ RenderWidget::RenderWidget(int32_t widget_routing_id,
}
#if defined(USE_AURA)
RendererWindowTreeClient::CreateIfNecessary(routing_id_);
- if (IsRunningInMash())
+ if (IsRunningWithMus())
RendererWindowTreeClient::Get(routing_id_)->SetVisible(!is_hidden_);
#endif
}
@@ -515,7 +515,7 @@ blink::WebWidget* RenderWidget::CreateWebWidget(RenderWidget* render_widget) {
default:
NOTREACHED();
}
- return NULL;
+ return nullptr;
}
void RenderWidget::CloseForFrame() {
@@ -541,7 +541,7 @@ void RenderWidget::Init(const ShowCallback& show_callback,
DCHECK(!webwidget_internal_);
DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
- input_handler_ = base::MakeUnique<RenderWidgetInputHandler>(this, this);
+ input_handler_ = std::make_unique<RenderWidgetInputHandler>(this, this);
if (base::FeatureList::IsEnabled(features::kMojoInputMessages)) {
RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
@@ -585,8 +585,7 @@ void RenderWidget::SetPopupOriginAdjustmentsForEmulation(
popup_origin_scale_for_emulation_ = emulator->scale();
popup_view_origin_for_emulation_ = emulator->applied_widget_rect().origin();
popup_screen_origin_for_emulation_ =
- gfx::Point(emulator->original_screen_rect().origin().x(),
- emulator->original_screen_rect().origin().y());
+ emulator->original_screen_rect().origin();
screen_info_ = emulator->original_screen_info();
device_scale_factor_ = screen_info_.device_scale_factor;
}
@@ -605,6 +604,30 @@ void RenderWidget::SetExternalPopupOriginAdjustmentsForEmulation(
}
#endif
+void RenderWidget::SetLocalSurfaceIdForAutoResize(
+ uint64_t sequence_number,
+ const content::ScreenInfo& screen_info,
+ const viz::LocalSurfaceId& local_surface_id) {
+ bool screen_info_changed = screen_info_ != screen_info;
+
+ screen_info_ = screen_info;
+ if (device_scale_factor_ != screen_info_.device_scale_factor) {
+ device_scale_factor_ = screen_info_.device_scale_factor;
+ OnDeviceScaleFactorChanged();
+ }
+
+ if (screen_info_changed) {
+ for (auto& observer : render_frame_proxies_)
+ observer.OnScreenInfoChanged(screen_info);
+
+ // Notify all BrowserPlugins of the updated ScreenInfo.
+ if (BrowserPluginManager::Get())
+ BrowserPluginManager::Get()->ScreenInfoChanged(screen_info);
+ }
+
+ AutoResizeCompositor(local_surface_id);
+}
+
void RenderWidget::OnShowHostContextMenu(ContextMenuParams* params) {
if (screen_metrics_emulator_)
screen_metrics_emulator_->OnShowContextMenu(params);
@@ -650,6 +673,8 @@ bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_SetViewportIntersection,
OnSetViewportIntersection)
IPC_MESSAGE_HANDLER(ViewMsg_SetIsInert, OnSetIsInert)
+ IPC_MESSAGE_HANDLER(ViewMsg_UpdateRenderThrottlingStatus,
+ OnUpdateRenderThrottlingStatus)
IPC_MESSAGE_HANDLER(ViewMsg_WaitForNextFrameForTests,
OnWaitNextFrameForTests)
IPC_MESSAGE_HANDLER(InputMsg_RequestCompositionUpdates,
@@ -756,6 +781,8 @@ void RenderWidget::OnClose() {
}
void RenderWidget::OnResize(const ResizeParams& params) {
+ gfx::Size old_visible_viewport_size = visible_viewport_size_;
+
if (resizing_mode_selector_->ShouldAbortOnResize(this, params))
return;
@@ -765,19 +792,28 @@ void RenderWidget::OnResize(const ResizeParams& params) {
}
Resize(params);
+
+ if (old_visible_viewport_size != visible_viewport_size_) {
+ for (auto& render_frame : render_frames_)
+ render_frame.DidChangeVisibleViewport();
+ }
}
void RenderWidget::OnSetLocalSurfaceIdForAutoResize(
uint64_t sequence_number,
+ const gfx::Size& min_size,
+ const gfx::Size& max_size,
+ const content::ScreenInfo& screen_info,
const viz::LocalSurfaceId& local_surface_id) {
if (!auto_resize_mode_ || resize_or_repaint_ack_num_ != sequence_number)
return;
- local_surface_id_ = local_surface_id;
- compositor_->SetViewportSize(physical_backing_size_, local_surface_id);
+
+ SetLocalSurfaceIdForAutoResize(sequence_number, screen_info,
+ local_surface_id);
}
void RenderWidget::OnEnableDeviceEmulation(
- const blink::WebDeviceEmulationParams& params) {
+ const blink::WebDeviceEmulationParams& params) {
if (!screen_metrics_emulator_) {
ResizeParams resize_params;
resize_params.screen_info = screen_info_;
@@ -859,6 +895,10 @@ void RenderWidget::OnHandleInputEvent(
latency_info, std::move(callback));
}
+int RenderWidget::GetWidgetRoutingIdAtPoint(const gfx::Point& point) {
+ return input_handler_->GetWidgetRoutingIdAtPoint(point);
+}
+
void RenderWidget::HandleInputEvent(
const blink::WebCoalescedInputEvent& input_event,
const ui::LatencyInfo& latency_info,
@@ -947,15 +987,14 @@ void RenderWidget::BeginMainFrame(double frame_time_sec) {
}
void RenderWidget::RequestNewLayerTreeFrameSink(
- bool fallback,
const LayerTreeFrameSinkCallback& callback) {
DCHECK(GetWebWidget());
// For widgets that are never visible, we don't start the compositor, so we
// never get a request for a cc::LayerTreeFrameSink.
DCHECK(!compositor_never_visible_);
RenderThreadImpl::current()->RequestNewLayerTreeFrameSink(
- fallback, routing_id_, frame_swap_message_queue_,
- GetURLForGraphicsContext3D(), callback);
+ routing_id_, frame_swap_message_queue_, GetURLForGraphicsContext3D(),
+ callback);
}
void RenderWidget::DidCommitAndDrawCompositorFrame() {
@@ -1054,13 +1093,6 @@ void RenderWidget::FocusChangeComplete() {
focused->AutofillClient()->DidCompleteFocusChangeInFrame();
}
-bool RenderWidget::HasTouchEventHandlersAt(const gfx::Point& point) const {
- if (owner_delegate_)
- return owner_delegate_->DoesRenderWidgetHaveTouchEventHandlersAt(point);
-
- return true;
-}
-
void RenderWidget::ObserveGestureEventAndResult(
const blink::WebGestureEvent& gesture_event,
const gfx::Vector2dF& unused_delta,
@@ -1075,7 +1107,7 @@ void RenderWidget::ObserveGestureEventAndResult(
RenderThreadImpl* render_thread = RenderThreadImpl::current();
InputHandlerManager* input_handler_manager =
- render_thread ? render_thread->input_handler_manager() : NULL;
+ render_thread ? render_thread->input_handler_manager() : nullptr;
if (input_handler_manager) {
input_handler_manager->ObserveGestureEventAndResultOnMainThread(
routing_id_, gesture_event, scroll_result);
@@ -1101,9 +1133,10 @@ void RenderWidget::ClearEditCommands() {
void RenderWidget::OnDidOverscroll(const ui::DidOverscrollParams& params) {
if (widget_input_handler_manager_) {
- WidgetInputHandlerManager::WidgetInputHandlerHost host =
- widget_input_handler_manager_->GetWidgetInputHandlerHost();
- (*host)->DidOverscroll(params);
+ if (mojom::WidgetInputHandlerHost* host =
+ widget_input_handler_manager_->GetWidgetInputHandlerHost()) {
+ host->DidOverscroll(params);
+ }
} else {
Send(new InputHostMsg_DidOverscroll(routing_id_, params));
}
@@ -1257,6 +1290,8 @@ void RenderWidget::Resize(const ResizeParams& params) {
screen_info_.orientation_angle != params.screen_info.orientation_angle ||
screen_info_.orientation_type != params.screen_info.orientation_type;
+ bool screen_info_changed = screen_info_ != params.screen_info;
+
screen_info_ = params.screen_info;
if (device_scale_factor_ != screen_info_.device_scale_factor) {
@@ -1283,10 +1318,8 @@ void RenderWidget::Resize(const ResizeParams& params) {
// If the ID is not valid, then the compositor will defer commits until
// it receives a valid surface ID. This is a no-op if surface
// synchronization is disabled.
- // TODO(crbug.com/758387): Re-enable this DCHECK once the mash login screen
- // is fixed.
- // DCHECK(!compositor_->IsSurfaceSynchronizationEnabled() ||
- // local_surface_id_.is_valid());
+ DCHECK(!compositor_->IsSurfaceSynchronizationEnabled() ||
+ !params.needs_resize_ack || local_surface_id_.is_valid());
compositor_->SetViewportSize(params.physical_backing_size,
local_surface_id_);
compositor_->SetBrowserControlsHeight(
@@ -1342,6 +1375,15 @@ void RenderWidget::Resize(const ResizeParams& params) {
if (orientation_changed)
OnOrientationChange();
+ if (screen_info_changed) {
+ for (auto& observer : render_frame_proxies_)
+ observer.OnScreenInfoChanged(params.screen_info);
+
+ // Notify all BrowserPlugins of the updated ScreenInfo.
+ if (BrowserPluginManager::Get())
+ BrowserPluginManager::Get()->ScreenInfoChanged(params.screen_info);
+ }
+
// If a resize ack is requested and it isn't set-up, then no more resizes will
// come in and in general things will go wrong.
DCHECK(!params.needs_resize_ack || next_paint_is_resize_ack());
@@ -1363,11 +1405,10 @@ void RenderWidget::SetScreenRects(const gfx::Rect& view_screen_rect,
///////////////////////////////////////////////////////////////////////////////
// WebWidgetClient
-void RenderWidget::AutoResizeCompositor() {
+void RenderWidget::AutoResizeCompositor(
+ const viz::LocalSurfaceId& local_surface_id) {
physical_backing_size_ = gfx::ScaleToCeiledSize(size_, device_scale_factor_);
- // A new LocalSurfaceId will need to be allocated by the browser for the new
- // size.
- local_surface_id_ = viz::LocalSurfaceId();
+ local_surface_id_ = local_surface_id;
if (compositor_)
compositor_->SetViewportSize(physical_backing_size_, local_surface_id_);
}
@@ -1420,6 +1461,8 @@ blink::WebLayerTreeView* RenderWidget::InitializeLayerTreeView() {
}
}
+ UpdateURLForCompositorUkm();
+
return compositor_.get();
}
@@ -1696,9 +1739,10 @@ void RenderWidget::OnImeSetComposition(
// process to cancel the input method's ongoing composition session, to make
// sure we are in a consistent state.
if (widget_input_handler_manager_) {
- WidgetInputHandlerManager::WidgetInputHandlerHost host =
- widget_input_handler_manager_->GetWidgetInputHandlerHost();
- (*host)->ImeCancelComposition();
+ if (mojom::WidgetInputHandlerHost* host =
+ widget_input_handler_manager_->GetWidgetInputHandlerHost()) {
+ host->ImeCancelComposition();
+ }
} else {
Send(new InputHostMsg_ImeCancelComposition(routing_id()));
}
@@ -1785,9 +1829,8 @@ void RenderWidget::OnRepaint(gfx::Size size_to_paint) {
}
void RenderWidget::OnSetTextDirection(WebTextDirection direction) {
- if (!GetWebWidget())
- return;
- GetWebWidget()->SetTextDirection(direction);
+ if (auto* frame = GetFocusedWebLocalFrameInWidget())
+ frame->SetTextDirection(direction);
}
void RenderWidget::OnUpdateScreenRects(const gfx::Rect& view_screen_rect,
@@ -1811,24 +1854,36 @@ void RenderWidget::OnUpdateWindowScreenRect(
void RenderWidget::OnSetViewportIntersection(
const gfx::Rect& viewport_intersection) {
- if (GetWebWidget() && GetWebWidget()->IsWebFrameWidget()) {
- DCHECK(popup_type_ == WebPopupType::kWebPopupTypeNone);
+ if (GetWebWidget()) {
+ DCHECK(GetWebWidget()->IsWebFrameWidget());
+ DCHECK_EQ(popup_type_, WebPopupType::kWebPopupTypeNone);
static_cast<WebFrameWidget*>(GetWebWidget())
->SetRemoteViewportIntersection(viewport_intersection);
}
}
void RenderWidget::OnSetIsInert(bool inert) {
- if (GetWebWidget() && GetWebWidget()->IsWebFrameWidget()) {
- DCHECK(popup_type_ == WebPopupType::kWebPopupTypeNone);
+ if (GetWebWidget()) {
+ DCHECK(GetWebWidget()->IsWebFrameWidget());
+ DCHECK_EQ(popup_type_, WebPopupType::kWebPopupTypeNone);
static_cast<WebFrameWidget*>(GetWebWidget())->SetIsInert(inert);
}
}
+void RenderWidget::OnUpdateRenderThrottlingStatus(bool is_throttled,
+ bool subtree_throttled) {
+ if (GetWebWidget()) {
+ DCHECK(GetWebWidget()->IsWebFrameWidget());
+ DCHECK_EQ(popup_type_, WebPopupType::kWebPopupTypeNone);
+ static_cast<WebFrameWidget*>(GetWebWidget())
+ ->UpdateRenderThrottlingStatus(is_throttled, subtree_throttled);
+ }
+}
+
void RenderWidget::OnDragTargetDragEnter(
const std::vector<DropData::Metadata>& drop_meta_data,
- const gfx::Point& client_point,
- const gfx::Point& screen_point,
+ const gfx::PointF& client_point,
+ const gfx::PointF& screen_point,
WebDragOperationsMask ops,
int key_modifiers) {
if (!GetWebWidget())
@@ -1843,8 +1898,8 @@ void RenderWidget::OnDragTargetDragEnter(
Send(new DragHostMsg_UpdateDragCursor(routing_id(), operation));
}
-void RenderWidget::OnDragTargetDragOver(const gfx::Point& client_point,
- const gfx::Point& screen_point,
+void RenderWidget::OnDragTargetDragOver(const gfx::PointF& client_point,
+ const gfx::PointF& screen_point,
WebDragOperationsMask ops,
int key_modifiers) {
if (!GetWebWidget())
@@ -1859,8 +1914,8 @@ void RenderWidget::OnDragTargetDragOver(const gfx::Point& client_point,
Send(new DragHostMsg_UpdateDragCursor(routing_id(), operation));
}
-void RenderWidget::OnDragTargetDragLeave(const gfx::Point& client_point,
- const gfx::Point& screen_point) {
+void RenderWidget::OnDragTargetDragLeave(const gfx::PointF& client_point,
+ const gfx::PointF& screen_point) {
if (!GetWebWidget())
return;
DCHECK(GetWebWidget()->IsWebFrameWidget());
@@ -1870,8 +1925,8 @@ void RenderWidget::OnDragTargetDragLeave(const gfx::Point& client_point,
}
void RenderWidget::OnDragTargetDrop(const DropData& drop_data,
- const gfx::Point& client_point,
- const gfx::Point& screen_point,
+ const gfx::PointF& client_point,
+ const gfx::PointF& screen_point,
int key_modifiers) {
if (!GetWebWidget())
return;
@@ -1883,8 +1938,8 @@ void RenderWidget::OnDragTargetDrop(const DropData& drop_data,
key_modifiers);
}
-void RenderWidget::OnDragSourceEnded(const gfx::Point& client_point,
- const gfx::Point& screen_point,
+void RenderWidget::OnDragSourceEnded(const gfx::PointF& client_point,
+ const gfx::PointF& screen_point,
WebDragOperation op) {
if (!GetWebWidget())
return;
@@ -1951,10 +2006,11 @@ void RenderWidget::UpdateCompositionInfo(bool immediate_request) {
composition_character_bounds_ = character_bounds;
composition_range_ = range;
if (widget_input_handler_manager_) {
- WidgetInputHandlerManager::WidgetInputHandlerHost host =
- widget_input_handler_manager_->GetWidgetInputHandlerHost();
- (*host)->ImeCompositionRangeChanged(composition_range_,
- composition_character_bounds_);
+ if (mojom::WidgetInputHandlerHost* host =
+ widget_input_handler_manager_->GetWidgetInputHandlerHost()) {
+ host->ImeCompositionRangeChanged(composition_range_,
+ composition_character_bounds_);
+ }
} else {
Send(new InputHostMsg_ImeCompositionRangeChanged(
routing_id(), composition_range_, composition_character_bounds_));
@@ -2009,15 +2065,6 @@ void RenderWidget::OnRequestCompositionUpdates(bool immediate_request,
UpdateCompositionInfo(true /* immediate request */);
}
-void RenderWidget::OnSetDeviceScaleFactor(float device_scale_factor) {
- if (device_scale_factor_ == device_scale_factor)
- return;
-
- device_scale_factor_ = device_scale_factor;
- OnDeviceScaleFactorChanged();
- physical_backing_size_ = gfx::ScaleToCeiledSize(size_, device_scale_factor_);
-}
-
void RenderWidget::OnOrientationChange() {
WebWidget* web_widget = GetWebWidget();
if (web_widget && web_widget->IsWebFrameWidget()) {
@@ -2042,15 +2089,16 @@ void RenderWidget::SetHidden(bool hidden) {
is_hidden_ = hidden;
#if defined(USE_AURA)
- if (IsRunningInMash())
+ if (IsRunningWithMus())
RendererWindowTreeClient::Get(routing_id_)->SetVisible(!hidden);
#endif
if (is_hidden_) {
RenderThreadImpl::current()->WidgetHidden();
first_update_visual_state_after_hidden_ = true;
- } else
+ } else {
RenderThreadImpl::current()->WidgetRestored();
+ }
if (render_widget_scheduling_state_)
render_widget_scheduling_state_->SetHidden(hidden);
@@ -2149,14 +2197,17 @@ void RenderWidget::UpdateSelectionBounds() {
#endif
if (send_ipc) {
ViewHostMsg_SelectionBounds_Params params;
+ params.is_anchor_first = false;
GetSelectionBounds(&params.anchor_rect, &params.focus_rect);
if (selection_anchor_rect_ != params.anchor_rect ||
selection_focus_rect_ != params.focus_rect) {
selection_anchor_rect_ = params.anchor_rect;
selection_focus_rect_ = params.focus_rect;
- GetWebWidget()->SelectionTextDirection(params.focus_dir,
- params.anchor_dir);
- params.is_anchor_first = GetWebWidget()->IsSelectionAnchorFirst();
+ if (auto* focused_frame = GetFocusedWebLocalFrameInWidget()) {
+ focused_frame->SelectionTextDirection(params.focus_dir,
+ params.anchor_dir);
+ params.is_anchor_first = focused_frame->IsSelectionAnchorFirst();
+ }
Send(new ViewHostMsg_SelectionBoundsChanged(routing_id_, params));
}
}
@@ -2178,10 +2229,10 @@ void RenderWidget::DidAutoResize(const gfx::Size& new_size) {
window_screen_rect_ = new_pos;
}
- AutoResizeCompositor();
+ AutoResizeCompositor(viz::LocalSurfaceId());
if (!resizing_mode_selector_->is_synchronous_mode()) {
- need_update_rect_for_auto_resize_ = true;
+ need_resize_ack_for_auto_resize_ = true;
// If surface synchronization is off, then ResizeAcks go to the browser in
// response to a DidReceiveCompositorFrame. With surface synchronization
// on, that notification will not arrive here because the compositor is
@@ -2221,7 +2272,8 @@ void RenderWidget::GetCompositionRange(gfx::Range* range) {
if (GetFocusedPepperPluginInsideWidget())
return;
#endif
- WebRange web_range = GetWebWidget()->CompositionRange();
+ blink::WebInputMethodController* controller = GetInputMethodController();
+ WebRange web_range = controller ? controller->CompositionRange() : WebRange();
if (web_range.IsNull()) {
*range = gfx::Range::InvalidRange();
return;
@@ -2285,6 +2337,7 @@ blink::WebScreenInfo RenderWidget::GetScreenInfo() {
break;
}
web_screen_info.orientation_angle = screen_info_.orientation_angle;
+
return web_screen_info;
}
@@ -2343,7 +2396,7 @@ void RenderWidget::DidOverscroll(
const blink::WebFloatSize& accumulatedOverscroll,
const blink::WebFloatPoint& position,
const blink::WebFloatSize& velocity,
- const blink::WebScrollBoundaryBehavior& behavior) {
+ const blink::WebOverscrollBehavior& behavior) {
#if defined(OS_MACOSX)
// On OSX the user can disable the elastic overscroll effect. If that's the
// case, don't forward the overscroll notification.
@@ -2379,6 +2432,11 @@ void RenderWidget::SetNeedsLowLatencyInput(bool needs_low_latency) {
input_event_queue_->SetNeedsLowLatency(needs_low_latency);
}
+void RenderWidget::RequestUnbufferedInputEvents() {
+ if (input_event_queue_)
+ input_event_queue_->RequestUnbufferedInputEvents();
+}
+
void RenderWidget::SetTouchAction(cc::TouchAction touch_action) {
if (!input_handler_->ProcessTouchAction(touch_action))
return;
@@ -2418,11 +2476,15 @@ float RenderWidget::GetOriginalDeviceScaleFactor() const {
device_scale_factor_;
}
-gfx::Point RenderWidget::ConvertWindowPointToViewport(
- const gfx::Point& point) {
+gfx::PointF RenderWidget::ConvertWindowPointToViewport(
+ const gfx::PointF& point) {
blink::WebFloatRect point_in_viewport(point.x(), point.y(), 0, 0);
ConvertWindowToViewport(&point_in_viewport);
- return gfx::Point(point_in_viewport.x, point_in_viewport.y);
+ return gfx::PointF(point_in_viewport.x, point_in_viewport.y);
+}
+
+gfx::Point RenderWidget::ConvertWindowPointToViewport(const gfx::Point& point) {
+ return gfx::ToRoundedPoint(ConvertWindowPointToViewport(gfx::PointF(point)));
}
bool RenderWidget::RequestPointerLock() {
@@ -2483,8 +2545,8 @@ blink::WebInputMethodController* RenderWidget::GetInputMethodController()
void RenderWidget::SetupWidgetInputHandler(
mojom::WidgetInputHandlerRequest request,
mojom::WidgetInputHandlerHostPtr host) {
- widget_input_handler_manager_->AddInterface(std::move(request));
- widget_input_handler_manager_->SetWidgetInputHandlerHost(std::move(host));
+ widget_input_handler_manager_->AddInterface(std::move(request),
+ std::move(host));
}
void RenderWidget::SetWidgetBinding(mojom::WidgetRequest request) {
@@ -2495,7 +2557,7 @@ void RenderWidget::SetWidgetBinding(mojom::WidgetRequest request) {
}
void RenderWidget::DidResizeOrRepaintAck() {
- if (!next_paint_flags_ && !need_update_rect_for_auto_resize_)
+ if (!next_paint_flags_ && !need_resize_ack_for_auto_resize_)
return;
ViewHostMsg_ResizeOrRepaint_ACK_Params params;
@@ -2505,7 +2567,28 @@ void RenderWidget::DidResizeOrRepaintAck() {
Send(new ViewHostMsg_ResizeOrRepaint_ACK(routing_id_, params));
next_paint_flags_ = 0;
- need_update_rect_for_auto_resize_ = false;
+ need_resize_ack_for_auto_resize_ = false;
+}
+
+void RenderWidget::UpdateURLForCompositorUkm() {
+ DCHECK(compositor_);
+
+ if (!GetWebWidget() || !GetWebWidget()->IsWebFrameWidget())
+ return;
+
+ auto* render_frame = RenderFrameImpl::FromWebFrame(
+ static_cast<blink::WebFrameWidget*>(GetWebWidget())->LocalRoot());
+ if (!render_frame->IsMainFrame())
+ return;
+
+ compositor_->SetURLForUkm(render_frame->GetWebFrame()->GetDocument().Url());
+}
+
+blink::WebLocalFrame* RenderWidget::GetFocusedWebLocalFrameInWidget() const {
+ if (!GetWebWidget() || !GetWebWidget()->IsWebFrameWidget())
+ return nullptr;
+ return static_cast<blink::WebFrameWidget*>(GetWebWidget())
+ ->FocusedWebLocalFrameInWidget();
}
#if BUILDFLAG(ENABLE_PLUGINS)
diff --git a/chromium/content/renderer/render_widget.h b/chromium/content/renderer/render_widget.h
index bad68cf6947..de2b24cfa30 100644
--- a/chromium/content/renderer/render_widget.h
+++ b/chromium/content/renderer/render_widget.h
@@ -245,7 +245,6 @@ class CONTENT_EXPORT RenderWidget
bool has_scrolled_by_touch) override;
void BeginMainFrame(double frame_time_sec) override;
void RequestNewLayerTreeFrameSink(
- bool fallback,
const LayerTreeFrameSinkCallback& callback) override;
void DidCommitAndDrawCompositorFrame() override;
void DidCommitCompositorFrame() override;
@@ -260,7 +259,6 @@ class CONTENT_EXPORT RenderWidget
// RenderWidgetInputHandlerDelegate
void FocusChangeComplete() override;
- bool HasTouchEventHandlersAt(const gfx::Point& point) const override;
void ObserveGestureEventAndResult(const blink::WebGestureEvent& gesture_event,
const gfx::Vector2dF& unused_delta,
bool event_processed) override;
@@ -304,7 +302,7 @@ class CONTENT_EXPORT RenderWidget
const blink::WebFloatSize& accumulatedOverscroll,
const blink::WebFloatPoint& position,
const blink::WebFloatSize& velocity,
- const blink::WebScrollBoundaryBehavior& behavior) override;
+ const blink::WebOverscrollBehavior& behavior) override;
void ShowVirtualKeyboardOnElementFocus() override;
void ConvertViewportToWindow(blink::WebRect* rect) override;
void ConvertWindowToViewport(blink::WebFloatRect* rect) override;
@@ -399,6 +397,7 @@ class CONTENT_EXPORT RenderWidget
float GetOriginalDeviceScaleFactor() const;
// Helper to convert |point| using ConvertWindowToViewport().
+ gfx::PointF ConvertWindowPointToViewport(const gfx::PointF& point);
gfx::Point ConvertWindowPointToViewport(const gfx::Point& point);
void TransferActiveWheelFlingAnimation(
@@ -412,6 +411,8 @@ class CONTENT_EXPORT RenderWidget
// Requests a BeginMainFrame callback from the compositor.
void SetNeedsMainFrame() override;
+ int GetWidgetRoutingIdAtPoint(const gfx::Point& point);
+
void HandleInputEvent(const blink::WebCoalescedInputEvent& input_event,
const ui::LatencyInfo& latency_info,
HandledEventCallback callback) override;
@@ -516,6 +517,11 @@ class CONTENT_EXPORT RenderWidget
RenderWidgetScreenMetricsEmulator* emulator);
#endif
+ void SetLocalSurfaceIdForAutoResize(
+ uint64_t sequence_number,
+ const content::ScreenInfo& screen_info,
+ const viz::LocalSurfaceId& local_surface_id);
+
// RenderWidget IPC message handlers
void OnHandleInputEvent(
const blink::WebInputEvent* event,
@@ -527,6 +533,9 @@ class CONTENT_EXPORT RenderWidget
virtual void OnResize(const ResizeParams& params);
void OnSetLocalSurfaceIdForAutoResize(
uint64_t sequence_number,
+ const gfx::Size& min_size,
+ const gfx::Size& max_size,
+ const content::ScreenInfo& screen_info,
const viz::LocalSurfaceId& local_surface_id);
void OnEnableDeviceEmulation(const blink::WebDeviceEmulationParams& params);
void OnDisableDeviceEmulation();
@@ -551,34 +560,34 @@ class CONTENT_EXPORT RenderWidget
void OnUpdateWindowScreenRect(const gfx::Rect& window_screen_rect);
void OnSetViewportIntersection(const gfx::Rect& viewport_intersection);
void OnSetIsInert(bool);
+ void OnUpdateRenderThrottlingStatus(bool is_throttled,
+ bool subtree_throttled);
// Real data that is dragged is not included at DragEnter time.
void OnDragTargetDragEnter(
const std::vector<DropData::Metadata>& drop_meta_data,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
blink::WebDragOperationsMask operations_allowed,
int key_modifiers);
- void OnDragTargetDragOver(const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ void OnDragTargetDragOver(const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
blink::WebDragOperationsMask operations_allowed,
int key_modifiers);
- void OnDragTargetDragLeave(const gfx::Point& client_point,
- const gfx::Point& screen_point);
+ void OnDragTargetDragLeave(const gfx::PointF& client_point,
+ const gfx::PointF& screen_point);
void OnDragTargetDrop(const DropData& drop_data,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
+ const gfx::PointF& client_pt,
+ const gfx::PointF& screen_pt,
int key_modifiers);
- void OnDragSourceEnded(const gfx::Point& client_point,
- const gfx::Point& screen_point,
+ void OnDragSourceEnded(const gfx::PointF& client_point,
+ const gfx::PointF& screen_point,
blink::WebDragOperation drag_operation);
void OnDragSourceSystemDragEnded();
// Notify the compositor about a change in viewport size. This should be
// used only with auto resize mode WebWidgets, as normal WebWidgets should
// go through OnResize.
- void AutoResizeCompositor();
-
- virtual void OnSetDeviceScaleFactor(float device_scale_factor);
+ void AutoResizeCompositor(const viz::LocalSurfaceId& local_surface_id);
void OnOrientationChange();
@@ -644,6 +653,10 @@ class CONTENT_EXPORT RenderWidget
// Called to update whether low latency input mode is enabled or not.
void SetNeedsLowLatencyInput(bool) override;
+ // Requests unbuffered (ie. low latency) input until a pointerup
+ // event occurs.
+ void RequestUnbufferedInputEvents() override;
+
// Tell the browser about the actions permitted for a new touch point.
void SetTouchAction(cc::TouchAction touch_action) override;
@@ -692,9 +705,9 @@ class CONTENT_EXPORT RenderWidget
// by extension popups.
bool auto_resize_mode_;
- // True if we need to send an UpdateRect message to notify the browser about
- // an already-completed auto-resize.
- bool need_update_rect_for_auto_resize_;
+ // True if we need to send a ViewHsotMsg_ResizeOrRepaint_ACK message to notify
+ // the browser about an already-completed auto-resize.
+ bool need_resize_ack_for_auto_resize_;
// The sequence number used for ViewHostMsg_UpdateRect.
uint64_t resize_or_repaint_ack_num_ = 0;
@@ -867,6 +880,16 @@ 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;
+
// Indicates whether this widget has focus.
bool has_focus_;
diff --git a/chromium/content/renderer/render_widget_browsertest.cc b/chromium/content/renderer/render_widget_browsertest.cc
index 7d4cc20603a..44f4dcf91e3 100644
--- a/chromium/content/renderer/render_widget_browsertest.cc
+++ b/chromium/content/renderer/render_widget_browsertest.cc
@@ -4,11 +4,13 @@
#include "base/strings/utf_string_conversions.h"
#include "content/common/resize_params.h"
+#include "content/public/renderer/render_frame_visitor.h"
#include "content/public/test/render_view_test.h"
#include "content/renderer/render_view_impl.h"
#include "content/renderer/render_widget.h"
#include "third_party/WebKit/public/web/WebFrameWidget.h"
#include "third_party/WebKit/public/web/WebInputMethodController.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebRange.h"
#include "ui/base/ime/text_input_type.h"
@@ -123,6 +125,21 @@ TEST_F(RenderWidgetInitialSizeTest, InitialSize) {
EXPECT_TRUE(next_paint_is_resize_ack());
}
+TEST_F(RenderWidgetTest, HitTestAPI) {
+ LoadHTML(
+ "<body style='padding: 0px; margin: 0px'>"
+ "<div style='background: green; padding: 100px; margin: 0px;'>"
+ "<iframe style='width: 200px; height: 100px;'"
+ "srcdoc='<body style=\"margin: 0px; height: 100px; width: 200px;\">"
+ "</body>'></iframe><div></body>");
+ blink::WebFrame* main_web_frame =
+ static_cast<RenderViewImpl*>(view_)->GetMainRenderFrame()->GetWebFrame();
+ EXPECT_EQ(RenderFrame::GetRoutingIdForWebFrame(main_web_frame),
+ widget()->GetWidgetRoutingIdAtPoint(gfx::Point(10, 10)));
+ EXPECT_EQ(RenderFrame::GetRoutingIdForWebFrame(main_web_frame->FirstChild()),
+ widget()->GetWidgetRoutingIdAtPoint(gfx::Point(150, 150)));
+}
+
TEST_F(RenderWidgetTest, GetCompositionRangeValidComposition) {
LoadHTML(
"<div contenteditable>EDITABLE</div>"
diff --git a/chromium/content/renderer/render_widget_fullscreen_pepper.cc b/chromium/content/renderer/render_widget_fullscreen_pepper.cc
index 42061369aca..002c3ac7da1 100644
--- a/chromium/content/renderer/render_widget_fullscreen_pepper.cc
+++ b/chromium/content/renderer/render_widget_fullscreen_pepper.cc
@@ -283,7 +283,7 @@ RenderWidgetFullscreenPepper::RenderWidgetFullscreenPepper(
std::move(widget_request)),
active_url_(active_url),
plugin_(plugin),
- layer_(NULL),
+ layer_(nullptr),
mouse_lock_dispatcher_(new FullscreenMouseLockDispatcher(this)) {}
RenderWidgetFullscreenPepper::~RenderWidgetFullscreenPepper() {
@@ -304,12 +304,12 @@ void RenderWidgetFullscreenPepper::ScrollRect(
void RenderWidgetFullscreenPepper::Destroy() {
// This function is called by the plugin instance as it's going away, so reset
// plugin_ to NULL to avoid calling into a dangling pointer e.g. on Close().
- plugin_ = NULL;
+ plugin_ = nullptr;
// After calling Destroy(), the plugin instance assumes that the layer is not
// used by us anymore, so it may destroy the layer before this object goes
// away.
- SetLayer(NULL);
+ SetLayer(nullptr);
Send(new ViewHostMsg_Close(routing_id_));
Release();
diff --git a/chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc b/chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc
index 20cc0ca5590..1aac9927d0a 100644
--- a/chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc
+++ b/chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc
@@ -12,8 +12,6 @@
#include "third_party/WebKit/public/web/WebView.h"
#include "third_party/WebKit/public/web/WebWidget.h"
-using blink::WebUserGestureIndicator;
-
namespace content {
RenderWidgetMouseLockDispatcher::RenderWidgetMouseLockDispatcher(
@@ -23,8 +21,14 @@ RenderWidgetMouseLockDispatcher::RenderWidgetMouseLockDispatcher(
RenderWidgetMouseLockDispatcher::~RenderWidgetMouseLockDispatcher() {}
void RenderWidgetMouseLockDispatcher::SendLockMouseRequest() {
- bool user_gesture = WebUserGestureIndicator::IsProcessingUserGesture();
+ blink::WebWidget* web_widget = render_widget_->GetWebWidget();
+ blink::WebLocalFrame* web_local_frame =
+ (web_widget && web_widget->IsWebFrameWidget())
+ ? static_cast<blink::WebFrameWidget*>(web_widget)->LocalRoot()
+ : nullptr;
+ bool user_gesture =
+ blink::WebUserGestureIndicator::IsProcessingUserGesture(web_local_frame);
render_widget_->Send(new ViewHostMsg_LockMouse(render_widget_->routing_id(),
user_gesture, false));
}
diff --git a/chromium/content/renderer/render_widget_owner_delegate.h b/chromium/content/renderer/render_widget_owner_delegate.h
index ac43a7b1002..22f573c9a7f 100644
--- a/chromium/content/renderer/render_widget_owner_delegate.h
+++ b/chromium/content/renderer/render_widget_owner_delegate.h
@@ -11,10 +11,6 @@ namespace blink {
class WebMouseEvent;
}
-namespace gfx {
-class Point;
-}
-
namespace content {
//
@@ -26,8 +22,6 @@ namespace content {
class CONTENT_EXPORT RenderWidgetOwnerDelegate {
public:
// As in RenderWidgetInputHandlerDelegate.
- virtual bool DoesRenderWidgetHaveTouchEventHandlersAt(
- const gfx::Point& point) const = 0;
virtual bool RenderWidgetWillHandleMouseEvent(
const blink::WebMouseEvent& event) = 0;
diff --git a/chromium/content/renderer/render_widget_unittest.cc b/chromium/content/renderer/render_widget_unittest.cc
index 73941aa0259..656b80c6ebb 100644
--- a/chromium/content/renderer/render_widget_unittest.cc
+++ b/chromium/content/renderer/render_widget_unittest.cc
@@ -8,14 +8,19 @@
#include <vector>
#include "base/macros.h"
+#include "base/optional.h"
+#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
+#include "content/common/input/input_handler.mojom.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/common/input_messages.h"
#include "content/common/resize_params.h"
#include "content/public/common/content_features.h"
#include "content/public/test/mock_render_thread.h"
#include "content/renderer/devtools/render_widget_screen_metrics_emulator.h"
+#include "content/renderer/input/widget_input_handler_manager.h"
#include "content/test/fake_compositor_dependencies.h"
#include "content/test/mock_render_process.h"
#include "ipc/ipc_test_sink.h"
@@ -29,6 +34,19 @@
using testing::_;
+namespace ui {
+
+bool operator==(const ui::DidOverscrollParams& lhs,
+ const ui::DidOverscrollParams& rhs) {
+ return lhs.accumulated_overscroll == rhs.accumulated_overscroll &&
+ lhs.latest_overscroll_delta == rhs.latest_overscroll_delta &&
+ lhs.current_fling_velocity == rhs.current_fling_velocity &&
+ lhs.causal_event_viewport_point == rhs.causal_event_viewport_point &&
+ lhs.overscroll_behavior == rhs.overscroll_behavior;
+}
+
+} // namespace ui
+
namespace content {
namespace {
@@ -48,12 +66,57 @@ enum {
PASSIVE_LISTENER_UMA_ENUM_COUNT
};
-bool ShouldBlockEventStream(const blink::WebInputEvent& event) {
- return ui::WebInputEventTraits::ShouldBlockEventStream(
- event,
- base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents),
- base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching));
-}
+class MockWidgetInputHandlerHost : public mojom::WidgetInputHandlerHost {
+ public:
+ MockWidgetInputHandlerHost(
+ mojo::InterfaceRequest<mojom::WidgetInputHandlerHost> request)
+ : binding_(this, std::move(request)) {}
+ MOCK_METHOD0(CancelTouchTimeout, void());
+
+ MOCK_METHOD3(SetWhiteListedTouchAction,
+ void(cc::TouchAction, uint32_t, content::InputEventAckState));
+
+ MOCK_METHOD1(DidOverscroll, void(const ui::DidOverscrollParams&));
+
+ MOCK_METHOD0(DidStopFlinging, void());
+
+ MOCK_METHOD0(ImeCancelComposition, void());
+
+ MOCK_METHOD2(ImeCompositionRangeChanged,
+ void(const gfx::Range&, const std::vector<gfx::Rect>&));
+
+ private:
+ mojo::Binding<mojom::WidgetInputHandlerHost> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockWidgetInputHandlerHost);
+};
+
+// Since std::unique_ptr isn't copyable we can't use the
+// MockCallback template.
+class MockHandledEventCallback {
+ public:
+ MockHandledEventCallback() = default;
+ MOCK_METHOD4_T(Run,
+ void(InputEventAckState,
+ const ui::LatencyInfo&,
+ std::unique_ptr<ui::DidOverscrollParams>&,
+ base::Optional<cc::TouchAction>));
+
+ HandledEventCallback GetCallback() {
+ return BindOnce(&MockHandledEventCallback::HandleCallback,
+ base::Unretained(this));
+ }
+
+ private:
+ void HandleCallback(InputEventAckState ack_state,
+ const ui::LatencyInfo& latency_info,
+ std::unique_ptr<ui::DidOverscrollParams> overscroll,
+ base::Optional<cc::TouchAction> touch_action) {
+ Run(ack_state, latency_info, overscroll, touch_action);
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(MockHandledEventCallback);
+};
class MockWebWidget : public blink::WebWidget {
public:
@@ -76,18 +139,20 @@ class InteractiveRenderWidget : public RenderWidget {
false),
always_overscroll_(false) {
Init(RenderWidget::ShowCallback(), mock_webwidget());
- }
- void SetTouchRegion(const std::vector<gfx::Rect>& rects) {
- rects_ = rects;
+ mojom::WidgetInputHandlerHostPtr widget_input_handler;
+ mock_input_handler_host_ = std::make_unique<MockWidgetInputHandlerHost>(
+ mojo::MakeRequest(&widget_input_handler));
+
+ widget_input_handler_manager_->AddInterface(
+ nullptr, std::move(widget_input_handler));
}
- void SendInputEvent(const blink::WebInputEvent& event) {
- OnHandleInputEvent(
- &event, std::vector<const blink::WebInputEvent*>(), ui::LatencyInfo(),
- ShouldBlockEventStream(event)
- ? InputEventDispatchType::DISPATCH_TYPE_BLOCKING
- : InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING);
+ void SendInputEvent(const blink::WebInputEvent& event,
+ HandledEventCallback callback) {
+ HandleInputEvent(blink::WebCoalescedInputEvent(
+ event, std::vector<const blink::WebInputEvent*>()),
+ ui::LatencyInfo(), std::move(callback));
}
void set_always_overscroll(bool overscroll) {
@@ -98,19 +163,14 @@ class InteractiveRenderWidget : public RenderWidget {
MockWebWidget* mock_webwidget() { return &mock_webwidget_; }
+ MockWidgetInputHandlerHost* mock_input_handler_host() {
+ return mock_input_handler_host_.get();
+ }
+
protected:
~InteractiveRenderWidget() override { webwidget_internal_ = nullptr; }
// Overridden from RenderWidget:
- bool HasTouchEventHandlersAt(const gfx::Point& point) const override {
- for (std::vector<gfx::Rect>::const_iterator iter = rects_.begin();
- iter != rects_.end(); ++iter) {
- if ((*iter).Contains(point))
- return true;
- }
- return false;
- }
-
bool WillHandleGestureEvent(const blink::WebGestureEvent& event) override {
if (always_overscroll_ &&
event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) {
@@ -121,7 +181,7 @@ class InteractiveRenderWidget : public RenderWidget {
blink::WebFloatPoint(event.x, event.y),
blink::WebFloatSize(event.data.scroll_update.velocity_x,
event.data.scroll_update.velocity_y),
- blink::WebScrollBoundaryBehavior());
+ blink::WebOverscrollBehavior());
return true;
}
@@ -135,10 +195,10 @@ class InteractiveRenderWidget : public RenderWidget {
}
private:
- std::vector<gfx::Rect> rects_;
IPC::TestSink sink_;
bool always_overscroll_;
MockWebWidget mock_webwidget_;
+ std::unique_ptr<MockWidgetInputHandlerHost> mock_input_handler_host_;
static int next_routing_id_;
DISALLOW_COPY_AND_ASSIGN(InteractiveRenderWidget);
@@ -148,8 +208,9 @@ int InteractiveRenderWidget::next_routing_id_ = 0;
class RenderWidgetUnittest : public testing::Test {
public:
- RenderWidgetUnittest()
- : widget_(new InteractiveRenderWidget(&compositor_deps_)) {
+ RenderWidgetUnittest() {
+ mojo_feature_list_.InitAndEnableFeature(features::kMojoInputMessages);
+ widget_ = new InteractiveRenderWidget(&compositor_deps_);
// RenderWidget::Init does an AddRef that's balanced by a browser-initiated
// Close IPC. That Close will never happen in this test, so do a Release
// here to ensure |widget_| is properly freed.
@@ -167,6 +228,7 @@ class RenderWidgetUnittest : public testing::Test {
protected:
base::test::ScopedTaskEnvironment scoped_task_environment_;
+ base::test::ScopedFeatureList mojo_feature_list_;
private:
MockRenderProcess render_process_;
@@ -178,84 +240,6 @@ class RenderWidgetUnittest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(RenderWidgetUnittest);
};
-TEST_F(RenderWidgetUnittest, TouchHitTestSinglePoint) {
- SyntheticWebTouchEvent touch;
- touch.PressPoint(10, 10);
-
- EXPECT_CALL(*widget()->mock_webwidget(), HandleInputEvent(_))
- .WillRepeatedly(
- ::testing::Return(blink::WebInputEventResult::kNotHandled));
-
- widget()->SendInputEvent(touch);
- ASSERT_EQ(1u, widget()->sink()->message_count());
-
- // Since there's currently no touch-event handling region, the response should
- // be 'no consumer exists'.
- const IPC::Message* message = widget()->sink()->GetMessageAt(0);
- EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
- InputHostMsg_HandleInputEvent_ACK::Param params;
- InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
- InputEventAckState ack_state = std::get<0>(params).state;
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state);
- widget()->sink()->ClearMessages();
-
- std::vector<gfx::Rect> rects;
- rects.push_back(gfx::Rect(0, 0, 20, 20));
- rects.push_back(gfx::Rect(25, 0, 10, 10));
- widget()->SetTouchRegion(rects);
-
- EXPECT_CALL(*widget()->mock_webwidget(), HandleInputEvent(_))
- .WillRepeatedly(
- ::testing::Return(blink::WebInputEventResult::kNotHandled));
-
- widget()->SendInputEvent(touch);
- ASSERT_EQ(1u, widget()->sink()->message_count());
- message = widget()->sink()->GetMessageAt(0);
- EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
- InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
- ack_state = std::get<0>(params).state;
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state);
- widget()->sink()->ClearMessages();
-}
-
-TEST_F(RenderWidgetUnittest, TouchHitTestMultiplePoints) {
- std::vector<gfx::Rect> rects;
- rects.push_back(gfx::Rect(0, 0, 20, 20));
- rects.push_back(gfx::Rect(25, 0, 10, 10));
- widget()->SetTouchRegion(rects);
-
- SyntheticWebTouchEvent touch;
- touch.PressPoint(25, 25);
-
- EXPECT_CALL(*widget()->mock_webwidget(), HandleInputEvent(_))
- .WillRepeatedly(
- ::testing::Return(blink::WebInputEventResult::kNotHandled));
-
- widget()->SendInputEvent(touch);
- ASSERT_EQ(1u, widget()->sink()->message_count());
-
- // Since there's currently no touch-event handling region, the response should
- // be 'no consumer exists'.
- const IPC::Message* message = widget()->sink()->GetMessageAt(0);
- EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
- InputHostMsg_HandleInputEvent_ACK::Param params;
- InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
- InputEventAckState ack_state = std::get<0>(params).state;
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state);
- widget()->sink()->ClearMessages();
-
- // Press a second touch point. This time, on a touch-handling region.
- touch.PressPoint(10, 10);
- widget()->SendInputEvent(touch);
- ASSERT_EQ(1u, widget()->sink()->message_count());
- message = widget()->sink()->GetMessageAt(0);
- EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
- InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
- ack_state = std::get<0>(params).state;
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state);
- widget()->sink()->ClearMessages();
-}
-
TEST_F(RenderWidgetUnittest, EventOverscroll) {
widget()->set_always_overscroll(true);
@@ -269,43 +253,41 @@ TEST_F(RenderWidgetUnittest, EventOverscroll) {
ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
scroll.x = -10;
scroll.data.scroll_update.delta_y = 10;
- widget()->SendInputEvent(scroll);
+ MockHandledEventCallback handled_event;
+
+ ui::DidOverscrollParams expected_overscroll;
+ expected_overscroll.latest_overscroll_delta = gfx::Vector2dF(0, 10);
+ expected_overscroll.accumulated_overscroll = gfx::Vector2dF(0, 10);
+ expected_overscroll.causal_event_viewport_point = gfx::PointF(-10, 0);
+ expected_overscroll.current_fling_velocity = gfx::Vector2dF();
// Overscroll notifications received while handling an input event should
// be bundled with the event ack IPC.
- ASSERT_EQ(1u, widget()->sink()->message_count());
- const IPC::Message* message = widget()->sink()->GetMessageAt(0);
- ASSERT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
- InputHostMsg_HandleInputEvent_ACK::Param params;
- InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
- const InputEventAck& ack = std::get<0>(params);
- ASSERT_EQ(ack.type, scroll.GetType());
- ASSERT_TRUE(ack.overscroll);
- EXPECT_EQ(gfx::Vector2dF(0, 10), ack.overscroll->accumulated_overscroll);
- EXPECT_EQ(gfx::Vector2dF(0, 10), ack.overscroll->latest_overscroll_delta);
- EXPECT_EQ(gfx::Vector2dF(), ack.overscroll->current_fling_velocity);
- EXPECT_EQ(gfx::PointF(-10, 0), ack.overscroll->causal_event_viewport_point);
- widget()->sink()->ClearMessages();
+ EXPECT_CALL(handled_event, Run(INPUT_EVENT_ACK_STATE_CONSUMED, _,
+ testing::Pointee(expected_overscroll), _))
+ .Times(1);
+
+ widget()->SendInputEvent(scroll, handled_event.GetCallback());
}
TEST_F(RenderWidgetUnittest, FlingOverscroll) {
+ ui::DidOverscrollParams expected_overscroll;
+ expected_overscroll.latest_overscroll_delta = gfx::Vector2dF(10, 5);
+ expected_overscroll.accumulated_overscroll = gfx::Vector2dF(5, 5);
+ expected_overscroll.causal_event_viewport_point = gfx::PointF(1, 1);
+ expected_overscroll.current_fling_velocity = gfx::Vector2dF(10, 5);
+
+ EXPECT_CALL(*widget()->mock_input_handler_host(),
+ DidOverscroll(expected_overscroll))
+ .Times(1);
+
// Overscroll notifications received outside of handling an input event should
// be sent as a separate IPC.
widget()->DidOverscroll(blink::WebFloatSize(10, 5), blink::WebFloatSize(5, 5),
blink::WebFloatPoint(1, 1),
blink::WebFloatSize(10, 5),
- blink::WebScrollBoundaryBehavior());
- ASSERT_EQ(1u, widget()->sink()->message_count());
- const IPC::Message* message = widget()->sink()->GetMessageAt(0);
- ASSERT_EQ(InputHostMsg_DidOverscroll::ID, message->type());
- InputHostMsg_DidOverscroll::Param params;
- InputHostMsg_DidOverscroll::Read(message, &params);
- const ui::DidOverscrollParams& overscroll = std::get<0>(params);
- EXPECT_EQ(gfx::Vector2dF(10, 5), overscroll.latest_overscroll_delta);
- EXPECT_EQ(gfx::Vector2dF(5, 5), overscroll.accumulated_overscroll);
- EXPECT_EQ(gfx::PointF(1, 1), overscroll.causal_event_viewport_point);
- EXPECT_EQ(gfx::Vector2dF(10, 5), overscroll.current_fling_velocity);
- widget()->sink()->ClearMessages();
+ blink::WebOverscrollBehavior());
+ base::RunLoop().RunUntilIdle();
}
TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
@@ -318,25 +300,25 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
.WillRepeatedly(
::testing::Return(blink::WebInputEventResult::kNotHandled));
- widget()->SendInputEvent(touch);
+ widget()->SendInputEvent(touch, HandledEventCallback());
histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_CANCELABLE, 1);
touch.dispatch_type = blink::WebInputEvent::DispatchType::kEventNonBlocking;
- widget()->SendInputEvent(touch);
+ widget()->SendInputEvent(touch, HandledEventCallback());
histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE,
1);
touch.dispatch_type =
blink::WebInputEvent::DispatchType::kListenersNonBlockingPassive;
- widget()->SendInputEvent(touch);
+ widget()->SendInputEvent(touch, HandledEventCallback());
histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_PASSIVE, 1);
touch.dispatch_type =
blink::WebInputEvent::DispatchType::kListenersForcedNonBlockingDueToFling;
- widget()->SendInputEvent(touch);
+ widget()->SendInputEvent(touch, HandledEventCallback());
histogram_tester().ExpectBucketCount(
EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING_DUE_TO_FLING, 1);
@@ -345,14 +327,14 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
touch.touch_start_or_first_touch_move = true;
touch.dispatch_type =
blink::WebInputEvent::DispatchType::kListenersForcedNonBlockingDueToFling;
- widget()->SendInputEvent(touch);
+ widget()->SendInputEvent(touch, HandledEventCallback());
histogram_tester().ExpectBucketCount(
EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING_DUE_TO_FLING, 2);
touch.dispatch_type = blink::WebInputEvent::DispatchType::
kListenersForcedNonBlockingDueToMainThreadResponsiveness;
- widget()->SendInputEvent(touch);
+ widget()->SendInputEvent(touch, HandledEventCallback());
histogram_tester().ExpectBucketCount(
EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING_DUE_TO_MAIN_THREAD_RESPONSIVENESS,
@@ -362,7 +344,7 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
touch.touch_start_or_first_touch_move = true;
touch.dispatch_type = blink::WebInputEvent::DispatchType::
kListenersForcedNonBlockingDueToMainThreadResponsiveness;
- widget()->SendInputEvent(touch);
+ widget()->SendInputEvent(touch, HandledEventCallback());
histogram_tester().ExpectBucketCount(
EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING_DUE_TO_MAIN_THREAD_RESPONSIVENESS,
@@ -372,7 +354,7 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
.WillOnce(
::testing::Return(blink::WebInputEventResult::kHandledSuppressed));
touch.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
- widget()->SendInputEvent(touch);
+ widget()->SendInputEvent(touch, HandledEventCallback());
histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED, 1);
@@ -380,39 +362,12 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
.WillOnce(
::testing::Return(blink::WebInputEventResult::kHandledApplication));
touch.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
- widget()->SendInputEvent(touch);
+ widget()->SendInputEvent(touch, HandledEventCallback());
histogram_tester().ExpectBucketCount(
EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED, 1);
}
-TEST_F(RenderWidgetUnittest, TouchDuringOrOutsideFlingUmaMetrics) {
- EXPECT_CALL(*widget()->mock_webwidget(), HandleInputEvent(_))
- .Times(3)
- .WillRepeatedly(
- ::testing::Return(blink::WebInputEventResult::kNotHandled));
-
- SyntheticWebTouchEvent touch;
- touch.PressPoint(10, 10);
- touch.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
- touch.touch_start_or_first_touch_move = true;
- widget()->SendInputEvent(touch);
- histogram_tester().ExpectTotalCount("Event.Touch.TouchLatencyOutsideFling",
- 1);
-
- touch.MovePoint(0, 10, 10);
- touch.touch_start_or_first_touch_move = true;
- widget()->SendInputEvent(touch);
- histogram_tester().ExpectTotalCount("Event.Touch.TouchLatencyOutsideFling",
- 2);
-
- touch.MovePoint(0, 30, 30);
- touch.touch_start_or_first_touch_move = false;
- widget()->SendInputEvent(touch);
- histogram_tester().ExpectTotalCount("Event.Touch.TouchLatencyOutsideFling",
- 2);
-}
-
class PopupRenderWidget : public RenderWidget {
public:
explicit PopupRenderWidget(CompositorDependencies* compositor_deps)
@@ -456,8 +411,9 @@ int PopupRenderWidget::routing_id_ = 1;
class RenderWidgetPopupUnittest : public testing::Test {
public:
- RenderWidgetPopupUnittest()
- : widget_(new PopupRenderWidget(&compositor_deps_)) {
+ RenderWidgetPopupUnittest() {
+ mojo_feature_list_.InitAndEnableFeature(features::kMojoInputMessages);
+ widget_ = new PopupRenderWidget(&compositor_deps_);
// RenderWidget::Init does an AddRef that's balanced by a browser-initiated
// Close IPC. That Close will never happen in this test, so do a Release
// here to ensure |widget_| is properly freed.
@@ -471,6 +427,7 @@ class RenderWidgetPopupUnittest : public testing::Test {
protected:
base::test::ScopedTaskEnvironment scoped_task_environment_;
+ base::test::ScopedFeatureList mojo_feature_list_;
private:
MockRenderProcess render_process_;
diff --git a/chromium/content/renderer/renderer_blink_platform_impl.cc b/chromium/content/renderer/renderer_blink_platform_impl.cc
index 1a9d6c2e7ef..edda27d2cfb 100644
--- a/chromium/content/renderer/renderer_blink_platform_impl.cc
+++ b/chromium/content/renderer/renderer_blink_platform_impl.cc
@@ -21,28 +21,19 @@
#include "base/numerics/safe_conversions.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/url_formatter/url_formatter.h"
-#include "content/child/blob_storage/webblobregistry_impl.h"
-#include "content/child/child_url_loader_factory_getter_impl.h"
-#include "content/child/file_info_util.h"
-#include "content/child/fileapi/webfilesystem_impl.h"
-#include "content/child/indexed_db/webidbfactory_impl.h"
-#include "content/child/loader/cors_url_loader_factory.h"
-#include "content/child/quota_dispatcher.h"
-#include "content/child/quota_message_filter.h"
-#include "content/child/storage_util.h"
+#include "content/child/child_process.h"
#include "content/child/thread_safe_sender.h"
-#include "content/child/web_database_observer_impl.h"
-#include "content/child/web_url_loader_impl.h"
-#include "content/child/webfileutilities_impl.h"
#include "content/common/frame_messages.h"
#include "content/common/gpu_stream_constants.h"
-#include "content/common/render_process_messages.h"
+#include "content/common/origin_trials/trial_policy_impl.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/service_manager_connection.h"
@@ -50,14 +41,24 @@
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/media_stream_utils.h"
#include "content/public/renderer/render_frame.h"
+#include "content/renderer/blob_storage/webblobregistry_impl.h"
#include "content/renderer/cache_storage/webserviceworkercachestorage_impl.h"
#include "content/renderer/device_sensors/device_motion_event_pump.h"
#include "content/renderer/device_sensors/device_orientation_event_pump.h"
#include "content/renderer/dom_storage/local_storage_cached_areas.h"
#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/gamepad_shared_memory_reader.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_getter_impl.h"
+#include "content/renderer/loader/cors_url_loader_factory.h"
+#include "content/renderer/loader/resource_dispatcher.h"
+#include "content/renderer/loader/web_data_consumer_handle_impl.h"
+#include "content/renderer/loader/web_url_loader_impl.h"
#include "content/renderer/media/audio_decoder.h"
#include "content/renderer/media/audio_device_factory.h"
#include "content/renderer/media/renderer_webaudiodevice_impl.h"
@@ -67,21 +68,30 @@
#include "content/renderer/media_capture_from_element/html_video_element_capturer_source.h"
#include "content/renderer/media_recorder/media_recorder_handler.h"
#include "content/renderer/mojo/blink_interface_provider_impl.h"
+#include "content/renderer/notifications/notification_dispatcher.h"
+#include "content/renderer/notifications/notification_manager.h"
+#include "content/renderer/push_messaging/push_provider.h"
+#include "content/renderer/quota_dispatcher.h"
#include "content/renderer/render_thread_impl.h"
-#include "content/renderer/renderer_clipboard_delegate.h"
+#include "content/renderer/storage_util.h"
+#include "content/renderer/web_database_observer_impl.h"
#include "content/renderer/webclipboard_impl.h"
+#include "content/renderer/webfileutilities_impl.h"
#include "content/renderer/webgraphicscontext3d_provider_impl.h"
#include "content/renderer/webpublicsuffixlist_impl.h"
+#include "content/renderer/worker_thread_registry.h"
#include "device/gamepad/public/cpp/gamepads.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/config/gpu_info.h"
#include "gpu/ipc/client/gpu_channel_host.h"
+#include "ipc/ipc_sync_channel.h"
#include "ipc/ipc_sync_message_filter.h"
#include "media/audio/audio_output_device.h"
#include "media/blink/webcontentdecryptionmodule_impl.h"
#include "media/filters/stream_parser_factory.h"
#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 "ppapi/features/features.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
@@ -105,18 +115,19 @@
#include "third_party/WebKit/public/platform/WebSocketHandshakeThrottle.h"
#include "third_party/WebKit/public/platform/WebThread.h"
#include "third_party/WebKit/public/platform/WebURL.h"
+#include "third_party/WebKit/public/platform/WebURLLoaderFactory.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h"
#include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceOrientationListener.h"
#include "third_party/WebKit/public/platform/modules/webmidi/WebMIDIAccessor.h"
+#include "third_party/WebKit/public/platform/scheduler/child/webthread_base.h"
#include "third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/sqlite/sqlite3.h"
#include "url/gurl.h"
#if defined(OS_MACOSX)
-#include "content/common/mac/font_descriptor.h"
#include "content/common/mac/font_loader.h"
#include "content/renderer/webscrollbarbehavior_impl_mac.h"
#include "third_party/WebKit/public/platform/mac/WebSandboxSupport.h"
@@ -136,10 +147,6 @@
#endif
#endif
-#if defined(OS_WIN)
-#include "content/common/child_process_messages.h"
-#endif
-
#if defined(USE_AURA)
#include "content/renderer/webscrollbarbehavior_impl_aura.h"
#elif !defined(OS_MACOSX)
@@ -232,7 +239,7 @@ class RendererBlinkPlatformImpl::SandboxSupport
virtual ~SandboxSupport() {}
#if defined(OS_MACOSX)
- bool LoadFont(NSFont* src_font,
+ bool LoadFont(CTFontRef src_font,
CGFontRef* container,
uint32_t* font_id) override;
#elif defined(OS_POSIX)
@@ -258,10 +265,12 @@ class RendererBlinkPlatformImpl::SandboxSupport
RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
blink::scheduler::RendererScheduler* renderer_scheduler)
- : BlinkPlatformImpl(renderer_scheduler->DefaultTaskRunner()),
+ : BlinkPlatformImpl(renderer_scheduler->DefaultTaskRunner(),
+ RenderThreadImpl::current()
+ ? RenderThreadImpl::current()->GetIOTaskRunner()
+ : nullptr),
+ compositor_thread_(nullptr),
main_thread_(renderer_scheduler->CreateMainThread()),
- clipboard_delegate_(new RendererClipboardDelegate),
- clipboard_(new WebClipboardImpl(clipboard_delegate_.get())),
sudden_termination_disables_(0),
plugin_refresh_allowed_(true),
default_task_runner_(renderer_scheduler->DefaultTaskRunner()),
@@ -283,7 +292,6 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
->Clone();
sync_message_filter_ = RenderThreadImpl::current()->sync_message_filter();
thread_safe_sender_ = RenderThreadImpl::current()->thread_safe_sender();
- quota_message_filter_ = RenderThreadImpl::current()->quota_message_filter();
shared_bitmap_manager_ =
RenderThreadImpl::current()->shared_bitmap_manager();
blob_registry_.reset(new WebBlobRegistryImpl(
@@ -292,6 +300,8 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
web_idb_factory_.reset(new WebIDBFactoryImpl(
sync_message_filter_,
RenderThreadImpl::current()->GetIOTaskRunner().get()));
+ notification_dispatcher_ =
+ RenderThreadImpl::current()->notification_dispatcher();
} else {
service_manager::mojom::ConnectorRequest request;
connector_ = service_manager::Connector::Create(&request);
@@ -327,24 +337,22 @@ void RendererBlinkPlatformImpl::Shutdown() {
//------------------------------------------------------------------------------
-std::unique_ptr<blink::WebURLLoader> RendererBlinkPlatformImpl::CreateURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- ChildThreadImpl* child_thread = ChildThreadImpl::current();
-
- if (!url_loader_factory_getter_ && child_thread)
- url_loader_factory_getter_ = CreateDefaultURLLoaderFactoryGetter();
-
- mojom::URLLoaderFactory* factory =
- url_loader_factory_getter_
- ? url_loader_factory_getter_->GetFactoryForURL(request.Url())
- : nullptr;
+std::unique_ptr<blink::WebURLLoaderFactory>
+RendererBlinkPlatformImpl::CreateDefaultURLLoaderFactory() {
+ if (!RenderThreadImpl::current()) {
+ // RenderThreadImpl is null in some tests, the default factory impl
+ // takes care of that in the case.
+ return std::make_unique<WebURLLoaderFactoryImpl>(nullptr, nullptr);
+ }
+ return std::make_unique<WebURLLoaderFactoryImpl>(
+ RenderThreadImpl::current()->resource_dispatcher()->GetWeakPtr(),
+ CreateDefaultURLLoaderFactoryGetter());
+}
- // There may be no child thread in RenderViewTests. These tests can still use
- // data URLs to bypass the ResourceDispatcher.
- return base::MakeUnique<WebURLLoaderImpl>(
- child_thread ? child_thread->resource_dispatcher() : nullptr,
- std::move(task_runner), factory);
+std::unique_ptr<blink::WebDataConsumerHandle>
+RendererBlinkPlatformImpl::CreateDataConsumerHandle(
+ mojo::ScopedDataPipeConsumerHandle handle) {
+ return std::make_unique<WebDataConsumerHandleImpl>(std::move(handle));
}
scoped_refptr<ChildURLLoaderFactoryGetter>
@@ -358,8 +366,8 @@ RendererBlinkPlatformImpl::CreateDefaultURLLoaderFactoryGetter() {
PossiblyAssociatedInterfacePtr<mojom::URLLoaderFactory>
RendererBlinkPlatformImpl::CreateNetworkURLLoaderFactory() {
- ChildThreadImpl* child_thread = ChildThreadImpl::current();
- DCHECK(child_thread);
+ RenderThreadImpl* render_thread = RenderThreadImpl::current();
+ DCHECK(render_thread);
PossiblyAssociatedInterfacePtr<mojom::URLLoaderFactory> url_loader_factory;
if (base::FeatureList::IsEnabled(features::kNetworkService)) {
@@ -368,7 +376,7 @@ RendererBlinkPlatformImpl::CreateNetworkURLLoaderFactory() {
url_loader_factory = std::move(factory_ptr);
} else {
mojom::URLLoaderFactoryAssociatedPtr factory_ptr;
- child_thread->channel()->GetRemoteAssociatedInterface(&factory_ptr);
+ render_thread->channel()->GetRemoteAssociatedInterface(&factory_ptr);
url_loader_factory = std::move(factory_ptr);
}
@@ -386,6 +394,13 @@ 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();
@@ -401,6 +416,9 @@ blink::WebClipboard* RendererBlinkPlatformImpl::Clipboard() {
GetContentClient()->renderer()->OverrideWebClipboard();
if (clipboard)
return clipboard;
+ if (!clipboard_) {
+ clipboard_ = std::make_unique<WebClipboardImpl>(GetClipboardHost());
+ }
return clipboard_.get();
}
@@ -427,7 +445,7 @@ blink::WebSandboxSupport* RendererBlinkPlatformImpl::GetSandboxSupport() {
blink::WebCookieJar* RendererBlinkPlatformImpl::CookieJar() {
NOTREACHED() << "Use WebFrameClient::cookieJar() instead!";
- return NULL;
+ return nullptr;
}
blink::WebThemeEngine* RendererBlinkPlatformImpl::ThemeEngine() {
@@ -472,10 +490,10 @@ void RendererBlinkPlatformImpl::CacheMetadata(const blink::WebURL& url,
// 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<char> copy(data, data + size);
- RenderThread::Get()->Send(
- new RenderProcessHostMsg_DidGenerateCacheableMetadata(url, response_time,
- copy));
+ std::vector<uint8_t> copy(data, data + size);
+ RenderThreadImpl::current()
+ ->render_message_filter()
+ ->DidGenerateCacheableMetadata(url, response_time, copy);
}
void RendererBlinkPlatformImpl::CacheMetadataInCacheStorage(
@@ -488,11 +506,12 @@ void RendererBlinkPlatformImpl::CacheMetadataInCacheStorage(
// Let the browser know we generated cacheable metadata for this resource in
// CacheStorage. The browser may cache it and return it on subsequent
// responses to speed the processing of this resource.
- std::vector<char> copy(data, data + size);
- RenderThread::Get()->Send(
- new RenderProcessHostMsg_DidGenerateCacheableMetadataInCacheStorage(
+ std::vector<uint8_t> copy(data, data + size);
+ RenderThreadImpl::current()
+ ->render_message_filter()
+ ->DidGenerateCacheableMetadataInCacheStorage(
url, response_time, copy, cacheStorageOrigin,
- cacheStorageCacheName.Utf8()));
+ cacheStorageCacheName.Utf8());
}
WebString RendererBlinkPlatformImpl::DefaultLocale() {
@@ -514,9 +533,21 @@ void RendererBlinkPlatformImpl::SuddenTerminationChanged(bool enabled) {
return;
}
- RenderThread* thread = RenderThread::Get();
+ RenderThreadImpl* thread = RenderThreadImpl::current();
if (thread) // NULL in unittests.
- thread->Send(new RenderProcessHostMsg_SuddenTerminationChanged(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>
@@ -525,15 +556,30 @@ RendererBlinkPlatformImpl::CreateLocalStorageNamespace() {
switches::kDisableMojoLocalStorage)) {
if (!local_storage_cached_areas_) {
local_storage_cached_areas_.reset(new LocalStorageCachedAreas(
- RenderThreadImpl::current()->GetStoragePartitionService()));
+ RenderThreadImpl::current()->GetStoragePartitionService(),
+ renderer_scheduler_));
}
- return base::MakeUnique<LocalStorageNamespace>(
+ return std::make_unique<LocalStorageNamespace>(
local_storage_cached_areas_.get());
}
- return base::MakeUnique<WebStorageNamespaceImpl>();
+ return std::make_unique<WebStorageNamespaceImpl>();
}
+std::unique_ptr<blink::WebStorageNamespace>
+RendererBlinkPlatformImpl::CreateSessionStorageNamespace(int64_t namespace_id) {
+ if (base::FeatureList::IsEnabled(features::kMojoSessionStorage)) {
+ if (!local_storage_cached_areas_) {
+ local_storage_cached_areas_.reset(new LocalStorageCachedAreas(
+ RenderThreadImpl::current()->GetStoragePartitionService(),
+ renderer_scheduler_));
+ }
+ return std::make_unique<SessionWebStorageNamespaceImpl>(
+ namespace_id, local_storage_cached_areas_.get());
+ }
+
+ return std::make_unique<WebStorageNamespaceImpl>(namespace_id);
+}
//------------------------------------------------------------------------------
@@ -546,7 +592,7 @@ WebIDBFactory* RendererBlinkPlatformImpl::IdbFactory() {
std::unique_ptr<blink::WebServiceWorkerCacheStorage>
RendererBlinkPlatformImpl::CreateCacheStorage(
const blink::WebSecurityOrigin& security_origin) {
- return base::MakeUnique<WebServiceWorkerCacheStorageImpl>(
+ return std::make_unique<WebServiceWorkerCacheStorageImpl>(
thread_safe_sender_.get(), security_origin);
}
@@ -582,22 +628,25 @@ bool RendererBlinkPlatformImpl::FileUtilities::GetFileInfo(
#if defined(OS_MACOSX)
-bool RendererBlinkPlatformImpl::SandboxSupport::LoadFont(NSFont* src_font,
+bool RendererBlinkPlatformImpl::SandboxSupport::LoadFont(CTFontRef src_font,
CGFontRef* out,
uint32_t* font_id) {
uint32_t font_data_size;
- FontDescriptor src_font_descriptor(src_font);
- base::SharedMemoryHandle font_data;
- if (!RenderThread::Get()->Send(new RenderProcessHostMsg_LoadFont(
- src_font_descriptor, &font_data_size, &font_data, font_id))) {
+ base::ScopedCFTypeRef<CFStringRef> name_ref(
+ CTFontCopyPostScriptName(src_font));
+ base::string16 font_name = SysCFStringRefToUTF16(name_ref);
+ float font_point_size = CTFontGetSize(src_font);
+ mojo::ScopedSharedBufferHandle font_data;
+ if (!RenderThreadImpl::current()->render_message_filter()->LoadFont(
+ font_name, font_point_size, &font_data_size, &font_data, font_id)) {
*out = NULL;
*font_id = 0;
return false;
}
- if (font_data_size == 0 || !font_data.IsValid() || *font_id == 0) {
- LOG(ERROR) << "Bad response from RenderProcessHostMsg_LoadFont() for " <<
- src_font_descriptor.font_name;
+ if (font_data_size == 0 || !font_data.is_valid() || *font_id == 0) {
+ LOG(ERROR) << "Bad response from RenderProcessHostMsg_LoadFont() for "
+ << font_name;
*out = NULL;
*font_id = 0;
return false;
@@ -607,7 +656,8 @@ bool RendererBlinkPlatformImpl::SandboxSupport::LoadFont(NSFont* src_font,
// isn't already activated, based on the font id. If it's already
// activated, don't reactivate it here - crbug.com/72727 .
- return FontLoader::CGFontRefFromBuffer(font_data, font_data_size, out);
+ return FontLoader::CGFontRefFromBuffer(std::move(font_data), font_data_size,
+ out);
}
#elif defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
@@ -708,10 +758,11 @@ bool RendererBlinkPlatformImpl::IsThreadedCompositingEnabled() {
return thread && thread->compositor_task_runner().get();
}
-bool RendererBlinkPlatformImpl::IsGPUCompositingEnabled() {
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- return !command_line.HasSwitch(switches::kDisableGpuCompositing);
+bool RendererBlinkPlatformImpl::IsGpuCompositingDisabled() {
+ DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+ RenderThreadImpl* thread = RenderThreadImpl::current();
+ // |thread| can be NULL in tests.
+ return !thread || thread->IsGpuCompositingDisabled();
}
bool RendererBlinkPlatformImpl::IsThreadedAnimationEnabled() {
@@ -789,7 +840,7 @@ RendererBlinkPlatformImpl::CreateMIDIAccessor(
if (accessor)
return accessor;
- return base::MakeUnique<RendererWebMIDIAccessorImpl>(client);
+ return std::make_unique<RendererWebMIDIAccessorImpl>(client);
}
void RendererBlinkPlatformImpl::GetPluginList(
@@ -855,7 +906,7 @@ void RendererBlinkPlatformImpl::SampleGamepads(device::Gamepads& gamepads) {
std::unique_ptr<WebMediaRecorderHandler>
RendererBlinkPlatformImpl::CreateMediaRecorderHandler() {
#if BUILDFLAG(ENABLE_WEBRTC)
- return base::MakeUnique<content::MediaRecorderHandler>();
+ return std::make_unique<content::MediaRecorderHandler>();
#else
return nullptr;
#endif
@@ -885,7 +936,7 @@ RendererBlinkPlatformImpl::CreateRTCPeerConnectionHandler(
std::unique_ptr<blink::WebRTCCertificateGenerator>
RendererBlinkPlatformImpl::CreateRTCCertificateGenerator() {
#if BUILDFLAG(ENABLE_WEBRTC)
- return base::MakeUnique<RTCCertificateGenerator>();
+ return std::make_unique<RTCCertificateGenerator>();
#else
return nullptr;
#endif // BUILDFLAG(ENABLE_WEBRTC)
@@ -974,7 +1025,7 @@ void RendererBlinkPlatformImpl::CreateHTMLAudioElementCapturer(
std::unique_ptr<WebImageCaptureFrameGrabber>
RendererBlinkPlatformImpl::CreateImageCaptureFrameGrabber() {
#if BUILDFLAG(ENABLE_WEBRTC)
- return base::MakeUnique<ImageCaptureFrameGrabber>();
+ return std::make_unique<ImageCaptureFrameGrabber>();
#else
return nullptr;
#endif // BUILDFLAG(ENABLE_WEBRTC)
@@ -1103,7 +1154,7 @@ RendererBlinkPlatformImpl::CreateOffscreenGraphicsContext3DProvider(
GURL(top_document_web_url), automatic_flushes, support_locking,
gpu::SharedMemoryLimits(), attributes, share_context,
ui::command_buffer_metrics::OFFSCREEN_CONTEXT_FOR_WEBGL));
- return base::MakeUnique<WebGraphicsContext3DProviderImpl>(
+ return std::make_unique<WebGraphicsContext3DProviderImpl>(
std::move(provider), is_software_rendering);
}
@@ -1130,7 +1181,7 @@ RendererBlinkPlatformImpl::CreateSharedOffscreenGraphicsContext3DProvider() {
bool is_software_rendering = host->gpu_info().software_rendering;
- return base::MakeUnique<WebGraphicsContext3DProviderImpl>(
+ return std::make_unique<WebGraphicsContext3DProviderImpl>(
std::move(provider), is_software_rendering);
}
@@ -1203,17 +1254,17 @@ RendererBlinkPlatformImpl::CreatePlatformEventObserverFromType(
// hardware changes. In order to make that happen, they will receive a null
// thread.
if (thread && RenderThreadImpl::current()->layout_test_mode())
- thread = NULL;
+ thread = nullptr;
switch (type) {
case blink::kWebPlatformEventTypeDeviceMotion:
- return base::MakeUnique<DeviceMotionEventPump>(thread);
+ return std::make_unique<DeviceMotionEventPump>(thread);
case blink::kWebPlatformEventTypeDeviceOrientation:
- return base::MakeUnique<DeviceOrientationEventPump>(thread);
+ return std::make_unique<DeviceOrientationEventPump>(thread);
case blink::kWebPlatformEventTypeDeviceOrientationAbsolute:
- return base::MakeUnique<DeviceOrientationAbsoluteEventPump>(thread);
+ return std::make_unique<DeviceOrientationAbsoluteEventPump>(thread);
case blink::kWebPlatformEventTypeGamepad:
- return base::MakeUnique<GamepadSharedMemoryReader>(thread);
+ return std::make_unique<GamepadSharedMemoryReader>(thread);
default:
// A default statement is required to prevent compilation errors when
// Blink adds a new type.
@@ -1221,7 +1272,7 @@ RendererBlinkPlatformImpl::CreatePlatformEventObserverFromType(
"unknown type.";
}
- return NULL;
+ return nullptr;
}
void RendererBlinkPlatformImpl::SetPlatformEventObserverForTesting(
@@ -1273,16 +1324,16 @@ void RendererBlinkPlatformImpl::SendFakeDeviceEventDataForTesting(
PlatformEventObserverBase* observer = platform_event_observers_.Lookup(type);
CHECK(observer);
- void* data = 0;
+ void* data = nullptr;
switch (type) {
case blink::kWebPlatformEventTypeDeviceMotion:
- if (!(g_test_device_motion_data == 0))
+ if (!(g_test_device_motion_data == nullptr))
data = &g_test_device_motion_data.Get();
break;
case blink::kWebPlatformEventTypeDeviceOrientation:
case blink::kWebPlatformEventTypeDeviceOrientationAbsolute:
- if (!(g_test_device_orientation_data == 0))
+ if (!(g_test_device_orientation_data == nullptr))
data = &g_test_device_orientation_data.Get();
break;
default:
@@ -1313,27 +1364,46 @@ void RendererBlinkPlatformImpl::QueryStorageUsageAndQuota(
const blink::WebURL& storage_partition,
blink::WebStorageQuotaType type,
blink::WebStorageQuotaCallbacks callbacks) {
- if (!thread_safe_sender_.get() || !quota_message_filter_.get())
- return;
- QuotaDispatcher::ThreadSpecificInstance(thread_safe_sender_.get(),
- quota_message_filter_.get())
+ QuotaDispatcher::ThreadSpecificInstance(default_task_runner_)
->QueryStorageUsageAndQuota(
- storage_partition,
- static_cast<storage::StorageType>(type),
+ storage_partition, static_cast<storage::StorageType>(type),
QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks));
}
//------------------------------------------------------------------------------
+blink::WebPushProvider* RendererBlinkPlatformImpl::PushProvider() {
+ return PushProvider::ThreadSpecificInstance(default_task_runner_);
+}
+
+//------------------------------------------------------------------------------
+
std::unique_ptr<blink::WebTrialTokenValidator>
-RendererBlinkPlatformImpl::TrialTokenValidator() {
+RendererBlinkPlatformImpl::CreateTrialTokenValidator() {
return std::make_unique<WebTrialTokenValidatorImpl>(
- std::make_unique<blink::TrialTokenValidator>(OriginTrialPolicy()));
+ TrialPolicyImpl::CreateValidatorForPolicy());
}
-std::unique_ptr<blink::TrialPolicy>
-RendererBlinkPlatformImpl::OriginTrialPolicy() {
- return std::make_unique<TrialPolicyImpl>();
+//------------------------------------------------------------------------------
+
+blink::WebNotificationManager*
+RendererBlinkPlatformImpl::GetWebNotificationManager() {
+ if (!thread_safe_sender_.get() || !notification_dispatcher_.get())
+ return nullptr;
+
+ return NotificationManager::ThreadSpecificInstance(
+ thread_safe_sender_.get(),
+ notification_dispatcher_.get());
+}
+
+//------------------------------------------------------------------------------
+
+void RendererBlinkPlatformImpl::DidStartWorkerThread() {
+ WorkerThreadRegistry::Instance()->DidStartCurrentWorkerThread();
+}
+
+void RendererBlinkPlatformImpl::WillStopWorkerThread() {
+ WorkerThreadRegistry::Instance()->WillStopCurrentWorkerThread();
}
void RendererBlinkPlatformImpl::WorkerContextCreated(
@@ -1353,16 +1423,23 @@ void RendererBlinkPlatformImpl::RequestPurgeMemory() {
void RendererBlinkPlatformImpl::InitializeWebDatabaseHostIfNeeded() {
if (!web_database_host_) {
- web_database_host_ = content::mojom::ThreadSafeWebDatabaseHostPtr::Create(
+ web_database_host_ = blink::mojom::ThreadSafeWebDatabaseHostPtr::Create(
std::move(web_database_host_info_),
base::CreateSequencedTaskRunnerWithTraits(
{base::WithBaseSyncPrimitives()}));
}
}
-mojom::WebDatabaseHost& RendererBlinkPlatformImpl::GetWebDatabaseHost() {
+blink::mojom::WebDatabaseHost& RendererBlinkPlatformImpl::GetWebDatabaseHost() {
InitializeWebDatabaseHostIfNeeded();
return **web_database_host_;
}
+mojom::ClipboardHost& RendererBlinkPlatformImpl::GetClipboardHost() {
+ if (!clipboard_host_) {
+ GetConnector()->BindInterface(mojom::kBrowserServiceName, &clipboard_host_);
+ }
+ return *clipboard_host_;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/renderer_blink_platform_impl.h b/chromium/content/renderer/renderer_blink_platform_impl.h
index 8d68defb758..72649102bfc 100644
--- a/chromium/content/renderer/renderer_blink_platform_impl.h
+++ b/chromium/content/renderer/renderer_blink_platform_impl.h
@@ -18,17 +18,17 @@
#include "cc/blink/web_compositor_support_impl.h"
#include "components/viz/client/client_shared_bitmap_manager.h"
#include "content/child/blink_platform_impl.h"
+#include "content/common/clipboard.mojom.h"
#include "content/common/content_export.h"
#include "content/common/file_utilities.mojom.h"
-#include "content/common/origin_trials/trial_policy_impl.h"
#include "content/common/possibly_associated_interface_ptr.h"
-#include "content/common/web_database.mojom.h"
#include "content/public/common/url_loader_factory.mojom.h"
#include "content/renderer/origin_trials/web_trial_token_validator_impl.h"
#include "content/renderer/top_level_blame_context.h"
#include "content/renderer/webpublicsuffixlist_impl.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBFactory.h"
#include "third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationType.h"
+#include "third_party/WebKit/public/platform/modules/webdatabase/web_database.mojom.h"
namespace IPC {
class SyncMessageFilter;
@@ -37,8 +37,8 @@ class SyncMessageFilter;
namespace blink {
namespace scheduler {
class RendererScheduler;
+class WebThreadBase;
}
-class TrialPolicy;
class WebCanvasCaptureHandler;
class WebGraphicsContext3DProvider;
class WebMediaPlayer;
@@ -62,9 +62,8 @@ namespace content {
class BlinkInterfaceProviderImpl;
class ChildURLLoaderFactoryGetter;
class LocalStorageCachedAreas;
+class NotificationDispatcher;
class PlatformEventObserverBase;
-class QuotaMessageFilter;
-class RendererClipboardDelegate;
class ThreadSafeSender;
class WebClipboardImpl;
class WebDatabaseObserverImpl;
@@ -107,8 +106,13 @@ 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(
+ int64_t namespace_id) override;
blink::Platform::FileHandle DatabaseOpenFile(
const blink::WebString& vfs_file_name,
int desired_flags) override;
@@ -139,7 +143,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
bool IsThreadedCompositingEnabled() override;
bool IsThreadedAnimationEnabled() override;
- bool IsGPUCompositingEnabled() override;
+ bool IsGpuCompositingDisabled() override;
double AudioHardwareSampleRate() override;
size_t AudioHardwareBufferSize() override;
unsigned AudioHardwareOutputChannels() override;
@@ -211,9 +215,12 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
void RecordRappor(const char* metric,
const blink::WebString& sample) override;
void RecordRapporURL(const char* metric, const blink::WebURL& url) override;
-
- std::unique_ptr<blink::WebTrialTokenValidator> TrialTokenValidator() override;
- std::unique_ptr<blink::TrialPolicy> OriginTrialPolicy() override;
+ blink::WebPushProvider* PushProvider() override;
+ std::unique_ptr<blink::WebTrialTokenValidator> CreateTrialTokenValidator()
+ override;
+ blink::WebNotificationManager* GetWebNotificationManager() override;
+ void DidStartWorkerThread() override;
+ void WillStopWorkerThread() override;
void WorkerContextCreated(const v8::Local<v8::Context>& worker) override;
// Set the PlatformEventObserverBase in |platform_event_observers_| associated
@@ -244,22 +251,30 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
return web_database_observer_impl_.get();
}
- std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
-
+ std::unique_ptr<blink::WebURLLoaderFactory> CreateDefaultURLLoaderFactory()
+ override;
+ std::unique_ptr<blink::WebDataConsumerHandle> CreateDataConsumerHandle(
+ mojo::ScopedDataPipeConsumerHandle handle) override;
void RequestPurgeMemory() override;
- PossiblyAssociatedInterfacePtr<mojom::URLLoaderFactory>
- CreateNetworkURLLoaderFactory();
-
// Returns non-null.
// It is invalid to call this in an incomplete env where
// RenderThreadImpl::current() returns nullptr (e.g. in some tests).
scoped_refptr<ChildURLLoaderFactoryGetter>
CreateDefaultURLLoaderFactoryGetter();
+ // 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);
+
+ // Return the mojo interface for making ClipboardHost calls.
+ mojom::ClipboardHost& GetClipboardHost();
+
private:
+ PossiblyAssociatedInterfacePtr<mojom::URLLoaderFactory>
+ CreateNetworkURLLoaderFactory();
+
bool CheckPreparsedJsCachingEnabled() const;
// Factory that takes a type and return PlatformEventObserverBase that matches
@@ -275,12 +290,13 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
void InitializeWebDatabaseHostIfNeeded();
// Return the mojo interface for making WebDatabaseHost calls.
- mojom::WebDatabaseHost& GetWebDatabaseHost();
+ blink::mojom::WebDatabaseHost& GetWebDatabaseHost();
+
+ blink::scheduler::WebThreadBase* compositor_thread_;
std::unique_ptr<blink::WebThread> main_thread_;
std::unique_ptr<service_manager::Connector> connector_;
- std::unique_ptr<RendererClipboardDelegate> clipboard_delegate_;
std::unique_ptr<WebClipboardImpl> clipboard_;
class FileUtilities;
@@ -309,7 +325,6 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_;
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
- scoped_refptr<QuotaMessageFilter> quota_message_filter_;
viz::ClientSharedBitmapManager* shared_bitmap_manager_;
std::unique_ptr<WebDatabaseObserverImpl> web_database_observer_impl_;
@@ -328,15 +343,15 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
std::unique_ptr<BlinkInterfaceProviderImpl> blink_interface_provider_;
- // Platform's default factory getter. TODO(kinuko): Migrate all
- // URLLoader{Factory} callsites to per-frame / per-context ones and
- // deprecate this.
- scoped_refptr<ChildURLLoaderFactoryGetter> url_loader_factory_getter_;
-
- mojom::WebDatabaseHostPtrInfo web_database_host_info_;
- scoped_refptr<mojom::ThreadSafeWebDatabaseHostPtr> web_database_host_;
+ blink::mojom::WebDatabaseHostPtrInfo web_database_host_info_;
+ scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host_;
mojom::FileUtilitiesHostPtrInfo file_utilities_host_info_;
+ mojom::ClipboardHostPtr clipboard_host_;
+
+ scoped_refptr<NotificationDispatcher> notification_dispatcher_;
+
+ THREAD_CHECKER(main_thread_checker_);
DISALLOW_COPY_AND_ASSIGN(RendererBlinkPlatformImpl);
};
diff --git a/chromium/content/renderer/renderer_clipboard_delegate.cc b/chromium/content/renderer/renderer_clipboard_delegate.cc
deleted file mode 100644
index ec5e4ff8623..00000000000
--- a/chromium/content/renderer/renderer_clipboard_delegate.cc
+++ /dev/null
@@ -1,162 +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.
-
-// This file provides the embedder's side of the Clipboard interface.
-
-#include "content/renderer/renderer_clipboard_delegate.h"
-
-#include "base/memory/shared_memory.h"
-#include "base/numerics/safe_math.h"
-#include "content/common/clipboard_messages.h"
-#include "content/public/renderer/content_renderer_client.h"
-#include "content/renderer/render_thread_impl.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/base/clipboard/clipboard.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace content {
-
-RendererClipboardDelegate::RendererClipboardDelegate() {
-}
-
-uint64_t RendererClipboardDelegate::GetSequenceNumber(ui::ClipboardType type) {
- uint64_t sequence_number = 0;
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_GetSequenceNumber(type, &sequence_number));
- return sequence_number;
-}
-
-bool RendererClipboardDelegate::IsFormatAvailable(
- content::ClipboardFormat format,
- ui::ClipboardType type) {
- bool result = false;
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_IsFormatAvailable(format, type, &result));
- return result;
-}
-
-void RendererClipboardDelegate::Clear(ui::ClipboardType type) {
- RenderThreadImpl::current()->Send(new ClipboardHostMsg_Clear(type));
-}
-
-void RendererClipboardDelegate::ReadAvailableTypes(
- ui::ClipboardType type,
- std::vector<base::string16>* types,
- bool* contains_filenames) {
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_ReadAvailableTypes(type, types, contains_filenames));
-}
-
-void RendererClipboardDelegate::ReadText(ui::ClipboardType type,
- base::string16* result) {
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_ReadText(type, result));
-}
-
-void RendererClipboardDelegate::ReadHTML(ui::ClipboardType type,
- base::string16* markup,
- GURL* url,
- uint32_t* fragment_start,
- uint32_t* fragment_end) {
- RenderThreadImpl::current()->Send(new ClipboardHostMsg_ReadHTML(
- type, markup, url, fragment_start, fragment_end));
-}
-
-void RendererClipboardDelegate::ReadRTF(ui::ClipboardType type,
- std::string* result) {
- RenderThreadImpl::current()->Send(new ClipboardHostMsg_ReadRTF(type, result));
-}
-
-void RendererClipboardDelegate::ReadImage(ui::ClipboardType type,
- std::string* blob_uuid,
- std::string* mime_type,
- int64_t* size) {
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_ReadImage(type, blob_uuid, mime_type, size));
-}
-
-void RendererClipboardDelegate::ReadCustomData(ui::ClipboardType clipboard_type,
- const base::string16& type,
- base::string16* data) {
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_ReadCustomData(clipboard_type, type, data));
-}
-
-void RendererClipboardDelegate::WriteText(ui::ClipboardType clipboard_type,
- const base::string16& text) {
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_WriteText(clipboard_type, text));
-}
-
-void RendererClipboardDelegate::WriteHTML(ui::ClipboardType clipboard_type,
- const base::string16& markup,
- const GURL& url) {
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_WriteHTML(clipboard_type, markup, url));
-}
-
-void RendererClipboardDelegate::WriteSmartPasteMarker(
- ui::ClipboardType clipboard_type) {
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_WriteSmartPasteMarker(clipboard_type));
-}
-
-void RendererClipboardDelegate::WriteCustomData(
- ui::ClipboardType clipboard_type,
- const std::map<base::string16, base::string16>& data) {
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_WriteCustomData(clipboard_type, data));
-}
-
-void RendererClipboardDelegate::WriteBookmark(ui::ClipboardType clipboard_type,
- const GURL& url,
- const base::string16& title) {
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_WriteBookmark(clipboard_type, url.spec(), title));
-}
-
-bool RendererClipboardDelegate::WriteImage(ui::ClipboardType clipboard_type,
- const SkBitmap& bitmap) {
- // Only 32-bit bitmaps are supported.
- DCHECK_EQ(bitmap.colorType(), kN32_SkColorType);
-
- const gfx::Size size(bitmap.width(), bitmap.height());
- std::unique_ptr<base::SharedMemory> shared_buf;
-
- {
- void* pixels = bitmap.getPixels();
- // TODO(piman): this should not be NULL, but it is. crbug.com/369621
- if (!pixels)
- return false;
-
- base::CheckedNumeric<uint32_t> checked_buf_size = 4;
- checked_buf_size *= size.width();
- checked_buf_size *= size.height();
- if (!checked_buf_size.IsValid())
- return false;
-
- // Allocate a shared memory buffer to hold the bitmap bits.
- uint32_t buf_size = checked_buf_size.ValueOrDie();
- shared_buf = ChildThreadImpl::AllocateSharedMemory(buf_size);
- if (!shared_buf)
- return false;
- if (!shared_buf->Map(buf_size))
- return false;
- // Copy the bits into shared memory
- DCHECK(shared_buf->memory());
- memcpy(shared_buf->memory(), pixels, buf_size);
- shared_buf->Unmap();
- }
-
- RenderThreadImpl::current()->Send(new ClipboardHostMsg_WriteImage(
- clipboard_type, size, shared_buf->handle()));
- return true;
-}
-
-void RendererClipboardDelegate::CommitWrite(ui::ClipboardType clipboard_type) {
- RenderThreadImpl::current()->Send(
- new ClipboardHostMsg_CommitWrite(clipboard_type));
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/renderer_clipboard_delegate.h b/chromium/content/renderer/renderer_clipboard_delegate.h
deleted file mode 100644
index 9328505bb1a..00000000000
--- a/chromium/content/renderer/renderer_clipboard_delegate.h
+++ /dev/null
@@ -1,70 +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_RENDERER_CLIPBOARD_DELEGATE_H_
-#define CONTENT_RENDERER_RENDERER_CLIPBOARD_DELEGATE_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/strings/string16.h"
-#include "content/common/clipboard_format.h"
-#include "ui/base/clipboard/clipboard_types.h"
-
-class GURL;
-class SkBitmap;
-
-namespace content {
-
-// Renderer interface to read/write from the clipboard over IPC.
-class RendererClipboardDelegate {
- public:
- RendererClipboardDelegate();
-
- uint64_t GetSequenceNumber(ui::ClipboardType type);
- bool IsFormatAvailable(ClipboardFormat format, ui::ClipboardType type);
- void Clear(ui::ClipboardType type);
- void ReadAvailableTypes(ui::ClipboardType type,
- std::vector<base::string16>* types,
- bool* contains_filenames);
- void ReadText(ui::ClipboardType type, base::string16* result);
- void ReadHTML(ui::ClipboardType type,
- base::string16* markup,
- GURL* url,
- uint32_t* fragment_start,
- uint32_t* fragment_end);
- void ReadRTF(ui::ClipboardType type, std::string* result);
- void ReadImage(ui::ClipboardType type,
- std::string* blob_uuid,
- std::string* mime_type,
- int64_t* size);
- void ReadCustomData(ui::ClipboardType clipboard_type,
- const base::string16& type,
- base::string16* data);
-
- void WriteText(ui::ClipboardType type, const base::string16& text);
- void WriteHTML(ui::ClipboardType type,
- const base::string16& markup,
- const GURL& url);
- void WriteSmartPasteMarker(ui::ClipboardType type);
- void WriteCustomData(ui::ClipboardType type,
- const std::map<base::string16, base::string16>& data);
- void WriteBookmark(ui::ClipboardType type,
- const GURL& url,
- const base::string16& title);
- bool WriteImage(ui::ClipboardType type, const SkBitmap& bitmap);
- void CommitWrite(ui::ClipboardType type);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RendererClipboardDelegate);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_RENDERER_CLIPBOARD_DELEGATE_H_
diff --git a/chromium/content/renderer/renderer_main.cc b/chromium/content/renderer/renderer_main.cc
index 965bf5735a1..89161707d5f 100644
--- a/chromium/content/renderer/renderer_main.cc
+++ b/chromium/content/renderer/renderer_main.cc
@@ -40,9 +40,11 @@
#include "base/android/library_loader/library_loader_hooks.h"
#endif // OS_ANDROID
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
+#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \
+ !defined(OS_FUCHSIA)
#include "content/common/font_config_ipc_linux.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
+#include "content/public/common/common_sandbox_support_linux.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#include "third_party/skia/include/ports/SkFontConfigInterface.h"
#endif
@@ -94,7 +96,7 @@ int RendererMain(const MainFunctionParams& parameters) {
// expect synchronous events around the main loop of a thread.
TRACE_EVENT_ASYNC_BEGIN0("startup", "RendererMain", 0);
- base::trace_event::TraceLog::GetInstance()->SetProcessName("Renderer");
+ base::trace_event::TraceLog::GetInstance()->set_process_name("Renderer");
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventRendererProcessSortIndex);
diff --git a/chromium/content/renderer/renderer_main_platform_delegate_android.cc b/chromium/content/renderer/renderer_main_platform_delegate_android.cc
index dc0ff56ed3e..b433720b1ca 100644
--- a/chromium/content/renderer/renderer_main_platform_delegate_android.cc
+++ b/chromium/content/renderer/renderer_main_platform_delegate_android.cc
@@ -34,7 +34,7 @@ bool RendererMainPlatformDelegate::EnableSandbox() {
sandbox::SeccompStarterAndroid starter(info->sdk_int(), info->device());
// The policy compiler is only available if USE_SECCOMP_BPF is enabled.
#if BUILDFLAG(USE_SECCOMP_BPF)
- starter.set_policy(base::MakeUnique<sandbox::BaselinePolicyAndroid>());
+ starter.set_policy(std::make_unique<sandbox::BaselinePolicyAndroid>());
#endif
starter.StartSandbox();
diff --git a/chromium/content/renderer/renderer_main_platform_delegate_linux.cc b/chromium/content/renderer/renderer_main_platform_delegate_linux.cc
index 5743abd8a4f..eeb53a45092 100644
--- a/chromium/content/renderer/renderer_main_platform_delegate_linux.cc
+++ b/chromium/content/renderer/renderer_main_platform_delegate_linux.cc
@@ -10,9 +10,10 @@
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/logging.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/sandbox_init.h"
+#include "services/service_manager/sandbox/sandbox.h"
namespace content {
@@ -33,19 +34,26 @@ bool RendererMainPlatformDelegate::EnableSandbox() {
// https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox.md
//
// Anything else is started in InitializeSandbox().
- LinuxSandbox::InitializeSandbox();
- // about:sandbox uses a value returned from LinuxSandbox::GetStatus() before
+ service_manager::SandboxLinux::Options options;
+ options.has_wasm_trap_handler =
+ base::FeatureList::IsEnabled(features::kWebAssemblyTrapHandler);
+ service_manager::Sandbox::Initialize(
+ service_manager::SandboxTypeFromCommandLine(
+ *base::CommandLine::ForCurrentProcess()),
+ service_manager::SandboxLinux::PreSandboxHook(), options);
+
+ // about:sandbox uses a value returned from SandboxLinux::GetStatus() before
// any renderer has been started.
// Here, we test that the status of SeccompBpf in the renderer is consistent
- // with what LinuxSandbox::GetStatus() said we would do.
- class LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance();
- if (linux_sandbox->GetStatus() & kSandboxLinuxSeccompBPF) {
+ // with what SandboxLinux::GetStatus() said we would do.
+ auto* linux_sandbox = service_manager::SandboxLinux::GetInstance();
+ if (linux_sandbox->GetStatus() & service_manager::SandboxLinux::kSeccompBPF) {
CHECK(linux_sandbox->seccomp_bpf_started());
}
// Under the setuid sandbox, we should not be able to open any file via the
// filesystem.
- if (linux_sandbox->GetStatus() & kSandboxLinuxSUID) {
+ if (linux_sandbox->GetStatus() & service_manager::SandboxLinux::kSUID) {
CHECK(!base::PathExists(base::FilePath("/proc/cpuinfo")));
}
diff --git a/chromium/content/renderer/renderer_main_platform_delegate_mac.mm b/chromium/content/renderer/renderer_main_platform_delegate_mac.mm
index 205ef42470d..aea4ae36d9e 100644
--- a/chromium/content/renderer/renderer_main_platform_delegate_mac.mm
+++ b/chromium/content/renderer/renderer_main_platform_delegate_mac.mm
@@ -16,8 +16,8 @@
#include "base/mac/scoped_cftyperef.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
-#include "content/common/sandbox_init_mac.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/sandbox_init.h"
#include "sandbox/mac/seatbelt.h"
#include "services/service_manager/sandbox/mac/sandbox_mac.h"
@@ -163,8 +163,8 @@ bool RendererMainPlatformDelegate::EnableSandbox() {
if (sandbox_initialized) {
DisconnectWindowServer();
} else {
- sandbox_initialized = InitializeSandboxWithPostWarmupHook(
- base::BindOnce(&DisconnectWindowServer));
+ sandbox_initialized =
+ InitializeSandbox(base::BindOnce(&DisconnectWindowServer));
}
// The sandbox is now engaged. Make sure that the renderer has not connected
diff --git a/chromium/content/renderer/renderer_main_platform_delegate_win.cc b/chromium/content/renderer/renderer_main_platform_delegate_win.cc
index 7d6bac89729..52d6c358821 100644
--- a/chromium/content/renderer/renderer_main_platform_delegate_win.cc
+++ b/chromium/content/renderer/renderer_main_platform_delegate_win.cc
@@ -11,7 +11,6 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/string16.h"
-#include "base/win/scoped_comptr.h"
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.h"
diff --git a/chromium/content/renderer/renderer_webapplicationcachehost_impl.cc b/chromium/content/renderer/renderer_webapplicationcachehost_impl.cc
index 1a54f5d60a8..949bbbbe6c3 100644
--- a/chromium/content/renderer/renderer_webapplicationcachehost_impl.cc
+++ b/chromium/content/renderer/renderer_webapplicationcachehost_impl.cc
@@ -66,8 +66,12 @@ void RendererWebApplicationCacheHostImpl::SetSubresourceFactory(
mojo::MessagePipeHandle loader_factory_pipe_handle) {
RenderFrameImpl* render_frame =
RenderFrameImpl::FromRoutingID(frame_routing_id_);
- if (render_frame)
- render_frame->SetCustomURLLoadeFactory(loader_factory_pipe_handle);
+ if (render_frame) {
+ mojom::URLLoaderFactoryPtr loader_factory;
+ loader_factory.Bind(mojom::URLLoaderFactoryPtrInfo(
+ mojo::ScopedMessagePipeHandle(loader_factory_pipe_handle), 0));
+ render_frame->SetCustomURLLoaderFactory(std::move(loader_factory));
+ }
}
RenderViewImpl* RendererWebApplicationCacheHostImpl::GetRenderView() {
diff --git a/chromium/content/renderer/renderer_webapplicationcachehost_impl.h b/chromium/content/renderer/renderer_webapplicationcachehost_impl.h
index 273308e7e04..fe4bb8abbbb 100644
--- a/chromium/content/renderer/renderer_webapplicationcachehost_impl.h
+++ b/chromium/content/renderer/renderer_webapplicationcachehost_impl.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_RENDERER_RENDERER_WEBAPPLICATIONCACHEHOST_IMPL_H_
#define CONTENT_RENDERER_RENDERER_WEBAPPLICATIONCACHEHOST_IMPL_H_
-#include "content/child/appcache/web_application_cache_host_impl.h"
+#include "content/renderer/appcache/web_application_cache_host_impl.h"
namespace content {
class RenderViewImpl;
diff --git a/chromium/content/renderer/renderer_webcookiejar_impl.cc b/chromium/content/renderer/renderer_webcookiejar_impl.cc
index fc25e80915d..4c2263429eb 100644
--- a/chromium/content/renderer/renderer_webcookiejar_impl.cc
+++ b/chromium/content/renderer/renderer_webcookiejar_impl.cc
@@ -4,6 +4,8 @@
#include "content/renderer/renderer_webcookiejar_impl.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/frame_messages.h"
#include "content/public/renderer/content_renderer_client.h"
@@ -21,7 +23,8 @@ 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);
+ sender_->GetRoutingID(), url, site_for_cookies, value_utf8,
+ base::BindOnce(&base::DoNothing));
}
WebString RendererWebCookieJarImpl::Cookies(const WebURL& url,
diff --git a/chromium/content/renderer/sandbox_mac_v2_unittest.mm b/chromium/content/renderer/sandbox_mac_v2_unittest.mm
index 647bb130c43..2d025d566f0 100644
--- a/chromium/content/renderer/sandbox_mac_v2_unittest.mm
+++ b/chromium/content/renderer/sandbox_mac_v2_unittest.mm
@@ -38,37 +38,39 @@ void SetParametersForTest(sandbox::SandboxCompiler* compiler,
const base::FilePath& executable_path) {
bool enable_logging = true;
CHECK(compiler->InsertBooleanParam(
- service_manager::Sandbox::kSandboxEnableLogging, enable_logging));
+ service_manager::SandboxMac::kSandboxEnableLogging, enable_logging));
CHECK(compiler->InsertBooleanParam(
- service_manager::Sandbox::kSandboxDisableDenialLogging, !enable_logging));
+ service_manager::SandboxMac::kSandboxDisableDenialLogging,
+ !enable_logging));
std::string homedir =
- service_manager::Sandbox::GetCanonicalSandboxPath(base::GetHomeDir())
- .value();
+ service_manager::SandboxMac::GetCanonicalPath(base::GetHomeDir()).value();
CHECK(compiler->InsertStringParam(
- service_manager::Sandbox::kSandboxHomedirAsLiteral, homedir));
+ service_manager::SandboxMac::kSandboxHomedirAsLiteral, homedir));
int32_t major_version, minor_version, bugfix_version;
base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
&bugfix_version);
int32_t os_version = (major_version * 100) + minor_version;
- CHECK(compiler->InsertStringParam(service_manager::Sandbox::kSandboxOSVersion,
- std::to_string(os_version)));
+ CHECK(compiler->InsertStringParam(
+ service_manager::SandboxMac::kSandboxOSVersion,
+ std::to_string(os_version)));
- std::string bundle_path = service_manager::Sandbox::GetCanonicalSandboxPath(
- base::mac::MainBundlePath())
- .value();
+ std::string bundle_path =
+ service_manager::SandboxMac::GetCanonicalPath(base::mac::MainBundlePath())
+ .value();
CHECK(compiler->InsertStringParam(
- service_manager::Sandbox::kSandboxBundlePath, bundle_path));
+ service_manager::SandboxMac::kSandboxBundlePath, bundle_path));
CHECK(compiler->InsertStringParam(
- service_manager::Sandbox::kSandboxChromeBundleId,
+ service_manager::SandboxMac::kSandboxChromeBundleId,
"com.google.Chrome.test.sandbox"));
CHECK(compiler->InsertStringParam(
- service_manager::Sandbox::kSandboxBrowserPID, std::to_string(getpid())));
+ service_manager::SandboxMac::kSandboxBrowserPID,
+ std::to_string(getpid())));
CHECK(compiler->InsertStringParam(
- service_manager::Sandbox::kSandboxLoggingPathAsLiteral,
+ service_manager::SandboxMac::kSandboxLoggingPathAsLiteral,
logging_path.value()));
// Parameters normally set by the main executable.
@@ -97,7 +99,7 @@ MULTIPROCESS_TEST_MAIN(SandboxProfileProcess) {
CHECK(temp_dir.CreateUniqueTempDir());
CHECK(temp_dir.IsValid());
base::FilePath temp_path = temp_dir.GetPath();
- temp_path = service_manager::Sandbox::GetCanonicalSandboxPath(temp_path);
+ temp_path = service_manager::SandboxMac::GetCanonicalPath(temp_path);
const base::FilePath log_file = temp_path.Append("log-file");
const base::FilePath exec_file("/bin/ls");
diff --git a/chromium/content/renderer/savable_resources.cc b/chromium/content/renderer/savable_resources.cc
index 24bcdb79b65..5f83331012d 100644
--- a/chromium/content/renderer/savable_resources.cc
+++ b/chromium/content/renderer/savable_resources.cc
@@ -125,7 +125,7 @@ bool GetSavableResourceLinksForFrame(WebLocalFrame* current_frame,
}
WebString GetSubResourceLinkFromElement(const WebElement& element) {
- const char* attribute_name = NULL;
+ const char* attribute_name = nullptr;
if (element.HasHTMLTagName("img") || element.HasHTMLTagName("frame") ||
element.HasHTMLTagName("iframe") || element.HasHTMLTagName("script")) {
attribute_name = "src";
diff --git a/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.cc b/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.cc
index 94afdeac891..63f35a80b89 100644
--- a/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.cc
+++ b/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.cc
@@ -4,8 +4,8 @@
#include "content/renderer/screen_orientation/screen_orientation_dispatcher.h"
-#include "content/public/common/associated_interface_provider.h"
#include "content/public/renderer/render_frame.h"
+#include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
namespace content {
diff --git a/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher_browsertest.cc b/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher_browsertest.cc
index 5fec7fbdcba..ca0760bffb7 100644
--- a/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher_browsertest.cc
+++ b/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher_browsertest.cc
@@ -59,7 +59,7 @@ class ScreenOrientationDispatcherTest : public RenderViewTest {
RenderViewTest::SetUp();
dispatcher_.reset(new ScreenOrientationDispatcher(nullptr));
ScreenOrientationAssociatedPtr screen_orientation;
- mojo::MakeIsolatedRequest(&screen_orientation);
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&screen_orientation);
dispatcher_->SetScreenOrientationForTests(screen_orientation);
}
@@ -87,7 +87,7 @@ TEST_F(ScreenOrientationDispatcherTest, CancelPending_Unlocking) {
LockOrientation(
blink::kWebScreenOrientationLockPortraitPrimary,
- base::MakeUnique<MockLockOrientationCallback>(&callback_results));
+ std::make_unique<MockLockOrientationCallback>(&callback_results));
UnlockOrientation();
EXPECT_FALSE(callback_results.succeeded_);
@@ -103,11 +103,11 @@ TEST_F(ScreenOrientationDispatcherTest, CancelPending_DoubleLock) {
LockOrientation(
blink::kWebScreenOrientationLockPortraitPrimary,
- base::MakeUnique<MockLockOrientationCallback>(&callback_results));
+ std::make_unique<MockLockOrientationCallback>(&callback_results));
LockOrientation(
blink::kWebScreenOrientationLockPortraitPrimary,
- base::MakeUnique<MockLockOrientationCallback>(&callback_results2));
+ std::make_unique<MockLockOrientationCallback>(&callback_results2));
EXPECT_FALSE(callback_results.succeeded_);
EXPECT_TRUE(callback_results.failed_);
@@ -131,7 +131,7 @@ TEST_F(ScreenOrientationDispatcherTest, LockRequest_Error) {
MockLockOrientationCallback::LockOrientationResultHolder callback_results;
LockOrientation(
blink::kWebScreenOrientationLockPortraitPrimary,
- base::MakeUnique<MockLockOrientationCallback>(&callback_results));
+ std::make_unique<MockLockOrientationCallback>(&callback_results));
RunLockResultCallback(GetRequestId(), it->first);
EXPECT_FALSE(callback_results.succeeded_);
EXPECT_TRUE(callback_results.failed_);
@@ -145,7 +145,7 @@ TEST_F(ScreenOrientationDispatcherTest, LockRequest_Success) {
MockLockOrientationCallback::LockOrientationResultHolder callback_results;
LockOrientation(
blink::kWebScreenOrientationLockPortraitPrimary,
- base::MakeUnique<MockLockOrientationCallback>(&callback_results));
+ std::make_unique<MockLockOrientationCallback>(&callback_results));
RunLockResultCallback(GetRequestId(),
LockResult::SCREEN_ORIENTATION_LOCK_RESULT_SUCCESS);
@@ -166,12 +166,12 @@ TEST_F(ScreenOrientationDispatcherTest, RaceScenario) {
LockOrientation(
blink::kWebScreenOrientationLockPortraitPrimary,
- base::MakeUnique<MockLockOrientationCallback>(&callback_results1));
+ std::make_unique<MockLockOrientationCallback>(&callback_results1));
int request_id1 = GetRequestId();
LockOrientation(
blink::kWebScreenOrientationLockLandscapePrimary,
- base::MakeUnique<MockLockOrientationCallback>(&callback_results2));
+ std::make_unique<MockLockOrientationCallback>(&callback_results2));
// callback_results1 must be rejected, tested in CancelPending_DoubleLock.
diff --git a/chromium/content/child/service_worker/controller_service_worker_connector.cc b/chromium/content/renderer/service_worker/controller_service_worker_connector.cc
index 643cc9ff976..e0ee79a6272 100644
--- a/chromium/content/child/service_worker/controller_service_worker_connector.cc
+++ b/chromium/content/renderer/service_worker/controller_service_worker_connector.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/child/service_worker/controller_service_worker_connector.h"
+#include "content/renderer/service_worker/controller_service_worker_connector.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -31,6 +31,14 @@ ControllerServiceWorkerConnector::GetControllerServiceWorker() {
return controller_service_worker_.get();
}
+void ControllerServiceWorkerConnector::AddObserver(Observer* observer) {
+ observer_list_.AddObserver(observer);
+}
+
+void ControllerServiceWorkerConnector::RemoveObserver(Observer* observer) {
+ observer_list_.RemoveObserver(observer);
+}
+
void ControllerServiceWorkerConnector::OnContainerHostConnectionClosed() {
container_host_ = nullptr;
}
@@ -38,9 +46,9 @@ void ControllerServiceWorkerConnector::OnContainerHostConnectionClosed() {
ControllerServiceWorkerConnector::~ControllerServiceWorkerConnector() = default;
void ControllerServiceWorkerConnector::OnControllerConnectionClosed() {
- // TODO(kinuko): If this happens during a resource loader we should let the
- // loader know and restart.
controller_service_worker_.reset();
+ for (auto& observer : observer_list_)
+ observer.OnConnectionClosed();
}
} // namespace content
diff --git a/chromium/content/child/service_worker/controller_service_worker_connector.h b/chromium/content/renderer/service_worker/controller_service_worker_connector.h
index e2fa8c280f3..5746cb9228e 100644
--- a/chromium/content/child/service_worker/controller_service_worker_connector.h
+++ b/chromium/content/renderer/service_worker/controller_service_worker_connector.h
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_CONNECTOR_H_
-#define CONTENT_CHILD_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_CONNECTOR_H_
+#ifndef CONTENT_RENDERER_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_CONNECTOR_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_CONNECTOR_H_
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/observer_list.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/controller_service_worker.mojom.h"
@@ -23,6 +24,12 @@ class ServiceWorkerContainerHost;
class CONTENT_EXPORT ControllerServiceWorkerConnector
: public base::RefCounted<ControllerServiceWorkerConnector> {
public:
+ // Observes the connection to the controller.
+ class Observer {
+ public:
+ virtual void OnConnectionClosed() = 0;
+ };
+
explicit ControllerServiceWorkerConnector(
mojom::ServiceWorkerContainerHost* container_host);
@@ -30,6 +37,9 @@ class CONTENT_EXPORT ControllerServiceWorkerConnector
// browser process) is already terminated.
mojom::ControllerServiceWorker* GetControllerServiceWorker();
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
void OnContainerHostConnectionClosed();
private:
@@ -51,9 +61,11 @@ class CONTENT_EXPORT ControllerServiceWorkerConnector
// in the renderer process)
mojom::ControllerServiceWorkerPtr controller_service_worker_;
+ base::ObserverList<Observer> observer_list_;
+
DISALLOW_COPY_AND_ASSIGN(ControllerServiceWorkerConnector);
};
} // namespace content
-#endif // CONTENT_CHILD_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_CONNECTOR_H_
+#endif // CONTENT_RENDERER_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_CONNECTOR_H_
diff --git a/chromium/content/renderer/service_worker/controller_service_worker_impl.cc b/chromium/content/renderer/service_worker/controller_service_worker_impl.cc
new file mode 100644
index 00000000000..6cc960de0ca
--- /dev/null
+++ b/chromium/content/renderer/service_worker/controller_service_worker_impl.cc
@@ -0,0 +1,37 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/service_worker/controller_service_worker_impl.h"
+
+#include "content/common/service_worker/service_worker_utils.h"
+#include "content/renderer/service_worker/service_worker_context_client.h"
+
+namespace content {
+
+ControllerServiceWorkerImpl::ControllerServiceWorkerImpl(
+ mojom::ControllerServiceWorkerRequest request,
+ base::WeakPtr<ServiceWorkerContextClient> context_client)
+ : context_client_(std::move(context_client)) {
+ CHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ bindings_.AddBinding(this, std::move(request));
+}
+
+ControllerServiceWorkerImpl::~ControllerServiceWorkerImpl() = default;
+
+void ControllerServiceWorkerImpl::Clone(
+ mojom::ControllerServiceWorkerRequest request) {
+ bindings_.AddBinding(this, std::move(request));
+}
+
+void ControllerServiceWorkerImpl::DispatchFetchEvent(
+ const ResourceRequest& request,
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ DispatchFetchEventCallback callback) {
+ DCHECK(context_client_);
+ context_client_->DispatchFetchEvent(request, nullptr /* preload_handle */,
+ std::move(response_callback),
+ std::move(callback));
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/service_worker/controller_service_worker_impl.h b/chromium/content/renderer/service_worker/controller_service_worker_impl.h
new file mode 100644
index 00000000000..b27b603cfa9
--- /dev/null
+++ b/chromium/content/renderer/service_worker/controller_service_worker_impl.h
@@ -0,0 +1,59 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_IMPL_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_IMPL_H_
+
+#include <utility>
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/service_worker/controller_service_worker.mojom.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+
+namespace content {
+
+class ServiceWorkerContextClient;
+
+// S13nServiceWorker:
+// An instance of this class is created on the service worker thread
+// when ServiceWorkerContextClient's WorkerContextData is created.
+// This implements mojom::ControllerServiceWorker and its Mojo endpoint
+// is connected by each controllee and also by the ServiceWorkerProviderHost
+// in the browser process.
+// Subresource requests made by the controllees are sent to this class as
+// Fetch events via the Mojo endpoints.
+//
+// TODO(kinuko): Implement self-killing timer, that does something similar to
+// what ServiceWorkerVersion::StopWorkerIfIdle does in the browser process in
+// non-S13n code.
+class ControllerServiceWorkerImpl : public mojom::ControllerServiceWorker {
+ public:
+ // |context_client|'s weak pointer is the one that is bound to the worker
+ // thread. (It should actually outlive this instance, but allow us to make
+ // sure the thread safety)
+ ControllerServiceWorkerImpl(
+ mojom::ControllerServiceWorkerRequest request,
+ base::WeakPtr<ServiceWorkerContextClient> context_client);
+ ~ControllerServiceWorkerImpl() override;
+
+ // mojom::ControllerServiceWorker:
+ void DispatchFetchEvent(
+ const ResourceRequest& request,
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ DispatchFetchEventCallback callback) override;
+ void Clone(mojom::ControllerServiceWorkerRequest request) override;
+
+ private:
+ // Connected by the ServiceWorkerProviderHost in the browser process
+ // and by the controllees.
+ mojo::BindingSet<mojom::ControllerServiceWorker> bindings_;
+
+ base::WeakPtr<ServiceWorkerContextClient> context_client_;
+
+ DISALLOW_COPY_AND_ASSIGN(ControllerServiceWorkerImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_IMPL_H_
diff --git a/chromium/content/renderer/service_worker/embedded_worker_devtools_agent.cc b/chromium/content/renderer/service_worker/embedded_worker_devtools_agent.cc
index ed6d267c9a8..299d88830ef 100644
--- a/chromium/content/renderer/service_worker/embedded_worker_devtools_agent.cc
+++ b/chromium/content/renderer/service_worker/embedded_worker_devtools_agent.cc
@@ -15,24 +15,40 @@ using blink::WebString;
namespace content {
+namespace {
+const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
+}
+
EmbeddedWorkerDevToolsAgent::EmbeddedWorkerDevToolsAgent(
blink::WebEmbeddedWorker* webworker,
int route_id)
: webworker_(webworker), route_id_(route_id) {
- RenderThreadImpl::current()->AddEmbeddedWorkerRoute(route_id_, this);
+ RenderThreadImpl::current()->AddRoute(route_id_, this);
}
EmbeddedWorkerDevToolsAgent::~EmbeddedWorkerDevToolsAgent() {
- RenderThreadImpl::current()->RemoveEmbeddedWorkerRoute(route_id_);
+ RenderThreadImpl::current()->RemoveRoute(route_id_);
}
void EmbeddedWorkerDevToolsAgent::SendMessage(IPC::Sender* sender,
int session_id,
int call_id,
- const std::string& message,
- const std::string& state_cookie) {
- DevToolsAgent::SendChunkedProtocolMessage(sender, route_id_, session_id,
- call_id, message, state_cookie);
+ std::string message,
+ std::string state_cookie) {
+ bool single_chunk = message.length() < kMaxMessageChunkSize;
+ for (size_t pos = 0; pos < message.length(); pos += kMaxMessageChunkSize) {
+ DevToolsMessageChunk chunk;
+ chunk.is_first = pos == 0;
+ chunk.message_size = pos == 0 ? message.size() : 0;
+ chunk.is_last = pos + kMaxMessageChunkSize >= message.length();
+ chunk.session_id = session_id;
+ chunk.call_id = chunk.is_last ? call_id : 0;
+ chunk.post_state = chunk.is_last ? std::move(state_cookie) : std::string();
+ chunk.data = single_chunk ? std::move(message)
+ : message.substr(pos, kMaxMessageChunkSize);
+ sender->Send(new DevToolsClientMsg_DispatchOnInspectorFrontend(
+ route_id_, std::move(chunk)));
+ }
}
bool EmbeddedWorkerDevToolsAgent::OnMessageReceived(
@@ -49,16 +65,13 @@ bool EmbeddedWorkerDevToolsAgent::OnMessageReceived(
return handled;
}
-void EmbeddedWorkerDevToolsAgent::OnAttach(const std::string& host_id,
- int session_id) {
- webworker_->AttachDevTools(WebString::FromUTF8(host_id), session_id);
+void EmbeddedWorkerDevToolsAgent::OnAttach(int session_id) {
+ webworker_->AttachDevTools(session_id);
}
-void EmbeddedWorkerDevToolsAgent::OnReattach(const std::string& host_id,
- int session_id,
+void EmbeddedWorkerDevToolsAgent::OnReattach(int session_id,
const std::string& state) {
- webworker_->ReattachDevTools(WebString::FromUTF8(host_id), session_id,
- WebString::FromUTF8(state));
+ webworker_->ReattachDevTools(session_id, WebString::FromUTF8(state));
}
void EmbeddedWorkerDevToolsAgent::OnDetach(int session_id) {
diff --git a/chromium/content/renderer/service_worker/embedded_worker_devtools_agent.h b/chromium/content/renderer/service_worker/embedded_worker_devtools_agent.h
index ebba1926a33..8593bcb8863 100644
--- a/chromium/content/renderer/service_worker/embedded_worker_devtools_agent.h
+++ b/chromium/content/renderer/service_worker/embedded_worker_devtools_agent.h
@@ -31,16 +31,14 @@ class EmbeddedWorkerDevToolsAgent : public IPC::Listener {
void SendMessage(IPC::Sender* sender,
int session_id,
int call_id,
- const std::string& message,
- const std::string& state_cookie);
+ std::string message,
+ std::string state_cookie);
bool OnMessageReceived(const IPC::Message& message) override;
private:
- void OnAttach(const std::string& host_id, int session_id);
- void OnReattach(const std::string& host_id,
- int session_id,
- const std::string& state);
+ void OnAttach(int session_id);
+ void OnReattach(int session_id, const std::string& state);
void OnDetach(int session_id);
void OnDispatchOnInspectorBackend(int session_id,
int call_id,
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 5b56e425c60..539f94df8d2 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
@@ -28,7 +28,7 @@ EmbeddedWorkerInstanceClientImpl::WorkerWrapper::WorkerWrapper(
std::unique_ptr<blink::WebEmbeddedWorker> worker,
int devtools_agent_route_id)
: worker_(std::move(worker)),
- devtools_agent_(base::MakeUnique<EmbeddedWorkerDevToolsAgent>(
+ devtools_agent_(std::make_unique<EmbeddedWorkerDevToolsAgent>(
worker_.get(),
devtools_agent_route_id)) {}
@@ -58,7 +58,9 @@ void EmbeddedWorkerInstanceClientImpl::WorkerContextDestroyed() {
void EmbeddedWorkerInstanceClientImpl::StartWorker(
const EmbeddedWorkerStartParams& params,
mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy) {
@@ -66,17 +68,20 @@ void EmbeddedWorkerInstanceClientImpl::StartWorker(
DCHECK(!wrapper_);
TRACE_EVENT0("ServiceWorker",
"EmbeddedWorkerInstanceClientImpl::StartWorker");
- auto client = base::MakeUnique<ServiceWorkerContextClient>(
+ service_manager::mojom::InterfaceProviderPtr interface_provider(
+ std::move(provider_info->interface_provider));
+ auto client = std::make_unique<ServiceWorkerContextClient>(
params.embedded_worker_id, params.service_worker_version_id, params.scope,
params.script_url,
ServiceWorkerUtils::IsScriptStreamingEnabled() && installed_scripts_info,
- std::move(dispatcher_request), std::move(instance_host),
+ std::move(dispatcher_request), std::move(controller_request),
+ std::move(service_worker_host), std::move(instance_host),
std::move(provider_info), std::move(temporal_self_));
client->set_blink_initialized_time(blink_initialized_time_);
client->set_start_worker_received_time(base::TimeTicks::Now());
- wrapper_ =
- StartWorkerContext(params, std::move(installed_scripts_info),
- std::move(client), std::move(content_settings_proxy));
+ wrapper_ = StartWorkerContext(
+ params, std::move(installed_scripts_info), std::move(client),
+ std::move(content_settings_proxy), std::move(interface_provider));
}
void EmbeddedWorkerInstanceClientImpl::StopWorker() {
@@ -126,7 +131,8 @@ EmbeddedWorkerInstanceClientImpl::StartWorkerContext(
const EmbeddedWorkerStartParams& params,
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
std::unique_ptr<ServiceWorkerContextClient> context_client,
- blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy) {
+ blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy,
+ service_manager::mojom::InterfaceProviderPtr interface_provider) {
std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManager> manager;
// |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
@@ -137,10 +143,11 @@ EmbeddedWorkerInstanceClientImpl::StartWorkerContext(
std::move(installed_scripts_info), io_thread_runner_);
}
- auto wrapper = base::MakeUnique<WorkerWrapper>(
+ auto wrapper = std::make_unique<WorkerWrapper>(
blink::WebEmbeddedWorker::Create(
std::move(context_client), std::move(manager),
- content_settings_proxy.PassInterface().PassHandle()),
+ content_settings_proxy.PassInterface().PassHandle(),
+ interface_provider.PassInterface().PassHandle()),
params.worker_devtools_agent_route_id);
blink::WebEmbeddedWorkerStartData start_data;
@@ -151,9 +158,10 @@ EmbeddedWorkerInstanceClientImpl::StartWorkerContext(
params.wait_for_debugger
? blink::WebEmbeddedWorkerStartData::kWaitForDebugger
: blink::WebEmbeddedWorkerStartData::kDontWaitForDebugger;
+ start_data.instrumentation_token =
+ blink::WebString::FromUTF8(params.devtools_worker_token.ToString());
start_data.v8_cache_options = static_cast<blink::WebSettings::V8CacheOptions>(
params.settings.v8_cache_options);
- start_data.data_saver_enabled = params.settings.data_saver_enabled;
start_data.pause_after_download_mode =
params.pause_after_download
? blink::WebEmbeddedWorkerStartData::kPauseAfterDownload
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 c97f47799d2..12f5eb0f20d 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
@@ -33,7 +33,7 @@ class ServiceWorkerContextClient;
// This class deletes itself when the worker stops (or if start failed). The
// ownership graph is a cycle like this:
// EmbeddedWorkerInstanceClientImpl -(owns)-> WorkerWrapper -(owns)->
-// WebEmbeddedWorkerInstance -(owns)-> ServiceWorkerContextClient -(owns)->
+// WebEmbeddedWorkerImpl -(owns)-> ServiceWorkerContextClient -(owns)->
// EmbeddedWorkerInstanceClientImpl. Therefore, an instance can delete itself by
// releasing its WorkerWrapper.
//
@@ -89,7 +89,9 @@ class EmbeddedWorkerInstanceClientImpl
void StartWorker(
const EmbeddedWorkerStartParams& params,
mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy)
@@ -99,14 +101,15 @@ class EmbeddedWorkerInstanceClientImpl
void AddMessageToConsole(blink::WebConsoleMessage::Level level,
const std::string& message) override;
- // Handler of connection error bound to |binding_|
+ // Handler of connection error bound to |binding_|.
void OnError();
std::unique_ptr<WorkerWrapper> StartWorkerContext(
const EmbeddedWorkerStartParams& params,
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
std::unique_ptr<ServiceWorkerContextClient> context_client,
- blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy);
+ blink::mojom::WorkerContentSettingsProxyPtr content_settings_proxy,
+ service_manager::mojom::InterfaceProviderPtr interface_provider);
mojo::AssociatedBinding<mojom::EmbeddedWorkerInstanceClient> binding_;
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 9382d65291f..31d16c0a76c 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_client.cc
+++ b/chromium/content/renderer/service_worker/service_worker_context_client.cc
@@ -18,48 +18,49 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
-#include "content/child/background_sync/background_sync_type_converters.h"
-#include "content/child/notifications/notification_data_conversions.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/service_worker/service_worker_dispatcher.h"
-#include "content/child/service_worker/service_worker_handle_reference.h"
-#include "content/child/service_worker/service_worker_network_provider.h"
-#include "content/child/service_worker/service_worker_provider_context.h"
-#include "content/child/service_worker/web_service_worker_impl.h"
-#include "content/child/service_worker/web_service_worker_provider_impl.h"
-#include "content/child/service_worker/web_service_worker_registration_impl.h"
#include "content/child/thread_safe_sender.h"
-#include "content/child/web_data_consumer_handle_impl.h"
-#include "content/child/web_url_loader_impl.h"
#include "content/common/devtools_messages.h"
#include "content/common/service_worker/embedded_worker_messages.h"
#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
#include "content/public/common/content_features.h"
#include "content/public/common/push_event_payload.h"
#include "content/public/common/referrer.h"
-#include "content/public/common/service_names.mojom.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/document_state.h"
+#include "content/renderer/background_sync/background_sync_type_converters.h"
#include "content/renderer/devtools/devtools_agent.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/loader/web_data_consumer_handle_impl.h"
+#include "content/renderer/loader/web_url_loader_impl.h"
+#include "content/renderer/loader/web_url_request_util.h"
+#include "content/renderer/notifications/notification_data_conversions.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/renderer_blink_platform_impl.h"
+#include "content/renderer/service_worker/controller_service_worker_impl.h"
#include "content/renderer/service_worker/embedded_worker_devtools_agent.h"
#include "content/renderer/service_worker/embedded_worker_instance_client_impl.h"
+#include "content/renderer/service_worker/service_worker_dispatcher.h"
#include "content/renderer/service_worker/service_worker_fetch_context_impl.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.h"
+#include "content/renderer/service_worker/service_worker_network_provider.h"
+#include "content/renderer/service_worker/service_worker_provider_context.h"
+#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"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "storage/common/blob_storage/blob_handle.h"
-#include "storage/public/interfaces/blobs.mojom.h"
+#include "third_party/WebKit/common/blob/blob.mojom.h"
+#include "third_party/WebKit/common/blob/blob_registry.mojom.h"
#include "third_party/WebKit/public/platform/InterfaceProvider.h"
#include "third_party/WebKit/public/platform/Platform.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
@@ -79,6 +80,7 @@
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
#include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h"
#include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h"
@@ -117,12 +119,12 @@ class WebServiceWorkerNetworkProviderImpl
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const blink::WebURLRequest& request,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
- RenderThreadImpl* child_thread = RenderThreadImpl::current();
- if (child_thread && provider_->script_loader_factory() &&
+ RenderThreadImpl* render_thread = RenderThreadImpl::current();
+ if (render_thread && provider_->script_loader_factory() &&
ServiceWorkerUtils::IsServicificationEnabled() &&
IsScriptRequest(request)) {
- return base::MakeUnique<WebURLLoaderImpl>(
- child_thread->resource_dispatcher(), std::move(task_runner),
+ return std::make_unique<WebURLLoaderImpl>(
+ render_thread->resource_dispatcher(), std::move(task_runner),
provider_->script_loader_factory());
}
return nullptr;
@@ -157,16 +159,6 @@ class StreamHandleListener
blink::mojom::ServiceWorkerStreamCallbackPtr callback_ptr_;
};
-WebURLRequest::FetchRequestMode GetBlinkFetchRequestMode(
- FetchRequestMode mode) {
- return static_cast<WebURLRequest::FetchRequestMode>(mode);
-}
-
-WebURLRequest::FetchCredentialsMode GetBlinkFetchCredentialsMode(
- FetchCredentialsMode credentials_mode) {
- return static_cast<WebURLRequest::FetchCredentialsMode>(credentials_mode);
-}
-
WebURLRequest::FetchRedirectMode GetBlinkFetchRedirectMode(
FetchRedirectMode redirect_mode) {
return static_cast<WebURLRequest::FetchRedirectMode>(redirect_mode);
@@ -197,6 +189,43 @@ ToWebServiceWorkerClientInfo(const ServiceWorkerClientInfo& client_info) {
return web_client_info;
}
+void ToWebServiceWorkerRequest(const ResourceRequest& request,
+ blink::WebServiceWorkerRequest* web_request) {
+ DCHECK(web_request);
+ web_request->SetURL(blink::WebURL(request.url));
+ web_request->SetMethod(blink::WebString::FromUTF8(request.method));
+ if (!request.headers.IsEmpty()) {
+ for (net::HttpRequestHeaders::Iterator it(request.headers); it.GetNext();) {
+ web_request->SetHeader(blink::WebString::FromUTF8(it.name()),
+ blink::WebString::FromUTF8(it.value()));
+ }
+ }
+ if (request.request_body) {
+ blink::WebHTTPBody body =
+ GetWebHTTPBodyForRequestBody(request.request_body);
+ body.SetUniqueBoundary();
+ web_request->SetBody(body);
+ }
+ web_request->SetReferrer(blink::WebString::FromUTF8(request.referrer.spec()),
+ request.referrer_policy);
+ web_request->SetMode(request.fetch_request_mode);
+ web_request->SetIsMainResourceLoad(
+ ServiceWorkerUtils::IsMainResourceType(request.resource_type));
+ web_request->SetCredentialsMode(request.fetch_credentials_mode);
+ web_request->SetCacheMode(
+ ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(request.load_flags));
+ web_request->SetRedirectMode(
+ GetBlinkFetchRedirectMode(request.fetch_redirect_mode));
+ web_request->SetRequestContext(
+ GetBlinkRequestContext(request.fetch_request_context_type));
+ web_request->SetFrameType(GetBlinkFrameType(request.fetch_frame_type));
+ // TODO(falken): Set client id. The browser needs to pass it to us.
+ web_request->SetIsReload(ui::PageTransitionCoreTypeIs(
+ request.transition_type, ui::PAGE_TRANSITION_RELOAD));
+ web_request->SetIntegrity(
+ blink::WebString::FromUTF8(request.fetch_integrity));
+}
+
// Converts the |request| to its equivalent type in the Blink API.
// TODO(peter): Remove this when the Mojo FetchAPIRequest type exists.
void ToWebServiceWorkerRequest(const ServiceWorkerFetchRequest& request,
@@ -220,10 +249,10 @@ void ToWebServiceWorkerRequest(const ServiceWorkerFetchRequest& request,
web_request->SetReferrer(
blink::WebString::FromUTF8(request.referrer.url.spec()),
request.referrer.policy);
- web_request->SetMode(GetBlinkFetchRequestMode(request.mode));
+ web_request->SetMode(request.mode);
web_request->SetIsMainResourceLoad(request.is_main_resource_load);
- web_request->SetCredentialsMode(
- GetBlinkFetchCredentialsMode(request.credentials_mode));
+ web_request->SetCredentialsMode(request.credentials_mode);
+ web_request->SetCacheMode(request.cache_mode);
web_request->SetRedirectMode(
GetBlinkFetchRedirectMode(request.redirect_mode));
web_request->SetRequestContext(
@@ -232,6 +261,7 @@ void ToWebServiceWorkerRequest(const ServiceWorkerFetchRequest& request,
web_request->SetClientId(blink::WebString::FromUTF8(request.client_id));
web_request->SetIsReload(request.is_reload);
web_request->SetIntegrity(blink::WebString::FromUTF8(request.integrity));
+ web_request->SetKeepalive(request.keepalive);
}
// Converts |response| to its equivalent type in the Blink API.
@@ -275,18 +305,61 @@ void ToWebServiceWorkerResponse(const ServiceWorkerResponse& response,
blink::WebVector<blink::WebString>(cors_exposed_header_names));
}
-template <typename T, class... TArgs>
-void AbortPendingEventCallbacks(T& callbacks, TArgs... args) {
- for (typename T::iterator it(&callbacks); !it.IsAtEnd(); it.Advance()) {
- std::move(*it.GetCurrentValue())
- .Run(blink::mojom::ServiceWorkerEventStatus::ABORTED, args...,
- base::Time::Now());
- }
-}
-
-void GetBlobRegistry(storage::mojom::BlobRegistryRequest request) {
- ChildThreadImpl::current()->GetConnector()->BindInterface(
- mojom::kBrowserServiceName, std::move(request));
+// Finds an event callback keyed by |event_id| from |map|, and runs the callback
+// with |args|. Returns true if the callback was found and called, otherwise
+// returns false.
+template <typename MapType, class... Args>
+bool RunEventCallback(MapType* map,
+ ServiceWorkerTimeoutTimer* timer,
+ int event_id,
+ Args... args) {
+ auto iter = map->find(event_id);
+ // The event may have been aborted.
+ if (iter == map->end())
+ return false;
+ std::move(iter->second).Run(args...);
+ map->erase(iter);
+ timer->EndEvent(event_id);
+ return true;
+}
+
+// Creates a callback which takes an |event_id|, which calls the given event's
+// callback with ABORTED status and removes it from |map|.
+template <typename MapType>
+base::OnceCallback<void(int /* event_id */)> CreateAbortCallback(MapType* map) {
+ return base::BindOnce(
+ [](MapType* map, base::Time dispatched_time, int event_id) {
+ auto iter = map->find(event_id);
+ DCHECK(iter != map->end());
+ std::move(iter->second)
+ .Run(blink::mojom::ServiceWorkerEventStatus::ABORTED,
+ dispatched_time);
+ map->erase(iter);
+ },
+ map, base::Time::Now());
+}
+
+// Same as CreateAbortCallback() for InstallEvent only.
+// DispatchInstallEventCallback has an additional parameter, so this is
+// separately defined.
+template <typename MapType>
+base::OnceCallback<void(int /* event_id */)> CreateInstallEventAbortCallback(
+ MapType* map) {
+ return base::BindOnce(
+ [](MapType* map, base::Time dispatched_time, int event_id) {
+ auto iter = map->find(event_id);
+ DCHECK(iter != map->end());
+ std::move(iter->second)
+ .Run(blink::mojom::ServiceWorkerEventStatus::ABORTED,
+ false /* has_fetch_handler */, dispatched_time);
+ map->erase(iter);
+ },
+ map, base::Time::Now());
+}
+
+void OnResponseBlobDispatchDone(
+ const blink::WebServiceWorkerResponse& response) {
+ // This frees the ref to the internal data of |response|.
}
} // namespace
@@ -302,32 +375,6 @@ struct ServiceWorkerContextClient::WorkerContextData {
base::IDMap<std::unique_ptr<blink::WebServiceWorkerClientCallbacks>>;
using SkipWaitingCallbacksMap =
base::IDMap<std::unique_ptr<blink::WebServiceWorkerSkipWaitingCallbacks>>;
- using InstallEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchInstallEventCallback>>;
- using ActivateEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchActivateEventCallback>>;
- using BackgroundFetchAbortEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchBackgroundFetchAbortEventCallback>>;
- using BackgroundFetchClickEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchBackgroundFetchClickEventCallback>>;
- using BackgroundFetchFailEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchBackgroundFetchFailEventCallback>>;
- using BackgroundFetchedEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchBackgroundFetchedEventCallback>>;
- using SyncEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchSyncEventCallback>>;
- using NotificationClickEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchNotificationClickEventCallback>>;
- using NotificationCloseEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchNotificationCloseEventCallback>>;
- using PushEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchPushEventCallback>>;
- using ExtendableMessageEventCallbacksMap =
- base::IDMap<std::unique_ptr<DispatchExtendableMessageEventCallback>>;
- using NavigationPreloadRequestsMap = base::IDMap<
- std::unique_ptr<ServiceWorkerContextClient::NavigationPreloadRequest>>;
- using InstallEventMethodsMap =
- std::map<int, mojom::ServiceWorkerInstallEventMethodsAssociatedPtr>;
explicit WorkerContextData(ServiceWorkerContextClient* owner)
: event_dispatcher_binding(owner),
@@ -339,6 +386,7 @@ struct ServiceWorkerContextClient::WorkerContextData {
}
mojo::Binding<mojom::ServiceWorkerEventDispatcher> event_dispatcher_binding;
+ blink::mojom::ServiceWorkerHostAssociatedPtr service_worker_host;
// Pending callbacks for GetClientDocuments().
ClientsCallbacksMap clients_callbacks;
@@ -352,83 +400,56 @@ struct ServiceWorkerContextClient::WorkerContextData {
// Pending callbacks for ClaimClients().
ClaimClientsCallbacksMap claim_clients_callbacks;
- // Pending callbacks for Install Events.
- InstallEventCallbacksMap install_event_callbacks;
-
- // Pending callbacks for Activate Events.
- ActivateEventCallbacksMap activate_event_callbacks;
-
- // Pending callbacks for Background Fetch Abort Events.
- BackgroundFetchAbortEventCallbacksMap background_fetch_abort_event_callbacks;
-
- // Pending callbacks for Background Fetch Click Events.
- BackgroundFetchClickEventCallbacksMap background_fetch_click_event_callbacks;
-
- // Pending callbacks for Background Fetch Fail Events.
- BackgroundFetchFailEventCallbacksMap background_fetch_fail_event_callbacks;
-
- // Pending callbacks for Background Fetched Events.
- BackgroundFetchedEventCallbacksMap background_fetched_event_callbacks;
-
- // Pending callbacks for Background Sync Events.
- SyncEventCallbacksMap sync_event_callbacks;
-
- // Pending callbacks for result of AbortPayment.
- std::map<int /* abort_payment_event_id */,
- payments::mojom::PaymentHandlerResponseCallbackPtr>
+ // 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.
+ std::map<int, DispatchInstallEventCallback> install_event_callbacks;
+ std::map<int, DispatchActivateEventCallback> activate_event_callbacks;
+ std::map<int, DispatchBackgroundFetchAbortEventCallback>
+ background_fetch_abort_event_callbacks;
+ std::map<int, DispatchBackgroundFetchClickEventCallback>
+ background_fetch_click_event_callbacks;
+ std::map<int, DispatchBackgroundFetchFailEventCallback>
+ background_fetch_fail_event_callbacks;
+ std::map<int, DispatchBackgroundFetchedEventCallback>
+ background_fetched_event_callbacks;
+ std::map<int, DispatchSyncEventCallback> sync_event_callbacks;
+ std::map<int, payments::mojom::PaymentHandlerResponseCallbackPtr>
abort_payment_result_callbacks;
-
- // Pending callbacks for AbortPayment Events.
- std::map<int /* abort_payment_event_id */,
- DispatchCanMakePaymentEventCallback>
+ std::map<int, DispatchCanMakePaymentEventCallback>
abort_payment_event_callbacks;
-
- // Pending callbacks for result of CanMakePayment.
- std::map<int /* can_make_payment_event_id */,
- payments::mojom::PaymentHandlerResponseCallbackPtr>
- can_make_payment_result_callbacks;
-
- // Pending callbacks for CanMakePayment Events.
- std::map<int /* can_make_payment_event_id */,
- DispatchCanMakePaymentEventCallback>
+ std::map<int, DispatchCanMakePaymentEventCallback>
can_make_payment_event_callbacks;
-
- // Pending callbacks for Payment App Response.
- std::map<int /* payment_request_id */,
- payments::mojom::PaymentHandlerResponseCallbackPtr>
- payment_response_callbacks;
-
- // Pending callbacks for Payment Request Events.
- std::map<int /* payment_request_id */, DispatchPaymentRequestEventCallback>
+ std::map<int, DispatchPaymentRequestEventCallback>
payment_request_event_callbacks;
-
- // Pending callbacks for Notification Click Events.
- NotificationClickEventCallbacksMap notification_click_event_callbacks;
-
- // Pending callbacks for Notification Close Events.
- NotificationCloseEventCallbacksMap notification_close_event_callbacks;
-
- // Pending callbacks for Push Events.
- PushEventCallbacksMap push_event_callbacks;
-
- // Pending callbacks for Fetch Events.
- std::map<int /* fetch_event_id */, DispatchFetchEventCallback>
- fetch_event_callbacks;
-
- // Pending callbacks for respondWith on each fetch event.
- std::map<int /* fetch_event_id */,
- mojom::ServiceWorkerFetchResponseCallbackPtr>
+ std::map<int, DispatchNotificationClickEventCallback>
+ notification_click_event_callbacks;
+ std::map<int, DispatchNotificationCloseEventCallback>
+ notification_close_event_callbacks;
+ std::map<int, DispatchPushEventCallback> push_event_callbacks;
+ std::map<int, DispatchFetchEventCallback> fetch_event_callbacks;
+ std::map<int, DispatchExtendableMessageEventCallback> message_event_callbacks;
+
+ // Maps for response callbacks.
+ // These are mapped from an event id to the Mojo interface pointer which is
+ // passed from the relevant DispatchSomeEvent() method.
+ std::map<int, payments::mojom::PaymentHandlerResponseCallbackPtr>
+ can_make_payment_result_callbacks;
+ std::map<int, payments::mojom::PaymentHandlerResponseCallbackPtr>
+ payment_response_callbacks;
+ std::map<int, mojom::ServiceWorkerFetchResponseCallbackPtr>
fetch_response_callbacks;
- // Pending callbacks for Extendable Message Events.
- ExtendableMessageEventCallbacksMap message_event_callbacks;
+ // Inflight navigation preload requests.
+ base::IDMap<std::unique_ptr<NavigationPreloadRequest>> preload_requests;
- // Pending navigation preload requests.
- NavigationPreloadRequestsMap preload_requests;
+ // S13nServiceWorker
+ std::unique_ptr<ControllerServiceWorkerImpl> controller_impl;
- // Maps every install event id with its corresponding
- // mojom::ServiceWorkerInstallEventMethodsAssociatedPt.
- InstallEventMethodsMap install_methods_map;
+ // S13nServiceWorker
+ // Timer triggered when the service worker considers it should be stopped or
+ // an event should be aborted.
+ std::unique_ptr<ServiceWorkerTimeoutTimer> timeout_timer;
base::ThreadChecker thread_checker;
base::WeakPtrFactory<ServiceWorkerContextClient> weak_factory;
@@ -454,7 +475,7 @@ class ServiceWorkerContextClient::NavigationPreloadRequest final
mojom::DownloadedTempFilePtr downloaded_file) override {
DCHECK(!response_);
DCHECK(!downloaded_file);
- response_ = base::MakeUnique<blink::WebURLResponse>();
+ response_ = std::make_unique<blink::WebURLResponse>();
// TODO(horo): Set report_security_info to true when DevTools is attached.
const bool report_security_info = false;
WebURLLoaderImpl::PopulateURLResponse(url_, response_head, response_.get(),
@@ -472,7 +493,7 @@ class ServiceWorkerContextClient::NavigationPreloadRequest final
ServiceWorkerContextClient::ThreadSpecificInstance();
if (!client)
return;
- response_ = base::MakeUnique<blink::WebURLResponse>();
+ response_ = std::make_unique<blink::WebURLResponse>();
WebURLLoaderImpl::PopulateURLResponse(url_, response_head, response_.get(),
false /* report_security_info */);
client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_),
@@ -507,7 +528,7 @@ class ServiceWorkerContextClient::NavigationPreloadRequest final
MaybeReportResponseToClient();
}
- void OnComplete(const ResourceRequestCompletionStatus& status) override {
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override {
if (status.error_code != net::OK) {
std::string message;
std::string unsanitized_message;
@@ -560,7 +581,7 @@ class ServiceWorkerContextClient::NavigationPreloadRequest final
client->OnNavigationPreloadResponse(
fetch_event_id_, std::move(response_),
- base::MakeUnique<WebDataConsumerHandleImpl>(std::move(body_)));
+ std::make_unique<WebDataConsumerHandleImpl>(std::move(body_)));
}
void ReportErrorToClient(const std::string& message,
@@ -571,7 +592,7 @@ class ServiceWorkerContextClient::NavigationPreloadRequest final
return;
// This will delete |this|.
client->OnNavigationPreloadError(
- fetch_event_id_, base::MakeUnique<blink::WebServiceWorkerError>(
+ fetch_event_id_, std::make_unique<blink::WebServiceWorkerError>(
blink::mojom::ServiceWorkerErrorType::kNetwork,
blink::WebString::FromUTF8(message),
blink::WebString::FromUTF8(unsanitized_message)));
@@ -598,6 +619,8 @@ ServiceWorkerContextClient::ServiceWorkerContextClient(
const GURL& script_url,
bool is_script_streaming,
mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
std::unique_ptr<EmbeddedWorkerInstanceClientImpl> embedded_worker_client)
@@ -607,8 +630,11 @@ ServiceWorkerContextClient::ServiceWorkerContextClient(
script_url_(script_url),
sender_(ChildThreadImpl::current()->thread_safe_sender()),
main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ io_thread_task_runner_(ChildThreadImpl::current()->GetIOTaskRunner()),
proxy_(nullptr),
pending_dispatcher_request_(std::move(dispatcher_request)),
+ pending_controller_request_(std::move(controller_request)),
+ pending_service_worker_host_(std::move(service_worker_host)),
embedded_worker_client_(std::move(embedded_worker_client)) {
instance_host_ =
mojom::ThreadSafeEmbeddedWorkerInstanceHostAssociatedPtr::Create(
@@ -657,10 +683,6 @@ void ServiceWorkerContextClient::OnMessageReceived(
DCHECK(handled);
}
-blink::WebURL ServiceWorkerContextClient::Scope() const {
- return service_worker_scope_;
-}
-
void ServiceWorkerContextClient::GetClient(
const blink::WebString& id,
std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks) {
@@ -701,12 +723,14 @@ void ServiceWorkerContextClient::OpenNewPopup(
void ServiceWorkerContextClient::SetCachedMetadata(const blink::WebURL& url,
const char* data,
size_t size) {
- std::vector<char> copy(data, data + size);
- Send(new ServiceWorkerHostMsg_SetCachedMetadata(GetRoutingID(), url, copy));
+ DCHECK(context_->service_worker_host);
+ context_->service_worker_host->SetCachedMetadata(
+ url, std::vector<uint8_t>(data, data + size));
}
void ServiceWorkerContextClient::ClearCachedMetadata(const blink::WebURL& url) {
- Send(new ServiceWorkerHostMsg_ClearCachedMetadata(GetRoutingID(), url));
+ DCHECK(context_->service_worker_host);
+ context_->service_worker_host->ClearCachedMetadata(url);
}
void ServiceWorkerContextClient::WorkerReadyForInspection() {
@@ -740,9 +764,9 @@ void ServiceWorkerContextClient::WorkerContextStarted(
DCHECK(!worker_task_runner_.get());
DCHECK_NE(0, WorkerThread::GetCurrentId());
worker_task_runner_ = base::ThreadTaskRunnerHandle::Get();
- // g_worker_client_tls.Pointer()->Get() could return NULL if this context
+ // g_worker_client_tls.Pointer()->Get() could return nullptr if this context
// gets deleted before workerContextStarted() is called.
- DCHECK(g_worker_client_tls.Pointer()->Get() == NULL);
+ DCHECK(g_worker_client_tls.Pointer()->Get() == nullptr);
DCHECK(!proxy_);
g_worker_client_tls.Pointer()->Set(this);
proxy_ = proxy;
@@ -752,20 +776,29 @@ void ServiceWorkerContextClient::WorkerContextStarted(
// willDestroyWorkerContext.
context_.reset(new WorkerContextData(this));
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info;
- ServiceWorkerVersionAttributes version_attrs;
- provider_context_->TakeRegistrationForServiceWorkerGlobalScope(
- &registration_info, &version_attrs);
- DCHECK_NE(registration_info->registration_id,
- blink::mojom::kInvalidServiceWorkerRegistrationId);
-
DCHECK(pending_dispatcher_request_.is_pending());
+ DCHECK(pending_controller_request_.is_pending());
DCHECK(!context_->event_dispatcher_binding.is_bound());
+ DCHECK(!context_->controller_impl);
context_->event_dispatcher_binding.Bind(
std::move(pending_dispatcher_request_));
- SetRegistrationInServiceWorkerGlobalScope(std::move(registration_info),
- version_attrs);
+ if (ServiceWorkerUtils::IsServicificationEnabled()) {
+ context_->controller_impl = std::make_unique<ControllerServiceWorkerImpl>(
+ std::move(pending_controller_request_), GetWeakPtr());
+ }
+
+ DCHECK(pending_service_worker_host_.is_valid());
+ DCHECK(!context_->service_worker_host);
+ context_->service_worker_host.Bind(std::move(pending_service_worker_host_));
+ // Set ServiceWorkerGlobalScope#registration.
+ // TakeRegistrationForServiceWorkerGlobalScope() expects the dispatcher to be
+ // already created, so create it first.
+ ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
+ sender_.get(), main_thread_task_runner_.get());
+ proxy_->SetRegistration(WebServiceWorkerRegistrationImpl::CreateHandle(
+ provider_context_->TakeRegistrationForServiceWorkerGlobalScope(
+ io_thread_task_runner_)));
(*instance_host_)->OnThreadStarted(WorkerThread::GetCurrentId());
@@ -803,45 +836,24 @@ void ServiceWorkerContextClient::WillDestroyWorkerContext(
// At this point WillStopCurrentWorkerThread is already called, so
// worker_task_runner_->RunsTasksInCurrentSequence() returns false
// (while we're still on the worker thread).
- proxy_ = NULL;
+ proxy_ = nullptr;
blob_registry_.reset();
- AbortPendingEventCallbacks(context_->install_event_callbacks,
- false /* has_fetch_handler */);
- AbortPendingEventCallbacks(context_->activate_event_callbacks);
- AbortPendingEventCallbacks(context_->background_fetch_abort_event_callbacks);
- AbortPendingEventCallbacks(context_->background_fetch_click_event_callbacks);
- AbortPendingEventCallbacks(context_->background_fetch_fail_event_callbacks);
- AbortPendingEventCallbacks(context_->background_fetched_event_callbacks);
- AbortPendingEventCallbacks(context_->sync_event_callbacks);
- AbortPendingEventCallbacks(context_->notification_click_event_callbacks);
- AbortPendingEventCallbacks(context_->notification_close_event_callbacks);
- AbortPendingEventCallbacks(context_->push_event_callbacks);
- // For some reason |fetch_event_callbacks| uses std::map while others use
- // base::IDMap.
- // TODO(falken): Make this consistent.
- for (auto& item : context_->fetch_event_callbacks) {
- std::move(item.second)
- .Run(blink::mojom::ServiceWorkerEventStatus::ABORTED,
- base::Time::Now());
- }
- AbortPendingEventCallbacks(context_->message_event_callbacks);
-
// We have to clear callbacks now, as they need to be freed on the
// same thread.
context_.reset();
// This also lets the message filter stop dispatching messages to
// this client.
- g_worker_client_tls.Pointer()->Set(NULL);
+ g_worker_client_tls.Pointer()->Set(nullptr);
GetContentClient()->renderer()->WillDestroyServiceWorkerContextOnWorkerThread(
context, service_worker_version_id_, service_worker_scope_, script_url_);
}
void ServiceWorkerContextClient::WorkerContextDestroyed() {
- DCHECK(g_worker_client_tls.Pointer()->Get() == NULL);
+ DCHECK(g_worker_client_tls.Pointer()->Get() == nullptr);
// TODO(shimazu): The signals to the browser should be in the order:
// (1) WorkerStopped (via mojo call EmbeddedWorkerInstanceHost.OnStopped())
@@ -863,7 +875,6 @@ void ServiceWorkerContextClient::WorkerContextDestroyed() {
FROM_HERE,
base::BindOnce(&EmbeddedWorkerInstanceClientImpl::WorkerContextDestroyed,
base::Passed(&embedded_worker_client_)));
- return;
}
void ServiceWorkerContextClient::CountFeature(uint32_t feature) {
@@ -913,97 +924,70 @@ void ServiceWorkerContextClient::DidHandleActivateEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchActivateEventCallback* callback =
- context_->activate_event_callbacks.Lookup(request_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status,
- base::Time::FromDoubleT(event_dispatch_time));
- context_->activate_event_callbacks.Remove(request_id);
+ RunEventCallback(&context_->activate_event_callbacks,
+ context_->timeout_timer.get(), request_id, status,
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::DidHandleBackgroundFetchAbortEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchBackgroundFetchAbortEventCallback* callback =
- context_->background_fetch_abort_event_callbacks.Lookup(request_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status,
- base::Time::FromDoubleT(event_dispatch_time));
- context_->background_fetch_abort_event_callbacks.Remove(request_id);
+ RunEventCallback(&context_->background_fetch_abort_event_callbacks,
+ context_->timeout_timer.get(), request_id, status,
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::DidHandleBackgroundFetchClickEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchBackgroundFetchClickEventCallback* callback =
- context_->background_fetch_click_event_callbacks.Lookup(request_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status,
- base::Time::FromDoubleT(event_dispatch_time));
- context_->background_fetch_click_event_callbacks.Remove(request_id);
+ RunEventCallback(&context_->background_fetch_click_event_callbacks,
+ context_->timeout_timer.get(), request_id, status,
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::DidHandleBackgroundFetchFailEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchBackgroundFetchFailEventCallback* callback =
- context_->background_fetch_fail_event_callbacks.Lookup(request_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status,
- base::Time::FromDoubleT(event_dispatch_time));
- context_->background_fetch_fail_event_callbacks.Remove(request_id);
+ RunEventCallback(&context_->background_fetch_fail_event_callbacks,
+ context_->timeout_timer.get(), request_id, status,
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::DidHandleBackgroundFetchedEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchBackgroundFetchedEventCallback* callback =
- context_->background_fetched_event_callbacks.Lookup(request_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status,
- base::Time::FromDoubleT(event_dispatch_time));
- context_->background_fetched_event_callbacks.Remove(request_id);
+ RunEventCallback(&context_->background_fetched_event_callbacks,
+ context_->timeout_timer.get(), request_id, status,
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::DidHandleExtendableMessageEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchExtendableMessageEventCallback* callback =
- context_->message_event_callbacks.Lookup(request_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status,
- base::Time::FromDoubleT(event_dispatch_time));
- context_->message_event_callbacks.Remove(request_id);
+ RunEventCallback(&context_->message_event_callbacks,
+ context_->timeout_timer.get(), request_id, status,
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::DidHandleInstallEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchInstallEventCallback* callback =
- context_->install_event_callbacks.Lookup(event_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status, proxy_->HasFetchEventHandler(),
- base::Time::FromDoubleT(event_dispatch_time));
- context_->install_event_callbacks.Remove(event_id);
- context_->install_methods_map.erase(event_id);
+ RunEventCallback(&context_->install_event_callbacks,
+ context_->timeout_timer.get(), event_id, status,
+ proxy_->HasFetchEventHandler(),
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::RespondToFetchEventWithNoResponse(
int fetch_event_id,
double event_dispatch_time) {
+ DCHECK(base::ContainsKey(context_->fetch_response_callbacks, fetch_event_id));
const mojom::ServiceWorkerFetchResponseCallbackPtr& response_callback =
context_->fetch_response_callbacks[fetch_event_id];
DCHECK(response_callback.is_bound());
@@ -1015,32 +999,26 @@ void ServiceWorkerContextClient::RespondToFetchEvent(
int fetch_event_id,
const blink::WebServiceWorkerResponse& web_response,
double event_dispatch_time) {
+ DCHECK(base::ContainsKey(context_->fetch_response_callbacks, fetch_event_id));
ServiceWorkerResponse response(
GetServiceWorkerResponseFromWebResponse(web_response));
const mojom::ServiceWorkerFetchResponseCallbackPtr& response_callback =
context_->fetch_response_callbacks[fetch_event_id];
if (response.blob_uuid.size()) {
- // TODO(kinuko): Remove this hack once kMojoBlobs is enabled by default
- // and crbug.com/755523 is resolved.
- storage::mojom::BlobPtr blob_ptr;
+ blink::mojom::BlobPtr blob_ptr;
if (response.blob) {
blob_ptr = response.blob->TakeBlobPtr();
response.blob = nullptr;
+ response_callback->OnResponseBlob(
+ response, std::move(blob_ptr),
+ base::Time::FromDoubleT(event_dispatch_time));
} else {
- if (!blob_registry_) {
- // TODO(kinuko): We should use per-frame / per-worker InterfaceProvider
- // instead (crbug.com/734210).
- main_thread_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&GetBlobRegistry, MakeRequest(&blob_registry_)));
- }
- blob_registry_->GetBlobFromUUID(MakeRequest(&blob_ptr),
- response.blob_uuid);
+ // TODO(kinuko): Remove this hack once kMojoBlobs is enabled by default.
+ response_callback->OnResponseLegacyBlob(
+ response, base::Time::FromDoubleT(event_dispatch_time),
+ base::BindOnce(&OnResponseBlobDispatchDone, web_response));
}
- response_callback->OnResponseBlob(
- response, std::move(blob_ptr),
- base::Time::FromDoubleT(event_dispatch_time));
} else {
response_callback->OnResponse(response,
base::Time::FromDoubleT(event_dispatch_time));
@@ -1053,6 +1031,7 @@ void ServiceWorkerContextClient::RespondToFetchEventWithResponseStream(
const blink::WebServiceWorkerResponse& web_response,
blink::WebServiceWorkerStreamHandle* web_body_as_stream,
double event_dispatch_time) {
+ DCHECK(base::ContainsKey(context_->fetch_response_callbacks, fetch_event_id));
ServiceWorkerResponse response(
GetServiceWorkerResponseFromWebResponse(web_response));
const mojom::ServiceWorkerFetchResponseCallbackPtr& response_callback =
@@ -1065,7 +1044,7 @@ void ServiceWorkerContextClient::RespondToFetchEventWithResponseStream(
DCHECK(body_as_stream->stream.is_valid());
web_body_as_stream->SetListener(
- base::MakeUnique<StreamHandleListener>(std::move(callback_ptr)));
+ std::make_unique<StreamHandleListener>(std::move(callback_ptr)));
response_callback->OnResponseStream(
response, std::move(body_as_stream),
@@ -1074,79 +1053,62 @@ void ServiceWorkerContextClient::RespondToFetchEventWithResponseStream(
}
void ServiceWorkerContextClient::DidHandleFetchEvent(
- int fetch_event_id,
+ int event_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
// This TRACE_EVENT is used for perf benchmark to confirm if all of fetch
// events have completed. (crbug.com/736697)
TRACE_EVENT1("ServiceWorker",
"ServiceWorkerContextClient::DidHandleFetchEvent", "event_id",
- fetch_event_id);
- DispatchFetchEventCallback callback =
- std::move(context_->fetch_event_callbacks[fetch_event_id]);
- DCHECK(callback);
- std::move(callback).Run(status, base::Time::FromDoubleT(event_dispatch_time));
- context_->fetch_event_callbacks.erase(fetch_event_id);
+ event_id);
+ if (RunEventCallback(&context_->fetch_event_callbacks,
+ context_->timeout_timer.get(), event_id, status,
+ base::Time::FromDoubleT(event_dispatch_time))) {
+ context_->fetch_response_callbacks.erase(event_id);
+ }
}
void ServiceWorkerContextClient::DidHandleNotificationClickEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchNotificationClickEventCallback* callback =
- context_->notification_click_event_callbacks.Lookup(request_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status,
- base::Time::FromDoubleT(event_dispatch_time));
-
- context_->notification_click_event_callbacks.Remove(request_id);
+ RunEventCallback(&context_->notification_click_event_callbacks,
+ context_->timeout_timer.get(), request_id, status,
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::DidHandleNotificationCloseEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchNotificationCloseEventCallback* callback =
- context_->notification_close_event_callbacks.Lookup(request_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status,
- base::Time::FromDoubleT(event_dispatch_time));
-
- context_->notification_close_event_callbacks.Remove(request_id);
+ RunEventCallback(&context_->notification_close_event_callbacks,
+ context_->timeout_timer.get(), request_id, status,
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::DidHandlePushEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchPushEventCallback* callback =
- context_->push_event_callbacks.Lookup(request_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status,
- base::Time::FromDoubleT(event_dispatch_time));
- context_->push_event_callbacks.Remove(request_id);
+ RunEventCallback(&context_->push_event_callbacks,
+ context_->timeout_timer.get(), request_id, status,
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::DidHandleSyncEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchSyncEventCallback* callback =
- context_->sync_event_callbacks.Lookup(request_id);
- DCHECK(callback);
- DCHECK(*callback);
- std::move(*callback).Run(status,
- base::Time::FromDoubleT(event_dispatch_time));
- context_->sync_event_callbacks.Remove(request_id);
+ RunEventCallback(&context_->sync_event_callbacks,
+ context_->timeout_timer.get(), request_id, status,
+ base::Time::FromDoubleT(event_dispatch_time));
}
void ServiceWorkerContextClient::RespondToAbortPaymentEvent(
int event_id,
bool payment_aborted,
double dispatch_event_time) {
+ 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(
@@ -1158,16 +1120,19 @@ void ServiceWorkerContextClient::DidHandleAbortPaymentEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
double dispatch_event_time) {
- DispatchAbortPaymentEventCallback callback =
- std::move(context_->abort_payment_event_callbacks[event_id]);
- std::move(callback).Run(status, base::Time::FromDoubleT(dispatch_event_time));
- context_->abort_payment_event_callbacks.erase(event_id);
+ if (RunEventCallback(&context_->abort_payment_event_callbacks,
+ context_->timeout_timer.get(), event_id, status,
+ base::Time::FromDoubleT(dispatch_event_time))) {
+ context_->abort_payment_result_callbacks.erase(event_id);
+ }
}
void ServiceWorkerContextClient::RespondToCanMakePaymentEvent(
int event_id,
bool can_make_payment,
double dispatch_event_time) {
+ DCHECK(
+ 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(
@@ -1179,16 +1144,19 @@ void ServiceWorkerContextClient::DidHandleCanMakePaymentEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
double dispatch_event_time) {
- DispatchCanMakePaymentEventCallback callback =
- std::move(context_->can_make_payment_event_callbacks[event_id]);
- std::move(callback).Run(status, base::Time::FromDoubleT(dispatch_event_time));
- context_->can_make_payment_event_callbacks.erase(event_id);
+ if (RunEventCallback(&context_->can_make_payment_event_callbacks,
+ context_->timeout_timer.get(), event_id, status,
+ base::Time::FromDoubleT(dispatch_event_time))) {
+ context_->can_make_payment_result_callbacks.erase(event_id);
+ }
}
void ServiceWorkerContextClient::RespondToPaymentRequestEvent(
int payment_request_id,
const blink::WebPaymentHandlerResponse& web_response,
double dispatch_event_time) {
+ DCHECK(base::ContainsKey(context_->payment_response_callbacks,
+ payment_request_id));
const payments::mojom::PaymentHandlerResponseCallbackPtr& response_callback =
context_->payment_response_callbacks[payment_request_id];
payments::mojom::PaymentHandlerResponsePtr response =
@@ -1204,17 +1172,18 @@ void ServiceWorkerContextClient::DidHandlePaymentRequestEvent(
int payment_request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- DispatchPaymentRequestEventCallback callback =
- std::move(context_->payment_request_event_callbacks[payment_request_id]);
- std::move(callback).Run(status, base::Time::FromDoubleT(event_dispatch_time));
- context_->payment_request_event_callbacks.erase(payment_request_id);
+ if (RunEventCallback(&context_->payment_request_event_callbacks,
+ context_->timeout_timer.get(), payment_request_id,
+ status, base::Time::FromDoubleT(event_dispatch_time))) {
+ context_->payment_response_callbacks.erase(payment_request_id);
+ }
}
std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
ServiceWorkerContextClient::CreateServiceWorkerNetworkProvider() {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
// Blink is responsible for deleting the returned object.
- return base::MakeUnique<WebServiceWorkerNetworkProviderImpl>(
+ return std::make_unique<WebServiceWorkerNetworkProviderImpl>(
std::move(pending_network_provider_));
}
@@ -1229,7 +1198,7 @@ ServiceWorkerContextClient::CreateServiceWorkerFetchContext() {
->CreateDefaultURLLoaderFactoryGetter();
DCHECK(url_loader_factory_getter);
// Blink is responsible for deleting the returned object.
- return base::MakeUnique<ServiceWorkerFetchContextImpl>(
+ return std::make_unique<ServiceWorkerFetchContextImpl>(
script_url_, url_loader_factory_getter->GetClonedInfo(),
provider_context_->provider_id());
}
@@ -1240,7 +1209,7 @@ ServiceWorkerContextClient::CreateServiceWorkerProvider() {
DCHECK(provider_context_);
// Blink is responsible for deleting the returned object.
- return base::MakeUnique<WebServiceWorkerProviderImpl>(
+ return std::make_unique<WebServiceWorkerProviderImpl>(
sender_.get(), provider_context_.get());
}
@@ -1285,24 +1254,15 @@ void ServiceWorkerContextClient::Claim(
Send(new ServiceWorkerHostMsg_ClaimClients(GetRoutingID(), request_id));
}
-void ServiceWorkerContextClient::RegisterForeignFetchScopes(
- int install_event_id,
- const blink::WebVector<blink::WebURL>& sub_scopes,
- const blink::WebVector<blink::WebSecurityOrigin>& origins) {
- DCHECK(context_->install_methods_map[install_event_id].is_bound());
- context_->install_methods_map[install_event_id]->RegisterForeignFetchScopes(
- std::vector<GURL>(sub_scopes.begin(), sub_scopes.end()),
- std::vector<url::Origin>(origins.begin(), origins.end()));
-}
-
void ServiceWorkerContextClient::DispatchSyncEvent(
const std::string& tag,
blink::mojom::BackgroundSyncEventLastChance last_chance,
DispatchSyncEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchSyncEvent");
- int request_id = context_->sync_event_callbacks.Add(
- base::MakeUnique<DispatchSyncEventCallback>(std::move(callback)));
+ int request_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->sync_event_callbacks));
+ context_->sync_event_callbacks.emplace(request_id, std::move(callback));
// TODO(shimazu): Use typemap when this is moved to blink-side.
blink::WebServiceWorkerContextProxy::LastChanceOption web_last_chance =
@@ -1316,29 +1276,33 @@ void ServiceWorkerContextClient::DispatchSyncEvent(
}
void ServiceWorkerContextClient::DispatchAbortPaymentEvent(
- int event_id,
+ int /* event_id */, // TODO(shimazu): Remove this.
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchAbortPaymentEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchAbortPaymentEvent");
- context_->abort_payment_result_callbacks.insert(
- std::make_pair(event_id, std::move(response_callback)));
- context_->abort_payment_event_callbacks.insert(
- std::make_pair(event_id, std::move(callback)));
+ int event_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->abort_payment_event_callbacks));
+ context_->abort_payment_event_callbacks.emplace(event_id,
+ std::move(callback));
+ context_->abort_payment_result_callbacks.emplace(
+ event_id, std::move(response_callback));
proxy_->DispatchAbortPaymentEvent(event_id);
}
void ServiceWorkerContextClient::DispatchCanMakePaymentEvent(
- int event_id,
+ int /* event_id */, // TODO(shimazu): Remove this.
payments::mojom::CanMakePaymentEventDataPtr eventData,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchCanMakePaymentEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchCanMakePaymentEvent");
- context_->can_make_payment_result_callbacks.insert(
- std::make_pair(event_id, std::move(response_callback)));
- context_->can_make_payment_event_callbacks.insert(
- std::make_pair(event_id, std::move(callback)));
+ int event_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->can_make_payment_event_callbacks));
+ context_->can_make_payment_event_callbacks.emplace(event_id,
+ std::move(callback));
+ context_->can_make_payment_result_callbacks.emplace(
+ event_id, std::move(response_callback));
blink::WebCanMakePaymentEventData webEventData =
mojo::ConvertTo<blink::WebCanMakePaymentEventData>(std::move(eventData));
@@ -1346,20 +1310,22 @@ void ServiceWorkerContextClient::DispatchCanMakePaymentEvent(
}
void ServiceWorkerContextClient::DispatchPaymentRequestEvent(
- int payment_request_id,
+ int /* payment_request_id */, // TODO(shimazu): Remove this.
payments::mojom::PaymentRequestEventDataPtr eventData,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchPaymentRequestEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchPaymentRequestEvent");
- context_->payment_response_callbacks.insert(
- std::make_pair(payment_request_id, std::move(response_callback)));
- context_->payment_request_event_callbacks.insert(
- std::make_pair(payment_request_id, std::move(callback)));
+ int event_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->payment_request_event_callbacks));
+ context_->payment_request_event_callbacks.emplace(event_id,
+ std::move(callback));
+ context_->payment_response_callbacks.emplace(event_id,
+ std::move(response_callback));
blink::WebPaymentRequestEventData webEventData =
mojo::ConvertTo<blink::WebPaymentRequestEventData>(std::move(eventData));
- proxy_->DispatchPaymentRequestEvent(payment_request_id, webEventData);
+ proxy_->DispatchPaymentRequestEvent(event_id, webEventData);
}
void ServiceWorkerContextClient::Send(IPC::Message* message) {
@@ -1375,31 +1341,20 @@ void ServiceWorkerContextClient::SendWorkerStarted() {
(*instance_host_)->OnStarted(std::move(timing));
TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "ServiceWorkerContextClient",
this);
-}
-void ServiceWorkerContextClient::SetRegistrationInServiceWorkerGlobalScope(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
- const ServiceWorkerVersionAttributes& attrs) {
- DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
- sender_.get(), main_thread_task_runner_.get());
-
- // Register a registration and its version attributes with the dispatcher
- // living on the worker thread.
- scoped_refptr<WebServiceWorkerRegistrationImpl> registration(
- dispatcher->GetOrCreateRegistration(std::move(info), attrs));
-
- proxy_->SetRegistration(
- WebServiceWorkerRegistrationImpl::CreateHandle(registration));
+ // Start the idle timer.
+ context_->timeout_timer =
+ std::make_unique<ServiceWorkerTimeoutTimer>(base::BindRepeating(
+ &ServiceWorkerContextClient::OnIdle, base::Unretained(this)));
}
void ServiceWorkerContextClient::DispatchActivateEvent(
DispatchActivateEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchActivateEvent");
- int request_id = context_->activate_event_callbacks.Add(
- base::MakeUnique<DispatchActivateEventCallback>(std::move(callback)));
+ int request_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->activate_event_callbacks));
+ context_->activate_event_callbacks.emplace(request_id, std::move(callback));
proxy_->DispatchActivateEvent(request_id);
}
@@ -1408,10 +1363,10 @@ void ServiceWorkerContextClient::DispatchBackgroundFetchAbortEvent(
DispatchBackgroundFetchAbortEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchBackgroundFetchAbortEvent");
- int request_id = context_->background_fetch_abort_event_callbacks.Add(
- base::MakeUnique<DispatchBackgroundFetchAbortEventCallback>(
- std::move(callback)));
-
+ int request_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->background_fetch_abort_event_callbacks));
+ context_->background_fetch_abort_event_callbacks.emplace(request_id,
+ std::move(callback));
proxy_->DispatchBackgroundFetchAbortEvent(
request_id, blink::WebString::FromUTF8(developer_id));
}
@@ -1422,15 +1377,15 @@ void ServiceWorkerContextClient::DispatchBackgroundFetchClickEvent(
DispatchBackgroundFetchClickEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchBackgroundFetchClickEvent");
- int request_id = context_->background_fetch_click_event_callbacks.Add(
- base::MakeUnique<DispatchBackgroundFetchClickEventCallback>(
- std::move(callback)));
+ int request_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->background_fetch_click_event_callbacks));
+ context_->background_fetch_click_event_callbacks.emplace(request_id,
+ std::move(callback));
// TODO(peter): Use typemap when this is moved to blink-side.
blink::WebServiceWorkerContextProxy::BackgroundFetchState web_state =
mojo::ConvertTo<
blink::WebServiceWorkerContextProxy::BackgroundFetchState>(state);
-
proxy_->DispatchBackgroundFetchClickEvent(
request_id, blink::WebString::FromUTF8(developer_id), web_state);
}
@@ -1441,9 +1396,10 @@ void ServiceWorkerContextClient::DispatchBackgroundFetchFailEvent(
DispatchBackgroundFetchFailEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchBackgroundFetchFailEvent");
- int request_id = context_->background_fetch_fail_event_callbacks.Add(
- base::MakeUnique<DispatchBackgroundFetchFailEventCallback>(
- std::move(callback)));
+ int request_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->background_fetch_fail_event_callbacks));
+ context_->background_fetch_fail_event_callbacks.emplace(request_id,
+ std::move(callback));
blink::WebVector<blink::WebBackgroundFetchSettledFetch> web_fetches(
fetches.size());
@@ -1463,9 +1419,10 @@ void ServiceWorkerContextClient::DispatchBackgroundFetchedEvent(
DispatchBackgroundFetchedEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchBackgroundFetchedEvent");
- int request_id = context_->background_fetched_event_callbacks.Add(
- base::MakeUnique<DispatchBackgroundFetchedEventCallback>(
- std::move(callback)));
+ int request_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->background_fetched_event_callbacks));
+ context_->background_fetched_event_callbacks.emplace(request_id,
+ std::move(callback));
blink::WebVector<blink::WebBackgroundFetchSettledFetch> web_fetches(
fetches.size());
@@ -1480,19 +1437,13 @@ void ServiceWorkerContextClient::DispatchBackgroundFetchedEvent(
}
void ServiceWorkerContextClient::DispatchInstallEvent(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client,
DispatchInstallEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchInstallEvent");
- int event_id = context_->install_event_callbacks.Add(
- base::MakeUnique<DispatchInstallEventCallback>(std::move(callback)));
-
- DCHECK(!context_->install_methods_map.count(event_id));
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtr install_methods;
- install_methods.Bind(std::move(client));
- context_->install_methods_map[event_id] = std::move(install_methods);
-
+ int event_id = context_->timeout_timer->StartEvent(
+ CreateInstallEventAbortCallback(&context_->install_event_callbacks));
+ context_->install_event_callbacks.emplace(event_id, std::move(callback));
proxy_->DispatchInstallEvent(event_id);
}
@@ -1501,9 +1452,9 @@ void ServiceWorkerContextClient::DispatchExtendableMessageEvent(
DispatchExtendableMessageEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchExtendableMessageEvent");
- int request_id = context_->message_event_callbacks.Add(
- base::MakeUnique<DispatchExtendableMessageEventCallback>(
- std::move(callback)));
+ int request_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->message_event_callbacks));
+ context_->message_event_callbacks.emplace(request_id, std::move(callback));
if (event->source.client_info.IsValid()) {
blink::WebServiceWorkerClientInfo web_client =
@@ -1516,10 +1467,13 @@ void ServiceWorkerContextClient::DispatchExtendableMessageEvent(
return;
}
- DCHECK(event->source.service_worker_info.IsValid());
+ DCHECK(event->source.service_worker_info.handle_id !=
+ blink::mojom::kInvalidServiceWorkerHandleId &&
+ event->source.service_worker_info.version_id !=
+ blink::mojom::kInvalidServiceWorkerVersionId);
std::unique_ptr<ServiceWorkerHandleReference> handle =
- ServiceWorkerHandleReference::Adopt(event->source.service_worker_info,
- sender_.get());
+ ServiceWorkerHandleReference::Adopt(
+ event->source.service_worker_info.Clone(), sender_);
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
sender_.get(), main_thread_task_runner_.get());
@@ -1532,41 +1486,64 @@ void ServiceWorkerContextClient::DispatchExtendableMessageEvent(
WebServiceWorkerImpl::CreateHandle(worker));
}
-void ServiceWorkerContextClient::DispatchFetchEvent(
- int fetch_event_id,
+// Non-S13nServiceWorker
+void ServiceWorkerContextClient::DispatchLegacyFetchEvent(
const ServiceWorkerFetchRequest& request,
mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- DispatchFetchEventCallback callback) {
+ DispatchLegacyFetchEventCallback callback) {
+ int event_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->fetch_event_callbacks));
+ context_->fetch_event_callbacks.emplace(event_id, std::move(callback));
+ context_->fetch_response_callbacks.emplace(event_id,
+ std::move(response_callback));
+
// This TRACE_EVENT is used for perf benchmark to confirm if all of fetch
// events have completed. (crbug.com/736697)
TRACE_EVENT1("ServiceWorker",
"ServiceWorkerContextClient::DispatchFetchEvent", "event_id",
- fetch_event_id);
- std::unique_ptr<NavigationPreloadRequest> preload_request =
- preload_handle
- ? base::MakeUnique<NavigationPreloadRequest>(
- fetch_event_id, request.url, std::move(preload_handle))
- : nullptr;
- const bool navigation_preload_sent = !!preload_request;
- context_->fetch_response_callbacks.insert(
- std::make_pair(fetch_event_id, std::move(response_callback)));
- context_->fetch_event_callbacks.insert(
- std::make_pair(fetch_event_id, std::move(callback)));
- if (preload_request) {
- context_->preload_requests.AddWithID(std::move(preload_request),
- fetch_event_id);
+ event_id);
+
+ // Set up for navigation preload (FetchEvent#preloadResponse) if needed.
+ const bool navigation_preload_sent = !!preload_handle;
+ if (navigation_preload_sent) {
+ SetupNavigationPreload(event_id, request.url, std::move(preload_handle));
}
+ // Dispatch the event to the service worker execution context.
blink::WebServiceWorkerRequest web_request;
ToWebServiceWorkerRequest(request, &web_request);
+ proxy_->DispatchFetchEvent(event_id, web_request, navigation_preload_sent);
+}
- if (request.fetch_type == ServiceWorkerFetchType::FOREIGN_FETCH) {
- proxy_->DispatchForeignFetchEvent(fetch_event_id, web_request);
- } else {
- proxy_->DispatchFetchEvent(fetch_event_id, web_request,
- navigation_preload_sent);
+// S13nServiceWorker
+void ServiceWorkerContextClient::DispatchFetchEvent(
+ const ResourceRequest& request,
+ mojom::FetchEventPreloadHandlePtr preload_handle,
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ DispatchFetchEventCallback callback) {
+ int event_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->fetch_event_callbacks));
+ context_->fetch_event_callbacks.emplace(event_id, std::move(callback));
+ context_->fetch_response_callbacks.emplace(event_id,
+ std::move(response_callback));
+
+ // This TRACE_EVENT is used for perf benchmark to confirm if all of fetch
+ // events have completed. (crbug.com/736697)
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchFetchEvent", "event_id",
+ event_id);
+
+ // Set up for navigation preload (FetchEvent#preloadResponse) if needed.
+ const bool navigation_preload_sent = !!preload_handle;
+ if (navigation_preload_sent) {
+ SetupNavigationPreload(event_id, request.url, std::move(preload_handle));
}
+
+ // Dispatch the event to the service worker execution context.
+ blink::WebServiceWorkerRequest web_request;
+ ToWebServiceWorkerRequest(request, &web_request);
+ proxy_->DispatchFetchEvent(event_id, web_request, navigation_preload_sent);
}
void ServiceWorkerContextClient::DispatchNotificationClickEvent(
@@ -1578,9 +1555,10 @@ void ServiceWorkerContextClient::DispatchNotificationClickEvent(
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchNotificationClickEvent");
- int request_id = context_->notification_click_event_callbacks.Add(
- base::MakeUnique<DispatchNotificationClickEventCallback>(
- std::move(callback)));
+ int request_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->notification_click_event_callbacks));
+ context_->notification_click_event_callbacks.emplace(request_id,
+ std::move(callback));
blink::WebString web_reply;
if (reply)
@@ -1598,10 +1576,10 @@ void ServiceWorkerContextClient::DispatchNotificationCloseEvent(
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchNotificationCloseEvent");
- int request_id = context_->notification_close_event_callbacks.Add(
- base::MakeUnique<DispatchNotificationCloseEventCallback>(
- std::move(callback)));
-
+ int request_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->notification_close_event_callbacks));
+ context_->notification_close_event_callbacks.emplace(request_id,
+ std::move(callback));
proxy_->DispatchNotificationCloseEvent(
request_id, blink::WebString::FromUTF8(notification_id),
ToWebNotificationData(notification_data));
@@ -1612,13 +1590,15 @@ void ServiceWorkerContextClient::DispatchPushEvent(
DispatchPushEventCallback callback) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerContextClient::DispatchPushEvent");
- int request_id = context_->push_event_callbacks.Add(
- base::MakeUnique<DispatchPushEventCallback>(std::move(callback)));
+
+ int request_id = context_->timeout_timer->StartEvent(
+ CreateAbortCallback(&context_->push_event_callbacks));
+ context_->push_event_callbacks.emplace(request_id, std::move(callback));
// Only set data to be a valid string if the payload had decrypted data.
blink::WebString data;
if (!payload.is_null)
- data.Assign(blink::WebString::FromUTF8(payload.data));
+ data = blink::WebString::FromUTF8(payload.data);
proxy_->DispatchPushEvent(request_id, data);
}
@@ -1837,6 +1817,22 @@ void ServiceWorkerContextClient::OnNavigationPreloadComplete(
context_->preload_requests.Remove(fetch_event_id);
}
+void ServiceWorkerContextClient::SetupNavigationPreload(
+ int fetch_event_id,
+ const GURL& url,
+ mojom::FetchEventPreloadHandlePtr preload_handle) {
+ auto preload_request = std::make_unique<NavigationPreloadRequest>(
+ fetch_event_id, url, std::move(preload_handle));
+ context_->preload_requests.AddWithID(std::move(preload_request),
+ fetch_event_id);
+}
+
+void ServiceWorkerContextClient::OnIdle() {
+ // TODO(crbug.com/774374): Ignore events from clients after this point until
+ // an event from the browser process or StopWorker() is received.
+ (*instance_host_)->RequestTermination();
+}
+
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 42ea9c9515b..07e243c932e 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_client.h
+++ b/chromium/content/renderer/service_worker/service_worker_context_client.h
@@ -19,6 +19,7 @@
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
+#include "content/common/service_worker/controller_service_worker.mojom.h"
#include "content/common/service_worker/embedded_worker.mojom.h"
#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
@@ -27,9 +28,10 @@
#include "content/public/common/service_worker_modes.h"
#include "ipc/ipc_listener.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "storage/public/interfaces/blobs.mojom.h"
+#include "third_party/WebKit/common/blob/blob_registry.mojom.h"
#include "third_party/WebKit/public/platform/modules/payments/payment_app.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
#include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h"
@@ -71,8 +73,8 @@ class WebWorkerFetchContext;
// starting up, and destroyed when the service worker stops. It is owned by
// EmbeddedWorkerInstanceClientImpl's internal WorkerWrapper class.
//
-// Unless otherwise noted (here or in the superclass documentation), all methods
-// are called on the worker thread.
+// Unless otherwise noted (here or in base class documentation), all methods are
+// called on the worker thread.
class ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient,
public mojom::ServiceWorkerEventDispatcher {
public:
@@ -90,6 +92,8 @@ class ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient,
const GURL& script_url,
bool is_script_streaming,
mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ControllerServiceWorkerRequest controller_request,
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
std::unique_ptr<EmbeddedWorkerInstanceClientImpl> embedded_worker_client);
@@ -109,7 +113,6 @@ class ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient,
const IPC::Message& message);
// WebServiceWorkerContextClient overrides.
- blink::WebURL Scope() const override;
void GetClient(
const blink::WebString& client_id,
std::unique_ptr<blink::WebServiceWorkerClientCallbacks>) override;
@@ -245,14 +248,11 @@ class ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient,
callbacks) override;
void Claim(std::unique_ptr<blink::WebServiceWorkerClientsClaimCallbacks>
callbacks) override;
- void RegisterForeignFetchScopes(
- int install_event_id,
- const blink::WebVector<blink::WebURL>& sub_scopes,
- const blink::WebVector<blink::WebSecurityOrigin>& origins) override;
private:
struct WorkerContextData;
class NavigationPreloadRequest;
+ friend class ControllerServiceWorkerImpl;
// Get routing_id for sending message to the ServiceWorkerVersion
// in the browser process.
@@ -260,13 +260,9 @@ class ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient,
void Send(IPC::Message* message);
void SendWorkerStarted();
- void SetRegistrationInServiceWorkerGlobalScope(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
- const ServiceWorkerVersionAttributes& attrs);
// mojom::ServiceWorkerEventDispatcher
void DispatchInstallEvent(
- mojom::ServiceWorkerInstallEventMethodsAssociatedPtrInfo client,
DispatchInstallEventCallback callback) override;
void DispatchActivateEvent(DispatchActivateEventCallback callback) override;
void DispatchBackgroundFetchAbortEvent(
@@ -288,12 +284,16 @@ class ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient,
void DispatchExtendableMessageEvent(
mojom::ExtendableMessageEventPtr event,
DispatchExtendableMessageEventCallback callback) override;
- void DispatchFetchEvent(
- int fetch_event_id,
+ void DispatchLegacyFetchEvent(
const ServiceWorkerFetchRequest& request,
mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) override;
+ void DispatchFetchEvent(
+ const ResourceRequest& request,
+ mojom::FetchEventPreloadHandlePtr preload_handle,
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ DispatchFetchEventCallback callback) override;
void DispatchNotificationClickEvent(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
@@ -359,8 +359,8 @@ class ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient,
std::unique_ptr<blink::WebURLResponse> response,
std::unique_ptr<blink::WebDataConsumerHandle> data_consumer_handle);
// Called when the navigation preload request completed. Either
- // OnNavigationPreloadComplete() or OnNavigationPreloadError() must be called
- // to release the preload related resources.
+ // OnNavigationPreloadComplete() or OnNavigationPreloadError() must be
+ // called to release the preload related resources.
void OnNavigationPreloadComplete(int fetch_event_id,
base::TimeTicks completion_time,
int64_t encoded_data_length,
@@ -372,6 +372,13 @@ class ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient,
int fetch_event_id,
std::unique_ptr<blink::WebServiceWorkerError> error);
+ void SetupNavigationPreload(int fetch_event_id,
+ const GURL& url,
+ mojom::FetchEventPreloadHandlePtr preload_handle);
+
+ // Called when a certain time has passed since the last task finished.
+ void OnIdle();
+
base::WeakPtr<ServiceWorkerContextClient> GetWeakPtr();
const int embedded_worker_id_;
@@ -381,29 +388,31 @@ class ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient,
scoped_refptr<ThreadSafeSender> sender_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;
scoped_refptr<base::TaskRunner> worker_task_runner_;
scoped_refptr<ServiceWorkerProviderContext> provider_context_;
- // Not owned; this object is destroyed when proxy_ becomes invalid.
+ // Not owned; |this| is destroyed when |proxy_| becomes invalid.
blink::WebServiceWorkerContextProxy* proxy_;
- // This is bound on the worker thread.
+ // These Mojo objects are bound on the worker thread.
mojom::ServiceWorkerEventDispatcherRequest pending_dispatcher_request_;
+ mojom::ControllerServiceWorkerRequest pending_controller_request_;
+ blink::mojom::ServiceWorkerHostAssociatedPtrInfo pending_service_worker_host_;
// This is bound on the main thread.
scoped_refptr<mojom::ThreadSafeEmbeddedWorkerInstanceHostAssociatedPtr>
instance_host_;
// This is passed to ServiceWorkerNetworkProvider when
- // createServiceWorkerNetworkProvider is called.
+ // CreateServiceWorkerNetworkProvider is called.
std::unique_ptr<ServiceWorkerNetworkProvider> pending_network_provider_;
- // Renderer-side object corresponding to WebEmbeddedWorkerInstance.
- // This is valid from the ctor to workerContextDestroyed.
+ // This is valid from the ctor to WorkerContextDestroyed.
std::unique_ptr<EmbeddedWorkerInstanceClientImpl> embedded_worker_client_;
- storage::mojom::BlobRegistryPtr blob_registry_;
+ blink::mojom::BlobRegistryPtr blob_registry_;
// Initialized on the worker thread in workerContextStarted and
// destructed on the worker thread in willDestroyWorkerContext.
diff --git a/chromium/content/renderer/service_worker/service_worker_context_message_filter.h b/chromium/content/renderer/service_worker/service_worker_context_message_filter.h
index 5ed6c46e512..6f32206ec31 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_message_filter.h
+++ b/chromium/content/renderer/service_worker/service_worker_context_message_filter.h
@@ -6,7 +6,7 @@
#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_MESSAGE_FILTER_H_
#include "base/macros.h"
-#include "content/child/worker_thread_message_filter.h"
+#include "content/renderer/worker_thread_message_filter.h"
namespace content {
diff --git a/chromium/content/renderer/service_worker/service_worker_dispatcher.cc b/chromium/content/renderer/service_worker/service_worker_dispatcher.cc
new file mode 100644
index 00000000000..1da3370eec8
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_dispatcher.cc
@@ -0,0 +1,141 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/service_worker/service_worker_dispatcher.h"
+
+#include <stddef.h>
+#include <utility>
+
+#include "base/lazy_instance.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+#include "base/stl_util.h"
+#include "base/threading/thread_local.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/trace_event/trace_event.h"
+#include "content/common/service_worker/service_worker_messages.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/common/content_constants.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.h"
+#include "content/renderer/service_worker/service_worker_provider_context.h"
+#include "content/renderer/service_worker/web_service_worker_impl.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+#include "url/url_constants.h"
+
+using blink::WebServiceWorkerError;
+using blink::WebServiceWorkerProvider;
+using base::ThreadLocalPointer;
+
+namespace content {
+
+namespace {
+
+base::LazyInstance<ThreadLocalPointer<void>>::Leaky g_dispatcher_tls =
+ LAZY_INSTANCE_INITIALIZER;
+
+void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1);
+
+} // namespace
+
+ServiceWorkerDispatcher::ServiceWorkerDispatcher(
+ ThreadSafeSender* thread_safe_sender,
+ base::SingleThreadTaskRunner* main_thread_task_runner)
+ : thread_safe_sender_(thread_safe_sender),
+ main_thread_task_runner_(main_thread_task_runner) {
+ g_dispatcher_tls.Pointer()->Set(static_cast<void*>(this));
+}
+
+ServiceWorkerDispatcher::~ServiceWorkerDispatcher() {
+ g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
+}
+
+void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) {
+ bool handled = true;
+
+ // When you add a new message handler, you should consider adding a similar
+ // handler in ServiceWorkerMessageFilter to release references passed from
+ // the browser process in case we fail to post task to the thread.
+ IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg)
+ IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged,
+ OnServiceWorkerStateChanged)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ DCHECK(handled) << "Unhandled message:" << msg.type();
+}
+
+ServiceWorkerDispatcher*
+ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
+ ThreadSafeSender* thread_safe_sender,
+ base::SingleThreadTaskRunner* main_thread_task_runner) {
+ if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
+ NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher.";
+ g_dispatcher_tls.Pointer()->Set(nullptr);
+ }
+ if (g_dispatcher_tls.Pointer()->Get())
+ return static_cast<ServiceWorkerDispatcher*>(
+ g_dispatcher_tls.Pointer()->Get());
+
+ ServiceWorkerDispatcher* dispatcher =
+ new ServiceWorkerDispatcher(thread_safe_sender, main_thread_task_runner);
+ if (WorkerThread::GetCurrentId())
+ WorkerThread::AddObserver(dispatcher);
+ return dispatcher;
+}
+
+ServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() {
+ if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted)
+ return nullptr;
+ return static_cast<ServiceWorkerDispatcher*>(
+ g_dispatcher_tls.Pointer()->Get());
+}
+
+void ServiceWorkerDispatcher::WillStopCurrentWorkerThread() {
+ delete this;
+}
+
+scoped_refptr<WebServiceWorkerImpl>
+ServiceWorkerDispatcher::GetOrCreateServiceWorker(
+ std::unique_ptr<ServiceWorkerHandleReference> handle_ref) {
+ if (!handle_ref)
+ return nullptr;
+
+ WorkerObjectMap::iterator found =
+ service_workers_.find(handle_ref->handle_id());
+ if (found != service_workers_.end())
+ return found->second;
+
+ // WebServiceWorkerImpl constructor calls AddServiceWorker.
+ return new WebServiceWorkerImpl(std::move(handle_ref),
+ thread_safe_sender_.get());
+}
+
+void ServiceWorkerDispatcher::OnServiceWorkerStateChanged(
+ int thread_id,
+ int handle_id,
+ blink::mojom::ServiceWorkerState state) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerDispatcher::OnServiceWorkerStateChanged",
+ "Thread ID", thread_id,
+ "State", static_cast<int>(state));
+ WorkerObjectMap::iterator worker = service_workers_.find(handle_id);
+ if (worker != service_workers_.end())
+ worker->second->OnStateChanged(state);
+}
+
+void ServiceWorkerDispatcher::AddServiceWorker(
+ int handle_id, WebServiceWorkerImpl* worker) {
+ DCHECK(!base::ContainsKey(service_workers_, handle_id));
+ service_workers_[handle_id] = worker;
+}
+
+void ServiceWorkerDispatcher::RemoveServiceWorker(int handle_id) {
+ DCHECK(base::ContainsKey(service_workers_, handle_id));
+ service_workers_.erase(handle_id);
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_dispatcher.h b/chromium/content/renderer/service_worker/service_worker_dispatcher.h
new file mode 100644
index 00000000000..1e03c84b539
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_dispatcher.h
@@ -0,0 +1,104 @@
+// 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_SERVICE_WORKER_DISPATCHER_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+#include <set>
+#include <vector>
+
+#include "base/containers/id_map.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/strings/string16.h"
+#include "content/child/thread_safe_sender.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/renderer/worker_thread.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProvider.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_state.mojom.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace IPC {
+class Message;
+}
+
+namespace content {
+
+class ServiceWorkerHandleReference;
+class ThreadSafeSender;
+class WebServiceWorkerImpl;
+
+// This class manages communication with the browser process about
+// registration of the service worker, exposed to renderer and worker
+// scripts through methods like navigator.registerServiceWorker().
+class CONTENT_EXPORT ServiceWorkerDispatcher : public WorkerThread::Observer {
+ public:
+ ServiceWorkerDispatcher(
+ ThreadSafeSender* thread_safe_sender,
+ base::SingleThreadTaskRunner* main_thread_task_runner);
+ ~ServiceWorkerDispatcher() override;
+
+ void OnMessageReceived(const IPC::Message& msg);
+
+ // Returns the existing service worker or a newly created one with the given
+ // handle reference. Returns nullptr if the given reference is invalid.
+ scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorker(
+ std::unique_ptr<ServiceWorkerHandleReference> handle_ref);
+
+ static ServiceWorkerDispatcher* GetOrCreateThreadSpecificInstance(
+ ThreadSafeSender* thread_safe_sender,
+ base::SingleThreadTaskRunner* main_thread_task_runner);
+
+ // Unlike GetOrCreateThreadSpecificInstance() this doesn't create a new
+ // instance if thread-local instance doesn't exist.
+ static ServiceWorkerDispatcher* GetThreadSpecificInstance();
+
+ base::SingleThreadTaskRunner* main_thread_task_runner() {
+ return main_thread_task_runner_.get();
+ }
+
+ scoped_refptr<ThreadSafeSender> thread_safe_sender() {
+ return thread_safe_sender_;
+ }
+
+ private:
+ using WorkerObjectMap = std::map<int, WebServiceWorkerImpl*>;
+
+ friend class ServiceWorkerDispatcherTest;
+ friend class WebServiceWorkerImpl;
+
+ // WorkerThread::Observer implementation.
+ void WillStopCurrentWorkerThread() override;
+
+ void OnServiceWorkerStateChanged(int thread_id,
+ int handle_id,
+ blink::mojom::ServiceWorkerState state);
+
+ // Keeps map from handle_id to ServiceWorker object.
+ void AddServiceWorker(int handle_id, WebServiceWorkerImpl* worker);
+ void RemoveServiceWorker(int handle_id);
+
+ WorkerObjectMap service_workers_;
+
+ scoped_refptr<ThreadSafeSender> thread_safe_sender_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcher);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
diff --git a/chromium/content/renderer/service_worker/service_worker_dispatcher_unittest.cc b/chromium/content/renderer/service_worker/service_worker_dispatcher_unittest.cc
new file mode 100644
index 00000000000..918631cf0d1
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_dispatcher_unittest.cc
@@ -0,0 +1,199 @@
+// 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/renderer/service_worker/service_worker_dispatcher.h"
+
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "content/child/thread_safe_sender.h"
+#include "content/common/service_worker/service_worker_container.mojom.h"
+#include "content/common/service_worker/service_worker_messages.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.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/web_service_worker_registration_impl.h"
+#include "ipc/ipc_sync_message_filter.h"
+#include "ipc/ipc_test_sink.h"
+#include "mojo/public/cpp/bindings/associated_binding_set.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+
+namespace content {
+
+namespace {
+
+class MockServiceWorkerRegistrationObjectHost
+ : public blink::mojom::ServiceWorkerRegistrationObjectHost {
+ public:
+ MockServiceWorkerRegistrationObjectHost() {
+ bindings_.set_connection_error_handler(
+ base::Bind(&MockServiceWorkerRegistrationObjectHost::OnConnectionError,
+ base::Unretained(this)));
+ }
+ ~MockServiceWorkerRegistrationObjectHost() override = default;
+
+ void AddBinding(
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedRequest
+ request) {
+ bindings_.AddBinding(this, std::move(request));
+ }
+
+ blink::mojom::ServiceWorkerRegistrationObjectAssociatedRequest
+ CreateRegistrationObjectRequest() {
+ if (!remote_registration_)
+ return mojo::MakeRequest(&remote_registration_);
+ return nullptr;
+ }
+
+ int GetBindingCount() const { return bindings_.size(); }
+
+ private:
+ // Implements blink::mojom::ServiceWorkerRegistrationObjectHost.
+ void Update(UpdateCallback callback) override {
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+ }
+ void Unregister(UnregisterCallback callback) override {
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+ }
+ void EnableNavigationPreload(
+ bool enable,
+ EnableNavigationPreloadCallback callback) override {
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+ }
+ void GetNavigationPreloadState(
+ GetNavigationPreloadStateCallback callback) override {
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt, nullptr);
+ }
+ void SetNavigationPreloadHeader(
+ const std::string& value,
+ SetNavigationPreloadHeaderCallback callback) override {
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+ }
+
+ void OnConnectionError() {
+ // If there are still bindings, |this| is still being used.
+ if (!bindings_.empty())
+ return;
+ // Will destroy corresponding remote WebServiceWorkerRegistrationImpl
+ // instance.
+ remote_registration_.reset();
+ }
+
+ mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerRegistrationObjectHost>
+ bindings_;
+ blink::mojom::ServiceWorkerRegistrationObjectAssociatedPtr
+ remote_registration_;
+};
+
+class ServiceWorkerTestSender : public ThreadSafeSender {
+ public:
+ explicit ServiceWorkerTestSender(IPC::TestSink* ipc_sink)
+ : ThreadSafeSender(nullptr, nullptr),
+ ipc_sink_(ipc_sink) {}
+
+ bool Send(IPC::Message* message) override {
+ return ipc_sink_->Send(message);
+ }
+
+ private:
+ ~ServiceWorkerTestSender() override {}
+
+ IPC::TestSink* ipc_sink_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTestSender);
+};
+
+} // namespace
+
+class ServiceWorkerDispatcherTest : public testing::Test {
+ public:
+ ServiceWorkerDispatcherTest() {}
+
+ void SetUp() override {
+ sender_ = new ServiceWorkerTestSender(&ipc_sink_);
+ dispatcher_.reset(new ServiceWorkerDispatcher(sender_.get(), nullptr));
+ }
+
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
+ CreateServiceWorkerRegistrationObjectInfo() {
+ auto info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New();
+ info->registration_id = 20;
+ remote_registration_object_host_.AddBinding(
+ mojo::MakeRequest(&info->host_ptr_info));
+ info->request =
+ remote_registration_object_host_.CreateRegistrationObjectRequest();
+
+ info->active = blink::mojom::ServiceWorkerObjectInfo::New();
+ info->active->handle_id = 100;
+ info->active->version_id = 200;
+ info->waiting = blink::mojom::ServiceWorkerObjectInfo::New();
+ info->waiting->handle_id = 101;
+ info->waiting->version_id = 201;
+ info->installing = blink::mojom::ServiceWorkerObjectInfo::New();
+ info->installing->handle_id = 102;
+ info->installing->version_id = 202;
+ return info;
+ }
+
+ bool ContainsServiceWorker(int handle_id) {
+ return ContainsKey(dispatcher_->service_workers_, handle_id);
+ }
+
+ std::unique_ptr<ServiceWorkerHandleReference> Adopt(
+ blink::mojom::ServiceWorkerObjectInfoPtr info) {
+ return ServiceWorkerHandleReference::Adopt(
+ std::move(info), dispatcher_->thread_safe_sender());
+ }
+
+ ServiceWorkerDispatcher* dispatcher() { return dispatcher_.get(); }
+ ThreadSafeSender* thread_safe_sender() { return sender_.get(); }
+ IPC::TestSink* ipc_sink() { return &ipc_sink_; }
+
+ private:
+ base::MessageLoop message_loop_;
+ IPC::TestSink ipc_sink_;
+ std::unique_ptr<ServiceWorkerDispatcher> dispatcher_;
+ scoped_refptr<ServiceWorkerTestSender> sender_;
+ MockServiceWorkerRegistrationObjectHost remote_registration_object_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcherTest);
+};
+
+TEST_F(ServiceWorkerDispatcherTest, GetServiceWorker) {
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ CreateServiceWorkerRegistrationObjectInfo();
+
+ // Should return a worker object newly created with the given reference.
+ scoped_refptr<WebServiceWorkerImpl> worker(
+ dispatcher()->GetOrCreateServiceWorker(Adopt(info->installing->Clone())));
+ EXPECT_TRUE(worker);
+ EXPECT_TRUE(ContainsServiceWorker(info->installing->handle_id));
+ EXPECT_EQ(0UL, ipc_sink()->message_count());
+
+ // Should return the same worker object and release the given reference.
+ scoped_refptr<WebServiceWorkerImpl> existing_worker =
+ dispatcher()->GetOrCreateServiceWorker(
+ Adopt(std::move(info->installing)));
+ EXPECT_EQ(worker, existing_worker);
+ ASSERT_EQ(1UL, ipc_sink()->message_count());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(0)->type());
+ ipc_sink()->ClearMessages();
+
+ // Should return nullptr when a given object is invalid.
+ scoped_refptr<WebServiceWorkerImpl> invalid_worker =
+ dispatcher()->GetOrCreateServiceWorker(
+ Adopt(blink::mojom::ServiceWorkerObjectInfo::New()));
+ EXPECT_FALSE(invalid_worker);
+ EXPECT_EQ(0UL, ipc_sink()->message_count());
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_fetch_context_impl.cc b/chromium/content/renderer/service_worker/service_worker_fetch_context_impl.cc
index 570b2de5914..2e0afc75233 100644
--- a/chromium/content/renderer/service_worker/service_worker_fetch_context_impl.cc
+++ b/chromium/content/renderer/service_worker/service_worker_fetch_context_impl.cc
@@ -5,10 +5,10 @@
#include "content/renderer/service_worker/service_worker_fetch_context_impl.h"
#include "base/feature_list.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/resource_dispatcher.h"
-#include "content/child/web_url_loader_impl.h"
#include "content/public/common/content_features.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/loader/resource_dispatcher.h"
+#include "content/renderer/loader/web_url_loader_impl.h"
namespace content {
@@ -25,19 +25,18 @@ ServiceWorkerFetchContextImpl::~ServiceWorkerFetchContextImpl() {}
void ServiceWorkerFetchContextImpl::InitializeOnWorkerThread(
scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner) {
- resource_dispatcher_ = base::MakeUnique<ResourceDispatcher>(
+ resource_dispatcher_ = std::make_unique<ResourceDispatcher>(
nullptr, std::move(loading_task_runner));
url_loader_factory_getter_ = url_loader_factory_getter_info_.Bind();
}
-std::unique_ptr<blink::WebURLLoader>
-ServiceWorkerFetchContextImpl::CreateURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- return base::MakeUnique<content::WebURLLoaderImpl>(
- resource_dispatcher_.get(), std::move(task_runner),
- url_loader_factory_getter_->GetFactoryForURL(request.Url()));
+std::unique_ptr<blink::WebURLLoaderFactory>
+ServiceWorkerFetchContextImpl::CreateURLLoaderFactory() {
+ DCHECK(url_loader_factory_getter_);
+ return std::make_unique<content::WebURLLoaderFactoryImpl>(
+ resource_dispatcher_->GetWeakPtr(),
+ std::move(url_loader_factory_getter_));
}
void ServiceWorkerFetchContextImpl::WillSendRequest(
@@ -53,14 +52,6 @@ bool ServiceWorkerFetchContextImpl::IsControlledByServiceWorker() const {
return false;
}
-void ServiceWorkerFetchContextImpl::SetDataSaverEnabled(bool enabled) {
- is_data_saver_enabled_ = enabled;
-}
-
-bool ServiceWorkerFetchContextImpl::IsDataSaverEnabled() const {
- return is_data_saver_enabled_;
-}
-
blink::WebURL ServiceWorkerFetchContextImpl::SiteForCookies() const {
// According to the spec, we can use the |worker_script_url_| for
// SiteForCookies, because "site for cookies" for the service worker is
diff --git a/chromium/content/renderer/service_worker/service_worker_fetch_context_impl.h b/chromium/content/renderer/service_worker/service_worker_fetch_context_impl.h
index 2ab942b810d..58b945036b9 100644
--- a/chromium/content/renderer/service_worker/service_worker_fetch_context_impl.h
+++ b/chromium/content/renderer/service_worker/service_worker_fetch_context_impl.h
@@ -5,8 +5,8 @@
#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_FETCH_CONTEXT_IMPL_H_
#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_FETCH_CONTEXT_IMPL_H_
-#include "content/public/child/child_url_loader_factory_getter.h"
#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
#include "third_party/WebKit/public/platform/WebWorkerFetchContext.h"
#include "url/gurl.h"
@@ -28,13 +28,9 @@ class ServiceWorkerFetchContextImpl : public blink::WebWorkerFetchContext {
// blink::WebWorkerFetchContext implementation:
void InitializeOnWorkerThread(
scoped_refptr<base::SingleThreadTaskRunner>) override;
- std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
+ std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory() override;
void WillSendRequest(blink::WebURLRequest&) override;
bool IsControlledByServiceWorker() const override;
- void SetDataSaverEnabled(bool enabled) override;
- bool IsDataSaverEnabled() const override;
blink::WebURL SiteForCookies() const override;
private:
@@ -46,8 +42,6 @@ class ServiceWorkerFetchContextImpl : public blink::WebWorkerFetchContext {
// Initialized on the worker thread when InitializeOnWorkerThread() is called.
std::unique_ptr<ResourceDispatcher> resource_dispatcher_;
scoped_refptr<ChildURLLoaderFactoryGetter> url_loader_factory_getter_;
-
- bool is_data_saver_enabled_ = false;
};
} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_handle_reference.cc b/chromium/content/renderer/service_worker/service_worker_handle_reference.cc
new file mode 100644
index 00000000000..5e4fd9165b8
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_handle_reference.cc
@@ -0,0 +1,59 @@
+// 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/service_worker/service_worker_handle_reference.h"
+
+#include "base/memory/ptr_util.h"
+#include "content/child/thread_safe_sender.h"
+#include "content/common/service_worker/service_worker_messages.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
+
+namespace content {
+
+std::unique_ptr<ServiceWorkerHandleReference>
+ServiceWorkerHandleReference::Create(
+ blink::mojom::ServiceWorkerObjectInfoPtr info,
+ scoped_refptr<ThreadSafeSender> sender) {
+ DCHECK(sender);
+ if (info->handle_id == blink::mojom::kInvalidServiceWorkerHandleId)
+ return nullptr;
+ return base::WrapUnique(new ServiceWorkerHandleReference(
+ std::move(info), std::move(sender), true));
+}
+
+std::unique_ptr<ServiceWorkerHandleReference>
+ServiceWorkerHandleReference::Adopt(
+ blink::mojom::ServiceWorkerObjectInfoPtr info,
+ scoped_refptr<ThreadSafeSender> sender) {
+ DCHECK(sender);
+ if (info->handle_id == blink::mojom::kInvalidServiceWorkerHandleId)
+ return nullptr;
+ return base::WrapUnique(new ServiceWorkerHandleReference(
+ std::move(info), std::move(sender), false));
+}
+
+ServiceWorkerHandleReference::ServiceWorkerHandleReference(
+ blink::mojom::ServiceWorkerObjectInfoPtr info,
+ scoped_refptr<ThreadSafeSender> sender,
+ bool increment_ref_in_ctor)
+ : info_(std::move(info)), sender_(sender) {
+ DCHECK_NE(info_->handle_id, blink::mojom::kInvalidServiceWorkerHandleId);
+ if (increment_ref_in_ctor) {
+ sender_->Send(new ServiceWorkerHostMsg_IncrementServiceWorkerRefCount(
+ info_->handle_id));
+ }
+}
+
+ServiceWorkerHandleReference::~ServiceWorkerHandleReference() {
+ DCHECK_NE(info_->handle_id, blink::mojom::kInvalidServiceWorkerHandleId);
+ sender_->Send(new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount(
+ info_->handle_id));
+}
+
+blink::mojom::ServiceWorkerObjectInfoPtr ServiceWorkerHandleReference::GetInfo()
+ const {
+ return info_->Clone();
+}
+
+} // namespace content
diff --git a/chromium/content/child/service_worker/service_worker_handle_reference.h b/chromium/content/renderer/service_worker/service_worker_handle_reference.h
index cb22a8f31df..4d8e97db284 100644
--- a/chromium/content/child/service_worker/service_worker_handle_reference.h
+++ b/chromium/content/renderer/service_worker/service_worker_handle_reference.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_CHILD_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_
-#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_
+#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_
#include <stdint.h>
@@ -13,6 +13,7 @@
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
namespace content {
@@ -26,32 +27,33 @@ class CONTENT_EXPORT ServiceWorkerHandleReference {
// Creates a new ServiceWorkerHandleReference and increments ref-count. If
// the handle id is kInvalidServiceWorkerHandleId, returns null instead.
static std::unique_ptr<ServiceWorkerHandleReference> Create(
- const ServiceWorkerObjectInfo& info,
- ThreadSafeSender* sender);
+ blink::mojom::ServiceWorkerObjectInfoPtr info,
+ scoped_refptr<ThreadSafeSender> sender);
// Creates a new ServiceWorkerHandleReference by adopting a ref-count. If
// the handle id is kInvalidServiceWorkerHandleId, returns null instead.
static std::unique_ptr<ServiceWorkerHandleReference> Adopt(
- const ServiceWorkerObjectInfo& info,
- ThreadSafeSender* sender);
+ blink::mojom::ServiceWorkerObjectInfoPtr info,
+ scoped_refptr<ThreadSafeSender> sender);
~ServiceWorkerHandleReference();
- const ServiceWorkerObjectInfo& info() const { return info_; }
- int handle_id() const { return info_.handle_id; }
- const GURL& url() const { return info_.url; }
- blink::mojom::ServiceWorkerState state() const { return info_.state; }
- int64_t version_id() const { return info_.version_id; }
+ blink::mojom::ServiceWorkerObjectInfoPtr GetInfo() const;
+
+ int handle_id() const { return info_->handle_id; }
+ const GURL& url() const { return info_->url; }
+ blink::mojom::ServiceWorkerState state() const { return info_->state; }
+ int64_t version_id() const { return info_->version_id; }
private:
- ServiceWorkerHandleReference(const ServiceWorkerObjectInfo& info,
- ThreadSafeSender* sender,
+ ServiceWorkerHandleReference(blink::mojom::ServiceWorkerObjectInfoPtr info,
+ scoped_refptr<ThreadSafeSender> sender,
bool increment_ref_in_ctor);
- ServiceWorkerObjectInfo info_;
+ blink::mojom::ServiceWorkerObjectInfoPtr info_;
scoped_refptr<ThreadSafeSender> sender_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandleReference);
};
} // namespace content
-#endif // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_
+#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_
diff --git a/chromium/content/renderer/service_worker/service_worker_message_filter.cc b/chromium/content/renderer/service_worker/service_worker_message_filter.cc
new file mode 100644
index 00000000000..eaab92ca8c2
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_message_filter.cc
@@ -0,0 +1,39 @@
+// 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/service_worker_message_filter.h"
+
+#include <stddef.h>
+
+#include "content/common/service_worker/service_worker_messages.h"
+#include "content/renderer/service_worker/service_worker_dispatcher.h"
+#include "ipc/ipc_message_macros.h"
+
+namespace content {
+
+ServiceWorkerMessageFilter::ServiceWorkerMessageFilter(ThreadSafeSender* sender)
+ : WorkerThreadMessageFilter(sender) {
+}
+
+ServiceWorkerMessageFilter::~ServiceWorkerMessageFilter() {}
+
+bool ServiceWorkerMessageFilter::ShouldHandleMessage(
+ const IPC::Message& msg) const {
+ return IPC_MESSAGE_CLASS(msg) == ServiceWorkerMsgStart;
+}
+
+void ServiceWorkerMessageFilter::OnFilteredMessageReceived(
+ const IPC::Message& msg) {
+ ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
+ thread_safe_sender(), main_thread_task_runner())
+ ->OnMessageReceived(msg);
+}
+
+bool ServiceWorkerMessageFilter::GetWorkerThreadIdForMessage(
+ const IPC::Message& msg,
+ int* ipc_thread_id) {
+ return base::PickleIterator(msg).ReadInt(ipc_thread_id);
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_message_filter.h b/chromium/content/renderer/service_worker/service_worker_message_filter.h
new file mode 100644
index 00000000000..fcad144bd61
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_message_filter.h
@@ -0,0 +1,34 @@
+// 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_SERVICE_WORKER_MESSAGE_FILTER_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "content/renderer/worker_thread_message_filter.h"
+
+namespace content {
+
+class CONTENT_EXPORT ServiceWorkerMessageFilter
+ : public WorkerThreadMessageFilter {
+ public:
+ explicit ServiceWorkerMessageFilter(ThreadSafeSender* thread_safe_sender);
+
+ protected:
+ ~ServiceWorkerMessageFilter() override;
+
+ private:
+ // WorkerThreadMessageFilter:
+ bool ShouldHandleMessage(const IPC::Message& msg) const override;
+ void OnFilteredMessageReceived(const IPC::Message& msg) override;
+ bool GetWorkerThreadIdForMessage(const IPC::Message& msg,
+ int* ipc_thread_id) override;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerMessageFilter);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_
diff --git a/chromium/content/child/service_worker/service_worker_network_provider.cc b/chromium/content/renderer/service_worker/service_worker_network_provider.cc
index 7962a804cef..0500acbeb09 100644
--- a/chromium/content/child/service_worker/service_worker_network_provider.cc
+++ b/chromium/content/renderer/service_worker/service_worker_network_provider.cc
@@ -2,27 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/service_worker/service_worker_network_provider.h"
+#include "content/renderer/service_worker/service_worker_network_provider.h"
#include "base/atomic_sequence_num.h"
-#include "content/child/child_thread_impl.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/service_worker/service_worker_dispatcher.h"
-#include "content/child/service_worker/service_worker_handle_reference.h"
-#include "content/child/service_worker/service_worker_provider_context.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/navigation_params.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/common/service_worker/service_worker_provider_host_info.h"
#include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
#include "content/public/common/browser_side_navigation_policy.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/render_thread_impl.h"
+#include "content/renderer/service_worker/service_worker_dispatcher.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.h"
+#include "content/renderer/service_worker/service_worker_provider_context.h"
#include "ipc/ipc_sync_channel.h"
#include "mojo/public/cpp/bindings/associated_group.h"
+#include "third_party/WebKit/common/sandbox_flags.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebSandboxFlags.h"
namespace content {
@@ -65,18 +66,18 @@ class WebServiceWorkerNetworkProviderForFrame
request.SetExtraData(extra_data);
// If the provider does not have a controller at this point, the renderer
- // expects the request to never be handled by a controlling service worker,
- // so set the ServiceWorkerMode to skip local workers here. Otherwise, a
+ // expects the request to never be handled by a service worker,
+ // so set the ServiceWorkerMode to skip service workers here. Otherwise, a
// service worker that is in the process of becoming the controller (i.e.,
- // via claim()) on the browser-side could handle the request and break
- // the assumptions of the renderer.
+ // via claim()) on the browser-side could handle the request and break the
+ // assumptions of the renderer.
if (request.GetFrameType() != blink::WebURLRequest::kFrameTypeTopLevel &&
request.GetFrameType() != blink::WebURLRequest::kFrameTypeNested &&
!provider_->IsControlledByServiceWorker() &&
request.GetServiceWorkerMode() !=
blink::WebURLRequest::ServiceWorkerMode::kNone) {
request.SetServiceWorkerMode(
- blink::WebURLRequest::ServiceWorkerMode::kForeign);
+ blink::WebURLRequest::ServiceWorkerMode::kNone);
}
}
@@ -87,9 +88,9 @@ class WebServiceWorkerNetworkProviderForFrame
}
int64_t ControllerServiceWorkerID() override {
- if (provider_->context() && provider_->context()->controller())
- return provider_->context()->controller()->version_id();
- return kInvalidServiceWorkerVersionId;
+ if (provider_->context())
+ return provider_->context()->GetControllerVersionId();
+ return blink::mojom::kInvalidServiceWorkerVersionId;
}
ServiceWorkerNetworkProvider* provider() { return provider_.get(); }
@@ -97,8 +98,8 @@ class WebServiceWorkerNetworkProviderForFrame
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const blink::WebURLRequest& request,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
- // ChildThreadImpl is nullptr in some tests.
- if (!ChildThreadImpl::current())
+ // RenderThreadImpl is nullptr in some tests.
+ if (!RenderThreadImpl::current())
return nullptr;
// S13nServiceWorker:
@@ -130,8 +131,8 @@ class WebServiceWorkerNetworkProviderForFrame
// S13nServiceWorker:
// Create our own SubresourceLoader to route the request
// to the controller ServiceWorker.
- return base::MakeUnique<WebURLLoaderImpl>(
- ChildThreadImpl::current()->resource_dispatcher(),
+ return std::make_unique<WebURLLoaderImpl>(
+ RenderThreadImpl::current()->resource_dispatcher(),
std::move(task_runner),
provider_->context()->subresource_loader_factory());
}
@@ -185,21 +186,22 @@ ServiceWorkerNetworkProvider::CreateForNavigation(
if (service_worker_provider_id == kInvalidServiceWorkerProviderId) {
network_provider = base::WrapUnique(new ServiceWorkerNetworkProvider(
- route_id, SERVICE_WORKER_PROVIDER_FOR_WINDOW, GetNextProviderId(),
- is_parent_frame_secure, std::move(default_loader_factory_getter)));
+ route_id, blink::mojom::ServiceWorkerProviderType::kForWindow,
+ GetNextProviderId(), is_parent_frame_secure,
+ std::move(default_loader_factory_getter)));
} else {
CHECK(browser_side_navigation);
DCHECK(ServiceWorkerUtils::IsBrowserAssignedProviderId(
service_worker_provider_id));
network_provider = base::WrapUnique(new ServiceWorkerNetworkProvider(
- route_id, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
+ route_id, blink::mojom::ServiceWorkerProviderType::kForWindow,
service_worker_provider_id, is_parent_frame_secure,
std::move(default_loader_factory_getter)));
}
} else {
network_provider = base::WrapUnique(new ServiceWorkerNetworkProvider());
}
- return base::MakeUnique<WebServiceWorkerNetworkProviderForFrame>(
+ return std::make_unique<WebServiceWorkerNetworkProviderForFrame>(
std::move(network_provider));
}
@@ -209,8 +211,8 @@ ServiceWorkerNetworkProvider::CreateForSharedWorker(int route_id) {
// TODO(kinuko): Provide ChildURLLoaderFactoryGetter associated with
// the SharedWorker.
return base::WrapUnique(new ServiceWorkerNetworkProvider(
- route_id, SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER, GetNextProviderId(),
- true /* is_parent_frame_secure */,
+ route_id, blink::mojom::ServiceWorkerProviderType::kForSharedWorker,
+ GetNextProviderId(), true /* is_parent_frame_secure */,
nullptr /* default_loader_factory_getter */));
}
@@ -246,7 +248,8 @@ int ServiceWorkerNetworkProvider::provider_id() const {
}
bool ServiceWorkerNetworkProvider::IsControlledByServiceWorker() const {
- return context() && context()->controller();
+ return context() && context()->GetControllerVersionId() !=
+ blink::mojom::kInvalidServiceWorkerVersionId;
}
// Creates an invalid instance (provider_id() returns
@@ -256,7 +259,7 @@ ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider() {}
// Constructor for service worker clients.
ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
int route_id,
- ServiceWorkerProviderType provider_type,
+ blink::mojom::ServiceWorkerProviderType provider_type,
int browser_provider_id,
bool is_parent_frame_secure,
scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter) {
@@ -265,8 +268,9 @@ ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
// We don't support dedicated worker (WORKER) as an independent service
// worker client yet.
- DCHECK(provider_type == SERVICE_WORKER_PROVIDER_FOR_WINDOW ||
- provider_type == SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER);
+ DCHECK(provider_type == blink::mojom::ServiceWorkerProviderType::kForWindow ||
+ provider_type ==
+ blink::mojom::ServiceWorkerProviderType::kForSharedWorker);
ServiceWorkerProviderHostInfo host_info(
browser_provider_id, route_id, provider_type, is_parent_frame_secure);
@@ -279,21 +283,19 @@ ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
// current() may be null in tests.
if (ChildThreadImpl::current()) {
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
- ChildThreadImpl::current()->thread_safe_sender(),
- base::ThreadTaskRunnerHandle::Get().get());
+ ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
+ ChildThreadImpl::current()->thread_safe_sender(),
+ base::ThreadTaskRunnerHandle::Get().get());
context_ = base::MakeRefCounted<ServiceWorkerProviderContext>(
browser_provider_id, provider_type, std::move(client_request),
- std::move(host_ptr_info), dispatcher, default_loader_factory_getter);
+ std::move(host_ptr_info), default_loader_factory_getter);
ChildThreadImpl::current()->channel()->GetRemoteAssociatedInterface(
&dispatcher_host_);
dispatcher_host_->OnProviderCreated(std::move(host_info));
} else {
context_ = base::MakeRefCounted<ServiceWorkerProviderContext>(
browser_provider_id, provider_type, std::move(client_request),
- std::move(host_ptr_info), nullptr /* dispatcher */,
- default_loader_factory_getter);
+ std::move(host_ptr_info), default_loader_factory_getter);
}
}
@@ -303,24 +305,17 @@ ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
// Initialize the provider context with info for
// ServiceWorkerGlobalScope#registration.
ThreadSafeSender* sender = ChildThreadImpl::current()->thread_safe_sender();
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
- sender, base::ThreadTaskRunnerHandle::Get().get());
+ ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
+ sender, base::ThreadTaskRunnerHandle::Get().get());
// TODO(kinuko): Split ServiceWorkerProviderContext ctor for
// controller and controllee.
context_ = base::MakeRefCounted<ServiceWorkerProviderContext>(
- info->provider_id, SERVICE_WORKER_PROVIDER_FOR_CONTROLLER,
+ info->provider_id,
+ blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
std::move(info->client_request), std::move(info->host_ptr_info),
- dispatcher, nullptr /* loader_factory_getter */);
- std::unique_ptr<ServiceWorkerHandleReference> installing =
- ServiceWorkerHandleReference::Adopt(info->attributes.installing, sender);
- std::unique_ptr<ServiceWorkerHandleReference> waiting =
- ServiceWorkerHandleReference::Adopt(info->attributes.waiting, sender);
- std::unique_ptr<ServiceWorkerHandleReference> active =
- ServiceWorkerHandleReference::Adopt(info->attributes.active, sender);
+ nullptr /* loader_factory_getter */);
context_->SetRegistrationForServiceWorkerGlobalScope(
- std::move(info->registration), std::move(installing), std::move(waiting),
- std::move(active));
+ std::move(info->registration), sender);
if (info->script_loader_factory_ptr_info.is_valid()) {
script_loader_factory_.Bind(
diff --git a/chromium/content/child/service_worker/service_worker_network_provider.h b/chromium/content/renderer/service_worker/service_worker_network_provider.h
index 07bd7a22ee7..e52ab07ac33 100644
--- a/chromium/content/child/service_worker/service_worker_network_provider.h
+++ b/chromium/content/renderer/service_worker/service_worker_network_provider.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_CHILD_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_H_
-#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_H_
+#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_H_
#include <stdint.h>
@@ -17,6 +17,7 @@
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker.mojom.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
namespace blink {
class WebLocalFrame;
@@ -33,16 +34,22 @@ struct RequestNavigationParams;
class ServiceWorkerProviderContext;
class ChildURLLoaderFactoryGetter;
-// A unique provider_id is generated for each instance.
-// Instantiated prior to the main resource load being started and remains
-// allocated until after the last subresource load has occurred.
-// This is used to track the lifetime of a Document to create
-// and dispose the ServiceWorkerProviderHost in the browser process
-// to match its lifetime. Each request coming from the Document is
-// tagged with this id in willSendRequest.
+// ServiceWorkerNetworkProvider enables the browser process to recognize
+// resource requests from Blink that should be handled by service worker
+// machinery rather than the usual network stack.
//
-// Basically, it's a scoped integer that sends an ipc upon construction
-// and destruction.
+// All requests associated with a network provider are tagged with its
+// |provider_id| (from ServiceWorkerProviderContext). The browser
+// process can then route the request to this provider's corresponding
+// ServiceWorkerProviderHost.
+//
+// It is created for both service worker clients and execution contexts. It is
+// instantiated prior to the main resource load being started and remains
+// allocated until after the last subresource load has occurred. It is owned by
+// the appropriate DocumentLoader for the provider (i.e., the loader for a
+// document, or the shadow page's loader for a shared worker or service worker).
+// Each request coming from the DocumentLoader is tagged with the provider_id in
+// WillSendRequest.
class CONTENT_EXPORT ServiceWorkerNetworkProvider {
public:
// Creates a ServiceWorkerNetworkProvider for navigation and wraps it
@@ -108,7 +115,7 @@ class CONTENT_EXPORT ServiceWorkerNetworkProvider {
// e.g. a frame, provides the loading factory getter for default loaders.
ServiceWorkerNetworkProvider(
int route_id,
- ServiceWorkerProviderType type,
+ blink::mojom::ServiceWorkerProviderType type,
int provider_id,
bool is_parent_frame_secure,
scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter);
@@ -126,4 +133,4 @@ class CONTENT_EXPORT ServiceWorkerNetworkProvider {
} // namespace content
-#endif // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_H_
+#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_H_
diff --git a/chromium/content/renderer/service_worker/service_worker_provider_context.cc b/chromium/content/renderer/service_worker/service_worker_provider_context.cc
new file mode 100644
index 00000000000..90f947427fb
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_provider_context.cc
@@ -0,0 +1,441 @@
+// 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/service_worker/service_worker_provider_context.h"
+
+#include <set>
+#include <utility>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/stl_util.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "content/child/child_thread_impl.h"
+#include "content/child/thread_safe_sender.h"
+#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/common/service_names.mojom.h"
+#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
+#include "content/renderer/service_worker/controller_service_worker_connector.h"
+#include "content/renderer/service_worker/service_worker_dispatcher.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.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"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+
+namespace content {
+
+// Holds state for service worker clients.
+struct ServiceWorkerProviderContext::ProviderStateForClient {
+ explicit ProviderStateForClient(
+ scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter)
+ : default_loader_factory_getter(
+ std::move(default_loader_factory_getter)) {}
+ ~ProviderStateForClient() = default;
+
+ // |controller| will be set by SetController() and taken by TakeController().
+ std::unique_ptr<ServiceWorkerHandleReference> controller;
+ // Keeps version id of the current controller service worker object.
+ int64_t controller_version_id = blink::mojom::kInvalidServiceWorkerVersionId;
+
+ // S13nServiceWorker:
+ // Used to intercept requests from the controllee and dispatch them
+ // as events to the controller ServiceWorker. This is reset when a new
+ // controller is set.
+ mojom::URLLoaderFactoryPtr subresource_loader_factory;
+
+ // S13nServiceWorker:
+ // Used when we create |subresource_loader_factory|.
+ scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter;
+
+ // Tracks feature usage for UseCounter.
+ std::set<blink::mojom::WebFeature> used_features;
+
+ // Corresponds to a ServiceWorkerContainer. We notify it when
+ // ServiceWorkerContainer#controller should be changed.
+ base::WeakPtr<WebServiceWorkerProviderImpl> web_service_worker_provider;
+
+ // Keeps ServiceWorkerWorkerClient pointers of dedicated or shared workers
+ // which are associated with the ServiceWorkerProviderContext.
+ // - If this ServiceWorkerProviderContext is for a Document, then
+ // |worker_clients| contains all its dedicated workers.
+ // - If this ServiceWorkerProviderContext is for a SharedWorker (technically
+ // speaking, for its shadow page), then |worker_clients| has one element:
+ // the shared worker.
+ std::vector<mojom::ServiceWorkerWorkerClientPtr> worker_clients;
+
+ // S13nServiceWorker
+ // Used in |subresource_loader_factory| to get the connection to the
+ // controller service worker. Kept here in order to call
+ // OnContainerHostConnectionClosed when container_host_ for the
+ // provider is reset.
+ scoped_refptr<ControllerServiceWorkerConnector> controller_connector;
+
+ // For service worker clients. Map from registration id to JavaScript
+ // ServiceWorkerRegistration object.
+ std::map<int64_t, WebServiceWorkerRegistrationImpl*> registrations_;
+};
+
+// Holds state for service worker execution contexts.
+struct ServiceWorkerProviderContext::ProviderStateForServiceWorker {
+ ProviderStateForServiceWorker() = default;
+ ~ProviderStateForServiceWorker() = default;
+ // |registration->host_ptr_info| will be taken by
+ // ServiceWorkerProviderContext::TakeRegistrationForServiceWorkerGlobalScope()
+ // means after that |registration| will be in a half-way taken state.
+ // TODO(leonhsl): To avoid the half-way taken state mentioned above, make
+ // ServiceWorkerProviderContext::TakeRegistrationForServiceWorkerGlobalScope()
+ // take/reset all information of |registration|, |installing|, |waiting| and
+ // |active| all at once.
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration;
+ std::unique_ptr<ServiceWorkerHandleReference> installing;
+ std::unique_ptr<ServiceWorkerHandleReference> waiting;
+ std::unique_ptr<ServiceWorkerHandleReference> active;
+};
+
+ServiceWorkerProviderContext::ServiceWorkerProviderContext(
+ int provider_id,
+ blink::mojom::ServiceWorkerProviderType provider_type,
+ mojom::ServiceWorkerContainerAssociatedRequest request,
+ mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info,
+ scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter)
+ : provider_type_(provider_type),
+ provider_id_(provider_id),
+ main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ binding_(this, std::move(request)),
+ weak_factory_(this) {
+ container_host_.Bind(std::move(host_ptr_info));
+ if (provider_type ==
+ blink::mojom::ServiceWorkerProviderType::kForServiceWorker) {
+ state_for_service_worker_ =
+ std::make_unique<ProviderStateForServiceWorker>();
+ } else {
+ state_for_client_ = std::make_unique<ProviderStateForClient>(
+ std::move(default_loader_factory_getter));
+ }
+}
+
+ServiceWorkerProviderContext::~ServiceWorkerProviderContext() = default;
+
+void ServiceWorkerProviderContext::SetRegistrationForServiceWorkerGlobalScope(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration,
+ scoped_refptr<ThreadSafeSender> sender) {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ ProviderStateForServiceWorker* state = state_for_service_worker_.get();
+ DCHECK(state);
+ DCHECK(!state->registration);
+ DCHECK(!state->installing && !state->waiting && !state->active);
+
+ state->installing = ServiceWorkerHandleReference::Adopt(
+ std::move(registration->installing), sender);
+ state->waiting = ServiceWorkerHandleReference::Adopt(
+ std::move(registration->waiting), sender);
+ state->active = ServiceWorkerHandleReference::Adopt(
+ std::move(registration->active), sender);
+
+ state->registration = std::move(registration);
+}
+
+scoped_refptr<WebServiceWorkerRegistrationImpl>
+ServiceWorkerProviderContext::TakeRegistrationForServiceWorkerGlobalScope(
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
+ DCHECK_EQ(blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
+ provider_type_);
+ ProviderStateForServiceWorker* state = state_for_service_worker_.get();
+ DCHECK(state);
+ DCHECK(state->registration);
+ DCHECK(state->registration->host_ptr_info.is_valid());
+ DCHECK_NE(state->registration->registration_id,
+ blink::mojom::kInvalidServiceWorkerRegistrationId);
+
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ std::move(state->registration);
+ if (state->installing)
+ info->installing = state->installing->GetInfo();
+ else
+ info->installing = blink::mojom::ServiceWorkerObjectInfo::New();
+ if (state->waiting)
+ info->waiting = state->waiting->GetInfo();
+ else
+ info->waiting = blink::mojom::ServiceWorkerObjectInfo::New();
+ if (state->active)
+ info->active = state->active->GetInfo();
+ else
+ info->active = blink::mojom::ServiceWorkerObjectInfo::New();
+
+ ServiceWorkerDispatcher* dispatcher =
+ ServiceWorkerDispatcher::GetThreadSpecificInstance();
+ DCHECK(dispatcher);
+ std::unique_ptr<ServiceWorkerHandleReference> installing =
+ ServiceWorkerHandleReference::Create(std::move(info->installing),
+ dispatcher->thread_safe_sender());
+ std::unique_ptr<ServiceWorkerHandleReference> waiting =
+ ServiceWorkerHandleReference::Create(std::move(info->waiting),
+ dispatcher->thread_safe_sender());
+ std::unique_ptr<ServiceWorkerHandleReference> active =
+ ServiceWorkerHandleReference::Create(std::move(info->active),
+ dispatcher->thread_safe_sender());
+ DCHECK(info->request.is_pending());
+ scoped_refptr<WebServiceWorkerRegistrationImpl> registration =
+ WebServiceWorkerRegistrationImpl::CreateForServiceWorkerGlobalScope(
+ std::move(info), std::move(io_task_runner));
+ registration->SetInstalling(
+ dispatcher->GetOrCreateServiceWorker(std::move(installing)));
+ registration->SetWaiting(
+ dispatcher->GetOrCreateServiceWorker(std::move(waiting)));
+ registration->SetActive(
+ dispatcher->GetOrCreateServiceWorker(std::move(active)));
+
+ return registration;
+}
+
+std::unique_ptr<ServiceWorkerHandleReference>
+ServiceWorkerProviderContext::TakeController() {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(state_for_client_);
+ return std::move(state_for_client_->controller);
+}
+
+int64_t ServiceWorkerProviderContext::GetControllerVersionId() {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(state_for_client_);
+ return state_for_client_->controller_version_id;
+}
+
+mojom::URLLoaderFactory*
+ServiceWorkerProviderContext::subresource_loader_factory() {
+ DCHECK(state_for_client_);
+ return state_for_client_->subresource_loader_factory.get();
+}
+
+mojom::ServiceWorkerContainerHost*
+ServiceWorkerProviderContext::container_host() const {
+ DCHECK_EQ(blink::mojom::ServiceWorkerProviderType::kForWindow,
+ provider_type_);
+ return container_host_.get();
+}
+
+const std::set<blink::mojom::WebFeature>&
+ServiceWorkerProviderContext::used_features() const {
+ DCHECK(state_for_client_);
+ return state_for_client_->used_features;
+}
+
+void ServiceWorkerProviderContext::SetWebServiceWorkerProvider(
+ base::WeakPtr<WebServiceWorkerProviderImpl> provider) {
+ DCHECK(state_for_client_);
+ state_for_client_->web_service_worker_provider = provider;
+}
+
+mojom::ServiceWorkerWorkerClientRequest
+ServiceWorkerProviderContext::CreateWorkerClientRequest() {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(state_for_client_);
+ mojom::ServiceWorkerWorkerClientPtr client;
+ mojom::ServiceWorkerWorkerClientRequest request = mojo::MakeRequest(&client);
+ client.set_connection_error_handler(base::BindOnce(
+ &ServiceWorkerProviderContext::UnregisterWorkerFetchContext,
+ base::Unretained(this), client.get()));
+ state_for_client_->worker_clients.push_back(std::move(client));
+ return request;
+}
+
+mojom::ServiceWorkerContainerHostPtrInfo
+ServiceWorkerProviderContext::CloneContainerHostPtrInfo() {
+ DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(state_for_client_);
+ mojom::ServiceWorkerContainerHostPtrInfo container_host_ptr_info;
+ container_host_->CloneForWorker(mojo::MakeRequest(&container_host_ptr_info));
+ return container_host_ptr_info;
+}
+
+scoped_refptr<WebServiceWorkerRegistrationImpl>
+ServiceWorkerProviderContext::GetOrCreateRegistrationForServiceWorkerClient(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info) {
+ DCHECK_EQ(blink::mojom::ServiceWorkerProviderType::kForWindow,
+ provider_type_);
+ DCHECK(state_for_client_);
+ ServiceWorkerDispatcher* dispatcher =
+ ServiceWorkerDispatcher::GetThreadSpecificInstance();
+ DCHECK(dispatcher);
+ std::unique_ptr<ServiceWorkerHandleReference> installing =
+ ServiceWorkerHandleReference::Adopt(std::move(info->installing),
+ dispatcher->thread_safe_sender());
+ std::unique_ptr<ServiceWorkerHandleReference> waiting =
+ ServiceWorkerHandleReference::Adopt(std::move(info->waiting),
+ dispatcher->thread_safe_sender());
+ std::unique_ptr<ServiceWorkerHandleReference> active =
+ ServiceWorkerHandleReference::Adopt(std::move(info->active),
+ dispatcher->thread_safe_sender());
+
+ auto found = state_for_client_->registrations_.find(info->registration_id);
+ if (found != state_for_client_->registrations_.end()) {
+ DCHECK(!info->request.is_pending());
+ found->second->AttachForServiceWorkerClient(std::move(info));
+ return found->second;
+ }
+
+ DCHECK(info->request.is_pending());
+ // WebServiceWorkerRegistrationImpl constructor calls
+ // AddServiceWorkerRegistration to add itself into
+ // |state_for_client_->registrations_|.
+ scoped_refptr<WebServiceWorkerRegistrationImpl> registration =
+ WebServiceWorkerRegistrationImpl::CreateForServiceWorkerClient(
+ std::move(info), weak_factory_.GetWeakPtr());
+
+ registration->SetInstalling(
+ dispatcher->GetOrCreateServiceWorker(std::move(installing)));
+ registration->SetWaiting(
+ dispatcher->GetOrCreateServiceWorker(std::move(waiting)));
+ registration->SetActive(
+ dispatcher->GetOrCreateServiceWorker(std::move(active)));
+ return registration;
+}
+
+void ServiceWorkerProviderContext::OnNetworkProviderDestroyed() {
+ container_host_.reset();
+ if (state_for_client_ && state_for_client_->controller_connector)
+ state_for_client_->controller_connector->OnContainerHostConnectionClosed();
+}
+
+void ServiceWorkerProviderContext::UnregisterWorkerFetchContext(
+ mojom::ServiceWorkerWorkerClient* client) {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(state_for_client_);
+ base::EraseIf(
+ state_for_client_->worker_clients,
+ [client](const mojom::ServiceWorkerWorkerClientPtr& client_ptr) {
+ return client_ptr.get() == client;
+ });
+}
+
+void ServiceWorkerProviderContext::SetController(
+ blink::mojom::ServiceWorkerObjectInfoPtr controller,
+ const std::vector<blink::mojom::WebFeature>& used_features,
+ bool should_notify_controllerchange) {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ ProviderStateForClient* state = state_for_client_.get();
+ DCHECK(state);
+ DCHECK(!state->controller || state->controller->handle_id() !=
+ blink::mojom::kInvalidServiceWorkerHandleId);
+ ServiceWorkerDispatcher* dispatcher =
+ ServiceWorkerDispatcher::GetThreadSpecificInstance();
+
+ state->controller_version_id = controller->version_id;
+ state->controller = ServiceWorkerHandleReference::Adopt(
+ std::move(controller), dispatcher->thread_safe_sender());
+
+ // Propagate the controller to workers related to this provider.
+ if (state->controller) {
+ for (const auto& worker : state->worker_clients) {
+ // This is a Mojo interface call to the (dedicated or shared) worker
+ // thread.
+ worker->SetControllerServiceWorker(state->controller->version_id());
+ }
+ }
+ for (blink::mojom::WebFeature feature : used_features)
+ state->used_features.insert(feature);
+
+ // S13nServiceWorker
+ // Set up the URL loader factory for sending URL requests to the controller.
+ if (!ServiceWorkerUtils::IsServicificationEnabled() || !state->controller) {
+ state->controller_connector = nullptr;
+ state->subresource_loader_factory = nullptr;
+ } else {
+ blink::mojom::BlobRegistryPtr blob_registry_ptr;
+ ChildThreadImpl::current()->GetConnector()->BindInterface(
+ mojom::kBrowserServiceName, mojo::MakeRequest(&blob_registry_ptr));
+ auto blob_registry = base::MakeRefCounted<
+ base::RefCountedData<blink::mojom::BlobRegistryPtr>>();
+ blob_registry->data = std::move(blob_registry_ptr);
+ state->controller_connector =
+ base::MakeRefCounted<ControllerServiceWorkerConnector>(
+ container_host_.get());
+ mojo::MakeStrongBinding(
+ std::make_unique<ServiceWorkerSubresourceLoaderFactory>(
+ state->controller_connector, state->default_loader_factory_getter,
+ state->controller->url().GetOrigin(), std::move(blob_registry)),
+ mojo::MakeRequest(&state->subresource_loader_factory));
+ }
+
+ // The WebServiceWorkerProviderImpl might not exist yet because the document
+ // has not yet been created (as WebServiceWorkerImpl 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) {
+ state->web_service_worker_provider->SetController(
+ std::move(state->controller), state->used_features,
+ should_notify_controllerchange);
+ }
+}
+
+void ServiceWorkerProviderContext::PostMessageToClient(
+ blink::mojom::ServiceWorkerObjectInfoPtr source,
+ const base::string16& message,
+ std::vector<mojo::ScopedMessagePipeHandle> message_pipes) {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ ProviderStateForClient* state = state_for_client_.get();
+ DCHECK(state);
+
+ if (state->web_service_worker_provider) {
+ state->web_service_worker_provider->PostMessageToClient(
+ std::move(source), message, std::move(message_pipes));
+ }
+}
+
+void ServiceWorkerProviderContext::AddServiceWorkerRegistration(
+ int64_t registration_id,
+ WebServiceWorkerRegistrationImpl* registration) {
+ DCHECK(state_for_client_);
+ DCHECK(
+ !base::ContainsKey(state_for_client_->registrations_, registration_id));
+ state_for_client_->registrations_[registration_id] = registration;
+}
+
+void ServiceWorkerProviderContext::RemoveServiceWorkerRegistration(
+ int64_t registration_id) {
+ DCHECK(state_for_client_);
+ DCHECK(base::ContainsKey(state_for_client_->registrations_, registration_id));
+ state_for_client_->registrations_.erase(registration_id);
+}
+
+bool ServiceWorkerProviderContext::ContainsServiceWorkerRegistrationForTesting(
+ int64_t registration_id) {
+ DCHECK(state_for_client_);
+ return base::ContainsKey(state_for_client_->registrations_, registration_id);
+}
+
+void ServiceWorkerProviderContext::CountFeature(
+ blink::mojom::WebFeature feature) {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(state_for_client_);
+ ProviderStateForClient* state = state_for_client_.get();
+
+ // ServiceWorkerProviderContext keeps track of features in order to propagate
+ // it to WebServiceWorkerProviderClient, which actually records the
+ // UseCounter.
+ state->used_features.insert(feature);
+ if (state->web_service_worker_provider) {
+ state->web_service_worker_provider->CountFeature(feature);
+ }
+}
+
+void ServiceWorkerProviderContext::DestructOnMainThread() const {
+ if (!main_thread_task_runner_->RunsTasksInCurrentSequence() &&
+ main_thread_task_runner_->DeleteSoon(FROM_HERE, this)) {
+ return;
+ }
+ delete this;
+}
+
+} // namespace content
diff --git a/chromium/content/child/service_worker/service_worker_provider_context.h b/chromium/content/renderer/service_worker/service_worker_provider_context.h
index b09c55a8cd5..843ac5f1736 100644
--- a/chromium/content/child/service_worker/service_worker_provider_context.h
+++ b/chromium/content/renderer/service_worker/service_worker_provider_context.h
@@ -2,21 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_CONTEXT_H_
-#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_CONTEXT_H_
+#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_CONTEXT_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_CONTEXT_H_
#include <memory>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner_helpers.h"
-#include "content/child/service_worker/service_worker_dispatcher.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/child/child_url_loader_factory_getter.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
+#include "content/renderer/service_worker/web_service_worker_provider_impl.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
namespace base {
@@ -30,6 +33,7 @@ class URLLoaderFactory;
}
class ServiceWorkerHandleReference;
+class WebServiceWorkerRegistrationImpl;
struct ServiceWorkerProviderContextDeleter;
// ServiceWorkerProviderContext stores common state for service worker
@@ -38,16 +42,10 @@ struct ServiceWorkerProviderContextDeleter;
// the same underlying entity hold strong references to a shared instance of
// this class.
//
-// The ServiceWorkerProviderContext has different roles depending on if it's for
-// a "controllee" (a Document or Worker execution context), or a "controller" (a
-// service worker execution context).
-// - For controllees, it's used for keeping the controller alive to create
-// controllee's ServiceWorkerContainer#controller. The reference to the
-// controller is kept until SetController() is called with an
-// invalid worker info.
-// - For controllers, it's used for keeping the associated registration and
-// its versions alive to create the controller's
-// ServiceWorkerGlobalScope#registration.
+// A service worker provider may exist for either a service worker client or a
+// service worker itself. Therefore, this class has different roles depending on
+// its provider type. See the implementation of ProviderStateForClient and
+// ProviderStateForServiceWorker for details.
//
// Created and destructed on the main thread. Unless otherwise noted, all
// methods are called on the main thread.
@@ -60,7 +58,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// browser process. |request| is an endpoint which is connected to
// the content::ServiceWorkerProviderHost that notifies of changes to the
// registration's and workers' status. |request| is bound with |binding_|.
- // The new instance is registered to |dispatcher|, which is not owned.
//
// For S13nServiceWorker:
// |default_loader_factory_getter| contains a set of default loader
@@ -70,13 +67,14 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// e.g. a frame, provides the default URLLoaderFactoryGetter.
ServiceWorkerProviderContext(
int provider_id,
- ServiceWorkerProviderType provider_type,
+ blink::mojom::ServiceWorkerProviderType provider_type,
mojom::ServiceWorkerContainerAssociatedRequest request,
mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info,
- ServiceWorkerDispatcher* dispatcher,
scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter);
- ServiceWorkerProviderType provider_type() const { return provider_type_; }
+ blink::mojom::ServiceWorkerProviderType provider_type() const {
+ return provider_type_;
+ }
int provider_id() const { return provider_id_; }
@@ -86,34 +84,49 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// SetRegistrationForServiceWorkerGlobalScope() is called during the setup for
// service worker startup, so it is guaranteed to be called before
// TakeRegistrationForServiceWorkerGlobalScope().
+ // |sender| is to initialize ServiceWorkerHandleReference which still needs to
+ // send legacy Incre/Decre IPCs, will disappear together with class
+ // ServiceWorkerHandleReference once ServiceWorkerObjectInfo starts to retain
+ // reference to ServiceWorkerHandle in the browser process.
void SetRegistrationForServiceWorkerGlobalScope(
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration,
- std::unique_ptr<ServiceWorkerHandleReference> installing,
- std::unique_ptr<ServiceWorkerHandleReference> waiting,
- std::unique_ptr<ServiceWorkerHandleReference> active);
+ scoped_refptr<ThreadSafeSender> sender);
// For service worker execution contexts. Used for initializing
// ServiceWorkerGlobalScope#registration. Called on the worker thread.
- // This takes ServiceWorkerRegistrationObjectHost ptr info from
- // ControllerState::registration.
- void TakeRegistrationForServiceWorkerGlobalScope(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr* info,
- ServiceWorkerVersionAttributes* attrs);
-
- // For service worker clients. The controller for
- // ServiceWorkerContainer#controller.
- void SetController(std::unique_ptr<ServiceWorkerHandleReference> controller,
- const std::set<uint32_t>& used_features);
- ServiceWorkerHandleReference* controller();
+ // This takes the registration that was passed to
+ // SetRegistrationForServiceWorkerScope(), then creates a new
+ // WebServiceWorkerRegistrationImpl instance and returns it. |io_task_runner|
+ // is used to initialize WebServiceWorkerRegistrationImpl. While creating the
+ // WebServiceWorkerRegistrationImpl, increments interprocess references to its
+ // versions via ServiceWorkerHandleReference.
+ scoped_refptr<WebServiceWorkerRegistrationImpl>
+ TakeRegistrationForServiceWorkerGlobalScope(
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
+
+ // For service worker clients. Returns version id of the controller service
+ // worker object (ServiceWorkerContainer#controller).
+ int64_t GetControllerVersionId();
+
+ // For service worker clients. Takes the controller service worker object set
+ // by SetController() if any, otherwise returns nullptr.
+ std::unique_ptr<ServiceWorkerHandleReference> TakeController();
// S13nServiceWorker:
// For service worker clients. Returns URLLoaderFactory for loading
// subresources with the controller ServiceWorker.
mojom::URLLoaderFactory* subresource_loader_factory();
- // For service worker clients. Keeps track of feature usage for UseCounter.
- void CountFeature(uint32_t feature);
- const std::set<uint32_t>& used_features() const;
+ // For service worker clients. Returns the feature usage of its controller.
+ const std::set<blink::mojom::WebFeature>& used_features() 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
+ // notify the WebServiceWorkerProviderImpl when
+ // ServiceWorkerContainer#controller should be changed.
+ void SetWebServiceWorkerProvider(
+ base::WeakPtr<WebServiceWorkerProviderImpl> provider);
// For service worker clients. Creates a ServiceWorkerWorkerClientRequest
// which can be used to bind with a WorkerFetchContextImpl in a (dedicated or
@@ -125,6 +138,20 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// ServiceWorkerProviderContext.
mojom::ServiceWorkerWorkerClientRequest CreateWorkerClientRequest();
+ // S13nServiceWorker:
+ // For service worker clients. Creates a ServiceWorkerContainerHostPtrInfo
+ // which can be bound to a ServiceWorkerContainerHostPtr in a (dedicated or
+ // shared) worker thread. WorkerFetchContextImpl will use the host pointer to
+ // get the controller service worker by GetControllerServiceWorker() and send
+ // FetchEvents to the service worker.
+ mojom::ServiceWorkerContainerHostPtrInfo CloneContainerHostPtrInfo();
+
+ // For service worker clients. Returns the registration object described by
+ // |info|. Creates a new object if needed, or else returns the existing one.
+ scoped_refptr<WebServiceWorkerRegistrationImpl>
+ GetOrCreateRegistrationForServiceWorkerClient(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr 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
@@ -146,9 +173,11 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
friend class base::DeleteHelper<ServiceWorkerProviderContext>;
friend class base::RefCountedThreadSafe<ServiceWorkerProviderContext,
ServiceWorkerProviderContextDeleter>;
+ friend class ServiceWorkerProviderContextTest;
+ friend class WebServiceWorkerRegistrationImpl;
friend struct ServiceWorkerProviderContextDeleter;
- struct ControlleeState;
- struct ControllerState;
+ struct ProviderStateForClient;
+ struct ProviderStateForServiceWorker;
~ServiceWorkerProviderContext() override;
void DestructOnMainThread() const;
@@ -157,7 +186,25 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// shared) worker, when the connection to the worker is disconnected.
void UnregisterWorkerFetchContext(mojom::ServiceWorkerWorkerClient*);
- const ServiceWorkerProviderType provider_type_;
+ // Implementation of mojom::ServiceWorkerContainer.
+ void SetController(blink::mojom::ServiceWorkerObjectInfoPtr controller,
+ const std::vector<blink::mojom::WebFeature>& used_features,
+ bool should_notify_controllerchange) override;
+ void PostMessageToClient(
+ blink::mojom::ServiceWorkerObjectInfoPtr source,
+ const base::string16& message,
+ std::vector<mojo::ScopedMessagePipeHandle> message_pipes) override;
+ void CountFeature(blink::mojom::WebFeature feature) override;
+
+ // For service worker clients. Keeps the mapping from registration_id to
+ // ServiceWorkerRegistration object.
+ void AddServiceWorkerRegistration(
+ int64_t registration_id,
+ WebServiceWorkerRegistrationImpl* registration);
+ void RemoveServiceWorkerRegistration(int64_t registration_id);
+ bool ContainsServiceWorkerRegistrationForTesting(int64_t registration_id);
+
+ const blink::mojom::ServiceWorkerProviderType provider_type_;
const int provider_id_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
@@ -177,9 +224,16 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// Note: Currently this is always bound on main thread.
mojom::ServiceWorkerContainerHostAssociatedPtr container_host_;
- // Either |controllee_state_| or |controller_state_| is non-null.
- std::unique_ptr<ControlleeState> controllee_state_;
- std::unique_ptr<ControllerState> controller_state_;
+ // Either |state_for_client_| or |state_for_service_worker_| is non-null.
+ // State for service worker clients.
+ std::unique_ptr<ProviderStateForClient> state_for_client_;
+ // State for service workers.
+ std::unique_ptr<ProviderStateForServiceWorker> state_for_service_worker_;
+
+ // NOTE: New members should usually be added to either service_worker_state_
+ // or client_state_. Not here!
+
+ base::WeakPtrFactory<ServiceWorkerProviderContext> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderContext);
};
@@ -192,4 +246,4 @@ struct ServiceWorkerProviderContextDeleter {
} // namespace content
-#endif // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_CONTEXT_H_
+#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_CONTEXT_H_
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
new file mode 100644
index 00000000000..5050aa4120a
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc
@@ -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.
+
+#include "content/renderer/service_worker/service_worker_provider_context.h"
+
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "content/child/thread_safe_sender.h"
+#include "content/common/service_worker/service_worker_container.mojom.h"
+#include "content/common/service_worker/service_worker_messages.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
+#include "content/renderer/service_worker/service_worker_dispatcher.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.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/web_service_worker_registration_impl.h"
+#include "ipc/ipc_sync_message_filter.h"
+#include "ipc/ipc_test_sink.h"
+#include "mojo/public/cpp/bindings/associated_binding_set.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+#include "third_party/WebKit/public/platform/web_feature.mojom.h"
+
+namespace content {
+
+namespace {
+
+class MockServiceWorkerRegistrationObjectHost
+ : public blink::mojom::ServiceWorkerRegistrationObjectHost {
+ public:
+ MockServiceWorkerRegistrationObjectHost() {
+ bindings_.set_connection_error_handler(
+ base::Bind(&MockServiceWorkerRegistrationObjectHost::OnConnectionError,
+ base::Unretained(this)));
+ }
+ ~MockServiceWorkerRegistrationObjectHost() override = default;
+
+ void AddBinding(
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedRequest
+ request) {
+ bindings_.AddBinding(this, std::move(request));
+ }
+
+ blink::mojom::ServiceWorkerRegistrationObjectAssociatedRequest
+ CreateRegistrationObjectRequest() {
+ if (!remote_registration_)
+ return mojo::MakeRequest(&remote_registration_);
+ return nullptr;
+ }
+
+ int GetBindingCount() const { return bindings_.size(); }
+
+ private:
+ // Implements blink::mojom::ServiceWorkerRegistrationObjectHost.
+ void Update(UpdateCallback callback) override {
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+ }
+ void Unregister(UnregisterCallback callback) override {
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+ }
+ void EnableNavigationPreload(
+ bool enable,
+ EnableNavigationPreloadCallback callback) override {
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+ }
+ void GetNavigationPreloadState(
+ GetNavigationPreloadStateCallback callback) override {
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt, nullptr);
+ }
+ void SetNavigationPreloadHeader(
+ const std::string& value,
+ SetNavigationPreloadHeaderCallback callback) override {
+ std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
+ base::nullopt);
+ }
+
+ void OnConnectionError() {
+ // If there are still bindings, |this| is still being used.
+ if (!bindings_.empty())
+ return;
+ // Will destroy corresponding remote WebServiceWorkerRegistrationImpl
+ // instance.
+ remote_registration_.reset();
+ }
+
+ mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerRegistrationObjectHost>
+ bindings_;
+ blink::mojom::ServiceWorkerRegistrationObjectAssociatedPtr
+ remote_registration_;
+};
+
+class MockWebServiceWorkerProviderClientImpl
+ : public blink::WebServiceWorkerProviderClient {
+ public:
+ MockWebServiceWorkerProviderClientImpl() {}
+
+ ~MockWebServiceWorkerProviderClientImpl() override {}
+
+ void SetController(std::unique_ptr<blink::WebServiceWorker::Handle> handle,
+ bool should_notify_controller_change) override {
+ was_set_controller_called_ = true;
+ }
+
+ void DispatchMessageEvent(
+ std::unique_ptr<blink::WebServiceWorker::Handle> handle,
+ const blink::WebString& message,
+ blink::WebVector<blink::MessagePortChannel> ports) override {
+ was_dispatch_message_event_called_ = true;
+ }
+
+ void CountFeature(blink::mojom::WebFeature feature) override {
+ used_features_.insert(feature);
+ }
+
+ bool was_set_controller_called() const { return was_set_controller_called_; }
+
+ bool was_dispatch_message_event_called() const {
+ return was_dispatch_message_event_called_;
+ }
+
+ const std::set<blink::mojom::WebFeature>& used_features() const {
+ return used_features_;
+ }
+
+ private:
+ bool was_set_controller_called_ = false;
+ bool was_dispatch_message_event_called_ = false;
+ std::set<blink::mojom::WebFeature> used_features_;
+};
+
+class ServiceWorkerTestSender : public ThreadSafeSender {
+ public:
+ explicit ServiceWorkerTestSender(IPC::TestSink* ipc_sink)
+ : ThreadSafeSender(nullptr, nullptr), ipc_sink_(ipc_sink) {}
+
+ bool Send(IPC::Message* message) override { return ipc_sink_->Send(message); }
+
+ private:
+ ~ServiceWorkerTestSender() override {}
+
+ IPC::TestSink* ipc_sink_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTestSender);
+};
+
+} // namespace
+
+class ServiceWorkerProviderContextTest : public testing::Test {
+ public:
+ ServiceWorkerProviderContextTest() = default;
+
+ void SetUp() override {
+ sender_ = new ServiceWorkerTestSender(&ipc_sink_);
+ dispatcher_.reset(new ServiceWorkerDispatcher(sender_.get(), nullptr));
+ }
+
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
+ CreateServiceWorkerRegistrationObjectInfo() {
+ auto info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New();
+ info->registration_id = 20;
+ remote_registration_object_host_.AddBinding(
+ mojo::MakeRequest(&info->host_ptr_info));
+ info->request =
+ remote_registration_object_host_.CreateRegistrationObjectRequest();
+
+ info->active = blink::mojom::ServiceWorkerObjectInfo::New();
+ info->active->handle_id = 100;
+ info->active->version_id = 200;
+ info->waiting = blink::mojom::ServiceWorkerObjectInfo::New();
+ info->waiting->handle_id = 101;
+ info->waiting->version_id = 201;
+ info->installing = blink::mojom::ServiceWorkerObjectInfo::New();
+ info->installing->handle_id = 102;
+ info->installing->version_id = 202;
+ return info;
+ }
+
+ bool ContainsRegistration(ServiceWorkerProviderContext* provider_context,
+ int64_t registration_id) {
+ return provider_context->ContainsServiceWorkerRegistrationForTesting(
+ registration_id);
+ }
+
+ ThreadSafeSender* thread_safe_sender() { return sender_.get(); }
+ IPC::TestSink* ipc_sink() { return &ipc_sink_; }
+ const MockServiceWorkerRegistrationObjectHost&
+ remote_registration_object_host() const {
+ return remote_registration_object_host_;
+ }
+
+ private:
+ base::MessageLoop message_loop_;
+ IPC::TestSink ipc_sink_;
+ std::unique_ptr<ServiceWorkerDispatcher> dispatcher_;
+ scoped_refptr<ServiceWorkerTestSender> sender_;
+ MockServiceWorkerRegistrationObjectHost remote_registration_object_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderContextTest);
+};
+
+TEST_F(ServiceWorkerProviderContextTest, CreateForController) {
+ // Assume that these objects are passed from the browser process and own
+ // references to browser-side registration/worker representations.
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info =
+ CreateServiceWorkerRegistrationObjectInfo();
+ // ServiceWorkerRegistrationObjectHost Mojo connection has been added.
+ ASSERT_EQ(1, remote_registration_object_host().GetBindingCount());
+
+ // Set up ServiceWorkerProviderContext for ServiceWorkerGlobalScope.
+ const int kProviderId = 10;
+ auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
+ kProviderId, blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
+ nullptr, nullptr, nullptr /* loader_factory_getter */);
+
+ // The passed references should be adopted and owned by the provider context.
+ provider_context->SetRegistrationForServiceWorkerGlobalScope(
+ std::move(registration_info), thread_safe_sender());
+ EXPECT_EQ(0UL, ipc_sink()->message_count());
+
+ // Destruction of the provider context should release references to the
+ // associated registration and its versions.
+ provider_context = nullptr;
+ ASSERT_EQ(3UL, ipc_sink()->message_count());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(0)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(1)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(2)->type());
+ // ServiceWorkerRegistrationObjectHost Mojo connection got broken.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0, remote_registration_object_host().GetBindingCount());
+}
+
+TEST_F(ServiceWorkerProviderContextTest, SetController) {
+ const int kProviderId = 10;
+
+ {
+ // Assume that these objects are passed from the browser process and own
+ // references to browser-side registration/worker representations.
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info =
+ CreateServiceWorkerRegistrationObjectInfo();
+
+ // (1) In the case there is no WebSWProviderClient but SWProviderContext for
+ // the provider, the passed reference should be adopted and owned by the
+ // provider context.
+ mojom::ServiceWorkerContainerAssociatedPtr container_ptr;
+ mojom::ServiceWorkerContainerAssociatedRequest container_request =
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&container_ptr);
+ auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
+ kProviderId, blink::mojom::ServiceWorkerProviderType::kForWindow,
+ std::move(container_request), nullptr /* host_ptr_info */,
+ nullptr /* loader_factory_getter */);
+
+ ipc_sink()->ClearMessages();
+ container_ptr->SetController(std::move(registration_info->active),
+ std::vector<blink::mojom::WebFeature>(), true);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0UL, ipc_sink()->message_count());
+
+ // Destruction of the provider context should release references to the
+ // the controller.
+ provider_context = nullptr;
+ ASSERT_EQ(1UL, ipc_sink()->message_count());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(0)->type());
+ ipc_sink()->ClearMessages();
+ }
+
+ {
+ // Assume that these objects are passed from the browser process and own
+ // references to browser-side registration/worker representations.
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info =
+ CreateServiceWorkerRegistrationObjectInfo();
+
+ // (2) In the case there are both SWProviderContext and SWProviderClient for
+ // the provider, the passed reference should be adopted by the provider
+ // context and then be transfered ownership to the provider client, after
+ // that due to limitation of the mock implementation, the reference
+ // immediately gets released.
+ mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info;
+ mojom::ServiceWorkerContainerHostAssociatedRequest host_request =
+ mojo::MakeRequest(&host_ptr_info);
+
+ mojom::ServiceWorkerContainerAssociatedPtr container_ptr;
+ mojom::ServiceWorkerContainerAssociatedRequest container_request =
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&container_ptr);
+ auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
+ kProviderId, blink::mojom::ServiceWorkerProviderType::kForWindow,
+ std::move(container_request), std::move(host_ptr_info),
+ nullptr /* loader_factory_getter */);
+ auto provider_impl = std::make_unique<WebServiceWorkerProviderImpl>(
+ thread_safe_sender(), provider_context.get());
+ auto client = std::make_unique<MockWebServiceWorkerProviderClientImpl>();
+ provider_impl->SetClient(client.get());
+ ASSERT_FALSE(client->was_set_controller_called());
+
+ ipc_sink()->ClearMessages();
+ container_ptr->SetController(std::move(registration_info->active),
+ std::vector<blink::mojom::WebFeature>(), true);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(client->was_set_controller_called());
+ ASSERT_EQ(1UL, ipc_sink()->message_count());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(0)->type());
+ }
+}
+
+// Test that clearing the controller by sending a kInvalidServiceWorkerHandle
+// results in the provider context having a null controller.
+TEST_F(ServiceWorkerProviderContextTest, SetController_Null) {
+ const int kProviderId = 10;
+
+ mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info;
+ mojom::ServiceWorkerContainerHostAssociatedRequest host_request =
+ mojo::MakeRequest(&host_ptr_info);
+
+ mojom::ServiceWorkerContainerAssociatedPtr container_ptr;
+ mojom::ServiceWorkerContainerAssociatedRequest container_request =
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&container_ptr);
+ auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
+ kProviderId, blink::mojom::ServiceWorkerProviderType::kForWindow,
+ std::move(container_request), std::move(host_ptr_info),
+ nullptr /* loader_factory_getter */);
+ auto provider_impl = std::make_unique<WebServiceWorkerProviderImpl>(
+ thread_safe_sender(), provider_context.get());
+ auto client = std::make_unique<MockWebServiceWorkerProviderClientImpl>();
+ provider_impl->SetClient(client.get());
+
+ container_ptr->SetController(blink::mojom::ServiceWorkerObjectInfo::New(),
+ std::vector<blink::mojom::WebFeature>(), true);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(nullptr, provider_context->TakeController());
+ EXPECT_TRUE(client->was_set_controller_called());
+}
+
+TEST_F(ServiceWorkerProviderContextTest, PostMessageToClient) {
+ const int kProviderId = 10;
+
+ // Assume that these objects are passed from the browser process and own
+ // references to browser-side registration/worker representations.
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info =
+ CreateServiceWorkerRegistrationObjectInfo();
+
+ mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info;
+ mojom::ServiceWorkerContainerHostAssociatedRequest host_request =
+ mojo::MakeRequest(&host_ptr_info);
+
+ mojom::ServiceWorkerContainerAssociatedPtr container_ptr;
+ mojom::ServiceWorkerContainerAssociatedRequest container_request =
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&container_ptr);
+ auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
+ kProviderId, blink::mojom::ServiceWorkerProviderType::kForWindow,
+ std::move(container_request), std::move(host_ptr_info),
+ nullptr /* loader_factory_getter */);
+ auto provider_impl = base::MakeUnique<WebServiceWorkerProviderImpl>(
+ thread_safe_sender(), provider_context.get());
+ auto client = base::MakeUnique<MockWebServiceWorkerProviderClientImpl>();
+ provider_impl->SetClient(client.get());
+ ASSERT_FALSE(client->was_dispatch_message_event_called());
+
+ ipc_sink()->ClearMessages();
+ container_ptr->PostMessageToClient(
+ std::move(registration_info->active), base::string16(),
+ std::vector<mojo::ScopedMessagePipeHandle>());
+ base::RunLoop().RunUntilIdle();
+
+ // The passed reference should be owned by the provider client (but the
+ // reference is immediately released due to limitation of the mock provider
+ // client. See the comment on dispatchMessageEvent() of the mock).
+ EXPECT_TRUE(client->was_dispatch_message_event_called());
+ ASSERT_EQ(2UL, ipc_sink()->message_count());
+ EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(0)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(1)->type());
+}
+
+TEST_F(ServiceWorkerProviderContextTest, CountFeature) {
+ const int kProviderId = 10;
+
+ mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info;
+ mojom::ServiceWorkerContainerHostAssociatedRequest host_request =
+ mojo::MakeRequest(&host_ptr_info);
+
+ mojom::ServiceWorkerContainerAssociatedPtr container_ptr;
+ mojom::ServiceWorkerContainerAssociatedRequest container_request =
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&container_ptr);
+ auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
+ kProviderId, blink::mojom::ServiceWorkerProviderType::kForWindow,
+ std::move(container_request), std::move(host_ptr_info),
+ nullptr /* loader_factory_getter */);
+ auto provider_impl = base::MakeUnique<WebServiceWorkerProviderImpl>(
+ thread_safe_sender(), provider_context.get());
+ auto client = base::MakeUnique<MockWebServiceWorkerProviderClientImpl>();
+
+ container_ptr->CountFeature(blink::mojom::WebFeature::kWorkerStart);
+ provider_impl->SetClient(client.get());
+ base::RunLoop().RunUntilIdle();
+
+ // Calling CountFeature() before client is set will save the feature usage in
+ // the set, and once SetClient() is called it gets propagated to the client.
+ ASSERT_EQ(1UL, client->used_features().size());
+ ASSERT_EQ(blink::mojom::WebFeature::kWorkerStart,
+ *(client->used_features().begin()));
+
+ container_ptr->CountFeature(blink::mojom::WebFeature::kWindowEvent);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_EQ(2UL, client->used_features().size());
+ ASSERT_EQ(blink::mojom::WebFeature::kWindowEvent,
+ *(++(client->used_features().begin())));
+}
+
+TEST_F(ServiceWorkerProviderContextTest,
+ SetAndTakeRegistrationForServiceWorkerGlobalScope) {
+ // Set up ServiceWorkerProviderContext for ServiceWorkerGlobalScope.
+ const int kProviderId = 10;
+ auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
+ kProviderId, blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
+ nullptr, nullptr, nullptr /* loader_factory_getter */);
+
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ CreateServiceWorkerRegistrationObjectInfo();
+ int64_t registration_id = info->registration_id;
+ ASSERT_EQ(1, remote_registration_object_host().GetBindingCount());
+
+ provider_context->SetRegistrationForServiceWorkerGlobalScope(
+ std::move(info), thread_safe_sender());
+ EXPECT_EQ(0UL, ipc_sink()->message_count());
+
+ // Should return a registration object newly created with incrementing
+ // the refcounts.
+ scoped_refptr<WebServiceWorkerRegistrationImpl> registration =
+ provider_context->TakeRegistrationForServiceWorkerGlobalScope(
+ base::ThreadTaskRunnerHandle::Get());
+ EXPECT_TRUE(registration);
+ EXPECT_EQ(registration_id, registration->RegistrationId());
+ EXPECT_EQ(1, remote_registration_object_host().GetBindingCount());
+ ASSERT_EQ(3UL, ipc_sink()->message_count());
+ EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(0)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(1)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(2)->type());
+
+ ipc_sink()->ClearMessages();
+
+ // The registration dtor decrements the refcounts.
+ registration = nullptr;
+ ASSERT_EQ(3UL, ipc_sink()->message_count());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(0)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(1)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(2)->type());
+ // The Mojo connection has been dropped.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0, remote_registration_object_host().GetBindingCount());
+}
+
+TEST_F(ServiceWorkerProviderContextTest, GetOrAdoptRegistration) {
+ scoped_refptr<WebServiceWorkerRegistrationImpl> registration1;
+ scoped_refptr<WebServiceWorkerRegistrationImpl> registration2;
+ int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId;
+ // Set up ServiceWorkerProviderContext for ServiceWorkerGlobalScope.
+ const int kProviderId = 10;
+ auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
+ kProviderId, blink::mojom::ServiceWorkerProviderType::kForWindow, nullptr,
+ nullptr, nullptr /* loader_factory_getter */);
+
+ {
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ CreateServiceWorkerRegistrationObjectInfo();
+ registration_id = info->registration_id;
+ // The 1st ServiceWorkerRegistrationObjectHost Mojo connection has been
+ // added.
+ ASSERT_EQ(1, remote_registration_object_host().GetBindingCount());
+
+ ASSERT_FALSE(ContainsRegistration(provider_context.get(), registration_id));
+ // Should return a registration object newly created with adopting the
+ // refcounts.
+ registration1 =
+ provider_context->GetOrCreateRegistrationForServiceWorkerClient(
+ std::move(info));
+ EXPECT_TRUE(registration1);
+ EXPECT_TRUE(ContainsRegistration(provider_context.get(), registration_id));
+ EXPECT_EQ(registration_id, registration1->RegistrationId());
+ EXPECT_EQ(1, remote_registration_object_host().GetBindingCount());
+ EXPECT_EQ(0UL, ipc_sink()->message_count());
+ }
+
+ ipc_sink()->ClearMessages();
+
+ {
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
+ CreateServiceWorkerRegistrationObjectInfo();
+ // The 2nd Mojo connection has been added.
+ ASSERT_EQ(2, remote_registration_object_host().GetBindingCount());
+ // Should return the same registration object without incrementing the
+ // refcounts.
+ registration2 =
+ provider_context->GetOrCreateRegistrationForServiceWorkerClient(
+ std::move(info));
+ EXPECT_TRUE(registration2);
+ EXPECT_EQ(registration1, registration2);
+ // The 2nd Mojo connection has been dropped.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, remote_registration_object_host().GetBindingCount());
+ ASSERT_EQ(3UL, ipc_sink()->message_count());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(0)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(1)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(2)->type());
+ }
+
+ ipc_sink()->ClearMessages();
+
+ // The registration dtor decrements the refcounts.
+ registration1 = nullptr;
+ registration2 = nullptr;
+ ASSERT_EQ(3UL, ipc_sink()->message_count());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(0)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(1)->type());
+ EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+ ipc_sink()->GetMessageAt(2)->type());
+ // The 1st Mojo connection has been dropped.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(ContainsRegistration(provider_context.get(), registration_id));
+ EXPECT_EQ(0, remote_registration_object_host().GetBindingCount());
+}
+
+} // namespace content
diff --git a/chromium/content/child/service_worker/service_worker_subresource_loader.cc b/chromium/content/renderer/service_worker/service_worker_subresource_loader.cc
index 818c2dad5f2..d0adb6730ec 100644
--- a/chromium/content/child/service_worker/service_worker_subresource_loader.cc
+++ b/chromium/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -2,17 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/service_worker/service_worker_subresource_loader.h"
+#include "content/renderer/service_worker/service_worker_subresource_loader.h"
#include "base/atomic_sequence_num.h"
#include "base/callback.h"
+#include "base/optional.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/service_worker/controller_service_worker_connector.h"
#include "content/common/service_worker/service_worker_loader_helpers.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
+#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/common/content_features.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
+#include "content/renderer/service_worker/controller_service_worker_connector.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "net/url_request/redirect_info.h"
+#include "net/url_request/redirect_util.h"
+#include "net/url_request/url_request.h"
#include "ui/base/page_transition_types.h"
namespace content {
@@ -115,7 +120,7 @@ class HeaderRewritingURLLoaderClient : public mojom::URLLoaderClient {
url_loader_client_->OnStartLoadingResponseBody(std::move(body));
}
- void OnComplete(const ResourceRequestCompletionStatus& status) override {
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override {
DCHECK(url_loader_client_.is_bound());
url_loader_client_->OnComplete(status);
}
@@ -140,12 +145,14 @@ ServiceWorkerSubresourceLoader::ServiceWorkerSubresourceLoader(
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter,
const GURL& controller_origin,
- scoped_refptr<base::RefCountedData<storage::mojom::BlobRegistryPtr>>
+ scoped_refptr<base::RefCountedData<blink::mojom::BlobRegistryPtr>>
blob_registry)
- : url_loader_client_(std::move(client)),
+ : redirect_limit_(net::URLRequest::kMaxRedirects),
+ url_loader_client_(std::move(client)),
url_loader_binding_(this, std::move(request)),
response_callback_binding_(this),
controller_connector_(std::move(controller_connector)),
+ fetch_request_restarted_(false),
routing_id_(routing_id),
request_id_(request_id),
options_(options),
@@ -160,12 +167,15 @@ ServiceWorkerSubresourceLoader::ServiceWorkerSubresourceLoader(
response_head_.request_start = base::TimeTicks::Now();
response_head_.load_timing.request_start = base::TimeTicks::Now();
response_head_.load_timing.request_start_time = base::Time::Now();
+ // base::Unretained() is safe since |url_loader_binding_| is owned by |this|.
url_loader_binding_.set_connection_error_handler(base::BindOnce(
- &ServiceWorkerSubresourceLoader::DeleteSoon, weak_factory_.GetWeakPtr()));
+ &ServiceWorkerSubresourceLoader::DeleteSoon, base::Unretained(this)));
StartRequest(resource_request);
}
-ServiceWorkerSubresourceLoader::~ServiceWorkerSubresourceLoader() = default;
+ServiceWorkerSubresourceLoader::~ServiceWorkerSubresourceLoader() {
+ SettleInflightFetchRequestIfNeeded();
+};
void ServiceWorkerSubresourceLoader::DeleteSoon() {
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
@@ -173,15 +183,16 @@ void ServiceWorkerSubresourceLoader::DeleteSoon() {
void ServiceWorkerSubresourceLoader::StartRequest(
const ResourceRequest& resource_request) {
- // TODO(kinuko): Implement request.request_body handling.
- DCHECK(!resource_request.request_body);
- std::unique_ptr<ServiceWorkerFetchRequest> request =
- ServiceWorkerLoaderHelpers::CreateFetchRequest(resource_request);
DCHECK_EQ(Status::kNotStarted, status_);
status_ = Status::kStarted;
- mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_ptr;
- response_callback_binding_.Bind(mojo::MakeRequest(&response_callback_ptr));
+ DCHECK(
+ !ServiceWorkerUtils::IsMainResourceType(resource_request.resource_type));
+
+ DCHECK(!inflight_fetch_request_);
+ inflight_fetch_request_ = std::make_unique<ResourceRequest>(resource_request);
+ controller_connector_->AddObserver(this);
+ 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
@@ -189,11 +200,30 @@ void ServiceWorkerSubresourceLoader::StartRequest(
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();
- // At this point controller should be non-null.
- // TODO(kinuko): re-start the request if we get connection error before we
- // get response for this.
- controller_connector_->GetControllerServiceWorker()->DispatchFetchEvent(
- *request, std::move(response_callback_ptr),
+ DispatchFetchEvent();
+}
+
+void ServiceWorkerSubresourceLoader::DispatchFetchEvent() {
+ DCHECK(inflight_fetch_request_);
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_ptr;
+ response_callback_binding_.Bind(mojo::MakeRequest(&response_callback_ptr));
+ mojom::ControllerServiceWorker* controller =
+ controller_connector_->GetControllerServiceWorker();
+ // When |controller| is null, the network request will be aborted soon since
+ // the network provider has already been discarded. In that case, We don't
+ // need to return an error as the client must be shutting down.
+ if (!controller) {
+ SettleInflightFetchRequestIfNeeded();
+ return;
+ }
+
+ // TODO(falken): Send client id so FetchEvent#clientId works. We have to
+ // plumb it from the provider host to subresource loader somehow.
+ // (crbug.com/780405)
+ // TODO(kinuko): Implement request timeout and ask the browser to kill
+ // the controller if it takes too long. (crbug.com/774374)
+ controller->DispatchFetchEvent(
+ *inflight_fetch_request_, std::move(response_callback_ptr),
base::BindOnce(&ServiceWorkerSubresourceLoader::OnFetchEventFinished,
weak_factory_.GetWeakPtr()));
}
@@ -201,6 +231,10 @@ void ServiceWorkerSubresourceLoader::StartRequest(
void ServiceWorkerSubresourceLoader::OnFetchEventFinished(
blink::mojom::ServiceWorkerEventStatus status,
base::Time dispatch_event_time) {
+ // Stop restarting logic here since OnFetchEventFinished() indicates that the
+ // fetch event could be successfully dispatched.
+ SettleInflightFetchRequestIfNeeded();
+
switch (status) {
case blink::mojom::ServiceWorkerEventStatus::COMPLETED:
// ServiceWorkerFetchResponseCallback interface (OnResponse*() or
@@ -214,48 +248,88 @@ void ServiceWorkerSubresourceLoader::OnFetchEventFinished(
case blink::mojom::ServiceWorkerEventStatus::ABORTED:
// We have an unexpected error: fetch event dispatch failed. Return
// network error.
- weak_factory_.InvalidateWeakPtrs();
CommitCompleted(net::ERR_FAILED);
}
}
+void ServiceWorkerSubresourceLoader::OnConnectionClosed() {
+ if (!inflight_fetch_request_)
+ return;
+ response_callback_binding_.Close();
+
+ // If the connection to the service worker gets disconnected after dispatching
+ // a fetch event and before getting the response of the fetch event, restart
+ // the fetch event again. If it has already been restarted, that means
+ // starting worker failed. In that case, abort the request.
+ if (fetch_request_restarted_) {
+ SettleInflightFetchRequestIfNeeded();
+ CommitCompleted(net::ERR_FAILED);
+ return;
+ }
+ fetch_request_restarted_ = true;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ServiceWorkerSubresourceLoader::DispatchFetchEvent,
+ weak_factory_.GetWeakPtr()));
+}
+
+void ServiceWorkerSubresourceLoader::SettleInflightFetchRequestIfNeeded() {
+ if (inflight_fetch_request_) {
+ inflight_fetch_request_.reset();
+ controller_connector_->RemoveObserver(this);
+ }
+}
+
void ServiceWorkerSubresourceLoader::OnResponse(
const ServiceWorkerResponse& response,
base::Time dispatch_event_time) {
+ SettleInflightFetchRequestIfNeeded();
StartResponse(response, nullptr /* body_as_blob */,
nullptr /* body_as_stream */);
}
void ServiceWorkerSubresourceLoader::OnResponseBlob(
const ServiceWorkerResponse& response,
- storage::mojom::BlobPtr body_as_blob,
+ blink::mojom::BlobPtr body_as_blob,
base::Time dispatch_event_time) {
+ SettleInflightFetchRequestIfNeeded();
StartResponse(response, std::move(body_as_blob),
nullptr /* body_as_stream */);
}
+void ServiceWorkerSubresourceLoader::OnResponseLegacyBlob(
+ const ServiceWorkerResponse& response,
+ base::Time dispatch_event_time,
+ OnResponseLegacyBlobCallback callback) {
+ NOTREACHED();
+}
+
void ServiceWorkerSubresourceLoader::OnResponseStream(
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
base::Time dispatch_event_time) {
+ SettleInflightFetchRequestIfNeeded();
StartResponse(response, nullptr /* body_as_blob */,
std::move(body_as_stream));
}
void ServiceWorkerSubresourceLoader::OnFallback(
base::Time dispatch_event_time) {
+ SettleInflightFetchRequestIfNeeded();
DCHECK(default_loader_factory_getter_);
+
// 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.
- if ((resource_request_.fetch_request_mode == FETCH_REQUEST_MODE_CORS ||
+ if ((resource_request_.fetch_request_mode ==
+ network::mojom::FetchRequestMode::kCORS ||
resource_request_.fetch_request_mode ==
- FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT) &&
+ network::mojom::FetchRequestMode::kCORSWithForcedPreflight) &&
(!resource_request_.request_initiator.has_value() ||
!resource_request_.request_initiator->IsSameOriginWith(
- url::Origin(resource_request_.url)))) {
+ url::Origin::Create(resource_request_.url)))) {
response_head_.was_fetched_via_service_worker = true;
response_head_.was_fallback_required_by_service_worker = true;
CommitResponseHeaders();
@@ -281,7 +355,7 @@ void ServiceWorkerSubresourceLoader::OnFallback(
void ServiceWorkerSubresourceLoader::StartResponse(
const ServiceWorkerResponse& response,
- storage::mojom::BlobPtr body_as_blob,
+ blink::mojom::BlobPtr body_as_blob,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream) {
// A response with status code 0 is Blink telling us to respond with network
// error.
@@ -297,6 +371,21 @@ void ServiceWorkerSubresourceLoader::StartResponse(
response_head_.response_start = base::TimeTicks::Now();
response_head_.load_timing.receive_headers_end = base::TimeTicks::Now();
+ // 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 */);
+ if (redirect_info_) {
+ if (redirect_limit_-- == 0) {
+ CommitCompleted(net::ERR_TOO_MANY_REDIRECTS);
+ return;
+ }
+ response_head_.encoded_data_length = 0;
+ url_loader_client_->OnReceiveRedirect(*redirect_info_, response_head_);
+ status_ = Status::kCompleted;
+ return;
+ }
+
// Handle a stream response body.
if (!body_as_stream.is_null() && body_as_stream->stream.is_valid()) {
CommitResponseHeaders();
@@ -351,18 +440,39 @@ void ServiceWorkerSubresourceLoader::CommitCompleted(int error_code) {
DCHECK_LT(status_, Status::kCompleted);
DCHECK(url_loader_client_.is_bound());
status_ = Status::kCompleted;
- ResourceRequestCompletionStatus completion_status;
- completion_status.error_code = error_code;
- completion_status.completion_time = base::TimeTicks::Now();
- url_loader_client_->OnComplete(completion_status);
+ network::URLLoaderCompletionStatus status;
+ status.error_code = error_code;
+ status.completion_time = base::TimeTicks::Now();
+ url_loader_client_->OnComplete(status);
}
// ServiceWorkerSubresourceLoader: URLLoader implementation -----------------
void ServiceWorkerSubresourceLoader::FollowRedirect() {
- // TODO(kinuko): Need to implement for the cases where a redirect is returned
- // by a ServiceWorker and the page determined to follow the redirect.
- NOTIMPLEMENTED();
+ DCHECK(redirect_info_);
+
+ bool should_clear_upload = false;
+ net::RedirectUtil::UpdateHttpRequest(
+ resource_request_.url, resource_request_.method, *redirect_info_,
+ &resource_request_.headers, &should_clear_upload);
+ if (should_clear_upload)
+ resource_request_.request_body = nullptr;
+
+ resource_request_.url = redirect_info_->new_url;
+ resource_request_.method = redirect_info_->new_method;
+ resource_request_.site_for_cookies = redirect_info_->new_site_for_cookies;
+ resource_request_.referrer = GURL(redirect_info_->new_referrer);
+ resource_request_.referrer_policy =
+ Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+ redirect_info_->new_referrer_policy);
+
+ // Restart the request.
+ status_ = Status::kNotStarted;
+ redirect_info_.reset();
+ response_callback_binding_.Close();
+ // We don't support the body of redirect responses.
+ DCHECK(!blob_loader_);
+ StartRequest(resource_request_);
}
void ServiceWorkerSubresourceLoader::SetPriority(net::RequestPriority priority,
@@ -429,7 +539,7 @@ void ServiceWorkerSubresourceLoader::OnStartLoadingResponseBody(
}
void ServiceWorkerSubresourceLoader::OnComplete(
- const ResourceRequestCompletionStatus& status) {
+ const network::URLLoaderCompletionStatus& status) {
DCHECK_EQ(Status::kSentHeader, status_);
DCHECK(url_loader_client_.is_bound());
status_ = Status::kCompleted;
@@ -442,7 +552,7 @@ ServiceWorkerSubresourceLoaderFactory::ServiceWorkerSubresourceLoaderFactory(
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter,
const GURL& controller_origin,
- scoped_refptr<base::RefCountedData<storage::mojom::BlobRegistryPtr>>
+ scoped_refptr<base::RefCountedData<blink::mojom::BlobRegistryPtr>>
blob_registry)
: controller_connector_(std::move(controller_connector)),
default_loader_factory_getter_(std::move(default_loader_factory_getter)),
diff --git a/chromium/content/child/service_worker/service_worker_subresource_loader.h b/chromium/content/renderer/service_worker/service_worker_subresource_loader.h
index 4fd31beb94a..6f52f4bb4d0 100644
--- a/chromium/content/child/service_worker/service_worker_subresource_loader.h
+++ b/chromium/content/renderer/service_worker/service_worker_subresource_loader.h
@@ -2,20 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_SUBRESOURCE_LOADER_H_
-#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_SUBRESOURCE_LOADER_H_
+#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_SUBRESOURCE_LOADER_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_SUBRESOURCE_LOADER_H_
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
#include "base/time/time.h"
-#include "content/child/service_worker/controller_service_worker_connector.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_fetch_response_callback.mojom.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/renderer/service_worker/controller_service_worker_connector.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "storage/public/interfaces/blobs.mojom.h"
+#include "net/url_request/redirect_info.h"
+#include "third_party/WebKit/common/blob/blob.mojom.h"
+#include "third_party/WebKit/common/blob/blob_registry.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_stream_handle.mojom.h"
@@ -32,7 +35,8 @@ class ControllerServiceWorkerConnector;
class CONTENT_EXPORT ServiceWorkerSubresourceLoader
: public mojom::URLLoader,
public mojom::URLLoaderClient,
- public mojom::ServiceWorkerFetchResponseCallback {
+ public mojom::ServiceWorkerFetchResponseCallback,
+ public ControllerServiceWorkerConnector::Observer {
public:
// See the comments for ServiceWorkerSubresourceLoaderFactory's ctor (below)
// to see how each parameter is used.
@@ -47,24 +51,32 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter,
const GURL& controller_origin,
- scoped_refptr<base::RefCountedData<storage::mojom::BlobRegistryPtr>>
+ scoped_refptr<base::RefCountedData<blink::mojom::BlobRegistryPtr>>
blob_registry);
~ServiceWorkerSubresourceLoader() override;
+ // ControllerServiceWorkerConnector::Observer overrdies:
+ void OnConnectionClosed() override;
+
private:
void DeleteSoon();
void StartRequest(const ResourceRequest& resource_request);
+ void DispatchFetchEvent();
void OnFetchEventFinished(blink::mojom::ServiceWorkerEventStatus status,
base::Time dispatch_event_time);
+ void SettleInflightFetchRequestIfNeeded();
// mojom::ServiceWorkerFetchResponseCallback overrides:
void OnResponse(const ServiceWorkerResponse& response,
base::Time dispatch_event_time) override;
void OnResponseBlob(const ServiceWorkerResponse& response,
- storage::mojom::BlobPtr blob,
+ blink::mojom::BlobPtr blob,
base::Time dispatch_event_time) override;
+ void OnResponseLegacyBlob(const ServiceWorkerResponse& response,
+ base::Time dispatch_event_time,
+ OnResponseLegacyBlobCallback callback) override;
void OnResponseStream(
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
@@ -72,7 +84,7 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
void OnFallback(base::Time dispatch_event_time) override;
void StartResponse(const ServiceWorkerResponse& response,
- storage::mojom::BlobPtr blob,
+ blink::mojom::BlobPtr blob,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream);
// mojom::URLLoader overrides:
@@ -103,9 +115,11 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- void OnComplete(const ResourceRequestCompletionStatus& status) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
ResourceResponseHead response_head_;
+ base::Optional<net::RedirectInfo> redirect_info_;
+ int redirect_limit_;
mojom::URLLoaderClientPtr url_loader_client_;
mojo::Binding<mojom::URLLoader> url_loader_binding_;
@@ -115,6 +129,9 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
scoped_refptr<ControllerServiceWorkerConnector> controller_connector_;
+ std::unique_ptr<ResourceRequest> inflight_fetch_request_;
+ bool fetch_request_restarted_;
+
// These are given by the constructor (as the params for
// URLLoaderFactory::CreateLoaderAndStart).
const int routing_id_;
@@ -124,11 +141,11 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
// To load a blob.
- storage::mojom::BlobURLHandlePtr blob_url_handle_;
+ blink::mojom::BlobURLHandlePtr blob_url_handle_;
GURL controller_origin_;
mojom::URLLoaderPtr blob_loader_;
mojo::Binding<mojom::URLLoaderClient> blob_client_binding_;
- scoped_refptr<base::RefCountedData<storage::mojom::BlobRegistryPtr>>
+ scoped_refptr<base::RefCountedData<blink::mojom::BlobRegistryPtr>>
blob_registry_;
// For Blob loading and network fallback loading.
@@ -165,7 +182,7 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoaderFactory
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
scoped_refptr<ChildURLLoaderFactoryGetter> default_loader_factory_getter,
const GURL& controller_origin,
- scoped_refptr<base::RefCountedData<storage::mojom::BlobRegistryPtr>>
+ scoped_refptr<base::RefCountedData<blink::mojom::BlobRegistryPtr>>
blob_registry);
~ServiceWorkerSubresourceLoaderFactory() override;
@@ -190,7 +207,7 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoaderFactory
GURL controller_origin_;
- scoped_refptr<base::RefCountedData<storage::mojom::BlobRegistryPtr>>
+ scoped_refptr<base::RefCountedData<blink::mojom::BlobRegistryPtr>>
blob_registry_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSubresourceLoaderFactory);
@@ -198,4 +215,4 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoaderFactory
} // namespace content
-#endif // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_SUBRESOURCE_LOADER_H_
+#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_SUBRESOURCE_LOADER_H_
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
new file mode 100644
index 00000000000..ebb4b79f70b
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
@@ -0,0 +1,844 @@
+// Copyright 2017 The Chromium Authors. 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/service_worker_subresource_loader.h"
+
+#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/test/scoped_feature_list.h"
+#include "content/common/service_worker/service_worker_container.mojom.h"
+#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/resource_type.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_url_loader_client.h"
+#include "content/renderer/loader/child_url_loader_factory_getter_impl.h"
+#include "content/renderer/service_worker/controller_service_worker_connector.h"
+#include "mojo/common/data_pipe_utils.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "net/http/http_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "net/url_request/url_request.h"
+#include "storage/browser/blob/blob_data_builder.h"
+#include "storage/browser/blob/blob_data_handle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/origin.h"
+
+namespace content {
+
+namespace {
+
+// This class need to set ChildURLLoaderFactoryGetter. CreateLoaderAndStart()
+// need to implement. todo(emim): Merge this and the one in
+// service_worker_url_loader_job_unittest.cc.
+class FakeNetworkURLLoaderFactory final : public mojom::URLLoaderFactory {
+ public:
+ FakeNetworkURLLoaderFactory() = default;
+
+ // mojom::URLLoaderFactory implementation.
+ void CreateLoaderAndStart(mojom::URLLoaderRequest request,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const ResourceRequest& url_request,
+ mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag&
+ traffic_annotation) override {
+ std::string headers = "HTTP/1.1 200 OK\n\n";
+ net::HttpResponseInfo info;
+ info.headers = new net::HttpResponseHeaders(
+ net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.length()));
+ ResourceResponseHead response;
+ response.headers = info.headers;
+ response.headers->GetMimeType(&response.mime_type);
+ client->OnReceiveResponse(response, base::nullopt, nullptr);
+
+ std::string body = "this body came from the network";
+ uint32_t bytes_written = body.size();
+ mojo::DataPipe data_pipe;
+ data_pipe.producer_handle->WriteData(body.data(), &bytes_written,
+ MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
+ client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
+
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::OK;
+ client->OnComplete(status);
+ }
+
+ void Clone(mojom::URLLoaderFactoryRequest factory) override { NOTREACHED(); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FakeNetworkURLLoaderFactory);
+};
+
+class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
+ public:
+ FakeControllerServiceWorker() = default;
+ ~FakeControllerServiceWorker() override = default;
+
+ void CloseAllBindings() { bindings_.CloseAllBindings(); }
+
+ // Tells this controller to abort the fetch event without a response.
+ // i.e., simulate the service worker failing to handle the fetch event.
+ void AbortEventWithNoResponse() { response_mode_ = ResponseMode::kAbort; }
+
+ // Tells this controller to respond to fetch events with network fallback.
+ // i.e., simulate the service worker not calling respondWith().
+ void RespondWithFallback() {
+ response_mode_ = ResponseMode::kFallbackResponse;
+ }
+
+ // Tells this controller to respond to fetch events with the specified stream.
+ void RespondWithStream(
+ blink::mojom::ServiceWorkerStreamCallbackRequest callback_request,
+ mojo::ScopedDataPipeConsumerHandle consumer_handle) {
+ response_mode_ = ResponseMode::kStream;
+ stream_handle_ = blink::mojom::ServiceWorkerStreamHandle::New();
+ stream_handle_->callback_request = std::move(callback_request);
+ stream_handle_->stream = std::move(consumer_handle);
+ }
+
+ // Tells this controller to respond to fetch events with a error response.
+ void RespondWithError() { response_mode_ = ResponseMode::kErrorResponse; }
+
+ // Tells this controller to respond to fetch events with a redirect response.
+ void RespondWithRedirect(const std::string& redirect_location_header) {
+ response_mode_ = ResponseMode::kRedirectResponse;
+ redirect_location_header_ = redirect_location_header;
+ }
+
+ void ReadRequestBody(std::string* out_string) {
+ ASSERT_TRUE(request_body_);
+ const std::vector<ResourceRequestBody::Element>* elements =
+ request_body_->elements();
+ // So far this test expects a single bytes element.
+ ASSERT_EQ(1u, elements->size());
+ const ResourceRequestBody::Element& element = elements->front();
+ ASSERT_EQ(ResourceRequestBody::Element::TYPE_BYTES, element.type());
+ *out_string = std::string(element.bytes(), element.length());
+ }
+
+ // mojom::ControllerServiceWorker:
+ void DispatchFetchEvent(
+ const ResourceRequest& request,
+ mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
+ DispatchFetchEventCallback callback) override {
+ EXPECT_FALSE(ServiceWorkerUtils::IsMainResourceType(request.resource_type));
+ request_body_ = request.request_body;
+
+ fetch_event_count_++;
+ fetch_event_request_ = request;
+ switch (response_mode_) {
+ case ResponseMode::kDefault:
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
+ break;
+ case ResponseMode::kAbort:
+ std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::ABORTED,
+ base::Time());
+ break;
+ case ResponseMode::kStream:
+ response_callback->OnResponseStream(
+ ServiceWorkerResponse(
+ std::make_unique<std::vector<GURL>>(), 200, "OK",
+ network::mojom::FetchResponseType::kDefault,
+ std::make_unique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
+ 0 /* blob_size */, nullptr /* blob */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown,
+ base::Time(), false /* response_is_in_cache_storage */,
+ std::string() /* response_cache_storage_cache_name */,
+ std::make_unique<
+ ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
+ std::move(stream_handle_), base::Time::Now());
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
+ break;
+ case ResponseMode::kFallbackResponse:
+ response_callback->OnFallback(base::Time::Now());
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerEventStatus::COMPLETED,
+ base::Time::Now());
+ break;
+ case ResponseMode::kErrorResponse:
+ response_callback->OnResponse(
+ ServiceWorkerResponse(
+ std::make_unique<std::vector<GURL>>(), 0 /* status_code */,
+ "" /* status_text */,
+ network::mojom::FetchResponseType::kDefault,
+ std::make_unique<ServiceWorkerHeaderMap>(), "" /* blob_uuid */,
+ 0 /* blob_size */, nullptr /* blob */,
+ blink::mojom::ServiceWorkerResponseError::kPromiseRejected,
+ base::Time(), false /* response_is_in_cache_storage */,
+ std::string() /* response_cache_storage_cache_name */,
+ std::make_unique<
+ ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
+ base::Time::Now());
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerEventStatus::REJECTED,
+ base::Time::Now());
+ break;
+ case ResponseMode::kRedirectResponse: {
+ auto headers = std::make_unique<ServiceWorkerHeaderMap>();
+ (*headers)["Location"] = redirect_location_header_;
+ response_callback->OnResponse(
+ ServiceWorkerResponse(
+ std::make_unique<std::vector<GURL>>(), 302, "Found",
+ network::mojom::FetchResponseType::kDefault, std::move(headers),
+ "" /* blob_uuid */, 0 /* blob_size */, nullptr /* blob */,
+ blink::mojom::ServiceWorkerResponseError::kUnknown,
+ base::Time(), false /* response_is_in_cache_storage */,
+ std::string() /* response_cache_storage_cache_name */,
+ std::make_unique<
+ ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
+ base::Time::Now());
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
+ } break;
+ }
+ if (fetch_event_callback_)
+ std::move(fetch_event_callback_).Run();
+ }
+
+ void Clone(mojom::ControllerServiceWorkerRequest request) override {
+ bindings_.AddBinding(this, std::move(request));
+ }
+
+ void RunUntilFetchEvent() {
+ base::RunLoop loop;
+ fetch_event_callback_ = loop.QuitClosure();
+ loop.Run();
+ }
+
+ int fetch_event_count() const { return fetch_event_count_; }
+ const ResourceRequest& fetch_event_request() const {
+ return fetch_event_request_;
+ }
+
+ private:
+ enum class ResponseMode {
+ kDefault,
+ kAbort,
+ kStream,
+ kFallbackResponse,
+ kErrorResponse,
+ kRedirectResponse
+ };
+
+ ResponseMode response_mode_ = ResponseMode::kDefault;
+ scoped_refptr<ResourceRequestBody> request_body_;
+
+ int fetch_event_count_ = 0;
+ ResourceRequest fetch_event_request_;
+ base::OnceClosure fetch_event_callback_;
+ mojo::BindingSet<mojom::ControllerServiceWorker> bindings_;
+
+ // For ResponseMode::kStream.
+ blink::mojom::ServiceWorkerStreamHandlePtr stream_handle_;
+
+ // For ResponseMode::kRedirectResponse
+ std::string redirect_location_header_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeControllerServiceWorker);
+};
+
+class FakeServiceWorkerContainerHost
+ : public mojom::ServiceWorkerContainerHost {
+ public:
+ explicit FakeServiceWorkerContainerHost(
+ FakeControllerServiceWorker* fake_controller)
+ : fake_controller_(fake_controller) {}
+
+ ~FakeServiceWorkerContainerHost() override = default;
+
+ void set_fake_controller(FakeControllerServiceWorker* new_fake_controller) {
+ fake_controller_ = new_fake_controller;
+ }
+
+ int get_controller_service_worker_count() const {
+ return get_controller_service_worker_count_;
+ }
+
+ private:
+ // Implements mojom::ServiceWorkerContainerHost.
+ void Register(const GURL& script_url,
+ blink::mojom::ServiceWorkerRegistrationOptionsPtr options,
+ RegisterCallback callback) override {
+ NOTIMPLEMENTED();
+ }
+ void GetRegistration(const GURL& client_url,
+ GetRegistrationCallback callback) override {
+ NOTIMPLEMENTED();
+ }
+ void GetRegistrations(GetRegistrationsCallback callback) override {
+ NOTIMPLEMENTED();
+ }
+ void GetRegistrationForReady(
+ GetRegistrationForReadyCallback callback) override {
+ NOTIMPLEMENTED();
+ }
+ void GetControllerServiceWorker(
+ mojom::ControllerServiceWorkerRequest request) override {
+ get_controller_service_worker_count_++;
+ if (!fake_controller_)
+ return;
+ fake_controller_->Clone(std::move(request));
+ }
+ void CloneForWorker(
+ mojom::ServiceWorkerContainerHostRequest request) override {
+ NOTIMPLEMENTED();
+ }
+
+ int get_controller_service_worker_count_ = 0;
+ FakeControllerServiceWorker* fake_controller_;
+ DISALLOW_COPY_AND_ASSIGN(FakeServiceWorkerContainerHost);
+};
+
+} // namespace
+
+
+class ServiceWorkerSubresourceLoaderTest : public ::testing::Test {
+ protected:
+ ServiceWorkerSubresourceLoaderTest()
+ : fake_container_host_(&fake_controller_) {}
+ ~ServiceWorkerSubresourceLoaderTest() override = default;
+
+ void SetUp() override {
+ feature_list_.InitAndEnableFeature(features::kNetworkService);
+
+ mojom::URLLoaderFactoryPtr fake_loader_factory;
+ mojo::MakeStrongBinding(std::make_unique<FakeNetworkURLLoaderFactory>(),
+ MakeRequest(&fake_loader_factory));
+ loader_factory_getter_ =
+ base::MakeRefCounted<ChildURLLoaderFactoryGetterImpl>(
+ std::move(fake_loader_factory), nullptr);
+ }
+
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory>
+ CreateSubresourceLoaderFactory(const GURL& controller_origin) {
+ auto connector = base::MakeRefCounted<ControllerServiceWorkerConnector>(
+ &fake_container_host_);
+ return std::make_unique<ServiceWorkerSubresourceLoaderFactory>(
+ connector, loader_factory_getter_, controller_origin,
+ base::MakeRefCounted<
+ base::RefCountedData<blink::mojom::BlobRegistryPtr>>());
+ }
+
+ // Starts |request| using |loader_factory| and sets |out_loader| and
+ // |out_loader_client| to the resulting URLLoader and its URLLoaderClient. The
+ // caller can then use functions like client.RunUntilComplete() to wait for
+ // completion. Calling fake_controller_->RunUntilFetchEvent() also advances
+ // the load to until |fake_controller_| receives the fetch event.
+ void StartRequest(ServiceWorkerSubresourceLoaderFactory* loader_factory,
+ const ResourceRequest& request,
+ mojom::URLLoaderPtr* out_loader,
+ std::unique_ptr<TestURLLoaderClient>* out_loader_client) {
+ *out_loader_client = std::make_unique<TestURLLoaderClient>();
+ loader_factory->CreateLoaderAndStart(
+ mojo::MakeRequest(out_loader), 0, 0, mojom::kURLLoadOptionNone, request,
+ (*out_loader_client)->CreateInterfacePtr(),
+ net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
+ }
+
+ ResourceRequest CreateRequest(const GURL& url) {
+ ResourceRequest request;
+ request.url = url;
+ request.method = "GET";
+ request.resource_type = RESOURCE_TYPE_SUB_RESOURCE;
+ return request;
+ }
+
+ TestBrowserThreadBundle thread_bundle_;
+ scoped_refptr<ChildURLLoaderFactoryGetter> loader_factory_getter_;
+
+ FakeServiceWorkerContainerHost fake_container_host_;
+ FakeControllerServiceWorker fake_controller_;
+ base::test::ScopedFeatureList feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSubresourceLoaderTest);
+};
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, Basic) {
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ fake_controller_.RunUntilFetchEvent();
+
+ EXPECT_EQ(request.url, fake_controller_.fetch_event_request().url);
+ EXPECT_EQ(request.method, fake_controller_.fetch_event_request().method);
+ EXPECT_EQ(1, fake_controller_.fetch_event_count());
+ EXPECT_EQ(1, fake_container_host_.get_controller_service_worker_count());
+}
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, Abort) {
+ fake_controller_.AbortEventWithNoResponse();
+
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+
+ // Perform the request.
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ client->RunUntilComplete();
+
+ EXPECT_EQ(net::ERR_FAILED, client->completion_status().error_code);
+}
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, DropController) {
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+ {
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ fake_controller_.RunUntilFetchEvent();
+
+ EXPECT_EQ(request.url, fake_controller_.fetch_event_request().url);
+ EXPECT_EQ(request.method, fake_controller_.fetch_event_request().method);
+ EXPECT_EQ(1, fake_controller_.fetch_event_count());
+ EXPECT_EQ(1, fake_container_host_.get_controller_service_worker_count());
+ }
+
+ // Loading another resource reuses the existing connection to the
+ // ControllerServiceWorker (i.e. it doesn't increase the get controller
+ // service worker count).
+ {
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo2.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ fake_controller_.RunUntilFetchEvent();
+
+ EXPECT_EQ(request.url, fake_controller_.fetch_event_request().url);
+ EXPECT_EQ(request.method, fake_controller_.fetch_event_request().method);
+ EXPECT_EQ(2, fake_controller_.fetch_event_count());
+ EXPECT_EQ(1, fake_container_host_.get_controller_service_worker_count());
+ }
+
+ // Drop the connection to the ControllerServiceWorker.
+ fake_controller_.CloseAllBindings();
+ base::RunLoop().RunUntilIdle();
+
+ {
+ // This should re-obtain the ControllerServiceWorker.
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo3.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ fake_controller_.RunUntilFetchEvent();
+
+ EXPECT_EQ(request.url, fake_controller_.fetch_event_request().url);
+ EXPECT_EQ(request.method, fake_controller_.fetch_event_request().method);
+ EXPECT_EQ(3, fake_controller_.fetch_event_count());
+ EXPECT_EQ(2, fake_container_host_.get_controller_service_worker_count());
+ }
+}
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, DropController_RestartFetchEvent) {
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+
+ {
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ fake_controller_.RunUntilFetchEvent();
+
+ EXPECT_EQ(request.url, fake_controller_.fetch_event_request().url);
+ EXPECT_EQ(request.method, fake_controller_.fetch_event_request().method);
+ EXPECT_EQ(1, fake_controller_.fetch_event_count());
+ EXPECT_EQ(1, fake_container_host_.get_controller_service_worker_count());
+ }
+
+ // Loading another resource reuses the existing connection to the
+ // ControllerServiceWorker (i.e. it doesn't increase the get controller
+ // service worker count).
+ {
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo2.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ fake_controller_.RunUntilFetchEvent();
+
+ EXPECT_EQ(request.url, fake_controller_.fetch_event_request().url);
+ EXPECT_EQ(request.method, fake_controller_.fetch_event_request().method);
+ EXPECT_EQ(2, fake_controller_.fetch_event_count());
+ EXPECT_EQ(1, fake_container_host_.get_controller_service_worker_count());
+ }
+
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo3.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+
+ // Drop the connection to the ControllerServiceWorker.
+ fake_controller_.CloseAllBindings();
+ base::RunLoop().RunUntilIdle();
+
+ // If connection is closed during fetch event, it's restarted and successfully
+ // finishes.
+ EXPECT_EQ(request.url, fake_controller_.fetch_event_request().url);
+ EXPECT_EQ(request.method, fake_controller_.fetch_event_request().method);
+ EXPECT_EQ(3, fake_controller_.fetch_event_count());
+ EXPECT_EQ(2, fake_container_host_.get_controller_service_worker_count());
+}
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, DropController_TooManyRestart) {
+ // Simulate the container host fails to start a service worker.
+ fake_container_host_.set_fake_controller(nullptr);
+
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+
+ // Try to dispatch fetch event to the bad worker.
+ base::RunLoop().RunUntilIdle();
+
+ // The request should be failed instead of infinite loop to restart the
+ // inflight fetch event.
+ EXPECT_EQ(2, fake_container_host_.get_controller_service_worker_count());
+ EXPECT_TRUE(client->has_received_completion());
+ EXPECT_EQ(net::ERR_FAILED, client->completion_status().error_code);
+}
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, StreamResponse) {
+ // Construct the Stream to respond with.
+ const char kResponseBody[] = "Here is sample text for the Stream.";
+ blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
+ mojo::DataPipe data_pipe;
+ fake_controller_.RespondWithStream(mojo::MakeRequest(&stream_callback),
+ std::move(data_pipe.consumer_handle));
+
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+
+ // Perform the request.
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ client->RunUntilResponseReceived();
+
+ const ResourceResponseHead& info = client->response_head();
+ EXPECT_EQ(200, info.headers->response_code());
+ EXPECT_EQ(true, info.was_fetched_via_service_worker);
+ EXPECT_EQ(false, info.was_fallback_required_by_service_worker);
+ EXPECT_EQ(std::vector<GURL>(), info.url_list_via_service_worker);
+ EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
+ info.response_type_via_service_worker);
+ EXPECT_EQ(false, info.is_in_cache_storage);
+ EXPECT_EQ(std::string(), info.cache_storage_cache_name);
+ EXPECT_EQ(false, info.did_service_worker_navigation_preload);
+ EXPECT_NE(base::TimeTicks(), info.service_worker_start_time);
+ EXPECT_NE(base::TimeTicks(), info.service_worker_ready_time);
+
+ // Write the body stream.
+ 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);
+ stream_callback->OnCompleted();
+ data_pipe.producer_handle.reset();
+
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+
+ // Test the body.
+ std::string response;
+ EXPECT_TRUE(client->response_body().is_valid());
+ EXPECT_TRUE(mojo::common::BlockingCopyToString(
+ client->response_body_release(), &response));
+ EXPECT_EQ(kResponseBody, response);
+}
+
+// Test when the service worker responds with network fallback.
+// i.e., does not call respondWith().
+TEST_F(ServiceWorkerSubresourceLoaderTest, FallbackResponse) {
+ fake_controller_.RespondWithFallback();
+
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+
+ // Perform the request.
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ client->RunUntilComplete();
+
+ // OnFallback() should complete the network request using network loader.
+ EXPECT_TRUE(client->has_received_completion());
+ EXPECT_FALSE(client->response_head().was_fetched_via_service_worker);
+}
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, ErrorResponse) {
+ fake_controller_.RespondWithError();
+
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+
+ // Perform the request.
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ client->RunUntilComplete();
+
+ EXPECT_EQ(net::ERR_FAILED, client->completion_status().error_code);
+}
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, RedirectResponse) {
+ fake_controller_.RespondWithRedirect("https://www.example.com/bar.png");
+
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+
+ // Perform the request.
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ client->RunUntilRedirectReceived();
+
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+ EXPECT_TRUE(client->has_received_redirect());
+ {
+ const net::RedirectInfo& redirect_info = client->redirect_info();
+ EXPECT_EQ(302, redirect_info.status_code);
+ EXPECT_EQ("GET", redirect_info.new_method);
+ EXPECT_EQ(GURL("https://www.example.com/bar.png"), redirect_info.new_url);
+ }
+ client->ClearHasReceivedRedirect();
+
+ // Redirect once more.
+ fake_controller_.RespondWithRedirect("https://other.example.com/baz.png");
+ loader->FollowRedirect();
+ client->RunUntilRedirectReceived();
+
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+ EXPECT_TRUE(client->has_received_redirect());
+ {
+ const net::RedirectInfo& redirect_info = client->redirect_info();
+ EXPECT_EQ(302, redirect_info.status_code);
+ EXPECT_EQ("GET", redirect_info.new_method);
+ EXPECT_EQ(GURL("https://other.example.com/baz.png"), redirect_info.new_url);
+ }
+ client->ClearHasReceivedRedirect();
+
+ // Give the final response.
+ const char kResponseBody[] = "Here is sample text for the Stream.";
+ blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
+ mojo::DataPipe data_pipe;
+ fake_controller_.RespondWithStream(mojo::MakeRequest(&stream_callback),
+ std::move(data_pipe.consumer_handle));
+ loader->FollowRedirect();
+ client->RunUntilResponseReceived();
+
+ const ResourceResponseHead& info = client->response_head();
+ EXPECT_EQ(200, info.headers->response_code());
+ EXPECT_EQ(network::mojom::FetchResponseType::kDefault,
+ info.response_type_via_service_worker);
+
+ // Write the body stream.
+ 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);
+ stream_callback->OnCompleted();
+ data_pipe.producer_handle.reset();
+
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+
+ // Test the body.
+ std::string response;
+ EXPECT_TRUE(client->response_body().is_valid());
+ EXPECT_TRUE(mojo::common::BlockingCopyToString(
+ client->response_body_release(), &response));
+ EXPECT_EQ(kResponseBody, response);
+}
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, TooManyRedirects) {
+ int count = 1;
+ std::string redirect_location =
+ std::string("https://www.example.com/redirect_") +
+ base::IntToString(count);
+ fake_controller_.RespondWithRedirect(redirect_location);
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+
+ // Perform the request.
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+
+ // The Fetch spec says: "If request’s redirect count is twenty, return a
+ // network error." https://fetch.spec.whatwg.org/#http-redirect-fetch
+ // So fetch can follow the redirect response until 20 times.
+ static_assert(net::URLRequest::kMaxRedirects == 20,
+ "The Fetch spec requires kMaxRedirects to be 20");
+ for (; count < net::URLRequest::kMaxRedirects + 1; ++count) {
+ client->RunUntilRedirectReceived();
+
+ EXPECT_TRUE(client->has_received_redirect());
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+ const net::RedirectInfo& redirect_info = client->redirect_info();
+ EXPECT_EQ(302, redirect_info.status_code);
+ EXPECT_EQ("GET", redirect_info.new_method);
+ EXPECT_EQ(GURL(redirect_location), redirect_info.new_url);
+
+ client->ClearHasReceivedRedirect();
+
+ // Redirect more.
+ redirect_location = std::string("https://www.example.com/redirect_") +
+ base::IntToString(count);
+ fake_controller_.RespondWithRedirect(redirect_location);
+ loader->FollowRedirect();
+ }
+ client->RunUntilComplete();
+
+ // Fetch can't follow the redirect response 21 times.
+ EXPECT_FALSE(client->has_received_redirect());
+ EXPECT_EQ(net::ERR_TOO_MANY_REDIRECTS,
+ client->completion_status().error_code);
+}
+
+// Test when the service worker responds with network fallback to CORS request.
+TEST_F(ServiceWorkerSubresourceLoaderTest, CORSFallbackResponse) {
+ fake_controller_.RespondWithFallback();
+
+ const GURL kScope("https://www.example.com/");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kScope.GetOrigin());
+
+ struct TestCase {
+ network::mojom::FetchRequestMode fetch_request_mode;
+ base::Optional<url::Origin> request_initiator;
+ bool expected_was_fallback_required_by_service_worker;
+ };
+ const TestCase kTests[] = {
+ {network::mojom::FetchRequestMode::kSameOrigin,
+ base::Optional<url::Origin>(), false},
+ {network::mojom::FetchRequestMode::kNoCORS, base::Optional<url::Origin>(),
+ false},
+ {network::mojom::FetchRequestMode::kCORS, base::Optional<url::Origin>(),
+ true},
+ {network::mojom::FetchRequestMode::kCORSWithForcedPreflight,
+ base::Optional<url::Origin>(), true},
+ {network::mojom::FetchRequestMode::kNavigate,
+ base::Optional<url::Origin>(), false},
+ {network::mojom::FetchRequestMode::kSameOrigin,
+ url::Origin::Create(GURL("https://www.example.com/")), false},
+ {network::mojom::FetchRequestMode::kNoCORS,
+ url::Origin::Create(GURL("https://www.example.com/")), false},
+ {network::mojom::FetchRequestMode::kCORS,
+ url::Origin::Create(GURL("https://www.example.com/")), false},
+ {network::mojom::FetchRequestMode::kCORSWithForcedPreflight,
+ url::Origin::Create(GURL("https://www.example.com/")), false},
+ {network::mojom::FetchRequestMode::kNavigate,
+ url::Origin::Create(GURL("https://other.example.com/")), false},
+ {network::mojom::FetchRequestMode::kSameOrigin,
+ url::Origin::Create(GURL("https://other.example.com/")), false},
+ {network::mojom::FetchRequestMode::kNoCORS,
+ url::Origin::Create(GURL("https://other.example.com/")), false},
+ {network::mojom::FetchRequestMode::kCORS,
+ url::Origin::Create(GURL("https://other.example.com/")), true},
+ {network::mojom::FetchRequestMode::kCORSWithForcedPreflight,
+ url::Origin::Create(GURL("https://other.example.com/")), true},
+ {network::mojom::FetchRequestMode::kNavigate,
+ url::Origin::Create(GURL("https://other.example.com/")), false}};
+
+ for (const auto& test : kTests) {
+ SCOPED_TRACE(
+ ::testing::Message()
+ << "fetch_request_mode: " << static_cast<int>(test.fetch_request_mode)
+ << " request_initiator: "
+ << (test.request_initiator ? test.request_initiator->Serialize()
+ : std::string("null")));
+ // Perform the request.
+ ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ request.fetch_request_mode = test.fetch_request_mode;
+ request.request_initiator = test.request_initiator;
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ client->RunUntilResponseReceived();
+
+ const ResourceResponseHead& info = client->response_head();
+ EXPECT_EQ(test.expected_was_fallback_required_by_service_worker,
+ info.was_fetched_via_service_worker);
+ EXPECT_EQ(test.expected_was_fallback_required_by_service_worker,
+ info.was_fallback_required_by_service_worker);
+ }
+}
+
+// Test that the request body is passed to the fetch event.
+TEST_F(ServiceWorkerSubresourceLoaderTest, RequestBody) {
+ const GURL kUrl("https://www.example.com");
+ std::unique_ptr<ServiceWorkerSubresourceLoaderFactory> factory =
+ CreateSubresourceLoaderFactory(kUrl.GetOrigin());
+
+ // Create a request with a body.
+ auto request_body = base::MakeRefCounted<ResourceRequestBody>();
+ const std::string kData = "hi this is the request body";
+ request_body->AppendBytes(kData.c_str(), kData.length());
+ ResourceRequest request = CreateRequest(kUrl);
+ request.method = "POST";
+ request.request_body = request_body;
+
+ // This test doesn't use the response to the fetch event, so just have the
+ // service worker do simple network fallback.
+ fake_controller_.RespondWithFallback();
+
+ // Perform the request.
+ mojom::URLLoaderPtr loader;
+ std::unique_ptr<TestURLLoaderClient> client;
+ StartRequest(factory.get(), request, &loader, &client);
+ fake_controller_.RunUntilFetchEvent();
+
+ // Verify that the request body was passed to the fetch event.
+ std::string body;
+ fake_controller_.ReadRequestBody(&body);
+ EXPECT_EQ(kData, body);
+}
+
+} // 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
new file mode 100644
index 00000000000..48edbd10493
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_timeout_timer.cc
@@ -0,0 +1,118 @@
+// Copyright 2017 The Chromium Authors. 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/service_worker_timeout_timer.h"
+
+#include "base/stl_util.h"
+#include "base/time/default_tick_clock.h"
+#include "base/time/time.h"
+#include "content/common/service_worker/service_worker_utils.h"
+
+namespace content {
+
+namespace {
+
+int NextEventId() {
+ // Event id should not start from zero since HashMap in Blink requires
+ // non-zero keys.
+ static int s_next_event_id = 1;
+ CHECK_LT(s_next_event_id, std::numeric_limits<int>::max());
+ return s_next_event_id++;
+}
+
+} // namespace
+
+// static
+constexpr base::TimeDelta ServiceWorkerTimeoutTimer::kIdleDelay;
+constexpr base::TimeDelta ServiceWorkerTimeoutTimer::kEventTimeout;
+constexpr base::TimeDelta ServiceWorkerTimeoutTimer::kUpdateInterval;
+
+ServiceWorkerTimeoutTimer::ServiceWorkerTimeoutTimer(
+ base::RepeatingClosure idle_callback)
+ : ServiceWorkerTimeoutTimer(std::move(idle_callback),
+ std::make_unique<base::DefaultTickClock>()) {}
+
+ServiceWorkerTimeoutTimer::ServiceWorkerTimeoutTimer(
+ base::RepeatingClosure idle_callback,
+ std::unique_ptr<base::TickClock> tick_clock)
+ : idle_callback_(std::move(idle_callback)),
+ tick_clock_(std::move(tick_clock)) {
+ // |idle_callback_| will be invoked if no event happens in |kIdleDelay|.
+ idle_time_ = tick_clock_->NowTicks() + kIdleDelay;
+ timer_.Start(FROM_HERE, kUpdateInterval,
+ base::BindRepeating(&ServiceWorkerTimeoutTimer::UpdateStatus,
+ base::Unretained(this)));
+}
+
+ServiceWorkerTimeoutTimer::~ServiceWorkerTimeoutTimer() {
+ // Abort all callbacks.
+ for (auto& event : inflight_events_)
+ std::move(event.abort_callback).Run();
+};
+
+int ServiceWorkerTimeoutTimer::StartEvent(
+ base::OnceCallback<void(int /* event_id */)> abort_callback) {
+ idle_time_ = base::TimeTicks();
+ const int event_id = NextEventId();
+ std::set<EventInfo>::iterator iter;
+ bool is_inserted;
+ std::tie(iter, is_inserted) = inflight_events_.emplace(
+ event_id, tick_clock_->NowTicks() + kEventTimeout,
+ base::BindOnce(std::move(abort_callback), event_id));
+ DCHECK(is_inserted);
+ id_event_map_.emplace(event_id, iter);
+ return event_id;
+}
+
+void ServiceWorkerTimeoutTimer::EndEvent(int event_id) {
+ auto iter = id_event_map_.find(event_id);
+ DCHECK(iter != id_event_map_.end());
+ inflight_events_.erase(iter->second);
+ id_event_map_.erase(iter);
+ if (inflight_events_.empty())
+ idle_time_ = tick_clock_->NowTicks() + kIdleDelay;
+}
+
+void ServiceWorkerTimeoutTimer::UpdateStatus() {
+ if (!ServiceWorkerUtils::IsServicificationEnabled())
+ return;
+
+ base::TimeTicks now = tick_clock_->NowTicks();
+
+ // Abort all events exceeding |kEventTimeout|.
+ auto iter = inflight_events_.begin();
+ while (iter != inflight_events_.end() && iter->expiration_time <= now) {
+ int event_id = iter->id;
+ base::OnceClosure callback = std::move(iter->abort_callback);
+ iter = inflight_events_.erase(iter);
+ id_event_map_.erase(event_id);
+ std::move(callback).Run();
+ }
+
+ // If |inflight_events_| is empty, the worker is now idle.
+ if (inflight_events_.empty() && idle_time_.is_null())
+ idle_time_ = tick_clock_->NowTicks() + kIdleDelay;
+
+ if (!idle_time_.is_null() && idle_time_ < now)
+ idle_callback_.Run();
+}
+
+ServiceWorkerTimeoutTimer::EventInfo::EventInfo(
+ int id,
+ base::TimeTicks expiration_time,
+ base::OnceClosure abort_callback)
+ : id(id),
+ expiration_time(expiration_time),
+ abort_callback(std::move(abort_callback)) {}
+
+ServiceWorkerTimeoutTimer::EventInfo::~EventInfo() = default;
+
+bool ServiceWorkerTimeoutTimer::EventInfo::operator<(
+ const EventInfo& other) const {
+ if (expiration_time == other.expiration_time)
+ return id < other.id;
+ return expiration_time < other.expiration_time;
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_timeout_timer.h b/chromium/content/renderer/service_worker/service_worker_timeout_timer.h
new file mode 100644
index 00000000000..be5cbe5a6f7
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_timeout_timer.h
@@ -0,0 +1,110 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_TIMEOUT_TIMER_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_TIMEOUT_TIMER_H_
+
+#include <map>
+#include <set>
+
+#include "base/callback.h"
+#include "base/containers/queue.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+#include "content/common/content_export.h"
+
+namespace base {
+
+class TickClock;
+
+} // namespace base
+
+namespace content {
+
+// ServiceWorkerTimeoutTimer manages two types of timeouts: the long standing
+// event timeout and the idle timeout.
+//
+// S13nServiceWorker:
+// 1) Event timeout: when an event starts, StartEvent() records the expiration
+// time of the event (kEventTimeout). If EndEvent() has not been called within
+// the timeout time, |abort_callback| passed to StartEvent() is called.
+// 2) Idle timeout: when a certain time has passed (kIdleDelay) since all of
+// events have ended, ServiceWorkerTimeoutTimer calls the |idle_callback|.
+// |idle_callback| will be continuously called at a certain interval
+// (kUpdateInterval) until the next event starts.
+//
+// The lifetime of ServiceWorkerTimeoutTimer is the same with the worker
+// thread. If ServiceWorkerTimeoutTimer is destructed while there are inflight
+// events, all |abort_callback|s will be immediately called.
+//
+// Non-S13nServiceWorker:
+// Does nothing except calls the abort callbacks upon destruction.
+class CONTENT_EXPORT ServiceWorkerTimeoutTimer {
+ public:
+ explicit ServiceWorkerTimeoutTimer(base::RepeatingClosure idle_callback);
+ // For testing.
+ ServiceWorkerTimeoutTimer(base::RepeatingClosure idle_callback,
+ std::unique_ptr<base::TickClock> tick_clock);
+ ~ServiceWorkerTimeoutTimer();
+
+ // StartEvent() should be called at the beginning of an event. It returns an
+ // event id. The event id should be passed to EndEvent() when the event has
+ // finished.
+ // See the class comment to know when |abort_callback| runs.
+ int StartEvent(base::OnceCallback<void(int /* event_id */)> abort_callback);
+ void EndEvent(int event_id);
+
+ // Idle timeout duration since the last event has finished.
+ static constexpr base::TimeDelta kIdleDelay =
+ base::TimeDelta::FromSeconds(30);
+ // Duration of the long standing event timeout since StartEvent() has been
+ // called.
+ static constexpr base::TimeDelta kEventTimeout =
+ base::TimeDelta::FromMinutes(5);
+ // ServiceWorkerTimeoutTimer periodically updates the timeout state by
+ // kUpdateInterval.
+ static constexpr base::TimeDelta kUpdateInterval =
+ base::TimeDelta::FromSeconds(30);
+
+ private:
+ // Updates the internal states and fires timeout callbacks if any.
+ void UpdateStatus();
+
+ struct EventInfo {
+ EventInfo(int id,
+ base::TimeTicks expiration_time,
+ base::OnceClosure abort_callback);
+ ~EventInfo();
+ // Compares |expiration_time|, or |id| if |expiration_time| is the same.
+ bool operator<(const EventInfo& other) const;
+
+ const int id;
+ const base::TimeTicks expiration_time;
+ mutable base::OnceClosure abort_callback;
+ };
+
+ // For long standing event timeouts. Ordered by expiration time.
+ std::set<EventInfo> inflight_events_;
+
+ // For long standing event timeouts. This is used to look up an event in
+ // |inflight_events_| by its id.
+ std::map<int /* event_id */, std::set<EventInfo>::iterator> id_event_map_;
+
+ // For idle timeouts. The time the service worker started being considered
+ // idle. This time is null if there are any inflight events.
+ base::TimeTicks idle_time_;
+
+ // For idle timeouts. Invoked when UpdateStatus() is called after
+ // |idle_time_|.
+ base::RepeatingClosure idle_callback_;
+
+ // |timer_| invokes UpdateEventStatus() periodically.
+ base::RepeatingTimer timer_;
+
+ std::unique_ptr<base::TickClock> tick_clock_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_TIMEOUT_TIMER_H_
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
new file mode 100644
index 00000000000..02350cf5a77
--- /dev/null
+++ b/chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
@@ -0,0 +1,211 @@
+// Copyright 2017 The Chromium Authors. 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/service_worker_timeout_timer.h"
+
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/test_mock_time_task_runner.h"
+#include "base/time/tick_clock.h"
+#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/common/content_features.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+class MockEvent {
+ public:
+ base::OnceCallback<void(int)> CreateAbortCallback() {
+ EXPECT_FALSE(has_aborted_);
+ return base::BindOnce(&MockEvent::Abort, base::Unretained(this));
+ }
+
+ int event_id() const { return event_id_; }
+ void set_event_id(int event_id) { event_id_ = event_id; }
+ bool has_aborted() const { return has_aborted_; }
+
+ private:
+ void Abort(int event_id) {
+ EXPECT_EQ(event_id_, event_id);
+ has_aborted_ = true;
+ }
+
+ bool has_aborted_ = false;
+ int event_id_ = 0;
+};
+
+} // namespace
+
+class ServiceWorkerTimeoutTimerTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ base::Time::Now(), base::TimeTicks::Now());
+ message_loop_.SetTaskRunner(task_runner_);
+ }
+
+ void EnableServicification() {
+ feature_list_.InitWithFeatures(
+ {features::kBrowserSideNavigation, features::kNetworkService}, {});
+ ASSERT_TRUE(ServiceWorkerUtils::IsServicificationEnabled());
+ }
+
+ base::TestMockTimeTaskRunner* task_runner() { return task_runner_.get(); }
+
+ private:
+ base::MessageLoop message_loop_;
+ scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
+ base::test::ScopedFeatureList feature_list_;
+};
+
+TEST_F(ServiceWorkerTimeoutTimerTest, IdleTimer) {
+ EnableServicification();
+
+ const base::TimeDelta kIdleInterval =
+ ServiceWorkerTimeoutTimer::kIdleDelay +
+ ServiceWorkerTimeoutTimer::kUpdateInterval +
+ base::TimeDelta::FromSeconds(1);
+
+ base::RepeatingCallback<void(int)> do_nothing_callback =
+ base::BindRepeating([](int) {});
+
+ bool is_idle = false;
+ ServiceWorkerTimeoutTimer timer(
+ base::BindRepeating([](bool* out_is_idle) { *out_is_idle = true; },
+ &is_idle),
+ task_runner()->GetMockTickClock());
+ task_runner()->FastForwardBy(kIdleInterval);
+ // |idle_callback| should be fired since there is no event.
+ EXPECT_TRUE(is_idle);
+
+ is_idle = false;
+ int event_id_1 = timer.StartEvent(do_nothing_callback);
+ task_runner()->FastForwardBy(kIdleInterval);
+ // Nothing happens since there is an inflight event.
+ EXPECT_FALSE(is_idle);
+
+ 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);
+
+ timer.EndEvent(event_id_2);
+ task_runner()->FastForwardBy(kIdleInterval);
+ // Nothing happens since there is an inflight event.
+ EXPECT_FALSE(is_idle);
+
+ timer.EndEvent(event_id_1);
+ task_runner()->FastForwardBy(kIdleInterval);
+ // |idle_callback| should be fired.
+ EXPECT_TRUE(is_idle);
+}
+
+TEST_F(ServiceWorkerTimeoutTimerTest, EventTimer) {
+ EnableServicification();
+
+ ServiceWorkerTimeoutTimer timer(base::BindRepeating(&base::DoNothing),
+ task_runner()->GetMockTickClock());
+ MockEvent event1, event2;
+
+ int event_id1 = timer.StartEvent(event1.CreateAbortCallback());
+ int event_id2 = timer.StartEvent(event2.CreateAbortCallback());
+ event1.set_event_id(event_id1);
+ event2.set_event_id(event_id2);
+ task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kUpdateInterval +
+ base::TimeDelta::FromSeconds(1));
+
+ EXPECT_FALSE(event1.has_aborted());
+ EXPECT_FALSE(event2.has_aborted());
+ timer.EndEvent(event1.event_id());
+ task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kEventTimeout +
+ base::TimeDelta::FromSeconds(1));
+
+ EXPECT_FALSE(event1.has_aborted());
+ EXPECT_TRUE(event2.has_aborted());
+}
+
+TEST_F(ServiceWorkerTimeoutTimerTest, BecomeIdleAfterAbort) {
+ EnableServicification();
+
+ bool is_idle = false;
+ ServiceWorkerTimeoutTimer timer(
+ base::BindRepeating([](bool* out_is_idle) { *out_is_idle = true; },
+ &is_idle),
+ task_runner()->GetMockTickClock());
+
+ MockEvent event;
+ int event_id = timer.StartEvent(event.CreateAbortCallback());
+ event.set_event_id(event_id);
+ task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kEventTimeout +
+ ServiceWorkerTimeoutTimer::kUpdateInterval +
+ base::TimeDelta::FromSeconds(1));
+
+ EXPECT_TRUE(event.has_aborted());
+ EXPECT_FALSE(is_idle);
+ task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kIdleDelay +
+ base::TimeDelta::FromSeconds(1));
+
+ EXPECT_TRUE(is_idle);
+}
+
+TEST_F(ServiceWorkerTimeoutTimerTest, AbortAllOnDestruction) {
+ EnableServicification();
+
+ MockEvent event1, event2;
+ {
+ ServiceWorkerTimeoutTimer timer(base::BindRepeating(&base::DoNothing),
+ task_runner()->GetMockTickClock());
+
+ int event_id1 = timer.StartEvent(event1.CreateAbortCallback());
+ int event_id2 = timer.StartEvent(event2.CreateAbortCallback());
+ event1.set_event_id(event_id1);
+ event2.set_event_id(event_id2);
+ task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kUpdateInterval +
+ base::TimeDelta::FromSeconds(1));
+
+ EXPECT_FALSE(event1.has_aborted());
+ EXPECT_FALSE(event2.has_aborted());
+ }
+
+ EXPECT_TRUE(event1.has_aborted());
+ EXPECT_TRUE(event2.has_aborted());
+}
+
+TEST_F(ServiceWorkerTimeoutTimerTest, NonS13nServiceWorker) {
+ ASSERT_FALSE(ServiceWorkerUtils::IsServicificationEnabled());
+
+ MockEvent event;
+ {
+ bool is_idle = false;
+ ServiceWorkerTimeoutTimer timer(
+ base::BindRepeating([](bool* out_is_idle) { *out_is_idle = true; },
+ &is_idle),
+ task_runner()->GetMockTickClock());
+
+ int event_id = timer.StartEvent(event.CreateAbortCallback());
+ event.set_event_id(event_id);
+ task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kEventTimeout +
+ ServiceWorkerTimeoutTimer::kUpdateInterval +
+ base::TimeDelta::FromSeconds(1));
+
+ // Timed out events should *NOT* be aborted in non-S13nServiceWorker.
+ EXPECT_FALSE(event.has_aborted());
+ EXPECT_FALSE(is_idle);
+
+ task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kIdleDelay +
+ ServiceWorkerTimeoutTimer::kUpdateInterval +
+ base::TimeDelta::FromSeconds(1));
+
+ // |idle_callback| should *NOT* be fired in non-S13nServiceWorker.
+ EXPECT_FALSE(is_idle);
+ }
+
+ // Events should be aborted when the timer is destructed.
+ EXPECT_TRUE(event.has_aborted());
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_type_util.cc b/chromium/content/renderer/service_worker/service_worker_type_util.cc
index 0365827f30a..9dde56d109c 100644
--- a/chromium/content/renderer/service_worker/service_worker_type_util.cc
+++ b/chromium/content/renderer/service_worker/service_worker_type_util.cc
@@ -48,7 +48,7 @@ std::unique_ptr<HeaderVisitor> MakeHeaderVisitor(
std::unique_ptr<ServiceWorkerHeaderMap> GetHeaderMap(
const blink::WebServiceWorkerResponse& web_response) {
std::unique_ptr<ServiceWorkerHeaderMap> result =
- base::MakeUnique<ServiceWorkerHeaderMap>();
+ std::make_unique<ServiceWorkerHeaderMap>();
web_response.VisitHTTPHeaderFields(MakeHeaderVisitor(result.get()).get());
return result;
}
@@ -56,7 +56,7 @@ std::unique_ptr<ServiceWorkerHeaderMap> GetHeaderMap(
std::unique_ptr<ServiceWorkerHeaderList> GetHeaderList(
const blink::WebVector<blink::WebString>& web_headers) {
std::unique_ptr<ServiceWorkerHeaderList> result =
- base::MakeUnique<ServiceWorkerHeaderList>(web_headers.size());
+ std::make_unique<ServiceWorkerHeaderList>(web_headers.size());
std::transform(web_headers.begin(), web_headers.end(), result->begin(),
[](const blink::WebString& s) { return s.Latin1(); });
return result;
@@ -65,7 +65,7 @@ std::unique_ptr<ServiceWorkerHeaderList> GetHeaderList(
std::unique_ptr<std::vector<GURL>> GetURLList(
const blink::WebVector<blink::WebURL>& web_url_list) {
std::unique_ptr<std::vector<GURL>> result =
- base::MakeUnique<std::vector<GURL>>(web_url_list.size());
+ std::make_unique<std::vector<GURL>>(web_url_list.size());
std::transform(web_url_list.begin(), web_url_list.end(), result->begin(),
[](const blink::WebURL& url) { return url; });
return result;
@@ -86,13 +86,13 @@ ServiceWorkerResponse GetServiceWorkerResponseFromWebResponse(
scoped_refptr<storage::BlobHandle> blob;
auto blob_pipe = web_response.CloneBlobPtr();
if (blob_pipe.is_valid()) {
- storage::mojom::BlobPtr blob_ptr;
- blob_ptr.Bind(storage::mojom::BlobPtrInfo(std::move(blob_pipe),
- storage::mojom::Blob::Version_));
+ blink::mojom::BlobPtr blob_ptr;
+ blob_ptr.Bind(blink::mojom::BlobPtrInfo(std::move(blob_pipe),
+ blink::mojom::Blob::Version_));
blob = base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr));
}
- return ServiceWorkerResponse(
+ ServiceWorkerResponse response = ServiceWorkerResponse(
GetURLList(web_response.UrlList()), web_response.Status(),
web_response.StatusText().Utf8(), web_response.ResponseType(),
GetHeaderMap(web_response), web_response.BlobUUID().Utf8(),
@@ -101,6 +101,19 @@ ServiceWorkerResponse GetServiceWorkerResponseFromWebResponse(
!web_response.CacheStorageCacheName().IsNull(),
web_response.CacheStorageCacheName().Utf8(),
GetHeaderList(web_response.CorsExposedHeaderNames()));
+ if (!web_response.SideDataBlobSize())
+ return response;
+ response.side_data_blob_uuid = web_response.SideDataBlobUUID().Utf8();
+ response.side_data_blob_size = web_response.SideDataBlobSize();
+ auto side_data_blob_pipe = web_response.CloneSideDataBlobPtr();
+ if (side_data_blob_pipe.is_valid()) {
+ blink::mojom::BlobPtr side_data_blob_ptr;
+ side_data_blob_ptr.Bind(blink::mojom::BlobPtrInfo(
+ std::move(side_data_blob_pipe), blink::mojom::Blob::Version_));
+ response.side_data_blob = base::MakeRefCounted<storage::BlobHandle>(
+ std::move(side_data_blob_ptr));
+ }
+ return response;
}
} // namespace content
diff --git a/chromium/content/renderer/service_worker/thread_safe_script_container.cc b/chromium/content/renderer/service_worker/thread_safe_script_container.cc
index 8675b4eddef..6f6e038c95c 100644
--- a/chromium/content/renderer/service_worker/thread_safe_script_container.cc
+++ b/chromium/content/renderer/service_worker/thread_safe_script_container.cc
@@ -14,7 +14,6 @@ ThreadSafeScriptContainer::ThreadSafeScriptContainer()
void ThreadSafeScriptContainer::AddOnIOThread(const GURL& url,
std::unique_ptr<Data> data) {
base::AutoLock lock(lock_);
- DCHECK(script_data_.find(url) == script_data_.end());
script_data_[url] = std::move(data);
if (url == waiting_url_)
waiting_cv_.Signal();
@@ -26,10 +25,16 @@ ThreadSafeScriptContainer::GetStatusOnWorkerThread(const GURL& url) {
auto it = script_data_.find(url);
if (it == script_data_.end())
return ScriptStatus::kPending;
- // If the instance is invalid, return |kFailed|.
- // TODO(shimazu): Keep the status for each entries instead of using IsValid().
- return (it->second && !it->second->IsValid()) ? ScriptStatus::kFailed
- : ScriptStatus::kSuccess;
+ 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) {
@@ -57,11 +62,9 @@ bool ThreadSafeScriptContainer::WaitOnWorkerThread(const GURL& url) {
std::unique_ptr<ThreadSafeScriptContainer::Data>
ThreadSafeScriptContainer::TakeOnWorkerThread(const GURL& url) {
base::AutoLock lock(lock_);
- DCHECK(script_data_.find(url) != script_data_.end())
+ DCHECK(base::ContainsKey(script_data_, url))
<< "Script should be added before calling Take.";
- auto data = std::move(script_data_[url]);
- DCHECK(script_data_[url] == nullptr);
- return data;
+ return std::move(script_data_[url]);
}
void ThreadSafeScriptContainer::OnAllDataAddedOnIOThread() {
diff --git a/chromium/content/renderer/service_worker/thread_safe_script_container.h b/chromium/content/renderer/service_worker/thread_safe_script_container.h
index c662d62fb16..037a072ae94 100644
--- a/chromium/content/renderer/service_worker/thread_safe_script_container.h
+++ b/chromium/content/renderer/service_worker/thread_safe_script_container.h
@@ -37,25 +37,34 @@ class CONTENT_EXPORT ThreadSafeScriptContainer
REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
ThreadSafeScriptContainer();
- enum class ScriptStatus { kSuccess, kFailed, kPending };
+ 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);
- // Returns the following values.
- // - |kSuccess| : the script data has been received.
- // - |kFailed| : receiving the script has failed.
- // - |kPending| : the script has not been received yet.
// 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);
- // Returns nullptr if the script has already been taken.
// Called on the worker thread.
std::unique_ptr<Data> TakeOnWorkerThread(const GURL& url);
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
index 7446464245f..a6853ed06c3 100644
--- a/chromium/content/renderer/service_worker/thread_safe_script_container_unittest.cc
+++ b/chromium/content/renderer/service_worker/thread_safe_script_container_unittest.cc
@@ -130,7 +130,7 @@ class ThreadSafeScriptContainerTest : public testing::Test {
TEST_F(ThreadSafeScriptContainerTest, WaitExistingKey) {
const GURL kKey("https://example.com/key");
{
- ScriptStatus result = ScriptStatus::kSuccess;
+ ScriptStatus result = ScriptStatus::kReceived;
GetStatusOnReaderThread(kKey, &result)->Wait();
EXPECT_EQ(ScriptStatus::kPending, result);
}
@@ -150,7 +150,7 @@ TEST_F(ThreadSafeScriptContainerTest, WaitExistingKey) {
{
ScriptStatus result = ScriptStatus::kFailed;
GetStatusOnReaderThread(kKey, &result)->Wait();
- EXPECT_EQ(ScriptStatus::kSuccess, result);
+ EXPECT_EQ(ScriptStatus::kReceived, result);
}
{
@@ -163,7 +163,7 @@ TEST_F(ThreadSafeScriptContainerTest, WaitExistingKey) {
ScriptStatus result = ScriptStatus::kFailed;
GetStatusOnReaderThread(kKey, &result)->Wait();
// The record of |kKey| should be exist though it's already taken.
- EXPECT_EQ(ScriptStatus::kSuccess, result);
+ EXPECT_EQ(ScriptStatus::kTaken, result);
}
{
@@ -197,7 +197,7 @@ TEST_F(ThreadSafeScriptContainerTest, WaitExistingKey) {
TEST_F(ThreadSafeScriptContainerTest, WaitNonExistingKey) {
const GURL kKey("https://example.com/key");
{
- ScriptStatus result = ScriptStatus::kSuccess;
+ ScriptStatus result = ScriptStatus::kReceived;
GetStatusOnReaderThread(kKey, &result)->Wait();
EXPECT_EQ(ScriptStatus::kPending, result);
}
diff --git a/chromium/content/child/service_worker/web_service_worker_impl.cc b/chromium/content/renderer/service_worker/web_service_worker_impl.cc
index dee36b8ed9c..9c53fe46a1a 100644
--- a/chromium/content/child/service_worker/web_service_worker_impl.cc
+++ b/chromium/content/renderer/service_worker/web_service_worker_impl.cc
@@ -2,21 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/service_worker/web_service_worker_impl.h"
+#include "content/renderer/service_worker/web_service_worker_impl.h"
#include <utility>
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "content/child/service_worker/service_worker_dispatcher.h"
-#include "content/child/service_worker/service_worker_handle_reference.h"
-#include "content/child/service_worker/web_service_worker_provider_impl.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/service_worker/service_worker_messages.h"
+#include "content/renderer/service_worker/service_worker_dispatcher.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.h"
+#include "content/renderer/service_worker/web_service_worker_provider_impl.h"
#include "third_party/WebKit/public/platform/WebRuntimeFeatures.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProxy.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
using blink::WebSecurityOrigin;
using blink::WebString;
@@ -48,7 +49,8 @@ WebServiceWorkerImpl::WebServiceWorkerImpl(
state_(handle_ref_->state()),
thread_safe_sender_(thread_safe_sender),
proxy_(nullptr) {
- DCHECK_NE(kInvalidServiceWorkerHandleId, handle_ref_->handle_id());
+ DCHECK_NE(blink::mojom::kInvalidServiceWorkerHandleId,
+ handle_ref_->handle_id());
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
DCHECK(dispatcher);
@@ -103,7 +105,7 @@ WebServiceWorkerImpl::CreateHandle(
const scoped_refptr<WebServiceWorkerImpl>& worker) {
if (!worker)
return nullptr;
- return base::MakeUnique<HandleImpl>(worker);
+ return std::make_unique<HandleImpl>(worker);
}
WebServiceWorkerImpl::~WebServiceWorkerImpl() {
diff --git a/chromium/content/child/service_worker/web_service_worker_impl.h b/chromium/content/renderer/service_worker/web_service_worker_impl.h
index 3ed3f40934d..56affc3e6a2 100644
--- a/chromium/content/child/service_worker/web_service_worker_impl.h
+++ b/chromium/content/renderer/service_worker/web_service_worker_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_IMPL_H_
-#define CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_IMPL_H_
+#ifndef CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_IMPL_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_IMPL_H_
#include <memory>
#include <vector>
@@ -72,4 +72,4 @@ class CONTENT_EXPORT WebServiceWorkerImpl
} // namespace content
-#endif // CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_IMPL_H_
+#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
index 759f8a7566b..4302774b684 100644
--- 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
@@ -150,7 +150,7 @@ class Internal : public mojom::ServiceWorkerInstalledScriptsManager {
scoped_refptr<ThreadSafeScriptContainer> script_container,
mojom::ServiceWorkerInstalledScriptsManagerRequest request) {
mojo::MakeStrongBinding(
- base::MakeUnique<Internal>(std::move(script_container)),
+ std::make_unique<Internal>(std::move(script_container)),
std::move(request));
}
@@ -172,7 +172,7 @@ class Internal : public mojom::ServiceWorkerInstalledScriptsManager {
mojom::ServiceWorkerScriptInfoPtr script_info) override {
DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
GURL script_url = script_info->script_url;
- auto receivers = base::MakeUnique<BundledReceivers>(
+ 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);
receivers->Start(base::BindOnce(&Internal::OnScriptReceived,
@@ -224,25 +224,30 @@ WebServiceWorkerInstalledScriptsManagerImpl::Create(
mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
auto script_container = base::MakeRefCounted<ThreadSafeScriptContainer>();
- std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManager>
- installed_scripts_manager =
- base::WrapUnique<WebServiceWorkerInstalledScriptsManagerImpl>(
- new WebServiceWorkerInstalledScriptsManagerImpl(
- std::move(installed_scripts_info->installed_urls),
- script_container));
+ 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)));
- return installed_scripts_manager;
+ return manager;
}
WebServiceWorkerInstalledScriptsManagerImpl::
WebServiceWorkerInstalledScriptsManagerImpl(
std::vector<GURL>&& installed_urls,
- scoped_refptr<ThreadSafeScriptContainer> script_container)
+ scoped_refptr<ThreadSafeScriptContainer> script_container,
+ mojom::ServiceWorkerInstalledScriptsManagerHostPtr manager_host)
: installed_urls_(installed_urls.begin(), installed_urls.end()),
- script_container_(std::move(script_container)) {}
+ script_container_(std::move(script_container)),
+ manager_host_(
+ mojom::ThreadSafeServiceWorkerInstalledScriptsManagerHostPtr::Create(
+ std::move(manager_host))) {}
WebServiceWorkerInstalledScriptsManagerImpl::
~WebServiceWorkerInstalledScriptsManagerImpl() = default;
@@ -255,11 +260,24 @@ bool WebServiceWorkerInstalledScriptsManagerImpl::IsScriptInstalled(
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);
@@ -272,17 +290,9 @@ WebServiceWorkerInstalledScriptsManagerImpl::GetRawScriptData(
if (status == ThreadSafeScriptContainer::ScriptStatus::kFailed)
return RawScriptData::CreateInvalidInstance();
- DCHECK_EQ(ThreadSafeScriptContainer::ScriptStatus::kSuccess, status);
-
- std::unique_ptr<RawScriptData> data =
- script_container_->TakeOnWorkerThread(script_url);
- // |data| is possible to be null when the script data has already been taken.
- if (!data) {
- // TODO(shimazu): Ask the browser process when the script has already been
- // served.
- return nullptr;
- }
- return data;
+ 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
index b22a338d76e..2c5f9caa528 100644
--- 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
@@ -32,10 +32,14 @@ class CONTENT_EXPORT WebServiceWorkerInstalledScriptsManagerImpl final
private:
WebServiceWorkerInstalledScriptsManagerImpl(
std::vector<GURL>&& installed_urls,
- scoped_refptr<ThreadSafeScriptContainer> script_container);
+ scoped_refptr<ThreadSafeScriptContainer> script_container,
+ mojom::ServiceWorkerInstalledScriptsManagerHostPtr manager_host);
const std::set<GURL> installed_urls_;
scoped_refptr<ThreadSafeScriptContainer> script_container_;
+
+ scoped_refptr<mojom::ThreadSafeServiceWorkerInstalledScriptsManagerHostPtr>
+ manager_host_;
};
} // namespace content
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
index cde08687b59..2d4763f0f71 100644
--- 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
@@ -6,35 +6,39 @@
#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 {
+class BrowserSideSender : mojom::ServiceWorkerInstalledScriptsManagerHost {
public:
- explicit BrowserSideSender(std::vector<GURL> installed_urls)
- : installed_urls_(std::move(installed_urls)) {}
+ BrowserSideSender() : binding_(this) {}
+ ~BrowserSideSender() override = default;
- mojom::ServiceWorkerInstalledScriptsInfoPtr CreateAndBind() {
+ 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 = mojom::ServiceWorkerInstalledScriptsInfo::New();
- scripts_info->installed_urls = installed_urls_;
+ 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;
}
- const GURL& TransferInstalledScript(int64_t body_size,
- int64_t meta_data_size) {
+ 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 = mojom::ServiceWorkerScriptInfo::New();
- const GURL& transferring_url = installed_urls()[next_transfer_index_];
- script_info->script_url = transferring_url;
+ 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_,
@@ -42,8 +46,6 @@ class BrowserSideSender {
script_info->body_size = body_size;
script_info->meta_data_size = meta_data_size;
manager_->TransferInstalledScript(std::move(script_info));
- next_transfer_index_++;
- return transferring_url;
}
void PushBody(const std::string& data) {
@@ -60,9 +62,20 @@ class BrowserSideSender {
void ResetManager() { manager_.reset(); }
- const std::vector<GURL>& installed_urls() const { return installed_urls_; }
+ 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.
@@ -74,10 +87,11 @@ class BrowserSideSender {
ASSERT_EQ(data.size() + 1, written_bytes);
}
- const std::vector<GURL> installed_urls_;
- size_t next_transfer_index_ = 0;
+ base::OnceClosure requested_script_closure_;
+ GURL waiting_requested_url_;
mojom::ServiceWorkerInstalledScriptsManagerPtr manager_;
+ mojo::Binding<mojom::ServiceWorkerInstalledScriptsManagerHost> binding_;
mojo::ScopedDataPipeProducerHandle body_handle_;
mojo::ScopedDataPipeProducerHandle meta_data_handle_;
@@ -175,8 +189,8 @@ 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({kScriptUrl});
- CreateInstalledScriptsManager(sender.CreateAndBind());
+ BrowserSideSender sender;
+ CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
{
bool result = false;
@@ -202,9 +216,8 @@ TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest, GetRawScriptData) {
GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
// Start transferring the script. +1 for null terminator.
- EXPECT_EQ(kScriptUrl,
- sender.TransferInstalledScript(kExpectedBody.size() + 1,
- kExpectedMetaData.size() + 1));
+ 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
@@ -231,10 +244,41 @@ TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest, GetRawScriptData) {
{
std::unique_ptr<RawScriptData> script_data;
- GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data)->Wait();
- // This should not be blocked because the script has already been received.
- // nullptr will be returned after the data has already been taken.
- EXPECT_EQ(nullptr, script_data.get());
+ 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());
}
}
@@ -243,8 +287,8 @@ TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest,
const GURL kScriptUrl = GURL("https://example.com/installed1.js");
const GURL kUnknownScriptUrl = GURL("https://example.com/not_installed.js");
- BrowserSideSender sender({kScriptUrl});
- CreateInstalledScriptsManager(sender.CreateAndBind());
+ BrowserSideSender sender;
+ CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
{
std::unique_ptr<RawScriptData> script_data;
@@ -257,9 +301,8 @@ TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest,
// 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).
- EXPECT_EQ(kScriptUrl,
- sender.TransferInstalledScript(kExpectedBody.size() + 100,
- kExpectedMetaData.size() + 1));
+ 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
@@ -291,8 +334,8 @@ TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest,
const GURL kScriptUrl = GURL("https://example.com/installed1.js");
const GURL kUnknownScriptUrl = GURL("https://example.com/not_installed.js");
- BrowserSideSender sender({kScriptUrl});
- CreateInstalledScriptsManager(sender.CreateAndBind());
+ BrowserSideSender sender;
+ CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
{
std::unique_ptr<RawScriptData> script_data;
@@ -305,9 +348,8 @@ TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest,
// 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).
- EXPECT_EQ(kScriptUrl,
- sender.TransferInstalledScript(kExpectedBody.size() + 1,
- kExpectedMetaData.size() + 100));
+ 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
@@ -339,8 +381,8 @@ TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest,
const GURL kScriptUrl = GURL("https://example.com/installed1.js");
const GURL kUnknownScriptUrl = GURL("https://example.com/not_installed.js");
- BrowserSideSender sender({kScriptUrl});
- CreateInstalledScriptsManager(sender.CreateAndBind());
+ BrowserSideSender sender;
+ CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
{
std::unique_ptr<RawScriptData> script_data;
diff --git a/chromium/content/child/service_worker/web_service_worker_provider_impl.cc b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc
index ead184d88d0..e97c5400d02 100644
--- a/chromium/content/child/service_worker/web_service_worker_provider_impl.cc
+++ b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc
@@ -2,21 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/service_worker/web_service_worker_provider_impl.h"
+#include "content/renderer/service_worker/web_service_worker_provider_impl.h"
#include <memory>
#include <utility>
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
-#include "content/child/service_worker/service_worker_dispatcher.h"
-#include "content/child/service_worker/service_worker_handle_reference.h"
-#include "content/child/service_worker/service_worker_provider_context.h"
-#include "content/child/service_worker/web_service_worker_impl.h"
-#include "content/child/service_worker/web_service_worker_registration_impl.h"
#include "content/child/thread_safe_sender.h"
-#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/renderer/service_worker/service_worker_dispatcher.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.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/web_service_worker_registration_impl.h"
+#include "third_party/WebKit/common/message_port/message_port_channel.h"
+#include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
@@ -37,44 +38,38 @@ WebServiceWorkerProviderImpl::WebServiceWorkerProviderImpl(
ServiceWorkerProviderContext* context)
: thread_safe_sender_(thread_safe_sender),
context_(context),
+ provider_client_(nullptr),
weak_factory_(this) {
DCHECK(context_);
- DCHECK(context_->provider_type() != SERVICE_WORKER_PROVIDER_FOR_WINDOW ||
- context_->container_host());
+ switch (context_->provider_type()) {
+ case blink::mojom::ServiceWorkerProviderType::kForWindow:
+ DCHECK(context_->container_host());
+ context_->SetWebServiceWorkerProvider(weak_factory_.GetWeakPtr());
+ break;
+ case blink::mojom::ServiceWorkerProviderType::kForServiceWorker:
+ // Do nothing.
+ break;
+ case blink::mojom::ServiceWorkerProviderType::kForSharedWorker:
+ case blink::mojom::ServiceWorkerProviderType::kUnknown:
+ NOTREACHED() << "Unimplemented type: " << context_->provider_type();
+ break;
+ }
}
-WebServiceWorkerProviderImpl::~WebServiceWorkerProviderImpl() {
- // Make sure the provider client is removed.
- RemoveProviderClient();
-}
+WebServiceWorkerProviderImpl::~WebServiceWorkerProviderImpl() = default;
void WebServiceWorkerProviderImpl::SetClient(
blink::WebServiceWorkerProviderClient* client) {
- if (!client) {
- RemoveProviderClient();
+ provider_client_ = client;
+ if (!provider_client_)
return;
- }
- // TODO(kinuko): Here we could also register the current thread ID
- // on the provider context so that multiple WebServiceWorkerProviderImpl
- // (e.g. on document and on dedicated workers) can properly share
- // the single provider context across threads. (http://crbug.com/366538
- // for more context)
- GetDispatcher()->AddProviderClient(context_->provider_id(), client);
-
- if (!context_->controller())
+ std::unique_ptr<ServiceWorkerHandleReference> controller =
+ context_->TakeController();
+ if (!controller)
return;
- scoped_refptr<WebServiceWorkerImpl> controller =
- GetDispatcher()->GetOrCreateServiceWorker(
- ServiceWorkerHandleReference::Create(context_->controller()->info(),
- thread_safe_sender_.get()));
-
- // Sync the controllee's use counter with |context_|'s, which keeps
- // track of the controller's use counter.
- for (uint32_t feature : context_->used_features())
- client->CountFeature(feature);
- client->SetController(WebServiceWorkerImpl::CreateHandle(controller),
- false /* shouldNotifyControllerChange */);
+ SetController(std::move(controller), context_->used_features(),
+ false /* notify_controllerchange */);
}
void WebServiceWorkerProviderImpl::RegisterServiceWorker(
@@ -192,17 +187,48 @@ bool WebServiceWorkerProviderImpl::ValidateScopeAndScriptURL(
return !has_error;
}
-int WebServiceWorkerProviderImpl::provider_id() const {
- return context_->provider_id();
+void WebServiceWorkerProviderImpl::SetController(
+ std::unique_ptr<ServiceWorkerHandleReference> controller,
+ const std::set<blink::mojom::WebFeature>& features,
+ bool should_notify_controller_change) {
+ if (!provider_client_)
+ return;
+
+ for (blink::mojom::WebFeature feature : features)
+ provider_client_->CountFeature(feature);
+ provider_client_->SetController(
+ WebServiceWorkerImpl::CreateHandle(
+ GetDispatcher()->GetOrCreateServiceWorker(std::move(controller))),
+ should_notify_controller_change);
+}
+
+void WebServiceWorkerProviderImpl::PostMessageToClient(
+ blink::mojom::ServiceWorkerObjectInfoPtr source,
+ const base::string16& message,
+ std::vector<mojo::ScopedMessagePipeHandle> message_pipes) {
+ if (!provider_client_)
+ return;
+
+ scoped_refptr<WebServiceWorkerImpl> worker =
+ GetDispatcher()->GetOrCreateServiceWorker(
+ ServiceWorkerHandleReference::Create(std::move(source),
+ thread_safe_sender_.get()));
+ auto message_ports =
+ blink::MessagePortChannel::CreateFromHandles(std::move(message_pipes));
+ provider_client_->DispatchMessageEvent(
+ WebServiceWorkerImpl::CreateHandle(std::move(worker)),
+ blink::WebString::FromUTF16(message), std::move(message_ports));
+}
+
+void WebServiceWorkerProviderImpl::CountFeature(
+ blink::mojom::WebFeature feature) {
+ if (!provider_client_)
+ return;
+ provider_client_->CountFeature(feature);
}
-void WebServiceWorkerProviderImpl::RemoveProviderClient() {
- // Remove the provider client, but only if the dispatcher is still there.
- // (For cleanup path we don't need to bother creating a new dispatcher)
- ServiceWorkerDispatcher* dispatcher =
- ServiceWorkerDispatcher::GetThreadSpecificInstance();
- if (dispatcher)
- dispatcher->RemoveProviderClient(context_->provider_id());
+int WebServiceWorkerProviderImpl::provider_id() const {
+ return context_->provider_id();
}
ServiceWorkerDispatcher* WebServiceWorkerProviderImpl::GetDispatcher() {
@@ -213,8 +239,7 @@ void WebServiceWorkerProviderImpl::OnRegistered(
std::unique_ptr<WebServiceWorkerRegistrationCallbacks> callbacks,
blink::mojom::ServiceWorkerErrorType error,
const base::Optional<std::string>& error_msg,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration,
- const base::Optional<ServiceWorkerVersionAttributes>& attributes) {
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration) {
TRACE_EVENT_ASYNC_END2(
"ServiceWorker", "WebServiceWorkerProviderImpl::RegisterServiceWorker",
this, "Error", ServiceWorkerUtils::ErrorTypeToString(error), "Message",
@@ -222,7 +247,6 @@ void WebServiceWorkerProviderImpl::OnRegistered(
if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
DCHECK(error_msg);
DCHECK(!registration);
- DCHECK(!attributes);
callbacks->OnError(blink::WebServiceWorkerError(
error, blink::WebString::FromASCII(*error_msg)));
return;
@@ -230,20 +254,18 @@ void WebServiceWorkerProviderImpl::OnRegistered(
DCHECK(!error_msg);
DCHECK(registration);
- DCHECK(attributes);
- DCHECK_NE(blink::mojom::kInvalidServiceWorkerRegistrationHandleId,
- registration->handle_id);
+ DCHECK_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
+ registration->registration_id);
callbacks->OnSuccess(WebServiceWorkerRegistrationImpl::CreateHandle(
- GetDispatcher()->GetOrAdoptRegistration(std::move(registration),
- *attributes)));
+ context_->GetOrCreateRegistrationForServiceWorkerClient(
+ std::move(registration))));
}
void WebServiceWorkerProviderImpl::OnDidGetRegistration(
std::unique_ptr<WebServiceWorkerGetRegistrationCallbacks> callbacks,
blink::mojom::ServiceWorkerErrorType error,
const base::Optional<std::string>& error_msg,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration,
- const base::Optional<ServiceWorkerVersionAttributes>& attributes) {
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration) {
TRACE_EVENT_ASYNC_END2("ServiceWorker",
"WebServiceWorkerProviderImpl::GetRegistration", this,
"Error", ServiceWorkerUtils::ErrorTypeToString(error),
@@ -251,24 +273,26 @@ void WebServiceWorkerProviderImpl::OnDidGetRegistration(
if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
DCHECK(error_msg);
DCHECK(!registration);
- DCHECK(!attributes);
callbacks->OnError(blink::WebServiceWorkerError(
error, blink::WebString::FromASCII(*error_msg)));
return;
}
DCHECK(!error_msg);
- DCHECK(registration);
- DCHECK(attributes);
- scoped_refptr<WebServiceWorkerRegistrationImpl> impl;
- // The handle id is invalid if no corresponding registration has been found
- // or the found one is uninstalling.
- if (registration->handle_id !=
- blink::mojom::kInvalidServiceWorkerRegistrationHandleId) {
- impl = GetDispatcher()->GetOrAdoptRegistration(std::move(registration),
- *attributes);
+ // |registration| is nullptr if there is no registration at the scope or it's
+ // uninstalling.
+ if (!registration) {
+ callbacks->OnSuccess(nullptr);
+ return;
}
- callbacks->OnSuccess(WebServiceWorkerRegistrationImpl::CreateHandle(impl));
+ DCHECK_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
+ registration->registration_id);
+ scoped_refptr<WebServiceWorkerRegistrationImpl> impl =
+ context_->GetOrCreateRegistrationForServiceWorkerClient(
+ std::move(registration));
+ DCHECK(impl);
+ callbacks->OnSuccess(
+ WebServiceWorkerRegistrationImpl::CreateHandle(std::move(impl)));
}
void WebServiceWorkerProviderImpl::OnDidGetRegistrations(
@@ -277,8 +301,7 @@ void WebServiceWorkerProviderImpl::OnDidGetRegistrations(
const base::Optional<std::string>& error_msg,
base::Optional<
std::vector<blink::mojom::ServiceWorkerRegistrationObjectInfoPtr>>
- infos,
- const base::Optional<std::vector<ServiceWorkerVersionAttributes>>& attrs) {
+ infos) {
TRACE_EVENT_ASYNC_END2("ServiceWorker",
"WebServiceWorkerProviderImpl::GetRegistrations", this,
"Error", ServiceWorkerUtils::ErrorTypeToString(error),
@@ -286,7 +309,6 @@ void WebServiceWorkerProviderImpl::OnDidGetRegistrations(
if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
DCHECK(error_msg);
DCHECK(!infos);
- DCHECK(!attrs);
callbacks->OnError(blink::WebServiceWorkerError(
error, blink::WebString::FromASCII(*error_msg)));
return;
@@ -294,30 +316,28 @@ void WebServiceWorkerProviderImpl::OnDidGetRegistrations(
DCHECK(!error_msg);
DCHECK(infos);
- DCHECK(attrs);
using WebServiceWorkerRegistrationHandles =
WebServiceWorkerProvider::WebServiceWorkerRegistrationHandles;
std::unique_ptr<WebServiceWorkerRegistrationHandles> registrations =
- base::MakeUnique<WebServiceWorkerRegistrationHandles>(infos->size());
+ std::make_unique<WebServiceWorkerRegistrationHandles>(infos->size());
for (size_t i = 0; i < infos->size(); ++i) {
- DCHECK_NE(blink::mojom::kInvalidServiceWorkerRegistrationHandleId,
- (*infos)[i]->handle_id);
+ DCHECK_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
+ (*infos)[i]->registration_id);
(*registrations)[i] = WebServiceWorkerRegistrationImpl::CreateHandle(
- GetDispatcher()->GetOrAdoptRegistration(std::move((*infos)[i]),
- (*attrs)[i]));
+ context_->GetOrCreateRegistrationForServiceWorkerClient(
+ std::move((*infos)[i])));
}
callbacks->OnSuccess(std::move(registrations));
}
void WebServiceWorkerProviderImpl::OnDidGetRegistrationForReady(
std::unique_ptr<WebServiceWorkerGetRegistrationForReadyCallbacks> callbacks,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration,
- const base::Optional<ServiceWorkerVersionAttributes>& attributes) {
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration) {
TRACE_EVENT_ASYNC_END0(
"ServiceWorker", "WebServiceWorkerProviderImpl::GetRegistrationForReady",
this);
// TODO(leonhsl): Currently the only reason that we allow nullable
- // |registration| and |attributes| is: impl of the mojo method
+ // |registration| is: impl of the mojo method
// GetRegistrationForReady() needs to respond some non-sense params even if it
// has found that the request is a bad message and has called
// mojo::ReportBadMessage(), this is forced by Mojo, please see
@@ -326,12 +346,11 @@ void WebServiceWorkerProviderImpl::OnDidGetRegistrationForReady(
// https://groups.google.com/a/chromium.org/forum/#!topic/chromium-mojo/NNsogKNurlA
// settled.
CHECK(registration);
- CHECK(attributes);
- DCHECK_NE(blink::mojom::kInvalidServiceWorkerRegistrationHandleId,
- registration->handle_id);
+ DCHECK_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
+ registration->registration_id);
callbacks->OnSuccess(WebServiceWorkerRegistrationImpl::CreateHandle(
- GetDispatcher()->GetOrAdoptRegistration(std::move(registration),
- *attributes)));
+ context_->GetOrCreateRegistrationForServiceWorkerClient(
+ std::move(registration))));
}
} // namespace content
diff --git a/chromium/content/child/service_worker/web_service_worker_provider_impl.h b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.h
index f55eedd7bf7..f0f274ee376 100644
--- a/chromium/content/child/service_worker/web_service_worker_provider_impl.h
+++ b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_PROVIDER_IMPL_H_
-#define CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_PROVIDER_IMPL_H_
+#ifndef CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_PROVIDER_IMPL_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_PROVIDER_IMPL_H_
#include <memory>
@@ -11,9 +11,11 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "content/common/service_worker/service_worker_types.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProvider.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+#include "third_party/WebKit/public/platform/web_feature.mojom.h"
namespace blink {
class WebURL;
@@ -23,14 +25,14 @@ class WebServiceWorkerProviderClient;
namespace content {
class ServiceWorkerDispatcher;
+class ServiceWorkerHandleReference;
class ServiceWorkerProviderContext;
class ThreadSafeSender;
-struct ServiceWorkerVersionAttributes;
-
// This class corresponds to one ServiceWorkerContainer interface in
// JS context (i.e. navigator.serviceWorker).
-class WebServiceWorkerProviderImpl : public blink::WebServiceWorkerProvider {
+class CONTENT_EXPORT WebServiceWorkerProviderImpl
+ : public blink::WebServiceWorkerProvider {
public:
WebServiceWorkerProviderImpl(ThreadSafeSender* thread_safe_sender,
ServiceWorkerProviderContext* context);
@@ -54,26 +56,37 @@ class WebServiceWorkerProviderImpl : public blink::WebServiceWorkerProvider {
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.
+ void SetController(std::unique_ptr<ServiceWorkerHandleReference> controller,
+ const std::set<blink::mojom::WebFeature>& features,
+ bool should_notify_controller_change);
+ // Posts a message to the ServiceWorkerContainer for this provider.
+ // Corresponds to Client#postMessage().
+ void PostMessageToClient(
+ blink::mojom::ServiceWorkerObjectInfoPtr source,
+ const base::string16& message,
+ std::vector<mojo::ScopedMessagePipeHandle> message_pipes);
+ // For UseCounter purposes. Called when the controller service worker used a
+ // 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 RemoveProviderClient();
ServiceWorkerDispatcher* GetDispatcher();
void OnRegistered(
std::unique_ptr<WebServiceWorkerRegistrationCallbacks> callbacks,
blink::mojom::ServiceWorkerErrorType error,
const base::Optional<std::string>& error_msg,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration,
- const base::Optional<ServiceWorkerVersionAttributes>& attributes);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration);
void OnDidGetRegistration(
std::unique_ptr<WebServiceWorkerGetRegistrationCallbacks> callbacks,
blink::mojom::ServiceWorkerErrorType error,
const base::Optional<std::string>& error_msg,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration,
- const base::Optional<ServiceWorkerVersionAttributes>& attributes);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration);
void OnDidGetRegistrations(
std::unique_ptr<WebServiceWorkerGetRegistrationsCallbacks> callbacks,
@@ -81,18 +94,21 @@ class WebServiceWorkerProviderImpl : public blink::WebServiceWorkerProvider {
const base::Optional<std::string>& error_msg,
base::Optional<
std::vector<blink::mojom::ServiceWorkerRegistrationObjectInfoPtr>>
- infos,
- const base::Optional<std::vector<ServiceWorkerVersionAttributes>>& attrs);
+ infos);
void OnDidGetRegistrationForReady(
std::unique_ptr<WebServiceWorkerGetRegistrationForReadyCallbacks>
callbacks,
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration,
- const base::Optional<ServiceWorkerVersionAttributes>& attributes);
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration);
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
scoped_refptr<ServiceWorkerProviderContext> context_;
+ // |provider_client_| is implemented by blink::SWContainer and this pointer's
+ // nullified when its execution context is destroyed. (|this| is attached to
+ // the same context, but could live longer until the context is GC'ed)
+ blink::WebServiceWorkerProviderClient* provider_client_;
+
base::WeakPtrFactory<WebServiceWorkerProviderImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerProviderImpl);
@@ -100,4 +116,4 @@ class WebServiceWorkerProviderImpl : public blink::WebServiceWorkerProvider {
} // namespace content
-#endif // CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_PROVIDER_IMPL_H_
+#endif // CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_PROVIDER_IMPL_H_
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
new file mode 100644
index 00000000000..bf5efd739e0
--- /dev/null
+++ b/chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc
@@ -0,0 +1,479 @@
+// 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/service_worker/web_service_worker_registration_impl.h"
+
+#include <utility>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "content/child/child_process.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/renderer/service_worker/service_worker_dispatcher.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.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/web_service_worker_provider_impl.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/WebNavigationPreloadState.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistrationProxy.h"
+
+namespace content {
+
+namespace {
+
+class HandleImpl : public blink::WebServiceWorkerRegistration::Handle {
+ public:
+ explicit HandleImpl(
+ scoped_refptr<WebServiceWorkerRegistrationImpl> registration)
+ : registration_(std::move(registration)) {}
+ ~HandleImpl() override {}
+
+ blink::WebServiceWorkerRegistration* Registration() override {
+ return registration_.get();
+ }
+
+ private:
+ scoped_refptr<WebServiceWorkerRegistrationImpl> registration_;
+
+ DISALLOW_COPY_AND_ASSIGN(HandleImpl);
+};
+
+} // namespace
+
+WebServiceWorkerRegistrationImpl::QueuedTask::QueuedTask(
+ QueuedTaskType type,
+ const scoped_refptr<WebServiceWorkerImpl>& worker)
+ : type(type), worker(worker) {}
+
+WebServiceWorkerRegistrationImpl::QueuedTask::QueuedTask(
+ const QueuedTask& other) = default;
+
+WebServiceWorkerRegistrationImpl::QueuedTask::~QueuedTask() {}
+
+// static
+scoped_refptr<WebServiceWorkerRegistrationImpl>
+WebServiceWorkerRegistrationImpl::CreateForServiceWorkerGlobalScope(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
+ DCHECK(info->request.is_pending());
+ scoped_refptr<WebServiceWorkerRegistrationImpl> impl =
+ new WebServiceWorkerRegistrationImpl(std::move(info),
+ nullptr /* provider_context */);
+ impl->host_for_global_scope_ =
+ blink::mojom::ThreadSafeServiceWorkerRegistrationObjectHostAssociatedPtr::
+ Create(std::move(impl->info_->host_ptr_info), io_task_runner);
+ // |impl|'s destruction needs both DetachAndMaybeDestroy() and
+ // OnConnectionError() to be called (see comments at LifecycleState enum), and
+ // OnConnectionError() cannot happen before BindRequest(), therefore using
+ // base::Unretained() here is safe.
+ io_task_runner->PostTask(
+ FROM_HERE, base::BindOnce(&WebServiceWorkerRegistrationImpl::BindRequest,
+ base::Unretained(impl.get()),
+ std::move(impl->info_->request)));
+ impl->state_ = LifecycleState::kAttachedAndBound;
+ return impl;
+}
+
+// static
+scoped_refptr<WebServiceWorkerRegistrationImpl>
+WebServiceWorkerRegistrationImpl::CreateForServiceWorkerClient(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
+ base::WeakPtr<ServiceWorkerProviderContext> provider_context) {
+ DCHECK(info->request.is_pending());
+ scoped_refptr<WebServiceWorkerRegistrationImpl> impl =
+ new WebServiceWorkerRegistrationImpl(std::move(info),
+ std::move(provider_context));
+ impl->host_for_client_.Bind(std::move(impl->info_->host_ptr_info));
+ impl->BindRequest(std::move(impl->info_->request));
+ impl->state_ = LifecycleState::kAttachedAndBound;
+ return impl;
+}
+
+void WebServiceWorkerRegistrationImpl::AttachForServiceWorkerClient(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info) {
+ if (state_ == LifecycleState::kAttachedAndBound)
+ return;
+ DCHECK_EQ(LifecycleState::kDetached, state_);
+ DCHECK(!info->request.is_pending());
+ Attach(std::move(info));
+
+ DCHECK(!host_for_global_scope_);
+ DCHECK(!host_for_client_);
+ host_for_client_.Bind(std::move(info_->host_ptr_info));
+ state_ = LifecycleState::kAttachedAndBound;
+}
+
+void WebServiceWorkerRegistrationImpl::SetInstalling(
+ const scoped_refptr<WebServiceWorkerImpl>& service_worker) {
+ if (state_ == LifecycleState::kDetached)
+ return;
+ DCHECK_EQ(LifecycleState::kAttachedAndBound, state_);
+ if (proxy_)
+ proxy_->SetInstalling(WebServiceWorkerImpl::CreateHandle(service_worker));
+ else
+ queued_tasks_.push_back(QueuedTask(INSTALLING, service_worker));
+}
+
+void WebServiceWorkerRegistrationImpl::SetWaiting(
+ const scoped_refptr<WebServiceWorkerImpl>& service_worker) {
+ if (state_ == LifecycleState::kDetached)
+ return;
+ DCHECK_EQ(LifecycleState::kAttachedAndBound, state_);
+ if (proxy_)
+ proxy_->SetWaiting(WebServiceWorkerImpl::CreateHandle(service_worker));
+ else
+ queued_tasks_.push_back(QueuedTask(WAITING, service_worker));
+}
+
+void WebServiceWorkerRegistrationImpl::SetActive(
+ const scoped_refptr<WebServiceWorkerImpl>& service_worker) {
+ if (state_ == LifecycleState::kDetached)
+ return;
+ DCHECK_EQ(LifecycleState::kAttachedAndBound, state_);
+ if (proxy_)
+ proxy_->SetActive(WebServiceWorkerImpl::CreateHandle(service_worker));
+ else
+ queued_tasks_.push_back(QueuedTask(ACTIVE, service_worker));
+}
+
+void WebServiceWorkerRegistrationImpl::SetProxy(
+ blink::WebServiceWorkerRegistrationProxy* proxy) {
+ DCHECK_EQ(LifecycleState::kAttachedAndBound, state_);
+ DCHECK(info_);
+ DCHECK(host_for_global_scope_ || host_for_client_);
+ proxy_ = proxy;
+ RunQueuedTasks();
+}
+
+void WebServiceWorkerRegistrationImpl::RunQueuedTasks() {
+ DCHECK(proxy_);
+ for (const QueuedTask& task : queued_tasks_) {
+ if (task.type == INSTALLING)
+ proxy_->SetInstalling(WebServiceWorkerImpl::CreateHandle(task.worker));
+ else if (task.type == WAITING)
+ proxy_->SetWaiting(WebServiceWorkerImpl::CreateHandle(task.worker));
+ else if (task.type == ACTIVE)
+ proxy_->SetActive(WebServiceWorkerImpl::CreateHandle(task.worker));
+ else if (task.type == UPDATE_FOUND)
+ proxy_->DispatchUpdateFoundEvent();
+ }
+ queued_tasks_.clear();
+}
+
+blink::mojom::ServiceWorkerRegistrationObjectHost*
+WebServiceWorkerRegistrationImpl::GetRegistrationObjectHost() {
+ if (host_for_client_)
+ return host_for_client_.get();
+ if (host_for_global_scope_)
+ return host_for_global_scope_->get();
+ NOTREACHED();
+ return nullptr;
+}
+
+void WebServiceWorkerRegistrationImpl::Attach(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info) {
+ DCHECK(!info_);
+ DCHECK(info);
+ DCHECK_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
+ info->registration_id);
+ DCHECK_EQ(registration_id_, info->registration_id);
+ DCHECK(info->host_ptr_info.is_valid());
+ info_ = std::move(info);
+}
+
+void WebServiceWorkerRegistrationImpl::DetachAndMaybeDestroy() {
+ DCHECK(creation_task_runner_->RunsTasksInCurrentSequence());
+ proxy_ = nullptr;
+ queued_tasks_.clear();
+ host_for_client_.reset();
+ host_for_global_scope_ = nullptr;
+ info_ = nullptr;
+ if (state_ == LifecycleState::kUnbound) {
+ state_ = LifecycleState::kDead;
+ delete this;
+ return;
+ }
+ DCHECK_EQ(LifecycleState::kAttachedAndBound, state_);
+ state_ = LifecycleState::kDetached;
+ // We will continue in OnConnectionError() triggered by destruction of the
+ // content::ServiceWorkerRegistrationObjectHost in the browser process, or
+ // else in Attach*() if |this| is reused.
+}
+
+void WebServiceWorkerRegistrationImpl::BindRequest(
+ blink::mojom::ServiceWorkerRegistrationObjectAssociatedRequest request) {
+ DCHECK(request.is_pending());
+ binding_.Bind(std::move(request));
+ binding_.set_connection_error_handler(
+ base::Bind(&WebServiceWorkerRegistrationImpl::OnConnectionError,
+ base::Unretained(this)));
+}
+
+void WebServiceWorkerRegistrationImpl::OnConnectionError() {
+ if (!creation_task_runner_->RunsTasksInCurrentSequence()) {
+ // If this registration impl is for a service worker execution context,
+ // |this| lives on the worker thread but |binding_| is bound on the IO
+ // thread due to limitations of channel-associated interfaces. Close
+ // |binding_| here since this is the thread it was bound on, then hop to the
+ // worker thread to handle lifetime of |this|. In the case of a service
+ // worker client, both |this| and |binding_| live on the main thread, so the
+ // binding can be closed normally during destruction.
+ binding_.Close();
+ creation_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&WebServiceWorkerRegistrationImpl::OnConnectionError,
+ base::Unretained(this)));
+ return;
+ }
+ if (state_ == LifecycleState::kDetached) {
+ state_ = LifecycleState::kDead;
+ delete this;
+ return;
+ }
+ DCHECK_EQ(LifecycleState::kAttachedAndBound, state_);
+ state_ = LifecycleState::kUnbound;
+ // We will continue in DetachAndMaybeDestroy() when all references of |this|
+ // have been released by Blink.
+}
+
+blink::WebServiceWorkerRegistrationProxy*
+WebServiceWorkerRegistrationImpl::Proxy() {
+ return proxy_;
+}
+
+blink::WebURL WebServiceWorkerRegistrationImpl::Scope() const {
+ return info_->options->scope;
+}
+
+void WebServiceWorkerRegistrationImpl::Update(
+ std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks) {
+ DCHECK(state_ == LifecycleState::kAttachedAndBound ||
+ state_ == LifecycleState::kUnbound);
+ GetRegistrationObjectHost()->Update(
+ base::BindOnce(&WebServiceWorkerRegistrationImpl::OnUpdated,
+ base::Unretained(this), std::move(callbacks)));
+}
+
+void WebServiceWorkerRegistrationImpl::Unregister(
+ std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks) {
+ DCHECK(state_ == LifecycleState::kAttachedAndBound ||
+ state_ == LifecycleState::kUnbound);
+ GetRegistrationObjectHost()->Unregister(
+ base::BindOnce(&WebServiceWorkerRegistrationImpl::OnUnregistered,
+ base::Unretained(this), std::move(callbacks)));
+}
+
+void WebServiceWorkerRegistrationImpl::EnableNavigationPreload(
+ bool enable,
+ std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks) {
+ DCHECK(state_ == LifecycleState::kAttachedAndBound ||
+ state_ == LifecycleState::kUnbound);
+ GetRegistrationObjectHost()->EnableNavigationPreload(
+ enable,
+ base::BindOnce(
+ &WebServiceWorkerRegistrationImpl::OnDidEnableNavigationPreload,
+ base::Unretained(this), std::move(callbacks)));
+}
+
+void WebServiceWorkerRegistrationImpl::GetNavigationPreloadState(
+ std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks) {
+ DCHECK(state_ == LifecycleState::kAttachedAndBound ||
+ state_ == LifecycleState::kUnbound);
+ GetRegistrationObjectHost()->GetNavigationPreloadState(base::BindOnce(
+ &WebServiceWorkerRegistrationImpl::OnDidGetNavigationPreloadState,
+ base::Unretained(this), std::move(callbacks)));
+}
+
+void WebServiceWorkerRegistrationImpl::SetNavigationPreloadHeader(
+ const blink::WebString& value,
+ std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks) {
+ DCHECK(state_ == LifecycleState::kAttachedAndBound ||
+ state_ == LifecycleState::kUnbound);
+ GetRegistrationObjectHost()->SetNavigationPreloadHeader(
+ value.Utf8(),
+ base::BindOnce(
+ &WebServiceWorkerRegistrationImpl::OnDidSetNavigationPreloadHeader,
+ base::Unretained(this), std::move(callbacks)));
+}
+
+int64_t WebServiceWorkerRegistrationImpl::RegistrationId() const {
+ return info_->registration_id;
+}
+
+void WebServiceWorkerRegistrationImpl::OnUpdated(
+ std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg) {
+ if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
+ DCHECK(error_msg);
+ callbacks->OnError(blink::WebServiceWorkerError(
+ error, blink::WebString::FromUTF8(*error_msg)));
+ return;
+ }
+
+ DCHECK(!error_msg);
+ callbacks->OnSuccess();
+}
+
+void WebServiceWorkerRegistrationImpl::OnUnregistered(
+ std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg) {
+ if (error != blink::mojom::ServiceWorkerErrorType::kNone &&
+ error != blink::mojom::ServiceWorkerErrorType::kNotFound) {
+ DCHECK(error_msg);
+ callbacks->OnError(blink::WebServiceWorkerError(
+ error, blink::WebString::FromUTF8(*error_msg)));
+ return;
+ }
+
+ callbacks->OnSuccess(error == blink::mojom::ServiceWorkerErrorType::kNone);
+}
+
+void WebServiceWorkerRegistrationImpl::OnDidEnableNavigationPreload(
+ std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg) {
+ if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
+ DCHECK(error_msg);
+ callbacks->OnError(blink::WebServiceWorkerError(
+ error, blink::WebString::FromUTF8(*error_msg)));
+ return;
+ }
+ callbacks->OnSuccess();
+}
+
+void WebServiceWorkerRegistrationImpl::OnDidGetNavigationPreloadState(
+ std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg,
+ blink::mojom::NavigationPreloadStatePtr state) {
+ if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
+ DCHECK(error_msg);
+ callbacks->OnError(blink::WebServiceWorkerError(
+ error, blink::WebString::FromUTF8(*error_msg)));
+ return;
+ }
+ callbacks->OnSuccess(blink::WebNavigationPreloadState(
+ state->enabled, blink::WebString::FromUTF8(state->header)));
+}
+
+void WebServiceWorkerRegistrationImpl::OnDidSetNavigationPreloadHeader(
+ std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg) {
+ if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
+ DCHECK(error_msg);
+ callbacks->OnError(blink::WebServiceWorkerError(
+ error, blink::WebString::FromUTF8(*error_msg)));
+ return;
+ }
+ callbacks->OnSuccess();
+}
+
+// static
+std::unique_ptr<blink::WebServiceWorkerRegistration::Handle>
+WebServiceWorkerRegistrationImpl::CreateHandle(
+ scoped_refptr<WebServiceWorkerRegistrationImpl> registration) {
+ if (!registration)
+ return nullptr;
+ return std::make_unique<HandleImpl>(std::move(registration));
+}
+
+// static
+void WebServiceWorkerRegistrationImpl::Destruct(
+ const WebServiceWorkerRegistrationImpl* impl) {
+ const_cast<WebServiceWorkerRegistrationImpl*>(impl)->DetachAndMaybeDestroy();
+}
+
+WebServiceWorkerRegistrationImpl::WebServiceWorkerRegistrationImpl(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
+ base::WeakPtr<ServiceWorkerProviderContext> provider_context)
+ : registration_id_(info->registration_id),
+ proxy_(nullptr),
+ binding_(this),
+ creation_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ state_(LifecycleState::kInitial),
+ provider_context_for_client_(std::move(provider_context)) {
+ Attach(std::move(info));
+
+ if (provider_context_for_client_)
+ provider_context_for_client_->AddServiceWorkerRegistration(registration_id_,
+ this);
+}
+
+WebServiceWorkerRegistrationImpl::~WebServiceWorkerRegistrationImpl() {
+ DCHECK_EQ(LifecycleState::kDead, state_);
+ if (provider_context_for_client_)
+ provider_context_for_client_->RemoveServiceWorkerRegistration(
+ registration_id_);
+}
+
+void WebServiceWorkerRegistrationImpl::SetVersionAttributes(
+ int changed_mask,
+ blink::mojom::ServiceWorkerObjectInfoPtr installing,
+ blink::mojom::ServiceWorkerObjectInfoPtr waiting,
+ blink::mojom::ServiceWorkerObjectInfoPtr active) {
+ if (!creation_task_runner_->RunsTasksInCurrentSequence()) {
+ // As this posted task will definitely run before OnConnectionError() on the
+ // |creation_task_runner_|, using base::Unretained() here is safe.
+ creation_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&WebServiceWorkerRegistrationImpl::SetVersionAttributes,
+ base::Unretained(this), changed_mask,
+ std::move(installing), std::move(waiting),
+ std::move(active)));
+ return;
+ }
+
+ if (state_ == LifecycleState::kDetached)
+ return;
+ DCHECK_EQ(LifecycleState::kAttachedAndBound, state_);
+ ServiceWorkerDispatcher* dispatcher =
+ ServiceWorkerDispatcher::GetThreadSpecificInstance();
+ DCHECK(dispatcher);
+ ChangedVersionAttributesMask mask(changed_mask);
+ if (mask.installing_changed()) {
+ DCHECK(installing);
+ SetInstalling(dispatcher->GetOrCreateServiceWorker(
+ ServiceWorkerHandleReference::Adopt(std::move(installing),
+ dispatcher->thread_safe_sender())));
+ }
+ if (mask.waiting_changed()) {
+ DCHECK(waiting);
+ SetWaiting(dispatcher->GetOrCreateServiceWorker(
+ ServiceWorkerHandleReference::Adopt(std::move(waiting),
+ dispatcher->thread_safe_sender())));
+ }
+ if (mask.active_changed()) {
+ DCHECK(active);
+ SetActive(dispatcher->GetOrCreateServiceWorker(
+ ServiceWorkerHandleReference::Adopt(std::move(active),
+ dispatcher->thread_safe_sender())));
+ }
+}
+
+void WebServiceWorkerRegistrationImpl::UpdateFound() {
+ if (!creation_task_runner_->RunsTasksInCurrentSequence()) {
+ // As this posted task will definitely run before OnConnectionError() on the
+ // |creation_task_runner_|, using base::Unretained() here is safe.
+ creation_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&WebServiceWorkerRegistrationImpl::UpdateFound,
+ base::Unretained(this)));
+ return;
+ }
+
+ if (state_ == LifecycleState::kDetached)
+ return;
+ DCHECK_EQ(LifecycleState::kAttachedAndBound, state_);
+ if (proxy_)
+ proxy_->DispatchUpdateFoundEvent();
+ else
+ queued_tasks_.push_back(QueuedTask(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
new file mode 100644
index 00000000000..2388b1dd3b6
--- /dev/null
+++ b/chromium/content/renderer/service_worker/web_service_worker_registration_impl.h
@@ -0,0 +1,293 @@
+// 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_SERVICE_WORKER_WEB_SERVICE_WORKER_REGISTRATION_IMPL_H_
+#define CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_REGISTRATION_IMPL_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_error_type.mojom.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_registration.mojom.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace blink {
+class WebServiceWorkerRegistrationProxy;
+}
+
+namespace content {
+
+class WebServiceWorkerImpl;
+class ServiceWorkerProviderContext;
+
+// WebServiceWorkerRegistrationImpl corresponds to one ServiceWorkerRegistration
+// object in JavaScript. It is owned by
+// content::ServiceWorkerRegistrationObjectHost in the browser process, but also
+// is refcounted by WebServiceWorkerRegistration::Handles in the renderer
+// process. See the detailed lifecycle explanation below.
+//
+// A WebServiceWorkerRegistrationImpl is created when the browser process sends
+// the first ServiceWorkerRegistrationObjectInfo to the renderer process that
+// describes the desired JavaScript object. The instance is created and takes
+// ownership of the object info. The object info has a Mojo connection to a
+// ServiceWorkerRegistrationObjectHost in the browser process
+// ((|this->info_.host_ptr_info|) . In addition, The
+// WebServiceWorkerRegistrationImpl itself is connected with the
+// ServiceWorkerRegistrationObjectHost (|this->binding_|). Creation always
+// happens in order to create a ServiceWorkerRegistration JavaScript object in
+// Blink. The instance is shared with Blink via
+// WebServiceWorkerRegistration::Handle. As long as a handle is alive in Blink,
+// this instance should not die.
+//
+// During the lifetime of WebServiceWorkerRegistrationImpl, multiple
+// WebServiceWorkerRegistration::Handles may be created and held by Blink. If
+// the browser process sends another ServiceWorkerRegistrationObjectInfo to the
+// renderer process for this same JavaScript object, the renderer reuses the
+// existing WebServiceWorkerRegistrationImpl instance and creates a new
+// WebServiceWorkerRegistration::Handle to share with Blink.
+//
+// If all WebServiceWorkerRegistration::Handles are destroyed, the
+// WebServiceWorkerRegistrationImpl clears |info_|, which informs the
+// ServiceWorkerRegistrationObjectHost in the browser process that this instance
+// is ready to be destroyed. If there was no ServiceWorkerRegistrationObjectInfo
+// inflight, the browser process destroys the Mojo connection to this instance,
+// which finally destroys it.
+//
+// Another destruction scenario is that the browser process destroys the
+// ServiceWorkerRegistrationObject Mojo connection while some
+// WebServiceWorkerRegistration::Handles are still held by Blink. In such a case
+// this instance will finally be destroyed after all Blink destroys all the
+// WebServiceWorkerRegistration::Handles.
+class CONTENT_EXPORT WebServiceWorkerRegistrationImpl
+ : public blink::mojom::ServiceWorkerRegistrationObject,
+ public blink::WebServiceWorkerRegistration,
+ public base::RefCounted<WebServiceWorkerRegistrationImpl,
+ WebServiceWorkerRegistrationImpl> {
+ public:
+ // |io_task_runner| is used to bind |host_for_global_scope_| and |binding_|
+ // for service worker execution context, as both of
+ // ServiceWorkerRegistrationObjectHost and ServiceWorkerRegistrationObject are
+ // Channel-associated interfaces and need to be bound on either the main or IO
+ // thread.
+ static scoped_refptr<WebServiceWorkerRegistrationImpl>
+ CreateForServiceWorkerGlobalScope(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
+ static scoped_refptr<WebServiceWorkerRegistrationImpl>
+ CreateForServiceWorkerClient(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
+ base::WeakPtr<ServiceWorkerProviderContext> provider_context);
+
+ void AttachForServiceWorkerClient(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info);
+
+ void SetInstalling(const scoped_refptr<WebServiceWorkerImpl>& service_worker);
+ void SetWaiting(const scoped_refptr<WebServiceWorkerImpl>& service_worker);
+ void SetActive(const scoped_refptr<WebServiceWorkerImpl>& service_worker);
+
+ // blink::WebServiceWorkerRegistration overrides.
+ void SetProxy(blink::WebServiceWorkerRegistrationProxy* proxy) override;
+ blink::WebServiceWorkerRegistrationProxy* Proxy() override;
+ blink::WebURL Scope() const override;
+ void Update(
+ std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks) override;
+ void Unregister(std::unique_ptr<WebServiceWorkerUnregistrationCallbacks>
+ callbacks) override;
+ void EnableNavigationPreload(
+ bool enable,
+ std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks) override;
+ void GetNavigationPreloadState(
+ std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks)
+ override;
+ void SetNavigationPreloadHeader(
+ const blink::WebString& value,
+ std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks)
+ override;
+ int64_t RegistrationId() const override;
+
+ // Creates blink::WebServiceWorkerRegistration::Handle object that owns a
+ // reference to the given WebServiceWorkerRegistrationImpl object.
+ static std::unique_ptr<blink::WebServiceWorkerRegistration::Handle>
+ CreateHandle(scoped_refptr<WebServiceWorkerRegistrationImpl> registration);
+
+ private:
+ friend class base::RefCounted<WebServiceWorkerRegistrationImpl,
+ WebServiceWorkerRegistrationImpl>;
+ WebServiceWorkerRegistrationImpl(
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info,
+ base::WeakPtr<ServiceWorkerProviderContext> provider_context);
+ ~WebServiceWorkerRegistrationImpl() override;
+
+ // Implements blink::mojom::ServiceWorkerRegistrationObject.
+ void SetVersionAttributes(
+ int changed_mask,
+ blink::mojom::ServiceWorkerObjectInfoPtr installing,
+ blink::mojom::ServiceWorkerObjectInfoPtr waiting,
+ blink::mojom::ServiceWorkerObjectInfoPtr active) override;
+ void UpdateFound() override;
+
+ // RefCounted traits implementation, rather than delete |impl| directly, calls
+ // |impl->DetachAndMaybeDestroy()| to notify that the last reference to it has
+ // gone away.
+ static void Destruct(const WebServiceWorkerRegistrationImpl* impl);
+
+ // Enumeration of the possible |state_| during lifetime of this class.
+ // - |kInitial| --> |kAttachedAndBound|
+ // |this| is initialized with |kInitial| state by the ctor then it is
+ // set to |kAttachedAndBound| state soon in the factory methods
+ // (CreateForServiceWorkerGlobalScope() or CreateForServiceWorkerClient()).
+ // From the beginning |this| is referenced by
+ // blink::WebServiceWorkerRegistration::Handle impl and the |binding_| Mojo
+ // connection has been established.
+ // - |kAttachedAndBound| --> |kDetached|
+ // When all references to |this| have been released by Blink,
+ // DetachAndMaybeDestroy() will be triggered to change |state_| from
+ // |kAttachedAndBound| to |kDetached|.
+ // - |kAttachedAndBound| --> |kUnbound|
+ // When |binding_| Mojo connection gets broken, OnConnectionError() will be
+ // triggered to change |state_| from |kAttachedAndBound| to |kUnbound|.
+ // - {|kUnbound|, |kDetached|} --> |kDead|
+ // But if DetachAndMaybeDestroy() saw that |state_| is already |kUnbound| or
+ // OnConnectionError() saw that |state_| is already |kDetached|, they will
+ // just set |state_| to |kDead| and delete |this| immediately.
+ // - |kDetached| --> |kAttachedAndBound|
+ // When |this| is in |kDetached| state, if an inflight
+ // ServiceWorkerRegistrationObjectInfo for the same JavaScript registration
+ // object arrived, |this| is reused to be provided to Blink. In such a case
+ // AttachForServiceWorkerClient() sets |state_| to |kAttachedAndBound|.
+ enum class LifecycleState {
+ kInitial,
+ kAttachedAndBound,
+ kUnbound,
+ kDetached,
+ kDead
+ };
+
+ enum QueuedTaskType {
+ INSTALLING,
+ WAITING,
+ ACTIVE,
+ UPDATE_FOUND,
+ };
+
+ struct QueuedTask {
+ QueuedTask(QueuedTaskType type,
+ const scoped_refptr<WebServiceWorkerImpl>& worker);
+ QueuedTask(const QueuedTask& other);
+ ~QueuedTask();
+ QueuedTaskType type;
+ scoped_refptr<WebServiceWorkerImpl> worker;
+ };
+
+ void RunQueuedTasks();
+ blink::mojom::ServiceWorkerRegistrationObjectHost*
+ GetRegistrationObjectHost();
+ void Attach(blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info);
+ void DetachAndMaybeDestroy();
+ void BindRequest(
+ blink::mojom::ServiceWorkerRegistrationObjectAssociatedRequest request);
+ void OnConnectionError();
+
+ void OnUpdated(std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg);
+ void OnUnregistered(
+ std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg);
+ void OnDidEnableNavigationPreload(
+ std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg);
+ void OnDidGetNavigationPreloadState(
+ std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg,
+ blink::mojom::NavigationPreloadStatePtr state);
+ void OnDidSetNavigationPreloadHeader(
+ std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg);
+
+ // |registration_id_| is the id of the corresponding
+ // content::ServiceWorkerRegistration in the browser process.
+ const int64_t registration_id_;
+ // |info_| is initialized by the contructor with |info| passed from the remote
+ // content::ServiceWorkerRegistrationObjectHost just created in the browser
+ // process. It will be reset to nullptr by DetachAndMaybeDestroy() when
+ // there is no any blink::WebServiceWorkerRegistration::Handle referencing
+ // |this|. After that if another Mojo connection from the same remote
+ // content::ServiceWorkerRegistrationObjectHost is passed here again (e.g.
+ // WebServiceWorkerProviderImpl::OnDidGetRegistration()), |info_| will be set
+ // to the valid value again by Attach().
+ // |info_->host_ptr_info| is taken/bound by |host_for_global_scope_| or
+ // |host_for_client_| which holds the Mojo connection caller end point
+ // retaining an reference to the remote
+ // content::ServiceWorkerRegistrationObjectHost to control its lifetime.
+ // |info_->request| is bound on |binding_|.
+ blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info_;
+ blink::WebServiceWorkerRegistrationProxy* proxy_;
+
+ // Either |host_for_global_scope_| or |host_for_client_| is non-null.
+ //
+ // |host_for_global_scope_| is for service worker execution contexts. It is
+ // used on the worker thread but bound on the IO thread, because it's a
+ // channel- associated interface which can be bound only on the main or IO
+ // thread.
+ // TODO(leonhsl): Once we can detach this interface out from the legacy IPC
+ // channel-associated interfaces world, we should bind it always on the worker
+ // thread on which |this| lives.
+ // Although it is a scoped_refptr, the only one owner is |this|.
+ scoped_refptr<
+ blink::mojom::ThreadSafeServiceWorkerRegistrationObjectHostAssociatedPtr>
+ host_for_global_scope_;
+ // |host_for_client_| is for service worker clients (document, shared worker).
+ // It is bound and used on the main thread.
+ blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedPtr
+ host_for_client_;
+
+ // |binding_| keeps the Mojo binding to serve its other Mojo endpoint (i.e.
+ // the caller end) held by the content::ServiceWorkerRegistrationObjectHost in
+ // the browser process, is bound with |info_->request| by BindRequest()
+ // function. This also controls lifetime of |this|, its connection error
+ // handler will delete |this|. It is bound on the main thread for service
+ // worker clients (document, shared worker). It is bound on the IO thread for
+ // service worker execution contexts, but always uses PostTask to handle
+ // received messages actually on the worker thread, because it's a
+ // channel-associated interface which can be bound only on the main or IO
+ // thread.
+ // TODO(leonhsl): Once we can detach this interface out from the legacy IPC
+ // channel-associated interfaces world, for service worker execution context
+ // we should bind it always on the worker thread on which |this| lives.
+ mojo::AssociatedBinding<blink::mojom::ServiceWorkerRegistrationObject>
+ binding_;
+ scoped_refptr<base::SingleThreadTaskRunner> creation_task_runner_;
+ LifecycleState state_;
+
+ std::vector<QueuedTask> queued_tasks_;
+
+ // For service worker client contexts, |this| is tracked (not owned) in
+ // |provider_context_for_client_->controllee_state_->registrations_|.
+ // For service worker execution contexts, |provider_context_for_client_| is
+ // null.
+ base::WeakPtr<ServiceWorkerProviderContext> provider_context_for_client_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerRegistrationImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_REGISTRATION_IMPL_H_
diff --git a/chromium/content/renderer/service_worker/worker_fetch_context_impl.cc b/chromium/content/renderer/service_worker/worker_fetch_context_impl.cc
index 880e0939123..da8ec85c1f9 100644
--- a/chromium/content/renderer/service_worker/worker_fetch_context_impl.cc
+++ b/chromium/content/renderer/service_worker/worker_fetch_context_impl.cc
@@ -6,24 +6,110 @@
#include "base/feature_list.h"
#include "content/child/child_thread_impl.h"
-#include "content/child/request_extra_data.h"
-#include "content/child/resource_dispatcher.h"
#include "content/child/thread_safe_sender.h"
-#include "content/child/web_url_loader_impl.h"
#include "content/common/frame_messages.h"
+#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/service_names.mojom.h"
+#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/loader/resource_dispatcher.h"
+#include "content/renderer/loader/web_url_loader_impl.h"
+#include "content/renderer/service_worker/controller_service_worker_connector.h"
+#include "content/renderer/service_worker/service_worker_subresource_loader.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
namespace content {
+class WorkerFetchContextImpl::URLLoaderFactoryImpl
+ : public blink::WebURLLoaderFactory {
+ public:
+ URLLoaderFactoryImpl(
+ base::WeakPtr<ResourceDispatcher> resource_dispatcher,
+ scoped_refptr<ChildURLLoaderFactoryGetter> loader_factory_getter)
+ : resource_dispatcher_(std::move(resource_dispatcher)),
+ loader_factory_getter_(std::move(loader_factory_getter)),
+ weak_ptr_factory_(this) {}
+ ~URLLoaderFactoryImpl() override = default;
+
+ std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
+ const blink::WebURLRequest& request,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
+ DCHECK(task_runner);
+ DCHECK(resource_dispatcher_);
+ if (auto loader = CreateServiceWorkerURLLoader(request, task_runner))
+ return loader;
+ return std::make_unique<WebURLLoaderImpl>(
+ resource_dispatcher_.get(), std::move(task_runner),
+ loader_factory_getter_->GetFactoryForURL(request.Url()));
+ }
+
+ void SetServiceWorkerURLLoaderFactory(
+ mojom::URLLoaderFactoryPtr service_worker_url_loader_factory) {
+ service_worker_url_loader_factory_ =
+ std::move(service_worker_url_loader_factory);
+ }
+
+ base::WeakPtr<URLLoaderFactoryImpl> GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+ }
+
+ private:
+ std::unique_ptr<blink::WebURLLoader> CreateServiceWorkerURLLoader(
+ const blink::WebURLRequest& request,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ // TODO(horo): Unify this code path with
+ // ServiceWorkerNetworkProvider::CreateURLLoader that is used for document
+ // cases.
+
+ // We need URLLoaderFactory populated in order to create our own URLLoader
+ // for subresource loading via a service worker.
+ if (!service_worker_url_loader_factory_)
+ return nullptr;
+
+ // If it's not for HTTP or HTTPS no need to intercept the request.
+ if (!GURL(request.Url()).SchemeIsHTTPOrHTTPS())
+ return nullptr;
+
+ // If the service worker mode is not all, no need to intercept the request.
+ if (request.GetServiceWorkerMode() !=
+ blink::WebURLRequest::ServiceWorkerMode::kAll) {
+ return nullptr;
+ }
+
+ // Create our own URLLoader to route the request to the controller service
+ // worker.
+ return std::make_unique<WebURLLoaderImpl>(
+ resource_dispatcher_.get(), std::move(task_runner),
+ service_worker_url_loader_factory_.get());
+ }
+
+ base::WeakPtr<ResourceDispatcher> resource_dispatcher_;
+ scoped_refptr<ChildURLLoaderFactoryGetter> loader_factory_getter_;
+ mojom::URLLoaderFactoryPtr service_worker_url_loader_factory_;
+ base::WeakPtrFactory<URLLoaderFactoryImpl> weak_ptr_factory_;
+ DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryImpl);
+};
+
WorkerFetchContextImpl::WorkerFetchContextImpl(
mojom::ServiceWorkerWorkerClientRequest service_worker_client_request,
+ mojom::ServiceWorkerContainerHostPtrInfo service_worker_container_host_info,
ChildURLLoaderFactoryGetter::Info url_loader_factory_getter_info)
: binding_(this),
service_worker_client_request_(std::move(service_worker_client_request)),
+ service_worker_container_host_info_(
+ std::move(service_worker_container_host_info)),
url_loader_factory_getter_info_(
std::move(url_loader_factory_getter_info)),
- thread_safe_sender_(ChildThreadImpl::current()->thread_safe_sender()) {}
+ thread_safe_sender_(ChildThreadImpl::current()->thread_safe_sender()) {
+ if (ServiceWorkerUtils::IsServicificationEnabled()) {
+ ChildThreadImpl::current()->GetConnector()->BindInterface(
+ mojom::kBrowserServiceName,
+ mojo::MakeRequest(&blob_registry_ptr_info_));
+ }
+}
WorkerFetchContextImpl::~WorkerFetchContextImpl() {}
@@ -32,21 +118,37 @@ void WorkerFetchContextImpl::InitializeOnWorkerThread(
DCHECK(loading_task_runner->RunsTasksInCurrentSequence());
DCHECK(!resource_dispatcher_);
DCHECK(!binding_.is_bound());
- resource_dispatcher_ = base::MakeUnique<ResourceDispatcher>(
+ resource_dispatcher_ = std::make_unique<ResourceDispatcher>(
nullptr, std::move(loading_task_runner));
url_loader_factory_getter_ = url_loader_factory_getter_info_.Bind();
-
if (service_worker_client_request_.is_pending())
binding_.Bind(std::move(service_worker_client_request_));
+
+ if (ServiceWorkerUtils::IsServicificationEnabled()) {
+ service_worker_container_host_.Bind(
+ std::move(service_worker_container_host_info_));
+
+ blink::mojom::BlobRegistryPtr blob_registry_ptr;
+ blob_registry_ptr.Bind(std::move(blob_registry_ptr_info_));
+ blob_registry_ = base::MakeRefCounted<
+ base::RefCountedData<blink::mojom::BlobRegistryPtr>>(
+ std::move(blob_registry_ptr));
+ }
}
-std::unique_ptr<blink::WebURLLoader> WorkerFetchContextImpl::CreateURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- return base::MakeUnique<content::WebURLLoaderImpl>(
- resource_dispatcher_.get(), std::move(task_runner),
- url_loader_factory_getter_->GetFactoryForURL(request.Url()));
+std::unique_ptr<blink::WebURLLoaderFactory>
+WorkerFetchContextImpl::CreateURLLoaderFactory() {
+ DCHECK(url_loader_factory_getter_);
+ DCHECK(!url_loader_factory_);
+ auto factory = std::make_unique<URLLoaderFactoryImpl>(
+ resource_dispatcher_->GetWeakPtr(), url_loader_factory_getter_);
+ url_loader_factory_ = factory->GetWeakPtr();
+
+ if (ServiceWorkerUtils::IsServicificationEnabled())
+ ResetServiceWorkerURLLoaderFactory();
+
+ return factory;
}
void WorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) {
@@ -60,22 +162,17 @@ void WorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) {
if (!IsControlledByServiceWorker() &&
request.GetServiceWorkerMode() !=
blink::WebURLRequest::ServiceWorkerMode::kNone) {
+ // TODO(falken): Is still this needed? It used to set kForeign for foreign
+ // fetch.
request.SetServiceWorkerMode(
- blink::WebURLRequest::ServiceWorkerMode::kForeign);
+ blink::WebURLRequest::ServiceWorkerMode::kNone);
}
}
bool WorkerFetchContextImpl::IsControlledByServiceWorker() const {
return is_controlled_by_service_worker_ ||
- (controller_version_id_ != kInvalidServiceWorkerVersionId);
-}
-
-void WorkerFetchContextImpl::SetDataSaverEnabled(bool enabled) {
- is_data_saver_enabled_ = enabled;
-}
-
-bool WorkerFetchContextImpl::IsDataSaverEnabled() const {
- return is_data_saver_enabled_;
+ (controller_version_id_ !=
+ blink::mojom::kInvalidServiceWorkerVersionId);
}
void WorkerFetchContextImpl::SetIsOnSubframe(bool is_on_sub_frame) {
@@ -143,6 +240,10 @@ void WorkerFetchContextImpl::set_is_secure_context(bool flag) {
is_secure_context_ = flag;
}
+void WorkerFetchContextImpl::set_origin_url(const GURL& origin_url) {
+ origin_url_ = origin_url;
+}
+
void WorkerFetchContextImpl::SetApplicationCacheHostID(int id) {
appcache_host_id_ = id;
}
@@ -154,10 +255,31 @@ int WorkerFetchContextImpl::ApplicationCacheHostID() const {
void WorkerFetchContextImpl::SetControllerServiceWorker(
int64_t controller_version_id) {
controller_version_id_ = controller_version_id;
+ if (ServiceWorkerUtils::IsServicificationEnabled())
+ ResetServiceWorkerURLLoaderFactory();
}
bool WorkerFetchContextImpl::Send(IPC::Message* message) {
return thread_safe_sender_->Send(message);
}
+void WorkerFetchContextImpl::ResetServiceWorkerURLLoaderFactory() {
+ DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ if (!url_loader_factory_)
+ return;
+ if (!IsControlledByServiceWorker()) {
+ url_loader_factory_->SetServiceWorkerURLLoaderFactory(nullptr);
+ return;
+ }
+ mojom::URLLoaderFactoryPtr service_worker_url_loader_factory;
+ mojo::MakeStrongBinding(
+ std::make_unique<ServiceWorkerSubresourceLoaderFactory>(
+ base::MakeRefCounted<ControllerServiceWorkerConnector>(
+ service_worker_container_host_.get()),
+ url_loader_factory_getter_, origin_url_, blob_registry_),
+ mojo::MakeRequest(&service_worker_url_loader_factory));
+ url_loader_factory_->SetServiceWorkerURLLoaderFactory(
+ std::move(service_worker_url_loader_factory));
+}
+
} // namespace content
diff --git a/chromium/content/renderer/service_worker/worker_fetch_context_impl.h b/chromium/content/renderer/service_worker/worker_fetch_context_impl.h
index 48903033d02..1e981e6346b 100644
--- a/chromium/content/renderer/service_worker/worker_fetch_context_impl.h
+++ b/chromium/content/renderer/service_worker/worker_fetch_context_impl.h
@@ -7,13 +7,15 @@
#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
#include "content/public/common/service_worker_modes.h"
#include "content/public/common/url_loader_factory.mojom.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
#include "ipc/ipc_message.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "third_party/WebKit/common/blob/blob_registry.mojom.h"
#include "third_party/WebKit/public/platform/WebApplicationCacheHost.h"
#include "third_party/WebKit/public/platform/WebWorkerFetchContext.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "url/gurl.h"
namespace base {
@@ -39,19 +41,17 @@ class WorkerFetchContextImpl : public blink::WebWorkerFetchContext,
public:
WorkerFetchContextImpl(
mojom::ServiceWorkerWorkerClientRequest service_worker_client_request,
+ mojom::ServiceWorkerContainerHostPtrInfo
+ service_worker_container_host_info,
ChildURLLoaderFactoryGetter::Info url_loader_factory_getter_info);
~WorkerFetchContextImpl() override;
// blink::WebWorkerFetchContext implementation:
void InitializeOnWorkerThread(
scoped_refptr<base::SingleThreadTaskRunner>) override;
- std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
+ std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory() override;
void WillSendRequest(blink::WebURLRequest&) override;
bool IsControlledByServiceWorker() const override;
- void SetDataSaverEnabled(bool) override;
- bool IsDataSaverEnabled() const override;
void SetIsOnSubframe(bool) override;
bool IsOnSubframe() const override;
blink::WebURL SiteForCookies() const override;
@@ -79,37 +79,65 @@ class WorkerFetchContextImpl : public blink::WebWorkerFetchContext,
// Sets whether the worker context is a secure context.
// https://w3c.github.io/webappsec-secure-contexts/
void set_is_secure_context(bool flag);
+ void set_origin_url(const GURL& origin_url);
private:
+ class URLLoaderFactoryImpl;
+
bool Send(IPC::Message* message);
+ // S13nServiceWorker:
+ // Resets the service worker url loader factory of a URLLoaderFactoryImpl
+ // which was passed to Blink. The url loader factory is connected to the
+ // controller service worker. Sets nullptr if the worker context is not
+ // controlled by a service worker.
+ void ResetServiceWorkerURLLoaderFactory();
+
mojo::Binding<mojom::ServiceWorkerWorkerClient> binding_;
+ // Bound to |this| on the worker thread.
mojom::ServiceWorkerWorkerClientRequest service_worker_client_request_;
+ // Consumed on the worker thread to create |service_worker_container_host_|.
+ mojom::ServiceWorkerContainerHostPtrInfo service_worker_container_host_info_;
// Consumed on the worker thread to create |url_loader_factory_getter_|.
ChildURLLoaderFactoryGetter::Info url_loader_factory_getter_info_;
+ // Consumed on the worker thread to create |blob_registry_|.
+ blink::mojom::BlobRegistryPtrInfo blob_registry_ptr_info_;
int service_worker_provider_id_ = kInvalidServiceWorkerProviderId;
bool is_controlled_by_service_worker_ = false;
+ // S13nServiceWorker:
+ // Initialized on the worker thread when InitializeOnWorkerThread() is called.
+ mojom::ServiceWorkerContainerHostPtr service_worker_container_host_;
// Initialized on the worker thread when InitializeOnWorkerThread() is called.
std::unique_ptr<ResourceDispatcher> resource_dispatcher_;
+ // Initialized on the worker thread when InitializeOnWorkerThread() is called.
scoped_refptr<ChildURLLoaderFactoryGetter> url_loader_factory_getter_;
+ // S13nServiceWorker:
+ // Initialized on the worker thread when InitializeOnWorkerThread() is called.
+ scoped_refptr<base::RefCountedData<blink::mojom::BlobRegistryPtr>>
+ blob_registry_;
+
// Updated when mojom::ServiceWorkerWorkerClient::SetControllerServiceWorker()
// is called from the browser process via mojo IPC.
- int controller_version_id_ = kInvalidServiceWorkerVersionId;
+ int controller_version_id_ = blink::mojom::kInvalidServiceWorkerVersionId;
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
std::unique_ptr<blink::WebDocumentSubresourceFilter::Builder>
subresource_filter_builder_;
- bool is_data_saver_enabled_ = false;
bool is_on_sub_frame_ = false;
int parent_frame_id_ = MSG_ROUTING_NONE;
GURL site_for_cookies_;
bool is_secure_context_ = false;
+ GURL origin_url_;
int appcache_host_id_ = blink::WebApplicationCacheHost::kAppCacheNoHostId;
+
+ // A weak ptr to blink::WebURLLoaderFactory which was created and passed to
+ // Blink by CreateURLLoaderFactory().
+ base::WeakPtr<URLLoaderFactoryImpl> url_loader_factory_;
};
} // namespace content
diff --git a/chromium/content/renderer/shared_memory_seqlock_reader.cc b/chromium/content/renderer/shared_memory_seqlock_reader.cc
index 894ddbd1cd1..0f06c393127 100644
--- a/chromium/content/renderer/shared_memory_seqlock_reader.cc
+++ b/chromium/content/renderer/shared_memory_seqlock_reader.cc
@@ -16,13 +16,13 @@ SharedMemorySeqLockReaderBase::InitializeSharedMemory(
base::SharedMemoryHandle shared_memory_handle, size_t buffer_size) {
renderer_shared_memory_handle_ = shared_memory_handle;
if (!base::SharedMemory::IsHandleValid(renderer_shared_memory_handle_))
- return 0;
+ return nullptr;
renderer_shared_memory_.reset(new base::SharedMemory(
renderer_shared_memory_handle_, true));
return (renderer_shared_memory_->Map(buffer_size))
- ? renderer_shared_memory_->memory()
- : 0;
+ ? renderer_shared_memory_->memory()
+ : nullptr;
}
bool SharedMemorySeqLockReaderBase::FetchFromBuffer(
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 f3ef68f8657..aaa0525a5b1 100644
--- a/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc
+++ b/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -9,28 +9,30 @@
#include "base/feature_list.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/appcache/appcache_dispatcher.h"
-#include "content/child/appcache/web_application_cache_host_impl.h"
-#include "content/child/request_extra_data.h"
#include "content/child/scoped_child_process_reference.h"
-#include "content/child/service_worker/service_worker_handle_reference.h"
-#include "content/child/service_worker/service_worker_network_provider.h"
-#include "content/child/service_worker/service_worker_provider_context.h"
-#include "content/child/shared_worker_devtools_agent.h"
-#include "content/public/child/child_url_loader_factory_getter.h"
+#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/common/appcache_info.h"
#include "content/public/common/content_features.h"
#include "content/public/common/origin_util.h"
+#include "content/public/renderer/child_url_loader_factory_getter.h"
+#include "content/renderer/appcache/appcache_dispatcher.h"
+#include "content/renderer/appcache/web_application_cache_host_impl.h"
#include "content/renderer/devtools/devtools_agent.h"
+#include "content/renderer/loader/request_extra_data.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/renderer_blink_platform_impl.h"
+#include "content/renderer/service_worker/service_worker_handle_reference.h"
+#include "content/renderer/service_worker/service_worker_network_provider.h"
+#include "content/renderer/service_worker/service_worker_provider_context.h"
#include "content/renderer/service_worker/worker_fetch_context_impl.h"
+#include "content/renderer/shared_worker/shared_worker_devtools_agent.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/WebKit/common/message_port/message_port_channel.h"
#include "third_party/WebKit/public/platform/InterfaceProvider.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h"
+#include "third_party/WebKit/public/platform/modules/serviceworker/service_worker_object.mojom.h"
#include "third_party/WebKit/public/web/WebSharedWorker.h"
#include "third_party/WebKit/public/web/WebSharedWorkerClient.h"
#include "url/origin.h"
@@ -53,8 +55,9 @@ class SharedWorkerWebApplicationCacheHostImpl
// loaded by the worker using WorkerScriptLoader.
// These overrides are stubbed out.
void WillStartMainResourceRequest(
- blink::WebURLRequest&,
- const blink::WebApplicationCacheHost*) override {}
+ const blink::WebURL& url,
+ const blink::WebString& method,
+ const WebApplicationCacheHost* spawning_host) override {}
void DidReceiveResponseForMainResource(
const blink::WebURLResponse&) override {}
void DidReceiveDataForMainResource(const char* data, unsigned len) override {}
@@ -87,7 +90,7 @@ class WebServiceWorkerNetworkProviderForSharedWorker
request.SetExtraData(extra_data.release());
// 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 the ServiceWorkerMode to skip local workers here.
+ // worker, so set the ServiceWorkerMode to skip service workers here.
// Otherwise, a service worker that is in the process of becoming the
// controller (i.e., via claim()) on the browser-side could handle the
// request and break the assumptions of the renderer.
@@ -97,7 +100,7 @@ class WebServiceWorkerNetworkProviderForSharedWorker
request.GetServiceWorkerMode() !=
blink::WebURLRequest::ServiceWorkerMode::kNone) {
request.SetServiceWorkerMode(
- blink::WebURLRequest::ServiceWorkerMode::kForeign);
+ blink::WebURLRequest::ServiceWorkerMode::kNone);
}
}
@@ -108,9 +111,9 @@ class WebServiceWorkerNetworkProviderForSharedWorker
}
int64_t ControllerServiceWorkerID() override {
- if (provider_->context()->controller())
- return provider_->context()->controller()->version_id();
- return kInvalidServiceWorkerVersionId;
+ if (provider_->context())
+ return provider_->context()->GetControllerVersionId();
+ return blink::mojom::kInvalidServiceWorkerVersionId;
}
ServiceWorkerNetworkProvider* provider() { return provider_.get(); }
@@ -128,16 +131,18 @@ class WebServiceWorkerNetworkProviderForSharedWorker
EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
+ const base::UnguessableToken& devtools_worker_token,
int route_id,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::SharedWorkerHostPtr host,
- mojom::SharedWorkerRequest request)
+ mojom::SharedWorkerRequest request,
+ service_manager::mojom::InterfaceProviderPtr interface_provider)
: binding_(this, std::move(request)),
host_(std::move(host)),
route_id_(route_id),
name_(info->name),
url_(info->url) {
- RenderThreadImpl::current()->AddEmbeddedWorkerRoute(route_id_, this);
+ RenderThreadImpl::current()->AddRoute(route_id_, this);
impl_ = blink::WebSharedWorker::Create(this);
if (pause_on_start) {
// Pause worker context when it starts and wait until either DevTools client
@@ -150,7 +155,9 @@ EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
url_, blink::WebString::FromUTF8(name_),
blink::WebString::FromUTF8(info->content_security_policy),
info->content_security_policy_type, info->creation_address_space,
- info->data_saver_enabled, content_settings.PassInterface().PassHandle());
+ blink::WebString::FromUTF8(devtools_worker_token.ToString()),
+ content_settings.PassInterface().PassHandle(),
+ interface_provider.PassInterface().PassHandle());
// If the host drops its connection, then self-destruct.
binding_.set_connection_error_handler(base::BindOnce(
@@ -158,7 +165,7 @@ EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
}
EmbeddedSharedWorkerStub::~EmbeddedSharedWorkerStub() {
- RenderThreadImpl::current()->RemoveEmbeddedWorkerRoute(route_id_);
+ RenderThreadImpl::current()->RemoveRoute(route_id_);
DCHECK(!impl_);
}
@@ -215,14 +222,14 @@ blink::WebNotificationPresenter*
EmbeddedSharedWorkerStub::NotificationPresenter() {
// TODO(horo): delete this method if we have no plan to implement this.
NOTREACHED();
- return NULL;
+ return nullptr;
}
std::unique_ptr<blink::WebApplicationCacheHost>
EmbeddedSharedWorkerStub::CreateApplicationCacheHost(
blink::WebApplicationCacheHostClient* client) {
std::unique_ptr<WebApplicationCacheHostImpl> host =
- base::MakeUnique<SharedWorkerWebApplicationCacheHostImpl>(client);
+ std::make_unique<SharedWorkerWebApplicationCacheHostImpl>(client);
app_cache_host_ = host.get();
return std::move(host);
}
@@ -235,7 +242,7 @@ EmbeddedSharedWorkerStub::CreateServiceWorkerNetworkProvider() {
ServiceWorkerNetworkProvider::CreateForSharedWorker(route_id_));
// Blink is responsible for deleting the returned object.
- return base::MakeUnique<WebServiceWorkerNetworkProviderForSharedWorker>(
+ return std::make_unique<WebServiceWorkerNetworkProviderForSharedWorker>(
std::move(provider), IsOriginSecure(url_));
}
@@ -258,20 +265,31 @@ EmbeddedSharedWorkerStub::CreateWorkerFetchContext(
blink::WebServiceWorkerNetworkProvider* web_network_provider) {
DCHECK(base::FeatureList::IsEnabled(features::kOffMainThreadFetch));
DCHECK(web_network_provider);
- mojom::ServiceWorkerWorkerClientRequest request =
+ ServiceWorkerProviderContext* context =
static_cast<WebServiceWorkerNetworkProviderForSharedWorker*>(
web_network_provider)
->provider()
- ->context()
- ->CreateWorkerClientRequest();
+ ->context();
+ mojom::ServiceWorkerWorkerClientRequest request =
+ context->CreateWorkerClientRequest();
+
+ mojom::ServiceWorkerContainerHostPtrInfo container_host_ptr_info;
+ // TODO(horo): Use this host pointer also when S13nServiceWorker is not
+ // enabled once we support navigator.serviceWorker on shared workers:
+ // crbug.com/371690. Currently we use this only to call
+ // GetControllerServiceWorker() from the worker thread if S13nServiceWorker
+ // is enabled.
+ if (ServiceWorkerUtils::IsServicificationEnabled())
+ container_host_ptr_info = context->CloneContainerHostPtrInfo();
scoped_refptr<ChildURLLoaderFactoryGetter> url_loader_factory_getter =
RenderThreadImpl::current()
->blink_platform_impl()
->CreateDefaultURLLoaderFactoryGetter();
DCHECK(url_loader_factory_getter);
- auto worker_fetch_context = base::MakeUnique<WorkerFetchContextImpl>(
- std::move(request), url_loader_factory_getter->GetClonedInfo());
+ auto worker_fetch_context = std::make_unique<WorkerFetchContextImpl>(
+ std::move(request), std::move(container_host_ptr_info),
+ url_loader_factory_getter->GetClonedInfo());
// TODO(horo): To get the correct first_party_to_cookies for the shared
// worker, we need to check the all documents bounded by the shared worker.
@@ -284,6 +302,7 @@ EmbeddedSharedWorkerStub::CreateWorkerFetchContext(
// non-secure. crbug.com/723575
// https://w3c.github.io/webappsec-secure-contexts/#examples-shared-workers
worker_fetch_context->set_is_secure_context(IsOriginSecure(url_));
+ worker_fetch_context->set_origin_url(url_.GetOrigin());
if (web_network_provider) {
worker_fetch_context->set_service_worker_provider_id(
web_network_provider->ProviderID());
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 9e62a82c8fe..8a212de5443 100644
--- a/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h
+++ b/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h
@@ -9,13 +9,15 @@
#include <vector>
#include "base/macros.h"
-#include "content/child/child_message_filter.h"
+#include "base/unguessable_token.h"
#include "content/child/scoped_child_process_reference.h"
#include "content/common/shared_worker/shared_worker.mojom.h"
#include "content/common/shared_worker/shared_worker_host.mojom.h"
#include "content/common/shared_worker/shared_worker_info.mojom.h"
+#include "content/renderer/child_message_filter.h"
#include "ipc/ipc_listener.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
#include "third_party/WebKit/public/platform/WebAddressSpace.h"
#include "third_party/WebKit/public/platform/WebContentSecurityPolicy.h"
#include "third_party/WebKit/public/platform/WebContentSettingsClient.h"
@@ -56,10 +58,12 @@ class EmbeddedSharedWorkerStub : public IPC::Listener,
EmbeddedSharedWorkerStub(
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
+ const base::UnguessableToken& devtools_worker_token,
int route_id,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::SharedWorkerHostPtr host,
- mojom::SharedWorkerRequest request);
+ mojom::SharedWorkerRequest request,
+ service_manager::mojom::InterfaceProviderPtr interface_provider);
~EmbeddedSharedWorkerStub() override;
// IPC::Listener implementation.
diff --git a/chromium/content/child/shared_worker_devtools_agent.cc b/chromium/content/renderer/shared_worker/shared_worker_devtools_agent.cc
index 89ddbd8c49e..73525e6b4fa 100644
--- a/chromium/content/child/shared_worker_devtools_agent.cc
+++ b/chromium/content/renderer/shared_worker/shared_worker_devtools_agent.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/child/shared_worker_devtools_agent.h"
+#include "content/renderer/shared_worker/shared_worker_devtools_agent.h"
#include <stddef.h>
@@ -79,16 +79,13 @@ void SharedWorkerDevToolsAgent::SendDevToolsMessage(
}
}
-void SharedWorkerDevToolsAgent::OnAttach(const std::string& host_id,
- int session_id) {
- webworker_->AttachDevTools(WebString::FromUTF8(host_id), session_id);
+void SharedWorkerDevToolsAgent::OnAttach(int session_id) {
+ webworker_->AttachDevTools(session_id);
}
-void SharedWorkerDevToolsAgent::OnReattach(const std::string& host_id,
- int session_id,
+void SharedWorkerDevToolsAgent::OnReattach(int session_id,
const std::string& state) {
- webworker_->ReattachDevTools(WebString::FromUTF8(host_id), session_id,
- WebString::FromUTF8(state));
+ webworker_->ReattachDevTools(session_id, WebString::FromUTF8(state));
}
void SharedWorkerDevToolsAgent::OnDetach(int session_id) {
diff --git a/chromium/content/child/shared_worker_devtools_agent.h b/chromium/content/renderer/shared_worker/shared_worker_devtools_agent.h
index 9059277d8f9..c44d4933642 100644
--- a/chromium/content/child/shared_worker_devtools_agent.h
+++ b/chromium/content/renderer/shared_worker/shared_worker_devtools_agent.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_CHILD_SHARED_WORKER_DEVTOOLS_AGENT_H_
-#define CONTENT_CHILD_SHARED_WORKER_DEVTOOLS_AGENT_H_
+#ifndef CONTENT_RENDERER_SHARED_WORKER_DEVTOOLS_AGENT_H_
+#define CONTENT_RENDERER_SHARED_WORKER_DEVTOOLS_AGENT_H_
#include <string>
@@ -33,10 +33,8 @@ class SharedWorkerDevToolsAgent {
const blink::WebString& post_state);
private:
- void OnAttach(const std::string& host_id, int session_id);
- void OnReattach(const std::string& host_id,
- int session_id,
- const std::string& state);
+ void OnAttach(int session_id);
+ void OnReattach(int session_id, const std::string& state);
void OnDetach(int session_id);
void OnDispatchOnInspectorBackend(
int session_id,
@@ -53,4 +51,4 @@ class SharedWorkerDevToolsAgent {
} // namespace content
-#endif // CONTENT_CHILD_SHARED_WORKER_DEVTOOLS_AGENT_H_
+#endif // CONTENT_RENDERER_SHARED_WORKER_DEVTOOLS_AGENT_H_
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 1f874c31b28..a80a140142f 100644
--- a/chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc
+++ b/chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc
@@ -22,14 +22,17 @@ SharedWorkerFactoryImpl::SharedWorkerFactoryImpl() {}
void SharedWorkerFactoryImpl::CreateSharedWorker(
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
+ const base::UnguessableToken& devtools_worker_token,
int32_t route_id,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::SharedWorkerHostPtr host,
- mojom::SharedWorkerRequest request) {
+ mojom::SharedWorkerRequest request,
+ service_manager::mojom::InterfaceProviderPtr interface_provider) {
// Bound to the lifetime of the underlying blink::WebSharedWorker instance.
- new EmbeddedSharedWorkerStub(std::move(info), pause_on_start, route_id,
- std::move(content_settings), std::move(host),
- std::move(request));
+ new EmbeddedSharedWorkerStub(
+ std::move(info), pause_on_start, devtools_worker_token, route_id,
+ std::move(content_settings), 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 8cf765d69dd..314579fc784 100644
--- a/chromium/content/renderer/shared_worker/shared_worker_factory_impl.h
+++ b/chromium/content/renderer/shared_worker/shared_worker_factory_impl.h
@@ -21,10 +21,12 @@ class SharedWorkerFactoryImpl : public mojom::SharedWorkerFactory {
void CreateSharedWorker(
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
+ const base::UnguessableToken& devtools_worker_token,
int32_t route_id,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::SharedWorkerHostPtr host,
- mojom::SharedWorkerRequest request) override;
+ mojom::SharedWorkerRequest request,
+ service_manager::mojom::InterfaceProviderPtr interface_provider) override;
DISALLOW_COPY_AND_ASSIGN(SharedWorkerFactoryImpl);
};
diff --git a/chromium/content/renderer/shared_worker/shared_worker_repository.cc b/chromium/content/renderer/shared_worker/shared_worker_repository.cc
index 1a78dbe8e1a..5b3eef8f593 100644
--- a/chromium/content/renderer/shared_worker/shared_worker_repository.cc
+++ b/chromium/content/renderer/shared_worker/shared_worker_repository.cc
@@ -25,7 +25,6 @@ void SharedWorkerRepository::Connect(
blink::WebContentSecurityPolicyType content_security_policy_type,
blink::WebAddressSpace creation_address_space,
blink::mojom::SharedWorkerCreationContextType creation_context_type,
- bool data_saver_enabled,
blink::MessagePortChannel channel,
std::unique_ptr<blink::WebSharedWorkerConnectListener> listener) {
// Lazy bind the connector.
@@ -34,8 +33,7 @@ void SharedWorkerRepository::Connect(
mojom::SharedWorkerInfoPtr info(mojom::SharedWorkerInfo::New(
url, name.Utf8(), content_security_policy.Utf8(),
- content_security_policy_type, creation_address_space,
- data_saver_enabled));
+ content_security_policy_type, creation_address_space));
mojom::SharedWorkerClientPtr client;
AddWorker(document_id,
diff --git a/chromium/content/renderer/shared_worker/shared_worker_repository.h b/chromium/content/renderer/shared_worker/shared_worker_repository.h
index f736c5e9ba7..cedec5a27e4 100644
--- a/chromium/content/renderer/shared_worker/shared_worker_repository.h
+++ b/chromium/content/renderer/shared_worker/shared_worker_repository.h
@@ -43,7 +43,6 @@ class SharedWorkerRepository final
blink::WebContentSecurityPolicyType,
blink::WebAddressSpace,
blink::mojom::SharedWorkerCreationContextType,
- bool data_saver_enabled,
blink::MessagePortChannel channel,
std::unique_ptr<blink::WebSharedWorkerConnectListener> listener) override;
void DocumentDetached(DocumentID document_id) override;
diff --git a/chromium/content/renderer/skia_benchmarking_extension.cc b/chromium/content/renderer/skia_benchmarking_extension.cc
index db82d966f5c..eeb18e53d68 100644
--- a/chromium/content/renderer/skia_benchmarking_extension.cc
+++ b/chromium/content/renderer/skia_benchmarking_extension.cc
@@ -11,8 +11,8 @@
#include "base/time/time.h"
#include "base/values.h"
#include "cc/base/math_util.h"
-#include "content/public/child/v8_value_converter.h"
#include "content/public/renderer/chrome_object_extensions_utils.h"
+#include "content/public/renderer/v8_value_converter.h"
#include "content/renderer/render_thread_impl.h"
#include "gin/arguments.h"
#include "gin/data_object_builder.h"
@@ -210,12 +210,12 @@ void SkiaBenchmarking::Rasterize(gin::Arguments* args) {
std::unique_ptr<base::Value> params_value =
content::V8ValueConverter::Create()->FromV8Value(params, context);
- const base::DictionaryValue* params_dict = NULL;
+ const base::DictionaryValue* params_dict = nullptr;
if (params_value.get() && params_value->GetAsDictionary(&params_dict)) {
params_dict->GetDouble("scale", &scale);
params_dict->GetInteger("stop", &stop_index);
- const base::Value* clip_value = NULL;
+ const base::Value* clip_value = nullptr;
if (params_dict->Get("clip", &clip_value))
cc::MathUtil::FromValue(clip_value, &clip_rect);
}
diff --git a/chromium/content/renderer/speech_recognition_dispatcher.cc b/chromium/content/renderer/speech_recognition_dispatcher.cc
index c846d6d0335..79f082961ae 100644
--- a/chromium/content/renderer/speech_recognition_dispatcher.cc
+++ b/chromium/content/renderer/speech_recognition_dispatcher.cc
@@ -11,7 +11,6 @@
#include "base/strings/utf_string_conversions.h"
#include "content/common/speech_recognition_messages.h"
#include "content/renderer/render_view_impl.h"
-#include "media/media_features.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/web/WebSpeechGrammar.h"
@@ -19,10 +18,6 @@
#include "third_party/WebKit/public/web/WebSpeechRecognitionResult.h"
#include "third_party/WebKit/public/web/WebSpeechRecognizerClient.h"
-#if BUILDFLAG(ENABLE_WEBRTC)
-#include "content/renderer/media/speech_recognition_audio_sink.h"
-#endif
-
using blink::WebVector;
using blink::WebString;
using blink::WebSpeechGrammar;
@@ -36,13 +31,12 @@ namespace content {
SpeechRecognitionDispatcher::SpeechRecognitionDispatcher(
RenderViewImpl* render_view)
: RenderViewObserver(render_view),
- recognizer_client_(NULL),
+ recognizer_client_(nullptr),
next_id_(1) {}
SpeechRecognitionDispatcher::~SpeechRecognitionDispatcher() {}
void SpeechRecognitionDispatcher::AbortAllRecognitions() {
- ResetAudioSink();
Send(new SpeechRecognitionHostMsg_AbortAllRequests(
routing_id()));
}
@@ -60,8 +54,6 @@ bool SpeechRecognitionDispatcher::OnMessageReceived(
IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_Ended, OnRecognitionEnded)
IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_ResultRetrieved,
OnResultsRetrieved)
- IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_AudioReceiverReady,
- OnAudioReceiverReady)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -78,28 +70,6 @@ void SpeechRecognitionDispatcher::Start(
DCHECK(!recognizer_client_ || recognizer_client_ == recognizer_client);
recognizer_client_ = recognizer_client;
-#if BUILDFLAG(ENABLE_WEBRTC)
- const blink::WebMediaStreamTrack track = params.AudioTrack();
- if (!track.IsNull()) {
- // Check if this type of track is allowed by implemented policy.
- if (SpeechRecognitionAudioSink::IsSupportedTrack(track)) {
- audio_track_.Assign(track);
- } else {
- audio_track_.Reset();
- // Notify user that the track used is not supported.
- recognizer_client_->DidReceiveError(
- handle, WebString("Provided audioTrack is not supported."),
- WebSpeechRecognizerClient::kAudioCaptureError);
-
- return;
- }
- }
-
- // Destroy any previous instance to detach from the audio track.
- // Each new session should reinstantiate the provider once the track is ready.
- ResetAudioSink();
-#endif
-
SpeechRecognitionHostMsg_StartRequest_Params msg_params;
for (size_t i = 0; i < params.Grammars().size(); ++i) {
const WebSpeechGrammar& grammar = params.Grammars()[i];
@@ -113,12 +83,7 @@ void SpeechRecognitionDispatcher::Start(
msg_params.origin_url = params.Origin().ToString().Utf8();
msg_params.render_view_id = routing_id();
msg_params.request_id = GetOrCreateIDForHandle(handle);
-#if BUILDFLAG(ENABLE_WEBRTC)
- // Fall back to default input when the track is not allowed.
- msg_params.using_audio_track = !audio_track_.IsNull();
-#else
- msg_params.using_audio_track = false;
-#endif
+
// The handle mapping will be removed in |OnRecognitionEnd|.
Send(new SpeechRecognitionHostMsg_StartRequest(msg_params));
}
@@ -126,7 +91,6 @@ void SpeechRecognitionDispatcher::Start(
void SpeechRecognitionDispatcher::Stop(
const WebSpeechRecognitionHandle& handle,
WebSpeechRecognizerClient* recognizer_client) {
- ResetAudioSink();
// Ignore a |stop| issued without a matching |start|.
if (recognizer_client_ != recognizer_client || !HandleExists(handle))
return;
@@ -137,7 +101,6 @@ void SpeechRecognitionDispatcher::Stop(
void SpeechRecognitionDispatcher::Abort(
const WebSpeechRecognitionHandle& handle,
WebSpeechRecognizerClient* recognizer_client) {
- ResetAudioSink();
// Ignore an |abort| issued without a matching |start|.
if (recognizer_client_ != recognizer_client || !HandleExists(handle))
return;
@@ -201,7 +164,6 @@ void SpeechRecognitionDispatcher::OnErrorOccurred(
recognizer_client_->DidReceiveNoMatch(GetHandleFromID(request_id),
WebSpeechRecognitionResult());
} else {
- ResetAudioSink();
recognizer_client_->DidReceiveError(
GetHandleFromID(request_id),
WebString(), // TODO(primiano): message?
@@ -222,7 +184,6 @@ void SpeechRecognitionDispatcher::OnRecognitionEnded(int request_id) {
// didEnd may call back synchronously to start a new recognition session,
// and we don't want to delete the handle from the map after that happens.
handle_map_.erase(request_id);
- ResetAudioSink();
recognizer_client_->DidEnd(handle);
}
}
@@ -260,30 +221,6 @@ void SpeechRecognitionDispatcher::OnResultsRetrieved(
provisional);
}
-void SpeechRecognitionDispatcher::OnAudioReceiverReady(
- int request_id,
- const media::AudioParameters& params,
- const base::SharedMemoryHandle memory,
- const base::SyncSocket::TransitDescriptor descriptor) {
-#if BUILDFLAG(ENABLE_WEBRTC)
- DCHECK(!speech_audio_sink_.get());
- if (audio_track_.IsNull()) {
- ResetAudioSink();
- return;
- }
-
- // The instantiation and type of SyncSocket is up to the client since it
- // is dependency injected to the SpeechRecognitionAudioSink.
- std::unique_ptr<base::SyncSocket> socket(new base::CancelableSyncSocket(
- base::SyncSocket::UnwrapHandle(descriptor)));
-
- speech_audio_sink_.reset(new SpeechRecognitionAudioSink(
- audio_track_, params, memory, std::move(socket),
- base::Bind(&SpeechRecognitionDispatcher::ResetAudioSink,
- base::Unretained(this))));
-#endif
-}
-
int SpeechRecognitionDispatcher::GetOrCreateIDForHandle(
const WebSpeechRecognitionHandle& handle) {
// Search first for an existing mapping.
@@ -311,12 +248,6 @@ bool SpeechRecognitionDispatcher::HandleExists(
return false;
}
-void SpeechRecognitionDispatcher::ResetAudioSink() {
-#if BUILDFLAG(ENABLE_WEBRTC)
- speech_audio_sink_.reset();
-#endif
-}
-
const WebSpeechRecognitionHandle& SpeechRecognitionDispatcher::GetHandleFromID(
int request_id) {
HandleMap::iterator iter = handle_map_.find(request_id);
diff --git a/chromium/content/renderer/speech_recognition_dispatcher.h b/chromium/content/renderer/speech_recognition_dispatcher.h
index b9348ba45b0..ea0ecf728c2 100644
--- a/chromium/content/renderer/speech_recognition_dispatcher.h
+++ b/chromium/content/renderer/speech_recognition_dispatcher.h
@@ -9,25 +9,13 @@
#include <memory>
#include "base/macros.h"
-#include "base/memory/shared_memory.h"
-#include "base/sync_socket.h"
#include "content/public/common/speech_recognition_result.h"
#include "content/public/renderer/render_view_observer.h"
-#include "media/media_features.h"
-#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
-#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/web/WebSpeechRecognitionHandle.h"
#include "third_party/WebKit/public/web/WebSpeechRecognizer.h"
-namespace media {
-class AudioParameters;
-}
-
namespace content {
class RenderViewImpl;
-#if BUILDFLAG(ENABLE_WEBRTC)
-class SpeechRecognitionAudioSink;
-#endif
struct SpeechRecognitionError;
// SpeechRecognitionDispatcher is a delegate for methods used by WebKit for
@@ -65,12 +53,6 @@ class SpeechRecognitionDispatcher : public RenderViewObserver,
void OnRecognitionEnded(int request_id);
void OnResultsRetrieved(int request_id,
const SpeechRecognitionResults& result);
- void OnAudioReceiverReady(int session_id,
- const media::AudioParameters& params,
- const base::SharedMemoryHandle handle,
- const base::SyncSocket::TransitDescriptor socket);
-
- void ResetAudioSink();
int GetOrCreateIDForHandle(const blink::WebSpeechRecognitionHandle& handle);
bool HandleExists(const blink::WebSpeechRecognitionHandle& handle);
@@ -79,15 +61,6 @@ class SpeechRecognitionDispatcher : public RenderViewObserver,
// The WebKit client class that we use to send events back to the JS world.
blink::WebSpeechRecognizerClient* recognizer_client_;
-#if BUILDFLAG(ENABLE_WEBRTC)
- // Media stream audio track that the speech recognition connects to.
- // Accessed on the render thread.
- blink::WebMediaStreamTrack audio_track_;
-
- // Audio sink used to provide audio from the track.
- std::unique_ptr<SpeechRecognitionAudioSink> speech_audio_sink_;
-#endif
-
typedef std::map<int, blink::WebSpeechRecognitionHandle> HandleMap;
HandleMap handle_map_;
int next_id_;
diff --git a/chromium/content/renderer/stats_collection_controller.cc b/chromium/content/renderer/stats_collection_controller.cc
index 16eb0f83a70..ed3fc2e039f 100644
--- a/chromium/content/renderer/stats_collection_controller.cc
+++ b/chromium/content/renderer/stats_collection_controller.cc
@@ -6,13 +6,17 @@
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/statistics_recorder.h"
#include "base/strings/string_util.h"
-#include "content/common/child_process_messages.h"
+#include "content/common/renderer_host.mojom.h"
+#include "content/public/common/service_names.mojom.h"
+#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
@@ -56,13 +60,13 @@ void ConvertLoadTimeToJSON(
base::DictionaryValue item;
if (load_start_time.is_null()) {
- item.Set("load_start_ms", base::MakeUnique<base::Value>());
+ 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", base::MakeUnique<base::Value>());
+ item.Set("load_duration_ms", std::make_unique<base::Value>());
} else {
item.SetDouble("load_duration_ms",
(load_stop_time - load_start_time).InMillisecondsF());
@@ -118,38 +122,28 @@ std::string StatsCollectionController::GetHistogram(
if (!histogram) {
output = "{}";
} else {
- histogram->WriteJSON(&output);
+ histogram->WriteJSON(&output, base::JSON_VERBOSITY_LEVEL_FULL);
}
return output;
}
std::string StatsCollectionController::GetBrowserHistogram(
const std::string& histogram_name) {
- RenderViewImpl *render_view_impl = NULL;
- if (!CurrentRenderViewImpl(&render_view_impl)) {
- NOTREACHED();
- return std::string();
- }
-
std::string histogram_json;
- render_view_impl->Send(new ChildProcessHostMsg_GetBrowserHistogram(
- histogram_name, &histogram_json));
+ RenderThreadImpl::current()->GetRendererHost()->GetBrowserHistogram(
+ histogram_name, &histogram_json);
+
return histogram_json;
}
std::string StatsCollectionController::GetTabLoadTiming() {
- RenderViewImpl *render_view_impl = NULL;
- if (!CurrentRenderViewImpl(&render_view_impl)) {
- NOTREACHED();
- return std::string();
- }
+ RenderViewImpl* render_view_impl = nullptr;
+ bool result = CurrentRenderViewImpl(&render_view_impl);
+ DCHECK(result);
StatsCollectionObserver* observer =
render_view_impl->GetStatsCollectionObserver();
- if (!observer) {
- NOTREACHED();
- return std::string();
- }
+ DCHECK(observer);
std::string tab_timing_json;
ConvertLoadTimeToJSON(
diff --git a/chromium/content/child/storage_util.cc b/chromium/content/renderer/storage_util.cc
index a613b957315..91f94d05b9e 100644
--- a/chromium/content/child/storage_util.cc
+++ b/chromium/content/renderer/storage_util.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/child/storage_util.h"
+#include "content/renderer/storage_util.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
diff --git a/chromium/content/child/storage_util.h b/chromium/content/renderer/storage_util.h
index e6f51a90c08..451550cdec5 100644
--- a/chromium/content/child/storage_util.h
+++ b/chromium/content/renderer/storage_util.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_CHILD_STORAGE_UTIL_H_
-#define CONTENT_CHILD_STORAGE_UTIL_H_
+#ifndef CONTENT_RENDERER_STORAGE_UTIL_H_
+#define CONTENT_RENDERER_STORAGE_UTIL_H_
class GURL;
@@ -21,4 +21,4 @@ GURL WebSecurityOriginToGURL(const blink::WebSecurityOrigin& origin);
} // namespace content
-#endif // CONTENT_CHILD_STORAGE_UTIL_H_
+#endif // CONTENT_RENDERER_STORAGE_UTIL_H_
diff --git a/chromium/content/child/v8_value_converter_impl.cc b/chromium/content/renderer/v8_value_converter_impl.cc
index d7939d25ba0..a80d2de8fa5 100644
--- a/chromium/content/child/v8_value_converter_impl.cc
+++ b/chromium/content/renderer/v8_value_converter_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/v8_value_converter_impl.h"
+#include "content/renderer/v8_value_converter_impl.h"
#include <stddef.h>
#include <stdint.h>
@@ -176,7 +176,7 @@ class V8ValueConverterImpl::ScopedUniquenessGuard {
};
std::unique_ptr<V8ValueConverter> V8ValueConverter::Create() {
- return base::MakeUnique<V8ValueConverterImpl>();
+ return std::make_unique<V8ValueConverterImpl>();
}
V8ValueConverterImpl::V8ValueConverterImpl()
@@ -186,7 +186,7 @@ V8ValueConverterImpl::V8ValueConverterImpl()
strip_null_from_objects_(false),
convert_negative_zero_to_int_(false),
avoid_identity_hash_for_testing_(false),
- strategy_(NULL) {}
+ strategy_(nullptr) {}
void V8ValueConverterImpl::SetDateAllowed(bool val) {
date_allowed_ = val;
@@ -292,7 +292,7 @@ v8::Local<v8::Value> V8ValueConverterImpl::ToV8Array(
v8::Local<v8::Context> context = isolate->GetCurrentContext();
for (size_t i = 0; i < val->GetSize(); ++i) {
- const base::Value* child = NULL;
+ const base::Value* child = nullptr;
CHECK(val->Get(i, &child));
v8::Local<v8::Value> child_v8 =
@@ -359,10 +359,10 @@ std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8ValueImpl(
return nullptr;
if (val->IsNull())
- return base::MakeUnique<base::Value>();
+ return std::make_unique<base::Value>();
if (val->IsBoolean())
- return base::MakeUnique<base::Value>(val->ToBoolean(isolate)->Value());
+ return std::make_unique<base::Value>(val->ToBoolean(isolate)->Value());
if (val->IsNumber() && strategy_) {
std::unique_ptr<base::Value> out;
@@ -371,7 +371,7 @@ std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8ValueImpl(
}
if (val->IsInt32())
- return base::MakeUnique<base::Value>(val->ToInt32(isolate)->Value());
+ return std::make_unique<base::Value>(val->ToInt32(isolate)->Value());
if (val->IsNumber()) {
double val_as_double = val.As<v8::Number>()->Value();
@@ -381,13 +381,13 @@ std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8ValueImpl(
// value is -0, it's treated internally as a double. Consumers are allowed
// to ignore this esoterica and treat it as an integer.
if (convert_negative_zero_to_int_ && val_as_double == 0.0)
- return base::MakeUnique<base::Value>(0);
- return base::MakeUnique<base::Value>(val_as_double);
+ return std::make_unique<base::Value>(0);
+ return std::make_unique<base::Value>(val_as_double);
}
if (val->IsString()) {
v8::String::Utf8Value utf8(val);
- return base::MakeUnique<base::Value>(std::string(*utf8, utf8.length()));
+ return std::make_unique<base::Value>(std::string(*utf8, utf8.length()));
}
if (val->IsUndefined()) {
@@ -406,14 +406,14 @@ std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8ValueImpl(
// consistent within this class.
return FromV8Object(val->ToObject(isolate), state, isolate);
v8::Date* date = v8::Date::Cast(*val);
- return base::MakeUnique<base::Value>(date->ValueOf() / 1000.0);
+ return std::make_unique<base::Value>(date->ValueOf() / 1000.0);
}
if (val->IsRegExp()) {
if (!reg_exp_allowed_)
// JSON.stringify converts to an object.
return FromV8Object(val.As<v8::Object>(), state, isolate);
- return base::MakeUnique<base::Value>(*v8::String::Utf8Value(val));
+ return std::make_unique<base::Value>(*v8::String::Utf8Value(val));
}
// v8::Value doesn't have a ToArray() method for some reason.
@@ -443,7 +443,7 @@ std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8Array(
v8::Isolate* isolate) const {
ScopedUniquenessGuard uniqueness_guard(state, val);
if (!uniqueness_guard.is_valid())
- return base::MakeUnique<base::Value>();
+ return std::make_unique<base::Value>();
std::unique_ptr<v8::Context::Scope> scope;
// If val was created in a different context than our current one, change to
@@ -476,7 +476,7 @@ std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8Array(
}
if (!val->HasRealIndexedProperty(i)) {
- result->Append(base::MakeUnique<base::Value>());
+ result->Append(std::make_unique<base::Value>());
continue;
}
@@ -487,7 +487,7 @@ std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8Array(
else
// JSON.stringify puts null in places where values don't serialize, for
// example undefined and functions. Emulate that behavior.
- result->Append(base::MakeUnique<base::Value>());
+ result->Append(std::make_unique<base::Value>());
}
return std::move(result);
}
@@ -510,7 +510,7 @@ std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8ArrayBuffer(
size_t byte_length = view->ByteLength();
std::vector<char> buffer(byte_length);
view->CopyContents(buffer.data(), buffer.size());
- return base::MakeUnique<base::Value>(std::move(buffer));
+ return std::make_unique<base::Value>(std::move(buffer));
} else {
NOTREACHED() << "Only ArrayBuffer and ArrayBufferView should get here.";
return nullptr;
@@ -523,7 +523,7 @@ std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8Object(
v8::Isolate* isolate) const {
ScopedUniquenessGuard uniqueness_guard(state, val);
if (!uniqueness_guard.is_valid())
- return base::MakeUnique<base::Value>();
+ return std::make_unique<base::Value>();
std::unique_ptr<v8::Context::Scope> scope;
// If val was created in a different context than our current one, change to
@@ -558,7 +558,7 @@ std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8Object(
// ANOTHER NOTE: returning an empty dictionary here to minimise surprise.
// See also http://crbug.com/330559.
if (val->InternalFieldCount())
- return base::MakeUnique<base::DictionaryValue>();
+ return std::make_unique<base::DictionaryValue>();
std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
v8::Local<v8::Array> property_names(val->GetOwnPropertyNames());
diff --git a/chromium/content/child/v8_value_converter_impl.h b/chromium/content/renderer/v8_value_converter_impl.h
index ce80a71a179..16d19a5f410 100644
--- a/chromium/content/child/v8_value_converter_impl.h
+++ b/chromium/content/renderer/v8_value_converter_impl.h
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_V8_VALUE_CONVERTER_IMPL_H_
-#define CONTENT_CHILD_V8_VALUE_CONVERTER_IMPL_H_
+#ifndef CONTENT_RENDERER_V8_VALUE_CONVERTER_IMPL_H_
+#define CONTENT_RENDERER_V8_VALUE_CONVERTER_IMPL_H_
#include <map>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "content/common/content_export.h"
-#include "content/public/child/v8_value_converter.h"
+#include "content/public/renderer/v8_value_converter.h"
namespace base {
class DictionaryValue;
@@ -100,4 +100,4 @@ class CONTENT_EXPORT V8ValueConverterImpl : public V8ValueConverter {
} // namespace content
-#endif // CONTENT_CHILD_V8_VALUE_CONVERTER_IMPL_H_
+#endif // CONTENT_RENDERER_V8_VALUE_CONVERTER_IMPL_H_
diff --git a/chromium/content/child/v8_value_converter_impl_unittest.cc b/chromium/content/renderer/v8_value_converter_impl_unittest.cc
index e27178dc847..b1cedffaed9 100644
--- a/chromium/content/child/v8_value_converter_impl_unittest.cc
+++ b/chromium/content/renderer/v8_value_converter_impl_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/v8_value_converter_impl.h"
+#include "content/renderer/v8_value_converter_impl.h"
#include <stddef.h>
#include <stdint.h>
@@ -61,7 +61,7 @@ class V8ValueConverterImplTest : public testing::Test {
void SetUp() override {
v8::HandleScope handle_scope(isolate_);
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_);
- context_.Reset(isolate_, v8::Context::New(isolate_, NULL, global));
+ context_.Reset(isolate_, v8::Context::New(isolate_, nullptr, global));
}
void TearDown() override { context_.Reset(); }
@@ -127,7 +127,7 @@ class V8ValueConverterImplTest : public testing::Test {
}
bool IsNull(base::DictionaryValue* value, const std::string& key) {
- base::Value* child = NULL;
+ base::Value* child = nullptr;
if (!value->Get(key, &child)) {
ADD_FAILURE();
return false;
@@ -146,7 +146,7 @@ class V8ValueConverterImplTest : public testing::Test {
}
bool IsNull(base::ListValue* value, uint32_t index) {
- base::Value* child = NULL;
+ base::Value* child = nullptr;
if (!value->Get(static_cast<size_t>(index), &child)) {
ADD_FAILURE();
return false;
@@ -186,7 +186,7 @@ class V8ValueConverterImplTest : public testing::Test {
ASSERT_TRUE(dictionary.get());
if (expected_value) {
- base::Value* temp = NULL;
+ base::Value* temp = nullptr;
ASSERT_TRUE(dictionary->Get("test", &temp));
EXPECT_EQ(expected_type, temp->type());
EXPECT_TRUE(expected_value->Equals(temp));
@@ -200,14 +200,14 @@ class V8ValueConverterImplTest : public testing::Test {
base::ListValue::From(converter.FromV8Value(array, context)));
ASSERT_TRUE(list.get());
if (expected_value) {
- base::Value* temp = NULL;
+ base::Value* temp = nullptr;
ASSERT_TRUE(list->Get(0, &temp));
EXPECT_EQ(expected_type, temp->type());
EXPECT_TRUE(expected_value->Equals(temp));
} else {
// Arrays should preserve their length, and convert unconvertible
// types into null.
- base::Value* temp = NULL;
+ base::Value* temp = nullptr;
ASSERT_TRUE(list->Get(0, &temp));
EXPECT_EQ(base::Value::Type::NONE, temp->type());
}
@@ -814,7 +814,7 @@ TEST_F(V8ValueConverterImplTest, DetectCycles) {
// The first repetition should be trimmed and replaced by a null value.
base::ListValue expected_list;
- expected_list.Append(base::MakeUnique<base::Value>());
+ expected_list.Append(std::make_unique<base::Value>());
// The actual result.
std::unique_ptr<base::Value> actual_list(
@@ -835,7 +835,7 @@ TEST_F(V8ValueConverterImplTest, DetectCycles) {
// The first repetition should be trimmed and replaced by a null value.
base::DictionaryValue expected_dictionary;
- expected_dictionary.Set(key, base::MakeUnique<base::Value>());
+ expected_dictionary.Set(key, std::make_unique<base::Value>());
// The actual result.
std::unique_ptr<base::Value> actual_dictionary(
@@ -942,7 +942,7 @@ TEST_F(V8ValueConverterImplTest, MaxRecursionDepth) {
base::Value* current = value.get();
for (int i = 1; i < kExpectedDepth; ++i) {
- base::DictionaryValue* current_as_object = NULL;
+ base::DictionaryValue* current_as_object = nullptr;
ASSERT_TRUE(current->GetAsDictionary(&current_as_object)) << i;
ASSERT_TRUE(current_as_object->Get(kKey, &current)) << i;
}
@@ -1021,7 +1021,7 @@ class V8ValueConverterOverridingStrategyForTesting
private:
static std::unique_ptr<base::Value> NewReferenceValue() {
- return base::MakeUnique<base::Value>("strategy");
+ return std::make_unique<base::Value>("strategy");
}
std::unique_ptr<base::Value> reference_value_;
};
diff --git a/chromium/content/child/web_database_observer_impl.cc b/chromium/content/renderer/web_database_observer_impl.cc
index 80aaf519898..7359e3ce717 100644
--- a/chromium/content/child/web_database_observer_impl.cc
+++ b/chromium/content/renderer/web_database_observer_impl.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/child/web_database_observer_impl.h"
+#include "content/renderer/web_database_observer_impl.h"
#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string16.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/storage_util.h"
+#include "content/renderer/storage_util.h"
#include "storage/common/database/database_identifier.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/WebString.h"
@@ -65,7 +65,7 @@ std::string GetIdentifierFromOrigin(const WebSecurityOrigin& origin) {
} // namespace
WebDatabaseObserverImpl::WebDatabaseObserverImpl(
- scoped_refptr<mojom::ThreadSafeWebDatabaseHostPtr> web_database_host)
+ scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host)
: web_database_host_(std::move(web_database_host)),
open_connections_(new storage::DatabaseConnectionsWrapper),
main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
@@ -190,7 +190,7 @@ void WebDatabaseObserverImpl::HandleSqliteError(const WebSecurityOrigin& origin,
}
}
-mojom::WebDatabaseHost& WebDatabaseObserverImpl::GetWebDatabaseHost() {
+blink::mojom::WebDatabaseHost& WebDatabaseObserverImpl::GetWebDatabaseHost() {
return **web_database_host_;
}
diff --git a/chromium/content/child/web_database_observer_impl.h b/chromium/content/renderer/web_database_observer_impl.h
index fcd8b05e1d0..b2ddbef2ed0 100644
--- a/chromium/content/child/web_database_observer_impl.h
+++ b/chromium/content/renderer/web_database_observer_impl.h
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_WEB_DATABASE_OBSERVER_IMPL_H_
-#define CONTENT_CHILD_WEB_DATABASE_OBSERVER_IMPL_H_
+#ifndef CONTENT_RENDERER_WEB_DATABASE_OBSERVER_IMPL_H_
+#define CONTENT_RENDERER_WEB_DATABASE_OBSERVER_IMPL_H_
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "content/common/web_database.mojom.h"
#include "storage/common/database/database_connections.h"
#include "third_party/WebKit/public/platform/WebDatabaseObserver.h"
+#include "third_party/WebKit/public/platform/modules/webdatabase/web_database.mojom.h"
namespace base {
class SingleThreadTaskRunner;
@@ -20,7 +20,8 @@ namespace content {
class WebDatabaseObserverImpl : public blink::WebDatabaseObserver {
public:
explicit WebDatabaseObserverImpl(
- scoped_refptr<mojom::ThreadSafeWebDatabaseHostPtr> web_database_host);
+ scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr>
+ web_database_host);
virtual ~WebDatabaseObserverImpl();
void DatabaseOpened(const blink::WebSecurityOrigin& origin,
@@ -69,9 +70,9 @@ class WebDatabaseObserverImpl : public blink::WebDatabaseObserver {
int error);
// Return the mojo interface for making WebDatabaseHost calls.
- mojom::WebDatabaseHost& GetWebDatabaseHost();
+ blink::mojom::WebDatabaseHost& GetWebDatabaseHost();
- scoped_refptr<mojom::ThreadSafeWebDatabaseHostPtr> web_database_host_;
+ scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host_;
scoped_refptr<storage::DatabaseConnectionsWrapper> open_connections_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
@@ -80,4 +81,4 @@ class WebDatabaseObserverImpl : public blink::WebDatabaseObserver {
} // namespace content
-#endif // CONTENT_CHILD_WEB_DATABASE_OBSERVER_IMPL_H_
+#endif // CONTENT_RENDERER_WEB_DATABASE_OBSERVER_IMPL_H_
diff --git a/chromium/content/renderer/web_ui_extension.cc b/chromium/content/renderer/web_ui_extension.cc
index bf9d778adff..93ff2804839 100644
--- a/chromium/content/renderer/web_ui_extension.cc
+++ b/chromium/content/renderer/web_ui_extension.cc
@@ -10,13 +10,13 @@
#include "base/strings/string_util.h"
#include "base/values.h"
#include "content/common/frame_messages.h"
-#include "content/public/child/v8_value_converter.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/url_constants.h"
#include "content/public/renderer/chrome_object_extensions_utils.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
+#include "content/public/renderer/v8_value_converter.h"
#include "content/renderer/web_ui_extension_data.h"
#include "gin/arguments.h"
#include "gin/function_template.h"
@@ -100,7 +100,7 @@ void WebUIExtension::Send(gin::Arguments* args) {
if (base::EndsWith(message, "RequiringGesture",
base::CompareCase::SENSITIVE) &&
- !blink::WebUserGestureIndicator::IsProcessingUserGesture()) {
+ !blink::WebUserGestureIndicator::IsProcessingUserGesture(frame)) {
NOTREACHED();
return;
}
@@ -120,6 +120,13 @@ void WebUIExtension::Send(gin::Arguments* args) {
content = base::ListValue::From(V8ValueConverter::Create()->FromV8Value(
obj, frame->MainWorldScriptContext()));
DCHECK(content);
+ // The conversion of |obj| could have triggered arbitrary JavaScript code,
+ // so check that the frame is still valid to avoid dereferencing a stale
+ // pointer.
+ if (frame != blink::WebLocalFrame::FrameForCurrentContext()) {
+ NOTREACHED();
+ return;
+ }
}
// Send the message up to the browser.
diff --git a/chromium/content/renderer/webclipboard_impl.cc b/chromium/content/renderer/webclipboard_impl.cc
index e914aef5963..f92961c1d54 100644
--- a/chromium/content/renderer/webclipboard_impl.cc
+++ b/chromium/content/renderer/webclipboard_impl.cc
@@ -5,6 +5,7 @@
#include "content/renderer/webclipboard_impl.h"
#include "base/logging.h"
+#include "base/memory/shared_memory.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
@@ -12,7 +13,8 @@
#include "content/public/common/drop_data.h"
#include "content/renderer/clipboard_utils.h"
#include "content/renderer/drop_data_builder.h"
-#include "content/renderer/renderer_clipboard_delegate.h"
+#include "content/renderer/render_thread_impl.h"
+#include "mojo/public/cpp/system/platform_handle.h"
#include "third_party/WebKit/public/platform/WebDragData.h"
#include "third_party/WebKit/public/platform/WebImage.h"
#include "third_party/WebKit/public/platform/WebSize.h"
@@ -31,46 +33,48 @@ using blink::WebVector;
namespace content {
-WebClipboardImpl::WebClipboardImpl(RendererClipboardDelegate* delegate)
- : delegate_(delegate) {
- DCHECK(delegate);
-}
+WebClipboardImpl::WebClipboardImpl(mojom::ClipboardHost& clipboard)
+ : clipboard_(clipboard) {}
-WebClipboardImpl::~WebClipboardImpl() {
-}
+WebClipboardImpl::~WebClipboardImpl() = default;
uint64_t WebClipboardImpl::SequenceNumber(Buffer buffer) {
ui::ClipboardType clipboard_type;
+ uint64_t result = 0;
if (!ConvertBufferType(buffer, &clipboard_type))
return 0;
- return delegate_->GetSequenceNumber(clipboard_type);
+ clipboard_.GetSequenceNumber(clipboard_type, &result);
+ return result;
}
bool WebClipboardImpl::IsFormatAvailable(Format format, Buffer buffer) {
ui::ClipboardType clipboard_type = ui::CLIPBOARD_TYPE_COPY_PASTE;
+ ClipboardFormat clipboard_format = CLIPBOARD_FORMAT_PLAINTEXT;
if (!ConvertBufferType(buffer, &clipboard_type))
return false;
switch (format) {
case kFormatPlainText:
- return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_PLAINTEXT,
- clipboard_type);
+ clipboard_format = CLIPBOARD_FORMAT_PLAINTEXT;
+ break;
case kFormatHTML:
- return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_HTML,
- clipboard_type);
+ clipboard_format = CLIPBOARD_FORMAT_HTML;
+ break;
case kFormatSmartPaste:
- return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_SMART_PASTE,
- clipboard_type);
+ clipboard_format = CLIPBOARD_FORMAT_SMART_PASTE;
+ break;
case kFormatBookmark:
- return delegate_->IsFormatAvailable(CLIPBOARD_FORMAT_BOOKMARK,
- clipboard_type);
+ clipboard_format = CLIPBOARD_FORMAT_BOOKMARK;
+ break;
default:
NOTREACHED();
}
- return false;
+ bool result = false;
+ clipboard_.IsFormatAvailable(clipboard_format, clipboard_type, &result);
+ return result;
}
WebVector<WebString> WebClipboardImpl::ReadAvailableTypes(
@@ -79,7 +83,7 @@ WebVector<WebString> WebClipboardImpl::ReadAvailableTypes(
ui::ClipboardType clipboard_type;
std::vector<base::string16> types;
if (ConvertBufferType(buffer, &clipboard_type)) {
- delegate_->ReadAvailableTypes(clipboard_type, &types, contains_filenames);
+ clipboard_.ReadAvailableTypes(clipboard_type, &types, contains_filenames);
}
WebVector<WebString> web_types(types.size());
std::transform(
@@ -94,7 +98,7 @@ WebString WebClipboardImpl::ReadPlainText(Buffer buffer) {
return WebString();
base::string16 text;
- delegate_->ReadText(clipboard_type, &text);
+ clipboard_.ReadText(clipboard_type, &text);
return WebString::FromUTF16(text);
}
@@ -108,7 +112,7 @@ WebString WebClipboardImpl::ReadHTML(Buffer buffer,
base::string16 html_stdstr;
GURL gurl;
- delegate_->ReadHTML(clipboard_type, &html_stdstr, &gurl,
+ clipboard_.ReadHtml(clipboard_type, &html_stdstr, &gurl,
static_cast<uint32_t*>(fragment_start),
static_cast<uint32_t*>(fragment_end));
*source_url = gurl;
@@ -121,7 +125,7 @@ WebString WebClipboardImpl::ReadRTF(Buffer buffer) {
return WebString();
std::string rtf;
- delegate_->ReadRTF(clipboard_type, &rtf);
+ clipboard_.ReadRtf(clipboard_type, &rtf);
return WebString::FromLatin1(rtf);
}
@@ -132,8 +136,8 @@ WebBlobInfo WebClipboardImpl::ReadImage(Buffer buffer) {
std::string blob_uuid;
std::string type;
- int64_t size;
- delegate_->ReadImage(clipboard_type, &blob_uuid, &type, &size);
+ int64_t size = -1;
+ clipboard_.ReadImage(clipboard_type, &blob_uuid, &type, &size);
if (size < 0)
return WebBlobInfo();
return WebBlobInfo(WebString::FromASCII(blob_uuid), WebString::FromUTF8(type),
@@ -147,38 +151,40 @@ WebString WebClipboardImpl::ReadCustomData(Buffer buffer,
return WebString();
base::string16 data;
- delegate_->ReadCustomData(clipboard_type, type.Utf16(), &data);
+ clipboard_.ReadCustomData(clipboard_type, type.Utf16(), &data);
return WebString::FromUTF16(data);
}
void WebClipboardImpl::WritePlainText(const WebString& plain_text) {
- delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, plain_text.Utf16());
- delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ clipboard_.WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, plain_text.Utf16());
+ clipboard_.CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
}
void WebClipboardImpl::WriteHTML(const WebString& html_text,
const WebURL& source_url,
const WebString& plain_text,
bool write_smart_paste) {
- delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE, html_text.Utf16(),
+ clipboard_.WriteHtml(ui::CLIPBOARD_TYPE_COPY_PASTE, html_text.Utf16(),
source_url);
- delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, plain_text.Utf16());
+ clipboard_.WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE, plain_text.Utf16());
if (write_smart_paste)
- delegate_->WriteSmartPasteMarker(ui::CLIPBOARD_TYPE_COPY_PASTE);
- delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ clipboard_.WriteSmartPasteMarker(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ clipboard_.CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
}
void WebClipboardImpl::WriteImage(const WebImage& image,
const WebURL& url,
const WebString& title) {
DCHECK(!image.IsNull());
- const SkBitmap& bitmap = image.GetSkBitmap();
- if (!delegate_->WriteImage(ui::CLIPBOARD_TYPE_COPY_PASTE, bitmap))
+ if (!WriteImageToClipboard(ui::CLIPBOARD_TYPE_COPY_PASTE,
+ image.GetSkBitmap()))
return;
if (!url.IsEmpty()) {
- delegate_->WriteBookmark(ui::CLIPBOARD_TYPE_COPY_PASTE, url, title.Utf16());
+ GURL gurl(url);
+ clipboard_.WriteBookmark(ui::CLIPBOARD_TYPE_COPY_PASTE, gurl.spec(),
+ title.Utf16());
#if !defined(OS_MACOSX)
// When writing the image, we also write the image markup so that pasting
// into rich text editors, such as Gmail, reveals the image. We also don't
@@ -187,12 +193,12 @@ void WebClipboardImpl::WriteImage(const WebImage& image,
// We also don't want to write HTML on a Mac, since Mail.app prefers to use
// the image markup over attaching the actual image. See
// http://crbug.com/33016 for details.
- delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE,
+ clipboard_.WriteHtml(ui::CLIPBOARD_TYPE_COPY_PASTE,
base::UTF8ToUTF16(URLToImageMarkup(url, title)),
GURL());
#endif
}
- delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ clipboard_.CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
}
void WebClipboardImpl::WriteDataObject(const WebDragData& data) {
@@ -202,15 +208,16 @@ void WebClipboardImpl::WriteDataObject(const WebDragData& data) {
// type. This prevents stomping on clipboard contents that might have been
// written by extension functions such as chrome.bookmarkManagerPrivate.copy.
if (!data_object.text.is_null())
- delegate_->WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE,
+ clipboard_.WriteText(ui::CLIPBOARD_TYPE_COPY_PASTE,
data_object.text.string());
if (!data_object.html.is_null())
- delegate_->WriteHTML(ui::CLIPBOARD_TYPE_COPY_PASTE,
+ clipboard_.WriteHtml(ui::CLIPBOARD_TYPE_COPY_PASTE,
data_object.html.string(), GURL());
- if (!data_object.custom_data.empty())
- delegate_->WriteCustomData(ui::CLIPBOARD_TYPE_COPY_PASTE,
- data_object.custom_data);
- delegate_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ if (!data_object.custom_data.empty()) {
+ clipboard_.WriteCustomData(ui::CLIPBOARD_TYPE_COPY_PASTE,
+ std::move(data_object.custom_data));
+ }
+ clipboard_.CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
}
bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
@@ -236,4 +243,32 @@ bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
return true;
}
+bool WebClipboardImpl::WriteImageToClipboard(ui::ClipboardType clipboard_type,
+ const SkBitmap& bitmap) {
+ // Only 32-bit bitmaps are supported.
+ DCHECK_EQ(bitmap.colorType(), kN32_SkColorType);
+
+ const gfx::Size size(bitmap.width(), bitmap.height());
+
+ void* pixels = bitmap.getPixels();
+ // TODO(piman): this should not be NULL, but it is. crbug.com/369621
+ if (!pixels)
+ return false;
+
+ base::CheckedNumeric<uint32_t> checked_buf_size = 4;
+ checked_buf_size *= size.width();
+ checked_buf_size *= size.height();
+ if (!checked_buf_size.IsValid())
+ return false;
+
+ // Allocate a shared memory buffer to hold the bitmap bits.
+ uint32_t buf_size = checked_buf_size.ValueOrDie();
+ auto buffer = mojo::SharedBufferHandle::Create(buf_size);
+ auto mapping = buffer->Map(buf_size);
+ memcpy(mapping.get(), pixels, buf_size);
+
+ clipboard_.WriteImage(clipboard_type, size, std::move(buffer));
+ return true;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/webclipboard_impl.h b/chromium/content/renderer/webclipboard_impl.h
index 4c3bf6aa556..acaf99a4bfe 100644
--- a/chromium/content/renderer/webclipboard_impl.h
+++ b/chromium/content/renderer/webclipboard_impl.h
@@ -10,15 +10,15 @@
#include <string>
#include "base/compiler_specific.h"
+#include "content/common/clipboard.mojom.h"
#include "third_party/WebKit/public/platform/WebClipboard.h"
#include "ui/base/clipboard/clipboard.h"
namespace content {
-class RendererClipboardDelegate;
class WebClipboardImpl : public blink::WebClipboard {
public:
- explicit WebClipboardImpl(RendererClipboardDelegate* delegate);
+ explicit WebClipboardImpl(mojom::ClipboardHost& clipboard);
virtual ~WebClipboardImpl();
@@ -49,7 +49,9 @@ class WebClipboardImpl : public blink::WebClipboard {
private:
bool ConvertBufferType(Buffer, ui::ClipboardType*);
- RendererClipboardDelegate* const delegate_;
+ bool WriteImageToClipboard(ui::ClipboardType clipboard_type,
+ const SkBitmap& bitmap);
+ mojom::ClipboardHost& clipboard_;
};
} // namespace content
diff --git a/chromium/content/renderer/webclipboard_impl_browsertest.cc b/chromium/content/renderer/webclipboard_impl_browsertest.cc
index 906c33628c5..809765f1649 100644
--- a/chromium/content/renderer/webclipboard_impl_browsertest.cc
+++ b/chromium/content/renderer/webclipboard_impl_browsertest.cc
@@ -4,6 +4,7 @@
#include "content/renderer/webclipboard_impl.h"
+#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
@@ -29,6 +30,8 @@ IN_PROC_BROWSER_TEST_F(WebClipboardImplTest, PasteRTF) {
// paste_listener.html takes RTF from the clipboard and sets the title.
NavigateToURL(shell(), GetTestUrl(".", "paste_listener.html"));
+ FrameFocusedObserver focus_observer(shell()->web_contents()->GetMainFrame());
+ focus_observer.Wait();
const base::string16 expected_title = base::UTF8ToUTF16(rtf_content);
content::TitleWatcher title_watcher(shell()->web_contents(), expected_title);
diff --git a/chromium/content/child/webfileutilities_impl.cc b/chromium/content/renderer/webfileutilities_impl.cc
index 2a6f3d12b78..bcb86d527a5 100644
--- a/chromium/content/child/webfileutilities_impl.cc
+++ b/chromium/content/renderer/webfileutilities_impl.cc
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/webfileutilities_impl.h"
+#include "content/renderer/webfileutilities_impl.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
-#include "content/child/file_info_util.h"
+#include "content/renderer/file_info_util.h"
#include "net/base/filename_util.h"
#include "third_party/WebKit/public/platform/FilePathConversion.h"
#include "third_party/WebKit/public/platform/WebFileInfo.h"
diff --git a/chromium/content/child/webfileutilities_impl.h b/chromium/content/renderer/webfileutilities_impl.h
index ef9b6df7849..7a13e7d7584 100644
--- a/chromium/content/child/webfileutilities_impl.h
+++ b/chromium/content/renderer/webfileutilities_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_WEBFILEUTILITIES_IMPL_H_
-#define CONTENT_CHILD_WEBFILEUTILITIES_IMPL_H_
+#ifndef CONTENT_RENDERER_WEBFILEUTILITIES_IMPL_H_
+#define CONTENT_RENDERER_WEBFILEUTILITIES_IMPL_H_
#include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/WebFileInfo.h"
@@ -33,4 +33,4 @@ class CONTENT_EXPORT WebFileUtilitiesImpl : public blink::WebFileUtilities {
} // namespace content
-#endif // CONTENT_CHILD_WEBFILEUTILITIES_IMPL_H_
+#endif // CONTENT_RENDERER_WEBFILEUTILITIES_IMPL_H_
diff --git a/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc b/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc
index 4795bc15139..754b10319e7 100644
--- a/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc
+++ b/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc
@@ -4,6 +4,7 @@
#include "content/renderer/webgraphicscontext3d_provider_impl.h"
+#include "components/viz/common/gl_helper.h"
#include "gpu/command_buffer/client/context_support.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
@@ -12,12 +13,18 @@ namespace content {
WebGraphicsContext3DProviderImpl::WebGraphicsContext3DProviderImpl(
scoped_refptr<ui::ContextProviderCommandBuffer> provider,
bool software_rendering)
- : provider_(std::move(provider)), software_rendering_(software_rendering) {}
+ : provider_(std::move(provider)), software_rendering_(software_rendering) {
+ provider_->AddObserver(this);
+}
-WebGraphicsContext3DProviderImpl::~WebGraphicsContext3DProviderImpl() {}
+WebGraphicsContext3DProviderImpl::~WebGraphicsContext3DProviderImpl() {
+ provider_->RemoveObserver(this);
+}
bool WebGraphicsContext3DProviderImpl::BindToCurrentThread() {
- return provider_->BindToCurrentThread();
+ // TODO(danakj): Could plumb this result out to the caller so they know to
+ // retry or not, if any client cared to know if it should retry or not.
+ return provider_->BindToCurrentThread() == gpu::ContextResult::kSuccess;
}
gpu::gles2::GLES2Interface* WebGraphicsContext3DProviderImpl::ContextGL() {
@@ -28,6 +35,10 @@ GrContext* WebGraphicsContext3DProviderImpl::GetGrContext() {
return provider_->GrContext();
}
+void WebGraphicsContext3DProviderImpl::InvalidateGrContext(uint32_t state) {
+ return provider_->InvalidateGrContext(state);
+}
+
const gpu::Capabilities& WebGraphicsContext3DProviderImpl::GetCapabilities()
const {
return provider_->ContextCapabilities();
@@ -38,24 +49,36 @@ const gpu::GpuFeatureInfo& WebGraphicsContext3DProviderImpl::GetGpuFeatureInfo()
return provider_->GetGpuFeatureInfo();
}
+viz::GLHelper* WebGraphicsContext3DProviderImpl::GetGLHelper() {
+ if (!gl_helper_) {
+ gl_helper_ = std::make_unique<viz::GLHelper>(provider_->ContextGL(),
+ provider_->ContextSupport());
+ }
+ return gl_helper_.get();
+}
+
bool WebGraphicsContext3DProviderImpl::IsSoftwareRendering() const {
return software_rendering_;
}
void WebGraphicsContext3DProviderImpl::SetLostContextCallback(
const base::Closure& c) {
- provider_->SetLostContextCallback(c);
+ context_lost_callback_ = c;
}
void WebGraphicsContext3DProviderImpl::SetErrorMessageCallback(
- const base::Callback<void(const char*, int32_t)>& c) {
- provider_->ContextSupport()->SetErrorMessageCallback(c);
+ base::RepeatingCallback<void(const char*, int32_t)> c) {
+ provider_->ContextSupport()->SetErrorMessageCallback(std::move(c));
+}
+
+void WebGraphicsContext3DProviderImpl::SignalQuery(uint32_t query,
+ base::OnceClosure callback) {
+ provider_->ContextSupport()->SignalQuery(query, std::move(callback));
}
-void WebGraphicsContext3DProviderImpl::SignalQuery(
- uint32_t query,
- const base::Closure& callback) {
- provider_->ContextSupport()->SignalQuery(query, callback);
+void WebGraphicsContext3DProviderImpl::OnContextLost() {
+ if (!context_lost_callback_.is_null())
+ context_lost_callback_.Run();
}
} // namespace content
diff --git a/chromium/content/renderer/webgraphicscontext3d_provider_impl.h b/chromium/content/renderer/webgraphicscontext3d_provider_impl.h
index 3ac2e4317d8..8f4dffb5f24 100644
--- a/chromium/content/renderer/webgraphicscontext3d_provider_impl.h
+++ b/chromium/content/renderer/webgraphicscontext3d_provider_impl.h
@@ -7,25 +7,31 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
+#include "components/viz/common/gpu/context_provider.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3DProvider.h"
namespace gpu {
namespace gles2 {
class GLES2Interface;
-}
-}
+} // namespace gles2
+} // namespace gpu
namespace ui {
class ContextProviderCommandBuffer;
-}
+} // namespace ui
+
+namespace viz {
+class GLHelper;
+} // namespace viz
namespace content {
class CONTENT_EXPORT WebGraphicsContext3DProviderImpl
- : public blink::WebGraphicsContext3DProvider {
+ : public blink::WebGraphicsContext3DProvider,
+ public viz::ContextLostObserver {
public:
- explicit WebGraphicsContext3DProviderImpl(
+ WebGraphicsContext3DProviderImpl(
scoped_refptr<ui::ContextProviderCommandBuffer> provider,
bool software_rendering);
~WebGraphicsContext3DProviderImpl() override;
@@ -34,21 +40,30 @@ class CONTENT_EXPORT WebGraphicsContext3DProviderImpl
bool BindToCurrentThread() override;
gpu::gles2::GLES2Interface* ContextGL() override;
GrContext* GetGrContext() override;
+ void InvalidateGrContext(uint32_t state) override;
const gpu::Capabilities& GetCapabilities() const override;
const gpu::GpuFeatureInfo& GetGpuFeatureInfo() const override;
+ viz::GLHelper* GetGLHelper() override;
bool IsSoftwareRendering() const override;
void SetLostContextCallback(const base::Closure&) override;
void SetErrorMessageCallback(
- const base::Callback<void(const char*, int32_t)>&) override;
- void SignalQuery(uint32_t, const base::Closure&) override;
+ base::RepeatingCallback<void(const char*, int32_t)>) override;
+ void SignalQuery(uint32_t, base::OnceClosure) override;
ui::ContextProviderCommandBuffer* context_provider() const {
return provider_.get();
}
private:
+ // viz::ContextLostObserver implementation.
+ void OnContextLost() override;
+
scoped_refptr<ui::ContextProviderCommandBuffer> provider_;
+ std::unique_ptr<viz::GLHelper> gl_helper_;
const bool software_rendering_;
+ base::Closure context_lost_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebGraphicsContext3DProviderImpl);
};
} // namespace content
diff --git a/chromium/content/child/worker_thread_message_filter.cc b/chromium/content/renderer/worker_thread_message_filter.cc
index 3f469f743ae..81b24c2c286 100644
--- a/chromium/content/child/worker_thread_message_filter.cc
+++ b/chromium/content/renderer/worker_thread_message_filter.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/worker_thread_message_filter.h"
+#include "content/renderer/worker_thread_message_filter.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/child/thread_safe_sender.h"
-#include "content/child/worker_thread_registry.h"
+#include "content/renderer/worker_thread_registry.h"
#include "ipc/ipc_message_macros.h"
namespace content {
diff --git a/chromium/content/child/worker_thread_message_filter.h b/chromium/content/renderer/worker_thread_message_filter.h
index 0e8063b592f..d08b47d8cba 100644
--- a/chromium/content/child/worker_thread_message_filter.h
+++ b/chromium/content/renderer/worker_thread_message_filter.h
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_CHILD_WORKER_THREAD_MESSAGE_FILTER_H_
-#define CONTENT_CHILD_WORKER_THREAD_MESSAGE_FILTER_H_
+#ifndef CONTENT_RENDERER_WORKER_THREAD_MESSAGE_FILTER_H_
+#define CONTENT_RENDERER_WORKER_THREAD_MESSAGE_FILTER_H_
#include "base/macros.h"
-#include "content/child/child_message_filter.h"
+#include "content/renderer/child_message_filter.h"
namespace base {
class SingleThreadTaskRunner;
@@ -56,4 +56,4 @@ class WorkerThreadMessageFilter : public ChildMessageFilter {
} // namespace content
-#endif // CONTENT_CHILD_WORKER_THREAD_MESSAGE_FILTER_H_
+#endif // CONTENT_RENDERER_WORKER_THREAD_MESSAGE_FILTER_H_
diff --git a/chromium/content/child/worker_thread_registry.cc b/chromium/content/renderer/worker_thread_registry.cc
index 8429a6bd325..47546f0e52b 100644
--- a/chromium/content/child/worker_thread_registry.cc
+++ b/chromium/content/renderer/worker_thread_registry.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/child/worker_thread_registry.h"
+#include "content/renderer/worker_thread_registry.h"
#include <memory>
#include <utility>
@@ -15,7 +15,7 @@
#include "base/stl_util.h"
#include "base/threading/thread_local.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/public/child/worker_thread.h"
+#include "content/public/renderer/worker_thread.h"
namespace content {
diff --git a/chromium/content/child/worker_thread_registry.h b/chromium/content/renderer/worker_thread_registry.h
index 657d88c8666..7c7d184e418 100644
--- a/chromium/content/child/worker_thread_registry.h
+++ b/chromium/content/renderer/worker_thread_registry.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_CHILD_WORKER_THREAD_REGISTRY_H_
-#define CONTENT_CHILD_WORKER_THREAD_REGISTRY_H_
+#ifndef CONTENT_RENDERER_WORKER_THREAD_REGISTRY_H_
+#define CONTENT_RENDERER_WORKER_THREAD_REGISTRY_H_
#include <map>
@@ -12,7 +12,7 @@
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
#include "content/common/content_export.h"
-#include "content/public/child/worker_thread.h"
+#include "content/public/renderer/worker_thread.h"
namespace base {
class TaskRunner;
@@ -59,4 +59,4 @@ class CONTENT_EXPORT WorkerThreadRegistry {
} // namespace content
-#endif // CONTENT_CHILD_WORKER_THREAD_REGISTRY_H_
+#endif // CONTENT_RENDERER_WORKER_THREAD_REGISTRY_H_
diff --git a/chromium/content/child/worker_thread_registry_unittest.cc b/chromium/content/renderer/worker_thread_registry_unittest.cc
index 3a5248405ee..6dcfbd1dd67 100644
--- a/chromium/content/child/worker_thread_registry_unittest.cc
+++ b/chromium/content/renderer/worker_thread_registry_unittest.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/child/worker_thread_registry.h"
+#include "content/renderer/worker_thread_registry.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
-#include "content/public/child/worker_thread.h"
+#include "content/public/renderer/worker_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/content/shell/BUILD.gn b/chromium/content/shell/BUILD.gn
index 825408259d7..5727bcf7a2b 100644
--- a/chromium/content/shell/BUILD.gn
+++ b/chromium/content/shell/BUILD.gn
@@ -10,6 +10,7 @@ import("//build/config/win/manifest.gni")
import("//media/media_options.gni")
import("//mojo/public/tools/bindings/mojom.gni")
import("//ppapi/features/features.gni")
+import("//services/service_manager/public/service_manifest.gni")
import("//tools/grit/repack.gni")
import("//tools/grit/grit_rule.gni")
if (is_android) {
@@ -213,11 +214,13 @@ static_library("content_shell_lib") {
"//content/public/child",
"//content/public/common",
"//content/public/gpu",
+ "//content/public/network",
"//content/public/renderer",
"//content/public/utility",
"//ipc",
]
deps = [
+ ":content_shell_packaged_services_manifest_overlay",
":mojo_bindings",
":resources",
"//base",
@@ -225,6 +228,10 @@ static_library("content_shell_lib") {
"//base/third_party/dynamic_annotations",
"//cc",
"//components/cdm/renderer",
+ "//components/crash/content/app",
+ "//components/crash/content/app:test_support",
+ "//components/crash/content/browser",
+ "//components/crash/core/common:crash_key",
"//components/keyed_service/content",
"//components/network_session_configurator/browser",
"//components/plugins/renderer",
@@ -245,6 +252,7 @@ static_library("content_shell_lib") {
"//device/bluetooth:fake_bluetooth",
"//device/bluetooth:mocks",
"//device/geolocation",
+ "//device/geolocation/public/interfaces",
"//device/sensors/public/cpp:full",
"//gin",
"//gpu",
@@ -258,6 +266,8 @@ static_library("content_shell_lib") {
"//ppapi/features",
"//sandbox",
"//services/service_manager/public/cpp",
+ "//services/test/echo:lib",
+ "//services/test/echo/public/interfaces",
"//skia",
"//storage/browser",
"//testing/gmock",
@@ -282,9 +292,13 @@ static_library("content_shell_lib") {
"//v8",
]
- if (!is_fuchsia) {
- deps +=
- [ "//components/crash/content/app:app_breakpad_mac_win_to_be_deleted" ]
+ if (is_fuchsia) {
+ sources += [ "app/blink_test_platform_support_fuchsia.cc" ]
+ deps -= [
+ "//components/crash/content/app",
+ "//components/crash/content/app:test_support",
+ "//components/crash/content/browser",
+ ]
}
# Annoyingly, this target and layouttest_support have circular includes.
@@ -337,13 +351,6 @@ static_library("content_shell_lib") {
]
}
- if (is_posix && !is_mac && !is_fuchsia) {
- deps += [
- "//components/crash/content/app",
- "//components/crash/content/browser",
- ]
- }
-
if (use_aura) {
deps += [
"//ui/aura",
@@ -405,6 +412,16 @@ grit("content_shell_resources_grit") {
"grit/shell_resources.h",
"shell_resources.pak",
]
+
+ # Mojo manifest overlays are generated.
+ source_is_generated = true
+ grit_flags = [
+ "-E",
+ "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir),
+ ]
+ deps = [
+ ":content_shell_packaged_services_manifest_overlay",
+ ]
}
copy("copy_shell_resources") {
@@ -441,6 +458,7 @@ repack("pak") {
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
"$root_gen_dir/content/content_resources.pak",
"$root_gen_dir/content/shell/shell_resources.pak",
+ "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
"$root_gen_dir/net/net_resources.pak",
"$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
"$root_gen_dir/ui/resources/webui_resources.pak",
@@ -454,6 +472,7 @@ repack("pak") {
"//content/app/resources",
"//content/app/strings",
"//content/browser/tracing:resources",
+ "//mojo/public/js:resources",
"//net:net_resources",
"//third_party/WebKit/public:resources",
"//third_party/WebKit/public:scaled_resources_100_percent",
@@ -566,6 +585,13 @@ if (is_android) {
configs -= [ "//build/config/win:console" ]
configs += [ "//build/config/win:windowed" ]
}
+
+ data_deps +=
+ [ "//third_party/crashpad/crashpad/handler:crashpad_handler" ]
+ }
+
+ if (is_linux) {
+ data_deps += [ "//third_party/content_shell_fonts" ]
}
if (is_linux && !is_component_build) {
@@ -573,25 +599,16 @@ if (is_android) {
configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
}
}
-}
-
-if (is_win) {
- executable("content_shell_crash_service") {
- sources = [
- "tools/content_shell_crash_service.cc",
- ]
-
- deps = [
- "//base",
- "//build/config:exe_and_shlib_deps",
- "//build/win:default_exe_manifest",
- "//components/crash/content/tools:crash_service",
- ]
- configs -= [ "//build/config/win:console" ]
- configs += [ "//build/config/win:windowed" ]
+ if (is_fuchsia) {
+ fuchsia_executable_runner("content_shell_fuchsia") {
+ testonly = true
+ exe_target = ":content_shell"
+ }
}
+}
+if (is_win) {
if (is_syzyasan) {
syzygy_asan("content_shell_syzyasan") {
binary_name = "content_shell.exe"
@@ -605,6 +622,19 @@ if (is_win) {
}
if (is_mac) {
+ bundle_data("content_shell_framework_helpers") {
+ testonly = true
+ sources = [
+ "$root_out_dir/crashpad_handler",
+ ]
+ outputs = [
+ "{{bundle_contents_dir}}/Helpers/{{source_file_part}}",
+ ]
+ public_deps = [
+ "//third_party/crashpad/crashpad/handler:crashpad_handler",
+ ]
+ }
+
mac_xib_bundle_data("content_shell_framework_xibs") {
sources = [
"app/English.lproj/HttpAuth.xib",
@@ -690,14 +720,11 @@ if (is_mac) {
"app/shell_content_main.h",
]
- # TODO(rsesek): Handle these missing pieces:
- # - crash_inspector
- # - crash_report_sender.app
-
public_deps = [
":content_shell_lib",
]
deps = [
+ ":content_shell_framework_helpers",
":content_shell_framework_resources",
":content_shell_framework_xibs",
"//third_party/icu:icudata",
@@ -801,6 +828,11 @@ mojom("mojo_bindings") {
]
}
+service_manifest("content_shell_packaged_services_manifest_overlay") {
+ source = "//content/shell/browser/content_shell_packaged_services_manifest_overlay.json"
+ packaged_services = [ "//services/test/echo:manifest" ]
+}
+
group("content_shell_crash_test") {
testonly = true
data_deps = [
@@ -820,10 +852,7 @@ group("content_shell_crash_test") {
]
}
if (is_win) {
- data_deps += [
- ":content_shell_crash_service",
- "//build/win:copy_cdb_to_output",
- ]
+ data_deps += [ "//build/win:copy_cdb_to_output" ]
}
if (is_posix && !is_android) {
data_deps += [
diff --git a/chromium/content/shell/shell_resources.grd b/chromium/content/shell/shell_resources.grd
index 0fdafbec4a2..4b447a807c0 100644
--- a/chromium/content/shell/shell_resources.grd
+++ b/chromium/content/shell/shell_resources.grd
@@ -16,6 +16,8 @@
<include name="IDR_CONTENT_SHELL_GPU_MANIFEST_OVERLAY" file="browser/content_shell_gpu_manifest_overlay.json" type="BINDATA" />
<include name="IDR_CONTENT_SHELL_RENDERER_MANIFEST_OVERLAY" file="browser/content_shell_renderer_manifest_overlay.json" type="BINDATA" />
<include name="IDR_CONTENT_SHELL_UTILITY_MANIFEST_OVERLAY" file="browser/content_shell_utility_manifest_overlay.json" type="BINDATA" />
+ <!-- Generated resources. -->
+ <include name="IDR_CONTENT_SHELL_PACKAGED_SERVICES_MANIFEST_OVERLAY" file="${root_gen_dir}/content/shell/content_shell_packaged_services_manifest_overlay.json" type="BINDATA" use_base_dir="false"/>
</includes>
</release>
</grit>
diff --git a/chromium/content/shell/test_runner/BUILD.gn b/chromium/content/shell/test_runner/BUILD.gn
index 7c5dadf67c7..f09442eac1b 100644
--- a/chromium/content/shell/test_runner/BUILD.gn
+++ b/chromium/content/shell/test_runner/BUILD.gn
@@ -46,16 +46,12 @@ component("test_runner") {
"mock_web_audio_device.h",
"mock_web_document_subresource_filter.cc",
"mock_web_document_subresource_filter.h",
- "mock_web_media_stream_center.cc",
- "mock_web_media_stream_center.h",
"mock_web_midi_accessor.cc",
"mock_web_midi_accessor.h",
"mock_web_speech_recognizer.cc",
"mock_web_speech_recognizer.h",
"mock_web_theme_engine.cc",
"mock_web_theme_engine.h",
- "mock_web_user_media_client.cc",
- "mock_web_user_media_client.h",
"pixel_dump.cc",
"pixel_dump.h",
"spell_check_client.cc",
diff --git a/chromium/content/test/BUILD.gn b/chromium/content/test/BUILD.gn
index 9966b7a9c6c..02c8fafd689 100644
--- a/chromium/content/test/BUILD.gn
+++ b/chromium/content/test/BUILD.gn
@@ -48,8 +48,6 @@ static_library("test_support") {
"../browser/download/mock_download_item_impl.h",
"../browser/download/mock_download_job.cc",
"../browser/download/mock_download_job.h",
- "../browser/download/slow_download_http_response.cc",
- "../browser/download/slow_download_http_response.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",
@@ -117,6 +115,8 @@ static_library("test_support") {
"../public/test/service_worker_test_helpers.h",
"../public/test/simple_url_loader_test_helper.cc",
"../public/test/simple_url_loader_test_helper.h",
+ "../public/test/slow_download_http_response.cc",
+ "../public/test/slow_download_http_response.h",
"../public/test/test_browser_context.cc",
"../public/test/test_browser_context.h",
"../public/test/test_browser_thread.cc",
@@ -125,6 +125,8 @@ static_library("test_support") {
"../public/test/test_browser_thread_bundle.h",
"../public/test/test_content_client_initializer.cc",
"../public/test/test_content_client_initializer.h",
+ "../public/test/test_download_http_response.cc",
+ "../public/test/test_download_http_response.h",
"../public/test/test_download_request_handler.cc",
"../public/test/test_download_request_handler.h",
"../public/test/test_file_error_injector.cc",
@@ -167,6 +169,8 @@ static_library("test_support") {
"../public/test/text_input_test_utils_mac.mm",
"../public/test/unittest_test_suite.cc",
"../public/test/unittest_test_suite.h",
+ "../public/test/url_loader_interceptor.cc",
+ "../public/test/url_loader_interceptor.h",
"../public/test/web_contents_binding_set_test_binder.h",
"../public/test/web_contents_tester.cc",
"../public/test/web_contents_tester.h",
@@ -187,6 +191,8 @@ static_library("test_support") {
"dwrite_font_fake_sender_win.h",
"fake_compositor_dependencies.cc",
"fake_compositor_dependencies.h",
+ "fake_leveldb_database.cc",
+ "fake_leveldb_database.h",
"fake_plugin_service.cc",
"fake_plugin_service.h",
"fake_renderer_compositor_frame_sink.cc",
@@ -199,8 +205,6 @@ static_library("test_support") {
"mock_keyboard.h",
"mock_keyboard_driver_win.cc",
"mock_keyboard_driver_win.h",
- "mock_leveldb_database.cc",
- "mock_leveldb_database.h",
"mock_overscroll_observer.h",
"mock_permission_manager.cc",
"mock_permission_manager.h",
@@ -218,6 +222,8 @@ static_library("test_support") {
"mock_webclipboard_impl.h",
"mock_widget_impl.cc",
"mock_widget_impl.h",
+ "mock_widget_input_handler.cc",
+ "mock_widget_input_handler.h",
"net/url_request_abort_on_end_job.cc",
"net/url_request_abort_on_end_job.h",
"ppapi_unittest.cc",
@@ -250,6 +256,10 @@ static_library("test_support") {
"test_render_view_host.h",
"test_render_view_host_factory.cc",
"test_render_view_host_factory.h",
+ "test_render_widget_host.cc",
+ "test_render_widget_host.h",
+ "test_render_widget_host_factory.cc",
+ "test_render_widget_host_factory.h",
"test_web_contents.cc",
"test_web_contents.h",
"test_web_contents_factory.cc",
@@ -262,6 +272,7 @@ static_library("test_support") {
configs += [
"//build/config:precompiled_headers",
"//v8:external_startup_data",
+ "//tools/v8_context_snapshot:use_v8_context_snapshot",
]
public_deps = [
@@ -274,6 +285,7 @@ static_library("test_support") {
"//media/mojo/interfaces",
"//third_party/WebKit/public:blink",
"//third_party/WebKit/public:test_support",
+ "//tools/v8_context_snapshot",
]
deps = [
":content_test_mojo_bindings",
@@ -328,6 +340,7 @@ static_library("test_support") {
"//ui/events:events_base",
"//ui/events:gesture_detection",
"//ui/events:test_support",
+ "//ui/events/blink",
"//ui/gfx:test_support",
"//ui/gl",
"//ui/gl:test_support",
@@ -370,8 +383,6 @@ static_library("test_support") {
sources += [
"../renderer/media/mock_data_channel_impl.cc",
"../renderer/media/mock_data_channel_impl.h",
- "../renderer/media/mock_media_stream_dispatcher.cc",
- "../renderer/media/mock_media_stream_dispatcher.h",
"../renderer/media/mock_mojo_media_stream_dispatcher_host.cc",
"../renderer/media/mock_mojo_media_stream_dispatcher_host.h",
"../renderer/media/mock_peer_connection_impl.cc",
@@ -659,6 +670,7 @@ test("content_browsertests") {
"../browser/accessibility/dump_accessibility_browsertest_base.h",
"../browser/accessibility/dump_accessibility_events_browsertest.cc",
"../browser/accessibility/dump_accessibility_tree_browsertest.cc",
+ "../browser/accessibility/fullscreen_browsertest.cc",
"../browser/accessibility/hit_testing_browsertest.cc",
"../browser/accessibility/site_per_process_accessibility_browsertest.cc",
"../browser/accessibility/snapshot_ax_tree_browsertest.cc",
@@ -670,6 +682,7 @@ test("content_browsertests") {
"../browser/blob_storage/blob_url_browsertest.cc",
"../browser/bookmarklet_browsertest.cc",
"../browser/browser_side_navigation_browsertest.cc",
+ "../browser/browsing_data/browsing_data_remover_impl_browsertest.cc",
"../browser/browsing_data/clear_site_data_throttle_browsertest.cc",
"../browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc",
"../browser/child_process_launcher_browsertest.cc",
@@ -731,6 +744,8 @@ test("content_browsertests") {
"../browser/message_port_provider_browsertest.cc",
"../browser/mojo_sandbox_browsertest.cc",
"../browser/net_info_browsertest.cc",
+ "../browser/network_service_browsertest.cc",
+ "../browser/network_service_restart_browsertest.cc",
"../browser/payments/payment_app_browsertest.cc",
"../browser/pointer_lock_browsertest.cc",
"../browser/pointer_lock_browsertest.h",
@@ -755,6 +770,7 @@ test("content_browsertests") {
"../browser/resource_loading_browsertest.cc",
"../browser/screen_orientation/screen_orientation_browsertest.cc",
"../browser/security_exploit_browsertest.cc",
+ "../browser/service_manager/service_manager_context_browsertest.cc",
"../browser/service_worker/service_worker_browsertest.cc",
"../browser/session_history_browsertest.cc",
"../browser/shape_detection/shape_detection_browsertest.cc",
@@ -780,10 +796,10 @@ test("content_browsertests") {
"../browser/webkit_browsertest.cc",
"../browser/webui/web_ui_browsertest.cc",
"../browser/webui/web_ui_mojo_browsertest.cc",
- "../child/site_isolation_stats_gatherer_browsertest.cc",
"../renderer/accessibility/render_accessibility_impl_browsertest.cc",
"../renderer/blink_platform_audio_hardware_browsertest.cc",
"../renderer/gin_browsertest.cc",
+ "../renderer/loader/site_isolation_stats_gatherer_browsertest.cc",
"../renderer/media/renderer_webmediaplayer_delegate_browsertest.cc",
"../renderer/mouse_lock_dispatcher_browsertest.cc",
"../renderer/render_frame_impl_browsertest.cc",
@@ -796,6 +812,7 @@ test("content_browsertests") {
"../renderer/webclipboard_impl_browsertest.cc",
"../test/browser_test_utils_browsertest.cc",
"../test/content_browser_test_test.cc",
+ "../test/url_loader_interceptor_test.cc",
"../test/webui_resource_browsertest.cc",
]
@@ -849,19 +866,22 @@ test("content_browsertests") {
"//net:test_support",
"//ppapi/features",
"//services/catalog:lib",
+ "//services/device/public/cpp:device_features",
"//services/device/public/cpp/generic_sensor",
"//services/device/public/interfaces",
"//services/device/public/interfaces:generic_sensor",
"//services/service_manager/public/cpp",
- "//services/ui/gpu/interfaces",
+ "//services/test/echo/public/interfaces",
"//services/ui/public/cpp/gpu",
"//services/video_capture/public/cpp",
"//services/video_capture/public/interfaces:constants",
+ "//services/viz/privileged/interfaces",
"//storage/browser",
"//testing/gmock",
"//testing/gtest",
"//third_party/WebKit/public:blink",
"//third_party/leveldatabase",
+ "//third_party/libaom:av1_features",
"//third_party/mesa:osmesa",
"//third_party/zlib",
"//ui/accessibility",
@@ -965,6 +985,8 @@ test("content_browsertests") {
]
sources -= [
"../browser/media/session/audio_focus_delegate_default_browsertest.cc",
+ "../browser/network_service_browsertest.cc",
+ "../browser/network_service_restart_browsertest.cc",
"../browser/pointer_lock_browsertest.cc",
"../browser/pointer_lock_browsertest.h",
]
@@ -1028,6 +1050,7 @@ test("content_browsertests") {
"../browser/webrtc/webrtc_internals_browsertest.cc",
"../browser/webrtc/webrtc_ip_permissions_browsertest.cc",
"../browser/webrtc/webrtc_media_recorder_browsertest.cc",
+ "../browser/webrtc/webrtc_pause_play_browsertest.cc",
"../browser/webrtc/webrtc_video_capture_browsertest.cc",
"../browser/webrtc/webrtc_webcam_browsertest.cc",
"../browser/webrtc/webrtc_webcam_browsertest.h",
@@ -1179,8 +1202,6 @@ test("content_unittests") {
"../browser/compositor/gpu_vsync_begin_frame_source_unittest.cc",
"../browser/compositor/reflector_impl_unittest.cc",
"../browser/compositor/software_browser_compositor_output_surface_unittest.cc",
- "../browser/compositor/software_output_device_mac_unittest.mm",
- "../browser/compositor/software_output_device_ozone_unittest.cc",
"../browser/devtools/devtools_http_handler_unittest.cc",
"../browser/devtools/devtools_manager_unittest.cc",
"../browser/devtools/protocol/tracing_handler_unittest.cc",
@@ -1205,7 +1226,6 @@ test("content_unittests") {
"../browser/fileapi/browser_file_system_helper_unittest.cc",
"../browser/fileapi/file_system_operation_runner_unittest.cc",
"../browser/fileapi/fileapi_message_filter_unittest.cc",
- "../browser/fileapi/upload_file_system_file_element_reader_unittest.cc",
"../browser/frame_host/ancestor_throttle_unittest.cc",
"../browser/frame_host/frame_service_base_unittest.cc",
"../browser/frame_host/frame_tree_node_blame_context_unittest.cc",
@@ -1279,7 +1299,6 @@ test("content_unittests") {
"../browser/loader/test_resource_handler.h",
"../browser/loader/throttling_resource_handler_unittest.cc",
"../browser/loader/upload_data_stream_builder_unittest.cc",
- "../browser/loader/upload_progress_tracker_unittest.cc",
"../browser/loader/url_loader_factory_impl_unittest.cc",
"../browser/mach_broker_mac_unittest.cc",
"../browser/manifest/manifest_icon_downloader_unittest.cc",
@@ -1310,26 +1329,24 @@ test("content_unittests") {
"../browser/notifications/notification_id_generator_unittest.cc",
"../browser/notifications/platform_notification_context_unittest.cc",
"../browser/notifications/type_converters_unittest.cc",
+ "../browser/origin_manifest/origin_manifest_parser_unittest.cc",
"../browser/payments/payment_app_content_unittest_base.cc",
"../browser/payments/payment_app_content_unittest_base.h",
"../browser/payments/payment_app_provider_impl_unittest.cc",
"../browser/payments/payment_manager_unittest.cc",
"../browser/permissions/permission_service_impl_unittest.cc",
"../browser/presentation/presentation_service_impl_unittest.cc",
- "../browser/renderer_host/clipboard_message_filter_unittest.cc",
+ "../browser/renderer_host/clipboard_host_impl_unittest.cc",
"../browser/renderer_host/compositor_resize_lock_unittest.cc",
"../browser/renderer_host/cursor_manager_unittest.cc",
"../browser/renderer_host/dwrite_font_proxy_message_filter_win_unittest.cc",
"../browser/renderer_host/input/gesture_event_queue_unittest.cc",
"../browser/renderer_host/input/input_router_impl_unittest.cc",
"../browser/renderer_host/input/legacy_input_router_impl_unittest.cc",
- "../browser/renderer_host/input/legacy_touch_event_queue_unittest.cc",
"../browser/renderer_host/input/mock_input_disposition_handler.cc",
"../browser/renderer_host/input/mock_input_disposition_handler.h",
"../browser/renderer_host/input/mock_input_router_client.cc",
"../browser/renderer_host/input/mock_input_router_client.h",
- "../browser/renderer_host/input/mock_widget_input_handler.cc",
- "../browser/renderer_host/input/mock_widget_input_handler.h",
"../browser/renderer_host/input/motion_event_web_unittest.cc",
"../browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc",
"../browser/renderer_host/input/mouse_wheel_rails_filter_unittest_mac.cc",
@@ -1344,12 +1361,18 @@ test("content_unittests") {
"../browser/renderer_host/input/web_input_event_builders_android_unittest.cc",
"../browser/renderer_host/input/web_input_event_builders_mac_unittest.mm",
"../browser/renderer_host/input/web_input_event_util_unittest.cc",
+ "../browser/renderer_host/media/audio_input_delegate_impl_unittest.cc",
"../browser/renderer_host/media/audio_input_device_manager_unittest.cc",
"../browser/renderer_host/media/audio_input_renderer_host_unittest.cc",
"../browser/renderer_host/media/audio_input_sync_writer_unittest.cc",
"../browser/renderer_host/media/audio_output_authorization_handler_unittest.cc",
"../browser/renderer_host/media/audio_output_delegate_impl_unittest.cc",
"../browser/renderer_host/media/audio_renderer_host_unittest.cc",
+ "../browser/renderer_host/media/audio_sync_reader_unittest.cc",
+ "../browser/renderer_host/media/fake_video_capture_device_launcher.cc",
+ "../browser/renderer_host/media/fake_video_capture_device_launcher.h",
+ "../browser/renderer_host/media/fake_video_capture_provider.cc",
+ "../browser/renderer_host/media/fake_video_capture_provider.h",
"../browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc",
"../browser/renderer_host/media/media_devices_manager_unittest.cc",
"../browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc",
@@ -1378,8 +1401,6 @@ test("content_unittests") {
"../browser/resolve_proxy_msg_helper_unittest.cc",
"../browser/screen_orientation/screen_orientation_provider_unittest.cc",
"../browser/service_worker/embedded_worker_instance_unittest.cc",
- "../browser/service_worker/foreign_fetch_request_handler_unittest.cc",
- "../browser/service_worker/link_header_support_unittest.cc",
"../browser/service_worker/service_worker_cache_writer_unittest.cc",
"../browser/service_worker/service_worker_context_core_unittest.cc",
"../browser/service_worker/service_worker_context_request_handler_unittest.cc",
@@ -1409,8 +1430,6 @@ test("content_unittests") {
"../browser/shared_worker/shared_worker_instance_unittest.cc",
"../browser/shared_worker/shared_worker_service_impl_unittest.cc",
"../browser/site_instance_impl_unittest.cc",
- "../browser/ssl/ignore_errors_cert_verifier_unittest.cc",
- "../browser/ssl/ssl_manager_unittest.cc",
"../browser/startup_task_runner_unittest.cc",
"../browser/storage_partition_impl_map_unittest.cc",
"../browser/storage_partition_impl_unittest.cc",
@@ -1429,42 +1448,17 @@ 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/webauth/authenticator_impl_unittest.cc",
"../browser/webauth/cbor/cbor_values_unittest.cc",
"../browser/webauth/cbor/cbor_writer_unittest.cc",
"../browser/websockets/websocket_manager_unittest.cc",
- "../browser/webui/i18n_source_stream_unittest.cc",
"../browser/webui/url_data_manager_backend_unittest.cc",
"../browser/webui/web_ui_data_source_unittest.cc",
"../browser/webui/web_ui_message_handler_unittest.cc",
"../child/blink_platform_impl_unittest.cc",
- "../child/blob_storage/blob_consolidation_unittest.cc",
- "../child/blob_storage/blob_transport_controller_unittest.cc",
"../child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc",
"../child/dwrite_font_proxy/font_fallback_win_unittest.cc",
- "../child/fileapi/webfilewriter_base_unittest.cc",
"../child/font_warmup_win_unittest.cc",
- "../child/indexed_db/mock_webidbcallbacks.cc",
- "../child/indexed_db/mock_webidbcallbacks.h",
- "../child/indexed_db/webidbcursor_impl_unittest.cc",
- "../child/indexed_db/webidbdatabase_impl_unittest.cc",
"../child/memory/child_memory_coordinator_impl_unittest.cc",
- "../child/notifications/notification_data_conversions_unittest.cc",
- "../child/resource_dispatcher_unittest.cc",
- "../child/service_worker/service_worker_dispatcher_unittest.cc",
- "../child/service_worker/service_worker_provider_context_unittest.cc",
- "../child/service_worker/service_worker_subresource_loader_unittest.cc",
- "../child/shared_memory_data_consumer_handle_unittest.cc",
- "../child/shared_memory_received_data_factory_unittest.cc",
- "../child/site_isolation_stats_gatherer_unittest.cc",
- "../child/test_request_peer.cc",
- "../child/test_request_peer.h",
- "../child/url_loader_client_impl_unittest.cc",
- "../child/url_response_body_consumer_unittest.cc",
- "../child/v8_value_converter_impl_unittest.cc",
- "../child/web_data_consumer_handle_impl_unittest.cc",
- "../child/web_url_loader_impl_unittest.cc",
- "../child/worker_thread_registry_unittest.cc",
"../common/android/gin_java_bridge_value_unittest.cc",
"../common/background_fetch/background_fetch_struct_traits_unittest.cc",
"../common/bluetooth/web_bluetooth_device_id_unittest.cc",
@@ -1476,9 +1470,7 @@ test("content_unittests") {
"../common/content_switches_internal_unittest.cc",
"../common/cross_site_document_classifier_unittest.cc",
"../common/cursors/webcursor_unittest.cc",
- "../common/devtools/devtools_network_controller_unittest.cc",
"../common/dom_storage/dom_storage_map_unittest.cc",
- "../common/feature_policy/feature_policy_unittest.cc",
"../common/indexed_db/indexed_db_key_unittest.cc",
"../common/input/event_with_latency_info_unittest.cc",
"../common/input/gesture_event_stream_validator_unittest.cc",
@@ -1486,7 +1478,6 @@ test("content_unittests") {
"../common/input/touch_event_stream_validator_unittest.cc",
"../common/inter_process_time_ticks_converter_unittest.cc",
"../common/mac/attributed_string_coder_unittest.mm",
- "../common/mac/font_descriptor_unittest.mm",
"../common/manifest_util_unittest.cc",
"../common/media/media_devices_unittest.cc",
"../common/origin_util_unittest.cc",
@@ -1502,35 +1493,63 @@ test("content_unittests") {
"../common/sandbox_mac_unittest_helper.h",
"../common/sandbox_mac_unittest_helper.mm",
"../common/service_manager/service_manager_connection_impl_unittest.cc",
+ "../common/service_worker/service_worker_types_unittest.cc",
"../common/service_worker/service_worker_utils_unittest.cc",
"../common/site_isolation_policy_unittest.cc",
"../common/throttling_url_loader_unittest.cc",
"../common/unique_name_helper_unittest.cc",
"../common/webplugininfo_unittest.cc",
- "../network/cookie_manager_impl_unittest.cc",
+ "../network/cookie_manager_unittest.cc",
+ "../network/network_change_manager_unittest.cc",
"../network/network_context_unittest.cc",
"../network/network_service_unittest.cc",
"../network/proxy_resolver_factory_mojo_unittest.cc",
- "../network/restricted_cookie_manager_impl_unittest.cc",
+ "../network/restricted_cookie_manager_unittest.cc",
+ "../network/throttling/throttling_controller_unittest.cc",
+ "../network/upload_progress_tracker_unittest.cc",
"../network/url_loader_unittest.cc",
+ "../public/common/drop_data_unittest.cc",
+ "../public/common/network_connection_tracker_unittest.cc",
"../public/common/simple_url_loader_unittest.cc",
"../public/common/url_utils_unittest.cc",
+ "../public/network/ignore_errors_cert_verifier_unittest.cc",
"../public/test/referrer_unittest.cc",
"../public/test/test_browser_thread_bundle_unittest.cc",
"../renderer/android/disambiguation_popup_helper_unittest.cc",
+ "../renderer/blob_storage/blob_consolidation_unittest.cc",
+ "../renderer/blob_storage/blob_transport_controller_unittest.cc",
"../renderer/bmp_image_decoder_unittest.cc",
"../renderer/categorized_worker_pool_unittest.cc",
"../renderer/device_sensors/device_motion_event_pump_unittest.cc",
"../renderer/device_sensors/device_orientation_event_pump_unittest.cc",
"../renderer/dom_storage/dom_storage_cached_area_unittest.cc",
"../renderer/dom_storage/local_storage_cached_area_unittest.cc",
+ "../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/compositor_forwarding_message_filter_unittest.cc",
"../renderer/gpu/frame_swap_message_queue_unittest.cc",
"../renderer/gpu/queue_message_swap_promise_unittest.cc",
"../renderer/gpu/render_widget_compositor_unittest.cc",
"../renderer/ico_image_decoder_unittest.cc",
+ "../renderer/indexed_db/mock_webidbcallbacks.cc",
+ "../renderer/indexed_db/mock_webidbcallbacks.h",
+ "../renderer/indexed_db/webidbcursor_impl_unittest.cc",
+ "../renderer/indexed_db/webidbdatabase_impl_unittest.cc",
"../renderer/input/input_event_filter_unittest.cc",
"../renderer/input/main_thread_event_queue_unittest.cc",
+ "../renderer/loader/cors_url_loader_unittest.cc",
+ "../renderer/loader/resource_dispatcher_unittest.cc",
+ "../renderer/loader/shared_memory_data_consumer_handle_unittest.cc",
+ "../renderer/loader/shared_memory_received_data_factory_unittest.cc",
+ "../renderer/loader/site_isolation_stats_gatherer_unittest.cc",
+ "../renderer/loader/test_request_peer.cc",
+ "../renderer/loader/test_request_peer.h",
+ "../renderer/loader/url_loader_client_impl_unittest.cc",
+ "../renderer/loader/url_response_body_consumer_unittest.cc",
+ "../renderer/loader/web_data_consumer_handle_impl_unittest.cc",
+ "../renderer/loader/web_url_loader_impl_unittest.cc",
"../renderer/manifest/manifest_parser_unittest.cc",
"../renderer/media/audio_ipc_factory_unittest.cc",
"../renderer/media/audio_message_filter_unittest.cc",
@@ -1538,11 +1557,13 @@ test("content_unittests") {
"../renderer/media/audio_renderer_sink_cache_unittest.cc",
"../renderer/media/mock_audio_device_factory.cc",
"../renderer/media/mock_audio_device_factory.h",
+ "../renderer/media/mojo_audio_input_ipc_unittest.cc",
"../renderer/media/mojo_audio_output_ipc_unittest.cc",
"../renderer/media/render_media_log_unittest.cc",
"../renderer/media/renderer_webaudiodevice_impl_unittest.cc",
"../renderer/media/video_capture_impl_manager_unittest.cc",
"../renderer/media/video_capture_impl_unittest.cc",
+ "../renderer/notifications/notification_data_conversions_unittest.cc",
"../renderer/peripheral_content_heuristic_unittest.cc",
"../renderer/presentation/presentation_dispatcher_unittest.cc",
"../renderer/presentation/test_presentation_connection.cc",
@@ -1550,9 +1571,15 @@ test("content_unittests") {
"../renderer/render_thread_impl_unittest.cc",
"../renderer/render_widget_unittest.cc",
"../renderer/scheduler/resource_dispatch_throttler_unittest.cc",
+ "../renderer/service_worker/service_worker_dispatcher_unittest.cc",
+ "../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",
"../test/renderer_audio_output_stream_factory_context_impl_unittest.cc",
"image_decoder_test.cc",
"image_decoder_test.h",
@@ -1596,13 +1623,13 @@ test("content_unittests") {
":content_unittests_catalog_source",
":test_interfaces",
":test_support",
+ "//base/allocator:features",
"//base/test:test_support",
"//base/third_party/dynamic_annotations",
"//cc",
"//cc:test_support",
"//cc/ipc",
"//components/leveldb/public/cpp",
- "//components/metrics/proto",
"//components/network_session_configurator/browser",
"//components/network_session_configurator/common",
"//components/offline_pages/features:features",
@@ -1679,6 +1706,7 @@ test("content_unittests") {
"//third_party/WebKit/public:blink",
"//third_party/icu",
"//third_party/leveldatabase",
+ "//third_party/metrics_proto",
"//third_party/re2",
"//third_party/widevine/cdm:headers",
"//ui/accessibility",
@@ -1696,6 +1724,7 @@ test("content_unittests") {
"//ui/gfx/ipc/skia",
"//ui/gl",
"//ui/gl:test_support",
+ "//ui/latency:test_support",
]
data_deps = [
@@ -1715,6 +1744,7 @@ test("content_unittests") {
# Put WebRTC-related plugins sources in the "enable_webrtc &&
# enable_plugins" section below.
sources += [
+ "../browser/plugin_service_impl_unittest.cc",
"../browser/renderer_host/pepper/browser_ppapi_host_test.cc",
"../browser/renderer_host/pepper/browser_ppapi_host_test.h",
"../browser/renderer_host/pepper/pepper_file_system_browser_host_unittest.cc",
@@ -1761,7 +1791,7 @@ test("content_unittests") {
"../renderer/media/media_stream_constraints_util_unittest.cc",
"../renderer/media/media_stream_constraints_util_video_content_unittest.cc",
"../renderer/media/media_stream_constraints_util_video_device_unittest.cc",
- "../renderer/media/media_stream_dispatcher_unittest.cc",
+ "../renderer/media/media_stream_device_observer_unittest.cc",
"../renderer/media/media_stream_video_capturer_source_unittest.cc",
"../renderer/media/media_stream_video_renderer_sink_unittest.cc",
"../renderer/media/media_stream_video_source_unittest.cc",
@@ -1777,7 +1807,6 @@ test("content_unittests") {
"../renderer/media/peer_connection_tracker_unittest.cc",
"../renderer/media/rtc_data_channel_handler_unittest.cc",
"../renderer/media/rtc_peer_connection_handler_unittest.cc",
- "../renderer/media/speech_recognition_audio_sink_unittest.cc",
"../renderer/media/user_media_client_impl_unittest.cc",
"../renderer/media/video_track_adapter_unittest.cc",
"../renderer/media/webmediaplayer_ms_unittest.cc",
@@ -1793,6 +1822,7 @@ test("content_unittests") {
"../renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc",
"../renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc",
"../renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc",
+ "../renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc",
"../renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc",
"../renderer/media/webrtc_audio_renderer_unittest.cc",
"../renderer/media/webrtc_local_audio_source_provider_unittest.cc",
@@ -1812,6 +1842,7 @@ test("content_unittests") {
"//third_party/webrtc/api:libjingle_peerconnection",
"//third_party/webrtc/api:rtc_stats_api",
"//third_party/webrtc/api:video_frame_api",
+ "//third_party/webrtc/api:video_frame_api_i420",
"//third_party/webrtc/api/video_codecs:video_codecs_api",
"//third_party/webrtc/media:rtc_media",
"//third_party/webrtc/modules/desktop_capture:primitives",
@@ -1848,7 +1879,9 @@ test("content_unittests") {
# Screen capture unit tests.
if (is_linux || is_mac || is_win) {
deps += [ "//third_party/libyuv" ]
- sources += [ "../browser/media/capture/web_contents_video_capture_device_unittest.cc" ]
+ sources += [
+ "../browser/media/capture/web_contents_video_capture_device_unittest.cc",
+ ]
if (use_aura) {
sources += [ "../browser/media/capture/cursor_renderer_aura_unittest.cc" ]
}
@@ -1921,6 +1954,7 @@ test("content_unittests") {
"../browser/speech/endpointer/endpointer_unittest.cc",
"../browser/speech/speech_recognition_engine_unittest.cc",
"../browser/speech/speech_recognizer_impl_unittest.cc",
+ "../browser/webauth/authenticator_impl_unittest.cc",
]
deps += [ "//third_party/libvpx" ]
}
@@ -1963,9 +1997,6 @@ test("content_unittests") {
if (use_ozone) {
deps += [ "//ui/ozone" ]
- } else {
- sources -=
- [ "../browser/compositor/software_output_device_ozone_unittest.cc" ]
}
if (is_mac) {
@@ -2020,6 +2051,10 @@ test("content_perftests") {
"//ui/events/blink",
"//ui/gfx",
"//ui/gfx/geometry",
+
+ # For TestMojoProxyResolverFactory. Remove once it moves to the network
+ # service.
+ "//services/service_manager/public/cpp",
]
if (is_android) {
diff --git a/chromium/content/test/fuzzer/BUILD.gn b/chromium/content/test/fuzzer/BUILD.gn
index d78755635b4..3907fe28655 100644
--- a/chromium/content/test/fuzzer/BUILD.gn
+++ b/chromium/content/test/fuzzer/BUILD.gn
@@ -38,6 +38,18 @@ fuzzer_test("origin_trial_token_fuzzer") {
seed_corpus = "//content/test/data/fuzzer_corpus/origin_trial_token_data/"
}
+fuzzer_test("origin_manifest_parser_fuzzer") {
+ sources = [
+ "origin_manifest_parser_fuzzer.cc",
+ ]
+ deps = [
+ ":fuzzer_support",
+ "//content/browser:for_content_tests",
+ ]
+ dict = "//content/test/data/fuzzer_dictionaries/origin_manifest_parser_fuzzer.dict"
+ seed_corpus = "//content/test/data/fuzzer_corpus/origin_manifest_parser_data/"
+}
+
fuzzer_test("renderer_fuzzer") {
sources = [
"renderer_fuzzer.cc",
diff --git a/chromium/content/utility/BUILD.gn b/chromium/content/utility/BUILD.gn
index 1b5dd17c04e..65bd8732395 100644
--- a/chromium/content/utility/BUILD.gn
+++ b/chromium/content/utility/BUILD.gn
@@ -47,6 +47,7 @@ source_set("utility") {
"//services/shape_detection/public/interfaces",
"//services/video_capture:lib",
"//services/video_capture/public/interfaces:constants",
+ "//services/viz:lib",
"//third_party/WebKit/public:blink_headers",
"//third_party/WebKit/public:mojo_bindings",
"//url",
diff --git a/chromium/content/utility/DEPS b/chromium/content/utility/DEPS
index af97e0997f4..b10de6b8583 100644
--- a/chromium/content/utility/DEPS
+++ b/chromium/content/utility/DEPS
@@ -6,5 +6,6 @@ include_rules = [
"+services/service_manager",
"+services/shape_detection",
"+services/video_capture",
+ "+services/viz",
"+sandbox/win/src",
]
diff --git a/chromium/content/utility/utility_main.cc b/chromium/content/utility/utility_main.cc
index b08ec35d585..856bf88b92a 100644
--- a/chromium/content/utility/utility_main.cc
+++ b/chromium/content/utility/utility_main.cc
@@ -17,10 +17,11 @@
#include "content/public/common/main_function_params.h"
#include "content/public/common/sandbox_init.h"
#include "content/utility/utility_thread_impl.h"
-#include "services/service_manager/sandbox/sandbox_type.h"
+#include "services/service_manager/sandbox/sandbox.h"
#if defined(OS_LINUX)
-#include "content/common/sandbox_linux/sandbox_linux.h"
+#include "content/network/network_sandbox_hook_linux.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#endif
#if defined(OS_WIN)
@@ -49,8 +50,17 @@ int UtilityMain(const MainFunctionParams& parameters) {
// Initializes the sandbox before any threads are created.
// TODO(jorgelo): move this after GTK initialization when we enable a strict
// Seccomp-BPF policy.
- if (parameters.zygote_child)
- LinuxSandbox::InitializeSandbox();
+ auto sandbox_type =
+ service_manager::SandboxTypeFromCommandLine(parameters.command_line);
+ if (parameters.zygote_child ||
+ sandbox_type == service_manager::SANDBOX_TYPE_NETWORK) {
+ service_manager::SandboxLinux::PreSandboxHook pre_sandbox_hook;
+ if (sandbox_type == service_manager::SANDBOX_TYPE_NETWORK)
+ pre_sandbox_hook = base::BindOnce(&NetworkPreSandboxHook);
+ service_manager::Sandbox::Initialize(
+ sandbox_type, std::move(pre_sandbox_hook),
+ service_manager::SandboxLinux::Options());
+ }
#elif defined(OS_WIN)
g_utility_target_services = parameters.sandbox_info->target_services;
#endif
diff --git a/chromium/content/utility/utility_service_factory.cc b/chromium/content/utility/utility_service_factory.cc
index 4ee0b3f5df7..499ec6bb520 100644
--- a/chromium/content/utility/utility_service_factory.cc
+++ b/chromium/content/utility/utility_service_factory.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/trace_event/trace_log.h"
#include "build/build_config.h"
#include "content/child/child_process.h"
#include "content/network/network_service_impl.h"
@@ -21,10 +22,13 @@
#include "media/media_features.h"
#include "services/data_decoder/data_decoder_service.h"
#include "services/data_decoder/public/interfaces/constants.mojom.h"
+#include "services/service_manager/public/interfaces/service.mojom.h"
#include "services/shape_detection/public/interfaces/constants.mojom.h"
#include "services/shape_detection/shape_detection_service.h"
#include "services/video_capture/public/interfaces/constants.mojom.h"
#include "services/video_capture/service_impl.h"
+#include "services/viz/public/interfaces/constants.mojom.h"
+#include "services/viz/service.h"
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "media/cdm/cdm_adapter_factory.h" // nogncheck
@@ -47,7 +51,7 @@ extern sandbox::TargetServices* g_utility_target_services;
namespace {
std::unique_ptr<service_manager::Service> CreateVideoCaptureService() {
- return base::MakeUnique<video_capture::ServiceImpl>();
+ return std::make_unique<video_capture::ServiceImpl>();
}
} // anonymous namespace
@@ -96,7 +100,7 @@ class CdmMojoMediaClient final : public media::MojoMediaClient {
std::unique_ptr<service_manager::Service> CreateCdmService() {
return std::unique_ptr<service_manager::Service>(
- new ::media::MediaService(base::MakeUnique<CdmMojoMediaClient>()));
+ new ::media::MediaService(std::make_unique<CdmMojoMediaClient>()));
}
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
@@ -105,13 +109,26 @@ std::unique_ptr<service_manager::Service> CreateDataDecoderService() {
return data_decoder::DataDecoderService::Create();
}
+std::unique_ptr<service_manager::Service> CreateVizService() {
+ return std::make_unique<viz::Service>();
+}
+
} // namespace
UtilityServiceFactory::UtilityServiceFactory()
- : network_registry_(base::MakeUnique<service_manager::BinderRegistry>()) {}
+ : network_registry_(std::make_unique<service_manager::BinderRegistry>()) {}
UtilityServiceFactory::~UtilityServiceFactory() {}
+void UtilityServiceFactory::CreateService(
+ service_manager::mojom::ServiceRequest request,
+ const std::string& name) {
+ auto* trace_log = base::trace_event::TraceLog::GetInstance();
+ if (trace_log->IsProcessNameEmpty())
+ trace_log->set_process_name("Service: " + name);
+ ServiceFactory::CreateService(std::move(request), name);
+}
+
void UtilityServiceFactory::RegisterServices(ServiceMap* services) {
GetContentClient()->utility()->RegisterServices(services);
@@ -137,6 +154,10 @@ void UtilityServiceFactory::RegisterServices(ServiceMap* services) {
services->insert(
std::make_pair(data_decoder::mojom::kServiceName, data_decoder_info));
+ service_manager::EmbeddedServiceInfo viz_info;
+ viz_info.factory = base::Bind(&CreateVizService);
+ services->insert(std::make_pair(viz::mojom::kVizServiceName, viz_info));
+
if (base::FeatureList::IsEnabled(features::kNetworkService)) {
GetContentClient()->utility()->RegisterNetworkBinders(
network_registry_.get());
@@ -162,7 +183,7 @@ void UtilityServiceFactory::OnLoadFailed() {
std::unique_ptr<service_manager::Service>
UtilityServiceFactory::CreateNetworkService() {
- return base::MakeUnique<NetworkServiceImpl>(std::move(network_registry_));
+ return std::make_unique<NetworkServiceImpl>(std::move(network_registry_));
}
} // namespace content
diff --git a/chromium/content/utility/utility_service_factory.h b/chromium/content/utility/utility_service_factory.h
index ed4363a5edf..620229c6643 100644
--- a/chromium/content/utility/utility_service_factory.h
+++ b/chromium/content/utility/utility_service_factory.h
@@ -5,9 +5,13 @@
#ifndef CONTENT_UTILITY_UTILITY_SERVICE_FACTORY_H_
#define CONTENT_UTILITY_UTILITY_SERVICE_FACTORY_H_
+#include <memory>
+#include <string>
+
#include "base/macros.h"
#include "content/child/service_factory.h"
#include "services/service_manager/public/cpp/binder_registry.h"
+#include "services/service_manager/public/interfaces/service.mojom.h"
namespace content {
@@ -19,6 +23,8 @@ class UtilityServiceFactory : public ServiceFactory {
~UtilityServiceFactory() override;
// ServiceFactory overrides:
+ void CreateService(service_manager::mojom::ServiceRequest request,
+ const std::string& name) override;
void RegisterServices(ServiceMap* services) override;
void OnServiceQuit() override;
diff --git a/chromium/content/utility/utility_thread_impl.cc b/chromium/content/utility/utility_thread_impl.cc
index 711333fb0a7..cd4f9b80aa3 100644
--- a/chromium/content/utility/utility_thread_impl.cc
+++ b/chromium/content/utility/utility_thread_impl.cc
@@ -70,7 +70,7 @@ void UtilityThreadImpl::EnsureBlinkInitialized() {
void UtilityThreadImpl::Init() {
ChildProcess::current()->AddRefProcess();
- auto registry = base::MakeUnique<service_manager::BinderRegistry>();
+ auto registry = std::make_unique<service_manager::BinderRegistry>();
registry->AddInterface(
base::Bind(&UtilityThreadImpl::BindServiceFactoryRequest,
base::Unretained(this)),
@@ -79,7 +79,7 @@ void UtilityThreadImpl::Init() {
content::ServiceManagerConnection* connection = GetServiceManagerConnection();
if (connection) {
connection->AddConnectionFilter(
- base::MakeUnique<SimpleConnectionFilter>(std::move(registry)));
+ std::make_unique<SimpleConnectionFilter>(std::move(registry)));
}
GetContentClient()->utility()->UtilityThreadStarted();
diff --git a/chromium/content/zygote/DEPS b/chromium/content/zygote/DEPS
new file mode 100644
index 00000000000..9af3bd99586
--- /dev/null
+++ b/chromium/content/zygote/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+services/service_manager/sandbox",
+] \ No newline at end of file
diff --git a/chromium/content/zygote/OWNERS b/chromium/content/zygote/OWNERS
index 75b96d59fa7..d38314f3fdd 100644
--- a/chromium/content/zygote/OWNERS
+++ b/chromium/content/zygote/OWNERS
@@ -1,6 +1,7 @@
jln@chromium.org
-mdempsky@chromium.org
-rickyz@chromium.org
+palmer@chromium.org
+rsesek@chromium.org
+tsepez@chromium.org
# TEAM: security-dev@chromium.org
# COMPONENT: Internals>Sandbox
diff --git a/chromium/content/zygote/zygote_linux.cc b/chromium/content/zygote/zygote_linux.cc
index 5fe541a1e1a..9d49148d572 100644
--- a/chromium/content/zygote/zygote_linux.cc
+++ b/chromium/content/zygote/zygote_linux.cc
@@ -32,18 +32,21 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
#include "content/common/zygote_commands_linux.h"
+#include "content/public/common/common_sandbox_support_linux.h"
#include "content/public/common/content_descriptors.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/mojo_channel_switches.h"
#include "content/public/common/result_codes.h"
-#include "content/public/common/sandbox_linux.h"
#include "content/public/common/send_zygote_child_ping_linux.h"
#include "content/public/common/zygote_fork_delegate_linux.h"
#include "ipc/ipc_channel.h"
#include "sandbox/linux/services/credentials.h"
#include "sandbox/linux/services/namespace_sandbox.h"
#include "services/service_manager/embedder/set_process_title.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
+#include "services/service_manager/sandbox/sandbox.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
// See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_zygote.md
@@ -84,7 +87,7 @@ void KillAndReap(pid_t pid, ZygoteForkDelegate* helper) {
// Kill the child process in case it's not already dead, so we can safely
// perform a blocking wait.
PCHECK(0 == kill(pid, SIGKILL));
- PCHECK(pid == HANDLE_EINTR(waitpid(pid, NULL, 0)));
+ PCHECK(pid == HANDLE_EINTR(waitpid(pid, nullptr, 0)));
}
} // namespace
@@ -114,7 +117,7 @@ bool Zygote::ProcessRequests() {
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_handler = &SIGCHLDHandler;
- PCHECK(sigaction(SIGCHLD, &action, NULL) == 0);
+ PCHECK(sigaction(SIGCHLD, &action, nullptr) == 0);
// Block SIGCHLD until a child might be ready to reap.
sigset_t sigset;
@@ -164,7 +167,7 @@ bool Zygote::ProcessRequests() {
if (pfd.revents & POLLIN) {
// This function call can return multiple times, once per fork().
if (HandleRequestFromBrowser(kZygoteSocketPairFd)) {
- PCHECK(sigprocmask(SIG_SETMASK, &orig_sigmask, NULL) == 0);
+ PCHECK(sigprocmask(SIG_SETMASK, &orig_sigmask, nullptr) == 0);
return true;
}
}
@@ -176,7 +179,7 @@ bool Zygote::ProcessRequests() {
bool Zygote::ReapChild(const base::TimeTicks& now, ZygoteProcessInfo* child) {
pid_t pid = child->internal_pid;
- pid_t r = HANDLE_EINTR(waitpid(pid, NULL, WNOHANG));
+ pid_t r = HANDLE_EINTR(waitpid(pid, nullptr, WNOHANG));
if (r > 0) {
if (r != pid) {
DLOG(ERROR) << "While waiting for " << pid << " to terminate, "
@@ -222,11 +225,11 @@ bool Zygote::GetProcessInfo(base::ProcessHandle pid,
}
bool Zygote::UsingSUIDSandbox() const {
- return sandbox_flags_ & kSandboxLinuxSUID;
+ return sandbox_flags_ & service_manager::SandboxLinux::kSUID;
}
bool Zygote::UsingNSSandbox() const {
- return sandbox_flags_ & kSandboxLinuxUserNS;
+ return sandbox_flags_ & service_manager::SandboxLinux::kUserNS;
}
bool Zygote::HandleRequestFromBrowser(int fd) {
@@ -249,7 +252,7 @@ bool Zygote::HandleRequestFromBrowser(int fd) {
CHECK(extra_children_.empty());
#endif
for (base::ProcessHandle pid : extra_children_) {
- PCHECK(pid == HANDLE_EINTR(waitpid(pid, NULL, 0)));
+ PCHECK(pid == HANDLE_EINTR(waitpid(pid, nullptr, 0)));
}
_exit(0);
return false;
@@ -417,7 +420,7 @@ int Zygote::ForkWithRealPid(const std::string& process_type,
std::string* uma_name,
int* uma_sample,
int* uma_boundary_value) {
- ZygoteForkDelegate* helper = NULL;
+ ZygoteForkDelegate* helper = nullptr;
for (auto i = helpers_.begin(); i != helpers_.end(); ++i) {
if ((*i)->CanHelp(process_type, uma_name, uma_sample, uma_boundary_value)) {
helper = i->get();
@@ -442,8 +445,8 @@ int Zygote::ForkWithRealPid(const std::string& process_type,
CHECK_NE(pid, 0);
} else {
CreatePipe(&read_pipe, &write_pipe);
- if (sandbox_flags_ & kSandboxLinuxPIDNS &&
- sandbox_flags_ & kSandboxLinuxUserNS) {
+ if (sandbox_flags_ & service_manager::SandboxLinux::kPIDNS &&
+ sandbox_flags_ & service_manager::SandboxLinux::kUserNS) {
pid = sandbox::NamespaceSandbox::ForkInNewPidNamespace(
/*drop_capabilities_in_child=*/true);
} else {
@@ -578,6 +581,17 @@ base::ProcessId Zygote::ReadArgsAndFork(base::PickleIterator iter,
channel_id = arg.substr(channel_id_prefix.length());
}
+ if (process_type == switches::kRendererProcess) {
+ // timezone_id is obtained from ICU in zygote host so that it can't be
+ // invalid. For an unknown reason, if an invalid ID is passed down here,
+ // the worst result would be that timezone would be set to Etc/Unknown.
+ base::string16 timezone_id;
+ if (!iter.ReadString16(&timezone_id))
+ return -1;
+ icu::TimeZone::adoptDefault(icu::TimeZone::createTimeZone(
+ icu::UnicodeString(FALSE, timezone_id.data(), timezone_id.length())));
+ }
+
if (!iter.ReadInt(&numfds))
return -1;
if (numfds != static_cast<int>(fds.size()))
@@ -616,7 +630,7 @@ base::ProcessId Zygote::ReadArgsAndFork(base::PickleIterator iter,
// Reset the process-wide command line to our new command line.
base::CommandLine::Reset();
- base::CommandLine::Init(0, NULL);
+ base::CommandLine::Init(0, nullptr);
base::CommandLine::ForCurrentProcess()->InitFromArgv(args);
// Update the process title. The argv was already cached by the call to
diff --git a/chromium/content/zygote/zygote_main_linux.cc b/chromium/content/zygote/zygote_main_linux.cc
index df207993b23..b5a7f4b5681 100644
--- a/chromium/content/zygote/zygote_main_linux.cc
+++ b/chromium/content/zygote/zygote_main_linux.cc
@@ -11,6 +11,7 @@
#include <stddef.h>
#include <stdint.h>
#include <string.h>
+#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
@@ -22,6 +23,8 @@
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
+#include "base/memory/protected_memory.h"
+#include "base/memory/protected_memory_cfi.h"
#include "base/native_library.h"
#include "base/pickle.h"
#include "base/posix/eintr_wrapper.h"
@@ -32,12 +35,10 @@
#include "base/sys_info.h"
#include "build/build_config.h"
#include "content/common/font_config_ipc_linux.h"
-#include "content/common/sandbox_linux/sandbox_debug_handling_linux.h"
-#include "content/common/sandbox_linux/sandbox_linux.h"
#include "content/common/zygote_commands_linux.h"
+#include "content/public/common/common_sandbox_support_linux.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
-#include "content/public/common/sandbox_linux.h"
#include "content/public/common/zygote_fork_delegate_linux.h"
#include "content/zygote/zygote_linux.h"
#include "media/media_features.h"
@@ -47,6 +48,9 @@
#include "sandbox/linux/services/namespace_sandbox.h"
#include "sandbox/linux/services/thread_helpers.h"
#include "sandbox/linux/suid/client/setuid_sandbox_client.h"
+#include "services/service_manager/sandbox/linux/sandbox_debug_handling_linux.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
+#include "services/service_manager/sandbox/sandbox.h"
#include "third_party/WebKit/public/web/linux/WebFontRendering.h"
#include "third_party/boringssl/src/include/openssl/crypto.h"
#include "third_party/boringssl/src/include/openssl/rand.h"
@@ -54,10 +58,6 @@
#include "third_party/skia/include/ports/SkFontConfigInterface.h"
#include "third_party/skia/include/ports/SkFontMgr_android.h"
-#if defined(OS_LINUX)
-#include <sys/prctl.h>
-#endif
-
#if BUILDFLAG(ENABLE_PLUGINS)
#include "content/common/pepper_plugin_list.h"
#include "content/public/common/pepper_plugin_info.h"
@@ -153,7 +153,7 @@ static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output,
char* timezone_out,
size_t timezone_out_len) {
base::Pickle request;
- request.WriteInt(LinuxSandbox::METHOD_LOCALTIME);
+ request.WriteInt(service_manager::SandboxLinux::METHOD_LOCALTIME);
request.WriteString(
std::string(reinterpret_cast<char*>(&input), sizeof(input)));
@@ -161,7 +161,7 @@ static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output,
uint8_t reply_buf[512];
const ssize_t r = base::UnixDomainSocket::SendRecvMsg(
- GetSandboxFD(), reply_buf, sizeof(reply_buf), NULL, request);
+ GetSandboxFD(), reply_buf, sizeof(reply_buf), nullptr, request);
if (r == -1) {
return;
}
@@ -216,23 +216,32 @@ typedef struct tm* (*LocaltimeFunction)(const time_t* timep);
typedef struct tm* (*LocaltimeRFunction)(const time_t* timep,
struct tm* result);
-static pthread_once_t g_libc_localtime_funcs_guard = PTHREAD_ONCE_INIT;
-static LocaltimeFunction g_libc_localtime;
-static LocaltimeFunction g_libc_localtime64;
-static LocaltimeRFunction g_libc_localtime_r;
-static LocaltimeRFunction g_libc_localtime64_r;
+struct LibcFunctions {
+ LocaltimeFunction localtime;
+ LocaltimeFunction localtime64;
+ LocaltimeRFunction localtime_r;
+ LocaltimeRFunction localtime64_r;
+};
+
+static pthread_once_t g_libc_funcs_guard = PTHREAD_ONCE_INIT;
+// The libc function pointers are stored in read-only memory after being
+// dynamically resolved as a security mitigation to prevent the pointer from
+// being tampered with. See crbug.com/771365 for details.
+static PROTECTED_MEMORY_SECTION base::ProtectedMemory<LibcFunctions>
+ g_libc_funcs;
static void InitLibcLocaltimeFunctions() {
- g_libc_localtime = reinterpret_cast<LocaltimeFunction>(
- dlsym(RTLD_NEXT, "localtime"));
- g_libc_localtime64 = reinterpret_cast<LocaltimeFunction>(
- dlsym(RTLD_NEXT, "localtime64"));
- g_libc_localtime_r = reinterpret_cast<LocaltimeRFunction>(
- dlsym(RTLD_NEXT, "localtime_r"));
- g_libc_localtime64_r = reinterpret_cast<LocaltimeRFunction>(
- dlsym(RTLD_NEXT, "localtime64_r"));
-
- if (!g_libc_localtime || !g_libc_localtime_r) {
+ auto writer = base::AutoWritableMemory::Create(g_libc_funcs);
+ g_libc_funcs->localtime =
+ reinterpret_cast<LocaltimeFunction>(dlsym(RTLD_NEXT, "localtime"));
+ g_libc_funcs->localtime64 =
+ reinterpret_cast<LocaltimeFunction>(dlsym(RTLD_NEXT, "localtime64"));
+ g_libc_funcs->localtime_r =
+ reinterpret_cast<LocaltimeRFunction>(dlsym(RTLD_NEXT, "localtime_r"));
+ g_libc_funcs->localtime64_r =
+ reinterpret_cast<LocaltimeRFunction>(dlsym(RTLD_NEXT, "localtime64_r"));
+
+ if (!g_libc_funcs->localtime || !g_libc_funcs->localtime_r) {
// http://code.google.com/p/chromium/issues/detail?id=16800
//
// Nvidia's libGL.so overrides dlsym for an unknown reason and replaces
@@ -244,14 +253,14 @@ static void InitLibcLocaltimeFunctions() {
"http://code.google.com/p/chromium/issues/detail?id=16800";
}
- if (!g_libc_localtime)
- g_libc_localtime = gmtime;
- if (!g_libc_localtime64)
- g_libc_localtime64 = g_libc_localtime;
- if (!g_libc_localtime_r)
- g_libc_localtime_r = gmtime_r;
- if (!g_libc_localtime64_r)
- g_libc_localtime64_r = g_libc_localtime_r;
+ if (!g_libc_funcs->localtime)
+ g_libc_funcs->localtime = gmtime;
+ if (!g_libc_funcs->localtime64)
+ g_libc_funcs->localtime64 = g_libc_funcs->localtime;
+ if (!g_libc_funcs->localtime_r)
+ g_libc_funcs->localtime_r = gmtime_r;
+ if (!g_libc_funcs->localtime64_r)
+ g_libc_funcs->localtime64_r = g_libc_funcs->localtime_r;
}
// Define localtime_override() function with asm name "localtime", so that all
@@ -271,9 +280,9 @@ struct tm* localtime_override(const time_t* timep) {
return &time_struct;
}
- CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
- InitLibcLocaltimeFunctions));
- struct tm* res = g_libc_localtime(timep);
+ CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions));
+ struct tm* res =
+ base::UnsanitizedCfiCall(g_libc_funcs, &LibcFunctions::localtime)(timep);
#if defined(MEMORY_SANITIZER)
if (res) __msan_unpoison(res, sizeof(*res));
if (res->tm_zone) __msan_unpoison_string(res->tm_zone);
@@ -295,9 +304,9 @@ struct tm* localtime64_override(const time_t* timep) {
return &time_struct;
}
- CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
- InitLibcLocaltimeFunctions));
- struct tm* res = g_libc_localtime64(timep);
+ CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions));
+ struct tm* res = base::UnsanitizedCfiCall(g_libc_funcs,
+ &LibcFunctions::localtime64)(timep);
#if defined(MEMORY_SANITIZER)
if (res) __msan_unpoison(res, sizeof(*res));
if (res->tm_zone) __msan_unpoison_string(res->tm_zone);
@@ -312,13 +321,13 @@ struct tm* localtime_r_override(const time_t* timep,
__attribute__ ((__visibility__("default")))
struct tm* localtime_r_override(const time_t* timep, struct tm* result) {
if (g_am_zygote_or_renderer && g_use_localtime_override) {
- ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0);
+ ProxyLocaltimeCallToBrowser(*timep, result, nullptr, 0);
return result;
}
- CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
- InitLibcLocaltimeFunctions));
- struct tm* res = g_libc_localtime_r(timep, result);
+ CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions));
+ struct tm* res = base::UnsanitizedCfiCall(
+ g_libc_funcs, &LibcFunctions::localtime_r)(timep, result);
#if defined(MEMORY_SANITIZER)
if (res) __msan_unpoison(res, sizeof(*res));
if (res->tm_zone) __msan_unpoison_string(res->tm_zone);
@@ -333,13 +342,13 @@ struct tm* localtime64_r_override(const time_t* timep,
__attribute__ ((__visibility__("default")))
struct tm* localtime64_r_override(const time_t* timep, struct tm* result) {
if (g_am_zygote_or_renderer && g_use_localtime_override) {
- ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0);
+ ProxyLocaltimeCallToBrowser(*timep, result, nullptr, 0);
return result;
}
- CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
- InitLibcLocaltimeFunctions));
- struct tm* res = g_libc_localtime64_r(timep, result);
+ CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions));
+ struct tm* res = base::UnsanitizedCfiCall(
+ g_libc_funcs, &LibcFunctions::localtime64_r)(timep, result);
#if defined(MEMORY_SANITIZER)
if (res) __msan_unpoison(res, sizeof(*res));
if (res->tm_zone) __msan_unpoison_string(res->tm_zone);
@@ -504,7 +513,7 @@ static bool EnterSuidSandbox(sandbox::SetuidSandboxClient* setuid_sandbox,
CHECK(CreateInitProcessReaper(post_fork_parent_callback));
}
- CHECK(SandboxDebugHandling::SetDumpableStatusAndHandlers());
+ CHECK(service_manager::SandboxDebugHandling::SetDumpableStatusAndHandlers());
return true;
}
@@ -512,10 +521,9 @@ static void DropAllCapabilities(int proc_fd) {
CHECK(sandbox::Credentials::DropAllCapabilities(proc_fd));
}
-static void EnterNamespaceSandbox(LinuxSandbox* linux_sandbox,
+static void EnterNamespaceSandbox(service_manager::SandboxLinux* linux_sandbox,
base::Closure* post_fork_parent_callback) {
- linux_sandbox->EngageNamespaceSandbox();
-
+ linux_sandbox->EngageNamespaceSandbox(true /* from_zygote */);
if (getpid() == 1) {
base::Closure drop_all_caps_callback =
base::Bind(&DropAllCapabilities, linux_sandbox->proc_fd());
@@ -525,7 +533,7 @@ static void EnterNamespaceSandbox(LinuxSandbox* linux_sandbox,
}
}
-static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox,
+static void EnterLayerOneSandbox(service_manager::SandboxLinux* linux_sandbox,
const bool using_layer1_sandbox,
base::Closure* post_fork_parent_callback) {
DCHECK(linux_sandbox);
@@ -557,8 +565,7 @@ bool ZygoteMain(
g_am_zygote_or_renderer = true;
std::vector<int> fds_to_close_post_fork;
-
- LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance();
+ auto* linux_sandbox = service_manager::SandboxLinux::GetInstance();
// Skip pre-initializing sandbox under --no-sandbox for crbug.com/444900.
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -617,10 +624,12 @@ bool ZygoteMain(
const int sandbox_flags = linux_sandbox->GetStatus();
- const bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID;
+ const bool setuid_sandbox_engaged =
+ sandbox_flags & service_manager::SandboxLinux::kSUID;
CHECK_EQ(using_setuid_sandbox, setuid_sandbox_engaged);
- const bool namespace_sandbox_engaged = sandbox_flags & kSandboxLinuxUserNS;
+ const bool namespace_sandbox_engaged =
+ sandbox_flags & service_manager::SandboxLinux::kUserNS;
CHECK_EQ(using_namespace_sandbox, namespace_sandbox_engaged);
Zygote zygote(sandbox_flags, std::move(fork_delegates), extra_children,